From 87d462bd56f90efdb095787838f65899e8b1273a Mon Sep 17 00:00:00 2001 From: Fabian Pichler Date: Fri, 7 Aug 2026 01:21:32 +0200 Subject: [PATCH 1/2] CELDEV-1338 - add router-independent admin frontend islands --- celements-admin-frontend/README.md | 19 +- celements-admin-frontend/package-lock.json | 188 ++++++++++++++---- celements-admin-frontend/package.json | 45 ++++- celements-admin-frontend/postcss.config.js | 41 +++- celements-admin-frontend/src/App.vue | 6 +- celements-admin-frontend/src/assets/main.css | 25 ++- celements-admin-frontend/src/bootstrap.ts | 150 +------------- .../src/conf/routes/index.ts | 8 +- celements-admin-frontend/src/embedded.ts | 6 + .../page-attachments/PageAttachments.vue | 95 +++++++++ .../src/features/page-attachments/types.ts | 22 ++ .../src/islands/PageAttachmentsIslandRoot.vue | 23 +++ .../src/islands/page-attachments-element.ts | 83 ++++++++ .../src/medialib/api/tagApi.ts | 3 +- .../src/medialib/components/TagSidebar.vue | 66 ++++-- .../src/medialib/components/TagStatusBar.vue | 28 ++- .../src/medialib/stores/tags.ts | 13 +- .../src/plugins/plugin.pinia.ts | 3 +- .../src/plugins/plugin.router.ts | 48 ++--- .../src/public/page-attachments-island.ts | 13 ++ .../src/public/page-attachments.ts | 7 + .../src/public/runtime.ts | 4 + celements-admin-frontend/src/public/styles.ts | 2 + .../src/runtime/application.ts | 131 ++++++++++++ .../src/runtime/styles.ts | 22 ++ .../src/spa/PageAttachmentsRoute.vue | 12 ++ .../src/views/MediaLib.vue | 6 +- .../src/views/PageAttachments.vue | 70 ------- celements-admin-frontend/tailwind.config.js | 6 +- .../test/page-attachments.test.ts | 181 +++++++++++++++++ celements-admin-frontend/vite.config.ts | 15 +- .../vite.library.config.ts | 49 +++++ .../celEditorTabs/loadTabAttachments.vm | 93 +-------- .../celTemplates/attachmentsinline.vm | 94 +-------- .../celTemplates/pageAttachmentsIsland.vm | 14 ++ ...ependent-admin-features-and-vue-islands.md | 173 ++++++++++++++++ 36 files changed, 1238 insertions(+), 526 deletions(-) create mode 100644 celements-admin-frontend/src/features/page-attachments/PageAttachments.vue create mode 100644 celements-admin-frontend/src/features/page-attachments/types.ts create mode 100644 celements-admin-frontend/src/islands/PageAttachmentsIslandRoot.vue create mode 100644 celements-admin-frontend/src/islands/page-attachments-element.ts create mode 100644 celements-admin-frontend/src/public/page-attachments-island.ts create mode 100644 celements-admin-frontend/src/public/page-attachments.ts create mode 100644 celements-admin-frontend/src/public/runtime.ts create mode 100644 celements-admin-frontend/src/public/styles.ts create mode 100644 celements-admin-frontend/src/runtime/application.ts create mode 100644 celements-admin-frontend/src/runtime/styles.ts create mode 100644 celements-admin-frontend/src/spa/PageAttachmentsRoute.vue delete mode 100644 celements-admin-frontend/src/views/PageAttachments.vue create mode 100644 celements-admin-frontend/test/page-attachments.test.ts create mode 100644 celements-admin-frontend/vite.library.config.ts create mode 100644 celements-webapp/src/main/webapp/templates/celTemplates/pageAttachmentsIsland.vm create mode 100644 docs/architecture/decisions/0001-router-independent-admin-features-and-vue-islands.md diff --git a/celements-admin-frontend/README.md b/celements-admin-frontend/README.md index 15a0d9923..d7c29d580 100644 --- a/celements-admin-frontend/README.md +++ b/celements-admin-frontend/README.md @@ -97,7 +97,24 @@ src/ └── main.ts # Standalone development entry ``` -The app exposes a `createCelementsAdminApp()` factory function from `bootstrap.ts` that allows the frontend to be embedded in a host application or run standalone. +The SPA bootstrap owns Vue Router. Shared feature components and islands use the router-independent +application runtime, which creates a separate Pinia instance for every mounted Vue application. + +## Public package API + +The supported `@celements/admin-frontend` entry points are: + +- `@celements/admin-frontend/runtime` for `createCelementsApplication()`. +- `@celements/admin-frontend/page-attachments` for the router-free `PageAttachments` component and + its typed props, selection event, and `attachment-actions` slot contract. +- `@celements/admin-frontend/page-attachments-island` for the guarded + `` custom-element registration. +- `@celements/admin-frontend/styles.css` for downstream Vue applications using the feature component. + +The custom element accepts `space-name`, `doc-name`, `locale`, and `local-dev`. It dispatches the +bubbling `attachment-selection-change` event. Framework packages are peer dependencies so a +downstream application supplies one Vue, Pinia, PrimeVue, vue-i18n, Vue Router, and VueFinder +runtime. --- diff --git a/celements-admin-frontend/package-lock.json b/celements-admin-frontend/package-lock.json index 3dc50244f..4d2698248 100644 --- a/celements-admin-frontend/package-lock.json +++ b/celements-admin-frontend/package-lock.json @@ -17,17 +17,11 @@ "findandreplacedomtext": "^0.4.6", "lodash": "^4.17.23", "luxon": "^3.7.2", - "pinia": "^3.0.4", - "primevue": "^4.5.4", "tailwind-merge": "^3.5.0", "tailwindcss-primeui": "^0.6.1", - "vue": "^3.5.30", "vue-dompurify-html": "^5.3.0", - "vue-i18n": "^11.3.0", "vue-matomo": "^4.2.0", - "vue-router": "^5.0.4", "vue3-spinners": "^1.3.3", - "vuefinder": "^4.1.1", "zod": "^4.3.6" }, "devDependencies": { @@ -49,13 +43,27 @@ "eslint-plugin-vue": "^10.8.0", "jsdom": "^29.0.1", "npm-run-all2": "^8.0.4", + "pinia": "^3.0.4", "postcss": "^8.5.8", "prettier": "^3.8.1", + "primevue": "^4.5.4", "tailwindcss": "^4.2.2", "typescript": "~5.9.3", "vite": "^8.0.1", "vitest": "^4.1.0", - "vue-tsc": "^3.2.6" + "vue": "^3.5.30", + "vue-i18n": "^11.3.0", + "vue-router": "^5.0.4", + "vue-tsc": "^3.2.6", + "vuefinder": "^4.1.1" + }, + "peerDependencies": { + "pinia": "^3.0.4", + "primevue": "^4.5.4", + "vue": "^3.5.30", + "vue-i18n": "^11.3.0", + "vue-router": "^5.0.4", + "vuefinder": "^4.1.1" } }, "node_modules/@alloc/quick-lru": { @@ -121,6 +129,7 @@ "version": "7.29.1", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.1.tgz", "integrity": "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==", + "dev": true, "dependencies": { "@babel/parser": "^7.29.0", "@babel/types": "^7.29.0", @@ -459,6 +468,7 @@ "version": "1.7.5", "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.5.tgz", "integrity": "sha512-1Ih4WTWyw0+lKyFMcBHGbb5U5FtuHJuujoyyr5zTaWS5EYMeT6Jb2AuDeftsCsEuchO+mM2ij5+q9crhydzLhQ==", + "dev": true, "dependencies": { "@floating-ui/utils": "^0.2.11" } @@ -467,6 +477,7 @@ "version": "1.7.6", "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.6.tgz", "integrity": "sha512-9gZSAI5XM36880PPMm//9dfiEngYoC6Am2izES1FF406YFsjvyBMmeJ2g4SAju3xWwtuynNRFL2s9hgxpLI5SQ==", + "dev": true, "dependencies": { "@floating-ui/core": "^1.7.5", "@floating-ui/utils": "^0.2.11" @@ -475,7 +486,8 @@ "node_modules/@floating-ui/utils": { "version": "0.2.11", "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.11.tgz", - "integrity": "sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg==" + "integrity": "sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg==", + "dev": true }, "node_modules/@fortawesome/fontawesome-common-types": { "version": "7.2.0", @@ -581,6 +593,7 @@ "version": "11.4.2", "resolved": "https://registry.npmjs.org/@intlify/core-base/-/core-base-11.4.2.tgz", "integrity": "sha512-7fpuCcVmeLv2T9qHsARqGvh8xt+sV2fH+Q+gMHFwB/rPXzo85DpbJFKn7dBH1L5p0c2cSh2DW+2h/64EKrISmA==", + "dev": true, "dependencies": { "@intlify/devtools-types": "11.4.2", "@intlify/message-compiler": "11.4.2", @@ -597,6 +610,7 @@ "version": "11.4.2", "resolved": "https://registry.npmjs.org/@intlify/devtools-types/-/devtools-types-11.4.2.tgz", "integrity": "sha512-3u8EN1kB6EMSi96KXs5k7a8y2X2g4+h3X6iwVZU47cP4n+mTuq//WMjG588BzSp/2XQ/dTXo2BLUXX+XS+PNfA==", + "dev": true, "dependencies": { "@intlify/core-base": "11.4.2", "@intlify/shared": "11.4.2" @@ -612,6 +626,7 @@ "version": "11.4.2", "resolved": "https://registry.npmjs.org/@intlify/message-compiler/-/message-compiler-11.4.2.tgz", "integrity": "sha512-a6CDSGSMTGrg0BjD97x8TBYPf7qQMDlZipJ6UDfv/pd4OIym8TMlHu3MsH0bTNnRdAG2D6EFEykIgiQPqvtTkA==", + "dev": true, "dependencies": { "@intlify/shared": "11.4.2", "source-map-js": "^1.0.2" @@ -627,6 +642,7 @@ "version": "11.4.2", "resolved": "https://registry.npmjs.org/@intlify/shared/-/shared-11.4.2.tgz", "integrity": "sha512-NzpHbguRCsOHDwxmlBa9qu/imc+/QWgsYUaK6FZeNC0wK8QfAbhqrktEp/haVzxU1aikH8IX4ytD+mfFEMi/9A==", + "dev": true, "engines": { "node": ">= 16" }, @@ -655,6 +671,7 @@ "version": "0.3.13", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" @@ -664,6 +681,7 @@ "version": "2.3.5", "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "dev": true, "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" @@ -673,6 +691,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, "engines": { "node": ">=6.0.0" } @@ -686,6 +705,7 @@ "version": "0.3.31", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" @@ -695,6 +715,7 @@ "version": "1.3.3", "resolved": "https://registry.npmjs.org/@nanostores/i18n/-/i18n-1.3.3.tgz", "integrity": "sha512-hwuTKJ+DKCOuszmmOuNfDeA8j86WJWLLzjzE1BYm+mabMcD5JYDnTd0wPMwgGJ+U//ApRaxviRvOtvk50F+RCg==", + "dev": true, "funding": [ { "type": "github", @@ -712,6 +733,7 @@ "version": "1.3.4", "resolved": "https://registry.npmjs.org/@nanostores/persistent/-/persistent-1.3.4.tgz", "integrity": "sha512-fZ42MOredSkqt450XrPxmQ94pSRPTas/rBUVCvEEMCR+rIp8bdo/xoaFFcG2cwpqAzA164PdD6p3D+MXLJYumw==", + "dev": true, "funding": [ { "type": "github", @@ -729,6 +751,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/@nanostores/vue/-/vue-1.1.0.tgz", "integrity": "sha512-14eY8/YA0AbtWkAjk8zHKxbjcuPubF+M7y9afQzg2b5VqRJcashwA0100vprau13BTBSynUmU6ZsU6x03YidjA==", + "dev": true, "funding": [ { "type": "buymeacoffee", @@ -858,6 +881,7 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/@primeuix/styles/-/styles-2.0.3.tgz", "integrity": "sha512-2ykAB6BaHzR/6TwF8ShpJTsZrid6cVIEBVlookSdvOdmlWuevGu5vWOScgIwqWwlZcvkFYAGR/SUV3OHCTBMdw==", + "dev": true, "dependencies": { "@primeuix/styled": "^0.7.4" } @@ -882,6 +906,7 @@ "version": "4.5.5", "resolved": "https://registry.npmjs.org/@primevue/core/-/core-4.5.5.tgz", "integrity": "sha512-JpkXhq1ddc70JdsC3CC4dM+UbeeWuCW/8DpS9dNBfrOk824TLSlRlMEGFyVKqRMn5WPQvYLiy3xXfLQeNdSqhQ==", + "dev": true, "dependencies": { "@primeuix/styled": "^0.7.4", "@primeuix/utils": "^0.6.2" @@ -897,6 +922,7 @@ "version": "4.5.5", "resolved": "https://registry.npmjs.org/@primevue/icons/-/icons-4.5.5.tgz", "integrity": "sha512-eteOhTdAOXEYE9qW1AOrBBgDxQ2szHJxSkEK1XVdV2TKxGM5FQf03Ovms0VDyZTc16XBIgvwYjXJQS0BPbhPaA==", + "dev": true, "dependencies": { "@primeuix/utils": "^0.6.2", "@primevue/core": "4.5.5" @@ -1419,6 +1445,7 @@ "version": "8.19.4", "resolved": "https://registry.npmjs.org/@tanstack/match-sorter-utils/-/match-sorter-utils-8.19.4.tgz", "integrity": "sha512-Wo1iKt2b9OT7d+YGhvEPD3DXvPv2etTusIMhMUoG7fbhmxcXCtIjJDEygy91Y2JFlwGyjqiBPRozme7UD8hoqg==", + "dev": true, "dependencies": { "remove-accents": "0.5.0" }, @@ -1434,6 +1461,7 @@ "version": "5.100.10", "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.100.10.tgz", "integrity": "sha512-8UR0yJR+GiQ40m3lPhUr0xbfAupe6GSQiksSBSa9SM2NjezFyxXCIA69/lz8cSoNKZLrw1/PktIyQBJcVeMi3w==", + "dev": true, "funding": { "type": "github", "url": "https://github.com/sponsors/tannerlinsley" @@ -1443,6 +1471,7 @@ "version": "5.100.10", "resolved": "https://registry.npmjs.org/@tanstack/vue-query/-/vue-query-5.100.10.tgz", "integrity": "sha512-S1aOmIPQNd5axR2Sw7H8d96EybY3kEZ396KA90e0SGLDYSfd2QgWi7+ItYXRGIDiSjOjlPUnthKDP0mDDBV8Kw==", + "dev": true, "dependencies": { "@tanstack/match-sorter-utils": "^8.19.4", "@tanstack/query-core": "5.100.10", @@ -1466,12 +1495,14 @@ "node_modules/@tanstack/vue-query/node_modules/@vue/devtools-api": { "version": "6.6.4", "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.6.4.tgz", - "integrity": "sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==" + "integrity": "sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==", + "dev": true }, "node_modules/@tanstack/vue-query/node_modules/vue-demi": { "version": "0.14.10", "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.10.tgz", "integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==", + "dev": true, "hasInstallScript": true, "bin": { "vue-demi-fix": "bin/vue-demi-fix.js", @@ -1496,7 +1527,8 @@ "node_modules/@transloadit/prettier-bytes": { "version": "0.3.5", "resolved": "https://registry.npmjs.org/@transloadit/prettier-bytes/-/prettier-bytes-0.3.5.tgz", - "integrity": "sha512-xF4A3d/ZyX2LJWeQZREZQw+qFX4TGQ8bGVP97OLRt6sPO6T0TNHBFTuRHOJh7RNmYOBmQ9MHxpolD9bXihpuVA==" + "integrity": "sha512-xF4A3d/ZyX2LJWeQZREZQw+qFX4TGQ8bGVP97OLRt6sPO6T0TNHBFTuRHOJh7RNmYOBmQ9MHxpolD9bXihpuVA==", + "dev": true }, "node_modules/@tsconfig/node20": { "version": "20.1.9", @@ -1590,7 +1622,8 @@ "node_modules/@types/retry": { "version": "0.12.2", "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.2.tgz", - "integrity": "sha512-XISRgDJ2Tc5q4TRqvgJtzsRkFYNJzZrhTdtMoGVBttwzzQJkPnS3WWTFc7kuDRoPtPakl+T+OfdEUjYJj7Jbow==" + "integrity": "sha512-XISRgDJ2Tc5q4TRqvgJtzsRkFYNJzZrhTdtMoGVBttwzzQJkPnS3WWTFc7kuDRoPtPakl+T+OfdEUjYJj7Jbow==", + "dev": true }, "node_modules/@types/tough-cookie": { "version": "4.0.5", @@ -1844,6 +1877,7 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/@uppy/companion-client/-/companion-client-5.1.1.tgz", "integrity": "sha512-DzrOWTbIZHvtgAFXBMYHk2wD27NjpBSVhY2tEiEIUhPd2CxbFRZjHM/N3HOt3VwZEAP471QWFLlJRWPcIY3A2Q==", + "dev": true, "dependencies": { "@uppy/utils": "^7.1.1", "namespace-emitter": "^2.0.1", @@ -1857,6 +1891,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/@uppy/components/-/components-1.2.0.tgz", "integrity": "sha512-rtIr+77Rw/q5Vw++xazF1dCg2d4A4zT9CV+ZyN8Rsx8xiIr2CxCR4TaHHBy+WeC0b7Mk6yNuJ0wUa34tFJ6pKg==", + "dev": true, "dependencies": { "clsx": "^2.1.1", "dequal": "^2.0.3", @@ -1885,6 +1920,7 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/@uppy/core/-/core-5.2.0.tgz", "integrity": "sha512-uvfNyz4cnaplt7LYJmEZHuqOuav0tKp4a9WKJIaH6iIj7XiqYvS2J5SEByexAlUFlzefOAyjzj4Ja2dd/8aMrw==", + "dev": true, "dependencies": { "@transloadit/prettier-bytes": "^0.3.4", "@uppy/store-default": "^5.0.0", @@ -1900,6 +1936,7 @@ "version": "5.1.11", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.1.11.tgz", "integrity": "sha512-v+KEsUv2ps74PaSKv0gHTxTCgMXOIfBEbaqa6w6ISIGC7ZsvHN4N9oJ8d4cmf0n5oTzQz2SLmThbQWhjd/8eKg==", + "dev": true, "funding": [ { "type": "github", @@ -1917,6 +1954,7 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/@uppy/locales/-/locales-5.1.1.tgz", "integrity": "sha512-zSbDU27JzfdssRJoa5/xmGOsrEtS+2Z9j41weaoCa/NoK4wqZzkFNQ0Z44etbTg3PDVFakZVDu/Z+c+vsJCfdQ==", + "dev": true, "dependencies": { "@uppy/utils": "^7.1.5" } @@ -1924,12 +1962,14 @@ "node_modules/@uppy/store-default": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/@uppy/store-default/-/store-default-5.0.0.tgz", - "integrity": "sha512-hQtCSQ1yGiaval/wVYUWquYGDJ+bpQ7e4FhUUAsRQz1x1K+o7NBtjfp63O9I4Ks1WRoKunpkarZ+as09l02cPw==" + "integrity": "sha512-hQtCSQ1yGiaval/wVYUWquYGDJ+bpQ7e4FhUUAsRQz1x1K+o7NBtjfp63O9I4Ks1WRoKunpkarZ+as09l02cPw==", + "dev": true }, "node_modules/@uppy/utils": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@uppy/utils/-/utils-7.2.0.tgz", "integrity": "sha512-6lC246qszMv6bTyl/+QyHwrudgeguWkA94ME1wHn+a6uRAvmtAEaUManIfGqTJfoKvWAiCJqdJPl5xRJjhAloQ==", + "dev": true, "dependencies": { "lodash": "^4.17.23", "preact": "^10.26.10" @@ -1939,6 +1979,7 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/@uppy/vue/-/vue-3.2.0.tgz", "integrity": "sha512-BZiyUZxpadf3uUp8YzgwRZTIde/m9Ne4ILFygJg7ilFq/Qfb1pBVspG9FJoG23RbOiRuxd4JixwFh0gaFdfL+w==", + "dev": true, "dependencies": { "@uppy/components": "^1.2.0", "preact": "^10.26.10", @@ -1971,6 +2012,7 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/@uppy/xhr-upload/-/xhr-upload-5.2.0.tgz", "integrity": "sha512-3LV/X5Of6BINnKplP+CwUJ0a4/7cRFfzxwGyXnW+uCrNQHoo09dttcz3begWHejGvzenQHuUnMO3Fxyc71Pryg==", + "dev": true, "dependencies": { "@uppy/companion-client": "^5.1.1", "@uppy/utils": "^7.2.0" @@ -1982,7 +2024,8 @@ "node_modules/@viselect/vanilla": { "version": "3.9.0", "resolved": "https://registry.npmjs.org/@viselect/vanilla/-/vanilla-3.9.0.tgz", - "integrity": "sha512-E9eBgoi/crJ0SlZMAc+Yst7nU324LZ5LLvcXjzWEcrfllscdpTml2OLOKHC7O8Bbz19OybSLv6VexxnjlJrLxQ==" + "integrity": "sha512-E9eBgoi/crJ0SlZMAc+Yst7nU324LZ5LLvcXjzWEcrfllscdpTml2OLOKHC7O8Bbz19OybSLv6VexxnjlJrLxQ==", + "dev": true }, "node_modules/@vitejs/plugin-vue": { "version": "6.0.6", @@ -2171,6 +2214,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/@vue-macros/common/-/common-3.1.2.tgz", "integrity": "sha512-h9t4ArDdniO9ekYHAD95t9AZcAbb19lEGK+26iAjUODOIJKmObDNBSe4+6ELQAA3vtYiFPPBtHh7+cQCKi3Dng==", + "dev": true, "dependencies": { "@vue/compiler-sfc": "^3.5.22", "ast-kit": "^2.1.2", @@ -2243,6 +2287,7 @@ "version": "7.7.9", "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-7.7.9.tgz", "integrity": "sha512-kIE8wvwlcZ6TJTbNeU2HQNtaxLx3a84aotTITUuL/4bzfPxzajGBOoqjMhwZJ8L9qFYDU/lAYMEEm11dnZOD6g==", + "dev": true, "dependencies": { "@vue/devtools-kit": "^7.7.9" } @@ -2251,6 +2296,7 @@ "version": "7.7.9", "resolved": "https://registry.npmjs.org/@vue/devtools-kit/-/devtools-kit-7.7.9.tgz", "integrity": "sha512-PyQ6odHSgiDVd4hnTP+aDk2X4gl2HmLDfiyEnn3/oV+ckFDuswRs4IbBT7vacMuGdwY/XemxBoh302ctbsptuA==", + "dev": true, "dependencies": { "@vue/devtools-shared": "^7.7.9", "birpc": "^2.3.0", @@ -2265,6 +2311,7 @@ "version": "7.7.9", "resolved": "https://registry.npmjs.org/@vue/devtools-shared/-/devtools-shared-7.7.9.tgz", "integrity": "sha512-iWAb0v2WYf0QWmxCGy0seZNDPdO3Sp5+u78ORnyeonS6MT4PC7VPrryX2BpMJrwlDeaZ6BD4vP4XKjK0SZqaeA==", + "dev": true, "dependencies": { "rfdc": "^1.4.1" } @@ -2466,6 +2513,7 @@ "version": "8.16.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", + "dev": true, "bin": { "acorn": "bin/acorn" }, @@ -2544,6 +2592,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/ast-kit/-/ast-kit-2.2.0.tgz", "integrity": "sha512-m1Q/RaVOnTp9JxPX+F+Zn7IcLYMzM8kZofDImfsKZd8MbR+ikdOzTeztStWqfrqIxZnYWryyI9ePm3NGjnZgGw==", + "dev": true, "dependencies": { "@babel/parser": "^7.28.5", "pathe": "^2.0.3" @@ -2559,6 +2608,7 @@ "version": "0.8.3", "resolved": "https://registry.npmjs.org/ast-walker-scope/-/ast-walker-scope-0.8.3.tgz", "integrity": "sha512-cbdCP0PGOBq0ASG+sjnKIoYkWMKhhz+F/h9pRexUdX2Hd38+WOlBkRKlqkGOSm0YQpcFMQBJeK4WspUAkwsEdg==", + "dev": true, "dependencies": { "@babel/parser": "^7.28.4", "ast-kit": "^2.1.3" @@ -2640,6 +2690,7 @@ "version": "2.9.0", "resolved": "https://registry.npmjs.org/birpc/-/birpc-2.9.0.tgz", "integrity": "sha512-KrayHS5pBi69Xi9JmvoqrIgYGDkD6mcSe/i6YKi3w5kekCLzrX4+nawcXqrj2tIp50Kw/mT/s3p+GVK0A0sKxw==", + "dev": true, "funding": { "url": "https://github.com/sponsors/antfu" } @@ -2768,6 +2819,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-5.0.0.tgz", "integrity": "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==", + "dev": true, "dependencies": { "readdirp": "^5.0.0" }, @@ -2781,7 +2833,8 @@ "node_modules/classnames": { "version": "2.5.1", "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz", - "integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==" + "integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==", + "dev": true }, "node_modules/cliui": { "version": "8.0.1", @@ -2859,6 +2912,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "dev": true, "engines": { "node": ">=6" } @@ -2922,7 +2976,8 @@ "node_modules/confbox": { "version": "0.2.4", "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.2.4.tgz", - "integrity": "sha512-ysOGlgTFbN2/Y6Cg3Iye8YKulHw+R2fNXHrgSmXISQdMnomY6eNDprVdW9R5xBguEqI954+S6709UyiO7B+6OQ==" + "integrity": "sha512-ysOGlgTFbN2/Y6Cg3Iye8YKulHw+R2fNXHrgSmXISQdMnomY6eNDprVdW9R5xBguEqI954+S6709UyiO7B+6OQ==", + "dev": true }, "node_modules/config-chain": { "version": "1.1.13", @@ -2952,6 +3007,7 @@ "version": "4.0.5", "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-4.0.5.tgz", "integrity": "sha512-7Vv6asjS4gMOuILabD3l739tsaxFQmC+a7pLZm02zyvs8p977bL3zEgq3yDk5rn9B0PbYgIv++jmHcuUab4RhA==", + "dev": true, "dependencies": { "is-what": "^5.2.0" }, @@ -3022,7 +3078,8 @@ "node_modules/debounce": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz", - "integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==" + "integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==", + "dev": true }, "node_modules/debug": { "version": "4.4.3", @@ -3057,6 +3114,7 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "dev": true, "engines": { "node": ">=6" } @@ -3087,7 +3145,8 @@ "node_modules/easy-bem": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/easy-bem/-/easy-bem-1.1.1.tgz", - "integrity": "sha512-GJRqdiy2h+EXy6a8E6R+ubmqUM08BK0FWNq41k24fup6045biQ8NXxoXimiwegMQvFFV3t1emADdGNL1TlS61A==" + "integrity": "sha512-GJRqdiy2h+EXy6a8E6R+ubmqUM08BK0FWNq41k24fup6045biQ8NXxoXimiwegMQvFFV3t1emADdGNL1TlS61A==", + "dev": true }, "node_modules/editorconfig": { "version": "1.0.7", @@ -3461,7 +3520,8 @@ "node_modules/exsolve": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/exsolve/-/exsolve-1.0.8.tgz", - "integrity": "sha512-LmDxfWXwcTArk8fUEnOfSZpHOJ6zOMUJKOtFLFqJLoKJetuQG874Uc7/Kki7zFLzYybmZhp1M7+98pfMqeX8yA==" + "integrity": "sha512-LmDxfWXwcTArk8fUEnOfSZpHOJ6zOMUJKOtFLFqJLoKJetuQG874Uc7/Kki7zFLzYybmZhp1M7+98pfMqeX8yA==", + "dev": true }, "node_modules/fast-deep-equal": { "version": "3.1.3", @@ -3721,7 +3781,8 @@ "node_modules/hookable": { "version": "5.5.3", "resolved": "https://registry.npmjs.org/hookable/-/hookable-5.5.3.tgz", - "integrity": "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==" + "integrity": "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==", + "dev": true }, "node_modules/html-encoding-sniffer": { "version": "6.0.0", @@ -3793,6 +3854,7 @@ "version": "1.3.2", "resolved": "https://registry.npmjs.org/is-network-error/-/is-network-error-1.3.2.tgz", "integrity": "sha512-PhBY86zaxNZUuWP6h13Vu5oFe0XY6/UlKzQnYFELzGVHygP3MxmvTfYSG7GN3aIab/iWudSMgjSnG9Dq+nHrgA==", + "dev": true, "engines": { "node": ">=16" }, @@ -3819,6 +3881,7 @@ "version": "5.5.0", "resolved": "https://registry.npmjs.org/is-what/-/is-what-5.5.0.tgz", "integrity": "sha512-oG7cgbmg5kLYae2N5IVd3jm2s+vldjxJzK1pcu9LfpGuQ93MQSzo0okvRna+7y5ifrD+20FE8FvjusyGaz14fw==", + "dev": true, "engines": { "node": ">=18" }, @@ -3939,6 +4002,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true, "bin": { "jsesc": "bin/jsesc" }, @@ -3977,6 +4041,7 @@ "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, "bin": { "json5": "lib/cli.js" }, @@ -4269,6 +4334,7 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-1.1.2.tgz", "integrity": "sha512-arhlxbFRmoQHl33a0Zkle/YWlmNwoyt6QNZEIJcqNbdrsix5Lvc4HyyI3EnwxTYlZYc32EbYrQ8SzEZ7dqgg9A==", + "dev": true, "dependencies": { "mlly": "^1.7.4", "pkg-types": "^2.3.0", @@ -4330,6 +4396,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/magic-string-ast/-/magic-string-ast-1.0.3.tgz", "integrity": "sha512-CvkkH1i81zl7mmb94DsRiFeG9V2fR2JeuK8yDgS8oiZSFa++wWLEgZ5ufEOyLHbvSbD1gTRKv9NdX69Rnvr9JA==", + "dev": true, "dependencies": { "magic-string": "^0.30.19" }, @@ -4381,6 +4448,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/mime-match/-/mime-match-1.0.2.tgz", "integrity": "sha512-VXp/ugGDVh3eCLOBCiHZMYWQaTNUHv2IJrut+yXA6+JbLPXHglHwfS/5A5L0ll+jkCY7fIzRJcH6OIunF+c6Cg==", + "dev": true, "dependencies": { "wildcard": "^1.1.0" } @@ -4412,12 +4480,14 @@ "node_modules/mitt": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz", - "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==" + "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==", + "dev": true }, "node_modules/mlly": { "version": "1.8.2", "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.8.2.tgz", "integrity": "sha512-d+ObxMQFmbt10sretNDytwt85VrbkhhUA/JBGm1MPaWJ65Cl4wOgLaB1NYvJSZ0Ef03MMEU/0xpPMXUIQ29UfA==", + "dev": true, "dependencies": { "acorn": "^8.16.0", "pathe": "^2.0.3", @@ -4428,12 +4498,14 @@ "node_modules/mlly/node_modules/confbox": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz", - "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==" + "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==", + "dev": true }, "node_modules/mlly/node_modules/pkg-types": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.3.1.tgz", "integrity": "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==", + "dev": true, "dependencies": { "confbox": "^0.1.8", "mlly": "^1.7.4", @@ -4449,12 +4521,14 @@ "node_modules/muggle-string": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/muggle-string/-/muggle-string-0.4.1.tgz", - "integrity": "sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==" + "integrity": "sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==", + "dev": true }, "node_modules/namespace-emitter": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/namespace-emitter/-/namespace-emitter-2.0.1.tgz", - "integrity": "sha512-N/sMKHniSDJBjfrkbS/tpkPj4RAbvW3mr8UAzvlMHyun93XEm83IAvhWtJVHo+RHn/oO8Job5YN4b+wRjSVp5g==" + "integrity": "sha512-N/sMKHniSDJBjfrkbS/tpkPj4RAbvW3mr8UAzvlMHyun93XEm83IAvhWtJVHo+RHn/oO8Job5YN4b+wRjSVp5g==", + "dev": true }, "node_modules/nanoid": { "version": "3.3.12", @@ -4477,6 +4551,7 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/nanostores/-/nanostores-1.3.0.tgz", "integrity": "sha512-XPUa/jz+P1oJvN9VBxw4L9MtdFfaH3DAryqPssqhb2kXjmb9npz0dly6rCsgFWOPr4Yg9mTfM3MDZgZZ+7A3lA==", + "dev": true, "funding": [ { "type": "github", @@ -4644,7 +4719,8 @@ "node_modules/overlayscrollbars": { "version": "2.16.0", "resolved": "https://registry.npmjs.org/overlayscrollbars/-/overlayscrollbars-2.16.0.tgz", - "integrity": "sha512-N03oje/q7j93D0aLZtoCdsDSYLmhheSsv8H7oSLE7HhdV9P/bmCURtLV/KbPye7P/bpfyt/obSfDpGUYoJ0OWg==" + "integrity": "sha512-N03oje/q7j93D0aLZtoCdsDSYLmhheSsv8H7oSLE7HhdV9P/bmCURtLV/KbPye7P/bpfyt/obSfDpGUYoJ0OWg==", + "dev": true }, "node_modules/p-limit": { "version": "3.1.0", @@ -4680,6 +4756,7 @@ "version": "6.2.1", "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-6.2.1.tgz", "integrity": "sha512-hEt02O4hUct5wtwg4H4KcWgDdm+l1bOaEy/hWzd8xtXB9BqxTWBBhb+2ImAtH4Cv4rPjV76xN3Zumqk3k3AhhQ==", + "dev": true, "dependencies": { "@types/retry": "0.12.2", "is-network-error": "^1.0.0", @@ -4776,12 +4853,14 @@ "node_modules/pathe": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", - "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==" + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "dev": true }, "node_modules/perfect-debounce": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-1.0.0.tgz", - "integrity": "sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==" + "integrity": "sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==", + "dev": true }, "node_modules/picocolors": { "version": "1.1.1", @@ -4816,6 +4895,7 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/pinia/-/pinia-3.0.4.tgz", "integrity": "sha512-l7pqLUFTI/+ESXn6k3nu30ZIzW5E2WZF/LaHJEpoq6ElcLD+wduZoB2kBN19du6K/4FDpPMazY2wJr+IndBtQw==", + "dev": true, "dependencies": { "@vue/devtools-api": "^7.7.7" }, @@ -4836,6 +4916,7 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-2.3.1.tgz", "integrity": "sha512-y+ichcgc2LrADuhLNAx8DFjVfgz91pRxfZdI3UDhxHvcVEZsenLO+7XaU5vOp0u/7V/wZ+plyuQxtrDlZJ+yeg==", + "dev": true, "dependencies": { "confbox": "^0.2.4", "exsolve": "^1.0.8", @@ -4892,6 +4973,7 @@ "version": "10.29.1", "resolved": "https://registry.npmjs.org/preact/-/preact-10.29.1.tgz", "integrity": "sha512-gQCLc/vWroE8lIpleXtdJhTFDogTdZG9AjMUpVkDf2iTCNwYNWA+u16dL41TqUDJO4gm2IgrcMv3uTpjd4Pwmg==", + "dev": true, "funding": { "type": "opencollective", "url": "https://opencollective.com/preact" @@ -4937,6 +5019,7 @@ "version": "6.1.1", "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-6.1.1.tgz", "integrity": "sha512-mQUvGU6aUFQ+rNvTIAcZuWGRT9a6f6Yrg9bHs4ImKF+HZCEK+plBvnAZYSIQztknZF2qnzNtr6F8s0+IuptdlQ==", + "dev": true, "engines": { "node": "^14.13.1 || >=16.0.0" }, @@ -4948,6 +5031,7 @@ "version": "4.5.5", "resolved": "https://registry.npmjs.org/primevue/-/primevue-4.5.5.tgz", "integrity": "sha512-Kv5REIewCdP806QaoU+4nBXfmpzOGFKkZ9qH4KsL6MjiAQVc4PUzypt8erl4r3Vzh3nr3aWZIxkxYRRsLGiX2A==", + "dev": true, "dependencies": { "@primeuix/styled": "^0.7.4", "@primeuix/styles": "^2.0.3", @@ -4978,6 +5062,7 @@ "version": "0.2.11", "resolved": "https://registry.npmjs.org/quansync/-/quansync-0.2.11.tgz", "integrity": "sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==", + "dev": true, "funding": [ { "type": "individual", @@ -5026,6 +5111,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-5.0.0.tgz", "integrity": "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==", + "dev": true, "engines": { "node": ">= 20.19.0" }, @@ -5037,7 +5123,8 @@ "node_modules/remove-accents": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/remove-accents/-/remove-accents-0.5.0.tgz", - "integrity": "sha512-8g3/Otx1eJaVD12e31UbJj1YzdtVvzH85HV7t+9MJYk/u3XmkOUJ5Ys9wQrf9PCPK8+xn4ymzqYCiZl6QWKn+A==" + "integrity": "sha512-8g3/Otx1eJaVD12e31UbJj1YzdtVvzH85HV7t+9MJYk/u3XmkOUJ5Ys9wQrf9PCPK8+xn4ymzqYCiZl6QWKn+A==", + "dev": true }, "node_modules/require-directory": { "version": "2.1.1", @@ -5061,6 +5148,7 @@ "version": "0.13.1", "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "dev": true, "engines": { "node": ">= 4" } @@ -5078,7 +5166,8 @@ "node_modules/rfdc": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", - "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==" + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", + "dev": true }, "node_modules/rolldown": { "version": "1.0.0", @@ -5166,7 +5255,8 @@ "node_modules/scule": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/scule/-/scule-1.3.0.tgz", - "integrity": "sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==" + "integrity": "sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==", + "dev": true }, "node_modules/semver": { "version": "7.8.0", @@ -5183,7 +5273,8 @@ "node_modules/shallow-equal": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/shallow-equal/-/shallow-equal-3.1.0.tgz", - "integrity": "sha512-pfVOw8QZIXpMbhBWvzBISicvToTiM5WBF1EeAUZDDSb5Dt29yl4AYbyywbJFSEsRUMr7gJaxqCdr4L3tQf9wVg==" + "integrity": "sha512-pfVOw8QZIXpMbhBWvzBISicvToTiM5WBF1EeAUZDDSb5Dt29yl4AYbyywbJFSEsRUMr7gJaxqCdr4L3tQf9wVg==", + "dev": true }, "node_modules/shebang-command": { "version": "2.0.0", @@ -5248,6 +5339,7 @@ "version": "14.0.1", "resolved": "https://registry.npmjs.org/speakingurl/-/speakingurl-14.0.1.tgz", "integrity": "sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==", + "dev": true, "engines": { "node": ">=0.10.0" } @@ -5369,6 +5461,7 @@ "version": "2.2.6", "resolved": "https://registry.npmjs.org/superjson/-/superjson-2.2.6.tgz", "integrity": "sha512-H+ue8Zo4vJmV2nRjpx86P35lzwDT3nItnIsocgumgr0hHMQ+ZGq5vrERg9kJBo5AWGmxZDhzDo+WVIJqkB0cGA==", + "dev": true, "dependencies": { "copy-anything": "^4" }, @@ -5466,6 +5559,7 @@ "version": "0.2.16", "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.16.tgz", "integrity": "sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==", + "dev": true, "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.4" @@ -5481,6 +5575,7 @@ "version": "6.5.0", "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, "engines": { "node": ">=12.0.0" }, @@ -5497,6 +5592,7 @@ "version": "4.0.4", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "dev": true, "engines": { "node": ">=12" }, @@ -5645,7 +5741,8 @@ "node_modules/ufo": { "version": "1.6.4", "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.4.tgz", - "integrity": "sha512-JFNbkD1Svwe0KvGi8GOeLcP4kAWQ609twvCdcHxq1oSL8svv39ZuSvajcD8B+5D0eL4+s1Is2D/O6KN3qcTeRA==" + "integrity": "sha512-JFNbkD1Svwe0KvGi8GOeLcP4kAWQ609twvCdcHxq1oSL8svv39ZuSvajcD8B+5D0eL4+s1Is2D/O6KN3qcTeRA==", + "dev": true }, "node_modules/undici": { "version": "7.25.0", @@ -5666,6 +5763,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-3.0.0.tgz", "integrity": "sha512-0Mqk3AT2TZCXWKdcoaufeXNukv2mTrEZExeXlHIOZXdqYoHHr4n51pymnwV8x2BOVxwXbK2HLlI7usrqMpycdg==", + "dev": true, "dependencies": { "@jridgewell/remapping": "^2.3.5", "picomatch": "^4.0.3", @@ -5679,6 +5777,7 @@ "version": "0.3.1", "resolved": "https://registry.npmjs.org/unplugin-utils/-/unplugin-utils-0.3.1.tgz", "integrity": "sha512-5lWVjgi6vuHhJ526bI4nlCOmkCIF3nnfXkCMDeMJrtdvxTs6ZFCM8oNufGTsDbKv/tJ/xj8RpvXjRuPBZJuJog==", + "dev": true, "dependencies": { "pathe": "^2.0.3", "picomatch": "^4.0.3" @@ -5694,6 +5793,7 @@ "version": "4.0.4", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "dev": true, "engines": { "node": ">=12" }, @@ -5705,6 +5805,7 @@ "version": "4.0.4", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "dev": true, "engines": { "node": ">=12" }, @@ -5761,6 +5862,7 @@ "version": "19.1.3", "resolved": "https://registry.npmjs.org/vanilla-lazyload/-/vanilla-lazyload-19.1.3.tgz", "integrity": "sha512-bBMERPu2AFJc35krS+8BOhq++c6dRfL6q368lJPnkS5U92fRQagTR3FsNta69/GukfZzDwDEjD5M3U7VuSiCDw==", + "dev": true, "funding": { "type": "individual", "url": "https://ko-fi.com/verlok" @@ -5986,6 +6088,7 @@ "version": "2.8.9", "resolved": "https://registry.npmjs.org/vue-advanced-cropper/-/vue-advanced-cropper-2.8.9.tgz", "integrity": "sha512-1jc5gO674kVGpJKekoaol6ZlwaF5VYDLSBwBOUpViW0IOrrRsyLw6XNszjEqgbavvqinlKNS6Kqlom3B5M72Tw==", + "dev": true, "dependencies": { "classnames": "^2.2.6", "debounce": "^1.2.0", @@ -6055,6 +6158,7 @@ "version": "11.4.2", "resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-11.4.2.tgz", "integrity": "sha512-sADDeKXqAGsPX6tK3t3y2ZiMpbVWN12tG+MhTiJ06rVoh58eGtM4wFyw3uWGbVkXByVp9Ne/AP+nSSzI+J9OAQ==", + "dev": true, "dependencies": { "@intlify/core-base": "11.4.2", "@intlify/devtools-types": "11.4.2", @@ -6074,7 +6178,8 @@ "node_modules/vue-i18n/node_modules/@vue/devtools-api": { "version": "6.6.4", "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.6.4.tgz", - "integrity": "sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==" + "integrity": "sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==", + "dev": true }, "node_modules/vue-matomo": { "version": "4.2.0", @@ -6089,6 +6194,7 @@ "version": "5.0.6", "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-5.0.6.tgz", "integrity": "sha512-9+kmUTGbKMyW9Asoy98IXXYIzrTMT7JDAdpDDeEkorHvybpUvBI2wsrSM5jFOXrFydpzRFJ9vAh+80DN2PGu9w==", + "dev": true, "dependencies": { "@babel/generator": "^7.28.6", "@vue-macros/common": "^3.1.1", @@ -6133,6 +6239,7 @@ "version": "8.1.2", "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-8.1.2.tgz", "integrity": "sha512-vA0O112YqyDuNA1s7Yb2gCgToQ/OxOWiFDO5ThLCcDy0ldHnSd1dUTaSYhOldbqoNgumE4dxtGAoAaSUKUD1Zg==", + "dev": true, "dependencies": { "@vue/devtools-kit": "^8.1.2" } @@ -6141,6 +6248,7 @@ "version": "8.1.2", "resolved": "https://registry.npmjs.org/@vue/devtools-kit/-/devtools-kit-8.1.2.tgz", "integrity": "sha512-f75/upc+GCyjXErpgPGz4582ujS0L/adAltGy+tqXMGUJpgAcfGr6CxnnhpZY8BHuMYt6KpbF8uaFrrQG66rGQ==", + "dev": true, "dependencies": { "@vue/devtools-shared": "^8.1.2", "birpc": "^2.6.1", @@ -6151,17 +6259,20 @@ "node_modules/vue-router/node_modules/@vue/devtools-shared": { "version": "8.1.2", "resolved": "https://registry.npmjs.org/@vue/devtools-shared/-/devtools-shared-8.1.2.tgz", - "integrity": "sha512-X9RyVFYAdkBe4IUf5v48TxBF/6QPmF8CmWrDAjXzfUHrgQ/HGfTC1A6TqgXqZ03ye66l3AD51BAGD69IvKM9sw==" + "integrity": "sha512-X9RyVFYAdkBe4IUf5v48TxBF/6QPmF8CmWrDAjXzfUHrgQ/HGfTC1A6TqgXqZ03ye66l3AD51BAGD69IvKM9sw==", + "dev": true }, "node_modules/vue-router/node_modules/perfect-debounce": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-2.1.0.tgz", - "integrity": "sha512-LjgdTytVFXeUgtHZr9WYViYSM/g8MkcTPYDlPa3cDqMirHjKiSZPYd6DoL7pK8AJQr+uWkQvCjHNdiMqsrJs+g==" + "integrity": "sha512-LjgdTytVFXeUgtHZr9WYViYSM/g8MkcTPYDlPa3cDqMirHjKiSZPYd6DoL7pK8AJQr+uWkQvCjHNdiMqsrJs+g==", + "dev": true }, "node_modules/vue-router/node_modules/picomatch": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "dev": true, "engines": { "node": ">=12" }, @@ -6173,6 +6284,7 @@ "version": "2.0.9", "resolved": "https://registry.npmjs.org/vue-sonner/-/vue-sonner-2.0.9.tgz", "integrity": "sha512-i6BokNlNDL93fpzNxN/LZSn6D6MzlO+i3qXt6iVZne3x1k7R46d5HlFB4P8tYydhgqOrRbIZEsnRd3kG7qGXyw==", + "dev": true, "peerDependencies": { "@nuxt/kit": "^4.0.3", "@nuxt/schema": "^4.0.3", @@ -6226,6 +6338,7 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/vuefinder/-/vuefinder-4.1.2.tgz", "integrity": "sha512-qoYdIRKQIrr+MgQlhNDzxVYOpWhNlncFDsS9ol0XL/kqnALr3rF7+W2KbS0GRjzzqyAuNxAJATcN3fRbj+/lsA==", + "dev": true, "dependencies": { "@floating-ui/dom": "^1.7.4", "@nanostores/i18n": "^1.2.2", @@ -6293,7 +6406,8 @@ "node_modules/webpack-virtual-modules": { "version": "0.6.2", "resolved": "https://registry.npmjs.org/webpack-virtual-modules/-/webpack-virtual-modules-0.6.2.tgz", - "integrity": "sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==" + "integrity": "sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==", + "dev": true }, "node_modules/whatwg-mimetype": { "version": "5.0.0", @@ -6352,7 +6466,8 @@ "node_modules/wildcard": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-1.1.2.tgz", - "integrity": "sha512-DXukZJxpHA8LuotRwL0pP1+rS6CS7FF2qStDDE1C7DDg2rLud2PXRMuEDYIPhgEezwnlHNL4c+N6MfMTjCGTng==" + "integrity": "sha512-DXukZJxpHA8LuotRwL0pP1+rS6CS7FF2qStDDE1C7DDg2rLud2PXRMuEDYIPhgEezwnlHNL4c+N6MfMTjCGTng==", + "dev": true }, "node_modules/word-wrap": { "version": "1.2.5", @@ -6479,6 +6594,7 @@ "version": "2.9.0", "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.9.0.tgz", "integrity": "sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==", + "dev": true, "bin": { "yaml": "bin.mjs" }, diff --git a/celements-admin-frontend/package.json b/celements-admin-frontend/package.json index a502f8e3c..f5a171dfd 100644 --- a/celements-admin-frontend/package.json +++ b/celements-admin-frontend/package.json @@ -3,12 +3,33 @@ "version": "0.1.0-SNAPSHOT", "private": false, "type": "module", + "files": [ + "dist" + ], "exports": { - "./src/*": "./src/*" + ".": { + "types": "./dist/types/public/runtime.d.ts", + "import": "./dist/package/runtime.js" + }, + "./runtime": { + "types": "./dist/types/public/runtime.d.ts", + "import": "./dist/package/runtime.js" + }, + "./page-attachments": { + "types": "./dist/types/public/page-attachments.d.ts", + "import": "./dist/package/page-attachments.js" + }, + "./page-attachments-island": { + "types": "./dist/types/public/page-attachments-island.d.ts", + "import": "./dist/package/page-attachments-island.js" + }, + "./styles.css": "./dist/package/styles.css" }, "scripts": { "dev": "concurrently \"vite\" \"npm:type-check-watch\" \"npm:test-watch\"", - "build": "npm run type-check && npm run test && vite build", + "build": "npm run type-check && npm run test && vite build && npm run build:package && npm run build:types", + "build:package": "vite build --config vite.library.config.ts", + "build:types": "vue-tsc -p tsconfig.app.json --declaration --emitDeclarationOnly --noEmit false --outDir dist/types --composite false", "preview": "vite preview", "test": "vitest run", "test-watch": "vitest", @@ -30,19 +51,21 @@ "findandreplacedomtext": "^0.4.6", "lodash": "^4.17.23", "luxon": "^3.7.2", - "pinia": "^3.0.4", - "primevue": "^4.5.4", "tailwind-merge": "^3.5.0", "tailwindcss-primeui": "^0.6.1", - "vue": "^3.5.30", "vue-dompurify-html": "^5.3.0", - "vue-i18n": "^11.3.0", "vue-matomo": "^4.2.0", - "vue-router": "^5.0.4", "vue3-spinners": "^1.3.3", - "vuefinder": "^4.1.1", "zod": "^4.3.6" }, + "peerDependencies": { + "pinia": "^3.0.4", + "primevue": "^4.5.4", + "vue": "^3.5.30", + "vue-i18n": "^11.3.0", + "vue-router": "^5.0.4", + "vuefinder": "^4.1.1" + }, "devDependencies": { "@tailwindcss/postcss": "^4.2.2", "@tsconfig/node20": "^20.1.9", @@ -62,12 +85,18 @@ "eslint-plugin-vue": "^10.8.0", "jsdom": "^29.0.1", "npm-run-all2": "^8.0.4", + "pinia": "^3.0.4", "postcss": "^8.5.8", "prettier": "^3.8.1", + "primevue": "^4.5.4", "tailwindcss": "^4.2.2", "typescript": "~5.9.3", "vite": "^8.0.1", "vitest": "^4.1.0", + "vue": "^3.5.30", + "vue-i18n": "^11.3.0", + "vue-router": "^5.0.4", + "vuefinder": "^4.1.1", "vue-tsc": "^3.2.6" }, "browserslist": [ diff --git a/celements-admin-frontend/postcss.config.js b/celements-admin-frontend/postcss.config.js index 6f51004b1..82a703c34 100644 --- a/celements-admin-frontend/postcss.config.js +++ b/celements-admin-frontend/postcss.config.js @@ -39,6 +39,45 @@ function conditionalTailwind() { } conditionalTailwind.postcss = true; +const adminScope = ':where(.cel-admin-surface, .cel-admin-teleport)'; +const globalSelectors = new Set([ + '*', + ':after', + ':before', + '::after', + '::backdrop', + '::before', + '::file-selector-button', +]); + +function scopeAdminStyles() { + return { + postcssPlugin: 'scope-celements-admin-styles', + OnceExit(root, helpers) { + const from = helpers?.result?.opts?.from || root?.source?.input?.file || ''; + const isApplicationStyles = from.includes('/src/assets/main.css'); + if (!isApplicationStyles && !from.includes('/node_modules/vuefinder/')) return; + root.walkRules((rule) => { + if (rule.parent?.type === 'atrule' && rule.parent.name.includes('keyframes')) return; + rule.selectors = rule.selectors.map((selector) => { + const trimmed = selector.trim(); + if (trimmed === ':root' || trimmed === ':host') return adminScope; + if (globalSelectors.has(trimmed)) return `${adminScope} ${trimmed}`; + if ( + isApplicationStyles && + !trimmed.includes('.cel-admin-surface') && + !trimmed.includes('.cel-admin-teleport') + ) { + return `${adminScope} ${trimmed}, ${adminScope}${trimmed}`; + } + return selector; + }); + }); + }, + }; +} +scopeAdminStyles.postcss = true; + export default { - plugins: [conditionalTailwind(), autoprefixer()], + plugins: [conditionalTailwind(), scopeAdminStyles(), autoprefixer()], }; diff --git a/celements-admin-frontend/src/App.vue b/celements-admin-frontend/src/App.vue index 34597bf14..485414a71 100644 --- a/celements-admin-frontend/src/App.vue +++ b/celements-admin-frontend/src/App.vue @@ -1,6 +1,8 @@ diff --git a/celements-admin-frontend/src/features/page-attachments/types.ts b/celements-admin-frontend/src/features/page-attachments/types.ts new file mode 100644 index 000000000..d79753aff --- /dev/null +++ b/celements-admin-frontend/src/features/page-attachments/types.ts @@ -0,0 +1,22 @@ +import type { DirEntry } from 'vuefinder'; + +export interface PageAttachmentsDocument { + spaceName: string; + docName: string; +} + +export interface PageAttachmentsProps extends PageAttachmentsDocument { + locale?: string; +} + +export interface PageAttachmentsActionContext { + document: PageAttachmentsDocument; + path: string; + count: number; + selectedAttachments: readonly DirEntry[]; +} + +export interface PageAttachmentsSelectionDetail { + document: PageAttachmentsDocument; + selectedAttachments: readonly DirEntry[]; +} diff --git a/celements-admin-frontend/src/islands/PageAttachmentsIslandRoot.vue b/celements-admin-frontend/src/islands/PageAttachmentsIslandRoot.vue new file mode 100644 index 000000000..7fac14116 --- /dev/null +++ b/celements-admin-frontend/src/islands/PageAttachmentsIslandRoot.vue @@ -0,0 +1,23 @@ + + + diff --git a/celements-admin-frontend/src/islands/page-attachments-element.ts b/celements-admin-frontend/src/islands/page-attachments-element.ts new file mode 100644 index 000000000..4ffd9e773 --- /dev/null +++ b/celements-admin-frontend/src/islands/page-attachments-element.ts @@ -0,0 +1,83 @@ +import PageAttachmentsIslandRoot from '@/islands/PageAttachmentsIslandRoot.vue'; +import { createCelementsApplication } from '@/runtime/application'; +import type { PageAttachmentsSelectionDetail } from '@/features/page-attachments/types'; + +export const PAGE_ATTACHMENTS_ELEMENT_NAME = 'cel-page-attachments'; + +export class CelPageAttachmentsElement extends HTMLElement { + static observedAttributes = ['space-name', 'doc-name', 'locale', 'local-dev']; + private application: ReturnType | null = null; + + get spaceName() { + return this.getAttribute('space-name') ?? ''; + } + set spaceName(value: string) { + this.setAttribute('space-name', value); + } + get docName() { + return this.getAttribute('doc-name') ?? ''; + } + set docName(value: string) { + this.setAttribute('doc-name', value); + } + get locale() { + return this.getAttribute('locale') ?? undefined; + } + set locale(value: string | undefined) { + if (value == null) this.removeAttribute('locale'); + else this.setAttribute('locale', value); + } + get localDev() { + const value = this.getAttribute('local-dev'); + return value == null ? undefined : value.toLowerCase() !== 'false'; + } + set localDev(value: boolean | undefined) { + if (value == null) this.removeAttribute('local-dev'); + else this.setAttribute('local-dev', String(value)); + } + connectedCallback() { + if (this.application) return; + if (!this.spaceName || !this.docName) return; + this.application = createCelementsApplication( + PageAttachmentsIslandRoot, + { + spaceName: this.spaceName, + docName: this.docName, + locale: this.locale, + onSelectionChange: (detail: PageAttachmentsSelectionDetail) => { + this.dispatchEvent( + new CustomEvent('attachment-selection-change', { + detail, + bubbles: true, + composed: true, + }) + ); + }, + }, + { locale: this.locale, localDev: this.localDev } + ); + this.application.mount(this); + } + disconnectedCallback() { + this.unmount(); + } + attributeChangedCallback(_name: string, oldValue: string | null, newValue: string | null) { + if (!this.isConnected || oldValue === newValue) return; + this.unmount(); + this.connectedCallback(); + } + private unmount() { + if (!this.application) return; + this.application.app.unmount(); + this.application = null; + this.replaceChildren(); + } +} + +export const registerPageAttachmentsElement = ( + registry: CustomElementRegistry = customElements +) => { + if (!registry.get(PAGE_ATTACHMENTS_ELEMENT_NAME)) { + registry.define(PAGE_ATTACHMENTS_ELEMENT_NAME, CelPageAttachmentsElement); + } +}; diff --git a/celements-admin-frontend/src/medialib/api/tagApi.ts b/celements-admin-frontend/src/medialib/api/tagApi.ts index 37a50cb6c..2083db2af 100644 --- a/celements-admin-frontend/src/medialib/api/tagApi.ts +++ b/celements-admin-frontend/src/medialib/api/tagApi.ts @@ -11,8 +11,7 @@ export async function apiFetchTags(): Promise { export async function apiFetchFilesForTag(tagId: string): Promise { const res = await fetch(`${API_BASE}/tags/files?tagId=${encodeURIComponent(tagId)}`); - if (!res.ok) - throw new Error(`GET ${API_BASE}/tags/files?tagId=${tagId} failed: ${res.status}`); + if (!res.ok) throw new Error(`GET ${API_BASE}/tags/files?tagId=${tagId} failed: ${res.status}`); return res.json() as Promise; } diff --git a/celements-admin-frontend/src/medialib/components/TagSidebar.vue b/celements-admin-frontend/src/medialib/components/TagSidebar.vue index de368fbaf..bbf750202 100644 --- a/celements-admin-frontend/src/medialib/components/TagSidebar.vue +++ b/celements-admin-frontend/src/medialib/components/TagSidebar.vue @@ -1,10 +1,10 @@ @@ -182,8 +217,7 @@ function isActive(tag: Tag): boolean { } function fileCountForTag(tag: Tag): number { - return Object.values(tagStore.fileTagMap).filter((tags) => - tags.some((t) => t.id === tag.id), - ).length; + return Object.values(tagStore.fileTagMap).filter((tags) => tags.some((t) => t.id === tag.id)) + .length; } diff --git a/celements-admin-frontend/src/medialib/components/TagStatusBar.vue b/celements-admin-frontend/src/medialib/components/TagStatusBar.vue index b9086ce1b..88c7151c8 100644 --- a/celements-admin-frontend/src/medialib/components/TagStatusBar.vue +++ b/celements-admin-frontend/src/medialib/components/TagStatusBar.vue @@ -1,15 +1,10 @@