collection json view

This commit is contained in:
Jan Prochazka 2021-04-05 11:15:59 +02:00
parent ff52430e1e
commit 554be51546
10 changed files with 195 additions and 18 deletions

View File

@ -294,6 +294,20 @@ export abstract class GridDisplay {
this.reload();
}
showFilter(uniqueName) {
this.setConfig(cfg => {
if (!cfg.filters.uniqueName)
return {
...cfg,
filters: {
..._.omitBy(cfg.filters, v => !v),
[uniqueName]: '',
},
};
return cfg;
});
}
removeFilter(uniqueName) {
this.setConfig(cfg => ({
...cfg,
@ -547,4 +561,11 @@ export abstract class GridDisplay {
formViewKeyRequested: null,
}));
}
switchToJsonView() {
this.setConfig(cfg => ({
...cfg,
isJsonView: true,
}));
}
}

View File

@ -1,5 +1,5 @@
<script context="module" lang="ts">
function buildCondition(props) {
export function buildGridMongoCondition(props) {
const filters = props?.display?.config?.filters;
const conditions = [];
@ -27,7 +27,7 @@
: undefined;
}
async function loadDataPage(props, offset, limit) {
export async function loadCollectionDataPage(props, offset, limit) {
const { conid, database } = props;
const response = await axiosInstance.request({
@ -42,7 +42,7 @@
pureName: props.pureName,
limit,
skip: offset,
condition: buildCondition(props),
condition: buildGridMongoCondition(props),
},
},
});
@ -72,7 +72,7 @@
options: {
pureName: props.pureName,
countDocuments: true,
condition: buildCondition(props),
condition: buildGridMongoCondition(props),
},
},
});
@ -211,7 +211,7 @@
<LoadingDataGridCore
{...$$props}
{loadDataPage}
loadDataPage={loadCollectionDataPage}
{dataPageAvailable}
{loadRowCount}
onExportGrid={exportGrid}

View File

@ -10,6 +10,7 @@
export let managerSize;
export let display: GridDisplay;
export let isJsonView = false;
let filter;
</script>
@ -23,6 +24,6 @@
{#each display
?.getColumns(filter)
?.filter(column => filterName(filter, column.columnName)) || [] as column (column.uniqueName)}
<ColumnManagerRow {display} {column} />
<ColumnManagerRow {display} {column} {isJsonView} />
{/each}
</ManagerInnerContainer>

View File

