mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2026-09-09 18:03:21 +00:00
AAE-43749 Added date formatting according to locale (#11769)
* [AAE-43749] added date formatting according to locale * [AAE-43749] applied pr comments * [AAE-43749] pipe use default date format reacting to locale
This commit is contained in:
@@ -15,47 +15,244 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { TimeAgoPipe } from './time-ago.pipe';
|
import { DatePipe, registerLocaleData } from '@angular/common';
|
||||||
|
import localeDe from '@angular/common/locales/de';
|
||||||
|
import localeDeExtra from '@angular/common/locales/extra/de';
|
||||||
import { TestBed } from '@angular/core/testing';
|
import { TestBed } from '@angular/core/testing';
|
||||||
import { AppConfigService } from '../app-config/app-config.service';
|
import { formatDistance } from 'date-fns';
|
||||||
import { UserPreferencesService } from '../common/services/user-preferences.service';
|
import { UserPreferencesService } from '../common/services/user-preferences.service';
|
||||||
import { of } from 'rxjs';
|
import { DateFnsUtils } from '../common/utils/date-fns-utils';
|
||||||
|
import { TimeAgoPipe } from './time-ago.pipe';
|
||||||
|
import { AppConfigService } from '../app-config';
|
||||||
|
|
||||||
|
registerLocaleData(localeDe, 'de', localeDeExtra);
|
||||||
|
|
||||||
describe('TimeAgoPipe', () => {
|
describe('TimeAgoPipe', () => {
|
||||||
let pipe: TimeAgoPipe;
|
const NOW = new Date('2026-03-27T12:00:00.000Z');
|
||||||
let userPreferences: UserPreferencesService;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
const createPipe = (dateFormat, locale): TimeAgoPipe => {
|
||||||
|
TestBed.resetTestingModule();
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
providers: [TimeAgoPipe, UserPreferencesService, AppConfigService]
|
providers: [
|
||||||
|
TimeAgoPipe,
|
||||||
|
{
|
||||||
|
provide: UserPreferencesService,
|
||||||
|
useValue: {
|
||||||
|
localeSignal: jasmine.createSpy('localeSignal').and.returnValue(locale)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
provide: AppConfigService,
|
||||||
|
useValue: {
|
||||||
|
get: jasmine.createSpy('get').and.returnValue(dateFormat)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
userPreferences = TestBed.inject(UserPreferencesService);
|
const newPipe = TestBed.inject(TimeAgoPipe);
|
||||||
spyOn(userPreferences, 'select').and.returnValue(of(''));
|
spyOn(newPipe, 'getCurrentDateTime').and.returnValue(NOW);
|
||||||
pipe = TestBed.inject(TimeAgoPipe);
|
|
||||||
|
return newPipe;
|
||||||
|
};
|
||||||
|
|
||||||
|
describe('AppConfigService returns "MMM d, y, h:mm" and locale="en-US" ', () => {
|
||||||
|
let pipe: TimeAgoPipe;
|
||||||
|
beforeEach(() => {
|
||||||
|
pipe = createPipe('MMM d, y, h:mm', 'en-US');
|
||||||
|
});
|
||||||
|
it('should return time difference for a given date', () => {
|
||||||
|
const date = pipe.getCurrentDateTime();
|
||||||
|
expect(pipe.transform(date)).toBe('less than a minute ago');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return exact date if given date is more than seven days for en locale ', () => {
|
||||||
|
const date = new Date('1990-11-02T15:25:42.749');
|
||||||
|
expect(pipe.transform(date)).toBe('Nov 2, 1990, 3:25');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return empty string if given date is empty', () => {
|
||||||
|
expect(pipe.transform(null)).toBe('');
|
||||||
|
expect(pipe.transform(undefined)).toBe('');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return relative distance when date is a few hours ago', () => {
|
||||||
|
const threeHoursAgo = new Date('2026-03-27T09:00:00.000Z');
|
||||||
|
|
||||||
|
const result = pipe.transform(threeHoursAgo);
|
||||||
|
|
||||||
|
const expected = formatDistance(threeHoursAgo, NOW, {
|
||||||
|
addSuffix: true,
|
||||||
|
locale: DateFnsUtils.getLocaleFromString('en-US')
|
||||||
|
});
|
||||||
|
expect(result).toBe(expected);
|
||||||
|
});
|
||||||
|
it('should return relative distance when date is 6 days ago', () => {
|
||||||
|
const sixDaysAgo = new Date('2026-03-21T12:00:00.000Z');
|
||||||
|
|
||||||
|
const result = pipe.transform(sixDaysAgo);
|
||||||
|
|
||||||
|
const expected = formatDistance(sixDaysAgo, NOW, {
|
||||||
|
addSuffix: true,
|
||||||
|
locale: DateFnsUtils.getLocaleFromString('en-US')
|
||||||
|
});
|
||||||
|
expect(result).toBe(expected);
|
||||||
|
});
|
||||||
|
it('should return relative distance when date is exactly 7 days ago', () => {
|
||||||
|
const sevenDaysAgo = new Date('2026-03-20T12:00:00.000Z');
|
||||||
|
|
||||||
|
const result = pipe.transform(sevenDaysAgo);
|
||||||
|
|
||||||
|
const expected = formatDistance(sevenDaysAgo, NOW, {
|
||||||
|
addSuffix: true,
|
||||||
|
locale: DateFnsUtils.getLocaleFromString('en-US')
|
||||||
|
});
|
||||||
|
expect(result).toBe(expected);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should use locale argument over user preference locale', () => {
|
||||||
|
const oldDate = new Date('2026-03-01T10:00:00.000Z');
|
||||||
|
const result = pipe.transform(oldDate, 'de');
|
||||||
|
|
||||||
|
expect(result).toBe('März 1, 2026, 10:00');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return time difference for a given date', () => {
|
describe('AppConfigService return "MMM d, y, h:mm" and locale="de" ', () => {
|
||||||
const date = new Date();
|
let pipe: TimeAgoPipe;
|
||||||
expect(pipe.transform(date)).toBe('less than a minute ago');
|
beforeEach(() => {
|
||||||
|
pipe = createPipe('MMM d, y, h:mm', 'de');
|
||||||
|
});
|
||||||
|
it('should return time difference for a given date', () => {
|
||||||
|
const date = pipe.getCurrentDateTime();
|
||||||
|
expect(pipe.transform(date)).toBe('vor weniger als 1 Minute');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return exact date if given date is more than seven days for de locale ', () => {
|
||||||
|
const date = new Date('1990-11-03T15:25:42.749');
|
||||||
|
expect(pipe.transform(date)).toBe('Nov. 3, 1990, 3:25');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return empty string if given date is empty', () => {
|
||||||
|
expect(pipe.transform(null)).toBe('');
|
||||||
|
expect(pipe.transform(undefined)).toBe('');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return relative distance when date is a few hours ago', () => {
|
||||||
|
const threeHoursAgo = new Date('2026-03-27T09:00:00.000Z');
|
||||||
|
const result = pipe.transform(threeHoursAgo);
|
||||||
|
const expected = formatDistance(threeHoursAgo, NOW, {
|
||||||
|
addSuffix: true,
|
||||||
|
locale: DateFnsUtils.getLocaleFromString('de')
|
||||||
|
});
|
||||||
|
expect(result).toBe(expected);
|
||||||
|
});
|
||||||
|
it('should return relative distance when date is 6 days ago', () => {
|
||||||
|
const sixDaysAgo = new Date('2026-03-21T12:00:00.000Z');
|
||||||
|
const result = pipe.transform(sixDaysAgo);
|
||||||
|
const expected = formatDistance(sixDaysAgo, NOW, {
|
||||||
|
addSuffix: true,
|
||||||
|
locale: DateFnsUtils.getLocaleFromString('de')
|
||||||
|
});
|
||||||
|
expect(result).toBe(expected);
|
||||||
|
});
|
||||||
|
it('should return relative distance when date is exactly 7 days ago', () => {
|
||||||
|
const sevenDaysAgo = new Date('2026-03-20T12:00:00.000Z');
|
||||||
|
const result = pipe.transform(sevenDaysAgo);
|
||||||
|
const expected = formatDistance(sevenDaysAgo, NOW, {
|
||||||
|
addSuffix: true,
|
||||||
|
locale: DateFnsUtils.getLocaleFromString('de')
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(result).toBe(expected);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should use locale argument over user preference locale', () => {
|
||||||
|
const oldDate = new Date('2026-03-01T10:00:00.000Z');
|
||||||
|
const result = pipe.transform(oldDate, 'en-US');
|
||||||
|
|
||||||
|
expect(result).toBe('Mar 1, 2026, 10:00');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return exact date if given date is more than seven days ', () => {
|
describe('AppConfigService has no value and returns default short and locale="en-US" ', () => {
|
||||||
const date = new Date('1990-11-03T15:25:42.749');
|
let pipe: TimeAgoPipe;
|
||||||
expect(pipe.transform(date)).toBe('03/11/1990 15:25');
|
beforeEach(() => {
|
||||||
|
pipe = createPipe('short', 'en-US');
|
||||||
|
});
|
||||||
|
it('should return time difference for a given date', () => {
|
||||||
|
const date = pipe.getCurrentDateTime();
|
||||||
|
expect(pipe.transform(date)).toBe('less than a minute ago');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return exact date if given date is more than seven days for en locale ', () => {
|
||||||
|
const date = new Date('1990-11-04T15:25:42.749');
|
||||||
|
|
||||||
|
expect(pipe.transform(date)).toBe('11/4/90, 3:25 PM');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return empty string if given date is empty', () => {
|
||||||
|
expect(pipe.transform(null)).toBe('');
|
||||||
|
expect(pipe.transform(undefined)).toBe('');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should use locale argument over user preference locale', () => {
|
||||||
|
const oldDate = new Date('2026-03-01T10:00:00.000Z');
|
||||||
|
const result = pipe.transform(oldDate, 'de');
|
||||||
|
|
||||||
|
expect(result).toBe('01.03.26, 10:00');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return empty string if given date is empty', () => {
|
describe('AppConfigService has no value and returns default short and locale="de" ', () => {
|
||||||
expect(pipe.transform(null)).toBe('');
|
let pipe: TimeAgoPipe;
|
||||||
expect(pipe.transform(undefined)).toBe('');
|
beforeEach(() => {
|
||||||
|
pipe = createPipe('short', 'de');
|
||||||
|
});
|
||||||
|
it('should return time difference for a given date', () => {
|
||||||
|
const date = pipe.getCurrentDateTime();
|
||||||
|
expect(pipe.transform(date)).toBe('vor weniger als 1 Minute');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return exact date if given date is more than seven days for de locale ', () => {
|
||||||
|
const date = new Date('1990-11-04T15:25:42.749');
|
||||||
|
expect(pipe.transform(date)).toBe('04.11.90, 15:25');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return empty string if given date is empty', () => {
|
||||||
|
expect(pipe.transform(null)).toBe('');
|
||||||
|
expect(pipe.transform(undefined)).toBe('');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should use locale argument over user preference locale', () => {
|
||||||
|
const oldDate = new Date('2026-03-01T10:00:00.000Z');
|
||||||
|
const result = pipe.transform(oldDate, 'en-US');
|
||||||
|
|
||||||
|
expect(result).toBe('3/1/26, 10:00 AM');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('When a locale is given', () => {
|
describe('locale handling', () => {
|
||||||
it('should return a localised message', () => {
|
let pipe: TimeAgoPipe;
|
||||||
const date = new Date();
|
beforeEach(() => {
|
||||||
const transformedDate = pipe.transform(date, 'de');
|
pipe = createPipe('short', undefined);
|
||||||
/* cspell:disable-next-line */
|
});
|
||||||
expect(transformedDate).toBe('vor weniger als 1 Minute');
|
it('should return localized relative message when locale argument is provided', () => {
|
||||||
|
const date = new Date(NOW);
|
||||||
|
const result = pipe.transform(date, 'de');
|
||||||
|
const expected = formatDistance(date, NOW, {
|
||||||
|
addSuffix: true,
|
||||||
|
locale: DateFnsUtils.getLocaleFromString('de')
|
||||||
|
});
|
||||||
|
expect(result).toBe(expected);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should fall back to DEFAULT_LOCALE when user preference locale is empty', () => {
|
||||||
|
const oldDate = new Date('2026-03-01T10:00:00.000Z');
|
||||||
|
const result = pipe.transform(oldDate);
|
||||||
|
const expected = new DatePipe('en-US').transform(oldDate, 'short');
|
||||||
|
|
||||||
|
expect(result).toBe(expected);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ export class TimeAgoPipe implements PipeTransform {
|
|||||||
appConfig = inject(AppConfigService);
|
appConfig = inject(AppConfigService);
|
||||||
|
|
||||||
static DEFAULT_LOCALE = 'en-US';
|
static DEFAULT_LOCALE = 'en-US';
|
||||||
static DEFAULT_DATE_TIME_FORMAT = 'dd/MM/yyyy HH:mm';
|
static DEFAULT_DATE_TIME_FORMAT = 'short';
|
||||||
|
|
||||||
defaultDateTimeFormat: string;
|
defaultDateTimeFormat: string;
|
||||||
|
|
||||||
@@ -40,18 +40,22 @@ export class TimeAgoPipe implements PipeTransform {
|
|||||||
this.defaultDateTimeFormat = this.appConfig.get<string>('dateValues.defaultDateTimeFormat', TimeAgoPipe.DEFAULT_DATE_TIME_FORMAT);
|
this.defaultDateTimeFormat = this.appConfig.get<string>('dateValues.defaultDateTimeFormat', TimeAgoPipe.DEFAULT_DATE_TIME_FORMAT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getCurrentDateTime(): Date {
|
||||||
|
return new Date();
|
||||||
|
}
|
||||||
|
|
||||||
transform(value: Date, locale?: string) {
|
transform(value: Date, locale?: string) {
|
||||||
if (value !== null && value !== undefined) {
|
if (value !== null && value !== undefined) {
|
||||||
// Use signal directly - no subscription needed!
|
// Use signal directly - no subscription needed!
|
||||||
const defaultLocale = this.userPreferenceService.localeSignal() || TimeAgoPipe.DEFAULT_LOCALE;
|
const defaultLocale = this.userPreferenceService.localeSignal() || TimeAgoPipe.DEFAULT_LOCALE;
|
||||||
const actualLocale = locale || defaultLocale;
|
const actualLocale = locale || defaultLocale;
|
||||||
const diff = differenceInDays(new Date(), new Date(value));
|
const diff = differenceInDays(this.getCurrentDateTime(), new Date(value));
|
||||||
if (diff > 7) {
|
if (diff > 7) {
|
||||||
const datePipe: DatePipe = new DatePipe(actualLocale);
|
const datePipe: DatePipe = new DatePipe(actualLocale);
|
||||||
return datePipe.transform(value, this.defaultDateTimeFormat);
|
return datePipe.transform(value, this.defaultDateTimeFormat);
|
||||||
} else {
|
} else {
|
||||||
const dateFnsLocale = DateFnsUtils.getLocaleFromString(actualLocale);
|
const dateFnsLocale = DateFnsUtils.getLocaleFromString(actualLocale);
|
||||||
return formatDistance(new Date(value), new Date(), { addSuffix: true, locale: dateFnsLocale });
|
return formatDistance(new Date(value), this.getCurrentDateTime(), { addSuffix: true, locale: dateFnsLocale });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return '';
|
return '';
|
||||||
|
|||||||
Reference in New Issue
Block a user