From 5094abf52c389c9271daa57b2fb001bf8dbddfdf Mon Sep 17 00:00:00 2001 From: Henry8192 <50559854+Henry8192@users.noreply.github.com> Date: Thu, 24 Oct 2024 18:00:09 -0400 Subject: [PATCH 01/24] refactor SearchTabPanel from new log viewer folder back to current log viewer --- .../Sidebar/SidebarTabs/CustomTabPanel.tsx | 17 ++- .../SidebarTabs/SearchTabPanel/Result.css | 15 +++ .../SidebarTabs/SearchTabPanel/Result.tsx | 61 +++++++++ .../SearchTabPanel/ResultsGroup.css | 21 ++++ .../SearchTabPanel/ResultsGroup.tsx | 107 ++++++++++++++++ .../SidebarTabs/SearchTabPanel/index.tsx | 119 ++++++++++++++++++ .../Sidebar/SidebarTabs/TitleButton.css | 4 + .../Sidebar/SidebarTabs/TitleButton.tsx | 21 ++++ .../Sidebar/SidebarTabs/index.tsx | 4 + src/typings/tab.ts | 2 + 10 files changed, 370 insertions(+), 1 deletion(-) create mode 100644 src/components/CentralContainer/Sidebar/SidebarTabs/SearchTabPanel/Result.css create mode 100644 src/components/CentralContainer/Sidebar/SidebarTabs/SearchTabPanel/Result.tsx create mode 100644 src/components/CentralContainer/Sidebar/SidebarTabs/SearchTabPanel/ResultsGroup.css create mode 100644 src/components/CentralContainer/Sidebar/SidebarTabs/SearchTabPanel/ResultsGroup.tsx create mode 100644 src/components/CentralContainer/Sidebar/SidebarTabs/SearchTabPanel/index.tsx create mode 100644 src/components/CentralContainer/Sidebar/SidebarTabs/TitleButton.css create mode 100644 src/components/CentralContainer/Sidebar/SidebarTabs/TitleButton.tsx diff --git a/src/components/CentralContainer/Sidebar/SidebarTabs/CustomTabPanel.tsx b/src/components/CentralContainer/Sidebar/SidebarTabs/CustomTabPanel.tsx index 9d1ab3e7..c9809988 100644 --- a/src/components/CentralContainer/Sidebar/SidebarTabs/CustomTabPanel.tsx +++ b/src/components/CentralContainer/Sidebar/SidebarTabs/CustomTabPanel.tsx @@ -1,6 +1,7 @@ import React from "react"; import { + ButtonGroup, DialogContent, DialogTitle, TabPanel, @@ -14,6 +15,7 @@ interface CustomTabPanelProps { children: React.ReactNode, tabName: string, title: string, + titleButtons?: React.ReactNode, } /** @@ -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 ( { > {title} + + {titleButtons} + {children} diff --git a/src/components/CentralContainer/Sidebar/SidebarTabs/SearchTabPanel/Result.css b/src/components/CentralContainer/Sidebar/SidebarTabs/SearchTabPanel/Result.css new file mode 100644 index 00000000..e68e46be --- /dev/null +++ b/src/components/CentralContainer/Sidebar/SidebarTabs/SearchTabPanel/Result.css @@ -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; +} diff --git a/src/components/CentralContainer/Sidebar/SidebarTabs/SearchTabPanel/Result.tsx b/src/components/CentralContainer/Sidebar/SidebarTabs/SearchTabPanel/Result.tsx new file mode 100644 index 00000000..591bd835 --- /dev/null +++ b/src/components/CentralContainer/Sidebar/SidebarTabs/SearchTabPanel/Result.tsx @@ -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 ( + + + {beforeMatch} + + + {match} + + + {afterMatch} + + + ); +}; + +export default Result; diff --git a/src/components/CentralContainer/Sidebar/SidebarTabs/SearchTabPanel/ResultsGroup.css b/src/components/CentralContainer/Sidebar/SidebarTabs/SearchTabPanel/ResultsGroup.css new file mode 100644 index 00000000..5244d6a1 --- /dev/null +++ b/src/components/CentralContainer/Sidebar/SidebarTabs/SearchTabPanel/ResultsGroup.css @@ -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); +} diff --git a/src/components/CentralContainer/Sidebar/SidebarTabs/SearchTabPanel/ResultsGroup.tsx b/src/components/CentralContainer/Sidebar/SidebarTabs/SearchTabPanel/ResultsGroup.tsx new file mode 100644 index 00000000..fe9e7b73 --- /dev/null +++ b/src/components/CentralContainer/Sidebar/SidebarTabs/SearchTabPanel/ResultsGroup.tsx @@ -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(isAllExpanded); + + const handleAccordionChange = ( + _: React.SyntheticEvent, + newValue: boolean + ) => { + setIsExpanded(newValue); + }; + + // On `isAllExpanded` updates, sync current results group's expand status. + useEffect(() => { + setIsExpanded(isAllExpanded); + }, [isAllExpanded]); + + return ( + + + + + + + Page + {" "} + {pageNum} + + + + {results.length} + + + + + + {results.map((r, index) => ( + + ))} + + + + ); +}; + +export default ResultsGroup; diff --git a/src/components/CentralContainer/Sidebar/SidebarTabs/SearchTabPanel/index.tsx b/src/components/CentralContainer/Sidebar/SidebarTabs/SearchTabPanel/index.tsx new file mode 100644 index 00000000..ce1cbda6 --- /dev/null +++ b/src/components/CentralContainer/Sidebar/SidebarTabs/SearchTabPanel/index.tsx @@ -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(true); + const [searchOptions, setSearchOptions] = useState([]); + + return ( + + { setIsAllExpanded((v) => !v); }}> + {isAllExpanded ? + : + } + + } + > +