Merge pull request #8547 from thingsboard/feature/dashboard-edit-panel

Improve dashboard edit panel
This commit is contained in:
Igor Kulikov 2023-05-15 17:41:35 +03:00 committed by GitHub
commit 07ff1ab44a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 301 additions and 141 deletions

View File

@ -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>

View File

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

View File

@ -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 = '';
}
}
}

View File

@ -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"
fxLayoutAlign.gt-sm="start center"
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-icon-button
matTooltip="{{'layout.manage' | translate}}"
matTooltipPosition="below"
(click)="manageDashboardLayouts($event)">
<mat-icon>view_compact</mat-icon>
</button>
</div>
<ng-container *ngIf="isEdit">
<div fxFlex.lt-md fxLayout="row"
fxLayoutAlign.gt-sm="start center"
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 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
#versionControlButton
matTooltip="{{'version-control.version-control' | translate}}"
<button [fxShow]="currentDashboardId && !isMobileApp && displayExport() && !isEdit" mat-icon-button
matTooltip="{{'dashboard.export' | translate}}"
matTooltipPosition="below"
(click)="toggleVersionControl($event, versionControlButton)">
<mat-icon>history</mat-icon>
(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"
direction="left"
tooltipPosition="below"
aggregation="true"
timezone="true"
[(ngModel)]="dashboardCtx.dashboardTimewindow">
</tb-timewindow>
<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)"

View File

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

View File

@ -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(() => {

View File

@ -16,6 +16,9 @@
@import "../../../../../scss/constants";
:host {
&.tb-hide {
display: none;
}
section.tb-filters-edit {
min-height: 32px;
padding: 0 6px;

View File

@ -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 = '';
}
}
}

View File

@ -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">

View File

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

View File

@ -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 &&

View File

@ -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 } }",

View File

@ -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);
}
}
}
}