From 3654707d132674582a8988bfc36e216df677191b Mon Sep 17 00:00:00 2001 From: Kevin Buhmann Date: Mon, 22 Jul 2024 09:14:20 -0500 Subject: [PATCH 1/2] fix(datagrid): propagate cell rendering changes only to owned rows This change prevents propagation of cell rendering changes to rows owned by nested datagrids. --- projects/angular/clarity.api.md | 4 +- .../src/data/datagrid/datagrid.spec.ts | 63 ++++++++++++++++--- .../src/data/datagrid/render/main-renderer.ts | 5 +- .../src/data/datagrid/render/row-renderer.ts | 11 +++- 4 files changed, 73 insertions(+), 10 deletions(-) diff --git a/projects/angular/clarity.api.md b/projects/angular/clarity.api.md index f3e28fa599..1e56f07fca 100644 --- a/projects/angular/clarity.api.md +++ b/projects/angular/clarity.api.md @@ -5275,13 +5275,15 @@ export class ÇlrDatagridRowRenderer implements AfterContentInit, OnDestroy { // (undocumented) cells: QueryList<ÇlrDatagridCellRenderer>; // (undocumented) + expandableRow: ÇlrDatagridRowRenderer; + // (undocumented) ngAfterContentInit(): void; // (undocumented) ngOnDestroy(): void; // (undocumented) setCellsState(): void; // (undocumented) - static ɵdir: i0.ɵɵDirectiveDeclaration<ÇlrDatagridRowRenderer, "clr-dg-row, clr-dg-row-detail", never, {}, {}, ["cells"], never, false, never>; + static ɵdir: i0.ɵɵDirectiveDeclaration<ÇlrDatagridRowRenderer, "clr-dg-row, clr-dg-row-detail", never, {}, {}, ["expandableRow", "cells"], never, false, never>; // (undocumented) static ɵfac: i0.ɵɵFactoryDeclaration<ÇlrDatagridRowRenderer, never>; } diff --git a/projects/angular/src/data/datagrid/datagrid.spec.ts b/projects/angular/src/data/datagrid/datagrid.spec.ts index 82fcd9fcc3..dc1c5186a4 100644 --- a/projects/angular/src/data/datagrid/datagrid.spec.ts +++ b/projects/angular/src/data/datagrid/datagrid.spec.ts @@ -411,23 +411,37 @@ class ProjectionTest { template: ` - First + First Second {{ item }} {{ item * item }} - - {{ item }} (col 1 detail) + + {{ item }} (col 1 detail) {{ item * item }} detail (col 2 detail) + + + + + Detail Column + + Detail Cell + + + + `, }) -class ExpandedReplacedCellsTest { +class ExpandedCellsTest { items = [1, 2, 3]; + detailItem = null; + replaceCells = false; + firstColumnHidden = false; } @Component({ @@ -784,14 +798,49 @@ export default function (): void { expect(rowDetail).not.toBeNull(); })); - it('hides cells in dg-row-detail when columns are hidden and rows are replaced', function () { - const context = this.create(ClrDatagrid, ExpandedReplacedCellsTest); + it('hides cells in dg-row-detail when column is hidden and rows are replaced', function () { + const context = this.create(ClrDatagrid, ExpandedCellsTest); + context.testComponent.replaceCells = true; + context.testComponent.firstColumnHidden = true; context.detectChanges(); - const hiddenCell: HTMLElement = context.clarityElement.querySelector('.hidden-cell'); + + const hiddenCell: HTMLElement = context.clarityElement.querySelector('.first-expandable-row-cell'); expect(hiddenCell.classList).toContain(HIDDEN_COLUMN_CLASS); expect(window.getComputedStyle(hiddenCell).display).toBe('none'); }); + it('shows cells in dg-row-detail when column is shown and rows are replaced', function () { + const context = this.create(ClrDatagrid, ExpandedCellsTest); + context.testComponent.replaceCells = true; + context.testComponent.firstColumnHidden = false; + context.detectChanges(); + + const hiddenCell: HTMLElement = context.clarityElement.querySelector('.first-expandable-row-cell'); + expect(hiddenCell.classList).not.toContain(HIDDEN_COLUMN_CLASS); + expect(window.getComputedStyle(hiddenCell).display).toBe('block'); + }); + + it('does not hide cells in nested datagrid', function () { + const context = this.create(ClrDatagrid, ExpandedCellsTest); + context.testComponent.firstColumnHidden = false; + context.testComponent.detailItem = context.testComponent.items[0]; + context.detectChanges(); + + // It is important to hide column after first render for this test. + context.testComponent.firstColumnHidden = true; + context.detectChanges(); + + // The expandable row cell should be hidden. + const firstExpandableRowCell: HTMLElement = context.clarityElement.querySelector('.first-expandable-row-cell'); + expect(firstExpandableRowCell.classList).toContain(HIDDEN_COLUMN_CLASS); + expect(window.getComputedStyle(firstExpandableRowCell).display).toBe('none'); + + // The nested datagrid cell should not be hidden. + const nestedDatagridCell: HTMLElement = context.clarityElement.querySelector('.nested-datagrid-cell'); + expect(nestedDatagridCell.classList).not.toContain(HIDDEN_COLUMN_CLASS); + expect(window.getComputedStyle(nestedDatagridCell).display).toBe('block'); + }); + it('can render mixed expandable/non-expandable', function () { const context = this.create(ClrDatagrid, MixedExpandableRowTest); const caretIcons = context.clarityElement.querySelectorAll('.datagrid-expandable-caret-icon'); diff --git a/projects/angular/src/data/datagrid/render/main-renderer.ts b/projects/angular/src/data/datagrid/render/main-renderer.ts index cbf2cd87d3..a642531706 100644 --- a/projects/angular/src/data/datagrid/render/main-renderer.ts +++ b/projects/angular/src/data/datagrid/render/main-renderer.ts @@ -54,7 +54,7 @@ export const domAdapterFactory = (platformId: any) => { }) export class DatagridMainRenderer implements AfterContentInit, AfterViewInit, AfterViewChecked, OnDestroy { @ContentChildren(DatagridHeaderRenderer) private headers: QueryList; - @ContentChildren(DatagridRowRenderer, { descendants: true }) private rows: QueryList; // if expandable row is expanded initially, query its cells too. + @ContentChildren(DatagridRowRenderer) private rows: QueryList; private _heightSet = false; private shouldStabilizeColumns = true; @@ -239,6 +239,7 @@ export class DatagridMainRenderer implements AfterContentInit, AfterViewInit, Af this.rows.forEach(row => { if (row?.cells.length === this.columnsService.columns.length) { row.cells.get(columnIndex).setWidth(state); + row.expandableRow?.cells.get(columnIndex)?.setWidth(state); } }); break; @@ -247,6 +248,7 @@ export class DatagridMainRenderer implements AfterContentInit, AfterViewInit, Af this.rows.forEach(row => { if (row.cells && row.cells.length) { row.cells.get(columnIndex).setHidden(state); + row.expandableRow?.cells.get(columnIndex)?.setHidden(state); } }); this.keyNavigation.resetKeyGrid(); @@ -256,6 +258,7 @@ export class DatagridMainRenderer implements AfterContentInit, AfterViewInit, Af this.headers.get(columnIndex).setHidden(state); this.rows.forEach(row => { row.setCellsState(); + row.expandableRow?.setCellsState(); }); } break; diff --git a/projects/angular/src/data/datagrid/render/row-renderer.ts b/projects/angular/src/data/datagrid/render/row-renderer.ts index dbf5143c52..02ac8429bf 100644 --- a/projects/angular/src/data/datagrid/render/row-renderer.ts +++ b/projects/angular/src/data/datagrid/render/row-renderer.ts @@ -5,7 +5,15 @@ * The full license information can be found in LICENSE in the root directory of this project. */ -import { AfterContentInit, ContentChildren, Directive, OnDestroy, QueryList } from '@angular/core'; +import { + AfterContentInit, + ContentChild, + ContentChildren, + Directive, + forwardRef, + OnDestroy, + QueryList, +} from '@angular/core'; import { Subscription } from 'rxjs'; import { ColumnsService } from '../providers/columns.service'; @@ -16,6 +24,7 @@ import { DatagridCellRenderer } from './cell-renderer'; }) export class DatagridRowRenderer implements AfterContentInit, OnDestroy { @ContentChildren(DatagridCellRenderer) cells: QueryList; + @ContentChild(forwardRef(() => DatagridRowRenderer)) expandableRow: DatagridRowRenderer; private subscriptions: Subscription[] = []; From 7097decc16d78fdb1ee87375d815521d744d96f7 Mon Sep 17 00:00:00 2001 From: Kevin Buhmann Date: Mon, 22 Jul 2024 21:27:05 -0500 Subject: [PATCH 2/2] add comment for regression test --- projects/angular/src/data/datagrid/datagrid.spec.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/projects/angular/src/data/datagrid/datagrid.spec.ts b/projects/angular/src/data/datagrid/datagrid.spec.ts index dc1c5186a4..d1b657869b 100644 --- a/projects/angular/src/data/datagrid/datagrid.spec.ts +++ b/projects/angular/src/data/datagrid/datagrid.spec.ts @@ -820,6 +820,7 @@ export default function (): void { expect(window.getComputedStyle(hiddenCell).display).toBe('block'); }); + // regression test for CDE-2199 it('does not hide cells in nested datagrid', function () { const context = this.create(ClrDatagrid, ExpandedCellsTest); context.testComponent.firstColumnHidden = false;