feat!: Migrate dashboard to frappe-ui v1 (and Vite 8)#272
Merged
Conversation
Bump frappe-ui 0.1.257 -> 1.0.0-beta.25 and remove the dashboard/frappe-ui git submodule; the npm package is now the single source. Simplify vite.config.js to a static config that always uses the published plugin, and exclude frappe-ui from esbuild pre-bundling since it ships as source importing ~icons/lucide/* virtuals that only the Vite plugin resolves. Fix four type errors surfaced by v1's stricter types (nullable length guard, Combobox string|null emit, FileUploader error slot prop). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Convert all Dialog usages from the deprecated `options` blob and `#body-content`/`#body-title`/`#body` slots to flat top-level props and the default/`#title` slots (`#body` -> `bare` prop). Flatten the withdraw dialog's icon to `theme` and rename its lucide icon to `triangle-alert`. Replace remaining feather icon strings with `lucide-` names.
The v1 ink-blue scale defines shades 1-3 only, so `hover:bg-ink-blue-4` resolved to nothing and the Join Zoom button no longer darkened on hover. Use the raw blue-700 palette shade (one step darker than ink-blue-3) to restore the hover feedback.
The Input component is deprecated in frappe-ui v1 and was registered globally but never used in any template. Remove its import and registration; TextInput and FormControl remain.
Excluding frappe-ui from esbuild pre-bundling (needed for its ~icons/lucide virtuals) left its bundled CJS feather-icons without ESM interop, so the FeatherIcon default import failed and the app never mounted (blank page). Pre-bundle feather-icons, including frappe-ui's nested copy via the `>` dep path, to restore the default export.
v1 renamed the design tokens (surface-white -> surface-base, expanded the ink accent scales, merged text size+weight into single classes). The old class names resolved to undefined CSS variables under v1, so text and surface colors rendered blank. Run the official tokens-v2 codemod across the dashboard to adopt the new names. Also give the app Layout a theme-aware background (bg-surface-base) and base text color. Previously the root had no background, so with the default dark theme the light ink text sat on an unstyled white page and was invisible. Both light and dark themes now render coherently.
Replace the deprecated TextEditor with the headless Editor from frappe-ui/editor, composed with EditorFixedMenu and EditorContent. The kit runs without the media extensions since proposals have no upload handler wired. Pin the ProseMirror packages via resolutions: the tree carried both a stale hoisted copy and the one tiptap resolves, which bundled the editor stack twice. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Vite 8 replaces esbuild with rolldown for bundling. @vitejs/plugin-vue 6 is the first release listing Vite 8 in its peer range. vue-tsc moves with it; nothing else is Vite-coupled. Drop unplugin-auto-import: it was never wired into vite.config.js, and pinning it at the root only forced frappe-ui to nest the 19.x its lucideIcons plugin actually imports. frappe-ui stays out of pre-bundling, but for a new reason — rolldown resolves the extensionless `#molecules/*` specifiers esbuild could not, so the note about esbuild no longer applies. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Greptile SummaryThis PR migrates the dashboard to frappe-ui v1 and Vite 8. The main changes are:
Confidence Score: 5/5This looks safe to merge.
|
| Filename | Overview |
|---|---|
| dashboard/package.json | Upgrades frappe-ui and the Vite toolchain, pins ProseMirror packages, and removes an unused development dependency. |
| dashboard/vite.config.js | Updates dependency optimization and module resolution for Vite 8 and frappe-ui v1. |
| dashboard/tailwind.config.js | Uses the frappe-ui v1 Tailwind preset and includes its component and editor source paths. |
| dashboard/src/layouts/Layout.vue | Adds theme-aware background and foreground tokens to the dashboard layout. |
| dashboard/src/components/ProposalEditDialog.vue | Migrates proposal editing to the headless frappe-ui editor and RichTextKit. |
| dashboard/src/components/AddOnPreferenceDialog.vue | Migrates the add-on preferences dialog to frappe-ui v1 props and slots. |
Reviews (3): Last reviewed commit: "fix(dashboard): inline add-on dialog pro..." | Re-trigger Greptile
frappe-ui v1 renders a select as a combobox button that opens a listbox instead of a native `select`, so the old locator matched nothing and `selectOption` had nothing to act on. Pick the option by clicking it. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The add-on dialog was the only one still passing its title and size through a `v-bind` object; inline them like the other dialogs, and translate the title while it moves. Building the combobox matcher with `new RegExp(label)` broke on any label containing regex metacharacters. A plain string already matches case-insensitively on a substring. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
There was a problem hiding this comment.
harshtandiya has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
There was a problem hiding this comment.
harshtandiya has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.
Contributor
|
Successfully created backport PR for |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Moves the dashboard from
frappe-ui@0.1.257to1.0.0-beta.25, then upgrades the build toolchain to Vite 8.Why this is more than a version bump
Component and JS APIs in frappe-ui v1 are backward compatible — deprecated paths still work and just warn. The design-token layer and the theme system are hard breaks, and they are what actually broke the running app: token names were renamed (
surface-white→surface-base, ink scales went to 1–10, typography classes merged), and v1 tokens are theme-aware (darkMode: ['selector', '[data-theme="dark"]']) where v0 ignoreddata-themeentirely. With the default dark theme, light ink text was landing on an unstyled white layout — invisible.What's in here
5cd520cdashboard/frappe-uisubmodule, simplifyvite.config.js0ffd66ed0cc4ffDialogprops + lucide icons (14 dialogs, 4 icon sites)d0ea5c2becb2b8Inputglobal registration8e78e75tokens-v2codemod (38 files) + theme-aware Layout background830d736TextEditor→ headlessEditor+RichTextKit4a90e41@vitejs/plugin-vue6,vue-tsc3.3; drop deadunplugin-auto-importThe submodule removal makes npm the single source of truth — it was a redundant local patch plus ~30k lines of format churn and a second version to keep in sync.
Notes for review
Two dev-only traps that are runtime-only — they pass typecheck and build, and only show up when you load the page:
frappe-uifrom pre-bundling (needed for its~icons/lucide/*virtuals) kills CJS interop for its nestedfeather-icons, so the app never mounts — blank page. Hence theoptimizeDeps.includeentry.data-theme="dark"default meant light ink text on an unstyled white layout. Hence the codemod plusbg-surface-baseon the Layout root.ProseMirror is pinned via
resolutions. yarn had hoisted a stale set (state@1.4.2,view@1.30.2,model@1.19.0,transform@1.7.1) alongside the versions tiptap resolves, so the editor stack was being bundled twice. Pinning cut theProposalDetailschunk from 1295 kB to 935 kB.optimizeDeps.exclude: ["frappe-ui"]has to stay on Vite 8, but for a new reason. Rolldown resolves the extensionless#molecules/*specifiers that esbuild could not, so the original justification is gone — butfrappe-uiandfrappe-ui/editorpre-bundle as two separate entries that each inline their own ProseMirror copy, which gives two selection-JSON-ID registries and the editor dies onDuplicate use of selection JSON ID gapcursor. Neitherresolve.dedupenor pre-bundling ProseMirror explicitly merges the entries. The comment invite.config.jsrecords this.Default theme stays dark (
Navbar.vue,useStorage("user-theme", "dark")) — now functional in both modes.Known cosmetic gap, not fixed: frappe-ui's
MenuItemsevaluates command availability during render, beforeEditorContentmounts the ProseMirror view, and only recomputes on an editor transaction. Editor toolbar buttons therefore render disabled until the first click into the editor, then stay enabled. Deliberately left alone rather than worked around — the first interaction is clicking into the editor anyway.Verification
Typecheck and build clean. Vite 8 build is 5.98s → 2.25s with better chunking (
index728 kB → 411 kB).Exercised in a browser on both the dev server and the production build: account pages (bookings, tickets, proposals, sponsorships), check-in, home — all render with no console errors. Proposal editor round-tripped end to end (typed, bolded via the toolbar, saved, confirmed
<p><strong>…</strong></p>persisted), test record reset afterward.Not covered: a full logged-in click-through of the booking and payment flows. Those use the same tokens and
dark:variants so they should follow, but they have not been exercised against real data.Deferred:
TextEditorelsewhere is untouched; only the proposal editor moved to the newEditor.🤖 Generated with Claude Code