-
Notifications
You must be signed in to change notification settings - Fork 904
feat(desktop): file tree sidebar, file pane renderers, and alert refactor #3122
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
a930a51
74646c0
84bc974
b7ccf6a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| export { RightSidebar } from "./RightSidebar"; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,106 @@ | ||
| import type { RendererContext } from "@superset/panes"; | ||
| import { useFileDocument } from "@superset/workspace-client"; | ||
| import { useCallback } from "react"; | ||
| import { isImageFile, isMarkdownFile } from "shared/file-types"; | ||
| import type { FilePaneData, PaneViewerData } from "../../../../types"; | ||
| import { CodeRenderer } from "./renderers/CodeRenderer"; | ||
| import { ImageRenderer } from "./renderers/ImageRenderer"; | ||
| import { MarkdownRenderer } from "./renderers/MarkdownRenderer"; | ||
|
|
||
| interface FilePaneProps { | ||
| context: RendererContext<PaneViewerData>; | ||
| workspaceId: string; | ||
| } | ||
|
|
||
| export function FilePane({ context, workspaceId }: FilePaneProps) { | ||
| const data = context.pane.data as FilePaneData; | ||
| const { filePath } = data; | ||
|
|
||
| const document = useFileDocument({ | ||
| workspaceId, | ||
| absolutePath: filePath, | ||
| mode: isImageFile(filePath) ? "bytes" : "auto", | ||
| maxBytes: isImageFile(filePath) ? 10 * 1024 * 1024 : 2 * 1024 * 1024, | ||
| hasLocalChanges: data.hasChanges, | ||
| autoReloadWhenClean: true, | ||
| }); | ||
|
|
||
| const handleDirtyChange = useCallback( | ||
| (dirty: boolean) => { | ||
| if (dirty !== data.hasChanges) { | ||
| context.actions.updateData({ | ||
| ...data, | ||
| hasChanges: dirty, | ||
| } as PaneViewerData); | ||
| } | ||
| }, | ||
| [context.actions, data], | ||
| ); | ||
|
|
||
| const handleSave = useCallback( | ||
| async (content: string) => { | ||
| const result = await document.save({ content }); | ||
| if (result.status === "saved") { | ||
| handleDirtyChange(false); | ||
| } | ||
| return result; | ||
| }, | ||
|
Comment on lines
+40
to
+47
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fail the This callback resolves even when 🤖 Prompt for AI Agents |
||
| [document, handleDirtyChange], | ||
| ); | ||
|
|
||
| if (document.state.kind === "loading") { | ||
| return null; | ||
| } | ||
|
|
||
| if (document.state.kind === "not-found") { | ||
| return ( | ||
| <div className="flex h-full items-center justify-center text-sm text-muted-foreground"> | ||
| File not found | ||
| </div> | ||
| ); | ||
| } | ||
|
|
||
| if (document.state.kind === "too-large") { | ||
| return ( | ||
| <div className="flex h-full items-center justify-center text-sm text-muted-foreground"> | ||
| File is too large to display | ||
| </div> | ||
| ); | ||
| } | ||
|
|
||
| if (document.state.kind === "binary" || document.state.kind === "bytes") { | ||
| if (isImageFile(filePath) && document.state.kind === "bytes") { | ||
| return ( | ||
| <ImageRenderer content={document.state.content} filePath={filePath} /> | ||
| ); | ||
| } | ||
| return ( | ||
| <div className="flex h-full items-center justify-center text-sm text-muted-foreground"> | ||
| Binary file — cannot display | ||
| </div> | ||
| ); | ||
| } | ||
|
|
||
| if (isMarkdownFile(filePath)) { | ||
| return ( | ||
| <MarkdownRenderer | ||
| content={document.state.content} | ||
| hasExternalChange={document.hasExternalChange} | ||
| onDirtyChange={handleDirtyChange} | ||
| onReload={document.reload} | ||
| onSave={handleSave} | ||
| /> | ||
| ); | ||
| } | ||
|
|
||
| return ( | ||
| <CodeRenderer | ||
| content={document.state.content} | ||
| filePath={filePath} | ||
| hasExternalChange={document.hasExternalChange} | ||
| onDirtyChange={handleDirtyChange} | ||
| onReload={document.reload} | ||
| onSave={handleSave} | ||
| /> | ||
| ); | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| interface ExternalChangeBarProps { | ||
| onReload: () => Promise<void>; | ||
| } | ||
|
|
||
| export function ExternalChangeBar({ onReload }: ExternalChangeBarProps) { | ||
| return ( | ||
| <div className="flex items-center gap-2 border-b border-border bg-warning/10 px-3 py-1.5 text-xs text-warning-foreground"> | ||
| <span>File changed on disk.</span> | ||
| <button | ||
| type="button" | ||
| className="underline hover:no-underline" | ||
| onClick={() => void onReload()} | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P2: Handle (Based on your team's feedback about awaiting/catching async calls to avoid unhandled promise rejections.) Prompt for AI agents |
||
| > | ||
| Reload | ||
| </button> | ||
| </div> | ||
| ); | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| export { ExternalChangeBar } from "./ExternalChangeBar"; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| export { FilePane } from "./FilePane"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reveal the initial selection too.
Because
prevSelectedRefis seeded fromselectedFilePathand updated on every effect run, the first selected file is treated as already handled. When the sidebar mounts with an active pane, the tree never expands/scrolls to that file until the selection changes again.🩹 Suggested fix
📝 Committable suggestion
🤖 Prompt for AI Agents