diff options
author | John Molakvoæ (skjnldsv) <skjnldsv@protonmail.com> | 2018-11-10 10:06:01 +0100 |
---|---|---|
committer | John Molakvoæ (skjnldsv) <skjnldsv@protonmail.com> | 2018-11-12 22:38:05 +0100 |
commit | 6822a6d6c232ad138ffd866d54b7204938c222a1 (patch) | |
tree | 3d78ca6b013a19b3fa9b94ed09e7f5e10f719206 | |
parent | faf4e4adea598aafafd36265922e865d8afe260a (diff) |
Cleanup code with Property Mixin
Signed-off-by: John Molakvoæ (skjnldsv) <skjnldsv@protonmail.com>
-rw-r--r-- | css/ContactDetails.scss | 6 | ||||
-rw-r--r-- | css/Properties/Properties.scss | 28 | ||||
-rw-r--r-- | css/Settings/SettingsAddressbook.scss | 2 | ||||
-rw-r--r-- | css/icons.scss | 6 | ||||
-rw-r--r-- | img/address-book.svg | 2 | ||||
-rw-r--r-- | img/eye.svg | 2 | ||||
-rw-r--r-- | package.json | 2 | ||||
-rw-r--r-- | src/components/ContactDetails.vue | 47 | ||||
-rw-r--r-- | src/components/ContactDetails/ContactDetailsProperty.vue | 8 | ||||
-rw-r--r-- | src/components/Properties/PropertyDateTime.vue | 68 | ||||
-rw-r--r-- | src/components/Properties/PropertyGroups.vue | 25 | ||||
-rw-r--r-- | src/components/Properties/PropertyMultipleText.vue | 93 | ||||
-rw-r--r-- | src/components/Properties/PropertySelect.vue | 72 | ||||
-rw-r--r-- | src/components/Properties/PropertyText.vue | 75 | ||||
-rw-r--r-- | src/components/Settings/SettingsAddressbookShare.vue | 2 | ||||
-rw-r--r-- | src/mixins/PropertyMixin.js | 100 | ||||
-rw-r--r-- | src/services/api.js | 127 | ||||
-rw-r--r-- | webpack.common.js | 1 |
18 files changed, 231 insertions, 435 deletions
diff --git a/css/ContactDetails.scss b/css/ContactDetails.scss index dc8aaa87..451bb4da 100644 --- a/css/ContactDetails.scss +++ b/css/ContactDetails.scss @@ -78,6 +78,12 @@ padding: 14px; border-radius: 22px; cursor: pointer; + background-size: 16px; + opacity: .7; + &:hover, + &:focus { + opacity: 1; + } &.header-icon--pulse { margin: 8px; width: 16px; diff --git a/css/Properties/Properties.scss b/css/Properties/Properties.scss index 5add862b..817627c8 100644 --- a/css/Properties/Properties.scss +++ b/css/Properties/Properties.scss @@ -98,13 +98,21 @@ } // mouse feedback - &.multiselect { - &:hover, - &:focus, - &:active { - opacity: 1; - .multiselect__tags { - border-color: var(--color-border-dark); + &:hover, + &:focus, + &:active { + opacity: 1; + .multiselect__tags { + border-color: var(--color-border-dark); + } + } + + // read-only mode + &.multiselect--disabled { + &, .multiselect__single { + &, &:hover, &:focus &:active { + background-color: var(--color-main-background) !important; + border-color: transparent !important; } } } @@ -124,10 +132,16 @@ // property value within row, after label &__value { flex: 1 1; + textarea& { align-self: flex-start; min-height: 2 * $grid-height-unit - 2*$grid-input-margin; max-height: 5 * $grid-height-unit - 2*$grid-input-margin; } + + // read-only mode + &:read-only { + border-color: var(--color-border-dark); + } } } diff --git a/css/Settings/SettingsAddressbook.scss b/css/Settings/SettingsAddressbook.scss index 34d27e9e..e3c98ea0 100644 --- a/css/Settings/SettingsAddressbook.scss +++ b/css/Settings/SettingsAddressbook.scss @@ -59,4 +59,4 @@ &--disabled &__name { opacity: .5; } -}
\ No newline at end of file +} diff --git a/css/icons.scss b/css/icons.scss index e5b18450..00f390e9 100644 --- a/css/icons.scss +++ b/css/icons.scss @@ -26,4 +26,8 @@ .icon-address-book { @include icon-color('address-book', 'contacts', $color-black, 1); -}
\ No newline at end of file +} + +.icon-eye-white { + @include icon-color('eye', 'contacts', $color-white, 1); +} diff --git a/img/address-book.svg b/img/address-book.svg index 6be6e4ab..f026938b 100644 --- a/img/address-book.svg +++ b/img/address-book.svg @@ -1,2 +1,2 @@ <?xml version="1.0" encoding="utf-8"?> -<svg width="1792" height="1792" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path d="M1703 478q40 57 18 129l-275 906q-19 64-76.5 107.5t-122.5 43.5h-923q-77 0-148.5-53.5t-99.5-131.5q-24-67-2-127 0-4 3-27t4-37q1-8-3-21.5t-3-19.5q2-11 8-21t16.5-23.5 16.5-23.5q23-38 45-91.5t30-91.5q3-10 .5-30t-.5-28q3-11 17-28t17-23q21-36 42-92t25-90q1-9-2.5-32t.5-28q4-13 22-30.5t22-22.5q19-26 42.5-84.5t27.5-96.5q1-8-3-25.5t-2-26.5q2-8 9-18t18-23 17-21q8-12 16.5-30.5t15-35 16-36 19.5-32 26.5-23.5 36-11.5 47.5 5.5l-1 3q38-9 51-9h761q74 0 114 56t18 130l-274 906q-36 119-71.5 153.5t-128.5 34.5h-869q-27 0-38 15-11 16-1 43 24 70 144 70h923q29 0 56-15.5t35-41.5l300-987q7-22 5-57 38 15 59 43zm-1064 2q-4 13 2 22.5t20 9.5h608q13 0 25.5-9.5t16.5-22.5l21-64q4-13-2-22.5t-20-9.5h-608q-13 0-25.5 9.5t-16.5 22.5zm-83 256q-4 13 2 22.5t20 9.5h608q13 0 25.5-9.5t16.5-22.5l21-64q4-13-2-22.5t-20-9.5h-608q-13 0-25.5 9.5t-16.5 22.5z"/></svg>
\ No newline at end of file +<svg width="16" height="16" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path d="M1703 478q40 57 18 129l-275 906q-19 64-76.5 107.5t-122.5 43.5h-923q-77 0-148.5-53.5t-99.5-131.5q-24-67-2-127 0-4 3-27t4-37q1-8-3-21.5t-3-19.5q2-11 8-21t16.5-23.5 16.5-23.5q23-38 45-91.5t30-91.5q3-10 .5-30t-.5-28q3-11 17-28t17-23q21-36 42-92t25-90q1-9-2.5-32t.5-28q4-13 22-30.5t22-22.5q19-26 42.5-84.5t27.5-96.5q1-8-3-25.5t-2-26.5q2-8 9-18t18-23 17-21q8-12 16.5-30.5t15-35 16-36 19.5-32 26.5-23.5 36-11.5 47.5 5.5l-1 3q38-9 51-9h761q74 0 114 56t18 130l-274 906q-36 119-71.5 153.5t-128.5 34.5h-869q-27 0-38 15-11 16-1 43 24 70 144 70h923q29 0 56-15.5t35-41.5l300-987q7-22 5-57 38 15 59 43zm-1064 2q-4 13 2 22.5t20 9.5h608q13 0 25.5-9.5t16.5-22.5l21-64q4-13-2-22.5t-20-9.5h-608q-13 0-25.5 9.5t-16.5 22.5zm-83 256q-4 13 2 22.5t20 9.5h608q13 0 25.5-9.5t16.5-22.5l21-64q4-13-2-22.5t-20-9.5h-608q-13 0-25.5 9.5t-16.5 22.5z"/></svg>
\ No newline at end of file diff --git a/img/eye.svg b/img/eye.svg new file mode 100644 index 00000000..2aa0dd0a --- /dev/null +++ b/img/eye.svg @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8"?> +<svg width="16" height="16" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path d="M1664 960q-152-236-381-353 61 104 61 225 0 185-131.5 316.5t-316.5 131.5-316.5-131.5-131.5-316.5q0-121 61-225-229 117-381 353 133 205 333.5 326.5t434.5 121.5 434.5-121.5 333.5-326.5zm-720-384q0-20-14-34t-34-14q-125 0-214.5 89.5t-89.5 214.5q0 20 14 34t34 14 34-14 14-34q0-86 61-147t147-61q20 0 34-14t14-34zm848 384q0 34-20 69-140 230-376.5 368.5t-499.5 138.5-499.5-139-376.5-368q-20-35-20-69t20-69q140-229 376.5-368t499.5-139 499.5 139 376.5 368q20 35 20 69z"/></svg>
\ No newline at end of file diff --git a/package.json b/package.json index e78025d2..b92c0bd6 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,6 @@ }, "dependencies": { "@babel/polyfill": "^7.0.0", - "axios": "^0.18.0", "cdav-library": "github:nextcloud/cdav-library", "debounce": "^1.2.0", "ical.js": "^1.3.0", @@ -48,7 +47,6 @@ "vue": "^2.5.17", "vue-click-outside": "^1.0.7", "vue-clipboard2": "^0.2.1", - "vue-multiselect": "^2.1.3", "vue-router": "^3.0.1", "vuex": "^3.0.1", "vuex-router-sync": "^5.0.0" diff --git a/src/components/ContactDetails.vue b/src/components/ContactDetails.vue index 35c3487b..211fe45d 100644 --- a/src/components/ContactDetails.vue +++ b/src/components/ContactDetails.vue @@ -48,17 +48,17 @@ <!-- fullname, org, title --> <div id="contact-header-infos"> <h2> - <input id="contact-fullname" v-model="contact.fullName" :disabled="contact.addressbook.readOnly" + <input id="contact-fullname" v-model="contact.fullName" :readonly="contact.addressbook.readOnly" :placeholder="t('contacts', 'Name')" type="text" autocomplete="off" autocorrect="off" spellcheck="false" name="fullname" value="" @input="debounceUpdateContact"> </h2> <div id="details-org-container"> - <input id="contact-org" v-model="contact.org" :disabled="contact.addressbook.readOnly" + <input id="contact-org" v-model="contact.org" :readonly="contact.addressbook.readOnly" :placeholder="t('contacts', 'Company')" type="text" autocomplete="off" autocorrect="off" spellcheck="false" name="org" value="" @input="debounceUpdateContact"> - <input id="contact-title" v-model="contact.title" :disabled="contact.addressbook.readOnly" + <input id="contact-title" v-model="contact.title" :readonly="contact.addressbook.readOnly" :placeholder="t('contacts', 'Title')" type="text" autocomplete="off" autocorrect="off" spellcheck="false" name="title" value="" @input="debounceUpdateContact"> @@ -67,7 +67,13 @@ <!-- actions --> <div id="contact-header-actions"> - <div v-tooltip.bottom="warning" :class="{'icon-loading-small': loadingUpdate, 'header-icon--pulse icon-error-white': warning}" class="header-icon" /> + <a v-tooltip.bottom="{ + content: warning ? warning.msg : '', + trigger: 'hover focus' + }" + v-if="loadingUpdate || warning" + :class="{'icon-loading-small': loadingUpdate, + [`${warning.icon}`]: warning}" class="header-icon" href="#" /> <div v-tooltip="{ content: conflict, show: true, @@ -95,12 +101,15 @@ :sorted-properties="sortedProperties" :property="property" :contact="contact" @updatedcontact="updateContact" /> - <!-- addressbook change select - no last property because class is not applied here--> + <!-- 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 + we are hijacking this... (this is supposed to be used with a ICAL.property, but to avoid code + duplication, we created a fake propModel and property with our own options here) --> <property-select :prop-model="addressbookModel" :value.sync="addressbook" :is-first-property="true" - :is-last-property="false" class="property--addressbooks" /> + :is-last-property="false" :property="{}" class="property--addressbooks" /> <!-- new property select --> - <add-new-prop :contact="contact" /> + <add-new-prop v-if="!isReadOnly" :contact="contact" /> </section> </template> </div> @@ -155,27 +164,43 @@ export default { }, computed: { + isReadOnly() { + if (this.contact.addressbook) { + return this.contact.addressbook.readOnly + } + return false + }, /** - * Warning message + * Warning messages * - * @returns {string|undefined} + * @returns {Object|Boolean} */ warning() { if (!this.contact.dav) { - return t('contacts', 'This contact is not yet synced. Edit it to trigger a change.') + return { + icon: 'icon-error-white header-icon--pulse', + msg: t('contacts', 'This contact is not yet synced. Edit it to trigger a change.') + } + } else if (this.isReadOnly) { + return { + icon: 'icon-eye-white', + msg: t('contacts', 'This contact is in read-only mode. You do not have permission to edit this contact.') + } } + return false }, /** * Conflict message * - * @returns {string|undefined} + * @returns {String|Boolean} */ conflict() { if (this.contact.conflict) { return t('contacts', 'The contact you were trying to edit has changed. Please manually refresh the contact. Any further edits will be discarded.') } + return false }, /** diff --git a/src/components/ContactDetails/ContactDetailsProperty.vue b/src/components/ContactDetails/ContactDetailsProperty.vue index dca5a7d9..4191ef16 100644 --- a/src/components/ContactDetails/ContactDetailsProperty.vue +++ b/src/components/ContactDetails/ContactDetailsProperty.vue @@ -26,7 +26,7 @@ :prop-model="propModel" :value.sync="value" :is-first-property="isFirstProperty" :property="property" :is-last-property="isLastProperty" :class="{'property--last': isLastProperty}" :contact="contact" :prop-name="propName" :prop-type="propType" - :options="sortedModelOptions" + :options="sortedModelOptions" :is-read-only="isReadOnly" @delete="deleteProp" /> </template> @@ -109,6 +109,12 @@ export default { } return true }, + isReadOnly() { + if (this.contact.addressbook) { + return this.contact.addressbook.readOnly + } + return false + }, /** * Return the type of the prop e.g. FN diff --git a/src/components/Properties/PropertyDateTime.vue b/src/components/Properties/PropertyDateTime.vue index 4a68f594..13e9038f 100644 --- a/src/components/Properties/PropertyDateTime.vue +++ b/src/components/Properties/PropertyDateTime.vue @@ -30,8 +30,8 @@ <!-- type selector --> <multiselect v-if="propModel.options" v-model="localType" :options="options" :searchable="false" :placeholder="t('contacts', 'Select type')" - class="property__label" track-by="id" label="name" - @input="updateType" /> + :disabled="isReadOnly" class="property__label" track-by="id" + label="name" @input="updateType" /> <!-- if we do not support any type on our model but one is set anyway --> <div v-else-if="selectType" class="property__label">{{ selectType.name }}</div> @@ -40,12 +40,13 @@ <div v-else class="property__label">{{ propModel.readableName }}</div> <!-- delete the prop --> - <button :title="t('contacts', 'Delete')" class="property__delete icon-delete" @click="deleteProperty" /> + <button v-if="!isReadOnly" :title="t('contacts', 'Delete')" class="property__delete icon-delete" + @click="deleteProperty" /> <!-- Real input where the picker shows --> <datetime-picker :value="localValue.toJSDate()" :minute-step="10" :lang="lang" :clearable="false" :first-day-of-week="firstDay" :type="inputType" - confirm @confirm="updateValue" /> + :readonly="isReadOnly" confirm @confirm="updateValue" /> </div> </div> </template> @@ -56,6 +57,7 @@ import moment from 'moment' import { DatetimePicker } from 'nextcloud-vue' import { VCardTime } from 'ical.js' +import PropertyMixin from 'Mixins/PropertyMixin' import PropertyTitle from './PropertyTitle' /** @@ -137,45 +139,18 @@ export default { PropertyTitle }, + mixins: [PropertyMixin], + props: { - selectType: { - type: [Object, Boolean], - default: () => {} - }, - propModel: { - type: Object, - default: () => {}, - required: true - }, value: { type: VCardTime, default: '', required: true - }, - options: { - type: Array, - default: () => [] - }, - property: { - type: Object, - default: () => {}, - required: true - }, - isFirstProperty: { - type: Boolean, - default: true - }, - isLastProperty: { - type: Boolean, - default: true } }, data() { return { - localValue: this.value, - localType: this.selectType, - // input type following DatePicker docs inputType: this.property.getDefaultType() === 'date-time' || this.property.getDefaultType() === 'date-and-or-time' ? 'datetime' @@ -205,20 +180,6 @@ export default { } }, - watch: { - /** - * Since we're updating a local data based on the value prop, - * we need to make sure to update the local data on pop change - * TODO: check if this create performance drop - */ - value: function() { - this.localValue = this.value - }, - selectType: function() { - this.localType = this.selectType - } - }, - mounted() { // Load the locale // convert format like en_GB to en-gb for `moment.js` @@ -245,14 +206,6 @@ export default { }, methods: { - - /** - * Delete the property - */ - deleteProperty() { - this.$emit('delete') - }, - /** * Debounce and send update event to parent */ @@ -274,11 +227,6 @@ export default { // https://vuejs.org/v2/guide/components-custom-events.html#sync-Modifier // Use moment to convert the JsDate to Object this.$emit('update:value', this.localValue) - }, 500), - - updateType: debounce(function(e) { - // https://vuejs.org/v2/guide/components-custom-events.html#sync-Modifier - this.$emit('update:selectType', this.localType) }, 500) } } diff --git a/src/components/Properties/PropertyGroups.vue b/src/components/Properties/PropertyGroups.vue index b4de6185..15677320 100644 --- a/src/components/Properties/PropertyGroups.vue +++ b/src/components/Properties/PropertyGroups.vue @@ -29,9 +29,9 @@ <!-- multiselect taggable groups with a limit to 3 groups shown --> <multiselect v-model="localValue" :options="groups" :placeholder="t('contacts', 'Add contact in group')" :limit="3" :multiple="true" :taggable="true" - :close-on-select="false" tag-placeholder="create" class="property__value" - @input="updateValue" @tag="validateGroup" @select="addContactToGroup" - @remove="removeContactToGroup"> + :close-on-select="false" :readonly="isReadOnly" tag-placeholder="create" + class="property__value" @input="updateValue" @tag="validateGroup" + @select="addContactToGroup" @remove="removeContactToGroup"> <!-- show how many groups are hidden and add tooltip --> <span v-tooltip.auto="formatGroupsTitle" slot="limit" class="multiselect__limit">+{{ localValue.length - 3 }}</span> @@ -63,6 +63,11 @@ export default { type: Contact, default: null, required: true + }, + // Is it read-only? + isReadOnly: { + type: Boolean, + default: false } }, @@ -88,20 +93,6 @@ export default { } }, - watch: { - /** - * Since we're updating a local data based on the value prop, - * we need to make sure to update the local data on pop change - * TODO: check if this create performance drop - */ - value: function() { - this.localValue = this.value - }, - selectType: function() { - this.localType = this.selectType - } - }, - methods: { /** diff --git a/src/components/Properties/PropertyMultipleText.vue b/src/components/Properties/PropertyMultipleText.vue index 79386ba2..51a76bc9 100644 --- a/src/components/Properties/PropertyMultipleText.vue +++ b/src/components/Properties/PropertyMultipleText.vue @@ -30,8 +30,8 @@ <!-- type selector --> <multiselect v-if="propModel.options" v-model="localType" :options="options" :searchable="false" :placeholder="t('contacts', 'Select type')" - class="property__label" track-by="id" label="name" - @input="updateType" /> + :disabled="isReadOnly" class="property__label" track-by="id" + label="name" @input="updateType" /> <!-- if we do not support any type on our model but one is set anyway --> <div v-else-if="selectType" class="property__label">{{ selectType.name }}</div> @@ -40,19 +40,20 @@ <div v-else class="property__label">{{ propModel.readableName }}</div> <!-- show the first input if not --> - <input v-if="!property.isStructuredValue" v-model.trim="localValue[0]" class="property__value" - type="text" @input="updateValue"> + <input v-if="!property.isStructuredValue" v-model.trim="localValue[0]" :readonly="isReadOnly" + class="property__value" type="text" @input="updateValue"> <!-- delete the prop --> - <button :title="t('contacts', 'Delete')" class="property__delete icon-delete" @click="deleteProperty" /> + <button v-if="!isReadOnly" :title="t('contacts', 'Delete')" class="property__delete icon-delete" + @click="deleteProperty" /> </div> <!-- force order based on model --> <template v-if="propModel.displayOrder && propModel.readableValues"> <div v-for="index in propModel.displayOrder" :key="index" class="property__row"> <div class="property__label">{{ propModel.readableValues[index] }}</div> - <input v-model.trim="localValue[index]" class="property__value" type="text" - @input="updateValue"> + <input v-model.trim="localValue[index]" :readonly="isReadOnly" class="property__value" + type="text" @input="updateValue"> </div> </template> @@ -61,16 +62,16 @@ <div v-for="(value, index) in localValue" v-if="index > 0" :key="index" class="property__row"> <div class="property__label" /> - <input v-model.trim="localValue[index]" class="property__value" type="text" - @input="updateValue"> + <input v-model.trim="localValue[index]" :readonly="isReadOnly" class="property__value" + type="text" @input="updateValue"> </div> </template> </div> </template> <script> +import PropertyMixin from 'Mixins/PropertyMixin' import PropertyTitle from './PropertyTitle' -import debounce from 'debounce' export default { name: 'PropertyText', @@ -79,44 +80,13 @@ export default { PropertyTitle }, + mixins: [PropertyMixin], + props: { - selectType: { - type: [Object, Boolean], - default: () => {} - }, - propModel: { - type: Object, - default: () => {}, - required: true - }, value: { type: [Array, Object], default: () => [], required: true - }, - options: { - type: Array, - default: () => [] - }, - property: { - type: Object, - default: () => {}, - required: true - }, - isFirstProperty: { - type: Boolean, - default: true - }, - isLastProperty: { - type: Boolean, - default: true - } - }, - - data() { - return { - localValue: this.value, - localType: this.selectType } }, @@ -128,43 +98,6 @@ export default { let length = this.propModel.displayOrder ? this.propModel.displayOrder.length : this.value.length return hasValueNames + hasTitle + length + isLast } - }, - - watch: { - /** - * Since we're updating a local data based on the value prop, - * we need to make sure to update the local data on pop change - * TODO: check if this create performance drop - */ - value: function() { - this.localValue = this.value - }, - selectType: function() { - this.localType = this.selectType - } - }, - - methods: { - - /** - * Delete the property - */ - deleteProperty() { - this.$emit('delete') - }, - - /** - * Debounce and send update event to parent - */ - updateValue: debounce(function(e) { - // https://vuejs.org/v2/guide/components-custom-events.html#sync-Modifier - this.$emit('update:value', this.localValue) - }, 500), - - updateType: debounce(function(e) { - // https://vuejs.org/v2/guide/components-custom-events.html#sync-Modifier - this.$emit('update:selectType', this.localType) - }, 500) } } diff --git a/src/components/Properties/PropertySelect.vue b/src/components/Properties/PropertySelect.vue index 92508124..5c2b4d4b 100644 --- a/src/components/Properties/PropertySelect.vue +++ b/src/components/Properties/PropertySelect.vue @@ -35,18 +35,19 @@ <div v-else class="property__label">{{ propModel.readableName }}</div> <!-- delete the prop --> - <button :title="t('contacts', 'Delete')" class="property__delete icon-delete" @click="deleteProperty" /> + <button v-if="!isReadOnly" :title="t('contacts', 'Delete')" class="property__delete icon-delete" + @click="deleteProperty" /> <multiselect v-model="matchedOptions" :options="propModel.options" :placeholder="t('contacts', 'Select option')" - :disabled="isSingleOption" class="multiselect-vue property__value" track-by="id" + :disabled="isSingleOption || isReadOnly" class="multiselect-vue property__value" track-by="id" label="name" @input="updateValue" /> </div> </div> </template> <script> +import PropertyMixin from 'Mixins/PropertyMixin' import PropertyTitle from './PropertyTitle' -import debounce from 'debounce' export default { name: 'PropertySelect', @@ -55,36 +56,13 @@ export default { PropertyTitle }, + mixins: [PropertyMixin], + props: { - selectType: { - type: [Object, Boolean], - default: () => {} - }, - propModel: { - type: Object, - default: () => {}, - required: true - }, value: { type: [Object, String], default: '', required: true - }, - isFirstProperty: { - type: Boolean, - default: true - }, - isLastProperty: { - type: Boolean, - default: true - } - }, - - data() { - return { - // value is represented by the ID of the possible options - localValue: this.value - // localType: this.selectType } }, @@ -113,44 +91,6 @@ export default { this.localValue = value.id } } - - }, - - watch: { - /** - * Since we're updating a local data based on the value prop, - * we need to make sure to update the local data on pop change - * TODO: check if this create performance drop - */ - value: function() { - this.localValue = this.value - } - // selectType: function() { - // this.localType = this.selectType - // } - }, - - methods: { - - /** - * Delete the property - */ - deleteProperty() { - this.$emit('delete') - }, - - /** - * Debounce and send update event to parent - */ - updateValue: debounce(function(e) { - // https://vuejs.org/v2/guide/components-custom-events.html#sync-Modifier - this.$emit('update:value', this.localValue) - }, 500) - - // updateType: debounce(function(e) { - // // https://vuejs.org/v2/guide/components-custom-events.html#sync-Modifier - // this.$emit('update:selectType', this.localType) - // }, 500) } } diff --git a/src/components/Properties/PropertyText.vue b/src/components/Properties/PropertyText.vue index b67514f0..7c9fd99e 100644 --- a/src/components/Properties/PropertyText.vue +++ b/src/components/Properties/PropertyText.vue @@ -30,8 +30,8 @@ <!-- type selector --> <multiselect v-if="propModel.options" v-model="localType" :options="options" :searchable="false" :placeholder="t('contacts', 'Select type')" - class="property__label" track-by="id" label="name" - @input="updateType" /> + :disabled="isReadOnly" class="property__label" track-by="id" + label="name" @input="updateType" /> <!-- if we do not support any type on our model but one is set anyway --> <div v-else-if="selectType" class="property__label">{{ selectType.name }}</div> |