Commit 9b8cf75c1a5ba5ba064ad70217e9221b1a127df1

Authored by Igor Kulikov
1 parent c1223b0c

UI: Refactor dashboard page. Add ability to open dashboard state in separate dialog.

Showing 57 changed files with 424 additions and 78 deletions
... ... @@ -53,6 +53,7 @@ import { EntityDataService } from '@core/api/entity-data.service';
53 53 import { PageData } from '@shared/models/page/page-data';
54 54 import { TranslateService } from '@ngx-translate/core';
55 55 import { AlarmDataService } from '@core/api/alarm-data.service';
  56 +import { IDashboardController } from '@home/components/dashboard-page/dashboard-page.models';
56 57
57 58 export interface TimewindowFunctions {
58 59 onUpdateTimewindow: (startTimeMs: number, endTimeMs: number, interval?: number) => void;
... ... @@ -137,6 +138,7 @@ export interface StateParams {
137 138 export type StateControllerHolder = () => IStateController;
138 139
139 140 export interface IStateController {
  141 + dashboardCtrl: IDashboardController;
140 142 getStateParams(): StateParams;
141 143 getStateParamsByStateId(stateId: string): StateParams;
142 144 openState(id: string, params?: StateParams, openRightLayout?: boolean): void;
... ...
... ... @@ -19,7 +19,6 @@ import { CommonModule } from '@angular/common';
19 19 import { SharedModule } from '@shared/shared.module';
20 20 import { HomeComponentsModule } from '@modules/home/components/home-components.module';
21 21 import { HomeDialogsModule } from '@app/modules/home/dialogs/home-dialogs.module';
22   -import { DashboardModule } from '@home/pages/dashboard/dashboard.module';
23 22 import { DashboardPagesRoutingModule } from './dashboard-pages.routing.module';
24 23
25 24 @NgModule({
... ... @@ -28,7 +27,6 @@ import { DashboardPagesRoutingModule } from './dashboard-pages.routing.module';
28 27 SharedModule,
29 28 HomeComponentsModule,
30 29 HomeDialogsModule,
31   - DashboardModule,
32 30 DashboardPagesRoutingModule
33 31 ]
34 32 })
... ...
... ... @@ -18,7 +18,7 @@ import { Injectable, NgModule } from '@angular/core';
18 18 import { ActivatedRouteSnapshot, Resolve, RouterModule, Routes } from '@angular/router';
19 19
20 20 import { Authority } from '@shared/models/authority.enum';
21   -import { DashboardPageComponent } from '@home/pages/dashboard/dashboard-page.component';
  21 +import { DashboardPageComponent } from '@home/components/dashboard-page/dashboard-page.component';
22 22 import { Dashboard } from '@app/shared/models/dashboard.models';
23 23 import { DashboardService } from '@core/http/dashboard.service';
24 24 import { DashboardUtilsService } from '@core/services/dashboard-utils.service';
... ...
ui-ngx/src/app/modules/home/components/dashboard-page/add-widget-dialog.component.html renamed from ui-ngx/src/app/modules/home/pages/dashboard/add-widget-dialog.component.html
ui-ngx/src/app/modules/home/components/dashboard-page/add-widget-dialog.component.ts renamed from ui-ngx/src/app/modules/home/pages/dashboard/add-widget-dialog.component.ts
ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-page.component.html renamed from ui-ngx/src/app/modules/home/pages/dashboard/dashboard-page.component.html
... ... @@ -21,7 +21,7 @@
21 21 <section class="tb-dashboard-toolbar"
22 22 [ngClass]="{ 'tb-dashboard-toolbar-opened': toolbarOpened,
23 23 'tb-dashboard-toolbar-closed': !toolbarOpened }">
24   - <tb-dashboard-toolbar [fxShow]="!widgetEditMode" [forceFullscreen]="forceFullscreen"
  24 + <tb-dashboard-toolbar [fxShow]="!widgetEditMode && !hideToolbar" [forceFullscreen]="forceFullscreen"
25 25 [toolbarOpened]="toolbarOpened" (triggerClick)="openToolbar()">
26 26 <div class="tb-dashboard-action-panels" fxLayout="column" fxLayout.gt-sm="row"
27 27 fxLayoutAlign="center stretch" fxLayoutAlign.gt-sm="space-between center">
... ... @@ -52,6 +52,7 @@
52 52 [dashboardId]="dashboard.id ? dashboard.id.id : ''"
53 53 [isMobile]="isMobile"
54 54 [state]="dashboardCtx.state"
  55 + [currentState]="currentState"
55 56 [states]="dashboardConfiguration.states">
56 57 </tb-states-component>
57 58 </div>
... ... @@ -183,11 +184,12 @@
183 184 </mat-drawer-content>
184 185 </mat-drawer-container>
185 186 <section fxLayout="row" class="layout-wrap tb-footer-buttons" fxLayoutAlign="start end">
186   - <tb-footer-fab-buttons [fxShow]="!isAddingWidget && isEdit && !widgetEditMode"
  187 + <tb-footer-fab-buttons *ngIf="!embedded"
  188 + [fxShow]="!isAddingWidget && isEdit && !widgetEditMode"
187 189 relative
188 190 [footerFabButtons]="addWidgetFabButtons">
189 191 </tb-footer-fab-buttons>
190   - <button *ngIf="(isTenantAdmin() || isSystemAdmin()) && !forceFullscreen"
  192 + <button *ngIf="(isTenantAdmin() || isSystemAdmin()) && !forceFullscreen && !embedded"
191 193 mat-fab color="accent" class="tb-btn-footer"
192 194 [ngClass]="{'tb-hide': !isEdit || isAddingWidget}"
193 195 [disabled]="isLoading$ | async"
... ...
ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-page.component.scss renamed from ui-ngx/src/app/modules/home/pages/dashboard/dashboard-page.component.scss
ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-page.component.ts renamed from ui-ngx/src/app/modules/home/pages/dashboard/dashboard-page.component.ts
... ... @@ -78,23 +78,23 @@ import {
78 78 EntityAliasesDialogData
79 79 } from '@home/components/alias/entity-aliases-dialog.component';
80 80 import { EntityAliases } from '@app/shared/models/alias.models';
81   -import { EditWidgetComponent } from '@home/pages/dashboard/edit-widget.component';
  81 +import { EditWidgetComponent } from '@home/components/dashboard-page/edit-widget.component';
82 82 import { WidgetsBundle } from '@shared/models/widgets-bundle.model';
83   -import { AddWidgetDialogComponent, AddWidgetDialogData } from '@home/pages/dashboard/add-widget-dialog.component';
  83 +import { AddWidgetDialogComponent, AddWidgetDialogData } from '@home/components/dashboard-page/add-widget-dialog.component';
84 84 import { TranslateService } from '@ngx-translate/core';
85 85 import {
86 86 ManageDashboardLayoutsDialogComponent,
87 87 ManageDashboardLayoutsDialogData
88   -} from '@home/pages/dashboard/layout/manage-dashboard-layouts-dialog.component';
  88 +} from '@home/components/dashboard-page/layout/manage-dashboard-layouts-dialog.component';
89 89 import { SelectTargetLayoutDialogComponent } from '@home/components/dashboard/select-target-layout-dialog.component';
90 90 import {
91 91 DashboardSettingsDialogComponent,
92 92 DashboardSettingsDialogData
93   -} from '@home/pages/dashboard/dashboard-settings-dialog.component';
  93 +} from '@home/components/dashboard-page/dashboard-settings-dialog.component';
