Skip to content

Commit

Permalink
feat: rename and delete groups
Browse files Browse the repository at this point in the history
Signed-off-by: Grigory Vodyanov <[email protected]>

feat: delete groups

Signed-off-by: Grigory Vodyanov <[email protected]>
  • Loading branch information
GVodyanov committed Jun 10, 2024
1 parent 6529247 commit 88d9e72
Show file tree
Hide file tree
Showing 5 changed files with 167 additions and 3 deletions.
75 changes: 75 additions & 0 deletions src/components/AppNavigation/GroupNavigationItem.vue
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@
</template>
{{ t('contacts', 'Add contacts') }}
</ActionButton>
<ActionInput @submit="renameGroup" :value.sync="newGroupName">

Check warning on line 26 in src/components/AppNavigation/GroupNavigationItem.vue

View workflow job for this annotation

GitHub Actions / NPM lint

Attribute ":value.sync" should go before "@submit"
<template #icon>
<IconRename :size="20" />
</template>
{{ t('contacts', 'Rename') }}
</ActionInput>
<ActionButton :close-after-click="true"
@click="downloadGroup(group)">
<template #icon>
Expand All @@ -42,6 +48,12 @@
</template>
{{ t('contacts', 'Send email as BCC') }}
</ActionButton>
<ActionButton @click="deleteGroup">
<template #icon>
<IconDelete :size="20" />
</template>
{{ t('contacts', 'Delete') }}
</ActionButton>
</template>

<template #counter>
Expand All @@ -57,16 +69,21 @@
import { emit } from '@nextcloud/event-bus'
import download from 'downloadjs'
import moment from 'moment'
import renameContactFromGroup from '../../services/renameContactFromGroup.js'
import removeContactFromGroup from '../../services/removeContactFromGroup.js'

import {
NcActionButton as ActionButton,
NcCounterBubble,
NcAppNavigationItem as AppNavigationItem,
NcActionInput as ActionInput,
} from '@nextcloud/vue'
import IconContact from 'vue-material-design-icons/AccountMultiple.vue'
import IconAdd from 'vue-material-design-icons/Plus.vue'
import IconDownload from 'vue-material-design-icons/Download.vue'
import IconEmail from 'vue-material-design-icons/Email.vue'
import IconRename from 'vue-material-design-icons/FolderEdit.vue'
import IconDelete from 'vue-material-design-icons/Delete.vue'
import { showError } from '@nextcloud/dialogs'

export default {
Expand All @@ -76,10 +93,19 @@ export default {
ActionButton,
NcCounterBubble,
AppNavigationItem,
ActionInput,
IconContact,
IconAdd,
IconDownload,
IconEmail,
IconRename,
IconDelete,
},

data() {
return {
newGroupName: '',
}
},

props: {

Check warning on line 111 in src/components/AppNavigation/GroupNavigationItem.vue

View workflow job for this annotation

GitHub Actions / NPM lint

The "props" property should be above the "data" property on line 105
Expand Down Expand Up @@ -219,6 +245,55 @@ export default {
window.location.href = `mailto:?${mode}=${emails.map(encodeURIComponent).join(',')}`
},

/**
* Rename group in store and on server
*/
renameGroup() {
if (this.newGroupName === '') {
return
}

this.group.contacts.forEach(async (key) => {
const contact = this.$store.getters.getContact(key)

if (contact === undefined) {
return
}

try {
await renameContactFromGroup(contact, this.group.name, this.newGroupName)
} catch (e) {
console.error('Error renaming group', e)
}
})

this.$store.commit('renameGroup', {
oldGroupName: this.group.name,
newGroupName: this.newGroupName,
})
},

/**
* Delete group from store and on server
*/
deleteGroup() {
this.group.contacts.forEach(async (key) => {
const contact = this.$store.getters.getContact(key)

if (contact === undefined) {
return
}

try {
await removeContactFromGroup(contact, this.group.name)
} catch (e) {
console.error('Error deleting group', e)
}
})

this.$store.commit('removeGroup', this.group.name)
},

},
}
</script>
Expand Down
28 changes: 28 additions & 0 deletions src/services/removeContactFromGroup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/**
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
import axios from '@nextcloud/axios'

/**
* Append a group to a contact
*
* @param {Contact} contact the contact model
* @param {string} groupName the group name
*/
const removeContactFromGroup = async function(contact, groupName) {
const foundGroups = contact.groups

let currentGroups = foundGroups.map(groupName => encodeURIComponent(groupName))

currentGroups = currentGroups.filter(e => e !== encodeURIComponent(groupName))

return axios.patch(contact.url, {}, {
headers: {
'X-PROPERTY': 'CATEGORIES',
'X-PROPERTY-REPLACE': currentGroups.join(','),
},
})
}

export default removeContactFromGroup
30 changes: 30 additions & 0 deletions src/services/renameContactFromGroup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/**
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
import axios from '@nextcloud/axios'

/**
* Append a group to a contact
*
* @param {Contact} contact the contact model
* @param {string} oldGroupName name that gets removed
* @param {string} newGroupName name that gets added
*/
const renameContactFromGroup = async function(contact, oldGroupName, newGroupName) {
const foundGroups = contact.groups
foundGroups.push(newGroupName)

let currentGroups = foundGroups.map(groupName => encodeURIComponent(groupName))

currentGroups = currentGroups.filter(e => e !== encodeURIComponent(oldGroupName))

return axios.patch(contact.url, {}, {
headers: {
'X-PROPERTY': 'CATEGORIES',
'X-PROPERTY-REPLACE': currentGroups.join(','),
},
})
}

export default renameContactFromGroup
1 change: 1 addition & 0 deletions src/store/contacts.js
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,7 @@ const mutations = {
* @param {object} state the store data
*/
sortContacts(state) {

state.sortedContacts = Object.values(state.contacts)
// exclude groups
.filter(contact => contact.kind !== 'group')
Expand Down
36 changes: 33 additions & 3 deletions src/store/groups.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,14 +66,34 @@ const mutations = {
* @param {string} data.groupName the name of the group
* @param {Contact} data.contact the contact
*/
removeContactToGroup(state, { groupName, contact }) {
removeContactFromGroup(state, { groupName, contact }) {
if (!state.groups.find(search => search.name === groupName)) {
return
}

const contacts = state.groups.find(search => search.name === groupName).contacts
const index = contacts.findIndex(search => search === contact.key)
if (index > -1) {
contacts.splice(index, 1)
}
},

/**
* Rename contact from group
*
* @param {object} state the store data
* @param {object} data destructuring object
* @param {string} data.oldGroupName name that gets removed
* @param {string} data.newGroupName name that gets added
*/
renameGroup(state, { oldGroupName, newGroupName }) {
state.groups.forEach((group) => {
if (group.name === oldGroupName) {
group.name = newGroupName
}
})
},

/**
* Remove contact from its groups
*
Expand Down Expand Up @@ -101,6 +121,16 @@ const mutations = {
contacts: [],
})
},

/**
* Remove a group
*
* @param {object} state the store data
* @param {string} groupName the name of the group
*/
removeGroup(state, groupName) {
state.groups = state.groups.filter(group => group.name !== groupName)
},
}

const getters = {
Expand Down Expand Up @@ -143,8 +173,8 @@ const actions = {
* @param {string} data.groupName the name of the group
* @param {Contact} data.contact the contact
*/
removeContactToGroup(context, { groupName, contact }) {
context.commit('removeContactToGroup', { groupName, contact })
removeContactFromGroup(context, { groupName, contact }) {
context.commit('removeContactFromGroup', { groupName, contact })
},

/**
Expand Down

0 comments on commit 88d9e72

Please sign in to comment.