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)