mcgilman opened a new pull request, #11238: URL: https://github.com/apache/nifi/pull/11238
… canvas graph controls. # Summary [NIFI-15823](https://issues.apache.org/jira/browse/NIFI-15823) Adds a Provenance preview card to the connector canvas graph-controls side panel, sitting directly below the existing Connector info card. When a provenance-eligible component is selected on the canvas, the card lists the latest provenance events for that component and offers the standard per-event actions (view details, view/download input/output content, replay). The preview is implemented as a new reusable presentation component under `apps/nifi/src/app/ui/common/` so it can be hosted by any page that already mounts the reusable `<reusable-canvas>`, and is backed by a new feature-scoped NgRx slice that lives with the connector canvas. ### What changed **New reusable component (`apps/nifi/src/app/ui/common/provenance-preview/`)** - `ProvenancePreview` — a `mat-expansion-panel` shell containing a compact table of recent provenance events. Owns its own collapsed state and persists it under `graph-control-visibility[<storageKey>]` via the shared `Storage` service. The `storageKey` input is configurable so independent instances on different pages do not collide (the connector canvas passes `connector-provenance-control`). Cluster-aware: when multiple nodes are reporting events the panel exposes a node-filter dropdown sourced from `connectedToCluster` + the events themselves. Surfaces a per-row action menu (View Details / View Input / View Output / Download Input / Download Output / Replay) with each item conditionally enabled based on `contentViewerAvailable`, `inputContentAvailable`, `outputContentAvailable`, and `replayAvailable`. Pure presentation -- all intent flows out as `output()` events (`refresh`, `collapsedChange`, `viewDetails`, `viewContent`, `downloadContent`, `replayEvent`) so the host page own s the side effects (the "emit, don't dispatch" rule). **New NgRx state slice (`pages/connectors/state/connector-provenance-preview/`)** - `connectorProvenancePreviewFeatureKey` registered alongside `connectorCanvas` in `ConnectorCanvasModule`. State shape is `{ events, error, status }` with a `'pending' | 'loading' | 'success' | 'error'` status machine. - Actions and effects for `loadLatestEventsForComponent`, `openProvenanceEventDialog`, `downloadContent`, `viewContent`, `replayEvent`, `showOkDialog`, and `resetState`. Effects reuse the existing `ProvenanceService`, `ProvenanceEventDialog`, `OkDialog`, and `ErrorHelper`; replay failures surface through the standard `ErrorActions.addBannerError` channel with `ErrorContextKey.CONNECTOR_CANVAS`. Module-scoped (`forFeature`) so the slice activates with the connector canvas and tears down when leaving. - Adds `getLatestEventsForComponent(componentId)` to the shared `ProvenanceService`, calling the existing `/provenance-events/latest/{id}` REST endpoint. **Wiring into the connector canvas (`pages/connectors/ui/connector-canvas/`)** - `connector-graph-controls` now hosts `<provenance-preview storageKey="connector-provenance-control" …>` below the Connector info card, guarded by `@if (canAccessProvenance())` so it is not rendered for users without `provenancePermissions.canRead`. All inputs/outputs are forwarded through the parent shell unchanged. - `connector-canvas.component.ts` wires the slice into the page: - Selects `provenanceEvents` / `provenanceStatus` / `provenanceError`, plus `connectedToCluster` (from `selectClusterSummary`) and `contentViewerAvailable` (from `selectAbout`). - Subscribes to a `combineLatest` of route params, input ports, and output ports and reduces them through `computeEligibleProvenanceId(...)` to a single eligible component id. Eligible types: `Processor`, `Connection`, `RemoteProcessGroup`; `InputPort` / `OutputPort` are only eligible when `allowRemoteAccess === true`. Everything else (Funnel, Label, ProcessGroup, multi-select, no selection) clears the preview via `resetState`. - Adds a deferred-load gate. The page tracks `graphControlsOpen` (existing) and a `provenanceCollapsed` mirror (updated only via the child's `(collapsedChange)` output). Eligibility changes only dispatch `loadLatestEventsForComponent` when both flags allow it; otherwise the component id is parked in `lastDeferredComponentId` and flushed when the user either opens the side panel (`toggleGraphControls`) or expands the card (`onProvenanceCollapsedChange(false)`). This avoids issuing the network call -- and showing skeleton rows -- for users who keep the card collapsed. - Re-emits the child's other outputs as page-level NgRx dispatches: `viewDetails -> openProvenanceEventDialog`, `downloadContent -> downloadContent`, `viewContent -> viewContent`, `replayEvent -> replayEvent`, `refresh -> loadLatestEventsForComponent` for the current eligible id. `ngOnDestroy` dispatches `resetState` alongside the existing canvas / entity resets. **Architectural note for reviewers** The card follows the same separation-of-concerns pattern as the sibling cards added in this series (`CanvasNavigationControl`, `ConnectorInfoControl`): the child owns its own collapsed state and persists it via the shared `graph-control-visibility` bag keyed by its `storageKey` input, and only emits intent. The page hosts a small in-memory mirror of that flag for one reason -- it gates an eager network call. That mirror starts collapsed-by-default and is updated solely through the child's `(collapsedChange)` output, so persistence stays single-owner in the child. The new NgRx slice deliberately lives under `pages/connectors/state/` rather than the global provenance module: it is short-lived (registered with `forFeature`, reset on every selection change and on destroy), and its dialog/replay handlers are connector-canvas specific (they route errors to `ErrorContextKey.CONNECTOR_CANVAS`). Reusing the existing `ProvenanceService` keeps the REST surface unchanged. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
