From 38d8c243f3f35c0fe899de03b0cf0a2d56b7f3bb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pablo=20de=20la=20Pen=CC=83a?=
Date: Tue, 8 Sep 2026 09:27:17 +0100
Subject: [PATCH] feat: migrate admin UI from Vue 2 to Vue 3
Vue 2 is EOL; keep the PHP in-DOM admin islands and dashboard widgets on Options API so they match Media Manager V2.
Co-authored-by: Cursor
---
.eslintrc | 2 +-
assets/js/admin.ui.js | 50 +++++++++++--------
assets/js/components/Dashboard/Grid.vue | 8 +--
assets/js/components/DashboardWidgets.js | 14 +++---
assets/js/components/admin-ui/CheckBox.vue | 11 ++--
assets/js/components/admin-ui/CreateModal.vue | 8 +--
assets/js/components/admin-ui/FilterModal.vue | 11 ++--
assets/js/components/admin-ui/SearchModal.vue | 44 ++++++++++++----
assets/js/components/admin-ui/SideNav.vue | 32 ++++++------
.../sass/admin-plugins/DashboardWidgets.scss | 25 ++++------
assets/sass/admin.ui.scss | 3 +-
package.json | 16 +++---
webpack.config.js | 17 +++++--
13 files changed, 139 insertions(+), 102 deletions(-)
diff --git a/.eslintrc b/.eslintrc
index adf1f103..0875b9f4 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -1,7 +1,7 @@
{
"extends": [
"eslint:recommended",
- "plugin:vue/recommended",
+ "plugin:vue/vue3-recommended",
],
"env": {
"browser": true,
diff --git a/assets/js/admin.ui.js b/assets/js/admin.ui.js
index f1be42a7..30d6d47b 100644
--- a/assets/js/admin.ui.js
+++ b/assets/js/admin.ui.js
@@ -7,6 +7,8 @@
* Source Imports 🛠
*/
import '../sass/admin.ui.scss';
+import {createApp} from 'vue';
+import mitt from 'mitt';
import CreateModal from './components/admin-ui/CreateModal.vue';
import FilterModal from './components/admin-ui/FilterModal.vue';
import MenuCollapse from './components/admin-ui/MenuCollapse.vue';
@@ -14,34 +16,42 @@ import MenuToggle from './components/admin-ui/MenuToggle.vue';
import ModalButton from './components/admin-ui/ModalButton.vue';
import SearchModal from './components/admin-ui/SearchModal.vue';
import SideNav from './components/admin-ui/SideNav.vue';
-import Vue from 'vue/dist/vue.esm';
import vSelect from 'vue-select';
import VueSweetalert2 from 'vue-sweetalert2';
-Vue.component('v-select', vSelect);
-Vue.use(VueSweetalert2);
+const emitter = mitt();
+const $bus = {
+ $on: (...args) => emitter.on(...args),
+ $off: (...args) => emitter.off(...args),
+ $emit: (...args) => emitter.emit(...args),
+};
-/**
- * Component Imports 🏗
- */
-Vue.component('CreateModal', CreateModal);
-Vue.component('FilterModal', FilterModal);
-Vue.component('MenuCollapse', MenuCollapse);
-Vue.component('MenuToggle', MenuToggle);
-Vue.component('ModalButton', ModalButton);
-Vue.component('SearchModal', SearchModal);
-Vue.component('SideNav', SideNav);
-
-/**
- * Bus 🚌
- */
-Vue.prototype.$bus = new Vue();
+const components = {
+ 'v-select': vSelect,
+ CreateModal,
+ FilterModal,
+ MenuCollapse,
+ MenuToggle,
+ ModalButton,
+ SearchModal,
+ SideNav,
+};
/**
* App kickoff 🚀
+ *
+ * Each .admin-vue-app island is a separate createApp() so PHP in-DOM
+ * templates (header, sidenav, footer) compile independently, while
+ * sharing one event bus and the same component / plugin registrations.
*/
for (let el of document.getElementsByClassName('admin-vue-app')) {
- new Vue({
- el: el
+ const app = createApp({});
+
+ Object.entries(components).forEach(([name, component]) => {
+ app.component(name, component);
});
+
+ app.use(VueSweetalert2);
+ app.config.globalProperties.$bus = $bus;
+ app.mount(el);
}
diff --git a/assets/js/components/Dashboard/Grid.vue b/assets/js/components/Dashboard/Grid.vue
index fb663962..5a7ce4b2 100644
--- a/assets/js/components/Dashboard/Grid.vue
+++ b/assets/js/components/Dashboard/Grid.vue
@@ -28,7 +28,7 @@
v-bind:class="classes.grid"
>
h(Grid, {
- props: {
- adminController: adminController,
- userWidgets: userWidgets,
- }
+ this.app = createApp({
+ render: () => h(Grid, {
+ adminController: adminController,
+ userWidgets: userWidgets,
}),
});
+ this.vue = this.app.mount(this.el);
}
}
diff --git a/assets/js/components/admin-ui/CheckBox.vue b/assets/js/components/admin-ui/CheckBox.vue
index 52c0a7b0..d283ad7b 100644
--- a/assets/js/components/admin-ui/CheckBox.vue
+++ b/assets/js/components/admin-ui/CheckBox.vue
@@ -14,17 +14,14 @@