File size: 3,241 Bytes
5534d69
34cfb9f
295842d
 
1a56472
843fee0
5534d69
34cfb9f
 
 
 
1a56472
 
 
 
 
 
 
 
 
 
5c42f3b
1a56472
 
0b7a4b4
5c42f3b
 
843fee0
5534d69
 
 
 
34cfb9f
 
 
5c42f3b
34cfb9f
0b7a4b4
 
295842d
 
 
 
 
 
 
 
 
34cfb9f
5c42f3b
 
295842d
34cfb9f
295842d
 
 
 
5534d69
 
 
 
 
295842d
 
 
 
 
 
 
5c42f3b
295842d
 
 
b9b1c66
295842d
 
 
 
 
5c42f3b
5534d69
295842d
 
 
 
 
 
34cfb9f
295842d
 
 
 
34cfb9f
 
0b7a4b4
295842d
34cfb9f
0b7a4b4
 
34cfb9f
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
import { useCallback, useState } from "react";
import { Table } from "./table";
import { Button } from "~/components/ui/button";
import { Textarea } from "~/components/ui/textarea";
import { useSearchParams } from "~/useSearchParams";
import { useDuckDb } from "~/useDuckDb";
import { useParquetTable } from "~/useParquetTable";

const DEFAULT_DATASET_URL =
  "https://huggingface.co/datasets/openai/openai_humaneval/resolve/main/openai_humaneval/test-00000-of-00001.parquet";

const usePersistedTextfield = (fieldName: string) => {
  const { searchParams, setSearchParams } = useSearchParams();
  const searchParamsObj = new URLSearchParams(searchParams);
  const textField = searchParamsObj.get(fieldName) || "";
  const setTextField = useCallback(
    (value: string) => {
      setSearchParams({ [fieldName]: value });
    },
    [fieldName, setSearchParams]
  );
  return [textField, setTextField] satisfies [string, (value: string) => void];
};

function App() {
  const [datasetUrl, setDatasetUrl] = usePersistedTextfield("datasetUrl");
  const [nextDatasetUrl, setNextDatasetUrl] = useState(() => datasetUrl);
  const db = useDuckDb();
  const { loading, dataset, error, clearDataset } = useParquetTable(
    db,
    datasetUrl
  );

  const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
    e.preventDefault();
    setDatasetUrl(nextDatasetUrl);
  };

  return (
    <section className="flex flex-col gap-4 w-full pt-10 px-4 lg:pt-[15%] items-center min-h-screen">
      <h1 className="text-4xl font-bold">📣🦆 Quack</h1>
      <h2 className="text-2xl font-medium">View Parquet Datasets via URL</h2>
      <form
        onSubmit={handleSubmit}
        className="lg:w-1/2 w-full flex flex-col gap-2"
      >
        <Textarea
          rows={2}
          name="textField"
          onChange={(e) => setNextDatasetUrl(e.target.value)}
          value={nextDatasetUrl}
          className="w-full lg:w-full"
        />
        <div className="flex flex-row justify-between gap-2">
          <Button
            className="w-full"
            type="submit"
            disabled={
              !nextDatasetUrl ||
              (nextDatasetUrl === datasetUrl && !!dataset) ||
              loading
            }
          >
            Load
          </Button>
          <Button
            variant={"secondary"}
            type="button"
            onClick={() => {
              setNextDatasetUrl(DEFAULT_DATASET_URL);
              setDatasetUrl(DEFAULT_DATASET_URL);
            }}
          >
            Load Example Dataset
          </Button>
          <Button
            type="button"
            variant={"destructive"}
            onClick={() => {
              setNextDatasetUrl("");
              clearDataset();
              setDatasetUrl("");
            }}
          >
            Clear
          </Button>
        </div>
      </form>
      <div className="flex flex-col gap-2 w-full max-w-full overflow-x-auto bg-secondary rounded">
        {loading && (
          <p className="text-lg font-medium self-center">Loading...</p>
        )}
        {error && <p style={{ color: "red" }}>{error}</p>}
        {dataset && <Table data={dataset} />}
      </div>
    </section>
  );
}

export default App;