Skip to content

Commit 52942ef

Browse files
committed
fix breadcrumb
1 parent b09afff commit 52942ef

1 file changed

Lines changed: 92 additions & 63 deletions

File tree

  • apps/sim/app/workspace/[workspaceId]/files

apps/sim/app/workspace/[workspaceId]/files/files.tsx

Lines changed: 92 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,9 @@ const MIME_TYPE_LABELS: Record<string, string> = {
137137
'text/markdown': 'Markdown',
138138
}
139139

140+
const EMPTY_WORKSPACE_FILES: WorkspaceFileRecord[] = []
141+
const EMPTY_WORKSPACE_FILE_FOLDERS: WorkspaceFileFolderApi[] = []
142+
140143
const fileRowId = (id: string) => `file:${id}`
141144
const folderRowId = (id: string) => `folder:${id}`
142145
const parseRowId = (rowId: string): { kind: 'file' | 'folder'; id: string } => {
@@ -186,8 +189,9 @@ export function Files() {
186189
}
187190
}, [permissionConfig.hideFilesTab, router, workspaceId])
188191

189-
const { data: files = [], isLoading, error } = useWorkspaceFiles(workspaceId)
190-
const { data: folders = [], isLoading: foldersLoading } = useWorkspaceFileFolders(workspaceId)
192+
const { data: files = EMPTY_WORKSPACE_FILES, isLoading, error } = useWorkspaceFiles(workspaceId)
193+
const { data: folders = EMPTY_WORKSPACE_FILE_FOLDERS, isLoading: foldersLoading } =
194+
useWorkspaceFileFolders(workspaceId)
191195
const { data: members } = useWorkspaceMembersQuery(workspaceId)
192196
const uploadFile = useUploadWorkspaceFile()
193197
const deleteFile = useDeleteWorkspaceFile()
@@ -493,15 +497,17 @@ export function Files() {
493497
const visibleRowIds = useMemo(() => rows.map((row) => row.id), [rows])
494498

495499
const prevVisibleRowIdsRef = useRef(visibleRowIds)
496-
if (prevVisibleRowIdsRef.current !== visibleRowIds) {
500+
useEffect(() => {
501+
if (prevVisibleRowIdsRef.current === visibleRowIds) return
497502
prevVisibleRowIdsRef.current = visibleRowIds
498503
lastSelectedIndexRef.current = -1
499504
const visible = new Set(visibleRowIds)
500505
setSelectedRowIds((prev) => {
506+
if (prev.size === 0) return prev
501507
const next = new Set(Array.from(prev).filter((id) => visible.has(id)))
502508
return next.size === prev.size ? prev : next
503509
})
504-
}
510+
}, [visibleRowIds])
505511

506512
const isAllSelected =
507513
visibleRowIds.length > 0 && visibleRowIds.every((id) => selectedRowIds.has(id))
@@ -813,7 +819,6 @@ export function Files() {
813819
})
814820
.catch((error) => {
815821
logger.error('Failed to move items via drag and drop:', error)
816-
toast.error(toError(error).message)
817822
})
818823
},
819824
onDragEnd: () => {
@@ -931,23 +936,26 @@ export function Files() {
931936
isDirtyRef.current = isDirty
932937
const saveStatusRef = useRef(saveStatus)
933938
saveStatusRef.current = saveStatus
939+
const pendingFileNavigationUrlRef = useRef<string | null>(null)
934940

935941
const handleSave = useCallback(async () => {
936942
if (!saveRef.current || !isDirtyRef.current || saveStatusRef.current === 'saving') return
937943
await saveRef.current()
938944
}, [])
939945

940-
const handleBackAttempt = useCallback(() => {
941-
const backUrl = currentFolderId
942-
? `/workspace/${workspaceId}/files?folderId=${currentFolderId}`
943-
: `/workspace/${workspaceId}/files`
944-
if (isDirtyRef.current) {
945-
setShowUnsavedChangesAlert(true)
946-
} else {
946+
const handleNavigateFromFileDetail = useCallback(
947+
(url: string) => {
948+
if (isDirtyRef.current) {
949+
pendingFileNavigationUrlRef.current = url
950+
setShowUnsavedChangesAlert(true)
951+
return
952+
}
953+
947954
setPreviewMode('editor')
948-
router.push(backUrl)
949-
}
950-
}, [router, workspaceId, currentFolderId])
955+
router.push(url)
956+
},
957+
[router]
958+
)
951959

952960
const handleStartHeaderRename = useCallback(() => {
953961
const file = selectedFileRef.current
@@ -997,57 +1005,80 @@ export function Files() {
9971005
window.location.href = `/api/workspaces/${workspaceId}/files/download?${query.toString()}`
9981006
}, [selectedFileIds, selectedFolderIds, files, handleDownload, workspaceId])
9991007

1000-
const fileDetailBreadcrumbs = useMemo(
1001-
() =>
1002-
selectedFile
1003-
? [
1004-
{ label: 'Files', onClick: handleBackAttempt },
1005-
{
1006-
label: selectedFile.name,
1007-
editing: headerRename.editingId
1008-
? {
1009-
isEditing: true,
1010-
value: headerRename.editValue,
1011-
onChange: headerRename.setEditValue,
1012-
onSubmit: headerRename.submitRename,
1013-
onCancel: headerRename.cancelRename,
1014-
}
1015-
: undefined,
1016-
dropdownItems: [
1017-
{ label: 'Download', icon: Download, onClick: handleDownloadSelected },
1018-
...(canEdit
1019-
? [
1020-
{ label: 'Rename', icon: Pencil, onClick: handleStartHeaderRename },
1021-
{ label: 'Delete', icon: Trash2, onClick: handleDeleteSelected },
1022-
]
1023-
: []),
1024-
],
1025-
},
1026-
]
1027-
: [],
1028-
[
1029-
selectedFile,
1030-
canEdit,
1031-
handleBackAttempt,
1032-
headerRename.editingId,
1033-
headerRename.editValue,
1034-
handleStartHeaderRename,
1035-
handleDownloadSelected,
1036-
handleDeleteSelected,
1008+
const fileDetailBreadcrumbs = useMemo(() => {
1009+
if (!selectedFile) return []
1010+
1011+
const folderBreadcrumbs: BreadcrumbItem[] = []
1012+
const visitedFolderIds = new Set<string>()
1013+
let folderId = selectedFile.folderId
1014+
1015+
while (folderId && !visitedFolderIds.has(folderId)) {
1016+
visitedFolderIds.add(folderId)
1017+
const folder = folderById.get(folderId)
1018+
if (!folder) break
1019+
1020+
folderBreadcrumbs.unshift({
1021+
label: folder.name,
1022+
onClick: () =>
1023+
handleNavigateFromFileDetail(`/workspace/${workspaceId}/files?folderId=${folder.id}`),
1024+
})
1025+
folderId = folder.parentId
1026+
}
1027+
1028+
return [
1029+
{
1030+
label: 'Files',
1031+
onClick: () => handleNavigateFromFileDetail(`/workspace/${workspaceId}/files`),
1032+
},
1033+
...folderBreadcrumbs,
1034+
{
1035+
label: selectedFile.name,
1036+
editing: headerRename.editingId
1037+
? {
1038+
isEditing: true,
1039+
value: headerRename.editValue,
1040+
onChange: headerRename.setEditValue,
1041+
onSubmit: headerRename.submitRename,
1042+
onCancel: headerRename.cancelRename,
1043+
}
1044+
: undefined,
1045+
dropdownItems: [
1046+
{ label: 'Download', icon: Download, onClick: handleDownloadSelected },
1047+
...(canEdit
1048+
? [
1049+
{ label: 'Rename', icon: Pencil, onClick: handleStartHeaderRename },
1050+
{ label: 'Delete', icon: Trash2, onClick: handleDeleteSelected },
1051+
]
1052+
: []),
1053+
],
1054+
},
10371055
]
1038-
)
1056+
}, [
1057+
selectedFile,
1058+
folderById,
1059+
handleNavigateFromFileDetail,
1060+
workspaceId,
1061+
canEdit,
1062+
headerRename.editingId,
1063+
headerRename.editValue,
1064+
handleStartHeaderRename,
1065+
handleDownloadSelected,
1066+
handleDeleteSelected,
1067+
])
10391068

10401069
const handleDiscardChanges = () => {
10411070
setShowUnsavedChangesAlert(false)
10421071
setIsDirty(false)
10431072
setSaveStatus('idle')
10441073
setPreviewMode('editor')
10451074
const folderId = selectedFileRef.current?.folderId
1046-
router.push(
1047-
folderId
1075+
const targetUrl =
1076+
pendingFileNavigationUrlRef.current ??
1077+
(folderId
10481078
? `/workspace/${workspaceId}/files?folderId=${folderId}`
1049-
: `/workspace/${workspaceId}/files`
1050-
)
1079+
: `/workspace/${workspaceId}/files`)
1080+
pendingFileNavigationUrlRef.current = null
1081+
router.push(targetUrl)
10511082
}
10521083

10531084
const creatingFileRef = useRef(creatingFile)
@@ -1213,7 +1244,6 @@ export function Files() {
12131244
closeContextMenu()
12141245
} catch (error) {
12151246
logger.error('Failed to move items:', error)
1216-
toast.error(toError(error).message)
12171247
}
12181248
},
12191249
[workspaceId, selectedFileIds, selectedFolderIds, closeContextMenu]
@@ -1240,7 +1270,8 @@ export function Files() {
12401270
}, [canEdit, uploading, closeListContextMenu])
12411271

12421272
const prevFileIdRef = useRef(fileIdFromRoute)
1243-
if (fileIdFromRoute !== prevFileIdRef.current) {
1273+
useEffect(() => {
1274+
if (fileIdFromRoute === prevFileIdRef.current) return
12441275
prevFileIdRef.current = fileIdFromRoute
12451276
const isJustCreated =
12461277
isNewFile || (fileIdFromRoute != null && justCreatedFileIdRef.current === fileIdFromRoute)
@@ -1255,10 +1286,8 @@ export function Files() {
12551286
: null
12561287
return file && isPreviewable(file) ? 'preview' : 'editor'
12571288
})()
1258-
if (nextMode !== previewMode) {
1259-
setPreviewMode(nextMode)
1260-
}
1261-
}
1289+
setPreviewMode((current) => (nextMode === current ? current : nextMode))
1290+
}, [fileIdFromRoute, isNewFile])
12621291

12631292
useEffect(() => {
12641293
if (isNewFile && fileIdFromRoute) {

0 commit comments

Comments
 (0)