mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-08-08 11:09:29 +08:00
Merge branch 'develop' of github.com:SigNoz/signoz into pranshuchittora/feat/y-axis-unit-selection
This commit is contained in:
commit
17738a58a2
5
.github/workflows/e2e-k3s.yaml
vendored
5
.github/workflows/e2e-k3s.yaml
vendored
@ -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
|
||||||
|
|
||||||
|
@ -34,8 +34,10 @@ SigNoz helps developers monitor applications and troubleshoot problems in their
|
|||||||
|
|
||||||
|
|
||||||

|

|
||||||
|
<br />
|
||||||

|

|
||||||
|
<br />
|
||||||
|

|
||||||
|
|
||||||
<br /><br />
|
<br /><br />
|
||||||
|
|
||||||
|
@ -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 false;
|
return !resizeObserverLoopErrRe.test(err.message);
|
||||||
}
|
|
||||||
return true;
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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',
|
||||||
|
@ -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);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -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;
|
||||||
|
@ -17,8 +17,8 @@ import {
|
|||||||
ServicesTablePage,
|
ServicesTablePage,
|
||||||
SettingsPage,
|
SettingsPage,
|
||||||
SignupPage,
|
SignupPage,
|
||||||
TraceFilter,
|
|
||||||
TraceDetail,
|
TraceDetail,
|
||||||
|
TraceFilter,
|
||||||
UsageExplorerPage,
|
UsageExplorerPage,
|
||||||
} from './pageComponents';
|
} from './pageComponents';
|
||||||
|
|
||||||
|
@ -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,
|
||||||
|
@ -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 '';
|
||||||
}
|
}
|
||||||
|
@ -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,
|
||||||
|
@ -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,
|
||||||
|
@ -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;
|
||||||
|
@ -16,7 +16,8 @@ const Value = (props: ValueProps): JSX.Element => {
|
|||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
)};
|
);
|
||||||
|
};
|
||||||
|
|
||||||
interface ValueProps {
|
interface ValueProps {
|
||||||
fillColor: React.CSSProperties['color'];
|
fillColor: React.CSSProperties['color'];
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
});
|
});
|
||||||
|
@ -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>>;
|
||||||
|
@ -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';
|
||||||
|
@ -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(() => {
|
||||||
|
@ -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`
|
||||||
&&& {
|
&&& {
|
||||||
|
@ -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>
|
||||||
);
|
);
|
||||||
|
@ -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;
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
@ -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>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -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 = ({
|
||||||
|
@ -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)`
|
||||||
&&& {
|
&&& {
|
||||||
|
@ -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 />}
|
||||||
@ -144,7 +147,7 @@ const Trace = (props: TraceProps): JSX.Element => {
|
|||||||
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>
|
||||||
|
@ -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;
|
||||||
|
@ -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) {
|
||||||
|
@ -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,
|
||||||
|
@ -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';
|
||||||
|
@ -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';
|
||||||
|
@ -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 => {
|
||||||
|
@ -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`
|
||||||
&&& {
|
&&& {
|
||||||
|
@ -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 => {
|
||||||
|
@ -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';
|
||||||
|
@ -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} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 }) => (
|
||||||
|
@ -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[] = [
|
||||||
{
|
{
|
||||||
|
@ -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 = ({
|
||||||
|
@ -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' },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
||||||
|
@ -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,
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
@ -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)}${
|
||||||
|
@ -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 {
|
||||||
|
@ -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 => {
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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 {
|
||||||
|
@ -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([]);
|
||||||
}
|
}
|
||||||
|
@ -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(() => {
|
||||||
|
if (counter.current === 0) {
|
||||||
|
counter.current = 1;
|
||||||
onSearchHandler();
|
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);
|
||||||
|
|
||||||
|
@ -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>
|
||||||
|
@ -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)`
|
||||||
&&& {
|
&&& {
|
||||||
|
@ -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}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
|
@ -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%;
|
||||||
|
@ -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([]);
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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(
|
||||||
|
(value): JSX.Element => (
|
||||||
<Option value={value.key} key={value.key}>
|
<Option value={value.key} key={value.key}>
|
||||||
{value.displayValue}
|
{value.displayValue}
|
||||||
</Option>
|
</Option>
|
||||||
))}
|
),
|
||||||
|
)}
|
||||||
</SelectComponent>
|
</SelectComponent>
|
||||||
</Space>
|
</Space>
|
||||||
);
|
);
|
||||||
|
@ -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)`
|
||||||
|
@ -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
|
||||||
|
@ -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>
|
||||||
|
@ -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));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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 />);
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
`;
|
`;
|
||||||
|
@ -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(
|
||||||
|
(e: Event) => {
|
||||||
const node = e?.target as HTMLElement;
|
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;
|
||||||
|
@ -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],
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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 };
|
||||||
|
@ -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]);
|
||||||
|
@ -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]);
|
||||||
|
@ -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 {
|
||||||
|
@ -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;
|
||||||
|
@ -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) =>
|
||||||
|
@ -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',
|
||||||
|
@ -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;
|
||||||
|
@ -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]);
|
||||||
|
@ -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<
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
@ -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`
|
||||||
|
@ -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 = ({
|
||||||
|
@ -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;
|
||||||
|
@ -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>();
|
||||||
|
@ -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,
|
||||||
|
@ -39,8 +39,6 @@ export const GetInitialData = (
|
|||||||
globalTime.maxTime / 1000000,
|
globalTime.maxTime / 1000000,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const step = 60;
|
|
||||||
|
|
||||||
const [
|
const [
|
||||||
// getDBOverViewResponse,
|
// getDBOverViewResponse,
|
||||||
// getExternalAverageDurationResponse,
|
// getExternalAverageDurationResponse,
|
||||||
|
@ -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,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -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,
|
||||||
|
@ -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 = (
|
||||||
|
@ -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 = (
|
||||||
|
@ -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');
|
||||||
|
|
||||||
|
@ -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';
|
|
||||||
|
@ -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 = (
|
||||||
|
@ -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 = (
|
||||||
|
@ -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 = (
|
||||||
|
@ -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: {
|
||||||
|
@ -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'],
|
||||||
|
@ -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
Loading…
x
Reference in New Issue
Block a user