mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-04-20 07:46:00 +00:00
open JSON array as tabular view
This commit is contained in:
@@ -14,7 +14,6 @@
|
||||
export let isJsonView = false;
|
||||
|
||||
let filter;
|
||||
|
||||
</script>
|
||||
|
||||
<SearchBoxWrapper>
|
||||
|
||||
@@ -147,19 +147,34 @@
|
||||
<HorizontalSplitter initialValue="300px" bind:size={managerSize} hideFirst={$collapsedLeftColumnStore}>
|
||||
<div class="left" slot="1">
|
||||
<WidgetColumnBar>
|
||||
<WidgetColumnBarItem title="Columns" name="columns" height="45%" skip={freeTableColumn || isFormView}>
|
||||
<WidgetColumnBarItem
|
||||
title="Columns"
|
||||
name="columns"
|
||||
height="45%"
|
||||
show={(!freeTableColumn || isDynamicStructure) && !isFormView}
|
||||
>
|
||||
<ColumnManager {...$$props} {managerSize} {isJsonView} />
|
||||
</WidgetColumnBarItem>
|
||||
|
||||
<WidgetColumnBarItem title="Filters" name="jsonFilters" height="30%" skip={!isDynamicStructure}>
|
||||
<WidgetColumnBarItem
|
||||
title="Filters"
|
||||
name="jsonFilters"
|
||||
height="30%"
|
||||
skip={!isDynamicStructure || !display?.filterable}
|
||||
>
|
||||
<JsonViewFilters {...$$props} {managerSize} />
|
||||
</WidgetColumnBarItem>
|
||||
|
||||
<WidgetColumnBarItem title="Columns" name="freeColumns" height="40%" skip={!freeTableColumn}>
|
||||
<WidgetColumnBarItem
|
||||
title="Columns"
|
||||
name="freeColumns"
|
||||
height="40%"
|
||||
show={freeTableColumn && !isDynamicStructure}
|
||||
>
|
||||
<FreeTableColumnEditor {...$$props} {managerSize} />
|
||||
</WidgetColumnBarItem>
|
||||
|
||||
<WidgetColumnBarItem title="Filters" name="filters" height="30%" skip={!isFormView}>
|
||||
<WidgetColumnBarItem title="Filters" name="filters" height="30%" show={isFormView}>
|
||||
<FormViewFilters {...$$props} {managerSize} driver={formDisplay?.driver} />
|
||||
</WidgetColumnBarItem>
|
||||
|
||||
@@ -168,12 +183,12 @@
|
||||
name="references"
|
||||
height="30%"
|
||||
collapsed={isDetailView}
|
||||
skip={!showReferences || !display?.hasReferences}
|
||||
show={showReferences && display?.hasReferences}
|
||||
>
|
||||
<ReferenceManager {...$$props} {managerSize} />
|
||||
</WidgetColumnBarItem>
|
||||
|
||||
<WidgetColumnBarItem title="Macros" name="macros" skip={!showMacros} collapsed>
|
||||
<WidgetColumnBarItem title="Macros" name="macros" show={showMacros} collapsed>
|
||||
<MacroManager {...$$props} {managerSize} />
|
||||
</WidgetColumnBarItem>
|
||||
</WidgetColumnBar>
|
||||
|
||||
@@ -25,4 +25,5 @@
|
||||
label="Array({value.length})"
|
||||
bracketOpen="["
|
||||
bracketClose="]"
|
||||
elementValue={value}
|
||||
/>
|
||||
@@ -10,9 +10,11 @@
|
||||
export let getValue = key => key;
|
||||
export let getPreviewValue = getValue;
|
||||
export let expanded = false, expandable = true;
|
||||
export let elementValue = null;
|
||||
|
||||
const context = getContext('json-tree-context-key');
|
||||
setContext('json-tree-context-key', { ...context, colon })
|
||||
const elementData=getContext('json-tree-element-data');
|
||||
|
||||
$: slicedKeys = expanded ? keys: previewKeys.slice(0, 5);
|
||||
|
||||
@@ -28,6 +30,12 @@
|
||||
expanded = true;
|
||||
}
|
||||
|
||||
let domElement;
|
||||
|
||||
$: if (domElement && elementData && elementValue) {
|
||||
elementData.set(domElement, elementValue)
|
||||
}
|
||||
|
||||
</script>
|
||||
<style>
|
||||
label {
|
||||
@@ -51,7 +59,7 @@
|
||||
position: relative;
|
||||
}
|
||||
</style>
|
||||
<li class:indent={isParentExpanded}>
|
||||
<li class:indent={isParentExpanded} class:jsonValueHolder={!!elementValue} bind:this={domElement}>
|
||||
<label>
|
||||
{#if expandable && isParentExpanded}
|
||||
<JSONArrow on:click={toggleExpand} {expanded} />
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
import JSONNode from './JSONNode.svelte';
|
||||
import { setContext } from 'svelte';
|
||||
import contextMenu, { getContextMenu } from '../utility/contextMenu';
|
||||
import openNewTab from '../utility/openNewTab';
|
||||
import _ from 'lodash';
|
||||
|
||||
setContext('json-tree-context-key', {});
|
||||
|
||||
@@ -15,10 +17,45 @@
|
||||
export let isInserted;
|
||||
export let isModified;
|
||||
|
||||
const elementData = new WeakMap();
|
||||
|
||||
if (elementData) {
|
||||
setContext('json-tree-element-data', elementData);
|
||||
}
|
||||
|
||||
const parentMenu = getContextMenu();
|
||||
|
||||
function getElementMenu({ targetElement }) {
|
||||
if (!targetElement) return null;
|
||||
const closest = targetElement.closest('.jsonValueHolder');
|
||||
if (!closest) return;
|
||||
const value = elementData.get(closest);
|
||||
|
||||
if (value && _.isArray(value)) {
|
||||
return {
|
||||
text: 'Open as data sheet',
|
||||
onClick: () => {
|
||||
openNewTab(
|
||||
{
|
||||
title: 'Data #',
|
||||
icon: 'img free-table',
|
||||
tabComponent: 'FreeTableTab',
|
||||
props: {},
|
||||
},
|
||||
{
|
||||
editor: {
|
||||
rows: value,
|
||||
structure: { __isDynamicStructure: true, columns: [] },
|
||||
},
|
||||
}
|
||||
);
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<ul use:contextMenu={[parentMenu, menu]} class:isDeleted class:isInserted class:isModified>
|
||||
<ul use:contextMenu={[parentMenu, menu, getElementMenu]} class:isDeleted class:isInserted class:isModified>
|
||||
<JSONNode {key} {value} isParentExpanded={true} isParentArray={false} {expanded} {labelOverride} />
|
||||
</ul>
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
left={$currentDropDownMenu.left}
|
||||
top={$currentDropDownMenu.top}
|
||||
items={$currentDropDownMenu.items}
|
||||
targetElement={$currentDropDownMenu.targetElement}
|
||||
on:close={() => ($currentDropDownMenu = null)}
|
||||
/>
|
||||
{/if}
|
||||
|
||||
@@ -53,7 +53,6 @@
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<script>
|
||||
@@ -69,6 +68,7 @@
|
||||
export let top;
|
||||
export let left;
|
||||
export let onCloseParent;
|
||||
export let targetElement;
|
||||
|
||||
let element;
|
||||
|
||||
@@ -104,7 +104,7 @@
|
||||
submenuOffset = hoverOffset;
|
||||
}, 500);
|
||||
|
||||
$: extracted = extractMenuItems(items);
|
||||
$: extracted = extractMenuItems(items, { targetElement });
|
||||
$: compacted = _.compact(extracted.map(x => mapItem(x, $commandsCustomized)));
|
||||
$: filtered = compacted.filter(x => !x.disabled || !x.hideDisabled);
|
||||
|
||||
@@ -121,7 +121,6 @@
|
||||
document.removeEventListener('mousedown', handleClickOutside, true);
|
||||
};
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<ul class="dropDownMenuMarker" style={`left: ${left}px; top: ${top}px`} bind:this={element}>
|
||||
@@ -217,5 +216,4 @@
|
||||
position: relative;
|
||||
left: 15px;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
@@ -119,7 +119,7 @@
|
||||
e.preventDefault();
|
||||
const left = e.pageX;
|
||||
const top = e.pageY;
|
||||
currentDropDownMenu.set({ left, top, items: _.isFunction(menu) ? menu() : menu });
|
||||
currentDropDownMenu.set({ left, top, items: menu, targetElement: e.target });
|
||||
};
|
||||
|
||||
const handleKeyDown = (data, hash, keyString, keyCode, event) => {
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import { createFreeTableModel, runMacro } from 'dbgate-datalib';
|
||||
import { createFreeTableModel, FreeTableGridDisplay, runMacro } from 'dbgate-datalib';
|
||||
import { setContext } from 'svelte';
|
||||
import { writable } from 'svelte/store';
|
||||
import registerCommand from '../commands/registerCommand';
|
||||
@@ -87,6 +87,9 @@
|
||||
setContext('collapsedLeftColumnStore', collapsedLeftColumnStore);
|
||||
|
||||
registerMenu({ command: 'freeTable.save', tag: 'save' });
|
||||
|
||||
// display is overridden in FreeTableGridCore, this is because of column manager
|
||||
$: display = new FreeTableGridDisplay($modelState.value, $config, config.update, null, null);
|
||||
</script>
|
||||
|
||||
{#if isLoading}
|
||||
@@ -104,5 +107,7 @@
|
||||
freeTableColumn
|
||||
showMacros
|
||||
onRunMacro={handleRunMacro}
|
||||
isDynamicStructure={$modelState.value?.structure?.__isDynamicStructure}
|
||||
{display}
|
||||
/>
|
||||
{/if}
|
||||
|
||||
@@ -15,7 +15,7 @@ export default function contextMenu(node, items = []) {
|
||||
if (items) {
|
||||
const left = e.pageX;
|
||||
const top = e.pageY;
|
||||
currentDropDownMenu.set({ left, top, items });
|
||||
currentDropDownMenu.set({ left, top, items, targetElement: e.target });
|
||||
}
|
||||
};
|
||||
|
||||
@@ -31,12 +31,12 @@ export default function contextMenu(node, items = []) {
|
||||
};
|
||||
}
|
||||
|
||||
function doExtractMenuItems(menu, res) {
|
||||
function doExtractMenuItems(menu, res, options) {
|
||||
if (_.isFunction(menu)) {
|
||||
doExtractMenuItems(menu(), res);
|
||||
doExtractMenuItems(menu(options), res, options);
|
||||
} else if (_.isArray(menu)) {
|
||||
for (const item of menu) {
|
||||
doExtractMenuItems(item, res);
|
||||
doExtractMenuItems(item, res, options);
|
||||
}
|
||||
} else if (_.isPlainObject(menu) && !menu._skip) {
|
||||
res.push(menu);
|
||||
@@ -77,9 +77,9 @@ function processTags(items) {
|
||||
return res;
|
||||
}
|
||||
|
||||
export function extractMenuItems(menu) {
|
||||
export function extractMenuItems(menu, options = null) {
|
||||
let res = [];
|
||||
doExtractMenuItems(menu, res);
|
||||
doExtractMenuItems(menu, res, options);
|
||||
res = processTags(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
export let title;
|
||||
export let name;
|
||||
export let skip = false;
|
||||
export let show = true;
|
||||
export let height = null;
|
||||
export let collapsed = null;
|
||||
|
||||
@@ -27,12 +28,12 @@
|
||||
{
|
||||
collapsed,
|
||||
height,
|
||||
skip,
|
||||
skip: skip || !show,
|
||||
},
|
||||
dynamicProps
|
||||
);
|
||||
|
||||
$: updateWidgetItemDefinition(widgetItemIndex, { collapsed: !visible, height, skip });
|
||||
$: updateWidgetItemDefinition(widgetItemIndex, { collapsed: !visible, height, skip: skip || !show });
|
||||
|
||||
$: setInitialSize(height, $widgetColumnBarHeight);
|
||||
|
||||
@@ -46,7 +47,7 @@
|
||||
let visible = !collapsed;
|
||||
</script>
|
||||
|
||||
{#if !skip}
|
||||
{#if !skip && show}
|
||||
<WidgetTitle on:click={() => (visible = !visible)}>{title}</WidgetTitle>
|
||||
|
||||
{#if visible}
|
||||
|
||||
Reference in New Issue
Block a user