mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-08-16 18:25:56 +08:00
chore: add analytics for metrics explorer
This commit is contained in:
parent
61b2f8cb31
commit
d838d83b12
@ -24,6 +24,10 @@ import { QueryParams } from 'constants/query';
|
||||
import { PANEL_TYPES } from 'constants/queryBuilder';
|
||||
import ROUTES from 'constants/routes';
|
||||
import ExportPanelContainer from 'container/ExportPanel/ExportPanelContainer';
|
||||
import {
|
||||
MetricsExplorerEventKeys,
|
||||
MetricsExplorerEvents,
|
||||
} from 'container/MetricsExplorer/events';
|
||||
import { useOptionsMenu } from 'container/OptionsMenu';
|
||||
import {
|
||||
defaultLogsSelectedColumns,
|
||||
@ -140,7 +144,9 @@ function ExplorerOptions({
|
||||
panelType,
|
||||
});
|
||||
} else if (isMetricsExplorer) {
|
||||
logEvent('Metrics Explorer: Save view clicked', {
|
||||
logEvent(MetricsExplorerEvents.SaveViewClicked, {
|
||||
[MetricsExplorerEventKeys.Tab]: 'explorer',
|
||||
[MetricsExplorerEventKeys.OneChartPerQueryEnabled]: isOneChartPerQuery,
|
||||
panelType,
|
||||
});
|
||||
}
|
||||
@ -184,8 +190,10 @@ function ExplorerOptions({
|
||||
panelType,
|
||||
});
|
||||
} else if (isMetricsExplorer) {
|
||||
logEvent('Metrics Explorer: Create alert', {
|
||||
logEvent(MetricsExplorerEvents.AddToAlertClicked, {
|
||||
panelType,
|
||||
[MetricsExplorerEventKeys.Tab]: 'explorer',
|
||||
[MetricsExplorerEventKeys.OneChartPerQueryEnabled]: isOneChartPerQuery,
|
||||
});
|
||||
}
|
||||
|
||||
@ -218,11 +226,14 @@ function ExplorerOptions({
|
||||
panelType,
|
||||
});
|
||||
} else if (isMetricsExplorer) {
|
||||
logEvent('Metrics Explorer: Add to dashboard clicked', {
|
||||
logEvent(MetricsExplorerEvents.AddToDashboardClicked, {
|
||||
panelType,
|
||||
[MetricsExplorerEventKeys.Tab]: 'explorer',
|
||||
[MetricsExplorerEventKeys.OneChartPerQueryEnabled]: isOneChartPerQuery,
|
||||
});
|
||||
}
|
||||
setIsExport(true);
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [isLogsExplorer, isMetricsExplorer, panelType, setIsExport, sourcepage]);
|
||||
|
||||
const {
|
||||
|
@ -2,6 +2,9 @@ import './Explorer.styles.scss';
|
||||
|
||||
import * as Sentry from '@sentry/react';
|
||||
import { Switch } from 'antd';
|
||||
import logEvent from 'api/common/logEvent';
|
||||
import axios from 'axios';
|
||||
import { LOCALSTORAGE } from 'constants/localStorage';
|
||||
import { initialQueriesMap, PANEL_TYPES } from 'constants/queryBuilder';
|
||||
import ExplorerOptionWrapper from 'container/ExplorerOptions/ExplorerOptionWrapper';
|
||||
import RightToolbarActions from 'container/QueryBuilder/components/ToolbarActions/RightToolbarActions';
|
||||
@ -10,7 +13,7 @@ import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
|
||||
import { useShareBuilderUrl } from 'hooks/queryBuilder/useShareBuilderUrl';
|
||||
import { useSafeNavigate } from 'hooks/useSafeNavigate';
|
||||
import ErrorBoundaryFallback from 'pages/ErrorBoundaryFallback/ErrorBoundaryFallback';
|
||||
import { useCallback, useMemo, useState } from 'react';
|
||||
import { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import { useSearchParams } from 'react-router-dom-v5-compat';
|
||||
import { Dashboard } from 'types/api/dashboard/getAll';
|
||||
import { Query } from 'types/api/queryBuilder/queryBuilderData';
|
||||
@ -18,6 +21,7 @@ import { DataSource } from 'types/common/queryBuilder';
|
||||
import { generateExportToDashboardLink } from 'utils/dashboard/generateExportToDashboardLink';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
|
||||
import { MetricsExplorerEventKeys, MetricsExplorerEvents } from '../events';
|
||||
import QuerySection from './QuerySection';
|
||||
import TimeSeries from './TimeSeries';
|
||||
import { ExplorerTabs } from './types';
|
||||
@ -93,6 +97,12 @@ function Explorer(): JSX.Element {
|
||||
[stagedQuery],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
logEvent(MetricsExplorerEvents.TabChanged, {
|
||||
[MetricsExplorerEventKeys.Tab]: 'explorer',
|
||||
});
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Sentry.ErrorBoundary fallback={<ErrorBoundaryFallback />}>
|
||||
<div className="metrics-explorer-explore-container">
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { Button } from 'antd';
|
||||
import logEvent from 'api/common/logEvent';
|
||||
import { PANEL_TYPES } from 'constants/queryBuilder';
|
||||
import { QueryBuilder } from 'container/QueryBuilder';
|
||||
import { ButtonWrapper } from 'container/TracesExplorer/QuerySection/styles';
|
||||
@ -6,6 +7,8 @@ import { useGetPanelTypesQueryParam } from 'hooks/queryBuilder/useGetPanelTypesQ
|
||||
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
|
||||
import { DataSource } from 'types/common/queryBuilder';
|
||||
|
||||
import { MetricsExplorerEventKeys, MetricsExplorerEvents } from '../events';
|
||||
|
||||
function QuerySection(): JSX.Element {
|
||||
const { handleRunQuery } = useQueryBuilder();
|
||||
|
||||
@ -19,7 +22,15 @@ function QuerySection(): JSX.Element {
|
||||
version="v4"
|
||||
actions={
|
||||
<ButtonWrapper>
|
||||
<Button onClick={(): void => handleRunQuery()} type="primary">
|
||||
<Button
|
||||
onClick={(): void => {
|
||||
handleRunQuery();
|
||||
logEvent(MetricsExplorerEvents.QueryBuilderQueryChanged, {
|
||||
[MetricsExplorerEventKeys.Tab]: 'explorer',
|
||||
});
|
||||
}}
|
||||
type="primary"
|
||||
>
|
||||
Run Query
|
||||
</Button>
|
||||
</ButtonWrapper>
|
||||
|
@ -4,6 +4,7 @@
|
||||
import { Color } from '@signozhq/design-tokens';
|
||||
import { Card, Tooltip, Typography } from 'antd';
|
||||
import { ColumnsType } from 'antd/es/table';
|
||||
import logEvent from 'api/common/logEvent';
|
||||
import { InspectMetricsSeries } from 'api/metricsExplorer/getInspectMetricsDetails';
|
||||
import classNames from 'classnames';
|
||||
import ResizeTable from 'components/ResizeTable/ResizeTable';
|
||||
@ -11,6 +12,7 @@ import { DataType } from 'container/LogDetailedView/TableView';
|
||||
import { ArrowDownCircle, ArrowRightCircle, Focus } from 'lucide-react';
|
||||
import { useEffect, useMemo, useState } from 'react';
|
||||
|
||||
import { MetricsExplorerEventKeys, MetricsExplorerEvents } from '../events';
|
||||
import {
|
||||
SPACE_AGGREGATION_OPTIONS_FOR_EXPANDED_VIEW,
|
||||
TIME_AGGREGATION_OPTIONS,
|
||||
@ -39,6 +41,21 @@ function ExpandedView({
|
||||
setSelectedTimeSeries,
|
||||
] = useState<InspectMetricsSeries | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
logEvent(MetricsExplorerEvents.InspectPointClicked, {
|
||||
[MetricsExplorerEventKeys.Modal]: 'inspect',
|
||||
[MetricsExplorerEventKeys.Filters]: metricInspectionOptions.filters,
|
||||
[MetricsExplorerEventKeys.TimeAggregationInterval]:
|
||||
metricInspectionOptions.timeAggregationInterval,
|
||||
[MetricsExplorerEventKeys.TimeAggregationOption]:
|
||||
metricInspectionOptions.timeAggregationOption,
|
||||
[MetricsExplorerEventKeys.SpaceAggregationOption]:
|
||||
metricInspectionOptions.spaceAggregationOption,
|
||||
[MetricsExplorerEventKeys.SpaceAggregationLabels]:
|
||||
metricInspectionOptions.spaceAggregationLabels,
|
||||
});
|
||||
}, [metricInspectionOptions]);
|
||||
|
||||
useEffect(() => {
|
||||
if (step !== InspectionStep.COMPLETED) {
|
||||
setSelectedTimeSeries(options?.timeSeries ?? null);
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { Color } from '@signozhq/design-tokens';
|
||||
import { Button, Skeleton, Switch, Typography } from 'antd';
|
||||
import logEvent from 'api/common/logEvent';
|
||||
import Uplot from 'components/Uplot';
|
||||
import { useIsDarkMode } from 'hooks/useDarkMode';
|
||||
import { useResizeObserver } from 'hooks/useDimensions';
|
||||
@ -8,6 +9,7 @@ import { useSelector } from 'react-redux';
|
||||
import { AppState } from 'store/reducers';
|
||||
import { GlobalReducer } from 'types/reducer/globalTime';
|
||||
|
||||
import { MetricsExplorerEventKeys, MetricsExplorerEvents } from '../events';
|
||||
import { formatNumberIntoHumanReadableFormat } from '../Summary/utils';
|
||||
import { METRIC_TYPE_TO_COLOR_MAP, METRIC_TYPE_TO_ICON_MAP } from './constants';
|
||||
import GraphPopover from './GraphPopover';
|
||||
@ -203,7 +205,14 @@ function GraphView({
|
||||
<div className="view-toggle-button">
|
||||
<Switch
|
||||
checked={viewType === 'graph'}
|
||||
onChange={(checked): void => setViewType(checked ? 'graph' : 'table')}
|
||||
onChange={(checked): void => {
|
||||
const newViewType = checked ? 'graph' : 'table';
|
||||
setViewType(newViewType);
|
||||
logEvent(MetricsExplorerEvents.InspectViewChanged, {
|
||||
[MetricsExplorerEventKeys.Tab]: 'inspect',
|
||||
[MetricsExplorerEventKeys.InspectView]: newViewType,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
<Typography.Text>
|
||||
{viewType === 'graph' ? 'Graph View' : 'Table View'}
|
||||
|
@ -3,6 +3,7 @@ import './Inspect.styles.scss';
|
||||
import * as Sentry from '@sentry/react';
|
||||
import { Color } from '@signozhq/design-tokens';
|
||||
import { Button, Drawer, Empty, Skeleton, Typography } from 'antd';
|
||||
import logEvent from 'api/common/logEvent';
|
||||
import { useGetMetricDetails } from 'hooks/metricsExplorer/useGetMetricDetails';
|
||||
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
|
||||
import { useQueryOperations } from 'hooks/queryBuilder/useQueryBuilderOperations';
|
||||
@ -11,11 +12,16 @@ import { Compass } from 'lucide-react';
|
||||
import ErrorBoundaryFallback from 'pages/ErrorBoundaryFallback/ErrorBoundaryFallback';
|
||||
import { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
|
||||
import { MetricsExplorerEventKeys, MetricsExplorerEvents } from '../events';
|
||||
import ExpandedView from './ExpandedView';
|
||||
import GraphView from './GraphView';
|
||||
import QueryBuilder from './QueryBuilder';
|
||||
import Stepper from './Stepper';
|
||||
import { GraphPopoverOptions, InspectProps } from './types';
|
||||
import {
|
||||
GraphPopoverOptions,
|
||||
InspectProps,
|
||||
MetricInspectionAction,
|
||||
} from './types';
|
||||
import { useInspectMetrics } from './useInspectMetrics';
|
||||
|
||||
function Inspect({
|
||||
@ -92,6 +98,25 @@ function Inspect({
|
||||
reset,
|
||||
} = useInspectMetrics(metricName);
|
||||
|
||||
const handleDispatchMetricInspectionOptions = useCallback(
|
||||
(action: MetricInspectionAction): void => {
|
||||
dispatchMetricInspectionOptions(action);
|
||||
logEvent(MetricsExplorerEvents.InspectQueryChanged, {
|
||||
[MetricsExplorerEventKeys.Modal]: 'inspect',
|
||||
[MetricsExplorerEventKeys.Filters]: metricInspectionOptions.filters,
|
||||
[MetricsExplorerEventKeys.TimeAggregationInterval]:
|
||||
metricInspectionOptions.timeAggregationInterval,
|
||||
[MetricsExplorerEventKeys.TimeAggregationOption]:
|
||||
metricInspectionOptions.timeAggregationOption,
|
||||
[MetricsExplorerEventKeys.SpaceAggregationOption]:
|
||||
metricInspectionOptions.spaceAggregationOption,
|
||||
[MetricsExplorerEventKeys.SpaceAggregationLabels]:
|
||||
metricInspectionOptions.spaceAggregationLabels,
|
||||
});
|
||||
},
|
||||
[dispatchMetricInspectionOptions, metricInspectionOptions],
|
||||
);
|
||||
|
||||
const selectedMetricType = useMemo(
|
||||
() => metricDetailsData?.payload?.data?.metadata?.metric_type,
|
||||
[metricDetailsData],
|
||||
@ -186,7 +211,7 @@ function Inspect({
|
||||
setMetricName={setMetricName}
|
||||
spaceAggregationLabels={spaceAggregationLabels}
|
||||
metricInspectionOptions={metricInspectionOptions}
|
||||
dispatchMetricInspectionOptions={dispatchMetricInspectionOptions}
|
||||
dispatchMetricInspectionOptions={handleDispatchMetricInspectionOptions}
|
||||
inspectionStep={inspectionStep}
|
||||
inspectMetricsTimeSeries={inspectMetricsTimeSeries}
|
||||
searchQuery={searchQuery}
|
||||
@ -227,12 +252,18 @@ function Inspect({
|
||||
popoverOptions,
|
||||
metricInspectionOptions,
|
||||
spaceAggregationLabels,
|
||||
dispatchMetricInspectionOptions,
|
||||
handleDispatchMetricInspectionOptions,
|
||||
searchQuery,
|
||||
expandedViewOptions,
|
||||
timeAggregatedSeriesMap,
|
||||
]);
|
||||
|
||||
useEffect(() => {
|
||||
logEvent(MetricsExplorerEvents.ModalOpened, {
|
||||
[MetricsExplorerEventKeys.Modal]: 'inspect',
|
||||
});
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Sentry.ErrorBoundary fallback={<ErrorBoundaryFallback />}>
|
||||
<Drawer
|
||||
|
@ -1,5 +1,6 @@
|
||||
/* eslint-disable no-nested-ternary */
|
||||
import { Card, Input, Select, Typography } from 'antd';
|
||||
import logEvent from 'api/common/logEvent';
|
||||
import { InspectMetricsSeries } from 'api/metricsExplorer/getInspectMetricsDetails';
|
||||
import { MetricType } from 'api/metricsExplorer/getMetricsList';
|
||||
import classNames from 'classnames';
|
||||
@ -16,6 +17,7 @@ import {
|
||||
import { TagFilter } from 'types/api/queryBuilder/queryBuilderData';
|
||||
import { DataSource } from 'types/common/queryBuilder';
|
||||
|
||||
import { MetricsExplorerEventKeys, MetricsExplorerEvents } from '../events';
|
||||
import {
|
||||
SPACE_AGGREGATION_OPTIONS,
|
||||
TIME_AGGREGATION_OPTIONS,
|
||||
@ -135,6 +137,9 @@ export function MetricFilters({
|
||||
}}
|
||||
onChange={(value): void => {
|
||||
handleChangeQueryData('filters', value);
|
||||
logEvent(MetricsExplorerEvents.FilterApplied, {
|
||||
[MetricsExplorerEventKeys.Modal]: 'inspect',
|
||||
});
|
||||
dispatchMetricInspectionOptions({
|
||||
type: 'SET_FILTERS',
|
||||
payload: value,
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { Button, Collapse, Input, Menu, Popover, Typography } from 'antd';
|
||||
import { ColumnsType } from 'antd/es/table';
|
||||
import logEvent from 'api/common/logEvent';
|
||||
import { ResizeTable } from 'components/ResizeTable';
|
||||
import { DataType } from 'container/LogDetailedView/TableView';
|
||||
import { useNotifications } from 'hooks/useNotifications';
|
||||
@ -10,6 +11,7 @@ import { useCopyToClipboard } from 'react-use';
|
||||
import { PANEL_TYPES } from '../../../constants/queryBuilder';
|
||||
import ROUTES from '../../../constants/routes';
|
||||
import { useHandleExplorerTabChange } from '../../../hooks/useHandleExplorerTabChange';
|
||||
import { MetricsExplorerEventKeys, MetricsExplorerEvents } from '../events';
|
||||
import { AllAttributesProps, AllAttributesValueProps } from './types';
|
||||
import { getMetricDetailsQuery } from './utils';
|
||||
|
||||
@ -135,9 +137,16 @@ function AllAttributes({
|
||||
},
|
||||
ROUTES.METRICS_EXPLORER_EXPLORER,
|
||||
);
|
||||
logEvent(MetricsExplorerEvents.OpenInExplorerClicked, {
|
||||
[MetricsExplorerEventKeys.MetricName]: metricName,
|
||||
[MetricsExplorerEventKeys.Tab]: 'summary',
|
||||
[MetricsExplorerEventKeys.Modal]: 'metric-details',
|
||||
[MetricsExplorerEventKeys.AttributeKey]: groupBy,
|
||||
});
|
||||
},
|
||||
[metricName, metricType, handleExplorerTabChange],
|
||||
);
|
||||
|
||||
const goToMetricsExploreWithAppliedAttribute = useCallback(
|
||||
(key: string, value: string) => {
|
||||
const compositeQuery = getMetricDetailsQuery(metricName, metricType, {
|
||||
@ -153,6 +162,13 @@ function AllAttributes({
|
||||
},
|
||||
ROUTES.METRICS_EXPLORER_EXPLORER,
|
||||
);
|
||||
logEvent(MetricsExplorerEvents.OpenInExplorerClicked, {
|
||||
[MetricsExplorerEventKeys.MetricName]: metricName,
|
||||
[MetricsExplorerEventKeys.Tab]: 'summary',
|
||||
[MetricsExplorerEventKeys.Modal]: 'metric-details',
|
||||
[MetricsExplorerEventKeys.AttributeKey]: key,
|
||||
[MetricsExplorerEventKeys.AttributeValue]: value,
|
||||
});
|
||||
},
|
||||
[metricName, metricType, handleExplorerTabChange],
|
||||
);
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { Button, Collapse, Input, Select, Typography } from 'antd';
|
||||
import { ColumnsType } from 'antd/es/table';
|
||||
import logEvent from 'api/common/logEvent';
|
||||
import { Temporality } from 'api/metricsExplorer/getMetricDetails';
|
||||
import { MetricType } from 'api/metricsExplorer/getMetricsList';
|
||||
import { UpdateMetricMetadataProps } from 'api/metricsExplorer/updateMetricMetadata';
|
||||
@ -11,6 +12,7 @@ import { useNotifications } from 'hooks/useNotifications';
|
||||
import { Edit2, Save, X } from 'lucide-react';
|
||||
import { useCallback, useMemo, useState } from 'react';
|
||||
|
||||
import { MetricsExplorerEventKeys, MetricsExplorerEvents } from '../events';
|
||||
import {
|
||||
METRIC_TYPE_LABEL_MAP,
|
||||
METRIC_TYPE_VALUES_MAP,
|
||||
@ -170,6 +172,11 @@ function Metadata({
|
||||
{
|
||||
onSuccess: (response): void => {
|
||||
if (response?.statusCode === 200) {
|
||||
logEvent(MetricsExplorerEvents.MetricMetadataUpdated, {
|
||||
[MetricsExplorerEventKeys.MetricName]: metricName,
|
||||
[MetricsExplorerEventKeys.Tab]: 'summary',
|
||||
[MetricsExplorerEventKeys.Modal]: 'metric-details',
|
||||
});
|
||||
notifications.success({
|
||||
message: 'Metadata updated successfully',
|
||||
});
|
||||
|
@ -11,14 +11,16 @@ import {
|
||||
Tooltip,
|
||||
Typography,
|
||||
} from 'antd';
|
||||
import logEvent from 'api/common/logEvent';
|
||||
import { useGetMetricDetails } from 'hooks/metricsExplorer/useGetMetricDetails';
|
||||
import { useIsDarkMode } from 'hooks/useDarkMode';
|
||||
import { Compass, Crosshair, X } from 'lucide-react';
|
||||
import { useCallback, useMemo } from 'react';
|
||||
import { useCallback, useEffect, useMemo } from 'react';
|
||||
|
||||
import { PANEL_TYPES } from '../../../constants/queryBuilder';
|
||||
import ROUTES from '../../../constants/routes';
|
||||
import { useHandleExplorerTabChange } from '../../../hooks/useHandleExplorerTabChange';
|
||||
import { MetricsExplorerEventKeys, MetricsExplorerEvents } from '../events';
|
||||
import { isInspectEnabled } from '../Inspect/utils';
|
||||
import { formatNumberIntoHumanReadableFormat } from '../Summary/utils';
|
||||
import AllAttributes from './AllAttributes';
|
||||
@ -95,11 +97,22 @@ function MetricDetails({
|
||||
},
|
||||
ROUTES.METRICS_EXPLORER_EXPLORER,
|
||||
);
|
||||
logEvent(MetricsExplorerEvents.OpenInExplorerClicked, {
|
||||
[MetricsExplorerEventKeys.MetricName]: metricName,
|
||||
[MetricsExplorerEventKeys.Tab]: 'summary',
|
||||
[MetricsExplorerEventKeys.Modal]: 'metric-details',
|
||||
});
|
||||
}
|
||||
}, [metricName, handleExplorerTabChange, metric?.metadata?.metric_type]);
|
||||
|
||||
const isMetricDetailsError = metricDetailsError || !metric;
|
||||
|
||||
useEffect(() => {
|
||||
logEvent(MetricsExplorerEvents.ModalOpened, {
|
||||
[MetricsExplorerEventKeys.Modal]: 'metric-details',
|
||||
});
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Drawer
|
||||
width="60%"
|
||||
|
@ -107,7 +107,7 @@ function MetricsTable({
|
||||
total: totalCount,
|
||||
}}
|
||||
onRow={(record): { onClick: () => void; className: string } => ({
|
||||
onClick: (): void => openMetricDetails(record.key),
|
||||
onClick: (): void => openMetricDetails(record.key, 'list'),
|
||||
className: 'clickable-row',
|
||||
})}
|
||||
/>
|
||||
|
@ -154,7 +154,7 @@ function MetricsTreemap({
|
||||
<foreignObject
|
||||
width={nodeWidth}
|
||||
height={nodeHeight}
|
||||
onClick={(): void => openMetricDetails(node.data.id)}
|
||||
onClick={(): void => openMetricDetails(node.data.id, 'treemap')}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
|
@ -1,6 +1,7 @@
|
||||
import './Summary.styles.scss';
|
||||
|
||||
import * as Sentry from '@sentry/react';
|
||||
import logEvent from 'api/common/logEvent';
|
||||
import { initialQueriesMap, PANEL_TYPES } from 'constants/queryBuilder';
|
||||
import { usePageSize } from 'container/InfraMonitoringK8s/utils';
|
||||
import { useGetMetricsList } from 'hooks/metricsExplorer/useGetMetricsList';
|
||||
@ -9,7 +10,7 @@ import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
|
||||
import { useQueryOperations } from 'hooks/queryBuilder/useQueryBuilderOperations';
|
||||
import { useShareBuilderUrl } from 'hooks/queryBuilder/useShareBuilderUrl';
|
||||
import ErrorBoundaryFallback from 'pages/ErrorBoundaryFallback/ErrorBoundaryFallback';
|
||||
import { useCallback, useMemo, useState } from 'react';
|
||||
import { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { useSearchParams } from 'react-router-dom-v5-compat';
|
||||
import { AppState } from 'store/reducers';
|
||||
@ -17,6 +18,7 @@ import { TagFilter } from 'types/api/queryBuilder/queryBuilderData';
|
||||
import { DataSource } from 'types/common/queryBuilder';
|
||||
import { GlobalReducer } from 'types/reducer/globalTime';
|
||||
|
||||
import { MetricsExplorerEventKeys, MetricsExplorerEvents } from '../events';
|
||||
import InspectModal from '../Inspect';
|
||||
import MetricDetails from '../MetricDetails';
|
||||
import {
|
||||
@ -44,7 +46,7 @@ function Summary(): JSX.Element {
|
||||
const { pageSize, setPageSize } = usePageSize('metricsExplorer');
|
||||
const [currentPage, setCurrentPage] = useState(1);
|
||||
const [orderBy, setOrderBy] = useState<OrderByPayload>(DEFAULT_ORDER_BY);
|
||||
const [heatmapView, setHeatmapView] = useState<TreemapViewType>(
|
||||
const [heatmapView, sexHeatmapView] = useState<TreemapViewType>(
|
||||
TreemapViewType.TIMESERIES,
|
||||
);
|
||||
|
||||
@ -63,6 +65,12 @@ function Summary(): JSX.Element {
|
||||
(state) => state.globalTime,
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
logEvent(MetricsExplorerEvents.TimeUpdated, {
|
||||
[MetricsExplorerEventKeys.Tab]: 'summary',
|
||||
});
|
||||
}, [maxTime, minTime]);
|
||||
|
||||
const { currentQuery, updateAllQueriesOperators } = useQueryBuilder();
|
||||
|
||||
const defaultQuery = useMemo(() => {
|
||||
@ -88,6 +96,12 @@ function Summary(): JSX.Element {
|
||||
|
||||
useShareBuilderUrl(defaultQuery);
|
||||
|
||||
useEffect(() => {
|
||||
logEvent(MetricsExplorerEvents.TabChanged, {
|
||||
[MetricsExplorerEventKeys.Tab]: 'summary',
|
||||
});
|
||||
}, []);
|
||||
|
||||
// This is used to avoid the filters from being serialized with the id
|
||||
const currentQueryFiltersString = useMemo(() => {
|
||||
const filters = currentQuery?.builder?.queryData[0]?.filters;
|
||||
@ -186,6 +200,9 @@ function Summary(): JSX.Element {
|
||||
[COMPOSITE_QUERY_KEY]: JSON.stringify(compositeQuery),
|
||||
});
|
||||
setCurrentPage(1);
|
||||
logEvent(MetricsExplorerEvents.FilterApplied, {
|
||||
[MetricsExplorerEventKeys.Tab]: 'summary',
|
||||
});
|
||||
},
|
||||
[handleChangeQueryData, currentQuery, setSearchParams],
|
||||
);
|
||||
@ -214,6 +231,14 @@ function Summary(): JSX.Element {
|
||||
const onPaginationChange = (page: number, pageSize: number): void => {
|
||||
setCurrentPage(page);
|
||||
setPageSize(pageSize);
|
||||
logEvent(MetricsExplorerEvents.PageNumberChanged, {
|
||||
[MetricsExplorerEventKeys.Tab]: 'summary',
|
||||
[MetricsExplorerEventKeys.PageNumber]: page,
|
||||
});
|
||||
logEvent(MetricsExplorerEvents.PageSizeChanged, {
|
||||
[MetricsExplorerEventKeys.Tab]: 'summary',
|
||||
[MetricsExplorerEventKeys.PageSize]: pageSize,
|
||||
});
|
||||
};
|
||||
|
||||
const formattedMetricsData = useMemo(
|
||||
@ -221,13 +246,20 @@ function Summary(): JSX.Element {
|
||||
[metricsData],
|
||||
);
|
||||
|
||||
const openMetricDetails = (metricName: string): void => {
|
||||
const openMetricDetails = (
|
||||
metricName: string,
|
||||
view: 'list' | 'treemap',
|
||||
): void => {
|
||||
setSelectedMetricName(metricName);
|
||||
setIsMetricDetailsOpen(true);
|
||||
setSearchParams({
|
||||
[IS_METRIC_DETAILS_OPEN_KEY]: 'true',
|
||||
[SELECTED_METRIC_NAME_KEY]: metricName,
|
||||
});
|
||||
logEvent(MetricsExplorerEvents.MetricClicked, {
|
||||
[MetricsExplorerEventKeys.MetricName]: metricName,
|
||||
[MetricsExplorerEventKeys.View]: view,
|
||||
});
|
||||
};
|
||||
|
||||
const closeMetricDetails = (): void => {
|
||||
@ -262,6 +294,22 @@ function Summary(): JSX.Element {
|
||||
});
|
||||
};
|
||||
|
||||
const handleSetHeatmapView = (view: TreemapViewType): void => {
|
||||
sexHeatmapView(view);
|
||||
logEvent(MetricsExplorerEvents.TreemapViewChanged, {
|
||||
[MetricsExplorerEventKeys.ViewType]: view,
|
||||
});
|
||||
};
|
||||
|
||||
const handleSetOrderBy = (orderBy: OrderByPayload): void => {
|
||||
setOrderBy(orderBy);
|
||||
logEvent(MetricsExplorerEvents.OrderByApplied, {
|
||||
[MetricsExplorerEventKeys.Tab]: 'summary',
|
||||
[MetricsExplorerEventKeys.ColumnName]: orderBy.columnName,
|
||||
[MetricsExplorerEventKeys.Order]: orderBy.order,
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<Sentry.ErrorBoundary fallback={<ErrorBoundaryFallback />}>
|
||||
<div className="metrics-explorer-summary-tab">
|
||||
@ -272,7 +320,7 @@ function Summary(): JSX.Element {
|
||||
isError={isProportionViewError}
|
||||
viewType={heatmapView}
|
||||
openMetricDetails={openMetricDetails}
|
||||
setHeatmapView={setHeatmapView}
|
||||
setHeatmapView={handleSetHeatmapView}
|
||||
/>
|
||||
<MetricsTable
|
||||
isLoading={isMetricsLoading || isMetricsFetching}
|
||||
@ -281,7 +329,7 @@ function Summary(): JSX.Element {
|
||||
pageSize={pageSize}
|
||||
currentPage={currentPage}
|
||||
onPaginationChange={onPaginationChange}
|
||||
setOrderBy={setOrderBy}
|
||||
setOrderBy={handleSetOrderBy}
|
||||
totalCount={metricsData?.payload?.data?.total || 0}
|
||||
openMetricDetails={openMetricDetails}
|
||||
/>
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { MetricsTreeMapResponse } from 'api/metricsExplorer/getMetricsTreeMap';
|
||||
import React, { Dispatch, SetStateAction } from 'react';
|
||||
import React from 'react';
|
||||
import {
|
||||
IBuilderQuery,
|
||||
TagFilter,
|
||||
@ -12,9 +12,9 @@ export interface MetricsTableProps {
|
||||
pageSize: number;
|
||||
currentPage: number;
|
||||
onPaginationChange: (page: number, pageSize: number) => void;
|
||||
setOrderBy: Dispatch<SetStateAction<OrderByPayload>>;
|
||||
setOrderBy: (orderBy: OrderByPayload) => void;
|
||||
totalCount: number;
|
||||
openMetricDetails: (metricName: string) => void;
|
||||
openMetricDetails: (metricName: string, view: 'list' | 'treemap') => void;
|
||||
}
|
||||
|
||||
export interface MetricsSearchProps {
|
||||
@ -27,7 +27,7 @@ export interface MetricsTreemapProps {
|
||||
isLoading: boolean;
|
||||
isError: boolean;
|
||||
viewType: TreemapViewType;
|
||||
openMetricDetails: (metricName: string) => void;
|
||||
openMetricDetails: (metricName: string, view: 'list' | 'treemap') => void;
|
||||
setHeatmapView: (value: TreemapViewType) => void;
|
||||
}
|
||||
|
||||
|
51
frontend/src/container/MetricsExplorer/events.ts
Normal file
51
frontend/src/container/MetricsExplorer/events.ts
Normal file
@ -0,0 +1,51 @@
|
||||
/**
|
||||
* This file contains all analytics events for the Metrics Explorer.
|
||||
*/
|
||||
export enum MetricsExplorerEvents {
|
||||
TabChanged = 'Metrics Explorer: Tab visited',
|
||||
ModalOpened = 'Metrics Explorer: Modal opened',
|
||||
MetricClicked = 'Metrics Explorer: Metric clicked',
|
||||
FilterApplied = 'Metrics Explorer: Filter applied',
|
||||
TimeUpdated = 'Metrics Explorer: Time updated',
|
||||
TreemapViewChanged = 'Metrics Explorer: Treemap view changed',
|
||||
PageNumberChanged = 'Metrics Explorer: Page number changed',
|
||||
PageSizeChanged = 'Metrics Explorer: Page size changed',
|
||||
OrderByApplied = 'Metrics Explorer: Order by applied',
|
||||
MetricMetadataUpdated = 'Metrics Explorer: Metric metadata updated',
|
||||
OpenInExplorerClicked = 'Metric Explorer: Open in explorer clicked',
|
||||
InspectViewChanged = 'Metrics Explorer: Inspect view changed',
|
||||
InspectQueryChanged = 'Metrics Explorer: Inspect query changed',
|
||||
InspectPointClicked = 'Metrics Explorer: Inspect point clicked',
|
||||
QueryBuilderQueryChanged = 'Metrics Explorer: QueryBuilder query changed',
|
||||
YAxisUnitApplied = 'Metrics Explorer: Y axis unit applied',
|
||||
AddToAlertClicked = 'Metrics Explorer: Add to alert clicked',
|
||||
AddToDashboardClicked = 'Metrics Explorer: Add to dashboard clicked',
|
||||
SaveViewClicked = 'Metrics Explorer: Save view clicked',
|
||||
SearchApplied = 'Metrics Explorer: Search applied',
|
||||
ViewEdited = 'Metrics Explorer: View edited',
|
||||
ViewDeleted = 'Metrics Explorer: View deleted',
|
||||
}
|
||||
|
||||
export enum MetricsExplorerEventKeys {
|
||||
Tab = 'tab',
|
||||
Modal = 'modal',
|
||||
View = 'view',
|
||||
Interval = 'interval',
|
||||
ViewType = 'viewType',
|
||||
PageNumber = 'pageNumber',
|
||||
PageSize = 'pageSize',
|
||||
ColumnName = 'columnName',
|
||||
Order = 'order',
|
||||
AttributeKey = 'attributeKey',
|
||||
AttributeValue = 'attributeValue',
|
||||
MetricName = 'metricName',
|
||||
InspectView = 'inspectView',
|
||||
TimeAggregationOption = 'timeAggregationOption',
|
||||
TimeAggregationInterval = 'timeAggregationInterval',
|
||||
SpaceAggregationOption = 'spaceAggregationOption',
|
||||
SpaceAggregationLabels = 'spaceAggregationLabels',
|
||||
OneChartPerQueryEnabled = 'oneChartPerQueryEnabled',
|
||||
YAxisUnit = 'yAxisUnit',
|
||||
ViewName = 'viewName',
|
||||
Filters = 'filters',
|
||||
}
|
@ -17,6 +17,10 @@ import {
|
||||
} from 'components/ExplorerCard/utils';
|
||||
import { DATE_TIME_FORMATS } from 'constants/dateTimeFormats';
|
||||
import { getRandomColor } from 'container/ExplorerOptions/utils';
|
||||
import {
|
||||
MetricsExplorerEventKeys,
|
||||
MetricsExplorerEvents,
|
||||
} from 'container/MetricsExplorer/events';
|
||||
import { useDeleteView } from 'hooks/saveViews/useDeleteView';
|
||||
import { useGetAllViews } from 'hooks/saveViews/useGetAllViews';
|
||||
import { useUpdateView } from 'hooks/saveViews/useUpdateView';
|
||||
@ -155,6 +159,10 @@ function SaveView(): JSX.Element {
|
||||
logEvent('Logs Views: Views visited', {
|
||||
number: viewsData?.data?.data?.length,
|
||||
});
|
||||
} else if (sourcepage === DataSource.METRICS) {
|
||||
logEvent(MetricsExplorerEvents.TabChanged, {
|
||||
[MetricsExplorerEventKeys.Tab]: 'views',
|
||||
});
|
||||
}
|
||||
logEventCalledRef.current = true;
|
||||
}
|
||||
@ -176,6 +184,9 @@ function SaveView(): JSX.Element {
|
||||
});
|
||||
hideEditViewModal();
|
||||
refetchAllView();
|
||||
logEvent(MetricsExplorerEvents.ViewEdited, {
|
||||
[MetricsExplorerEventKeys.Tab]: 'views',
|
||||
});
|
||||
},
|
||||
onError: (err) => {
|
||||
showErrorNotification(notifications, err);
|
||||
@ -204,6 +215,10 @@ function SaveView(): JSX.Element {
|
||||
},
|
||||
SOURCEPAGE_VS_ROUTES[sourcepage],
|
||||
);
|
||||
logEvent(MetricsExplorerEvents.OpenInExplorerClicked, {
|
||||
[MetricsExplorerEventKeys.Tab]: 'views',
|
||||
[MetricsExplorerEventKeys.ViewName]: name,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1,6 +1,11 @@
|
||||
import { NotificationInstance } from 'antd/es/notification/interface';
|
||||
import logEvent from 'api/common/logEvent';
|
||||
import { MenuItemLabelGeneratorProps } from 'components/ExplorerCard/types';
|
||||
import { showErrorNotification } from 'components/ExplorerCard/utils';
|
||||
import {
|
||||
MetricsExplorerEventKeys,
|
||||
MetricsExplorerEvents,
|
||||
} from 'container/MetricsExplorer/events';
|
||||
import { UseMutateAsyncFunction } from 'react-query';
|
||||
import { DeleteViewPayloadProps } from 'types/api/saveViews/types';
|
||||
|
||||
@ -29,6 +34,9 @@ export const deleteViewHandler = ({
|
||||
message: 'View Deleted Successfully',
|
||||
});
|
||||
refetchAllView();
|
||||
logEvent(MetricsExplorerEvents.ViewDeleted, {
|
||||
[MetricsExplorerEventKeys.Tab]: 'views',
|
||||
});
|
||||
},
|
||||
onError: (err) => {
|
||||
showErrorNotification(notifications, err);
|
||||
|
Loading…
x
Reference in New Issue
Block a user