Skip to content

fix(deletion): leave the route of a deleted contact - #5709

Open
hamza221 wants to merge 2 commits into
mainfrom
fix/contact-deletion
Open

fix(deletion): leave the route of a deleted contact#5709
hamza221 wants to merge 2 commits into
mainfrom
fix/contact-deletion

Conversation

@hamza221

@hamza221 hamza221 commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

Assisted-by: ClaudeCode:claude-opus-5

🤖 AI (if applicable)

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

Summary by CodeRabbit

  • Bug Fixes

    • Deleting an open contact now redirects to the appropriate contact list after deletion completes.
    • Deleting multiple contacts now navigates away only when the currently open contact is included, preventing routes from pointing to deleted contacts.
  • Tests

    • Added coverage for contact deletion and route navigation behavior.

Assisted-by: ClaudeCode:claude-opus-5
Signed-off-by: Hamza <hamzamahjoubi221@gmail.com>
@hamza221
hamza221 requested a review from GVodyanov as a code owner September 7, 2026 13:21
@hamza221 hamza221 added the bug Something isn't working label Sep 7, 2026
@hamza221 hamza221 added the 3. to review Waiting for reviews label Sep 7, 2026
@hamza221

hamza221 commented Sep 7, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai review please

@coderabbitai

coderabbitai Bot commented Sep 7, 2026

Copy link
Copy Markdown

@hamza221 I will review the changes for correctness, test coverage, and maintainability.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@hamza221

hamza221 commented Sep 7, 2026

Copy link
Copy Markdown
Contributor Author

/backport to stable8.8

@codecov

codecov Bot commented Sep 7, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 36.36364% with 7 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/components/ContactsList.vue 36.36% 7 Missing ⚠️

📢 Thoughts on this report? Let us know!

@coderabbitai

coderabbitai Bot commented Sep 7, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Contact deletion now waits for store removal and redirects to the appropriate list route. Multi-selection deletion redirects only when it includes the open contact. New tests cover route selection, deletion ordering, and conditional navigation.

Changes

Contact deletion routing

Layer / File(s) Summary
Single-contact deletion routing
src/components/ContactDetails.vue, tests/javascript/components/contact-deletion-route.test.js
ContactDetails uses RouterMixin. deleteContact awaits the store action and replaces the route with listRoute(). Tests cover group routes, addressbook routes, and deletion-before-navigation ordering.
Multi-selection deletion routing
src/components/ContactsList.vue, tests/javascript/components/contact-deletion-route.test.js
deleteAllMultiSelected() checks whether the open contact is selected. It replaces the route only when that contact is deleted. Tests cover both conditions.

Estimated code review effort: 2 (Simple) | ~15 minutes

Merge Risk: 🟡 Moderate · up to 26869

This change clears the contact route after deletion, but multi-contact deletion can navigate away from a read-only contact that remains available and can change routes before batch deletion starts. These correctness issues should be resolved before merge.

Sequence Diagram(s)

