feat: element is made into focus and scrolled into view after edit/save (#4046)

This commit is contained in:
Palash Gupta 2023-11-29 18:21:26 +05:30 committed by GitHub
parent ae3b604cdc
commit 1f0fdfd403
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 72 additions and 40 deletions

View File

@ -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

View File

@ -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"

View File

@ -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,13 +137,15 @@ 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,
@ -162,22 +166,25 @@ function NewWidget({ selectedGraph }: NewWidgetProps): JSX.Element {
...afterWidgets, ...afterWidgets,
], ],
}, },
}, };
{
updateDashboardMutation.mutateAsync(dashboard, {
onSuccess: () => { onSuccess: () => {
setSelectedDashboard(dashboard);
setToScrollWidgetId(selectedWidget?.id || '');
featureResponse.refetch(); featureResponse.refetch();
history.push(generatePath(ROUTES.DASHBOARD, { dashboardId })); history.push({
pathname: generatePath(ROUTES.DASHBOARD, { dashboardId }),
});
}, },
onError: () => { onError: () => {
notifications.error({ notifications.error({
message: SOMETHING_WENT_WRONG, 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,

View File

@ -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,
], ],
); );

View File

@ -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>>;
} }