diff --git a/changelog/unreleased/enhancement-shared-by-filter b/changelog/unreleased/enhancement-shared-by-filter new file mode 100644 index 00000000000..337bb9514f8 --- /dev/null +++ b/changelog/unreleased/enhancement-shared-by-filter @@ -0,0 +1,6 @@ +Enhancement: Shared by filter + +The received shares on the "Shared with me"-page can now be filtered by the users that created the share. + +https://github.com/owncloud/web/issues/10013 +https://github.com/owncloud/web/pull/10029 diff --git a/packages/web-app-files/src/views/shares/SharedWithMe.vue b/packages/web-app-files/src/views/shares/SharedWithMe.vue index 1045d20cf68..7a16c6238ae 100644 --- a/packages/web-app-files/src/views/shares/SharedWithMe.vue +++ b/packages/web-app-files/src/views/shares/SharedWithMe.vue @@ -20,7 +20,6 @@ @toggle-filter="setAreHiddenFilesShown" /> @@ -36,6 +35,25 @@ + + + + { + let result = unref(currentItems) + const selectedShareTypes = queryItemAsString(unref(selectedShareTypesQuery))?.split('+') - if (!selectedShareTypes || selectedShareTypes.length === 0) { - return unref(currentItems) + if (selectedShareTypes?.length) { + result = result.filter(({ share }) => { + return selectedShareTypes.map((t) => ShareTypes[t].value).includes(share.shareType) + }) + } + + const selectedSharedBy = queryItemAsString(unref(selectedSharedByQuery))?.split('+') + if (selectedSharedBy?.length) { + result = result.filter(({ owner }) => + owner.some(({ username }) => selectedSharedBy.includes(username)) + ) } - return unref(currentItems).filter((item) => { - return selectedShareTypes.map((t) => ShareTypes[t].value).includes(item.share.shareType) - }) + + return result }) const { sortBy, sortDir, items, handleSort } = useSort({ @@ -172,7 +201,14 @@ export default defineComponent({ const shareTypes = computed(() => { const uniqueShareTypes = uniq(unref(storeItems).map((i) => i.share?.shareType)) - return ShareTypes.getByValues(uniqueShareTypes) + return ShareTypes.getByValues(uniqueShareTypes).map(({ label, key }) => ({ label, key })) + }) + + const fileOwners = computed(() => { + const flatList = unref(storeItems) + .map((i) => i.owner) + .flat() + return [...new Map(flatList.map((item) => [item.username, item])).values()] }) onMounted(() => { @@ -197,6 +233,7 @@ export default defineComponent({ shareSectionTitle, visibleShares, shareTypes, + fileOwners, handleSort, sortBy, diff --git a/packages/web-app-files/tests/unit/views/shares/SharedWithMe.spec.ts b/packages/web-app-files/tests/unit/views/shares/SharedWithMe.spec.ts index 814e5dadc21..8928c0cd38a 100644 --- a/packages/web-app-files/tests/unit/views/shares/SharedWithMe.spec.ts +++ b/packages/web-app-files/tests/unit/views/shares/SharedWithMe.spec.ts @@ -86,20 +86,42 @@ describe('SharedWithMe view', () => { }) }) describe('share type', () => { - it('shows filter if more than one share types are present', () => { + it('shows all available share types as filter option', () => { + const shareType1 = ShareTypes.user + const shareType2 = ShareTypes.group const { wrapper } = getMountedWrapper({ files: [ - mock({ share: { shareType: ShareTypes.user.value } }), - mock({ share: { shareType: ShareTypes.group.value } }) + mock({ share: { shareType: shareType1.value } }), + mock({ share: { shareType: shareType2.value } }) ] }) + const filterItems = wrapper.findComponent('.share-type-filter').props('items') expect(wrapper.find('.share-type-filter').exists()).toBeTruthy() + expect(filterItems).toEqual([ + { label: shareType1.label, key: shareType1.key }, + { label: shareType2.label, key: shareType2.key } + ]) }) - it('does not show filter if only one share type is present', () => { + }) + describe('shared by', () => { + it('shows all available collaborators as filter option', () => { + const collaborator1 = { username: 'user1', displayName: 'user1' } + const collaborator2 = { username: 'user2', displayName: 'user2' } const { wrapper } = getMountedWrapper({ - files: [mock({ share: { shareType: ShareTypes.user.value } })] + files: [ + mock({ + owner: [collaborator1], + share: { shareType: ShareTypes.user.value } + }), + mock({ + owner: [collaborator2], + share: { shareType: ShareTypes.user.value } + }) + ] }) - expect(wrapper.find('.share-type-filter').exists()).toBeFalsy() + const filterItems = wrapper.findComponent('.shared-by-filter').props('items') + expect(wrapper.find('.shared-by-filter').exists()).toBeTruthy() + expect(filterItems).toEqual([collaborator1, collaborator2]) }) }) }) @@ -120,6 +142,8 @@ function getMountedWrapper({ jest.mocked(useSort).mockImplementation((options) => useSortMock({ items: ref(options.items) })) // selected share types jest.mocked(queryItemAsString).mockImplementationOnce(() => undefined) + // selected shared by + jest.mocked(queryItemAsString).mockImplementationOnce(() => undefined) // openWithDefaultAppQuery jest.mocked(queryItemAsString).mockImplementationOnce(() => openWithDefaultAppQuery)