use real data in UsertimezoneSelect
This commit is contained in:
parent
30ff3e840d
commit
d85a3f615d
11 changed files with 147 additions and 85 deletions
|
|
@ -115,8 +115,8 @@ class Rotations extends Component<RotationsProps, RotationsState> {
|
|||
onHide={() => {
|
||||
this.setState({ layerIdToCreateRotation: undefined });
|
||||
}}
|
||||
onUpdate={onCreate}
|
||||
onCreate={onUpdate}
|
||||
onUpdate={onUpdate}
|
||||
onCreate={onCreate}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
|
|
|
|||
|
|
@ -18,22 +18,35 @@ import styles from './Rotations.module.css';
|
|||
|
||||
const cx = cn.bind(styles);
|
||||
|
||||
interface ScheduleOverridesProps extends WithStoreProps {
|
||||
interface ScheduleFinalProps extends WithStoreProps {
|
||||
startMoment: dayjs.Dayjs;
|
||||
currentTimezone: Timezone;
|
||||
scheduleId: Schedule['id'];
|
||||
hideHeader?: boolean;
|
||||
}
|
||||
|
||||
interface ScheduleOverridesState {}
|
||||
|
||||
@observer
|
||||
class ScheduleOverrides extends Component<ScheduleOverridesProps, ScheduleOverridesState> {
|
||||
class ScheduleFinal extends Component<ScheduleFinalProps, ScheduleOverridesState> {
|
||||
state: ScheduleOverridesState = {};
|
||||
|
||||
componentDidMount() {
|
||||
const { store, scheduleId, startMoment, currentTimezone } = this.props;
|
||||
this.updateEvents();
|
||||
}
|
||||
|
||||
const {} = this.props;
|
||||
componentDidUpdate(
|
||||
prevProps: Readonly<ScheduleFinalProps>,
|
||||
prevState: Readonly<ScheduleOverridesState>,
|
||||
snapshot?: any
|
||||
) {
|
||||
if (this.props.startMoment !== prevProps.startMoment) {
|
||||
this.updateEvents();
|
||||
}
|
||||
}
|
||||
|
||||
updateEvents() {
|
||||
const { store, scheduleId, startMoment, currentTimezone } = this.props;
|
||||
|
||||
const startMomentString = startMoment.utc().format('YYYY-MM-DD');
|
||||
|
||||
|
|
@ -41,7 +54,7 @@ class ScheduleOverrides extends Component<ScheduleOverridesProps, ScheduleOverri
|
|||
}
|
||||
|
||||
render() {
|
||||
const { scheduleId, startMoment, currentTimezone, store } = this.props;
|
||||
const { scheduleId, startMoment, currentTimezone, store, hideHeader } = this.props;
|
||||
const { showAddOverrideForm, searchTerm } = this.state;
|
||||
|
||||
const base = 7 * 24 * 60; // in minutes
|
||||
|
|
@ -52,17 +65,19 @@ class ScheduleOverrides extends Component<ScheduleOverridesProps, ScheduleOverri
|
|||
return (
|
||||
<>
|
||||
<div className={cx('root')}>
|
||||
<div className={cx('header')}>
|
||||
<HorizontalGroup justify="space-between">
|
||||
<div className={cx('title')}>Final schedule</div>
|
||||
<Input
|
||||
prefix={<Icon name="search" />}
|
||||
placeholder="Search..."
|
||||
value={searchTerm}
|
||||
onChange={this.onSearchTermChangeCallback}
|
||||
/>
|
||||
</HorizontalGroup>
|
||||
</div>
|
||||
{!hideHeader && (
|
||||
<div className={cx('header')}>
|
||||
<HorizontalGroup justify="space-between">
|
||||
<div className={cx('title')}>Final schedule</div>
|
||||
<Input
|
||||
prefix={<Icon name="search" />}
|
||||
placeholder="Search..."
|
||||
value={searchTerm}
|
||||
onChange={this.onSearchTermChangeCallback}
|
||||
/>
|
||||
</HorizontalGroup>
|
||||
</div>
|
||||
)}
|
||||
<div className={cx('header-plus-content')}>
|
||||
<div className={cx('current-time')} style={{ left: `${currentTimeX * 100}%` }} />
|
||||
<TimelineMarks startMoment={startMoment} />
|
||||
|
|
@ -85,4 +100,4 @@ class ScheduleOverrides extends Component<ScheduleOverridesProps, ScheduleOverri
|
|||
onSearchTermChangeCallback = () => {};
|
||||
}
|
||||
|
||||
export default withMobXProviderContext(ScheduleOverrides);
|
||||
export default withMobXProviderContext(ScheduleFinal);
|
||||
|
|
|
|||
|
|
@ -68,8 +68,8 @@ class ScheduleOverrides extends Component<ScheduleOverridesProps, ScheduleOverri
|
|||
onHide={() => {
|
||||
this.setState({ showAddOverrideForm: false });
|
||||
}}
|
||||
onUpdate={onCreate}
|
||||
onCreate={onUpdate}
|
||||
onUpdate={onUpdate}
|
||||
onCreate={onCreate}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
|
|
|
|||
|
|
@ -24,14 +24,14 @@ const UserTimezoneSelect: FC<UserTimezoneSelectProps> = (props) => {
|
|||
|
||||
const options = useMemo(() => {
|
||||
return users.reduce((memo, user) => {
|
||||
let item = memo.find((item) => item.label === user.tz);
|
||||
let item = memo.find((item) => item.label === user.timezone);
|
||||
|
||||
if (!item) {
|
||||
item = {
|
||||
value: user.pk,
|
||||
label: `${user.tz} ${getTzOffsetString(dayjs().tz(user.tz))}`,
|
||||
label: `${user.timezone} ${getTzOffsetString(dayjs().tz(user.timezone))}`,
|
||||
imgUrl: user.avatar,
|
||||
description: user.name,
|
||||
description: user.username,
|
||||
};
|
||||
memo.push(item);
|
||||
} else {
|
||||
|
|
@ -44,7 +44,7 @@ const UserTimezoneSelect: FC<UserTimezoneSelectProps> = (props) => {
|
|||
}, [users]);
|
||||
|
||||
const selectValue = useMemo(() => {
|
||||
const user = users.find((user) => user.tz === value);
|
||||
const user = users.find((user) => user.timezone === value);
|
||||
return user.pk;
|
||||
}, [value, users]);
|
||||
|
||||
|
|
@ -52,7 +52,7 @@ const UserTimezoneSelect: FC<UserTimezoneSelectProps> = (props) => {
|
|||
({ value }) => {
|
||||
const user = users.find((user) => user.pk === value);
|
||||
|
||||
onChange(user.tz);
|
||||
onChange(user.timezone);
|
||||
},
|
||||
[users]
|
||||
);
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ const Rotation: FC<RotationProps> = observer((props) => {
|
|||
}, []);
|
||||
|
||||
const x = useMemo(() => {
|
||||
if (!events) {
|
||||
if (!events || !events.length) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -93,26 +93,28 @@ const Rotation: FC<RotationProps> = observer((props) => {
|
|||
{/* <div className={cx('current-time')} />*/}
|
||||
<div className={cx('timeline')}>
|
||||
{events ? (
|
||||
<div
|
||||
className={cx('slots', { slots__animate: animate, slots__transparent: transparent })}
|
||||
style={{ transform: `translate(${x * 100}%, 0)` }}
|
||||
ref={slots}
|
||||
>
|
||||
{events.map((event, index) => {
|
||||
return (
|
||||
<ScheduleSlot
|
||||
index={index}
|
||||
key={event.start}
|
||||
event={event}
|
||||
layerIndex={layerIndex}
|
||||
rotationIndex={rotationIndex}
|
||||
startMoment={startMoment}
|
||||
currentTimezone={currentTimezone}
|
||||
color={color}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
events.length ? (
|
||||
<div
|
||||
className={cx('slots', { slots__animate: animate, slots__transparent: transparent })}
|
||||
style={{ transform: `translate(${x * 100}%, 0)` }}
|
||||
ref={slots}
|
||||
>
|
||||
{events.map((event, index) => {
|
||||
return (
|
||||
<ScheduleSlot
|
||||
index={index}
|
||||
key={event.start}
|
||||
event={event}
|
||||
layerIndex={layerIndex}
|
||||
rotationIndex={rotationIndex}
|
||||
startMoment={startMoment}
|
||||
currentTimezone={currentTimezone}
|
||||
color={color}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
) : null
|
||||
) : (
|
||||
<HorizontalGroup align="center" justify="center">
|
||||
<LoadingPlaceholder text="Loading shifts..." />
|
||||
|
|
|
|||
|
|
@ -89,9 +89,12 @@ const RotationForm: FC<RotationFormProps> = (props) => {
|
|||
shift_end: getUTCString(shiftEnd),
|
||||
rolling_users: userGroups,
|
||||
frequency: repeatEveryValue,
|
||||
by_day: selectedDays,
|
||||
by_day: repeatEveryPeriod === 1 ? selectedDays : null,
|
||||
})
|
||||
.then(onUpdate);
|
||||
.then(() => {
|
||||
onHide();
|
||||
onCreate();
|
||||
});
|
||||
}, [
|
||||
repeatEveryValue,
|
||||
repeatEveryPeriod,
|
||||
|
|
@ -168,7 +171,7 @@ const RotationForm: FC<RotationFormProps> = (props) => {
|
|||
/>
|
||||
</Field>
|
||||
</HorizontalGroup>
|
||||
{repeatEveryPeriod === 0 && (
|
||||
{repeatEveryPeriod === 1 && (
|
||||
/*<HorizontalGroup justify="center">*/
|
||||
<Field label="Select days to repeat">
|
||||
<DaysSelector
|
||||
|
|
|
|||
|
|
@ -65,10 +65,13 @@ const ScheduleOverrideForm: FC<RotationFormProps> = (props) => {
|
|||
rotation_start: getUTCString(shiftStart),
|
||||
shift_start: getUTCString(shiftStart),
|
||||
shift_end: getUTCString(shiftEnd),
|
||||
rolling_users: userGroups[0],
|
||||
rolling_users: userGroups,
|
||||
frequency: null,
|
||||
})
|
||||
.then(onUpdate);
|
||||
.then(() => {
|
||||
onHide();
|
||||
onCreate();
|
||||
});
|
||||
}, [shiftStart, shiftEnd, userGroups]);
|
||||
|
||||
const moment = dayjs();
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ export class UserStore extends BaseStore {
|
|||
|
||||
this.items = {
|
||||
...this.items,
|
||||
[user.pk]: user,
|
||||
[user.pk]: { ...user, timezone: this.rootStore.currentTimezone },
|
||||
};
|
||||
|
||||
this.currentUserPk = user.pk;
|
||||
|
|
@ -108,6 +108,7 @@ export class UserStore extends BaseStore {
|
|||
'Maxim Mordasov': 'Europe/Moscow',
|
||||
'Vadim Stepanov': 'Europe/London',
|
||||
'Ildar Iskhakov': 'Asia/Yerevan',
|
||||
'Raphael Batyrbaev': 'Europe/Rome',
|
||||
'Innokentii Konstantinov': 'Asia/Singapore',
|
||||
/* 'Matvey Kukuy',*/
|
||||
}[item.username],
|
||||
|
|
|
|||
|
|
@ -35,21 +35,22 @@ interface SchedulePageState {
|
|||
startMoment: dayjs.Dayjs;
|
||||
schedulePeriodType: string;
|
||||
renderType: string;
|
||||
users: User[];
|
||||
currentTimezone: Timezone;
|
||||
}
|
||||
|
||||
const INITIAL_TIMEZONE = 'UTC'; // todo check why doesn't work
|
||||
|
||||
@observer
|
||||
class SchedulePage extends React.Component<SchedulePageProps, SchedulePageState> {
|
||||
state: SchedulePageState = {
|
||||
startMoment: getStartOfWeek(INITIAL_TIMEZONE),
|
||||
schedulePeriodType: 'week',
|
||||
renderType: 'timeline',
|
||||
users: getRandomUsers(),
|
||||
currentTimezone: INITIAL_TIMEZONE,
|
||||
};
|
||||
constructor(props: SchedulePageProps) {
|
||||
super(props);
|
||||
|
||||
const { store } = this.props;
|
||||
this.state = {
|
||||
startMoment: getStartOfWeek(store.currentTimezone),
|
||||
schedulePeriodType: 'week',
|
||||
renderType: 'timeline',
|
||||
};
|
||||
}
|
||||
|
||||
async componentDidMount() {
|
||||
const { store } = this.props;
|
||||
|
|
@ -71,11 +72,13 @@ class SchedulePage extends React.Component<SchedulePageProps, SchedulePageState>
|
|||
|
||||
render() {
|
||||
const { store } = this.props;
|
||||
const { startMoment, schedulePeriodType, renderType, users, currentTimezone } = this.state;
|
||||
const { startMoment, schedulePeriodType, renderType } = this.state;
|
||||
const { query } = this.props;
|
||||
const { id: scheduleId } = query;
|
||||
|
||||
const { scheduleStore } = store;
|
||||
const users = store.userStore.getSearchResult().results;
|
||||
|
||||
const { scheduleStore, currentTimezone } = store;
|
||||
|
||||
const schedule = scheduleStore.items[scheduleId];
|
||||
|
||||
|
|
@ -111,7 +114,9 @@ class SchedulePage extends React.Component<SchedulePageProps, SchedulePageState>
|
|||
/>
|
||||
</HorizontalGroup>
|
||||
<HorizontalGroup>
|
||||
<UserTimezoneSelect value={currentTimezone} users={users} onChange={this.handleTimezoneChange} />
|
||||
{users && (
|
||||
<UserTimezoneSelect value={currentTimezone} users={users} onChange={this.handleTimezoneChange} />
|
||||
)}
|
||||
<ScheduleQuality quality={0.89} />
|
||||
<ToolbarButton icon="copy" tooltip="Copy" />
|
||||
<ToolbarButton icon="brackets-curly" tooltip="Code" />
|
||||
|
|
@ -203,7 +208,7 @@ class SchedulePage extends React.Component<SchedulePageProps, SchedulePageState>
|
|||
|
||||
const { startMoment } = this.state;
|
||||
|
||||
//debugger;
|
||||
// debugger;
|
||||
|
||||
store.scheduleStore.updateEvents(scheduleId, startMoment.format('YYYY-MM-DD'));
|
||||
};
|
||||
|
|
@ -221,7 +226,11 @@ class SchedulePage extends React.Component<SchedulePageProps, SchedulePageState>
|
|||
};
|
||||
|
||||
handleTimezoneChange = (value: Timezone) => {
|
||||
this.setState({ currentTimezone: value, startMoment: getStartOfWeek(value) });
|
||||
const { store } = this.props;
|
||||
|
||||
store.currentTimezone = value;
|
||||
|
||||
this.setState({ startMoment: getStartOfWeek(value) });
|
||||
};
|
||||
|
||||
handleShedulePeriodTypeChange = (value: string) => {
|
||||
|
|
@ -233,9 +242,9 @@ class SchedulePage extends React.Component<SchedulePageProps, SchedulePageState>
|
|||
};
|
||||
|
||||
handleTodayClick = () => {
|
||||
const { currentTimezone } = this.state;
|
||||
const { store } = this.props;
|
||||
|
||||
this.setState({ startMoment: getStartOfWeek(currentTimezone) });
|
||||
this.setState({ startMoment: getStartOfWeek(store.currentTimezone) });
|
||||
};
|
||||
|
||||
handleLeftClick = () => {
|
||||
|
|
|
|||
|
|
@ -8,16 +8,20 @@ import { observer } from 'mobx-react';
|
|||
|
||||
import NewScheduleSelector from 'components/NewScheduleSelector/NewScheduleSelector';
|
||||
import PluginLink from 'components/PluginLink/PluginLink';
|
||||
import ScheduleFinal from 'components/Rotations/ScheduleFinal';
|
||||
import ScheduleCounter from 'components/ScheduleCounter/ScheduleCounter';
|
||||
import SchedulesFilters from 'components/SchedulesFilters_NEW/SchedulesFilters';
|
||||
import { SchedulesFiltersType } from 'components/SchedulesFilters_NEW/SchedulesFilters.types';
|
||||
import Table from 'components/Table/Table';
|
||||
import Text from 'components/Text/Text';
|
||||
import TimelineMarks from 'components/TimelineMarks/TimelineMarks';
|
||||
import UserTimezoneSelect from 'components/UserTimezoneSelect/UserTimezoneSelect';
|
||||
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';
|
||||
import { Timezone } from 'models/timezone/timezone.types';
|
||||
import { getStartOfWeek } from 'pages/schedule/Schedule.helpers';
|
||||
import { WithStoreProps } from 'state/types';
|
||||
import { withMobXProviderContext } from 'state/withStore';
|
||||
|
||||
|
|
@ -35,12 +39,16 @@ interface SchedulesPageState {
|
|||
|
||||
@observer
|
||||
class SchedulesPage extends React.Component<SchedulesPageProps, SchedulesPageState> {
|
||||
state: SchedulesPageState = {
|
||||
startMoment: dayjs().utc().startOf('week'),
|
||||
// schedules: getRandomSchedules(),
|
||||
filters: { searchTerm: '', status: 'all', type: 'all' },
|
||||
showNewScheduleSelector: false,
|
||||
};
|
||||
constructor(props: SchedulesPageProps) {
|
||||
super(props);
|
||||
|
||||
const { store } = this.props;
|
||||
this.state = {
|
||||
startMoment: getStartOfWeek(store.currentTimezone),
|
||||
filters: { searchTerm: '', status: 'all', type: 'all' },
|
||||
showNewScheduleSelector: false,
|
||||
};
|
||||
}
|
||||
|
||||
async componentDidMount() {
|
||||
const { store } = this.props;
|
||||
|
|
@ -96,7 +104,9 @@ class SchedulesPage extends React.Component<SchedulesPageProps, SchedulesPageSta
|
|||
},
|
||||
];
|
||||
|
||||
const moment = dayjs();
|
||||
const moment = dayjs().tz(store.currentTimezone);
|
||||
|
||||
const users = store.userStore.getSearchResult().results;
|
||||
|
||||
return (
|
||||
<>
|
||||
|
|
@ -105,13 +115,14 @@ class SchedulesPage extends React.Component<SchedulesPageProps, SchedulesPageSta
|
|||
<HorizontalGroup justify="space-between">
|
||||
<SchedulesFilters value={filters} onChange={this.handleSchedulesFiltersChange} />
|
||||
<HorizontalGroup spacing="lg">
|
||||
<HorizontalGroup>
|
||||
<Text type="secondary">Timezone:</Text>
|
||||
<Text type="primary">
|
||||
{getTzOffsetString(moment)} ({dayjs.tz.guess()})
|
||||
</Text>
|
||||
</HorizontalGroup>
|
||||
<Button variant="primary" onClick={this.handleCreateScheduleClick}>
|
||||
{users && (
|
||||
<UserTimezoneSelect
|
||||
value={store.currentTimezone}
|
||||
users={users}
|
||||
onChange={this.handleTimezoneChange}
|
||||
/>
|
||||
)}
|
||||
<Button size="sm" variant="primary" onClick={this.handleCreateScheduleClick}>
|
||||
+ New schedule
|
||||
</Button>
|
||||
</HorizontalGroup>
|
||||
|
|
@ -142,6 +153,14 @@ class SchedulesPage extends React.Component<SchedulesPageProps, SchedulesPageSta
|
|||
);
|
||||
}
|
||||
|
||||
handleTimezoneChange = (value: Timezone) => {
|
||||
const { store } = this.props;
|
||||
|
||||
store.currentTimezone = value;
|
||||
|
||||
this.setState({ startMoment: getStartOfWeek(value) });
|
||||
};
|
||||
|
||||
handleCreateScheduleClick = () => {
|
||||
this.setState({ showNewScheduleSelector: true });
|
||||
};
|
||||
|
|
@ -154,14 +173,20 @@ class SchedulesPage extends React.Component<SchedulesPageProps, SchedulesPageSta
|
|||
}
|
||||
};
|
||||
|
||||
renderSchedule = () => {
|
||||
renderSchedule = (data: Schedule) => {
|
||||
const { startMoment } = this.state;
|
||||
const { store } = this.props;
|
||||
|
||||
return (
|
||||
<div className={cx('schedule')}>
|
||||
<TimelineMarks startMoment={startMoment} />
|
||||
<div className={cx('rotations')}>
|
||||
<Rotation startMoment={startMoment} id={`${1}-${2}`} layerIndex={1} rotationIndex={2} />
|
||||
<ScheduleFinal
|
||||
hideHeader
|
||||
scheduleId={data.id}
|
||||
currentTimezone={store.currentTimezone}
|
||||
startMoment={startMoment}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ import { SlackStore } from 'models/slack/slack';
|
|||
import { SlackChannelStore } from 'models/slack_channel/slack_channel';
|
||||
import { TeamStore } from 'models/team/team';
|
||||
import { TelegramChannelStore } from 'models/telegram_channel/telegram_channel';
|
||||
import { Timezone } from 'models/timezone/timezone.types';
|
||||
import { UserStore } from 'models/user/user';
|
||||
import { UserGroupStore } from 'models/user_group/user_group';
|
||||
import { makeRequest } from 'network';
|
||||
|
|
@ -38,6 +39,9 @@ export class RootBaseStore {
|
|||
@observable
|
||||
appLoading = true;
|
||||
|
||||
@observable
|
||||
currentTimezone: Timezone = 'UTC';
|
||||
|
||||
@observable
|
||||
backendVersion = '';
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue