-
-
-
- {commitSummary.last_commit.author_name}
- {commitSummary.last_commit.message}
-
-
- {commitSummary.last_commit.short_hash} • {timeAgo(commitSummary.last_commit.committed_at)}
-
-
-
- {commitSummary.total_commits} commits
-
-
- )}
-
- {/* Three-column layout: left tree, middle directory listing, right preview */}
-
-
- {
- // Update center panel with this directory contents
- setSelectedDir(dirPath)
- try {
- const res = await getRepositoryStructure(repositoryId, dirPath)
- setDirEntries(res?.structure || [])
- } catch {
- setDirEntries([])
- }
- }}
- onSelectFile={async (filePath) => {
- setSelectedFile(filePath)
- try {
- setPreviewLoading(true)
- const file = await getRepositoryFileContent(repositoryId, filePath)
- setPreviewContent(file?.content || null)
- } finally {
- setPreviewLoading(false)
- }
- }}
- />
-
- {/* Middle: Directory listing */}
-
-
- Folder
- {selectedDir || "/"}
-
-
- {dirEntries.length === 0 && (
-
Select a folder from the tree.
- )}
- {dirEntries.map((e, i) => {
- const rawPath = (e as any).path || (e as any).relative_path || ''
- const displayName = (e as any).name || (e as any).filename || (rawPath ? rawPath.split('/').slice(-1)[0] : '(unknown)')
- const typeVal = (e as any).type || (e as any).entry_type
- const isDirHint = typeVal === 'directory' || typeVal === 'dir' || (e as any).is_directory === true || (e as any).isDir === true
- // heuristic fallback if type missing: no dot in last segment often means folder
- const isDir = isDirHint || (!!displayName && !displayName.includes('.'))
- return (
-
{
- const relPath = (e as any).path || (e as any).relative_path || displayName
- if (isDir) {
- // drill down in tree and center
- setSelectedDir(relPath)
- try {
- const res = await getRepositoryStructure(repositoryId, relPath)
- setDirEntries(res?.structure || [])
- } catch {
- setDirEntries([])
- }
- return
- }
- // file
- setSelectedFile(relPath)
- try {
- setPreviewLoading(true)
- let file = await getRepositoryFileContent(repositoryId, relPath)
- // if backend still reports directory, probe and navigate instead of showing error
- if (!file?.content) {
- try {
- const probe = await getRepositoryStructure(repositoryId, relPath)
- if (Array.isArray(probe?.structure) && probe.structure.length > 0) {
- setPreviewContent(null)
- setSelectedFile(null)
- setSelectedDir(relPath)
- setDirEntries(probe.structure)
- return
- }
- } catch {}
- }
- setPreviewContent(file?.content || null)
- } finally {
- setPreviewLoading(false)
- }
- }}>
-
- {isDir ? : }
-
-
{displayName}
-
{isDir ? 'folder' : 'file'}
-
- )
- })}
-
-
- {/* Right: Preview */}
-
-
- Preview
- {selectedFile && {selectedFile}}
-
- {previewLoading ? (
-
Loading file...
- ) : !selectedFile ? (
-
Select a file to preview its contents.
- ) : previewContent ? (
-
{previewContent}
- ) : (
-
No preview available (binary or empty file).
+
+
+ {loading && (
+ Loading...
)}
-
-
+ {!loading && visible.length === 0 && (
+ No entries found.
+ )}
+ {visible.map((e, i) => (
+