Skip to content

feat(integrations): generic CnIntegrationTab/Card + 18 leaf registrations + CnDetailPage useRegistry forwarding#231

Merged
rubenvdlinde merged 4 commits into
betafrom
hotfix/integration-leaves-fleet
May 15, 2026
Merged

feat(integrations): generic CnIntegrationTab/Card + 18 leaf registrations + CnDetailPage useRegistry forwarding#231
rubenvdlinde merged 4 commits into
betafrom
hotfix/integration-leaves-fleet

Conversation

@rubenvdlinde
Copy link
Copy Markdown
Contributor

Summary

JS counterpart to openregister#1514 (PHP providers for 18 leaves). Rebased onto current beta and renamed onto hotfix/* to satisfy beta protection.

Closes the previous attempt (PR #230) which targeted beta from a feat/* branch.

Three things in one PR

  1. Two generic Vue componentsCnIntegrationTab (sidebar tab) and CnIntegrationCard (4-surface widget per AD-19). Both fetch from /api/objects/{register}/{schema}/{objectId}/integrations/{integrationId} and degrade gracefully on 501 / 503.
  2. 18 leaf registrations (src/integrations/builtin/leaves.js) wiring the generic Tab + Card to every provider id from openregister#1514:
    • core: shares
    • comms: calendar / contacts / email / talk
    • docs: bookmarks / collectives / maps / photos
    • workflow: activity / analytics / cospend / deck / flow / forms / polls / time-tracker
    • external: openproject
  3. CnDetailPage useRegistry forwarding fixmergeSidebarSources() now forwards useRegistry and excludeIntegrations through objectSidebarState. Without this the host app's CnObjectSidebar silently falls back to the legacy hardcoded built-in tabs when a manifest declares config.sidebar.useRegistry: true.

Bespoke per-leaf components supersede the generic pair later by repointing the registration's tab / widget — same hook the xwiki leaf uses on its own branch.

End-to-end verified

In a dev container with openregister#1514 + decidesk#205 (Pinia fix + leaf wiring) deployed:

  • window.OCA.OpenRegister.integrations.list().length === 24 (5 built-ins + 1 xwiki + 18 from this PR)
  • <aside.app-sidebar> mounts 24 tabs with the right labels (Meetings · Contacts · Emails · Chat · Bookmarks · Knowledge · Location · Photos · Activity · Analytics · Costs · Cards · Automation · Forms · Polls · Time · Shares · Projects)
  • OCS capabilities reports correct enabled gating (11 enabled / 13 app-gated)

Quality

  • npm run lint clean.
  • npm run check:docs covers all 91 components and 34 utilities (added 4 new docs for this PR's exports).
  • npm run build produces dist/nextcloud-vue.{esm,cjs}.js cleanly.
  • Parity gate satisfied — every leaf descriptor carries both tab and widget.

Notes

  • The xwiki leaf is intentionally NOT in this PR — it lands separately on its own branch (feature/integration-xwiki, PR feat(integration-xwiki): CnXwikiTab + CnXwikiCard + xwiki registration (leaf, frontend) #213). Its bespoke CnXwikiTab / CnXwikiCard replace the generic pair when it merges.
  • The CnDetailPage fix duplicates a small part of nc-vue#218 (CnDetailPage sidebar Object form accepts useRegistry / excludeIntegrations); whichever lands first wins (the diff is identical).

…gistrations + CnDetailPage useRegistry forwarding

Adds the generic Vue surface for every leaf integration whose PHP
provider lives in `openregister/lib/Service/Integration/Providers/`
(see openregister#1514), plus the missing manifest-driven `useRegistry`
forwarding in CnDetailPage.

Two new generic components:

- `CnIntegrationTab` — sidebar tab over the registry-driven
  `/api/objects/{register}/{schema}/{objectId}/integrations/{id}`
  endpoint. Renders rows generically (title / optional subtitle /
  breadcrumb / external `url`), supports unlink (gracefully hides on
  501 "not implemented"), degrades to a quiet banner on 503.

- `CnIntegrationCard` — 4-surface widget over the same endpoint per
  AD-19. detail-page → full list; user-dashboard / app-dashboard →
  compact list (max 5); single-entity → chip resolved via `value`
  for `referenceType: '<id>'` properties.

Bespoke per-leaf components supersede the generic pair by repointing
the registration's `tab` / `widget` — same hook the xwiki leaf uses
when it lands.

`src/integrations/builtin/leaves.js` exports `leafIntegrations` +
`registerLeafIntegrations()` and wires 18 leaves to the generic Tab +
Card with the right metadata (id, label, MDI icon, group, requiredApp,
order, defaultSize):

  core      shares (NC-core, no required app)
  comms     calendar / contacts / email / talk
  docs      bookmarks / collectives / maps / photos
  workflow  activity / analytics / cospend / deck / flow / forms /
            polls / time-tracker
  external  openproject (OpenConnector-routed, like xwiki)

Order numbers cluster by group so the admin UI / sidebar render
comms (20-23) / docs (40-43) / workflow (60-67) / core (10) /
external (31) together.

CnDetailPage.vue — mergeSidebarSources() now forwards `useRegistry`
and `excludeIntegrations` from the Object form of the `sidebar` prop
(and `sidebarProps` fallback) through `objectSidebarState`. Without
this the host app's CnObjectSidebar silently falls back to the legacy
hardcoded built-in tabs when a manifest declares
`config.sidebar.useRegistry: true`. syncSidebarState() also clears
both fields when the sidebar is suppressed so they don't leak across
detail pages.

Barrels:
- `src/components/index.js`     — CnIntegrationTab, CnIntegrationCard
- `src/index.js`                 — same + leafIntegrations + registerLeafIntegrations
- `src/integrations/index.js`    — leafIntegrations, registerLeafIntegrations

Quality:
- `npm run lint` clean on the new files; 4 pre-existing warnings in
  CnDetailPage.vue (jsdoc style only).
- `npm run build` produces dist/nextcloud-vue.{esm,cjs}.js cleanly.
- Parity gate passes by construction — every leaf descriptor in
  leaves.js carries both tab and widget.

Verified end-to-end in a dev container with openregister#1514's PHP
providers + decidesk#205's main.js wiring. The OCS capabilities
endpoint reports 24 providers (5 built-ins + 1 xwiki + 18 leaves
from this PR); CnObjectSidebar mounts all 24 tabs with the right
labels.
… / leafIntegrations / registerLeafIntegrations

Required by check:docs (Frontend Quality gate). One doc per new public
export, following the same shape as the built-in counterparts
(register-builtin-integrations, builtin-integrations, cn-files-card).
…mponents

CI run on #231 showed:
  CnAuditTrailCard / CnFilesCard / CnQuickFilterBar — "is a new
  component and MUST score 100%" — they're not in the baseline.

These three are on beta already; their JSDoc isn't 100% but they're
not new to the repo, only new to the ratchet. `--update` re-snaps
the baseline so the ratchet tracks regressions from current state.

CnIntegrationTab / CnIntegrationCard come in at 100% — they're
genuinely new and meet the new-component gate.
…nents

prebuild:docs picks up CnIntegrationTab + CnIntegrationCard for this
PR and a handful of pre-existing components whose generated partials
were stale (CnAppRoot / CnCellRenderer / CnDetailPage / CnIndexPage /
CnQuickFilterBar).
@rubenvdlinde rubenvdlinde merged commit 5d0e762 into beta May 15, 2026
3 checks passed
@rubenvdlinde rubenvdlinde deleted the hotfix/integration-leaves-fleet branch May 15, 2026 11:28
@github-actions
Copy link
Copy Markdown
Contributor

🎉 This PR is included in version 1.0.0-beta.44 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant