Skip to content

Refine archive management UX across web and mobile - #3552

Closed
Quicksaver wants to merge 106 commits into
pingdotgg:mainfrom
Quicksaver:split/archive-settings-ux
Closed

Refine archive management UX across web and mobile#3552
Quicksaver wants to merge 106 commits into
pingdotgg:mainfrom
Quicksaver:split/archive-settings-ux

Conversation

@Quicksaver

@Quicksaver Quicksaver commented Jun 25, 2026

Copy link
Copy Markdown

Summary

This replaces the flat Archive settings list with a compact project-grouped browser on web and brings the same information hierarchy and management capabilities to the native Archived Threads screen. Archived conversations can be searched by ranked title matches, sorted by archived or created time, and expanded or collapsed by project.

Both surfaces load archive snapshots for every configured environment and expose scoped per-thread and project-level unarchive/delete actions. Destructive actions preserve each platform's guarded delete behavior, filtered bulk actions affect only matching rows, and bulk execution is bounded and failure-aware.

Native Settings exposes Archived Threads consistently in local-only and T3 Connect-configured modes through a shared settings-tail and route contract, while retaining the legacy waitlist deep-link alias as a distinct sign-in route.

What Changed

  • Moved the web Archive settings UI into ArchiveSettings.tsx and wired the archived settings route directly to the dedicated panel.
  • Grouped archived conversations by environment and project on web and native, using collision-safe scoped keys for grouping, list identity, and expansion state.
  • Added ranked, case-insensitive multi-term title search with bounded score tiers that preserve phrase/all-token/partial ordering for long titles, search-forced expansion that preserves saved collapse state, sortable archived/created columns, relative timestamps with invalid archive-date fallback, project favicons, counts, and compact rows.
  • Loaded archived snapshots from the full environment catalog so archived-only environments remain visible even when they have no active projects.
  • Filtered active rows defensively from web archive snapshots and kept native project-section ordering aligned with the selected sort field and direction.
  • Added web hover/focus row actions with tooltips, plus native swipe actions and long-press menus for unarchive and guarded delete.
  • Centralized the native General, Appearance, Beta, Archive, and App settings tail plus archive and legacy waitlist route metadata in a tested contract, preserving the same order and Archive entry in both local-only and configured modes.
  • Kept archive confirmations aligned with the standard thread-action fallback when no local dialog host is available.
  • Added project-level unarchive/delete menus scoped to all rows or visible search matches, with scope-accurate labels and confirmations that respect confirmThreadDelete on web and native confirmation flows on mobile.
  • Limited bulk work to four concurrent actions, stopped scheduling new work after unexpected exceptions, waited for active workers to settle, preserved completed success/failure/skipped counts in exception feedback, refreshed snapshots after attempts, reported partial or interrupted outcomes accurately, and surfaced distinct underlying exception messages on both surfaces.
  • Added collision-safe per-thread reservations across web row and project actions, kept confirmation state distinct from mutation busy state, scoped rendered busy keys to actions that actually started, disabled overlapping mutation controls while work is pending, surfaced rejected duplicates explicitly, and suppressed per-row archive refreshes so bulk operations refresh snapshots once after the batch settles.
  • Added the same collision-safe reservation ownership to native archive row and project actions, reserving bulk targets before confirmation, disabling overlapping swipe/menu controls while reserved, and starting visible busy indicators only after confirmation. The lower-level mobile action executor now also uses collision-safe tuple identity keys, so separator-containing environment and thread IDs cannot be mis-deduplicated.
  • Distinguished succeeded, failed, and already-in-flight skipped outcomes for native thread actions so overlapping bulk work reports skipped rows separately instead of presenting them as server failures.
  • Kept the native archive list mounted across incremental search updates so filtering preserves scroll position and transient row state while viewport changes can still reset the render window.
  • Kept search ranking, grouping, sorting, and concurrency behavior in dedicated web and native logic modules rather than the React components.
  • Added focused web and native tests for search ranking including long-title tier boundaries, active-row filtering, grouping and collision-resistant keys, timestamp fallback, sorting, bulk scope labels, bounded concurrency, failure aggregation, interruption feedback, and exception handling.
  • Added a server regression test proving projects whose only threads are archived still require force before deletion.
  • Added an Archive user guide covering reversible lifecycle controls, safeguards, and search-scoped bulk actions across web, desktop, and mobile; linked it from the documentation index and defined Archive separately from deletion in the encyclopedia.
  • Documented the shared web/mobile archive behavior, primary files, and branch-assigned development ports in BRANCH_DETAILS.md.

Why

The previous archive views became difficult to scan and manage for users with large archives, and web and mobile exposed different levels of control. A shared dense hierarchy, consistent search and sort behavior, and actions close to each project or conversation make archive maintenance faster while preserving environment isolation and platform-native interaction patterns.

Validation

  • pnpm exec vp test run apps/web/src/components/settings/SettingsPanels.logic.test.ts apps/web/src/hooks/useThreadActions.test.ts apps/mobile/src/features/archive/archivedThreadList.test.ts apps/mobile/src/features/home/useThreadListActions.test.ts passed with 4 files and 49 tests.
  • The final focused mobile executor regression suite passed with 1 file and 5 tests, including distinct scoped thread pairs whose IDs contain separators.
  • The latest focused web and mobile archive logic suites passed with 2 files and 44 tests, including partial outcome preservation when a bounded worker throws.
  • The review-specific mobile archive logic suite passed with 1 file and 16 tests, including overlapping project date ranges that verify ascending sections use each project's oldest thread while descending sections use its newest thread. Focused formatting, type-aware/type-check lint, and git diff --check passed.
  • An integrated iOS recheck paired a disposable client to a three-row archive fixture on port 13774, but the Archive sheet body rendered neither rows nor an error despite exposing the connected environment and archive controls. The MJPEG serve-sim fallback streamed the same blank state successfully, so this pass could not drive the sort control through the fixture.
  • Focused formatting and type-aware lint passed for the current review-affected files; git diff --check also passed.
  • Playwright verified the isolated web Archive panel filters active rows from archive content and empty-state counts, falls back from an invalid archived timestamp for display, reorders rows when archived-date direction changes, and preserves phrase/all-token/partial ordering when matches occur late in long titles.
  • Playwright also verified confirmation keeps the archived row and project idle and enabled, while two immediate clicks on the same row emit one mutation, show explicit duplicate-action feedback, and expose busy state that disables both row actions plus the project menu.
  • Playwright verified an overlapping confirmation/mutation scenario keeps the unstarted reserved row idle and enabled while only the started row and project controls are busy and disabled.
  • An installed iOS development client connected to a disposable server on the branch-assigned port and rendered 22 archived rows on an iPhone 17 Pro simulator. After scrolling to row 10, changing the native search query preserved row 10 as the first visible result, proving the list was not remounted per keystroke.
  • A rebuilt iOS development client connected to a disposable server on port 13774 and rendered two archived rows on an iPhone 17 Pro simulator. A semantic long-press exposed the native Unarchive action; executing it moved the selected row to the live thread list while leaving the other row archived. The simulator was also exposed through the requested serve-sim collaborative browser stream.
  • The requested serve-sim stream registered the simulator framebuffer but failed to encode frames (encodingFailed), so native verification used XcodeBuildMCP semantic UI snapshots and screenshots instead.
  • Package typechecks were attempted but remain blocked by unrelated existing errors elsewhere in the web and mobile packages.

Proof

Archive settings grouped project browser Screenshot_20260719-223953

Note

Medium Risk
Large UI and state-management change across web and mobile thread lifecycle (unarchive/delete/bulk) with concurrency and snapshot refresh; mistakes could cause duplicate mutations or stale archive views, but behavior is heavily tested and confirmations/guards are preserved.

Overview
Replaces the flat web Archive list with a dense, project-grouped browser in ArchiveSettings.tsx and aligns native Archived Threads with the same hierarchy: collapsed project sections, ranked title search, sortable Archived / Created columns, environment labels, and per-row unarchive/delete (web hover overlay; native swipe and long-press).

Archive data and logic now pull snapshots from all configured environments, exclude non-archived rows from grouping and empty states, fall back to created time when archive timestamps are invalid, and use collision-safe scoped keys for expansion, list identity, and action locks. Search ranking (phrase → all tokens → partial) and sort/group behavior live in SettingsPanels.logic.ts and archivedThreadList.ts with expanded tests.

Bulk and concurrency: project menus unarchive or delete all or matching rows (search-scoped labels and confirmations; web respects confirmThreadDelete). Row and bulk actions reserve threads before confirm, show busy only after work starts, reject overlapping duplicates, run bulk work with bounded concurrency and structured partial-failure feedback, and refresh archive snapshots once after bulk attempts. Native thread actions return succeeded / failed / skipped; settings tail and archive route metadata are centralized in settingsContract.ts (legacy waitlist alias unchanged).

Docs and server: Archive user guide, encyclopedia entry, and index link; regression that projects with only archived threads still require force to delete.

Reviewed by Cursor Bugbot for commit 3d969ba. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Refine archived threads UX with search, sorting, bulk actions, and concurrency guards across web and mobile

  • Adds tiered search ranking (archivedThreadSearchScore) that scores thread titles by phrase match, all-token match, and partial-token match; non-matching threads are excluded during search
  • Introduces per-field sort state (createdAt/archivedAt, asc/desc) with nextArchivedThreadSortState and compareArchivedThreads; groups reorder based on search score or per-group extremal timestamps
  • Adds cooperative action locking (tryAcquireArchivedThreadActionLock/releaseArchivedThreadActionLock) to prevent concurrent unarchive/delete operations on the same threads, with busy/reserved visual states in both web and mobile UIs
  • Adds runArchivedThreadActions/runArchivedProjectThreadActions for bounded-concurrency bulk actions with structured outcome summaries (ArchivedProjectBulkActionError/ArchivedThreadActionError) and human-readable failure descriptions
  • Rebuilds ArchivedThreadsScreen.tsx with FlatList, collapsible project groups, context menus per thread and project, and dual timestamp display; replaces the old ArchivedThreadsPanel on web with a new implementation in ArchiveSettings.tsx
  • Centralizes mobile settings tail section ordering in settingsContract.ts and updates useArchivedThreadListActions to return a tri-state succeeded/failed/skipped result with optional Alert and refresh suppression
  • Risk: the old ArchivedThreadsPanel export is removed from SettingsPanels.tsx; any consumer still importing it will fail at build time

