[AAE-16965] Improve data table date column (#9038)

* [AAE-16965] Improve Date data table column type

* [AAE-16965] Date unit tests

* update docs

* cleanup cells after implement inject

* bring back removed constructors

* remove empty constructors

* replace constructor token injection by inject function

* [AAE-16965] Use other variable for template

* implement suggestions

* update demo shell module

* fix unit test

* fix timeAgo problem

* add some more unit tests

* fake change in extensions

* [AAE-16965] fix for backward compatibility
This commit is contained in:
Tomasz Gnyp 2023-11-03 10:31:13 +01:00 committed by GitHub
parent 85ddcdf22c
commit 9278d9296f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 452 additions and 171 deletions

View File

@ -19,7 +19,7 @@ import { NgModule } from '@angular/core';
import { TaskListDemoComponent } from './task-list-demo.component';
import { Routes, RouterModule } from '@angular/router';
import { CommonModule } from '@angular/common';
import { CoreModule } from '@alfresco/adf-core';
import { CoreModule, LocalizedDatePipe } from '@alfresco/adf-core';
import { ProcessModule } from '@alfresco/adf-process-services';
const routes: Routes = [
@ -38,7 +38,8 @@ const routes: Routes = [
CommonModule,
RouterModule.forChild(routes),
CoreModule,
ProcessModule.forChild()
ProcessModule.forChild(),
LocalizedDatePipe
],
declarations: [TaskListDemoComponent]
})

View File

@ -63,6 +63,7 @@ Defines column properties for DataTable, Tasklist, Document List and other compo
| order | `number` | | Sets position of column. |
| currencyConfig | `CurrencyConfig` | [Default currency config](#default-currency-config) | Currency configuration to customize the formatting and display of currency values within the component. |
| decimalConfig | `DecimalConfig` | [Default decimal config](#default-decimal-config) | Decimal configuration to customize the formatting and display of decimal values within the component. |
| dateConfig | `DateConfig` | [Default date config](#default-date-config) | Date configuration to customize the formatting and localization of date values within the component. |
## Properties configuration
@ -72,6 +73,7 @@ The `type` input allows us to specify the type of hosted values for a given colu
- `text` - The given values are represented as a strings (default option).
- `boolean` - The column expects true / false (boolean values) and in addition accepts two strings - 'false' and 'true'. Other values are not recognized by the column, and the cell remains empty.
- `date` - This column is responsible for displaying dates. It expects date represented by a string, number or Date object. This type comes with [`dateConfig`](#default-date-config),
- `amount` - This column is responsible for displaying currencies. It expects numerals represented by a string or a number. This type comes with [`currencyConfig`](#default-currency-config),
- `number` - This column is responsible for displaying numbers (integers and decimals). It expects numerals represented by a string or a number. This type comes with [`decimalConfig`](#default-decimal-config)
- `location` - This column displays a clickable location link pointing to the parent path of the node. **Note:** This type is strongly related to the document list component ([document-list.component.md](../../content-services/components/document-list.component.md)).
@ -120,6 +122,28 @@ These properties offer flexibility in customizing how decimal values are present
For more details on the possible use cases of the above properties, see the [official Angular documents](https://angular.io/api/common/DecimalPipe).
### `dateConfig` Input
The `dateConfig` input allows you to configure date formatting and localization for a component. It accepts an object of type `DateConfig` with optional properties for specifying the format of displayed date, tooltip and locale.
#### Properties
- `format` (optional): A string specifying the date format ([pre-defined formats](https://angular.io/api/common/DatePipe#pre-defined-format-options)).
- `tooltipFormat` (optional): A string specifying the date format for tooltips.
- `locale` (optional): A string indicating the locale or region-specific formatting to use for the currency.
#### Default date config
By default, the `dateConfig` object is not required. If not provided, the component will use the following default values:
- `format`: "medium"
- `tooltipFormat`: "medium"
- `locale`: undefined
These properties offer flexibility in customizing how date values are presented within the component.
For more details on the possible use cases of the above properties, see the [official Angular documents](https://angular.io/api/common/DatePipe).
## Details
### Conditional visibility

View File

@ -20,13 +20,11 @@ import {
Component,
ViewEncapsulation,
Input,
Optional,
OnInit,
DEFAULT_CURRENCY_CODE,
Inject
inject
} from '@angular/core';
import { DataTableCellComponent } from '../datatable-cell/datatable-cell.component';
import { DataTableService } from '../../services/datatable.service';
import { CurrencyConfig } from '../../data/data-column.model';
import { CommonModule } from '@angular/common';
@ -44,6 +42,8 @@ export class AmountCellComponent extends DataTableCellComponent implements OnIni
@Input()
currencyConfig: CurrencyConfig;
private readonly defaultCurrencyCode: string = inject(DEFAULT_CURRENCY_CODE);
readonly defaultCurrencyConfig: CurrencyConfig = {
code: this.defaultCurrencyCode,
display: 'symbol',
@ -51,16 +51,7 @@ export class AmountCellComponent extends DataTableCellComponent implements OnIni
locale: undefined
};
constructor(
@Optional() dataTableService: DataTableService,
@Inject(DEFAULT_CURRENCY_CODE) private readonly defaultCurrencyCode: string
) {
super(dataTableService);
}
ngOnInit() {
if (this.column?.key && this.row && this.data) {
this.value$.next(this.data.getValue(this.row, this.column, this.resolverFn));
}
super.ngOnInit();
}
}

View File

@ -15,10 +15,9 @@
* limitations under the License.
*/
import { ChangeDetectionStrategy, Component, OnInit, Optional, ViewEncapsulation } from '@angular/core';
import { ChangeDetectionStrategy, Component, OnInit, ViewEncapsulation } from '@angular/core';
import { DataTableCellComponent } from '../datatable-cell/datatable-cell.component';
import { CommonModule } from '@angular/common';
import { DataTableService } from '../../services/datatable.service';
import { BooleanPipe } from '../../../pipes/boolean.pipe';
@Component({
@ -37,13 +36,8 @@ import { BooleanPipe } from '../../../pipes/boolean.pipe';
host: { class: 'adf-datatable-content-cell' }
})
export class BooleanCellComponent extends DataTableCellComponent implements OnInit {
constructor(@Optional() dataTableService: DataTableService) {
super(dataTableService);
}
ngOnInit() {
if (this.column?.key && this.row && this.data) {
this.value$.next(this.data.getValue(this.row, this.column, this.resolverFn));
}
super.ngOnInit();
}
}

View File

@ -15,58 +15,86 @@
* limitations under the License.
*/
import { UserPreferencesService } from '../../../common/services/user-preferences.service';
import { AppConfigService } from '../../../app-config';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { CoreTestingModule } from '../../../testing';
import { DateCellComponent } from '../date-cell/date-cell.component';
import { DataTableCellComponent } from './datatable-cell.component';
import { DataRow } from '../../data/data-row.model';
import { BehaviorSubject } from 'rxjs/internal/BehaviorSubject';
import { DataTableService } from '../../services/datatable.service';
import { ObjectDataTableAdapter } from '../../data/object-datatable-adapter';
import { mockCarsData, mockCarsSchemaDefinition } from '../mocks/datatable.mock';
describe('DateCellComponent', () => {
let appConfigService: AppConfigService;
let userPreferencesService: UserPreferencesService;
let fixture: ComponentFixture<DateCellComponent>;
let component: DateCellComponent;
let getLocaleSpy: jasmine.Spy;
describe('DataTableCellComponent', () => {
let component: DataTableCellComponent;
let fixture: ComponentFixture<DataTableCellComponent>;
let dataTableService: DataTableService;
const renderTextCell = (value: string, tooltip: string) => {
component.value$ = new BehaviorSubject<string>(value);
component.tooltip = tooltip;
fixture.detectChanges();
};
const checkDisplayedText = (expectedText: string) => {
const displayedText = fixture.nativeElement.querySelector('span').textContent.trim();
expect(displayedText).toBeTruthy();
expect(displayedText).toBe(expectedText);
};
const checkDisplayedTooltip = (expectedTooltip: string) => {
const displayedTooltip = fixture.nativeElement.querySelector('span').title;
expect(displayedTooltip).toBeTruthy();
expect(displayedTooltip).toBe(expectedTooltip);
};
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
CoreTestingModule
],
declarations: [DateCellComponent]
declarations: [DataTableCellComponent],
providers: [DataTableService]
});
appConfigService = TestBed.inject(AppConfigService);
userPreferencesService = TestBed.inject(UserPreferencesService);
getLocaleSpy = spyOn(userPreferencesService, 'select').and.callThrough();
appConfigService.config = {
dateValues: {
defaultDateFormat: 'mediumDate',
defaultTooltipDateFormat: 'medium'
}
};
fixture = TestBed.createComponent(DateCellComponent);
fixture = TestBed.createComponent(DataTableCellComponent);
component = fixture.componentInstance;
dataTableService = TestBed.inject(DataTableService);
});
it('should read locale from user preferences service', () => {
expect(getLocaleSpy).toHaveBeenCalledWith('locale');
expect(component.currentLocale).toEqual('en');
it('should display text and tooltip', () => {
const row: DataRow = {
id: '1',
isSelected: false,
hasValue: () => true,
getValue: () => 'hello world',
obj: 'Initial Value',
cache: []
};
component.row = row;
renderTextCell('hello world', 'hello world tooltip');
checkDisplayedText('hello world');
checkDisplayedTooltip('hello world tooltip');
});
it('should read date format values from app config service', () => {
expect(component.format).toEqual('mediumDate');
expect(component.tooltipDateFormat).toEqual('medium');
});
it('should update row obj value on data changes', () => {
const row: DataRow = {
id: '1',
isSelected: false,
hasValue: () => true,
getValue: () => 'hello world',
obj: 'Initial Value',
cache: []
};
component.data = new ObjectDataTableAdapter(mockCarsData, mockCarsSchemaDefinition);
component.column = { key: 'car_name', type: 'text' };
component.row = row;
it('should date values be formatted based on the formats defined in the app config', () => {
component.value$.next('2022-07-14T11:50:45.973+0000');
component.tooltip = '2022-07-14T11:50:45.973+0000';
fixture.detectChanges();
const dateCellValue = fixture.nativeElement.querySelector('.adf-datatable-cell-value');
const tooltipValue = dateCellValue.attributes['title'].value;
dataTableService.rowUpdate.next({ id: '1', obj: 'New Value' });
expect(dateCellValue.textContent.trim()).toEqual('Jul 14, 2022');
expect(tooltipValue).toEqual('Jul 14, 2022, 11:50:45 AM');
expect(component.row.obj).toBe('New Value');
});
});

View File

@ -15,7 +15,7 @@
* limitations under the License.
*/
import { ChangeDetectionStrategy, Component, Input, OnInit, ViewEncapsulation, OnDestroy, Optional } from '@angular/core';
import { ChangeDetectionStrategy, Component, Input, OnInit, ViewEncapsulation, OnDestroy, inject } from '@angular/core';
import { DataColumn } from '../../data/data-column.model';
import { DataRow } from '../../data/data-row.model';
import { DataTableAdapter } from '../../data/datatable-adapter';
@ -58,8 +58,6 @@ export class DataTableCellComponent implements OnInit, OnDestroy {
@Input()
row: DataRow;
value$ = new BehaviorSubject<any>('');
/** Enables/disables a Clipboard directive to allow copying of the cell's content. */
@Input()
copyContent: boolean;
@ -73,8 +71,9 @@ export class DataTableCellComponent implements OnInit, OnDestroy {
resolverFn: (row: DataRow, col: DataColumn) => any = null;
protected onDestroy$ = new Subject<boolean>();
protected dataTableService = inject(DataTableService, { optional: true });
constructor(@Optional() protected dataTableService: DataTableService) {}
value$ = new BehaviorSubject<any>('');
ngOnInit() {
this.updateValue();
@ -97,6 +96,7 @@ export class DataTableCellComponent implements OnInit, OnDestroy {
if (!this.dataTableService || !this.row.obj) {
return;
}
this.dataTableService.rowUpdate.pipe(takeUntil(this.onDestroy$)).subscribe((data) => {
if (data?.id === this.row?.id && data.obj) {
this.row.obj = data.obj;

View File

@ -253,7 +253,8 @@
[column]="col"
[row]="row"
[resolverFn]="resolverFn"
[tooltip]="getCellTooltip(row, col)">
[tooltip]="getCellTooltip(row, col)"
[dateConfig]="col.dateConfig">
</adf-date-cell>
</div>
<div *ngSwitchCase="'location'" [attr.tabindex]="data.getValue(row, col, resolverFn)? 0 : -1" class="adf-cell-value"

View File

@ -1229,6 +1229,17 @@ describe('DataTable', () => {
expect(rows[1].getValue('fuel_consumption')).toBe(6);
expect(rows[2].getValue('fuel_consumption')).toBe(4.9);
});
it('should be able to display column of type date', () => {
dataTable.data = new ObjectDataTableAdapter(mockCarsData, mockCarsSchemaDefinition);
fixture.detectChanges();
const rows = dataTable.data.getRows();
expect(rows[0].getValue('production_start')).toBe('1972-04-23');
expect(rows[1].getValue('production_start')).toBe('1998-06-25T12:25:20');
expect(rows[2].getValue('production_start')).toBe('2004-02-10T12:25:43.511Z');
});
});
describe('Accesibility', () => {

View File

@ -0,0 +1,15 @@
<ng-container *ngIf="value$ | async as date">
<span
[title]="tooltip | adfLocalizedDate: config.tooltipFormat: config.locale"
class="adf-datatable-cell-value"
*ngIf="format === 'timeAgo'; else standard_date">
{{ date | adfTimeAgo: config.locale }}
</span>
<ng-template #standard_date>
<span
class="adf-datatable-cell-value"
[title]="tooltip | adfLocalizedDate: config.tooltipFormat: config.locale">
{{ date | adfLocalizedDate: format: config.locale }}
</span>
</ng-template>
</ng-container>

View File

@ -0,0 +1,235 @@
/*!
* @license
* Copyright © 2005-2023 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
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 { HttpClientTestingModule } from '@angular/common/http/testing';
import { TranslateModule } from '@ngx-translate/core';
import { LOCALE_ID } from '@angular/core';
import { registerLocaleData } from '@angular/common';
import localePL from '@angular/common/locales/pl';
let component: DateCellComponent;
let appConfigService: AppConfigService;
let fixture: ComponentFixture<DateCellComponent>;
const mockDate = new Date('2023-10-25');
const mockTooltip = mockDate.toISOString();
const mockColumn: DataColumn = {
key: 'mock-date',
type: 'date',
format: 'full'
};
const renderDateCell = (dateConfig: DateConfig, value: number | string | Date, tooltip: string) => {
component.value$ = new BehaviorSubject<number | string | Date>(value);
component.dateConfig = dateConfig;
component.tooltip = tooltip;
fixture.detectChanges();
};
const checkDisplayedDate = (expectedDate: string) => {
const displayedDate = fixture.nativeElement.querySelector('span').textContent.trim();
expect(displayedDate).toBeTruthy();
expect(displayedDate).toBe(expectedDate);
};
const checkDisplayedTooltip = (expectedTooltip: string) => {
const displayedTooltip = fixture.nativeElement.querySelector('span').title;
expect(displayedTooltip).toBeTruthy();
expect(displayedTooltip).toBe(expectedTooltip);
};
const configureTestingModule = (providers: any[]) => {
TestBed.configureTestingModule({
imports: [
DateCellComponent,
HttpClientTestingModule,
TranslateModule.forRoot()
],
providers
});
fixture = TestBed.createComponent(DateCellComponent);
component = fixture.componentInstance;
appConfigService = TestBed.inject(AppConfigService);
appConfigService.config = {
dateValues: {
defaultDateFormat: 'mediumDate',
defaultTooltipDateFormat: 'long',
defaultLocale: 'en-US'
}
};
};
describe('DateCellComponent', () => {
beforeEach(() => {
configureTestingModule([]);
});
it('should set default date config', () => {
expect(component.defaultDateConfig.format).toBe('medium');
expect(component.defaultDateConfig.tooltipFormat).toBe('medium');
expect(component.defaultDateConfig.locale).toBeUndefined();
});
it('should display date and tooltip with provided config', () => {
const mockDateConfig: DateConfig = {
format: 'short',
tooltipFormat: 'shortDate'
};
const expectedDate = '10/25/23, 12:00 AM';
const expectedTooltip = '10/25/23';
renderDateCell(mockDateConfig, mockDate, mockTooltip);
checkDisplayedDate(expectedDate);
checkDisplayedTooltip(expectedTooltip);
});
it('should display date and tooltip with based on appConfig values if dateConfig is NOT provided', () => {
const mockDateConfig: DateConfig = {};
const expectedDate = 'Oct 25, 2023';
const expectedTooltip = 'October 25, 2023 at 12:00:00 AM GMT+0';
renderDateCell(mockDateConfig, mockDate, mockTooltip);
checkDisplayedDate(expectedDate);
checkDisplayedTooltip(expectedTooltip);
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', () => {
appConfigService.config = {
dateValues: {}
};
const mockDateConfig: DateConfig = {};
const expectedDate = 'Oct 25, 2023, 12:00:00 AM';
const expectedTooltip = expectedDate;
renderDateCell(mockDateConfig, mockDate, mockTooltip);
checkDisplayedDate(expectedDate);
checkDisplayedTooltip(expectedTooltip);
});
it('should display date with timeAgo format', () => {
const mockDateConfig: DateConfig = {
format: 'timeAgo'
};
const today = new Date();
const yesterday = new Date(today);
yesterday.setDate(today.getDate() - 1);
const expectedDate = '1 day ago';
renderDateCell(mockDateConfig, yesterday, mockTooltip);
checkDisplayedDate(expectedDate);
});
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';
renderDateCell(mockDateConfig, yesterday, mockTooltip);
checkDisplayedDate(expectedDate);
});
it('should display date with column format if dateConfig format is not provided', () => {
component.column = mockColumn;
const mockDateConfig: DateConfig = {
tooltipFormat: 'short'
};
const expectedDate = 'Wednesday, October 25, 2023 at 12:00:00 AM GMT+00:00';
renderDateCell(mockDateConfig, mockDate, mockTooltip);
checkDisplayedDate(expectedDate);
});
it('should display date and override dateConfig by column format if is provided', () => {
component.column = mockColumn;
const mockDateConfig: DateConfig = {
format: 'short'
};
const expectedDate = 'Wednesday, October 25, 2023 at 12:00:00 AM GMT+00:00';
renderDateCell(mockDateConfig, mockDate, mockTooltip);
checkDisplayedDate(expectedDate);
});
it('should display date based on string', () => {
const mockDateConfig: DateConfig = {
format: 'short',
tooltipFormat: 'short'
};
const mockStringDate = 'Oct 25, 2023';
const expectedDate = '10/25/23, 12:00 AM';
renderDateCell(mockDateConfig, mockStringDate, mockTooltip);
checkDisplayedDate(expectedDate);
});
it('should display date based on timestamp', () => {
const mockDateConfig: DateConfig = {
format: 'short',
tooltipFormat: 'short'
};
const mockTimestamp = Date.parse('Oct 25, 2023');
const expectedDate = '10/25/23, 12:00 AM';
renderDateCell(mockDateConfig, mockTimestamp, mockTooltip);
checkDisplayedDate(expectedDate);
});
});
describe('DateCellComponent locale', () => {
it('should display date and tooltip with custom locale', () => {
configureTestingModule([{ provide: LOCALE_ID, useValue: 'pl-PL' }]);
registerLocaleData(localePL);
const mockDateConfig: DateConfig = {
format: 'short',
tooltipFormat: 'medium',
locale: 'pl-PL'
};
const expectedDate = '25.10.2023, 00:00';
const expectedTooltip = '25 paź 2023, 00:00:00';
renderDateCell(mockDateConfig, mockDate, mockTooltip);
checkDisplayedDate(expectedDate);
checkDisplayedTooltip(expectedTooltip);
});
});

View File

@ -15,67 +15,52 @@
* limitations under the License.
*/
import { Component, Optional, ViewEncapsulation } from '@angular/core';
import { Component, Input, OnInit, ViewEncapsulation, inject } from '@angular/core';
import { DataTableCellComponent } from '../datatable-cell/datatable-cell.component';
import {
UserPreferencesService,
UserPreferenceValues
} from '../../../common/services/user-preferences.service';
import { AppConfigService } from '../../../app-config/app-config.service';
import { takeUntil } from 'rxjs/operators';
import { DataTableService } from '../../services/datatable.service';
import { DateConfig } from '../../data/data-column.model';
import { CommonModule } from '@angular/common';
import { LocalizedDatePipe, TimeAgoPipe } from '../../../pipes';
@Component({
standalone: true,
imports: [CommonModule, LocalizedDatePipe, TimeAgoPipe],
selector: 'adf-date-cell',
template: `
<ng-container>
<span
title="{{ tooltip | adfLocalizedDate: 'medium' }}"
class="adf-datatable-cell-value"
*ngIf="format === 'timeAgo'; else standard_date">
{{ value$ | async | adfTimeAgo: currentLocale }}
</span>
</ng-container>
<ng-template #standard_date>
<span
class="adf-datatable-cell-value"
title="{{ tooltip | adfLocalizedDate: tooltipDateFormat }}">
{{ value$ | async | adfLocalizedDate: format }}
</span>
</ng-template>
`,
templateUrl: './date-cell.component.html',
encapsulation: ViewEncapsulation.None,
host: { class: 'adf-date-cell adf-datatable-content-cell' }
host: { class: 'adf-datatable-content-cell' }
})
export class DateCellComponent extends DataTableCellComponent {
export class DateCellComponent extends DataTableCellComponent implements OnInit {
static DATE_FORMAT = 'medium';
@Input()
dateConfig: DateConfig;
currentLocale: string;
dateFormat: string;
tooltipDateFormat: string;
config: DateConfig = {};
private readonly appConfig: AppConfigService = inject(AppConfigService);
readonly defaultDateConfig: DateConfig = {
format: 'medium',
tooltipFormat: 'medium',
locale: undefined
};
ngOnInit(): void {
super.ngOnInit();
this.setConfig();
}
get format(): string {
if (this.column) {
return this.column.format || this.dateFormat;
}
return this.dateFormat;
return this.column?.format ?? this.config.format;
}
constructor(
userPreferenceService: UserPreferencesService,
@Optional() dataTableService: DataTableService,
appConfig: AppConfigService
) {
super(dataTableService);
private setConfig(): void {
this.config.format = this.dateConfig?.format || this.getAppConfigPropertyValue('dateValues.defaultDateFormat', this.defaultDateConfig.format);
this.config.tooltipFormat = this.dateConfig?.tooltipFormat || this.getAppConfigPropertyValue('dateValues.defaultTooltipDateFormat', this.defaultDateConfig.tooltipFormat);
this.config.locale = this.dateConfig?.locale || this.getAppConfigPropertyValue('dateValues.defaultLocale', this.defaultDateConfig.locale);
}
this.dateFormat = appConfig.get('dateValues.defaultDateFormat', DateCellComponent.DATE_FORMAT);
this.tooltipDateFormat = appConfig.get('dateValues.defaultTooltipDateFormat', DateCellComponent.DATE_FORMAT);
if (userPreferenceService) {
userPreferenceService
.select(UserPreferenceValues.Locale)
.pipe(takeUntil(this.onDestroy$))
.subscribe(locale => this.currentLocale = locale);
}
private getAppConfigPropertyValue(key: string, defaultValue: string): string {
return this.appConfig.get(key, defaultValue);
}
}

View File

@ -15,25 +15,22 @@
* limitations under the License.
*/
import { Component, Optional, ViewEncapsulation } from '@angular/core';
import { Component, OnInit, ViewEncapsulation } from '@angular/core';
import { DataTableCellComponent } from '../datatable-cell/datatable-cell.component';
import { DataTableService } from '../../services/datatable.service';
@Component({
selector: 'adf-filesize-cell',
template: `
<ng-container *ngIf="(value$ | async | adfFileSize) as fileSize">
<span
[title]="tooltip"
>{{ fileSize }}</span
>
<span [title]="tooltip">{{ fileSize }}</span>
</ng-container>
`,
encapsulation: ViewEncapsulation.None,
host: { class: 'adf-filesize-cell' }
})
export class FileSizeCellComponent extends DataTableCellComponent {
constructor(@Optional() dataTableService: DataTableService) {
super(dataTableService);
export class FileSizeCellComponent extends DataTableCellComponent implements OnInit {
ngOnInit(): void {
super.ngOnInit();
}
}

View File

@ -15,11 +15,10 @@
* limitations under the License.
*/
import { ChangeDetectionStrategy, Component, OnInit, ViewEncapsulation, Input, Optional } from '@angular/core';
import { ChangeDetectionStrategy, Component, OnInit, ViewEncapsulation, Input } from '@angular/core';
import { DataTableCellComponent } from '../datatable-cell/datatable-cell.component';
import { MatDialog } from '@angular/material/dialog';
import { EditJsonDialogComponent, EditJsonDialogSettings } from '../../../dialogs/edit-json/edit-json.dialog';
import { DataTableService } from '../../services/datatable.service';
@Component({
selector: 'adf-json-cell',
@ -42,14 +41,12 @@ export class JsonCellComponent extends DataTableCellComponent implements OnInit
@Input()
editable: boolean = false;
constructor(private dialog: MatDialog, @Optional() dataTableService: DataTableService) {
super(dataTableService);
constructor(private dialog: MatDialog) {
super();
}
ngOnInit() {
if (this.column?.key && this.row && this.data) {
this.value$.next(this.data.getValue(this.row, this.column, this.resolverFn));
}
super.ngOnInit();
}
view() {

View File

@ -15,9 +15,8 @@
* limitations under the License.
*/
import { ChangeDetectionStrategy, Component, Input, OnInit, Optional, ViewEncapsulation } from '@angular/core';
import { ChangeDetectionStrategy, Component, Input, OnInit, ViewEncapsulation } from '@angular/core';
import { DataTableCellComponent } from '../datatable-cell/datatable-cell.component';
import { DataTableService } from '../../services/datatable.service';
import { AsyncPipe } from '@angular/common';
import { RouterModule } from '@angular/router';
import { PathInfo } from '@alfresco/js-api';
@ -41,10 +40,6 @@ export class LocationCellComponent extends DataTableCellComponent implements OnI
@Input()
link: any[];
constructor(@Optional() dataTableService: DataTableService) {
super(dataTableService);
}
ngOnInit() {
super.ngOnInit();
}

View File

@ -20,11 +20,9 @@ import {
Component,
ViewEncapsulation,
Input,
Optional,
OnInit
} from '@angular/core';
import { DataTableCellComponent } from '../datatable-cell/datatable-cell.component';
import { DataTableService } from '../../services/datatable.service';
import { DecimalConfig } from '../../data/data-column.model';
import { CommonModule } from '@angular/common';
@ -47,13 +45,7 @@ export class NumberCellComponent extends DataTableCellComponent implements OnIni
locale: undefined
};
constructor(@Optional() dataTableService: DataTableService) {
super(dataTableService);
}
ngOnInit() {
if (this.column?.key && this.row && this.data) {
this.value$.next(this.data.getValue(this.row, this.column, this.resolverFn));
}
super.ngOnInit();
}
}

View File

@ -43,12 +43,23 @@ export interface DataColumn<T = unknown> {
order?: number;
currencyConfig?: CurrencyConfig;
decimalConfig?: DecimalConfig;
dateConfig?: DateConfig;
}
export interface DecimalConfig {
digitsInfo?: string;
export interface LocaleConfig {
locale?: string;
}
export interface DecimalConfig extends LocaleConfig {
digitsInfo?: string;
}
export interface CurrencyConfig extends DecimalConfig {
code?: string;
display?: string;
}
export interface DateConfig extends LocaleConfig {
format?: string;
tooltipFormat?: string;
}

View File

@ -17,7 +17,7 @@
import { TemplateRef } from '@angular/core';
import { DataColumnType } from '@alfresco/adf-extensions';
import { CurrencyConfig, DataColumn, DecimalConfig } from './data-column.model';
import { CurrencyConfig, DataColumn, DecimalConfig, DateConfig } from './data-column.model';
// Simple implementation of the DataColumn interface.
export class ObjectDataColumn<T = unknown> implements DataColumn<T> {
@ -41,6 +41,7 @@ export class ObjectDataColumn<T = unknown> implements DataColumn<T> {
order?: number;
currencyConfig?: CurrencyConfig;
decimalConfig?: DecimalConfig;
dateConfig?: DateConfig;
constructor(input: any) {
this.id = input.id ?? '';
@ -63,5 +64,6 @@ export class ObjectDataColumn<T = unknown> implements DataColumn<T> {
this.order = input.order;
this.currencyConfig = input.currencyConfig;
this.decimalConfig = input.decimalConfig;
this.dateConfig = input.dateConfig;
}
}

View File

@ -56,6 +56,7 @@ import { DataColumnModule } from './data-column/data-column.module';
import { BooleanCellComponent } from './components/boolean-cell/boolean-cell.component';
import { AmountCellComponent } from './components/amount-cell/amount-cell.component';
import { NumberCellComponent } from './components/number-cell/number-cell.component';
import { LocalizedDatePipe } from '../pipes';
@NgModule({
imports: [
@ -76,7 +77,9 @@ import { NumberCellComponent } from './components/number-cell/number-cell.compon
BooleanCellComponent,
AmountCellComponent,
NumberCellComponent,
LocationCellComponent
LocationCellComponent,
DateCellComponent,
LocalizedDatePipe
],
declarations: [
DataTableComponent,
@ -86,7 +89,6 @@ import { NumberCellComponent } from './components/number-cell/number-cell.compon
EmptyListFooterDirective,
DataTableCellComponent,
DataTableRowComponent,
DateCellComponent,
FileSizeCellComponent,
JsonCellComponent,
ColumnsSelectorComponent,
@ -108,7 +110,6 @@ import { NumberCellComponent } from './components/number-cell/number-cell.compon
EmptyListFooterDirective,
DataTableCellComponent,
DataTableRowComponent,
DateCellComponent,
ColumnsSelectorComponent,
FileSizeCellComponent,
JsonCellComponent,

View File

@ -23,6 +23,7 @@ import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
@Pipe({
standalone: true,
name: 'adfLocalizedDate',
pure: false
})

View File

@ -40,19 +40,19 @@ import { DateTimePipe } from './date-time.pipe';
@NgModule({
imports: [
CommonModule,
TranslateModule
TranslateModule,
LocalizedDatePipe,
TimeAgoPipe
],
declarations: [
FileSizePipe,
HighlightPipe,
TimeAgoPipe,
MimeTypeIconPipe,
InitialUsernamePipe,
FullNamePipe,
FormatSpacePipe,
FileTypePipe,
MultiValuePipe,
LocalizedDatePipe,
DecimalNumberPipe,
LocalizedRolePipe,
MomentDatePipe,
@ -70,14 +70,14 @@ import { DateTimePipe } from './date-time.pipe';
FormatSpacePipe,
FileTypePipe,
MultiValuePipe,
LocalizedDatePipe,
DecimalNumberPipe,
LocalizedRolePipe,
MomentDatePipe,
MomentDateTimePipe,
DateTimePipe,
FilterStringPipe,
FilterOutArrayObjectsByPropPipe
FilterOutArrayObjectsByPropPipe,
LocalizedDatePipe
],
exports: [
FileSizePipe,
@ -89,7 +89,6 @@ import { DateTimePipe } from './date-time.pipe';
FormatSpacePipe,
FileTypePipe,
MultiValuePipe,
LocalizedDatePipe,
DecimalNumberPipe,
LocalizedRolePipe,
MomentDatePipe,

View File

@ -25,6 +25,7 @@ import { differenceInDays, formatDistance } from 'date-fns';
import * as Locales from 'date-fns/locale';
@Pipe({
standalone: true,
name: 'adfTimeAgo'
})
export class TimeAgoPipe implements PipeTransform, OnDestroy {

View File

@ -35,18 +35,18 @@ export interface DataColumnTypes {
export type DataColumnType = keyof DataColumnTypes;
export interface DocumentListPresetRef extends ExtensionElement {
key: string;
type: DataColumnType;
title?: string;
format?: string;
class?: string;
sortable: boolean;
template: string;
desktopOnly: boolean;
sortingKey: string;
isHidden?: boolean;
rules?: {
[key: string]: string;
visible?: string;
};
key: string;
type: DataColumnType;
title?: string;
format?: string;
class?: string;
sortable: boolean;
template: string;
desktopOnly: boolean;
sortingKey: string;
isHidden?: boolean;
rules?: {
[key: string]: string;
visible?: string;
};
}