Browse Source

Merge pull request #6 from vvlladd28/feature/lazy-load/rulechain-page-components

Add lazy-load rulechain page components
pull/12407/head
Vladyslav Prykhodko 2 years ago
committed by GitHub
parent
commit
4dd973f75b
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 6
      ui-ngx/src/app/core/http/rule-chain.service.ts
  2. 38
      ui-ngx/src/app/core/services/resources.service.ts
  3. 26
      ui-ngx/src/app/modules/home/components/rule-node/action/action-rule-node-config.module.ts
  4. 13
      ui-ngx/src/app/modules/home/components/rule-node/enrichment/enrichment-rule-node-core.module.ts
  5. 16
      ui-ngx/src/app/modules/home/components/rule-node/external/external-rule-node-config.module.ts
  6. 11
      ui-ngx/src/app/modules/home/components/rule-node/filter/filter-rule-node-config.module.ts
  7. 5
      ui-ngx/src/app/modules/home/components/rule-node/flow/flow-rule-node-config.module.ts
  8. 46
      ui-ngx/src/app/modules/home/components/rule-node/rule-node-config.module.ts
  9. 11
      ui-ngx/src/app/modules/home/components/rule-node/transformation/transformation-rule-node-config.module.ts
  10. 3
      ui-ngx/src/app/modules/home/pages/edge/edge-routing.module.ts
  11. 10
      ui-ngx/src/app/modules/home/pages/rulechain/rule-node-config.component.ts
  12. 57
      ui-ngx/src/app/modules/home/pages/rulechain/rulechain-page.module.ts
  13. 2
      ui-ngx/src/app/modules/home/pages/rulechain/rulechain-routing.module.ts
  14. 25
      ui-ngx/src/app/modules/home/pages/rulechain/rulechain.module.ts

6
ui-ngx/src/app/core/http/rule-chain.service.ts

