Browse Source

UI: Improve flot line chart widget latest data key config. Improve toggle select component.

pull/8881/head
Igor Kulikov 3 years ago
parent
commit
425b52b91b
  1. 16
      ui-ngx/src/app/modules/home/components/dashboard-page/add-widget-dialog.component.html
  2. 16
      ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-page.component.html
  3. 6
      ui-ngx/src/app/modules/home/components/widget/config/data-key-config-dialog.component.html
  4. 17
      ui-ngx/src/app/modules/home/components/widget/config/datasources.component.html
  5. 11
      ui-ngx/src/app/modules/home/components/widget/config/timewindow-config-panel.component.html
  6. 19
      ui-ngx/src/app/modules/home/components/widget/lib/home-page/getting-started-widget.component.html
  7. 13
      ui-ngx/src/app/modules/home/components/widget/lib/home-page/recent-dashboards-widget.component.html
  8. 13
      ui-ngx/src/app/modules/home/components/widget/lib/home-page/usage-info-widget.component.html
  9. 2
      ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/label-widget-label.component.ts
  10. 43
      ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/flot-latest-key-settings.component.html
  11. 2
      ui-ngx/src/app/modules/home/components/widget/lib/settings/gauge/fixed-color-level.component.ts
  12. 2
      ui-ngx/src/app/modules/home/components/widget/lib/settings/gauge/gauge-highlight.component.ts
  13. 2
      ui-ngx/src/app/modules/home/components/widget/lib/settings/gauge/tick-value.component.ts
  14. 2
      ui-ngx/src/app/modules/home/components/widget/lib/settings/gpio/gpio-item.component.ts
  15. 2
      ui-ngx/src/app/modules/home/components/widget/lib/settings/input/datakey-select-option.component.ts
  16. 6
      ui-ngx/src/app/modules/home/components/widget/widget-config.component.html
  17. 4
      ui-ngx/src/app/modules/home/pages/home-links/tenant_admin_home_page.raw
  18. 88
      ui-ngx/src/app/shared/components/toggle-header.component.ts
  19. 1
      ui-ngx/src/app/shared/components/toggle-select.component.html
  20. 74
      ui-ngx/src/app/shared/components/toggle-select.component.ts
  21. 8
      ui-ngx/src/app/shared/shared.module.ts

16
ui-ngx/src/app/modules/home/components/dashboard-page/add-widget-dialog.component.html

@ -20,18 +20,10 @@
<h2 translate>widget.add</h2> <h2 translate>widget.add</h2>
<span fxFlex>: {{data.widgetInfo.widgetName}}</span> <span fxFlex>: {{data.widgetInfo.widgetName}}</span>
<div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="16px"> <div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="16px">
<tb-toggle-header *ngIf="hasBasicMode" (valueChange)="widgetConfigMode = $event" ignoreMdLgSize="true" <tb-toggle-select *ngIf="hasBasicMode" appearance="fill-invert" [(ngModel)]="widgetConfigMode" [ngModelOptions]="{standalone: true}">
appearance="fill-invert" [options]="[ <tb-toggle-option value="basic">{{ 'widget.basic-mode' | translate }}</tb-toggle-option>
{ <tb-toggle-option value="advanced">{{ 'widget.advanced-mode' | translate }}</tb-toggle-option>
name: translate.instant('widget.basic-mode'), </tb-toggle-select>
value: 'basic'
},
{
name: translate.instant('widget.advanced-mode'),
value: 'advanced'
}
]" [value]="widgetConfigMode" name="widgetConfigModeHeader" useSelectOnMdLg="false">
</tb-toggle-header>
<div [tb-help]="helpLinkIdForWidgetType()"></div> <div [tb-help]="helpLinkIdForWidgetType()"></div>
</div> </div>
<button mat-icon-button <button mat-icon-button

16
ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-page.component.html

@ -360,18 +360,10 @@
[isReadOnly]="true" [isReadOnly]="true"
(closeDetails)="onEditWidgetClosed()"> (closeDetails)="onEditWidgetClosed()">
<div class="details-buttons" fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="16px"> <div class="details-buttons" fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="16px">
<tb-toggle-header *ngIf="tbEditWidget.hasBasicMode" (valueChange)="tbEditWidget.widgetConfigMode = $event" ignoreMdLgSize="true" <tb-toggle-select *ngIf="tbEditWidget.hasBasicMode" appearance="fill-invert" [(ngModel)]="tbEditWidget.widgetConfigMode">
appearance="fill-invert" [options]="[ <tb-toggle-option value="basic">{{ 'widget.basic-mode' | translate }}</tb-toggle-option>
{ <tb-toggle-option value="advanced">{{ 'widget.advanced-mode' | translate }}</tb-toggle-option>
name: translate.instant('widget.basic-mode'), </tb-toggle-select>
value: 'basic'
},
{
name: translate.instant('widget.advanced-mode'),
value: 'advanced'
}
]" [value]="tbEditWidget.widgetConfigMode" name="widgetConfigModeHeader" useSelectOnMdLg="false">
</tb-toggle-header>
<div [tb-help]="helpLinkIdForWidgetType()"></div> <div [tb-help]="helpLinkIdForWidgetType()"></div>
</div> </div>
<tb-edit-widget #tbEditWidget <tb-edit-widget #tbEditWidget

6
ui-ngx/src/app/modules/home/components/widget/config/data-key-config-dialog.component.html

@ -19,10 +19,10 @@
<mat-toolbar color="primary"> <mat-toolbar color="primary">
<h2>{{ 'datakey.configuration' | translate }}</h2> <h2>{{ 'datakey.configuration' | translate }}</h2>
<span fxFlex></span> <span fxFlex></span>
<tb-toggle-header *ngIf="hasAdvanced" (valueChange)="dataKeyConfigMode = $event" ignoreMdLgSize="true" <tb-toggle-select *ngIf="hasAdvanced"
appearance="fill-invert" [options]="dataKeyConfigHeaderOptions" appearance="fill-invert" [options]="dataKeyConfigHeaderOptions"
[value]="dataKeyConfigMode" name="dataKeyConfigModeHeader" useSelectOnMdLg="false"> [(ngModel)]="dataKeyConfigMode" [ngModelOptions]="{ standalone: true }">
</tb-toggle-header> </tb-toggle-select>
<button mat-icon-button <button mat-icon-button
(click)="cancel()" (click)="cancel()"
type="button"> type="button">

17
ui-ngx/src/app/modules/home/components/widget/config/datasources.component.html

@ -22,18 +22,11 @@
<div fxFlex fxLayout="row" fxLayoutAlign="center center" *ngIf="timeseriesKeyError"> <div fxFlex fxLayout="row" fxLayoutAlign="center center" *ngIf="timeseriesKeyError">
<mat-error >{{ 'widget-config.timeseries-key-error' | translate }}</mat-error> <mat-error >{{ 'widget-config.timeseries-key-error' | translate }}</mat-error>
</div> </div>
<tb-toggle-header *ngIf="basicMode" (valueChange)="datasourcesModeChange($event)" ignoreMdLgSize="true" <tb-toggle-select *ngIf="basicMode" [ngModel]="datasourcesMode" (ngModelChange)="datasourcesModeChange($event)"
[options]="[ [ngModelOptions]="{ standalone: true }">
{ <tb-toggle-option [value]="datasourceType.device">{{ 'device.device' | translate }}</tb-toggle-option>
name: translate.instant('device.device'), <tb-toggle-option [value]="datasourceType.entity">{{ 'entity.entity-alias' | translate }}</tb-toggle-option>
value: datasourceType.device </tb-toggle-select>
},
{
name: translate.instant('entity.entity-alias'),
value: datasourceType.entity
}
]" [value]="datasourcesMode" name="widgetConfigModeHeader" useSelectOnMdLg="false">
</tb-toggle-header>
</div> </div>
<div *ngIf="maxDatasources > 1" <div *ngIf="maxDatasources > 1"
class="tb-widget-config-panel-hint">{{ 'widget-config.maximum-datasources' | translate:{count: maxDatasources} }}</div> class="tb-widget-config-panel-hint">{{ 'widget-config.maximum-datasources' | translate:{count: maxDatasources} }}</div>

11
ui-ngx/src/app/modules/home/components/widget/config/timewindow-config-panel.component.html

@ -18,13 +18,10 @@
<div [formGroup]="timewindowConfig" class="tb-widget-config-panel"> <div [formGroup]="timewindowConfig" class="tb-widget-config-panel">
<div fxLayout="row" fxLayoutAlign="space-between center"> <div fxLayout="row" fxLayoutAlign="space-between center">
<div class="tb-widget-config-panel-title" translate>timewindow.timewindow</div> <div class="tb-widget-config-panel-title" translate>timewindow.timewindow</div>
<tb-toggle-header (valueChange)="timewindowConfig.get('useDashboardTimewindow').patchValue($event)" ignoreMdLgSize="true" <tb-toggle-select formControlName="useDashboardTimewindow">
[options]="[ <tb-toggle-option [value]="true">{{ 'widget-config.use-dashboard-timewindow' | translate }}</tb-toggle-option>
{ name: translate.instant('widget-config.use-dashboard-timewindow'), value: true}, <tb-toggle-option [value]="false">{{ 'widget-config.use-widget-timewindow' | translate }}</tb-toggle-option>
{ name: translate.instant('widget-config.use-widget-timewindow'), value: false} </tb-toggle-select>
]"
[value]="timewindowConfig.get('useDashboardTimewindow').value" name="useDashboardTimewindow" useSelectOnMdLg="false">
</tb-toggle-header>
</div> </div>
<div class="tb-widget-config-row"> <div class="tb-widget-config-row">
<tb-timewindow asButton="true" <tb-timewindow asButton="true"

19
ui-ngx/src/app/modules/home/components/widget/lib/home-page/getting-started-widget.component.html

@ -111,21 +111,10 @@
</ng-template> </ng-template>
<div [innerHTML]="'widgets.getting-started.tenant-admin.step2.content-before' | translate | safe: 'html'"></div> <div [innerHTML]="'widgets.getting-started.tenant-admin.step2.content-before' | translate | safe: 'html'"></div>
<div class="tb-bordered-content"> <div class="tb-bordered-content">
<tb-toggle-header #publishCommandSteps value="ubuntu" name="publishCommandSteps" useSelectOnMdLg="false" <tb-toggle-header #publishCommandSteps value="ubuntu" name="publishCommandSteps" useSelectOnMdLg="false">
[options]="[ <tb-toggle-option value="ubuntu">Ubuntu</tb-toggle-option>
{ <tb-toggle-option value="macos">MacOS</tb-toggle-option>
name: 'Ubuntu', <tb-toggle-option value="windows">Windows</tb-toggle-option>
value: 'ubuntu'
},
{
name: 'MacOS',
value: 'macos'
},
{
name: 'Windows',
value: 'windows'
}
]">
</tb-toggle-header> </tb-toggle-header>
<ng-container [ngSwitch]="publishCommandSteps.value"> <ng-container [ngSwitch]="publishCommandSteps.value">
<ng-template [ngSwitchCase]="'ubuntu'"> <ng-template [ngSwitchCase]="'ubuntu'">

13
ui-ngx/src/app/modules/home/components/widget/lib/home-page/recent-dashboards-widget.component.html

@ -20,16 +20,9 @@
<div class="tb-card-header"> <div class="tb-card-header">
<a class="tb-title-link" routerLink="/dashboards">{{ 'widgets.recent-dashboards.title' | translate }}</a> <a class="tb-title-link" routerLink="/dashboards">{{ 'widgets.recent-dashboards.title' | translate }}</a>
<div fxLayout="row" fxLayoutAlign="start center" fxLayoutAlign.lt-md="space-between center" fxLayoutGap="8px"> <div fxLayout="row" fxLayoutAlign="start center" fxLayoutAlign.lt-md="space-between center" fxLayoutGap="8px">
<tb-toggle-header #dashboardsToggle [value]="toggleValue" name="usageToggle" (valueChange)="toggleValueChange($event)" [options]="[ <tb-toggle-header #dashboardsToggle [value]="toggleValue" name="usageToggle" (valueChange)="toggleValueChange($event)">
{ <tb-toggle-option value="last">{{ 'widgets.recent-dashboards.last' | translate }}</tb-toggle-option>
name: ctx.translate.instant('widgets.recent-dashboards.last'), <tb-toggle-option value="starred">{{ 'widgets.recent-dashboards.starred' | translate }}</tb-toggle-option>
value: 'last'
},
{
name: ctx.translate.instant('widgets.recent-dashboards.starred'),
value: 'starred'
}
]">
</tb-toggle-header> </tb-toggle-header>
<a *ngIf="authUser.authority === authority.TENANT_ADMIN" fxHide.md <a *ngIf="authUser.authority === authority.TENANT_ADMIN" fxHide.md
mat-flat-button color="primary" routerLink="/dashboards" [queryParams]="{action: 'add'}">{{ 'dashboard.add' | translate }}</a> mat-flat-button color="primary" routerLink="/dashboards" [queryParams]="{action: 'add'}">{{ 'dashboard.add' | translate }}</a>

13
ui-ngx/src/app/modules/home/components/widget/lib/home-page/usage-info-widget.component.html

