Browse Source

Merge remote-tracking branch 'upstream/develop/3.5.2' into feature/check-connectivity-device

pull/8938/head
Vladyslav_Prykhodko 3 years ago
parent
commit
e0f9cb3b41
  1. 3
      ui-ngx/src/app/core/services/dialog.service.ts
  2. 6
      ui-ngx/src/app/modules/home/components/alarm/alarm-assignee.component.scss
  3. 27
      ui-ngx/src/app/modules/home/components/widget/config/basic/alarm/alarms-table-basic-config.component.html
  4. 27
      ui-ngx/src/app/modules/home/components/widget/config/basic/cards/entities-table-basic-config.component.html
  5. 22
      ui-ngx/src/app/modules/home/components/widget/config/basic/cards/simple-card-basic-config.component.html
  6. 27
      ui-ngx/src/app/modules/home/components/widget/config/basic/cards/timeseries-table-basic-config.component.html
  7. 27
      ui-ngx/src/app/modules/home/components/widget/config/basic/chart/flot-basic-config.component.html
  8. 11
      ui-ngx/src/app/modules/home/components/widget/config/data-key-config.component.html
  9. 2
      ui-ngx/src/app/modules/home/components/widget/config/data-keys.component.html
  10. 32
      ui-ngx/src/app/modules/home/components/widget/config/data-keys.component.ts
  11. 11
      ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/flot-key-settings.component.html
  12. 11
      ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/flot-latest-key-settings.component.html
  13. 54
      ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/flot-widget-settings.component.html
  14. 27
      ui-ngx/src/app/modules/home/components/widget/widget-config.component.html
  15. 43
      ui-ngx/src/app/modules/home/pages/home-links/home-links-routing.module.ts
  16. 13
      ui-ngx/src/app/shared/components/color-input.component.html
  17. 9
      ui-ngx/src/app/shared/components/color-input.component.scss
  18. 42
      ui-ngx/src/app/shared/components/color-input.component.ts
  19. 30
      ui-ngx/src/app/shared/components/color-picker/color-picker-panel.component.html
  20. 36
      ui-ngx/src/app/shared/components/color-picker/color-picker-panel.component.scss
  21. 55
      ui-ngx/src/app/shared/components/color-picker/color-picker-panel.component.ts
  22. 14
      ui-ngx/src/app/shared/components/color-picker/color-picker.component.html
  23. 39
      ui-ngx/src/app/shared/components/color-picker/color-picker.component.scss
  24. 27
      ui-ngx/src/app/shared/components/color-picker/color-picker.component.ts
  25. 30
      ui-ngx/src/app/shared/components/dialog/color-picker-dialog.component.html
  26. 22
      ui-ngx/src/app/shared/components/dialog/color-picker-dialog.component.scss
  27. 24
      ui-ngx/src/app/shared/components/dialog/color-picker-dialog.component.ts
  28. 3
      ui-ngx/src/app/shared/shared.module.ts
  29. 0
      ui-ngx/src/assets/dashboard/customer_user_home_page.json
  30. 0
      ui-ngx/src/assets/dashboard/sys_admin_home_page.json
  31. 0
      ui-ngx/src/assets/dashboard/tenant_admin_home_page.json
  32. 3
      ui-ngx/src/assets/locale/locale.constant-en_US.json
  33. 53
      ui-ngx/src/form.scss

3
ui-ngx/src/app/core/services/dialog.service.ts

@ -103,7 +103,8 @@ export class DialogService {
panelClass: ['tb-dialog', 'tb-fullscreen-dialog'],
data: {
color
}
},
autoFocus: false
}).afterClosed();
}

6
ui-ngx/src/app/modules/home/components/alarm/alarm-assignee.component.scss

@ -45,9 +45,3 @@
margin-right: 8px;
}
}
.drop-down-icon {
&.inline {
margin-right: -12px;
}
}

27
ui-ngx/src/app/modules/home/components/widget/config/basic/alarm/alarms-table-basic-config.component.html

@ -58,16 +58,15 @@
<input matInput formControlName="title" placeholder="{{ 'widget-config.set' | translate }}">
</mat-form-field>
</div>
<div class="tb-form-row space-between same-padding">
<div class="tb-form-row space-between">
<mat-slide-toggle class="mat-slide" formControlName="showTitleIcon">
{{ 'widget-config.card-icon' | translate }}
</mat-slide-toggle>
<div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="16px">
<div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="8px">
<tb-material-icon-select asBoxInput
[color]="alarmsTableWidgetConfigForm.get('iconColor').value"
formControlName="titleIcon">
</tb-material-icon-select>
<mat-divider vertical></mat-divider>
<tb-color-input asBoxInput
formControlName="iconColor">
</tb-color-input>
@ -82,23 +81,17 @@
<mat-chip-option value="fullscreen">{{ 'fullscreen.fullscreen' | translate }}</mat-chip-option>
</mat-chip-listbox>
</div>
<div class="tb-form-row space-between same-padding">
<div class="tb-form-row space-between">
<div>{{ 'widget-config.text-color' | translate }}</div>
<div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="16px">
<mat-divider vertical></mat-divider>
<tb-color-input asBoxInput
formControlName="color">
</tb-color-input>
</div>
<tb-color-input asBoxInput
formControlName="color">
</tb-color-input>
</div>
<div class="tb-form-row space-between same-padding">
<div class="tb-form-row space-between">
<div>{{ 'widget-config.background-color' | translate }}</div>
<div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="16px">
<mat-divider vertical></mat-divider>
<tb-color-input asBoxInput
formControlName="backgroundColor">
</tb-color-input>
</div>
<tb-color-input asBoxInput
formControlName="backgroundColor">
</tb-color-input>
</div>
</div>
<tb-widget-actions-panel

27
ui-ngx/src/app/modules/home/components/widget/config/basic/cards/entities-table-basic-config.component.html

