mirror of
https://github.com/garraflavatra/rolens.git
synced 2025-01-18 21:17:59 +00:00
Many at once - this seems a good time to commit
This commit is contained in:
parent
0b5ec78d8c
commit
9811235be7
@ -11,14 +11,20 @@
|
|||||||
export let activePath = [];
|
export let activePath = [];
|
||||||
export let level = 0;
|
export let level = 0;
|
||||||
export let striped = true;
|
export let striped = true;
|
||||||
|
export let hideObjectIndicators = false;
|
||||||
|
|
||||||
const dispatch = createEventDispatcher();
|
const dispatch = createEventDispatcher();
|
||||||
let childrenOpen = {};
|
let childrenOpen = {};
|
||||||
|
let _items = [];
|
||||||
|
|
||||||
$: _items = objectToArray(items).map(item => {
|
$: refresh(hideObjectIndicators, items);
|
||||||
item.children = objectToArray(item.children);
|
|
||||||
return item;
|
function refresh(hideObjectIndicators, items) {
|
||||||
});
|
_items = objectToArray(items).map(item => {
|
||||||
|
item.children = objectToArray(item.children);
|
||||||
|
return item;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function objectToArray(obj) {
|
function objectToArray(obj) {
|
||||||
if (Array.isArray(obj)) {
|
if (Array.isArray(obj)) {
|
||||||
@ -56,7 +62,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function doubleClick(itemKey) {
|
function doubleClick(itemKey) {
|
||||||
toggleChildren(itemKey, false);
|
// toggleChildren(itemKey, false);
|
||||||
dispatch('trigger', { level, itemKey });
|
dispatch('trigger', { level, itemKey });
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,17 +73,20 @@
|
|||||||
|
|
||||||
function formatValue(value) {
|
function formatValue(value) {
|
||||||
if (Array.isArray(value)) {
|
if (Array.isArray(value)) {
|
||||||
return '[...]';
|
return hideObjectIndicators ? '' : '[...]';
|
||||||
}
|
|
||||||
if (typeof value === 'object') {
|
|
||||||
return '{...}';
|
|
||||||
}
|
|
||||||
if (value === undefined || value === null) {
|
|
||||||
return '';
|
|
||||||
}
|
}
|
||||||
if (typeof value === 'number' || typeof value === 'boolean') {
|
if (typeof value === 'number' || typeof value === 'boolean') {
|
||||||
return String(value);
|
return String(value);
|
||||||
}
|
}
|
||||||
|
if ((value === undefined) || (value === null)) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
if (new Date(value).toString() !== 'Invalid Date') {
|
||||||
|
return new Date(value);
|
||||||
|
}
|
||||||
|
if (typeof value === 'object') {
|
||||||
|
return hideObjectIndicators ? '' : '{...}';
|
||||||
|
}
|
||||||
if (String(value).length <= 1000) {
|
if (String(value).length <= 1000) {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
@ -118,6 +127,7 @@
|
|||||||
{#if item.children && childrenOpen[item[key]]}
|
{#if item.children && childrenOpen[item[key]]}
|
||||||
<svelte:self
|
<svelte:self
|
||||||
{columns}
|
{columns}
|
||||||
|
{hideObjectIndicators}
|
||||||
{key}
|
{key}
|
||||||
{striped}
|
{striped}
|
||||||
path={[ ...path, item[key] ]}
|
path={[ ...path, item[key] ]}
|
||||||
@ -150,7 +160,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
td .value {
|
td .value {
|
||||||
height: 2.1ex;
|
height: 15px;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
export let key = 'id';
|
export let key = 'id';
|
||||||
export let activePath = [];
|
export let activePath = [];
|
||||||
export let striped = true;
|
export let striped = true;
|
||||||
|
export let hideObjectIndicators = false;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="grid">
|
<div class="grid">
|
||||||
@ -24,7 +25,16 @@
|
|||||||
|
|
||||||
<table>
|
<table>
|
||||||
<tbody>
|
<tbody>
|
||||||
<GridItems {items} {columns} {key} {striped} bind:activePath on:select on:trigger />
|
<GridItems
|
||||||
|
{items}
|
||||||
|
{columns}
|
||||||
|
{key}
|
||||||
|
{striped}
|
||||||
|
{hideObjectIndicators}
|
||||||
|
bind:activePath
|
||||||
|
on:select
|
||||||
|
on:trigger
|
||||||
|
/>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
58
frontend/src/components/icon.svelte
vendored
58
frontend/src/components/icon.svelte
vendored
@ -2,28 +2,36 @@
|
|||||||
export let name = '';
|
export let name = '';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if name === 'radio'}
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-radio"><circle cx="12" cy="12" r="2"></circle><path d="M16.24 7.76a6 6 0 0 1 0 8.49m-8.48-.01a6 6 0 0 1 0-8.49m11.31-2.82a10 10 0 0 1 0 14.14m-14.14 0a10 10 0 0 1 0-14.14"></path></svg>
|
{#if name === 'radio'}
|
||||||
{:else if name === 'chev-l'}
|
<circle cx="12" cy="12" r="2"></circle><path d="M16.24 7.76a6 6 0 0 1 0 8.49m-8.48-.01a6 6 0 0 1 0-8.49m11.31-2.82a10 10 0 0 1 0 14.14m-14.14 0a10 10 0 0 1 0-14.14"></path>
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-chevron-left"><polyline points="15 18 9 12 15 6"></polyline></svg>
|
{:else if name === 'chev-l'}
|
||||||
{:else if name === 'chev-r'}
|
<polyline points="15 18 9 12 15 6"></polyline>
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-chevron-right"><polyline points="9 18 15 12 9 6"></polyline></svg>
|
{:else if name === 'chev-r'}
|
||||||
{:else if name === 'chev-d'}
|
<polyline points="9 18 15 12 9 6"></polyline>
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-chevron-down"><polyline points="6 9 12 15 18 9"></polyline></svg>
|
{:else if name === 'chev-d'}
|
||||||
{:else if name === 'db'}
|
<polyline points="6 9 12 15 18 9"></polyline>
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-database"><ellipse cx="12" cy="5" rx="9" ry="3"></ellipse><path d="M21 12c0 1.66-4 3-9 3s-9-1.34-9-3"></path><path d="M3 5v14c0 1.66 4 3 9 3s9-1.34 9-3V5"></path></svg>
|
{:else if name === 'db'}
|
||||||
{:else if name === 'x'}
|
<ellipse cx="12" cy="5" rx="9" ry="3"></ellipse><path d="M21 12c0 1.66-4 3-9 3s-9-1.34-9-3"></path><path d="M3 5v14c0 1.66 4 3 9 3s9-1.34 9-3V5"></path>
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-x"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg>
|
{:else if name === 'x'}
|
||||||
{:else if name === '+'}
|
<line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line>
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-plus"><line x1="12" y1="5" x2="12" y2="19"></line><line x1="5" y1="12" x2="19" y2="12"></line></svg>
|
{:else if name === '+'}
|
||||||
{:else if name === '-'}
|
<line x1="12" y1="5" x2="12" y2="19"></line><line x1="5" y1="12" x2="19" y2="12"></line>
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-minus"><line x1="5" y1="12" x2="19" y2="12"></line></svg>
|
{:else if name === '-'}
|
||||||
{:else if name === 'reload'}
|
<line x1="5" y1="12" x2="19" y2="12"></line>
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-refresh-cw"><polyline points="23 4 23 10 17 10"></polyline><polyline points="1 20 1 14 7 14"></polyline><path d="M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15"></path></svg>
|
{:else if name === 'reload'}
|
||||||
{:else if name === 'clipboard'}
|
<polyline points="23 4 23 10 17 10"></polyline><polyline points="1 20 1 14 7 14"></polyline><path d="M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15"></path>
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-clipboard"><path d="M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2"></path><rect x="8" y="2" width="8" height="4" rx="1" ry="1"></rect></svg>
|
{:else if name === 'clipboard'}
|
||||||
{:else if name === 'edit'}
|
<path d="M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2"></path><rect x="8" y="2" width="8" height="4" rx="1" ry="1"></rect>
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-edit-3"><path d="M12 20h9"></path><path d="M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4L16.5 3.5z"></path></svg>
|
{:else if name === 'edit'}
|
||||||
{:else if name === 'check'}
|
<path d="M12 20h9"></path><path d="M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4L16.5 3.5z"></path>
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-check-circle"><path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"></path><polyline points="22 4 12 14.01 9 11.01"></polyline></svg>
|
{:else if name === 'check'}
|
||||||
{/if}
|
<path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"></path><polyline points="22 4 12 14.01 9 11.01"></polyline>
|
||||||
|
{:else if name === 'list'}
|
||||||
|
<path d="M8 6h13M8 12h13M8 18h13M3 6h.01M3 12h.01M3 18h.01"/>
|
||||||
|
{:else if name === 'table'}
|
||||||
|
<path d="M9 3H5a2 2 0 0 0-2 2v4m6-6h10a2 2 0 0 1 2 2v4M9 3v18m0 0h10a2 2 0 0 0 2-2V9M9 21H5a2 2 0 0 1-2-2V9m0 0h18"/>
|
||||||
|
{:else if name === 'cog'}
|
||||||
|
<circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"/>
|
||||||
|
{/if}
|
||||||
|
</svg>
|
||||||
|
@ -26,12 +26,13 @@
|
|||||||
|
|
||||||
function keydown(event) {
|
function keydown(event) {
|
||||||
if ((event.key === 'Escape') && (level === numberOfModalsOpen)) {
|
if ((event.key === 'Escape') && (level === numberOfModalsOpen)) {
|
||||||
|
event.preventDefault();
|
||||||
show = false;
|
show = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<svelte:window on:keydown|preventDefault={keydown} />
|
<svelte:window on:keydown={keydown} />
|
||||||
|
|
||||||
{#if show}
|
{#if show}
|
||||||
<div class="modal outer" on:mousedown|self={() => show = false} transition:fade>
|
<div class="modal outer" on:mousedown|self={() => show = false} transition:fade>
|
||||||
@ -94,7 +95,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
header {
|
header {
|
||||||
border-bottom: 1px solid #ccc;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
@ -114,6 +114,9 @@
|
|||||||
.content.padded {
|
.content.padded {
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
}
|
}
|
||||||
|
header + .content.padded {
|
||||||
|
border-top: 1px solid #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
footer {
|
footer {
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
export let data = [];
|
export let data = [];
|
||||||
export let key = '_id';
|
export let key = '_id';
|
||||||
export let activePath = [];
|
export let activePath = [];
|
||||||
|
export let hideObjectIndicators = false;
|
||||||
|
|
||||||
const columns = [
|
const columns = [
|
||||||
{ key: 'key', label: 'Key' },
|
{ key: 'key', label: 'Key' },
|
||||||
@ -76,4 +77,5 @@
|
|||||||
bind:activePath
|
bind:activePath
|
||||||
{columns}
|
{columns}
|
||||||
{items}
|
{items}
|
||||||
|
{hideObjectIndicators}
|
||||||
/>
|
/>
|
||||||
|
@ -23,14 +23,9 @@
|
|||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.tabs {
|
|
||||||
border-bottom: 1px solid #ccc;
|
|
||||||
padding: 0 0.5rem;
|
|
||||||
}
|
|
||||||
.tabs ul {
|
.tabs ul {
|
||||||
overflow-x: scroll;
|
overflow-x: scroll;
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 0.5rem;
|
|
||||||
list-style: none;
|
list-style: none;
|
||||||
}
|
}
|
||||||
.tabs li {
|
.tabs li {
|
||||||
@ -41,11 +36,13 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 0.7rem 1rem;
|
padding: 0.7rem 1rem;
|
||||||
border: 1px solid #ccc;
|
border: 1px solid #ccc;
|
||||||
border-bottom: none;
|
border-right: none;
|
||||||
border-radius: 5px 5px 0 0;
|
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
}
|
}
|
||||||
|
.tabs li:last-child button {
|
||||||
|
border-right: 1px solid #ccc;
|
||||||
|
}
|
||||||
.tabs li.active button {
|
.tabs li.active button {
|
||||||
color: #fff;
|
color: #fff;
|
||||||
background-color: #00008b;
|
background-color: #00008b;
|
||||||
|
@ -0,0 +1,54 @@
|
|||||||
|
<script>
|
||||||
|
import TabBar from '../../../components/tabbar.svelte';
|
||||||
|
import Modal from '../../../components/modal.svelte';
|
||||||
|
|
||||||
|
export let show = false;
|
||||||
|
export let activeView = 'list';
|
||||||
|
export let config = {
|
||||||
|
hideObjectIndicators: false,
|
||||||
|
columns: [],
|
||||||
|
};
|
||||||
|
|
||||||
|
let activeTab = activeView || 'list';
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<Modal title="View configuration" bind:show contentPadding={false}>
|
||||||
|
<TabBar
|
||||||
|
tabs={[
|
||||||
|
{ key: 'list', title: 'List view' },
|
||||||
|
{ key: 'table', title: 'Table view' },
|
||||||
|
]}
|
||||||
|
bind:selectedKey={activeTab}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div class="options">
|
||||||
|
{#if activeTab === 'list'}
|
||||||
|
<div class="flex">
|
||||||
|
<input type="checkbox" id="hideObjectIndicators" bind:checked={config.hideObjectIndicators} />
|
||||||
|
<label for="hideObjectIndicators">
|
||||||
|
Hide object indicators ({'{...}'} and [...]) in list view and show nothing instead
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
{:else if activeTab === 'table'}
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
value={config.columns?.map(c => c.key).join(', ') || ''}
|
||||||
|
on:input={e => config.columns = e.currentTarget.value?.split(',').map(k => ({ key: k.trim() })) || ''}
|
||||||
|
/>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
</Modal>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.options {
|
||||||
|
padding: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex {
|
||||||
|
display: flex;
|
||||||
|
gap: 0.5rem;
|
||||||
|
}
|
||||||
|
.flex + .flex {
|
||||||
|
margin-top: 1rem;
|
||||||
|
}
|
||||||
|
</style>
|
@ -1,10 +1,12 @@
|
|||||||
<script>
|
<script>
|
||||||
import { FindItems, RemoveItemById } from '../../../../wailsjs/go/app/App';
|
import { FindItems, Hosts, RemoveItemById, UpdateHost } from '../../../../wailsjs/go/app/App';
|
||||||
import CodeExample from '../../../components/code-example.svelte';
|
import CodeExample from '../../../components/code-example.svelte';
|
||||||
import { input } from '../../../actions';
|
import { input } from '../../../actions';
|
||||||
import ObjectGrid from '../../../components/objectgrid.svelte';
|
import ObjectGrid from '../../../components/objectgrid.svelte';
|
||||||
import Icon from '../../../components/icon.svelte';
|
import Icon from '../../../components/icon.svelte';
|
||||||
import ObjectViewer from '../../../components/objectviewer.svelte';
|
import ObjectViewer from '../../../components/objectviewer.svelte';
|
||||||
|
import FindViewConfigModal from './find-viewconfig.svelte';
|
||||||
|
import { onMount } from 'svelte';
|
||||||
|
|
||||||
export let collection;
|
export let collection;
|
||||||
|
|
||||||
@ -17,13 +19,30 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
let form = { ...defaults };
|
let form = { ...defaults };
|
||||||
|
let view = 'list';
|
||||||
let result = {};
|
let result = {};
|
||||||
let submittedForm = {};
|
let submittedForm = {};
|
||||||
let queryField;
|
let queryField;
|
||||||
let activePath = [];
|
let activePath = [];
|
||||||
let objectViewerData;
|
let objectViewerData;
|
||||||
|
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})` : ''};`;
|
$: 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})` : ''};`;
|
||||||
|
|
||||||
|
$: collection && refresh();
|
||||||
|
$: updateConfig(viewConfig);
|
||||||
|
|
||||||
|
async function getViewConfig() {
|
||||||
|
try {
|
||||||
|
const hosts = await Hosts();
|
||||||
|
viewConfig = hosts?.[collection.hostKey]?.databases?.[collection.dbKey]?.collections?.[collection.key]?.viewConfig || {};
|
||||||
|
console.log(hosts, viewConfig);
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function submitQuery() {
|
async function submitQuery() {
|
||||||
activePath = [];
|
activePath = [];
|
||||||
result = await FindItems(collection.hostKey, collection.dbKey, collection.key, JSON.stringify(form));
|
result = await FindItems(collection.hostKey, collection.dbKey, collection.key, JSON.stringify(form));
|
||||||
@ -33,6 +52,27 @@
|
|||||||
resetFocus();
|
resetFocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function refresh() {
|
||||||
|
await getViewConfig();
|
||||||
|
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() {
|
function prev() {
|
||||||
form.skip -= form.limit;
|
form.skip -= form.limit;
|
||||||
if (form.skip < 0) {
|
if (form.skip < 0) {
|
||||||
@ -66,10 +106,16 @@
|
|||||||
objectViewerData = item;
|
objectViewerData = item;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function toggleView() {
|
||||||
|
view = view === 'table' ? 'list' : 'table';
|
||||||
|
}
|
||||||
|
|
||||||
export function performQuery(q) {
|
export function performQuery(q) {
|
||||||
form = { ...defaults, ...q };
|
form = { ...defaults, ...q };
|
||||||
submitQuery();
|
submitQuery();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onMount(refresh);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="find">
|
<div class="find">
|
||||||
@ -111,7 +157,12 @@
|
|||||||
<div class="result">
|
<div class="result">
|
||||||
<div class="grid">
|
<div class="grid">
|
||||||
{#key result}
|
{#key result}
|
||||||
<ObjectGrid data={result.results} bind:activePath on:trigger={e => openJson(e.detail?.itemKey)} />
|
<ObjectGrid
|
||||||
|
data={result.results}
|
||||||
|
hideObjectIndicators={viewConfig?.hideObjectIndicators}
|
||||||
|
bind:activePath
|
||||||
|
on:trigger={e => openJson(e.detail?.itemKey)}
|
||||||
|
/>
|
||||||
{/key}
|
{/key}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -122,13 +173,19 @@
|
|||||||
{/key}
|
{/key}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<button class="btn danger" on:click={removeActive} disabled={!activePath?.length}>
|
<button class="btn" on:click={() => viewConfigModalOpen = true} title="Configure view">
|
||||||
|
<Icon name="cog" />
|
||||||
|
</button>
|
||||||
|
<button class="btn" on:click={toggleView} title="Toggle view">
|
||||||
|
<Icon name={view} />
|
||||||
|
</button>
|
||||||
|
<button class="btn danger" on:click={removeActive} disabled={!activePath?.length} title="Drop selected item">
|
||||||
<Icon name="-" />
|
<Icon name="-" />
|
||||||
</button>
|
</button>
|
||||||
<button class="btn" on:click={prev} disabled={!submittedForm.limit || (submittedForm.skip <= 0) || !result?.results?.length}>
|
<button class="btn" on:click={prev} disabled={!submittedForm.limit || (submittedForm.skip <= 0) || !result?.results?.length} title="Previous {form.limit} items">
|
||||||
<Icon name="chev-l" />
|
<Icon name="chev-l" />
|
||||||
</button>
|
</button>
|
||||||
<button class="btn" on:click={next} disabled={!submittedForm.limit || ((result?.results?.length || 0) < submittedForm.limit) || !result?.results?.length}>
|
<button class="btn" on:click={next} disabled={!submittedForm.limit || ((result?.results?.length || 0) < submittedForm.limit) || !result?.results?.length} title="Next {form.limit} items">
|
||||||
<Icon name="chev-r" />
|
<Icon name="chev-r" />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@ -137,6 +194,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ObjectViewer bind:data={objectViewerData} />
|
<ObjectViewer bind:data={objectViewerData} />
|
||||||
|
<FindViewConfigModal bind:show={viewConfigModalOpen} activeView={view} bind:config={viewConfig} />
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.find {
|
.find {
|
||||||
|
@ -68,3 +68,7 @@ input:not([type="checkbox"]) {
|
|||||||
min-width: 100px;
|
min-width: 100px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
input[type="checkbox"] {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
2
frontend/wailsjs/go/app/App.d.ts
vendored
2
frontend/wailsjs/go/app/App.d.ts
vendored
@ -32,4 +32,6 @@ export function RemoveItemById(arg1:string,arg2:string,arg3:string,arg4:string):
|
|||||||
|
|
||||||
export function RemoveItems(arg1:string,arg2:string,arg3:string,arg4:string,arg5:boolean):Promise<number>;
|
export function RemoveItems(arg1:string,arg2:string,arg3:string,arg4:string,arg5:boolean):Promise<number>;
|
||||||
|
|
||||||
|
export function UpdateHost(arg1:string,arg2:string):Promise<void>;
|
||||||
|
|
||||||
export function UpdateItems(arg1:string,arg2:string,arg3:string,arg4:string):Promise<number>;
|
export function UpdateItems(arg1:string,arg2:string,arg3:string,arg4:string):Promise<number>;
|
||||||
|
@ -58,6 +58,10 @@ export function RemoveItems(arg1, arg2, arg3, arg4, arg5) {
|
|||||||
return window['go']['app']['App']['RemoveItems'](arg1, arg2, arg3, arg4, arg5);
|
return window['go']['app']['App']['RemoveItems'](arg1, arg2, arg3, arg4, arg5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function UpdateHost(arg1, arg2) {
|
||||||
|
return window['go']['app']['App']['UpdateHost'](arg1, arg2);
|
||||||
|
}
|
||||||
|
|
||||||
export function UpdateItems(arg1, arg2, arg3, arg4) {
|
export function UpdateItems(arg1, arg2, arg3, arg4) {
|
||||||
return window['go']['app']['App']['UpdateItems'](arg1, arg2, arg3, arg4);
|
return window['go']['app']['App']['UpdateItems'](arg1, arg2, arg3, arg4);
|
||||||
}
|
}
|
||||||
|
@ -16,8 +16,19 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Host struct {
|
type Host struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
URI string `json:"uri"`
|
URI string `json:"uri"`
|
||||||
|
Databases map[string]struct {
|
||||||
|
Collections map[string]struct {
|
||||||
|
ViewConfig struct {
|
||||||
|
HideObjectIndicators bool `json:"hideObjectIndicators"`
|
||||||
|
Columns []struct {
|
||||||
|
Key string `json:"key"`
|
||||||
|
Width int64 `json:"width"`
|
||||||
|
} `json:"columns"`
|
||||||
|
} `json:"viewConfig"`
|
||||||
|
} `json:"collections"`
|
||||||
|
} `json:"databases"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateHostsFile(newData map[string]Host) error {
|
func updateHostsFile(newData map[string]Host) error {
|
||||||
@ -81,7 +92,7 @@ func (a *App) AddHost(jsonData string) error {
|
|||||||
Type: runtime.InfoDialog,
|
Type: runtime.InfoDialog,
|
||||||
Title: "Malformed JSON",
|
Title: "Malformed JSON",
|
||||||
})
|
})
|
||||||
return errors.New("could not retrieve existing host list")
|
return errors.New("invalid JSON")
|
||||||
}
|
}
|
||||||
|
|
||||||
id, err := uuid.NewRandom()
|
id, err := uuid.NewRandom()
|
||||||
@ -93,8 +104,6 @@ func (a *App) AddHost(jsonData string) error {
|
|||||||
return errors.New("could not generate a UUID")
|
return errors.New("could not generate a UUID")
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println(hosts)
|
|
||||||
|
|
||||||
hosts[id.String()] = newHost
|
hosts[id.String()] = newHost
|
||||||
err = updateHostsFile(hosts)
|
err = updateHostsFile(hosts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -108,6 +117,39 @@ func (a *App) AddHost(jsonData string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *App) UpdateHost(hostKey string, jsonData string) error {
|
||||||
|
hosts, err := a.Hosts()
|
||||||
|
if err != nil {
|
||||||
|
runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{
|
||||||
|
Type: runtime.InfoDialog,
|
||||||
|
Title: "Could not retrieve hosts",
|
||||||
|
})
|
||||||
|
return errors.New("could not retrieve existing host list")
|
||||||
|
}
|
||||||
|
|
||||||
|
var host Host
|
||||||
|
err = json.Unmarshal([]byte(jsonData), &host)
|
||||||
|
if err != nil {
|
||||||
|
runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{
|
||||||
|
Type: runtime.InfoDialog,
|
||||||
|
Title: "Malformed JSON",
|
||||||
|
})
|
||||||
|
return errors.New("invalid JSON")
|
||||||
|
}
|
||||||
|
|
||||||
|
hosts[hostKey] = host
|
||||||
|
err = updateHostsFile(hosts)
|
||||||
|
if err != nil {
|
||||||
|
runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{
|
||||||
|
Type: runtime.InfoDialog,
|
||||||
|
Title: "Could not update host list",
|
||||||
|
})
|
||||||
|
return errors.New("could not update host list")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (a *App) RemoveHost(key string) error {
|
func (a *App) RemoveHost(key string) error {
|
||||||
hosts, err := a.Hosts()
|
hosts, err := a.Hosts()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
Loading…
Reference in New Issue
Block a user