Skip to content

feat: multi-select bulk editing for document fields#32

Draft
reeseherber wants to merge 1 commit into
mainfrom
feat/multi-select-field-editing
Draft

feat: multi-select bulk editing for document fields#32
reeseherber wants to merge 1 commit into
mainfrom
feat/multi-select-field-editing

Conversation

@reeseherber

Copy link
Copy Markdown
Collaborator

Closes #15

Summary

Adds a bulk-edit panel for editing multiple document fields at once, in both the document and template field editors.

What changed

  • Multi-selecting fields (ctrl/cmd/shift-click — already supported) now surfaces a floating "N fields selected" panel whenever 2+ fields are selected.
  • The panel edits shared properties across the whole selection at once:
    • Field type (converts every selected field to one type)
    • Font size
    • Text alignment (shown when the selection includes alignment-capable types)
    • Required / Read only (shown for fields that support them)
  • Each change applies immediately to all selected fields. Controls show a "Mixed" indicator when selected fields currently differ.
  • Field-type conversions start from the new type's defaults and carry over compatible shared properties (font size, alignment, required/read-only).
  • Selection is cleared when switching the active recipient so the panel never targets another recipient's now-disabled fields.

The panel is a draggable/collapsible floating panel matching the existing single-field advanced-settings panel, and reuses the existing selection state (useFieldDeletion) and per-field selection ring for visual indication.

Acceptance criteria

  • Select multiple fields (ctrl/cmd/shift-click)
  • Bulk-edit panel appears when multiple fields are selected
  • Panel changes alignment, text size, field type, and other shared properties
  • Changes apply to all selected fields simultaneously
  • Selection is visually indicated (primary ring on each selected field)

Implementation notes

  • New shared component: packages/ui/primitives/document-flow/bulk-field-settings.tsx (BulkFieldSettings + applyBulkSettingsToField helper). The helper rebuilds each field's meta as a plain object and validates it through ZFieldMetaSchema, so the result is correctly narrowed to the discriminated meta union.
  • Wired into both add-fields.tsx (documents) and add-template-fields.tsx (templates).
  • Also fixes a pre-existing flow-analysis bug in auto-sized-text.tsx where newFontSize could be used before assignment.

Testing

  • npx tsc --noEmit passes for the @documenso/ui package (0 errors).

🤖 Generated with Claude Code

Adds a bulk-edit panel that appears when two or more fields are selected
(via ctrl/cmd/shift-click) in the document and template field editors.

The panel lets users change shared properties — field type, font size,
text alignment, required and read-only — across the whole selection at
once. Each change applies immediately to every selected field, with
"Mixed" indicators when values differ. Type conversions reuse the new
type's defaults while carrying over compatible shared properties.

Selection is already visually indicated by the primary ring on each
selected field. The selection is cleared when switching recipients so
the panel never targets another recipient's fields.

Also fixes a pre-existing flow-analysis error in auto-sized-text where
newFontSize could be used before assignment.

Closes #15

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@reeseherber reeseherber added the needs-validation PR awaiting AI validator review label May 21, 2026

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a bulk field settings feature, allowing users to edit properties like type, font size, and alignment across multiple selected fields simultaneously in both document and template flows. It also includes a fix for AutoSizedText to prevent undefined font sizes. A high-severity issue was identified in the bulk settings logic where using parse instead of safeParse on schema validation could cause the UI to crash during intermediate input states.

}
}

const fieldMeta: TFieldMetaSchema = candidate ? ZFieldMetaSchema.parse(candidate) : undefined;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Using ZFieldMetaSchema.parse here will throw an exception if the candidate object is invalid according to the schema. This is likely to happen during user input, for example, when a user is typing a font size and the value is temporarily outside the allowed range (8-96). A crash in this mapping function will break the UI and prevent further updates.

Consider using safeParse and falling back to the raw candidate object if parsing fails. This allows the form state to hold the intermediate invalid value (ensuring a smooth UX without flickering) while the form's overall validation (triggered in handleAutoSave) will correctly prevent the invalid data from being persisted.

  const parsed = candidate ? ZFieldMetaSchema.safeParse(candidate) : null;
  const fieldMeta: TFieldMetaSchema = parsed
    ? parsed.success
      ? parsed.data
      : (candidate as TFieldMetaSchema)
    : undefined;

@reeseherber reeseherber added validating Validator polecat is reviewing needs-validation PR awaiting AI validator review and removed needs-validation PR awaiting AI validator review validating Validator polecat is reviewing labels May 21, 2026
@reeseherber

Copy link
Copy Markdown
Collaborator Author