@ -19,16 +19,9 @@
<ng-container *ngIf="hasUsageInfoAccess; else noDataAvailable"> <ng-container *ngIf="hasUsageInfoAccess; else noDataAvailable">
<div class="tb-card-header"> <div class="tb-card-header">
<a class="tb-title-link" routerLink="/usage">{{ 'widgets.usage-info.title' | translate }}</a> <a class="tb-title-link" routerLink="/usage">{{ 'widgets.usage-info.title' | translate }}</a>
<tb-toggle-header #usageToggle [value]="toggleValue" name="usageToggle" [options]="[ <tb-toggle-header #usageToggle [value]="toggleValue" name="usageToggle">
{ <tb-toggle-option value="entities">{{ 'widgets.usage-info.entities' | translate }}</tb-toggle-option>
name: ctx.translate.instant('widgets.usage-info.entities'), <tb-toggle-option value="apiCalls">{{ 'widgets.usage-info.api-calls' | translate }}</tb-toggle-option>
value: 'entities'
},
{
name: ctx.translate.instant('widgets.usage-info.api-calls'),
value: 'apiCalls'
}
]">
</tb-toggle-header> </tb-toggle-header>
</div> </div>
<ng-container [ngSwitch]="usageToggle.value"> <ng-container [ngSwitch]="usageToggle.value">

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

