chore: upgrade Vuetify 3→4 with breaking changes migration#1055
chore: upgrade Vuetify 3→4 with breaking changes migration#1055
Conversation
Co-authored-by: Rhilip <13842140+Rhilip@users.noreply.github.com>
Co-authored-by: Rhilip <13842140+Rhilip@users.noreply.github.com>
…or internalItem.raw) Co-authored-by: Rhilip <13842140+Rhilip@users.noreply.github.com>
Co-authored-by: Rhilip <13842140+Rhilip@users.noreply.github.com>
…er in Vuetify 4) Co-authored-by: Rhilip <13842140+Rhilip@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Upgrades the extension’s UI layer from Vuetify 3 to Vuetify 4 and migrates templates away from deprecated/breaking APIs to keep the Options UI functional across settings, overview pages, and dialogs.
Changes:
- Bump Vuetify dependency to
^4.0.0(and lockfile updates). - Migrate Vuetify template breaking changes (slot prop shape changes, deprecated grid props like
dense/justify/align, andno-guttersplacement). - Minor TypeScript typing adjustment in the Pinia WebExtension persistence plugin.
Reviewed changes
Copilot reviewed 26 out of 27 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| src/extends/pinia/webExtPersistence.ts | Tightens $patch typing for storage change hydration. |
| src/entries/options/views/Settings/SetSite/Index.vue | Updates header layout row props for Vuetify 4 grid changes. |
| src/entries/options/views/Settings/SetSite/AddDialog.vue | Updates v-autocomplete slot item shape usage for Vuetify 4. |
| src/entries/options/views/Settings/SetSearchSolution/SiteCategoryPanel.vue | Replaces deprecated align-self/justify props with utility classes. |
| src/entries/options/views/Settings/SetSearchSolution/Index.vue | Updates header layout row props for Vuetify 4 grid changes. |
| src/entries/options/views/Settings/SetMediaServer/Index.vue | Updates header layout row props for Vuetify 4 grid changes. |
| src/entries/options/views/Settings/SetMediaServer/AddDialog.vue | Updates v-autocomplete slot item shape usage for Vuetify 4. |
| src/entries/options/views/Settings/SetDownloader/Index.vue | Updates header layout row props for Vuetify 4 grid changes. |
| src/entries/options/views/Settings/SetDownloader/DefaultDownloaderEditDialog.vue | Updates v-autocomplete slot item shape usage for Vuetify 4. |
| src/entries/options/views/Settings/SetDownloader/AddDialog.vue | Updates v-autocomplete slot item shape usage for Vuetify 4. |
| src/entries/options/views/Settings/SetBase/UiWindow.vue | Migrates v-select slot item access and replaces dense with density. |
| src/entries/options/views/Settings/SetBase/SearchEntityWindow.vue | Replaces dense with density on grid rows. |
| src/entries/options/views/Settings/SetBackup/Index.vue | Updates header layout row props for Vuetify 4 grid changes. |
| src/entries/options/views/Settings/SetBackup/AddDialog.vue | Updates v-autocomplete slot item shape usage for Vuetify 4. |
| src/entries/options/views/Overview/SearchEntity/Index.vue | Fixes no-gutters placement for nested grid in data-table cell template. |
| src/entries/options/views/Overview/MyData/UserDataTimeline/Index.vue | Replaces deprecated justify/align-self grid props with utility classes. |
| src/entries/options/views/Overview/MyData/UserDataStatistic/Index.vue | Replaces deprecated justify/align-self grid props with utility classes. |
| src/entries/options/views/Overview/MyData/Index.vue | Updates header layout row props and replaces deprecated row/col props in table cell layouts. |
| src/entries/options/views/Overview/MyData/HistoryDataViewDialog.vue | Replaces deprecated row alignment/justify props with utility classes in table cell templates. |
| src/entries/options/views/Overview/MediaServerEntity/ItemInformationDialog.vue | Replaces deprecated row align prop with utility class. |
| src/entries/options/views/Overview/DownloadHistory/Index.vue | Updates header layout row props for Vuetify 4 grid changes. |
| src/entries/options/views/Layout/Navigation.vue | Replaces deprecated justify prop on footer row with utility class. |
| src/entries/options/views/Devtools/Debugger.vue | Replaces deprecated dense with density in grid rows. |
| src/entries/options/components/TorrentTitleTd.vue | Adjusts grid/container spacing and row configuration for Vuetify 4. |
| src/entries/options/components/SentToDownloaderDialog/Index.vue | Updates v-autocomplete slot item shape usage for Vuetify 4. |
| pnpm-lock.yaml | Locks Vuetify to v4 and updates dependent resolution metadata. |
| package.json | Upgrades vuetify dependency from v3 to v4. |
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
| @update:model-value="(e) => updateStoredMediaServerConfigByDefault(e)" | ||
| > | ||
| <template #selection="{ item: { raw: downloader } }"> | ||
| <v-list-item :prepend-avatar="getMediaServerIcon(downloader.type)" :title="downloader.type" /> | ||
| <template #selection="{ item }"> |
There was a problem hiding this comment.
updateStoredMediaServerConfigByDefault is declared as (e: TDownloaderKey), but this dialog’s selectedMediaServerType/item-value="type" are TMediaServerKey. The parameter type should match TMediaServerKey (and the log label storedDownloaderConfig should likely be updated too) to avoid incorrect typing/usage.
| @@ -91,7 +91,7 @@ async function saveSite() { | |||
| </v-list-item-title> | |||
| </v-list-item> | |||
| </template> | |||
| <template #item="{ props, item: { raw: site } }"> | |||
| <template #item="{ props, item: site }"> | |||
| <v-list-item v-bind="props"> | |||
There was a problem hiding this comment.
This autocomplete still uses :filter-keys="['raw.name', 'raw.urls', 'raw.aka']", but the slots were updated to treat item as the raw site object (no { raw: ... }). That mismatch can break filtering/search. Update filter-keys to match the new item shape (e.g. ['name', 'urls', 'aka']) or keep slot props consistent with a { raw } structure.
| @update:model-value="restoreAddTorrentOptions" | ||
| > | ||
| <template #selection="{ item: { raw: downloader } }"> | ||
| <template #selection="{ item: downloader }"> | ||
| <v-list-item | ||
| :prepend-avatar="getDownloaderIcon(downloader.type)" |
There was a problem hiding this comment.
The slots were migrated to treat item as the raw downloader object (item: downloader), but this autocomplete’s :filter-keys still targets raw.* fields. Please align filter-keys with the actual item shape to ensure the autocomplete search still works.
| t('SetDownloader.add.NoneSelectNotice') | ||
| " | ||
| @update:model-value="(e) => updateStoredDownloaderConfigByDefault(e)" | ||
| > | ||
| <template #selection="{ item: { raw: backupServer } }"> | ||
| <v-list-item :prepend-avatar="getBackupServerIcon(backupServer.type)" :title="backupServer.type" /> | ||
| <template #selection="{ item }"> |
There was a problem hiding this comment.
In this backup-server dialog the handler is named updateStoredDownloaderConfigByDefault, but it actually builds a backup-server config. Renaming it (and the @update:model-value call site) to something like updateStoredBackupServerConfigByDefault would reduce confusion and avoid copy/paste leakage from the downloader dialogs.
| @update:model-value="(e) => updateStoredDownloaderConfigByDefault(e)" | ||
| > | ||
| <template #selection="{ item: { raw: downloader } }"> | ||
| <v-list-item :prepend-avatar="getDownloaderIcon(downloader.type)" :title="downloader.type" /> | ||
| <template #selection="{ item }"> | ||
| <v-list-item :prepend-avatar="getDownloaderIcon(item.type)" :title="item.type" /> | ||
| </template> | ||
| <template #item="{ props, item: { raw: downloader } }"> | ||
| <v-list-item | ||
| v-bind="props" | ||
| :prepend-avatar="getDownloaderIcon(downloader.type)" | ||
| :title="downloader.type" | ||
| > | ||
| <template #item="{ props, item }"> |
There was a problem hiding this comment.
After switching the #selection/#item slots to treat item as the raw object (using item.type), this autocomplete still uses :filter-keys="['raw.type']". That leaves filtering inconsistent with the slot assumptions and can break search. Align these by either updating filter-keys to match the new item shape (e.g. ['type']) or adjusting the slots back to the structure that includes raw.
| persistent-hint | ||
| @update:model-value="(e) => updateStoredMediaServerConfigByDefault(e)" | ||
| > | ||
| <template #selection="{ item: { raw: downloader } }"> | ||
| <v-list-item :prepend-avatar="getMediaServerIcon(downloader.type)" :title="downloader.type" /> | ||
| <template #selection="{ item }"> | ||
| <v-list-item :prepend-avatar="getMediaServerIcon(item.type)" :title="item.type" /> | ||
| </template> | ||
| <template #item="{ props, item: { raw: downloader } }"> | ||
| <v-list-item | ||
| v-bind="props" | ||
| :prepend-avatar="getMediaServerIcon(downloader.type)" | ||
| :title="downloader.type" | ||
| > | ||
| <template #item="{ props, item }"> |
There was a problem hiding this comment.
Same inconsistency here: the slots now use item.type as if item is the raw value, but :filter-keys="['raw.type']" still assumes a { raw: ... } structure. Please align filter-keys with the slot item shape to keep autocomplete searching functional.
Scans and fixes Vuetify 3→4 breaking changes across the codebase. Three categories of issues addressed.
Fixed in prior commits
item.rawremoval in slot templates — In v4,iteminv-data-tablecolumn slots is the raw row data directly (no.rawindirection). Applied across all data table slot templates.Deprecated
v-row/v-colprops —align,justify,align-{breakpoint},justify-{breakpoint}, anddenseare deprecated in v4. Replaced with CSS utility classes (class="align-center") or the newdensityprop across 10 files.Fixed in this commit
no-guttersmisplaced on<v-container>(SearchEntity/Index.vue:378) —no-guttersis av-rowprop; it was never valid onv-container. Moved to the inner<v-row>elements.No changes required
v-select/v-autocomplete#itemand#selectionslots — already useitemas raw value (correct for v4)VColorInputfromvuetify/labs/VColorInput— still valid in v4 (remains in labs)VTimePicker— promoted from labs to main package in v4; auto-import works correctlyv-formdefault slot props — not used anywhere; the "unreffed slot props" breaking change doesn't apply✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.