diff --git a/surfsense_web/app/dashboard/[workspace_id]/playground/components/output-viewer.tsx b/surfsense_web/app/dashboard/[workspace_id]/playground/components/output-viewer.tsx index 72262d440..106200a70 100644 --- a/surfsense_web/app/dashboard/[workspace_id]/playground/components/output-viewer.tsx +++ b/surfsense_web/app/dashboard/[workspace_id]/playground/components/output-viewer.tsx @@ -2,15 +2,9 @@ import { Check, Copy, Download } from "lucide-react"; import { useMemo, useState } from "react"; +import { JsonView } from "@/components/json-view"; import { Button } from "@/components/ui/button"; -import { - Table, - TableBody, - TableCell, - TableHead, - TableHeader, - TableRow, -} from "@/components/ui/table"; +import { TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"; import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { downloadCsv, rowsToCsv } from "@/lib/playground/csv"; @@ -48,10 +42,11 @@ function ResultTable({ items }: { items: Record[] }) { const rows = items.slice(0, MAX_TABLE_ROWS); + // overscroll-contain keeps table scrolling from chaining to the page. return ( -
- - +
+
+ {columns.map((col) => ( @@ -72,7 +67,7 @@ function ResultTable({ items }: { items: Record[] }) { ))} -
+
); } @@ -152,9 +147,9 @@ export function OutputViewer({ data, filenameBase }: { data: unknown; filenameBa )} ) : ( -
-					{json}
-				
+
+ +
)} ); diff --git a/surfsense_web/app/dashboard/[workspace_id]/playground/components/run-detail.tsx b/surfsense_web/app/dashboard/[workspace_id]/playground/components/run-detail.tsx index 4a128f5d8..fdf41729c 100644 --- a/surfsense_web/app/dashboard/[workspace_id]/playground/components/run-detail.tsx +++ b/surfsense_web/app/dashboard/[workspace_id]/playground/components/run-detail.tsx @@ -1,6 +1,7 @@ "use client"; import { useMemo } from "react"; +import { JsonView } from "@/components/json-view"; import { Spinner } from "@/components/ui/spinner"; import { useScraperRun } from "@/hooks/use-scraper-runs"; import { OutputViewer } from "./output-viewer"; @@ -69,7 +70,7 @@ export function RunDetail({ workspaceId, runId }: { workspaceId: number; runId: {run.progress && run.progress.length > 0 && (

Progress

-
+
{run.progress.map((event, i) => (
{progressLine(event)} @@ -81,9 +82,9 @@ export function RunDetail({ workspaceId, runId }: { workspaceId: number; runId:

Input

-
-					{JSON.stringify(run.input ?? {}, null, 2)}
-				
+
+ +
diff --git a/surfsense_web/app/dashboard/[workspace_id]/playground/components/runs-table.tsx b/surfsense_web/app/dashboard/[workspace_id]/playground/components/runs-table.tsx index 57b7a547c..0d642ac3f 100644 --- a/surfsense_web/app/dashboard/[workspace_id]/playground/components/runs-table.tsx +++ b/surfsense_web/app/dashboard/[workspace_id]/playground/components/runs-table.tsx @@ -2,7 +2,7 @@ import { useInfiniteQuery } from "@tanstack/react-query"; import { ChevronDown, ChevronRight, History, Info } from "lucide-react"; -import { Fragment, useState } from "react"; +import { useState } from "react"; import { Alert, AlertDescription } from "@/components/ui/alert"; import { Button } from "@/components/ui/button"; import { @@ -13,14 +13,6 @@ import { SelectValue, } from "@/components/ui/select"; import { Spinner } from "@/components/ui/spinner"; -import { - Table, - TableBody, - TableCell, - TableHead, - TableHeader, - TableRow, -} from "@/components/ui/table"; import { scrapersApiService } from "@/lib/apis/scrapers-api.service"; import { formatRelativeDate } from "@/lib/format-date"; import { PLAYGROUND_PLATFORMS } from "@/lib/playground/catalog"; @@ -33,6 +25,12 @@ import { RunStatusBadge } from "./run-status-badge"; const PAGE_SIZE = 25; const ALL = "__all__"; +// A grid (not a ) keeps an expanded row's detail out of a table-cell, +// where overflow/max-height scroll containers get ignored. Tracks are fr/fixed +// (never content-based auto) so separate per-row grids stay column-aligned. +const ROW_GRID = + "grid grid-cols-[2rem_minmax(8rem,2fr)_minmax(4rem,1fr)_minmax(5rem,1fr)_4rem_5rem_5rem_minmax(6rem,1fr)] items-center gap-2 px-3"; + const CAPABILITY_OPTIONS = PLAYGROUND_PLATFORMS.flatMap((platform) => platform.verbs.map((verb) => verb.name) ); @@ -122,63 +120,60 @@ export function RunsTable({ workspaceId }: { workspaceId: number }) { ) : (
-
- - - - API - Origin - Status - Items - Duration - Cost - When - - - - {runs.map((run) => { - const isOpen = expanded === run.id; - return ( - - setExpanded(isOpen ? null : run.id)} - > - - {isOpen ? ( - - ) : ( - - )} - - {run.capability} - {run.origin} - - - - {run.item_count} - - {formatDuration(run.duration_ms)} - - - {formatCost(run.cost_micros)} - - - {formatRelativeDate(run.created_at)} - - - {isOpen && ( - - - - - - )} - - ); - })} - -
+
+ + API + Origin + Status + Items + Duration + Cost + When +
+ {runs.map((run) => { + const isOpen = expanded === run.id; + return ( +
+ + {isOpen && } +
+ ); + })}
)}