diff --git a/src/app/translation/common-string-pipes.ts b/src/app/translation/common-string-pipes.ts
index e1177ee0..1787b362 100644
--- a/src/app/translation/common-string-pipes.ts
+++ b/src/app/translation/common-string-pipes.ts
@@ -13,10 +13,10 @@
* this program. If not, see .
*/
-import {DecimalPipe} from '@angular/common';
import {Injectable, OnDestroy, Pipe, PipeTransform} from '@angular/core';
import {LangChangeEvent, TranslateService} from '@ngx-translate/core';
import {Subscription} from 'rxjs';
+import {logger} from '../_helpers/ts-logger';
@Injectable()
@Pipe({
@@ -26,7 +26,7 @@ import {Subscription} from 'rxjs';
export class ArrayJoinPipe implements PipeTransform {
value = '';
- transform(anArray: unknown[], separator: string | unknown): unknown {
+ transform(anArray: unknown[] | unknown, separator: string | unknown): string {
if (typeof separator !== 'string' || separator.length <= 0) {
return this.value;
}
@@ -43,6 +43,27 @@ export class ArrayJoinPipe implements PipeTransform {
}
}
+@Injectable()
+@Pipe({
+ name: 'sentencecase',
+ pure: false, // required to update the value when the promise is resolved
+})
+export class SentenceCasePipe implements PipeTransform {
+ value = '';
+
+ transform(aString: string | unknown): string {
+
+ if (typeof aString !== 'string'){
+ throw new SyntaxError(`Wrong parameter in StringSplitPipe. Expected a valid String, received: ${aString}`);
+ }
+
+ this.value = aString.substr(0,1)
+ .toUpperCase() + aString.substr(1);
+
+ return this.value;
+ }
+}
+
@Injectable()
@Pipe({
name: 'split',
@@ -51,7 +72,7 @@ export class ArrayJoinPipe implements PipeTransform {
export class StringSplitPipe implements PipeTransform {
value = new Array();
- transform(aString: string | T, splitter: string | T): T {
+ transform(aString: string | unknown, splitter: string | unknown): unknown[] {
if (typeof splitter !== 'string' || splitter.length <= 0) {
return this.value as never;
}
@@ -74,21 +95,16 @@ export class StringSplitPipe implements PipeTransform {
pure: false, // required to update the value when the promise is resolved
})
export class NumberLocalizedPipe implements PipeTransform, OnDestroy {
- decimalPipe: DecimalPipe;
-
locale: string;
-
- onLangChange: Subscription;
-
- value: unknown;
+ onLangChange?: Subscription;
+ value: string;
constructor(private readonly translate: TranslateService) {
- this.decimalPipe = new DecimalPipe('de-DE');
this.locale = translate.currentLang;
}
private _dispose(): void {
- if (this.onLangChange?.closed) {
+ if (this.onLangChange?.closed === false) {
this.onLangChange?.unsubscribe();
}
}
@@ -98,33 +114,97 @@ export class NumberLocalizedPipe implements PipeTransform, OnDestroy {
}
/**
- * @param value The number to be formatted.
- * @param digitsInfo Decimal representation options, specified by a string
- * in the following format: {minIntegerDigits}.{minFractionDigits}-{maxFractionDigits}
- * - `minIntegerDigits`: The minimum number of integer digits before the decimal point.
- * Default is `1`.
- * - `minFractionDigits`: The minimum number of digits after the decimal point.
- * Default is `0`.
- * - `maxFractionDigits`: The maximum number of digits after the decimal point.
- * Default is `3`.
+ * @param value The number to be formatted
+ * @param formatOptions Formatting options to include.
+ * As specified by Intl.NumberFormatOptions as comma seperated key:value pairs.
*/
- transform(value: unknown, digitsInfo?: string | undefined): unknown {
- this.updateValue(value, digitsInfo);
+ transform(value: string | number | unknown, formatOptions?: string): string {
+ this.updateValue(value, formatOptions);
this._dispose();
- if (typeof this.onLangChange === 'undefined' || this.onLangChange.closed) {
- this.onLangChange = this.translate.onLangChange.subscribe(
- (event: LangChangeEvent) => {
- this.locale = event.lang;
- this.updateValue(value, digitsInfo);
- },
- );
+ if (this.onLangChange?.closed === true) {
+ this.onLangChange = this.translate.onLangChange.subscribe((event: LangChangeEvent) => {
+ this.locale = event.lang;
+ this.updateValue(value, formatOptions);
+ });
}
return this.value;
}
- updateValue(value: unknown, digitsInfo?: string | undefined): void {
- // this.value = this.locale;
- this.value = this.decimalPipe.transform(value, digitsInfo, this.locale);
+ updateValue(value: string | number | unknown, formatOptions?: string): void {
+ if (typeof value !== 'string' && typeof value !== 'number') {
+ logger.warn(`numberLocalized pipe unable to parse input: ${value}`);
+
+ return;
+ }
+ const options = formatOptions?.split(',')
+ .map((element) => element.split(':'))
+ .reduce((acc, [key, val]) => ({...acc, [key.trim()]: val.trim()}),{}) as Intl.NumberFormatOptions;
+ const float = typeof value === 'string' ? Number.parseFloat(value) : value as number;
+ this.value = new Intl.NumberFormat(this.locale, options).format(float);
+ }
+}
+
+@Injectable()
+@Pipe({
+ name: 'dateFormat',
+ pure: false, // required to update the value when the promise is resolved
+})
+export class DateLocalizedFormatPipe implements PipeTransform, OnDestroy {
+ locale: string;
+ onLangChange?: Subscription;
+ value: string;
+
+ constructor(private readonly translate: TranslateService) {
+ this.locale = translate.currentLang;
+ }
+
+ private _dispose(): void {
+ if (this.onLangChange?.closed === false) {
+ this.onLangChange?.unsubscribe();
+ }
+ }
+
+ ngOnDestroy(): void {
+ this._dispose();
+ }
+
+ /**
+ * @param value The date to be formatted
+ * @param formatOptions Dateformat options to include.
+ * As specified by Intl.DateTimeFormatOptions as comma seperated key:value pairs
+ * Default is year,month,day,hour and minute in numeric representation e.g. (en-US) "8/6/2021, 10:35"
+ */
+ transform(value: string | unknown, formatOptions?: string): string {
+ this.updateValue(value, formatOptions);
+ this._dispose();
+ if (this.onLangChange?.closed === true) {
+ this.onLangChange = this.translate.onLangChange.subscribe((event: LangChangeEvent) => {
+ this.locale = event.lang;
+ this.updateValue(value, formatOptions);
+ });
+ }
+
+ return this.value;
+ }
+
+ updateValue(value: string | Date | unknown, formatOptions?: string): void {
+ if (typeof value !== 'string' && Object.prototype.toString.call(value) !== '[object Date]') {
+ logger.warn(`dateFormat pipe unable to parse input: ${value}`);
+
+ return;
+ }
+ const options = formatOptions?.split(',')
+ .map((element) => element.split(':'))
+ .reduce((acc, [key, val]) => ({...acc, [key.trim()]: val.trim()}),{}) as Intl.DateTimeFormatOptions;
+ const date = typeof value === 'string' ? Date.parse(value) : value as Date;
+ this.value = new Intl.DateTimeFormat(this.locale, options ?? {
+ day: 'numeric',
+ month: 'numeric',
+ year: 'numeric',
+ hour: 'numeric',
+ minute: 'numeric',
+ })
+ .format(date);
}
}
diff --git a/src/app/translation/thing-translate.module.ts b/src/app/translation/thing-translate.module.ts
index e411c771..3434fe47 100644
--- a/src/app/translation/thing-translate.module.ts
+++ b/src/app/translation/thing-translate.module.ts
@@ -14,19 +14,9 @@
*/
import {ModuleWithProviders, NgModule, Provider} from '@angular/core';
-import {
- ArrayJoinPipe,
- NumberLocalizedPipe,
- StringSplitPipe,
-} from './common-string-pipes';
-import {
- ThingTranslateDefaultParser,
- ThingTranslateParser,
-} from './thing-translate.parser';
-import {
- ThingPropertyNameTranslatePipe,
- ThingTranslatePipe,
-} from './thing-translate.pipe';
+import {ArrayJoinPipe, DateLocalizedFormatPipe, NumberLocalizedPipe, SentenceCasePipe, StringSplitPipe} from './common-string-pipes';
+import {ThingTranslateDefaultParser, ThingTranslateParser} from './thing-translate.parser';
+import {ThingPropertyNameTranslatePipe, ThingTranslatePipe} from './thing-translate.pipe';
import {ThingTranslateService} from './thing-translate.service';
export interface ThingTranslateModuleConfig {
@@ -40,6 +30,8 @@ export interface ThingTranslateModuleConfig {
StringSplitPipe,
ThingPropertyNameTranslatePipe,
ThingTranslatePipe,
+ DateLocalizedFormatPipe,
+ SentenceCasePipe,
],
exports: [
ArrayJoinPipe,
@@ -47,6 +39,8 @@ export interface ThingTranslateModuleConfig {
StringSplitPipe,
ThingPropertyNameTranslatePipe,
ThingTranslatePipe,
+ DateLocalizedFormatPipe,
+ SentenceCasePipe,
],
})
export class ThingTranslateModule {