Skip to content

ci(docs): sync documentation branch with development - #235

Merged
rubenvdlinde merged 27 commits into
documentationfrom
chore/sync-from-development
May 13, 2026
Merged

ci(docs): sync documentation branch with development#235
rubenvdlinde merged 27 commits into
documentationfrom
chore/sync-from-development

Conversation

@rubenvdlinde

Copy link
Copy Markdown
Contributor

Brings the documentation branch up to date with development so the live docs site (which deploys from documentation) reflects the latest preset/landing/tutorial work.

Annotates every schema in the softwarecatalogus register that has a
status enum:

| Schema       | Actions |
|--------------|---------|
| organisatie  | activate, deactivate, reactivate |
| gebruik      | plan, goLive, phaseOut, retire |
| contract     | sign, expire, renegotiate |
| koppeling    | release, sunset, withdraw |
| moduleVersie | release, sunset, withdraw |

OpenRegister's LifecycleValidationListener now enforces every status
move on these schemas. Status changes that skip steps (e.g. organisatie
Concept → Deactief without going through Actief) are rejected via
HookStoppedException → HTTP 422.

Companion: ConductionNL/openregister#1357
Add the softwarecatalog-manifest-v1 OpenSpec change that mirrors the
decidesk Tier-4 migration (ConductionNL/decidesk#160) for SoftwareCatalog.

- proposal.md: 14 page entries (6 index, 6 detail, 1 settings, 2
  custom: Organisaties + Dashboard) consuming
  @conduction/nextcloud-vue@^1.0.0-beta.12.
- design.md: per-page mapping table + custom-fallback inventory + the
  @resolve:voorzieningen_register sentinel pattern + cleanup
  follow-up tracker.
- tasks.md: 9-phase task list mirroring decidesk's adopt sequence.
- specs/softwarecatalog-manifest-v1/spec.md: REQ-SCMV1-1..10 covering
  manifest invariants (version, dependencies, page types, sentinel
  usage, shallow-clone bootstrap, webpack alias).

References ADR-024 (App Manifest), the merged decidesk migration PR
#160, and nextcloud-vue/openspec/changes/manifest-resolve-sentinel/.
…builder + validator

Introduce the JSON manifest as the source of truth for SoftwareCatalog's
shell, with a paired customComponents registry, a routesFromManifest()
helper, and a Node validator script.

- src/manifest.json: 15 page entries (1 dashboard custom + 1
  organisaties custom + 6 indexes + 6 details + 1 settings).
  Register slug field uses the @resolve:voorzieningen_register
  sentinel so per-tenant IAppConfig values flow through the loader
  (manifest-resolve-sentinel contract). Schema slugs stay literal.
- src/customComponents.js: registry exporting the 3 surviving
  custom components — OrganisatieIndexView (bespoke card view +
  AddContactpersoonModal), SoftwareCatalogSettingsPage (admin
  settings orchestration), DashboardCustomView (info-box + 2
  stats tables). Each entry documents its lib-gap rationale.
- src/router.js: routesFromManifest() builds vue-router routes from
  manifest.pages[*]. Shallow-clones CnPageRenderer to dodge Vue 2's
  Vue.extend() mutation guard against frozen lib exports.
- tests/validate-manifest.js: Ajv 2020-12 validator mirroring
  decidesk's tests/validate-manifest.js. Schema lookup falls back
  to the sibling decidesk node_modules copy when softwarecatalog
  has not yet npm-installed.

Validation: node tests/validate-manifest.js — Ajv validation: PASS
(0 errors against schema v1.2.0).
…e + deps + webpack)

