Skip to content

feat(workflow-form): Form View widget refinements (render canvas-only widgets fully, HuggingFace mode, compile-on-blur) #8439

Open
2 of 6 issues completed

Description

@yangzhang75

Refinements surfaced in review of the Form View render PRs (#8437 render inputs, #8436 field-type rules). All are out of scope for the MVP, which ships clean fallbacks; filing so they are not lost. Part of the Form View feature (#8011).

1. Render the code editor in the form (not a fallback)

An exposed code-editor property currently falls back to a plain editable control (CANVAS_ONLY_FORMLY_TYPES), and is not offered for exposure at all (NON_FORM_FIELD_TYPES). The code editor is not an inline field: it is a button that opens Monaco via createComponent into a ViewContainerRef the workspace registers, keyed off the canvas's highlighted operator. The form has neither, so rendering it here means giving the form its own editor host and supplying the operator id from the binding (plus a change to the shared codearea component). Raised by @mengw15 on #8436.

2. Render Projection's drag-reorder list in the form (with the drag)

An exposed drag-reorder property currently falls back to a plain repeated list (CANVAS_ONLY_FORMLY_TYPES). The widget is a FieldArrayType whose rows come from an item template the panel builds with extra dynamic-schema wiring for Projection's attributes; the reorder callback itself is optional (the form's valueChanges persists a reorder). Rendering it with the drag needs that item-template wiring reproduced and verified against the real schema. Overlaps the nested/array work in #8438. Raised by @mengw15 on #8436.

3. Full HuggingFace form-view mode

An exposed HuggingFace model picker (modelId) now gets the operator's other properties (including task) as read-only context, so it loads the right models and labels the field, and only the bound property is written back. Not yet handled: the widget's own task selector is still interactive and a task change is not persisted, so a reader could in principle pick a model/task pair the operator's real task does not match. A form-view mode would use the provided task and hide/lock the task selector. Touches the shared hugging-face.component. Raised by Copilot on #8437.

4. Compilation update dropped while the reader is typing

The inputs rebuild on the compilation-state stream, skipped while the reader is typing so it does not throw away a half-entered value. The stream is a ReplaySubject(1), so a state update that arrives during typing is dropped and not replayed once focus leaves the field; if it carried new upstream column names, an attribute control stays a plain text box until an unrelated compilation. Record a pending rebuild and flush it on blur. Raised by Copilot on #8437.

5. Read-only lock must block keyboard too, not just pointer

The read-only input card uses pointer-events: none, which only blocks pointing-device hit testing. A keyboard user can still tab to a custom widget's own controls (a file picker button, the HuggingFace file input) and activate them with Enter/Space -- e.g. the HF audio input ignores formly's disabled control and POSTs the selected file. Use the inert attribute on the card (or disable each descendant control semantically) so read-only blocks keyboard interaction too. Raised by Copilot on #8437/#8438/#8440.

6. ui-udf-parameters overrides in the form

ui-udf-parameters is exposable, but its renderer hides formly's labels and shows hard-coded column headers (Value / Name / Type), so a binding's displayName/hidden sub-field overrides do not change what the reader sees. Either fall back to an override-aware Form View renderer for this type, or have the component consume the nested labels/visibility. Same class as the HuggingFace form-mode item above. Raised by Copilot on #8438.

  • Form View result-frame rebuild churn (from feat(workflow-form): show the chosen results #8441 review): the Form View bumps a viz result key on every result-update emission, destroying/recreating the visualization iframe, which defeats VisualizationFrameContentComponent's own throttled (auditTime 2s) in-place self-update. Fix: bump the key only when a result is genuinely new (first appearance / re-run), handling clearResults (a separate stream) so a re-run still gets a fresh frame without reintroducing the stale/undefined-picture bug the key was added to fix. Must be verified on a flag-on instance (the iframe cannot render in jsdom).

Tracking

Activity

  1. github-actions commented on Sep 6, 2026

    @github-actions
    Contributor

    👋 Thanks for opening this issue, @yangzhang75!

    It looks like the issue description doesn't quite follow our template yet:

    • This issue doesn't appear to use one of our templates (Bug, Feature, or Task). Please open it using a template so the required details are captured.

    Filling out the template helps reviewers understand and triage your contribution faster. Please edit the description to complete it. This message will disappear automatically once the template is followed.

    You can find the template prompts by editing the description, or see CONTRIBUTING.md for the full contribution flow.

  2. changed the title [-]feat(workflow-form): Form View input refinements (HuggingFace form mode, compilation-on-blur)[/-] [+]feat(workflow-form): Form View widget refinements (render canvas-only widgets fully, HuggingFace mode, compile-on-blur)[/+] on Sep 6, 2026
  3. yangzhang75 commented on Sep 6, 2026

    @yangzhang75
    ContributorAuthor

    /take

  4. yangzhang75 commented on Sep 22, 2026

    @yangzhang75
    ContributorAuthor

    A second way to item 1's missing editor host, found while auditing #8581. It is not only an exposed code property that reaches it: the Form View's step panel renders the operator's real property frame, and in edit mode (panelLive) that frame is interactive, so a Python UDF step shows the ordinary code-editor button. Pressing it calls codeEditorService.vc.createComponent(...) (codearea-custom-template.component.ts:87), and the only thing that ever sets vc is the canvas (workspace.component.ts, its <ng-template #codeEditor>).

    Two failure modes, both broken: before #8581 the Form View was a fresh page load, so vc was undefined and the click threw; with #8581 the canvas -> form switch routes, so vc is the destroyed canvas's ViewContainerRef (its ngOnDestroy clears the container but keeps the reference) and Monaco is created into a detached view -- nothing visible. Neither is a regression of #8581; it is the same missing host. Worth knowing when this is picked up: the button is reachable today, so hiding it in the form until the host exists is a cheap interim, and whatever host is added should be owned above both views (or handed over with the session) rather than by the canvas alone.

  5. yangzhang75 commented on Oct 4, 2026

    @yangzhang75
    ContributorAuthor
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions