Event/task edit: handle timezones.

Fixes #29
master
Tom Hacohen 5 years ago
parent bfc54018ce
commit 3730300411

@ -20,6 +20,7 @@ import IconSave from '@material-ui/icons/Save';
import DateTimePicker from '../widgets/DateTimePicker'; import DateTimePicker from '../widgets/DateTimePicker';
import ConfirmationDialog from '../widgets/ConfirmationDialog'; import ConfirmationDialog from '../widgets/ConfirmationDialog';
import TimezonePicker from '../widgets/TimezonePicker';
import { Location } from 'history'; import { Location } from 'history';
import { withRouter } from 'react-router'; import { withRouter } from 'react-router';
@ -29,7 +30,9 @@ import * as ICAL from 'ical.js';
import * as EteSync from 'etesync'; import * as EteSync from 'etesync';
import { EventType } from '../pim-types'; import { getCurrentTimezone } from '../helpers';
import { EventType, timezoneLoadFromName } from '../pim-types';
interface PropsType { interface PropsType {
collections: EteSync.CollectionInfo[]; collections: EteSync.CollectionInfo[];
@ -48,6 +51,7 @@ class EventEdit extends React.PureComponent<PropsType> {
allDay: boolean; allDay: boolean;
start?: Date; start?: Date;
end?: Date; end?: Date;
timezone: string | null;
location: string; location: string;
description: string; description: string;
journalUid: string; journalUid: string;
@ -64,6 +68,7 @@ class EventEdit extends React.PureComponent<PropsType> {
allDay: false, allDay: false,
location: '', location: '',
description: '', description: '',
timezone: null,
journalUid: '', journalUid: '',
showDeleteDialog: false, showDeleteDialog: false,
@ -94,14 +99,17 @@ class EventEdit extends React.PureComponent<PropsType> {
this.state.uid = event.uid; this.state.uid = event.uid;
this.state.title = event.title ? event.title : ''; this.state.title = event.title ? event.title : '';
this.state.allDay = allDay; this.state.allDay = allDay;
this.state.start = event.startDate.toJSDate(); this.state.start = event.startDate.convertToZone(ICAL.Timezone.localTimezone).toJSDate();
this.state.end = endDate.toJSDate(); this.state.end = endDate.convertToZone(ICAL.Timezone.localTimezone).toJSDate();
this.state.location = event.location ? event.location : ''; this.state.location = event.location ? event.location : '';
this.state.description = event.description ? event.description : ''; this.state.description = event.description ? event.description : '';
this.state.timezone = event.timezone;
} else { } else {
this.state.uid = uuid.v4(); this.state.uid = uuid.v4();
} }
this.state.timezone = this.state.timezone || getCurrentTimezone();
if (props.initialCollection) { if (props.initialCollection) {
this.state.journalUid = props.initialCollection; this.state.journalUid = props.initialCollection;
} else if (props.collections[0]) { } else if (props.collections[0]) {
@ -189,6 +197,13 @@ class EventEdit extends React.PureComponent<PropsType> {
event.endDate = endDate; event.endDate = endDate;
event.location = this.state.location; event.location = this.state.location;
event.description = this.state.description; event.description = this.state.description;
if (this.state.timezone) {
const timezone = timezoneLoadFromName(this.state.timezone);
if (timezone) {
event.startDate = event.startDate?.convertToZone(timezone);
event.endDate = event.endDate?.convertToZone(timezone);
}
}
event.component.updatePropertyWithValue('last-modified', ICAL.Time.now()); event.component.updatePropertyWithValue('last-modified', ICAL.Time.now());
@ -218,6 +233,7 @@ class EventEdit extends React.PureComponent<PropsType> {
}; };
const recurring = this.props.item && this.props.item.isRecurring(); const recurring = this.props.item && this.props.item.isRecurring();
const differentTimezone = this.state.timezone && (this.state.timezone !== getCurrentTimezone()) && timezoneLoadFromName(this.state.timezone);
return ( return (
<React.Fragment> <React.Fragment>
@ -267,6 +283,9 @@ class EventEdit extends React.PureComponent<PropsType> {
value={this.state.start} value={this.state.start}
onChange={(date?: Date) => this.setState({ start: date })} onChange={(date?: Date) => this.setState({ start: date })}
/> />
{differentTimezone && this.state.start && (
<FormHelperText>{ICAL.Time.fromJSDate(this.state.start, false).convertToZone(differentTimezone!).toJSDate().toString()}</FormHelperText>
)}
</FormControl> </FormControl>
<FormControl> <FormControl>
@ -277,6 +296,9 @@ class EventEdit extends React.PureComponent<PropsType> {
value={this.state.end} value={this.state.end}
onChange={(date?: Date) => this.setState({ end: date })} onChange={(date?: Date) => this.setState({ end: date })}
/> />
{differentTimezone && this.state.end && (
<FormHelperText>{ICAL.Time.fromJSDate(this.state.end, false).convertToZone(differentTimezone!).toJSDate().toString()}</FormHelperText>
)}
</FormControl> </FormControl>
<FormGroup> <FormGroup>
@ -293,6 +315,10 @@ class EventEdit extends React.PureComponent<PropsType> {
/> />
</FormGroup> </FormGroup>
{(!this.state.allDay) && (
<TimezonePicker value={this.state.timezone} onChange={(zone) => this.setState({ timezone: zone })} />
)}
<TextField <TextField
name="location" name="location"
placeholder="Add location" placeholder="Add location"

@ -20,6 +20,7 @@ import IconSave from '@material-ui/icons/Save';
import DateTimePicker from '../widgets/DateTimePicker'; import DateTimePicker from '../widgets/DateTimePicker';
import ConfirmationDialog from '../widgets/ConfirmationDialog'; import ConfirmationDialog from '../widgets/ConfirmationDialog';
import TimezonePicker from '../widgets/TimezonePicker';
import { Location } from 'history'; import { Location } from 'history';
import { withRouter } from 'react-router'; import { withRouter } from 'react-router';
@ -29,7 +30,9 @@ import * as ICAL from 'ical.js';
import * as EteSync from 'etesync'; import * as EteSync from 'etesync';
import { TaskType, TaskStatusType } from '../pim-types'; import { getCurrentTimezone } from '../helpers';
import { TaskType, TaskStatusType, timezoneLoadFromName } from '../pim-types';
interface PropsType { interface PropsType {
collections: EteSync.CollectionInfo[]; collections: EteSync.CollectionInfo[];
@ -49,6 +52,7 @@ class TaskEdit extends React.PureComponent<PropsType> {
allDay: boolean; allDay: boolean;
start?: Date; start?: Date;
due?: Date; due?: Date;
timezone: string | null;
location: string; location: string;
description: string; description: string;
journalUid: string; journalUid: string;
@ -66,6 +70,7 @@ class TaskEdit extends React.PureComponent<PropsType> {
allDay: false, allDay: false,
location: '', location: '',
description: '', description: '',
timezone: null,
journalUid: '', journalUid: '',
showDeleteDialog: false, showDeleteDialog: false,
@ -79,17 +84,20 @@ class TaskEdit extends React.PureComponent<PropsType> {
this.state.status = event.status; this.state.status = event.status;
if (event.startDate) { if (event.startDate) {
this.state.allDay = event.startDate.isDate; this.state.allDay = event.startDate.isDate;
this.state.start = event.startDate.toJSDate(); this.state.start = event.startDate.convertToZone(ICAL.Timezone.localTimezone).toJSDate();
} }
if (event.dueDate) { if (event.dueDate) {
this.state.due = event.dueDate.toJSDate(); this.state.due = event.dueDate.convertToZone(ICAL.Timezone.localTimezone).toJSDate();
} }
this.state.location = event.location ? event.location : ''; this.state.location = event.location ? event.location : '';
this.state.description = event.description ? event.description : ''; this.state.description = event.description ? event.description : '';
this.state.timezone = event.timezone;
} else { } else {
this.state.uid = uuid.v4(); this.state.uid = uuid.v4();
} }
this.state.timezone = this.state.timezone || getCurrentTimezone();
if (props.initialCollection) { if (props.initialCollection) {
this.state.journalUid = props.initialCollection; this.state.journalUid = props.initialCollection;
} else if (props.collections[0]) { } else if (props.collections[0]) {
@ -177,6 +185,14 @@ class TaskEdit extends React.PureComponent<PropsType> {
event.dueDate = dueDate; event.dueDate = dueDate;
event.location = this.state.location; event.location = this.state.location;
event.description = this.state.description; event.description = this.state.description;
if (this.state.timezone) {
const timezone = timezoneLoadFromName(this.state.timezone);
if (timezone) {
event.startDate = event.startDate?.convertToZone(timezone);
event.dueDate = event.dueDate?.convertToZone(timezone);
event.completionDate = event.completionDate?.convertToZone(timezone);
}
}
event.component.updatePropertyWithValue('last-modified', ICAL.Time.now()); event.component.updatePropertyWithValue('last-modified', ICAL.Time.now());
@ -206,6 +222,7 @@ class TaskEdit extends React.PureComponent<PropsType> {
}; };
const recurring = this.props.item && this.props.item.isRecurring(); const recurring = this.props.item && this.props.item.isRecurring();
const differentTimezone = this.state.timezone && (this.state.timezone !== getCurrentTimezone()) && timezoneLoadFromName(this.state.timezone);
return ( return (
<React.Fragment> <React.Fragment>
@ -271,6 +288,9 @@ class TaskEdit extends React.PureComponent<PropsType> {
value={this.state.start} value={this.state.start}
onChange={(date?: Date) => this.setState({ start: date })} onChange={(date?: Date) => this.setState({ start: date })}
/> />
{differentTimezone && this.state.start && (
<FormHelperText>{ICAL.Time.fromJSDate(this.state.start, false).convertToZone(differentTimezone!).toJSDate().toString()}</FormHelperText>
)}
</FormControl> </FormControl>
<FormControl> <FormControl>
@ -281,6 +301,9 @@ class TaskEdit extends React.PureComponent<PropsType> {
value={this.state.due} value={this.state.due}
onChange={(date?: Date) => this.setState({ due: date })} onChange={(date?: Date) => this.setState({ due: date })}
/> />
{differentTimezone && this.state.due && (
<FormHelperText>{ICAL.Time.fromJSDate(this.state.due, false).convertToZone(differentTimezone!).toJSDate().toString()}</FormHelperText>
)}
</FormControl> </FormControl>
<FormGroup> <FormGroup>
@ -297,6 +320,10 @@ class TaskEdit extends React.PureComponent<PropsType> {
/> />
</FormGroup> </FormGroup>
{(!this.state.allDay) && (
<TimezonePicker value={this.state.timezone} onChange={(zone) => this.setState({ timezone: zone })} />
)}
<TextField <TextField
name="location" name="location"
placeholder="Add location" placeholder="Add location"

Loading…
Cancel
Save