1
0
mirror of https://github.com/garraflavatra/rolens.git synced 2025-01-18 13:07:58 +00:00

Preserve state between tabs (cc #37) (fixes #56)

This commit is contained in:
Romein van Buren 2023-07-08 13:07:55 +02:00
parent 64fb9ed173
commit 5476df5fe9
Signed by: romein
GPG Key ID: 0EFF8478ADDF6C49
12 changed files with 106 additions and 110 deletions

View File

@ -95,6 +95,7 @@ async function refresh() {
collection.key = collKey; collection.key = collKey;
collection.dbKey = dbKey; collection.dbKey = dbKey;
collection.hostKey = hostKey; collection.hostKey = hostKey;
collection.viewKey = 'list';
collection.indexes = collection.indexes || []; collection.indexes = collection.indexes || [];
delete collection.new; delete collection.new;

View File

@ -68,7 +68,8 @@
<!-- svelte-ignore a11y-label-has-associated-control --> <!-- svelte-ignore a11y-label-has-associated-control -->
<label class="field"> <label class="field">
<ObjectEditor bind:text={stage.data} <ObjectEditor
bind:text={stage.data}
on:inited={e => { on:inited={e => {
e.detail.editor.dispatch({ e.detail.editor.dispatch({
changes: { changes: {
@ -80,7 +81,6 @@
anchor: 3, anchor: 3,
}, },
}); });
e.detail.editor.focus();
}} /> }} />
</label> </label>
</Details> </Details>

View File

@ -11,9 +11,9 @@
import { convertLooseJson } from '$lib/strings'; import { convertLooseJson } from '$lib/strings';
import { FindItems, RemoveItemById, UpdateFoundDocument } from '$wails/go/app/App'; import { FindItems, RemoveItemById, UpdateFoundDocument } from '$wails/go/app/App';
import { EJSON } from 'bson'; import { EJSON } from 'bson';
import { onMount } from 'svelte';
export let collection; export let collection;
export let visible = false;
const defaults = { const defaults = {
query: '{}', query: '{}',
@ -42,7 +42,7 @@
} }
async function submitQuery() { async function submitQuery() {
if (querying) { if (querying || !visible) {
return; return;
} }
@ -159,7 +159,7 @@
} }
$: collection && refresh(); $: collection && refresh();
onMount(refresh); $: visible && refresh();
</script> </script>
<div class="find"> <div class="find">

View File

@ -1,7 +1,6 @@
<script> <script>
import BlankState from '$components/blankstate.svelte'; import BlankState from '$components/blankstate.svelte';
import TabBar from '$components/tabbar.svelte'; import TabBar from '$components/tabbar.svelte';
import { EventsOn } from '$wails/runtime/runtime';
import { tick } from 'svelte'; import { tick } from 'svelte';
import Aggregate from './aggregate.svelte'; import Aggregate from './aggregate.svelte';
@ -14,61 +13,44 @@
import Update from './update.svelte'; import Update from './update.svelte';
export let collection; export let collection;
export let hostKey; export let tab = 'stats';
export let dbKey;
export let collKey;
export let tab = 'find';
let find; const tabs = {
'stats': { icon: 'chart', title: 'Stats', component: Stats },
'find': { icon: 'db', title: 'Find', component: Find },
'insert': { icon: '+', title: 'Insert', component: Insert },
'update': { icon: 'edit', title: 'Update', component: Update },
'remove': { icon: 'trash', title: 'Remove', component: Remove },
'indexes': { icon: 'list', title: 'Indexes', component: Indexes },
'aggregate': { icon: 're', title: 'Aggregate', component: Aggregate },
'shell': { icon: 'shell', title: 'Shell', component: Shell },
};
$: if (collection) { for (const key of Object.keys(tabs)) {
collection.hostKey = hostKey; tabs[key].key = key;
collection.dbKey = dbKey;
collection.key = collKey;
} }
$: if (hostKey || dbKey || collKey) {
tab = 'find';
}
EventsOn('OpenCollectionTab', name => (tab = name || tab));
async function catchQuery(event) { async function catchQuery(event) {
tab = 'find'; tab = 'find';
await tick(); await tick();
find.performQuery(event.detail); tabs.find.instance.performQuery(event.detail);
} }
</script> </script>
<div class="view" class:empty={!collection}> <div class="view" class:empty={!collection}>
{#if collection} {#if collection}
{#key collection} <TabBar tabs={Object.values(tabs)} bind:selectedKey={tab} />
<TabBar
tabs={[
{ key: 'stats', icon: 'chart', title: 'Stats' },
{ key: 'find', icon: 'db', title: 'Find' },
{ key: 'insert', icon: '+', title: 'Insert' },
{ key: 'update', icon: 'edit', title: 'Update' },
{ key: 'remove', icon: 'trash', title: 'Remove' },
{ key: 'indexes', icon: 'list', title: 'Indexes' },
{ key: 'aggregate', icon: 're', title: 'Aggregate' },
{ key: 'shell', icon: 'shell', title: 'Shell' },
]}
bind:selectedKey={tab}
/>
<div class="container"> {#each Object.values(tabs) as view}
{#if tab === 'stats'} <Stats {collection} /> <div class="container" class:hidden={tab !== view.key}>
{:else if tab === 'find'} <Find {collection} bind:this={find} /> <svelte:component
{:else if tab === 'insert'} <Insert {collection} on:performFind={catchQuery} /> this={view.component}
{:else if tab === 'update'} <Update {collection} on:performFind={catchQuery} /> visible={tab === view.key}
{:else if tab === 'remove'} <Remove {collection} /> on:performFind={catchQuery}
{:else if tab === 'indexes'} <Indexes {collection} /> {collection}
{:else if tab === 'aggregate'} <Aggregate {collection} /> />
{:else if tab === 'shell'} <Shell {collection} />
{/if}
</div> </div>
{/key} {/each}
{:else} {:else}
<BlankState label="Select a collection to continue" /> <BlankState label="Select a collection to continue" />
{/if} {/if}
@ -92,6 +74,9 @@
min-height: 0; min-height: 0;
min-width: 0; min-width: 0;
} }
.container.hidden {
display: none;
}
.container > :global(*) { .container > :global(*) {
width: 100%; width: 100%;
} }

View File

@ -1,9 +1,9 @@
<script> <script>
import Icon from '$components/icon.svelte'; import Icon from '$components/icon.svelte';
import ObjectGrid from '$components/objectgrid.svelte'; import ObjectGrid from '$components/objectgrid.svelte';
import { onMount } from 'svelte';
export let collection; export let collection;
export let visible = false;
let activePath = []; let activePath = [];
let _indexes = []; let _indexes = [];
@ -11,6 +11,10 @@
let busy = false; let busy = false;
async function refresh() { async function refresh() {
if (!visible) {
return;
}
busy = 'Fetching indexes…'; busy = 'Fetching indexes…';
error = await collection.getIndexes(); error = await collection.getIndexes();
@ -49,7 +53,7 @@
} }
} }
onMount(refresh); $: visible && refresh();
</script> </script>
<div class="indexes"> <div class="indexes">

View File

@ -14,6 +14,7 @@
import Form from './components/form.svelte'; import Form from './components/form.svelte';
export let collection; export let collection;
export let visible = false;
const dispatch = createEventDispatcher(); const dispatch = createEventDispatcher();
const formValidity = {}; const formValidity = {};
@ -98,6 +99,8 @@
views.openConfig(collection); views.openConfig(collection);
} }
$: visible && editor.focus();
onMount(() => { onMount(() => {
if (collection.viewKey === 'list') { if (collection.viewKey === 'list') {
editor.dispatch({ editor.dispatch({
@ -110,7 +113,6 @@
anchor: 3, anchor: 3,
}, },
}); });
editor.focus();
} }
}); });
</script> </script>

