diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/canvas-context-menu.service.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/canvas-context-menu.service.ts index 3551dd1841b8..ec00ba526d48 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/canvas-context-menu.service.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/canvas-context-menu.service.ts @@ -22,14 +22,16 @@ import { CanvasState } from '../state'; import { centerSelectedComponents, deleteComponents, + downloadFlow, enterProcessGroup, getParameterContextsAndOpenGroupComponentsDialog, goToRemoteProcessGroup, leaveProcessGroup, moveComponents, + moveToFront, + navigateToAdvancedProcessorUi, navigateToComponent, navigateToControllerServicesForProcessGroup, - navigateToAdvancedProcessorUi, navigateToEditComponent, navigateToEditCurrentProcessGroup, navigateToManageComponentPolicies, @@ -37,6 +39,7 @@ import { navigateToProvenanceForComponent, navigateToQueueListing, navigateToViewStatusHistoryForComponent, + openChangeProcessorVersionDialog, openChangeVersionDialogRequest, openCommitLocalChangesDialogRequest, openForceCommitLocalChangesDialogRequest, @@ -51,9 +54,7 @@ import { startCurrentProcessGroup, stopComponents, stopCurrentProcessGroup, - stopVersionControlRequest, - downloadFlow, - moveToFront + stopVersionControlRequest } from '../state/flow/flow.actions'; import { ComponentType } from '../../../state/shared'; import { @@ -970,14 +971,24 @@ export class CanvasContextMenu implements ContextMenuDefinitionProvider { } }, { - condition: (selection: any) => { - // TODO - canChangeProcessorVersion - return false; + condition: (selection: d3.Selection) => { + return this.canvasUtils.canChangeProcessorVersion(selection); }, clazz: 'fa fa-exchange', text: 'Change version', - action: () => { - // TODO - changeVersion + action: (selection: d3.Selection) => { + const data = selection.datum(); + this.store.dispatch( + openChangeProcessorVersionDialog({ + request: { + id: data.component.id, + uri: data.uri, + revision: data.revision, + type: data.component.type, + bundle: data.component.bundle + } + }) + ); } }, { diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/canvas-utils.service.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/canvas-utils.service.ts index 1538a6c1d2bc..e57e39099107 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/canvas-utils.service.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/canvas-utils.service.ts @@ -1712,6 +1712,33 @@ export class CanvasUtils { return false; } + /** + * Determines whether the current selection is a processor with more than one version. + * + * @argument {d3.Selection} selection The selection + * @returns {boolean} + */ + public canChangeProcessorVersion(selection: d3.Selection): boolean { + if (selection.size() !== 1) { + return false; + } + + if (!this.canRead(selection) || !this.canModify(selection)) { + return false; + } + + if (this.isProcessor(selection)) { + const data = selection.datum(); + const supportsModification = !( + data.status.aggregateSnapshot.runStatus === 'Running' || + data.status.aggregateSnapshot.activeThreadCount > 0 + ); + + return supportsModification && data.component.multipleVersionsAvailable; + } + return false; + } + public canMoveToFront(selection: d3.Selection): boolean { // ensure the correct number of components are selected if (selection.size() !== 1) { diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/state/controller-services/controller-services.actions.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/state/controller-services/controller-services.actions.ts index 64b75b193db1..840e5a684547 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/state/controller-services/controller-services.actions.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/state/controller-services/controller-services.actions.ts @@ -30,6 +30,7 @@ import { CreateControllerServiceRequest, DisableControllerServiceDialogRequest, EditControllerServiceDialogRequest, + FetchComponentVersionsRequest, SetEnableControllerServiceDialogRequest } from '../../../../state/shared'; @@ -121,3 +122,8 @@ export const selectControllerService = createAction( '[Controller Services] Select Controller Service', props<{ request: SelectControllerServiceRequest }>() ); + +export const openChangeControllerServiceVersionDialog = createAction( + `[Controller Services] Open Change Controller Service Version Dialog`, + props<{ request: FetchComponentVersionsRequest }>() +); diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/state/controller-services/controller-services.effects.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/state/controller-services/controller-services.effects.ts index 771a6161640a..70d4cdd95665 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/state/controller-services/controller-services.effects.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/state/controller-services/controller-services.effects.ts @@ -30,6 +30,7 @@ import { EditControllerService } from '../../../../ui/common/controller-service/ import { ComponentType, ControllerServiceReferencingComponent, + OpenChangeComponentVersionDialogRequest, EditControllerServiceDialogRequest, UpdateControllerServiceRequest } from '../../../../state/shared'; @@ -49,6 +50,8 @@ import { ErrorHelper } from '../../../../service/error-helper.service'; import { HttpErrorResponse } from '@angular/common/http'; import { ParameterHelperService } from '../../service/parameter-helper.service'; import { LARGE_DIALOG, SMALL_DIALOG, XL_DIALOG } from '../../../../index'; +import { ExtensionTypesService } from '../../../../service/extension-types.service'; +import { ChangeComponentVersionDialog } from '../../../../ui/common/change-component-version-dialog/change-component-version-dialog'; @Injectable() export class ControllerServicesEffects { @@ -61,7 +64,8 @@ export class ControllerServicesEffects { private dialog: MatDialog, private router: Router, private propertyTableHelperService: PropertyTableHelperService, - private parameterHelperService: ParameterHelperService + private parameterHelperService: ParameterHelperService, + private extensionTypesService: ExtensionTypesService ) {} loadControllerServices$ = createEffect(() => @@ -551,6 +555,58 @@ export class ControllerServicesEffects { { dispatch: false } ); + openChangeControllerServiceVersionDialog$ = createEffect( + () => + this.actions$.pipe( + ofType(ControllerServicesActions.openChangeControllerServiceVersionDialog), + map((action) => action.request), + switchMap((request) => + from( + this.extensionTypesService.getControllerServiceVersionsForType(request.type, request.bundle) + ).pipe( + map( + (response) => + ({ + fetchRequest: request, + componentVersions: response.controllerServiceTypes + }) as OpenChangeComponentVersionDialogRequest + ), + tap({ + error: (errorResponse: HttpErrorResponse) => { + this.store.dispatch(ErrorActions.snackBarError({ error: errorResponse.error })); + } + }) + ) + ), + tap((request) => { + const dialogRequest = this.dialog.open(ChangeComponentVersionDialog, { + ...LARGE_DIALOG, + data: request + }); + + dialogRequest.componentInstance.changeVersion.pipe(take(1)).subscribe((newVersion) => { + this.store.dispatch( + ControllerServicesActions.configureControllerService({ + request: { + id: request.fetchRequest.id, + uri: request.fetchRequest.uri, + payload: { + component: { + bundle: newVersion.bundle, + id: request.fetchRequest.id + }, + revision: request.fetchRequest.revision + } + } + }) + ); + dialogRequest.close(); + }); + }) + ), + { dispatch: false } + ); + private getRouteForReference(reference: ControllerServiceReferencingComponent): string[] { if (reference.referenceType == 'ControllerService') { if (reference.groupId == null) { diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/state/flow/flow.actions.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/state/flow/flow.actions.ts index ee58813aa7ba..030d9a01fcfe 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/state/flow/flow.actions.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/state/flow/flow.actions.ts @@ -94,6 +94,7 @@ import { VersionControlInformationEntity } from './index'; import { StatusHistoryRequest } from '../../../../state/status-history'; +import { FetchComponentVersionsRequest } from '../../../../state/shared'; const CANVAS_PREFIX = '[Canvas]'; @@ -769,3 +770,8 @@ export const downloadFlow = createAction( ); export const moveToFront = createAction(`${CANVAS_PREFIX} Move To Front`, props<{ request: MoveToFrontRequest }>()); + +export const openChangeProcessorVersionDialog = createAction( + `${CANVAS_PREFIX} Open Change Processor Version Dialog`, + props<{ request: FetchComponentVersionsRequest }>() +); diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/state/flow/flow.effects.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/state/flow/flow.effects.ts index 6c43c1823426..4e6f79db87fa 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/state/flow/flow.effects.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/state/flow/flow.effects.ts @@ -80,6 +80,7 @@ import { BucketEntity, ComponentType, isDefinedAndNotNull, + OpenChangeComponentVersionDialogRequest, RegistryClientEntity, VersionedFlowEntity, VersionedFlowSnapshotMetadataEntity @@ -116,6 +117,8 @@ import { ChangeVersionDialog } from '../../ui/canvas/items/flow/change-version-d import { ChangeVersionProgressDialog } from '../../ui/canvas/items/flow/change-version-progress-dialog/change-version-progress-dialog'; import { LocalChangesDialog } from '../../ui/canvas/items/flow/local-changes-dialog/local-changes-dialog'; import { ClusterConnectionService } from '../../../../service/cluster-connection.service'; +import { ExtensionTypesService } from '../../../../service/extension-types.service'; +import { ChangeComponentVersionDialog } from '../../../../ui/common/change-component-version-dialog/change-component-version-dialog'; @Injectable() export class FlowEffects { @@ -134,7 +137,8 @@ export class FlowEffects { private router: Router, private dialog: MatDialog, private propertyTableHelperService: PropertyTableHelperService, - private parameterHelperService: ParameterHelperService + private parameterHelperService: ParameterHelperService, + private extensionTypesService: ExtensionTypesService ) {} reloadFlow$ = createEffect(() => @@ -3199,4 +3203,55 @@ export class FlowEffects { }) ) ); + + openChangeProcessorVersionDialog$ = createEffect( + () => + this.actions$.pipe( + ofType(FlowActions.openChangeProcessorVersionDialog), + map((action) => action.request), + switchMap((request) => + from(this.extensionTypesService.getProcessorVersionsForType(request.type, request.bundle)).pipe( + map( + (response) => + ({ + fetchRequest: request, + componentVersions: response.processorTypes + }) as OpenChangeComponentVersionDialogRequest + ), + tap({ + error: (errorResponse: HttpErrorResponse) => { + this.store.dispatch(FlowActions.flowSnackbarError({ error: errorResponse.error })); + } + }) + ) + ), + tap((request) => { + const dialogRequest = this.dialog.open(ChangeComponentVersionDialog, { + ...LARGE_DIALOG, + data: request + }); + + dialogRequest.componentInstance.changeVersion.pipe(take(1)).subscribe((newVersion) => { + this.store.dispatch( + FlowActions.updateProcessor({ + request: { + id: request.fetchRequest.id, + uri: request.fetchRequest.uri, + type: ComponentType.Processor, + payload: { + component: { + bundle: newVersion.bundle, + id: request.fetchRequest.id + }, + revision: request.fetchRequest.revision + } + } + }) + ); + dialogRequest.close(); + }); + }) + ), + { dispatch: false } + ); } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/controller-service/controller-services.component.html b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/controller-service/controller-services.component.html index 357be8ef22c1..854cbe3888de 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/controller-service/controller-services.component.html +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/controller-service/controller-services.component.html @@ -53,6 +53,7 @@

Controller Services

(enableControllerService)="enableControllerService($event)" (disableControllerService)="disableControllerService($event)" (viewStateControllerService)="viewStateControllerService($event)" + (changeControllerServiceVersion)="changeControllerServiceVersion($event)" (deleteControllerService)="deleteControllerService($event)"> } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/controller-service/controller-services.component.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/controller-service/controller-services.component.ts index 1b9df8e42cfd..1d233e0f0e97 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/controller-service/controller-services.component.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/controller-service/controller-services.component.ts @@ -31,6 +31,7 @@ import { loadControllerServices, navigateToAdvancedServiceUi, navigateToEditService, + openChangeControllerServiceVersionDialog, openConfigureControllerServiceDialog, openDisableControllerServiceDialog, openEnableControllerServiceDialog, @@ -228,6 +229,20 @@ export class ControllerServices implements OnInit, OnDestroy { ); } + changeControllerServiceVersion(entity: ControllerServiceEntity): void { + this.store.dispatch( + openChangeControllerServiceVersionDialog({ + request: { + id: entity.id, + bundle: entity.component.bundle, + uri: entity.uri, + type: entity.component.type, + revision: entity.revision + } + }) + ); + } + deleteControllerService(entity: ControllerServiceEntity): void { this.store.dispatch( promptControllerServiceDeletion({ diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/parameter-contexts/ui/parameter-context-listing/edit-parameter-context/edit-parameter-context.component.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/parameter-contexts/ui/parameter-context-listing/edit-parameter-context/edit-parameter-context.component.ts index 068c91992f0e..3aac271a45f6 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/parameter-contexts/ui/parameter-context-listing/edit-parameter-context/edit-parameter-context.component.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/parameter-contexts/ui/parameter-context-listing/edit-parameter-context/edit-parameter-context.component.ts @@ -156,6 +156,7 @@ export class EditParameterContext { const payload: any = { revision: this.client.getRevision(pc), disconnectedNodeAcknowledged: this.clusterConnectionService.isDisconnectionAcknowledged(), + id: pc.id, component: { id: pc.id, name: this.editParameterContextForm.get('name')?.value, diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/state/flow-analysis-rules/flow-analysis-rules.actions.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/state/flow-analysis-rules/flow-analysis-rules.actions.ts index acae3493f3f1..11c9dc27782a 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/state/flow-analysis-rules/flow-analysis-rules.actions.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/state/flow-analysis-rules/flow-analysis-rules.actions.ts @@ -23,14 +23,15 @@ import { CreateFlowAnalysisRuleSuccess, DeleteFlowAnalysisRuleRequest, DeleteFlowAnalysisRuleSuccess, - EditFlowAnalysisRuleDialogRequest, - LoadFlowAnalysisRulesResponse, - SelectFlowAnalysisRuleRequest, DisableFlowAnalysisRuleRequest, + DisableFlowAnalysisRuleSuccess, + EditFlowAnalysisRuleDialogRequest, EnableFlowAnalysisRuleRequest, EnableFlowAnalysisRuleSuccess, - DisableFlowAnalysisRuleSuccess + LoadFlowAnalysisRulesResponse, + SelectFlowAnalysisRuleRequest } from './index'; +import { FetchComponentVersionsRequest } from '../../../../state/shared'; export const resetFlowAnalysisRulesState = createAction('[Flow Analysis Rules] Reset Flow Analysis Rules State'); @@ -126,3 +127,8 @@ export const selectFlowAnalysisRule = createAction( '[Flow Analysis Rules] Select Flow Analysis Rule', props<{ request: SelectFlowAnalysisRuleRequest }>() ); + +export const openChangeFlowAnalysisRuleVersionDialog = createAction( + `[Flow Analysis Rules] Open Change Flow Analysis Rule Version Dialog`, + props<{ request: FetchComponentVersionsRequest }>() +); diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/state/flow-analysis-rules/flow-analysis-rules.effects.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/state/flow-analysis-rules/flow-analysis-rules.effects.ts index 02af6d48096a..141887b4870c 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/state/flow-analysis-rules/flow-analysis-rules.effects.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/state/flow-analysis-rules/flow-analysis-rules.effects.ts @@ -29,7 +29,7 @@ import { ManagementControllerServiceService } from '../../service/management-con import { CreateFlowAnalysisRule } from '../../ui/flow-analysis-rules/create-flow-analysis-rule/create-flow-analysis-rule.component'; import { Router } from '@angular/router'; import { selectSaving } from '../management-controller-services/management-controller-services.selectors'; -import { UpdateControllerServiceRequest } from '../../../../state/shared'; +import { OpenChangeComponentVersionDialogRequest, UpdateControllerServiceRequest } from '../../../../state/shared'; import { EditFlowAnalysisRule } from '../../ui/flow-analysis-rules/edit-flow-analysis-rule/edit-flow-analysis-rule.component'; import { CreateFlowAnalysisRuleSuccess, EditFlowAnalysisRuleDialogRequest } from './index'; import { PropertyTableHelperService } from '../../../../service/property-table-helper.service'; @@ -38,6 +38,8 @@ import { ErrorHelper } from '../../../../service/error-helper.service'; import { selectStatus } from './flow-analysis-rules.selectors'; import { HttpErrorResponse } from '@angular/common/http'; import { LARGE_DIALOG, SMALL_DIALOG } from '../../../../index'; +import { ChangeComponentVersionDialog } from '../../../../ui/common/change-component-version-dialog/change-component-version-dialog'; +import { ExtensionTypesService } from '../../../../service/extension-types.service'; @Injectable() export class FlowAnalysisRulesEffects { @@ -49,7 +51,8 @@ export class FlowAnalysisRulesEffects { private errorHelper: ErrorHelper, private dialog: MatDialog, private router: Router, - private propertyTableHelperService: PropertyTableHelperService + private propertyTableHelperService: PropertyTableHelperService, + private extensionTypesService: ExtensionTypesService ) {} loadFlowAnalysisRule$ = createEffect(() => @@ -464,4 +467,56 @@ export class FlowAnalysisRulesEffects { ), { dispatch: false } ); + + openChangeFlowAnalysisRuleVersionDialog$ = createEffect( + () => + this.actions$.pipe( + ofType(FlowAnalysisRuleActions.openChangeFlowAnalysisRuleVersionDialog), + map((action) => action.request), + switchMap((request) => + from( + this.extensionTypesService.getFlowAnalysisRuleVersionsForType(request.type, request.bundle) + ).pipe( + map( + (response) => + ({ + fetchRequest: request, + componentVersions: response.flowAnalysisRuleTypes + }) as OpenChangeComponentVersionDialogRequest + ), + tap({ + error: (errorResponse: HttpErrorResponse) => { + this.store.dispatch(ErrorActions.snackBarError({ error: errorResponse.error })); + } + }) + ) + ), + tap((request) => { + const dialogRequest = this.dialog.open(ChangeComponentVersionDialog, { + ...LARGE_DIALOG, + data: request + }); + + dialogRequest.componentInstance.changeVersion.pipe(take(1)).subscribe((newVersion) => { + this.store.dispatch( + FlowAnalysisRuleActions.configureFlowAnalysisRule({ + request: { + id: request.fetchRequest.id, + uri: request.fetchRequest.uri, + payload: { + component: { + bundle: newVersion.bundle, + id: request.fetchRequest.id + }, + revision: request.fetchRequest.revision + } + } + }) + ); + dialogRequest.close(); + }); + }) + ), + { dispatch: false } + ); } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/state/management-controller-services/management-controller-services.actions.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/state/management-controller-services/management-controller-services.actions.ts index 75a2d20d4313..42f1958e6ec3 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/state/management-controller-services/management-controller-services.actions.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/state/management-controller-services/management-controller-services.actions.ts @@ -29,6 +29,7 @@ import { CreateControllerServiceRequest, DisableControllerServiceDialogRequest, EditControllerServiceDialogRequest, + FetchComponentVersionsRequest, SetEnableControllerServiceDialogRequest } from '../../../../state/shared'; @@ -128,3 +129,8 @@ export const selectControllerService = createAction( '[Management Controller Services] Select Controller Service', props<{ request: SelectControllerServiceRequest }>() ); + +export const openChangeMgtControllerServiceVersionDialog = createAction( + `[Management Controller Services] Open Change Management Controller Service Version Dialog`, + props<{ request: FetchComponentVersionsRequest }>() +); diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/state/management-controller-services/management-controller-services.effects.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/state/management-controller-services/management-controller-services.effects.ts index eb44d76f85de..a784fb7aa50c 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/state/management-controller-services/management-controller-services.effects.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/state/management-controller-services/management-controller-services.effects.ts @@ -33,6 +33,7 @@ import { ComponentType, ControllerServiceReferencingComponent, EditControllerServiceDialogRequest, + OpenChangeComponentVersionDialogRequest, UpdateControllerServiceRequest } from '../../../../state/shared'; import { Router } from '@angular/router'; @@ -43,6 +44,8 @@ import { PropertyTableHelperService } from '../../../../service/property-table-h import { HttpErrorResponse } from '@angular/common/http'; import { ErrorHelper } from '../../../../service/error-helper.service'; import { LARGE_DIALOG, SMALL_DIALOG, XL_DIALOG } from '../../../../index'; +import { ChangeComponentVersionDialog } from '../../../../ui/common/change-component-version-dialog/change-component-version-dialog'; +import { ExtensionTypesService } from '../../../../service/extension-types.service'; @Injectable() export class ManagementControllerServicesEffects { @@ -54,7 +57,8 @@ export class ManagementControllerServicesEffects { private errorHelper: ErrorHelper, private dialog: MatDialog, private router: Router, - private propertyTableHelperService: PropertyTableHelperService + private propertyTableHelperService: PropertyTableHelperService, + private extensionTypesService: ExtensionTypesService ) {} loadManagementControllerServices$ = createEffect(() => @@ -507,6 +511,58 @@ export class ManagementControllerServicesEffects { { dispatch: false } ); + openChangeMgtControllerServiceVersionDialog$ = createEffect( + () => + this.actions$.pipe( + ofType(ManagementControllerServicesActions.openChangeMgtControllerServiceVersionDialog), + map((action) => action.request), + switchMap((request) => + from( + this.extensionTypesService.getControllerServiceVersionsForType(request.type, request.bundle) + ).pipe( + map( + (response) => + ({ + fetchRequest: request, + componentVersions: response.controllerServiceTypes + }) as OpenChangeComponentVersionDialogRequest + ), + tap({ + error: (errorResponse: HttpErrorResponse) => { + this.store.dispatch(ErrorActions.snackBarError({ error: errorResponse.error })); + } + }) + ) + ), + tap((request) => { + const dialogRequest = this.dialog.open(ChangeComponentVersionDialog, { + ...LARGE_DIALOG, + data: request + }); + + dialogRequest.componentInstance.changeVersion.pipe(take(1)).subscribe((newVersion) => { + this.store.dispatch( + ManagementControllerServicesActions.configureControllerService({ + request: { + id: request.fetchRequest.id, + uri: request.fetchRequest.uri, + payload: { + component: { + bundle: newVersion.bundle, + id: request.fetchRequest.id + }, + revision: request.fetchRequest.revision + } + } + }) + ); + dialogRequest.close(); + }); + }) + ), + { dispatch: false } + ); + private getRouteForReference(reference: ControllerServiceReferencingComponent): string[] { if (reference.referenceType == 'ControllerService') { if (reference.groupId == null) { diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/state/reporting-tasks/reporting-tasks.actions.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/state/reporting-tasks/reporting-tasks.actions.ts index 993f05fab16c..88cb5c74938d 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/state/reporting-tasks/reporting-tasks.actions.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/state/reporting-tasks/reporting-tasks.actions.ts @@ -17,6 +17,8 @@ import { createAction, props } from '@ngrx/store'; import { + ConfigureReportingTaskRequest, + ConfigureReportingTaskSuccess, CreateReportingTaskRequest, CreateReportingTaskSuccess, DeleteReportingTaskRequest, @@ -27,10 +29,9 @@ import { StartReportingTaskRequest, StartReportingTaskSuccess, StopReportingTaskRequest, - StopReportingTaskSuccess, - ConfigureReportingTaskRequest, - ConfigureReportingTaskSuccess + StopReportingTaskSuccess } from './index'; +import { FetchComponentVersionsRequest } from '../../../../state/shared'; export const resetReportingTasksState = createAction('[Reporting Tasks] Reset Reporting Tasks State'); @@ -127,3 +128,8 @@ export const selectReportingTask = createAction( '[Reporting Tasks] Select Reporting Task', props<{ request: SelectReportingTaskRequest }>() ); + +export const openChangeReportingTaskVersionDialog = createAction( + `[Reporting Tasks] Open Change Reporting Task Version Dialog`, + props<{ request: FetchComponentVersionsRequest }>() +); diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/state/reporting-tasks/reporting-tasks.effects.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/state/reporting-tasks/reporting-tasks.effects.ts index 5a3d8fade4f5..8084446609b3 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/state/reporting-tasks/reporting-tasks.effects.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/state/reporting-tasks/reporting-tasks.effects.ts @@ -28,7 +28,7 @@ import { ReportingTaskService } from '../../service/reporting-task.service'; import { CreateReportingTask } from '../../ui/reporting-tasks/create-reporting-task/create-reporting-task.component'; import { Router } from '@angular/router'; import { selectSaving } from '../management-controller-services/management-controller-services.selectors'; -import { UpdateControllerServiceRequest } from '../../../../state/shared'; +import { OpenChangeComponentVersionDialogRequest, UpdateControllerServiceRequest } from '../../../../state/shared'; import { EditReportingTask } from '../../ui/reporting-tasks/edit-reporting-task/edit-reporting-task.component'; import { CreateReportingTaskSuccess, EditReportingTaskDialogRequest } from './index'; import { ManagementControllerServiceService } from '../../service/management-controller-service.service'; @@ -38,6 +38,8 @@ import { ErrorHelper } from '../../../../service/error-helper.service'; import { selectStatus } from './reporting-tasks.selectors'; import { HttpErrorResponse } from '@angular/common/http'; import { LARGE_DIALOG, SMALL_DIALOG } from '../../../../index'; +import { ChangeComponentVersionDialog } from '../../../../ui/common/change-component-version-dialog/change-component-version-dialog'; +import { ExtensionTypesService } from '../../../../service/extension-types.service'; @Injectable() export class ReportingTasksEffects { @@ -49,7 +51,8 @@ export class ReportingTasksEffects { private errorHelper: ErrorHelper, private dialog: MatDialog, private router: Router, - private propertyTableHelperService: PropertyTableHelperService + private propertyTableHelperService: PropertyTableHelperService, + private extensionTypesService: ExtensionTypesService ) {} loadReportingTasks$ = createEffect(() => @@ -444,4 +447,54 @@ export class ReportingTasksEffects { ), { dispatch: false } ); + + openChangeReportingTaskVersionDialog$ = createEffect( + () => + this.actions$.pipe( + ofType(ReportingTaskActions.openChangeReportingTaskVersionDialog), + map((action) => action.request), + switchMap((request) => + from(this.extensionTypesService.getReportingTaskVersionsForType(request.type, request.bundle)).pipe( + map( + (response) => + ({ + fetchRequest: request, + componentVersions: response.reportingTaskTypes + }) as OpenChangeComponentVersionDialogRequest + ), + tap({ + error: (errorResponse: HttpErrorResponse) => { + this.store.dispatch(ErrorActions.snackBarError({ error: errorResponse.error })); + } + }) + ) + ), + tap((request) => { + const dialogRequest = this.dialog.open(ChangeComponentVersionDialog, { + ...LARGE_DIALOG, + data: request + }); + + dialogRequest.componentInstance.changeVersion.pipe(take(1)).subscribe((newVersion) => { + this.store.dispatch( + ReportingTaskActions.configureReportingTask({ + request: { + id: request.fetchRequest.id, + uri: request.fetchRequest.uri, + payload: { + component: { + bundle: newVersion.bundle, + id: request.fetchRequest.id + }, + revision: request.fetchRequest.revision + } + } + }) + ); + dialogRequest.close(); + }); + }) + ), + { dispatch: false } + ); } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/flow-analysis-rules/flow-analysis-rule-table/flow-analysis-rule-table.component.html b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/flow-analysis-rules/flow-analysis-rule-table/flow-analysis-rule-table.component.html index 813825f463e3..c674e92801f0 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/flow-analysis-rules/flow-analysis-rule-table/flow-analysis-rule-table.component.html +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/flow-analysis-rules/flow-analysis-rule-table/flow-analysis-rule-table.component.html @@ -142,7 +142,10 @@ title="Enable"> } @if (canChangeVersion(item)) { -
+
} @if (canDelete(item)) {
(); @Output() disableFlowAnalysisRule: EventEmitter = new EventEmitter(); + @Output() changeFlowAnalysisRuleVersion: EventEmitter = + new EventEmitter(); sort: Sort = { active: 'name', @@ -230,6 +232,10 @@ export class FlowAnalysisRuleTable { this.enableFlowAnalysisRule.next(entity); } + changeVersionClicked(entity: FlowAnalysisRuleEntity): void { + this.changeFlowAnalysisRuleVersion.next(entity); + } + canDisable(entity: FlowAnalysisRuleEntity): boolean { const userAuthorized: boolean = this.canRead(entity) && this.canOperate(entity); return userAuthorized && this.isEnabled(entity); diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/flow-analysis-rules/flow-analysis-rules.component.html b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/flow-analysis-rules/flow-analysis-rules.component.html index e4b84518bb47..9ff6e5598811 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/flow-analysis-rules/flow-analysis-rules.component.html +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/flow-analysis-rules/flow-analysis-rules.component.html @@ -41,6 +41,7 @@ (enableFlowAnalysisRule)="enableFlowAnalysisRule($event)" (disableFlowAnalysisRule)="disableFlowAnalysisRule($event)" (viewStateFlowAnalysisRule)="viewStateFlowAnalysisRule($event)" + (changeFlowAnalysisRuleVersion)="changeFlowAnalysisRuleVersion($event)" (deleteFlowAnalysisRule)="deleteFlowAnalysisRule($event)">
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/flow-analysis-rules/flow-analysis-rules.component.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/flow-analysis-rules/flow-analysis-rules.component.ts index c9622614aedd..38e97d6ff628 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/flow-analysis-rules/flow-analysis-rules.component.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/flow-analysis-rules/flow-analysis-rules.component.ts @@ -30,6 +30,7 @@ import { enableFlowAnalysisRule, loadFlowAnalysisRules, navigateToEditFlowAnalysisRule, + openChangeFlowAnalysisRuleVersionDialog, openConfigureFlowAnalysisRuleDialog, openNewFlowAnalysisRuleDialog, promptFlowAnalysisRuleDeletion, @@ -155,6 +156,20 @@ export class FlowAnalysisRules implements OnInit, OnDestroy { ); } + changeFlowAnalysisRuleVersion(entity: FlowAnalysisRuleEntity): void { + this.store.dispatch( + openChangeFlowAnalysisRuleVersionDialog({ + request: { + id: entity.id, + bundle: entity.component.bundle, + uri: entity.uri, + type: entity.component.type, + revision: entity.revision + } + }) + ); + } + deleteFlowAnalysisRule(entity: FlowAnalysisRuleEntity): void { this.store.dispatch( promptFlowAnalysisRuleDeletion({ diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/management-controller-services/management-controller-services.component.html b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/management-controller-services/management-controller-services.component.html index 13c1dc27b1aa..b3a177d0c750 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/management-controller-services/management-controller-services.component.html +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/management-controller-services/management-controller-services.component.html @@ -46,6 +46,7 @@ (enableControllerService)="enableControllerService($event)" (disableControllerService)="disableControllerService($event)" (viewStateControllerService)="viewStateControllerService($event)" + (changeControllerServiceVersion)="changeControllerServiceVersion($event)" (deleteControllerService)="deleteControllerService($event)">
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/management-controller-services/management-controller-services.component.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/management-controller-services/management-controller-services.component.ts index 45038e2cb774..edcfef84eca0 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/management-controller-services/management-controller-services.component.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/management-controller-services/management-controller-services.component.ts @@ -28,6 +28,7 @@ import { loadManagementControllerServices, navigateToAdvancedServiceUi, navigateToEditService, + openChangeMgtControllerServiceVersionDialog, openConfigureControllerServiceDialog, openDisableControllerServiceDialog, openEnableControllerServiceDialog, @@ -175,6 +176,20 @@ export class ManagementControllerServices implements OnInit, OnDestroy { ); } + changeControllerServiceVersion(entity: ControllerServiceEntity): void { + this.store.dispatch( + openChangeMgtControllerServiceVersionDialog({ + request: { + id: entity.id, + bundle: entity.component.bundle, + uri: entity.uri, + type: entity.component.type, + revision: entity.revision + } + }) + ); + } + deleteControllerService(entity: ControllerServiceEntity): void { this.store.dispatch( promptControllerServiceDeletion({ diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/reporting-tasks/reporting-task-table/reporting-task-table.component.html b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/reporting-tasks/reporting-task-table/reporting-task-table.component.html index abe91ebdf06e..e5b2d05f4483 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/reporting-tasks/reporting-task-table/reporting-task-table.component.html +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/reporting-tasks/reporting-task-table/reporting-task-table.component.html @@ -143,7 +143,10 @@ title="Start">
} @if (canChangeVersion(item)) { -
+
} @if (canDelete(item)) {
= new EventEmitter(); @Output() viewStateReportingTask: EventEmitter = new EventEmitter(); @Output() stopReportingTask: EventEmitter = new EventEmitter(); + @Output() changeReportingTaskVersion: EventEmitter = new EventEmitter(); protected readonly TextTip = TextTip; protected readonly BulletinsTip = BulletinsTip; @@ -235,6 +236,10 @@ export class ReportingTaskTable { ); } + changeVersionClicked(entity: ReportingTaskEntity): void { + this.changeReportingTaskVersion.next(entity); + } + deleteClicked(entity: ReportingTaskEntity): void { this.deleteReportingTask.next(entity); } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/reporting-tasks/reporting-tasks.component.html b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/reporting-tasks/reporting-tasks.component.html index 4105bad1c05e..f4a148e7b6c7 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/reporting-tasks/reporting-tasks.component.html +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/reporting-tasks/reporting-tasks.component.html @@ -43,6 +43,7 @@ (viewReportingTaskDocumentation)="viewReportingTaskDocumentation($event)" (deleteReportingTask)="deleteReportingTask($event)" (stopReportingTask)="stopReportingTask($event)" + (changeReportingTaskVersion)="changeReportingTaskVersion($event)" (startReportingTask)="startReportingTask($event)">
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/reporting-tasks/reporting-tasks.component.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/reporting-tasks/reporting-tasks.component.ts index fe37c458a262..257a0b5fce94 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/reporting-tasks/reporting-tasks.component.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/reporting-tasks/reporting-tasks.component.ts @@ -28,15 +28,16 @@ import { } from '../../state/reporting-tasks/reporting-tasks.selectors'; import { loadReportingTasks, + navigateToAdvancedReportingTaskUi, navigateToEditReportingTask, + openChangeReportingTaskVersionDialog, openConfigureReportingTaskDialog, openNewReportingTaskDialog, promptReportingTaskDeletion, resetReportingTasksState, - startReportingTask, - stopReportingTask, selectReportingTask, - navigateToAdvancedReportingTaskUi + startReportingTask, + stopReportingTask } from '../../state/reporting-tasks/reporting-tasks.actions'; import { initialState } from '../../state/reporting-tasks/reporting-tasks.reducer'; import { selectCurrentUser } from '../../../../state/current-user/current-user.selectors'; @@ -184,6 +185,20 @@ export class ReportingTasks implements OnInit, OnDestroy { ); } + changeReportingTaskVersion(entity: ReportingTaskEntity): void { + this.store.dispatch( + openChangeReportingTaskVersionDialog({ + request: { + id: entity.id, + bundle: entity.component.bundle, + uri: entity.uri, + type: entity.component.type, + revision: entity.revision + } + }) + ); + } + ngOnDestroy(): void { this.store.dispatch(resetReportingTasksState()); } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/service/extension-types.service.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/service/extension-types.service.ts index 5fbc01928acf..0cb93ba8de84 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/service/extension-types.service.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/service/extension-types.service.ts @@ -30,10 +30,28 @@ export class ExtensionTypesService { return this.httpClient.get(`${ExtensionTypesService.API}/flow/processor-types`); } + getProcessorVersionsForType(processorType: string, bundle: Bundle): Observable { + const params = { + bundleGroupFilter: bundle.group, + bundleArtifactFilter: bundle.artifact, + type: processorType + }; + return this.httpClient.get(`${ExtensionTypesService.API}/flow/processor-types`, { params }); + } + getControllerServiceTypes(): Observable { return this.httpClient.get(`${ExtensionTypesService.API}/flow/controller-service-types`); } + getControllerServiceVersionsForType(serviceType: string, bundle: Bundle): Observable { + const params: any = { + serviceBundleGroup: bundle.group, + serviceBundleArtifact: bundle.artifact, + typeFilter: serviceType + }; + return this.httpClient.get(`${ExtensionTypesService.API}/flow/controller-service-types`, { params }); + } + getImplementingControllerServiceTypes(serviceType: string, bundle: Bundle): Observable { const params: any = { serviceType, @@ -48,6 +66,15 @@ export class ExtensionTypesService { return this.httpClient.get(`${ExtensionTypesService.API}/flow/reporting-task-types`); } + getReportingTaskVersionsForType(reportingTaskType: string, bundle: Bundle): Observable { + const params = { + serviceBundleGroup: bundle.group, + serviceBundleArtifact: bundle.artifact, + type: reportingTaskType + }; + return this.httpClient.get(`${ExtensionTypesService.API}/flow/reporting-task-types`, { params }); + } + getRegistryClientTypes(): Observable { return this.httpClient.get(`${ExtensionTypesService.API}/controller/registry-types`); } @@ -60,6 +87,15 @@ export class ExtensionTypesService { return this.httpClient.get(`${ExtensionTypesService.API}/flow/flow-analysis-rule-types`); } + getFlowAnalysisRuleVersionsForType(flowAnalysisRuleType: string, bundle: Bundle): Observable { + const params: any = { + serviceBundleGroup: bundle.group, + serviceBundleArtifact: bundle.artifact, + type: flowAnalysisRuleType + }; + return this.httpClient.get(`${ExtensionTypesService.API}/flow/flow-analysis-rule-types`, { params }); + } + getParameterProviderTypes(): Observable { return this.httpClient.get(`${ExtensionTypesService.API}/flow/parameter-provider-types`); } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/state/shared/index.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/state/shared/index.ts index 7ed8312e4a50..67c5c90bbd65 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/state/shared/index.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/state/shared/index.ts @@ -646,3 +646,16 @@ export interface ParameterProviderConfigurationEntity { id: string; component: ParameterProviderConfiguration; } + +export interface FetchComponentVersionsRequest { + id: string; + uri: string; + revision: Revision; + type: string; + bundle: Bundle; +} + +export interface OpenChangeComponentVersionDialogRequest { + fetchRequest: FetchComponentVersionsRequest; + componentVersions: DocumentedType[]; +} diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/change-component-version-dialog/change-component-version-dialog.html b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/change-component-version-dialog/change-component-version-dialog.html new file mode 100644 index 000000000000..902669e7ca7b --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/change-component-version-dialog/change-component-version-dialog.html @@ -0,0 +1,84 @@ + + +

Change Version

+
+
+ +
+
+
Name
+
+ {{ getName(selected) }} +
+
+
+
Bundle
+
+ {{ selected?.bundle?.group }} - {{ selected?.bundle?.artifact }} +
+
+ + Version + + @for (version of versions; track version) { + + {{ version.bundle.version }} + + } + + + @if (selected?.controllerServiceApis) { +
+
Supports Controller Services
+
+
    + @for (serviceApi of selected?.controllerServiceApis; track serviceApi) { +
  • + +
  • + } +
+
+
+ } +
+
Restriction
+ @if (selected?.usageRestriction) { +
+ {{ selected?.usageRestriction }} +
+ } @else { +
Not Restricted
+ } +
+
+
Description
+
{{ selected?.description }}
+
+
+
+ + + + +
+
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/change-component-version-dialog/change-component-version-dialog.scss b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/change-component-version-dialog/change-component-version-dialog.scss new file mode 100644 index 000000000000..b33f7cac34e6 --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/change-component-version-dialog/change-component-version-dialog.scss @@ -0,0 +1,16 @@ +/*! + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/change-component-version-dialog/change-component-version-dialog.spec.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/change-component-version-dialog/change-component-version-dialog.spec.ts new file mode 100644 index 000000000000..66b136dce686 --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/change-component-version-dialog/change-component-version-dialog.spec.ts @@ -0,0 +1,86 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ChangeComponentVersionDialog } from './change-component-version-dialog'; +import { MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog'; +import { NoopAnimationsModule } from '@angular/platform-browser/animations'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { OpenChangeComponentVersionDialogRequest } from '../../../state/shared'; + +describe('ChangeComponentVersionDialog', () => { + let component: ChangeComponentVersionDialog; + let fixture: ComponentFixture; + const data: OpenChangeComponentVersionDialogRequest = { + fetchRequest: { + id: 'd3acc2a0-018e-1000-e4c1-1fd32cb579b6', + uri: 'https://localhost:4200/nifi-api/processors/d3acc2a0-018e-1000-e4c1-1fd32cb579b6', + revision: { + clientId: 'e23146d1-018e-1000-9d09-6a3c09c72420', + version: 8 + }, + type: 'org.apache.nifi.processors.standard.GenerateFlowFile', + bundle: { + group: 'org.apache.nifi', + artifact: 'nifi-standard-nar', + version: '2.0.0-M2' + } + }, + componentVersions: [ + { + type: 'org.apache.nifi.processors.standard.GenerateFlowFile', + bundle: { + group: 'org.apache.nifi', + artifact: 'nifi-standard-nar', + version: '2.0.0-SNAPSHOT' + }, + description: + 'This processor creates FlowFiles with random data or custom content. GenerateFlowFile is useful for load testing, configuration, and simulation. Also see DuplicateFlowFile for additional load testing.', + restricted: false, + tags: ['random', 'test', 'load', 'generate'] + }, + { + type: 'org.apache.nifi.processors.standard.GenerateFlowFile', + bundle: { + group: 'org.apache.nifi', + artifact: 'nifi-standard-nar', + version: '2.0.0-M2' + }, + description: + 'This processor creates FlowFiles with random data or custom content. GenerateFlowFile is useful for load testing, configuration, and simulation. Also see DuplicateFlowFile for additional load testing.', + restricted: false, + tags: ['random', 'test', 'load', 'generate'] + } + ] + }; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [ChangeComponentVersionDialog, MatDialogModule, NoopAnimationsModule, MatFormFieldModule], + providers: [{ provide: MAT_DIALOG_DATA, useValue: data }] + }).compileComponents(); + + fixture = TestBed.createComponent(ChangeComponentVersionDialog); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/change-component-version-dialog/change-component-version-dialog.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/change-component-version-dialog/change-component-version-dialog.ts new file mode 100644 index 000000000000..61341f04c3d1 --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/change-component-version-dialog/change-component-version-dialog.ts @@ -0,0 +1,85 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 { Component, EventEmitter, Inject, Output } from '@angular/core'; +import { MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog'; +import { MatButton } from '@angular/material/button'; +import { Bundle, DocumentedType, OpenChangeComponentVersionDialogRequest } from '../../../state/shared'; +import { MatFormField, MatLabel, MatOption, MatSelect } from '@angular/material/select'; +import { FormBuilder, FormControl, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms'; +import { TextTip } from '../tooltips/text-tip/text-tip.component'; +import { NifiTooltipDirective } from '../tooltips/nifi-tooltip.directive'; +import { NiFiCommon } from '../../../service/nifi-common.service'; +import { ControllerServiceApi } from '../controller-service/controller-service-api/controller-service-api.component'; + +@Component({ + selector: 'change-component-version-dialog', + standalone: true, + imports: [ + MatDialogModule, + MatButton, + MatSelect, + MatLabel, + MatOption, + MatFormField, + ReactiveFormsModule, + NifiTooltipDirective, + ControllerServiceApi + ], + templateUrl: './change-component-version-dialog.html', + styleUrl: './change-component-version-dialog.scss' +}) +export class ChangeComponentVersionDialog { + versions: DocumentedType[]; + selected: DocumentedType | null = null; + changeComponentVersionForm: FormGroup; + private currentBundle: Bundle; + + @Output() changeVersion: EventEmitter = new EventEmitter(); + + constructor( + @Inject(MAT_DIALOG_DATA) private dialogRequest: OpenChangeComponentVersionDialogRequest, + private formBuilder: FormBuilder, + private nifiCommon: NiFiCommon + ) { + this.versions = dialogRequest.componentVersions; + this.currentBundle = dialogRequest.fetchRequest.bundle; + const idx = this.versions.findIndex( + (version: DocumentedType) => version.bundle.version === this.currentBundle.version + ); + this.selected = this.versions[idx > 0 ? idx : 0]; + this.changeComponentVersionForm = this.formBuilder.group({ + bundle: new FormControl(this.selected, [Validators.required]) + }); + } + + apply(): void { + if (this.selected) { + this.changeVersion.next(this.selected); + } + } + + isCurrent(selection: DocumentedType | null): boolean { + return selection?.bundle.version === this.currentBundle.version; + } + + getName(selected: DocumentedType | null): string { + return this.nifiCommon.substringAfterLast(selected?.type || '', '.'); + } + + protected readonly TextTip = TextTip; +} diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/controller-service/controller-service-table/controller-service-table.component.html b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/controller-service/controller-service-table/controller-service-table.component.html index 5fc5b47ca42a..177149107025 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/controller-service/controller-service-table/controller-service-table.component.html +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/controller-service/controller-service-table/controller-service-table.component.html @@ -150,7 +150,10 @@ title="Enable">
} @if (canChangeVersion(item)) { -
+
} @if (canDelete(item)) {
(); @Output() viewStateControllerService: EventEmitter = new EventEmitter(); + @Output() changeControllerServiceVersion: EventEmitter = + new EventEmitter(); protected readonly TextTip = TextTip; protected readonly BulletinsTip = BulletinsTip; @@ -266,6 +268,10 @@ export class ControllerServiceTable { this.deleteControllerService.next(entity); } + changeVersionClicked(entity: ControllerServiceEntity) { + this.changeControllerServiceVersion.next(entity); + } + canViewState(entity: ControllerServiceEntity): boolean { return this.canRead(entity) && this.canWrite(entity) && entity.component.persistsState === true; } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/extension-creation/extension-creation.component.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/extension-creation/extension-creation.component.ts index d7a33386407d..e2f6c7355e0e 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/extension-creation/extension-creation.component.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/extension-creation/extension-creation.component.ts @@ -159,8 +159,20 @@ export class ExtensionCreation { } isSelected(documentedType: DocumentedType): boolean { - if (this.selectedType) { - return documentedType.type == this.selectedType.type; + return this.areDocumentedTypesTheSame(this.selectedType, documentedType); + } + + private areDocumentedTypesTheSame(type1: DocumentedType | null, type2: DocumentedType | null): boolean { + if (type1 == type2) { + return true; + } + if (type1 && type2) { + return ( + type1.type === type2.type && + type1.bundle.version === type2.bundle.version && + type1.bundle.group === type2.bundle.group && + type1.bundle.artifact === type2.bundle.artifact + ); } return false; } @@ -197,8 +209,8 @@ export class ExtensionCreation { private selectRow(offset: number) { if (this.selectedType && this.dataSource.filteredData.length > 0) { // find the index of the currently selected row - const selectedIndex = this.dataSource.filteredData.findIndex( - (data) => data.type === this.selectedType?.type + const selectedIndex = this.dataSource.filteredData.findIndex((data) => + this.areDocumentedTypesTheSame(this.selectedType, data) ); if (selectedIndex > -1) {