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-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 >
< main >
< 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 >
{ /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-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 >