Skip to content

chore: upgrade Vuetify 3→4 with breaking changes migration#1055

Draft
Copilot wants to merge 7 commits intomasterfrom
copilot/upgrade-vuetify-3-to-4
Draft

chore: upgrade Vuetify 3→4 with breaking changes migration#1055
Copilot wants to merge 7 commits intomasterfrom
copilot/upgrade-vuetify-3-to-4

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Mar 1, 2026

Scans and fixes Vuetify 3→4 breaking changes across the codebase. Three categories of issues addressed.

Fixed in prior commits

  • item.raw removal in slot templates — In v4, item in v-data-table column slots is the raw row data directly (no .raw indirection). Applied across all data table slot templates.

  • Deprecated v-row/v-col propsalign, justify, align-{breakpoint}, justify-{breakpoint}, and dense are deprecated in v4. Replaced with CSS utility classes (class="align-center") or the new density prop across 10 files.

Fixed in this commit

  • no-gutters misplaced on <v-container> (SearchEntity/Index.vue:378) — no-gutters is a v-row prop; it was never valid on v-container. Moved to the inner <v-row> elements.
- <v-container no-gutters>
-   <v-row>
+ <v-container>
+   <v-row no-gutters>
      ...
    </v-row>
-   <v-row v-if="...">
+   <v-row v-if="..." no-gutters>

No changes required

  • v-select/v-autocomplete #item and #selection slots — already use item as raw value (correct for v4)
  • VColorInput from vuetify/labs/VColorInput — still valid in v4 (remains in labs)
  • VTimePicker — promoted from labs to main package in v4; auto-import works correctly
  • v-form default 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.

Copilot AI and others added 2 commits March 1, 2026 03:06
Co-authored-by: Rhilip <13842140+Rhilip@users.noreply.github.com>
Co-authored-by: Rhilip <13842140+Rhilip@users.noreply.github.com>
Copilot AI changed the title [WIP] Upgrade project from Vuetify 3 to 4 and scan for breaking changes chore: upgrade Vuetify 3 → 4, fix breaking slot API changes Mar 1, 2026
…or internalItem.raw)

Co-authored-by: Rhilip <13842140+Rhilip@users.noreply.github.com>
Co-authored-by: Rhilip <13842140+Rhilip@users.noreply.github.com>
Copilot AI changed the title chore: upgrade Vuetify 3 → 4, fix breaking slot API changes fix: Vuetify 4 grid migration — VRow/VCol deprecated prop removal Mar 1, 2026
Copilot stopped work on behalf of Rhilip due to an error March 1, 2026 04:11
…er in Vuetify 4)

Co-authored-by: Rhilip <13842140+Rhilip@users.noreply.github.com>
Copilot AI changed the title fix: Vuetify 4 grid migration — VRow/VCol deprecated prop removal fix: Vuetify 3→4 breaking changes migration Mar 1, 2026
@Rhilip Rhilip changed the title fix: Vuetify 3→4 breaking changes migration chore: upgrade Vuetify 3→4 with breaking changes migration Mar 1, 2026
@Rhilip Rhilip requested a review from Copilot March 1, 2026 11:38
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

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, and no-gutters placement).
  • 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

Comment on lines 94 to +96
@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 }">
Copy link

Copilot AI Mar 1, 2026

Choose a reason for hiding this comment

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

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.

Copilot uses AI. Check for mistakes.
Comment on lines 84 to 95
@@ -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">
Copy link

Copilot AI Mar 1, 2026

Choose a reason for hiding this comment

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

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.

Copilot uses AI. Check for mistakes.
Comment on lines 216 to 220
@update:model-value="restoreAddTorrentOptions"
>
<template #selection="{ item: { raw: downloader } }">
<template #selection="{ item: downloader }">
<v-list-item
:prepend-avatar="getDownloaderIcon(downloader.type)"
Copy link

Copilot AI Mar 1, 2026

Choose a reason for hiding this comment

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

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.

Copilot uses AI. Check for mistakes.
Comment on lines 93 to +97
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 }">
Copy link

Copilot AI Mar 1, 2026

Choose a reason for hiding this comment

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

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.

Copilot uses AI. Check for mistakes.
Comment on lines 105 to +110
@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 }">
Copy link

Copilot AI Mar 1, 2026

Choose a reason for hiding this comment

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

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.

Copilot uses AI. Check for mistakes.
Comment on lines 93 to +99
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 }">
Copy link

Copilot AI Mar 1, 2026

Choose a reason for hiding this comment

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

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.

Copilot uses AI. Check for mistakes.
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.

3 participants