diff --git a/grafana-plugin/src/containers/RotationForm/RotationForm.tsx b/grafana-plugin/src/containers/RotationForm/RotationForm.tsx index e45fc18698..ef16aed45a 100644 --- a/grafana-plugin/src/containers/RotationForm/RotationForm.tsx +++ b/grafana-plugin/src/containers/RotationForm/RotationForm.tsx @@ -109,6 +109,7 @@ export const RotationForm = observer((props: RotationFormProps) => { const [rotationName, setRotationName] = useState(`[L${layerPriority}] Rotation`); const [isOpen, setIsOpen] = useState(false); const [offsetTop, setOffsetTop] = useState(0); + const [draggablePosition, setDraggablePosition] = useState<{ x: number; y: number }>(undefined); const [shiftStart, setShiftStart] = useState(propsShiftStart); const [shiftEnd, setShiftEnd] = useState(propsShiftEnd || shiftStart.add(1, 'day')); @@ -130,6 +131,14 @@ export const RotationForm = observer((props: RotationFormProps) => { const [userGroups, setUserGroups] = useState([]); const [showDeleteRotationConfirmation, setShowDeleteRotationConfirmation] = useState(false); + const debouncedOnResize = useDebouncedCallback(onResize, 250); + + useEffect(() => { + window.addEventListener('resize', debouncedOnResize); + return () => { + window.removeEventListener('resize', debouncedOnResize); + }; + }, []); useEffect(() => { if (rotationStart.isBefore(shiftStart)) { @@ -146,16 +155,7 @@ export const RotationForm = observer((props: RotationFormProps) => { useEffect(() => { (async () => { if (isOpen) { - const elm = await waitForElement(`#layer${shiftId === 'new' ? layerPriority : shift?.priority_level}`); - const modal = document.querySelector(`.${cx('draggable')}`) as HTMLDivElement; - const coords = getCoords(elm); - - const offsetTop = Math.max( - Math.min(coords.top - modal?.offsetHeight - 10, document.body.offsetHeight - modal?.offsetHeight - 10), - GRAFANA_HEADER_HEIGHT + 10 - ); - - setOffsetTop(offsetTop); + setOffsetTop(await calculateOffsetTop()); } })(); }, [isOpen]); @@ -480,13 +480,6 @@ export const RotationForm = observer((props: RotationFormProps) => { } }, [store.timezoneStore.selectedTimezoneOffset]); - useEffect(() => { - window.addEventListener('resize', onResize); - return () => { - window.removeEventListener('resize', onResize); - }; - }, []); - const isFormValid = useMemo(() => !Object.keys(errors).length, [errors]); const hasUpdatedShift = shift && shift.updated_shift; @@ -506,8 +499,10 @@ export const RotationForm = observer((props: RotationFormProps) => { handle=".drag-handler" defaultClassName={cx('draggable')} positionOffset={{ x: 0, y: offsetTop }} + position={draggablePosition} bounds={{ ...bounds } || 'body'} onStart={onDraggableInit} + onStop={(_e, data) => setDraggablePosition({ x: data.x, y: data.y })} >
{children}
@@ -765,8 +760,21 @@ export const RotationForm = observer((props: RotationFormProps) => { ); - function onResize() { - onHide(); + async function onResize() { + setDraggablePosition({ x: 0, y: await calculateOffsetTop() }); + } + + async function calculateOffsetTop(): Promise { + const elm = await waitForElement(`#layer${shiftId === 'new' ? layerPriority : shift?.priority_level}`); + const modal = document.querySelector(`.${cx('draggable')}`) as HTMLDivElement; + const coords = getCoords(elm); + + const offsetTop = Math.max( + Math.min(coords.top - modal?.offsetHeight - 10, document.body.offsetHeight - modal?.offsetHeight - 10), + GRAFANA_HEADER_HEIGHT + 10 + ); + + return offsetTop; } function onDraggableInit(_e: DraggableEvent, data: DraggableData) { diff --git a/grafana-plugin/src/containers/Rotations/ScheduleFinal.tsx b/grafana-plugin/src/containers/Rotations/ScheduleFinal.tsx index 51837b6f8d..2329d91f79 100644 --- a/grafana-plugin/src/containers/Rotations/ScheduleFinal.tsx +++ b/grafana-plugin/src/containers/Rotations/ScheduleFinal.tsx @@ -1,4 +1,4 @@ -import React, { FC, useEffect } from 'react'; +import React, { FC } from 'react'; import { HorizontalGroup } from '@grafana/ui'; import cn from 'classnames/bind'; @@ -40,8 +40,7 @@ interface ScheduleFinalProps extends WithStoreProps { const _ScheduleFinal: FC = observer( ({ store, simplified, scheduleId, filters, onShowShiftSwapForm, onShowOverrideForm, onSlotClick }) => { const { - timezoneStore: { currentDateInSelectedTimezone, calendarStartDate, selectedTimezoneOffset }, - scheduleStore: { refreshEvents }, + timezoneStore: { currentDateInSelectedTimezone, calendarStartDate }, } = store; const base = 7 * 24 * 60; // in minutes const diff = currentDateInSelectedTimezone.diff(calendarStartDate, 'minutes'); @@ -62,10 +61,6 @@ const _ScheduleFinal: FC = observer( onShowOverrideForm('new', shiftStart, shiftEnd); }; - useEffect(() => { - refreshEvents(scheduleId); - }, [selectedTimezoneOffset]); - return (
{!simplified && ( diff --git a/grafana-plugin/src/containers/UserTimezoneSelect/UserTimezoneSelect.tsx b/grafana-plugin/src/containers/UserTimezoneSelect/UserTimezoneSelect.tsx index b4aef8325f..a340daeb51 100644 --- a/grafana-plugin/src/containers/UserTimezoneSelect/UserTimezoneSelect.tsx +++ b/grafana-plugin/src/containers/UserTimezoneSelect/UserTimezoneSelect.tsx @@ -23,9 +23,10 @@ interface TimezoneOption { interface UserTimezoneSelectProps { scheduleId?: string; + onChange: (value: number) => void; } -export const UserTimezoneSelect: FC = observer(({ scheduleId }) => { +export const UserTimezoneSelect: FC = observer(({ scheduleId, onChange }) => { const store = useStore(); const users = UserHelper.getSearchResult(store.userStore).results || []; @@ -107,9 +108,6 @@ export const UserTimezoneSelect: FC = observer(({ sched description: '', }, ]); - - store.timezoneStore.setSelectedTimezoneOffset(utcOffset); - store.scheduleStore.refreshEvents(scheduleId); } }, [options] @@ -119,7 +117,11 @@ export const UserTimezoneSelect: FC = observer(({ sched