yangzhang75 opened a new pull request, #8843:
URL: https://github.com/apache/texera/pull/8843

   ### What changes were proposed in this PR?
   
   Closes #8761. Part of the Form View feature (#8011); from the #8439 
refinements (item 2).
   
   An exposed drag-reorder property -- Projection's columns, formly type 
`repeat-section-dnd` -- fell back to a plain repeated list in the Form View 
(`CANVAS_ONLY_FORMLY_TYPES`): a reader could edit the rows but not reorder 
them, which is what the widget is for. The fallback assumed the drag had 
nowhere to attach on a form; the widget carries its own CDK drop list, and the 
row template it needs comes from the operator's own schema (the per-instance 
one, with the upstream columns), which the form already builds.
   
   - `repeat-section-dnd` leaves `CANVAS_ONLY_FORMLY_TYPES`; the set now holds 
the code editor only. On the form the widget renders with the drag, and a 
reorder reaches the operator through the card's `valueChanges` write-back (the 
canvas's `reorder` callback is optional, as it always was).
   - The widget gets a keyboard path, as the form's own step list has: Move up 
/ Move down on every row, through the same move as the drag (model, field 
configs, form controls, then the parent's callback). At the ends the buttons 
are `aria-disabled`, not disabled, so the focused button is not dropped; after 
a move the focus is put back on the same button of the row where it landed, 
since a moved DOM node loses it. The drag handle is hidden from assistive tech, 
and the drag is disabled with the section. These buttons appear wherever the 
widget renders, so the operator property panel's Projection rows gain them too 
(two small buttons per row); an a11y gain there as well, called out here so it 
is a decision, not a surprise.
   - Two defects in the widget itself, found while reviewing this and in reach 
of the form for the first time: every button now has `type="button"` -- 
`nz-button` sets no type, so inside a form (the card's, the panel's) a typeless 
button is the submit button and Enter in a row's input clicked it, removing the 
first row (the fallback the form used before had typed buttons; the panel has 
had this since the widget exists); and the rows are re-keyed to their positions 
after a move, as formly's own `remove()` does -- formly keys rows by position 
and writes a cell's value into the model by that key path, so a value typed 
into a moved row landed on the row that used to be there (the same after a drag 
on the panel, until the operator was re-selected).
   
   ### Any related issues, documentation, discussions?
   
   Closes #8761. Raised by @mengw15 on #8436; filed from #8439. Builds on the 
sub-field walk from #8438. #8760 (proper) also shrinks 
`CANVAS_ONLY_FORMLY_TYPES`; whichever lands second deletes the then-empty set. 
Known limitation, not this PR's code: the Form View rebuilds every card on 
every compilation, including the one a card's own write triggers, so on the 
form a Move's write redraws the row buttons about a second later, drops the 
keyboard focus the widget had just put back, and can undo a second Move made in 
the last 150 ms before that redraw. The canvas panel has no such rebuild. It is 
filed separately with a fix verified on a branch (the form rebuilds only when 
the schema, the set of inputs or a value it does not hold changed); this PR is 
independent of it. Other follow-ups: a card's model is seeded once and never 
re-seeded from a co-editor's edit of the same property, so a reorder writes the 
whole array back over such an edit (pre-existing for every array/object 
property; a r
 eorder is one more trigger); the HuggingFace and codearea widgets also carry 
typeless buttons.
   
   ### How was this PR tested?
   
   Unit tests (vitest). The widget's spec: a keyboard move reorders the model, 
the field configs and the form controls and tells the parent; at the ends it 
goes nowhere and the buttons stay in the tab order; the focus is put back on 
the moved row's button, Move up and Move down alike (asserted on the restoring 
call, since jsdom does not model the browser's focus drop); a disabled section 
locks the move buttons and the drag; the handle is hidden from assistive tech; 
every button carries `type="button"`; a keyless row's children are re-keyed to 
the row's new position, as formly's own remove() does. A second spec stands the 
widget up under real formly (`FormlyModule.forRoot`, a form, a model): a move 
changes the model and the cells and keeps the rows' keys in step with their 
positions, and a value typed into a moved row lands on that row's entry. The 
form's spec: Projection's `attributes` renders through `repeat-section-dnd`. 
`custom-formly-type`'s spec pins the set. Each guard was dele
 tion-checked (the move in the wrong direction; no focus restore; the Move-up 
restore aimed at the Move-down button; no guard at the ends; the parent never 
told; the drag live for a disabled section; the move buttons live; `disabled` 
instead of `aria-disabled` at the ends; the handle exposed; the type back in 
the canvas-only set; the re-keying dropped; the remove button typeless) and 
turned a named test red. eslint, prettier and the production (AOT) build pass; 
the full frontend suite passes; every statement, function and branch this PR 
adds is covered.
   
   Checked on a flag-on instance (main-demo; a Python source with four columns 
feeding a Projection whose `attributes` is exposed), with the canvas and the 
form open side by side: on main the card is a plain list (no handle, no Move 
buttons); with this PR the card shows the drag handles and the Move buttons, as 
the panel does. Move down on the first row: the operator's order follows in the 
canvas tab's panel within a second and in the saved workflow. Dragging the last 
row to the top with the mouse: the same. An alias typed into the moved row 
lands on that column, not its neighbour; Enter in an alias input removes no 
row; a reload shows the same order. A Move made on the canvas panel reaches the 
form within a second.
   
   ### Was this PR authored or co-authored using generative AI tooling?
   
   Yes. Generated-by: Claude Code (Claude Fable 5.1, Anthropic). Co-authored 
with Claude, reviewed line by line by the author before submission.
   
   🤖 Generated with [Claude Code](https://claude.com/claude-code)


-- 
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]

Reply via email to