Showing
16 changed files
with
165 additions
and
93 deletions
@@ -22,6 +22,7 @@ | @@ -22,6 +22,7 @@ | ||
22 | "main": "src/main.ts", | 22 | "main": "src/main.ts", |
23 | "polyfills": "src/polyfills.ts", | 23 | "polyfills": "src/polyfills.ts", |
24 | "tsConfig": "src/tsconfig.app.json", | 24 | "tsConfig": "src/tsconfig.app.json", |
25 | + "aot": true, | ||
25 | "assets": [ | 26 | "assets": [ |
26 | "src/thingsboard.ico", | 27 | "src/thingsboard.ico", |
27 | "src/assets", | 28 | "src/assets", |
@@ -161,6 +162,7 @@ | @@ -161,6 +162,7 @@ | ||
161 | "serve": { | 162 | "serve": { |
162 | "builder": "@angular-builders/custom-webpack:dev-server", | 163 | "builder": "@angular-builders/custom-webpack:dev-server", |
163 | "options": { | 164 | "options": { |
165 | + "aot": true, | ||
164 | "browserTarget": "thingsboard:build", | 166 | "browserTarget": "thingsboard:build", |
165 | "proxyConfig": "proxy.conf.js" | 167 | "proxyConfig": "proxy.conf.js" |
166 | }, | 168 | }, |
@@ -14,8 +14,10 @@ | @@ -14,8 +14,10 @@ | ||
14 | * limitations under the License. | 14 | * limitations under the License. |
15 | */ | 15 | */ |
16 | const CompressionPlugin = require("compression-webpack-plugin"); | 16 | const CompressionPlugin = require("compression-webpack-plugin"); |
17 | +const TerserPlugin = require("terser-webpack-plugin"); | ||
17 | const webpack = require("webpack"); | 18 | const webpack = require("webpack"); |
18 | const dirTree = require("directory-tree"); | 19 | const dirTree = require("directory-tree"); |
20 | +const AngularCompilerPlugin = require('@ngtools/webpack'); | ||
19 | 21 | ||
20 | var langs = []; | 22 | var langs = []; |
21 | 23 | ||
@@ -25,12 +27,14 @@ dirTree("./src/assets/locale/", {extensions: /\.json$/}, (item) => { | @@ -25,12 +27,14 @@ dirTree("./src/assets/locale/", {extensions: /\.json$/}, (item) => { | ||
25 | langs.push(item.name.slice(item.name.lastIndexOf("-") + 1, -5)); | 27 | langs.push(item.name.slice(item.name.lastIndexOf("-") + 1, -5)); |
26 | }); | 28 | }); |
27 | 29 | ||
28 | -module.exports = { | ||
29 | - plugins: [ | 30 | +module.exports = (config, options) => { |
31 | + config.plugins.push( | ||
30 | new webpack.DefinePlugin({ | 32 | new webpack.DefinePlugin({ |
31 | TB_VERSION: JSON.stringify(require("./package.json").version), | 33 | TB_VERSION: JSON.stringify(require("./package.json").version), |
32 | SUPPORTED_LANGS: JSON.stringify(langs), | 34 | SUPPORTED_LANGS: JSON.stringify(langs), |
33 | - }), | 35 | + }) |
36 | + ); | ||
37 | + config.plugins.push( | ||
34 | new CompressionPlugin({ | 38 | new CompressionPlugin({ |
35 | filename: "[path][base].gz[query]", | 39 | filename: "[path][base].gz[query]", |
36 | algorithm: "gzip", | 40 | algorithm: "gzip", |
@@ -38,6 +42,21 @@ module.exports = { | @@ -38,6 +42,21 @@ module.exports = { | ||
38 | threshold: 10240, | 42 | threshold: 10240, |
39 | minRatio: 0.8, | 43 | minRatio: 0.8, |
40 | deleteOriginalAssets: false, | 44 | deleteOriginalAssets: false, |
41 | - }), | ||
42 | - ], | 45 | + }) |
46 | + ); | ||
47 | + | ||
48 | + if (config.mode === 'production') { | ||
49 | + const index = config.plugins.findIndex(p => p instanceof AngularCompilerPlugin.AngularCompilerPlugin); | ||
50 | + const angularCompilerOptions = config.plugins[index]._options; | ||
51 | + angularCompilerOptions.emitClassMetadata = true; | ||
52 | + angularCompilerOptions.emitNgModuleScope = true; | ||
53 | + config.plugins.splice(index, 1); | ||
54 | + config.plugins.push(new AngularCompilerPlugin.AngularCompilerPlugin(angularCompilerOptions)); | ||
55 | + const terserPluginOptions = config.optimization.minimizer[1].options; | ||
56 | + delete terserPluginOptions.terserOptions.compress.global_defs.ngJitMode; | ||
57 | + terserPluginOptions.terserOptions.compress.side_effects = false; | ||
58 | + config.optimization.minimizer.splice(1, 1); | ||
59 | + config.optimization.minimizer.push(new TerserPlugin(terserPluginOptions)); | ||
60 | + } | ||
61 | + return config; | ||
43 | }; | 62 | }; |
@@ -100,6 +100,7 @@ | @@ -100,6 +100,7 @@ | ||
100 | "@angular/cli": "^10.1.5", | 100 | "@angular/cli": "^10.1.5", |
101 | "@angular/compiler-cli": "^10.1.5", | 101 | "@angular/compiler-cli": "^10.1.5", |
102 | "@angular/language-service": "^10.1.5", | 102 | "@angular/language-service": "^10.1.5", |
103 | + "@ngtools/webpack": "10.1.5", | ||
103 | "@types/canvas-gauges": "^2.1.2", | 104 | "@types/canvas-gauges": "^2.1.2", |
104 | "@types/flot": "^0.0.31", | 105 | "@types/flot": "^0.0.31", |
105 | "@types/jasmine": "^3.5.12", | 106 | "@types/jasmine": "^3.5.12", |
@@ -446,8 +446,12 @@ export class AuthService { | @@ -446,8 +446,12 @@ export class AuthService { | ||
446 | const refreshTokenValid = AuthService.isTokenValid('refresh_token'); | 446 | const refreshTokenValid = AuthService.isTokenValid('refresh_token'); |
447 | this.setUserFromJwtToken(null, null, false); | 447 | this.setUserFromJwtToken(null, null, false); |
448 | if (!refreshTokenValid) { | 448 | if (!refreshTokenValid) { |
449 | - this.refreshTokenSubject.error(new Error(this.translate.instant('access.refresh-token-expired'))); | ||
450 | - this.refreshTokenSubject = null; | 449 | + this.translate.get('access.refresh-token-expired').subscribe( |
450 | + (translation) => { | ||
451 | + this.refreshTokenSubject.error(new Error(translation)); | ||
452 | + this.refreshTokenSubject = null; | ||
453 | + } | ||
454 | + ); | ||
451 | } else { | 455 | } else { |
452 | const refreshTokenRequest = { | 456 | const refreshTokenRequest = { |
453 | refreshToken | 457 | refreshToken |
@@ -59,37 +59,40 @@ export class DynamicComponentFactoryService { | @@ -59,37 +59,40 @@ export class DynamicComponentFactoryService { | ||
59 | template: string, | 59 | template: string, |
60 | modules?: Type<any>[]): Observable<ComponentFactory<T>> { | 60 | modules?: Type<any>[]): Observable<ComponentFactory<T>> { |
61 | const dymamicComponentFactorySubject = new ReplaySubject<ComponentFactory<T>>(); | 61 | const dymamicComponentFactorySubject = new ReplaySubject<ComponentFactory<T>>(); |
62 | - const comp = this.createDynamicComponent(componentType, template); | ||
63 | - let moduleImports: Type<any>[] = [CommonModule]; | ||
64 | - if (modules) { | ||
65 | - moduleImports = [...moduleImports, ...modules]; | ||
66 | - } | ||
67 | - // noinspection AngularInvalidImportedOrDeclaredSymbol | ||
68 | - @NgModule({ | ||
69 | - declarations: [comp], | ||
70 | - imports: moduleImports | ||
71 | - }) | ||
72 | - class DynamicComponentInstanceModule extends DynamicComponentModule {} | ||
73 | - try { | ||
74 | - this.compiler.compileModuleAsync(DynamicComponentInstanceModule).then( | ||
75 | - (module) => { | ||
76 | - const moduleRef = module.create(this.injector); | ||
77 | - const factory = moduleRef.componentFactoryResolver.resolveComponentFactory(comp); | ||
78 | - this.dynamicComponentModulesMap.set(factory, { | ||
79 | - moduleRef, | ||
80 | - moduleType: module.moduleType | ||
81 | - }); | ||
82 | - dymamicComponentFactorySubject.next(factory); | ||
83 | - dymamicComponentFactorySubject.complete(); | 62 | + import('@angular/compiler').then( |
63 | + () => { | ||
64 | + const comp = this.createDynamicComponent(componentType, template); | ||
65 | + let moduleImports: Type<any>[] = [CommonModule]; | ||
66 | + if (modules) { | ||
67 | + moduleImports = [...moduleImports, ...modules]; | ||
84 | } | 68 | } |
85 | - ).catch( | ||
86 | - (e) => { | 69 | + // noinspection AngularInvalidImportedOrDeclaredSymbol |
70 | + const dynamicComponentInstanceModule = NgModule({ | ||
71 | + declarations: [comp], | ||
72 | + imports: moduleImports | ||
73 | + })(class DynamicComponentInstanceModule extends DynamicComponentModule {}); | ||
74 | + try { | ||
75 | + this.compiler.compileModuleAsync(dynamicComponentInstanceModule).then( | ||
76 | + (module) => { | ||
77 | + const moduleRef = module.create(this.injector); | ||
78 | + const factory = moduleRef.componentFactoryResolver.resolveComponentFactory(comp); | ||
79 | + this.dynamicComponentModulesMap.set(factory, { | ||
80 | + moduleRef, | ||
81 | + moduleType: module.moduleType | ||
82 | + }); | ||
83 | + dymamicComponentFactorySubject.next(factory); | ||
84 | + dymamicComponentFactorySubject.complete(); | ||
85 | + } | ||
86 | + ).catch( | ||
87 | + (e) => { | ||
88 | + dymamicComponentFactorySubject.error(e); | ||
89 | + } | ||
90 | + ); | ||
91 | + } catch (e) { | ||
87 | dymamicComponentFactorySubject.error(e); | 92 | dymamicComponentFactorySubject.error(e); |
88 | } | 93 | } |
89 | - ); | ||
90 | - } catch (e) { | ||
91 | - dymamicComponentFactorySubject.error(e); | ||
92 | - } | 94 | + } |
95 | + ); | ||
93 | return dymamicComponentFactorySubject.asObservable(); | 96 | return dymamicComponentFactorySubject.asObservable(); |
94 | } | 97 | } |
95 | 98 |
@@ -78,28 +78,31 @@ export class ResourcesService { | @@ -78,28 +78,31 @@ export class ResourcesService { | ||
78 | (module) => { | 78 | (module) => { |
79 | const modules = this.extractNgModules(module); | 79 | const modules = this.extractNgModules(module); |
80 | if (modules.length) { | 80 | if (modules.length) { |
81 | - const tasks: Promise<ModuleWithComponentFactories<any>>[] = []; | ||
82 | - for (const m of modules) { | ||
83 | - tasks.push(this.compiler.compileModuleAndAllComponentsAsync(m)); | ||
84 | - } | ||
85 | - forkJoin(tasks).subscribe((compiled) => { | ||
86 | - try { | ||
87 | - const componentFactories: ComponentFactory<any>[] = []; | ||
88 | - for (const c of compiled) { | ||
89 | - c.ngModuleFactory.create(this.injector); | ||
90 | - componentFactories.push(...c.componentFactories); | 81 | + import('@angular/compiler').then( |
82 | + () => { | ||
83 | + const tasks: Promise<ModuleWithComponentFactories<any>>[] = []; | ||
84 | + for (const m of modules) { | ||
85 | + tasks.push(this.compiler.compileModuleAndAllComponentsAsync(m)); | ||
91 | } | 86 | } |
92 | - this.loadedFactories[url].next(componentFactories); | ||
93 | - this.loadedFactories[url].complete(); | ||
94 | - } catch (e) { | ||
95 | - this.loadedFactories[url].error(new Error(`Unable to init module from url: ${url}`)); | ||
96 | - delete this.loadedFactories[url]; | ||
97 | - } | ||
98 | - }, | ||
99 | - (e) => { | ||
100 | - this.loadedFactories[url].error(new Error(`Unable to compile module from url: ${url}`)); | ||
101 | - delete this.loadedFactories[url]; | ||
102 | - }); | 87 | + forkJoin(tasks).subscribe((compiled) => { |
88 | + try { | ||
89 | + const componentFactories: ComponentFactory<any>[] = []; | ||
90 | + for (const c of compiled) { | ||
91 | + c.ngModuleFactory.create(this.injector); | ||
92 | + componentFactories.push(...c.componentFactories); | ||
93 | + } | ||
94 | + this.loadedFactories[url].next(componentFactories); | ||
95 | + this.loadedFactories[url].complete(); | ||
96 | + } catch (e) { | ||
97 | + this.loadedFactories[url].error(new Error(`Unable to init module from url: ${url}`)); | ||
98 | + delete this.loadedFactories[url]; | ||
99 | + } | ||
100 | + }, | ||
101 | + (e) => { | ||
102 | + this.loadedFactories[url].error(new Error(`Unable to compile module from url: ${url}`)); | ||
103 | + delete this.loadedFactories[url]; | ||
104 | + }); } | ||
105 | + ); | ||
103 | } else { | 106 | } else { |
104 | this.loadedFactories[url].error(new Error(`Module '${url}' doesn't have default export!`)); | 107 | this.loadedFactories[url].error(new Error(`Module '${url}' doesn't have default export!`)); |
105 | delete this.loadedFactories[url]; | 108 | delete this.loadedFactories[url]; |
@@ -133,26 +136,30 @@ export class ResourcesService { | @@ -133,26 +136,30 @@ export class ResourcesService { | ||
133 | } catch (e) { | 136 | } catch (e) { |
134 | } | 137 | } |
135 | if (modules && modules.length) { | 138 | if (modules && modules.length) { |
136 | - const tasks: Promise<ModuleWithComponentFactories<any>>[] = []; | ||
137 | - for (const m of modules) { | ||
138 | - tasks.push(this.compiler.compileModuleAndAllComponentsAsync(m)); | ||
139 | - } | ||
140 | - forkJoin(tasks).subscribe((compiled) => { | ||
141 | - try { | ||
142 | - for (const c of compiled) { | ||
143 | - c.ngModuleFactory.create(this.injector); | ||
144 | - } | ||
145 | - this.loadedModules[url].next(modules); | ||
146 | - this.loadedModules[url].complete(); | ||
147 | - } catch (e) { | ||
148 | - this.loadedModules[url].error(new Error(`Unable to init module from url: ${url}`)); | ||
149 | - delete this.loadedModules[url]; | 139 | + import('@angular/compiler').then( |
140 | + () => { | ||
141 | + const tasks: Promise<ModuleWithComponentFactories<any>>[] = []; | ||
142 | + for (const m of modules) { | ||
143 | + tasks.push(this.compiler.compileModuleAndAllComponentsAsync(m)); | ||
150 | } | 144 | } |
151 | - }, | ||
152 | - (e) => { | ||
153 | - this.loadedModules[url].error(new Error(`Unable to compile module from url: ${url}`)); | ||
154 | - delete this.loadedModules[url]; | ||
155 | - }); | 145 | + forkJoin(tasks).subscribe((compiled) => { |
146 | + try { | ||
147 | + for (const c of compiled) { | ||
148 | + c.ngModuleFactory.create(this.injector); | ||
149 | + } | ||
150 | + this.loadedModules[url].next(modules); | ||
151 | + this.loadedModules[url].complete(); | ||
152 | + } catch (e) { | ||
153 | + this.loadedModules[url].error(new Error(`Unable to init module from url: ${url}`)); | ||
154 | + delete this.loadedModules[url]; | ||
155 | + } | ||
156 | + }, | ||
157 | + (e) => { | ||
158 | + this.loadedModules[url].error(new Error(`Unable to compile module from url: ${url}`)); | ||
159 | + delete this.loadedModules[url]; | ||
160 | + }); | ||
161 | + } | ||
162 | + ); | ||
156 | } else { | 163 | } else { |
157 | this.loadedModules[url].error(new Error(`Module '${url}' doesn't have default export or not NgModule!`)); | 164 | this.loadedModules[url].error(new Error(`Module '${url}' doesn't have default export or not NgModule!`)); |
158 | delete this.loadedModules[url]; | 165 | delete this.loadedModules[url]; |
@@ -77,7 +77,7 @@ export class ComplexFilterPredicateComponent implements ControlValueAccessor, On | @@ -77,7 +77,7 @@ export class ComplexFilterPredicateComponent implements ControlValueAccessor, On | ||
77 | this.complexFilterPredicate = predicate; | 77 | this.complexFilterPredicate = predicate; |
78 | } | 78 | } |
79 | 79 | ||
80 | - private openComplexFilterDialog() { | 80 | + public openComplexFilterDialog() { |
81 | this.dialog.open<ComplexFilterPredicateDialogComponent, ComplexFilterPredicateDialogData, | 81 | this.dialog.open<ComplexFilterPredicateDialogComponent, ComplexFilterPredicateDialogData, |
82 | ComplexFilterPredicateInfo>(ComplexFilterPredicateDialogComponent, { | 82 | ComplexFilterPredicateInfo>(ComplexFilterPredicateDialogComponent, { |
83 | disableClose: true, | 83 | disableClose: true, |
@@ -59,7 +59,7 @@ export class FilterTextComponent implements ControlValueAccessor, OnInit { | @@ -59,7 +59,7 @@ export class FilterTextComponent implements ControlValueAccessor, OnInit { | ||
59 | 59 | ||
60 | requiredClass = false; | 60 | requiredClass = false; |
61 | 61 | ||
62 | - private filterText: string; | 62 | + public filterText: string; |
63 | 63 | ||
64 | private propagateChange = (v: any) => { }; | 64 | private propagateChange = (v: any) => { }; |
65 | 65 |
@@ -38,7 +38,7 @@ export interface AlarmRuleConditionDialogData { | @@ -38,7 +38,7 @@ export interface AlarmRuleConditionDialogData { | ||
38 | selector: 'tb-alarm-rule-condition-dialog', | 38 | selector: 'tb-alarm-rule-condition-dialog', |
39 | templateUrl: './alarm-rule-condition-dialog.component.html', | 39 | templateUrl: './alarm-rule-condition-dialog.component.html', |
40 | providers: [{provide: ErrorStateMatcher, useExisting: AlarmRuleConditionDialogComponent}], | 40 | providers: [{provide: ErrorStateMatcher, useExisting: AlarmRuleConditionDialogComponent}], |
41 | - styleUrls: ['/alarm-rule-condition-dialog.component.scss'] | 41 | + styleUrls: ['./alarm-rule-condition-dialog.component.scss'] |
42 | }) | 42 | }) |
43 | export class AlarmRuleConditionDialogComponent extends DialogComponent<AlarmRuleConditionDialogComponent, AlarmCondition> | 43 | export class AlarmRuleConditionDialogComponent extends DialogComponent<AlarmRuleConditionDialogComponent, AlarmCondition> |
44 | implements OnInit, ErrorStateMatcher { | 44 | implements OnInit, ErrorStateMatcher { |
@@ -15,7 +15,7 @@ | @@ -15,7 +15,7 @@ | ||
15 | /// | 15 | /// |
16 | 16 | ||
17 | import { MatDialogRef } from '@angular/material/dialog'; | 17 | import { MatDialogRef } from '@angular/material/dialog'; |
18 | -import { Inject, InjectionToken } from '@angular/core'; | 18 | +import { Directive, Inject, InjectionToken } from '@angular/core'; |
19 | import { Store } from '@ngrx/store'; | 19 | import { Store } from '@ngrx/store'; |
20 | import { AppState } from '@core/core.state'; | 20 | import { AppState } from '@core/core.state'; |
21 | import { Router } from '@angular/router'; | 21 | import { Router } from '@angular/router'; |
@@ -30,6 +30,7 @@ export interface CustomDialogData { | @@ -30,6 +30,7 @@ export interface CustomDialogData { | ||
30 | [key: string]: any; | 30 | [key: string]: any; |
31 | } | 31 | } |
32 | 32 | ||
33 | +@Directive() | ||
33 | export class CustomDialogComponent extends PageComponent { | 34 | export class CustomDialogComponent extends PageComponent { |
34 | 35 | ||
35 | [key: string]: any; | 36 | [key: string]: any; |
@@ -154,7 +154,7 @@ export class AlarmsTableWidgetComponent extends PageComponent implements OnInit, | @@ -154,7 +154,7 @@ export class AlarmsTableWidgetComponent extends PageComponent implements OnInit, | ||
154 | private alarmsTitlePattern: string; | 154 | private alarmsTitlePattern: string; |
155 | 155 | ||
156 | private displayDetails = true; | 156 | private displayDetails = true; |
157 | - private allowAcknowledgment = true; | 157 | + public allowAcknowledgment = true; |
158 | private allowClear = true; | 158 | private allowClear = true; |
159 | 159 | ||
160 | private defaultPageSize = 10; | 160 | private defaultPageSize = 10; |
@@ -186,11 +186,16 @@ export type TripAnimationSettings = { | @@ -186,11 +186,16 @@ export type TripAnimationSettings = { | ||
186 | usePointAsAnchor: boolean; | 186 | usePointAsAnchor: boolean; |
187 | normalizationStep: number; | 187 | normalizationStep: number; |
188 | showPolygon: boolean; | 188 | showPolygon: boolean; |
189 | + showLabel: boolean; | ||
190 | + showTooltip: boolean; | ||
189 | latKeyName: string; | 191 | latKeyName: string; |
190 | lngKeyName: string; | 192 | lngKeyName: string; |
191 | rotationAngle: number; | 193 | rotationAngle: number; |
192 | label: string; | 194 | label: string; |
193 | tooltipPattern: string; | 195 | tooltipPattern: string; |
196 | + tooltipColor: string; | ||
197 | + tooltipOpacity: number; | ||
198 | + tooltipFontColor: string; | ||
194 | useTooltipFunction: boolean; | 199 | useTooltipFunction: boolean; |
195 | useLabelFunction: boolean; | 200 | useLabelFunction: boolean; |
196 | pointAsAnchorFunction: GenericFunction; | 201 | pointAsAnchorFunction: GenericFunction; |
@@ -102,11 +102,11 @@ export class MultipleInputWidgetComponent extends PageComponent implements OnIni | @@ -102,11 +102,11 @@ export class MultipleInputWidgetComponent extends PageComponent implements OnIni | ||
102 | ctx: WidgetContext; | 102 | ctx: WidgetContext; |
103 | 103 | ||
104 | private formResize$: ResizeObserver; | 104 | private formResize$: ResizeObserver; |
105 | - private settings: MultipleInputWidgetSettings; | 105 | + public settings: MultipleInputWidgetSettings; |
106 | private widgetConfig: WidgetConfig; | 106 | private widgetConfig: WidgetConfig; |
107 | private subscription: IWidgetSubscription; | 107 | private subscription: IWidgetSubscription; |
108 | private datasources: Array<Datasource>; | 108 | private datasources: Array<Datasource>; |
109 | - private sources: Array<MultipleInputWidgetSource> = []; | 109 | + public sources: Array<MultipleInputWidgetSource> = []; |
110 | 110 | ||
111 | isVerticalAlignment: boolean; | 111 | isVerticalAlignment: boolean; |
112 | inputWidthSettings: string; | 112 | inputWidthSettings: string; |
@@ -126,7 +126,7 @@ export class TimeseriesTableWidgetComponent extends PageComponent implements OnI | @@ -126,7 +126,7 @@ export class TimeseriesTableWidgetComponent extends PageComponent implements OnI | ||
126 | private defaultPageSize = 10; | 126 | private defaultPageSize = 10; |
127 | private defaultSortOrder = '-0'; | 127 | private defaultSortOrder = '-0'; |
128 | private hideEmptyLines = false; | 128 | private hideEmptyLines = false; |
129 | - private showTimestamp = true; | 129 | + public showTimestamp = true; |
130 | private dateFormatFilter: string; | 130 | private dateFormatFilter: string; |
131 | 131 | ||
132 | private searchAction: WidgetAction = { | 132 | private searchAction: WidgetAction = { |
@@ -36,12 +36,14 @@ import { JsonFormProps } from './react/json-form.models'; | @@ -36,12 +36,14 @@ import { JsonFormProps } from './react/json-form.models'; | ||
36 | import inspector from 'schema-inspector'; | 36 | import inspector from 'schema-inspector'; |
37 | import * as tinycolor_ from 'tinycolor2'; | 37 | import * as tinycolor_ from 'tinycolor2'; |
38 | import { DialogService } from '@app/core/services/dialog.service'; | 38 | import { DialogService } from '@app/core/services/dialog.service'; |
39 | -import * as React from 'react'; | ||
40 | -import * as ReactDOM from 'react-dom'; | ||
41 | -import ReactSchemaForm from './react/json-form-react'; | 39 | +// import * as React from 'react'; |
40 | +// import * as ReactDOM from 'react-dom'; | ||
41 | +// import ReactSchemaForm from './react/json-form-react'; | ||
42 | import JsonFormUtils from './react/json-form-utils'; | 42 | import JsonFormUtils from './react/json-form-utils'; |
43 | import { JsonFormComponentData } from './json-form-component.models'; | 43 | import { JsonFormComponentData } from './json-form-component.models'; |
44 | import { GroupInfo } from '@shared/models/widget.models'; | 44 | import { GroupInfo } from '@shared/models/widget.models'; |
45 | +import { Observable } from 'rxjs/internal/Observable'; | ||
46 | +import { forkJoin, from } from 'rxjs'; | ||
45 | 47 | ||
46 | const tinycolor = tinycolor_; | 48 | const tinycolor = tinycolor_; |
47 | 49 | ||
@@ -252,11 +254,35 @@ export class JsonFormComponent implements OnInit, ControlValueAccessor, Validato | @@ -252,11 +254,35 @@ export class JsonFormComponent implements OnInit, ControlValueAccessor, Validato | ||
252 | if (destroy) { | 254 | if (destroy) { |
253 | this.destroyReactSchemaForm(); | 255 | this.destroyReactSchemaForm(); |
254 | } | 256 | } |
255 | - ReactDOM.render(React.createElement(ReactSchemaForm, this.formProps), this.reactRootElmRef.nativeElement); | 257 | + |
258 | + // import ReactSchemaForm from './react/json-form-react'; | ||
259 | + const reactSchemaFormObservables: Observable<any>[] = []; | ||
260 | + reactSchemaFormObservables.push(from(import('react'))); | ||
261 | + reactSchemaFormObservables.push(from(import('react-dom'))); | ||
262 | + reactSchemaFormObservables.push(from(import('./react/json-form-react'))); | ||
263 | + forkJoin(reactSchemaFormObservables).subscribe( | ||
264 | + (modules) => { | ||
265 | + const react = modules[0]; | ||
266 | + const reactDom = modules[1]; | ||
267 | + const jsonFormReact = modules[2].default; | ||
268 | + reactDom.render(react.createElement(jsonFormReact, this.formProps), this.reactRootElmRef.nativeElement); | ||
269 | + } | ||
270 | + ); | ||
271 | + /* import('./react/json-form-react').then( | ||
272 | + (mod) => { | ||
273 | + ReactDOM.render(React.createElement(mod.default, this.formProps), this.reactRootElmRef.nativeElement); | ||
274 | + } | ||
275 | + );*/ | ||
276 | + // ReactDOM.render(React.createElement(ReactSchemaForm, this.formProps), this.reactRootElmRef.nativeElement); | ||
256 | } | 277 | } |
257 | 278 | ||
258 | private destroyReactSchemaForm() { | 279 | private destroyReactSchemaForm() { |
259 | - ReactDOM.unmountComponentAtNode(this.reactRootElmRef.nativeElement); | 280 | + import('react-dom').then( |
281 | + (reactDom) => { | ||
282 | + reactDom.unmountComponentAtNode(this.reactRootElmRef.nativeElement); | ||
283 | + } | ||
284 | + ); | ||
285 | + // ReactDOM.unmountComponentAtNode(this.reactRootElmRef.nativeElement); | ||
260 | } | 286 | } |
261 | 287 | ||
262 | private validateModel(): boolean { | 288 | private validateModel(): boolean { |
@@ -16,7 +16,7 @@ | @@ -16,7 +16,7 @@ | ||
16 | 16 | ||
17 | import { AfterViewInit, Component, ElementRef, Input, OnChanges, OnInit, SimpleChanges } from '@angular/core'; | 17 | import { AfterViewInit, Component, ElementRef, Input, OnChanges, OnInit, SimpleChanges } from '@angular/core'; |
18 | import { coerceBooleanProperty } from '@angular/cdk/coercion'; | 18 | import { coerceBooleanProperty } from '@angular/cdk/coercion'; |
19 | -import Raphael, { RaphaelElement, RaphaelPaper, RaphaelSet } from 'raphael'; | 19 | +import { RaphaelElement, RaphaelPaper, RaphaelSet } from 'raphael'; |
20 | import * as tinycolor_ from 'tinycolor2'; | 20 | import * as tinycolor_ from 'tinycolor2'; |
21 | 21 | ||
22 | const tinycolor = tinycolor_; | 22 | const tinycolor = tinycolor_; |
@@ -90,10 +90,14 @@ export class LedLightComponent implements OnInit, AfterViewInit, OnChanges { | @@ -90,10 +90,14 @@ export class LedLightComponent implements OnInit, AfterViewInit, OnChanges { | ||
90 | if (this.paper) { | 90 | if (this.paper) { |
91 | this.paper.remove(); | 91 | this.paper.remove(); |
92 | } | 92 | } |
93 | - this.paper = Raphael($('#canvas_container', this.elementRef.nativeElement)[0], this.canvasSize, this.canvasSize); | ||
94 | - const center = this.canvasSize / 2; | ||
95 | - this.circleElement = this.paper.circle(center, center, this.radius); | ||
96 | - this.draw(); | 93 | + import('raphael').then( |
94 | + (raphael) => { | ||
95 | + this.paper = raphael.default($('#canvas_container', this.elementRef.nativeElement)[0], this.canvasSize, this.canvasSize); | ||
96 | + const center = this.canvasSize / 2; | ||
97 | + this.circleElement = this.paper.circle(center, center, this.radius); | ||
98 | + this.draw(); | ||
99 | + } | ||
100 | + ); | ||
97 | } | 101 | } |
98 | 102 | ||
99 | private draw() { | 103 | private draw() { |