From 1f0fdfd403998cc973c9ce606cf6d5b1fc1e8502 Mon Sep 17 00:00:00 2001 From: Palash Gupta Date: Wed, 29 Nov 2023 18:21:26 +0530 Subject: [PATCH] feat: element is made into focus and scrolled into view after edit/save (#4046) --- .../GridCardLayout/GridCard/index.tsx | 15 +++- .../GridCardLayout/GridCardLayout.tsx | 2 +- frontend/src/container/NewWidget/index.tsx | 86 +++++++++++-------- .../src/providers/Dashboard/Dashboard.tsx | 7 ++ frontend/src/providers/Dashboard/types.ts | 2 + 5 files changed, 72 insertions(+), 40 deletions(-) diff --git a/frontend/src/container/GridCardLayout/GridCard/index.tsx b/frontend/src/container/GridCardLayout/GridCard/index.tsx index bb8a8453e7..d1b7e024bf 100644 --- a/frontend/src/container/GridCardLayout/GridCard/index.tsx +++ b/frontend/src/container/GridCardLayout/GridCard/index.tsx @@ -9,7 +9,8 @@ import { getUPlotChartOptions } from 'lib/uPlotLib/getUplotChartOptions'; import { getUPlotChartData } from 'lib/uPlotLib/utils/getUplotChartData'; import isEmpty from 'lodash-es/isEmpty'; 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 { UpdateTimeInterval } from 'store/actions'; import { AppState } from 'store/reducers'; @@ -32,6 +33,7 @@ function GridCardGraph({ }: GridCardGraphProps): JSX.Element { const dispatch = useDispatch(); const [errorMessage, setErrorMessage] = useState(); + const { toScrollWidgetId, setToScrollWidgetId } = useDashboard(); const onDragSelect = useCallback( (start: number, end: number): void => { @@ -49,6 +51,17 @@ function GridCardGraph({ 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< AppState, GlobalReducer diff --git a/frontend/src/container/GridCardLayout/GridCardLayout.tsx b/frontend/src/container/GridCardLayout/GridCardLayout.tsx index 5cebd36c0e..93c779f93f 100644 --- a/frontend/src/container/GridCardLayout/GridCardLayout.tsx +++ b/frontend/src/container/GridCardLayout/GridCardLayout.tsx @@ -165,7 +165,7 @@ function GraphLayout({ onAddPanelHandler }: GraphLayoutProps): JSX.Element { className={isDashboardLocked ? '' : 'enable-resize'} isDarkMode={isDarkMode} key={id} - data-grid={layout} + data-grid={JSON.stringify(currentWidget)} > { @@ -135,49 +137,54 @@ function NewWidget({ selectedGraph }: NewWidgetProps): JSX.Element { return { selectedWidget, preWidgets, afterWidgets }; }, [selectedDashboard, query]); + const { notifications } = useNotifications(); + const onClickSaveHandler = useCallback(() => { if (!selectedDashboard) { return; } - updateDashboardMutation.mutateAsync( - { - uuid: selectedDashboard.uuid, - data: { - ...selectedDashboard.data, - widgets: [ - ...preWidgets, - { - ...(selectedWidget || ({} as Widgets)), - description, - timePreferance: selectedTime.enum, - isStacked: stacked, - opacity, - nullZeroValues: selectedNullZeroValue, - title, - yAxisUnit, - panelTypes: graphType, - thresholds, - }, - ...afterWidgets, - ], - }, + const dashboard: Dashboard = { + ...selectedDashboard, + uuid: selectedDashboard.uuid, + data: { + ...selectedDashboard.data, + widgets: [ + ...preWidgets, + { + ...(selectedWidget || ({} as Widgets)), + description, + timePreferance: selectedTime.enum, + isStacked: stacked, + opacity, + nullZeroValues: selectedNullZeroValue, + title, + yAxisUnit, + panelTypes: graphType, + thresholds, + }, + ...afterWidgets, + ], }, - { - onSuccess: () => { - featureResponse.refetch(); - history.push(generatePath(ROUTES.DASHBOARD, { dashboardId })); - }, - onError: () => { - notifications.error({ - message: SOMETHING_WENT_WRONG, - }); - }, + }; + + updateDashboardMutation.mutateAsync(dashboard, { + onSuccess: () => { + setSelectedDashboard(dashboard); + setToScrollWidgetId(selectedWidget?.id || ''); + featureResponse.refetch(); + history.push({ + pathname: generatePath(ROUTES.DASHBOARD, { dashboardId }), + }); }, - ); + onError: () => { + notifications.error({ + message: SOMETHING_WENT_WRONG, + }); + }, + }); }, [ selectedDashboard, - updateDashboardMutation, preWidgets, selectedWidget, description, @@ -190,6 +197,9 @@ function NewWidget({ selectedGraph }: NewWidgetProps): JSX.Element { graphType, thresholds, afterWidgets, + updateDashboardMutation, + setSelectedDashboard, + setToScrollWidgetId, featureResponse, dashboardId, notifications, diff --git a/frontend/src/providers/Dashboard/Dashboard.tsx b/frontend/src/providers/Dashboard/Dashboard.tsx index d9d3b8bdc3..4365b6c35b 100644 --- a/frontend/src/providers/Dashboard/Dashboard.tsx +++ b/frontend/src/providers/Dashboard/Dashboard.tsx @@ -48,6 +48,8 @@ const DashboardContext = createContext({ setLayouts: () => {}, setSelectedDashboard: () => {}, updatedTimeRef: {} as React.MutableRefObject, + toScrollWidgetId: '', + setToScrollWidgetId: () => {}, }); interface Props { @@ -59,6 +61,8 @@ export function DashboardProvider({ }: PropsWithChildren): JSX.Element { const [isDashboardSliderOpen, setIsDashboardSlider] = useState(false); + const [toScrollWidgetId, setToScrollWidgetId] = useState(''); + const [isDashboardLocked, setIsDashboardLocked] = useState(false); const isDashboardPage = useRouteMatch({ @@ -235,6 +239,7 @@ export function DashboardProvider({ const value: IDashboardContext = useMemo( () => ({ + toScrollWidgetId, isDashboardSliderOpen, isDashboardLocked, handleToggleDashboardSlider, @@ -246,6 +251,7 @@ export function DashboardProvider({ setLayouts, setSelectedDashboard, updatedTimeRef, + setToScrollWidgetId, }), // eslint-disable-next-line react-hooks/exhaustive-deps [ @@ -255,6 +261,7 @@ export function DashboardProvider({ selectedDashboard, dashboardId, layouts, + toScrollWidgetId, ], ); diff --git a/frontend/src/providers/Dashboard/types.ts b/frontend/src/providers/Dashboard/types.ts index 11e2da2212..a8e249015e 100644 --- a/frontend/src/providers/Dashboard/types.ts +++ b/frontend/src/providers/Dashboard/types.ts @@ -17,4 +17,6 @@ export interface IDashboardContext { React.SetStateAction >; updatedTimeRef: React.MutableRefObject; + toScrollWidgetId: string; + setToScrollWidgetId: React.Dispatch>; }