Skip to content

Commit

Permalink
wip: Fix breadcrumbs
Browse files Browse the repository at this point in the history
  • Loading branch information
dschmidt committed Sep 12, 2023
1 parent 8def550 commit fa973c3
Show file tree
Hide file tree
Showing 9 changed files with 123 additions and 72 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@
<script lang="ts">
import { defineComponent, PropType, computed, unref, ref, ComputedRef } from 'vue'
import { mapGetters, mapActions, mapState } from 'vuex'
import { basename, dirname } from 'path'
import { dirname } from 'path'
import { useWindowSize } from '@vueuse/core'
import { Resource } from 'web-client'
import {
Expand Down
2 changes: 1 addition & 1 deletion packages/web-app-files/src/components/Search/Preview.vue
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import { debounce } from 'lodash-es'
import { computed, defineComponent, PropType, ref, unref } from 'vue'
import { mapGetters } from 'vuex'
import { createLocationShares, createLocationSpaces } from '../../router'
import { basename, dirname } from 'path'
import { dirname } from 'path'
import { useCapabilityShareJailEnabled, useGetMatchingSpace } from 'web-pkg/src/composables'
import {
extractParentFolderName,
Expand Down
64 changes: 44 additions & 20 deletions packages/web-app-files/src/helpers/breadcrumbs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,33 +2,57 @@ import { eventBus } from 'web-pkg/src/services/eventBus'
import { RouteLocation } from 'vue-router'
import { BreadcrumbItem } from 'design-system/src/components/OcBreadcrumb/types'
import { v4 as uuidv4 } from 'uuid'
import { AncestorMetaData } from 'web-app-files/src/helpers/resource'
import omit from 'lodash-es/omit'
import { AncestorMetaData } from 'web-pkg/src/types'
import { join } from 'path'

export const breadcrumbsFromPath = (
export const breadcrumbsFor = (
currentRoute: RouteLocation,
resourceId: string,
resourcePath: string,
anbestorMetaData: AncestorMetaData
ancestorMetaData: AncestorMetaData
): BreadcrumbItem[] => {
// if the resource is no file id but a storageId we have no breadcrumbs
if (resourceId && !resourceId.includes('!')) {
return []
}

const pathSplit = (p = '') => p.split('/').filter(Boolean)
const current = pathSplit(currentRoute.path)
const resource = pathSplit(resourcePath)

return resource.map(
(text, i) =>
({
id: uuidv4(),
allowContextActions: true,
text,
...(i >= resource.length - Object.keys(anbestorMetaData).length && {
to: {
path: '/' + [...current].splice(0, current.length - resource.length + i + 1).join('/'),
query: omit(currentRoute.query, 'fileId', 'page') // TODO: we need the correct fileId in the query. until we have that we must omit it because otherwise we would correct the path to the one of the (wrong) fileId.
}
}),
isStaticNav: false
} as BreadcrumbItem)
)

const breadcrumbs = [] as BreadcrumbItem[]
let currentAncestorMetaDataValue
if (resourceId) {
currentAncestorMetaDataValue = ancestorMetaData[resourceId]
} else {
currentAncestorMetaDataValue = Object.values(ancestorMetaData).find((v) => {
return v.path === resourcePath
})
}

// FIXME: triggers flickering ...
if (!currentAncestorMetaDataValue) {
return []
}

const basePath =
'/' + current.slice(0, -pathSplit(currentAncestorMetaDataValue.path).length).join('/')
while (currentAncestorMetaDataValue && currentAncestorMetaDataValue.path !== '/') {
const item: BreadcrumbItem = {
id: uuidv4(),
allowContextActions: true,
text: currentAncestorMetaDataValue.name,
to: {
path: join(basePath, currentAncestorMetaDataValue.path),
query: { ...omit(currentRoute.query, 'page'), fileId: currentAncestorMetaDataValue.id }
},
isStaticNav: false
} as BreadcrumbItem
breadcrumbs.unshift(item)
currentAncestorMetaDataValue = ancestorMetaData[currentAncestorMetaDataValue.parentFolderId]
}

return breadcrumbs
}

export const concatBreadcrumbs = (...items: BreadcrumbItem[]): BreadcrumbItem[] => {
Expand Down
12 changes: 11 additions & 1 deletion packages/web-app-files/src/helpers/statusIndicators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,20 @@ export const getIndicators = ({
ancestorMetaData: AncestorMetaData
}) => {
const indicators = []
const parentShareTypes = Object.values(ancestorMetaData).reduce((acc: any, data: any) => {
let ancestor = ancestorMetaData[resource.parentFolderId]
const ancestors = []
while (ancestor && ancestor.parentFolderId !== ancestor.spaceId) {
ancestor = ancestorMetaData[ancestor.parentFolderId]
if (ancestor) {
ancestors.unshift(ancestor)
}
}

const parentShareTypes = ancestors.reduce((acc: any, data: any) => {
acc.push(...(data.shareTypes || []))
return acc
}, [])

const isDirectUserShare = isUserShare(resource.shareTypes)
if (isDirectUserShare || isUserShare(parentShareTypes)) {
indicators.push(getUserIndicator({ resource, isDirect: isDirectUserShare }))
Expand Down
32 changes: 19 additions & 13 deletions packages/web-app-files/src/services/folder/loaderSpace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,22 @@ export class FolderLoaderSpace implements FolderLoader {
store.commit('Files/CLEAR_CURRENT_FILES_LIST')

let { resource: currentFolder, children: resources } = yield webdav.listFiles(space, {
fileId
fileId,
path
})

const mountPoint = store.getters['runtime/spaces/spaces'].find(
(s) => isMountPointSpaceResource(s) && path.startsWith(s.root.remoteItem.path)
)
currentFolder.path = path

// space
const mountPoint = store.getters['runtime/spaces/spaces'].find((s) => {
return (
isMountPointSpaceResource(s) &&
(s.root.remoteItem as any).rootId === currentFolder.storageId &&
path.startsWith(s.root.remoteItem.path)
)
})

// FIXME: does this still work / have effect?!
if (mountPoint && !configurationManager.options.routing.fullShareOwnerPaths) {
currentFolder.path = mountPoint.root.remoteItem.path
const hiddenPath = currentFolder.path.split('/').slice(0, -1).join('/')
Expand All @@ -62,17 +72,13 @@ export class FolderLoaderSpace implements FolderLoader {
r.path = urlJoin(path, r.path)
r.visiblePath = r.path.replace(`/${hiddenPath}`, '')
})
} else {
currentFolder.path = path
resources.forEach((r) => {
r.path = urlJoin(path, r.path)
})
}

// if current folder has no id (= singe file public link) we must not correct the route
if (currentFolder.id) {
yield replaceInvalidFileRoute({ space, resource: currentFolder, path, fileId })
}
// // if current folder has no id (= singe file public link) we must not correct the route
// if (currentFolder.id) {
// console.log('currentFolder.id', currentFolder.id)
// yield replaceInvalidFileRoute({ space, resource: currentFolder, path, fileId })
// }

if (path === '/') {
if (space.driveType === 'share') {
Expand Down
4 changes: 2 additions & 2 deletions packages/web-app-files/src/store/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ export default {
commit(
'runtime/ancestorMetaData/UPDATE_ANCESTOR_FIELD',
{
path: ancestorEntry.path,
id: ancestorEntry.id,
field: 'shareTypes',
value: computeShareTypes(state.outgoingShares.filter((s) => !s.indirect))
},
Expand Down Expand Up @@ -460,7 +460,7 @@ export default {
commit(
'runtime/ancestorMetaData/UPDATE_ANCESTOR_FIELD',
{
path: ancestor.path,
id: ancestor.id,
field: 'shareTypes',
value: [...shareTypes, ShareTypes.link.value]
},
Expand Down
23 changes: 9 additions & 14 deletions packages/web-app-files/src/views/spaces/GenericSpace.vue
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ import { ImageType } from 'web-pkg/src/constants'
import { VisibilityObserver } from 'web-pkg/src/observer'
import { createFileRouteOptions } from 'web-pkg/src/helpers/router'
import { eventBus } from 'web-pkg/src/services/eventBus'
import { breadcrumbsFromPath, concatBreadcrumbs } from '../../helpers/breadcrumbs'
import { breadcrumbsFor, breadcrumbsFromPath, concatBreadcrumbs } from '../../helpers/breadcrumbs'
import { createLocationPublic, createLocationSpaces } from '../../router'
import { useResourcesViewDefaults } from '../../composables'
import { AncestorMetaData, ResourceTransfer, TransferType } from '../../helpers/resource'
Expand Down Expand Up @@ -346,17 +346,6 @@ export default defineComponent({
})
})
}
} else if (isMountPointSpaceResource(space)) {
// FIXME: Remove?
spaceBreadcrumbItem = {
id: uuidv4(),
allowContextActions: true,
text: space.driveAlias.split('/')[1],
to: createLocationSpaces('files-spaces-generic', {
params,
query: omit(query, 'fileId')
})
}
} else if (isPublicSpaceResource(space)) {
spaceBreadcrumbItem = {
id: uuidv4(),
Expand All @@ -379,12 +368,18 @@ export default defineComponent({
}
}
return concatBreadcrumbs(
const concatted = concatBreadcrumbs(
...rootBreadcrumbItems,
spaceBreadcrumbItem,
// FIXME: needs file ids for each parent folder path
...breadcrumbsFromPath(unref(route), props.item, unref(ancestorMetaData))
...breadcrumbsFor(
unref(route),
props.itemId?.toString(),
props.item,
unref(ancestorMetaData)
)
)
return concatted
})
const focusAndAnnounceBreadcrumb = (sameRoute) => {
Expand Down
4 changes: 2 additions & 2 deletions packages/web-pkg/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ export interface AncestorMetaDataValue {
id: string
shareTypes: number[]
parentFolderId: string
spaceId: string
path?: string // TODO: remove?
path: string
name: string
spaceId: string
}

export type AncestorMetaData = Record<string, AncestorMetaDataValue>
52 changes: 34 additions & 18 deletions packages/web-runtime/src/store/ancestorMetaData.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { join } from 'path'
import { SpaceResource } from 'web-client/src'
import { WebDAV } from 'web-client/src/webdav'
import { DavProperty } from 'web-client/src/webdav/constants'
import { getParentPaths } from 'web-pkg/src/helpers/path'
import { AncestorMetaData } from 'web-pkg/src/types'

const state = {
Expand All @@ -20,7 +20,7 @@ const mutations = {
},

UPDATE_ANCESTOR_FIELD(state, params) {
const resource = state.ancestorMetaData[params.path] ?? null
const resource = state.ancestorMetaData[params.id] ?? null
if (resource) {
resource[params.field] = params.value
}
Expand All @@ -37,49 +37,65 @@ const actions = {
fileId
}: { space: SpaceResource; path: string; client: WebDAV; fileId: string }
) {
const ancestorMetaData: AncestorMetaData = {}
const davProperties = [
DavProperty.FileId,
DavProperty.ShareTypes,
DavProperty.FileParent,
DavProperty.Name
]

const addAncestor = async (fileId: string) => {
const loadMetaDataValue = async (fileId: string) => {
const { resource } = await client.listFiles(
space,
{ fileId, path },
{
...(fileId && { fileId }),
...(!fileId && path && { path })
},
{ depth: 0, davProperties }
)
ancestorMetaData[resource.fileId] = {
const value = {
id: resource.fileId,
shareTypes: resource.shareTypes,
parentFolderId: resource.parentFolderId,
spaceId: space.id.toString(),
name: resource.name
name: resource.name,
path: ''
}
return resource
ancestorMetaData[resource.fileId] = value
return value
}

let resource = await addAncestor(fileId)
while (resource.parentFolderId && resource.parentFolderId !== resource.storageId) {
const cachedData = state.ancestorMetaData[resource.parentFolderId]
// TODO: still need the space check?
if (cachedData?.spaceId === space.id) {
ancestorMetaData[resource.parentFolderId] = cachedData
const ancestorMetaData: AncestorMetaData = {}

let value = await loadMetaDataValue(fileId)
const ancestorList = [value]
while (value.parentFolderId !== value.spaceId) {
const cachedData = (state.ancestorMetaData as AncestorMetaData)[value.parentFolderId]
// FIXME: checking for Boolean(cachedData) should be enough, space id should be contained in the file/folder id
if (cachedData && cachedData?.spaceId === space.id) {
ancestorMetaData[value.parentFolderId] = cachedData
ancestorList.unshift(value)
value = cachedData
continue
}
const oldResource = resource

const lastValue = value
try {
resource = await addAncestor(resource.parentFolderId)
value = await loadMetaDataValue(value.parentFolderId)
ancestorMetaData[value.parentFolderId] = cachedData
ancestorList.unshift(value)
} catch (e) {
console.error(e)
ancestorMetaData[oldResource.fileId].parentFolderId = null
ancestorMetaData[lastValue.id].parentFolderId = null
break
}
}

console.log('ancestorMetaData', ancestorMetaData)
ancestorList[0].path = `/`
for (let i = 1; i < ancestorList.length; i++) {
ancestorList[i].path = join(ancestorList[i - 1].path, ancestorList[i].name)
}

commit('SET_ANCESTOR_META_DATA', ancestorMetaData)
}
}
Expand Down

0 comments on commit fa973c3

Please sign in to comment.