Fix(FE): some eslint error are fixed (#382)

* chore(UI): @types/node version is updated and port sync finder is removed

* chore(UI): tsconfig is updated

* fix(bug) webpack config is updated

* fix(bug): some eslint error is now fixed

* chore(lock): yarn lock is fixed
This commit is contained in:
pal-sig 2021-11-22 12:26:20 +05:30 committed by GitHub
parent 73b5134971
commit 4dfbdd2d63
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
38 changed files with 153 additions and 1273 deletions

View File

@ -19,6 +19,8 @@
/**
* @type {Cypress.PluginConfig}
*/
module.exports = (on, config: Cypress.ConfigOptions): void => {};
module.exports = (): void => {
return undefined;
};
export {};

View File

@ -6,7 +6,7 @@
"noEmit": true,
// be explicit about types included
// to avoid clashing with Jest types
"types": ["cypress", "@testing-library/cypress"],
"types": ["cypress", "@testing-library/cypress", "node"],
"isolatedModules": false
},
"include": ["../node_modules/cypress", "./**/*.ts"]

View File

@ -18,13 +18,6 @@ export const ServiceMapPage = Loadable(
),
);
export const TraceDetailPage = Loadable(
() =>
import(
/* webpackChunkName: "TraceDetailPage" */ 'modules/Traces/TraceDetail'
),
);
export const TraceDetailPages = Loadable(
() => import(/* webpackChunkName: "TraceDetailPage" */ 'pages/TraceDetails'),
);

View File

@ -17,7 +17,6 @@ import {
ServicesTablePage,
SettingsPage,
SignupPage,
TraceDetailPage,
TraceDetailPages,
TraceGraphPage,
UsageExplorerPage,
@ -64,11 +63,6 @@ const routes: AppRoutes[] = [
exact: true,
component: InstrumentationPage,
},
{
path: ROUTES.TRACES,
exact: true,
component: TraceDetailPage,
},
{
path: ROUTES.ALL_DASHBOARD,
exact: true,

View File

@ -12,5 +12,5 @@ export const SpinerStyle = styled.div<Props>`
display: flex;
justify-content: center;
align-items: center;
height: ${({ height = '100vh' }) => height};
height: ${({ height = '100vh' }): number | string => height};
`;

View File

@ -2,7 +2,6 @@ const ROUTES = {
SIGN_UP: '/signup',
SERVICE_METRICS: '/application/:servicename',
SERVICE_MAP: '/service-map',
TRACES: '/traces',
TRACE: '/trace',
TRACE_GRAPH: '/traces/:id',
SETTINGS: '/settings',

View File

@ -1,5 +1,5 @@
import { Typography } from 'antd';
import { ChartData, ChartOptions } from 'chart.js';
import { ChartData } from 'chart.js';
import Graph, { graphOnClickHandler } from 'components/Graph';
import ValueGraph from 'components/ValueGraph';
import { GRAPH_TYPES } from 'container/NewDashboard/ComponentsSlider';

View File

@ -1,5 +1,5 @@
import { Button, Select as DefaultSelect } from 'antd';
import React, { useCallback, useEffect, useRef, useState } from 'react';
import React, { useCallback, useEffect, useState } from 'react';
import { getDefaultOption, getOptions, Time } from './config';
import { Container, Form, FormItem } from './styles';
@ -75,7 +75,7 @@ const DateTimeSelection = ({
false,
);
const { maxTime, minTime, selectedTime, loading } = useSelector<
const { maxTime, minTime, selectedTime } = useSelector<
AppState,
GlobalReducer
>((state) => state.globalTime);

View File

@ -56,7 +56,15 @@ const DescriptionOfDashboard = ({
} else {
toggleEditMode();
}
}, [isEditMode, updatedTitle, updatedTags, updatedDescription]);
}, [
isEditMode,
updatedTitle,
updatedTags,
updatedDescription,
selectedDashboard,
toggleEditMode,
updateDashboardTitleDescriptionTags,
]);
return (
<>

View File

@ -6,17 +6,16 @@ import { AppState } from 'store/reducers';
const { Option } = Select;
import { bindActionCreators } from 'redux';
import { ThunkDispatch } from 'redux-thunk';
import {
GetTraceVisualAggregates,
GetTraceVisualAggregatesProps,
} from 'store/actions/trace/getTraceVisualAgrregates';
import AppActions from 'types/actions';
import { TraceReducer } from 'types/reducer/trace';
import { aggregation_options, entity } from './config';
import { Card, CustomVisualizationsTitle, FormItem, Space } from './styles';
import TraceCustomGraph from './TraceCustomGraph';
import {
GetTraceVisualAggregates,
GetTraceVisualAggregatesProps,
} from 'store/actions/trace/getTraceVisualAgrregates';
const TraceCustomVisualisation = ({
getTraceVisualAggregates,

View File

@ -5,12 +5,7 @@ import { connect, useSelector } from 'react-redux';
import { bindActionCreators, Dispatch } from 'redux';
import { ThunkDispatch } from 'redux-thunk';
import { TagItem } from 'store/actions';
import {
UpdateSelectedLatency,
UpdateSelectedOperation,
UpdateSelectedService,
UpdateSelectedTags,
} from 'store/actions/trace';
import { UpdateSelectedTags } from 'store/actions/trace';
import {
UpdateSelectedData,
UpdateSelectedDataProps,

View File

@ -1,4 +1,4 @@
import { Button, Input, Typography, notification } from 'antd';
import { Button, Input, notification, Typography } from 'antd';
import { SelectValue } from 'antd/lib/select';
import React, { useCallback, useEffect, useState } from 'react';
import { connect, useSelector } from 'react-redux';
@ -237,7 +237,13 @@ const TraceList = ({
} ms`,
});
}
}, [selectedService, selectedOperation, selectedKind, selectedLatency]);
}, [
selectedService,
selectedOperation,
selectedKind,
selectedLatency,
form_basefilter,
]);
return (
<>

View File

@ -1,26 +1,26 @@
import React, { useState } from "react";
import { servicesItem } from "store/actions";
import { InfoCircleOutlined } from "@ant-design/icons";
import { Select } from "antd";
import styled from "styled-components";
import { InfoCircleOutlined } from '@ant-design/icons';
import { Select } from 'antd';
import React, { useState } from 'react';
import { servicesItem } from 'store/actions';
import styled from 'styled-components';
const { Option } = Select;
import { cloneDeep } from "lodash-es";
import { cloneDeep } from 'lodash-es';
const Container = styled.div`
margin-top: 12px;
display: flex;
.info {
display:flex;
font-family: Roboto;
margin-left: auto;
margin-right: 12px;
color: #4F4F4F;
font-size: 14px;
.anticon-info-circle {
margin-top: 22px;
margin-right: 18px;
}
}
margin-top: 12px;
display: flex;
.info {
display: flex;
font-family: Roboto;
margin-left: auto;
margin-right: 12px;
color: #4f4f4f;
font-size: 14px;
.anticon-info-circle {
margin-top: 22px;
margin-right: 18px;
}
}
`;
interface SelectServiceProps {
@ -30,17 +30,20 @@ interface SelectServiceProps {
}
const defaultOption = {
serviceName: "Default"
serviceName: 'Default',
};
const SelectService = (props: SelectServiceProps) => {
const [selectedVal, setSelectedVal] = useState<string>(defaultOption.serviceName);
const SelectService = (props: SelectServiceProps): JSX.Element => {
const [selectedVal, setSelectedVal] = useState<string>(
defaultOption.serviceName,
);
const { zoomToService, zoomToDefault } = props;
const services = cloneDeep(props.services);
services.unshift(defaultOption)
const handleSelect = (value: string) => {
if(value === defaultOption.serviceName){
zoomToDefault()
services.unshift(defaultOption);
const handleSelect = (value: string): void => {
if (value === defaultOption.serviceName) {
zoomToDefault();
} else {
zoomToService(value);
}
@ -49,7 +52,7 @@ const SelectService = (props: SelectServiceProps) => {
return (
<Container>
<Select
style={{ width: 270, marginBottom: "56px" }}
style={{ width: 270, marginBottom: '56px' }}
placeholder="Select a service"
onChange={handleSelect}
value={selectedVal}
@ -60,14 +63,16 @@ const SelectService = (props: SelectServiceProps) => {
</Option>
))}
</Select>
<div className='info'>
<InfoCircleOutlined />
<div>
<div>-> Size of circles is proportial to the number of requests served by each node </div>
<div>-> Click on node name to reposition the node</div>
</div>
</div>
<div className="info">
<InfoCircleOutlined />
<div>
<div>
&gt; Size of circles is proportial to the number of requests served by
each node
</div>
<div>&gt; Click on node name to reposition the node</div>
</div>
</div>
</Container>
);
};

View File

@ -34,8 +34,8 @@ const Container = styled.div`
interface ServiceMapProps extends RouteComponentProps<any> {
serviceMap: serviceMapStore;
globalTime: GlobalTime;
getServiceMapItems: Function;
getDetailedServiceMapItems: Function;
getServiceMapItems: (time: GlobalTime) => void;
getDetailedServiceMapItems: (time: GlobalTime) => void;
}
interface graphNode {
id: string;
@ -51,7 +51,7 @@ export interface graphDataType {
links: graphLink[];
}
const ServiceMap = (props: ServiceMapProps) => {
const ServiceMap = (props: ServiceMapProps): JSX.Element => {
const fgRef = useRef();
const {
@ -68,7 +68,7 @@ const ServiceMap = (props: ServiceMapProps) => {
*/
getServiceMapItems(globalTime);
getDetailedServiceMapItems(globalTime);
}, [globalTime]);
}, [globalTime, getServiceMapItems, getDetailedServiceMapItems]);
useEffect(() => {
fgRef.current && fgRef.current.d3Force('charge').strength(-400);
@ -77,12 +77,14 @@ const ServiceMap = (props: ServiceMapProps) => {
return <Spinner size="large" tip="Loading..." />;
}
const zoomToService = (value: string) => {
fgRef && fgRef.current.zoomToFit(700, getZoomPx(), (e) => e.id === value);
const zoomToService = (value: string): void => {
fgRef &&
fgRef.current &&
fgRef.current.zoomToFit(700, getZoomPx(), (e) => e.id === value);
};
const zoomToDefault = () => {
fgRef && fgRef.current.zoomToFit(100, 120);
fgRef && fgRef.current && fgRef.current.zoomToFit(100, 120);
};
const { nodes, links } = getGraphData(serviceMap);

View File

@ -1,94 +0,0 @@
import { Col, Form, InputNumber, Modal, Row } from 'antd';
import { NamePath, Store } from 'antd/lib/form/interface';
import React from 'react';
interface LatencyModalFormProps {
onCreate: (values: Store) => void; //Store is defined in antd forms library
onCancel: () => void;
latencyFilterValues: { min: string; max: string };
}
const LatencyModalForm: React.FC<LatencyModalFormProps> = ({
onCreate,
onCancel,
latencyFilterValues,
}) => {
const [form] = Form.useForm();
const validateMinValue = ({
getFieldValue,
}: {
getFieldValue: (name: NamePath) => any;
}) => ({
validator(_, value: any) {
if (value < getFieldValue('max')) {
return Promise.resolve();
}
return Promise.reject(new Error('Min value should be less than Max value'));
},
});
const validateMaxValue = ({
getFieldValue,
}: {
getFieldValue: (name: NamePath) => any;
}) => ({
validator(_, value: any) {
if (value > getFieldValue('min')) {
return Promise.resolve();
}
return Promise.reject(
new Error('Max value should be greater than Min value'),
);
},
});
return (
<Modal
visible={true}
title="Chose min and max values of Latency"
okText="Apply"
cancelText="Cancel"
onCancel={onCancel}
onOk={() => {
form
.validateFields()
.then((values) => {
form.resetFields();
onCreate(values); // giving error for values
})
.catch((info) => {
// console.log('Validate Failed:', info);
});
}}
>
<Form
form={form}
layout="horizontal"
name="form_in_modal"
initialValues={latencyFilterValues}
>
<Row>
<Col span={12}>
<Form.Item
name="min"
label="Min (in ms)"
rules={[validateMinValue]}
// rules={[{ required: true, message: 'Please input the title of collection!' }]}
>
<InputNumber />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item name="max" label="Max (in ms)" rules={[validateMaxValue]}>
<InputNumber />
</Form.Item>
</Col>
</Row>
{/* </Input.Group> */}
</Form>
</Modal>
);
};
export default LatencyModalForm;

View File

@ -54,7 +54,7 @@ const CardContainer = styled(Card)`
}
`;
const SelectedSpanDetails = (props: SelectedSpanDetailsProps) => {
const SelectedSpanDetails = (props: SelectedSpanDetailsProps): JSX.Element => {
const spanTags = props.data?.tags;
const service = props.data?.name?.split(':')[0];
const operation = props.data?.name?.split(':')[1];

View File

@ -1,272 +0,0 @@
import { Form, Select, Space } from 'antd';
import Graph from 'components/Graph';
import React, { useEffect, useState } from 'react';
import { connect, useSelector } from 'react-redux';
import { TraceFilters } from 'store/actions';
import { getFilteredTraceMetrics } from 'store/actions/MetricsActions';
import { customMetricsItem } from 'store/actions/MetricsActions';
import { AppState } from 'store/reducers';
const { Option } = Select;
import { colors } from 'lib/getRandomColor';
import { GlobalTime } from 'types/actions/globalTime';
import { GlobalReducer } from 'types/reducer/globalTime';
import {
Card,
CustomGraphContainer,
CustomVisualizationsTitle,
} from './styles';
const entity = [
{
title: 'Calls',
key: 'calls',
dataindex: 'calls',
},
{
title: 'Duration',
key: 'duration',
dataindex: 'duration',
},
{
title: 'Error',
key: 'error',
dataindex: 'error',
},
{
title: 'Status Code',
key: 'status_code',
dataindex: 'status_code',
},
];
const aggregation_options = [
{
linked_entity: 'calls',
default_selected: { title: 'Count', dataindex: 'count' },
options_available: [
{ title: 'Count', dataindex: 'count' },
{ title: 'Rate (per sec)', dataindex: 'rate_per_sec' },
],
},
{
linked_entity: 'duration',
default_selected: { title: 'p99', dataindex: 'p99' },
// options_available: [ {title:'Avg', dataindex:'avg'}, {title:'Max', dataindex:'max'},{title:'Min', dataindex:'min'}, {title:'p50', dataindex:'p50'},{title:'p95', dataindex:'p95'}, {title:'p95', dataindex:'p95'}]
options_available: [
{ title: 'p50', dataindex: 'p50' },
{ title: 'p95', dataindex: 'p95' },
{ title: 'p99', dataindex: 'p99' },
],
},
{
linked_entity: 'error',
default_selected: { title: 'Count', dataindex: 'count' },
options_available: [
{ title: 'Count', dataindex: 'count' },
{ title: 'Rate (per sec)', dataindex: 'rate_per_sec' },
],
},
{
linked_entity: 'status_code',
default_selected: { title: 'Count', dataindex: 'count' },
options_available: [{ title: 'Count', dataindex: 'count' }],
},
];
interface TraceCustomVisualizationsProps {
filteredTraceMetrics: customMetricsItem[];
globalTime: GlobalTime;
getFilteredTraceMetrics: (value: string, time: GlobalTime) => void;
traceFilters: TraceFilters;
}
const _TraceCustomVisualizations = (
props: TraceCustomVisualizationsProps,
): JSX.Element => {
const [selectedEntity, setSelectedEntity] = useState('calls');
const [selectedAggOption, setSelectedAggOption] = useState('count');
const [form] = Form.useForm();
const selectedStep = '60';
const {
filteredTraceMetrics,
getFilteredTraceMetrics,
globalTime,
traceFilters,
} = props;
const { loading } = useSelector<AppState, GlobalReducer>(
(state) => state.globalTime,
);
// Step should be multiples of 60, 60 -> 1 min
useEffect(() => {
let request_string =
'service=' +
traceFilters.service +
'&operation=' +
traceFilters.operation +
'&maxDuration=' +
traceFilters.latency?.max +
'&minDuration=' +
traceFilters.latency?.min +
'&kind=' +
traceFilters.kind;
if (traceFilters.tags)
request_string =
request_string +
'&tags=' +
encodeURIComponent(JSON.stringify(traceFilters.tags));
if (selectedEntity)
request_string =
request_string + '&dimension=' + selectedEntity.toLowerCase();
if (selectedAggOption)
request_string =
request_string + '&aggregation_option=' + selectedAggOption.toLowerCase();
if (selectedStep) request_string = request_string + '&step=' + selectedStep;
const plusMinus15 = {
minTime: globalTime.minTime - 15 * 60 * 1000000000,
maxTime: globalTime.maxTime + 15 * 60 * 1000000000,
};
/*
Call the apis only when the route is loaded.
Check this issue: https://github.com/SigNoz/signoz/issues/110
*/
if (loading === false) {
getFilteredTraceMetrics(request_string, plusMinus15);
}
}, [
selectedEntity,
selectedAggOption,
traceFilters,
getFilteredTraceMetrics,
globalTime,
loading,
]);
//Custom metrics API called if time, tracefilters, selected entity or agg option changes
// PNOTE - Can also use 'coordinate' option in antd Select for implementing this - https://ant.design/components/select/
const handleFormValuesChange = (changedValues: any): void => {
const formFieldName = Object.keys(changedValues)[0];
if (formFieldName === 'entity') {
const temp_entity = aggregation_options.filter(
(item) => item.linked_entity === changedValues[formFieldName],
)[0];
form.setFieldsValue({
agg_options: temp_entity.default_selected.title,
// PNOTE - TO DO Check if this has the same behaviour as selecting an option?
});
const temp = form.getFieldsValue(['agg_options', 'entity']);
setSelectedEntity(temp.entity);
setSelectedAggOption(temp.agg_options);
//form.setFieldsValue({ agg_options: aggregation_options.filter( item => item.linked_entity === selectedEntity )[0] }); //reset product selection
// PNOTE - https://stackoverflow.com/questions/64377293/update-select-option-list-based-on-other-select-field-selection-ant-design
}
if (formFieldName === 'agg_options') {
setSelectedAggOption(changedValues[formFieldName]);
}
};
return (
<Card>
<CustomVisualizationsTitle>Custom Visualizations</CustomVisualizationsTitle>
<Form
form={form}
onValuesChange={handleFormValuesChange}
initialValues={{
agg_options: 'Count',
chart_style: 'line',
interval: '5m',
group_by: 'none',
}}
>
<Space>
<Form.Item name="entity">
<Select defaultValue={selectedEntity} style={{ width: 120 }} allowClear>
{entity.map((item) => (
<Option key={item.key} value={item.dataindex}>
{item.title}
</Option>
))}
</Select>
</Form.Item>
<Form.Item name="agg_options">
<Select style={{ width: 120 }} allowClear>
{aggregation_options
.filter((item) => item.linked_entity === selectedEntity)[0]
.options_available.map((item) => (
<Option key={item.dataindex} value={item.dataindex}>
{item.title}
</Option>
))}
</Select>
</Form.Item>
<Form.Item name="chart_style">
<Select style={{ width: 120 }} allowClear>
<Option value="line">Line Chart</Option>
<Option value="bar">Bar Chart</Option>
<Option value="area">Area Chart</Option>
</Select>
</Form.Item>
<Form.Item name="interval">
<Select style={{ width: 120 }} allowClear>
<Option value="1m">1 min</Option>
<Option value="5m">5 min</Option>
<Option value="30m">30 min</Option>
</Select>
</Form.Item>
{/* Need heading for each option */}
<Form.Item name="group_by">
<Select style={{ width: 120 }} allowClear>
<Option value="none">Group By</Option>
<Option value="status">Status Code</Option>
<Option value="protocol">Protocol</Option>
</Select>
</Form.Item>
</Space>
</Form>
<CustomGraphContainer>
<Graph
type="line"
data={{
labels: filteredTraceMetrics.map((s) => new Date(s.timestamp / 1000000)),
datasets: [
{
data: filteredTraceMetrics.map((e) => e.value),
borderColor: colors[0],
},
],
}}
/>
</CustomGraphContainer>
</Card>
);
};
const mapStateToProps = (
state: AppState,
): {
filteredTraceMetrics: customMetricsItem[];
globalTime: GlobalTime;
traceFilters: TraceFilters;
} => {
return {
filteredTraceMetrics: state.metricsData.customMetricsItem,
globalTime: state.globalTime,
traceFilters: state.traceFilters,
};
};
export const TraceCustomVisualizations = connect(mapStateToProps, {
getFilteredTraceMetrics: getFilteredTraceMetrics,
})(_TraceCustomVisualizations);

View File

@ -1,17 +0,0 @@
import React from 'react';
import { TraceCustomVisualizations } from './TraceCustomVisualizations';
import { TraceFilter } from './TraceFilter';
import { TraceList } from './TraceList';
const TraceDetail = (): JSX.Element => {
return (
<>
<TraceFilter />
<TraceCustomVisualizations />
<TraceList />
</>
);
};
export default TraceDetail;

View File

@ -1,487 +0,0 @@
import { AutoComplete, Button, Form, Input, Select, Typography } from 'antd';
import FormItem from 'antd/lib/form/FormItem';
import { Store } from 'antd/lib/form/interface';
import api from 'api';
import { METRICS_PAGE_QUERY_PARAM } from 'constants/query';
import React, {
useCallback,
useEffect,
useMemo,
useRef,
useState,
} from 'react';
import { connect, useSelector } from 'react-redux';
import { useLocation } from 'react-router-dom';
import { fetchTraces, TraceFilters, updateTraceFilters } from 'store/actions';
import { AppState } from 'store/reducers';
import styled from 'styled-components';
import { GlobalTime } from 'types/actions/globalTime';
import { GlobalReducer } from 'types/reducer/globalTime';
import { FilterStateDisplay } from './FilterStateDisplay';
import LatencyModalForm from './LatencyModalForm';
const { Option } = Select;
const InfoWrapper = styled.div`
padding-top: 10px;
font-style: italic;
font-size: 12px;
`;
interface TraceFilterProps {
traceFilters: TraceFilters;
globalTime: GlobalTime;
updateTraceFilters: (props: TraceFilters) => void;
fetchTraces: (globalTime: GlobalTime, filter_params: string) => void;
}
interface TagKeyOptionItem {
tagKeys: string;
tagCount: number;
}
interface ISpanKind {
label: 'SERVER' | 'CLIENT';
value: string;
}
const _TraceFilter = (props: TraceFilterProps): JSX.Element => {
const [serviceList, setServiceList] = useState<string[]>([]);
const [operationList, setOperationsList] = useState<string[]>([]);
const [tagKeyOptions, setTagKeyOptions] = useState<TagKeyOptionItem[]>([]);
const location = useLocation();
const urlParams = useMemo(() => {
return new URLSearchParams(location.search.split('?')[1]);
}, [location.search]);
const { loading } = useSelector<AppState, GlobalReducer>(
(state) => state.globalTime,
);
const { updateTraceFilters, traceFilters, globalTime, fetchTraces } = props;
const [modalVisible, setModalVisible] = useState(false);
const [latencyFilterValues, setLatencyFilterValues] = useState<{
min: string;
max: string;
}>({
min: '100',
max: '500',
});
const [form] = Form.useForm();
const [form_basefilter] = Form.useForm();
const handleChangeOperation = useCallback(
(value: string) => {
updateTraceFilters({ ...traceFilters, operation: value });
},
[traceFilters, updateTraceFilters],
);
const populateData = useCallback(
(value: string) => {
if (loading === false) {
const service_request = '/service/' + value + '/operations';
api.get<string[]>(service_request).then((response) => {
// form_basefilter.resetFields(['operation',])
setOperationsList(response.data);
});
const tagkeyoptions_request = '/tags?service=' + value;
api.get<TagKeyOptionItem[]>(tagkeyoptions_request).then((response) => {
setTagKeyOptions(response.data);
});
}
},
[loading],
);
const handleChangeService = useCallback(
(value: string) => {
populateData(value);
updateTraceFilters({ ...traceFilters, service: value });
},
[traceFilters, updateTraceFilters, populateData],
);
const spanKindList: ISpanKind[] = [
{
label: 'SERVER',
value: '2',
},
{
label: 'CLIENT',
value: '3',
},
];
const handleApplyFilterForm = useCallback(
(values: any): void => {
updateTraceFilters({
service: values.service,
operation: values.operation,
latency: {
max: '',
min: '',
},
kind: values.kind,
});
},
[updateTraceFilters],
);
useEffect(() => {
handleApplyFilterForm({
service: '',
tags: [],
operation: '',
latency: { min: '', max: '' },
kind: '',
});
}, [handleApplyFilterForm]);
const onTagFormSubmit = useCallback(
(values) => {
if (traceFilters.tags) {
// If there are existing tag filters present
updateTraceFilters({
service: traceFilters.service,
operation: traceFilters.operation,
latency: traceFilters.latency,
tags: [
...traceFilters.tags,
{
key: values.tag_key,
value: values.tag_value,
operator: values.operator,
},
],
kind: traceFilters.kind,
});
} else {
updateTraceFilters({
service: traceFilters.service,
operation: traceFilters.operation,
latency: traceFilters.latency,
tags: [
{
key: values.tag_key,
value: values.tag_value,
operator: values.operator,
},
],
kind: traceFilters.kind,
});
}
form.resetFields();
},
[form, traceFilters, updateTraceFilters],
);
const counter = useRef(0);
useEffect(() => {
if (loading === false && counter.current === 0) {
counter.current = 1;
api
.get<string[]>(`/services/list`)
.then((response) => {
setServiceList(response.data);
})
.then(() => {
const operationName = urlParams.get(METRICS_PAGE_QUERY_PARAM.operation);
const serviceName = urlParams.get(METRICS_PAGE_QUERY_PARAM.service);
const errorTag = urlParams.get(METRICS_PAGE_QUERY_PARAM.error);
if (operationName && serviceName) {
updateTraceFilters({
...traceFilters,
operation: operationName,
service: serviceName,
kind: '',
});
populateData(serviceName);
} else if (serviceName && errorTag) {
updateTraceFilters({
...traceFilters,
service: serviceName,
tags: [
{
key: METRICS_PAGE_QUERY_PARAM.error,
value: errorTag,
operator: 'equals',
},
],
kind: '',
});
} else {
if (operationName) {
handleChangeOperation(operationName);
}
if (serviceName) {
handleChangeService(serviceName);
}
if (errorTag) {
onTagFormSubmit({
tag_key: METRICS_PAGE_QUERY_PARAM.error,
tag_value: errorTag,
operator: 'equals',
});
}
}
});
}
}, [
handleChangeOperation,
onTagFormSubmit,
handleChangeService,
traceFilters,
urlParams,
updateTraceFilters,
populateData,
loading,
]);
useEffect(() => {
let request_string =
'service=' +
traceFilters.service +
'&operation=' +
traceFilters.operation +
'&maxDuration=' +
traceFilters.latency?.max +
'&minDuration=' +
traceFilters.latency?.min +
'&kind=' +
traceFilters.kind;
if (traceFilters.tags)
request_string =
request_string +
'&tags=' +
encodeURIComponent(JSON.stringify(traceFilters.tags));
if (loading === false) {
fetchTraces(globalTime, request_string);
}
}, [traceFilters, fetchTraces, loading, globalTime]);
useEffect(() => {
let latencyButtonText = 'Latency';
if (traceFilters.latency?.min === '' && traceFilters.latency?.max !== '')
latencyButtonText =
'Latency<' +
(parseInt(traceFilters.latency?.max) / 1000000).toString() +
'ms';
else if (traceFilters.latency?.min !== '' && traceFilters.latency?.max === '')
latencyButtonText =
'Latency>' +
(parseInt(traceFilters.latency?.min) / 1000000).toString() +
'ms';
else if (
traceFilters.latency !== undefined &&
traceFilters.latency?.min !== '' &&
traceFilters.latency?.max !== ''
)
latencyButtonText =
(parseInt(traceFilters.latency.min) / 1000000).toString() +
'ms <Latency<' +
(parseInt(traceFilters.latency.max) / 1000000).toString() +
'ms';
form_basefilter.setFieldsValue({ latency: latencyButtonText });
form_basefilter.setFieldsValue({ service: traceFilters.service });
form_basefilter.setFieldsValue({ operation: traceFilters.operation });
form_basefilter.setFieldsValue({ kind: traceFilters.kind });
}, [traceFilters, form_basefilter]);
const onLatencyButtonClick = (): void => {
setModalVisible(true);
};
const onLatencyModalApply = (values: Store): void => {
setModalVisible(false);
const { min, max } = values;
updateTraceFilters({
...traceFilters,
latency: {
min: min ? (parseInt(min) * 1000000).toString() : '',
max: max ? (parseInt(max) * 1000000).toString() : '',
},
});
setLatencyFilterValues({ min, max });
};
// For autocomplete
//Setting value when autocomplete field is changed
const onChangeTagKey = (data: string): void => {
form.setFieldsValue({ tag_key: data });
};
const dataSource = ['status:200'];
const children = [];
for (let i = 0; i < dataSource.length; i++) {
children.push(
<Option value={dataSource[i]} key={dataSource[i]}>
{dataSource[i]}
</Option>,
);
}
useEffect(() => {
return (): void => {
updateTraceFilters({
service: '',
operation: '',
tags: [],
latency: { min: '', max: '' },
kind: '',
});
};
}, [updateTraceFilters]);
const handleChangeSpanKind = (value = ''): void => {
updateTraceFilters({ ...traceFilters, kind: value });
};
return (
<div>
<Typography>Filter Traces</Typography>
<Form
form={form_basefilter}
layout="inline"
onFinish={handleApplyFilterForm}
initialValues={{ service: '', operation: '', latency: 'Latency' }}
style={{ marginTop: 10, marginBottom: 10 }}
>
<FormItem rules={[{ required: true }]} name="service">
<Select
showSearch
style={{ width: 180 }}
onChange={handleChangeService}
placeholder="Select Service"
allowClear
>
{serviceList.map((s) => (
<Option key={s} value={s}>
{s}
</Option>
))}
</Select>
</FormItem>
<FormItem name="operation">
<Select
showSearch
style={{ width: 180 }}
onChange={handleChangeOperation}
placeholder="Select Operation"
allowClear
>
{operationList.map((item) => (
<Option key={item} value={item}>
{item}
</Option>
))}
</Select>
</FormItem>
<FormItem name="latency">
<Input
style={{ width: 200 }}
type="button"
onClick={onLatencyButtonClick}
/>
</FormItem>
<FormItem name="spanKind">
<Select
showSearch
style={{ width: 180 }}
onChange={handleChangeSpanKind}
placeholder="Select Span Kind"
allowClear
>
{spanKindList.map((spanKind) => (
<Option value={spanKind.value} key={spanKind.value}>
{spanKind.label}
</Option>
))}
</Select>
</FormItem>
</Form>
<FilterStateDisplay />
<InfoWrapper>Select Service to get Tag suggestions </InfoWrapper>
<Form
form={form}
layout="inline"
onFinish={onTagFormSubmit}
initialValues={{ operator: 'equals' }}
style={{ marginTop: 10, marginBottom: 10 }}
>
<FormItem rules={[{ required: true }]} name="tag_key">
<AutoComplete
options={tagKeyOptions.map((s) => {
return { value: s.tagKeys };
})}
style={{ width: 200, textAlign: 'center' }}
onChange={onChangeTagKey}
filterOption={(inputValue, option): boolean =>
option?.value.toUpperCase().indexOf(inputValue.toUpperCase()) !== -1
}
placeholder="Tag Key"
/>
</FormItem>
<FormItem name="operator">
<Select style={{ width: 120, textAlign: 'center' }}>
<Option value="equals">EQUAL</Option>
<Option value="contains">CONTAINS</Option>
<Option value="regex">REGEX</Option>
</Select>
</FormItem>
<FormItem rules={[{ required: true }]} name="tag_value">
<Input
style={{ width: 160, textAlign: 'center' }}
placeholder="Tag Value"
/>
</FormItem>
<FormItem>
<Button type="primary" htmlType="submit">
{' '}
Apply Tag Filter{' '}
</Button>
</FormItem>
</Form>
{modalVisible && (
<LatencyModalForm
onCreate={onLatencyModalApply}
latencyFilterValues={latencyFilterValues}
onCancel={(): void => {
setModalVisible(false);
}}
/>
)}
</div>
);
};
const mapStateToProps = (
state: AppState,
): { traceFilters: TraceFilters; globalTime: GlobalTime } => {
return { traceFilters: state.traceFilters, globalTime: state.globalTime };
};
export const TraceFilter = connect(mapStateToProps, {
updateTraceFilters: updateTraceFilters,
fetchTraces: fetchTraces,
})(_TraceFilter);

View File

@ -1,160 +0,0 @@
import { Space, Table } from 'antd';
import ROUTES from 'constants/routes';
import moment from 'moment';
import React, { useEffect } from 'react';
import { connect } from 'react-redux';
import { useHistory } from 'react-router-dom';
import { fetchTraces, pushDStree, traceResponseNew } from 'store/actions';
import { AppState } from 'store/reducers';
import styled from 'styled-components';
import { isOnboardingSkipped } from 'utils/app';
const StyledTable = styled(Table)`
cursor: pointer;
`;
const TraceHeader = styled.div`
margin: 16px 0;
`;
interface TraceListProps {
traces: traceResponseNew;
fetchTraces: Function;
}
interface TableDataSourceItem {
key: string;
spanid: string;
traceid: string;
operationName: string;
startTime: number;
duration: number;
service: string;
}
const _TraceList = (props: TraceListProps) => {
// PNOTE (TO DO) - Currently this use of useEffect gives warning. May need to memoise fetchtraces - https://stackoverflow.com/questions/55840294/how-to-fix-missing-dependency-warning-when-using-useeffect-react-hook
const history = useHistory();
useEffect(() => {
props.fetchTraces();
}, []);
const columns: any = [
{
title: 'Start Time',
dataIndex: 'startTime',
key: 'startTime',
sorter: (a: any, b: any) => a.startTime - b.startTime,
sortDirections: ['descend', 'ascend'],
render: (value: number) => moment(value).format('YYYY-MM-DD hh:mm:ss'),
// new Date() assumes input in milliseconds. Start Time stamp returned by druid api for span list is in ms
},
{
title: 'Service',
dataIndex: 'service',
key: 'service',
},
{
title: 'Operation',
dataIndex: 'operationName',
key: 'operationName',
},
{
title: 'Duration (in ms)',
dataIndex: 'duration',
key: 'duration',
sorter: (a: any, b: any) => a.duration - b.duration,
sortDirections: ['descend', 'ascend'],
render: (value: number) => (value / 1000000).toFixed(2),
},
];
const dataSource: TableDataSourceItem[] = [];
const renderTraces = () => {
if (
typeof props.traces[0] !== 'undefined' &&
props.traces[0].events.length > 0
) {
props.traces[0].events.map(
(item: (number | string | string[] | pushDStree[])[], index) => {
if (
typeof item[0] === 'number' &&
typeof item[4] === 'string' &&
typeof item[6] === 'string' &&
typeof item[1] === 'string' &&
typeof item[2] === 'string' &&
typeof item[3] === 'string'
)
dataSource.push({
startTime: item[0],
operationName: item[4],
duration: parseInt(item[6]),
spanid: item[1],
traceid: item[2],
key: index.toString(),
service: item[3],
});
},
);
//antd table in typescript - https://codesandbox.io/s/react-typescript-669cv
return (
<StyledTable
dataSource={dataSource}
columns={columns}
size="middle"
rowClassName=""
onRow={(record) => ({
onClick: () => {
history.push({
pathname: ROUTES.TRACES + '/' + record.traceid,
state: {
spanId: record.spanid,
},
});
},
})}
/>
);
} else {
if (isOnboardingSkipped()) {
return (
<Space
style={{ width: '100%', margin: '40px 0', justifyContent: 'center' }}
>
No spans found. Please add instrumentation (follow this
<a
href={'https://signoz.io/docs/instrumentation/overview'}
target={'_blank'}
style={{ marginLeft: 3 }}
rel="noreferrer"
>
guide
</a>
)
</Space>
);
}
return <div> No spans found for given filter!</div>;
}
}; // end of renderTraces
return (
<div>
<TraceHeader>List of filtered spans</TraceHeader>
<div>{renderTraces()}</div>
</div>
);
};
const mapStateToProps = (state: AppState): { traces: traceResponseNew } => {
return { traces: state.traces };
};
export const TraceList = connect(mapStateToProps, {
fetchTraces: fetchTraces,
})(_TraceList);

View File

@ -14,8 +14,13 @@ import { Card } from './styles';
interface UsageExplorerProps {
usageData: usageDataItem[];
getUsageData: Function;
getServicesList: Function;
getUsageData: (
minTime: number,
maxTime: number,
selectedInterval: any,
selectedService: string,
) => void;
getServicesList: (time: GlobalTime) => void;
globalTime: GlobalTime;
servicesList: servicesListItem[];
totalCount: number;
@ -47,27 +52,30 @@ const interval = [
},
];
const _UsageExplorer = (props: UsageExplorerProps) => {
const _UsageExplorer = (props: UsageExplorerProps): JSX.Element => {
const [selectedTime, setSelectedTime] = useState(timeDaysOptions[1]);
const [selectedInterval, setSelectedInterval] = useState(interval[2]);
const [selectedService, setSelectedService] = useState<string>('');
const { loading } = useSelector<AppState, GlobalReducer>(
(state) => state.globalTime,
);
const {
getServicesList,
getUsageData,
globalTime,
servicesList,
totalCount,
usageData,
} = props;
useEffect(() => {
if (selectedTime && selectedInterval) {
const maxTime = new Date().getTime() * 1000000;
const minTime = maxTime - selectedTime.value * 24 * 3600000 * 1000000;
props.getUsageData(
minTime,
maxTime,
selectedInterval!.value,
selectedService,
);
getUsageData(minTime, maxTime, selectedInterval.value, selectedService);
}
}, [selectedTime, selectedInterval, selectedService]);
}, [selectedTime, selectedInterval, selectedService, getUsageData]);
useEffect(() => {
/*
@ -75,16 +83,16 @@ const _UsageExplorer = (props: UsageExplorerProps) => {
Check this issue: https://github.com/SigNoz/signoz/issues/110
*/
if (loading) {
props.getServicesList(props.globalTime);
getServicesList(globalTime);
}
}, [loading, props]);
}, [loading, globalTime, getServicesList]);
const data = {
labels: props.usageData.map((s) => new Date(s.timestamp / 1000000)),
labels: usageData.map((s) => new Date(s.timestamp / 1000000)),
datasets: [
{
label: 'Span Count',
data: props.usageData.map((s) => s.count),
data: usageData.map((s) => s.count),
backgroundColor: 'rgba(255, 99, 132, 0.2)',
borderColor: 'rgba(255, 99, 132, 1)',
borderWidth: 2,
@ -94,11 +102,10 @@ const _UsageExplorer = (props: UsageExplorerProps) => {
return (
<React.Fragment>
{/* PNOTE - TODO - Keep it in reponsive row column tab */}
<Space style={{ marginTop: 40, marginLeft: 20 }}>
<Space>
<Select
onSelect={(value, option) => {
onSelect={(value): void => {
setSelectedTime(
timeDaysOptions.filter((item) => item.value == parseInt(value))[0],
);
@ -106,42 +113,48 @@ const _UsageExplorer = (props: UsageExplorerProps) => {
value={selectedTime.label}
>
{timeDaysOptions.map(({ value, label }) => (
<Option value={value}>{label}</Option>
<Option key={value} value={value}>
{label}
</Option>
))}
</Select>
</Space>
<Space>
<Select
onSelect={(value) => {
onSelect={(value): void => {
setSelectedInterval(
interval.filter((item) => item!.value === parseInt(value))[0],
interval.filter((item) => item.value === parseInt(value))[0],
);
}}
value={selectedInterval!.label}
value={selectedInterval.label}
>
{interval
.filter((interval) => interval!.applicableOn.includes(selectedTime))
.filter((interval) => interval.applicableOn.includes(selectedTime))
.map((item) => (
<Option value={item!.value}>{item!.label}</Option>
<Option key={item.label} value={item.value}>
{item.label}
</Option>
))}
</Select>
</Space>
<Space>
<Select
onSelect={(value) => {
onSelect={(value): void => {
setSelectedService(value);
}}
value={selectedService || 'All Services'}
>
<Option value={''}>All Services</Option>
{props.servicesList.map((service) => (
<Option value={service.serviceName}>{service.serviceName}</Option>
{servicesList.map((service) => (
<Option key={service.serviceName} value={service.serviceName}>
{service.serviceName}
</Option>
))}
</Select>
</Space>
{isOnboardingSkipped() && props.totalCount === 0 ? (
{isOnboardingSkipped() && totalCount === 0 ? (
<Space
style={{
width: '100%',
@ -163,7 +176,7 @@ const _UsageExplorer = (props: UsageExplorerProps) => {
</Space>
) : (
<Space style={{ display: 'block', marginLeft: 20, width: 200 }}>
{`Total count is ${props.totalCount}`}
{`Total count is ${totalCount}`}
</Space>
)}
</Space>
@ -191,7 +204,7 @@ const mapStateToProps = (
totalCount: totalCount,
usageData: state.usageDate,
globalTime: state.globalTime,
servicesList: state.metricsData.serviceList,
servicesList: state.metricsData.serviceList || [],
};
};

View File

@ -1,7 +1,7 @@
import { Typography } from 'antd';
import Spinner from 'components/Spinner';
import MetricsApplicationContainer from 'container/MetricsApplication';
import React, { useEffect, useRef } from 'react';
import React, { useEffect } from 'react';
import { connect, useSelector } from 'react-redux';
import { useParams } from 'react-router-dom';
import { bindActionCreators } from 'redux';
@ -38,10 +38,10 @@ const MetricsApplication = ({
});
}
return () => {
return (): void => {
resetInitialData();
};
}, [servicename, getInitialData, selectedTime]);
}, [servicename, getInitialData, selectedTime, resetInitialData]);
if (metricsApplicationLoading) {
return <Spinner tip="Loading..." />;

View File

@ -9,8 +9,8 @@ import { bindActionCreators } from 'redux';
import { ThunkDispatch } from 'redux-thunk';
import {
GetInitialTraceData,
ResetRaceData,
GetInitialTraceDataProps,
ResetRaceData,
} from 'store/actions/trace';
import { AppState } from 'store/reducers';
import AppActions from 'types/actions';
@ -40,7 +40,7 @@ const TraceDetail = ({
return (): void => {
resetTraceData();
};
}, [getInitialTraceData, loading, selectedTime]);
}, [getInitialTraceData, loading, selectedTime, resetTraceData]);
if (error) {
return <Typography>{errorMessage}</Typography>;

View File

@ -6,7 +6,7 @@ export const ResetInitialData = (): ((
dispatch: Dispatch<AppActions>,
getState: () => AppState,
) => void) => {
return (dispatch, getState): void => {
return (dispatch): void => {
dispatch({
type: 'RESET_INITIAL_APPLICATION_DATA',
});

View File

@ -38,7 +38,7 @@ export interface servicesAction {
}
export const getServiceMapItems = (globalTime: GlobalTime) => {
return async (dispatch: Dispatch) => {
return async (dispatch: Dispatch): Promise<void> => {
dispatch<serviceMapItemAction>({
type: ActionTypes.getServiceMapItems,
payload: [],
@ -60,7 +60,7 @@ export const getServiceMapItems = (globalTime: GlobalTime) => {
};
export const getDetailedServiceMapItems = (globalTime: GlobalTime) => {
return async (dispatch: Dispatch) => {
return async (dispatch: Dispatch): Promise<void> => {
dispatch<servicesAction>({
type: ActionTypes.getServices,
payload: [],

View File

@ -1,4 +1,5 @@
export * from './getInitialData';
export * from './resetTraceDetails';
export * from './updateSelectedAggOption';
export * from './updateSelectedEntity';
export * from './updateSelectedKind';
@ -6,4 +7,3 @@ export * from './updateSelectedLatency';
export * from './updateSelectedOperation';
export * from './updateSelectedService';
export * from './updateSelectedTags';
export * from './resetTraceDetails';

View File

@ -26,7 +26,9 @@ export interface updateTraceFiltersAction {
payload: TraceFilters;
}
export const updateTraceFilters = (traceFilters: TraceFilters) => {
export const updateTraceFilters = (
traceFilters: TraceFilters,
): updateTraceFiltersAction => {
return {
type: ActionTypes.updateTraceFilters,
payload: traceFilters,

View File

@ -20,7 +20,7 @@ export const getUsageData = (
step: number,
service: string,
) => {
return async (dispatch: Dispatch) => {
return async (dispatch: Dispatch): Promise<void> => {
const request_string = `/usage?start=${toUTCEpoch(minTime)}&end=${toUTCEpoch(
maxTime,
)}&step=${step}&service=${service ? service : ''}`;

View File

@ -4,7 +4,6 @@ import appReducer from './app';
import dashboardReducer from './dashboard';
import globalTimeReducer from './global';
import metricsReducers from './metric';
import { metricsReducer } from './metrics';
import { ServiceMapReducer } from './serviceMap';
import { traceReducer } from './trace';
import TraceFilterReducer from './traceFilters';
@ -18,7 +17,6 @@ const reducers = combineReducers({
trace: traceReducer,
usageDate: usageDataReducer,
globalTime: globalTimeReducer,
metricsData: metricsReducer,
serviceMap: ServiceMapReducer,
dashboards: dashboardReducer,
app: appReducer,

View File

@ -5,8 +5,8 @@ import {
GET_SERVICE_LIST_ERROR,
GET_SERVICE_LIST_LOADING_START,
GET_SERVICE_LIST_SUCCESS,
RESET_INITIAL_APPLICATION_DATA,
MetricsActions,
RESET_INITIAL_APPLICATION_DATA,
} from 'types/actions/metrics';
import InitialValueTypes from 'types/reducer/metrics';

View File

@ -1,112 +0,0 @@
import {
customMetricsItem,
dbOverviewMetricsItem,
externalErrCodeMetricsItem,
externalMetricsAvgDurationItem,
externalMetricsItem,
metricItem,
servicesListItem,
topEndpointListItem,
} from 'store/actions/MetricsActions';
import { MetricsActionTypes as ActionTypes } from 'store/actions/MetricsActions/metricsActionTypes';
export type MetricsInitialState = {
serviceList?: servicesListItem[];
metricItems?: metricItem[];
topEndpointListItem?: topEndpointListItem[];
externalMetricsAvgDurationItem?: externalMetricsAvgDurationItem[];
externalErrCodeMetricsItem?: externalErrCodeMetricsItem[];
externalMetricsItem?: externalMetricsItem[];
dbOverviewMetricsItem?: dbOverviewMetricsItem[];
customMetricsItem?: customMetricsItem[];
loading: boolean;
};
export const metricsInitialState: MetricsInitialState = {
serviceList: [],
metricItems: [],
topEndpointListItem: [],
externalMetricsAvgDurationItem: [],
externalErrCodeMetricsItem: [],
externalMetricsItem: [],
dbOverviewMetricsItem: [],
customMetricsItem: [],
loading: false,
};
type ActionType = {
type: string;
payload: any;
};
export const metricsReducer = (
state: MetricsInitialState = metricsInitialState,
action: ActionType,
) => {
switch (action.type) {
case ActionTypes.getFilteredTraceMetrics:
return {
...state,
customMetricsItem: action.payload,
};
case ActionTypes.getServiceMetrics:
return {
...state,
metricItems: action.payload,
};
case ActionTypes.getDbOverviewMetrics:
return {
...state,
dbOverviewMetricsItem: action.payload,
};
case ActionTypes.getExternalMetrics:
return {
...state,
externalMetricsItem: action.payload,
};
case ActionTypes.getTopEndpoints:
return {
...state,
topEndpointListItem: action.payload,
};
case ActionTypes.getErrCodeMetrics:
return {
...state,
externalErrCodeMetricsItem: action.payload,
};
case ActionTypes.getAvgDurationMetrics:
return {
...state,
externalMetricsAvgDurationItem: action.payload,
};
case ActionTypes.getServicesList:
return {
...state,
serviceList: action.payload,
};
case 'UPDATE_INITIAL_VALUE_START': {
return {
...state,
loading: true,
};
}
case 'UPDATE_INITIAL_VALUE': {
return {
...state,
dbOverviewMetricsItem: action.payload.dbResponse,
topEndpointListItem: action.payload.topEndPointsResponse,
externalMetricsAvgDurationItem: action.payload.avgExternalDurationResponse,
externalErrCodeMetricsItem: action.payload.externalErrorCodeMetricsResponse,
metricItems: action.payload.serviceOverViewResponse,
externalMetricsItem: action.payload.externalServiceResponse,
loading: false,
};
}
default:
return {
...state,
};
}
};

View File

@ -5,7 +5,10 @@ const initialState: serviceMapStore = {
services: [],
};
export const ServiceMapReducer = (state = initialState, action: Action) => {
export const ServiceMapReducer = (
state = initialState,
action: Action,
): serviceMapStore => {
switch (action.type) {
case ActionTypes.getServiceMapItems:
return {

View File

@ -3,7 +3,9 @@ import {
GET_TRACE_INITIAL_DATA_SUCCESS,
GET_TRACE_LOADING_END,
GET_TRACE_LOADING_START,
RESET_TRACE_DATA,
TraceActions,
UPDATE_AGGREGATES,
UPDATE_SELECTED_AGG_OPTION,
UPDATE_SELECTED_ENTITY,
UPDATE_SELECTED_TRACE_DATA,
@ -13,8 +15,6 @@ import {
UPDATE_TRACE_SELECTED_OPERATION,
UPDATE_TRACE_SELECTED_SERVICE,
UPDATE_TRACE_SELECTED_TAGS,
RESET_TRACE_DATA,
UPDATE_AGGREGATES,
} from 'types/actions/trace';
import { TraceReducer } from 'types/reducer/trace';

View File

@ -14,7 +14,10 @@ const initialState: TraceFilters = {
kind: '',
};
const TraceFilterReducer = (state = initialState, action: ACTION) => {
const TraceFilterReducer = (
state = initialState,
action: ACTION,
): TraceFilters => {
switch (action.type) {
case ActionTypes.updateTraceFilters:
return action.payload;

View File

@ -11,7 +11,7 @@ const spanlistinstance: spanList = { events: [], segmentID: '', columns: [] };
export const tracesReducer = (
state: traceResponseNew = { '0': spanlistinstance },
action: Action,
) => {
): traceResponseNew => {
switch (action.type) {
case ActionTypes.fetchTraces:
return action.payload;
@ -23,7 +23,7 @@ export const tracesReducer = (
export const traceItemReducer = (
state: spansWSameTraceIDResponse = { '0': spanlistinstance },
action: Action,
) => {
): spansWSameTraceIDResponse => {
switch (action.type) {
case ActionTypes.fetchTraceItem:
return action.payload;

View File

@ -3,7 +3,7 @@ import { Action, ActionTypes, usageDataItem } from 'store/actions';
export const usageDataReducer = (
state: usageDataItem[] = [{ timestamp: 0, count: 0 }],
action: Action,
) => {
): usageDataItem[] => {
switch (action.type) {
case ActionTypes.getUsageData:
return action.payload;

View File

@ -34,6 +34,6 @@ declare module 'react-graph-vis' {
NetworkGraphProps,
NetworkGraphState
> {
render();
render(): JSX.Element;
}
}

View File

@ -2236,9 +2236,9 @@
integrity sha512-09x2d6kNBwjHgyh3jOUE2GE4DFoxDriDvWdu6mFhMP1ysynGYazt4ecZmJlL6/fe4Zi2vtYvTvtL7epjQQrBhA==
"@types/node@^16.10.3":
version "16.10.3"
resolved "https://registry.yarnpkg.com/@types/node/-/node-16.10.3.tgz#7a8f2838603ea314d1d22bb3171d899e15c57bd5"
integrity sha512-ho3Ruq+fFnBrZhUYI46n/bV2GjwzSkwuT4dTf0GkuNFmnb8nq4ny2z9JEVemFi6bdEJanHLlYfy9c6FN9B9McQ==
version "16.11.9"
resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.9.tgz#879be3ad7af29f4c1a5c433421bf99fab7047185"
integrity sha512-MKmdASMf3LtPzwLyRrFjtFFZ48cMf8jmX5VRYrDQiJa8Ybu5VAmkqBWqKU8fdCwD8ysw4mQ9nrEHvzg6gunR7A==
"@types/normalize-package-data@^2.4.0":
version "2.4.0"