From 160c7ae24baefb5aa0be4962da1c09459185ee3f Mon Sep 17 00:00:00 2001 From: Matt Gilman Date: Fri, 3 May 2024 08:04:44 -0400 Subject: [PATCH] NIFI-13119: When evaluating dependent Properties, the UI should identify when the Property value is a parameter reference and resolve the value accordingly (#8724) * NIFI-13119: - When evaluating dependent Properties, the UI should identify when the Property value is a parameter reference and resolve the value accordingly. * NIFI-13119: - Requiring a value to be present when showing dependent property that doesn't require any specific value. * NIFI-13119: - Using error helper to get error string. * NIFI-13119: - Handle convert to parameter error scenario. This closes #8724 --- .../service/parameter-helper.service.ts | 59 ++++++------- .../controller-services.effects.ts | 34 +++++++- .../flow-designer/state/flow/flow.effects.ts | 32 ++++++- .../pages/flow-designer/state/flow/index.ts | 2 +- .../edit-process-group.component.ts | 3 +- .../edit-processor.component.html | 1 - .../edit-processor.component.ts | 13 +-- .../service/parameter-contexts.service.ts | 10 +-- .../state/parameter-context-listing/index.ts | 34 +------- .../parameter-context-listing.selectors.ts | 3 +- .../edit-parameter-context.component.spec.ts | 3 +- .../edit-parameter-context.component.ts | 3 +- ...parameter-context-inheritance.component.ts | 3 +- .../parameter-context-listing.component.ts | 3 +- .../parameter-context-table.component.ts | 2 +- .../process-group-references.component.ts | 2 +- .../feature/route-not-found.component.spec.ts | 6 +- .../edit-registry-client.component.html | 1 - .../edit-registry-client.component.ts | 2 - .../interceptors/polling.interceptor.ts | 2 + .../main/nifi/src/app/state/shared/index.ts | 26 ++++++ .../edit-controller-service.component.html | 1 - .../edit-controller-service.component.ts | 13 +-- .../combo-editor/combo-editor.component.html | 83 +++++++++---------- .../combo-editor.component.spec.ts | 9 +- .../combo-editor/combo-editor.component.ts | 67 +++++++-------- .../editors/nf-editor/nf-editor.component.ts | 32 ++++--- .../property-table.component.html | 4 +- .../property-table.component.ts | 80 ++++++++++++++---- 29 files changed, 303 insertions(+), 230 deletions(-) diff --git a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/parameter-helper.service.ts b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/parameter-helper.service.ts index fad0378e4e..18825ac294 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/parameter-helper.service.ts +++ b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/parameter-helper.service.ts @@ -17,23 +17,27 @@ import { Injectable } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; -import { catchError, EMPTY, filter, map, Observable, switchMap, take, takeUntil, tap } from 'rxjs'; +import { catchError, EMPTY, filter, map, Observable, switchMap, takeUntil, tap } from 'rxjs'; import { Store } from '@ngrx/store'; import { HttpErrorResponse } from '@angular/common/http'; import { NiFiState } from '../../../state'; import { ParameterService } from './parameter.service'; import { Client } from '../../../service/client.service'; -import { EditParameterRequest, EditParameterResponse, Parameter, ParameterEntity } from '../../../state/shared'; +import { EditParameterRequest, EditParameterResponse, ParameterContext, ParameterEntity } from '../../../state/shared'; import { EditParameterDialog } from '../../../ui/common/edit-parameter-dialog/edit-parameter-dialog.component'; import { selectParameterSaving, selectParameterState } from '../state/parameter/parameter.selectors'; import { ParameterState } from '../state/parameter'; import * as ErrorActions from '../../../state/error/error.actions'; import * as ParameterActions from '../state/parameter/parameter.actions'; -import { FlowService } from './flow.service'; import { MEDIUM_DIALOG } from '../../../index'; import { ClusterConnectionService } from '../../../service/cluster-connection.service'; import { ErrorHelper } from '../../../service/error-helper.service'; +export interface ConvertToParameterResponse { + propertyValue: string; + parameterContext?: ParameterContext; +} + @Injectable({ providedIn: 'root' }) @@ -41,40 +45,12 @@ export class ParameterHelperService { constructor( private dialog: MatDialog, private store: Store, - private flowService: FlowService, private parameterService: ParameterService, private clusterConnectionService: ClusterConnectionService, private client: Client, private errorHelper: ErrorHelper ) {} - /** - * Returns a function that can be used to pass into a PropertyTable to retrieve available Parameters. - * - * @param parameterContextId the current Parameter Context id - */ - getParameters(parameterContextId: string): (sensitive: boolean) => Observable { - return (sensitive: boolean) => { - return this.flowService.getParameterContext(parameterContextId).pipe( - take(1), - catchError((errorResponse: HttpErrorResponse) => { - this.store.dispatch( - ErrorActions.snackBarError({ error: this.errorHelper.getErrorString(errorResponse) }) - ); - - // consider the error handled and allow the user to reattempt the action - return EMPTY; - }), - map((response) => response.component.parameters), - map((parameterEntities) => { - return parameterEntities - .map((parameterEntity: ParameterEntity) => parameterEntity.parameter) - .filter((parameter: Parameter) => parameter.sensitive == sensitive); - }) - ); - }; - } - /** * Returns a function that can be used to pass into a PropertyTable to convert a Property into a Parameter, inline. * @@ -82,7 +58,7 @@ export class ParameterHelperService { */ convertToParameter( parameterContextId: string - ): (name: string, sensitive: boolean, value: string | null) => Observable { + ): (name: string, sensitive: boolean, value: string | null) => Observable { return (name: string, sensitive: boolean, value: string | null) => { return this.parameterService.getParameterContext(parameterContextId, false).pipe( catchError((errorResponse: HttpErrorResponse) => { @@ -127,6 +103,7 @@ export class ParameterHelperService { request: { id: parameterContextId, payload: { + id: parameterContextEntity.id, revision: this.client.getRevision(parameterContextEntity), disconnectedNodeAcknowledged: this.clusterConnectionService.isDisconnectionAcknowledged(), @@ -139,6 +116,8 @@ export class ParameterHelperService { }) ); + let parameterContext: ParameterContext; + return this.store.select(selectParameterState).pipe( takeUntil(convertToParameterDialogReference.afterClosed()), tap((parameterState: ParameterState) => { @@ -146,12 +125,24 @@ export class ParameterHelperService { // if the convert to parameter sequence stores an error, // throw it to avoid the completion mapping logic below throw new Error(parameterState.error); + } else if (parameterState.updateRequestEntity?.request.failureReason) { + // if the convert to parameter sequence completes successfully + // with an error, throw the message + throw new Error(parameterState.updateRequestEntity?.request.failureReason); + } + + if (parameterState.saving) { + parameterContext = parameterState.updateRequestEntity?.request.parameterContext; } }), - filter((parameterState: ParameterState) => !parameterState.saving), + filter((parameterState) => !parameterState.saving), map(() => { convertToParameterDialogReference.close(); - return `#{${dialogResponse.parameter.name}}`; + + return { + propertyValue: `#{${dialogResponse.parameter.name}}`, + parameterContext + } as ConvertToParameterResponse; }), catchError((error) => { convertToParameterDialogReference.close(); diff --git a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/state/controller-services/controller-services.effects.ts b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/state/controller-services/controller-services.effects.ts index 7d1bb6680e..9d64fbe2a1 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/state/controller-services/controller-services.effects.ts +++ b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/state/controller-services/controller-services.effects.ts @@ -53,6 +53,7 @@ import { ParameterHelperService } from '../../service/parameter-helper.service'; import { LARGE_DIALOG, SMALL_DIALOG, XL_DIALOG } from '../../../../index'; import { ExtensionTypesService } from '../../../../service/extension-types.service'; import { ChangeComponentVersionDialog } from '../../../../ui/common/change-component-version-dialog/change-component-version-dialog'; +import { FlowService } from '../../service/flow.service'; @Injectable() export class ControllerServicesEffects { @@ -61,6 +62,7 @@ export class ControllerServicesEffects { private store: Store, private client: Client, private controllerServiceService: ControllerServiceService, + private flowService: FlowService, private errorHelper: ErrorHelper, private dialog: MatDialog, private router: Router, @@ -236,6 +238,34 @@ export class ControllerServicesEffects { this.store.select(selectParameterContext), this.store.select(selectCurrentProcessGroupId) ]), + switchMap(([request, parameterContextReference, processGroupId]) => { + if (parameterContextReference && parameterContextReference.permissions.canRead) { + return from(this.flowService.getParameterContext(parameterContextReference.id)).pipe( + map((parameterContext) => { + return [request, parameterContext, processGroupId]; + }), + tap({ + error: (errorResponse: HttpErrorResponse) => { + this.store.dispatch( + ControllerServicesActions.selectControllerService({ + request: { + processGroupId, + id: request.id + } + }) + ); + this.store.dispatch( + ErrorActions.snackBarError({ + error: this.errorHelper.getErrorString(errorResponse) + }) + ); + } + }) + ); + } + + return of([request, null, processGroupId]); + }), tap(([request, parameterContext, processGroupId]) => { const serviceId: string = request.id; @@ -282,10 +312,6 @@ export class ControllerServicesEffects { }; if (parameterContext != null) { - editDialogReference.componentInstance.getParameters = this.parameterHelperService.getParameters( - parameterContext.id - ); - editDialogReference.componentInstance.parameterContext = parameterContext; editDialogReference.componentInstance.goToParameter = () => { const commands: string[] = ['/parameter-contexts', parameterContext.id]; diff --git a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/state/flow/flow.effects.ts b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/state/flow/flow.effects.ts index 44224036bb..c50e5c93a2 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/state/flow/flow.effects.ts +++ b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/state/flow/flow.effects.ts @@ -1200,6 +1200,34 @@ export class FlowEffects { this.store.select(selectCurrentParameterContext), this.store.select(selectCurrentProcessGroupId) ]), + switchMap(([request, parameterContextReference, processGroupId]) => { + if (parameterContextReference && parameterContextReference.permissions.canRead) { + return from(this.flowService.getParameterContext(parameterContextReference.id)).pipe( + map((parameterContext) => { + return [request, parameterContext, processGroupId]; + }), + tap({ + error: (errorResponse: HttpErrorResponse) => { + this.store.dispatch( + FlowActions.selectComponents({ + request: { + components: [ + { + id: request.entity.id, + componentType: request.type + } + ] + } + }) + ); + this.store.dispatch(this.snackBarOrFullScreenError(errorResponse)); + } + }) + ); + } + + return of([request, null, processGroupId]); + }), tap(([request, parameterContext, processGroupId]) => { const processorId: string = request.entity.id; @@ -1239,10 +1267,6 @@ export class FlowEffects { }; if (parameterContext != null) { - editDialogReference.componentInstance.getParameters = this.parameterHelperService.getParameters( - parameterContext.id - ); - editDialogReference.componentInstance.parameterContext = parameterContext; editDialogReference.componentInstance.goToParameter = () => { const commands: string[] = ['/parameter-contexts', parameterContext.id]; diff --git a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/state/flow/index.ts b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/state/flow/index.ts index 5cc8372a0e..e9292fb29e 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/state/flow/index.ts +++ b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/state/flow/index.ts @@ -22,6 +22,7 @@ import { ComponentHistory, ComponentType, DocumentedType, + ParameterContextEntity, ParameterContextReferenceEntity, Permissions, RegistryClientEntity, @@ -30,7 +31,6 @@ import { SparseVersionedFlow, VersionedFlowSnapshotMetadataEntity } from '../../../../state/shared'; -import { ParameterContextEntity } from '../../../parameter-contexts/state/parameter-context-listing'; import { HttpErrorResponse } from '@angular/common/http'; export const flowFeatureKey = 'flowState'; diff --git a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/process-group/edit-process-group/edit-process-group.component.ts b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/process-group/edit-process-group/edit-process-group.component.ts index da70e2efdb..687dd48f45 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/process-group/edit-process-group/edit-process-group.component.ts +++ b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/process-group/edit-process-group/edit-process-group.component.ts @@ -26,13 +26,12 @@ import { MatTabsModule } from '@angular/material/tabs'; import { MatOptionModule } from '@angular/material/core'; import { MatSelectModule } from '@angular/material/select'; import { Observable } from 'rxjs'; -import { SelectOption } from '../../../../../../../state/shared'; +import { ParameterContextEntity, SelectOption } from '../../../../../../../state/shared'; import { Client } from '../../../../../../../service/client.service'; 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'; import { TextTip } from '../../../../../../../ui/common/tooltips/text-tip/text-tip.component'; -import { ParameterContextEntity } from '../../../../../../parameter-contexts/state/parameter-context-listing'; import { ControllerServiceTable } from '../../../../../../../ui/common/controller-service/controller-service-table/controller-service-table.component'; import { EditComponentDialogRequest } from '../../../../../state/flow'; import { ClusterConnectionService } from '../../../../../../../service/cluster-connection.service'; diff --git a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/processor/edit-processor/edit-processor.component.html b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/processor/edit-processor/edit-processor.component.html index 8cb5355223..ee4a697ce3 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/processor/edit-processor/edit-processor.component.html +++ b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/processor/edit-processor/edit-processor.component.html @@ -237,7 +237,6 @@ formControlName="properties" [createNewProperty]="createNewProperty" [createNewService]="createNewService" - [getParameters]="getParameters" [goToParameter]="goToParameter" [parameterContext]="parameterContext" [convertToParameter]="convertToParameter" diff --git a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/processor/edit-processor/edit-processor.component.ts b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/processor/edit-processor/edit-processor.component.ts index 568e895ab0..413a7b42e0 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/processor/edit-processor/edit-processor.component.ts +++ b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/processor/edit-processor/edit-processor.component.ts @@ -29,8 +29,7 @@ import { Observable } from 'rxjs'; import { InlineServiceCreationRequest, InlineServiceCreationResponse, - Parameter, - ParameterContextReferenceEntity, + ParameterContextEntity, Property, SelectOption } from '../../../../../../../state/shared'; @@ -49,6 +48,7 @@ import { import { ErrorBanner } from '../../../../../../../ui/common/error-banner/error-banner.component'; import { ClusterConnectionService } from '../../../../../../../service/cluster-connection.service'; import { CanvasUtils } from '../../../../../service/canvas-utils.service'; +import { ConvertToParameterResponse } from '../../../../../service/parameter-helper.service'; @Component({ selector: 'edit-processor', @@ -76,10 +76,13 @@ import { CanvasUtils } from '../../../../../service/canvas-utils.service'; export class EditProcessor { @Input() createNewProperty!: (existingProperties: string[], allowsSensitive: boolean) => Observable; @Input() createNewService!: (request: InlineServiceCreationRequest) => Observable; - @Input() getParameters!: (sensitive: boolean) => Observable; - @Input() parameterContext: ParameterContextReferenceEntity | undefined; + @Input() parameterContext: ParameterContextEntity | undefined; @Input() goToParameter!: (parameter: string) => void; - @Input() convertToParameter!: (name: string, sensitive: boolean, value: string | null) => Observable; + @Input() convertToParameter!: ( + name: string, + sensitive: boolean, + value: string | null + ) => Observable; @Input() goToService!: (serviceId: string) => void; @Input() saving$!: Observable; @Output() editProcessor: EventEmitter = new EventEmitter(); diff --git a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/parameter-contexts/service/parameter-contexts.service.ts b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/parameter-contexts/service/parameter-contexts.service.ts index cc2dd0b567..993033b4ef 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/parameter-contexts/service/parameter-contexts.service.ts +++ b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/parameter-contexts/service/parameter-contexts.service.ts @@ -20,12 +20,12 @@ import { Observable } from 'rxjs'; import { HttpClient, HttpParams } from '@angular/common/http'; import { Client } from '../../../service/client.service'; import { NiFiCommon } from '../../../service/nifi-common.service'; +import { CreateParameterContextRequest, DeleteParameterContextRequest } from '../state/parameter-context-listing'; import { - CreateParameterContextRequest, - DeleteParameterContextRequest, - ParameterContextEntity -} from '../state/parameter-context-listing'; -import { ParameterContextUpdateRequest, SubmitParameterContextUpdate } from '../../../state/shared'; + ParameterContextEntity, + ParameterContextUpdateRequest, + SubmitParameterContextUpdate +} from '../../../state/shared'; import { ClusterConnectionService } from '../../../service/cluster-connection.service'; @Injectable({ providedIn: 'root' }) diff --git a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/parameter-contexts/state/parameter-context-listing/index.ts b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/parameter-contexts/state/parameter-context-listing/index.ts index 06eb2d71ef..76cca5f24f 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/parameter-contexts/state/parameter-context-listing/index.ts +++ b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/parameter-contexts/state/parameter-context-listing/index.ts @@ -15,14 +15,7 @@ * limitations under the License. */ -import { - ParameterContextReferenceEntity, - ParameterContextUpdateRequestEntity, - ParameterEntity, - ParameterProviderConfigurationEntity, - Permissions, - Revision -} from '../../../../state/shared'; +import { ParameterContextEntity, ParameterContextUpdateRequestEntity } from '../../../../state/shared'; export const parameterContextListingFeatureKey = 'parameterContextListing'; @@ -59,31 +52,6 @@ export interface SelectParameterContextRequest { id: string; } -export interface ParameterContextEntity { - revision: Revision; - permissions: Permissions; - id: string; - uri: string; - component: ParameterContext; -} - -export interface ParameterContext { - id: string; - name: string; - description: string; - parameters: ParameterEntity[]; - boundProcessGroups: BoundProcessGroup[]; - inheritedParameterContexts: ParameterContextReferenceEntity[]; - parameterProviderConfiguration?: ParameterProviderConfigurationEntity; -} - -// TODO - Replace this with ProcessGroupEntity was available -export interface BoundProcessGroup { - permissions: Permissions; - id: string; - component: any; -} - export interface ParameterContextListingState { parameterContexts: ParameterContextEntity[]; updateRequestEntity: ParameterContextUpdateRequestEntity | null; diff --git a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/parameter-contexts/state/parameter-context-listing/parameter-context-listing.selectors.ts b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/parameter-contexts/state/parameter-context-listing/parameter-context-listing.selectors.ts index 622429a95f..ab344a3a92 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/parameter-contexts/state/parameter-context-listing/parameter-context-listing.selectors.ts +++ b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/parameter-contexts/state/parameter-context-listing/parameter-context-listing.selectors.ts @@ -17,8 +17,9 @@ import { createSelector } from '@ngrx/store'; import { ParameterContextsState, selectParameterContextState } from '../index'; -import { ParameterContextEntity, parameterContextListingFeatureKey, ParameterContextListingState } from './index'; +import { parameterContextListingFeatureKey, ParameterContextListingState } from './index'; import { selectCurrentRoute } from '../../../../state/router/router.selectors'; +import { ParameterContextEntity } from '../../../../state/shared'; export const selectParameterContextListingState = createSelector( selectParameterContextState, diff --git a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/parameter-contexts/ui/parameter-context-listing/edit-parameter-context/edit-parameter-context.component.spec.ts b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/parameter-contexts/ui/parameter-context-listing/edit-parameter-context/edit-parameter-context.component.spec.ts index 6358da10e9..6c89bf0c5d 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/parameter-contexts/ui/parameter-context-listing/edit-parameter-context/edit-parameter-context.component.spec.ts +++ b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/parameter-contexts/ui/parameter-context-listing/edit-parameter-context/edit-parameter-context.component.spec.ts @@ -18,13 +18,14 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { EditParameterContext } from './edit-parameter-context.component'; -import { EditParameterContextRequest, ParameterContextEntity } from '../../../state/parameter-context-listing'; +import { EditParameterContextRequest } from '../../../state/parameter-context-listing'; import { MAT_DIALOG_DATA } from '@angular/material/dialog'; import { of } from 'rxjs'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { provideMockStore } from '@ngrx/store/testing'; import { initialState } from '../../../state/parameter-context-listing/parameter-context-listing.reducer'; import { ClusterConnectionService } from '../../../../../service/cluster-connection.service'; +import { ParameterContextEntity } from '../../../../../state/shared'; describe('EditParameterContext', () => { let component: EditParameterContext; diff --git a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/parameter-contexts/ui/parameter-context-listing/edit-parameter-context/edit-parameter-context.component.ts b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/parameter-contexts/ui/parameter-context-listing/edit-parameter-context/edit-parameter-context.component.ts index 45649324ee..036ca911dd 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/parameter-contexts/ui/parameter-context-listing/edit-parameter-context/edit-parameter-context.component.ts +++ b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/parameter-contexts/ui/parameter-context-listing/edit-parameter-context/edit-parameter-context.component.ts @@ -26,12 +26,13 @@ import { MatTabsModule } from '@angular/material/tabs'; import { MatOptionModule } from '@angular/material/core'; import { MatSelectModule } from '@angular/material/select'; import { Observable } from 'rxjs'; -import { EditParameterContextRequest, ParameterContextEntity } from '../../../state/parameter-context-listing'; +import { EditParameterContextRequest } 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, + ParameterContextEntity, ParameterContextUpdateRequestEntity, ParameterEntity, ParameterProviderConfiguration diff --git a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/parameter-contexts/ui/parameter-context-listing/parameter-context-inheritance/parameter-context-inheritance.component.ts b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/parameter-contexts/ui/parameter-context-listing/parameter-context-inheritance/parameter-context-inheritance.component.ts index 4c6b25cd12..50b0d6308f 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/parameter-contexts/ui/parameter-context-listing/parameter-context-inheritance/parameter-context-inheritance.component.ts +++ b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/parameter-contexts/ui/parameter-context-listing/parameter-context-inheritance/parameter-context-inheritance.component.ts @@ -24,11 +24,10 @@ import { AsyncPipe, NgTemplateOutlet } from '@angular/common'; import { CdkConnectedOverlay, CdkOverlayOrigin } from '@angular/cdk/overlay'; import { RouterLink } from '@angular/router'; import { NiFiCommon } from '../../../../../service/nifi-common.service'; -import { ParameterContextReferenceEntity } from '../../../../../state/shared'; +import { ParameterContextEntity, ParameterContextReferenceEntity } from '../../../../../state/shared'; import { NifiTooltipDirective } from '../../../../../ui/common/tooltips/nifi-tooltip.directive'; import { TextTip } from '../../../../../ui/common/tooltips/text-tip/text-tip.component'; import { ParameterReferences } from '../../../../../ui/common/parameter-references/parameter-references.component'; -import { ParameterContextEntity } from '../../../state/parameter-context-listing'; import { DragDropModule, CdkDrag, diff --git a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/parameter-contexts/ui/parameter-context-listing/parameter-context-listing.component.ts b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/parameter-contexts/ui/parameter-context-listing/parameter-context-listing.component.ts index 850ddf2a39..fe88993e3c 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/parameter-contexts/ui/parameter-context-listing/parameter-context-listing.component.ts +++ b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/parameter-contexts/ui/parameter-context-listing/parameter-context-listing.component.ts @@ -17,7 +17,7 @@ import { Component, OnInit } from '@angular/core'; import { Store } from '@ngrx/store'; -import { ParameterContextEntity, ParameterContextListingState } from '../../state/parameter-context-listing'; +import { ParameterContextListingState } from '../../state/parameter-context-listing'; import { selectContext, selectParameterContextIdFromRoute, @@ -37,6 +37,7 @@ import { filter, switchMap, take } from 'rxjs'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { selectCurrentUser } from '../../../../state/current-user/current-user.selectors'; import { selectFlowConfiguration } from '../../../../state/flow-configuration/flow-configuration.selectors'; +import { ParameterContextEntity } from '../../../../state/shared'; @Component({ selector: 'parameter-context-listing', diff --git a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/parameter-contexts/ui/parameter-context-listing/parameter-context-table/parameter-context-table.component.ts b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/parameter-contexts/ui/parameter-context-listing/parameter-context-table/parameter-context-table.component.ts index 531bc4c447..cfd57170f9 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/parameter-contexts/ui/parameter-context-listing/parameter-context-table/parameter-context-table.component.ts +++ b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/parameter-contexts/ui/parameter-context-listing/parameter-context-table/parameter-context-table.component.ts @@ -19,9 +19,9 @@ import { Component, EventEmitter, Input, Output } from '@angular/core'; import { MatTableDataSource } from '@angular/material/table'; import { Sort } from '@angular/material/sort'; import { NiFiCommon } from '../../../../../service/nifi-common.service'; -import { ParameterContextEntity } from '../../../state/parameter-context-listing'; import { FlowConfiguration } from '../../../../../state/flow-configuration'; import { CurrentUser } from '../../../../../state/current-user'; +import { ParameterContextEntity } from '../../../../../state/shared'; @Component({ selector: 'parameter-context-table', diff --git a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/parameter-contexts/ui/parameter-context-listing/process-group-references/process-group-references.component.ts b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/parameter-contexts/ui/parameter-context-listing/process-group-references/process-group-references.component.ts index 74ddcd74ef..854614e853 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/parameter-contexts/ui/parameter-context-listing/process-group-references/process-group-references.component.ts +++ b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/parameter-contexts/ui/parameter-context-listing/process-group-references/process-group-references.component.ts @@ -23,7 +23,7 @@ import { NgClass, NgTemplateOutlet } from '@angular/common'; import { RouterLink } from '@angular/router'; import { MatDialogModule } from '@angular/material/dialog'; import { NifiTooltipDirective } from '../../../../../ui/common/tooltips/nifi-tooltip.directive'; -import { BoundProcessGroup } from '../../../state/parameter-context-listing'; +import { BoundProcessGroup } from '../../../../../state/shared'; @Component({ selector: 'process-group-references', diff --git a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/route-not-found/feature/route-not-found.component.spec.ts b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/route-not-found/feature/route-not-found.component.spec.ts index 5312b2b67f..5ec9e86776 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/route-not-found/feature/route-not-found.component.spec.ts +++ b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/route-not-found/feature/route-not-found.component.spec.ts @@ -18,6 +18,9 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { RouteNotFound } from './route-not-found.component'; +import { PageContent } from '../../../ui/common/page-content/page-content.component'; +import { HttpClientTestingModule } from '@angular/common/http/testing'; +import { RouterTestingModule } from '@angular/router/testing'; describe('RouteNotFound', () => { let component: RouteNotFound; @@ -25,7 +28,8 @@ describe('RouteNotFound', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [RouteNotFound] + declarations: [RouteNotFound], + imports: [PageContent, HttpClientTestingModule, RouterTestingModule] }).compileComponents(); fixture = TestBed.createComponent(RouteNotFound); diff --git a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/registry-clients/edit-registry-client/edit-registry-client.component.html b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/registry-clients/edit-registry-client/edit-registry-client.component.html index 250f6bb8e7..3a8f856d8a 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/registry-clients/edit-registry-client/edit-registry-client.component.html +++ b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/registry-clients/edit-registry-client/edit-registry-client.component.html @@ -61,7 +61,6 @@ formControlName="properties" [createNewProperty]="createNewProperty" [createNewService]="createNewService" - [getParameters]="getParameters" [goToService]="goToService" [supportsSensitiveDynamicProperties]=" request.registryClient.component.supportsSensitiveDynamicProperties diff --git a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/registry-clients/edit-registry-client/edit-registry-client.component.ts b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/registry-clients/edit-registry-client/edit-registry-client.component.ts index 9111959bb4..3c2041b1d5 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/registry-clients/edit-registry-client/edit-registry-client.component.ts +++ b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/registry-clients/edit-registry-client/edit-registry-client.component.ts @@ -26,7 +26,6 @@ import { Observable } from 'rxjs'; import { InlineServiceCreationRequest, InlineServiceCreationResponse, - Parameter, Property, RegistryClientEntity } from '../../../../../state/shared'; @@ -65,7 +64,6 @@ import { ClusterConnectionService } from '../../../../../service/cluster-connect export class EditRegistryClient { @Input() createNewProperty!: (existingProperties: string[], allowsSensitive: boolean) => Observable; @Input() createNewService!: (request: InlineServiceCreationRequest) => Observable; - @Input() getParameters!: (sensitive: boolean) => Observable; @Input() goToService!: (serviceId: string) => void; @Input() saving$!: Observable; @Output() editRegistryClient: EventEmitter = diff --git a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/service/interceptors/polling.interceptor.ts b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/service/interceptors/polling.interceptor.ts index f56b5110d0..0868390668 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/service/interceptors/polling.interceptor.ts +++ b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/service/interceptors/polling.interceptor.ts @@ -22,6 +22,7 @@ import { NiFiState } from '../../state'; import { Store } from '@ngrx/store'; import { stopCurrentUserPolling } from '../../state/current-user/current-user.actions'; import { stopProcessGroupPolling } from '../../pages/flow-designer/state/flow/flow.actions'; +import { stopClusterSummaryPolling } from '../../state/cluster-summary/cluster-summary.actions'; @Injectable({ providedIn: 'root' @@ -36,6 +37,7 @@ export class PollingInterceptor implements HttpInterceptor { if (error instanceof HttpErrorResponse && error.status === 0) { this.store.dispatch(stopCurrentUserPolling()); this.store.dispatch(stopProcessGroupPolling()); + this.store.dispatch(stopClusterSummaryPolling()); } } }) diff --git a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/state/shared/index.ts b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/state/shared/index.ts index b5415c47fc..9680c37d6c 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/state/shared/index.ts +++ b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/state/shared/index.ts @@ -337,6 +337,31 @@ export interface Parameter { inherited?: boolean; } +export interface ParameterContextEntity { + revision: Revision; + permissions: Permissions; + id: string; + uri: string; + component: ParameterContext; +} + +export interface ParameterContext { + id: string; + name: string; + description: string; + parameters: ParameterEntity[]; + boundProcessGroups: BoundProcessGroup[]; + inheritedParameterContexts: ParameterContextReferenceEntity[]; + parameterProviderConfiguration?: ParameterProviderConfigurationEntity; +} + +// TODO - Replace this with ProcessGroupEntity was available +export interface BoundProcessGroup { + permissions: Permissions; + id: string; + component: any; +} + export interface ParameterContextReferenceEntity { permissions: Permissions; id: string; @@ -388,6 +413,7 @@ export interface ParameterContextUpdateRequest { updateSteps: any[]; uri: string; parameterContext?: any; + failureReason?: string; } export interface ParameterContextUpdateRequestEntity { diff --git a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/controller-service/edit-controller-service/edit-controller-service.component.html b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/controller-service/edit-controller-service/edit-controller-service.component.html index c570998641..147d1f1d5e 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/controller-service/edit-controller-service/edit-controller-service.component.html +++ b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/controller-service/edit-controller-service/edit-controller-service.component.html @@ -120,7 +120,6 @@ formControlName="properties" [createNewProperty]="createNewProperty" [createNewService]="createNewService" - [getParameters]="getParameters" [parameterContext]="parameterContext" [goToParameter]="goToParameter" [convertToParameter]="convertToParameter" diff --git a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/controller-service/edit-controller-service/edit-controller-service.component.ts b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/controller-service/edit-controller-service/edit-controller-service.component.ts index b5c8d39d33..1d3a171075 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/controller-service/edit-controller-service/edit-controller-service.component.ts +++ b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/controller-service/edit-controller-service/edit-controller-service.component.ts @@ -25,8 +25,7 @@ import { EditControllerServiceDialogRequest, InlineServiceCreationRequest, InlineServiceCreationResponse, - Parameter, - ParameterContextReferenceEntity, + ParameterContextEntity, Property, UpdateControllerServiceRequest } from '../../../../state/shared'; @@ -47,6 +46,7 @@ import { ErrorBanner } from '../../error-banner/error-banner.component'; import { ClusterConnectionService } from '../../../../service/cluster-connection.service'; import { TextTip } from '../../tooltips/text-tip/text-tip.component'; import { NifiTooltipDirective } from '../../tooltips/nifi-tooltip.directive'; +import { ConvertToParameterResponse } from '../../../../pages/flow-designer/service/parameter-helper.service'; @Component({ selector: 'edit-controller-service', @@ -74,10 +74,13 @@ import { NifiTooltipDirective } from '../../tooltips/nifi-tooltip.directive'; export class EditControllerService { @Input() createNewProperty!: (existingProperties: string[], allowsSensitive: boolean) => Observable; @Input() createNewService!: (request: InlineServiceCreationRequest) => Observable; - @Input() getParameters!: (sensitive: boolean) => Observable; - @Input() parameterContext: ParameterContextReferenceEntity | undefined; + @Input() parameterContext: ParameterContextEntity | undefined; @Input() goToParameter!: (parameter: string) => void; - @Input() convertToParameter!: (name: string, sensitive: boolean, value: string | null) => Observable; + @Input() convertToParameter!: ( + name: string, + sensitive: boolean, + value: string | null + ) => Observable; @Input() goToService!: (serviceId: string) => void; @Input() goToReferencingComponent!: (component: ControllerServiceReferencingComponent) => void; @Input() saving$!: Observable; diff --git a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/property-table/editors/combo-editor/combo-editor.component.html b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/property-table/editors/combo-editor/combo-editor.component.html index 194d2c50af..3a48cd26e5 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/property-table/editors/combo-editor/combo-editor.component.html +++ b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/property-table/editors/combo-editor/combo-editor.component.html @@ -63,51 +63,46 @@
-
- -
- - - Parameter - - - - - {{ parameterAllowableValue.displayName }} - - - - - {{ parameterAllowableValue.displayName }} - - + + Parameter + + + + + {{ parameterAllowableValue.displayName }} + - - - + + + {{ parameterAllowableValue.displayName }} + + + + +
@if (readonly) { diff --git a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/property-table/editors/combo-editor/combo-editor.component.spec.ts b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/property-table/editors/combo-editor/combo-editor.component.spec.ts index 6a2ed67447..53cbb0a74e 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/property-table/editors/combo-editor/combo-editor.component.spec.ts +++ b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/property-table/editors/combo-editor/combo-editor.component.spec.ts @@ -20,7 +20,6 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { ComboEditor } from './combo-editor.component'; import { PropertyItem } from '../../property-table.component'; import { Parameter } from '../../../../../state/shared'; -import { of } from 'rxjs'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; describe('ComboEditor', () => { @@ -186,9 +185,7 @@ describe('ComboEditor', () => { item.value = '#{one}'; component.item = item; - component.getParameters = () => { - return of(parameters); - }; + component.parameters = parameters; fixture.detectChanges(); fixture.whenStable().then(() => { const formValue = component.comboEditorForm.get('value')?.value; @@ -210,9 +207,7 @@ describe('ComboEditor', () => { item.value = '#{three}'; component.item = item; - component.getParameters = () => { - return of(parameters); - }; + component.parameters = parameters; fixture.detectChanges(); fixture.whenStable().then(() => { const formValue = component.comboEditorForm.get('value')?.value; diff --git a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/property-table/editors/combo-editor/combo-editor.component.ts b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/property-table/editors/combo-editor/combo-editor.component.ts index 61508d13c6..460ec4b58d 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/property-table/editors/combo-editor/combo-editor.component.ts +++ b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/property-table/editors/combo-editor/combo-editor.component.ts @@ -31,7 +31,6 @@ import { MatSelectModule } from '@angular/material/select'; import { MatTooltipModule } from '@angular/material/tooltip'; import { TextTip } from '../../../tooltips/text-tip/text-tip.component'; import { A11yModule } from '@angular/cdk/a11y'; -import { Observable, take } from 'rxjs'; import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader'; export interface AllowableValueItem extends AllowableValue { @@ -77,10 +76,10 @@ export class ComboEditor { this.initialAllowableValues(); } - @Input() set getParameters(getParameters: (sensitive: boolean) => Observable) { - this._getParameters = getParameters; + @Input() set parameters(parameters: Parameter[]) { + this._parameters = parameters; - this.supportsParameters = getParameters != null; + this.supportsParameters = parameters != null; this.initialAllowableValues(); } @Input() width!: number; @@ -104,11 +103,10 @@ export class ComboEditor { sensitive = false; supportsParameters = false; - parametersLoaded = false; itemSet = false; configuredValue: string | null = null; - _getParameters!: (sensitive: boolean) => Observable; + _parameters!: Parameter[]; constructor(private formBuilder: FormBuilder) { this.comboEditorForm = this.formBuilder.group({ @@ -159,8 +157,6 @@ export class ComboEditor { } if (this.supportsParameters) { - this.parametersLoaded = false; - // parameters are supported so add the item to support showing // and hiding the parameter options select const referencesParameterOption: AllowableValueItem = { @@ -183,40 +179,35 @@ export class ComboEditor { this.allowableValueChanged(this.referencesParametersId); } - this._getParameters(this.sensitive) - .pipe(take(1)) - .subscribe((parameters) => { - if (parameters.length > 0) { - // capture the value of i which will be the id of the first - // parameter - this.configuredParameterId = i; + const parameters: Parameter[] = this._parameters; + if (parameters.length > 0) { + // capture the value of i which will be the id of the first + // parameter + this.configuredParameterId = i; - // create allowable values for each parameter - parameters.forEach((parameter) => { - const parameterItem: AllowableValueItem = { - id: i++, - displayName: parameter.name, - value: '#{' + parameter.name + '}', - description: parameter.description - }; - this.parameterAllowableValues.push(parameterItem); - this.itemLookup.set(parameterItem.id, parameterItem); + // create allowable values for each parameter + parameters.forEach((parameter) => { + const parameterItem: AllowableValueItem = { + id: i++, + displayName: parameter.name, + value: `#{${parameter.name}}`, + description: parameter.description + }; + this.parameterAllowableValues.push(parameterItem); + this.itemLookup.set(parameterItem.id, parameterItem); - // if the configured parameter is still available, - // capture the id, so we can auto select it - if (parameterItem.value === this.configuredValue) { - this.configuredParameterId = parameterItem.id; - } - }); - - // if combo still set to reference a parameter, set the default value - if (this.comboEditorForm.get('value')?.value == this.referencesParametersId) { - this.comboEditorForm.get('parameterReference')?.setValue(this.configuredParameterId); - } + // if the configured parameter is still available, + // capture the id, so we can auto select it + if (parameterItem.value === this.configuredValue) { + this.configuredParameterId = parameterItem.id; } - - this.parametersLoaded = true; }); + + // if combo still set to reference a parameter, set the default value + if (selectedItem?.id == this.referencesParametersId) { + this.comboEditorForm.get('parameterReference')?.setValue(this.configuredParameterId); + } + } } else { this.parameterAllowableValues = []; } diff --git a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/property-table/editors/nf-editor/nf-editor.component.ts b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/property-table/editors/nf-editor/nf-editor.component.ts index ebc0c9568e..1cecd2f2ad 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/property-table/editors/nf-editor/nf-editor.component.ts +++ b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/property-table/editors/nf-editor/nf-editor.component.ts @@ -29,7 +29,6 @@ import { PropertyHintTip } from '../../../tooltips/property-hint-tip/property-hi import { Parameter, PropertyHintTipInput } from '../../../../../state/shared'; import { A11yModule } from '@angular/cdk/a11y'; import { CodemirrorModule } from '@ctrl/ngx-codemirror'; -import { Observable, take } from 'rxjs'; import { NfEl } from './modes/nfel'; import { NfPr } from './modes/nfpr'; import { Editor } from 'codemirror'; @@ -75,8 +74,8 @@ export class NfEditor implements OnDestroy { this.loadParameters(); } - @Input() set getParameters(getParameters: (sensitive: boolean) => Observable) { - this._getParameters = getParameters; + @Input() set parameters(parameters: Parameter[]) { + this._parameters = parameters; this.getParametersSet = true; this.loadParameters(); @@ -98,7 +97,7 @@ export class NfEditor implements OnDestroy { supportsParameters = false; mode!: string; - _getParameters!: (sensitive: boolean) => Observable; + _parameters!: Parameter[]; editor!: Editor; @@ -127,22 +126,19 @@ export class NfEditor implements OnDestroy { this.nfpr.setViewContainerRef(this.viewContainerRef, this.renderer); if (this.getParametersSet) { - if (this._getParameters) { + if (this._parameters) { this.supportsParameters = true; - this._getParameters(this.sensitive) - .pipe(take(1)) - .subscribe((parameters) => { - if (this.supportsEl) { - this.nfel.enableParameters(); - this.nfel.setParameters(parameters); - this.nfel.configureAutocomplete(); - } else { - this.nfpr.enableParameters(); - this.nfpr.setParameters(parameters); - this.nfpr.configureAutocomplete(); - } - }); + const parameters: Parameter[] = this._parameters; + if (this.supportsEl) { + this.nfel.enableParameters(); + this.nfel.setParameters(parameters); + this.nfel.configureAutocomplete(); + } else { + this.nfpr.enableParameters(); + this.nfpr.setParameters(parameters); + this.nfpr.configureAutocomplete(); + } } else { this.supportsParameters = false; diff --git a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/property-table/property-table.component.html b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/property-table/property-table.component.html index e13b73db36..ae041f2b9b 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/property-table/property-table.component.html +++ b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/property-table/property-table.component.html @@ -159,7 +159,7 @@ @if (hasAllowableValues(editorItem)) { Observable; @Input() createNewService!: (request: InlineServiceCreationRequest) => Observable; - @Input() getParameters!: (sensitive: boolean) => Observable; - @Input() parameterContext: ParameterContextReferenceEntity | undefined; + @Input() parameterContext: ParameterContextEntity | undefined; @Input() goToParameter!: (parameter: string) => void; - @Input() convertToParameter!: (name: string, sensitive: boolean, value: string | null) => Observable; + @Input() convertToParameter!: ( + name: string, + sensitive: boolean, + value: string | null + ) => Observable; @Input() goToService!: (serviceId: string) => void; @Input() supportsSensitiveDynamicProperties = false; @Input() propertyHistory: ComponentHistory | undefined; @@ -129,6 +133,7 @@ export class PropertyTable implements AfterViewInit, ControlValueAccessor { editorOpen = false; editorTrigger: any = null; editorItem!: PropertyItem; + editorParameters: Parameter[] = []; editorWidth = 0; editorOffsetX = 0; editorOffsetY = 0; @@ -215,18 +220,49 @@ export class PropertyTable implements AfterViewInit, ControlValueAccessor { return false; } - // if the dependent item is visible, but does not require a specific - // dependent value consider the dependency met - if (this.nifiCommon.isEmpty(dependency.dependentValues)) { + // if the dependent item is sensitive, in this case we are lenient and + // consider the dependency met + if (dependentItem.descriptor.sensitive) { return true; } - // TODO resolve parameter value in dependentItem if necessary + // ensure the dependent item has a value + let dependentValue = dependentItem.value; + if (dependentValue != null) { + // check if the dependent value is a parameter reference + if (PropertyTable.PARAM_REF_REGEX.test(dependentValue)) { + // the dependent value contains parameter reference, if the user can view + // the parameter context resolve the parameter value to see if it + // satisfies the dependent values + if (this.parameterContext?.permissions.canRead) { + const referencedParameter = this.parameterContext.component.parameters + .map((parameterEntity) => parameterEntity.parameter) + .find((parameter: Parameter) => dependentValue == `#{${parameter.name}}`); - // if the dependent item has a value, see if it is present in the - // allowed dependent value. if so, consider the dependency met - if (dependentItem.value) { - return dependency.dependentValues.includes(dependentItem.value); + // if we found a matching parameter then we'll use its value when determining if the + // dependency is satisfied. if a matching parameter was not found we'll continue using + // the dependent property value + if (referencedParameter) { + dependentValue = referencedParameter.value; + } + } else { + // the user lacks permissions to the parameter context so we cannot + // verify if the dependency is satisfied, in this case we are lenient + // and consider the dependency met + return true; + } + } + + // ensure the dependent item has a value + if (dependentValue != null) { + if (this.nifiCommon.isEmpty(dependency.dependentValues)) { + // if the dependency does not require a specific value, consider the dependency met + return true; + } else { + // see if value is present in the allowed dependent values. if so, consider the dependency met. + return dependency.dependentValues.includes(dependentValue); + } + } } // if the dependent item does not have a value, consider the @@ -279,6 +315,16 @@ export class PropertyTable implements AfterViewInit, ControlValueAccessor { this.initFilter(); } + private getParametersForItem(propertyItem: PropertyItem): Parameter[] { + if (this.parameterContext?.permissions.canRead) { + return this.parameterContext.component.parameters + .map((parameterEntity) => parameterEntity.parameter) + .filter((parameter: Parameter) => parameter.sensitive == propertyItem.descriptor.sensitive); + } else { + return []; + } + } + newPropertyClicked(): void { // filter out deleted properties in case the user needs to re-add one const existingProperties: string[] = this.dataSource.data @@ -398,6 +444,7 @@ export class PropertyTable implements AfterViewInit, ControlValueAccessor { this.editorPositions.pop(); this.editorItem = item; + this.editorParameters = this.getParametersForItem(this.editorItem); this.editorTrigger = editorTrigger; this.editorOpen = true; @@ -484,10 +531,15 @@ export class PropertyTable implements AfterViewInit, ControlValueAccessor { convertToParameterClicked(item: PropertyItem): void { this.convertToParameter(item.descriptor.displayName, item.descriptor.sensitive, item.value) .pipe(take(1)) - .subscribe((propertyValue) => { - item.value = propertyValue; + .subscribe((response) => { + item.value = response.propertyValue; item.dirty = true; + // update the parameter context which includes any new parameters + if (this.parameterContext && response.parameterContext) { + this.parameterContext.component = response.parameterContext; + } + this.handleChanged(); }); }