From 6703950734fe43d1ecc1283bb433255b21d8e0e3 Mon Sep 17 00:00:00 2001 From: Romein van Buren Date: Fri, 20 Jan 2023 13:54:57 +0100 Subject: [PATCH] A lot of improvements --- frontend/src/components/grid-items.svelte | 13 +-- frontend/src/components/grid.svelte | 23 +++++ frontend/src/components/icon.svelte | 8 ++ frontend/src/components/objectgrid.svelte | 8 +- frontend/src/components/objectviewer.svelte | 20 ++-- .../collection/find-viewconfig.svelte | 81 +++++++++++++-- .../connection/collection/find.svelte | 99 +++++++++++++------ .../connection/collection/indexes.svelte | 15 ++- .../connection/collection/insert.svelte | 5 +- .../connection/collection/remove.svelte | 5 +- .../connection/collection/update.svelte | 4 +- frontend/src/reset.css | 2 +- frontend/src/style.css | 5 + frontend/src/utils.js | 21 ++++ 14 files changed, 248 insertions(+), 61 deletions(-) create mode 100644 frontend/src/utils.js diff --git a/frontend/src/components/grid-items.svelte b/frontend/src/components/grid-items.svelte index 598d809..d54d320 100644 --- a/frontend/src/components/grid-items.svelte +++ b/frontend/src/components/grid-items.svelte @@ -2,6 +2,7 @@ import { contextMenu } from '../stores'; import { createEventDispatcher } from 'svelte'; import Icon from './icon.svelte'; + import { resolveKeypath } from '../utils'; export let items = []; export let columns = []; @@ -30,7 +31,7 @@ if (Array.isArray(obj)) { return obj; } - else if (typeof obj === 'object') { + else if ((typeof obj === 'object') && (obj !== null)) { return Object.entries(obj).map(([ k, item ]) => ({ ...item, [key]: k })); } else { @@ -81,10 +82,10 @@ if ((value === undefined) || (value === null)) { return ''; } - if (new Date(value).toString() !== 'Invalid Date') { - return new Date(value); - } - if (typeof value === 'object') { + // if (new Date(value).toString() !== 'Invalid Date') { + // return new Date(value); + // } + if ((typeof value === 'object') && (value !== null)) { return hideObjectIndicators ? '' : '{...}'; } if (String(value).length <= 1000) { @@ -115,7 +116,7 @@ {#each columns as column, columnIndex} - {@const value = item[column.key]} + {@const value = column.key?.includes('.') ? resolveKeypath(item, column.key) : item[column.key]}
{formatValue(value)} diff --git a/frontend/src/components/grid.svelte b/frontend/src/components/grid.svelte index ffc9591..2d0002f 100644 --- a/frontend/src/components/grid.svelte +++ b/frontend/src/components/grid.svelte @@ -9,6 +9,7 @@ export let activePath = []; export let striped = true; export let hideObjectIndicators = false; + export let showHeaders = false;
@@ -24,6 +25,17 @@ {/if} + {#if showHeaders && columns.some(col => col.title)} + + + + {#each columns as column} + + {/each} + + + {/if} + diff --git a/frontend/src/components/icon.svelte b/frontend/src/components/icon.svelte index 1c18de1..0c97326 100644 --- a/frontend/src/components/icon.svelte +++ b/frontend/src/components/icon.svelte @@ -11,6 +11,12 @@ {:else if name === 'chev-d'} + {:else if name === 'chev-u'} + + {:else if name === 'chevs-l'} + + {:else if name === 'chevs-r'} + {:else if name === 'db'} {:else if name === 'x'} @@ -33,5 +39,7 @@ {:else if name === 'cog'} + {:else if name === 'zap'} + {/if} diff --git a/frontend/src/components/objectgrid.svelte b/frontend/src/components/objectgrid.svelte index 3a073e7..558acad 100644 --- a/frontend/src/components/objectgrid.svelte +++ b/frontend/src/components/objectgrid.svelte @@ -42,10 +42,10 @@ } return 'integer'; } - else if (new Date(value).toString() !== 'Invalid Date') { - return 'date'; - } - else if (typeof value === 'object') { + // else if (new Date(value).toString() !== 'Invalid Date') { + // return 'date'; + // } + else if ((typeof value === 'object') && (value !== null)) { const keys = Object.keys(value); return `object (${keys.length} item${keys.length === 1 ? '' : 's'})`; } diff --git a/frontend/src/components/objectviewer.svelte b/frontend/src/components/objectviewer.svelte index 621a304..ce9c79b 100644 --- a/frontend/src/components/objectviewer.svelte +++ b/frontend/src/components/objectviewer.svelte @@ -8,9 +8,19 @@ let copySucceeded = false; let timeout; + let _data; + + $: if (data) { + _data = JSON.parse(JSON.stringify(data)); + for (const key of Object.keys(_data)) { + if (typeof _data[key] === 'undefined') { + delete _data[key]; + } + } + } async function copy() { - await navigator.clipboard.writeText(JSON.stringify(data)); + await navigator.clipboard.writeText(JSON.stringify(_data)); copySucceeded = true; timeout = setTimeout(() => copySucceeded = false, 1500); } @@ -19,7 +29,7 @@ {#if data} - +
- +
@@ -37,14 +47,10 @@ .objectviewer { position: relative; } - .code { - padding: 1rem; - } .buttons { position: absolute; top: 0; right: 0; - margin: 1rem; } .buttons button { margin-left: 1rem; diff --git a/frontend/src/organisms/connection/collection/find-viewconfig.svelte b/frontend/src/organisms/connection/collection/find-viewconfig.svelte index 629b6b7..405a907 100644 --- a/frontend/src/organisms/connection/collection/find-viewconfig.svelte +++ b/frontend/src/organisms/connection/collection/find-viewconfig.svelte @@ -1,6 +1,7 @@ @@ -30,11 +71,31 @@ {:else if activeTab === 'table'} - c.key).join(', ') || ''} - on:input={e => config.columns = e.currentTarget.value?.split(',').map(k => ({ key: k.trim() })) || ''} - /> + {#each config.columns as column, columnIndex} +
+ + + + + +
+ {/each} + + {/if}
@@ -48,7 +109,11 @@ display: flex; gap: 0.5rem; } - .flex + .flex { - margin-top: 1rem; + + .column { + display: grid; + grid-template: 1fr / 1fr repeat(4, auto); + gap: 0.5rem; + margin-bottom: 0.5rem; } diff --git a/frontend/src/organisms/connection/collection/find.svelte b/frontend/src/organisms/connection/collection/find.svelte index e600ce4..f3c45f7 100644 --- a/frontend/src/organisms/connection/collection/find.svelte +++ b/frontend/src/organisms/connection/collection/find.svelte @@ -7,6 +7,7 @@ import ObjectViewer from '../../../components/objectviewer.svelte'; import FindViewConfigModal from './find-viewconfig.svelte'; import { onMount } from 'svelte'; + import Grid from '../../../components/grid.svelte'; export let collection; @@ -28,6 +29,8 @@ let viewConfigModalOpen = false; let viewConfig = {}; $: code = `db.${collection.key}.find(${form.query || '{}'}${form.fields && form.fields !== '{}' ? `, ${form.fields}` : ''}).sort(${form.sort})${form.skip ? `.skip(${form.skip})` : ''}${form.limit ? `.limit(${form.limit})` : ''};`; + $: lastPage = (submittedForm.limit && result?.results?.length) ? Math.max(0, Math.ceil((result.total - submittedForm.limit) / submittedForm.limit)) : 0; + $: activePage = (submittedForm.limit && submittedForm.skip && result?.results?.length) ? submittedForm.skip / submittedForm.limit : 0; $: collection && refresh(); $: updateConfig(viewConfig); @@ -43,6 +46,21 @@ } } + async function updateConfig(viewConfig) { + try { + const hosts = await Hosts(); + hosts[collection.hostKey].databases = hosts[collection.hostKey].databases || {}; + hosts[collection.hostKey].databases[collection.dbKey] = hosts[collection.hostKey].databases[collection.dbKey] || {}; + hosts[collection.hostKey].databases[collection.dbKey].collections = hosts[collection.hostKey].databases[collection.dbKey].collections || {}; + hosts[collection.hostKey].databases[collection.dbKey].collections[collection.key] = hosts[collection.hostKey].databases[collection.dbKey].collections[collection.key] || {}; + hosts[collection.hostKey].databases[collection.dbKey].collections[collection.key].viewConfig = viewConfig; + await UpdateHost(collection.hostKey, JSON.stringify(hosts[collection.hostKey])); + } + catch (e) { + console.error(e); + } + } + async function submitQuery() { activePath = []; result = await FindItems(collection.hostKey, collection.dbKey, collection.key, JSON.stringify(form)); @@ -57,22 +75,6 @@ await submitQuery(); } - async function updateConfig(viewConfig) { - try { - const hosts = await Hosts(); - hosts[collection.hostKey].databases = hosts[collection.hostKey].databases || {}; - hosts[collection.hostKey].databases[collection.dbKey] = hosts[collection.hostKey].databases[collection.dbKey] || {}; - hosts[collection.hostKey].databases[collection.dbKey].collections = hosts[collection.hostKey].databases[collection.dbKey].collections || {}; - hosts[collection.hostKey].databases[collection.dbKey].collections[collection.key] = hosts[collection.hostKey].databases[collection.dbKey].collections[collection.key] || {}; - hosts[collection.hostKey].databases[collection.dbKey].collections[collection.key].viewConfig = viewConfig; - await UpdateHost(collection.hostKey, JSON.stringify(hosts[collection.hostKey])); - } - catch (e) { - console.error(e); - } - console.log(viewConfig); - } - function prev() { form.skip -= form.limit; if (form.skip < 0) { @@ -86,6 +88,16 @@ submitQuery(); } + function first() { + form.skip = 0; + submitQuery(); + } + + function last() { + form.skip = lastPage * submittedForm.limit; + submitQuery(); + } + async function removeActive() { if (!activePath[0]) { return; @@ -140,12 +152,12 @@ @@ -157,12 +169,23 @@
{#key result} - openJson(e.detail?.itemKey)} - /> + {#if view === 'table'} + ({ key: c.key, title: c.key })) || []} + showHeaders={true} + items={result.results || []} + bind:activePath + on:trigger={e => openJson(e.detail?.itemKey)} + /> + {:else if view === 'list'} + openJson(e.detail?.itemKey)} + /> + {/if} {/key}
@@ -177,24 +200,44 @@ - + - +
- + + + + {#each [ 1, 5, 10, 25, 50, 100, 200 ] as value} + + +{#if submittedForm?.limit} + + {#each Array(lastPage).fill('').map((_, i) => i * submittedForm.limit) as value} + +{/if}
{column.title || ''}