Properly handle multiple shares in a row and refactor sharee loading

Signed-off-by: Julius Härtl <jus@bitgrid.net>
This commit is contained in:
Julius Härtl
2020-10-07 10:00:25 +02:00
parent 974f4b0f6d
commit 556d3d1164
2 changed files with 43 additions and 20 deletions

View File

@@ -7,10 +7,19 @@
:options="formatedSharees" :options="formatedSharees"
:user-select="true" :user-select="true"
label="displayName" label="displayName"
:loading="isLoading || !!isSearching"
:disabled="isLoading"
track-by="multiselectKey" track-by="multiselectKey"
:internal-search="true" :internal-search="true"
@input="clickAddAcl" @input="clickAddAcl"
@search-change="asyncFind" /> @search-change="asyncFind">
<template #noOptions>
{{ isSearching ? t('deck', 'Searching for users, groups and circles ...') : t('deck', 'No participants found') }}
</template>
<template #noResult>
{{ isSearching ? t('deck', 'Searching for users, groups and circles ...') : t('deck', 'No participants found') }}
</template>
</Multiselect>
<ul <ul
id="shareWithList" id="shareWithList"
@@ -63,6 +72,7 @@ import { Avatar, Multiselect, Actions, ActionButton, ActionCheckbox } from '@nex
import { CollectionList } from 'nextcloud-vue-collections' import { CollectionList } from 'nextcloud-vue-collections'
import { mapGetters, mapState } from 'vuex' import { mapGetters, mapState } from 'vuex'
import { getCurrentUser } from '@nextcloud/auth' import { getCurrentUser } from '@nextcloud/auth'
import { showError } from '@nextcloud/dialogs'
export default { export default {
name: 'SharingTabSidebar', name: 'SharingTabSidebar',
@@ -83,6 +93,7 @@ export default {
data() { data() {
return { return {
isLoading: false, isLoading: false,
isSearching: false,
addAcl: null, addAcl: null,
addAclForAPI: null, addAclForAPI: null,
} }
@@ -137,13 +148,20 @@ export default {
this.asyncFind('') this.asyncFind('')
}, },
methods: { methods: {
asyncFind(query) { async asyncFind(query) {
this.isLoading = true // manual debounce to handle async searching more easily and have more control over the loading state
this.$store.dispatch('loadSharees', query).then(response => { const timestamp = (new Date()).getTime()
this.isLoading = false if (!this.isSearching || timestamp > this.isSearching + 300) {
}) this.isSearching = timestamp
await this.$store.dispatch('loadSharees', query)
// only reset searching flag if the most recent search finished
if (this.isSearching === timestamp) {
this.isSearching = false
}
}
}, },
clickAddAcl() { async clickAddAcl() {
this.addAclForAPI = { this.addAclForAPI = {
type: this.addAcl.value.shareType, type: this.addAcl.value.shareType,
participant: this.addAcl.value.shareWith, participant: this.addAcl.value.shareWith,
@@ -151,7 +169,16 @@ export default {
permissionShare: false, permissionShare: false,
permissionManage: false, permissionManage: false,
} }
this.$store.dispatch('addAclToCurrentBoard', this.addAclForAPI) this.isLoading = true
try {
await this.$store.dispatch('addAclToCurrentBoard', this.addAclForAPI)
} catch (e) {
const errorMessage = t('deck', 'Failed to create share with {displayName}', { displayName: this.addAcl.displayName })
console.error(errorMessage, e)
showError(errorMessage)
}
this.addAcl = null
this.isLoading = false
}, },
clickEditAcl(acl) { clickEditAcl(acl) {
this.addAclForAPI = Object.assign({}, acl) this.addAclForAPI = Object.assign({}, acl)

View File

@@ -34,7 +34,6 @@ import comment from './comment'
import trashbin from './trashbin' import trashbin from './trashbin'
import attachment from './attachment' import attachment from './attachment'
import overview from './overview' import overview from './overview'
import debounce from 'lodash/debounce'
Vue.use(Vuex) Vue.use(Vuex)
const apiClient = new BoardApi() const apiClient = new BoardApi()
@@ -392,7 +391,7 @@ export default new Vuex.Store({
const boards = await apiClient.loadBoards() const boards = await apiClient.loadBoards()
commit('setBoards', boards) commit('setBoards', boards)
}, },
loadSharees: debounce(function({ commit }, query) { async loadSharees({ commit }, query) {
const params = new URLSearchParams() const params = new URLSearchParams()
if (typeof query === 'undefined') { if (typeof query === 'undefined') {
return return
@@ -402,10 +401,9 @@ export default new Vuex.Store({
params.append('perPage', 20) params.append('perPage', 20)
params.append('itemType', [0, 1, 7]) params.append('itemType', [0, 1, 7])
axios.get(generateOcsUrl('apps/files_sharing/api/v1') + 'sharees', { params }).then((response) => { const response = await axios.get(generateOcsUrl('apps/files_sharing/api/v1') + 'sharees', { params })
commit('setSharees', response.data.ocs.data) commit('setSharees', response.data.ocs.data)
}) },
}, 250),
setBoardFilter({ commmit }, filter) { setBoardFilter({ commmit }, filter) {
commmit('setBoardFilter', filter) commmit('setBoardFilter', filter)
@@ -454,13 +452,11 @@ export default new Vuex.Store({
}, },
// acl actions // acl actions
addAclToCurrentBoard({ dispatch, commit }, newAcl) { async addAclToCurrentBoard({ dispatch, commit }, newAcl) {
newAcl.boardId = this.state.currentBoard.id newAcl.boardId = this.state.currentBoard.id
apiClient.addAcl(newAcl) const result = await apiClient.addAcl(newAcl)
.then((returnAcl) => { commit('addAclToCurrentBoard', result)
commit('addAclToCurrentBoard', returnAcl) dispatch('refreshBoard', newAcl.boardId)
dispatch('refreshBoard', newAcl.boardId)
})
}, },
updateAclFromCurrentBoard({ commit }, acl) { updateAclFromCurrentBoard({ commit }, acl) {
acl.boardId = this.state.currentBoard.id acl.boardId = this.state.currentBoard.id