@ -47,16 +47,15 @@
<input matInput formControlName="title" placeholder="{{ 'widget-config.set' | translate }}">
</mat-form-field>
</div>
<div class="tb-form-row space-between same-padding">
<div class="tb-form-row space-between">
<mat-slide-toggle class="mat-slide" formControlName="showTitleIcon">
{{ 'widget-config.card-icon' | translate }}
</mat-slide-toggle>
<div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="16px">
<div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="8px">
<tb-material-icon-select asBoxInput
[color]="entitiesTableWidgetConfigForm.get('iconColor').value"
formControlName="titleIcon">
</tb-material-icon-select>
<mat-divider vertical></mat-divider>
<tb-color-input asBoxInput
formControlName="iconColor">
</tb-color-input>
@ -70,23 +69,17 @@
<mat-chip-option value="fullscreen">{{ 'fullscreen.fullscreen' | translate }}</mat-chip-option>
</mat-chip-listbox>
</div>
<div class="tb-form-row space-between same-padding">
<div class="tb-form-row space-between">
<div>{{ 'widget-config.text-color' | translate }}</div>
<div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="16px">
<mat-divider vertical></mat-divider>
<tb-color-input asBoxInput
formControlName="color">
</tb-color-input>
</div>
<tb-color-input asBoxInput
formControlName="color">
</tb-color-input>
</div>
<div class="tb-form-row space-between same-padding">
<div class="tb-form-row space-between">
<div>{{ 'widget-config.background-color' | translate }}</div>
<div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="16px">
<mat-divider vertical></mat-divider>
<tb-color-input asBoxInput
formControlName="backgroundColor">
</tb-color-input>
</div>
<tb-color-input asBoxInput
formControlName="backgroundColor">
</tb-color-input>
</div>
</div>
<tb-widget-actions-panel

22
ui-ngx/src/app/modules/home/components/widget/config/basic/cards/simple-card-basic-config.component.html

@ -67,23 +67,17 @@
<mat-chip-option value="fullscreen">{{ 'fullscreen.fullscreen' | translate }}</mat-chip-option>
</mat-chip-listbox>
</div>
<div class="tb-form-row space-between same-padding">
<div class="tb-form-row space-between">
<div>{{ 'widget-config.text-color' | translate }}</div>
<div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="16px">
<mat-divider vertical></mat-divider>
<tb-color-input asBoxInput
formControlName="color">
</tb-color-input>
</div>
<tb-color-input asBoxInput
formControlName="color">
</tb-color-input>
</div>
<div class="tb-form-row space-between same-padding">
<div class="tb-form-row space-between">
<div>{{ 'widget-config.background' | translate }}</div>
<div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="16px">
<mat-divider vertical></mat-divider>
<tb-color-input asBoxInput
formControlName="backgroundColor">
</tb-color-input>
</div>
<tb-color-input asBoxInput
formControlName="backgroundColor">
</tb-color-input>
</div>
</div>
<tb-widget-actions-panel

27
ui-ngx/src/app/modules/home/components/widget/config/basic/cards/timeseries-table-basic-config.component.html

@ -47,16 +47,15 @@
<input matInput formControlName="title" placeholder="{{ 'widget-config.set' | translate }}">
</mat-form-field>
</div>
<div class="tb-form-row space-between same-padding">
<div class="tb-form-row space-between">
<mat-slide-toggle class="mat-slide" formControlName="showTitleIcon">
{{ 'widget-config.card-icon' | translate }}
</mat-slide-toggle>
<div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="16px">
<div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="8px">
<tb-material-icon-select asBoxInput
[color]="timeseriesTableWidgetConfigForm.get('iconColor').value"
formControlName="titleIcon">
</tb-material-icon-select>
<mat-divider vertical></mat-divider>
<tb-color-input asBoxInput
formControlName="iconColor">
</tb-color-input>
@ -70,23 +69,17 @@
<mat-chip-option value="fullscreen">{{ 'fullscreen.fullscreen' | translate }}</mat-chip-option>
</mat-chip-listbox>
</div>
<div class="tb-form-row space-between same-padding">
<div class="tb-form-row space-between">
<div>{{ 'widget-config.text-color' | translate }}</div>
<div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="16px">
<mat-divider vertical></mat-divider>
<tb-color-input asBoxInput
formControlName="color">
</tb-color-input>
</div>
<tb-color-input asBoxInput
formControlName="color">
</tb-color-input>
</div>
<div class="tb-form-row space-between same-padding">
<div class="tb-form-row space-between">
<div>{{ 'widget-config.background-color' | translate }}</div>
<div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="16px">
<mat-divider vertical></mat-divider>
<tb-color-input asBoxInput
formControlName="backgroundColor">
</tb-color-input>
</div>
<tb-color-input asBoxInput
formControlName="backgroundColor">
</tb-color-input>
</div>
</div>
<tb-widget-actions-panel

27
ui-ngx/src/app/modules/home/components/widget/config/basic/chart/flot-basic-config.component.html

@ -47,16 +47,15 @@
<input matInput formControlName="title" placeholder="{{ 'widget-config.set' | translate }}">
</mat-form-field>
</div>
<div class="tb-form-row space-between same-padding">
<div class="tb-form-row space-between">
<mat-slide-toggle class="mat-slide" formControlName="showTitleIcon">
{{ 'widget-config.card-icon' | translate }}
</mat-slide-toggle>
<div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="16px">
<div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="8px">
<tb-material-icon-select asBoxInput
[color]="flotWidgetConfigForm.get('iconColor').value"
formControlName="titleIcon">
</tb-material-icon-select>
<mat-divider vertical></mat-divider>
<tb-color-input asBoxInput
formControlName="iconColor">
</tb-color-input>
@ -68,23 +67,17 @@
<mat-chip-option value="fullscreen">{{ 'fullscreen.fullscreen' | translate }}</mat-chip-option>
</mat-chip-listbox>
</div>
<div class="tb-form-row space-between same-padding">
<div class="tb-form-row space-between">
<div>{{ 'widget-config.text-color' | translate }}</div>
<div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="16px">
<mat-divider vertical></mat-divider>
<tb-color-input asBoxInput
formControlName="color">
</tb-color-input>
</div>
<tb-color-input asBoxInput
formControlName="color">
</tb-color-input>
</div>
<div class="tb-form-row space-between same-padding">
<div class="tb-form-row space-between">
<div>{{ 'widget-config.background-color' | translate }}</div>
<div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="16px">
<mat-divider vertical></mat-divider>
<tb-color-input asBoxInput
formControlName="backgroundColor">
</tb-color-input>
</div>
<tb-color-input asBoxInput
formControlName="backgroundColor">
</tb-color-input>
</div>
</div>
<div class="tb-form-panel">

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

