Skip to content

🗃️ Make archiving tables/applications a personal option - #2476

Open
AndyScherzinger wants to merge 8 commits into
mainfrom
feat/2125/personal-archiving-option
Open

🗃️ Make archiving tables/applications a personal option#2476
AndyScherzinger wants to merge 8 commits into
mainfrom
feat/2125/personal-archiving-option

Conversation

@AndyScherzinger

@AndyScherzinger AndyScherzinger commented Apr 12, 2026

Copy link
Copy Markdown
Member

🖼️ Screenshots

Archived categories Archive app Archive table Unarchive app Unarchive table
2026-04-12 15_33_25-Tables - Nextcloud — Mozilla Firefox 2026-04-12 15_34_51-Tables - Nextcloud — Mozilla Firefox 2026-04-12 15_34_35-Tables - Nextcloud — Mozilla Firefox 2026-04-12 15_34_05-Tables - Nextcloud — Mozilla Firefox 2026-04-12 15_33_50-Tables - Nextcloud — Mozilla Firefox

The original ticket #2125 defined tables and views, while this PR tacked tables and apps. Given a clear view on how archived views should get displayed this could be added as a follow-up PR to not make this PR grow in review-size and complexity.


Summary

  • This change replaces the existing single-user global archived flag on tables with a two-layer per-user model: an owner-level flag on the entity and a new tables_archive_user table that stores individual user overrides, so archive state is resolved per-user at read time. When an owner archives a table or application, it is automatically treated as archived for every user with access, but any of those users may override this for themselves; an owner unarchiving resets the state for everyone by clearing all per-user overrides.
  • The existing tables_tables.archived column is repurposed from a simple global toggle into the owner-level signal, and the database migration converts all currently-archived tables into owner-archived entries to preserve existing data without disruption.
  • Application (context) archiving is introduced as a completely new capability end-to-end: covering database schema, entity, service, API endpoints, routes, and frontend navigation - while table archiving is substantially reworked from a simple owner toggle into the full per-user propagation system.
  • A new ArchiveService centralizes all business logic for both resource types, four new API endpoints are split across ApiTablesController and ContextController following existing naming conventions, and the frontend gains archive/unarchive actions in both navigation item menus alongside a new collapsible "Archived applications" section mirroring the already-existing "Archived tables" section.

⚠️ Beware

The database migration only covers the owner and direct user shares, not groups, etc. since they can't be resolved directly via SQL (think teams/groups). So in these cases archived tables would resurface until manually archived by the respective user. Also there is no cleanup for teams/groups, if a user is taken out of a team, the archive meta-info would not get deleted. Only simple but confusing way around it would be to prevent archiving/unarchiving for tables/apps where a user is neither the owner nor a user-share receiver. Expensive alternative would be a housekeeping job checking all these archive bits periodically, but that also sounds expensive with little use. Else we would need to consume a team/group changes event and check if some cleanup is needed. WDYT?

🏁 Checklist

  • ⛑️ Tests (unit and/or integration) are included or not needed
  • 🔙 Backport requests are created or not needed: /backport to stableX.X
  • 📅 Milestone is set
  • 🌸 PR title is meaningful (if it should be in the changelog: is it meaningful to users?)

🤖 AI (if applicable)

  • The content of this PR was partly or fully generated using AI

@AndyScherzinger AndyScherzinger added enhancement New feature or request 2. developing Work in progress labels Apr 12, 2026
@AndyScherzinger AndyScherzinger changed the title Personal archiving option 🗃️ Make archiving tables/applications personal option Apr 12, 2026
@AndyScherzinger
AndyScherzinger force-pushed the feat/2125/personal-archiving-option branch 5 times, most recently from 008f4f3 to 0e2bbdc Compare April 12, 2026 15:34
@AndyScherzinger AndyScherzinger changed the title 🗃️ Make archiving tables/applications personal option 🗃️ Make archiving tables/applications a personal option Apr 12, 2026
@AndyScherzinger
AndyScherzinger force-pushed the feat/2125/personal-archiving-option branch 2 times, most recently from d3fce3e to fd235a6 Compare April 12, 2026 18:56
@AndyScherzinger
AndyScherzinger marked this pull request as ready for review April 12, 2026 19:36
@AndyScherzinger AndyScherzinger added 3. to review Waiting for reviews and removed 2. developing Work in progress labels Apr 12, 2026

@jancborchardt jancborchardt left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks generally nice, 2 details

  • I’d say to use outline icons instead of filled for both cases, archiving and unarchiving
  • In the cases of "Archive app" and "Unarchive app", the sorting of actions in the menu is off. We always recommend the destructive action (Delete) to be the very last, and then the next most destructive like Archive could be directly above it.

@jancborchardt jancborchardt moved this to 🏗️ At engineering in 🖍 Design team Apr 28, 2026
@AndyScherzinger
AndyScherzinger force-pushed the feat/2125/personal-archiving-option branch from fd235a6 to ba16212 Compare April 28, 2026 13:13
Comment thread lib/Db/UserArchive.php Outdated
Comment thread lib/Db/UserArchiveMapper.php Outdated
@AndyScherzinger
AndyScherzinger force-pushed the feat/2125/personal-archiving-option branch 4 times, most recently from 840a1ab to 086aad3 Compare April 28, 2026 20:06
@AndyScherzinger AndyScherzinger added 2. developing Work in progress and removed 3. to review Waiting for reviews labels Aug 30, 2026
@AndyScherzinger
AndyScherzinger force-pushed the feat/2125/personal-archiving-option branch from a7be73c to 9698f18 Compare September 4, 2026 16:53
@AndyScherzinger

Copy link
Copy Markdown
Member Author

@samin-z regarding #2476 (comment)

Fixed in 6f4140f
fix(archiving): pass context type as typeParam in RequirePermission

Instead of extending the middleware's numeric whitelist as suggested, the two endpoints now pass typeParam: 'context' like every other context endpoint in the controller, so the existing string-based context detection in PermissionMiddleware applies.

@AndyScherzinger
AndyScherzinger force-pushed the feat/2125/personal-archiving-option branch from db76d80 to faf39c4 Compare September 4, 2026 18:18
@AndyScherzinger
AndyScherzinger force-pushed the feat/2125/personal-archiving-option branch 2 times, most recently from 24d6afb to 802890d Compare September 5, 2026 06:30
@AndyScherzinger AndyScherzinger added 3. to review Waiting for reviews and removed 2. developing Work in progress labels Sep 5, 2026
@AndyScherzinger
AndyScherzinger force-pushed the feat/2125/personal-archiving-option branch 11 times, most recently from 86d5be7 to 36faeb9 Compare September 12, 2026 09:27
Add the tables_archive_user table and the contexts.archived column, the UserArchive entity and mapper, and the archived flag on the Table and Context entities. Non-owner archive decisions are stored as per-user override rows, owner decisions live on the entity flag.

Assisted-by: ClaudeCode:claude-fable-5
Signed-off-by: Andy Scherzinger <info@andy-scherzinger.de>
Owner archiving toggles the shared entity flag inside a transaction and clears every per-user override; non-owners store or drop a personal override. The service also resolves the per-user flag onto entity collections and migrates overrides when ownership is transferred.

Assisted-by: ClaudeCode:claude-fable-5
Signed-off-by: Andy Scherzinger <info@andy-scherzinger.de>
…ices

Enrich read paths with the per-user resolved archived flag, add archive/unarchive, keep the state consistent across ownership transfer and deletion, hide archived contexts from the navigation, and expose the archived field in the API response definitions.

Assisted-by: ClaudeCode:claude-fable-5
Signed-off-by: Andy Scherzinger <info@andy-scherzinger.de>
Add the v2 table and context archive/unarchive endpoints (rate-limited, permission-checked, contexts addressed via the string typeParam) and their routes, resolve the per-user state in the single-item GET endpoints, and leave the archived state unchanged on partial updates through API v1 and the occ command.

Assisted-by: ClaudeCode:claude-fable-5
Signed-off-by: Andy Scherzinger <info@andy-scherzinger.de>
Remove stale archive overrides when a share is deleted, a group or circle membership ends, a receiver is deleted, or a user account is removed. Per-user access re-checks are handed to a background job so an unrelated request does not scale with the number of override holders.

Assisted-by: ClaudeCode:claude-fable-5
Signed-off-by: Andy Scherzinger <info@andy-scherzinger.de>
Add archive/unarchive actions to the table and context navigation items, a collapsible archived-applications section, and the matching store actions that guard against a missing local item.

Assisted-by: ClaudeCode:claude-fable-5
Signed-off-by: Andy Scherzinger <info@andy-scherzinger.de>
Assisted-by: ClaudeCode:claude-fable-5
Signed-off-by: Andy Scherzinger <info@andy-scherzinger.de>
Cover the archive service and cleanup service, the mapper, the archive/unarchive controller endpoints, the background job, and the archive/unarchive UI flows for tables and applications.

Assisted-by: ClaudeCode:claude-fable-5
Signed-off-by: Andy Scherzinger <info@andy-scherzinger.de>
@AndyScherzinger
AndyScherzinger force-pushed the feat/2125/personal-archiving-option branch from 36faeb9 to 40aec24 Compare September 12, 2026 10:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

3. to review Waiting for reviews AI assisted enhancement New feature or request

Projects

Status: 🏗️ At engineering

Development

Successfully merging this pull request may close these issues.

5 participants