Skip to content
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
117 changes: 61 additions & 56 deletions apps/files_sharing/src/components/SharingInput.vue
Original file line number Diff line number Diff line change
Expand Up @@ -23,32 +23,23 @@
<template>
<div class="sharing-search">
<label for="sharing-search-input">{{ t('files_sharing', 'Search for share recipients') }}</label>
<NcMultiselect ref="multiselect"
<NcSelect ref="select"
id="sharing-search-input"
class="sharing-search__input"
:clear-on-select="true"
:disabled="!canReshare"
:hide-selected="true"
:internal-search="false"
:loading="loading"
:options="options"
:filterable="false"
:placeholder="inputPlaceholder"
:preselect-first="true"
:preserve-search="true"
:searchable="true"
:clear-search-on-blur="() => false"
:user-select="true"
open-direction="below"
label="displayName"
track-by="id"
@search-change="asyncFind"
@select="addShare">
<template #noOptions>
{{ t('files_sharing', 'No recommendations. Start typing.') }}
</template>
<template #noResult>
{{ noResultText }}
:options="options"
v-model="value"
@search="asyncFind"
@option:selected="addShare">
<template #no-options="{ search }">
{{ search ? noResultText : t('files_sharing', 'No recommendations. Start typing.') }}
</template>
</NcMultiselect>
</NcSelect>
</div>
</template>

Expand All @@ -57,7 +48,7 @@ import { generateOcsUrl } from '@nextcloud/router'
import { getCurrentUser } from '@nextcloud/auth'
import axios from '@nextcloud/axios'
import debounce from 'debounce'
import NcMultiselect from '@nextcloud/vue/dist/Components/NcMultiselect'
import NcSelect from '@nextcloud/vue/dist/Components/NcSelect.js'

import Config from '../services/ConfigService'
import GeneratePassword from '../utils/GeneratePassword'
Expand All @@ -69,7 +60,7 @@ export default {
name: 'SharingInput',

components: {
NcMultiselect,
NcSelect,
},

mixins: [ShareTypes, ShareRequests],
Expand Down Expand Up @@ -108,6 +99,7 @@ export default {
recommendations: [],
ShareSearch: OCA.Sharing.ShareSearch.state,
suggestions: [],
value: null,
}
},

Expand Down Expand Up @@ -161,7 +153,7 @@ export default {
},

methods: {
async asyncFind(query, id) {
async asyncFind(query) {
// save current query to check if we display
// recommendations or search results
this.query = query.trim()
Expand Down Expand Up @@ -391,21 +383,38 @@ export default {
// themselves from it, so let's not display the user icon
// case this.SHARE_TYPES.SHARE_TYPE_REMOTE:
// case this.SHARE_TYPES.SHARE_TYPE_USER:
return 'icon-user'
return {
icon: 'icon-user',
iconTitle: t('files_sharing', 'Guest'),
}
case this.SHARE_TYPES.SHARE_TYPE_REMOTE_GROUP:
case this.SHARE_TYPES.SHARE_TYPE_GROUP:
return 'icon-group'
return {
icon: 'icon-group',
iconTitle: t('files_sharing', 'Group'),
}
case this.SHARE_TYPES.SHARE_TYPE_EMAIL:
return 'icon-mail'
return {
icon: 'icon-mail',
iconTitle: t('files_sharing', 'Email'),
}
case this.SHARE_TYPES.SHARE_TYPE_CIRCLE:
return 'icon-circle'
return {
icon: 'icon-circle',
iconTitle: t('files_sharing', 'Circle'),
}
case this.SHARE_TYPES.SHARE_TYPE_ROOM:
return 'icon-room'
return {
icon: 'icon-room',
iconTitle: t('files_sharing', 'Talk conversation'),
}
case this.SHARE_TYPES.SHARE_TYPE_DECK:
return 'icon-deck'

return {
icon: 'icon-deck',
iconTitle: t('files_sharing', 'Deck board'),
}
default:
return ''
return {}
}
},

Expand Down Expand Up @@ -438,7 +447,7 @@ export default {
displayName: result.name || result.label,
subtitle,
shareWithDisplayNameUnique: result.shareWithDisplayNameUnique || '',
icon: this.shareTypeToIcon(result.value.shareType),
...this.shareTypeToIcon(result.value.shareType),
}
},

Expand All @@ -448,12 +457,15 @@ export default {
* @param {object} value the multiselect option
*/
async addShare(value) {
// Clear the displayed selection
this.value = null

if (value.lookup) {
await this.getSuggestions(this.query, true)

// focus the input again
this.$nextTick(() => {
this.$refs.multiselect.$el.querySelector('.multiselect__input').focus()
// open the dropdown again
this.$refs.select.$children[0].open = true
})
return true
}
Expand Down Expand Up @@ -501,19 +513,12 @@ export default {
this.$emit('add:share', share)
}

// reset the search string when done
// FIXME: https://github.com/shentao/vue-multiselect/issues/633
if (this.$refs.multiselect?.$refs?.VueMultiselect?.search) {
this.$refs.multiselect.$refs.VueMultiselect.search = ''
}

await this.getRecommendations()
} catch (error) {
// focus back if any error
const input = this.$refs.multiselect.$el.querySelector('input')
if (input) {
input.focus()
}
this.$nextTick(() => {
// open the dropdown again on error
this.$refs.select.$children[0].open = true
})
this.query = value.shareWith
console.error('Error while adding new share', error)
} finally {
Expand All @@ -537,19 +542,19 @@ export default {
&__input {
width: 100%;
margin: 10px 0;
}
}

// properly style the lookup entry
.multiselect__option {
span[lookup] {
.avatardiv {
background-image: var(--icon-search-white);
background-repeat: no-repeat;
background-position: center;
background-color: var(--color-text-maxcontrast) !important;
div {
display: none;
}
}
.vs__dropdown-menu {
// properly style the lookup entry
span[lookup] {
.avatardiv {
background-image: var(--icon-search-white);
background-repeat: no-repeat;
background-position: center;
background-color: var(--color-text-maxcontrast) !important;
div {
display: none;
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions dist/core-common.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/core-common.js.map

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions dist/files_sharing-files_sharing_tab.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/files_sharing-files_sharing_tab.js.map

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public static function sharedByLabel() {
* @return Locator
*/
public static function shareWithInput() {
return Locator::forThe()->css(".sharing-search__input .multiselect__input")->
return Locator::forThe()->css(".sharing-search__input input")->
descendantOf(FilesAppContext::detailsView())->
describedAs("Share with input in the details view in Files app");
}
Expand All @@ -50,16 +50,15 @@ public static function shareWithInput() {
* @return Locator
*/
public static function shareWithInputResults() {
return Locator::forThe()->css(".sharing-search__input .multiselect__content-wrapper")->
descendantOf(FilesAppContext::detailsView())->
return Locator::forThe()->css(".vs__dropdown-menu")->
describedAs("Share with input results list in the details view in Files app");
}

/**
* @return Locator
*/
public static function shareWithInputResult($result) {
return Locator::forThe()->xpath("//li[contains(concat(' ', normalize-space(@class), ' '), ' multiselect__element ')]//span[normalize-space() = '$result']/ancestor::li")->
return Locator::forThe()->xpath("//li//span[normalize-space() = '$result']/ancestor::li")->
descendantOf(self::shareWithInputResults())->
describedAs("Share with input result from the results list in the details view in Files app");
}
Expand Down