diff options
-rw-r--r-- | package-lock.json | 82 | ||||
-rw-r--r-- | package.json | 1 | ||||
-rw-r--r-- | src/components/AppNavigation/Settings/SettingsAddressbook.vue | 28 | ||||
-rw-r--r-- | src/main.js | 6 | ||||
-rw-r--r-- | src/store/principals.js | 34 | ||||
-rw-r--r-- | src/views/Contacts.vue | 4 |
6 files changed, 148 insertions, 7 deletions
diff --git a/package-lock.json b/package-lock.json index 7f560b8c..fcf04a8e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -37,6 +37,7 @@ "mitt": "^3.0.1", "moment": "^2.30.1", "p-limit": "^5.0.0", + "pinia": "^2.1.7", "qr-image": "^3.2.0", "string-natural-compare": "^3.0.1", "uuid": "^9.0.1", @@ -4323,6 +4324,11 @@ "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", "dev": true }, + "node_modules/@vue/devtools-api": { + "version": "6.6.1", + "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.6.1.tgz", + "integrity": "sha512-LgPscpE3Vs0x96PzSSB4IGVSZXZBZHpfxs+ZA1d+VEPwHdOXowy/Y2CsvCAIFrf+ssVU1pD1jidj505EpUnfbA==" + }, "node_modules/@vue/eslint-config-typescript": { "version": "12.0.0", "resolved": "https://registry.npmjs.org/@vue/eslint-config-typescript/-/eslint-config-typescript-12.0.0.tgz", @@ -14674,6 +14680,56 @@ "node": ">=6" } }, + "node_modules/pinia": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/pinia/-/pinia-2.1.7.tgz", + "integrity": "sha512-+C2AHFtcFqjPih0zpYuvof37SFxMQ7OEG2zV9jRI12i9BOy3YQVAHwdKtyyc8pDcDyIc33WCIsZaCFWU7WWxGQ==", + "dependencies": { + "@vue/devtools-api": "^6.5.0", + "vue-demi": ">=0.14.5" + }, + "funding": { + "url": "https://github.com/sponsors/posva" + }, + "peerDependencies": { + "@vue/composition-api": "^1.4.0", + "typescript": ">=4.4.4", + "vue": "^2.6.14 || ^3.3.0" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + }, + "typescript": { + "optional": true + } + } + }, + "node_modules/pinia/node_modules/vue-demi": { + "version": "0.14.7", + "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.7.tgz", + "integrity": "sha512-EOG8KXDQNwkJILkx/gPcoL/7vH+hORoBaKgGe+6W7VFMvCYJfmF2dGbvgDroVnI8LU7/kTu8mbjRZGBU1z9NTA==", + "hasInstallScript": true, + "bin": { + "vue-demi-fix": "bin/vue-demi-fix.js", + "vue-demi-switch": "bin/vue-demi-switch.js" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@vue/composition-api": "^1.0.0-rc.1", + "vue": "^3.0.0-0 || ^2.6.0" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + } + } + }, "node_modules/pirates": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz", @@ -17842,7 +17898,7 @@ "version": "5.3.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", - "dev": true, + "devOptional": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -22378,6 +22434,11 @@ } } }, + "@vue/devtools-api": { + "version": "6.6.1", + "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.6.1.tgz", + "integrity": "sha512-LgPscpE3Vs0x96PzSSB4IGVSZXZBZHpfxs+ZA1d+VEPwHdOXowy/Y2CsvCAIFrf+ssVU1pD1jidj505EpUnfbA==" + }, "@vue/eslint-config-typescript": { "version": "12.0.0", "resolved": "https://registry.npmjs.org/@vue/eslint-config-typescript/-/eslint-config-typescript-12.0.0.tgz", @@ -29909,6 +29970,23 @@ "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==" }, + "pinia": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/pinia/-/pinia-2.1.7.tgz", + "integrity": "sha512-+C2AHFtcFqjPih0zpYuvof37SFxMQ7OEG2zV9jRI12i9BOy3YQVAHwdKtyyc8pDcDyIc33WCIsZaCFWU7WWxGQ==", + "requires": { + "@vue/devtools-api": "^6.5.0", + "vue-demi": ">=0.14.5" + }, + "dependencies": { + "vue-demi": { + "version": "0.14.7", + "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.7.tgz", + "integrity": "sha512-EOG8KXDQNwkJILkx/gPcoL/7vH+hORoBaKgGe+6W7VFMvCYJfmF2dGbvgDroVnI8LU7/kTu8mbjRZGBU1z9NTA==", + "requires": {} + } + } + }, "pirates": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz", @@ -32263,7 +32341,7 @@ "version": "5.3.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", - "dev": true + "devOptional": true }, "unbox-primitive": { "version": "1.0.2", diff --git a/package.json b/package.json index 66a88089..5ca25aa8 100644 --- a/package.json +++ b/package.json @@ -64,6 +64,7 @@ "mitt": "^3.0.1", "moment": "^2.30.1", "p-limit": "^5.0.0", + "pinia": "^2.1.7", "qr-image": "^3.2.0", "string-natural-compare": "^3.0.1", "uuid": "^9.0.1", diff --git a/src/components/AppNavigation/Settings/SettingsAddressbook.vue b/src/components/AppNavigation/Settings/SettingsAddressbook.vue index c972b202..1f81fd33 100644 --- a/src/components/AppNavigation/Settings/SettingsAddressbook.vue +++ b/src/components/AppNavigation/Settings/SettingsAddressbook.vue @@ -105,9 +105,16 @@ </template> </ActionInput> </template> - <!-- delete addressbook --> - <ActionButton v-if="hasMultipleAddressbooks" + <ActionButton v-if="hasMultipleAddressbooks && addressbook.owner !== principalUrl && addressbook.owner !== '/remote.php/dav/principals/system/system/'" + @click="confirmUnshare"> + <template #icon> + <IconLoading v-if="deleteAddressbookLoading" :size="20" /> + <IconDelete :size="20" /> + </template> + {{ t('contacts', 'Unshare from me') }} + </ActionButton> + <ActionButton v-else-if="hasMultipleAddressbooks && addressbook.owner !== '/remote.php/dav/principals/system/system/'" @click="confirmDeletion"> <template #icon> <IconLoading v-if="deleteAddressbookLoading" :size="20" /> @@ -116,7 +123,6 @@ {{ t('contacts', 'Delete') }} </ActionButton> </Actions> - <!-- sharing input --> <ShareAddressBook v-if="shareOpen && !addressbook.readOnly" :addressbook="addressbook" /> </li> @@ -143,6 +149,8 @@ import { showError } from '@nextcloud/dialogs' import CopyToClipboardMixin from '../../../mixins/CopyToClipboardMixin.js' +import usePrincipalsStore from '../../../store/principals.js' + export default { name: 'SettingsAddressbook', @@ -241,6 +249,10 @@ export default { groupsCount() { return this.groups.length }, + principalUrl() { + const principalsStore = usePrincipalsStore() + return principalsStore.currentUserPrincipal.principalUrl + }, }, watch: { menuOpen() { @@ -277,7 +289,6 @@ export default { this.toggleEnabledLoading = false } }, - confirmDeletion() { OC.dialogs.confirm( t('contacts', 'This will delete the address book and every contacts within it'), @@ -286,7 +297,14 @@ export default { true, ) }, - + confirmUnshare() { + OC.dialogs.confirm( + t('contacts', 'This will unshare the address book and every contacts within it'), + t('contacts', 'Unshare {addressbook}?', { addressbook: this.addressbook.displayName }), + this.deleteAddressbook, + true, + ) + }, async deleteAddressbook(confirm) { if (confirm) { // change to loading status diff --git a/src/main.js b/src/main.js index d95c40b5..ab3c61eb 100644 --- a/src/main.js +++ b/src/main.js @@ -40,6 +40,8 @@ import '../css/contacts.scss' // Dialogs css import '@nextcloud/dialogs/style.css' +import { createPinia, PiniaVuePlugin } from 'pinia' + // CSP config for webpack dynamic chunk loading // eslint-disable-next-line __webpack_nonce__ = btoa(getRequestToken()) @@ -51,6 +53,9 @@ __webpack_nonce__ = btoa(getRequestToken()) // eslint-disable-next-line __webpack_public_path__ = generateFilePath('contacts', '', 'js/') +Vue.use(PiniaVuePlugin) +const pinia = createPinia() + // Register global directives Vue.directive('ClickOutside', ClickOutside) Vue.directive('Tooltip', VTooltip) @@ -81,4 +86,5 @@ export default new Vue({ router, store, render: h => h(App), + pinia, }) diff --git a/src/store/principals.js b/src/store/principals.js new file mode 100644 index 00000000..1523dd6f --- /dev/null +++ b/src/store/principals.js @@ -0,0 +1,34 @@ +/** + * @copyright Copyright (c) 2024 Grigory Vodyanov <scratchx@gmx.com> + * + * @author Grigory Vodyanov <scratchx@gmx.com> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +import { defineStore } from 'pinia' + +export default defineStore('principals', { + state: () => ({ + currentUserPrincipal: null, + }), + actions: { + setCurrentUserPrincipal(client) { + this.currentUserPrincipal = client?.currentUserPrincipal + }, + }, +}) diff --git a/src/views/Contacts.vue b/src/views/Contacts.vue index 01981f66..9d52e130 100644 --- a/src/views/Contacts.vue +++ b/src/views/Contacts.vue @@ -96,6 +96,8 @@ import rfcProps from '../models/rfcProps.js' import client from '../services/cdav.js' import isCirclesEnabled from '../services/isCirclesEnabled.js' +import usePrincipalsStore from '../store/principals.js' + export default { name: 'Contacts', @@ -250,6 +252,8 @@ export default { // get addressbooks then get contacts client.connect({ enableCardDAV: true }).then(() => { this.logger.debug('Connected to dav!', { client }) + const principalsStore = usePrincipalsStore() + principalsStore.setCurrentUserPrincipal(client) this.$store.dispatch('getAddressbooks') .then((addressbooks) => { const writeableAddressBooks = addressbooks.filter(addressbook => !addressbook.readOnly) |