Skip to content

Commit

Permalink
refactor SearchTabPanel from new log viewer folder back to current lo…
Browse files Browse the repository at this point in the history
…g viewer
  • Loading branch information
Henry8192 committed Oct 28, 2024
1 parent 4c69bc1 commit 5094abf
Show file tree
Hide file tree
Showing 10 changed files with 370 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from "react";

import {
ButtonGroup,
DialogContent,
DialogTitle,
TabPanel,
Expand All @@ -14,6 +15,7 @@ interface CustomTabPanelProps {
children: React.ReactNode,
tabName: string,
title: string,
titleButtons?: React.ReactNode,
}

/**
Expand All @@ -23,9 +25,15 @@ interface CustomTabPanelProps {
* @param props.children
* @param props.tabName
* @param props.title
* @param props.titleButtons
* @return
*/
const CustomTabPanel = ({children, tabName, title}: CustomTabPanelProps) => {
const CustomTabPanel = ({
children,
tabName,
title,
titleButtons,
}: CustomTabPanelProps) => {
return (
<TabPanel
className={"sidebar-tab-panel"}
Expand All @@ -38,6 +46,13 @@ const CustomTabPanel = ({children, tabName, title}: CustomTabPanelProps) => {
>
{title}
</Typography>
<ButtonGroup
size={"sm"}
spacing={"1px"}
variant={"plain"}
>
{titleButtons}
</ButtonGroup>
</DialogTitle>
<DialogContent>
{children}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
.result-button {
user-select: none;

overflow: hidden;
display: block !important;

text-overflow: ellipsis;
white-space: nowrap;
}

.result-text {
display: inline !important;
font-size: 0.875rem !important;
font-weight: 400 !important;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import {
ListItemButton,
Typography,
} from "@mui/joy";

import "./Result.css";


interface ResultProps {
message: string,
matchRange: [number, number]
}

/**
* Displays a button containing a message, which highlights a specific range of text.
*
* @param props
* @param props.message
* @param props.matchRange A two-element array indicating the start and end indices of the substring
* to be highlighted.
* @return
*/
const Result = ({message, matchRange}: ResultProps) => {
const [
beforeMatch,
match,
afterMatch,
] = [
message.slice(0, matchRange[0]),
message.slice(...matchRange),
message.slice(matchRange[1]),
];

return (
<ListItemButton className={"result-button"}>
<Typography
className={"result-text"}
level={"body-xs"}
>
{beforeMatch}
</Typography>
<Typography
className={"result-text"}
level={"body-xs"}
sx={{
backgroundColor: "warning.softBg",
}}
>
{match}
</Typography>
<Typography
className={"result-text"}
level={"body-xs"}
>
{afterMatch}
</Typography>
</ListItemButton>
);
};

export default Result;
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
.results-group-title-button {
flex-direction: row-reverse !important;
gap: 2px !important;
padding-inline-start: 0 !important;
}

.results-group-title-container {
display: flex;
flex-grow: 1;
}

.results-group-title-text-container {
flex-grow: 1;
gap: 0.1rem;
align-items: center;
}

.results-group-content {
margin-left: 1.5px !important;
border-left: 1px solid var(--joy-palette-neutral-outlinedBorder, #cdd7e1);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import {
useEffect,
useState,
} from "react";
import * as React from "react";

import {
Accordion,
AccordionDetails,
AccordionSummary,
Box,
Chip,
List,
Stack,
Typography,
} from "@mui/joy";

import DescriptionOutlinedIcon from "@mui/icons-material/DescriptionOutlined";

import Result from "./Result";

import "./ResultsGroup.css";


interface SearchResultOnPage {
logEventNum: number,
message: string,
matchRange: [number, number],
}

interface ResultsGroupProps {
isAllExpanded: boolean,
pageNum: number,
results: SearchResultOnPage[]
}

/**
*
* @param props
* @param props.isAllCollapsed
* @param props.pageNum
* @param props.results
* @param props.isAllExpanded
*/
const ResultsGroup = ({
isAllExpanded,
pageNum,
results,
}: ResultsGroupProps) => {
const [isExpanded, setIsExpanded] = useState<boolean>(isAllExpanded);

const handleAccordionChange = (
_: React.SyntheticEvent,
newValue: boolean
) => {
setIsExpanded(newValue);
};

// On `isAllExpanded` updates, sync current results group's expand status.
useEffect(() => {
setIsExpanded(isAllExpanded);
}, [isAllExpanded]);

return (
<Accordion
expanded={isExpanded}
onChange={handleAccordionChange}
>
<AccordionSummary
slotProps={{
button: {className: "results-group-title-button"},
}}
>
<Box className={"results-group-title-container"}>
<Stack
className={"results-group-title-text-container"}
direction={"row"}
>
<DescriptionOutlinedIcon fontSize={"inherit"}/>
<Typography
level={"title-sm"}
>
Page
{" "}
{pageNum}
</Typography>
</Stack>
<Chip size={"sm"}>
{results.length}
</Chip>
</Box>
</AccordionSummary>
<AccordionDetails className={"results-group-content"}>
<List size={"sm"}>
{results.map((r, index) => (
<Result
key={index}
matchRange={r.matchRange}
message={r.message}/>
))}
</List>
</AccordionDetails>
</Accordion>
);
};

export default ResultsGroup;
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import {useState} from "react";

import {
AccordionGroup,
IconButton,
Textarea,
ToggleButtonGroup,
} from "@mui/joy";

import UnfoldLessIcon from "@mui/icons-material/UnfoldLess";
import UnfoldMoreIcon from "@mui/icons-material/UnfoldMore";

import {
TAB_DISPLAY_NAMES,
TAB_NAME,
} from "../../../../../typings/tab";
import CustomTabPanel from "../CustomTabPanel";
import TitleButton from "../TitleButton";
import ResultsGroup from "./ResultsGroup";


enum SEARCH_OPTION {
IS_CASE_SENSITIVE = "isCaseSensitive",
IS_REGEX = "isRegex"
}

/**
*
*/
const SAMPLE_RESULTS = Object.freeze({
1: [{logEventNum: 1,
message: "hi how are you",
matchRange: [0,
2] as [number, number]}],
2: [{logEventNum: 202,
message: "i'm a super long message that supposedly overflows in the panel width.",
matchRange: [4,
6] as [number, number]}],
8: [{logEventNum: 808,
message: "hi how are you",
matchRange: [4,
6] as [number, number]},
{logEventNum: 809,
message: "hi how are you",
matchRange: [4,
6] as [number, number]}],
});

/**
* Displays a panel for submitting search queries and viewing query results.
*
* @return
*/
const SearchTabPanel = () => {
const [isAllExpanded, setIsAllExpanded] = useState<boolean>(true);
const [searchOptions, setSearchOptions] = useState<SEARCH_OPTION[]>([]);

return (
<CustomTabPanel
tabName={TAB_NAME.SEARCH}
title={TAB_DISPLAY_NAMES[TAB_NAME.SEARCH]}
titleButtons={<>
<TitleButton onClick={() => { setIsAllExpanded((v) => !v); }}>
{isAllExpanded ?
<UnfoldLessIcon/> :
<UnfoldMoreIcon/>}
</TitleButton>
</>}
>
<Textarea
maxRows={7}
placeholder={"Search"}
size={"sm"}
slotProps={{endDecorator: {sx: {marginBlockStart: 0, display: "block"}}}}
sx={{flexDirection: "row"}}
endDecorator={
<>
<ToggleButtonGroup
size={"sm"}
spacing={0.3}
sx={{borderRadius: "2px"}}
value={searchOptions}
variant={"plain"}
onChange={(_, newValue) => {
setSearchOptions(newValue);
}}
>
<IconButton
sx={{fontFamily: "Inter"}}
value={SEARCH_OPTION.IS_CASE_SENSITIVE}
>
Aa
</IconButton>
<IconButton
sx={{fontFamily: "Inter"}}
value={SEARCH_OPTION.IS_REGEX}
>
.*
</IconButton>
</ToggleButtonGroup>
</>
}/>
<AccordionGroup
disableDivider={true}
size={"sm"}
>
{Object.entries(SAMPLE_RESULTS).map(([pageNum, resultsOnPage]) => (
<ResultsGroup
isAllExpanded={isAllExpanded}
key={pageNum}
pageNum={parseInt(pageNum, 10)}
results={resultsOnPage}/>
))}
</AccordionGroup>
</CustomTabPanel>
);
};

export default SearchTabPanel;
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.sidebar-tab-title-button {
min-width: 0 !important;
min-height: 0 !important;
}
Loading

0 comments on commit 5094abf

Please sign in to comment.