run macros in table data editor #68

This commit is contained in:
Jan Prochazka
2021-03-25 19:07:51 +01:00
parent 2afa7a5f58
commit 952bdc4baa
9 changed files with 184 additions and 15 deletions

View File

@@ -3,7 +3,6 @@ import { recentDatabases, currentDatabase, getRecentDatabases } from '../stores'
import registerCommand from './registerCommand';
currentDatabase.subscribe(value => {
console.log('DB', value);
if (!value) return;
recentDatabases.update(list => {
const res = [

View File

@@ -7,8 +7,12 @@ import {
findExistingChangeSetItem,
getChangeSetInsertedRows,
GridDisplay,
MacroDefinition,
MacroSelectedCell,
revertChangeSetRowChanges,
setChangeSetValue,
compileMacroFunction,
runMacroOnValue,
} from 'dbgate-datalib';
import Grider, { GriderRowStatus } from './Grider';
@@ -21,8 +25,18 @@ export default class ChangeSetGrider extends Grider {
private rowStatusCache;
private rowDefinitionsCache;
private batchChangeSet: ChangeSet;
private _errors = null;
private compiledMacroFunc;
constructor(public sourceRows: any[], public changeSetState, public dispatchChangeSet, public display: GridDisplay) {
constructor(
public sourceRows: any[],
public changeSetState,
public dispatchChangeSet,
public display: GridDisplay,
public macro: MacroDefinition,
public macroArgs: {},
public selectedCells: MacroSelectedCell[]
) {
super();
this.changeSet = changeSetState && changeSetState.value;
this.insertedRows = getChangeSetInsertedRows(this.changeSet, display.baseTable);
@@ -32,6 +46,11 @@ export default class ChangeSetGrider extends Grider {
this.rowStatusCache = {};
this.rowDefinitionsCache = {};
this.batchChangeSet = null;
this.compiledMacroFunc = compileMacroFunction(macro, this._errors);
}
get errors() {
return this._errors;
}
getRowSource(index: number) {
@@ -49,7 +68,11 @@ export default class ChangeSetGrider extends Grider {
const insertedRowIndex = this.getInsertedRowIndex(index);
const rowDefinition = this.display.getChangeSetRow(row, insertedRowIndex);
const [matchedField, matchedChangeSetItem] = findExistingChangeSetItem(this.changeSet, rowDefinition);
const rowUpdated = matchedChangeSetItem ? { ...row, ...matchedChangeSetItem.fields } : row;
const rowUpdated = matchedChangeSetItem
? { ...row, ...matchedChangeSetItem.fields }
: this.compiledMacroFunc
? { ...row }
: row;
let status = 'regular';
if (matchedChangeSetItem && matchedField == 'updates') status = 'updated';
if (matchedField == 'deletes') status = 'deleted';
@@ -59,6 +82,23 @@ export default class ChangeSetGrider extends Grider {
modifiedFields:
matchedChangeSetItem && matchedChangeSetItem.fields ? new Set(Object.keys(matchedChangeSetItem.fields)) : null,
};
if (this.compiledMacroFunc) {
for (const cell of this.selectedCells) {
if (cell.row != index) continue;
const newValue = runMacroOnValue(
this.compiledMacroFunc,
this.macroArgs,
rowUpdated[cell.column],
index,
rowUpdated,
cell.column,
this._errors
);
rowUpdated[cell.column] = newValue;
}
}
this.rowDataCache[index] = rowUpdated;
this.rowStatusCache[index] = rowStatus;
this.rowDefinitionsCache[index] = rowDefinition;

View File

@@ -1,6 +1,15 @@
<script lang="ts">
import { setContext } from 'svelte';
import { writable } from 'svelte/store';
import { runMacroOnChangeSet } from 'dbgate-datalib';
import HorizontalSplitter from '../elements/HorizontalSplitter.svelte';
import VerticalSplitter from '../elements/VerticalSplitter.svelte';
import FormViewFilters from '../formview/FormViewFilters.svelte';
import { extractMacroValuesForMacro } from '../freetable/FreeTableGrid.svelte';
import MacroDetail from '../freetable/MacroDetail.svelte';
import MacroManager from '../freetable/MacroManager.svelte';
import createRef from '../utility/createRef';
import WidgetColumnBar from '../widgets/WidgetColumnBar.svelte';
import WidgetColumnBarItem from '../widgets/WidgetColumnBarItem.svelte';
import ColumnManager from './ColumnManager.svelte';
@@ -11,13 +20,37 @@
export let formViewComponent;
export let formDisplay;
export let display;
export let changeSetState;
export let dispatchChangeSet;
export let isDetailView = false;
export let showReferences = false;
export let showMacros;
let selectedCellsPublished = [];
const selectedMacro = writable(null);
setContext('selectedMacro', selectedMacro);
const macroValues = writable({});
setContext('macroValues', macroValues);
let managerSize;
$: isFormView = !!(formDisplay && formDisplay.config && formDisplay.config.isFormView);
const handleExecuteMacro = () => {
const newChangeSet = runMacroOnChangeSet(
$selectedMacro,
extractMacroValuesForMacro($macroValues, $selectedMacro),
selectedCellsPublished,
changeSetState?.value,
display
);
if (newChangeSet) {
dispatchChangeSet({ type: 'set', value: newChangeSet });
}
$selectedMacro = null;
};
</script>
<HorizontalSplitter initialValue="300px" bind:size={managerSize}>
@@ -40,18 +73,36 @@
>
<ReferenceManager {...$$props} {managerSize} />
</WidgetColumnBarItem>
<WidgetColumnBarItem title="Macros" name="macros" skip={!showMacros} collapsed={isDetailView}>
<MacroManager {...$$props} {managerSize} macroCondition={macro => macro.type == 'transformValue'} />
</WidgetColumnBarItem>
</WidgetColumnBar>
</div>
<svelte:fragment slot="2">
{#if isFormView}
<svelte:component this={formViewComponent} {...$$props} />
{:else}
<svelte:component
this={gridCoreComponent}
{...$$props}
formViewAvailable={!!formViewComponent && !!formDisplay}
/>
{/if}
<VerticalSplitter initialValue="70%" isSplitter={!!$selectedMacro && !isFormView && showMacros}>
<svelte:fragment slot="1">
{#if isFormView}
<svelte:component this={formViewComponent} {...$$props} />
{:else}
<svelte:component
this={gridCoreComponent}
{...$$props}
formViewAvailable={!!formViewComponent && !!formDisplay}
onSelectionChanged={value => (selectedCellsPublished = value)}
macroValues={extractMacroValuesForMacro($macroValues, $selectedMacro)}
macroPreview={$selectedMacro}
{selectedCellsPublished}
/>
{/if}
</svelte:fragment>
<svelte:fragment slot="2">
{#if $selectedMacro}
<MacroDetail onExecute={handleExecuteMacro} />
{/if}
</svelte:fragment>
</VerticalSplitter>
</svelte:fragment>
</HorizontalSplitter>

View File

@@ -66,11 +66,26 @@
export let changeSetState;
export let dispatchChangeSet;
export let macroPreview;
export let macroValues;
export let selectedCellsPublished;
// export let onChangeGrider = undefined;
let loadedRows = [];
// $: console.log('loadedRows BIND', loadedRows);
$: grider = new ChangeSetGrider(loadedRows, changeSetState, dispatchChangeSet, display);
$: grider = new ChangeSetGrider(
loadedRows,
changeSetState,
dispatchChangeSet,
display,
macroPreview,
macroValues,
selectedCellsPublished
);
// $: console.log('GRIDER', grider);
// $: if (onChangeGrider) onChangeGrider(grider);
async function handleConfirmSql(sql) {
const resp = await axiosInstance.request({
@@ -162,6 +177,7 @@
onOpenQuery={openQuery}
onOpenActiveChart={openActiveChart}
bind:loadedRows
frameSelection={!!macroPreview}
{grider}
onSave={handleSave}
/>

View File

@@ -119,6 +119,7 @@
{display}
{formDisplay}
showReferences
showMacros
onReferenceSourceChanged={reference ? handleReferenceSourceChanged : null}
onReferenceClick={value => {
if (value && value.referenceId && reference && reference.referenceId == value.referenceId) {

View File

@@ -1,5 +1,5 @@
<script lang="ts" context="module">
function extractMacroValuesForMacro(macroValues, macro) {
export function extractMacroValuesForMacro(macroValues, macro) {
// return {};
if (!macro) return {};
return {

View File

@@ -11,11 +11,17 @@
let filter = '';
export let managerSize;
export let macroCondition;
</script>
<ManagerInnerContainer width={managerSize}>
<SearchBoxWrapper>
<SearchInput placeholder="Search macros" bind:value={filter} />
</SearchBoxWrapper>
<AppObjectList list={_.sortBy(macros, 'title')} module={macroAppObject} {filter} groupFunc={data => data.group} />
<AppObjectList
list={_.sortBy(macros, 'title').filter(x => (macroCondition ? macroCondition(x) : true))}
module={macroAppObject}
{filter}
groupFunc={data => data.group}
/>
</ManagerInnerContainer>