diff --git a/ui-ngx/src/app/modules/home/components/widget/dynamic-widget.component.ts b/ui-ngx/src/app/modules/home/components/widget/dynamic-widget.component.ts index 040e27b2ff..8bd881f38f 100644 --- a/ui-ngx/src/app/modules/home/components/widget/dynamic-widget.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/dynamic-widget.component.ts @@ -46,6 +46,7 @@ import { TranslateService } from '@ngx-translate/core'; import { DomSanitizer } from '@angular/platform-browser'; import { Router } from '@angular/router'; import { TbInject } from '@shared/decorators/tb-inject'; +import { MillisecondsToTimeStringPipe } from '@shared/pipe/milliseconds-to-time-string.pipe'; @Directive() // tslint:disable-next-line:directive-class-suffix @@ -83,6 +84,7 @@ export class DynamicWidgetComponent extends PageComponent implements IDynamicWid this.ctx.resourceService = $injector.get(ResourceService); this.ctx.telemetryWsService = $injector.get(TelemetryWebsocketService); this.ctx.date = $injector.get(DatePipe); + this.ctx.milliSecondsToTimeString = $injector.get(MillisecondsToTimeStringPipe); this.ctx.translate = $injector.get(TranslateService); this.ctx.http = $injector.get(HttpClient); this.ctx.sanitizer = $injector.get(DomSanitizer); diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/markdown-widget.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/markdown-widget.component.ts index d76e43d765..07c4555937 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/markdown-widget.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/markdown-widget.component.ts @@ -42,7 +42,7 @@ interface MarkdownWidgetSettings { markdownCss: string; } -type MarkdownTextFunction = (data: FormattedData[]) => string; +type MarkdownTextFunction = (data: FormattedData[], ctx: WidgetContext) => string; @Component({ selector: 'tb-markdown-widget ', @@ -72,7 +72,8 @@ export class MarkdownWidgetComponent extends PageComponent implements OnInit { ngOnInit(): void { this.ctx.$scope.markdownWidget = this; this.settings = this.ctx.settings; - this.markdownTextFunction = this.settings.useMarkdownTextFunction ? parseFunction(this.settings.markdownTextFunction, ['data']) : null; + this.markdownTextFunction = this.settings.useMarkdownTextFunction ? + parseFunction(this.settings.markdownTextFunction, ['data', 'ctx']) : null; this.markdownClass = 'markdown-widget'; const cssString = this.settings.markdownCss; if (isNotEmptyStr(cssString)) { @@ -117,7 +118,7 @@ export class MarkdownWidgetComponent extends PageComponent implements OnInit { } const data = formattedDataFormDatasourceData(initialData); let markdownText = this.settings.useMarkdownTextFunction ? - safeExecute(this.markdownTextFunction, [data]) : this.settings.markdownTextPattern; + safeExecute(this.markdownTextFunction, [data, this.ctx]) : this.settings.markdownTextPattern; const allData: FormattedData = flatDataWithoutOverride(data); markdownText = createLabelFromPattern(markdownText, allData); if (this.markdownText !== markdownText) { diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/markdown-widget-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/markdown-widget-settings.component.html index 040e470be1..06a419542b 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/markdown-widget-settings.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/markdown-widget-settings.component.html @@ -22,7 +22,7 @@ diff --git a/ui-ngx/src/app/modules/home/models/services.map.ts b/ui-ngx/src/app/modules/home/models/services.map.ts index 7514e972b5..f8c4390611 100644 --- a/ui-ngx/src/app/modules/home/models/services.map.ts +++ b/ui-ngx/src/app/modules/home/models/services.map.ts @@ -40,6 +40,7 @@ import { AuthService } from '@core/auth/auth.service'; import { ResourceService } from '@core/http/resource.service'; import { TwoFactorAuthenticationService } from '@core/http/two-factor-authentication.service'; import { TelemetryWebsocketService } from '@core/ws/telemetry-websocket.service'; +import { MillisecondsToTimeStringPipe } from '@shared/pipe/milliseconds-to-time-string.pipe'; export const ServicesMap = new Map>( [ @@ -57,6 +58,7 @@ export const ServicesMap = new Map>( ['dialogs', DialogService], ['customDialog', CustomDialogService], ['date', DatePipe], + ['milliSecondsToTimeString', MillisecondsToTimeStringPipe], ['utils', UtilsService], ['translate', TranslateService], ['http', HttpClient], diff --git a/ui-ngx/src/app/modules/home/models/widget-component.models.ts b/ui-ngx/src/app/modules/home/models/widget-component.models.ts index 813b3b6927..41c7453fc6 100644 --- a/ui-ngx/src/app/modules/home/models/widget-component.models.ts +++ b/ui-ngx/src/app/modules/home/models/widget-component.models.ts @@ -88,7 +88,7 @@ import * as RxJSOperators from 'rxjs/operators'; import { TbPopoverComponent } from '@shared/components/popover.component'; import { EntityId } from '@shared/models/id/entity-id'; import { AlarmQuery, AlarmSearchStatus, AlarmStatus} from '@app/shared/models/alarm.models'; -import { TelemetrySubscriber } from '@app/shared/public-api'; +import { MillisecondsToTimeStringPipe, TelemetrySubscriber } from '@app/shared/public-api'; export interface IWidgetAction { name: string; @@ -182,6 +182,7 @@ export class WidgetContext { telemetryWsService: TelemetryWebsocketService; telemetrySubscribers?: TelemetrySubscriber[]; date: DatePipe; + milliSecondsToTimeString: MillisecondsToTimeStringPipe; translate: TranslateService; http: HttpClient; sanitizer: DomSanitizer; diff --git a/ui-ngx/src/app/shared/pipe/milliseconds-to-time-string.pipe.ts b/ui-ngx/src/app/shared/pipe/milliseconds-to-time-string.pipe.ts index 6722f2f72e..d66513e057 100644 --- a/ui-ngx/src/app/shared/pipe/milliseconds-to-time-string.pipe.ts +++ b/ui-ngx/src/app/shared/pipe/milliseconds-to-time-string.pipe.ts @@ -25,33 +25,51 @@ export class MillisecondsToTimeStringPipe implements PipeTransform { constructor(private translate: TranslateService) { } - transform(millseconds: number, args?: any): string { + transform(millseconds: number, shortFormat = false): string { let seconds = Math.floor(millseconds / 1000); const days = Math.floor(seconds / 86400); let hours = Math.floor((seconds % 86400) / 3600); let minutes = Math.floor(((seconds % 86400) % 3600) / 60); seconds = seconds % 60; let timeString = ''; - if (days > 0) { - timeString += this.translate.instant('timewindow.days', {days}); - } - if (hours > 0) { - if (timeString.length === 0 && hours === 1) { - hours = 0; + if (shortFormat) { + if (days > 0) { + timeString += this.translate.instant('timewindow.short.days', {days}); } - timeString += this.translate.instant('timewindow.hours', {hours}); - } - if (minutes > 0) { - if (timeString.length === 0 && minutes === 1) { - minutes = 0; + if (hours > 0) { + timeString += this.translate.instant('timewindow.short.hours', {hours}); } - timeString += this.translate.instant('timewindow.minutes', {minutes}); - } - if (seconds > 0) { - if (timeString.length === 0 && seconds === 1) { - seconds = 0; + if (minutes > 0) { + timeString += this.translate.instant('timewindow.short.minutes', {minutes}); + } + if (seconds > 0) { + timeString += this.translate.instant('timewindow.short.seconds', {seconds}); + } + if (!timeString.length) { + timeString += this.translate.instant('timewindow.short.seconds', {seconds: 0}); + } + } else { + if (days > 0) { + timeString += this.translate.instant('timewindow.days', {days}); + } + if (hours > 0) { + if (timeString.length === 0 && hours === 1) { + hours = 0; + } + timeString += this.translate.instant('timewindow.hours', {hours}); + } + if (minutes > 0) { + if (timeString.length === 0 && minutes === 1) { + minutes = 0; + } + timeString += this.translate.instant('timewindow.minutes', {minutes}); + } + if (seconds > 0) { + if (timeString.length === 0 && seconds === 1) { + seconds = 0; + } + timeString += this.translate.instant('timewindow.seconds', {seconds}); } - timeString += this.translate.instant('timewindow.seconds', {seconds}); } return timeString; } diff --git a/ui-ngx/src/assets/help/en_US/widget/lib/markdown/markdown_text_fn.md b/ui-ngx/src/assets/help/en_US/widget/lib/markdown/markdown_text_fn.md index 9bbcb7fd7c..c11f412b6f 100644 --- a/ui-ngx/src/assets/help/en_US/widget/lib/markdown/markdown_text_fn.md +++ b/ui-ngx/src/assets/help/en_US/widget/lib/markdown/markdown_text_fn.md @@ -3,7 +3,7 @@

