diff --git a/packages/datalib/src/PerspectiveDisplay.ts b/packages/datalib/src/PerspectiveDisplay.ts index 75d7bfa46..e3d16455c 100644 --- a/packages/datalib/src/PerspectiveDisplay.ts +++ b/packages/datalib/src/PerspectiveDisplay.ts @@ -3,6 +3,8 @@ import _max from 'lodash/max'; import _range from 'lodash/max'; import _fill from 'lodash/fill'; import _findIndex from 'lodash/findIndex'; +import _isPlainObject from 'lodash/isPlainObject'; +import _isArray from 'lodash/isArray'; import debug from 'debug'; const dbg = debug('dbgate:PerspectiveDisplay'); @@ -167,13 +169,30 @@ export class PerspectiveDisplay { // return _findIndex(this.columns, x => x.dataNode.designerId == node.designerId); // } + extractArray(value) { + if (_isArray(value)) return value; + if (_isPlainObject(value)) return [value]; + return []; + } + collectRows(sourceRows: any[], nodes: PerspectiveTreeNode[]): CollectedPerspectiveDisplayRow[] { // console.log('********** COLLECT ROWS', sourceRows); - const columnNodes = nodes.filter(x => x.isCheckedColumn); - const treeNodes = nodes.filter(x => x.isCheckedNode); + const columnNodes = nodes.filter(x => x.generatesDataGridColumn); + const treeNodes = nodes.filter(x => x.generatesHiearchicGridColumn); - // console.log('columnNodes', columnNodes); - // console.log('treeNodes', treeNodes); + // console.log( + // 'columnNodes', + // columnNodes.map(x => x.title) + // ); + // console.log( + // 'treeNodes', + // treeNodes.map(x => x.title) + // ); + + // console.log( + // 'nodes', + // nodes.map(x => x.title) + // ); const columnIndexes = columnNodes.map(node => this.findColumnIndexFromNode(node)); @@ -181,14 +200,14 @@ export class PerspectiveDisplay { for (const sourceRow of sourceRows) { // console.log('PROCESS SOURCE', sourceRow); // row.startIndex = startIndex; - const rowData = columnNodes.map(node => sourceRow[node.codeName]); + const rowData = columnNodes.map(node => sourceRow[node.fieldName]); const subRowCollections = []; for (const node of treeNodes) { // console.log('sourceRow[node.fieldName]', node.fieldName, sourceRow[node.fieldName]); if (sourceRow[node.fieldName]) { const subrows = { - rows: this.collectRows(sourceRow[node.fieldName], node.childNodes), + rows: this.collectRows(this.extractArray(sourceRow[node.fieldName]), node.childNodes), }; subRowCollections.push(subrows); } diff --git a/packages/datalib/src/PerspectiveTreeNode.ts b/packages/datalib/src/PerspectiveTreeNode.ts index b0c8a5e99..8b4bce444 100644 --- a/packages/datalib/src/PerspectiveTreeNode.ts +++ b/packages/datalib/src/PerspectiveTreeNode.ts @@ -797,6 +797,7 @@ export class PerspectivePatternColumnNode extends PerspectiveTreeNode { } get generatesHiearchicGridColumn() { + // console.log('generatesHiearchicGridColumn', this.parentTableNode?.nodeConfig?.checkedColumns, this.codeName + '::'); return !!this.parentTableNode?.nodeConfig?.checkedColumns?.find(x => x.startsWith(this.codeName + '::')); } diff --git a/packages/datalib/src/tests/PerspectiveDisplay.test.ts b/packages/datalib/src/tests/PerspectiveDisplay.test.ts index dfba7a3aa..82bbedc82 100644 --- a/packages/datalib/src/tests/PerspectiveDisplay.test.ts +++ b/packages/datalib/src/tests/PerspectiveDisplay.test.ts @@ -1,4 +1,3 @@ -import { TableInfo } from 'dbgate-types'; import { PerspectiveDisplay } from '../PerspectiveDisplay'; import { PerspectiveTableNode } from '../PerspectiveTreeNode'; import { chinookDbInfo } from './chinookDbInfo'; @@ -7,9 +6,6 @@ import artistDataFlat from './artistDataFlat'; import artistDataAlbum from './artistDataAlbum'; import artistDataAlbumTrack from './artistDataAlbumTrack'; import { processPerspectiveDefaultColunns } from '../processPerspectiveDefaultColunns'; -import { DatabaseAnalyser, isCollectionInfo } from 'dbgate-tools'; -import { analyseDataPattern } from '../PerspectiveDataPattern'; -import { PerspectiveDataProvider } from '../PerspectiveDataProvider'; test('test flat view', () => { const artistTable = chinookDbInfo.tables.find(x => x.pureName == 'Artist'); @@ -144,52 +140,3 @@ test('test two level nesting', () => { expect(display.rows[2].rowSpans).toEqual([1, 2, 1]); expect(display.rows[2].rowCellSkips).toEqual([true, false, false]); }); - -test('test nosql display', () => { - const collectionInfo = { - objectTypeField: 'collections', - pureName: 'Account', - }; - const dbInfo = { - ...DatabaseAnalyser.createEmptyStructure(), - collections: [collectionInfo], - }; - const accountData = [ - { name: 'jan', email: 'jan@foo.co', follows: [{ name: 'lucie' }, { name: 'petr' }] }, - { name: 'romeo', email: 'romeo@foo.co', follows: [{ name: 'julie' }, { name: 'wiliam' }] }, - ]; - const config = createPerspectiveConfig({ pureName: 'Account' }); - const dataPatterns = { - [config.rootDesignerId]: analyseDataPattern( - { - conid: 'conid', - database: 'db', - pureName: 'Account', - }, - accountData - ), - }; - - const configColumns = processPerspectiveDefaultColunns( - config, - { conid: { db: dbInfo } }, - dataPatterns, - 'conid', - 'db' - ); - const root = new PerspectiveTableNode( - collectionInfo, - { conid: { db: dbInfo } }, - configColumns, - null, - new PerspectiveDataProvider(null, null, dataPatterns), - { conid: 'conid', database: 'db' }, - null, - configColumns.rootDesignerId - ); - const display = new PerspectiveDisplay(root, accountData); - - expect(display.rows.length).toEqual(2); - expect(display.rows[0].rowData).toEqual(['jan']); - expect(display.rows[1].rowData).toEqual(['romeo']); -}); diff --git a/packages/datalib/src/tests/PerspectiveDisplayNoSql.test.ts b/packages/datalib/src/tests/PerspectiveDisplayNoSql.test.ts new file mode 100644 index 000000000..aa08e0f83 --- /dev/null +++ b/packages/datalib/src/tests/PerspectiveDisplayNoSql.test.ts @@ -0,0 +1,98 @@ +import { PerspectiveDisplay } from '../PerspectiveDisplay'; +import { PerspectiveTableNode } from '../PerspectiveTreeNode'; +import { createPerspectiveConfig, PerspectiveNodeConfig } from '../PerspectiveConfig'; +import { processPerspectiveDefaultColunns } from '../processPerspectiveDefaultColunns'; +import { DatabaseAnalyser } from 'dbgate-tools'; +import { analyseDataPattern } from '../PerspectiveDataPattern'; +import { PerspectiveDataProvider } from '../PerspectiveDataProvider'; + +const accountData = [ + { + name: 'jan', + email: 'jan@foo.co', + follows: [{ name: 'lucie' }, { name: 'petr' }], + nested: { email: 'jan@nest.cz' }, + }, + { + name: 'romeo', + email: 'romeo@foo.co', + follows: [{ name: 'julie' }, { name: 'wiliam' }], + nested: { email: 'romeo@nest.cz' }, + }, +]; + +function createDisplay(cfgFunc?: (cfg: PerspectiveNodeConfig) => void) { + const collectionInfo = { + objectTypeField: 'collections', + pureName: 'Account', + }; + const dbInfo = { + ...DatabaseAnalyser.createEmptyStructure(), + collections: [collectionInfo], + }; + const config = createPerspectiveConfig({ pureName: 'Account' }); + const dataPatterns = { + [config.rootDesignerId]: analyseDataPattern( + { + conid: 'conid', + database: 'db', + pureName: 'Account', + }, + accountData + ), + }; + const configColumns = processPerspectiveDefaultColunns( + config, + { conid: { db: dbInfo } }, + dataPatterns, + 'conid', + 'db' + ); + if (cfgFunc) { + cfgFunc(configColumns.nodes[0]); + } + const root = new PerspectiveTableNode( + collectionInfo, + { conid: { db: dbInfo } }, + configColumns, + null, + new PerspectiveDataProvider(null, null, dataPatterns), + { conid: 'conid', database: 'db' }, + null, + configColumns.rootDesignerId + ); + + const display = new PerspectiveDisplay(root, accountData); + + return display; +} + +test('test nosql display', () => { + const display = createDisplay(); + + expect(display.rows.length).toEqual(2); + expect(display.rows[0].rowData).toEqual(['jan']); + expect(display.rows[1].rowData).toEqual(['romeo']); +}); + +test('test nosql nested array display', () => { + const display = createDisplay(cfg => { + cfg.checkedColumns = ['name', 'follows::name']; + }); + + expect(display.rows.length).toEqual(4); + expect(display.rows[0].rowData).toEqual(['jan', 'lucie']); + expect(display.rows[1].rowData).toEqual([undefined, 'petr']); + expect(display.rows[2].rowData).toEqual(['romeo', 'julie']); + expect(display.rows[3].rowData).toEqual([undefined, 'wiliam']); +}); + +test('test nosql nested object', () => { + const display = createDisplay(cfg => { + cfg.checkedColumns = ['name', 'nested::email']; + }); + + expect(display.rows.length).toEqual(2); + expect(display.rows[0].rowData).toEqual(['jan', 'jan@nest.cz']); + expect(display.rows[1].rowData).toEqual(['romeo', 'romeo@nest.cz']); +});