diff --git a/packages/web-app-files/src/components/SideBar/Shares/FileShares.vue b/packages/web-app-files/src/components/SideBar/Shares/FileShares.vue index 9698f3fab2b..206c0c8a447 100644 --- a/packages/web-app-files/src/components/SideBar/Shares/FileShares.vue +++ b/packages/web-app-files/src/components/SideBar/Shares/FileShares.vue @@ -43,6 +43,18 @@ + @@ -55,6 +67,11 @@ import { dirname } from 'path' import InviteCollaboratorForm from './InviteCollaborator/InviteCollaboratorForm.vue' import CollaboratorListItem from './Collaborators/ListItem.vue' import { ShareTypes } from '../../../helpers/share' +import { useStore } from 'web-pkg/src/composables' +import { clientService } from 'web-pkg/src/services' +import { useTask } from 'vue-concurrency' +import { buildSpaceShare } from '../../../helpers/resources' +import { sortSpaceMembers } from '../../../helpers/space' export default { title: ($gettext) => { @@ -65,10 +82,45 @@ export default { InviteCollaboratorForm, CollaboratorListItem }, + inject: { + currentSpace: { + default: null + } + }, + setup() { + const store = useStore() + + const loadSpaceMembersTask = useTask(function* (signal, ref) { + const graphClient = clientService.graphAuthenticated( + store.getters.configuration.server, + store.getters.getToken + ) + + const promises = [] + const spaceShares = [] + + for (const role of Object.keys(ref.space.spaceRoles)) { + for (const userId of ref.space.spaceRoles[role]) { + promises.push( + graphClient.users.getUser(userId).then((resolved) => { + spaceShares.push(buildSpaceShare({ ...resolved.data, role }, ref.space.id)) + }) + ) + } + } + + yield Promise.all(promises).then(() => { + ref.spaceMembers = sortSpaceMembers(spaceShares) + }) + }) + + return { loadSpaceMembersTask } + }, data() { return { currentShare: null, - showShareesList: true + showShareesList: true, + spaceMembers: [] } }, computed: { @@ -84,6 +136,9 @@ export default { sharedWithLabel() { return this.$gettext('Shared with') }, + spaceMemberLabel() { + return this.$gettext('Space Members') + }, hasSharees() { return this.collaboratorsAvatar.length > 0 @@ -205,6 +260,15 @@ export default { } return null + }, + space() { + return this.currentSpace?.value + }, + currentUserIsMemberOfSpace() { + return this.space?.spaceMemberIds.includes(this.user.uuid) + }, + showSpaceMembers() { + return this.space && this.currentUserIsMemberOfSpace } }, watch: { @@ -216,6 +280,14 @@ export default { } }, immediate: true + }, + space: { + handler: function () { + if (this.showSpaceMembers) { + this.loadSpaceMembersTask.perform(this) + } + }, + immediate: true } }, diff --git a/packages/web-app-files/src/components/SideBar/SideBar.vue b/packages/web-app-files/src/components/SideBar/SideBar.vue index 3d1ced36e80..63203066d8b 100644 --- a/packages/web-app-files/src/components/SideBar/SideBar.vue +++ b/packages/web-app-files/src/components/SideBar/SideBar.vue @@ -91,16 +91,19 @@ import { mapGetters, mapState, mapActions } from 'vuex' import { VisibilityObserver } from 'web-pkg/src/observer' import { DavProperties } from 'web-pkg/src/constants' -import { buildResource } from '../../helpers/resources' +import { buildResource, buildSpace } from '../../helpers/resources' import { isLocationCommonActive, isLocationPublicActive, isLocationSharesActive } from '../../router' -import { computed } from '@vue/composition-api' +import { computed, ref } from '@vue/composition-api' import FileInfo from './FileInfo.vue' import SpaceInfo from './SpaceInfo.vue' +import { useTask } from 'vue-concurrency' +import { clientService } from 'web-pkg/src/services' +import { useStore } from 'web-pkg/src/composables' let visibilityObserver let hiddenObserver @@ -110,10 +113,32 @@ export default { provide() { return { - displayedItem: computed(() => this.selectedFile) + displayedItem: computed(() => this.selectedFile), + currentSpace: computed(() => this.currentSpace) } }, + setup() { + const currentSpace = ref(null) + const store = useStore() + + const loadSpaceTask = useTask(function* (signal, ref, spaceId) { + const graphClient = clientService.graphAuthenticated( + store.getters.configuration.server, + store.getters.getToken + ) + const graphResponse = yield graphClient.drives.getDrive(spaceId) + + if (!graphResponse.data) { + return + } + + currentSpace.value = buildSpace(graphResponse.data) + }) + + return { currentSpace, loadSpaceTask } + }, + data() { return { focused: undefined, @@ -243,9 +268,11 @@ export default { if (!this.areMultipleSelected) { await this.fetchFileInfo() } + if (this.$route.params.spaceId && !this.highlightedFileIsSpace) { + this.loadSpaceTask.perform(this, this.$route.params.spaceId) + } this.$nextTick(this.initVisibilityObserver) }, - beforeDestroy() { visibilityObserver.disconnect() hiddenObserver.disconnect() diff --git a/packages/web-app-files/src/helpers/space/index.ts b/packages/web-app-files/src/helpers/space/index.ts new file mode 100644 index 00000000000..85cc350c927 --- /dev/null +++ b/packages/web-app-files/src/helpers/space/index.ts @@ -0,0 +1 @@ +export * from './sortMembers' diff --git a/packages/web-app-files/src/helpers/space/sortMembers.ts b/packages/web-app-files/src/helpers/space/sortMembers.ts new file mode 100644 index 00000000000..570efb991c3 --- /dev/null +++ b/packages/web-app-files/src/helpers/space/sortMembers.ts @@ -0,0 +1,17 @@ +import { spaceRoleManager } from '../share' + +export const sortSpaceMembers = (shares: Array): Array => { + const sortedManagers = shares + .filter((share) => share.role.name === spaceRoleManager.name) + .sort((a, b) => { + return a.collaborator.displayName.localeCompare(b.collaborator.displayName) + }) + + const sortedRest = shares + .filter((share) => share.role.name !== spaceRoleManager.name) + .sort((a, b) => { + return a.collaborator.displayName.localeCompare(b.collaborator.displayName) + }) + + return [...sortedManagers, ...sortedRest] +} diff --git a/packages/web-app-files/src/store/actions.js b/packages/web-app-files/src/store/actions.js index 8887d5d1809..e83eb190612 100644 --- a/packages/web-app-files/src/store/actions.js +++ b/packages/web-app-files/src/store/actions.js @@ -14,6 +14,7 @@ import { loadPreview } from '../helpers/resource' import { avatarUrl } from '../helpers/user' import { has } from 'lodash-es' import { ShareTypes, SpacePeopleShareRoles } from '../helpers/share' +import { sortSpaceMembers } from '../helpers/space' export default { updateFileProgress({ commit }, progress) { @@ -179,7 +180,7 @@ export default { return Promise.all(promises) .then(() => { - context.commit('CURRENT_FILE_OUTGOING_SHARES_SET', spaceShares) + context.commit('CURRENT_FILE_OUTGOING_SHARES_SET', sortSpaceMembers(spaceShares)) context.dispatch('updateCurrentFileShareTypes') context.commit('CURRENT_FILE_OUTGOING_SHARES_LOADING', false) })