History

Remove the kind facet chips

Kind was the only facet and it earned its row less than it cost: the surface is already in every card's name, and the search covers all kinds. The paste-URL hint moves onto the start-from-scratch line.

Rhys Sullivan committed 2 months ago

Commit bafd0a61 parent 6a410c31 file · +7 −47Browse files

Unified · Split

packages/react/src/pages/integration-browse.tsx+7−47
@@ -19,7 +19,6 @@ import { Button } from "../components/button"; · 18 unmodified lines
19import { Input } from "../components/input";19import { Input } from "../components/input";
20import { PageContainer, PageHeader } from "../components/page";20import { PageContainer, PageHeader } from "../components/page";
21import { Skeleton } from "../components/skeleton";21import { Skeleton } from "../components/skeleton";
22import { cn } from "../lib/utils";
23import { useExecutorDocumentTitle } from "../lib/document-title";22import { useExecutorDocumentTitle } from "../lib/document-title";
24import {23import {
25 availableCatalogKinds,24 availableCatalogKinds,
@@ -298,29 +297,6 @@ function CardSkeleton(props: { readonly index: number }) { · 272 unmodified lines
298 );297 );
299}298}
300 299
301function KindChip(props: {
302 readonly label: string;
303 readonly active: boolean;
304 readonly onSelect: () => void;
305}) {
306 return (
307 // oxlint-disable-next-line react/forbid-elements -- a filter chip, not a Button variant
308 <button
309 type="button"
310 onClick={props.onSelect}
311 aria-pressed={props.active}
312 className={cn(
313 "rounded-full border px-3 py-1 text-xs font-medium transition-colors",
314 props.active
315 ? "border-foreground/20 bg-foreground text-background"
316 : "border-border text-muted-foreground hover:bg-accent hover:text-foreground",
317 )}
318 >
319 {props.label}
320 </button>
321 );
322}
323
324// ---------------------------------------------------------------------------300// ---------------------------------------------------------------------------
325// Page301// Page
326// ---------------------------------------------------------------------------302// ---------------------------------------------------------------------------
@@ -333,7 +309,6 @@ export function IntegrationBrowsePage() { · 6 unmodified lines
333 const installed = useAtomValue(integrationsOptimisticAtom);309 const installed = useAtomValue(integrationsOptimisticAtom);
334 310
335 const [query, setQuery] = useState("");311 const [query, setQuery] = useState("");
336 const [kind, setKind] = useState<CatalogKind | null>(null);
337 const [detecting, setDetecting] = useState(false);312 const [detecting, setDetecting] = useState(false);
338 const [error, setError] = useState<string | null>(null);313 const [error, setError] = useState<string | null>(null);
339 // Resolve-on-click failures belong on the card that was clicked — a page-top314 // Resolve-on-click failures belong on the card that was clicked — a page-top
@@ -357,7 +332,7 @@ export function IntegrationBrowsePage() { · 17 unmodified lines
357 // Nothing to exclude now that the registry is the only source.332 // Nothing to exclude now that the registry is the only source.
358 const excludeDomains = useMemo(() => new Set<string>(), []);333 const excludeDomains = useMemo(() => new Set<string>(), []);
359 334
360 const catalog = useCatalogBrowse({ query: listQuery, ...(kind ? { kind } : {}) });335 const catalog = useCatalogBrowse({ query: listQuery });
361 const catalogEntries = useMemo(336 const catalogEntries = useMemo(
362 () => filterCatalogEntries(catalog.entries, { excludeDomains, availableKinds }),337 () => filterCatalogEntries(catalog.entries, { excludeDomains, availableKinds }),
363 [catalog.entries, excludeDomains, availableKinds],338 [catalog.entries, excludeDomains, availableKinds],
@@ -541,7 +516,6 @@ export function IntegrationBrowsePage() { · 177 unmodified lines
541 const rows: Row[] = [];516 const rows: Row[] = [];
542 for (const entry of allPresets) {517 for (const entry of allPresets) {
543 if (entry.preset.url !== undefined || entry.preset.endpoint !== undefined) continue;518 if (entry.preset.url !== undefined || entry.preset.endpoint !== undefined) continue;
544 if (kind !== null && entry.pluginKey !== kind) continue;
545 if (text.length > 0) {519 if (text.length > 0) {
546 const corpus =520 const corpus =
547 `${entry.preset.name} ${entry.preset.summary ?? ""} ${entry.preset.family ?? ""} ${entry.pluginLabel}`.toLowerCase();521 `${entry.preset.name} ${entry.preset.summary ?? ""} ${entry.preset.family ?? ""} ${entry.pluginLabel}`.toLowerCase();
@@ -566,7 +540,7 @@ export function IntegrationBrowsePage() { · 18 unmodified lines
566 });540 });
567 }541 }
568 return rows;542 return rows;
569 }, [allPresets, kind, text, pickPreset, isAdded]);543 }, [allPresets, text, pickPreset, isAdded]);
570 544
571 // --- Catalog rows: one per (service, surface) -----------------------------545 // --- Catalog rows: one per (service, surface) -----------------------------
572 const catalogRows = useMemo<readonly Row[]>(() => {546 const catalogRows = useMemo<readonly Row[]>(() => {
@@ -688,27 +662,10 @@ export function IntegrationBrowsePage() { · 115 unmodified lines
688 ) : null}662 ) : null}
689 </div>663 </div>
690 664
691 <div className="mb-3 flex flex-wrap items-center gap-1.5">
692 <KindChip label="All" active={kind === null} onSelect={() => setKind(null)} />
693 {availableKinds.map((candidate) => (
694 <KindChip
695 key={candidate}
696 label={CATALOG_KIND_LABEL[candidate]}
697 active={kind === candidate}
698 onSelect={() => setKind(candidate)}
699 />
700 ))}
701 <span className="ml-auto shrink-0 text-xs text-muted-foreground">
702 Can&apos;t find it? Paste its URL above.
703 </span>
704 </div>
705
706 {/* Above the results, not below: an endless list has no reachable665 {/* Above the results, not below: an endless list has no reachable
707 bottom, and this is the escape hatch for exactly the person the666 bottom, and this is the escape hatch for exactly the person the
708 list is failing. One quiet line — the label carries the action, so667 list is failing. One quiet line; the label carries the action, so
709 the chips can stay as bare format names without colliding with the668 the chips stay bare format names. */}
710 facet pills above (those FILTER, these CREATE, and the plus mark +
711 leading verb keep that legible). */}
712 <div className="mb-8 flex flex-wrap items-center gap-x-3 gap-y-2">669 <div className="mb-8 flex flex-wrap items-center gap-x-3 gap-y-2">
713 <span className="shrink-0 text-xs text-muted-foreground">Start from scratch:</span>670 <span className="shrink-0 text-xs text-muted-foreground">Start from scratch:</span>
714 <div className="flex shrink-0 items-center gap-1.5">671 <div className="flex shrink-0 items-center gap-1.5">
@@ -734,6 +691,9 @@ export function IntegrationBrowsePage() { · 19 unmodified lines
734 ),691 ),
735 )}692 )}
736 </div>693 </div>
694 <span className="ml-auto shrink-0 text-xs text-muted-foreground">
695 Can&apos;t find it? Paste its URL above.
696 </span>
737 </div>697 </div>
738 698
739 {error ? (699 {error ? (