[ 
https://issues.apache.org/jira/browse/NIFI-16447?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Matt Gilman updated NIFI-16447:
-------------------------------
    Description: 
h2. Background

The reusable canvas does not yet use one consistent contract for visibility, 
interaction gating, preview state, and connector-host persistence.

The canvas currently classifies visible, entering, and leaving components in 
updateCanvasVisibility, while individual layers expose Renderer.pan() methods. 
Click and double-click handlers are often attached only when canSelect is true 
during rendering, so editing-state changes may not affect existing elements 
until another render occurs. Processor preview status is calculated in the 
renderer instead of being carried in ProcessorUiState.preview.

The connector canvas also does not bind the reusable canvas mutation outputs. 
Component dragging, label resizing, bend updates, connection-label movement, 
connection creation, and endpoint reconnection therefore have no 
connector-scoped action and effect boundary.

Upcoming troubleshooting features enable editing on an already-mounted canvas 
and depend on bulk-position persistence, current selection, permissions, and 
visual bounds. These shared contracts should be established before those 
features build on them.

h2. Goals

* Classify visibility inside each renderer during its normal update.
* Attach interaction handlers once and evaluate canSelect and canEdit when 
events occur.
* Stamp ui.preview where processor wrapper data is produced.
* Connect reusable-canvas mutation outputs to typed connector state actions and 
effects.
* Preserve revisions correctly across gesture, request, success, and failure 
paths.
* Preserve current rendered appearance and read-only behavior.

h2. Scope

h3. Visibility

* Move viewport classification out of CanvasComponent.updateCanvasVisibility 
and into each renderer update.
* Apply the same visibility contract to funnel, label, port, processor, 
process-group, remote-process-group, and connection renderers.
* Remove Renderer.pan() and layer pan() methods used only to refresh entering 
and leaving components.
* Continue suppressing off-screen details and preserving entering and leaving 
transitions.

h3. Selection and edit gating

* Attach click and double-click handlers when rendered elements enter.
* Evaluate getCanSelect() and getCanEdit() inside each event handler.
* Do not omit handlers because editing or selection was disabled when the 
element was rendered.
* Apply the same live gating to component dragging, connection creation, bend 
editing, label movement, resizing, and endpoint reconnection.
* Ensure changing editing state affects the next interaction without requiring 
wrapper or DOM reconstruction.

h3. Preview state

* Stamp ui.preview when processor wrappers are created and refreshed.
* Stamp the same preview value on processor selection targets.
* Match readable processors using type and bundle group, artifact, and version 
against the Preview-tagged extension list.
* Make the processor renderer read ui.preview instead of performing its own 
extension lookup.
* Preserve existing badge visibility, placement, and processor-name positioning.

h3. Connector canvas mutation integration

Bind the connector canvas to these reusable-canvas outputs:

* componentsDragEnd
* labelResizeEnd
* connectionBendPointsUpdate
* connectionLabelDragEnd
* createConnectionRequested
* connectionDestinationChangeRequested

For each mutation:

* Add typed connector-canvas actions, effects, and service requests.
* Keep the reusable canvas independent of connector state and NgRx.
* Preserve the gesture-baseline revision emitted by the canvas.
* Build request revisions containing only version and the local clientId.
* Do not copy read-only revision fields into request payloads.
* Support single and bulk component-position updates.
* Update the appropriate typed entity collection from successful responses.
* Apply revision-aware reconciliation so stale responses cannot replace newer 
entities.
* Mark affected canvas items as saving while requests are active.
* Invoke the reusable canvas confirmation API after success.
* Invoke the corresponding revert API after failure.
* Surface failures through the connector error context.
* Keep mutation behavior disabled until the host editing gate allows it.

h3. Connection policy

* Provide the connector canvas with a ConnectablePolicy backed by live edit 
state and component permissions.
* Validate source and destination eligibility using the current entities and 
process group.
* Keep connection creation and reconnection inert while editing is disabled.
* Ensure policy replacement or removal tears down stale handles, previews, and 
listeners.

h3. Tests

Add coverage for:

* Renderer-owned visibility classification.
* Entering, visible, and leaving transitions.
* Interaction gates changing after elements have rendered.
* Processor wrapper and selection-target preview values.
* Each reusable-canvas mutation output reaching the correct connector action.
* Local clientId substitution and exclusion of read-only revision fields.
* Gesture-baseline revision preservation.
* Single and bulk position persistence.
* Success confirmation and failure reversion.
* Saving-state cleanup.
* Stale-response protection.
* Connection policy enablement, replacement, and teardown.
* Continued read-only behavior while editing is disabled.

h2. Out of Scope

* Entering or ending troubleshooting mode.
* Troubleshooting route guards and banners.
* Component run-status commands and operation panels.
* Processor advanced UI.
* Controller Service management.
* Alignment commands, Remote Process Group refresh, and provenance replay.
* Changes to REST resource semantics.
* Changes to rendered appearance.
* Changes to the legacy flow-designer canvas.

h2. Acceptance Criteria

* The canvas no longer owns renderer visibility classification.
* Renderers no longer expose pan() solely for viewport refresh.
* Selection and editing changes take effect on the next event without handler 
reattachment.
* The processor renderer reads ui.preview and does not inspect the extension 
list.
* The connector canvas binds every reusable-canvas mutation output listed above.
* Requests use gesture-baseline versions and the local clientId without 
read-only revision fields.
* Successful requests reconcile the correct entities and confirm optimistic 
state.
* Failed requests revert optimistic state and clear saving indicators.
* Stale responses cannot overwrite newer revisions.
* Connection behavior remains inert while editing is disabled.
* Existing rendered appearance and read-only interactions remain unchanged.
* Frontend lint, strict type-check, unit tests, and production build pass.

  was:
h2. Background

The reusable canvas renderers do not share one contract for visibility, 
selection, or the processor Preview badge.

The canvas classifies visible, entering, and leaving components in 
updateCanvasVisibility, then each layer calls Renderer.pan() to refresh only 
those components. Click and double-click handlers are often attached only when 
canSelect is already true at render time, so a later editing change does not 
affect an existing element until something renders it again. The processor 
Preview badge is decided inside ProcessorRenderer.isPreviewProcessor during 
update, while ProcessorUiState.preview is left unset.

Upcoming troubleshooting work enables canvas editing on an already mounted 
canvas, builds context menus and an operation panel from the current selection, 
and aligns components from their visual bounds. Those features need one place 
to classify visibility, one place to read canSelect and canEdit, and one 
stamped preview flag.

h2. Goals

* Classify visibility inside each renderer during its normal update.
* Attach pointer handlers once and read canSelect and canEdit when the event 
fires.
* Stamp ui.preview where processor data is produced, and have the processor 
renderer read that flag.
* Preserve the current rendered appearance and interaction results.
* Leave troubleshooting features to their existing tickets.

h2. Scope

h3. Visibility

* Move viewport classification out of CanvasComponent.updateCanvasVisibility 
and into each renderer update.
* Apply this to the funnel, label, port, processor, process-group, 
remote-process-group, and connection renderers.
* Remove Renderer.pan() and the layer pan() methods that exist only to refresh 
entering and leaving components.
* Keep off-screen components from drawing their details, and keep entering and 
leaving transitions.

h3. Selection and edit gating

* Attach click and double-click handlers when an element enters, including 
connection bend and endpoint handlers.
* Read getCanSelect() and getCanEdit() inside the handler.
* Do not skip attaching a handler because canSelect was false on the render 
that created the element.
* Keep drag behavior on the same fire-time gate.

h3. Preview badge

* Stamp ui.preview when processors are mapped and when a same-id processor 
refresh arrives.
* Stamp the same flag on processor selection targets so an operation panel can 
read it without joining canvas wrappers.
* Match a readable processor whose type and bundle group, artifact, and version 
are in the Preview-tagged extension list.
* Change the processor renderer to show the badge only when ui.preview is true.
* Remove the render-time preview lookup.

h2. Out of Scope

* Adding troubleshooting commands, banners, route guards, alignment, provenance 
replay, or Controller Service editing.
* Migrating the legacy flow-designer canvas.
* Changing REST payloads or rendered appearance.
* Rewriting connection bend and endpoint behavior beyond the shared handler and 
gating contract.

h2. Acceptance Criteria

* No renderer exposes pan(), and the canvas no longer classifies visibility for 
the renderers.
* Each renderer sets visible, entering, and leaving during its own update.
* A canSelect or canEdit change takes effect on the next event without waiting 
for handlers to be reattached.
* The processor renderer reads ui.preview and does not match the extension list 
itself.
* The same preview match feeds the canvas wrapper and the processor selection 
target.
* Off-screen detail suppression, badge placement, and selection behavior remain 
unchanged.
* Frontend lint, unit tests, and the reusable-canvas specs pass.


> Give the reusable canvas one visibility pass, one selection gate, and one 
> preview flag
> --------------------------------------------------------------------------------------
>
>                 Key: NIFI-16447
>                 URL: https://issues.apache.org/jira/browse/NIFI-16447
>             Project: Apache NiFi
>          Issue Type: Improvement
>          Components: Core UI
>            Reporter: Matt Gilman
>            Assignee: Matt Gilman
>            Priority: Major
>
> h2. Background
> The reusable canvas does not yet use one consistent contract for visibility, 
> interaction gating, preview state, and connector-host persistence.
> The canvas currently classifies visible, entering, and leaving components in 
> updateCanvasVisibility, while individual layers expose Renderer.pan() 
> methods. Click and double-click handlers are often attached only when 
> canSelect is true during rendering, so editing-state changes may not affect 
> existing elements until another render occurs. Processor preview status is 
> calculated in the renderer instead of being carried in 
> ProcessorUiState.preview.
> The connector canvas also does not bind the reusable canvas mutation outputs. 
> Component dragging, label resizing, bend updates, connection-label movement, 
> connection creation, and endpoint reconnection therefore have no 
> connector-scoped action and effect boundary.
> Upcoming troubleshooting features enable editing on an already-mounted canvas 
> and depend on bulk-position persistence, current selection, permissions, and 
> visual bounds. These shared contracts should be established before those 
> features build on them.
> h2. Goals
> * Classify visibility inside each renderer during its normal update.
> * Attach interaction handlers once and evaluate canSelect and canEdit when 
> events occur.
> * Stamp ui.preview where processor wrapper data is produced.
> * Connect reusable-canvas mutation outputs to typed connector state actions 
> and effects.
> * Preserve revisions correctly across gesture, request, success, and failure 
> paths.
> * Preserve current rendered appearance and read-only behavior.
> h2. Scope
> h3. Visibility
> * Move viewport classification out of CanvasComponent.updateCanvasVisibility 
> and into each renderer update.
> * Apply the same visibility contract to funnel, label, port, processor, 
> process-group, remote-process-group, and connection renderers.
> * Remove Renderer.pan() and layer pan() methods used only to refresh entering 
> and leaving components.
> * Continue suppressing off-screen details and preserving entering and leaving 
> transitions.
> h3. Selection and edit gating
> * Attach click and double-click handlers when rendered elements enter.
> * Evaluate getCanSelect() and getCanEdit() inside each event handler.
> * Do not omit handlers because editing or selection was disabled when the 
> element was rendered.
> * Apply the same live gating to component dragging, connection creation, bend 
> editing, label movement, resizing, and endpoint reconnection.
> * Ensure changing editing state affects the next interaction without 
> requiring wrapper or DOM reconstruction.
> h3. Preview state
> * Stamp ui.preview when processor wrappers are created and refreshed.
> * Stamp the same preview value on processor selection targets.
> * Match readable processors using type and bundle group, artifact, and 
> version against the Preview-tagged extension list.
> * Make the processor renderer read ui.preview instead of performing its own 
> extension lookup.
> * Preserve existing badge visibility, placement, and processor-name 
> positioning.
> h3. Connector canvas mutation integration
> Bind the connector canvas to these reusable-canvas outputs:
> * componentsDragEnd
> * labelResizeEnd
> * connectionBendPointsUpdate
> * connectionLabelDragEnd
> * createConnectionRequested
> * connectionDestinationChangeRequested
> For each mutation:
> * Add typed connector-canvas actions, effects, and service requests.
> * Keep the reusable canvas independent of connector state and NgRx.
> * Preserve the gesture-baseline revision emitted by the canvas.
> * Build request revisions containing only version and the local clientId.
> * Do not copy read-only revision fields into request payloads.
> * Support single and bulk component-position updates.
> * Update the appropriate typed entity collection from successful responses.
> * Apply revision-aware reconciliation so stale responses cannot replace newer 
> entities.
> * Mark affected canvas items as saving while requests are active.
> * Invoke the reusable canvas confirmation API after success.
> * Invoke the corresponding revert API after failure.
> * Surface failures through the connector error context.
> * Keep mutation behavior disabled until the host editing gate allows it.
> h3. Connection policy
> * Provide the connector canvas with a ConnectablePolicy backed by live edit 
> state and component permissions.
> * Validate source and destination eligibility using the current entities and 
> process group.
> * Keep connection creation and reconnection inert while editing is disabled.
> * Ensure policy replacement or removal tears down stale handles, previews, 
> and listeners.
> h3. Tests
> Add coverage for:
> * Renderer-owned visibility classification.
> * Entering, visible, and leaving transitions.
> * Interaction gates changing after elements have rendered.
> * Processor wrapper and selection-target preview values.
> * Each reusable-canvas mutation output reaching the correct connector action.
> * Local clientId substitution and exclusion of read-only revision fields.
> * Gesture-baseline revision preservation.
> * Single and bulk position persistence.
> * Success confirmation and failure reversion.
> * Saving-state cleanup.
> * Stale-response protection.
> * Connection policy enablement, replacement, and teardown.
> * Continued read-only behavior while editing is disabled.
> h2. Out of Scope
> * Entering or ending troubleshooting mode.
> * Troubleshooting route guards and banners.
> * Component run-status commands and operation panels.
> * Processor advanced UI.
> * Controller Service management.
> * Alignment commands, Remote Process Group refresh, and provenance replay.
> * Changes to REST resource semantics.
> * Changes to rendered appearance.
> * Changes to the legacy flow-designer canvas.
> h2. Acceptance Criteria
> * The canvas no longer owns renderer visibility classification.
> * Renderers no longer expose pan() solely for viewport refresh.
> * Selection and editing changes take effect on the next event without handler 
> reattachment.
> * The processor renderer reads ui.preview and does not inspect the extension 
> list.
> * The connector canvas binds every reusable-canvas mutation output listed 
> above.
> * Requests use gesture-baseline versions and the local clientId without 
> read-only revision fields.
> * Successful requests reconcile the correct entities and confirm optimistic 
> state.
> * Failed requests revert optimistic state and clear saving indicators.
> * Stale responses cannot overwrite newer revisions.
> * Connection behavior remains inert while editing is disabled.
> * Existing rendered appearance and read-only interactions remain unchanged.
> * Frontend lint, strict type-check, unit tests, and production build pass.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to