mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-08-13 16:49:02 +08:00
Merge branch 'develop' of github.com:SigNoz/signoz into pc/feat/shared-styles-for-styled-components
This commit is contained in:
commit
9404768f9d
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
|
||||||
|
|
||||||
|
25
.github/workflows/repo-stats.yml
vendored
Normal file
25
.github/workflows/repo-stats.yml
vendored
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
# Run this once per day, towards the end of the day for keeping the most
|
||||||
|
# recent data point most meaningful (hours are interpreted in UTC).
|
||||||
|
- cron: "0 8 * * *"
|
||||||
|
workflow_dispatch: # Allow for running this manually.
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
j1:
|
||||||
|
name: repostats
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: run-ghrs
|
||||||
|
uses: jgehrcke/github-repo-stats@v1.1.0
|
||||||
|
with:
|
||||||
|
# Define the stats repository (the repo to fetch
|
||||||
|
# stats for and to generate the report for).
|
||||||
|
# Remove the parameter when the stats repository
|
||||||
|
# and the data repository are the same.
|
||||||
|
repository: signoz/signoz
|
||||||
|
# Set a GitHub API token that can read the stats
|
||||||
|
# repository, and that can push to the data
|
||||||
|
# repository (which this workflow file lives in),
|
||||||
|
# to store data and the report files.
|
||||||
|
ghtoken: ${{ github.token }}
|
@ -21,6 +21,12 @@ Need to update [https://github.com/SigNoz/signoz/tree/main/frontend](https://git
|
|||||||
- comment out frontend service section at `deploy/docker/clickhouse-setup/docker-compose.yaml#L59`
|
- comment out frontend service section at `deploy/docker/clickhouse-setup/docker-compose.yaml#L59`
|
||||||
- run `cd deploy` to move to deploy directory
|
- run `cd deploy` to move to deploy directory
|
||||||
- Install signoz locally without the frontend
|
- Install signoz locally without the frontend
|
||||||
|
- Add below configuration to query-service section at `docker/clickhouse-setup/docker-compose.yaml#L36`
|
||||||
|
|
||||||
|
```docker
|
||||||
|
ports:
|
||||||
|
- "8080:8080"
|
||||||
|
```
|
||||||
- If you are using x86_64 processors (All Intel/AMD processors) run `sudo docker-compose -f docker/clickhouse-setup/docker-compose.yaml up -d`
|
- If you are using x86_64 processors (All Intel/AMD processors) run `sudo docker-compose -f docker/clickhouse-setup/docker-compose.yaml up -d`
|
||||||
- If you are on arm64 processors (Apple M1 Macbooks) run `sudo docker-compose -f docker/clickhouse-setup/docker-compose.arm.yaml up -d`
|
- If you are on arm64 processors (Apple M1 Macbooks) run `sudo docker-compose -f docker/clickhouse-setup/docker-compose.arm.yaml up -d`
|
||||||
- `cd ../frontend` and change baseURL to `http://localhost:8080` in file `src/constants/env.ts`
|
- `cd ../frontend` and change baseURL to `http://localhost:8080` in file `src/constants/env.ts`
|
||||||
@ -47,20 +53,32 @@ Need to update [https://github.com/SigNoz/signoz/tree/main/pkg/query-service](ht
|
|||||||
### To run ClickHouse setup (recommended for local development)
|
### To run ClickHouse setup (recommended for local development)
|
||||||
|
|
||||||
- git clone https://github.com/SigNoz/signoz.git
|
- git clone https://github.com/SigNoz/signoz.git
|
||||||
|
- run `cd signoz` to move to signoz directory
|
||||||
- run `sudo make dev-setup` to configure local setup to run query-service
|
- run `sudo make dev-setup` to configure local setup to run query-service
|
||||||
- comment out frontend service section at `docker/clickhouse-setup/docker-compose.yaml#L45`
|
- comment out frontend service section at `docker/clickhouse-setup/docker-compose.yaml#L45`
|
||||||
- comment out query-service section at `docker/clickhouse-setup/docker-compose.yaml#L28`
|
- comment out query-service section at `docker/clickhouse-setup/docker-compose.yaml#L28`
|
||||||
- add below configuration to clickhouse section at `docker/clickhouse-setup/docker-compose.yaml`
|
- add below configuration to clickhouse section at `docker/clickhouse-setup/docker-compose.yaml#L6`
|
||||||
```
|
```docker
|
||||||
expose:
|
expose:
|
||||||
- 9000
|
- 9000
|
||||||
ports:
|
ports:
|
||||||
- 9001:9000
|
- 9001:9000
|
||||||
```
|
```
|
||||||
|
|
||||||
|
- run `cd pkg/query-service/` to move to query-service directory
|
||||||
|
- Open ./constants/constants.go
|
||||||
|
- Replace ```const RELATIONAL_DATASOURCE_PATH = "/var/lib/signoz/signoz.db"``` \
|
||||||
|
with ```const RELATIONAL_DATASOURCE_PATH = "./signoz.db".```
|
||||||
|
|
||||||
- Install signoz locally without the frontend and query-service
|
- Install signoz locally without the frontend and query-service
|
||||||
- If you are using x86_64 processors (All Intel/AMD processors) run `sudo make run-x86`
|
- If you are using x86_64 processors (All Intel/AMD processors) run `sudo make run-x86`
|
||||||
- If you are on arm64 processors (Apple M1 Macbooks) run `sudo make run-arm`
|
- If you are on arm64 processors (Apple M1 Macbooks) run `sudo make run-arm`
|
||||||
|
|
||||||
|
#### Run locally
|
||||||
|
```console
|
||||||
|
ClickHouseUrl=tcp://localhost:9001 STORAGE=clickhouse go run main.go
|
||||||
|
```
|
||||||
|
|
||||||
> Notes for Maintainers/Contributors who will change Line Numbers of Frontend & Query-Section. Please Update Line Numbers in `./scripts/commentLinesForSetup.sh`
|
> Notes for Maintainers/Contributors who will change Line Numbers of Frontend & Query-Section. Please Update Line Numbers in `./scripts/commentLinesForSetup.sh`
|
||||||
|
|
||||||
**_Query Service should now be available at `http://localhost:8080`_**
|
**_Query Service should now be available at `http://localhost:8080`_**
|
||||||
@ -68,13 +86,13 @@ Need to update [https://github.com/SigNoz/signoz/tree/main/pkg/query-service](ht
|
|||||||
> If you want to see how, frontend plays with query service, you can run frontend also in you local env with the baseURL changed to `http://localhost:8080` in file `src/constants/env.ts` as the query-service is now running at port `8080`
|
> If you want to see how, frontend plays with query service, you can run frontend also in you local env with the baseURL changed to `http://localhost:8080` in file `src/constants/env.ts` as the query-service is now running at port `8080`
|
||||||
|
|
||||||
---
|
---
|
||||||
Instead of configuring a local setup, you can also use [Gitpod](https://www.gitpod.io/), a VSCode-based Web IDE.
|
<!-- Instead of configuring a local setup, you can also use [Gitpod](https://www.gitpod.io/), a VSCode-based Web IDE.
|
||||||
|
|
||||||
Click the button below. A workspace with all required environments will be created.
|
Click the button below. A workspace with all required environments will be created.
|
||||||
|
|
||||||
[](https://gitpod.io/#https://github.com/SigNoz/signoz)
|
[](https://gitpod.io/#https://github.com/SigNoz/signoz)
|
||||||
|
|
||||||
> To use it on your forked repo, edit the 'Open in Gitpod' button url to `https://gitpod.io/#https://github.com/<your-github-username>/signoz`
|
> To use it on your forked repo, edit the 'Open in Gitpod' button url to `https://gitpod.io/#https://github.com/<your-github-username>/signoz` -->
|
||||||
|
|
||||||
# Contribute to SigNoz Helm Chart
|
# Contribute to SigNoz Helm Chart
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<img alt="License" src="https://img.shields.io/badge/license-MIT-brightgreen"> </a>
|
<img alt="License" src="https://img.shields.io/badge/license-MIT-brightgreen"> </a>
|
||||||
<img alt="Downloads" src="https://img.shields.io/docker/pulls/signoz/frontend?label=Downloads"> </a>
|
<img alt="Downloads" src="https://img.shields.io/docker/pulls/signoz/query-service?label=Downloads"> </a>
|
||||||
<img alt="GitHub issues" src="https://img.shields.io/github/issues/signoz/signoz"> </a>
|
<img alt="GitHub issues" src="https://img.shields.io/github/issues/signoz/signoz"> </a>
|
||||||
<a href="https://twitter.com/intent/tweet?text=Monitor%20your%20applications%20and%20troubleshoot%20problems%20with%20SigNoz,%20an%20open-source%20alternative%20to%20DataDog,%20NewRelic.&url=https://signoz.io/&via=SigNozHQ&hashtags=opensource,signoz,observability">
|
<a href="https://twitter.com/intent/tweet?text=Monitor%20your%20applications%20and%20troubleshoot%20problems%20with%20SigNoz,%20an%20open-source%20alternative%20to%20DataDog,%20NewRelic.&url=https://signoz.io/&via=SigNozHQ&hashtags=opensource,signoz,observability">
|
||||||
<img alt="tweet" src="https://img.shields.io/twitter/url/http/shields.io.svg?style=social"> </a>
|
<img alt="tweet" src="https://img.shields.io/twitter/url/http/shields.io.svg?style=social"> </a>
|
||||||
@ -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
|
||||||
|
@ -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)`
|
||||||
&&& {
|
&&& {
|
||||||
|
@ -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 = ({
|
||||||
|
@ -17,7 +17,10 @@ import {
|
|||||||
SaveDashboard,
|
SaveDashboard,
|
||||||
SaveDashboardProps,
|
SaveDashboardProps,
|
||||||
} from 'store/actions/dashboard/saveDashboard';
|
} from 'store/actions/dashboard/saveDashboard';
|
||||||
import { UpdateQuery, UpdateQueryProps } from 'store/actions/dashboard/updateQuery';
|
import {
|
||||||
|
UpdateQuery,
|
||||||
|
UpdateQueryProps,
|
||||||
|
} from 'store/actions/dashboard/updateQuery';
|
||||||
import { AppState } from 'store/reducers';
|
import { AppState } from 'store/reducers';
|
||||||
import AppActions from 'types/actions';
|
import AppActions from 'types/actions';
|
||||||
import { GlobalTime } from 'types/actions/globalTime';
|
import { GlobalTime } from 'types/actions/globalTime';
|
||||||
@ -40,7 +43,7 @@ const NewWidget = ({
|
|||||||
applySettingsToPanel,
|
applySettingsToPanel,
|
||||||
saveSettingOfPanel,
|
saveSettingOfPanel,
|
||||||
getQueryResults,
|
getQueryResults,
|
||||||
updateQuery
|
updateQuery,
|
||||||
}: Props): JSX.Element => {
|
}: Props): JSX.Element => {
|
||||||
const { dashboards } = useSelector<AppState, DashboardReducer>(
|
const { dashboards } = useSelector<AppState, DashboardReducer>(
|
||||||
(state) => state.dashboards,
|
(state) => state.dashboards,
|
||||||
@ -128,9 +131,9 @@ const NewWidget = ({
|
|||||||
widgetId: selectedWidget?.id || '',
|
widgetId: selectedWidget?.id || '',
|
||||||
query: element.query || '',
|
query: element.query || '',
|
||||||
legend: element.legend || '',
|
legend: element.legend || '',
|
||||||
currentIndex: index
|
currentIndex: index,
|
||||||
|
});
|
||||||
});
|
});
|
||||||
})
|
|
||||||
|
|
||||||
applySettingsToPanel({
|
applySettingsToPanel({
|
||||||
description,
|
description,
|
||||||
@ -141,7 +144,7 @@ const NewWidget = ({
|
|||||||
title,
|
title,
|
||||||
widgetId: selectedWidget?.id || '',
|
widgetId: selectedWidget?.id || '',
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
const onClickDiscardHandler = useCallback(() => {
|
const onClickDiscardHandler = useCallback(() => {
|
||||||
push(generatePath(ROUTES.DASHBOARD, { dashboardId }));
|
push(generatePath(ROUTES.DASHBOARD, { dashboardId }));
|
||||||
@ -233,7 +236,7 @@ const mapDispatchToProps = (
|
|||||||
applySettingsToPanel: bindActionCreators(ApplySettingsToPanel, dispatch),
|
applySettingsToPanel: bindActionCreators(ApplySettingsToPanel, dispatch),
|
||||||
saveSettingOfPanel: bindActionCreators(SaveDashboard, dispatch),
|
saveSettingOfPanel: bindActionCreators(SaveDashboard, dispatch),
|
||||||
getQueryResults: bindActionCreators(GetQueryResults, dispatch),
|
getQueryResults: bindActionCreators(GetQueryResults, dispatch),
|
||||||
updateQuery: bindActionCreators(UpdateQuery, dispatch)
|
updateQuery: bindActionCreators(UpdateQuery, dispatch),
|
||||||
});
|
});
|
||||||
|
|
||||||
type Props = DispatchProps & NewWidgetProps;
|
type Props = DispatchProps & NewWidgetProps;
|
||||||
|
@ -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,33 +1,27 @@
|
|||||||
import { StyledDiv } from 'components/Styled';
|
import { StyledDiv } from 'components/Styled';
|
||||||
import { INTERVAL_UNITS } from 'container/TraceDetail/utils';
|
import { INTERVAL_UNITS } from 'container/TraceDetail/utils';
|
||||||
import useThemeMode from 'hooks/useThemeMode';
|
import useThemeMode from 'hooks/useThemeMode';
|
||||||
import React, { useMemo, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import { useMeasure } from 'react-use';
|
import { useMeasure } from 'react-use';
|
||||||
|
|
||||||
import { styles, Svg, TimelineInterval } from './styles';
|
import { styles, Svg, TimelineInterval } from './styles';
|
||||||
import { Interval } from './types';
|
import { Interval } from './types';
|
||||||
import { getIntervals, getIntervalSpread } 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): JSX.Element => {
|
}: TimelineProps): JSX.Element => {
|
||||||
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,
|
||||||
@ -41,7 +35,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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -55,7 +49,7 @@ const Timeline = ({
|
|||||||
intervalUnit,
|
intervalUnit,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
}, [traceMetaData, globalTraceMetadata]);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StyledDiv ref={ref} styledclass={[styles.timelineContainer]}>
|
<StyledDiv ref={ref} styledclass={[styles.timelineContainer]}>
|
||||||
@ -96,4 +90,11 @@ const Timeline = ({
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
interface TimelineProps {
|
||||||
|
traceMetaData: object;
|
||||||
|
globalTraceMetadata: object;
|
||||||
|
intervalUnit: object;
|
||||||
|
setIntervalUnit: any;
|
||||||
|
}
|
||||||
|
|
||||||
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,13 +1,13 @@
|
|||||||
import React, { useMemo } from 'react';
|
import { Typography } from 'antd';
|
||||||
|
|
||||||
import Graph from 'components/Graph';
|
import Graph from 'components/Graph';
|
||||||
|
import Spinner from 'components/Spinner';
|
||||||
|
import React, { useMemo } from 'react';
|
||||||
import { useSelector } from 'react-redux';
|
import { useSelector } from 'react-redux';
|
||||||
import { AppState } from 'store/reducers';
|
import { AppState } from 'store/reducers';
|
||||||
import { TraceReducer } from 'types/reducer/trace';
|
import { TraceReducer } from 'types/reducer/trace';
|
||||||
import Spinner from 'components/Spinner';
|
|
||||||
import { Container } from './styles';
|
|
||||||
import { Typography } from 'antd';
|
|
||||||
import { getChartData, getChartDataforGroupBy } from './config';
|
import { getChartData, getChartDataforGroupBy } from './config';
|
||||||
|
import { Container } from './styles';
|
||||||
|
|
||||||
const TraceGraph = () => {
|
const TraceGraph = () => {
|
||||||
const { spansGraph, selectedGroupBy } = useSelector<AppState, TraceReducer>(
|
const { spansGraph, selectedGroupBy } = useSelector<AppState, TraceReducer>(
|
||||||
|
@ -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
|
||||||
@ -74,11 +75,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)`
|
||||||
|
@ -32,6 +32,7 @@ const ErrorTag = ({ event }: ErrorTagProps): JSX.Element => {
|
|||||||
key={`${name}${JSON.stringify(attributeMap)}`}
|
key={`${name}${JSON.stringify(attributeMap)}`}
|
||||||
defaultActiveKey={[name || attributeMap.event]}
|
defaultActiveKey={[name || attributeMap.event]}
|
||||||
expandIconPosition="right"
|
expandIconPosition="right"
|
||||||
|
key={name}
|
||||||
>
|
>
|
||||||
<Panel
|
<Panel
|
||||||
header={name || attributeMap?.event}
|
header={name || attributeMap?.event}
|
||||||
|
@ -35,10 +35,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 || '');
|
||||||
|
|
||||||
@ -48,9 +48,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({
|
const [globalTraceMetadata] = useState<Record<string, number>>({
|
||||||
...traceMetaData,
|
...traceMetaData,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -67,10 +67,10 @@ const TraceDetail = ({ response }: TraceDetailProps): JSX.Element => {
|
|||||||
return getNodeById(activeSelectedId, treeData);
|
return getNodeById(activeSelectedId, treeData);
|
||||||
}, [activeSelectedId, treeData]);
|
}, [activeSelectedId, treeData]);
|
||||||
|
|
||||||
const onSearchHandler = (value: string): void => {
|
// 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) {
|
||||||
|
@ -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 />);
|
||||||
|
@ -6,6 +6,7 @@ import {
|
|||||||
import useThemeMode from 'hooks/useThemeMode';
|
import useThemeMode from 'hooks/useThemeMode';
|
||||||
import React, { useLayoutEffect, useMemo, useState } from 'react';
|
import React, { useLayoutEffect, useMemo, useState } from 'react';
|
||||||
import { pushDStree } from 'store/actions';
|
import { pushDStree } from 'store/actions';
|
||||||
|
import { ITraceTree } from 'types/api/trace/getTraceItem';
|
||||||
import { toFixed } from 'utils/toFixed';
|
import { toFixed } from 'utils/toFixed';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@ -14,6 +15,18 @@ import {
|
|||||||
TraceFlameGraphContainer,
|
TraceFlameGraphContainer,
|
||||||
} from './styles';
|
} 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
|
||||||
leftOffset = 0, // left offset in %
|
leftOffset = 0, // left offset in %
|
||||||
@ -24,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;
|
|
||||||
}): JSX.Element => {
|
|
||||||
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(() => {
|
||||||
@ -47,13 +50,13 @@ const SpanItem = ({
|
|||||||
) {
|
) {
|
||||||
setIsSelected(true);
|
setIsSelected(true);
|
||||||
}
|
}
|
||||||
}, [hoveredSpanId, selectedSpanId]);
|
}, [hoveredSpanId, selectedSpanId, isSelected, spanData]);
|
||||||
|
|
||||||
const handleHover = (hoverState: boolean): void => {
|
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 = (): void => {
|
const handleClick = (): void => {
|
||||||
@ -65,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}
|
||||||
@ -90,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;
|
||||||
}): null | JSX.Element => {
|
}): 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,
|
||||||
@ -119,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;
|
||||||
}): null | JSX.Element => {
|
}): 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'],
|
||||||
|
@ -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_SELECTED_TAGS } from 'types/actions/trace';
|
import { UPDATE_SELECTED_TAGS } from 'types/actions/trace';
|
||||||
|
import { TraceReducer } from 'types/reducer/trace';
|
||||||
|
|
||||||
export const UpdateSelectedTags = (
|
export const UpdateSelectedTags = (
|
||||||
selectedTags: TraceReducer['selectedTags'],
|
selectedTags: TraceReducer['selectedTags'],
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { TraceFilterEnum, TraceReducer } from 'types/reducer/trace';
|
|
||||||
import history from 'lib/history';
|
|
||||||
import { AllTraceFilterEnum } from 'container/Trace/Filters';
|
import { AllTraceFilterEnum } from 'container/Trace/Filters';
|
||||||
|
import history from 'lib/history';
|
||||||
import { PayloadProps as GetFilterPayload } from 'types/api/trace/getFilters';
|
import { PayloadProps as GetFilterPayload } from 'types/api/trace/getFilters';
|
||||||
|
import { TraceFilterEnum, TraceReducer } from 'types/reducer/trace';
|
||||||
export * from './parseFilter';
|
export * from './parseFilter';
|
||||||
export interface ParsedUrl<T> {
|
export interface ParsedUrl<T> {
|
||||||
currentValue: T;
|
currentValue: T;
|
||||||
@ -11,10 +11,7 @@ export interface ParsedUrl<T> {
|
|||||||
export function isTraceFilterEnum(
|
export function isTraceFilterEnum(
|
||||||
value: TraceFilterEnum | string,
|
value: TraceFilterEnum | string,
|
||||||
): value is TraceFilterEnum {
|
): value is TraceFilterEnum {
|
||||||
if (AllTraceFilterEnum.find((enums) => enums === value)) {
|
return AllTraceFilterEnum.find((enums) => enums === value) ? true : false;
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const updateURL = (
|
export const updateURL = (
|
||||||
@ -25,7 +22,7 @@ export const updateURL = (
|
|||||||
filter: TraceReducer['filter'],
|
filter: TraceReducer['filter'],
|
||||||
isFilterExclude: TraceReducer['isFilterExclude'],
|
isFilterExclude: TraceReducer['isFilterExclude'],
|
||||||
userSelectedFilter: TraceReducer['userSelectedFilter'],
|
userSelectedFilter: TraceReducer['userSelectedFilter'],
|
||||||
) => {
|
): void => {
|
||||||
const search = new URLSearchParams(location.search);
|
const search = new URLSearchParams(location.search);
|
||||||
const preResult: { key: string; value: string }[] = [];
|
const preResult: { key: string; value: string }[] = [];
|
||||||
|
|
||||||
|
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