94 94 import {
95 95 ManageDashboardStatesDialogComponent,
96 96 ManageDashboardStatesDialogData
97   -} from '@home/pages/dashboard/states/manage-dashboard-states-dialog.component';
  97 +} from '@home/components/dashboard-page/states/manage-dashboard-states-dialog.component';
98 98 import { ImportExportService } from '@home/components/import-export/import-export.service';
99 99 import { AuthState } from '@app/core/auth/auth.models';
100 100 import { FiltersDialogComponent, FiltersDialogData } from '@home/components/filter/filters-dialog.component';
... ... @@ -118,6 +118,12 @@ export class DashboardPageComponent extends PageComponent implements IDashboardC
118 118 embedded = false;
119 119
120 120 @Input()
  121 + currentState: string;
  122 +
  123 + @Input()
  124 + hideToolbar: boolean;
  125 +
  126 + @Input()
121 127 dashboard: Dashboard;
122 128 dashboardConfiguration: DashboardConfiguration;
123 129
... ... @@ -159,6 +165,7 @@ export class DashboardPageComponent extends PageComponent implements IDashboardC
159 165
160 166
161 167 dashboardCtx: DashboardContext = {
  168 + instanceId: this.utils.guid(),
162 169 getDashboard: () => this.dashboard,
163 170 dashboardTimewindow: null,
164 171 state: null,
... ... @@ -218,7 +225,7 @@ export class DashboardPageComponent extends PageComponent implements IDashboardC
218 225 private rxSubscriptions = new Array<Subscription>();
219 226
220 227 get toolbarOpened(): boolean {
221   - return !this.widgetEditMode &&
  228 + return !this.widgetEditMode && !this.hideToolbar &&
222 229 (this.toolbarAlwaysOpen() || this.isToolbarOpened || this.isEdit || this.showRightLayoutSwitch());
223 230 }
224 231 set toolbarOpened(toolbarOpened: boolean) {
... ...
ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-page.models.ts renamed from ui-ngx/src/app/modules/home/pages/dashboard/dashboard-page.models.ts
... ... @@ -24,6 +24,7 @@ import { DashboardContextMenuItem, WidgetContextMenuItem } from '@home/models/da
24 24 export declare type DashboardPageScope = 'tenant' | 'customer';
25 25
26 26 export interface DashboardContext {
  27 + instanceId: string;
27 28 state: string;
28 29 getDashboard: () => Dashboard;
29 30 dashboardTimewindow: Timewindow;
... ...
ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-settings-dialog.component.html renamed from ui-ngx/src/app/modules/home/pages/dashboard/dashboard-settings-dialog.component.html
ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-settings-dialog.component.scss renamed from ui-ngx/src/app/modules/home/pages/dashboard/dashboard-settings-dialog.component.scss
ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-settings-dialog.component.ts renamed from ui-ngx/src/app/modules/home/pages/dashboard/dashboard-settings-dialog.component.ts
ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-toolbar.component.html renamed from ui-ngx/src/app/modules/home/pages/dashboard/dashboard-toolbar.component.html
ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-toolbar.component.scss renamed from ui-ngx/src/app/modules/home/pages/dashboard/dashboard-toolbar.component.scss
ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-toolbar.component.ts renamed from ui-ngx/src/app/modules/home/pages/dashboard/dashboard-toolbar.component.ts
ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-widget-select.component.html renamed from ui-ngx/src/app/modules/home/pages/dashboard/dashboard-widget-select.component.html
ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-widget-select.component.scss renamed from ui-ngx/src/app/modules/home/pages/dashboard/dashboard-widget-select.component.scss
ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-widget-select.component.ts renamed from ui-ngx/src/app/modules/home/pages/dashboard/dashboard-widget-select.component.ts
ui-ngx/src/app/modules/home/components/dashboard-page/edit-widget.component.html renamed from ui-ngx/src/app/modules/home/pages/dashboard/edit-widget.component.html
ui-ngx/src/app/modules/home/components/dashboard-page/edit-widget.component.ts renamed from ui-ngx/src/app/modules/home/pages/dashboard/edit-widget.component.ts
ui-ngx/src/app/modules/home/components/dashboard-page/layout/dashboard-layout.component.html renamed from ui-ngx/src/app/modules/home/pages/dashboard/layout/dashboard-layout.component.html
ui-ngx/src/app/modules/home/components/dashboard-page/layout/dashboard-layout.component.scss renamed from ui-ngx/src/app/modules/home/pages/dashboard/layout/dashboard-layout.component.scss
ui-ngx/src/app/modules/home/components/dashboard-page/layout/dashboard-layout.component.ts renamed from ui-ngx/src/app/modules/home/pages/dashboard/layout/dashboard-layout.component.ts
... ... @@ -15,8 +15,8 @@
15 15 ///
16 16
17 17 import { Component, Input, OnDestroy, OnInit, ViewChild } from '@angular/core';
18   -import { ILayoutController } from '@home/pages/dashboard/layout/layout.models';
19   -import { DashboardContext, DashboardPageLayoutContext } from '@home/pages/dashboard/dashboard-page.models';
  18 +import { ILayoutController } from '@home/components/dashboard-page/layout/layout.models';
  19 +import { DashboardContext, DashboardPageLayoutContext } from '@home/components/dashboard-page/dashboard-page.models';
20 20 import { PageComponent } from '@shared/components/page.component';
21 21 import { Store } from '@ngrx/store';
22 22 import { AppState } from '@core/core.state';
... ...
ui-ngx/src/app/modules/home/components/dashboard-page/layout/layout.models.ts renamed from ui-ngx/src/app/modules/home/pages/dashboard/layout/layout.models.ts
ui-ngx/src/app/modules/home/components/dashboard-page/layout/manage-dashboard-layouts-dialog.component.html renamed from ui-ngx/src/app/modules/home/pages/dashboard/layout/manage-dashboard-layouts-dialog.component.html
ui-ngx/src/app/modules/home/components/dashboard-page/layout/manage-dashboard-layouts-dialog.component.ts renamed from ui-ngx/src/app/modules/home/pages/dashboard/layout/manage-dashboard-layouts-dialog.component.ts
... ... @@ -30,7 +30,7 @@ import { DashboardUtilsService } from '@core/services/dashboard-utils.service';
30 30 import {
31 31 DashboardSettingsDialogComponent,
32 32 DashboardSettingsDialogData
33   -} from '@home/pages/dashboard/dashboard-settings-dialog.component';
  33 +} from '@home/components/dashboard-page/dashboard-settings-dialog.component';
34 34
35 35 export interface ManageDashboardLayoutsDialogData {
36 36 layouts: DashboardStateLayouts;
... ...
ui-ngx/src/app/modules/home/components/dashboard-page/states/dashboard-state-dialog.component.html renamed from ui-ngx/src/app/modules/home/pages/dashboard/states/dashboard-state-dialog.component.html
ui-ngx/src/app/modules/home/components/dashboard-page/states/dashboard-state-dialog.component.ts renamed from ui-ngx/src/app/modules/home/pages/dashboard/states/dashboard-state-dialog.component.ts
... ... @@ -31,7 +31,7 @@ import {
31 31 import { Router } from '@angular/router';
32 32 import { DialogComponent } from '@app/shared/components/dialog.component';
33 33 import { DashboardState } from '@app/shared/models/dashboard.models';
34   -import { DashboardStateInfo } from '@home/pages/dashboard/states/manage-dashboard-states-dialog.component.models';
  34 +import { DashboardStateInfo } from '@home/components/dashboard-page/states/manage-dashboard-states-dialog.component.models';
35 35 import { TranslateService } from '@ngx-translate/core';
36 36 import { DashboardUtilsService } from '@core/services/dashboard-utils.service';
37 37
... ...
ui-ngx/src/app/modules/home/components/dashboard-page/states/default-state-controller.component.html renamed from ui-ngx/src/app/modules/home/pages/dashboard/states/default-state-controller.component.html
ui-ngx/src/app/modules/home/components/dashboard-page/states/default-state-controller.component.scss renamed from ui-ngx/src/app/modules/home/pages/dashboard/states/default-state-controller.component.scss
ui-ngx/src/app/modules/home/components/dashboard-page/states/default-state-controller.component.ts renamed from ui-ngx/src/app/modules/home/pages/dashboard/states/default-state-controller.component.ts
... ... @@ -20,7 +20,7 @@ import { ActivatedRoute, Router } from '@angular/router';
20 20 import { DashboardState } from '@shared/models/dashboard.models';
21 21 import { StateControllerState } from './state-controller.models';
22 22 import { StateControllerComponent } from './state-controller.component';
23   -import { StatesControllerService } from '@home/pages/dashboard/states/states-controller.service';
  23 +import { StatesControllerService } from '@home/components/dashboard-page/states/states-controller.service';
24 24 import { EntityId } from '@app/shared/models/id/entity-id';
25 25 import { UtilsService } from '@core/services/utils.service';
26 26 import { base64toObj, objToBase64URI } from '@app/core/utils';
... ...
ui-ngx/src/app/modules/home/components/dashboard-page/states/entity-state-controller.component.html renamed from ui-ngx/src/app/modules/home/pages/dashboard/states/entity-state-controller.component.html
ui-ngx/src/app/modules/home/components/dashboard-page/states/entity-state-controller.component.scss renamed from ui-ngx/src/app/modules/home/pages/dashboard/states/entity-state-controller.component.scss
ui-ngx/src/app/modules/home/components/dashboard-page/states/entity-state-controller.component.ts renamed from ui-ngx/src/app/modules/home/pages/dashboard/states/entity-state-controller.component.ts
... ... @@ -20,7 +20,7 @@ import { ActivatedRoute, Router } from '@angular/router';
20 20 import { forkJoin, Observable, of } from 'rxjs';
21 21 import { StateControllerState } from './state-controller.models';
22 22 import { StateControllerComponent } from './state-controller.component';
23   -import { StatesControllerService } from '@home/pages/dashboard/states/states-controller.service';
  23 +import { StatesControllerService } from '@home/components/dashboard-page/states/states-controller.service';
24 24 import { EntityId } from '@app/shared/models/id/entity-id';
25 25 import { UtilsService } from '@core/services/utils.service';
26 26 import { base64toObj, insertVariable, isEmpty, objToBase64URI } from '@app/core/utils';
... ...
ui-ngx/src/app/modules/home/components/dashboard-page/states/manage-dashboard-states-dialog.component.html renamed from ui-ngx/src/app/modules/home/pages/dashboard/states/manage-dashboard-states-dialog.component.html
ui-ngx/src/app/modules/home/components/dashboard-page/states/manage-dashboard-states-dialog.component.models.ts renamed from ui-ngx/src/app/modules/home/pages/dashboard/states/manage-dashboard-states-dialog.component.models.ts
ui-ngx/src/app/modules/home/components/dashboard-page/states/manage-dashboard-states-dialog.component.scss renamed from ui-ngx/src/app/modules/home/pages/dashboard/states/manage-dashboard-states-dialog.component.scss
ui-ngx/src/app/modules/home/components/dashboard-page/states/manage-dashboard-states-dialog.component.ts renamed from ui-ngx/src/app/modules/home/pages/dashboard/states/manage-dashboard-states-dialog.component.ts
... ... @@ -27,7 +27,7 @@ import { PageLink } from '@shared/models/page/page-link';
27 27 import {
28 28 DashboardStateInfo,
29 29 DashboardStatesDatasource
30   -} from '@home/pages/dashboard/states/manage-dashboard-states-dialog.component.models';
  30 +} from '@home/components/dashboard-page/states/manage-dashboard-states-dialog.component.models';
31 31 import { Direction, SortOrder } from '@shared/models/page/sort-order';
32 32 import { MatPaginator } from '@angular/material/paginator';
33 33 import { MatSort } from '@angular/material/sort';
... ... @@ -39,7 +39,7 @@ import { deepClone, isUndefined } from '@core/utils';
39 39 import {
40 40 DashboardStateDialogComponent,
41 41 DashboardStateDialogData
42   -} from '@home/pages/dashboard/states/dashboard-state-dialog.component';
  42 +} from '@home/components/dashboard-page/states/dashboard-state-dialog.component';
43 43
44 44 export interface ManageDashboardStatesDialogData {
45 45 states: {[id: string]: DashboardState };
... ...
ui-ngx/src/app/modules/home/components/dashboard-page/states/state-controller.component.ts renamed from ui-ngx/src/app/modules/home/pages/dashboard/states/state-controller.component.ts
... ... @@ -14,13 +14,13 @@
14 14 /// limitations under the License.
15 15 ///
16 16
17   -import { IStateControllerComponent, StateControllerState } from '@home/pages/dashboard/states/state-controller.models';
  17 +import { IStateControllerComponent, StateControllerState } from '@home/components/dashboard-page/states/state-controller.models';
18 18 import { IDashboardController } from '../dashboard-page.models';
19 19 import { DashboardState } from '@app/shared/models/dashboard.models';
20 20 import { Subscription } from 'rxjs';
21 21 import { NgZone, OnDestroy, OnInit, Directive } from '@angular/core';
22 22 import { ActivatedRoute, Params, Router } from '@angular/router';
23   -import { StatesControllerService } from '@home/pages/dashboard/states/states-controller.service';
  23 +import { StatesControllerService } from '@home/components/dashboard-page/states/states-controller.service';
24 24 import { EntityId } from '@app/shared/models/id/entity-id';
25 25 import { StateObject, StateParams } from '@app/core/api/widget-api.models';
26 26
... ... @@ -31,6 +31,8 @@ export abstract class StateControllerComponent implements IStateControllerCompon
31 31 dashboardCtrl: IDashboardController;
32 32 preservedState: any;
33 33
  34 + stateControllerInstanceId: string;
  35 +
34 36 isMobileValue: boolean;
35 37 set isMobile(val: boolean) {
36 38 if (this.isMobileValue !== val) {
... ... @@ -139,7 +141,7 @@ export abstract class StateControllerComponent implements IStateControllerCompon
139 141 }
140 142
141 143 public preserveState() {
142   - this.statesControllerService.preserveStateControllerState(this.stateControllerId(), this.stateObject);
  144 + this.statesControllerService.preserveStateControllerState(this.stateControllerInstanceId, this.stateObject);
143 145 }
144 146
145 147 public cleanupPreservedStates() {
... ...
ui-ngx/src/app/modules/home/components/dashboard-page/states/state-controller.models.ts renamed from ui-ngx/src/app/modules/home/pages/dashboard/states/state-controller.models.ts
... ... @@ -15,15 +15,16 @@
15 15 ///
16 16
17 17 import { IStateController, StateObject } from '@core/api/widget-api.models';
18   -import { IDashboardController } from '@home/pages/dashboard/dashboard-page.models';
  18 +import { IDashboardController } from '@home/components/dashboard-page/dashboard-page.models';
19 19 import { DashboardState } from '@shared/models/dashboard.models';
20 20
21 21 export declare type StateControllerState = StateObject[];
22 22
23 23 export interface IStateControllerComponent extends IStateController {
  24 + stateControllerInstanceId: string;
24 25 state: string;
  26 + currentState: string;
25 27 isMobile: boolean;
26   - dashboardCtrl: IDashboardController;
27 28 states: {[id: string]: DashboardState };
28 29 dashboardId: string;
29 30 preservedState: any;
... ...
ui-ngx/src/app/modules/home/components/dashboard-page/states/states-component.directive.ts renamed from ui-ngx/src/app/modules/home/pages/dashboard/states/states-component.directive.ts
... ... @@ -25,9 +25,9 @@ import {
25 25 ViewContainerRef
26 26 } from '@angular/core';
27 27 import { DashboardState } from '@shared/models/dashboard.models';
28   -import { IDashboardController } from '@home/pages/dashboard/dashboard-page.models';
29   -import { StatesControllerService } from '@home/pages/dashboard/states/states-controller.service';
30   -import { IStateControllerComponent } from '@home/pages/dashboard/states/state-controller.models';
  28 +import { IDashboardController } from '@home/components/dashboard-page/dashboard-page.models';
  29 +import { StatesControllerService } from '@home/components/dashboard-page/states/states-controller.service';
  30 +import { IStateControllerComponent } from '@home/components/dashboard-page/states/state-controller.models';
31 31
32 32 @Directive({
33 33 // tslint:disable-next-line:directive-selector
... ... @@ -51,6 +51,9 @@ export class StatesComponentDirective implements OnInit, OnDestroy, OnChanges {
51 51 state: string;
52 52
53 53 @Input()
  54 + currentState: string;
  55 +
  56 + @Input()
54 57 isMobile: boolean;
55 58
56 59 stateControllerComponentRef: ComponentRef<IStateControllerComponent>;
... ... @@ -84,6 +87,8 @@ export class StatesComponentDirective implements OnInit, OnDestroy, OnChanges {
84 87 this.stateControllerComponent.isMobile = this.isMobile;
85 88 } else if (propName === 'state') {
86 89 this.stateControllerComponent.state = this.state;
  90 + } else if (propName === 'currentState') {
  91 + this.stateControllerComponent.currentState = this.currentState;
87 92 }
88 93 }
89 94 }
... ... @@ -103,14 +108,17 @@ export class StatesComponentDirective implements OnInit, OnDestroy, OnChanges {
103 108 if (!stateControllerData) {
104 109 stateControllerData = this.statesControllerService.getStateController('default');
105 110 }
106   - const preservedState = this.statesControllerService.withdrawStateControllerState(this.statesControllerId);
  111 + const stateControllerInstanceId = this.dashboardCtrl.dashboardCtx.instanceId + '_' + this.statesControllerId;
  112 + const preservedState = this.statesControllerService.withdrawStateControllerState(stateControllerInstanceId);
107 113 const stateControllerFactory = stateControllerData.factory;
108 114 this.stateControllerComponentRef = this.viewContainerRef.createComponent(stateControllerFactory);
109 115 this.stateControllerComponent = this.stateControllerComponentRef.instance;
110 116 this.dashboardCtrl.dashboardCtx.stateController = this.stateControllerComponent;
111 117 this.stateControllerComponent.preservedState = preservedState;
112 118 this.stateControllerComponent.dashboardCtrl = this.dashboardCtrl;
  119 + this.stateControllerComponent.stateControllerInstanceId = stateControllerInstanceId;
113 120 this.stateControllerComponent.state = this.state;
  121 + this.stateControllerComponent.currentState = this.currentState;
114 122 this.stateControllerComponent.isMobile = this.isMobile;
115 123 this.stateControllerComponent.states = this.states;
116 124 this.stateControllerComponent.dashboardId = this.dashboardId;
... ...
ui-ngx/src/app/modules/home/components/dashboard-page/states/states-controller.module.ts renamed from ui-ngx/src/app/modules/home/pages/dashboard/states/states-controller.module.ts
... ... @@ -17,12 +17,11 @@
17 17 import { NgModule } from '@angular/core';
18 18 import { CommonModule } from '@angular/common';
19 19 import { SharedModule } from '@shared/shared.module';
20   -import { HomeComponentsModule } from '@modules/home/components/home-components.module';
21 20 import { StatesControllerService } from './states-controller.service';
22 21 import { EntityStateControllerComponent } from './entity-state-controller.component';
23 22 import { StatesComponentDirective } from './states-component.directive';
24 23 import { HomeDialogsModule } from '@app/modules/home/dialogs/home-dialogs.module';
25   -import { DefaultStateControllerComponent } from '@home/pages/dashboard/states/default-state-controller.component';
  24 +import { DefaultStateControllerComponent } from '@home/components/dashboard-page/states/default-state-controller.component';
26 25
27 26 @NgModule({
28 27 declarations: [
... ... @@ -33,7 +32,6 @@ import { DefaultStateControllerComponent } from '@home/pages/dashboard/states/de
33 32 imports: [
34 33 CommonModule,
35 34 SharedModule,
36   - HomeComponentsModule,
37 35 HomeDialogsModule
38 36 ],
39 37 exports: [
... ...
ui-ngx/src/app/modules/home/components/dashboard-page/states/states-controller.service.ts renamed from ui-ngx/src/app/modules/home/pages/dashboard/states/states-controller.service.ts
... ... @@ -16,11 +16,10 @@
16 16
17 17 import { ComponentFactory, ComponentFactoryResolver, Injectable, Type } from '@angular/core';
18 18 import { deepClone } from '@core/utils';
19   -import { IStateControllerComponent } from '@home/pages/dashboard/states/state-controller.models';
  19 +import { IStateControllerComponent } from '@home/components/dashboard-page/states/state-controller.models';
20 20
21 21 export interface StateControllerData {
22 22 factory: ComponentFactory<IStateControllerComponent>;
23   - state?: any;
24 23 }
25 24
26 25 @Injectable()
... ... @@ -28,6 +27,8 @@ export class StatesControllerService {
28 27
29 28 statesControllers: {[stateControllerId: string]: StateControllerData} = {};
30 29
  30 + statesControllerStates: {[stateControllerInstanceId: string]: any} = {};
  31 +
31 32 constructor(private componentFactoryResolver: ComponentFactoryResolver) {
32 33 }
33 34
... ... @@ -46,19 +47,17 @@ export class StatesControllerService {
46 47 return this.statesControllers[stateControllerId];
47 48 }
48 49
49   - public preserveStateControllerState(stateControllerId: string, state: any) {
50   - this.statesControllers[stateControllerId].state = deepClone(state);
  50 + public preserveStateControllerState(stateControllerInstanceId: string, state: any) {
  51 + this.statesControllerStates[stateControllerInstanceId] = deepClone(state);
51 52 }
52 53
53   - public withdrawStateControllerState(stateControllerId: string): any {
54   - const state = this.statesControllers[stateControllerId].state;
55   - this.statesControllers[stateControllerId].state = null;
  54 + public withdrawStateControllerState(stateControllerInstanceId: string): any {
  55 + const state = this.statesControllerStates[stateControllerInstanceId];
  56 + delete this.statesControllerStates[stateControllerInstanceId];
56 57 return state;
57 58 }
58 59
59 60 public cleanupPreservedStates() {
60   - for (const stateControllerId of Object.keys(this.statesControllers)) {
61   - this.statesControllers[stateControllerId].state = null;
62   - }
  61 + this.statesControllerStates = {};
63 62 }
64 63 }
... ...
... ... @@ -119,6 +119,19 @@ import { SmsProviderConfigurationComponent } from '@home/components/sms/sms-prov
119 119 import { AwsSnsProviderConfigurationComponent } from '@home/components/sms/aws-sns-provider-configuration.component';
120 120 import { TwilioSmsProviderConfigurationComponent } from '@home/components/sms/twilio-sms-provider-configuration.component';
121 121 import { CopyDeviceCredentialsComponent } from '@home/components/device/copy-device-credentials.component';
  122 +import { DashboardPageComponent } from '@home/components/dashboard-page/dashboard-page.component';
  123 +import { DashboardToolbarComponent } from '@home/components/dashboard-page/dashboard-toolbar.component';
  124 +import { StatesControllerModule } from '@home/components/dashboard-page/states/states-controller.module';
  125 +import { DashboardLayoutComponent } from '@home/components/dashboard-page/layout/dashboard-layout.component';
  126 +import { EditWidgetComponent } from '@home/components/dashboard-page/edit-widget.component';
  127 +import { DashboardWidgetSelectComponent } from '@home/components/dashboard-page/dashboard-widget-select.component';
  128 +import { AddWidgetDialogComponent } from '@home/components/dashboard-page/add-widget-dialog.component';
  129 +import { ManageDashboardLayoutsDialogComponent } from '@home/components/dashboard-page/layout/manage-dashboard-layouts-dialog.component';
  130 +import { DashboardSettingsDialogComponent } from '@home/components/dashboard-page/dashboard-settings-dialog.component';
  131 +import { ManageDashboardStatesDialogComponent } from '@home/components/dashboard-page/states/manage-dashboard-states-dialog.component';
  132 +import { DashboardStateDialogComponent } from '@home/components/dashboard-page/states/dashboard-state-dialog.component';
  133 +import { EmbedDashboardDialogComponent } from '@home/components/widget/dialog/embed-dashboard-dialog.component';
  134 +import { EMBED_DASHBOARD_DIALOG_TOKEN } from '@home/components/widget/dialog/embed-dashboard-dialog-token';
122 135
123 136 @NgModule({
124 137 declarations:
... ... @@ -220,12 +233,24 @@ import { CopyDeviceCredentialsComponent } from '@home/components/device/copy-dev
220 233 EditAlarmDetailsDialogComponent,
221 234 SmsProviderConfigurationComponent,
222 235 AwsSnsProviderConfigurationComponent,
223   - TwilioSmsProviderConfigurationComponent
  236 + TwilioSmsProviderConfigurationComponent,
  237 + DashboardToolbarComponent,
  238 + DashboardPageComponent,
  239 + DashboardLayoutComponent,
  240 + EditWidgetComponent,
  241 + DashboardWidgetSelectComponent,
  242 + AddWidgetDialogComponent,
  243 + ManageDashboardLayoutsDialogComponent,
  244 + DashboardSettingsDialogComponent,
  245 + ManageDashboardStatesDialogComponent,
  246 + DashboardStateDialogComponent,
  247 + EmbedDashboardDialogComponent
224 248 ],
225 249 imports: [
226 250 CommonModule,
227 251 SharedModule,
228   - SharedHomeComponentsModule
  252 + SharedHomeComponentsModule,
  253 + StatesControllerModule
229 254 ],
230 255 exports: [
231 256 EntitiesTableComponent,
... ... @@ -309,12 +334,24 @@ import { CopyDeviceCredentialsComponent } from '@home/components/device/copy-dev
309 334 DeviceProfileProvisionConfigurationComponent,
310 335 SmsProviderConfigurationComponent,
311 336 AwsSnsProviderConfigurationComponent,
312   - TwilioSmsProviderConfigurationComponent
  337 + TwilioSmsProviderConfigurationComponent,
  338 + DashboardToolbarComponent,
  339 + DashboardPageComponent,
  340 + DashboardLayoutComponent,
  341 + EditWidgetComponent,
  342 + DashboardWidgetSelectComponent,
  343 + AddWidgetDialogComponent,
  344 + ManageDashboardLayoutsDialogComponent,
  345 + DashboardSettingsDialogComponent,
  346 + ManageDashboardStatesDialogComponent,
  347 + DashboardStateDialogComponent,
  348 + EmbedDashboardDialogComponent
313 349 ],
314 350 providers: [
315 351 WidgetComponentService,
316 352 CustomDialogService,
317   - ImportExportService
  353 + ImportExportService,
  354 + {provide: EMBED_DASHBOARD_DIALOG_TOKEN, useValue: EmbedDashboardDialogComponent}
318 355 ]
319 356 })
320 357 export class HomeComponentsModule { }
... ...
... ... @@ -136,6 +136,41 @@
136 136 </mat-form-field>
137 137 </div>
138 138 </ng-template>
  139 + <ng-template [ngSwitchCase]="widgetActionFormGroup.get('type').value === widgetActionType.openDashboardState ?
  140 + widgetActionFormGroup.get('type').value : ''">
  141 + <mat-checkbox formControlName="openInSeparateDialog">
  142 + {{ 'widget-action.open-in-separate-dialog' | translate }}
  143 + </mat-checkbox>
  144 + <section fxLayout="column" *ngIf="actionTypeFormGroup.get('openInSeparateDialog').value">
  145 + <mat-form-field class="mat-block">
  146 + <mat-label translate>widget-action.dialog-title</mat-label>
  147 + <input matInput formControlName="dialogTitle">
  148 + </mat-form-field>
  149 + <mat-checkbox formControlName="dialogHideDashboardToolbar">
  150 + {{ 'widget-action.dialog-hide-dashboard-toolbar' | translate }}
  151 + </mat-checkbox>
  152 + <mat-form-field class="mat-block">
  153 + <mat-label translate>widget-action.dialog-width</mat-label>
  154 + <input type="number" min="1" max="100" step="1" matInput formControlName="dialogWidth">
  155 + <mat-error *ngIf="actionTypeFormGroup.get('dialogWidth').hasError('min')">
  156 + {{ 'widget-action.dialog-size-range-error' | translate }}
  157 + </mat-error>
  158 + <mat-error *ngIf="actionTypeFormGroup.get('dialogWidth').hasError('max')">
  159 + {{ 'widget-action.dialog-size-range-error' | translate }}
  160 + </mat-error>
  161 + </mat-form-field>
  162 + <mat-form-field class="mat-block">
  163 + <mat-label translate>widget-action.dialog-height</mat-label>
  164 + <input type="number" min="1" max="100" step="1" matInput formControlName="dialogHeight">
  165 + <mat-error *ngIf="actionTypeFormGroup.get('dialogHeight').hasError('min')">
  166 + {{ 'widget-action.dialog-size-range-error' | translate }}
  167 + </mat-error>
  168 + <mat-error *ngIf="actionTypeFormGroup.get('dialogHeight').hasError('max')">
  169 + {{ 'widget-action.dialog-size-range-error' | translate }}
  170 + </mat-error>
  171 + </mat-form-field>
  172 + </section>
  173 + </ng-template>
139 174 <ng-template [ngSwitchCase]="widgetActionType.custom">
140 175 <tb-js-func
141 176 formControlName="customFunction"
... ...
... ... @@ -44,6 +44,7 @@ import { DashboardService } from '@core/http/dashboard.service';
44 44 import { Dashboard } from '@shared/models/dashboard.models';
45 45 import { DashboardUtilsService } from '@core/services/dashboard-utils.service';
46 46 import { CustomActionEditorCompleter } from '@home/components/widget/action/custom-action.models';
  47 +import { isDefinedAndNotNull } from '@core/utils';
47 48
48 49 export interface WidgetActionDialogData {
49 50 isAdd: boolean;
... ... @@ -155,6 +156,28 @@ export class WidgetActionDialogComponent extends DialogComponent<WidgetActionDia
155 156 );
156 157 this.setupSelectedDashboardStateIds(action ? action.targetDashboardId : null);
157 158 } else {
  159 + if (type === WidgetActionType.openDashboardState) {
  160 + this.actionTypeFormGroup.addControl(
  161 + 'openInSeparateDialog',
  162 + this.fb.control(action ? action.openInSeparateDialog : false, [])
  163 + );
  164 + this.actionTypeFormGroup.addControl(
  165 + 'dialogTitle',
  166 + this.fb.control(action ? action.dialogTitle : '', [])
  167 + );
  168 + this.actionTypeFormGroup.addControl(
  169 + 'dialogHideDashboardToolbar',
  170 + this.fb.control(action && isDefinedAndNotNull(action.dialogHideDashboardToolbar) ? action.dialogHideDashboardToolbar : true, [])
  171 + );
  172 + this.actionTypeFormGroup.addControl(
  173 + 'dialogWidth',
  174 + this.fb.control(action ? action.dialogWidth : null, [Validators.min(1), Validators.max(100)])
  175 + );
  176 + this.actionTypeFormGroup.addControl(
  177 + 'dialogHeight',
  178 + this.fb.control(action ? action.dialogHeight : null, [Validators.min(1), Validators.max(100)])
  179 + );
  180 + }
158 181 this.actionTypeFormGroup.addControl(
159 182 'openRightLayout',
160 183 this.fb.control(action ? action.openRightLayout : false, [])
... ...
  1 +///
  2 +/// Copyright © 2016-2021 The Thingsboard Authors
  3 +///
  4 +/// Licensed under the Apache License, Version 2.0 (the "License");
  5 +/// you may not use this file except in compliance with the License.
  6 +/// You may obtain a copy of the License at
  7 +///
  8 +/// http://www.apache.org/licenses/LICENSE-2.0
  9 +///
  10 +/// Unless required by applicable law or agreed to in writing, software
  11 +/// distributed under the License is distributed on an "AS IS" BASIS,
  12 +/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 +/// See the License for the specific language governing permissions and
  14 +/// limitations under the License.
  15 +///
  16 +
  17 +import { InjectionToken } from '@angular/core';
  18 +import { ComponentType } from '@angular/cdk/portal';
  19 +
  20 +export const EMBED_DASHBOARD_DIALOG_TOKEN: InjectionToken<ComponentType<any>> =
  21 + new InjectionToken<ComponentType<any>>('EMBED_DASHBOARD_DIALOG_TOKEN');
  22 +
... ...
  1 +<!--
  2 +
  3 + Copyright © 2016-2021 The Thingsboard Authors
  4 +
  5 + Licensed under the Apache License, Version 2.0 (the "License");
  6 + you may not use this file except in compliance with the License.
  7 + You may obtain a copy of the License at
  8 +
  9 + http://www.apache.org/licenses/LICENSE-2.0
  10 +
  11 + Unless required by applicable law or agreed to in writing, software
  12 + distributed under the License is distributed on an "AS IS" BASIS,
  13 + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14 + See the License for the specific language governing permissions and
  15 + limitations under the License.
  16 +
  17 +-->
  18 +<div class="dashboard-state-dialog" [ngStyle]="dialogStyle" fxLayout="column">
  19 + <mat-toolbar color="primary">
  20 + <h2>{{title}}</h2>
  21 + <span fxFlex></span>
  22 + <button mat-icon-button (click)="close()" type="button">
  23 + <mat-icon class="material-icons">close</mat-icon>
  24 + </button>
  25 + </mat-toolbar>
  26 + <mat-progress-bar color="warn" mode="indeterminate" *ngIf="isLoading$ | async">
  27 + </mat-progress-bar>
  28 + <div style="height: 4px;" *ngIf="!(isLoading$ | async)"></div>
  29 + <div class="dashboard-state-dialog-content" mat-dialog-content fxFlex fxLayout="column" style="padding: 8px;">
  30 + <tb-dashboard-page [embedded]="true" [hideToolbar]="hideToolbar" [currentState]="state" [dashboard]="dashboard" style="width: 100%; height: 100%;"></tb-dashboard-page>
  31 + </div>
  32 + <div mat-dialog-actions fxLayoutAlign="end center">
  33 + <button mat-button color="primary"
  34 + type="button"
  35 + [disabled]="(isLoading$ | async)"
  36 + (click)="close()" cdkFocusInitial>
  37 + Close
  38 + </button>
  39 + </div>
  40 +</div>
... ...
  1 +/**
  2 + * Copyright © 2016-2021 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +:host {
  17 + .dashboard-state-dialog {
  18 + .mat-dialog-content.dashboard-state-dialog-content {
  19 + max-height: 100%;
  20 + }
  21 +
  22 + @media screen and (max-width: 599px) {
  23 + width: 100% !important;
  24 + height: 100% !important;
  25 + }
  26 +
  27 + @media screen and (min-width: 600px) {
  28 + width: 480px;
  29 + height: 600px;
  30 + }
  31 +
  32 + @media screen and (min-width: 960px) {
  33 + width: 768px;
  34 + height: 600px;
  35 + }
  36 +
  37 + @media screen and (min-width: 1280px) {
  38 + width: 1000px;
  39 + height: 800px;
  40 + }
  41 + }
  42 +}
... ...
  1 +///
  2 +/// Copyright © 2016-2021 The Thingsboard Authors
  3 +///
  4 +/// Licensed under the Apache License, Version 2.0 (the "License");
  5 +/// you may not use this file except in compliance with the License.
  6 +/// You may obtain a copy of the License at
  7 +///
  8 +/// http://www.apache.org/licenses/LICENSE-2.0
  9 +///
  10 +/// Unless required by applicable law or agreed to in writing, software
  11 +/// distributed under the License is distributed on an "AS IS" BASIS,
  12 +/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 +/// See the License for the specific language governing permissions and
  14 +/// limitations under the License.
  15 +///
  16 +
  17 +import {
  18 + Component,
  19 + ComponentFactoryResolver,
  20 + Inject,
  21 + Injector,
  22 + OnInit,
  23 + ViewChild,
  24 + ViewContainerRef
  25 +} from '@angular/core';
  26 +import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
  27 +import { Store } from '@ngrx/store';
  28 +import { AppState } from '@core/core.state';
  29 +import { Router } from '@angular/router';
  30 +import { DialogComponent } from '@shared/components/dialog.component';
  31 +import { Dashboard } from '@shared/models/dashboard.models';
  32 +
  33 +export interface EmbedDashboardDialogData {
  34 + dashboard: Dashboard;
  35 + state: string;
  36 + title: string;
  37 + hideToolbar: boolean;
  38 + width?: number;
  39 + height?: number;
  40 +}
  41 +
  42 +@Component({
  43 + selector: 'tb-embed-dashboard-dialog',
  44 + templateUrl: './embed-dashboard-dialog.component.html',
  45 + styleUrls: ['./embed-dashboard-dialog.component.scss']
  46 +})
  47 +export class EmbedDashboardDialogComponent extends DialogComponent<EmbedDashboardDialogComponent>
  48 + implements OnInit {
  49 +
  50 + @ViewChild('dashboardContent', {read: ViewContainerRef, static: true}) dashboardContentContainer: ViewContainerRef;
  51 +
  52 + dashboard = this.data.dashboard;
  53 + state = this.data.state;
  54 + title = this.data.title;
  55 + hideToolbar = this.data.hideToolbar;
  56 +
  57 + dialogStyle: any = {};
  58 +
  59 + constructor(protected store: Store<AppState>,
  60 + protected router: Router,
  61 + @Inject(MAT_DIALOG_DATA) public data: EmbedDashboardDialogData,
  62 + public dialogRef: MatDialogRef<EmbedDashboardDialogComponent>) {
  63 + super(store, router, dialogRef);
  64 + if (this.data.width) {
  65 + this.dialogStyle.width = this.data.width + 'vw';
  66 + }
  67 + if (this.data.height) {
  68 + this.dialogStyle.height = this.data.height + 'vh';
  69 + }
  70 + }
  71 +
  72 + ngOnInit(): void {
  73 + }
  74 +
  75 + close(): void {
  76 + this.dialogRef.close(null);
  77 + }
  78 +
  79 +}
... ...
... ... @@ -22,6 +22,7 @@ import {
22 22 ComponentFactoryResolver,
23 23 ComponentRef,
24 24 ElementRef,
  25 + Inject,
25 26 Injector,
26 27 Input,
27 28 NgZone,
... ... @@ -54,7 +55,7 @@ import { AppState } from '@core/core.state';
54 55 import { WidgetService } from '@core/http/widget.service';
55 56 import { UtilsService } from '@core/services/utils.service';
56 57 import { forkJoin, Observable, of, ReplaySubject, Subscription, throwError } from 'rxjs';
57   -import { deepClone, isDefined, objToBase64URI } from '@core/utils';
  58 +import { deepClone, insertVariable, isDefined, objToBase64, objToBase64URI } from '@core/utils';
58 59 import {
59 60 IDynamicWidgetComponent,
60 61 WidgetContext,
... ... @@ -93,6 +94,10 @@ import { EntityDataService } from '@core/api/entity-data.service';
93 94 import { TranslateService } from '@ngx-translate/core';
94 95 import { NotificationType } from '@core/notification/notification.models';
95 96 import { AlarmDataService } from '@core/api/alarm-data.service';
  97 +import { MatDialog } from '@angular/material/dialog';
  98 +import { ComponentType } from '@angular/cdk/portal';
  99 +import { EMBED_DASHBOARD_DIALOG_TOKEN } from '@home/components/widget/dialog/embed-dashboard-dialog-token';
  100 +import { Dashboard } from '@shared/models/dashboard.models';
96 101
97 102 @Component({
98 103 selector: 'tb-widget',
... ... @@ -161,6 +166,8 @@ export class WidgetComponent extends PageComponent implements OnInit, AfterViewI
161 166 private componentFactoryResolver: ComponentFactoryResolver,
162 167 private elementRef: ElementRef,
163 168 private injector: Injector,
  169 + private dialog: MatDialog,
  170 + @Inject(EMBED_DASHBOARD_DIALOG_TOKEN) private embedDashboardDialogComponent: ComponentType<any>,
164 171 private widgetService: WidgetService,
165 172 private resources: ResourcesService,
166 173 private timeService: TimeService,
... ... @@ -1007,7 +1014,11 @@ export class WidgetComponent extends PageComponent implements OnInit, AfterViewI
1007 1014 const params = deepClone(this.widgetContext.stateController.getStateParams());
1008 1015 this.updateEntityParams(params, targetEntityParamName, targetEntityId, entityName, entityLabel);
1009 1016 if (type === WidgetActionType.openDashboardState) {
1010   - this.widgetContext.stateController.openState(targetDashboardStateId, params, descriptor.openRightLayout);
  1017 + if (descriptor.openInSeparateDialog) {
  1018 + this.openDashboardStateInDialog(descriptor, entityId, entityName, additionalParams, entityLabel);
  1019 + } else {
  1020 + this.widgetContext.stateController.openState(targetDashboardStateId, params, descriptor.openRightLayout);
  1021 + }
1011 1022 } else {
1012 1023 this.widgetContext.stateController.updateState(targetDashboardStateId, params, descriptor.openRightLayout);
1013 1024 }
... ... @@ -1083,6 +1094,61 @@ export class WidgetComponent extends PageComponent implements OnInit, AfterViewI
1083 1094 }
1084 1095 }
1085 1096
  1097 + private openDashboardStateInDialog(descriptor: WidgetActionDescriptor,
  1098 + entityId?: EntityId, entityName?: string, additionalParams?: any, entityLabel?: string) {
  1099 + const dashboard = deepClone(this.widgetContext.stateController.dashboardCtrl.dashboardCtx.getDashboard());
  1100 + const stateObject: StateObject = {};
  1101 + stateObject.params = {};
  1102 + const targetEntityParamName = descriptor.stateEntityParamName;
  1103 + const targetDashboardStateId = descriptor.targetDashboardStateId;
  1104 + let targetEntityId: EntityId;
  1105 + if (descriptor.setEntityId) {
  1106 + targetEntityId = entityId;
  1107 + }
  1108 + this.updateEntityParams(stateObject.params, targetEntityParamName, targetEntityId, entityName, entityLabel);
  1109 + if (targetDashboardStateId) {
  1110 + stateObject.id = targetDashboardStateId;
  1111 + }
  1112 + let title = descriptor.dialogTitle;
  1113 + if (!title) {
  1114 + if (targetDashboardStateId && dashboard.configuration.states) {
  1115 + const dashboardState = dashboard.configuration.states[targetDashboardStateId];
  1116 + if (dashboardState) {
  1117 + title = dashboardState.name;
  1118 + }
  1119 + }
  1120 + }
  1121 + if (!title) {
  1122 + title = dashboard.title;
  1123 + }
  1124 + title = this.utils.customTranslation(title, title);
  1125 + const params = stateObject.params;
  1126 + const paramsEntityName = params && params.entityName ? params.entityName : '';
  1127 + const paramsEntityLabel = params && params.entityLabel ? params.entityLabel : '';
  1128 + title = insertVariable(title, 'entityName', paramsEntityName);
  1129 + title = insertVariable(title, 'entityLabel', paramsEntityLabel);
  1130 + for (const prop of Object.keys(params)) {
  1131 + if (params[prop] && params[prop].entityName) {
  1132 + title = insertVariable(title, prop + ':entityName', params[prop].entityName);
  1133 + }
  1134 + if (params[prop] && params[prop].entityLabel) {
  1135 + title = insertVariable(title, prop + ':entityLabel', params[prop].entityLabel);
  1136 + }
  1137 + }
  1138 + this.dialog.open(this.embedDashboardDialogComponent, {
  1139 + disableClose: true,
  1140 + panelClass: ['tb-dialog', 'tb-fullscreen-dialog'],
  1141 + data: {
  1142 + dashboard,
  1143 + state: objToBase64([ stateObject ]),
  1144 + title,
  1145 + hideToolbar: descriptor.dialogHideDashboardToolbar,
  1146 + width: descriptor.dialogWidth,
  1147 + height: descriptor.dialogHeight
  1148 + }
  1149 + });
  1150 + }
  1151 +
1086 1152 private elementClick($event: Event) {
1087 1153 const e = ($event.target || $event.srcElement) as Element;
1088 1154 if (e.id) {
... ...
... ... @@ -19,7 +19,6 @@ import { CommonModule } from '@angular/common';
19 19 import { SharedModule } from '@app/shared/shared.module';
20 20 import { HomeComponentsModule } from '@modules/home/components/home-components.module';
21 21 import { ApiUsageComponent } from '@home/pages/api-usage/api-usage.component';
22   -import { DashboardModule } from '@home/pages/dashboard/dashboard.module';
23 22 import { ApiUsageRoutingModule } from '@home/pages/api-usage/api-usage-routing.module';
24 23
25 24 @NgModule({
... ... @@ -31,7 +30,6 @@ import { ApiUsageRoutingModule } from '@home/pages/api-usage/api-usage-routing.m
31 30 CommonModule,
32 31 SharedModule,
33 32 HomeComponentsModule,
34   - DashboardModule,
35 33 ApiUsageRoutingModule
36 34 ]
37 35 })
... ...
... ... @@ -24,7 +24,7 @@ import { CustomersTableConfigResolver } from './customers-table-config.resolver'
24 24 import { DevicesTableConfigResolver } from '@modules/home/pages/device/devices-table-config.resolver';
25 25 import { AssetsTableConfigResolver } from '../asset/assets-table-config.resolver';
26 26 import { DashboardsTableConfigResolver } from '@modules/home/pages/dashboard/dashboards-table-config.resolver';
27   -import { DashboardPageComponent } from '@home/pages/dashboard/dashboard-page.component';
  27 +import { DashboardPageComponent } from '@home/components/dashboard-page/dashboard-page.component';
28 28 import { BreadCrumbConfig } from '@shared/components/breadcrumb';
29 29 import { dashboardBreadcumbLabelFunction, DashboardResolver } from '@home/pages/dashboard/dashboard-routing.module';
30 30
... ...
... ... @@ -20,7 +20,7 @@ import { ActivatedRouteSnapshot, Resolve, RouterModule, Routes } from '@angular/
20 20 import { EntitiesTableComponent } from '../../components/entity/entities-table.component';
21 21 import { Authority } from '@shared/models/authority.enum';
22 22 import { DashboardsTableConfigResolver } from './dashboards-table-config.resolver';
23   -import { DashboardPageComponent } from '@home/pages/dashboard/dashboard-page.component';
  23 +import { DashboardPageComponent } from '@home/components/dashboard-page/dashboard-page.component';
24 24 import { BreadCrumbConfig, BreadCrumbLabelFunction } from '@shared/components/breadcrumb';
25 25 import { Observable } from 'rxjs';
26 26 import { Dashboard } from '@app/shared/models/dashboard.models';
... ...
... ... @@ -24,44 +24,19 @@ import { DashboardRoutingModule } from './dashboard-routing.module';
24 24 import { MakeDashboardPublicDialogComponent } from '@modules/home/pages/dashboard/make-dashboard-public-dialog.component';
25 25 import { HomeComponentsModule } from '@modules/home/components/home-components.module';
26 26 import { DashboardTabsComponent } from '@home/pages/dashboard/dashboard-tabs.component';
27   -import { DashboardPageComponent } from '@home/pages/dashboard/dashboard-page.component';
28   -import { DashboardToolbarComponent } from './dashboard-toolbar.component';
29   -import { StatesControllerModule } from '@home/pages/dashboard/states/states-controller.module';
30   -import { DashboardLayoutComponent } from './layout/dashboard-layout.component';
31   -import { EditWidgetComponent } from './edit-widget.component';
32   -import { DashboardWidgetSelectComponent } from './dashboard-widget-select.component';
33   -import { AddWidgetDialogComponent } from './add-widget-dialog.component';
34   -import { ManageDashboardLayoutsDialogComponent } from './layout/manage-dashboard-layouts-dialog.component';
35   -import { DashboardSettingsDialogComponent } from './dashboard-settings-dialog.component';
36   -import { ManageDashboardStatesDialogComponent } from './states/manage-dashboard-states-dialog.component';
37   -import { DashboardStateDialogComponent } from './states/dashboard-state-dialog.component';
38 27
39 28 @NgModule({
40 29 declarations: [
41 30 DashboardFormComponent,
42 31 DashboardTabsComponent,
43 32 ManageDashboardCustomersDialogComponent,
44   - MakeDashboardPublicDialogComponent,
45   - DashboardToolbarComponent,
46   - DashboardPageComponent,
47   - DashboardLayoutComponent,
48   - EditWidgetComponent,
49   - DashboardWidgetSelectComponent,
50   - AddWidgetDialogComponent,
51   - ManageDashboardLayoutsDialogComponent,
52   - DashboardSettingsDialogComponent,
53   - ManageDashboardStatesDialogComponent,
54   - DashboardStateDialogComponent
55   - ],
56   - exports: [
57   - DashboardPageComponent
  33 + MakeDashboardPublicDialogComponent
58 34 ],
59 35 imports: [
60 36 CommonModule,
61 37 SharedModule,
62 38 HomeComponentsModule,
63 39 HomeDialogsModule,
64   - StatesControllerModule,
65 40 DashboardRoutingModule
66 41 ]
67 42 })
... ...
... ... @@ -345,6 +345,11 @@ export interface WidgetActionDescriptor extends CustomActionDescriptor {
345 345 targetDashboardStateId?: string;
346 346 openRightLayout?: boolean;
347 347 openNewBrowserTab?: boolean;
  348 + openInSeparateDialog?: boolean;
  349 + dialogTitle?: string;
  350 + dialogHideDashboardToolbar?: boolean;
  351 + dialogWidth?: number;
  352 + dialogHeight?: number;
348 353 setEntityId?: boolean;
349 354 stateEntityParamName?: string;
350 355 }
... ...
... ... @@ -2258,6 +2258,12 @@
2258 2258 "set-entity-from-widget": "Set entity from widget",
2259 2259 "target-dashboard": "Target dashboard",
2260 2260 "open-right-layout": "Open right dashboard layout (mobile view)",
  2261 + "open-in-separate-dialog": "Open in separate dialog",
  2262 + "dialog-title": "Dialog title",
  2263 + "dialog-hide-dashboard-toolbar": "Hide dashboard toolbar in dialog",
  2264 + "dialog-width": "Dialog width in percents relative to viewport width",
  2265 + "dialog-height": "Dialog height in percents relative to viewport height",
  2266 + "dialog-size-range-error": "Dialog size percent value should be in a range from 1 to 100.",
2261 2267 "open-new-browser-tab": "Open in a new browser tab"
2262 2268 },
2263 2269 "widgets-bundle": {
... ...