From b66ee40fb621d32c992355ed26b6dc589662a0e9 Mon Sep 17 00:00:00 2001 From: Matthieu Date: Wed, 1 Jul 2026 08:58:17 +0200 Subject: [PATCH 1/4] fix: restore addressbook navigation and fix sharing button MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add address books section to the left sidebar navigation so users can filter contacts by address book (feature was removed in bd536c0e when settings were moved to a modal dialog) - Fix sharing button never showing due to wrong property name: currentUserPrincipal.principalUrl → currentUserPrincipal.url, causing isSharedWithMe to always be true and hiding the share button Co-Authored-By: Claude Sonnet 4.6 Signed-off-by: Matthieu --- .../AppNavigation/RootNavigation.vue | 37 +++++++++++++++++++ .../Settings/SettingsAddressbook.vue | 2 +- src/mixins/RouterMixin.js | 3 ++ src/models/constants.ts | 1 + src/router/index.js | 7 +++- src/views/Contacts.vue | 8 ++++ 6 files changed, 56 insertions(+), 2 deletions(-) diff --git a/src/components/AppNavigation/RootNavigation.vue b/src/components/AppNavigation/RootNavigation.vue index de60ab6ca3..4bc43d7bd3 100644 --- a/src/components/AppNavigation/RootNavigation.vue +++ b/src/components/AppNavigation/RootNavigation.vue @@ -94,6 +94,29 @@ + + + + + + + ab.enabled) + }, + circles() { return this.$store.getters.getCircles }, @@ -426,6 +459,10 @@ export default { }, methods: { + addressbookContactCount(addressbook) { + return Object.keys(addressbook.contacts || {}).length + }, + toggleNewGroupMenu() { this.isNewGroupMenuOpen = !this.isNewGroupMenuOpen }, diff --git a/src/components/AppNavigation/Settings/SettingsAddressbook.vue b/src/components/AppNavigation/Settings/SettingsAddressbook.vue index 9bd5be7ca1..a15def2501 100644 --- a/src/components/AppNavigation/Settings/SettingsAddressbook.vue +++ b/src/components/AppNavigation/Settings/SettingsAddressbook.vue @@ -245,7 +245,7 @@ export default { principalUrl() { const principalsStore = usePrincipalsStore() - return principalsStore.currentUserPrincipal.principalUrl + return principalsStore.currentUserPrincipal?.url }, isSharedWithMe() { diff --git a/src/mixins/RouterMixin.js b/src/mixins/RouterMixin.js index e88635ff32..a1cf183449 100644 --- a/src/mixins/RouterMixin.js +++ b/src/mixins/RouterMixin.js @@ -20,5 +20,8 @@ export default { selectedChart() { return this.$route.params.selectedChart }, + selectedAddressbook() { + return this.$route.params.selectedAddressbook + }, }, } diff --git a/src/models/constants.ts b/src/models/constants.ts index fed33ce1ad..8f67f8749f 100644 --- a/src/models/constants.ts +++ b/src/models/constants.ts @@ -28,6 +28,7 @@ export const CHART_ALL_CONTACTS: DefaultChart = t('contacts', 'Organization char export const ROUTE_CIRCLE = 'circle' export const ROUTE_CHART = 'chart' export const ROUTE_USER_GROUP = 'user_group' +export const ROUTE_ADDRESSBOOK = 'addressbook' // Contact settings export const CONTACTS_SETTINGS: DefaultGroup = t('contacts', 'Contacts settings') diff --git a/src/router/index.js b/src/router/index.js index 4913933020..cf546458bd 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -6,7 +6,7 @@ import { generateUrl } from '@nextcloud/router' import { createRouter, createWebHistory } from 'vue-router' import Contacts from '../views/Contacts.vue' -import { ROUTE_CHART, ROUTE_CIRCLE, ROUTE_USER_GROUP } from '../models/constants.ts' +import { ROUTE_ADDRESSBOOK, ROUTE_CHART, ROUTE_CIRCLE, ROUTE_USER_GROUP } from '../models/constants.ts' // if index.php is in the url AND we got this far, then it's working: // let's keep using index.php in the url @@ -57,6 +57,11 @@ export default createRouter({ name: 'user_group', component: Contacts, }, + { + path: `${ROUTE_ADDRESSBOOK}/:selectedAddressbook`, + name: 'addressbook', + component: Contacts, + }, ], }, ], diff --git a/src/views/Contacts.vue b/src/views/Contacts.vue index 9def24512d..2d4da41c2d 100644 --- a/src/views/Contacts.vue +++ b/src/views/Contacts.vue @@ -187,6 +187,14 @@ export default { * @return {Array} */ contactsList() { + if (this.selectedAddressbook) { + const addressbook = this.addressbooks.find((ab) => ab.id === this.selectedAddressbook) + if (addressbook) { + const keys = Object.keys(addressbook.contacts) + return this.sortedContacts.filter((contact) => keys.includes(contact.key)) + } + return [] + } if (this.selectedGroup === GROUP_ALL_CONTACTS) { return this.sortedContacts } else if (this.selectedGroup === GROUP_NO_GROUP_CONTACTS) { From fae80bed0dc8eb879bb5e14dc54c86aa8d620fde Mon Sep 17 00:00:00 2001 From: Matthieu Date: Wed, 1 Jul 2026 09:47:43 +0200 Subject: [PATCH 2/4] fix: handle addressbook route in contact navigation and creation - Fix "Missing required param selectedGroup" error when browsing an address book: ContactsListItem now uses GROUP_ALL_CONTACTS as fallback and selectFirstContactIfNone() early-exits on the addressbook route - New contacts created while an address book is selected are saved into that address book instead of the default one Co-Authored-By: Claude Sonnet 4.6 Signed-off-by: Matthieu --- .../ContactsList/ContactsListItem.vue | 28 +++++++++++++++---- src/views/Contacts.vue | 21 +++++++++----- 2 files changed, 36 insertions(+), 13 deletions(-) diff --git a/src/components/ContactsList/ContactsListItem.vue b/src/components/ContactsList/ContactsListItem.vue index 2ae0208c4e..fd51c60629 100644 --- a/src/components/ContactsList/ContactsListItem.vue +++ b/src/components/ContactsList/ContactsListItem.vue @@ -13,7 +13,7 @@ :key="source.key" class="list-item-style envelope" :name="source.displayName" - :to="isStatic ? undefined : { name: 'contact', params: { selectedGroup: selectedGroup, selectedContact: source.key } }"> + :to="isStatic ? undefined : contactRoute">