@ -33,7 +33,7 @@ export interface LabelWidgetLabel {
@Component({ @Component({
selector: 'tb-label-widget-label', selector: 'tb-label-widget-label',
templateUrl: './label-widget-label.component.html', templateUrl: './label-widget-label.component.html',
styleUrls: ['./label-widget-label.component.scss', './../widget-settings.scss'], styleUrls: ['./label-widget-label.component.scss'],
providers: [ providers: [
{ {
provide: NG_VALUE_ACCESSOR, provide: NG_VALUE_ACCESSOR,

43
ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/flot-latest-key-settings.component.html

@ -15,34 +15,37 @@
limitations under the License. limitations under the License.
--> -->
<section class="tb-widget-settings" [formGroup]="flotLatestKeySettingsForm" fxLayout="column"> <ng-container [formGroup]="flotLatestKeySettingsForm">
<fieldset class="fields-group fields-group-slider"> <div class="tb-widget-config-panel tb-slide-toggle">
<legend class="group-title" translate>widgets.chart.threshold-settings</legend> <div class="tb-widget-config-panel-title" translate>widgets.chart.threshold-settings</div>
<mat-expansion-panel class="tb-settings" [expanded]="flotLatestKeySettingsForm.get('useAsThreshold').value"> <mat-expansion-panel class="tb-settings" [expanded]="flotLatestKeySettingsForm.get('useAsThreshold').value"
[disabled]="!flotLatestKeySettingsForm.get('useAsThreshold').value">
<mat-expansion-panel-header fxLayout="row wrap"> <mat-expansion-panel-header fxLayout="row wrap">
<mat-panel-title> <mat-panel-title>
<mat-slide-toggle formControlName="useAsThreshold" (click)="$event.stopPropagation()" <mat-slide-toggle class="mat-slide" formControlName="useAsThreshold" (click)="$event.stopPropagation()"
fxLayoutAlign="center"> fxLayoutAlign="center">
{{ 'widgets.chart.use-as-threshold' | translate }} {{ 'widgets.chart.use-as-threshold' | translate }}
</mat-slide-toggle> </mat-slide-toggle>
</mat-panel-title> </mat-panel-title>
<mat-panel-description fxLayoutAlign="end center" fxHide.xs translate>
widget-config.advanced-settings
</mat-panel-description>
</mat-expansion-panel-header> </mat-expansion-panel-header>
<ng-template matExpansionPanelContent> <ng-template matExpansionPanelContent>
<section fxLayout="column" fxLayout.gt-xs="row" fxLayoutGap.gt-xs="8px"> <div class="tb-widget-config-row space-between">
<mat-form-field fxFlex class="mat-block"> <div translate>widgets.chart.threshold-line-width</div>
<mat-label translate>widgets.chart.threshold-line-width</mat-label> <mat-form-field appearance="outline" class="number" subscriptSizing="dynamic">
<input type="number" min="0" matInput formControlName="thresholdLineWidth"> <input matInput formControlName="thresholdLineWidth" type="number" min="0" placeholder="{{ 'widget-config.set' | translate }}">
<span matSuffix>px</span>
</mat-form-field> </mat-form-field>
<tb-color-input fxFlex </div>
formControlName="thresholdColor" <div class="tb-widget-config-row space-between same-padding">
icon="format_color_fill" <div>{{ 'widgets.chart.threshold-color' | translate }}</div>
label="{{ 'widgets.chart.threshold-color' | translate }}" openOnInput colorClearButton> <div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="16px">
</tb-color-input> <mat-divider vertical></mat-divider>
</section> <tb-color-input asBoxInput
formControlName="thresholdColor">
</tb-color-input>
</div>
</div>
</ng-template> </ng-template>
</mat-expansion-panel> </mat-expansion-panel>
</fieldset> </div>
</section> </ng-container>

2
ui-ngx/src/app/modules/home/components/widget/lib/settings/gauge/fixed-color-level.component.ts

@ -50,7 +50,7 @@ export function fixedColorLevelValidator(control: AbstractControl): ValidationEr
@Component({ @Component({
selector: 'tb-fixed-color-level', selector: 'tb-fixed-color-level',
templateUrl: './fixed-color-level.component.html', templateUrl: './fixed-color-level.component.html',
styleUrls: ['./fixed-color-level.component.scss', './../widget-settings.scss'], styleUrls: ['./fixed-color-level.component.scss'],
providers: [ providers: [
{ {
provide: NG_VALUE_ACCESSOR, provide: NG_VALUE_ACCESSOR,

2
ui-ngx/src/app/modules/home/components/widget/lib/settings/gauge/gauge-highlight.component.ts

@ -31,7 +31,7 @@ export interface GaugeHighlight {
@Component({ @Component({
selector: 'tb-gauge-highlight', selector: 'tb-gauge-highlight',
templateUrl: './gauge-highlight.component.html', templateUrl: './gauge-highlight.component.html',
styleUrls: ['./gauge-highlight.component.scss', './../widget-settings.scss'], styleUrls: ['./gauge-highlight.component.scss'],
providers: [ providers: [
{ {
provide: NG_VALUE_ACCESSOR, provide: NG_VALUE_ACCESSOR,

2
ui-ngx/src/app/modules/home/components/widget/lib/settings/gauge/tick-value.component.ts

@ -27,7 +27,7 @@ import { IAliasController } from '@core/api/widget-api.models';
@Component({ @Component({
selector: 'tb-tick-value', selector: 'tb-tick-value',
templateUrl: './tick-value.component.html', templateUrl: './tick-value.component.html',
styleUrls: ['./tick-value.component.scss', './../widget-settings.scss'], styleUrls: ['./tick-value.component.scss'],
providers: [ providers: [
{ {
provide: NG_VALUE_ACCESSOR, provide: NG_VALUE_ACCESSOR,

2
ui-ngx/src/app/modules/home/components/widget/lib/settings/gpio/gpio-item.component.ts

@ -56,7 +56,7 @@ export const gpioItemValidator = (hasColor: boolean): ValidatorFn => (control: A
@Component({ @Component({
selector: 'tb-gpio-item', selector: 'tb-gpio-item',
templateUrl: './gpio-item.component.html', templateUrl: './gpio-item.component.html',
styleUrls: ['./gpio-item.component.scss', './../widget-settings.scss'], styleUrls: ['./gpio-item.component.scss'],
providers: [ providers: [
{ {
provide: NG_VALUE_ACCESSOR, provide: NG_VALUE_ACCESSOR,

2
ui-ngx/src/app/modules/home/components/widget/lib/settings/input/datakey-select-option.component.ts

@ -46,7 +46,7 @@ export const dataKeySelectOptionValidator = (control: AbstractControl) => {
@Component({ @Component({
selector: 'tb-datakey-select-option', selector: 'tb-datakey-select-option',
templateUrl: './datakey-select-option.component.html', templateUrl: './datakey-select-option.component.html',
styleUrls: ['./datakey-select-option.component.scss', './../widget-settings.scss'], styleUrls: ['./datakey-select-option.component.scss'],
providers: [ providers: [
{ {
provide: NG_VALUE_ACCESSOR, provide: NG_VALUE_ACCESSOR,

6
ui-ngx/src/app/modules/home/components/widget/widget-config.component.html

@ -17,9 +17,9 @@
--> -->
<div class="tb-widget-config tb-absolute-fill"> <div class="tb-widget-config tb-absolute-fill">
<div class="tb-widget-config-header" *ngIf="!hideHeader"> <div class="tb-widget-config-header" *ngIf="!hideHeader">
<tb-toggle-header *ngIf="!hideToggleHeader && widgetConfigMode === widgetConfigModes.advanced" (valueChange)="selectedOption = $event" ignoreMdLgSize="true" <tb-toggle-select *ngIf="!hideToggleHeader && widgetConfigMode === widgetConfigModes.advanced"
appearance="fill" [options]="headerOptions" [value]="selectedOption" name="widgetConfigHeader" useSelectOnMdLg="false"> appearance="fill" [options]="headerOptions" [(ngModel)]="selectedOption">
</tb-toggle-header> </tb-toggle-select>
<ng-content select=".tb-widget-config-header-prefix"></ng-content> <ng-content select=".tb-widget-config-header-prefix"></ng-content>
<ng-content select=".tb-widget-config-header-suffix"></ng-content> <ng-content select=".tb-widget-config-header-suffix"></ng-content>
</div> </div>

4
ui-ngx/src/app/modules/home/pages/home-links/tenant_admin_home_page.raw

@ -48,7 +48,7 @@
"padding": "16px", "padding": "16px",
"settings": { "settings": {
"useMarkdownTextFunction": false, "useMarkdownTextFunction": false,
"markdownTextPattern": "<div class=\"tb-card-content\">\n <div fxLayout=\"row\" fxLayoutAlign=\"space-between start\" fxLayout.lt-md=\"column\" fxLayoutGap.lt-md=\"12px\">\n <div class=\"tb-home-widget-title\">{{ 'widgets.activity.title' | translate }}</div>\n <tb-toggle-header #activityStates value=\"devices\" name=\"activityStates\"\n [options]=\"[\n {\n name: ctx.translate.instant('device.devices'),\n value: 'devices'\n },\n {\n name: ctx.translate.instant('widgets.transport-messages.title'),\n value: 'transportMessages'\n }\n ]\">\n </tb-toggle-header>\n </div>\n <ng-container [ngSwitch]=\"activityStates.value\">\n <ng-template [ngSwitchCase]=\"'devices'\">\n <tb-dashboard-state fxFlex stateId=\"devices_activity\" [ctx]=\"ctx\"></tb-dashboard-state>\n </ng-template>\n <ng-template [ngSwitchCase]=\"'transportMessages'\">\n <tb-dashboard-state fxFlex stateId=\"transport_messages\" [ctx]=\"ctx\"></tb-dashboard-state>\n </ng-template>\n </ng-container>\n</div>", "markdownTextPattern": "<div class=\"tb-card-content\">\n <div fxLayout=\"row\" fxLayoutAlign=\"space-between start\" fxLayout.lt-md=\"column\" fxLayoutGap.lt-md=\"12px\">\n <div class=\"tb-home-widget-title\">{{ 'widgets.activity.title' | translate }}</div>\n <tb-toggle-header #activityStates value=\"devices\" name=\"activityStates\">\n <tb-toggle-option value=\"devices\">{{ 'device.devices' | translate }}</tb-toggle-option>\n <tb-toggle-option value=\"transportMessages\">{{ 'widgets.transport-messages.title' | translate }}</tb-toggle-option>\n </tb-toggle-header>\n </div>\n <ng-container [ngSwitch]=\"activityStates.value\">\n <ng-template [ngSwitchCase]=\"'devices'\">\n <tb-dashboard-state fxFlex stateId=\"devices_activity\" [ctx]=\"ctx\"></tb-dashboard-state>\n </ng-template>\n <ng-template [ngSwitchCase]=\"'transportMessages'\">\n <tb-dashboard-state fxFlex stateId=\"transport_messages\" [ctx]=\"ctx\"></tb-dashboard-state>\n </ng-template>\n </ng-container>\n</div>",
"applyDefaultMarkdownStyle": false, "applyDefaultMarkdownStyle": false,
"markdownCss": ".tb-card-content {\n width: 100%;\n height: 100%;\n display: flex;\n flex-direction: column;\n justify-content: space-between;\n}\n" "markdownCss": ".tb-card-content {\n width: 100%;\n height: 100%;\n display: flex;\n flex-direction: column;\n justify-content: space-between;\n}\n"
}, },
@ -1101,4 +1101,4 @@
}, },
"externalId": null, "externalId": null,
"name": "Tenant Administrator Home Page" "name": "Tenant Administrator Home Page"
} }

88
ui-ngx/src/app/shared/components/toggle-header.component.ts

@ -16,29 +16,26 @@
import { import {
AfterContentInit, AfterContentInit,
AfterViewInit,
ChangeDetectorRef, ChangeDetectorRef,
Component, Component,
ContentChildren, EventEmitter, ContentChildren,
Directive,
ElementRef,
EventEmitter,
Input, Input,
OnInit, Output, OnDestroy,
QueryList, OnInit,
ViewChild Output,
QueryList
} from '@angular/core'; } from '@angular/core';
import { PageComponent } from '@shared/components/page.component'; import { PageComponent } from '@shared/components/page.component';
import { Store } from '@ngrx/store'; import { Store } from '@ngrx/store';
import { AppState } from '@core/core.state'; import { AppState } from '@core/core.state';
import { AdminService } from '@core/http/admin.service'; import { Subject, Subscription } from 'rxjs';
import { UpdateMessage } from '@shared/models/settings.models';
import { getCurrentAuthUser } from '@core/auth/auth.selectors';
import { Authority } from '@shared/models/authority.enum';
import { of, Subscription } from 'rxjs';
import { MatStepper } from '@angular/material/stepper';
import { MatButtonToggle, MatButtonToggleGroup } from '@angular/material/button-toggle';
import { BreakpointObserver, BreakpointState } from '@angular/cdk/layout'; import { BreakpointObserver, BreakpointState } from '@angular/cdk/layout';
import { MediaBreakpoints } from '@shared/models/constants'; import { MediaBreakpoints } from '@shared/models/constants';
import { coerceBoolean } from '@shared/decorators/coercion'; import { coerceBoolean } from '@shared/decorators/coercion';
import { BreadCrumb } from '@shared/components/breadcrumb'; import { startWith, takeUntil } from 'rxjs/operators';
export interface ToggleHeaderOption { export interface ToggleHeaderOption {
name: string; name: string;
@ -47,12 +44,72 @@ export interface ToggleHeaderOption {
export type ToggleHeaderAppearance = 'fill' | 'fill-invert' | 'stroked'; export type ToggleHeaderAppearance = 'fill' | 'fill-invert' | 'stroked';
@Directive(
{
// eslint-disable-next-line @angular-eslint/directive-selector
selector: 'tb-toggle-option',
}
)
// eslint-disable-next-line @angular-eslint/directive-class-suffix
export class ToggleOption {
@Input() value: any;
get viewValue(): string {
return (this._element?.nativeElement.textContent || '').trim();
}
constructor(
private _element: ElementRef<HTMLElement>
) {}
}
@Directive()
export abstract class _ToggleBase extends PageComponent implements AfterContentInit, OnDestroy {
@ContentChildren(ToggleOption) toggleOptions: QueryList<ToggleOption>;
@Input()
options: ToggleHeaderOption[] = [];
private _destroyed = new Subject<void>();
protected constructor(protected store: Store<AppState>) {
super(store);
}
ngAfterContentInit(): void {
this.toggleOptions.changes.pipe(startWith(null), takeUntil(this._destroyed)).subscribe(() => {
this.syncToggleHeaderOptions();
});
}
ngOnDestroy() {
this._destroyed.next();
this._destroyed.complete();
}
private syncToggleHeaderOptions() {
if (this.toggleOptions?.length) {
this.options.length = 0;
this.toggleOptions.forEach(option => {
this.options.push(
{ name: option.viewValue,
value: option.value
}
);
});
}
}
}
@Component({ @Component({
selector: 'tb-toggle-header', selector: 'tb-toggle-header',
templateUrl: './toggle-header.component.html', templateUrl: './toggle-header.component.html',
styleUrls: ['./toggle-header.component.scss'] styleUrls: ['./toggle-header.component.scss']
}) })
export class ToggleHeaderComponent extends PageComponent implements OnInit { export class ToggleHeaderComponent extends _ToggleBase implements OnInit, AfterContentInit, OnDestroy {
@Input() @Input()
value: any; value: any;
@ -60,9 +117,6 @@ export class ToggleHeaderComponent extends PageComponent implements OnInit {
@Output() @Output()
valueChange = new EventEmitter<any>(); valueChange = new EventEmitter<any>();
@Input()
options: ToggleHeaderOption[];
@Input() @Input()
name: string; name: string;

1
ui-ngx/src/app/shared/components/toggle-select.component.html

@ -18,6 +18,7 @@
<tb-toggle-header <tb-toggle-header
ignoreMdLgSize="true" ignoreMdLgSize="true"
useSelectOnMdLg="false" useSelectOnMdLg="false"
[appearance]="appearance"
[options]="options" [options]="options"
[value]="modelValue" [value]="modelValue"
(valueChange)="updateModel($event)"> (valueChange)="updateModel($event)">

74
ui-ngx/src/app/shared/components/toggle-select.component.ts

@ -14,45 +14,11 @@
/// limitations under the License. /// limitations under the License.
/// ///
import { import { Component, forwardRef, Input } from '@angular/core';
AfterContentInit,
ChangeDetectorRef,
Component,
ContentChildren,
Directive,
ElementRef,
forwardRef,
Input,
OnDestroy,
QueryList
} from '@angular/core';
import { PageComponent } from '@shared/components/page.component';
import { Store } from '@ngrx/store'; import { Store } from '@ngrx/store';
import { AppState } from '@core/core.state'; import { AppState } from '@core/core.state';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
import { Subject } from 'rxjs'; import { _ToggleBase, ToggleHeaderAppearance } from '@shared/components/toggle-header.component';
import { startWith, takeUntil } from 'rxjs/operators';
import { ToggleHeaderOption } from '@shared/components/toggle-header.component';
@Directive(
{
// eslint-disable-next-line @angular-eslint/directive-selector
selector: 'tb-toggle-option',
}
)
// eslint-disable-next-line @angular-eslint/directive-class-suffix
export class ToggleSelectOption {
@Input() value: any;
get viewValue(): string {
return (this._element?.nativeElement.textContent || '').trim();
}
constructor(
private _element: ElementRef<HTMLElement>
) {}
}
@Component({ @Component({
selector: 'tb-toggle-select', selector: 'tb-toggle-select',
@ -66,37 +32,22 @@ export class ToggleSelectOption {
} }
] ]
}) })
export class ToggleSelectComponent extends PageComponent implements AfterContentInit, OnDestroy, ControlValueAccessor { export class ToggleSelectComponent extends _ToggleBase implements ControlValueAccessor {
@ContentChildren(ToggleSelectOption) toggleSelectOptions: QueryList<ToggleSelectOption>;
@Input() @Input()
disabled: boolean; disabled: boolean;
options: ToggleHeaderOption[] = []; @Input()
appearance: ToggleHeaderAppearance = 'stroked';
private _destroyed = new Subject<void>();
modelValue: any; modelValue: any;
private propagateChange = null; private propagateChange = null;
constructor(protected store: Store<AppState>, constructor(protected store: Store<AppState>) {
private cd: ChangeDetectorRef) {
super(store); super(store);
} }
ngAfterContentInit(): void {
this.toggleSelectOptions.changes.pipe(startWith(null), takeUntil(this._destroyed)).subscribe(() => {
this.syncToggleHeaderOptions();
});
}
ngOnDestroy() {
this._destroyed.next();
this._destroyed.complete();
}
registerOnChange(fn: any): void { registerOnChange(fn: any): void {
this.propagateChange = fn; this.propagateChange = fn;
} }
@ -112,19 +63,6 @@ export class ToggleSelectComponent extends PageComponent implements AfterContent
this.modelValue = value; this.modelValue = value;
} }
private syncToggleHeaderOptions() {
this.options.length = 0;
if (this.toggleSelectOptions) {
this.toggleSelectOptions.forEach(selectOption => {
this.options.push(
{ name: selectOption.viewValue,
value: selectOption.value
}
);
});
}
}
updateModel(value: any) { updateModel(value: any) {
this.modelValue = value; this.modelValue = value;
this.propagateChange(this.modelValue); this.propagateChange(this.modelValue);

8
ui-ngx/src/app/shared/shared.module.ts

@ -191,9 +191,9 @@ import {
import { ColorPickerComponent } from '@shared/components/color-picker/color-picker.component'; import { ColorPickerComponent } from '@shared/components/color-picker/color-picker.component';
import { ResourceAutocompleteComponent } from '@shared/components/resource/resource-autocomplete.component'; import { ResourceAutocompleteComponent } from '@shared/components/resource/resource-autocomplete.component';
import { ShortNumberPipe } from '@shared/pipe/short-number.pipe'; import { ShortNumberPipe } from '@shared/pipe/short-number.pipe';
import { ToggleHeaderComponent } from '@shared/components/toggle-header.component'; import { ToggleHeaderComponent, ToggleOption } from '@shared/components/toggle-header.component';
import { RuleChainSelectComponent } from '@shared/components/rule-chain/rule-chain-select.component'; import { RuleChainSelectComponent } from '@shared/components/rule-chain/rule-chain-select.component';
import { ToggleSelectComponent, ToggleSelectOption } from '@shared/components/toggle-select.component'; import { ToggleSelectComponent } from '@shared/components/toggle-select.component';
export function MarkedOptionsFactory(markedOptionsService: MarkedOptionsService) { export function MarkedOptionsFactory(markedOptionsService: MarkedOptionsService) {
return markedOptionsService; return markedOptionsService;
@ -365,7 +365,7 @@ export function MarkedOptionsFactory(markedOptionsService: MarkedOptionsService)
ColorPickerComponent, ColorPickerComponent,
ResourceAutocompleteComponent, ResourceAutocompleteComponent,
ToggleHeaderComponent, ToggleHeaderComponent,
ToggleSelectOption, ToggleOption,
ToggleSelectComponent, ToggleSelectComponent,
RuleChainSelectComponent RuleChainSelectComponent
], ],
@ -595,7 +595,7 @@ export function MarkedOptionsFactory(markedOptionsService: MarkedOptionsService)
ColorPickerComponent, ColorPickerComponent,
ResourceAutocompleteComponent, ResourceAutocompleteComponent,
ToggleHeaderComponent, ToggleHeaderComponent,
ToggleSelectOption, ToggleOption,
ToggleSelectComponent, ToggleSelectComponent,
RuleChainSelectComponent RuleChainSelectComponent
] ]

Loading…
Cancel
Save