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

Aggregation

This commit is contained in:
2023-02-18 15:41:53 +01:00
parent 715519b06d
commit 1b2315b0b0
14 changed files with 526 additions and 8 deletions

View File

@ -0,0 +1,127 @@
<script>
import Details from '$components/details.svelte';
import Icon from '$components/icon.svelte';
import Modal from '$components/modal.svelte';
import MongoCollation from '$components/mongo-collation.svelte';
import input from '$lib/actions/input';
import { aggregationStageDocumentationURL, aggregationStages } from '$lib/mongo';
import { Aggregate } from '$wails/go/app/App';
import { BrowserOpenURL } from '$wails/runtime/runtime';
import { onMount } from 'svelte';
export let collection;
const options = {};
let stages = [];
let settingsModalOpen = false;
$: invalid = !stages.length || stages.some(stage => {
try {
JSON.parse(stage.data);
return false;
}
catch {
return true;
}
});
function addStage() {
stages = [ ...stages, { type: '$match' } ];
}
function deleteStage(index) {
stages = [ ...stages.slice(0, index), ...stages.slice(index + 1) ];
}
function openStageDocs(type) {
const url = aggregationStageDocumentationURL(type);
BrowserOpenURL(url);
}
async function run() {
const pipeline = stages.map(stage => ({ [stage.type]: JSON.parse(stage.data) }));
await Aggregate(collection.hostKey, collection.dbKey, collection.key, JSON.stringify(pipeline), JSON.stringify(options));
}
onMount(() => {
if (!stages.length) {
stages = [ { type: '$match' } ];
}
});
</script>
<form class="aggregate" on:submit|preventDefault={run}>
<div>
{#each stages as stage, index}
<Details title="#{index + 1}: {stage.type}" deletable={true} on:delete={() => deleteStage(index)} initiallyOpen>
<label class="field">
<span class="label">Stage type</span>
<select bind:value={stage.type}>
{#each aggregationStages as value}
<option {value}>{value}</option>
{/each}
</select>
<button class="btn secondary" type="button" on:click={() => openStageDocs(stage.type)} title="Open documentation about {stage.type || 'this stage'} on mongodb.org">
<Icon name="info" />
</button>
</label>
<label class="field">
<textarea bind:value={stage.data} class="code" use:input={{ type: 'json' }}></textarea>
</label>
</Details>
{/each}
<button class="btn-sm" type="button" on:click={addStage}>
<Icon name="+" /> Add stage
</button>
</div>
<div class="controls">
<div>
<button class="btn" type="submit" disabled={invalid}>
<Icon name="play" /> Run pipeline
</button>
<button class="btn" type="button" on:click={() => settingsModalOpen = true}>
<Icon name="cog" /> Settings
</button>
</div>
</div>
</form>
<Modal title="Advanced settings" bind:show={settingsModalOpen}>
<div class="settinggrid">
<label for="allowDiskUse">Allow disk use</label>
<div class="field">
<span class="checkbox">
<input type="checkbox" id="allowDiskUse" bind:checked={options.allowDiskUse} />
</span>
</div>
</div>
<Details title="Set custom collation options">
<MongoCollation bind:collation={options.collation} />
</Details>
</Modal>
<style>
.aggregate {
display: grid;
gap: 0.5rem;
grid-template: 1fr auto / 1fr;
}
.settinggrid {
margin-bottom: 0.5rem;
}
.controls {
display: flex;
justify-content: space-between;
align-items: center;
}
textarea {
min-height: 100px;
margin-top: 0.5rem;
}
</style>

View File

@ -3,6 +3,7 @@
import TabBar from '$components/tabbar.svelte';
import { EventsOn } from '$wails/runtime/runtime';
import { tick } from 'svelte';
import Aggregate from './aggregate.svelte';
import ViewConfig from './components/viewconfig.svelte';
import Find from './find.svelte';
import Indexes from './indexes.svelte';
@ -46,12 +47,13 @@
{#if collection}
{#key collection}
<TabBar tabs={[
{ key: 'stats', title: 'Stats' },
{ key: 'find', title: 'Find' },
{ key: 'insert', title: 'Insert' },
{ key: 'update', title: 'Update' },
{ key: 'remove', title: 'Remove' },
{ key: 'indexes', title: 'Indexes' },
{ 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' },
]} bind:selectedKey={tab} />
<div class="container">
@ -61,6 +63,7 @@
{:else if tab === 'update'} <Update {collection} on:performFind={catchQuery} />
{:else if tab === 'remove'} <Remove {collection} />
{:else if tab === 'indexes'} <Indexes {collection} />
{:else if tab === 'aggregate'} <Aggregate {collection} />
{/if}
</div>
{/key}