Skip to content

feat(contexts): export and import menus and pages - #54

Open
rubenvdlinde wants to merge 1 commit into
stack/s2-application-overviewfrom
stack/s3-export-import
Open

rubenvdlinde wants to merge 1 commit into
stack/s2-application-overviewfrom
stack/s3-export-import

Conversation

@rubenvdlinde

Copy link
Copy Markdown
Collaborator

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.

  • Export: menuItems name tables and views by targetUuid, pages by targetPageTechnicalName, parents by parentTechnicalName. A menu item whose target is gone is left out. The pages with their widgets, settings and sources are r1's export (getPagesWithWidgets), unchanged.
  • Import order: tables, then nodes, then pages, then menu. Pages go through r5's 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.
  • Older schemes with 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: header title/subtitle/... become heading/subheading/... settings, text keeps its text, a configured title shows when the widget showed it. A data widget's content.target becomes 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.
  • Validation: the request becomes a ContextScheme in the controller; a malformed scheme (no name, wrong types, tables without addTables/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. A BadRequestError or a missing page rolls the import back with a 400 or 404.
  • Dialog: the preview has a "Menu and pages" switch. On, the menu, the pages and any grid views of the file come along; pages only come along with the resources they show.
  • API: menuItems and gridViews on POST /api/2/contexts/{id}/scheme/import (pages came with r5). OpenAPI and TS types regenerated.

Carried over from #41, and what changed because of nextcloud#3100

  • Carried over: menu export by uuid and parent technical name, skipping unusable items on import, derived technical names, ContextScheme::createFromInputArray, the controller's rollbacks, the dialog's switch, the service accessors a test can replace, the grid view conversion.
  • Not duplicated: feat(contexts): export and import menus and pages聽#41's own page import (ContextSchemeService::importPages with start page "arranged on the grid" detection, PageContentHelper) is gone. Pages use r1/r5's scheme code; ContextSchemeService keeps only the menu and the grid view conversion, which produces scheme pages for importSchemePages.
  • Page menu targets are exported by technical name instead of by scheme page id: pages have required technical names since r5, and re-import matches pages by them.
  • A grid view data widget whose table cannot be used no longer disappears: it stays without a source (Grid pages in applications (data model and API)聽nextcloud/tables#3100 keeps widgets, never deletes them).

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).
  • Playwright at 1600 x 1000, --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 of application.spec.ts and tables-import-export-scheme.spec.ts: 13 passed (1.4m).
  • composer cs:check: no files; psalm No errors found!; composer openapi regenerated; 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.

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
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