mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-04-20 03:06:00 +00:00
master/detail working
This commit is contained in:
@@ -70,6 +70,10 @@
|
||||
export let frameSelection = undefined;
|
||||
export let isLoading = false;
|
||||
export let allRowCount = undefined;
|
||||
export let onReferenceSourceChanged = undefined;
|
||||
|
||||
export let isLoadedAll;
|
||||
export let loadedTime;
|
||||
|
||||
const wheelRowCount = 5;
|
||||
const instance = get_current_component();
|
||||
@@ -148,6 +152,13 @@
|
||||
});
|
||||
}
|
||||
|
||||
$: {
|
||||
const _unused = selectedCells;
|
||||
if (onReferenceSourceChanged && (grider.rowCount > 0 || isLoadedAll)) {
|
||||
onReferenceSourceChanged(getSelectedRowData(), loadedTime);
|
||||
}
|
||||
}
|
||||
|
||||
function scrollIntoView(cell) {
|
||||
const [row, col] = cell;
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
export let loadRowCount;
|
||||
export let grider;
|
||||
export let display;
|
||||
export let masterLoadedTime = undefined;
|
||||
// export let griderFactory;
|
||||
|
||||
export let loadedRows = [];
|
||||
@@ -87,6 +88,20 @@
|
||||
$: if (display.cache.refreshTime > loadedTime) {
|
||||
reload();
|
||||
}
|
||||
|
||||
$: {
|
||||
if (masterLoadedTime && masterLoadedTime > loadedTime) {
|
||||
display.reload();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<DataGridCore {...$$props} loadNextData={handleLoadNextData} {grider} {isLoading} {allRowCount} />
|
||||
<DataGridCore
|
||||
{...$$props}
|
||||
loadNextData={handleLoadNextData}
|
||||
{grider}
|
||||
{isLoading}
|
||||
{allRowCount}
|
||||
{isLoadedAll}
|
||||
{loadedTime}
|
||||
/>
|
||||
|
||||
39
packages/web/src/datagrid/ReferenceHeader.svelte
Normal file
39
packages/web/src/datagrid/ReferenceHeader.svelte
Normal file
@@ -0,0 +1,39 @@
|
||||
<script lang="ts">
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
import FontIcon from '../icons/FontIcon.svelte';
|
||||
import ToolbarButton from '../widgets/ToolbarButton.svelte';
|
||||
|
||||
const dispatch = createEventDispatcher();
|
||||
|
||||
export let reference;
|
||||
</script>
|
||||
|
||||
<div class="container">
|
||||
<div class="header">
|
||||
<FontIcon icon="img reference" />
|
||||
<div class="ml-2">
|
||||
{reference.pureName} [{reference.columns.map(x => x.refName).join(', ')}] = master [
|
||||
{reference.columns.map(x => x.baseName).join(', ')}]
|
||||
</div>
|
||||
</div>
|
||||
<ToolbarButton icon="icon close" on:click={() => dispatch('close')}>Close</ToolbarButton>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.container {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
background: var(--theme-bg-modalheader);
|
||||
height: var(--dim-toolbar-height);
|
||||
min-height: var(--dim-toolbar-height);
|
||||
overflow: hidden;
|
||||
border-top: 1px solid var(--theme-border);
|
||||
border-bottom: 1px solid var(--theme-border);
|
||||
}
|
||||
.header {
|
||||
font-weight: bold;
|
||||
margin-left: 10px;
|
||||
display: flex;
|
||||
}
|
||||
</style>
|
||||
@@ -12,6 +12,7 @@
|
||||
|
||||
export let managerSize;
|
||||
export let display: GridDisplay;
|
||||
export let onReferenceClick = (ref) => {};
|
||||
|
||||
const dispatch = createEventDispatcher();
|
||||
|
||||
@@ -31,7 +32,7 @@
|
||||
<div
|
||||
class="link"
|
||||
on:click={() =>
|
||||
dispatch('referenceclick', {
|
||||
onReferenceClick({
|
||||
schemaName: fk.refSchemaName,
|
||||
pureName: fk.refTableName,
|
||||
columns: fk.columns.map(col => ({
|
||||
@@ -50,12 +51,12 @@
|
||||
{/if}
|
||||
|
||||
{#if dependencies.length > 0}
|
||||
<div class="bold nowrap ml-1">References tables ({dependencies.length})</div>
|
||||
<div class="bold nowrap ml-1">Dependend tables ({dependencies.length})</div>
|
||||
{#each dependencies.filter(fk => filterName(filter, fk.pureName)) as fk}
|
||||
<div
|
||||
class="link"
|
||||
on:click={() =>
|
||||
dispatch('referenceclick', {
|
||||
onReferenceClick({
|
||||
schemaName: fk.schemaName,
|
||||
pureName: fk.pureName,
|
||||
columns: fk.columns.map(col => ({
|
||||
|
||||
@@ -1,24 +1,36 @@
|
||||
<script lang="ts">
|
||||
import { createGridCache, TableFormViewDisplay, TableGridDisplay } from 'dbgate-datalib';
|
||||
import { createGridCache, createGridConfig, TableFormViewDisplay, TableGridDisplay } from 'dbgate-datalib';
|
||||
import { getFilterValueExpression } from 'dbgate-filterparser';
|
||||
import { findEngineDriver } from 'dbgate-tools';
|
||||
import _ from 'lodash';
|
||||
import { writable } from 'svelte/store';
|
||||
import VerticalSplitter from '../elements/VerticalSplitter.svelte';
|
||||
import { extensions } from '../stores';
|
||||
import stableStringify from 'json-stable-stringify';
|
||||
|
||||
import { useConnectionInfo, useDatabaseInfo } from '../utility/metadataLoaders';
|
||||
|
||||
import DataGrid from './DataGrid.svelte';
|
||||
import ReferenceHeader from './ReferenceHeader.svelte';
|
||||
import SqlDataGridCore from './SqlDataGridCore.svelte';
|
||||
|
||||
export let conid;
|
||||
export let database;
|
||||
export let schemaName;
|
||||
export let pureName;
|
||||
|
||||
export let config;
|
||||
export let setConfig;
|
||||
|
||||
export let cache;
|
||||
export let setCache;
|
||||
|
||||
$: connection = useConnectionInfo({ conid });
|
||||
$: dbinfo = useDatabaseInfo({ conid, database });
|
||||
|
||||
const cache = writable(createGridCache());
|
||||
let myLoadedTime = 0;
|
||||
|
||||
const childCache = writable(createGridCache());
|
||||
|
||||
// $: console.log('display', display);
|
||||
|
||||
@@ -26,10 +38,10 @@
|
||||
? new TableGridDisplay(
|
||||
{ schemaName, pureName },
|
||||
findEngineDriver($connection, $extensions),
|
||||
$config,
|
||||
config.update,
|
||||
$cache,
|
||||
cache.update,
|
||||
config,
|
||||
setConfig,
|
||||
cache,
|
||||
setCache,
|
||||
$dbinfo
|
||||
)
|
||||
: // ? new TableFormViewDisplay(
|
||||
@@ -42,6 +54,102 @@
|
||||
// $dbinfo
|
||||
// )
|
||||
null;
|
||||
|
||||
const setChildConfig = (value, reference = undefined) => {
|
||||
if (_.isFunction(value)) {
|
||||
setConfig(x => ({
|
||||
...x,
|
||||
childConfig: value(x.childConfig),
|
||||
}));
|
||||
} else {
|
||||
setConfig(x => ({
|
||||
...x,
|
||||
childConfig: value,
|
||||
reference: reference === undefined ? x.reference : reference,
|
||||
}));
|
||||
}
|
||||
};
|
||||
|
||||
const handleReferenceSourceChanged = (selectedRows, loadedTime) => {
|
||||
myLoadedTime = loadedTime;
|
||||
if (!reference) return;
|
||||
|
||||
const filtersBase = display && display.isGrouped ? config.filters : childConfig.filters;
|
||||
|
||||
const filters = {
|
||||
...filtersBase,
|
||||
..._.fromPairs(
|
||||
reference.columns.map(col => [
|
||||
col.refName,
|
||||
selectedRows.map(x => getFilterValueExpression(x[col.baseName], col.dataType)).join(', '),
|
||||
])
|
||||
),
|
||||
};
|
||||
if (stableStringify(filters) != stableStringify(childConfig.filters)) {
|
||||
setChildConfig(cfg => ({
|
||||
...cfg,
|
||||
filters,
|
||||
}));
|
||||
childCache.update(ca => ({
|
||||
...ca,
|
||||
refreshTime: new Date().getTime(),
|
||||
}));
|
||||
}
|
||||
};
|
||||
|
||||
const handleCloseReference = () => {
|
||||
setChildConfig(null, null);
|
||||
};
|
||||
|
||||
$: reference = config.reference;
|
||||
$: childConfig = config.childConfig;
|
||||
</script>
|
||||
|
||||
<DataGrid {...$$props} gridCoreComponent={SqlDataGridCore} {display} />
|
||||
<VerticalSplitter isSplitter={!!reference}>
|
||||
<div slot="1">
|
||||
<DataGrid
|
||||
{...$$props}
|
||||
gridCoreComponent={SqlDataGridCore}
|
||||
{display}
|
||||
onReferenceSourceChanged={reference ? handleReferenceSourceChanged : null}
|
||||
onReferenceClick={reference => setChildConfig(createGridConfig(), reference)}
|
||||
/>
|
||||
</div>
|
||||
<div slot="2" class="reference-container">
|
||||
{#if reference}
|
||||
<ReferenceHeader {reference} on:close={handleCloseReference} />
|
||||
<div class="detail">
|
||||
{#key `${reference.schemaName}.${reference.pureName}`}
|
||||
<svelte:self
|
||||
{...$$props}
|
||||
pureName={reference.pureName}
|
||||
schemaName={reference.schemaName}
|
||||
config={childConfig}
|
||||
setConfig={setChildConfig}
|
||||
cache={$childCache}
|
||||
setCache={childCache.update}
|
||||
masterLoadedTime={myLoadedTime}
|
||||
isDetailView
|
||||
/>
|
||||
{/key}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</VerticalSplitter>
|
||||
|
||||
<style>
|
||||
.reference-container {
|
||||
position: absolute;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
.detail {
|
||||
position: relative;
|
||||
flex: 1;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
import App from '../App.svelte';
|
||||
import TableDataGrid from '../datagrid/TableDataGrid.svelte';
|
||||
import useGridConfig from '../utility/useGridConfig';
|
||||
import { createGridCache, createGridConfig, TableFormViewDisplay, TableGridDisplay } from 'dbgate-datalib';
|
||||
import { findEngineDriver } from 'dbgate-tools';
|
||||
import { writable } from 'svelte/store';
|
||||
|
||||
export let tabid;
|
||||
export let conid;
|
||||
@@ -10,6 +13,7 @@
|
||||
export let pureName;
|
||||
|
||||
const config = useGridConfig(tabid);
|
||||
const cache = writable(createGridCache());
|
||||
</script>
|
||||
|
||||
<TableDataGrid {...$$props} {config} />
|
||||
<TableDataGrid {...$$props} config={$config} setConfig={config.update} cache={$cache} setCache={cache.update} />
|
||||
|
||||
Reference in New Issue
Block a user