-*function (data): string* +*function (data, ctx): string* A JavaScript function used to calculate markdown or HTML content. @@ -13,6 +13,9 @@ A JavaScript function used to calculate markdown or HTML content.
  • data: FormattedData[] - An array of FormattedData objects resolved from configured datasources.
    Each object represents basic entity properties (ex. entityId, entityName)
    and provides access to other entity attributes/timeseries declared in widget datasource configuration.
  • +
  • ctx: WidgetContext - A reference to WidgetContext that has all necessary API + and data used by widget instance. +
  • **Returns:** diff --git a/ui-ngx/src/assets/locale/locale.constant-en_US.json b/ui-ngx/src/assets/locale/locale.constant-en_US.json index dd28154103..c7ce4f9211 100644 --- a/ui-ngx/src/assets/locale/locale.constant-en_US.json +++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json @@ -3379,6 +3379,12 @@ "hours": "{ hours, plural, 0 { hour } 1 {1 hour } other {# hours } }", "minutes": "{ minutes, plural, 0 { minute } 1 {1 minute } other {# minutes } }", "seconds": "{ seconds, plural, 0 { second } 1 {1 second } other {# seconds } }", + "short": { + "days": "{ days, plural, 1 {1 day } other {# days } }", + "hours": "{ hours, plural, 1 {1 hour } other {# hours } }", + "minutes": "{{minutes}} min ", + "seconds": "{{seconds}} sec " + }, "realtime": "Realtime", "history": "History", "last-prefix": "last",