Replace the hand-wired NcContent + MainMenu + Views shell with the
manifest-driven CnAppRoot + CnPageRenderer renderer from
@conduction/nextcloud-vue@^1.0.0-beta.12. Mirrors decidesk's Tier-4
adoption commit (ConductionNL/decidesk#160 commit ed34703c) plus the
mount-survivable bootstrap pattern from commit 50e4df7c.

- src/main.js: bootstrap rewrite. Imports defaultPageTypes,
  registerIcons, registerTranslations from the lib. Builds vue-router
  routes from the manifest via routesFromManifest(). Mount-survivable
  tryLoadTranslations() — fire-and-forget, never blocks $mount() on a
  translation 404. Shallow-clones defaultPageTypes + customComponents
  before passing as props (Vue.extend frozen-component guard).
- src/App.vue: replace NcContent shell with <CnAppRoot> mounting the
  manifest, custom-components, page-types props. Provides the
  objectSidebarState reactive channel for CnDetailPage to drive a
  single host-rendered <CnObjectSidebar> via the #sidebar slot. Keeps
  the legacy global <Modals /> + <Dialogs /> mounted at app root.
- package.json: bump @conduction/nextcloud-vue to ^1.0.0-beta.12;
  add vue-router ^3.6.5; add npm script check:manifest.
- webpack.config.js: add @nextcloud/axios$ exact-match alias (works
  around @nextcloud/vue's CJS bundle requiring @nextcloud/axios while
  the package's exports field only declares the import condition).
  Add SCSS rule for aliased @conduction/nextcloud-vue components.
  Add vue-router to the shared vendor split-chunk match.
- eslint.config.js: turn off import/named (cannot statically resolve
  the lib's frozen barrel re-exports), n/no-missing-require,
  n/no-extraneous-require, n/no-process-exit, n/shebang, no-console
  for the validate-manifest Node script. Mirrors decidesk's eslintrc.
- l10n/en_US.json + en_US.js: mirror en.json + en.js so Apache's l10n
  route serves the en_US locale identically (i18n required pattern).
- appinfo/info.xml: bump <version> 0.1.141 → 0.2.0 to mark Tier-4
  adoption.

Validation:
- node tests/validate-manifest.js: PASS (0 errors).
- eslint src/main.js src/router.js src/customComponents.js src/App.vue
  tests/validate-manifest.js: clean (0 errors).
- Production webpack build deferred — node_modules carries the
  pre-manifest-renderer @conduction/nextcloud-vue@0.1.0-beta.17;
  npm install at deploy time pulls ^1.0.0-beta.12 (tracked in
  tasks.md §8.3 + §9.6).
…nifest renderer

Remove the legacy hand-wired shell now that CnAppRoot + CnPageRenderer
take over from the manifest:

- src/views/Views.vue — replaced by manifest page dispatch via
  CnPageRenderer.
- src/views/ObjectIndex.vue — replaced by built-in type='index'
  rendering with manifest-supplied register / schema / columns config.
- src/views/dashboard/DashboardIndex.vue — legacy nested empty
  scaffolding, dead code.
- src/navigation/MainMenu.vue — replaced by CnAppNav, mounted by
  CnAppRoot from manifest.menu[].

Surviving custom views (registered in src/customComponents.js):
- src/views/Dashboard.vue → DashboardCustomView (deferred to a
  follow-up that extracts info-box + 2 stats-table widgets into
  declarative widgets[]).
- src/views/organisaties/OrganisatieIndex.vue → OrganisatieIndexView
  (lib gap: bespoke OrganisatieCard + AddContactpersoonModal flow).
- src/views/settings/SoftwareCatalogSettings.vue →
  SoftwareCatalogSettingsPage (lib gap: 8-tab settings sub-section
  orchestration + ArchiMate status polling not yet covered by the
  type='settings' rich-section widgets).

Run-time route inventory (15 entries) preserved 1:1; the legacy
navigationStore.selected dispatcher is no longer wired but stays
in src/store for the surviving custom views.
…ifest-v1

feat: migrate softwarecatalog to JSON manifest renderer
Captures the spec that softwarecatalog's OpenRegister-CRUD store at
src/store/modules/object.js MUST be created via createObjectStore +
plugins (already true since PR #189), and that the four remaining
vanilla defineStore modules (navigation/settings/catalog/organisatie)
hold non-OpenRegister state and are exempt.

Flags two lib gaps:
- @resolve: sentinel resolution unimplemented in nextcloud-vue
- liveUpdatesPlugin available but not wired (out-of-scope here)

References:
- Project memory rule feedback_store-pattern.md
- Decidesk #162 (canonical failure case)
- nextcloud-vue/openspec/changes/manifest-resolve-sentinel/
ESLint flagged four `@param {Type} [name=null]` JSDoc shapes as
violations of `jsdoc/no-defaults`. The annotation is meant to declare
optionality (`[name]`) — defaults belong in the description text.
Rewriting the four offenders without semantic change.
…re-migration

fix: migrate softwarecatalog to @conduction/nextcloud-vue useObjectStore
Bumps the lib from caret on beta.12 (lockfile pinned at 0.1.0-beta.3
because the carat doesn't slide forward across prerelease segments) to
^1.0.0-beta.30, the latest beta dist-tag.

Activates the lib's `manifest-resolve-sentinel` capability for
softwarecatalog. The bundled manifest declares 12 `@resolve:` sentinels
(`@resolve:voorzieningen_register` across all voorzieningen pages); the
old lib passed them through unresolved, breaking voorzieningen pages
at runtime. main.js now wires `useAppManifest` so the resolver runs
on boot, consulting `@nextcloud/initial-state` first and falling back
to `/apps/softwarecatalog/api/configs/{key}`. The render function
reads `manifestRef.value` inside `render(h)` so Vue re-renders App
when sentinel resolution completes.

Gates (extended with workspace-server node_modules for hoisted
webpack/jest):
  - npm run build: success, 4 size-budget warnings (same as dev)
  - npm test: 4/4 pass
  - npm run check:manifest: PASS (0 errors)
  - npm run lint: pre-existing peer-dep failure on dev baseline
    (eslint-plugin-import not installed); not introduced by this PR.
The 12 `@resolve:voorzieningen_register` sentinels in src/manifest.json
weren't being resolved at runtime because the lib's useAppManifest only
runs sentinel resolution inside the backend-fetch success path, and
softwarecatalog has no /api/manifest controller. Beta.30 (PR #220)
brought in the resolver but it couldn't fire without backend wiring.

This patch provisions every distinct `@resolve:<key>` sentinel via
OCP\AppFramework\Services\IInitialState in Application::boot(). The
lib's readInitialState() helper calls loadState(appId, key, undefined)
synchronously (Step 1 of resolveManifestSentinels.js), so the chain
hits initial-state before falling back to the deferred backend fetch
(Step 2), unblocking all 12 voorzieningen pages immediately.

A full /api/manifest backend controller (Option A) is deferred as a
future follow-up — Option B (IInitialState) is the minimal fix.

Keys provisioned: voorzieningen_register

Closes #221
…ffs (#223)

* chore: add missing @nextcloud/eslint-config peer deps + fix PHPCS sniffs

Restore the npm run lint baseline by adding the peer dependencies that
@nextcloud/eslint-config requires but were not installed. Lint was
failing in #220 and #222 with "ESLint couldn't find the plugin
eslint-plugin-import" (and a chain of follow-on errors).

Added to devDependencies:
- eslint-plugin-import ^2.26.0
- eslint-plugin-n ^16.0.0
- eslint-plugin-vue ^9.7.0
- eslint-plugin-jsdoc ^46.2.6
- eslint-plugin-promise ^6.6.0
- eslint-config-standard ^17.1.0
- @nextcloud/eslint-plugin ^2.2.1
- @vue/eslint-config-typescript ^13.0.0
- @babel/eslint-parser ^7.16.5
- eslint-import-resolver-exports ^1.0.0-beta.5
- eslint-import-resolver-typescript ^3.8.0

All versions match the peerDependencies declared by
@nextcloud/eslint-config@^8.4.1.

Also fixes the two PHPCS Squiz tag-value-indent errors flagged in #222:
- lib/Service/SymfonyEmailService.php:53
- lib/Service/SettingsService.php:57

Both are auto-fixable via phpcbf — alignment of the tag value to 13
spaces after @SuppressWarnings(PHPMD.StaticAccess).

Gates:
- npm run lint — 0 errors (was: ESLint plugin not found)
- npm test     — 4/4 pass (unchanged)
- phpcs        — clean on the 2 touched files (was: 2 errors)

No source code changes; devDependencies and docblock indentation only.

* ci(npm): add .npmrc with legacy-peer-deps=true so npm ci works

Mirror of the fleet-wide pattern. CI's `npm ci` is strict; without
this flag it fails on @nextcloud/eslint-config peer chain conflicts
(@typescript-eslint/utils version mismatch with eslint-plugin-import-x
peerOptional).
…224)

* chore(stylelint): add missing @nextcloud/stylelint-config peer deps

Mirrors pipelinq #333. @nextcloud/stylelint-config declares its
shared configs as peerDependencies, which npm install
--legacy-peer-deps does not auto-install — so the stylelint
binary itself plus stylelint-config-recommended-scss were both
missing from node_modules and npm run stylelint was failing.

Adds stylelint, postcss-html, stylelint-config-recommended-scss
and stylelint-config-recommended-vue to devDependencies. No
source changes.

Before: npm run stylelint -> "stylelint: not found"
After:  npm run stylelint -> stylelint runs (see PR body for
        pre-existing source-level violations to address in a
        follow-up).

* style: auto-fix 144 stylelint indentation errors via --fix

The new stylelint deps (added in the parent commit) un-blocked the
gate so 144 pre-existing 'indentation' rule errors became visible
in src/components/AlwaysVisibleSection.vue and
src/components/ContactpersonenList.vue. Applied stylelint --fix
which mechanically realigned indentation in both files; no semantic
or visual change.

Note: the 'indentation' rule is itself deprecated in stylelint 16+;
a future config migration will replace it with prettier or
@Stylistic. Until then, --fix output is the canonical source of
truth and the gate now passes.
Picks up the manifest column abstractions and — crucially — the
`CnIndexPage` store-backed self-fetch mode (nc-vue #219/#221/#222/#223):

- `CnIndexPage` now self-fetches its collection in the manifest path
  (`register` + `schema`, no `objects` prop) via `useListView`, so the
  six `type:"index"` manifest pages (Contactpersonen, Contracten,
  Standaarden, Reviews, Komplianties, Moduleversies) render their object
  collection instead of an empty table.
- `columns[].formatter` / `columns[].widget` / `columns[].aggregate` and
  `pages[].config.filter` are available for those pages.

Also: add `ajv` + `ajv-formats` to devDependencies — `npm run
check:manifest` crashed because the only top-level `ajv` was v6 (a
transitive dep) while `ajv-formats` needs v8; the validate-manifest
script's `require('ajv/dist/2020')` now resolves. `check:manifest` →
PASS (0 errors). `npm run build` ✓, `npm test` ✓ (4 tests).

Update the `OrganisatieIndexView` note in customComponents.js: the
`cardComponent` config field it was waiting on landed, but the
OrganisationModal/AddContactpersoonModal/status-dialog/`_extend`/URL-hash
flow around it keeps the page type='custom' for now.
chore(deps): bump @conduction/nextcloud-vue to ^1.0.0-beta.40
…c getters that can't be mocked) + autoload tests/Stubs; disable Newman until the magic-mapper collection is rewritten for CI base_url/paths
…ge")

Wire the built-in `"badge"` cell widget (→ CnStatusBadge, nc-vue
beta.40) on the enum columns of the `type:"index"` pages so they render
as styled pills instead of raw text:

- Contracten / Komplianties / Moduleversies — `status`
- Standaarden — `status` + `categorie`

Pure manifest change — `"badge"` resolves to the lib's built-in widget
(no `cellWidgets` registry needed); object-shaped columns require a
`label`, so each carries one.

Verified: `node tests/validate-manifest.js` → PASS (0 errors, schema 1.5.0),
`npm run build` ✓.
feat(manifest): render status/category columns as badges
nc-vue beta.42 (#226) ships built-in `date` / `datetime` / `relative-time`
formatters in `cnFormatters` so manifests can use them without a per-app
`formatters.js`. Wire them on the date columns of the `type:"index"`
pages so they render as locale-formatted dates instead of raw ISO strings:

- Contracten `ingangsdatum` / `einddatum` → `formatter:"date"` (labels Start / End)
- Reviews `datum` → `formatter:"date"`
- Komplianties `datum` → `formatter:"date"`
- Moduleversies `releaseDatum` → `formatter:"date"` (label Released)

Object-shaped columns require a `label` so each carries one (English; the
lib's `t()` wiring translates).

Also bumps `@conduction/nextcloud-vue` `^1.0.0-beta.40` → `^1.0.0-beta.42`.

Verified: `node tests/validate-manifest.js` PASS (0 errors, schema 1.5.0),
`npm run build` ✓. Closes part of #229.
…ta42

feat(manifest): render date columns via the built-in date formatter
@rubenvdlinde
rubenvdlinde merged commit d99f365 into documentation May 13, 2026
@rubenvdlinde
rubenvdlinde deleted the chore/sync-from-development branch May 13, 2026 09:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant