feat: load data based on isLoaded flag

This commit is contained in:
Nidhi Tandon 2021-05-23 15:40:48 +05:30
parent 44495b7669
commit e4b41b1a27
5 changed files with 56 additions and 38 deletions

View File

@ -13,41 +13,12 @@ interface BaseLayoutProps {
children: ReactNode;
}
interface RouteObj {
[key: string]: {
route: string;
isLoaded: boolean;
};
}
const BaseLayout: React.FC<BaseLayoutProps> = ({ children }) => {
const location = useLocation();
const { dispatch } = useRoute();
/*
Create a routes obj with values as
{
SERVICE_MAP: {
route: '/service-map',
isLoaded: false
}
*/
const routes: RouteObj = {};
Object.keys(ROUTES).map((items) => {
routes[items] = {
route: `${ROUTES[items]}`,
isLoaded: false,
};
});
useEffect(() => {
/*
Update the isLoaded property in routes obj
if the route matches the current pathname
*/
Object.keys(ROUTES).map((items) => {
routes[items].isLoaded = routes[items].route === location.pathname;
});
dispatch({ type: "UPDATE", payload: routes });
dispatch({ type: "UPDATE_IS_LOADED", payload: location.pathname });
}, [location]);
return (

View File

@ -1,4 +1,5 @@
import React, { useContext, createContext, ReactNode, Dispatch } from "react";
import ROUTES from "Src/constants/routes";
type State = {
[key: string]: {
@ -7,9 +8,13 @@ type State = {
};
};
enum ActionTypes {
UPDATE_IS_LOADED = "UPDATE_IS_LOADED",
}
type Action = {
type: "UPDATE";
payload: State;
type: ActionTypes;
payload: string;
};
interface ContextType {
@ -22,12 +27,28 @@ const RouteContext = createContext<ContextType | null>(null);
interface RouteProviderProps {
children: ReactNode;
}
interface RouteObj {
[key: string]: {
route: string;
isLoaded: boolean;
};
}
const updateLocation = (state: State, action: Action): State => {
if (action.type === "UPDATE") {
if (action.type === ActionTypes.UPDATE_IS_LOADED) {
/*
Update the isLoaded property in routes obj
if the route matches the current pathname
Why: Checkout this issue https://github.com/SigNoz/signoz/issues/110
To avoid calling the api's twice for Date picker,
We will only call once the route is changed
*/
Object.keys(ROUTES).map((items) => {
state[items].isLoaded = state[items].route === action.payload;
});
return {
...state,
...action.payload,
};
}
return {
@ -35,8 +56,19 @@ const updateLocation = (state: State, action: Action): State => {
};
};
const getInitialState = () => {
const routes: RouteObj = {};
Object.keys(ROUTES).map((items) => {
routes[items] = {
route: `${ROUTES[items]}`,
isLoaded: false,
};
});
return routes;
};
const RouteProvider: React.FC<RouteProviderProps> = ({ children }) => {
const [state, dispatch] = React.useReducer(updateLocation, {});
const [state, dispatch] = React.useReducer(updateLocation, getInitialState());
const value = { state, dispatch };
return <RouteContext.Provider value={value}>{children}</RouteContext.Provider>;
};

View File

@ -10,6 +10,7 @@ import {
GlobalTime,
TraceFilters,
} from "../../store/actions";
import { useRoute } from "../RouteProvider";
const { Option } = Select;
@ -81,6 +82,8 @@ const _TraceCustomVisualizations = (props: TraceCustomVisualizationsProps) => {
const [selectedEntity, setSelectedEntity] = useState("calls");
const [selectedAggOption, setSelectedAggOption] = useState("count");
const [selectedStep, setSelectedStep] = useState("60");
const { state } = useRoute();
// Step should be multiples of 60, 60 -> 1 min
useEffect(() => {
@ -109,7 +112,10 @@ const _TraceCustomVisualizations = (props: TraceCustomVisualizationsProps) => {
minTime: props.globalTime.minTime - 15 * 60 * 1000000000,
maxTime: props.globalTime.maxTime + 15 * 60 * 1000000000,
};
props.getFilteredTraceMetrics(request_string, plusMinus15);
if (state.TRACES.isLoaded) {
props.getFilteredTraceMetrics(request_string, plusMinus15);
}
}, [selectedEntity, selectedAggOption, props.traceFilters, props.globalTime]);
//Custom metrics API called if time, tracefilters, selected entity or agg option changes

View File

@ -18,6 +18,7 @@ import FormItem from "antd/lib/form/FormItem";
import api, { apiV1 } from "../../api";
import { useLocation } from "react-router-dom";
import { METRICS_PAGE_QUERY_PARAM } from "Src/constants/query";
import { useRoute } from "../RouteProvider";
const { Option } = Select;
@ -45,6 +46,7 @@ const _TraceFilter = (props: TraceFilterProps) => {
const [tagKeyOptions, setTagKeyOptions] = useState<TagKeyOptionItem[]>([]);
const location = useLocation();
const urlParams = new URLSearchParams(location.search.split("?")[1]);
const { state } = useRoute();
useEffect(() => {
handleApplyFilterForm({
@ -122,7 +124,9 @@ const _TraceFilter = (props: TraceFilterProps) => {
"&tags=" +
encodeURIComponent(JSON.stringify(props.traceFilters.tags));
props.fetchTraces(props.globalTime, request_string);
if (state.TRACES.isLoaded) {
props.fetchTraces(props.globalTime, request_string);
}
}, [props.traceFilters, props.globalTime]);
useEffect(() => {

View File

@ -13,6 +13,7 @@ import {
import { StoreState } from "../../store/reducers";
import moment from "moment";
import { isOnboardingSkipped } from "../../utils/app";
import { useRoute } from "../RouteProvider";
const { Option } = Select;
interface UsageExplorerProps {
@ -56,6 +57,8 @@ const _UsageExplorer = (props: UsageExplorerProps) => {
const [selectedInterval, setSelectedInterval] = useState(interval[2]);
const [selectedService, setSelectedService] = useState<string>("");
const { state } = useRoute();
useEffect(() => {
if (selectedTime && selectedInterval) {
const maxTime = new Date().getTime() * 1000000;
@ -71,7 +74,9 @@ const _UsageExplorer = (props: UsageExplorerProps) => {
}, [selectedTime, selectedInterval, selectedService]);
useEffect(() => {
props.getServicesList(props.globalTime);
if (state.USAGE_EXPLORER.isLoaded) {
props.getServicesList(props.globalTime);
}
}, []);
const data = {