From 14bdc11deeaee97cac24c8c80622bf81fc34c2db Mon Sep 17 00:00:00 2001 From: Ferdinand Thiessen Date: Tue, 20 Feb 2024 13:08:45 +0100 Subject: feat(settings): Refactor routing code to use named router views Signed-off-by: Ferdinand Thiessen --- apps/settings/src/App.vue | 31 ------ apps/settings/src/main-apps-users-management.js | 55 ---------- apps/settings/src/main-apps-users-management.ts | 61 +++++++++++ apps/settings/src/router.js | 136 ------------------------ apps/settings/src/router/index.ts | 42 ++++++++ apps/settings/src/router/routes.ts | 52 +++++++++ apps/settings/src/views/SettingsApp.vue | 34 ++++++ apps/settings/src/webpack.shim.d.ts | 1 + webpack.modules.js | 2 +- 9 files changed, 191 insertions(+), 223 deletions(-) delete mode 100644 apps/settings/src/App.vue delete mode 100644 apps/settings/src/main-apps-users-management.js create mode 100644 apps/settings/src/main-apps-users-management.ts delete mode 100644 apps/settings/src/router.js create mode 100644 apps/settings/src/router/index.ts create mode 100644 apps/settings/src/router/routes.ts create mode 100644 apps/settings/src/views/SettingsApp.vue create mode 100644 apps/settings/src/webpack.shim.d.ts diff --git a/apps/settings/src/App.vue b/apps/settings/src/App.vue deleted file mode 100644 index 21565aea9ad..00000000000 --- a/apps/settings/src/App.vue +++ /dev/null @@ -1,31 +0,0 @@ - - - - - diff --git a/apps/settings/src/main-apps-users-management.js b/apps/settings/src/main-apps-users-management.js deleted file mode 100644 index f81670fa624..00000000000 --- a/apps/settings/src/main-apps-users-management.js +++ /dev/null @@ -1,55 +0,0 @@ -/** - * @copyright Copyright (c) 2018 John Molakvoæ - * - * @author John Molakvoæ - * @author rakekniven - * @author Roeland Jago Douma - * - * @license AGPL-3.0-or-later - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - * - */ - -import Vue from 'vue' -import VTooltip from 'v-tooltip' -import { sync } from 'vuex-router-sync' - -import App from './App.vue' -import router from './router.js' -import store from './store/index.js' - -Vue.use(VTooltip, { defaultHtml: false }) - -sync(store, router) - -// CSP config for webpack dynamic chunk loading -// eslint-disable-next-line camelcase -__webpack_nonce__ = btoa(OC.requestToken) - -// bind to window -Vue.prototype.t = t -Vue.prototype.n = n -Vue.prototype.OC = OC -Vue.prototype.OCA = OCA -// eslint-disable-next-line camelcase -Vue.prototype.oc_userconfig = oc_userconfig - -const app = new Vue({ - router, - store, - render: h => h(App), -}).$mount('#content') - -export { app, router, store } diff --git a/apps/settings/src/main-apps-users-management.ts b/apps/settings/src/main-apps-users-management.ts new file mode 100644 index 00000000000..37d7e9ba821 --- /dev/null +++ b/apps/settings/src/main-apps-users-management.ts @@ -0,0 +1,61 @@ +/** + * @copyright Copyright (c) 2018 John Molakvoæ + * + * @author John Molakvoæ + * @author rakekniven + * @author Roeland Jago Douma + * + * @license AGPL-3.0-or-later + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +import Vue from 'vue' +import VTooltip from 'v-tooltip' +import { sync } from 'vuex-router-sync' +import { translate as t, translatePlural as n } from '@nextcloud/l10n' + +import SettingsApp from './views/SettingsApp.vue' +import router from './router/index.ts' +import store from './store/index.js' +import { getRequestToken } from '@nextcloud/auth' +import { PiniaVuePlugin, createPinia } from 'pinia' + +Vue.use(VTooltip, { defaultHtml: false }) + +sync(store, router) + +// CSP config for webpack dynamic chunk loading +// eslint-disable-next-line camelcase +__webpack_nonce__ = btoa(getRequestToken() ?? '') + +// bind to window +Vue.prototype.t = t +Vue.prototype.n = n +Vue.prototype.OC = window.OC +Vue.prototype.OCA = window.OCA +// @ts-expect-error This is a private property we use +Vue.prototype.oc_userconfig = window.oc_userconfig +Vue.use(PiniaVuePlugin) + +const pinia = createPinia() + +export default new Vue({ + router, + store, + pinia, + render: h => h(SettingsApp), + el: '#content', +}) diff --git a/apps/settings/src/router.js b/apps/settings/src/router.js deleted file mode 100644 index 977cab2de96..00000000000 --- a/apps/settings/src/router.js +++ /dev/null @@ -1,136 +0,0 @@ -/** - * @copyright Copyright (c) 2018 John Molakvoæ - * - * @author John Molakvoæ - * @author Julius Härtl - * @author Roeland Jago Douma - * - * @license AGPL-3.0-or-later - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - * - */ - -import Vue from 'vue' -import Router from 'vue-router' -import { generateUrl } from '@nextcloud/router' -import { APPS_SECTION_ENUM } from './constants/AppsConstants.js' -import store from './store/index.js' -import { setPageHeading } from '../../../core/src/OCP/accessibility.js' - -// Dynamic loading -const Users = () => import(/* webpackChunkName: 'settings-users' */'./views/Users.vue') -const Apps = () => import(/* webpackChunkName: 'settings-apps-view' */'./views/Apps.vue') - -Vue.use(Router) - -/* - * This is the list of routes where the vuejs app will - * take over php to provide data - * You need to forward the php routing (routes.php) to - * the settings-vue template, where the vue-router will - * ensure the proper route. - * ⚠️ Routes needs to match the php routes. - */ -const baseTitle = document.title -const router = new Router({ - mode: 'history', - // if index.php is in the url AND we got this far, then it's working: - // let's keep using index.php in the url - base: generateUrl(''), - linkActiveClass: 'active', - routes: [ - { - path: '/:index(index.php/)?settings/users', - component: Users, - props: true, - name: 'users', - meta: { - title: () => { - return t('settings', 'Active users') - }, - }, - children: [ - { - path: ':selectedGroup', - name: 'group', - meta: { - title: (to) => { - if (to.params.selectedGroup === 'admin') { - return t('settings', 'Admins') - } - if (to.params.selectedGroup === 'disabled') { - return t('settings', 'Disabled users') - } - return decodeURIComponent(to.params.selectedGroup) - }, - }, - component: Users, - }, - ], - }, - { - path: '/:index(index.php/)?settings/apps', - component: Apps, - props: true, - name: 'apps', - meta: { - title: () => { - return t('settings', 'Your apps') - }, - }, - children: [ - { - path: ':category', - name: 'apps-category', - meta: { - title: async (to) => { - if (to.name === 'apps') { - return t('settings', 'Your apps') - } - if (APPS_SECTION_ENUM[to.params.category]) { - return APPS_SECTION_ENUM[to.params.category] - } - await store.dispatch('getCategories') - const category = store.getters.getCategoryById(to.params.category) - if (category.displayName) { - return category.displayName - } - }, - }, - component: Apps, - children: [ - { - path: ':id', - name: 'apps-details', - component: Apps, - }, - ], - }, - ], - }, - ], -}) - -router.afterEach(async (to) => { - const metaTitle = await to.meta.title?.(to) - if (metaTitle) { - document.title = `${metaTitle} - ${baseTitle}` - setPageHeading(metaTitle) - } else { - document.title = baseTitle - } -}) - -export default router diff --git a/apps/settings/src/router/index.ts b/apps/settings/src/router/index.ts new file mode 100644 index 00000000000..6dbeea2cd57 --- /dev/null +++ b/apps/settings/src/router/index.ts @@ -0,0 +1,42 @@ +/** + * @copyright Copyright (c) 2018 John Molakvoæ + * + * @author John Molakvoæ + * @author Julius Härtl + * @author Roeland Jago Douma + * @author Ferdinand Thiessen + * + * @license AGPL-3.0-or-later + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +import Vue from 'vue' +import Router from 'vue-router' +import { generateUrl } from '@nextcloud/router' +import routes from './routes.ts' + +Vue.use(Router) + +const router = new Router({ + mode: 'history', + // if index.php is in the url AND we got this far, then it's working: + // let's keep using index.php in the url + base: generateUrl(''), + linkActiveClass: 'active', + routes, +}) + +export default router diff --git a/apps/settings/src/router/routes.ts b/apps/settings/src/router/routes.ts new file mode 100644 index 00000000000..7d6b2da3bee --- /dev/null +++ b/apps/settings/src/router/routes.ts @@ -0,0 +1,52 @@ +import type { RouteConfig } from 'vue-router' + +import { defineAsyncComponent } from 'vue' + +// Dynamic loading +const AppStore = defineAsyncComponent(() => import(/* webpackChunkName: 'settings-apps-view' */'../views/AppStore.vue')) +const AppStoreNavigation = defineAsyncComponent(() => import(/* webpackChunkName: 'settings-apps-view' */'../views/AppStoreNavigation.vue')) +const AppstoreSidebar = defineAsyncComponent(() => import(/* webpackChunkName: 'settings-apps-view' */'../views/AppstoreSidebar.vue')) + +const UserManagement = defineAsyncComponent(() => import(/* webpackChunkName: 'settings-users' */'../views/UserManagement.vue')) +const UserManagementNavigation = defineAsyncComponent(() => import(/* webpackChunkName: 'settings-users' */'../views/UserManagementNavigation.vue')) + +const routes: RouteConfig[] = [ + { + name: 'users', + path: '/:index(index.php/)?settings/users', + components: { + default: UserManagement, + navigation: UserManagementNavigation, + }, + props: true, + children: [ + { + path: ':selectedGroup', + name: 'group', + }, + ], + }, + { + path: '/:index(index.php/)?settings/apps', + name: 'apps', + components: { + default: AppStore, + navigation: AppStoreNavigation, + sidebar: AppstoreSidebar, + }, + children: [ + { + path: ':category', + name: 'apps-category', + children: [ + { + path: ':id', + name: 'apps-details', + }, + ], + }, + ], + }, +] + +export default routes diff --git a/apps/settings/src/views/SettingsApp.vue b/apps/settings/src/views/SettingsApp.vue new file mode 100644 index 00000000000..4b36fcff7b1 --- /dev/null +++ b/apps/settings/src/views/SettingsApp.vue @@ -0,0 +1,34 @@ + + + + + diff --git a/apps/settings/src/webpack.shim.d.ts b/apps/settings/src/webpack.shim.d.ts new file mode 100644 index 00000000000..5caff2257e9 --- /dev/null +++ b/apps/settings/src/webpack.shim.d.ts @@ -0,0 +1 @@ +declare let __webpack_nonce__: string diff --git a/webpack.modules.js b/webpack.modules.js index 676646ff73b..09be290eb10 100644 --- a/webpack.modules.js +++ b/webpack.modules.js @@ -92,7 +92,7 @@ module.exports = { 'vue-settings-admin-delegation': path.join(__dirname, 'apps/settings/src', 'main-admin-delegation.js'), 'vue-settings-admin-security': path.join(__dirname, 'apps/settings/src', 'main-admin-security.js'), 'vue-settings-admin-sharing': path.join(__dirname, 'apps/settings/src', 'admin-settings-sharing.ts'), - 'vue-settings-apps-users-management': path.join(__dirname, 'apps/settings/src', 'main-apps-users-management.js'), + 'vue-settings-apps-users-management': path.join(__dirname, 'apps/settings/src', 'main-apps-users-management.ts'), 'vue-settings-nextcloud-pdf': path.join(__dirname, 'apps/settings/src', 'main-nextcloud-pdf.js'), 'vue-settings-personal-info': path.join(__dirname, 'apps/settings/src', 'main-personal-info.js'), 'vue-settings-personal-password': path.join(__dirname, 'apps/settings/src', 'main-personal-password.js'), -- cgit v1.2.3