View File

@ -6,6 +6,7 @@
import { onMount } from 'svelte'; import { onMount } from 'svelte';
export let collection; export let collection;
export let visible = false;
let json = ''; let json = '';
let many = true; let many = true;
@ -23,6 +24,8 @@
); );
} }
$: visible && editor.focus();
onMount(() => { onMount(() => {
editor.dispatch({ editor.dispatch({
changes: { changes: {
@ -34,7 +37,6 @@
anchor: 3, anchor: 3,
}, },
}); });
editor.focus();
}); });
</script> </script>

View File

@ -7,17 +7,15 @@
import Stats from './stats.svelte'; import Stats from './stats.svelte';
export let database; export let database;
export let hostKey;
export let dbKey;
export let tab = 'stats'; export let tab = 'stats';
$: if (database) { const tabs = {
database.hostKey = hostKey; 'stats': { icon: 'chart', title: 'Database stats', component: Stats },
database.dbKey = dbKey; 'shell': { icon: 'shell', title: 'Shell', component: Shell },
} };
$: if (hostKey || dbKey) { for (const key of Object.keys(tabs)) {
tab = 'stats'; tabs[key].key = key;
} }
EventsOn('OpenStatsTab', name => (tab = name || tab)); EventsOn('OpenStatsTab', name => (tab = name || tab));
@ -26,17 +24,13 @@
<div class="view" class:empty={!database}> <div class="view" class:empty={!database}>
{#if database} {#if database}
{#key database} {#key database}
<TabBar <TabBar tabs={Object.values(tabs)} bind:selectedKey={tab} />
tabs={[
{ key: 'stats', icon: 'chart', title: 'Database stats' }, {#each Object.values(tabs) as view}
{ key: 'shell', icon: 'shell', title: 'Shell' }, <div class="container" class:hidden={tab !== view.key}>
]} <svelte:component this={view.component} visible={tab === view.key} {database} />
bind:selectedKey={tab} /> </div>
<div class="container"> {/each}
{#if tab === 'stats'} <Stats {database} />
{:else if tab === 'shell'} <Shell {database} />
{/if}
</div>
{/key} {/key}
{:else} {:else}
<BlankState label="Select a database to continue" /> <BlankState label="Select a database to continue" />
@ -61,6 +55,9 @@
min-height: 0; min-height: 0;
min-width: 0; min-width: 0;
} }
.container.hidden {
display: none;
}
.container > :global(*) { .container > :global(*) {
width: 100%; width: 100%;
} }

View File

@ -9,15 +9,17 @@
import SystemInfo from './systeminfo.svelte'; import SystemInfo from './systeminfo.svelte';
export let host; export let host;
export let hostKey;
export let tab = 'status'; export let tab = 'status';
$: if (host) { const tabs = {
host.hostKey = hostKey; 'status': { icon: 'chart', title: 'Host status', component: Status },
} 'shell': { icon: 'shell', title: 'Shell', component: Shell },
'logs': { icon: 'doc', title: 'Logs', component: Logs },
'systemInfo': { icon: 'server', title: 'System info', component: SystemInfo },
};
$: if (hostKey) { for (const key of Object.keys(tabs)) {
tab = 'status'; tabs[key].key = key;
} }
EventsOn('OpenStatusTab', name => (tab = name || tab)); EventsOn('OpenStatusTab', name => (tab = name || tab));
@ -26,23 +28,13 @@
<div class="view" class:empty={!host}> <div class="view" class:empty={!host}>
{#if host} {#if host}
{#key host} {#key host}
<TabBar <TabBar tabs={Object.values(tabs)} bind:selectedKey={tab} />
tabs={[
{ key: 'status', icon: 'chart', title: 'Host status' },
{ key: 'shell', icon: 'shell', title: 'Shell' },
{ key: 'logs', icon: 'doc', title: 'Logs' },
{ key: 'systemInfo', icon: 'server', title: 'System info' },
]}
bind:selectedKey={tab}
/>
<div class="container"> {#each Object.values(tabs) as view}
{#if tab === 'status'} <Status {host} /> <div class="container" class:hidden={tab !== view.key}>
{:else if tab === 'logs'} <Logs {host} /> <svelte:component this={view.component} visible={tab === view.key} {host} />
{:else if tab === 'systemInfo'} <SystemInfo {host} /> </div>
{:else if tab === 'shell'} <Shell {host} /> {/each}
{/if}
</div>
{/key} {/key}
{:else} {:else}
<BlankState label="Select a host to continue" /> <BlankState label="Select a host to continue" />
@ -67,6 +59,9 @@
min-height: 0; min-height: 0;
min-width: 0; min-width: 0;
} }
.container.hidden {
display: none;
}
.container > :global(*) { .container > :global(*) {
width: 100%; width: 100%;
} }

View File

@ -8,6 +8,7 @@
import { onDestroy } from 'svelte'; import { onDestroy } from 'svelte';
export let host; export let host;
export let visible = false;
const autoReloadIntervals = [ 1, 2, 5, 10, 30, 60 ]; const autoReloadIntervals = [ 1, 2, 5, 10, 30, 60 ];
let filter = 'global'; let filter = 'global';
@ -31,6 +32,10 @@
} }
async function refresh() { async function refresh() {
if (!visible) {
return;
}
let _logs = []; let _logs = [];
({ logs: _logs, total, error } = await host.getLogs(filter)); ({ logs: _logs, total, error } = await host.getLogs(filter));
logs = []; logs = [];
@ -64,6 +69,8 @@
setTimeout(() => copySucceeded = false, 1500); setTimeout(() => copySucceeded = false, 1500);
} }
$: visible && !logs && refresh();
onDestroy(() => { onDestroy(() => {
if (interval) { if (interval) {
clearInterval(interval); clearInterval(interval);

View File

@ -9,10 +9,18 @@
import HostTree from './hosttree.svelte'; import HostTree from './hosttree.svelte';
let path = []; let path = [];
let prevPath = '';
let hostTab = ''; let hostTab = '';
let dbTab = ''; let dbTab = '';
let collTab = ''; let collTab = '';
$: if (path.join('.') !== prevPath) {
hostTab = 'status';
dbTab = 'stats';
collTab = 'stats';
prevPath = path.join('.');
}
$: activeHostKey = path[0]; $: activeHostKey = path[0];
$: activeDbKey = path[1]; $: activeDbKey = path[1];
$: activeCollKey = path[2]; $: activeCollKey = path[2];
@ -55,26 +63,17 @@
</div> </div>
{#if activeCollKey} {#if activeCollKey}
<CollectionView {#key activeCollKey}
collection={$hostTree[activeHostKey]?.databases[activeDbKey]?.collections?.[activeCollKey]} <CollectionView collection={$hostTree[activeHostKey]?.databases[activeDbKey]?.collections?.[activeCollKey]} bind:tab={collTab} />
hostKey={activeHostKey} {/key}
dbKey={activeDbKey}
collKey={activeCollKey}
bind:tab={collTab}
/>
{:else if activeDbKey} {:else if activeDbKey}
<DatabaseView {#key activeDbKey}
database={$hostTree[activeHostKey]?.databases[activeDbKey]} <DatabaseView database={$hostTree[activeHostKey]?.databases[activeDbKey]} bind:tab={dbTab} />
hostKey={activeHostKey} {/key}
dbKey={activeDbKey}
bind:tab={dbTab}
/>
{:else if activeHostKey} {:else if activeHostKey}
<HostView {#key activeHostKey}
host={$hostTree[activeHostKey]} <HostView host={$hostTree[activeHostKey]} bind:tab={hostTab} />
hostKey={activeHostKey} {/key}
bind:tab={hostTab}
/>
{/if} {/if}
<style> <style>

View File

@ -8,6 +8,7 @@
export let host = undefined; export let host = undefined;
export let database = undefined; export let database = undefined;
export let collection = undefined; export let collection = undefined;
export let visible = false;
const placeholder = '// Write your script here...'; const placeholder = '// Write your script here...';
const extensions = [ javascript() ]; const extensions = [ javascript() ];
@ -40,6 +41,8 @@
timeout = setTimeout(() => copySucceeded = false, 1500); timeout = setTimeout(() => copySucceeded = false, 1500);
} }
$: visible && editor.focus();
onMount(() => { onMount(() => {
editor.dispatch({ editor.dispatch({
changes: { changes: {
@ -56,6 +59,7 @@
}); });
editor.focus(); editor.focus();
}); });
onDestroy(() => clearTimeout(timeout)); onDestroy(() => clearTimeout(timeout));
</script> </script>