diff --git a/demo-shell/resources/i18n/en.json b/demo-shell/resources/i18n/en.json index af6270f2e0..9fb603b5f9 100644 --- a/demo-shell/resources/i18n/en.json +++ b/demo-shell/resources/i18n/en.json @@ -78,7 +78,7 @@ "UPLOADER": "Uploader", "WEBSCRIPT": "Webscript", "TAG": "Tag", - "DATE": "Date", + "PIPES": "Pipes", "TRASHCAN": "Trashcan", "SOCIAL": "Social", "SETTINGS": "Settings", diff --git a/demo-shell/src/app.config.json b/demo-shell/src/app.config.json index b770b4ad60..3f86aad399 100644 --- a/demo-shell/src/app.config.json +++ b/demo-shell/src/app.config.json @@ -438,11 +438,16 @@ 20 ] }, - "dateValues":{ + "dateValues": { "defaultDateFormat": "mediumDate", "defaultDateTimeFormat": "MMM d, y, H:mm", "defaultLocale": "en" }, + "decimalValues": { + "minIntegerDigits": 1, + "minFractionDigits": 0, + "maxFractionDigits": 2 + }, "files": { "excluded": [ ".DS_Store", diff --git a/demo-shell/src/app/app.routes.ts b/demo-shell/src/app/app.routes.ts index 49381be768..188e58e1c9 100644 --- a/demo-shell/src/app/app.routes.ts +++ b/demo-shell/src/app/app.routes.ts @@ -127,11 +127,11 @@ export const appRoutes: Routes = [ ] }, { - path: 'date', + path: 'pipes', children: [ { path: '', - loadChildren: 'app/components/date/date.module#AppDateModule' + loadChildren: 'app/components/pipes/pipes.module#AppPipesModule' } ] }, diff --git a/demo-shell/src/app/components/app-layout/app-layout.component.ts b/demo-shell/src/app/components/app-layout/app-layout.component.ts index 80e5cbf1a2..84a3186de6 100644 --- a/demo-shell/src/app/components/app-layout/app-layout.component.ts +++ b/demo-shell/src/app/components/app-layout/app-layout.component.ts @@ -74,7 +74,7 @@ export class AppLayoutComponent implements OnInit, OnDestroy { { href: '/webscript', icon: 'extension', title: 'APP_LAYOUT.WEBSCRIPT' }, { href: '/tag', icon: 'local_offer', title: 'APP_LAYOUT.TAG' }, { href: '/social', icon: 'thumb_up', title: 'APP_LAYOUT.SOCIAL' }, - { href: '/date', icon: 'calendar_today', title: 'APP_LAYOUT.DATE' }, + { href: '/pipes', icon: 'layers', title: 'APP_LAYOUT.PIPES' }, { href: '/settings-layout', icon: 'settings', title: 'APP_LAYOUT.SETTINGS' }, { href: '/config-editor', icon: 'code', title: 'APP_LAYOUT.CONFIG-EDITOR' }, { href: '/extendedSearch', icon: 'search', title: 'APP_LAYOUT.SEARCH' }, diff --git a/demo-shell/src/app/components/card-view/card-view.component.ts b/demo-shell/src/app/components/card-view/card-view.component.ts index 66291c863c..fe85f5c65e 100644 --- a/demo-shell/src/app/components/card-view/card-view.component.ts +++ b/demo-shell/src/app/components/card-view/card-view.component.ts @@ -27,7 +27,8 @@ import { CardViewSelectItemModel, CardViewUpdateService, CardViewMapItemModel, - UpdateNotification + UpdateNotification, + DecimalNumberPipe } from '@alfresco/adf-core'; import { of, Subject } from 'rxjs'; import { takeUntil } from 'rxjs/operators'; @@ -46,7 +47,8 @@ export class CardViewComponent implements OnInit, OnDestroy { private onDestroy$ = new Subject(); - constructor(private cardViewUpdateService: CardViewUpdateService) { + constructor(private cardViewUpdateService: CardViewUpdateService, + private decimalNumberPipe: DecimalNumberPipe) { this.logs = []; this.createCard(); } @@ -112,7 +114,8 @@ export class CardViewComponent implements OnInit, OnDestroy { value: 9.9, key: 'float', default: 0.0, - editable: this.isEditable + editable: this.isEditable, + pipes: [{ pipe: this.decimalNumberPipe}] }), new CardViewKeyValuePairsItemModel({ label: 'CardView Key-Value Pairs Item', diff --git a/demo-shell/src/app/components/date/date.component.html b/demo-shell/src/app/components/date/date.component.html deleted file mode 100644 index a4821deb0f..0000000000 --- a/demo-shell/src/app/components/date/date.component.html +++ /dev/null @@ -1,32 +0,0 @@ -
-

Date Pipes

- - - - - - - - - {{language.label}} - - - - -

AdfLocalizedDate Pipe - Default

-
{{ today | adfLocalizedDate }}
-
-

AdfLocalizedDate Pipe - Custom format

-
{{ today | adfLocalizedDate : format }}
-
-

AdfLocalizedDate Pipe - Custom format and locale

-
{{ today | adfLocalizedDate : format : locale }}
-
-

AdfTimeAgo Pipe

-
{{ today | adfTimeAgo }}
-
-

AdfTimeAgo Pipe - Custom locale

-
{{ today | adfTimeAgo : locale}}
-
diff --git a/demo-shell/src/app/components/date/date.component.scss b/demo-shell/src/app/components/date/date.component.scss deleted file mode 100644 index 720ae78a4d..0000000000 --- a/demo-shell/src/app/components/date/date.component.scss +++ /dev/null @@ -1,7 +0,0 @@ -.adf-date-pipes-container { - padding: 20px; -} - -.adf-date-field { - margin: 20px; -} diff --git a/demo-shell/src/app/components/pipes/pipes.component.html b/demo-shell/src/app/components/pipes/pipes.component.html new file mode 100644 index 0000000000..9018e2d5a9 --- /dev/null +++ b/demo-shell/src/app/components/pipes/pipes.component.html @@ -0,0 +1,109 @@ +

ADF Pipes

+ + + + + + Localized dates + + + adfLocalizedDate + + + + + + + + + + + {{language.label}} + + + + +

AdfLocalizedDate Pipe - Default

+
{{ today | adfLocalizedDate }}
+
+

AdfLocalizedDate Pipe - Custom format

+
{{ today | adfLocalizedDate : format }}
+
+

AdfLocalizedDate Pipe - Custom format and locale

+
{{ today | adfLocalizedDate : format : locale }}
+
+ + + + + Time ago + + + adfTimeAgo + + + + + + + + + + + {{language.label}} + + + +

AdfTimeAgo Pipe - Default

+
{{ today | adfTimeAgo }}
+
+

AdfTimeAgo Pipe - Custom locale

+
{{ today | adfTimeAgo : locale}}
+
+ + + + + Decimal numbers + + + adfDecimalNumber + + + + + + + + + + + + + + + + + + + + {{language.label}} + + + + +

AdfDecimalNumber Pipe - Default

+
{{ number | adfDecimalNumber }}
+
+

AdfDecimalNumber Pipe - Custom digits config

+
{{ number | adfDecimalNumber : decimalValues }}
+
+

AdfDecimalNumber Pipe - Custom locale

+
{{ number | adfDecimalNumber : {} : locale }}
+
+

AdfDecimalNumber Pipe - Custom digits config and locale

+
{{ number | adfDecimalNumber : decimalValues : locale }}
+
+ +
+
diff --git a/demo-shell/src/app/components/pipes/pipes.component.scss b/demo-shell/src/app/components/pipes/pipes.component.scss new file mode 100644 index 0000000000..9ed9b6f6a6 --- /dev/null +++ b/demo-shell/src/app/components/pipes/pipes.component.scss @@ -0,0 +1,7 @@ +h2 { + padding: 20px; +} + +.adf-input-field { + margin: 20px; +} diff --git a/demo-shell/src/app/components/date/date.component.ts b/demo-shell/src/app/components/pipes/pipes.component.ts similarity index 75% rename from demo-shell/src/app/components/date/date.component.ts rename to demo-shell/src/app/components/pipes/pipes.component.ts index 372621d1d6..5d10e99419 100644 --- a/demo-shell/src/app/components/date/date.component.ts +++ b/demo-shell/src/app/components/pipes/pipes.component.ts @@ -19,15 +19,21 @@ import { Component } from '@angular/core'; import { AppConfigService } from '@alfresco/adf-core'; @Component({ - selector: 'app-date-page', - templateUrl: './date.component.html', - styleUrls: ['date.component.scss'] + selector: 'app-pipes-page', + templateUrl: './pipes.component.html', + styleUrls: ['pipes.component.scss'] }) -export class DateComponent { +export class PipesComponent { today = new Date(); locale: string; format: string; + number = 12345.56; + decimalValues = { + minIntegerDigits: undefined, + minFractionDigits: undefined, + maxFractionDigits: undefined + }; languages: any[]; constructor(private appConfig: AppConfigService) { diff --git a/demo-shell/src/app/components/date/date.module.ts b/demo-shell/src/app/components/pipes/pipes.module.ts similarity index 86% rename from demo-shell/src/app/components/date/date.module.ts rename to demo-shell/src/app/components/pipes/pipes.module.ts index 84d757f2d4..38d2822b4d 100644 --- a/demo-shell/src/app/components/date/date.module.ts +++ b/demo-shell/src/app/components/pipes/pipes.module.ts @@ -17,14 +17,14 @@ import { NgModule } from '@angular/core'; import { Routes, RouterModule } from '@angular/router'; -import { DateComponent } from './date.component'; +import { PipesComponent } from './pipes.component'; import { CommonModule } from '@angular/common'; import { CoreModule } from '@alfresco/adf-core'; const routes: Routes = [ { path: '', - component: DateComponent + component: PipesComponent } ]; @@ -34,6 +34,6 @@ const routes: Routes = [ CoreModule.forChild(), RouterModule.forChild(routes) ], - declarations: [DateComponent] + declarations: [PipesComponent] }) -export class AppDateModule {} +export class AppPipesModule {} diff --git a/docs/core/pipes/decimal-number.pipe.md b/docs/core/pipes/decimal-number.pipe.md new file mode 100644 index 0000000000..326f29ccfc --- /dev/null +++ b/docs/core/pipes/decimal-number.pipe.md @@ -0,0 +1,53 @@ +# [Decimal Number Pipe](../../../lib/core/pipes/decimal-number.pipe.ts "Defined in multi-value.pipe.ts") + +Transforms a number to have a certain amount of digits in its integer part and also in its decimal part. + +## Basic Usage + +### Properties + +| Name | Type | Default value | Description | +| ---------- | ---------------------------------------------------------------------- | ------------- | ----------------------------------------------------------------------------------------------------------------------- | +| digitsInfo | [DecimalNumberModel](../../../lib/core/models/decimal-number.model.ts) | | A format to apply to the date value. [Date Pipe Formats.](https://angular.io/api/common/DatePipe#custom-format-options) | +| locale | string | 'en-US' | A locale id for the locale format rules to use. | + +## Details + +This pipe transforms a given number so it follows the set configuration for the pipe. You can change this configuration by changing the parameters in your `app.config.json`. + +```json +"decimalValues": { + "minIntegerDigits": 1, + "minFractionDigits": 0, + "maxFractionDigits": 2 + } +``` + +You can also overwrite this config by passing a [DecimalNumberModel](../../../lib/core/models/decimal-number.model.ts) as an argument for this pipe. + +The number can be also localized so it applies commas and dots in the right place depending on the locale id in use. + +#### Result + +```ts +decimalNumberPipe.transform(1234.567); +//Returns '1,234.57' + +decimalNumberPipe.transform(1234.567, digitsConfig, "it"); +//Returns '1.234,57' +``` + +And now with a different config: + +```ts +digitsConfig = { + minIntegerDigits: 6, + minFractionDigits: 4, + maxFractionDigits: 4 +}; + +decimalNumberPipe.transform(1234.567, digitsConfig); +//Returns '001,234.5670' +``` + +More info: [Angular DecimalPipe](https://angular.io/api/common/DecimalPipe) diff --git a/docs/user-guide/localization.md b/docs/user-guide/localization.md index 6a7de86da1..31e1c44aa1 100644 --- a/docs/user-guide/localization.md +++ b/docs/user-guide/localization.md @@ -10,6 +10,7 @@ Dates are not written the same around the world. That is where localizing a date - [Adding language support](#adding-language-support) - [Using the localized date pipe](#using-the-localized-date-pipe) - [Using the time ago pipe](#using-the-time-ago-pipe) +- [Using the decimal number pipe](#using-the-decimal-number-pipe) ## Setting up the configuration in your app @@ -71,4 +72,19 @@ Converts a recent past date into a number of days ago. Usage of the [time ago pipe](../core/pipes/time-ago.pipe.md). +## Using the decimal number pipe + +Localizes the punctuation marks of a given number. + + + + {{ number | adfDecimalNumber }} + + +`Input:` 1999.12 +`Output (english locale):` 1,999.12 +`Output (italian locale):` 1.999,12 + +Usage of the [decimal number pipe](../core/pipes/decimal-number.pipe.md). + Find more info about localization in the [Angular Docs](https://angular.io/guide/i18n#setting-up-the-locale-of-your-app). diff --git a/lib/content-services/content-metadata/services/property-groups-translator.service.ts b/lib/content-services/content-metadata/services/property-groups-translator.service.ts index 5ec97325fe..59730612d0 100644 --- a/lib/content-services/content-metadata/services/property-groups-translator.service.ts +++ b/lib/content-services/content-metadata/services/property-groups-translator.service.ts @@ -27,7 +27,8 @@ import { CardViewFloatItemModel, LogService, MultiValuePipe, - AppConfigService + AppConfigService, + DecimalNumberPipe } from '@alfresco/adf-core'; import { Property, CardViewGroup, OrganisedPropertyGroup } from '../interfaces/content-metadata.interfaces'; @@ -52,6 +53,7 @@ export class PropertyGroupTranslatorService { constructor(private logService: LogService, private multiValuePipe: MultiValuePipe, + private decimalNumberPipe: DecimalNumberPipe, private appConfig: AppConfigService) { this.valueSeparator = this.appConfig.get('content-metadata.multi-value-pipe-separator'); } @@ -104,7 +106,9 @@ export class PropertyGroupTranslatorService { case D_FLOAT: case D_DOUBLE: - cardViewItemProperty = new CardViewFloatItemModel(propertyDefinition); + cardViewItemProperty = new CardViewFloatItemModel(Object.assign(propertyDefinition, { + pipes: [{ pipe: this.decimalNumberPipe }] + })); break; case D_DATE: diff --git a/lib/core/app-config/schema.json b/lib/core/app-config/schema.json index 25f30c6455..c2ffdb7912 100644 --- a/lib/core/app-config/schema.json +++ b/lib/core/app-config/schema.json @@ -541,6 +541,29 @@ } } }, + "decimalValues": { + "description": "Configuration of date formats in the app", + "type": "object", + "required": [ + "minIntegerDigits", + "minFractionDigits", + "maxFractionDigits" + ], + "properties": { + "minIntegerDigits": { + "description": "Minimum integer digits in number", + "type": "number" + }, + "minFractionDigits": { + "description": "Minimum decimal digits in number", + "type": "number" + }, + "maxFractionDigits": { + "description": "Maximum decimal digits in number", + "type": "number" + } + } + }, "files": { "description": "Configuration of rules applied to file upload", "type": "object", diff --git a/lib/core/card-view/models/card-view-floatitem.model.ts b/lib/core/card-view/models/card-view-floatitem.model.ts index f8fa97de63..0a99f61f23 100644 --- a/lib/core/card-view/models/card-view-floatitem.model.ts +++ b/lib/core/card-view/models/card-view-floatitem.model.ts @@ -19,7 +19,7 @@ import { CardViewItem } from '../interfaces/card-view-item.interface'; import { DynamicComponentModel } from '../../services/dynamic-component-mapper.service'; import { CardViewTextItemModel } from './card-view-textitem.model'; import { CardViewTextItemProperties } from '../interfaces/card-view.interfaces'; -import { CardViewItemFloatValidator } from '..//validators/card-view.validators'; +import { CardViewItemFloatValidator } from '../validators/card-view.validators'; export class CardViewFloatItemModel extends CardViewTextItemModel implements CardViewItem, DynamicComponentModel { type: string = 'float'; diff --git a/lib/core/form/components/widgets/number/number.widget.html b/lib/core/form/components/widgets/number/number.widget.html index 5cebd88816..27e5075f08 100644 --- a/lib/core/form/components/widgets/number/number.widget.html +++ b/lib/core/form/components/widgets/number/number.widget.html @@ -8,7 +8,7 @@ pattern="-?[0-9]*(\.[0-9]+)?" [id]="field.id" [required]="isRequired()" - [value]="field.value" + [value]="displayValue" [(ngModel)]="field.value" (ngModelChange)="onFieldChanged(field)" [disabled]="field.readOnly" diff --git a/lib/core/form/components/widgets/number/number.widget.spec.ts b/lib/core/form/components/widgets/number/number.widget.spec.ts index 076a584c75..b3a0698d3f 100644 --- a/lib/core/form/components/widgets/number/number.widget.spec.ts +++ b/lib/core/form/components/widgets/number/number.widget.spec.ts @@ -22,7 +22,7 @@ describe('NumberWidgetComponent', () => { let widget: NumberWidgetComponent; beforeEach(() => { - widget = new NumberWidgetComponent(null); + widget = new NumberWidgetComponent(null, null); }); it('should exist', () => { diff --git a/lib/core/form/components/widgets/number/number.widget.ts b/lib/core/form/components/widgets/number/number.widget.ts index 8d6cc82d56..c6493d6e38 100644 --- a/lib/core/form/components/widgets/number/number.widget.ts +++ b/lib/core/form/components/widgets/number/number.widget.ts @@ -17,9 +17,10 @@ /* tslint:disable:component-selector no-input-rename */ -import { Component, ViewEncapsulation } from '@angular/core'; +import { Component, ViewEncapsulation, OnInit } from '@angular/core'; import { FormService } from './../../../services/form.service'; import { baseHost , WidgetComponent } from './../widget.component'; +import { DecimalNumberPipe } from '../../../../pipes/decimal-number.pipe'; @Component({ selector: 'number-widget', @@ -28,10 +29,21 @@ import { baseHost , WidgetComponent } from './../widget.component'; host: baseHost, encapsulation: ViewEncapsulation.None }) -export class NumberWidgetComponent extends WidgetComponent { +export class NumberWidgetComponent extends WidgetComponent implements OnInit { - constructor(public formService: FormService) { + displayValue: number; + + constructor(public formService: FormService, + private decimalNumberPipe: DecimalNumberPipe) { super(formService); } + ngOnInit() { + if (this.field.readOnly) { + this.displayValue = this.decimalNumberPipe.transform(this.field.value); + } else { + this.displayValue = this.field.value; + } + } + } diff --git a/lib/core/models/decimal-number.model.ts b/lib/core/models/decimal-number.model.ts new file mode 100644 index 0000000000..6ffc9889f3 --- /dev/null +++ b/lib/core/models/decimal-number.model.ts @@ -0,0 +1,30 @@ +/*! + * @license + * Copyright 2019 Alfresco Software, Ltd. + * + * 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. + */ + +export class DecimalNumberModel { + minIntegerDigits: number; + minFractionDigits: number; + maxFractionDigits: number; + + constructor(obj?: any) { + if (obj) { + this.minIntegerDigits = obj.minIntegerDigits; + this.minFractionDigits = obj.minFractionDigits; + this.maxFractionDigits = obj.maxFractionDigits; + } + } +} diff --git a/lib/core/models/public-api.ts b/lib/core/models/public-api.ts index 4805bf3ea1..8df9e6af25 100644 --- a/lib/core/models/public-api.ts +++ b/lib/core/models/public-api.ts @@ -27,3 +27,4 @@ export * from './pagination.model'; export * from './oauth-config.model'; export * from './request-pagination.model'; export * from './notification.model'; +export * from './decimal-number.model'; diff --git a/lib/core/pipes/decimal-number.pipe.spec.ts b/lib/core/pipes/decimal-number.pipe.spec.ts new file mode 100644 index 0000000000..03d1e62772 --- /dev/null +++ b/lib/core/pipes/decimal-number.pipe.spec.ts @@ -0,0 +1,74 @@ +/*! + * @license + * Copyright 2019 Alfresco Software, Ltd. + * + * 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 { async, TestBed } from '@angular/core/testing'; +import { AppConfigService } from '../app-config/app-config.service'; +import { UserPreferencesService } from '../services/user-preferences.service'; +import { of } from 'rxjs'; +import { setupTestBed } from '../testing/setupTestBed'; +import { CoreTestingModule } from '../testing/core.testing.module'; +import { DecimalNumberPipe } from './decimal-number.pipe'; + +describe('DecimalNumberPipe', () => { + + let pipe: DecimalNumberPipe; + let userPreferences: UserPreferencesService; + + setupTestBed({ + imports: [CoreTestingModule] + }); + + beforeEach(async(() => { + userPreferences = TestBed.get(UserPreferencesService); + spyOn(userPreferences, 'select').and.returnValue(of('')); + pipe = new DecimalNumberPipe(userPreferences, new AppConfigService(null)); + })); + + it('should return number localized and rounded following the default config', () => { + expect(pipe.transform(1234.567)).toBe('1,234.57'); + }); + + it('should return number with at least the minimum of digints in the integer part', () => { + const decimalValues = { + minIntegerDigits: 6, + minFractionDigits: undefined, + maxFractionDigits: undefined + }; + + expect(pipe.transform(1234.567, decimalValues)).toBe('001,234.57'); + }); + + it('should return number with at least the minimum of digints in the integer part', () => { + const decimalValues = { + minIntegerDigits: undefined, + minFractionDigits: 4, + maxFractionDigits: 10 + }; + + expect(pipe.transform(1234.567, decimalValues)).toBe('1,234.5670'); + }); + + it('should return number with at least the minimum of digints in the integer part', () => { + const decimalValues = { + minIntegerDigits: undefined, + minFractionDigits: 0, + maxFractionDigits: 1 + }; + + expect(pipe.transform(1234.567, decimalValues)).toBe('1,234.6'); + }); +}); diff --git a/lib/core/pipes/decimal-number.pipe.ts b/lib/core/pipes/decimal-number.pipe.ts new file mode 100644 index 0000000000..f50b7a04de --- /dev/null +++ b/lib/core/pipes/decimal-number.pipe.ts @@ -0,0 +1,82 @@ +/*! + * @license + * Copyright 2019 Alfresco Software, Ltd. + * + * 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 { DecimalPipe } from '@angular/common'; +import { Pipe, PipeTransform, OnDestroy } from '@angular/core'; +import { AppConfigService } from '../app-config/app-config.service'; +import { UserPreferencesService, UserPreferenceValues } from '../services/user-preferences.service'; +import { DecimalNumberModel } from '../models/decimal-number.model'; +import { Subject } from 'rxjs'; +import { takeUntil } from 'rxjs/operators'; + +@Pipe({ + name: 'adfDecimalNumber', + pure: false +}) +export class DecimalNumberPipe implements PipeTransform, OnDestroy { + + static DEFAULT_LOCALE = 'en-US'; + static DEFAULT_MIN_INTEGER_DIGITS = 1; + 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; + + onDestroy$: Subject = new Subject(); + + 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; + } + }); + } + + if (this.appConfig) { + this.defaultMinIntegerDigits = this.appConfig.get('decimalValues.minIntegerDigits', DecimalNumberPipe.DEFAULT_MIN_INTEGER_DIGITS); + this.defaultMinFractionDigits = this.appConfig.get('decimalValues.minFractionDigits', DecimalNumberPipe.DEFAULT_MIN_FRACTION_DIGITS); + this.defaultMaxFractionDigits = this.appConfig.get('decimalValues.maxFractionDigits', DecimalNumberPipe.DEFAULT_MAX_FRACTION_DIGITS); + } + } + + transform(value: any, digitsInfo?: DecimalNumberModel, locale?: string): any { + const actualMinIntegerDigits: number = digitsInfo && digitsInfo.minIntegerDigits ? digitsInfo.minIntegerDigits : this.defaultMinIntegerDigits; + const actualMinFractionDigits: number = digitsInfo && digitsInfo.minFractionDigits ? digitsInfo.minFractionDigits : this.defaultMinFractionDigits; + const actualMaxFractionDigits: number = digitsInfo && digitsInfo.maxFractionDigits ? digitsInfo.maxFractionDigits : this.defaultMaxFractionDigits; + + const actualDigitsInfo = `${actualMinIntegerDigits}.${actualMinFractionDigits}-${actualMaxFractionDigits}`; + const actualLocale = locale || this.defaultLocale; + + const datePipe: DecimalPipe = new DecimalPipe(actualLocale); + return datePipe.transform(value, actualDigitsInfo); + } + + ngOnDestroy(): void { + this.onDestroy$.next(true); + this.onDestroy$.complete(); + } +} diff --git a/lib/core/pipes/pipe.module.ts b/lib/core/pipes/pipe.module.ts index 1be5b82b03..7bbe49eaed 100644 --- a/lib/core/pipes/pipe.module.ts +++ b/lib/core/pipes/pipe.module.ts @@ -29,6 +29,7 @@ import { FormatSpacePipe } from './format-space.pipe'; import { FileTypePipe } from './file-type.pipe'; import { MultiValuePipe } from './multi-value.pipe'; import { LocalizedDatePipe } from './localized-date.pipe'; +import { DecimalNumberPipe } from './decimal-number.pipe'; @NgModule({ imports: [ @@ -45,7 +46,8 @@ import { LocalizedDatePipe } from './localized-date.pipe'; FormatSpacePipe, FileTypePipe, MultiValuePipe, - LocalizedDatePipe + LocalizedDatePipe, + DecimalNumberPipe ], providers: [ FileSizePipe, @@ -57,7 +59,8 @@ import { LocalizedDatePipe } from './localized-date.pipe'; FormatSpacePipe, FileTypePipe, MultiValuePipe, - LocalizedDatePipe + LocalizedDatePipe, + DecimalNumberPipe ], exports: [ FileSizePipe, @@ -70,7 +73,8 @@ import { LocalizedDatePipe } from './localized-date.pipe'; FormatSpacePipe, FileTypePipe, MultiValuePipe, - LocalizedDatePipe + LocalizedDatePipe, + DecimalNumberPipe ] }) export class PipeModule { diff --git a/lib/core/pipes/public-api.ts b/lib/core/pipes/public-api.ts index 5e9f16d9de..3b86da84b0 100644 --- a/lib/core/pipes/public-api.ts +++ b/lib/core/pipes/public-api.ts @@ -24,5 +24,6 @@ export * from './user-initial.pipe'; export * from './full-name.pipe'; export * from './multi-value.pipe'; export * from './localized-date.pipe'; +export * from './decimal-number.pipe'; export * from './pipe.module';