Playwright Validation Evidence (PR #32)

Screenshots from automated validation against https://documenso-dev.psd401.net running the PR 32 docker build (image documenso-pr32:test, built from commit 66fbb976):

Signin form (PR 32 enables email/password)
Post-signin landing
Team documents
Editor step 1 (Document & Recipients)
Editor step 2 (Add Fields)
Bundle marker check

Bundle verification

The PR's bulk-edit panel ships in the deployed build — grep'ing the served chunks finds the new data-testid markers:

bulk-field-delete
bulk-field-font-size
bulk-field-read-only
bulk-field-required
bulk-field-settings-close
bulk-field-settings-drag-handle
bulk-field-settings-panel
bulk-field-text-align
bulk-field-type

(all found in /app/apps/remix/build/client/assets/legacy-field-warning-popover-*.js)

Note

The headless Playwright drag-to-place flow was thwarted in this environment — the Add Fields page renders the PDF page as an <img> and overlays a Konva canvas on top, so the click-target stack starts with the Konva canvas rather than .react-pdf__Page. Documenso's onMouseClick runs but the bounds resolution falls through and no FieldItem gets appended. This is independent of PR #32 — the placement code is unchanged on this branch — but it kept me from exercising the bulk panel end-to-end in screenshots. The bundle-marker check above confirms the new panel ships in the production build.

Automated Playwright screenshots from https://documenso-dev.psd401.net (image documenso-pr32:test).

@reeseherber reeseherber left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

VALIDATION FAIL

What I verified

  • PR branch (feat/multi-select-field-editing, single commit 66fbb976) built and deployed on the dev server (image documenso-pr32:test, recreated from ghcr.io/psd401/documenso:latest).
  • Site reachable, pipeline@psd401.net email/password sign-in works.
  • Reviewed gh pr diff 32 against the acceptance criteria — new BulkFieldSettings panel + applyBulkSettingsToField helper wired into both add-fields.tsx and add-template-fields.tsx; selection-clearing-on-recipient-switch effect in place; auto-sized-text.tsx flow-analysis fix is reasonable.
  • All nine new data-testid markers from bulk-field-settings.tsx appear in the deployed JS bundle (/app/apps/remix/build/client/assets/legacy-field-warning-popover-*.js).

Why I'm calling FAIL

Gemini's high-severity comment on packages/ui/primitives/document-flow/bulk-field-settings.tsx:148 is correct, the PR was updated since then, but the fix was not applied.

const fieldMeta: TFieldMetaSchema = candidate ? ZFieldMetaSchema.parse(candidate) : undefined;

This runs on every bulk update. The font-size <Input type="number" min={8} max={96}> calls onApply({ fontSize: parsed }) from onChange for any numeric value the user types — min/max on the input are hints, not gates. The schema is z.number().min(8).max(96), so as soon as the user clears the input and types 7 (or anything past 96), ZFieldMetaSchema.parse(...) throws a ZodError mid-render of the bulk panel, which propagates to the nearest error boundary and tears the editor out from under the user. Same hazard if any other future caller passes an unvalidated value.

The suggested swap to safeParse with fallback to the raw candidate keeps the form state holding the intermediate invalid value (so the input doesn't fight the user mid-keystroke) and leaves the form's outer handleAutoSave validation to refuse persisting it — exactly the behaviour every other meta-editor in the codebase relies on. Please apply the suggested fix (or equivalent) and I'll re-validate.

What I could not finish, and why

I wanted to drive the panel end-to-end in Playwright (multi-select two fields, change font size including out-of-range to confirm the crash, change type, toggle required/read-only). On this dev environment the editor renders the PDF page as <img class="react-pdf__Page"> with a Konva <canvas> overlay on top, so document.elementFromPoint(...) at the drop target returns the Konva canvas, not a descendant of .react-pdf__Page. Documenso's onMouseClick (packages/ui/primitives/document-flow/add-fields.tsx:297) clears selectedField but append never fires, so no FieldItem gets placed and the bulk panel can't be shown. That's an environment issue independent of this PR — add-fields.tsx was not touched in a way that would change placement — but it kept me from producing a live screenshot of the panel itself. Evidence comment with screenshots: posted alongside this review.

Verdict

FAIL — please address the ZFieldMetaSchema.parsesafeParse change Gemini flagged. Everything else looks good.

@reeseherber reeseherber added changes-requested Validator rejected - builder should iterate building Builder polecat is implementing and removed validating Validator polecat is reviewing changes-requested Validator rejected - builder should iterate building Builder polecat is implementing labels May 26, 2026
reeseherber added a commit that referenced this pull request Jun 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Multi-select editing for document fields

1 participant