From 572da098d07c2e519d25bcc32b9babe2ad4cee70 Mon Sep 17 00:00:00 2001 From: Thijn Date: Thu, 19 Dec 2024 16:47:46 +0100 Subject: [PATCH 01/10] WIP - small part of routing is functional as proof of concept --- lib/Controller/ZakenController.php | 38 ++++++++++++++++ package-lock.json | 19 ++++---- package.json | 3 +- src/App.vue | 7 ++- src/main.js | 2 + src/navigation/MainMenu.vue | 36 ++++++++------- src/router/router.ts | 72 ++++++++++++++++++++++++++++++ src/shims-vue.d.ts | 4 ++ src/store/modules/navigation.ts | 5 ++- src/views/Views.vue | 56 +++++------------------ src/views/componentMapping.js | 29 ++++++++++++ src/views/zaken/ZaakDetails.vue | 21 +++++---- src/views/zaken/ZakenIndex.vue | 9 +++- src/views/zaken/ZakenList.vue | 6 ++- tsconfig.json | 2 +- webpack.config.js | 7 +++ 16 files changed, 227 insertions(+), 89 deletions(-) create mode 100644 src/router/router.ts create mode 100644 src/shims-vue.d.ts create mode 100644 src/views/componentMapping.js diff --git a/lib/Controller/ZakenController.php b/lib/Controller/ZakenController.php index 6e8529e..fa54500 100644 --- a/lib/Controller/ZakenController.php +++ b/lib/Controller/ZakenController.php @@ -6,6 +6,8 @@ use OCP\AppFramework\Controller; use OCP\AppFramework\Http\JSONResponse; use OCP\IRequest; +use OCP\AppFramework\Http\TemplateResponse; +use OCP\AppFramework\Http\ContentSecurityPolicy; /** * Geeft invulling aan https://vng-realisatie.github.io/gemma-zaken/standaard/zaken/ @@ -41,6 +43,42 @@ public function index(): JSONResponse return new JSONResponse($data); } + /** + * Render no page. + * + * @param string|null $getParameter Optional GET parameter + * @return TemplateResponse The rendered template response + * + * @NoAdminRequired + * @NoCSRFRequired + */ + public function page(?string $getParameter): TemplateResponse + { + try { + // Create a new TemplateResponse for the index page + $response = new TemplateResponse( + $this->appName, + 'index', + [] + ); + + // Set up Content Security Policy + $csp = new ContentSecurityPolicy(); + $csp->addAllowedConnectDomain('*'); + $response->setContentSecurityPolicy($csp); + + return $response; + } catch (\Exception $e) { + // Return an error template response if an exception occurs + return new TemplateResponse( + $this->appName, + 'error', + ['error' => $e->getMessage()], + '500' + ); + } + } + /** * Read a single object * diff --git a/package-lock.json b/package-lock.json index 7ac9a80..5e35d3d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,7 +15,7 @@ "@nextcloud/dialogs": "^3.2.0", "@nextcloud/initial-state": "^2.2.0", "@nextcloud/l10n": "^2.0.1", - "@nextcloud/router": "^2.0.1", + "@nextcloud/router": "^2.1.2", "@nextcloud/vue": "^8.12.0", "bootstrap-vue": "^2.23.1", "lodash": "^4.17.21", @@ -23,6 +23,7 @@ "vue": "^2.7.14", "vue-loading-overlay": "^3.4.3", "vue-material-design-icons": "^5.3.0", + "vue-router": "^3.6.5", "zod": "^3.23.8" }, "devDependencies": { @@ -3554,17 +3555,16 @@ } }, "node_modules/@nextcloud/router": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@nextcloud/router/-/router-2.2.1.tgz", - "integrity": "sha512-ZRc/WI0RaksEJMz08H/6LimIdP+1A1xTHThCYEghs7VgAKNp5917vT2OKSpG0cMRbIwk0ongFVt5FB5qjy/iFg==", - "license": "GPL-3.0-or-later", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@nextcloud/router/-/router-2.1.2.tgz", + "integrity": "sha512-Jj5fgjeHT1vVIgOyUGOeHfwk2KgaO77QGfqZAT6GWXvpAsN0mkqwljkg4FkHrQRouYqCE4VnJ5o8/w0DAN89tA==", "dependencies": { - "@nextcloud/typings": "^1.7.0", + "@nextcloud/typings": "^1.0.0", "core-js": "^3.6.4" }, "engines": { - "node": "^20.0.0", - "npm": "^10.0.0" + "node": "^16.0.0", + "npm": "^7.0.0 || ^8.0.0" } }, "node_modules/@nextcloud/sharing": { @@ -21872,8 +21872,7 @@ "node_modules/vue-router": { "version": "3.6.5", "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-3.6.5.tgz", - "integrity": "sha512-VYXZQLtjuvKxxcshuRAwjHnciqZVoXAjTjcqBTz4rKc8qih9g9pI3hbDjmqXaHdgL3v8pV6P8Z335XvHzESxLQ==", - "license": "MIT" + "integrity": "sha512-VYXZQLtjuvKxxcshuRAwjHnciqZVoXAjTjcqBTz4rKc8qih9g9pI3hbDjmqXaHdgL3v8pV6P8Z335XvHzESxLQ==" }, "node_modules/vue-style-loader": { "version": "4.1.3", diff --git a/package.json b/package.json index 2be7d13..239e9f0 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "@nextcloud/dialogs": "^3.2.0", "@nextcloud/initial-state": "^2.2.0", "@nextcloud/l10n": "^2.0.1", - "@nextcloud/router": "^2.0.1", + "@nextcloud/router": "^2.1.2", "@nextcloud/vue": "^8.12.0", "bootstrap-vue": "^2.23.1", "lodash": "^4.17.21", @@ -34,6 +34,7 @@ "vue": "^2.7.14", "vue-loading-overlay": "^3.4.3", "vue-material-design-icons": "^5.3.0", + "vue-router": "^3.6.5", "zod": "^3.23.8" }, "devDependencies": { diff --git a/src/App.vue b/src/App.vue index 2a2f5b2..b2612fe 100644 --- a/src/App.vue +++ b/src/App.vue @@ -1,7 +1,7 @@ - diff --git a/src/views/componentMapping.js b/src/views/componentMapping.js new file mode 100644 index 0000000..eeb2a9a --- /dev/null +++ b/src/views/componentMapping.js @@ -0,0 +1,29 @@ +import BerichtenIndex from './berichten/BerichtenIndex.vue' +import BesluitenIndex from './besluiten/BesluitenIndex.vue' +import SearchIndex from './search/SearchIndex.vue' +import DocumentenIndex from './documenten/DocumentenIndex.vue' +import KlantenIndex from './klanten/KlantenIndex.vue' +import MedewerkerIndex from './medewerkers/MedewerkerIndex.vue' +import ResultatenIndex from './resultaten/ResultatenIndex.vue' +import RollenIndex from './rollen/RollenIndex.vue' +import StatusssenIndex from './statussen/StatussenIndex.vue' +import TakenIndex from './taken/TakenIndex.vue' +import ZaakTypenIndex from './zaakTypen/ZakenTypenIndex.vue' +import ZakenIndex from './zaken/ZakenIndex.vue' +import ContactMomentenIndex from './contactMomenten/ContactMomentenIndex.vue' + +export const viewComponents = { + berichten: BerichtenIndex, + besluiten: BesluitenIndex, + search: SearchIndex, + documenten: DocumentenIndex, + klanten: KlantenIndex, + medewerkers: MedewerkerIndex, + resultaten: ResultatenIndex, + rollen: RollenIndex, + statussen: StatusssenIndex, + taken: TakenIndex, + zaakTypen: ZaakTypenIndex, + zaken: ZakenIndex, + contactMomenten: ContactMomentenIndex, +} diff --git a/src/views/zaken/ZaakDetails.vue b/src/views/zaken/ZaakDetails.vue index 48703ca..737ab6f 100644 --- a/src/views/zaken/ZaakDetails.vue +++ b/src/views/zaken/ZaakDetails.vue @@ -222,26 +222,31 @@ export default { FileDocumentPlusOutline, VectorPolylineEdit, }, + props: { + id: { + type: String, + required: true, + }, + }, data() { return { // state loading: true, - currentActiveZaak: null, // data auditTrails: [], zaak: [], } }, + watch: { + id(newId) { + zaakStore.getZaak(newId, { setItem: true }) + this.fetchAuditTrails(newId) + }, + }, mounted() { - this.currentActiveZaak = zaakStore.zaakItem + zaakStore.getZaak(this.id, { setItem: true }) this.fetchAuditTrails(zaakStore.zaakItem.id) }, - updated() { - if (zaakStore.zaakItem?.id && JSON.stringify(this.currentActiveZaak) !== JSON.stringify(zaakStore.zaakItem)) { - this.currentActiveZaak = zaakStore.zaakItem - this.fetchAuditTrails(zaakStore.zaakItem.id) - } - }, methods: { fetchData() { this.loading = true diff --git a/src/views/zaken/ZakenIndex.vue b/src/views/zaken/ZakenIndex.vue index c5e2604..15b800f 100644 --- a/src/views/zaken/ZakenIndex.vue +++ b/src/views/zaken/ZakenIndex.vue @@ -8,7 +8,7 @@ import { navigationStore, zaakStore } from '../../store/store.js' - + @@ -42,5 +42,10 @@ export default { ZaakDetails, BriefcaseAccountOutline, }, + data() { + return { + id: this.$route.params.id, + } + }, } diff --git a/src/views/zaken/ZakenList.vue b/src/views/zaken/ZakenList.vue index e4479ac..d605277 100644 --- a/src/views/zaken/ZakenList.vue +++ b/src/views/zaken/ZakenList.vue @@ -39,7 +39,7 @@ import { navigationStore, zaakStore } from '../../store/store.js' :active="zaakStore.zaakItem?.id === zaak?.id" :details="'1h'" :counter-number="zaak.uiterlijkeEinddatumAfdoening ? `${Math.ceil((new Date(zaak.uiterlijkeEinddatumAfdoening) - new Date()) / (1000 * 60 * 60 * 24))} dagen` : 'no deadline'" - @click="zaakStore.setZaakItem(zaak)"> + @click="openZaak(zaak.id)"> + + :active="$route.path === '/'" + name="Dashboard"> @@ -24,81 +24,88 @@ import { navigationStore } from '../store/store.js' + :active="$route.path.startsWith('/zaken')" + name="Zaken"> - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - + + + + + + + + + + diff --git a/src/router/router.ts b/src/router/router.ts index b9b4b21..8863978 100644 --- a/src/router/router.ts +++ b/src/router/router.ts @@ -13,10 +13,8 @@ import Router from 'vue-router' import Vue from 'vue' // Pages -import App from '../App.vue' -import DashboardIndex from '../views/dashboard/DashboardIndex.vue' -// Pages > views import Views from '../views/Views.vue' +import DashboardIndex from '../views/dashboard/DashboardIndex.vue' // Prevent router from throwing errors when we're already on the page we're trying to go to const originalPush = Router.prototype.push as (to: any, onComplete?: any, onAbort?: any) => Promise @@ -37,7 +35,6 @@ const router = new Router({ routes: [ { - path: '/', component: Views, children: [ @@ -62,6 +59,9 @@ const router = new Router({ // But let's assume Views.vue will have the . render(h: any) { return h('div', [h('router-view')]) }, }, + // used to watch for changes in the views modal + // otherwise it wont reload the component + meta: { watchParam: 'id' }, }, ], diff --git a/src/store/modules/navigation.ts b/src/store/modules/navigation.ts index 9c677b6..6a61e63 100644 --- a/src/store/modules/navigation.ts +++ b/src/store/modules/navigation.ts @@ -2,7 +2,6 @@ import { defineStore } from 'pinia' interface NavigationStoreState { - selected: 'dashboard' | 'berichten' | 'klanten' | 'rollen' | 'taken' | 'zaken' | 'zaakTypen' | 'search' | 'auditTrail' | 'contactMomenten' | 'medewerkers'; modal: string; viewModal: string; dialog: string; @@ -11,8 +10,6 @@ interface NavigationStoreState { export const useNavigationStore = defineStore('ui', { state: () => ({ - // The currently active menu item, defaults to '' which triggers the dashboard - selected: '', // The currently active modal, managed trough the state to ensure that only one modal can be active at the same time modal: null, // The currently active view modal, managed trough the state to ensure that only one view modal can be active at the same time @@ -21,13 +18,8 @@ export const useNavigationStore = defineStore('ui', { dialog: null, // Any data needed in various models, dialogs, views which cannot be transferred through normal means or without writing bad/excessive code transferData: null, - }), - // } as NavigationStoreState), + } as NavigationStoreState), actions: { - setSelected(selected: NavigationStoreState['selected']) { - this.selected = selected - console.log('Active menu item set to ' + selected) - }, setModal(modal: NavigationStoreState['modal']) { this.modal = modal console.log('Active modal set to ' + modal) diff --git a/src/views/Views.vue b/src/views/Views.vue index 86c5cc2..4658766 100644 --- a/src/views/Views.vue +++ b/src/views/Views.vue @@ -3,7 +3,7 @@ diff --git a/src/views/zaken/ZaakDetails.vue b/src/views/zaken/ZaakDetails.vue index 737ab6f..4938120 100644 --- a/src/views/zaken/ZaakDetails.vue +++ b/src/views/zaken/ZaakDetails.vue @@ -5,8 +5,9 @@ import { navigationStore, zaakStore } from '../../store/store.js' @@ -43,5 +43,10 @@ export default { TaakDetails, CalendarMonthOutline, }, + data() { + return { + id: this.$route.params.id, + } + }, } diff --git a/src/views/taken/TakenList.vue b/src/views/taken/TakenList.vue index f6366e6..8ca5903 100644 --- a/src/views/taken/TakenList.vue +++ b/src/views/taken/TakenList.vue @@ -30,19 +30,17 @@ import { klantStore, medewerkerStore, navigationStore, taakStore } from '../../s -
+
+ @click="openTaak(taak)"> @@ -44,8 +44,7 @@ export default { }, data() { return { - activeMetaData: false, - klantId: undefined, + id: this.$route.params.id, } }, } diff --git a/src/views/klanten/KlantenList.vue b/src/views/klanten/KlantenList.vue index beecbc0..1cd731e 100644 --- a/src/views/klanten/KlantenList.vue +++ b/src/views/klanten/KlantenList.vue @@ -30,18 +30,16 @@ import { navigationStore, klantStore } from '../../store/store.js'
-
+
+ @click="openKlant(klant)"> @@ -44,8 +44,7 @@ export default { }, data() { return { - activeMetaData: false, - medewerkerId: undefined, + id: this.$route.params.id, } }, } diff --git a/src/views/medewerkers/MedewerkerList.vue b/src/views/medewerkers/MedewerkerList.vue index e6d5c9f..2200b6d 100644 --- a/src/views/medewerkers/MedewerkerList.vue +++ b/src/views/medewerkers/MedewerkerList.vue @@ -30,18 +30,16 @@ import { navigationStore, medewerkerStore } from '../../store/store.js'
-
+
+ @click="openMedewerker(medewerker)"> - +