|
1 | | -import { ArrowDownTrayIcon, ClipboardIcon } from "@heroicons/react/20/solid"; |
| 1 | +import { ArrowDownTrayIcon, ArrowsPointingInIcon, ArrowsPointingOutIcon, ArrowTrendingUpIcon, ClipboardIcon } from "@heroicons/react/20/solid"; |
2 | 2 | import type { OutputColumnMetadata, WhereClauseFallback } from "@internal/clickhouse"; |
3 | 3 | import { |
4 | 4 | redirect, |
@@ -68,6 +68,8 @@ import { formatQueryStats } from "./utils"; |
68 | 68 | import { requireUser } from "~/services/session.server"; |
69 | 69 | import parse from "parse-duration"; |
70 | 70 | import { SimpleTooltip } from "~/components/primitives/Tooltip"; |
| 71 | +import { Dialog, DialogContent, DialogHeader, DialogPortal, DialogTrigger } from "~/components/primitives/Dialog"; |
| 72 | +import { DialogOverlay } from "@radix-ui/react-dialog"; |
71 | 73 |
|
72 | 74 | /** Convert a Date or ISO string to ISO string format */ |
73 | 75 | function toISOString(value: Date | string): string { |
@@ -719,29 +721,12 @@ export default function Page() { |
719 | 721 | className="m-0 grid min-h-0 grid-rows-[1fr] overflow-hidden" |
720 | 722 | > |
721 | 723 | {results?.rows && results?.columns && results.rows.length > 0 ? ( |
722 | | - <ResizablePanelGroup className="h-full overflow-hidden"> |
723 | | - <ResizablePanel id="chart-results"> |
724 | | - <div className="h-full bg-charcoal-900 p-2 overflow-y-auto scrollbar-thin scrollbar-track-transparent scrollbar-thumb-charcoal-600"> |
725 | | - <Card> |
726 | | - <Card.Content> |
727 | | - <QueryResultsChart |
728 | | - rows={results.rows} |
729 | | - columns={results.columns} |
730 | | - config={chartConfig} |
731 | | - /> |
732 | | - </Card.Content> |
733 | | - </Card> |
734 | | - </div> |
735 | | - </ResizablePanel> |
736 | | - <ResizableHandle id="chart-split" /> |
737 | | - <ResizablePanel id="chart-config" min="50px" default="200px"> |
738 | | - <ChartConfigPanel |
739 | | - columns={results.columns} |
740 | | - config={chartConfig} |
741 | | - onChange={handleChartConfigChange} |
742 | | - /> |
743 | | - </ResizablePanel> |
744 | | - </ResizablePanelGroup> |
| 724 | + <ResultsChart |
| 725 | + rows={results.rows} |
| 726 | + columns={results.columns} |
| 727 | + chartConfig={chartConfig} |
| 728 | + onChartConfigChange={handleChartConfigChange} |
| 729 | + /> |
745 | 730 | ) : ( |
746 | 731 | <Paragraph variant="small" className="p-4 text-text-dimmed"> |
747 | 732 | Run a query to visualize results. |
@@ -858,3 +843,56 @@ function ScopeItem({ scope }: { scope: QueryScope }) { |
858 | 843 | return scope; |
859 | 844 | } |
860 | 845 | } |
| 846 | + |
| 847 | +function ResultsChart({ |
| 848 | + rows, |
| 849 | + columns, |
| 850 | + chartConfig, |
| 851 | + onChartConfigChange, |
| 852 | +}: { |
| 853 | + rows: Record<string, unknown>[]; |
| 854 | + columns: OutputColumnMetadata[]; |
| 855 | + chartConfig: ChartConfiguration; |
| 856 | + onChartConfigChange: (config: ChartConfiguration) => void; |
| 857 | +}) { |
| 858 | + const [isOpen, setIsOpen] = useState(false); |
| 859 | + |
| 860 | + return ( |
| 861 | + <><ResizablePanelGroup className="h-full overflow-hidden"> |
| 862 | + <ResizablePanel id="chart-results"> |
| 863 | + <div className="h-full bg-charcoal-900 p-2 overflow-y-auto scrollbar-thin scrollbar-track-transparent scrollbar-thumb-charcoal-600"> |
| 864 | + <Card> |
| 865 | + <Card.Header> |
| 866 | + <div className="flex items-center gap-1.5"> |
| 867 | + <ArrowTrendingUpIcon className="size-5 text-indigo-500" /> |
| 868 | + Chart |
| 869 | + </div> |
| 870 | + <Card.Accessory> |
| 871 | + <Button variant="minimal/small" LeadingIcon={ArrowsPointingOutIcon} onClick={() => setIsOpen(true)} /> |
| 872 | + </Card.Accessory> |
| 873 | + </Card.Header> |
| 874 | + <Card.Content> |
| 875 | + <QueryResultsChart rows={rows} columns={columns} config={chartConfig} /> |
| 876 | + </Card.Content> |
| 877 | + </Card> |
| 878 | + |
| 879 | + </div> |
| 880 | + </ResizablePanel> |
| 881 | + <ResizableHandle id="chart-split" /> |
| 882 | + <ResizablePanel id="chart-config" min="50px" default="200px"> |
| 883 | + <ChartConfigPanel columns={columns} config={chartConfig} onChange={onChartConfigChange} /> |
| 884 | + </ResizablePanel> |
| 885 | + </ResizablePanelGroup> |
| 886 | + <Dialog open={isOpen} onOpenChange={setIsOpen}> |
| 887 | + <DialogContent fullscreen> |
| 888 | + <DialogHeader> |
| 889 | + Chart |
| 890 | + </DialogHeader> |
| 891 | + <div className="overflow-hidden w-full"> |
| 892 | + <QueryResultsChart rows={rows} columns={columns} config={chartConfig} fullLegend={true} /> |
| 893 | + </div> |
| 894 | + </DialogContent> |
| 895 | + </Dialog> |
| 896 | + </> |
| 897 | + ); |
| 898 | +} |
0 commit comments