Skip to content

Commit

Permalink
Remove schedule events duplicate requests and ignore window.resize (#…
Browse files Browse the repository at this point in the history
…4307)

# What this PR does

Remove schedule events duplicate requests

## Which issue(s) this PR closes


## Checklist

- [ ] Unit, integration, and e2e (if applicable) tests updated
- [x] Documentation added (or `pr:no public docs` PR label added if not
required)
- [x] Added the relevant release notes label (see labels prefixed w/
`release:`). These labels dictate how your PR will
    show up in the autogenerated release notes.

---------

Co-authored-by: Rares Mardare <rares.mardare@grafana.com>
  • Loading branch information
maskin25 and teodosii committed May 20, 2024
1 parent 3e4407b commit 5544769
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 36 deletions.
46 changes: 27 additions & 19 deletions grafana-plugin/src/containers/RotationForm/RotationForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ export const RotationForm = observer((props: RotationFormProps) => {
const [rotationName, setRotationName] = useState<string>(`[L${layerPriority}] Rotation`);
const [isOpen, setIsOpen] = useState<boolean>(false);
const [offsetTop, setOffsetTop] = useState<number>(0);
const [draggablePosition, setDraggablePosition] = useState<{ x: number; y: number }>(undefined);

const [shiftStart, setShiftStart] = useState<dayjs.Dayjs>(propsShiftStart);
const [shiftEnd, setShiftEnd] = useState<dayjs.Dayjs>(propsShiftEnd || shiftStart.add(1, 'day'));
Expand All @@ -130,6 +131,14 @@ export const RotationForm = observer((props: RotationFormProps) => {
const [userGroups, setUserGroups] = useState([]);

const [showDeleteRotationConfirmation, setShowDeleteRotationConfirmation] = useState<boolean>(false);
const debouncedOnResize = useDebouncedCallback(onResize, 250);

useEffect(() => {
window.addEventListener('resize', debouncedOnResize);
return () => {
window.removeEventListener('resize', debouncedOnResize);
};
}, []);

useEffect(() => {
if (rotationStart.isBefore(shiftStart)) {
Expand All @@ -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]);
Expand Down Expand Up @@ -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;
Expand All @@ -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 })}
>
<div {...props}>{children}</div>
</Draggable>
Expand Down Expand Up @@ -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<number> {
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) {
Expand Down
9 changes: 2 additions & 7 deletions grafana-plugin/src/containers/Rotations/ScheduleFinal.tsx
Original file line number Diff line number Diff line change
@@ -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';
Expand Down Expand Up @@ -40,8 +40,7 @@ interface ScheduleFinalProps extends WithStoreProps {
const _ScheduleFinal: FC<ScheduleFinalProps> = 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');
Expand All @@ -62,10 +61,6 @@ const _ScheduleFinal: FC<ScheduleFinalProps> = observer(
onShowOverrideForm('new', shiftStart, shiftEnd);
};

useEffect(() => {
refreshEvents(scheduleId);
}, [selectedTimezoneOffset]);

return (
<div className={cx('root')}>
{!simplified && (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,10 @@ interface TimezoneOption {

interface UserTimezoneSelectProps {
scheduleId?: string;
onChange: (value: number) => void;
}

export const UserTimezoneSelect: FC<UserTimezoneSelectProps> = observer(({ scheduleId }) => {
export const UserTimezoneSelect: FC<UserTimezoneSelectProps> = observer(({ scheduleId, onChange }) => {
const store = useStore();
const users = UserHelper.getSearchResult(store.userStore).results || [];

Expand Down Expand Up @@ -107,9 +108,6 @@ export const UserTimezoneSelect: FC<UserTimezoneSelectProps> = observer(({ sched
description: '',
},
]);

store.timezoneStore.setSelectedTimezoneOffset(utcOffset);
store.scheduleStore.refreshEvents(scheduleId);
}
},
[options]
Expand All @@ -119,7 +117,11 @@ export const UserTimezoneSelect: FC<UserTimezoneSelectProps> = observer(({ sched
<div className={cx('root')} data-testid="timezone-select">
<Select
value={selectedOption}
onChange={(option) => store.timezoneStore.setSelectedTimezoneOffset(option.value)}
onChange={(option) => {
store.timezoneStore.setSelectedTimezoneOffset(option.value);

onChange(option.value);
}}
width={30}
options={options}
filterOption={filterOption}
Expand Down
2 changes: 1 addition & 1 deletion grafana-plugin/src/pages/schedule/Schedule.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ class _SchedulePage extends React.Component<SchedulePageProps, SchedulePageState
{users && (
<HorizontalGroup>
<Text type="secondary">Current timezone:</Text>
<UserTimezoneSelect scheduleId={scheduleId} />
<UserTimezoneSelect scheduleId={scheduleId} onChange={this.handleDateRangeUpdate} />
</HorizontalGroup>
)}
<HorizontalGroup>
Expand Down
12 changes: 8 additions & 4 deletions grafana-plugin/src/pages/schedules/Schedules.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ class _SchedulesPage extends React.Component<SchedulesPageProps, SchedulesPageSt
<HorizontalGroup justify="space-between">
<Text.Title level={3}>Schedules</Text.Title>
<div className={cx('schedules__actions')}>
<UserTimezoneSelect />
<UserTimezoneSelect onChange={this.refreshExpandedSchedules} />
<WithPermissionControlTooltip userAction={UserActions.SchedulesWrite}>
<Button variant="primary" onClick={this.handleCreateScheduleClick}>
+ New schedule
Expand Down Expand Up @@ -171,12 +171,16 @@ class _SchedulesPage extends React.Component<SchedulesPageProps, SchedulesPageSt
const index = expandedRowKeys.indexOf(data.id);
const newExpandedRowKeys = [...expandedRowKeys];
newExpandedRowKeys.splice(index, 1);
this.setState({ expandedRowKeys: newExpandedRowKeys }, () => {
this.props.store.scheduleStore.refreshEvents(data.id);
});
this.setState({ expandedRowKeys: newExpandedRowKeys });
}
};

refreshExpandedSchedules = () => {
const { expandedRowKeys } = this.state;

expandedRowKeys.forEach(this.props.store.scheduleStore.refreshEvents);
};

renderSchedule = (data: Schedule) => (
<div className={cx('schedule')}>
<TimelineMarks />
Expand Down

0 comments on commit 5544769

Please sign in to comment.