nosql: view expandable data (arrays, objects)

This commit is contained in:
Jan Prochazka
2021-04-03 20:45:57 +02:00
parent fcedeb2316
commit 69e1c6c625
6 changed files with 54 additions and 11 deletions

View File

@@ -3,6 +3,27 @@ import { GridDisplay, ChangeCacheFunc, ChangeConfigFunc } from './GridDisplay';
import { EngineDriver, ViewInfo, ColumnInfo, CollectionInfo } from 'dbgate-types'; import { EngineDriver, ViewInfo, ColumnInfo, CollectionInfo } from 'dbgate-types';
import { GridConfig, GridCache } from './GridConfig'; import { GridConfig, GridCache } from './GridConfig';
function getObjectKeys(obj) {
if (_.isArray(obj)) {
return Object.keys(obj)
.slice(0, 10)
.map(x => parseInt(x));
}
if (_.isPlainObject(obj)) {
return Object.keys(obj);
}
return [];
}
function createHeaderText(path) {
let res = path[0];
for (let i = 1; i < path.length; i++) {
const name = path[i];
if (_.isNumber(name)) res += `[${name}]`;
else res += `.${name}`;
}
return res;
}
export class CollectionGridDisplay extends GridDisplay { export class CollectionGridDisplay extends GridDisplay {
constructor( constructor(
public collection: CollectionInfo, public collection: CollectionInfo,
@@ -19,15 +40,13 @@ export class CollectionGridDisplay extends GridDisplay {
this.sortable = true; this.sortable = true;
this.editable = false; this.editable = false;
this.supportsReload = true; this.supportsReload = true;
this.isDynamicStructure = true;
} }
getDisplayColumns(rows) { getDisplayColumns(rows) {
const res = []; const res = [];
for (const row of rows) { for (const row of rows) {
for (const name of Object.keys(row)) { this.getColumnsForObject([], row, res);
if (res.find(x => x.columnName == name)) continue;
res.push(this.getDisplayColumn(name));
}
} }
return ( return (
res.map(col => ({ res.map(col => ({
@@ -37,14 +56,32 @@ export class CollectionGridDisplay extends GridDisplay {
); );
} }
getDisplayColumn(columnName: string) { getColumnsForObject(basePath, obj, res) {
const uniquePath = [columnName]; for (const name of getObjectKeys(obj)) {
let column = res.find(x => x.columnName == name);
if (!column) {
column = this.getDisplayColumn(basePath, name);
res.push(column);
}
if (_.isPlainObject(obj[name]) || _.isArray(obj[name])) {
column.isExpandable = true;
}
if (this.isExpandedColumn(column.uniqueName)) {
this.getColumnsForObject([...basePath, name], obj[name], res);
}
}
}
getDisplayColumn(basePath, columnName) {
const uniquePath = [...basePath, columnName];
const uniqueName = uniquePath.join('.'); const uniqueName = uniquePath.join('.');
return { return {
columnName, columnName,
headerText: columnName, headerText: createHeaderText(uniquePath),
uniqueName, uniqueName,
uniquePath, uniquePath,
isStructured: true,
}; };
} }
} }

View File

@@ -18,9 +18,11 @@ export interface DisplayColumn {
autoIncrement?: boolean; autoIncrement?: boolean;
isPrimaryKey?: boolean; isPrimaryKey?: boolean;
foreignKey?: ForeignKeyInfo; foreignKey?: ForeignKeyInfo;
isExpandable?: boolean;
isChecked?: boolean; isChecked?: boolean;
hintColumnName?: string; hintColumnName?: string;
dataType?: string; dataType?: string;
isStructured?: boolean;
} }
export interface DisplayedColumnEx extends DisplayColumn { export interface DisplayedColumnEx extends DisplayColumn {
@@ -59,6 +61,7 @@ export abstract class GridDisplay {
editable = false; editable = false;
isLoadedCorrectly = true; isLoadedCorrectly = true;
supportsReload = false; supportsReload = false;
isDynamicStructure = false;
setColumnVisibility(uniquePath: string[], isVisible: boolean) { setColumnVisibility(uniquePath: string[], isVisible: boolean) {
const uniqueName = uniquePath.join('.'); const uniqueName = uniquePath.join('.');
@@ -66,7 +69,7 @@ export abstract class GridDisplay {
this.includeInColumnSet('hiddenColumns', uniqueName, !isVisible); this.includeInColumnSet('hiddenColumns', uniqueName, !isVisible);
} else { } else {
this.includeInColumnSet('addedColumns', uniqueName, isVisible); this.includeInColumnSet('addedColumns', uniqueName, isVisible);
this.reload(); if (!this.isDynamicStructure) this.reload();
} }
} }

View File

@@ -59,6 +59,7 @@ export class TableGridDisplay extends GridDisplay {
...col, ...col,
isChecked: this.isColumnChecked(col), isChecked: this.isColumnChecked(col),
hintColumnName: col.foreignKey ? `hint_${col.uniqueName}` : null, hintColumnName: col.foreignKey ? `hint_${col.uniqueName}` : null,
isExpandable: !!col.foreignKey,
})) || [] })) || []
); );
} }

View File

@@ -18,7 +18,7 @@
> >
<span class="expandColumnIcon"> <span class="expandColumnIcon">
<FontIcon <FontIcon
icon={column.foreignKey ? plusExpandIcon(display.isExpandedColumn(column.uniqueName)) : 'icon invisible-box'} icon={column.isExpandable ? plusExpandIcon(display.isExpandedColumn(column.uniqueName)) : 'icon invisible-box'}
on:click={() => display.toggleExpandedColumn(column.uniqueName)} on:click={() => display.toggleExpandedColumn(column.uniqueName)}
/> />
</span> </span>

View File

@@ -39,7 +39,7 @@
export let hideContent = false; export let hideContent = false;
export let onSetFormView; export let onSetFormView;
$: value = (rowData || {})[col.uniqueName]; $: value = col.isStructured ? _.get(rowData || {}, col.uniquePath) : (rowData || {})[col.uniqueName];
</script> </script>
<td <td

View File

@@ -61,7 +61,9 @@ export function countColumnSizes(grider: Grider, columns, containerWidth, displa
continue; continue;
} }
const text = row[uqName]; const value = row[uqName];
let text = value;
if (_.isArray(value)) text = `[${value.length} items]`;
const width = context.measureText(text).width + 8; const width = context.measureText(text).width + 8;
// console.log('colName', colName, text, width); // console.log('colName', colName, text, width);
columnSizes.putSizeOverride(colIndex, width); columnSizes.putSizeOverride(colIndex, width);