@ -6,6 +6,7 @@
export let column;
export let display;
export let isJsonView = false;
</script>
<div
@ -13,21 +14,25 @@
on:click={e => {
// @ts-ignore
if (e.target.closest('.expandColumnIcon')) return;
display.focusColumn(column.uniqueName);
if (isJsonView) display.showFilter(column.uniqueName);
else display.focusColumn(column.uniqueName);
}}
>
<span class="expandColumnIcon">
<span class="expandColumnIcon" style={`margin-right: ${5 + (column.uniquePath.length - 1) * 10}px`}>
<FontIcon
icon={column.isExpandable ? plusExpandIcon(display.isExpandedColumn(column.uniqueName)) : 'icon invisible-box'}
on:click={() => display.toggleExpandedColumn(column.uniqueName)}
/>
</span>
<input
type="checkbox"
style={`margin-left: ${5 + (column.uniquePath.length - 1) * 10}px`}
checked={column.isChecked}
on:change={() => display.setColumnVisibility(column.uniquePath, !column.isChecked)}
/>
{#if isJsonView}
<FontIcon icon="img column" />
{:else}
<input
type="checkbox"
checked={column.isChecked}
on:change={() => display.setColumnVisibility(column.uniquePath, !column.isChecked)}
/>
{/if}
<ColumnLabel {...column} />
</div>

View File

@ -29,7 +29,8 @@
export let config;
export let gridCoreComponent;
export let formViewComponent;
export let formViewComponent = null;
export let jsonViewComponent = null;
export let formDisplay;
export let display;
export let changeSetState;
@ -55,6 +56,7 @@
let managerSize;
$: isFormView = !!(formDisplay && formDisplay.config && formDisplay.config.isFormView);
$: isJsonView = !!config.isJsonView;
const handleExecuteMacro = () => {
onRunMacro($selectedMacro, extractMacroValuesForMacro($macroValues, $selectedMacro), selectedCellsPublished());
@ -83,7 +85,7 @@
height={showReferences ? '40%' : '60%'}
skip={freeTableColumn || isFormView}
>
<ColumnManager {...$$props} {managerSize} />
<ColumnManager {...$$props} {managerSize} {isJsonView} />
</WidgetColumnBarItem>
<WidgetColumnBarItem title="Filters" name="jsonFilters" height="30%" skip={!isDynamicStructure}>
@ -118,11 +120,14 @@
<svelte:fragment slot="1">
{#if isFormView}
<svelte:component this={formViewComponent} {...$$props} />
{:else if isJsonView}
<svelte:component this={jsonViewComponent} {...$$props} bind:loadedRows />
{:else}
<svelte:component
this={gridCoreComponent}
{...$$props}
formViewAvailable={!!formViewComponent && !!formDisplay}
jsonViewAvailable={!!jsonViewComponent}
macroValues={extractMacroValuesForMacro($macroValues, $selectedMacro)}
macroPreview={$selectedMacro}
bind:loadedRows

View File

@ -131,6 +131,15 @@
onClick: () => getCurrentDataGrid().switchToForm(),
});
registerCommand({
id: 'dataGrid.switchToJson',
category: 'Data grid',
name: 'Switch to JSON',
keyText: 'F4',
testEnabled: () => getCurrentDataGrid()?.jsonViewEnabled(),
onClick: () => getCurrentDataGrid().switchToJson(),
});
registerCommand({
id: 'dataGrid.filterSelected',
category: 'Data grid',
@ -265,6 +274,7 @@
export let onOpenQuery = null;
export let onOpenActiveChart = null;
export let formViewAvailable = false;
export let jsonViewAvailable=false;
export let errorMessage = undefined;
export let isLoadedAll;
@ -409,12 +419,20 @@
return formViewAvailable && display.baseTable && display.baseTable.primaryKey;
}
export function jsonViewEnabled() {
return jsonViewAvailable;
}
export function switchToForm() {
const cell = currentCell;
const rowData = isRegularCell(cell) ? grider.getRowData(cell[0]) : null;
display.switchToFormView(rowData);
}
export function switchToJson() {
display.switchToJsonView();
}
export function filterSelectedValue() {
const flts = {};
for (const cell of selectedCells) {
@ -1009,6 +1027,7 @@
{ command: 'dataGrid.copyToClipboard' },
{ command: 'dataGrid.export' },
{ command: 'dataGrid.switchToForm' },
{ command: 'dataGrid.switchToJson' },
{ divider: true },
{ command: 'dataGrid.save' },
{ command: 'dataGrid.revertRowChanges' },

View File

@ -0,0 +1,58 @@
<script lang="ts">
import InlineButton from '../elements/InlineButton.svelte';
import TextField from '../forms/TextField.svelte';
import FontIcon from '../icons/FontIcon.svelte';
import { createEventDispatcher } from 'svelte';
import keycodes from '../utility/keycodes';
const dispatch = createEventDispatcher();
export let skip;
export let limit;
function handleKeyDown(e) {
if (e.keyCode == keycodes.enter) {
e.preventDefault();
e.stopPropagation();
dispatch('load');
}
}
</script>
<div class="wrapper">
<InlineButton
on:click={() => {
skip -= limit;
if (skip < 0) skip = 0;
dispatch('load');
}}
>
<FontIcon icon="icon arrow-left" />
</InlineButton>
<span class="label">Start:</span>
<TextField type="number" bind:value={skip} on:blur={() => dispatch('load')} on:keydown={handleKeyDown} />
<span class="label">Rows:</span>
<TextField type="number" bind:value={limit} on:blur={() => dispatch('load')} on:keydown={handleKeyDown} />
<InlineButton
on:click={() => {
skip += limit;
dispatch('load');
}}
>
<FontIcon icon="icon arrow-right" />
</InlineButton>
</div>
<style>
.wrapper :global(input) {
width: 100px;
}
.wrapper {
display: flex;
align-items: center;
}
.label {
margin-left: 5px;
margin-right: 5px;
}
</style>

View File

@ -5,8 +5,8 @@
setContext(contextKey, {});
export let key = '',
value;
export let key = '';
export let value;
</script>
<ul>

View File

@ -0,0 +1,66 @@
<script lang="ts">
import { onMount } from 'svelte';
import { loadCollectionDataPage } from '../datagrid/CollectionDataGridCore.svelte';
import InlineButton from '../elements/InlineButton.svelte';
import LoadingInfo from '../elements/LoadingInfo.svelte';
import Pager from '../elements/Pager.svelte';
import TextField from '../forms/TextField.svelte';
import FontIcon from '../icons/FontIcon.svelte';
import JSONTree from '../jsontree/JSONTree.svelte';
export let conid;
export let database;
export let cache;
export let display;
let isLoading = false;
let loadedTime = null;
export let loadedRows = null;
let skip = 0;
let limit = 50;
async function loadData() {
isLoading = true;
// @ts-ignore
loadedRows = await loadCollectionDataPage($$props, parseInt(skip) || 0, parseInt(limit) || 50);
isLoading = false;
loadedTime = new Date().getTime();
}
$: if (cache?.refreshTime > loadedTime) {
loadData();
}
onMount(() => {
loadData();
});
</script>
<div class="flexcol flex1">
<div class="toolbar">
<Pager bind:skip bind:limit on:load={() => display.reload()} />
</div>
<div class="json">
<JSONTree value={loadedRows} />
</div>
</div>
{#if isLoading}
<LoadingInfo wrapper message="Loading data" />
{/if}
<style>
.toolbar {
background: var(--theme-bg-3);
display: flex;
border-bottom: 1px solid var(--theme-border);
margin-bottom: 3px;
}
.json {
overflow: auto;
}
</style>

View File

@ -21,6 +21,7 @@
import CollectionDataGridCore from '../datagrid/CollectionDataGridCore.svelte';
import { useCollectionInfo, useConnectionInfo } from '../utility/metadataLoaders';
import { extensions } from '../stores';
import CollectionJsonView from '../jsonview/CollectionJsonView.svelte';
export let tabid;
export let conid;
@ -72,5 +73,6 @@
{changeSetStore}
{dispatchChangeSet}
gridCoreComponent={CollectionDataGridCore}
jsonViewComponent={CollectionJsonView}
isDynamicStructure
/>