@kit-data-manager/react-search-component
Version:
All-in-one component for rendering an elastic search UI for searching anything. Built-in support for visualizing related items in a graph and resolving unique identifiers.
73 lines • 3.99 kB
JavaScript
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
import { useCallback, useEffect, useMemo, useState } from "react";
import { Tooltip, TooltipContent, TooltipTrigger } from "../../components/ui/tooltip";
import { Badge } from "../../components/ui/badge";
import { useCopyToClipboard } from "usehooks-ts";
import { CheckIcon } from "lucide-react";
import { autoUnwrap } from "../../lib/utils";
export function GenericResultViewTag({ field, result, icon, label, valueMapper, singleValueMapper, clickBehavior = "copy-text", onClick }) {
const [showCopiedNotice, setShowCopiedNotice] = useState(false);
useEffect(() => {
if (showCopiedNotice) {
setTimeout(() => {
setShowCopiedNotice(false);
}, 1000);
}
}, [showCopiedNotice]);
const fieldValue = useMemo(() => {
return autoUnwrap(result[field]);
}, [field, result]);
const value = useMemo(() => {
if (!fieldValue)
return undefined;
if (valueMapper)
return valueMapper(fieldValue);
if (singleValueMapper)
return Array.isArray(fieldValue) ? fieldValue.map(singleValueMapper) : singleValueMapper(fieldValue);
else
return fieldValue;
}, [fieldValue, singleValueMapper, valueMapper]);
const [, copy] = useCopyToClipboard();
const copyTagValue = useCallback((e) => {
if ("innerText" in e.target && typeof e.target.innerText === "string") {
copy(e.target.innerText).then();
}
else
console.warn("Failed to copy innerText of", e.target);
}, [copy]);
const handleClick = useCallback((fieldValue, value, e) => {
if (onClick)
onClick(e, value, fieldValue);
if (clickBehavior === "copy-text" && !showCopiedNotice) {
copyTagValue(e);
setShowCopiedNotice(true);
}
else if (clickBehavior === "follow-url" && !Array.isArray(fieldValue)) {
window.open(fieldValue, "_blank");
}
}, [clickBehavior, copyTagValue, onClick, showCopiedNotice]);
const clickBehaviourText = useMemo(() => {
if (onClick)
return null; // We don't know what will happen on click...
if (clickBehavior === "copy-text") {
return "Click to copy";
}
else if (clickBehavior === "follow-url") {
return "Click to open";
}
else
return null;
}, [clickBehavior, onClick]);
const base = useCallback((fieldValue, value, key) => {
return (_jsx(Badge, { variant: "secondary", className: "rfs-truncate", onClick: (e) => handleClick(fieldValue, value, e), children: _jsx("span", { className: "rfs-flex rfs-truncate", children: showCopiedNotice ? (_jsxs(_Fragment, { children: [_jsx(CheckIcon, { className: "rfs-size-4 rfs-mr-2" }), " ", _jsx("span", { children: "Copied" })] })) : (_jsxs(_Fragment, { children: [icon, " ", value] })) }) }, key));
}, [handleClick, icon, showCopiedNotice]);
if (!label)
return Array.isArray(value) ? value.map((v, i) => base(fieldValue[value.indexOf(v)], v, field + i)) : base(fieldValue, value);
if (!value)
return null;
if (Array.isArray(value)) {
return value.map((entry, i) => (_jsxs(Tooltip, { delayDuration: 500, children: [_jsx(TooltipTrigger, { children: base(fieldValue[value.indexOf(entry)], entry) }), _jsxs(TooltipContent, { children: [_jsx("div", { children: label }), _jsx("div", { className: "rfs-text-xs rfs-text-muted-foreground", children: clickBehaviourText })] })] }, field + i)));
}
return (_jsxs(Tooltip, { delayDuration: 500, children: [_jsx(TooltipTrigger, { children: base(fieldValue, value) }), _jsxs(TooltipContent, { children: [_jsx("div", { children: label }), _jsx("div", { className: "rfs-text-xs rfs-text-muted-foreground", children: clickBehaviourText })] })] }));
}
//# sourceMappingURL=GenericResultViewTag.js.map