@ -59,14 +59,11 @@
</mat-form-field>
</div>
</ng-container>
<div class="tb-form-row space-between same-padding" *ngIf="!hideDataKeyColor">
<div class="tb-form-row space-between" *ngIf="!hideDataKeyColor">
<div>{{ 'datakey.color' | translate }}</div>
<div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="16px">
<mat-divider vertical></mat-divider>
<tb-color-input asBoxInput
formControlName="color">
</tb-color-input>
</div>
<tb-color-input asBoxInput
formControlName="color">
</tb-color-input>
</div>
<ng-container *ngIf="widgetType === widgetTypes.latest && modelValue.type === dataKeyTypes.timeseries">
<mat-form-field subscriptSizing="dynamic">

2
ui-ngx/src/app/modules/home/components/widget/config/data-keys.component.html

@ -72,7 +72,7 @@
</div>
</div>
<div *ngIf="!hideDataKeyColor" style="padding: 3px;">
<div class="tb-color-preview small box" (click)="showColorPicker(key)">
<div #keyColorButton class="tb-color-preview small box" (click)="openColorPickerPopup(key, $event, keyColorButton)">
<div class="tb-color-result" [ngStyle]="{background: key.color}"></div>
</div>
</div>

32
ui-ngx/src/app/modules/home/components/widget/config/data-keys.component.ts

