From 3ab081876ce53796b23c2f1544f1bf9dfdd7f005 Mon Sep 17 00:00:00 2001 From: Jannik Stehle Date: Tue, 21 Nov 2023 15:34:30 +0100 Subject: [PATCH 1/3] fix: missing labels in share type filter The share type properties are getters which the `ItemFilter` component can't handle. Hence we need to compute new objects that have the relevant information as props. --- packages/web-app-files/src/views/shares/SharedWithMe.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/web-app-files/src/views/shares/SharedWithMe.vue b/packages/web-app-files/src/views/shares/SharedWithMe.vue index 1045d20cf68..bfe0478605e 100644 --- a/packages/web-app-files/src/views/shares/SharedWithMe.vue +++ b/packages/web-app-files/src/views/shares/SharedWithMe.vue @@ -172,7 +172,7 @@ 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 })) }) onMounted(() => { From e1e59984ac6cac78e3e26ed7c0cf864126b65522 Mon Sep 17 00:00:00 2001 From: Jannik Stehle Date: Tue, 21 Nov 2023 16:09:31 +0100 Subject: [PATCH 2/3] feat: add shared by filter on 'Shared with me'-page --- .../unreleased/enhancement-shared-by-filter | 6 +++ .../src/views/shares/SharedWithMe.vue | 50 ++++++++++++++++--- .../unit/views/shares/SharedWithMe.spec.ts | 23 +++++++++ 3 files changed, 73 insertions(+), 6 deletions(-) create mode 100644 changelog/unreleased/enhancement-shared-by-filter 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 bfe0478605e..7cf61e343db 100644 --- a/packages/web-app-files/src/views/shares/SharedWithMe.vue +++ b/packages/web-app-files/src/views/shares/SharedWithMe.vue @@ -28,7 +28,7 @@ :option-filter-label="$gettext('Filter share types')" :show-option-filter="true" id-attribute="key" - class="share-type-filter oc-mx-s" + class="share-type-filter oc-ml-s" display-name-attribute="label" filter-name="shareType" > @@ -36,6 +36,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({ @@ -175,6 +205,13 @@ export default defineComponent({ 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(() => { performLoaderTask() }) @@ -197,6 +234,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..8915b52b530 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 @@ -102,6 +102,27 @@ describe('SharedWithMe view', () => { expect(wrapper.find('.share-type-filter').exists()).toBeFalsy() }) }) + 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({ + owner: [collaborator1], + share: { shareType: ShareTypes.user.value } + }), + mock({ + owner: [collaborator2], + share: { shareType: ShareTypes.user.value } + }) + ] + }) + const filterItems = wrapper.findComponent('.shared-by-filter').props('items') + expect(wrapper.find('.shared-by-filter').exists()).toBeTruthy() + expect(filterItems).toEqual([collaborator1, collaborator2]) + }) + }) }) }) @@ -120,6 +141,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) From 31121ab8cc78b6ee9b059ee5d9d0d6da491e154b Mon Sep 17 00:00:00 2001 From: Jannik Stehle Date: Tue, 21 Nov 2023 16:21:53 +0100 Subject: [PATCH 3/3] feat: always show share type filter --- .../src/views/shares/SharedWithMe.vue | 1 - .../unit/views/shares/SharedWithMe.spec.ts | 19 ++++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/packages/web-app-files/src/views/shares/SharedWithMe.vue b/packages/web-app-files/src/views/shares/SharedWithMe.vue index 7cf61e343db..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" /> { }) }) 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() - }) - it('does not show filter if only one share type is present', () => { - const { wrapper } = getMountedWrapper({ - files: [mock({ share: { shareType: ShareTypes.user.value } })] - }) - expect(wrapper.find('.share-type-filter').exists()).toBeFalsy() + expect(filterItems).toEqual([ + { label: shareType1.label, key: shareType1.key }, + { label: shareType2.label, key: shareType2.key } + ]) }) }) describe('shared by', () => {