Browse Source

[3.0] minor fix (#2645)

* Improvement layout-setting setting from mobile/tablet view

* Fix EntityView not show type in translate

* Clear code and update tablet/mobile view

* Update tablet/mobile view

* Fix hide title and text-overflow

* Add support Safari

* Minor fix
pull/2663/head
Vladyslav 7 years ago
committed by GitHub
parent
commit
3103d0a726
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      ui-ngx/src/app/modules/home/components/alias/aliases-entity-select-panel.component.html
  2. 4
      ui-ngx/src/app/modules/home/components/alias/aliases-entity-select.component.html
  3. 10
      ui-ngx/src/app/modules/home/components/alias/entity-alias-dialog.component.html
  4. 14
      ui-ngx/src/app/modules/home/components/alias/entity-alias-dialog.component.ts
  5. 2
      ui-ngx/src/app/modules/home/components/alias/entity-alias-select.component.html
  6. 23
      ui-ngx/src/app/modules/home/components/alias/entity-alias-select.component.ts
  7. 38
      ui-ngx/src/app/modules/home/components/alias/entity-aliases-dialog.component.html
  8. 6
      ui-ngx/src/app/modules/home/components/alias/entity-aliases-dialog.component.scss
  9. 7
      ui-ngx/src/app/modules/home/components/alias/entity-aliases-dialog.component.ts
  10. 8
      ui-ngx/src/app/modules/home/components/attribute/add-attribute-dialog.component.html
  11. 8
      ui-ngx/src/app/modules/home/components/attribute/add-widget-to-dashboard-dialog.component.html
  12. 16
      ui-ngx/src/app/modules/home/components/attribute/add-widget-to-dashboard-dialog.component.ts
  13. 1
      ui-ngx/src/app/modules/home/components/dashboard/dashboard.component.html
  14. 8
      ui-ngx/src/app/modules/home/components/dashboard/dashboard.component.scss
  15. 8
      ui-ngx/src/app/modules/home/components/dashboard/layout-button.scss
  16. 18
      ui-ngx/src/app/modules/home/components/dashboard/select-target-layout-dialog.component.html
  17. 15
      ui-ngx/src/app/modules/home/components/dashboard/select-target-state-dialog.component.html
  18. 3
      ui-ngx/src/app/modules/home/components/dashboard/select-target-state-dialog.component.ts
  19. 2
      ui-ngx/src/app/modules/home/components/details-panel.component.html
  20. 2
      ui-ngx/src/app/modules/home/components/details-panel.component.scss
  21. 6
      ui-ngx/src/app/modules/home/components/entity/entity-filter-view.component.ts
  22. 12
      ui-ngx/src/app/modules/home/components/entity/entity-filter.component.html
  23. 60
      ui-ngx/src/app/modules/home/components/relation/relation-filters.component.html
  24. 24
      ui-ngx/src/app/modules/home/components/relation/relation-filters.component.scss
  25. 16
      ui-ngx/src/app/modules/home/components/relation/relation-filters.component.ts
  26. 4
      ui-ngx/src/app/modules/home/components/relation/relation-table.component.html
  27. 2
      ui-ngx/src/app/modules/home/components/widget/action/custom-action-pretty-editor.component.html
  28. 34
      ui-ngx/src/app/modules/home/components/widget/action/custom-action-pretty-editor.component.ts
  29. 4
      ui-ngx/src/app/modules/home/components/widget/action/custom-action-pretty-resources-tabs.component.html
  30. 7
      ui-ngx/src/app/modules/home/components/widget/action/custom-action-pretty-resources-tabs.component.ts
  31. 16
      ui-ngx/src/app/modules/home/components/widget/action/manage-widget-actions.component.html
  32. 15
      ui-ngx/src/app/modules/home/components/widget/action/manage-widget-actions.component.models.ts
  33. 19
      ui-ngx/src/app/modules/home/components/widget/action/manage-widget-actions.component.ts
  34. 20
      ui-ngx/src/app/modules/home/components/widget/action/widget-action-dialog.component.html
  35. 20
      ui-ngx/src/app/modules/home/components/widget/action/widget-action-dialog.component.scss
  36. 2
      ui-ngx/src/app/modules/home/components/widget/action/widget-action-dialog.component.ts
  37. 10
      ui-ngx/src/app/modules/home/components/widget/data-key-config-dialog.component.html
  38. 1
      ui-ngx/src/app/modules/home/components/widget/data-key-config-dialog.component.scss
  39. 21
      ui-ngx/src/app/modules/home/components/widget/data-key-config.component.html
  40. 22
      ui-ngx/src/app/modules/home/components/widget/data-key-config.component.scss
  41. 5
      ui-ngx/src/app/modules/home/components/widget/data-keys.component.scss
  42. 14
      ui-ngx/src/app/modules/home/components/widget/dialog/custom-dialog-container.component.ts
  43. 3
      ui-ngx/src/app/modules/home/components/widget/dialog/custom-dialog.component.ts
  44. 1
      ui-ngx/src/app/modules/home/components/widget/dynamic-widget.component.ts
  45. 4
      ui-ngx/src/app/modules/home/components/widget/lib/alarms-table-widget.component.html
  46. 4
      ui-ngx/src/app/modules/home/components/widget/lib/entities-table-widget.component.html
  47. 4
      ui-ngx/src/app/modules/home/components/widget/lib/timeseries-table-widget.component.html
  48. 162
      ui-ngx/src/app/modules/home/components/widget/widget-config.component.html
  49. 24
      ui-ngx/src/app/modules/home/components/widget/widget-config.component.scss
  50. 13
      ui-ngx/src/app/modules/home/pages/dashboard/add-widget-dialog.component.html
  51. 8
      ui-ngx/src/app/modules/home/pages/dashboard/add-widget-dialog.component.ts
  52. 24
      ui-ngx/src/app/modules/home/pages/dashboard/dashboard-page.component.html
  53. 20
      ui-ngx/src/app/modules/home/pages/dashboard/dashboard-settings-dialog.component.html
  54. 26
      ui-ngx/src/app/modules/home/pages/dashboard/dashboard-settings-dialog.component.scss
  55. 2
      ui-ngx/src/app/modules/home/pages/dashboard/dashboard-settings-dialog.component.ts
  56. 6
      ui-ngx/src/app/modules/home/pages/dashboard/dashboard-toolbar.component.html
  57. 2
      ui-ngx/src/app/modules/home/pages/dashboard/layout/dashboard-layout.component.ts
  58. 3
      ui-ngx/src/app/modules/home/pages/dashboard/layout/layout.models.ts
  59. 27
      ui-ngx/src/app/modules/home/pages/dashboard/layout/manage-dashboard-layouts-dialog.component.html
  60. 11
      ui-ngx/src/app/modules/home/pages/dashboard/layout/manage-dashboard-layouts-dialog.component.ts
  61. 10
      ui-ngx/src/app/modules/home/pages/dashboard/states/dashboard-state-dialog.component.html
  62. 4
      ui-ngx/src/app/modules/home/pages/dashboard/states/dashboard-state-dialog.component.ts
  63. 30
      ui-ngx/src/app/modules/home/pages/dashboard/states/manage-dashboard-states-dialog.component.html
  64. 8
      ui-ngx/src/app/modules/home/pages/dashboard/states/states-component.directive.ts
  65. 32
      ui-ngx/src/app/modules/home/pages/widget/widget-editor.component.html
  66. 7
      ui-ngx/src/app/modules/home/pages/widget/widget-editor.component.ts
  67. 6
      ui-ngx/src/app/shared/components/color-input.component.scss
  68. 22
      ui-ngx/src/app/shared/components/color-input.component.ts
  69. 31
      ui-ngx/src/app/shared/components/dashboard-autocomplete.component.ts
  70. 2
      ui-ngx/src/app/shared/components/dashboard-select.component.html
  71. 39
      ui-ngx/src/app/shared/components/entity/entity-type-list.component.ts
  72. 11
      ui-ngx/src/app/shared/components/fab-toolbar.component.ts
  73. 1
      ui-ngx/src/app/shared/components/json-form/react/json-form-checkbox.tsx
  74. 2
      ui-ngx/src/app/shared/components/material-icon-select.component.html
  75. 6
      ui-ngx/src/app/shared/components/material-icon-select.component.scss
  76. 24
      ui-ngx/src/app/shared/components/material-icon-select.component.ts
  77. 2
      ui-ngx/src/app/shared/components/relation/relation-type-autocomplete.component.html
  78. 28
      ui-ngx/src/app/shared/components/relation/relation-type-autocomplete.component.ts
  79. 1
      ui-ngx/src/styles.scss

2
ui-ngx/src/app/modules/home/components/alias/aliases-entity-select-panel.component.html

@ -19,7 +19,7 @@
<div fxLayout="row" *ngFor="let alias of entityAliasesInfo | keyvalue">
<mat-form-field>
<mat-label>{{alias.value.alias}}</mat-label>
<mat-select matInput [(ngModel)]="alias.value.selectedId"
<mat-select [(ngModel)]="alias.value.selectedId"
(ngModelChange)="currentAliasEntityChanged(alias.key, alias.value.selectedId)">
<mat-option *ngFor="let resolvedEntity of alias.value.resolvedEntities" [value]="resolvedEntity.id">
{{resolvedEntity.name}}

4
ui-ngx/src/app/modules/home/components/alias/aliases-entity-select.component.html

@ -16,14 +16,14 @@
-->
<section class="tb-aliases-entity-select" fxLayout="row" fxLayoutAlign="start center">
<button mat-button mat-icon-button
<button mat-icon-button
cdkOverlayOrigin #aliasEntitySelectPanelOrigin="cdkOverlayOrigin"
(click)="openEditMode()"
matTooltip="{{ 'entity.select-entities' | translate }}"
[matTooltipPosition]="tooltipPosition">
<mat-icon class="material-icons">devices_other</mat-icon>
</button>
<span fxHide.xs fxHide.sm fxHide.md
<span fxHide.lt-lg
(click)="openEditMode()"
matTooltip="{{ 'entity.select-entities' | translate }}"
[matTooltipPosition]="tooltipPosition">

10
ui-ngx/src/app/modules/home/components/alias/entity-alias-dialog.component.html

@ -15,11 +15,11 @@
limitations under the License.
-->
<form #entityAliasForm="ngForm" [formGroup]="entityAliasFormGroup" (ngSubmit)="save()" style="min-width: 550px;">
<form #entityAliasForm="ngForm" [formGroup]="entityAliasFormGroup" (ngSubmit)="save()" style="min-width: 480px;">
<mat-toolbar color="primary">
<h2>{{ (isAdd ? 'alias.add' : 'alias.edit') | translate }}</h2>
<span fxFlex></span>
<button mat-button mat-icon-button
<button mat-icon-button
(click)="cancel()"
type="button">
<mat-icon class="material-icons">close</mat-icon>
@ -58,15 +58,13 @@
</div>
</fieldset>
</div>
<div mat-dialog-actions fxLayout="row">
<span fxFlex></span>
<button mat-button mat-raised-button color="primary"
<div mat-dialog-actions fxLayoutAlign="end center">
<button mat-raised-button color="primary"
type="submit"
[disabled]="(isLoading$ | async) || entityAliasFormGroup.invalid || !entityAliasFormGroup.dirty">
{{ (isAdd ? 'action.add' : 'action.save') | translate }}
</button>
<button mat-button color="primary"
style="margin-right: 20px;"
type="button"
[disabled]="(isLoading$ | async)"
(click)="cancel()" cdkFocusInitial>

14
ui-ngx/src/app/modules/home/components/alias/entity-alias-dialog.component.ts

@ -20,26 +20,22 @@ import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { Store } from '@ngrx/store';
import { AppState } from '@core/core.state';
import {
AbstractControl,
FormArray,
FormBuilder,
FormControl,
FormGroup,
FormGroupDirective,
NgForm, Validators, ValidatorFn
NgForm,
ValidatorFn,
Validators
} from '@angular/forms';
import { Router } from '@angular/router';
import { DialogComponent } from '@app/shared/components/dialog.component';
import { AttributeData } from '@shared/models/telemetry/telemetry.models';
import { EntityAlias, EntityAliases, EntityAliasFilter } from '@shared/models/alias.models';
import { DatasourceType, Widget, widgetType } from '@shared/models/widget.models';
import { EntityAlias, EntityAliases } from '@shared/models/alias.models';
import { AliasEntityType, EntityType } from '@shared/models/entity-type.models';
import { UtilsService } from '@core/services/utils.service';
import { TranslateService } from '@ngx-translate/core';
import { ActionNotificationShow } from '@core/notification/notification.actions';
import { DialogService } from '@core/services/dialog.service';
import { EntityService } from '@core/http/entity.service';
import { Observable, of } from 'rxjs';
import { Observable } from 'rxjs';
export interface EntityAliasDialogData {
isAdd: boolean;

2
ui-ngx/src/app/modules/home/components/alias/entity-alias-select.component.html

@ -27,7 +27,7 @@
[matAutocomplete]="entityAliasAutocomplete">
<button *ngIf="selectEntityAliasFormGroup.get('entityAlias').value && !disabled"
type="button"
matSuffix mat-button mat-icon-button aria-label="Clear"
matSuffix mat-icon-button aria-label="Clear"
(click)="clear()">
<mat-icon class="material-icons">close</mat-icon>
</button>

23
ui-ngx/src/app/modules/home/components/alias/entity-alias-select.component.ts

@ -21,24 +21,23 @@ import {
FormControl,
FormGroup,
FormGroupDirective,
NG_VALUE_ACCESSOR, NgForm
NG_VALUE_ACCESSOR,
NgForm
} from '@angular/forms';
import { Observable, of } from 'rxjs';
import { map, mergeMap, startWith, tap, share, filter } from 'rxjs/operators';
import {Store} from '@ngrx/store';
import {AppState} from '@app/core/core.state';
import {TranslateService} from '@ngx-translate/core';
import {AliasEntityType, EntityType} from '@shared/models/entity-type.models';
import {BaseData} from '@shared/models/base-data';
import {EntityId} from '@shared/models/id/entity-id';
import {EntityService} from '@core/http/entity.service';
import {coerceBooleanProperty} from '@angular/cdk/coercion';
import { map, mergeMap, share, tap } from 'rxjs/operators';
import { Store } from '@ngrx/store';
import { AppState } from '@app/core/core.state';
import { TranslateService } from '@ngx-translate/core';
import { EntityType } from '@shared/models/entity-type.models';
import { EntityService } from '@core/http/entity.service';
import { coerceBooleanProperty } from '@angular/cdk/coercion';
import { EntityAlias } from '@shared/models/alias.models';
import { IAliasController } from '@core/api/widget-api.models';
import { TruncatePipe } from '@shared/pipe/truncate.pipe';
import { MatAutocomplete, MatAutocompleteSelectedEvent, MatAutocompleteTrigger } from '@angular/material/autocomplete';
import { MatAutocomplete, MatAutocompleteTrigger } from '@angular/material/autocomplete';
import { EntityAliasSelectCallbacks } from './entity-alias-select.component.models';
import {ENTER} from '@angular/cdk/keycodes';
import { ENTER } from '@angular/cdk/keycodes';
import { ErrorStateMatcher } from '@angular/material/core';
@Component({

38
ui-ngx/src/app/modules/home/components/alias/entity-aliases-dialog.component.html

@ -16,10 +16,10 @@
-->
<form #entityAliasesForm="ngForm" [formGroup]="entityAliasesFormGroup" (ngSubmit)="save()" style="width: 700px;">
<mat-toolbar fxLayout="row" color="primary">
<mat-toolbar color="primary">
<h2>{{ title | translate }}</h2>
<span fxFlex></span>
<button mat-button mat-icon-button
<button mat-icon-button
(click)="cancel()"
type="button">
<mat-icon class="material-icons">close</mat-icon>
@ -28,18 +28,18 @@
<mat-progress-bar color="warn" mode="indeterminate" *ngIf="isLoading$ | async">
</mat-progress-bar>
<div style="height: 4px;" *ngIf="!(isLoading$ | async)"></div>
<div class="tb-aliases-header" fxFlex fxLayout="row" fxLayoutAlign="start center">
<span fxFlex="5"></span>
<div fxFlex="95" fxLayout="row" fxLayoutAlign="start center">
<span class="tb-header-label" translate fxFlex="150px">alias.name</span>
<span class="tb-header-label" translate fxFlex style="padding-left: 10px;">alias.entity-filter</span>
<span class="tb-header-label" translate fxFlex="120px" style="padding-left: 10px;">alias.resolve-multiple</span>
<span style="min-width: 80px;"></span>
</div>
</div>
<mat-divider></mat-divider>
<div mat-dialog-content>
<div class="tb-aliases-header" fxLayout="row" fxLayoutAlign="start center">
<span fxFlex="5"></span>
<div fxFlex="95" fxLayout="row" fxLayoutAlign="start center">
<span class="tb-header-label" translate fxFlex="150px">alias.name</span>
<span class="tb-header-label" translate fxFlex style="padding-left: 10px;">alias.entity-filter</span>
<span class="tb-header-label" translate fxFlex="120px" style="padding-left: 10px;">alias.resolve-multiple</span>
<span style="min-width: 80px;"></span>
</div>
</div>
<fieldset [disabled]="isLoading$ | async">
<mat-divider></mat-divider>
<div fxFlex fxLayout="row" fxLayoutAlign="start center"
formArrayName="entityAliases"
*ngFor="let entityAliasControl of entityAliasesFormArray().controls; let $index = index">
@ -63,7 +63,7 @@
</mat-slide-toggle>
</section>
<button [disabled]="isLoading$ | async"
mat-button mat-icon-button color="primary"
mat-icon-button color="primary"
style="min-width: 40px;"
type="button"
(click)="editAlias($index)"
@ -72,7 +72,7 @@
<mat-icon>edit</mat-icon>
</button>
<button [disabled]="isLoading$ | async"
mat-button mat-icon-button color="primary"
mat-icon-button color="primary"
style="min-width: 40px;"
type="button"
(click)="removeAlias($index)"
@ -84,8 +84,8 @@
</div>
</fieldset>
</div>
<div mat-dialog-actions fxLayout="row">
<button mat-button mat-raised-button color="primary"
<div mat-dialog-actions>
<button mat-raised-button color="primary"
type="button"
(click)="addAlias()"
[fxShow]="!disableAdd"
@ -95,16 +95,16 @@
{{ 'alias.add' | translate }}
</button>
<span fxFlex></span>
<button mat-button mat-raised-button color="primary"
<button mat-raised-button color="primary"
type="submit"
[disabled]="(isLoading$ | async) || entityAliasesFormGroup.invalid || !entityAliasesFormGroup.dirty">
{{ 'action.save' | translate }}
</button>
<button mat-button color="primary"
style="margin-right: 20px;"
type="button"
[disabled]="(isLoading$ | async)"
(click)="cancel()" cdkFocusInitial>
(click)="cancel()"
cdkFocusInitial>
{{ 'action.cancel' | translate }}
</button>
</div>

6
ui-ngx/src/app/modules/home/components/alias/entity-aliases-dialog.component.scss

@ -17,7 +17,7 @@
.tb-aliases-header {
min-height: 40px;
padding: 0 34px 0 34px;
padding: 0 11px;
margin: 5px;
.tb-header-label {
@ -26,6 +26,10 @@
}
}
mat-divider{
margin: -1px -24px;
}
.tb-alias {
padding: 0 0 0 10px;
margin: 5px;

7
ui-ngx/src/app/modules/home/components/alias/entity-aliases-dialog.component.ts

@ -16,7 +16,7 @@
import { Component, Inject, OnInit, SkipSelf } from '@angular/core';
import { ErrorStateMatcher } from '@angular/material/core';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { MAT_DIALOG_DATA, MatDialog, MatDialogRef } from '@angular/material/dialog';
import { Store } from '@ngrx/store';
import { AppState } from '@core/core.state';
import {
@ -26,11 +26,11 @@ import {
FormControl,
FormGroup,
FormGroupDirective,
NgForm, Validators
NgForm,
Validators
} from '@angular/forms';
import { Router } from '@angular/router';
import { DialogComponent } from '@app/shared/components/dialog.component';
import { AttributeData } from '@shared/models/telemetry/telemetry.models';
import { EntityAlias, EntityAliases, EntityAliasFilter } from '@shared/models/alias.models';
import { DatasourceType, Widget, widgetType } from '@shared/models/widget.models';
import { AliasEntityType, EntityType } from '@shared/models/entity-type.models';
@ -39,7 +39,6 @@ import { TranslateService } from '@ngx-translate/core';
import { ActionNotificationShow } from '@core/notification/notification.actions';
import { DialogService } from '@core/services/dialog.service';
import { deepClone, isUndefined } from '@core/utils';
import { MatDialog } from '@angular/material/dialog';
import { EntityAliasDialogComponent, EntityAliasDialogData } from './entity-alias-dialog.component';
export interface EntityAliasesDialogData {

8
ui-ngx/src/app/modules/home/components/attribute/add-attribute-dialog.component.html

@ -16,7 +16,7 @@
-->
<form [formGroup]="attributeFormGroup" (ngSubmit)="add()" style="min-width: 400px;">
<mat-toolbar fxLayout="row" color="primary">
<mat-toolbar color="primary">
<h2>{{ 'attribute.add' | translate }}</h2>
<span fxFlex></span>
<button mat-button mat-icon-button
@ -43,15 +43,13 @@
</tb-value-input>
</fieldset>
</div>
<div mat-dialog-actions fxLayout="row">
<span fxFlex></span>
<button mat-button mat-raised-button color="primary"
<div mat-dialog-actions fxLayoutAlign="end center">
<button mat-raised-button color="primary"
type="submit"
[disabled]="(isLoading$ | async) || attributeFormGroup.invalid || !attributeFormGroup.dirty">
{{ 'action.add' | translate }}
</button>
<button mat-button color="primary"
style="margin-right: 20px;"
type="button"
[disabled]="(isLoading$ | async)"
(click)="cancel()" cdkFocusInitial>

8
ui-ngx/src/app/modules/home/components/attribute/add-widget-to-dashboard-dialog.component.html

@ -16,7 +16,7 @@
-->
<form #addWidgetForm="ngForm" [formGroup]="addWidgetFormGroup" (ngSubmit)="add()" style="min-width: 400px;">
<mat-toolbar fxLayout="row" color="primary">
<mat-toolbar color="primary">
<h2 translate>attribute.add-widget-to-dashboard</h2>
<span fxFlex></span>
<button mat-button mat-icon-button
@ -55,19 +55,17 @@
</mat-radio-group>
</fieldset>
</div>
<div mat-dialog-actions fxLayout="row">
<span fxFlex></span>
<div mat-dialog-actions fxLayoutAlign="end center">
<mat-checkbox formControlName="openDashboard"
style="margin-bottom: 0px; padding-right: 20px;">
{{ 'dashboard.open-dashboard' | translate }}
</mat-checkbox>
<button mat-button mat-raised-button color="primary"
<button mat-raised-button color="primary"
type="submit"
[disabled]="(isLoading$ | async) || addWidgetFormGroup.invalid || !addWidgetFormGroup.dirty">
{{ 'action.add' | translate }}
</button>
<button mat-button color="primary"
style="margin-right: 20px;"
type="button"
[disabled]="(isLoading$ | async)"
(click)="cancel()" cdkFocusInitial>

16
ui-ngx/src/app/modules/home/components/attribute/add-widget-to-dashboard-dialog.component.ts

@ -16,34 +16,26 @@
import { Component, Inject, OnInit, SkipSelf } from '@angular/core';
import { ErrorStateMatcher } from '@angular/material/core';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { MAT_DIALOG_DATA, MatDialog, MatDialogRef } from '@angular/material/dialog';
import { Store } from '@ngrx/store';
import { AppState } from '@core/core.state';
import { FormBuilder, FormControl, FormGroup, FormGroupDirective, NgForm, Validators } from '@angular/forms';
import { Router } from '@angular/router';
import { DialogComponent } from '@app/shared/components/dialog.component';
import { UtilsService } from '@core/services/utils.service';
import { TranslateService } from '@ngx-translate/core';
import {
DashboardLayoutId,
DashboardSettings,
GridSettings,
StateControllerId,
Dashboard
} from '@app/shared/models/dashboard.models';
import { isUndefined, objToBase64 } from '@core/utils';
import { Dashboard, DashboardLayoutId } from '@app/shared/models/dashboard.models';
import { objToBase64 } from '@core/utils';
import { DashboardUtilsService } from '@core/services/dashboard-utils.service';
import { EntityId } from '@app/shared/models/id/entity-id';
import { Widget } from '@app/shared/models/widget.models';
import { DashboardService } from '@core/http/dashboard.service';
import { forkJoin, Observable, of } from 'rxjs';
import { SelectTargetLayoutDialogComponent } from '@home/components/dashboard/select-target-layout-dialog.component';
import { MatDialog } from '@angular/material/dialog';
import {
SelectTargetStateDialogComponent,
SelectTargetStateDialogData
} from '@home/components/dashboard/select-target-state-dialog.component';
import { mergeMap, map } from 'rxjs/operators';
import { mergeMap } from 'rxjs/operators';
import { AliasesInfo } from '@shared/models/alias.models';
import { ItemBufferService } from '@core/services/item-buffer.service';
import { StateObject } from '@core/api/widget-api.models';

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

@ -83,6 +83,7 @@
<div fxLayout="row" fxLayoutAlign="space-between start">
<div class="tb-widget-title" fxLayout="column" fxLayoutAlign="center start" [fxShow]="widget.showWidgetTitlePanel">
<span [fxShow]="widget.showTitle"
[ngClass]="{'single-row': widget.hasTimewindow}"
[ngStyle]="widget.titleStyle"
[matTooltip]="widget.titleTooltip"
matTooltipClass="tb-tooltip-multiline"

8
ui-ngx/src/app/modules/home/components/dashboard/dashboard.component.scss

@ -76,6 +76,7 @@ div.tb-widget {
tb-timewindow {
font-size: 14px;
opacity: .85;
margin: 0;
}
.title {
@ -85,6 +86,13 @@ div.tb-widget {
line-height: 24px;
letter-spacing: .01em;
margin: 0;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
&.single-row{
-webkit-line-clamp: 1;
}
}
}

8
ui-ngx/src/app/modules/home/components/dashboard/layout-button.scss

@ -13,13 +13,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
:host ::ng-deep {
:host {
button.tb-layout-button {
width: 100%;
max-width: 240px;
height: 100%;
padding: 40px 20px;
}
&::ng-deep {
.mat-button-wrapper {
padding: 40px;
line-height: 18px;
span {
font-size: 18px;

18
ui-ngx/src/app/modules/home/components/dashboard/select-target-layout-dialog.component.html

@ -16,10 +16,10 @@
-->
<form #widgetForm="ngForm">
<mat-toolbar fxLayout="row" color="primary">
<mat-toolbar color="primary">
<h2 translate>layout.select</h2>
<span fxFlex></span>
<button mat-button mat-icon-button
<button mat-icon-button
(click)="cancel()"
type="button">
<mat-icon class="material-icons">close</mat-icon>
@ -30,16 +30,18 @@
<div mat-dialog-content>
<fieldset [disabled]="isLoading$ | async" fxLayout="column" fxLayoutGap="8px">
<div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="8px">
<button fxFlex fxLayout="column"
type="button" mat-button mat-raised-button color="primary"
<button fxFlex
mat-raised-button color="primary"
type="button"
class="tb-layout-button"
(click)="selectLayout('main')">
(click)="selectLayout('main')">
<span translate>layout.main</span>
</button>
<button fxFlex fxLayout="column"
type="button" mat-button mat-raised-button color="primary"
<button fxFlex
mat-raised-button color="primary"
type="button"
class="tb-layout-button"
(click)="selectLayout('right')">
(click)="selectLayout('right')">
<span translate>layout.right</span>
</button>
</div>

15
ui-ngx/src/app/modules/home/components/dashboard/select-target-state-dialog.component.html

@ -16,10 +16,10 @@
-->
<form #stateForm="ngForm" [formGroup]="stateFormGroup" (ngSubmit)="save()">
<mat-toolbar fxLayout="row" color="primary">
<mat-toolbar color="primary">
<h2 translate>dashboard.select-state</h2>
<span fxFlex></span>
<button mat-button mat-icon-button
<button mat-icon-button
(click)="cancel()"
type="button">
<mat-icon class="material-icons">close</mat-icon>
@ -31,7 +31,7 @@
<fieldset [disabled]="isLoading$ | async" fxLayout="column">
<mat-form-field class="mat-block">
<mat-label translate>dashboard.state</mat-label>
<mat-select required matInput formControlName="stateId">
<mat-select required formControlName="stateId">
<mat-option *ngFor="let stateItem of states | keyvalue" [value]="stateItem.key">
{{ stateItem.value.name }}
</mat-option>
@ -39,18 +39,17 @@
</mat-form-field>
</fieldset>
</div>
<div mat-dialog-actions fxLayout="row">
<span fxFlex></span>
<button mat-button mat-raised-button color="primary"
<div mat-dialog-actions fxLayoutAlign="end center">
<button mat-raised-button color="primary"
type="submit"
[disabled]="(isLoading$ | async) || stateFormGroup.invalid">
{{ 'action.select' | translate }}
</button>
<button mat-button color="primary"
style="margin-right: 20px;"
type="button"
[disabled]="(isLoading$ | async)"
(click)="cancel()" cdkFocusInitial>
(click)="cancel()"
cdkFocusInitial>
{{ 'action.cancel' | translate }}
</button>
</div>

3
ui-ngx/src/app/modules/home/components/dashboard/select-target-state-dialog.component.ts

@ -22,11 +22,8 @@ import { AppState } from '@core/core.state';
import { FormBuilder, FormControl, FormGroup, FormGroupDirective, NgForm, Validators } from '@angular/forms';
import { Router } from '@angular/router';
import { DialogComponent } from '@app/shared/components/dialog.component';
import { UtilsService } from '@core/services/utils.service';
import { TranslateService } from '@ngx-translate/core';
import { DashboardState } from '@app/shared/models/dashboard.models';
import { DashboardUtilsService } from '@core/services/dashboard-utils.service';
import { DashboardService } from '@core/http/dashboard.service';
export interface SelectTargetStateDialogData {
states: {[id: string]: DashboardState };

2
ui-ngx/src/app/modules/home/components/details-panel.component.html

@ -17,7 +17,7 @@
-->
<header>
<mat-toolbar class="details-toolbar" color="primary" [ngStyle]="{height: headerHeightPx+'px'}">
<div class="mat-toolbar-tools" fxFlex fxLayout="row" fxLayoutAlign="start center" style="height: 100%;">
<div class="mat-toolbar-tools" fxLayout="row" fxLayoutAlign="start center" style="height: 100%;">
<div class="mat-toolbar-tools tb-details-title-header" fxFlex fxLayout="column" fxLayoutAlign="start start">
<span class="tb-details-title">{{ headerTitle }}</span>
<span class="tb-details-subtitle">{{ headerSubtitle }}</span>

2
ui-ngx/src/app/modules/home/components/details-panel.component.scss

@ -45,7 +45,7 @@
white-space: nowrap;
@media #{$mat-gt-sm} {
font-size: 1.6rem;
font-size: 1.5rem;
}
}

6
ui-ngx/src/app/modules/home/components/entity/entity-filter-view.component.ts

@ -102,14 +102,14 @@ export class EntityFilterViewComponent implements ControlValueAccessor {
}
break;
case AliasFilterType.entityViewType:
const entityViewType = this.filter.entityViewType;
const entityView = this.filter.entityViewType;
prefix = this.filter.entityViewNameFilter;
if (prefix && prefix.length) {
this.filterDisplayValue = this.translate.instant('alias.filter-type-entity-view-type-and-name-description',
{entityViewType, prefix});
{entityView, prefix});
} else {
this.filterDisplayValue = this.translate.instant('alias.filter-type-entity-view-type-description',
{entityViewType});
{entityView});
}
break;
case AliasFilterType.relationsQuery:

12
ui-ngx/src/app/modules/home/components/entity/entity-filter.component.html

@ -141,10 +141,10 @@
<label class="tb-small root-state-entity-label" translate>alias.last-level-relation</label>
</section>
</div>
<div fxFlex fxLayoutGap="8px" fxLayout="row">
<div fxFlex fxLayoutGap="8px" fxLayout="row" fxLayout.xs="column">
<mat-form-field class="mat-block" style="min-width: 100px;">
<mat-label translate>relation.direction</mat-label>
<mat-select required matInput formControlName="direction">
<mat-select required formControlName="direction">
<mat-option *ngFor="let type of directionTypes" [value]="type">
{{ directionTypeTranslations.get(directionTypeEnum[type]) | translate }}
</mat-option>
@ -172,7 +172,7 @@
entityFilterFormGroup.get('type').value === aliasFilterType.entityViewSearchQuery ?
entityFilterFormGroup.get('type').value : ''">
<label class="tb-small">{{ 'alias.root-entity' | translate }}</label>
<section class="tb-root-state-entity-switch" fxLayout="row" fxLayoutAlign="start center" style="padding-left: 0px;">
<section class="tb-root-state-entity-switch" fxLayout="row" fxLayoutAlign="start center" style="padding-left: 0;">
<mat-slide-toggle class="root-state-entity-switch"
formControlName="rootStateEntity">
</mat-slide-toggle>
@ -200,17 +200,17 @@
</div>
</div>
<div fxFlex fxLayout="row">
<section class="tb-root-state-entity-switch" fxLayout="row" fxLayoutAlign="start center" style="padding-left: 0px;">
<section class="tb-root-state-entity-switch" fxLayout="row" fxLayoutAlign="start center" style="padding-left: 0;">
<mat-slide-toggle class="root-state-entity-switch"
formControlName="fetchLastLevelOnly">
</mat-slide-toggle>
<label class="tb-small root-state-entity-label" translate>alias.last-level-relation</label>
</section>
</div>
<div fxFlex fxLayoutGap="8px" fxLayout="row">
<div fxFlex fxLayoutGap="8px" fxLayout="row" fxLayout.xs="column">
<mat-form-field class="mat-block" style="min-width: 100px;">
<mat-label translate>relation.direction</mat-label>
<mat-select required matInput formControlName="direction">
<mat-select required formControlName="direction">
<mat-option *ngFor="let type of directionTypes" [value]="type">
{{ directionTypeTranslations.get(directionTypeEnum[type]) | translate }}
</mat-option>

60
ui-ngx/src/app/modules/home/components/relation/relation-filters.component.html

@ -16,35 +16,37 @@
-->
<div class="tb-relation-filters" [formGroup]="relationFiltersFormGroup">
<div class="header" [fxShow]="relationFiltersFormArray().length">
<div fxLayout="row" fxLayoutAlign="start center">
<span class="cell" style="width: 200px; min-width: 200px;" translate>relation.type</span>
<span class="cell" fxFlex translate>entity.entity-types</span>
<span class="cell" style="width: 40px; min-width: 40px;">&nbsp;</span>
<div class="container">
<div class="header" [fxShow]="relationFiltersFormArray().length">
<div fxLayout="row" fxLayoutAlign="start center">
<span class="cell" style="width: 200px; min-width: 200px;" translate>relation.type</span>
<span class="cell" fxFlex translate>entity.entity-types</span>
<span class="cell" style="width: 40px; min-width: 40px;">&nbsp;</span>
</div>
</div>
</div>
<div class="body" [fxShow]="relationFiltersFormArray().length">
<div class="row" fxFlex fxLayout="row"
fxLayoutAlign="start center" formArrayName="relationFilters"
*ngFor="let relationFilterControl of relationFiltersFormArray().controls; let $index = index">
<div class="mat-elevation-z1" fxFlex fxLayout="row" fxLayoutAlign="start center">
<tb-relation-type-autocomplete
class="cell" style="width: 200px; min-width: 200px;"
[formControl]="relationFilterControl.get('relationType')">
</tb-relation-type-autocomplete>
<tb-entity-type-list class="cell" fxFlex
[allowedEntityTypes]="allowedEntityTypes"
[formControl]="relationFilterControl.get('entityTypes')">
</tb-entity-type-list>
<button mat-button mat-icon-button color="primary"
type="button"
style="width: 40px; min-width: 40px;"
(click)="removeFilter($index)"
[disabled]="isLoading$ | async"
matTooltip="{{ 'relation.remove-relation-filter' | translate }}"
matTooltipPosition="above">
<mat-icon>close</mat-icon>
</button>
<div class="body" [fxShow]="relationFiltersFormArray().length">
<div class="row" fxFlex fxLayout="row"
fxLayoutAlign="start center" formArrayName="relationFilters"
*ngFor="let relationFilterControl of relationFiltersFormArray().controls; let $index = index">
<div class="mat-elevation-z1" fxFlex fxLayout="row" fxLayoutAlign="start center">
<tb-relation-type-autocomplete
class="cell" style="width: 200px; min-width: 200px;"
[formControl]="relationFilterControl.get('relationType')">
</tb-relation-type-autocomplete>
<tb-entity-type-list class="cell" fxFlex
[allowedEntityTypes]="allowedEntityTypes"
[formControl]="relationFilterControl.get('entityTypes')">
</tb-entity-type-list>
<button mat-icon-button color="primary"
type="button"
style="width: 40px; min-width: 40px;"
(click)="removeFilter($index)"
[disabled]="isLoading$ | async"
matTooltip="{{ 'relation.remove-relation-filter' | translate }}"
matTooltipPosition="above">
<mat-icon>close</mat-icon>
</button>
</div>
</div>
</div>
</div>
@ -53,7 +55,7 @@
class="tb-prompt" translate>relation.any-relation</span>
</div>
<div>
<button mat-button mat-raised-button color="primary"
<button mat-raised-button color="primary"
[disabled]="isLoading$ | async"
(click)="addFilter()"
type="button"

24
ui-ngx/src/app/modules/home/components/relation/relation-filters.component.scss

@ -15,10 +15,17 @@
*/
:host {
.tb-relation-filters {
max-width: calc(100vw - 48px);
overflow: hidden;
.container{
width: 100%;
overflow: auto;
}
.header {
padding-right: 5px;
padding-bottom: 5px;
padding-left: 5px;
width: max-content;
padding: 0 5px 5px;
.cell {
padding-right: 5px;
@ -31,11 +38,8 @@
}
.body {
max-height: 300px;
padding-right: 5px;
padding-bottom: 20px;
padding-left: 5px;
overflow: auto;
width: max-content;
padding: 0 5px 20px;
.row {
padding-top: 5px;
@ -46,6 +50,10 @@
padding-left: 5px;
}
}
.any-filter{
margin: 10px 0 20px;
}
}
}

16
ui-ngx/src/app/modules/home/components/relation/relation-filters.component.ts

@ -14,21 +14,17 @@
/// limitations under the License.
///
import { Component, EventEmitter, forwardRef, Input, OnInit, Output } from '@angular/core';
import { Component, forwardRef, Input, OnInit } from '@angular/core';
import {
AbstractControl,
ControlValueAccessor, FormArray,
FormBuilder, FormControl,
ControlValueAccessor,
FormArray,
FormBuilder,
FormGroup,
NG_VALUE_ACCESSOR,
ValidatorFn,
Validators
NG_VALUE_ACCESSOR
} from '@angular/forms';
import { AliasFilterType, aliasFilterTypeTranslationMap, EntityAliasFilter } from '@shared/models/alias.models';
import { AliasEntityType, EntityType } from '@shared/models/entity-type.models';
import { TranslateService } from '@ngx-translate/core';
import { EntityService } from '@core/http/entity.service';
import { EntitySearchDirection, entitySearchDirectionTranslations, EntityTypeFilter } from '@shared/models/relation.models';
import { EntityTypeFilter } from '@shared/models/relation.models';
import { PageComponent } from '@shared/components/page.component';
import { Store } from '@ngrx/store';
import { AppState } from '@core/core.state';

4
ui-ngx/src/app/modules/home/components/relation/relation-table.component.html

@ -86,7 +86,7 @@
</div>
</mat-toolbar>
<div fxFlex class="table-container">
<mat-table [dataSource]="dataSource"
<table mat-table [dataSource]="dataSource"
matSort [matSortActive]="pageLink.sortOrder.property" [matSortDirection]="pageLink.sortDirection()" matSortDisableClear>
<ng-container matColumnDef="select" sticky>
<mat-header-cell *matHeaderCellDef style="width: 30px;">
@ -156,7 +156,7 @@
<mat-row [ngClass]="{'mat-row-select': true,
'mat-selected': dataSource.selection.isSelected(relation)}"
*matRowDef="let relation; columns: displayedColumns;" (click)="dataSource.selection.toggle(relation)"></mat-row>
</mat-table>
</table>
<span [fxShow]="dataSource.isEmpty() | async"
fxLayoutAlign="center center"
class="no-data-found" translate>{{ 'relation.no-relations-text' }}</span>

2
ui-ngx/src/app/modules/home/components/widget/action/custom-action-pretty-editor.component.html

@ -17,7 +17,7 @@
-->
<div class="tb-custom-action-pretty mat-elevation-z1" tb-fullscreen [fullscreen]="fullscreen">
<div fxLayout="row" fxLayoutAlign="end center" class="tb-action-expand-button" [ngClass]="{'tb-fullscreen-editor': fullscreen}">
<button mat-button fxHide.xs fxHide.sm
<button mat-button fxHide.lt-md
matTooltip="{{ 'widget.toggle-fullscreen' | translate }}"
matTooltipPosition="above"
(click)="fullscreen = !fullscreen">

34
ui-ngx/src/app/modules/home/components/widget/action/custom-action-pretty-editor.component.ts

@ -19,46 +19,22 @@
import {
AfterViewInit,
ChangeDetectionStrategy,
Component,
ElementRef,
forwardRef,
Input,
OnDestroy,
OnInit,
ViewChild, ViewEncapsulation, ViewChildren, QueryList, ComponentFactoryResolver
QueryList,
ViewChildren,
ViewEncapsulation
} from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
import { TranslateService } from '@ngx-translate/core';
import { PageComponent } from '@shared/components/page.component';
import { Store } from '@ngrx/store';
import { AppState } from '@core/core.state';
import { MatDialog } from '@angular/material/dialog';
import { DialogService } from '@core/services/dialog.service';
import { PageLink } from '@shared/models/page/page-link';
import { Direction, SortOrder } from '@shared/models/page/sort-order';
import { MatPaginator } from '@angular/material/paginator';
import { MatSort } from '@angular/material/sort';
import { combineLatest, fromEvent, merge } from 'rxjs';
import { debounceTime, distinctUntilChanged, tap } from 'rxjs/operators';
import {
WidgetActionDescriptorInfo,
WidgetActionsData,
WidgetActionsDatasource,
WidgetActionCallbacks, toWidgetActionDescriptor
} from '@home/components/widget/action/manage-widget-actions.component.models';
import { UtilsService } from '@core/services/utils.service';
import { EntityRelation, EntitySearchDirection, RelationTypeGroup } from '@shared/models/relation.models';
import { RelationDialogComponent, RelationDialogData } from '@home/components/relation/relation-dialog.component';
import { CustomActionDescriptor, WidgetActionDescriptor, WidgetActionSource } from '@shared/models/widget.models';
import {
WidgetActionDialogComponent,
WidgetActionDialogData
} from '@home/components/widget/action/widget-action-dialog.component';
import { deepClone } from '@core/utils';
import { TbAnchorComponent } from '@shared/components/tb-anchor.component';
import { CustomActionPrettyResourcesTabsComponent } from '@home/components/widget/action/custom-action-pretty-resources-tabs.component';
import { MatTab, MatTabGroup } from '@angular/material/tabs';
import { combineLatest } from 'rxjs';
import { CustomActionDescriptor } from '@shared/models/widget.models';
@Component({
selector: 'tb-custom-action-pretty-editor',

4
ui-ngx/src/app/modules/home/components/widget/action/custom-action-pretty-resources-tabs.component.html

@ -23,12 +23,12 @@
fxLayoutAlign="start center"
*ngFor="let resource of action.customResources; let i = index" >
<mat-form-field fxFlex class="mat-block resource-field" floatLabel="never"
style="margin: 10px 0px 0px 0px; max-height: 40px;">
style="margin: 10px 0 0; max-height: 40px;">
<input required matInput [(ngModel)]="resource.url"
(ngModelChange)="notifyActionUpdated()"
placeholder="{{ 'widget.resource-url' | translate }}"/>
</mat-form-field>
<button mat-button mat-icon-button color="primary"
<button mat-icon-button color="primary"
[disabled]="isLoading$ | async"
type="button"
(click)="removeResource(i)"

7
ui-ngx/src/app/modules/home/components/widget/action/custom-action-pretty-resources-tabs.component.ts

@ -22,9 +22,10 @@ import {
OnChanges,
OnDestroy,
OnInit,
Output, QueryList,
Output,
SimpleChanges,
ViewChild, ViewChildren, ViewEncapsulation
ViewChild,
ViewEncapsulation
} from '@angular/core';
import { TranslateService } from '@ngx-translate/core';
import { PageComponent } from '@shared/components/page.component';
@ -34,8 +35,6 @@ import { CustomActionDescriptor } from '@shared/models/widget.models';
import * as ace from 'ace-builds';
import { CancelAnimationFrame, RafService } from '@core/services/raf.service';
import { css_beautify, html_beautify } from 'js-beautify';
import { MatTab } from '@angular/material/tabs';
import { BehaviorSubject } from 'rxjs';
@Component({
selector: 'tb-custom-action-pretty-resources-tabs',

16
ui-ngx/src/app/modules/home/components/widget/action/manage-widget-actions.component.html

@ -21,14 +21,14 @@
<div class="mat-toolbar-tools">
<span class="tb-entity-table-title" translate>widget-config.actions</span>
<span fxFlex></span>
<button mat-button mat-icon-button [disabled]="isLoading$ | async"
<button mat-icon-button [disabled]="isLoading$ | async"
type="button"
(click)="addAction($event)"
matTooltip="{{ 'widget-config.add-action' | translate }}"
matTooltipPosition="above">
<mat-icon>add</mat-icon>
</button>
<button mat-button mat-icon-button [disabled]="isLoading$ | async" (click)="enterFilterMode()"
<button mat-icon-button [disabled]="isLoading$ | async" (click)="enterFilterMode()"
type="button"
matTooltip="{{ 'action.search' | translate }}"
matTooltipPosition="above">
@ -38,7 +38,7 @@
</mat-toolbar>
<mat-toolbar class="mat-table-toolbar" [fxShow]="textSearchMode">
<div class="mat-toolbar-tools">
<button mat-button mat-icon-button
<button mat-icon-button
type="button"
matTooltip="{{ 'widget-config.search-actions' | translate }}"
matTooltipPosition="above">
@ -50,7 +50,7 @@
[(ngModel)]="pageLink.textSearch"
placeholder="{{ 'widget-config.search-actions' | translate }}"/>
</mat-form-field>
<button mat-button mat-icon-button (click)="exitFilterMode()"
<button mat-icon-button (click)="exitFilterMode()"
type="button"
matTooltip="{{ 'action.close' | translate }}"
matTooltipPosition="above">
@ -59,7 +59,7 @@
</div>
</mat-toolbar>
<div fxFlex class="table-container">
<mat-table [dataSource]="dataSource"
<table mat-table [dataSource]="dataSource"
matSort [matSortActive]="pageLink.sortOrder.property" [matSortDirection]="pageLink.sortDirection()" matSortDisableClear>
<ng-container matColumnDef="actionSourceName">
<mat-header-cell *matHeaderCellDef mat-sort-header style="width: 20%"> {{ 'widget-config.action-source' | translate }} </mat-header-cell>
@ -90,14 +90,14 @@
</mat-header-cell>
<mat-cell *matCellDef="let action">
<div fxFlex fxLayout="row" fxLayoutAlign="end">
<button mat-button mat-icon-button [disabled]="isLoading$ | async"
<button mat-icon-button [disabled]="isLoading$ | async"
type="button"
matTooltip="{{ 'widget-config.edit-action' | translate }}"
matTooltipPosition="above"
(click)="editAction($event, action)">
<mat-icon>edit</mat-icon>
</button>
<button mat-button mat-icon-button [disabled]="isLoading$ | async"
<button mat-icon-button [disabled]="isLoading$ | async"
type="button"
matTooltip="{{ 'widget-config.delete-action' | translate }}"
matTooltipPosition="above"
@ -110,7 +110,7 @@
<mat-header-row [ngClass]="{'mat-row-select': true}" *matHeaderRowDef="displayedColumns; sticky: true"></mat-header-row>
<mat-row [ngClass]="{'mat-row-select': true}"
*matRowDef="let action; columns: displayedColumns;"></mat-row>
</mat-table>
</table>
<span [fxShow]="dataSource.isEmpty() | async"
fxLayoutAlign="center center"
class="no-data-found" translate>{{ 'widget-config.no-actions-text' }}</span>

15
ui-ngx/src/app/modules/home/components/widget/action/manage-widget-actions.component.models.ts

@ -14,19 +14,18 @@
/// limitations under the License.
///
import { WidgetActionDescriptor, WidgetActionSource,
widgetActionTypeTranslationMap, CustomActionDescriptor } from '@app/shared/models/widget.models';
import {
CustomActionDescriptor,
WidgetActionDescriptor,
WidgetActionSource,
widgetActionTypeTranslationMap
} from '@app/shared/models/widget.models';
import { CollectionViewer, DataSource } from '@angular/cdk/collections';
import { EntityRelationInfo, EntitySearchDirection } from '@shared/models/relation.models';
import { BehaviorSubject, Observable, of, ReplaySubject } from 'rxjs';
import { emptyPageData, PageData } from '@shared/models/page/page-data';
import { SelectionModel } from '@angular/cdk/collections';
import { EntityRelationService } from '@core/http/entity-relation.service';
import { TranslateService } from '@ngx-translate/core';
import { EntityId } from '@shared/models/id/entity-id';
import { PageLink } from '@shared/models/page/page-link';
import { catchError, map, publishReplay, refCount, share, take, tap } from 'rxjs/operators';
import { entityTypeTranslations } from '@shared/models/entity-type.models';
import { catchError, map, publishReplay, refCount } from 'rxjs/operators';
import { UtilsService } from '@core/services/utils.service';
import { deepClone, isDefined, isUndefined } from '@core/utils';

19
ui-ngx/src/app/modules/home/components/widget/action/manage-widget-actions.component.ts

@ -14,17 +14,7 @@
/// limitations under the License.
///
import {
AfterViewInit,
ChangeDetectionStrategy,
Component,
ElementRef,
forwardRef,
Input,
OnDestroy,
OnInit,
ViewChild
} from '@angular/core';
import { AfterViewInit, Component, ElementRef, forwardRef, Input, OnDestroy, OnInit, ViewChild } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
import { TranslateService } from '@ngx-translate/core';
import { PageComponent } from '@shared/components/page.component';
@ -39,14 +29,13 @@ import { MatSort } from '@angular/material/sort';
import { fromEvent, merge } from 'rxjs';
import { debounceTime, distinctUntilChanged, tap } from 'rxjs/operators';
import {
toWidgetActionDescriptor,
WidgetActionCallbacks,
WidgetActionDescriptorInfo,
WidgetActionsData,
WidgetActionsDatasource,
WidgetActionCallbacks, toWidgetActionDescriptor
WidgetActionsDatasource
} from '@home/components/widget/action/manage-widget-actions.component.models';
import { UtilsService } from '@core/services/utils.service';
import { EntityRelation, EntitySearchDirection, RelationTypeGroup } from '@shared/models/relation.models';
import { RelationDialogComponent, RelationDialogData } from '@home/components/relation/relation-dialog.component';
import { WidgetActionDescriptor, WidgetActionSource } from '@shared/models/widget.models';
import {
WidgetActionDialogComponent,

20
ui-ngx/src/app/modules/home/components/widget/action/widget-action-dialog.component.html

@ -15,8 +15,8 @@
limitations under the License.
-->
<form #widgetActionForm="ngForm" [formGroup]="widgetActionFormGroup" (ngSubmit)="save()" style="min-width: 600px;">
<mat-toolbar fxLayout="row" color="primary">
<form #widgetActionForm="ngForm" [formGroup]="widgetActionFormGroup" (ngSubmit)="save()" style="min-width: 480px;">
<mat-toolbar color="primary">
<h2>{{ (isAdd ? 'widget-config.add-action' : 'widget-config.edit-action' ) | translate }}</h2>
<span fxFlex></span>
<button mat-button mat-icon-button
@ -32,7 +32,7 @@
<fieldset [disabled]="isLoading$ | async">
<mat-form-field class="mat-block">
<mat-label translate>widget-config.action-source</mat-label>
<mat-select required matInput formControlName="actionSourceId">
<mat-select required formControlName="actionSourceId">
<mat-option *ngFor="let actionSourceItem of data.actionsData.actionSources | keyvalue" [value]="actionSourceItem.key">
{{ actionSourceName(actionSourceItem.value) }}
</mat-option>
@ -41,7 +41,7 @@
{{ 'widget-config.action-source-required' | translate }}
</mat-error>
</mat-form-field>
<mat-form-field class="mat-block" style="padding-bottom: 20px;">
<mat-form-field class="mat-block">
<mat-label translate>widget-config.action-name</mat-label>
<input required matInput formControlName="name">
<mat-error *ngIf="widgetActionFormGroup.get('name').hasError('required')">
@ -56,7 +56,7 @@
</tb-material-icon-select>
<mat-form-field class="mat-block">
<mat-label translate>widget-config.action-type</mat-label>
<mat-select required matInput formControlName="type">
<mat-select required formControlName="type">
<mat-option *ngFor="let actionType of widgetActionTypes" [value]="actionType">
{{ widgetActionTypeTranslations.get(widgetActionType[actionType]) | translate }}
</mat-option>
@ -67,7 +67,7 @@
</mat-form-field>
<section fxLayout="column" [formGroup]="actionTypeFormGroup" [ngSwitch]="widgetActionFormGroup.get('type').value">
<ng-template [ngSwitchCase]="widgetActionType.openDashboard">
<div fxLayout="column" style="padding-bottom: 20px;">
<div fxLayout="column">
<div class="mat-caption tb-required"
style="padding-left: 3px; padding-bottom: 10px; color: rgba(0,0,0,0.57);" translate>widget-action.target-dashboard</div>
<tb-dashboard-autocomplete
@ -89,7 +89,7 @@
[matAutocomplete]="targetDashboardStateAutocomplete">
<button *ngIf="actionTypeFormGroup.get('targetDashboardStateId').value"
type="button"
matSuffix mat-button mat-icon-button aria-label="Clear"
matSuffix mat-icon-button aria-label="Clear"
(click)="clearTargetDashboardState()">
<mat-icon class="material-icons">close</mat-icon>
</button>
@ -145,15 +145,13 @@
</section>
</fieldset>
</div>
<div mat-dialog-actions fxLayout="row">
<span fxFlex></span>
<button mat-button mat-raised-button color="primary"
<div mat-dialog-actions fxLayoutAlign="end center">
<button mat-raised-button color="primary"
type="submit"
[disabled]="(isLoading$ | async) || widgetActionFormGroup.invalid || actionTypeFormGroup.invalid || (!widgetActionFormGroup.dirty && !actionTypeFormGroup.dirty)">
{{ (isAdd ? 'action.add' : 'action.save') | translate }}
</button>
<button mat-button color="primary"
style="margin-right: 20px;"
type="button"
[disabled]="(isLoading$ | async)"
(click)="cancel()" cdkFocusInitial>

20
ui-ngx/src/app/modules/home/components/widget/action/widget-action-dialog.component.scss

@ -0,0 +1,20 @@
/**
* Copyright © 2016-2020 The Thingsboard Authors
*
* 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.
*/
:host ::ng-deep {
.mat-checkbox-label {
white-space: normal;
}
}

2
ui-ngx/src/app/modules/home/components/widget/action/widget-action-dialog.component.ts

@ -55,7 +55,7 @@ export interface WidgetActionDialogData {
selector: 'tb-widget-action-dialog',
templateUrl: './widget-action-dialog.component.html',
providers: [{provide: ErrorStateMatcher, useExisting: WidgetActionDialogComponent}],
styleUrls: []
styleUrls: ['./widget-action-dialog.component.scss']
})
export class WidgetActionDialogComponent extends DialogComponent<WidgetActionDialogComponent,
WidgetActionDescriptorInfo> implements OnInit, ErrorStateMatcher {

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

@ -15,8 +15,8 @@
limitations under the License.
-->
<form #dataKeyForm="ngForm" [formGroup]="dataKeyFormGroup" (ngSubmit)="save()" style="width: 600px;">
<mat-toolbar fxLayout="row" color="primary">
<form #dataKeyForm="ngForm" [formGroup]="dataKeyFormGroup" (ngSubmit)="save()" style="min-width: 480px;">
<mat-toolbar color="primary">
<h2>{{ 'datakey.configuration' | translate }}</h2>
<span fxFlex></span>
<button mat-button mat-icon-button
@ -36,15 +36,13 @@
formControlName="dataKey">
</tb-data-key-config>
</div>
<div mat-dialog-actions fxLayout="row">
<span fxFlex></span>
<button mat-button mat-raised-button color="primary"
<div mat-dialog-actions fxLayoutAlign="end center">
<button mat-raised-button color="primary"
type="submit"
[disabled]="(isLoading$ | async) || dataKeyForm.invalid || !dataKeyForm.dirty">
{{ 'action.save' | translate }}
</button>
<button mat-button color="primary"
style="margin-right: 20px;"
type="button"
[disabled]="(isLoading$ | async)"
(click)="cancel()" cdkFocusInitial>

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

@ -17,5 +17,6 @@
.mat-dialog-content {
padding: 0 !important;
margin: 0 !important;
overflow: hidden;
}
}

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

@ -15,10 +15,9 @@
limitations under the License.
-->
<mat-tab-group class="tb-datakey-config" [ngClass]="{'tb-headless': !displayAdvanced}"
class="tb-datakey-config">
<mat-tab-group class="tb-datakey-config" [ngClass]="{'tb-headless': !displayAdvanced}">
<mat-tab [formGroup]="dataKeyFormGroup" label="{{ 'datakey.settings' | translate }}">
<div class="mat-content mat-padding" fxLayout="column">
<div class="mat-padding settings" fxLayout="column">
<mat-form-field class="mat-block" *ngIf="modelValue.type !== dataKeyTypes.function">
<mat-label>{{ 'entity.key' | translate }}</mat-label>
<input matInput type="text" placeholder="{{ 'entity.key-name' | translate }}"
@ -28,7 +27,7 @@
[matAutocomplete]="keyAutocomplete">
<button *ngIf="dataKeyFormGroup.get('name').value"
type="button"
matSuffix mat-button mat-icon-button aria-label="Clear"
matSuffix mat-icon-button aria-label="Clear"
(click)="clearKey()">
<mat-icon class="material-icons">close</mat-icon>
</button>
@ -40,7 +39,7 @@
</mat-option>
</mat-autocomplete>
</mat-form-field>
<div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="8px">
<div fxLayout="row" fxLayout.xs="column" fxLayoutAlign="start center" fxLayoutAlign.xs fxLayoutGap="8px">
<mat-form-field fxFlex class="mat-block">
<mat-label translate>datakey.label</mat-label>
<input matInput formControlName="label" required>
@ -53,7 +52,7 @@
formControlName="color">
</tb-color-input>
</div>
<div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="8px" *ngIf="modelValue.type !== dataKeyTypes.alarm">
<div fxLayout="row" fxLayout.xs="column" fxLayoutAlign="start center" fxLayoutAlign.xs fxLayoutGap="8px" *ngIf="modelValue.type !== dataKeyTypes.alarm">
<mat-form-field fxFlex>
<mat-label translate>datakey.units</mat-label>
<input matInput formControlName="units">
@ -94,12 +93,10 @@
</div>
</mat-tab>
<mat-tab [formGroup]="dataKeySettingsFormGroup" label="{{ 'datakey.advanced' | translate }}" *ngIf="displayAdvanced">
<div class="mat-content mat-padding" fxLayout="column">
<div style="overflow: auto;">
<tb-json-form
formControlName="settings">
</tb-json-form>
</div>
<div class="mat-padding" fxLayout="column">
<tb-json-form
formControlName="settings">
</tb-json-form>
</div>
</mat-tab>
</mat-tab-group>

22
ui-ngx/src/app/modules/home/components/widget/data-key-config.component.scss

@ -13,11 +13,21 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
@import '../../../../../scss/constants';
:host {
.tb-datakey-config {
min-width: 500px !important;
min-height: 500px !important;
height: 500px !important;
height: 100%;
.settings{
&> :first-child{
padding-top: 12px;
}
&> :nth-child(n){
padding-right: 12px;
padding-left: 12px;
}
}
}
}
@ -25,7 +35,11 @@
.tb-datakey-config {
.mat-tab-body.mat-tab-body-active {
.mat-tab-body-content > div {
height: 100%;
height: calc(65vh - 50px);
overflow: initial;
@media #{$mat-xs} {
height: 500px;
}
}
}
}

5
ui-ngx/src/app/modules/home/components/widget/data-keys.component.scss

@ -15,6 +15,8 @@
*/
:host {
.mat-chip.mat-standard-chip {
overflow: hidden;
.tb-attribute-chip {
max-width: 100%;
color: rgb(66, 66, 66);
@ -32,7 +34,8 @@
.tb-chip-labels {
display: flex;
flex-direction: row;
min-width: 0px;
align-items: flex-end;
min-width: 0;
.tb-chip-label {
overflow: hidden;
text-overflow: ellipsis;

14
ui-ngx/src/app/modules/home/components/widget/dialog/custom-dialog-container.component.ts

@ -16,23 +16,21 @@
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import {
Inject,
ComponentRef,
ElementRef,
ViewContainerRef,
Component,
ComponentFactory,
ComponentRef,
Inject,
Injector,
ReflectiveInjector,
Component,
OnDestroy
OnDestroy,
ViewContainerRef
} from '@angular/core';
import { DialogComponent } from '@shared/components/dialog.component';
import { Store } from '@ngrx/store';
import { AppState } from '@core/core.state';
import { Router } from '@angular/router';
import {
CustomDialogComponent,
CUSTOM_DIALOG_DATA,
CustomDialogComponent,
CustomDialogData
} from '@home/components/widget/dialog/custom-dialog.component';

3
ui-ngx/src/app/modules/home/components/widget/dialog/custom-dialog.component.ts

@ -14,9 +14,8 @@
/// limitations under the License.
///
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { MatDialogRef } from '@angular/material/dialog';
import { Inject, InjectionToken } from '@angular/core';
import { DialogComponent } from '@shared/components/dialog.component';
import { Store } from '@ngrx/store';
import { AppState } from '@core/core.state';
import { Router } from '@angular/router';

1
ui-ngx/src/app/modules/home/components/widget/dynamic-widget.component.ts

@ -21,7 +21,6 @@ import { AppState } from '@core/core.state';
import { IDynamicWidgetComponent, WidgetContext } from '@home/models/widget-component.models';
import { HttpErrorResponse } from '@angular/common/http';
import { RafService } from '@core/services/raf.service';
import { ActionNotificationShow } from '@core/notification/notification.actions';
import {
NotificationHorizontalPosition,
NotificationType,

4
ui-ngx/src/app/modules/home/components/widget/lib/alarms-table-widget.component.html

@ -61,7 +61,7 @@
</div>
</mat-toolbar>
<div fxFlex class="table-container">
<mat-table [dataSource]="alarmsDatasource"
<table mat-table [dataSource]="alarmsDatasource"
matSort [matSortActive]="sortOrderProperty" [matSortDirection]="pageLink.sortDirection()" matSortDisableClear>
<ng-container matColumnDef="select" sticky>
<mat-header-cell *matHeaderCellDef style="width: 30px;">
@ -124,7 +124,7 @@
'tb-current-entity': alarmsDatasource.isCurrentAlarm(alarm)}"
*matRowDef="let alarm; columns: displayedColumns;"
(click)="onRowClick($event, alarm)"></mat-row>
</mat-table>
</table>
<span [fxShow]="alarmsDatasource.isEmpty() | async"
fxLayoutAlign="center center"
class="no-data-found" translate>alarm.no-alarms-prompt</span>

4
ui-ngx/src/app/modules/home/components/widget/lib/entities-table-widget.component.html

@ -38,7 +38,7 @@
</div>
</mat-toolbar>
<div fxFlex class="table-container">
<mat-table [dataSource]="entityDatasource"
<table mat-table [dataSource]="entityDatasource"
matSort [matSortActive]="sortOrderProperty" [matSortDirection]="pageLink.sortDirection()" matSortDisableClear>
<ng-container [matColumnDef]="column.def" *ngFor="let column of columns; trackBy: trackByColumnDef;">
<mat-header-cell [ngStyle]="headerStyle(column)" *matHeaderCellDef mat-sort-header> {{ column.title }} </mat-header-cell>
@ -85,7 +85,7 @@
<mat-row [ngClass]="{'tb-current-entity': entityDatasource.isCurrentEntity(entity)}"
*matRowDef="let entity; columns: displayedColumns;"
(click)="onRowClick($event, entity)" (dblclick)="onRowClick($event, entity, true)"></mat-row>
</mat-table>
</table>
<span [fxShow]="entityDatasource.isEmpty() | async"
fxLayoutAlign="center center"
class="no-data-found" translate>entity.no-entities-prompt</span>

4
ui-ngx/src/app/modules/home/components/widget/lib/timeseries-table-widget.component.html

@ -41,7 +41,7 @@
[(selectedIndex)]="sourceIndex" (selectedIndexChange)="onSourceIndexChanged()">
<mat-tab *ngFor="let source of sources" label="{{ source.datasource.name }}">
<div fxFlex class="table-container">
<mat-table [dataSource]="source.timeseriesDatasource" [trackBy]="trackByRowIndex"
<table mat-table [dataSource]="source.timeseriesDatasource" [trackBy]="trackByRowIndex"
matSort [matSortActive]="source.pageLink.sortOrder.property" [matSortDirection]="source.pageLink.sortDirection()" matSortDisableClear>
<ng-container *ngIf="showTimestamp" [matColumnDef]="'0'">
<mat-header-cell *matHeaderCellDef mat-sort-header>Timestamp</mat-header-cell>
@ -94,7 +94,7 @@
<mat-header-row *matHeaderRowDef="source.displayedColumns; sticky: true"></mat-header-row>
<mat-row *matRowDef="let row; columns: source.displayedColumns;"
(click)="onRowClick($event, row)"></mat-row>
</mat-table>
</table>
<span [fxShow]="source.timeseriesDatasource.isEmpty() | async"
fxLayoutAlign="center center"
class="no-data-found" translate>widget.no-data-found</span>

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

@ -16,12 +16,12 @@
-->
<mat-tab-group [ngClass]="{'tb-headless': (widgetType === widgetTypes.static && !displayAdvanced())}"
fxFlex class="tb-widget-config tb-absolute-fill" [(selectedIndex)]="selectedTab">
class="tb-widget-config tb-absolute-fill" [(selectedIndex)]="selectedTab">
<mat-tab label="{{ 'widget-config.data' | translate }}" [fxShow]="widgetType !== widgetTypes.static">
<div [formGroup]="dataSettings" class="mat-content mat-padding" fxLayout="column" fxLayoutGap="8px">
<div *ngIf="widgetType === widgetTypes.timeseries || widgetType === widgetTypes.alarm"
fxLayout="column" fxLayoutGap="8px" fxLayoutAlign="center" fxLayout.gt-sm="row" fxLayoutAlign.gt-sm="start center">
<div fxLayout="column" fxLayoutGap="8px" fxFlex>
<div *ngIf="widgetType === widgetTypes.timeseries || widgetType === widgetTypes.alarm" fxFlex="100"
fxLayout.xs="column" fxLayoutGap="8px" fxLayoutAlign.xs="center" fxLayout="row" fxLayoutAlign="start center">
<div fxLayout="column" fxLayoutGap="8px" fxFlex.gt-xs>
<mat-checkbox formControlName="useDashboardTimewindow">
{{ 'widget-config.use-dashboard-timewindow' | translate }}
</mat-checkbox>
@ -29,8 +29,10 @@
{{ 'widget-config.display-timewindow' | translate }}
</mat-checkbox>
</div>
<section fxFlex fxLayout="row" fxLayoutAlign="start center" style="margin-bottom: 16px;">
<span [ngClass]="{'tb-disabled-label': dataSettings.get('useDashboardTimewindow').value}" translate style="padding-right: 8px;">widget-config.timewindow</span>
<section fxLayout="row" fxLayoutAlign="start center" fxLayout.lt-lg="column" fxLayoutAlign.lt-lg="center start"
fxFlex.gt-xs style="margin-bottom: 16px;">
<span [ngClass]="{'tb-disabled-label': dataSettings.get('useDashboardTimewindow').value}" translate
style="padding-right: 8px;">widget-config.timewindow</span>
<tb-timewindow asButton="true"
isEdit="true"
aggregation="{{ widgetType === widgetTypes.timeseries }}"
@ -38,10 +40,11 @@
</section>
</div>
<div *ngIf="widgetType === widgetTypes.alarm" fxLayout="column" fxLayoutAlign="center">
<div fxLayout.gt-sm="row" fxLayoutAlign.gt-sm="start center" fxLayoutGap="8px">
<div fxLayout="column" fxLayoutAlign="center" fxLayout.gt-xs="row" fxLayoutAlign.gt-xs="start center"
fxLayoutGap="8px">
<mat-form-field fxFlex class="mat-block">
<mat-label translate>alarm.alarm-status</mat-label>
<mat-select matInput formControlName="alarmSearchStatus">
<mat-select formControlName="alarmSearchStatus">
<mat-option *ngFor="let searchStatus of alarmSearchStatuses" [value]="searchStatus">
{{ ('alarm.search-status.' + searchStatus) | translate }}
</mat-option>
@ -61,7 +64,8 @@
</mat-error>
</mat-form-field>
</div>
<div fxLayout.gt-sm="row" fxLayoutAlign.gt-sm="start center" fxLayoutGap="8px">
<div fxLayout="column" fxLayoutAlign="center" fxLayout.gt-xs="row" fxLayoutAlign.gt-xs="start center"
fxLayoutGap="8px">
<mat-form-field fxFlex class="mat-block">
<mat-label translate>alarm.max-count-load</mat-label>
<input matInput required
@ -100,7 +104,7 @@
<mat-panel-title fxLayout="column">
<div class="tb-panel-title" translate>widget-config.datasources</div>
<div *ngIf="modelValue?.typeParameters && modelValue?.typeParameters.maxDatasources > -1"
class="tb-hint">{{ 'widget-config.maximum-datasources' | translate:{count: modelValue?.typeParameters.maxDatasources} }}</div>
class="tb-panel-hint">{{ 'widget-config.maximum-datasources' | translate:{count: modelValue?.typeParameters.maxDatasources} }}</div>
</mat-panel-title>
</mat-expansion-panel-header>
<div *ngIf="datasourcesFormArray().length === 0; else datasourcesTemplate">
@ -133,7 +137,7 @@
fxLayout.gt-sm="row"
fxLayoutAlign.gt-sm="start center">
<mat-form-field class="tb-datasource-type">
<mat-select matInput formControlName="type">
<mat-select formControlName="type">
<mat-option *ngFor="let datasourceType of datasourceTypes" [value]="datasourceType">
{{ datasourceTypesTranslations.get(datasourceType) | translate }}
</mat-option>
@ -172,7 +176,7 @@
</section>
<button [disabled]="isLoading$ | async"
type="button"
mat-button mat-icon-button color="primary"
mat-icon-button color="primary"
style="min-width: 40px;"
(click)="removeDatasource($index)"
matTooltip="{{ 'widget-config.remove-datasource' | translate }}"
@ -186,7 +190,7 @@
<div fxFlex fxLayout="row" fxLayoutAlign="start center">
<button [disabled]="isLoading$ | async"
type="button"
mat-button mat-raised-button color="primary"
mat-raised-button color="primary"
[fxShow]="modelValue?.typeParameters &&
(modelValue?.typeParameters.maxDatasources == -1 || datasourcesFormArray().controls.length < modelValue?.typeParameters.maxDatasources)"
(click)="addDatasource()"
@ -228,7 +232,7 @@
fxLayout.gt-sm="row"
fxLayoutAlign.gt-sm="start center">
<mat-form-field class="tb-datasource-type">
<mat-select matInput formControlName="type">
<mat-select formControlName="type">
<mat-option *ngFor="let datasourceType of datasourceTypes" [value]="datasourceType">
{{ datasourceTypesTranslations.get(datasourceType) | translate }}
</mat-option>
@ -268,15 +272,20 @@
</div>
</mat-tab>
<mat-tab label="{{ 'widget-config.settings' | translate }}">
<div class="mat-content mat-padding"
fxLayout="column" fxLayoutGap="8px">
<div class="mat-content mat-padding" fxLayout="column" fxLayoutGap="8px">
<div [formGroup]="widgetSettings" fxLayout="column" fxLayoutGap="8px">
<span translate>widget-config.general-settings</span>
<div fxLayout="column" fxLayoutAlign="center" fxLayout.gt-sm="row" fxLayoutAlign.gt-sm="start center">
<mat-form-field fxFlex class="mat-block">
<mat-label translate>widget-config.title</mat-label>
<input matInput formControlName="title">
</mat-form-field>
<div fxLayout.xs="column" fxLayoutAlign.xs="center" fxLayout="row" fxLayoutAlign="start center">
<div fxLayout="column" fxLayoutAlign="center" fxFlex.sm="40%" fxFlex.gt-sm="30%">
<mat-form-field fxFlex class="mat-block">
<mat-label translate>widget-config.title</mat-label>
<input matInput formControlName="title">
</mat-form-field>
<mat-form-field fxFlex>
<mat-label translate>widget-config.title-tooltip</mat-label>
<input matInput formControlName="titleTooltip">
</mat-form-field>
</div>
<div fxFlex [fxShow]="widgetSettings.get('showTitle').value">
<tb-json-object-edit
[editorStyle]="{minHeight: '100px'}"
@ -286,46 +295,40 @@
></tb-json-object-edit>
</div>
</div>
<div fxLayout="column" fxLayoutAlign="center" fxLayout.gt-sm="row" fxLayoutAlign.gt-sm="start center"
<div fxLayout="column" fxLayoutAlign="center" fxLayout.gt-md="row" fxLayoutAlign.gt-md="start center" fxFlex="100%"
fxLayoutGap="8px">
<div fxLayout="row" fxFlex>
<mat-checkbox formControlName="showTitleIcon">
<div fxLayout.xs="column" fxLayoutAlign.xs="center" fxLayout="row" fxLayoutAlign="start center"
fxLayoutGap="8px" fxFlex.gt-md>
<mat-checkbox fxFlex formControlName="showTitleIcon">
{{ 'widget-config.display-icon' | translate }}
</mat-checkbox>
</div>
<div fxFlex>
<tb-material-icon-select
<tb-material-icon-select fxFlex
formControlName="titleIcon">
</tb-material-icon-select>
</div>
<tb-color-input fxFlex
label="{{'widget-config.icon-color' | translate}}"
icon="format_color_fill"
openOnInput
formControlName="iconColor">
</tb-color-input>
<mat-form-field fxFlex>
<mat-label translate>widget-config.icon-size</mat-label>
<input matInput formControlName="iconSize">
</mat-form-field>
<mat-form-field fxFlex>
<mat-label translate>widget-config.title-tooltip</mat-label>
<input matInput formControlName="titleTooltip">
</mat-form-field>
<div fxLayout.xs="column" fxLayoutAlign.xs="center" fxLayout="row" fxLayoutAlign="start center"
fxLayoutGap="8px" fxFlex.gt-md>
<tb-color-input fxFlex
label="{{'widget-config.icon-color' | translate}}"
icon="format_color_fill"
openOnInput
formControlName="iconColor">
</tb-color-input>
<mat-form-field fxFlex>
<mat-label translate>widget-config.icon-size</mat-label>
<input matInput formControlName="iconSize">
</mat-form-field>
</div>
</div>
<div fxLayout="column" fxLayoutAlign="center" fxLayout.gt-sm="row" fxLayoutAlign.gt-sm="start center"
<div fxLayout.xs="column" fxLayoutAlign.xs="center" fxLayout="row" fxLayoutAlign="start center"
fxLayoutGap="8px">
<div fxLayout="row">
<div fxLayout="column" fxLayoutAlign="center" fxLayoutGap="8px" fxFlex.sm="40%" fxFlex.gt-sm="30%">
<mat-checkbox formControlName="showTitle">
{{ 'widget-config.display-title' | translate }}
</mat-checkbox>
</div>
<div fxLayout="row">
<mat-checkbox formControlName="dropShadow">
{{ 'widget-config.drop-shadow' | translate }}
</mat-checkbox>
</div>
<div fxLayout="row">
<mat-checkbox formControlName="enableFullscreen">
{{ 'widget-config.enable-fullscreen' | translate }}
</mat-checkbox>
@ -339,30 +342,36 @@
></tb-json-object-edit>
</div>
</div>
<div fxLayout="column" fxLayoutAlign="center" fxLayout.gt-sm="row" fxLayoutAlign.gt-sm="start center"
fxLayoutGap="8px">
<tb-color-input fxFlex
label="{{'widget-config.background-color' | translate}}"
icon="format_color_fill"
openOnInput
formControlName="backgroundColor">
</tb-color-input>
<tb-color-input fxFlex
label="{{'widget-config.text-color' | translate}}"
icon="format_color_fill"
openOnInput
formControlName="color">
</tb-color-input>
<mat-form-field fxFlex>
<mat-label translate>widget-config.padding</mat-label>
<input matInput formControlName="padding">
</mat-form-field>
<mat-form-field fxFlex>
<mat-label translate>widget-config.margin</mat-label>
<input matInput formControlName="margin">
</mat-form-field>
<div fxLayout="column" fxLayoutAlign="center" fxLayout.gt-md="row" fxLayoutAlign.gt-md="start center"
fxFlex="100%" fxLayoutGap="8px">
<div fxLayout.xs="column" fxLayoutAlign.xs="center" fxLayout="row" fxLayoutAlign="start center"
fxLayoutGap="8px" fxFlex.gt-md>
<tb-color-input fxFlex
label="{{'widget-config.background-color' | translate}}"
icon="format_color_fill"
openOnInput
formControlName="backgroundColor">
</tb-color-input>
<tb-color-input fxFlex
label="{{'widget-config.text-color' | translate}}"
icon="format_color_fill"
openOnInput
formControlName="color">
</tb-color-input>
</div>
<div fxLayout.xs="column" fxLayoutAlign.xs="center" fxLayout="row" fxLayoutAlign="start center"
fxLayoutGap="8px" fxFlex.gt-md>
<mat-form-field fxFlex>
<mat-label translate>widget-config.padding</mat-label>
<input matInput formControlName="padding">
</mat-form-field>
<mat-form-field fxFlex>
<mat-label translate>widget-config.margin</mat-label>
<input matInput formControlName="margin">
</mat-form-field>
</div>
</div>
<div fxLayout="column" fxLayoutAlign="center" fxLayout.gt-sm="row" fxLayoutAlign.gt-sm="start center"
<div fxLayout.xs="column" fxLayoutAlign.xs="center" fxLayout="row" fxLayoutAlign="start center"
fxLayoutGap="8px">
<mat-form-field fxFlex>
<mat-label translate>widget-config.units</mat-label>
@ -373,14 +382,13 @@
<input matInput formControlName="decimals" type="number" min="0" max="15" step="1">
</mat-form-field>
</div>
<div [fxShow]="widgetType === widgetTypes.timeseries ||
widgetType === widgetTypes.latest"
fxLayout="column" fxLayoutAlign="center" fxLayout.gt-sm="row" fxLayoutAlign.gt-sm="start center"
fxLayoutGap="8px">
<mat-checkbox fxFlex formControlName="showLegend">
<div [fxShow]="widgetType === widgetTypes.timeseries || widgetType === widgetTypes.latest"
fxLayout.xs="column" fxLayoutAlign.xs="center" fxLayout="row" fxLayoutAlign="start center"
fxLayoutGap="8px" fxFlex="100%">
<mat-checkbox fxFlex.gt-xs formControlName="showLegend">
{{ 'widget-config.display-legend' | translate }}
</mat-checkbox>
<section fxFlex fxLayout="row" fxLayoutAlign="start center" style="margin-bottom: 16px;">
<section fxFlex.gt-xs fxLayout="row" fxLayoutAlign="start center" style="margin-bottom: 16px;">
<tb-legend-config formControlName="legendConfig">
</tb-legend-config>
</section>
@ -388,7 +396,7 @@
</div>
<div [formGroup]="layoutSettings" fxLayout="column" fxLayoutGap="8px">
<span translate>widget-config.mobile-mode-settings</span>
<div fxLayout="column" fxLayoutAlign="center" fxLayout.gt-sm="row" fxLayoutAlign.gt-sm="start center"
<div fxLayout.xs="column" fxLayoutAlign.xs="center" fxLayout="row" fxLayoutAlign="start center"
fxLayoutGap="8px">
<mat-form-field fxFlex>
<mat-label translate>widget-config.order</mat-label>

24
ui-ngx/src/app/modules/home/components/widget/widget-config.component.scss

@ -57,14 +57,26 @@
right: 0;
bottom: 0;
}
.mat-tab-body.mat-tab-body-active {
.mat-tab-body-content > div {
height: 100%;
}
.tb-panel-hint {
font-size: 12px;
color: #808080;
}
//.mat-tab-body.mat-tab-body-active {
// .mat-tab-body-content > div {
// height: 100%;
// }
//}
.mat-checkbox-label {
white-space: normal;
}
.mat-expansion-panel {
&.tb-datasources.mat-expanded {
overflow: visible;
&.tb-datasources{
&.mat-expanded {
overflow: visible;
}
.mat-expansion-panel-body{
padding: 0 12px 16px;
}
}
.mat-expansion-panel-content {
font: inherit;

13
ui-ngx/src/app/modules/home/pages/dashboard/add-widget-dialog.component.html

@ -16,11 +16,11 @@
-->
<form #widgetForm="ngForm" [formGroup]="widgetFormGroup" (ngSubmit)="add()" style="width: 900px;">
<mat-toolbar fxLayout="row" color="primary">
<mat-toolbar color="primary">
<h2 translate>widget.add</h2>
<span fxFlex></span>
<div [tb-help]="helpLinkIdForWidgetType()"></div>
<button mat-button mat-icon-button
<button mat-icon-button
(click)="cancel()"
type="button">
<mat-icon class="material-icons">close</mat-icon>
@ -39,18 +39,17 @@
</tb-widget-config>
</fieldset>
</div>
<div mat-dialog-actions fxLayout="row">
<span fxFlex></span>
<button mat-button mat-raised-button color="primary"
<div mat-dialog-actions fxLayoutAlign="end center">
<button mat-raised-button color="primary"
type="submit"
[disabled]="(isLoading$ | async) || widgetFormGroup.invalid">
{{ 'action.add' | translate }}
</button>
<button mat-button color="primary"
style="margin-right: 20px;"
type="button"
[disabled]="(isLoading$ | async)"
(click)="cancel()" cdkFocusInitial>
(click)="cancel()"
cdkFocusInitial>
{{ 'action.cancel' | translate }}
</button>
</div>

8
ui-ngx/src/app/modules/home/pages/dashboard/add-widget-dialog.component.ts

@ -23,9 +23,6 @@ import { FormBuilder, FormControl, FormGroup, FormGroupDirective, NgForm } from
import { Router } from '@angular/router';
import { DialogComponent } from '@app/shared/components/dialog.component';
import { Widget, widgetTypesData } from '@shared/models/widget.models';
import { UtilsService } from '@core/services/utils.service';
import { TranslateService } from '@ngx-translate/core';
import { EntityService } from '@core/http/entity.service';
import { Dashboard } from '@app/shared/models/dashboard.models';
import { IAliasController } from '@core/api/widget-api.models';
import { WidgetConfigComponentData, WidgetInfo } from '@home/models/widget-component.models';
@ -60,10 +57,7 @@ export class AddWidgetDialogComponent extends DialogComponent<AddWidgetDialogCom
@Inject(MAT_DIALOG_DATA) public data: AddWidgetDialogData,
@SkipSelf() private errorStateMatcher: ErrorStateMatcher,
public dialogRef: MatDialogRef<AddWidgetDialogComponent, Widget>,
private fb: FormBuilder,
private utils: UtilsService,
private translate: TranslateService,
private entityService: EntityService) {
private fb: FormBuilder) {
super(store, router, dialogRef);
this.dashboard = this.data.dashboard;

24
ui-ngx/src/app/modules/home/pages/dashboard/dashboard-page.component.html

@ -27,27 +27,27 @@
fxLayoutAlign="center stretch" fxLayoutAlign.gt-sm="space-between center">
<div class="tb-dashboard-action-panel" fxFlex.md="30" fxLayout="row-reverse"
fxLayoutAlign.gt-sm="start center" fxLayoutAlign="space-between center" fxLayoutGap="12px">
<button [fxShow]="showCloseToolbar()" mat-button mat-icon-button class="close-action"
<button [fxShow]="showCloseToolbar()" mat-icon-button class="close-action"
matTooltip="{{ 'dashboard.close-toolbar' | translate }}"
matTooltipPosition="below"
(click)="closeToolbar()">
<mat-icon>arrow_forward</mat-icon>
</button>
<tb-user-menu *ngIf="!isPublicUser() && forceFullscreen" fxHide.xs fxHide.sm displayUserInfo="true">
<tb-user-menu *ngIf="!isPublicUser() && forceFullscreen" fxHide.lt-md displayUserInfo="true">
</tb-user-menu>
<button [fxShow]="showRightLayoutSwitch()" mat-button mat-icon-button
<button [fxShow]="showRightLayoutSwitch()" mat-icon-button
matTooltip="{{ (isRightLayoutOpened ? 'dashboard.hide-details' : 'dashboard.show-details') | translate }}"
matTooltipPosition="below"
(click)="toggleLayouts()">
<mat-icon>{{isRightLayoutOpened ? 'arrow_back' : 'menu'}}</mat-icon>
</button>
<button [fxShow]="!hideFullscreenButton()" mat-button mat-icon-button
<button [fxShow]="!hideFullscreenButton()" mat-icon-button
matTooltip="{{(isFullscreen ? 'fullscreen.exit' : 'fullscreen.expand') | translate}}"
matTooltipPosition="below"
(click)="isFullscreen = !isFullscreen">
<mat-icon>{{ isFullscreen ? 'fullscreen_exit' : 'fullscreen' }}</mat-icon>
</button>
<button [fxShow]="isEdit || displayExport()" mat-button mat-icon-button
<button [fxShow]="isEdit || displayExport()" mat-icon-button
matTooltip="{{'dashboard.export' | translate}}"
matTooltipPosition="below"
(click)="exportDashboard($event)">
@ -65,13 +65,13 @@
tooltipPosition="below"
[aliasController]="dashboardCtx.aliasController">
</tb-aliases-entity-select>
<button [fxShow]="isEdit" mat-button mat-icon-button
<button [fxShow]="isEdit" mat-icon-button
matTooltip="{{ 'entity.aliases' | translate }}"
matTooltipPosition="below"
(click)="openEntityAliases($event)">
<mat-icon>devices_other</mat-icon>
</button>
<button [fxShow]="isEdit" mat-button mat-icon-button
<button [fxShow]="isEdit" mat-icon-button
matTooltip="{{ 'dashboard.settings' | translate }}"
matTooltipPosition="below"
(click)="openDashboardSettings($event)">
@ -89,23 +89,23 @@
<tb-user-menu *ngIf="!isPublicUser() && forceFullscreen" fxHide.gt-sm displayUserInfo="true">
</tb-user-menu>
<div [fxShow]="isEdit"
fxFlex.xs fxFlex.sm fxLayout="row"
fxFlex.lt-md fxLayout="row"
fxLayoutAlign.gt-sm="start center"
fxLayoutAlign="space-between center" fxLayoutGap="12px">
<button mat-button mat-icon-button
fxLayoutAlign="end center" fxLayoutGap="12px">
<button mat-icon-button
matTooltip="{{'dashboard.manage-states' | translate}}"
matTooltipPosition="below"
(click)="manageDashboardStates($event)">
<mat-icon>layers</mat-icon>
</button>
<button mat-button mat-icon-button
<button mat-icon-button
matTooltip="{{'layout.manage' | translate}}"
matTooltipPosition="below"
(click)="manageDashboardLayouts($event)">
<mat-icon>view_compact</mat-icon>
</button>
</div>
<tb-states-component fxFlex.xs fxFlex.sm
<tb-states-component fxFlex.lt-md
[statesControllerId]="isEdit ? 'default' : dashboardConfiguration.settings.stateControllerId"
[dashboardCtrl]="this"
[dashboardId]="dashboard.id ? dashboard.id.id : ''"

20
ui-ngx/src/app/modules/home/pages/dashboard/dashboard-settings-dialog.component.html

@ -16,7 +16,7 @@
-->
<form #settingsForm="ngForm" (ngSubmit)="save()">
<mat-toolbar fxLayout="row" color="primary">
<mat-toolbar color="primary">
<h2 translate>{{settings ? 'dashboard.settings' : 'layout.settings'}}</h2>
<span fxFlex></span>
<button mat-button mat-icon-button
@ -28,17 +28,17 @@
<mat-progress-bar color="warn" mode="indeterminate" *ngIf="isLoading$ | async">
</mat-progress-bar>
<div mat-dialog-content>
<fieldset [disabled]="isLoading$ | async">
<fieldset [disabled]="isLoading$ | async" fxLayout="column" fxLayoutGap="16px">
<div *ngIf="settings" [formGroup]="settingsFormGroup">
<mat-form-field class="mat-block">
<mat-label translate>dashboard.state-controller</mat-label>
<mat-select required matInput formControlName="stateControllerId">
<mat-select required formControlName="stateControllerId">
<mat-option *ngFor="let stateControllerId of stateControllerIds" [value]="stateControllerId">
{{stateControllerId}}
</mat-option>
</mat-select>
</mat-form-field>
<div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="8px">
<div fxLayout="row" fxLayoutAlign="start center" fxLayout.lt-md="column" fxLayoutAlign.lt-md fxLayoutGap="8px">
<mat-checkbox fxFlex formControlName="toolbarAlwaysOpen">
{{ 'dashboard.toolbar-always-open' | translate }}
</mat-checkbox>
@ -52,7 +52,7 @@
formControlName="titleColor">
</tb-color-input>
</div>
<div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="8px">
<div fxLayout="row" fxLayoutAlign="start center" fxLayout.lt-md="column" fxLayoutAlign.lt-md fxLayoutGap="8px">
<mat-checkbox fxFlex formControlName="showDashboardsSelect">
{{ 'dashboard.display-dashboards-selection' | translate }}
</mat-checkbox>
@ -117,7 +117,7 @@
</tb-image-input>
<mat-form-field class="mat-block">
<mat-label translate>dashboard.background-size-mode</mat-label>
<mat-select matInput formControlName="backgroundSizeMode">
<mat-select formControlName="backgroundSizeMode">
<mat-option value="100%">Fit width</mat-option>
<mat-option value="auto 100%">Fit height</mat-option>
<mat-option value="cover">Cover</mat-option>
@ -126,7 +126,7 @@
</mat-select>
</mat-form-field>
<small translate>dashboard.mobile-layout</small>
<div fxFlex fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="8px">
<div fxLayout="row" fxLayoutAlign="start center" fxLayout.xs="column" fxLayoutAlign.xs fxLayoutGap="8px" style="margin-top: 8px">
<mat-checkbox fxFlex formControlName="mobileAutoFillHeight">
{{ 'dashboard.autofill-height' | translate }}
</mat-checkbox>
@ -148,16 +148,14 @@
</div>
</fieldset>
</div>
<div mat-dialog-actions fxLayout="row">
<span fxFlex></span>
<button mat-button mat-raised-button color="primary"
<div mat-dialog-actions fxLayoutAlign="end center">
<button mat-raised-button color="primary"
type="submit"
[disabled]="(isLoading$ | async) || settingsFormGroup.invalid || gridSettingsFormGroup.invalid
|| (!settingsFormGroup.dirty && !gridSettingsFormGroup.dirty)">
{{ 'action.save' | translate }}
</button>
<button mat-button color="primary"
style="margin-right: 20px;"
type="button"
[disabled]="(isLoading$ | async)"
(click)="cancel()" cdkFocusInitial>

26
ui-ngx/src/app/modules/home/pages/dashboard/dashboard-settings-dialog.component.scss

@ -0,0 +1,26 @@
/**
* Copyright © 2016-2020 The Thingsboard Authors
*
* 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.
*/
:host {
small {
white-space: normal;
}
}
:host ::ng-deep {
.mat-checkbox-label {
white-space: normal;
}
}

2
ui-ngx/src/app/modules/home/pages/dashboard/dashboard-settings-dialog.component.ts

@ -38,7 +38,7 @@ export interface DashboardSettingsDialogData {
selector: 'tb-dashboard-settings-dialog',
templateUrl: './dashboard-settings-dialog.component.html',
providers: [{provide: ErrorStateMatcher, useExisting: DashboardSettingsDialogComponent}],
styleUrls: []
styleUrls: ['./dashboard-settings-dialog.component.scss']
})
export class DashboardSettingsDialogComponent extends DialogComponent<DashboardSettingsDialogComponent, DashboardSettingsDialogData>
implements OnInit, ErrorStateMatcher {

6
ui-ngx/src/app/modules/home/pages/dashboard/dashboard-toolbar.component.html

@ -15,12 +15,10 @@
limitations under the License.
-->
<mat-fab-toolbar [isOpen]="toolbarOpened"
color="primary"
direction="left"
<mat-fab-toolbar [isOpen]="toolbarOpened" color="primary" direction="left"
[ngClass]="{'is-fullscreen': forceFullscreen, 'mat-elevation-z1': forceFullscreen && toolbarOpened }">
<mat-fab-trigger>
<button mat-button mat-icon-button mat-fab color="primary"
<button mat-fab color="primary"
[matTooltip]="!toolbarOpened ? ('dashboard.open-toolbar' | translate) : ''"
matTooltipPosition="below"
(click)="onTriggerClick()">

2
ui-ngx/src/app/modules/home/pages/dashboard/layout/dashboard-layout.component.ts

@ -28,7 +28,7 @@ import {
WidgetContextMenuItem
} from '@home/models/dashboard-component.models';
import { Subscription } from 'rxjs';
import { Hotkey, HotkeysService } from 'angular2-hotkeys';
import { Hotkey } from 'angular2-hotkeys';
import { TranslateService } from '@ngx-translate/core';
import { ItemBufferService } from '@app/core/services/item-buffer.service';
import { DomSanitizer, SafeStyle } from '@angular/platform-browser';

3
ui-ngx/src/app/modules/home/pages/dashboard/layout/layout.models.ts

@ -14,9 +14,6 @@
/// limitations under the License.
///
import { Widget } from '@shared/models/widget.models';
import { WidgetLayout } from '@shared/models/dashboard.models';
export interface ILayoutController {
reload();
resetHighlight();

27
ui-ngx/src/app/modules/home/pages/dashboard/layout/manage-dashboard-layouts-dialog.component.html

@ -16,7 +16,7 @@
-->
<form #widgetForm="ngForm" [formGroup]="layoutsFormGroup" (ngSubmit)="save()">
<mat-toolbar fxLayout="row" color="primary">
<mat-toolbar color="primary">
<h2 translate>layout.manage</h2>
<span fxFlex></span>
<button mat-button mat-icon-button
@ -38,33 +38,32 @@
</mat-checkbox>
</div>
<div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="8px">
<button fxFlex fxLayout="column"
type="button" mat-button mat-raised-button color="primary"
<button fxFlex
type="button" mat-raised-button color="primary"
class="tb-layout-button"
(click)="openLayoutSettings('main')">
<span translate>layout.main</span>
</button>
<button fxFlex fxLayout="column" [fxShow]="layoutsFormGroup.get('right').value"
type="button" mat-button mat-raised-button color="primary"
<button fxFlex [fxShow]="layoutsFormGroup.get('right').value"
type="button" mat-raised-button color="primary"
class="tb-layout-button"
(click)="openLayoutSettings('right')">
(click)="openLayoutSettings('right')">
<span translate>layout.right</span>
</button>
</div>
</fieldset>
</div>
<div mat-dialog-actions fxLayout="row">
<span fxFlex></span>
<button mat-button mat-raised-button color="primary"
<div mat-dialog-actions fxLayoutAlign="end center">
<button mat-raised-button color="primary"
type="submit"
[disabled]="(isLoading$ | async) || layoutsFormGroup.invalid || !layoutsFormGroup.dirty">
[disabled]="(isLoading$ | async) || layoutsFormGroup.invalid || !layoutsFormGroup.dirty">
{{ 'action.save' | translate }}
</button>
<button mat-button color="primary"
style="margin-right: 20px;"
<button mat-button
color="primary"
type="button"
[disabled]="(isLoading$ | async)"
(click)="cancel()" cdkFocusInitial>
[disabled]="(isLoading$ | async)"
(click)="cancel()" cdkFocusInitial>
{{ 'action.cancel' | translate }}
</button>
</div>

11
ui-ngx/src/app/modules/home/pages/dashboard/layout/manage-dashboard-layouts-dialog.component.ts

@ -16,22 +16,17 @@
import { Component, Inject, OnInit, SkipSelf } from '@angular/core';
import { ErrorStateMatcher } from '@angular/material/core';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { MAT_DIALOG_DATA, MatDialog, MatDialogRef } from '@angular/material/dialog';
import { Store } from '@ngrx/store';
import { AppState } from '@core/core.state';
import { FormBuilder, FormControl, FormGroup, FormGroupDirective, NgForm } from '@angular/forms';
import { Router } from '@angular/router';
import { DialogComponent } from '@app/shared/components/dialog.component';
import { Widget, widgetTypesData } from '@shared/models/widget.models';
import { UtilsService } from '@core/services/utils.service';
import { TranslateService } from '@ngx-translate/core';
import { EntityService } from '@core/http/entity.service';
import { Dashboard, DashboardLayoutId, DashboardStateLayouts } from '@app/shared/models/dashboard.models';
import { IAliasController } from '@core/api/widget-api.models';
import { WidgetConfigComponentData, WidgetInfo } from '@home/models/widget-component.models';
import { deepClone, isDefined, isString } from '@core/utils';
import { DashboardLayoutId, DashboardStateLayouts } from '@app/shared/models/dashboard.models';
import { deepClone, isDefined } from '@core/utils';
import { DashboardUtilsService } from '@core/services/dashboard-utils.service';
import { MatDialog } from '@angular/material/dialog';
import {
DashboardSettingsDialogComponent,
DashboardSettingsDialogData

10
ui-ngx/src/app/modules/home/pages/dashboard/states/dashboard-state-dialog.component.html

@ -15,8 +15,8 @@
limitations under the License.
-->
<form #stateForm="ngForm" [formGroup]="stateFormGroup" (ngSubmit)="save()" style="min-width: 600px;">
<mat-toolbar fxLayout="row" color="primary">
<form #stateForm="ngForm" [formGroup]="stateFormGroup" (ngSubmit)="save()" style="min-width: 480px;">
<mat-toolbar color="primary">
<h2 translate>{{ isAdd ? 'dashboard.add-state' : 'dashboard.edit-state' }}</h2>
<span fxFlex></span>
<button mat-button mat-icon-button
@ -51,15 +51,13 @@
</mat-checkbox>
</fieldset>
</div>
<div mat-dialog-actions fxLayout="row">
<span fxFlex></span>
<button mat-button mat-raised-button color="primary"
<div mat-dialog-actions fxLayoutAlign="end center">
<button mat-raised-button color="primary"
type="submit"
[disabled]="(isLoading$ | async) || stateFormGroup.invalid || !stateFormGroup.dirty">
{{ (isAdd ? 'action.add' : 'action.save') | translate }}
</button>
<button mat-button color="primary"
style="margin-right: 20px;"
type="button"
[disabled]="(isLoading$ | async)"
(click)="cancel()" cdkFocusInitial>

4
ui-ngx/src/app/modules/home/pages/dashboard/states/dashboard-state-dialog.component.ts

@ -31,7 +31,6 @@ import {
import { Router } from '@angular/router';
import { DialogComponent } from '@app/shared/components/dialog.component';
import { DashboardState } from '@app/shared/models/dashboard.models';
import { MatDialog } from '@angular/material/dialog';
import { DashboardStateInfo } from '@home/pages/dashboard/states/manage-dashboard-states-dialog.component.models';
import { TranslateService } from '@ngx-translate/core';
import { DashboardUtilsService } from '@core/services/dashboard-utils.service';
@ -71,8 +70,7 @@ export class DashboardStateDialogComponent extends
public dialogRef: MatDialogRef<DashboardStateDialogComponent, DashboardStateInfo>,
private fb: FormBuilder,
private translate: TranslateService,
private dashboardUtils: DashboardUtilsService,
private dialog: MatDialog) {
private dashboardUtils: DashboardUtilsService) {
super(store, router, dialogRef);
this.states = this.data.states;

30
ui-ngx/src/app/modules/home/pages/dashboard/states/manage-dashboard-states-dialog.component.html

@ -15,8 +15,8 @@
limitations under the License.
-->
<form #statesForm="ngForm" [formGroup]="statesFormGroup" (ngSubmit)="save()" style="min-width: 620px;">
<mat-toolbar fxLayout="row" color="primary">
<form #statesForm="ngForm" [formGroup]="statesFormGroup" (ngSubmit)="save()" style="min-width: 480px;">
<mat-toolbar color="primary">
<h2 translate>dashboard.manage-states</h2>
<span fxFlex></span>
<button mat-button mat-icon-button
@ -36,14 +36,14 @@
<div class="mat-toolbar-tools">
<span class="tb-entity-table-title" translate>dashboard.states</span>
<span fxFlex></span>
<button mat-button mat-icon-button [disabled]="isLoading$ | async"
<button mat-icon-button [disabled]="isLoading$ | async"
type="button"
(click)="addState($event)"
matTooltip="{{ 'dashboard.add-state' | translate }}"
matTooltipPosition="above">
<mat-icon>add</mat-icon>
</button>
<button mat-button mat-icon-button [disabled]="isLoading$ | async" (click)="enterFilterMode()"
<button mat-icon-button [disabled]="isLoading$ | async" (click)="enterFilterMode()"
type="button"
matTooltip="{{ 'action.search' | translate }}"
matTooltipPosition="above">
@ -53,7 +53,7 @@
</mat-toolbar>
<mat-toolbar class="mat-table-toolbar" [fxShow]="textSearchMode">
<div class="mat-toolbar-tools">
<button mat-button mat-icon-button
<button mat-icon-button
type="button"
matTooltip="{{ 'dashboard.search-states' | translate }}"
matTooltipPosition="above">
@ -66,7 +66,7 @@
[ngModelOptions]="{standalone: true}"
placeholder="{{ 'dashboard.search-states' | translate }}"/>
</mat-form-field>
<button mat-button mat-icon-button (click)="exitFilterMode()"
<button mat-icon-button (click)="exitFilterMode()"
type="button"
matTooltip="{{ 'action.close' | translate }}"
matTooltipPosition="above">
@ -75,16 +75,16 @@
</div>
</mat-toolbar>
<div class="table-container">
<mat-table [dataSource]="dataSource"
<table mat-table [dataSource]="dataSource"
matSort [matSortActive]="pageLink.sortOrder.property" [matSortDirection]="pageLink.sortDirection()" matSortDisableClear>
<ng-container matColumnDef="name">
<mat-header-cell *matHeaderCellDef mat-sort-header style="width: 60%"> {{ 'dashboard.state-name' | translate }} </mat-header-cell>
<mat-header-cell *matHeaderCellDef mat-sort-header style="flex: 0 0 60%"> {{ 'dashboard.state-name' | translate }} </mat-header-cell>
<mat-cell *matCellDef="let state">
{{ state.name }}
</mat-cell>
</ng-container>
<ng-container matColumnDef="id">
<mat-header-cell *matHeaderCellDef mat-sort-header style="width: 40%"> {{ 'dashboard.state-id' | translate }} </mat-header-cell>
<mat-header-cell *matHeaderCellDef mat-sort-header style="flex: 0 0 40%"> {{ 'dashboard.state-id' | translate }} </mat-header-cell>
<mat-cell *matCellDef="let state">
{{ state.id }}
</mat-cell>
@ -100,14 +100,14 @@
</mat-header-cell>
<mat-cell *matCellDef="let state">
<div fxFlex fxLayout="row">
<button mat-button mat-icon-button [disabled]="isLoading$ | async"
<button mat-icon-button [disabled]="isLoading$ | async"
type="button"
matTooltip="{{ 'dashboard.edit-state' | translate }}"
matTooltipPosition="above"
(click)="editState($event, state)">
<mat-icon>edit</mat-icon>
</button>
<button [fxShow]="!state.root" mat-button mat-icon-button [disabled]="isLoading$ | async"
<button [fxShow]="!state.root" mat-icon-button [disabled]="isLoading$ | async"
type="button"
matTooltip="{{ 'dashboard.delete-state' | translate }}"
matTooltipPosition="above"
@ -120,7 +120,7 @@
<mat-header-row class="mat-row-select" *matHeaderRowDef="displayedColumns; sticky: true"></mat-header-row>
<mat-row class="mat-row-select"
*matRowDef="let state; columns: displayedColumns;"></mat-row>
</mat-table>
</table>
<span [fxShow]="dataSource.isEmpty() | async"
fxLayoutAlign="center center"
class="no-data-found" translate>{{ 'dashboard.no-states-text' }}</span>
@ -135,15 +135,13 @@
</div>
</fieldset>
</div>
<div mat-dialog-actions fxLayout="row">
<span fxFlex></span>
<button mat-button mat-raised-button color="primary"
<div mat-dialog-actions fxLayoutAlign="end center">
<button mat-raised-button color="primary"
type="submit"
[disabled]="(isLoading$ | async) || statesFormGroup.invalid || !statesFormGroup.dirty">
{{ 'action.save' | translate }}
</button>
<button mat-button color="primary"
style="margin-right: 20px;"
type="button"
[disabled]="(isLoading$ | async)"
(click)="cancel()" cdkFocusInitial>

8
ui-ngx/src/app/modules/home/pages/dashboard/states/states-component.directive.ts

@ -17,20 +17,16 @@
import {
ComponentRef,
Directive,
ElementRef,
Input,
OnChanges,
OnInit,
OnDestroy,
OnInit,
SimpleChanges,
ViewContainerRef,
ChangeDetectorRef
ViewContainerRef
} from '@angular/core';
import { DashboardPageComponent } from '@home/pages/dashboard/dashboard-page.component';
import { DashboardState } from '@shared/models/dashboard.models';
import { IDashboardController } from '@home/pages/dashboard/dashboard-page.models';
import { StatesControllerService } from '@home/pages/dashboard/states/states-controller.service';
import { IStateController } from '@core/api/widget-api.models';
import { IStateControllerComponent } from '@home/pages/dashboard/states/state-controller.models';
@Directive({

32
ui-ngx/src/app/modules/home/pages/widget/widget-editor.component.html

@ -34,23 +34,23 @@
</mat-select>
</mat-form-field>
<span fxFlex></span>
<button mat-button fxHide.xs fxHide.sm [disabled]="!iframeWidgetEditModeInited"
<button mat-button fxHide.lt-md [disabled]="!iframeWidgetEditModeInited"
(click)="applyWidgetScript()"
matTooltip="{{ 'widget.run' | translate }} (CTRL + Return)"
matTooltipPosition="below">
<mat-icon>play_arrow</mat-icon>
<span translate>action.run</span>
</button>
<button mat-button mat-raised-button
fxHide.xs fxHide.sm [disabled]="(isLoading$ | async) || undoDisabled()"
<button mat-raised-button
fxHide.lt-md [disabled]="(isLoading$ | async) || undoDisabled()"
(click)="undoWidget()"
matTooltip="{{ 'widget.undo' | translate }} (CTRL + Q)"
matTooltipPosition="below">
<mat-icon>undo</mat-icon>
<span translate>action.undo</span>
</button>
<button *ngIf="!isReadOnly" mat-button mat-raised-button
fxHide.xs fxHide.sm [disabled]="(isLoading$ | async) || saveDisabled()"
<button *ngIf="!isReadOnly" mat-raised-button
fxHide.lt-md [disabled]="(isLoading$ | async) || saveDisabled()"
(click)="saveWidget()"
[tb-circular-progress]="saveWidgetPending"
matTooltip="{{ 'widget.save' | translate }} (CTRL + S)"
@ -58,8 +58,8 @@
<mat-icon>save</mat-icon>
<span translate>action.save</span>
</button>
<button mat-button mat-raised-button
fxHide.xs fxHide.sm [disabled]="(isLoading$ | async) || saveAsDisabled()"
<button mat-raised-button
fxHide.lt-md [disabled]="(isLoading$ | async) || saveAsDisabled()"
(click)="saveWidgetAs()"
[tb-circular-progress]="saveWidgetAsPending"
matTooltip="{{ 'widget.saveAs' | translate }} (Shift + CTRL + S)"
@ -68,14 +68,14 @@
<span translate>action.saveAs</span>
</button>
<button mat-button
fxHide.xs fxHide.sm
fxHide.lt-md
(click)="fullscreen = !fullscreen"
matTooltip="{{ 'widget.toggle-fullscreen' | translate }} (Shift + CTRL + F)"
matTooltipPosition="below">
<mat-icon>{{ fullscreen ? 'fullscreen_exit' : 'fullscreen' }}</mat-icon>
<span translate>widget.toggle-fullscreen</span>
</button>
<button mat-button mat-icon-button fxHide.gt-sm
<button mat-icon-button fxHide.gt-sm
[matMenuTriggerFor]="widgetEditMenu">
<mat-icon>more_vert</mat-icon>
</button>
@ -123,7 +123,7 @@
(ngModelChange)="isDirty = true"
placeholder="{{ 'widget.resource-url' | translate }}"/>
</mat-form-field>
<button mat-button mat-icon-button color="primary"
<button mat-icon-button color="primary"
[disabled]="isLoading$ | async"
(click)="removeResource(i)"
matTooltip="{{'widget.remove-resource' | translate}}"
@ -132,7 +132,7 @@
</button>
</div>
<div style="margin-top: 6px;">
<button mat-button mat-raised-button color="primary"
<button mat-raised-button color="primary"
[disabled]="isLoading$ | async"
(click)="addResource()"
matTooltip="{{'widget.add-resource' | translate}}"
@ -165,7 +165,7 @@
<button mat-button (click)="beautifyCss()">
{{ 'widget.tidy' | translate }}
</button>
<button mat-button mat-icon-button class="tb-mat-32"
<button mat-icon-button class="tb-mat-32"
(click)="cssFullscreen = !cssFullscreen"
matTooltip="{{(cssFullscreen ? 'fullscreen.exit' : 'fullscreen.expand') | translate}}"
matTooltipPosition="above">
@ -185,7 +185,7 @@
<button mat-button (click)="beautifyJson()">
{{ 'widget.tidy' | translate }}
</button>
<button mat-button mat-icon-button class="tb-mat-32"
<button mat-icon-button class="tb-mat-32"
(click)="jsonSettingsFullscreen = !jsonSettingsFullscreen"
matTooltip="{{(jsonSettingsFullscreen ? 'fullscreen.exit' : 'fullscreen.expand') | translate}}"
matTooltipPosition="above">
@ -201,7 +201,7 @@
<button mat-button (click)="beautifyDataKeyJson()">
{{ 'widget.tidy' | translate }}
</button>
<button mat-button mat-icon-button class="tb-mat-32"
<button mat-icon-button class="tb-mat-32"
(click)="jsonDataKeySettingsFullscreen = !jsonDataKeySettingsFullscreen"
matTooltip="{{(jsonDataKeySettingsFullscreen ? 'fullscreen.exit' : 'fullscreen.expand') | translate}}"
matTooltipPosition="above">
@ -222,7 +222,7 @@
<button mat-button (click)="beautifyJs()">
{{ 'widget.tidy' | translate }}
</button>
<button mat-button mat-icon-button class="tb-mat-32"
<button mat-icon-button class="tb-mat-32"
(click)="javascriptFullscreen = !javascriptFullscreen"
matTooltip="{{(javascriptFullscreen ? 'fullscreen.exit' : 'fullscreen.expand') | translate}}"
matTooltipPosition="above">
@ -240,7 +240,7 @@
<div tb-fullscreen [fullscreen]="iFrameFullscreen" style="width: 100%; height: 100%;">
<iframe #widgetIFrame frameborder="0" height="100%" width="100%"></iframe>
<div style="position: absolute; top: 10px; left: 10px; bottom: initial;">
<button mat-button mat-icon-button
<button mat-icon-button
class="tb-fullscreen-button-style"
(click)="iFrameFullscreen = !iFrameFullscreen"
matTooltip="{{(iFrameFullscreen ? 'fullscreen.exit' : 'fullscreen.expand') | translate}}"

7
ui-ngx/src/app/modules/home/pages/widget/widget-editor.component.ts

@ -21,7 +21,7 @@ import { Store } from '@ngrx/store';
import { AppState } from '@core/core.state';
import { WidgetService } from '@core/http/widget.service';
import { toWidgetInfo, WidgetInfo } from '@home/models/widget-component.models';
import { WidgetConfig, widgetType, WidgetType, widgetTypesData, Widget } from '@shared/models/widget.models';
import { Widget, WidgetConfig, WidgetType, widgetType, widgetTypesData } from '@shared/models/widget.models';
import { ActivatedRoute, Router } from '@angular/router';
import { deepClone } from '@core/utils';
import { HasDirtyFlag } from '@core/guards/confirm-on-exit.guard';
@ -29,7 +29,7 @@ import { AuthUser } from '@shared/models/user.model';
import { getCurrentAuthUser } from '@core/auth/auth.selectors';
import { Authority } from '@shared/models/authority.enum';
import { NULL_UUID } from '@shared/models/id/has-uuid';
import { Hotkey, HotkeysService } from 'angular2-hotkeys';
import { Hotkey } from 'angular2-hotkeys';
import { TranslateService } from '@ngx-translate/core';
import { getCurrentIsLoading } from '@app/core/interceptors/load.selectors';
import * as ace from 'ace-builds';
@ -38,15 +38,14 @@ import { CancelAnimationFrame, RafService } from '@core/services/raf.service';
import { WINDOW } from '@core/services/window.service';
import { WindowMessage } from '@shared/models/window-message.model';
import { ExceptionData } from '@shared/models/error.models';
import Timeout = NodeJS.Timeout;
import { ActionNotificationHide, ActionNotificationShow } from '@core/notification/notification.actions';
import { MatDialog } from '@angular/material/dialog';
import { SelectWidgetTypeDialogComponent } from '@home/pages/widget/select-widget-type-dialog.component';
import {
SaveWidgetTypeAsDialogComponent,
SaveWidgetTypeAsDialogResult
} from '@home/pages/widget/save-widget-type-as-dialog.component';
import { Subscription } from 'rxjs';
import Timeout = NodeJS.Timeout;
// @dynamic
@Component({

6
ui-ngx/src/app/shared/components/color-input.component.scss

@ -18,3 +18,9 @@
width: 100%;
}
}
:host ::ng-deep {
.mat-form-field-infix{
width: 150px;
}
}

22
ui-ngx/src/app/shared/components/color-input.component.ts

@ -14,30 +14,12 @@
/// limitations under the License.
///
import { Component, ElementRef, forwardRef, Input, OnInit, ViewChild } from '@angular/core';
import { Component, forwardRef, Input, OnInit } from '@angular/core';
import { PageComponent } from '@shared/components/page.component';
import { Store } from '@ngrx/store';
import { AppState } from '@core/core.state';
import { DataKey, DatasourceType } from '@shared/models/widget.models';
import {
ControlValueAccessor,
FormBuilder,
FormControl,
FormGroup,
NG_VALIDATORS,
NG_VALUE_ACCESSOR,
Validator,
Validators
} from '@angular/forms';
import { UtilsService } from '@core/services/utils.service';
import { ControlValueAccessor, FormBuilder, FormGroup, NG_VALUE_ACCESSOR, Validators } from '@angular/forms';
import { TranslateService } from '@ngx-translate/core';
import { MatDialog } from '@angular/material/dialog';
import { EntityService } from '@core/http/entity.service';
import { DataKeysCallbacks } from '@home/components/widget/data-keys.component.models';
import { DataKeyType } from '@shared/models/telemetry/telemetry.models';
import { Observable, of } from 'rxjs';
import { map, mergeMap, tap } from 'rxjs/operators';
import { alarmFields } from '@shared/models/alarm.models';
import { coerceBooleanProperty } from '@angular/cdk/coercion';
import { DialogService } from '@core/services/dialog.service';

31
ui-ngx/src/app/shared/components/dashboard-autocomplete.component.ts

@ -14,22 +14,21 @@
/// limitations under the License.
///
import {AfterViewInit, Component, ElementRef, forwardRef, Input, OnInit, ViewChild} from '@angular/core';
import {ControlValueAccessor, FormBuilder, FormGroup, NG_VALUE_ACCESSOR} from '@angular/forms';
import {Observable, of} from 'rxjs';
import {PageLink} from '@shared/models/page/page-link';
import {Direction} from '@shared/models/page/sort-order';
import {map, mergeMap, startWith, tap} from 'rxjs/operators';
import {PageData, emptyPageData} from '@shared/models/page/page-data';
import {DashboardInfo} from '@app/shared/models/dashboard.models';
import {DashboardId} from '@app/shared/models/id/dashboard-id';
import {DashboardService} from '@core/http/dashboard.service';
import {Store} from '@ngrx/store';
import {AppState} from '@app/core/core.state';
import {getCurrentAuthUser} from '@app/core/auth/auth.selectors';
import {Authority} from '@shared/models/authority.enum';
import {TranslateService} from '@ngx-translate/core';
import {coerceBooleanProperty} from '@angular/cdk/coercion';
import { AfterViewInit, Component, ElementRef, forwardRef, Input, OnInit, ViewChild } from '@angular/core';
import { ControlValueAccessor, FormBuilder, FormGroup, NG_VALUE_ACCESSOR } from '@angular/forms';
import { Observable, of } from 'rxjs';
import { PageLink } from '@shared/models/page/page-link';
import { Direction } from '@shared/models/page/sort-order';
import { map, mergeMap, startWith, tap } from 'rxjs/operators';
import { emptyPageData, PageData } from '@shared/models/page/page-data';
import { DashboardInfo } from '@app/shared/models/dashboard.models';
import { DashboardService } from '@core/http/dashboard.service';
import { Store } from '@ngrx/store';
import { AppState } from '@app/core/core.state';
import { getCurrentAuthUser } from '@app/core/auth/auth.selectors';
import { Authority } from '@shared/models/authority.enum';
import { TranslateService } from '@ngx-translate/core';
import { coerceBooleanProperty } from '@angular/cdk/coercion';
@Component({
selector: 'tb-dashboard-autocomplete',

2
ui-ngx/src/app/shared/components/dashboard-select.component.html

@ -15,7 +15,7 @@
limitations under the License.
-->
<mat-select fxHide.xs fxHide.sm fxHide.md
<mat-select fxHide.lt-lg
[required]="required"
[disabled]="disabled"
[(ngModel)]="dashboardId"

39
ui-ngx/src/app/shared/components/entity/entity-type-list.component.ts

@ -14,39 +14,18 @@
/// limitations under the License.
///
import {
AfterContentInit,
AfterViewInit,
Component,
ElementRef,
forwardRef,
Input,
OnInit,
SkipSelf,
ViewChild
} from '@angular/core';
import {
ControlValueAccessor,
FormBuilder,
FormControl,
FormGroup,
FormGroupDirective,
NG_VALUE_ACCESSOR, NgForm, Validators
} from '@angular/forms';
import {Observable, of} from 'rxjs';
import {map, mergeMap, startWith, tap, share, pairwise, filter} from 'rxjs/operators';
import {Store} from '@ngrx/store';
import {AppState} from '@app/core/core.state';
import {TranslateService} from '@ngx-translate/core';
import { AfterViewInit, Component, ElementRef, forwardRef, Input, OnInit, ViewChild } from '@angular/core';
import { ControlValueAccessor, FormBuilder, FormGroup, NG_VALUE_ACCESSOR, Validators } from '@angular/forms';
import { Observable, of } from 'rxjs';
import { filter, map, mergeMap, share, tap } from 'rxjs/operators';
import { Store } from '@ngrx/store';
import { AppState } from '@app/core/core.state';
import { TranslateService } from '@ngx-translate/core';
import { AliasEntityType, EntityType, entityTypeTranslations } from '@shared/models/entity-type.models';
import {BaseData} from '@shared/models/base-data';
import {EntityId} from '@shared/models/id/entity-id';
import {EntityService} from '@core/http/entity.service';
import { MatAutocomplete, MatAutocompleteSelectedEvent } from '@angular/material/autocomplete';
import { EntityService } from '@core/http/entity.service';
import { MatAutocomplete } from '@angular/material/autocomplete';
import { MatChipList } from '@angular/material/chips';
import { ErrorStateMatcher } from '@angular/material/core';
import { coerceBooleanProperty } from '@angular/cdk/coercion';
import { emptyPageData } from '@shared/models/page/page-data';
interface EntityTypeInfo {
name: string;

11
ui-ngx/src/app/shared/components/fab-toolbar.component.ts

@ -15,19 +15,20 @@
///
import {
AfterViewInit,
Component,
Directive,
ElementRef,
Inject,
Input,
OnChanges,
OnDestroy,
OnInit,
Renderer2,
ViewEncapsulation,
SimpleChanges,
Inject, AfterViewInit, AfterViewChecked, Directive, OnDestroy
ViewEncapsulation
} from '@angular/core';
import { PageComponent } from '@shared/components/page.component';
import { WINDOW } from '@core/services/window.service';
import { mixinColor, CanColorCtor } from '@angular/material/core';
import { CanColorCtor, mixinColor } from '@angular/material/core';
export declare type FabToolbarDirection = 'left' | 'right';

1
ui-ngx/src/app/shared/components/json-form/react/json-form-checkbox.tsx

@ -33,7 +33,6 @@ class ThingsboardCheckbox extends React.Component<JsonFormFieldProps, JsonFormFi
onChange={(e, checked) => {
this.props.onChangeValidate(e);
}}
style={{paddingTop: '14px'}}
/>
}
label={this.props.form.title}

2
ui-ngx/src/app/shared/components/material-icon-select.component.html

@ -17,7 +17,7 @@
-->
<div fxLayout="row" [formGroup]="materialIconFormGroup">
<mat-icon (click)="openIconDialog()">{{materialIconFormGroup.get('icon').value}}</mat-icon>
<mat-form-field>
<mat-form-field fxFlex>
<mat-label translate>icon.icon</mat-label>
<input matInput formControlName="icon" (mousedown)="openIconDialog()">
</mat-form-field>

6
ui-ngx/src/app/shared/components/material-icon-select.component.scss

@ -21,3 +21,9 @@
border: solid 1px rgba(0, 0, 0, .27);
}
}
:host ::ng-deep {
.mat-form-field-infix{
width: 146px;
}
}

24
ui-ngx/src/app/shared/components/material-icon-select.component.ts

@ -14,31 +14,11 @@
/// limitations under the License.
///
import { Component, ElementRef, forwardRef, Input, OnInit, ViewChild } from '@angular/core';
import { Component, forwardRef, Input, OnInit } from '@angular/core';
import { PageComponent } from '@shared/components/page.component';
import { Store } from '@ngrx/store';
import { AppState } from '@core/core.state';
import { DataKey, DatasourceType } from '@shared/models/widget.models';
import {
ControlValueAccessor,
FormBuilder,
FormControl,
FormGroup,
NG_VALIDATORS,
NG_VALUE_ACCESSOR,
Validator,
Validators
} from '@angular/forms';
import { UtilsService } from '@core/services/utils.service';
import { TranslateService } from '@ngx-translate/core';
import { MatDialog } from '@angular/material/dialog';
import { EntityService } from '@core/http/entity.service';
import { DataKeysCallbacks } from '@home/components/widget/data-keys.component.models';
import { DataKeyType } from '@shared/models/telemetry/telemetry.models';
import { Observable, of } from 'rxjs';
import { map, mergeMap, tap } from 'rxjs/operators';
import { alarmFields } from '@shared/models/alarm.models';
import { coerceBooleanProperty } from '@angular/cdk/coercion';
import { ControlValueAccessor, FormBuilder, FormGroup, NG_VALUE_ACCESSOR } from '@angular/forms';
import { DialogService } from '@core/services/dialog.service';
@Component({

2
ui-ngx/src/app/shared/components/relation/relation-type-autocomplete.component.html

@ -24,7 +24,7 @@
[matAutocomplete]="relationTypeAutocomplete">
<button *ngIf="relationTypeFormGroup.get('relationType').value && !disabled"
type="button"
matSuffix mat-button mat-icon-button aria-label="Clear"
matSuffix mat-icon-button aria-label="Clear"
(click)="clear()">
<mat-icon class="material-icons">close</mat-icon>
</button>

28
ui-ngx/src/app/shared/components/relation/relation-type-autocomplete.component.ts

@ -14,27 +14,15 @@
/// limitations under the License.
///
import {AfterViewInit, Component, ElementRef, forwardRef, Input, OnInit, ViewChild, OnDestroy} from '@angular/core';
import { AfterViewInit, Component, ElementRef, forwardRef, Input, OnDestroy, OnInit, ViewChild } from '@angular/core';
import { ControlValueAccessor, FormBuilder, FormGroup, NG_VALUE_ACCESSOR, Validators } from '@angular/forms';
import {Observable, of, throwError, Subscription} from 'rxjs';
import {PageLink} from '@shared/models/page/page-link';
import {Direction} from '@shared/models/page/sort-order';
import {filter, map, mergeMap, publishReplay, refCount, startWith, tap, publish} from 'rxjs/operators';
import {PageData, emptyPageData} from '@shared/models/page/page-data';
import {DashboardInfo} from '@app/shared/models/dashboard.models';
import {DashboardId} from '@app/shared/models/id/dashboard-id';
import {DashboardService} from '@core/http/dashboard.service';
import {Store} from '@ngrx/store';
import {AppState} from '@app/core/core.state';
import {getCurrentAuthUser} from '@app/core/auth/auth.selectors';
import {Authority} from '@shared/models/authority.enum';
import {TranslateService} from '@ngx-translate/core';
import {DeviceService} from '@core/http/device.service';
import {EntitySubtype, EntityType} from '@app/shared/models/entity-type.models';
import {BroadcastService} from '@app/core/services/broadcast.service';
import {coerceBooleanProperty} from '@angular/cdk/coercion';
import {AssetService} from '@core/http/asset.service';
import {EntityViewService} from '@core/http/entity-view.service';
import { Observable, of } from 'rxjs';
import { map, mergeMap, tap } from 'rxjs/operators';
import { Store } from '@ngrx/store';
import { AppState } from '@app/core/core.state';
import { TranslateService } from '@ngx-translate/core';
import { BroadcastService } from '@app/core/services/broadcast.service';
import { coerceBooleanProperty } from '@angular/cdk/coercion';
import { RelationTypes } from '@app/shared/models/relation.models';
@Component({

1
ui-ngx/src/styles.scss

@ -863,6 +863,7 @@ mat-label {
.mat-dialog-container {
> *:first-child, form {
min-width: 100% !important;
height: 100vh;
}
.mat-dialog-content {
max-height: 100%;

Loading…
Cancel
Save