@@ -48,6 +48,70 @@ which would increase the page loading time significantly.
4848
4949Improvements on Nextcloud server and Deck itself will improve the situation.
5050
51+ ## Embedding a Deck board in another Nextcloud app
52+
53+ Deck provides an opt-in ` nextcloud-deck-board ` custom element implemented as a
54+ Vue single-file component and registered with Vue's ` defineCustomElement() ` .
55+ It reuses the
56+ existing board UI without Deck's app navigation or browser-history router.
57+ The normal Deck app and the reference widgets keep their existing entry points.
58+ The element is intended for authenticated, same-instance Nextcloud pages.
59+ Existing Deck permissions apply to every API request; passing a board ID does
60+ not grant access or establish that the board belongs to a particular team.
61+ The host app must validate its own team-resource context.
62+
63+ Before rendering the host page, check that Deck is enabled for the current user
64+ and dispatch its loading event:
65+
66+ ``` php
67+ $eventDispatcher->dispatchTyped(new \OCA\Deck\Event\LoadBoardWebComponentEvent());
68+ ```
69+
70+ This loads ` deck-boardComponent ` , the Deck styles, and the attachment/editor
71+ integrations. Do not load ` deck-main ` in the host page. Hosts supporting older
72+ Deck versions must check that the event class exists and show an explicit
73+ unavailable state when this integration is not supported.
74+
75+ ``` html
76+ <nextcloud-deck-board board-id =" 42" style =" display : block ; height : 100% " >
77+ </nextcloud-deck-board >
78+ ```
79+
80+ Wait for ` customElements.whenDefined('nextcloud-deck-board') ` before relying on
81+ the component. Vue hosts must configure this tag as a custom element. Give the
82+ element a bounded height; the board handles its own scrolling. The component
83+ uses light DOM to work with Nextcloud's shared styles, dialogs and viewer.
84+ When binding IDs from Vue, use ` :board-id.attr="boardId" ` and
85+ ` :card-id.attr="cardId" ` so a ` null ` card ID removes the attribute rather than
86+ being coerced into an empty or zero-valued DOM property.
87+ Vue manages the element's rendering, reactive attributes and lifecycle. Each
88+ element still mounts an isolated Deck app with its own stores and memory router;
89+ removing an element disposes that app after Vue's disconnection tick. Moving an
90+ element within the same document preserves its mounted instance.
91+
92+ - ` board-id ` : required positive safe integer. Changing it disposes the previous
93+ instance and opens the new board with independent state.
94+ - ` card-id ` : optional positive safe integer. Set it to open a card, or remove it
95+ to close card details. Cards must belong to the displayed board. Opening
96+ archived card details after the board has loaded preserves the current list
97+ view and its active cards.
98+ - ` deck-ready ` : the board and its lists have loaded; ` detail ` contains ` boardId ` .
99+ - ` deck-error ` : loading, navigation, or runtime failed; ` detail ` contains
100+ ` boardId ` , ` message ` , and ` status ` (HTTP status when available).
101+ - ` deck-navigation ` : user navigation requested a board/card; ` detail ` contains
102+ ` boardId ` , ` cardId ` (or ` null ` ), and ` tabId ` (or ` null ` ).
103+
104+ Events bubble. The component never changes the host's URL. The host owns its
105+ route and active navigation styling, and should mirror card navigation into
106+ ` card-id ` . Cross-board links emit a navigation request but do not change the
107+ embedded board; the host must check its context before changing ` board-id ` .
108+ Removing the element disposes its Vue app, stores, live-update subscriptions
109+ and session. The embedded sessions do not change global Axios session headers.
110+
111+ Board management/sharing sidebars and global Deck keyboard shortcuts are not
112+ part of this embed entry point. Board-level filtering, view modes, lists, card
113+ editing and card-detail tabs use the existing Deck components.
114+
51115## Developing
52116
53117There are multiple ways to develop on Deck. As you will need a Nextcloud server running, the individual options are described below.
@@ -100,6 +164,28 @@ You need to setup a [development environment](https://docs.nextcloud.com/server/
100164After the finished installation, you can clone the deck project directly in the ` /[nextcloud-docker-dev-dir]/workspace/server/apps/ ` folder.
101165
102166### Running tests
167+ Run the frontend logic regression tests with ` npm test -- --runInBand ` .
168+ The embedded board's browser lifecycle, navigation, archive and undo behavior,
169+ and the existing non-interactive board reference entry point are tested in the Cypress E2E
170+ suite. With a running Nextcloud test instance (using the existing ` admin ` /` admin `
171+ test credentials), build the frontend and run:
172+
173+ ``` sh
174+ npm run dev
175+ npx cypress run --spec cypress/e2e/embeddedBoard.js
176+ ```
177+
178+ The default test URL is ` http://nextcloud.local/index.php ` ; set ` CYPRESS_baseUrl `
179+ to use another instance. The spec creates its own user and boards and deletes
180+ the user afterwards. It swaps the normal Deck entry bundle for the embed or
181+ reference bundle in the browser, reusing the authenticated page's integrations
182+ without mounting the full Deck app.
183+
184+ Cypress runs in the existing E2E CI workflow. It does not collect JavaScript
185+ coverage; ` npm run test:coverage -- --runInBand ` measures the Jest logic tests
186+ only. The Codecov configuration enables project and patch coverage checks,
187+ but does not make Cypress E2E assertions a JavaScript coverage report.
188+
103189You can use the provided Makefile to run all tests by using:
104190
105191 make test
0 commit comments