Repository navigation
feat(contexts): export and import menus and pages - #54
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 carries its menu: tables and views by uuid, pages by technical name, parents by technical name; an item whose target is gone is left out. The import validates the scheme in the controller, then sets the nodes, then the pages through importSchemePages (matched by technical name), then the menu, skipping items whose target does not exist here or cannot be managed. Grid views of an older scheme become grid pages; a data widget without a usable table keeps its place without a source. The import dialog gets a "Menu and pages" switch. Assisted-by: ClaudeCode:claude-opus-5-5
This was referenced Oct 16, 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 #41 (originally #27) on the page model of nextcloud#3100, see #13. Stacked on #53.
What changes
An exported application scheme now carries its menu next to its pages, so an application moves between instances with its pages and menu intact.
menuItemsname tables and views bytargetUuid, pages bytargetPageTechnicalName, parents byparentTechnicalName. A menu item whose target is gone is left out. The pages with their widgets, settings and sources are r1's export (getPagesWithWidgets), unchanged.importSchemePages: a page updates the page with the same technical name (title, emoji, description, widgets), other pages are added, local pages the scheme does not name stay. Sources are remapped through the node uuids. The menu is resolved after the pages, so a page item finds its page by technical name; an item that is invalid or whose table or view does not exist here or cannot be managed is skipped, a child whose parent was skipped moves to the top, a later item with a taken technical name gets a derived one.gridViews: every grid view becomes a grid page (technical name from the grid view, else its title, apart from the scheme's own pages), its widgets placed as its layout placed them: headertitle/subtitle/...becomeheading/subheading/...settings, text keeps its text, a configured title shows when the widget showed it. A data widget'scontent.targetbecomes its source: the scheme node with that uuid, else a node added to the application when the importer can manage the table or view. Otherwise the widget keeps its place without a source and asks for a new table (Grid pages in applications (data model and API)聽nextcloud/tables#3100). A menu item that opened the grid view opens its 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 or whose widgets are not a list, a grid view without uuid or title) is a 400 that never reaches the service. ABadRequestErroror a missing page rolls the import back with a 400 or 404.menuItemsandgridViewsonPOST /api/2/contexts/{id}/scheme/import(pagescame with r5). OpenAPI and TS types regenerated.Carried over from #41, and what changed because of nextcloud#3100
ContextScheme::createFromInputArray, the controller's rollbacks, the dialog's switch, the service accessors a test can replace, the grid view conversion.ContextSchemeService::importPageswith start page "arranged on the grid" detection,PageContentHelper) is gone. Pages use r1/r5's scheme code;ContextSchemeServicekeeps only the menu and the grid view conversion, which produces scheme pages forimportSchemePages.Tests
Nextcloud 34 container (PostgreSQL 16), one file per call:
tests/unit/Service/ContextSchemeServiceTest.php(new):OK (4 tests, 21 assertions): export by uuid and page technical name, skipping broken and foreign items; page and grid view targets mapped on import; taken technical names; a grid view turned into a page (names, settings, titles, positions, sources from a scheme node, an added node, none).tests/unit/Model/ContextSchemeTest.php(new):OK (14 tests, 33 assertions)tests/unit/Service/ContextServiceTest.php:OK (38 tests, 110 assertions)(nodes then pages then menu, grid view node replaced by its page and its widget's view added; no pages or menu left alone; an empty menu clears it; the export carries the menu).tests/unit/Controller/ContextControllerTest.php:OK (7 tests, 20 assertions);ContextPagesRoundTripTest.php(real DB):OK (4 tests, 18 assertions);TablesMigratorTest.php:OK (12 tests, 20 assertions).--timeout=120000: a scheme imported through the dialog brings its menu (Dashboard, Front page, Cases, Handbook), the start page's header and the front page; importing twice adds no page again; 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 a data widget on the table it named, its menu item opens it. With the rest ofapplication.spec.tsandtables-import-export-scheme.spec.ts:13 passed (1.4m).composer cs:check: no files; psalmNo errors found!;composer openapiregenerated;npm run lint: 0 errors, 1 inherited warning (src/store/store.js:176);npm run stylelint: clean.Size: 1,246 changed lines without the generated OpenAPI files.
Prepared in the Conduction fork for porting upstream by @remko48. Prepared with Claude Code.