CELDEV-1338 - Add router-independent admin frontend islands - #561
CELDEV-1338 - Add router-independent admin frontend islands#561fpichler wants to merge 2 commits into
Conversation
There was a problem hiding this comment.
Jenkinsfile.npm and publish-forge-package.sh contain mostly reusable npm-specific publication workflow logic. Please move this into a focused npmPackagePipeline in the server-tools Jenkins shared library, analogous to dockerImagePipeline, and keep this repository’s pipeline declarative:
@Library('synventis') _
npmPackagePipeline(appDir: 'celements-admin-frontend')
| </div> | ||
| </div> ## row | ||
| #end ## foreach | ||
| #parse('celTemplates/pageAttachmentsIsland.vm') |
There was a problem hiding this comment.
Preserve anonymous attachment listing
Replacing the server-rendered template with the Vue island affects normal document views, the attachments page, and the attachment overlay—not only editors. The previous template listed attachments, metadata, history, and download links for all viewers while restricting upload and delete actions to users with edit/admin rights. The island loads this list through PageAttachmentsController, whose prepareRequest() returns 401 when no authenticated user exists before evaluating VIEW rights. Anonymous users therefore lose the attachment listing on public documents despite having VIEW access.
| upload: true, | ||
| delete: true, |
There was a problem hiding this comment.
hardcodes upload and delete to true, while pageAttachmentsIsland.vm passes only the document identity and locale. Because the shared island now replaces attachmentsinline.vm on normal document views and overlays, authenticated users with only VIEW permission receive enabled mutation controls. It regresses the previous UI, which exposed mutations only to authorized users. Pass explicit can-upload and can-delete capabilities through Velocity → custom element → component and use them for the VueFinder feature flags.
| @import 'tailwindcss/theme.css' layer(theme); | ||
| @import 'tailwindcss/utilities.css' layer(utilities); |
There was a problem hiding this comment.
Please align with the legacy-safe Tailwind setup already established for existing Vue islands:
| @import 'tailwindcss/theme.css' layer(theme); | |
| @import 'tailwindcss/utilities.css' layer(utilities); | |
| @import 'tailwindcss/theme.css' layer(theme) prefix(tw); | |
| @import 'tailwindcss/utilities.css' layer(utilities) prefix(tw) important source(none); | |
| @source '..'; | |
| @source '../../index.html'; |
This provides prefixed tw: classes, emits utility declarations with !important, excludes preflight and limits source scanning. Please also remove the ancestor-selector important setting from tailwind.config.js and update all utility references, including @apply and TypeScript class strings, to use the tw: prefix.
| #end | ||
| <script type="module" src="$pageAttachmentsModule"></script> | ||
| <span class="cel_lazyloadJS_exec" style="display:none">import('$pageAttachmentsModule')</span> | ||
| <cel-page-attachments |
There was a problem hiding this comment.
<cel-page-attachments> remains inline by default. The Vue root’s w-full cannot establish that layout through an inline host.
cel-page-attachments {
display: block;
}
There was a problem hiding this comment.
This ADR mixes the router-independent feature/island decision with detailed package APIs, CSS selector allowlists and Jenkins/Forge publication policy. That makes the core decision difficult to identify and couples unrelated details that will evolve independently.
Please keep the ADR focused on router-free features, SPA/island adapters, per-mount state isolation, and the light-DOM decision. Move the remaining details to dedicated documentation or omit them when they are already defined by code.
| edit: false, | ||
| fullscreen: false, | ||
| language: false, | ||
| history: false, |
There was a problem hiding this comment.
The replaced attachmentsinline.vm linked each attachment’s version to the viewattachrev action. The new VueFinder UI sets history: false and exposes no equivalent link. The action itself remains functional, but users can no longer reach attachment revision history from the attachment listing.
| "private": false, | ||
| "type": "module", | ||
| "files": [ | ||
| "dist" |
There was a problem hiding this comment.
The build produces two different deliverables in the same dist/ tree:
dist/
├─ assets/ # deployable SPA assets for the Caddy container
├─ .vite/ # deployable manifest
├─ package/ # npm library JavaScript and CSS
└─ types/ # npm library declarations
"files": ["dist"] causes npm pack to include all four. Publish only the npm library artifacts:
| "dist" | |
| "dist/package", | |
| "dist/types" |
| const app = createApp(rootComponent, rootProps); | ||
| const pinia = createCelementsPinia(); | ||
| app.config.errorHandler = (err, instance, info) => { | ||
| logger.error(err as string, instance, info); |
There was a problem hiding this comment.
| logger.error(err as string, instance, info); | |
| logger.error(err, instance, info); |
avoid as, it is not needed here
| } | ||
|
|
||
| function optimisticallyDeleteTag(tag: Tag): { backupTags: Tag[]; backupMap: Record<string, Tag[]> } { | ||
| function optimisticallyDeleteTag(tag: Tag): { |
There was a problem hiding this comment.
Prefer arrow functions over function declarations, per $synventis-vue-style. This affects several places in this PR/repo, please do a cleanup pass.
| const instanceId = ref(`page_attachments_${crypto.randomUUID()}`); | ||
| const finderId = computed(() => instanceId.value); |
There was a problem hiding this comment.
| const instanceId = ref(`page_attachments_${crypto.randomUUID()}`); | |
| const finderId = computed(() => instanceId.value); | |
| const finderId = `page_attachments_${crypto.randomUUID()}`; |
no need for reactive state
| @@ -30,19 +58,20 @@ | |||
| "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" | |||
| }, | |||
There was a problem hiding this comment.
@primeuix/themes, findandreplacedomtext, lodash, tailwind-merge, vue-dompurify-html, vue-matomo, vue3-spinners, and zod have no source imports.
tailwindcss-primeui is build-only.
Remove the unused entries and move build-only to devDependencies so consumers do not install them.
Summary
PageAttachmentsrouter-independent by passing typedspaceName,docName, and locale context into a shared feature component<cel-page-attachments>island with explicit attribute/property mapping, safe reconnect and attribute-change handling, DOM event forwarding, and a fresh Pinia per mountattachment-actionsslot with document, path, count, and selected attachments so downstream products can add actions without replacing routes or copying the componentsrc/*imports or a Vue Router requirement in reusable package codeStylesheet contract and containment
@celements/admin-frontend/styles.css, while keeping VueFinder JavaScript external as a peer.disabled, and.cropper-viewersselectors to the admin surface or known teleport boundariesForge npm delivery
@celementsscope forhttps://forge.celhosting.ch/api/packages/celements/npm/usingFORGE_TOKENJenkinsfile.npmpackage pipeline; the existingJenkinsfilecontinues to publish only the Docker imagex.y.z-snapshot.<BUILD_NUMBER>.<GIT_SHA>versions with thesnapshotdist-tag, and require exactadmin-frontend-vx.y.ztags for release versions published withlatestx.y.z-SNAPSHOTpublication and refuse overwriting a package version already present in ForgeCI operations must still configure a Jenkins job whose script path is
celements-admin-frontend/Jenkinsfile.npm. No npm package is published automatically until that infrastructure step exists.Validation
npm run build— passed; 3 test files and 16 tests passednpm run lint— passednpm run format— passednpm pack --dry-run --json --cache <writable-temp-cache>— passed;dist/package/styles.cssincludedmvn -f celements-webapp/pom.xml -DskipTests compile—BUILD SUCCESS(repository metadata checks emitted local authentication warnings)git diff --check origin/dev...HEAD— passedJira: https://synjira.atlassian.net/browse/CELDEV-1338