Skip to content

Commit

Permalink
fix bugs in navigation for plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
ck-c8y committed Jan 2, 2025
1 parent 320fbdd commit eb6dbb5
Show file tree
Hide file tree
Showing 9 changed files with 124 additions and 74 deletions.
2 changes: 2 additions & 0 deletions dynamic-mapping-ui/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { NgModule } from '@angular/core';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { RouterModule as ngRouterModule } from '@angular/router';
import { BootstrapComponent, CoreModule, RouterModule } from '@c8y/ngx-components';
import { DynamicMappingModule } from './src/dynamic-mapping.module';
import './src/shared/styles/shared.css';

@NgModule({
Expand All @@ -31,6 +32,7 @@ import './src/shared/styles/shared.css';
ngRouterModule.forRoot([], { enableTracing: false, useHash: true }),
RouterModule.forRoot(),
CoreModule.forRoot(),
DynamicMappingModule
],
bootstrap: [BootstrapComponent]
})
Expand Down
2 changes: 1 addition & 1 deletion dynamic-mapping-ui/cumulocity.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export default {
{
name: 'Dynamic Mapping Mapper Plugin',
module: 'DynamicMappingModule',
path: './src/dynamic-mapping.module',
path: './src/dynamic-mapping.module.ts',
description: 'Adds a Dynamic Mapping Mapper Plugin',
scope: 'self'
}
Expand Down
4 changes: 2 additions & 2 deletions dynamic-mapping-ui/src/dynamic-mapping.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import { NgModule } from '@angular/core';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import {
BootstrapComponent,
CommonModule,
CoreModule,
DynamicFormsModule,
Expand Down Expand Up @@ -65,7 +66,6 @@ import { LandingModule } from './landing/landing.module';
CommonModule,
DynamicFormsModule,
FormlyPresetModule,
SharedModule,
RealtimeModule
],
exports: [],
Expand All @@ -75,7 +75,7 @@ import { LandingModule } from './landing/landing.module';
BsModalService,
hookNavigator(MappingNavigationFactory),
hookTab(MappingTabFactory),
]
],
})
export class DynamicMappingModule {
constructor() {}
Expand Down
1 change: 0 additions & 1 deletion dynamic-mapping-ui/src/mapping/grid/mapping.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,6 @@ import { ImportMappingsComponent } from '../import/import-modal.component';
import { MappingTypeComponent } from '../mapping-type/mapping-type.component';
import { StatusActivationRendererComponent } from '../renderer/status-activation.renderer.component';
import { StatusRendererComponent } from '../renderer/status.renderer.component';
// import { TemplateRendererComponent } from '../renderer/template.renderer.component';
import { HttpStatusCode } from '@angular/common/http';
import { DeploymentMapEntry, ExtensionType, MappingTypeDescriptionMap, StepperConfiguration } from '../../shared';
import { MappingFilterComponent } from '../filter/mapping-filter.component';
Expand Down
2 changes: 1 addition & 1 deletion dynamic-mapping-ui/src/mapping/mapping.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,4 +128,4 @@ import { MappingSubscriptionComponent } from './subscription/subscription.compon
}
]
})
export class MappingModule {}
export class MappingModule { }
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,9 @@ import {
SAMPLE_TEMPLATES_C8Y,
SnoopStatus,
StepperConfiguration,
countDeviceIdentifiers,
getGenericDeviceIdentifier
} from '../../shared';
import { countDeviceIdentifiers, getGenericDeviceIdentifier } from '../../shared/mapping/mapping.model';
import { MappingService } from '../core/mapping.service';
import { ValidationError } from '../shared/mapping.model';
import { EditorMode, STEP_DEFINE_SUBSTITUTIONS, STEP_GENERAL_SETTINGS, STEP_SELECT_TEMPLATES, STEP_TEST_MAPPING } from '../shared/stepper.model';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,25 +18,22 @@
*
* @authors Christof Strack
*/
import { CdkStep } from '@angular/cdk/stepper';
import { Component, EventEmitter, Input, OnDestroy, OnInit, Output, ViewEncapsulation } from '@angular/core';
import { FormGroup } from '@angular/forms';
import { AlertService, C8yStepper } from '@c8y/ngx-components';
import { BehaviorSubject, Subject } from 'rxjs';
import { CdkStep } from '@angular/cdk/stepper';

