|
|
|
@ -14,7 +14,7 @@ |
|
|
|
/// limitations under the License.
|
|
|
|
///
|
|
|
|
|
|
|
|
import { Inject, Injectable, Optional, Type } from '@angular/core'; |
|
|
|
import { ComponentFactory, Inject, Injectable, Optional, Type } from '@angular/core'; |
|
|
|
import { DynamicComponentFactoryService } from '@core/services/dynamic-component-factory.service'; |
|
|
|
import { WidgetService } from '@core/http/widget.service'; |
|
|
|
import { forkJoin, from, Observable, of, ReplaySubject, Subject, throwError } from 'rxjs'; |
|
|
|
@ -28,7 +28,7 @@ import { |
|
|
|
} from '@home/models/widget-component.models'; |
|
|
|
import cssjs from '@core/css/css'; |
|
|
|
import { UtilsService } from '@core/services/utils.service'; |
|
|
|
import { ResourcesService } from '@core/services/resources.service'; |
|
|
|
import { ModulesWithFactories, ResourcesService } from '@core/services/resources.service'; |
|
|
|
import { Widget, widgetActionSources, WidgetControllerDescriptor, WidgetType } from '@shared/models/widget.models'; |
|
|
|
import { catchError, map, mergeMap, switchMap, tap } from 'rxjs/operators'; |
|
|
|
import { isFunction, isUndefined } from '@core/utils'; |
|
|
|
@ -46,6 +46,7 @@ import * as tinycolor_ from 'tinycolor2'; |
|
|
|
import moment from 'moment'; |
|
|
|
import { IModulesMap } from '@modules/common/modules-map.models'; |
|
|
|
import { HOME_COMPONENTS_MODULE_TOKEN } from '@home/components/tokens'; |
|
|
|
import { widgetSettingsComponentsMap } from '@home/components/widget/lib/settings/widget-settings.module'; |
|
|
|
|
|
|
|
const tinycolor = tinycolor_; |
|
|
|
|
|
|
|
@ -314,12 +315,12 @@ export class WidgetComponentService { |
|
|
|
this.cssParser.cssPreviewNamespace = widgetNamespace; |
|
|
|
this.cssParser.createStyleElement(widgetNamespace, widgetInfo.templateCss); |
|
|
|
const resourceTasks: Observable<string>[] = []; |
|
|
|
const modulesTasks: Observable<Type<any>[] | string>[] = []; |
|
|
|
const modulesTasks: Observable<ModulesWithFactories | string>[] = []; |
|
|
|
if (widgetInfo.resources.length > 0) { |
|
|
|
widgetInfo.resources.filter(r => r.isModule).forEach( |
|
|
|
(resource) => { |
|
|
|
modulesTasks.push( |
|
|
|
this.resources.loadModules(resource.url, this.modulesMap).pipe( |
|
|
|
this.resources.loadFactories(resource.url, this.modulesMap).pipe( |
|
|
|
catchError((e: Error) => of(e?.message ? e.message : `Failed to load widget resource module: '${resource.url}'`)) |
|
|
|
) |
|
|
|
); |
|
|
|
@ -336,7 +337,7 @@ export class WidgetComponentService { |
|
|
|
} |
|
|
|
); |
|
|
|
|
|
|
|
let modulesObservable: Observable<string | Type<any>[]>; |
|
|
|
let modulesObservable: Observable<string | ModulesWithFactories>; |
|
|
|
if (modulesTasks.length) { |
|
|
|
modulesObservable = forkJoin(modulesTasks).pipe( |
|
|
|
map(res => { |
|
|
|
@ -344,16 +345,20 @@ export class WidgetComponentService { |
|
|
|
if (msg) { |
|
|
|
return msg as string; |
|
|
|
} else { |
|
|
|
let resModules = (res as Type<any>[][]).flat(); |
|
|
|
const modulesWithFactoriesList = res as ModulesWithFactories[]; |
|
|
|
const resModulesWithFactories: ModulesWithFactories = { |
|
|
|
modules: modulesWithFactoriesList.map(mf => mf.modules).flat(), |
|
|
|
factories: modulesWithFactoriesList.map(mf => mf.factories).flat() |
|
|
|
}; |
|
|
|
if (modules && modules.length) { |
|
|
|
resModules = resModules.concat(modules); |
|
|
|
resModulesWithFactories.modules.concat(modules); |
|
|
|
} |
|
|
|
return resModules; |
|
|
|
return resModulesWithFactories; |
|
|
|
} |
|
|
|
}) |
|
|
|
); |
|
|
|
} else { |
|
|
|
modulesObservable = modules && modules.length ? of(modules) : of([]); |
|
|
|
modulesObservable = modules && modules.length ? of({modules, factories: []}) : of({modules: [], factories: []}); |
|
|
|
} |
|
|
|
|
|
|
|
resourceTasks.push( |
|
|
|
@ -362,10 +367,11 @@ export class WidgetComponentService { |
|
|
|
if (typeof resolvedModules === 'string') { |
|
|
|
return of(resolvedModules); |
|
|
|
} else { |
|
|
|
this.registerWidgetSettingsForms(widgetInfo, resolvedModules.factories); |
|
|
|
return this.dynamicComponentFactoryService.createDynamicComponentFactory( |
|
|
|
class DynamicWidgetComponentInstance extends DynamicWidgetComponent {}, |
|
|
|
widgetInfo.templateHtml, |
|
|
|
resolvedModules |
|
|
|
resolvedModules.modules |
|
|
|
).pipe( |
|
|
|
map((factory) => { |
|
|
|
widgetInfo.componentFactory = factory; |
|
|
|
@ -395,6 +401,25 @@ export class WidgetComponentService { |
|
|
|
)); |
|
|
|
} |
|
|
|
|
|
|
|
private registerWidgetSettingsForms(widgetInfo: WidgetInfo, factories: ComponentFactory<any>[]) { |
|
|
|
const directives: string[] = []; |
|
|
|
if (widgetInfo.settingsDirective && widgetInfo.settingsDirective.length) { |
|
|
|
directives.push(widgetInfo.settingsDirective); |
|
|
|
} |
|
|
|
if (widgetInfo.dataKeySettingsDirective && widgetInfo.dataKeySettingsDirective.length) { |
|
|
|
directives.push(widgetInfo.dataKeySettingsDirective); |
|
|
|
} |
|
|
|
if (widgetInfo.latestDataKeySettingsDirective && widgetInfo.latestDataKeySettingsDirective.length) { |
|
|
|
directives.push(widgetInfo.latestDataKeySettingsDirective); |
|
|
|
} |
|
|
|
if (directives.length) { |
|
|
|
factories.filter((factory) => directives.includes(factory.selector)) |
|
|
|
.forEach((foundFactory) => { |
|
|
|
widgetSettingsComponentsMap[foundFactory.selector] = foundFactory.componentType; |
|
|
|
}); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private createWidgetControllerDescriptor(widgetInfo: WidgetInfo, name: string): WidgetControllerDescriptor { |
|
|
|
let widgetTypeFunctionBody = `return function _${name} (ctx) {\n` + |
|
|
|
' var self = this;\n' + |
|
|
|
|