Skip to content

fix(contacts): create new contacts in the selected address book - #5764

Open
whoalin1 wants to merge 1 commit into
nextcloud:mainfrom
whoalin1:fix-activity-addressbook-on-create
Open

whoalin1 wants to merge 1 commit into
nextcloud:mainfrom
whoalin1:fix-activity-addressbook-on-create

Conversation

@whoalin1

@whoalin1 whoalin1 commented Oct 6, 2026 •

Copy link
Copy Markdown

Summary

Saving a new contact after changing the address-book dropdown created the vCard in the current/default book and then moved it. Activity therefore showed the temporary book instead of the one the user selected.

For unsaved contacts (!dav), move locally into the target book before createVCard so Activity credits the final address book. Existing contacts still update then move.

Closes #5757

Test plan

  • Two address books A (default) and B; from All contacts / A, New contact → switch dropdown to B → Save → contact lives in B; Activity says created in B (not A)
  • Same flow starting already inside B → Save → Activity still B; no double move
  • Edit existing contact in A, change to B, Save → contact moves to B (regression)
  • New contact without changing address book → still creates in the expected book

AI disclosure

This PR was drafted with the help of AI coding assistants (Cursor agents / LLM-based tools), including the description. I am responsible for it and happy to rework anything that doesn't fit.

All commits carry an Assisted-by: Cursor:grok-4.7 trailer.

Summary by CodeRabbit

  • Bug Fixes
    • New contacts are now placed in the selected address book when saved, including when that destination differs from the current address book.
    • Moving a contact to another address book now completes before the save operation finishes, helping ensure the contact appears in the expected location.

@whoalin1
whoalin1 force-pushed the fix-activity-addressbook-on-create branch from 6afa4d8 to dee595a Compare October 9, 2026 14:13
@github-actions

Copy link
Copy Markdown
Contributor

Hello there,
Thank you so much for taking the time and effort to create a pull request to our Nextcloud project.

We hope that the review process is going smooth and is helpful for you. We want to ensure your pull request is reviewed to your satisfaction. If you have a moment, our community management team would very much appreciate your feedback on your experience with this PR review process.

Your feedback is valuable to us as we continuously strive to improve our community developer experience. Please take a moment to complete our short survey by clicking on the following link: https://cloud.nextcloud.com/apps/forms/s/i9Ago4EQRZ7TWxjfmeEpPkf6

Thank you for contributing to Nextcloud and we hope to hear from you soon!

(If you believe you should not receive this message, you can add yourself to the blocklist.)

@hamza221

Copy link
Copy Markdown
Contributor

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Oct 28, 2026 •

Copy link
Copy Markdown
✅ 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 added bug Something isn't working 3. to review Waiting for reviews labels Oct 28, 2026
@codecov

codecov Bot commented Oct 28, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 0% with 8 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/components/ContactDetails.vue 0.00% 8 Missing ⚠️

📢 Thoughts on this report? Let us know!

@coderabbitai

coderabbitai Bot commented Oct 28, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Walkthrough

When a new contact has a different pending destination address book, the save flow moves it there before saving and clears the pending destination. A destination that remains pending after saving is moved with an awaited call.

Changes: Contact save flow

Layer / File(s) Summary
Move new contact before save
src/components/ContactDetails.vue
Before saving, onSave moves a new contact to its valid, different pending destination address book, updates the local contact, and clears the pending destination. The post-save move is awaited when a destination remains pending.

Priority: Low

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

Change: Bug fix · Severity of issue fixed: Low

Suggested labels: AI assisted

Merge Risk: High · up to dee59

Creating a contact and choosing a different address book can show "Contact not found" and redirect away during the save. This is the main flow the PR targets, so the navigation should be fixed before merging.

Pre-merge checks: Passed 5
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title names the main change: new contacts are now created in the address book the user selected, which fixes the Activity entry that named the wrong default book. The changeset adds the pending de…
Linked Issues check Passed Issue #5757 requires Activity to name the address book selected for a new contact. ContactDetails.onSave detects an unsaved contact with a different pending address book, updates the local address-b…
Out of Scope Changes check Passed The pull request changes only src/components/ContactDetails.vue. The changes reorder new-contact address-book handling and await the existing move operation. These changes directly support issue #57…
Docstring Coverage Passed No eligible functions found in the changed files. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentat…
Full details: Title check

Explanation

The title names the main change: new contacts are now created in the address book the user selected, which fixes the Activity entry that named the wrong default book. The changeset adds the pending destination handling in ContactDetails.onSave that moves a new contact before updateContact, matching this title. The title is specific and short, and it does not need to list every detail.

Full details: Linked Issues check

Explanation

Issue #5757 requires Activity to name the address book selected for a new contact. ContactDetails.onSave detects an unsaved contact with a different pending address book, updates the local address-book reference, moves locally before updateContact/createVCard, and clears the pending move. Existing contacts still update before moving. The reviewed diff supports the required behavior. No automated regression test was added, but issue #5757 does not specify an automated-test requirement.

Full details: Out of Scope Changes check

Explanation

The pull request changes only src/components/ContactDetails.vue. The changes reorder new-contact address-book handling and await the existing move operation. These changes directly support issue #5757 and the stated contact-save behavior.

Full details: Docstring Coverage

Explanation

No eligible functions found in the changed files. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 0 functions across 0 files. (1 skipped: 1 unsupported.)

Finishing Touches: 💡 1
🛠️ Fix failing CI checks: 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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: 1


Review info
Run configuration
Commits

Reviewing files that changed from the base of the PR and between 2377b88 and dee595a.

Files selected for processing: 1
  • src/components/ContactDetails.vue

