Commit 9b8cf75c1a5ba5ba064ad70217e9221b1a127df1
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 | + | ... | ... |
ui-ngx/src/app/modules/home/components/widget/dialog/embed-dashboard-dialog.component.html
0 → 100644
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> | ... | ... |
ui-ngx/src/app/modules/home/components/widget/dialog/embed-dashboard-dialog.component.scss
0 → 100644
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": { | ... | ... |