1
0
mirror of https://github.com/garraflavatra/rolens.git synced 2025-07-19 14:14:05 +00:00

Save queries

This commit is contained in:
2023-02-15 17:00:53 +01:00
parent 3291bc845f
commit 5f358885a3
12 changed files with 419 additions and 37 deletions

View File

@ -0,0 +1,134 @@
<script>
import Icon from '../../../../components/icon.svelte';
import { createEventDispatcher } from 'svelte';
import Modal from '../../../../components/modal.svelte';
import { input } from '../../../../lib/actions';
import queries from '../../../../lib/stores/queries';
import Grid from '../../../../components/grid.svelte';
import Hint from '../../../../components/hint.svelte';
export let queryToSave = undefined;
export let collection = {};
export let show = false;
const dispatch = createEventDispatcher();
let gridSelectedPath = [];
let selectedKey = '';
function submit() {
if (queryToSave) {
queryToSave.hostKey = collection.hostKey;
queryToSave.dbKey = collection.dbKey;
queryToSave.collKey = collection.key;
const newId = queries.create(queryToSave);
if (newId) {
dispatch('created', newId);
queryToSave = undefined;
selectedKey = newId;
select();
}
}
else {
select();
}
}
function select() {
dispatch('select', selectedKey);
show = false;
}
function gridSelect(event) {
if (event?.detail?.level === 0) {
selectedKey = event.detail.itemKey;
if (queryToSave) {
queryToSave.name = event.detail.itemKey;
}
}
}
function gridTrigger(event) {
gridSelect(event);
select();
}
async function gridRemove(event) {
await queries.remove(event.detail);
}
$: if (queryToSave && !queryToSave.name) {
queryToSave.name = 'New query';
}
$: if (queryToSave?.name) {
gridSelectedPath = [ queryToSave.name ];
}
$: if (selectedKey) {
gridSelectedPath = [ selectedKey ];
}
</script>
<Modal bind:show title={queryToSave ? 'Save query' : 'Load query'} width="500px">
<form on:submit|preventDefault={submit}>
{#if queryToSave}
<label class="field queryname">
<span class="label">Query name</span>
<input type="text" bind:value={queryToSave.name} use:input={{ autofocus: true }} />
</label>
<label class="field">
<textarea bind:value={queryToSave.remarks} placeholder="Remarks…" use:input></textarea>
</label>
{/if}
<div class="querylist">
<Grid
columns={[ { key: 'name', title: 'Query name' } ]}
items={$queries}
showHeaders={true}
canRemoveItems={true}
bind:activePath={gridSelectedPath}
on:select={gridSelect}
on:trigger={gridTrigger}
on:removeItem={gridRemove}
/>
</div>
{#if queryToSave}
<button class="btn" type="submit">
<Icon name="save" /> Save query
</button>
{#if Object.keys($queries).includes(queryToSave.name)}
<Hint>
You are about to <strong>overwrite</strong> a saved query. Rename it
if you do not want to overwrite.
</Hint>
{/if}
{:else}
<button class="btn" type="submit" disabled={!selectedKey}>
<Icon name="upload" /> Load query
</button>
{/if}
</form>
</Modal>
<style>
.field, .querylist {
margin-bottom: 0.5rem;
}
textarea {
min-height: 100px;
}
.querylist {
border: 1px solid #ccc;
min-height: 200px;
}
.btn + :global(.hint) {
margin-top: 0.5rem;
}
</style>

View File

@ -9,6 +9,8 @@
import Icon from '../../../components/icon.svelte';
import ObjectGrid from '../../../components/objectgrid.svelte';
import views from '../../../lib/stores/views';
import QueryChooser from './components/querychooser.svelte';
import queries from '../../../lib/stores/queries';
// import ObjectViewer from '../../../components/objectviewer.svelte';
export let collection;
@ -28,6 +30,9 @@
let queryField;
let activePath = [];
let objectViewerData;
let queryToSave;
let showQueryChooser = false;
$: viewsForCollection = views.forCollection(collection.hostKey, collection.dbKey, collection.key);
$: 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;
@ -50,6 +55,23 @@
}
}
function loadQuery() {
queryToSave = undefined;
showQueryChooser = true;
}
function saveQuery() {
queryToSave = form;
showQueryChooser = true;
}
function queryChosen(event) {
if ($queries[event?.detail]) {
form = { ...$queries[event?.detail] };
submitQuery();
}
}
function prev() {
form.skip -= form.limit;
if (form.skip < 0) {
@ -131,13 +153,22 @@
<span class="label">Limit</span>
<input type="number" min="0" bind:value={form.limit} use:input placeholder={defaults.limit} list="limits" />
</label>
</div>
<button type="submit" class="btn">Run</button>
<div class="form-row three">
<CodeExample {code} />
<button class="btn" type="button" on:click={loadQuery} title="Load query…">
<Icon name="upload" />
</button>
<button class="btn" type="button" on:click={saveQuery} title="Save query as…">
<Icon name="save" />
</button>
<button type="submit" class="btn" title="Run query">
<Icon name="play" /> Run
</button>
</div>
</form>
<CodeExample {code} />
<div class="result">
<div class="grid">
{#key result}
@ -198,6 +229,12 @@
</div>
</div>
<QueryChooser
bind:queryToSave
bind:show={showQueryChooser}
on:select={queryChosen}
/>
<!-- <ObjectViewer bind:data={objectViewerData} /> -->
<datalist id="limits">
@ -218,19 +255,23 @@
.find {
display: grid;
gap: 0.5rem;
grid-template: auto auto 1fr / 1fr;
grid-template: auto 1fr / 1fr;
}
.form-row {
display: grid;
gap: 0.5rem;
margin-bottom: 0.5rem;
}
.form-row.one {
grid-template: 1fr / 3fr 2fr;
margin-bottom: 0.5rem;
}
.form-row.two {
grid-template: 1fr / 5fr 1fr 1fr 1fr;
grid-template: 1fr / 5fr 1fr 1fr;
}
.form-row.three {
margin-bottom: 0rem;
grid-template: 1fr / 1fr repeat(3, auto);
}
.result {