From 6d0e415f2ec5761afa2a72fff608638f9079fc4e Mon Sep 17 00:00:00 2001 From: mollykreis <20542556+mollykreis@users.noreply.github.com> Date: Fri, 14 Apr 2023 09:46:49 -0500 Subject: [PATCH 1/3] add angular support for row selection --- .../app/customapp/customapp.component.html | 2 +- .../src/app/customapp/customapp.component.ts | 14 ++++--- .../table/nimble-table.directive.ts | 25 +++++++++-- .../tests/nimble-table.directive.spec.ts | 42 +++++++++++++++++-- 4 files changed, 70 insertions(+), 13 deletions(-) diff --git a/angular-workspace/projects/example-client-app/src/app/customapp/customapp.component.html b/angular-workspace/projects/example-client-app/src/app/customapp/customapp.component.html index 9c29df809a..eed12946d5 100644 --- a/angular-workspace/projects/example-client-app/src/app/customapp/customapp.component.html +++ b/angular-workspace/projects/example-client-app/src/app/customapp/customapp.component.html @@ -185,7 +185,7 @@
Table
- + ; private readonly tableDataSubject = new BehaviorSubject([ - { stringValue1: 'hello world', stringValue2: 'more text' }, - { stringValue1: 'foo', stringValue2: 'bar' }, - { stringValue1: 'candy', stringValue2: 'bar' }, - { stringValue1: 'dive', stringValue2: 'bar' }, - { stringValue1: 're', stringValue2: 'bar' }, - { stringValue1: 'last row', stringValue2: 'yay!' } + { id: '0', stringValue1: 'hello world', stringValue2: 'more text' }, + { id: '1', stringValue1: 'foo', stringValue2: 'bar' }, + { id: '2', stringValue1: 'candy', stringValue2: 'bar' }, + { id: '3', stringValue1: 'dive', stringValue2: 'bar' }, + { id: '4', stringValue1: 're', stringValue2: 'bar' }, + { id: '5', stringValue1: 'last row', stringValue2: 'yay!' } ]); @ViewChild('dialog', { read: NimbleDialogDirective }) private readonly dialog: NimbleDialogDirective; @@ -92,6 +93,7 @@ export class CustomAppComponent { public onAddTableRow(): void { const tableData = this.tableDataSubject.value; tableData.push({ + id: tableData.length.toString(), stringValue1: `new string ${tableData.length}`, stringValue2: `bar ${tableData.length}` }); diff --git a/angular-workspace/projects/ni/nimble-angular/src/directives/table/nimble-table.directive.ts b/angular-workspace/projects/ni/nimble-angular/src/directives/table/nimble-table.directive.ts index f707fdfa0c..c5e7344120 100644 --- a/angular-workspace/projects/ni/nimble-angular/src/directives/table/nimble-table.directive.ts +++ b/angular-workspace/projects/ni/nimble-angular/src/directives/table/nimble-table.directive.ts @@ -1,11 +1,12 @@ import { Directive, ElementRef, Input, OnDestroy, Renderer2 } from '@angular/core'; import type { Table } from '@ni/nimble-components/dist/esm/table'; -import type { TableRecord, TableFieldName, TableFieldValue, TableValidity, TableActionMenuToggleEventDetail } from '@ni/nimble-components/dist/esm/table/types'; +import type { TableRecord, TableFieldName, TableFieldValue, TableValidity, TableActionMenuToggleEventDetail, TableRowSelectionEventDetail } from '@ni/nimble-components/dist/esm/table/types'; +import { TableRowSelectionMode } from '@ni/nimble-components/dist/esm/table/types'; import type { Observable, Subscription } from 'rxjs'; export type { Table }; -export type { TableActionMenuToggleEventDetail }; -export { TableRecord, TableFieldName, TableFieldValue, TableValidity }; +export type { TableActionMenuToggleEventDetail, TableRowSelectionEventDetail }; +export { TableRecord, TableFieldName, TableFieldValue, TableValidity, TableRowSelectionMode }; /** * Directive to provide Angular integration for the table element. @@ -41,6 +42,16 @@ export class NimbleTableDirective imple this.renderer.setProperty(this.elementRef.nativeElement, 'idFieldName', value); } + public get selectionMode(): TableRowSelectionMode { + return this.elementRef.nativeElement.selectionMode; + } + + // Renaming because property should have camel casing, but attribute should not + // eslint-disable-next-line @angular-eslint/no-input-rename + @Input('selection-mode') public set selectionMode(value: TableRowSelectionMode) { + this.renderer.setProperty(this.elementRef.nativeElement, 'selectionMode', value); + } + public get validity(): TableValidity { return this.elementRef.nativeElement.validity; } @@ -61,4 +72,12 @@ export class NimbleTableDirective imple public async setData(data: readonly TData[]): Promise { return this.elementRef.nativeElement.setData(data); } + + public async getSelectedRecordIds(): Promise { + return this.elementRef.nativeElement.getSelectedRecordIds(); + } + + public async setSelectedRecordIds(recordIds: string[]): Promise { + return this.elementRef.nativeElement.setSelectedRecordIds(recordIds); + } } diff --git a/angular-workspace/projects/ni/nimble-angular/src/directives/table/tests/nimble-table.directive.spec.ts b/angular-workspace/projects/ni/nimble-angular/src/directives/table/tests/nimble-table.directive.spec.ts index 4276161e0f..9ce9e1b37b 100644 --- a/angular-workspace/projects/ni/nimble-angular/src/directives/table/tests/nimble-table.directive.spec.ts +++ b/angular-workspace/projects/ni/nimble-angular/src/directives/table/tests/nimble-table.directive.spec.ts @@ -2,7 +2,7 @@ import { Component, ElementRef, ViewChild } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { processUpdates, Table, TableRecord, TableValidity } from '@ni/nimble-angular'; import { Observable, Subject } from 'rxjs'; -import { NimbleTableDirective } from '../nimble-table.directive'; +import { NimbleTableDirective, TableRowSelectionMode } from '../nimble-table.directive'; import { NimbleTableModule } from '../nimble-table.module'; describe('Nimble table', () => { @@ -197,6 +197,11 @@ describe('Nimble table', () => { expect(directive.idFieldName).toEqual(undefined); expect(nativeElement.idFieldName).toEqual(undefined); }); + + it('has expected defaults for selectionMode', () => { + expect(directive.selectionMode).toEqual(TableRowSelectionMode.none); + expect(nativeElement.selectionMode).toEqual(TableRowSelectionMode.none); + }); }); describe('with property bound values', () => { @@ -207,7 +212,12 @@ describe('Nimble table', () => { @Component({ template: ` - + + ` }) class TestHostComponent { @@ -216,6 +226,7 @@ describe('Nimble table', () => { public data$ = new Observable(); public idFieldName = 'field1'; + public selectionMode: TableRowSelectionMode = TableRowSelectionMode.multiple; } let fixture: ComponentFixture; @@ -252,6 +263,17 @@ describe('Nimble table', () => { expect(directive.idFieldName).toEqual('field2'); expect(nativeElement.idFieldName).toEqual('field2'); }); + + it('can be configured with property binding for selectionMode', () => { + expect(directive.selectionMode).toEqual(fixture.componentInstance.selectionMode); + expect(nativeElement.selectionMode).toEqual(fixture.componentInstance.selectionMode); + + fixture.componentInstance.selectionMode = TableRowSelectionMode.single; + fixture.detectChanges(); + + expect(directive.selectionMode).toEqual(TableRowSelectionMode.single); + expect(nativeElement.selectionMode).toEqual(TableRowSelectionMode.single); + }); }); describe('with attribute bound values', () => { @@ -263,7 +285,9 @@ describe('Nimble table', () => { @Component({ template: ` + [attr.id-field-name]="idFieldName" + [attr.selection-mode]="selectionMode" + > ` }) @@ -276,6 +300,7 @@ describe('Nimble table', () => { }] as const; public idFieldName = 'field1'; + public selectionMode: TableRowSelectionMode = TableRowSelectionMode.multiple; } let fixture: ComponentFixture; @@ -303,5 +328,16 @@ describe('Nimble table', () => { expect(directive.idFieldName).toEqual('field2'); expect(nativeElement.idFieldName).toEqual('field2'); }); + + it('can be configured with attribute binding for selectionMode', () => { + expect(directive.selectionMode).toEqual(fixture.componentInstance.selectionMode); + expect(nativeElement.selectionMode).toEqual(fixture.componentInstance.selectionMode); + + fixture.componentInstance.selectionMode = TableRowSelectionMode.single; + fixture.detectChanges(); + + expect(directive.selectionMode).toEqual(TableRowSelectionMode.single); + expect(nativeElement.selectionMode).toEqual(TableRowSelectionMode.single); + }); }); }); From be19d489dd77f6bbfb60d5ed6de08ff4f73056aa Mon Sep 17 00:00:00 2001 From: mollykreis <20542556+mollykreis@users.noreply.github.com> Date: Fri, 14 Apr 2023 09:47:19 -0500 Subject: [PATCH 2/3] Change files --- ...imble-angular-8813fe02-2dd9-40db-ac5d-b7470f7345b5.json | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 change/@ni-nimble-angular-8813fe02-2dd9-40db-ac5d-b7470f7345b5.json diff --git a/change/@ni-nimble-angular-8813fe02-2dd9-40db-ac5d-b7470f7345b5.json b/change/@ni-nimble-angular-8813fe02-2dd9-40db-ac5d-b7470f7345b5.json new file mode 100644 index 0000000000..8d35d0f61c --- /dev/null +++ b/change/@ni-nimble-angular-8813fe02-2dd9-40db-ac5d-b7470f7345b5.json @@ -0,0 +1,7 @@ +{ + "type": "patch", + "comment": "Angular support for row selection in the table", + "packageName": "@ni/nimble-angular", + "email": "20542556+mollykreis@users.noreply.github.com", + "dependentChangeType": "patch" +} From 2bf1332fe249b51ff210aa80920a964995c99869 Mon Sep 17 00:00:00 2001 From: mollykreis <20542556+mollykreis@users.noreply.github.com> Date: Fri, 14 Apr 2023 14:34:36 -0500 Subject: [PATCH 3/3] Default to no table rows --- .../src/app/customapp/customapp.component.ts | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/angular-workspace/projects/example-client-app/src/app/customapp/customapp.component.ts b/angular-workspace/projects/example-client-app/src/app/customapp/customapp.component.ts index 8e4fbd2d37..3622fd1b4e 100644 --- a/angular-workspace/projects/example-client-app/src/app/customapp/customapp.component.ts +++ b/angular-workspace/projects/example-client-app/src/app/customapp/customapp.component.ts @@ -39,14 +39,7 @@ export class CustomAppComponent { public activeAnchorTabId = 'a-tab-2'; public readonly tableData$: Observable; - private readonly tableDataSubject = new BehaviorSubject([ - { id: '0', stringValue1: 'hello world', stringValue2: 'more text' }, - { id: '1', stringValue1: 'foo', stringValue2: 'bar' }, - { id: '2', stringValue1: 'candy', stringValue2: 'bar' }, - { id: '3', stringValue1: 'dive', stringValue2: 'bar' }, - { id: '4', stringValue1: 're', stringValue2: 'bar' }, - { id: '5', stringValue1: 'last row', stringValue2: 'yay!' } - ]); + private readonly tableDataSubject = new BehaviorSubject([]); @ViewChild('dialog', { read: NimbleDialogDirective }) private readonly dialog: NimbleDialogDirective; @ViewChild('drawer', { read: NimbleDrawerDirective }) private readonly drawer: NimbleDrawerDirective;