You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Wave A — preparation, merged to main, shipped on Vue 2.7
Wave A ships as three PRs, one per section below. Each section is a single theme, is
independently releasable, and is independently revertible. The item IDs (A1…A18) are stable and
still index the per-item detail in §3; only the packaging changed.
Merge order is A-1 → A-2 → A-3, because A-3 contains A11, which rewrites the import line of nearly
every component and will conflict with anything still in flight.
A-1 — Template API alignment (@nextcloud/vue prop, event and slot renames) #13589
Everything the v8.40 forward-compatible aliases already accept: props renamed, events renamed, slots
renamed, booleans inverted. Mechanical, template-only, no behaviour change on Vue 2.7. Land the items
in the listed order and rebase between them — they touch overlapping component files.
A12 — Drop the exact prop (Envelope.vue, EnvelopeSkeleton.vue)
A-2 — Retire the Vue-2-only dependencies and component APIs
Everything that has to stop being a Vue-2-only package or a removed-in-v9 component API. Few files,
but the only hand-written UI in Wave A, so this is the section that needs manual testing. Give each
replacement its own commit and its own QA pass — see §8.
A2 — Drop the unused v-tooltip plugin from src/main.js (imported, registered, never used in a template)
A8 — isMobile mixin → useIsMobile() composable (src/components/MailboxThread.vue, the only user)
A10 — FilePickerVue component → getFilePickerBuilder() function (4 files)
A13 — Replace vue-autosize (Vue-2-only, no successor)
Everything that changes how modules are imported rather than how components are used, plus the
written-down audit of what Wave B will have to repair. A11 is the whole reason this section is last.
A1 — import { translate as t } → import { t } (18 sites); same for translatePlural as n
A3 — Replace Vue.set/Vue.delete with a local set/del shim (55 call sites, 3 files)
A11 — Barrel imports from '@nextcloud/vue' → per-component subpath imports (~50 files) — last item in the wave
A18 — Deep-selector and internal-class-name audit (105 hits) — write down what will break, fix what can be fixed early
The three are close in size for different reasons: A-1 is the most files but one changed line per
site; A-2 is the fewest files but the only real new code; A-3 is ~50 mechanical files plus a
document. If A-2's replacements turn out larger than estimated, split A14–A16 out rather than
letting the PR grow past a few thousand lines.
Wave B — the flip, stacked onto the vue3 branch
Nothing here works on Vue 2. Land these onto vue3, then merge vue3 → mainonce.
Related to nextcloud/groupware#64
Wave A — preparation, merged to
main, shipped on Vue 2.7Wave A ships as three PRs, one per section below. Each section is a single theme, is
independently releasable, and is independently revertible. The item IDs (
A1…A18) are stable andstill index the per-item detail in §3; only the packaging changed.
Merge order is A-1 → A-2 → A-3, because A-3 contains A11, which rewrites the import line of nearly
every component and will conflict with anything still in flight.
A-1 — Template API alignment (
@nextcloud/vueprop, event and slot renames) #13589Everything the v8.40 forward-compatible aliases already accept: props renamed, events renamed, slots
renamed, booleans inverted. Mechanical, template-only, no behaviour change on Vue 2.7. Land the items
in the listed order and rebase between them — they touch overlapping component files.
:checked/@update:checked→v-model/@update:model-valueonNcCheckboxRadioSwitch,NcActionCheckbox,NcActionRadio(13 files):value/@update:value/@input→v-model/@update:model-valueon the 13 other input components (32 files)type="primary|secondary|…"→variant=, andnative-type→typeonNcButton/NcActions/NcDialogButton#default→#iconslot onNcInputField/NcTextField/NcPasswordFieldcanClose,focusTrap,closeOnClickOutside,enableSwipe,showUserStatus*: feat(vue3): inverted boolean props #13624exactprop (Envelope.vue,EnvelopeSkeleton.vue)A-2 — Retire the Vue-2-only dependencies and component APIs
Everything that has to stop being a Vue-2-only package or a removed-in-v9 component API. Few files,
but the only hand-written UI in Wave A, so this is the section that needs manual testing. Give each
replacement its own commit and its own QA pass — see §8.
v-tooltipplugin fromsrc/main.js(imported, registered, never used in a template)isMobilemixin →useIsMobile()composable (src/components/MailboxThread.vue, the only user)FilePickerVuecomponent →getFilePickerBuilder()function (4 files)vue-autosize(Vue-2-only, no successor)@riophae/vue-treeselectinMailboxInlinePicker.vue(Vue-2-only, unmaintained) — revives #13412vue-tabs-componentinAccountForm.vue(Vue-2-only) — revives #13411vue-dndropinquickActions/Settings.vue(Vue-2-only) — revives #13413emojiSearch/emojiAddRecentimport path for v9 (TextEditor.vue)A-3 — Module boundaries and the v9 audit
Everything that changes how modules are imported rather than how components are used, plus the
written-down audit of what Wave B will have to repair. A11 is the whole reason this section is last.
import { translate as t }→import { t }(18 sites); same fortranslatePlural as nVue.set/Vue.deletewith a localset/delshim (55 call sites, 3 files)from '@nextcloud/vue'→ per-component subpath imports (~50 files) — last item in the waveThe three are close in size for different reasons: A-1 is the most files but one changed line per
site; A-2 is the fewest files but the only real new code; A-3 is ~50 mechanical files plus a
document. If A-2's replacements turn out larger than estimated, split A14–A16 out rather than
letting the PR grow past a few thousand lines.
Wave B — the flip, stacked onto the
vue3branchNothing here works on Vue 2. Land these onto
vue3, then mergevue3→mainonce.patch-package: fix or droppatches/splitpanes+2.4.1.patch(v9 ships splitpanes 4.x)createApp(#13405/#13408, pick one, rebase)createRouter/createWebHistory(folded into B3).sync→v-model:prop(#13410, rebase — 13 sites, 10 files)@ckeditor/ckeditor5-vue(#13414, rebase)vue-shortkey→vue3-shortkeyvue-frag(NavigationAccount.vue) — Vue 3 has native fragments.nativemodifiers (4 sites) and add the correspondingemitsdeclarations<template functional>→ plain SFC (src/components/icons/JunkIcon.vue)<transition>class renames:v-enter→v-enter-from,v-leave→v-leave-from(3 components)set/delshim from A3 into plain assignment (one-file diff)@vue/test-utilsv1 → v2 (#13415, rebase)vitest.config.js:@vitejs/plugin-vue2→@vitejs/plugin-vueeslint.config.mjs:recommendedVue2→recommended, thennpm run lint:fix@pinia/testingbump, dropPiniaVuePluginemits:declarations across components (ESLintvue/require-explicit-emits)Nextcloud.jsmixin in favour ofapp.config.globalPropertiesor per-file importsbox-sizing: border-boxon modals/popovers,vs__*(vue-select 4),@vuepic/vue-datepickerreplacingmx-datepickernpm run buildclean,npm run lintclean,npm run stylelintclean,npm run test:unitgreenWave C — after the flip
npm run test:e2e)@nextcloud/vuefor anything broken in the library itselfappinfo/info.xmlif the Nextcloud minimum has to move<script setup>, TypeScript