Skip to content

refactor(dialog): migrate to frappe-ui v1 Dialog API#480

Merged
netchampfaris merged 4 commits into
developfrom
v1-dialog
May 13, 2026
Merged

refactor(dialog): migrate to frappe-ui v1 Dialog API#480
netchampfaris merged 4 commits into
developfrom
v1-dialog

Conversation

@netchampfaris
Copy link
Copy Markdown
Contributor

Summary

Sweeping migration of every dialog call site in gameplan to the v1 Dialog surface shipped in frappe-ui v1-release/dialog.

Net impact: 39 files changed, +798 / -1202 lines (net -404 lines). One module deleted entirely (frontend/src/utils/dialogs.tsx, -93 lines).

What changed

Declarative <Dialog> rewrites

  • Flatten :options="{ ... }" blob to top-level props across all dialogs
  • Replace #body-content / #body wrappers with default slot + bare mode
  • Swap manual focus hacks (v-focus, ref + setTimeout) for the standard autofocus attribute
  • Update action onClick from (close) => ... to ({ close }) => ... ctx form
  • v-modelv-model:open
  • disableOutsideClickToClose:dismissable="false" (inverted)

Imperative API rewrites

  • Migrate 16 destructive confirm dialogs (delete / discard / remove / stop / retract) to dialog.danger, dropping redundant theme: 'red' / confirmLabel: 'Delete' since danger provides both as defaults
  • Adopt the new onConfirm callback contract: auto-close on resolve, throw-to-stay-open with the thrown message rendered inline as a validation error
  • Remove the now-obsolete frontend/src/utils/dialogs.tsx wrapper — the imperative helpers now ship from frappe-ui directly via dialog.confirm / dialog.danger / dialog.prompt

Submodule

  • Bump frappe-ui pointer to pick up the v1 imperative API helpers, the close-behaviour story, and the aligned docs

Top files by churn

File Lines changed Notable
pages/Project.vue 170 Several embedded dialogs (project move, settings, archive flows)
components/CommandPalette/CommandPalette.vue 142 Adopts bare mode + Dialog.Close re-export
components/DiscussionView.vue 120 4 confirm dialogs (pin / close / reopen / delete); delete moved to dialog.danger
components/RevisionsDialog.vue 106
components/AddMemberDialog.vue 104
components/NewTaskDialog/NewTaskDialog.vue 98
components/Poll.vue 98 3 confirms migrated to dialog.danger (stop / retract / delete)
components/NewSpaceDialog.vue 94
utils/dialogs.tsx -93 (deleted) Obsolete wrapper
pages/NewDiscussion/useNewDiscussion.ts 85 Discard / delete-draft confirms migrated to dialog.danger
components/AboutDialog.vue 80

Destructive call sites migrated to dialog.danger

File Use case
components/TaskDetail.vue Delete task
components/TaskList.vue Delete task (row action)
components/Poll.vue Stop poll, retract vote, delete poll
components/SpaceOptions.vue Delete space
components/Comment.vue Delete comment
components/CommentsArea.vue Discard new comment
components/CommentsList.vue Discard new comment
components/DiscussionView.vue Delete post
components/Settings/Members.vue Remove user
pages/ProjectDiscussionNew.vue Discard post
pages/PageGrid.vue Delete page
pages/Page.vue Delete page
pages/NewDiscussion/useNewDiscussion.ts Delete draft, discard post

Non-destructive dialog.confirm usages (archive, mark-as-read, close/re-open discussion, change role, save-or-discard) were intentionally left on dialog.confirmdialog.danger would mis-colour those flows red.

Related work in frappe-ui

Pushed on v1-release/dialog:

  • acc50047Imperative.vue story: close-behaviour matrix, optimisticClose, keepOpenAfterAsync demos
  • 134aa37e — docs alignment: migration guide §7, spec 08f Imperative API section, ADR-0002 marked superseded, new ADR-0003 explaining why implementation reversed the original caller-closes design

