use real data in UsertimezoneSelect

This commit is contained in:
Maxim 2022-07-27 13:48:19 +03:00
parent 30ff3e840d
commit d85a3f615d
11 changed files with 147 additions and 85 deletions

View file

@ -115,8 +115,8 @@ class Rotations extends Component<RotationsProps, RotationsState> {
onHide={() => {
this.setState({ layerIdToCreateRotation: undefined });
}}
onUpdate={onCreate}
onCreate={onUpdate}
onUpdate={onUpdate}
onCreate={onCreate}
/>
)}
</>

View file

@ -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);

View file

@ -68,8 +68,8 @@ class ScheduleOverrides extends Component<ScheduleOverridesProps, ScheduleOverri
onHide={() => {
this.setState({ showAddOverrideForm: false });
}}
onUpdate={onCreate}
onCreate={onUpdate}
onUpdate={onUpdate}
onCreate={onCreate}
/>
)}
</>

View file

@ -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]
);

View file

@ -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..." />

View file

@ -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

View file

@ -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();

View file

@ -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],

View file

@ -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 = () => {

View file

@ -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>
);

View file

@ -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 = '';