Merge branch 'develop' of github.com:SigNoz/signoz into pranshuchittora/feat/y-axis-unit-selection

This commit is contained in:
Pranshu Chittora 2022-03-16 16:24:40 +05:30
commit 17738a58a2
No known key found for this signature in database
GPG Key ID: 3A9E57A016CC0626
108 changed files with 575 additions and 542 deletions

View File

@ -52,14 +52,11 @@ jobs:
helm install my-release signoz/signoz -n platform \ helm install my-release signoz/signoz -n platform \
--wait \ --wait \
--timeout 10m0s \ --timeout 10m0s \
--set cloud=null \
--set frontend.service.type=LoadBalancer \ --set frontend.service.type=LoadBalancer \
--set query-service.image.tag=$DOCKER_TAG \ --set queryService.image.tag=$DOCKER_TAG \
--set frontend.image.tag=$DOCKER_TAG --set frontend.image.tag=$DOCKER_TAG
# get pods, services and the container images # get pods, services and the container images
kubectl describe deploy/my-release-frontend -n platform | grep Image
kubectl describe statefulset/my-release-query-service -n platform | grep Image
kubectl get pods -n platform kubectl get pods -n platform
kubectl get svc -n platform kubectl get svc -n platform

View File

@ -34,8 +34,10 @@ SigNoz helps developers monitor applications and troubleshoot problems in their
![screenzy-1644432902955](https://user-images.githubusercontent.com/504541/153270713-1b2156e6-ec03-42de-975b-3c02b8ec1836.png) ![screenzy-1644432902955](https://user-images.githubusercontent.com/504541/153270713-1b2156e6-ec03-42de-975b-3c02b8ec1836.png)
<br />
![screenzy-1644432986784](https://user-images.githubusercontent.com/504541/153270725-0efb73b3-06ed-4207-bf13-9b7e2e17c4b8.png) ![screenzy-1644432986784](https://user-images.githubusercontent.com/504541/153270725-0efb73b3-06ed-4207-bf13-9b7e2e17c4b8.png)
<br />
![screenzy-1647005040573](https://user-images.githubusercontent.com/504541/157875938-a3d57904-ea6d-4278-b929-bd1408d7f94c.png)
<br /><br /> <br /><br />

View File

@ -1,13 +1,10 @@
const resizeObserverLoopErrRe = /ResizeObserver loop limit exceeded/; const resizeObserverLoopErrRe = /ResizeObserver loop limit exceeded/;
const unCaughtExpection = () => { const unCaughtExpection = (): void => {
cy.on('uncaught:exception', (err) => { cy.on('uncaught:exception', (err) => {
if (resizeObserverLoopErrRe.test(err.message)) { // returning false here prevents Cypress from
// returning false here prevents Cypress from // failing the test
// failing the test return !resizeObserverLoopErrRe.test(err.message);
return false;
}
return true;
}); });
}; };

View File

@ -4,6 +4,8 @@ import ROUTES from 'constants/routes';
import defaultRules from '../../fixtures/defaultRules.json'; import defaultRules from '../../fixtures/defaultRules.json';
const defaultRuleRoutes = `**/rules/**`;
describe('Alerts', () => { describe('Alerts', () => {
beforeEach(() => { beforeEach(() => {
window.localStorage.setItem('isLoggedIn', 'yes'); window.localStorage.setItem('isLoggedIn', 'yes');
@ -21,7 +23,7 @@ describe('Alerts', () => {
it('Edit Rules Page Failure', async () => { it('Edit Rules Page Failure', async () => {
cy cy
.intercept('**/rules/**', { .intercept(defaultRuleRoutes, {
statusCode: 500, statusCode: 500,
}) })
.as('Get Rules Error'); .as('Get Rules Error');
@ -49,7 +51,7 @@ describe('Alerts', () => {
const text = 'this is the sample value'; const text = 'this is the sample value';
cy cy
.intercept('**/rules/**', { .intercept(defaultRuleRoutes, {
statusCode: 200, statusCode: 200,
body: { body: {
data: { data: {
@ -103,7 +105,7 @@ describe('Alerts', () => {
it('Rules are Deleted', async () => { it('Rules are Deleted', async () => {
cy cy
.intercept('**/rules/**', { .intercept(defaultRuleRoutes, {
body: { body: {
data: 'Deleted', data: 'Deleted',
message: 'Success', message: 'Success',

View File

@ -1,9 +1,15 @@
/* eslint-disable sonarjs/no-duplicate-string */
import ROUTES from 'constants/routes'; import ROUTES from 'constants/routes';
import { TraceFilterEnum } from 'types/reducer/trace';
import TableInitialResponse from '../../fixtures/trace/initialSpans.json';
import FilterInitialResponse from '../../fixtures/trace/initialSpanFilter.json';
import GraphInitialResponse from '../../fixtures/trace/initialAggregates.json';
import { AppState } from 'store/reducers'; import { AppState } from 'store/reducers';
import { TraceFilterEnum } from 'types/reducer/trace';
import GraphInitialResponse from '../../fixtures/trace/initialAggregates.json';
import FilterInitialResponse from '../../fixtures/trace/initialSpanFilter.json';
import TableInitialResponse from '../../fixtures/trace/initialSpans.json';
const allFilters = '@Filters.all';
const allGraphs = '@Graph.all';
const allTable = '@Table.all';
describe('Trace', () => { describe('Trace', () => {
beforeEach(() => { beforeEach(() => {
@ -74,9 +80,9 @@ describe('Trace', () => {
JSON.stringify(TableInitialResponse), JSON.stringify(TableInitialResponse),
); );
}); });
cy.get('@Filters.all').should('have.length', 1); cy.get(allFilters).should('have.length', 1);
cy.get('@Graph.all').should('have.length', 1); cy.get(allGraphs).should('have.length', 1);
cy.get('@Table.all').should('have.length', 1); cy.get(allTable).should('have.length', 1);
}); });
it('Clear All', () => { it('Clear All', () => {
@ -102,9 +108,9 @@ describe('Trace', () => {
cy.wait(['@Filters', '@Graph', '@Table']); cy.wait(['@Filters', '@Graph', '@Table']);
// insuring the api get call // insuring the api get call
cy.get('@Filters.all').should('have.length', 2); cy.get(allFilters).should('have.length', 2);
cy.get('@Graph.all').should('have.length', 2); cy.get(allGraphs).should('have.length', 2);
cy.get('@Table.all').should('have.length', 2); cy.get(allTable).should('have.length', 2);
cy cy
.window() .window()
@ -146,9 +152,9 @@ describe('Trace', () => {
expect(tableBody.exclude[0] === 'status').to.be.true; expect(tableBody.exclude[0] === 'status').to.be.true;
}); });
cy.get('@Filters.all').should('have.length', 2); cy.get(allFilters).should('have.length', 2);
cy.get('@Graph.all').should('have.length', 2); cy.get(allGraphs).should('have.length', 2);
cy.get('@Table.all').should('have.length', 2); cy.get(allTable).should('have.length', 2);
}); });
}); });
}); });

View File

@ -11,7 +11,6 @@ import AppReducer from 'types/reducer/app';
import routes from './routes'; import routes from './routes';
const App = (): JSX.Element => { const App = (): JSX.Element => {
const { isLoggedIn } = useSelector<AppState, AppReducer>((state) => state.app); const { isLoggedIn } = useSelector<AppState, AppReducer>((state) => state.app);
@ -20,8 +19,8 @@ const App = (): JSX.Element => {
<AppLayout> <AppLayout>
<Suspense fallback={<Spinner size="large" tip="Loading..." />}> <Suspense fallback={<Spinner size="large" tip="Loading..." />}>
<Switch> <Switch>
{routes.map(({ path, component, exact }, index) => ( {routes.map(({ path, component, exact }) => (
<Route key={index} exact={exact} path={path} component={component} /> <Route key={`${path}`} exact={exact} path={path} component={component} />
))} ))}
<Route <Route
path="/" path="/"
@ -42,5 +41,4 @@ const App = (): JSX.Element => {
); );
}; };
export default App; export default App;

View File

@ -17,8 +17,8 @@ import {
ServicesTablePage, ServicesTablePage,
SettingsPage, SettingsPage,
SignupPage, SignupPage,
TraceFilter,
TraceDetail, TraceDetail,
TraceFilter,
UsageExplorerPage, UsageExplorerPage,
} from './pageComponents'; } from './pageComponents';

View File

@ -1,9 +1,9 @@
import { AxiosAlertManagerInstance } from 'api'; import { AxiosAlertManagerInstance } from 'api';
import { ErrorResponseHandler } from 'api/ErrorResponseHandler'; import { ErrorResponseHandler } from 'api/ErrorResponseHandler';
import { AxiosError } from 'axios'; import { AxiosError } from 'axios';
import convertObjectIntoParams from 'lib/query/convertObjectIntoParams';
import { ErrorResponse, SuccessResponse } from 'types/api'; import { ErrorResponse, SuccessResponse } from 'types/api';
import { PayloadProps, Props } from 'types/api/alerts/getGroups'; import { PayloadProps, Props } from 'types/api/alerts/getGroups';
import convertObjectIntoParams from 'lib/query/convertObjectIntoParams';
const getGroups = async ( const getGroups = async (
props: Props, props: Props,

View File

@ -1,7 +1,6 @@
const get = (key: string): string | null => { const get = (key: string): string | null => {
try { try {
const value = localStorage.getItem(key); return localStorage.getItem(key);
return value;
} catch (e) { } catch (e) {
return ''; return '';
} }

View File

@ -1,9 +1,9 @@
import axios from 'api'; import axios from 'api';
import { ErrorResponseHandler } from 'api/ErrorResponseHandler'; import { ErrorResponseHandler } from 'api/ErrorResponseHandler';
import { AxiosError } from 'axios'; import { AxiosError } from 'axios';
import omitBy from 'lodash-es/omitBy';
import { ErrorResponse, SuccessResponse } from 'types/api'; import { ErrorResponse, SuccessResponse } from 'types/api';
import { PayloadProps, Props } from 'types/api/trace/getFilters'; import { PayloadProps, Props } from 'types/api/trace/getFilters';
import omitBy from 'lodash-es/omitBy';
const getFilters = async ( const getFilters = async (
props: Props, props: Props,

View File

@ -2,7 +2,7 @@ import axios from 'api';
import { ErrorResponseHandler } from 'api/ErrorResponseHandler'; import { ErrorResponseHandler } from 'api/ErrorResponseHandler';
import { AxiosError } from 'axios'; import { AxiosError } from 'axios';
import { ErrorResponse, SuccessResponse } from 'types/api'; import { ErrorResponse, SuccessResponse } from 'types/api';
import { Props, PayloadProps } from 'types/api/trace/getTraceItem'; import { PayloadProps, Props } from 'types/api/trace/getTraceItem';
const getTraceItem = async ( const getTraceItem = async (
props: Props, props: Props,

View File

@ -1,6 +1,6 @@
import React from 'react'; import React from 'react';
const TimeSeries = (props: TimeSeriesProps): JSX.Element => ( const TimeSeries = (): JSX.Element => (
<React.Fragment> <React.Fragment>
<svg <svg
width="81" width="81"
@ -34,9 +34,4 @@ const TimeSeries = (props: TimeSeriesProps): JSX.Element => (
</React.Fragment> </React.Fragment>
); );
export interface TimeSeriesProps{
fillColor: React.CSSProperties['color'];
}
export default TimeSeries; export default TimeSeries;

View File

@ -1,24 +1,25 @@
import React from 'react'; import React from 'react';
const Value = (props: ValueProps): JSX.Element => { const Value = (props: ValueProps): JSX.Element => {
return( return (
<React.Fragment> <React.Fragment>
<svg <svg
width="78" width="78"
height="32" height="32"
viewBox="0 0 78 32" viewBox="0 0 78 32"
fill="none" fill="none"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
> >
<path <path
d="M15.0215 17.875C14.2285 18.8184 13.2783 19.5771 12.1709 20.1514C11.0771 20.7256 9.87402 21.0127 8.56152 21.0127C6.83887 21.0127 5.33496 20.5889 4.0498 19.7412C2.77832 18.8936 1.79395 17.7041 1.09668 16.1729C0.399414 14.6279 0.0507812 12.9258 0.0507812 11.0664C0.0507812 9.07031 0.426758 7.27246 1.17871 5.67285C1.94434 4.07324 3.02441 2.84961 4.41895 2.00195C5.81348 1.1543 7.44043 0.730469 9.2998 0.730469C12.2529 0.730469 14.5771 1.83789 16.2725 4.05273C17.9814 6.25391 18.8359 9.26172 18.8359 13.0762V14.1836C18.8359 19.9941 17.6875 24.2393 15.3906 26.9189C13.0938 29.585 9.62793 30.9521 4.99316 31.0205H4.25488V27.8213H5.05469C8.18555 27.7666 10.5918 26.9531 12.2734 25.3809C13.9551 23.7949 14.8711 21.293 15.0215 17.875ZM9.17676 17.875C10.4482 17.875 11.6172 17.4854 12.6836 16.7061C13.7637 15.9268 14.5498 14.9629 15.042 13.8145V12.2969C15.042 9.80859 14.502 7.78516 13.4219 6.22656C12.3418 4.66797 10.9746 3.88867 9.32031 3.88867C7.65234 3.88867 6.3125 4.53125 5.30078 5.81641C4.28906 7.08789 3.7832 8.76953 3.7832 10.8613C3.7832 12.8984 4.26855 14.5801 5.23926 15.9062C6.22363 17.2188 7.53613 17.875 9.17676 17.875ZM24.5371 29.0107C24.5371 28.3545 24.7285 27.8076 25.1113 27.3701C25.5078 26.9326 26.0957 26.7139 26.875 26.7139C27.6543 26.7139 28.2422 26.9326 28.6387 27.3701C29.0488 27.8076 29.2539 28.3545 29.2539 29.0107C29.2539 29.6396 29.0488 30.166 28.6387 30.5898C28.2422 31.0137 27.6543 31.2256 26.875 31.2256C26.0957 31.2256 25.5078 31.0137 25.1113 30.5898C24.7285 30.166 24.5371 29.6396 24.5371 29.0107ZM51.1562 20.9717H55.2988V24.0684H51.1562V31H47.3418V24.0684H33.7451V21.833L47.1162 1.14062H51.1562V20.9717ZM38.0518 20.9717H47.3418V6.3291L46.8906 7.14941L38.0518 20.9717ZM73.6123 1.12012V4.33984H72.915C69.9619 4.39453 67.6104 5.26953 65.8604 6.96484C64.1104 8.66016 63.0986 11.0459 62.8252 14.1221C64.3975 12.3174 66.5439 11.415 69.2646 11.415C71.8623 11.415 73.9336 12.3311 75.4785 14.1631C77.0371 15.9951 77.8164 18.3604 77.8164 21.2588C77.8164 24.335 76.9756 26.7959 75.2939 28.6416C73.626 30.4873 71.3838 31.4102 68.5674 31.4102C65.71 31.4102 63.3926 30.3164 61.6152 28.1289C59.8379 25.9277 58.9492 23.0977 58.9492 19.6387V18.1826C58.9492 12.6865 60.1182 8.48926 62.4561 5.59082C64.8076 2.67871 68.3008 1.18848 72.9355 1.12012H73.6123ZM68.6289 14.5732C67.3301 14.5732 66.1338 14.9629 65.04 15.7422C63.9463 16.5215 63.1875 17.499 62.7637 18.6748V20.0693C62.7637 22.5303 63.3174 24.5127 64.4248 26.0166C65.5322 27.5205 66.9131 28.2725 68.5674 28.2725C70.2764 28.2725 71.6162 27.6436 72.5869 26.3857C73.5713 25.1279 74.0635 23.4805 74.0635 21.4434C74.0635 19.3926 73.5645 17.7383 72.5664 16.4805C71.582 15.209 70.2695 14.5732 68.6289 14.5732Z" d="M15.0215 17.875C14.2285 18.8184 13.2783 19.5771 12.1709 20.1514C11.0771 20.7256 9.87402 21.0127 8.56152 21.0127C6.83887 21.0127 5.33496 20.5889 4.0498 19.7412C2.77832 18.8936 1.79395 17.7041 1.09668 16.1729C0.399414 14.6279 0.0507812 12.9258 0.0507812 11.0664C0.0507812 9.07031 0.426758 7.27246 1.17871 5.67285C1.94434 4.07324 3.02441 2.84961 4.41895 2.00195C5.81348 1.1543 7.44043 0.730469 9.2998 0.730469C12.2529 0.730469 14.5771 1.83789 16.2725 4.05273C17.9814 6.25391 18.8359 9.26172 18.8359 13.0762V14.1836C18.8359 19.9941 17.6875 24.2393 15.3906 26.9189C13.0938 29.585 9.62793 30.9521 4.99316 31.0205H4.25488V27.8213H5.05469C8.18555 27.7666 10.5918 26.9531 12.2734 25.3809C13.9551 23.7949 14.8711 21.293 15.0215 17.875ZM9.17676 17.875C10.4482 17.875 11.6172 17.4854 12.6836 16.7061C13.7637 15.9268 14.5498 14.9629 15.042 13.8145V12.2969C15.042 9.80859 14.502 7.78516 13.4219 6.22656C12.3418 4.66797 10.9746 3.88867 9.32031 3.88867C7.65234 3.88867 6.3125 4.53125 5.30078 5.81641C4.28906 7.08789 3.7832 8.76953 3.7832 10.8613C3.7832 12.8984 4.26855 14.5801 5.23926 15.9062C6.22363 17.2188 7.53613 17.875 9.17676 17.875ZM24.5371 29.0107C24.5371 28.3545 24.7285 27.8076 25.1113 27.3701C25.5078 26.9326 26.0957 26.7139 26.875 26.7139C27.6543 26.7139 28.2422 26.9326 28.6387 27.3701C29.0488 27.8076 29.2539 28.3545 29.2539 29.0107C29.2539 29.6396 29.0488 30.166 28.6387 30.5898C28.2422 31.0137 27.6543 31.2256 26.875 31.2256C26.0957 31.2256 25.5078 31.0137 25.1113 30.5898C24.7285 30.166 24.5371 29.6396 24.5371 29.0107ZM51.1562 20.9717H55.2988V24.0684H51.1562V31H47.3418V24.0684H33.7451V21.833L47.1162 1.14062H51.1562V20.9717ZM38.0518 20.9717H47.3418V6.3291L46.8906 7.14941L38.0518 20.9717ZM73.6123 1.12012V4.33984H72.915C69.9619 4.39453 67.6104 5.26953 65.8604 6.96484C64.1104 8.66016 63.0986 11.0459 62.8252 14.1221C64.3975 12.3174 66.5439 11.415 69.2646 11.415C71.8623 11.415 73.9336 12.3311 75.4785 14.1631C77.0371 15.9951 77.8164 18.3604 77.8164 21.2588C77.8164 24.335 76.9756 26.7959 75.2939 28.6416C73.626 30.4873 71.3838 31.4102 68.5674 31.4102C65.71 31.4102 63.3926 30.3164 61.6152 28.1289C59.8379 25.9277 58.9492 23.0977 58.9492 19.6387V18.1826C58.9492 12.6865 60.1182 8.48926 62.4561 5.59082C64.8076 2.67871 68.3008 1.18848 72.9355 1.12012H73.6123ZM68.6289 14.5732C67.3301 14.5732 66.1338 14.9629 65.04 15.7422C63.9463 16.5215 63.1875 17.499 62.7637 18.6748V20.0693C62.7637 22.5303 63.3174 24.5127 64.4248 26.0166C65.5322 27.5205 66.9131 28.2725 68.5674 28.2725C70.2764 28.2725 71.6162 27.6436 72.5869 26.3857C73.5713 25.1279 74.0635 23.4805 74.0635 21.4434C74.0635 19.3926 73.5645 17.7383 72.5664 16.4805C71.582 15.209 70.2695 14.5732 68.6289 14.5732Z"
fill={props.fillColor} fill={props.fillColor}
/> />
</svg> </svg>
</React.Fragment> </React.Fragment>
)}; );
};
interface ValueProps{ interface ValueProps {
fillColor: React.CSSProperties['color']; fillColor: React.CSSProperties['color'];
} }

View File

@ -1,6 +1,6 @@
import generatePicker from 'antd/es/date-picker/generatePicker';
import { Dayjs } from 'dayjs'; import { Dayjs } from 'dayjs';
import dayjsGenerateConfig from 'rc-picker/lib/generate/dayjs'; import dayjsGenerateConfig from 'rc-picker/lib/generate/dayjs';
import generatePicker from 'antd/es/date-picker/generatePicker';
const DatePicker = generatePicker<Dayjs>(dayjsGenerateConfig); const DatePicker = generatePicker<Dayjs>(dayjsGenerateConfig);

View File

@ -1,7 +1,11 @@
import { Plugin, ChartType, Chart, ChartOptions } from 'chart.js'; import { Chart, ChartType, Plugin } from 'chart.js';
import { colors } from 'lib/getRandomColor'; import { colors } from 'lib/getRandomColor';
const getOrCreateLegendList = (chart: Chart, id: string, isLonger: boolean) => { const getOrCreateLegendList = (
chart: Chart,
id: string,
isLonger: boolean,
): HTMLUListElement => {
const legendContainer = document.getElementById(id); const legendContainer = document.getElementById(id);
let listContainer = legendContainer?.querySelector('ul'); let listContainer = legendContainer?.querySelector('ul');
@ -27,7 +31,7 @@ const getOrCreateLegendList = (chart: Chart, id: string, isLonger: boolean) => {
export const legend = (id: string, isLonger: boolean): Plugin<ChartType> => { export const legend = (id: string, isLonger: boolean): Plugin<ChartType> => {
return { return {
id: 'htmlLegend', id: 'htmlLegend',
afterUpdate(chart, args, options: ChartOptions) { afterUpdate(chart): void {
const ul = getOrCreateLegendList(chart, id || 'legend', isLonger); const ul = getOrCreateLegendList(chart, id || 'legend', isLonger);
// Remove old legend items // Remove old legend items
@ -46,7 +50,7 @@ export const legend = (id: string, isLonger: boolean): Plugin<ChartType> => {
li.style.marginLeft = '10px'; li.style.marginLeft = '10px';
li.style.marginTop = '5px'; li.style.marginTop = '5px';
li.onclick = () => { li.onclick = (): void => {
const { type } = chart.config; const { type } = chart.config;
if (type === 'pie' || type === 'doughnut') { if (type === 'pie' || type === 'doughnut') {
// Pie and doughnut charts only have a single dataset and visibility is per item // Pie and doughnut charts only have a single dataset and visibility is per item

View File

@ -77,8 +77,8 @@ export const useXAxisTimeUnit = (data: Chart['data']): IAxisTimeConfig => {
try { try {
let minTime = Number.POSITIVE_INFINITY; let minTime = Number.POSITIVE_INFINITY;
let maxTime = Number.NEGATIVE_INFINITY; let maxTime = Number.NEGATIVE_INFINITY;
data?.labels?.forEach((timeStamp: any) => { data?.labels?.forEach((timeStamp: string | number): void => {
timeStamp = Date.parse(timeStamp); if (typeof timeStamp === 'string') timeStamp = Date.parse(timeStamp);
minTime = Math.min(timeStamp, minTime); minTime = Math.min(timeStamp, minTime);
maxTime = Math.max(timeStamp, maxTime); maxTime = Math.max(timeStamp, maxTime);
}); });

View File

@ -3,9 +3,7 @@ import { ComponentType, lazy } from 'react';
function Loadable(importPath: { function Loadable(importPath: {
(): LoadableProps; (): LoadableProps;
}): React.LazyExoticComponent<LazyComponent> { }): React.LazyExoticComponent<LazyComponent> {
const LazyComponent = lazy(() => importPath()); return lazy(() => importPath());
return LazyComponent;
} }
type LazyComponent = ComponentType<Record<string, unknown>>; type LazyComponent = ComponentType<Record<string, unknown>>;

View File

@ -1,5 +1,5 @@
import React from 'react';
import { Tabs, TabsProps } from 'antd'; import { Tabs, TabsProps } from 'antd';
import React from 'react';
const { TabPane } = Tabs; const { TabPane } = Tabs;
import history from 'lib/history'; import history from 'lib/history';

View File

@ -10,7 +10,7 @@ import React, { useCallback } from 'react';
const { Paragraph } = Typography; const { Paragraph } = Typography;
import AlertChannlesComponent from './AlertChannels'; import AlertChannlesComponent from './AlertChannels';
import { ButtonContainer, Button } from './styles'; import { Button, ButtonContainer } from './styles';
const AlertChannels = (): JSX.Element => { const AlertChannels = (): JSX.Element => {
const onToggleHandler = useCallback(() => { const onToggleHandler = useCallback(() => {

View File

@ -1,5 +1,5 @@
import styled from 'styled-components';
import { Button as ButtonComponent } from 'antd'; import { Button as ButtonComponent } from 'antd';
import styled from 'styled-components';
export const ButtonContainer = styled.div` export const ButtonContainer = styled.div`
&&& { &&& {

View File

@ -7,7 +7,7 @@ import { useSelector } from 'react-redux';
import { AppState } from 'store/reducers'; import { AppState } from 'store/reducers';
import AppReducer from 'types/reducer/app'; import AppReducer from 'types/reducer/app';
import { Content, Footer, Layout } from './styles'; import { Content, Layout } from './styles';
const AppLayout: React.FC<AppLayoutProps> = ({ children }) => { const AppLayout: React.FC<AppLayoutProps> = ({ children }) => {
const { isLoggedIn } = useSelector<AppState, AppReducer>((state) => state.app); const { isLoggedIn } = useSelector<AppState, AppReducer>((state) => state.app);
@ -27,8 +27,6 @@ const AppLayout: React.FC<AppLayoutProps> = ({ children }) => {
} }
}, [isLoggedIn, isSignUpPage]); }, [isLoggedIn, isSignUpPage]);
const currentYear = new Date().getFullYear();
return ( return (
<Layout> <Layout>
{!isSignUpPage && <SideNav />} {!isSignUpPage && <SideNav />}
@ -37,7 +35,6 @@ const AppLayout: React.FC<AppLayoutProps> = ({ children }) => {
{!isSignUpPage && <TopNav />} {!isSignUpPage && <TopNav />}
{children} {children}
</Content> </Content>
{/* <Footer>{`SigNoz Inc. © ${currentYear}`}</Footer> */}
</Layout> </Layout>
</Layout> </Layout>
); );

View File

@ -16,10 +16,3 @@ export const Content = styled(LayoutComponent.Content)`
flex-direction: column; flex-direction: column;
} }
`; `;
export const Footer = styled(LayoutComponent.Footer)`
&&& {
text-align: center;
font-size: 0.7rem;
}
`;

View File

@ -1,9 +1,13 @@
import { Tooltip, Typography } from 'antd'; import { Tooltip, Typography } from 'antd';
import React from 'react'; import {
import { SpanBorder, SpanText, SpanWrapper, SpanLine } from './styles'; IIntervalUnit,
import { toFixed } from 'utils/toFixed' resolveTimeFromInterval,
import { IIntervalUnit, resolveTimeFromInterval } from 'container/TraceDetail/utils'; } from 'container/TraceDetail/utils';
import useThemeMode from 'hooks/useThemeMode'; import useThemeMode from 'hooks/useThemeMode';
import React from 'react';
import { toFixed } from 'utils/toFixed';
import { SpanBorder, SpanLine, SpanText, SpanWrapper } from './styles';
interface SpanLengthProps { interface SpanLengthProps {
width: string; width: string;
leftOffset: string; leftOffset: string;
@ -16,12 +20,15 @@ interface SpanLengthProps {
const SpanLength = (props: SpanLengthProps): JSX.Element => { const SpanLength = (props: SpanLengthProps): JSX.Element => {
const { width, leftOffset, bgColor, intervalUnit } = props; const { width, leftOffset, bgColor, intervalUnit } = props;
const { isDarkMode } = useThemeMode() const { isDarkMode } = useThemeMode();
return ( return (
<SpanWrapper> <SpanWrapper>
<SpanLine leftOffset={leftOffset} isDarkMode={isDarkMode} /> <SpanLine leftOffset={leftOffset} isDarkMode={isDarkMode} />
<SpanBorder bgColor={bgColor} leftOffset={leftOffset} width={width} /> <SpanBorder bgColor={bgColor} leftOffset={leftOffset} width={width} />
<SpanText leftOffset={leftOffset} isDarkMode={isDarkMode}>{`${toFixed(resolveTimeFromInterval(props.inMsCount, intervalUnit), 2)} ${intervalUnit.name}`}</SpanText> <SpanText leftOffset={leftOffset} isDarkMode={isDarkMode}>{`${toFixed(
resolveTimeFromInterval(props.inMsCount, intervalUnit),
2,
)} ${intervalUnit.name}`}</SpanText>
</SpanWrapper> </SpanWrapper>
); );
}; };

View File

@ -1,11 +1,12 @@
import React from 'react'; import React from 'react';
import { import {
Container,
Service, Service,
Span, Span,
SpanWrapper,
SpanConnector, SpanConnector,
Container,
SpanName, SpanName,
SpanWrapper,
} from './styles'; } from './styles';
const SpanNameComponent = ({ const SpanNameComponent = ({

View File

@ -1,5 +1,5 @@
import styled from 'styled-components';
import { Typography } from 'antd'; import { Typography } from 'antd';
import styled from 'styled-components';
export const Span = styled(Typography.Paragraph)` export const Span = styled(Typography.Paragraph)`
&&& { &&& {

View File

@ -1,22 +1,25 @@
import React, { useRef, useState, useEffect } from 'react'; import { CaretDownFilled, CaretRightFilled } from '@ant-design/icons';
import { Col, Row } from 'antd';
import {
IIntervalUnit,
resolveTimeFromInterval,
} from 'container/TraceDetail/utils';
import useThemeMode from 'hooks/useThemeMode';
import { SPAN_DETAILS_LEFT_COL_WIDTH } from 'pages/TraceDetail/constants';
import React, { useEffect, useRef, useState } from 'react';
import { pushDStree } from 'store/actions';
import { ITraceMetaData } from '..';
import SpanLength from '../SpanLength';
import SpanName from '../SpanName';
import { getMetaDataFromSpanTree, getTopLeftFromBody } from '../utils';
import { import {
CardComponent, CardComponent,
CardContainer, CardContainer,
CaretContainer, CaretContainer,
Wrapper,
HoverCard, HoverCard,
Wrapper,
} from './styles'; } from './styles';
import { CaretDownFilled, CaretRightFilled } from '@ant-design/icons';
import SpanLength from '../SpanLength';
import SpanName from '../SpanName';
import { pushDStree } from 'store/actions';
import { getMetaDataFromSpanTree, getTopLeftFromBody } from '../utils';
import { ITraceMetaData } from '..';
import { Col, Row } from 'antd';
import { SPAN_DETAILS_LEFT_COL_WIDTH } from 'pages/TraceDetail/constants'
import { IIntervalUnit, resolveTimeFromInterval } from 'container/TraceDetail/utils';
import useThemeMode from 'hooks/useThemeMode';
const Trace = (props: TraceProps): JSX.Element => { const Trace = (props: TraceProps): JSX.Element => {
const { const {
@ -38,7 +41,7 @@ const Trace = (props: TraceProps): JSX.Element => {
intervalUnit, intervalUnit,
} = props; } = props;
const { isDarkMode } = useThemeMode() const { isDarkMode } = useThemeMode();
const [isOpen, setOpen] = useState<boolean>(activeSpanPath[level] === id); const [isOpen, setOpen] = useState<boolean>(activeSpanPath[level] === id);
const localTreeExpandInteraction = useRef<boolean | 0>(0); // Boolean is for the state of the expansion whereas the number i.e. 0 is for skipping the user interaction. const localTreeExpandInteraction = useRef<boolean | 0>(0); // Boolean is for the state of the expansion whereas the number i.e. 0 is for skipping the user interaction.
@ -47,20 +50,18 @@ const Trace = (props: TraceProps): JSX.Element => {
if (localTreeExpandInteraction.current !== 0) { if (localTreeExpandInteraction.current !== 0) {
setOpen(localTreeExpandInteraction.current); setOpen(localTreeExpandInteraction.current);
localTreeExpandInteraction.current = 0; localTreeExpandInteraction.current = 0;
} else if (!isOpen) {
setOpen(activeSpanPath[level] === id);
} }
else if (!isOpen) { }, [activeSpanPath, isOpen]);
setOpen(activeSpanPath[level] === id)
}
}, [activeSpanPath, isOpen])
useEffect(() => { useEffect(() => {
if (isExpandAll) { if (isExpandAll) {
setOpen(isExpandAll) setOpen(isExpandAll);
} else {
setOpen(activeSpanPath[level] === id);
} }
else { }, [isExpandAll]);
setOpen(activeSpanPath[level] === id)
}
}, [isExpandAll])
const isOnlyChild = props.children.length === 1; const isOnlyChild = props.children.length === 1;
const [top, setTop] = useState<number>(0); const [top, setTop] = useState<number>(0);
@ -69,9 +70,13 @@ const Trace = (props: TraceProps): JSX.Element => {
React.useEffect(() => { React.useEffect(() => {
if (activeSelectedId === id) { if (activeSelectedId === id) {
ref.current?.scrollIntoView({ block: 'nearest', behavior: 'auto', inline: 'nearest' }); ref.current?.scrollIntoView({
block: 'nearest',
behavior: 'auto',
inline: 'nearest',
});
} }
}, [activeSelectedId]) }, [activeSelectedId]);
const onMouseEnterHandler = () => { const onMouseEnterHandler = () => {
setActiveHoverId(props.id); setActiveHoverId(props.id);
@ -87,18 +92,21 @@ const Trace = (props: TraceProps): JSX.Element => {
const onClick = () => { const onClick = () => {
setActiveSelectedId(id); setActiveSelectedId(id);
} };
const onClickTreeExpansion = (event) => { const onClickTreeExpansion = (event) => {
event.stopPropagation() event.stopPropagation();
setOpen((state) => { localTreeExpandInteraction.current = !isOpen; return !state }); setOpen((state) => {
} localTreeExpandInteraction.current = !isOpen;
return !state;
});
};
const { totalSpans } = getMetaDataFromSpanTree(props); const { totalSpans } = getMetaDataFromSpanTree(props);
const inMsCount = value; const inMsCount = value;
const nodeLeftOffset = ((startTime - globalStart) * 1e2) / globalSpread; const nodeLeftOffset = ((startTime - globalStart) * 1e2) / globalSpread;
const width = (value * 1e2) / (globalSpread * 1e6); const width = (value * 1e2) / (globalSpread * 1e6);
const panelWidth = SPAN_DETAILS_LEFT_COL_WIDTH - (level * (16 + 1)) - 16; const panelWidth = SPAN_DETAILS_LEFT_COL_WIDTH - level * (16 + 1) - 16;
return ( return (
<> <>
@ -115,17 +123,12 @@ const Trace = (props: TraceProps): JSX.Element => {
isDarkMode={isDarkMode} isDarkMode={isDarkMode}
/> />
<CardContainer <CardContainer onClick={onClick}>
onClick={onClick}
>
<Col flex={`${panelWidth}px`} style={{ overflow: 'hidden' }}> <Col flex={`${panelWidth}px`} style={{ overflow: 'hidden' }}>
<Row style={{ flexWrap: 'nowrap' }}> <Row style={{ flexWrap: 'nowrap' }}>
<Col> <Col>
{totalSpans !== 1 && ( {totalSpans !== 1 && (
<CardComponent <CardComponent isDarkMode={isDarkMode} onClick={onClickTreeExpansion}>
isDarkMode={isDarkMode}
onClick={onClickTreeExpansion}
>
{totalSpans} {totalSpans}
<CaretContainer> <CaretContainer>
{isOpen ? <CaretDownFilled /> : <CaretRightFilled />} {isOpen ? <CaretDownFilled /> : <CaretRightFilled />}
@ -138,13 +141,13 @@ const Trace = (props: TraceProps): JSX.Element => {
</Col> </Col>
</Row> </Row>
</Col> </Col>
<Col flex={'1'} > <Col flex={'1'}>
<SpanLength <SpanLength
leftOffset={nodeLeftOffset.toString()} leftOffset={nodeLeftOffset.toString()}
width={width.toString()} width={width.toString()}
bgColor={serviceColour} bgColor={serviceColour}
id={id} id={id}
inMsCount={(inMsCount / 1e6)} inMsCount={inMsCount / 1e6}
intervalUnit={intervalUnit} intervalUnit={intervalUnit}
/> />
</Col> </Col>

View File

@ -1,11 +1,12 @@
import { MinusSquareOutlined, PlusSquareOutlined } from '@ant-design/icons';
import { IIntervalUnit } from 'container/TraceDetail/utils';
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
import Trace from './Trace';
import { MinusSquareOutlined, PlusSquareOutlined } from '@ant-design/icons'
import { Wrapper, CardWrapper, CardContainer, CollapseButton } from './styles';
import { getSpanPath } from './utils';
import { IIntervalUnit } from 'container/TraceDetail/utils'
import { ITraceTree } from 'types/api/trace/getTraceItem'; import { ITraceTree } from 'types/api/trace/getTraceItem';
import { CardContainer, CardWrapper, CollapseButton, Wrapper } from './styles';
import Trace from './Trace';
import { getSpanPath } from './utils';
const GanttChart = (props: GanttChartProps): JSX.Element => { const GanttChart = (props: GanttChartProps): JSX.Element => {
const { const {
data, data,
@ -15,7 +16,7 @@ const GanttChart = (props: GanttChartProps): JSX.Element => {
activeSelectedId, activeSelectedId,
setActiveSelectedId, setActiveSelectedId,
spanId, spanId,
intervalUnit intervalUnit,
} = props; } = props;
const { globalStart, spread: globalSpread } = traceMetaData; const { globalStart, spread: globalSpread } = traceMetaData;
@ -24,11 +25,11 @@ const GanttChart = (props: GanttChartProps): JSX.Element => {
const [activeSpanPath, setActiveSpanPath] = useState<string[]>([]); const [activeSpanPath, setActiveSpanPath] = useState<string[]>([]);
useEffect(() => { useEffect(() => {
setActiveSpanPath(getSpanPath(data, spanId)) setActiveSpanPath(getSpanPath(data, spanId));
}, [spanId]); }, [spanId]);
useEffect(() => { useEffect(() => {
setActiveSpanPath(getSpanPath(data, activeSelectedId)) setActiveSpanPath(getSpanPath(data, activeSelectedId));
}, [activeSelectedId]); }, [activeSelectedId]);
const handleCollapse = () => { const handleCollapse = () => {
@ -38,7 +39,11 @@ const GanttChart = (props: GanttChartProps): JSX.Element => {
<> <>
<Wrapper> <Wrapper>
<CardContainer> <CardContainer>
<CollapseButton onClick={handleCollapse} style={{ fontSize: '1.2rem' }} title={isExpandAll ? 'Collapse All' : "Expand All"}> <CollapseButton
onClick={handleCollapse}
style={{ fontSize: '1.2rem' }}
title={isExpandAll ? 'Collapse All' : 'Expand All'}
>
{isExpandAll ? <MinusSquareOutlined /> : <PlusSquareOutlined />} {isExpandAll ? <MinusSquareOutlined /> : <PlusSquareOutlined />}
</CollapseButton> </CollapseButton>
<CardWrapper> <CardWrapper>
@ -81,7 +86,7 @@ export interface GanttChartProps {
setActiveHoverId: React.Dispatch<React.SetStateAction<string>>; setActiveHoverId: React.Dispatch<React.SetStateAction<string>>;
setActiveSelectedId: React.Dispatch<React.SetStateAction<string>>; setActiveSelectedId: React.Dispatch<React.SetStateAction<string>>;
spanId: string; spanId: string;
intervalUnit: IIntervalUnit intervalUnit: IIntervalUnit;
} }
export default GanttChart; export default GanttChart;

View File

@ -5,7 +5,7 @@ export const getMetaDataFromSpanTree = (treeData: ITraceTree) => {
let globalEnd = Number.NEGATIVE_INFINITY; let globalEnd = Number.NEGATIVE_INFINITY;
let totalSpans = 0; let totalSpans = 0;
let levels = 1; let levels = 1;
const traverse = (treeNode: ITraceTree, level: number = 0) => { const traverse = (treeNode: ITraceTree, level = 0) => {
if (!treeNode) { if (!treeNode) {
return; return;
} }
@ -35,19 +35,19 @@ export const getMetaDataFromSpanTree = (treeData: ITraceTree) => {
}; };
export function getTopLeftFromBody(elem: HTMLElement) { export function getTopLeftFromBody(elem: HTMLElement) {
let box = elem.getBoundingClientRect(); const box = elem.getBoundingClientRect();
let body = document.body; const body = document.body;
let docEl = document.documentElement; const docEl = document.documentElement;
let scrollTop = window.pageYOffset || docEl.scrollTop || body.scrollTop; const scrollTop = window.pageYOffset || docEl.scrollTop || body.scrollTop;
let scrollLeft = window.pageXOffset || docEl.scrollLeft || body.scrollLeft; const scrollLeft = window.pageXOffset || docEl.scrollLeft || body.scrollLeft;
let clientTop = docEl.clientTop || body.clientTop || 0; const clientTop = docEl.clientTop || body.clientTop || 0;
let clientLeft = docEl.clientLeft || body.clientLeft || 0; const clientLeft = docEl.clientLeft || body.clientLeft || 0;
let top = box.top + scrollTop - clientTop; const top = box.top + scrollTop - clientTop;
let left = box.left + scrollLeft - clientLeft; const left = box.left + scrollLeft - clientLeft;
return { top: Math.round(top), left: Math.round(left) }; return { top: Math.round(top), left: Math.round(left) };
} }
@ -57,7 +57,7 @@ export const getNodeById = (
treeData: ITraceTree, treeData: ITraceTree,
): ITraceTree | undefined => { ): ITraceTree | undefined => {
let foundNode: ITraceTree | undefined = undefined; let foundNode: ITraceTree | undefined = undefined;
const traverse = (treeNode: ITraceTree, level: number = 0) => { const traverse = (treeNode: ITraceTree, level = 0) => {
if (!treeNode) { if (!treeNode) {
return; return;
} }
@ -115,7 +115,7 @@ export const isSpanPresent = (
const traverse = ( const traverse = (
treeNode: ITraceTree, treeNode: ITraceTree,
level: number = 0, level = 0,
foundNode: ITraceTree[], foundNode: ITraceTree[],
) => { ) => {
if (!treeNode) { if (!treeNode) {

View File

@ -23,7 +23,7 @@ import { Widgets } from 'types/api/dashboard/getAll';
import Bar from './Bar'; import Bar from './Bar';
import FullView from './FullView'; import FullView from './FullView';
import { Modal, FullViewContainer, ErrorContainer } from './styles'; import { ErrorContainer, FullViewContainer, Modal } from './styles';
const GridCardGraph = ({ const GridCardGraph = ({
widget, widget,

View File

@ -7,8 +7,8 @@ const { Option } = DefaultSelect;
import getLocalStorageKey from 'api/browser/localstorage/get'; import getLocalStorageKey from 'api/browser/localstorage/get';
import setLocalStorageKey from 'api/browser/localstorage/set'; import setLocalStorageKey from 'api/browser/localstorage/set';
import { LOCAL_STORAGE } from 'constants/localStorage'; import { LOCAL_STORAGE } from 'constants/localStorage';
import getTimeString from 'lib/getTimeString';
import dayjs, { Dayjs } from 'dayjs'; import dayjs, { Dayjs } from 'dayjs';
import getTimeString from 'lib/getTimeString';
import { connect, useSelector } from 'react-redux'; import { connect, useSelector } from 'react-redux';
import { RouteComponentProps, withRouter } from 'react-router'; import { RouteComponentProps, withRouter } from 'react-router';
import { bindActionCreators, Dispatch } from 'redux'; import { bindActionCreators, Dispatch } from 'redux';

View File

@ -2,7 +2,7 @@ import { Col } from 'antd';
import ROUTES from 'constants/routes'; import ROUTES from 'constants/routes';
import history from 'lib/history'; import history from 'lib/history';
import React from 'react'; import React from 'react';
import { useLocation, matchPath } from 'react-router-dom'; import { matchPath, useLocation } from 'react-router-dom';
import ShowBreadcrumbs from './Breadcrumbs'; import ShowBreadcrumbs from './Breadcrumbs';
import DateTimeSelector from './DateTimeSelection'; import DateTimeSelector from './DateTimeSelection';

View File

@ -12,7 +12,7 @@ import { generatePath } from 'react-router';
import { Alerts } from 'types/api/alerts/getAll'; import { Alerts } from 'types/api/alerts/getAll';
import DeleteAlert from './DeleteAlert'; import DeleteAlert from './DeleteAlert';
import { ButtonContainer, Button } from './styles'; import { Button, ButtonContainer } from './styles';
import Status from './TableComponents/Status'; import Status from './TableComponents/Status';
const ListAlert = ({ allAlertRules }: ListAlertProps): JSX.Element => { const ListAlert = ({ allAlertRules }: ListAlertProps): JSX.Element => {

View File

@ -1,5 +1,5 @@
import styled from 'styled-components';
import { Button as ButtonComponent } from 'antd'; import { Button as ButtonComponent } from 'antd';
import styled from 'styled-components';
export const ButtonContainer = styled.div` export const ButtonContainer = styled.div`
&&& { &&& {

View File

@ -1,8 +1,9 @@
import { Button } from 'antd'; import { Button } from 'antd';
import ROUTES from 'constants/routes'; import ROUTES from 'constants/routes';
import history from 'lib/history';
import React from 'react'; import React from 'react';
import { generatePath } from 'react-router-dom'; import { generatePath } from 'react-router-dom';
import history from 'lib/history';
import { Data } from '..'; import { Data } from '..';
const Name = (name: Data['name'], data: Data): JSX.Element => { const Name = (name: Data['name'], data: Data): JSX.Element => {

View File

@ -11,7 +11,7 @@ import { AppState } from 'store/reducers';
import DashboardReducer from 'types/reducer/dashboards'; import DashboardReducer from 'types/reducer/dashboards';
import { v4 } from 'uuid'; import { v4 } from 'uuid';
import { NewDashboardButton, TableContainer, ButtonContainer } from './styles'; import { ButtonContainer, NewDashboardButton, TableContainer } from './styles';
import Createdby from './TableComponents/CreatedBy'; import Createdby from './TableComponents/CreatedBy';
import DateComponent from './TableComponents/Date'; import DateComponent from './TableComponents/Date';
import DeleteButton from './TableComponents/DeleteButton'; import DeleteButton from './TableComponents/DeleteButton';

View File

@ -1,4 +1,6 @@
import Table, { ColumnsType } from 'antd/lib/table'; import Table, { ColumnsType } from 'antd/lib/table';
import localStorageGet from 'api/browser/localstorage/get';
import localStorageSet from 'api/browser/localstorage/set';
import { SKIP_ONBOARDING } from 'constants/onboarding'; import { SKIP_ONBOARDING } from 'constants/onboarding';
import ROUTES from 'constants/routes'; import ROUTES from 'constants/routes';
import history from 'lib/history'; import history from 'lib/history';
@ -10,8 +12,6 @@ import MetricReducer from 'types/reducer/metrics';
import SkipBoardModal from './SkipOnBoardModal'; import SkipBoardModal from './SkipOnBoardModal';
import { Container, Name } from './styles'; import { Container, Name } from './styles';
import localStorageGet from 'api/browser/localstorage/get';
import localStorageSet from 'api/browser/localstorage/set';
const Metrics = (): JSX.Element => { const Metrics = (): JSX.Element => {
const [skipOnboarding, setSkipOnboarding] = useState( const [skipOnboarding, setSkipOnboarding] = useState(
@ -31,7 +31,12 @@ const Metrics = (): JSX.Element => {
history.push(to); history.push(to);
}; };
if (services.length === 0 && loading === false && !skipOnboarding && error === true) { if (
services.length === 0 &&
loading === false &&
!skipOnboarding &&
error === true
) {
return <SkipBoardModal onContinueClick={onContinueClick} />; return <SkipBoardModal onContinueClick={onContinueClick} />;
} }

View File

@ -26,7 +26,7 @@ const DashboardGraphSlider = (): JSX.Element => {
[push, pathname], [push, pathname],
); );
const { isDarkMode } = useSelector<AppState, AppReducer>((state) => state.app); const { isDarkMode } = useSelector<AppState, AppReducer>((state) => state.app);
const fillColor:React.CSSProperties['color'] = isDarkMode?"white" : "black"; const fillColor: React.CSSProperties['color'] = isDarkMode ? 'white' : 'black';
return ( return (
<Container> <Container>
{menuItems.map(({ name, Icon, display }) => ( {menuItems.map(({ name, Icon, display }) => (
@ -37,7 +37,7 @@ const DashboardGraphSlider = (): JSX.Element => {
key={name} key={name}
draggable draggable
> >
<Icon fillColor={fillColor}/> <Icon fillColor={fillColor} />
<Text>{display}</Text> <Text>{display}</Text>
</Card> </Card>
))} ))}

View File

@ -1,6 +1,6 @@
import TimeSeries from 'assets/Dashboard/TimeSeries'; import TimeSeries from 'assets/Dashboard/TimeSeries';
import ValueIcon from 'assets/Dashboard/Value';
import { TimeSeriesProps as IconProps } from 'assets/Dashboard/TimeSeries'; import { TimeSeriesProps as IconProps } from 'assets/Dashboard/TimeSeries';
import ValueIcon from 'assets/Dashboard/Value';
const Items: ItemsProps[] = [ const Items: ItemsProps[] = [
{ {

View File

@ -16,10 +16,10 @@ import AppActions from 'types/actions';
import { DeleteQueryProps } from 'types/actions/dashboard'; import { DeleteQueryProps } from 'types/actions/dashboard';
import { import {
ButtonContainer,
Container, Container,
InputContainer, InputContainer,
QueryWrapper, QueryWrapper,
ButtonContainer,
} from './styles'; } from './styles';
const Query = ({ const Query = ({

View File

@ -97,7 +97,23 @@ export const dataTypeCategories = [
{ name: 'exahashes/sec', id: 'EHs' }, { name: 'exahashes/sec', id: 'EHs' },
], ],
}, },
{
name: 'Misc',
formats: [
{ name: 'none', id: 'none' },
{ name: 'String', id: 'string' },
{ name: 'short', id: 'short' },
{ name: 'Percent (0-100)', id: 'percent' },
{ name: 'Percent (0.0-1.0)', id: 'percentunit' },
{ name: 'Humidity (%H)', id: 'humidity' },
{ name: 'Decibel', id: 'dB' },
{ name: 'Hexadecimal (0x)', id: 'hex0x' },
{ name: 'Hexadecimal', id: 'hex' },
{ name: 'Scientific notation', id: 'sci' },
{ name: 'Locale format', id: 'locale' },
{ name: 'Pixels', id: 'pixel' },
],
},
{ {
name: 'Acceleration', name: 'Acceleration',
formats: [ formats: [
@ -364,22 +380,6 @@ export const dataTypeCategories = [
{ name: 'On / Off', id: 'bool_on_off' }, { name: 'On / Off', id: 'bool_on_off' },
], ],
}, },
{
name: 'Misc',
formats: [
{ name: 'String', id: 'string' },
{ name: 'short', id: 'short' },
{ name: 'Percent (0-100)', id: 'percent' },
{ name: 'Percent (0.0-1.0)', id: 'percentunit' },
{ name: 'Humidity (%H)', id: 'humidity' },
{ name: 'Decibel', id: 'dB' },
{ name: 'Hexadecimal (0x)', id: 'hex0x' },
{ name: 'Hexadecimal', id: 'hex' },
{ name: 'Scientific notation', id: 'sci' },
{ name: 'Locale format', id: 'locale' },
{ name: 'Pixels', id: 'pixel' },
],
},
]; ];

View File

@ -77,7 +77,7 @@ const NewWidget = ({
const [description, setDescription] = useState<string>( const [description, setDescription] = useState<string>(
selectedWidget?.description || '', selectedWidget?.description || '',
); );
const [yAxisUnit, setYAxisUnit] = useState<string>(selectedWidget?.yAxisUnit); const [yAxisUnit, setYAxisUnit] = useState<string>(selectedWidget?.yAxisUnit || 'none');
const [stacked, setStacked] = useState<boolean>( const [stacked, setStacked] = useState<boolean>(
selectedWidget?.isStacked || false, selectedWidget?.isStacked || false,

View File

@ -1,7 +1,7 @@
import { Menu, Typography } from 'antd'; import { Menu, Typography } from 'antd';
import { SlackButton, SlackMenuItemContainer, ToggleButton } from './styles';
import ROUTES from 'constants/routes'; import ROUTES from 'constants/routes';
import history from 'lib/history'; import history from 'lib/history';
import setTheme from 'lib/theme/setTheme';
import React, { useCallback, useState } from 'react'; import React, { useCallback, useState } from 'react';
import { connect, useSelector } from 'react-redux'; import { connect, useSelector } from 'react-redux';
import { NavLink } from 'react-router-dom'; import { NavLink } from 'react-router-dom';
@ -12,11 +12,11 @@ import { ToggleDarkMode } from 'store/actions';
import { AppState } from 'store/reducers'; import { AppState } from 'store/reducers';
import AppActions from 'types/actions'; import AppActions from 'types/actions';
import AppReducer from 'types/reducer/app'; import AppReducer from 'types/reducer/app';
import setTheme from 'lib/theme/setTheme';
import menus from './menuItems'; import menus from './menuItems';
import { Logo, Sider, ThemeSwitcherWrapper } from './styles';
import Slack from './Slack'; import Slack from './Slack';
import { SlackButton, SlackMenuItemContainer, ToggleButton } from './styles';
import { Logo, Sider, ThemeSwitcherWrapper } from './styles';
const SideNav = ({ toggleDarkMode }: Props): JSX.Element => { const SideNav = ({ toggleDarkMode }: Props): JSX.Element => {
const [collapsed, setCollapsed] = useState<boolean>(false); const [collapsed, setCollapsed] = useState<boolean>(false);

View File

@ -1,36 +1,26 @@
import React, { useState, useMemo } from 'react'; import { INTERVAL_UNITS } from 'container/TraceDetail/utils';
import { isEqual } from 'lodash-es';
import styles from './style.module.css';
import { useMeasure } from 'react-use';
import { toFixed } from 'utils/toFixed';
import {
INTERVAL_UNITS,
resolveTimeFromInterval,
} from 'container/TraceDetail/utils';
import useThemeMode from 'hooks/useThemeMode'; import useThemeMode from 'hooks/useThemeMode';
import React, { useEffect, useState } from 'react';
import { useMeasure } from 'react-use';
import styles from './style.module.css';
import { Interval } from './types'; import { Interval } from './types';
import { getIntervalSpread, getIntervals } from './utils'; import { getIntervals, getIntervalSpread } from './utils';
interface TimelineProps {
traceMetaData: object; const Timeline_Height = 22;
globalTraceMetadata: object; const Timeline_H_Spacing = 0;
intervalUnit: object;
setIntervalUnit: Function;
}
const Timeline = ({ const Timeline = ({
traceMetaData, traceMetaData,
globalTraceMetadata, globalTraceMetadata,
intervalUnit,
setIntervalUnit, setIntervalUnit,
}: TimelineProps) => { }: TimelineProps) => {
const [ref, { width }] = useMeasure<HTMLDivElement>(); const [ref, { width }] = useMeasure<HTMLDivElement>();
const { isDarkMode } = useThemeMode(); const { isDarkMode } = useThemeMode();
const Timeline_Height = 22;
const Timeline_H_Spacing = 0;
const [intervals, setIntervals] = useState<Interval[] | null>(null); const [intervals, setIntervals] = useState<Interval[] | null>(null);
useMemo(() => { useEffect(() => {
const { const {
baseInterval, baseInterval,
baseSpread, baseSpread,
@ -44,7 +34,7 @@ const Timeline = ({
for (const idx in INTERVAL_UNITS) { for (const idx in INTERVAL_UNITS) {
const standard_interval = INTERVAL_UNITS[idx]; const standard_interval = INTERVAL_UNITS[idx];
if (baseSpread * standard_interval.multiplier < 1) { if (baseSpread * standard_interval.multiplier < 1) {
intervalUnit = INTERVAL_UNITS[idx - 1]; if (idx > 1) intervalUnit = INTERVAL_UNITS[idx - 1];
break; break;
} }
} }
@ -58,7 +48,7 @@ const Timeline = ({
intervalUnit, intervalUnit,
}), }),
); );
}, [traceMetaData, globalTraceMetadata]); }, []);
return ( return (
<div ref={ref} style={{ flex: 1, overflow: 'inherit' }}> <div ref={ref} style={{ flex: 1, overflow: 'inherit' }}>
@ -102,4 +92,11 @@ const Timeline = ({
); );
}; };
interface TimelineProps {
traceMetaData: object;
globalTraceMetadata: object;
intervalUnit: object;
setIntervalUnit: Function;
}
export default Timeline; export default Timeline;

View File

@ -1,20 +1,22 @@
import { isEqual } from 'lodash-es';
import { toFixed } from 'utils/toFixed';
import { import {
INTERVAL_UNITS, INTERVAL_UNITS,
resolveTimeFromInterval, resolveTimeFromInterval,
} from 'container/TraceDetail/utils'; } from 'container/TraceDetail/utils';
import { isEqual } from 'lodash-es';
import { toFixed } from 'utils/toFixed';
import { Interval } from './types';
export const getIntervalSpread = ({ export const getIntervalSpread = ({
localTraceMetaData, localTraceMetaData,
globalTraceMetadata, globalTraceMetadata,
}) => { }): {
const { baseInterval: number;
globalStart: localStart, baseSpread: number;
globalEnd: localEnd, intervalSpreadNormalized: number;
spread: localSpread, } => {
} = localTraceMetaData; const { globalStart: localStart, spread: localSpread } = localTraceMetaData;
const { globalStart, globalEnd, globalSpread } = globalTraceMetadata; const { globalStart } = globalTraceMetadata;
let baseInterval = 0; let baseInterval = 0;
@ -24,7 +26,7 @@ export const getIntervalSpread = ({
const MIN_INTERVALS = 5; const MIN_INTERVALS = 5;
const baseSpread = localSpread; const baseSpread = localSpread;
let intervalSpread = (baseSpread / MIN_INTERVALS) * 1.0; const intervalSpread = (baseSpread / MIN_INTERVALS) * 1.0;
const integerPartString = intervalSpread.toString().split('.')[0]; const integerPartString = intervalSpread.toString().split('.')[0];
const integerPartLength = integerPartString.length; const integerPartLength = integerPartString.length;
const intervalSpreadNormalized = const intervalSpreadNormalized =
@ -45,7 +47,7 @@ export const getIntervals = ({
baseSpread, baseSpread,
intervalSpreadNormalized, intervalSpreadNormalized,
intervalUnit, intervalUnit,
}) => { }): Interval[] => {
const intervals: Interval[] = [ const intervals: Interval[] = [
{ {
label: `${toFixed(resolveTimeFromInterval(baseInterval, intervalUnit), 2)}${ label: `${toFixed(resolveTimeFromInterval(baseInterval, intervalUnit), 2)}${

View File

@ -1,19 +1,19 @@
import React, { useState } from 'react';
import { CheckBoxContainer } from './styles';
import { Checkbox, notification, Typography } from 'antd'; import { Checkbox, notification, Typography } from 'antd';
import { connect, useDispatch, useSelector } from 'react-redux';
import { AppState } from 'store/reducers';
import { TraceFilterEnum, TraceReducer } from 'types/reducer/trace';
import { SelectedTraceFilter } from 'store/actions/trace/selectTraceFilter';
import AppActions from 'types/actions';
import { ThunkDispatch } from 'redux-thunk';
import { bindActionCreators, Dispatch } from 'redux';
import { getFilter, updateURL } from 'store/actions/trace/util';
import getFilters from 'api/trace/getFilters'; import getFilters from 'api/trace/getFilters';
import { AxiosError } from 'axios'; import { AxiosError } from 'axios';
import { GlobalReducer } from 'types/reducer/globalTime'; import React, { useState } from 'react';
import { connect, useDispatch, useSelector } from 'react-redux';
import { bindActionCreators, Dispatch } from 'redux';
import { ThunkDispatch } from 'redux-thunk';
import { SelectedTraceFilter } from 'store/actions/trace/selectTraceFilter';
import { getFilter, updateURL } from 'store/actions/trace/util';
import { AppState } from 'store/reducers';
import AppActions from 'types/actions';
import { UPDATE_ALL_FILTERS } from 'types/actions/trace'; import { UPDATE_ALL_FILTERS } from 'types/actions/trace';
import { GlobalReducer } from 'types/reducer/globalTime';
import { TraceFilterEnum, TraceReducer } from 'types/reducer/trace';
import { CheckBoxContainer } from './styles';
const CheckBoxComponent = (props: CheckBoxProps): JSX.Element => { const CheckBoxComponent = (props: CheckBoxProps): JSX.Element => {
const { const {

View File

@ -2,6 +2,7 @@ import React from 'react';
import { useSelector } from 'react-redux'; import { useSelector } from 'react-redux';
import { AppState } from 'store/reducers'; import { AppState } from 'store/reducers';
import { TraceFilterEnum, TraceReducer } from 'types/reducer/trace'; import { TraceFilterEnum, TraceReducer } from 'types/reducer/trace';
import CheckBoxComponent from '../Common/Checkbox'; import CheckBoxComponent from '../Common/Checkbox';
const CommonCheckBox = (props: CommonCheckBoxProps): JSX.Element => { const CommonCheckBox = (props: CommonCheckBoxProps): JSX.Element => {

View File

@ -1,20 +1,20 @@
import React, { useState } from 'react';
import { Input, Slider } from 'antd'; import { Input, Slider } from 'antd';
import { Container, InputContainer, Text } from './styles'; import { SliderRangeProps } from 'antd/lib/slider';
import { useDispatch, useSelector } from 'react-redux'; import getFilters from 'api/trace/getFilters';
import { AppState } from 'store/reducers';
import { TraceReducer } from 'types/reducer/trace';
import useDebouncedFn from 'hooks/useDebouncedFunction';
import { getFilter, updateURL } from 'store/actions/trace/util';
import dayjs from 'dayjs'; import dayjs from 'dayjs';
import durationPlugin from 'dayjs/plugin/duration'; import durationPlugin from 'dayjs/plugin/duration';
import useDebouncedFn from 'hooks/useDebouncedFunction';
import React, { useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { Dispatch } from 'redux'; import { Dispatch } from 'redux';
import { getFilter, updateURL } from 'store/actions/trace/util';
import { AppState } from 'store/reducers';
import AppActions from 'types/actions'; import AppActions from 'types/actions';
import { UPDATE_ALL_FILTERS } from 'types/actions/trace'; import { UPDATE_ALL_FILTERS } from 'types/actions/trace';
import getFilters from 'api/trace/getFilters';
import { GlobalReducer } from 'types/reducer/globalTime'; import { GlobalReducer } from 'types/reducer/globalTime';
import { SliderRangeProps } from 'antd/lib/slider'; import { TraceReducer } from 'types/reducer/trace';
import { Container, InputContainer, Text } from './styles';
dayjs.extend(durationPlugin); dayjs.extend(durationPlugin);

View File

@ -1,5 +1,5 @@
import styled from 'styled-components';
import { Typography } from 'antd'; import { Typography } from 'antd';
import styled from 'styled-components';
export const DurationText = styled.div` export const DurationText = styled.div`
display: flex; display: flex;

View File

@ -1,12 +1,12 @@
import React from 'react';
import { TraceFilterEnum, TraceReducer } from 'types/reducer/trace';
import { Card } from 'antd'; import { Card } from 'antd';
import Spinner from 'components/Spinner';
import Duration from './Duration'; import React from 'react';
import CommonCheckBox from './CommonCheckBox';
import { useSelector } from 'react-redux'; import { useSelector } from 'react-redux';
import { AppState } from 'store/reducers'; import { AppState } from 'store/reducers';
import Spinner from 'components/Spinner'; import { TraceFilterEnum, TraceReducer } from 'types/reducer/trace';
import CommonCheckBox from './CommonCheckBox';
import Duration from './Duration';
const PanelBody = (props: PanelBodyProps): JSX.Element => { const PanelBody = (props: PanelBodyProps): JSX.Element => {
const { type } = props; const { type } = props;

View File

@ -1,6 +1,9 @@
import React, { useState } from 'react';
import { DownOutlined, RightOutlined } from '@ant-design/icons'; import { DownOutlined, RightOutlined } from '@ant-design/icons';
import { Card, Typography, Divider, notification } from 'antd'; import { Card, Divider, notification, Typography } from 'antd';
import React, { useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { AppState } from 'store/reducers';
import { TraceFilterEnum, TraceReducer } from 'types/reducer/trace';
import { import {
ButtonComponent, ButtonComponent,
@ -9,19 +12,16 @@ import {
IconContainer, IconContainer,
TextCotainer, TextCotainer,
} from './styles'; } from './styles';
import { useDispatch, useSelector } from 'react-redux';
import { AppState } from 'store/reducers';
import { TraceFilterEnum, TraceReducer } from 'types/reducer/trace';
const { Text } = Typography; const { Text } = Typography;
import { AllPanelHeading } from 'types/reducer/trace';
import getFilters from 'api/trace/getFilters'; import getFilters from 'api/trace/getFilters';
import { GlobalReducer } from 'types/reducer/globalTime'; import { AxiosError } from 'axios';
import { Dispatch } from 'redux';
import { getFilter, updateURL } from 'store/actions/trace/util'; import { getFilter, updateURL } from 'store/actions/trace/util';
import AppActions from 'types/actions'; import AppActions from 'types/actions';
import { Dispatch } from 'redux';
import { UPDATE_ALL_FILTERS } from 'types/actions/trace'; import { UPDATE_ALL_FILTERS } from 'types/actions/trace';
import { AxiosError } from 'axios'; import { GlobalReducer } from 'types/reducer/globalTime';
import { AllPanelHeading } from 'types/reducer/trace';
const PanelHeading = (props: PanelHeadingProps): JSX.Element => { const PanelHeading = (props: PanelHeadingProps): JSX.Element => {
const { const {

View File

@ -1,10 +1,10 @@
import { ChartData, ChartDataset, ChartDatasetProperties } from 'chart.js'; import { ChartData, ChartDataset, ChartDatasetProperties } from 'chart.js';
import { TraceReducer } from 'types/reducer/trace';
import dayjs from 'dayjs'; import dayjs from 'dayjs';
import { colors } from 'lib/getRandomColor'; import { colors } from 'lib/getRandomColor';
import { TraceReducer } from 'types/reducer/trace';
function transposeArray(array: number[][], arrayLength: number) { function transposeArray(array: number[][], arrayLength: number) {
let newArray: number[][] = []; const newArray: number[][] = [];
for (let i = 0; i < array.length; i++) { for (let i = 0; i < array.length; i++) {
newArray.push([]); newArray.push([]);
} }

View File

@ -1,6 +1,6 @@
import { AutoComplete, AutoCompleteProps, Input, notification } from 'antd'; import { AutoComplete, AutoCompleteProps, Input, notification } from 'antd';
import getTagFilters from 'api/trace/getTagFilter'; import getTagFilters from 'api/trace/getTagFilter';
import React, { useEffect, useState } from 'react'; import React, { useCallback, useEffect, useRef, useState } from 'react';
import { useSelector } from 'react-redux'; import { useSelector } from 'react-redux';
import { AppState } from 'store/reducers'; import { AppState } from 'store/reducers';
import { GlobalReducer } from 'types/reducer/globalTime'; import { GlobalReducer } from 'types/reducer/globalTime';
@ -18,7 +18,7 @@ const TagsKey = (props: TagsKeysProps): JSX.Element => {
const [options, setOptions] = useState<AutoCompleteProps['options']>([]); const [options, setOptions] = useState<AutoCompleteProps['options']>([]);
const onSearchHandler = async () => { const onSearchHandler = useCallback(async () => {
try { try {
setSelectLoading(true); setSelectLoading(true);
const response = await getTagFilters({ const response = await getTagFilters({
@ -55,11 +55,16 @@ const TagsKey = (props: TagsKeysProps): JSX.Element => {
}); });
setSelectLoading(false); setSelectLoading(false);
} }
}; }, [globalTime, traces]);
const counter = useRef(0);
useEffect(() => { useEffect(() => {
onSearchHandler(); if (counter.current === 0) {
}, []); counter.current = 1;
onSearchHandler();
}
}, [onSearchHandler]);
return ( return (
<AutoComplete <AutoComplete
@ -68,7 +73,7 @@ const TagsKey = (props: TagsKeysProps): JSX.Element => {
style={{ width: 300 }} style={{ width: 300 }}
options={options} options={options}
value={selectedKey} value={selectedKey}
onChange={(value) => { onChange={(value): void => {
if (options && options.find((option) => option.value === value)) { if (options && options.find((option) => option.value === value)) {
setSelectedKey(value); setSelectedKey(value);

View File

@ -1,21 +1,21 @@
import React from 'react'; import { CloseOutlined } from '@ant-design/icons';
import { Select } from 'antd'; import { Select } from 'antd';
import { SelectValue } from 'antd/lib/select';
import React from 'react';
import { connect, useSelector } from 'react-redux';
import { bindActionCreators } from 'redux';
import { ThunkDispatch } from 'redux-thunk';
import { UpdateSelectedTags } from 'store/actions/trace/updateTagsSelected';
import { AppState } from 'store/reducers';
import AppActions from 'types/actions';
import { TraceReducer } from 'types/reducer/trace';
import { import {
Container, Container,
IconContainer, IconContainer,
SelectComponent, SelectComponent,
ValueSelect, ValueSelect,
} from './styles'; } from './styles';
import { connect, useSelector } from 'react-redux';
import { AppState } from 'store/reducers';
import { TraceReducer } from 'types/reducer/trace';
import { CloseOutlined } from '@ant-design/icons';
import { SelectValue } from 'antd/lib/select';
import { ThunkDispatch } from 'redux-thunk';
import AppActions from 'types/actions';
import { bindActionCreators } from 'redux';
import { UpdateSelectedTags } from 'store/actions/trace/updateTagsSelected';
import TagsKey from './TagKey'; import TagsKey from './TagKey';
const { Option } = Select; const { Option } = Select;
@ -45,11 +45,11 @@ const SingleTags = (props: AllTagsProps): JSX.Element => {
Values: selectedValues, Values: selectedValues,
} = props.tag; } = props.tag;
const onDeleteTagHandler = (index: number) => { const onDeleteTagHandler = (index: number): void => {
props.onCloseHandler(index); props.onCloseHandler(index);
}; };
const onChangeOperatorHandler = (key: SelectValue) => { const onChangeOperatorHandler = (key: SelectValue): void => {
props.setLocalSelectedTags([ props.setLocalSelectedTags([
...traces.selectedTags.slice(0, props.index), ...traces.selectedTags.slice(0, props.index),
{ {
@ -83,7 +83,7 @@ const SingleTags = (props: AllTagsProps): JSX.Element => {
<ValueSelect <ValueSelect
value={selectedValues} value={selectedValues}
onChange={(value) => { onChange={(value): void => {
props.setLocalSelectedTags((tags) => [ props.setLocalSelectedTags((tags) => [
...tags.slice(0, props.index), ...tags.slice(0, props.index),
{ {
@ -99,7 +99,7 @@ const SingleTags = (props: AllTagsProps): JSX.Element => {
<IconContainer <IconContainer
role={'button'} role={'button'}
onClick={() => onDeleteTagHandler(props.index)} onClick={(): void => onDeleteTagHandler(props.index)}
> >
<CloseOutlined /> <CloseOutlined />
</IconContainer> </IconContainer>

View File

@ -1,5 +1,5 @@
import { Select, Space } from 'antd';
import styled from 'styled-components'; import styled from 'styled-components';
import { Button, Select, Space } from 'antd';
export const SpaceComponent = styled(Space)` export const SpaceComponent = styled(Space)`
&&& { &&& {

View File

@ -1,27 +1,28 @@
import { CaretRightFilled } from '@ant-design/icons';
import { Button, Space, Typography } from 'antd';
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
import { Button, Space, Typography } from 'antd';
import { CaretRightFilled } from '@ant-design/icons';
import { import {
Container,
ButtonContainer, ButtonContainer,
Container,
CurrentTagsContainer, CurrentTagsContainer,
Wrapper,
ErrorContainer, ErrorContainer,
Wrapper,
} from './styles'; } from './styles';
import Tags from './Tag'; import Tags from './Tag';
const { Text } = Typography; const { Text } = Typography;
import { PlusOutlined } from '@ant-design/icons'; import { PlusOutlined } from '@ant-design/icons';
import { isEqual } from 'lodash-es';
import { connect, useSelector } from 'react-redux'; import { connect, useSelector } from 'react-redux';
import { AppState } from 'store/reducers';
import { TraceReducer } from 'types/reducer/trace';
import { bindActionCreators } from 'redux'; import { bindActionCreators } from 'redux';
import { ThunkDispatch } from 'redux-thunk'; import { ThunkDispatch } from 'redux-thunk';
import AppActions from 'types/actions';
import { UpdateTagIsError } from 'store/actions/trace/updateIsTagsError'; import { UpdateTagIsError } from 'store/actions/trace/updateIsTagsError';
import { parseTagsToQuery } from '../util';
import { isEqual } from 'lodash-es';
import { UpdateTagVisiblity } from 'store/actions/trace/updateTagPanelVisiblity'; import { UpdateTagVisiblity } from 'store/actions/trace/updateTagPanelVisiblity';
import { AppState } from 'store/reducers';
import AppActions from 'types/actions';
import { TraceReducer } from 'types/reducer/trace';
import { parseTagsToQuery } from '../util';
const { Paragraph } = Typography; const { Paragraph } = Typography;
@ -37,7 +38,7 @@ const AllTags = ({
TraceReducer['selectedTags'] TraceReducer['selectedTags']
>(traces.selectedTags); >(traces.selectedTags);
const onTagAddHandler = () => { const onTagAddHandler = (): void => {
setLocalSelectedTags((tags) => [ setLocalSelectedTags((tags) => [
...tags, ...tags,
{ {
@ -52,16 +53,16 @@ const AllTags = ({
if (!isEqual(traces.selectedTags, localSelectedTags)) { if (!isEqual(traces.selectedTags, localSelectedTags)) {
setLocalSelectedTags(traces.selectedTags); setLocalSelectedTags(traces.selectedTags);
} }
}, [traces.selectedTags]); }, [traces.selectedTags, localSelectedTags]);
const onCloseHandler = (index: number) => { const onCloseHandler = (index: number): void => {
setLocalSelectedTags([ setLocalSelectedTags([
...localSelectedTags.slice(0, index), ...localSelectedTags.slice(0, index),
...localSelectedTags.slice(index + 1, localSelectedTags.length), ...localSelectedTags.slice(index + 1, localSelectedTags.length),
]); ]);
}; };
const onRunQueryHandler = () => { const onRunQueryHandler = (): void => {
const parsedQuery = parseTagsToQuery(localSelectedTags); const parsedQuery = parseTagsToQuery(localSelectedTags);
if (parsedQuery.isError) { if (parsedQuery.isError) {
@ -74,7 +75,7 @@ const AllTags = ({
} }
}; };
const onResetHandler = () => { const onResetHandler = (): void => {
setLocalSelectedTags([]); setLocalSelectedTags([]);
}; };
@ -102,10 +103,10 @@ const AllTags = ({
<CurrentTagsContainer> <CurrentTagsContainer>
{localSelectedTags.map((tags, index) => ( {localSelectedTags.map((tags, index) => (
<Tags <Tags
key={index} key={tags.Key.join(',')}
tag={tags} tag={tags}
index={index} index={index}
onCloseHandler={() => onCloseHandler(index)} onCloseHandler={(): void => onCloseHandler(index)}
setLocalSelectedTags={setLocalSelectedTags} setLocalSelectedTags={setLocalSelectedTags}
/> />
))} ))}

View File

@ -1,5 +1,5 @@
import styled from 'styled-components';
import { Card } from 'antd'; import { Card } from 'antd';
import styled from 'styled-components';
export const Container = styled(Card)` export const Container = styled(Card)`
top: 120%; top: 120%;

View File

@ -1,20 +1,21 @@
import React, { useEffect, useRef, useState } from 'react';
import { Space } from 'antd';
import { Container, SearchComponent } from './styles';
import useClickOutside from 'hooks/useClickOutside';
import Tags from './AllTags';
import { connect, useDispatch, useSelector } from 'react-redux';
import { AppState } from 'store/reducers';
import { TraceReducer } from 'types/reducer/trace';
import { ThunkDispatch } from 'redux-thunk';
import AppActions from 'types/actions';
import { bindActionCreators, Dispatch } from 'redux';
import { UpdateTagVisiblity } from 'store/actions/trace/updateTagPanelVisiblity';
import { parseQueryToTags, parseTagsToQuery } from './util';
import { UpdateTagIsError } from 'store/actions/trace/updateIsTagsError';
import { CaretRightFilled } from '@ant-design/icons'; import { CaretRightFilled } from '@ant-design/icons';
import { Space } from 'antd';
import useClickOutside from 'hooks/useClickOutside';
import React, { useEffect, useRef, useState } from 'react';
import { connect, useDispatch, useSelector } from 'react-redux';
import { bindActionCreators, Dispatch } from 'redux';
import { ThunkDispatch } from 'redux-thunk';
import { UpdateTagIsError } from 'store/actions/trace/updateIsTagsError';
import { UpdateTagVisiblity } from 'store/actions/trace/updateTagPanelVisiblity';
import { updateURL } from 'store/actions/trace/util'; import { updateURL } from 'store/actions/trace/util';
import { AppState } from 'store/reducers';
import AppActions from 'types/actions';
import { UPDATE_ALL_FILTERS } from 'types/actions/trace'; import { UPDATE_ALL_FILTERS } from 'types/actions/trace';
import { TraceReducer } from 'types/reducer/trace';
import Tags from './AllTags';
import { Container, SearchComponent } from './styles';
import { parseQueryToTags, parseTagsToQuery } from './util';
const Search = ({ const Search = ({
updateTagVisiblity, updateTagVisiblity,
@ -38,7 +39,7 @@ const Search = ({
if (value.length === 0 && traces.isTagModalError) { if (value.length === 0 && traces.isTagModalError) {
updateTagIsError(false); updateTagIsError(false);
} }
}, [traces.isTagModalError, value]); }, [traces.isTagModalError, value, updateTagIsError]);
const tagRef = useRef<HTMLDivElement>(null); const tagRef = useRef<HTMLDivElement>(null);
@ -69,11 +70,11 @@ const Search = ({
} }
}); });
const onChangeHandler = (search: string) => { const onChangeHandler = (search: string): void => {
setValue(search); setValue(search);
}; };
const setIsTagsModalHandler = (value: boolean) => { const setIsTagsModalHandler = (value: boolean): void => {
updateTagVisiblity(value); updateTagVisiblity(value);
}; };
@ -82,7 +83,9 @@ const Search = ({
setIsTagsModalHandler(true); setIsTagsModalHandler(true);
}; };
const updateFilters = async (selectedTags: TraceReducer['selectedTags']) => { const updateFilters = async (
selectedTags: TraceReducer['selectedTags'],
): Promise<void> => {
dispatch({ dispatch({
type: UPDATE_ALL_FILTERS, type: UPDATE_ALL_FILTERS,
payload: { payload: {
@ -111,7 +114,7 @@ const Search = ({
<Space direction="vertical" style={{ width: '100%' }}> <Space direction="vertical" style={{ width: '100%' }}>
<Container ref={tagRef}> <Container ref={tagRef}>
<SearchComponent <SearchComponent
onChange={(event) => onChangeHandler(event.target.value)} onChange={(event): void => onChangeHandler(event.target.value)}
value={value} value={value}
allowClear allowClear
disabled={traces.filterLoading} disabled={traces.filterLoading}
@ -119,7 +122,7 @@ const Search = ({
placeholder="Click to filter by tags" placeholder="Click to filter by tags"
type={'search'} type={'search'}
enterButton={<CaretRightFilled />} enterButton={<CaretRightFilled />}
onSearch={(string) => { onSearch={(string): void => {
if (string.length === 0) { if (string.length === 0) {
updateTagVisiblity(false); updateTagVisiblity(false);
updateFilters([]); updateFilters([]);

View File

@ -1,5 +1,5 @@
import styled from 'styled-components';
import { Input } from 'antd'; import { Input } from 'antd';
import styled from 'styled-components';
const { Search } = Input; const { Search } = Input;

View File

@ -1,21 +1,22 @@
import { SelectProps, Space } from 'antd';
import { SelectValue } from 'antd/lib/select';
import React from 'react'; import React from 'react';
import { Space, SelectProps } from 'antd';
import { functions, groupBy } from './config';
import { useDispatch, useSelector } from 'react-redux'; import { useDispatch, useSelector } from 'react-redux';
import { Dispatch } from 'redux';
import { AppState } from 'store/reducers'; import { AppState } from 'store/reducers';
import { TraceReducer } from 'types/reducer/trace';
import AppActions from 'types/actions'; import AppActions from 'types/actions';
import { import {
UPDATE_SELECTED_FUNCTION, UPDATE_SELECTED_FUNCTION,
UPDATE_SELECTED_GROUP_BY, UPDATE_SELECTED_GROUP_BY,
} from 'types/actions/trace'; } from 'types/actions/trace';
import { Dispatch } from 'redux'; import { TraceReducer } from 'types/reducer/trace';
import { functions, groupBy } from './config';
import { SelectComponent } from './styles'; import { SelectComponent } from './styles';
import { SelectValue } from 'antd/lib/select';
const { Option } = SelectComponent; const { Option } = SelectComponent;
const TraceGraphFilter = () => { const TraceGraphFilter = (): JSX.Element => {
const { selectedFunction, selectedGroupBy } = useSelector< const { selectedFunction, selectedGroupBy } = useSelector<
AppState, AppState,
TraceReducer TraceReducer
@ -75,11 +76,13 @@ const TraceGraphFilter = () => {
value={groupBy.find((e) => selectedGroupBy === e.key)?.displayValue} value={groupBy.find((e) => selectedGroupBy === e.key)?.displayValue}
onChange={onClickSelectedGroupByHandler} onChange={onClickSelectedGroupByHandler}
> >
{groupBy.map((value) => ( {groupBy.map(
<Option value={value.key} key={value.key}> (value): JSX.Element => (
{value.displayValue} <Option value={value.key} key={value.key}>
</Option> {value.displayValue}
))} </Option>
),
)}
</SelectComponent> </SelectComponent>
</Space> </Space>
); );

View File

@ -1,5 +1,4 @@
import { Select } from 'antd'; import { Select } from 'antd';
import styled from 'styled-components'; import styled from 'styled-components';
export const SelectComponent = styled(Select)` export const SelectComponent = styled(Select)`

View File

@ -1,13 +1,13 @@
import { Button, Modal, Collapse } from 'antd'; import { Button, Collapse, Modal } from 'antd';
import useThemeMode from 'hooks/useThemeMode'; import useThemeMode from 'hooks/useThemeMode';
import React, { useRef, useState } from 'react'; import React, { useState } from 'react';
import { ITraceTree } from 'types/api/trace/getTraceItem'; import { ITraceTree } from 'types/api/trace/getTraceItem';
import { CustomSubText, CustomSubTitle } from './styles'; import { CustomSubText, CustomSubTitle } from './styles';
// import Editor from 'components/Editor';
const { Panel } = Collapse; const { Panel } = Collapse;
const ErrorTag = ({ event }: ErrorTagProps) => { const ErrorTag = ({ event }: ErrorTagProps): JSX.Element => {
const [isOpen, setIsOpen] = useState(false); const [isOpen, setIsOpen] = useState(false);
const { isDarkMode } = useThemeMode(); const { isDarkMode } = useThemeMode();
// const useTextRef = useRef(''); // const useTextRef = useRef('');
@ -17,7 +17,7 @@ const ErrorTag = ({ event }: ErrorTagProps) => {
subText: '', subText: '',
}); });
const onToggleHandler = (state: boolean) => { const onToggleHandler = (state: boolean): void => {
setIsOpen(state); setIsOpen(state);
}; };
@ -30,6 +30,7 @@ const ErrorTag = ({ event }: ErrorTagProps) => {
<Collapse <Collapse
defaultActiveKey={[name || attributeMap.event]} defaultActiveKey={[name || attributeMap.event]}
expandIconPosition="right" expandIconPosition="right"
key={name}
> >
<Panel <Panel
header={name || attributeMap?.event} header={name || attributeMap?.event}
@ -48,7 +49,7 @@ const ErrorTag = ({ event }: ErrorTagProps) => {
{isEllipsed && ( {isEllipsed && (
<Button <Button
style={{ padding: 0, margin: 0 }} style={{ padding: 0, margin: 0 }}
onClick={() => { onClick={(): void => {
onToggleHandler(true); onToggleHandler(true);
setText({ setText({
subText: value, subText: value,
@ -62,8 +63,6 @@ const ErrorTag = ({ event }: ErrorTagProps) => {
</Button> </Button>
)} )}
</CustomSubText> </CustomSubText>
</> </>
); );
})} })}
@ -72,7 +71,7 @@ const ErrorTag = ({ event }: ErrorTagProps) => {
); );
})} })}
<Modal <Modal
onCancel={() => onToggleHandler(false)} onCancel={(): void => onToggleHandler(false)}
title="Log Message" title="Log Message"
visible={isOpen} visible={isOpen}
destroyOnClose destroyOnClose

View File

@ -1,6 +1,9 @@
import { Space, Tabs, Typography } from 'antd'; import { Space, Tabs, Typography } from 'antd';
import useThemeMode from 'hooks/useThemeMode';
import React from 'react'; import React from 'react';
import { ITraceTree } from 'types/api/trace/getTraceItem'; import { ITraceTree } from 'types/api/trace/getTraceItem';
import ErrorTag from './ErrorTag';
import { import {
CardContainer, CardContainer,
CustomSubText, CustomSubText,
@ -8,8 +11,6 @@ import {
CustomText, CustomText,
CustomTitle, CustomTitle,
} from './styles'; } from './styles';
import ErrorTag from './ErrorTag';
import useThemeMode from 'hooks/useThemeMode';
const { TabPane } = Tabs; const { TabPane } = Tabs;
@ -40,7 +41,7 @@ const SelectedSpanDetails = (props: SelectedSpanDetailsProps): JSX.Element => {
{tags.length !== 0 ? ( {tags.length !== 0 ? (
tags.map((tags) => { tags.map((tags) => {
return ( return (
<React.Fragment> <React.Fragment key={tags.key}>
{tags.value && ( {tags.value && (
<> <>
<CustomSubTitle>{tags.key}</CustomSubTitle> <CustomSubTitle>{tags.key}</CustomSubTitle>

View File

@ -1,21 +1,22 @@
import React, { useEffect, useMemo, useState } from 'react';
import { Col, Divider, Row, Typography, Space, Button } from 'antd';
import { FilterOutlined } from '@ant-design/icons'; import { FilterOutlined } from '@ant-design/icons';
import { Button, Col, Divider, Row, Space, Typography } from 'antd';
import GanttChart from 'container/GantChart'; import GanttChart from 'container/GantChart';
import { getNodeById } from 'container/GantChart/utils'; import { getNodeById } from 'container/GantChart/utils';
import Timeline from 'container/Timeline'; import Timeline from 'container/Timeline';
import TraceFlameGraph from 'container/TraceFlameGraph'; import TraceFlameGraph from 'container/TraceFlameGraph';
import dayjs from 'dayjs'; import dayjs from 'dayjs';
import useUrlQuery from 'hooks/useUrlQuery';
import { spanServiceNameToColorMapping } from 'lib/getRandomColor'; import { spanServiceNameToColorMapping } from 'lib/getRandomColor';
import { getSortedData } from './utils'; import history from 'lib/history';
import { SPAN_DETAILS_LEFT_COL_WIDTH } from 'pages/TraceDetail/constants';
import React, { useEffect, useMemo, useState } from 'react';
import { ITraceTree, PayloadProps } from 'types/api/trace/getTraceItem'; import { ITraceTree, PayloadProps } from 'types/api/trace/getTraceItem';
import { getSpanTreeMetadata } from 'utils/getSpanTreeMetadata'; import { getSpanTreeMetadata } from 'utils/getSpanTreeMetadata';
import { spanToTreeUtil } from 'utils/spanToTree'; import { spanToTreeUtil } from 'utils/spanToTree';
import SelectedSpanDetails from './SelectedSpanDetails'; import SelectedSpanDetails from './SelectedSpanDetails';
import useUrlQuery from 'hooks/useUrlQuery';
import styles from './TraceGraph.module.css'; import styles from './TraceGraph.module.css';
import history from 'lib/history'; import { getSortedData } from './utils';
import { SPAN_DETAILS_LEFT_COL_WIDTH } from 'pages/TraceDetail/constants';
import { INTERVAL_UNITS } from './utils'; import { INTERVAL_UNITS } from './utils';
const TraceDetail = ({ response }: TraceDetailProps): JSX.Element => { const TraceDetail = ({ response }: TraceDetailProps): JSX.Element => {
@ -25,10 +26,10 @@ const TraceDetail = ({ response }: TraceDetailProps): JSX.Element => {
); );
const urlQuery = useUrlQuery(); const urlQuery = useUrlQuery();
const [spanId, _setSpanId] = useState<string | null>(urlQuery.get('spanId')); const [spanId] = useState<string | null>(urlQuery.get('spanId'));
const [intervalUnit, setIntervalUnit] = useState(INTERVAL_UNITS[0]); const [intervalUnit, setIntervalUnit] = useState(INTERVAL_UNITS[0]);
const [searchSpanString, setSearchSpanString] = useState(''); // const [searchSpanString, setSearchSpanString] = useState('');
const [activeHoverId, setActiveHoverId] = useState<string>(''); const [activeHoverId, setActiveHoverId] = useState<string>('');
const [activeSelectedId, setActiveSelectedId] = useState<string>(spanId || ''); const [activeSelectedId, setActiveSelectedId] = useState<string>(spanId || '');
@ -38,9 +39,9 @@ const TraceDetail = ({ response }: TraceDetailProps): JSX.Element => {
const { treeData: tree, ...traceMetaData } = useMemo(() => { const { treeData: tree, ...traceMetaData } = useMemo(() => {
return getSpanTreeMetadata(getSortedData(treeData), spanServiceColors); return getSpanTreeMetadata(getSortedData(treeData), spanServiceColors);
}, [treeData]); }, [treeData, spanServiceColors]);
const [globalTraceMetadata, _setGlobalTraceMetadata] = useState<object>({ const [globalTraceMetadata] = useState<Record<string, number>>({
...traceMetaData, ...traceMetaData,
}); });
@ -57,10 +58,10 @@ const TraceDetail = ({ response }: TraceDetailProps): JSX.Element => {
return getNodeById(activeSelectedId, treeData); return getNodeById(activeSelectedId, treeData);
}, [activeSelectedId, treeData]); }, [activeSelectedId, treeData]);
const onSearchHandler = (value: string) => { // const onSearchHandler = (value: string) => {
setSearchSpanString(value); // setSearchSpanString(value);
setTreeData(spanToTreeUtil(response[0].events)); // setTreeData(spanToTreeUtil(response[0].events));
}; // };
const onFocusSelectedSpanHandler = () => { const onFocusSelectedSpanHandler = () => {
const treeNode = getNodeById(activeSelectedId, tree); const treeNode = getNodeById(activeSelectedId, tree);
if (treeNode) { if (treeNode) {
@ -68,7 +69,7 @@ const TraceDetail = ({ response }: TraceDetailProps): JSX.Element => {
} }
}; };
const onResetHandler = () => { const onResetHandler = (): void => {
setTreeData(spanToTreeUtil(response[0].events)); setTreeData(spanToTreeUtil(response[0].events));
}; };

View File

@ -1,8 +1,8 @@
/** /**
* string is present on the span or not * string is present on the span or not
*/ */
import { ITraceTree, Span } from 'types/api/trace/getTraceItem';
import { sortBy } from 'lodash-es'; import { sortBy } from 'lodash-es';
import { ITraceTree, Span } from 'types/api/trace/getTraceItem';
export const filterSpansByString = ( export const filterSpansByString = (
searchString: string, searchString: string,
@ -35,12 +35,12 @@ export const INTERVAL_UNITS: IIntervalUnit[] = [
export const resolveTimeFromInterval = ( export const resolveTimeFromInterval = (
intervalTime: number, intervalTime: number,
intervalUnit: IIntervalUnit, intervalUnit: IIntervalUnit,
) => { ): number => {
return intervalTime * intervalUnit.multiplier; return intervalTime * intervalUnit.multiplier;
}; };
export const getSortedData = (treeData: ITraceTree) => { export const getSortedData = (treeData: ITraceTree): undefined | ITraceTree => {
const traverse = (treeNode: ITraceTree, level: number = 0) => { const traverse = (treeNode: ITraceTree, level = 0): void => {
if (!treeNode) { if (!treeNode) {
return; return;
} }

View File

@ -1,7 +1,7 @@
import { expect } from '@jest/globals'; import { expect } from '@jest/globals';
import React from 'react';
import { render } from '@testing-library/react'; import { render } from '@testing-library/react';
import TraceFlameGraph from 'container/TraceFlameGraph'; import TraceFlameGraph from 'container/TraceFlameGraph';
import React from 'react';
test('loads and displays greeting', async () => { test('loads and displays greeting', async () => {
const { asFragment } = render(<TraceFlameGraph />); const { asFragment } = render(<TraceFlameGraph />);

View File

@ -1,17 +1,31 @@
import React, { useState, useLayoutEffect, useMemo } from 'react';
import Color from 'color'; import Color from 'color';
import { pushDStree } from 'store/actions'; import { ITraceMetaData } from 'container/GantChart';
import {
SpanItemContainer,
TraceFlameGraphContainer,
TOTAL_SPAN_HEIGHT,
} from './styles';
import { import {
IIntervalUnit, IIntervalUnit,
resolveTimeFromInterval, resolveTimeFromInterval,
} from 'container/TraceDetail/utils'; } from 'container/TraceDetail/utils';
import { toFixed } from 'utils/toFixed';
import useThemeMode from 'hooks/useThemeMode'; import useThemeMode from 'hooks/useThemeMode';
import React, { useLayoutEffect, useMemo, useState } from 'react';
import { ITraceTree } from 'types/api/trace/getTraceItem';
import { toFixed } from 'utils/toFixed';
import {
SpanItemContainer,
TOTAL_SPAN_HEIGHT,
TraceFlameGraphContainer,
} from './styles';
interface SpanItem {
topOffset: number;
leftOffset: number;
width: number;
spanData: ITraceTree;
tooltipText: string;
onSpanSelect: (id: string) => void;
onSpanHover: React.Dispatch<React.SetStateAction<string>>;
hoveredSpanId: string;
selectedSpanId: string;
}
const SpanItem = ({ const SpanItem = ({
topOffset = 0, // top offset in px topOffset = 0, // top offset in px
@ -23,20 +37,10 @@ const SpanItem = ({
onSpanHover, onSpanHover,
hoveredSpanId, hoveredSpanId,
selectedSpanId, selectedSpanId,
}: { }: SpanItem): JSX.Element => {
topOffset: number;
leftOffset: number;
width: number;
spanData: pushDStree;
tooltipText: string;
onSpanSelect: Function;
onSpanHover: Function;
hoveredSpanId: string;
selectedSpanId: string;
}) => {
const { serviceColour } = spanData; const { serviceColour } = spanData;
const [isSelected, setIsSelected] = useState<boolean>(false); const [isSelected, setIsSelected] = useState<boolean>(false);
const [isLocalHover, setIsLocalHover] = useState<boolean>(false); // const [isLocalHover, setIsLocalHover] = useState<boolean>(false);
const { isDarkMode } = useThemeMode(); const { isDarkMode } = useThemeMode();
useLayoutEffect(() => { useLayoutEffect(() => {
@ -46,16 +50,16 @@ const SpanItem = ({
) { ) {
setIsSelected(true); setIsSelected(true);
} }
}, [hoveredSpanId, selectedSpanId]); }, [hoveredSpanId, selectedSpanId, isSelected, spanData]);
const handleHover = (hoverState: boolean) => { const handleHover = (hoverState: boolean): void => {
setIsLocalHover(hoverState); // setIsLocalHover(hoverState);
if (hoverState) onSpanHover(spanData.id); if (hoverState) onSpanHover(spanData.id);
else onSpanHover(null); else onSpanHover('');
}; };
const handleClick = () => { const handleClick = (): void => {
onSpanSelect(spanData.id); onSpanSelect(spanData.id);
}; };
@ -64,17 +68,17 @@ const SpanItem = ({
? Color(serviceColour).lighten(0.3) ? Color(serviceColour).lighten(0.3)
: Color(serviceColour).darken(0.3); : Color(serviceColour).darken(0.3);
return `${isSelected ? selectedSpanColor : serviceColour}`; return `${isSelected ? selectedSpanColor : serviceColour}`;
}, [isSelected, serviceColour]); }, [isSelected, serviceColour, isDarkMode]);
return ( return (
<> <>
<SpanItemContainer <SpanItemContainer
title={tooltipText} title={tooltipText}
onClick={handleClick} onClick={handleClick}
onMouseEnter={() => { onMouseEnter={(): void => {
handleHover(true); handleHover(true);
}} }}
onMouseLeave={() => { onMouseLeave={(): void => {
handleHover(false); handleHover(false);
}} }}
topOffset={topOffset} topOffset={topOffset}
@ -89,26 +93,20 @@ const SpanItem = ({
}; };
const TraceFlameGraph = (props: { const TraceFlameGraph = (props: {
treeData: pushDStree; treeData: ITraceTree;
traceMetaData: any; traceMetaData: ITraceMetaData;
onSpanHover: Function; onSpanHover: SpanItem['onSpanHover'];
onSpanSelect: Function; onSpanSelect: SpanItem['onSpanSelect'];
hoveredSpanId: string; hoveredSpanId: string;
selectedSpanId: string; selectedSpanId: string;
intervalUnit: IIntervalUnit; intervalUnit: IIntervalUnit;
}) => { }): JSX.Element => {
if (!props.treeData || props.treeData.id === 'empty' || !props.traceMetaData) { if (!props.treeData || props.treeData.id === 'empty' || !props.traceMetaData) {
return null; return <></>;
} }
const { intervalUnit } = props; const { intervalUnit } = props;
const { const { globalStart, spread, levels } = props.traceMetaData;
globalStart,
globalEnd,
spread,
totalSpans,
levels,
} = props.traceMetaData;
const RenderSpanRecursive = ({ const RenderSpanRecursive = ({
level = 0, level = 0,
spanData, spanData,
@ -118,16 +116,16 @@ const TraceFlameGraph = (props: {
hoveredSpanId, hoveredSpanId,
selectedSpanId, selectedSpanId,
}: { }: {
spanData: pushDStree; spanData: ITraceTree;
level?: number; level?: number;
parentLeftOffset?: number; parentLeftOffset?: number;
onSpanHover: Function; onSpanHover: SpanItem['onSpanHover'];
onSpanSelect: Function; onSpanSelect: SpanItem['onSpanSelect'];
hoveredSpanId: string; hoveredSpanId: string;
selectedSpanId: string; selectedSpanId: string;
}) => { }): JSX.Element => {
if (!spanData) { if (!spanData) {
return null; return <></>;
} }
const leftOffset = ((spanData.startTime - globalStart) * 100) / spread; const leftOffset = ((spanData.startTime - globalStart) * 100) / spread;

View File

@ -16,14 +16,14 @@ export const SpanItemContainer = styled.div<{
zIdx: number; zIdx: number;
}>` }>`
position: absolute; position: absolute;
top: ${(props) => props.topOffset}px; top: ${(props): string | number => props.topOffset}px;
left: ${(props) => props.leftOffset}%; left: ${(props): string | number => props.leftOffset}%;
width: ${(props) => props.width}%; width: ${(props): string | number => props.width}%;
height: ${SPAN_HEIGHT}px; height: ${SPAN_HEIGHT}px;
margin: ${SPAN_V_PADDING}px 0; margin: ${SPAN_V_PADDING}px 0;
background-color: ${({ spanColor }) => spanColor}; background-color: ${({ spanColor }): string | number => spanColor};
border-radius: ${SPAN_HEIGHT / 2}px; border-radius: ${SPAN_HEIGHT / 2}px;
z-index: ${(props) => props.zIdx}; z-index: ${(props): string | number => props.zIdx};
`; `;
/** /**
@ -34,5 +34,5 @@ export const TraceFlameGraphContainer = styled.div<{
}>` }>`
position: relative; position: relative;
width: 100%; width: 100%;
height: ${({ height }) => (height ? height : 120)}px; height: ${({ height }): string | number => (height ? height : 120)}px;
`; `;

View File

@ -1,26 +1,27 @@
import React, { useEffect } from 'react'; import React, { useCallback, useEffect } from 'react';
const useClickOutside = ( const useClickOutside = (
ref: React.RefObject<HTMLElement>, ref: React.RefObject<HTMLElement>,
callback: (e: HTMLElement) => void | null, callback: (e: HTMLElement) => void | null,
) => { ): void => {
const listener = (e: Event) => { const listener = useCallback(
const node = e?.target as HTMLElement; (e: Event) => {
const node = e?.target as HTMLElement;
if (ref.current && !ref.current.contains(node)) { if (ref.current && !ref.current.contains(node) && callback) {
if (callback) {
callback(node); callback(node);
} }
} },
}; [callback, ref],
);
useEffect(() => { useEffect(() => {
document.addEventListener('click', listener); document.addEventListener('click', listener);
return () => { return (): void => {
document.removeEventListener('click', listener); document.removeEventListener('click', listener);
}; };
}, [ref, callback]); }, [ref, callback, listener]);
}; };
export default useClickOutside; export default useClickOutside;

View File

@ -1,7 +1,7 @@
import { useMemo, useRef } from 'react';
import debounce from 'lodash-es/debounce'; import debounce from 'lodash-es/debounce';
import { useMemo, useRef } from 'react';
export interface DebouncedFunc<T extends (...args: any[]) => any> { export interface DebouncedFunc<T extends (...args: unknown[]) => unknown> {
(...args: Parameters<T>): ReturnType<T> | undefined; (...args: Parameters<T>): ReturnType<T> | undefined;
cancel(): void; cancel(): void;
@ -20,18 +20,17 @@ const defaultOptions: DebounceOptions = {
trailing: true, trailing: true,
}; };
const useDebouncedFn = <T extends (...args: any) => any>( const useDebouncedFn = <T extends (...args: Array<unknown>) => unknown>(
fn: T, fn: T,
wait: number = 100, wait = 100,
options: DebounceOptions = defaultOptions, options: DebounceOptions = defaultOptions,
dependencies?: ReadonlyArray<any>,
): DebouncedFunc<T> => { ): DebouncedFunc<T> => {
const fnRef = useRef(fn); const fnRef = useRef(fn);
fnRef.current = fn; fnRef.current = fn;
return useMemo( return useMemo(
() => debounce(((...args) => fnRef.current(...args)) as T, wait, options), () => debounce(((...args) => fnRef.current(...args)) as T, wait, options),
[...(dependencies || [])], [options, wait],
); );
}; };

View File

@ -6,7 +6,7 @@ export interface IUseThemeModeReturn {
isDarkMode: boolean; isDarkMode: boolean;
} }
const useThemeMode = () => { const useThemeMode = (): IUseThemeModeReturn => {
const { isDarkMode } = useSelector<AppState, AppReducer>((state) => state.app); const { isDarkMode } = useSelector<AppState, AppReducer>((state) => state.app);
return { isDarkMode }; return { isDarkMode };

View File

@ -1,7 +1,7 @@
import { useMemo } from 'react'; import { useMemo } from 'react';
import { useLocation } from 'react-router-dom'; import { useLocation } from 'react-router-dom';
function useUrlQuery() { function useUrlQuery(): URLSearchParams {
const { search } = useLocation(); const { search } = useLocation();
return useMemo(() => new URLSearchParams(search), [search]); return useMemo(() => new URLSearchParams(search), [search]);

View File

@ -1,4 +1,4 @@
import { span } from 'store/actions'; import { Span } from 'types/api/trace/getTraceItem';
export const colors = [ export const colors = [
'#2F80ED', '#2F80ED',
@ -21,7 +21,9 @@ const getRandomColor = (): string => {
return colors[index]; return colors[index];
}; };
export const spanServiceNameToColorMapping = (spans: span[]) => { export const spanServiceNameToColorMapping = (
spans: Span[],
): { [key: string]: string } => {
const serviceNameSet = new Set(); const serviceNameSet = new Set();
spans.forEach((spanItem) => { spans.forEach((spanItem) => {
serviceNameSet.add(spanItem[3]); serviceNameSet.add(spanItem[3]);

View File

@ -1,9 +1,7 @@
const getMinAgo = ({ minutes }: getMinAgoProps): Date => { const getMinAgo = ({ minutes }: getMinAgoProps): Date => {
const currentDate = new Date(); const currentDate = new Date();
const agoDate = new Date(currentDate.getTime() - minutes * 60000); return new Date(currentDate.getTime() - minutes * 60000);
return agoDate;
}; };
interface getMinAgoProps { interface getMinAgoProps {

View File

@ -12,7 +12,10 @@ interface GetStepInput {
/** /**
* Converts given timestamp to ms. * Converts given timestamp to ms.
*/ */
const convertToMs = (timestamp: number, inputFormat: DateInputFormatType) => { const convertToMs = (
timestamp: number,
inputFormat: DateInputFormatType,
): number => {
switch (inputFormat) { switch (inputFormat) {
case 's': case 's':
return timestamp * 1e3; return timestamp * 1e3;

View File

@ -1,7 +1,7 @@
const convertObjectIntoParams = ( const convertObjectIntoParams = (
props: Record<any, any>, props: Record<string, unknown>,
stringify = false, stringify = false,
) => { ): string => {
return Object.keys(props) return Object.keys(props)
.map( .map(
(e) => (e) =>

View File

@ -18,7 +18,7 @@ const SettingsPage = (): JSX.Element => {
route: ROUTES.SETTINGS, route: ROUTES.SETTINGS,
}, },
{ {
Component: () => { Component: (): JSX.Element => {
return <CreateAlertChannels />; return <CreateAlertChannels />;
}, },
name: 'Alert Channels', name: 'Alert Channels',

View File

@ -1,9 +1,9 @@
import AlertChannels from 'container/AllAlertChannels';
import GeneralSettings from 'container/GeneralSettings';
import React from 'react';
import RouteTab from 'components/RouteTab'; import RouteTab from 'components/RouteTab';
import ROUTES from 'constants/routes'; import ROUTES from 'constants/routes';
import AlertChannels from 'container/AllAlertChannels';
import GeneralSettings from 'container/GeneralSettings';
import history from 'lib/history'; import history from 'lib/history';
import React from 'react';
const AllAlertChannels = (): JSX.Element => { const AllAlertChannels = (): JSX.Element => {
const pathName = history.location.pathname; const pathName = history.location.pathname;

View File

@ -26,6 +26,9 @@ const CreateAlert = (): JSX.Element => {
}); });
const [notifications, Element] = notification.useNotification(); const [notifications, Element] = notification.useNotification();
const defaultError =
'Oops! Some issue occured in saving the alert please try again or contact support@signoz.io';
const onSaveHandler = useCallback(async () => { const onSaveHandler = useCallback(async () => {
try { try {
setNewAlertState((state) => ({ setNewAlertState((state) => ({
@ -65,24 +68,19 @@ const CreateAlert = (): JSX.Element => {
}, 3000); }, 3000);
} else { } else {
notifications.error({ notifications.error({
description: description: response.error || defaultError,
response.error ||
'Oops! Some issue occured in saving the alert please try again or contact support@signoz.io',
message: 'Error', message: 'Error',
}); });
setNewAlertState((state) => ({ setNewAlertState((state) => ({
...state, ...state,
loading: false, loading: false,
error: true, error: true,
errorMessage: errorMessage: response.error || defaultError,
response.error ||
'Oops! Some issue occured in saving the alert please try again or contact support@signoz.io',
})); }));
} }
} catch (error) { } catch (error) {
notifications.error({ notifications.error({
message: message: defaultError,
'Oops! Some issue occured in saving the alert please try again or contact support@signoz.io',
}); });
} }
}, [notifications]); }, [notifications]);

View File

@ -1,3 +1,4 @@
import getLocalStorageKey from 'api/browser/localstorage/get';
import Spinner from 'components/Spinner'; import Spinner from 'components/Spinner';
import { SKIP_ONBOARDING } from 'constants/onboarding'; import { SKIP_ONBOARDING } from 'constants/onboarding';
import MetricTable from 'container/MetricsTable'; import MetricTable from 'container/MetricsTable';
@ -10,7 +11,6 @@ import { AppState } from 'store/reducers';
import AppActions from 'types/actions'; import AppActions from 'types/actions';
import { GlobalReducer } from 'types/reducer/globalTime'; import { GlobalReducer } from 'types/reducer/globalTime';
import MetricReducer from 'types/reducer/metrics'; import MetricReducer from 'types/reducer/metrics';
import getLocalStorageKey from 'api/browser/localstorage/get';
const Metrics = ({ getService }: MetricsProps): JSX.Element => { const Metrics = ({ getService }: MetricsProps): JSX.Element => {
const { minTime, maxTime, loading, selectedTime } = useSelector< const { minTime, maxTime, loading, selectedTime } = useSelector<

View File

@ -1,9 +1,9 @@
import AlertChannels from 'container/AllAlertChannels';
import GeneralSettings from 'container/GeneralSettings';
import React from 'react';
import RouteTab from 'components/RouteTab'; import RouteTab from 'components/RouteTab';
import ROUTES from 'constants/routes'; import ROUTES from 'constants/routes';
import AlertChannels from 'container/AllAlertChannels';
import GeneralSettings from 'container/GeneralSettings';
import history from 'lib/history'; import history from 'lib/history';
import React from 'react';
const SettingsPage = (): JSX.Element => { const SettingsPage = (): JSX.Element => {
const pathName = history.location.pathname; const pathName = history.location.pathname;

View File

@ -1,20 +1,23 @@
import { import {
Button, Button,
Card,
Input, Input,
notification, notification,
Typography,
Switch,
Space, Space,
Card, Switch,
Typography,
} from 'antd'; } from 'antd';
import setLocalStorageKey from 'api/browser/localstorage/set';
import signup from 'api/user/signup'; import signup from 'api/user/signup';
import ROUTES from 'constants/routes'; import ROUTES from 'constants/routes';
import history from 'lib/history'; import history from 'lib/history';
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
import setLocalStorageKey from 'api/browser/localstorage/set';
import AppActions from 'types/actions'; import AppActions from 'types/actions';
const { Title } = Typography; const { Title } = Typography;
import setPreference from 'api/user/setPreference';
import { IS_LOGGED_IN } from 'constants/auth';
import { useDispatch } from 'react-redux';
import { Dispatch } from 'redux';
import { PayloadProps } from 'types/api/user/getUserPreference'; import { PayloadProps } from 'types/api/user/getUserPreference';
import { import {
@ -26,10 +29,6 @@ import {
Logo, Logo,
MarginTop, MarginTop,
} from './styles'; } from './styles';
import { IS_LOGGED_IN } from 'constants/auth';
import { useDispatch } from 'react-redux';
import { Dispatch } from 'redux';
import setPreference from 'api/user/setPreference';
const Signup = ({ version, userpref }: SignupProps): JSX.Element => { const Signup = ({ version, userpref }: SignupProps): JSX.Element => {
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
@ -52,7 +51,7 @@ const Signup = ({ version, userpref }: SignupProps): JSX.Element => {
const setState = ( const setState = (
value: string, value: string,
setFunction: React.Dispatch<React.SetStateAction<string>>, setFunction: React.Dispatch<React.SetStateAction<string>>,
) => { ): void => {
setFunction(value); setFunction(value);
}; };
@ -109,7 +108,7 @@ const Signup = ({ version, userpref }: SignupProps): JSX.Element => {
const onSwitchHandler = ( const onSwitchHandler = (
value: boolean, value: boolean,
setFunction: React.Dispatch<React.SetStateAction<boolean>>, setFunction: React.Dispatch<React.SetStateAction<boolean>>,
) => { ): void => {
setFunction(value); setFunction(value);
}; };

View File

@ -1,15 +1,15 @@
import useFetch from 'hooks/useFetch';
import React from 'react';
import SignUpComponent from './SignUp';
import getVersion from 'api/user/getVersion';
import { PayloadProps as VersionPayload } from 'types/api/user/getVersion';
import { PayloadProps as UserPrefPayload } from 'types/api/user/getUserPreference';
import Spinner from 'components/Spinner';
import { Typography } from 'antd'; import { Typography } from 'antd';
import getPreference from 'api/user/getPreference'; import getPreference from 'api/user/getPreference';
import getVersion from 'api/user/getVersion';
import Spinner from 'components/Spinner';
import useFetch from 'hooks/useFetch';
import React from 'react';
import { PayloadProps as UserPrefPayload } from 'types/api/user/getUserPreference';
import { PayloadProps as VersionPayload } from 'types/api/user/getVersion';
const SignUp = () => { import SignUpComponent from './SignUp';
const SignUp = (): JSX.Element => {
const versionResponse = useFetch<VersionPayload, undefined>(getVersion); const versionResponse = useFetch<VersionPayload, undefined>(getVersion);
const userPrefResponse = useFetch<UserPrefPayload, undefined>(getPreference); const userPrefResponse = useFetch<UserPrefPayload, undefined>(getPreference);

View File

@ -45,7 +45,7 @@ interface Props {
} }
export const MarginTop = styled.div<Props>` export const MarginTop = styled.div<Props>`
margin-top: ${({ marginTop }) => marginTop}; margin-top: ${({ marginTop = 0 }): number | string => marginTop};
`; `;
export const Logo = styled.img` export const Logo = styled.img`

View File

@ -23,10 +23,10 @@ import { GlobalReducer } from 'types/reducer/globalTime';
import { TraceReducer } from 'types/reducer/trace'; import { TraceReducer } from 'types/reducer/trace';
import { import {
ClearAllFilter,
Container, Container,
LeftContainer, LeftContainer,
RightContainer, RightContainer,
ClearAllFilter,
} from './styles'; } from './styles';
const Trace = ({ const Trace = ({

View File

@ -1,5 +1,5 @@
import styled from 'styled-components';
import { Button, Card } from 'antd'; import { Button, Card } from 'antd';
import styled from 'styled-components';
export const Container = styled.div` export const Container = styled.div`
display: flex; display: flex;

View File

@ -1,11 +1,11 @@
import React from 'react'; import { Typography } from 'antd';
import useFetch from 'hooks/useFetch';
import getTraceItem from 'api/trace/getTraceItem'; import getTraceItem from 'api/trace/getTraceItem';
import Spinner from 'components/Spinner';
import TraceDetailContainer from 'container/TraceDetail';
import useFetch from 'hooks/useFetch';
import React from 'react';
import { useParams } from 'react-router-dom'; import { useParams } from 'react-router-dom';
import { Props as TraceDetailProps } from 'types/api/trace/getTraceItem'; import { Props as TraceDetailProps } from 'types/api/trace/getTraceItem';
import Spinner from 'components/Spinner';
import { Typography } from 'antd';
import TraceDetailContainer from 'container/TraceDetail';
const TraceDetail = (): JSX.Element => { const TraceDetail = (): JSX.Element => {
const { id } = useParams<TraceDetailProps>(); const { id } = useParams<TraceDetailProps>();

View File

@ -6,10 +6,10 @@ import GetMaxMinTime from 'lib/getMaxMinTime';
import GetMinMax from 'lib/getMinMax'; import GetMinMax from 'lib/getMinMax';
import GetStartAndEndTime from 'lib/getStartAndEndTime'; import GetStartAndEndTime from 'lib/getStartAndEndTime';
import { Dispatch } from 'redux'; import { Dispatch } from 'redux';
import store from 'store';
import AppActions from 'types/actions'; import AppActions from 'types/actions';
import { Query } from 'types/api/dashboard/getAll'; import { Query } from 'types/api/dashboard/getAll';
import { GlobalReducer } from 'types/reducer/globalTime'; import { GlobalReducer } from 'types/reducer/globalTime';
import store from 'store';
export const GetQueryResults = ( export const GetQueryResults = (
props: GetQueryResultsProps, props: GetQueryResultsProps,

View File

@ -39,8 +39,6 @@ export const GetInitialData = (
globalTime.maxTime / 1000000, globalTime.maxTime / 1000000,
]); ]);
const step = 60;
const [ const [
// getDBOverViewResponse, // getDBOverViewResponse,
// getExternalAverageDurationResponse, // getExternalAverageDurationResponse,

View File

@ -1,25 +1,26 @@
import { notification } from 'antd';
import getFiltersApi from 'api/trace/getFilters';
import xor from 'lodash-es/xor';
import { Dispatch, Store } from 'redux'; import { Dispatch, Store } from 'redux';
import { AppState } from 'store/reducers'; import { AppState } from 'store/reducers';
import AppActions from 'types/actions'; import AppActions from 'types/actions';
import { GlobalReducer } from 'types/reducer/globalTime';
import getFiltersApi from 'api/trace/getFilters';
import {
parseSelectedFilter,
parseFilterToFetchData,
parseQueryIntoCurrent,
parseQueryIntoSelectedTags,
isTraceFilterEnum,
parseQueryIntoFilter,
parseIsSkippedSelection,
parseFilterExclude,
} from './util';
import { import {
UPDATE_ALL_FILTERS, UPDATE_ALL_FILTERS,
UPDATE_TRACE_FILTER_LOADING, UPDATE_TRACE_FILTER_LOADING,
} from 'types/actions/trace'; } from 'types/actions/trace';
import { GlobalReducer } from 'types/reducer/globalTime';
import { TraceFilterEnum, TraceReducer } from 'types/reducer/trace'; import { TraceFilterEnum, TraceReducer } from 'types/reducer/trace';
import { notification } from 'antd';
import xor from 'lodash-es/xor'; import {
isTraceFilterEnum,
parseFilterExclude,
parseFilterToFetchData,
parseIsSkippedSelection,
parseQueryIntoCurrent,
parseQueryIntoFilter,
parseQueryIntoSelectedTags,
parseSelectedFilter,
} from './util';
export const GetInitialTraceFilter = ( export const GetInitialTraceFilter = (
minTime: GlobalReducer['minTime'], minTime: GlobalReducer['minTime'],
@ -89,7 +90,7 @@ export const GetInitialTraceFilter = (
isFilterExclude: getIsFilterExcluded.currentValue, isFilterExclude: getIsFilterExcluded.currentValue,
}); });
let preSelectedFilter: Map<TraceFilterEnum, string[]> = new Map( const preSelectedFilter: Map<TraceFilterEnum, string[]> = new Map(
getSelectedFilter.currentValue, getSelectedFilter.currentValue,
); );

View File

@ -1,3 +1,5 @@
import { notification } from 'antd';
import getSpans from 'api/trace/getSpans';
import { Dispatch, Store } from 'redux'; import { Dispatch, Store } from 'redux';
import { AppState } from 'store/reducers'; import { AppState } from 'store/reducers';
import AppActions from 'types/actions'; import AppActions from 'types/actions';
@ -6,9 +8,7 @@ import {
UPDATE_TRACE_GRAPH_LOADING, UPDATE_TRACE_GRAPH_LOADING,
UPDATE_TRACE_GRAPH_SUCCESS, UPDATE_TRACE_GRAPH_SUCCESS,
} from 'types/actions/trace'; } from 'types/actions/trace';
import getSpans from 'api/trace/getSpans';
import { Props } from 'types/api/trace/getSpans'; import { Props } from 'types/api/trace/getSpans';
import { notification } from 'antd';
export const GetSpans = ( export const GetSpans = (
props: GetSpansProps, props: GetSpansProps,

View File

@ -1,4 +1,5 @@
import { TraceReducer } from 'types/reducer/trace'; import { TraceReducer } from 'types/reducer/trace';
import { ParsedUrl } from '../util'; import { ParsedUrl } from '../util';
export const parseQueryIntoCurrent = ( export const parseQueryIntoCurrent = (

View File

@ -1,4 +1,5 @@
import { TraceFilterEnum, TraceReducer } from 'types/reducer/trace'; import { TraceFilterEnum, TraceReducer } from 'types/reducer/trace';
import { isTraceFilterEnum, ParsedUrl } from '../util'; import { isTraceFilterEnum, ParsedUrl } from '../util';
export const parseQueryIntoFilter = ( export const parseQueryIntoFilter = (

View File

@ -1,4 +1,5 @@
import { TraceFilterEnum, TraceReducer } from 'types/reducer/trace'; import { TraceFilterEnum, TraceReducer } from 'types/reducer/trace';
import { ParsedUrl } from '../util'; import { ParsedUrl } from '../util';
export const parseFilterToFetchData = ( export const parseFilterToFetchData = (
@ -7,7 +8,7 @@ export const parseFilterToFetchData = (
): ParsedUrl<TraceFilterEnum[]> => { ): ParsedUrl<TraceFilterEnum[]> => {
const url = new URLSearchParams(query); const url = new URLSearchParams(query);
let filterToFetchData: TraceFilterEnum[] = []; const filterToFetchData: TraceFilterEnum[] = [];
const selected = url.get('filterToFetchData'); const selected = url.get('filterToFetchData');

View File

@ -1,8 +1,8 @@
export * from './current';
export * from './filter';
export * from './filterToFetchData';
export * from './isFilterExclude';
export * from './minMaxTime'; export * from './minMaxTime';
export * from './selectedFilter'; export * from './selectedFilter';
export * from './filterToFetchData';
export * from './selectedTags'; export * from './selectedTags';
export * from './filter';
export * from './skippedSelected'; export * from './skippedSelected';
export * from './current';
export * from './isFilterExclude';

View File

@ -1,4 +1,5 @@
import { TraceFilterEnum, TraceReducer } from 'types/reducer/trace'; import { TraceFilterEnum, TraceReducer } from 'types/reducer/trace';
import { isTraceFilterEnum, ParsedUrl } from '../util'; import { isTraceFilterEnum, ParsedUrl } from '../util';
export const parseFilterExclude = ( export const parseFilterExclude = (

View File

@ -1,4 +1,5 @@
import { TraceFilterEnum, TraceReducer } from 'types/reducer/trace'; import { TraceFilterEnum, TraceReducer } from 'types/reducer/trace';
import { isTraceFilterEnum, ParsedUrl } from '../util'; import { isTraceFilterEnum, ParsedUrl } from '../util';
export const parseSelectedFilter = ( export const parseSelectedFilter = (

View File

@ -1,4 +1,5 @@
import { TraceReducer } from 'types/reducer/trace'; import { TraceReducer } from 'types/reducer/trace';
import { ParsedUrl } from '../util'; import { ParsedUrl } from '../util';
export const parseQueryIntoSelectedTags = ( export const parseQueryIntoSelectedTags = (

View File

@ -2,6 +2,7 @@ import { Dispatch, Store } from 'redux';
import { AppState } from 'store/reducers'; import { AppState } from 'store/reducers';
import AppActions from 'types/actions'; import AppActions from 'types/actions';
import { TraceFilterEnum } from 'types/reducer/trace'; import { TraceFilterEnum } from 'types/reducer/trace';
import { updateURL } from './util'; import { updateURL } from './util';
export const SelectedTraceFilter = (props: { export const SelectedTraceFilter = (props: {

View File

@ -1,7 +1,7 @@
import { Dispatch } from 'redux'; import { Dispatch } from 'redux';
import AppActions from 'types/actions'; import AppActions from 'types/actions';
import { TraceReducer } from 'types/reducer/trace';
import { UPDATE_IS_TAG_ERROR } from 'types/actions/trace'; import { UPDATE_IS_TAG_ERROR } from 'types/actions/trace';
import { TraceReducer } from 'types/reducer/trace';
export const UpdateTagIsError = ( export const UpdateTagIsError = (
isTagModalError: TraceReducer['isTagModalError'], isTagModalError: TraceReducer['isTagModalError'],

View File

@ -1,7 +1,7 @@
import { Dispatch } from 'redux'; import { Dispatch } from 'redux';
import AppActions from 'types/actions'; import AppActions from 'types/actions';
import { TraceReducer } from 'types/reducer/trace';
import { UPDATE_TAG_MODAL_VISIBLITY } from 'types/actions/trace'; import { UPDATE_TAG_MODAL_VISIBLITY } from 'types/actions/trace';
import { TraceReducer } from 'types/reducer/trace';
export const UpdateTagVisiblity = ( export const UpdateTagVisiblity = (
isTagModalOpen: TraceReducer['isTagModalOpen'], isTagModalOpen: TraceReducer['isTagModalOpen'],

Some files were not shown because too many files have changed in this diff Show More