mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-06-30 21:59:46 +02:00
refactor: improve loading state handling and error display in report panel
This commit is contained in:
parent
a668219240
commit
04a10da3ca
2 changed files with 47 additions and 23 deletions
|
|
@ -249,20 +249,29 @@ function ReportPanelContent({
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
if (isLoading) {
|
// Show full-page skeleton only on initial load (no data loaded yet).
|
||||||
return <ReportPanelSkeleton />;
|
// Once we have versions/content from a prior fetch, keep the action bar visible.
|
||||||
}
|
const hasLoadedBefore = versions.length > 0 || reportContent !== null;
|
||||||
|
|
||||||
if (error || !reportContent) {
|
if (isLoading && !hasLoadedBefore) {
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-1 flex-col items-center justify-center gap-3 p-6 text-center">
|
<>
|
||||||
<div>
|
{/* Minimal top bar with close button even during initial load */}
|
||||||
<p className="font-medium text-foreground">Failed to load report</p>
|
<div className="flex items-center justify-end px-4 py-2 shrink-0">
|
||||||
<p className="text-sm text-red-500 mt-1">
|
{onClose && (
|
||||||
{error || "An unknown error occurred"}
|
<Button
|
||||||
</p>
|
variant="ghost"
|
||||||
|
size="icon"
|
||||||
|
onClick={onClose}
|
||||||
|
className="size-7 shrink-0"
|
||||||
|
>
|
||||||
|
<XIcon className="size-4" />
|
||||||
|
<span className="sr-only">Close report panel</span>
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<ReportPanelSkeleton />
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -270,7 +279,7 @@ function ReportPanelContent({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{/* Action bar */}
|
{/* Action bar — always visible after initial load */}
|
||||||
<div className="flex items-center justify-between px-4 py-2 shrink-0">
|
<div className="flex items-center justify-between px-4 py-2 shrink-0">
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
{/* Copy button */}
|
{/* Copy button */}
|
||||||
|
|
@ -278,6 +287,7 @@ function ReportPanelContent({
|
||||||
variant="outline"
|
variant="outline"
|
||||||
size="sm"
|
size="sm"
|
||||||
onClick={handleCopy}
|
onClick={handleCopy}
|
||||||
|
disabled={isLoading || !reportContent?.content}
|
||||||
className="h-8 min-w-[80px] px-3.5 py-4 text-[15px]"
|
className="h-8 min-w-[80px] px-3.5 py-4 text-[15px]"
|
||||||
>
|
>
|
||||||
{copied ? "Copied" : "Copy"}
|
{copied ? "Copied" : "Copy"}
|
||||||
|
|
@ -289,6 +299,7 @@ function ReportPanelContent({
|
||||||
<Button
|
<Button
|
||||||
variant="outline"
|
variant="outline"
|
||||||
size="sm"
|
size="sm"
|
||||||
|
disabled={isLoading || !reportContent?.content}
|
||||||
className="h-8 px-3.5 py-4 text-[15px] gap-1.5"
|
className="h-8 px-3.5 py-4 text-[15px] gap-1.5"
|
||||||
>
|
>
|
||||||
Export
|
Export
|
||||||
|
|
@ -364,17 +375,30 @@ function ReportPanelContent({
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Report content */}
|
{/* Report content — skeleton/error/content shown only in this area */}
|
||||||
<div className="flex-1 overflow-y-auto scrollbar-thin">
|
<div className="flex-1 overflow-y-auto scrollbar-thin">
|
||||||
<div className="px-5 py-5">
|
{isLoading ? (
|
||||||
{reportContent.content ? (
|
<ReportPanelSkeleton />
|
||||||
<MarkdownViewer content={reportContent.content} />
|
) : error || !reportContent ? (
|
||||||
) : (
|
<div className="flex flex-1 flex-col items-center justify-center gap-3 p-6 text-center">
|
||||||
<p className="text-muted-foreground italic">
|
<div>
|
||||||
No content available.
|
<p className="font-medium text-foreground">Failed to load report</p>
|
||||||
</p>
|
<p className="text-sm text-red-500 mt-1">
|
||||||
)}
|
{error || "An unknown error occurred"}
|
||||||
</div>
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<div className="px-5 py-5">
|
||||||
|
{reportContent.content ? (
|
||||||
|
<MarkdownViewer content={reportContent.content} />
|
||||||
|
) : (
|
||||||
|
<p className="text-muted-foreground italic">
|
||||||
|
No content available.
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -200,7 +200,7 @@ function ReportCard({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={`my-4 overflow-hidden rounded-xl border bg-card transition-colors ${isActive ? "ring-2 ring-primary/50" : ""}`}
|
className={`my-4 overflow-hidden rounded-xl border bg-card transition-colors ${isActive ? "ring-1 ring-primary/50" : ""}`}
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue