Skip to content

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

Closed
rubenvdlinde wants to merge 1 commit into
betafrom
feat/integration-leaves-fleet-vue
Closed

feat(integrations): generic CnIntegrationTab/Card + 18 leaf registrations + CnDetailPage useRegistry forwarding#230
rubenvdlinde wants to merge 1 commit into
betafrom
feat/integration-leaves-fleet-vue

Conversation

@rubenvdlinde
Copy link
Copy Markdown
Contributor

@rubenvdlinde rubenvdlinde commented May 15, 2026

Summary

JS counterpart to openregister#1514 (PHP providers for 18 leaves). Rebased onto current beta with all required dependencies absorbed (no stack on top of the umbrella).

This branch now contains:

  1. Two generic Vue components — `CnIntegrationTab` (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 fix — `mergeSidebarSources()` now forwards `useRegistry` and `excludeIntegrations` from the Object form of the `sidebar` prop 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 (e.g. a future CnCalendarTab) supersede the generic pair by repointing their registration's `tab` / `widget` — no consumer changes needed.

End-to-end proof

Verified in a dev container with openregister#1514 (PHP providers) + decidesk#205 (Pinia fix + leaf registration). After the chain was deployed:

```
window.OCA.OpenRegister.integrations.list().length → 24
document.querySelectorAll('aside.app-sidebar [role="tab"]').length → 24
```

24 sidebar tabs render: 5 built-ins (Files / Notes / Tags / Tasks / Audit trail) + 1 xwiki + 18 from this PR (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 (required NC app installed), 13 app-gated (correct, app absent).

Quality

  • `npm run lint` clean (4 pre-existing warnings in CnDetailPage.vue, unrelated).
  • `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) so its bespoke `CnXwikiTab` / `CnXwikiCard` components can replace the generic pair before merge if desired.
  • 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).

@rubenvdlinde
Copy link
Copy Markdown
Contributor Author

Visually verified end-to-end via decidesk (15 May)

Verified the 17 leaf registrations + generic CnIntegrationTab/Card light up in a real consumer (decidesk).

After porting this PR's source + openregister#1514's PHP providers + decidesk#205's main.js Pinia fix into a dev container:

  • window.OCA.OpenRegister.integrations.list().length === 24 (5 built-ins + 1 xwiki + 18 leaves from this PR).
  • <CnObjectSidebar :use-registry="true"> mounts 24 tabs (every tab + widget resolves; parity gate satisfied).
  • Each tab-button-{id} element renders with the right label (Meetings / Contacts / Emails / Chat / Articles / Projects / Bookmarks / Knowledge / Location / Photos / Activity / Analytics / Costs / Cards / Automation / Forms / Polls / Time).

Required prerequisite for the consumer side: nc-vue#218 (CnDetailPage sidebar Object form accepts useRegistry / excludeIntegrations) MUST land before #230, because the current mergeSidebarSources in beta drops the useRegistry flag when forwarding the sidebar config from <CnDetailPage :sidebar="{...}"> to objectSidebarState. Verified locally by porting #218's patch into the dev source.

Tab content hits 503 because openregister umbrella #1473 (routes + controllers) hasn't merged yet — expected.

See decidesk#205 comment for the full verification trace.

…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.
@rubenvdlinde rubenvdlinde force-pushed the feat/integration-leaves-fleet-vue branch from 984c177 to 932f65e Compare May 15, 2026 08:51
@rubenvdlinde rubenvdlinde changed the title feat(integrations): generic CnIntegrationTab + CnIntegrationCard + 17 leaf registrations feat(integrations): generic CnIntegrationTab/Card + 18 leaf registrations + CnDetailPage useRegistry forwarding May 15, 2026
@rubenvdlinde rubenvdlinde deleted the feat/integration-leaves-fleet-vue branch May 15, 2026 09:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant