Skip to content

Commit

Permalink
modify data table widget adapter instead of core object data table ad…
Browse files Browse the repository at this point in the history
…apter
  • Loading branch information
tomgny committed May 8, 2024
1 parent ab75ee6 commit d6726ea
Show file tree
Hide file tree
Showing 12 changed files with 249 additions and 207 deletions.
127 changes: 0 additions & 127 deletions lib/core/src/lib/datatable/data/object-datatable-adapter.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import { DataSorting } from './data-sorting.model';
import { ObjectDataTableAdapter } from './object-datatable-adapter';
import { ObjectDataRow } from './object-datarow.model';
import { ObjectDataColumn } from './object-datacolumn.model';
import { mockPersonsData, mockPersonDataFirstRow } from './mocks/object-datatable-adapter.mock';

describe('ObjectDataTableAdapter', () => {
it('should init with empty row collection', () => {
Expand Down Expand Up @@ -290,132 +289,6 @@ describe('ObjectDataTableAdapter', () => {
})
);
});

describe('should create proper rows and columns from schema and data with nested properties for', () => {
it('one column', () => {
const mockPersonSchema: DataColumn[] = [
{
type: 'text',
key: 'person.name',
title: 'Name'
}
];

const adapter = new ObjectDataTableAdapter(mockPersonsData, mockPersonSchema);
const rows = adapter.getRows();
const columns = adapter.getColumns();

const expectedFirstRow = new ObjectDataRow({
name: 'John Doe'
});
const expectedSecondRow = new ObjectDataRow({
name: 'Sam Smith'
});
const expectedColumns = [new ObjectDataColumn({ key: 'name', type: 'text', title: 'Name' })];

expect(rows.length).toBe(2);
expect(rows[0]).toEqual(expectedFirstRow);
expect(rows[1]).toEqual(expectedSecondRow);

expect(columns.length).toBe(1);
expect(columns).toEqual(expectedColumns);
});

it('one row', () => {
const mockPersonSchema: DataColumn[] = [
{
type: 'text',
key: 'name',
title: 'Name'
},
{
type: 'text',
key: 'personData.[address.[data]test].city',
title: 'City'
}
];

const adapter = new ObjectDataTableAdapter([mockPersonDataFirstRow], mockPersonSchema);
const rows = adapter.getRows();
const columns = adapter.getColumns();

const expectedFirstRow = new ObjectDataRow({
name: 'John Doe',
city: 'Springfield'
});
const expectedColumns = [
new ObjectDataColumn({ key: 'name', type: 'text', title: 'Name' }),
new ObjectDataColumn({ key: 'city', type: 'text', title: 'City' })
];

expect(rows.length).toBe(1);
expect(rows[0]).toEqual(expectedFirstRow);

expect(columns.length).toBe(2);
expect(columns).toEqual(expectedColumns);
});

it('complex schema', () => {
const mockPersonSchema: DataColumn[] = [
{
type: 'text',
key: 'person.name',
title: 'Name'
},
{
type: 'text',
key: 'person.personData.[address.[data]test].city',
title: 'City'
},
{
type: 'text',
key: 'person.personData.[address.[data]test].street',
title: 'Street'
},
{
type: 'json',
key: 'person.phoneNumbers',
title: 'Phone numbers'
}
];

const adapter = new ObjectDataTableAdapter(mockPersonsData, mockPersonSchema);
const rows = adapter.getRows();
const columns = adapter.getColumns();

const expectedFirstRow = new ObjectDataRow({
city: 'Springfield',
street: '1234 Main St',
name: 'John Doe',
phoneNumbers: [
{ type: 'home', phoneNumber: '123-456-7890' },
{ type: 'work', phoneNumber: '098-765-4321' }
]
});
const expectedSecondRow = new ObjectDataRow({
city: 'Westlake',
street: '731 Second St',
name: 'Sam Smith',
phoneNumbers: [
{ type: 'home', phoneNumber: '123-456-7891' },
{ type: 'work', phoneNumber: '321-654-1987' }
]
});
const expectedColumns = [
new ObjectDataColumn({ key: 'name', type: 'text', title: 'Name' }),
new ObjectDataColumn({ key: 'city', type: 'text', title: 'City' }),
new ObjectDataColumn({ key: 'street', type: 'text', title: 'Street' }),
new ObjectDataColumn({ key: 'phoneNumbers', type: 'json', title: 'Phone numbers' })
];

expect(rows.length).toBe(2);
expect(rows[0]).toEqual(expectedFirstRow);
expect(rows[1]).toEqual(expectedSecondRow);

expect(columns.length).toBe(4);
expect(columns).toEqual(expectedColumns);
});
});
});