@ -180,6 +180,10 @@ export class RuleChainService {
return this.http.post<TestScriptResult>(url, inputParams, defaultHttpOptionsFromConfig(config));
}
public registerSystemRuleNodeConfigModule(module: any) {
Object.assign(this.ruleNodeConfigComponents, this.resourcesService.extractComponentsFromModule<IRuleNodeConfigurationComponent>(module, true));
}
private loadRuleNodeComponents(ruleChainType: RuleChainType, config?: RequestConfig): Observable<Array<RuleNodeComponentDescriptor>> {
return this.componentDescriptorService.getComponentDescriptorsByTypes(ruleNodeTypeComponentTypes, ruleChainType, config).pipe(
map((components) => {
@ -211,7 +215,7 @@ export class RuleChainService {
Observable<RuleNodeComponentDescriptor> {
const nodeDefinition = component.configurationDescriptor.nodeDefinition;
const uiResources = nodeDefinition.uiResources;
if (uiResources && uiResources.length) {
if (!this.ruleNodeConfigComponents[nodeDefinition.configDirective] && uiResources && uiResources.length) {
const commonResources = uiResources.filter((resource) => !resource.endsWith('.js'));
const moduleResource = uiResources.find((resource) => resource.endsWith('.js'));
const tasks: Observable<any>[] = [];

38
ui-ngx/src/app/core/services/resources.service.ts

@ -31,7 +31,7 @@ import { forkJoin, from, Observable, ReplaySubject, throwError } from 'rxjs';
import { HttpClient } from '@angular/common/http';
import { IModulesMap } from '@modules/common/modules-map.models';
import { TbResourceId } from '@shared/models/id/tb-resource-id';
import { isObject } from '@core/utils';
import { camelCase, isObject } from '@core/utils';
import { AuthService } from '@core/auth/auth.service';
import { select, Store } from '@ngrx/store';
import { selectIsAuthenticated } from '@core/auth/auth.selectors';
@ -51,6 +51,8 @@ export interface ModulesWithComponents {
standaloneComponents: ɵComponentDef<any>[];
}
export type ComponentsSelectorMap<T> = Record<string, Type<T>>;
export const flatModulesWithComponents = (modulesWithComponentsList: ModulesWithComponents[]): ModulesWithComponents => {
const modulesWithComponents: ModulesWithComponents = {
modules: [],
@ -91,6 +93,17 @@ export const componentTypeBySelector = (modulesWithComponents: ModulesWithCompon
const matchesSelector = (selectors: ɵCssSelectorList, selector: string) =>
selectors.some(s => s.some(s1 => typeof s1 === 'string' && s1 === selector));
const extractSelectorFromComponent = (comp: ɵComponentDef<any>): string => {
for (const selectors of comp.selectors) {
for (const selector of selectors) {
if (typeof selector === 'string') {
return selector;
}
}
}
return null;
}
@Injectable({
providedIn: 'root'
})
@ -252,6 +265,27 @@ export class ResourcesService {
);
}
public extractComponentsFromModule<T>(module: any, isCamelCaseSelector = false): ComponentsSelectorMap<T> {
const modulesWithComponents = this.extractModulesWithComponents(module);
const componentMap: ComponentsSelectorMap<T> = {};
const processComponents = (components: Array<ɵComponentDef<T>>) => {
components.forEach(item => {
let selector = extractSelectorFromComponent(item);
if (isCamelCaseSelector) {
selector = camelCase(selector);
}
componentMap[selector] = item.type;
});
};
processComponents(modulesWithComponents.standaloneComponents);
modulesWithComponents.modules.forEach(module => {
processComponents(module.components);
})
return componentMap;
}
private extractModulesWithComponents(module: any,
modulesWithComponents: ModulesWithComponents = {
@ -284,7 +318,7 @@ export class ResourcesService {
modulesWithComponents.standaloneComponents.push(component);
}
} else {
this.extractModulesWithComponents(module, modulesWithComponents, visitedModules);
this.extractModulesWithComponents(element, modulesWithComponents, visitedModules);
}
}
} else if (ɵNG_COMP_DEF in module) {

26
ui-ngx/src/app/modules/home/components/rule-node/action/action-rule-node-config.module.ts

@ -103,29 +103,3 @@ import { SendRestApiCallReplyConfigComponent } from './send-rest-api-call-reply-
})
export class ActionRuleNodeConfigModule {
}
export const actionRuleNodeConfigComponentsMap: Record<string, Type<IRuleNodeConfigurationComponent>> = {
'tbActionNodeAssignToCustomerConfig': AssignCustomerConfigComponent,
'tbActionNodeAttributesConfig': AttributesConfigComponent,
'tbActionNodeClearAlarmConfig': ClearAlarmConfigComponent,
'tbActionNodeCreateAlarmConfig': CreateAlarmConfigComponent,
'tbActionNodeCreateRelationConfig': CreateRelationConfigComponent,
'tbActionNodeDeleteAttributesConfig': DeleteAttributesConfigComponent,
'tbActionNodeDeleteRelationConfig': DeleteRelationConfigComponent,
'tbActionNodeDeviceProfileConfig': DeviceProfileConfigComponent,
'tbActionNodeDeviceStateConfig': DeviceStateConfigComponent,
'tbActionNodeGeneratorConfig': GeneratorConfigComponent,
'tbActionNodeGpsGeofencingConfig': GpsGeoActionConfigComponent,
'tbActionNodeLogConfig': LogConfigComponent,
'tbActionNodeMathFunctionConfig': MathFunctionConfigComponent,
'tbActionNodeMsgCountConfig': MsgCountConfigComponent,
'tbActionNodeMsgDelayConfig': MsgDelayConfigComponent,
'tbActionNodePushToCloudConfig': PushToCloudConfigComponent,
'tbActionNodePushToEdgeConfig': PushToEdgeConfigComponent,
'tbActionNodeRpcReplyConfig': RpcReplyConfigComponent,
'tbActionNodeRpcRequestConfig': RpcRequestConfigComponent,
'tbActionNodeCustomTableConfig': SaveToCustomTableConfigComponent,
'tbActionNodeSendRestApiCallReplyConfig': SendRestApiCallReplyConfigComponent,
'tbActionNodeTimeseriesConfig': TimeseriesConfigComponent,
'tbActionNodeUnAssignToCustomerConfig': UnassignCustomerConfigComponent
};

13
ui-ngx/src/app/modules/home/components/rule-node/enrichment/enrichment-rule-node-core.module.ts

@ -62,16 +62,3 @@ import { FetchDeviceCredentialsConfigComponent } from './fetch-device-credential
})
export class EnrichmentRuleNodeCoreModule {
}
export const enrichmentRuleNodeConfigComponentsMap: Record<string, Type<IRuleNodeConfigurationComponent>> = {
'tbEnrichmentNodeCalculateDeltaConfig': CalculateDeltaConfigComponent,
'tbEnrichmentNodeCustomerAttributesConfig': CustomerAttributesConfigComponent,
'tbEnrichmentNodeDeviceAttributesConfig': DeviceAttributesConfigComponent,
'tbEnrichmentNodeEntityDetailsConfig': EntityDetailsConfigComponent,
'tbEnrichmentNodeFetchDeviceCredentialsConfig': FetchDeviceCredentialsConfigComponent,
'tbEnrichmentNodeGetTelemetryFromDatabase': GetTelemetryFromDatabaseConfigComponent,
'tbEnrichmentNodeOriginatorAttributesConfig': OriginatorAttributesConfigComponent,
'tbEnrichmentNodeOriginatorFieldsConfig': OriginatorFieldsConfigComponent,
'tbEnrichmentNodeRelatedAttributesConfig': RelatedAttributesConfigComponent,
'tbEnrichmentNodeTenantAttributesConfig': TenantAttributesConfigComponent
}

16
ui-ngx/src/app/modules/home/components/rule-node/external/external-rule-node-config.module.ts

@ -73,19 +73,3 @@ import { LambdaConfigComponent } from './lambda-config.component';
})
export class ExternalRuleNodeConfigModule {
}
export const externalRuleNodeConfigComponentsMap: Record<string, Type<IRuleNodeConfigurationComponent>> = {
'tbExternalNodeAzureIotHubConfig': AzureIotHubConfigComponent,
'tbExternalNodeKafkaConfig': KafkaConfigComponent,
'tbExternalNodeLambdaConfig': LambdaConfigComponent,
'tbExternalNodeMqttConfig': MqttConfigComponent,
'tbExternalNodeNotificationConfig': NotificationConfigComponent,
'tbExternalNodePubSubConfig': PubSubConfigComponent,
'tbExternalNodeRabbitMqConfig': RabbitMqConfigComponent,
'tbExternalNodeRestApiCallConfig': RestApiCallConfigComponent,
'tbExternalNodeSendEmailConfig': SendEmailConfigComponent,
'tbExternalNodeSendSmsConfig': SendSmsConfigComponent,
'tbExternalNodeSlackConfig': SlackConfigComponent,
'tbExternalNodeSnsConfig': SnsConfigComponent,
'tbExternalNodeSqsConfig': SqsConfigComponent
}

11
ui-ngx/src/app/modules/home/components/rule-node/filter/filter-rule-node-config.module.ts

@ -56,14 +56,3 @@ import { CommonRuleNodeConfigModule } from '../common/common-rule-node-config.mo
})
export class FilterRuleNodeConfigModule {
}
export const filterRuleNodeConfigComponentsMap: Record<string, Type<IRuleNodeConfigurationComponent>> = {
'tbFilterNodeCheckAlarmStatusConfig': CheckAlarmStatusComponent,
'tbFilterNodeCheckMessageConfig': CheckMessageConfigComponent,
'tbFilterNodeCheckRelationConfig': CheckRelationConfigComponent,
'tbFilterNodeGpsGeofencingConfig': GpsGeoFilterConfigComponent,
'tbFilterNodeMessageTypeConfig': MessageTypeConfigComponent,
'tbFilterNodeOriginatorTypeConfig': OriginatorTypeConfigComponent,
'tbFilterNodeScriptConfig': ScriptConfigComponent,
'tbFilterNodeSwitchConfig': SwitchConfigComponent
}

5
ui-ngx/src/app/modules/home/components/rule-node/flow/flow-rule-node-config.module.ts

@ -36,8 +36,3 @@ import { RuleChainOutputComponent } from './rule-chain-output.component';
})
export class FlowRuleNodeConfigModule {
}
export const flowRuleNodeConfigComponentsMap: Record<string, Type<IRuleNodeConfigurationComponent>> = {
'tbFlowNodeRuleChainInputConfig': RuleChainInputComponent,
'tbFlowNodeRuleChainOutputConfig': RuleChainOutputComponent
}

