Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
folderViewsFolderExtensionPoint,
folderViewsProjectSpacesExtensionPoint,
folderViewsSharedViaLink,
folderViewsSharedWithOthers,
folderViewsTrashExtensionPoint,
folderViewsTrashOverviewExtensionPoint
} from '../../extensionPoints'
Expand All @@ -21,7 +22,8 @@ export const useFolderViews = (): FolderViewExtension[] => {
folderViewsTrashExtensionPoint.id,
folderViewsTrashOverviewExtensionPoint.id,
folderViewsProjectSpacesExtensionPoint.id,
folderViewsSharedViaLink.id
folderViewsSharedViaLink.id,
folderViewsSharedWithOthers.id
],
folderView: {
name: 'resource-table-condensed',
Expand All @@ -42,7 +44,8 @@ export const useFolderViews = (): FolderViewExtension[] => {
folderViewsFavoritesExtensionPoint.id,
folderViewsTrashExtensionPoint.id,
folderViewsTrashOverviewExtensionPoint.id,
folderViewsSharedViaLink.id
folderViewsSharedViaLink.id,
folderViewsSharedWithOthers.id
],
folderView: {
name: 'resource-table',
Expand All @@ -63,7 +66,8 @@ export const useFolderViews = (): FolderViewExtension[] => {
folderViewsFavoritesExtensionPoint.id,
folderViewsTrashExtensionPoint.id,
folderViewsTrashOverviewExtensionPoint.id,
folderViewsSharedViaLink.id
folderViewsSharedViaLink.id,
folderViewsSharedWithOthers.id
],
folderView: {
name: 'resource-tiles',
Expand Down
5 changes: 5 additions & 0 deletions packages/web-app-files/src/extensionPoints.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@ export const folderViewsSharedViaLink: ExtensionPoint<FolderViewExtension> = {
extensionType: 'folderView'
}

export const folderViewsSharedWithOthers: ExtensionPoint<FolderViewExtension> = {
id: 'app.files.folder-views.shared-with-others',
extensionType: 'folderView'
}

export const extensionPoints = () => {
return computed<ExtensionPoint<any>[]>(() => {
return [
Expand Down
41 changes: 37 additions & 4 deletions packages/web-app-files/src/views/shares/SharedWithOthers.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<template>
<div class="flex">
<files-view-wrapper>
<app-bar :is-side-bar-open="isSideBarOpen">
<app-bar ref="appBarRef" :is-side-bar-open="isSideBarOpen" :view-modes="viewModes">
<template #navigation>
<SharesNavigation />
</template>
Expand Down Expand Up @@ -35,7 +35,8 @@
<span v-text="$gettext('You have not shared any resources with other people.')" />
</template>
</no-content-message>
<resource-table
<component
:is="folderView.component"
v-else
v-model:selected-ids="selectedResourcesIds"
:is-side-bar-open="isSideBarOpen"
Expand All @@ -45,6 +46,10 @@
:header-position="fileListHeaderY"
:sort-by="sortBy"
:sort-dir="sortDir"
:sort-fields="sortFields.filter((field) => field.name === 'name')"
Copy link

Copilot AI Oct 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The inline filter operation creates a new array on every render. Consider memoizing this with computed() to improve performance.

Copilot uses AI. Check for mistakes.
:view-mode="viewMode"
:view-size="viewSize"
:style="folderViewStyle"
:grouping-settings="groupingSettings"
@file-click="triggerDefaultAction"
@item-visible="loadPreview({ space: getMatchingSpace($event), resource: $event })"
Expand All @@ -60,7 +65,7 @@
<pagination :pages="paginationPages" :current-page="paginationPage" />
<list-info v-if="filteredItems.length > 0" class="w-full my-2" />
</template>
</resource-table>
</component>
</template>
</files-view-wrapper>
<file-side-bar
Expand All @@ -77,6 +82,7 @@ import {
useAppsStore,
useCapabilityStore,
useConfigStore,
useExtensionRegistry,
useFileActions,
useLoadPreview,
useResourcesStore,
Expand All @@ -95,13 +101,14 @@ import { ContextActions } from '@opencloud-eu/web-pkg'
import FilesViewWrapper from '../../components/FilesViewWrapper.vue'

import { useResourcesViewDefaults } from '../../composables'
import { defineComponent, computed, unref } from 'vue'
import { defineComponent, computed, unref, useTemplateRef, ComponentPublicInstance } from 'vue'
import { useGroupingSettings } from '@opencloud-eu/web-pkg'
import { useGetMatchingSpace } from '@opencloud-eu/web-pkg'
import SharesNavigation from '../../components/AppBar/SharesNavigation.vue'
import { OutgoingShareResource, ShareTypes } from '@opencloud-eu/web-client'
import { storeToRefs } from 'pinia'
import { useGettext } from 'vue3-gettext'
import { folderViewsSharedWithOthers } from '../../extensionPoints'

export default defineComponent({
components: {
Expand Down Expand Up @@ -139,6 +146,28 @@ export default defineComponent({
} = resourcesViewDefaults
const { loadPreview } = useLoadPreview(viewMode)

const extensionRegistry = useExtensionRegistry()

const folderView = computed(() => {
const viewMode = unref(resourcesViewDefaults.viewMode)
return unref(viewModes).find((v) => v.name === viewMode)
})

const viewModes = computed(() => {
return [
...extensionRegistry.requestExtensions(folderViewsSharedWithOthers).map((e) => e.folderView)
]
})

const appBarRef = useTemplateRef<ComponentPublicInstance<typeof AppBar>>('appBarRef')
const folderViewStyle = computed(() => {
return {
...(unref(folderView)?.isScrollable === false && {
height: `calc(100% - ${unref(appBarRef)?.$el.getBoundingClientRect().height}px)`
})
}
})

const shareTypes = computed(() => {
const uniqueShareTypes = uniq(unref(paginatedResources).flatMap((i) => i.shareTypes))

Expand Down Expand Up @@ -199,6 +228,10 @@ export default defineComponent({
shareTypes,
getMatchingSpace,
loadPreview,
folderView,
folderViewStyle,
viewModes,
appBarRef,

// CERN
...useGroupingSettings({ sortBy, sortDir })
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,14 @@ import { IncomingShareResource } from '@opencloud-eu/web-client'
import { defaultPlugins, mount, defaultComponentMocks } from '@opencloud-eu/web-test-helpers'
import { ShareTypes } from '@opencloud-eu/web-client'
import { useSortMock } from '../../../mocks/useSortMock'
import { ResourceTable } from '@opencloud-eu/web-pkg'
import { ResourceTable, FolderViewExtension, useExtensionRegistry } from '@opencloud-eu/web-pkg'
import {
folderViewsSharedWithOthers,
folderViewsTrashOverviewExtensionPoint,
folderViewsFavoritesExtensionPoint,
folderViewsProjectSpacesExtensionPoint,
folderViewsFolderExtensionPoint
} from '../../../../src/extensionPoints'

vi.mock('../../../../src/composables')
vi.mock('@opencloud-eu/web-pkg', async (importOriginal) => ({
Expand Down Expand Up @@ -81,12 +88,40 @@ function getMountedWrapper({
files?: IncomingShareResource[]
loading?: boolean
} = {}) {
const plugins = [...defaultPlugins()]

vi.mocked(useResourcesViewDefaults).mockImplementation(() =>
useResourcesViewDefaultsMock({
paginatedResources: ref(files),
areResourcesLoading: ref(loading)
})
)

const extensions = [
{
id: 'com.github.opencloud-eu.web.files.folder-view.resource-table',
type: 'folderView',
extensionPointIds: [
folderViewsFolderExtensionPoint.id,
folderViewsProjectSpacesExtensionPoint.id,
folderViewsFavoritesExtensionPoint.id,
folderViewsTrashOverviewExtensionPoint.id,
folderViewsSharedWithOthers.id
],
folderView: {
name: 'resource-table',
label: 'Switch to default view',
icon: {
name: 'menu-line',
fillType: 'none'
},
component: ResourceTable
}
}
] satisfies FolderViewExtension[]
const { requestExtensions } = useExtensionRegistry()
vi.mocked(requestExtensions).mockReturnValue(extensions)

const defaultMocks = {
...defaultComponentMocks({
currentRoute: mock<RouteLocation>({ name: 'files-shares-with-others' })
Expand All @@ -98,7 +133,7 @@ function getMountedWrapper({
mocks: defaultMocks,
wrapper: mount(SharedWithOthers, {
global: {
plugins: [...defaultPlugins()],
plugins,
mocks: defaultMocks,
provide: defaultMocks,
stubs: { ...defaultStubs, ItemFilter: true }
Expand Down
3 changes: 2 additions & 1 deletion packages/web-pkg/src/components/FilesList/ResourceTile.vue
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@
:is-resource-clickable="isResourceClickable"
:is-path-displayed="isPathDisplayed"
:parent-folder-name="getParentFolderName(resource)"
:parent-folder-link="getParentFolderLink(resource)"
:link="resourceRoute"
@click.stop="$emit('click', $event)"
/>
Expand Down Expand Up @@ -163,7 +164,7 @@ defineSlots<{

const { toggleTile } = useToggleTile()
const { $gettext } = useGettext()
const { getParentFolderName } = useFolderLink()
const { getParentFolderName, getParentFolderLink } = useFolderLink()

const observerTarget = useTemplateRef<InstanceType<typeof OcCard>>('observerTarget')
const observerTargetElement = computed<HTMLElement>(() => unref(observerTarget)?.$el)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ exports[`OcTile component > renders default space correctly 1`] = `
<div class="p-2">
<div class="flex justify-between items-center">
<div class="flex items-center truncate resource-name-wrapper text-role-on-surface overflow-hidden">
<resource-list-item-stub resource="[object Object]" pathprefix="" ispathdisplayed="false" parentfoldername="." parentfolderlinkiconadditionalattributes="[object Object]" isextensiondisplayed="true" isthumbnaildisplayed="true" isicondisplayed="false" isresourceclickable="true"></resource-list-item-stub>
<resource-list-item-stub resource="[object Object]" pathprefix="" ispathdisplayed="false" parentfolderlink="[object Object]" parentfoldername="." parentfolderlinkiconadditionalattributes="[object Object]" isextensiondisplayed="true" isthumbnaildisplayed="true" isicondisplayed="false" isresourceclickable="true"></resource-list-item-stub>
</div>
<div class="flex items-center">
<!-- Slot for indicators !-->
Expand All @@ -37,7 +37,7 @@ exports[`OcTile component > renders disabled space correctly 1`] = `
<div class="p-2">
<div class="flex justify-between items-center">
<div class="flex items-center truncate resource-name-wrapper text-role-on-surface overflow-hidden">
<resource-list-item-stub resource="[object Object]" pathprefix="" ispathdisplayed="false" parentfoldername="." parentfolderlinkiconadditionalattributes="[object Object]" isextensiondisplayed="true" isthumbnaildisplayed="true" isicondisplayed="false" isresourceclickable="true"></resource-list-item-stub>
<resource-list-item-stub resource="[object Object]" pathprefix="" ispathdisplayed="false" parentfolderlink="[object Object]" parentfoldername="." parentfolderlinkiconadditionalattributes="[object Object]" isextensiondisplayed="true" isthumbnaildisplayed="true" isicondisplayed="false" isresourceclickable="true"></resource-list-item-stub>
</div>
<div class="flex items-center">
<!-- Slot for indicators !-->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Feature: profile photo

When "Alice" changes the profile image "testavatar.png"
Then "Alice" should have a profile picture

When "Alice" deletes the profile image
Then "Alice" should not have a profile picture
And "Alice" logs out
Expand All @@ -35,21 +35,22 @@ Feature: profile photo
| resource | recipient | type | role |
| sharedFolder | Brian | user | Can edit |
| sharedFolder | Carol | user | Can edit |

When "Alice" logs in
Then "Alice" should see the following recipients
| resource | recipient | hasAvatar |
| sharedFolder | Brian | true |
| sharedFolder | Carol | false |
And "Alice" should see "Brian" avatar for the resource "sharedFolder" in the activity panel
And "Alice" navigates to the shared with others page
And "Alice" switches to the "table" view
And "Alice" should see "recipient" avatar for the resource "sharedFolder"
And "Alice" should see the following recipients
| resource | recipient | hasAvatar |
| sharedFolder | Brian | true |
| sharedFolder | Carol | false |
And "Alice" logs out

When "Brian" logs in
Then "Brian" should see sharer avatar in the notification
And "Brian" navigates to the shared with me page
Expand Down