@conduction/nextcloud-vue 2.56.0-beta.3 → 2.56.0-beta.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/components/CnAppRoot/CnAppRoot.vue2.js +21 -1
- package/dist/esm/components/CnAppRoot/CnAppRoot.vue2.js.map +1 -1
- package/dist/esm/components/CnAppRoot/CnAppRoot.vue3.js +1 -1
- package/dist/esm/components/CnAppRoot/CnAppRoot.vue3.js.map +1 -1
- package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue2.js +49 -5
- package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue2.js.map +1 -1
- package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue3.js +1 -1
- package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue3.js.map +1 -1
- package/dist/esm/l10n/en.json.js +1 -0
- package/dist/esm/l10n/en.json.js.map +1 -1
- package/dist/esm/l10n/nl.json.js +1 -0
- package/dist/esm/l10n/nl.json.js.map +1 -1
- package/dist/esm/nextcloud-vue.css +7 -0
- package/dist/esm/utils/validateManifestV2.compiled.js +2 -2
- package/dist/esm/utils/validateManifestV2.compiled.js.map +1 -1
- package/dist/nextcloud-vue.cjs.js +76 -10
- package/dist/nextcloud-vue.cjs.js.map +2 -2
- package/dist/nextcloud-vue.css +7 -0
- package/l10n/en.json +1 -0
- package/l10n/nl.json +1 -0
- package/package.json +1 -1
- package/src/components/CnAppRoot/CnAppRoot.vue +31 -2
- package/src/components/CnSetupWizard/CnSetupWizard.vue +57 -6
- package/src/schemas/app-manifest-v2.schema.json +2 -1
- package/src/utils/validateManifestV2.compiled.js +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CnAppRoot.vue2.js","sources":["../../../../src/components/CnAppRoot/CnAppRoot.vue"],"sourcesContent":["<!--\n CnAppRoot — top-level wrapper for manifest-driven Conduction apps.\n\n Provides the manifest, custom-component registry, and translate\n function to descendants via Vue's `provide`/`inject`. Orchestrates\n four rendering phases:\n\n 0. Capabilities — checks the Nextcloud capabilities API for any\n app id listed in `requiresApps` (default\n `['openregister']`). When a required app is\n missing, default content is <NcEmptyContent>\n with an OR-store action; consumers may replace\n the surface entirely via the #or-missing slot.\n Apps that do not need the guard pass\n `:requires-apps=\"[]\"`.\n 1. Loading — while useAppManifest.isLoading is true.\n Default: <CnAppLoading />. Override: #loading slot.\n 2. Dependency — after loading; when any entry in\n manifest.dependencies is not installed/enabled.\n Default: <CnDependencyMissing />. Override:\n #dependency-missing slot.\n 3. Shell — manifest loaded + dependencies satisfied.\n Renders #menu (default <CnAppNav />) + the\n consuming app's <router-view>, plus optional\n #header-actions, #sidebar, and #footer slots.\n\n Consuming apps that want manifest-driven pages but their own root\n layout can skip CnAppRoot entirely and use CnPageRenderer / CnAppNav\n with explicit props (the props-vs-inject fallback). CnAppRoot is the\n full-shell convenience.\n\n Hosts a per-user `NcAppSettingsDialog` that any descendant can open\n via the injected `cnOpenUserSettings()` method. CnAppNav binds the\n inject to manifest entries with `action: \"user-settings\"`. Apps\n populate the modal by passing `NcAppSettingsSection`s into the\n `#user-settings` slot; the slot falls back to a single placeholder\n section when no content is supplied.\n\n A SECOND, distinct `NcAppSettingsDialog` hosts admin-only, app-level\n (not per-user) settings, driven GENERICALLY by `manifest.adminSettings[]`\n (sorted by `order`) — one `NcAppSettingsSection` per entry. The built-in\n `type: \"organisation-credentials\"` renders the organisation credential\n broker (`CnCredentials scope=\"organisation\"`); a `component` entry\n resolves from the `customComponents` registry, forwarding `props`. Any\n descendant opens the dialog via the injected `cnOpenAdminSettings()`\n method; CnAppNav auto-prepends an \"Admin settings\" entry (visible only\n to app OWNERS — `currentUserGroups` ∩ `permissions.owners`, or a\n `runtime.user` owner signal; NOT `OC.isUserAdmin()`) that opens it, and\n also binds manifest entries with `action: \"admin-settings\"`. An app\n with no (or empty) `adminSettings` mounts no admin dialog and no admin\n nav entry at all — the org-credentials pane is no longer hardcoded;\n apps declare it explicitly as one `adminSettings` entry. Apps can still\n populate it via the `#admin-settings` slot (which overrides the\n generic render entirely).\n\n See REQ-JMR-003 and REQ-JMR-013 of the json-manifest-renderer spec,\n and REQ-OR-1..REQ-OR-7 of the cnapproot-app-availability-guard spec.\n-->\n<template>\n\t<NcContent :appName=\"appDisplayName || (manifest && manifest.name) || appId\" :data-nldesign-theme-scope=\"appId\" data-testid=\"cn-app-root\">\n\t\t<!-- Phase 0a: capabilities check in flight -->\n\t\t<template v-if=\"capabilitiesLoading\">\n\t\t\t<div class=\"cn-app-root__capabilities-loading\" data-testid=\"cn-app-root-capabilities-loading\">\n\t\t\t\t<NcLoadingIcon :size=\"32\" />\n\t\t\t</div>\n\t\t</template>\n\n\t\t<!--\n\t\t @slot or-missing\n\t\t @description Custom missing-app screen used when one or more\n\t\t entries in `requiresApps` are absent from the Nextcloud\n\t\t capabilities payload. Receives `{ missingApps: string[] }`.\n\t\t Default content: an `<NcEmptyContent>` with the OpenRegister\n\t\t database icon, i18n title/description, and a primary action\n\t\t linking to the OpenRegister integration page. Override when\n\t\t the consumer needs a custom CTA (e.g. softwarecatalog linking\n\t\t to its public landing page). See REQ-OR-4.\n\t\t-->\n\t\t<template v-else-if=\"missingApps.length > 0\">\n\t\t\t<slot name=\"or-missing\" :missingApps=\"missingApps\">\n\t\t\t\t<div class=\"cn-app-root__or-missing\">\n\t\t\t\t\t<NcEmptyContent\n\t\t\t\t\t\t:name=\"orMissingTitle\"\n\t\t\t\t\t\t:description=\"orMissingDescription\">\n\t\t\t\t\t\t<template #icon>\n\t\t\t\t\t\t\t<DatabaseSearchOutline :size=\"64\" />\n\t\t\t\t\t\t</template>\n\t\t\t\t\t\t<template #action>\n\t\t\t\t\t\t\t<!--\n\t\t\t\t\t\t\t Admin: one click installs-and-enables (or enables)\n\t\t\t\t\t\t\t the missing app via Nextcloud's own settings/apps/\n\t\t\t\t\t\t\t enable endpoint, then reloads. On failure the error\n\t\t\t\t\t\t\t shows inline and the store link stays as a fallback\n\t\t\t\t\t\t\t (REQ-DIA-3).\n\t\t\t\t\t\t\t-->\n\t\t\t\t\t\t\t<template v-if=\"isAdmin\">\n\t\t\t\t\t\t\t\t<NcButton\n\t\t\t\t\t\t\t\t\tvariant=\"primary\"\n\t\t\t\t\t\t\t\t\tdata-testid=\"cn-app-root-or-missing-install\"\n\t\t\t\t\t\t\t\t\t:disabled=\"depInstalling\"\n\t\t\t\t\t\t\t\t\t@click=\"installDependency(orMissingPrimaryApp)\">\n\t\t\t\t\t\t\t\t\t<template #icon>\n\t\t\t\t\t\t\t\t\t\t<NcLoadingIcon v-if=\"depInstalling\" :size=\"20\" />\n\t\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t\t\t{{ orMissingInstallLabel }}\n\t\t\t\t\t\t\t\t</NcButton>\n\t\t\t\t\t\t\t\t<p v-if=\"depInstallError\" class=\"cn-app-root__or-missing-error\">\n\t\t\t\t\t\t\t\t\t{{ depInstallError }}\n\t\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t\t\t<a\n\t\t\t\t\t\t\t\t\tv-if=\"depInstallError\"\n\t\t\t\t\t\t\t\t\tclass=\"cn-app-root__or-missing-action\"\n\t\t\t\t\t\t\t\t\t:href=\"orStoreLink\">\n\t\t\t\t\t\t\t\t\t{{ orMissingActionLabel }}\n\t\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t<!--\n\t\t\t\t\t\t\t Non-admin: no dead-end link they cannot act on —\n\t\t\t\t\t\t\t point them at their administrator instead (REQ-DIA-3).\n\t\t\t\t\t\t\t-->\n\t\t\t\t\t\t\t<p v-else class=\"cn-app-root__or-missing-ask-admin\" data-testid=\"cn-app-root-or-missing-ask-admin\">\n\t\t\t\t\t\t\t\t{{ orMissingAskAdmin }}\n\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t</template>\n\t\t\t\t\t</NcEmptyContent>\n\t\t\t\t</div>\n\t\t\t</slot>\n\t\t</template>\n\n\t\t<!--\n\t\t @slot loading\n\t\t @description Loading screen rendered while the manifest\n\t\t fetch is in flight (REQ-JMR-013). Default content is a\n\t\t `<CnAppLoading />` brand spinner. Override when the consumer\n\t\t needs a custom skeleton or branded loader.\n\t\t-->\n\t\t<template v-else-if=\"phase === 'loading'\">\n\t\t\t<slot name=\"loading\">\n\t\t\t\t<CnAppLoading />\n\t\t\t</slot>\n\t\t</template>\n\n\t\t<!--\n\t\t @slot dependency-missing\n\t\t @description Empty-state surface rendered when one or more\n\t\t entries in `manifest.dependencies` are not installed/enabled.\n\t\t Receives `{ dependencies }` (the unresolved list). Default:\n\t\t `<CnDependencyMissing>`. See REQ-JMR-011.\n\t\t-->\n\t\t<template v-else-if=\"phase === 'dependency-missing'\">\n\t\t\t<slot name=\"dependency-missing\" :dependencies=\"unresolvedHardDependencies\">\n\t\t\t\t<CnDependencyMissing\n\t\t\t\t\t:dependencies=\"unresolvedHardDependencies\"\n\t\t\t\t\t:appName=\"appId\" />\n\t\t\t</slot>\n\t\t</template>\n\n\t\t<!--\n\t\t Phase 2b: setup — a REQUIRED first-time-setup step (ADR-042) is unmet,\n\t\t so the shell is gated to CnSetupWizard until it clears.\n\t\t-->\n\t\t<template v-else-if=\"phase === 'setup'\">\n\t\t\t<!--\n\t\t\t @slot setup\n\t\t\t @description Override the gating setup surface. Scope: the manifest\n\t\t\t setup steps + the useSetupStatus state.\n\t\t\t-->\n\t\t\t<slot name=\"setup\" :steps=\"manifest.setup.steps\" :status=\"setupState\">\n\t\t\t\t<div class=\"cn-app-root__setup\">\n\t\t\t\t\t<CnSetupWizard\n\t\t\t\t\t\t:appId=\"appId\"\n\t\t\t\t\t\t:appName=\"appDisplayName || (manifest && manifest.name) || appId\"\n\t\t\t\t\t\t:steps=\"manifest.setup.steps\"\n\t\t\t\t\t\t:cancellable=\"false\"\n\t\t\t\t\t\t:completedStepIds=\"setupCompletedStepIds\"\n\t\t\t\t\t\t@complete=\"onSetupComplete\" />\n\t\t\t\t</div>\n\t\t\t</slot>\n\t\t</template>\n\n\t\t<!-- Phase 3: shell -->\n\t\t<template v-else>\n\t\t\t<!--\n\t\t\t @slot menu\n\t\t\t @description Left-rail navigation surface. Default:\n\t\t\t `<CnAppNav>` reading `manifest.menu` and filtering by\n\t\t\t `permissions`. Override to ship a hand-rolled menu while\n\t\t\t keeping the rest of CnAppRoot's shell.\n\n\t\t\t An override that wraps `CnAppNav` MUST forward these bindings.\n\t\t\t The slot used to carry none, so a wrapper could only pass\n\t\t\t `manifest`, and `isAdmin` silently defaulted to false: the\n\t\t\t Admin-settings entry then rendered for nobody, on apps whose\n\t\t\t whole admin surface lives behind it. Openregister shipped that\n\t\t\t way until its own e2e caught it.\n\t\t\t-->\n\t\t\t<!-- @binding {object} manifest The menu manifest, after page-derived entries are merged. -->\n\t\t\t<!-- @binding {object} permissions Permission map used to filter menu entries. -->\n\t\t\t<!-- @binding {boolean} isOwner Whether the user owns this app (ADR-079 §3). -->\n\t\t\t<!-- @binding {boolean} isAdmin Whether the user administers the instance; gates the Admin-settings link. -->\n\t\t\t<!-- @binding {string} appId The app id used to build the Admin-settings target. -->\n\t\t\t<slot name=\"menu\"\n\t\t\t\t:manifest=\"menuManifest\"\n\t\t\t\t:permissions=\"permissions\"\n\t\t\t\t:isOwner=\"isOwner\"\n\t\t\t\t:isAdmin=\"isAdmin\"\n\t\t\t\t:appId=\"appId\">\n\t\t\t\t<CnAppNav :manifest=\"menuManifest\"\n\t\t\t\t\t:permissions=\"permissions\"\n\t\t\t\t\t:isOwner=\"isOwner\"\n\t\t\t\t\t:isAdmin=\"isAdmin\"\n\t\t\t\t\t:appId=\"appId\" />\n\t\t\t</slot>\n\t\t\t<NcAppContent>\n\t\t\t\t<!--\n\t\t\t\t Soft-dependency notices (REQ-DIA-6) — DEPRECATED, off by\n\t\t\t\t default since 2.1.0.\n\n\t\t\t\t These stacked. An app declaring four optional leaves rendered\n\t\t\t\t four orange NcNoteCards above its own content and pushed the\n\t\t\t\t page below the fold, every page load, for every user — while\n\t\t\t\t the only person who can act on the message is an\n\t\t\t\t administrator. The information now lives where that audience\n\t\t\t\t is: `CnLeafDependencySettings`, an admin-settings section\n\t\t\t\t carrying the same two states (not installed → \"Install and\n\t\t\t\t enable\"; installed but disabled → \"Enable\").\n\n\t\t\t\t The markup stays behind `softDependencyNotices` for one\n\t\t\t\t release so a consumer that genuinely needs the in-app surface\n\t\t\t\t can opt back in while it adopts the settings section. It is\n\t\t\t\t slated for removal.\n\t\t\t\t-->\n\t\t\t\t<NcNoteCard\n\t\t\t\t\tv-for=\"dep in visibleSoftDependencyNotices\"\n\t\t\t\t\t:key=\"'cn-soft-dep-' + dep.id\"\n\t\t\t\t\ttype=\"warning\"\n\t\t\t\t\t:heading=\"softDepHeading(dep)\"\n\t\t\t\t\tclass=\"cn-app-root__soft-dep\"\n\t\t\t\t\t:data-testid=\"'cn-app-root-soft-dep-' + dep.id\">\n\t\t\t\t\t<div class=\"cn-app-root__soft-dep-body\">\n\t\t\t\t\t\t<p class=\"cn-app-root__soft-dep-text\">\n\t\t\t\t\t\t\t{{ softDepText(dep) }}\n\t\t\t\t\t\t</p>\n\t\t\t\t\t\t<div class=\"cn-app-root__soft-dep-actions\">\n\t\t\t\t\t\t\t<NcButton\n\t\t\t\t\t\t\t\tv-if=\"isAdmin\"\n\t\t\t\t\t\t\t\tvariant=\"secondary\"\n\t\t\t\t\t\t\t\t:data-testid=\"'cn-app-root-soft-dep-install-' + dep.id\"\n\t\t\t\t\t\t\t\t:disabled=\"depInstalling\"\n\t\t\t\t\t\t\t\t@click=\"installDependency(dep.id)\">\n\t\t\t\t\t\t\t\t<template #icon>\n\t\t\t\t\t\t\t\t\t<NcLoadingIcon v-if=\"depInstalling && installingDepId === dep.id\" :size=\"20\" />\n\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t\t{{ dep.enabled === false ? softDepEnableLabel : softDepInstallLabel }}\n\t\t\t\t\t\t\t</NcButton>\n\t\t\t\t\t\t\t<span v-else class=\"cn-app-root__soft-dep-ask-admin\">\n\t\t\t\t\t\t\t\t{{ softDepAskAdmin(dep) }}\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t<NcButton\n\t\t\t\t\t\t\t\tvariant=\"tertiary\"\n\t\t\t\t\t\t\t\t:data-testid=\"'cn-app-root-soft-dep-dismiss-' + dep.id\"\n\t\t\t\t\t\t\t\t@click=\"dismissSoftDep(dep.id)\">\n\t\t\t\t\t\t\t\t{{ softDepDismissLabel }}\n\t\t\t\t\t\t\t</NcButton>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<p v-if=\"depInstallError && erroredDepId === dep.id\" class=\"cn-app-root__soft-dep-error\">\n\t\t\t\t\t\t\t{{ depInstallError }}\n\t\t\t\t\t\t</p>\n\t\t\t\t\t</div>\n\t\t\t\t</NcNoteCard>\n\t\t\t\t<!--\n\t\t\t\t In-app edit shell (ADR-041). The Conduction-orange Buildiq edit\n\t\t\t\t button is rendered INSIDE each page's action row (CnDashboardPage /\n\t\t\t\t CnDetailPage / CnIndexPage) — it self-wires from the `cnManifestEditor`\n\t\t\t\t and `cnOpenBuildAvailable` this component provides, so it sits inline\n\t\t\t\t with the page's normal buttons rather than as a floating overlay.\n\t\t\t\t-->\n\t\t\t\t<router-view :key=\"routerViewKey\" />\n\t\t\t\t<!--\n\t\t\t\t @slot tenant-badge\n\t\t\t\t @description Top-bar tenant indicator surface\n\t\t\t\t (multi-tenancy-context REQ-MT-4). Default:\n\t\t\t\t <CnTenantBadge /> — auto-hides when the user has 0–1\n\t\t\t\t organisations. Override to suppress entirely\n\t\t\t\t (`<template #tenant-badge></template>`) or to render\n\t\t\t\t a custom multi-tenant switcher.\n\t\t\t\t-->\n\t\t\t\t<slot name=\"tenant-badge\">\n\t\t\t\t\t<CnTenantBadge />\n\t\t\t\t</slot>\n\t\t\t\t<!--\n\t\t\t\t @slot header-actions\n\t\t\t\t @description Optional action buttons rendered in the\n\t\t\t\t page header alongside the router-view. Empty by\n\t\t\t\t default; consumer apps fill it with toolbar buttons.\n\t\t\t\t-->\n\t\t\t\t<slot name=\"header-actions\" />\n\t\t\t\t<!--\n\t\t\t\t @slot footer\n\t\t\t\t @description Optional footer surface rendered below the\n\t\t\t\t router-view inside `NcAppContent`. Empty by default.\n\t\t\t\t-->\n\t\t\t\t<slot name=\"footer\" />\n\t\t\t</NcAppContent>\n\t\t\t<!--\n\t\t\t Sidebar slot — gated by the `cnPageSidebarVisible` inject\n\t\t\t provided by `CnPageRenderer`. When the current manifest\n\t\t\t page declares `sidebar.show: false` (sibling of `config`),\n\t\t\t the renderer flips the holder's `.value` to `false` and\n\t\t\t the slot stops rendering. The default holder value (used\n\t\t\t when no `CnPageRenderer` ancestor exists) is `true`, so\n\t\t\t apps that mount their own page components without the\n\t\t\t renderer keep rendering the slot exactly as today.\n\n\t\t\t Default content: when `cnPageSidebarComponent.value` is a\n\t\t\t Vue component (set by the renderer when the current page\n\t\t\t declares a `sidebarComponent` registry name), it renders\n\t\t\t here as the slot's DEFAULT content. The consumer's\n\t\t\t `#sidebar` slot override (when supplied) wins via Vue's\n\t\t\t standard slot mechanic; the resolved component is the\n\t\t\t fallback. See manifest-named-view-sidebar spec.\n\t\t\t-->\n\t\t\t<!--\n\t\t\t @slot sidebar\n\t\t\t @description Right-rail sidebar surface. Gated by the\n\t\t\t `cnPageSidebarVisible` inject (provided by `CnPageRenderer`)\n\t\t\t so manifest pages can suppress the sidebar via\n\t\t\t `pages[].sidebar.show: false`. Default content: when\n\t\t\t `cnPageSidebarComponent.value` is set (provided by\n\t\t\t `CnPageRenderer` for `pages[].sidebarComponent`), that\n\t\t\t component renders here; otherwise empty.\n\n\t\t\t Consumer-supplied slot content wins over the resolved\n\t\t\t component, because Vue only falls back when the slot is\n\t\t\t ABSENT. An app that fills this slot unconditionally therefore\n\t\t\t SUPPRESSES `pages[].sidebarComponent` silently: no warning,\n\t\t\t no error, just no sidebar. That is why the resolved component\n\t\t\t is exposed as the `pageSidebarComponent` slot prop. An app\n\t\t\t with its own rail should render both:\n\n\t\t\t <template #sidebar=\"{ pageSidebarComponent }\">\n\t\t\t <MyOwnSidebar />\n\t\t\t <component :is=\"pageSidebarComponent\" v-if=\"pageSidebarComponent\" />\n\t\t\t </template>\n\t\t\t-->\n\t\t\t<!-- eslint-disable-next-line vue/attribute-hyphenation -- on a <slot>, the attribute IS the scoped-slot prop's key: hyphenating it would rename `pageSidebarComponent` for every consumer destructuring this slot -->\n\t\t\t<slot v-if=\"cnPageSidebarVisible.value !== false\" name=\"sidebar\" :pageSidebarComponent=\"pageSidebarComponent\">\n\t\t\t\t<component\n\t\t\t\t\t:is=\"pageSidebarComponent\"\n\t\t\t\t\tv-if=\"pageSidebarComponent\" />\n\t\t\t</slot>\n\t\t\t<!--\n\t\t\t Hoisted index-page sidebar. CnIndexPage publishes its\n\t\t\t embedded CnIndexSidebar config (component + props +\n\t\t\t listeners) into the `cnIndexSidebarConfig` holder so it\n\t\t\t mounts at NcContent level — the only place where Nextcloud's\n\t\t\t NcAppSidebar slides correctly from the right. Rendering\n\t\t\t alongside the consumer's `#sidebar` slot is safe because\n\t\t\t the embedded sidebar only sets the holder when the page is\n\t\t\t an index AND `sidebar.enabled !== false`; detail-page\n\t\t\t sidebars (CnObjectSidebar) keep owning the slot.\n\t\t\t-->\n\t\t\t<component\n\t\t\t\t:is=\"cnIndexSidebarConfig.value.component\"\n\t\t\t\tv-if=\"cnIndexSidebarConfig.value\"\n\t\t\t\tv-bind=\"cnIndexSidebarConfig.value.props\"\n\t\t\t\tv-on=\"cnIndexSidebarConfig.value.listeners\" />\n\n\t\t\t<!--\n\t\t\t Hoisted object-sidebar. CnDetailPage writes into the\n\t\t\t provided `objectSidebarState` holder to publish its\n\t\t\t schema-driven sidebar (Files / Notes / Tags / Tasks /\n\t\t\t Audit) at NcContent level — same ADR-017 reason as the\n\t\t\t hoisted index sidebar above. The auto-mount is suppressed\n\t\t\t when:\n\t\t\t - the consumer fills the `#sidebar` slot (their sidebar\n\t\t\t keeps owning the slot); or\n\t\t\t - an ancestor already provides `objectSidebarState` (the\n\t\t\t ancestor renders its own sidebar, e.g. decidesk's host\n\t\t\t wrapper); or\n\t\t\t - `objectType` + `objectId` are empty (defense-in-depth\n\t\t\t against CnIndexPage's `inject('sidebarState') ??\n\t\t\t inject('objectSidebarState')` fallback leaking an\n\t\t\t `active: true` write into this channel — see\n\t\t\t CnAppRootObjectSidebar.spec.js).\n\t\t\t-->\n\t\t\t<CnObjectSidebar\n\t\t\t\tv-if=\"shouldAutoMountObjectSidebar\"\n\t\t\t\t:open=\"effectiveObjectSidebarState.open === true\"\n\t\t\t\t:tabs=\"effectiveObjectSidebarState.tabs\"\n\t\t\t\t:useRegistry=\"objectSidebarUseRegistry\"\n\t\t\t\t:objectType=\"effectiveObjectSidebarState.objectType\"\n\t\t\t\t:objectId=\"effectiveObjectSidebarState.objectId\"\n\t\t\t\t:objectData=\"effectiveObjectSidebarState.object\"\n\t\t\t\t:objectSchema=\"effectiveObjectSidebarState.schemaObject\"\n\t\t\t\t:register=\"effectiveObjectSidebarState.register\"\n\t\t\t\t:schema=\"effectiveObjectSidebarState.schema\"\n\t\t\t\t:title=\"effectiveObjectSidebarState.title\"\n\t\t\t\t:subtitle=\"effectiveObjectSidebarState.subtitle\"\n\t\t\t\t:hiddenTabs=\"effectiveObjectSidebarState.hiddenTabs\"\n\t\t\t\t:requestedTab=\"effectiveObjectSidebarState.requestedTab\"\n\t\t\t\t@update:open=\"effectiveObjectSidebarState.open = $event\" />\n\n\t\t\t<!--\n\t\t\t AI Chat Companion — auto-mounted at the END of NcContent's\n\t\t\t children so its embedded NcAppSidebar slides in from the right\n\t\t\t edge (positioning relies on being the last NcContent sibling,\n\t\t\t same trick the hoisted index-page sidebar above uses).\n\t\t\t Gating (health probe, pageKind overrides) happens inside the\n\t\t\t component; app opt-in is via the `aiCompanion` prop (default off).\n\t\t\t-->\n\t\t\t<CnAiCompanion v-if=\"aiCompanion\" :chatAppId=\"chatAppId\" />\n\n\t\t\t<!--\n\t\t\t Non-gating setup wizard (REQ-SETUP-NV-012 optional path). Shown\n\t\t\t when every required setup step is met but an optional one isn't;\n\t\t\t auto-opens once per manifest `setup.version` and stays dismissible\n\t\t\t (Cancel/ESC/backdrop) — unlike the gating phase 2b instance above.\n\t\t\t-->\n\t\t\t<div v-if=\"setupWizardOpen\" class=\"cn-app-root__setup-optional\">\n\t\t\t\t<CnSetupWizard\n\t\t\t\t\t:appId=\"appId\"\n\t\t\t\t\t:appName=\"appDisplayName || (manifest && manifest.name) || appId\"\n\t\t\t\t\t:steps=\"manifest.setup.steps\"\n\t\t\t\t\t:cancellable=\"true\"\n\t\t\t\t\t:completedStepIds=\"setupCompletedStepIds\"\n\t\t\t\t\t@complete=\"onSetupComplete\"\n\t\t\t\t\t@close=\"dismissSetupWizard\" />\n\t\t\t</div>\n\n\t\t\t<!--\n\t\t\t Command palette (Ctrl/Cmd+K) — auto-mounted, opt-in via the\n\t\t\t `commandPalette` prop (default off). Zero-config navigation\n\t\t\t source from `manifest.menu`; the \"objects\" live-search source\n\t\t\t is wired by passing `commandPalette: { objectSearch: ... }`\n\t\t\t (see `createObjectSearchSource`). Actions register themselves\n\t\t\t via `useCommandPalette().register(...)` from anywhere in the\n\t\t\t app — no additional wiring here.\n\t\t\t-->\n\t\t\t<CnCommandPalette\n\t\t\t\tv-if=\"cnCommandPaletteVisible\"\n\t\t\t\t:manifest=\"manifest\"\n\t\t\t\t:router=\"$router\"\n\t\t\t\t:appId=\"appId\"\n\t\t\t\tv-bind=\"cnCommandPaletteOverrides\" />\n\n\t\t\t<!--\n\t\t\t Support note — auto-mounted on first open per the fleet\n\t\t\t support-dialog rollout. Deriving slug/name/URLs from `appId`\n\t\t\t by convention means apps gain it on a lib bump with no\n\t\t\t per-app wiring; pass `:support-dialog=\"false\"` to opt out or\n\t\t\t an object to override copy/URLs. Persistence is per-user\n\t\t\t (server preferences endpoint) with a localStorage fallback.\n\t\t\t-->\n\t\t\t<!--\n\t\t\t Waits for the setup status: until it loads the shell renders\n\t\t\t provisionally, and a required unmet step then swaps it for the\n\t\t\t wizard, unmounting the dialog mid-transition (NcModal's focus trap\n\t\t\t then throws on its missing mask).\n\t\t\t-->\n\t\t\t<CnSupportDialog\n\t\t\t\tv-if=\"cnSupportVisible && setupStatusSettled\"\n\t\t\t\t:appName=\"cnSupportAppName\"\n\t\t\t\t:appSlug=\"appId\"\n\t\t\t\t:appStoreUrl=\"cnSupportAppStoreUrl\"\n\t\t\t\t:featureRequestUrl=\"cnSupportFeatureRequestUrl\"\n\t\t\t\tv-bind=\"cnSupportOverrides\"\n\t\t\t\t@close=\"cnSupportHide\" />\n\t\t\t<!--\n\t\t\t Product walkthrough (ADR-043) — a non-gating spotlight tour\n\t\t\t auto-mounted over the live shell. Reads `manifest.walkthrough` and\n\t\t\t auto-starts a tour that qualifies for the user's app version. No\n\t\t\t per-app wiring; declare a `walkthrough` block to opt in.\n\t\t\t-->\n\t\t\t<!--\n\t\t\t Gated on `walkthroughSeenResolved` as well: when the manifest\n\t\t\t declares `walkthrough.completionConfigKey`, the per-user\n\t\t\t preference is fetched first so a returning user never sees the\n\t\t\t tour flash open before the answer arrives. Without a key the\n\t\t\t flag is already true at data() time (localStorage-only, sync).\n\n\t\t\t Also withheld while the first-open support note is on screen\n\t\t\t (`cnSupportVisible`): a fresh user qualifies for BOTH, and two\n\t\t\t stacked overlays fight for the same first moment. The tour's\n\t\t\t machine state lives in the per-app useWalkthrough cache, so\n\t\t\t unmounting here only hides the overlay — when the note is\n\t\t\t dismissed the walkthrough remounts and the first-visit tour\n\t\t\t starts (or resumes) then. `!== true` keeps apps that opted out\n\t\t\t of the support note (`cnSupportVisible` undefined) unaffected.\n\t\t\t-->\n\t\t\t<!-- @slot walkthrough Override the gating-free walkthrough overlay. Scope: { manifest, seenVersion }. -->\n\t\t\t<slot v-if=\"walkthroughEnabled && walkthroughSeenResolved && cnSupportVisible !== true\"\n\t\t\t\tname=\"walkthrough\"\n\t\t\t\t:manifest=\"manifest\"\n\t\t\t\t:seenVersion=\"walkthroughSeenVersion\">\n\t\t\t\t<CnWalkthrough\n\t\t\t\t\t:appId=\"appId\"\n\t\t\t\t\t:manifest=\"manifest\"\n\t\t\t\t\t:seenVersion=\"walkthroughSeenVersion\"\n\t\t\t\t\t:resume=\"walkthroughResume\"\n\t\t\t\t\t:translate=\"translate\"\n\t\t\t\t\t@complete=\"onWalkthroughComplete\"\n\t\t\t\t\t@dismiss=\"onWalkthroughComplete\" />\n\t\t\t</slot>\n\t\t\t<!--\n\t\t\t User-settings modal. Always mounted so descendants can\n\t\t\t open it via the `cnOpenUserSettings` inject (CnAppNav\n\t\t\t wires this to manifest entries with\n\t\t\t `action: \"user-settings\"`). The `#user-settings` slot\n\t\t\t hosts NcAppSettingsSection children; the placeholder\n\t\t\t fallback below renders when no slot content is supplied.\n\t\t\t-->\n\t\t\t<NcAppSettingsDialog\n\t\t\t\t:open=\"userSettingsOpen\"\n\t\t\t\t:showNavigation=\"true\"\n\t\t\t\t:name=\"resolvedUserSettingsTitle\"\n\t\t\t\t@update:open=\"userSettingsOpen = $event\">\n\t\t\t\t<!-- @slot user-settings Sections rendered inside the host NcAppSettingsDialog. Pass NcAppSettingsSection children. Defaults to the notification-preferences pane when omitted. -->\n\t\t\t\t<slot name=\"user-settings\">\n\t\t\t\t\t<CnNotificationPreferences v-if=\"userSettingsOpen\" />\n\t\t\t\t\t<!--\n\t\t\t\t\t\tCredential broker (OpenRegister). Lets the user manage the\n\t\t\t\t\t\tsecrets OR holds on their behalf; apps call external providers\n\t\t\t\t\t\tthrough OR without ever seeing the secret. The app's manifest\n\t\t\t\t\t\t`credentials[]` declarations drive the informational \"Apps\n\t\t\t\t\t\trequesting credentials\" list.\n\t\t\t\t\t-->\n\t\t\t\t\t<NcAppSettingsSection v-if=\"userSettingsOpen\"\n\t\t\t\t\t\tid=\"credentials\"\n\t\t\t\t\t\t:name=\"translate('Credentials')\">\n\t\t\t\t\t\t<CnCredentials\n\t\t\t\t\t\t\tscope=\"personal\"\n\t\t\t\t\t\t\t:appId=\"appId\"\n\t\t\t\t\t\t\t:appName=\"appDisplayName || (manifest && manifest.name) || appId\"\n\t\t\t\t\t\t\t:appCredentials=\"(manifest && manifest.credentials) || []\" />\n\t\t\t\t\t</NcAppSettingsSection>\n\t\t\t\t\t<!--\n\t\t\t\t\t\tSelf-service walkthrough replay (ADR-043). Only mounts\n\t\t\t\t\t\twhen the manifest declares an enabled tour, so apps\n\t\t\t\t\t\twithout a walkthrough never show an empty section.\n\t\t\t\t\t-->\n\t\t\t\t\t<NcAppSettingsSection v-if=\"walkthroughEnabled\"\n\t\t\t\t\t\tid=\"cn-walkthrough\"\n\t\t\t\t\t\t:name=\"restartWalkthroughSectionName\">\n\t\t\t\t\t\t<p class=\"cn-app-root__walkthrough-hint\">\n\t\t\t\t\t\t\t{{ restartWalkthroughHint }}\n\t\t\t\t\t\t</p>\n\t\t\t\t\t\t<NcButton variant=\"secondary\" @click=\"restartWalkthroughFromSettings\">\n\t\t\t\t\t\t\t<template #icon>\n\t\t\t\t\t\t\t\t<Restart :size=\"20\" />\n\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t{{ restartWalkthroughLabel }}\n\t\t\t\t\t\t</NcButton>\n\t\t\t\t\t</NcAppSettingsSection>\n\t\t\t\t</slot>\n\t\t\t\t<!--\n\t\t\t\t\tIntegrations (ADR-110) — the links that leave this app for\n\t\t\t\t\tanother one, gathered out of the navigation into one place.\n\n\t\t\t\t\tDELIBERATELY OUTSIDE the #user-settings slot. Six fleet apps\n\t\t\t\t\toverride that slot, and anything placed inside the default\n\t\t\t\t\tfallback disappears the moment an app supplies its own\n\t\t\t\t\tcontent — silently, because an unmatched slot renders nothing\n\t\t\t\t\tand reports nothing. A contract every app is supposed to\n\t\t\t\t\thonour cannot live somewhere six apps switch off by accident.\n\n\t\t\t\t\tRenders nothing when the app declares no integration\n\t\t\t\t\tentries, so apps without any never show an empty section.\n\t\t\t\t-->\n\t\t\t\t<NcAppSettingsSection v-if=\"userSettingsOpen && integrationEntries.length\"\n\t\t\t\t\tid=\"cn-integrations\"\n\t\t\t\t\t:name=\"translate('Integrations')\">\n\t\t\t\t\t<p class=\"cn-app-root__integrations-hint\">\n\t\t\t\t\t\t{{ translate('These open in another app.') }}\n\t\t\t\t\t</p>\n\t\t\t\t\t<ul class=\"cn-app-root__integrations\">\n\t\t\t\t\t\t<li v-for=\"entry in integrationEntries\" :key=\"entry.id\">\n\t\t\t\t\t\t\t<!--\n\t\t\t\t\t\t\t\tOne uniform external-link icon rather than the\n\t\t\t\t\t\t\t\tentry's own: every row here goes to a different\n\t\t\t\t\t\t\t\tapp, which is the thing worth signalling, and\n\t\t\t\t\t\t\t\tCnIcon falls back to a question mark for any\n\t\t\t\t\t\t\t\tname an app has not registered — a broken-looking\n\t\t\t\t\t\t\t\tglyph on a link that works fine.\n\t\t\t\t\t\t\t-->\n\t\t\t\t\t\t\t<NcButton variant=\"tertiary\"\n\t\t\t\t\t\t\t\t:href=\"entry.href\"\n\t\t\t\t\t\t\t\t:aria-label=\"entry.label\">\n\t\t\t\t\t\t\t\t<template #icon>\n\t\t\t\t\t\t\t\t\t<OpenInNew :size=\"20\" />\n\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t\t{{ entry.label }}\n\t\t\t\t\t\t\t</NcButton>\n\t\t\t\t\t\t</li>\n\t\t\t\t\t</ul>\n\t\t\t\t</NcAppSettingsSection>\n\t\t\t</NcAppSettingsDialog>\n\n\t\t\t<!--\n\t\t\t ADR-079 Step 2: the generic admin-settings modal has been REMOVED.\n\n\t\t\t It rendered `manifest.adminSettings[]` behind an app-OWNERSHIP gate.\n\t\t\t No app in the fleet ever declared that array, so the surface was\n\t\t\t unreachable everywhere — and its one real payload, the organisation\n\t\t\t credential broker, was unreachable with it. The broker now lives on\n\t\t\t the app's Nextcloud admin page via CnAdminSettingsShell's\n\t\t\t `show-organisation-credentials` prop, where the access decision is\n\t\t\t made SERVER-SIDE for /settings/admin/<app> rather than by a\n\t\t\t client-side ownership flag.\n\t\t\t-->\n\n\t\t\t<!--\n\t\t\t V2 registry modal — mounted when cnOpenModal(key, props) is\n\t\t\t called by the actions dispatcher. The resolved component is\n\t\t\t whatever was registered under that key in the `registry` prop.\n\t\t\t Closes by setting activeModalKey to null.\n\t\t\t-->\n\t\t\t<component\n\t\t\t\t:is=\"activeModalComponent\"\n\t\t\t\tv-if=\"activeModalComponent\"\n\t\t\t\tv-bind=\"activeModalProps\"\n\t\t\t\t@close=\"activeModalKey = null\"\n\t\t\t\t@update:open=\"activeModalKey = null\" />\n\t\t</template>\n\t</NcContent>\n</template>\n\n<script>\nimport { getCurrentUser } from '@nextcloud/auth'\nimport axios from '@nextcloud/axios'\nimport { loadState } from '@nextcloud/initial-state'\nimport { generateUrl } from '@nextcloud/router'\nimport { NcAppContent, NcAppSettingsDialog, NcAppSettingsSection, NcButton, NcContent, NcEmptyContent, NcLoadingIcon, NcNoteCard } from '@nextcloud/vue'\nimport { computed, reactive, shallowRef, watch } from 'vue'\nimport DatabaseSearchOutline from 'vue-material-design-icons/DatabaseSearchOutline.vue'\nimport OpenInNew from 'vue-material-design-icons/OpenInNew.vue'\nimport Restart from 'vue-material-design-icons/Restart.vue'\nimport CnAiCompanion from '../CnAiCompanion/CnAiCompanion.vue'\nimport CnAppLoading from '../CnAppLoading/CnAppLoading.vue'\nimport CnAppNav from '../CnAppNav/CnAppNav.vue'\nimport CnCommandPalette from '../CnCommandPalette/CnCommandPalette.vue'\nimport CnCredentials from '../CnCredentials/CnCredentials.vue'\nimport CnDependencyMissing from '../CnDependencyMissing/CnDependencyMissing.vue'\nimport CnNotificationPreferences from '../CnNotificationPreferences/CnNotificationPreferences.vue'\nimport CnObjectSidebar from '../CnObjectSidebar/CnObjectSidebar.vue'\nimport CnSetupWizard from '../CnSetupWizard/CnSetupWizard.vue'\nimport CnSupportDialog from '../CnSupportDialog/CnSupportDialog.vue'\nimport CnTenantBadge from '../CnTenantBadge/CnTenantBadge.vue'\nimport CnWalkthrough from '../CnWalkthrough/CnWalkthrough.vue'\nimport { DEFAULT_CHAT_APP_ID } from '../../composables/aiChatConfig.js'\nimport { useAppInstaller } from '../../composables/useAppInstaller.js'\nimport { useAppStatus } from '../../composables/useAppStatus.js'\nimport { useBuildiqEditAvailability } from '../../composables/useBuildiqEditAvailability.js'\nimport { useManifestEditor } from '../../composables/useManifestEditor.js'\nimport { useScopedTheme } from '../../composables/useScopedTheme.js'\nimport { useSetupStatus } from '../../composables/useSetupStatus.js'\nimport { useSupportDialog } from '../../composables/useSupportDialog.js'\nimport { provideTenantContext } from '../../composables/useTenantContext.js'\nimport { useUserPreferences } from '../../composables/useUserPreferences.js'\nimport {\n\tloadWalkthroughSeenVersion,\n\tnormaliseSeenVersion,\n\tpersistWalkthroughSeenVersion,\n\treadLocalWalkthroughSeenVersion,\n\tuseWalkthrough,\n} from '../../composables/useWalkthrough.js'\nimport { RegistryKindError } from '../../errors/RegistryKindError.js'\nimport { useObjectStore } from '../../store/index.js'\nimport { isAppInstalled } from '../../utils/appInstalled.js'\nimport { BUILT_IN_FORMATTERS } from '../../utils/builtInFormatters.js'\nimport { DEFAULT_FORGE, resolveForge } from '../../utils/forge.js'\nimport { BUILT_IN_KB_PROVIDERS } from '../../utils/kbSearchProviders.js'\nimport { installModalStack, uninstallModalStack } from '../../utils/modalStack.js'\nimport { passesContextPredicates } from '../../utils/visibleIfContext.js'\n\n/**\n * Recognised registry kinds and their required metadata fields.\n * An empty array means no additional fields are required beyond `component`.\n */\nconst REGISTRY_KIND_REQUIRED_FIELDS = {\n\twidget: ['defaultSize', 'minSize', 'maxSize', 'allowedSlots', 'propsSchema'],\n\tmodal: ['propsSchema'],\n\tpage: [],\n\t'form-field': ['appliesTo'],\n\t'cell-renderer': ['appliesTo'],\n\t// Slot-component kinds: a registered component mounted into a named page\n\t// slot (CnPageRenderer resolves these by registry name, independent of\n\t// `kind`). `header`/`actions` back the `headerComponent`/`actionsComponent`\n\t// manifest sugar; `tab` backs `config.sidebarTabs[].component`; `section`\n\t// backs `config.bodyWidgets[].component` (rendered into a `section:*` slot).\n\t// They carry no required metadata (like `page`) — listing them here keeps the\n\t// mount-time registry validator from rejecting a valid slot registration.\n\theader: [],\n\tactions: [],\n\ttab: [],\n\t// In-body section component (CnDetailPage `config.bodyWidgets[].component`,\n\t// reusable by dashboard/index). Resolved by registry name and rendered as a\n\t// titled card IN THE PAGE BODY with the object/page context injected. Unlike\n\t// an integration `widget`, a `section` requires NO sidebar tab and carries no\n\t// grid metadata — it sits wherever the page's `placement` puts it.\n\tsection: [],\n\t// Named behaviour: a plain function (exposed as `.handler` / `.fn`) that a\n\t// manifest names from `actions[].handler`, `bulkActions[].handler` or\n\t// `headerActions[].handler`. Resolved by name through\n\t// `resolveRegisteredHandler`, never mounted, so it carries no component and\n\t// no metadata — the registry home for what used to live in the legacy\n\t// `customComponents` map as a bare function.\n\thandler: [],\n\t// Create-override handler: a plain async function (exposed as `.handler` /\n\t// `.fn`) that CnPageRenderer resolves for CnIndexPage's `createOverride`\n\t// prop so a declarative `type:\"index\"` page can route its generic Add\n\t// through an app-specific create flow. Carries no component/metadata — it is\n\t// resolved by name, not mounted — so it lists no required fields (like\n\t// `page`); listing it here keeps the mount-time validator from rejecting a\n\t// valid handler registration.\n\t'create-override': [],\n}\n\nconst KNOWN_REGISTRY_KINDS = Object.keys(REGISTRY_KIND_REQUIRED_FIELDS)\n\n/**\n * Default URL for the OpenRegister integration page. The empty-state\n * action links here so users can install / enable OpenRegister with one\n * click. Override per-environment by replacing the default empty-state\n * via the `#or-missing` slot.\n */\nconst OR_STORE_LINK = '/index.php/settings/apps/integration/openregister'\n\nexport default {\n\tname: 'CnAppRoot',\n\n\tcomponents: {\n\t\tNcAppContent,\n\t\tNcAppSettingsDialog,\n\t\tNcAppSettingsSection,\n\t\tNcButton,\n\t\tNcContent,\n\t\tNcEmptyContent,\n\t\tNcLoadingIcon,\n\t\tNcNoteCard,\n\t\tDatabaseSearchOutline,\n\t\tOpenInNew,\n\t\tRestart,\n\t\tCnAppNav,\n\t\tCnAppLoading,\n\t\tCnDependencyMissing,\n\t\tCnSetupWizard,\n\t\tCnWalkthrough,\n\t\tCnAiCompanion,\n\t\tCnCommandPalette,\n\t\tCnObjectSidebar,\n\t\tCnSupportDialog,\n\t\tCnNotificationPreferences,\n\t\tCnCredentials,\n\t\tCnTenantBadge,\n\t},\n\n\t/**\n\t * What every descendant of this app shell can reach: the manifest,\n\t * the registries, and this person's own preferences.\n\t *\n\t * @spec openspec/changes/case-page-and-list-as-a-place/specs/index-page/spec.md\n\t */\n\tprovide() {\n\t\t// `self` is load-bearing: the returned object exposes `cnManifest` as a\n\t\t// GETTER, and inside a getter on that literal `this` is the literal —\n\t\t// not the component. A getter is what keeps the provide reactive, and a\n\t\t// getter cannot be an arrow function, so the alias is the only way to\n\t\t// reach the instance from inside it.\n\t\t// eslint-disable-next-line @typescript-eslint/no-this-alias\n\t\tconst self = this\n\t\treturn {\n\t\t\t// In-app editing (ADR-041): descendants read the editor's `source`\n\t\t\t// — the working copy while editing, the live manifest otherwise. A\n\t\t\t// getter so it stays reactive despite provide() running once; when\n\t\t\t// not editing it returns the live manifest, identical to before.\n\t\t\tget cnManifest() {\n\t\t\t\treturn self.manifestEditor ? self.manifestEditor.source.value : self.manifest\n\t\t\t},\n\n\t\t\t// The per-user preference reader and writer, so any descendant can\n\t\t\t// hold something against THIS person rather than against the\n\t\t\t// records. A getter for the same reason as cnManifest above: the\n\t\t\t// group is built from the manifest's `personalisation` block, and\n\t\t\t// provide() runs once while the manifest arrives later.\n\t\t\tget cnUserPreferences() {\n\t\t\t\treturn self.userPreferences\n\t\t\t},\n\n\t\t\t// The same manifest as a REF. The getter above is NOT enough on its\n\t\t\t// own: Options-API `inject` resolves a provided value once, at the\n\t\t\t// descendant's creation, so a renderer created before edit mode gets\n\t\t\t// the pre-edit manifest and never re-derives from an in-app edit —\n\t\t\t// which is why adding a widget to a page that had none appeared to do\n\t\t\t// nothing. `inject` unwraps a ref into a reactive getter instead.\n\t\t\tcnManifestSource: this.manifestEditor ? this.manifestEditor.source : null,\n\t\t\tcnManifestEditor: this.manifestEditor,\n\t\t\t// App registers/schemas for the in-app pages editor (index/detail\n\t\t\t// data source). Plain value (not a getter) so deep descendants —\n\t\t\t// the page-tree rows under the edit button — resolve it reliably.\n\t\t\t// Being a plain value is also why it goes stale: provide() runs\n\t\t\t// once, so this can never reflect a schema created after boot.\n\t\t\t// Kept as-is for backwards compatibility; `cnDataSourcesState`\n\t\t\t// below is the live path, and descendants prefer it.\n\t\t\tcnDataSources: this.dataSources,\n\t\t\t// Live data sources for the pages editor. Provided BY REFERENCE —\n\t\t\t// the holder's identity never changes, only its fields — so the\n\t\t\t// one-shot provide() still sees every update. Descendants resolve\n\t\t\t// `cnDataSourcesState.value ?? cnDataSources`.\n\t\t\tcnDataSourcesState: this.dataSourcesState,\n\t\t\t// Re-fetch the data sources via `dataSourcesLoader`. The pages-editor\n\t\t\t// modals call this on open. No-op when no loader is configured.\n\t\t\tcnRefreshDataSources: this.refreshDataSources,\n\t\t\t// Provided as the raw refs (not getters): Vue 2 inject resolves plain\n\t\t\t// provided properties at any depth, but getter-defined provide\n\t\t\t// properties don't reliably reach deep descendants (e.g. the edit\n\t\t\t// button under a page component). Descendants unwrap with `.value`.\n\t\t\t// The inject KEY keeps its `cnOpenBuildAvailable` spelling on purpose:\n\t\t\t// consumer apps may already inject it, so the 2026-08-21 OpenBuild →\n\t\t\t// Buildiq rename deliberately left this runtime contract untouched.\n\t\t\tcnOpenBuildAvailable: this.buildiqAvailable,\n\t\t\tcnEditingBody: this.manifestEditor ? this.manifestEditor.editing : false,\n\t\t\t// Page-level permission enforcement. The manifest schema has carried\n\t\t\t// `pages[].permission` as SCHEMA-ONLY since it was added — \"consumers\n\t\t\t// that want enforcement filter the manifest themselves\" — and no\n\t\t\t// consumer did, so a page declaring it was hidden from the menu and\n\t\t\t// served to anyone who typed its URL. dossiq's Integrations page\n\t\t\t// answered a non-admin with seven links into admin settings.\n\t\t\t//\n\t\t\t// A getter, so it tracks the prop rather than freezing at the single\n\t\t\t// provide() call, and normalised to an array here so every descendant\n\t\t\t// reads one shape.\n\t\t\tget cnPermissions() {\n\t\t\t\treturn Array.isArray(self.permissions) ? self.permissions : []\n\t\t\t},\n\n\t\t\tcnCustomComponents: this.customComponents,\n\t\t\tcnTranslate: this.translate,\n\t\t\tcnPageTypes: this.pageTypes,\n\t\t\tcnFormatters: { ...BUILT_IN_FORMATTERS, ...this.formatters },\n\t\t\tcnCellWidgets: this.cellWidgets,\n\t\t\t// Pluggable kb-search providers (#91 Wave 3): library built-ins\n\t\t\t// (`default`) merged UNDER the consumer registry — the same\n\t\t\t// last-wins spread as cnFormatters. CnKbSearchWidget resolves\n\t\t\t// `content.provider` against this.\n\t\t\tcnKbSearchProviders: { ...BUILT_IN_KB_PROVIDERS, ...this.kbSearchProviders },\n\t\t\t/**\n\t\t\t * V2 component registry. Provided to all descendants so\n\t\t\t * CnWidgetGrid and CnPageRenderer can resolve widget keys.\n\t\t\t * The registry prop is passed by reference — mutations\n\t\t\t * after mount are NOT tracked; consumers should mount with\n\t\t\t * the complete registry.\n\t\t\t */\n\t\t\tcnRegistry: this.registry,\n\t\t\t/**\n\t\t\t * Open a modal registered in the v2 registry. Used by\n\t\t\t * the actions dispatcher to open modals declared in the\n\t\t\t * manifest's `actions[]` array. Validates `kind === \"modal\"`\n\t\t\t * before delegating to the `cnModalKey` reactive holder.\n\t\t\t *\n\t\t\t * @param {string} key The registry key of the modal to open.\n\t\t\t * @param {object} props Props forwarded to the modal component.\n\t\t\t */\n\t\t\tcnOpenModal: (key, props = {}) => {\n\t\t\t\tconst entry = this.registry[key]\n\t\t\t\tif (!entry || entry.kind !== 'modal') {\n\t\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\t\tconsole.warn(`[CnAppRoot] cnOpenModal: \"${key}\" is not a registered modal (kind must be \"modal\").`)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tthis.activeModalKey = key\n\t\t\t\tthis.activeModalProps = props\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * Open the host app's NcAppSettingsDialog. Bound to\n\t\t\t * `this` so descendants don't have to. Used by CnAppNav\n\t\t\t * to dispatch `action: \"user-settings\"` clicks; consumer\n\t\t\t * apps can also call it directly via inject for custom\n\t\t\t * triggers (e.g. an avatar-menu entry).\n\t\t\t */\n\t\t\tcnOpenUserSettings: () => {\n\t\t\t\tthis.userSettingsOpen = true\n\t\t\t},\n\t\t\t/**\n\t\t\t * Open the host app's admin-settings NcAppSettingsDialog —\n\t\t\t * the app-level (not per-user) surface introduced to hold\n\t\t\t * the organisation credential broker out of the personal\n\t\t\t * settings modal. Bound to `this` so descendants don't have\n\t\t\t * to. Used by CnAppNav to dispatch the auto-prepended \"Admin\n\t\t\t * settings\" entry (admins only) and `action:\n\t\t\t * \"admin-settings\"` manifest entries; consumer apps can also\n\t\t\t * call it directly via inject for custom triggers.\n\t\t\t */\n\n\t\t\t/**\n\t\t\t * Restart entry for the product walkthrough (ADR-043). Descendants\n\t\t\t * (a menu/settings \"Replay walkthrough\" entry, or a manifest menu\n\t\t\t * `action: \"replay-walkthrough\"`) call this to re-run a tour. With no\n\t\t\t * `tourId` the first declared tour is used.\n\t\t\t *\n\t\t\t * @param {string} [tourId] The tour to restart.\n\t\t\t * @return {void}\n\t\t\t */\n\t\t\tcnReplayWalkthrough: (tourId) => {\n\t\t\t\tif (!this.walkthroughEnabled) {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tconst wt = useWalkthrough(this.appId, this.manifest)\n\t\t\t\tconst id = tourId || (this.manifest.walkthrough.tours[0] && this.manifest.walkthrough.tours[0].id)\n\t\t\t\tif (id) {\n\t\t\t\t\twt.restart(id)\n\t\t\t\t}\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * Reactive AI context holder. Page components (CnIndexPage,\n\t\t\t * CnDetailPage, CnDashboardPage) overwrite fields on this object\n\t\t\t * in created() and watch() so the widget sees live context.\n\t\t\t * The same object reference is stable for the lifetime of CnAppRoot.\n\t\t\t */\n\t\t\tcnAiContext: this.cnAiContext,\n\t\t\t/**\n\t\t\t * Reactive holder that descendants — specifically\n\t\t\t * CnIndexPage — write to in order to mount their embedded\n\t\t\t * sidebar at NcContent level. The Vue 2 reactive idiom is\n\t\t\t * `{ value }` so descendants assign `holder.value = config`.\n\t\t\t * `config` is `{ component, props, listeners }`.\n\t\t\t *\n\t\t\t * Default null. CnIndexPage clears it on unmount so the\n\t\t\t * hoisted sidebar disappears when the user navigates away.\n\t\t\t */\n\t\t\tcnIndexSidebarConfig: this.cnIndexSidebarConfig,\n\t\t\t/**\n\t\t\t * Sentinel that CnIndexPage checks to decide whether to\n\t\t\t * publish its embedded sidebar to the hoist (true) or\n\t\t\t * render it inline (false, default for non-CnAppRoot\n\t\t\t * hosts).\n\t\t\t */\n\t\t\tcnHostsIndexSidebar: true,\n\t\t\t/**\n\t\t\t * Consuming app's slug (e.g. \"pipelinq\"). Mirrors the `appId`\n\t\t\t * prop, so descendants (the Actions menus, the forge deep-link\n\t\t\t * builders) know which app they act for without per-widget\n\t\t\t * wiring.\n\t\t\t */\n\t\t\tcnAppId: this.appId,\n\t\t\t/**\n\t\t\t * Target repo slug for the in-product feature-request deep\n\t\t\t * link (e.g. `ConductionNL/pipelinq`). Read from the\n\t\t\t * manifest's `nav.featureRequestRepo` when set; falls back\n\t\t\t * to `ConductionNL/<appId>` which is the convention for\n\t\t\t * every Conduction app on GitHub.\n\t\t\t */\n\t\t\tcnFeatureRequestRepo: this.resolvedFeatureRequestRepo,\n\t\t\t/**\n\t\t\t * Forge config (`{type, baseUrl}`) for the in-product\n\t\t\t * feature-request deep link. Read from the manifest's\n\t\t\t * `nav.forge` (merged over the Codeberg default). Switching\n\t\t\t * the fleet's forge — back to GitHub, or onto a self-hosted\n\t\t\t * Forgejo/Gitea — is just this one manifest field.\n\t\t\t */\n\t\t\tcnFeatureRequestForge: this.resolvedFeatureRequestForge,\n\t\t\t/**\n\t\t\t * Object-sidebar channel — reactive holder that\n\t\t\t * `CnDetailPage` writes to publish its schema-driven\n\t\t\t * sidebar to the NcContent-level auto-mount above.\n\t\t\t * Always exposed (even when an ancestor provides its\n\t\t\t * own) so descendants under THIS CnAppRoot see a\n\t\t\t * consistent inject; the auto-mount itself defers to\n\t\t\t * the ancestor via `ancestorObjectSidebarState`.\n\t\t\t *\n\t\t\t * Shape mirrors what CnDetailPage.syncSidebarState\n\t\t\t * writes — `{ active, open, objectType, objectId,\n\t\t\t * title, subtitle, register, schema, hiddenTabs, tabs\n\t\t\t * }` — plus the always-truthy `_origin` marker so\n\t\t\t * tests can tell the two channels apart.\n\t\t\t *\n\t\t\t * When an ANCESTOR already provides `objectSidebarState`\n\t\t\t * (a host App shell that mounts its own CnObjectSidebar in\n\t\t\t * the `#sidebar` slot — decidesk / procest / openregister),\n\t\t\t * we re-provide THAT holder rather than our local one.\n\t\t\t * Otherwise the descendant CnDetailPage (a deep child of\n\t\t\t * this CnAppRoot via `<router-view>`) would inject our\n\t\t\t * local holder and write the published tab strip there,\n\t\t\t * while the host's `#sidebar` slot — compiled in the\n\t\t\t * ancestor's render scope — reads the ancestor's holder.\n\t\t\t * The two never meet and the strip never renders. Sharing\n\t\t\t * the ancestor holder here keeps the write target and the\n\t\t\t * read target the same object.\n\t\t\t */\n\t\t\tobjectSidebarState: this.ancestorObjectSidebarState || this.localObjectSidebarState,\n\t\t\t/**\n\t\t\t * Index-sidebar channel — CnIndexPage's inject probes\n\t\t\t * `sidebarState` FIRST and falls back to\n\t\t\t * `objectSidebarState`. Providing a distinct holder\n\t\t\t * here keeps the two channels isolated so index-page\n\t\t\t * writes never leak into the object-sidebar\n\t\t\t * auto-mount (the openbuilt double-sidebar regression).\n\t\t\t * Shape covers the CnIndexPage write surface\n\t\t\t * (`searchValue`, `activeFilters`, `facetData`, etc.).\n\t\t\t */\n\t\t\tsidebarState: this.localIndexSidebarState,\n\t\t\t/**\n\t\t\t * Reactive `{ [register]: { [schema]: number } }` totals\n\t\t\t * populated by `_hydrateMenuCounts()` from `useObjectStore()`\n\t\t\t * for every `count: \"auto\"` menu entry whose resolved page is\n\t\t\t * `type: \"index\"` with `register`/`schema` in its config.\n\t\t\t *\n\t\t\t * `CnAppNav.resolveCount()` reads from this map to render\n\t\t\t * `NcCounterBubble` badges next to menu entries. The hydration\n\t\t\t * happens once at mount (one `?_limit=1` fetch per unique\n\t\t\t * `(register, schema)` pair); subsequent index-page mounts\n\t\t\t * reuse the same store entry so no extra round-trip.\n\t\t\t *\n\t\t\t * Defaults to an empty object so `resolveCount` returns\n\t\t\t * `null` (no badge) until hydration completes — which keeps\n\t\t\t * the navigation rendering immediately without waiting for\n\t\t\t * the counts.\n\t\t\t */\n\t\t\tcnMenuCounts: this.cnMenuCounts,\n\t\t}\n\t},\n\n\t/**\n\t * Inject the current page's sidebar-visibility flag and\n\t * sidebar-component override. The provider is `CnPageRenderer`\n\t * (a typical descendant via `<router-view>`).\n\t *\n\t * `cnPageSidebarVisible` default — used when no `CnPageRenderer`\n\t * ancestor exists (e.g. apps mounting their own page components\n\t * without the renderer) — is `{ value: true }` so the `#sidebar`\n\t * slot renders unchanged.\n\t *\n\t * `cnPageSidebarComponent` default is `{ value: null }` so the\n\t * slot's default content stays empty unless the manifest\n\t * explicitly opts in via `pages[].sidebarComponent`. Apps that\n\t * already provide a `#sidebar` slot override see no behaviour\n\t * change either way — the override wins over the slot default.\n\t *\n\t * The shape `{ value: T }` is a hand-rolled reactive holder\n\t * (Vue 2 options API) — see `CnPageRenderer.data()`.\n\t */\n\tinject: {\n\t\tcnPageSidebarVisible: { default: () => ({ value: true }) },\n\t\tcnPageSidebarComponent: { default: () => ({ value: null }) },\n\t\t/**\n\t\t * Ancestor-provided `objectSidebarState` — when set, an\n\t\t * ancestor (e.g. decidesk's host wrapper, procest's app\n\t\t * shell) owns the channel and renders its own\n\t\t * CnObjectSidebar. We defer to it by suppressing our local\n\t\t * auto-mount. Default `null` so a fresh CnAppRoot always\n\t\t * uses its own local holder.\n\t\t */\n\t\tancestorObjectSidebarState: { from: 'objectSidebarState', default: null },\n\t},\n\n\tprops: {\n\t\t/**\n\t\t * Reactive manifest object (from useAppManifest). The renderer\n\t\t * reads `manifest.dependencies`, `manifest.menu`, and is\n\t\t * propagated to descendants via provide/inject.\n\t\t *\n\t\t * @type {object}\n\t\t */\n\t\tmanifest: {\n\t\t\ttype: Object,\n\t\t\trequired: true,\n\t\t},\n\n\t\t/**\n\t\t * DEPRECATED (2.1.0) — render the in-shell orange soft-dependency\n\t\t * banners above the routed page. Off by default: they stacked one per\n\t\t * optional leaf and pushed the app's own content below the fold, for\n\t\t * an audience (end users) who cannot act on them. Mount\n\t\t * `CnLeafDependencySettings` in the app's admin settings instead — it\n\t\t * carries the same two states and the same install/enable action.\n\t\t * Set true only as a temporary bridge while adopting that section;\n\t\t * this prop is slated for removal.\n\t\t *\n\t\t * @type {boolean}\n\t\t */\n\t\tsoftDependencyNotices: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/**\n\t\t * Remount key for the routed `<router-view>`. Hosts that rebuild the\n\t\t * router at runtime (e.g. the Buildiq builder adding a page mid-edit)\n\t\t * bump this AFTER the rebuild so the view drops its stale component-\n\t\t * instance cache and mounts the new routes — a Vue Router 3 matcher swap\n\t\t * alone resolves the new hrefs but leaves SPA-navigation to a just-added\n\t\t * route rendering a blank view. Keep at the default for static apps: the\n\t\t * key is stable across ordinary navigation, so the view is never\n\t\t * needlessly remounted (and the shell / teleported modals are untouched).\n\t\t *\n\t\t * @type {string|number}\n\t\t */\n\t\trouterViewKey: {\n\t\t\ttype: [String, Number],\n\t\t\tdefault: 'cn-router-view',\n\t\t},\n\n\t\t/**\n\t\t * Optional persistence hook for in-app editing (ADR-041). Called with the\n\t\t * minimal manifest delta when the user saves an edit. When omitted, Save\n\t\t * still updates the rendered manifest in memory but persists nothing —\n\t\t * wire this to the Buildiq app-override endpoint to make edits durable.\n\t\t *\n\t\t * @type {((delta: object) => void|Promise<void>)|null}\n\t\t */\n\t\tpersistManifestDelta: {\n\t\t\ttype: Function,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/**\n\t\t * App data sources for the in-app pages editor (ADR-041). Lets the\n\t\t * Edit-pages modal offer Register / Schema / Columns dropdowns for\n\t\t * `index`/`detail` pages instead of free-text slug inputs, so a\n\t\t * created page actually renders a table. Shape: `{ registers:\n\t\t * [{ value, label, schemas: [{ value, label, columns: string[] }] }] }`.\n\t\t * Provided to descendants as `cnDataSources`; when omitted the editor\n\t\t * falls back to free-text register/schema fields.\n\t\t *\n\t\t * @type {object|null}\n\t\t */\n\t\tdataSources: {\n\t\t\ttype: Object,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/**\n\t\t * Async loader for the same data sources, re-invoked every time a\n\t\t * pages-editor modal opens — so a register or schema created after\n\t\t * app boot shows up without a page reload. Prefer this over the\n\t\t * static `dataSources` snapshot, which is captured once and cannot\n\t\t * change (`provide()` runs a single time).\n\t\t *\n\t\t * Signature: `async () => ({ registers: [...] })`, returning the\n\t\t * same shape as `dataSources`. Passing it also moves the fetch off\n\t\t * the app-boot path onto the (much rarer) editor-open path. When\n\t\t * both props are given, `dataSources` seeds the initial list and\n\t\t * the loader's result replaces it on the first refresh.\n\t\t *\n\t\t * @type {(() => Promise<{ registers: Array<object> }>)|null}\n\t\t */\n\t\tdataSourcesLoader: {\n\t\t\ttype: Function,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/**\n\t\t * Nextcloud app id. Forwarded to NcContent as `app-name` and\n\t\t * to CnDependencyMissing for the heading.\n\t\t *\n\t\t * @type {string}\n\t\t */\n\t\tappId: {\n\t\t\ttype: String,\n\t\t\trequired: true,\n\t\t},\n\n\t\t/**\n\t\t * Human-readable name shown in the Nextcloud top bar. When set it\n\t\t * overrides the technical `appId` so a virtual app shows its own name\n\t\t * (e.g. \"Pet Store\") instead of the host app id.\n\t\t */\n\t\tappDisplayName: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/**\n\t\t * First-open support note (`CnSupportDialog`). `true` (default)\n\t\t * auto-mounts it, deriving the app name and the App-Store /\n\t\t * feature-request URLs from `appId` by convention. Pass `false`\n\t\t * to opt out, or an object to override any `CnSupportDialog`\n\t\t * prop (e.g. `{ appName, appStoreUrl, featureRequestUrl,\n\t\t * donateUrl, founderName, … }`). Dismissal persists per-user via\n\t\t * the app's `/api/preferences/support-dialog-seen` endpoint, with\n\t\t * a localStorage fallback.\n\t\t *\n\t\t * @type {boolean|object}\n\t\t */\n\t\tsupportDialog: {\n\t\t\ttype: [Boolean, Object],\n\t\t\tdefault: true,\n\t\t},\n\n\t\t/**\n\t\t * Whether to mount the floating AI-chat companion (`CnAiCompanion`).\n\t\t * Opt-in: `false` (default) keeps the companion off; pass `true` to\n\t\t * show it. When enabled the companion still self-gates on its own\n\t\t * backend health probe and hides on chat pages. The companion is an\n\t\t * AI capability provided by the Hermiq app, so apps opt in explicitly\n\t\t * rather than every app auto-mounting it whenever a chat backend\n\t\t * happens to be reachable.\n\t\t *\n\t\t * @type {boolean}\n\t\t */\n\t\taiCompanion: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/**\n\t\t * Whether to mount the Ctrl/Cmd+K command palette (`CnCommandPalette`).\n\t\t * Opt-in: `false` (default) keeps it off, so existing apps are\n\t\t * unaffected until they enable it. Pass `true` for the zero-config\n\t\t * default (navigation from `manifest.menu` + any commands the app\n\t\t * registers via `useCommandPalette().register(...)`, no live\n\t\t * object search), or an object to override any `CnCommandPalette`\n\t\t * prop — most commonly `{ objectSearch: createObjectSearchSource({...}) }`\n\t\t * (see `src/utils/commandPaletteObjectSource.js`) to wire live\n\t\t * OpenRegister search into the palette's \"objects\" source.\n\t\t *\n\t\t * @type {boolean|object}\n\t\t */\n\t\tcommandPalette: {\n\t\t\ttype: [Boolean, Object],\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/**\n\t\t * Backend app id the AI Chat Companion targets for its chat / health /\n\t\t * conversation HTTP calls (`/index.php/apps/{chatAppId}/api/...`). This is\n\t\t * the single configuration point for switching the chat backend — see\n\t\t * composables/aiChatConfig.js. Defaults to `hermiq`.\n\t\t *\n\t\t * Per hydra ADR-034 \"Amendment 2026-07-05\" the agent engine moved from\n\t\t * OpenRegister to Hermiq and the default flipped to `hermiq`\n\t\t * (`chat-appid-default-flip`). Deployments riding OpenRegister's compat\n\t\t * window (openregister#305) can pass `chatAppId=\"openregister\"` explicitly.\n\t\t *\n\t\t * @type {string}\n\t\t */\n\t\tchatAppId: {\n\t\t\ttype: String,\n\t\t\tdefault: DEFAULT_CHAT_APP_ID,\n\t\t},\n\n\t\t/**\n\t\t * Whether the manifest is still loading from the backend.\n\t\t * Typically wired to `useAppManifest().isLoading`. Defaults to\n\t\t * false so that apps using only the bundled manifest skip the\n\t\t * loading phase.\n\t\t *\n\t\t * @type {boolean}\n\t\t */\n\t\tisLoading: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/**\n\t\t * Custom-component registry consumed by CnPageRenderer for\n\t\t * `type: \"custom\"` pages and slot overrides. Empty by default.\n\t\t *\n\t\t * @type {object}\n\t\t */\n\t\tcustomComponents: {\n\t\t\ttype: Object,\n\t\t\tdefault: () => ({}),\n\t\t},\n\n\t\t/**\n\t\t * Cell-formatter registry. Map of formatter-id →\n\t\t * `(value, row, property) => string|number`. Resolves the\n\t\t * `pages[].config.columns[].formatter` ids that index/logs pages\n\t\t * declare, so per-column value formatting (status-label maps,\n\t\t * \"days in step\", currency, …) lives in small pure data functions\n\t\t * instead of bespoke `type:\"custom\"` table views. Provided to\n\t\t * descendant CnDataTable / CnCellRenderer via inject (`cnFormatters`).\n\t\t * Empty by default — a column with no `formatter`, or an app that\n\t\t * passes no `formatters`, renders exactly as before.\n\t\t *\n\t\t * @type {object}\n\t\t */\n\t\tformatters: {\n\t\t\ttype: Object,\n\t\t\tdefault: () => ({}),\n\t\t},\n\n\t\t/**\n\t\t * Cell-widget registry. Map of widget-id → Vue component, rendered\n\t\t * for a column that declares `pages[].config.columns[].widget`. The\n\t\t * component receives `{ value, row, property, formatted, ...widgetProps }`.\n\t\t * The library ships one built-in id, `\"badge\"` (renders `CnStatusBadge`);\n\t\t * consumer entries cover everything else (status pills with custom\n\t\t * colour maps, inline toggles, link cells, …). Provided to descendant\n\t\t * `CnDataTable` / `CnCellRenderer` via inject (`cnCellWidgets`). Empty\n\t\t * by default — a column with no `widget` renders as before.\n\t\t *\n\t\t * @type {object}\n\t\t */\n\t\tcellWidgets: {\n\t\t\ttype: Object,\n\t\t\tdefault: () => ({}),\n\t\t},\n\n\t\t/**\n\t\t * Pluggable knowledge-base search providers (#91 Wave 3). Map of\n\t\t * provider-key → provider object (`{ search(query, opts), externalOpen? }`),\n\t\t * merged OVER the library built-ins (`default`) and provided to\n\t\t * descendant `CnKbSearchWidget` via inject (`cnKbSearchProviders`).\n\t\t * A `kb-search` widget selects its provider by `content.provider`;\n\t\t * an app talking to a bespoke KB backend (the xwiki proxy) registers\n\t\t * its client here — the library ships only the `default` endpoint\n\t\t * provider + the seam. Empty by default (the built-in `default`\n\t\t * provider then serves every `kb-search` widget).\n\t\t *\n\t\t * @type {object}\n\t\t */\n\t\tkbSearchProviders: {\n\t\t\ttype: Object,\n\t\t\tdefault: () => ({}),\n\t\t},\n\n\t\t/**\n\t\t * Translate function provided by the consuming app. The library\n\t\t * never imports `t()` from a specific app, so the consumer\n\t\t * passes its own translator. Typically a closure over the\n\t\t * Nextcloud `t()` mixin pre-bound to the app id, e.g.\n\t\t * `(key) => t(appId, key)`.\n\t\t *\n\t\t * Defaults to an identity function so untranslated keys surface\n\t\t * visibly rather than crashing.\n\t\t *\n\t\t * Note: the prop is named `translate` (not `t`) to avoid\n\t\t * shadowing the global `t()` method that Conduction apps\n\t\t * install via `Vue.mixin({ methods: { t, n } })`. The provide\n\t\t * key is `cnTranslate`.\n\t\t *\n\t\t * @type {(key: string) => string}\n\t\t */\n\t\ttranslate: {\n\t\t\ttype: Function,\n\t\t\tdefault: (key) => key,\n\t\t},\n\n\t\t/**\n\t\t * List of permission strings the current user holds. Forwarded\n\t\t * to CnAppNav's permission filter.\n\t\t *\n\t\t * @type {Array<string>}\n\t\t */\n\t\tpermissions: {\n\t\t\ttype: Array,\n\t\t\tdefault: () => [],\n\t\t},\n\n\t\t/**\n\t\t * Page-type registry. Map of `pages[].type` → Vue component.\n\t\t * Provided to descendant CnPageRenderer instances via inject.\n\t\t * When omitted, the renderer falls back to the library's\n\t\t * `defaultPageTypes`. Apps with custom page types pass a merged\n\t\t * map: `{ ...defaultPageTypes, report: MyReportPage }`.\n\t\t *\n\t\t * @type {object|null}\n\t\t */\n\t\tpageTypes: {\n\t\t\ttype: Object,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/**\n\t\t * Component registry for v2 manifests. Map of registry key →\n\t\t * `{ kind, component, ...kindMetadata }`. Provided to descendants\n\t\t * via Vue provide under key `cnRegistry`. Validated at `mounted()`\n\t\t * time — unknown `kind` throws `RegistryKindError`; missing required\n\t\t * kind-metadata emits `console.warn`.\n\t\t *\n\t\t * Recognised kinds: `widget`, `modal`, `page`, `form-field`,\n\t\t * `cell-renderer`, the slot-component kinds `header`, `actions`,\n\t\t * `tab`, `section` (mounted into named page slots), and the function\n\t\t * kinds `handler` (a manifest `actions[]` / `bulkActions[]` /\n\t\t * `headerActions[]` handler) and `create-override`. See spec\n\t\t * REQ-MVR-002.\n\t\t *\n\t\t * @type {object}\n\t\t */\n\t\tregistry: {\n\t\t\ttype: Object,\n\t\t\tdefault: () => ({}),\n\t\t},\n\n\t\t/**\n\t\t * Required Nextcloud apps for this Conduction app to function.\n\t\t * Default `['openregister']` — every fleet app stores its data\n\t\t * in OpenRegister, so the guard is on by default. Consumer apps\n\t\t * that don't need OpenRegister (the styleguide, the docs site,\n\t\t * future utility apps) opt out via `:requires-apps=\"[]\"`.\n\t\t *\n\t\t * On `mounted()`, CnAppRoot calls `getCapabilities()` from\n\t\t * `@nextcloud/capabilities` exactly once and compares the\n\t\t * returned capability keys against this list. When ANY entry\n\t\t * is missing, CnAppRoot renders an `<NcEmptyContent>` (the\n\t\t * default) or the consumer's `#or-missing` slot.\n\t\t *\n\t\t * Multi-app future-proofing free: a future docudesk-derived app\n\t\t * needing both can declare\n\t\t * `:requires-apps=\"['openregister', 'openconnector']\"`.\n\t\t *\n\t\t * Network failure on `getCapabilities()` (admin-restricted,\n\t\t * offline, CORS) falls through to the renderer rather than\n\t\t * blocking the app on a flaky check — the data layer surfaces\n\t\t * the actual failure when API calls hit OpenRegister.\n\t\t *\n\t\t * See REQ-OR-1..REQ-OR-7 of cnapproot-app-availability-guard.\n\t\t *\n\t\t * @type {Array<string>}\n\t\t */\n\t\trequiresApps: {\n\t\t\ttype: Array,\n\t\t\tdefault: () => ['openregister'],\n\t\t},\n\n\t\t/**\n\t\t * Title rendered at the top of the user-settings modal\n\t\t * (NcAppSettingsDialog `name` prop). Defaults to the\n\t\t * translated string \"User settings\"; pass a custom label\n\t\t * (e.g. \"Decidiq preferences\") to override per app.\n\t\t *\n\t\t * @type {string}\n\t\t */\n\t\tuserSettingsTitle: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/**\n\t\t * Title rendered at the top of the admin-settings modal\n\t\t * (NcAppSettingsDialog `name` prop). Defaults to the\n\t\t * translated string \"Administration\"; pass a custom label\n\t\t * (e.g. \"Pipelinq administration\") to override per app.\n\t\t *\n\t\t * @type {string}\n\t\t */\n\t\tadminSettingsTitle: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/**\n\t\t * Initial active organisation UUID (multi-tenancy-context). When\n\t\t * set, the provided `useTenantContext()` mounts with this UUID\n\t\t * already active so the first render stamps the right\n\t\t * `X-OpenRegister-Organisation` header and the top-bar\n\t\t * `CnTenantBadge` shows the right name immediately. Updates via\n\t\t * `useTenantContext().setActiveTenant()` from any descendant.\n\t\t *\n\t\t * @type {string|null}\n\t\t */\n\t\tinitialOrganisationUuid: {\n\t\t\ttype: String,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/**\n\t\t * Initial active organisation entity (multi-tenancy-context).\n\t\t * When set, surfaces the resolved name + slug for the badge\n\t\t * without a second fetch.\n\t\t *\n\t\t * @type {object|null}\n\t\t */\n\t\tinitialOrganisation: {\n\t\t\ttype: Object,\n\t\t\tdefault: null,\n\t\t},\n\t},\n\n\temits: ['setup-complete', 'walkthrough-complete'],\n\n\t/**\n\t * Component-instance state for the capabilities guard.\n\t *\n\t * - `capabilitiesLoading`: `true` only when the prop says we need\n\t * to check (i.e. `requiresApps.length > 0`). Apps that opt out\n\t * via `:requires-apps=\"[]\"` see this initialise to `false`, so\n\t * no spinner flashes and the renderer mounts on the first\n\t * render. Apps that need the guard see `true` initially; the\n\t * `mounted()` hook runs the check and flips to `false`.\n\t * - `missingApps`: the list of `requiresApps` entries NOT\n\t * present in the capabilities payload. When empty, the\n\t * renderer mounts; when non-empty, the empty-state renders.\n\t * - `guardError`: stores the caught error so consumers\n\t * inspecting the component instance can introspect failures.\n\t * The error path falls through to the renderer regardless.\n\t */\n\t/**\n\t * Auto-mount the first-open support note unless the host opted out\n\t * with `:support-dialog=\"false\"`. Per-user persistence via the app's\n\t * preferences endpoint (localStorage fallback inside the composable).\n\t * Returns no refs when disabled, so the `v-if=\"cnSupportVisible\"` in\n\t * the template stays false.\n\t *\n\t * @param {object} props Component props (reads `appId`, `supportDialog`).\n\t * @return {object} `{ cnSupportVisible, cnSupportHide }` or `{}` when disabled.\n\t */\n\tsetup(props) {\n\t\t// Mount the multi-tenancy context provider so descendants can\n\t\t// reach the shared `activeOrganisationUuid` / `setActiveTenant`\n\t\t// via `useTenantContext()` (composable) or the\n\t\t// `tenantContextMixin` (Options API). The provider is mounted\n\t\t// even on single-tenant apps so consumers can opt-in later\n\t\t// without restructuring their CnAppRoot wrapper.\n\t\tconst tenantContext = provideTenantContext(\n\t\t\tprops.initialOrganisationUuid || null,\n\t\t\tprops.initialOrganisation || null,\n\t\t)\n\n\t\t// Off when the host opts out (`:support-dialog=\"false\"`) OR the manifest's\n\t\t// support block is explicitly disabled (the \"Show the support note on\n\t\t// first open\" toggle in Buildiq's editor). Omitting the block keeps the\n\t\t// default-on first-open behaviour.\n\t\tconst manifestSupportDisabled = !!(props.manifest && props.manifest.support\n\t\t\t&& typeof props.manifest.support === 'object'\n\t\t\t&& props.manifest.support.enabled === false)\n\t\tconst supportPair = (props.supportDialog === false || manifestSupportDisabled)\n\t\t\t? {}\n\t\t\t: (() => {\n\t\t\t\t\tconst { visible, hide } = useSupportDialog(props.appId, { persistence: 'server' })\n\t\t\t\t\treturn { cnSupportVisible: visible, cnSupportHide: hide }\n\t\t\t\t})()\n\n\t\t// In-app editing (ADR-041) + the raw/reactive boundary (audit item 9,\n\t\t// `manifest-markraw-reactivity`). `baseRef` is the SINGLE reactive holder\n\t\t// for the manifest — it reconciles the prop read path and the editor's\n\t\t// live source into one wrap site. It is a `shallowRef`, NOT a `ref`: a\n\t\t// plain `ref(obj)` deep-observes the whole immutable manifest graph (up to\n\t\t// ~434 KB of nested objects) at boot for a structure the renderer only\n\t\t// ever reads. `shallowRef` holds the manifest RAW — `isReactive(baseRef\n\t\t// .value) === false` — so ordinary navigation and rendering never trigger\n\t\t// per-node observer conversion. The ADR-041 editor opts the live manifest\n\t\t// into deep reactivity IN PLACE on edit-enter (see `useManifestEditor`),\n\t\t// preserving object identity so already-mounted renderers see the edits;\n\t\t// on the next manifest publish the watch below re-installs a fresh raw\n\t\t// manifest, returning the read path to non-reactive.\n\t\tconst baseRef = shallowRef(props.manifest)\n\t\tconst manifestEditor = useManifestEditor(baseRef, {\n\t\t\tpersist: (delta) => (typeof props.persistManifestDelta === 'function'\n\t\t\t\t? props.persistManifestDelta(delta)\n\t\t\t\t: undefined),\n\t\t})\n\t\twatch(() => props.manifest, (m) => {\n\t\t\tif (!manifestEditor.editing.value) {\n\t\t\t\tbaseRef.value = m\n\t\t\t}\n\t\t})\n\t\t// One shared install/enable action for the or-missing guard and the\n\t\t// soft-dependency banners (REQ-DIA-3 / REQ-DIA-6). `depInstalling` /\n\t\t// `depInstallError` are the composable refs, returned top-level so the\n\t\t// template auto-unwraps them; `installAndEnable` is called from the\n\t\t// `installDependency` method.\n\t\tconst appInstaller = useAppInstaller()\n\n\t\tconst { available: buildiqAvailable } = useBuildiqEditAvailability()\n\t\t// A manifest may opt OUT of the Buildiq in-app edit button by setting\n\t\t// `openbuildEditable: false` (e.g. Buildiq's own pages — an app does not\n\t\t// edit itself with itself). Default true: omitting the flag keeps the\n\t\t// button wherever the Buildiq app is enabled (ADR-041). The manifest key\n\t\t// keeps its `openbuild` spelling — it is shipped manifest data.\n\t\tconst buildiqEditable = computed(() => buildiqAvailable.value && props.manifest?.openbuildEditable !== false)\n\n\t\t// Scoped NL Design token-set theming (scoped-theme-applier). Watches the\n\t\t// SAME editing/props branch `cnManifest`'s getter already uses, so the\n\t\t// applied theme tracks whichever manifest is currently effective —\n\t\t// including an in-app live-preview editing session (ADR-041) — with no\n\t\t// separate wiring needed for that case. `apply()` is a progressive\n\t\t// enhancement: nldesign absent/unreachable/non-conformant degrades\n\t\t// silently to default styling, never a throw (REQ-STA-1/REQ-STA-3).\n\t\tconst scopedTheme = useScopedTheme()\n\t\twatch(\n\t\t\t() => (manifestEditor.editing.value ? manifestEditor.source.value : props.manifest)?.runtime?.theme,\n\t\t\t() => scopedTheme.apply(\n\t\t\t\tmanifestEditor.editing.value ? manifestEditor.source.value : props.manifest,\n\t\t\t\tprops.appId,\n\t\t\t),\n\t\t\t{ deep: true, immediate: true },\n\t\t)\n\n\t\treturn {\n\t\t\t...supportPair,\n\t\t\tcnTenantContext: tenantContext,\n\t\t\tmanifestEditor,\n\t\t\tbuildiqAvailable: buildiqEditable,\n\t\t\tappInstaller,\n\t\t\tdepInstalling: appInstaller.installing,\n\t\t\tdepInstallError: appInstaller.error,\n\t\t\tcnScopedTheme: scopedTheme,\n\t\t}\n\t},\n\n\t/**\n\t * Component-instance state for the capabilities guard.\n\t *\n\t * - `capabilitiesLoading`: `true` only when the prop says we need\n\t * to check (i.e. `requiresApps.length > 0`). Apps that opt out\n\t * via `:requires-apps=\"[]\"` see this initialise to `false`, so\n\t * no spinner flashes and the renderer mounts on the first\n\t * render. Apps that need the guard see `true` initially; the\n\t * `mounted()` hook runs the check and flips to `false`.\n\t * - `missingApps`: the list of `requiresApps` entries NOT\n\t * present in the capabilities payload. When empty, the\n\t * renderer mounts; when non-empty, the empty-state renders.\n\t * - `guardError`: stores the caught error so consumers\n\t * inspecting the component instance can introspect failures.\n\t * The error path falls through to the renderer regardless.\n\t */\n\tdata() {\n\t\tconst willCheck = Array.isArray(this.requiresApps) && this.requiresApps.length > 0\n\t\treturn {\n\t\t\tcapabilitiesLoading: willCheck,\n\t\t\tmissingApps: [],\n\t\t\tguardError: null,\n\t\t\t/**\n\t\t\t * Reactive holder that descendants write into to mount\n\t\t\t * their embedded index sidebar at NcContent level. Shared\n\t\t\t * via provide(); see the `cnIndexSidebarConfig` provide\n\t\t\t * docs for the contract.\n\t\t\t */\n\t\t\tcnIndexSidebarConfig: { value: null },\n\t\t\t/**\n\t\t\t * Reactive AI context. Provided to all descendants via\n\t\t\t * provide('cnAiContext'). Page components overwrite fields\n\t\t\t * in their created() + watch() to give the companion\n\t\t\t * per-page context. The same object reference is stable\n\t\t\t * across the lifetime of CnAppRoot.\n\t\t\t *\n\t\t\t * Shape: CnAiContext (hydra-locked TypeScript interface)\n\t\t\t * { appId, pageKind, objectUuid?, registerSlug?,\n\t\t\t * schemaSlug?, route? }\n\t\t\t */\n\t\t\tcnAiContext: reactive({\n\t\t\t\tappId: this.appId || 'unknown',\n\t\t\t\tpageKind: 'custom',\n\t\t\t\troute: { path: (typeof window !== 'undefined' ? window.location.pathname : '') },\n\t\t\t}),\n\n\t\t\t/**\n\t\t\t * Reactive holder for the pages editor's register/schema\n\t\t\t * data sources. Provided as `cnDataSourcesState`.\n\t\t\t *\n\t\t\t * The object reference is STABLE for the lifetime of\n\t\t\t * CnAppRoot — `refreshDataSources()` mutates its fields and\n\t\t\t * never reassigns it. That is load-bearing: provide() runs\n\t\t\t * once, so a value provided from a prop can never change\n\t\t\t * (which is exactly why the legacy `cnDataSources` snapshot\n\t\t\t * goes stale). Descendants read `.value`, mirroring how they\n\t\t\t * already unwrap `cnOpenBuildAvailable` / `cnEditingBody`.\n\t\t\t *\n\t\t\t * `value` holds the `{ registers: [...] }` payload (seeded\n\t\t\t * from the `dataSources` snapshot when one is passed), and\n\t\t\t * `hasLoader` lets descendants render the pickers instead of\n\t\t\t * free-text fields before the first fetch resolves.\n\t\t\t */\n\t\t\tdataSourcesState: {\n\t\t\t\tvalue: this.dataSources || null,\n\t\t\t\tloading: false,\n\t\t\t\terror: null,\n\t\t\t\thasLoader: typeof this.dataSourcesLoader === 'function',\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * Reactive `{ [register]: { [schema]: number } }` map of\n\t\t\t * object-store totals — one entry per unique\n\t\t\t * `(register, schema)` pair declared on a menu item with\n\t\t\t * `count: \"auto\"`. Provided to descendants as\n\t\t\t * `cnMenuCounts`; CnAppNav reads from it inside its\n\t\t\t * `resolveCount()` to render `NcCounterBubble` badges.\n\t\t\t *\n\t\t\t * Populated by `_hydrateMenuCounts()` at mount. Wrapped in\n\t\t\t * `Vue.observable` so direct property writes\n\t\t\t * (`this.cnMenuCounts[register][schema] = total`) are\n\t\t\t * picked up by CnAppNav's reactive render.\n\t\t\t */\n\t\t\tcnMenuCounts: reactive({}),\n\t\t\t/**\n\t\t\t * Open state of the host NcAppSettingsDialog. Toggled\n\t\t\t * to `true` by the provided `cnOpenUserSettings()`\n\t\t\t * method (CnAppNav binds this to manifest entries with\n\t\t\t * `action: \"user-settings\"`); the dialog flips it back\n\t\t\t * via its `update:open` event.\n\t\t\t */\n\t\t\tuserSettingsOpen: false,\n\t\t\t/**\n\t\t\t * Id of the dependency whose install/enable action is currently\n\t\t\t * in flight (REQ-DIA-3 / REQ-DIA-6). Drives the per-button spinner\n\t\t\t * so, with several soft-dependency banners on screen, only the\n\t\t\t * clicked one shows busy. `null` when nothing is installing.\n\t\t\t *\n\t\t\t * @type {string|null}\n\t\t\t */\n\t\t\tinstallingDepId: null,\n\t\t\t/**\n\t\t\t * Id of the dependency whose last install/enable attempt failed —\n\t\t\t * scopes the inline soft-dependency banner error to that dep even\n\t\t\t * after `installingDepId` clears on settle.\n\t\t\t *\n\t\t\t * @type {string|null}\n\t\t\t */\n\t\t\terroredDepId: null,\n\t\t\t/**\n\t\t\t * Ids of SOFT dependencies whose in-shell banner the user has\n\t\t\t * dismissed (REQ-DIA-6). Seeded synchronously from `localStorage`\n\t\t\t * (`cn-soft-dep-dismissed:{appId}:{depId}`) so a previously\n\t\t\t * dismissed notice never flashes on mount; a fresh dismissal pushes\n\t\t\t * the id here (reactive hide) and persists the key.\n\t\t\t *\n\t\t\t * @type {Array<string>}\n\t\t\t */\n\t\t\tdismissedSoftDeps: (() => {\n\t\t\t\tconst out = []\n\t\t\t\ttry {\n\t\t\t\t\tconst deps = Array.isArray(this.manifest?.dependencies)\n\t\t\t\t\t\t? this.manifest.dependencies\n\t\t\t\t\t\t: []\n\t\t\t\t\tfor (const entry of deps) {\n\t\t\t\t\t\tconst isObject = entry !== null && typeof entry === 'object'\n\t\t\t\t\t\tconst id = isObject ? entry.id : entry\n\t\t\t\t\t\tconst required = isObject ? entry.required !== false : true\n\t\t\t\t\t\tif (required || typeof id !== 'string' || id === '') {\n\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (window.localStorage.getItem('cn-soft-dep-dismissed:' + this.appId + ':' + id)) {\n\t\t\t\t\t\t\tout.push(id)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} catch {\n\t\t\t\t\t// localStorage unavailable (private mode) — nothing dismissed.\n\t\t\t\t}\n\t\t\t\treturn out\n\t\t\t})(),\n\n\t\t\t/**\n\t\t\t * Session-only flag: the user dismissed (or finished) the non-gating\n\t\t\t * setup wizard during THIS page load. The durable answer lives in\n\t\t\t * `localStorage` and is read through `isSetupWizardDismissed()` —\n\t\t\t * deliberately NOT seeded here, because `manifest` can still be\n\t\t\t * replaced by `useAppManifest`'s async backend merge and a seed\n\t\t\t * would then have been checked against a stale `setup.version`.\n\t\t\t *\n\t\t\t * @type {boolean}\n\t\t\t */\n\t\t\tsetupWizardDismissed: false,\n\t\t\t/**\n\t\t\t * Whether the non-gating setup wizard overlay is currently open.\n\t\t\t * Flips true once (auto-open) when only optional steps are unmet\n\t\t\t * and the user hasn't already dismissed this manifest version; the\n\t\t\t * user can reopen later from wherever the host surfaces it (e.g.\n\t\t\t * admin settings), independent of this auto-open state.\n\t\t\t *\n\t\t\t * @type {boolean}\n\t\t\t */\n\t\t\tsetupWizardOpen: false,\n\t\t\t/**\n\t\t\t * The user's last-seen walkthrough app version (ADR-043).\n\t\t\t *\n\t\t\t * Seeded SYNCHRONOUSLY from the per-browser localStorage mirror so\n\t\t\t * nothing flashes, then overwritten by the `walkthroughConfigKey`\n\t\t\t * watcher from the authoritative per-user preference addressed by\n\t\t\t * `manifest.walkthrough.completionConfigKey`. `''` means the user\n\t\t\t * has never completed or dismissed the tour.\n\t\t\t *\n\t\t\t * @type {string}\n\t\t\t */\n\t\t\twalkthroughSeenVersionValue: readLocalWalkthroughSeenVersion(this.appId),\n\t\t\t/**\n\t\t\t * Whether `walkthroughSeenVersionValue` is settled. Starts `true`\n\t\t\t * when the manifest declares no `completionConfigKey` (the local\n\t\t\t * read above is already the final answer) and `false` when it does,\n\t\t\t * so the overlay waits for the server round trip instead of\n\t\t\t * auto-opening a tour the user already finished on another device.\n\t\t\t *\n\t\t\t * @type {boolean}\n\t\t\t */\n\t\t\twalkthroughSeenResolved: !(this.manifest\n\t\t\t\t&& this.manifest.walkthrough\n\t\t\t\t&& this.manifest.walkthrough.completionConfigKey),\n\n\t\t\t/**\n\t\t\t * Whether the setup status has finished loading at least once.\n\t\t\t * Stays `true` across later refreshes.\n\t\t\t *\n\t\t\t * @type {boolean}\n\t\t\t */\n\t\t\tsetupStatusSettled: false,\n\n\t\t\t/**\n\t\t\t * Key of the currently active modal (opened via cnOpenModal).\n\t\t\t * null when no modal is open.\n\t\t\t *\n\t\t\t * @type {string|null}\n\t\t\t */\n\t\t\tactiveModalKey: null,\n\t\t\t/**\n\t\t\t * Props forwarded to the active modal component.\n\t\t\t *\n\t\t\t * @type {object}\n\t\t\t */\n\t\t\tactiveModalProps: {},\n\t\t\t/**\n\t\t\t * Local holder for the object-sidebar channel. Lives on\n\t\t\t * this CnAppRoot instance (Vue.observable so descendant\n\t\t\t * writes via inject trigger re-renders); the `provide()`\n\t\t\t * block exposes it under the `objectSidebarState` key.\n\t\t\t *\n\t\t\t * CnDetailPage flips `active: true` + fills the object\n\t\t\t * coordinates in its `syncSidebarState()`; we render the\n\t\t\t * hoisted CnObjectSidebar when both `objectType` and\n\t\t\t * `objectId` are non-empty AND the consumer hasn't\n\t\t\t * supplied a `#sidebar` slot AND no ancestor already\n\t\t\t * owns the channel.\n\t\t\t */\n\t\t\tlocalObjectSidebarState: reactive({\n\t\t\t\tactive: false,\n\t\t\t\topen: false,\n\t\t\t\tobjectType: '',\n\t\t\t\tobjectId: '',\n\t\t\t\ttitle: '',\n\t\t\t\tsubtitle: '',\n\t\t\t\tregister: '',\n\t\t\t\tschema: '',\n\t\t\t\t// The loaded object, published by CnDetailPage so the hoisted\n\t\t\t\t// sidebar's data/metadata tab widgets get it as `objectData`.\n\t\t\t\t// Pre-declared here so Vue 2 keeps it reactive.\n\t\t\t\tobject: null,\n\t\t\t\t// The resolved schema OBJECT, for the `data` tab widget.\n\t\t\t\tschemaObject: null,\n\t\t\t\thiddenTabs: [],\n\t\t\t\ttabs: undefined,\n\t\t\t\t// Host-requested active tab id (e.g. a detail-page \"Linked\n\t\t\t\t// apps\" row deep-linking into a specific leaf). null = let\n\t\t\t\t// the sidebar pick its own default.\n\t\t\t\trequestedTab: null,\n\t\t\t}),\n\n\t\t\t/**\n\t\t\t * Local holder for the index-sidebar channel. Distinct\n\t\t\t * reference from `localObjectSidebarState` so the\n\t\t\t * `sidebarState`-first inject in CnIndexPage never\n\t\t\t * leaks an `active: true` write into the object-sidebar\n\t\t\t * channel.\n\t\t\t */\n\t\t\tlocalIndexSidebarState: reactive({\n\t\t\t\tactive: false,\n\t\t\t\topen: false,\n\t\t\t\tsearchValue: '',\n\t\t\t\tactiveFilters: {},\n\t\t\t\tfacetData: null,\n\t\t\t\tfacetableFields: [],\n\t\t\t\tfacetableConfig: null,\n\t\t\t}),\n\t\t}\n\t},\n\n\tcomputed: {\n\t\t/**\n\t\t * The per-user preference reader and writer for this app, built from\n\t\t * the manifest's `personalisation` block.\n\t\t *\n\t\t * One group per app, shared by every descendant through the\n\t\t * `cnUserPreferences` provide, so a list holding a row order and the\n\t\t * preferences screen showing it are looking at the same thing.\n\t\t *\n\t\t * @return {object} The group from useUserPreferences.\n\t\t * @spec openspec/changes/case-page-and-list-as-a-place/specs/index-page/spec.md\n\t\t */\n\t\tuserPreferences() {\n\t\t\treturn useUserPreferences(this.appId, {\n\t\t\t\tpersonalisation: this.manifest?.personalisation || {},\n\t\t\t})\n\t\t},\n\n\t\t/**\n\t\t * The component to render as this page's sidebar.\n\t\t *\n\t\t * Two sources, in order:\n\t\t * 1. `pages[].sidebarComponent` on the routed manifest page, resolved\n\t\t * here — see `resolvePageSidebarComponent()` for why it cannot be\n\t\t * resolved by the renderer that declares it.\n\t\t * 2. The injected `cnPageSidebarComponent` holder, kept so an app that\n\t\t * genuinely provides one from an ANCESTOR still works.\n\t\t *\n\t\t * A consumer's own `#sidebar` slot content always wins over both, via\n\t\t * Vue's standard slot mechanic.\n\t\t *\n\t\t * @return {import('vue').Component|null} The component, or null.\n\t\t */\n\t\tpageSidebarComponent() {\n\t\t\treturn this.resolvePageSidebarComponent() ?? this.cnPageSidebarComponent?.value ?? null\n\t\t},\n\n\t\t/**\n\t\t * Whether the current user is an OWNER of this app — the gate for\n\t\t * the admin-settings nav entry + dialog (admin-settings-owner-gating\n\t\t * capability). Deliberately NOT `OC.isUserAdmin()`: a Nextcloud\n\t\t * super-admin who is not an app owner does not see the admin\n\t\t * surface, and an app owner who is not a super-admin does.\n\t\t *\n\t\t * PRIMARY signal: `manifest.runtime.user.isOwner === true`, a\n\t\t * read-only projection the backend computes via\n\t\t * `PermissionResolver::matchesCaller(...['owners'])` (D5) — the\n\t\t * reliable path for the ordinary manifest-render case.\n\t\t *\n\t\t * FALLBACK: a non-empty intersection of the caller's groups\n\t\t * (`openbuild.currentUserGroups` initial state) with the owner GIDs\n\t\t * parsed from the `permissions` prop using the same `group:<gid>` /\n\t\t * bare-GID grammar as per-item `permission` narrowing — for hosts\n\t\t * (e.g. an OpenBuilt virtual app) that pass the app's\n\t\t * `Application.permissions.owners` principals through `permissions`\n\t\t * rather than (or in addition to) the backend runtime.user\n\t\t * projection. Read via `loadState` initial-state, never DOM\n\t\t * data-attributes (hydra initial-state gate).\n\t\t *\n\t\t * @return {boolean}\n\t\t */\n\t\tisOwner() {\n\t\t\tconst runtime = this.manifest && this.manifest.runtime\n\t\t\tconst runtimeUser = runtime && typeof runtime.user === 'object' && runtime.user !== null\n\t\t\t\t? runtime.user\n\t\t\t\t: null\n\t\t\tif (runtimeUser && runtimeUser.isOwner === true) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\treturn this.ownerGroupsIntersect\n\t\t},\n\n\t\t/**\n\t\t * Caller's Nextcloud group GIDs, published by Buildiq's\n\t\t * `DashboardController::publishCurrentUserGroups()` initial state.\n\t\t * Read via `loadState`, never DOM attributes. Defensive try/catch\n\t\t * mirrors `serverAppStatuses` — hosts without the initial-state key\n\t\t * (non-Buildiq hosts, tests) simply resolve to an empty list, so the\n\t\t * fallback gate stays false rather than throwing.\n\t\t *\n\t\t * Initial state is namespaced by the PUBLISHING app's id, which moved\n\t\t * from `openbuild` to `buildiq`, so both are tried. A miss is silent:\n\t\t * `loadState` with a default returns the default, the gate reads\n\t\t * false, and nothing reports a stale key. Drop `openbuild` once no\n\t\t * supported install ships the old app id.\n\t\t *\n\t\t * @return {Array<string>}\n\t\t */\n\t\tcurrentUserGroups() {\n\t\t\ttry {\n\t\t\t\tconst groups = loadState('buildiq', 'currentUserGroups', null)\n\t\t\t\t\t?? loadState('openbuild', 'currentUserGroups', [])\n\t\t\t\treturn Array.isArray(groups) ? groups : []\n\t\t\t} catch {\n\t\t\t\treturn []\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Owner GIDs parsed from the `permissions` prop using the existing\n\t\t * per-item permission grammar (`group:<gid>` or a bare GID). Not\n\t\t * every `permissions` entry is necessarily an owner GID (a host may\n\t\t * also pass unrelated permission strings) — this is a best-effort\n\t\t * parse, and only feeds the FALLBACK gate; the PRIMARY signal is\n\t\t * `runtime.user.isOwner`.\n\t\t *\n\t\t * @return {Array<string>}\n\t\t */\n\t\townerGidsFromPermissions() {\n\t\t\tif (!Array.isArray(this.permissions)) {\n\t\t\t\treturn []\n\t\t\t}\n\t\t\treturn this.permissions\n\t\t\t\t.filter((p) => typeof p === 'string' && p.length > 0)\n\t\t\t\t.map((p) => (p.startsWith('group:') ? p.slice('group:'.length) : p))\n\t\t},\n\n\t\t/**\n\t\t * Whether `currentUserGroups` and `ownerGidsFromPermissions`\n\t\t * intersect — the FALLBACK half of `isOwner`.\n\t\t *\n\t\t * @return {boolean}\n\t\t */\n\t\townerGroupsIntersect() {\n\t\t\tconst groups = this.currentUserGroups\n\t\t\tconst owners = this.ownerGidsFromPermissions\n\t\t\tif (groups.length === 0 || owners.length === 0) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\treturn groups.some((g) => owners.includes(g))\n\t\t},\n\n\t\t/**\n\t\t * The manifest the default `<CnAppNav>` renders — the editor's working\n\t\t * `source` while in-app editing, else the live `manifest` prop. Passed to\n\t\t * CnAppNav as a REACTIVE prop (not left to the provide/inject fallback):\n\t\t * Vue 2 `inject` resolves the provided `cnManifest` getter once at the\n\t\t * child's create time, so an async manifest update (e.g. a backend\n\t\t * `/api/manifest` delta merged in by `useAppManifest`) never reaches the\n\t\t * injected value. Binding the prop makes the nav update reactively.\n\t\t * Mirrors the `cnManifest` provide getter so deep descendants stay\n\t\t * consistent with the menu.\n\t\t *\n\t\t * @return {object}\n\t\t */\n\t\tmenuManifest() {\n\t\t\tconst m = this.manifestEditor ? this.manifestEditor.source.value : this.manifest\n\t\t\t// Raw/reactive boundary (audit item 9). The manifest is held raw at\n\t\t\t// boot (CnAppRoot's shallowRef), so the default CnAppNav establishes\n\t\t\t// its render dependencies against a NON-reactive `menu` at first\n\t\t\t// render. When the in-app editor opts the manifest into reactivity on\n\t\t\t// edit-enter (`useManifestEditor.enter()` → `reactive()` in place),\n\t\t\t// CnAppNav would otherwise keep its stale dep-less render and miss live\n\t\t\t// menu edits. Handing it a FRESH wrapper identity while editing forces\n\t\t\t// one re-render that re-subscribes to the now-reactive `menu` array, so\n\t\t\t// menu add/label/reorder edits render live exactly as before — while\n\t\t\t// the spread's `menu` is the SAME reactive array, so in-place edits\n\t\t\t// flow through. Outside edit mode the live manifest is returned BY\n\t\t\t// IDENTITY (regression guard: the CnAppNav prop must === the manifest\n\t\t\t// prop for async backend-merge updates — see the reactive-menu tests).\n\t\t\tif (this.manifestEditor && this.manifestEditor.editing.value && m && typeof m === 'object') {\n\t\t\t\treturn { ...m }\n\t\t\t}\n\t\t\treturn m\n\t\t},\n\n\t\t/**\n\t\t * Active object-sidebar holder for the auto-mount block.\n\t\t * Mirrors the local holder; if an ancestor already provides\n\t\t * `objectSidebarState`, the auto-mount is suppressed by\n\t\t * `shouldAutoMountObjectSidebar`, so this getter is only\n\t\t * read when we own the channel.\n\t\t *\n\t\t * @return {object}\n\t\t */\n\t\teffectiveObjectSidebarState() {\n\t\t\treturn this.localObjectSidebarState\n\t\t},\n\n\t\t/**\n\t\t * Which mode the auto-mounted CnObjectSidebar runs in.\n\t\t *\n\t\t * CnObjectSidebar treats `tabs` and `useRegistry` as mutually\n\t\t * exclusive and warns when it gets both. This mount site passes\n\t\t * `:tabs` unconditionally, so leaving `useRegistry` at its default\n\t\t * `true` warned on every detail page that publishes tabs — advice no\n\t\t * consumer could act on, since they never see this element. Published\n\t\t * tabs mean tabs mode, which is what the sidebar picks anyway.\n\t\t *\n\t\t * @return {boolean}\n\t\t */\n\t\tobjectSidebarUseRegistry() {\n\t\t\tconst tabs = this.effectiveObjectSidebarState?.tabs\n\t\t\treturn !(Array.isArray(tabs) && tabs.length > 0)\n\t\t},\n\n\t\t/**\n\t\t * Decide whether THIS CnAppRoot should render the hoisted\n\t\t * CnObjectSidebar. False when:\n\t\t * - the consumer fills `#sidebar` (their slot owns the rail);\n\t\t * - an ancestor already provides `objectSidebarState`\n\t\t * (ancestor renders its own sidebar);\n\t\t * - `localObjectSidebarState.active` is false (default);\n\t\t * - `objectType` + `objectId` are both empty (defense-in-\n\t\t * depth against CnIndexPage's fallback writing `active:\n\t\t * true` into the wrong channel — see\n\t\t * CnAppRootObjectSidebar.spec.js for the regression).\n\t\t *\n\t\t * @return {boolean}\n\t\t */\n\t\tshouldAutoMountObjectSidebar() {\n\t\t\tif (this.$slots && this.$slots.sidebar) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tif (this.$slots && this.$slots.sidebar) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tif (this.ancestorObjectSidebarState) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tconst holder = this.localObjectSidebarState\n\t\t\tif (!holder || !holder.active) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tconst hasObjectCoordinates = !!(holder.objectType && holder.objectId)\n\t\t\treturn hasObjectCoordinates\n\t\t},\n\n\t\t/**\n\t\t * Resolved support-dialog config — the manifest's `support` block\n\t\t * (authored in Buildiq's \"Edit support & donation\" editor) overlaid\n\t\t * by any host-supplied `supportDialog` override object, so app authors\n\t\t * can configure the donation/support note entirely from the UI while a\n\t\t * host can still override per-mount.\n\t\t *\n\t\t * @return {object}\n\t\t */\n\t\tcnSupportConfig() {\n\t\t\tconst fromManifest = (this.manifest && this.manifest.support && typeof this.manifest.support === 'object')\n\t\t\t\t? this.manifest.support\n\t\t\t\t: {}\n\t\t\tconst fromProp = (this.supportDialog && typeof this.supportDialog === 'object')\n\t\t\t\t? this.supportDialog\n\t\t\t\t: {}\n\t\t\treturn { ...fromManifest, ...fromProp }\n\t\t},\n\n\t\t/**\n\t\t * App display name for the support note — host override, else the\n\t\t * capitalised `appId` (e.g. `pipelinq` → `Pipelinq`).\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\tcnSupportAppName() {\n\t\t\tif (this.cnSupportConfig.appName) {\n\t\t\t\treturn this.cnSupportConfig.appName\n\t\t\t}\n\t\t\treturn this.appId\n\t\t\t\t? this.appId.charAt(0).toUpperCase() + this.appId.slice(1)\n\t\t\t\t: ''\n\t\t},\n\n\t\t/**\n\t\t * App Store listing URL — host override, else the conventional\n\t\t * `apps.nextcloud.com/apps/{appId}`.\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\tcnSupportAppStoreUrl() {\n\t\t\treturn this.cnSupportConfig.appStoreUrl\n\t\t\t\t|| ('https://apps.nextcloud.com/apps/' + this.appId)\n\t\t},\n\n\t\t/**\n\t\t * Feature-request URL — host override, else the new-issue link on\n\t\t * the app's own forge. Derived from the SAME resolved repo and\n\t\t * forge the actions menu uses, rather than a second hardcoded\n\t\t * host: this spelled out `codeberg.org/Conduction/{appId}` and so\n\t\t * kept pointing at the unmaintained mirror after the fleet moved\n\t\t * back to GitHub, while the menu's link had already moved.\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\tcnSupportFeatureRequestUrl() {\n\t\t\tif (this.cnSupportConfig.featureRequestUrl) {\n\t\t\t\treturn this.cnSupportConfig.featureRequestUrl\n\t\t\t}\n\t\t\tconst { baseUrl } = resolveForge(this.resolvedFeatureRequestForge)\n\t\t\treturn `${baseUrl}/${this.resolvedFeatureRequestRepo}/issues/new`\n\t\t},\n\n\t\t/**\n\t\t * Pass-through of any other `CnSupportDialog` props supplied in\n\t\t * the `supportDialog` override object (donateUrl, supportUrl,\n\t\t * conductionUrl, appsUrl, founderName/title/avatar/profile,\n\t\t * bodyParagraphs). Lets a host re-sign the note without forking.\n\t\t *\n\t\t * @return {object}\n\t\t */\n\t\tcnSupportOverrides() {\n\t\t\tconst cfg = this.cnSupportConfig\n\t\t\tconst passthrough = ['title', 'donateUrl', 'supportUrl', 'conductionUrl', 'appsUrl', 'founderName', 'founderTitle', 'founderAvatarUrl', 'founderProfileUrl', 'bodyParagraphs', 'buttons']\n\t\t\tconst out = {}\n\t\t\tfor (const key of passthrough) {\n\t\t\t\tif (cfg[key] !== undefined) {\n\t\t\t\t\tout[key] = cfg[key]\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn out\n\t\t},\n\n\t\t/**\n\t\t * Whether the `CnCommandPalette` auto-mount is active — `true`, or\n\t\t * an override object (per the `supportDialog` Boolean|Object\n\t\t * convention above).\n\t\t *\n\t\t * @return {boolean}\n\t\t */\n\t\tcnCommandPaletteVisible() {\n\t\t\treturn this.commandPalette === true || (!!this.commandPalette && typeof this.commandPalette === 'object')\n\t\t},\n\n\t\t/**\n\t\t * Prop overrides supplied via the `commandPalette` object form,\n\t\t * spread onto `CnCommandPalette` OVER the auto-wired `manifest` /\n\t\t * `router` / `app-id` — so an app can override e.g. `objectSearch`\n\t\t * or `shortcut` without losing the zero-config navigation source.\n\t\t *\n\t\t * @return {object}\n\t\t */\n\t\tcnCommandPaletteOverrides() {\n\t\t\treturn (this.commandPalette && typeof this.commandPalette === 'object') ? this.commandPalette : {}\n\t\t},\n\n\t\t/**\n\t\t * Per-dependency status, computed once per `appId` declared in\n\t\t * `manifest.dependencies`. Reading the value here triggers the\n\t\t * useAppStatus composable for each id; results are cached\n\t\t * module-side so subsequent reads are free.\n\t\t */\n\t\tdependencyStatuses() {\n\t\t\tconst deps = Array.isArray(this.manifest?.dependencies)\n\t\t\t\t? this.manifest.dependencies\n\t\t\t\t: []\n\t\t\t// HARD/SOFT dependency model (REQ-DIA-4/REQ-DIA-5). Each manifest\n\t\t\t// entry is normalised to `{ id, required, name, status }`:\n\t\t\t// - string → HARD (`required: true`), name = id\n\t\t\t// - { id, required?, name? } → `required` defaults to true;\n\t\t\t// `required: false` marks a SOFT (optional) dependency.\n\t\t\treturn deps\n\t\t\t\t.map((entry) => {\n\t\t\t\t\tconst isObject = entry !== null && typeof entry === 'object'\n\t\t\t\t\tconst id = isObject ? entry.id : entry\n\t\t\t\t\tif (typeof id !== 'string' || id === '') {\n\t\t\t\t\t\treturn null\n\t\t\t\t\t}\n\t\t\t\t\tconst required = isObject ? entry.required !== false : true\n\t\t\t\t\tconst name = (isObject && entry.name) || id\n\t\t\t\t\treturn { id, required, name, status: useAppStatus(id) }\n\t\t\t\t})\n\t\t\t\t.filter((entry) => entry !== null)\n\t\t},\n\n\t\t/**\n\t\t * App statuses injected by the PHP boot() via IInitialStateService.\n\t\t * Keyed by app id: { installed: bool, enabled: bool }.\n\t\t * Falls back to {} when not injected (non-pipelinq consumers, tests).\n\t\t */\n\t\tserverAppStatuses() {\n\t\t\ttry {\n\t\t\t\tconst statuses = loadState(this.appId, 'dependency_statuses', {})\n\t\t\t\treturn statuses\n\t\t\t} catch {\n\t\t\t\treturn {}\n\t\t\t}\n\t\t},\n\n\t\tunresolvedDependencies() {\n\t\t\treturn this.dependencyStatuses\n\t\t\t\t.filter(({ id, status }) => {\n\t\t\t\t\tconst server = this.serverAppStatuses[id]\n\t\t\t\t\tif (server !== undefined) {\n\t\t\t\t\t\treturn !server.installed || !server.enabled\n\t\t\t\t\t}\n\t\t\t\t\treturn !status.installed.value || !status.enabled.value\n\t\t\t\t})\n\t\t\t\t.map(({ id, required, name }) => {\n\t\t\t\t\tconst server = this.serverAppStatuses[id]\n\t\t\t\t\tif (server !== undefined) {\n\t\t\t\t\t\t// Server data available: correctly distinguish the two states.\n\t\t\t\t\t\t// enabled: false → installed but disabled (→ \"Enable\")\n\t\t\t\t\t\t// enabled: undefined → not installed (→ \"Install\")\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tid,\n\t\t\t\t\t\t\tname,\n\t\t\t\t\t\t\trequired,\n\t\t\t\t\t\t\tcategory: server.category ?? 'featured',\n\t\t\t\t\t\t\tenabled: server.installed ? false : undefined,\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t// No server data and the JS heuristic cannot tell not-installed\n\t\t\t\t\t// from installed-but-disabled. Default to the safe \"not\n\t\t\t\t\t// installed\" shape (enabled: undefined → \"Install and enable\"):\n\t\t\t\t\t// a genuinely-missing app must never be mislabelled \"Enable\".\n\t\t\t\t\treturn { id, name, required, category: 'featured', enabled: undefined }\n\t\t\t\t})\n\t\t},\n\n\t\t/**\n\t\t * Unresolved HARD dependencies — the app cannot run without these,\n\t\t * so their presence gates the shell behind the blocking\n\t\t * `dependency-missing` phase / `CnDependencyMissing` screen\n\t\t * (REQ-DIA-5).\n\t\t *\n\t\t * @return {Array<object>} Unresolved entries with `required === true`.\n\t\t */\n\t\tunresolvedHardDependencies() {\n\t\t\treturn this.unresolvedDependencies.filter((dep) => dep.required)\n\t\t},\n\n\t\t/**\n\t\t * Unresolved SOFT dependencies — optional integrations whose\n\t\t * absence must NOT block the shell. Each surfaces as a dismissible\n\t\t * in-shell `NcNoteCard` banner (REQ-DIA-6), filtered here to those\n\t\t * not yet dismissed in `localStorage`.\n\t\t *\n\t\t * @return {Array<object>} Undismissed unresolved entries with\n\t\t * `required === false`.\n\t\t */\n\t\tunresolvedSoftDependencies() {\n\t\t\treturn this.unresolvedDependencies\n\t\t\t\t.filter((dep) => !dep.required)\n\t\t\t\t.filter((dep) => !this.dismissedSoftDeps.includes(dep.id))\n\t\t},\n\n\t\t/**\n\t\t * The soft-dependency notices actually RENDERED in the shell. Empty\n\t\t * unless the deprecated `softDependencyNotices` prop is switched back\n\t\t * on — the banners now live in admin settings\n\t\t * (`CnLeafDependencySettings`) instead of above every index page.\n\t\t * `unresolvedSoftDependencies` itself is untouched and still exposed,\n\t\t * so an app rendering its own surface from it keeps working.\n\t\t *\n\t\t * @return {Array<object>}\n\t\t */\n\t\tvisibleSoftDependencyNotices() {\n\t\t\treturn this.softDependencyNotices ? this.unresolvedSoftDependencies : []\n\t\t},\n\n\t\t/**\n\t\t * First-time-setup status for this app (ADR-042), or null when the\n\t\t * manifest declares no `setup` block. Calls useSetupStatus inside the\n\t\t * computed so the returned refs stay reactive (same pattern as\n\t\t * unresolvedDependencies → useAppStatus).\n\t\t */\n\t\tsetupState() {\n\t\t\tif (!this.appId || !this.manifest || !this.manifest.setup || this.manifest.setup.enabled === false) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\treturn useSetupStatus(this.appId, this.manifest)\n\t\t},\n\n\t\t/**\n\t\t * Whether a REQUIRED setup step is unmet — the app shell is gated to\n\t\t * the setup wizard until this clears. Never gates while the status is\n\t\t * still loading (avoids a flash before the answer is known).\n\t\t */\n\t\tsetupGating() {\n\t\t\tconst s = this.setupState\n\t\t\treturn !!s && s.loading.value === false && s.requiredUnmet.value.length > 0\n\t\t},\n\n\t\t/**\n\t\t * Whether the setup status is still loading. `false` when the manifest\n\t\t * declares no setup block.\n\t\t */\n\t\tsetupStatusLoading() {\n\t\t\tconst s = this.setupState\n\t\t\treturn !!s && s.loading.value !== false\n\t\t},\n\n\t\t/**\n\t\t * Whether the setup wizard should be OFFERED (non-gating) because\n\t\t * every required step is met but at least one ACTIONABLE optional step\n\t\t * isn't (REQ-SETUP-NV-012). Never true while the gating phase is active —\n\t\t * required-unmet already renders `CnSetupWizard` itself.\n\t\t *\n\t\t * Two independent guards keep this from being permanently true, because\n\t\t * a step can look \"unmet\" for two unrelated reasons:\n\t\t *\n\t\t * 1. Only steps the server POSITIVELY REPORTED count. An app may declare\n\t\t * optional steps its SetupController never reports a status key for —\n\t\t * pipelinq's `demo-data` run-action is one — and such a step is\n\t\t * UNKNOWN, not outstanding. Auto-opening on it parked the wizard over\n\t\t * the app on every fresh browser profile even though\n\t\t * `/api/setup/status` answered `200 {completed:true}`, which read as\n\t\t * \"the setup gate never clears\" and timed out every UI e2e spec in the\n\t\t * consuming app.\n\t\t *\n\t\t * This guard used to be a blanket short-circuit on the server's\n\t\t * `completed` flag — a BLUNTER instrument aimed at the same target,\n\t\t * which overshot. `completed` means \"no REQUIRED step is\n\t\t * outstanding\", so it is true for every correctly-configured app, and\n\t\t * suppressing on it hid reported-and-undone OPTIONAL steps too.\n\t\t * Dossiq declares a `seed` step whose controller answers\n\t\t * `{done: false}` — genuinely outstanding, genuinely actionable — and\n\t\t * the wizard offering it never opened, leaving the app with no\n\t\t * reachable demo-data affordance at all. `completed` is still honoured\n\t\t * as a NEGATIVE signal (a server saying \"unfinished\" is believed\n\t\t * outright); it just no longer overrides a step the server explicitly\n\t\t * reported as not done.\n\t\t *\n\t\t * 2. `info` and `summary` steps are excluded: the server has nothing to\n\t\t * persist for them, so they report `done: false` forever and would\n\t\t * keep this permanently true (auto-prompting fully-configured users)\n\t\t * even when `completed` is absent or false.\n\t\t *\n\t\t * Neither guard subsumes the other — (1) is about steps the server never\n\t\t * reports, (2) about steps it can never mark done — so both are needed.\n\t\t *\n\t\t * @return {boolean} True when an actionable optional step is genuinely outstanding.\n\t\t */\n\t\toptionalSetupPending() {\n\t\t\tconst s = this.setupState\n\t\t\tif (!s || s.loading.value !== false) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tif (s.requiredUnmet.value.length > 0) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\t// When the server itself says setup is UNFINISHED, take it at its word:\n\t\t\t// every unmet optional step is fair game, reported or not.\n\t\t\t//\n\t\t\t// When it says setup IS complete, only steps it positively reported\n\t\t\t// as `{done: false}` are outstanding. An unreported step is unknown,\n\t\t\t// and prompting on unknown is what parked the wizard over pipelinq.\n\t\t\tconst outstanding = s.completed.value === true\n\t\t\t\t? (s.optionalUnmetReported ? s.optionalUnmetReported.value : [])\n\t\t\t\t: s.optionalUnmet.value\n\t\t\treturn outstanding.some((st) => st.type !== 'info' && st.type !== 'summary')\n\t\t},\n\n\t\t/**\n\t\t * Ids of setup steps the server already reports done. Passed to\n\t\t * `CnSetupWizard` so a freshly (re)mounted wizard resumes at the\n\t\t * first actually-unmet step instead of restarting from the top —\n\t\t * the wizard's own local state only tracks the current session.\n\t\t *\n\t\t * @return {Array<string>}\n\t\t */\n\t\tsetupCompletedStepIds() {\n\t\t\tconst s = this.setupState\n\t\t\treturn s ? s.steps.value.filter((st) => st.done).map((st) => st.id) : []\n\t\t},\n\n\t\t/**\n\t\t * The manifest's `section: \"integrations\"` menu entries — the links\n\t\t * that leave this app for another one, rendered in the Integrations\n\t\t * section of the per-user settings modal rather than in the navigation\n\t\t * (ADR-110).\n\t\t *\n\t\t * Applies the SAME `permission` and `visibleIf` rules CnAppNav applies\n\t\t * to nav entries, for two reasons. Skipping `permission` would surface\n\t\t * an admin-only link to everyone, and skipping `visibleIf.appInstalled`\n\t\t * would list a link to an app that is not installed — a guaranteed\n\t\t * 404 presented as a feature. That second case is the whole reason\n\t\t * these entries are worth gating: unlike a nav entry pointing at this\n\t\t * app's own route, a cross-app link can be dead through no fault of\n\t\t * this app.\n\t\t *\n\t\t * Only clickable entries qualify: `href` is what makes a row a link,\n\t\t * and a group with children has no meaning in a flat settings section.\n\t\t *\n\t\t * @return {Array<object>} Ordered, filtered integration entries.\n\t\t */\n\t\tintegrationEntries() {\n\t\t\tconst items = (this.manifest && this.manifest.menu) || []\n\t\t\treturn items\n\t\t\t\t.filter((item) => item.section === 'integrations')\n\t\t\t\t.filter((item) => typeof item.href === 'string' && item.href !== '')\n\t\t\t\t.filter((item) => this.passesIntegrationPermission(item))\n\t\t\t\t.filter((item) => this.passesIntegrationVisibleIf(item))\n\t\t\t\t.slice()\n\t\t\t\t.sort((a, b) => {\n\t\t\t\t\tconst aHas = typeof a.order === 'number'\n\t\t\t\t\tconst bHas = typeof b.order === 'number'\n\t\t\t\t\tif (aHas && !bHas) {\n\t\t\t\t\t\treturn -1\n\t\t\t\t\t}\n\t\t\t\t\tif (!aHas && bHas) {\n\t\t\t\t\t\treturn 1\n\t\t\t\t\t}\n\t\t\t\t\tif (!aHas && !bHas) {\n\t\t\t\t\t\treturn 0\n\t\t\t\t\t}\n\t\t\t\t\treturn a.order - b.order\n\t\t\t\t})\n\t\t},\n\n\t\t/**\n\t\t * Whether the manifest declares an enabled walkthrough with at least one\n\t\t * tour (ADR-043). Drives the non-gating CnWalkthrough overlay in the shell.\n\t\t *\n\t\t * @return {boolean} True when a walkthrough should mount.\n\t\t */\n\t\twalkthroughEnabled() {\n\t\t\tconst w = this.manifest && this.manifest.walkthrough\n\t\t\treturn !!(w && w.enabled !== false && Array.isArray(w.tours) && w.tours.length > 0)\n\t\t},\n\n\t\t/**\n\t\t * The per-user preference key holding the last app version whose tour the\n\t\t * user has seen (`manifest.walkthrough.completionConfigKey`). Empty when\n\t\t * the manifest declares none, in which case persistence stays per-browser.\n\t\t *\n\t\t * @return {string} The preference key, or ''.\n\t\t */\n\t\twalkthroughConfigKey() {\n\t\t\tconst w = this.manifest && this.manifest.walkthrough\n\t\t\treturn (w && typeof w.completionConfigKey === 'string' && w.completionConfigKey) || ''\n\t\t},\n\n\t\t/**\n\t\t * The user's last-seen app version for walkthrough composition. Resolved\n\t\t * from the per-user `completionConfigKey` preference (cross-device) with\n\t\t * the localStorage mirror as fallback; CnAppRoot writes BOTH on completion\n\t\t * or dismissal, so a returning user is not shown the tour again.\n\t\t *\n\t\t * @return {string} The last-seen version, or '' for a fresh user.\n\t\t */\n\t\twalkthroughSeenVersion() {\n\t\t\treturn this.walkthroughSeenVersionValue\n\t\t},\n\n\t\t/**\n\t\t * Cross-app / refresh resume token parsed from the URL query\n\t\t * (`cn_resume_tour` / `cn_resume_step`), or null.\n\t\t *\n\t\t * @return {object|null} `{ tourId, stepId }` or null.\n\t\t */\n\t\twalkthroughResume() {\n\t\t\ttry {\n\t\t\t\tconst p = new URLSearchParams(window.location.search)\n\t\t\t\tconst tourId = p.get('cn_resume_tour')\n\t\t\t\tif (!tourId) {\n\t\t\t\t\treturn null\n\t\t\t\t}\n\t\t\t\treturn { tourId, stepId: p.get('cn_resume_step') || '' }\n\t\t\t} catch {\n\t\t\t\treturn null\n\t\t\t}\n\t\t},\n\n\t\tphase() {\n\t\t\tif (this.isLoading) {\n\t\t\t\treturn 'loading'\n\t\t\t}\n\t\t\t// Only unresolved HARD dependencies block the shell (REQ-DIA-5);\n\t\t\t// unresolved SOFT dependencies surface as a non-blocking in-shell\n\t\t\t// banner and let the app advance to setup/shell.\n\t\t\tif (this.unresolvedHardDependencies.length > 0) {\n\t\t\t\treturn 'dependency-missing'\n\t\t\t}\n\t\t\tif (this.setupGating) {\n\t\t\t\treturn 'setup'\n\t\t\t}\n\t\t\treturn 'shell'\n\t\t},\n\n\t\t/**\n\t\t * Default link surfaced by the missing-app empty-state action.\n\t\t * Points at the OpenRegister integration page in the Nextcloud\n\t\t * app store. Replaceable per consumer via the `#or-missing`\n\t\t * slot.\n\t\t */\n\t\torStoreLink() {\n\t\t\treturn OR_STORE_LINK\n\t\t},\n\n\t\t/**\n\t\t * Whether the current user is a Nextcloud admin. Only admins can\n\t\t * hit `settings/apps/enable`, so both dependency surfaces branch on\n\t\t * this: admins get the in-place install/enable action, non-admins\n\t\t * get \"ask your administrator\" copy (REQ-DIA-2 / REQ-DIA-3).\n\t\t *\n\t\t * ALSO passed to CnAppNav as `is-admin` to gate visibility of the\n\t\t * \"Admin settings\" link to `/settings/admin/<appId>` (ADR-079 §3).\n\t\t * Read from `getCurrentUser()?.isAdmin` (`@nextcloud/auth`), never\n\t\t * the legacy `OC.isUserAdmin()` global. Presentation only — the\n\t\t * access boundary is Nextcloud's settings framework, which refuses\n\t\t * that page server-side for non-admins. A DIFFERENT signal from\n\t\t * `isOwner` (which means \"owns this app\", not \"administers this\n\t\t * instance\"); the two must not be conflated.\n\t\t *\n\t\t * @return {boolean}\n\t\t */\n\t\tisAdmin() {\n\t\t\ttry {\n\t\t\t\treturn getCurrentUser()?.isAdmin === true\n\t\t\t} catch {\n\t\t\t\treturn false\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * The missing app the or-missing guard's primary install/enable\n\t\t * action targets — the first entry of `missingApps` (typically\n\t\t * `openregister`). Empty string when nothing is missing.\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\torMissingPrimaryApp() {\n\t\t\treturn this.missingApps[0] || ''\n\t\t},\n\n\t\t/**\n\t\t * Human-readable list of the missing apps for the guard copy.\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\tmissingAppsLabel() {\n\t\t\treturn this.missingApps.join(', ')\n\t\t},\n\n\t\t/**\n\t\t * Guard title — the translated `app-availability.title`, or a\n\t\t * sensible English default when the key is untranslated (REQ-DIA-7).\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\torMissingTitle() {\n\t\t\treturn this.availabilityCopy('app-availability.title', 'Required app not available')\n\t\t},\n\n\t\t/**\n\t\t * Guard description — translated `app-availability.description` or an\n\t\t * English default naming the missing app(s) (REQ-DIA-7).\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\torMissingDescription() {\n\t\t\treturn this.availabilityCopy(\n\t\t\t\t'app-availability.description',\n\t\t\t\t`This app requires ${this.missingAppsLabel || 'another Nextcloud app'} to be installed and enabled.`,\n\t\t\t)\n\t\t},\n\n\t\t/**\n\t\t * Fallback store-link label — translated `app-availability.action`\n\t\t * or an English default (REQ-DIA-7).\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\torMissingActionLabel() {\n\t\t\treturn this.availabilityCopy('app-availability.action', 'Open app settings')\n\t\t},\n\n\t\t/**\n\t\t * Admin install button label for the or-missing guard.\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\torMissingInstallLabel() {\n\t\t\treturn this.availabilityCopy('app-availability.install', 'Install and enable')\n\t\t},\n\n\t\t/**\n\t\t * Non-admin \"ask your administrator\" copy for the or-missing guard\n\t\t * (REQ-DIA-3), naming the missing app(s).\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\torMissingAskAdmin() {\n\t\t\treturn this.availabilityCopy(\n\t\t\t\t'app-availability.ask-admin',\n\t\t\t\t`Ask your administrator to enable ${this.missingAppsLabel || 'the required app'}.`,\n\t\t\t)\n\t\t},\n\n\t\t/**\n\t\t * Soft-dependency install-action label (app not installed).\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\tsoftDepInstallLabel() {\n\t\t\treturn this.availabilityCopy('app-availability.soft.install', 'Install and enable')\n\t\t},\n\n\t\t/**\n\t\t * Soft-dependency enable-action label (installed but disabled).\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\tsoftDepEnableLabel() {\n\t\t\treturn this.availabilityCopy('app-availability.soft.enable', 'Enable')\n\t\t},\n\n\t\t/**\n\t\t * Soft-dependency dismiss-action label.\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\tsoftDepDismissLabel() {\n\t\t\treturn this.availabilityCopy('app-availability.soft.dismiss', 'Dismiss')\n\t\t},\n\n\t\t/**\n\t\t * Repo target for the built-in feature-request deep link.\n\t\t * Provided to descendants under the `cnFeatureRequestRepo`\n\t\t * inject key. Reads `manifest.nav.featureRequestRepo` when set;\n\t\t * falls back to `ConductionNL/<appId>` — the convention for\n\t\t * every Conduction app on GitHub, which is where DEFAULT_FORGE\n\t\t * points. The fallback used the Codeberg org slug `Conduction`\n\t\t * while the forge default was Codeberg; the forge moved back to\n\t\t * GitHub and this did not, so every app that configures nothing\n\t\t * — which is every app, no fleet manifest sets\n\t\t * `nav.featureRequestRepo` — resolved to a github.com org that\n\t\t * does not exist. Deriving it from `appId` is what keeps this\n\t\t * right per app: no consumer hardcodes its own slug, and an app\n\t\t * whose repo is named differently sets the manifest field.\n\t\t * GitHub resolves repo-name casing, so a lowercase `appId`\n\t\t * reaches a CamelCase repo. Returns empty string when no\n\t\t * `appId` is available (defensive — should never happen since\n\t\t * `appId` is a required prop).\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\tresolvedFeatureRequestRepo() {\n\t\t\tconst explicit = this.manifest?.nav?.featureRequestRepo\n\t\t\tif (typeof explicit === 'string' && explicit.length > 0) {\n\t\t\t\treturn explicit\n\t\t\t}\n\t\t\tif (!this.appId) {\n\t\t\t\treturn ''\n\t\t\t}\n\t\t\treturn `ConductionNL/${this.appId}`\n\t\t},\n\n\t\t/**\n\t\t * Forge config for the built-in feature-request deep link,\n\t\t * provided under the `cnFeatureRequestForge` inject key. Reads\n\t\t * `manifest.nav.forge` and merges it over the Codeberg default,\n\t\t * so a manifest may set just `type` (e.g. back to `github`) or\n\t\t * also `baseUrl` (self-hosted Forgejo/Gitea).\n\t\t *\n\t\t * @return {{type: string, baseUrl: string}}\n\t\t */\n\t\tresolvedFeatureRequestForge() {\n\t\t\tconst cfg = this.manifest?.nav?.forge\n\t\t\treturn { ...DEFAULT_FORGE, ...(cfg && typeof cfg === 'object' ? cfg : {}) }\n\t\t},\n\n\t\tresolvedUserSettingsTitle() {\n\t\t\treturn this.userSettingsTitle || this.translate('User settings')\n\t\t},\n\n\t\t/**\n\t\t * Title for the admin-settings modal. Prop override, else the\n\t\t * translated \"Administration\". Mirrors `resolvedUserSettingsTitle`.\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\tresolvedAdminSettingsTitle() {\n\t\t\treturn this.adminSettingsTitle || this.translate('Administration')\n\t\t},\n\n\t\t/**\n\t\t * Section heading for the walkthrough-replay block in user settings.\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\trestartWalkthroughSectionName() {\n\t\t\treturn this.translate('Walkthrough')\n\t\t},\n\n\t\t/**\n\t\t * Explanatory line above the restart-walkthrough button.\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\trestartWalkthroughHint() {\n\t\t\treturn this.translate('Take the guided tour of this app again.')\n\t\t},\n\n\t\t/**\n\t\t * Label for the restart-walkthrough button in user settings.\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\trestartWalkthroughLabel() {\n\t\t\treturn this.translate('Restart walkthrough')\n\t\t},\n\n\t\t/**\n\t\t * Resolve the active modal's Vue component from the registry.\n\t\t * Returns null when no modal is open or the key no longer resolves.\n\t\t *\n\t\t * @return {object|null}\n\t\t */\n\t\tactiveModalComponent() {\n\t\t\tif (!this.activeModalKey) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst entry = (this.registry || {})[this.activeModalKey]\n\t\t\treturn (entry && entry.component) ? entry.component : null\n\t\t},\n\t},\n\n\twatch: {\n\t\t/**\n\t\t * Close a registry modal when the route changes.\n\t\t *\n\t\t * `cnOpenModal` sets `activeModalKey` and only the modal's own `close`\n\t\t * clears it, so navigating away left the dialog mounted over the new\n\t\t * page — open \"New lead\" on a dashboard, click through to another page,\n\t\t * and the dialog follows you there, still covering the content.\n\t\t */\n\t\t$route() {\n\t\t\tthis.activeModalKey = null\n\t\t},\n\n\t\t/**\n\t\t * Auto-open the non-gating setup wizard once optional-unmet becomes\n\t\t * true, unless the user already dismissed this manifest version.\n\t\t * `immediate: true` so a fresh mount that's already optional-unmet\n\t\t * opens it without waiting for a later reactive change.\n\t\t */\n\t\toptionalSetupPending: {\n\t\t\timmediate: true,\n\t\t\thandler(pending) {\n\t\t\t\tif (pending && !this.isSetupWizardDismissed()) {\n\t\t\t\t\tthis.setupWizardOpen = true\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\n\t\t/**\n\t\t * Resolve the per-user walkthrough completion preference whenever the\n\t\t * declared `completionConfigKey` appears or changes (ADR-043).\n\t\t * `immediate: true` covers the common static-manifest case; the watch\n\t\t * also covers a manifest that arrives asynchronously, where a\n\t\t * mount-time-only read would have found no key and let the tour open\n\t\t * for a user who already finished it.\n\t\t */\n\t\twalkthroughConfigKey: {\n\t\t\timmediate: true,\n\t\t\thandler(key) {\n\t\t\t\tif (!key) {\n\t\t\t\t\tthis.walkthroughSeenResolved = true\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tthis.walkthroughSeenResolved = false\n\t\t\t\tthis.resolveWalkthroughSeenVersion()\n\t\t\t},\n\t\t},\n\n\t\tsetupStatusLoading: {\n\t\t\timmediate: true,\n\t\t\thandler(loading) {\n\t\t\t\tif (!loading) {\n\t\t\t\t\tthis.setupStatusSettled = true\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t},\n\n\tmounted() {\n\t\t// Nested modals: without this every `.modal-mask` in the app shares one\n\t\t// z-index, so two open dialogs tie and the painting order falls back to\n\t\t// DOM order between two nodes teleported to <body> — clicks aimed at the\n\t\t// top dialog get swallowed by the one underneath. Installed on the app\n\t\t// root (not per dialog) because the colliding dialogs are not all ours:\n\t\t// the consuming app's own NcDialogs need the same layering, and\n\t\t// @nextcloud/vue exposes no z-index prop. Reference-counted, so the\n\t\t// nested CnAppRoot in Buildiq's BuilderHost is safe.\n\t\tinstallModalStack()\n\n\t\t// Guard against silently losing unsaved in-app edits. The manifest\n\t\t// editor stays `dirty` for the whole Save (the persist PUT can take a\n\t\t// few seconds), so a refresh mid-save would drop the edit before the\n\t\t// write lands; this warns the user while there are unsaved/in-flight\n\t\t// changes. Registered before the early-return so it always installs.\n\t\twindow.addEventListener('beforeunload', this.onBeforeUnload)\n\n\t\t// Opt-out fast-path: empty `requiresApps` already initialised\n\t\t// `capabilitiesLoading` to `false` in data(); skip the check.\n\t\tif (!Array.isArray(this.requiresApps) || this.requiresApps.length === 0) {\n\t\t\tthis._validateRegistry()\n\t\t\tthis._warnCustomComponentsDeprecation()\n\t\t\tthis._hydrateMenuCounts()\n\t\t\treturn\n\t\t}\n\n\t\ttry {\n\t\t\t// Use useAppStatus which checks OC.appswebroots first — Nextcloud\n\t\t\t// populates that map for every enabled app regardless of which\n\t\t\t// folder it lives in (apps/, custom-apps/, custom_apps/). Falling\n\t\t\t// back to getCapabilities() alone misses apps that do not register\n\t\t\t// an ICapability (OpenRegister being the primary example).\n\t\t\tthis.missingApps = this.requiresApps.filter((id) => {\n\t\t\t\tconst { installed } = useAppStatus(id)\n\t\t\t\treturn !installed.value\n\t\t\t})\n\t\t} catch (err) {\n\t\t\t// eslint-disable-next-line no-console\n\t\t\tconsole.warn(\n\t\t\t\t'[CnAppRoot] Failed to check app availability for the app-availability guard:',\n\t\t\t\terr,\n\t\t\t)\n\t\t\tthis.guardError = err\n\t\t\tthis.missingApps = []\n\t\t} finally {\n\t\t\tthis.capabilitiesLoading = false\n\t\t}\n\n\t\tthis._validateRegistry()\n\t\tthis._warnCustomComponentsDeprecation()\n\t\tthis._hydrateMenuCounts()\n\t},\n\n\tbeforeUnmount() {\n\t\twindow.removeEventListener('beforeunload', this.onBeforeUnload)\n\t\tthis.cnScopedTheme.teardown(this.appId)\n\t\t// Scope the side effect to the shell's lifetime. Layers already written\n\t\t// stay on screen (see `uninstallModalStack`), so a dialog outliving the\n\t\t// shell does not lose its stacking.\n\t\tuninstallModalStack()\n\t},\n\n\tmethods: {\n\t\t/**\n\t\t * Permission gate for an Integrations entry — deliberately identical\n\t\t * to `CnAppNav.passesPermission`, including the \"no permissions prop\n\t\t * means do not filter\" escape. The two surfaces read the same\n\t\t * `menu[]` array, so a rule that held in the nav and not here would\n\t\t * mean an entry's visibility changed purely by being relocated.\n\t\t *\n\t\t * @param {object} item The menu entry.\n\t\t * @return {boolean} True when the entry may render.\n\t\t */\n\t\tpassesIntegrationPermission(item) {\n\t\t\tif (!item.permission) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\tif (!this.permissions || this.permissions.length === 0) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\treturn this.permissions.includes(item.permission)\n\t\t},\n\n\t\t/**\n\t\t * `visibleIf` gate for an Integrations entry, mirroring\n\t\t * `CnAppNav.passesVisibleIf`. `appInstalled` matters more here than\n\t\t * anywhere else in the manifest: it is what stops the section\n\t\t * advertising a link into an app the instance does not have.\n\t\t *\n\t\t * @param {object} item The menu entry.\n\t\t * @return {boolean} True when the entry may render.\n\t\t */\n\t\tpassesIntegrationVisibleIf(item) {\n\t\t\tconst condition = item.visibleIf\n\t\t\tif (!condition || typeof condition !== 'object') {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\tif (condition.appInstalled && !isAppInstalled(condition.appInstalled)) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tconst runtime = (this.manifest && this.manifest.runtime) || null\n\t\t\treturn passesContextPredicates(condition, runtime)\n\t\t},\n\n\t\t/**\n\t\t * Re-fetch the pages editor's register/schema data sources via the\n\t\t * `dataSourcesLoader` prop. Provided to descendants as\n\t\t * `cnRefreshDataSources`; the pages-editor modals call it on open.\n\t\t *\n\t\t * Mutates `dataSourcesState` in place (never reassigns it — see the\n\t\t * stable-identity contract in `data()`). A refresh already in flight\n\t\t * is reused rather than duplicated, so two modals opening at once\n\t\t * issue one fetch. The previous list stays in `value` while a refresh\n\t\t * runs and survives a failure, so the user can keep editing against\n\t\t * the last known-good data instead of an empty dropdown.\n\t\t *\n\t\t * @return {Promise<void>} Resolves when the refresh settles. Never rejects.\n\t\t */\n\t\tasync refreshDataSources() {\n\t\t\tif (typeof this.dataSourcesLoader !== 'function') {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif (this._dataSourcesInFlight) {\n\t\t\t\treturn this._dataSourcesInFlight\n\t\t\t}\n\n\t\t\tthis.dataSourcesState.loading = true\n\t\t\tthis.dataSourcesState.error = null\n\n\t\t\t// Wrapped so a loader that throws synchronously is handled\n\t\t\t// identically to one that returns a rejecting promise.\n\t\t\tthis._dataSourcesInFlight = (async () => {\n\t\t\t\ttry {\n\t\t\t\t\tconst next = await this.dataSourcesLoader()\n\t\t\t\t\tthis.dataSourcesState.value = next || { registers: [] }\n\t\t\t\t} catch (e) {\n\t\t\t\t\tthis.dataSourcesState.error = e\n\t\t\t\t\t// Keep the last good `value` — a failed refresh must not\n\t\t\t\t\t// blank a list the user is mid-edit against.\n\t\t\t\t} finally {\n\t\t\t\t\tthis.dataSourcesState.loading = false\n\t\t\t\t\tthis._dataSourcesInFlight = null\n\t\t\t\t}\n\t\t\t})()\n\n\t\t\treturn this._dataSourcesInFlight\n\t\t},\n\n\t\t/**\n\t\t * Resolve a custom `adminSettings` entry's `component` key against\n\t\t * the same registries `CnBodySections.resolveSectionComponent` /\n\t\t * `CnPageRenderer.resolveCustomComponent` use for slot components:\n\t\t * the v2 `registry` prop (any kind exposing a `.component`) wins,\n\t\t * falling back to the legacy `customComponents` map. Returns `null`\n\t\t * (renders nothing) when neither has the key registered.\n\t\t *\n\t\t * @param {string} key The entry's `component` registry key.\n\t\t * @return {import('vue').Component|null}\n\t\t */\n\t\t/**\n\t\t * Resolve the routed manifest page's `sidebarComponent`.\n\t\t *\n\t\t * Resolved HERE rather than received from `CnPageRenderer`, which is\n\t\t * why the manifest key works at all. The renderer *provides*\n\t\t * `cnPageSidebarComponent` and this component *injects* it — but the\n\t\t * renderer is our descendant, and provide/inject only flows downward,\n\t\t * so that value could never reach this slot. `pages[].sidebarComponent`\n\t\t * was dead config for every app that tried it (#528).\n\t\t *\n\t\t * The route name is the page id (the same match `_hydrateMenuCounts`\n\t\t * uses), and the component name resolves through the same registries\n\t\t * every other slot component uses.\n\t\t *\n\t\t * @return {import('vue').Component|null} The sidebar component, or null.\n\t\t */\n\t\tresolvePageSidebarComponent() {\n\t\t\tconst routeName = this.$route?.name\n\t\t\tif (!routeName) {\n\t\t\t\treturn null\n\t\t\t}\n\n\t\t\tconst page = (this.manifest?.pages ?? []).find((p) => p?.id === routeName)\n\t\t\tif (!page || typeof page.sidebarComponent !== 'string' || page.sidebarComponent === '') {\n\t\t\t\treturn null\n\t\t\t}\n\n\t\t\t// `sidebar.show: false` suppresses the rail entirely, so a page\n\t\t\t// declaring both is contradictory; visibility wins, matching what\n\t\t\t// CnPageRenderer already warns about.\n\t\t\tif (page?.sidebar?.show === false) {\n\t\t\t\treturn null\n\t\t\t}\n\n\t\t\treturn this.resolveAdminSettingsComponent(page.sidebarComponent)\n\t\t},\n\n\t\tresolveAdminSettingsComponent(key) {\n\t\t\tif (typeof key !== 'string' || key === '') {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst reg = (this.registry && this.registry[key]) || null\n\t\t\tif (reg && reg.component) {\n\t\t\t\treturn reg.component\n\t\t\t}\n\t\t\tconst legacy = this.customComponents && this.customComponents[key]\n\t\t\treturn legacy || null\n\t\t},\n\n\t\t/**\n\t\t * Return the translated copy for `key`, or `fallback` when the\n\t\t * `translate` prop leaves the key unchanged (its default is the\n\t\t * identity function and no consumer app defines the\n\t\t * `app-availability.*` keys). Keeps real l10n working for apps that\n\t\t * DO supply the strings while guaranteeing English prose otherwise\n\t\t * (REQ-DIA-7).\n\t\t *\n\t\t * @param {string} key The i18n key.\n\t\t * @param {string} fallback The English default.\n\t\t * @return {string}\n\t\t */\n\t\tavailabilityCopy(key, fallback) {\n\t\t\tconst translated = this.translate(key)\n\t\t\treturn (translated === undefined || translated === null || translated === key)\n\t\t\t\t? fallback\n\t\t\t\t: translated\n\t\t},\n\n\t\t/**\n\t\t * Install-and-enable (or enable) a missing dependency via the shared\n\t\t * `useAppInstaller` (REQ-DIA-3 / REQ-DIA-6). Marks the dependency\n\t\t * busy for the per-button spinner, reloads on success (a freshly\n\t\t * installed app's assets only exist after a full load), and on\n\t\t * failure leaves `depInstallError` set so the store link stays as a\n\t\t * fallback.\n\t\t *\n\t\t * @param {string} id The Nextcloud app id to install/enable.\n\t\t * @return {Promise<void>}\n\t\t */\n\t\tasync installDependency(id) {\n\t\t\tif (!id) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.installingDepId = id\n\t\t\tthis.erroredDepId = null\n\t\t\ttry {\n\t\t\t\tawait this.appInstaller.installAndEnable(id)\n\t\t\t\twindow.location.reload()\n\t\t\t} catch {\n\t\t\t\t// Error is surfaced inline via `depInstallError`; the store\n\t\t\t\t// link remains available as a manual fallback. A cancelled\n\t\t\t\t// password confirmation also lands here (no error text).\n\t\t\t\tthis.erroredDepId = id\n\t\t\t} finally {\n\t\t\t\tthis.installingDepId = null\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Dismiss a soft-dependency banner (REQ-DIA-6). Persists the\n\t\t * dismissal under `cn-soft-dep-dismissed:{appId}:{depId}` and hides\n\t\t * the banner reactively. Independent per dependency.\n\t\t *\n\t\t * @param {string} id The soft dependency's app id.\n\t\t * @return {void}\n\t\t */\n\t\tdismissSoftDep(id) {\n\t\t\ttry {\n\t\t\t\twindow.localStorage.setItem('cn-soft-dep-dismissed:' + this.appId + ':' + id, '1')\n\t\t\t} catch {\n\t\t\t\t// Best-effort persistence (private mode / no storage).\n\t\t\t}\n\t\t\tif (!this.dismissedSoftDeps.includes(id)) {\n\t\t\t\tthis.dismissedSoftDeps.push(id)\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Heading for a soft-dependency banner.\n\t\t *\n\t\t * @param {object} dep The normalised dependency `{ id, name, ... }`.\n\t\t * @return {string}\n\t\t */\n\t\tsoftDepHeading(dep) {\n\t\t\treturn this.availabilityCopy('app-availability.soft.heading', `Optional: ${dep.name}`)\n\t\t},\n\n\t\t/**\n\t\t * Body text for a soft-dependency banner.\n\t\t *\n\t\t * @param {object} dep The normalised dependency `{ id, name, ... }`.\n\t\t * @return {string}\n\t\t */\n\t\tsoftDepText(dep) {\n\t\t\treturn this.availabilityCopy(\n\t\t\t\t'app-availability.soft.description',\n\t\t\t\t`${dep.name} unlocks optional features in this app but is not installed or enabled.`,\n\t\t\t)\n\t\t},\n\n\t\t/**\n\t\t * Non-admin \"ask your administrator\" copy for a soft-dependency\n\t\t * banner.\n\t\t *\n\t\t * @param {object} dep The normalised dependency `{ id, name, ... }`.\n\t\t * @return {string}\n\t\t */\n\t\tsoftDepAskAdmin(dep) {\n\t\t\treturn this.availabilityCopy('app-availability.soft.ask-admin', `Ask your administrator to enable ${dep.name}.`)\n\t\t},\n\n\t\t/**\n\t\t * Warn before unload when the manifest editor has unsaved (or still-\n\t\t * persisting) changes, so a refresh can't silently discard an in-app\n\t\t * edit. No-op when not editing / nothing dirty.\n\t\t *\n\t\t * @param {BeforeUnloadEvent} event The browser beforeunload event.\n\t\t * @return {string|undefined} A non-empty string triggers the native prompt.\n\t\t */\n\t\tonBeforeUnload(event) {\n\t\t\tconst editor = this.manifestEditor\n\t\t\tconst dirtyRef = editor && editor.dirty\n\t\t\tconst dirty = dirtyRef && typeof dirtyRef === 'object' && 'value' in dirtyRef ? dirtyRef.value : dirtyRef\n\t\t\tif (!dirty) {\n\t\t\t\treturn undefined\n\t\t\t}\n\t\t\t// The standard cross-browser incantation to trigger the prompt.\n\t\t\tevent.preventDefault()\n\t\t\tevent.returnValue = ''\n\t\t\treturn ''\n\t\t},\n\n\t\t/**\n\t\t * Re-fetch setup status after the wizard reports completion so the\n\t\t * phase flips from `setup` to `shell` without a page reload.\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\tonSetupComplete() {\n\t\t\t// Finishing counts as dismissal. A user may legitimately reach Finish\n\t\t\t// with an optional step still un-done (Next skips optional steps), and\n\t\t\t// the server keeps reporting it unmet — so without this the wizard\n\t\t\t// auto-opens again on every visit. Cancel must not be the only way to\n\t\t\t// get peace.\n\t\t\tthis.persistSetupWizardDismissal()\n\t\t\tif (this.setupState && typeof this.setupState.refresh === 'function') {\n\t\t\t\tthis.setupState.refresh()\n\t\t\t}\n\t\t\t// NOT closing here: CnSetupWizard has just flipped CnWizardDialog into\n\t\t\t// its result phase (\"Setup complete.\"). Unmounting now would swallow it.\n\t\t\t// The result phase's Close emits `@close` → dismissSetupWizard().\n\t\t\t/**\n\t\t\t * @event setup-complete Emitted after the gating setup wizard reports\n\t\t\t * completion and the status has been re-fetched.\n\t\t\t */\n\t\t\tthis.$emit('setup-complete')\n\t\t},\n\n\t\t/**\n\t\t * Dismiss the non-gating optional-setup wizard (REQ-SETUP-NV-012) and\n\t\t * unmount it.\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\tdismissSetupWizard() {\n\t\t\tthis.persistSetupWizardDismissal()\n\t\t\tthis.setupWizardOpen = false\n\t\t},\n\n\t\t/**\n\t\t * `localStorage` key holding the non-gating setup wizard's dismissal for\n\t\t * the manifest's CURRENT `setup.version`. Read at use time rather than\n\t\t * cached, so an async manifest merge that bumps the version is honoured.\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\tsetupWizardDismissKey() {\n\t\t\tconst version = (this.manifest && this.manifest.setup && this.manifest.setup.version) || 0\n\t\t\treturn 'cn-setup-wizard-dismissed:' + this.appId + ':' + version\n\t\t},\n\n\t\t/**\n\t\t * Whether the non-gating setup wizard has already been dismissed for\n\t\t * this manifest `setup.version` — this session or a previous visit.\n\t\t *\n\t\t * @return {boolean}\n\t\t */\n\t\tisSetupWizardDismissed() {\n\t\t\tif (this.setupWizardDismissed) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\ttry {\n\t\t\t\treturn window.localStorage.getItem(this.setupWizardDismissKey()) === '1'\n\t\t\t} catch {\n\t\t\t\treturn false\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Record the non-gating setup wizard as dismissed for this manifest\n\t\t * `setup.version` so it doesn't auto-open again.\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\tpersistSetupWizardDismissal() {\n\t\t\ttry {\n\t\t\t\twindow.localStorage.setItem(this.setupWizardDismissKey(), '1')\n\t\t\t} catch {\n\t\t\t\t// Best-effort persistence (private mode / no storage).\n\t\t\t}\n\t\t\tthis.setupWizardDismissed = true\n\t\t},\n\n\t\t/**\n\t\t * Resolve the user's last-seen walkthrough version from the per-user\n\t\t * `completionConfigKey` preference before the overlay is allowed to\n\t\t * mount (ADR-043, REQ-WALK-NV-004). Without a declared key the value\n\t\t * seeded synchronously in `data()` is already final.\n\t\t *\n\t\t * Never rejects: an absent endpoint / unauthenticated user falls back to\n\t\t * the localStorage mirror inside the loader.\n\t\t *\n\t\t * @return {Promise<void>}\n\t\t */\n\t\tasync resolveWalkthroughSeenVersion() {\n\t\t\tif (!this.walkthroughEnabled || !this.walkthroughConfigKey) {\n\t\t\t\tthis.walkthroughSeenResolved = true\n\t\t\t\treturn\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tthis.walkthroughSeenVersionValue = await loadWalkthroughSeenVersion(\n\t\t\t\t\tthis.appId,\n\t\t\t\t\tthis.walkthroughConfigKey,\n\t\t\t\t)\n\t\t\t} finally {\n\t\t\t\tthis.walkthroughSeenResolved = true\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Persist the current app version as the user's last-seen walkthrough\n\t\t * version (so an upgrade later surfaces only newer steps) and notify.\n\t\t *\n\t\t * Writes BOTH the localStorage mirror and — when the manifest declares\n\t\t * `walkthrough.completionConfigKey` — the per-user preference the load\n\t\t * path reads, so completing or dismissing the tour actually sticks for\n\t\t * that user instead of re-opening on the next visit.\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\tonWalkthroughComplete() {\n\t\t\tconst v = normaliseSeenVersion((this.manifest && this.manifest.version) || '1.0.0')\n\t\t\tthis.walkthroughSeenVersionValue = v\n\t\t\tthis.walkthroughSeenResolved = true\n\t\t\t// Fire-and-forget: the loader never rejects and the local mirror is\n\t\t\t// already written, so a failed PUT must not surface as an error.\n\t\t\tpersistWalkthroughSeenVersion(this.appId, this.walkthroughConfigKey, v)\n\t\t\t/**\n\t\t\t * @event walkthrough-complete Emitted when the walkthrough finishes or is dismissed.\n\t\t\t */\n\t\t\tthis.$emit('walkthrough-complete')\n\t\t},\n\n\t\t/**\n\t\t * Replay the product tour from the user-settings dialog. Closes the\n\t\t * dialog first, then restarts the first declared tour on the next tick\n\t\t * — the modal must finish unmounting before the tour overlay paints, or\n\t\t * the spotlight anchors against the closing modal. Mirrors the\n\t\t * `cnReplayWalkthrough` provide method (same useWalkthrough cache, so\n\t\t * the rendered CnWalkthrough genuinely re-fires).\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\trestartWalkthroughFromSettings() {\n\t\t\tthis.userSettingsOpen = false\n\t\t\tif (!this.walkthroughEnabled) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\t// 50ms lets the dialog's close animation settle so the tour\n\t\t\t// re-appears cleanly over the app shell, not the closing modal.\n\t\t\tsetTimeout(() => {\n\t\t\t\tconst id = this.manifest.walkthrough.tours[0] && this.manifest.walkthrough.tours[0].id\n\t\t\t\tif (id) {\n\t\t\t\t\tuseWalkthrough(this.appId, this.manifest).restart(id)\n\t\t\t\t}\n\t\t\t}, 50)\n\t\t},\n\n\t\t/**\n\t\t * Validate every entry in the `registry` prop at mount time.\n\t\t *\n\t\t * - Unknown `kind` throws `RegistryKindError` (hard error; developer\n\t\t * must fix the registration).\n\t\t * - Known `kind` with missing required metadata emits `console.warn`\n\t\t * (soft error; the widget still renders with defaults).\n\t\t */\n\t\t_validateRegistry() {\n\t\t\tconst registry = this.registry || {}\n\t\t\tfor (const [key, entry] of Object.entries(registry)) {\n\t\t\t\tif (!entry || typeof entry !== 'object') {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\tconst kind = entry.kind\n\n\t\t\t\tif (!KNOWN_REGISTRY_KINDS.includes(kind)) {\n\t\t\t\t\tthrow new RegistryKindError(key, kind)\n\t\t\t\t}\n\n\t\t\t\tconst requiredFields = REGISTRY_KIND_REQUIRED_FIELDS[kind]\n\t\t\t\tfor (const field of requiredFields) {\n\t\t\t\t\tif (!Object.hasOwn(entry, field)) {\n\t\t\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\t\t\tconsole.warn(`[CnAppRoot] Registry entry \"${key}\" (kind: \"${kind}\") is missing required metadata field \"${field}\".`)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Emit a single console.warn per mount when both a non-empty\n\t\t * customComponents prop AND a v2 manifest are present.\n\t\t *\n\t\t * Uses an instance flag `_customComponentsWarnedOnce` to prevent\n\t\t * repeat warnings on re-render.\n\t\t */\n\t\t_warnCustomComponentsDeprecation() {\n\t\t\tif (this._customComponentsWarnedOnce) {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tconst hasCustomComponents = this.customComponents\n\t\t\t\t&& typeof this.customComponents === 'object'\n\t\t\t\t&& Object.keys(this.customComponents).length > 0\n\n\t\t\tconst isV2Manifest = this.manifest\n\t\t\t\t&& typeof this.manifest.$schema === 'string'\n\t\t\t\t&& this.manifest.$schema.includes('app-manifest-v2')\n\n\t\t\tif (hasCustomComponents && isV2Manifest) {\n\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\tconsole.warn('CnAppRoot: `customComponents` prop is deprecated when using v2 manifests. '\n\t\t\t\t\t+ 'Use the `registry` prop instead (see ADR-036).')\n\t\t\t\tthis._customComponentsWarnedOnce = true\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Scan the manifest for `count: \"auto\"` menu entries (top-level\n\t\t * AND nested children) AND `count: \"auto\"` `nav-card-grid` widget\n\t\t * entries (`pages[].widgets[]`, ADR-044 §4 cards-collapse), and\n\t\t * hydrate `this.cnMenuCounts` from\n\t\t * `useObjectStore().getPagination(slug).total` for each unique\n\t\t * `(register, schema)` pair whose resolved page is `type: \"index\"`.\n\t\t *\n\t\t * The `nav-card-grid` walk exists because `applyMenuRemovals`\n\t\t * deletes a cards-collapse group's former leaf items from `menu`\n\t\t * entirely once they're relocated into a card page — without this\n\t\t * second walk, `cnMenuCounts` would never contain the\n\t\t * register/schema pairs those cards need, and their\n\t\t * `count: \"auto\"` would silently show no badge even though the\n\t\t * underlying data exists.\n\t\t *\n\t\t * Triggers one `fetchCollection(slug, { _limit: 1 })` per pair so\n\t\t * the store's pagination cache is warmed. Subsequent CnIndexPage\n\t\t * mounts reuse the same store entry (no extra round-trip).\n\t\t *\n\t\t * Failures are non-fatal — missing Pinia (no `pinia` plugin\n\t\t * installed on the Vue instance), unregistered type slugs, or\n\t\t * network errors all degrade gracefully to \"no badge\".\n\t\t *\n\t\t * @return {void}\n\t\t * @private\n\t\t */\n\t\t_hydrateMenuCounts() {\n\t\t\tconst menu = this.manifest?.menu ?? []\n\t\t\tconst pages = this.manifest?.pages ?? []\n\n\t\t\tconst collectAutoTargets = (items) => {\n\t\t\t\tconst targets = []\n\t\t\t\tfor (const item of items ?? []) {\n\t\t\t\t\tif (item?.count === 'auto' && item?.route) {\n\t\t\t\t\t\tconst page = pages.find((p) => p.id === item.route)\n\t\t\t\t\t\tif (page?.type === 'index' && page?.config?.register && page?.config?.schema) {\n\t\t\t\t\t\t\ttargets.push({ register: page.config.register, schema: page.config.schema })\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif (Array.isArray(item?.children)) {\n\t\t\t\t\t\ttargets.push(...collectAutoTargets(item.children))\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn targets\n\t\t\t}\n\n\t\t\t/**\n\t\t\t * Collect `(register, schema)` targets from every `nav-card-grid`\n\t\t\t * widget's `props.entries[]` across all pages, for entries\n\t\t\t * declaring `count: \"auto\"` with a `route` resolving to an\n\t\t\t * index page.\n\t\t\t *\n\t\t\t * @return {Array<{register: string, schema: string}>}\n\t\t\t */\n\t\t\tconst collectNavCardGridTargets = () => {\n\t\t\t\tconst targets = []\n\t\t\t\tfor (const page of pages) {\n\t\t\t\t\tfor (const widget of page?.widgets ?? []) {\n\t\t\t\t\t\tif (widget?.widgetKey !== 'nav-card-grid') {\n\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfor (const entry of widget?.props?.entries ?? []) {\n\t\t\t\t\t\t\tif (entry?.count !== 'auto' || !entry?.route) {\n\t\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tconst target = pages.find((p) => p.id === entry.route)\n\t\t\t\t\t\t\tif (target?.type === 'index' && target?.config?.register && target?.config?.schema) {\n\t\t\t\t\t\t\t\ttargets.push({ register: target.config.register, schema: target.config.schema })\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn targets\n\t\t\t}\n\n\t\t\tconst pairs = [...collectAutoTargets(menu), ...collectNavCardGridTargets()]\n\t\t\tif (pairs.length === 0) {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// De-duplicate by (register, schema).\n\t\t\tconst seen = new Set()\n\t\t\tconst uniquePairs = []\n\t\t\tfor (const pair of pairs) {\n\t\t\t\tconst key = `${pair.register}|${pair.schema}`\n\t\t\t\tif (seen.has(key)) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tseen.add(key)\n\t\t\t\tuniquePairs.push(pair)\n\t\t\t}\n\n\t\t\t// Prefer ONE batched round-trip (audit item 26): shillinq's nav\n\t\t\t// alone hits ~dozens of unique (register, schema) pairs, each of\n\t\t\t// which was a separate `?_limit=1` request at boot. On an\n\t\t\t// OpenRegister without the batch route (404) or any error, fall\n\t\t\t// back to the per-entry store path below so badges still render.\n\t\t\tthis._hydrateMenuCountsBatched(uniquePairs).catch(() => {\n\t\t\t\tthis._hydrateMenuCountsPerEntry(uniquePairs)\n\t\t\t})\n\t\t},\n\n\t\t/**\n\t\t * Hydrate all menu counts with a single `POST /api/objects/counts`\n\t\t * (OpenRegister batched-counts endpoint). Distributes each returned\n\t\t * count into the reactive `cnMenuCounts` map. Rejects (so the caller\n\t\t * falls back) on a non-2xx status, a missing/404 route, or a malformed\n\t\t * response — never leaving a half-populated batch masquerading as done.\n\t\t *\n\t\t * @param {Array<{register: string, schema: string}>} uniquePairs Deduped pairs.\n\t\t * @return {Promise<void>}\n\t\t * @private\n\t\t */\n\t\tasync _hydrateMenuCountsBatched(uniquePairs) {\n\t\t\tconst url = generateUrl('/apps/openregister/api/objects/counts')\n\t\t\tconst { data } = await axios.post(url, {\n\t\t\t\tcounts: uniquePairs.map(({ register, schema }) => ({ register, schema })),\n\t\t\t})\n\t\t\tconst results = data?.results\n\t\t\tif (!Array.isArray(results)) {\n\t\t\t\tthrow new Error('batched counts: malformed response')\n\t\t\t}\n\t\t\tfor (const result of results) {\n\t\t\t\tconst { register, schema, count } = result ?? {}\n\t\t\t\tif (typeof count !== 'number' || count < 0) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tif (!this.cnMenuCounts[register]) {\n\t\t\t\t\tthis.cnMenuCounts[register] = {}\n\t\t\t\t}\n\t\t\t\tthis.cnMenuCounts[register][schema] = count\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Legacy per-entry hydration: one `?_limit=1` store fetch per pair.\n\t\t * The pre-batch behaviour, retained verbatim as the fallback for an\n\t\t * OpenRegister without the batch route.\n\t\t *\n\t\t * @param {Array<{register: string, schema: string}>} uniquePairs Deduped pairs.\n\t\t * @return {void}\n\t\t * @private\n\t\t */\n\t\t_hydrateMenuCountsPerEntry(uniquePairs) {\n\t\t\tlet store\n\t\t\ttry {\n\t\t\t\tstore = useObjectStore()\n\t\t\t} catch {\n\t\t\t\t// No Pinia plugin installed (tests, isolated mounts) —\n\t\t\t\t// silently skip; CnAppNav renders no badge.\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif (!store) {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tfor (const { register, schema } of uniquePairs) {\n\t\t\t\tconst slug = `${register}-${schema}`\n\t\t\t\tthis._fetchAndCacheCount(store, slug, register, schema)\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Fire-and-forget count fetch + cache writer. Registers the type\n\t\t * with the store on demand (so the consuming app doesn't need to\n\t\t * pre-register every counted slug), issues a `?_limit=1` index\n\t\t * fetch, and writes the resulting `total` into `cnMenuCounts`.\n\t\t *\n\t\t * Errors are swallowed so a single broken endpoint cannot blank\n\t\t * the entire navigation. The most common failure modes\n\t\t * (unregistered type, network error, store unavailable) all leave\n\t\t * the badge unrendered — which is the documented fallback.\n\t\t *\n\t\t * @param {object} store The `useObjectStore()` result.\n\t\t * @param {string} slug The store's type slug (`${register}-${schema}`).\n\t\t * @param {string} register OpenRegister register slug.\n\t\t * @param {string} schema OpenRegister schema slug.\n\t\t * @return {Promise<void>}\n\t\t * @private\n\t\t */\n\t\tasync _fetchAndCacheCount(store, slug, register, schema) {\n\t\t\ttry {\n\t\t\t\tif (typeof store.registerObjectType === 'function'\n\t\t\t\t\t&& (!store.objectTypeRegistry || !store.objectTypeRegistry[slug])) {\n\t\t\t\t\tstore.registerObjectType(slug, schema, register)\n\t\t\t\t}\n\t\t\t\tif (typeof store.fetchCollection === 'function') {\n\t\t\t\t\tawait store.fetchCollection(slug, { _limit: 1 })\n\t\t\t\t}\n\t\t\t\tconst pagination = typeof store.getPagination === 'function'\n\t\t\t\t\t? store.getPagination(slug)\n\t\t\t\t\t: null\n\t\t\t\tconst total = pagination?.total\n\t\t\t\tif (typeof total === 'number' && total >= 0) {\n\t\t\t\t\tif (!this.cnMenuCounts[register]) {\n\t\t\t\t\t\tthis.cnMenuCounts[register] = {}\n\t\t\t\t\t}\n\t\t\t\t\tthis.cnMenuCounts[register][schema] = total\n\t\t\t\t}\n\t\t\t} catch {\n\t\t\t\t// Non-fatal — leave the badge unrendered.\n\t\t\t}\n\t\t},\n\t},\n}\n</script>\n\n<style>\n.cn-app-root__capabilities-loading {\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\twidth: 100%;\n\tmin-height: 100vh;\n\tbackground: var(--color-main-background);\n}\n\n.cn-app-root__or-missing {\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\twidth: 100%;\n\tmin-height: 100vh;\n\tbackground: var(--color-main-background);\n\tcolor: var(--color-main-text);\n}\n\n.cn-app-root__or-missing-action {\n\tdisplay: inline-block;\n\tpadding: calc(1.5 * var(--default-grid-baseline)) calc(3 * var(--default-grid-baseline));\n\tborder-radius: var(--border-radius);\n\tbackground: var(--color-primary-element);\n\tcolor: var(--color-primary-element-text);\n\ttext-decoration: none;\n}\n\n.cn-app-root__or-missing-action:hover,\n.cn-app-root__or-missing-action:focus {\n\tbackground: var(--color-primary-element-hover);\n\ttext-decoration: underline;\n}\n\n.cn-app-root__walkthrough-hint {\n\tmargin-bottom: 12px;\n\tcolor: var(--color-text-maxcontrast);\n}\n\n.cn-app-root__integrations-hint {\n\tmargin-bottom: 12px;\n\tcolor: var(--color-text-maxcontrast);\n}\n\n.cn-app-root__integrations {\n\tdisplay: flex;\n\tflex-direction: column;\n\talign-items: flex-start;\n\tgap: calc(0.5 * var(--default-grid-baseline));\n\tmargin: 0;\n\tpadding: 0;\n\tlist-style: none;\n}\n\n.cn-app-root__or-missing-error {\n\tmargin: calc(2 * var(--default-grid-baseline)) 0 calc(1 * var(--default-grid-baseline));\n\tcolor: var(--color-error);\n}\n\n.cn-app-root__or-missing-ask-admin {\n\tcolor: var(--color-text-maxcontrast);\n}\n\n.cn-app-root__soft-dep {\n\tmargin: calc(2 * var(--default-grid-baseline));\n}\n\n.cn-app-root__soft-dep-body {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: var(--default-grid-baseline);\n}\n\n.cn-app-root__soft-dep-actions {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: calc(2 * var(--default-grid-baseline));\n\tflex-wrap: wrap;\n}\n\n.cn-app-root__soft-dep-ask-admin {\n\tcolor: var(--color-text-maxcontrast);\n}\n\n.cn-app-root__soft-dep-error {\n\tmargin: 0;\n\tcolor: var(--color-error);\n}\n</style>\n"],"names":["CnAppNav","CnAppLoading","CnDependencyMissing","CnSetupWizard","CnWalkthrough","CnAiCompanion","CnCommandPalette","CnObjectSidebar","CnSupportDialog","CnNotificationPreferences","CnCredentials","CnTenantBadge","axios"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"CnAppRoot.vue2.js","sources":["../../../../src/components/CnAppRoot/CnAppRoot.vue"],"sourcesContent":["<!--\n CnAppRoot — top-level wrapper for manifest-driven Conduction apps.\n\n Provides the manifest, custom-component registry, and translate\n function to descendants via Vue's `provide`/`inject`. Orchestrates\n four rendering phases:\n\n 0. Capabilities — checks the Nextcloud capabilities API for any\n app id listed in `requiresApps` (default\n `['openregister']`). When a required app is\n missing, default content is <NcEmptyContent>\n with an OR-store action; consumers may replace\n the surface entirely via the #or-missing slot.\n Apps that do not need the guard pass\n `:requires-apps=\"[]\"`.\n 1. Loading — while useAppManifest.isLoading is true.\n Default: <CnAppLoading />. Override: #loading slot.\n 2. Dependency — after loading; when any entry in\n manifest.dependencies is not installed/enabled.\n Default: <CnDependencyMissing />. Override:\n #dependency-missing slot.\n 3. Shell — manifest loaded + dependencies satisfied.\n Renders #menu (default <CnAppNav />) + the\n consuming app's <router-view>, plus optional\n #header-actions, #sidebar, and #footer slots.\n\n Consuming apps that want manifest-driven pages but their own root\n layout can skip CnAppRoot entirely and use CnPageRenderer / CnAppNav\n with explicit props (the props-vs-inject fallback). CnAppRoot is the\n full-shell convenience.\n\n Hosts a per-user `NcAppSettingsDialog` that any descendant can open\n via the injected `cnOpenUserSettings()` method. CnAppNav binds the\n inject to manifest entries with `action: \"user-settings\"`. Apps\n populate the modal by passing `NcAppSettingsSection`s into the\n `#user-settings` slot; the slot falls back to a single placeholder\n section when no content is supplied.\n\n A SECOND, distinct `NcAppSettingsDialog` hosts admin-only, app-level\n (not per-user) settings, driven GENERICALLY by `manifest.adminSettings[]`\n (sorted by `order`) — one `NcAppSettingsSection` per entry. The built-in\n `type: \"organisation-credentials\"` renders the organisation credential\n broker (`CnCredentials scope=\"organisation\"`); a `component` entry\n resolves from the `customComponents` registry, forwarding `props`. Any\n descendant opens the dialog via the injected `cnOpenAdminSettings()`\n method; CnAppNav auto-prepends an \"Admin settings\" entry (visible only\n to app OWNERS — `currentUserGroups` ∩ `permissions.owners`, or a\n `runtime.user` owner signal; NOT `OC.isUserAdmin()`) that opens it, and\n also binds manifest entries with `action: \"admin-settings\"`. An app\n with no (or empty) `adminSettings` mounts no admin dialog and no admin\n nav entry at all — the org-credentials pane is no longer hardcoded;\n apps declare it explicitly as one `adminSettings` entry. Apps can still\n populate it via the `#admin-settings` slot (which overrides the\n generic render entirely).\n\n See REQ-JMR-003 and REQ-JMR-013 of the json-manifest-renderer spec,\n and REQ-OR-1..REQ-OR-7 of the cnapproot-app-availability-guard spec.\n-->\n<template>\n\t<NcContent :appName=\"appDisplayName || (manifest && manifest.name) || appId\" :data-nldesign-theme-scope=\"appId\" data-testid=\"cn-app-root\">\n\t\t<!-- Phase 0a: capabilities check in flight -->\n\t\t<template v-if=\"capabilitiesLoading\">\n\t\t\t<div class=\"cn-app-root__capabilities-loading\" data-testid=\"cn-app-root-capabilities-loading\">\n\t\t\t\t<NcLoadingIcon :size=\"32\" />\n\t\t\t</div>\n\t\t</template>\n\n\t\t<!--\n\t\t @slot or-missing\n\t\t @description Custom missing-app screen used when one or more\n\t\t entries in `requiresApps` are absent from the Nextcloud\n\t\t capabilities payload. Receives `{ missingApps: string[] }`.\n\t\t Default content: an `<NcEmptyContent>` with the OpenRegister\n\t\t database icon, i18n title/description, and a primary action\n\t\t linking to the OpenRegister integration page. Override when\n\t\t the consumer needs a custom CTA (e.g. softwarecatalog linking\n\t\t to its public landing page). See REQ-OR-4.\n\t\t-->\n\t\t<template v-else-if=\"missingApps.length > 0\">\n\t\t\t<slot name=\"or-missing\" :missingApps=\"missingApps\">\n\t\t\t\t<div class=\"cn-app-root__or-missing\">\n\t\t\t\t\t<NcEmptyContent\n\t\t\t\t\t\t:name=\"orMissingTitle\"\n\t\t\t\t\t\t:description=\"orMissingDescription\">\n\t\t\t\t\t\t<template #icon>\n\t\t\t\t\t\t\t<DatabaseSearchOutline :size=\"64\" />\n\t\t\t\t\t\t</template>\n\t\t\t\t\t\t<template #action>\n\t\t\t\t\t\t\t<!--\n\t\t\t\t\t\t\t Admin: one click installs-and-enables (or enables)\n\t\t\t\t\t\t\t the missing app via Nextcloud's own settings/apps/\n\t\t\t\t\t\t\t enable endpoint, then reloads. On failure the error\n\t\t\t\t\t\t\t shows inline and the store link stays as a fallback\n\t\t\t\t\t\t\t (REQ-DIA-3).\n\t\t\t\t\t\t\t-->\n\t\t\t\t\t\t\t<template v-if=\"isAdmin\">\n\t\t\t\t\t\t\t\t<NcButton\n\t\t\t\t\t\t\t\t\tvariant=\"primary\"\n\t\t\t\t\t\t\t\t\tdata-testid=\"cn-app-root-or-missing-install\"\n\t\t\t\t\t\t\t\t\t:disabled=\"depInstalling\"\n\t\t\t\t\t\t\t\t\t@click=\"installDependency(orMissingPrimaryApp)\">\n\t\t\t\t\t\t\t\t\t<template #icon>\n\t\t\t\t\t\t\t\t\t\t<NcLoadingIcon v-if=\"depInstalling\" :size=\"20\" />\n\t\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t\t\t{{ orMissingInstallLabel }}\n\t\t\t\t\t\t\t\t</NcButton>\n\t\t\t\t\t\t\t\t<p v-if=\"depInstallError\" class=\"cn-app-root__or-missing-error\">\n\t\t\t\t\t\t\t\t\t{{ depInstallError }}\n\t\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t\t\t<a\n\t\t\t\t\t\t\t\t\tv-if=\"depInstallError\"\n\t\t\t\t\t\t\t\t\tclass=\"cn-app-root__or-missing-action\"\n\t\t\t\t\t\t\t\t\t:href=\"orStoreLink\">\n\t\t\t\t\t\t\t\t\t{{ orMissingActionLabel }}\n\t\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t<!--\n\t\t\t\t\t\t\t Non-admin: no dead-end link they cannot act on —\n\t\t\t\t\t\t\t point them at their administrator instead (REQ-DIA-3).\n\t\t\t\t\t\t\t-->\n\t\t\t\t\t\t\t<p v-else class=\"cn-app-root__or-missing-ask-admin\" data-testid=\"cn-app-root-or-missing-ask-admin\">\n\t\t\t\t\t\t\t\t{{ orMissingAskAdmin }}\n\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t</template>\n\t\t\t\t\t</NcEmptyContent>\n\t\t\t\t</div>\n\t\t\t</slot>\n\t\t</template>\n\n\t\t<!--\n\t\t @slot loading\n\t\t @description Loading screen rendered while the manifest\n\t\t fetch is in flight (REQ-JMR-013). Default content is a\n\t\t `<CnAppLoading />` brand spinner. Override when the consumer\n\t\t needs a custom skeleton or branded loader.\n\t\t-->\n\t\t<template v-else-if=\"phase === 'loading'\">\n\t\t\t<slot name=\"loading\">\n\t\t\t\t<CnAppLoading />\n\t\t\t</slot>\n\t\t</template>\n\n\t\t<!--\n\t\t @slot dependency-missing\n\t\t @description Empty-state surface rendered when one or more\n\t\t entries in `manifest.dependencies` are not installed/enabled.\n\t\t Receives `{ dependencies }` (the unresolved list). Default:\n\t\t `<CnDependencyMissing>`. See REQ-JMR-011.\n\t\t-->\n\t\t<template v-else-if=\"phase === 'dependency-missing'\">\n\t\t\t<slot name=\"dependency-missing\" :dependencies=\"unresolvedHardDependencies\">\n\t\t\t\t<CnDependencyMissing\n\t\t\t\t\t:dependencies=\"unresolvedHardDependencies\"\n\t\t\t\t\t:appName=\"appId\" />\n\t\t\t</slot>\n\t\t</template>\n\n\t\t<!--\n\t\t Phase 2b: setup — a REQUIRED first-time-setup step (ADR-042) is unmet,\n\t\t so the shell is gated to CnSetupWizard until it clears.\n\t\t-->\n\t\t<template v-else-if=\"phase === 'setup'\">\n\t\t\t<!--\n\t\t\t @slot setup\n\t\t\t @description Override the gating setup surface. Scope: the manifest\n\t\t\t setup steps + the useSetupStatus state.\n\t\t\t-->\n\t\t\t<slot name=\"setup\" :steps=\"manifest.setup.steps\" :status=\"setupState\">\n\t\t\t\t<div class=\"cn-app-root__setup\">\n\t\t\t\t\t<CnSetupWizard\n\t\t\t\t\t\t:appId=\"appId\"\n\t\t\t\t\t\t:appName=\"appDisplayName || (manifest && manifest.name) || appId\"\n\t\t\t\t\t\t:steps=\"manifest.setup.steps\"\n\t\t\t\t\t\t:cancellable=\"false\"\n\t\t\t\t\t\t:completedStepIds=\"setupCompletedStepIds\"\n\t\t\t\t\t\t@complete=\"onSetupComplete\" />\n\t\t\t\t</div>\n\t\t\t</slot>\n\t\t</template>\n\n\t\t<!-- Phase 3: shell -->\n\t\t<template v-else>\n\t\t\t<!--\n\t\t\t @slot menu\n\t\t\t @description Left-rail navigation surface. Default:\n\t\t\t `<CnAppNav>` reading `manifest.menu` and filtering by\n\t\t\t `permissions`. Override to ship a hand-rolled menu while\n\t\t\t keeping the rest of CnAppRoot's shell.\n\n\t\t\t An override that wraps `CnAppNav` MUST forward these bindings.\n\t\t\t The slot used to carry none, so a wrapper could only pass\n\t\t\t `manifest`, and `isAdmin` silently defaulted to false: the\n\t\t\t Admin-settings entry then rendered for nobody, on apps whose\n\t\t\t whole admin surface lives behind it. Openregister shipped that\n\t\t\t way until its own e2e caught it.\n\t\t\t-->\n\t\t\t<!-- @binding {object} manifest The menu manifest, after page-derived entries are merged. -->\n\t\t\t<!-- @binding {object} permissions Permission map used to filter menu entries. -->\n\t\t\t<!-- @binding {boolean} isOwner Whether the user owns this app (ADR-079 §3). -->\n\t\t\t<!-- @binding {boolean} isAdmin Whether the user administers the instance; gates the Admin-settings link. -->\n\t\t\t<!-- @binding {string} appId The app id used to build the Admin-settings target. -->\n\t\t\t<slot name=\"menu\"\n\t\t\t\t:manifest=\"menuManifest\"\n\t\t\t\t:permissions=\"permissions\"\n\t\t\t\t:isOwner=\"isOwner\"\n\t\t\t\t:isAdmin=\"isAdmin\"\n\t\t\t\t:appId=\"appId\">\n\t\t\t\t<CnAppNav :manifest=\"menuManifest\"\n\t\t\t\t\t:permissions=\"permissions\"\n\t\t\t\t\t:isOwner=\"isOwner\"\n\t\t\t\t\t:isAdmin=\"isAdmin\"\n\t\t\t\t\t:appId=\"appId\" />\n\t\t\t</slot>\n\t\t\t<NcAppContent>\n\t\t\t\t<!--\n\t\t\t\t Soft-dependency notices (REQ-DIA-6) — DEPRECATED, off by\n\t\t\t\t default since 2.1.0.\n\n\t\t\t\t These stacked. An app declaring four optional leaves rendered\n\t\t\t\t four orange NcNoteCards above its own content and pushed the\n\t\t\t\t page below the fold, every page load, for every user — while\n\t\t\t\t the only person who can act on the message is an\n\t\t\t\t administrator. The information now lives where that audience\n\t\t\t\t is: `CnLeafDependencySettings`, an admin-settings section\n\t\t\t\t carrying the same two states (not installed → \"Install and\n\t\t\t\t enable\"; installed but disabled → \"Enable\").\n\n\t\t\t\t The markup stays behind `softDependencyNotices` for one\n\t\t\t\t release so a consumer that genuinely needs the in-app surface\n\t\t\t\t can opt back in while it adopts the settings section. It is\n\t\t\t\t slated for removal.\n\t\t\t\t-->\n\t\t\t\t<NcNoteCard\n\t\t\t\t\tv-for=\"dep in visibleSoftDependencyNotices\"\n\t\t\t\t\t:key=\"'cn-soft-dep-' + dep.id\"\n\t\t\t\t\ttype=\"warning\"\n\t\t\t\t\t:heading=\"softDepHeading(dep)\"\n\t\t\t\t\tclass=\"cn-app-root__soft-dep\"\n\t\t\t\t\t:data-testid=\"'cn-app-root-soft-dep-' + dep.id\">\n\t\t\t\t\t<div class=\"cn-app-root__soft-dep-body\">\n\t\t\t\t\t\t<p class=\"cn-app-root__soft-dep-text\">\n\t\t\t\t\t\t\t{{ softDepText(dep) }}\n\t\t\t\t\t\t</p>\n\t\t\t\t\t\t<div class=\"cn-app-root__soft-dep-actions\">\n\t\t\t\t\t\t\t<NcButton\n\t\t\t\t\t\t\t\tv-if=\"isAdmin\"\n\t\t\t\t\t\t\t\tvariant=\"secondary\"\n\t\t\t\t\t\t\t\t:data-testid=\"'cn-app-root-soft-dep-install-' + dep.id\"\n\t\t\t\t\t\t\t\t:disabled=\"depInstalling\"\n\t\t\t\t\t\t\t\t@click=\"installDependency(dep.id)\">\n\t\t\t\t\t\t\t\t<template #icon>\n\t\t\t\t\t\t\t\t\t<NcLoadingIcon v-if=\"depInstalling && installingDepId === dep.id\" :size=\"20\" />\n\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t\t{{ dep.enabled === false ? softDepEnableLabel : softDepInstallLabel }}\n\t\t\t\t\t\t\t</NcButton>\n\t\t\t\t\t\t\t<span v-else class=\"cn-app-root__soft-dep-ask-admin\">\n\t\t\t\t\t\t\t\t{{ softDepAskAdmin(dep) }}\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t<NcButton\n\t\t\t\t\t\t\t\tvariant=\"tertiary\"\n\t\t\t\t\t\t\t\t:data-testid=\"'cn-app-root-soft-dep-dismiss-' + dep.id\"\n\t\t\t\t\t\t\t\t@click=\"dismissSoftDep(dep.id)\">\n\t\t\t\t\t\t\t\t{{ softDepDismissLabel }}\n\t\t\t\t\t\t\t</NcButton>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<p v-if=\"depInstallError && erroredDepId === dep.id\" class=\"cn-app-root__soft-dep-error\">\n\t\t\t\t\t\t\t{{ depInstallError }}\n\t\t\t\t\t\t</p>\n\t\t\t\t\t</div>\n\t\t\t\t</NcNoteCard>\n\t\t\t\t<!--\n\t\t\t\t In-app edit shell (ADR-041). The Conduction-orange Buildiq edit\n\t\t\t\t button is rendered INSIDE each page's action row (CnDashboardPage /\n\t\t\t\t CnDetailPage / CnIndexPage) — it self-wires from the `cnManifestEditor`\n\t\t\t\t and `cnOpenBuildAvailable` this component provides, so it sits inline\n\t\t\t\t with the page's normal buttons rather than as a floating overlay.\n\t\t\t\t-->\n\t\t\t\t<router-view :key=\"routerViewKey\" />\n\t\t\t\t<!--\n\t\t\t\t @slot tenant-badge\n\t\t\t\t @description Top-bar tenant indicator surface\n\t\t\t\t (multi-tenancy-context REQ-MT-4). Default:\n\t\t\t\t <CnTenantBadge /> — auto-hides when the user has 0–1\n\t\t\t\t organisations. Override to suppress entirely\n\t\t\t\t (`<template #tenant-badge></template>`) or to render\n\t\t\t\t a custom multi-tenant switcher.\n\t\t\t\t-->\n\t\t\t\t<slot name=\"tenant-badge\">\n\t\t\t\t\t<CnTenantBadge />\n\t\t\t\t</slot>\n\t\t\t\t<!--\n\t\t\t\t @slot header-actions\n\t\t\t\t @description Optional action buttons rendered in the\n\t\t\t\t page header alongside the router-view. Empty by\n\t\t\t\t default; consumer apps fill it with toolbar buttons.\n\t\t\t\t-->\n\t\t\t\t<slot name=\"header-actions\" />\n\t\t\t\t<!--\n\t\t\t\t @slot footer\n\t\t\t\t @description Optional footer surface rendered below the\n\t\t\t\t router-view inside `NcAppContent`. Empty by default.\n\t\t\t\t-->\n\t\t\t\t<slot name=\"footer\" />\n\t\t\t</NcAppContent>\n\t\t\t<!--\n\t\t\t Sidebar slot — gated by the `cnPageSidebarVisible` inject\n\t\t\t provided by `CnPageRenderer`. When the current manifest\n\t\t\t page declares `sidebar.show: false` (sibling of `config`),\n\t\t\t the renderer flips the holder's `.value` to `false` and\n\t\t\t the slot stops rendering. The default holder value (used\n\t\t\t when no `CnPageRenderer` ancestor exists) is `true`, so\n\t\t\t apps that mount their own page components without the\n\t\t\t renderer keep rendering the slot exactly as today.\n\n\t\t\t Default content: when `cnPageSidebarComponent.value` is a\n\t\t\t Vue component (set by the renderer when the current page\n\t\t\t declares a `sidebarComponent` registry name), it renders\n\t\t\t here as the slot's DEFAULT content. The consumer's\n\t\t\t `#sidebar` slot override (when supplied) wins via Vue's\n\t\t\t standard slot mechanic; the resolved component is the\n\t\t\t fallback. See manifest-named-view-sidebar spec.\n\t\t\t-->\n\t\t\t<!--\n\t\t\t @slot sidebar\n\t\t\t @description Right-rail sidebar surface. Gated by the\n\t\t\t `cnPageSidebarVisible` inject (provided by `CnPageRenderer`)\n\t\t\t so manifest pages can suppress the sidebar via\n\t\t\t `pages[].sidebar.show: false`. Default content: when\n\t\t\t `cnPageSidebarComponent.value` is set (provided by\n\t\t\t `CnPageRenderer` for `pages[].sidebarComponent`), that\n\t\t\t component renders here; otherwise empty.\n\n\t\t\t Consumer-supplied slot content wins over the resolved\n\t\t\t component, because Vue only falls back when the slot is\n\t\t\t ABSENT. An app that fills this slot unconditionally therefore\n\t\t\t SUPPRESSES `pages[].sidebarComponent` silently: no warning,\n\t\t\t no error, just no sidebar. That is why the resolved component\n\t\t\t is exposed as the `pageSidebarComponent` slot prop. An app\n\t\t\t with its own rail should render both:\n\n\t\t\t <template #sidebar=\"{ pageSidebarComponent }\">\n\t\t\t <MyOwnSidebar />\n\t\t\t <component :is=\"pageSidebarComponent\" v-if=\"pageSidebarComponent\" />\n\t\t\t </template>\n\t\t\t-->\n\t\t\t<!-- eslint-disable-next-line vue/attribute-hyphenation -- on a <slot>, the attribute IS the scoped-slot prop's key: hyphenating it would rename `pageSidebarComponent` for every consumer destructuring this slot -->\n\t\t\t<slot v-if=\"cnPageSidebarVisible.value !== false\" name=\"sidebar\" :pageSidebarComponent=\"pageSidebarComponent\">\n\t\t\t\t<component\n\t\t\t\t\t:is=\"pageSidebarComponent\"\n\t\t\t\t\tv-if=\"pageSidebarComponent\" />\n\t\t\t</slot>\n\t\t\t<!--\n\t\t\t Hoisted index-page sidebar. CnIndexPage publishes its\n\t\t\t embedded CnIndexSidebar config (component + props +\n\t\t\t listeners) into the `cnIndexSidebarConfig` holder so it\n\t\t\t mounts at NcContent level — the only place where Nextcloud's\n\t\t\t NcAppSidebar slides correctly from the right. Rendering\n\t\t\t alongside the consumer's `#sidebar` slot is safe because\n\t\t\t the embedded sidebar only sets the holder when the page is\n\t\t\t an index AND `sidebar.enabled !== false`; detail-page\n\t\t\t sidebars (CnObjectSidebar) keep owning the slot.\n\t\t\t-->\n\t\t\t<component\n\t\t\t\t:is=\"cnIndexSidebarConfig.value.component\"\n\t\t\t\tv-if=\"cnIndexSidebarConfig.value\"\n\t\t\t\tv-bind=\"cnIndexSidebarConfig.value.props\"\n\t\t\t\tv-on=\"cnIndexSidebarConfig.value.listeners\" />\n\n\t\t\t<!--\n\t\t\t Hoisted object-sidebar. CnDetailPage writes into the\n\t\t\t provided `objectSidebarState` holder to publish its\n\t\t\t schema-driven sidebar (Files / Notes / Tags / Tasks /\n\t\t\t Audit) at NcContent level — same ADR-017 reason as the\n\t\t\t hoisted index sidebar above. The auto-mount is suppressed\n\t\t\t when:\n\t\t\t - the consumer fills the `#sidebar` slot (their sidebar\n\t\t\t keeps owning the slot); or\n\t\t\t - an ancestor already provides `objectSidebarState` (the\n\t\t\t ancestor renders its own sidebar, e.g. decidesk's host\n\t\t\t wrapper); or\n\t\t\t - `objectType` + `objectId` are empty (defense-in-depth\n\t\t\t against CnIndexPage's `inject('sidebarState') ??\n\t\t\t inject('objectSidebarState')` fallback leaking an\n\t\t\t `active: true` write into this channel — see\n\t\t\t CnAppRootObjectSidebar.spec.js).\n\t\t\t-->\n\t\t\t<CnObjectSidebar\n\t\t\t\tv-if=\"shouldAutoMountObjectSidebar\"\n\t\t\t\t:open=\"effectiveObjectSidebarState.open === true\"\n\t\t\t\t:tabs=\"effectiveObjectSidebarState.tabs\"\n\t\t\t\t:useRegistry=\"objectSidebarUseRegistry\"\n\t\t\t\t:objectType=\"effectiveObjectSidebarState.objectType\"\n\t\t\t\t:objectId=\"effectiveObjectSidebarState.objectId\"\n\t\t\t\t:objectData=\"effectiveObjectSidebarState.object\"\n\t\t\t\t:objectSchema=\"effectiveObjectSidebarState.schemaObject\"\n\t\t\t\t:register=\"effectiveObjectSidebarState.register\"\n\t\t\t\t:schema=\"effectiveObjectSidebarState.schema\"\n\t\t\t\t:title=\"effectiveObjectSidebarState.title\"\n\t\t\t\t:subtitle=\"effectiveObjectSidebarState.subtitle\"\n\t\t\t\t:hiddenTabs=\"effectiveObjectSidebarState.hiddenTabs\"\n\t\t\t\t:requestedTab=\"effectiveObjectSidebarState.requestedTab\"\n\t\t\t\t@update:open=\"effectiveObjectSidebarState.open = $event\" />\n\n\t\t\t<!--\n\t\t\t AI Chat Companion — auto-mounted at the END of NcContent's\n\t\t\t children so its embedded NcAppSidebar slides in from the right\n\t\t\t edge (positioning relies on being the last NcContent sibling,\n\t\t\t same trick the hoisted index-page sidebar above uses).\n\t\t\t Gating (health probe, pageKind overrides) happens inside the\n\t\t\t component; app opt-in is via the `aiCompanion` prop (default off).\n\t\t\t-->\n\t\t\t<CnAiCompanion v-if=\"aiCompanion\" :chatAppId=\"chatAppId\" />\n\n\t\t\t<!--\n\t\t\t Non-gating setup wizard (REQ-SETUP-NV-012 optional path). Shown\n\t\t\t when every required setup step is met but an optional one isn't;\n\t\t\t auto-opens once per manifest `setup.version` and stays dismissible\n\t\t\t (Cancel/ESC/backdrop) — unlike the gating phase 2b instance above.\n\t\t\t-->\n\t\t\t<div v-if=\"setupWizardOpen\" class=\"cn-app-root__setup-optional\">\n\t\t\t\t<CnSetupWizard\n\t\t\t\t\t:appId=\"appId\"\n\t\t\t\t\t:appName=\"appDisplayName || (manifest && manifest.name) || appId\"\n\t\t\t\t\t:steps=\"manifest.setup.steps\"\n\t\t\t\t\t:cancellable=\"true\"\n\t\t\t\t\t:completedStepIds=\"setupCompletedStepIds\"\n\t\t\t\t\t@complete=\"onSetupComplete\"\n\t\t\t\t\t@close=\"dismissSetupWizard\" />\n\t\t\t</div>\n\n\t\t\t<!--\n\t\t\t Command palette (Ctrl/Cmd+K) — auto-mounted, opt-in via the\n\t\t\t `commandPalette` prop (default off). Zero-config navigation\n\t\t\t source from `manifest.menu`; the \"objects\" live-search source\n\t\t\t is wired by passing `commandPalette: { objectSearch: ... }`\n\t\t\t (see `createObjectSearchSource`). Actions register themselves\n\t\t\t via `useCommandPalette().register(...)` from anywhere in the\n\t\t\t app — no additional wiring here.\n\t\t\t-->\n\t\t\t<CnCommandPalette\n\t\t\t\tv-if=\"cnCommandPaletteVisible\"\n\t\t\t\t:manifest=\"manifest\"\n\t\t\t\t:router=\"$router\"\n\t\t\t\t:appId=\"appId\"\n\t\t\t\tv-bind=\"cnCommandPaletteOverrides\" />\n\n\t\t\t<!--\n\t\t\t Support note — auto-mounted on first open per the fleet\n\t\t\t support-dialog rollout. Deriving slug/name/URLs from `appId`\n\t\t\t by convention means apps gain it on a lib bump with no\n\t\t\t per-app wiring; pass `:support-dialog=\"false\"` to opt out or\n\t\t\t an object to override copy/URLs. Persistence is per-user\n\t\t\t (server preferences endpoint) with a localStorage fallback.\n\t\t\t-->\n\t\t\t<!--\n\t\t\t Waits for the setup status: until it loads the shell renders\n\t\t\t provisionally, and a required unmet step then swaps it for the\n\t\t\t wizard, unmounting the dialog mid-transition (NcModal's focus trap\n\t\t\t then throws on its missing mask).\n\t\t\t-->\n\t\t\t<CnSupportDialog\n\t\t\t\tv-if=\"cnSupportVisible && setupStatusSettled\"\n\t\t\t\t:appName=\"cnSupportAppName\"\n\t\t\t\t:appSlug=\"appId\"\n\t\t\t\t:appStoreUrl=\"cnSupportAppStoreUrl\"\n\t\t\t\t:featureRequestUrl=\"cnSupportFeatureRequestUrl\"\n\t\t\t\tv-bind=\"cnSupportOverrides\"\n\t\t\t\t@close=\"cnSupportHide\" />\n\t\t\t<!--\n\t\t\t Product walkthrough (ADR-043) — a non-gating spotlight tour\n\t\t\t auto-mounted over the live shell. Reads `manifest.walkthrough` and\n\t\t\t auto-starts a tour that qualifies for the user's app version. No\n\t\t\t per-app wiring; declare a `walkthrough` block to opt in.\n\t\t\t-->\n\t\t\t<!--\n\t\t\t Gated on `walkthroughSeenResolved` as well: when the manifest\n\t\t\t declares `walkthrough.completionConfigKey`, the per-user\n\t\t\t preference is fetched first so a returning user never sees the\n\t\t\t tour flash open before the answer arrives. Without a key the\n\t\t\t flag is already true at data() time (localStorage-only, sync).\n\n\t\t\t Also withheld while the first-open support note is on screen\n\t\t\t (`cnSupportVisible`): a fresh user qualifies for BOTH, and two\n\t\t\t stacked overlays fight for the same first moment. The tour's\n\t\t\t machine state lives in the per-app useWalkthrough cache, so\n\t\t\t unmounting here only hides the overlay — when the note is\n\t\t\t dismissed the walkthrough remounts and the first-visit tour\n\t\t\t starts (or resumes) then. `!== true` keeps apps that opted out\n\t\t\t of the support note (`cnSupportVisible` undefined) unaffected.\n\n\t\t\t Withheld the same way while the setup status is still loading\n\t\t\t and while the non-gating setup wizard is open\n\t\t\t (`walkthroughHeldForSetup`). On a first run the wizard and the\n\t\t\t first-visit tour both qualify; the tour used to open behind the\n\t\t\t wizard, and its window-level ESC listener meant closing the\n\t\t\t wizard with ESC also dismissed the tour and recorded it as seen.\n\t\t\t Held back, the tour is never mounted, so nothing is recorded; it\n\t\t\t starts when the wizard is dismissed or finished.\n\t\t\t-->\n\t\t\t<!-- @slot walkthrough Override the gating-free walkthrough overlay. Scope: { manifest, seenVersion }. -->\n\t\t\t<slot v-if=\"walkthroughEnabled && walkthroughSeenResolved && cnSupportVisible !== true && !walkthroughHeldForSetup\"\n\t\t\t\tname=\"walkthrough\"\n\t\t\t\t:manifest=\"manifest\"\n\t\t\t\t:seenVersion=\"walkthroughSeenVersion\">\n\t\t\t\t<CnWalkthrough\n\t\t\t\t\t:appId=\"appId\"\n\t\t\t\t\t:manifest=\"manifest\"\n\t\t\t\t\t:seenVersion=\"walkthroughSeenVersion\"\n\t\t\t\t\t:resume=\"walkthroughResume\"\n\t\t\t\t\t:translate=\"translate\"\n\t\t\t\t\t@complete=\"onWalkthroughComplete\"\n\t\t\t\t\t@dismiss=\"onWalkthroughComplete\" />\n\t\t\t</slot>\n\t\t\t<!--\n\t\t\t User-settings modal. Always mounted so descendants can\n\t\t\t open it via the `cnOpenUserSettings` inject (CnAppNav\n\t\t\t wires this to manifest entries with\n\t\t\t `action: \"user-settings\"`). The `#user-settings` slot\n\t\t\t hosts NcAppSettingsSection children; the placeholder\n\t\t\t fallback below renders when no slot content is supplied.\n\t\t\t-->\n\t\t\t<NcAppSettingsDialog\n\t\t\t\t:open=\"userSettingsOpen\"\n\t\t\t\t:showNavigation=\"true\"\n\t\t\t\t:name=\"resolvedUserSettingsTitle\"\n\t\t\t\t@update:open=\"userSettingsOpen = $event\">\n\t\t\t\t<!-- @slot user-settings Sections rendered inside the host NcAppSettingsDialog. Pass NcAppSettingsSection children. Defaults to the notification-preferences pane when omitted. -->\n\t\t\t\t<slot name=\"user-settings\">\n\t\t\t\t\t<CnNotificationPreferences v-if=\"userSettingsOpen\" />\n\t\t\t\t\t<!--\n\t\t\t\t\t\tCredential broker (OpenRegister). Lets the user manage the\n\t\t\t\t\t\tsecrets OR holds on their behalf; apps call external providers\n\t\t\t\t\t\tthrough OR without ever seeing the secret. The app's manifest\n\t\t\t\t\t\t`credentials[]` declarations drive the informational \"Apps\n\t\t\t\t\t\trequesting credentials\" list.\n\t\t\t\t\t-->\n\t\t\t\t\t<NcAppSettingsSection v-if=\"userSettingsOpen\"\n\t\t\t\t\t\tid=\"credentials\"\n\t\t\t\t\t\t:name=\"translate('Credentials')\">\n\t\t\t\t\t\t<CnCredentials\n\t\t\t\t\t\t\tscope=\"personal\"\n\t\t\t\t\t\t\t:appId=\"appId\"\n\t\t\t\t\t\t\t:appName=\"appDisplayName || (manifest && manifest.name) || appId\"\n\t\t\t\t\t\t\t:appCredentials=\"(manifest && manifest.credentials) || []\" />\n\t\t\t\t\t</NcAppSettingsSection>\n\t\t\t\t\t<!--\n\t\t\t\t\t\tSelf-service walkthrough replay (ADR-043). Only mounts\n\t\t\t\t\t\twhen the manifest declares an enabled tour, so apps\n\t\t\t\t\t\twithout a walkthrough never show an empty section.\n\t\t\t\t\t-->\n\t\t\t\t\t<NcAppSettingsSection v-if=\"walkthroughEnabled\"\n\t\t\t\t\t\tid=\"cn-walkthrough\"\n\t\t\t\t\t\t:name=\"restartWalkthroughSectionName\">\n\t\t\t\t\t\t<p class=\"cn-app-root__walkthrough-hint\">\n\t\t\t\t\t\t\t{{ restartWalkthroughHint }}\n\t\t\t\t\t\t</p>\n\t\t\t\t\t\t<NcButton variant=\"secondary\" @click=\"restartWalkthroughFromSettings\">\n\t\t\t\t\t\t\t<template #icon>\n\t\t\t\t\t\t\t\t<Restart :size=\"20\" />\n\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t{{ restartWalkthroughLabel }}\n\t\t\t\t\t\t</NcButton>\n\t\t\t\t\t</NcAppSettingsSection>\n\t\t\t\t</slot>\n\t\t\t\t<!--\n\t\t\t\t\tIntegrations (ADR-110) — the links that leave this app for\n\t\t\t\t\tanother one, gathered out of the navigation into one place.\n\n\t\t\t\t\tDELIBERATELY OUTSIDE the #user-settings slot. Six fleet apps\n\t\t\t\t\toverride that slot, and anything placed inside the default\n\t\t\t\t\tfallback disappears the moment an app supplies its own\n\t\t\t\t\tcontent — silently, because an unmatched slot renders nothing\n\t\t\t\t\tand reports nothing. A contract every app is supposed to\n\t\t\t\t\thonour cannot live somewhere six apps switch off by accident.\n\n\t\t\t\t\tRenders nothing when the app declares no integration\n\t\t\t\t\tentries, so apps without any never show an empty section.\n\t\t\t\t-->\n\t\t\t\t<NcAppSettingsSection v-if=\"userSettingsOpen && integrationEntries.length\"\n\t\t\t\t\tid=\"cn-integrations\"\n\t\t\t\t\t:name=\"translate('Integrations')\">\n\t\t\t\t\t<p class=\"cn-app-root__integrations-hint\">\n\t\t\t\t\t\t{{ translate('These open in another app.') }}\n\t\t\t\t\t</p>\n\t\t\t\t\t<ul class=\"cn-app-root__integrations\">\n\t\t\t\t\t\t<li v-for=\"entry in integrationEntries\" :key=\"entry.id\">\n\t\t\t\t\t\t\t<!--\n\t\t\t\t\t\t\t\tOne uniform external-link icon rather than the\n\t\t\t\t\t\t\t\tentry's own: every row here goes to a different\n\t\t\t\t\t\t\t\tapp, which is the thing worth signalling, and\n\t\t\t\t\t\t\t\tCnIcon falls back to a question mark for any\n\t\t\t\t\t\t\t\tname an app has not registered — a broken-looking\n\t\t\t\t\t\t\t\tglyph on a link that works fine.\n\t\t\t\t\t\t\t-->\n\t\t\t\t\t\t\t<NcButton variant=\"tertiary\"\n\t\t\t\t\t\t\t\t:href=\"entry.href\"\n\t\t\t\t\t\t\t\t:aria-label=\"entry.label\">\n\t\t\t\t\t\t\t\t<template #icon>\n\t\t\t\t\t\t\t\t\t<OpenInNew :size=\"20\" />\n\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t\t{{ entry.label }}\n\t\t\t\t\t\t\t</NcButton>\n\t\t\t\t\t\t</li>\n\t\t\t\t\t</ul>\n\t\t\t\t</NcAppSettingsSection>\n\t\t\t</NcAppSettingsDialog>\n\n\t\t\t<!--\n\t\t\t ADR-079 Step 2: the generic admin-settings modal has been REMOVED.\n\n\t\t\t It rendered `manifest.adminSettings[]` behind an app-OWNERSHIP gate.\n\t\t\t No app in the fleet ever declared that array, so the surface was\n\t\t\t unreachable everywhere — and its one real payload, the organisation\n\t\t\t credential broker, was unreachable with it. The broker now lives on\n\t\t\t the app's Nextcloud admin page via CnAdminSettingsShell's\n\t\t\t `show-organisation-credentials` prop, where the access decision is\n\t\t\t made SERVER-SIDE for /settings/admin/<app> rather than by a\n\t\t\t client-side ownership flag.\n\t\t\t-->\n\n\t\t\t<!--\n\t\t\t V2 registry modal — mounted when cnOpenModal(key, props) is\n\t\t\t called by the actions dispatcher. The resolved component is\n\t\t\t whatever was registered under that key in the `registry` prop.\n\t\t\t Closes by setting activeModalKey to null.\n\t\t\t-->\n\t\t\t<component\n\t\t\t\t:is=\"activeModalComponent\"\n\t\t\t\tv-if=\"activeModalComponent\"\n\t\t\t\tv-bind=\"activeModalProps\"\n\t\t\t\t@close=\"activeModalKey = null\"\n\t\t\t\t@update:open=\"activeModalKey = null\" />\n\t\t</template>\n\t</NcContent>\n</template>\n\n<script>\nimport { getCurrentUser } from '@nextcloud/auth'\nimport axios from '@nextcloud/axios'\nimport { loadState } from '@nextcloud/initial-state'\nimport { generateUrl } from '@nextcloud/router'\nimport { NcAppContent, NcAppSettingsDialog, NcAppSettingsSection, NcButton, NcContent, NcEmptyContent, NcLoadingIcon, NcNoteCard } from '@nextcloud/vue'\nimport { computed, reactive, shallowRef, watch } from 'vue'\nimport DatabaseSearchOutline from 'vue-material-design-icons/DatabaseSearchOutline.vue'\nimport OpenInNew from 'vue-material-design-icons/OpenInNew.vue'\nimport Restart from 'vue-material-design-icons/Restart.vue'\nimport CnAiCompanion from '../CnAiCompanion/CnAiCompanion.vue'\nimport CnAppLoading from '../CnAppLoading/CnAppLoading.vue'\nimport CnAppNav from '../CnAppNav/CnAppNav.vue'\nimport CnCommandPalette from '../CnCommandPalette/CnCommandPalette.vue'\nimport CnCredentials from '../CnCredentials/CnCredentials.vue'\nimport CnDependencyMissing from '../CnDependencyMissing/CnDependencyMissing.vue'\nimport CnNotificationPreferences from '../CnNotificationPreferences/CnNotificationPreferences.vue'\nimport CnObjectSidebar from '../CnObjectSidebar/CnObjectSidebar.vue'\nimport CnSetupWizard from '../CnSetupWizard/CnSetupWizard.vue'\nimport CnSupportDialog from '../CnSupportDialog/CnSupportDialog.vue'\nimport CnTenantBadge from '../CnTenantBadge/CnTenantBadge.vue'\nimport CnWalkthrough from '../CnWalkthrough/CnWalkthrough.vue'\nimport { DEFAULT_CHAT_APP_ID } from '../../composables/aiChatConfig.js'\nimport { useAppInstaller } from '../../composables/useAppInstaller.js'\nimport { useAppStatus } from '../../composables/useAppStatus.js'\nimport { useBuildiqEditAvailability } from '../../composables/useBuildiqEditAvailability.js'\nimport { useManifestEditor } from '../../composables/useManifestEditor.js'\nimport { useScopedTheme } from '../../composables/useScopedTheme.js'\nimport { useSetupStatus } from '../../composables/useSetupStatus.js'\nimport { useSupportDialog } from '../../composables/useSupportDialog.js'\nimport { provideTenantContext } from '../../composables/useTenantContext.js'\nimport { useUserPreferences } from '../../composables/useUserPreferences.js'\nimport {\n\tloadWalkthroughSeenVersion,\n\tnormaliseSeenVersion,\n\tpersistWalkthroughSeenVersion,\n\treadLocalWalkthroughSeenVersion,\n\tuseWalkthrough,\n} from '../../composables/useWalkthrough.js'\nimport { RegistryKindError } from '../../errors/RegistryKindError.js'\nimport { useObjectStore } from '../../store/index.js'\nimport { isAppInstalled } from '../../utils/appInstalled.js'\nimport { BUILT_IN_FORMATTERS } from '../../utils/builtInFormatters.js'\nimport { DEFAULT_FORGE, resolveForge } from '../../utils/forge.js'\nimport { BUILT_IN_KB_PROVIDERS } from '../../utils/kbSearchProviders.js'\nimport { installModalStack, uninstallModalStack } from '../../utils/modalStack.js'\nimport { passesContextPredicates } from '../../utils/visibleIfContext.js'\n\n/**\n * Recognised registry kinds and their required metadata fields.\n * An empty array means no additional fields are required beyond `component`.\n */\nconst REGISTRY_KIND_REQUIRED_FIELDS = {\n\twidget: ['defaultSize', 'minSize', 'maxSize', 'allowedSlots', 'propsSchema'],\n\tmodal: ['propsSchema'],\n\tpage: [],\n\t'form-field': ['appliesTo'],\n\t'cell-renderer': ['appliesTo'],\n\t// Slot-component kinds: a registered component mounted into a named page\n\t// slot (CnPageRenderer resolves these by registry name, independent of\n\t// `kind`). `header`/`actions` back the `headerComponent`/`actionsComponent`\n\t// manifest sugar; `tab` backs `config.sidebarTabs[].component`; `section`\n\t// backs `config.bodyWidgets[].component` (rendered into a `section:*` slot).\n\t// They carry no required metadata (like `page`) — listing them here keeps the\n\t// mount-time registry validator from rejecting a valid slot registration.\n\theader: [],\n\tactions: [],\n\ttab: [],\n\t// In-body section component (CnDetailPage `config.bodyWidgets[].component`,\n\t// reusable by dashboard/index). Resolved by registry name and rendered as a\n\t// titled card IN THE PAGE BODY with the object/page context injected. Unlike\n\t// an integration `widget`, a `section` requires NO sidebar tab and carries no\n\t// grid metadata — it sits wherever the page's `placement` puts it.\n\tsection: [],\n\t// Named behaviour: a plain function (exposed as `.handler` / `.fn`) that a\n\t// manifest names from `actions[].handler`, `bulkActions[].handler` or\n\t// `headerActions[].handler`. Resolved by name through\n\t// `resolveRegisteredHandler`, never mounted, so it carries no component and\n\t// no metadata — the registry home for what used to live in the legacy\n\t// `customComponents` map as a bare function.\n\thandler: [],\n\t// Create-override handler: a plain async function (exposed as `.handler` /\n\t// `.fn`) that CnPageRenderer resolves for CnIndexPage's `createOverride`\n\t// prop so a declarative `type:\"index\"` page can route its generic Add\n\t// through an app-specific create flow. Carries no component/metadata — it is\n\t// resolved by name, not mounted — so it lists no required fields (like\n\t// `page`); listing it here keeps the mount-time validator from rejecting a\n\t// valid handler registration.\n\t'create-override': [],\n}\n\nconst KNOWN_REGISTRY_KINDS = Object.keys(REGISTRY_KIND_REQUIRED_FIELDS)\n\n/**\n * Default URL for the OpenRegister integration page. The empty-state\n * action links here so users can install / enable OpenRegister with one\n * click. Override per-environment by replacing the default empty-state\n * via the `#or-missing` slot.\n */\nconst OR_STORE_LINK = '/index.php/settings/apps/integration/openregister'\n\nexport default {\n\tname: 'CnAppRoot',\n\n\tcomponents: {\n\t\tNcAppContent,\n\t\tNcAppSettingsDialog,\n\t\tNcAppSettingsSection,\n\t\tNcButton,\n\t\tNcContent,\n\t\tNcEmptyContent,\n\t\tNcLoadingIcon,\n\t\tNcNoteCard,\n\t\tDatabaseSearchOutline,\n\t\tOpenInNew,\n\t\tRestart,\n\t\tCnAppNav,\n\t\tCnAppLoading,\n\t\tCnDependencyMissing,\n\t\tCnSetupWizard,\n\t\tCnWalkthrough,\n\t\tCnAiCompanion,\n\t\tCnCommandPalette,\n\t\tCnObjectSidebar,\n\t\tCnSupportDialog,\n\t\tCnNotificationPreferences,\n\t\tCnCredentials,\n\t\tCnTenantBadge,\n\t},\n\n\t/**\n\t * What every descendant of this app shell can reach: the manifest,\n\t * the registries, and this person's own preferences.\n\t *\n\t * @spec openspec/changes/case-page-and-list-as-a-place/specs/index-page/spec.md\n\t */\n\tprovide() {\n\t\t// `self` is load-bearing: the returned object exposes `cnManifest` as a\n\t\t// GETTER, and inside a getter on that literal `this` is the literal —\n\t\t// not the component. A getter is what keeps the provide reactive, and a\n\t\t// getter cannot be an arrow function, so the alias is the only way to\n\t\t// reach the instance from inside it.\n\t\t// eslint-disable-next-line @typescript-eslint/no-this-alias\n\t\tconst self = this\n\t\treturn {\n\t\t\t// In-app editing (ADR-041): descendants read the editor's `source`\n\t\t\t// — the working copy while editing, the live manifest otherwise. A\n\t\t\t// getter so it stays reactive despite provide() running once; when\n\t\t\t// not editing it returns the live manifest, identical to before.\n\t\t\tget cnManifest() {\n\t\t\t\treturn self.manifestEditor ? self.manifestEditor.source.value : self.manifest\n\t\t\t},\n\n\t\t\t// The per-user preference reader and writer, so any descendant can\n\t\t\t// hold something against THIS person rather than against the\n\t\t\t// records. A getter for the same reason as cnManifest above: the\n\t\t\t// group is built from the manifest's `personalisation` block, and\n\t\t\t// provide() runs once while the manifest arrives later.\n\t\t\tget cnUserPreferences() {\n\t\t\t\treturn self.userPreferences\n\t\t\t},\n\n\t\t\t// The same manifest as a REF. The getter above is NOT enough on its\n\t\t\t// own: Options-API `inject` resolves a provided value once, at the\n\t\t\t// descendant's creation, so a renderer created before edit mode gets\n\t\t\t// the pre-edit manifest and never re-derives from an in-app edit —\n\t\t\t// which is why adding a widget to a page that had none appeared to do\n\t\t\t// nothing. `inject` unwraps a ref into a reactive getter instead.\n\t\t\tcnManifestSource: this.manifestEditor ? this.manifestEditor.source : null,\n\t\t\tcnManifestEditor: this.manifestEditor,\n\t\t\t// App registers/schemas for the in-app pages editor (index/detail\n\t\t\t// data source). Plain value (not a getter) so deep descendants —\n\t\t\t// the page-tree rows under the edit button — resolve it reliably.\n\t\t\t// Being a plain value is also why it goes stale: provide() runs\n\t\t\t// once, so this can never reflect a schema created after boot.\n\t\t\t// Kept as-is for backwards compatibility; `cnDataSourcesState`\n\t\t\t// below is the live path, and descendants prefer it.\n\t\t\tcnDataSources: this.dataSources,\n\t\t\t// Live data sources for the pages editor. Provided BY REFERENCE —\n\t\t\t// the holder's identity never changes, only its fields — so the\n\t\t\t// one-shot provide() still sees every update. Descendants resolve\n\t\t\t// `cnDataSourcesState.value ?? cnDataSources`.\n\t\t\tcnDataSourcesState: this.dataSourcesState,\n\t\t\t// Re-fetch the data sources via `dataSourcesLoader`. The pages-editor\n\t\t\t// modals call this on open. No-op when no loader is configured.\n\t\t\tcnRefreshDataSources: this.refreshDataSources,\n\t\t\t// Provided as the raw refs (not getters): Vue 2 inject resolves plain\n\t\t\t// provided properties at any depth, but getter-defined provide\n\t\t\t// properties don't reliably reach deep descendants (e.g. the edit\n\t\t\t// button under a page component). Descendants unwrap with `.value`.\n\t\t\t// The inject KEY keeps its `cnOpenBuildAvailable` spelling on purpose:\n\t\t\t// consumer apps may already inject it, so the 2026-08-21 OpenBuild →\n\t\t\t// Buildiq rename deliberately left this runtime contract untouched.\n\t\t\tcnOpenBuildAvailable: this.buildiqAvailable,\n\t\t\tcnEditingBody: this.manifestEditor ? this.manifestEditor.editing : false,\n\t\t\t// Page-level permission enforcement. The manifest schema has carried\n\t\t\t// `pages[].permission` as SCHEMA-ONLY since it was added — \"consumers\n\t\t\t// that want enforcement filter the manifest themselves\" — and no\n\t\t\t// consumer did, so a page declaring it was hidden from the menu and\n\t\t\t// served to anyone who typed its URL. dossiq's Integrations page\n\t\t\t// answered a non-admin with seven links into admin settings.\n\t\t\t//\n\t\t\t// A getter, so it tracks the prop rather than freezing at the single\n\t\t\t// provide() call, and normalised to an array here so every descendant\n\t\t\t// reads one shape.\n\t\t\tget cnPermissions() {\n\t\t\t\treturn Array.isArray(self.permissions) ? self.permissions : []\n\t\t\t},\n\n\t\t\tcnCustomComponents: this.customComponents,\n\t\t\tcnTranslate: this.translate,\n\t\t\tcnPageTypes: this.pageTypes,\n\t\t\tcnFormatters: { ...BUILT_IN_FORMATTERS, ...this.formatters },\n\t\t\tcnCellWidgets: this.cellWidgets,\n\t\t\t// Pluggable kb-search providers (#91 Wave 3): library built-ins\n\t\t\t// (`default`) merged UNDER the consumer registry — the same\n\t\t\t// last-wins spread as cnFormatters. CnKbSearchWidget resolves\n\t\t\t// `content.provider` against this.\n\t\t\tcnKbSearchProviders: { ...BUILT_IN_KB_PROVIDERS, ...this.kbSearchProviders },\n\t\t\t/**\n\t\t\t * V2 component registry. Provided to all descendants so\n\t\t\t * CnWidgetGrid and CnPageRenderer can resolve widget keys.\n\t\t\t * The registry prop is passed by reference — mutations\n\t\t\t * after mount are NOT tracked; consumers should mount with\n\t\t\t * the complete registry.\n\t\t\t */\n\t\t\tcnRegistry: this.registry,\n\t\t\t/**\n\t\t\t * Open a modal registered in the v2 registry. Used by\n\t\t\t * the actions dispatcher to open modals declared in the\n\t\t\t * manifest's `actions[]` array. Validates `kind === \"modal\"`\n\t\t\t * before delegating to the `cnModalKey` reactive holder.\n\t\t\t *\n\t\t\t * @param {string} key The registry key of the modal to open.\n\t\t\t * @param {object} props Props forwarded to the modal component.\n\t\t\t */\n\t\t\tcnOpenModal: (key, props = {}) => {\n\t\t\t\tconst entry = this.registry[key]\n\t\t\t\tif (!entry || entry.kind !== 'modal') {\n\t\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\t\tconsole.warn(`[CnAppRoot] cnOpenModal: \"${key}\" is not a registered modal (kind must be \"modal\").`)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tthis.activeModalKey = key\n\t\t\t\tthis.activeModalProps = props\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * Open the host app's NcAppSettingsDialog. Bound to\n\t\t\t * `this` so descendants don't have to. Used by CnAppNav\n\t\t\t * to dispatch `action: \"user-settings\"` clicks; consumer\n\t\t\t * apps can also call it directly via inject for custom\n\t\t\t * triggers (e.g. an avatar-menu entry).\n\t\t\t */\n\t\t\tcnOpenUserSettings: () => {\n\t\t\t\tthis.userSettingsOpen = true\n\t\t\t},\n\t\t\t/**\n\t\t\t * Open the host app's admin-settings NcAppSettingsDialog —\n\t\t\t * the app-level (not per-user) surface introduced to hold\n\t\t\t * the organisation credential broker out of the personal\n\t\t\t * settings modal. Bound to `this` so descendants don't have\n\t\t\t * to. Used by CnAppNav to dispatch the auto-prepended \"Admin\n\t\t\t * settings\" entry (admins only) and `action:\n\t\t\t * \"admin-settings\"` manifest entries; consumer apps can also\n\t\t\t * call it directly via inject for custom triggers.\n\t\t\t */\n\n\t\t\t/**\n\t\t\t * Restart entry for the product walkthrough (ADR-043). Descendants\n\t\t\t * (a menu/settings \"Replay walkthrough\" entry, or a manifest menu\n\t\t\t * `action: \"replay-walkthrough\"`) call this to re-run a tour. With no\n\t\t\t * `tourId` the first declared tour is used.\n\t\t\t *\n\t\t\t * @param {string} [tourId] The tour to restart.\n\t\t\t * @return {void}\n\t\t\t */\n\t\t\tcnReplayWalkthrough: (tourId) => {\n\t\t\t\tif (!this.walkthroughEnabled) {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tconst wt = useWalkthrough(this.appId, this.manifest)\n\t\t\t\tconst id = tourId || (this.manifest.walkthrough.tours[0] && this.manifest.walkthrough.tours[0].id)\n\t\t\t\tif (id) {\n\t\t\t\t\twt.restart(id)\n\t\t\t\t}\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * Reactive AI context holder. Page components (CnIndexPage,\n\t\t\t * CnDetailPage, CnDashboardPage) overwrite fields on this object\n\t\t\t * in created() and watch() so the widget sees live context.\n\t\t\t * The same object reference is stable for the lifetime of CnAppRoot.\n\t\t\t */\n\t\t\tcnAiContext: this.cnAiContext,\n\t\t\t/**\n\t\t\t * Reactive holder that descendants — specifically\n\t\t\t * CnIndexPage — write to in order to mount their embedded\n\t\t\t * sidebar at NcContent level. The Vue 2 reactive idiom is\n\t\t\t * `{ value }` so descendants assign `holder.value = config`.\n\t\t\t * `config` is `{ component, props, listeners }`.\n\t\t\t *\n\t\t\t * Default null. CnIndexPage clears it on unmount so the\n\t\t\t * hoisted sidebar disappears when the user navigates away.\n\t\t\t */\n\t\t\tcnIndexSidebarConfig: this.cnIndexSidebarConfig,\n\t\t\t/**\n\t\t\t * Sentinel that CnIndexPage checks to decide whether to\n\t\t\t * publish its embedded sidebar to the hoist (true) or\n\t\t\t * render it inline (false, default for non-CnAppRoot\n\t\t\t * hosts).\n\t\t\t */\n\t\t\tcnHostsIndexSidebar: true,\n\t\t\t/**\n\t\t\t * Consuming app's slug (e.g. \"pipelinq\"). Mirrors the `appId`\n\t\t\t * prop, so descendants (the Actions menus, the forge deep-link\n\t\t\t * builders) know which app they act for without per-widget\n\t\t\t * wiring.\n\t\t\t */\n\t\t\tcnAppId: this.appId,\n\t\t\t/**\n\t\t\t * Target repo slug for the in-product feature-request deep\n\t\t\t * link (e.g. `ConductionNL/pipelinq`). Read from the\n\t\t\t * manifest's `nav.featureRequestRepo` when set; falls back\n\t\t\t * to `ConductionNL/<appId>` which is the convention for\n\t\t\t * every Conduction app on GitHub.\n\t\t\t */\n\t\t\tcnFeatureRequestRepo: this.resolvedFeatureRequestRepo,\n\t\t\t/**\n\t\t\t * Forge config (`{type, baseUrl}`) for the in-product\n\t\t\t * feature-request deep link. Read from the manifest's\n\t\t\t * `nav.forge` (merged over the Codeberg default). Switching\n\t\t\t * the fleet's forge — back to GitHub, or onto a self-hosted\n\t\t\t * Forgejo/Gitea — is just this one manifest field.\n\t\t\t */\n\t\t\tcnFeatureRequestForge: this.resolvedFeatureRequestForge,\n\t\t\t/**\n\t\t\t * Object-sidebar channel — reactive holder that\n\t\t\t * `CnDetailPage` writes to publish its schema-driven\n\t\t\t * sidebar to the NcContent-level auto-mount above.\n\t\t\t * Always exposed (even when an ancestor provides its\n\t\t\t * own) so descendants under THIS CnAppRoot see a\n\t\t\t * consistent inject; the auto-mount itself defers to\n\t\t\t * the ancestor via `ancestorObjectSidebarState`.\n\t\t\t *\n\t\t\t * Shape mirrors what CnDetailPage.syncSidebarState\n\t\t\t * writes — `{ active, open, objectType, objectId,\n\t\t\t * title, subtitle, register, schema, hiddenTabs, tabs\n\t\t\t * }` — plus the always-truthy `_origin` marker so\n\t\t\t * tests can tell the two channels apart.\n\t\t\t *\n\t\t\t * When an ANCESTOR already provides `objectSidebarState`\n\t\t\t * (a host App shell that mounts its own CnObjectSidebar in\n\t\t\t * the `#sidebar` slot — decidesk / procest / openregister),\n\t\t\t * we re-provide THAT holder rather than our local one.\n\t\t\t * Otherwise the descendant CnDetailPage (a deep child of\n\t\t\t * this CnAppRoot via `<router-view>`) would inject our\n\t\t\t * local holder and write the published tab strip there,\n\t\t\t * while the host's `#sidebar` slot — compiled in the\n\t\t\t * ancestor's render scope — reads the ancestor's holder.\n\t\t\t * The two never meet and the strip never renders. Sharing\n\t\t\t * the ancestor holder here keeps the write target and the\n\t\t\t * read target the same object.\n\t\t\t */\n\t\t\tobjectSidebarState: this.ancestorObjectSidebarState || this.localObjectSidebarState,\n\t\t\t/**\n\t\t\t * Index-sidebar channel — CnIndexPage's inject probes\n\t\t\t * `sidebarState` FIRST and falls back to\n\t\t\t * `objectSidebarState`. Providing a distinct holder\n\t\t\t * here keeps the two channels isolated so index-page\n\t\t\t * writes never leak into the object-sidebar\n\t\t\t * auto-mount (the openbuilt double-sidebar regression).\n\t\t\t * Shape covers the CnIndexPage write surface\n\t\t\t * (`searchValue`, `activeFilters`, `facetData`, etc.).\n\t\t\t */\n\t\t\tsidebarState: this.localIndexSidebarState,\n\t\t\t/**\n\t\t\t * Reactive `{ [register]: { [schema]: number } }` totals\n\t\t\t * populated by `_hydrateMenuCounts()` from `useObjectStore()`\n\t\t\t * for every `count: \"auto\"` menu entry whose resolved page is\n\t\t\t * `type: \"index\"` with `register`/`schema` in its config.\n\t\t\t *\n\t\t\t * `CnAppNav.resolveCount()` reads from this map to render\n\t\t\t * `NcCounterBubble` badges next to menu entries. The hydration\n\t\t\t * happens once at mount (one `?_limit=1` fetch per unique\n\t\t\t * `(register, schema)` pair); subsequent index-page mounts\n\t\t\t * reuse the same store entry so no extra round-trip.\n\t\t\t *\n\t\t\t * Defaults to an empty object so `resolveCount` returns\n\t\t\t * `null` (no badge) until hydration completes — which keeps\n\t\t\t * the navigation rendering immediately without waiting for\n\t\t\t * the counts.\n\t\t\t */\n\t\t\tcnMenuCounts: this.cnMenuCounts,\n\t\t}\n\t},\n\n\t/**\n\t * Inject the current page's sidebar-visibility flag and\n\t * sidebar-component override. The provider is `CnPageRenderer`\n\t * (a typical descendant via `<router-view>`).\n\t *\n\t * `cnPageSidebarVisible` default — used when no `CnPageRenderer`\n\t * ancestor exists (e.g. apps mounting their own page components\n\t * without the renderer) — is `{ value: true }` so the `#sidebar`\n\t * slot renders unchanged.\n\t *\n\t * `cnPageSidebarComponent` default is `{ value: null }` so the\n\t * slot's default content stays empty unless the manifest\n\t * explicitly opts in via `pages[].sidebarComponent`. Apps that\n\t * already provide a `#sidebar` slot override see no behaviour\n\t * change either way — the override wins over the slot default.\n\t *\n\t * The shape `{ value: T }` is a hand-rolled reactive holder\n\t * (Vue 2 options API) — see `CnPageRenderer.data()`.\n\t */\n\tinject: {\n\t\tcnPageSidebarVisible: { default: () => ({ value: true }) },\n\t\tcnPageSidebarComponent: { default: () => ({ value: null }) },\n\t\t/**\n\t\t * Ancestor-provided `objectSidebarState` — when set, an\n\t\t * ancestor (e.g. decidesk's host wrapper, procest's app\n\t\t * shell) owns the channel and renders its own\n\t\t * CnObjectSidebar. We defer to it by suppressing our local\n\t\t * auto-mount. Default `null` so a fresh CnAppRoot always\n\t\t * uses its own local holder.\n\t\t */\n\t\tancestorObjectSidebarState: { from: 'objectSidebarState', default: null },\n\t},\n\n\tprops: {\n\t\t/**\n\t\t * Reactive manifest object (from useAppManifest). The renderer\n\t\t * reads `manifest.dependencies`, `manifest.menu`, and is\n\t\t * propagated to descendants via provide/inject.\n\t\t *\n\t\t * @type {object}\n\t\t */\n\t\tmanifest: {\n\t\t\ttype: Object,\n\t\t\trequired: true,\n\t\t},\n\n\t\t/**\n\t\t * DEPRECATED (2.1.0) — render the in-shell orange soft-dependency\n\t\t * banners above the routed page. Off by default: they stacked one per\n\t\t * optional leaf and pushed the app's own content below the fold, for\n\t\t * an audience (end users) who cannot act on them. Mount\n\t\t * `CnLeafDependencySettings` in the app's admin settings instead — it\n\t\t * carries the same two states and the same install/enable action.\n\t\t * Set true only as a temporary bridge while adopting that section;\n\t\t * this prop is slated for removal.\n\t\t *\n\t\t * @type {boolean}\n\t\t */\n\t\tsoftDependencyNotices: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/**\n\t\t * Remount key for the routed `<router-view>`. Hosts that rebuild the\n\t\t * router at runtime (e.g. the Buildiq builder adding a page mid-edit)\n\t\t * bump this AFTER the rebuild so the view drops its stale component-\n\t\t * instance cache and mounts the new routes — a Vue Router 3 matcher swap\n\t\t * alone resolves the new hrefs but leaves SPA-navigation to a just-added\n\t\t * route rendering a blank view. Keep at the default for static apps: the\n\t\t * key is stable across ordinary navigation, so the view is never\n\t\t * needlessly remounted (and the shell / teleported modals are untouched).\n\t\t *\n\t\t * @type {string|number}\n\t\t */\n\t\trouterViewKey: {\n\t\t\ttype: [String, Number],\n\t\t\tdefault: 'cn-router-view',\n\t\t},\n\n\t\t/**\n\t\t * Optional persistence hook for in-app editing (ADR-041). Called with the\n\t\t * minimal manifest delta when the user saves an edit. When omitted, Save\n\t\t * still updates the rendered manifest in memory but persists nothing —\n\t\t * wire this to the Buildiq app-override endpoint to make edits durable.\n\t\t *\n\t\t * @type {((delta: object) => void|Promise<void>)|null}\n\t\t */\n\t\tpersistManifestDelta: {\n\t\t\ttype: Function,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/**\n\t\t * App data sources for the in-app pages editor (ADR-041). Lets the\n\t\t * Edit-pages modal offer Register / Schema / Columns dropdowns for\n\t\t * `index`/`detail` pages instead of free-text slug inputs, so a\n\t\t * created page actually renders a table. Shape: `{ registers:\n\t\t * [{ value, label, schemas: [{ value, label, columns: string[] }] }] }`.\n\t\t * Provided to descendants as `cnDataSources`; when omitted the editor\n\t\t * falls back to free-text register/schema fields.\n\t\t *\n\t\t * @type {object|null}\n\t\t */\n\t\tdataSources: {\n\t\t\ttype: Object,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/**\n\t\t * Async loader for the same data sources, re-invoked every time a\n\t\t * pages-editor modal opens — so a register or schema created after\n\t\t * app boot shows up without a page reload. Prefer this over the\n\t\t * static `dataSources` snapshot, which is captured once and cannot\n\t\t * change (`provide()` runs a single time).\n\t\t *\n\t\t * Signature: `async () => ({ registers: [...] })`, returning the\n\t\t * same shape as `dataSources`. Passing it also moves the fetch off\n\t\t * the app-boot path onto the (much rarer) editor-open path. When\n\t\t * both props are given, `dataSources` seeds the initial list and\n\t\t * the loader's result replaces it on the first refresh.\n\t\t *\n\t\t * @type {(() => Promise<{ registers: Array<object> }>)|null}\n\t\t */\n\t\tdataSourcesLoader: {\n\t\t\ttype: Function,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/**\n\t\t * Nextcloud app id. Forwarded to NcContent as `app-name` and\n\t\t * to CnDependencyMissing for the heading.\n\t\t *\n\t\t * @type {string}\n\t\t */\n\t\tappId: {\n\t\t\ttype: String,\n\t\t\trequired: true,\n\t\t},\n\n\t\t/**\n\t\t * Human-readable name shown in the Nextcloud top bar. When set it\n\t\t * overrides the technical `appId` so a virtual app shows its own name\n\t\t * (e.g. \"Pet Store\") instead of the host app id.\n\t\t */\n\t\tappDisplayName: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/**\n\t\t * First-open support note (`CnSupportDialog`). `true` (default)\n\t\t * auto-mounts it, deriving the app name and the App-Store /\n\t\t * feature-request URLs from `appId` by convention. Pass `false`\n\t\t * to opt out, or an object to override any `CnSupportDialog`\n\t\t * prop (e.g. `{ appName, appStoreUrl, featureRequestUrl,\n\t\t * donateUrl, founderName, … }`). Dismissal persists per-user via\n\t\t * the app's `/api/preferences/support-dialog-seen` endpoint, with\n\t\t * a localStorage fallback.\n\t\t *\n\t\t * @type {boolean|object}\n\t\t */\n\t\tsupportDialog: {\n\t\t\ttype: [Boolean, Object],\n\t\t\tdefault: true,\n\t\t},\n\n\t\t/**\n\t\t * Whether to mount the floating AI-chat companion (`CnAiCompanion`).\n\t\t * Opt-in: `false` (default) keeps the companion off; pass `true` to\n\t\t * show it. When enabled the companion still self-gates on its own\n\t\t * backend health probe and hides on chat pages. The companion is an\n\t\t * AI capability provided by the Hermiq app, so apps opt in explicitly\n\t\t * rather than every app auto-mounting it whenever a chat backend\n\t\t * happens to be reachable.\n\t\t *\n\t\t * @type {boolean}\n\t\t */\n\t\taiCompanion: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/**\n\t\t * Whether to mount the Ctrl/Cmd+K command palette (`CnCommandPalette`).\n\t\t * Opt-in: `false` (default) keeps it off, so existing apps are\n\t\t * unaffected until they enable it. Pass `true` for the zero-config\n\t\t * default (navigation from `manifest.menu` + any commands the app\n\t\t * registers via `useCommandPalette().register(...)`, no live\n\t\t * object search), or an object to override any `CnCommandPalette`\n\t\t * prop — most commonly `{ objectSearch: createObjectSearchSource({...}) }`\n\t\t * (see `src/utils/commandPaletteObjectSource.js`) to wire live\n\t\t * OpenRegister search into the palette's \"objects\" source.\n\t\t *\n\t\t * @type {boolean|object}\n\t\t */\n\t\tcommandPalette: {\n\t\t\ttype: [Boolean, Object],\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/**\n\t\t * Backend app id the AI Chat Companion targets for its chat / health /\n\t\t * conversation HTTP calls (`/index.php/apps/{chatAppId}/api/...`). This is\n\t\t * the single configuration point for switching the chat backend — see\n\t\t * composables/aiChatConfig.js. Defaults to `hermiq`.\n\t\t *\n\t\t * Per hydra ADR-034 \"Amendment 2026-07-05\" the agent engine moved from\n\t\t * OpenRegister to Hermiq and the default flipped to `hermiq`\n\t\t * (`chat-appid-default-flip`). Deployments riding OpenRegister's compat\n\t\t * window (openregister#305) can pass `chatAppId=\"openregister\"` explicitly.\n\t\t *\n\t\t * @type {string}\n\t\t */\n\t\tchatAppId: {\n\t\t\ttype: String,\n\t\t\tdefault: DEFAULT_CHAT_APP_ID,\n\t\t},\n\n\t\t/**\n\t\t * Whether the manifest is still loading from the backend.\n\t\t * Typically wired to `useAppManifest().isLoading`. Defaults to\n\t\t * false so that apps using only the bundled manifest skip the\n\t\t * loading phase.\n\t\t *\n\t\t * @type {boolean}\n\t\t */\n\t\tisLoading: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/**\n\t\t * Custom-component registry consumed by CnPageRenderer for\n\t\t * `type: \"custom\"` pages and slot overrides. Empty by default.\n\t\t *\n\t\t * @type {object}\n\t\t */\n\t\tcustomComponents: {\n\t\t\ttype: Object,\n\t\t\tdefault: () => ({}),\n\t\t},\n\n\t\t/**\n\t\t * Cell-formatter registry. Map of formatter-id →\n\t\t * `(value, row, property) => string|number`. Resolves the\n\t\t * `pages[].config.columns[].formatter` ids that index/logs pages\n\t\t * declare, so per-column value formatting (status-label maps,\n\t\t * \"days in step\", currency, …) lives in small pure data functions\n\t\t * instead of bespoke `type:\"custom\"` table views. Provided to\n\t\t * descendant CnDataTable / CnCellRenderer via inject (`cnFormatters`).\n\t\t * Empty by default — a column with no `formatter`, or an app that\n\t\t * passes no `formatters`, renders exactly as before.\n\t\t *\n\t\t * @type {object}\n\t\t */\n\t\tformatters: {\n\t\t\ttype: Object,\n\t\t\tdefault: () => ({}),\n\t\t},\n\n\t\t/**\n\t\t * Cell-widget registry. Map of widget-id → Vue component, rendered\n\t\t * for a column that declares `pages[].config.columns[].widget`. The\n\t\t * component receives `{ value, row, property, formatted, ...widgetProps }`.\n\t\t * The library ships one built-in id, `\"badge\"` (renders `CnStatusBadge`);\n\t\t * consumer entries cover everything else (status pills with custom\n\t\t * colour maps, inline toggles, link cells, …). Provided to descendant\n\t\t * `CnDataTable` / `CnCellRenderer` via inject (`cnCellWidgets`). Empty\n\t\t * by default — a column with no `widget` renders as before.\n\t\t *\n\t\t * @type {object}\n\t\t */\n\t\tcellWidgets: {\n\t\t\ttype: Object,\n\t\t\tdefault: () => ({}),\n\t\t},\n\n\t\t/**\n\t\t * Pluggable knowledge-base search providers (#91 Wave 3). Map of\n\t\t * provider-key → provider object (`{ search(query, opts), externalOpen? }`),\n\t\t * merged OVER the library built-ins (`default`) and provided to\n\t\t * descendant `CnKbSearchWidget` via inject (`cnKbSearchProviders`).\n\t\t * A `kb-search` widget selects its provider by `content.provider`;\n\t\t * an app talking to a bespoke KB backend (the xwiki proxy) registers\n\t\t * its client here — the library ships only the `default` endpoint\n\t\t * provider + the seam. Empty by default (the built-in `default`\n\t\t * provider then serves every `kb-search` widget).\n\t\t *\n\t\t * @type {object}\n\t\t */\n\t\tkbSearchProviders: {\n\t\t\ttype: Object,\n\t\t\tdefault: () => ({}),\n\t\t},\n\n\t\t/**\n\t\t * Translate function provided by the consuming app. The library\n\t\t * never imports `t()` from a specific app, so the consumer\n\t\t * passes its own translator. Typically a closure over the\n\t\t * Nextcloud `t()` mixin pre-bound to the app id, e.g.\n\t\t * `(key) => t(appId, key)`.\n\t\t *\n\t\t * Defaults to an identity function so untranslated keys surface\n\t\t * visibly rather than crashing.\n\t\t *\n\t\t * Note: the prop is named `translate` (not `t`) to avoid\n\t\t * shadowing the global `t()` method that Conduction apps\n\t\t * install via `Vue.mixin({ methods: { t, n } })`. The provide\n\t\t * key is `cnTranslate`.\n\t\t *\n\t\t * @type {(key: string) => string}\n\t\t */\n\t\ttranslate: {\n\t\t\ttype: Function,\n\t\t\tdefault: (key) => key,\n\t\t},\n\n\t\t/**\n\t\t * List of permission strings the current user holds. Forwarded\n\t\t * to CnAppNav's permission filter.\n\t\t *\n\t\t * @type {Array<string>}\n\t\t */\n\t\tpermissions: {\n\t\t\ttype: Array,\n\t\t\tdefault: () => [],\n\t\t},\n\n\t\t/**\n\t\t * Page-type registry. Map of `pages[].type` → Vue component.\n\t\t * Provided to descendant CnPageRenderer instances via inject.\n\t\t * When omitted, the renderer falls back to the library's\n\t\t * `defaultPageTypes`. Apps with custom page types pass a merged\n\t\t * map: `{ ...defaultPageTypes, report: MyReportPage }`.\n\t\t *\n\t\t * @type {object|null}\n\t\t */\n\t\tpageTypes: {\n\t\t\ttype: Object,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/**\n\t\t * Component registry for v2 manifests. Map of registry key →\n\t\t * `{ kind, component, ...kindMetadata }`. Provided to descendants\n\t\t * via Vue provide under key `cnRegistry`. Validated at `mounted()`\n\t\t * time — unknown `kind` throws `RegistryKindError`; missing required\n\t\t * kind-metadata emits `console.warn`.\n\t\t *\n\t\t * Recognised kinds: `widget`, `modal`, `page`, `form-field`,\n\t\t * `cell-renderer`, the slot-component kinds `header`, `actions`,\n\t\t * `tab`, `section` (mounted into named page slots), and the function\n\t\t * kinds `handler` (a manifest `actions[]` / `bulkActions[]` /\n\t\t * `headerActions[]` handler) and `create-override`. See spec\n\t\t * REQ-MVR-002.\n\t\t *\n\t\t * @type {object}\n\t\t */\n\t\tregistry: {\n\t\t\ttype: Object,\n\t\t\tdefault: () => ({}),\n\t\t},\n\n\t\t/**\n\t\t * Required Nextcloud apps for this Conduction app to function.\n\t\t * Default `['openregister']` — every fleet app stores its data\n\t\t * in OpenRegister, so the guard is on by default. Consumer apps\n\t\t * that don't need OpenRegister (the styleguide, the docs site,\n\t\t * future utility apps) opt out via `:requires-apps=\"[]\"`.\n\t\t *\n\t\t * On `mounted()`, CnAppRoot calls `getCapabilities()` from\n\t\t * `@nextcloud/capabilities` exactly once and compares the\n\t\t * returned capability keys against this list. When ANY entry\n\t\t * is missing, CnAppRoot renders an `<NcEmptyContent>` (the\n\t\t * default) or the consumer's `#or-missing` slot.\n\t\t *\n\t\t * Multi-app future-proofing free: a future docudesk-derived app\n\t\t * needing both can declare\n\t\t * `:requires-apps=\"['openregister', 'openconnector']\"`.\n\t\t *\n\t\t * Network failure on `getCapabilities()` (admin-restricted,\n\t\t * offline, CORS) falls through to the renderer rather than\n\t\t * blocking the app on a flaky check — the data layer surfaces\n\t\t * the actual failure when API calls hit OpenRegister.\n\t\t *\n\t\t * See REQ-OR-1..REQ-OR-7 of cnapproot-app-availability-guard.\n\t\t *\n\t\t * @type {Array<string>}\n\t\t */\n\t\trequiresApps: {\n\t\t\ttype: Array,\n\t\t\tdefault: () => ['openregister'],\n\t\t},\n\n\t\t/**\n\t\t * Title rendered at the top of the user-settings modal\n\t\t * (NcAppSettingsDialog `name` prop). Defaults to the\n\t\t * translated string \"User settings\"; pass a custom label\n\t\t * (e.g. \"Decidiq preferences\") to override per app.\n\t\t *\n\t\t * @type {string}\n\t\t */\n\t\tuserSettingsTitle: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/**\n\t\t * Title rendered at the top of the admin-settings modal\n\t\t * (NcAppSettingsDialog `name` prop). Defaults to the\n\t\t * translated string \"Administration\"; pass a custom label\n\t\t * (e.g. \"Pipelinq administration\") to override per app.\n\t\t *\n\t\t * @type {string}\n\t\t */\n\t\tadminSettingsTitle: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/**\n\t\t * Initial active organisation UUID (multi-tenancy-context). When\n\t\t * set, the provided `useTenantContext()` mounts with this UUID\n\t\t * already active so the first render stamps the right\n\t\t * `X-OpenRegister-Organisation` header and the top-bar\n\t\t * `CnTenantBadge` shows the right name immediately. Updates via\n\t\t * `useTenantContext().setActiveTenant()` from any descendant.\n\t\t *\n\t\t * @type {string|null}\n\t\t */\n\t\tinitialOrganisationUuid: {\n\t\t\ttype: String,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/**\n\t\t * Initial active organisation entity (multi-tenancy-context).\n\t\t * When set, surfaces the resolved name + slug for the badge\n\t\t * without a second fetch.\n\t\t *\n\t\t * @type {object|null}\n\t\t */\n\t\tinitialOrganisation: {\n\t\t\ttype: Object,\n\t\t\tdefault: null,\n\t\t},\n\t},\n\n\temits: ['setup-complete', 'walkthrough-complete'],\n\n\t/**\n\t * Component-instance state for the capabilities guard.\n\t *\n\t * - `capabilitiesLoading`: `true` only when the prop says we need\n\t * to check (i.e. `requiresApps.length > 0`). Apps that opt out\n\t * via `:requires-apps=\"[]\"` see this initialise to `false`, so\n\t * no spinner flashes and the renderer mounts on the first\n\t * render. Apps that need the guard see `true` initially; the\n\t * `mounted()` hook runs the check and flips to `false`.\n\t * - `missingApps`: the list of `requiresApps` entries NOT\n\t * present in the capabilities payload. When empty, the\n\t * renderer mounts; when non-empty, the empty-state renders.\n\t * - `guardError`: stores the caught error so consumers\n\t * inspecting the component instance can introspect failures.\n\t * The error path falls through to the renderer regardless.\n\t */\n\t/**\n\t * Auto-mount the first-open support note unless the host opted out\n\t * with `:support-dialog=\"false\"`. Per-user persistence via the app's\n\t * preferences endpoint (localStorage fallback inside the composable).\n\t * Returns no refs when disabled, so the `v-if=\"cnSupportVisible\"` in\n\t * the template stays false.\n\t *\n\t * @param {object} props Component props (reads `appId`, `supportDialog`).\n\t * @return {object} `{ cnSupportVisible, cnSupportHide }` or `{}` when disabled.\n\t */\n\tsetup(props) {\n\t\t// Mount the multi-tenancy context provider so descendants can\n\t\t// reach the shared `activeOrganisationUuid` / `setActiveTenant`\n\t\t// via `useTenantContext()` (composable) or the\n\t\t// `tenantContextMixin` (Options API). The provider is mounted\n\t\t// even on single-tenant apps so consumers can opt-in later\n\t\t// without restructuring their CnAppRoot wrapper.\n\t\tconst tenantContext = provideTenantContext(\n\t\t\tprops.initialOrganisationUuid || null,\n\t\t\tprops.initialOrganisation || null,\n\t\t)\n\n\t\t// Off when the host opts out (`:support-dialog=\"false\"`) OR the manifest's\n\t\t// support block is explicitly disabled (the \"Show the support note on\n\t\t// first open\" toggle in Buildiq's editor). Omitting the block keeps the\n\t\t// default-on first-open behaviour.\n\t\tconst manifestSupportDisabled = !!(props.manifest && props.manifest.support\n\t\t\t&& typeof props.manifest.support === 'object'\n\t\t\t&& props.manifest.support.enabled === false)\n\t\tconst supportPair = (props.supportDialog === false || manifestSupportDisabled)\n\t\t\t? {}\n\t\t\t: (() => {\n\t\t\t\t\tconst { visible, hide } = useSupportDialog(props.appId, { persistence: 'server' })\n\t\t\t\t\treturn { cnSupportVisible: visible, cnSupportHide: hide }\n\t\t\t\t})()\n\n\t\t// In-app editing (ADR-041) + the raw/reactive boundary (audit item 9,\n\t\t// `manifest-markraw-reactivity`). `baseRef` is the SINGLE reactive holder\n\t\t// for the manifest — it reconciles the prop read path and the editor's\n\t\t// live source into one wrap site. It is a `shallowRef`, NOT a `ref`: a\n\t\t// plain `ref(obj)` deep-observes the whole immutable manifest graph (up to\n\t\t// ~434 KB of nested objects) at boot for a structure the renderer only\n\t\t// ever reads. `shallowRef` holds the manifest RAW — `isReactive(baseRef\n\t\t// .value) === false` — so ordinary navigation and rendering never trigger\n\t\t// per-node observer conversion. The ADR-041 editor opts the live manifest\n\t\t// into deep reactivity IN PLACE on edit-enter (see `useManifestEditor`),\n\t\t// preserving object identity so already-mounted renderers see the edits;\n\t\t// on the next manifest publish the watch below re-installs a fresh raw\n\t\t// manifest, returning the read path to non-reactive.\n\t\tconst baseRef = shallowRef(props.manifest)\n\t\tconst manifestEditor = useManifestEditor(baseRef, {\n\t\t\tpersist: (delta) => (typeof props.persistManifestDelta === 'function'\n\t\t\t\t? props.persistManifestDelta(delta)\n\t\t\t\t: undefined),\n\t\t})\n\t\twatch(() => props.manifest, (m) => {\n\t\t\tif (!manifestEditor.editing.value) {\n\t\t\t\tbaseRef.value = m\n\t\t\t}\n\t\t})\n\t\t// One shared install/enable action for the or-missing guard and the\n\t\t// soft-dependency banners (REQ-DIA-3 / REQ-DIA-6). `depInstalling` /\n\t\t// `depInstallError` are the composable refs, returned top-level so the\n\t\t// template auto-unwraps them; `installAndEnable` is called from the\n\t\t// `installDependency` method.\n\t\tconst appInstaller = useAppInstaller()\n\n\t\tconst { available: buildiqAvailable } = useBuildiqEditAvailability()\n\t\t// A manifest may opt OUT of the Buildiq in-app edit button by setting\n\t\t// `openbuildEditable: false` (e.g. Buildiq's own pages — an app does not\n\t\t// edit itself with itself). Default true: omitting the flag keeps the\n\t\t// button wherever the Buildiq app is enabled (ADR-041). The manifest key\n\t\t// keeps its `openbuild` spelling — it is shipped manifest data.\n\t\tconst buildiqEditable = computed(() => buildiqAvailable.value && props.manifest?.openbuildEditable !== false)\n\n\t\t// Scoped NL Design token-set theming (scoped-theme-applier). Watches the\n\t\t// SAME editing/props branch `cnManifest`'s getter already uses, so the\n\t\t// applied theme tracks whichever manifest is currently effective —\n\t\t// including an in-app live-preview editing session (ADR-041) — with no\n\t\t// separate wiring needed for that case. `apply()` is a progressive\n\t\t// enhancement: nldesign absent/unreachable/non-conformant degrades\n\t\t// silently to default styling, never a throw (REQ-STA-1/REQ-STA-3).\n\t\tconst scopedTheme = useScopedTheme()\n\t\twatch(\n\t\t\t() => (manifestEditor.editing.value ? manifestEditor.source.value : props.manifest)?.runtime?.theme,\n\t\t\t() => scopedTheme.apply(\n\t\t\t\tmanifestEditor.editing.value ? manifestEditor.source.value : props.manifest,\n\t\t\t\tprops.appId,\n\t\t\t),\n\t\t\t{ deep: true, immediate: true },\n\t\t)\n\n\t\treturn {\n\t\t\t...supportPair,\n\t\t\tcnTenantContext: tenantContext,\n\t\t\tmanifestEditor,\n\t\t\tbuildiqAvailable: buildiqEditable,\n\t\t\tappInstaller,\n\t\t\tdepInstalling: appInstaller.installing,\n\t\t\tdepInstallError: appInstaller.error,\n\t\t\tcnScopedTheme: scopedTheme,\n\t\t}\n\t},\n\n\t/**\n\t * Component-instance state for the capabilities guard.\n\t *\n\t * - `capabilitiesLoading`: `true` only when the prop says we need\n\t * to check (i.e. `requiresApps.length > 0`). Apps that opt out\n\t * via `:requires-apps=\"[]\"` see this initialise to `false`, so\n\t * no spinner flashes and the renderer mounts on the first\n\t * render. Apps that need the guard see `true` initially; the\n\t * `mounted()` hook runs the check and flips to `false`.\n\t * - `missingApps`: the list of `requiresApps` entries NOT\n\t * present in the capabilities payload. When empty, the\n\t * renderer mounts; when non-empty, the empty-state renders.\n\t * - `guardError`: stores the caught error so consumers\n\t * inspecting the component instance can introspect failures.\n\t * The error path falls through to the renderer regardless.\n\t */\n\tdata() {\n\t\tconst willCheck = Array.isArray(this.requiresApps) && this.requiresApps.length > 0\n\t\treturn {\n\t\t\tcapabilitiesLoading: willCheck,\n\t\t\tmissingApps: [],\n\t\t\tguardError: null,\n\t\t\t/**\n\t\t\t * Reactive holder that descendants write into to mount\n\t\t\t * their embedded index sidebar at NcContent level. Shared\n\t\t\t * via provide(); see the `cnIndexSidebarConfig` provide\n\t\t\t * docs for the contract.\n\t\t\t */\n\t\t\tcnIndexSidebarConfig: { value: null },\n\t\t\t/**\n\t\t\t * Reactive AI context. Provided to all descendants via\n\t\t\t * provide('cnAiContext'). Page components overwrite fields\n\t\t\t * in their created() + watch() to give the companion\n\t\t\t * per-page context. The same object reference is stable\n\t\t\t * across the lifetime of CnAppRoot.\n\t\t\t *\n\t\t\t * Shape: CnAiContext (hydra-locked TypeScript interface)\n\t\t\t * { appId, pageKind, objectUuid?, registerSlug?,\n\t\t\t * schemaSlug?, route? }\n\t\t\t */\n\t\t\tcnAiContext: reactive({\n\t\t\t\tappId: this.appId || 'unknown',\n\t\t\t\tpageKind: 'custom',\n\t\t\t\troute: { path: (typeof window !== 'undefined' ? window.location.pathname : '') },\n\t\t\t}),\n\n\t\t\t/**\n\t\t\t * Reactive holder for the pages editor's register/schema\n\t\t\t * data sources. Provided as `cnDataSourcesState`.\n\t\t\t *\n\t\t\t * The object reference is STABLE for the lifetime of\n\t\t\t * CnAppRoot — `refreshDataSources()` mutates its fields and\n\t\t\t * never reassigns it. That is load-bearing: provide() runs\n\t\t\t * once, so a value provided from a prop can never change\n\t\t\t * (which is exactly why the legacy `cnDataSources` snapshot\n\t\t\t * goes stale). Descendants read `.value`, mirroring how they\n\t\t\t * already unwrap `cnOpenBuildAvailable` / `cnEditingBody`.\n\t\t\t *\n\t\t\t * `value` holds the `{ registers: [...] }` payload (seeded\n\t\t\t * from the `dataSources` snapshot when one is passed), and\n\t\t\t * `hasLoader` lets descendants render the pickers instead of\n\t\t\t * free-text fields before the first fetch resolves.\n\t\t\t */\n\t\t\tdataSourcesState: {\n\t\t\t\tvalue: this.dataSources || null,\n\t\t\t\tloading: false,\n\t\t\t\terror: null,\n\t\t\t\thasLoader: typeof this.dataSourcesLoader === 'function',\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * Reactive `{ [register]: { [schema]: number } }` map of\n\t\t\t * object-store totals — one entry per unique\n\t\t\t * `(register, schema)` pair declared on a menu item with\n\t\t\t * `count: \"auto\"`. Provided to descendants as\n\t\t\t * `cnMenuCounts`; CnAppNav reads from it inside its\n\t\t\t * `resolveCount()` to render `NcCounterBubble` badges.\n\t\t\t *\n\t\t\t * Populated by `_hydrateMenuCounts()` at mount. Wrapped in\n\t\t\t * `Vue.observable` so direct property writes\n\t\t\t * (`this.cnMenuCounts[register][schema] = total`) are\n\t\t\t * picked up by CnAppNav's reactive render.\n\t\t\t */\n\t\t\tcnMenuCounts: reactive({}),\n\t\t\t/**\n\t\t\t * Open state of the host NcAppSettingsDialog. Toggled\n\t\t\t * to `true` by the provided `cnOpenUserSettings()`\n\t\t\t * method (CnAppNav binds this to manifest entries with\n\t\t\t * `action: \"user-settings\"`); the dialog flips it back\n\t\t\t * via its `update:open` event.\n\t\t\t */\n\t\t\tuserSettingsOpen: false,\n\t\t\t/**\n\t\t\t * Id of the dependency whose install/enable action is currently\n\t\t\t * in flight (REQ-DIA-3 / REQ-DIA-6). Drives the per-button spinner\n\t\t\t * so, with several soft-dependency banners on screen, only the\n\t\t\t * clicked one shows busy. `null` when nothing is installing.\n\t\t\t *\n\t\t\t * @type {string|null}\n\t\t\t */\n\t\t\tinstallingDepId: null,\n\t\t\t/**\n\t\t\t * Id of the dependency whose last install/enable attempt failed —\n\t\t\t * scopes the inline soft-dependency banner error to that dep even\n\t\t\t * after `installingDepId` clears on settle.\n\t\t\t *\n\t\t\t * @type {string|null}\n\t\t\t */\n\t\t\terroredDepId: null,\n\t\t\t/**\n\t\t\t * Ids of SOFT dependencies whose in-shell banner the user has\n\t\t\t * dismissed (REQ-DIA-6). Seeded synchronously from `localStorage`\n\t\t\t * (`cn-soft-dep-dismissed:{appId}:{depId}`) so a previously\n\t\t\t * dismissed notice never flashes on mount; a fresh dismissal pushes\n\t\t\t * the id here (reactive hide) and persists the key.\n\t\t\t *\n\t\t\t * @type {Array<string>}\n\t\t\t */\n\t\t\tdismissedSoftDeps: (() => {\n\t\t\t\tconst out = []\n\t\t\t\ttry {\n\t\t\t\t\tconst deps = Array.isArray(this.manifest?.dependencies)\n\t\t\t\t\t\t? this.manifest.dependencies\n\t\t\t\t\t\t: []\n\t\t\t\t\tfor (const entry of deps) {\n\t\t\t\t\t\tconst isObject = entry !== null && typeof entry === 'object'\n\t\t\t\t\t\tconst id = isObject ? entry.id : entry\n\t\t\t\t\t\tconst required = isObject ? entry.required !== false : true\n\t\t\t\t\t\tif (required || typeof id !== 'string' || id === '') {\n\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (window.localStorage.getItem('cn-soft-dep-dismissed:' + this.appId + ':' + id)) {\n\t\t\t\t\t\t\tout.push(id)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} catch {\n\t\t\t\t\t// localStorage unavailable (private mode) — nothing dismissed.\n\t\t\t\t}\n\t\t\t\treturn out\n\t\t\t})(),\n\n\t\t\t/**\n\t\t\t * Session-only flag: the user dismissed (or finished) the non-gating\n\t\t\t * setup wizard during THIS page load. The durable answer lives in\n\t\t\t * `localStorage` and is read through `isSetupWizardDismissed()` —\n\t\t\t * deliberately NOT seeded here, because `manifest` can still be\n\t\t\t * replaced by `useAppManifest`'s async backend merge and a seed\n\t\t\t * would then have been checked against a stale `setup.version`.\n\t\t\t *\n\t\t\t * @type {boolean}\n\t\t\t */\n\t\t\tsetupWizardDismissed: false,\n\t\t\t/**\n\t\t\t * Whether the non-gating setup wizard overlay is currently open.\n\t\t\t * Flips true once (auto-open) when only optional steps are unmet\n\t\t\t * and the user hasn't already dismissed this manifest version; the\n\t\t\t * user can reopen later from wherever the host surfaces it (e.g.\n\t\t\t * admin settings), independent of this auto-open state.\n\t\t\t *\n\t\t\t * @type {boolean}\n\t\t\t */\n\t\t\tsetupWizardOpen: false,\n\t\t\t/**\n\t\t\t * The user's last-seen walkthrough app version (ADR-043).\n\t\t\t *\n\t\t\t * Seeded SYNCHRONOUSLY from the per-browser localStorage mirror so\n\t\t\t * nothing flashes, then overwritten by the `walkthroughConfigKey`\n\t\t\t * watcher from the authoritative per-user preference addressed by\n\t\t\t * `manifest.walkthrough.completionConfigKey`. `''` means the user\n\t\t\t * has never completed or dismissed the tour.\n\t\t\t *\n\t\t\t * @type {string}\n\t\t\t */\n\t\t\twalkthroughSeenVersionValue: readLocalWalkthroughSeenVersion(this.appId),\n\t\t\t/**\n\t\t\t * Whether `walkthroughSeenVersionValue` is settled. Starts `true`\n\t\t\t * when the manifest declares no `completionConfigKey` (the local\n\t\t\t * read above is already the final answer) and `false` when it does,\n\t\t\t * so the overlay waits for the server round trip instead of\n\t\t\t * auto-opening a tour the user already finished on another device.\n\t\t\t *\n\t\t\t * @type {boolean}\n\t\t\t */\n\t\t\twalkthroughSeenResolved: !(this.manifest\n\t\t\t\t&& this.manifest.walkthrough\n\t\t\t\t&& this.manifest.walkthrough.completionConfigKey),\n\n\t\t\t/**\n\t\t\t * Whether the setup status has finished loading at least once.\n\t\t\t * Stays `true` across later refreshes.\n\t\t\t *\n\t\t\t * @type {boolean}\n\t\t\t */\n\t\t\tsetupStatusSettled: false,\n\n\t\t\t/**\n\t\t\t * Key of the currently active modal (opened via cnOpenModal).\n\t\t\t * null when no modal is open.\n\t\t\t *\n\t\t\t * @type {string|null}\n\t\t\t */\n\t\t\tactiveModalKey: null,\n\t\t\t/**\n\t\t\t * Props forwarded to the active modal component.\n\t\t\t *\n\t\t\t * @type {object}\n\t\t\t */\n\t\t\tactiveModalProps: {},\n\t\t\t/**\n\t\t\t * Local holder for the object-sidebar channel. Lives on\n\t\t\t * this CnAppRoot instance (Vue.observable so descendant\n\t\t\t * writes via inject trigger re-renders); the `provide()`\n\t\t\t * block exposes it under the `objectSidebarState` key.\n\t\t\t *\n\t\t\t * CnDetailPage flips `active: true` + fills the object\n\t\t\t * coordinates in its `syncSidebarState()`; we render the\n\t\t\t * hoisted CnObjectSidebar when both `objectType` and\n\t\t\t * `objectId` are non-empty AND the consumer hasn't\n\t\t\t * supplied a `#sidebar` slot AND no ancestor already\n\t\t\t * owns the channel.\n\t\t\t */\n\t\t\tlocalObjectSidebarState: reactive({\n\t\t\t\tactive: false,\n\t\t\t\topen: false,\n\t\t\t\tobjectType: '',\n\t\t\t\tobjectId: '',\n\t\t\t\ttitle: '',\n\t\t\t\tsubtitle: '',\n\t\t\t\tregister: '',\n\t\t\t\tschema: '',\n\t\t\t\t// The loaded object, published by CnDetailPage so the hoisted\n\t\t\t\t// sidebar's data/metadata tab widgets get it as `objectData`.\n\t\t\t\t// Pre-declared here so Vue 2 keeps it reactive.\n\t\t\t\tobject: null,\n\t\t\t\t// The resolved schema OBJECT, for the `data` tab widget.\n\t\t\t\tschemaObject: null,\n\t\t\t\thiddenTabs: [],\n\t\t\t\ttabs: undefined,\n\t\t\t\t// Host-requested active tab id (e.g. a detail-page \"Linked\n\t\t\t\t// apps\" row deep-linking into a specific leaf). null = let\n\t\t\t\t// the sidebar pick its own default.\n\t\t\t\trequestedTab: null,\n\t\t\t}),\n\n\t\t\t/**\n\t\t\t * Local holder for the index-sidebar channel. Distinct\n\t\t\t * reference from `localObjectSidebarState` so the\n\t\t\t * `sidebarState`-first inject in CnIndexPage never\n\t\t\t * leaks an `active: true` write into the object-sidebar\n\t\t\t * channel.\n\t\t\t */\n\t\t\tlocalIndexSidebarState: reactive({\n\t\t\t\tactive: false,\n\t\t\t\topen: false,\n\t\t\t\tsearchValue: '',\n\t\t\t\tactiveFilters: {},\n\t\t\t\tfacetData: null,\n\t\t\t\tfacetableFields: [],\n\t\t\t\tfacetableConfig: null,\n\t\t\t}),\n\t\t}\n\t},\n\n\tcomputed: {\n\t\t/**\n\t\t * The per-user preference reader and writer for this app, built from\n\t\t * the manifest's `personalisation` block.\n\t\t *\n\t\t * One group per app, shared by every descendant through the\n\t\t * `cnUserPreferences` provide, so a list holding a row order and the\n\t\t * preferences screen showing it are looking at the same thing.\n\t\t *\n\t\t * @return {object} The group from useUserPreferences.\n\t\t * @spec openspec/changes/case-page-and-list-as-a-place/specs/index-page/spec.md\n\t\t */\n\t\tuserPreferences() {\n\t\t\treturn useUserPreferences(this.appId, {\n\t\t\t\tpersonalisation: this.manifest?.personalisation || {},\n\t\t\t})\n\t\t},\n\n\t\t/**\n\t\t * The component to render as this page's sidebar.\n\t\t *\n\t\t * Two sources, in order:\n\t\t * 1. `pages[].sidebarComponent` on the routed manifest page, resolved\n\t\t * here — see `resolvePageSidebarComponent()` for why it cannot be\n\t\t * resolved by the renderer that declares it.\n\t\t * 2. The injected `cnPageSidebarComponent` holder, kept so an app that\n\t\t * genuinely provides one from an ANCESTOR still works.\n\t\t *\n\t\t * A consumer's own `#sidebar` slot content always wins over both, via\n\t\t * Vue's standard slot mechanic.\n\t\t *\n\t\t * @return {import('vue').Component|null} The component, or null.\n\t\t */\n\t\tpageSidebarComponent() {\n\t\t\treturn this.resolvePageSidebarComponent() ?? this.cnPageSidebarComponent?.value ?? null\n\t\t},\n\n\t\t/**\n\t\t * Whether the current user is an OWNER of this app — the gate for\n\t\t * the admin-settings nav entry + dialog (admin-settings-owner-gating\n\t\t * capability). Deliberately NOT `OC.isUserAdmin()`: a Nextcloud\n\t\t * super-admin who is not an app owner does not see the admin\n\t\t * surface, and an app owner who is not a super-admin does.\n\t\t *\n\t\t * PRIMARY signal: `manifest.runtime.user.isOwner === true`, a\n\t\t * read-only projection the backend computes via\n\t\t * `PermissionResolver::matchesCaller(...['owners'])` (D5) — the\n\t\t * reliable path for the ordinary manifest-render case.\n\t\t *\n\t\t * FALLBACK: a non-empty intersection of the caller's groups\n\t\t * (`openbuild.currentUserGroups` initial state) with the owner GIDs\n\t\t * parsed from the `permissions` prop using the same `group:<gid>` /\n\t\t * bare-GID grammar as per-item `permission` narrowing — for hosts\n\t\t * (e.g. an OpenBuilt virtual app) that pass the app's\n\t\t * `Application.permissions.owners` principals through `permissions`\n\t\t * rather than (or in addition to) the backend runtime.user\n\t\t * projection. Read via `loadState` initial-state, never DOM\n\t\t * data-attributes (hydra initial-state gate).\n\t\t *\n\t\t * @return {boolean}\n\t\t */\n\t\tisOwner() {\n\t\t\tconst runtime = this.manifest && this.manifest.runtime\n\t\t\tconst runtimeUser = runtime && typeof runtime.user === 'object' && runtime.user !== null\n\t\t\t\t? runtime.user\n\t\t\t\t: null\n\t\t\tif (runtimeUser && runtimeUser.isOwner === true) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\treturn this.ownerGroupsIntersect\n\t\t},\n\n\t\t/**\n\t\t * Caller's Nextcloud group GIDs, published by Buildiq's\n\t\t * `DashboardController::publishCurrentUserGroups()` initial state.\n\t\t * Read via `loadState`, never DOM attributes. Defensive try/catch\n\t\t * mirrors `serverAppStatuses` — hosts without the initial-state key\n\t\t * (non-Buildiq hosts, tests) simply resolve to an empty list, so the\n\t\t * fallback gate stays false rather than throwing.\n\t\t *\n\t\t * Initial state is namespaced by the PUBLISHING app's id, which moved\n\t\t * from `openbuild` to `buildiq`, so both are tried. A miss is silent:\n\t\t * `loadState` with a default returns the default, the gate reads\n\t\t * false, and nothing reports a stale key. Drop `openbuild` once no\n\t\t * supported install ships the old app id.\n\t\t *\n\t\t * @return {Array<string>}\n\t\t */\n\t\tcurrentUserGroups() {\n\t\t\ttry {\n\t\t\t\tconst groups = loadState('buildiq', 'currentUserGroups', null)\n\t\t\t\t\t?? loadState('openbuild', 'currentUserGroups', [])\n\t\t\t\treturn Array.isArray(groups) ? groups : []\n\t\t\t} catch {\n\t\t\t\treturn []\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Owner GIDs parsed from the `permissions` prop using the existing\n\t\t * per-item permission grammar (`group:<gid>` or a bare GID). Not\n\t\t * every `permissions` entry is necessarily an owner GID (a host may\n\t\t * also pass unrelated permission strings) — this is a best-effort\n\t\t * parse, and only feeds the FALLBACK gate; the PRIMARY signal is\n\t\t * `runtime.user.isOwner`.\n\t\t *\n\t\t * @return {Array<string>}\n\t\t */\n\t\townerGidsFromPermissions() {\n\t\t\tif (!Array.isArray(this.permissions)) {\n\t\t\t\treturn []\n\t\t\t}\n\t\t\treturn this.permissions\n\t\t\t\t.filter((p) => typeof p === 'string' && p.length > 0)\n\t\t\t\t.map((p) => (p.startsWith('group:') ? p.slice('group:'.length) : p))\n\t\t},\n\n\t\t/**\n\t\t * Whether `currentUserGroups` and `ownerGidsFromPermissions`\n\t\t * intersect — the FALLBACK half of `isOwner`.\n\t\t *\n\t\t * @return {boolean}\n\t\t */\n\t\townerGroupsIntersect() {\n\t\t\tconst groups = this.currentUserGroups\n\t\t\tconst owners = this.ownerGidsFromPermissions\n\t\t\tif (groups.length === 0 || owners.length === 0) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\treturn groups.some((g) => owners.includes(g))\n\t\t},\n\n\t\t/**\n\t\t * The manifest the default `<CnAppNav>` renders — the editor's working\n\t\t * `source` while in-app editing, else the live `manifest` prop. Passed to\n\t\t * CnAppNav as a REACTIVE prop (not left to the provide/inject fallback):\n\t\t * Vue 2 `inject` resolves the provided `cnManifest` getter once at the\n\t\t * child's create time, so an async manifest update (e.g. a backend\n\t\t * `/api/manifest` delta merged in by `useAppManifest`) never reaches the\n\t\t * injected value. Binding the prop makes the nav update reactively.\n\t\t * Mirrors the `cnManifest` provide getter so deep descendants stay\n\t\t * consistent with the menu.\n\t\t *\n\t\t * @return {object}\n\t\t */\n\t\tmenuManifest() {\n\t\t\tconst m = this.manifestEditor ? this.manifestEditor.source.value : this.manifest\n\t\t\t// Raw/reactive boundary (audit item 9). The manifest is held raw at\n\t\t\t// boot (CnAppRoot's shallowRef), so the default CnAppNav establishes\n\t\t\t// its render dependencies against a NON-reactive `menu` at first\n\t\t\t// render. When the in-app editor opts the manifest into reactivity on\n\t\t\t// edit-enter (`useManifestEditor.enter()` → `reactive()` in place),\n\t\t\t// CnAppNav would otherwise keep its stale dep-less render and miss live\n\t\t\t// menu edits. Handing it a FRESH wrapper identity while editing forces\n\t\t\t// one re-render that re-subscribes to the now-reactive `menu` array, so\n\t\t\t// menu add/label/reorder edits render live exactly as before — while\n\t\t\t// the spread's `menu` is the SAME reactive array, so in-place edits\n\t\t\t// flow through. Outside edit mode the live manifest is returned BY\n\t\t\t// IDENTITY (regression guard: the CnAppNav prop must === the manifest\n\t\t\t// prop for async backend-merge updates — see the reactive-menu tests).\n\t\t\tif (this.manifestEditor && this.manifestEditor.editing.value && m && typeof m === 'object') {\n\t\t\t\treturn { ...m }\n\t\t\t}\n\t\t\treturn m\n\t\t},\n\n\t\t/**\n\t\t * Active object-sidebar holder for the auto-mount block.\n\t\t * Mirrors the local holder; if an ancestor already provides\n\t\t * `objectSidebarState`, the auto-mount is suppressed by\n\t\t * `shouldAutoMountObjectSidebar`, so this getter is only\n\t\t * read when we own the channel.\n\t\t *\n\t\t * @return {object}\n\t\t */\n\t\teffectiveObjectSidebarState() {\n\t\t\treturn this.localObjectSidebarState\n\t\t},\n\n\t\t/**\n\t\t * Which mode the auto-mounted CnObjectSidebar runs in.\n\t\t *\n\t\t * CnObjectSidebar treats `tabs` and `useRegistry` as mutually\n\t\t * exclusive and warns when it gets both. This mount site passes\n\t\t * `:tabs` unconditionally, so leaving `useRegistry` at its default\n\t\t * `true` warned on every detail page that publishes tabs — advice no\n\t\t * consumer could act on, since they never see this element. Published\n\t\t * tabs mean tabs mode, which is what the sidebar picks anyway.\n\t\t *\n\t\t * @return {boolean}\n\t\t */\n\t\tobjectSidebarUseRegistry() {\n\t\t\tconst tabs = this.effectiveObjectSidebarState?.tabs\n\t\t\treturn !(Array.isArray(tabs) && tabs.length > 0)\n\t\t},\n\n\t\t/**\n\t\t * Decide whether THIS CnAppRoot should render the hoisted\n\t\t * CnObjectSidebar. False when:\n\t\t * - the consumer fills `#sidebar` (their slot owns the rail);\n\t\t * - an ancestor already provides `objectSidebarState`\n\t\t * (ancestor renders its own sidebar);\n\t\t * - `localObjectSidebarState.active` is false (default);\n\t\t * - `objectType` + `objectId` are both empty (defense-in-\n\t\t * depth against CnIndexPage's fallback writing `active:\n\t\t * true` into the wrong channel — see\n\t\t * CnAppRootObjectSidebar.spec.js for the regression).\n\t\t *\n\t\t * @return {boolean}\n\t\t */\n\t\tshouldAutoMountObjectSidebar() {\n\t\t\tif (this.$slots && this.$slots.sidebar) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tif (this.$slots && this.$slots.sidebar) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tif (this.ancestorObjectSidebarState) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tconst holder = this.localObjectSidebarState\n\t\t\tif (!holder || !holder.active) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tconst hasObjectCoordinates = !!(holder.objectType && holder.objectId)\n\t\t\treturn hasObjectCoordinates\n\t\t},\n\n\t\t/**\n\t\t * Resolved support-dialog config — the manifest's `support` block\n\t\t * (authored in Buildiq's \"Edit support & donation\" editor) overlaid\n\t\t * by any host-supplied `supportDialog` override object, so app authors\n\t\t * can configure the donation/support note entirely from the UI while a\n\t\t * host can still override per-mount.\n\t\t *\n\t\t * @return {object}\n\t\t */\n\t\tcnSupportConfig() {\n\t\t\tconst fromManifest = (this.manifest && this.manifest.support && typeof this.manifest.support === 'object')\n\t\t\t\t? this.manifest.support\n\t\t\t\t: {}\n\t\t\tconst fromProp = (this.supportDialog && typeof this.supportDialog === 'object')\n\t\t\t\t? this.supportDialog\n\t\t\t\t: {}\n\t\t\treturn { ...fromManifest, ...fromProp }\n\t\t},\n\n\t\t/**\n\t\t * App display name for the support note — host override, else the\n\t\t * capitalised `appId` (e.g. `pipelinq` → `Pipelinq`).\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\tcnSupportAppName() {\n\t\t\tif (this.cnSupportConfig.appName) {\n\t\t\t\treturn this.cnSupportConfig.appName\n\t\t\t}\n\t\t\treturn this.appId\n\t\t\t\t? this.appId.charAt(0).toUpperCase() + this.appId.slice(1)\n\t\t\t\t: ''\n\t\t},\n\n\t\t/**\n\t\t * App Store listing URL — host override, else the conventional\n\t\t * `apps.nextcloud.com/apps/{appId}`.\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\tcnSupportAppStoreUrl() {\n\t\t\treturn this.cnSupportConfig.appStoreUrl\n\t\t\t\t|| ('https://apps.nextcloud.com/apps/' + this.appId)\n\t\t},\n\n\t\t/**\n\t\t * Feature-request URL — host override, else the new-issue link on\n\t\t * the app's own forge. Derived from the SAME resolved repo and\n\t\t * forge the actions menu uses, rather than a second hardcoded\n\t\t * host: this spelled out `codeberg.org/Conduction/{appId}` and so\n\t\t * kept pointing at the unmaintained mirror after the fleet moved\n\t\t * back to GitHub, while the menu's link had already moved.\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\tcnSupportFeatureRequestUrl() {\n\t\t\tif (this.cnSupportConfig.featureRequestUrl) {\n\t\t\t\treturn this.cnSupportConfig.featureRequestUrl\n\t\t\t}\n\t\t\tconst { baseUrl } = resolveForge(this.resolvedFeatureRequestForge)\n\t\t\treturn `${baseUrl}/${this.resolvedFeatureRequestRepo}/issues/new`\n\t\t},\n\n\t\t/**\n\t\t * Pass-through of any other `CnSupportDialog` props supplied in\n\t\t * the `supportDialog` override object (donateUrl, supportUrl,\n\t\t * conductionUrl, appsUrl, founderName/title/avatar/profile,\n\t\t * bodyParagraphs). Lets a host re-sign the note without forking.\n\t\t *\n\t\t * @return {object}\n\t\t */\n\t\tcnSupportOverrides() {\n\t\t\tconst cfg = this.cnSupportConfig\n\t\t\tconst passthrough = ['title', 'donateUrl', 'supportUrl', 'conductionUrl', 'appsUrl', 'founderName', 'founderTitle', 'founderAvatarUrl', 'founderProfileUrl', 'bodyParagraphs', 'buttons']\n\t\t\tconst out = {}\n\t\t\tfor (const key of passthrough) {\n\t\t\t\tif (cfg[key] !== undefined) {\n\t\t\t\t\tout[key] = cfg[key]\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn out\n\t\t},\n\n\t\t/**\n\t\t * Whether the `CnCommandPalette` auto-mount is active — `true`, or\n\t\t * an override object (per the `supportDialog` Boolean|Object\n\t\t * convention above).\n\t\t *\n\t\t * @return {boolean}\n\t\t */\n\t\tcnCommandPaletteVisible() {\n\t\t\treturn this.commandPalette === true || (!!this.commandPalette && typeof this.commandPalette === 'object')\n\t\t},\n\n\t\t/**\n\t\t * Prop overrides supplied via the `commandPalette` object form,\n\t\t * spread onto `CnCommandPalette` OVER the auto-wired `manifest` /\n\t\t * `router` / `app-id` — so an app can override e.g. `objectSearch`\n\t\t * or `shortcut` without losing the zero-config navigation source.\n\t\t *\n\t\t * @return {object}\n\t\t */\n\t\tcnCommandPaletteOverrides() {\n\t\t\treturn (this.commandPalette && typeof this.commandPalette === 'object') ? this.commandPalette : {}\n\t\t},\n\n\t\t/**\n\t\t * Per-dependency status, computed once per `appId` declared in\n\t\t * `manifest.dependencies`. Reading the value here triggers the\n\t\t * useAppStatus composable for each id; results are cached\n\t\t * module-side so subsequent reads are free.\n\t\t */\n\t\tdependencyStatuses() {\n\t\t\tconst deps = Array.isArray(this.manifest?.dependencies)\n\t\t\t\t? this.manifest.dependencies\n\t\t\t\t: []\n\t\t\t// HARD/SOFT dependency model (REQ-DIA-4/REQ-DIA-5). Each manifest\n\t\t\t// entry is normalised to `{ id, required, name, status }`:\n\t\t\t// - string → HARD (`required: true`), name = id\n\t\t\t// - { id, required?, name? } → `required` defaults to true;\n\t\t\t// `required: false` marks a SOFT (optional) dependency.\n\t\t\treturn deps\n\t\t\t\t.map((entry) => {\n\t\t\t\t\tconst isObject = entry !== null && typeof entry === 'object'\n\t\t\t\t\tconst id = isObject ? entry.id : entry\n\t\t\t\t\tif (typeof id !== 'string' || id === '') {\n\t\t\t\t\t\treturn null\n\t\t\t\t\t}\n\t\t\t\t\tconst required = isObject ? entry.required !== false : true\n\t\t\t\t\tconst name = (isObject && entry.name) || id\n\t\t\t\t\treturn { id, required, name, status: useAppStatus(id) }\n\t\t\t\t})\n\t\t\t\t.filter((entry) => entry !== null)\n\t\t},\n\n\t\t/**\n\t\t * App statuses injected by the PHP boot() via IInitialStateService.\n\t\t * Keyed by app id: { installed: bool, enabled: bool }.\n\t\t * Falls back to {} when not injected (non-pipelinq consumers, tests).\n\t\t */\n\t\tserverAppStatuses() {\n\t\t\ttry {\n\t\t\t\tconst statuses = loadState(this.appId, 'dependency_statuses', {})\n\t\t\t\treturn statuses\n\t\t\t} catch {\n\t\t\t\treturn {}\n\t\t\t}\n\t\t},\n\n\t\tunresolvedDependencies() {\n\t\t\treturn this.dependencyStatuses\n\t\t\t\t.filter(({ id, status }) => {\n\t\t\t\t\tconst server = this.serverAppStatuses[id]\n\t\t\t\t\tif (server !== undefined) {\n\t\t\t\t\t\treturn !server.installed || !server.enabled\n\t\t\t\t\t}\n\t\t\t\t\treturn !status.installed.value || !status.enabled.value\n\t\t\t\t})\n\t\t\t\t.map(({ id, required, name }) => {\n\t\t\t\t\tconst server = this.serverAppStatuses[id]\n\t\t\t\t\tif (server !== undefined) {\n\t\t\t\t\t\t// Server data available: correctly distinguish the two states.\n\t\t\t\t\t\t// enabled: false → installed but disabled (→ \"Enable\")\n\t\t\t\t\t\t// enabled: undefined → not installed (→ \"Install\")\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tid,\n\t\t\t\t\t\t\tname,\n\t\t\t\t\t\t\trequired,\n\t\t\t\t\t\t\tcategory: server.category ?? 'featured',\n\t\t\t\t\t\t\tenabled: server.installed ? false : undefined,\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t// No server data and the JS heuristic cannot tell not-installed\n\t\t\t\t\t// from installed-but-disabled. Default to the safe \"not\n\t\t\t\t\t// installed\" shape (enabled: undefined → \"Install and enable\"):\n\t\t\t\t\t// a genuinely-missing app must never be mislabelled \"Enable\".\n\t\t\t\t\treturn { id, name, required, category: 'featured', enabled: undefined }\n\t\t\t\t})\n\t\t},\n\n\t\t/**\n\t\t * Unresolved HARD dependencies — the app cannot run without these,\n\t\t * so their presence gates the shell behind the blocking\n\t\t * `dependency-missing` phase / `CnDependencyMissing` screen\n\t\t * (REQ-DIA-5).\n\t\t *\n\t\t * @return {Array<object>} Unresolved entries with `required === true`.\n\t\t */\n\t\tunresolvedHardDependencies() {\n\t\t\treturn this.unresolvedDependencies.filter((dep) => dep.required)\n\t\t},\n\n\t\t/**\n\t\t * Unresolved SOFT dependencies — optional integrations whose\n\t\t * absence must NOT block the shell. Each surfaces as a dismissible\n\t\t * in-shell `NcNoteCard` banner (REQ-DIA-6), filtered here to those\n\t\t * not yet dismissed in `localStorage`.\n\t\t *\n\t\t * @return {Array<object>} Undismissed unresolved entries with\n\t\t * `required === false`.\n\t\t */\n\t\tunresolvedSoftDependencies() {\n\t\t\treturn this.unresolvedDependencies\n\t\t\t\t.filter((dep) => !dep.required)\n\t\t\t\t.filter((dep) => !this.dismissedSoftDeps.includes(dep.id))\n\t\t},\n\n\t\t/**\n\t\t * The soft-dependency notices actually RENDERED in the shell. Empty\n\t\t * unless the deprecated `softDependencyNotices` prop is switched back\n\t\t * on — the banners now live in admin settings\n\t\t * (`CnLeafDependencySettings`) instead of above every index page.\n\t\t * `unresolvedSoftDependencies` itself is untouched and still exposed,\n\t\t * so an app rendering its own surface from it keeps working.\n\t\t *\n\t\t * @return {Array<object>}\n\t\t */\n\t\tvisibleSoftDependencyNotices() {\n\t\t\treturn this.softDependencyNotices ? this.unresolvedSoftDependencies : []\n\t\t},\n\n\t\t/**\n\t\t * First-time-setup status for this app (ADR-042), or null when the\n\t\t * manifest declares no `setup` block. Calls useSetupStatus inside the\n\t\t * computed so the returned refs stay reactive (same pattern as\n\t\t * unresolvedDependencies → useAppStatus).\n\t\t */\n\t\tsetupState() {\n\t\t\tif (!this.appId || !this.manifest || !this.manifest.setup || this.manifest.setup.enabled === false) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\treturn useSetupStatus(this.appId, this.manifest)\n\t\t},\n\n\t\t/**\n\t\t * Whether a REQUIRED setup step is unmet — the app shell is gated to\n\t\t * the setup wizard until this clears. Never gates while the status is\n\t\t * still loading (avoids a flash before the answer is known).\n\t\t */\n\t\tsetupGating() {\n\t\t\tconst s = this.setupState\n\t\t\treturn !!s && s.loading.value === false && s.requiredUnmet.value.length > 0\n\t\t},\n\n\t\t/**\n\t\t * Whether the setup status is still loading. `false` when the manifest\n\t\t * declares no setup block.\n\t\t */\n\t\tsetupStatusLoading() {\n\t\t\tconst s = this.setupState\n\t\t\treturn !!s && s.loading.value !== false\n\t\t},\n\n\t\t/**\n\t\t * Whether the setup wizard should be OFFERED (non-gating) because\n\t\t * every required step is met but at least one ACTIONABLE optional step\n\t\t * isn't (REQ-SETUP-NV-012). Never true while the gating phase is active —\n\t\t * required-unmet already renders `CnSetupWizard` itself.\n\t\t *\n\t\t * Two independent guards keep this from being permanently true, because\n\t\t * a step can look \"unmet\" for two unrelated reasons:\n\t\t *\n\t\t * 1. Only steps the server POSITIVELY REPORTED count. An app may declare\n\t\t * optional steps its SetupController never reports a status key for —\n\t\t * pipelinq's `demo-data` run-action is one — and such a step is\n\t\t * UNKNOWN, not outstanding. Auto-opening on it parked the wizard over\n\t\t * the app on every fresh browser profile even though\n\t\t * `/api/setup/status` answered `200 {completed:true}`, which read as\n\t\t * \"the setup gate never clears\" and timed out every UI e2e spec in the\n\t\t * consuming app.\n\t\t *\n\t\t * This guard used to be a blanket short-circuit on the server's\n\t\t * `completed` flag — a BLUNTER instrument aimed at the same target,\n\t\t * which overshot. `completed` means \"no REQUIRED step is\n\t\t * outstanding\", so it is true for every correctly-configured app, and\n\t\t * suppressing on it hid reported-and-undone OPTIONAL steps too.\n\t\t * Dossiq declares a `seed` step whose controller answers\n\t\t * `{done: false}` — genuinely outstanding, genuinely actionable — and\n\t\t * the wizard offering it never opened, leaving the app with no\n\t\t * reachable demo-data affordance at all. `completed` is still honoured\n\t\t * as a NEGATIVE signal (a server saying \"unfinished\" is believed\n\t\t * outright); it just no longer overrides a step the server explicitly\n\t\t * reported as not done.\n\t\t *\n\t\t * 2. `info` and `summary` steps are excluded: the server has nothing to\n\t\t * persist for them, so they report `done: false` forever and would\n\t\t * keep this permanently true (auto-prompting fully-configured users)\n\t\t * even when `completed` is absent or false.\n\t\t *\n\t\t * Neither guard subsumes the other — (1) is about steps the server never\n\t\t * reports, (2) about steps it can never mark done — so both are needed.\n\t\t *\n\t\t * 3. On-demand steps (`onDemand: true`) are excluded too: they run only\n\t\t * when the user asks (learniq's \"Remove the example data\"), so they\n\t\t * are never outstanding work.\n\t\t *\n\t\t * @return {boolean} True when an actionable optional step is genuinely outstanding.\n\t\t */\n\t\toptionalSetupPending() {\n\t\t\tconst s = this.setupState\n\t\t\tif (!s || s.loading.value !== false) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tif (s.requiredUnmet.value.length > 0) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\t// When the server itself says setup is UNFINISHED, take it at its word:\n\t\t\t// every unmet optional step is fair game, reported or not.\n\t\t\t//\n\t\t\t// When it says setup IS complete, only steps it positively reported\n\t\t\t// as `{done: false}` are outstanding. An unreported step is unknown,\n\t\t\t// and prompting on unknown is what parked the wizard over pipelinq.\n\t\t\tconst outstanding = s.completed.value === true\n\t\t\t\t? (s.optionalUnmetReported ? s.optionalUnmetReported.value : [])\n\t\t\t\t: s.optionalUnmet.value\n\t\t\t// On-demand steps (`onDemand: true`) run only when the user asks,\n\t\t\t// so they are never outstanding and never reason to open the wizard.\n\t\t\treturn outstanding.some((st) => st.type !== 'info' && st.type !== 'summary' && st.onDemand !== true)\n\t\t},\n\n\t\t/**\n\t\t * Ids of setup steps the server already reports done. Passed to\n\t\t * `CnSetupWizard` so a freshly (re)mounted wizard resumes at the\n\t\t * first actually-unmet step instead of restarting from the top —\n\t\t * the wizard's own local state only tracks the current session.\n\t\t *\n\t\t * @return {Array<string>}\n\t\t */\n\t\tsetupCompletedStepIds() {\n\t\t\tconst s = this.setupState\n\t\t\treturn s ? s.steps.value.filter((st) => st.done).map((st) => st.id) : []\n\t\t},\n\n\t\t/**\n\t\t * The manifest's `section: \"integrations\"` menu entries — the links\n\t\t * that leave this app for another one, rendered in the Integrations\n\t\t * section of the per-user settings modal rather than in the navigation\n\t\t * (ADR-110).\n\t\t *\n\t\t * Applies the SAME `permission` and `visibleIf` rules CnAppNav applies\n\t\t * to nav entries, for two reasons. Skipping `permission` would surface\n\t\t * an admin-only link to everyone, and skipping `visibleIf.appInstalled`\n\t\t * would list a link to an app that is not installed — a guaranteed\n\t\t * 404 presented as a feature. That second case is the whole reason\n\t\t * these entries are worth gating: unlike a nav entry pointing at this\n\t\t * app's own route, a cross-app link can be dead through no fault of\n\t\t * this app.\n\t\t *\n\t\t * Only clickable entries qualify: `href` is what makes a row a link,\n\t\t * and a group with children has no meaning in a flat settings section.\n\t\t *\n\t\t * @return {Array<object>} Ordered, filtered integration entries.\n\t\t */\n\t\tintegrationEntries() {\n\t\t\tconst items = (this.manifest && this.manifest.menu) || []\n\t\t\treturn items\n\t\t\t\t.filter((item) => item.section === 'integrations')\n\t\t\t\t.filter((item) => typeof item.href === 'string' && item.href !== '')\n\t\t\t\t.filter((item) => this.passesIntegrationPermission(item))\n\t\t\t\t.filter((item) => this.passesIntegrationVisibleIf(item))\n\t\t\t\t.slice()\n\t\t\t\t.sort((a, b) => {\n\t\t\t\t\tconst aHas = typeof a.order === 'number'\n\t\t\t\t\tconst bHas = typeof b.order === 'number'\n\t\t\t\t\tif (aHas && !bHas) {\n\t\t\t\t\t\treturn -1\n\t\t\t\t\t}\n\t\t\t\t\tif (!aHas && bHas) {\n\t\t\t\t\t\treturn 1\n\t\t\t\t\t}\n\t\t\t\t\tif (!aHas && !bHas) {\n\t\t\t\t\t\treturn 0\n\t\t\t\t\t}\n\t\t\t\t\treturn a.order - b.order\n\t\t\t\t})\n\t\t},\n\n\t\t/**\n\t\t * Whether the manifest declares an enabled walkthrough with at least one\n\t\t * tour (ADR-043). Drives the non-gating CnWalkthrough overlay in the shell.\n\t\t *\n\t\t * @return {boolean} True when a walkthrough should mount.\n\t\t */\n\t\twalkthroughEnabled() {\n\t\t\tconst w = this.manifest && this.manifest.walkthrough\n\t\t\treturn !!(w && w.enabled !== false && Array.isArray(w.tours) && w.tours.length > 0)\n\t\t},\n\n\t\t/**\n\t\t * The per-user preference key holding the last app version whose tour the\n\t\t * user has seen (`manifest.walkthrough.completionConfigKey`). Empty when\n\t\t * the manifest declares none, in which case persistence stays per-browser.\n\t\t *\n\t\t * @return {string} The preference key, or ''.\n\t\t */\n\t\twalkthroughConfigKey() {\n\t\t\tconst w = this.manifest && this.manifest.walkthrough\n\t\t\treturn (w && typeof w.completionConfigKey === 'string' && w.completionConfigKey) || ''\n\t\t},\n\n\t\t/**\n\t\t * Whether the setup flow holds the walkthrough back: the setup status\n\t\t * has not settled yet (an outstanding optional step may still open the\n\t\t * wizard), or the non-gating setup wizard is open. The gating setup\n\t\t * phase needs no check here, it replaces the shell (and the tour with\n\t\t * it) outright. Apps without a `setup` block settle immediately, so\n\t\t * this is `false` for them from the first render.\n\t\t *\n\t\t * @return {boolean} True while the tour must wait for setup.\n\t\t */\n\t\twalkthroughHeldForSetup() {\n\t\t\treturn !this.setupStatusSettled || this.setupWizardOpen\n\t\t},\n\n\t\t/**\n\t\t * The user's last-seen app version for walkthrough composition. Resolved\n\t\t * from the per-user `completionConfigKey` preference (cross-device) with\n\t\t * the localStorage mirror as fallback; CnAppRoot writes BOTH on completion\n\t\t * or dismissal, so a returning user is not shown the tour again.\n\t\t *\n\t\t * @return {string} The last-seen version, or '' for a fresh user.\n\t\t */\n\t\twalkthroughSeenVersion() {\n\t\t\treturn this.walkthroughSeenVersionValue\n\t\t},\n\n\t\t/**\n\t\t * Cross-app / refresh resume token parsed from the URL query\n\t\t * (`cn_resume_tour` / `cn_resume_step`), or null.\n\t\t *\n\t\t * @return {object|null} `{ tourId, stepId }` or null.\n\t\t */\n\t\twalkthroughResume() {\n\t\t\ttry {\n\t\t\t\tconst p = new URLSearchParams(window.location.search)\n\t\t\t\tconst tourId = p.get('cn_resume_tour')\n\t\t\t\tif (!tourId) {\n\t\t\t\t\treturn null\n\t\t\t\t}\n\t\t\t\treturn { tourId, stepId: p.get('cn_resume_step') || '' }\n\t\t\t} catch {\n\t\t\t\treturn null\n\t\t\t}\n\t\t},\n\n\t\tphase() {\n\t\t\tif (this.isLoading) {\n\t\t\t\treturn 'loading'\n\t\t\t}\n\t\t\t// Only unresolved HARD dependencies block the shell (REQ-DIA-5);\n\t\t\t// unresolved SOFT dependencies surface as a non-blocking in-shell\n\t\t\t// banner and let the app advance to setup/shell.\n\t\t\tif (this.unresolvedHardDependencies.length > 0) {\n\t\t\t\treturn 'dependency-missing'\n\t\t\t}\n\t\t\tif (this.setupGating) {\n\t\t\t\treturn 'setup'\n\t\t\t}\n\t\t\treturn 'shell'\n\t\t},\n\n\t\t/**\n\t\t * Default link surfaced by the missing-app empty-state action.\n\t\t * Points at the OpenRegister integration page in the Nextcloud\n\t\t * app store. Replaceable per consumer via the `#or-missing`\n\t\t * slot.\n\t\t */\n\t\torStoreLink() {\n\t\t\treturn OR_STORE_LINK\n\t\t},\n\n\t\t/**\n\t\t * Whether the current user is a Nextcloud admin. Only admins can\n\t\t * hit `settings/apps/enable`, so both dependency surfaces branch on\n\t\t * this: admins get the in-place install/enable action, non-admins\n\t\t * get \"ask your administrator\" copy (REQ-DIA-2 / REQ-DIA-3).\n\t\t *\n\t\t * ALSO passed to CnAppNav as `is-admin` to gate visibility of the\n\t\t * \"Admin settings\" link to `/settings/admin/<appId>` (ADR-079 §3).\n\t\t * Read from `getCurrentUser()?.isAdmin` (`@nextcloud/auth`), never\n\t\t * the legacy `OC.isUserAdmin()` global. Presentation only — the\n\t\t * access boundary is Nextcloud's settings framework, which refuses\n\t\t * that page server-side for non-admins. A DIFFERENT signal from\n\t\t * `isOwner` (which means \"owns this app\", not \"administers this\n\t\t * instance\"); the two must not be conflated.\n\t\t *\n\t\t * @return {boolean}\n\t\t */\n\t\tisAdmin() {\n\t\t\ttry {\n\t\t\t\treturn getCurrentUser()?.isAdmin === true\n\t\t\t} catch {\n\t\t\t\treturn false\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * The missing app the or-missing guard's primary install/enable\n\t\t * action targets — the first entry of `missingApps` (typically\n\t\t * `openregister`). Empty string when nothing is missing.\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\torMissingPrimaryApp() {\n\t\t\treturn this.missingApps[0] || ''\n\t\t},\n\n\t\t/**\n\t\t * Human-readable list of the missing apps for the guard copy.\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\tmissingAppsLabel() {\n\t\t\treturn this.missingApps.join(', ')\n\t\t},\n\n\t\t/**\n\t\t * Guard title — the translated `app-availability.title`, or a\n\t\t * sensible English default when the key is untranslated (REQ-DIA-7).\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\torMissingTitle() {\n\t\t\treturn this.availabilityCopy('app-availability.title', 'Required app not available')\n\t\t},\n\n\t\t/**\n\t\t * Guard description — translated `app-availability.description` or an\n\t\t * English default naming the missing app(s) (REQ-DIA-7).\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\torMissingDescription() {\n\t\t\treturn this.availabilityCopy(\n\t\t\t\t'app-availability.description',\n\t\t\t\t`This app requires ${this.missingAppsLabel || 'another Nextcloud app'} to be installed and enabled.`,\n\t\t\t)\n\t\t},\n\n\t\t/**\n\t\t * Fallback store-link label — translated `app-availability.action`\n\t\t * or an English default (REQ-DIA-7).\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\torMissingActionLabel() {\n\t\t\treturn this.availabilityCopy('app-availability.action', 'Open app settings')\n\t\t},\n\n\t\t/**\n\t\t * Admin install button label for the or-missing guard.\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\torMissingInstallLabel() {\n\t\t\treturn this.availabilityCopy('app-availability.install', 'Install and enable')\n\t\t},\n\n\t\t/**\n\t\t * Non-admin \"ask your administrator\" copy for the or-missing guard\n\t\t * (REQ-DIA-3), naming the missing app(s).\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\torMissingAskAdmin() {\n\t\t\treturn this.availabilityCopy(\n\t\t\t\t'app-availability.ask-admin',\n\t\t\t\t`Ask your administrator to enable ${this.missingAppsLabel || 'the required app'}.`,\n\t\t\t)\n\t\t},\n\n\t\t/**\n\t\t * Soft-dependency install-action label (app not installed).\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\tsoftDepInstallLabel() {\n\t\t\treturn this.availabilityCopy('app-availability.soft.install', 'Install and enable')\n\t\t},\n\n\t\t/**\n\t\t * Soft-dependency enable-action label (installed but disabled).\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\tsoftDepEnableLabel() {\n\t\t\treturn this.availabilityCopy('app-availability.soft.enable', 'Enable')\n\t\t},\n\n\t\t/**\n\t\t * Soft-dependency dismiss-action label.\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\tsoftDepDismissLabel() {\n\t\t\treturn this.availabilityCopy('app-availability.soft.dismiss', 'Dismiss')\n\t\t},\n\n\t\t/**\n\t\t * Repo target for the built-in feature-request deep link.\n\t\t * Provided to descendants under the `cnFeatureRequestRepo`\n\t\t * inject key. Reads `manifest.nav.featureRequestRepo` when set;\n\t\t * falls back to `ConductionNL/<appId>` — the convention for\n\t\t * every Conduction app on GitHub, which is where DEFAULT_FORGE\n\t\t * points. The fallback used the Codeberg org slug `Conduction`\n\t\t * while the forge default was Codeberg; the forge moved back to\n\t\t * GitHub and this did not, so every app that configures nothing\n\t\t * — which is every app, no fleet manifest sets\n\t\t * `nav.featureRequestRepo` — resolved to a github.com org that\n\t\t * does not exist. Deriving it from `appId` is what keeps this\n\t\t * right per app: no consumer hardcodes its own slug, and an app\n\t\t * whose repo is named differently sets the manifest field.\n\t\t * GitHub resolves repo-name casing, so a lowercase `appId`\n\t\t * reaches a CamelCase repo. Returns empty string when no\n\t\t * `appId` is available (defensive — should never happen since\n\t\t * `appId` is a required prop).\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\tresolvedFeatureRequestRepo() {\n\t\t\tconst explicit = this.manifest?.nav?.featureRequestRepo\n\t\t\tif (typeof explicit === 'string' && explicit.length > 0) {\n\t\t\t\treturn explicit\n\t\t\t}\n\t\t\tif (!this.appId) {\n\t\t\t\treturn ''\n\t\t\t}\n\t\t\treturn `ConductionNL/${this.appId}`\n\t\t},\n\n\t\t/**\n\t\t * Forge config for the built-in feature-request deep link,\n\t\t * provided under the `cnFeatureRequestForge` inject key. Reads\n\t\t * `manifest.nav.forge` and merges it over the Codeberg default,\n\t\t * so a manifest may set just `type` (e.g. back to `github`) or\n\t\t * also `baseUrl` (self-hosted Forgejo/Gitea).\n\t\t *\n\t\t * @return {{type: string, baseUrl: string}}\n\t\t */\n\t\tresolvedFeatureRequestForge() {\n\t\t\tconst cfg = this.manifest?.nav?.forge\n\t\t\treturn { ...DEFAULT_FORGE, ...(cfg && typeof cfg === 'object' ? cfg : {}) }\n\t\t},\n\n\t\tresolvedUserSettingsTitle() {\n\t\t\treturn this.userSettingsTitle || this.translate('User settings')\n\t\t},\n\n\t\t/**\n\t\t * Title for the admin-settings modal. Prop override, else the\n\t\t * translated \"Administration\". Mirrors `resolvedUserSettingsTitle`.\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\tresolvedAdminSettingsTitle() {\n\t\t\treturn this.adminSettingsTitle || this.translate('Administration')\n\t\t},\n\n\t\t/**\n\t\t * Section heading for the walkthrough-replay block in user settings.\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\trestartWalkthroughSectionName() {\n\t\t\treturn this.translate('Walkthrough')\n\t\t},\n\n\t\t/**\n\t\t * Explanatory line above the restart-walkthrough button.\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\trestartWalkthroughHint() {\n\t\t\treturn this.translate('Take the guided tour of this app again.')\n\t\t},\n\n\t\t/**\n\t\t * Label for the restart-walkthrough button in user settings.\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\trestartWalkthroughLabel() {\n\t\t\treturn this.translate('Restart walkthrough')\n\t\t},\n\n\t\t/**\n\t\t * Resolve the active modal's Vue component from the registry.\n\t\t * Returns null when no modal is open or the key no longer resolves.\n\t\t *\n\t\t * @return {object|null}\n\t\t */\n\t\tactiveModalComponent() {\n\t\t\tif (!this.activeModalKey) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst entry = (this.registry || {})[this.activeModalKey]\n\t\t\treturn (entry && entry.component) ? entry.component : null\n\t\t},\n\t},\n\n\twatch: {\n\t\t/**\n\t\t * Close a registry modal when the route changes.\n\t\t *\n\t\t * `cnOpenModal` sets `activeModalKey` and only the modal's own `close`\n\t\t * clears it, so navigating away left the dialog mounted over the new\n\t\t * page — open \"New lead\" on a dashboard, click through to another page,\n\t\t * and the dialog follows you there, still covering the content.\n\t\t */\n\t\t$route() {\n\t\t\tthis.activeModalKey = null\n\t\t},\n\n\t\t/**\n\t\t * Auto-open the non-gating setup wizard once optional-unmet becomes\n\t\t * true, unless the user already dismissed this manifest version.\n\t\t * `immediate: true` so a fresh mount that's already optional-unmet\n\t\t * opens it without waiting for a later reactive change.\n\t\t */\n\t\toptionalSetupPending: {\n\t\t\timmediate: true,\n\t\t\thandler(pending) {\n\t\t\t\tif (pending && !this.isSetupWizardDismissed()) {\n\t\t\t\t\tthis.setupWizardOpen = true\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\n\t\t/**\n\t\t * Resolve the per-user walkthrough completion preference whenever the\n\t\t * declared `completionConfigKey` appears or changes (ADR-043).\n\t\t * `immediate: true` covers the common static-manifest case; the watch\n\t\t * also covers a manifest that arrives asynchronously, where a\n\t\t * mount-time-only read would have found no key and let the tour open\n\t\t * for a user who already finished it.\n\t\t */\n\t\twalkthroughConfigKey: {\n\t\t\timmediate: true,\n\t\t\thandler(key) {\n\t\t\t\tif (!key) {\n\t\t\t\t\tthis.walkthroughSeenResolved = true\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tthis.walkthroughSeenResolved = false\n\t\t\t\tthis.resolveWalkthroughSeenVersion()\n\t\t\t},\n\t\t},\n\n\t\tsetupStatusLoading: {\n\t\t\timmediate: true,\n\t\t\thandler(loading) {\n\t\t\t\tif (!loading) {\n\t\t\t\t\tthis.setupStatusSettled = true\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t},\n\n\tmounted() {\n\t\t// Nested modals: without this every `.modal-mask` in the app shares one\n\t\t// z-index, so two open dialogs tie and the painting order falls back to\n\t\t// DOM order between two nodes teleported to <body> — clicks aimed at the\n\t\t// top dialog get swallowed by the one underneath. Installed on the app\n\t\t// root (not per dialog) because the colliding dialogs are not all ours:\n\t\t// the consuming app's own NcDialogs need the same layering, and\n\t\t// @nextcloud/vue exposes no z-index prop. Reference-counted, so the\n\t\t// nested CnAppRoot in Buildiq's BuilderHost is safe.\n\t\tinstallModalStack()\n\n\t\t// Guard against silently losing unsaved in-app edits. The manifest\n\t\t// editor stays `dirty` for the whole Save (the persist PUT can take a\n\t\t// few seconds), so a refresh mid-save would drop the edit before the\n\t\t// write lands; this warns the user while there are unsaved/in-flight\n\t\t// changes. Registered before the early-return so it always installs.\n\t\twindow.addEventListener('beforeunload', this.onBeforeUnload)\n\n\t\t// Opt-out fast-path: empty `requiresApps` already initialised\n\t\t// `capabilitiesLoading` to `false` in data(); skip the check.\n\t\tif (!Array.isArray(this.requiresApps) || this.requiresApps.length === 0) {\n\t\t\tthis._validateRegistry()\n\t\t\tthis._warnCustomComponentsDeprecation()\n\t\t\tthis._hydrateMenuCounts()\n\t\t\treturn\n\t\t}\n\n\t\ttry {\n\t\t\t// Use useAppStatus which checks OC.appswebroots first — Nextcloud\n\t\t\t// populates that map for every enabled app regardless of which\n\t\t\t// folder it lives in (apps/, custom-apps/, custom_apps/). Falling\n\t\t\t// back to getCapabilities() alone misses apps that do not register\n\t\t\t// an ICapability (OpenRegister being the primary example).\n\t\t\tthis.missingApps = this.requiresApps.filter((id) => {\n\t\t\t\tconst { installed } = useAppStatus(id)\n\t\t\t\treturn !installed.value\n\t\t\t})\n\t\t} catch (err) {\n\t\t\t// eslint-disable-next-line no-console\n\t\t\tconsole.warn(\n\t\t\t\t'[CnAppRoot] Failed to check app availability for the app-availability guard:',\n\t\t\t\terr,\n\t\t\t)\n\t\t\tthis.guardError = err\n\t\t\tthis.missingApps = []\n\t\t} finally {\n\t\t\tthis.capabilitiesLoading = false\n\t\t}\n\n\t\tthis._validateRegistry()\n\t\tthis._warnCustomComponentsDeprecation()\n\t\tthis._hydrateMenuCounts()\n\t},\n\n\tbeforeUnmount() {\n\t\twindow.removeEventListener('beforeunload', this.onBeforeUnload)\n\t\tthis.cnScopedTheme.teardown(this.appId)\n\t\t// Scope the side effect to the shell's lifetime. Layers already written\n\t\t// stay on screen (see `uninstallModalStack`), so a dialog outliving the\n\t\t// shell does not lose its stacking.\n\t\tuninstallModalStack()\n\t},\n\n\tmethods: {\n\t\t/**\n\t\t * Permission gate for an Integrations entry — deliberately identical\n\t\t * to `CnAppNav.passesPermission`, including the \"no permissions prop\n\t\t * means do not filter\" escape. The two surfaces read the same\n\t\t * `menu[]` array, so a rule that held in the nav and not here would\n\t\t * mean an entry's visibility changed purely by being relocated.\n\t\t *\n\t\t * @param {object} item The menu entry.\n\t\t * @return {boolean} True when the entry may render.\n\t\t */\n\t\tpassesIntegrationPermission(item) {\n\t\t\tif (!item.permission) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\tif (!this.permissions || this.permissions.length === 0) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\treturn this.permissions.includes(item.permission)\n\t\t},\n\n\t\t/**\n\t\t * `visibleIf` gate for an Integrations entry, mirroring\n\t\t * `CnAppNav.passesVisibleIf`. `appInstalled` matters more here than\n\t\t * anywhere else in the manifest: it is what stops the section\n\t\t * advertising a link into an app the instance does not have.\n\t\t *\n\t\t * @param {object} item The menu entry.\n\t\t * @return {boolean} True when the entry may render.\n\t\t */\n\t\tpassesIntegrationVisibleIf(item) {\n\t\t\tconst condition = item.visibleIf\n\t\t\tif (!condition || typeof condition !== 'object') {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\tif (condition.appInstalled && !isAppInstalled(condition.appInstalled)) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tconst runtime = (this.manifest && this.manifest.runtime) || null\n\t\t\treturn passesContextPredicates(condition, runtime)\n\t\t},\n\n\t\t/**\n\t\t * Re-fetch the pages editor's register/schema data sources via the\n\t\t * `dataSourcesLoader` prop. Provided to descendants as\n\t\t * `cnRefreshDataSources`; the pages-editor modals call it on open.\n\t\t *\n\t\t * Mutates `dataSourcesState` in place (never reassigns it — see the\n\t\t * stable-identity contract in `data()`). A refresh already in flight\n\t\t * is reused rather than duplicated, so two modals opening at once\n\t\t * issue one fetch. The previous list stays in `value` while a refresh\n\t\t * runs and survives a failure, so the user can keep editing against\n\t\t * the last known-good data instead of an empty dropdown.\n\t\t *\n\t\t * @return {Promise<void>} Resolves when the refresh settles. Never rejects.\n\t\t */\n\t\tasync refreshDataSources() {\n\t\t\tif (typeof this.dataSourcesLoader !== 'function') {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif (this._dataSourcesInFlight) {\n\t\t\t\treturn this._dataSourcesInFlight\n\t\t\t}\n\n\t\t\tthis.dataSourcesState.loading = true\n\t\t\tthis.dataSourcesState.error = null\n\n\t\t\t// Wrapped so a loader that throws synchronously is handled\n\t\t\t// identically to one that returns a rejecting promise.\n\t\t\tthis._dataSourcesInFlight = (async () => {\n\t\t\t\ttry {\n\t\t\t\t\tconst next = await this.dataSourcesLoader()\n\t\t\t\t\tthis.dataSourcesState.value = next || { registers: [] }\n\t\t\t\t} catch (e) {\n\t\t\t\t\tthis.dataSourcesState.error = e\n\t\t\t\t\t// Keep the last good `value` — a failed refresh must not\n\t\t\t\t\t// blank a list the user is mid-edit against.\n\t\t\t\t} finally {\n\t\t\t\t\tthis.dataSourcesState.loading = false\n\t\t\t\t\tthis._dataSourcesInFlight = null\n\t\t\t\t}\n\t\t\t})()\n\n\t\t\treturn this._dataSourcesInFlight\n\t\t},\n\n\t\t/**\n\t\t * Resolve a custom `adminSettings` entry's `component` key against\n\t\t * the same registries `CnBodySections.resolveSectionComponent` /\n\t\t * `CnPageRenderer.resolveCustomComponent` use for slot components:\n\t\t * the v2 `registry` prop (any kind exposing a `.component`) wins,\n\t\t * falling back to the legacy `customComponents` map. Returns `null`\n\t\t * (renders nothing) when neither has the key registered.\n\t\t *\n\t\t * @param {string} key The entry's `component` registry key.\n\t\t * @return {import('vue').Component|null}\n\t\t */\n\t\t/**\n\t\t * Resolve the routed manifest page's `sidebarComponent`.\n\t\t *\n\t\t * Resolved HERE rather than received from `CnPageRenderer`, which is\n\t\t * why the manifest key works at all. The renderer *provides*\n\t\t * `cnPageSidebarComponent` and this component *injects* it — but the\n\t\t * renderer is our descendant, and provide/inject only flows downward,\n\t\t * so that value could never reach this slot. `pages[].sidebarComponent`\n\t\t * was dead config for every app that tried it (#528).\n\t\t *\n\t\t * The route name is the page id (the same match `_hydrateMenuCounts`\n\t\t * uses), and the component name resolves through the same registries\n\t\t * every other slot component uses.\n\t\t *\n\t\t * @return {import('vue').Component|null} The sidebar component, or null.\n\t\t */\n\t\tresolvePageSidebarComponent() {\n\t\t\tconst routeName = this.$route?.name\n\t\t\tif (!routeName) {\n\t\t\t\treturn null\n\t\t\t}\n\n\t\t\tconst page = (this.manifest?.pages ?? []).find((p) => p?.id === routeName)\n\t\t\tif (!page || typeof page.sidebarComponent !== 'string' || page.sidebarComponent === '') {\n\t\t\t\treturn null\n\t\t\t}\n\n\t\t\t// `sidebar.show: false` suppresses the rail entirely, so a page\n\t\t\t// declaring both is contradictory; visibility wins, matching what\n\t\t\t// CnPageRenderer already warns about.\n\t\t\tif (page?.sidebar?.show === false) {\n\t\t\t\treturn null\n\t\t\t}\n\n\t\t\treturn this.resolveAdminSettingsComponent(page.sidebarComponent)\n\t\t},\n\n\t\tresolveAdminSettingsComponent(key) {\n\t\t\tif (typeof key !== 'string' || key === '') {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst reg = (this.registry && this.registry[key]) || null\n\t\t\tif (reg && reg.component) {\n\t\t\t\treturn reg.component\n\t\t\t}\n\t\t\tconst legacy = this.customComponents && this.customComponents[key]\n\t\t\treturn legacy || null\n\t\t},\n\n\t\t/**\n\t\t * Return the translated copy for `key`, or `fallback` when the\n\t\t * `translate` prop leaves the key unchanged (its default is the\n\t\t * identity function and no consumer app defines the\n\t\t * `app-availability.*` keys). Keeps real l10n working for apps that\n\t\t * DO supply the strings while guaranteeing English prose otherwise\n\t\t * (REQ-DIA-7).\n\t\t *\n\t\t * @param {string} key The i18n key.\n\t\t * @param {string} fallback The English default.\n\t\t * @return {string}\n\t\t */\n\t\tavailabilityCopy(key, fallback) {\n\t\t\tconst translated = this.translate(key)\n\t\t\treturn (translated === undefined || translated === null || translated === key)\n\t\t\t\t? fallback\n\t\t\t\t: translated\n\t\t},\n\n\t\t/**\n\t\t * Install-and-enable (or enable) a missing dependency via the shared\n\t\t * `useAppInstaller` (REQ-DIA-3 / REQ-DIA-6). Marks the dependency\n\t\t * busy for the per-button spinner, reloads on success (a freshly\n\t\t * installed app's assets only exist after a full load), and on\n\t\t * failure leaves `depInstallError` set so the store link stays as a\n\t\t * fallback.\n\t\t *\n\t\t * @param {string} id The Nextcloud app id to install/enable.\n\t\t * @return {Promise<void>}\n\t\t */\n\t\tasync installDependency(id) {\n\t\t\tif (!id) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.installingDepId = id\n\t\t\tthis.erroredDepId = null\n\t\t\ttry {\n\t\t\t\tawait this.appInstaller.installAndEnable(id)\n\t\t\t\twindow.location.reload()\n\t\t\t} catch {\n\t\t\t\t// Error is surfaced inline via `depInstallError`; the store\n\t\t\t\t// link remains available as a manual fallback. A cancelled\n\t\t\t\t// password confirmation also lands here (no error text).\n\t\t\t\tthis.erroredDepId = id\n\t\t\t} finally {\n\t\t\t\tthis.installingDepId = null\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Dismiss a soft-dependency banner (REQ-DIA-6). Persists the\n\t\t * dismissal under `cn-soft-dep-dismissed:{appId}:{depId}` and hides\n\t\t * the banner reactively. Independent per dependency.\n\t\t *\n\t\t * @param {string} id The soft dependency's app id.\n\t\t * @return {void}\n\t\t */\n\t\tdismissSoftDep(id) {\n\t\t\ttry {\n\t\t\t\twindow.localStorage.setItem('cn-soft-dep-dismissed:' + this.appId + ':' + id, '1')\n\t\t\t} catch {\n\t\t\t\t// Best-effort persistence (private mode / no storage).\n\t\t\t}\n\t\t\tif (!this.dismissedSoftDeps.includes(id)) {\n\t\t\t\tthis.dismissedSoftDeps.push(id)\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Heading for a soft-dependency banner.\n\t\t *\n\t\t * @param {object} dep The normalised dependency `{ id, name, ... }`.\n\t\t * @return {string}\n\t\t */\n\t\tsoftDepHeading(dep) {\n\t\t\treturn this.availabilityCopy('app-availability.soft.heading', `Optional: ${dep.name}`)\n\t\t},\n\n\t\t/**\n\t\t * Body text for a soft-dependency banner.\n\t\t *\n\t\t * @param {object} dep The normalised dependency `{ id, name, ... }`.\n\t\t * @return {string}\n\t\t */\n\t\tsoftDepText(dep) {\n\t\t\treturn this.availabilityCopy(\n\t\t\t\t'app-availability.soft.description',\n\t\t\t\t`${dep.name} unlocks optional features in this app but is not installed or enabled.`,\n\t\t\t)\n\t\t},\n\n\t\t/**\n\t\t * Non-admin \"ask your administrator\" copy for a soft-dependency\n\t\t * banner.\n\t\t *\n\t\t * @param {object} dep The normalised dependency `{ id, name, ... }`.\n\t\t * @return {string}\n\t\t */\n\t\tsoftDepAskAdmin(dep) {\n\t\t\treturn this.availabilityCopy('app-availability.soft.ask-admin', `Ask your administrator to enable ${dep.name}.`)\n\t\t},\n\n\t\t/**\n\t\t * Warn before unload when the manifest editor has unsaved (or still-\n\t\t * persisting) changes, so a refresh can't silently discard an in-app\n\t\t * edit. No-op when not editing / nothing dirty.\n\t\t *\n\t\t * @param {BeforeUnloadEvent} event The browser beforeunload event.\n\t\t * @return {string|undefined} A non-empty string triggers the native prompt.\n\t\t */\n\t\tonBeforeUnload(event) {\n\t\t\tconst editor = this.manifestEditor\n\t\t\tconst dirtyRef = editor && editor.dirty\n\t\t\tconst dirty = dirtyRef && typeof dirtyRef === 'object' && 'value' in dirtyRef ? dirtyRef.value : dirtyRef\n\t\t\tif (!dirty) {\n\t\t\t\treturn undefined\n\t\t\t}\n\t\t\t// The standard cross-browser incantation to trigger the prompt.\n\t\t\tevent.preventDefault()\n\t\t\tevent.returnValue = ''\n\t\t\treturn ''\n\t\t},\n\n\t\t/**\n\t\t * Re-fetch setup status after the wizard reports completion so the\n\t\t * phase flips from `setup` to `shell` without a page reload.\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\tonSetupComplete() {\n\t\t\t// Finishing counts as dismissal. A user may legitimately reach Finish\n\t\t\t// with an optional step still un-done (Next skips optional steps), and\n\t\t\t// the server keeps reporting it unmet — so without this the wizard\n\t\t\t// auto-opens again on every visit. Cancel must not be the only way to\n\t\t\t// get peace.\n\t\t\tthis.persistSetupWizardDismissal()\n\t\t\tif (this.setupState && typeof this.setupState.refresh === 'function') {\n\t\t\t\tthis.setupState.refresh()\n\t\t\t}\n\t\t\t// NOT closing here: CnSetupWizard has just flipped CnWizardDialog into\n\t\t\t// its result phase (\"Setup complete.\"). Unmounting now would swallow it.\n\t\t\t// The result phase's Close emits `@close` → dismissSetupWizard().\n\t\t\t/**\n\t\t\t * @event setup-complete Emitted after the gating setup wizard reports\n\t\t\t * completion and the status has been re-fetched.\n\t\t\t */\n\t\t\tthis.$emit('setup-complete')\n\t\t},\n\n\t\t/**\n\t\t * Dismiss the non-gating optional-setup wizard (REQ-SETUP-NV-012) and\n\t\t * unmount it.\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\tdismissSetupWizard() {\n\t\t\tthis.persistSetupWizardDismissal()\n\t\t\tthis.setupWizardOpen = false\n\t\t},\n\n\t\t/**\n\t\t * `localStorage` key holding the non-gating setup wizard's dismissal for\n\t\t * the manifest's CURRENT `setup.version`. Read at use time rather than\n\t\t * cached, so an async manifest merge that bumps the version is honoured.\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\tsetupWizardDismissKey() {\n\t\t\tconst version = (this.manifest && this.manifest.setup && this.manifest.setup.version) || 0\n\t\t\treturn 'cn-setup-wizard-dismissed:' + this.appId + ':' + version\n\t\t},\n\n\t\t/**\n\t\t * Whether the non-gating setup wizard has already been dismissed for\n\t\t * this manifest `setup.version` — this session or a previous visit.\n\t\t *\n\t\t * @return {boolean}\n\t\t */\n\t\tisSetupWizardDismissed() {\n\t\t\tif (this.setupWizardDismissed) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\ttry {\n\t\t\t\treturn window.localStorage.getItem(this.setupWizardDismissKey()) === '1'\n\t\t\t} catch {\n\t\t\t\treturn false\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Record the non-gating setup wizard as dismissed for this manifest\n\t\t * `setup.version` so it doesn't auto-open again.\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\tpersistSetupWizardDismissal() {\n\t\t\ttry {\n\t\t\t\twindow.localStorage.setItem(this.setupWizardDismissKey(), '1')\n\t\t\t} catch {\n\t\t\t\t// Best-effort persistence (private mode / no storage).\n\t\t\t}\n\t\t\tthis.setupWizardDismissed = true\n\t\t},\n\n\t\t/**\n\t\t * Resolve the user's last-seen walkthrough version from the per-user\n\t\t * `completionConfigKey` preference before the overlay is allowed to\n\t\t * mount (ADR-043, REQ-WALK-NV-004). Without a declared key the value\n\t\t * seeded synchronously in `data()` is already final.\n\t\t *\n\t\t * Never rejects: an absent endpoint / unauthenticated user falls back to\n\t\t * the localStorage mirror inside the loader.\n\t\t *\n\t\t * @return {Promise<void>}\n\t\t */\n\t\tasync resolveWalkthroughSeenVersion() {\n\t\t\tif (!this.walkthroughEnabled || !this.walkthroughConfigKey) {\n\t\t\t\tthis.walkthroughSeenResolved = true\n\t\t\t\treturn\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tthis.walkthroughSeenVersionValue = await loadWalkthroughSeenVersion(\n\t\t\t\t\tthis.appId,\n\t\t\t\t\tthis.walkthroughConfigKey,\n\t\t\t\t)\n\t\t\t} finally {\n\t\t\t\tthis.walkthroughSeenResolved = true\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Persist the current app version as the user's last-seen walkthrough\n\t\t * version (so an upgrade later surfaces only newer steps) and notify.\n\t\t *\n\t\t * Writes BOTH the localStorage mirror and — when the manifest declares\n\t\t * `walkthrough.completionConfigKey` — the per-user preference the load\n\t\t * path reads, so completing or dismissing the tour actually sticks for\n\t\t * that user instead of re-opening on the next visit.\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\tonWalkthroughComplete() {\n\t\t\tconst v = normaliseSeenVersion((this.manifest && this.manifest.version) || '1.0.0')\n\t\t\tthis.walkthroughSeenVersionValue = v\n\t\t\tthis.walkthroughSeenResolved = true\n\t\t\t// Fire-and-forget: the loader never rejects and the local mirror is\n\t\t\t// already written, so a failed PUT must not surface as an error.\n\t\t\tpersistWalkthroughSeenVersion(this.appId, this.walkthroughConfigKey, v)\n\t\t\t/**\n\t\t\t * @event walkthrough-complete Emitted when the walkthrough finishes or is dismissed.\n\t\t\t */\n\t\t\tthis.$emit('walkthrough-complete')\n\t\t},\n\n\t\t/**\n\t\t * Replay the product tour from the user-settings dialog. Closes the\n\t\t * dialog first, then restarts the first declared tour on the next tick\n\t\t * — the modal must finish unmounting before the tour overlay paints, or\n\t\t * the spotlight anchors against the closing modal. Mirrors the\n\t\t * `cnReplayWalkthrough` provide method (same useWalkthrough cache, so\n\t\t * the rendered CnWalkthrough genuinely re-fires).\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\trestartWalkthroughFromSettings() {\n\t\t\tthis.userSettingsOpen = false\n\t\t\tif (!this.walkthroughEnabled) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\t// 50ms lets the dialog's close animation settle so the tour\n\t\t\t// re-appears cleanly over the app shell, not the closing modal.\n\t\t\tsetTimeout(() => {\n\t\t\t\tconst id = this.manifest.walkthrough.tours[0] && this.manifest.walkthrough.tours[0].id\n\t\t\t\tif (id) {\n\t\t\t\t\tuseWalkthrough(this.appId, this.manifest).restart(id)\n\t\t\t\t}\n\t\t\t}, 50)\n\t\t},\n\n\t\t/**\n\t\t * Validate every entry in the `registry` prop at mount time.\n\t\t *\n\t\t * - Unknown `kind` throws `RegistryKindError` (hard error; developer\n\t\t * must fix the registration).\n\t\t * - Known `kind` with missing required metadata emits `console.warn`\n\t\t * (soft error; the widget still renders with defaults).\n\t\t */\n\t\t_validateRegistry() {\n\t\t\tconst registry = this.registry || {}\n\t\t\tfor (const [key, entry] of Object.entries(registry)) {\n\t\t\t\tif (!entry || typeof entry !== 'object') {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\tconst kind = entry.kind\n\n\t\t\t\tif (!KNOWN_REGISTRY_KINDS.includes(kind)) {\n\t\t\t\t\tthrow new RegistryKindError(key, kind)\n\t\t\t\t}\n\n\t\t\t\tconst requiredFields = REGISTRY_KIND_REQUIRED_FIELDS[kind]\n\t\t\t\tfor (const field of requiredFields) {\n\t\t\t\t\tif (!Object.hasOwn(entry, field)) {\n\t\t\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\t\t\tconsole.warn(`[CnAppRoot] Registry entry \"${key}\" (kind: \"${kind}\") is missing required metadata field \"${field}\".`)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Emit a single console.warn per mount when both a non-empty\n\t\t * customComponents prop AND a v2 manifest are present.\n\t\t *\n\t\t * Uses an instance flag `_customComponentsWarnedOnce` to prevent\n\t\t * repeat warnings on re-render.\n\t\t */\n\t\t_warnCustomComponentsDeprecation() {\n\t\t\tif (this._customComponentsWarnedOnce) {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tconst hasCustomComponents = this.customComponents\n\t\t\t\t&& typeof this.customComponents === 'object'\n\t\t\t\t&& Object.keys(this.customComponents).length > 0\n\n\t\t\tconst isV2Manifest = this.manifest\n\t\t\t\t&& typeof this.manifest.$schema === 'string'\n\t\t\t\t&& this.manifest.$schema.includes('app-manifest-v2')\n\n\t\t\tif (hasCustomComponents && isV2Manifest) {\n\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\tconsole.warn('CnAppRoot: `customComponents` prop is deprecated when using v2 manifests. '\n\t\t\t\t\t+ 'Use the `registry` prop instead (see ADR-036).')\n\t\t\t\tthis._customComponentsWarnedOnce = true\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Scan the manifest for `count: \"auto\"` menu entries (top-level\n\t\t * AND nested children) AND `count: \"auto\"` `nav-card-grid` widget\n\t\t * entries (`pages[].widgets[]`, ADR-044 §4 cards-collapse), and\n\t\t * hydrate `this.cnMenuCounts` from\n\t\t * `useObjectStore().getPagination(slug).total` for each unique\n\t\t * `(register, schema)` pair whose resolved page is `type: \"index\"`.\n\t\t *\n\t\t * The `nav-card-grid` walk exists because `applyMenuRemovals`\n\t\t * deletes a cards-collapse group's former leaf items from `menu`\n\t\t * entirely once they're relocated into a card page — without this\n\t\t * second walk, `cnMenuCounts` would never contain the\n\t\t * register/schema pairs those cards need, and their\n\t\t * `count: \"auto\"` would silently show no badge even though the\n\t\t * underlying data exists.\n\t\t *\n\t\t * Triggers one `fetchCollection(slug, { _limit: 1 })` per pair so\n\t\t * the store's pagination cache is warmed. Subsequent CnIndexPage\n\t\t * mounts reuse the same store entry (no extra round-trip).\n\t\t *\n\t\t * Failures are non-fatal — missing Pinia (no `pinia` plugin\n\t\t * installed on the Vue instance), unregistered type slugs, or\n\t\t * network errors all degrade gracefully to \"no badge\".\n\t\t *\n\t\t * @return {void}\n\t\t * @private\n\t\t */\n\t\t_hydrateMenuCounts() {\n\t\t\tconst menu = this.manifest?.menu ?? []\n\t\t\tconst pages = this.manifest?.pages ?? []\n\n\t\t\tconst collectAutoTargets = (items) => {\n\t\t\t\tconst targets = []\n\t\t\t\tfor (const item of items ?? []) {\n\t\t\t\t\tif (item?.count === 'auto' && item?.route) {\n\t\t\t\t\t\tconst page = pages.find((p) => p.id === item.route)\n\t\t\t\t\t\tif (page?.type === 'index' && page?.config?.register && page?.config?.schema) {\n\t\t\t\t\t\t\ttargets.push({ register: page.config.register, schema: page.config.schema })\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif (Array.isArray(item?.children)) {\n\t\t\t\t\t\ttargets.push(...collectAutoTargets(item.children))\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn targets\n\t\t\t}\n\n\t\t\t/**\n\t\t\t * Collect `(register, schema)` targets from every `nav-card-grid`\n\t\t\t * widget's `props.entries[]` across all pages, for entries\n\t\t\t * declaring `count: \"auto\"` with a `route` resolving to an\n\t\t\t * index page.\n\t\t\t *\n\t\t\t * @return {Array<{register: string, schema: string}>}\n\t\t\t */\n\t\t\tconst collectNavCardGridTargets = () => {\n\t\t\t\tconst targets = []\n\t\t\t\tfor (const page of pages) {\n\t\t\t\t\tfor (const widget of page?.widgets ?? []) {\n\t\t\t\t\t\tif (widget?.widgetKey !== 'nav-card-grid') {\n\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfor (const entry of widget?.props?.entries ?? []) {\n\t\t\t\t\t\t\tif (entry?.count !== 'auto' || !entry?.route) {\n\t\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tconst target = pages.find((p) => p.id === entry.route)\n\t\t\t\t\t\t\tif (target?.type === 'index' && target?.config?.register && target?.config?.schema) {\n\t\t\t\t\t\t\t\ttargets.push({ register: target.config.register, schema: target.config.schema })\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn targets\n\t\t\t}\n\n\t\t\tconst pairs = [...collectAutoTargets(menu), ...collectNavCardGridTargets()]\n\t\t\tif (pairs.length === 0) {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// De-duplicate by (register, schema).\n\t\t\tconst seen = new Set()\n\t\t\tconst uniquePairs = []\n\t\t\tfor (const pair of pairs) {\n\t\t\t\tconst key = `${pair.register}|${pair.schema}`\n\t\t\t\tif (seen.has(key)) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tseen.add(key)\n\t\t\t\tuniquePairs.push(pair)\n\t\t\t}\n\n\t\t\t// Prefer ONE batched round-trip (audit item 26): shillinq's nav\n\t\t\t// alone hits ~dozens of unique (register, schema) pairs, each of\n\t\t\t// which was a separate `?_limit=1` request at boot. On an\n\t\t\t// OpenRegister without the batch route (404) or any error, fall\n\t\t\t// back to the per-entry store path below so badges still render.\n\t\t\tthis._hydrateMenuCountsBatched(uniquePairs).catch(() => {\n\t\t\t\tthis._hydrateMenuCountsPerEntry(uniquePairs)\n\t\t\t})\n\t\t},\n\n\t\t/**\n\t\t * Hydrate all menu counts with a single `POST /api/objects/counts`\n\t\t * (OpenRegister batched-counts endpoint). Distributes each returned\n\t\t * count into the reactive `cnMenuCounts` map. Rejects (so the caller\n\t\t * falls back) on a non-2xx status, a missing/404 route, or a malformed\n\t\t * response — never leaving a half-populated batch masquerading as done.\n\t\t *\n\t\t * @param {Array<{register: string, schema: string}>} uniquePairs Deduped pairs.\n\t\t * @return {Promise<void>}\n\t\t * @private\n\t\t */\n\t\tasync _hydrateMenuCountsBatched(uniquePairs) {\n\t\t\tconst url = generateUrl('/apps/openregister/api/objects/counts')\n\t\t\tconst { data } = await axios.post(url, {\n\t\t\t\tcounts: uniquePairs.map(({ register, schema }) => ({ register, schema })),\n\t\t\t})\n\t\t\tconst results = data?.results\n\t\t\tif (!Array.isArray(results)) {\n\t\t\t\tthrow new Error('batched counts: malformed response')\n\t\t\t}\n\t\t\tfor (const result of results) {\n\t\t\t\tconst { register, schema, count } = result ?? {}\n\t\t\t\tif (typeof count !== 'number' || count < 0) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tif (!this.cnMenuCounts[register]) {\n\t\t\t\t\tthis.cnMenuCounts[register] = {}\n\t\t\t\t}\n\t\t\t\tthis.cnMenuCounts[register][schema] = count\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Legacy per-entry hydration: one `?_limit=1` store fetch per pair.\n\t\t * The pre-batch behaviour, retained verbatim as the fallback for an\n\t\t * OpenRegister without the batch route.\n\t\t *\n\t\t * @param {Array<{register: string, schema: string}>} uniquePairs Deduped pairs.\n\t\t * @return {void}\n\t\t * @private\n\t\t */\n\t\t_hydrateMenuCountsPerEntry(uniquePairs) {\n\t\t\tlet store\n\t\t\ttry {\n\t\t\t\tstore = useObjectStore()\n\t\t\t} catch {\n\t\t\t\t// No Pinia plugin installed (tests, isolated mounts) —\n\t\t\t\t// silently skip; CnAppNav renders no badge.\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif (!store) {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tfor (const { register, schema } of uniquePairs) {\n\t\t\t\tconst slug = `${register}-${schema}`\n\t\t\t\tthis._fetchAndCacheCount(store, slug, register, schema)\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Fire-and-forget count fetch + cache writer. Registers the type\n\t\t * with the store on demand (so the consuming app doesn't need to\n\t\t * pre-register every counted slug), issues a `?_limit=1` index\n\t\t * fetch, and writes the resulting `total` into `cnMenuCounts`.\n\t\t *\n\t\t * Errors are swallowed so a single broken endpoint cannot blank\n\t\t * the entire navigation. The most common failure modes\n\t\t * (unregistered type, network error, store unavailable) all leave\n\t\t * the badge unrendered — which is the documented fallback.\n\t\t *\n\t\t * @param {object} store The `useObjectStore()` result.\n\t\t * @param {string} slug The store's type slug (`${register}-${schema}`).\n\t\t * @param {string} register OpenRegister register slug.\n\t\t * @param {string} schema OpenRegister schema slug.\n\t\t * @return {Promise<void>}\n\t\t * @private\n\t\t */\n\t\tasync _fetchAndCacheCount(store, slug, register, schema) {\n\t\t\ttry {\n\t\t\t\tif (typeof store.registerObjectType === 'function'\n\t\t\t\t\t&& (!store.objectTypeRegistry || !store.objectTypeRegistry[slug])) {\n\t\t\t\t\tstore.registerObjectType(slug, schema, register)\n\t\t\t\t}\n\t\t\t\tif (typeof store.fetchCollection === 'function') {\n\t\t\t\t\tawait store.fetchCollection(slug, { _limit: 1 })\n\t\t\t\t}\n\t\t\t\tconst pagination = typeof store.getPagination === 'function'\n\t\t\t\t\t? store.getPagination(slug)\n\t\t\t\t\t: null\n\t\t\t\tconst total = pagination?.total\n\t\t\t\tif (typeof total === 'number' && total >= 0) {\n\t\t\t\t\tif (!this.cnMenuCounts[register]) {\n\t\t\t\t\t\tthis.cnMenuCounts[register] = {}\n\t\t\t\t\t}\n\t\t\t\t\tthis.cnMenuCounts[register][schema] = total\n\t\t\t\t}\n\t\t\t} catch {\n\t\t\t\t// Non-fatal — leave the badge unrendered.\n\t\t\t}\n\t\t},\n\t},\n}\n</script>\n\n<style>\n.cn-app-root__capabilities-loading {\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\twidth: 100%;\n\tmin-height: 100vh;\n\tbackground: var(--color-main-background);\n}\n\n.cn-app-root__or-missing {\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\twidth: 100%;\n\tmin-height: 100vh;\n\tbackground: var(--color-main-background);\n\tcolor: var(--color-main-text);\n}\n\n.cn-app-root__or-missing-action {\n\tdisplay: inline-block;\n\tpadding: calc(1.5 * var(--default-grid-baseline)) calc(3 * var(--default-grid-baseline));\n\tborder-radius: var(--border-radius);\n\tbackground: var(--color-primary-element);\n\tcolor: var(--color-primary-element-text);\n\ttext-decoration: none;\n}\n\n.cn-app-root__or-missing-action:hover,\n.cn-app-root__or-missing-action:focus {\n\tbackground: var(--color-primary-element-hover);\n\ttext-decoration: underline;\n}\n\n.cn-app-root__walkthrough-hint {\n\tmargin-bottom: 12px;\n\tcolor: var(--color-text-maxcontrast);\n}\n\n.cn-app-root__integrations-hint {\n\tmargin-bottom: 12px;\n\tcolor: var(--color-text-maxcontrast);\n}\n\n.cn-app-root__integrations {\n\tdisplay: flex;\n\tflex-direction: column;\n\talign-items: flex-start;\n\tgap: calc(0.5 * var(--default-grid-baseline));\n\tmargin: 0;\n\tpadding: 0;\n\tlist-style: none;\n}\n\n.cn-app-root__or-missing-error {\n\tmargin: calc(2 * var(--default-grid-baseline)) 0 calc(1 * var(--default-grid-baseline));\n\tcolor: var(--color-error);\n}\n\n.cn-app-root__or-missing-ask-admin {\n\tcolor: var(--color-text-maxcontrast);\n}\n\n.cn-app-root__soft-dep {\n\tmargin: calc(2 * var(--default-grid-baseline));\n}\n\n.cn-app-root__soft-dep-body {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: var(--default-grid-baseline);\n}\n\n.cn-app-root__soft-dep-actions {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: calc(2 * var(--default-grid-baseline));\n\tflex-wrap: wrap;\n}\n\n.cn-app-root__soft-dep-ask-admin {\n\tcolor: var(--color-text-maxcontrast);\n}\n\n.cn-app-root__soft-dep-error {\n\tmargin: 0;\n\tcolor: var(--color-error);\n}\n</style>\n"],"names":["CnAppNav","CnAppLoading","CnDependencyMissing","CnSetupWizard","CnWalkthrough","CnAiCompanion","CnCommandPalette","CnObjectSidebar","CnSupportDialog","CnNotificationPreferences","CnCredentials","CnTenantBadge","axios"],"mappings":"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"}
|