46
ui-ngx/src/app/modules/home/components/rule-node/rule-node-config.module.ts

@ -14,35 +14,19 @@
/// limitations under the License.
///
import { NgModule, Type } from '@angular/core';
import { NgModule } from '@angular/core';
import { EmptyConfigComponent } from './empty-config.component';
import { CommonModule } from '@angular/common';
import { SharedModule } from '@shared/shared.module';
import { ActionRuleNodeConfigModule } from '@home/components/rule-node/action/action-rule-node-config.module';
import { FilterRuleNodeConfigModule } from '@home/components/rule-node/filter/filter-rule-node-config.module';
import { EnrichmentRuleNodeCoreModule } from '@home/components/rule-node/enrichment/enrichment-rule-node-core.module';
import { ExternalRuleNodeConfigModule } from '@home/components/rule-node/external/external-rule-node-config.module';
import {
actionRuleNodeConfigComponentsMap,
ActionRuleNodeConfigModule
} from '@home/components/rule-node/action/action-rule-node-config.module';
import {
filterRuleNodeConfigComponentsMap,
FilterRuleNodeConfigModule
} from '@home/components/rule-node/filter/filter-rule-node-config.module';
import {
enrichmentRuleNodeConfigComponentsMap,
EnrichmentRuleNodeCoreModule
} from '@home/components/rule-node/enrichment/enrichment-rule-node-core.module';
import {
externalRuleNodeConfigComponentsMap,
ExternalRuleNodeConfigModule
} from '@home/components/rule-node/external/external-rule-node-config.module';
import {
transformationRuleNodeConfigComponentsMap,
TransformationRuleNodeConfigModule
} from '@home/components/rule-node/transformation/transformation-rule-node-config.module';
import {
flowRuleNodeConfigComponentsMap,
FlowRuleNodeConfigModule
} from '@home/components/rule-node/flow/flow-rule-node-config.module';
import { IRuleNodeConfigurationComponent } from '@shared/models/rule-node.models';
import { FlowRuleNodeConfigModule } from '@home/components/rule-node/flow/flow-rule-node-config.module';
import { RuleChainService } from '@core/http/rule-chain.service';
@NgModule({
declarations: [
@ -62,14 +46,8 @@ import { IRuleNodeConfigurationComponent } from '@shared/models/rule-node.models
EmptyConfigComponent
]
})
export class RuleNodeConfigModule {}
export const ruleNodeConfigComponentsMap: Record<string, Type<IRuleNodeConfigurationComponent>> = {
...actionRuleNodeConfigComponentsMap,
...enrichmentRuleNodeConfigComponentsMap,
...externalRuleNodeConfigComponentsMap,
...filterRuleNodeConfigComponentsMap,
...flowRuleNodeConfigComponentsMap,
...transformationRuleNodeConfigComponentsMap,
'tbNodeEmptyConfig': EmptyConfigComponent
};
export class RuleNodeConfigModule {
constructor(private ruleChainService: RuleChainService) {
this.ruleChainService.registerSystemRuleNodeConfigModule(this.constructor);
}
}

