mirror of
https://github.com/SigNoz/signoz.git
synced 2026-03-09 15:02:21 +00:00
Compare commits
2 Commits
cursor/use
...
feat/y-axi
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fce3198f68 | ||
|
|
8c58905c80 |
@@ -55,4 +55,5 @@ export enum QueryParams {
|
||||
source = 'source',
|
||||
showClassicCreateAlertsPage = 'showClassicCreateAlertsPage',
|
||||
isTestAlert = 'isTestAlert',
|
||||
yAxisUnit = 'yAxisUnit',
|
||||
}
|
||||
|
||||
@@ -39,6 +39,7 @@ import { useGetExplorerQueryRange } from 'hooks/queryBuilder/useGetExplorerQuery
|
||||
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
|
||||
import { useSafeNavigate } from 'hooks/useSafeNavigate';
|
||||
import useUrlQueryData from 'hooks/useUrlQueryData';
|
||||
import useUrlYAxisUnit from 'hooks/useUrlYAxisUnit';
|
||||
import { isEmpty, isUndefined } from 'lodash-es';
|
||||
import LiveLogs from 'pages/LiveLogs';
|
||||
import { UpdateTimeInterval } from 'store/actions';
|
||||
@@ -59,6 +60,7 @@ import LogsActionsContainer from './LogsActionsContainer';
|
||||
|
||||
import './LogsExplorerViews.styles.scss';
|
||||
|
||||
// eslint-disable-next-line sonarjs/cognitive-complexity
|
||||
function LogsExplorerViewsContainer({
|
||||
setIsLoadingQueries,
|
||||
listQueryKeyRef,
|
||||
@@ -109,7 +111,7 @@ function LogsExplorerViewsContainer({
|
||||
|
||||
const [orderBy, setOrderBy] = useState<string>('timestamp:desc');
|
||||
|
||||
const [yAxisUnit, setYAxisUnit] = useState<string>('');
|
||||
const { yAxisUnit, onUnitChange } = useUrlYAxisUnit('');
|
||||
|
||||
const listQuery = useMemo(() => getListQuery(stagedQuery) || null, [
|
||||
stagedQuery,
|
||||
@@ -367,10 +369,6 @@ function LogsExplorerViewsContainer({
|
||||
orderBy,
|
||||
]);
|
||||
|
||||
const onUnitChangeHandler = useCallback((value: string): void => {
|
||||
setYAxisUnit(value);
|
||||
}, []);
|
||||
|
||||
const chartData = useMemo(() => {
|
||||
if (!stagedQuery) {
|
||||
return [];
|
||||
@@ -488,10 +486,7 @@ function LogsExplorerViewsContainer({
|
||||
{selectedPanelType === PANEL_TYPES.TIME_SERIES && !showLiveLogs && (
|
||||
<div className="time-series-view-container">
|
||||
<div className="time-series-view-container-header">
|
||||
<BuilderUnitsFilter
|
||||
onChange={onUnitChangeHandler}
|
||||
yAxisUnit={yAxisUnit}
|
||||
/>
|
||||
<BuilderUnitsFilter onChange={onUnitChange} yAxisUnit={yAxisUnit} />
|
||||
</div>
|
||||
<TimeSeriesView
|
||||
isLoading={isLoading || isFetching}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useMemo, useState } from 'react';
|
||||
import { useMemo } from 'react';
|
||||
import { useQueries } from 'react-query';
|
||||
// eslint-disable-next-line no-restricted-imports
|
||||
import { useSelector } from 'react-redux';
|
||||
@@ -11,6 +11,7 @@ import { BuilderUnitsFilter } from 'container/QueryBuilder/filters/BuilderUnitsF
|
||||
import TimeSeriesView from 'container/TimeSeriesView/TimeSeriesView';
|
||||
import { convertDataValueToMs } from 'container/TimeSeriesView/utils';
|
||||
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
|
||||
import useUrlYAxisUnit from 'hooks/useUrlYAxisUnit';
|
||||
import { GetMetricQueryRange } from 'lib/dashboard/getQueryResults';
|
||||
import { useErrorModal } from 'providers/ErrorModalProvider';
|
||||
import { AppState } from 'store/reducers';
|
||||
@@ -22,14 +23,13 @@ import { GlobalReducer } from 'types/reducer/globalTime';
|
||||
|
||||
function TimeSeries(): JSX.Element {
|
||||
const { stagedQuery, currentQuery } = useQueryBuilder();
|
||||
const { yAxisUnit, onUnitChange } = useUrlYAxisUnit('');
|
||||
|
||||
const { selectedTime: globalSelectedTime, maxTime, minTime } = useSelector<
|
||||
AppState,
|
||||
GlobalReducer
|
||||
>((state) => state.globalTime);
|
||||
|
||||
const [yAxisUnit, setYAxisUnit] = useState<string>('');
|
||||
|
||||
const isValidToConvertToMs = useMemo(() => {
|
||||
const isValid: boolean[] = [];
|
||||
|
||||
@@ -112,10 +112,6 @@ function TimeSeries(): JSX.Element {
|
||||
[data, isValidToConvertToMs],
|
||||
);
|
||||
|
||||
const onUnitChangeHandler = (value: string): void => {
|
||||
setYAxisUnit(value);
|
||||
};
|
||||
|
||||
const hasMetricSelected = useMemo(
|
||||
() => currentQuery.builder.queryData.some((q) => q.aggregateAttribute?.key),
|
||||
[currentQuery],
|
||||
@@ -123,7 +119,7 @@ function TimeSeries(): JSX.Element {
|
||||
|
||||
return (
|
||||
<div className="meter-time-series-container">
|
||||
<BuilderUnitsFilter onChange={onUnitChangeHandler} yAxisUnit={yAxisUnit} />
|
||||
<BuilderUnitsFilter onChange={onUnitChange} yAxisUnit={yAxisUnit} />
|
||||
<div className="time-series-container">
|
||||
{!hasMetricSelected && <EmptyMetricsSearch />}
|
||||
{hasMetricSelected &&
|
||||
|
||||
59
frontend/src/hooks/useUrlYAxisUnit.ts
Normal file
59
frontend/src/hooks/useUrlYAxisUnit.ts
Normal file
@@ -0,0 +1,59 @@
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
import { QueryParams } from 'constants/query';
|
||||
import { useSafeNavigate } from 'hooks/useSafeNavigate';
|
||||
import useUrlQuery from 'hooks/useUrlQuery';
|
||||
|
||||
interface UseUrlYAxisUnitResult {
|
||||
yAxisUnit: string;
|
||||
onUnitChange: (value: string) => void;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook to manage y-axis unit synchronized with the URL query param.
|
||||
* It:
|
||||
* - Initializes from `QueryParams.yAxisUnit` or a provided default
|
||||
* - Keeps local state in sync when the URL changes (e.g. back/forward, shared links)
|
||||
* - Writes updates back to the URL while preserving existing query params
|
||||
*/
|
||||
function useUrlYAxisUnit(defaultUnit = ''): UseUrlYAxisUnitResult {
|
||||
const urlQuery = useUrlQuery();
|
||||
const location = useLocation();
|
||||
const { safeNavigate } = useSafeNavigate();
|
||||
|
||||
const initialUnit = urlQuery.get(QueryParams.yAxisUnit) ?? defaultUnit;
|
||||
const [yAxisUnit, setYAxisUnit] = useState<string>(initialUnit);
|
||||
|
||||
// Sync yAxisUnit when URL param changes (e.g. browser back or shared link)
|
||||
useEffect(() => {
|
||||
const fromUrl = urlQuery.get(QueryParams.yAxisUnit) ?? defaultUnit;
|
||||
if (fromUrl !== yAxisUnit) {
|
||||
setYAxisUnit(fromUrl);
|
||||
}
|
||||
// Only react to URL param changes
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [location.search]);
|
||||
|
||||
const onUnitChange = useCallback(
|
||||
(value: string): void => {
|
||||
setYAxisUnit(value);
|
||||
|
||||
const params = new URLSearchParams(urlQuery);
|
||||
if (value) {
|
||||
params.set(QueryParams.yAxisUnit, value);
|
||||
} else {
|
||||
params.delete(QueryParams.yAxisUnit);
|
||||
}
|
||||
|
||||
safeNavigate({
|
||||
pathname: location.pathname,
|
||||
search: `?${params.toString()}`,
|
||||
});
|
||||
},
|
||||
[location.pathname, safeNavigate, urlQuery],
|
||||
);
|
||||
|
||||
return { yAxisUnit, onUnitChange };
|
||||
}
|
||||
|
||||
export default useUrlYAxisUnit;
|
||||
@@ -4,7 +4,6 @@ import {
|
||||
SetStateAction,
|
||||
useEffect,
|
||||
useMemo,
|
||||
useState,
|
||||
} from 'react';
|
||||
// eslint-disable-next-line no-restricted-imports
|
||||
import { useSelector } from 'react-redux';
|
||||
@@ -16,6 +15,7 @@ import TimeSeriesView from 'container/TimeSeriesView/TimeSeriesView';
|
||||
import { convertDataValueToMs } from 'container/TimeSeriesView/utils';
|
||||
import { useGetQueryRange } from 'hooks/queryBuilder/useGetQueryRange';
|
||||
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
|
||||
import useUrlYAxisUnit from 'hooks/useUrlYAxisUnit';
|
||||
import { AppState } from 'store/reducers';
|
||||
import { Warning } from 'types/api';
|
||||
import APIError from 'types/api/error';
|
||||
@@ -52,13 +52,8 @@ function TimeSeriesViewContainer({
|
||||
return isValid.every(Boolean);
|
||||
}, [currentQuery]);
|
||||
|
||||
const [yAxisUnit, setYAxisUnit] = useState<string>(
|
||||
isValidToConvertToMs ? 'ms' : 'short',
|
||||
);
|
||||
|
||||
const onUnitChangeHandler = (value: string): void => {
|
||||
setYAxisUnit(value);
|
||||
};
|
||||
const defaultUnit = isValidToConvertToMs ? 'ms' : 'short';
|
||||
const { yAxisUnit, onUnitChange } = useUrlYAxisUnit(defaultUnit);
|
||||
|
||||
const { selectedTime: globalSelectedTime, maxTime, minTime } = useSelector<
|
||||
AppState,
|
||||
@@ -121,7 +116,7 @@ function TimeSeriesViewContainer({
|
||||
return (
|
||||
<div className="trace-explorer-time-series-view-container">
|
||||
<div className="trace-explorer-time-series-view-container-header">
|
||||
<BuilderUnitsFilter onChange={onUnitChangeHandler} yAxisUnit={yAxisUnit} />
|
||||
<BuilderUnitsFilter onChange={onUnitChange} yAxisUnit={yAxisUnit} />
|
||||
</div>
|
||||
<TimeSeriesView
|
||||
isFilterApplied={isFilterApplied}
|
||||
|
||||
Reference in New Issue
Block a user