Repository navigation
feat(contexts): keep widgets in step with pages and applications - #3132
rubenvdlinde wants to merge 1 commit into
Conversation
9c0151e to
bcce8b6
Compare
bcce8b6 to
390968d
Compare
3dedb5e to
669999e
Compare
Saving a page syncs its widgets by id in one transaction. Deleting a page or an application deletes its widgets and their sources, and removing a table or view from an application deletes only the sources that point at it, so the widget stays. Moving a user's data carries pages, widgets and sources, remapped to the imported nodes and checked like a save. The header, text and data widget types are defined in one place with the schema their settings are checked against. Assisted-by: ClaudeCode:claude-opus-5-5 Signed-off-by: Ruben van der Linde <[email protected]>
669999e to
af7e75b
Compare
enjeck
left a comment
There was a problem hiding this comment.
It seems like we have more test code than feature code. Most of the extra comes from the same case being tested in two or three places, or from tests that check mocks or config instead of behaviour. We should cut out some tests or merge. Having too many tests which are not useful slows down CI and adds clutter
| 'c.*', | ||
| 'r.id as node_rel_id', 'r.node_id', 'r.node_type', 'r.permissions', | ||
| 'p.id as page_id', 'p.page_type', | ||
| 'p.id as page_id', 'p.page_type', 'p.technical_name as page_technical_name', 'p.title as page_title', 'p.icon as page_icon', 'p.description as page_description', |
There was a problem hiding this comment.
Could we join only the start page here, and load the page fields in a separate query? Otherwise, imagine someone opens just a start page, we might be wasting time processing stuff that doesn't matter for them? Maybe i misunderstand
| $context->getDescription(), | ||
| array_values($nodes), | ||
| $context->getPages(), | ||
| $this->getPagesWithWidgets($context), |
There was a problem hiding this comment.
The scheme export now includes pages and widgets, but the scheme import ignores them though. Why?
| // the relations of the table being imported, the only node a widget source can keep | ||
| $sourceRelMap = []; |
There was a problem hiding this comment.
We seem to have a bug: If I have an application with 2 tables and export an account. When i import, the application is created twice 🤔
| ['value' => 'left', 'label' => $this->l10n->t('Start')], | ||
| ['value' => 'center', 'label' => $this->l10n->t('Centered')], | ||
| ['value' => 'right', 'label' => $this->l10n->t('End')], |
There was a problem hiding this comment.
Maybe better if values are start, center and end too for consistency
| * @throws Exception | ||
| * @throws \JsonException | ||
| */ | ||
| public function syncPage(int $pageId, array $widgets): void { |
There was a problem hiding this comment.
The PR says saving a page happens in one transaction, but syncPage() doesn't seem to. Do we need atomic()?
Part of #3099, on top of #3131 (data model). This adds the behaviour #3100 describes for widgets, still without an API or UI.
Size: 1717 lines: 627 code, 1090 tests.
TablesMigrator) carries an application's pages, widgets and settings. A widget source only comes along when it points at the table being imported:importContext()maps every node to that table, so a source for another table would land on the wrong one. Imported widgets and page texts are checked the same way as saved ones, and invalid ones are skipped with a warning in the log.#rgbor#rrggbb.Data exported with widgets can't be imported into an older version of Tables. That belongs in the changelog.
Three smaller changes come with it:
The widget types aren't in
ResponseDefinitionsyet, because the OpenAPI generator refuses schemas that no endpoint uses. They move there together with the endpoints in the next pull request.Why nothing breaks
There is still no way to create a widget, so all of this runs on empty tables. Deleting an application or removing a table behaves as before; it now also checks two more tables.
How it was tested
On Nextcloud 34 with PostgreSQL:
WidgetServiceTest(database, including clearing a widget title back to empty, and refusing a widget id from another page)GridWidgetTypesTestandContextServiceTestContextPagesRoundTripTest(database: export, import, removing a table, deleting an application)ContextMapperTestandTablesMigratorTestcomposer cs:check, psalm and rector, all clean🖼️ Screenshots
Backend only, no UI changes.
🏁 Checklist
/backport to stableX.X🤖 AI (if applicable)