Skip to content

Commit 6e54136

Browse files
committed
new search & new formula links
1 parent 8b8cec3 commit 6e54136

17 files changed

Lines changed: 162957 additions & 70661 deletions

web/src/components/data-table.tsx

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ export function DataTable<TData>({
124124
const [data, setData] = React.useState<TData[] | "loading">(
125125
binX86 as unknown as TData[],
126126
);
127+
const [searchValue, setSearchValue] = React.useState("");
127128

128129
const columns = React.useMemo(() => {
129130
return col(page);
@@ -183,11 +184,21 @@ export function DataTable<TData>({
183184
getFilteredRowModel: getFilteredRowModel(),
184185
onColumnVisibilityChange: setColumnVisibility,
185186
getPaginationRowModel: getPaginationRowModel(),
187+
filterFns: {
188+
nameOrFamily: (row, columnId, filterValue) => {
189+
if (column === "category") return true;
190+
const searchLower = filterValue.toLowerCase();
191+
const name = (row.getValue("name") as string)?.toLowerCase() || "";
192+
const family = (row.getValue("family") as string)?.toLowerCase() || "";
193+
return name.includes(searchLower) || family.includes(searchLower);
194+
},
195+
},
186196
state: {
187197
sorting,
188198
columnFilters,
189199
columnVisibility,
190-
},
200+
globalFilter: column !== "category" ? searchValue : undefined,
201+
}
191202
});
192203

193204
React.useEffect(() => {
@@ -205,6 +216,13 @@ export function DataTable<TData>({
205216
const pageNumberInput: React.RefObject<HTMLInputElement | null> =
206217
React.useRef(null);
207218

219+
const handleSearch = (value: string) => {
220+
setSearchValue(value);
221+
if (column === "category") {
222+
table.getColumn("category")?.setFilterValue(value);
223+
}
224+
};
225+
208226
return (
209227
<div className="rounded-md border">
210228
<div className="flex flex-col md:flex-row justify-center md:justify-normal items-center py-4 md:px-3">
@@ -214,22 +232,23 @@ export function DataTable<TData>({
214232
e.preventDefault();
215233
if (input.current) {
216234
const val = input.current.value.trim();
217-
if (val) {
218-
table.getColumn(column)?.setFilterValue(val);
219-
}
235+
handleSearch(val);
220236
}
221237
}}
222238
>
223239
<Input
224-
placeholder="Filter using name..."
240+
placeholder={`Filter using ${column === "category" ? "category" : "name or package ID"}...`}
225241
ref={input}
226242
maxLength={64}
227-
// value={(table.getColumn("name")?.getFilterValue() as string) ?? ""}
228243
onChange={(event) => {
229-
if (!event.target.value.trim()) {
244+
const value = event.target.value.trim();
245+
if (!value) {
246+
handleSearch("");
230247
for (const col of table.getAllColumns()) {
231248
col.setFilterValue("");
232249
}
250+
} else {
251+
handleSearch(value);
233252
}
234253
}}
235254
className="max-w-sm rounded-r-none"
@@ -264,8 +283,7 @@ export function DataTable<TData>({
264283
<SelectContent>
265284
<SelectGroup>
266285
<SelectLabel>Filter among</SelectLabel>
267-
<SelectItem value="name">Name</SelectItem>
268-
<SelectItem value="family">Package ID</SelectItem>
286+
<SelectItem value="name">Name OR Package ID</SelectItem>
269287
<SelectItem value="category">Category</SelectItem>
270288
</SelectGroup>
271289
</SelectContent>
@@ -329,9 +347,9 @@ export function DataTable<TData>({
329347
{header.isPlaceholder
330348
? null
331349
: flexRender(
332-
header.column.columnDef.header,
333-
header.getContext(),
334-
)}
350+
header.column.columnDef.header,
351+
header.getContext(),
352+
)}
335353
</TableHead>
336354
);
337355
})}

web/src/components/formula-links.tsx

Lines changed: 92 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,111 @@
1-
import { FileJson, DownloadCloud } from 'lucide-react';
1+
import { FileJson, DownloadCloud, Copy, ExternalLink } from 'lucide-react';
2+
import { useClipboard } from '../hooks/use-clipboard';
3+
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from './ui/tooltip';
4+
import { useState } from 'react';
25

36
interface Props {
47
webpage_url: string;
58
repo: string;
69
}
710

811
const FormulaLinks = ({ webpage_url, repo }: Props) => {
12+
const { copy } = useClipboard();
13+
const [jsonCopied, setJsonCopied] = useState(false);
14+
const [downloadCopied, setDownloadCopied] = useState(false);
915
const jsonApiUrl = `${webpage_url}/raw.json`;
1016

1117
const [, , , , ...dataf] = webpage_url.split("/");
12-
1318
const downloadUrl = new URL(`/dl/${dataf.join("/")}/raw.dl`, window.location.origin);
1419

20+
const handleJsonCopy = () => {
21+
copy(jsonApiUrl);
22+
setJsonCopied(true);
23+
setTimeout(() => setJsonCopied(false), 2000);
24+
};
25+
26+
const handleDownloadCopy = () => {
27+
copy(downloadUrl.toString());
28+
setDownloadCopied(true);
29+
setTimeout(() => setDownloadCopied(false), 2000);
30+
};
31+
1532
return (
16-
<div className="grid gap-3 p-4 bg-blue-50/30 dark:bg-blue-950/30 rounded-lg border border-blue-100 dark:border-blue-900">
17-
<div className="space-y-2">
18-
<h2 className="text-sm font-medium text-blue-700/70 dark:text-blue-300/70">Package Links</h2>
19-
<div className="grid gap-2">
20-
<a
21-
href={jsonApiUrl}
22-
target="_blank"
23-
rel="noreferrer"
24-
className="flex items-center gap-3 w-full group"
25-
>
26-
<FileJson className="h-5 w-5 transition-transform duration-200 text-blue-600/70 dark:text-blue-400/70 group-hover:scale-110" />
27-
<div className="flex flex-col items-start">
28-
<span className="text-sm font-medium text-gray-700 dark:text-gray-300">JSON API</span>
29-
<code className="text-xs text-gray-500 dark:text-gray-400 font-mono">
30-
{`${webpage_url}/raw.json`}
31-
</code>
33+
<TooltipProvider delayDuration={0}>
34+
<div className="grid gap-3 p-4 bg-blue-50/30 dark:bg-blue-950/30 rounded-lg border border-blue-100 dark:border-blue-900">
35+
<div className="space-y-2">
36+
<h2 className="text-sm font-medium text-blue-700/70 dark:text-blue-300/70">Package Links</h2>
37+
<div className="grid gap-3">
38+
<div className="flex items-center gap-3 w-full group">
39+
<FileJson className="h-5 w-5 text-blue-600/70 dark:text-blue-400/70" />
40+
<div className="flex flex-col items-start gap-1 flex-1">
41+
<span className="text-sm font-medium">JSON API</span>
42+
<div className="flex items-center gap-2 w-full">
43+
<Tooltip open={jsonCopied}>
44+
<TooltipTrigger asChild>
45+
<button
46+
onClick={handleJsonCopy}
47+
className="flex items-center gap-2 px-3 py-1.5 rounded-md bg-blue-50 dark:bg-blue-950 hover:bg-blue-100 dark:hover:bg-blue-900 text-blue-600 dark:text-blue-400 transition-colors flex-1"
48+
>
49+
<code className="text-xs font-mono">{jsonApiUrl}</code>
50+
<Copy className="h-4 w-4 shrink-0" />
51+
</button>
52+
</TooltipTrigger>
53+
<TooltipContent>
54+
<p>Copied!</p>
55+
</TooltipContent>
56+
</Tooltip>
57+
58+
<a
59+
href={jsonApiUrl}
60+
target="_blank"
61+
rel="noreferrer"
62+
className="px-3 py-1.5 rounded-md bg-blue-600 hover:bg-blue-700 dark:bg-blue-700 dark:hover:bg-blue-600 text-white transition-colors flex items-center gap-2"
63+
>
64+
<span className="text-xs">Open</span>
65+
<ExternalLink className="h-4 w-4" />
66+
</a>
67+
</div>
68+
</div>
3269
</div>
33-
</a>
34-
35-
{repo != "soarpkgs" && <a
36-
href={downloadUrl.toString()}
37-
target="_blank"
38-
rel="noreferrer"
39-
className="flex items-center gap-3 w-full group"
40-
>
41-
<DownloadCloud className="h-5 w-5 text-blue-600/70 dark:text-blue-400/70 group-hover:scale-110 transition-transform duration-200" />
42-
<div className="flex flex-col items-start">
43-
<span className="text-sm font-medium text-gray-700 dark:text-gray-300">Download</span>
44-
<code className="text-xs text-gray-500 dark:text-gray-400 font-mono">
45-
https://pkgs.pkgforge.dev/dl/{`${dataf.join("/")}/raw.dl`}
46-
</code>
47-
</div>
48-
</a>}
70+
71+
{repo != "soarpkgs" && (
72+
<div className="flex items-center gap-3 w-full group">
73+
<DownloadCloud className="h-5 w-5 text-blue-600/70 dark:text-blue-400/70" />
74+
<div className="flex flex-col items-start gap-1 flex-1">
75+
<span className="text-sm font-medium">Download URL</span>
76+
<div className="flex items-center gap-2 w-full">
77+
<Tooltip open={downloadCopied}>
78+
<TooltipTrigger asChild>
79+
<button
80+
onClick={handleDownloadCopy}
81+
className="flex items-center gap-2 px-3 py-1.5 rounded-md bg-blue-50 dark:bg-blue-950 hover:bg-blue-100 dark:hover:bg-blue-900 text-blue-600 dark:text-blue-400 transition-colors flex-1"
82+
>
83+
<code className="text-xs font-mono">{downloadUrl.toString()}</code>
84+
<Copy className="h-4 w-4 shrink-0" />
85+
</button>
86+
</TooltipTrigger>
87+
<TooltipContent>
88+
<p>Copied!</p>
89+
</TooltipContent>
90+
</Tooltip>
91+
92+
<a
93+
href={downloadUrl.toString()}
94+
target="_blank"
95+
rel="noreferrer"
96+
className="px-3 py-1.5 rounded-md bg-blue-600 hover:bg-blue-700 dark:bg-blue-700 dark:hover:bg-blue-600 text-white transition-colors flex items-center gap-2"
97+
>
98+
<span className="text-xs">Download</span>
99+
<ExternalLink className="h-4 w-4" />
100+
</a>
101+
</div>
102+
</div>
103+
</div>
104+
)}
105+
</div>
49106
</div>
50107
</div>
51-
</div>
108+
</TooltipProvider>
52109
);
53110
};
54111

web/src/metadata_bincache_aarch64-linux.json

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

web/src/metadata_bincache_x86_64-linux.json

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)