diff --git a/src/shared/components/ncContextResource/ResourceSharees.vue b/src/shared/components/ncContextResource/ResourceSharees.vue index 254a67a17..d3d36b98d 100644 --- a/src/shared/components/ncContextResource/ResourceSharees.vue +++ b/src/shared/components/ncContextResource/ResourceSharees.vue @@ -19,14 +19,10 @@ - - diff --git a/src/shared/mixins/searchUserGroup.js b/src/shared/mixins/searchUserGroup.js new file mode 100644 index 000000000..674bce486 --- /dev/null +++ b/src/shared/mixins/searchUserGroup.js @@ -0,0 +1,105 @@ +import axios from '@nextcloud/axios' +import { generateOcsUrl } from '@nextcloud/router' +import { getCurrentUser } from '@nextcloud/auth' +import debounce from 'debounce' +import { showError } from '@nextcloud/dialogs' +import '@nextcloud/dialogs/style.css' + +export default { + data() { + return { + query: '', + loading: false, + minSearchStringLength: 1, + maxAutocompleteResults: 20, + suggestions: [], + } + }, + computed: { + isValidQuery() { + return this.query?.trim() && this.query.length >= this.minSearchStringLength + }, + options() { + if (this.isValidQuery) { + return this.suggestions + } + return [] + }, + + noResultText() { + if (this.loading) { + return t('tables', 'Searching …') + } + return t('tables', 'No elements found.') + }, + + userId() { + return getCurrentUser().uid + }, + }, + methods: { + getShareTypes() { + const types = [] + if (this.selectUsers) { + types.push(this.SHARE_TYPES.SHARE_TYPE_USER) + } + if (this.selectGroups) { + types.push(this.SHARE_TYPES.SHARE_TYPE_GROUP) + } + return types + }, + getShareTypeString() { + if (this.selectUsers && !this.selectGroups) { + return 'User' + } else if (!this.selectUsers && this.selectGroups) { + return 'Group' + } else { + return 'User or group' + } + }, + getPlaceholder() { + return t('tables', '{shareTypeString}...', { shareTypeString: this.getShareTypeString() }) + }, + async asyncFind(query) { + this.query = query.trim() + if (this.isValidQuery) { + this.loading = true + await this.debounceGetSuggestions(query) + } + }, + async getSuggestions(search) { + this.loading = true + const shareTypes = this.getShareTypes() + let shareTypeQueryString = '' + shareTypes.forEach(shareType => { + shareTypeQueryString += `&shareTypes[]=${shareType}` + }) + const url = generateOcsUrl(`core/autocomplete/get?search=${search}${shareTypeQueryString}&limit=${this.maxAutocompleteResults}`) + + try { + const res = await axios.get(url) + const rawSuggestions = res.data.ocs.data.map(autocompleteResult => { + return { + user: autocompleteResult.id, + displayName: autocompleteResult.label, + icon: autocompleteResult.icon, + isUser: autocompleteResult.source.startsWith('users'), + key: autocompleteResult.source + '-' + autocompleteResult.id, + } + }) + this.suggestions = this.filterOutUnwantedItems(rawSuggestions) + this.loading = false + } catch (err) { + console.debug(err) + showError(t('tables', 'Failed to fetch {shareTypeString}', { shareTypeString: this.getShareTypeString().toLowerCase() })) + } + }, + debounceGetSuggestions: debounce(function(...args) { + this.getSuggestions(...args) + }, 300), + + filterOutCurrentUser(list) { + return list.filter((item) => !(item.isUser && item.user === getCurrentUser().uid)) + }, + }, +}