Skip to content

feat(app-page): add the Support & donation editor to the app page - #453

Merged
rubenvdlinde merged 3 commits into
developmentfrom
feat/app-page-support-button
Aug 24, 2026
Merged

feat(app-page): add the Support & donation editor to the app page#453
rubenvdlinde merged 3 commits into
developmentfrom
feat/app-page-support-button

Conversation

@rubenvdlinde

Copy link
Copy Markdown
Contributor

Completes the app-level editor row on the app detail page. It now edits all four pieces of an app's chrome — settings, first-run wizard, guided tour, support note — instead of sending the user into the running app's orange edit menu for the last one.

Button Opens
Settings AppSettingsModal
Setup wizard Walkthrough Designer, ?mode=setup
Walkthrough Walkthrough Designer
Support & donation CnEditSupportModal ← this PR

Why it could not land before

CnEditSupportModal shipped inside the library for months and was never exported from its package index, so no consumer could mount it. It was compiled into dist the whole time, because CnBuildiqEditButton imports it internally — the component existed, the door did not.

ConductionNL/nextcloud-vue#748 exports it, and 2.15.1 is the first release carrying that. This PR bumps the dependency to ^2.15.1.

I verified the published tarball, not the repo: CnEditSupportModal is present in dist/esm/index.js, and the v2 schema carries the support block (5 occurrences). A green source repo would not have proven the artefact consumers actually install.

Behaviour

The button opens the editor on a clone of the resolved manifest, so cancelling costs nothing — the copy is dropped.

The manifest is resolved from the active version through the app's own endpoint, not read off the Application record: an Application carries no manifest, it lives on the ApplicationVersion, and obApp.manifest is undefined. Opening the editor on that would hand it an empty object and silently save an empty support block over a real one.

Verification

  • eslint src exit 0, npm run build exit 0, 0 errors, button present in the emitted bundle — built against the real published package, no local patching.
  • Earlier in development I confirmed in a browser that all four buttons render and the modal opens, by patching the export lines into the installed copy; that patch was reverted and node_modules restored to stock before this branch was built.

Also drops the stale comment claiming these modals "cannot be imported" — true when written, not any more.

Completes the app-level editor row. The app page now edits all four pieces of
an app's chrome — its settings, its first-run wizard, its guided tour and its
support note — rather than sending the user into the running app's orange edit
menu for the last one.

The button opens `CnEditSupportModal` on a CLONE of the resolved manifest, so
cancelling costs nothing: the copy is simply dropped. The manifest is resolved
from the active version through the app's own endpoint rather than read off the
Application record, because an Application carries no manifest — it lives on
the ApplicationVersion, and `obApp.manifest` is undefined.

Requires @conduction/nextcloud-vue 2.15.1, bumped here. The modal shipped
inside the library for months but was never exported from its package index,
so no consumer could mount it; ConductionNL/nextcloud-vue#748 exports it and
2.15.1 is the first release that carries it. Verified against the published
tarball rather than the repo: `CnEditSupportModal` is present in
dist/esm/index.js and the v2 schema carries the `support` block.

Also drops the stale comment that said these modals "cannot be imported" —
that was true when it was written and is not any more.
`test:l10n` caught two strings the support button introduced that no catalogue
carried: "Support & donation" and "Failed to load settings".