import { isDisabled } from '../shared/util';
import {
Direction,
SnoopStatus,
DeploymentMapEntry,
StepperConfiguration,
Mapping,
SAMPLE_TEMPLATES_C8Y,
SharedService
import {
ConnectorType,
DeploymentMapEntry,
Direction,
Mapping,
SAMPLE_TEMPLATES_C8Y, SnoopStatus,
StepperConfiguration
} from '../../shared';
import { EditorMode } from '../shared/stepper.model';
import { MappingService } from '../core/mapping.service';
import { BsModalService } from 'ngx-bootstrap/modal';
import { isDisabled } from '../shared/util';

interface StepperLabels {
next: string;
Expand All @@ -48,12 +45,6 @@ const CONSTANTS = {
SNOOP_TEMPLATES_MAX: 10
} as const;

@Component({
selector: 'd11r-snooping-stepper',
templateUrl: 'snooping-stepper.component.html',
styleUrls: ['../shared/mapping.style.css'],
encapsulation: ViewEncapsulation.None
})
@Component({
selector: 'd11r-snooping-stepper',
templateUrl: 'snooping-stepper.component.html',
Expand All @@ -63,27 +54,19 @@ const CONSTANTS = {
export class SnoopingStepperComponent implements OnInit, OnDestroy {
@Input() mapping: Mapping;
@Input() stepperConfiguration: StepperConfiguration;

@Input() set deploymentMapEntry(value: DeploymentMapEntry) {
this._deploymentMapEntry = value;
this.deploymentMapEntryChange(value); // Add this line to handle changes
}
get deploymentMapEntry(): DeploymentMapEntry {
return this._deploymentMapEntry;
}

@Input() deploymentMapEntry: DeploymentMapEntry;
@Output() cancel = new EventEmitter<void>();
@Output() commit = new EventEmitter<Mapping>();

readonly Direction = Direction;
readonly EditorMode = EditorMode;
readonly SnoopStatus = SnoopStatus;
readonly isDisabled = isDisabled;
Direction = Direction;
EditorMode = EditorMode;
SnoopStatus = SnoopStatus;
isDisabled = isDisabled;

propertyFormly = new FormGroup({});
isButtonDisabled$ = new BehaviorSubject<boolean>(true);
supportsMessageContext: boolean;
private readonly destroy$ = new Subject<void>();
private _deploymentMapEntry: DeploymentMapEntry;

snoopedTemplateCounter = 0;
stepLabel: any;
Expand All @@ -93,21 +76,13 @@ export class SnoopingStepperComponent implements OnInit, OnDestroy {
};

constructor(
private bsModalService: BsModalService,
private mappingService: MappingService,
private alertService: AlertService,
private sharedService: SharedService
) {}
) { }


// Add back the deploymentMapEntryChange method
deploymentMapEntryChange(entry: DeploymentMapEntry): void {
const isDisabled = !entry?.connectors || entry?.connectors?.length === 0;
this.isButtonDisabled$.next(isDisabled);
}

ngOnInit(): void {
// Initial check for button state
this.deploymentMapEntryChange(this._deploymentMapEntry);
}

ngOnDestroy(): void {
Expand All @@ -116,21 +91,26 @@ export class SnoopingStepperComponent implements OnInit, OnDestroy {
this.isButtonDisabled$.complete();
}

private initializeComponent(): void {
// Add any initialization logic here
this.updateButtonState();
}

private cleanup(): void {
this.destroy$.next();
this.destroy$.complete();
this.isButtonDisabled$.complete();
}

private updateButtonState(): void {
const isDisabled = !this._deploymentMapEntry?.connectors ||
this._deploymentMapEntry?.connectors?.length === 0;
this.isButtonDisabled$.next(isDisabled);
// eslint-disable-next-line @typescript-eslint/no-unused-vars
deploymentMapEntryChange(e) {
this.isButtonDisabled$.next(
!this.deploymentMapEntry?.connectors ||
this.deploymentMapEntry?.connectors?.length == 0
);

setTimeout(() => {
this.supportsMessageContext =
this.deploymentMapEntry.connectorsDetailed?.some(
(con) => con.connectorType == ConnectorType.KAFKA
);
});
}

getCurrentMapping(): Mapping {
Expand Down Expand Up @@ -177,7 +157,7 @@ export class SnoopingStepperComponent implements OnInit, OnDestroy {

private showSnoopingInfo(): void {
const message = `Wait ${CONSTANTS.HOUSEKEEPING_INTERVAL_SECONDS} seconds before snooped messages are visible. ` +
`Only the last ${CONSTANTS.SNOOP_TEMPLATES_MAX} messages are visible!`;
`Only the last ${CONSTANTS.SNOOP_TEMPLATES_MAX} messages are visible!`;
this.alertService.info(message);
}

Expand Down
80 changes: 74 additions & 6 deletions dynamic-mapping-ui/src/shared/misc/navigation.factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export class MappingNavigationFactory implements NavigatorNodeFactory {
appName: string;
isStandaloneApp: boolean = false;
configurations: ConnectorConfiguration[] = [];
readonly staticNodes = {
staticNodesStandalone = {
rootNode: new NavigatorNode({
label: gettext('Home'),
icon: 'home',
Expand Down Expand Up @@ -80,7 +80,43 @@ export class MappingNavigationFactory implements NavigatorNodeFactory {
priority: 300,
preventDuplicates: true
})
} as const;
} as const;

staticNodesPlugin = {
rootNode: new NavigatorNode({
label: gettext('Dynamic Data Mapper'),
icon: 'home',
path: '/sag-ps-pkg-dynamic-mapping/landing',
priority: 600,
preventDuplicates: true
}),
configurationNode: new NavigatorNode({
parent: gettext('Dynamic Data Mapper'),
label: gettext('Configuration'),
icon: 'cog',
path: `/sag-ps-pkg-dynamic-mapping/${NODE3}/serviceConfiguration`,
priority: 550,
preventDuplicates: true
}),
mappingNode: new NavigatorNode({
parent: gettext('Dynamic Data Mapper'),
label: gettext('Mapping'),
icon: 'rules',
path: `/sag-ps-pkg-dynamic-mapping/${NODE1}/mappings/inbound`,
priority: 400,
preventDuplicates: true
}),
monitoringNode: new NavigatorNode({
parent: gettext('Dynamic Data Mapper'),
label: gettext('Monitoring'),
icon: 'pie-chart',
path: `/sag-ps-pkg-dynamic-mapping/${NODE2}/monitoring/grid`,
priority: 300,
preventDuplicates: true
})
} as const;

staticNodes = {};

constructor(
private applicationService: ApplicationService,
Expand All @@ -103,7 +139,22 @@ export class MappingNavigationFactory implements NavigatorNodeFactory {
});

this.connectorConfigurationService.getConnectorConfigurationsAsObservable().subscribe(configs => {
const connectorsNavNode = this.staticNodes.connectorNode;
let connectorsNavNode;
if (this.isStandaloneApp) {
connectorsNavNode = this.staticNodesStandalone['connectorNode'];
} else {
connectorsNavNode = new NavigatorNode({
// parent: gettext('Configuration'),
// parent: gettext('Dynamic Data Mapper'),
label: gettext('Connectors'),
icon: 'c8y-device-management',
path: `/sag-ps-pkg-dynamic-mapping/${NODE3}/connectorConfiguration`,
priority: 500,
preventDuplicates: true
});
const configurationNode = this.staticNodesPlugin['configurationNode'];
configurationNode.add(connectorsNavNode);
}
// lets clear the array
connectorsNavNode.children.length = 0;
configs.forEach(config => {
Expand All @@ -119,8 +170,25 @@ export class MappingNavigationFactory implements NavigatorNodeFactory {
});
}

get() {
const navsFixed = Object.values(this.staticNodes);
return navsFixed;
async get() {
const feature: any = await this.sharedService.getFeatures();
let navs;
if (this.isStandaloneApp) {
navs = Object.values(this.staticNodesStandalone) as NavigatorNode[];
} else {
navs = Object.values(this.staticNodesPlugin) as NavigatorNode[];
}
return this.applicationService
.isAvailable(MappingNavigationFactory.APPLICATION_DYNAMIC_MAPPING_SERVICE)
.then((data) => {
if (!data.data || !feature) {
this.alertService.danger(
'Microservice:dynamic-mapping-service not subscribed. Please subscribe this service before using the mapping editor!'
);
console.error('dynamic-mapping-service microservice not subscribed!');
return [];
}
return navs;
});
}
}
22 changes: 11 additions & 11 deletions dynamic-mapping-ui/src/shared/shared.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,30 +19,30 @@
* @authors Christof Strack
*/
import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';
import { CoreModule } from '@c8y/ngx-components';
import { FORMLY_CONFIG } from '@ngx-formly/core';
import { BsDatepickerModule } from 'ngx-bootstrap/datepicker';
import { BsDropdownModule } from 'ngx-bootstrap/dropdown';
import { PaginationModule } from 'ngx-bootstrap/pagination';
import { WrapperCustomFormField } from './component/formly/custom-form-field-wrapper.component';
import { FieldInputCustom } from './component/formly/input-custom.type.component';
import { FieldTextareaCustom } from './component/formly/textarea.type.component';
import { ConfirmationModalComponent } from './confirmation/confirmation-modal.component';
import { CheckedRendererComponent } from './connector-configuration/renderer/checked-renderer.component';
import { ConnectorGridComponent } from './connector-configuration/connector-grid.component';
import { ConnectorStatusRendererComponent } from './connector-configuration/renderer/connector-status.renderer.component';
import { ConnectorConfigurationModalComponent } from './connector-configuration/create/connector-configuration-modal.component';
import { CheckedRendererComponent } from './connector-configuration/renderer/checked-renderer.component';
import { ConnectorDetailCellRendererComponent } from './connector-configuration/renderer/connector-link.renderer.component';
import { ConnectorStatusRendererComponent } from './connector-configuration/renderer/connector-status.renderer.component';
import { StatusEnabledRendererComponent } from './connector-configuration/renderer/status-enabled-renderer.component';
import { ConnectorDetailsComponent } from './connector-details/connector-details.component';
import { ConnectorStatusComponent } from './connector-log/connector-log.component';
import { JsonEditorComponent } from './editor/jsoneditor.component';
import { CamelCasePipe } from './misc/camel-case.pipe';
import { CapitalizeCasePipe } from './misc/capitalize-case.pipe';
import { DisableDirective } from './misc/disable.directive';
import { FormatStringPipe } from './misc/format-string.pipe';
import { WrapperCustomFormField } from './component/formly/custom-form-field-wrapper.component';
import { FieldTextareaCustom } from './component/formly/textarea.type.component';
import { FieldInputCustom } from './component/formly/input-custom.type.component';
import { FORMLY_CONFIG } from '@ngx-formly/core';
import { StatusEnabledRendererComponent } from './connector-configuration/renderer/status-enabled-renderer.component';
import { FilterJsonPipe } from './misc/filter-json.pipe';
import { ConnectorDetailCellRendererComponent } from './connector-configuration/renderer/connector-link.renderer.component';
import { RouterModule } from '@angular/router';
import { ConnectorDetailsComponent } from './connector-details/connector-details.component';
import { FormatStringPipe } from './misc/format-string.pipe';

@NgModule({
declarations: [
Expand Down

0 comments on commit eb6dbb5

Please sign in to comment.