Included review availability: This review used your included allowance. Your plan provides up to 4 included reviews per hour; 3 remain after this review.

this.updateAddressBookAccesses(pendingAddressBookId)
// createVCard uses localContact.addressbook — keep the clone in sync
this.localContact.addressbook = addressbook
await this.moveContactToAddressbook(pendingAddressBookId)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Major · Functional Correctness · Heavy lift

Supported by static analysis

Script executed:

grep -n "moveContactToAddressbook\|pendingAddressBook\|selectFirstContactIfNone" -r src | head -50
sed -n '1170,1240p' src/components/ContactDetails.vue

Repository: nextcloud/contacts

Length of output: 3980


Script executed:

grep -n "moveContactToAddressbook" -A60 src/components/ContactDetails.vue | sed -n '1,140p'

Repository: nextcloud/contacts

Length of output: 4809


Script executed:

set -e
printf '%s\n' '--- store move action ---'
sed -n '500,610p' src/store/contacts.js
printf '%s\n' '--- contact creation/update bindings ---'
rg -n -F --glob '*.js' -e 'createVCard' -e 'updateContact' -e 'moveContactToAddressbook' src/store src/components/ContactDetails.vue
printf '%s\n' '--- matching store declarations ---'
grep -n -E '^[[:space:]]*(async )?(createVCard|updateContact|moveContactToAddressbook)|createVCard|updateContact' src/store/contacts.js
printf '%s\n' '--- route selection guard ---'
sed -n '540,635p' src/views/Contacts.vue
printf '%s\n' '--- current versus merge-base save flow ---'
git diff --unified=35 c171dbecb062d38d402da688466180dc8094d75e dee595a9dce995453044d7c760a353c6d2a36f77 -- src/components/ContactDetails.vue src/store/contacts.js

Repository: nextcloud/contacts

Length of output: 9710


Script executed:

set -e
printf '%s\n' '--- addressbook move action ---'
sed -n '535,585p' src/store/addressbooks.js
printf '%s\n' '--- contacts update action ---'
sed -n '400,515p' src/store/contacts.js
printf '%s\n' '--- ContactDetails update and contact binding ---'
sed -n '860,925p' src/components/ContactDetails.vue
rg -n -F --glob 'src/components/ContactDetails.vue' -e 'computed:' -e 'contact()' -e 'mapGetters' -e 'selectedAddressbook' -e 'localContact'
printf '%s\n' '--- ContactDetails component setup/computed region ---'
sed -n '300,470p' src/components/ContactDetails.vue
printf '%s\n' '--- contacts list source ---'
rg -n -F --glob 'src/views/Contacts.vue' -e 'contactsList' -e 'selectedContact' -e 'selectedAddressbook'
sed -n '120,230p' src/views/Contacts.vue

Repository: nextcloud/contacts

Length of output: 21773


Script executed:

set -e
printf '%s\n' '--- ContactDetails computed contact and selection ---'
sed -n '540,835p' src/components/ContactDetails.vue
sed -n '945,1015p' src/components/ContactDetails.vue
sed -n '1100,1140p' src/components/ContactDetails.vue
printf '%s\n' '--- contact/addressbook mutations ---'
sed -n '110,270p' src/store/contacts.js
sed -n '1,130p' src/store/addressbooks.js
printf '%s\n' '--- Contacts list and selected route bindings ---'
sed -n '315,420p' src/views/Contacts.vue

Repository: nextcloud/contacts

Length of output: 22152


Script executed:

set -e
printf '%s\n' '--- new-contact creation route ---'
sed -n '450,555p' src/views/Contacts.vue
rg -n -F --glob 'src/**/*.js' -e 'new Contact' -e 'dispatch('\''addContact' -e 'dispatch("addContact"' -e 'addContact(' -e 'getContact' src/views src/components src/store
printf '%s\n' '--- contact getter and key/addressbook model ---'
rg -n -F --glob 'src/models/contact.js' -e 'get key' -e 'set addressbook' -e 'get addressbook' -e 'key()' -e 'addressbook =' -e 'constructor'
sed -n '1,220p' src/models/contact.js
printf '%s\n' '--- ContactDetails props and route contact key ---'
sed -n '470,545p' src/components/ContactDetails.vue
rg -n -F --glob 'src/store/contacts.js' -e 'getContact' -e 'sortedContacts'

Repository: nextcloud/contacts

Length of output: 12709


Navigate to the destination address book after creating the new contact.

The new contact is already in the store. Contacts.vue dispatches addContact before routing to the edit view, so this.contact resolves to the stored contact in A.

The pre-save move changes that stored contact’s address book to B. Because Contact.key includes the address-book ID, this changes the key from A’s key to B’s key. moveContactToAddressbook then pushes the B key while preserving the current selectedAddressbook route parameter, which is still A.

A’s contactsList excludes the B contact. The route watchers can therefore call selectFirstContactIfNone(), show “Contact not found”, and redirect while createVCard is still pending. The move action does not change selectedAddressbook; it only mutates the store and starts navigation.

Keep the store move required for Activity separate from navigation. Suppress navigation for the pre-save move, then push the B route with the new key after updateContact() completes. Retain the existing post-save behavior for existing contacts.

Assisted-by: Cursor:grok-4.7
Signed-off-by: whoalin1 <[email protected]>
@hamza221
hamza221 force-pushed the fix-activity-addressbook-on-create branch from dee595a to 3f468aa Compare October 28, 2026 16:53

This branch has not been deployed

No deployments
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 bug Something isn't working feedback-requested

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Activity shows contact being created in the wrong address book

2 participants