Skip to content

Commit

Permalink
feat: transparent shares
Browse files Browse the repository at this point in the history
  • Loading branch information
Jannik Stehle committed Sep 3, 2024
1 parent 0280a89 commit 89e0a7c
Show file tree
Hide file tree
Showing 24 changed files with 446 additions and 278 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ export default defineComponent({
const clientService = useClientService()
const { showMessage, showErrorMessage } = useMessages()
const spacesStore = useSpacesStore()
const { upsertSpace, upsertSpaceMember } = spacesStore
const { upsertSpace } = spacesStore
const capabilityStore = useCapabilityStore()
const capabilityRefs = storeToRefs(capabilityStore)
const configStore = useConfigStore()
Expand Down Expand Up @@ -426,10 +426,6 @@ export default defineComponent({
)
upsertSpace(updatedSpace)
addedShares.forEach((member) => {
upsertSpaceMember({ member })
})
}
if (results.length !== errors.length) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ export default defineComponent({
const sharesStore = useSharesStore()
const { graphRoles } = storeToRefs(sharesStore)
const { updateShare } = sharesStore
const { upsertSpace, upsertSpaceMember } = useSpacesStore()
const { upsertSpace } = useSpacesStore()
const { user } = storeToRefs(userStore)
Expand Down Expand Up @@ -260,7 +260,6 @@ export default defineComponent({
showMessage,
showErrorMessage,
upsertSpace,
upsertSpaceMember,
isExternalShare,
DateTime
}
Expand Down Expand Up @@ -413,7 +412,7 @@ export default defineComponent({
expirationDateTime?: string
}) {
try {
const share = await this.updateShare({
await this.updateShare({
clientService: this.$clientService,
space: this.space,
resource: this.resource,
Expand All @@ -426,7 +425,6 @@ export default defineComponent({
const space = await client.drives.getDrive(this.resource.id, this.graphRoles)
this.upsertSpace(space)
this.upsertSpaceMember({ member: share })
}
this.showMessage({ title: this.$gettext('Share successfully changed') })
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ import {
} from '@ownclouders/web-pkg'
import { isLocationSharesActive } from '@ownclouders/web-pkg'
import { textUtils } from '../../../helpers/textUtils'
import { ShareTypes } from '@ownclouders/web-client'
import { isShareSpaceResource, ShareTypes } from '@ownclouders/web-client'
import InviteCollaboratorForm from './Collaborators/InviteCollaborator/InviteCollaboratorForm.vue'
import CollaboratorListItem from './Collaborators/ListItem.vue'
import {
Expand Down Expand Up @@ -147,21 +147,29 @@ export default defineComponent({
const resourcesStore = useResourcesStore()
const { removeResources, getAncestorById } = resourcesStore
const spacesStore = useSpacesStore()
const { spaceMembers } = storeToRefs(spacesStore)
const { getSpaceMembers } = useSpacesStore()
const configStore = useConfigStore()
const { options: configOptions } = storeToRefs(configStore)
const sharesStore = useSharesStore()
const { addShare, deleteShare } = sharesStore
const { collaboratorShares } = storeToRefs(sharesStore)
const { user } = storeToRefs(userStore)
const resource = inject<Ref<Resource>>('resource')
const space = inject<Ref<SpaceResource>>('space')
const collaboratorShares = computed(() => {
if (isProjectSpaceResource(unref(space))) {
// filter out project space members, they are listed separately (see down below)
return sharesStore.collaboratorShares.filter((c) => c.resourceId !== unref(space).id)
}
return sharesStore.collaboratorShares
})
const spaceMembers = computed(() => getSpaceMembers(unref(space)))
const sharesListCollapsed = ref(true)
const toggleShareListCollapsed = () => {
sharesListCollapsed.value = !unref(sharesListCollapsed)
Expand Down Expand Up @@ -433,7 +441,7 @@ export default defineComponent({
return false
}
if (isProjectSpaceResource(this.space)) {
if (isProjectSpaceResource(this.space) || isShareSpaceResource(this.space)) {
return this.space.canShare({ user: this.user })
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ import {
useModals,
useResourcesStore
} from '@ownclouders/web-pkg'
import { LinkShare, ShareTypes } from '@ownclouders/web-client'
import { LinkShare } from '@ownclouders/web-client'
import { computed, defineComponent, inject, PropType, Ref, ref, unref } from 'vue'
import { formatDateFromDateTime, formatRelativeDateFromDateTime } from '@ownclouders/web-pkg'
import { Resource, SpaceResource } from '@ownclouders/web-client'
Expand Down Expand Up @@ -291,10 +291,7 @@ export default defineComponent({
})
const sharedAncestor = computed(() => {
const ancestorPath = Object.keys(unref(ancestorMetaData)).find((key) =>
unref(ancestorMetaData)[key].shareTypes.includes(ShareTypes.link.value)
)
return ancestorPath ? unref(ancestorMetaData)[ancestorPath] : undefined
return resourcesStore.getAncestorById(props.linkShare.resourceId)
})
const viaRouterParams = computed(() => {
Expand All @@ -317,9 +314,13 @@ export default defineComponent({
return null
}
return $gettext('Navigate to the parent (%{folderName})', {
folderName: basename(unref(sharedAncestor).path)
})
let folderName = basename(unref(sharedAncestor).path)
if (!folderName) {
// no folder name means path is "/" -> parent is the space
folderName = unref(space).name
}
return $gettext('Navigate to the parent (%{folderName})', { folderName })
})
return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ import {
useSpacesStore,
useUserStore
} from '@ownclouders/web-pkg'
import { defineComponent, inject, ref, Ref } from 'vue'
import { computed, defineComponent, inject, ref, Ref, unref } from 'vue'
import { shareSpaceAddMemberHelp } from '../../../helpers/contextualHelpers'
import { ProjectSpaceResource, CollaboratorShare } from '@ownclouders/web-client'
import { useClientService } from '@ownclouders/web-pkg'
Expand All @@ -109,8 +109,7 @@ export default defineComponent({
const { deleteShare } = sharesStore
const { graphRoles } = storeToRefs(sharesStore)
const spacesStore = useSpacesStore()
const { upsertSpace, removeSpaceMember } = spacesStore
const { spaceMembers } = storeToRefs(spacesStore)
const { upsertSpace, getSpaceMembers } = spacesStore
const capabilityStore = useCapabilityStore()
const { filesPrivateLinks } = storeToRefs(capabilityStore)
Expand All @@ -121,17 +120,20 @@ export default defineComponent({
const markInstance = ref<Mark>()
const resource = inject<Ref<ProjectSpaceResource>>('resource')
const spaceMembers = computed(() => getSpaceMembers(unref(resource)))
return {
user,
clientService,
configStore,
configOptions,
resource: inject<Ref<ProjectSpaceResource>>('resource'),
resource,
dispatchModal,
spaceMembers,
deleteShare,
upsertSpace,
removeSpaceMember,
canShare,
markInstance,
filesPrivateLinks,
Expand Down Expand Up @@ -233,8 +235,6 @@ export default defineComponent({
this.upsertSpace(space)
}
this.removeSpaceMember({ member: share })
this.showMessage({
title: this.$gettext('Share was removed successfully')
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,19 @@ import {
SpaceDetailsMultiple,
SpaceNoSelection,
isLocationTrashActive,
isLocationPublicActive,
isLocationSpacesActive,
isLocationSharesActive,
useRouter,
SidebarPanelExtension,
useIsFilesAppActive,
useGetMatchingSpace,
useUserStore,
useCapabilityStore
useCapabilityStore,
useCanListShares
} from '@ownclouders/web-pkg'
import {
isPersonalSpaceResource,
isProjectSpaceResource,
isShareResource,
isShareSpaceResource,
isSpaceResource,
SpaceResource
} from '@ownclouders/web-client'
Expand All @@ -44,6 +42,7 @@ export const useSideBarPanels = (): SidebarPanelExtension<SpaceResource, Resourc
const { $gettext } = useGettext()
const isFilesAppActive = useIsFilesAppActive()
const { isPersonalSpaceRoot } = useGetMatchingSpace()
const { canListShares } = useCanListShares()
const userStore = useUserStore()

return [
Expand Down Expand Up @@ -232,23 +231,7 @@ export const useSideBarPanels = (): SidebarPanelExtension<SpaceResource, Resourc
// project space roots have their own "sharing" panel (= space members)
return false
}
if (isPersonalSpaceRoot(items[0])) {
// sharing panel is not available on the personal space root
return false
}
if (isShareResource(items[0])) {
return false
}
if (isShareSpaceResource(root)) {
return false
}
if (
isLocationTrashActive(router, 'files-trash-generic') ||
isLocationPublicActive(router, 'files-public-link')
) {
return false
}
return capabilityStore.sharingApiEnabled
return canListShares({ space: root, resource: items[0] })
}
}
},
Expand Down
8 changes: 1 addition & 7 deletions packages/web-app-files/src/services/folder/loaderSpace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import {
import {
buildIncomingShareResource,
call,
isMountPointSpaceResource,
isPersonalSpaceResource,
isPublicSpaceResource,
isShareSpaceResource,
Expand Down Expand Up @@ -152,12 +151,7 @@ export class FolderLoaderSpace implements FolderLoader {
spacesStore: SpacesStore
space: SpaceResource
}) {
await spacesStore.loadMountPoints({ graphClient })

const mountPoints = spacesStore.spaces.filter(isMountPointSpaceResource)
// even if the resource has been shared via multiple permissions (e.g. directly via user and a group)
// we only care about one matching mount point since the remote item contains all permissions
const matchingMountPoint = mountPoints.find((s) => s.root?.remoteItem?.id === space.id)
const matchingMountPoint = await spacesStore.getMountPointForSpace({ graphClient, space })
if (!matchingMountPoint) {
return null
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
defaultComponentMocks,
nextTicks
} from 'web-test-helpers'
import { useMessages, useSharesStore, useSpacesStore } from '@ownclouders/web-pkg'
import { useMessages, useSharesStore } from '@ownclouders/web-pkg'
import EditDropdown from '../../../../../../src/components/SideBar/Shares/Collaborators/EditDropdown.vue'
import RoleDropdown from '../../../../../../src/components/SideBar/Shares/Collaborators/RoleDropdown.vue'
import { mock } from 'vitest-mock-extended'
Expand Down Expand Up @@ -155,21 +155,6 @@ describe('Collaborator ListItem component', () => {
const sharesStore = useSharesStore()
expect(sharesStore.updateShare).toHaveBeenCalled()
})
it('calls "upsertSpaceMember" for space resources', async () => {
const resource = mock<SpaceResource>({ driveType: 'project' })
const { wrapper } = createWrapper({
share: getShareMock({ shareType: ShareTypes.user.value }),
resource
})
wrapper.findComponent<typeof RoleDropdown>('role-dropdown-stub').vm.$emit('optionChange', {
permissions: [GraphSharePermission.readBasic]
})

await nextTicks(4)

const spacesStore = useSpacesStore()
expect(spacesStore.upsertSpaceMember).toHaveBeenCalled()
})
it('shows a message on error', async () => {
const resource = mock<SpaceResource>({ driveType: 'project' })
vi.spyOn(console, 'error').mockImplementation(() => undefined)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,8 @@ describe('FileShares', () => {
const user = { id: '1' } as User
const space = mock<SpaceResource>({ driveType: 'project', isMember: () => true })
const spaceMembers = [
{ sharedWith: { id: user.id } },
{ sharedWith: { id: '2' } }
{ sharedWith: { id: user.id, displayName: '' }, resourceId: space.id, permissions: [] },
{ sharedWith: { id: '2', displayName: '' }, resourceId: space.id, permissions: [] }
] as CollaboratorShare[]
const collaborator = getCollaborator()
collaborator.sharedWith = {
Expand All @@ -137,7 +137,9 @@ describe('FileShares', () => {
it('does not load space members if a space is given but the current user not a member', () => {
const user = { id: '1' } as User
const space = mock<SpaceResource>({ driveType: 'project' })
const spaceMembers = [{ sharedWith: { id: `${user}-2` } }] as CollaboratorShare[]
const spaceMembers = [
{ sharedWith: { id: `${user}-2`, displayName: '' }, resourceId: space.id, permissions: [] }
] as CollaboratorShare[]
const collaborator = getCollaborator()
collaborator.sharedWith = {
...collaborator.sharedWith,
Expand Down Expand Up @@ -183,6 +185,10 @@ function getWrapper({
files_sharing: { deny_access: false }
} satisfies Partial<CapabilityStore['capabilities']>

if (spaceMembers.length) {
collaborators = [...collaborators, ...spaceMembers]
}

return {
wrapper: mountType(FileShares, {
global: {
Expand All @@ -191,7 +197,6 @@ function getWrapper({
piniaOptions: {
stubActions: false,
userState: { user },
spacesState: { spaceMembers },
capabilityState: { capabilities },
configState: {
options: { contextHelpers: true }
Expand Down
Loading

0 comments on commit 89e0a7c

Please sign in to comment.