Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Properly format displayName and fields validation #880

Merged
merged 2 commits into from
Jan 25, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ module.exports = {
'no-tabs': 0,
'vue/html-indent': ['error', 'tab'],
// only debug console
'no-console': ['error', { allow: ['error', 'warn', 'debug'] }],
'no-console': ['error', { allow: ['error', 'warn', 'info', 'debug'] }],
skjnldsv marked this conversation as resolved.
Show resolved Hide resolved
// classes blocks
'padded-blocks': ['error', { classes: 'always' }],
// always have the operator in front
Expand Down
54 changes: 41 additions & 13 deletions src/models/contact.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
import uuid from 'uuid'
import ICAL from 'ical.js'

import store from '../store'

export default class Contact {

/**
Expand Down Expand Up @@ -52,7 +54,7 @@ export default class Contact {

// if no uid set, create one
if (!this.vCard.hasProperty('uid')) {
console.debug('This contact did not have a proper uid. Setting a new one for ', this)
console.info('This contact did not have a proper uid. Setting a new one for ', this)
this.vCard.addPropertyWithValue('uid', uuid())
}
}
Expand Down Expand Up @@ -271,25 +273,51 @@ export default class Contact {
}

/**
* Return the display name
* Formatted display name based on the order key
*
* @readonly
* @memberof Contact
* @returns {string} the displayName
*/
get displayName() {
if (this.vCard.hasProperty('fn')) {
return this.vCard.getFirstPropertyValue('fn')
const orderKey = store.getters.getOrderKey
const n = this.vCard.getFirstPropertyValue('n')
const fn = this.vCard.getFirstPropertyValue('fn')
const org = this.vCard.getFirstPropertyValue('org')

// if ordered by last or first name we need the N property
// ! by checking the property we check for null AND empty string
// ! that means we can then check for empty array and be safe not to have
// ! 'xxxx'.join('') !== ''
if (orderKey && n && n.join('') !== '') {
switch (orderKey) {
case 'firstName':
// Stevenson;John;Philip,Paul;Dr.;Jr.,M.D.,A.C.P.
// -> John Stevenson
return n.slice(0, 2).reverse().join(' ')

case 'lastName':
// Stevenson;John;Philip,Paul;Dr.;Jr.,M.D.,A.C.P.
// -> Stevenson, John
return n.slice(0, 2).join(', ')
}
}
if (this.vCard.hasProperty('n')) {
// reverse and join
return this.vCard.getFirstPropertyValue('n')
.filter(function(part) {
return part
})
.join(' ')
// otherwise the FN is enough
if (fn) {
return fn
}
return null
// BUT if no FN property use the N anyway
if (n && n.join('') !== '') {
// Stevenson;John;Philip,Paul;Dr.;Jr.,M.D.,A.C.P.
// -> John Stevenson
return n.slice(0, 2).reverse().join(' ')
}
// LAST chance, use the org ir that's the only thing we have
if (org && org.join('') !== '') {
// org is supposed to be an array but is also used as plain string
return Array.isArray(org) ? org[0] : org
}
return ''

}

/**
Expand Down
27 changes: 27 additions & 0 deletions src/services/checks/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/**
* @copyright Copyright (c) 2019 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/>.
*
*/

import missingFN from './missingFN'

export default [
missingFN
]
49 changes: 49 additions & 0 deletions src/services/checks/missingFN.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/**
* @copyright Copyright (c) 2019 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/>.
*
*/

/**
* the FN field is mandatory. If there is none we need to
* create it based on the available data
*/
export default {
name: 'missing FN',
run: contact => {
return !contact.vCard.hasProperty('fn') // No FN
|| contact.vCard.getFirstPropertyValue('fn') === '' // Empty FN
},
fix: contact => {
if (contact.vCard.hasProperty('n')) {
// Stevenson;John;Philip,Paul;Dr.;Jr.,M.D.,A.C.P.
// -> John Stevenson
const n = contact.vCard.getFirstPropertyValue('n')
contact.fullName = n.slice(0, 2).reverse().join(' ')
return true
} else if (contact.vCard.hasProperty('org')) {
const org = contact.vCard.getFirstPropertyValue('org')
// ABC, Inc.;North American Division;Marketing
// -> ABC, Inc.
contact.fullName = org[0]
return true
}
return false
}
}
2 changes: 1 addition & 1 deletion src/services/parseVcf.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export default function parseVcf(data = '', addressbook) {
let vCards = data.match(regexp)

if (!vCards) {
console.debug('Error during the parsing of the following vcf file: ', data)
console.error('Error during the parsing of the following vcf file: ', data)
return []
}

Expand Down
47 changes: 47 additions & 0 deletions src/services/validate.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/**
* @copyright Copyright (c) 2019 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/>.
*
*/

import Contact from '../models/contact'
import checks from './checks/'

export default function(contact) {
if (contact instanceof Contact) {

// Going through every checks
checks.forEach(check => {
if (check.run(contact)) {

// A fix is needed, running ⏳
if (!check.fix(contact)) {
// FAILURE 🙅
console.warn('The following contact needed a correction that failed:', check.name, contact)
} else {
// SUCCESS 💪
console.info('The following contact has been repaired:', check.name, contact)
}
}
})

} else {
throw new Error('Invalid contact provided')
}
}
2 changes: 1 addition & 1 deletion src/store/addressbooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ const mutations = {
// convert list into an array and remove duplicate
addressbook.contacts = contacts.reduce((list, contact) => {
if (list[contact.uid]) {
console.debug('Duplicate contact overrided', list[contact.uid], contact)
console.info('Duplicate contact overrided', list[contact.uid], contact)
}
Vue.set(list, contact.uid, contact)
return list
Expand Down
4 changes: 4 additions & 0 deletions src/store/contacts.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import Vue from 'vue'
import ICAL from 'ical.js'
import Contact from '../models/contact'
import validate from '../services/validate'

const state = {
// Using objects for performance
Expand Down Expand Up @@ -78,6 +79,9 @@ const mutations = {
addContact(state, contact) {
if (contact instanceof Contact) {

// Checking contact validity 🙈
validate(contact)

let sortedContact = {
key: contact.key,
value: contact[state.orderKey]
Expand Down
1 change: 1 addition & 0 deletions src/views/Contacts.vue
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,7 @@ export default {
})
} catch (error) {
OC.Notification.showTemporary(t('contacts', 'Unable to create the contact.'))
console.error(error)
}
},

Expand Down