This is an automated email from the ASF dual-hosted git repository.

rfellows pushed a commit to branch NIFI-15258
in repository https://gitbox.apache.org/repos/asf/nifi.git


The following commit(s) were added to refs/heads/NIFI-15258 by this push:
     new 2ee0178e5d NIFI-15577: Including connector id in provenance event dto. 
(#10883)
2ee0178e5d is described below

commit 2ee0178e5dee706b52acc0efe8686f9392f6b8b7
Author: Matt Gilman <[email protected]>
AuthorDate: Wed Feb 11 17:28:56 2026 -0500

    NIFI-15577: Including connector id in provenance event dto. (#10883)
    
    * NIFI-15577: Including connector id in provenance event dto.
    - Fixing go to routing logic in the provenance event table.
    
    * NIFI-15577: Fixing back navigation context when navigating to provenance 
from the flow designer.
    
    This closes #10883
---
 .../web/api/dto/provenance/ProvenanceEventDTO.java |  14 +++
 .../nifi/web/controller/ControllerFacade.java      |  16 ++-
 .../nifi/web/controller/ControllerFacadeTest.java  | 115 +++++++++++++++++++++
 .../flow-designer/feature/flow-designer.module.ts  |   4 +-
 .../service/canvas-context-menu.service.ts         |   3 +-
 .../pages/flow-designer/state/flow/flow.actions.ts |   3 +-
 .../flow-designer/state/flow/flow.effects.spec.ts  | 104 ++++++++++++++++++-
 .../pages/flow-designer/state/flow/flow.effects.ts |  10 +-
 .../state/provenance-event-listing/index.ts        |   1 +
 .../provenance-event-listing.effects.ts            |  18 +++-
 .../provenance-event-table.component.ts            |   3 +-
 11 files changed, 274 insertions(+), 17 deletions(-)

diff --git 
a/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/provenance/ProvenanceEventDTO.java
 
b/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/provenance/ProvenanceEventDTO.java
index 071ccf01be..4ce0514514 100644
--- 
a/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/provenance/ProvenanceEventDTO.java
+++ 
b/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/provenance/ProvenanceEventDTO.java
@@ -49,6 +49,7 @@ public class ProvenanceEventDTO {
     private String clusterNodeAddress; // include when clustered
 
     private String groupId;
+    private String connectorId;
     private String componentId;
     private String componentType;
     private String componentName;
@@ -217,6 +218,19 @@ public class ProvenanceEventDTO {
         this.groupId = groupId;
     }
 
+    /**
+     * @return id of the Connector that manages the component that generated 
this event, or {@code null} if the component is not managed by a Connector
+     */
+    @Schema(description = "The id of the connector that manages the component 
that generated the event. If the component is not managed by a connector, this 
will not be set."
+    )
+    public String getConnectorId() {
+        return connectorId;
+    }
+
+    public void setConnectorId(String connectorId) {
+        this.connectorId = connectorId;
+    }
+
     /**
      * @return id of the component that generated this event
      */
diff --git 
a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/controller/ControllerFacade.java
 
b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/controller/ControllerFacade.java
index 924b7ca3e6..68e73d88b7 100644
--- 
a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/controller/ControllerFacade.java
+++ 
b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/controller/ControllerFacade.java
@@ -1864,7 +1864,9 @@ public class ControllerFacade implements Authorizable {
 
         final Connectable connectable = 
findLocalConnectable(dto.getComponentId());
         if (connectable != null) {
-            dto.setGroupId(connectable.getProcessGroup().getIdentifier());
+            final ProcessGroup connectableGroup = 
connectable.getProcessGroup();
+            dto.setGroupId(connectableGroup.getIdentifier());
+            
connectableGroup.getConnectorIdentifier().ifPresent(dto::setConnectorId);
 
             // if the user is approved for this component policy, provide 
additional details, otherwise override/redact as necessary
             if 
(Result.Approved.equals(connectable.checkAuthorization(authorizer, 
RequestAction.READ, user).getResult())) {
@@ -1880,7 +1882,13 @@ public class ControllerFacade implements Authorizable {
 
         final RemoteGroupPort remoteGroupPort = 
root.findRemoteGroupPort(dto.getComponentId());
         if (remoteGroupPort != null) {
-            dto.setGroupId(remoteGroupPort.getProcessGroupIdentifier());
+            final String remoteGroupPortGroupId = 
remoteGroupPort.getProcessGroupIdentifier();
+            dto.setGroupId(remoteGroupPortGroupId);
+
+            final ProcessGroup remotePortGroup = 
root.findProcessGroup(remoteGroupPortGroupId);
+            if (remotePortGroup != null) {
+                
remotePortGroup.getConnectorIdentifier().ifPresent(dto::setConnectorId);
+            }
 
             // if the user is approved for this component policy, provide 
additional details, otherwise override/redact as necessary
             if 
(Result.Approved.equals(remoteGroupPort.checkAuthorization(authorizer, 
RequestAction.READ, user).getResult())) {
@@ -1895,7 +1903,9 @@ public class ControllerFacade implements Authorizable {
 
         final Connection connection = 
root.findConnection(dto.getComponentId());
         if (connection != null) {
-            dto.setGroupId(connection.getProcessGroup().getIdentifier());
+            final ProcessGroup connectionGroup = connection.getProcessGroup();
+            dto.setGroupId(connectionGroup.getIdentifier());
+            
connectionGroup.getConnectorIdentifier().ifPresent(dto::setConnectorId);
 
             // if the user is approved for this component policy, provide 
additional details, otherwise override/redact as necessary
             if 
(Result.Approved.equals(connection.checkAuthorization(authorizer, 
RequestAction.READ, user).getResult())) {
diff --git 
a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/web/controller/ControllerFacadeTest.java
 
b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/web/controller/ControllerFacadeTest.java
index 5dad329baf..eb43ece3ea 100644
--- 
a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/web/controller/ControllerFacadeTest.java
+++ 
b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/web/controller/ControllerFacadeTest.java
@@ -16,6 +16,10 @@
  */
 package org.apache.nifi.web.controller;
 
+import org.apache.nifi.authorization.AuthorizationResult;
+import org.apache.nifi.authorization.Authorizer;
+import org.apache.nifi.authorization.RequestAction;
+import org.apache.nifi.authorization.resource.Authorizable;
 import org.apache.nifi.authorization.user.NiFiUser;
 import org.apache.nifi.authorization.user.NiFiUserDetails;
 import org.apache.nifi.authorization.user.StandardNiFiUser;
@@ -23,8 +27,16 @@ import org.apache.nifi.c2.protocol.component.api.Bundle;
 import org.apache.nifi.c2.protocol.component.api.ComponentManifest;
 import org.apache.nifi.c2.protocol.component.api.ConnectorDefinition;
 import org.apache.nifi.c2.protocol.component.api.RuntimeManifest;
+import org.apache.nifi.connectable.Connectable;
+import org.apache.nifi.controller.FlowController;
+import org.apache.nifi.controller.flow.FlowManager;
 import org.apache.nifi.groups.ProcessGroup;
 import org.apache.nifi.manifest.RuntimeManifestService;
+import org.apache.nifi.provenance.ProvenanceAuthorizableFactory;
+import org.apache.nifi.provenance.ProvenanceEventRecord;
+import org.apache.nifi.provenance.ProvenanceEventType;
+import org.apache.nifi.provenance.ProvenanceRepository;
+import org.apache.nifi.web.api.dto.provenance.ProvenanceEventDTO;
 import org.apache.nifi.web.api.dto.search.SearchResultsDTO;
 import org.apache.nifi.web.search.query.SearchQuery;
 import org.apache.nifi.web.search.query.SearchQueryParser;
@@ -36,14 +48,18 @@ import org.mockito.Mock;
 import org.mockito.junit.jupiter.MockitoExtension;
 import org.springframework.security.core.context.SecurityContextHolder;
 
+import java.io.IOException;
 import java.util.Collections;
 import java.util.List;
+import java.util.Map;
+import java.util.Optional;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertNotNull;
 import static org.junit.jupiter.api.Assertions.assertNull;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
@@ -186,5 +202,104 @@ public class ControllerFacadeTest {
 
         assertNull(result);
     }
+
+    @Test
+    public void 
testGetProvenanceEventSetsConnectorIdWhenComponentBelongsToConnector() throws 
IOException {
+        final String componentId = "test-component-id";
+        final String groupId = "test-group-id";
+        final String connectorId = "test-connector-id";
+
+        final ControllerFacade facade = createProvenanceFacade(componentId, 
groupId, Optional.of(connectorId));
+
+        final ProvenanceEventDTO result = facade.getProvenanceEvent(1L);
+
+        assertNotNull(result);
+        assertEquals(connectorId, result.getConnectorId());
+        assertEquals(groupId, result.getGroupId());
+        assertEquals(componentId, result.getComponentId());
+    }
+
+    @Test
+    public void 
testGetProvenanceEventConnectorIdIsNullWhenComponentNotManagedByConnector() 
throws IOException {
+        final String componentId = "test-component-id";
+        final String groupId = "test-group-id";
+
+        final ControllerFacade facade = createProvenanceFacade(componentId, 
groupId, Optional.empty());
+
+        final ProvenanceEventDTO result = facade.getProvenanceEvent(1L);
+
+        assertNotNull(result);
+        assertNull(result.getConnectorId());
+        assertEquals(groupId, result.getGroupId());
+        assertEquals(componentId, result.getComponentId());
+    }
+
+    /**
+     * Creates a ControllerFacade wired with mocks sufficient to test 
provenance event creation
+     * through the connectable branch of setComponentDetails.
+     */
+    private ControllerFacade createProvenanceFacade(final String componentId, 
final String groupId,
+                                                     final Optional<String> 
connectorIdentifier) throws IOException {
+        // Mock the ProvenanceEventRecord
+        final ProvenanceEventRecord event = mock(ProvenanceEventRecord.class);
+        when(event.getEventId()).thenReturn(1L);
+        when(event.getEventTime()).thenReturn(System.currentTimeMillis());
+        when(event.getEventType()).thenReturn(ProvenanceEventType.CREATE);
+        when(event.getFlowFileUuid()).thenReturn("test-flowfile-uuid");
+        when(event.getFileSize()).thenReturn(1024L);
+        when(event.getComponentId()).thenReturn(componentId);
+        when(event.getComponentType()).thenReturn("TestProcessor");
+        when(event.getUpdatedAttributes()).thenReturn(Map.of());
+        when(event.getPreviousAttributes()).thenReturn(Map.of());
+        when(event.getParentUuids()).thenReturn(List.of());
+        when(event.getChildUuids()).thenReturn(List.of());
+        when(event.getEventDuration()).thenReturn(-1L);
+        when(event.getLineageStartDate()).thenReturn(0L);
+
+        // Mock the ProcessGroup that the connectable belongs to
+        final ProcessGroup processGroup = mock(ProcessGroup.class);
+        when(processGroup.getIdentifier()).thenReturn(groupId);
+        
when(processGroup.getConnectorIdentifier()).thenReturn(connectorIdentifier);
+
+        // Mock a Connectable found in the flow
+        final Connectable connectable = mock(Connectable.class);
+        when(connectable.getProcessGroup()).thenReturn(processGroup);
+        when(connectable.getName()).thenReturn("Test Component");
+        when(connectable.checkAuthorization(any(), any(), 
any())).thenReturn(AuthorizationResult.approved());
+
+        // Mock FlowManager
+        final FlowManager flowManager = mock(FlowManager.class);
+        when(flowManager.findConnectable(componentId)).thenReturn(connectable);
+        when(flowManager.getRootGroup()).thenReturn(mock(ProcessGroup.class));
+
+        // Mock ProvenanceRepository
+        final ProvenanceRepository provenanceRepository = 
mock(ProvenanceRepository.class);
+        when(provenanceRepository.getEvent(eq(1L), 
any(NiFiUser.class))).thenReturn(event);
+
+        // Mock data authorization as not approved so we skip content 
availability logic
+        final Authorizable dataAuthorizable = mock(Authorizable.class);
+        when(dataAuthorizable.checkAuthorization(any(), 
eq(RequestAction.READ), any(NiFiUser.class), any()))
+                .thenReturn(AuthorizationResult.denied("test"));
+
+        // Mock ProvenanceAuthorizableFactory
+        final ProvenanceAuthorizableFactory provenanceAuthorizableFactory = 
mock(ProvenanceAuthorizableFactory.class);
+        
when(provenanceAuthorizableFactory.createLocalDataAuthorizable(componentId)).thenReturn(dataAuthorizable);
+
+        // Mock FlowController
+        final FlowController flowController = mock(FlowController.class);
+        when(flowController.getFlowManager()).thenReturn(flowManager);
+        
when(flowController.getProvenanceRepository()).thenReturn(provenanceRepository);
+        
when(flowController.getProvenanceAuthorizableFactory()).thenReturn(provenanceAuthorizableFactory);
+
+        // Mock Authorizer
+        final Authorizer authorizer = mock(Authorizer.class);
+
+        // Build the ControllerFacade
+        final ControllerFacade facade = new ControllerFacade();
+        facade.setFlowController(flowController);
+        facade.setAuthorizer(authorizer);
+
+        return facade;
+    }
 }
 
diff --git 
a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/feature/flow-designer.module.ts
 
b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/feature/flow-designer.module.ts
index d68b3c9f75..bb3e63033a 100644
--- 
a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/feature/flow-designer.module.ts
+++ 
b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/feature/flow-designer.module.ts
@@ -30,6 +30,7 @@ import { ParameterEffects } from 
'../state/parameter/parameter.effects';
 import { QueueEffects } from '../state/queue/queue.effects';
 import { BannerText } from 
'../../../ui/common/banner-text/banner-text.component';
 import { FlowAnalysisEffects } from 
'../state/flow-analysis/flow-analysis.effects';
+import { ComponentTypeNamePipe } from '@nifi/shared';
 
 @NgModule({
     declarations: [FlowDesigner],
@@ -49,6 +50,7 @@ import { FlowAnalysisEffects } from 
'../state/flow-analysis/flow-analysis.effect
         NgOptimizedImage,
         MatDialogModule,
         BannerText
-    ]
+    ],
+    providers: [ComponentTypeNamePipe]
 })
 export class FlowDesignerModule {}
diff --git 
a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/service/canvas-context-menu.service.ts
 
b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/service/canvas-context-menu.service.ts
index ab7cdbe04b..2e8baea059 100644
--- 
a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/service/canvas-context-menu.service.ts
+++ 
b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/service/canvas-context-menu.service.ts
@@ -887,7 +887,8 @@ export class CanvasContextMenu implements 
ContextMenuDefinitionProvider {
                     const selectionData = selection.datum();
                     this.store.dispatch(
                         navigateToProvenanceForComponent({
-                            id: selectionData.id
+                            id: selectionData.id,
+                            componentType: selectionData.type
                         })
                     );
                 }
diff --git 
a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/state/flow/flow.actions.ts
 
b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/state/flow/flow.actions.ts
index 32614579b6..efb96845ed 100644
--- 
a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/state/flow/flow.actions.ts
+++ 
b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/state/flow/flow.actions.ts
@@ -120,6 +120,7 @@ import {
 } from '../../../../state/shared';
 import { ErrorContext } from '../../../../state/error';
 import { CopyResponseContext, CopyResponseEntity } from 
'../../../../state/copy';
+import { ComponentType } from '@nifi/shared';
 
 const CANVAS_PREFIX = '[Canvas]';
 
@@ -608,7 +609,7 @@ export const renderConnectionsForComponent = createAction(
 
 export const navigateToProvenanceForComponent = createAction(
     `${CANVAS_PREFIX} Navigate To Provenance For Component`,
-    props<{ id: string }>()
+    props<{ id: string; componentType: ComponentType }>()
 );
 
 export const replayLastProvenanceEvent = createAction(
diff --git 
a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/state/flow/flow.effects.spec.ts
 
b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/state/flow/flow.effects.spec.ts
index ba287885d7..70cf7bcc71 100644
--- 
a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/state/flow/flow.effects.spec.ts
+++ 
b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/state/flow/flow.effects.spec.ts
@@ -58,9 +58,10 @@ import { CopyPasteService } from 
'../../service/copy-paste.service';
 import { CanvasView } from '../../service/canvas-view.service';
 import { BirdseyeView } from '../../service/birdseye-view.service';
 import { selectDisconnectionAcknowledged } from 
'../../../../state/cluster-summary/cluster-summary.selectors';
-import { ComponentType } from '@nifi/shared';
+import { ComponentType, ComponentTypeNamePipe } from '@nifi/shared';
 import { ParameterContextService } from 
'../../../parameter-contexts/service/parameter-contexts.service';
 import { HttpErrorResponse } from '@angular/common/http';
+import { provideRouter, Router } from '@angular/router';
 import { ErrorHelper } from '../../../../service/error-helper.service';
 import { selectConnectedStateChanged } from 
'../../../../state/cluster-summary/cluster-summary.selectors';
 
@@ -775,6 +776,8 @@ describe('FlowEffects', () => {
             imports: [],
             providers: [
                 FlowEffects,
+                ComponentTypeNamePipe,
+                provideRouter([]),
                 provideMockActions(() => action$),
                 provideMockStore({
                     selectors: [
@@ -1182,4 +1185,103 @@ describe('FlowEffects', () => {
             );
         });
     });
+
+    describe('navigateToProvenanceForComponent$', () => {
+        let router: Router;
+
+        beforeEach(() => {
+            router = TestBed.inject(Router);
+            jest.spyOn(router, 'navigate').mockImplementation(() => 
Promise.resolve(true));
+            store.overrideSelector(selectCurrentProcessGroupId, 'pg-123');
+            store.refreshState();
+        });
+
+        it('should navigate to provenance with Processor type in back 
navigation route and context', () => {
+            effects.navigateToProvenanceForComponent$.subscribe();
+
+            action$.next(
+                FlowActions.navigateToProvenanceForComponent({
+                    id: 'comp-1',
+                    componentType: ComponentType.Processor
+                })
+            );
+
+            expect(router.navigate).toHaveBeenCalledWith(['/provenance'], {
+                queryParams: { componentId: 'comp-1' },
+                state: {
+                    backNavigation: {
+                        route: ['/process-groups', 'pg-123', 
ComponentType.Processor, 'comp-1'],
+                        routeBoundary: ['/provenance'],
+                        context: 'Processor'
+                    }
+                }
+            });
+        });
+
+        it('should navigate to provenance with Funnel type in back navigation 
route and context', () => {
+            effects.navigateToProvenanceForComponent$.subscribe();
+
+            action$.next(
+                FlowActions.navigateToProvenanceForComponent({
+                    id: 'funnel-1',
+                    componentType: ComponentType.Funnel
+                })
+            );
+
+            expect(router.navigate).toHaveBeenCalledWith(['/provenance'], {
+                queryParams: { componentId: 'funnel-1' },
+                state: {
+                    backNavigation: {
+                        route: ['/process-groups', 'pg-123', 
ComponentType.Funnel, 'funnel-1'],
+                        routeBoundary: ['/provenance'],
+                        context: 'Funnel'
+                    }
+                }
+            });
+        });
+
+        it('should navigate to provenance with InputPort type in back 
navigation route and context', () => {
+            effects.navigateToProvenanceForComponent$.subscribe();
+
+            action$.next(
+                FlowActions.navigateToProvenanceForComponent({
+                    id: 'port-1',
+                    componentType: ComponentType.InputPort
+                })
+            );
+
+            expect(router.navigate).toHaveBeenCalledWith(['/provenance'], {
+                queryParams: { componentId: 'port-1' },
+                state: {
+                    backNavigation: {
+                        route: ['/process-groups', 'pg-123', 
ComponentType.InputPort, 'port-1'],
+                        routeBoundary: ['/provenance'],
+                        context: 'Input Port'
+                    }
+                }
+            });
+        });
+
+        it('should navigate to provenance with OutputPort type in back 
navigation route and context', () => {
+            effects.navigateToProvenanceForComponent$.subscribe();
+
+            action$.next(
+                FlowActions.navigateToProvenanceForComponent({
+                    id: 'port-2',
+                    componentType: ComponentType.OutputPort
+                })
+            );
+
+            expect(router.navigate).toHaveBeenCalledWith(['/provenance'], {
+                queryParams: { componentId: 'port-2' },
+                state: {
+                    backNavigation: {
+                        route: ['/process-groups', 'pg-123', 
ComponentType.OutputPort, 'port-2'],
+                        routeBoundary: ['/provenance'],
+                        context: 'Output Port'
+                    }
+                }
+            });
+        });
+    });
 });
diff --git 
a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/state/flow/flow.effects.ts
 
b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/state/flow/flow.effects.ts
index 94553f29f7..bef4fb79ab 100644
--- 
a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/state/flow/flow.effects.ts
+++ 
b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/flow-designer/state/flow/flow.effects.ts
@@ -128,6 +128,7 @@ import { EditProcessGroup } from 
'../../ui/canvas/items/process-group/edit-proce
 import { ControllerServiceService } from 
'../../service/controller-service.service';
 import {
     ComponentType,
+    ComponentTypeNamePipe,
     isDefinedAndNotNull,
     LARGE_DIALOG,
     MEDIUM_DIALOG,
@@ -200,6 +201,7 @@ export class FlowEffects {
     private parameterContextService = inject(ParameterContextService);
     private extensionTypesService = inject(ExtensionTypesService);
     private errorHelper = inject(ErrorHelper);
+    private componentTypeNamePipe = inject(ComponentTypeNamePipe);
     private copyPasteService = inject(CopyPasteService);
 
     private createProcessGroupDialogRef: MatDialogRef<CreateProcessGroup, any> 
| undefined;
@@ -2968,16 +2970,16 @@ export class FlowEffects {
         () =>
             this.actions$.pipe(
                 ofType(FlowActions.navigateToProvenanceForComponent),
-                map((action) => action.id),
+                map((action) => ({ id: action.id, componentType: 
action.componentType })),
                 concatLatestFrom(() => 
this.store.select(selectCurrentProcessGroupId)),
-                tap(([componentId, processGroupId]) => {
+                tap(([{ id: componentId, componentType }, processGroupId]) => {
                     this.router.navigate(['/provenance'], {
                         queryParams: { componentId },
                         state: {
                             backNavigation: {
-                                route: ['/process-groups', processGroupId, 
ComponentType.Processor, componentId],
+                                route: ['/process-groups', processGroupId, 
componentType, componentId],
                                 routeBoundary: ['/provenance'],
-                                context: 'Processor'
+                                context: 
this.componentTypeNamePipe.transform(componentType)
                             } as BackNavigation
                         }
                     });
diff --git 
a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/provenance/state/provenance-event-listing/index.ts
 
b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/provenance/state/provenance-event-listing/index.ts
index 8cb87708e5..f8d95b4fba 100644
--- 
a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/provenance/state/provenance-event-listing/index.ts
+++ 
b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/provenance/state/provenance-event-listing/index.ts
@@ -41,6 +41,7 @@ export interface ProvenanceEventRequest {
 export interface GoToProvenanceEventSourceRequest {
     eventId?: number;
     componentId?: string;
+    componentType?: string;
     groupId?: string;
     clusterNodeId?: string;
 }
diff --git 
a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/provenance/state/provenance-event-listing/provenance-event-listing.effects.ts
 
b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/provenance/state/provenance-event-listing/provenance-event-listing.effects.ts
index 46cb2e7915..9ff84a4d93 100644
--- 
a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/provenance/state/provenance-event-listing/provenance-event-listing.effects.ts
+++ 
b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/provenance/state/provenance-event-listing/provenance-event-listing.effects.ts
@@ -444,7 +444,9 @@ export class ProvenanceEventListingEffects {
                         
this.provenanceService.getProvenanceEvent(request.eventId, 
request.clusterNodeId).subscribe({
                             next: (response) => {
                                 const event: any = response.provenanceEvent;
-                                
this.router.navigate(this.getEventComponentLink(event.groupId, 
event.componentId));
+                                this.router.navigate(
+                                    this.getEventComponentLink(event.groupId, 
event.componentId, event.componentType)
+                                );
                             },
                             error: (errorResponse: HttpErrorResponse) => {
                                 this.store.dispatch(
@@ -455,7 +457,9 @@ export class ProvenanceEventListingEffects {
                             }
                         });
                     } else if (request.groupId && request.componentId) {
-                        
this.router.navigate(this.getEventComponentLink(request.groupId, 
request.componentId));
+                        this.router.navigate(
+                            this.getEventComponentLink(request.groupId, 
request.componentId, request.componentType)
+                        );
                     }
                 })
             ),
@@ -495,15 +499,19 @@ export class ProvenanceEventListingEffects {
         { dispatch: false }
     );
 
-    private getEventComponentLink(groupId: string, componentId: string): 
string[] {
+    private getEventComponentLink(groupId: string, componentId: string, 
componentType?: string): string[] {
         let link: string[];
 
         if (groupId == componentId) {
             link = ['/process-groups', componentId];
-        } else if (componentId === 'Connection' || componentId === 'Load 
Balanced Connection') {
+        } else if (componentType === 'Connection' || componentType === 'Load 
Balanced Connection') {
             link = ['/process-groups', groupId, 'Connection', componentId];
-        } else if (componentId === 'Output Port') {
+        } else if (componentType === 'Output Port') {
             link = ['/process-groups', groupId, 'OutputPort', componentId];
+        } else if (componentType === 'Input Port') {
+            link = ['/process-groups', groupId, 'InputPort', componentId];
+        } else if (componentType === 'Funnel') {
+            link = ['/process-groups', groupId, 'Funnel', componentId];
         } else {
             link = ['/process-groups', groupId, 'Processor', componentId];
         }
diff --git 
a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/provenance/ui/provenance-event-listing/provenance-event-table/provenance-event-table.component.ts
 
b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/provenance/ui/provenance-event-listing/provenance-event-table/provenance-event-table.component.ts
index e2df47bb35..adb6266130 100644
--- 
a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/provenance/ui/provenance-event-listing/provenance-event-table/provenance-event-table.component.ts
+++ 
b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/provenance/ui/provenance-event-listing/provenance-event-table/provenance-event-table.component.ts
@@ -338,12 +338,13 @@ export class ProvenanceEventTable implements 
AfterViewInit {
             return false;
         }
 
-        return !(event.componentId === 'Remote Output Port' || 
event.componentId === 'Remote Input Port');
+        return !(event.componentType === 'Remote Output Port' || 
event.componentType === 'Remote Input Port');
     }
 
     goToClicked(event: ProvenanceEventSummary): void {
         this.goToEventSource({
             componentId: event.componentId,
+            componentType: event.componentType,
             groupId: event.groupId
         });
     }

Reply via email to