Skip to content

Commit

Permalink
Merge pull request #6577 from owncloud/sharing-within-spaces
Browse files Browse the repository at this point in the history
Implement people sharing for resources within a space
  • Loading branch information
kulmann authored Mar 18, 2022
2 parents a19c85c + 062e0f0 commit f6bf7cd
Show file tree
Hide file tree
Showing 14 changed files with 214 additions and 41 deletions.
6 changes: 6 additions & 0 deletions changelog/unreleased/enhancement-spaces-sharing-within-space
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Enhancement: Implement people sharing for resources within a space

Resources within a space can now be shared with other people.

https://github.com/owncloud/web/pull/6577
https://github.com/owncloud/web/issues/6283
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,9 @@ import { ImageDimension } from '../../../constants'
import { loadPreview } from '../../../helpers/resource'
import upperFirst from 'lodash-es/upperFirst'
import path from 'path'
import { createLocationSpaces, isAuthenticatedRoute } from '../../../router'
import { createLocationSpaces, isAuthenticatedRoute, isLocationSpacesActive } from '../../../router'
import { ShareTypes } from '../../../helpers/share'
import { useRoute, useRouter } from 'web-pkg/src/composables'
import { getIndicators } from '../../../helpers/statusIndicators'
export default {
Expand All @@ -103,11 +104,20 @@ export default {
inject: ['displayedItem'],
setup() {
const sharedParentDir = ref('')
const sharedParentRoute = computed(() =>
createLocationSpaces('files-spaces-personal-home', {
const router = useRouter()
const route = useRoute()
const sharedParentRoute = computed(() => {
if (isLocationSpacesActive(router, 'files-spaces-project')) {
return createLocationSpaces('files-spaces-project', {
params: { storageId: route.value.params.storageId, item: sharedParentDir.value }
})
}
return createLocationSpaces('files-spaces-personal-home', {
params: { item: sharedParentDir.value }
})
)
})
return {
sharedParentDir,
Expand Down Expand Up @@ -307,7 +317,8 @@ export default {
await this.loadSharesTree({
client: this.$client,
path: this.file.path,
$gettext: this.$gettext
$gettext: this.$gettext,
storageId: this.$route.params.storageId
})
this.shareIndicators = getIndicators(this.file, this.sharesTree)
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -197,12 +197,14 @@ export default {
this.loadCurrentFileOutgoingShares({
client: this.$client,
path: this.highlightedFile.path,
$gettext: this.$gettext
$gettext: this.$gettext,
storageId: this.$route.params.storageId
})
this.loadSharesTree({
client: this.$client,
path: dirname(this.highlightedFile.path),
$gettext: this.$gettext
$gettext: this.$gettext,
storageId: this.$route.params.storageId
})
},
linksComparator(l1, l2) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@
<template v-if="showShareesList && hasSharees">
<ul
id="files-collaborators-list"
class="oc-list oc-list-divider oc-overflow-hidden oc-m-rm"
class="oc-list oc-list-divider oc-overflow-hidden"
:class="{ 'oc-mb-l': showSpaceMembers, 'oc-m-rm': !showSpaceMembers }"
:aria-label="$gettext('Share receivers')"
>
<li v-for="collaborator in collaborators" :key="collaborator.key">
Expand Down Expand Up @@ -246,7 +247,7 @@ export default {
},
currentUserCanShare() {
return this.highlightedFile.canShare()
return this.highlightedFile.canShare({ user: this.user })
},
noResharePermsMessage() {
const translatedFile = this.$gettext("You don't have permission to share this file.")
Expand Down Expand Up @@ -340,24 +341,28 @@ export default {
this.deleteShare({
client: this.$client,
share: share,
resource: this.highlightedFile
resource: this.highlightedFile,
storageId: this.$route.params.storageId
})
},
$_reloadShares() {
this.loadCurrentFileOutgoingShares({
client: this.$client,
path: this.highlightedFile.path,
$gettext: this.$gettext
$gettext: this.$gettext,
storageId: this.$route.params.storageId
})
this.loadIncomingShares({
client: this.$client,
path: this.highlightedFile.path,
$gettext: this.$gettext
$gettext: this.$gettext,
storageId: this.$route.params.storageId
})
this.loadSharesTree({
client: this.$client,
path: dirname(this.highlightedFile.path),
$gettext: this.$gettext
$gettext: this.$gettext,
storageId: this.$route.params.storageId
})
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,14 @@ export default {
: SharePermissions.permissionsToBitmask(
this.selectedRole.permissions(!this.isOcis || this.resourceIsSpace)
)
let storageId
if (this.resourceIsSpace) {
storageId = this.highlightedFile.id
} else if (this.$route.params.storageId) {
storageId = this.$route.params.storageId
}
this.addShare({
client: this.$client,
graphClient: this.graphClient,
Expand All @@ -264,7 +272,7 @@ export default {
shareType: collaborator.value.shareType,
permissions: bitmask,
expirationDate: this.expirationDate,
storageId: this.resourceIsSpace ? this.highlightedFile.id : null
storageId
})
})
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ export default {
yield ref.loadCurrentFileOutgoingShares({
client: graphClient,
path: ref.space.id,
space: ref.space
resource: ref.space
})
})
Expand Down
8 changes: 6 additions & 2 deletions packages/web-app-files/src/services/folder/loaderProject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { useTask } from 'vue-concurrency'
import { isLocationSpacesActive } from '../../router'
import { clientService } from 'web-pkg/src/services'
import { buildResource, buildSpace, buildWebDavSpacesPath } from '../../helpers/resources'
import { DavProperties } from 'web-pkg/src/constants'

export class FolderLoaderProject implements FolderLoader {
public isEnabled(router: Router): boolean {
Expand Down Expand Up @@ -37,7 +38,9 @@ export class FolderLoaderProject implements FolderLoader {
}

const webDavResponse = yield ref.$client.files.list(
buildWebDavSpacesPath(ref.$route.params.storageId, path || '')
buildWebDavSpacesPath(ref.$route.params.storageId, path || ''),
1,
DavProperties.Default
)

let resources = []
Expand All @@ -60,7 +63,8 @@ export class FolderLoaderProject implements FolderLoader {
})
ref.loadIndicators({
client: ref.$client,
currentFolder: currentFolder?.path
currentFolder: currentFolder?.path,
storageId: ref.space.id
})

if (!sameRoute) {
Expand Down
46 changes: 31 additions & 15 deletions packages/web-app-files/src/store/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -151,17 +151,17 @@ export default {
value: computeShareTypes(state.currentFileOutgoingShares)
})
},
loadCurrentFileOutgoingShares(context, { client, path, space }) {
loadCurrentFileOutgoingShares(context, { client, path, resource, storageId }) {
context.commit('CURRENT_FILE_OUTGOING_SHARES_SET', [])
context.commit('CURRENT_FILE_OUTGOING_SHARES_ERROR', null)
context.commit('CURRENT_FILE_OUTGOING_SHARES_LOADING', true)

if (space) {
if (resource?.type === 'space') {
const promises = []
const spaceShares = []

for (const role of Object.keys(space.spaceRoles)) {
for (const userId of space.spaceRoles[role]) {
for (const role of Object.keys(resource.spaceRoles)) {
for (const userId of resource.spaceRoles[role]) {
promises.push(
client.users.getUser(userId).then((resolved) => {
spaceShares.push(
Expand All @@ -170,7 +170,7 @@ export default {
...resolved.data,
role
},
space.id
resource.id
)
)
})
Expand All @@ -190,9 +190,14 @@ export default {
})
}

let spaceRef
if (storageId) {
spaceRef = `${storageId}${path}`
}

// see https://owncloud.dev/owncloud-sdk/Shares.html
client.shares
.getShares(path, { reshares: true })
.getShares(path, { reshares: true, spaceRef })
.then((data) => {
context.commit(
'CURRENT_FILE_OUTGOING_SHARES_SET',
Expand Down Expand Up @@ -391,12 +396,18 @@ export default {
return
}

let spaceRef
if (storageId) {
spaceRef = `${storageId}${path}`
}

const remoteShare = shareType === ShareTypes.remote.value
client.shares
.shareFileWithUser(path, shareWith, {
permissions: permissions,
remoteUser: remoteShare,
expirationDate: expirationDate
expirationDate: expirationDate,
spaceRef
})
.then((share) => {
context.commit(
Expand All @@ -408,7 +419,7 @@ export default {
)
)
context.dispatch('updateCurrentFileShareTypes')
context.dispatch('loadIndicators', { client, currentFolder: path })
context.dispatch('loadIndicators', { client, currentFolder: path, storageId })
})
.catch((e) => {
context.dispatch(
Expand All @@ -422,7 +433,7 @@ export default {
)
})
},
deleteShare(context, { client, graphClient, share, resource }) {
deleteShare(context, { client, graphClient, share, resource, storageId }) {
const additionalParams = {}
if (share.shareType === ShareTypes.space.value) {
additionalParams.shareWith = share.collaborator.name
Expand All @@ -435,7 +446,7 @@ export default {

if (share.shareType !== ShareTypes.space.value) {
context.dispatch('updateCurrentFileShareTypes')
context.dispatch('loadIndicators', { client, currentFolder: resource.path })
context.dispatch('loadIndicators', { client, currentFolder: resource.path, storageId })
} else {
context.commit('CURRENT_FILE_OUTGOING_SHARES_LOADING', true)

Expand Down Expand Up @@ -466,7 +477,7 @@ export default {
* This will add new entries into the shares tree and will
* not remove unrelated existing ones.
*/
loadSharesTree(context, { client, path }) {
loadSharesTree(context, { client, path, storageId }) {
context.commit('SHARESTREE_ERROR', null)
// prune shares tree cache for all unrelated paths, keeping only
// existing relevant parent entries
Expand All @@ -479,6 +490,11 @@ export default {
return Promise.resolve()
}

let spaceRef
if (storageId) {
spaceRef = `${storageId}${path}`
}

// remove last entry which is the root folder
parentPaths.pop()

Expand All @@ -496,7 +512,7 @@ export default {
shareQueriesPromises.push(
shareQueriesQueue.add(() =>
client.shares
.getShares(queryPath, { reshares: true })
.getShares(queryPath, { reshares: true, spaceRef })
.then((data) => {
data.forEach((element) => {
sharesTree[queryPath].push({
Expand All @@ -517,7 +533,7 @@ export default {
shareQueriesPromises.push(
shareQueriesQueue.add(() =>
client.shares
.getShares(queryPath, { shared_with_me: true })
.getShares(queryPath, { shared_with_me: true, spaceRef })
.then((data) => {
data.forEach((element) => {
sharesTree[queryPath].push({
Expand Down Expand Up @@ -619,11 +635,11 @@ export default {
commit('CLEAR_RESOURCES_TO_DELETE_LIST')
},

async loadIndicators({ dispatch, commit }, { client, currentFolder }) {
async loadIndicators({ dispatch, commit }, { client, currentFolder, storageId }) {
// kind of bruteforce for now: remove the shares for the current folder and children, reload shares tree for the current folder.
// TODO: when we refactor the shares tree we want to modify shares tree nodes incrementally during adding and removing shares, not loading everything new from the backend.
commit('SHARESTREE_PRUNE_OUTSIDE_PATH', dirname(currentFolder))
await dispatch('loadSharesTree', { client, path: currentFolder })
await dispatch('loadSharesTree', { client, path: currentFolder, storageId })
commit('LOAD_INDICATORS')
},

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,11 @@ describe('FileLinks', () => {
stubs: stubs,
provide: {
changeView: jest.fn()
},
mocks: {
$route: {
params: {}
}
}
})
}
Expand All @@ -249,6 +254,11 @@ describe('FileLinks', () => {
},
provide: {
changeView: jest.fn()
},
mocks: {
$route: {
params: {}
}
}
})
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,10 @@ function getMountedWrapper(data, loading = false) {
localVue,
store: createStore(data),
mocks: {
sharesLoading: loading
sharesLoading: loading,
$route: {
params: {}
}
},
stubs: {
'oc-button': false,
Expand Down
Loading

0 comments on commit f6bf7cd

Please sign in to comment.