diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
new file mode 100644
index 0000000000..8a22860f1c
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug_report.md
@@ -0,0 +1,30 @@
+---
+name: Bug report
+about: Create a report to help us improve
+title: ''
+labels: ''
+assignees: ''
+
+---
+
+## Bug description
+
+*Please describe.*
+*If this affects the front-end, screenshots would be of great help.*
+
+## Expected behavior
+
+
+
+## How to reproduce
+
+1.
+2.
+3.
+
+
+
+## Additional context
+
+
+#### *Thank you* for your bug report – we love squashing them!
diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md
new file mode 100644
index 0000000000..b8871ec018
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/feature_request.md
@@ -0,0 +1,29 @@
+---
+name: Feature request
+about: Suggest an idea for this project
+title: ''
+labels: ''
+assignees: ''
+
+---
+
+## Is your feature request related to a problem?
+
+*Please describe.*
+
+## Describe the solution you'd like
+
+
+
+## Describe alternatives you've considered
+
+
+
+## Additional context
+
+
+
+#### *Thank you* for your feature request – we love each and every one!
+
+**Additional context**
+Add any other context or screenshots about the feature request here.
diff --git a/.github/ISSUE_TEMPLATE/performance-issue-report.md b/.github/ISSUE_TEMPLATE/performance-issue-report.md
new file mode 100644
index 0000000000..c038877ca1
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/performance-issue-report.md
@@ -0,0 +1,33 @@
+---
+name: Performance issue report
+about: Long response times, high resource usage? Ensuring that SigNoz is scalable
+ is our top priority
+title: ''
+labels: ''
+assignees: ''
+
+---
+
+## In what situation are you experiencing subpar performance?
+
+*Please describe.*
+
+## How to reproduce
+
+1.
+2.
+3.
+
+## Your Environment
+
+- [ ] Linux
+- [ ] Mac
+- [ ] Windows
+
+Please provide details of OS version etc.
+
+## Additional context
+
+
+
+#### *Thank you* for your performance issue report – we want SigNoz to be blazing fast!
diff --git a/README.md b/README.md
index 9f9b7234d3..99ef8c3c61 100644
--- a/README.md
+++ b/README.md
@@ -8,7 +8,7 @@
-
+
diff --git a/frontend/src/modules/AppWrapper.tsx b/frontend/src/modules/AppWrapper.tsx
index b261ad3e32..11e53cd04d 100644
--- a/frontend/src/modules/AppWrapper.tsx
+++ b/frontend/src/modules/AppWrapper.tsx
@@ -17,6 +17,7 @@ import {
SettingsPage,
IntstrumentationPage,
} from "Src/pages";
+import { RouteProvider } from "./RouteProvider";
const App = () => {
const { status } = useThemeSwitcher();
@@ -30,36 +31,38 @@ const App = () => {
}>
-
-
-
-
-
-
-
-
-
-
- {
- return localStorage.getItem(IS_LOGGED_IN) === "yes" ? (
-
- ) : (
-
- );
- }}
- />
-
+
+
+
+
+
+
+
+
+
+
+
+ {
+ return localStorage.getItem(IS_LOGGED_IN) === "yes" ? (
+
+ ) : (
+
+ );
+ }}
+ />
+
+
diff --git a/frontend/src/modules/BaseLayout.tsx b/frontend/src/modules/BaseLayout.tsx
index a36ac96e66..6e3f52769e 100644
--- a/frontend/src/modules/BaseLayout.tsx
+++ b/frontend/src/modules/BaseLayout.tsx
@@ -1,8 +1,12 @@
-import React, { ReactNode } from "react";
+import React, { ReactNode, useEffect } from "react";
import { Layout } from "antd";
import SideNav from "./Nav/SideNav";
import TopNav from "./Nav/TopNav";
+import { useLocation } from "react-router-dom";
+import ROUTES from "Src/constants/routes";
+import { useRoute } from "./RouteProvider";
+
const { Content, Footer } = Layout;
interface BaseLayoutProps {
@@ -10,6 +14,13 @@ interface BaseLayoutProps {
}
const BaseLayout: React.FC = ({ children }) => {
+ const location = useLocation();
+ const { dispatch } = useRoute();
+
+ useEffect(() => {
+ dispatch({ type: "UPDATE_IS_LOADED", payload: location.pathname });
+ }, [location]);
+
return (
diff --git a/frontend/src/modules/Metrics/TopEndpointsTable.css b/frontend/src/modules/Metrics/TopEndpointsTable.css
new file mode 100644
index 0000000000..526a2f8349
--- /dev/null
+++ b/frontend/src/modules/Metrics/TopEndpointsTable.css
@@ -0,0 +1,12 @@
+@media only screen and (min-width: 768px) {
+ .topEndpointsButton {
+ white-space: nowrap;
+ padding: 0;
+ }
+
+ .topEndpointsButton span {
+ text-overflow: ellipsis;
+ overflow: hidden;
+ max-width: 120px;
+ }
+}
diff --git a/frontend/src/modules/Metrics/TopEndpointsTable.tsx b/frontend/src/modules/Metrics/TopEndpointsTable.tsx
index b4584981cd..6ab2022574 100644
--- a/frontend/src/modules/Metrics/TopEndpointsTable.tsx
+++ b/frontend/src/modules/Metrics/TopEndpointsTable.tsx
@@ -1,5 +1,5 @@
import React from "react";
-import { Table, Button } from "antd";
+import { Table, Button, Tooltip } from "antd";
import { connect } from "react-redux";
import styled from "styled-components";
import { useHistory, useParams } from "react-router-dom";
@@ -7,12 +7,16 @@ import { topEndpointListItem } from "../../store/actions/metrics";
import { METRICS_PAGE_QUERY_PARAM } from "Src/constants/query";
import { GlobalTime } from "Src/store/actions";
import { StoreState } from "Src/store/reducers";
+import "./TopEndpointsTable.css";
const Wrapper = styled.div`
padding-top: 10px;
padding-bottom: 10px;
- padding-left: 20px;
- padding-right: 20px;
+ padding-left: 8px;
+ padding-right: 8px;
+ @media only screen and (max-width: 767px) {
+ padding: 0;
+ }
.ant-table table {
font-size: 12px;
}
@@ -22,6 +26,9 @@ const Wrapper = styled.div`
.ant-table-thead > tr > th {
padding: 10px;
}
+ .ant-table-column-sorters {
+ padding: 6px;
+ }
`;
interface TopEndpointsTableProps {
@@ -58,9 +65,15 @@ const _TopEndpointsTable = (props: TopEndpointsTableProps) => {
key: "name",
render: (text: string) => (
- handleOnClick(text)}>
- {text}
-
+
+ handleOnClick(text)}
+ >
+ {text}
+
+
),
},
{
diff --git a/frontend/src/modules/RouteProvider.tsx b/frontend/src/modules/RouteProvider.tsx
new file mode 100644
index 0000000000..0680e912c8
--- /dev/null
+++ b/frontend/src/modules/RouteProvider.tsx
@@ -0,0 +1,83 @@
+import React, { useContext, createContext, ReactNode, Dispatch } from "react";
+import ROUTES from "Src/constants/routes";
+
+type State = {
+ [key: string]: {
+ route: string;
+ isLoaded: boolean;
+ };
+};
+
+enum ActionTypes {
+ UPDATE_IS_LOADED = "UPDATE_IS_LOADED",
+}
+
+type Action = {
+ type: ActionTypes;
+ payload: string;
+};
+
+interface ContextType {
+ state: State;
+ dispatch: Dispatch;
+}
+
+const RouteContext = createContext(null);
+
+interface RouteProviderProps {
+ children: ReactNode;
+}
+interface RouteObj {
+ [key: string]: {
+ route: string;
+ isLoaded: boolean;
+ };
+}
+
+const updateLocation = (state: State, action: Action): State => {
+ 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,
+ };
+ }
+ return {
+ ...state,
+ };
+};
+
+const getInitialState = () => {
+ const routes: RouteObj = {};
+ Object.keys(ROUTES).map((items) => {
+ routes[items] = {
+ route: `${ROUTES[items]}`,
+ isLoaded: false,
+ };
+ });
+ return routes;
+};
+
+const RouteProvider: React.FC = ({ children }) => {
+ const [state, dispatch] = React.useReducer(updateLocation, getInitialState());
+ const value = { state, dispatch };
+ return {children} ;
+};
+
+const useRoute = (): ContextType => {
+ const context = useContext(RouteContext);
+ if (context === undefined) {
+ throw new Error("useRoute must be used within a RouteProvider");
+ }
+ return context as ContextType;
+};
+export { RouteProvider, useRoute };
diff --git a/frontend/src/modules/Servicemap/ServiceMap.tsx b/frontend/src/modules/Servicemap/ServiceMap.tsx
index 048c6980b9..fe31b8d8fb 100644
--- a/frontend/src/modules/Servicemap/ServiceMap.tsx
+++ b/frontend/src/modules/Servicemap/ServiceMap.tsx
@@ -1,4 +1,4 @@
-import React, { useEffect, useRef, useState } from "react";
+import React, { useContext, useEffect, useRef } from "react";
import { connect } from "react-redux";
import { RouteComponentProps } from "react-router-dom";
import {
@@ -14,6 +14,7 @@ import { StoreState } from "../../store/reducers";
import { getZoomPx, getGraphData, getTooltip, transformLabel } from "./utils";
import SelectService from "./SelectService";
import { ForceGraph2D } from "react-force-graph";
+import { useRoute } from "../RouteProvider";
const Container = styled.div`
.force-graph-container .graph-tooltip {
@@ -53,6 +54,8 @@ export interface graphDataType {
const ServiceMap = (props: ServiceMapProps) => {
const fgRef = useRef();
+ const { state } = useRoute();
+
const {
getDetailedServiceMapItems,
getServiceMapItems,
@@ -61,8 +64,14 @@ const ServiceMap = (props: ServiceMapProps) => {
} = props;
useEffect(() => {
- getServiceMapItems(globalTime);
- getDetailedServiceMapItems(globalTime);
+ /*
+ Call the apis only when the route is loaded.
+ Check this issue: https://github.com/SigNoz/signoz/issues/110
+ */
+ if (state.SERVICE_MAP.isLoaded) {
+ getServiceMapItems(globalTime);
+ getDetailedServiceMapItems(globalTime);
+ }
}, [globalTime]);
useEffect(() => {
diff --git a/frontend/src/modules/Traces/TraceCustomVisualizations.tsx b/frontend/src/modules/Traces/TraceCustomVisualizations.tsx
index 3c81ad244b..baf3271c64 100644
--- a/frontend/src/modules/Traces/TraceCustomVisualizations.tsx
+++ b/frontend/src/modules/Traces/TraceCustomVisualizations.tsx
@@ -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,14 @@ const _TraceCustomVisualizations = (props: TraceCustomVisualizationsProps) => {
minTime: props.globalTime.minTime - 15 * 60 * 1000000000,
maxTime: props.globalTime.maxTime + 15 * 60 * 1000000000,
};
- props.getFilteredTraceMetrics(request_string, plusMinus15);
+
+ /*
+ Call the apis only when the route is loaded.
+ Check this issue: https://github.com/SigNoz/signoz/issues/110
+ */
+ 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
diff --git a/frontend/src/modules/Traces/TraceFilter.tsx b/frontend/src/modules/Traces/TraceFilter.tsx
index 839ef64d12..82d679895d 100644
--- a/frontend/src/modules/Traces/TraceFilter.tsx
+++ b/frontend/src/modules/Traces/TraceFilter.tsx
@@ -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([]);
const location = useLocation();
const urlParams = new URLSearchParams(location.search.split("?")[1]);
+ const { state } = useRoute();
useEffect(() => {
handleApplyFilterForm({
@@ -122,7 +124,13 @@ const _TraceFilter = (props: TraceFilterProps) => {
"&tags=" +
encodeURIComponent(JSON.stringify(props.traceFilters.tags));
- props.fetchTraces(props.globalTime, request_string);
+ /*
+ Call the apis only when the route is loaded.
+ Check this issue: https://github.com/SigNoz/signoz/issues/110
+ */
+ if (state.TRACES.isLoaded) {
+ props.fetchTraces(props.globalTime, request_string);
+ }
}, [props.traceFilters, props.globalTime]);
useEffect(() => {
diff --git a/frontend/src/modules/Usage/UsageExplorer.tsx b/frontend/src/modules/Usage/UsageExplorer.tsx
index 3152e12693..d02cc8eebb 100644
--- a/frontend/src/modules/Usage/UsageExplorer.tsx
+++ b/frontend/src/modules/Usage/UsageExplorer.tsx
@@ -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("");
+ const { state } = useRoute();
+
useEffect(() => {
if (selectedTime && selectedInterval) {
const maxTime = new Date().getTime() * 1000000;
@@ -71,7 +74,13 @@ const _UsageExplorer = (props: UsageExplorerProps) => {
}, [selectedTime, selectedInterval, selectedService]);
useEffect(() => {
- props.getServicesList(props.globalTime);
+ /*
+ Call the apis only when the route is loaded.
+ Check this issue: https://github.com/SigNoz/signoz/issues/110
+ */
+ if (state.USAGE_EXPLORER.isLoaded) {
+ props.getServicesList(props.globalTime);
+ }
}, []);
const data = {