Test plan

  • Destructive flows fire dialog.danger and show the red alert-triangle icon: delete task, delete space, delete page, delete poll, delete comment, delete discussion, delete draft, remove user, stop poll, retract vote
  • Discard flows: discard new comment (with/without content), discard new post, discard draft
  • Non-destructive confirms still appear neutral (no red icon): archive space, archive team, archive/unarchive project, mark space as read, change member role, close/re-open discussion, unpin discussion
  • Multi-action confirms render and behave: Drafts bulk delete, InviteGuestDialog (delete invitation, remove guest), ManageMembersDialog
  • Throw-to-stay-open contract: server-side validation errors from any prompt/confirm render inline and leave the dialog open with buttons re-enabled
  • Focus management on open: NewSpaceDialog first field receives focus, NewTaskDialog/EditCategoryDialog etc. focus their primary input
  • Dismiss control: Escape and outside-click close most dialogs; suppressed where :dismissable="false" (in-flight forms)
  • Command Palette renders correctly with bare mode
  • v-model (legacy) still works wherever it remains
  • No console deprecation warnings in production-shaped flows

🤖 Generated with Claude Code

netchampfaris and others added 2 commits May 13, 2026 18:48
Aligns with the project convention of explicit `lucide-` prefixes for
Lucide icons (also required by frappe-ui v1, which no longer falls back
to FeatherIcon for unprefixed strings).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Sweeping migration of every dialog call site in gameplan to the v1
Dialog surface shipped in frappe-ui (see frappe-ui v1-release/dialog).

Declarative <Dialog> rewrites:
- flatten :options="{ ... }" blob to top-level props across all dialogs
- replace #body-content / #body wrappers with default slot + bare mode
- swap manual focus hacks (v-focus, ref + setTimeout) for autofocus attr
- update action onClick from (close) => ... to ({ close }) => ... ctx form
- v-model -> v-model:open

Imperative API rewrites:
- migrate 16 destructive confirms (delete/discard/remove/stop/retract) to
  dialog.danger, dropping redundant theme: 'red' / confirmLabel: 'Delete'
- adopt onConfirm callback contract with throw-to-stay-open semantics
- remove now-obsolete frontend/src/utils/dialogs.tsx wrapper (-93 lines)

Submodule:
- bump frappe-ui pointer to pick up the v1 imperative API helpers

39 files changed, +799 insertions, -1202 deletions (net -403 lines).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@netchampfaris netchampfaris changed the base branch from main to develop May 13, 2026 16:58
@cypress
Copy link
Copy Markdown

cypress Bot commented May 13, 2026

gameplan    Run #435

Run Properties:  status check passed Passed #435  •  git commit 55a4c53d2e ℹ️: Merge a18cbb1bf0fe27c2d408fffe056f5e431ab303f6 into 12921fbe71fb68a3cb0cf53a5e94...
Project gameplan
Branch Review v1-dialog
Run status status check passed Passed #435
Run duration 00m 57s
Commit git commit 55a4c53d2e ℹ️: Merge a18cbb1bf0fe27c2d408fffe056f5e431ab303f6 into 12921fbe71fb68a3cb0cf53a5e94...
Committer Faris Ansari
View all properties for this run ↗︎

Test results
Tests that failed  Failures 0
Tests that were flaky  Flaky 0
Tests that did not run due to a developer annotating a test with .skip  Pending 0
Tests that did not run due to a failure in a mocha hook  Skipped 0
Tests that passed  Passing 7
⚠️ You've recorded test results over your free plan limit.
Upgrade your plan to view test results.
View all changes introduced in this branch ↗︎

…omboboxes

The v1 Dialog renders its body inside reka-ui's DialogPortal, which mounts
the content asynchronously. The helper's one-shot cy.get('body').then(...)
check could run before the input-mode trigger was in the DOM, falling
through to the wrong (button-mode) selector and timing out.

Switch to a retrying .should() that waits until either trigger form is
present before deciding which path to take.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@netchampfaris netchampfaris merged commit 0bb85fc into develop May 13, 2026
3 checks passed
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.

1 participant