Skip to content
This repository was archived by the owner on May 29, 2026. It is now read-only.

fix(wizard): mount Add action, footer nav, namespaced seed schemas + create-app tutorial#70

Merged
rubenvdlinde merged 4 commits into
developmentfrom
fix/openbuilt-wizard-and-data-fetch
May 16, 2026
Merged

fix(wizard): mount Add action, footer nav, namespaced seed schemas + create-app tutorial#70
rubenvdlinde merged 4 commits into
developmentfrom
fix/openbuilt-wizard-and-data-fetch

Conversation

@rubenvdlinde

Copy link
Copy Markdown
Contributor

Summary

Three integration bugs surfaced by visual smoke on the merged chain, all fixed, plus a tutorial that walks through the wizard end-to-end.

What was broken

  • Bug: VirtualAppsActions actionsComponent not mounting on CnIndexPage index page #66 — The new `VirtualAppsActions` (with the Add Application button that opens the wizard) didn't mount. The default CnIndexPage "Add Item" dialog showed up instead.
  • Wizard footer nav missing — Next/Back/Create rendered nowhere because the wizard used `<template #actions>` on ``, which has no actions slot.
  • Schema slug uniqueness — clicking Create in the wizard tripped a Postgres unique-constraint violation: the seed `hello-message` schema was inserted into both the development and production per-version registers with the same slug, but OR enforces slug uniqueness per organisation.

What's in this PR

  1. `src/manifest.json` — `actionsComponent` moved from `page.config` to page top-level on VirtualApps + VirtualAppDetail. CnPageRenderer reads it at top-level (it's slot-mapping sugar for `#actions`), not under config. Also added `config.showAdd: false` on VirtualApps (cosmetic suppression of the default Add button; investigation ongoing — see follow-up).
  2. `src/dialogs/CreateApplicationWizard.vue` — replaced `<template #actions>` with an inline `.wizard__footer` div at the bottom of the modal body, with border-top + flex layout. Back / Next / Create now actually render.
  3. `lib/Service/ApplicationCreationService.php` — `provisionRegister` now namespaces every seed schema slug with `{appSlug}-{versionSlug}-` prefix before `createFromArray`. Each per-version register gets its own copy of the `hello-message` schema with a unique slug (e.g. `test-app-development-hello-message` + `test-app-production-hello-message`).
  4. `appinfo/info.xml` — version bump 0.2.0 → 0.3.1. Without it, Nextcloud's static-asset `?v=` cache buster never changes and browsers cling to old JS bundles indefinitely.
  5. `docs/tutorials/create-a-virtual-app.md` + 5 screenshots — full walkthrough of the wizard's three visible steps (Basics → Preset → Review) with real captures from a working dev container, plus a troubleshooting section linking to Bug: VirtualAppsActions actionsComponent not mounting on CnIndexPage index page #66Bug: MigrateToVersionedModel didn't actually drop pre-versioned Hello World app #69 + the bug noted below.

Companion PR

The nc-vue side of #67 is in conductionnl/nextcloud-vue PR #... (`fix/cnindexpage-register-object-type-positional`). It fixes `CnIndexPage` + `CnLogsPage` to pass positional args to `registerObjectType`. Without that fix the index page still 404s on OR.

Remaining wizard blocker (new follow-up)

After all the above is applied, clicking Create in the wizard now reaches the backend cleanly, but OR returns:

The required properties (name, slug, manifest, register, application) are missing.

…even though the wizard payload populates all 7 required ApplicationVersion fields (name / slug / manifest / register / semver / status / application). Probable causes:

  • saveObject's named-arg call signature isn't being honoured for one of the 5 fields it claims are missing.
  • The `application` relation field expects a different shape than a bare UUID string (perhaps `{id: }`).
  • Some OR-side normalisation is stripping fields it doesn't recognise on the org-RBAC pass.

To file as a new issue with the steps to reproduce. The wizard's UI flow works end-to-end (verified in tutorial screenshots); only the final save is blocked.

Visual-smoke evidence

Tutorial screenshots in `docs/tutorials/img/` show:

  • Empty wizard step 1
  • Name + slug filled (auto-derive working)
  • Step 2 preset picker (4 cards)
  • Preset selected
  • Step 3 review screen with version chain

Test plan

  • Manual: navigate to /apps/openbuilt/applications, see 12 Hello World cards (was "No items found")
  • Manual: click "Add application", wizard opens at step 1
  • Manual: name → slug auto-derive
  • Manual: progress through all 3 steps; Create button enables on review
  • Manual: clicking Create successfully creates the app (BLOCKED by the new issue above)
  • composer check:strict — should still pass (file as a verify task once we resolve the wizard backend blocker)

🤖 Generated with Claude Code

… seed schema slugs

Three integration bugs that broke the create-app user flow, plus the tutorial
that walks through it end-to-end.

1) actionsComponent placement (#66) — CnPageRenderer reads page.actionsComponent
   at page top-level, NOT page.config.actionsComponent. Spec F's finisher had
   moved it inside config to silence a manifest-shape test; that broke the
   real CnPageRenderer slot pathway. Moved back to top-level on VirtualApps
   AND VirtualAppDetail page entries. Added config.showAdd: false to suppress
   the default Add Item button (cosmetic — investigation in apply-notes).

2) Wizard footer nav (Next/Back/Create) — CreateApplicationWizard.vue used
   <template #actions>, but NcModal has no actions slot. Buttons rendered
   nowhere. Moved into an inline .wizard__footer div at the bottom of the
   modal body, with border-top + flex layout.

