diff --git a/libs/docs/platform/table/e2e/table.e2e-spec.ts b/libs/docs/platform/table/e2e/table.e2e-spec.ts index 72fb73e357b..36d548bd2ff 100644 --- a/libs/docs/platform/table/e2e/table.e2e-spec.ts +++ b/libs/docs/platform/table/e2e/table.e2e-spec.ts @@ -264,7 +264,7 @@ describe('Table component test suite', () => { describe('Check Multi Row Selection', () => { it('should verify checkboxes', async () => { - await checkAllCheckbox(tableMultipleRowSelectionExample); + await checkAllCheckbox(tableMultipleRowSelectionExample, true); }); }); @@ -923,12 +923,14 @@ describe('Table component test suite', () => { await click(barButton); } - async function checkAllCheckbox(selector): Promise { + async function checkAllCheckbox(selector, skipFirst = false): Promise { await scrollIntoView(selector); await click(selector + 'fd-checkbox'); const checkboxLength = await getElementArrayLength(selector + tableRow); for (let i = 0; i < checkboxLength; i++) { - await expect(await getAttributeByName(selector + tableRow, 'aria-selected', i)).toBe('true'); + await expect(await getAttributeByName(selector + tableRow, 'aria-selected', i)).toBe( + skipFirst && i === 0 ? 'false' : 'true' + ); } } diff --git a/libs/docs/platform/table/examples/platform-table-multiple-row-selection-example.component.html b/libs/docs/platform/table/examples/platform-table-multiple-row-selection-example.component.html index b7449b26040..06f1046a4c6 100644 --- a/libs/docs/platform/table/examples/platform-table-multiple-row-selection-example.component.html +++ b/libs/docs/platform/table/examples/platform-table-multiple-row-selection-example.component.html @@ -1,6 +1,8 @@ diff --git a/libs/docs/platform/table/examples/platform-table-multiple-row-selection-example.component.ts b/libs/docs/platform/table/examples/platform-table-multiple-row-selection-example.component.ts index 9bc2f2fe09d..a3a2dab1a58 100644 --- a/libs/docs/platform/table/examples/platform-table-multiple-row-selection-example.component.ts +++ b/libs/docs/platform/table/examples/platform-table-multiple-row-selection-example.component.ts @@ -36,6 +36,8 @@ export interface ExampleItem { statusColor?: string; date: FdDate; verified: boolean; + selectable?: boolean; + selected?: boolean; } /** @@ -93,7 +95,8 @@ const ITEMS: ExampleItem[] = [ status: 'Stocked on demand', statusColor: 'informative', date: new FdDate(2020, 1, 7), - verified: true + verified: true, + selectable: false }, { name: 'Astro Laptop 1516', @@ -105,7 +108,8 @@ const ITEMS: ExampleItem[] = [ status: 'Out of stock', statusColor: 'negative', date: new FdDate(2020, 2, 5), - verified: true + verified: true, + selected: true }, { name: 'Astro Phone 6', diff --git a/libs/docs/platform/table/platform-table-docs.component.html b/libs/docs/platform/table/platform-table-docs.component.html index e181539775e..842fc21a89e 100644 --- a/libs/docs/platform/table/platform-table-docs.component.html +++ b/libs/docs/platform/table/platform-table-docs.component.html @@ -92,6 +92,16 @@ Consider that in the table with selection column present the overall columns width cannot be less than table container.

+ +

+ You can have preselected rows by providing selectedKey input property for the table with field name + in row object. Any truthy value will be considered as selected. +

+ +

+ You also can disable selecting for some rows by providing selectableKey input property for the + table with field name in row object. Only false value disables selection. +

diff --git a/libs/platform/src/lib/table/interfaces/save-rows-event.interface.ts b/libs/platform/src/lib/table/interfaces/save-rows-event.interface.ts deleted file mode 100644 index e065cc8a110..00000000000 --- a/libs/platform/src/lib/table/interfaces/save-rows-event.interface.ts +++ /dev/null @@ -1,10 +0,0 @@ -export interface SaveRowsEvent { - /** - * Callback function. Call it when newly added items has been saved and new data source fetch is needed. - */ - done: () => void; - /** - * Array of newly created items. - */ - items: T[]; -} diff --git a/libs/platform/src/lib/table/models/index.ts b/libs/platform/src/lib/table/models/index.ts index 45ec3bad7e0..204ecf4ea10 100644 --- a/libs/platform/src/lib/table/models/index.ts +++ b/libs/platform/src/lib/table/models/index.ts @@ -12,3 +12,4 @@ export * from './table-rows-rearrange-event.model'; export * from './table-row-activate-event.model'; export * from './row-comparator.model'; export * from './table-managed-preset'; +export * from './save-rows-event.interface'; diff --git a/libs/platform/src/lib/table/models/save-rows-event.interface.ts b/libs/platform/src/lib/table/models/save-rows-event.interface.ts new file mode 100644 index 00000000000..c2164b01be4 --- /dev/null +++ b/libs/platform/src/lib/table/models/save-rows-event.interface.ts @@ -0,0 +1,8 @@ +export class SaveRowsEvent { + /** + * Table save rows event + * @param done Callback function. Call it when newly added items has been saved and new data source fetch is needed. + * @param items Array of newly created items. + */ + constructor(public done: () => void, public items: T[]) {} +} diff --git a/libs/platform/src/lib/table/public_api.ts b/libs/platform/src/lib/table/public_api.ts index 1d536c40084..9ff31d60b41 100644 --- a/libs/platform/src/lib/table/public_api.ts +++ b/libs/platform/src/lib/table/public_api.ts @@ -75,7 +75,6 @@ export * from './interfaces/collection-state.interface'; export * from './interfaces/search-field.interface'; export * from './interfaces/selection-value.interface'; export * from './interfaces/table-state.interface'; -export * from './interfaces/save-rows-event.interface'; export * from './interfaces/column-responsive-state.interface'; export * from './models'; diff --git a/libs/platform/src/lib/table/table.component.html b/libs/platform/src/lib/table/table.component.html index 1443aefe417..ebf7043d878 100644 --- a/libs/platform/src/lib/table/table.component.html +++ b/libs/platform/src/lib/table/table.component.html @@ -290,6 +290,7 @@ + + + + extends Table implements AfterViewInit, /** @hidden */ private _forceSemanticHighlighting = false; + /** Value with the key of the row item's field to enable selecting. */ + @Input() + set selectedKey(value: string) { + this._selectedKey = value; + } + + get selectedKey(): string { + return this._selectedKey; + } + + /** @hidden */ + private _selectedKey: string; + + /** Value with the key of the row item's field to enable selecting. */ + @Input() + set selectableKey(value: string) { + this._selectableKey = value; + } + + get selectableKey(): string { + return this._selectableKey; + } + + /** @hidden */ + private _selectableKey: string; + /** * Tracking function that will be used to check the differences in data changes. * Used similarly to `ngFor` `trackBy` function. @@ -1086,7 +1112,7 @@ export class TableComponent extends Table implements AfterViewInit, toggleSelectableRow(rowIndex: number): void { const row = this._tableRows[rowIndex]; - if (!row) { + if (!row || row.value[this.selectableKey] === false) { return; } @@ -1156,8 +1182,9 @@ export class TableComponent extends Table implements AfterViewInit, * Adds empty row for editing at the beginning of the rows array. */ addRow(): void { - const newRow = this._buildNewRowSkeleton(); this._forceSemanticHighlighting = true; + + const newRow = this._buildNewRowSkeleton(); newRow[this.semanticHighlighting] = EDITABLE_ROW_SEMANTIC_STATE; this._addedItems.unshift(newRow); @@ -1165,7 +1192,7 @@ export class TableComponent extends Table implements AfterViewInit, const newRows = this._createTableRowsByDataSourceItems([newRow]); this._newTableRows = [...newRows, ...this._newTableRows]; - this._setTableRows(this._dataSourceTableRows); + this._setTableRows(); this.emptyRowAdded.emit(); } @@ -1179,12 +1206,9 @@ export class TableComponent extends Table implements AfterViewInit, * Emits save event and resets editable rows array. */ saveRows(): void { - const event: SaveRowsEvent = { - items: [...this._addedItems], - done: () => { - this._tableDataSource.fetch(this.getTableState()); - } - }; + const event = new SaveRowsEvent(() => { + this._tableDataSource.fetch(this.getTableState()); + }, [...this._addedItems]); const forms = [...this.customEditableCells.toArray(), ...this.editableCells.toArray()].map((t) => t.form); @@ -1751,7 +1775,12 @@ export class TableComponent extends Table implements AfterViewInit, return source.map((item: T, index: number) => { const isNewItem = this._addedItems.includes(item); - const row = new TableRow(TableRowType.ITEM, !!selectedRowsMap.get(item), index, item); + const row = new TableRow( + TableRowType.ITEM, + item[this.selectedKey] ?? !!selectedRowsMap.get(item), + index, + item + ); row.navigatable = this._isRowNavigatable(item, this.rowNavigatable); row.state = isNewItem ? 'editable' : 'readonly'; return row; @@ -1771,7 +1800,7 @@ export class TableComponent extends Table implements AfterViewInit, item[this.relationKey].length; const row = new TableRow( hasChildren ? TableRowType.TREE : TableRowType.ITEM, - !!selectedRowsMap.get(item), + item[this.selectedKey] ?? !!selectedRowsMap.get(item), index, item ); @@ -1821,7 +1850,7 @@ export class TableComponent extends Table implements AfterViewInit, } /** @hidden */ - private _setTableRows(rows: TableRow[]): void { + private _setTableRows(rows = this._dataSourceTableRows): void { this._dataSourceTableRows = rows; this._tableRows = [...this._newTableRows, ...this._dataSourceTableRows]; this._onTableRowsChanged(); @@ -2248,7 +2277,7 @@ export class TableComponent extends Table implements AfterViewInit, /** @hidden */ private _isSelectableRow(row: TableRow): boolean { - return this._isItemRow(row) || this._isTreeRow(row); + return (this._isItemRow(row) || this._isTreeRow(row)) && row.value[this.selectableKey] !== false; } /** @hidden */ @@ -2442,7 +2471,7 @@ export class TableComponent extends Table implements AfterViewInit, this._newTableRows = []; this._addedItems = []; this._forceSemanticHighlighting = false; - this._setTableRows(this._dataSourceTableRows); + this._setTableRows(); } /** @hidden */ diff --git a/libs/platform/src/lib/table/table.ts b/libs/platform/src/lib/table/table.ts index 9e11cc51f39..3ebcaa09d58 100644 --- a/libs/platform/src/lib/table/table.ts +++ b/libs/platform/src/lib/table/table.ts @@ -2,7 +2,6 @@ import { EventEmitter, Injector } from '@angular/core'; import { PresetManagedComponent } from '@fundamental-ngx/platform/shared'; import { Observable } from 'rxjs'; -import { SaveRowsEvent } from './interfaces/save-rows-event.interface'; import { TableState } from './interfaces/table-state.interface'; import { CollectionSort } from './interfaces/collection-sort.interface'; import { CollectionFilter } from './interfaces/collection-filter.interface'; @@ -10,7 +9,7 @@ import { CollectionGroup } from './interfaces/collection-group.interface'; import { SearchInput } from './interfaces/search-field.interface'; import { TableColumn } from './components/table-column/table-column'; import { TableDataSource } from './domain'; -import { PlatformTableManagedPreset } from './models'; +import { PlatformTableManagedPreset, SaveRowsEvent } from './models'; export abstract class Table implements PresetManagedComponent { abstract readonly name: string;