Skip to content

NIFI-15823: Adding the proveance preview component into the connector…#11238

Open
mcgilman wants to merge 1 commit into
apache:mainfrom
mcgilman:NIFI-15823
Open

NIFI-15823: Adding the proveance preview component into the connector…#11238
mcgilman wants to merge 1 commit into
apache:mainfrom
mcgilman:NIFI-15823

Conversation

@mcgilman
Copy link
Copy Markdown
Contributor

… canvas graph controls.

Summary

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 owns 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.

@mcgilman mcgilman added the ui Pull requests for work relating to the user interface label May 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ui Pull requests for work relating to the user interface

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant