mirror of https://github.com/apache/nifi.git
[NIFI-13034] Change Component Version (#8653)
* [NIFI-13034] - Change Processor version * Change controller service version * Change version of reporting task and flow analysis rule * add missing license header * fix for updating parameter context when in clustered mode. * review feedback - collapse 2 actions for opening change component version into 1 * update DocumentedType comparison logic This closes #8653
This commit is contained in:
parent
5eccc4c7e7
commit
20ec8064c9
|
@ -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<any, any, any, any>) => {
|
||||
return this.canvasUtils.canChangeProcessorVersion(selection);
|
||||
},
|
||||
clazz: 'fa fa-exchange',
|
||||
text: 'Change version',
|
||||
action: () => {
|
||||
// TODO - changeVersion
|
||||
action: (selection: d3.Selection<any, any, any, any>) => {
|
||||
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
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
|
@ -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<any, any, any, any>): 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<any, any, any, any>): boolean {
|
||||
// ensure the correct number of components are selected
|
||||
if (selection.size() !== 1) {
|
||||
|
|
|
@ -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 }>()
|
||||
);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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 }>()
|
||||
);
|
||||
|
|
|
@ -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 }
|
||||
);
|
||||
}
|
||||
|
|
|
@ -53,6 +53,7 @@
|
|||
(enableControllerService)="enableControllerService($event)"
|
||||
(disableControllerService)="disableControllerService($event)"
|
||||
(viewStateControllerService)="viewStateControllerService($event)"
|
||||
(changeControllerServiceVersion)="changeControllerServiceVersion($event)"
|
||||
(deleteControllerService)="deleteControllerService($event)"></controller-service-table>
|
||||
</div>
|
||||
}
|
||||
|
|
|
@ -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({
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 }>()
|
||||
);
|
||||
|
|
|
@ -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 }
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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 }>()
|
||||
);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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 }>()
|
||||
);
|
||||
|
|
|
@ -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 }
|
||||
);
|
||||
}
|
||||
|
|
|
@ -142,7 +142,10 @@
|
|||
title="Enable"></div>
|
||||
}
|
||||
@if (canChangeVersion(item)) {
|
||||
<div class="pointer fa fa-exchange primary-color" title="Change Version"></div>
|
||||
<div
|
||||
class="pointer fa fa-exchange primary-color"
|
||||
(click)="changeVersionClicked(item)"
|
||||
title="Change Version"></div>
|
||||
}
|
||||
@if (canDelete(item)) {
|
||||
<div
|
||||
|
|
|
@ -66,6 +66,8 @@ export class FlowAnalysisRuleTable {
|
|||
new EventEmitter<FlowAnalysisRuleEntity>();
|
||||
@Output() disableFlowAnalysisRule: EventEmitter<FlowAnalysisRuleEntity> =
|
||||
new EventEmitter<FlowAnalysisRuleEntity>();
|
||||
@Output() changeFlowAnalysisRuleVersion: EventEmitter<FlowAnalysisRuleEntity> =
|
||||
new EventEmitter<FlowAnalysisRuleEntity>();
|
||||
|
||||
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);
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
(enableFlowAnalysisRule)="enableFlowAnalysisRule($event)"
|
||||
(disableFlowAnalysisRule)="disableFlowAnalysisRule($event)"
|
||||
(viewStateFlowAnalysisRule)="viewStateFlowAnalysisRule($event)"
|
||||
(changeFlowAnalysisRuleVersion)="changeFlowAnalysisRuleVersion($event)"
|
||||
(deleteFlowAnalysisRule)="deleteFlowAnalysisRule($event)"></flow-analysis-rule-table>
|
||||
</div>
|
||||
<div class="flex justify-between">
|
||||
|
|
|
@ -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({
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
(enableControllerService)="enableControllerService($event)"
|
||||
(disableControllerService)="disableControllerService($event)"
|
||||
(viewStateControllerService)="viewStateControllerService($event)"
|
||||
(changeControllerServiceVersion)="changeControllerServiceVersion($event)"
|
||||
(deleteControllerService)="deleteControllerService($event)"></controller-service-table>
|
||||
</div>
|
||||
<div class="flex justify-between">
|
||||
|
|
|
@ -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({
|
||||
|
|
|
@ -143,7 +143,10 @@
|
|||
title="Start"></div>
|
||||
}
|
||||
@if (canChangeVersion(item)) {
|
||||
<div class="pointer fa fa-exchange primary-color" title="Change Version"></div>
|
||||
<div
|
||||
class="pointer fa fa-exchange primary-color"
|
||||
(click)="changeVersionClicked(item)"
|
||||
title="Change Version"></div>
|
||||
}
|
||||
@if (canDelete(item)) {
|
||||
<div
|
||||
|
|
|
@ -57,6 +57,7 @@ export class ReportingTaskTable {
|
|||
@Output() openAdvancedUi: EventEmitter<ReportingTaskEntity> = new EventEmitter<ReportingTaskEntity>();
|
||||
@Output() viewStateReportingTask: EventEmitter<ReportingTaskEntity> = new EventEmitter<ReportingTaskEntity>();
|
||||
@Output() stopReportingTask: EventEmitter<ReportingTaskEntity> = new EventEmitter<ReportingTaskEntity>();
|
||||
@Output() changeReportingTaskVersion: EventEmitter<ReportingTaskEntity> = new EventEmitter<ReportingTaskEntity>();
|
||||
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
(viewReportingTaskDocumentation)="viewReportingTaskDocumentation($event)"
|
||||
(deleteReportingTask)="deleteReportingTask($event)"
|
||||
(stopReportingTask)="stopReportingTask($event)"
|
||||
(changeReportingTaskVersion)="changeReportingTaskVersion($event)"
|
||||
(startReportingTask)="startReportingTask($event)"></reporting-task-table>
|
||||
</div>
|
||||
<div class="flex justify-between">
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -30,10 +30,28 @@ export class ExtensionTypesService {
|
|||
return this.httpClient.get(`${ExtensionTypesService.API}/flow/processor-types`);
|
||||
}
|
||||
|
||||
getProcessorVersionsForType(processorType: string, bundle: Bundle): Observable<any> {
|
||||
const params = {
|
||||
bundleGroupFilter: bundle.group,
|
||||
bundleArtifactFilter: bundle.artifact,
|
||||
type: processorType
|
||||
};
|
||||
return this.httpClient.get(`${ExtensionTypesService.API}/flow/processor-types`, { params });
|
||||
}
|
||||
|
||||
getControllerServiceTypes(): Observable<any> {
|
||||
return this.httpClient.get(`${ExtensionTypesService.API}/flow/controller-service-types`);
|
||||
}
|
||||
|
||||
getControllerServiceVersionsForType(serviceType: string, bundle: Bundle): Observable<any> {
|
||||
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<any> {
|
||||
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<any> {
|
||||
const params = {
|
||||
serviceBundleGroup: bundle.group,
|
||||
serviceBundleArtifact: bundle.artifact,
|
||||
type: reportingTaskType
|
||||
};
|
||||
return this.httpClient.get(`${ExtensionTypesService.API}/flow/reporting-task-types`, { params });
|
||||
}
|
||||
|
||||
getRegistryClientTypes(): Observable<any> {
|
||||
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<any> {
|
||||
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<any> {
|
||||
return this.httpClient.get(`${ExtensionTypesService.API}/flow/parameter-provider-types`);
|
||||
}
|
||||
|
|
|
@ -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[];
|
||||
}
|
||||
|
|
|
@ -0,0 +1,84 @@
|
|||
<!--
|
||||
~ 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.
|
||||
-->
|
||||
|
||||
<h2 mat-dialog-title>Change Version</h2>
|
||||
<div class="change-version">
|
||||
<form [formGroup]="changeComponentVersionForm">
|
||||
<mat-dialog-content>
|
||||
<div class="flex flex-col gap-y-4 w-full">
|
||||
<div>
|
||||
<div>Name</div>
|
||||
<div class="accent-color font-medium">
|
||||
{{ getName(selected) }}
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div>Bundle</div>
|
||||
<div class="accent-color font-medium">
|
||||
{{ selected?.bundle?.group }} - {{ selected?.bundle?.artifact }}
|
||||
</div>
|
||||
</div>
|
||||
<mat-form-field subscriptSizing="dynamic">
|
||||
<mat-label>Version</mat-label>
|
||||
<mat-select [(value)]="selected" tabindex="0">
|
||||
@for (version of versions; track version) {
|
||||
<mat-option [value]="version" [disabled]="isCurrent(version)">
|
||||
{{ version.bundle.version }}
|
||||
</mat-option>
|
||||
}
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
@if (selected?.controllerServiceApis) {
|
||||
<div>
|
||||
<div>Supports Controller Services</div>
|
||||
<div class="accent-color font-medium">
|
||||
<ul>
|
||||
@for (serviceApi of selected?.controllerServiceApis; track serviceApi) {
|
||||
<li>
|
||||
<controller-service-api
|
||||
[type]="serviceApi.type"
|
||||
[bundle]="serviceApi.bundle"></controller-service-api>
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
<div>
|
||||
<div>Restriction</div>
|
||||
@if (selected?.usageRestriction) {
|
||||
<div class="accent-color font-medium">
|
||||
{{ selected?.usageRestriction }}
|
||||
</div>
|
||||
} @else {
|
||||
<div class="unset nifi-surface-default">Not Restricted</div>
|
||||
}
|
||||
</div>
|
||||
<div>
|
||||
<div>Description</div>
|
||||
<div class="accent-color font-medium">{{ selected?.description }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</mat-dialog-content>
|
||||
<mat-dialog-actions align="end">
|
||||
<button mat-button mat-dialog-close>Cancel</button>
|
||||
<button type="button" color="primary" mat-button (click)="apply()" [disabled]="isCurrent(selected)">
|
||||
Apply
|
||||
</button>
|
||||
</mat-dialog-actions>
|
||||
</form>
|
||||
</div>
|
|
@ -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.
|
||||
*/
|
|
@ -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<ChangeComponentVersionDialog>;
|
||||
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();
|
||||
});
|
||||
});
|
|
@ -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<DocumentedType> = new EventEmitter<DocumentedType>();
|
||||
|
||||
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;
|
||||
}
|
|
@ -150,7 +150,10 @@
|
|||
title="Enable"></div>
|
||||
}
|
||||
@if (canChangeVersion(item)) {
|
||||
<div class="pointer fa fa-exchange primary-color" title="Change Version"></div>
|
||||
<div
|
||||
class="pointer fa fa-exchange primary-color"
|
||||
(click)="changeVersionClicked(item)"
|
||||
title="Change Version"></div>
|
||||
}
|
||||
@if (canDelete(item)) {
|
||||
<div
|
||||
|
|
|
@ -85,6 +85,8 @@ export class ControllerServiceTable {
|
|||
new EventEmitter<ControllerServiceEntity>();
|
||||
@Output() viewStateControllerService: EventEmitter<ControllerServiceEntity> =
|
||||
new EventEmitter<ControllerServiceEntity>();
|
||||
@Output() changeControllerServiceVersion: EventEmitter<ControllerServiceEntity> =
|
||||
new EventEmitter<ControllerServiceEntity>();
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue