aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFerdinand Thiessen <opensource@fthiessen.de>2024-02-20 13:08:45 +0100
committerFerdinand Thiessen <opensource@fthiessen.de>2024-03-11 16:02:33 +0100
commit14bdc11deeaee97cac24c8c80622bf81fc34c2db (patch)
tree6360e4a4af6918845fa17551ae5c5a79ff226ac6
parentf4beb95cdc3161a99e048e03ab486e5218d10e0a (diff)
downloadnextcloud-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.js136
-rw-r--r--apps/settings/src/router/index.ts42
-rw-r--r--apps/settings/src/router/routes.ts52
-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.ts1
-rw-r--r--webpack.modules.js2
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'),