1
0
mirror of https://github.com/garraflavatra/rolens.git synced 2025-01-19 13:27:58 +00:00
rolens/frontend/src/app.svelte

225 lines
6.7 KiB
Svelte
Raw Normal View History

2023-01-10 16:28:27 +00:00
<script>
2023-01-15 15:49:08 +00:00
import { onMount, tick } from 'svelte';
2023-01-14 20:09:21 +00:00
import { DropCollection, DropDatabase, Hosts, OpenCollection, OpenConnection, OpenDatabase } from '../wailsjs/go/app/App';
2023-01-10 16:28:27 +00:00
import AddressBar from './organisms/addressbar/index.svelte';
import Grid from './components/grid.svelte';
import CollectionDetail from './organisms/collection-detail/index.svelte';
2023-01-14 19:38:39 +00:00
import { busy, contextMenu } from './stores';
import ContextMenu from './components/contextmenu.svelte';
2023-01-15 15:49:08 +00:00
import Modal from './components/modal.svelte';
import { input } from './actions';
2023-01-15 16:10:30 +00:00
import BlankState from './components/blankstate.svelte';
2023-01-10 16:28:27 +00:00
const connections = {};
let hosts = {};
2023-01-15 15:49:08 +00:00
2023-01-10 16:28:27 +00:00
let activeHostKey = '';
let activeDbKey = '';
let activeCollKey = '';
2023-01-15 15:49:08 +00:00
2023-01-11 19:41:15 +00:00
let addressBarModalOpen = true;
2023-01-10 16:28:27 +00:00
2023-01-15 15:49:08 +00:00
let newDb;
let newDbInput;
let newColl;
let newCollInput;
2023-01-10 16:28:27 +00:00
$: host = hosts[activeHostKey];
$: connection = connections[activeHostKey];
$: database = connection?.databases[activeDbKey];
$: collection = database?.collections?.[activeCollKey];
2023-01-15 15:49:08 +00:00
$: if (newDb) {
tick().then(() => newDbInput.focus());
}
2023-01-10 16:28:27 +00:00
async function openConnection(hostKey) {
2023-01-14 20:09:21 +00:00
busy.start();
2023-01-10 16:28:27 +00:00
const databases = await OpenConnection(hostKey);
if (databases) {
connections[hostKey] = { databases: {} };
databases.forEach(dbKey => {
connections[hostKey].databases[dbKey] = { collections: {} };
});
activeHostKey = hostKey;
addressBarModalOpen = false;
window.runtime.WindowSetTitle(`${host.name} - Mongodup`);
}
2023-01-14 20:09:21 +00:00
busy.end();
2023-01-10 16:28:27 +00:00
}
2023-01-15 15:49:08 +00:00
function createDatabase() {
busy.start();
connections[activeHostKey].databases[newDb.name] = { collections: {} };
newDb = undefined;
busy.end();
}
2023-01-10 16:28:27 +00:00
async function openDatabase(dbKey) {
2023-01-14 20:09:21 +00:00
busy.start();
2023-01-10 16:28:27 +00:00
const collections = await OpenDatabase(activeHostKey, dbKey);
for (const collKey of collections || []) {
connections[activeHostKey].databases[dbKey].collections[collKey] = {};
}
2023-01-14 20:09:21 +00:00
busy.end();
2023-01-10 16:28:27 +00:00
}
2023-01-14 19:38:39 +00:00
async function dropDatabase(dbKey) {
2023-01-14 20:09:21 +00:00
busy.start();
2023-01-14 19:38:39 +00:00
await DropDatabase(activeHostKey, dbKey);
2023-01-15 15:49:08 +00:00
await reload();
busy.end();
}
function createCollection() {
busy.start();
connections[activeHostKey].databases[activeDbKey].collections[newColl.name] = {};
newColl = undefined;
2023-01-14 20:09:21 +00:00
busy.end();
2023-01-14 19:38:39 +00:00
}
2023-01-10 16:28:27 +00:00
async function openCollection(collKey) {
2023-01-14 20:09:21 +00:00
busy.start();
2023-01-10 16:28:27 +00:00
const stats = await OpenCollection(activeHostKey, activeDbKey, collKey);
connections[activeHostKey].databases[activeDbKey].collections[collKey].stats = stats;
2023-01-14 20:09:21 +00:00
busy.end();
}
async function dropCollection(dbKey, collKey) {
busy.start();
await DropCollection(activeHostKey, dbKey, collKey);
2023-01-15 15:49:08 +00:00
await reload();
2023-01-14 20:09:21 +00:00
busy.end();
2023-01-10 16:28:27 +00:00
}
2023-01-14 19:38:39 +00:00
async function reload() {
activeHostKey && await openConnection(activeHostKey);
activeDbKey && await openDatabase(activeDbKey);
}
2023-01-10 16:28:27 +00:00
onMount(() => {
Hosts().then(h => hosts = h);
});
</script>
2023-01-15 16:10:30 +00:00
<main class:empty={!host || !connection}>
2023-01-10 16:28:27 +00:00
<AddressBar {hosts} bind:activeHostKey on:select={e => openConnection(e.detail)} bind:modalOpen={addressBarModalOpen} />
2023-01-11 19:41:15 +00:00
{#if host && connection}
2023-01-14 19:38:39 +00:00
<div class="databaselist">
2023-01-11 19:41:15 +00:00
<Grid
columns={[ { key: 'id' }, { key: 'collCount', right: true } ]}
2023-01-14 20:09:21 +00:00
items={Object.keys(connection.databases).map(dbKey => ({
id: dbKey,
2023-01-15 15:49:08 +00:00
collCount: Object.keys(connection.databases[dbKey].collections || {}).length || '',
2023-01-14 20:09:21 +00:00
children: Object.keys(connection.databases[dbKey].collections).map(collKey => ({
id: collKey,
menu: [ { label: `Drop ${collKey}`, fn: () => dropCollection(dbKey, collKey) } ],
2023-01-15 15:49:08 +00:00
})).sort((a, b) => a.id.localeCompare(b)) || [],
2023-01-14 20:09:21 +00:00
menu: [ { label: `Drop ${dbKey}`, fn: () => dropDatabase(dbKey) } ],
2023-01-11 19:41:15 +00:00
}))}
2023-01-14 19:38:39 +00:00
actions={[
{ icon: 'reload', fn: reload },
2023-01-15 15:49:08 +00:00
{ icon: '+', fn: evt => {
if (activeDbKey) {
contextMenu.show(evt, [
{ label: 'New database', fn: () => newDb = {} },
{ label: 'New collection', fn: () => newColl = {} },
]);
}
else {
newDb = {};
}
} },
2023-01-15 15:51:39 +00:00
{ icon: '-', fn: evt => {
if (activeCollKey) {
contextMenu.show(evt, [
{ label: 'Drop database', fn: () => dropDatabase(activeDbKey) },
{ label: 'Drop collection', fn: () => dropCollection(activeDbKey, activeCollKey) },
]);
}
else {
dropDatabase(activeDbKey);
}
}, disabled: !activeDbKey },
2023-01-14 19:38:39 +00:00
]}
2023-01-11 19:41:15 +00:00
bind:activeKey={activeDbKey}
bind:activeChildKey={activeCollKey}
on:select={e => openDatabase(e.detail)}
on:selectChild={e => openCollection(e.detail)}
/>
</div>
<div class="collection">
<CollectionDetail
{collection}
hostKey={activeHostKey}
dbKey={activeDbKey}
collectionKey={activeCollKey}
/>
</div>
2023-01-15 16:10:30 +00:00
{:else}
<BlankState label="A database client is nothing without a host" image="/fish.svg" />
2023-01-11 19:41:15 +00:00
{/if}
2023-01-10 16:28:27 +00:00
</main>
2023-01-15 15:49:08 +00:00
{#if newDb}
<Modal bind:show={newDb}>
<p><strong>Create a database</strong></p>
<p>Note: databases in MongoDB do not exist until they have a collection and an item. Your new database will not persist on the server; fill it to have it created.</p>
<form on:submit|preventDefault={createDatabase}>
<label class="field">
<input type="text" spellcheck="false" bind:value={newDb.name} use:input placeholder="New collection name" bind:this={newDbInput} />
</label>
<button class="btn create" type="submit">Create database</button>
</form>
</Modal>
{/if}
{#if newColl}
<Modal bind:show={newColl}>
<p><strong>Create a collections</strong></p>
<p>Note: collections in MongoDB do not exist until they have at least one item. Your new collection will not persist on the server; fill it to have it created.</p>
<form on:submit|preventDefault={createCollection}>
<label class="field">
<input type="text" spellcheck="false" bind:value={newColl.name} use:input placeholder="New collection name" bind:this={newCollInput} />
</label>
<button class="btn create" type="submit">Create collection</button>
</form>
</Modal>
{/if}
2023-01-14 19:38:39 +00:00
{#key $contextMenu}
<ContextMenu {...$contextMenu} on:close={contextMenu.hide} />
{/key}
2023-01-10 16:28:27 +00:00
<style>
main {
height: 100vh;
2023-01-11 19:41:15 +00:00
display: grid;
grid-template: 3rem auto / 250px 1fr;
gap: 0.5rem;
padding: 0.5rem;
2023-01-10 16:28:27 +00:00
}
2023-01-15 16:10:30 +00:00
main.empty {
grid-template: 3rem auto / 1fr;
}
2023-01-11 19:41:15 +00:00
main > :global(.addressbar) {
grid-column: 1 / 3;
2023-01-10 16:28:27 +00:00
}
2023-01-14 19:38:39 +00:00
.databaselist {
2023-01-10 19:10:39 +00:00
overflow: scroll;
2023-01-10 16:28:27 +00:00
}
2023-01-15 15:49:08 +00:00
.btn.create {
margin-top: 0.5rem;
}
2023-01-10 16:28:27 +00:00
</style>