forked from y-scope/clp
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add support for viewing search results in context for text logs (clp-…
…text). (y-scope#489)
- Loading branch information
1 parent
b96f5a1
commit e9d5b2b
Showing
17 changed files
with
1,000 additions
and
108 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import axios from "axios"; | ||
|
||
|
||
/** | ||
* @typedef {object} ExtractIrResp | ||
* @property {number} begin_msg_ix | ||
* @property {number} end_msg_ix | ||
* @property {string} file_split_id | ||
* @property {boolean} is_last_ir_chunk | ||
* @property {string} orig_file_id | ||
* @property {string} path | ||
* @property {string} _id | ||
*/ | ||
|
||
/** | ||
* Submits a job to extract the split of an original file that contains a given log event. The file | ||
* is extracted as a CLP IR file. | ||
* | ||
* @param {number|string} origFileId The ID of the original file | ||
* @param {number} logEventIdx The index of the log event | ||
* @param {Function} onUploadProgress Callback to handle upload progress events. | ||
* @return {Promise<axios.AxiosResponse<ExtractIrResp>>} | ||
*/ | ||
const submitExtractIrJob = async (origFileId, logEventIdx, onUploadProgress) => { | ||
return await axios.post( | ||
"/query/extract-ir", | ||
{logEventIdx, origFileId}, | ||
{onUploadProgress} | ||
); | ||
}; | ||
|
||
export {submitExtractIrJob}; |
8 changes: 8 additions & 0 deletions
8
components/log-viewer-webui/client/src/typings/LOCAL_STORAGE_KEY.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
/** | ||
* Enum of `window.localStorage` keys. | ||
*/ | ||
const LOCAL_STORAGE_KEY = Object.freeze({ | ||
UI_THEME: "uiTheme", | ||
}); | ||
|
||
export default LOCAL_STORAGE_KEY; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
/** | ||
* @typedef {number} QueryLoadingState | ||
*/ | ||
let enumQueryLoadingState; | ||
/** | ||
* Enum of query loading state. | ||
* | ||
* @enum {QueryLoadingState} | ||
*/ | ||
const QUERY_LOADING_STATES = Object.freeze({ | ||
SUBMITTING: (enumQueryLoadingState = 0), | ||
WAITING: ++enumQueryLoadingState, | ||
LOADING: ++enumQueryLoadingState, | ||
}); | ||
|
||
/** | ||
* Descriptions for query loading states. | ||
*/ | ||
const QUERY_LOADING_STATE_DESCRIPTIONS = Object.freeze({ | ||
[QUERY_LOADING_STATES.SUBMITTING]: { | ||
label: "Submitting query Job", | ||
description: "Parsing arguments and submitting job to the server.", | ||
}, | ||
[QUERY_LOADING_STATES.WAITING]: { | ||
label: "Waiting for job to finish", | ||
description: "The job is running. Waiting for the job to finish.", | ||
}, | ||
[QUERY_LOADING_STATES.LOADING]: { | ||
label: "Loading Log Viewer", | ||
description: "The query has been completed and the results are being loaded.", | ||
}, | ||
}); | ||
|
||
export { | ||
QUERY_LOADING_STATE_DESCRIPTIONS, | ||
QUERY_LOADING_STATES, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
.loading-sheet { | ||
height: 100%; | ||
|
||
display: flex; | ||
flex-direction: column; | ||
|
||
align-items: center; | ||
justify-content: center; | ||
} | ||
|
||
.loading-progress-container { | ||
width: 100%; | ||
} | ||
|
||
.loading-stepper-container { | ||
display: flex; | ||
flex-grow: 1; | ||
|
||
align-items: center; | ||
} | ||
|
||
.loading-stepper { | ||
--Stepper-verticalGap: 2rem !important; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
import { | ||
Box, | ||
LinearProgress, | ||
Sheet, | ||
Step, | ||
StepIndicator, | ||
Stepper, | ||
Typography, | ||
} from "@mui/joy"; | ||
|
||
import { | ||
QUERY_LOADING_STATE_DESCRIPTIONS, | ||
QUERY_LOADING_STATES, | ||
} from "../typings/query.js"; | ||
|
||
import "./Loading.css"; | ||
|
||
|
||
/** | ||
* Renders a step with a label and description. | ||
* | ||
* @param {object} props | ||
* @param {string} props.description | ||
* @param {boolean} props.isActive | ||
* @param {boolean} props.isError | ||
* @param {string} props.label | ||
* @param {number | string} props.stepIndicatorText | ||
* @return {React.ReactElement} | ||
*/ | ||
const LoadingStep = ({ | ||
description, | ||
isActive, | ||
isError, | ||
label, | ||
stepIndicatorText, | ||
}) => { | ||
let color = isActive ? | ||
"primary" : | ||
"neutral"; | ||
|
||
if (isError) { | ||
color = "danger"; | ||
} | ||
|
||
return ( | ||
<Step | ||
indicator={ | ||
<StepIndicator | ||
color={color} | ||
variant={isActive ? | ||
"solid" : | ||
"outlined"} | ||
> | ||
{stepIndicatorText} | ||
</StepIndicator> | ||
} | ||
> | ||
<Typography | ||
color={color} | ||
level={"title-lg"} | ||
> | ||
{label} | ||
</Typography> | ||
<Typography level={"body-sm"}> | ||
{description} | ||
</Typography> | ||
</Step> | ||
); | ||
}; | ||
|
||
/** | ||
* Displays status of a pending query job. | ||
* | ||
* @param {object} props | ||
* @param {QueryLoadState} props.currentState | ||
* @param {string} props.errorMsg | ||
* @return {React.ReactElement} | ||
*/ | ||
const Loading = ({currentState, errorMsg}) => { | ||
const steps = []; | ||
Object.values(QUERY_LOADING_STATES).forEach((state) => { | ||
const isActive = (currentState === state); | ||
const stateDescription = QUERY_LOADING_STATE_DESCRIPTIONS[state]; | ||
steps.push( | ||
<LoadingStep | ||
description={stateDescription.description} | ||
isActive={isActive} | ||
isError={false} | ||
key={state} | ||
label={stateDescription.label} | ||
stepIndicatorText={state + 1}/> | ||
); | ||
if (isActive && null !== errorMsg) { | ||
steps.push( | ||
<LoadingStep | ||
description={errorMsg} | ||
isActive={isActive} | ||
isError={true} | ||
key={`${state}-error`} | ||
label={"Error"} | ||
stepIndicatorText={"X"}/> | ||
); | ||
} | ||
}); | ||
|
||
return ( | ||
<> | ||
<Sheet className={"loading-sheet"}> | ||
<Box className={"loading-progress-container"}> | ||
<LinearProgress | ||
determinate={null !== errorMsg} | ||
color={null === errorMsg ? | ||
"primary" : | ||
"danger"}/> | ||
</Box> | ||
<Box className={"loading-stepper-container"}> | ||
<Stepper | ||
className={"loading-stepper"} | ||
orientation={"vertical"} | ||
size={"lg"} | ||
> | ||
{steps} | ||
</Stepper> | ||
</Box> | ||
</Sheet> | ||
</> | ||
); | ||
}; | ||
|
||
export default Loading; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
import { | ||
useEffect, | ||
useRef, | ||
useState, | ||
} from "react"; | ||
|
||
import {AxiosError} from "axios"; | ||
|
||
import {submitExtractIrJob} from "../api/query.js"; | ||
import {QUERY_LOADING_STATES} from "../typings/query.js"; | ||
import Loading from "./Loading.jsx"; | ||
|
||
|
||
/** | ||
* Submits queries and renders the query states. | ||
* | ||
* @return {React.ReactElement} | ||
*/ | ||
const QueryStatus = () => { | ||
const [queryState, setQueryState] = useState(QUERY_LOADING_STATES.SUBMITTING); | ||
const [errorMsg, setErrorMsg] = useState(null); | ||
const isFirstRun = useRef(true); | ||
|
||
useEffect(() => { | ||
if (false === isFirstRun.current) { | ||
return; | ||
} | ||
isFirstRun.current = false; | ||
|
||
const searchParams = new URLSearchParams(window.location.search); | ||
const origFileId = searchParams.get("origFileId"); | ||
const logEventIdx = searchParams.get("logEventIdx"); | ||
if (null === origFileId || null === logEventIdx) { | ||
const error = "Either `origFileId` or `logEventIdx` are missing from the URL " + | ||
"parameters. Note that non-IR-extraction queries are not supported at the moment."; | ||
|
||
console.error(error); | ||
setErrorMsg(error); | ||
return; | ||
} | ||
|
||
submitExtractIrJob( | ||
origFileId, | ||
Number(logEventIdx), | ||
() => { | ||
setQueryState(QUERY_LOADING_STATES.WAITING); | ||
} | ||
) | ||
.then(({data}) => { | ||
setQueryState(QUERY_LOADING_STATES.LOADING); | ||
|
||
const innerLogEventNum = logEventIdx - data.begin_msg_ix + 1; | ||
window.location = `/log-viewer/index.html?filePath=/ir/${data.path}` + | ||
`#logEventIdx=${innerLogEventNum}`; | ||
}) | ||
.catch((e) => { | ||
let msg = "Unknown error."; | ||
if (e instanceof AxiosError) { | ||
msg = e.message; | ||
if ("undefined" !== typeof e.response) { | ||
if ("undefined" !== typeof e.response.data.message) { | ||
msg = e.response.data.message; | ||
} else { | ||
msg = e.response.statusText; | ||
} | ||
} | ||
} | ||
console.error(msg, e); | ||
setErrorMsg(msg); | ||
}); | ||
}, []); | ||
|
||
return ( | ||
<Loading | ||
currentState={queryState} | ||
errorMsg={errorMsg}/> | ||
); | ||
}; | ||
|
||
export default QueryStatus; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.