diff options
author | John Molakvoæ <skjnldsv@users.noreply.github.com> | 2018-09-04 16:37:53 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-09-04 16:37:53 +0200 |
commit | 36374d1691d9cf625c7ffd5e31e819d4bcb003cb (patch) | |
tree | 8a0b35fca2f4c7293c59bc5bcfc7d56bb961469c /src | |
parent | 1b12c5e5e57b74512e07482795c0502c589ab75d (diff) | |
parent | 55d202166d3a3d107e6c6bbab767f02b03134d21 (diff) |
Merge branch 'vue' into multiplevalues-fix
Diffstat (limited to 'src')
-rw-r--r-- | src/components/ContactDetails.vue | 13 | ||||
-rw-r--r-- | src/components/ContactDetails/ContactDetailsAddNewProp.vue | 82 | ||||
-rw-r--r-- | src/components/ContactDetails/ContactDetailsProperty.vue | 5 | ||||
-rw-r--r-- | src/models/contact.js | 6 | ||||
-rw-r--r-- | src/services/parseVcf.js | 10 | ||||
-rw-r--r-- | src/store/FakeName.vcf | 11 | ||||
-rw-r--r-- | src/store/groups.js | 28 |
7 files changed, 131 insertions, 24 deletions
diff --git a/src/components/ContactDetails.vue b/src/components/ContactDetails.vue index a15a6970..0b506716 100644 --- a/src/components/ContactDetails.vue +++ b/src/components/ContactDetails.vue @@ -83,13 +83,16 @@ <!-- properties iteration --> <!-- using contact.key in the key and index as key to avoid conflicts between similar data and exact key --> - <contact-details-property v-for="(property, index) in sortedProperties" :key="index+contact.key" :index="index" + <contact-property v-for="(property, index) in sortedProperties" :key="index+contact.key" :index="index" :sorted-properties="sortedProperties" :property="property" :contact="contact" @updatedcontact="updateContact" /> <!-- addressbook change select - no last property because class is not applied here--> <property-select :prop-model="addressbookModel" :value.sync="addressbook" :is-first-property="true" :is-last-property="false" :options="addressbooksOptions" class="property--addressbooks" /> + + <!-- new property select --> + <add-new-prop :contact="contact" /> </section> </template> </div> @@ -105,7 +108,8 @@ import Contact from '../models/contact' import rfcProps from '../models/rfcProps.js' import PopoverMenu from './core/popoverMenu' -import ContactDetailsProperty from './ContactDetails/ContactDetailsProperty' +import ContactProperty from './ContactDetails/ContactDetailsProperty' +import AddNewProp from './ContactDetails/ContactDetailsAddNewProp' import PropertySelect from './Properties/PropertySelect' import PropertyGroups from './Properties/PropertyGroups' @@ -116,9 +120,10 @@ export default { components: { PopoverMenu, - ContactDetailsProperty, + ContactProperty, PropertySelect, - PropertyGroups + PropertyGroups, + AddNewProp }, directives: { diff --git a/src/components/ContactDetails/ContactDetailsAddNewProp.vue b/src/components/ContactDetails/ContactDetailsAddNewProp.vue new file mode 100644 index 00000000..5d87ceab --- /dev/null +++ b/src/components/ContactDetails/ContactDetailsAddNewProp.vue @@ -0,0 +1,82 @@ +<!-- + - @copyright Copyright (c) 2018 John Molakvoæ <skjnldsv@protonmail.com> + - + - @author John Molakvoæ <skjnldsv@protonmail.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/>. + - + --> + +<template> + <div class="grid-span-2 property"> + + <!-- title --> + <property-title :icon="'icon-add'" :readable-name="t('contacts', 'Add new property')" /> + + <div class="property__row"> + <div class="property__label" /> + + <!-- type selector --> + <multiselect :options="availableProperties" :placeholder="t('contacts', 'Choose property type')" class="multiselect-vue property__value" + track-by="id" label="name" @input="addProp" /> + </div> + </div> +</template> + +<script> +import rfcProps from '../../models/rfcProps.js' +import Contact from '../../models/contact' +import propertyTitle from '../Properties/PropertyTitle' + +import Multiselect from 'vue-multiselect' + +export default { + name: 'ContactDetailsAddNewProp', + + components: { + propertyTitle, + Multiselect + }, + + props: { + contact: { + type: Contact, + default: null + } + }, + + computed: { + availableProperties() { + return Object.keys(rfcProps.properties).map(key => { + return { + id: key, + name: rfcProps.properties[key].readableName + } + }) + } + }, + + methods: { + addProp({ id }) { + let defaultData = rfcProps.properties[id].defaultValue + let property = this.contact.vCard.addPropertyWithValue(id, defaultData ? defaultData.value : '') + if (defaultData && defaultData.type) { + property.setParameter('type', defaultData.type) + } + } + } +} +</script> diff --git a/src/components/ContactDetails/ContactDetailsProperty.vue b/src/components/ContactDetails/ContactDetailsProperty.vue index fc58dbb6..dd352517 100644 --- a/src/components/ContactDetails/ContactDetailsProperty.vue +++ b/src/components/ContactDetails/ContactDetailsProperty.vue @@ -218,8 +218,11 @@ export default { }, methods: { + /** + * Delete this property + */ deleteProp() { - alert('deleted') + this.contact.vCard.removeProperty(this.property) } } diff --git a/src/models/contact.js b/src/models/contact.js index e5e9e83e..438b1f22 100644 --- a/src/models/contact.js +++ b/src/models/contact.js @@ -120,9 +120,9 @@ export default class Contact { * @memberof Contact */ get groups() { - let prop = this.vCard.getFirstProperty('categories') - if (prop) { - return this.vCard.getFirstProperty('categories').getValues() + let groupsProp = this.vCard.getFirstProperty('categories') + if (groupsProp) { + return groupsProp.getValues() } return [] } diff --git a/src/services/parseVcf.js b/src/services/parseVcf.js index e74b083f..65d5f95c 100644 --- a/src/services/parseVcf.js +++ b/src/services/parseVcf.js @@ -35,17 +35,19 @@ export default function parseVcf(data = '', addressbook) { importState.total = vCards.length - return vCards.map(vCard => { + // Not using map because we want to only push valid contacts + // map force to return at least undefined + return vCards.reduce((contacts, vCard) => { try { // console.log(vCards.indexOf(vCard)) let contact = new Contact(vCard, addressbook) importState.accepted++ - return contact + contacts.push(contact) } catch (e) { // Parse error! Do not stop here... importState.denied++ - // eslint-disable-next-line console.error(e) } - }) + return contacts + }, []) } diff --git a/src/store/FakeName.vcf b/src/store/FakeName.vcf index 9dd899b0..98a1ee92 100644 --- a/src/store/FakeName.vcf +++ b/src/store/FakeName.vcf @@ -10,6 +10,17 @@ UID:5acf667e-1cbf-48a8-87fe-546ee31a0b23 END:VCARD BEGIN:VCARD +VERSION:2.1 +FN:Jean Dupont +N:Dupont;Jean +ADR;WORK;PREF;QUOTED-PRINTABLE:;Bruxelles 1200=Belgique;6A Rue Th. Decuyper +LABEL;QUOTED-PRINTABLE;WORK;PREF:Rue Th. Decuyper 6A=Bruxelles 1200=Belgique +TEL;CELL:+1234 56789 +EMAIL;INTERNET:jean.dupont@example.com +UID:dfs541fds15 +END:VCARD + +BEGIN:VCARD VERSION:4.0 KIND:org FN:ABC Marketing ORG diff --git a/src/store/groups.js b/src/store/groups.js index 9c3061be..e1ed9721 100644 --- a/src/store/groups.js +++ b/src/store/groups.js @@ -35,18 +35,22 @@ const mutations = { appendGroupsFromContacts(state, contacts) { // init groups list let groups = Object.values(contacts) - .map(contact => contact.groups.map(group => { - // extend group to model - return { - name: group, - contacts: [] - } - })[0]) - // ensure we only have one group of each - state.groups = state.groups.concat(groups) - .filter(function(group, index, self) { - return group && self.findIndex(search => search && search.name === group.name) === index - }) + // iterate on every contacts + .reduce((groups, contact) => { + // transform group names into Object + contact.groups.map(groupName => { + // overriding existing groups: remove duplicates + groups[groupName] = { + name: groupName, + contacts: [] + } + }) + return groups + }, {}) + + // store in state + state.groups = Object.values(groups) + // append keys to groups Object.values(contacts) .forEach(contact => { |