Repository navigation
feat(contexts): export and import menus and pages - #41
Open
rubenvdlinde wants to merge 1 commit into
Open
rubenvdlinde wants to merge 1 commit into
rubenvdlinde wants to merge 1 commit into
Conversation
An exported application scheme now carries its menu and its pages with their widgets, so an application moves between instances with its pages and menu intact. - Export: pages come as the page API returns them; data widgets name their node by its relation id in the scheme's nodes. Menu items name tables and views by uuid, pages by their id in the scheme and their parent by technical name. An item whose target is gone is left out. - Import: pages come after the nodes, the menu after the pages. The start page is filled only when the scheme arranged it on the grid; a grid page replaces the page with the same technical name or is added. A data widget whose table or view does not exist here, or that the importer cannot add, is left out. A menu item that is invalid or whose target cannot be used is skipped; a child whose parent was skipped moves to the top. - Older schemes: every grid view of the scheme becomes a grid page with its widgets in place, its data widgets pointing at their table or view as a node; a menu item that opened it opens that page, and its node is no longer imported as a view. - Validation: the import request is validated into a ContextScheme in the controller; a malformed scheme is a 400, and every failure rolls the import back. - Dialog: a "Menu and pages" switch in the preview brings both along; pages only come with the resources they show. - API: menuItems, pages and gridViews on the import endpoint (OpenAPI and TS types regenerated). Assisted-by: ClaudeCode:claude-opus-5-5
This was referenced Oct 15, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Rebuild of #27 on application pages (nextcloud#3075, see #13). Stacked on #40.
What changes
An exported application scheme now carries its menu and its pages with their widgets, so an application can move between instances with its pages and menu intact.
pagesis the page list of the page API (title, technical name, widgets with type, configuration, content and position). A data widget names its node bynode_rel_id, the relation id of that node in the scheme'snodes, which carry the uuid. Menu items name tables and views bytargetUuid, pages bytargetPageId(the page's id in the scheme), parents byparentTechnicalName. A menu item whose target is gone is left out.gridViews: every grid view becomes a grid page, titled as the view, with its widgets placed as its layout placed them. A data widget'scontent.target(table or view by uuid) becomes its node. A menu item that opened the grid view opens that page; a node pointing at the grid view is not imported as a view.ContextSchemein the controller; a malformed scheme (no name, wrong types,tableswithoutaddTables/modifyTables, a page that is not an object, a grid view without uuid or title) is a 400 that never reaches the service. ABadRequestError(an invalid widget, for instance) or a missing page rolls the import back with a 400 or 404.menuItems,pagesandgridViewsonPOST /api/2/contexts/{id}/scheme/import(OpenAPI and TS types regenerated). The menu and page logic lives in a newContextSchemeService.Carried over from #27, and what changed because of pages
ContextScheme::createFromInputArray, the controller's rollbacks, the dialog's switch, the service accessors that a test can replace.Tests
Nextcloud 34 container (PostgreSQL 16), one file per call:
tests/unit/Service/ContextSchemeServiceTest.php(new):OK (7 tests, 27 assertions): export by uuid and page id and skipping broken items; page targets and grid view targets mapped on import; taken technical names; start page filled only when arranged; page replaced by technical name and added otherwise; data widgets without a usable node left out; a grid view turned into a page.tests/unit/Model/ContextSchemeTest.php(new):OK (12 tests, 31 assertions)tests/unit/Service/ContextServiceTest.php:OK (36 tests, 120 assertions)(nodes, then pages, then menu; no pages or menu left alone; an empty menu clears it; the export carries pages and menu).tests/unit/Controller/ContextControllerTest.php:OK (7 tests, 20 assertions)(malformed scheme 400 without the service, rollbacks with 400/500/404, menu, pages and grid views passed on).Dashboard, Front page, Cases, Handbook) and its pages, and the front page shows its header; with "Menu and pages" off the request has neither and the menu stays; an older scheme's grid view becomes a page with its header and data widget, its menu item opens it.3 passed.tables-import-export-scheme.spec.ts:2 passed.composer cs:checkclean, psalmNo errors found!,composer openapiregenerated,npm run lint0 errors (1 inherited warning instore.js),npm run stylelintclean.Size: 1,413 changed lines without the generated OpenAPI files.
Prepared in the Conduction fork for porting upstream by @remko48. Prepared with Claude Code.