render rotation with real data
This commit is contained in:
parent
87994ae23d
commit
9ca33114d2
13 changed files with 227 additions and 84 deletions
|
|
@ -21,9 +21,9 @@ const cx = cn.bind(styles);
|
|||
interface RotationsProps {
|
||||
startMoment: dayjs.Dayjs;
|
||||
currentTimezone: Timezone;
|
||||
onCreate: (date: RotationCreateData) => void;
|
||||
scheduleId: Schedule['id'];
|
||||
onRotationUpdate: () => void;
|
||||
onCreate: () => void;
|
||||
onUpdate: () => void;
|
||||
}
|
||||
|
||||
type Layer = {
|
||||
|
|
@ -40,7 +40,7 @@ class Rotations extends Component<RotationsProps, RotationsState> {
|
|||
};
|
||||
|
||||
render() {
|
||||
const { startMoment, currentTimezone, scheduleId, onRotationUpdate } = this.props;
|
||||
const { scheduleId, startMoment, currentTimezone, onCreate, onUpdate } = this.props;
|
||||
const { layerIdToCreateRotation } = this.state;
|
||||
|
||||
const layers = [
|
||||
|
|
@ -115,8 +115,8 @@ class Rotations extends Component<RotationsProps, RotationsState> {
|
|||
onHide={() => {
|
||||
this.setState({ layerIdToCreateRotation: undefined });
|
||||
}}
|
||||
onUpdate={onRotationUpdate}
|
||||
onCreate={this.onRotationCreate}
|
||||
onUpdate={onCreate}
|
||||
onCreate={onUpdate}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
|
|
@ -125,12 +125,6 @@ class Rotations extends Component<RotationsProps, RotationsState> {
|
|||
|
||||
updateEvents = () => {};
|
||||
|
||||
onRotationCreate = (data: RotationCreateData) => {
|
||||
const { onCreate } = this.props;
|
||||
|
||||
onCreate(data);
|
||||
};
|
||||
|
||||
handleAddLayer = () => {};
|
||||
|
||||
handleAddRotation = (option) => {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import React, { Component } from 'react';
|
||||
import React, { Component, useEffect } from 'react';
|
||||
|
||||
import { Button, HorizontalGroup, Icon, Input, ValuePicker } from '@grafana/ui';
|
||||
import cn from 'classnames/bind';
|
||||
|
|
@ -9,6 +9,8 @@ import RotationForm from 'components/RotationForm/RotationForm';
|
|||
import ScheduleOverrideForm from 'components/ScheduleOverrideForm/ScheduleOverrideForm';
|
||||
import TimelineMarks from 'components/TimelineMarks/TimelineMarks';
|
||||
import Rotation from 'containers/Rotation/Rotation';
|
||||
import { Schedule } from 'models/schedule/schedule.types';
|
||||
import { Timezone } from 'models/timezone/timezone.types';
|
||||
import { WithStoreProps } from 'state/types';
|
||||
import { withMobXProviderContext } from 'state/withStore';
|
||||
|
||||
|
|
@ -16,7 +18,11 @@ import styles from './Rotations.module.css';
|
|||
|
||||
const cx = cn.bind(styles);
|
||||
|
||||
interface ScheduleOverridesProps extends WithStoreProps {}
|
||||
interface ScheduleOverridesProps extends WithStoreProps {
|
||||
startMoment: dayjs.Dayjs;
|
||||
currentTimezone: Timezone;
|
||||
scheduleId: Schedule['id'];
|
||||
}
|
||||
|
||||
interface ScheduleOverridesState {}
|
||||
|
||||
|
|
@ -24,8 +30,18 @@ interface ScheduleOverridesState {}
|
|||
class ScheduleOverrides extends Component<ScheduleOverridesProps, ScheduleOverridesState> {
|
||||
state: ScheduleOverridesState = {};
|
||||
|
||||
componentDidMount() {
|
||||
const { store, scheduleId, startMoment, currentTimezone } = this.props;
|
||||
|
||||
const {} = this.props;
|
||||
|
||||
const startMomentString = startMoment.utc().format('YYYY-MM-DD');
|
||||
|
||||
store.scheduleStore.updateEvents(scheduleId, startMomentString, 'final');
|
||||
}
|
||||
|
||||
render() {
|
||||
const { title, startMoment, currentTimezone } = this.props;
|
||||
const { scheduleId, startMoment, currentTimezone, store } = this.props;
|
||||
const { showAddOverrideForm, searchTerm } = this.state;
|
||||
|
||||
const base = 7 * 24 * 60; // in minutes
|
||||
|
|
@ -52,7 +68,8 @@ class ScheduleOverrides extends Component<ScheduleOverridesProps, ScheduleOverri
|
|||
<TimelineMarks startMoment={startMoment} />
|
||||
<div className={cx('rotations')}>
|
||||
<Rotation
|
||||
id="final"
|
||||
type="final"
|
||||
scheduleId={scheduleId}
|
||||
startMoment={startMoment}
|
||||
currentTimezone={currentTimezone}
|
||||
layerIndex={0}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,10 @@ import { observer } from 'mobx-react';
|
|||
|
||||
import TimelineMarks from 'components/TimelineMarks/TimelineMarks';
|
||||
import Rotation from 'containers/Rotation/Rotation';
|
||||
import { RotationCreateData } from 'containers/RotationForm/RotationForm.types';
|
||||
import ScheduleOverrideForm from 'containers/RotationForm/ScheduleOverrideForm';
|
||||
import { Schedule } from 'models/schedule/schedule.types';
|
||||
import { Timezone } from 'models/timezone/timezone.types';
|
||||
import { WithStoreProps } from 'state/types';
|
||||
import { withMobXProviderContext } from 'state/withStore';
|
||||
|
||||
|
|
@ -15,7 +18,13 @@ import styles from './Rotations.module.css';
|
|||
|
||||
const cx = cn.bind(styles);
|
||||
|
||||
interface ScheduleOverridesProps extends WithStoreProps {}
|
||||
interface ScheduleOverridesProps extends WithStoreProps {
|
||||
startMoment: dayjs.Dayjs;
|
||||
currentTimezone: Timezone;
|
||||
scheduleId: Schedule['id'];
|
||||
onCreate: () => void;
|
||||
onUpdate: () => void;
|
||||
}
|
||||
|
||||
interface ScheduleOverridesState {}
|
||||
|
||||
|
|
@ -24,7 +33,7 @@ class ScheduleOverrides extends Component<ScheduleOverridesProps, ScheduleOverri
|
|||
state: ScheduleOverridesState = {};
|
||||
|
||||
render() {
|
||||
const { title, startMoment, currentTimezone } = this.props;
|
||||
const { scheduleId, startMoment, currentTimezone, onCreate, onUpdate } = this.props;
|
||||
const { showAddOverrideForm } = this.state;
|
||||
|
||||
const base = 7 * 24 * 60; // in minutes
|
||||
|
|
@ -54,9 +63,13 @@ class ScheduleOverrides extends Component<ScheduleOverridesProps, ScheduleOverri
|
|||
</div>
|
||||
{showAddOverrideForm && (
|
||||
<ScheduleOverrideForm
|
||||
scheduleId={scheduleId}
|
||||
currentTimezone={currentTimezone}
|
||||
onHide={() => {
|
||||
this.setState({ showAddOverrideForm: false });
|
||||
}}
|
||||
onUpdate={onCreate}
|
||||
onCreate={onUpdate}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import { observer } from 'mobx-react';
|
|||
import Line from 'components/ScheduleUserDetails/img/line.svg';
|
||||
import Text from 'components/Text/Text';
|
||||
import WorkingHours from 'components/WorkingHours/WorkingHours';
|
||||
import { Shift } from 'models/schedule/schedule.types';
|
||||
import { Event } from 'models/schedule/schedule.types';
|
||||
import { Timezone } from 'models/timezone/timezone.types';
|
||||
import { User } from 'models/user/user.types';
|
||||
import { useStore } from 'state/useStore';
|
||||
|
|
@ -21,7 +21,7 @@ interface ScheduleSlotProps {
|
|||
index: number;
|
||||
layerIndex: number;
|
||||
rotationIndex: number;
|
||||
shift: Shift;
|
||||
event: Event;
|
||||
startMoment: dayjs.Dayjs;
|
||||
currentTimezone: Timezone;
|
||||
color?: string;
|
||||
|
|
@ -30,8 +30,13 @@ interface ScheduleSlotProps {
|
|||
const cx = cn.bind(styles);
|
||||
|
||||
const ScheduleSlot: FC<ScheduleSlotProps> = observer((props) => {
|
||||
const { index, layerIndex, rotationIndex, shift, startMoment, currentTimezone, color: propColor, x, basePx } = props;
|
||||
const { duration, users } = shift;
|
||||
const { index, layerIndex, rotationIndex, event, startMoment, currentTimezone, color: propColor } = props;
|
||||
const { users } = event;
|
||||
|
||||
const start = dayjs(event.start);
|
||||
const end = dayjs(event.end);
|
||||
|
||||
const duration = end.diff(start, 'seconds');
|
||||
|
||||
const store = useStore();
|
||||
|
||||
|
|
@ -43,9 +48,9 @@ const ScheduleSlot: FC<ScheduleSlotProps> = observer((props) => {
|
|||
|
||||
return (
|
||||
<div className={cx('stack')} style={{ width: `${width * 100}%` /*left: `${x * 100}%`*/ }}>
|
||||
{!shift.is_gap ? (
|
||||
users.map((pk, userIndex) => {
|
||||
const storeUser = store.userStore.items[pk];
|
||||
{!event.is_gap ? (
|
||||
users.map(({ pk: userPk }, userIndex) => {
|
||||
const storeUser = store.userStore.items[userPk];
|
||||
|
||||
const inactive = false;
|
||||
|
||||
|
|
@ -64,10 +69,10 @@ const ScheduleSlot: FC<ScheduleSlotProps> = observer((props) => {
|
|||
<WorkingHours
|
||||
className={cx('working-hours')}
|
||||
// timezone={storeUser.timezone}
|
||||
timezone={['America/Vancouver', 'Europe/London'][userIndex]}
|
||||
timezone={storeUser.timezone}
|
||||
//workingHours={storeUser.working_hours}
|
||||
startMoment={shift.start}
|
||||
duration={shift.duration}
|
||||
startMoment={start}
|
||||
duration={duration}
|
||||
/>
|
||||
)}
|
||||
{userIndex === 0 && label && (
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ interface WorkingHoursProps {
|
|||
workingHours: any;
|
||||
startMoment: dayjs.Dayjs;
|
||||
duration: number; // in seconds
|
||||
width: number; // in pixels
|
||||
className: string;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import { CSSTransitionGroup } from 'react-transition-group'; // ES6
|
|||
|
||||
import ScheduleSlot from 'components/ScheduleSlot/ScheduleSlot';
|
||||
import Text from 'components/Text/Text';
|
||||
import { Rotation as RotationType } from 'models/schedule/schedule.types';
|
||||
import { Rotation as RotationType, Schedule } from 'models/schedule/schedule.types';
|
||||
import { Timezone } from 'models/timezone/timezone.types';
|
||||
import { useStore } from 'state/useStore';
|
||||
import { usePrevious } from 'utils/hooks';
|
||||
|
|
@ -20,7 +20,8 @@ const cx = cn.bind(styles);
|
|||
interface ScheduleSlotState {}
|
||||
|
||||
interface RotationProps {
|
||||
id: RotationType['id'];
|
||||
type: 'final' | 'rotation' | 'override';
|
||||
scheduleId: Schedule['id'];
|
||||
label: string;
|
||||
startMoment: dayjs.Dayjs;
|
||||
currentTimezone: Timezone;
|
||||
|
|
@ -30,7 +31,7 @@ interface RotationProps {
|
|||
}
|
||||
|
||||
const Rotation: FC<RotationProps> = observer((props) => {
|
||||
const { id, layerIndex, rotationIndex, label, startMoment, currentTimezone, color } = props;
|
||||
const { type, scheduleId, layerIndex, rotationIndex, label, startMoment, currentTimezone, color } = props;
|
||||
|
||||
const [animate, setAnimate] = useState<boolean>(true);
|
||||
const [width, setWidth] = useState<number | undefined>();
|
||||
|
|
@ -38,12 +39,15 @@ const Rotation: FC<RotationProps> = observer((props) => {
|
|||
|
||||
const store = useStore();
|
||||
|
||||
const startMomentString = useMemo(() => startMoment.utc().format('YYYY-MM-DDTHH:mm:ss.000Z'), [startMoment]);
|
||||
const startMomentString = useMemo(() => startMoment.utc().format('YYYY-MM-DD'), [startMoment]);
|
||||
|
||||
const prevStartMomentString = usePrevious(startMomentString);
|
||||
|
||||
const rotation = store.scheduleStore.rotations[id]?.[startMomentString];
|
||||
//const rotation = store.scheduleStore.rotations[id]?.[prevStartMomentString];
|
||||
const events = store.scheduleStore.events[scheduleId]?.[type]?.[startMomentString];
|
||||
|
||||
console.log(events);
|
||||
|
||||
// const rotation = store.scheduleStore.rotations[id]?.[prevStartMomentString];
|
||||
|
||||
/* useEffect(() => {
|
||||
setTransparent(false);
|
||||
|
|
@ -58,7 +62,7 @@ const Rotation: FC<RotationProps> = observer((props) => {
|
|||
|
||||
console.log('CHANGE START MOMENT', startMomentString);
|
||||
|
||||
store.scheduleStore.updateRotationMock(id, startMomentString, currentTimezone);
|
||||
// store.scheduleStore.updateEvents(scheduleId, startMomentString, currentTimezone);
|
||||
}, [startMomentString]);
|
||||
|
||||
const slots = useCallback((node) => {
|
||||
|
|
@ -68,21 +72,19 @@ const Rotation: FC<RotationProps> = observer((props) => {
|
|||
}, []);
|
||||
|
||||
const x = useMemo(() => {
|
||||
if (!rotation) {
|
||||
if (!events) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const { shifts } = rotation;
|
||||
const firstShift = events[0];
|
||||
|
||||
const firstShift = shifts[0];
|
||||
|
||||
const firstShiftOffset = firstShift.start.diff(startMoment, 'minutes');
|
||||
const firstShiftOffset = dayjs(firstShift.start).diff(startMoment, 'minutes');
|
||||
|
||||
const base = 60 * 24 * 7; // in minutes only
|
||||
const utcOffset = dayjs().tz(currentTimezone).utcOffset();
|
||||
|
||||
return firstShiftOffset / base;
|
||||
}, [rotation]);
|
||||
}, [events]);
|
||||
|
||||
useEffect(() => {});
|
||||
|
||||
|
|
@ -90,18 +92,18 @@ const Rotation: FC<RotationProps> = observer((props) => {
|
|||
<div className={cx('root')}>
|
||||
{/* <div className={cx('current-time')} />*/}
|
||||
<div className={cx('timeline')}>
|
||||
{rotation ? (
|
||||
{events ? (
|
||||
<div
|
||||
className={cx('slots', { slots__animate: animate, slots__transparent: transparent })}
|
||||
style={{ transform: `translate(${x * 100}%, 0)` }}
|
||||
ref={slots}
|
||||
>
|
||||
{rotation.shifts.map((shift, index) => {
|
||||
{events.map((event, index) => {
|
||||
return (
|
||||
<ScheduleSlot
|
||||
key={shift.pk}
|
||||
index={index}
|
||||
shift={shift}
|
||||
key={event.start}
|
||||
event={event}
|
||||
layerIndex={layerIndex}
|
||||
rotationIndex={rotationIndex}
|
||||
startMoment={startMoment}
|
||||
|
|
|
|||
|
|
@ -19,11 +19,13 @@ import Draggable from 'react-draggable';
|
|||
import Modal from 'components/Modal/Modal';
|
||||
import Text from 'components/Text/Text';
|
||||
import UserGroups from 'components/UserGroups/UserGroups';
|
||||
import RemoteSelect from 'containers/RemoteSelect/RemoteSelect';
|
||||
import { Rotation, Schedule } from 'models/schedule/schedule.types';
|
||||
import { getTzOffsetString } from 'models/timezone/timezone.helpers';
|
||||
import { Timezone } from 'models/timezone/timezone.types';
|
||||
import { User } from 'models/user/user.types';
|
||||
import { getUTCString } from 'pages/schedule/Schedule.helpers';
|
||||
import { SelectOption } from 'state/types';
|
||||
import { useStore } from 'state/useStore';
|
||||
|
||||
import { RotationCreateData } from './RotationForm.types';
|
||||
|
|
@ -33,11 +35,11 @@ import styles from './RotationForm.module.css';
|
|||
interface RotationFormProps {
|
||||
layerId: string;
|
||||
onHide: () => void;
|
||||
onCreate: (date: RotationCreateData) => void;
|
||||
id: number | 'new';
|
||||
currentTimezone: Timezone;
|
||||
scheduleId: Schedule['id'];
|
||||
onUpdate: (data: Rotation) => void;
|
||||
onCreate: () => void;
|
||||
onUpdate: () => void;
|
||||
}
|
||||
|
||||
const cx = cn.bind(styles);
|
||||
|
|
@ -46,8 +48,8 @@ const RotationForm: FC<RotationFormProps> = (props) => {
|
|||
const { onHide, onCreate, currentTimezone, scheduleId, onUpdate } = props;
|
||||
|
||||
const [repeatEveryValue, setRepeatEveryValue] = useState<number>(1);
|
||||
const [repeatEveryPeriod, setRepeatEveryPeriod] = useState<string>('days');
|
||||
const [selectedDays, setSelectedDays] = useState<string[]>(['Tuesday']);
|
||||
const [repeatEveryPeriod, setRepeatEveryPeriod] = useState<number>(0);
|
||||
const [selectedDays, setSelectedDays] = useState<string[]>([]);
|
||||
const [shiftStart, setShiftStart] = useState<DateTime>(dateTime('2022-07-26 17:00:00'));
|
||||
const [shiftEnd, setShiftEnd] = useState<DateTime>(dateTime('2022-07-26 19:00:00'));
|
||||
const [rotationStart, setRotationStart] = useState<DateTime>(dateTime('2022-07-26 17:00:00'));
|
||||
|
|
@ -79,17 +81,17 @@ const RotationForm: FC<RotationFormProps> = (props) => {
|
|||
*/
|
||||
|
||||
store.scheduleStore
|
||||
.createRotation(scheduleId, true, {
|
||||
name: 'Rotation' + Math.floor(Math.random() * 100),
|
||||
.createRotation(scheduleId, false, {
|
||||
name: 'Rotation ' + Math.floor(Math.random() * 100),
|
||||
rotation_start: getUTCString(rotationStart),
|
||||
until: endLess ? null : getUTCString(rotationEnd),
|
||||
shift_start: getUTCString(shiftStart),
|
||||
shift_end: getUTCString(shiftEnd),
|
||||
rolling_users: userGroups,
|
||||
frequency: 0,
|
||||
frequency: repeatEveryValue,
|
||||
by_day: selectedDays,
|
||||
})
|
||||
.then((data) => {
|
||||
onUpdate(data);
|
||||
});
|
||||
.then(onUpdate);
|
||||
}, [
|
||||
repeatEveryValue,
|
||||
repeatEveryPeriod,
|
||||
|
|
@ -159,21 +161,21 @@ const RotationForm: FC<RotationFormProps> = (props) => {
|
|||
/>
|
||||
</Field>
|
||||
<Field className={cx('control')} label="">
|
||||
<Select
|
||||
<RemoteSelect
|
||||
href="/oncall_shifts/frequency_options/"
|
||||
value={repeatEveryPeriod}
|
||||
options={[
|
||||
{ label: 'days', value: 'days' },
|
||||
{ label: 'weeks', value: 'weeks' },
|
||||
{ label: 'hours', value: 'hours' },
|
||||
]}
|
||||
onChange={handleRepeatEveryPeriodChange}
|
||||
onChange={setRepeatEveryPeriod}
|
||||
/>
|
||||
</Field>
|
||||
</HorizontalGroup>
|
||||
{repeatEveryPeriod === 'weeks' && (
|
||||
{repeatEveryPeriod === 0 && (
|
||||
/*<HorizontalGroup justify="center">*/
|
||||
<Field label="Select days to repeat">
|
||||
<DaysSelector value={selectedDays} onChange={(value) => setSelectedDays(value)} />
|
||||
<DaysSelector
|
||||
options={store.scheduleStore.byDayOptions}
|
||||
value={selectedDays}
|
||||
onChange={(value) => setSelectedDays(value)}
|
||||
/>
|
||||
</Field>
|
||||
/*</HorizontalGroup>*/
|
||||
)}
|
||||
|
|
@ -257,9 +259,10 @@ const DAYS = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'
|
|||
interface DaysSelectorProps {
|
||||
value: string[];
|
||||
onChange: (value: string[]) => void;
|
||||
options: SelectOption[];
|
||||
}
|
||||
|
||||
const DaysSelector = ({ value, onChange }: DaysSelectorProps) => {
|
||||
const DaysSelector = ({ value, onChange, options }: DaysSelectorProps) => {
|
||||
const getDayClickHandler = (day: string) => {
|
||||
return () => {
|
||||
const newValue = [...value];
|
||||
|
|
@ -275,9 +278,12 @@ const DaysSelector = ({ value, onChange }: DaysSelectorProps) => {
|
|||
|
||||
return (
|
||||
<div className={cx('days')}>
|
||||
{DAYS.map((day: string) => (
|
||||
<div onClick={getDayClickHandler(day)} className={cx('day', { day__selected: value.includes(day) })}>
|
||||
{day.charAt(0).toUpperCase()}
|
||||
{options.map(({ display_name, value: itemValue }) => (
|
||||
<div
|
||||
onClick={getDayClickHandler(itemValue as string)}
|
||||
className={cx('day', { day__selected: value.includes(itemValue as string) })}
|
||||
>
|
||||
{display_name.charAt(0)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -19,22 +19,30 @@ import Draggable from 'react-draggable';
|
|||
import Modal from 'components/Modal/Modal';
|
||||
import Text from 'components/Text/Text';
|
||||
import UserGroups from 'components/UserGroups/UserGroups';
|
||||
import { Rotation, Schedule } from 'models/schedule/schedule.types';
|
||||
import { getTzOffsetString } from 'models/timezone/timezone.helpers';
|
||||
import { Timezone } from 'models/timezone/timezone.types';
|
||||
import { User } from 'models/user/user.types';
|
||||
import { getUTCString } from 'pages/schedule/Schedule.helpers';
|
||||
import { useStore } from 'state/useStore';
|
||||
|
||||
import { RotationCreateData } from './RotationForm.types';
|
||||
|
||||
import styles from './RotationForm.module.css';
|
||||
|
||||
interface RotationFormProps {
|
||||
layerId: string;
|
||||
onHide: () => void;
|
||||
id: number | 'new';
|
||||
currentTimezone: Timezone;
|
||||
scheduleId: Schedule['id'];
|
||||
onCreate: () => void;
|
||||
onUpdate: () => void;
|
||||
}
|
||||
|
||||
const cx = cn.bind(styles);
|
||||
|
||||
const ScheduleOverrideForm: FC<RotationFormProps> = (props) => {
|
||||
const { onHide } = props;
|
||||
const { onHide, onCreate, currentTimezone, scheduleId, onUpdate } = props;
|
||||
|
||||
const store = useStore();
|
||||
|
||||
|
|
@ -50,6 +58,19 @@ const ScheduleOverrideForm: FC<RotationFormProps> = (props) => {
|
|||
};
|
||||
};
|
||||
|
||||
const handleCreate = useCallback(() => {
|
||||
store.scheduleStore
|
||||
.createRotation(scheduleId, true, {
|
||||
name: 'Rotation ' + Math.floor(Math.random() * 100),
|
||||
rotation_start: getUTCString(shiftStart),
|
||||
shift_start: getUTCString(shiftStart),
|
||||
shift_end: getUTCString(shiftEnd),
|
||||
rolling_users: userGroups[0],
|
||||
frequency: null,
|
||||
})
|
||||
.then(onUpdate);
|
||||
}, [shiftStart, shiftEnd, userGroups]);
|
||||
|
||||
const moment = dayjs();
|
||||
|
||||
return (
|
||||
|
|
@ -102,7 +123,9 @@ const ScheduleOverrideForm: FC<RotationFormProps> = (props) => {
|
|||
<HorizontalGroup justify="space-between">
|
||||
<Text type="secondary">Timezone: {getTzOffsetString(moment)}</Text>
|
||||
<HorizontalGroup>
|
||||
<Button variant="primary">Save</Button>
|
||||
<Button variant="primary" onClick={handleCreate}>
|
||||
Save
|
||||
</Button>
|
||||
</HorizontalGroup>
|
||||
</HorizontalGroup>
|
||||
</VerticalGroup>
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import { SelectOptions } from '@grafana/ui';
|
||||
import dayjs from 'dayjs';
|
||||
import { omit, reject } from 'lodash-es';
|
||||
import { action, observable, toJS } from 'mobx';
|
||||
|
|
@ -7,8 +8,9 @@ import BaseStore from 'models/base_store';
|
|||
import { Timezone } from 'models/timezone/timezone.types';
|
||||
import { makeRequest } from 'network';
|
||||
import { RootStore } from 'state';
|
||||
import { SelectOption } from 'state/types';
|
||||
|
||||
import { Rotation, Schedule, ScheduleEvent } from './schedule.types';
|
||||
import { Events, Rotation, Schedule, ScheduleEvent } from './schedule.types';
|
||||
|
||||
const DEFAULT_FORMAT = 'YYYY-MM-DDTHH:mm:ss';
|
||||
|
||||
|
|
@ -56,11 +58,23 @@ export class ScheduleStore extends BaseStore {
|
|||
};
|
||||
} = {};
|
||||
|
||||
@observable.shallow
|
||||
events: {
|
||||
[scheduleId: string]: {
|
||||
[type: string]: {
|
||||
[startMoment: string]: Events['events'];
|
||||
};
|
||||
};
|
||||
} = {};
|
||||
|
||||
@observable
|
||||
scheduleToScheduleEvents: {
|
||||
[id: string]: ScheduleEvent[];
|
||||
} = {};
|
||||
|
||||
@observable
|
||||
byDayOptions: SelectOption[];
|
||||
|
||||
constructor(rootStore: RootStore) {
|
||||
super(rootStore);
|
||||
|
||||
|
|
@ -155,10 +169,8 @@ export class ScheduleStore extends BaseStore {
|
|||
async createRotation(scheduleId: Schedule['id'], isOverride: boolean, params: any) {
|
||||
const type = isOverride ? 3 : 2;
|
||||
|
||||
const { name, shift_start, shift_end, rotation_start, rolling_users, frequency } = params;
|
||||
|
||||
return await makeRequest(`/oncall_shifts/`, {
|
||||
data: { name, type, schedule: scheduleId, shift_start, shift_end, rotation_start, rolling_users, frequency },
|
||||
data: { type, schedule: scheduleId, ...params },
|
||||
method: 'POST',
|
||||
});
|
||||
}
|
||||
|
|
@ -229,7 +241,7 @@ export class ScheduleStore extends BaseStore {
|
|||
});
|
||||
}
|
||||
async updateEvents(scheduleId: Schedule['id'], fromString: string, type = 'rotation', days = 7) {
|
||||
const events = await makeRequest(`/schedules/${scheduleId}/filter_events/`, {
|
||||
const response = await makeRequest(`/schedules/${scheduleId}/filter_events/`, {
|
||||
params: {
|
||||
type,
|
||||
date: fromString,
|
||||
|
|
@ -238,6 +250,19 @@ export class ScheduleStore extends BaseStore {
|
|||
method: 'GET',
|
||||
});
|
||||
|
||||
this.events = {
|
||||
...this.events,
|
||||
[scheduleId]: {
|
||||
...this.events[scheduleId],
|
||||
[type]: {
|
||||
...this.events[scheduleId]?.[type],
|
||||
[fromString]: response.events,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
console.log(toJS(this.events));
|
||||
|
||||
/*this.rotations = {
|
||||
...this.rotations,
|
||||
[rotationId]: {
|
||||
|
|
@ -256,7 +281,7 @@ export class ScheduleStore extends BaseStore {
|
|||
}
|
||||
|
||||
async updateDaysOptions() {
|
||||
return await makeRequest(`/oncall_shifts/days_options/`, {
|
||||
this.byDayOptions = await makeRequest(`/oncall_shifts/days_options/`, {
|
||||
method: 'GET',
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -58,3 +58,24 @@ export interface Rotation {
|
|||
id: string;
|
||||
shifts: Shift[];
|
||||
}
|
||||
|
||||
export interface Event {
|
||||
all_day: boolean;
|
||||
calendar_type: 0;
|
||||
end: string;
|
||||
is_empty: boolean;
|
||||
is_gap: boolean;
|
||||
missing_users: [];
|
||||
priority_level: number;
|
||||
shift: { pk: string };
|
||||
source: string;
|
||||
start: string;
|
||||
users: [{ display_name: User['username']; pk: User['pk'] }];
|
||||
}
|
||||
|
||||
export interface Events {
|
||||
events: Event[];
|
||||
id: string;
|
||||
name: string;
|
||||
type: number; //?
|
||||
}
|
||||
|
|
|
|||
|
|
@ -100,7 +100,17 @@ export class UserStore extends BaseStore {
|
|||
...acc,
|
||||
[item.pk]: {
|
||||
...item,
|
||||
timezone: getRandomTimezone(),
|
||||
timezone: {
|
||||
'Hello Oncall': 'UTC',
|
||||
'Matias Bordese': 'America/Montevideo',
|
||||
'Michael Derynck': 'America/Vancouver',
|
||||
'Yulia Shanyrova': 'Europe/Amsterdam',
|
||||
'Maxim Mordasov': 'Europe/Moscow',
|
||||
'Vadim Stepanov': 'Europe/London',
|
||||
'Ildar Iskhakov': 'Asia/Yerevan',
|
||||
'Innokentii Konstantinov': 'Asia/Singapore',
|
||||
/* 'Matvey Kukuy',*/
|
||||
}[item.username],
|
||||
working_hours: {
|
||||
monday: [{ start: '09:00:00', end: '18:00:00' }],
|
||||
tuesday: [{ start: '09:00:00', end: '18:00:00' }],
|
||||
|
|
|
|||
|
|
@ -174,22 +174,28 @@ class SchedulePage extends React.Component<SchedulePageProps, SchedulePageState>
|
|||
</div>
|
||||
{/* <div className={'current-time'} />*/}
|
||||
<div className={cx('rotations')}>
|
||||
{/*<ScheduleFinal currentTimezone={currentTimezone} startMoment={startMoment} />*/}
|
||||
<ScheduleFinal scheduleId={scheduleId} currentTimezone={currentTimezone} startMoment={startMoment} />
|
||||
<Rotations
|
||||
scheduleId={scheduleId}
|
||||
currentTimezone={currentTimezone}
|
||||
startMoment={startMoment}
|
||||
onCreate={this.handleCreateRotation}
|
||||
onRotationUpdate={this.updateEvents}
|
||||
onUpdate={this.updateEvents}
|
||||
/>
|
||||
<ScheduleOverrides
|
||||
scheduleId={scheduleId}
|
||||
currentTimezone={currentTimezone}
|
||||
startMoment={startMoment}
|
||||
onCreate={this.handleCreateOverride}
|
||||
onUpdate={this.updateEvents}
|
||||
/>
|
||||
<ScheduleOverrides currentTimezone={currentTimezone} startMoment={startMoment} />
|
||||
</div>
|
||||
</VerticalGroup>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
updateEvents = () => {
|
||||
updateEvents = (...rest) => {
|
||||
const {
|
||||
store,
|
||||
query: { id: scheduleId },
|
||||
|
|
@ -197,11 +203,21 @@ class SchedulePage extends React.Component<SchedulePageProps, SchedulePageState>
|
|||
|
||||
const { startMoment } = this.state;
|
||||
|
||||
//debugger;
|
||||
|
||||
store.scheduleStore.updateEvents(scheduleId, startMoment.format('YYYY-MM-DD'));
|
||||
};
|
||||
|
||||
handleCreateRotation = () => {
|
||||
handleCreateRotation = (...rest) => {
|
||||
const { store } = this.props;
|
||||
|
||||
// debugger;
|
||||
};
|
||||
|
||||
handleCreateOverride = (...rest) => {
|
||||
const { store } = this.props;
|
||||
|
||||
// debugger;
|
||||
};
|
||||
|
||||
handleTimezoneChange = (value: Timezone) => {
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import { SchedulesFiltersType } from 'components/SchedulesFilters_NEW/SchedulesF
|
|||
import Table from 'components/Table/Table';
|
||||
import Text from 'components/Text/Text';
|
||||
import TimelineMarks from 'components/TimelineMarks/TimelineMarks';
|
||||
import WithConfirm from 'components/WithConfirm/WithConfirm';
|
||||
import Rotation from 'containers/Rotation/Rotation';
|
||||
import { Schedule, ScheduleType } from 'models/schedule/schedule.types';
|
||||
import { getTzOffsetString } from 'models/timezone/timezone.helpers';
|
||||
|
|
@ -228,11 +229,22 @@ class SchedulesPage extends React.Component<SchedulesPageProps, SchedulesPageSta
|
|||
<IconButton tooltip="Copy" name="copy" />
|
||||
<IconButton tooltip="Settings" name="cog" />
|
||||
<IconButton tooltip="Code" name="brackets-curly" />
|
||||
<IconButton tooltip="Delete" name="trash-alt" />
|
||||
<WithConfirm>
|
||||
<IconButton tooltip="Delete" name="trash-alt" onClick={this.getDeleteScheduleClickHandler(item.id)} />
|
||||
</WithConfirm>
|
||||
</HorizontalGroup>
|
||||
);
|
||||
};
|
||||
|
||||
getDeleteScheduleClickHandler = (id: Schedule['id']) => {
|
||||
const { store } = this.props;
|
||||
const { scheduleStore } = store;
|
||||
|
||||
return () => {
|
||||
scheduleStore.delete(id).then(this.update);
|
||||
};
|
||||
};
|
||||
|
||||
handleSchedulesFiltersChange = (filters: SchedulesFiltersType) => {
|
||||
this.setState({ filters });
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue