Skip to content

fix(web): preserve thread archive view#952

Merged
AchoArnold merged 6 commits into
mainfrom
feat/message-thread-archive-ui
Jul 18, 2026
Merged

fix(web): preserve thread archive view#952
AchoArnold merged 6 commits into
mainfrom
feat/message-thread-archive-ui

Conversation

@AchoArnold

Copy link
Copy Markdown
Member

Summary

  • use the primary color for the active message thread list item
  • preserve the current archived/unarchived list filter after moving a thread
  • return to the thread list and show Archived or Unarchived after success

Validation

  • targeted ESLint, Stylelint, and Prettier checks
  • Nuxt static generation
  • archive state and navigation source assertions

AchoArnold and others added 6 commits July 18, 2026 09:44
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: bf78429e-573c-406c-9f7c-1d6e1bddbbb5
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: bf78429e-573c-406c-9f7c-1d6e1bddbbb5
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: bf7ad4f0-3e1b-4f2d-9587-fe5b0dfae6dc
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: bf7ad4f0-3e1b-4f2d-9587-fe5b0dfae6dc
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: bf7ad4f0-3e1b-4f2d-9587-fe5b0dfae6dc
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: bf7ad4f0-3e1b-4f2d-9587-fe5b0dfae6dc
@codacy-production

Copy link
Copy Markdown

Not up to standards ⛔

🔴 Issues 56 minor

Alerts:
⚠ 56 issues (≤ 0 issues of at least minor severity)

Results:
56 new issues

Category Results
CodeStyle 56 minor

View in Codacy

🟢 Metrics 0 complexity · 0 duplication

Metric Results
Complexity 0
Duplication 0

View in Codacy

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

Copilot AI 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.

Pull request overview

This PR updates the web thread UI to keep the current archived/unarchived filter stable when archiving/unarchiving a thread, while improving active-thread styling and returning the user to the thread list after the action.

Changes:

  • Keep the existing archivedThreads filter unchanged when a thread is archived/unarchived; update local store state by removing the moved thread and clearing selection, then show a success notification.
  • Navigate back to /threads after archive/unarchive completes successfully.
  • Apply color="primary" to thread list items so the active item uses the primary color styling.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated no comments.

Show a summary per file
File Description
web/app/stores/threads.ts Updates updateThread to preserve the current archive filter, remove the moved thread from the visible list, clear selection, and show “Archived”/“Unarchived” success notifications.
web/app/pages/threads/[id]/index.vue After archiving/unarchiving, routes back to /threads immediately (instead of delayed menu-state resets).
web/app/components/MessageThread.vue Adds color="primary" to each thread list item to use Vuetify’s active styling.
docs/superpowers/specs/2026-07-18-unarchive-thread-on-receive-design.md Adds an approved design spec for auto-unarchive-on-receive (future scope beyond this PR’s web UI change).
docs/superpowers/specs/2026-07-18-message-thread-archive-ui-design.md Adds a design spec describing the intended archive UI behavior and styling.
docs/superpowers/plans/2026-07-18-unarchive-thread-on-receive.md Adds an implementation plan for the auto-unarchive-on-receive feature across API + web.
docs/superpowers/plans/2026-07-18-message-thread-archive-ui.md Adds an implementation plan for the archive UI behavior implemented by this PR.

@greptile-apps

greptile-apps Bot commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes two related UX issues with the message thread archive view: the active thread list item now highlights in the primary colour, and archive/unarchive actions preserve the current list filter instead of switching it.

  • threads.ts: updateThread now filters the moved thread out of the local collection and shows a success notification (Archived / Unarchived), replacing the previous behaviour of switching archivedThreads and reloading the list.
  • threads/[id]/index.vue: archiveThread and unArchiveThread navigate to /threads after the store action resolves, replacing a setTimeout that only reset selectedMenuItem — the navigation is consistent with the existing deleteThread handler.
  • MessageThread.vue: adds color="primary" to v-list-item so Vuetify automatically applies primary styling when :active is true.

Confidence Score: 5/5

Safe to merge — all three source-file changes are small and well-scoped with no new state or API surface introduced.

The store mutation is straightforward: it filters the list in place and clears the selection without touching the archive filter flag, which is exactly the desired behaviour. The currentThread!.id non-null assertion in the page is evaluated before the await, so the store mutation does not cause a race. The color="primary" addition is a single-prop Vuetify change with no side effects. The docs files are planning artifacts and do not affect the build.

