diff options
author | Ferdinand Thiessen <opensource@fthiessen.de> | 2024-02-20 13:08:45 +0100 |
---|---|---|
committer | Ferdinand Thiessen <opensource@fthiessen.de> | 2024-03-11 16:02:33 +0100 |
commit | 14bdc11deeaee97cac24c8c80622bf81fc34c2db (patch) | |
tree | 6360e4a4af6918845fa17551ae5c5a79ff226ac6 | |
parent | f4beb95cdc3161a99e048e03ab486e5218d10e0a (diff) | |
download | nextcloud-server-14bdc11deeaee97cac24c8c80622bf81fc34c2db.tar.gz nextcloud-server-14bdc11deeaee97cac24c8c80622bf81fc34c2db.zip |
feat(settings): Refactor routing code to use named router views
Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
-rw-r--r-- | apps/settings/src/main-apps-users-management.ts (renamed from apps/settings/src/main-apps-users-management.js) | 30 | ||||
-rw-r--r-- | apps/settings/src/router.js | 136 | ||||
-rw-r--r-- | apps/settings/src/router/index.ts | 42 | ||||
-rw-r--r-- | apps/settings/src/router/routes.ts | 52 | ||||
-rw-r--r-- | apps/settings/src/views/SettingsApp.vue (renamed from apps/settings/src/App.vue) | 15 | ||||
-rw-r--r-- | apps/settings/src/webpack.shim.d.ts | 1 | ||||
-rw-r--r-- | webpack.modules.js | 2 |
7 files changed, 123 insertions, 155 deletions
diff --git a/apps/settings/src/main-apps-users-management.js b/apps/settings/src/main-apps-users-management.ts index f81670fa624..37d7e9ba821 100644 --- a/apps/settings/src/main-apps-users-management.js +++ b/apps/settings/src/main-apps-users-management.ts @@ -25,10 +25,13 @@ 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 App from './App.vue' -import router from './router.js' +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 }) @@ -36,20 +39,23 @@ sync(store, router) // CSP config for webpack dynamic chunk loading // eslint-disable-next-line camelcase -__webpack_nonce__ = btoa(OC.requestToken) +__webpack_nonce__ = btoa(getRequestToken() ?? '') // 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 +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() -const app = new Vue({ +export default new Vue({ router, store, - render: h => h(App), -}).$mount('#content') - -export { app, 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æ <skjnldsv@protonmail.com> - * - * @author John Molakvoæ <skjnldsv@protonmail.com> - * @author Julius Härtl <jus@bitgrid.net> - * @author Roeland Jago Douma <roeland@famdouma.nl> - * - * @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 <http://www.gnu.org/licenses/>. - * - */ - -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æ <skjnldsv@protonmail.com> + * + * @author John Molakvoæ <skjnldsv@protonmail.com> + * @author Julius Härtl <jus@bitgrid.net> + * @author Roeland Jago Douma <roeland@famdouma.nl> + * @author Ferdinand Thiessen <opensource@fthiessen.de> + * + * @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 <http://www.gnu.org/licenses/>. + * + */ + +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/App.vue b/apps/settings/src/views/SettingsApp.vue index 21565aea9ad..4b36fcff7b1 100644 --- a/apps/settings/src/App.vue +++ b/apps/settings/src/views/SettingsApp.vue @@ -2,8 +2,9 @@ - @copyright Copyright (c) 2018 John Molakvoæ <skjnldsv@protonmail.com> - - @author John Molakvoæ <skjnldsv@protonmail.com> + - @author Ferdinand Thiessen <opensource@fthiessen.de> - - - @license GNU AGPL version 3 or any later version + - @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 @@ -21,11 +22,13 @@ --> <template> - <router-view /> + <NcContent app-name="settings"> + <router-view name="navigation" /> + <router-view /> + <router-view name="sidebar" /> + </NcContent> </template> -<script> -export default { - name: 'App', -} +<script setup lang="ts"> +import NcContent from '@nextcloud/vue/dist/Components/NcContent.js' </script> 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'), |