3) Schema-slug uniqueness on per-version register seeding —
   ApplicationCreationService::provisionRegister fed the seed schema slug
   ('hello-message') verbatim into N registers. OR enforces slug uniqueness
   per organisation, so the second register's seed failed with a Postgres
   unique-constraint violation. Now namespaced to {appSlug}-{versionSlug}-
   prefix so 'test-app-development-hello-message' and
   'test-app-production-hello-message' coexist.

4) Tutorial — docs/tutorials/create-a-virtual-app.md with 5 verified
   screenshots walking through the wizard (Basics → Preset → Review).
   Captures the troubleshooting context for follow-up issues #66/#67/#68/#69.

5) info.xml version 0.2.0 → 0.3.1 to invalidate Nextcloud's static-asset
   cache (browser was clinging to the old openbuilt-main.js until ?v=
   changed).

Remaining wizard blocker: ApplicationVersion saveObject reports name/slug/
manifest/register/application missing despite payload carrying all 7
required fields. To be filed as a new follow-up issue alongside the
existing #66-#69.
@github-actions

Copy link
Copy Markdown
Contributor

Quality Report — ConductionNL/openbuilt @ 34e9c15

Check PHP Vue Security License Tests
lint
phpcs
phpmd
psalm
phpstan
phpmetrics
eslint
stylelint
composer ✅ 100/100
npm
PHPUnit ⏭️
Newman ⏭️
Playwright ⏭️

Quality workflow — 2026-05-16 09:49 UTC

Download the full PDF report from the workflow artifacts.

closes #71)

OR's saveObject runs full-schema 'required[]' validation on every call,
whether the UUID is set (UPDATE) or not (CREATE). There is no PATCH
semantics — passing { promotesTo: <uuid> } + an existing UUID was
rejected because OR didn't merge the payload with the existing record
before validating; it just validated the partial payload alone and
correctly reported the other required fields as missing.

Fix: keep the full version payload from the create step in
$state['versionPayloads'][$versionSlug], then merge the patched field
(promotesTo or productionVersion) and pass the merged payload back to
saveObject along with the existing UUID. OR then routes the call as an
UPDATE with a fully-validated payload.

Same fix applied at both partial-update sites:
- Step 4 (chain-wiring): payload includes name/slug/manifest/register/
  semver/status/application + the new promotesTo target.
