mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-08-15 13:16:00 +08:00
feat: element is made into focus and scrolled into view after edit/save (#4046)
This commit is contained in:
parent
ae3b604cdc
commit
1f0fdfd403
@ -9,7 +9,8 @@ import { getUPlotChartOptions } from 'lib/uPlotLib/getUplotChartOptions';
|
|||||||
import { getUPlotChartData } from 'lib/uPlotLib/utils/getUplotChartData';
|
import { getUPlotChartData } from 'lib/uPlotLib/utils/getUplotChartData';
|
||||||
import isEmpty from 'lodash-es/isEmpty';
|
import isEmpty from 'lodash-es/isEmpty';
|
||||||
import _noop from 'lodash-es/noop';
|
import _noop from 'lodash-es/noop';
|
||||||
import { memo, useCallback, useMemo, useRef, useState } from 'react';
|
import { useDashboard } from 'providers/Dashboard/Dashboard';
|
||||||
|
import { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||||
import { useDispatch, useSelector } from 'react-redux';
|
import { useDispatch, useSelector } from 'react-redux';
|
||||||
import { UpdateTimeInterval } from 'store/actions';
|
import { UpdateTimeInterval } from 'store/actions';
|
||||||
import { AppState } from 'store/reducers';
|
import { AppState } from 'store/reducers';
|
||||||
@ -32,6 +33,7 @@ function GridCardGraph({
|
|||||||
}: GridCardGraphProps): JSX.Element {
|
}: GridCardGraphProps): JSX.Element {
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const [errorMessage, setErrorMessage] = useState<string>();
|
const [errorMessage, setErrorMessage] = useState<string>();
|
||||||
|
const { toScrollWidgetId, setToScrollWidgetId } = useDashboard();
|
||||||
|
|
||||||
const onDragSelect = useCallback(
|
const onDragSelect = useCallback(
|
||||||
(start: number, end: number): void => {
|
(start: number, end: number): void => {
|
||||||
@ -49,6 +51,17 @@ function GridCardGraph({
|
|||||||
|
|
||||||
const isVisible = useIntersectionObserver(graphRef, undefined, true);
|
const isVisible = useIntersectionObserver(graphRef, undefined, true);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (toScrollWidgetId === widget.id) {
|
||||||
|
graphRef.current?.scrollIntoView({
|
||||||
|
behavior: 'smooth',
|
||||||
|
block: 'center',
|
||||||
|
});
|
||||||
|
graphRef.current?.focus();
|
||||||
|
setToScrollWidgetId('');
|
||||||
|
}
|
||||||
|
}, [toScrollWidgetId, setToScrollWidgetId, widget.id]);
|
||||||
|
|
||||||
const { minTime, maxTime, selectedTime: globalSelectedInterval } = useSelector<
|
const { minTime, maxTime, selectedTime: globalSelectedInterval } = useSelector<
|
||||||
AppState,
|
AppState,
|
||||||
GlobalReducer
|
GlobalReducer
|
||||||
|
@ -165,7 +165,7 @@ function GraphLayout({ onAddPanelHandler }: GraphLayoutProps): JSX.Element {
|
|||||||
className={isDashboardLocked ? '' : 'enable-resize'}
|
className={isDashboardLocked ? '' : 'enable-resize'}
|
||||||
isDarkMode={isDarkMode}
|
isDarkMode={isDarkMode}
|
||||||
key={id}
|
key={id}
|
||||||
data-grid={layout}
|
data-grid={JSON.stringify(currentWidget)}
|
||||||
>
|
>
|
||||||
<Card
|
<Card
|
||||||
className="grid-item"
|
className="grid-item"
|
||||||
|
@ -21,7 +21,7 @@ import { useCallback, useMemo, useState } from 'react';
|
|||||||
import { useSelector } from 'react-redux';
|
import { useSelector } from 'react-redux';
|
||||||
import { generatePath, useLocation, useParams } from 'react-router-dom';
|
import { generatePath, useLocation, useParams } from 'react-router-dom';
|
||||||
import { AppState } from 'store/reducers';
|
import { AppState } from 'store/reducers';
|
||||||
import { Widgets } from 'types/api/dashboard/getAll';
|
import { Dashboard, Widgets } from 'types/api/dashboard/getAll';
|
||||||
import { EQueryType } from 'types/common/dashboard';
|
import { EQueryType } from 'types/common/dashboard';
|
||||||
import { DataSource } from 'types/common/queryBuilder';
|
import { DataSource } from 'types/common/queryBuilder';
|
||||||
import AppReducer from 'types/reducer/app';
|
import AppReducer from 'types/reducer/app';
|
||||||
@ -41,7 +41,11 @@ import {
|
|||||||
import { NewWidgetProps } from './types';
|
import { NewWidgetProps } from './types';
|
||||||
|
|
||||||
function NewWidget({ selectedGraph }: NewWidgetProps): JSX.Element {
|
function NewWidget({ selectedGraph }: NewWidgetProps): JSX.Element {
|
||||||
const { selectedDashboard } = useDashboard();
|
const {
|
||||||
|
selectedDashboard,
|
||||||
|
setSelectedDashboard,
|
||||||
|
setToScrollWidgetId,
|
||||||
|
} = useDashboard();
|
||||||
|
|
||||||
const { currentQuery } = useQueryBuilder();
|
const { currentQuery } = useQueryBuilder();
|
||||||
|
|
||||||
@ -104,8 +108,6 @@ function NewWidget({ selectedGraph }: NewWidgetProps): JSX.Element {
|
|||||||
enum: selectedWidget?.timePreferance || 'GLOBAL_TIME',
|
enum: selectedWidget?.timePreferance || 'GLOBAL_TIME',
|
||||||
});
|
});
|
||||||
|
|
||||||
const { notifications } = useNotifications();
|
|
||||||
|
|
||||||
const updateDashboardMutation = useUpdateDashboard();
|
const updateDashboardMutation = useUpdateDashboard();
|
||||||
|
|
||||||
const { afterWidgets, preWidgets } = useMemo(() => {
|
const { afterWidgets, preWidgets } = useMemo(() => {
|
||||||
@ -135,49 +137,54 @@ function NewWidget({ selectedGraph }: NewWidgetProps): JSX.Element {
|
|||||||
return { selectedWidget, preWidgets, afterWidgets };
|
return { selectedWidget, preWidgets, afterWidgets };
|
||||||
}, [selectedDashboard, query]);
|
}, [selectedDashboard, query]);
|
||||||
|
|
||||||
|
const { notifications } = useNotifications();
|
||||||
|
|
||||||
const onClickSaveHandler = useCallback(() => {
|
const onClickSaveHandler = useCallback(() => {
|
||||||
if (!selectedDashboard) {
|
if (!selectedDashboard) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
updateDashboardMutation.mutateAsync(
|
const dashboard: Dashboard = {
|
||||||
{
|
...selectedDashboard,
|
||||||
uuid: selectedDashboard.uuid,
|
uuid: selectedDashboard.uuid,
|
||||||
data: {
|
data: {
|
||||||
...selectedDashboard.data,
|
...selectedDashboard.data,
|
||||||
widgets: [
|
widgets: [
|
||||||
...preWidgets,
|
...preWidgets,
|
||||||
{
|
{
|
||||||
...(selectedWidget || ({} as Widgets)),
|
...(selectedWidget || ({} as Widgets)),
|
||||||
description,
|
description,
|
||||||
timePreferance: selectedTime.enum,
|
timePreferance: selectedTime.enum,
|
||||||
isStacked: stacked,
|
isStacked: stacked,
|
||||||
opacity,
|
opacity,
|
||||||
nullZeroValues: selectedNullZeroValue,
|
nullZeroValues: selectedNullZeroValue,
|
||||||
title,
|
title,
|
||||||
yAxisUnit,
|
yAxisUnit,
|
||||||
panelTypes: graphType,
|
panelTypes: graphType,
|
||||||
thresholds,
|
thresholds,
|
||||||
},
|
},
|
||||||
...afterWidgets,
|
...afterWidgets,
|
||||||
],
|
],
|
||||||
},
|
|
||||||
},
|
},
|
||||||
{
|
};
|
||||||
onSuccess: () => {
|
|
||||||
featureResponse.refetch();
|
updateDashboardMutation.mutateAsync(dashboard, {
|
||||||
history.push(generatePath(ROUTES.DASHBOARD, { dashboardId }));
|
onSuccess: () => {
|
||||||
},
|
setSelectedDashboard(dashboard);
|
||||||
onError: () => {
|
setToScrollWidgetId(selectedWidget?.id || '');
|
||||||
notifications.error({
|
featureResponse.refetch();
|
||||||
message: SOMETHING_WENT_WRONG,
|
history.push({
|
||||||
});
|
pathname: generatePath(ROUTES.DASHBOARD, { dashboardId }),
|
||||||
},
|
});
|
||||||
},
|
},
|
||||||
);
|
onError: () => {
|
||||||
|
notifications.error({
|
||||||
|
message: SOMETHING_WENT_WRONG,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
}, [
|
}, [
|
||||||
selectedDashboard,
|
selectedDashboard,
|
||||||
updateDashboardMutation,
|
|
||||||
preWidgets,
|
preWidgets,
|
||||||
selectedWidget,
|
selectedWidget,
|
||||||
description,
|
description,
|
||||||
@ -190,6 +197,9 @@ function NewWidget({ selectedGraph }: NewWidgetProps): JSX.Element {
|
|||||||
graphType,
|
graphType,
|
||||||
thresholds,
|
thresholds,
|
||||||
afterWidgets,
|
afterWidgets,
|
||||||
|
updateDashboardMutation,
|
||||||
|
setSelectedDashboard,
|
||||||
|
setToScrollWidgetId,
|
||||||
featureResponse,
|
featureResponse,
|
||||||
dashboardId,
|
dashboardId,
|
||||||
notifications,
|
notifications,
|
||||||
|
@ -48,6 +48,8 @@ const DashboardContext = createContext<IDashboardContext>({
|
|||||||
setLayouts: () => {},
|
setLayouts: () => {},
|
||||||
setSelectedDashboard: () => {},
|
setSelectedDashboard: () => {},
|
||||||
updatedTimeRef: {} as React.MutableRefObject<Dayjs | null>,
|
updatedTimeRef: {} as React.MutableRefObject<Dayjs | null>,
|
||||||
|
toScrollWidgetId: '',
|
||||||
|
setToScrollWidgetId: () => {},
|
||||||
});
|
});
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
@ -59,6 +61,8 @@ export function DashboardProvider({
|
|||||||
}: PropsWithChildren): JSX.Element {
|
}: PropsWithChildren): JSX.Element {
|
||||||
const [isDashboardSliderOpen, setIsDashboardSlider] = useState<boolean>(false);
|
const [isDashboardSliderOpen, setIsDashboardSlider] = useState<boolean>(false);
|
||||||
|
|
||||||
|
const [toScrollWidgetId, setToScrollWidgetId] = useState<string>('');
|
||||||
|
|
||||||
const [isDashboardLocked, setIsDashboardLocked] = useState<boolean>(false);
|
const [isDashboardLocked, setIsDashboardLocked] = useState<boolean>(false);
|
||||||
|
|
||||||
const isDashboardPage = useRouteMatch<Props>({
|
const isDashboardPage = useRouteMatch<Props>({
|
||||||
@ -235,6 +239,7 @@ export function DashboardProvider({
|
|||||||
|
|
||||||
const value: IDashboardContext = useMemo(
|
const value: IDashboardContext = useMemo(
|
||||||
() => ({
|
() => ({
|
||||||
|
toScrollWidgetId,
|
||||||
isDashboardSliderOpen,
|
isDashboardSliderOpen,
|
||||||
isDashboardLocked,
|
isDashboardLocked,
|
||||||
handleToggleDashboardSlider,
|
handleToggleDashboardSlider,
|
||||||
@ -246,6 +251,7 @@ export function DashboardProvider({
|
|||||||
setLayouts,
|
setLayouts,
|
||||||
setSelectedDashboard,
|
setSelectedDashboard,
|
||||||
updatedTimeRef,
|
updatedTimeRef,
|
||||||
|
setToScrollWidgetId,
|
||||||
}),
|
}),
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
[
|
[
|
||||||
@ -255,6 +261,7 @@ export function DashboardProvider({
|
|||||||
selectedDashboard,
|
selectedDashboard,
|
||||||
dashboardId,
|
dashboardId,
|
||||||
layouts,
|
layouts,
|
||||||
|
toScrollWidgetId,
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -17,4 +17,6 @@ export interface IDashboardContext {
|
|||||||
React.SetStateAction<Dashboard | undefined>
|
React.SetStateAction<Dashboard | undefined>
|
||||||
>;
|
>;
|
||||||
updatedTimeRef: React.MutableRefObject<dayjs.Dayjs | null>;
|
updatedTimeRef: React.MutableRefObject<dayjs.Dayjs | null>;
|
||||||
|
toScrollWidgetId: string;
|
||||||
|
setToScrollWidgetId: React.Dispatch<React.SetStateAction<string>>;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user