0% found this document useful (0 votes)
7K views11 pages

Overview Models

This document defines components for displaying model overview data in React. It imports React and Material UI components. It defines an Overview component that accepts model type as a prop. The component uses hooks to make API calls to fetch overview data based on the model type. It handles date range filtering and displays the results in a graph and summary list. On modal open, it also allows creating a new experiment from the selected overview data.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
7K views11 pages

Overview Models

This document defines components for displaying model overview data in React. It imports React and Material UI components. It defines an Overview component that accepts model type as a prop. The component uses hooks to make API calls to fetch overview data based on the model type. It handles date range filtering and displays the results in a graph and summary list. On modal open, it also allows creating a new experiment from the selected overview data.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 11

import React, {

useCallback,
useEffect,
useMemo,
useRef,
useState,
} from 'react';
import { useNavigate } from 'react-router-dom';
import { useDispatch } from 'react-redux';
import {
Paper,
Stack,
Typography,
Button,
TextField,
Box,
} from '@mui/material';
import {
// dateIsValid as isValidDate,
validateDateRangeFilter,
} from 'utils/validations';

import AssignmentOutlinedIcon from '@mui/icons-material/AssignmentOutlined';


import { ApprovalDialog } from 'components/search/dictionary/ApprovalDialog';
import { R_MODELS_CONFIGURATION } from 'routes/route_constants';
import { showAlert } from 'store/actions/alert';
import { useApi, useAppId, useQuery } from 'hooks';
import theme from 'theme';
import { ModelType } from 'components/models/types';
import { MLOpsService } from 'services';
import { modelsApis } from 'apiEndpoints';
import {
GetDateRangeFilter,
getDateRange,
} from 'components/reusable/GetDateRangeFilter';
import { useSearchParams } from 'react-router-dom';
import { StoreType } from 'store/types/store/state';
import { startDate as START_DATE_ACTION } from 'store/actions/dates';
import { dateIsValid as isValidDate } from 'utils/validations';
import { DateRange } from '@mui/lab';
import { useSelector } from 'react-redux';
import { Debounce } from 'utils/debounce';
import NEROverview from './NEROverview';

interface IOverviewProps {
modelType: ModelType;
text?: string | React.ReactNode;
}

