Browse Source

UI: Add MillisecondsToTimeStringPipe to widget context. Markdown widget: Add widget context argument to markdown text function.

pull/7991/head
Igor Kulikov 3 years ago
parent
commit
1ac8bd458d
  1. 2
      ui-ngx/src/app/modules/home/components/widget/dynamic-widget.component.ts
  2. 7
      ui-ngx/src/app/modules/home/components/widget/lib/markdown-widget.component.ts
  3. 2
      ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/markdown-widget-settings.component.html
  4. 2
      ui-ngx/src/app/modules/home/models/services.map.ts
  5. 3
      ui-ngx/src/app/modules/home/models/widget-component.models.ts
  6. 54
      ui-ngx/src/app/shared/pipe/milliseconds-to-time-string.pipe.ts
  7. 5
      ui-ngx/src/assets/help/en_US/widget/lib/markdown/markdown_text_fn.md
  8. 6
      ui-ngx/src/assets/locale/locale.constant-en_US.json

2
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);

7
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) {

2
ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/markdown-widget-settings.component.html

@ -22,7 +22,7 @@
<tb-js-func [fxShow]="markdownWidgetSettingsForm.get('useMarkdownTextFunction').value"
formControlName="markdownTextFunction"
[globalVariables]="functionScopeVariables"
[functionArgs]="['data']"
[functionArgs]="['data', 'ctx']"
functionTitle="{{ 'widgets.markdown.markdown-text-function' | translate }}"
helpId="widget/lib/markdown/markdown_text_fn">
</tb-js-func>

2
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<string, Type<any>>(
[
@ -57,6 +58,7 @@ export const ServicesMap = new Map<string, Type<any>>(
['dialogs', DialogService],
['customDialog', CustomDialogService],
['date', DatePipe],
['milliSecondsToTimeString', MillisecondsToTimeStringPipe],
['utils', UtilsService],
['translate', TranslateService],
['http', HttpClient],

3
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;

54
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;
}

5
ui-ngx/src/assets/help/en_US/widget/lib/markdown/markdown_text_fn.md

@ -3,7 +3,7 @@
<div class="divider"></div>
<br/>
*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.
<li><b>data:</b> <code><a href="https://github.com/thingsboard/thingsboard/blob/5bb6403407aa4898084832d6698aa9ea6d484889/ui-ngx/src/app/modules/home/components/widget/lib/maps/map-models.ts#L108" target="_blank">FormattedData[]</a></code> - An array of <a href="https://github.com/thingsboard/thingsboard/blob/5bb6403407aa4898084832d6698aa9ea6d484889/ui-ngx/src/app/modules/home/components/widget/lib/maps/map-models.ts#L108" target="_blank">FormattedData</a> objects resolved from configured datasources.<br/>
Each object represents basic entity properties (ex. <code>entityId</code>, <code>entityName</code>)<br/>and provides access to other entity attributes/timeseries declared in widget datasource configuration.
</li>
<li><b>ctx:</b> <code><a href="https://github.com/thingsboard/thingsboard/blob/5bb6403407aa4898084832d6698aa9ea6d484889/ui-ngx/src/app/modules/home/models/widget-component.models.ts#L107" target="_blank">WidgetContext</a></code> - A reference to <a href="https://github.com/thingsboard/thingsboard/blob/5bb6403407aa4898084832d6698aa9ea6d484889/ui-ngx/src/app/modules/home/models/widget-component.models.ts#L107" target="_blank">WidgetContext</a> that has all necessary API
and data used by widget instance.
</li>
</ul>
**Returns:**

6
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",

Loading…
Cancel
Save