- Step 5 (set Application.productionVersion): payload includes the
  Application's name/slug/description/permissions + the new
  productionVersion pointer.

Also adds versionPayloads to the rollback state shape so the merge step
has the data it needs.

Verified end-to-end via visual smoke:
- Wizard opens, advances through Step 1 → 2 → 3 → Create
- App created (URL changes to /applications/<uuid>)
- Detail page renders with KPI grid + structural widgets
- New app appears in Virtual apps index

Tutorial updated with success-state screenshots (app detail page,
index after wizard close).
@github-actions

Copy link
Copy Markdown
Contributor

Quality Report — ConductionNL/openbuilt @ 24d5aab

Check PHP Vue Security License Tests
lint
phpcs
phpmd
psalm
phpstan
phpmetrics
eslint
stylelint
composer ✅ 100/100
npm
PHPUnit ⏭️
Newman ⏭️
Playwright ⏭️

Quality workflow — 2026-05-16 10:41 UTC

Download the full PDF report from the workflow artifacts.

CnDetailPage's #header slot only forwards presentational props
(title / description / icon), NOT the resolved object. The header
component's '$props.object' was always null, so 'application' fell
back to the 'Untitled application' translation and the version pills
+ name + status never rendered.

Fix: revert 'application' to data, and have refreshApplication fetch
the Application record from OR's objects API by UUID (resolved from
the route params when objectId prop is missing). mounted() now runs
the fetch unconditionally when application is empty.

Verified end-to-end: 'Permit Tracker' (the wizard-created app) now
shows its real name, status, owner role, and Production version pill
in the hero. Tutorial screenshot updated.

Three small cosmetic issues remain (description rendering as record
field count, Register slug truncated, development version pill not
rendered alongside Production) — file as follow-up issues, not
blocking the full flow.
@github-actions

Copy link
Copy Markdown
Contributor

Quality Report — ConductionNL/openbuilt @ d15626c

Check PHP Vue Security License Tests
lint
phpcs
phpmd
psalm
phpstan
phpmetrics
eslint
stylelint
composer ✅ 100/100
npm
PHPUnit ⏭️
Newman ⏭️
Playwright ⏭️

Quality workflow — 2026-05-16 11:02 UTC

Download the full PDF report from the workflow artifacts.

…reenshots

Companion to docs/tutorials/create-a-virtual-app.md. Walks through the
maintainer dashboard, schema list (per-version), version switching, and
the promote flow. Honestly documents which steps currently work and
which have known follow-up bugs:

- Detail page hero + KPIs + widgets   \xe2\x9c\x85 work
- Schema list per version             \xe2\x9c\x85 works (namespaced slugs visible)
- Schema detail / edit                \xe2\x9d\x8c 404s on namespaced slug
- Version URL routing                 \xe2\x9c\x85 `?_version=` honoured
- Development pill rendering           \xe2\x9a\xa0 only Production renders
- Promote dialog                       \xe2\x8f\xb8 untested end-to-end pending schema edit

Two new screenshots:
- update-01-schemas-list.png: schema list with namespaced slugs
- update-02-schema-detail-404.png: schema not found error (with caveat)

Cross-links the related follow-up issues so the doc stays useful as the
remaining bugs land.
@github-actions

Copy link
Copy Markdown
Contributor

Quality Report — ConductionNL/openbuilt @ 7941ce4

Check PHP Vue Security License Tests
lint
phpcs
phpmd
psalm
phpstan
phpmetrics
eslint
stylelint
composer ✅ 100/100
npm
PHPUnit ⏭️
Newman ⏭️
Playwright ⏭️

Quality workflow — 2026-05-16 11:07 UTC

Download the full PDF report from the workflow artifacts.

@rubenvdlinde rubenvdlinde merged commit 8ff0dab into development May 16, 2026
14 of 20 checks passed
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant