Showing
15 changed files
with
348 additions
and
10 deletions
@@ -3,7 +3,7 @@ | @@ -3,7 +3,7 @@ | ||
3 | "version": "3.0.0", | 3 | "version": "3.0.0", |
4 | "scripts": { | 4 | "scripts": { |
5 | "ng": "ng", | 5 | "ng": "ng", |
6 | - "start": "ng serve --open", | 6 | + "start": "ng serve --host 0.0.0.0 --open", |
7 | "build": "ng build", | 7 | "build": "ng build", |
8 | "build:prod": "ng build --prod --vendor-chunk", | 8 | "build:prod": "ng build --prod --vendor-chunk", |
9 | "test": "ng test", | 9 | "test": "ng test", |
@@ -36,6 +36,9 @@ import { DatasourceService } from '@core/api/datasource.service'; | @@ -36,6 +36,9 @@ import { DatasourceService } from '@core/api/datasource.service'; | ||
36 | import { RafService } from '@core/services/raf.service'; | 36 | import { RafService } from '@core/services/raf.service'; |
37 | import { EntityAliases } from '@shared/models/alias.models'; | 37 | import { EntityAliases } from '@shared/models/alias.models'; |
38 | import { EntityInfo } from '@app/shared/models/entity.models'; | 38 | import { EntityInfo } from '@app/shared/models/entity.models'; |
39 | +import { Type } from '@angular/core'; | ||
40 | +import { AssetService } from '@core/http/asset.service'; | ||
41 | +import { DialogService } from '@core/services/dialog.service'; | ||
39 | 42 | ||
40 | export interface TimewindowFunctions { | 43 | export interface TimewindowFunctions { |
41 | onUpdateTimewindow: (startTimeMs: number, endTimeMs: number, interval?: number) => void; | 44 | onUpdateTimewindow: (startTimeMs: number, endTimeMs: number, interval?: number) => void; |
@@ -30,6 +30,7 @@ import { | @@ -30,6 +30,7 @@ import { | ||
30 | MaterialIconsDialogComponent, | 30 | MaterialIconsDialogComponent, |
31 | MaterialIconsDialogData | 31 | MaterialIconsDialogData |
32 | } from '@shared/components/dialog/material-icons-dialog.component'; | 32 | } from '@shared/components/dialog/material-icons-dialog.component'; |
33 | +import { DynamicComponentFactoryService } from '@core/services/dynamic-component-factory.service'; | ||
33 | 34 | ||
34 | @Injectable( | 35 | @Injectable( |
35 | { | 36 | { |
@@ -41,6 +42,7 @@ export class DialogService { | @@ -41,6 +42,7 @@ export class DialogService { | ||
41 | constructor( | 42 | constructor( |
42 | private translate: TranslateService, | 43 | private translate: TranslateService, |
43 | private authService: AuthService, | 44 | private authService: AuthService, |
45 | + private dynamicComponentFactoryService: DynamicComponentFactoryService, | ||
44 | public dialog: MatDialog | 46 | public dialog: MatDialog |
45 | ) { | 47 | ) { |
46 | } | 48 | } |
@@ -31,7 +31,6 @@ import { CommonModule } from '@angular/common'; | @@ -31,7 +31,6 @@ import { CommonModule } from '@angular/common'; | ||
31 | export abstract class DynamicComponentModule implements OnDestroy { | 31 | export abstract class DynamicComponentModule implements OnDestroy { |
32 | 32 | ||
33 | ngOnDestroy(): void { | 33 | ngOnDestroy(): void { |
34 | - console.log('Module destroyed!'); | ||
35 | } | 34 | } |
36 | 35 | ||
37 | } | 36 | } |
@@ -56,6 +56,8 @@ import { ManageWidgetActionsComponent } from './widget/action/manage-widget-acti | @@ -56,6 +56,8 @@ import { ManageWidgetActionsComponent } from './widget/action/manage-widget-acti | ||
56 | import { WidgetActionDialogComponent } from './widget/action/widget-action-dialog.component'; | 56 | import { WidgetActionDialogComponent } from './widget/action/widget-action-dialog.component'; |
57 | import { CustomActionPrettyResourcesTabsComponent } from './widget/action/custom-action-pretty-resources-tabs.component'; | 57 | import { CustomActionPrettyResourcesTabsComponent } from './widget/action/custom-action-pretty-resources-tabs.component'; |
58 | import { CustomActionPrettyEditorComponent } from './widget/action/custom-action-pretty-editor.component'; | 58 | import { CustomActionPrettyEditorComponent } from './widget/action/custom-action-pretty-editor.component'; |
59 | +import { CustomDialogService } from './widget/dialog/custom-dialog.service'; | ||
60 | +import { CustomDialogContainerComponent } from './widget/dialog/custom-dialog-container.component'; | ||
59 | 61 | ||
60 | @NgModule({ | 62 | @NgModule({ |
61 | entryComponents: [ | 63 | entryComponents: [ |
@@ -72,7 +74,8 @@ import { CustomActionPrettyEditorComponent } from './widget/action/custom-action | @@ -72,7 +74,8 @@ import { CustomActionPrettyEditorComponent } from './widget/action/custom-action | ||
72 | EntityAliasDialogComponent, | 74 | EntityAliasDialogComponent, |
73 | DataKeyConfigDialogComponent, | 75 | DataKeyConfigDialogComponent, |
74 | LegendConfigPanelComponent, | 76 | LegendConfigPanelComponent, |
75 | - WidgetActionDialogComponent | 77 | + WidgetActionDialogComponent, |
78 | + CustomDialogContainerComponent | ||
76 | ], | 79 | ], |
77 | declarations: | 80 | declarations: |
78 | [ | 81 | [ |
@@ -113,7 +116,8 @@ import { CustomActionPrettyEditorComponent } from './widget/action/custom-action | @@ -113,7 +116,8 @@ import { CustomActionPrettyEditorComponent } from './widget/action/custom-action | ||
113 | ManageWidgetActionsComponent, | 116 | ManageWidgetActionsComponent, |
114 | WidgetActionDialogComponent, | 117 | WidgetActionDialogComponent, |
115 | CustomActionPrettyResourcesTabsComponent, | 118 | CustomActionPrettyResourcesTabsComponent, |
116 | - CustomActionPrettyEditorComponent | 119 | + CustomActionPrettyEditorComponent, |
120 | + CustomDialogContainerComponent | ||
117 | ], | 121 | ], |
118 | imports: [ | 122 | imports: [ |
119 | CommonModule, | 123 | CommonModule, |
@@ -149,10 +153,12 @@ import { CustomActionPrettyEditorComponent } from './widget/action/custom-action | @@ -149,10 +153,12 @@ import { CustomActionPrettyEditorComponent } from './widget/action/custom-action | ||
149 | ManageWidgetActionsComponent, | 153 | ManageWidgetActionsComponent, |
150 | WidgetActionDialogComponent, | 154 | WidgetActionDialogComponent, |
151 | CustomActionPrettyResourcesTabsComponent, | 155 | CustomActionPrettyResourcesTabsComponent, |
152 | - CustomActionPrettyEditorComponent | 156 | + CustomActionPrettyEditorComponent, |
157 | + CustomDialogContainerComponent | ||
153 | ], | 158 | ], |
154 | providers: [ | 159 | providers: [ |
155 | - WidgetComponentService | 160 | + WidgetComponentService, |
161 | + CustomDialogService | ||
156 | ] | 162 | ] |
157 | }) | 163 | }) |
158 | export class HomeComponentsModule { } | 164 | export class HomeComponentsModule { } |
1 | +/*================================================================================*/ | ||
2 | +/*======================= New TB 3.0 / Angular 8 Example =======================*/ | ||
3 | +/*================================================================================*/ | ||
4 | +/* | ||
5 | +.edit-entity-form mat-form-field { | ||
6 | + padding-right: 10px; | ||
7 | +} | ||
8 | +*/ | ||
1 | /*=======================================================================*/ | 9 | /*=======================================================================*/ |
2 | /*========== There are two examples: for edit and add entity ==========*/ | 10 | /*========== There are two examples: for edit and add entity ==========*/ |
3 | /*=======================================================================*/ | 11 | /*=======================================================================*/ |
1 | <!--=======================================================================--> | 1 | <!--=======================================================================--> |
2 | +<!--=================== New TB 3.0 / Angular 8 Example =================--> | ||
3 | +<!--=======================================================================--> | ||
4 | +<!--<form #editEntityForm="ngForm" [formGroup]="editEntityFormGroup"--> | ||
5 | +<!-- class="edit-entity-form"--> | ||
6 | +<!-- (ngSubmit)="save()" style="width: 600px;">--> | ||
7 | +<!-- <mat-toolbar fxLayout="row" color="primary">--> | ||
8 | +<!-- <h2>Edit {{entityType.toLowerCase()}} {{entityName}}</h2>--> | ||
9 | +<!-- <span fxFlex></span>--> | ||
10 | +<!-- <button mat-button mat-icon-button--> | ||
11 | +<!-- (click)="cancel()"--> | ||
12 | +<!-- type="button">--> | ||
13 | +<!-- <mat-icon class="material-icons">close</mat-icon>--> | ||
14 | +<!-- </button>--> | ||
15 | +<!-- </mat-toolbar>--> | ||
16 | +<!-- <mat-progress-bar color="warn" mode="indeterminate" *ngIf="isLoading$ | async">--> | ||
17 | +<!-- </mat-progress-bar>--> | ||
18 | +<!-- <div style="height: 4px;" *ngIf="!(isLoading$ | async)"></div>--> | ||
19 | +<!-- <div mat-dialog-content>--> | ||
20 | +<!-- <div class="mat-padding" fxLayout="column">--> | ||
21 | +<!-- <mat-form-field class="mat-block">--> | ||
22 | +<!-- <mat-label>Entity name</mat-label>--> | ||
23 | +<!-- <input matInput formControlName="entityName" required>--> | ||
24 | +<!-- <mat-error *ngIf="editEntityFormGroup.get('entityName').hasError('required')">--> | ||
25 | +<!-- Entity name required--> | ||
26 | +<!-- </mat-error>--> | ||
27 | +<!-- </mat-form-field>--> | ||
28 | +<!-- </div> --> | ||
29 | +<!-- </div>--> | ||
30 | +<!-- <div mat-dialog-actions fxLayout="row">--> | ||
31 | +<!-- <span fxFlex></span>--> | ||
32 | +<!-- <button mat-button mat-raised-button color="primary"--> | ||
33 | +<!-- type="submit"--> | ||
34 | +<!-- [disabled]="(isLoading$ | async) || editEntityForm.invalid || !editEntityForm.dirty">--> | ||
35 | +<!-- {{ 'action.save' | translate }}--> | ||
36 | +<!-- </button>--> | ||
37 | +<!-- <button mat-button color="primary"--> | ||
38 | +<!-- style="margin-right: 20px;"--> | ||
39 | +<!-- type="button"--> | ||
40 | +<!-- [disabled]="(isLoading$ | async)"--> | ||
41 | +<!-- (click)="cancel()" cdkFocusInitial>--> | ||
42 | +<!-- {{ 'action.cancel' | translate }}--> | ||
43 | +<!-- </button>--> | ||
44 | +<!-- </div>--> | ||
45 | +<!--</form>--> | ||
46 | +<!--=======================================================================--> | ||
2 | <!--===== There are two example templates: for edit and add entity =====--> | 47 | <!--===== There are two example templates: for edit and add entity =====--> |
3 | <!--=======================================================================--> | 48 | <!--=======================================================================--> |
4 | <!--======================== Edit entity example ========================--> | 49 | <!--======================== Edit entity example ========================--> |
1 | +/*================================================================================*/ | ||
2 | +/*======================= New TB 3.0 / Angular 8 Example =======================*/ | ||
3 | +/*================================================================================*/ | ||
4 | +// | ||
5 | +//let $injector = widgetContext.$scope.$injector; | ||
6 | +//let deviceService = $injector.get(widgetContext.servicesMap.get('deviceService')); | ||
7 | +// | ||
8 | +//deviceService.getDevice(entityId.id).subscribe(function(device) { | ||
9 | +// console.log(device); | ||
10 | +//}); | ||
11 | +// | ||
12 | +// | ||
13 | +//let customDialog = $injector.get(widgetContext.servicesMap.get('customDialog')); | ||
14 | +// | ||
15 | +//customDialog.customDialog(htmlTemplate, EditEntityDialogController).subscribe( | ||
16 | +// function(res) { | ||
17 | +// console.log(res); | ||
18 | +// } | ||
19 | +//); | ||
20 | +// | ||
21 | +//function EditEntityDialogController(instance) { | ||
22 | +// let vm = instance; | ||
23 | +// vm.entityId = entityId; | ||
24 | +// vm.entityName = entityName; | ||
25 | +// vm.entityType = entityId.entityType; | ||
26 | +// | ||
27 | +// vm.editEntityFormGroup = vm.fb.group({ | ||
28 | +// entityName: [vm.entityName, [vm.Validators.required]] | ||
29 | +// }); | ||
30 | +// | ||
31 | +// vm.cancel = function() { | ||
32 | +// vm.dialogRef.close(null); | ||
33 | +// }; | ||
34 | +// | ||
35 | +// vm.save = function() { | ||
36 | +// const newVal = vm.editEntityFormGroup.value; | ||
37 | +// vm.dialogRef.close(newVal); | ||
38 | +// }; | ||
39 | +//} | ||
40 | +// | ||
1 | /*=======================================================================*/ | 41 | /*=======================================================================*/ |
2 | /*===== There are three examples: for delete, edit and add entity =====*/ | 42 | /*===== There are three examples: for delete, edit and add entity =====*/ |
3 | /*=======================================================================*/ | 43 | /*=======================================================================*/ |
ui-ngx/src/app/modules/home/components/widget/dialog/custom-dialog-container.component.ts
0 → 100644
1 | +/// | ||
2 | +/// Copyright © 2016-2019 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 { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; | ||
18 | +import { | ||
19 | + Inject, | ||
20 | + ComponentRef, | ||
21 | + ElementRef, | ||
22 | + ViewContainerRef, | ||
23 | + ComponentFactory, | ||
24 | + Injector, | ||
25 | + ReflectiveInjector, | ||
26 | + Component, | ||
27 | + OnDestroy | ||
28 | +} from '@angular/core'; | ||
29 | +import { DialogComponent } from '@shared/components/dialog.component'; | ||
30 | +import { Store } from '@ngrx/store'; | ||
31 | +import { AppState } from '@core/core.state'; | ||
32 | +import { Router } from '@angular/router'; | ||
33 | +import { | ||
34 | + CustomDialogComponent, | ||
35 | + CUSTOM_DIALOG_DATA, | ||
36 | + CustomDialogData | ||
37 | +} from '@home/components/widget/dialog/custom-dialog.component'; | ||
38 | + | ||
39 | +export interface CustomDialogContainerData { | ||
40 | + controller: (instance: CustomDialogComponent) => void; | ||
41 | + data?: any; | ||
42 | + customComponentFactory: ComponentFactory<CustomDialogComponent>; | ||
43 | +} | ||
44 | + | ||
45 | +@Component({ | ||
46 | + selector: 'tb-custom-dialog-container-component', | ||
47 | + template: '' | ||
48 | +}) | ||
49 | +export class CustomDialogContainerComponent extends DialogComponent<CustomDialogContainerComponent, any> implements OnDestroy { | ||
50 | + | ||
51 | + private customComponentRef: ComponentRef<CustomDialogComponent>; | ||
52 | + | ||
53 | + constructor(protected store: Store<AppState>, | ||
54 | + protected router: Router, | ||
55 | + public viewContainerRef: ViewContainerRef, | ||
56 | + public dialogRef: MatDialogRef<CustomDialogContainerComponent, any>, | ||
57 | + @Inject(MAT_DIALOG_DATA) public data: CustomDialogContainerData) { | ||
58 | + super(store, router, dialogRef); | ||
59 | + let customDialogData: CustomDialogData = { | ||
60 | + controller: this.data.controller | ||
61 | + }; | ||
62 | + if (this.data.data) { | ||
63 | + customDialogData = {...customDialogData, ...this.data.data}; | ||
64 | + } | ||
65 | + const injector: Injector = ReflectiveInjector.resolveAndCreate([ | ||
66 | + { | ||
67 | + provide: CUSTOM_DIALOG_DATA, | ||
68 | + useValue: customDialogData | ||
69 | + }, | ||
70 | + { | ||
71 | + provide: MatDialogRef, | ||
72 | + useValue: dialogRef | ||
73 | + } | ||
74 | + ]); | ||
75 | + this.customComponentRef = this.viewContainerRef.createComponent(this.data.customComponentFactory, 0, injector); | ||
76 | + } | ||
77 | + | ||
78 | + ngOnDestroy(): void { | ||
79 | + super.ngOnDestroy(); | ||
80 | + if (this.customComponentRef) { | ||
81 | + this.customComponentRef.destroy(); | ||
82 | + } | ||
83 | + } | ||
84 | + | ||
85 | +} |
1 | +/// | ||
2 | +/// Copyright © 2016-2019 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 { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; | ||
18 | +import { Inject, InjectionToken } from '@angular/core'; | ||
19 | +import { DialogComponent } from '@shared/components/dialog.component'; | ||
20 | +import { Store } from '@ngrx/store'; | ||
21 | +import { AppState } from '@core/core.state'; | ||
22 | +import { Router } from '@angular/router'; | ||
23 | +import { PageComponent } from '@shared/components/page.component'; | ||
24 | +import { CustomDialogContainerComponent } from './custom-dialog-container.component'; | ||
25 | +import { FormBuilder, Validators } from '@angular/forms'; | ||
26 | + | ||
27 | +export const CUSTOM_DIALOG_DATA = new InjectionToken<any>('ConfigDialogData'); | ||
28 | + | ||
29 | +export interface CustomDialogData { | ||
30 | + controller: (instance: CustomDialogComponent) => void; | ||
31 | + [key: string]: any; | ||
32 | +} | ||
33 | + | ||
34 | +export class CustomDialogComponent extends PageComponent { | ||
35 | + | ||
36 | + [key: string]: any; | ||
37 | + | ||
38 | + constructor(protected store: Store<AppState>, | ||
39 | + protected router: Router, | ||
40 | + public dialogRef: MatDialogRef<CustomDialogContainerComponent>, | ||
41 | + public fb: FormBuilder, | ||
42 | + @Inject(CUSTOM_DIALOG_DATA) public data: CustomDialogData) { | ||
43 | + super(store); | ||
44 | + // @ts-ignore | ||
45 | + this.Validators = Validators; | ||
46 | + this.data.controller(this); | ||
47 | + } | ||
48 | +} |
1 | +/// | ||
2 | +/// Copyright © 2016-2019 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 { Injectable, Injector, NgModule } from '@angular/core'; | ||
18 | +import { Observable } from 'rxjs'; | ||
19 | +import { MatDialog } from '@angular/material'; | ||
20 | +import { TranslateService } from '@ngx-translate/core'; | ||
21 | +import { AuthService } from '@core/auth/auth.service'; | ||
22 | +import { DynamicComponentFactoryService } from '@core/services/dynamic-component-factory.service'; | ||
23 | +import { CommonModule } from '@angular/common'; | ||
24 | +import { SharedModule } from '@shared/shared.module'; | ||
25 | +import { mergeMap, tap } from 'rxjs/operators'; | ||
26 | +import { CustomDialogComponent } from './custom-dialog.component'; | ||
27 | +import { | ||
28 | + CustomDialogContainerComponent, | ||
29 | + CustomDialogContainerData | ||
30 | +} from '@home/components/widget/dialog/custom-dialog-container.component'; | ||
31 | + | ||
32 | +@Injectable() | ||
33 | +export class CustomDialogService { | ||
34 | + | ||
35 | + constructor( | ||
36 | + private translate: TranslateService, | ||
37 | + private authService: AuthService, | ||
38 | + private dynamicComponentFactoryService: DynamicComponentFactoryService, | ||
39 | + private injector: Injector, | ||
40 | + public dialog: MatDialog | ||
41 | + ) { | ||
42 | + } | ||
43 | + | ||
44 | + customDialog(template: string, controller: (instance: CustomDialogComponent) => void, data?: any): Observable<any> { | ||
45 | + return this.dynamicComponentFactoryService.createDynamicComponentFactory( | ||
46 | + class CustomDialogComponentInstance extends CustomDialogComponent {}, | ||
47 | + template, | ||
48 | + [SharedModule, CustomDialogModule]).pipe( | ||
49 | + mergeMap((factory) => { | ||
50 | + const dialogData: CustomDialogContainerData = { | ||
51 | + controller, | ||
52 | + customComponentFactory: factory, | ||
53 | + data | ||
54 | + }; | ||
55 | + return this.dialog.open<CustomDialogContainerComponent, CustomDialogContainerData, any>( | ||
56 | + CustomDialogContainerComponent, | ||
57 | + { | ||
58 | + disableClose: true, | ||
59 | + panelClass: ['tb-dialog', 'tb-fullscreen-dialog'], | ||
60 | + data: dialogData | ||
61 | + }).afterClosed().pipe( | ||
62 | + tap(() => { | ||
63 | + this.dynamicComponentFactoryService.destroyDynamicComponentFactory(factory); | ||
64 | + }) | ||
65 | + ); | ||
66 | + } | ||
67 | + )); | ||
68 | + } | ||
69 | + | ||
70 | +} | ||
71 | + | ||
72 | +@NgModule({ | ||
73 | + entryComponents: [ | ||
74 | + ], | ||
75 | + declarations: | ||
76 | + [ | ||
77 | + ], | ||
78 | + imports: [ | ||
79 | + CommonModule, | ||
80 | + SharedModule | ||
81 | + ], | ||
82 | + exports: [ | ||
83 | + ] | ||
84 | +}) | ||
85 | +class CustomDialogModule { } |
@@ -28,7 +28,7 @@ import { | @@ -28,7 +28,7 @@ import { | ||
28 | OnChanges, | 28 | OnChanges, |
29 | OnDestroy, | 29 | OnDestroy, |
30 | OnInit, | 30 | OnInit, |
31 | - SimpleChanges, | 31 | + SimpleChanges, Type, |
32 | ViewChild, | 32 | ViewChild, |
33 | ViewContainerRef, | 33 | ViewContainerRef, |
34 | ViewEncapsulation | 34 | ViewEncapsulation |
@@ -90,6 +90,15 @@ import { DashboardService } from '@core/http/dashboard.service'; | @@ -90,6 +90,15 @@ import { DashboardService } from '@core/http/dashboard.service'; | ||
90 | import { DatasourceService } from '@core/api/datasource.service'; | 90 | import { DatasourceService } from '@core/api/datasource.service'; |
91 | import { WidgetSubscription } from '@core/api/widget-subscription'; | 91 | import { WidgetSubscription } from '@core/api/widget-subscription'; |
92 | import { EntityService } from '@core/http/entity.service'; | 92 | import { EntityService } from '@core/http/entity.service'; |
93 | +import { AssetService } from '@core/http/asset.service'; | ||
94 | +import { DialogService } from '@core/services/dialog.service'; | ||
95 | +import { CustomDialogService } from '@home/components/widget/dialog/custom-dialog.service'; | ||
96 | + | ||
97 | +const ServicesMap = new Map<string, Type<any>>(); | ||
98 | +ServicesMap.set('deviceService', DeviceService); | ||
99 | +ServicesMap.set('assetService', AssetService); | ||
100 | +ServicesMap.set('dialogs', DialogService); | ||
101 | +ServicesMap.set('customDialog', CustomDialogService); | ||
93 | 102 | ||
94 | @Component({ | 103 | @Component({ |
95 | selector: 'tb-widget', | 104 | selector: 'tb-widget', |
@@ -242,6 +251,7 @@ export class WidgetComponent extends PageComponent implements OnInit, AfterViewI | @@ -242,6 +251,7 @@ export class WidgetComponent extends PageComponent implements OnInit, AfterViewI | ||
242 | } | 251 | } |
243 | 252 | ||
244 | this.widgetContext = this.dashboardWidget.widgetContext; | 253 | this.widgetContext = this.dashboardWidget.widgetContext; |
254 | + this.widgetContext.servicesMap = ServicesMap; | ||
245 | this.widgetContext.inited = false; | 255 | this.widgetContext.inited = false; |
246 | this.widgetContext.hideTitlePanel = false; | 256 | this.widgetContext.hideTitlePanel = false; |
247 | this.widgetContext.isEdit = this.isEdit; | 257 | this.widgetContext.isEdit = this.isEdit; |
@@ -647,6 +657,7 @@ export class WidgetComponent extends PageComponent implements OnInit, AfterViewI | @@ -647,6 +657,7 @@ export class WidgetComponent extends PageComponent implements OnInit, AfterViewI | ||
647 | this.dynamicWidgetComponent.errorMessages = this.errorMessages; | 657 | this.dynamicWidgetComponent.errorMessages = this.errorMessages; |
648 | 658 | ||
649 | this.widgetContext.$scope = this.dynamicWidgetComponent; | 659 | this.widgetContext.$scope = this.dynamicWidgetComponent; |
660 | + this.widgetContext.$scope.$injector = this.injector; | ||
650 | 661 | ||
651 | const containerElement = $(this.elementRef.nativeElement.querySelector('#widget-container')); | 662 | const containerElement = $(this.elementRef.nativeElement.querySelector('#widget-container')); |
652 | 663 |
@@ -39,12 +39,16 @@ import { | @@ -39,12 +39,16 @@ import { | ||
39 | WidgetActionsApi, | 39 | WidgetActionsApi, |
40 | WidgetSubscriptionApi | 40 | WidgetSubscriptionApi |
41 | } from '@core/api/widget-api.models'; | 41 | } from '@core/api/widget-api.models'; |
42 | -import { ComponentFactory } from '@angular/core'; | 42 | +import { ComponentFactory, Type } from '@angular/core'; |
43 | import { HttpErrorResponse } from '@angular/common/http'; | 43 | import { HttpErrorResponse } from '@angular/common/http'; |
44 | import { RafService } from '@core/services/raf.service'; | 44 | import { RafService } from '@core/services/raf.service'; |
45 | import { WidgetTypeId } from '@shared/models/id/widget-type-id'; | 45 | import { WidgetTypeId } from '@shared/models/id/widget-type-id'; |
46 | import { TenantId } from '@shared/models/id/tenant-id'; | 46 | import { TenantId } from '@shared/models/id/tenant-id'; |
47 | import { WidgetLayout } from '@shared/models/dashboard.models'; | 47 | import { WidgetLayout } from '@shared/models/dashboard.models'; |
48 | +import { DeviceService } from '@core/http/device.service'; | ||
49 | +import { AssetService } from '@app/core/http/asset.service'; | ||
50 | +import { DialogService } from '@core/services/dialog.service'; | ||
51 | +import { CustomDialogService } from '@home/components/widget/dialog/custom-dialog.service'; | ||
48 | 52 | ||
49 | export interface IWidgetAction { | 53 | export interface IWidgetAction { |
50 | name: string; | 54 | name: string; |
@@ -98,6 +102,7 @@ export interface WidgetContext { | @@ -98,6 +102,7 @@ export interface WidgetContext { | ||
98 | customHeaderActions?: Array<WidgetHeaderAction>; | 102 | customHeaderActions?: Array<WidgetHeaderAction>; |
99 | widgetActions?: Array<WidgetAction>; | 103 | widgetActions?: Array<WidgetAction>; |
100 | 104 | ||
105 | + servicesMap?: Map<string, Type<any>>; | ||
101 | } | 106 | } |
102 | 107 | ||
103 | export interface IDynamicWidgetComponent { | 108 | export interface IDynamicWidgetComponent { |
@@ -92,7 +92,7 @@ export class FullscreenDirective implements OnChanges, OnDestroy { | @@ -92,7 +92,7 @@ export class FullscreenDirective implements OnChanges, OnDestroy { | ||
92 | 92 | ||
93 | this.overlayRef = this.overlay.create(config); | 93 | this.overlayRef = this.overlay.create(config); |
94 | this.overlayRef.attach(new EmptyPortal()); | 94 | this.overlayRef.attach(new EmptyPortal()); |
95 | - this.overlayRef.overlayElement.append( targetElement ); | 95 | + this.overlayRef.overlayElement.appendChild( targetElement ); |
96 | this.fullscreenChanged.emit(true); | 96 | this.fullscreenChanged.emit(true); |
97 | } | 97 | } |
98 | 98 | ||
@@ -100,7 +100,7 @@ export class FullscreenDirective implements OnChanges, OnDestroy { | @@ -100,7 +100,7 @@ export class FullscreenDirective implements OnChanges, OnDestroy { | ||
100 | const targetElement: HTMLElement = this.fullscreenElement || this.elementRef.nativeElement; | 100 | const targetElement: HTMLElement = this.fullscreenElement || this.elementRef.nativeElement; |
101 | if (this.parentElement) { | 101 | if (this.parentElement) { |
102 | this.overlayRef.overlayElement.removeChild( targetElement ); | 102 | this.overlayRef.overlayElement.removeChild( targetElement ); |
103 | - this.parentElement.append(targetElement); | 103 | + this.parentElement.appendChild(targetElement); |
104 | this.parentElement = null; | 104 | this.parentElement = null; |
105 | } | 105 | } |
106 | targetElement.classList.remove('tb-fullscreen'); | 106 | targetElement.classList.remove('tb-fullscreen'); |