mirror of https://github.com/apache/nifi.git
NIFI-12502: Handle additional Property Table capabilities (#8159)
* NIFI-12502: - Go To Service. - Save before navigating if form dirty. - Go To Parameter. - Convert To Parameter. * NIFI-12502: - Ensuring tests are still bootstrapped correctly. * NIFI-12502: - Addressing review feedback. This closes #8159
This commit is contained in:
parent
80700cc6c6
commit
49bbc38b6b
|
@ -27,6 +27,7 @@ import { VersionControlTip } from '../ui/common/tooltips/version-control-tip/ver
|
|||
import { canvasFeatureKey, reducers } from '../state';
|
||||
import { MatDialogModule } from '@angular/material/dialog';
|
||||
import { ControllerServicesEffects } from '../state/controller-services/controller-services.effects';
|
||||
import { ParameterEffects } from '../state/parameter/parameter.effects';
|
||||
|
||||
@NgModule({
|
||||
declarations: [FlowDesigner, VersionControlTip],
|
||||
|
@ -35,7 +36,7 @@ import { ControllerServicesEffects } from '../state/controller-services/controll
|
|||
CommonModule,
|
||||
FlowDesignerRoutingModule,
|
||||
StoreModule.forFeature(canvasFeatureKey, reducers),
|
||||
EffectsModule.forFeature(FlowEffects, TransformEffects, ControllerServicesEffects),
|
||||
EffectsModule.forFeature(FlowEffects, TransformEffects, ControllerServicesEffects, ParameterEffects),
|
||||
NgOptimizedImage,
|
||||
MatDialogModule
|
||||
]
|
||||
|
|
|
@ -29,6 +29,8 @@ import { controllerServicesFeatureKey } from '../../state/controller-services';
|
|||
import * as fromControllerServices from '../../state/controller-services/controller-services.reducer';
|
||||
import { selectUser } from '../../../../state/user/user.selectors';
|
||||
import * as fromUser from '../../../../state/user/user.reducer';
|
||||
import { parameterFeatureKey } from '../../state/parameter';
|
||||
import * as fromParameter from '../../state/parameter/parameter.reducer';
|
||||
|
||||
describe('ConnectableBehavior', () => {
|
||||
let service: ConnectableBehavior;
|
||||
|
@ -37,7 +39,8 @@ describe('ConnectableBehavior', () => {
|
|||
const initialState: CanvasState = {
|
||||
[flowFeatureKey]: fromFlow.initialState,
|
||||
[transformFeatureKey]: fromTransform.initialState,
|
||||
[controllerServicesFeatureKey]: fromControllerServices.initialState
|
||||
[controllerServicesFeatureKey]: fromControllerServices.initialState,
|
||||
[parameterFeatureKey]: fromParameter.initialState
|
||||
};
|
||||
|
||||
TestBed.configureTestingModule({
|
||||
|
|
|
@ -30,6 +30,8 @@ import { controllerServicesFeatureKey } from '../../state/controller-services';
|
|||
import * as fromControllerServices from '../../state/controller-services/controller-services.reducer';
|
||||
import { selectUser } from '../../../../state/user/user.selectors';
|
||||
import * as fromUser from '../../../../state/user/user.reducer';
|
||||
import { parameterFeatureKey } from '../../state/parameter';
|
||||
import * as fromParameter from '../../state/parameter/parameter.reducer';
|
||||
|
||||
describe('DraggableBehavior', () => {
|
||||
let service: DraggableBehavior;
|
||||
|
@ -38,7 +40,8 @@ describe('DraggableBehavior', () => {
|
|||
const initialState: CanvasState = {
|
||||
[flowFeatureKey]: fromFlow.initialState,
|
||||
[transformFeatureKey]: fromTransform.initialState,
|
||||
[controllerServicesFeatureKey]: fromControllerServices.initialState
|
||||
[controllerServicesFeatureKey]: fromControllerServices.initialState,
|
||||
[parameterFeatureKey]: fromParameter.initialState
|
||||
};
|
||||
|
||||
TestBed.configureTestingModule({
|
||||
|
|
|
@ -30,6 +30,8 @@ import { controllerServicesFeatureKey } from '../../state/controller-services';
|
|||
import * as fromControllerServices from '../../state/controller-services/controller-services.reducer';
|
||||
import { selectUser } from '../../../../state/user/user.selectors';
|
||||
import * as fromUser from '../../../../state/user/user.reducer';
|
||||
import { parameterFeatureKey } from '../../state/parameter';
|
||||
import * as fromParameter from '../../state/parameter/parameter.reducer';
|
||||
|
||||
describe('EditableBehaviorService', () => {
|
||||
let service: EditableBehavior;
|
||||
|
@ -37,7 +39,8 @@ describe('EditableBehaviorService', () => {
|
|||
const initialState: CanvasState = {
|
||||
[flowFeatureKey]: fromFlow.initialState,
|
||||
[transformFeatureKey]: fromTransform.initialState,
|
||||
[controllerServicesFeatureKey]: fromControllerServices.initialState
|
||||
[controllerServicesFeatureKey]: fromControllerServices.initialState,
|
||||
[parameterFeatureKey]: fromParameter.initialState
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
|
|
|
@ -29,6 +29,8 @@ import { controllerServicesFeatureKey } from '../../state/controller-services';
|
|||
import * as fromControllerServices from '../../state/controller-services/controller-services.reducer';
|
||||
import { selectUser } from '../../../../state/user/user.selectors';
|
||||
import * as fromUser from '../../../../state/user/user.reducer';
|
||||
import { parameterFeatureKey } from '../../state/parameter';
|
||||
import * as fromParameter from '../../state/parameter/parameter.reducer';
|
||||
|
||||
describe('QuickSelectBehavior', () => {
|
||||
let service: QuickSelectBehavior;
|
||||
|
@ -37,7 +39,8 @@ describe('QuickSelectBehavior', () => {
|
|||
const initialState: CanvasState = {
|
||||
[flowFeatureKey]: fromFlow.initialState,
|
||||
[transformFeatureKey]: fromTransform.initialState,
|
||||
[controllerServicesFeatureKey]: fromControllerServices.initialState
|
||||
[controllerServicesFeatureKey]: fromControllerServices.initialState,
|
||||
[parameterFeatureKey]: fromParameter.initialState
|
||||
};
|
||||
|
||||
TestBed.configureTestingModule({
|
||||
|
|
|
@ -28,6 +28,8 @@ import { controllerServicesFeatureKey } from '../../state/controller-services';
|
|||
import * as fromControllerServices from '../../state/controller-services/controller-services.reducer';
|
||||
import { selectUser } from '../../../../state/user/user.selectors';
|
||||
import * as fromUser from '../../../../state/user/user.reducer';
|
||||
import { parameterFeatureKey } from '../../state/parameter';
|
||||
import * as fromParameter from '../../state/parameter/parameter.reducer';
|
||||
|
||||
describe('SelectableBehavior', () => {
|
||||
let service: SelectableBehavior;
|
||||
|
@ -36,7 +38,8 @@ describe('SelectableBehavior', () => {
|
|||
const initialState: CanvasState = {
|
||||
[flowFeatureKey]: fromFlow.initialState,
|
||||
[transformFeatureKey]: fromTransform.initialState,
|
||||
[controllerServicesFeatureKey]: fromControllerServices.initialState
|
||||
[controllerServicesFeatureKey]: fromControllerServices.initialState,
|
||||
[parameterFeatureKey]: fromParameter.initialState
|
||||
};
|
||||
|
||||
TestBed.configureTestingModule({
|
||||
|
|
|
@ -30,6 +30,8 @@ import { controllerServicesFeatureKey } from '../state/controller-services';
|
|||
import * as fromControllerServices from '../state/controller-services/controller-services.reducer';
|
||||
import { selectUser } from '../../../state/user/user.selectors';
|
||||
import * as fromUser from '../../../state/user/user.reducer';
|
||||
import { parameterFeatureKey } from '../state/parameter';
|
||||
import * as fromParameter from '../state/parameter/parameter.reducer';
|
||||
|
||||
describe('BirdseyeView', () => {
|
||||
let service: BirdseyeView;
|
||||
|
@ -38,7 +40,8 @@ describe('BirdseyeView', () => {
|
|||
const initialState: CanvasState = {
|
||||
[flowFeatureKey]: fromFlow.initialState,
|
||||
[transformFeatureKey]: fromTransform.initialState,
|
||||
[controllerServicesFeatureKey]: fromControllerServices.initialState
|
||||
[controllerServicesFeatureKey]: fromControllerServices.initialState,
|
||||
[parameterFeatureKey]: fromParameter.initialState
|
||||
};
|
||||
|
||||
TestBed.configureTestingModule({
|
||||
|
|
|
@ -29,6 +29,8 @@ import { controllerServicesFeatureKey } from '../state/controller-services';
|
|||
import * as fromControllerServices from '../state/controller-services/controller-services.reducer';
|
||||
import { selectUser } from '../../../state/user/user.selectors';
|
||||
import * as fromUser from '../../../state/user/user.reducer';
|
||||
import { parameterFeatureKey } from '../state/parameter';
|
||||
import * as fromParameter from '../state/parameter/parameter.reducer';
|
||||
|
||||
describe('CanvasUtils', () => {
|
||||
let service: CanvasUtils;
|
||||
|
@ -37,7 +39,8 @@ describe('CanvasUtils', () => {
|
|||
const initialState: CanvasState = {
|
||||
[flowFeatureKey]: fromFlow.initialState,
|
||||
[transformFeatureKey]: fromTransform.initialState,
|
||||
[controllerServicesFeatureKey]: fromControllerServices.initialState
|
||||
[controllerServicesFeatureKey]: fromControllerServices.initialState,
|
||||
[parameterFeatureKey]: fromParameter.initialState
|
||||
};
|
||||
|
||||
TestBed.configureTestingModule({
|
||||
|
|
|
@ -30,6 +30,8 @@ import { controllerServicesFeatureKey } from '../state/controller-services';
|
|||
import * as fromControllerServices from '../state/controller-services/controller-services.reducer';
|
||||
import { selectUser } from '../../../state/user/user.selectors';
|
||||
import * as fromUser from '../../../state/user/user.reducer';
|
||||
import { parameterFeatureKey } from '../state/parameter';
|
||||
import * as fromParameter from '../state/parameter/parameter.reducer';
|
||||
|
||||
describe('CanvasView', () => {
|
||||
let service: CanvasView;
|
||||
|
@ -38,7 +40,8 @@ describe('CanvasView', () => {
|
|||
const initialState: CanvasState = {
|
||||
[flowFeatureKey]: fromFlow.initialState,
|
||||
[transformFeatureKey]: fromTransform.initialState,
|
||||
[controllerServicesFeatureKey]: fromControllerServices.initialState
|
||||
[controllerServicesFeatureKey]: fromControllerServices.initialState,
|
||||
[parameterFeatureKey]: fromParameter.initialState
|
||||
};
|
||||
|
||||
TestBed.configureTestingModule({
|
||||
|
|
|
@ -64,10 +64,6 @@ export class FlowService {
|
|||
return this.httpClient.get(`${FlowService.API}/flow/process-groups/${processGroupId}`);
|
||||
}
|
||||
|
||||
getControllerService(id: string): Observable<any> {
|
||||
return this.httpClient.get(`${FlowService.API}/controller-services/${id}`);
|
||||
}
|
||||
|
||||
getProcessGroupStatus(processGroupId: string = 'root', recursive: boolean = false): Observable<any> {
|
||||
return this.httpClient.get(`${FlowService.API}/flow/process-groups/${processGroupId}/status`, {
|
||||
params: { recursive: recursive }
|
||||
|
|
|
@ -30,6 +30,8 @@ import { controllerServicesFeatureKey } from '../../state/controller-services';
|
|||
import * as fromControllerServices from '../../state/controller-services/controller-services.reducer';
|
||||
import { selectUser } from '../../../../state/user/user.selectors';
|
||||
import * as fromUser from '../../../../state/user/user.reducer';
|
||||
import { parameterFeatureKey } from '../../state/parameter';
|
||||
import * as fromParameter from '../../state/parameter/parameter.reducer';
|
||||
|
||||
describe('ConnectionManager', () => {
|
||||
let service: ConnectionManager;
|
||||
|
@ -38,7 +40,8 @@ describe('ConnectionManager', () => {
|
|||
const initialState: CanvasState = {
|
||||
[flowFeatureKey]: fromFlow.initialState,
|
||||
[transformFeatureKey]: fromTransform.initialState,
|
||||
[controllerServicesFeatureKey]: fromControllerServices.initialState
|
||||
[controllerServicesFeatureKey]: fromControllerServices.initialState,
|
||||
[parameterFeatureKey]: fromParameter.initialState
|
||||
};
|
||||
|
||||
TestBed.configureTestingModule({
|
||||
|
|
|
@ -30,6 +30,8 @@ import { controllerServicesFeatureKey } from '../../state/controller-services';
|
|||
import * as fromControllerServices from '../../state/controller-services/controller-services.reducer';
|
||||
import { selectUser } from '../../../../state/user/user.selectors';
|
||||
import * as fromUser from '../../../../state/user/user.reducer';
|
||||
import { parameterFeatureKey } from '../../state/parameter';
|
||||
import * as fromParameter from '../../state/parameter/parameter.reducer';
|
||||
|
||||
describe('FunnelManager', () => {
|
||||
let service: FunnelManager;
|
||||
|
@ -38,7 +40,8 @@ describe('FunnelManager', () => {
|
|||
const initialState: CanvasState = {
|
||||
[flowFeatureKey]: fromFlow.initialState,
|
||||
[transformFeatureKey]: fromTransform.initialState,
|
||||
[controllerServicesFeatureKey]: fromControllerServices.initialState
|
||||
[controllerServicesFeatureKey]: fromControllerServices.initialState,
|
||||
[parameterFeatureKey]: fromParameter.initialState
|
||||
};
|
||||
|
||||
TestBed.configureTestingModule({
|
||||
|
|
|
@ -30,6 +30,8 @@ import { controllerServicesFeatureKey } from '../../state/controller-services';
|
|||
import * as fromControllerServices from '../../state/controller-services/controller-services.reducer';
|
||||
import { selectUser } from '../../../../state/user/user.selectors';
|
||||
import * as fromUser from '../../../../state/user/user.reducer';
|
||||
import { parameterFeatureKey } from '../../state/parameter';
|
||||
import * as fromParameter from '../../state/parameter/parameter.reducer';
|
||||
|
||||
describe('LabelManager', () => {
|
||||
let service: LabelManager;
|
||||
|
@ -38,7 +40,8 @@ describe('LabelManager', () => {
|
|||
const initialState: CanvasState = {
|
||||
[flowFeatureKey]: fromFlow.initialState,
|
||||
[transformFeatureKey]: fromTransform.initialState,
|
||||
[controllerServicesFeatureKey]: fromControllerServices.initialState
|
||||
[controllerServicesFeatureKey]: fromControllerServices.initialState,
|
||||
[parameterFeatureKey]: fromParameter.initialState
|
||||
};
|
||||
|
||||
TestBed.configureTestingModule({
|
||||
|
|
|
@ -30,6 +30,8 @@ import { controllerServicesFeatureKey } from '../../state/controller-services';
|
|||
import * as fromControllerServices from '../../state/controller-services/controller-services.reducer';
|
||||
import { selectUser } from '../../../../state/user/user.selectors';
|
||||
import * as fromUser from '../../../../state/user/user.reducer';
|
||||
import { parameterFeatureKey } from '../../state/parameter';
|
||||
import * as fromParameter from '../../state/parameter/parameter.reducer';
|
||||
|
||||
describe('PortManager', () => {
|
||||
let service: PortManager;
|
||||
|
@ -38,7 +40,8 @@ describe('PortManager', () => {
|
|||
const initialState: CanvasState = {
|
||||
[flowFeatureKey]: fromFlow.initialState,
|
||||
[transformFeatureKey]: fromTransform.initialState,
|
||||
[controllerServicesFeatureKey]: fromControllerServices.initialState
|
||||
[controllerServicesFeatureKey]: fromControllerServices.initialState,
|
||||
[parameterFeatureKey]: fromParameter.initialState
|
||||
};
|
||||
|
||||
TestBed.configureTestingModule({
|
||||
|
|
|
@ -30,6 +30,8 @@ import { controllerServicesFeatureKey } from '../../state/controller-services';
|
|||
import * as fromControllerServices from '../../state/controller-services/controller-services.reducer';
|
||||
import { selectUser } from '../../../../state/user/user.selectors';
|
||||
import * as fromUser from '../../../../state/user/user.reducer';
|
||||
import { parameterFeatureKey } from '../../state/parameter';
|
||||
import * as fromParameter from '../../state/parameter/parameter.reducer';
|
||||
|
||||
describe('ProcessGroupManager', () => {
|
||||
let service: ProcessGroupManager;
|
||||
|
@ -38,7 +40,8 @@ describe('ProcessGroupManager', () => {
|
|||
const initialState: CanvasState = {
|
||||
[flowFeatureKey]: fromFlow.initialState,
|
||||
[transformFeatureKey]: fromTransform.initialState,
|
||||
[controllerServicesFeatureKey]: fromControllerServices.initialState
|
||||
[controllerServicesFeatureKey]: fromControllerServices.initialState,
|
||||
[parameterFeatureKey]: fromParameter.initialState
|
||||
};
|
||||
|
||||
TestBed.configureTestingModule({
|
||||
|
|
|
@ -30,6 +30,8 @@ import { controllerServicesFeatureKey } from '../../state/controller-services';
|
|||
import * as fromControllerServices from '../../state/controller-services/controller-services.reducer';
|
||||
import { selectUser } from '../../../../state/user/user.selectors';
|
||||
import * as fromUser from '../../../../state/user/user.reducer';
|
||||
import { parameterFeatureKey } from '../../state/parameter';
|
||||
import * as fromParameter from '../../state/parameter/parameter.reducer';
|
||||
|
||||
describe('ProcessorManager', () => {
|
||||
let service: ProcessorManager;
|
||||
|
@ -38,7 +40,8 @@ describe('ProcessorManager', () => {
|
|||
const initialState: CanvasState = {
|
||||
[flowFeatureKey]: fromFlow.initialState,
|
||||
[transformFeatureKey]: fromTransform.initialState,
|
||||
[controllerServicesFeatureKey]: fromControllerServices.initialState
|
||||
[controllerServicesFeatureKey]: fromControllerServices.initialState,
|
||||
[parameterFeatureKey]: fromParameter.initialState
|
||||
};
|
||||
|
||||
TestBed.configureTestingModule({
|
||||
|
|
|
@ -30,6 +30,8 @@ import { controllerServicesFeatureKey } from '../../state/controller-services';
|
|||
import * as fromControllerServices from '../../state/controller-services/controller-services.reducer';
|
||||
import { selectUser } from '../../../../state/user/user.selectors';
|
||||
import * as fromUser from '../../../../state/user/user.reducer';
|
||||
import { parameterFeatureKey } from '../../state/parameter';
|
||||
import * as fromParameter from '../../state/parameter/parameter.reducer';
|
||||
|
||||
describe('RemoteProcessGroupManager', () => {
|
||||
let service: RemoteProcessGroupManager;
|
||||
|
@ -38,7 +40,8 @@ describe('RemoteProcessGroupManager', () => {
|
|||
const initialState: CanvasState = {
|
||||
[flowFeatureKey]: fromFlow.initialState,
|
||||
[transformFeatureKey]: fromTransform.initialState,
|
||||
[controllerServicesFeatureKey]: fromControllerServices.initialState
|
||||
[controllerServicesFeatureKey]: fromControllerServices.initialState,
|
||||
[parameterFeatureKey]: fromParameter.initialState
|
||||
};
|
||||
|
||||
TestBed.configureTestingModule({
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* 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 { Injectable } from '@angular/core';
|
||||
import { Observable, throwError } from 'rxjs';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { NiFiCommon } from '../../../service/nifi-common.service';
|
||||
import { ParameterContextUpdateRequest, SubmitParameterContextUpdate } from '../../../state/shared';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class ParameterService {
|
||||
private static readonly API: string = '../nifi-api';
|
||||
|
||||
constructor(
|
||||
private httpClient: HttpClient,
|
||||
private nifiCommon: NiFiCommon
|
||||
) {}
|
||||
|
||||
/**
|
||||
* The NiFi model contain the url for each component. That URL is an absolute URL. Angular CSRF handling
|
||||
* does not work on absolute URLs, so we need to strip off the proto for the request header to be added.
|
||||
*
|
||||
* https://stackoverflow.com/a/59586462
|
||||
*
|
||||
* @param url
|
||||
* @private
|
||||
*/
|
||||
private stripProtocol(url: string): string {
|
||||
return this.nifiCommon.substringAfterFirst(url, ':');
|
||||
}
|
||||
|
||||
getParameterContext(id: string, includeInheritedParameters: boolean): Observable<any> {
|
||||
return this.httpClient.get(`${ParameterService.API}/parameter-contexts/${id}`, {
|
||||
params: {
|
||||
includeInheritedParameters
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
submitParameterContextUpdate(configureParameterContext: SubmitParameterContextUpdate): Observable<any> {
|
||||
return this.httpClient.post(
|
||||
`${ParameterService.API}/parameter-contexts/${configureParameterContext.id}/update-requests`,
|
||||
configureParameterContext.payload
|
||||
);
|
||||
}
|
||||
|
||||
pollParameterContextUpdate(updateRequest: ParameterContextUpdateRequest): Observable<any> {
|
||||
return this.httpClient.get(this.stripProtocol(updateRequest.uri));
|
||||
}
|
||||
|
||||
deleteParameterContextUpdate(updateRequest: ParameterContextUpdateRequest): Observable<any> {
|
||||
return this.httpClient.delete(this.stripProtocol(updateRequest.uri));
|
||||
}
|
||||
}
|
|
@ -21,6 +21,7 @@ import * as ControllerServicesActions from './controller-services.actions';
|
|||
import {
|
||||
catchError,
|
||||
combineLatest,
|
||||
filter,
|
||||
from,
|
||||
map,
|
||||
NEVER,
|
||||
|
@ -28,6 +29,7 @@ import {
|
|||
of,
|
||||
switchMap,
|
||||
take,
|
||||
takeUntil,
|
||||
tap,
|
||||
withLatestFrom
|
||||
} from 'rxjs';
|
||||
|
@ -40,18 +42,29 @@ import { Client } from '../../../../service/client.service';
|
|||
import { YesNoDialog } from '../../../../ui/common/yes-no-dialog/yes-no-dialog.component';
|
||||
import { EditControllerService } from '../../../../ui/common/controller-service/edit-controller-service/edit-controller-service.component';
|
||||
import {
|
||||
EditParameterRequest,
|
||||
EditParameterResponse,
|
||||
InlineServiceCreationRequest,
|
||||
InlineServiceCreationResponse,
|
||||
NewPropertyDialogRequest,
|
||||
NewPropertyDialogResponse,
|
||||
Parameter,
|
||||
ParameterEntity,
|
||||
Property,
|
||||
PropertyDescriptor
|
||||
PropertyDescriptor,
|
||||
UpdateControllerServiceRequest
|
||||
} from '../../../../state/shared';
|
||||
import { NewPropertyDialog } from '../../../../ui/common/new-property-dialog/new-property-dialog.component';
|
||||
import { Router } from '@angular/router';
|
||||
import { ExtensionTypesService } from '../../../../service/extension-types.service';
|
||||
import { selectCurrentProcessGroupId, selectSaving } from './controller-services.selectors';
|
||||
import { ControllerServiceService } from '../../service/controller-service.service';
|
||||
import { selectCurrentParameterContext } from '../flow/flow.selectors';
|
||||
import { FlowService } from '../../service/flow.service';
|
||||
import { EditParameterDialog } from '../../../../ui/common/edit-parameter-dialog/edit-parameter-dialog.component';
|
||||
import { selectParameterSaving } from '../parameter/parameter.selectors';
|
||||
import * as ParameterActions from '../parameter/parameter.actions';
|
||||
import { ParameterService } from '../../service/parameter.service';
|
||||
|
||||
@Injectable()
|
||||
export class ControllerServicesEffects {
|
||||
|
@ -60,6 +73,8 @@ export class ControllerServicesEffects {
|
|||
private store: Store<NiFiState>,
|
||||
private client: Client,
|
||||
private controllerServiceService: ControllerServiceService,
|
||||
private flowService: FlowService,
|
||||
private parameterService: ParameterService,
|
||||
private extensionTypesService: ExtensionTypesService,
|
||||
private dialog: MatDialog,
|
||||
private router: Router
|
||||
|
@ -190,14 +205,18 @@ export class ControllerServicesEffects {
|
|||
this.actions$.pipe(
|
||||
ofType(ControllerServicesActions.openConfigureControllerServiceDialog),
|
||||
map((action) => action.request),
|
||||
withLatestFrom(this.store.select(selectCurrentProcessGroupId)),
|
||||
tap(([request, processGroupId]) => {
|
||||
withLatestFrom(
|
||||
this.store.select(selectCurrentParameterContext),
|
||||
this.store.select(selectCurrentProcessGroupId)
|
||||
),
|
||||
tap(([request, parameterContext, processGroupId]) => {
|
||||
const serviceId: string = request.id;
|
||||
|
||||
const editDialogReference = this.dialog.open(EditControllerService, {
|
||||
data: {
|
||||
controllerService: request.controllerService
|
||||
},
|
||||
id: serviceId,
|
||||
panelClass: 'large-dialog'
|
||||
});
|
||||
|
||||
|
@ -234,18 +253,134 @@ export class ControllerServicesEffects {
|
|||
);
|
||||
};
|
||||
|
||||
editDialogReference.componentInstance.getServiceLink = (serviceId: string) => {
|
||||
return this.controllerServiceService.getControllerService(serviceId).pipe(
|
||||
take(1),
|
||||
map((serviceEntity) => {
|
||||
return [
|
||||
const goTo = (commands: string[], destination: string): void => {
|
||||
if (editDialogReference.componentInstance.editControllerServiceForm.dirty) {
|
||||
const saveChangesDialogReference = this.dialog.open(YesNoDialog, {
|
||||
data: {
|
||||
title: 'Controller Service Configuration',
|
||||
message: `Save changes before going to this ${destination}?`
|
||||
},
|
||||
panelClass: 'small-dialog'
|
||||
});
|
||||
|
||||
saveChangesDialogReference.componentInstance.yes.pipe(take(1)).subscribe(() => {
|
||||
editDialogReference.componentInstance.submitForm(commands);
|
||||
});
|
||||
|
||||
saveChangesDialogReference.componentInstance.no.pipe(take(1)).subscribe(() => {
|
||||
editDialogReference.close('ROUTED');
|
||||
this.router.navigate(commands);
|
||||
});
|
||||
} else {
|
||||
editDialogReference.close('ROUTED');
|
||||
this.router.navigate(commands);
|
||||
}
|
||||
};
|
||||
|
||||
if (parameterContext != null) {
|
||||
editDialogReference.componentInstance.getParameters = (sensitive: boolean) => {
|
||||
return this.flowService.getParameterContext(parameterContext.id).pipe(
|
||||
take(1),
|
||||
map((response) => response.component.parameters),
|
||||
map((parameterEntities) => {
|
||||
return parameterEntities
|
||||
.map((parameterEntity: ParameterEntity) => parameterEntity.parameter)
|
||||
.filter((parameter: Parameter) => parameter.sensitive == sensitive);
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
editDialogReference.componentInstance.parameterContext = parameterContext;
|
||||
editDialogReference.componentInstance.goToParameter = (parameter: string) => {
|
||||
const commands: string[] = ['/parameter-contexts', parameterContext.id];
|
||||
goTo(commands, 'Parameter');
|
||||
};
|
||||
|
||||
editDialogReference.componentInstance.convertToParameter = (
|
||||
name: string,
|
||||
sensitive: boolean,
|
||||
value: string | null
|
||||
) => {
|
||||
return this.parameterService.getParameterContext(parameterContext.id, false).pipe(
|
||||
switchMap((parameterContextEntity) => {
|
||||
const existingParameters: string[] =
|
||||
parameterContextEntity.component.parameters.map(
|
||||
(parameterEntity: ParameterEntity) => parameterEntity.parameter.name
|
||||
);
|
||||
const convertToParameterDialogRequest: EditParameterRequest = {
|
||||
parameter: {
|
||||
name,
|
||||
value,
|
||||
sensitive,
|
||||
description: ''
|
||||
},
|
||||
existingParameters
|
||||
};
|
||||
const convertToParameterDialogReference = this.dialog.open(EditParameterDialog, {
|
||||
data: convertToParameterDialogRequest,
|
||||
panelClass: 'medium-dialog'
|
||||
});
|
||||
|
||||
convertToParameterDialogReference.componentInstance.saving$ =
|
||||
this.store.select(selectParameterSaving);
|
||||
|
||||
convertToParameterDialogReference.componentInstance.cancel.pipe(
|
||||
takeUntil(convertToParameterDialogReference.afterClosed()),
|
||||
tap(() => ParameterActions.stopPollingParameterContextUpdateRequest())
|
||||
);
|
||||
|
||||
return convertToParameterDialogReference.componentInstance.editParameter.pipe(
|
||||
takeUntil(convertToParameterDialogReference.afterClosed()),
|
||||
switchMap((dialogResponse: EditParameterResponse) => {
|
||||
this.store.dispatch(
|
||||
ParameterActions.submitParameterContextUpdateRequest({
|
||||
request: {
|
||||
id: parameterContext.id,
|
||||
payload: {
|
||||
revision: this.client.getRevision(parameterContextEntity),
|
||||
component: {
|
||||
id: parameterContextEntity.id,
|
||||
parameters: [{ parameter: dialogResponse.parameter }]
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
return this.store.select(selectParameterSaving).pipe(
|
||||
takeUntil(convertToParameterDialogReference.afterClosed()),
|
||||
filter((parameterSaving) => parameterSaving === false),
|
||||
map(() => {
|
||||
convertToParameterDialogReference.close();
|
||||
return `#{${dialogResponse.parameter.name}}`;
|
||||
})
|
||||
);
|
||||
})
|
||||
);
|
||||
}),
|
||||
catchError((error) => {
|
||||
// TODO handle error
|
||||
return NEVER;
|
||||
})
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
editDialogReference.componentInstance.goToService = (serviceId: string) => {
|
||||
this.controllerServiceService.getControllerService(serviceId).subscribe({
|
||||
next: (serviceEntity) => {
|
||||
const commands: string[] = [
|
||||
'/process-groups',
|
||||
serviceEntity.component.parentGroupId,
|
||||
'controller-services',
|
||||
serviceEntity.id
|
||||
];
|
||||
})
|
||||
);
|
||||
goTo(commands, 'Controller Service');
|
||||
},
|
||||
error: () => {
|
||||
// TODO - handle error
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
editDialogReference.componentInstance.createNewService = (
|
||||
|
@ -289,13 +424,13 @@ export class ControllerServicesEffects {
|
|||
})
|
||||
.pipe(
|
||||
take(1),
|
||||
switchMap((createReponse) => {
|
||||
switchMap((createResponse) => {
|
||||
// dispatch an inline create service success action so the new service is in the state
|
||||
this.store.dispatch(
|
||||
ControllerServicesActions.inlineCreateControllerServiceSuccess(
|
||||
{
|
||||
response: {
|
||||
controllerService: createReponse
|
||||
controllerService: createResponse
|
||||
}
|
||||
}
|
||||
)
|
||||
|
@ -310,7 +445,7 @@ export class ControllerServicesEffects {
|
|||
createServiceDialogReference.close();
|
||||
|
||||
return {
|
||||
value: createReponse.id,
|
||||
value: createResponse.id,
|
||||
descriptor:
|
||||
descriptorResponse.propertyDescriptor
|
||||
};
|
||||
|
@ -329,14 +464,15 @@ export class ControllerServicesEffects {
|
|||
};
|
||||
|
||||
editDialogReference.componentInstance.editControllerService
|
||||
.pipe(take(1))
|
||||
.subscribe((payload: any) => {
|
||||
.pipe(takeUntil(editDialogReference.afterClosed()))
|
||||
.subscribe((updateControllerServiceRequest: UpdateControllerServiceRequest) => {
|
||||
this.store.dispatch(
|
||||
ControllerServicesActions.configureControllerService({
|
||||
request: {
|
||||
id: request.controllerService.id,
|
||||
uri: request.controllerService.uri,
|
||||
payload
|
||||
payload: updateControllerServiceRequest.payload,
|
||||
postUpdateNavigation: updateControllerServiceRequest.postUpdateNavigation
|
||||
}
|
||||
})
|
||||
);
|
||||
|
@ -369,7 +505,8 @@ export class ControllerServicesEffects {
|
|||
ControllerServicesActions.configureControllerServiceSuccess({
|
||||
response: {
|
||||
id: request.id,
|
||||
controllerService: response
|
||||
controllerService: response,
|
||||
postUpdateNavigation: request.postUpdateNavigation
|
||||
}
|
||||
})
|
||||
),
|
||||
|
@ -389,8 +526,14 @@ export class ControllerServicesEffects {
|
|||
() =>
|
||||
this.actions$.pipe(
|
||||
ofType(ControllerServicesActions.configureControllerServiceSuccess),
|
||||
tap(() => {
|
||||
this.dialog.closeAll();
|
||||
map((action) => action.response),
|
||||
tap((response) => {
|
||||
if (response.postUpdateNavigation) {
|
||||
this.router.navigate(response.postUpdateNavigation);
|
||||
this.dialog.getDialogById(response.id)?.close('ROUTED');
|
||||
} else {
|
||||
this.dialog.closeAll();
|
||||
}
|
||||
})
|
||||
),
|
||||
{ dispatch: false }
|
||||
|
|
|
@ -46,11 +46,13 @@ export interface ConfigureControllerServiceRequest {
|
|||
id: string;
|
||||
uri: string;
|
||||
payload: any;
|
||||
postUpdateNavigation?: string[];
|
||||
}
|
||||
|
||||
export interface ConfigureControllerServiceSuccess {
|
||||
id: string;
|
||||
controllerService: ControllerServiceEntity;
|
||||
postUpdateNavigation?: string[];
|
||||
}
|
||||
|
||||
export interface DeleteControllerServiceRequest {
|
||||
|
|
|
@ -19,6 +19,7 @@ import { Injectable } from '@angular/core';
|
|||
import { FlowService } from '../../service/flow.service';
|
||||
import { Actions, createEffect, ofType } from '@ngrx/effects';
|
||||
import * as FlowActions from './flow.actions';
|
||||
import * as ParameterActions from '../parameter/parameter.actions';
|
||||
import {
|
||||
asyncScheduler,
|
||||
catchError,
|
||||
|
@ -46,7 +47,8 @@ import {
|
|||
Snippet,
|
||||
UpdateComponentFailure,
|
||||
UpdateComponentResponse,
|
||||
UpdateConnectionSuccess
|
||||
UpdateConnectionSuccess,
|
||||
UpdateProcessorRequest
|
||||
} from './index';
|
||||
import { Action, Store } from '@ngrx/store';
|
||||
import {
|
||||
|
@ -65,6 +67,8 @@ import { CreatePort } from '../../ui/canvas/items/port/create-port/create-port.c
|
|||
import { EditPort } from '../../ui/canvas/items/port/edit-port/edit-port.component';
|
||||
import {
|
||||
ComponentType,
|
||||
EditParameterRequest,
|
||||
EditParameterResponse,
|
||||
InlineServiceCreationRequest,
|
||||
InlineServiceCreationResponse,
|
||||
NewPropertyDialogRequest,
|
||||
|
@ -94,6 +98,10 @@ import { CreateControllerService } from '../../../../ui/common/controller-servic
|
|||
import * as ControllerServicesActions from '../controller-services/controller-services.actions';
|
||||
import { ExtensionTypesService } from '../../../../service/extension-types.service';
|
||||
import { ControllerServiceService } from '../../service/controller-service.service';
|
||||
import { YesNoDialog } from '../../../../ui/common/yes-no-dialog/yes-no-dialog.component';
|
||||
import { EditParameterDialog } from '../../../../ui/common/edit-parameter-dialog/edit-parameter-dialog.component';
|
||||
import { selectParameterSaving } from '../parameter/parameter.selectors';
|
||||
import { ParameterService } from '../../service/parameter.service';
|
||||
|
||||
@Injectable()
|
||||
export class FlowEffects {
|
||||
|
@ -103,6 +111,7 @@ export class FlowEffects {
|
|||
private flowService: FlowService,
|
||||
private extensionTypesService: ExtensionTypesService,
|
||||
private controllerServiceService: ControllerServiceService,
|
||||
private parameterService: ParameterService,
|
||||
private client: Client,
|
||||
private canvasUtils: CanvasUtils,
|
||||
private canvasView: CanvasView,
|
||||
|
@ -771,6 +780,7 @@ export class FlowEffects {
|
|||
|
||||
const editDialogReference = this.dialog.open(EditProcessor, {
|
||||
data: request,
|
||||
id: processorId,
|
||||
panelClass: 'large-dialog'
|
||||
});
|
||||
|
||||
|
@ -807,6 +817,30 @@ export class FlowEffects {
|
|||
);
|
||||
};
|
||||
|
||||
const goTo = (commands: string[], destination: string): void => {
|
||||
if (editDialogReference.componentInstance.editProcessorForm.dirty) {
|
||||
const saveChangesDialogReference = this.dialog.open(YesNoDialog, {
|
||||
data: {
|
||||
title: 'Processor Configuration',
|
||||
message: `Save changes before going to this ${destination}?`
|
||||
},
|
||||
panelClass: 'small-dialog'
|
||||
});
|
||||
|
||||
saveChangesDialogReference.componentInstance.yes.pipe(take(1)).subscribe(() => {
|
||||
editDialogReference.componentInstance.submitForm(commands);
|
||||
});
|
||||
|
||||
saveChangesDialogReference.componentInstance.no.pipe(take(1)).subscribe(() => {
|
||||
editDialogReference.close('ROUTED');
|
||||
this.router.navigate(commands);
|
||||
});
|
||||
} else {
|
||||
editDialogReference.close('ROUTED');
|
||||
this.router.navigate(commands);
|
||||
}
|
||||
};
|
||||
|
||||
if (parameterContext != null) {
|
||||
editDialogReference.componentInstance.getParameters = (sensitive: boolean) => {
|
||||
return this.flowService.getParameterContext(parameterContext.id).pipe(
|
||||
|
@ -819,20 +853,98 @@ export class FlowEffects {
|
|||
})
|
||||
);
|
||||
};
|
||||
|
||||
editDialogReference.componentInstance.parameterContext = parameterContext;
|
||||
editDialogReference.componentInstance.goToParameter = (parameter: string) => {
|
||||
const commands: string[] = ['/parameter-contexts', parameterContext.id];
|
||||
goTo(commands, 'Parameter');
|
||||
};
|
||||
|
||||
editDialogReference.componentInstance.convertToParameter = (
|
||||
name: string,
|
||||
sensitive: boolean,
|
||||
value: string | null
|
||||
) => {
|
||||
return this.parameterService.getParameterContext(parameterContext.id, false).pipe(
|
||||
switchMap((parameterContextEntity) => {
|
||||
const existingParameters: string[] =
|
||||
parameterContextEntity.component.parameters.map(
|
||||
(parameterEntity: ParameterEntity) => parameterEntity.parameter.name
|
||||
);
|
||||
const convertToParameterDialogRequest: EditParameterRequest = {
|
||||
parameter: {
|
||||
name,
|
||||
value,
|
||||
sensitive,
|
||||
description: ''
|
||||
},
|
||||
existingParameters
|
||||
};
|
||||
const convertToParameterDialogReference = this.dialog.open(EditParameterDialog, {
|
||||
data: convertToParameterDialogRequest,
|
||||
panelClass: 'medium-dialog'
|
||||
});
|
||||
|
||||
convertToParameterDialogReference.componentInstance.saving$ =
|
||||
this.store.select(selectParameterSaving);
|
||||
|
||||
convertToParameterDialogReference.componentInstance.cancel.pipe(
|
||||
takeUntil(convertToParameterDialogReference.afterClosed()),
|
||||
tap(() => ParameterActions.stopPollingParameterContextUpdateRequest())
|
||||
);
|
||||
|
||||
return convertToParameterDialogReference.componentInstance.editParameter.pipe(
|
||||
takeUntil(convertToParameterDialogReference.afterClosed()),
|
||||
switchMap((dialogResponse: EditParameterResponse) => {
|
||||
this.store.dispatch(
|
||||
ParameterActions.submitParameterContextUpdateRequest({
|
||||
request: {
|
||||
id: parameterContext.id,
|
||||
payload: {
|
||||
revision: this.client.getRevision(parameterContextEntity),
|
||||
component: {
|
||||
id: parameterContextEntity.id,
|
||||
parameters: [{ parameter: dialogResponse.parameter }]
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
return this.store.select(selectParameterSaving).pipe(
|
||||
takeUntil(convertToParameterDialogReference.afterClosed()),
|
||||
filter((parameterSaving) => parameterSaving === false),
|
||||
map(() => {
|
||||
convertToParameterDialogReference.close();
|
||||
return `#{${dialogResponse.parameter.name}}`;
|
||||
})
|
||||
);
|
||||
})
|
||||
);
|
||||
}),
|
||||
catchError((error) => {
|
||||
// TODO handle error
|
||||
return NEVER;
|
||||
})
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
editDialogReference.componentInstance.getServiceLink = (serviceId: string) => {
|
||||
return this.flowService.getControllerService(serviceId).pipe(
|
||||
take(1),
|
||||
map((serviceEntity) => {
|
||||
return [
|
||||
editDialogReference.componentInstance.goToService = (serviceId: string) => {
|
||||
this.controllerServiceService.getControllerService(serviceId).subscribe({
|
||||
next: (serviceEntity) => {
|
||||
const commands: string[] = [
|
||||
'/process-groups',
|
||||
serviceEntity.component.parentGroupId,
|
||||
'controller-services',
|
||||
serviceEntity.id
|
||||
];
|
||||
})
|
||||
);
|
||||
goTo(commands, 'Controller Service');
|
||||
},
|
||||
error: () => {
|
||||
// TODO - handle error
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
editDialogReference.componentInstance.createNewService = (
|
||||
|
@ -917,14 +1029,15 @@ export class FlowEffects {
|
|||
|
||||
editDialogReference.componentInstance.editProcessor
|
||||
.pipe(takeUntil(editDialogReference.afterClosed()))
|
||||
.subscribe((payload: any) => {
|
||||
.subscribe((updateProcessorRequest: UpdateProcessorRequest) => {
|
||||
this.store.dispatch(
|
||||
FlowActions.updateProcessor({
|
||||
request: {
|
||||
id: processorId,
|
||||
uri: request.uri,
|
||||
type: request.type,
|
||||
payload
|
||||
payload: updateProcessorRequest.payload,
|
||||
postUpdateNavigation: updateProcessorRequest.postUpdateNavigation
|
||||
}
|
||||
})
|
||||
);
|
||||
|
@ -1082,7 +1195,8 @@ export class FlowEffects {
|
|||
requestId: request.requestId,
|
||||
id: request.id,
|
||||
type: request.type,
|
||||
response: response
|
||||
postUpdateNavigation: request.postUpdateNavigation,
|
||||
response
|
||||
};
|
||||
return FlowActions.updateComponentSuccess({ response: updateComponentResponse });
|
||||
}),
|
||||
|
@ -1104,8 +1218,14 @@ export class FlowEffects {
|
|||
() =>
|
||||
this.actions$.pipe(
|
||||
ofType(FlowActions.updateComponentSuccess),
|
||||
tap(() => {
|
||||
this.dialog.closeAll();
|
||||
map((action) => action.response),
|
||||
tap((response) => {
|
||||
if (response.postUpdateNavigation) {
|
||||
this.router.navigate(response.postUpdateNavigation);
|
||||
this.dialog.getDialogById(response.id)?.close('ROUTED');
|
||||
} else {
|
||||
this.dialog.closeAll();
|
||||
}
|
||||
})
|
||||
),
|
||||
{ dispatch: false }
|
||||
|
@ -1130,7 +1250,8 @@ export class FlowEffects {
|
|||
requestId: request.requestId,
|
||||
id: request.id,
|
||||
type: request.type,
|
||||
response: response
|
||||
postUpdateNavigation: request.postUpdateNavigation,
|
||||
response
|
||||
};
|
||||
return FlowActions.updateProcessorSuccess({ response: updateComponentResponse });
|
||||
}),
|
||||
|
@ -1151,10 +1272,16 @@ export class FlowEffects {
|
|||
updateProcessorSuccess$ = createEffect(() =>
|
||||
this.actions$.pipe(
|
||||
ofType(FlowActions.updateProcessorSuccess),
|
||||
tap(() => {
|
||||
this.dialog.closeAll();
|
||||
}),
|
||||
map((action) => action.response),
|
||||
tap((response) => {
|
||||
if (response.postUpdateNavigation) {
|
||||
this.router.navigate(response.postUpdateNavigation);
|
||||
this.dialog.getDialogById(response.id)?.close('ROUTED');
|
||||
} else {
|
||||
this.dialog.closeAll();
|
||||
}
|
||||
}),
|
||||
filter((response) => response.postUpdateNavigation == null),
|
||||
switchMap((response) => of(FlowActions.loadConnectionsForComponent({ id: response.id })))
|
||||
)
|
||||
);
|
||||
|
|
|
@ -237,6 +237,11 @@ export interface EditConnectionDialogRequest extends EditComponentDialogRequest
|
|||
};
|
||||
}
|
||||
|
||||
export interface UpdateProcessorRequest {
|
||||
payload: any;
|
||||
postUpdateNavigation?: string[];
|
||||
}
|
||||
|
||||
export interface UpdateComponentRequest {
|
||||
requestId?: number;
|
||||
id: string;
|
||||
|
@ -244,6 +249,7 @@ export interface UpdateComponentRequest {
|
|||
uri: string;
|
||||
payload: any;
|
||||
restoreOnFailure?: any;
|
||||
postUpdateNavigation?: string[];
|
||||
}
|
||||
|
||||
export interface UpdateComponentResponse {
|
||||
|
@ -251,6 +257,7 @@ export interface UpdateComponentResponse {
|
|||
id: string;
|
||||
type: ComponentType;
|
||||
response: any;
|
||||
postUpdateNavigation?: string[];
|
||||
}
|
||||
|
||||
export interface UpdateComponentFailure {
|
||||
|
|
|
@ -26,6 +26,8 @@ import { transformReducer } from './transform/transform.reducer';
|
|||
import { flowReducer } from './flow/flow.reducer';
|
||||
import { controllerServicesFeatureKey, ControllerServicesState } from './controller-services';
|
||||
import { controllerServicesReducer } from './controller-services/controller-services.reducer';
|
||||
import { parameterFeatureKey, ParameterState } from './parameter';
|
||||
import { parameterReducer } from './parameter/parameter.reducer';
|
||||
|
||||
export const canvasFeatureKey = 'canvas';
|
||||
|
||||
|
@ -33,13 +35,15 @@ export interface CanvasState {
|
|||
[flowFeatureKey]: FlowState;
|
||||
[transformFeatureKey]: CanvasTransform;
|
||||
[controllerServicesFeatureKey]: ControllerServicesState;
|
||||
[parameterFeatureKey]: ParameterState;
|
||||
}
|
||||
|
||||
export function reducers(state: CanvasState | undefined, action: Action) {
|
||||
return combineReducers({
|
||||
[flowFeatureKey]: flowReducer,
|
||||
[transformFeatureKey]: transformReducer,
|
||||
[controllerServicesFeatureKey]: controllerServicesReducer
|
||||
[controllerServicesFeatureKey]: controllerServicesReducer,
|
||||
[parameterFeatureKey]: parameterReducer
|
||||
})(state, action);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* 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 { ParameterContextUpdateRequestEntity } from '../../../../state/shared';
|
||||
|
||||
export const parameterFeatureKey = 'parameter';
|
||||
|
||||
export interface ParameterState {
|
||||
updateRequestEntity: ParameterContextUpdateRequestEntity | null;
|
||||
saving: boolean;
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* 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 { createAction, props } from '@ngrx/store';
|
||||
import { PollParameterContextUpdateSuccess, SubmitParameterContextUpdate } from '../../../../state/shared';
|
||||
|
||||
export const parameterApiError = createAction('[Parameter] Parameter Error', props<{ error: string }>());
|
||||
|
||||
export const submitParameterContextUpdateRequest = createAction(
|
||||
'[Parameter] Submit Parameter Context Update Request',
|
||||
props<{ request: SubmitParameterContextUpdate }>()
|
||||
);
|
||||
|
||||
export const submitParameterContextUpdateRequestSuccess = createAction(
|
||||
'[Parameter] Submit Parameter Context Update Request Success',
|
||||
props<{ response: PollParameterContextUpdateSuccess }>()
|
||||
);
|
||||
|
||||
export const startPollingParameterContextUpdateRequest = createAction(
|
||||
'[Parameter] Start Polling Parameter Context Update Request'
|
||||
);
|
||||
|
||||
export const pollParameterContextUpdateRequest = createAction('[Parameter] Poll Parameter Context Update Request');
|
||||
|
||||
export const pollParameterContextUpdateRequestSuccess = createAction(
|
||||
'[Parameter] Poll Parameter Context Update Request Success',
|
||||
props<{ response: PollParameterContextUpdateSuccess }>()
|
||||
);
|
||||
|
||||
export const stopPollingParameterContextUpdateRequest = createAction(
|
||||
'[Parameter] Stop Polling Parameter Context Update Request'
|
||||
);
|
||||
|
||||
export const deleteParameterContextUpdateRequest = createAction('[Parameter] Delete Parameter Context Update Request');
|
||||
|
||||
export const editParameterContextComplete = createAction('[Parameter] Edit Parameter Context Complete');
|
|
@ -0,0 +1,163 @@
|
|||
/*
|
||||
* 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 { Injectable } from '@angular/core';
|
||||
import { Actions, createEffect, ofType } from '@ngrx/effects';
|
||||
import * as ParameterActions from './parameter.actions';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { CanvasState } from '../index';
|
||||
import {
|
||||
asyncScheduler,
|
||||
catchError,
|
||||
from,
|
||||
interval,
|
||||
map,
|
||||
NEVER,
|
||||
of,
|
||||
switchMap,
|
||||
takeUntil,
|
||||
tap,
|
||||
withLatestFrom
|
||||
} from 'rxjs';
|
||||
import { ParameterContextUpdateRequest } from '../../../../state/shared';
|
||||
import { selectUpdateRequest } from './parameter.selectors';
|
||||
import { ParameterService } from '../../service/parameter.service';
|
||||
|
||||
@Injectable()
|
||||
export class ParameterEffects {
|
||||
constructor(
|
||||
private actions$: Actions,
|
||||
private store: Store<CanvasState>,
|
||||
private parameterService: ParameterService
|
||||
) {}
|
||||
|
||||
submitParameterContextUpdateRequest$ = createEffect(() =>
|
||||
this.actions$.pipe(
|
||||
ofType(ParameterActions.submitParameterContextUpdateRequest),
|
||||
map((action) => action.request),
|
||||
switchMap((request) =>
|
||||
from(this.parameterService.submitParameterContextUpdate(request)).pipe(
|
||||
map((response) =>
|
||||
ParameterActions.submitParameterContextUpdateRequestSuccess({
|
||||
response: {
|
||||
requestEntity: response
|
||||
}
|
||||
})
|
||||
),
|
||||
catchError((error) =>
|
||||
of(
|
||||
ParameterActions.parameterApiError({
|
||||
error: error.error
|
||||
})
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
submitParameterContextUpdateRequestSuccess$ = createEffect(() =>
|
||||
this.actions$.pipe(
|
||||
ofType(ParameterActions.submitParameterContextUpdateRequestSuccess),
|
||||
map((action) => action.response),
|
||||
switchMap((response) => {
|
||||
const updateRequest: ParameterContextUpdateRequest = response.requestEntity.request;
|
||||
if (updateRequest.complete) {
|
||||
return of(ParameterActions.deleteParameterContextUpdateRequest());
|
||||
} else {
|
||||
return of(ParameterActions.startPollingParameterContextUpdateRequest());
|
||||
}
|
||||
})
|
||||
)
|
||||
);
|
||||
|
||||
startPollingParameterContextUpdateRequest$ = createEffect(() =>
|
||||
this.actions$.pipe(
|
||||
ofType(ParameterActions.startPollingParameterContextUpdateRequest),
|
||||
switchMap(() =>
|
||||
interval(2000, asyncScheduler).pipe(
|
||||
takeUntil(this.actions$.pipe(ofType(ParameterActions.stopPollingParameterContextUpdateRequest)))
|
||||
)
|
||||
),
|
||||
switchMap(() => of(ParameterActions.pollParameterContextUpdateRequest()))
|
||||
)
|
||||
);
|
||||
|
||||
pollParameterContextUpdateRequest$ = createEffect(() =>
|
||||
this.actions$.pipe(
|
||||
ofType(ParameterActions.pollParameterContextUpdateRequest),
|
||||
withLatestFrom(this.store.select(selectUpdateRequest)),
|
||||
switchMap(([action, updateRequest]) => {
|
||||
if (updateRequest) {
|
||||
return from(this.parameterService.pollParameterContextUpdate(updateRequest.request)).pipe(
|
||||
map((response) =>
|
||||
ParameterActions.pollParameterContextUpdateRequestSuccess({
|
||||
response: {
|
||||
requestEntity: response
|
||||
}
|
||||
})
|
||||
),
|
||||
catchError((error) =>
|
||||
of(
|
||||
ParameterActions.parameterApiError({
|
||||
error: error.error
|
||||
})
|
||||
)
|
||||
)
|
||||
);
|
||||
} else {
|
||||
return NEVER;
|
||||
}
|
||||
})
|
||||
)
|
||||
);
|
||||
|
||||
pollParameterContextUpdateRequestSuccess$ = createEffect(() =>
|
||||
this.actions$.pipe(
|
||||
ofType(ParameterActions.pollParameterContextUpdateRequestSuccess),
|
||||
map((action) => action.response),
|
||||
switchMap((response) => {
|
||||
const updateRequest: ParameterContextUpdateRequest = response.requestEntity.request;
|
||||
if (updateRequest.complete) {
|
||||
return of(ParameterActions.stopPollingParameterContextUpdateRequest());
|
||||
} else {
|
||||
return NEVER;
|
||||
}
|
||||
})
|
||||
)
|
||||
);
|
||||
|
||||
stopPollingParameterContextUpdateRequest$ = createEffect(() =>
|
||||
this.actions$.pipe(
|
||||
ofType(ParameterActions.stopPollingParameterContextUpdateRequest),
|
||||
switchMap((response) => of(ParameterActions.deleteParameterContextUpdateRequest()))
|
||||
)
|
||||
);
|
||||
|
||||
deleteParameterContextUpdateRequest$ = createEffect(() =>
|
||||
this.actions$.pipe(
|
||||
ofType(ParameterActions.deleteParameterContextUpdateRequest),
|
||||
withLatestFrom(this.store.select(selectUpdateRequest)),
|
||||
tap(([action, updateRequest]) => {
|
||||
if (updateRequest) {
|
||||
this.parameterService.deleteParameterContextUpdate(updateRequest.request).subscribe();
|
||||
}
|
||||
}),
|
||||
switchMap(() => of(ParameterActions.editParameterContextComplete()))
|
||||
)
|
||||
);
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* 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 { createReducer, on } from '@ngrx/store';
|
||||
import { ParameterState } from './index';
|
||||
import {
|
||||
editParameterContextComplete,
|
||||
pollParameterContextUpdateRequestSuccess,
|
||||
submitParameterContextUpdateRequest,
|
||||
submitParameterContextUpdateRequestSuccess
|
||||
} from './parameter.actions';
|
||||
|
||||
export const initialState: ParameterState = {
|
||||
updateRequestEntity: null,
|
||||
saving: false
|
||||
};
|
||||
|
||||
export const parameterReducer = createReducer(
|
||||
initialState,
|
||||
on(submitParameterContextUpdateRequest, (state, { request }) => ({
|
||||
...state,
|
||||
saving: true
|
||||
})),
|
||||
on(submitParameterContextUpdateRequestSuccess, pollParameterContextUpdateRequestSuccess, (state, { response }) => ({
|
||||
...state,
|
||||
updateRequestEntity: response.requestEntity
|
||||
})),
|
||||
on(editParameterContextComplete, (state) => ({
|
||||
...state,
|
||||
saving: false,
|
||||
updateRequestEntity: null
|
||||
}))
|
||||
);
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* 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 { createSelector } from '@ngrx/store';
|
||||
import { CanvasState, selectCanvasState } from '../index';
|
||||
import { parameterFeatureKey, ParameterState } from './index';
|
||||
|
||||
export const selectParameterState = createSelector(
|
||||
selectCanvasState,
|
||||
(state: CanvasState) => state[parameterFeatureKey]
|
||||
);
|
||||
|
||||
export const selectUpdateRequest = createSelector(
|
||||
selectParameterState,
|
||||
(state: ParameterState) => state.updateRequestEntity
|
||||
);
|
||||
|
||||
export const selectParameterSaving = createSelector(selectParameterState, (state: ParameterState) => state.saving);
|
|
@ -20,6 +20,7 @@ import {
|
|||
deleteComponents,
|
||||
getParameterContextsAndOpenGroupComponentsDialog,
|
||||
navigateToEditComponent,
|
||||
navigateToEditCurrentProcessGroup,
|
||||
setOperationCollapsed
|
||||
} from '../../../../state/flow/flow.actions';
|
||||
import { Store } from '@ngrx/store';
|
||||
|
@ -174,15 +175,19 @@ export class OperationControl {
|
|||
}
|
||||
|
||||
configure(selection: any): void {
|
||||
const selectionData = selection.datum();
|
||||
this.store.dispatch(
|
||||
navigateToEditComponent({
|
||||
request: {
|
||||
type: selectionData.type,
|
||||
id: selectionData.id
|
||||
}
|
||||
})
|
||||
);
|
||||
if (selection.empty()) {
|
||||
this.store.dispatch(navigateToEditCurrentProcessGroup());
|
||||
} else {
|
||||
const selectionData = selection.datum();
|
||||
this.store.dispatch(
|
||||
navigateToEditComponent({
|
||||
request: {
|
||||
type: selectionData.type,
|
||||
id: selectionData.id
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
canManageAccess(selection: any): boolean {
|
||||
|
|
|
@ -153,7 +153,10 @@
|
|||
[createNewProperty]="createNewProperty"
|
||||
[createNewService]="createNewService"
|
||||
[getParameters]="getParameters"
|
||||
[getServiceLink]="getServiceLink"
|
||||
[goToParameter]="goToParameter"
|
||||
[parameterContext]="parameterContext"
|
||||
[convertToParameter]="convertToParameter"
|
||||
[goToService]="goToService"
|
||||
[supportsSensitiveDynamicProperties]="
|
||||
request.entity.component.supportsSensitiveDynamicProperties
|
||||
"></property-table>
|
||||
|
|
|
@ -30,13 +30,14 @@ import {
|
|||
InlineServiceCreationRequest,
|
||||
InlineServiceCreationResponse,
|
||||
Parameter,
|
||||
ParameterContextReferenceEntity,
|
||||
Property,
|
||||
SelectOption,
|
||||
TextTipInput
|
||||
} from '../../../../../../../state/shared';
|
||||
import { Client } from '../../../../../../../service/client.service';
|
||||
import { NiFiCommon } from '../../../../../../../service/nifi-common.service';
|
||||
import { EditComponentDialogRequest } from '../../../../../state/flow';
|
||||
import { EditComponentDialogRequest, UpdateProcessorRequest } from '../../../../../state/flow';
|
||||
import { PropertyTable } from '../../../../../../../ui/common/property-table/property-table.component';
|
||||
import { NifiSpinnerDirective } from '../../../../../../../ui/common/spinner/nifi-spinner.directive';
|
||||
import { NifiTooltipDirective } from '../../../../../../../ui/common/tooltips/nifi-tooltip.directive';
|
||||
|
@ -75,9 +76,12 @@ export class EditProcessor {
|
|||
@Input() createNewProperty!: (existingProperties: string[], allowsSensitive: boolean) => Observable<Property>;
|
||||
@Input() createNewService!: (request: InlineServiceCreationRequest) => Observable<InlineServiceCreationResponse>;
|
||||
@Input() getParameters!: (sensitive: boolean) => Observable<Parameter[]>;
|
||||
@Input() getServiceLink!: (serviceId: string) => Observable<string[]>;
|
||||
@Input() parameterContext: ParameterContextReferenceEntity | undefined;
|
||||
@Input() goToParameter!: (parameter: string) => void;
|
||||
@Input() convertToParameter!: (name: string, sensitive: boolean, value: string | null) => Observable<string>;
|
||||
@Input() goToService!: (serviceId: string) => void;
|
||||
@Input() saving$!: Observable<boolean>;
|
||||
@Output() editProcessor: EventEmitter<any> = new EventEmitter<any>();
|
||||
@Output() editProcessor: EventEmitter<UpdateProcessorRequest> = new EventEmitter<UpdateProcessorRequest>();
|
||||
|
||||
protected readonly TextTip = TextTip;
|
||||
|
||||
|
@ -275,7 +279,7 @@ export class EditProcessor {
|
|||
);
|
||||
}
|
||||
|
||||
submitForm() {
|
||||
submitForm(postUpdateNavigation?: string[]) {
|
||||
const relationshipConfiguration: RelationshipConfiguration =
|
||||
this.editProcessorForm.get('relationshipConfiguration')?.value;
|
||||
const autoTerminated: string[] = relationshipConfiguration.relationships
|
||||
|
@ -326,6 +330,9 @@ export class EditProcessor {
|
|||
payload.component.config.retryCount = relationshipConfiguration.retryCount;
|
||||
}
|
||||
|
||||
this.editProcessor.next(payload);
|
||||
this.editProcessor.next({
|
||||
postUpdateNavigation,
|
||||
payload
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,12 +21,11 @@ import { HttpClient } from '@angular/common/http';
|
|||
import { Client } from '../../../service/client.service';
|
||||
import { NiFiCommon } from '../../../service/nifi-common.service';
|
||||
import {
|
||||
SubmitParameterContextUpdate,
|
||||
CreateParameterContextRequest,
|
||||
DeleteParameterContextRequest,
|
||||
ParameterContextEntity,
|
||||
ParameterContextUpdateRequest
|
||||
ParameterContextEntity
|
||||
} from '../state/parameter-context-listing';
|
||||
import { ParameterContextUpdateRequest, SubmitParameterContextUpdate } from '../../../state/shared';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class ParameterContextService {
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
import {
|
||||
AffectedComponentEntity,
|
||||
ParameterContextReferenceEntity,
|
||||
ParameterContextUpdateRequestEntity,
|
||||
ParameterEntity,
|
||||
Permissions,
|
||||
Revision
|
||||
|
@ -46,15 +47,6 @@ export interface EditParameterContextRequest {
|
|||
parameterContext?: ParameterContextEntity;
|
||||
}
|
||||
|
||||
export interface SubmitParameterContextUpdate {
|
||||
id: string;
|
||||
payload: any;
|
||||
}
|
||||
|
||||
export interface PollParameterContextUpdateSuccess {
|
||||
requestEntity: ParameterContextUpdateRequestEntity;
|
||||
}
|
||||
|
||||
export interface DeleteParameterContextRequest {
|
||||
parameterContext: ParameterContextEntity;
|
||||
}
|
||||
|
@ -67,23 +59,6 @@ export interface SelectParameterContextRequest {
|
|||
id: string;
|
||||
}
|
||||
|
||||
export interface ParameterContextUpdateRequest {
|
||||
complete: boolean;
|
||||
lastUpdated: string;
|
||||
percentComponent: number;
|
||||
referencingComponents: AffectedComponentEntity[];
|
||||
requestId: string;
|
||||
state: string;
|
||||
updateSteps: any[];
|
||||
uri: string;
|
||||
parameterContext?: any;
|
||||
}
|
||||
|
||||
export interface ParameterContextUpdateRequestEntity {
|
||||
parameterContextRevision: Revision;
|
||||
request: ParameterContextUpdateRequest;
|
||||
}
|
||||
|
||||
export interface ParameterContextEntity {
|
||||
revision: Revision;
|
||||
permissions: Permissions;
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
|
||||
import { createAction, props } from '@ngrx/store';
|
||||
import {
|
||||
SubmitParameterContextUpdate,
|
||||
CreateParameterContextRequest,
|
||||
CreateParameterContextSuccess,
|
||||
DeleteParameterContextRequest,
|
||||
|
@ -25,9 +24,9 @@ import {
|
|||
EditParameterContextRequest,
|
||||
LoadParameterContextsResponse,
|
||||
SelectParameterContextRequest,
|
||||
PollParameterContextUpdateSuccess,
|
||||
GetEffectiveParameterContext
|
||||
} from './index';
|
||||
import { PollParameterContextUpdateSuccess, SubmitParameterContextUpdate } from '../../../../state/shared';
|
||||
|
||||
export const loadParameterContexts = createAction('[Parameter Context Listing] Load Parameter Contexts');
|
||||
|
||||
|
|
|
@ -41,9 +41,13 @@ import { ParameterContextService } from '../../service/parameter-contexts.servic
|
|||
import { YesNoDialog } from '../../../../ui/common/yes-no-dialog/yes-no-dialog.component';
|
||||
import { EditParameterContext } from '../../ui/parameter-context-listing/edit-parameter-context/edit-parameter-context.component';
|
||||
import { selectParameterContexts, selectSaving, selectUpdateRequest } from './parameter-context-listing.selectors';
|
||||
import { EditParameterRequest, EditParameterResponse, Parameter } from '../../../../state/shared';
|
||||
import {
|
||||
EditParameterRequest,
|
||||
EditParameterResponse,
|
||||
Parameter,
|
||||
ParameterContextUpdateRequest
|
||||
} from '../../../../state/shared';
|
||||
import { EditParameterDialog } from '../../../../ui/common/edit-parameter-dialog/edit-parameter-dialog.component';
|
||||
import { ParameterContextUpdateRequest } from './index';
|
||||
import { OkDialog } from '../../../../ui/common/ok-dialog/ok-dialog.component';
|
||||
|
||||
@Injectable()
|
||||
|
@ -104,7 +108,7 @@ export class ParameterContextListingEffects {
|
|||
panelClass: 'medium-dialog'
|
||||
});
|
||||
|
||||
newParameterDialogReference.componentInstance.saving = false;
|
||||
newParameterDialogReference.componentInstance.saving$ = of(false);
|
||||
|
||||
return newParameterDialogReference.componentInstance.editParameter.pipe(
|
||||
take(1),
|
||||
|
@ -236,7 +240,7 @@ export class ParameterContextListingEffects {
|
|||
panelClass: 'medium-dialog'
|
||||
});
|
||||
|
||||
newParameterDialogReference.componentInstance.saving = false;
|
||||
newParameterDialogReference.componentInstance.saving$ = of(false);
|
||||
|
||||
return newParameterDialogReference.componentInstance.editParameter.pipe(
|
||||
take(1),
|
||||
|
@ -263,7 +267,7 @@ export class ParameterContextListingEffects {
|
|||
panelClass: 'medium-dialog'
|
||||
});
|
||||
|
||||
editParameterDialogReference.componentInstance.saving = false;
|
||||
editParameterDialogReference.componentInstance.saving$ = of(false);
|
||||
|
||||
return editParameterDialogReference.componentInstance.editParameter.pipe(
|
||||
take(1),
|
||||
|
@ -336,7 +340,14 @@ export class ParameterContextListingEffects {
|
|||
this.actions$.pipe(
|
||||
ofType(ParameterContextListingActions.submitParameterContextUpdateRequestSuccess),
|
||||
map((action) => action.response),
|
||||
switchMap((response) => of(ParameterContextListingActions.startPollingParameterContextUpdateRequest()))
|
||||
switchMap((response) => {
|
||||
const updateRequest: ParameterContextUpdateRequest = response.requestEntity.request;
|
||||
if (updateRequest.complete) {
|
||||
return of(ParameterContextListingActions.deleteParameterContextUpdateRequest());
|
||||
} else {
|
||||
return of(ParameterContextListingActions.startPollingParameterContextUpdateRequest());
|
||||
}
|
||||
})
|
||||
)
|
||||
);
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
*/
|
||||
|
||||
import { createReducer, on } from '@ngrx/store';
|
||||
import { ParameterContextListingState, ParameterContextUpdateRequestEntity } from './index';
|
||||
import { ParameterContextListingState } from './index';
|
||||
import { produce } from 'immer';
|
||||
import {
|
||||
createParameterContext,
|
||||
|
@ -30,7 +30,7 @@ import {
|
|||
submitParameterContextUpdateRequest,
|
||||
submitParameterContextUpdateRequestSuccess
|
||||
} from './parameter-context-listing.actions';
|
||||
import { Revision } from '../../../../state/shared';
|
||||
import { ParameterContextUpdateRequestEntity, Revision } from '../../../../state/shared';
|
||||
|
||||
export const initialState: ParameterContextListingState = {
|
||||
parameterContexts: [],
|
||||
|
@ -74,11 +74,7 @@ export const parameterContextListingReducer = createReducer(
|
|||
...state,
|
||||
saving: true
|
||||
})),
|
||||
on(submitParameterContextUpdateRequestSuccess, (state, { response }) => ({
|
||||
...state,
|
||||
updateRequestEntity: response.requestEntity
|
||||
})),
|
||||
on(pollParameterContextUpdateRequestSuccess, (state, { response }) => ({
|
||||
on(submitParameterContextUpdateRequestSuccess, pollParameterContextUpdateRequestSuccess, (state, { response }) => ({
|
||||
...state,
|
||||
updateRequestEntity: response.requestEntity
|
||||
})),
|
||||
|
|
|
@ -25,16 +25,12 @@ import { AsyncPipe, NgForOf, NgIf } from '@angular/common';
|
|||
import { MatTabsModule } from '@angular/material/tabs';
|
||||
import { MatOptionModule } from '@angular/material/core';
|
||||
import { MatSelectModule } from '@angular/material/select';
|
||||
import { Observable, take, tap } from 'rxjs';
|
||||
import {
|
||||
EditParameterContextRequest,
|
||||
ParameterContextEntity,
|
||||
ParameterContextUpdateRequestEntity
|
||||
} from '../../../state/parameter-context-listing';
|
||||
import { Observable } from 'rxjs';
|
||||
import { EditParameterContextRequest, ParameterContextEntity } from '../../../state/parameter-context-listing';
|
||||
import { NifiSpinnerDirective } from '../../../../../ui/common/spinner/nifi-spinner.directive';
|
||||
import { Client } from '../../../../../service/client.service';
|
||||
import { ParameterTable } from '../parameter-table/parameter-table.component';
|
||||
import { Parameter, ParameterEntity } from '../../../../../state/shared';
|
||||
import { Parameter, ParameterContextUpdateRequestEntity, ParameterEntity } from '../../../../../state/shared';
|
||||
import { ProcessGroupReferences } from '../process-group-references/process-group-references.component';
|
||||
import { ParameterContextInheritance } from '../parameter-context-inheritance/parameter-context-inheritance.component';
|
||||
import { ParameterReferences } from '../parameter-references/parameter-references.component';
|
||||
|
|
|
@ -38,11 +38,13 @@ export interface ConfigureControllerServiceRequest {
|
|||
id: string;
|
||||
uri: string;
|
||||
payload: any;
|
||||
postUpdateNavigation?: string[];
|
||||
}
|
||||
|
||||
export interface ConfigureControllerServiceSuccess {
|
||||
id: string;
|
||||
controllerService: ControllerServiceEntity;
|
||||
postUpdateNavigation?: string[];
|
||||
}
|
||||
|
||||
export interface DeleteControllerServiceRequest {
|
||||
|
|
|
@ -34,7 +34,8 @@ import {
|
|||
NewPropertyDialogRequest,
|
||||
NewPropertyDialogResponse,
|
||||
Property,
|
||||
PropertyDescriptor
|
||||
PropertyDescriptor,
|
||||
UpdateControllerServiceRequest
|
||||
} from '../../../../state/shared';
|
||||
import { NewPropertyDialog } from '../../../../ui/common/new-property-dialog/new-property-dialog.component';
|
||||
import { Router } from '@angular/router';
|
||||
|
@ -182,6 +183,7 @@ export class ManagementControllerServicesEffects {
|
|||
data: {
|
||||
controllerService: request.controllerService
|
||||
},
|
||||
id: serviceId,
|
||||
panelClass: 'large-dialog'
|
||||
});
|
||||
|
||||
|
@ -218,8 +220,33 @@ export class ManagementControllerServicesEffects {
|
|||
);
|
||||
};
|
||||
|
||||
editDialogReference.componentInstance.getServiceLink = (serviceId: string) => {
|
||||
return of(['/settings', 'management-controller-services', serviceId]);
|
||||
const goTo = (commands: string[]): void => {
|
||||
if (editDialogReference.componentInstance.editControllerServiceForm.dirty) {
|
||||
const saveChangesDialogReference = this.dialog.open(YesNoDialog, {
|
||||
data: {
|
||||
title: 'Controller Service Configuration',
|
||||
message: `Save changes before going to this Controller Service?`
|
||||
},
|
||||
panelClass: 'small-dialog'
|
||||
});
|
||||
|
||||
saveChangesDialogReference.componentInstance.yes.pipe(take(1)).subscribe(() => {
|
||||
editDialogReference.componentInstance.submitForm(commands);
|
||||
});
|
||||
|
||||
saveChangesDialogReference.componentInstance.no.pipe(take(1)).subscribe(() => {
|
||||
editDialogReference.close('ROUTED');
|
||||
this.router.navigate(commands);
|
||||
});
|
||||
} else {
|
||||
editDialogReference.close('ROUTED');
|
||||
this.router.navigate(commands);
|
||||
}
|
||||
};
|
||||
|
||||
editDialogReference.componentInstance.goToService = (serviceId: string) => {
|
||||
const commands: string[] = ['/settings', 'management-controller-services', serviceId];
|
||||
goTo(commands);
|
||||
};
|
||||
|
||||
editDialogReference.componentInstance.createNewService = (
|
||||
|
@ -303,13 +330,14 @@ export class ManagementControllerServicesEffects {
|
|||
|
||||
editDialogReference.componentInstance.editControllerService
|
||||
.pipe(takeUntil(editDialogReference.afterClosed()))
|
||||
.subscribe((payload: any) => {
|
||||
.subscribe((updateControllerServiceRequest: UpdateControllerServiceRequest) => {
|
||||
this.store.dispatch(
|
||||
ManagementControllerServicesActions.configureControllerService({
|
||||
request: {
|
||||
id: request.controllerService.id,
|
||||
uri: request.controllerService.uri,
|
||||
payload
|
||||
payload: updateControllerServiceRequest.payload,
|
||||
postUpdateNavigation: updateControllerServiceRequest.postUpdateNavigation
|
||||
}
|
||||
})
|
||||
);
|
||||
|
@ -341,7 +369,8 @@ export class ManagementControllerServicesEffects {
|
|||
ManagementControllerServicesActions.configureControllerServiceSuccess({
|
||||
response: {
|
||||
id: request.id,
|
||||
controllerService: response
|
||||
controllerService: response,
|
||||
postUpdateNavigation: request.postUpdateNavigation
|
||||
}
|
||||
})
|
||||
),
|
||||
|
@ -361,8 +390,14 @@ export class ManagementControllerServicesEffects {
|
|||
() =>
|
||||
this.actions$.pipe(
|
||||
ofType(ManagementControllerServicesActions.configureControllerServiceSuccess),
|
||||
tap(() => {
|
||||
this.dialog.closeAll();
|
||||
map((action) => action.response),
|
||||
tap((response) => {
|
||||
if (response.postUpdateNavigation) {
|
||||
this.router.navigate(response.postUpdateNavigation);
|
||||
this.dialog.getDialogById(response.id)?.close('ROUTED');
|
||||
} else {
|
||||
this.dialog.closeAll();
|
||||
}
|
||||
})
|
||||
),
|
||||
{ dispatch: false }
|
||||
|
|
|
@ -49,11 +49,13 @@ export interface EditRegistryClientRequest {
|
|||
id: string;
|
||||
uri: string;
|
||||
payload: any;
|
||||
postUpdateNavigation?: string[];
|
||||
}
|
||||
|
||||
export interface EditRegistryClientRequestSuccess {
|
||||
id: string;
|
||||
registryClient: RegistryClientEntity;
|
||||
postUpdateNavigation?: string[];
|
||||
}
|
||||
|
||||
export interface DeleteRegistryClientRequest {
|
||||
|
|
|
@ -42,6 +42,7 @@ import { ExtensionTypesService } from '../../../../service/extension-types.servi
|
|||
import { CreateControllerService } from '../../../../ui/common/controller-service/create-controller-service/create-controller-service.component';
|
||||
import { ManagementControllerServiceService } from '../../service/management-controller-service.service';
|
||||
import { Client } from '../../../../service/client.service';
|
||||
import { EditRegistryClientRequest } from './index';
|
||||
|
||||
@Injectable()
|
||||
export class RegistryClientsEffects {
|
||||
|
@ -174,6 +175,7 @@ export class RegistryClientsEffects {
|
|||
|
||||
const editDialogReference = this.dialog.open(EditRegistryClient, {
|
||||
data: request,
|
||||
id: registryClientId,
|
||||
panelClass: 'large-dialog'
|
||||
});
|
||||
|
||||
|
@ -214,8 +216,30 @@ export class RegistryClientsEffects {
|
|||
);
|
||||
};
|
||||
|
||||
editDialogReference.componentInstance.getServiceLink = (serviceId: string) => {
|
||||
return of(['/settings', 'management-controller-services', serviceId]);
|
||||
editDialogReference.componentInstance.goToService = (serviceId: string) => {
|
||||
const commands: string[] = ['/settings', 'management-controller-services', serviceId];
|
||||
|
||||
if (editDialogReference.componentInstance.editRegistryClientForm.dirty) {
|
||||
const saveChangesDialogReference = this.dialog.open(YesNoDialog, {
|
||||
data: {
|
||||
title: 'Registry Client Configuration',
|
||||
message: `Save changes before going to this Controller Service?`
|
||||
},
|
||||
panelClass: 'small-dialog'
|
||||
});
|
||||
|
||||
saveChangesDialogReference.componentInstance.yes.pipe(take(1)).subscribe(() => {
|
||||
editDialogReference.componentInstance.submitForm(commands);
|
||||
});
|
||||
|
||||
saveChangesDialogReference.componentInstance.no.pipe(take(1)).subscribe(() => {
|
||||
editDialogReference.close('ROUTED');
|
||||
this.router.navigate(commands);
|
||||
});
|
||||
} else {
|
||||
editDialogReference.close('ROUTED');
|
||||
this.router.navigate(commands);
|
||||
}
|
||||
};
|
||||
|
||||
editDialogReference.componentInstance.createNewService = (
|
||||
|
@ -292,14 +316,10 @@ export class RegistryClientsEffects {
|
|||
|
||||
editDialogReference.componentInstance.editRegistryClient
|
||||
.pipe(takeUntil(editDialogReference.afterClosed()))
|
||||
.subscribe((payload: any) => {
|
||||
.subscribe((editRegistryClientRequest: EditRegistryClientRequest) => {
|
||||
this.store.dispatch(
|
||||
RegistryClientsActions.configureRegistryClient({
|
||||
request: {
|
||||
id: registryClientId,
|
||||
uri: request.registryClient.uri,
|
||||
payload
|
||||
}
|
||||
request: editRegistryClientRequest
|
||||
})
|
||||
);
|
||||
});
|
||||
|
@ -320,7 +340,7 @@ export class RegistryClientsEffects {
|
|||
{ dispatch: false }
|
||||
);
|
||||
|
||||
configureControllerService$ = createEffect(() =>
|
||||
configureRegistryClient$ = createEffect(() =>
|
||||
this.actions$.pipe(
|
||||
ofType(RegistryClientsActions.configureRegistryClient),
|
||||
map((action) => action.request),
|
||||
|
@ -330,7 +350,8 @@ export class RegistryClientsEffects {
|
|||
RegistryClientsActions.configureRegistryClientSuccess({
|
||||
response: {
|
||||
id: request.id,
|
||||
registryClient: response
|
||||
registryClient: response,
|
||||
postUpdateNavigation: request.postUpdateNavigation
|
||||
}
|
||||
})
|
||||
),
|
||||
|
@ -350,8 +371,14 @@ export class RegistryClientsEffects {
|
|||
() =>
|
||||
this.actions$.pipe(
|
||||
ofType(RegistryClientsActions.configureRegistryClientSuccess),
|
||||
tap(() => {
|
||||
this.dialog.closeAll();
|
||||
map((action) => action.response),
|
||||
tap((response) => {
|
||||
if (response.postUpdateNavigation) {
|
||||
this.router.navigate(response.postUpdateNavigation);
|
||||
this.dialog.getDialogById(response.id)?.close('ROUTED');
|
||||
} else {
|
||||
this.dialog.closeAll();
|
||||
}
|
||||
})
|
||||
),
|
||||
{ dispatch: false }
|
||||
|
|
|
@ -50,7 +50,7 @@
|
|||
[createNewProperty]="createNewProperty"
|
||||
[createNewService]="createNewService"
|
||||
[getParameters]="getParameters"
|
||||
[getServiceLink]="getServiceLink"
|
||||
[goToService]="goToService"
|
||||
[supportsSensitiveDynamicProperties]="
|
||||
request.registryClient.component.supportsSensitiveDynamicProperties
|
||||
"></property-table>
|
||||
|
@ -64,7 +64,7 @@
|
|||
[disabled]="!editRegistryClientForm.dirty || editRegistryClientForm.invalid || saving.value"
|
||||
type="button"
|
||||
color="primary"
|
||||
(click)="createRegistryClientClicked()"
|
||||
(click)="submitForm()"
|
||||
mat-raised-button>
|
||||
<span *nifiSpinner="saving.value">Apply</span>
|
||||
</button>
|
||||
|
|
|
@ -31,7 +31,7 @@ import {
|
|||
Property,
|
||||
TextTipInput
|
||||
} from '../../../../../state/shared';
|
||||
import { EditRegistryClientDialogRequest } from '../../../state/registry-clients';
|
||||
import { EditRegistryClientDialogRequest, EditRegistryClientRequest } from '../../../state/registry-clients';
|
||||
import { NifiSpinnerDirective } from '../../../../../ui/common/spinner/nifi-spinner.directive';
|
||||
import { Client } from '../../../../../service/client.service';
|
||||
import { MatSelectModule } from '@angular/material/select';
|
||||
|
@ -66,9 +66,10 @@ export class EditRegistryClient {
|
|||
@Input() createNewProperty!: (existingProperties: string[], allowsSensitive: boolean) => Observable<Property>;
|
||||
@Input() createNewService!: (request: InlineServiceCreationRequest) => Observable<InlineServiceCreationResponse>;
|
||||
@Input() getParameters!: (sensitive: boolean) => Observable<Parameter[]>;
|
||||
@Input() getServiceLink!: (serviceId: string) => Observable<string[]>;
|
||||
@Input() goToService!: (serviceId: string) => void;
|
||||
@Input() saving$!: Observable<boolean>;
|
||||
@Output() editRegistryClient: EventEmitter<any> = new EventEmitter<any>();
|
||||
@Output() editRegistryClient: EventEmitter<EditRegistryClientRequest> =
|
||||
new EventEmitter<EditRegistryClientRequest>();
|
||||
|
||||
protected readonly TextTip = TextTip;
|
||||
|
||||
|
@ -109,7 +110,7 @@ export class EditRegistryClient {
|
|||
};
|
||||
}
|
||||
|
||||
createRegistryClientClicked() {
|
||||
submitForm(postUpdateNavigation?: string[]) {
|
||||
const payload: any = {
|
||||
revision: this.client.getRevision(this.request.registryClient),
|
||||
component: {
|
||||
|
@ -131,6 +132,11 @@ export class EditRegistryClient {
|
|||
.map((property) => property.descriptor.name);
|
||||
}
|
||||
|
||||
this.editRegistryClient.next(payload);
|
||||
this.editRegistryClient.next({
|
||||
id: this.request.registryClient.id,
|
||||
uri: this.request.registryClient.uri,
|
||||
payload,
|
||||
postUpdateNavigation
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -58,6 +58,11 @@ export interface EditControllerServiceDialogRequest {
|
|||
controllerService: ControllerServiceEntity;
|
||||
}
|
||||
|
||||
export interface UpdateControllerServiceRequest {
|
||||
payload: any;
|
||||
postUpdateNavigation?: string[];
|
||||
}
|
||||
|
||||
export interface ProvenanceEventSummary {
|
||||
id: string;
|
||||
eventId: number;
|
||||
|
@ -253,6 +258,32 @@ export interface AffectedComponent {
|
|||
validationErrors: string[];
|
||||
}
|
||||
|
||||
export interface SubmitParameterContextUpdate {
|
||||
id: string;
|
||||
payload: any;
|
||||
}
|
||||
|
||||
export interface PollParameterContextUpdateSuccess {
|
||||
requestEntity: ParameterContextUpdateRequestEntity;
|
||||
}
|
||||
|
||||
export interface ParameterContextUpdateRequest {
|
||||
complete: boolean;
|
||||
lastUpdated: string;
|
||||
percentComponent: number;
|
||||
referencingComponents: AffectedComponentEntity[];
|
||||
requestId: string;
|
||||
state: string;
|
||||
updateSteps: any[];
|
||||
uri: string;
|
||||
parameterContext?: any;
|
||||
}
|
||||
|
||||
export interface ParameterContextUpdateRequestEntity {
|
||||
parameterContextRevision: Revision;
|
||||
request: ParameterContextUpdateRequest;
|
||||
}
|
||||
|
||||
export interface ElFunction {
|
||||
name: string;
|
||||
description: string;
|
||||
|
|
|
@ -84,7 +84,10 @@
|
|||
[createNewProperty]="createNewProperty"
|
||||
[createNewService]="createNewService"
|
||||
[getParameters]="getParameters"
|
||||
[getServiceLink]="getServiceLink"
|
||||
[parameterContext]="parameterContext"
|
||||
[goToParameter]="goToParameter"
|
||||
[convertToParameter]="convertToParameter"
|
||||
[goToService]="goToService"
|
||||
[supportsSensitiveDynamicProperties]="
|
||||
request.controllerService.component.supportsSensitiveDynamicProperties
|
||||
"></property-table>
|
||||
|
|
|
@ -25,7 +25,9 @@ import {
|
|||
InlineServiceCreationRequest,
|
||||
InlineServiceCreationResponse,
|
||||
Parameter,
|
||||
Property
|
||||
ParameterContextReferenceEntity,
|
||||
Property,
|
||||
UpdateControllerServiceRequest
|
||||
} from '../../../../state/shared';
|
||||
import { MatInputModule } from '@angular/material/input';
|
||||
import { MatCheckboxModule } from '@angular/material/checkbox';
|
||||
|
@ -68,9 +70,13 @@ export class EditControllerService {
|
|||
@Input() createNewProperty!: (existingProperties: string[], allowsSensitive: boolean) => Observable<Property>;
|
||||
@Input() createNewService!: (request: InlineServiceCreationRequest) => Observable<InlineServiceCreationResponse>;
|
||||
@Input() getParameters!: (sensitive: boolean) => Observable<Parameter[]>;
|
||||
@Input() getServiceLink!: (serviceId: string) => Observable<string[]>;
|
||||
@Input() parameterContext: ParameterContextReferenceEntity | undefined;
|
||||
@Input() goToParameter!: (parameter: string) => void;
|
||||
@Input() convertToParameter!: (name: string, sensitive: boolean, value: string | null) => Observable<string>;
|
||||
@Input() goToService!: (serviceId: string) => void;
|
||||
@Input() saving$!: Observable<boolean>;
|
||||
@Output() editControllerService: EventEmitter<any> = new EventEmitter<any>();
|
||||
@Output() editControllerService: EventEmitter<UpdateControllerServiceRequest> =
|
||||
new EventEmitter<UpdateControllerServiceRequest>();
|
||||
|
||||
editControllerServiceForm: FormGroup;
|
||||
|
||||
|
@ -130,7 +136,7 @@ export class EditControllerService {
|
|||
return this.nifiCommon.formatBundle(entity.component.bundle);
|
||||
}
|
||||
|
||||
submitForm() {
|
||||
submitForm(postUpdateNavigation?: string[]) {
|
||||
const payload: any = {
|
||||
revision: this.client.getRevision(this.request.controllerService),
|
||||
component: {
|
||||
|
@ -151,6 +157,9 @@ export class EditControllerService {
|
|||
.map((property) => property.descriptor.name);
|
||||
}
|
||||
|
||||
this.editControllerService.next(payload);
|
||||
this.editControllerService.next({
|
||||
payload,
|
||||
postUpdateNavigation
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,14 +48,14 @@
|
|||
</mat-form-field>
|
||||
</div>
|
||||
</mat-dialog-content>
|
||||
<mat-dialog-actions align="end">
|
||||
<mat-dialog-actions align="end" *ngIf="{ value: (saving$ | async)! } as saving">
|
||||
<button mat-raised-button mat-dialog-close color="accent">Cancel</button>
|
||||
<button
|
||||
mat-raised-button
|
||||
[disabled]="!editParameterForm.dirty || editParameterForm.invalid || saving"
|
||||
(click)="addProperty()"
|
||||
[disabled]="editParameterForm.invalid || saving.value"
|
||||
(click)="okClicked()"
|
||||
color="primary">
|
||||
<span *nifiSpinner="saving">Ok</span>
|
||||
<span *nifiSpinner="saving.value">Ok</span>
|
||||
</button>
|
||||
</mat-dialog-actions>
|
||||
</form>
|
||||
|
|
|
@ -35,7 +35,8 @@ import { MatInputModule } from '@angular/material/input';
|
|||
import { MatRadioModule } from '@angular/material/radio';
|
||||
import { MatCheckboxModule } from '@angular/material/checkbox';
|
||||
import { NifiSpinnerDirective } from '../spinner/nifi-spinner.directive';
|
||||
import { NgIf } from '@angular/common';
|
||||
import { AsyncPipe, NgIf } from '@angular/common';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
@Component({
|
||||
selector: 'edit-parameter-dialog',
|
||||
|
@ -50,16 +51,19 @@ import { NgIf } from '@angular/common';
|
|||
MatRadioModule,
|
||||
MatCheckboxModule,
|
||||
NifiSpinnerDirective,
|
||||
NgIf
|
||||
NgIf,
|
||||
AsyncPipe
|
||||
],
|
||||
templateUrl: './edit-parameter-dialog.component.html',
|
||||
styleUrls: ['./edit-parameter-dialog.component.scss']
|
||||
})
|
||||
export class EditParameterDialog {
|
||||
@Input() saving!: boolean;
|
||||
@Input() saving$!: Observable<boolean>;
|
||||
@Output() editParameter: EventEmitter<EditParameterResponse> = new EventEmitter<EditParameterResponse>();
|
||||
@Output() cancel: EventEmitter<void> = new EventEmitter<void>();
|
||||
|
||||
name: FormControl;
|
||||
sensitive: FormControl;
|
||||
editParameterForm: FormGroup;
|
||||
isNew: boolean;
|
||||
|
||||
|
@ -67,38 +71,48 @@ export class EditParameterDialog {
|
|||
@Inject(MAT_DIALOG_DATA) public request: EditParameterRequest,
|
||||
private formBuilder: FormBuilder
|
||||
) {
|
||||
// get the optional parameter. when existingParameters are specified this parameter is used to
|
||||
// seed the form for the new parameter. when existingParameters are not specified, this is the
|
||||
// existing parameter that populates the form
|
||||
const parameter: Parameter | undefined = request.parameter;
|
||||
|
||||
if (parameter) {
|
||||
this.isNew = false;
|
||||
|
||||
// in edit scenarios the existing parameters shouldn't be enforced since the parameter does exist
|
||||
this.name = new FormControl({ value: parameter.name, disabled: true }, Validators.required);
|
||||
|
||||
this.editParameterForm = this.formBuilder.group({
|
||||
name: this.name,
|
||||
value: new FormControl(parameter.value),
|
||||
empty: new FormControl(parameter.value == ''),
|
||||
sensitive: new FormControl({ value: parameter.sensitive, disabled: true }, Validators.required),
|
||||
description: new FormControl(parameter.description)
|
||||
});
|
||||
} else {
|
||||
const validators: any[] = [Validators.required];
|
||||
if (request.existingParameters) {
|
||||
this.isNew = true;
|
||||
|
||||
const validators: any[] = [Validators.required];
|
||||
if (request.existingParameters) {
|
||||
validators.push(this.existingParameterValidator(request.existingParameters));
|
||||
}
|
||||
this.name = new FormControl('', validators);
|
||||
// since there were existing parameters in the request, add the existing parameters validator because
|
||||
// parameters names must be unique
|
||||
validators.push(this.existingParameterValidator(request.existingParameters));
|
||||
|
||||
this.editParameterForm = this.formBuilder.group({
|
||||
name: this.name,
|
||||
value: new FormControl(''),
|
||||
empty: new FormControl(false),
|
||||
sensitive: new FormControl({ value: false, disabled: false }, Validators.required),
|
||||
description: new FormControl('')
|
||||
});
|
||||
this.name = new FormControl(parameter ? parameter.name : '', validators);
|
||||
|
||||
// when seeding a new parameter with a sensitivity flag do not allow it to be changed
|
||||
const disableSensitive: boolean = parameter != null;
|
||||
this.sensitive = new FormControl(
|
||||
{ value: parameter ? parameter.sensitive : false, disabled: disableSensitive },
|
||||
Validators.required
|
||||
);
|
||||
} else {
|
||||
this.isNew = false;
|
||||
|
||||
// without existingParameters, we are editing an existing parameter. in this case the name and sensitivity cannot be modified
|
||||
this.name = new FormControl(
|
||||
{ value: parameter ? parameter.name : '', disabled: true },
|
||||
Validators.required
|
||||
);
|
||||
this.sensitive = new FormControl(
|
||||
{ value: parameter ? parameter.sensitive : false, disabled: true },
|
||||
Validators.required
|
||||
);
|
||||
}
|
||||
|
||||
this.editParameterForm = this.formBuilder.group({
|
||||
name: this.name,
|
||||
value: new FormControl(parameter ? parameter.value : ''),
|
||||
empty: new FormControl(parameter ? parameter.value == '' : false),
|
||||
sensitive: this.sensitive,
|
||||
description: new FormControl(parameter ? parameter.description : '')
|
||||
});
|
||||
}
|
||||
|
||||
private existingParameterValidator(existingParameters: string[]): ValidatorFn {
|
||||
|
@ -136,7 +150,11 @@ export class EditParameterDialog {
|
|||
}
|
||||
}
|
||||
|
||||
addProperty(): void {
|
||||
cancelClicked(): void {
|
||||
this.cancel.next();
|
||||
}
|
||||
|
||||
okClicked(): void {
|
||||
const value: string = this.editParameterForm.get('value')?.value;
|
||||
const empty: boolean = this.editParameterForm.get('empty')?.value;
|
||||
|
||||
|
|
|
@ -103,19 +103,26 @@
|
|||
<th mat-header-cell *matHeaderCellDef></th>
|
||||
<td mat-cell *matCellDef="let item">
|
||||
<div class="flex items-center gap-x-3">
|
||||
<!-- TODO - convert to parameter, go to parameter -->
|
||||
<div
|
||||
class="pointer fa fa-plus"
|
||||
*ngIf="item.descriptor.identifiesControllerService"
|
||||
(click)="createNewControllerService(item)"
|
||||
title="Create new service"></div>
|
||||
<!-- TODO - need to prevent navigation if outstanding changes -->
|
||||
<div
|
||||
class="pointer fa fa-level-up"
|
||||
*ngIf="canConvertToParameter(item)"
|
||||
(click)="convertToParameterClicked(item)"
|
||||
title="Convert to Parameter"></div>
|
||||
<div
|
||||
class="pointer fa fa-long-arrow-right"
|
||||
*ngIf="item.serviceLink"
|
||||
[routerLink]="item.serviceLink"
|
||||
mat-dialog-close="ROUTED"
|
||||
title="Go to"></div>
|
||||
*ngIf="canGoToParameter(item)"
|
||||
(click)="goToParameterClicked(item)"
|
||||
title="Go to Parameter"></div>
|
||||
<div
|
||||
class="pointer fa fa-long-arrow-right"
|
||||
*ngIf="canGoToService(item)"
|
||||
(click)="goToServiceClicked(item)"
|
||||
title="Go to Service"></div>
|
||||
<div
|
||||
class="pointer fa fa-trash"
|
||||
*ngIf="item.type == 'userDefined'"
|
||||
|
|
|
@ -37,6 +37,7 @@ import {
|
|||
InlineServiceCreationRequest,
|
||||
InlineServiceCreationResponse,
|
||||
Parameter,
|
||||
ParameterContextReferenceEntity,
|
||||
Property,
|
||||
PropertyDependency,
|
||||
PropertyDescriptor,
|
||||
|
@ -100,9 +101,14 @@ export class PropertyTable implements AfterViewInit, ControlValueAccessor {
|
|||
@Input() createNewProperty!: (existingProperties: string[], allowsSensitive: boolean) => Observable<Property>;
|
||||
@Input() createNewService!: (request: InlineServiceCreationRequest) => Observable<InlineServiceCreationResponse>;
|
||||
@Input() getParameters!: (sensitive: boolean) => Observable<Parameter[]>;
|
||||
@Input() getServiceLink!: (serviceId: string) => Observable<string[]>;
|
||||
@Input() parameterContext: ParameterContextReferenceEntity | undefined;
|
||||
@Input() goToParameter!: (parameter: string) => void;
|
||||
@Input() convertToParameter!: (name: string, sensitive: boolean, value: string | null) => Observable<string>;
|
||||
@Input() goToService!: (serviceId: string) => void;
|
||||
@Input() supportsSensitiveDynamicProperties: boolean = false;
|
||||
|
||||
private static readonly PARAM_REF_REGEX: RegExp = /#{[a-zA-Z0-9-_. ]+}/;
|
||||
|
||||
private destroyRef = inject(DestroyRef);
|
||||
|
||||
protected readonly NfEditor = NfEditor;
|
||||
|
@ -264,8 +270,6 @@ export class PropertyTable implements AfterViewInit, ControlValueAccessor {
|
|||
: 'optional'
|
||||
};
|
||||
|
||||
this.populateServiceLink(item);
|
||||
|
||||
// store the property item in a map for an efficient lookup later
|
||||
this.itemLookup.set(property.property, item);
|
||||
return item;
|
||||
|
@ -274,16 +278,6 @@ export class PropertyTable implements AfterViewInit, ControlValueAccessor {
|
|||
this.setPropertyItems(propertyItems);
|
||||
}
|
||||
|
||||
private populateServiceLink(item: PropertyItem): void {
|
||||
if (this.canGoTo(item) && item.value) {
|
||||
this.getServiceLink(item.value)
|
||||
.pipe(take(1))
|
||||
.subscribe((serviceLink: string[]) => {
|
||||
item.serviceLink = serviceLink;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private setPropertyItems(propertyItems: PropertyItem[]): void {
|
||||
this.dataSource = new MatTableDataSource<PropertyItem>(propertyItems);
|
||||
this.initFilter();
|
||||
|
@ -311,8 +305,6 @@ export class PropertyTable implements AfterViewInit, ControlValueAccessor {
|
|||
: 'optional'
|
||||
};
|
||||
|
||||
this.populateServiceLink(item);
|
||||
|
||||
this.itemLookup.set(property.property, item);
|
||||
|
||||
const propertyItems: PropertyItem[] = [...currentPropertyItems, item];
|
||||
|
@ -388,7 +380,7 @@ export class PropertyTable implements AfterViewInit, ControlValueAccessor {
|
|||
this.editorOpen = true;
|
||||
}
|
||||
|
||||
canGoTo(item: PropertyItem): boolean {
|
||||
canGoToService(item: PropertyItem): boolean {
|
||||
// TODO - add Input() for supportsGoTo? currently only false in summary table
|
||||
|
||||
const descriptor: PropertyDescriptor = item.descriptor;
|
||||
|
@ -401,6 +393,11 @@ export class PropertyTable implements AfterViewInit, ControlValueAccessor {
|
|||
return false;
|
||||
}
|
||||
|
||||
goToServiceClicked(item: PropertyItem): void {
|
||||
// @ts-ignore
|
||||
this.goToService(item.value);
|
||||
}
|
||||
|
||||
createNewControllerService(item: PropertyItem): void {
|
||||
this.createNewService({ descriptor: item.descriptor })
|
||||
.pipe(take(1))
|
||||
|
@ -413,6 +410,48 @@ export class PropertyTable implements AfterViewInit, ControlValueAccessor {
|
|||
});
|
||||
}
|
||||
|
||||
canGoToParameter(item: PropertyItem): boolean {
|
||||
// TODO - currently parameter context route does not support navigating
|
||||
// directly to a specific parameter so the parameter context link
|
||||
// is not item specific.
|
||||
if (this.parameterContext && item.value) {
|
||||
return this.parameterContext.permissions.canRead && PropertyTable.PARAM_REF_REGEX.test(item.value);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
goToParameterClicked(item: PropertyItem): void {
|
||||
// @ts-ignore
|
||||
this.goToParameter(item.value);
|
||||
}
|
||||
|
||||
canConvertToParameter(item: PropertyItem): boolean {
|
||||
let canUpdateParameterContext: boolean = false;
|
||||
if (this.parameterContext) {
|
||||
canUpdateParameterContext =
|
||||
this.parameterContext.permissions.canRead && this.parameterContext.permissions.canWrite;
|
||||
}
|
||||
|
||||
let propertyReferencesParameter: boolean = false;
|
||||
if (canUpdateParameterContext && item.value) {
|
||||
propertyReferencesParameter = PropertyTable.PARAM_REF_REGEX.test(item.value);
|
||||
}
|
||||
|
||||
return canUpdateParameterContext && !propertyReferencesParameter;
|
||||
}
|
||||
|
||||
convertToParameterClicked(item: PropertyItem): void {
|
||||
this.convertToParameter(item.property, item.descriptor.sensitive, item.value)
|
||||
.pipe(take(1))
|
||||
.subscribe((propertyValue) => {
|
||||
item.value = propertyValue;
|
||||
item.dirty = true;
|
||||
|
||||
this.handleChanged();
|
||||
});
|
||||
}
|
||||
|
||||
deleteProperty(item: PropertyItem): void {
|
||||
if (!item.deleted) {
|
||||
item.value = null;
|
||||
|
@ -428,8 +467,6 @@ export class PropertyTable implements AfterViewInit, ControlValueAccessor {
|
|||
item.value = newValue;
|
||||
item.dirty = true;
|
||||
|
||||
this.populateServiceLink(item);
|
||||
|
||||
this.handleChanged();
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,6 @@
|
|||
<div class="text-sm" data-qa="yes-no-message">{{ request.message }}</div>
|
||||
</mat-dialog-content>
|
||||
<mat-dialog-actions align="end">
|
||||
<button mat-raised-button mat-dialog-close color="accent">No</button>
|
||||
<button mat-raised-button mat-dialog-close color="accent" (click)="noClicked()">No</button>
|
||||
<button mat-raised-button mat-dialog-close cdkFocusInitial color="primary" (click)="yesClicked()">Yes</button>
|
||||
</mat-dialog-actions>
|
||||
|
|
|
@ -29,10 +29,15 @@ import { MatButtonModule } from '@angular/material/button';
|
|||
})
|
||||
export class YesNoDialog {
|
||||
@Output() yes: EventEmitter<void> = new EventEmitter<void>();
|
||||
@Output() no: EventEmitter<void> = new EventEmitter<void>();
|
||||
|
||||
constructor(@Inject(MAT_DIALOG_DATA) public request: YesNoDialogRequest) {}
|
||||
|
||||
yesClicked(): void {
|
||||
this.yes.next();
|
||||
}
|
||||
|
||||
noClicked(): void {
|
||||
this.no.next();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue