@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.
78 lines • 3.98 kB
JavaScript
import { createElement as _createElement } from "react";
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(props) {
const { field, valueOverride, result, icon, label, valueMapper, singleValueMapper, clickBehavior = "copy-text", onClick } = props;
const [showCopiedNotice, setShowCopiedNotice] = useState(false);
useEffect(() => {
if (showCopiedNotice) {
setTimeout(() => {
setShowCopiedNotice(false);
}, 1000);
}
}, [showCopiedNotice]);
const fieldValue = useMemo(() => {
if (valueOverride !== undefined)
return valueOverride;
return autoUnwrap(result[field]);
}, [field, result, valueOverride]);
const value = useMemo(() => {
if (fieldValue === null || fieldValue === undefined)
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.toString(), "_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 (value === undefined)
return null;
if (Array.isArray(value) && Array.isArray(fieldValue)) {
return value.map((entry, i) => _createElement(GenericResultViewTag, { ...props, key: field + i, valueOverride: fieldValue[value.indexOf(entry)] }));
}
else if (!label) {
return base(fieldValue, value);
}
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