Added to l10n/en.json via the repo's own extractor, translated on the Dutch
side, and — the part that matters — regenerated l10n/*.js.

Nextcloud does not serve the JSON. It serves the compiled l10n/*.js built from
it, so a key present only in the JSON is a string the browser never receives.
That is the same gap that made `test:l10n` pass and `check:l10n-js` fail
earlier on this branch's predecessor: two l10n gates, only one of which can see
the artefact the runtime loads.

Both now pass, and the key is present in en.js and nl.js.
development bumped @conduction/nextcloud-vue to ^2.15.0 while this branch was
open; this branch needs ^2.15.1.

That is not a preference for the higher number. 2.15.0 does NOT export
`CnEditSupportModal` — ConductionNL/nextcloud-vue#748 landed after it was cut,
and 2.15.1 is the first published version carrying the export. Resolving toward
development here would leave the import in this branch pointing at a symbol the
installed package does not provide, and the build would fail.

Took development's package-lock.json wholesale and regenerated it against the
resolved package.json rather than hand-merging a lockfile, so the tree is npm's
own resolution and not a three-way guess.

Verified after the merge: eslint clean, prettier clean, test:l10n OK, and
check:l10n-js OK — the second of those matters because it is the gate that
reads the compiled artefact the browser actually loads.
@github-actions

Copy link
Copy Markdown
Contributor

Quality Report — ConductionNL/buildiq @ 249abf5

Check PHP Vue Security License Tests
lint
phpcs
phpmd
psalm
phpstan
phpmetrics
eslint
stylelint
build
check-manifest
test-l10n
check-gitignore
check-nc-floor
format
check-l10n-js
check-schema-l10n
composer ✅ 106/106
npm ✅ 642/642
app:check-code ⏭️
info.xml
REUSE
PHPUnit
Newman
Playwright
Hydra gates

Quality workflow — 2026-08-24 22:12 UTC

Download the full PDF report from the workflow artifacts.

@rubenvdlinde
rubenvdlinde merged commit ab730b2 into development Aug 24, 2026
87 checks passed
rubenvdlinde added a commit that referenced this pull request Aug 25, 2026
Two e2e tests are red on development, both refused at creation with 400:

    creating the fixture flow must succeed (got 400)
    seeding the definition must succeed (got 400)

openregister's TriggerScheduleNode now refuses a schedule trigger whose
config carries no 'runAs' (ADR-099). Nobody is present when a schedule
fires, so there is no session to take an identity from, and the flow's
owner is deliberately not used as a fallback — authoring a flow is not
consent to unattended execution as its author.

Both fixtures posted 'openregister.trigger-schedule' with an empty config,
so both are refused. The value is validated against real accounts via
userManager->get(), so it cannot be an arbitrary label; RUN_AS tracks the
account the suite authenticates as, from the same environment variable
playwright.config.ts reads.

Not caused by #453, which is simply the commit these failures first appear
on: the two commits between the last green e2e and this one are CI and docs
config only, and the 400 comes from openregister's validator rather than
from anything in this app. The same contract change is failing integriq's
JobToFlowGenerator test.
rubenvdlinde added a commit that referenced this pull request Aug 25, 2026
…461)

* fix(e2e): a scheduled fixture flow must name the identity it runs as

Two e2e tests are red on development, both refused at creation with 400:

    creating the fixture flow must succeed (got 400)
    seeding the definition must succeed (got 400)

openregister's TriggerScheduleNode now refuses a schedule trigger whose
config carries no 'runAs' (ADR-099). Nobody is present when a schedule
fires, so there is no session to take an identity from, and the flow's
owner is deliberately not used as a fallback — authoring a flow is not
consent to unattended execution as its author.

Both fixtures posted 'openregister.trigger-schedule' with an empty config,
so both are refused. The value is validated against real accounts via
userManager->get(), so it cannot be an arbitrary label; RUN_AS tracks the
account the suite authenticates as, from the same environment variable
playwright.config.ts reads.

Not caused by #453, which is simply the commit these failures first appear
on: the two commits between the last green e2e and this one are CI and docs
config only, and the 400 comes from openregister's validator rather than
from anything in this app. The same contract change is failing integriq's
JobToFlowGenerator test.

* fix(e2e): the schedule trigger needs cron AND runAs, not either

The first commit added runAs alone, and CI still returned 400 — the error
simply moved. Probed against a live instance to establish the whole
contract rather than inferring it from one message:

    {cron, runAs} -> 201
    {cron}        -> 400  'must carry a "runAs" naming the user its runs act as'
    {runAs}       -> 400  'must carry a "cron" expression'

Both are mandatory and each is refused separately, so an error naming one
says nothing about the other. These fixtures sent config: {}, so they were
always missing both; fixing one at a time reads as 'the fix did not work'
when it was half a fix.

FIXTURE_CRON is a five-field expression because macros like @hourly are
refused. Nothing here waits for the schedule to fire — the flows are
created disabled or driven directly — so the time only has to be valid.
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