mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2026-09-09 18:03:21 +00:00
AAE-40136 Migrate locale settings to signals (#11361)
This commit is contained in:
+9
-7
@@ -15,7 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Component, DestroyRef, EventEmitter, inject, Inject, Input, OnInit, Output, ViewEncapsulation } from '@angular/core';
|
||||
import { Component, DestroyRef, effect, EventEmitter, inject, Inject, Input, OnInit, Output, ViewEncapsulation } from '@angular/core';
|
||||
import { endOfDay, isAfter, isBefore, isValid, parse } from 'date-fns';
|
||||
import { DateAdapter, MAT_DATE_FORMATS, MAT_DATE_LOCALE, MatDateFormats } from '@angular/material/core';
|
||||
import { DateFnsAdapter, MAT_DATE_FNS_FORMATS } from '@angular/material-date-fns-adapter';
|
||||
@@ -23,7 +23,7 @@ import { InLastDateType } from './in-last-date-type';
|
||||
import { DateRangeType } from './date-range-type';
|
||||
import { SearchDateRange } from './search-date-range';
|
||||
import { FormBuilder, ReactiveFormsModule, UntypedFormControl, Validators } from '@angular/forms';
|
||||
import { DateFnsUtils, UserPreferencesService, UserPreferenceValues } from '@alfresco/adf-core';
|
||||
import { DateFnsUtils, UserPreferencesService } from '@alfresco/adf-core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { MatRadioModule } from '@angular/material/radio';
|
||||
import { TranslatePipe } from '@ngx-translate/core';
|
||||
@@ -100,7 +100,13 @@ export class SearchDateRangeComponent implements OnInit {
|
||||
private userPreferencesService: UserPreferencesService,
|
||||
private dateAdapter: DateAdapter<DateFnsAdapter>,
|
||||
@Inject(MAT_DATE_FORMATS) private dateFormatConfig: MatDateFormats
|
||||
) {}
|
||||
) {
|
||||
// Use effect to react to locale signal changes (must be in injection context)
|
||||
effect(() => {
|
||||
const locale = this.userPreferencesService.localeSignal();
|
||||
this.dateAdapter.setLocale(DateFnsUtils.getLocaleFromString(locale));
|
||||
});
|
||||
}
|
||||
|
||||
readonly endDateValidator = (formControl: UntypedFormControl): { [key: string]: boolean } | null => {
|
||||
if (isBefore(formControl.value, this.betweenStartDateFormControl.value) || isAfter(formControl.value, this.convertedMaxDate)) {
|
||||
@@ -114,10 +120,6 @@ export class SearchDateRangeComponent implements OnInit {
|
||||
ngOnInit(): void {
|
||||
this.dateFormatConfig.display.dateInput = this.dateFormat;
|
||||
this.convertedMaxDate = endOfDay(this.maxDate && this.maxDate !== 'today' ? parse(this.maxDate, this.dateFormat, new Date()) : new Date());
|
||||
this.userPreferencesService
|
||||
.select(UserPreferenceValues.Locale)
|
||||
.pipe(takeUntilDestroyed(this.destroyRef))
|
||||
.subscribe((locale) => this.dateAdapter.setLocale(DateFnsUtils.getLocaleFromString(locale)));
|
||||
this.form.controls.dateRangeType.valueChanges
|
||||
.pipe(takeUntilDestroyed(this.destroyRef))
|
||||
.subscribe((dateRangeType) => this.updateValidators(dateRangeType));
|
||||
|
||||
+6
-12
@@ -15,7 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Component, DestroyRef, inject, Input, OnInit, ViewChild, ViewEncapsulation } from '@angular/core';
|
||||
import { Component, effect, Input, OnInit, ViewChild, ViewEncapsulation } from '@angular/core';
|
||||
import { DateAdapter, MAT_DATE_FORMATS } from '@angular/material/core';
|
||||
import {
|
||||
DatetimeAdapter,
|
||||
@@ -25,7 +25,7 @@ import {
|
||||
MatDatetimepickerModule
|
||||
} from '@mat-datetimepicker/core';
|
||||
import { CardViewDateItemModel } from '../../models/card-view-dateitem.model';
|
||||
import { UserPreferencesService, UserPreferenceValues } from '../../../common/services/user-preferences.service';
|
||||
import { UserPreferencesService } from '../../../common/services/user-preferences.service';
|
||||
import { BaseCardView } from '../base-card-view';
|
||||
import { ClipboardService } from '../../../clipboard/clipboard.service';
|
||||
import { TranslationService } from '../../../translation/translation.service';
|
||||
@@ -40,7 +40,6 @@ import { MatChipsModule } from '@angular/material/chips';
|
||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
||||
import { MatDatepickerModule } from '@angular/material/datepicker';
|
||||
import { MatSnackBarModule } from '@angular/material/snack-bar';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
import { FormControl, ReactiveFormsModule } from '@angular/forms';
|
||||
import { MatInputModule } from '@angular/material/input';
|
||||
|
||||
@@ -83,8 +82,6 @@ export class CardViewDateItemComponent extends BaseCardView<CardViewDateItemMode
|
||||
|
||||
cardViewDateTimeControl: FormControl<Date> = new FormControl<Date>(null);
|
||||
|
||||
private readonly destroyRef = inject(DestroyRef);
|
||||
|
||||
constructor(
|
||||
private dateAdapter: DateAdapter<Date>,
|
||||
private userPreferencesService: UserPreferencesService,
|
||||
@@ -92,16 +89,13 @@ export class CardViewDateItemComponent extends BaseCardView<CardViewDateItemMode
|
||||
private translateService: TranslationService
|
||||
) {
|
||||
super();
|
||||
// Use effect to react to locale signal changes (must be in injection context)
|
||||
effect(() => {
|
||||
this.property.locale = this.userPreferencesService.localeSignal();
|
||||
});
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.userPreferencesService
|
||||
.select(UserPreferenceValues.Locale)
|
||||
.pipe(takeUntilDestroyed(this.destroyRef))
|
||||
.subscribe((locale) => {
|
||||
this.property.locale = locale;
|
||||
});
|
||||
|
||||
(this.dateAdapter as AdfDateFnsAdapter).displayFormat = 'MMM DD';
|
||||
|
||||
if (this.property.multivalued) {
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { inject, Injectable, RendererFactory2 } from '@angular/core';
|
||||
import { inject, Injectable, RendererFactory2, Signal } from '@angular/core';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { Observable, BehaviorSubject } from 'rxjs';
|
||||
import { AppConfigService, AppConfigValues } from '../../app-config/app-config.service';
|
||||
@@ -25,6 +25,7 @@ import { LanguageItem } from './language-item.interface';
|
||||
import { DOCUMENT } from '@angular/common';
|
||||
import { Directionality, Direction } from '@angular/cdk/bidi';
|
||||
import { DEFAULT_LANGUAGE_LIST } from '../models/default-languages.model';
|
||||
import { toSignal } from '@angular/core/rxjs-interop';
|
||||
|
||||
// eslint-disable-next-line no-shadow
|
||||
export enum UserPreferenceValues {
|
||||
@@ -53,10 +54,78 @@ export class UserPreferencesService {
|
||||
private onChangeSubject: BehaviorSubject<any>;
|
||||
onChange: Observable<any>;
|
||||
|
||||
constructor(public translate: TranslateService, private appConfig: AppConfigService, private storage: StorageService) {
|
||||
/**
|
||||
* Observable that emits the current locale whenever it changes.
|
||||
* This is a convenience property that simplifies subscribing to locale changes.
|
||||
*
|
||||
* @example Observable usage (requires manual unsubscription):
|
||||
* ```typescript
|
||||
* constructor(private userPreferencesService: UserPreferencesService) {
|
||||
* this.userPreferencesService.locale$
|
||||
* .pipe(takeUntilDestroyed())
|
||||
* .subscribe(locale => {
|
||||
* this.currentLocale = locale;
|
||||
* });
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* @example Signal usage (automatic cleanup, recommended):
|
||||
* ```typescript
|
||||
* export class MyComponent {
|
||||
* private userPreferencesService = inject(UserPreferencesService);
|
||||
* currentLocale = this.userPreferencesService.localeSignal; // Signal - no subscription needed!
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
readonly locale$: Observable<string>;
|
||||
|
||||
/**
|
||||
* Signal that provides the current locale value.
|
||||
* Automatically handles cleanup - no need for takeUntilDestroyed or manual unsubscription.
|
||||
* This is the recommended way to access locale in components.
|
||||
*/
|
||||
readonly localeSignal: Signal<string>;
|
||||
|
||||
/**
|
||||
* Observable that emits the current pagination size whenever it changes.
|
||||
*/
|
||||
readonly paginationSize$: Observable<number>;
|
||||
|
||||
/**
|
||||
* Signal that provides the current pagination size value.
|
||||
*/
|
||||
readonly paginationSizeSignal: Signal<number>;
|
||||
|
||||
/**
|
||||
* Observable that emits the supported page sizes whenever they change.
|
||||
*/
|
||||
readonly supportedPageSizes$: Observable<number[]>;
|
||||
|
||||
/**
|
||||
* Signal that provides the supported page sizes array.
|
||||
*/
|
||||
readonly supportedPageSizesSignal: Signal<number[]>;
|
||||
|
||||
constructor(
|
||||
public translate: TranslateService,
|
||||
private appConfig: AppConfigService,
|
||||
private storage: StorageService
|
||||
) {
|
||||
this.onChangeSubject = new BehaviorSubject(this.userPreferenceStatus);
|
||||
this.onChange = this.onChangeSubject.asObservable();
|
||||
|
||||
// Initialize convenience observables
|
||||
this.locale$ = this.select<string>(UserPreferenceValues.Locale);
|
||||
this.paginationSize$ = this.select<number>(UserPreferenceValues.PaginationSize);
|
||||
this.supportedPageSizes$ = this.select<string>(UserPreferenceValues.SupportedPageSizes).pipe(
|
||||
map((value) => (value ? JSON.parse(value) : this.defaults.supportedPageSizes))
|
||||
);
|
||||
|
||||
// Initialize convenience signals (automatically handle cleanup)
|
||||
this.localeSignal = toSignal(this.locale$, { initialValue: this.defaults.locale });
|
||||
this.paginationSizeSignal = toSignal(this.paginationSize$, { initialValue: this.defaults.paginationSize });
|
||||
this.supportedPageSizesSignal = toSignal(this.supportedPageSizes$, { initialValue: this.defaults.supportedPageSizes });
|
||||
|
||||
this.appConfig.onLoad.subscribe(() => {
|
||||
this.initUserPreferenceStatus();
|
||||
});
|
||||
|
||||
@@ -17,10 +17,11 @@
|
||||
|
||||
import { DateFnsAdapter } from '@angular/material-date-fns-adapter';
|
||||
import { DateFnsUtils } from './date-fns-utils';
|
||||
import { Inject, Injectable, Optional } from '@angular/core';
|
||||
import { effect, Inject, Injectable, Optional } from '@angular/core';
|
||||
import { MAT_DATE_FORMATS, MAT_DATE_LOCALE, MatDateFormats } from '@angular/material/core';
|
||||
import { UserPreferenceValues, UserPreferencesService } from '../services/user-preferences.service';
|
||||
import { UserPreferencesService } from '../services/user-preferences.service';
|
||||
import { isValid, Locale, parse } from 'date-fns';
|
||||
import { enUS } from 'date-fns/locale';
|
||||
|
||||
/**
|
||||
* Date-fns adapter with moment-to-date-fns conversion.
|
||||
@@ -82,10 +83,24 @@ export class AdfDateFnsAdapter extends DateFnsAdapter {
|
||||
@Optional() @Inject(MAT_DATE_FORMATS) private formats: MatDateFormats,
|
||||
preferences: UserPreferencesService
|
||||
) {
|
||||
super(matDateLocale);
|
||||
// Ensure we have a valid locale for the base class
|
||||
// If matDateLocale is not provided, use enUS as default
|
||||
super(matDateLocale || enUS);
|
||||
|
||||
preferences.select(UserPreferenceValues.Locale).subscribe((locale: string) => {
|
||||
this.setLocale(DateFnsUtils.getLocaleFromString(locale));
|
||||
// Initialize locale synchronously from signal's initial value
|
||||
// This ensures locale is set before any format() calls
|
||||
const initialLocale = preferences.localeSignal();
|
||||
if (initialLocale) {
|
||||
this.setLocale(DateFnsUtils.getLocaleFromString(initialLocale));
|
||||
}
|
||||
|
||||
// Use effect to reactively update locale when signal changes
|
||||
// Note: This adapter is a singleton service, so no cleanup needed
|
||||
effect(() => {
|
||||
const locale = preferences.localeSignal();
|
||||
if (locale) {
|
||||
this.setLocale(DateFnsUtils.getLocaleFromString(locale));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -15,9 +15,9 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Injectable } from '@angular/core';
|
||||
import { effect, Injectable } from '@angular/core';
|
||||
import { DateAdapter } from '@angular/material/core';
|
||||
import { UserPreferencesService, UserPreferenceValues } from '../services/user-preferences.service';
|
||||
import { UserPreferencesService } from '../services/user-preferences.service';
|
||||
|
||||
// Stub for the moment.js integration.
|
||||
// While this dependency is no longer used by the libraries, the moment adapter can still discover the moment.js linked to the application
|
||||
@@ -37,7 +37,10 @@ export class MomentDateAdapter extends DateAdapter<Moment> {
|
||||
constructor(preferences: UserPreferencesService) {
|
||||
super();
|
||||
|
||||
preferences.select(UserPreferenceValues.Locale).subscribe((locale: string) => {
|
||||
// Use effect to reactively update locale when signal changes
|
||||
// Note: This adapter is a singleton service, so no cleanup needed
|
||||
effect(() => {
|
||||
const locale = preferences.localeSignal();
|
||||
this.setLocale(locale);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -15,14 +15,13 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { ChangeDetectionStrategy, Component, Input, OnInit, ViewEncapsulation, inject, ChangeDetectorRef } from '@angular/core';
|
||||
import { ChangeDetectionStrategy, Component, Input, OnInit, ViewEncapsulation, inject, ChangeDetectorRef, effect } 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, UserPreferenceValues } from '../../../common/services/user-preferences.service';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
import { UserPreferencesService } from '../../../common/services/user-preferences.service';
|
||||
|
||||
@Component({
|
||||
imports: [LocalizedDatePipe, TimeAgoPipe, AsyncPipe],
|
||||
@@ -52,19 +51,18 @@ export class DateCellComponent extends DataTableCellComponent implements OnInit
|
||||
locale: undefined
|
||||
};
|
||||
|
||||
ngOnInit(): void {
|
||||
// Subscribe to locale changes
|
||||
this.userPreferencesService
|
||||
.select(UserPreferenceValues.Locale)
|
||||
.pipe(takeUntilDestroyed(this.destroyRef))
|
||||
.subscribe((locale) => {
|
||||
this.userLocale = locale || 'en';
|
||||
this.setConfig();
|
||||
this.updateValue(); // Recalculate computedTitle with new locale
|
||||
this.cdr.markForCheck();
|
||||
});
|
||||
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();
|
||||
});
|
||||
}
|
||||
|
||||
this.setConfig();
|
||||
ngOnInit(): void {
|
||||
super.ngOnInit();
|
||||
}
|
||||
|
||||
|
||||
@@ -18,9 +18,8 @@
|
||||
import { DecimalPipe } from '@angular/common';
|
||||
import { Pipe, PipeTransform } from '@angular/core';
|
||||
import { AppConfigService } from '../app-config/app-config.service';
|
||||
import { UserPreferencesService, UserPreferenceValues } from '../common/services/user-preferences.service';
|
||||
import { UserPreferencesService } from '../common/services/user-preferences.service';
|
||||
import { DecimalNumberModel } from '../models/decimal-number.model';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
|
||||
@Pipe({
|
||||
name: 'adfDecimalNumber',
|
||||
@@ -32,22 +31,14 @@ export class DecimalNumberPipe implements PipeTransform {
|
||||
static DEFAULT_MIN_FRACTION_DIGITS = 0;
|
||||
static DEFAULT_MAX_FRACTION_DIGITS = 2;
|
||||
|
||||
defaultLocale: string = DecimalNumberPipe.DEFAULT_LOCALE;
|
||||
defaultMinIntegerDigits: number = DecimalNumberPipe.DEFAULT_MIN_INTEGER_DIGITS;
|
||||
defaultMinFractionDigits: number = DecimalNumberPipe.DEFAULT_MIN_FRACTION_DIGITS;
|
||||
defaultMaxFractionDigits: number = DecimalNumberPipe.DEFAULT_MAX_FRACTION_DIGITS;
|
||||
constructor(public userPreferenceService?: UserPreferencesService, public appConfig?: AppConfigService) {
|
||||
if (this.userPreferenceService) {
|
||||
this.userPreferenceService
|
||||
.select(UserPreferenceValues.Locale)
|
||||
.pipe(takeUntilDestroyed())
|
||||
.subscribe((locale) => {
|
||||
if (locale) {
|
||||
this.defaultLocale = locale;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
constructor(
|
||||
public userPreferenceService?: UserPreferencesService,
|
||||
public appConfig?: AppConfigService
|
||||
) {
|
||||
if (this.appConfig) {
|
||||
this.defaultMinIntegerDigits = this.appConfig.get<number>('decimalValues.minIntegerDigits', DecimalNumberPipe.DEFAULT_MIN_INTEGER_DIGITS);
|
||||
this.defaultMinFractionDigits = this.appConfig.get<number>(
|
||||
@@ -67,7 +58,9 @@ export class DecimalNumberPipe implements PipeTransform {
|
||||
const actualMaxFractionDigits: number = digitsInfo?.maxFractionDigits ? digitsInfo.maxFractionDigits : this.defaultMaxFractionDigits;
|
||||
|
||||
const actualDigitsInfo = `${actualMinIntegerDigits}.${actualMinFractionDigits}-${actualMaxFractionDigits}`;
|
||||
const actualLocale = locale || this.defaultLocale;
|
||||
// Use signal directly - no subscription needed!
|
||||
const defaultLocale = this.userPreferenceService?.localeSignal() || DecimalNumberPipe.DEFAULT_LOCALE;
|
||||
const actualLocale = locale || defaultLocale;
|
||||
|
||||
const decimalPipe: DecimalPipe = new DecimalPipe(actualLocale);
|
||||
|
||||
|
||||
@@ -16,38 +16,25 @@
|
||||
*/
|
||||
|
||||
import { DatePipe } from '@angular/common';
|
||||
import { Pipe, PipeTransform, OnDestroy } from '@angular/core';
|
||||
import { Pipe, PipeTransform } from '@angular/core';
|
||||
import { AppConfigService } from '../app-config/app-config.service';
|
||||
import { UserPreferencesService, UserPreferenceValues } from '../common/services/user-preferences.service';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { UserPreferencesService } from '../common/services/user-preferences.service';
|
||||
|
||||
@Pipe({
|
||||
standalone: true,
|
||||
name: 'adfLocalizedDate',
|
||||
pure: false
|
||||
})
|
||||
export class LocalizedDatePipe implements PipeTransform, OnDestroy {
|
||||
export class LocalizedDatePipe implements PipeTransform {
|
||||
static DEFAULT_LOCALE = 'en-US';
|
||||
static DEFAULT_DATE_FORMAT = 'mediumDate';
|
||||
|
||||
defaultLocale: string = LocalizedDatePipe.DEFAULT_LOCALE;
|
||||
defaultFormat: string = LocalizedDatePipe.DEFAULT_DATE_FORMAT;
|
||||
|
||||
private onDestroy$ = new Subject<boolean>();
|
||||
|
||||
constructor(public userPreferenceService?: UserPreferencesService, public appConfig?: AppConfigService) {
|
||||
if (this.userPreferenceService) {
|
||||
this.userPreferenceService
|
||||
.select(UserPreferenceValues.Locale)
|
||||
.pipe(takeUntil(this.onDestroy$))
|
||||
.subscribe((locale) => {
|
||||
if (locale) {
|
||||
this.defaultLocale = locale;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
constructor(
|
||||
public userPreferenceService?: UserPreferencesService,
|
||||
public appConfig?: AppConfigService
|
||||
) {
|
||||
if (this.appConfig) {
|
||||
this.defaultFormat = this.appConfig.get<string>('dateValues.defaultDateFormat', LocalizedDatePipe.DEFAULT_DATE_FORMAT);
|
||||
}
|
||||
@@ -55,13 +42,10 @@ export class LocalizedDatePipe implements PipeTransform, OnDestroy {
|
||||
|
||||
transform(value: Date | string | number, format?: string, locale?: string, timezone?: string): string {
|
||||
const actualFormat = format || this.defaultFormat;
|
||||
const actualLocale = locale || this.defaultLocale;
|
||||
// Use signal directly - no subscription needed!
|
||||
const defaultLocale = this.userPreferenceService?.localeSignal() || LocalizedDatePipe.DEFAULT_LOCALE;
|
||||
const actualLocale = locale || defaultLocale;
|
||||
const datePipe = timezone ? new DatePipe(actualLocale, timezone) : new DatePipe(actualLocale);
|
||||
return datePipe.transform(value, actualFormat);
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.onDestroy$.next(true);
|
||||
this.onDestroy$.complete();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,10 +17,9 @@
|
||||
|
||||
import { Pipe, PipeTransform } from '@angular/core';
|
||||
import { AppConfigService } from '../app-config/app-config.service';
|
||||
import { UserPreferencesService, UserPreferenceValues } from '../common/services/user-preferences.service';
|
||||
import { UserPreferencesService } from '../common/services/user-preferences.service';
|
||||
import { DatePipe } from '@angular/common';
|
||||
import { differenceInDays, formatDistance } from 'date-fns';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
import { DateFnsUtils } from '../common/utils/date-fns-utils';
|
||||
|
||||
@Pipe({
|
||||
@@ -32,25 +31,20 @@ export class TimeAgoPipe implements PipeTransform {
|
||||
static DEFAULT_LOCALE = 'en-US';
|
||||
static DEFAULT_DATE_TIME_FORMAT = 'dd/MM/yyyy HH:mm';
|
||||
|
||||
defaultLocale: string;
|
||||
defaultDateTimeFormat: string;
|
||||
|
||||
constructor(
|
||||
public userPreferenceService: UserPreferencesService,
|
||||
public appConfig: AppConfigService
|
||||
) {
|
||||
this.userPreferenceService
|
||||
.select(UserPreferenceValues.Locale)
|
||||
.pipe(takeUntilDestroyed())
|
||||
.subscribe((locale) => {
|
||||
this.defaultLocale = locale || TimeAgoPipe.DEFAULT_LOCALE;
|
||||
});
|
||||
this.defaultDateTimeFormat = this.appConfig.get<string>('dateValues.defaultDateTimeFormat', TimeAgoPipe.DEFAULT_DATE_TIME_FORMAT);
|
||||
}
|
||||
|
||||
transform(value: Date, locale?: string) {
|
||||
if (value !== null && value !== undefined) {
|
||||
const actualLocale = locale || this.defaultLocale;
|
||||
// Use signal directly - no subscription needed!
|
||||
const defaultLocale = this.userPreferenceService.localeSignal() || TimeAgoPipe.DEFAULT_LOCALE;
|
||||
const actualLocale = locale || defaultLocale;
|
||||
const diff = differenceInDays(new Date(), new Date(value));
|
||||
if (diff > 7) {
|
||||
const datePipe: DatePipe = new DatePipe(actualLocale);
|
||||
|
||||
@@ -15,11 +15,11 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Inject, Injectable, InjectionToken, Optional } from '@angular/core';
|
||||
import { effect, Inject, Injectable, InjectionToken, Optional } from '@angular/core';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { Observable } from 'rxjs';
|
||||
import { TranslateLoaderService } from './translate-loader.service';
|
||||
import { UserPreferencesService, UserPreferenceValues } from '../common/services/user-preferences.service';
|
||||
import { UserPreferencesService } from '../common/services/user-preferences.service';
|
||||
|
||||
export const TRANSLATION_PROVIDER = new InjectionToken('Injection token for translation providers.');
|
||||
|
||||
@@ -71,7 +71,10 @@ export class TranslationService {
|
||||
}
|
||||
}
|
||||
|
||||
userPreferencesService.select(UserPreferenceValues.Locale).subscribe((locale) => {
|
||||
// Use effect to reactively update translations when locale signal changes
|
||||
// Note: This is a singleton service, so no cleanup needed
|
||||
effect(() => {
|
||||
const locale = userPreferencesService.localeSignal();
|
||||
if (locale) {
|
||||
this.userLang = locale;
|
||||
this.use(this.userLang);
|
||||
|
||||
+4
-1
@@ -22,12 +22,14 @@ import { DateCloudFilterType } from '../../models/date-cloud-filter.model';
|
||||
import { DateRangeFilterService } from './date-range-filter.service';
|
||||
import { mockFilterProperty } from '../mock/date-range-filter.mock';
|
||||
import { add, endOfDay } from 'date-fns';
|
||||
import { enUS } from 'date-fns/locale';
|
||||
import { HarnessLoader } from '@angular/cdk/testing';
|
||||
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
|
||||
import { MatSelectHarness } from '@angular/material/select/testing';
|
||||
import { MatFormFieldHarness } from '@angular/material/form-field/testing';
|
||||
import { MatDateRangeInputHarness } from '@angular/material/datepicker/testing';
|
||||
import { NoopTranslateModule } from '@alfresco/adf-core';
|
||||
import { MAT_DATE_LOCALE } from '@angular/material/core';
|
||||
|
||||
describe('DateRangeFilterComponent', () => {
|
||||
let component: DateRangeFilterComponent;
|
||||
@@ -37,7 +39,8 @@ describe('DateRangeFilterComponent', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [NoopTranslateModule, DateRangeFilterComponent]
|
||||
imports: [NoopTranslateModule, DateRangeFilterComponent],
|
||||
providers: [{ provide: MAT_DATE_LOCALE, useValue: enUS }]
|
||||
});
|
||||
fixture = TestBed.createComponent(DateRangeFilterComponent);
|
||||
component = fixture.componentInstance;
|
||||
|
||||
+11
-10
@@ -15,7 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Component, DestroyRef, EventEmitter, inject, Input, OnChanges, OnInit, Output, SimpleChanges, ViewEncapsulation } from '@angular/core';
|
||||
import { Component, DestroyRef, effect, EventEmitter, inject, Input, OnChanges, Output, SimpleChanges, ViewEncapsulation } from '@angular/core';
|
||||
import { AbstractControl, FormBuilder, FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms';
|
||||
import { DateAdapter } from '@angular/material/core';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
@@ -29,7 +29,7 @@ import {
|
||||
ProcessFilterProperties,
|
||||
ProcessSortFilterProperty
|
||||
} from '../../models/process-filter-cloud.model';
|
||||
import { DateFnsUtils, IconComponent, TranslationService, UserPreferencesService, UserPreferenceValues } from '@alfresco/adf-core';
|
||||
import { DateFnsUtils, IconComponent, TranslationService, UserPreferencesService } from '@alfresco/adf-core';
|
||||
import { ProcessFilterCloudService } from '../../services/process-filter-cloud.service';
|
||||
import { ProcessFilterDialogCloudComponent } from '../process-filter-dialog/process-filter-dialog-cloud.component';
|
||||
import { ProcessCloudService } from '../../../services/process-cloud.service';
|
||||
@@ -101,7 +101,7 @@ interface ProcessFilterFormProps {
|
||||
styleUrls: ['./edit-process-filter-cloud.component.scss'],
|
||||
encapsulation: ViewEncapsulation.None
|
||||
})
|
||||
export class EditProcessFilterCloudComponent implements OnInit, OnChanges {
|
||||
export class EditProcessFilterCloudComponent implements OnChanges {
|
||||
/** The name of the application. */
|
||||
@Input()
|
||||
appName: string = '';
|
||||
@@ -228,13 +228,14 @@ export class EditProcessFilterCloudComponent implements OnInit, OnChanges {
|
||||
private processFilterCloudService: ProcessFilterCloudService,
|
||||
private appsProcessCloudService: AppsProcessCloudService,
|
||||
private processCloudService: ProcessCloudService
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.userPreferencesService
|
||||
.select(UserPreferenceValues.Locale)
|
||||
.pipe(takeUntilDestroyed(this.destroyRef))
|
||||
.subscribe((locale) => this.dateAdapter.setLocale(locale));
|
||||
) {
|
||||
// Use effect to react to locale signal changes (must be in injection context)
|
||||
effect(() => {
|
||||
const locale = this.userPreferencesService.localeSignal();
|
||||
if (locale) {
|
||||
this.dateAdapter.setLocale(DateFnsUtils.getLocaleFromString(locale));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges) {
|
||||
|
||||
+11
-8
@@ -15,7 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { DestroyRef, Directive, EventEmitter, inject, Input, OnChanges, OnInit, Output, SimpleChanges } from '@angular/core';
|
||||
import { DestroyRef, Directive, effect, EventEmitter, inject, Input, OnChanges, Output, SimpleChanges } from '@angular/core';
|
||||
import { AssignmentType, FilterOptions, TaskFilterAction, TaskFilterProperties, TaskStatusFilter } from '../../models/filter-cloud.model';
|
||||
import { TaskCloudService } from './../../../services/task-cloud.service';
|
||||
import { AppsProcessCloudService } from './../../../../app/services/apps-process-cloud.service';
|
||||
@@ -24,7 +24,7 @@ import { AbstractControl, UntypedFormBuilder, UntypedFormGroup } from '@angular/
|
||||
import { debounceTime, filter, finalize, switchMap } from 'rxjs/operators';
|
||||
import { Observable } from 'rxjs';
|
||||
import { DateAdapter } from '@angular/material/core';
|
||||
import { DateFnsUtils, TranslationService, UserPreferencesService, UserPreferenceValues } from '@alfresco/adf-core';
|
||||
import { DateFnsUtils, TranslationService, UserPreferencesService } from '@alfresco/adf-core';
|
||||
import { TaskFilterDialogCloudComponent } from '../task-filter-dialog/task-filter-dialog-cloud.component';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import { IdentityUserModel } from '../../../../people/models/identity-user.model';
|
||||
@@ -55,7 +55,7 @@ const ORDER_PROPERTY = 'order';
|
||||
|
||||
@Directive()
|
||||
// eslint-disable-next-line @angular-eslint/directive-class-suffix
|
||||
export abstract class BaseEditTaskFilterCloudComponent<T> implements OnInit, OnChanges {
|
||||
export abstract class BaseEditTaskFilterCloudComponent<T> implements OnChanges {
|
||||
public static ACTIONS_DISABLED_BY_DEFAULT = [ACTION_SAVE, ACTION_DELETE];
|
||||
|
||||
/** (required) Name of the app. */
|
||||
@@ -145,11 +145,14 @@ export abstract class BaseEditTaskFilterCloudComponent<T> implements OnInit, OnC
|
||||
protected formBuilder = inject(UntypedFormBuilder);
|
||||
protected dateAdapter = inject<DateAdapter<Date>>(DateAdapter);
|
||||
|
||||
ngOnInit() {
|
||||
this.userPreferencesService
|
||||
.select(UserPreferenceValues.Locale)
|
||||
.pipe(takeUntilDestroyed(this.destroyRef))
|
||||
.subscribe((locale) => this.dateAdapter.setLocale(locale));
|
||||
constructor() {
|
||||
// Use effect to react to locale signal changes (must be in injection context)
|
||||
effect(() => {
|
||||
const locale = this.userPreferencesService.localeSignal();
|
||||
if (locale) {
|
||||
this.dateAdapter.setLocale(DateFnsUtils.getLocaleFromString(locale));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges) {
|
||||
|
||||
Reference in New Issue
Block a user