diff options
author | John Molakvoæ <skjnldsv@users.noreply.github.com> | 2018-11-09 19:18:47 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-11-09 19:18:47 +0100 |
commit | 1bfdf08c66254857178606006e8e2611a831f0f0 (patch) | |
tree | f2f6d227624ded0e1787a80dceb68f82d46a2130 | |
parent | 38ea18f362d5c506582cfa715f30789fb85beae3 (diff) | |
parent | 5729951b251f2ffd4471ed0c92c77fbfe8d4c61a (diff) |
Merge pull request #704 from nextcloud/disabled-ab-should-not-be-suggested
Disabled ab should not be suggested
-rw-r--r-- | .travis.yml | 1 | ||||
-rw-r--r-- | css/Properties/Properties.scss | 14 | ||||
-rw-r--r-- | css/Settings/SettingsAddressbook.scss | 1 | ||||
-rw-r--r-- | css/Settings/SettingsAddressbookSharee.scss | 5 | ||||
-rw-r--r-- | css/Settings/SettingsAddressbookShares.scss | 3 | ||||
-rw-r--r-- | css/SettingsSection.scss | 41 | ||||
-rw-r--r-- | css/icons.scss | 4 | ||||
-rw-r--r-- | img/address-book.svg | 2 | ||||
-rw-r--r-- | src/components/ContactDetails.vue | 4 | ||||
-rw-r--r-- | src/components/Properties/PropertySelect.vue | 8 | ||||
-rw-r--r-- | src/components/Settings/SettingsAddressbook.vue | 30 | ||||
-rw-r--r-- | src/components/Settings/SettingsImportContacts.vue | 50 | ||||
-rw-r--r-- | src/components/Settings/SettingsSortContacts.vue | 21 | ||||
-rw-r--r-- | src/main.js | 16 | ||||
-rw-r--r-- | webpack.common.js | 6 |
15 files changed, 122 insertions, 84 deletions
diff --git a/.travis.yml b/.travis.yml index 86d38e93..25b6e682 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,3 +8,4 @@ script: - npm run build - npm run lint - npm run stylelint +- npm run test diff --git a/css/Properties/Properties.scss b/css/Properties/Properties.scss index 8ca4bf90..5add862b 100644 --- a/css/Properties/Properties.scss +++ b/css/Properties/Properties.scss @@ -71,7 +71,7 @@ // property label or multiselect within row &__label, - &__label.multiselect { + &__label.multiselect.multiselect-vue { margin: $grid-input-margin; margin: $grid-input-margin 5px $grid-input-margin 0; height: $grid-input-height-with-margin; @@ -81,6 +81,10 @@ user-select: none; background-size: 16px; + .multiselect__tags { + border-color: transparent; + } + &, .multiselect__input::placeholder { text-align: right; @@ -93,10 +97,15 @@ overflow-x: hidden; } + // mouse feedback &.multiselect { &:hover, - &:focus { + &:focus, + &:active { opacity: 1; + .multiselect__tags { + border-color: var(--color-border-dark); + } } } } @@ -105,7 +114,6 @@ .multiselect__tags { border: none; .multiselect__single { - @include icon-color('triangle-s', 'actions', $color-black, 1, true); background-repeat: no-repeat; background-position: center right 4px; padding-right: 24px; diff --git a/css/Settings/SettingsAddressbook.scss b/css/Settings/SettingsAddressbook.scss index 92d6fc20..680a7c7d 100644 --- a/css/Settings/SettingsAddressbook.scss +++ b/css/Settings/SettingsAddressbook.scss @@ -23,6 +23,7 @@ .addressbook { display: flex; + flex-wrap: wrap; align-items: center; white-space: nowrap; text-overflow: ellipsis; diff --git a/css/Settings/SettingsAddressbookSharee.scss b/css/Settings/SettingsAddressbookSharee.scss index c9777c52..82fafebb 100644 --- a/css/Settings/SettingsAddressbookSharee.scss +++ b/css/Settings/SettingsAddressbookSharee.scss @@ -57,12 +57,15 @@ width: 16px; height: 16px; display: inline-block; + margin-bottom: 2px; } .icon-delete { display: inline-block; - width: 24px; + width: 20px; height: 20px; opacity: 0.4; + margin-bottom: 2px; + margin-left: 4px; } }
\ No newline at end of file diff --git a/css/Settings/SettingsAddressbookShares.scss b/css/Settings/SettingsAddressbookShares.scss index 9a311bb6..87cf2f9c 100644 --- a/css/Settings/SettingsAddressbookShares.scss +++ b/css/Settings/SettingsAddressbookShares.scss @@ -41,8 +41,9 @@ width: 14px; } - .multiselect { + .multiselect.multiselect-vue { width: inherit; + margin: 0; .multiselect__tags:focus-within, .multiselect__tags:hover { border-color: var(--color-primary-element); diff --git a/css/SettingsSection.scss b/css/SettingsSection.scss index c4989001..561036df 100644 --- a/css/SettingsSection.scss +++ b/css/SettingsSection.scss @@ -26,27 +26,29 @@ .settings-section { display: flex; align-items: center; + margin-top: 5px; } } #new-addressbook-form { display: flex; + input { + margin-top: 0; + margin-bottom: 0; + } } // Sort Contacts .sort-contacts { .multiselect.multiselect-vue { - width: 120px; - margin-left: 5px; - } - input#sort-by, .multiselect__single { - padding: 6px 12px; - min-height: 34px; - text-align: center; - background: url(/core/css/../img/actions/triangle-s.svg) no-repeat right 4px center; - background-color: inherit; - outline: 0; - padding-right: 24px !important; + width: 100%; + margin: 0; + .multiselect__single { + padding-right: 24px !important; + @include icon-color('triangle-s', 'actions', $color-black, 1, true); + background-repeat: no-repeat; + background-position: right 4px center; + } } } @@ -54,22 +56,21 @@ .import-contact { display: flex; flex-direction: column; - .multiselect-label { + &__multiselect-label { width: 100%; - padding: 6px 12px 6px 34px; + padding: 6px 12px; + padding-left: 34px; margin: 0; border-radius: var(--border-radius) var(--border-radius) 0 0; - background: url(/core/css/../img/actions/upload.svg) no-repeat left 9px center; - background-color: #f7f7f7; + background-position: left 9px center; z-index: 2; + &--no-select { + border-radius: var(--border-radius); + } } - .multiselect-vue { + &__multiselect.multiselect.multiselect-vue { width: 100%; margin: 0; - } - .multiselect-vue .multiselect__tags { - border: 1px solid var(--color-border-dark); - border-radius: 0 0 var(--border-radius) var(--border-radius); margin-top: -1px; } } diff --git a/css/icons.scss b/css/icons.scss index f688ac51..e5b18450 100644 --- a/css/icons.scss +++ b/css/icons.scss @@ -22,4 +22,8 @@ .icon-social { @include icon-color('social', 'contacts', $color-black, 1); +} + +.icon-address-book { + @include icon-color('address-book', 'contacts', $color-black, 1); }
\ No newline at end of file diff --git a/img/address-book.svg b/img/address-book.svg new file mode 100644 index 00000000..6be6e4ab --- /dev/null +++ b/img/address-book.svg @@ -0,0 +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 diff --git a/src/components/ContactDetails.vue b/src/components/ContactDetails.vue index 3517b24e..206aa749 100644 --- a/src/components/ContactDetails.vue +++ b/src/components/ContactDetails.vue @@ -237,7 +237,7 @@ export default { addressbookModel() { return { readableName: t('contacts', 'Addressbook'), - icon: 'icon-addressbook', + icon: 'icon-address-book', options: this.addressbooksOptions } }, @@ -264,7 +264,7 @@ export default { */ addressbooksOptions() { return this.addressbooks - .filter(addressbook => !addressbook.readOnly) + .filter(addressbook => !addressbook.readOnly && addressbook.enabled) .map(addressbook => { return { id: addressbook.id, diff --git a/src/components/Properties/PropertySelect.vue b/src/components/Properties/PropertySelect.vue index f7b7b0bb..92508124 100644 --- a/src/components/Properties/PropertySelect.vue +++ b/src/components/Properties/PropertySelect.vue @@ -38,8 +38,8 @@ <button :title="t('contacts', 'Delete')" class="property__delete icon-delete" @click="deleteProperty" /> <multiselect v-model="matchedOptions" :options="propModel.options" :placeholder="t('contacts', 'Select option')" - class="property__value" track-by="id" label="name" - @input="updateValue" /> + :disabled="isSingleOption" class="multiselect-vue property__value" track-by="id" + label="name" @input="updateValue" /> </div> </div> </template> @@ -95,6 +95,10 @@ export default { // length is one & add one space at the end return hasTitle + 1 + isLast }, + // is there only one option available + isSingleOption() { + return this.propModel.options.length <= 1 + }, // matching value to the options we provide matchedOptions: { diff --git a/src/components/Settings/SettingsAddressbook.vue b/src/components/Settings/SettingsAddressbook.vue index aaf9cd4c..9a580cc9 100644 --- a/src/components/Settings/SettingsAddressbook.vue +++ b/src/components/Settings/SettingsAddressbook.vue @@ -21,24 +21,22 @@ - --> <template> - <div> - <li :class="{'addressbook--disabled': !addressbook.enabled}" class="addressbook"> - <!-- addressbook name --> - <span class="addressbook__name">{{ addressbook.displayName }}</span> - <!-- sharing button --> - <a href="#" class="addressbook__share icon-shared" - @click="toggleShare" /> - <!-- popovermenu --> - <a v-click-outside="closeMenu" href="#" class="addressbook__menu"> - <div class="icon-more" @click="toggleMenu" /> - <div :class="{open: menuOpen}" class="popovermenu"> - <popover-menu :menu="menu" /> - </div> - </a> - </li> + <li :class="{'addressbook--disabled': !addressbook.enabled}" class="addressbook"> + <!-- addressbook name --> + <span class="addressbook__name">{{ addressbook.displayName }}</span> + <!-- sharing button --> + <a href="#" class="addressbook__share icon-shared" + @click="toggleShare" /> + <!-- popovermenu --> + <a v-click-outside="closeMenu" href="#" class="addressbook__menu"> + <div class="icon-more" @click="toggleMenu" /> + <div :class="{open: menuOpen}" class="popovermenu"> + <popover-menu :menu="menu" /> + </div> + </a> <!-- sharing input --> <share-address-book v-if="shareOpen" :addressbook="addressbook" /> - </div> + </li> </template> <script> diff --git a/src/components/Settings/SettingsImportContacts.vue b/src/components/Settings/SettingsImportContacts.vue index 725637e0..e52b9f03 100644 --- a/src/components/Settings/SettingsImportContacts.vue +++ b/src/components/Settings/SettingsImportContacts.vue @@ -22,17 +22,24 @@ <template> <div class="import-contact"> - <input id="contact-import" type="file" class="hidden-visually" - @change="processFile"> - <label id="upload" for="contact-import" class="button multiselect-label icon-upload no-select"> - {{ t('contacts', 'Import into') }} - </label> - <multiselect - v-model="selectedAddressbook" - :options="options" - :disabled="isSingleAddressbook" - :placeholder="t('contacts', 'Contacts')" - label="displayName" /> + <template v-if="!isNoAddressbookAvailable"> + <input id="contact-import" type="file" class="hidden-visually" + @change="processFile"> + <label id="upload" for="contact-import" class="button import-contact__multiselect-label icon-upload"> + {{ t('contacts', 'Import into') }} + </label> + <multiselect + v-model="selectedAddressbook" + :options="options" + :disabled="isSingleAddressbook" + :placeholder="t('contacts', 'Contacts')" + label="displayName" + class="multiselect-vue import-contact__multiselect" /> + </template> + <button v-else id="upload" for="contact-import" + class="button import-contact__multiselect-label import-contact__multiselect--no-select icon-error"> + {{ t('contacts', 'Importing is disabled because there are no address books available') }} + </button> </div> </template> @@ -51,12 +58,14 @@ export default { return this.$store.getters.getAddressbooks }, options() { - return this.addressbooks.map(addressbook => { - return { - id: addressbook.id, - displayName: addressbook.displayName - } - }) + return this.addressbooks + .filter(addressbook => !addressbook.readOnly && addressbook.enabled) + .map(addressbook => { + return { + id: addressbook.id, + displayName: addressbook.displayName + } + }) }, importState() { return this.$store.getters.getImportState @@ -73,9 +82,12 @@ export default { this.importDestination = value } }, - // disable multiselect when there is at most one address book + // disable multiselect when there is only one address book isSingleAddressbook() { - return this.addressbooks.length <= 1 + return this.options.length === 1 + }, + isNoAddressbookAvailable() { + return this.options.length < 1 } }, methods: { diff --git a/src/components/Settings/SettingsSortContacts.vue b/src/components/Settings/SettingsSortContacts.vue index 6e13f575..d6cb83c5 100644 --- a/src/components/Settings/SettingsSortContacts.vue +++ b/src/components/Settings/SettingsSortContacts.vue @@ -22,13 +22,13 @@ <template> <div class="sort-contacts"> - <label for="sort-by">{{ t('contacts', 'Sort by:') }}</label> <multiselect id="sort-by" - :placeholder="orderKey" + :value="orderKeyOption" :searchable="false" :allow-empty="false" :options="options" + :custom-label="formatSortByLabel" track-by="key" label="label" @input="sortContacts" /> @@ -40,15 +40,6 @@ export default { name: 'SettingsSortContacts', - props: { - addressbook: { - type: Object, - default() { - return {} - } - } - }, - computed: { /* Order Keys */ options() { @@ -69,7 +60,10 @@ export default { }, /* Current order Key */ orderKey() { - return t('contacts', this.options.filter(f => f.key === this.$store.getters.getOrderKey)[0].label) + return this.$store.getters.getOrderKey + }, + orderKeyOption() { + return this.options.filter(option => option.key === this.orderKey)[0] } }, methods: { @@ -78,6 +72,9 @@ export default { this.$store.commit('setOrder', key) this.$store.commit('sortContacts') localStorage.setItem('orderKey', key) + }, + formatSortByLabel(option) { + return t('contacts', 'Sort by {sorting}', { sorting: option.label }) } } } diff --git a/src/main.js b/src/main.js index 5d02fcb9..dd27bd7d 100644 --- a/src/main.js +++ b/src/main.js @@ -33,14 +33,6 @@ import ClickOutside from 'vue-click-outside' import Tooltip from 'v-tooltip' import VueClipboard from 'vue-clipboard2' -Vue.component('AppNavigation', AppNavigation) -Vue.component('DatetimePicker', DatetimePicker) -Vue.component('Multiselect', Multiselect) -Vue.component('PopoverMenu', PopoverMenu) -Vue.directive('ClickOutside', ClickOutside) -Vue.directive('Tooltip', Tooltip) -Vue.use(VueClipboard) - // CSP config for webpack dynamic chunk loading // eslint-disable-next-line __webpack_nonce__ = btoa(OC.requestToken) @@ -52,6 +44,14 @@ __webpack_nonce__ = btoa(OC.requestToken) // eslint-disable-next-line __webpack_public_path__ = OC.linkTo('contacts', 'js/') +Vue.component('AppNavigation', AppNavigation) +Vue.component('DatetimePicker', DatetimePicker) +Vue.component('Multiselect', Multiselect) +Vue.component('PopoverMenu', PopoverMenu) +Vue.directive('ClickOutside', ClickOutside) +Vue.directive('Tooltip', Tooltip) +Vue.use(VueClipboard) + sync(store, router) Vue.prototype.t = t diff --git a/webpack.common.js b/webpack.common.js index 409625f8..5e2c4b31 100644 --- a/webpack.common.js +++ b/webpack.common.js @@ -11,6 +11,12 @@ module.exports = { filename: 'contacts.js', chunkFilename: 'chunks/[name].js' }, + optimization: { + splitChunks: { + automaticNameDelimiter: '-', + chunks: 'all' + } + }, module: { rules: [ { |