No files require special attention.

Important Files Changed

Filename Overview
web/app/stores/threads.ts updateThread now filters the moved thread out of the local list and shows a notification instead of switching archivedThreads and reloading — core of the fix, logic is correct
web/app/pages/threads/[id]/index.vue archiveThread and unArchiveThread now navigate to /threads after the store action succeeds, replacing a setTimeout that only reset selectedMenuItem — navigation is straightforward and consistent with deleteThread
web/app/components/MessageThread.vue Adds color="primary" to v-list-item so Vuetify applies the primary theme colour when the :active binding is true — one-line styling change, correct usage
docs/superpowers/plans/2026-07-18-message-thread-archive-ui.md Implementation plan / agentic task document describing the steps executed in this PR; no production code
docs/superpowers/plans/2026-07-18-unarchive-thread-on-receive.md Implementation plan for a future unarchive-on-inbound-message feature; no production code in this PR
docs/superpowers/specs/2026-07-18-message-thread-archive-ui-design.md Design spec for the archive-UI changes implemented in this PR; confirms intent of the store and navigation changes
docs/superpowers/specs/2026-07-18-unarchive-thread-on-receive-design.md Design spec for the future auto-unarchive feature; no production code in this PR

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
    participant User
    participant ThreadPage as threads/[id]/index.vue
    participant Store as threads.ts (Pinia)
    participant API as PUT /v1/message-threads/:id
    participant Router

    User->>ThreadPage: clicks Archive / Unarchive
    ThreadPage->>Store: "await updateThread({ threadId, isArchived })"
    Store->>API: PUT is_archived
    API-->>Store: 200 OK
    Store->>Store: "threads.value = threads.filter(t => t.id !== threadId)"
    Store->>Store: "threadId.value = null"
    Store->>Store: "notificationsStore.addNotification("Archived" | "Unarchived")"
    Store-->>ThreadPage: resolves
    ThreadPage->>Router: await router.push('/threads')
    Router-->>User: threads list (current archivedThreads filter preserved)
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
    participant User
    participant ThreadPage as threads/[id]/index.vue
    participant Store as threads.ts (Pinia)
    participant API as PUT /v1/message-threads/:id
    participant Router

    User->>ThreadPage: clicks Archive / Unarchive
    ThreadPage->>Store: "await updateThread({ threadId, isArchived })"
    Store->>API: PUT is_archived
    API-->>Store: 200 OK
    Store->>Store: "threads.value = threads.filter(t => t.id !== threadId)"
    Store->>Store: "threadId.value = null"
    Store->>Store: "notificationsStore.addNotification("Archived" | "Unarchived")"
    Store-->>ThreadPage: resolves
    ThreadPage->>Router: await router.push('/threads')
    Router-->>User: threads list (current archivedThreads filter preserved)
Loading

Reviews (1): Last reviewed commit: "fix(web): preserve thread archive filter" | Re-trigger Greptile

@AchoArnold
AchoArnold merged commit f03d163 into main Jul 18, 2026
12 of 13 checks passed
AchoArnold added a commit that referenced this pull request Jul 18, 2026
Integrate current origin/main (thread archive-view preservation #952,
unarchive-on-receive #954, webhook email payload formatting #955) with the
read-receipts feature set, preserving both.

Semantic resolutions:
- UpdateThread now resolves the per-phone unarchive decision and the inbound
  unread watermark in a single atomic repository.UpdateActivity call. Added an
  Unarchive flag to MessageThreadActivityUpdate so is_archived=false is applied
  in the same transaction as the read-state/last-message updates.
- Missed calls and inbound SMS both use MessageStatusReceived + MarksUnread, so
  they share the same unarchive + mark-unread rules.
- Combined the message thread service test suites (read-receipt stubs plus
  shouldCheckUnarchive coverage) and updated the service/handler test helpers to
  the 5-arg NewMessageThreadService signature (adds phoneRepository).
- Merged tests/README.md coverage entries for both E2E suites.
- Regenerated Swagger and web/shared/types/api.ts so both main's new fields and
  read-receipt fields are present.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: bf00a0ac-e11f-4015-b295-3cdd9b491229
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.

2 participants