export type State = {


userQueries: unknown[];
field_config: any[];

overviewType: string | undefined;


summaryList: unknown[];
summaryFieldConfig: any[];
graph: {
data_points: { x: string; y: number }[];
x_axis_field: string;
y_axis_field: string[];
data_key: { key: string; label: string }[];
};
isGraphLoading: boolean;
selectedMetrics?: string[];
};
export const Overview = (props: IOverviewProps) => {
const { text, modelType } = props;
const defaultSearchMetrics =
modelType === 'RANKING'
? ['ndcg_views']
: [
'oov_query_frequency',
// 'total_search_term_frequency',
];
const createExperimentAPI = useApi(MLOpsService.createExperiment);
const experimentsGridAPI = useApi(MLOpsService.experimentsGrid);
const createNERViewMetricsAPI = useApi(MLOpsService.createNERViewMetrics);
const createCLSViewMetricsAPI = useApi(MLOpsService.createCLSViewMetrics);
const createRankingViewMetricsApi = useApi(
MLOpsService.createRankingViewMetrics
);

const apiMapping: any = {


NER: createNERViewMetricsAPI,
CLS: createCLSViewMetricsAPI,
RANKING: createRankingViewMetricsApi,
};

const { loading } = createExperimentAPI;


const onboardingReducer = useSelector(
(store: StoreType) => store.onboardingReducer
);
const clickStreamEnabled =
onboardingReducer?.getAppSettingsConfig?.data?.click_stream_enabled ||
false;
const dispatch = useDispatch();
const [searchParams] = useSearchParams();
const [state, setState] = useState<any>(() => ({
userQueries: [],
field_config: [],
// page: pageFromSearchParams || 0,
// page_size: pageSizeFromSearchParams || 25,
// loading: false,
// showTopUserQueriesDrawer: false,
// searchText: '',
// isSearchTextAdded: false,
// sortBy: '',
// sortOrder: -1,
// total: 0,
overviewType: 'total_searches',
summaryList: [],
summaryFieldConfig: [],
graph: {
data_points: [{ x: '', y: 0 }],
x_axis_field: '',
y_axis_field: [],
data_key: [],
},
isGraphLoading: false,
isFileDownLoadInitiated: false,
selectedMetrics: defaultSearchMetrics,
}));

const query = useQuery();


const start = query.get('start_date');
const end = query.get('end_date');
const type = query.get('type');
const dateStart = searchParams.get('dateStart');
const dateEnd = searchParams.get('dateEnd');
const dateType = searchParams.get('dateType');
useEffect(() => {
if (dateStart && dateEnd && dateType) {
dispatch(
START_DATE_ACTION({
start_date: dateStart,
end_date: dateEnd,
date_type: dateType,
})
);
}
}, [dateStart, dateEnd, dateType]);

const dateFromStorage = useSelector((state: StoreType) => state.dateReducer);


const start_date =
(isValidDate(dateFromStorage?.start_date?.toString()) &&
new Date(dateFromStorage?.start_date)?.toISOString()) ||
(isValidDate(dateStart?.toString()) && new Date(dateStart)?.toISOString());
const end_date =
(isValidDate(dateFromStorage?.end_date?.toString()) &&
new Date(dateFromStorage?.end_date)?.toISOString()) ||
(isValidDate(dateEnd?.toString()) && new Date(dateEnd)?.toISOString());
const [selectedDateRange, setSelectedDateRange] = useState(
dateFromStorage?.date_type || type || dateType || 'last_7_days'
);
const [selectedCustomDateRange, setSelectedCustomDateRange] = React.useState<
DateRange<Date>
>([
(start_date && new Date(start_date)) ||
(start && new Date(start)) ||
new Date(),
(end_date && new Date(end_date)) || (end && new Date(end)) || new Date(),
]);
const [showDatePicker, setShowDatePicker] = useState(false);
const selectedDateRangeRef = useRef(selectedDateRange);
const selectedCustomDateRangeRef = useRef(selectedCustomDateRange);

const navigate = useNavigate();


const getAppId = useAppId('search');
// const [showDatePicker, setShowDatePicker] = useState(false);
const selectWorkspace = useSelector(
(store: StoreType) => store.selectWorkspace
);
const [openModal, setOpenModal] = useState(false);
const [experimentName, setExperimentName] = useState('');
// const experimentsGridData = experimentsGridAPI?.data?.data?.data;

const { startDate, endDate } = useMemo(


() => getDateRange(selectedDateRange, selectedCustomDateRange),
[selectedDateRange, selectedCustomDateRange]
);

const handleCreateExperiment = () => {


createExperimentAPI
.request({
data: {
params: {
app_id: getAppId,
model_type: modelType,
name: experimentName,
},
},
})
.then(res => {
dispatch(
showAlert({
message: 'Experiment created successfully',
severity: 'success',
})
);
navigate(
`${R_MODELS_CONFIGURATION(modelType.toLowerCase())}?exp_id=${
res?.data?.data?._id
}`
);
setOpenModal(false);
});
};
const handleOverviewGraphApiCall = (postData?: any) => {
if (modelType === 'NER' || modelType === 'CLS' || modelType === 'RANKING') {
const payload = {
data: {
metrics_type:
modelType === 'RANKING' ? ['OVERVIEW_GRAPH'] : ['OVERVIEW'],
view_type: 'GRAPH',
app_id: getAppId,
clickstream: clickStreamEnabled,
...postData,
},
};
if (
selectWorkspace?.applications?.length > 0 &&
((selectedDateRangeRef.current === 'custom' &&
!validateDateRangeFilter(
selectedDateRangeRef.current,
selectedCustomDateRangeRef.current[0],
selectedCustomDateRangeRef.current[1]
)?.error) ||
selectedDateRangeRef.current !== 'custom')
) {
setState((prev: State) => ({ ...prev, isGraphLoading: true }));
// createNERViewMetricsAPI
apiMapping[modelType]
?.request(payload)
.then((res: any) => {
const dataKey: Set<string> = new Set();
const graphLabel =
modelType === 'RANKING' ? 'OVERVIEW_GRAPH' : 'OVERVIEW';

if (res?.data?.[graphLabel]?.data)
res?.data?.[graphLabel]?.data?.graph?.data_points?.forEach(
(data: any) => {
Object.keys(data).forEach(key => {
if (key !== 'date') {
dataKey.add(key);
}
});
}
);

setState((prev: State) => ({


...prev,
graph: {
data_points: res?.data?.[graphLabel].data?.graph?.data_points,
x_axis_field:
res?.data?.[graphLabel]?.data?.graph?.x_axis_field,
y_axis_field:
res?.data?.[graphLabel]?.data?.graph?.y_axis_field,
data_key: res?.data?.[graphLabel]?.data
? Array.from(dataKey)?.map((key: string) => ({
key,
label:
res?.data?.[graphLabel]?.meta?.field_config?.find(
(field: any) => field?.field_name === key
)?.label || key,
// color:
// index >= segmentColors?.length
// ? getRandomColor()
// : segmentColors[index],
}))
: [],
},
summaryList: res?.data?.[graphLabel].data?.summary,
summaryFieldConfig: res?.data?.[graphLabel]?.meta?.field_config,
isGraphLoading: false,
}));
})
.catch((errors: { msg: string }[]) => {
dispatch(
showAlert({
message: errors?.[0]?.msg || 'Something Went Wrong!',
severity: 'error',
})
);
setState((prev: State) => ({
...prev,
isGraphLoading: false,
}));
});
}
}
};
const dateRangeProps = {
selectedCustomDateRange,
selectedDateRange,
showDatePicker,
setShowDatePicker,
setSelectedDateRange,
setSelectedCustomDateRange,
};

useEffect(() => {
if (getAppId && modelType) {
experimentsGridAPI.request({
params: {
path: modelsApis.GET_EXPERIMENT_DETAILS,
method: 'POST',
},
data: {
payload: {
app_id: getAppId,
model_type: modelType.toUpperCase(),
// ...postData,
},
},
});
}
}, []);
const graphCall = useCallback(Debounce(handleOverviewGraphApiCall, 500), []);
const graphPayload = {
// filters: [],
start_date: startDate,
end_date: endDate,
app_id: getAppId,
clickstream: clickStreamEnabled,
pagination: {
page: state.page,
page_size: state.page_size,
},
// filters:
// state.selectedMetrics?.length > 0
// ? [{ y_field: state.selectedMetrics.map((item: any) => item) }]
// : [
// {
// y_field: [],
// },
// ],
};

useEffect(() => {
if (selectedDateRange === 'custom') {
graphCall(graphPayload);
} else {
handleOverviewGraphApiCall(graphPayload);
}
}, [selectedCustomDateRange, selectedDateRange]);
selectedDateRangeRef.current = selectedDateRange;
selectedCustomDateRangeRef.current = selectedCustomDateRange;

// const graphfilteredData = state?.graph?.data_points.map((item: any) => {


// const filteredItem: any = {};
// filteredItem.date = item?.date;

// for (const metric of state?.selectedMetrics) {


// if (item.hasOwnProperty(metric)) {
// filteredItem[metric] = item[metric];
// }
// }

// return filteredItem;
// });

// const selectedObjects = state?.graph?.data_key.filter((item: any) =>


// state?.selectedMetrics.includes(item.key)
// );
return (
<Paper
elevation={0}
sx={{
background: theme.palette.common.white,
border: `1px solid ${theme.palette.grey[300]}`,
// height: 'calc(100vh - 190px)',
// height: 'calc(100vh - 120px)',
// height: 'fit-content',
padding: '31px 24px',
}}
>
{experimentsGridAPI?.data?.data?.data?.length === 0 ||
(['SPELL'].includes(modelType) && (
<Stack>
<Stack direction="column" gap={4}>
<Typography
sx={{
fontWeight: theme.typography.customFontWeight.medium,
fontSize: theme.typography.customFontSize.xxxl,
}}
>
{modelType} Model Training
</Typography>
<Stack direction="row" gap={2}>
<Stack gap={3}>
<AssignmentOutlinedIcon
sx={{
fontSize: '10rem',
}}
/>
<Button
variant="outlined"
disableRipple
sx={{
width: 'fit-content',
fontSize: theme.typography.customFontSize.sm,
fontWeight: theme.typography.customFontWeight.regular,
}}
onClick={() => setOpenModal(true)}
>
Start Configuration
</Button>
</Stack>
<Stack
direction="column"
sx={{
gap: '0.5rem',
}}
>
<Typography
sx={{
fontWeight: theme.typography.customFontWeight.medium,
fontSize: theme.typography.customFontSize.md,
}}
>
Train your first model
</Typography>
<Stack
sx={{
height: 'calc(100vh - 290px)',
overflow: 'auto',
width: '500px',
}}
spacing={1}
>
{text}
</Stack>
</Stack>
</Stack>
</Stack>
</Stack>
))}
{/* {experimentsGridAPI?.data?.data?.data?.length !== 0 &&
(modelType === 'NER' || modelType === 'CLS') &&
state?.summaryFieldConfig?.length > 0 && (
<Stack width="210px" direction="row" pt={2}>
<MetricsDropdown
options={state?.summaryFieldConfig?.filter(
(item: any) => item?.selectable
)}
defaultMetrics={['total_search_term_frequency']}
title="Maximum 5"
selectedMatchCriteria={state.selectedMetrics}
setSelectedMatchCriteria={(value: any) =>
setState((prev: State) => ({
...prev,
selectedMetrics: value,
}))
}
/>
</Stack>
)}
{experimentsGridAPI?.data?.data?.data?.length !== 0 &&
modelType === 'NER' && (
<Stack pt={2} flexGrow={1} sx={{ '.recharts-surface': { p: 0.3 } }}>
{state.isGraphLoading ? (
<Skeleton
height="150px"
sx={{
borderRadius: '6px',
flexGrow: 1,
// width: isSidebarOpen
// ? 'calc(100vw - 300px)'
// : 'calc(100vw - 145px)',
}}
animation="wave"
/>
) : (
<>
<SearchLineChart
isCustomToolTip
customToolTip={
<CustomLineChartTooltip
active={undefined}
payload={undefined}
label={undefined}
title="Metrics"
matchCriteria={
state?.field_config?.filter(
(item: any) =>
item.selectable &&
item?.field_name === state?.selectedMetrics
)?.[0]?.label || ''
}
/>
}
dx={-5}
lineData={selectedObjects?.map((item: any, index: any) => ({
dataKey: item?.key,
XAxisLabel: item?.label,
stroke: segmentColors[index],
}))}
width="100%"
height="100%"
margin={{ margin: 30 }}
data={graphfilteredData}
XDataKey="date"
YAxisLabel={
state?.graph?.y_axis_field?.length > 1
? 'Metrics'
: state?.summaryFieldConfig?.filter(
(item: any) =>
item?.field_name === state?.graph?.y_axis_field?.[0]
)?.[0]?.label
}
containerHeight={230}
// YAxisLabel={
// state?.graph?.y_axis_field?.length > 1
// ? 'metrics'
// : state?.graph?.y_axis_field?.[0]
// }
/>
</>
)}
</Stack>
)}
<Divider sx={{ mt: 2 }} />
{experimentsGridAPI?.data?.data?.data?.length !== 0 &&
(modelType === 'NER' || modelType === 'CLS') && (
<Stack mt={2}>
<TopSearches
queryType="OVERVIEW"
searchAndFilterNeeded
mainAPI={apiMapping[modelType]}
dateRangeProps={dateRangeProps}
isDefaultColumnsNeeded
defaultColumns={[
'search_term',
'ner',
'model_id',
'total_searches',
'clicks',
'cr',
'ctr',
]}
/>
<Stack gap={2} mt={2} direction="row">
<Stack>
<TopSearches
queryType="OVERVIEW_OOV_WORDS"
mainAPI={apiMapping[modelType]}
tableWidth="calc(50vw - 186px)"
minWidth={350}
dateRangeProps={dateRangeProps}
defaultColumns={['oov_word', 'frequency']}
/>
</Stack>
<Stack>
<TopSearches
queryType="OVERVIEW_OOV_QUERIES"
mainAPI={apiMapping[modelType]}
tableWidth="calc(50vw - 186px)"
minWidth={350}
dateRangeProps={dateRangeProps}
defaultColumns={['search_term', 'frequency']}
/>
</Stack>
</Stack>
</Stack>
)} */}
{experimentsGridAPI?.data?.data?.data?.length !== 0 &&
['NER', 'CLS', 'RANKING']?.includes(modelType) &&
modelType?.length > 0 && (
<NEROverview
experimentsGridAPI={
experimentsGridAPI?.data?.data?.data?.length !== 0
}
modelType={modelType}
state={state}
setState={setState}
dateRangeProps={dateRangeProps}
apiMapping={apiMapping}
/>
)}
{/* <CLSOverview
experimentsGridAPI={experimentsGridAPI}
modelType={modelType}
state={state}
setState={setState}
dateRangeProps={dateRangeProps}
apiMapping={apiMapping}
/> */}
<ApprovalDialog
open={openModal}
approveBtnText="Create"
handleClose={() => {
setOpenModal(false);
// setAnchorEl(null);
// setId('');
}}
validateData={() => experimentName?.length === 0}
handleApproval={handleCreateExperiment}
title="Experiment Name"
loading={loading}
>
<Stack spacing={1}>
<Stack>
<Typography
sx={{
fontSize: theme.typography.customFontSize.sm,
fontWeight: theme.typography.customFontWeight.regular,
color: theme.palette.text.secondary,
}}
>
Enter a name for the experiment
</Typography>
</Stack>
<Stack spacing={0.5}>
<Typography
sx={{
fontSize: theme.typography.customFontSize.sm,
fontWeight: theme.typography.customFontWeight.semiBold,
}}
>
Experiment Name
</Typography>
<TextField
placeholder="Enter Name"
value={experimentName}
onChange={e => setExperimentName(e.target.value)}
/>
</Stack>
</Stack>
</ApprovalDialog>
{experimentsGridAPI?.data?.data?.data?.length !== 0 &&
(modelType === 'NER' ||
modelType === 'CLS' ||
modelType === 'RANKING') && (
<Box sx={{ position: 'absolute', right: '2%', top: '4px' }}>
<GetDateRangeFilter {...dateRangeProps} />
</Box>
)}
</Paper>
);
};

You might also like