mirror of
https://github.com/garraflavatra/rolens.git
synced 2025-04-16 15:51:03 +00:00
157 lines
4.2 KiB
Svelte
157 lines
4.2 KiB
Svelte
<script>
|
|
import Details from '$components/details.svelte';
|
|
import Icon from '$components/icon.svelte';
|
|
import Modal from '$components/modal.svelte';
|
|
import ObjectEditor from '$components/objecteditor.svelte';
|
|
import { aggregationStageDocumentationURL, aggregationStages } from '$lib/mongo';
|
|
import Collation from '$lib/mongo/collation.svelte';
|
|
import { jsonLooseParse, looseJsonIsValid } from '$lib/strings';
|
|
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 => !stage.data || !looseJsonIsValid(stage.data));
|
|
|
|
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 => {
|
|
return { [stage.type]: jsonLooseParse(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="button secondary" type="button" on:click={() => openStageDocs(stage.type)} title="Open documentation about {stage.type || 'this stage'} on mongodb.org">
|
|
<Icon name="?" />
|
|
</button>
|
|
</label>
|
|
|
|
<!-- svelte-ignore a11y-label-has-associated-control -->
|
|
<label class="field">
|
|
<ObjectEditor
|
|
bind:text={stage.data}
|
|
on:inited={e => {
|
|
e.detail.editor.dispatch({
|
|
changes: {
|
|
from: 0,
|
|
to: e.detail.editor.state.doc.length,
|
|
insert: '{\n\t\n}',
|
|
},
|
|
selection: {
|
|
anchor: 3,
|
|
},
|
|
});
|
|
}} />
|
|
</label>
|
|
</Details>
|
|
{/each}
|
|
|
|
<button class="button-small" type="button" on:click={addStage}>
|
|
<Icon name="+" /> Add stage
|
|
</button>
|
|
</div>
|
|
|
|
<div class="controls">
|
|
<div>
|
|
<button class="button" type="submit" disabled={invalid}>
|
|
<Icon name="play" /> Run pipeline
|
|
</button>
|
|
<button class="button" type="button" on:click={() => settingsModalOpen = true}>
|
|
<Icon name="cog" /> Settings
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
|
|
<Modal title="Advanced aggregation settings" show={settingsModalOpen} on:close={() => settingsModalOpen = false}>
|
|
<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">
|
|
<Collation bind:collation={options.collation} />
|
|
</Details>
|
|
</Modal>
|
|
|
|
<style>
|
|
.aggregate {
|
|
display: grid;
|
|
gap: 0.5rem;
|
|
grid-template: 1fr auto / 1fr;
|
|
}
|
|
|
|
.aggregate :global(details) {
|
|
position: relative;
|
|
z-index: 2;
|
|
}
|
|
.aggregate :global(details + details::before) {
|
|
content: "";
|
|
position: absolute;
|
|
top: -0.6rem;
|
|
left: 50%;
|
|
width: 1px;
|
|
height: 0.6rem;
|
|
background-color: #888;
|
|
z-index: 1;
|
|
}
|
|
|
|
.settinggrid {
|
|
margin-bottom: 0.5rem;
|
|
}
|
|
|
|
.controls {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
}
|
|
|
|
.field + .field {
|
|
margin-top: 0.5rem;
|
|
}
|
|
</style>
|