-
Notifications
You must be signed in to change notification settings - Fork 26
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(ui): Added new Json Editor revamp code
- Loading branch information
1 parent
bf23120
commit 8619cb2
Showing
7 changed files
with
474 additions
and
20 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
255 changes: 255 additions & 0 deletions
255
...pp/components/alert-wizard-v2/alert-template/preview-chart/preview-chart-v2.component.tsx
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,255 @@ | ||
/* | ||
* Copyright 2023 StarTree Inc | ||
* | ||
* Licensed under the StarTree Community License (the "License"); you may not use | ||
* this file except in compliance with the License. You may obtain a copy of the | ||
* License at http://www.startree.ai/legal/startree-community-license | ||
* | ||
* Unless required by applicable law or agreed to in writing, software distributed under the | ||
* License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OF ANY KIND, | ||
* either express or implied. | ||
* | ||
* See the License for the specific language governing permissions and limitations under | ||
* the License. | ||
*/ | ||
import { Box } from "@material-ui/core"; | ||
import { isEqual } from "lodash"; | ||
import React, { FunctionComponent, useEffect, useMemo, useState } from "react"; | ||
import { useTranslation } from "react-i18next"; | ||
import { useSearchParams } from "react-router-dom"; | ||
import { | ||
SkeletonV1, | ||
useNotificationProviderV1, | ||
} from "../../../../platform/components"; | ||
import { ActionStatus } from "../../../../rest/actions.interfaces"; | ||
import { | ||
useGetAlertInsight, | ||
useGetEvaluation, | ||
} from "../../../../rest/alerts/alerts.actions"; | ||
import { | ||
AlertEvaluation, | ||
EditableAlert, | ||
} from "../../../../rest/dto/alert.interfaces"; | ||
import { | ||
createAlertEvaluation, | ||
extractDetectionEvaluation, | ||
} from "../../../../utils/alerts/alerts.util"; | ||
import { generateNameForDetectionResult } from "../../../../utils/enumeration-items/enumeration-items.util"; | ||
import { notifyIfErrors } from "../../../../utils/notifications/notifications.util"; | ||
import { ChartContent } from "../../../alert-wizard-v3/preview-chart/chart-content/chart-content.component"; | ||
import { PreviewChartHeader } from "../../../alert-wizard-v3/preview-chart/header/preview-chart-header-v3.component"; | ||
import { NoDataIndicator } from "../../../no-data-indicator/no-data-indicator.component"; | ||
import { LoadingErrorStateSwitch } from "../../../page-states/loading-error-state-switch/loading-error-state-switch.component"; | ||
import { TimeRangeQueryStringKey } from "../../../time-range/time-range-provider/time-range-provider.interfaces"; | ||
import { TimeSeriesChartProps } from "../../../visualizations/time-series-chart/time-series-chart.interfaces"; | ||
import { PreviewChartProps } from "./preview-chart.interfaces"; | ||
import { usePreviewChartStyles } from "./preview-chart.styles"; | ||
|
||
export const PreviewChart: FunctionComponent<PreviewChartProps> = ({ | ||
alert, | ||
onChartDataLoadSuccess, | ||
hideCallToActionPrompt, | ||
disableReload, | ||
showTimeRange = true, | ||
children, | ||
legendsPlacement, | ||
}) => { | ||
const classes = usePreviewChartStyles(); | ||
const { t } = useTranslation(); | ||
const [searchParams, setSearchParams] = useSearchParams(); | ||
const [startTime, endTime] = useMemo( | ||
() => [ | ||
Number(searchParams.get(TimeRangeQueryStringKey.START_TIME)), | ||
Number(searchParams.get(TimeRangeQueryStringKey.END_TIME)), | ||
], | ||
[searchParams] | ||
); | ||
const { notify } = useNotificationProviderV1(); | ||
useState<TimeSeriesChartProps>(); | ||
|
||
const [selectedEvaluationToDisplay, setSelectedEvaluationToDisplay] = | ||
useState<string>(""); | ||
const [alertForCurrentEvaluation, setAlertForCurrentEvaluation] = | ||
useState<EditableAlert>(); | ||
const [evaluationTimeRange, setEvaluationTimeRange] = useState({ | ||
startTime: startTime, | ||
endTime: endTime, | ||
}); | ||
const { | ||
evaluation, | ||
getEvaluation, | ||
errorMessages: getEvaluationRequestErrors, | ||
status: getEvaluationStatus, | ||
} = useGetEvaluation(); | ||
|
||
const { | ||
alertInsight, | ||
getAlertInsight, | ||
status: getAlertInsightStatus, | ||
} = useGetAlertInsight(); | ||
|
||
const fetchAlertEvaluation = async ( | ||
start: number, | ||
end: number | ||
): Promise<void> => { | ||
const copiedAlert = { ...alert }; | ||
delete copiedAlert.id; | ||
/* On the Preview Page we have to defer fetching the data for enumeration items till they | ||
are in view. | ||
We only fetch the list of enumeration items without data and anomalies | ||
by passing {listEnumerationItemsOnly: true} as fetching all the data at once introduces | ||
significant latency because of the request size. | ||
Hence we first fetch the evaluations with enumeration items without anomalies and data. | ||
And then enumerationRow component fetches anomalies and data progresivelly */ | ||
const hasEnumerationItems = | ||
!!alert.templateProperties?.enumeratorQuery || | ||
!!alert.templateProperties?.enumerationItems; | ||
const fetchedAlertEvaluation = await getEvaluation( | ||
createAlertEvaluation(copiedAlert, start, end, { | ||
listEnumerationItemsOnly: hasEnumerationItems, | ||
}) | ||
); | ||
|
||
setAlertForCurrentEvaluation(alert); | ||
setEvaluationTimeRange({ startTime: start, endTime: end }); | ||
if (fetchedAlertEvaluation === undefined) { | ||
return; | ||
} | ||
|
||
const evaluations = extractDetectionEvaluation( | ||
fetchedAlertEvaluation as AlertEvaluation | ||
); | ||
// Call the callback function if its passed | ||
onChartDataLoadSuccess && onChartDataLoadSuccess(); | ||
|
||
if (evaluations.length === 1) { | ||
setSelectedEvaluationToDisplay( | ||
generateNameForDetectionResult(evaluations[0]) | ||
); | ||
} else if (evaluations.length > 1) { | ||
// Reset what's chosen if the current selected is not in the data | ||
if ( | ||
evaluations.find( | ||
(evaluation) => | ||
selectedEvaluationToDisplay === | ||
generateNameForDetectionResult(evaluation) | ||
) === undefined | ||
) { | ||
setSelectedEvaluationToDisplay( | ||
generateNameForDetectionResult(evaluations[0]) | ||
); | ||
} | ||
} | ||
}; | ||
|
||
useEffect(() => { | ||
notifyIfErrors( | ||
getEvaluationStatus, | ||
getEvaluationRequestErrors, | ||
notify, | ||
t("message.error-while-fetching", { | ||
entity: t("label.chart-data"), | ||
}) | ||
); | ||
}, [getEvaluationStatus]); | ||
|
||
const handleAutoRangeClick = (): void => { | ||
if ( | ||
getAlertInsightStatus === ActionStatus.Initial || | ||
getAlertInsightStatus === ActionStatus.Error | ||
) { | ||
getAlertInsight({ alert }).then( | ||
(insights) => { | ||
if (insights) { | ||
searchParams.set( | ||
TimeRangeQueryStringKey.START_TIME, | ||
insights.defaultStartTime.toString() | ||
); | ||
searchParams.set( | ||
TimeRangeQueryStringKey.END_TIME, | ||
insights.defaultEndTime.toString() | ||
); | ||
setSearchParams(searchParams, { replace: true }); | ||
fetchAlertEvaluation( | ||
insights.defaultStartTime, | ||
insights.defaultEndTime | ||
); | ||
} else { | ||
fetchAlertEvaluation(startTime, endTime); | ||
} | ||
}, | ||
() => { | ||
// If API fails use current start and end | ||
fetchAlertEvaluation(startTime, endTime); | ||
} | ||
); | ||
} else if ((!startTime || !endTime) && alertInsight) { | ||
// If start or end is missing and there exists an alert insight | ||
fetchAlertEvaluation( | ||
alertInsight.defaultStartTime, | ||
alertInsight.defaultEndTime | ||
); | ||
} else { | ||
fetchAlertEvaluation(startTime, endTime); | ||
} | ||
}; | ||
|
||
return ( | ||
<> | ||
{/** Header Section **/} | ||
<PreviewChartHeader | ||
alertInsight={alertInsight} | ||
disableReload={disableReload} | ||
getEvaluationStatus={getEvaluationStatus} | ||
showConfigurationNotReflective={ | ||
!isEqual(alertForCurrentEvaluation, alert) | ||
} | ||
showTimeRange={showTimeRange} | ||
onReloadClick={handleAutoRangeClick} | ||
onStartEndChange={(newStart, newEnd) => { | ||
fetchAlertEvaluation(newStart, newEnd); | ||
}} | ||
> | ||
{children} | ||
</PreviewChartHeader> | ||
<Box className={classes.chartContainer} marginTop={2}> | ||
<LoadingErrorStateSwitch | ||
errorState={ | ||
<Box pb={20} pt={20}> | ||
<NoDataIndicator> | ||
{t( | ||
"message.experienced-issues-loading-chart-data-try" | ||
)} | ||
</NoDataIndicator> | ||
</Box> | ||
} | ||
isError={getEvaluationStatus === ActionStatus.Error} | ||
isLoading={ | ||
getEvaluationStatus === ActionStatus.Working || | ||
getAlertInsightStatus === ActionStatus.Working | ||
} | ||
loadingState={ | ||
<Box paddingTop={1}> | ||
<SkeletonV1 | ||
animation="pulse" | ||
delayInMS={0} | ||
height={300} | ||
variant="rect" | ||
/> | ||
</Box> | ||
} | ||
> | ||
<ChartContent | ||
showLoadButton | ||
alert={alert} | ||
alertEvaluation={evaluation} | ||
evaluationTimeRange={evaluationTimeRange} | ||
hideCallToActionPrompt={hideCallToActionPrompt} | ||
legendsPlacement={legendsPlacement} | ||
onReloadClick={handleAutoRangeClick} | ||
/> | ||
</LoadingErrorStateSwitch> | ||
</Box> | ||
</> | ||
); | ||
}; |
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
90 changes: 90 additions & 0 deletions
90
...app/components/alert-wizard-v3/preview-chart/header/preview-chart-header-v3.component.tsx
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,90 @@ | ||
/* | ||
* Copyright 2023 StarTree Inc | ||
* | ||
* Licensed under the StarTree Community License (the "License"); you may not use | ||
* this file except in compliance with the License. You may obtain a copy of the | ||
* License at http://www.startree.ai/legal/startree-community-license | ||
* | ||
* Unless required by applicable law or agreed to in writing, software distributed under the | ||
* License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OF ANY KIND, | ||
* either express or implied. | ||
* | ||
* See the License for the specific language governing permissions and limitations under | ||
* the License. | ||
*/ | ||
import { Button, Grid } from "@material-ui/core"; | ||
import RefreshIcon from "@material-ui/icons/Refresh"; | ||
import { Alert } from "@material-ui/lab"; | ||
import React, { FunctionComponent } from "react"; | ||
import { useTranslation } from "react-i18next"; | ||
import { ActionStatus } from "../../../../rest/actions.interfaces"; | ||
import { determineTimezoneFromAlertInEvaluation } from "../../../../utils/alerts/alerts.util"; | ||
import { TimeRangeButtonWithContext } from "../../../time-range/time-range-button-with-context-v2/time-range-button.component"; | ||
import { PreviewChartHeaderProps } from "./preview-chart-header.interfaces"; | ||
import { previewChartHeaderStyles } from "./preview-chart-header.styles"; | ||
|
||
export const PreviewChartHeader: FunctionComponent<PreviewChartHeaderProps> = ({ | ||
alertInsight, | ||
getEvaluationStatus, | ||
disableReload, | ||
onReloadClick, | ||
onStartEndChange, | ||
showConfigurationNotReflective, | ||
showTimeRange = true, | ||
children, | ||
}) => { | ||
const { t } = useTranslation(); | ||
const classes = previewChartHeaderStyles(); | ||
|
||
return ( | ||
<> | ||
{getEvaluationStatus !== ActionStatus.Initial && ( | ||
<Grid | ||
container | ||
alignItems="center" | ||
justifyContent="space-between" | ||
> | ||
<Grid item> | ||
{showTimeRange && ( | ||
<TimeRangeButtonWithContext | ||
hideQuickExtend | ||
btnGroupColor="default" | ||
maxDate={alertInsight?.datasetEndTime} | ||
minDate={alertInsight?.datasetStartTime} | ||
timezone={determineTimezoneFromAlertInEvaluation( | ||
alertInsight?.templateWithProperties | ||
)} | ||
onTimeRangeChange={onStartEndChange} | ||
/> | ||
)} | ||
</Grid> | ||
<Grid item> | ||
<Grid container> | ||
<Grid item> | ||
<Button | ||
className={classes.refreshButton} | ||
color="primary" | ||
disabled={disableReload} | ||
variant="outlined" | ||
onClick={onReloadClick} | ||
> | ||
<RefreshIcon fontSize="small" /> | ||
{t("label.reload-preview")} | ||
</Button> | ||
</Grid> | ||
<Grid item>{children}</Grid> | ||
</Grid> | ||
</Grid> | ||
{showConfigurationNotReflective && | ||
getEvaluationStatus !== ActionStatus.Working && ( | ||
<Grid item> | ||
<Alert severity="warning" variant="outlined"> | ||
{t("message.chart-data-not-reflective")} | ||
</Alert> | ||
</Grid> | ||
)} | ||
</Grid> | ||
)} | ||
</> | ||
); | ||
}; |
24 changes: 24 additions & 0 deletions
24
...ui/src/app/components/alert-wizard-v3/preview-chart/header/preview-chart-header.styles.ts
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 @@ | ||
/* | ||
* Copyright 2024 StarTree Inc | ||
* | ||
* Licensed under the StarTree Community License (the "License"); you may not use | ||
* this file except in compliance with the License. You may obtain a copy of the | ||
* License at http://www.startree.ai/legal/startree-community-license | ||
* | ||
* Unless required by applicable law or agreed to in writing, software distributed under the | ||
* License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OF ANY KIND, | ||
* either express or implied. | ||
* | ||
* See the License for the specific language governing permissions and limitations under | ||
* the License. | ||
*/ | ||
import { makeStyles } from "@material-ui/core"; | ||
|
||
export const previewChartHeaderStyles = makeStyles(() => ({ | ||
refreshButton: { | ||
color: "#006065", | ||
height: "36px", | ||
backgroundColor: "#E0F7FA", | ||
borderRadius: "8px", | ||
}, | ||
})); |
Oops, something went wrong.