@ -27,6 +27,7 @@ import {
SimpleChanges,
SkipSelf,
ViewChild,
ViewContainerRef,
ViewEncapsulation
} from '@angular/core';
import {
@ -56,7 +57,6 @@ import { alarmFields } from '@shared/models/alarm.models';
import { UtilsService } from '@core/services/utils.service';
import { ErrorStateMatcher } from '@angular/material/core';
import { TruncatePipe } from '@shared/pipe/truncate.pipe';
import { DialogService } from '@core/services/dialog.service';
import { MatDialog } from '@angular/material/dialog';
import {
DataKeyConfigDialogComponent,
@ -69,6 +69,8 @@ import { DndDropEvent } from 'ngx-drag-drop/lib/dnd-dropzone.directive';
import { moveItemInArray } from '@angular/cdk/drag-drop';
import { coerceBoolean } from '@shared/decorators/coercion';
import { DatasourceComponent } from '@home/components/widget/config/datasource.component';
import { ColorPickerPanelComponent } from '@shared/components/color-picker/color-picker-panel.component';
import { TbPopoverService } from '@shared/components/popover.service';
@Component({
selector: 'tb-data-keys',
@ -208,10 +210,11 @@ export class DataKeysComponent implements ControlValueAccessor, OnInit, OnChange
private datasourceComponent: DatasourceComponent,
public translate: TranslateService,
private utils: UtilsService,
private dialogs: DialogService,
private dialog: MatDialog,
private fb: UntypedFormBuilder,
private cd: ChangeDetectorRef,
private popoverService: TbPopoverService,
private viewContainerRef: ViewContainerRef,
private renderer: Renderer2,
public truncate: TruncatePipe) {
}
@ -471,15 +474,30 @@ export class DataKeysComponent implements ControlValueAccessor, OnInit, OnChange
this.propagateChange(this.modelValue);
}
showColorPicker(key: DataKey) {
this.dialogs.colorPicker(key.color).subscribe(
(color) => {
openColorPickerPopup(key: DataKey, $event: Event, keyColorButton: HTMLDivElement) {
if ($event) {
$event.stopPropagation();
}
const trigger = keyColorButton;
if (this.popoverService.hasPopover(trigger)) {
this.popoverService.hidePopover(trigger);
} else {
const colorPickerPopover = this.popoverService.displayPopover(trigger, this.renderer,
this.viewContainerRef, ColorPickerPanelComponent, 'left', true, null,
{
color: key.color
},
{},
{}, {}, true);
colorPickerPopover.tbComponentRef.instance.popover = colorPickerPopover;
colorPickerPopover.tbComponentRef.instance.colorSelected.subscribe((color) => {
colorPickerPopover.hide();
if (color && key.color !== color) {
key.color = color;
this.propagateChange(this.modelValue);
}
}
);
});
}
}
editDataKey(key: DataKey, index: number) {

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

@ -235,14 +235,11 @@
<input matInput formControlName="comparisonValuesLabel" placeholder="{{ 'widget-config.set' | translate }}">
</mat-form-field>
</div>
<div class="tb-form-row space-between same-padding">
<div class="tb-form-row space-between">
<div>{{ 'widgets.chart.comparison-line-color' | translate }}</div>
<div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="16px">
<mat-divider vertical></mat-divider>
<tb-color-input asBoxInput
formControlName="color">
</tb-color-input>
</div>
<tb-color-input asBoxInput
formControlName="color">
</tb-color-input>
</div>
</ng-template>
</mat-expansion-panel>

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

@ -36,14 +36,11 @@
<span matSuffix>px</span>
</mat-form-field>
</div>
<div class="tb-form-row space-between same-padding">
<div class="tb-form-row space-between">
<div>{{ 'widgets.chart.threshold-color' | translate }}</div>
<div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="16px">
<mat-divider vertical></mat-divider>
<tb-color-input asBoxInput
formControlName="thresholdColor">
</tb-color-input>
</div>
<tb-color-input asBoxInput
formControlName="thresholdColor">
</tb-color-input>
</div>
</ng-template>
</mat-expansion-panel>

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

@ -61,14 +61,13 @@
<input matInput formControlName="thresholdsLineWidth" type="number" min="0" placeholder="{{ 'widget-config.set' | translate }}">
</mat-form-field>
</div>
<div class="tb-form-row space-between same-padding">
<div class="tb-form-row space-between">
<div>{{ 'widgets.chart.default-font' | translate }}</div>
<div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="16px">
<div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="8px">
<mat-form-field appearance="outline" class="number" subscriptSizing="dynamic">
<input matInput formControlName="fontSize" type="number" min="0" placeholder="{{ 'widget-config.set' | translate }}">
<span matSuffix>px</span>
</mat-form-field>
<mat-divider vertical></mat-divider>
<tb-color-input asBoxInput
formControlName="fontColor">
</tb-color-input>
@ -132,14 +131,11 @@
</mat-panel-description>
</mat-expansion-panel-header>
<ng-template matExpansionPanelContent>
<div class="tb-form-row space-between same-padding">
<div class="tb-form-row space-between">
<div>{{ 'widget-config.color' | translate }}</div>
<div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="16px">
<mat-divider vertical></mat-divider>
<tb-color-input asBoxInput
formControlName="color">
</tb-color-input>
</div>
<tb-color-input asBoxInput
formControlName="color">
</tb-color-input>
</div>
<div class="tb-form-row space-between">
<div translate>widget-config.decimals-short</div>
@ -187,14 +183,11 @@
</mat-panel-description>
</mat-expansion-panel-header>
<ng-template matExpansionPanelContent>
<div class="tb-form-row space-between same-padding">
<div class="tb-form-row space-between">
<div>{{ 'widget-config.color' | translate }}</div>
<div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="16px">
<mat-divider vertical></mat-divider>
<tb-color-input asBoxInput
formControlName="color">
</tb-color-input>
</div>
<tb-color-input asBoxInput
formControlName="color">
</tb-color-input>
</div>
</ng-template>
</mat-expansion-panel>
@ -213,36 +206,29 @@
{{ 'widgets.chart.horizontal-grid-lines' | translate }}
</mat-slide-toggle>
</div>
<div class="tb-form-row space-between same-padding">
<div class="tb-form-row space-between">
<div>{{ 'widgets.chart.grid-lines-color' | translate }}</div>
<div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="16px">
<mat-divider vertical></mat-divider>
<tb-color-input asBoxInput
formControlName="tickColor">
</tb-color-input>
</div>
<tb-color-input asBoxInput
formControlName="tickColor">
</tb-color-input>
</div>
<div class="tb-form-row space-between same-padding">
<div class="tb-form-row space-between">
<div>{{ 'widgets.chart.border' | translate }}</div>
<div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="16px">
<div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="8px">
<mat-form-field appearance="outline" class="number" subscriptSizing="dynamic">
<input matInput formControlName="outlineWidth" type="number" min="0" placeholder="{{ 'widget-config.set' | translate }}">
<span matSuffix>px</span>
</mat-form-field>
<mat-divider vertical></mat-divider>
<tb-color-input asBoxInput
formControlName="color">
</tb-color-input>
</div>
</div>
<div class="tb-form-row space-between same-padding">
<div class="tb-form-row space-between">
<div>{{ 'widgets.chart.background-color' | translate }}</div>
<div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="16px">
<mat-divider vertical></mat-divider>
<tb-color-input asBoxInput
formControlName="backgroundColor">
</tb-color-input>
</div>
<tb-color-input asBoxInput
formControlName="backgroundColor">
</tb-color-input>
</div>
</div>
<div class="tb-form-panel tb-slide-toggle">

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

@ -48,11 +48,11 @@
<input matInput formControlName="titleTooltip" placeholder="{{ 'widget-config.set' | translate }}">
</mat-form-field>
</div>
<div class="tb-form-row space-between same-padding">
<div class="tb-form-row space-between">
<mat-slide-toggle class="mat-slide" formControlName="showTitleIcon">
{{ 'widget-config.display-icon' | translate }}
</mat-slide-toggle>
<div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="16px">
<div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="8px">
<tb-material-icon-select asBoxInput
[color]="widgetSettings.get('iconColor').value"
formControlName="titleIcon">
@ -60,7 +60,6 @@
<mat-form-field appearance="outline" subscriptSizing="dynamic">
<input matInput formControlName="iconSize">
</mat-form-field>
<mat-divider vertical></mat-divider>
<tb-color-input asBoxInput
formControlName="iconColor">
</tb-color-input>
@ -84,23 +83,17 @@
</div>
<div class="tb-form-panel">
<div class="tb-form-panel-title" translate>widget-config.card-style</div>
<div class="tb-form-row space-between same-padding">
<div class="tb-form-row space-between">
<div>{{ 'widget-config.text-color' | translate }}</div>
<div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="16px">
<mat-divider vertical></mat-divider>
<tb-color-input asBoxInput
formControlName="color">
</tb-color-input>
</div>
<tb-color-input asBoxInput
formControlName="color">
</tb-color-input>
</div>
<div class="tb-form-row space-between same-padding">
<div class="tb-form-row space-between">
<div>{{ 'widget-config.background-color' | translate }}</div>
<div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="16px">
<mat-divider vertical></mat-divider>
<tb-color-input asBoxInput
formControlName="backgroundColor">
</tb-color-input>
</div>
<tb-color-input asBoxInput
formControlName="backgroundColor">
</tb-color-input>
</div>
<div class="tb-form-row space-between">
<div>{{ 'widget-config.padding' | translate }}</div>

43
ui-ngx/src/app/modules/home/pages/home-links/home-links-routing.module.ts

@ -25,20 +25,19 @@ import { DashboardService } from '@core/http/dashboard.service';
import { select, Store } from '@ngrx/store';
import { AppState } from '@core/core.state';
import { map } from 'rxjs/operators';
import {
getCurrentAuthUser,
selectHasRepository,
selectPersistDeviceStateToTelemetry
} from '@core/auth/auth.selectors';
import sysAdminHomePageDashboardJson from '!raw-loader!./sys_admin_home_page.raw';
import tenantAdminHomePageDashboardJson from '!raw-loader!./tenant_admin_home_page.raw';
import customerUserHomePageDashboardJson from '!raw-loader!./customer_user_home_page.raw';
import { getCurrentAuthUser, selectPersistDeviceStateToTelemetry } from '@core/auth/auth.selectors';
import { EntityKeyType } from '@shared/models/query/query.models';
import { ResourcesService } from '@core/services/resources.service';
const sysAdminHomePageJson = '/assets/dashboard/sys_admin_home_page.json';
const tenantAdminHomePageJson = '/assets/dashboard/tenant_admin_home_page.json';
const customerUserHomePageJson = '/assets/dashboard/customer_user_home_page.json';
@Injectable()
export class HomeDashboardResolver implements Resolve<HomeDashboard> {
constructor(private dashboardService: DashboardService,
private resourcesService: ResourcesService,
private store: Store<AppState>) {
}
@ -50,13 +49,13 @@ export class HomeDashboardResolver implements Resolve<HomeDashboard> {
const authority = getCurrentAuthUser(this.store).authority;
switch (authority) {
case Authority.SYS_ADMIN:
dashboard$ = of(JSON.parse(sysAdminHomePageDashboardJson));
dashboard$ = this.resourcesService.loadJsonResource(sysAdminHomePageJson);
break;
case Authority.TENANT_ADMIN:
dashboard$ = this.updateDeviceActivityKeyFilterIfNeeded(JSON.parse(tenantAdminHomePageDashboardJson));
dashboard$ = this.updateDeviceActivityKeyFilterIfNeeded(this.resourcesService.loadJsonResource(tenantAdminHomePageJson));
break;
case Authority.CUSTOMER_USER:
dashboard$ = this.updateDeviceActivityKeyFilterIfNeeded(JSON.parse(customerUserHomePageDashboardJson));
dashboard$ = this.updateDeviceActivityKeyFilterIfNeeded(this.resourcesService.loadJsonResource(customerUserHomePageJson));
break;
}
if (dashboard$) {
@ -73,18 +72,20 @@ export class HomeDashboardResolver implements Resolve<HomeDashboard> {
);
}
private updateDeviceActivityKeyFilterIfNeeded(dashboard: HomeDashboard): Observable<HomeDashboard> {
private updateDeviceActivityKeyFilterIfNeeded(dashboard$: Observable<HomeDashboard>): Observable<HomeDashboard> {
return this.store.pipe(select(selectPersistDeviceStateToTelemetry)).pipe(
map((persistToTelemetry) => {
if (persistToTelemetry) {
for (const filterId of Object.keys(dashboard.configuration.filters)) {
if (['Active Devices', 'Inactive Devices'].includes(dashboard.configuration.filters[filterId].filter)) {
dashboard.configuration.filters[filterId].keyFilters[0].key.type = EntityKeyType.TIME_SERIES;
mergeMap((persistToTelemetry) => dashboard$.pipe(
map((dashboard) => {
if (persistToTelemetry) {
for (const filterId of Object.keys(dashboard.configuration.filters)) {
if (['Active Devices', 'Inactive Devices'].includes(dashboard.configuration.filters[filterId].filter)) {
dashboard.configuration.filters[filterId].keyFilters[0].key.type = EntityKeyType.TIME_SERIES;
}
}
}
}
}
return dashboard;
})
return dashboard;
})
))
);
}
}

13
ui-ngx/src/app/shared/components/color-input.component.html

@ -35,7 +35,14 @@
</mat-error>
</mat-form-field>
<ng-template #boxInput>
<div class="tb-color-preview no-margin box" [ngClass]="{'disabled': disabled}" (click)="!disabled && showColorPicker($event)">
<div class="tb-color-result" [ngStyle]="!disabled ? {background: colorFormGroup.get('color').value} : {}"></div>
</div>
<button type="button"
mat-stroked-button
class="color-box"
[disabled]="disabled"
#matButton
(click)="openColorPickerPopup($event, matButton)">
<div class="tb-color-preview no-margin box" [ngClass]="{'disabled': disabled}">
<div class="tb-color-result" [ngStyle]="!disabled ? {background: colorFormGroup.get('color').value} : {}"></div>
</div>
</button>
</ng-template>

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

@ -13,6 +13,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
@import './../../../scss/mixins';
:host {
.mat-mdc-form-field {
width: 100%;
@ -29,4 +32,10 @@
margin: 0;
}
}
button.mat-mdc-button-base.color-box {
width: 40px;
min-width: 40px;
height: 40px;
padding: 7px;
}
}

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

@ -14,15 +14,24 @@
/// limitations under the License.
///
import { ChangeDetectorRef, Component, forwardRef, Input, OnInit } from '@angular/core';
import { ChangeDetectorRef, Component, forwardRef, Input, OnInit, Renderer2, ViewContainerRef } from '@angular/core';
import { PageComponent } from '@shared/components/page.component';
import { Store } from '@ngrx/store';
import { AppState } from '@core/core.state';
import { ControlValueAccessor, UntypedFormBuilder, UntypedFormGroup, NG_VALUE_ACCESSOR, Validators } from '@angular/forms';
import {
ControlValueAccessor,
NG_VALUE_ACCESSOR,
UntypedFormBuilder,
UntypedFormGroup,
Validators
} from '@angular/forms';
import { TranslateService } from '@ngx-translate/core';
import { coerceBooleanProperty } from '@angular/cdk/coercion';
import { DialogService } from '@core/services/dialog.service';
import { coerceBoolean } from '@shared/decorators/coercion';
import { TbPopoverService } from '@shared/components/popover.service';
import { ColorPickerPanelComponent } from '@shared/components/color-picker/color-picker-panel.component';
import { MatButton } from '@angular/material/button';
@Component({
selector: 'tb-color-input',
@ -100,6 +109,9 @@ export class ColorInputComponent extends PageComponent implements OnInit, Contro
constructor(protected store: Store<AppState>,
private dialogs: DialogService,
private translate: TranslateService,
private popoverService: TbPopoverService,
private renderer: Renderer2,
private viewContainerRef: ViewContainerRef,
private fb: UntypedFormBuilder,
private cd: ChangeDetectorRef) {
super(store);
@ -167,6 +179,32 @@ export class ColorInputComponent extends PageComponent implements OnInit, Contro
);
}
openColorPickerPopup($event: Event, matButton: MatButton) {
if ($event) {
$event.stopPropagation();
}
const trigger = matButton._elementRef.nativeElement;
if (this.popoverService.hasPopover(trigger)) {
this.popoverService.hidePopover(trigger);
} else {
const colorPickerPopover = this.popoverService.displayPopover(trigger, this.renderer,
this.viewContainerRef, ColorPickerPanelComponent, 'left', true, null,
{
color: this.colorFormGroup.get('color').value
},
{},
{}, {}, true);
colorPickerPopover.tbComponentRef.instance.popover = colorPickerPopover;
colorPickerPopover.tbComponentRef.instance.colorSelected.subscribe((color) => {
colorPickerPopover.hide();
this.colorFormGroup.patchValue(
{color}, {emitEvent: true}
);
this.cd.markForCheck();
});
}
}
clear() {
this.colorFormGroup.get('color').patchValue(null, {emitEvent: true});
this.cd.markForCheck();

30
ui-ngx/src/app/shared/components/color-picker/color-picker-panel.component.html

@ -0,0 +1,30 @@
<!--
Copyright © 2016-2023 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.
-->
<div class="tb-color-picker-panel">
<div class="tb-color-picker-title" translate>color.color</div>
<tb-color-picker [formControl]="colorPickerControl"></tb-color-picker>
<div class="tb-color-picker-panel-buttons">
<button mat-raised-button
color="primary"
type="button"
(click)="selectColor()"
[disabled]="colorPickerControl.invalid || !colorPickerControl.dirty">
{{ 'action.select' | translate }}
</button>
</div>
</div>

36
ui-ngx/src/app/shared/components/color-picker/color-picker-panel.component.scss

@ -0,0 +1,36 @@
/**
* Copyright © 2016-2023 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.
*/
.tb-color-picker-panel {
width: 328px;
display: flex;
flex-direction: column;
gap: 16px;
.tb-color-picker-title {
font-size: 16px;
font-weight: 500;
line-height: 24px;
letter-spacing: 0.25px;
color: rgba(0, 0, 0, 0.87);
}
.tb-color-picker-panel-buttons {
height: 60px;
display: flex;
flex-direction: row;
gap: 16px;
justify-content: flex-end;
align-items: flex-end;
}
}

55
ui-ngx/src/app/shared/components/color-picker/color-picker-panel.component.ts

@ -0,0 +1,55 @@
///
/// Copyright © 2016-2023 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.
///
import { PageComponent } from '@shared/components/page.component';
import { Component, EventEmitter, Input, OnInit, Output, ViewEncapsulation } from '@angular/core';
import { Store } from '@ngrx/store';
import { AppState } from '@core/core.state';
import { UntypedFormControl } from '@angular/forms';
import { TbPopoverComponent } from '@shared/components/popover.component';
@Component({
selector: 'tb-color-picker-panel',
templateUrl: './color-picker-panel.component.html',
providers: [],
styleUrls: ['./color-picker-panel.component.scss'],
encapsulation: ViewEncapsulation.None
})
export class ColorPickerPanelComponent extends PageComponent implements OnInit {
@Input()
color: string;
@Input()
popover: TbPopoverComponent<ColorPickerPanelComponent>;
@Output()
colorSelected = new EventEmitter<string>();
colorPickerControl: UntypedFormControl;
constructor(protected store: Store<AppState>) {
super(store);
}
ngOnInit(): void {
this.colorPickerControl = new UntypedFormControl(this.color);
}
selectColor() {
this.colorSelected.emit(this.colorPickerControl.value);
}
}

14
ui-ngx/src/app/shared/components/color-picker/color-picker.component.html

@ -19,7 +19,7 @@
<div class="control-component">
<indicator-component class="indicator-component"
[colorType]="presentations[selectedPresentation]"
[colorType]="presentations[presentationControl.value]"
[color]="control.value">
</indicator-component>
<div class="hue-alpha-range">
@ -29,7 +29,12 @@
</div>
<div class="color-input-block">
<div class="color-input" [ngSwitch]="presentations[selectedPresentation]">
<mat-select class="presentation-select" [formControl]="presentationControl">
<mat-option [value]="0">HEX</mat-option>
<mat-option [value]="1">RGBA</mat-option>
<mat-option [value]="2">HSLA</mat-option>
</mat-select>
<div class="color-input" [ngSwitch]="presentations[presentationControl.value]">
<rgba-input-component *ngSwitchCase="'rgba'" label
[(color)]="control.value" [(hue)]="control.hue"></rgba-input-component>
<hsla-input-component *ngSwitchCase="'hsla'" label
@ -37,5 +42,8 @@
<hex-input-component *ngSwitchCase="'hex'" label prefix="#" [(color)]="control.value"
[(hue)]="control.hue"></hex-input-component>
</div>
<div class="type-btn" (click)="changePresentation()"></div>
</div>
<div class="color-presets-block">
<color-presets-component class="color-presets-component" columns="11" [colorPresets]="colorPresets" [(color)]="control.value" [(hue)]="control.hue"></color-presets-component>
</div>

39
ui-ngx/src/app/shared/components/color-picker/color-picker.component.scss

@ -17,12 +17,10 @@
width: 100%;
display: flex;
flex-direction: column;
gap: 16px;
gap: 32px;
.saturation-component {
height: 100%;
min-height: 200px;
max-height: 300px;
height: 238px;
border-radius: 8px;
}
@ -55,6 +53,12 @@
.color-input-block {
display: flex;
gap: 20px;
.presentation-select {
font-size: 14px;
width: 56px;
}
.color-input {
flex: 1;
@ -63,16 +67,13 @@
color: initial;
}
}
}
.type-btn {
height: 26px;
width: 20px;
background: transparent url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAAgCAMAAAAootjDAAAAM1BMVEUAAAAzMzMzMzMzMzMzMzM0NDQzMzMzMzM0NDQzMzMzMzM0NDQzMzMzMzMyMjIrKyszMzPF8UZlAAAAEHRSTlMA1fHr4ZxxSRP45sG+sCkGH2+Z6QAAAHJJREFUKM+9kkkSgCAQA0FEVLb5/2tViqgQvNrHviSzKGCt6nDGuNass8i8NsrLiX+bZbrUtDwm7VLYE0zWUtEZ+RvUZpEvN8YhH9QmQRoC8kFpEnVHVP/DJUZVeSAem5fDKxwtms/BR+PT8gN8vwk/0wE1gQzNVYryIwAAAABJRU5ErkJggg==') no-repeat center;
background-size: 6px 12px;
&:hover {
background-color: #eee;
}
.color-presets-block {
.color-presets-component {
display: flex;
flex-direction: column;
gap: 12px;
}
}
}
@ -105,4 +106,16 @@
}
}
}
.color-presets-component {
.presets-row {
gap: 10px;
justify-content: space-between;
}
color-preset {
height: 20px;
width: 20px;
border-radius: 4px;
}
}
}

27
ui-ngx/src/app/shared/components/color-picker/color-picker.component.ts

@ -17,7 +17,7 @@
import { Component, forwardRef, OnDestroy } from '@angular/core';
import { Color, ColorPickerControl } from '@iplab/ngx-color-picker';
import { Subscription } from 'rxjs';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
import { ControlValueAccessor, NG_VALUE_ACCESSOR, UntypedFormControl } from '@angular/forms';
export enum ColorType {
hex = 'hex',
@ -29,6 +29,10 @@ export enum ColorType {
cmyk = 'cmyk'
}
const colorPresetsHex =
['#435B63', '#F44336', '#E89623', '#F5DD00', '#8BC34A', '#4CAF50', '#009688', '#048AD3', '#673AB7', '#9C27B0', '#E91E63',
'#A1ADB1', '#F9A19B', '#FFD190', '#FFF59D', '#C5E1A4', '#A5D7A7', '#80CBC3', '#81C4E9', '#B39CDB', '#CD93D7', '#F48FB1'];
@Component({
selector: `tb-color-picker`,
templateUrl: `./color-picker.component.html`,
@ -43,10 +47,13 @@ export enum ColorType {
})
export class ColorPickerComponent implements ControlValueAccessor, OnDestroy {
selectedPresentation = 0;
presentations = [ColorType.hex, ColorType.rgba, ColorType.hsla];
control = new ColorPickerControl();
presentationControl = new UntypedFormControl(0);
colorPresets: Color[] = colorPresetsHex.map(c => Color.from(c));
private modelValue: string;
private subscriptions: Array<Subscription> = [];
@ -65,6 +72,11 @@ export class ColorPickerComponent implements ControlValueAccessor, OnDestroy {
}
})
);
this.subscriptions.push(
this.presentationControl.valueChanges.subscribe(() => {
this.updateModel();
})
);
}
registerOnChange(fn: any): void {
@ -86,12 +98,11 @@ export class ColorPickerComponent implements ControlValueAccessor, OnDestroy {
} else if (this.control.initType === ColorType.hsl) {
this.control.initType = ColorType.hsla;
}
this.selectedPresentation = this.presentations.indexOf(this.control.initType);
this.presentationControl.patchValue(this.presentations.indexOf(this.control.initType), {emitEvent: false});
}
private updateModel() {
const color: string = this.getValueByType(this.control.value, this.presentations[this.selectedPresentation]);
const color: string = this.getValueByType(this.control.value, this.presentations[this.presentationControl.value]);
if (this.modelValue !== color) {
this.modelValue = color;
this.propagateChange(color);
@ -103,12 +114,6 @@ export class ColorPickerComponent implements ControlValueAccessor, OnDestroy {
this.subscriptions.length = 0;
}
public changePresentation(): void {
this.selectedPresentation =
this.selectedPresentation === this.presentations.length - 1 ? 0 : this.selectedPresentation + 1;
this.updateModel();
}
getValueByType(color: Color, type: ColorType): string {
switch (type) {
case ColorType.hex:

30
ui-ngx/src/app/shared/components/dialog/color-picker-dialog.component.html

@ -15,22 +15,14 @@
limitations under the License.
-->
<form [formGroup]="colorPickerFormGroup" (ngSubmit)="select()" style="width: 320px">
<div mat-dialog-content style="padding: 16px; display: flex">
<tb-color-picker formControlName="color"></tb-color-picker>
</div>
<div mat-dialog-actions fxLayout="row">
<span fxFlex></span>
<button mat-button
type="button"
[disabled]="(isLoading$ | async)"
(click)="cancel()">
{{ 'action.cancel' | translate }}
</button>
<button mat-button
type="submit"
[disabled]="(isLoading$ | async) || colorPickerFormGroup.invalid || !colorPickerFormGroup.dirty">
{{ 'action.select' | translate }}
</button>
</div>
</form>
<div mat-dialog-content>
<button class="tb-close-button"
mat-icon-button
(click)="cancel()"
type="button">
<mat-icon>close</mat-icon>
</button>
<tb-color-picker-panel [color]="color"
(colorSelected)="selectColor($event)">
</tb-color-picker-panel>
</div>

22
ui-ngx/src/app/shared/components/dialog/color-picker-dialog.component.scss

@ -0,0 +1,22 @@
/**
* Copyright © 2016-2023 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 {
.tb-close-button {
position: absolute;
top: 6px;
right: 6px;
}
}

24
ui-ngx/src/app/shared/components/dialog/color-picker-dialog.component.ts

@ -14,11 +14,10 @@
/// limitations under the License.
///
import { Component, Inject, OnInit } from '@angular/core';
import { Component, Inject } from '@angular/core';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { Store } from '@ngrx/store';
import { AppState } from '@core/core.state';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { Router } from '@angular/router';
import { DialogComponent } from '@shared/components/dialog.component';
@ -29,33 +28,26 @@ export interface ColorPickerDialogData {
@Component({
selector: 'tb-color-picker-dialog',
templateUrl: './color-picker-dialog.component.html',
styleUrls: []
styleUrls: ['./color-picker-dialog.component.scss']
})
export class ColorPickerDialogComponent extends DialogComponent<ColorPickerDialogComponent, string>
implements OnInit {
export class ColorPickerDialogComponent extends DialogComponent<ColorPickerDialogComponent, string> {
colorPickerFormGroup: FormGroup;
color: string;
constructor(protected store: Store<AppState>,
protected router: Router,
@Inject(MAT_DIALOG_DATA) public data: ColorPickerDialogData,
public dialogRef: MatDialogRef<ColorPickerDialogComponent, string>,
public fb: FormBuilder) {
public dialogRef: MatDialogRef<ColorPickerDialogComponent, string>) {
super(store, router, dialogRef);
this.color = data.color;
}
ngOnInit(): void {
this.colorPickerFormGroup = this.fb.group({
color: [this.data.color, [Validators.required]]
});
selectColor(color: string) {
this.dialogRef.close(color);
}
cancel(): void {
this.dialogRef.close(null);
}
select(): void {
const color: string = this.colorPickerFormGroup.get('color').value;
this.dialogRef.close(color);
}
}

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

@ -196,6 +196,7 @@ import { RuleChainSelectComponent } from '@shared/components/rule-chain/rule-cha
import { ToggleSelectComponent } from '@shared/components/toggle-select.component';
import { UnitInputComponent } from '@shared/components/unit-input.component';
import { MaterialIconsComponent } from '@shared/components/material-icons.component';
import { ColorPickerPanelComponent } from '@shared/components/color-picker/color-picker-panel.component';
export function MarkedOptionsFactory(markedOptionsService: MarkedOptionsService) {
return markedOptionsService;
@ -365,6 +366,7 @@ export function MarkedOptionsFactory(markedOptionsService: MarkedOptionsService)
GtMdLgLayoutGapDirective,
GtMdLgShowHideDirective,
ColorPickerComponent,
ColorPickerPanelComponent,
ResourceAutocompleteComponent,
ToggleHeaderComponent,
ToggleOption,
@ -597,6 +599,7 @@ export function MarkedOptionsFactory(markedOptionsService: MarkedOptionsService)
GtMdLgLayoutGapDirective,
GtMdLgShowHideDirective,
ColorPickerComponent,
ColorPickerPanelComponent,
ResourceAutocompleteComponent,
ToggleHeaderComponent,
ToggleOption,

0
ui-ngx/src/app/modules/home/pages/home-links/customer_user_home_page.raw → ui-ngx/src/assets/dashboard/customer_user_home_page.json

0
ui-ngx/src/app/modules/home/pages/home-links/sys_admin_home_page.raw → ui-ngx/src/assets/dashboard/sys_admin_home_page.json

0
ui-ngx/src/app/modules/home/pages/home-links/tenant_admin_home_page.raw → ui-ngx/src/assets/dashboard/tenant_admin_home_page.json

3
ui-ngx/src/assets/locale/locale.constant-en_US.json

@ -5500,6 +5500,9 @@
}
}
},
"color": {
"color": "Color"
},
"icon": {
"icon": "Icon",
"icons": "Icons",

53
ui-ngx/src/form.scss

@ -131,14 +131,11 @@
}
.tb-form-row {
height: 100%;
padding-top: 7px;
padding-bottom: 7px;
display: flex;
flex-direction: row;
align-items: center;
gap: 16px;
padding-left: 16px;
padding-right: 12px;
padding: 7px 7px 7px 16px;
border: 1px solid rgba(0, 0, 0, 0.12);
border-radius: 6px;
&.same-padding {
@ -314,33 +311,33 @@
.tb-prompt {
height: 38px;
}
}
.tb-form-table-row {
height: 38px;
display: flex;
flex-direction: row;
gap: 12px;
padding-left: 12px;
.tb-form-table-row {
height: 38px;
display: flex;
flex-direction: row;
gap: 12px;
padding-left: 12px;
&.tb-draggable {
gap: 0;
padding-left: 0;
background: #fff;
}
&.tb-draggable {
gap: 0;
padding-left: 0;
background: #fff;
}
&-cell-buttons {
display: flex;
flex-direction: row;
button.mat-mdc-icon-button.mat-mdc-button-base {
padding: 7px;
width: 38px;
height: 38px;
.mat-icon {
color: rgba(0, 0, 0, 0.38);
}
&.tb-hidden {
visibility: hidden;
}
&-cell-buttons {
display: flex;
flex-direction: row;
button.mat-mdc-icon-button.mat-mdc-button-base {
padding: 7px;
width: 38px;
height: 38px;
.mat-icon {
color: rgba(0, 0, 0, 0.38);
}
&.tb-hidden {
visibility: hidden;
}
}
}

Loading…
Cancel
Save