diff --git a/grafana-plugin/src/components/Modal/Modal.tsx b/grafana-plugin/src/components/Modal/Modal.tsx index 5f6352ce..b26cafaa 100644 --- a/grafana-plugin/src/components/Modal/Modal.tsx +++ b/grafana-plugin/src/components/Modal/Modal.tsx @@ -1,6 +1,7 @@ import React, { FC, PropsWithChildren } from 'react'; -import ReactModal from 'react-modal'; + import cn from 'classnames/bind'; +import ReactModal from 'react-modal'; import styles from './Modal.module.css'; @@ -13,12 +14,13 @@ export interface ModalProps { onDismiss?: () => void; width: string; contentElement?: (props, children: React.ReactNode) => React.ReactNode; + isOpen: boolean; } const cx = cn.bind(styles); const Modal: FC> = (props) => { - const { title, children, onDismiss, width = '600px', contentElement } = props; + const { title, children, onDismiss, width = '600px', contentElement, isOpen = true } = props; return ( > = (props) => { width, }, }} - isOpen + isOpen={isOpen} onAfterOpen={() => {}} onRequestClose={onDismiss} contentLabel={title} diff --git a/grafana-plugin/src/containers/RotationForm/RotationForm.tsx b/grafana-plugin/src/containers/RotationForm/RotationForm.tsx index 36a18cf8..df652fe0 100644 --- a/grafana-plugin/src/containers/RotationForm/RotationForm.tsx +++ b/grafana-plugin/src/containers/RotationForm/RotationForm.tsx @@ -55,6 +55,8 @@ const startOfDay = dayjs().startOf('day').add(1, 'day'); const RotationForm: FC = observer((props) => { const { onHide, onCreate, startMoment, currentTimezone, scheduleId, onUpdate, layerPriority, shiftId } = props; + const [isOpen, setIsOpen] = useState(true); + const [repeatEveryValue, setRepeatEveryValue] = useState(1); const [repeatEveryPeriod, setRepeatEveryPeriod] = useState(0); const [selectedDays, setSelectedDays] = useState([]); @@ -135,7 +137,11 @@ const RotationForm: FC = observer((props) => { }, [shiftId, params]); const handleChange = useDebouncedCallback(() => { - store.scheduleStore.updateRotationPreview(scheduleId, shiftId, getFromString(startMoment), false, params); + store.scheduleStore + .updateRotationPreview(scheduleId, shiftId, getFromString(startMoment), false, params) + .finally(() => { + setIsOpen(true); + }); }, 1000); useEffect(handleChange, [params]); @@ -175,6 +181,7 @@ const RotationForm: FC = observer((props) => { return ( ( diff --git a/grafana-plugin/src/containers/Rotations/Rotations.tsx b/grafana-plugin/src/containers/Rotations/Rotations.tsx index 02ea59ec..bae5e108 100644 --- a/grafana-plugin/src/containers/Rotations/Rotations.tsx +++ b/grafana-plugin/src/containers/Rotations/Rotations.tsx @@ -56,15 +56,53 @@ class Rotations extends Component { const storeLayers = store.scheduleStore.events[scheduleId]?.['rotation']?.[getFromString(startMoment)] as Layer[]; + console.log('store.scheduleStore.rotationPreview', store.scheduleStore.rotationPreview); + let layers = storeLayers; if (store.scheduleStore.rotationPreview) { - layers = [...layers, { priority: 2, shifts: [store.scheduleStore.rotationPreview] }]; + layers = [...layers]; + + const isNew = store.scheduleStore.rotationPreview.shifts[0].shiftId === 'new'; + const priority = store.scheduleStore.rotationPreview.priority; + + let added = false; + layers = layers.reduce((memo, layer, index) => { + if (isNew) { + if (layer.priority === priority) { + const newLayer = { ...layer }; + newLayer.shifts = [...layer.shifts, ...store.scheduleStore.rotationPreview.shifts]; + + memo[index] = newLayer; + + added = true; + } + } else { + const oldShiftIndex = layer.shifts.findIndex( + (shift) => shift.shiftId === store.scheduleStore.rotationPreview.shifts[0].shiftId + ); + if (oldShiftIndex > -1) { + const newLayer = { ...layer }; + newLayer.shifts = [...layer.shifts]; + newLayer.shifts[oldShiftIndex] = store.scheduleStore.rotationPreview.shifts[0]; + + memo[index] = newLayer; + + added = true; + } + } + + return layers; + }, layers); + + if (!added) { + layers.push(store.scheduleStore.rotationPreview); + } } const options = layers ? layers.map((layer) => ({ label: `Layer ${layer.priority}`, - value: layer.priority - 1, + value: layer.priority, })) : []; @@ -180,6 +218,8 @@ class Rotations extends Component { const { store } = this.props; store.scheduleStore.rotationPreview = undefined; + store.scheduleStore.finalPreview = undefined; + this.setState({ shiftIdToShowRotationForm: undefined, layerPriority: undefined }); }; diff --git a/grafana-plugin/src/containers/Rotations/ScheduleFinal.tsx b/grafana-plugin/src/containers/Rotations/ScheduleFinal.tsx index 752f4123..b680c2eb 100644 --- a/grafana-plugin/src/containers/Rotations/ScheduleFinal.tsx +++ b/grafana-plugin/src/containers/Rotations/ScheduleFinal.tsx @@ -43,7 +43,9 @@ class ScheduleFinal extends Component 1; diff --git a/grafana-plugin/src/models/schedule/schedule.ts b/grafana-plugin/src/models/schedule/schedule.ts index f268b4a7..c3b251dd 100644 --- a/grafana-plugin/src/models/schedule/schedule.ts +++ b/grafana-plugin/src/models/schedule/schedule.ts @@ -72,10 +72,10 @@ export class ScheduleStore extends BaseStore { }; } = {}; - @observable.shallow - rotationPreview?: { shiftId: Shift['id']; events: Event[] }; + @observable + rotationPreview?: Layer; - @observable.shallow + @observable finalPreview?: Array<{ shiftId: Shift['id']; events: Event[] }>; @observable @@ -210,8 +210,11 @@ export class ScheduleStore extends BaseStore { method: 'POST', }).catch(this.onApiError); - this.rotationPreview = { shiftId: shiftId, events: fillGaps(response.rotation.filter((event) => !event.is_gap)) }; - this.finalPreview = splitToShiftsAndFillGaps(response.final); + this.rotationPreview = { + priority: params.priority_level, + shifts: [{ shiftId: shiftId, events: fillGaps(response.rotation.filter((event) => !event.is_gap)) }], + }; + this.finalPreview = splitToShiftsAndFillGaps(response.final).filter((shift) => shift.shiftId !== shiftId); } async updateRotation(shiftId: Shift['id'], params: Partial) {