import { styled, Box } from "@mui/material"; import { SearchState } from "@/components/base/base-search-box"; const Item = styled(Box)(({ theme: { palette, typography } }) => ({ padding: "8px 0", margin: "0 12px", lineHeight: 1.35, borderBottom: `1px solid ${palette.divider}`, fontSize: "0.875rem", fontFamily: typography.fontFamily, userSelect: "text", "& .time": { color: palette.text.secondary, }, "& .type": { display: "inline-block", marginLeft: 8, textAlign: "center", borderRadius: 2, textTransform: "uppercase", fontWeight: "600", }, '& .type[data-type="error"], & .type[data-type="err"]': { color: palette.error.main, }, '& .type[data-type="warning"], & .type[data-type="warn"]': { color: palette.warning.main, }, '& .type[data-type="info"], & .type[data-type="inf"]': { color: palette.info.main, }, "& .data": { color: palette.text.primary, overflowWrap: "anywhere", }, "& .highlight": { backgroundColor: palette.mode === "dark" ? "#ffeb3b40" : "#ffeb3b90", borderRadius: 2, padding: "0 2px", }, })); interface Props { value: ILogItem; searchState?: SearchState; } const LogItem = ({ value, searchState }: Props) => { const renderHighlightText = (text: string) => { if (!searchState?.text.trim()) return text; try { const searchText = searchState.text; let pattern: string; if (searchState.useRegularExpression) { try { new RegExp(searchText); pattern = searchText; } catch { pattern = searchText.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } } else { const escaped = searchText.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); pattern = searchState.matchWholeWord ? `\\b${escaped}\\b` : escaped; } const flags = searchState.matchCase ? "g" : "gi"; const parts = text.split(new RegExp(`(${pattern})`, flags)); return parts.map((part, index) => { return index % 2 === 1 ? ( {part} ) : ( part ); }); } catch { return text; } }; return (
{value.time} {value.type}
{renderHighlightText(value.payload)}
); }; export default LogItem;