describe('ObjectDataRow', () => {
Expand Down
68 changes: 11 additions & 57 deletions lib/core/src/lib/datatable/data/object-datatable-adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,22 +22,19 @@ import { ObjectDataColumn } from './object-datacolumn.model';
import { DataSorting } from './data-sorting.model';
import { DataTableAdapter } from './datatable-adapter';
import { Subject } from 'rxjs';
import { DataTablePathParserHelper } from '../helpers/data-table-path-parser.helper';

// Simple implementation of the DataTableAdapter interface.
export class ObjectDataTableAdapter implements DataTableAdapter {
private _sorting: DataSorting;
private _rows: DataRow[];
private _columns: DataColumn[];
private columnPaths: string[] = [];
private columnKeys: string[] = [];
private helper = new DataTablePathParserHelper();

selectedRow: DataRow;
rowsChanged: Subject<Array<DataRow>>;

static generateSchema(data: any[]) {
const schema = [];

if (data?.length) {
const rowToExamine = data[0];

Expand All @@ -61,64 +58,21 @@ export class ObjectDataTableAdapter implements DataTableAdapter {
this._rows = [];
this._columns = [];

this.createColumns(schema);
this.createRows(data);
this.sortColumns();

this.rowsChanged = new Subject<Array<DataRow>>();
}

private createColumns(schema: DataColumn[]): void {
if (schema?.length) {
this._columns = this.buildColumnsFromSchema(schema);
}
}

private buildColumnsFromSchema(schema: DataColumn[]): ObjectDataColumn[] {
return schema.map((dataColumn) => {
const columnKey = this.extractNestedColumnKey(dataColumn.key);
this.columnPaths.push(dataColumn.key);
this.columnKeys.push(columnKey);
dataColumn.key = columnKey;

return new ObjectDataColumn(dataColumn);
});
}

private sortColumns(): void {
const sortable = this._columns.filter((column) => column.sortable);
if (sortable?.length) {
this.sort(sortable[0].key, 'asc');
if (data && data.length > 0) {
this._rows = data.map((item) => new ObjectDataRow(item));
}
}

private extractNestedColumnKey(path: string): string {
const properties = this.helper.splitPathIntoProperties(path);
if (schema && schema.length > 0) {
this._columns = schema.map((item) => new ObjectDataColumn(item));

return this.helper.removeSquareBracketsFromProperty(properties[properties.length - 1]);
}

private createRows(data: any[]): void {
if (data?.length) {
this._rows = data.map((item) => this.buildDataRowFromItem(item));
}
}

private buildDataRowFromItem(item: any): ObjectDataRow {
const rowData = {};
this.columnPaths.forEach((path, i) => {
const rowValue = this.extractPropertyValue(this.helper.splitPathIntoProperties(path), item);

if (rowValue) {
rowData[this.columnKeys[i]] = rowValue;
// Sort by first sortable or just first column
const sortable = this._columns.filter((column) => column.sortable);
if (sortable.length > 0) {
this.sort(sortable[0].key, 'asc');
}
});

return new ObjectDataRow(rowData);
}
}

private extractPropertyValue(properties: string[], item: any): string {
return properties.reduce((acc, property) => (acc ? acc[this.helper.removeSquareBracketsFromProperty(property)] : undefined), item);
this.rowsChanged = new Subject<Array<DataRow>>();
}

getColumnType(_row: DataRow, col: DataColumn): string {
Expand Down
2 changes: 0 additions & 2 deletions lib/core/src/lib/datatable/public-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,5 @@ export * from './directives/main-data-table-action-template.directive';

export * from './services/datatable.service';

export * from './helpers/data-table-path-parser.helper';

export * from './datatable.module';
export * from './data-column';
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ import {
mockInvalidSchemaDefinition,
mockSchemaDefinition
} from './mocks/data-table-widget.mock';
import { ObjectDataRow } from '@alfresco/adf-core';
import { mockPersonDataFirstRow, mockPersonsData } from './mocks/data-table-adapter.mock';
import { DataColumn, ObjectDataColumn, ObjectDataRow } from '@alfresco/adf-core';

describe('WidgetDataTableAdapter', () => {
let widgetDataTableAdapter: WidgetDataTableAdapter;
Expand Down Expand Up @@ -64,4 +65,130 @@ describe('WidgetDataTableAdapter', () => {

expect(isValid).toBeTrue();
});

describe('should create proper rows and columns from schema and data with nested properties for', () => {
it('one column', () => {
const mockPersonSchema: DataColumn[] = [
{
type: 'text',
key: 'person.name',
title: 'Name'
}
];

const adapter = new WidgetDataTableAdapter(mockPersonsData, mockPersonSchema);
const rows = adapter.getRows();
const columns = adapter.getColumns();

const expectedFirstRow = new ObjectDataRow({
'person.name': 'John Doe'
});
const expectedSecondRow = new ObjectDataRow({
'person.name': 'Sam Smith'
});
const expectedColumns = [new ObjectDataColumn({ key: 'person.name', type: 'text', title: 'Name' })];

expect(rows.length).toBe(2);
expect(rows[0]).toEqual(expectedFirstRow);
expect(rows[1]).toEqual(expectedSecondRow);

expect(columns.length).toBe(1);
expect(columns).toEqual(expectedColumns);
});

it('one row', () => {
const mockPersonSchema: DataColumn[] = [
{
type: 'text',
key: 'name',
title: 'Name'
},
{
type: 'text',
key: 'personData.[address.[data]test].city',
title: 'City'
}
];

const adapter = new WidgetDataTableAdapter([mockPersonDataFirstRow], mockPersonSchema);
const rows = adapter.getRows();
const columns = adapter.getColumns();

const expectedFirstRow = new ObjectDataRow({
name: 'John Doe',
'personData.[address.[data]test].city': 'Springfield'
});
const expectedColumns = [
new ObjectDataColumn({ key: 'name', type: 'text', title: 'Name' }),
new ObjectDataColumn({ key: 'personData.[address.[data]test].city', type: 'text', title: 'City' })
];

expect(rows.length).toBe(1);
expect(rows[0]).toEqual(expectedFirstRow);

expect(columns.length).toBe(2);
expect(columns).toEqual(expectedColumns);
});

it('complex schema', () => {
const mockPersonSchema: DataColumn[] = [
{
type: 'text',
key: 'person.name',
title: 'Name'
},
{
type: 'text',
key: 'person.personData.[address.[data]test].city',
title: 'City'
},
{
type: 'text',
key: 'person.personData.[address.[data]test].street',
title: 'Street'
},
{
type: 'json',
key: 'person.phoneNumbers',
title: 'Phone numbers'
}
];

const adapter = new WidgetDataTableAdapter(mockPersonsData, mockPersonSchema);
const rows = adapter.getRows();
const columns = adapter.getColumns();

const expectedFirstRow = new ObjectDataRow({
'person.personData.[address.[data]test].city': 'Springfield',
'person.personData.[address.[data]test].street': '1234 Main St',
'person.name': 'John Doe',
'person.phoneNumbers': [
{ type: 'home', phoneNumber: '123-456-7890' },
{ type: 'work', phoneNumber: '098-765-4321' }
]
});
const expectedSecondRow = new ObjectDataRow({
'person.personData.[address.[data]test].city': 'Westlake',
'person.personData.[address.[data]test].street': '731 Second St',
'person.name': 'Sam Smith',
'person.phoneNumbers': [
{ type: 'home', phoneNumber: '123-456-7891' },
{ type: 'work', phoneNumber: '321-654-1987' }
]
});
const expectedColumns = [
new ObjectDataColumn({ key: 'person.name', type: 'text', title: 'Name' }),
new ObjectDataColumn({ key: 'person.personData.[address.[data]test].city', type: 'text', title: 'City' }),
new ObjectDataColumn({ key: 'person.personData.[address.[data]test].street', type: 'text', title: 'Street' }),
new ObjectDataColumn({ key: 'person.phoneNumbers', type: 'json', title: 'Phone numbers' })
];

expect(rows.length).toBe(2);
expect(rows[0]).toEqual(expectedFirstRow);
expect(rows[1]).toEqual(expectedSecondRow);

expect(columns.length).toBe(4);
expect(columns).toEqual(expectedColumns);
});
});
});
Loading

0 comments on commit d6726ea

Please sign in to comment.