diff --git a/lib/core/src/lib/form/components/widgets/amount/amount.widget.spec.ts b/lib/core/src/lib/form/components/widgets/amount/amount.widget.spec.ts
index bc416e9e63..38a224d9d6 100644
--- a/lib/core/src/lib/form/components/widgets/amount/amount.widget.spec.ts
+++ b/lib/core/src/lib/form/components/widgets/amount/amount.widget.spec.ts
@@ -23,6 +23,10 @@ import { FormModel } from '../core/form.model';
import { HarnessLoader } from '@angular/cdk/testing';
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
import { UnitTestingUtils } from '../../../../testing/unit-testing-utils';
+import { of } from 'rxjs';
+import { FormService } from '../../../services/form.service';
+import { FormFieldEvent } from '../../../events/form-field.event';
+import { TranslationService } from '../../../../translation/translation.service';
describe('AmountWidgetComponent', () => {
let loader: HarnessLoader;
@@ -32,8 +36,10 @@ describe('AmountWidgetComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
- imports: [AmountWidgetComponent]
+ imports: [AmountWidgetComponent],
+ providers: [{ provide: TranslationService, useValue: { getLocale: () => 'en-US' } }]
});
+
fixture = TestBed.createComponent(AmountWidgetComponent);
widget = fixture.componentInstance;
loader = TestbedHarnessEnvironment.loader(fixture);
@@ -94,6 +100,109 @@ describe('AmountWidgetComponent', () => {
expect(widget.placeholder).toBe('1234');
});
+ it('it should return locale based on browser', () => {
+ const expectedLanguage = 'en-US';
+ widget.enableDisplayBasedOnLocale = true;
+ widget.field = new FormFieldModel(null, { id: 1, name: 'test', value: 25, currency: 'USD' });
+ widget.setInitialValues();
+ fixture.detectChanges();
+
+ expect(widget.locale).toBe(expectedLanguage);
+ });
+
+ it('should set initial values when enableDisplayBasedOnLocale is enabled', () => {
+ widget.field = new FormFieldModel(null, { id: 1, name: 'test', value: 25, currency: 'USD' });
+ widget.enableDisplayBasedOnLocale = true;
+ widget.currency = 'USD';
+ widget.setInitialValues();
+
+ expect(widget.amountWidgetValue).toBe('$25');
+ expect(widget.decimalProperty).toBe('1.0-0');
+ expect(widget.valueAsNumber).toBe(25);
+ });
+
+ it('should set initial values with correct currency', () => {
+ widget.field = new FormFieldModel(null, { id: 2, name: 'test', value: 25, currency: 'GBP' });
+ widget.enableDisplayBasedOnLocale = true;
+ widget.currency = 'GBP';
+ widget.setInitialValues();
+
+ expect(widget.amountWidgetValue).toBe('£25');
+ expect(widget.decimalProperty).toBe('1.0-0');
+ });
+
+ it('should set initial values with correct currency icon', () => {
+ widget.field = new FormFieldModel(null, { id: 2, name: 'test', value: 25, currency: '¥' });
+ widget.enableDisplayBasedOnLocale = true;
+ widget.currency = '¥';
+ widget.setInitialValues();
+
+ expect(widget.amountWidgetValue).toBe('¥25');
+ expect(widget.decimalProperty).toBe('1.0-0');
+ });
+
+ it('should set initial values without currency', () => {
+ widget.field = new FormFieldModel(null, { id: 3, name: 'test', value: 25, currency: '' });
+ widget.enableDisplayBasedOnLocale = true;
+ widget.currency = '';
+ widget.currencyDisplay = '';
+ widget.setInitialValues();
+
+ expect(widget.amountWidgetValue).toBe('25');
+ expect(widget.decimalProperty).toBe('1.0-0');
+ });
+
+ it('should set initial values when enableDisplayBasedOnLocale is disabled', () => {
+ widget.field = new FormFieldModel(null, { id: 4, name: 'test', value: 25, enableFractions: false, className: '' });
+ widget.enableDisplayBasedOnLocale = false;
+ widget.setInitialValues();
+
+ expect(widget.amountWidgetValue.toString()).toBe('25');
+ });
+
+ it('should transform value from number to string', () => {
+ widget.enableDisplayBasedOnLocale = true;
+ widget.valueAsNumber = 123456;
+ widget.amountWidgetOnFocus();
+ expect(widget.amountWidgetValue).toBe('123456');
+
+ widget.valueAsNumber = 123456.11;
+ widget.amountWidgetOnFocus();
+ expect(widget.amountWidgetValue).toBe('123456.11');
+
+ widget.valueAsNumber = 0;
+ widget.amountWidgetOnFocus();
+ expect(widget.amountWidgetValue).toBe('0');
+
+ widget.valueAsNumber = undefined;
+ widget.amountWidgetOnFocus();
+ expect(widget.amountWidgetValue).toBe(null);
+ });
+
+ it('should update field.value on change', () => {
+ widget.field = new FormFieldModel(null, { id: 5, name: 'test', value: 25 });
+ const mockValue = '1234.12';
+ widget.amountWidgetValue = mockValue;
+ widget.onFieldChangedAmountWidget();
+
+ expect(widget.field.value).toBe(mockValue);
+ });
+
+ it('should transform values on blur', () => {
+ widget.enableDisplayBasedOnLocale = true;
+ widget.amountWidgetValue = '1234.56';
+ widget.amountWidgetOnBlur();
+
+ expect(widget.valueAsNumber).toBe(1234.56);
+ expect(widget.amountWidgetValue).toBe('$1,234.56');
+
+ widget.amountWidgetValue = '';
+ widget.amountWidgetOnBlur();
+
+ expect(widget.valueAsNumber).toBe(null);
+ expect(widget.amountWidgetValue).toBe(null);
+ });
+
describe('when tooltip is set', () => {
beforeEach(() => {
widget.field = new FormFieldModel(new FormModel({ taskId: '
' }), {
@@ -145,6 +254,7 @@ describe('AmountWidgetComponent - rendering', () => {
let widget: AmountWidgetComponent;
let fixture: ComponentFixture;
let testingUtils: UnitTestingUtils;
+ let formService: FormService;
beforeEach(() => {
TestBed.configureTestingModule({
@@ -154,6 +264,7 @@ describe('AmountWidgetComponent - rendering', () => {
widget = fixture.componentInstance;
loader = TestbedHarnessEnvironment.loader(fixture);
testingUtils = new UnitTestingUtils(fixture.debugElement, loader);
+ formService = TestBed.inject(FormService);
});
it('[C289915] - Should be able to display different currency icons', async () => {
@@ -345,6 +456,311 @@ describe('AmountWidgetComponent - rendering', () => {
expect(asterisk.textContent).toEqual('*');
});
});
+
+ describe('Test widget with ADF_AMOUNT_SETTINGS as observable', () => {
+ beforeEach(() => {
+ TestBed.resetTestingModule();
+ });
+
+ describe('set module for enableDisplayBasedOnLocale = true', () => {
+ const mockField = new FormFieldModel(new FormModel(), {
+ id: 'TestAmount1',
+ name: 'Test Amount',
+ type: 'amount',
+ currency: 'USD',
+ enableFractions: true,
+ value: '1234.55'
+ });
+ beforeEach(async () => {
+ TestBed.configureTestingModule({
+ imports: [AmountWidgetComponent],
+ providers: [
+ { provide: ADF_AMOUNT_SETTINGS, useValue: of({ enableDisplayBasedOnLocale: true }) },
+ { provide: TranslationService, useValue: { getLocale: () => 'en-US' } }
+ ]
+ });
+ fixture = TestBed.createComponent(AmountWidgetComponent);
+ widget = fixture.componentInstance;
+ fixture.componentRef.setInput('field', mockField);
+ loader = TestbedHarnessEnvironment.loader(fixture);
+ testingUtils = new UnitTestingUtils(fixture.debugElement, loader);
+ fixture.detectChanges();
+ });
+
+ it('should set enableDisplayBasedOnLocale to true', () => {
+ expect(widget.enableDisplayBasedOnLocale).toBeTrue();
+ expect(widget.decimalProperty).toBe('1.2-2');
+ expect(widget.locale).toBe('en-US');
+ expect(widget.valueAsNumber).toBe('1234.55');
+ expect(widget.amountWidgetValue).toBe('$1,234.55');
+ });
+
+ it('should not display prefix with currency when enableDisplayBasedOnLocale = true', async () => {
+ const field = await testingUtils.getMatFormField();
+ expect(await field.getPrefixText()).toBe('');
+ });
+ });
+ });
+
+ describe('AmountWidgetComponent - subscribeToFieldChanges', () => {
+ it('should subscribe to formFieldValueChanged events for the specific field', () => {
+ const mockField = new FormFieldModel(new FormModel(), {
+ id: 'amount-1',
+ name: 'Test Amount',
+ type: 'amount',
+ value: '100'
+ });
+ const subscriptionSpy = spyOn(formService.formFieldValueChanged, 'subscribe').and.callThrough();
+ widget.field = mockField;
+ widget.subscribeToFieldChanges();
+
+ expect(subscriptionSpy).toHaveBeenCalled();
+ });
+
+ it('should update value when field value changes and input is not in focus with enableDisplayBasedOnLocale enabled', async () => {
+ const mockField = new FormFieldModel(new FormModel(), {
+ id: 'amount-1',
+ name: 'Test Amount',
+ type: 'amount',
+ value: '100',
+ currency: 'USD'
+ });
+ widget.field = mockField;
+ widget.enableDisplayBasedOnLocale = true;
+ widget.isInputInFocus = false;
+ widget.currency = 'USD';
+ widget.decimalProperty = '1.0-0';
+ widget.ngOnInit();
+
+ const updateValueSpy = spyOn(widget, 'updateValue').and.callThrough();
+ formService.formFieldValueChanged.next(new FormFieldEvent(mockField.form, { ...mockField, value: '200' } as FormFieldModel));
+ await fixture.whenStable();
+
+ expect(updateValueSpy).toHaveBeenCalledWith('200');
+ expect(widget.amountWidgetValue).toBe('$200');
+ });
+
+ it('should update amountWidgetValue when field value changes and input is not in focus with enableDisplayBasedOnLocale disabled', () => {
+ const updateValueSpy = spyOn(widget, 'updateValue').and.callThrough();
+ const mockField = new FormFieldModel(new FormModel(), {
+ id: 'amount-1',
+ name: 'Test Amount',
+ type: 'amount',
+ value: '100'
+ });
+ widget.field = mockField;
+ widget.enableDisplayBasedOnLocale = false;
+ widget.isInputInFocus = false;
+ widget.ngOnInit();
+
+ formService.formFieldValueChanged.next(new FormFieldEvent(mockField.form, { ...mockField, value: '200' } as FormFieldModel));
+
+ expect(updateValueSpy).not.toHaveBeenCalled();
+ expect(widget.amountWidgetValue).toBe('200');
+ });
+
+ it('should not update value with formService.formFieldValueChanged when input is in focus', () => {
+ const mockField = new FormFieldModel(new FormModel(), {
+ id: 'amount-1',
+ name: 'Test Amount',
+ type: 'amount',
+ value: '100'
+ });
+ widget.field = mockField;
+ widget.enableDisplayBasedOnLocale = true;
+ widget.isInputInFocus = true;
+ widget.amountWidgetValue = '100';
+ widget.ngOnInit();
+ const updateValueSpy = spyOn(widget, 'updateValue');
+ formService.formFieldValueChanged.next(new FormFieldEvent(mockField.form, { ...mockField, value: '200' } as FormFieldModel));
+
+ expect(updateValueSpy).not.toHaveBeenCalled();
+ expect(widget.amountWidgetValue).toBe('100');
+ });
+
+ it('should not react to events from different fields', () => {
+ const mockField = new FormFieldModel(new FormModel(), {
+ id: 'amount-1',
+ name: 'Test Amount',
+ type: 'amount',
+ value: '100',
+ enableFractions: false
+ });
+ const otherField = new FormFieldModel(new FormModel(), {
+ id: 'amount-2',
+ name: 'Other Amount',
+ type: 'amount',
+ value: '200'
+ });
+ widget.field = mockField;
+ widget.currency = 'USD';
+ widget.enableDisplayBasedOnLocale = true;
+ widget.isInputInFocus = false;
+ widget.amountWidgetValue = '100';
+ widget.ngOnInit();
+
+ const updateValueSpy = spyOn(widget, 'updateValue').and.callThrough();
+
+ formService.formFieldValueChanged.next(new FormFieldEvent(otherField.form, otherField));
+
+ expect(updateValueSpy).not.toHaveBeenCalled();
+ });
+
+ it('should use field.value when updating without enableDisplayBasedOnLocale and input not in focus', () => {
+ const mockField = new FormFieldModel(new FormModel(), {
+ id: 'amount-1',
+ name: 'Test Amount',
+ type: 'amount',
+ value: '100'
+ });
+ widget.field = mockField;
+ widget.enableDisplayBasedOnLocale = false;
+ widget.isInputInFocus = false;
+ widget.ngOnInit();
+
+ mockField.value = '300';
+ formService.formFieldValueChanged.next(new FormFieldEvent(mockField.form, mockField));
+
+ expect(widget.amountWidgetValue).toBe('300');
+ });
+ });
+
+ describe('Test widget with different setting for enableDisplayBasedOnLocale', () => {
+ beforeEach(() => {
+ TestBed.resetTestingModule();
+ });
+
+ describe('set module for enableDisplayBasedOnLocale = true', () => {
+ const mockField = new FormFieldModel(new FormModel(), {
+ id: 'TestAmount1',
+ name: 'Test Amount',
+ type: 'amount',
+ currency: 'USD',
+ enableFractions: true,
+ value: '1234.55'
+ });
+ beforeEach(async () => {
+ TestBed.configureTestingModule({
+ imports: [AmountWidgetComponent],
+ providers: [{ provide: ADF_AMOUNT_SETTINGS, useValue: { enableDisplayBasedOnLocale: true } }]
+ });
+ fixture = TestBed.createComponent(AmountWidgetComponent);
+ widget = fixture.componentInstance;
+
+ fixture.componentRef.setInput('field', mockField);
+ loader = TestbedHarnessEnvironment.loader(fixture);
+ testingUtils = new UnitTestingUtils(fixture.debugElement, loader);
+ fixture.detectChanges();
+ });
+
+ it('should not display prefix with currency when enableDisplayBasedOnLocale = true', async () => {
+ const field = await testingUtils.getMatFormField();
+ expect(await field.getPrefixText()).toBe('');
+ });
+
+ it('should call method on focus and change input value', async () => {
+ const focusSpy = spyOn(widget, 'amountWidgetOnFocus').and.callThrough();
+ fixture.detectChanges();
+
+ const field = await testingUtils.getMatInput();
+ const fieldValueBeforeFocus = await field.getValue();
+ await field.focus();
+ const fieldValue = await field.getValue();
+
+ expect(field).toBeDefined();
+ expect(widget.field.value).toBe('1234.55');
+ expect(fieldValueBeforeFocus).toBe('$1,234.55');
+ expect(focusSpy).toHaveBeenCalled();
+ expect(fieldValue).toBe('1234.55');
+ });
+
+ it('should transform value on blur', async () => {
+ const newValue = '456789';
+ const blurSpy = spyOn(widget, 'amountWidgetOnBlur').and.callThrough();
+ fixture.detectChanges();
+
+ const field = await testingUtils.getMatInput();
+ const fieldValueBeforeBlur = await field.getValue();
+ await field.setValue(newValue);
+ await field.blur();
+ const fieldValue = await field.getValue();
+
+ expect(field).toBeDefined();
+ expect(widget.field.value).toBe(newValue);
+ expect(fieldValueBeforeBlur).toBe('$1,234.55');
+ expect(blurSpy).toHaveBeenCalled();
+ expect(widget.valueAsNumber).toBe(parseFloat(newValue));
+ expect(widget.amountWidgetValue).toBe('$456,789.00');
+ expect(fieldValue).toBe('$456,789.00');
+ });
+ });
+ describe('set module for enableDisplayBasedOnLocale = false', () => {
+ const mockField = new FormFieldModel(new FormModel(), {
+ id: 'TestAmount1',
+ name: 'Test Amount',
+ type: 'amount',
+ currency: 'USD',
+ enableFractions: true,
+ value: '1234.55'
+ });
+ beforeEach(async () => {
+ TestBed.configureTestingModule({
+ imports: [AmountWidgetComponent],
+ providers: [{ provide: ADF_AMOUNT_SETTINGS, useValue: { enableDisplayBasedOnLocale: false } }]
+ });
+ fixture = TestBed.createComponent(AmountWidgetComponent);
+ widget = fixture.componentInstance;
+
+ fixture.componentRef.setInput('field', mockField);
+ loader = TestbedHarnessEnvironment.loader(fixture);
+ testingUtils = new UnitTestingUtils(fixture.debugElement, loader);
+ fixture.detectChanges();
+ });
+
+ it('should display prefix with currency when enableDisplayBasedOnLocale = true', async () => {
+ const field = await testingUtils.getMatFormField();
+ expect(await field.getPrefixText()).toBe('USD');
+ });
+
+ it('should call method on focus and not change input value', async () => {
+ const focusSpy = spyOn(widget, 'amountWidgetOnFocus').and.callThrough();
+ fixture.detectChanges();
+
+ const field = await testingUtils.getMatInput();
+ const fieldValueBeforeFocus = await field.getValue();
+ await field.focus();
+ const fieldValue = await field.getValue();
+
+ expect(field).toBeDefined();
+ expect(widget.field.value).toBe('1234.55');
+ expect(widget.valueAsNumber).toBeUndefined();
+ expect(fieldValueBeforeFocus).toBe('1234.55');
+ expect(focusSpy).toHaveBeenCalled();
+ expect(fieldValue).toBe('1234.55');
+ });
+
+ it('should call method on blur and not change input value', async () => {
+ const newValue = '456789';
+ const blurSpy = spyOn(widget, 'amountWidgetOnBlur').and.callThrough();
+ fixture.detectChanges();
+
+ const field = await testingUtils.getMatInput();
+ const fieldValueBeforeBlur = await field.getValue();
+ await field.setValue(newValue);
+ await field.blur();
+ const fieldValue = await field.getValue();
+
+ expect(field).toBeDefined();
+ expect(widget.field.value).toBe(newValue);
+ expect(widget.valueAsNumber).toBeUndefined();
+ expect(fieldValueBeforeBlur).toBe('1234.55');
+ expect(blurSpy).toHaveBeenCalled();
+ expect(widget.valueAsNumber).toBeUndefined();
+ expect(widget.amountWidgetValue).toBe('456789');
+ expect(fieldValue).toBe('456789');
+ });
+ });
+ });
});
describe('AmountWidgetComponent settings', () => {
diff --git a/lib/core/src/lib/form/components/widgets/amount/amount.widget.ts b/lib/core/src/lib/form/components/widgets/amount/amount.widget.ts
index 1a8e5bb014..db7929b8dc 100644
--- a/lib/core/src/lib/form/components/widgets/amount/amount.widget.ts
+++ b/lib/core/src/lib/form/components/widgets/amount/amount.widget.ts
@@ -17,8 +17,8 @@
/* eslint-disable @angular-eslint/component-selector */
-import { NgIf } from '@angular/common';
-import { Component, OnInit, ViewEncapsulation, InjectionToken, Inject, Optional } from '@angular/core';
+import { CurrencyPipe, NgIf } from '@angular/common';
+import { Component, OnInit, ViewEncapsulation, InjectionToken, Inject, Optional, inject, DestroyRef } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';
@@ -26,12 +26,17 @@ import { TranslatePipe } from '@ngx-translate/core';
import { FormService } from '../../../services/form.service';
import { ErrorWidgetComponent } from '../error/error.component';
import { WidgetComponent } from '../widget.component';
+import { filter, isObservable, Observable } from 'rxjs';
+import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
+import { FormFieldEvent } from '../../../events/form-field.event';
+import { TranslationService } from '../../../../translation/translation.service';
export interface AmountWidgetSettings {
showReadonlyPlaceholder: boolean;
+ enableDisplayBasedOnLocale: boolean;
}
-export const ADF_AMOUNT_SETTINGS = new InjectionToken('adf-amount-settings');
+export const ADF_AMOUNT_SETTINGS = new InjectionToken | AmountWidgetSettings>('adf-amount-settings');
@Component({
selector: 'amount-widget',
@@ -49,13 +54,25 @@ export const ADF_AMOUNT_SETTINGS = new InjectionToken('adf
'(select)': 'event($event)'
},
imports: [MatFormFieldModule, MatInputModule, FormsModule, ErrorWidgetComponent, TranslatePipe, NgIf],
+ providers: [CurrencyPipe],
encapsulation: ViewEncapsulation.None
})
export class AmountWidgetComponent extends WidgetComponent implements OnInit {
static DEFAULT_CURRENCY: string = '$';
private showPlaceholder = true;
+ private readonly destroyRef = inject(DestroyRef);
+ amountWidgetValue: string;
currency: string = AmountWidgetComponent.DEFAULT_CURRENCY;
+ currencyDisplay: string | boolean = 'symbol';
+ decimalProperty: string;
+ enableDisplayBasedOnLocale: boolean;
+ isInputInFocus = false;
+ locale: string;
+ notShowDecimalDigits = '1.0-0';
+ showDecimalDigits = '1.2-2';
+ showReadonlyPlaceholder: boolean;
+ valueAsNumber: number;
get placeholder(): string {
return this.showPlaceholder ? this.field.placeholder : '';
@@ -63,22 +80,103 @@ export class AmountWidgetComponent extends WidgetComponent implements OnInit {
constructor(
public formService: FormService,
- @Inject(ADF_AMOUNT_SETTINGS)
- @Optional()
- private settings: AmountWidgetSettings
+ @Optional() @Inject(ADF_AMOUNT_SETTINGS) settings: Observable | AmountWidgetSettings,
+ private currencyPipe: CurrencyPipe,
+ private translationService: TranslationService
) {
super(formService);
+ if (isObservable(settings)) {
+ settings.pipe(takeUntilDestroyed()).subscribe((data: AmountWidgetSettings) => {
+ this.updateSettingsBasedProperties(data);
+ });
+ } else {
+ this.updateSettingsBasedProperties(settings);
+ }
}
ngOnInit() {
if (this.field) {
if (this.field.currency) {
this.currency = this.field.currency;
+ } else {
+ if (this.enableDisplayBasedOnLocale) {
+ this.currency = '';
+ this.currencyDisplay = '';
+ }
}
if (this.field.readOnly) {
- this.showPlaceholder = this.settings?.showReadonlyPlaceholder;
+ this.showPlaceholder = this.showReadonlyPlaceholder;
}
+ this.subscribeToFieldChanges();
+ this.setInitialValues();
}
}
+
+ amountWidgetOnBlur(): void {
+ this.isInputInFocus = false;
+ if (this.enableDisplayBasedOnLocale) {
+ if (this.amountWidgetValue) {
+ this.valueAsNumber = parseFloat(this.amountWidgetValue);
+ this.amountWidgetValue = this.currencyPipe.transform(
+ this.amountWidgetValue,
+ this.currency,
+ this.currencyDisplay,
+ this.decimalProperty
+ );
+ } else {
+ this.valueAsNumber = null;
+ this.amountWidgetValue = null;
+ }
+ }
+ this.markAsTouched();
+ }
+
+ amountWidgetOnFocus(): void {
+ this.isInputInFocus = true;
+ if (this.enableDisplayBasedOnLocale) {
+ const hasValue = this.valueAsNumber === 0 || this.valueAsNumber;
+ this.amountWidgetValue = hasValue ? this.valueAsNumber.toString() : null;
+ }
+ }
+
+ onFieldChangedAmountWidget(): void {
+ this.field.value = this.amountWidgetValue;
+ super.onFieldChanged(this.field);
+ }
+
+ setInitialValues(): void {
+ if (this.enableDisplayBasedOnLocale) {
+ this.decimalProperty = this.field.enableFractions ? this.showDecimalDigits : this.notShowDecimalDigits;
+ this.locale = this.translationService.getLocale();
+ this.updateValue(this.field.value);
+ } else {
+ this.amountWidgetValue = this.field.value;
+ }
+ }
+
+ subscribeToFieldChanges(): void {
+ this.formService.formFieldValueChanged
+ .pipe(
+ filter((ev: FormFieldEvent) => ev.field.id === this.field.id),
+ takeUntilDestroyed(this.destroyRef)
+ )
+ .subscribe((ev: FormFieldEvent) => {
+ if (!this.isInputInFocus && this.enableDisplayBasedOnLocale) {
+ this.updateValue(ev.field.value);
+ } else if (!this.isInputInFocus) {
+ this.amountWidgetValue = ev.field.value;
+ }
+ });
+ }
+
+ updateValue(value: any): void {
+ this.valueAsNumber = value;
+ this.amountWidgetValue = this.currencyPipe.transform(value, this.currency, this.currencyDisplay, this.decimalProperty, this.locale);
+ }
+
+ updateSettingsBasedProperties(data: AmountWidgetSettings): void {
+ this.enableDisplayBasedOnLocale = data?.enableDisplayBasedOnLocale ?? false;
+ this.showReadonlyPlaceholder = data?.showReadonlyPlaceholder;
+ }
}
diff --git a/lib/core/src/lib/mock/translation.service.mock.ts b/lib/core/src/lib/mock/translation.service.mock.ts
index 5f3c0f219e..011d898bc3 100644
--- a/lib/core/src/lib/mock/translation.service.mock.ts
+++ b/lib/core/src/lib/mock/translation.service.mock.ts
@@ -47,6 +47,8 @@ export class TranslationMock implements TranslationService {
return of(key);
}
+ getLocale(): any {}
+
instant(key: string | Array): string | any {
return key;
}
diff --git a/lib/core/src/lib/testing/noop-translate.module.ts b/lib/core/src/lib/testing/noop-translate.module.ts
index bd906c7bd8..0e5f7a0196 100644
--- a/lib/core/src/lib/testing/noop-translate.module.ts
+++ b/lib/core/src/lib/testing/noop-translate.module.ts
@@ -41,6 +41,8 @@ export class NoopTranslationService implements TranslationService {
return of(key);
}
+ getLocale(): any {}
+
instant(key: string | Array): string | any {
return key;
}
diff --git a/lib/core/src/lib/translation/translation.service.spec.ts b/lib/core/src/lib/translation/translation.service.spec.ts
index 587d8a9c1b..f89fd22e9a 100644
--- a/lib/core/src/lib/translation/translation.service.spec.ts
+++ b/lib/core/src/lib/translation/translation.service.spec.ts
@@ -83,4 +83,37 @@ describe('TranslationService', () => {
expect(translationService.instant('')).toEqual('');
expect(translationService.instant(undefined)).toEqual('');
});
+
+ describe('getLocale', () => {
+ it('returns the first language from navigator.languages when available', () => {
+ translationService.userLang = 'it';
+ const returnedLanguages: string[] = ['fr-FR', 'en-US'];
+ const mockLanguages = spyOnProperty(window, 'navigator').and.returnValue({
+ language: 'en-GB',
+ languages: returnedLanguages
+ } as any);
+
+ expect(translationService.getLocale()).toBe('fr-FR');
+ expect(mockLanguages).toHaveBeenCalled();
+ });
+
+ it('falls back to navigator.language when languages list is absent', () => {
+ translationService.userLang = 'fr';
+ const mockLanguages = spyOnProperty(window, 'navigator').and.returnValue({
+ language: 'de-DE',
+ languages: []
+ } as any);
+
+ expect(translationService.getLocale()).toBe('de-DE');
+ expect(mockLanguages).toHaveBeenCalled();
+ });
+
+ it('falls back to the provided default locale when navigator is unavailable', () => {
+ translationService.userLang = 'en';
+ const mockLanguages = spyOnProperty(window, 'navigator').and.returnValue(undefined);
+
+ expect(translationService.getLocale()).toBe('en');
+ expect(mockLanguages).toHaveBeenCalled();
+ });
+ });
});
diff --git a/lib/core/src/lib/translation/translation.service.ts b/lib/core/src/lib/translation/translation.service.ts
index 4713f3be4a..b2f2b88798 100644
--- a/lib/core/src/lib/translation/translation.service.ts
+++ b/lib/core/src/lib/translation/translation.service.ts
@@ -151,6 +151,22 @@ export class TranslationService {
return this.translate.get(key, interpolateParams);
}
+ /**
+ * Determines the preferred locale for the current user.
+ *
+ * @returns Locale identifier resolved from the browser or the default translation locale
+ */
+ getLocale(): string {
+ const defaultLocale = this.userLang || this.defaultLang;
+ if (typeof window?.navigator === 'undefined') {
+ return defaultLocale;
+ }
+ const wn = window.navigator as Navigator;
+ let lang = wn.languages ? wn.languages[0] : defaultLocale;
+ lang = lang || wn.language;
+ return lang;
+ }
+
/**
* Directly returns the translation for the supplied key.
*
diff --git a/lib/process-services-cloud/src/lib/form/services/form-cloud.service.ts b/lib/process-services-cloud/src/lib/form/services/form-cloud.service.ts
index dacb861699..f08dd3ca54 100644
--- a/lib/process-services-cloud/src/lib/form/services/form-cloud.service.ts
+++ b/lib/process-services-cloud/src/lib/form/services/form-cloud.service.ts
@@ -15,8 +15,8 @@
* limitations under the License.
*/
-import { Inject, Injectable, InjectionToken, Optional } from '@angular/core';
-import { FormValues, FormModel, FormFieldOption, FormFieldValidator } from '@alfresco/adf-core';
+import { inject, Inject, Injectable, InjectionToken, Optional } from '@angular/core';
+import { FormValues, FormModel, FormFieldOption, FormFieldValidator, FormService } from '@alfresco/adf-core';
import { Observable, from, EMPTY } from 'rxjs';
import { expand, map, reduce, switchMap } from 'rxjs/operators';
import { TaskDetailsCloudModel } from '../../task/models/task-details-cloud.model';
@@ -35,6 +35,7 @@ export const FORM_CLOUD_SERVICE_FIELD_VALIDATORS_TOKEN = new InjectionToken