Macroscope summarized 3d969ba.

- Group archived threads by project with collapsible sections
- Add sortable archived/created columns and inline row actions
- Support direct delete and bulk project actions with confirmation
@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Jun 25, 2026
@coderabbitai

coderabbitai Bot commented Jun 25, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: f535adae-f439-478d-b0c1-86f15e7794ce

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Comment thread apps/web/src/components/settings/SettingsPanels.tsx Outdated
Comment thread apps/web/src/components/settings/SettingsPanels.tsx Outdated
@macroscopeapp

macroscopeapp Bot commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR introduces significant new archive management features including search ranking, bulk project actions, and collision-safe action locking across web and mobile surfaces. New user-facing capabilities of this scope warrant human review.

You can customize Macroscope's approvability policy. Learn more.

- Replace inline project-level unarchive/delete buttons with a right-click menu
- Keep the existing confirmation flow for bulk archived-thread actions
- Add case-insensitive search across archived thread titles
- Rank exact phrase, full-term, and partial matches; auto-expand matching projects
- Update archive empty states and preserve project actions under search
- Use filtered archive rows for project actions during search
- Use the full project archive list for bulk context actions

- Keep search filtering from narrowing project-wide confirmations
- Limit project archive actions to filtered visible threads

- Add archive search ranking tests
@github-actions github-actions Bot added size:XL 500-999 changed lines (additions + deletions). and removed size:L 100-499 changed lines (additions + deletions). labels Jun 25, 2026
Selective archive-settings portion of main commit 1c6f66b. Keeps the branch-local extracted search-ranking helper and tests while preserving the project header interaction cleanup.
Comment thread apps/web/src/components/settings/SettingsPanels.tsx Outdated
Comment thread apps/web/src/components/settings/SettingsPanels.tsx Outdated
Comment thread apps/web/src/components/settings/SettingsPanels.tsx Outdated
- Move archived search and grouping into logic helpers
- Share bulk action and sort helpers with the panel
- Add tests for grouping, sorting, and bulk action concurrency
- Wait for active bulk-action workers before rethrowing

- Assert archived project bulk actions cover queued threads
- Aggregate archived bulk action errors

- Index archived threads by project

- Strengthen archived settings logic tests
- Skip local dialog confirmation when no local API is available
Comment thread apps/web/src/components/settings/SettingsPanels.logic.ts Outdated
- Encode environment and project ids as tuple keys

- Cover colon-containing ids in archive grouping tests

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit c281ad8. Configure here.

Comment thread apps/mobile/src/features/archive/archivedThreadList.ts Outdated
- Use the oldest project thread timestamp for ascending sorts
- Cover overlapping project date ranges in the mobile archive suite
Comment thread apps/mobile/src/features/archive/archivedThreadList.ts Outdated
T3 Verification added 16 commits July 28, 2026 18:02
- Compute project sort extrema in one pass for large archives
- Preserve oldest-first and newest-first section ordering
- Keep alias metadata limited to values consumed by the stack
- Clarify where the legacy alias screen binding is owned
…ngs-ux

# Conflicts:
#	apps/web/src/components/settings/SettingsPanels.logic.test.ts
#	apps/web/src/components/settings/SettingsPanels.logic.ts
#	apps/web/src/components/settings/SettingsPanels.tsx
@juliusmarminge

Copy link
Copy Markdown
Member

Closing in favor of #2829 (orchestration V2).

#2829 deletes the V1 orchestration layer this PR builds on — apps/server/src/orchestration/**, provider/Layers/*Adapter.ts and provider/Services/** are removed and replaced by apps/server/src/orchestration-v2/**, with the IPC surface renamed to ORCHESTRATION_V2_WS_METHODS. The files this PR touches either no longer exist or are rewritten, so it can't be rebased — it would need reimplementing against the V2 adapters.

This is not a judgement on the change itself. Several of these are real gaps we still want fixed; the base just moved out from under them.

Once #2829 merges, please rebase onto main, port the change to the V2 equivalent, and reopen (or open a fresh PR). Ping me and I'll prioritise the review.

@Quicksaver

Copy link
Copy Markdown
Author

Re-opening this. The relation to the #2829 work is tangential. the behavior implemented here is entirely unrelated. The branch is routinely kept up-to-date with main, #2829 will be merged in here when that's integrated as well (if it goes in first).

Together with #4016 and #4384, this provides real value right now that should not by itself be held up by orchestration v2.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL 1,000+ changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants