diff --git a/packages/web-app-files/src/components/SideBar/Details/FileDetails.vue b/packages/web-app-files/src/components/SideBar/Details/FileDetails.vue
index 526f4fc7ef2..146c86142b5 100644
--- a/packages/web-app-files/src/components/SideBar/Details/FileDetails.vue
+++ b/packages/web-app-files/src/components/SideBar/Details/FileDetails.vue
@@ -74,9 +74,6 @@
{{ ownerDisplayName }}
(me)
- ({{ ownerAdditionalInfo }})
@@ -326,14 +323,7 @@ export default defineComponent({
return this.resource.mdate?.length > 0
},
ownerDisplayName() {
- return (
- this.resource.ownerDisplayName ||
- this.resource.shareOwnerDisplayname ||
- this.resource.owner?.[0].displayName
- )
- },
- ownerAdditionalInfo() {
- return this.resource.owner?.[0].additionalInfo
+ return this.resource.owner?.displayName
},
resourceSize() {
return formatFileSize(this.resource.size, this.$language.current)
@@ -362,17 +352,13 @@ export default defineComponent({
)
},
ownedByCurrentUser() {
- return (
- this.resource.ownerId === this.user?.onPremisesSamAccountName ||
- this.resource.owner?.[0].username === this.user?.onPremisesSamAccountName ||
- this.resource.shareOwner === this.user?.onPremisesSamAccountName
- )
+ return this.resource.owner?.id === this.user?.onPremisesSamAccountName
},
shareIndicators() {
return getIndicators({ resource: this.resource, ancestorMetaData: this.ancestorMetaData })
},
sharedByDisplayName() {
- return this.resource.share?.fileOwner?.displayName
+ return this.resource.sharedBy?.displayName
}
},
methods: {
diff --git a/packages/web-app-files/src/services/folder/loaderSharedWithMe.ts b/packages/web-app-files/src/services/folder/loaderSharedWithMe.ts
index 8ee2231cf07..13164ca794d 100644
--- a/packages/web-app-files/src/services/folder/loaderSharedWithMe.ts
+++ b/packages/web-app-files/src/services/folder/loaderSharedWithMe.ts
@@ -1,7 +1,7 @@
import { FolderLoader, FolderLoaderTask, TaskContext } from '../folder'
import { Router } from 'vue-router'
import { useTask } from 'vue-concurrency'
-import { aggregateResourceShares } from '@ownclouders/web-client/src/helpers/share'
+import { aggregateResourceShares } from '@ownclouders/web-client/src/helpers/share/functionsNG'
import { isLocationSharesActive } from '@ownclouders/web-pkg'
export class FolderLoaderSharedWithMe implements FolderLoader {
@@ -14,8 +14,7 @@ export class FolderLoaderSharedWithMe implements FolderLoader {
}
public getTask(context: TaskContext): FolderLoaderTask {
- const { userStore, spacesStore, clientService, configStore, capabilityStore, resourcesStore } =
- context
+ const { spacesStore, clientService, configStore, capabilityStore, resourcesStore } = context
// eslint-disable-next-line @typescript-eslint/no-unused-vars
return useTask(function* (signal1, signal2) {
@@ -26,31 +25,17 @@ export class FolderLoaderSharedWithMe implements FolderLoader {
yield spacesStore.loadMountPoints({ graphClient: clientService.graphAuthenticated })
}
- let resources = yield clientService.owncloudSdk.shares.getShares('', {
- state: 'all',
- include_tags: false,
- shared_with_me: true,
- show_hidden: true
- })
+ const {
+ data: { value }
+ } = yield clientService.graphAuthenticated.drives.listSharedWithMe()
- resources = resources.map((r) => r.shareInfo)
-
- if (resources.length) {
- resources = aggregateResourceShares({
- shares: resources,
- spaces: spacesStore.spaces,
- incomingShares: true,
- allowSharePermission: capabilityStore.sharingResharing,
- hasShareJail: capabilityStore.spacesShareJail,
- fullShareOwnerPaths: configStore.options.routing.fullShareOwnerPaths
- }).map((resource) => {
- // info: in oc10 we have no storageId in resources. All resources are mounted into the personal space.
- if (!resource.storageId) {
- resource.storageId = userStore.user.onPremisesSamAccountName
- }
- return resource
- })
- }
+ const resources = aggregateResourceShares({
+ driveItems: value,
+ spaces: spacesStore.spaces,
+ incomingShares: true,
+ allowSharePermission: capabilityStore.sharingResharing,
+ fullShareOwnerPaths: configStore.options.routing.fullShareOwnerPaths
+ })
resourcesStore.initResourceList({ currentFolder: null, resources })
})
diff --git a/packages/web-app-files/src/views/shares/SharedWithMe.vue b/packages/web-app-files/src/views/shares/SharedWithMe.vue
index 4cf16c774f0..3fb1591d168 100644
--- a/packages/web-app-files/src/views/shares/SharedWithMe.vue
+++ b/packages/web-app-files/src/views/shares/SharedWithMe.vue
@@ -45,13 +45,13 @@
:items="fileOwners"
:option-filter-label="$gettext('Filter shared by')"
:show-option-filter="true"
- id-attribute="username"
+ id-attribute="id"
class="shared-by-filter oc-ml-s"
display-name-attribute="displayName"
filter-name="sharedBy"
>
-
+
@@ -109,7 +109,6 @@ import { AppBar, ItemFilterInline } from '@ownclouders/web-pkg'
import { queryItemAsString, useRouteQuery } from '@ownclouders/web-pkg'
import SharedWithMeSection from '../../components/Shares/SharedWithMeSection.vue'
import { computed, defineComponent, onMounted, ref, unref, watch } from 'vue'
-import { Resource } from '@ownclouders/web-client'
import FilesViewWrapper from '../../components/FilesViewWrapper.vue'
import { useGetMatchingSpace, useSort } from '@ownclouders/web-pkg'
import { useGroupingSettings } from '@ownclouders/web-pkg'
@@ -147,7 +146,7 @@ export default defineComponent({
isSideBarOpen,
storeItems,
scrollToResourceFromRoute
- } = useResourcesViewDefaults()
+ } = useResourcesViewDefaults()
const { $gettext } = useGettext()
@@ -182,16 +181,14 @@ export default defineComponent({
const selectedShareTypes = queryItemAsString(unref(selectedShareTypesQuery))?.split('+')
if (selectedShareTypes?.length) {
- result = result.filter(({ share }) => {
- return selectedShareTypes.map((t) => ShareTypes[t].value).includes(share.shareType)
+ result = result.filter(({ shareType }) => {
+ return selectedShareTypes.map((t) => ShareTypes[t].value).includes(shareType)
})
}
const selectedSharedBy = queryItemAsString(unref(selectedSharedByQuery))?.split('+')
if (selectedSharedBy?.length) {
- result = result.filter(({ owner }) =>
- owner.some(({ username }) => selectedSharedBy.includes(username))
- )
+ result = result.filter(({ owner }) => selectedSharedBy.includes(owner.id))
}
if (unref(filterTerm).trim()) {
@@ -247,15 +244,15 @@ export default defineComponent({
}
const shareTypes = computed(() => {
- const uniqueShareTypes = uniq(unref(storeItems).map((i) => i.share?.shareType))
+ const uniqueShareTypes = uniq(unref(storeItems).map((i) => i.shareType))
return ShareTypes.getByValues(uniqueShareTypes)
})
const fileOwners = computed(() => {
const flatList = unref(storeItems)
- .map((i) => i.owner)
+ .map((i) => i.sharedBy)
.flat()
- return [...new Map(flatList.map((item) => [item.username, item])).values()]
+ return [...new Map(flatList.map((item) => [item.displayName, item])).values()]
})
onMounted(() => {
diff --git a/packages/web-client/src/graph.ts b/packages/web-client/src/graph.ts
index 27c8591bcc0..640c905c01f 100644
--- a/packages/web-client/src/graph.ts
+++ b/packages/web-client/src/graph.ts
@@ -24,7 +24,9 @@ import {
ApplicationsApiFactory,
UserAppRoleAssignmentApiFactory,
AppRoleAssignment,
- ExportPersonalDataRequest
+ ExportPersonalDataRequest,
+ MeDriveApiFactory,
+ DriveItem
} from './generated'
export interface Graph {
@@ -39,6 +41,8 @@ export interface Graph {
drives: {
listMyDrives: (orderBy?: string, filter?: string) => Promise>
listAllDrives: (orderBy?: string, filter?: string) => Promise>
+ listSharedWithMe: () => AxiosPromise<{ data: { value: DriveItem[] } }>
+ listSharedByMe: () => AxiosPromise<{ data: { value: DriveItem[] } }>
getDrive: (id: string) => AxiosPromise
createDrive: (drive: Drive, options: any) => AxiosPromise
updateDrive: (id: string, drive: Drive, options: any) => AxiosPromise
@@ -84,6 +88,7 @@ export const graph = (baseURI: string, axiosClient: AxiosInstance): Graph => {
const meDrivesApi = new MeDrivesApi(config, config.basePath, axiosClient)
const allDrivesApi = new DrivesGetDrivesApi(config, config.basePath, axiosClient)
const meUserApiFactory = MeUserApiFactory(config, config.basePath, axiosClient)
+ const meDriveApiFactory = MeDriveApiFactory(config, config.basePath, axiosClient)
const meChangepasswordApiFactory = MeChangepasswordApiFactory(
config,
config.basePath,
@@ -117,6 +122,8 @@ export const graph = (baseURI: string, axiosClient: AxiosInstance): Graph => {
meDrivesApi.listMyDrives(orderBy, filter),
listAllDrives: (orderBy?: string, filter?: string) =>
allDrivesApi.listAllDrives(orderBy, filter),
+ listSharedWithMe: () => meDriveApiFactory.listSharedWithMe(),
+ listSharedByMe: () => meDriveApiFactory.listSharedByMe(),
getDrive: (id: string) => drivesApiFactory.getDrive(id),
createDrive: (drive: Drive, options: any): AxiosPromise =>
drivesApiFactory.createDrive(drive, options),
diff --git a/packages/web-client/src/helpers/resource/functions.ts b/packages/web-client/src/helpers/resource/functions.ts
index 9d9126d8b72..73eb3a8d54a 100644
--- a/packages/web-client/src/helpers/resource/functions.ts
+++ b/packages/web-client/src/helpers/resource/functions.ts
@@ -134,14 +134,15 @@ export function buildResource(resource: WebDavResponseResource): Resource {
permissions: resource.props[DavProperty.Permissions] || '',
starred: resource.props[DavProperty.IsFavorite] !== 0,
etag: resource.props[DavProperty.ETag],
- sharePermissions: resource.props[DavProperty.SharePermissions],
shareTypes,
privateLink: resource.props[DavProperty.PrivateLink],
downloadURL: resource.props[DavProperty.DownloadURL],
shareId: resource.props[DavProperty.ShareId],
shareRoot: resource.props[DavProperty.ShareRoot],
- ownerId: resource.props[DavProperty.OwnerId],
- ownerDisplayName: resource.props[DavProperty.OwnerDisplayName],
+ owner: {
+ id: resource.props[DavProperty.OwnerId],
+ displayName: resource.props[DavProperty.OwnerDisplayName]
+ },
tags: (resource.props[DavProperty.Tags] || '').split(',').filter(Boolean),
audio: resource.props[DavProperty.Audio],
location: resource.props[DavProperty.Location],
diff --git a/packages/web-client/src/helpers/resource/types.ts b/packages/web-client/src/helpers/resource/types.ts
index 3abf7e07c76..94706febb2e 100644
--- a/packages/web-client/src/helpers/resource/types.ts
+++ b/packages/web-client/src/helpers/resource/types.ts
@@ -1,6 +1,5 @@
import { DavFileInfoResponse } from '@ownclouders/web-client/src/webdav/constants'
-import { User } from '../../generated'
-import { User as LegacyUser } from '../user'
+import { Identity, User } from '../../generated'
import { MongoAbility, SubjectRawRule } from '@casl/ability'
import { DAVResultResponseProps, FileStat } from 'webdav'
import { Audio, GeoCoordinates } from '../../generated'
@@ -58,7 +57,6 @@ export interface Resource {
downloadURL?: string
type?: string
thumbnail?: string
- status?: number
processing?: boolean
locked?: boolean
lockOwnerName?: string
@@ -78,7 +76,6 @@ export interface Resource {
permissions?: string
starred?: boolean
etag?: string
- sharePermissions?: number | string // FIXME
shareId?: string
shareRoot?: string
shareTypes?: number[]
@@ -86,6 +83,10 @@ export interface Resource {
description?: string
driveType?: 'mountpoint' | 'personal' | 'project' | 'share' | 'public' | (string & unknown)
driveAlias?: string
+ matchingSpace?: any
+ owner?: Identity
+ extension?: string
+ ddate?: string
canCreate?(): boolean
canUpload?({ user }: { user?: User }): boolean
@@ -106,27 +107,17 @@ export interface Resource {
canEditTags?(): boolean
isReceivedShare?(): boolean
-
isShareRoot?(): boolean
-
isMounted?(): boolean
getDomSelector?(): string
- matchingSpace?: any
-
- resourceOwner?: LegacyUser
- owner?: LegacyUser[]
- ownerDisplayName?: string
- ownerId?: string
- sharedWith?: string
- shareOwner?: string
- shareOwnerDisplayname?: string
- hidden?: boolean
- extension?: string
- share?: any
-
- ddate?: string
+ share?: any // FIXME: type: DriveItem & move to ShareResource OR remove?!
+ status?: number //FIXME: remove?
+ sharedWith?: Identity[] // FIXME: move to ShareResource
+ sharedBy?: Identity // FIXME: move to ShareResource
+ shareType?: number // FIXME: move to ShareResource
+ hidden?: boolean // FIXME: move to ShareResource
}
// These interfaces have empty (unused) __${type}SpaceResource properties which are only
diff --git a/packages/web-client/src/helpers/share/functions.ts b/packages/web-client/src/helpers/share/functions.ts
index 45978aaca7d..9baf7751487 100644
--- a/packages/web-client/src/helpers/share/functions.ts
+++ b/packages/web-client/src/helpers/share/functions.ts
@@ -157,23 +157,21 @@ export function buildSharedResource(
tags: [],
path: undefined,
webDavPath: undefined,
- processing: share.processing || false
+ processing: share.processing || false,
+ shareType: parseInt(share.share_type),
+ sharedBy: { id: share.uid_owner, displayName: share.displayname_owner },
+ sharedWith: (share.sharedWith || []).map((s) => ({
+ id: s.username,
+ displayName: s.displayName
+ }))
}
if (incomingShares) {
- resource.resourceOwner = {
- username: share.uid_file_owner as string,
- displayName: share.displayname_file_owner as string
+ resource.owner = {
+ id: share.uid_file_owner,
+ displayName: share.displayname_file_owner
}
- resource.owner = [
- {
- username: share.uid_owner as string,
- displayName: share.displayname_owner as string,
- avatar: undefined,
- shareType: ShareTypes.user.value
- }
- ]
- resource.sharedWith = share.sharedWith || []
+
resource.status = parseInt(share.state)
resource.hidden = share.hidden === 'true' || share.hidden === true
resource.name = isRemoteShare ? share.name : path.basename(share.file_target)
@@ -197,9 +195,6 @@ export function buildSharedResource(
parseInt(share.state) === ShareStatus.accepted &&
SharePermissions.update.enabled(share.permissions)
} else {
- resource.sharedWith = share.sharedWith || []
- resource.shareOwner = share.uid_owner
- resource.shareOwnerDisplayname = share.displayname_owner
resource.name = isRemoteShare ? share.name : path.basename(share.path)
resource.path = share.path
resource.webDavPath = hasShareJail
diff --git a/packages/web-client/src/helpers/share/functionsNG.ts b/packages/web-client/src/helpers/share/functionsNG.ts
new file mode 100644
index 00000000000..3e789644648
--- /dev/null
+++ b/packages/web-client/src/helpers/share/functionsNG.ts
@@ -0,0 +1,78 @@
+import { extractDomSelector, extractExtensionFromFile, extractStorageId } from '../resource'
+import { ShareTypes } from './type'
+import { SHARE_JAIL_ID, SpaceResource, buildWebDavSpacesPath } from '../space'
+import { ShareStatus } from './status'
+import { DriveItem } from '../../generated'
+import { ShareResource } from './types'
+
+export function aggregateResourceShares({
+ driveItems,
+ spaces,
+ allowSharePermission = true,
+ incomingShares = false,
+ fullShareOwnerPaths = false
+}: {
+ driveItems: DriveItem[]
+ spaces: SpaceResource[]
+ allowSharePermission?: boolean
+ incomingShares?: boolean
+ fullShareOwnerPaths?: boolean
+}): ShareResource[] {
+ if (incomingShares) {
+ return driveItems.map((driveItem) => {
+ return buildIncomingShareResource({ driveItem })
+ })
+ }
+
+ // TODO: outgoing shares
+ return []
+}
+
+export function buildIncomingShareResource({ driveItem }: { driveItem: DriveItem }): ShareResource {
+ const resourceName = driveItem.name || driveItem.remoteItem.name
+ const storageId = extractStorageId(driveItem.remoteItem.id)
+ const permission = driveItem.remoteItem?.permissions[0]
+ const id = permission?.id || driveItem.id
+
+ const resource: ShareResource = {
+ id,
+ shareId: id,
+ path: '/',
+ name: resourceName,
+ fileId: driveItem.remoteItem.id,
+ storageId,
+ parentFolderId: driveItem.parentReference?.id,
+ sdate: driveItem.remoteItem.shared.sharedDateTime,
+ indicators: [],
+ tags: [],
+ webDavPath: buildWebDavSpacesPath([SHARE_JAIL_ID, id].join('!'), '/'),
+ sharedBy: driveItem.remoteItem.createdBy.user,
+ owner: driveItem.remoteItem.shared.owner.user,
+ sharedWith: [
+ permission?.grantedToV2.group ? permission.grantedToV2.group : permission?.grantedToV2.user
+ ],
+ shareType: permission?.grantedToV2.group ? ShareTypes.group.value : ShareTypes.user.value,
+ share: driveItem,
+ isFolder: !!driveItem.remoteItem.folder,
+ type: !!driveItem.remoteItem.folder ? 'folder' : 'file',
+ mimeType: driveItem.remoteItem.file?.mimeType || 'httpd/unix-directory',
+ status: permission?.['@client.synchronize'] ? ShareStatus.accepted : ShareStatus.declined,
+ syncEnabled: permission?.['@client.synchronize'],
+ hidden: permission?.['@ui.hidden'],
+ canDownload: () => true,
+ canShare: () => true, // FIXME
+ canRename: () => true, // FIXME
+ canUpload: () => true, // FIXME
+ canCreate: () => true, // FIXME
+ canDeny: () => true, // FIXME
+ canBeDeleted: () => true, // FIXME
+ canEditTags: () => true,
+ isMounted: () => false,
+ isReceivedShare: () => true,
+ getDomSelector: () => extractDomSelector(id)
+ }
+
+ resource.extension = extractExtensionFromFile(resource)
+
+ return resource
+}
diff --git a/packages/web-client/src/helpers/share/index.ts b/packages/web-client/src/helpers/share/index.ts
index 05ef5a916fa..e7c182b7f4f 100644
--- a/packages/web-client/src/helpers/share/index.ts
+++ b/packages/web-client/src/helpers/share/index.ts
@@ -6,3 +6,4 @@ export * from './share'
export * from './space'
export * from './status'
export * from './type'
+export * from './types'
diff --git a/packages/web-client/src/helpers/share/types.ts b/packages/web-client/src/helpers/share/types.ts
new file mode 100644
index 00000000000..52785f0d70a
--- /dev/null
+++ b/packages/web-client/src/helpers/share/types.ts
@@ -0,0 +1,5 @@
+import { Resource } from '../resource'
+
+export interface ShareResource extends Resource {
+ syncEnabled?: boolean
+}
diff --git a/packages/web-client/src/helpers/space/functions.ts b/packages/web-client/src/helpers/space/functions.ts
index 2d89069165e..ea12f086bbd 100644
--- a/packages/web-client/src/helpers/space/functions.ts
+++ b/packages/web-client/src/helpers/space/functions.ts
@@ -204,14 +204,12 @@ export function buildSpace(
starred: false,
etag: '',
shareId: data.shareId?.toString(),
- sharePermissions: '',
shareTypes: (function () {
return []
})(),
privateLink: '',
downloadURL: '',
- ownerDisplayName: '',
- ownerId: data.owner?.user?.id,
+ owner: data.owner?.user,
disabled,
root: data.root,
spaceQuota: data.quota,
@@ -292,7 +290,7 @@ export function buildSpace(
return this.isViewer(user) || this.isEditor(user) || this.isManager(user)
},
isOwner({ id }: User): boolean {
- return id === this.ownerId
+ return id === this.owner?.id
}
}
Object.defineProperty(s, 'nodeId', {
diff --git a/packages/web-pkg/src/components/FilesList/ResourceTable.vue b/packages/web-pkg/src/components/FilesList/ResourceTable.vue
index 3962a1728f5..b0892748362 100644
--- a/packages/web-pkg/src/components/FilesList/ResourceTable.vue
+++ b/packages/web-pkg/src/components/FilesList/ResourceTable.vue
@@ -175,11 +175,11 @@
-
@@ -187,7 +187,7 @@
!u.link).length
- const linkCount = resource.sharedWith.filter((u) => !!u.link).length
+
+ const count = resource.sharedWith.length
+
+ if (resource.shareType === ShareTypes.link.value) {
+ const linkText =
+ count > 0
+ ? this.$ngettext(
+ 'This %{ resourceType } is shared via %{ count } link',
+ 'This %{ resourceType } is shared via %{ count } links',
+ count
+ )
+ : ''
+
+ return this.$gettext(linkText, {
+ resourceType,
+ count: count.toString()
+ })
+ }
+
const shareText =
- shareCount > 0
+ count > 0
? this.$ngettext(
- 'This %{ resourceType } is shared via %{ shareCount } invite',
- 'This %{ resourceType } is shared via %{ shareCount } invites',
- shareCount
+ 'This %{ resourceType } is shared via %{ count } invite',
+ 'This %{ resourceType } is shared via %{ count } invites',
+ count
)
: ''
- const linkText =
- linkCount > 0
- ? this.$ngettext(
- 'This %{ resourceType } is shared via %{ linkCount } link',
- 'This %{ resourceType } is shared via %{ linkCount } links',
- linkCount
- )
- : ''
- const description = [shareText, linkText].join(' ')
- return this.$gettext(description, {
+
+ return this.$gettext(shareText, {
resourceType,
- shareCount,
- linkCount
+ count: count.toString()
})
},
getOwnerAvatarDescription(resource: Resource) {
@@ -1047,8 +1056,16 @@ export default defineComponent({
resource.type === 'folder' ? this.$gettext('folder') : this.$gettext('file')
return this.$gettext('This %{ resourceType } is owned by %{ ownerName }', {
resourceType,
- ownerName: resource.owner[0].displayName
+ ownerName: resource.owner.displayName
})
+ },
+ getSharedWithItems(resource: Resource) {
+ return resource.sharedWith.map((s) => ({
+ displayName: s.displayName,
+ name: s.displayName,
+ shareType: resource.shareType,
+ username: s.id
+ }))
}
}
})
diff --git a/packages/web-pkg/src/helpers/share/triggerShareAction.ts b/packages/web-pkg/src/helpers/share/triggerShareAction.ts
index 9eb33b7a18d..3a08e5dffdd 100644
--- a/packages/web-pkg/src/helpers/share/triggerShareAction.ts
+++ b/packages/web-pkg/src/helpers/share/triggerShareAction.ts
@@ -27,7 +27,7 @@ export async function triggerShareAction({
throw new Error('invalid new share status')
}
- let action = `api/v1/shares/pending/${resource.share.id}`
+ let action = `api/v1/shares/pending/${resource.shareId}`
if (hidden !== undefined) {
action += `?hidden=${hidden ? 'true' : 'false'}`
}