From 9a6cd813de53989b91f103a8aa704e09c6b673fc Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Fri, 21 Nov 2025 10:54:21 +0000 Subject: [PATCH] ACS-10745 File size columns not translating the tooltips (#11368) --- .../amount-cell/amount-cell.component.html | 5 +- .../amount-cell/amount-cell.component.spec.ts | 5 +- .../amount-cell/amount-cell.component.ts | 13 ++-- .../boolean-cell/boolean-cell.component.ts | 29 +++----- .../datatable-cell.component.ts | 28 +++++++- .../date-cell/date-cell.component.html | 19 ----- .../date-cell/date-cell.component.spec.ts | 35 ++++++---- .../date-cell/date-cell.component.ts | 69 ++++++++++++------- .../filesize-cell/filesize-cell.component.ts | 19 +---- .../icon-cell/icon-cell.component.ts | 37 ++++------ .../json-cell/json-cell.component.ts | 41 +++++------ .../location-cell/location-cell.component.ts | 22 +++--- .../number-cell/number-cell.component.html | 5 +- .../number-cell/number-cell.component.spec.ts | 5 +- .../number-cell/number-cell.component.ts | 9 ++- 15 files changed, 162 insertions(+), 179 deletions(-) delete mode 100644 lib/core/src/lib/datatable/components/date-cell/date-cell.component.html diff --git a/lib/core/src/lib/datatable/components/amount-cell/amount-cell.component.html b/lib/core/src/lib/datatable/components/amount-cell/amount-cell.component.html index 3b04817cce..1b5de73e71 100644 --- a/lib/core/src/lib/datatable/components/amount-cell/amount-cell.component.html +++ b/lib/core/src/lib/datatable/components/amount-cell/amount-cell.component.html @@ -1,4 +1,5 @@ - +@let amount = amountValue(); +@if (amount) { {{ amount | currency: (currencyConfig?.code || defaultCurrencyConfig.code): @@ -7,4 +8,4 @@ (currencyConfig?.locale || defaultCurrencyConfig.locale) }} - +} diff --git a/lib/core/src/lib/datatable/components/amount-cell/amount-cell.component.spec.ts b/lib/core/src/lib/datatable/components/amount-cell/amount-cell.component.spec.ts index 69481f0bf8..8ee19000bd 100644 --- a/lib/core/src/lib/datatable/components/amount-cell/amount-cell.component.spec.ts +++ b/lib/core/src/lib/datatable/components/amount-cell/amount-cell.component.spec.ts @@ -18,7 +18,6 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { AmountCellComponent } from './amount-cell.component'; import { CurrencyConfig } from '../../data/data-column.model'; -import { BehaviorSubject } from 'rxjs'; import { LOCALE_ID } from '@angular/core'; import { registerLocaleData } from '@angular/common'; import localePL from '@angular/common/locales/pl'; @@ -30,8 +29,8 @@ describe('AmountCellComponent', () => { let testingUtils: UnitTestingUtils; const renderAndCheckCurrencyValue = (currencyConfig: CurrencyConfig, value: number, expectedResult: string) => { - component.value$ = new BehaviorSubject(value); component.currencyConfig = currencyConfig; + component.value$.next(value); fixture.detectChanges(); const displayedAmount = testingUtils.getByCSS('span'); @@ -89,8 +88,8 @@ describe('AmountCellComponent locale', () => { testingUtils = new UnitTestingUtils(fixture.debugElement); registerLocaleData(localePL); - component.value$ = new BehaviorSubject(123.45); component.currencyConfig = { code: 'PLN', display: 'symbol', locale: 'pl-PL' }; + component.value$.next(123.45); fixture.detectChanges(); const displayedAmount = testingUtils.getByCSS('span'); diff --git a/lib/core/src/lib/datatable/components/amount-cell/amount-cell.component.ts b/lib/core/src/lib/datatable/components/amount-cell/amount-cell.component.ts index e2f5c083bb..0072ef7901 100644 --- a/lib/core/src/lib/datatable/components/amount-cell/amount-cell.component.ts +++ b/lib/core/src/lib/datatable/components/amount-cell/amount-cell.component.ts @@ -15,20 +15,21 @@ * limitations under the License. */ -import { ChangeDetectionStrategy, Component, ViewEncapsulation, Input, OnInit, DEFAULT_CURRENCY_CODE, inject } from '@angular/core'; +import { ChangeDetectionStrategy, Component, ViewEncapsulation, Input, DEFAULT_CURRENCY_CODE, inject } from '@angular/core'; import { DataTableCellComponent } from '../datatable-cell/datatable-cell.component'; import { CurrencyConfig } from '../../data/data-column.model'; -import { CommonModule } from '@angular/common'; +import { CurrencyPipe } from '@angular/common'; +import { toSignal } from '@angular/core/rxjs-interop'; @Component({ - imports: [CommonModule], + imports: [CurrencyPipe], selector: 'adf-amount-cell', templateUrl: './amount-cell.component.html', host: { class: 'adf-datatable-content-cell' }, encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush }) -export class AmountCellComponent extends DataTableCellComponent implements OnInit { +export class AmountCellComponent extends DataTableCellComponent { @Input() currencyConfig: CurrencyConfig; @@ -40,7 +41,5 @@ export class AmountCellComponent extends DataTableCellComponent implements OnIni locale: undefined }; - ngOnInit() { - super.ngOnInit(); - } + readonly amountValue = toSignal(this.value$); } diff --git a/lib/core/src/lib/datatable/components/boolean-cell/boolean-cell.component.ts b/lib/core/src/lib/datatable/components/boolean-cell/boolean-cell.component.ts index 310bae5abe..4c04e1f7f8 100644 --- a/lib/core/src/lib/datatable/components/boolean-cell/boolean-cell.component.ts +++ b/lib/core/src/lib/datatable/components/boolean-cell/boolean-cell.component.ts @@ -15,35 +15,26 @@ * limitations under the License. */ -import { ChangeDetectionStrategy, Component, OnInit, ViewEncapsulation } from '@angular/core'; +import { ChangeDetectionStrategy, Component, ViewEncapsulation, computed } from '@angular/core'; import { DataTableCellComponent } from '../datatable-cell/datatable-cell.component'; -import { CommonModule } from '@angular/common'; -import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; +import { toSignal } from '@angular/core/rxjs-interop'; @Component({ - imports: [CommonModule], selector: 'adf-boolean-cell', changeDetection: ChangeDetectionStrategy.OnPush, - template: ` - - {{ boolValue }} - - `, + template: ` {{ boolValue() }} `, encapsulation: ViewEncapsulation.None, host: { class: 'adf-datatable-content-cell' } }) -export class BooleanCellComponent extends DataTableCellComponent implements OnInit { - boolValue = ''; +export class BooleanCellComponent extends DataTableCellComponent { + private readonly booleanValue = toSignal(this.value$); - ngOnInit() { - super.ngOnInit(); + readonly boolValue = computed(() => { + const value = this.booleanValue(); + return this.transformBoolean(value); + }); - this.value$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((value) => { - this.boolValue = this.transformBoolean(value); - }); - } - - private transformBoolean(value: any): string { + private transformBoolean(value: unknown): string { if (value === true || value === 'true') { return 'true'; } diff --git a/lib/core/src/lib/datatable/components/datatable-cell/datatable-cell.component.ts b/lib/core/src/lib/datatable/components/datatable-cell/datatable-cell.component.ts index db9ac2dc7f..649627eaa7 100644 --- a/lib/core/src/lib/datatable/components/datatable-cell/datatable-cell.component.ts +++ b/lib/core/src/lib/datatable/components/datatable-cell/datatable-cell.component.ts @@ -15,7 +15,7 @@ * limitations under the License. */ -import { ChangeDetectionStrategy, Component, DestroyRef, inject, Input, OnInit, ViewEncapsulation, signal, computed } from '@angular/core'; +import { ChangeDetectionStrategy, Component, DestroyRef, inject, Input, OnInit, ViewEncapsulation, signal, computed, effect } from '@angular/core'; import { DataColumn } from '../../data/data-column.model'; import { DataRow } from '../../data/data-row.model'; import { DataTableAdapter } from '../../data/datatable-adapter'; @@ -25,6 +25,7 @@ import { CommonModule } from '@angular/common'; import { ClipboardDirective } from '../../../clipboard/clipboard.directive'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { TruncatePipe } from '../../../pipes/truncate.pipe'; +import { UserPreferencesService } from '../../../common/services/user-preferences.service'; @Component({ selector: 'adf-datatable-cell', @@ -77,6 +78,7 @@ export class DataTableCellComponent implements OnInit { protected destroyRef = inject(DestroyRef); protected dataTableService = inject(DataTableService, { optional: true }); + protected readonly userPreferencesService = inject(UserPreferencesService); value$ = new BehaviorSubject(''); // Signal to track the raw computed title (without tooltip override) @@ -85,6 +87,18 @@ export class DataTableCellComponent implements OnInit { // Computed signal that automatically combines tooltip input with computed title title = computed(() => this.tooltip || this.rawComputedTitle()); + // Store the latest value for locale change re-computation + private latestValue: any = null; + + constructor() { + // Listen to locale changes and re-compute the title with the latest value + effect(() => { + this.userPreferencesService.localeSignal(); + // When locale changes, re-compute title using the stored latest value + this.recomputeTitle(); + }); + } + ngOnInit() { this.updateValue(); this.subscribeToRowUpdates(); @@ -94,10 +108,20 @@ export class DataTableCellComponent implements OnInit { if (this.column?.key && this.row && this.data) { const value = this.data.getValue(this.row, this.column, this.resolverFn); this.value$.next(value); - this.rawComputedTitle.set(this.computeTitle(value)); + // Store the value for locale change re-computation and update the title + this.latestValue = value; + this.recomputeTitle(); } } + /** + * Re-computes the title based on the current latestValue. + * This is called both when the value changes (via updateValue) and when the locale changes (via effect). + */ + private recomputeTitle(): void { + this.rawComputedTitle.set(this.computeTitle(this.latestValue)); + } + private subscribeToRowUpdates() { if (!this.dataTableService || !this.row.obj) { return; diff --git a/lib/core/src/lib/datatable/components/date-cell/date-cell.component.html b/lib/core/src/lib/datatable/components/date-cell/date-cell.component.html deleted file mode 100644 index abac2de12b..0000000000 --- a/lib/core/src/lib/datatable/components/date-cell/date-cell.component.html +++ /dev/null @@ -1,19 +0,0 @@ -@let date = value$ | async; - -@if (date) { - - @if (config.format === 'timeAgo') { - @if (config.locale) { - {{ date | adfTimeAgo: config.locale }} - } @else { - {{ date | adfTimeAgo }} - } - } @else { - @if (config.locale) { - {{ date | adfLocalizedDate: config.format: config.locale }} - } @else { - {{ date | adfLocalizedDate: config.format }} - } - } - -} diff --git a/lib/core/src/lib/datatable/components/date-cell/date-cell.component.spec.ts b/lib/core/src/lib/datatable/components/date-cell/date-cell.component.spec.ts index d7e57c4b6f..76906dcff6 100644 --- a/lib/core/src/lib/datatable/components/date-cell/date-cell.component.spec.ts +++ b/lib/core/src/lib/datatable/components/date-cell/date-cell.component.spec.ts @@ -18,7 +18,6 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { DateCellComponent } from './date-cell.component'; import { DataColumn, DateConfig } from '../../data/data-column.model'; -import { BehaviorSubject } from 'rxjs'; import { AppConfigService } from '../../../app-config'; import { LOCALE_ID } from '@angular/core'; import { registerLocaleData } from '@angular/common'; @@ -39,25 +38,31 @@ const mockColumn: DataColumn = { const renderDateCell = (dateConfig: DateConfig, value: number | string | Date, tooltip?: string) => { // Set up mock data if not already set - if (!component.data) { - component.data = { - getValue: () => value - } as any; - } - if (!component.row) { - component.row = { id: '1', getValue: () => value } as any; - } + component.data = { + getValue: () => value + } as any; + component.row = { id: '1', getValue: () => value } as any; + + // Only set column if not already set (preserve any test-specific column config) if (!component.column) { component.column = { key: 'date' } as any; } - component.value$ = new BehaviorSubject(value); component.dateConfig = dateConfig; + if (tooltip) { component.tooltip = tooltip; } + // Initialize the component first, then emit the value component.ngOnInit(); + + // Trigger config recalculation by simulating a locale change + // This is needed when column.format is set after component construction + (component as any).setConfig(); + + // Emit the value to the observable which will trigger the signal update + component.value$.next(value); fixture.detectChanges(); }; @@ -131,9 +136,9 @@ describe('DateCellComponent', () => { checkDisplayedDate(expectedDate); checkDisplayedTooltip(expectedTooltip); - expect(component.config.format).toEqual('mediumDate'); - expect(component.config.tooltipFormat).toEqual('long'); - expect(component.config.locale).toEqual('en-US'); + expect(component.config().format).toEqual('mediumDate'); + expect(component.config().tooltipFormat).toEqual('long'); + expect(component.config().locale).toEqual('en-US'); }); it('should display date and tooltip with defaules values if NO dateConfig or appConfig is provided', () => { @@ -165,13 +170,15 @@ describe('DateCellComponent', () => { }); it('should display date with timeAgo format if NO dateConfig and column format provided', () => { - component.column = { ...mockColumn, format: 'timeAgo' }; const mockDateConfig = undefined as any; const today = new Date(); const yesterday = new Date(today); yesterday.setDate(today.getDate() - 1); const expectedDate = '1 day ago'; + + // Set column format before calling renderDateCell + component.column = { ...mockColumn, format: 'timeAgo' }; renderDateCell(mockDateConfig, yesterday); checkDisplayedDate(expectedDate); }); diff --git a/lib/core/src/lib/datatable/components/date-cell/date-cell.component.ts b/lib/core/src/lib/datatable/components/date-cell/date-cell.component.ts index 7853d63eb3..791a9d258b 100644 --- a/lib/core/src/lib/datatable/components/date-cell/date-cell.component.ts +++ b/lib/core/src/lib/datatable/components/date-cell/date-cell.component.ts @@ -15,33 +15,34 @@ * limitations under the License. */ -import { ChangeDetectionStrategy, Component, Input, OnInit, ViewEncapsulation, inject, ChangeDetectorRef, effect } from '@angular/core'; +import { ChangeDetectionStrategy, Component, Input, OnInit, ViewEncapsulation, inject, effect, signal, computed } from '@angular/core'; import { DataTableCellComponent } from '../datatable-cell/datatable-cell.component'; import { AppConfigService } from '../../../app-config/app-config.service'; import { DateConfig } from '../../data/data-column.model'; import { LocalizedDatePipe, TimeAgoPipe } from '../../../pipes'; -import { AsyncPipe } from '@angular/common'; -import { UserPreferencesService } from '../../../common/services/user-preferences.service'; +import { toSignal } from '@angular/core/rxjs-interop'; @Component({ - imports: [LocalizedDatePipe, TimeAgoPipe, AsyncPipe], selector: 'adf-date-cell', - templateUrl: './date-cell.component.html', + template: ` + @if (formattedDate()) { + {{ formattedDate() }} + } + `, encapsulation: ViewEncapsulation.None, host: { class: 'adf-datatable-content-cell' }, changeDetection: ChangeDetectionStrategy.OnPush, - providers: [LocalizedDatePipe] + providers: [LocalizedDatePipe, TimeAgoPipe] }) export class DateCellComponent extends DataTableCellComponent implements OnInit { @Input() dateConfig: DateConfig; - config: DateConfig = {}; + config = signal({}); - private readonly appConfig: AppConfigService = inject(AppConfigService); - private readonly localizedDatePipe: LocalizedDatePipe = inject(LocalizedDatePipe); - private readonly userPreferencesService: UserPreferencesService = inject(UserPreferencesService); - private readonly cdr: ChangeDetectorRef = inject(ChangeDetectorRef); + private readonly appConfig = inject(AppConfigService); + private readonly localizedDatePipe = inject(LocalizedDatePipe); + private readonly timeAgoPipe = inject(TimeAgoPipe); private userLocale: string = 'en'; @@ -51,14 +52,31 @@ export class DateCellComponent extends DataTableCellComponent implements OnInit locale: undefined }; + // Convert value$ observable to signal for reactive computation + private readonly dateValue = toSignal(this.value$); + + // Computed signal that automatically formats the date based on value and config + protected readonly formattedDate = computed(() => { + const date = this.dateValue(); + const currentConfig = this.config(); + + if (!date) { + return ''; + } + + if (currentConfig.format === 'timeAgo') { + return this.timeAgoPipe.transform(date, currentConfig.locale) || ''; + } + + return this.localizedDatePipe.transform(date, currentConfig.format, currentConfig.locale) || ''; + }); + constructor() { super(); // Use effect to react to locale signal changes (must be in injection context) effect(() => { this.userLocale = this.userPreferencesService.localeSignal() || 'en'; this.setConfig(); - this.updateValue(); // Recalculate computedTitle with new locale - this.cdr.markForCheck(); }); } @@ -68,7 +86,8 @@ export class DateCellComponent extends DataTableCellComponent implements OnInit protected override computeTitle(value: any): string { if (value) { - return this.localizedDatePipe.transform(value, this.config.tooltipFormat, this.config.locale) || ''; + const currentConfig = this.config(); + return this.localizedDatePipe.transform(value, currentConfig.tooltipFormat, currentConfig.locale) || ''; } return ''; } @@ -82,15 +101,19 @@ export class DateCellComponent extends DataTableCellComponent implements OnInit } private setCustomConfig(): void { - this.config.format = this.dateConfig?.format || this.getDefaultFormat(); - this.config.tooltipFormat = this.dateConfig?.tooltipFormat || this.getDefaultTooltipFormat(); - this.config.locale = this.normalizeLocale(this.dateConfig?.locale || this.getDefaultLocale()); + this.config.set({ + format: this.dateConfig?.format || this.getDefaultFormat(), + tooltipFormat: this.dateConfig?.tooltipFormat || this.getDefaultTooltipFormat(), + locale: this.normalizeLocale(this.dateConfig?.locale || this.userLocale) + }); } private setDefaultConfig(): void { - this.config.format = this.getDefaultFormat(); - this.config.tooltipFormat = this.getDefaultTooltipFormat(); - this.config.locale = this.normalizeLocale(this.getDefaultLocale()); + this.config.set({ + format: this.getDefaultFormat(), + tooltipFormat: this.getDefaultTooltipFormat(), + locale: this.normalizeLocale(this.userLocale) + }); } private normalizeLocale(locale: string): string { @@ -109,12 +132,6 @@ export class DateCellComponent extends DataTableCellComponent implements OnInit return this.column?.format || this.getAppConfigPropertyValue('dateValues.defaultDateFormat', this.defaultDateConfig.format); } - private getDefaultLocale(): string { - // Always use the user locale from UserPreferencesService - // This is kept in sync via subscription and reflects the user's current locale choice - return this.userLocale; - } - private getDefaultTooltipFormat(): string { return this.getAppConfigPropertyValue('dateValues.defaultTooltipDateFormat', this.defaultDateConfig.tooltipFormat); } diff --git a/lib/core/src/lib/datatable/components/filesize-cell/filesize-cell.component.ts b/lib/core/src/lib/datatable/components/filesize-cell/filesize-cell.component.ts index 1fa35219b7..bb5c82395a 100644 --- a/lib/core/src/lib/datatable/components/filesize-cell/filesize-cell.component.ts +++ b/lib/core/src/lib/datatable/components/filesize-cell/filesize-cell.component.ts @@ -15,7 +15,7 @@ * limitations under the License. */ -import { Component, OnInit, ViewEncapsulation, inject } from '@angular/core'; +import { Component, ViewEncapsulation } from '@angular/core'; import { DataTableCellComponent } from '../datatable-cell/datatable-cell.component'; import { FileSizePipe } from '../../../pipes'; import { AsyncPipe } from '@angular/common'; @@ -25,23 +25,10 @@ import { AsyncPipe } from '@angular/common'; imports: [FileSizePipe, AsyncPipe], template: ` @let value = value$ | async; - {{ value | adfFileSize }} + {{ value | adfFileSize }} `, encapsulation: ViewEncapsulation.None, host: { class: 'adf-filesize-cell' }, providers: [FileSizePipe] }) -export class FileSizeCellComponent extends DataTableCellComponent implements OnInit { - private readonly fileSizePipe = inject(FileSizePipe); - - ngOnInit(): void { - super.ngOnInit(); - } - - protected override computeTitle(value: any): string { - if (value != null) { - return this.fileSizePipe.transform(value); - } - return ''; - } -} +export class FileSizeCellComponent extends DataTableCellComponent {} diff --git a/lib/core/src/lib/datatable/components/icon-cell/icon-cell.component.ts b/lib/core/src/lib/datatable/components/icon-cell/icon-cell.component.ts index 5a285a78ab..96dee74775 100644 --- a/lib/core/src/lib/datatable/components/icon-cell/icon-cell.component.ts +++ b/lib/core/src/lib/datatable/components/icon-cell/icon-cell.component.ts @@ -15,43 +15,32 @@ * limitations under the License. */ -import { CommonModule } from '@angular/common'; -import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnInit, ViewEncapsulation } from '@angular/core'; +import { ChangeDetectionStrategy, Component, ViewEncapsulation, computed } from '@angular/core'; import { MatIconModule } from '@angular/material/icon'; import { DataTableCellComponent } from '../datatable-cell/datatable-cell.component'; -import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; +import { toSignal } from '@angular/core/rxjs-interop'; @Component({ - imports: [CommonModule, MatIconModule], + imports: [MatIconModule], selector: 'adf-icon-cell', changeDetection: ChangeDetectionStrategy.OnPush, template: ` - - - + @if (icon()) { + + } `, encapsulation: ViewEncapsulation.None, host: { class: 'adf-datatable-content-cell' } }) -export class IconCellComponent extends DataTableCellComponent implements OnInit { - icon: string = ''; +export class IconCellComponent extends DataTableCellComponent { + private readonly iconValue = toSignal(this.value$); - constructor(private changeDetectorRef: ChangeDetectorRef) { - super(); - } + readonly icon = computed(() => { + const value = this.iconValue(); + return this.validateIconValue(value) ? value : ''; + }); - ngOnInit(): void { - super.ngOnInit(); - this.value$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((value) => { - const newIcon = this.validateIconValue(value) ? value : ''; - if (this.icon !== newIcon) { - this.icon = newIcon; - this.changeDetectorRef.detectChanges(); - } - }); - } - - private validateIconValue(value: any): boolean { + private validateIconValue(value: unknown): boolean { return typeof value === 'string'; } } diff --git a/lib/core/src/lib/datatable/components/json-cell/json-cell.component.ts b/lib/core/src/lib/datatable/components/json-cell/json-cell.component.ts index 5f5875ad35..9a644286b6 100644 --- a/lib/core/src/lib/datatable/components/json-cell/json-cell.component.ts +++ b/lib/core/src/lib/datatable/components/json-cell/json-cell.component.ts @@ -15,46 +15,45 @@ * limitations under the License. */ -import { ChangeDetectionStrategy, Component, OnInit, ViewEncapsulation, Input } from '@angular/core'; +import { ChangeDetectionStrategy, Component, ViewEncapsulation, Input, computed } from '@angular/core'; import { DataTableCellComponent } from '../datatable-cell/datatable-cell.component'; import { MatDialog, MatDialogModule } from '@angular/material/dialog'; import { EditJsonDialogComponent, EditJsonDialogSettings } from '../../../dialogs/edit-json/edit-json.dialog'; -import { CommonModule } from '@angular/common'; import { MatButtonModule } from '@angular/material/button'; +import { toSignal } from '@angular/core/rxjs-interop'; @Component({ selector: 'adf-json-cell', - imports: [CommonModule, MatButtonModule, MatDialogModule], + imports: [MatButtonModule, MatDialogModule], changeDetection: ChangeDetectionStrategy.OnPush, template: ` - - - - - - - + @if (shouldShowButton()) { + + } `, styleUrls: ['./json-cell.component.scss'], encapsulation: ViewEncapsulation.None, host: { class: 'adf-datatable-content-cell' } }) -export class JsonCellComponent extends DataTableCellComponent implements OnInit { +export class JsonCellComponent extends DataTableCellComponent { /** Editable JSON. */ @Input() editable: boolean = false; + private readonly jsonValue = toSignal(this.value$); + + readonly shouldShowButton = computed(() => { + const value = this.jsonValue(); + return !!value || this.editable; + }); + constructor(private dialog: MatDialog) { super(); } - ngOnInit() { - super.ngOnInit(); - } - view() { - const rawValue: string | any = this.data.getValue(this.row, this.column, this.resolverFn); - const value = typeof rawValue === 'object' ? JSON.stringify(rawValue || {}, null, 2) : rawValue; + const rawValue = this.data.getValue(this.row, this.column, this.resolverFn); + const value = typeof rawValue === 'object' ? JSON.stringify(rawValue || {}, null, 2) : String(rawValue ?? ''); const settings: EditJsonDialogSettings = { title: this.column.title, @@ -69,12 +68,6 @@ export class JsonCellComponent extends DataTableCellComponent implements OnInit minHeight: '50%' }) .afterClosed() - .subscribe((/*result: string*/) => { - if (typeof rawValue === 'object') { - // todo: update cell value as object - } else { - // todo: update cell value as string - } - }); + .subscribe(); } } diff --git a/lib/core/src/lib/datatable/components/location-cell/location-cell.component.ts b/lib/core/src/lib/datatable/components/location-cell/location-cell.component.ts index f84fa8009a..d7f82729b0 100644 --- a/lib/core/src/lib/datatable/components/location-cell/location-cell.component.ts +++ b/lib/core/src/lib/datatable/components/location-cell/location-cell.component.ts @@ -15,33 +15,29 @@ * limitations under the License. */ -import { ChangeDetectionStrategy, Component, Input, OnInit, ViewEncapsulation } from '@angular/core'; +import { ChangeDetectionStrategy, Component, Input, ViewEncapsulation } from '@angular/core'; import { DataTableCellComponent } from '../datatable-cell/datatable-cell.component'; -import { AsyncPipe } from '@angular/common'; import { RouterModule } from '@angular/router'; import { PathInfo } from '../../../models/path.model'; +import { toSignal } from '@angular/core/rxjs-interop'; @Component({ - imports: [AsyncPipe, RouterModule], + imports: [RouterModule], selector: 'adf-location-cell', changeDetection: ChangeDetectionStrategy.OnPush, template: ` - - - {{ value$ | async }} - - + + {{ locationValue() }} + `, encapsulation: ViewEncapsulation.None, host: { class: 'adf-location-cell adf-datatable-content-cell' } }) -export class LocationCellComponent extends DataTableCellComponent implements OnInit { +export class LocationCellComponent extends DataTableCellComponent { @Input() - link: any[]; + link: (string | number)[]; - ngOnInit() { - super.ngOnInit(); - } + readonly locationValue = toSignal(this.value$); protected updateValue(): void { if (this.column?.key && this.column?.format && this.row && this.data) { diff --git a/lib/core/src/lib/datatable/components/number-cell/number-cell.component.html b/lib/core/src/lib/datatable/components/number-cell/number-cell.component.html index 87eb4dbc3a..fc6233bf01 100644 --- a/lib/core/src/lib/datatable/components/number-cell/number-cell.component.html +++ b/lib/core/src/lib/datatable/components/number-cell/number-cell.component.html @@ -1,8 +1,9 @@ - +@let number = numberValue(); +@if (number) { {{ number | number: (decimalConfig?.digitsInfo || defaultDecimalConfig.digitsInfo): (decimalConfig?.locale || defaultDecimalConfig.locale) }} - +} diff --git a/lib/core/src/lib/datatable/components/number-cell/number-cell.component.spec.ts b/lib/core/src/lib/datatable/components/number-cell/number-cell.component.spec.ts index 8f193ec8d5..47fe111dde 100644 --- a/lib/core/src/lib/datatable/components/number-cell/number-cell.component.spec.ts +++ b/lib/core/src/lib/datatable/components/number-cell/number-cell.component.spec.ts @@ -18,7 +18,6 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { NumberCellComponent } from './number-cell.component'; import { DecimalConfig } from '../../data/data-column.model'; -import { BehaviorSubject } from 'rxjs'; import { LOCALE_ID } from '@angular/core'; import { registerLocaleData } from '@angular/common'; import localePL from '@angular/common/locales/pl'; @@ -30,8 +29,8 @@ describe('NumberCellComponent', () => { let testingUtils: UnitTestingUtils; const renderAndCheckNumberValue = (decimalConfig: DecimalConfig, value: number, expectedResult: string) => { - component.value$ = new BehaviorSubject(value); component.decimalConfig = decimalConfig; + component.value$.next(value); fixture.detectChanges(); const displayedNumber = testingUtils.getByCSS('span'); @@ -79,8 +78,8 @@ describe('NumberCellComponent locale', () => { testingUtils = new UnitTestingUtils(fixture.debugElement); registerLocaleData(localePL); - component.value$ = new BehaviorSubject(123.45); component.decimalConfig = { locale: 'pl-PL' }; + component.value$.next(123.45); fixture.detectChanges(); const displayedNumber = testingUtils.getByCSS('span'); diff --git a/lib/core/src/lib/datatable/components/number-cell/number-cell.component.ts b/lib/core/src/lib/datatable/components/number-cell/number-cell.component.ts index 4f624cd8ae..0725126da1 100644 --- a/lib/core/src/lib/datatable/components/number-cell/number-cell.component.ts +++ b/lib/core/src/lib/datatable/components/number-cell/number-cell.component.ts @@ -15,10 +15,11 @@ * limitations under the License. */ -import { ChangeDetectionStrategy, Component, ViewEncapsulation, Input, OnInit } from '@angular/core'; +import { ChangeDetectionStrategy, Component, ViewEncapsulation, Input } from '@angular/core'; import { DataTableCellComponent } from '../datatable-cell/datatable-cell.component'; import { DecimalConfig } from '../../data/data-column.model'; import { CommonModule } from '@angular/common'; +import { toSignal } from '@angular/core/rxjs-interop'; @Component({ imports: [CommonModule], @@ -28,7 +29,7 @@ import { CommonModule } from '@angular/common'; encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush }) -export class NumberCellComponent extends DataTableCellComponent implements OnInit { +export class NumberCellComponent extends DataTableCellComponent { @Input() decimalConfig: DecimalConfig; @@ -37,7 +38,5 @@ export class NumberCellComponent extends DataTableCellComponent implements OnIni locale: undefined }; - ngOnInit() { - super.ngOnInit(); - } + readonly numberValue = toSignal(this.value$); }