11
ui-ngx/src/app/modules/home/components/rule-node/transformation/transformation-rule-node-config.module.ts

@ -57,14 +57,3 @@ import { ScriptConfigComponent } from '@home/components/rule-node/filter/script-
})
export class TransformationRuleNodeConfigModule {
}
export const transformationRuleNodeConfigComponentsMap: Record<string, Type<IRuleNodeConfigurationComponent>> = {
'tbTransformationNodeChangeOriginatorConfig': ChangeOriginatorConfigComponent,
'tbTransformationNodeCopyKeysConfig': CopyKeysConfigComponent,
'tbTransformationNodeDeduplicationConfig': DeduplicationConfigComponent,
'tbTransformationNodeDeleteKeysConfig': DeleteKeysConfigComponent,
'tbTransformationNodeJsonPathConfig': NodeJsonPathConfigComponent,
'tbTransformationNodeRenameKeysConfig': RenameKeysConfigComponent,
'tbTransformationNodeScriptConfig': ScriptConfigComponent,
'tbTransformationNodeToEmailConfig': ToEmailConfigComponent
}

3
ui-ngx/src/app/modules/home/pages/edge/edge-routing.module.ts

@ -291,6 +291,7 @@ const routes: Routes = [
import: false,
ruleChainType: RuleChainType.EDGE
},
loadChildren: () => import('../rulechain/rulechain-page.module').then(m => m.RuleChainPageModule),
resolve: {
ruleChain: RuleChainResolver,
ruleChainMetaData: RuleChainMetaDataResolver,
@ -336,6 +337,7 @@ const routes: Routes = [
import: false,
ruleChainType: RuleChainType.EDGE
},
loadChildren: () => import('../rulechain/rulechain-page.module').then(m => m.RuleChainPageModule),
resolve: {
ruleChain: RuleChainResolver,
ruleChainMetaData: RuleChainMetaDataResolver,
@ -358,6 +360,7 @@ const routes: Routes = [
import: true,
ruleChainType: RuleChainType.EDGE
},
loadChildren: () => import('../rulechain/rulechain-page.module').then(m => m.RuleChainPageModule),
resolve: {
ruleNodeComponents: RuleNodeComponentsResolver,
tooltipster: TooltipsterResolver

10
ui-ngx/src/app/modules/home/pages/rulechain/rule-node-config.component.ts

@ -21,7 +21,7 @@ import {
forwardRef,
Input,
OnDestroy,
Output, Type,
Output,
ViewChild,
ViewContainerRef
} from '@angular/core';
@ -43,7 +43,6 @@ import { coerceBooleanProperty } from '@angular/cdk/coercion';
import { JsonObjectEditComponent } from '@shared/components/json-object-edit.component';
import { deepClone } from '@core/utils';
import { RuleChainType } from '@shared/models/rule-chain.models';
import { ruleNodeConfigComponentsMap } from '@home/components/rule-node/rule-node-config.module';
@Component({
selector: 'tb-rule-node-config',
@ -213,12 +212,7 @@ export class RuleNodeConfigComponent implements ControlValueAccessor, OnDestroy
this.changeScriptSubscription = null;
}
this.definedConfigContainer.clear();
let component: Type<IRuleNodeConfigurationComponent>;
if (!this.nodeDefinition.uiResources?.length) {
component = ruleNodeConfigComponentsMap[this.nodeDefinition.configDirective];
} else {
component = this.ruleChainService.getRuleNodeConfigComponent(this.nodeDefinition.configDirective);
}
const component = this.ruleChainService.getRuleNodeConfigComponent(this.nodeDefinition.configDirective);
this.definedConfigComponentRef = this.definedConfigContainer.createComponent(component);
this.definedConfigComponent = this.definedConfigComponentRef.instance;
this.definedConfigComponent.ruleNodeId = this.ruleNodeId;

57
ui-ngx/src/app/modules/home/pages/rulechain/rulechain-page.module.ts

@ -0,0 +1,57 @@
///
/// Copyright © 2016-2024 The Thingsboard Authors
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { SharedModule } from '@shared/shared.module';
import { HomeComponentsModule } from '@home/components/home-components.module';
import { DurationLeftPipe } from '@shared/pipe/duration-left.pipe';
import {
EntityDebugSettingsButtonComponent
} from '@home/components/entity/debug/entity-debug-settings-button.component';
import { RuleNodeConfigModule } from '@home/components/rule-node/rule-node-config.module';
import {
AddRuleNodeDialogComponent,
AddRuleNodeLinkDialogComponent,
CreateNestedRuleChainDialogComponent,
RuleChainPageComponent
} from '@home/pages/rulechain/rulechain-page.component';
import { RuleNodeDetailsComponent } from '@home/pages/rulechain/rule-node-details.component';
import { RuleNodeConfigComponent } from '@home/pages/rulechain/rule-node-config.component';
import { LinkLabelsComponent } from '@home/pages/rulechain/link-labels.component';
import { RuleNodeLinkComponent } from '@home/pages/rulechain/rule-node-link.component';
@NgModule({
declarations: [
RuleChainPageComponent,
RuleNodeDetailsComponent,
LinkLabelsComponent,
RuleNodeLinkComponent,
RuleNodeConfigComponent,
AddRuleNodeLinkDialogComponent,
AddRuleNodeDialogComponent,
CreateNestedRuleChainDialogComponent
],
imports: [
CommonModule,
SharedModule,
DurationLeftPipe,
EntityDebugSettingsButtonComponent,
RuleNodeConfigModule,
HomeComponentsModule,
]
})
export class RuleChainPageModule {}

2
ui-ngx/src/app/modules/home/pages/rulechain/rulechain-routing.module.ts

@ -148,6 +148,7 @@ const routes: Routes = [
import: false,
ruleChainType: RuleChainType.CORE
},
loadChildren: () => import('./rulechain-page.module').then(m => m.RuleChainPageModule),
resolve: {
ruleChain: RuleChainResolver,
ruleChainMetaData: RuleChainMetaDataResolver,
@ -170,6 +171,7 @@ const routes: Routes = [
import: true,
ruleChainType: RuleChainType.CORE
},
loadChildren: () => import('./rulechain-page.module').then(m => m.RuleChainPageModule),
resolve: {
ruleNodeComponents: RuleNodeComponentsResolver,
tooltipster: TooltipsterResolver

25
ui-ngx/src/app/modules/home/pages/rulechain/rulechain.module.ts

@ -21,34 +21,14 @@ import { RuleChainComponent } from '@modules/home/pages/rulechain/rulechain.comp
import { RuleChainRoutingModule } from '@modules/home/pages/rulechain/rulechain-routing.module';
import { HomeComponentsModule } from '@modules/home/components/home-components.module';
import { RuleChainTabsComponent } from '@home/pages/rulechain/rulechain-tabs.component';
import {
AddRuleNodeDialogComponent,
AddRuleNodeLinkDialogComponent, CreateNestedRuleChainDialogComponent,
RuleChainPageComponent
} from './rulechain-page.component';
import { RuleNodeComponent } from '@home/pages/rulechain/rulenode.component';
import { FC_NODE_COMPONENT_CONFIG } from 'ngx-flowchart';
import { RuleNodeDetailsComponent } from './rule-node-details.component';
import { RuleNodeLinkComponent } from './rule-node-link.component';
import { LinkLabelsComponent } from '@home/pages/rulechain/link-labels.component';
import { RuleNodeConfigComponent } from './rule-node-config.component';
import { DurationLeftPipe } from '@shared/pipe/duration-left.pipe';
import { EntityDebugSettingsButtonComponent } from '@home/components/entity/debug/entity-debug-settings-button.component';
import { RuleNodeConfigModule } from '@home/components/rule-node/rule-node-config.module';
@NgModule({
declarations: [
RuleChainComponent,
RuleChainTabsComponent,
RuleChainPageComponent,
RuleNodeComponent,
RuleNodeDetailsComponent,
RuleNodeConfigComponent,
LinkLabelsComponent,
RuleNodeLinkComponent,
AddRuleNodeLinkDialogComponent,
AddRuleNodeDialogComponent,
CreateNestedRuleChainDialogComponent
],
providers: [
{
@ -56,16 +36,13 @@ import { RuleNodeConfigModule } from '@home/components/rule-node/rule-node-confi
useValue: {
nodeComponentType: RuleNodeComponent
}
}
},
],
imports: [
CommonModule,
SharedModule,
HomeComponentsModule,
RuleChainRoutingModule,
DurationLeftPipe,
EntityDebugSettingsButtonComponent,
RuleNodeConfigModule,
]
})
export class RuleChainModule { }

Loading…
Cancel
Save