Merge pull request #8547 from thingsboard/feature/dashboard-edit-panel
Improve dashboard edit panel
This commit is contained in:
commit
07ff1ab44a
@ -15,17 +15,17 @@
|
||||
limitations under the License.
|
||||
|
||||
-->
|
||||
<section class="tb-aliases-entity-select" fxLayout="row" fxLayoutAlign="start center">
|
||||
<section class="tb-aliases-entity-select" fxLayout="row" fxLayoutAlign="start center" *ngIf="hasSelectableAliasEntities">
|
||||
<button mat-icon-button
|
||||
cdkOverlayOrigin #aliasEntitySelectPanelOrigin="cdkOverlayOrigin"
|
||||
(click)="openEditMode()"
|
||||
matTooltip="{{ hasSelectableAliasEntities ? ('entity.select-entities' | translate) : '' }}"
|
||||
matTooltip="{{ 'entity.select-entities' | translate }}"
|
||||
[matTooltipPosition]="tooltipPosition">
|
||||
<mat-icon class="material-icons">devices_other</mat-icon>
|
||||
</button>
|
||||
<span fxHide.lt-lg
|
||||
(click)="openEditMode()"
|
||||
matTooltip="{{ hasSelectableAliasEntities ? ('entity.select-entities' | translate) : '' }}"
|
||||
matTooltip="{{ 'entity.select-entities' | translate }}"
|
||||
[matTooltipPosition]="tooltipPosition">
|
||||
{{displayValue}}
|
||||
</span>
|
||||
|
||||
@ -16,9 +16,11 @@
|
||||
@import "../../../../../scss/constants";
|
||||
|
||||
:host {
|
||||
min-width: 52px;
|
||||
|
||||
&.tb-hide {
|
||||
display: none;
|
||||
}
|
||||
section.tb-aliases-entity-select {
|
||||
min-width: 52px;
|
||||
min-height: 32px;
|
||||
padding: 0 6px;
|
||||
|
||||
|
||||
@ -16,7 +16,7 @@
|
||||
|
||||
import {
|
||||
ChangeDetectorRef,
|
||||
Component,
|
||||
Component, HostBinding,
|
||||
Injector,
|
||||
Input,
|
||||
OnDestroy,
|
||||
@ -47,6 +47,9 @@ import { AliasFilterType } from '@shared/models/alias.models';
|
||||
})
|
||||
export class AliasesEntitySelectComponent implements OnInit, OnDestroy {
|
||||
|
||||
@HostBinding('class')
|
||||
aliasesEntitySelectClass = 'tb-hide';
|
||||
|
||||
aliasControllerValue: IAliasController;
|
||||
|
||||
@Input()
|
||||
@ -188,12 +191,14 @@ export class AliasesEntitySelectComponent implements OnInit, OnDestroy {
|
||||
const allEntityAliases = this.aliasController.getEntityAliases();
|
||||
this.entityAliasesInfo = {};
|
||||
this.hasSelectableAliasEntities = false;
|
||||
this.aliasesEntitySelectClass = 'tb-hide';
|
||||
for (const aliasId of Object.keys(allEntityAliases)) {
|
||||
const aliasInfo = this.aliasController.getInstantAliasInfo(aliasId);
|
||||
if (aliasInfo && !aliasInfo.resolveMultiple && aliasInfo.currentEntity
|
||||
&& aliasInfo.entityFilter && aliasInfo.entityFilter.type !== AliasFilterType.singleEntity) {
|
||||
this.entityAliasesInfo[aliasId] = deepClone(aliasInfo);
|
||||
this.hasSelectableAliasEntities = true;
|
||||
this.aliasesEntitySelectClass = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -26,26 +26,41 @@
|
||||
<div class="tb-dashboard-action-panels" fxLayout="column" fxLayout.gt-sm="row"
|
||||
fxLayoutAlign="center stretch" fxLayoutAlign.gt-sm="space-between center">
|
||||
<div class="tb-dashboard-action-panel" fxFlex="auto" fxLayout="row-reverse" [fxHide]="isMobileApp && !isEdit"
|
||||
fxLayoutAlign.gt-sm="end center" fxLayoutAlign="space-between center" fxLayoutGap="12px">
|
||||
fxLayoutAlign.gt-sm="end center" fxLayoutAlign="space-between center" fxLayoutGap.lt-lg="6px" fxLayoutGap.gt-md="12px">
|
||||
<tb-user-menu *ngIf="!isPublicUser() && forceFullscreen" fxHide.gt-sm displayUserInfo="true">
|
||||
</tb-user-menu>
|
||||
<div [fxShow]="isEdit"
|
||||
fxFlex.lt-md fxLayout="row"
|
||||
<ng-container *ngIf="isEdit">
|
||||
<div fxFlex.lt-md fxLayout="row"
|
||||
fxLayoutAlign.gt-sm="start center"
|
||||
fxLayoutAlign="end center" fxLayoutGap="12px">
|
||||
<button mat-icon-button
|
||||
fxLayoutAlign="end center" fxLayoutGap.lt-lg="6px" fxLayoutGap.gt-md="12px">
|
||||
<button fxHide.gt-md mat-icon-button
|
||||
matTooltip="{{'dashboard.manage-states' | translate}}"
|
||||
matTooltipPosition="below"
|
||||
(click)="manageDashboardStates($event)">
|
||||
<mat-icon>layers</mat-icon>
|
||||
</button>
|
||||
<button mat-icon-button
|
||||
<button fxHide.lt-lg mat-button
|
||||
matTooltip="{{'dashboard.manage-states' | translate}}"
|
||||
matTooltipPosition="below"
|
||||
(click)="manageDashboardStates($event)">
|
||||
<mat-icon>layers</mat-icon>
|
||||
{{'dashboard.states-short' | translate}}
|
||||
</button>
|
||||
<button fxHide.gt-md mat-icon-button
|
||||
matTooltip="{{'layout.manage' | translate}}"
|
||||
matTooltipPosition="below"
|
||||
(click)="manageDashboardLayouts($event)">
|
||||
<mat-icon>view_compact</mat-icon>
|
||||
</button>
|
||||
<button fxHide.lt-lg mat-button
|
||||
matTooltip="{{'layout.manage' | translate}}"
|
||||
matTooltipPosition="below"
|
||||
(click)="manageDashboardLayouts($event)">
|
||||
<mat-icon>view_compact</mat-icon>
|
||||
{{'layout.layouts' | translate}}
|
||||
</button>
|
||||
</div>
|
||||
</ng-container>
|
||||
<tb-states-component fxFlex.lt-md
|
||||
[statesControllerId]="isEdit ? 'default' : dashboardConfiguration.settings.stateControllerId"
|
||||
[dashboardCtrl]="this"
|
||||
@ -60,7 +75,7 @@
|
||||
aria-label="dashboard_logo" class="dashboard_logo"/>
|
||||
</div>
|
||||
<div class="tb-dashboard-action-panel" fxFlex="1 0 auto" fxLayout="row-reverse"
|
||||
fxLayoutAlign.gt-sm="start center" fxLayoutAlign="space-between center" fxLayoutGap="12px">
|
||||
fxLayoutAlign.gt-sm="start center" fxLayoutAlign="space-between center" fxLayoutGap.lt-lg="6px" fxLayoutGap.gt-md="12px">
|
||||
<button [fxShow]="showCloseToolbar()" mat-icon-button class="close-action"
|
||||
matTooltip="{{ 'dashboard.close-toolbar' | translate }}"
|
||||
matTooltipPosition="below"
|
||||
@ -81,34 +96,147 @@
|
||||
(click)="isFullscreen = !isFullscreen">
|
||||
<mat-icon>{{ isFullscreen ? 'fullscreen_exit' : 'fullscreen' }}</mat-icon>
|
||||
</button>
|
||||
<button [fxShow]="currentDashboardId && isEdit && isTenantAdmin()" mat-icon-button
|
||||
<button [fxShow]="currentDashboardId && !isMobileApp && displayExport() && !isEdit" mat-icon-button
|
||||
matTooltip="{{'dashboard.export' | translate}}"
|
||||
matTooltipPosition="below"
|
||||
(click)="exportDashboard($event)">
|
||||
<mat-icon>file_download</mat-icon>
|
||||
</button>
|
||||
<ng-container *ngIf="!readonly && !isEdit">
|
||||
<button fxHide.gt-md mat-icon-button (click)="toggleDashboardEditMode()"
|
||||
matTooltip="{{'dashboard.edit-mode' | translate}}"
|
||||
matTooltipPosition="below">
|
||||
<mat-icon>edit</mat-icon></button>
|
||||
<button fxHide.lt-lg mat-stroked-button (click)="toggleDashboardEditMode()">
|
||||
<mat-icon>edit</mat-icon>{{'dashboard.edit-mode' | translate}}</button>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="isEdit">
|
||||
<button fxHide.gt-md mat-icon-button (click)="saveDashboard()"
|
||||
matTooltip="{{'action.save' | translate}}"
|
||||
matTooltipPosition="below">
|
||||
<mat-icon>done</mat-icon></button>
|
||||
<button fxHide.lt-lg mat-button (click)="saveDashboard()">
|
||||
<mat-icon>done</mat-icon>{{ 'action.save' | translate }}</button>
|
||||
<button fxHide.gt-md mat-icon-button (click)="toggleDashboardEditMode()"
|
||||
matTooltip="{{'action.cancel' | translate}}"
|
||||
matTooltipPosition="below">
|
||||
<mat-icon>close</mat-icon></button>
|
||||
<button fxHide.lt-lg mat-button (click)="toggleDashboardEditMode()">
|
||||
<mat-icon>close</mat-icon>{{ 'action.cancel' | translate }}</button>
|
||||
<mat-divider class="tb-toolbar-divider" vertical></mat-divider>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="currentDashboardId && isEdit && isTenantAdmin()">
|
||||
<button fxHide.lt-lg fxHide.gt-lg mat-icon-button
|
||||
#versionControlIconButton
|
||||
matTooltip="{{'version-control.version-control' | translate}}"
|
||||
matTooltipPosition="below"
|
||||
(click)="toggleVersionControl($event, versionControlIconButton)">
|
||||
<mat-icon>history</mat-icon>
|
||||
</button>
|
||||
<button fxHide.lt-xl mat-button
|
||||
#versionControlButton
|
||||
matTooltip="{{'version-control.version-control' | translate}}"
|
||||
matTooltipPosition="below"
|
||||
(click)="toggleVersionControl($event, versionControlButton)">
|
||||
<mat-icon>history</mat-icon>
|
||||
{{'version-control.versions' | translate}}
|
||||
</button>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="isEdit">
|
||||
<button fxHide.gt-lg mat-icon-button
|
||||
matTooltip="{{ 'filter.filters' | translate }}"
|
||||
matTooltipPosition="below"
|
||||
(click)="openFilters($event)">
|
||||
<mat-icon>filter_list</mat-icon>
|
||||
</button>
|
||||
<button fxHide.lt-xl mat-button
|
||||
matTooltip="{{ 'filter.filters' | translate }}"
|
||||
matTooltipPosition="below"
|
||||
(click)="openFilters($event)">
|
||||
<mat-icon>filter_list</mat-icon>
|
||||
{{ 'filter.filters' | translate }}
|
||||
</button>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="isEdit">
|
||||
<button fxHide.gt-lg mat-icon-button
|
||||
matTooltip="{{ 'entity.aliases' | translate }}"
|
||||
matTooltipPosition="below"
|
||||
(click)="openEntityAliases($event)">
|
||||
<mat-icon>devices_other</mat-icon>
|
||||
</button>
|
||||
<button fxHide.lt-xl mat-button
|
||||
matTooltip="{{ 'entity.aliases' | translate }}"
|
||||
matTooltipPosition="below"
|
||||
(click)="openEntityAliases($event)">
|
||||
<mat-icon>devices_other</mat-icon>
|
||||
{{ 'entity.aliases-short' | translate }}
|
||||
</button>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="isEdit">
|
||||
<button fxHide.gt-lg mat-icon-button
|
||||
matTooltip="{{ 'dashboard.settings' | translate }}"
|
||||
matTooltipPosition="below"
|
||||
(click)="openDashboardSettings($event)">
|
||||
<mat-icon>settings</mat-icon>
|
||||
</button>
|
||||
<button fxHide.lt-xl mat-button
|
||||
matTooltip="{{ 'dashboard.settings' | translate }}"
|
||||
matTooltipPosition="below"
|
||||
(click)="openDashboardSettings($event)">
|
||||
<mat-icon>settings</mat-icon>
|
||||
{{ 'dashboard.settings' | translate }}
|
||||
</button>
|
||||
</ng-container>
|
||||
<button [fxShow]="currentDashboardId && !isEdit && !isMobileApp && isTenantAdmin() && displayUpdateDashboardImage()" mat-icon-button
|
||||
matTooltip="{{'dashboard.update-image' | translate}}"
|
||||
matTooltipPosition="below"
|
||||
(click)="updateDashboardImage($event)">
|
||||
<mat-icon>wallpaper</mat-icon>
|
||||
</button>
|
||||
<button [fxShow]="currentDashboardId && !isMobileApp && (isEdit || displayExport())" mat-icon-button
|
||||
matTooltip="{{'dashboard.export' | translate}}"
|
||||
matTooltipPosition="below"
|
||||
(click)="exportDashboard($event)">
|
||||
<mat-icon>file_download</mat-icon>
|
||||
</button>
|
||||
<tb-timewindow [fxShow]="isEdit || displayDashboardTimewindow()"
|
||||
isToolbar="true"
|
||||
[isEdit]="isEdit"
|
||||
<ng-container *ngIf="isEdit; else timewindowTemplate">
|
||||
<tb-timewindow fxHide.lt-xl asButton
|
||||
flatButton
|
||||
[displayTimewindowValue]="false"
|
||||
[isEdit]="true"
|
||||
direction="left"
|
||||
tooltipPosition="below"
|
||||
aggregation="true"
|
||||
timezone="true"
|
||||
[(ngModel)]="dashboardCtx.dashboardTimewindow">
|
||||
</tb-timewindow>
|
||||
<tb-timewindow fxHide.gt-lg
|
||||
hideLabel
|
||||
[isEdit]="true"
|
||||
direction="left"
|
||||
tooltipPosition="below"
|
||||
aggregation="true"
|
||||
timezone="true"
|
||||
[(ngModel)]="dashboardCtx.dashboardTimewindow">
|
||||
</tb-timewindow>
|
||||
</ng-container>
|
||||
<ng-template #timewindowTemplate>
|
||||
<ng-container *ngIf="displayDashboardTimewindow()">
|
||||
<tb-timewindow fxHide.gt-md
|
||||
[isEdit]="false"
|
||||
hideLabel
|
||||
direction="left"
|
||||
tooltipPosition="below"
|
||||
aggregation="true"
|
||||
timezone="true"
|
||||
[(ngModel)]="dashboardCtx.dashboardTimewindow">
|
||||
</tb-timewindow>
|
||||
<tb-timewindow fxHide.lt-lg
|
||||
[isEdit]="false"
|
||||
direction="left"
|
||||
tooltipPosition="below"
|
||||
aggregation="true"
|
||||
timezone="true"
|
||||
[(ngModel)]="dashboardCtx.dashboardTimewindow">
|
||||
</tb-timewindow>
|
||||
</ng-container>
|
||||
</ng-template>
|
||||
<button [fxShow]="isEdit" mat-stroked-button (click)="addWidget($event)">
|
||||
<mat-icon>add</mat-icon>{{ 'dashboard.add-widget-button-text' | translate }}</button>
|
||||
<tb-filters-edit [fxShow]="!isEdit && displayFilters()"
|
||||
tooltipPosition="below"
|
||||
[aliasController]="dashboardCtx.aliasController">
|
||||
@ -117,24 +245,6 @@
|
||||
tooltipPosition="below"
|
||||
[aliasController]="dashboardCtx.aliasController">
|
||||
</tb-aliases-entity-select>
|
||||
<button [fxShow]="isEdit" mat-icon-button
|
||||
matTooltip="{{ 'filter.filters' | translate }}"
|
||||
matTooltipPosition="below"
|
||||
(click)="openFilters($event)">
|
||||
<mat-icon>filter_list</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-icon-button
|
||||
matTooltip="{{ 'dashboard.settings' | translate }}"
|
||||
matTooltipPosition="below"
|
||||
(click)="openDashboardSettings($event)">
|
||||
<mat-icon>settings</mat-icon>
|
||||
</button>
|
||||
<tb-dashboard-select *ngIf="!isEdit && !widgetEditMode && !embedded && displayDashboardsSelect()"
|
||||
[(ngModel)]="currentDashboardId"
|
||||
(ngModelChange)="currentDashboardIdChanged(currentDashboardId)"
|
||||
@ -157,7 +267,7 @@
|
||||
<section *ngIf="!widgetEditMode" class="tb-dashboard-title"
|
||||
[ngStyle]="{'color': dashboard.configuration.settings.titleColor}">
|
||||
<h3 [fxShow]="!isEdit && displayTitle()">{{ translatedDashboardTitle }}</h3>
|
||||
<mat-form-field [fxShow]="isEdit" class="mat-block tb-appearance-transparent">
|
||||
<mat-form-field [fxShow]="isEdit" class="mat-block tb-appearance-transparent" subscriptSizing="dynamic">
|
||||
<mat-label translate [ngStyle]="{'color': dashboard.configuration.settings.titleColor}">dashboard.title</mat-label>
|
||||
<input matInput class="tb-dashboard-title"
|
||||
[ngStyle]="{'color': dashboard.configuration.settings.titleColor}"
|
||||
@ -206,28 +316,32 @@
|
||||
</tb-dashboard-layout>
|
||||
</mat-drawer-content>
|
||||
</mat-drawer-container>
|
||||
<section data-html2canvas-ignore fxLayout="row" class="layout-wrap tb-footer-buttons" fxLayoutAlign="start end"
|
||||
*ngIf="!readonly">
|
||||
<tb-footer-fab-buttons [fxShow]="!isAddingWidget && isEdit && !widgetEditMode"
|
||||
relative
|
||||
[footerFabButtons]="addWidgetFabButtons">
|
||||
</tb-footer-fab-buttons>
|
||||
<button mat-fab color="accent" class="tb-btn-footer"
|
||||
[ngClass]="{'tb-hide': !isEdit || isAddingWidget}"
|
||||
[disabled]="isLoading$ | async"
|
||||
(click)="saveDashboard()"
|
||||
matTooltip="{{ 'action.apply-changes' | translate }}"
|
||||
matTooltipPosition="above">
|
||||
<mat-icon>done</mat-icon>
|
||||
</button>
|
||||
<button mat-fab color="accent" class="tb-btn-footer"
|
||||
[ngClass]="{'tb-hide': isAddingWidget || (isLoading$ | async)}"
|
||||
[disabled]="isLoading$ | async"
|
||||
<section data-html2canvas-ignore fxLayout="row" class="layout-wrap tb-header-buttons tb-enter-edit-mode" fxLayoutAlign="start end" *ngIf="!readonly && (hideToolbar || widgetEditMode)">
|
||||
<button [fxShow]="!isEdit"
|
||||
color="primary"
|
||||
mat-mini-fab
|
||||
class="tb-btn-header tb-btn-edit"
|
||||
(click)="toggleDashboardEditMode()"
|
||||
matTooltip="{{ (isEdit ? 'action.decline-changes': 'action.enter-edit-mode') | translate }}"
|
||||
matTooltip="{{ 'action.enter-edit-mode' | translate }}"
|
||||
matTooltipPosition="above">
|
||||
<mat-icon>{{ isEdit ? 'close' : 'edit' }}</mat-icon>
|
||||
<mat-icon>edit</mat-icon>
|
||||
</button>
|
||||
<button [fxShow]="isEdit"
|
||||
color="primary"
|
||||
mat-mini-fab
|
||||
class="tb-btn-header tb-btn-edit"
|
||||
(click)="saveDashboard()"
|
||||
matTooltip="{{'action.save' | translate}}"
|
||||
matTooltipPosition="below">
|
||||
<mat-icon>done</mat-icon></button>
|
||||
<button [fxShow]="isEdit"
|
||||
color="primary"
|
||||
mat-mini-fab
|
||||
class="tb-btn-header tb-btn-edit"
|
||||
(click)="toggleDashboardEditMode()"
|
||||
matTooltip="{{'action.cancel' | translate}}"
|
||||
matTooltipPosition="below">
|
||||
<mat-icon>close</mat-icon></button>
|
||||
</section>
|
||||
<section *ngIf="!embedded" data-html2canvas-ignore class="tb-powered-by-footer" [ngStyle]="{'color': dashboard.configuration.settings.titleColor}">
|
||||
<span>Powered by <a href="https://thingsboard.io" target="_blank">Thingsboard v.{{ thingsboardVersion }}</a></span>
|
||||
@ -285,6 +399,9 @@
|
||||
</tb-widgets-bundle-search>
|
||||
</div>
|
||||
<div class="details-buttons" *ngIf="isAddingWidget">
|
||||
<button mat-button type="button" (click)="importWidget($event)"
|
||||
*ngIf="!dashboardWidgetSelectComponent?.widgetsBundle">
|
||||
<mat-icon>file_upload</mat-icon>{{ 'dashboard.import-widget' | translate }}</button>
|
||||
<button mat-icon-button type="button"
|
||||
*ngIf="dashboardWidgetSelectComponent?.widgetTypes.size > 1"
|
||||
(click)="editWidgetsTypesToDisplay($event)"
|
||||
|
||||
@ -77,6 +77,11 @@ div.tb-dashboard-page {
|
||||
}
|
||||
}
|
||||
|
||||
.mat-divider-vertical.tb-toolbar-divider {
|
||||
border-right-color: rgba(255,255,255,0.75);
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
.tb-dashboard-container {
|
||||
&.tb-dashboard-toolbar-opened {
|
||||
&.is-fullscreen {
|
||||
@ -139,6 +144,13 @@ div.tb-dashboard-page {
|
||||
}
|
||||
}
|
||||
|
||||
section.tb-header-buttons.tb-enter-edit-mode {
|
||||
top: 2px;
|
||||
.mdc-fab.tb-btn-edit {
|
||||
opacity: .5;
|
||||
}
|
||||
}
|
||||
|
||||
section.tb-powered-by-footer {
|
||||
position: absolute;
|
||||
right: 25px;
|
||||
|
||||
@ -85,7 +85,6 @@ import { DialogService } from '@core/services/dialog.service';
|
||||
import { EntityService } from '@core/http/entity.service';
|
||||
import { AliasController } from '@core/api/alias-controller';
|
||||
import { Observable, of, Subscription } from 'rxjs';
|
||||
import { FooterFabButtons } from '@shared/components/footer-fab-buttons.component';
|
||||
import { DashboardUtilsService } from '@core/services/dashboard-utils.service';
|
||||
import { DashboardService } from '@core/http/dashboard.service';
|
||||
import {
|
||||
@ -293,27 +292,6 @@ export class DashboardPageComponent extends PageComponent implements IDashboardC
|
||||
}
|
||||
};
|
||||
|
||||
addWidgetFabButtons: FooterFabButtons = {
|
||||
fabTogglerName: 'dashboard.add-widget',
|
||||
fabTogglerIcon: 'add',
|
||||
buttons: [
|
||||
{
|
||||
name: 'dashboard.create-new-widget',
|
||||
icon: 'insert_drive_file',
|
||||
onAction: ($event) => {
|
||||
this.addWidget($event);
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'dashboard.import-widget',
|
||||
icon: 'file_upload',
|
||||
onAction: ($event) => {
|
||||
this.importWidget($event);
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
updateBreadcrumbs = new EventEmitter();
|
||||
|
||||
private rxSubscriptions = new Array<Subscription>();
|
||||
@ -580,7 +558,7 @@ export class DashboardPageComponent extends PageComponent implements IDashboardC
|
||||
}
|
||||
|
||||
public hideFullscreenButton(): boolean {
|
||||
return this.widgetEditMode || this.iframeMode || this.forceFullscreen || this.singlePageMode;
|
||||
return (this.widgetEditMode || this.iframeMode || this.forceFullscreen || this.singlePageMode || this.isEdit);
|
||||
}
|
||||
|
||||
public toolbarAlwaysOpen(): boolean {
|
||||
@ -927,7 +905,7 @@ export class DashboardPageComponent extends PageComponent implements IDashboardC
|
||||
this.openDashboardState(targetState);
|
||||
}
|
||||
|
||||
private importWidget($event: Event) {
|
||||
public importWidget($event: Event) {
|
||||
if ($event) {
|
||||
$event.stopPropagation();
|
||||
}
|
||||
@ -935,6 +913,10 @@ export class DashboardPageComponent extends PageComponent implements IDashboardC
|
||||
this.selectTargetLayout.bind(this), this.entityAliasesUpdated.bind(this), this.filtersUpdated.bind(this)).subscribe(
|
||||
(importData) => {
|
||||
if (importData) {
|
||||
if (this.isAddingWidget) {
|
||||
this.onAddWidgetClosed();
|
||||
this.isAddingWidgetClosed = true;
|
||||
}
|
||||
const widget = importData.widget;
|
||||
const layoutId = importData.layoutId;
|
||||
this.layouts[layoutId].layoutCtx.widgets.addWidgetId(widget.id);
|
||||
@ -1018,6 +1000,14 @@ export class DashboardPageComponent extends PageComponent implements IDashboardC
|
||||
this.dashboardCtx.stateController.preserveState();
|
||||
this.prevDashboard = deepClone(this.dashboard);
|
||||
} else {
|
||||
if (this.isEditingWidget) {
|
||||
this.onEditWidgetClosed();
|
||||
this.isEditingWidgetClosed = true;
|
||||
}
|
||||
if (this.isAddingWidget) {
|
||||
this.onAddWidgetClosed();
|
||||
this.isAddingWidgetClosed = true;
|
||||
}
|
||||
if (this.widgetEditMode) {
|
||||
if (revert) {
|
||||
this.dashboard = this.prevDashboard;
|
||||
@ -1088,6 +1078,11 @@ export class DashboardPageComponent extends PageComponent implements IDashboardC
|
||||
if ($event) {
|
||||
$event.stopPropagation();
|
||||
}
|
||||
if (this.isEditingWidget) {
|
||||
this.onEditWidgetClosed();
|
||||
this.isEditingWidgetClosed = true;
|
||||
this.isAddingWidgetClosed = false;
|
||||
}
|
||||
this.isAddingWidget = true;
|
||||
this.addingLayoutCtx = layoutCtx;
|
||||
}
|
||||
@ -1456,9 +1451,8 @@ export class DashboardPageComponent extends PageComponent implements IDashboardC
|
||||
});
|
||||
|
||||
const filterWidgetTypes = this.dashboardWidgetSelectComponent.filterWidgetTypes;
|
||||
const widgetTypesList = Array.from(this.dashboardWidgetSelectComponent.widgetTypes.values()).map(type => {
|
||||
return {type, display: filterWidgetTypes === null ? true : filterWidgetTypes.includes(type)};
|
||||
});
|
||||
const widgetTypesList = Array.from(this.dashboardWidgetSelectComponent.widgetTypes.values()).map(type =>
|
||||
({type, display: filterWidgetTypes === null ? true : filterWidgetTypes.includes(type)}));
|
||||
|
||||
const providers: StaticProvider[] = [
|
||||
{
|
||||
@ -1522,14 +1516,12 @@ export class DashboardPageComponent extends PageComponent implements IDashboardC
|
||||
externalEntityId: this.dashboard.externalId || this.dashboard.id,
|
||||
entityId: this.dashboard.id,
|
||||
entityName: this.dashboard.name,
|
||||
onBeforeCreateVersion: () => {
|
||||
return this.dashboardService.saveDashboard(this.dashboard).pipe(
|
||||
onBeforeCreateVersion: () => this.dashboardService.saveDashboard(this.dashboard).pipe(
|
||||
tap((dashboard) => {
|
||||
this.dashboard = this.dashboardUtils.validateAndUpdateDashboard(dashboard);
|
||||
this.prevDashboard = deepClone(this.dashboard);
|
||||
})
|
||||
);
|
||||
}
|
||||
)
|
||||
}, {}, {}, {}, true);
|
||||
versionControlPopover.tbComponentRef.instance.popoverComponent = versionControlPopover;
|
||||
versionControlPopover.tbComponentRef.instance.versionRestored.subscribe(() => {
|
||||
|
||||
@ -16,6 +16,9 @@
|
||||
@import "../../../../../scss/constants";
|
||||
|
||||
:host {
|
||||
&.tb-hide {
|
||||
display: none;
|
||||
}
|
||||
section.tb-filters-edit {
|
||||
min-height: 32px;
|
||||
padding: 0 6px;
|
||||
|
||||
@ -15,7 +15,7 @@
|
||||
///
|
||||
|
||||
import {
|
||||
Component,
|
||||
Component, HostBinding,
|
||||
Injector,
|
||||
Input,
|
||||
OnDestroy,
|
||||
@ -48,6 +48,9 @@ import { MatDialog } from '@angular/material/dialog';
|
||||
})
|
||||
export class FiltersEditComponent implements OnInit, OnDestroy {
|
||||
|
||||
@HostBinding('class')
|
||||
filtersEditClass = 'tb-hide';
|
||||
|
||||
aliasControllerValue: IAliasController;
|
||||
|
||||
@Input()
|
||||
@ -174,11 +177,13 @@ export class FiltersEditComponent implements OnInit, OnDestroy {
|
||||
const allFilters = this.aliasController.getFilters();
|
||||
this.filtersInfo = {};
|
||||
this.hasEditableFilters = false;
|
||||
this.filtersEditClass = 'tb-hide';
|
||||
for (const filterId of Object.keys(allFilters)) {
|
||||
const filterInfo = this.aliasController.getFilterInfo(filterId);
|
||||
if (filterInfo && isFilterEditable(filterInfo)) {
|
||||
this.filtersInfo[filterId] = deepClone(filterInfo);
|
||||
this.hasEditableFilters = true;
|
||||
this.filtersEditClass = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -15,13 +15,13 @@
|
||||
limitations under the License.
|
||||
|
||||
-->
|
||||
<button *ngIf="asButton && !strokedButton"
|
||||
<button *ngIf="asButton && !strokedButton && !flatButton"
|
||||
[disabled]="timewindowDisabled"
|
||||
type="button"
|
||||
mat-raised-button color="primary"
|
||||
(click)="toggleTimewindow($event)">
|
||||
<mat-icon class="material-icons">query_builder</mat-icon>
|
||||
<span>{{innerValue?.displayValue}}</span>
|
||||
<span>{{displayValue()}}</span>
|
||||
</button>
|
||||
<button *ngIf="asButton && strokedButton"
|
||||
[disabled]="timewindowDisabled"
|
||||
@ -29,7 +29,15 @@
|
||||
mat-stroked-button color="primary"
|
||||
(click)="toggleTimewindow($event)">
|
||||
<mat-icon class="material-icons">query_builder</mat-icon>
|
||||
<span>{{innerValue?.displayValue}}</span>
|
||||
<span>{{displayValue()}}</span>
|
||||
</button>
|
||||
<button *ngIf="asButton && flatButton"
|
||||
[disabled]="timewindowDisabled"
|
||||
type="button"
|
||||
mat-button
|
||||
(click)="toggleTimewindow($event)">
|
||||
<mat-icon class="material-icons">query_builder</mat-icon>
|
||||
<span>{{displayValue()}}</span>
|
||||
</button>
|
||||
<section *ngIf="!asButton"
|
||||
class="tb-timewindow"
|
||||
@ -42,7 +50,7 @@
|
||||
[matTooltipPosition]="tooltipPosition">
|
||||
<mat-icon class="material-icons">query_builder</mat-icon>
|
||||
</button>
|
||||
<span [fxHide]="hideLabel()"
|
||||
<span [fxHide]="hideLabel"
|
||||
(click)="toggleTimewindow($event)"
|
||||
matTooltip="{{ 'timewindow.edit' | translate }}"
|
||||
[matTooltipPosition]="tooltipPosition">
|
||||
|
||||
@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
:host {
|
||||
min-width: 52px;
|
||||
min-width: 48px;
|
||||
margin: 8px 0;
|
||||
max-width: 100%;
|
||||
.mdc-button {
|
||||
@ -22,7 +22,7 @@
|
||||
}
|
||||
section.tb-timewindow {
|
||||
min-height: 32px;
|
||||
padding: 0 6px;
|
||||
padding: 0 8px;
|
||||
|
||||
span {
|
||||
overflow: hidden;
|
||||
|
||||
@ -45,8 +45,6 @@ import {
|
||||
TimewindowPanelComponent,
|
||||
TimewindowPanelData
|
||||
} from '@shared/components/time/timewindow-panel.component';
|
||||
import { MediaBreakpoints } from '@shared/models/constants';
|
||||
import { BreakpointObserver } from '@angular/cdk/layout';
|
||||
import { TimeService } from '@core/services/time.service';
|
||||
import { TooltipPosition } from '@angular/material/tooltip';
|
||||
import { deepClone, isDefinedAndNotNull } from '@core/utils';
|
||||
@ -135,17 +133,6 @@ export class TimewindowComponent implements OnInit, OnDestroy, ControlValueAcces
|
||||
return this.timezoneValue;
|
||||
}
|
||||
|
||||
isToolbarValue = false;
|
||||
|
||||
@Input()
|
||||
set isToolbar(val) {
|
||||
this.isToolbarValue = coerceBooleanProperty(val);
|
||||
}
|
||||
|
||||
get isToolbar() {
|
||||
return this.isToolbarValue;
|
||||
}
|
||||
|
||||
asButtonValue = false;
|
||||
|
||||
@Input()
|
||||
@ -161,6 +148,18 @@ export class TimewindowComponent implements OnInit, OnDestroy, ControlValueAcces
|
||||
@coerceBoolean()
|
||||
strokedButton = false;
|
||||
|
||||
@Input()
|
||||
@coerceBoolean()
|
||||
flatButton = false;
|
||||
|
||||
@Input()
|
||||
@coerceBoolean()
|
||||
displayTimewindowValue = true;
|
||||
|
||||
@Input()
|
||||
@coerceBoolean()
|
||||
hideLabel = false;
|
||||
|
||||
isEditValue = false;
|
||||
|
||||
@Input()
|
||||
@ -194,8 +193,7 @@ export class TimewindowComponent implements OnInit, OnDestroy, ControlValueAcces
|
||||
private datePipe: DatePipe,
|
||||
private cd: ChangeDetectorRef,
|
||||
private nativeElement: ElementRef,
|
||||
public viewContainerRef: ViewContainerRef,
|
||||
public breakpointObserver: BreakpointObserver) {
|
||||
public viewContainerRef: ViewContainerRef) {
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
@ -300,6 +298,10 @@ export class TimewindowComponent implements OnInit, OnDestroy, ControlValueAcces
|
||||
this.propagateChange(cloneSelectedTimewindow(this.innerValue));
|
||||
}
|
||||
|
||||
displayValue(): string {
|
||||
return this.displayTimewindowValue ? this.innerValue?.displayValue : this.translate.instant('timewindow.timewindow');
|
||||
}
|
||||
|
||||
updateDisplayValue() {
|
||||
if (this.innerValue.selectedTab === TimewindowType.REALTIME && !this.historyOnly) {
|
||||
this.innerValue.displayValue = this.translate.instant('timewindow.realtime') + ' - ';
|
||||
@ -334,10 +336,6 @@ export class TimewindowComponent implements OnInit, OnDestroy, ControlValueAcces
|
||||
this.cd.detectChanges();
|
||||
}
|
||||
|
||||
hideLabel() {
|
||||
return this.isToolbar && !this.breakpointObserver.isMatched(MediaBreakpoints['gt-md']);
|
||||
}
|
||||
|
||||
private isTimewindowDisabled(): boolean {
|
||||
return this.disabled ||
|
||||
(!this.isEdit && (!this.innerValue || this.innerValue.hideInterval &&
|
||||
|
||||
@ -930,6 +930,7 @@
|
||||
"no-dashboards-text": "No dashboards found",
|
||||
"no-widgets": "No widgets configured",
|
||||
"add-widget": "Add new widget",
|
||||
"add-widget-button-text": "Add widget",
|
||||
"title": "Title",
|
||||
"image": "Dashboard image",
|
||||
"mobile-app-settings": "Mobile application settings",
|
||||
@ -1058,6 +1059,7 @@
|
||||
"public-link-copied-message": "Dashboard public link has been copied to clipboard",
|
||||
"manage-states": "Manage dashboard states",
|
||||
"states": "Dashboard states",
|
||||
"states-short": "States",
|
||||
"search-states": "Search dashboard states",
|
||||
"selected-states": "{ count, plural, =1 {1 dashboard state} other {# dashboard states} } selected",
|
||||
"edit-state": "Edit dashboard state",
|
||||
@ -1086,7 +1088,8 @@
|
||||
"unassign-dashboards-from-edge-text": "After the confirmation all selected dashboards will be unassigned and won't be accessible by the edge.",
|
||||
"assign-dashboard-to-edge": "Assign Dashboard(s) To Edge",
|
||||
"assign-dashboard-to-edge-text": "Please select the dashboards to assign to the edge",
|
||||
"non-existent-dashboard-state-error": "Dashboard state with id \"{{ stateId }}\" is not found"
|
||||
"non-existent-dashboard-state-error": "Dashboard state with id \"{{ stateId }}\" is not found",
|
||||
"edit-mode": "Edit mode"
|
||||
},
|
||||
"datakey": {
|
||||
"settings": "Settings",
|
||||
@ -1937,6 +1940,7 @@
|
||||
"entities-count": "Entities count",
|
||||
"alarms-count": "Alarms count",
|
||||
"aliases": "Entity aliases",
|
||||
"aliases-short": "Aliases",
|
||||
"entity-alias": "Entity alias",
|
||||
"unable-delete-entity-alias-title": "Unable to delete entity alias",
|
||||
"unable-delete-entity-alias-text": "Entity alias '{{entityAlias}}' can't be deleted as it used by the following widget(s):<br/>{{widgetsList}}",
|
||||
@ -2698,6 +2702,7 @@
|
||||
},
|
||||
"layout": {
|
||||
"layout": "Layout",
|
||||
"layouts": "Layouts",
|
||||
"manage": "Manage layouts",
|
||||
"settings": "Layout settings",
|
||||
"color": "Color",
|
||||
@ -3752,6 +3757,7 @@
|
||||
"days": "Days"
|
||||
},
|
||||
"timewindow": {
|
||||
"timewindow": "Timewindow",
|
||||
"years": "{ years, plural, =1 { year } other {# years } }",
|
||||
"months": "{ months, plural, =1 { month } other {# months } }",
|
||||
"weeks": "{ weeks, plural, =1 { week } other {# weeks } }",
|
||||
|
||||
@ -17,6 +17,7 @@
|
||||
|
||||
@mixin theme-overwrites($primary, $config-or-theme) {
|
||||
@include _mat-form-field-overwrites($primary, $config-or-theme);
|
||||
@include _mat-button-overwrites($primary, $config-or-theme);
|
||||
}
|
||||
|
||||
@mixin _mat-form-field-overwrites($primary, $config-or-theme) {
|
||||
@ -52,3 +53,14 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@mixin _mat-button-overwrites($primary, $config-or-theme) {
|
||||
.mat-toolbar {
|
||||
.mat-mdc-outlined-button {
|
||||
--mdc-outlined-button-outline-color: inherit;
|
||||
&:not(:disabled) {
|
||||
border-color: var(--mdc-outlined-button-outline-color, inherit);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user