sequenceDiagram
  participant ContactDetails
  participant ContactsList
  participant Store
  participant Router

  ContactDetails->>Store: Dispatch contact deletion
  Store-->>ContactDetails: Deletion resolves
  ContactDetails->>Router: Replace with listRoute()

  ContactsList->>ContactsList: Check whether selected contact is deleted
  ContactsList->>Store: Delete selected contacts
  alt Open contact was deleted
    ContactsList->>Router: Replace with listRoute()
  end
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: navigating away from a route after deleting its contact.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 1 functions across 1 files. (2 skipped: 2 …
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/contact-deletion

Warning

Some tools did not complete. Review the errors below.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

tests/javascript/components/contact-deletion-route.test.js

Oops! Something went wrong! :(

ESLint: 10.10.0

ReferenceError: module is not defined in ES module scope
This file is being treated as an ES module because it has a '.js' file extension and '/package.json' contains "type": "module". To treat it as a CommonJS script, rename it to use the '.cjs' file extension.
at file:///tests/.eslintrc.js?mtime=1788787448645:5:1
at ModuleJob.run (node:internal/modules/esm/module_job:437:25)
at async node:internal/modules/esm/loader:639:26
at async dynamicImportConfig (/.eslint-tmp/node_modules/.pnpm/eslint@10.10.0_supports-color@8.1.1/node_modules/eslint/lib/config/config-loader.js:185:17)
at async loadConfigFile (/.eslint-tmp/node_modules/.pnpm/eslint@10.10.0_supports-color@8.1.1/node_modules/eslint/lib/config/config-loader.js:275:9)
at async ConfigLoader.calculateConfigArray (/.eslint-tmp/node_modules/.pnpm/eslint@10.10.0_supports-color@8.1.1/node_modules/eslint/lib/config/config-loader.js:594:23)
at async #calculateConfigArray (/.eslint-tmp/node_modules/.pnpm/eslint@10.10.0_supports-color@8.1.1/node_modules/eslint/lib/config/config-loader.js:369:19)
at async Promise.all (index 0)
at async findFiles (/.eslint-tmp/node_modules/.pnpm/eslint@10.10.0_supports-color@8.1.1/node_modules/eslint/lib/eslint/eslint-helpers.js:637:25)
at async ESLint.lintFiles (/.eslint-tmp/node_modules/.pnpm/eslint@10.10.0_supports-color@8.1.1/node_modules/eslint/lib/eslint/eslint.js:1025:21)


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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2


ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Team

Run ID: a8e82b49-4182-4246-b049-95d3561da743

📥 Commits

Reviewing files that changed from the base of the PR and between 7d3b079 and 2686942.

📒 Files selected for processing (3)
  • src/components/ContactDetails.vue
  • src/components/ContactsList.vue
  • tests/javascript/components/contact-deletion-route.test.js

Included review availability: Your plan provides up to 4 included reviews per hour; 2 remain after this review.

Comment thread src/components/ContactsList.vue Outdated
Comment on lines +503 to +504
const deletesSelectedContact = Array.from(this.multiSelectedContacts.values())
.some((contact) => contact.key === this.selectedContact)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Navigate only when the open contact will be deleted.

deletesSelectedContact checks only selection membership. The deletion loop skips read-only contacts. If the open contact is read-only and another selected contact is deleted, the new route replacement removes the still-existing open contact from the URL.

  • src/components/ContactsList.vue#L503-L504: include the same deletion-eligibility condition used by the deletion loop when computing deletesSelectedContact.
  • tests/javascript/components/contact-deletion-route.test.js#L113-L116: make the navigation case use a deletable open contact, and add a read-only open-contact case that expects no route replacement.
📍 Affects 2 files
  • src/components/ContactsList.vue#L503-L504 (this comment)
  • tests/javascript/components/contact-deletion-route.test.js#L113-L116

Comment on lines +517 to +520
// the route would otherwise keep pointing at a deleted contact
if (deletesSelectedContact) {
this.$router.replace(this.listRoute())
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🔎 Supported by static analysis

🏁 Script executed:

#!/bin/bash
set -eu

printf '%s\n' '--- ContactsList.vue relevant methods and route replacement ---'
rg -n -A45 -B25 'deleteAllMultiSelected|deletesSelectedContact|this\.\$router\.replace' src/components/ContactsList.vue
printf '%s\n' '--- file header ---'
head -n 12 src/components/ContactsList.vue

Repository: nextcloud/contacts

Length of output: 5090


Await batch deletions before replacing the route.

Map.forEach(async ...) does not await its callbacks. Each callback waits 500 ms, so this.$router.replace(this.listRoute()) can run before deleteContact starts. Make deleteAllMultiSelected async and await all writable-contact deletion promises before replacing the route.

Signed-off-by: Hamza <hamzamahjoubi221@gmail.com>

@GVodyanov GVodyanov 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.

Tested, works

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 backport-request bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants