Skip to content

Commit

Permalink
Merge pull request #898 from nextcloud/populate-FN-if-unchanged
Browse files Browse the repository at this point in the history
Add property-defined actions and populate FN if unchanged or empty
  • Loading branch information
skjnldsv authored Jan 30, 2019
2 parents a338c12 + 41e8ec1 commit 91c02d8
Show file tree
Hide file tree
Showing 21 changed files with 148 additions and 78 deletions.
41 changes: 21 additions & 20 deletions css/Properties/Properties.scss
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ $property-value-max-width: 250px;
.property {
@include generate-grid-span(1);
position: relative;
padding-right: 44px; // delete button
// we need this to keep the alignment of the ext and delete button
padding-right: 44px; // actions menu / button
// we need this to keep the alignment of the ext and delete/action button
// The flex grow will never go over those values. Therefore we can set
// the max width and keep the right alignment
max-width: $property-label-max-width + $property-value-max-width + 44px;
Expand All @@ -37,8 +37,8 @@ $property-value-max-width: 250px;
&--last {
margin-bottom: $grid-height-unit;
}
// no delete icon on addressbook selector
&--addressbooks &__delete {
// no delete/action icon on addressbook selector
&--addressbooks &__actions {
display: none !important;
}

Expand Down Expand Up @@ -132,17 +132,15 @@ $property-value-max-width: 250px;
&:hover,
&:focus,
&:active {
~ .property__ext,
~ .property__delete {
~ .property__ext {
opacity: .5;
}
}
}
}

// show ext & delete button on full row hover
&:hover &__ext,
&:hover &__delete {
// show ext button on full row hover
&:hover &__ext{
opacity: .5;
}

Expand All @@ -156,28 +154,31 @@ $property-value-max-width: 250px;
&:focus,
&:active {
opacity: .7;
// still show the delete button for keyboard accessibility
~ .property__delete {
opacity: .5;
}
}
}

// Delete property button
&__delete {
position: absolute;
// Delete property button + actions
&__actions {
position: absolute !important;
top: 0;
left: 100%;
width: $grid-height-unit;
height: $grid-height-unit;
margin: 0;
margin-top: -3px; // align with line because of the 44x44px size
border: 0;
background-color: transparent;
opacity: 0;
z-index: 10;
// opacity applies on the single action OR
&:not(.action-item--multiple),
&.action-item--multiple .icon-more {
opacity: 0.5;
}
&:hover,
&:active,
&:focus {
opacity: .7;
&:not(.action-item--multiple),
&.action-item--multiple .icon-more {
opacity: 0.7;
}
}
}
}
4 changes: 4 additions & 0 deletions css/icons.scss
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,7 @@
.icon-eye-white {
@include icon-color('eye', 'contacts', $color-white, 1);
}

.icon-up {
@include icon-color('up', 'contacts', $color-black, 1);
}
3 changes: 3 additions & 0 deletions img/up.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion src/components/ContactDetails.vue
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,11 @@
<section v-else class="contact-details">
<!-- properties iteration -->
<!-- using contact.key in the key and index as key to avoid conflicts between similar data and exact key -->
<!-- passing the debounceUpdateContact so that the contact-property component contains the function
and allow us to use it on the rfcProps since the scope is forwarded to the actions -->
<contact-property v-for="(property, index) in sortedProperties" :key="`${index}-${contact.key}-${property.name}`" :index="index"
:sorted-properties="sortedProperties" :property="property" :contact="contact"
@updatedcontact="debounceUpdateContact" />
:update-contact="debounceUpdateContact" @updatedcontact="debounceUpdateContact" />

<!-- addressbook change select - no last property because class is not applied here,
empty property because this is a required prop on regular property-select. But since
Expand Down
17 changes: 13 additions & 4 deletions src/components/ContactDetails/ContactDetailsAddNewProp.vue
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,15 @@ export default {
},

computed: {

/**
* Rfc props scoped
* @returns {Object}
*/
properties() {
return rfcProps.properties(this)
},

/**
* List of properties that the contact already have
*
Expand All @@ -71,14 +80,14 @@ export default {
* @returns {Object[]}
*/
availableProperties() {
return Object.keys(rfcProps.properties)
return Object.keys(this.properties)
// only allow to add multiple properties OR props that are not yet in the contact
.filter(key => rfcProps.properties[key].multiple || this.usedProperties.indexOf(key) === -1)
.filter(key => this.properties[key].multiple || this.usedProperties.indexOf(key) === -1)
// usable array of objects
.map(key => {
return {
id: key,
name: rfcProps.properties[key].readableName
name: this.properties[key].readableName
}
}).sort((a, b) => a.name.localeCompare(b.name))
}
Expand All @@ -92,7 +101,7 @@ export default {
* @param {string} data.id the id of the property. e.g fn
*/
addProp({ id }) {
let defaultData = rfcProps.properties[id].defaultValue
let defaultData = this.properties[id].defaultValue
let property = this.contact.vCard.addPropertyWithValue(id, defaultData ? defaultData.value : '')
if (defaultData && defaultData.type) {
property.setParameter('type', defaultData.type)
Expand Down
12 changes: 6 additions & 6 deletions src/components/ContactDetails/ContactDetailsAvatar.vue
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
<!--
import rfcProps from '../../models/rfcProps';
* @copyright Copyright (c) 2018 Team Popcorn <teampopcornberlin@gmail.com>
*
* @author Team Popcorn <teampopcornberlin@gmail.com>
*
* @license GNU AGPL version 3 or any later version
- @copyright Copyright (c) 2018 Team Popcorn <teampopcornberlin@gmail.com>
-
- @author Team Popcorn <teampopcornberlin@gmail.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
Expand Down
12 changes: 11 additions & 1 deletion src/components/ContactDetails/ContactDetailsProperty.vue
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,14 @@ export default {
contact: {
type: Contact,
default: null
},
/**
* This is needed so that we can update
* the contact within the rfcProps actions
*/
updateContact: {
type: Function,
default: () => {}
}
},

Expand All @@ -81,8 +89,10 @@ export default {
},

// rfc properties list
// passing this to properties to allow us to scope the properties object
// this make possible defining actions there
properties() {
return rfcProps.properties
return rfcProps.properties(this)
},
fieldOrder() {
return rfcProps.fieldOrder
Expand Down
2 changes: 1 addition & 1 deletion src/components/ContactsList/ContactsListItem.vue
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ export default {
* @returns {boolean}
*/
matchSearch() {
if (this.searchQuery !== '') {
if (this.searchQuery.trim() !== '') {
return this.contact.searchData.toString().toLowerCase().search(this.searchQuery.toLowerCase()) !== -1
}
return true
Expand Down
5 changes: 2 additions & 3 deletions src/components/Properties/PropertyDateTime.vue
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,8 @@
{{ propModel.readableName }}
</div>

<!-- delete the prop -->
<button v-if="!isReadOnly" :title="t('contacts', 'Delete')" class="property__delete icon-delete"
@click="deleteProperty" />
<!-- props actions -->
<action :actions="actions" class="property__actions" />

<!-- Real input where the picker shows -->
<datetime-picker :value="localValue.toJSDate()" :minute-step="10" :lang="lang"
Expand Down
5 changes: 2 additions & 3 deletions src/components/Properties/PropertyMultipleText.vue
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,8 @@
<input v-if="!property.isStructuredValue" v-model.trim="localValue[0]" :readonly="isReadOnly"
class="property__value" type="text" @input="updateValue">

<!-- delete the prop -->
<button v-if="!isReadOnly" :title="t('contacts', 'Delete')" class="property__delete icon-delete"
@click="deleteProperty" />
<!-- props actions -->
<action :actions="actions" class="property__actions" />
</div>

<!-- force order based on model -->
Expand Down
5 changes: 2 additions & 3 deletions src/components/Properties/PropertySelect.vue
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,8 @@
{{ propModel.readableName }}
</div>

<!-- delete the prop -->
<button v-if="!isReadOnly" :title="t('contacts', 'Delete')" class="property__delete icon-delete"
@click="deleteProperty" />
<!-- props actions -->
<action :actions="actions" class="property__actions" />

<multiselect v-model="matchedOptions" :options="propModel.options" :placeholder="t('contacts', 'Select option')"
:disabled="isSingleOption || isReadOnly" class="property__value" track-by="id"
Expand Down
13 changes: 3 additions & 10 deletions src/components/Properties/PropertyText.vue
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,8 @@
<a v-if="haveExtHandler" :href="externalHandler" class="property__ext icon-external"
target="_blank" />

<!-- delete the prop -->
<button v-if="!isReadOnly" :title="t('contacts', 'Delete')" class="property__delete icon-delete"
@click="deleteProperty" />
<!-- props actions -->
<action :actions="actions" class="property__actions" />
</div>
</div>
</template>
Expand Down Expand Up @@ -148,7 +147,7 @@ export default {
},

haveExtHandler() {
return this.externalHandler !== '' && this.value && this.value.length > 0
return this.externalHandler.trim() !== '' && this.value && this.value.length > 0
}
},

Expand All @@ -157,12 +156,6 @@ export default {
},

methods: {
/**
* Delete the property
*/
deleteProperty() {
this.$emit('delete')
},

/**
* Watch textarea resize and update the gridSize accordingly
Expand Down
3 changes: 2 additions & 1 deletion src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import { sync } from 'vuex-router-sync'
import { generateFilePath } from 'nextcloud-server/dist/router'

/** GLOBAL COMPONENTS AND DIRECTIVE */
import { AppNavigation, DatetimePicker, Multiselect, PopoverMenu } from 'nextcloud-vue'
import { Action, AppNavigation, DatetimePicker, Multiselect, PopoverMenu } from 'nextcloud-vue'
import ClickOutside from 'vue-click-outside'
import { VTooltip } from 'v-tooltip'
import VueClipboard from 'vue-clipboard2'
Expand All @@ -43,6 +43,7 @@ __webpack_nonce__ = btoa(OC.requestToken)
// eslint-disable-next-line
__webpack_public_path__ = generateFilePath('contacts', '', 'js/')

Vue.component('Action', Action)
Vue.component('AppNavigation', AppNavigation)
Vue.component('DatetimePicker', DatetimePicker)
Vue.component('Multiselect', Multiselect)
Expand Down
13 changes: 12 additions & 1 deletion src/mixins/PropertyMixin.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export default {
type: [Object],
default: () => {}
},
// Coming fro the rfcProps Model
// Coming from the rfcProps Model
propModel: {
type: Object,
default: () => {},
Expand Down Expand Up @@ -76,6 +76,17 @@ export default {
}
},

computed: {
actions() {
const del = {
text: t('contacts', 'Delete'),
icon: 'icon-delete',
action: this.deleteProperty
}
return [...this.propModel.actions ? this.propModel.actions : [], del]
}
},

watch: {
/**
* Since we're updating a local data based on the value prop,
Expand Down
2 changes: 1 addition & 1 deletion src/models/contact.js
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ export default class Contact {
let groupsProp = this.vCard.getFirstProperty('categories')
if (groupsProp) {
return groupsProp.getValues()
.filter(group => group !== '')
.filter(group => group.trim() !== '')
}
return []
}
Expand Down
23 changes: 20 additions & 3 deletions src/models/rfcProps.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,17 @@
*/
import { VCardTime } from 'ical.js'

const properties = {
const copyNtoFN = ({ contact, updateContact }) => () => {
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(' ')
updateContact()
}
}

const properties = component => ({
nickname: {
readableName: t('contacts', 'Nickname'),
icon: 'icon-user'
Expand All @@ -39,7 +49,14 @@ const properties = {
defaultValue: {
value: ['', '', '', '', '']
},
icon: 'icon-user'
icon: 'icon-user',
actions: [
{
text: t('contacts', 'Copy to full name'),
icon: 'icon-up',
action: copyNtoFN(component)
}
]
},
note: {
readableName: t('contacts', 'Notes'),
Expand Down Expand Up @@ -266,7 +283,7 @@ const properties = {
{ id: 'O', name: t('contacts', 'Other') }
]
}
}
})

const fieldOrder = [
'org',
Expand Down
Loading

0 comments on commit 91c02d8

Please sign in to comment.