Skip to content

Commit

Permalink
allow creation of events without start/end time
Browse files Browse the repository at this point in the history
STT-40
  • Loading branch information
petrjasek committed Dec 11, 2024
1 parent a15abe9 commit 8c985de
Show file tree
Hide file tree
Showing 28 changed files with 506 additions and 287 deletions.
4 changes: 4 additions & 0 deletions client/components/Events/EventDateTime.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ export class EventDateTime extends React.PureComponent<IProps> {
date={start}
{...commonProps}
withTime={false}
testId="event-start-date"
/>
)}
{gettext('All day')}
Expand All @@ -95,9 +96,11 @@ export class EventDateTime extends React.PureComponent<IProps> {
</span>
)}
<DateTime
withTime={!isFullDay}
withDate={showEventStartDate}
withYear={withYear}
date={start}
testId="event-start-date"
{...commonProps}
/>
{showDash && <>&ndash;</>}
Expand All @@ -106,6 +109,7 @@ export class EventDateTime extends React.PureComponent<IProps> {
withYear={withYear}
isEndEventDateTime={true}
date={end}
testId="event-end-date"
{...commonProps}
/>
{isRemoteTimeZone && (
Expand Down
6 changes: 5 additions & 1 deletion client/components/Events/EventDateTimeColumn.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ export class EventDateTimeColumn extends React.PureComponent<IProps> {
withYear={!isThisYear}
withTime={false}
date={start}
testId="event-start-date"
{...commonProps}
/>
{!multiDay ? null : (
Expand All @@ -62,13 +63,14 @@ export class EventDateTimeColumn extends React.PureComponent<IProps> {
withYear={!isThisYear}
withTime={false}
date={end}
testId="event-end-date"
{...commonProps}
/>
</React.Fragment>
)}
{!isRemoteTimeZone ? null : (
<span className="sd-margin-l--0-5">(
<span className="EventDateTime__timezone">
<span className="EventDateTime__timezone" data-test-id="event-timezone">
{tzCode}
</span>
)</span>
Expand All @@ -85,13 +87,15 @@ export class EventDateTimeColumn extends React.PureComponent<IProps> {
withDate={false}
withYear={false}
date={start}
testId="event-start-date"
{...commonProps}
/>
&ndash;
<DateTime
withDate={false}
withYear={false}
date={end}
testId="event-end-date"
{...commonProps}
/>
</React.Fragment>
Expand Down
2 changes: 2 additions & 0 deletions client/components/Events/EventEditor/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,8 @@ class EventEditorComponent extends React.PureComponent<IProps> {
start: value['dates.start'],
end: value['dates.end'],
tz: value['dates.tz'],
all_day: value['dates.all_day'],
no_end_time: value['dates.no_end_time'],
});

this.props.onChangeHandler(value);
Expand Down
4 changes: 3 additions & 1 deletion client/components/UI/DateTime.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ interface IPropsDateTime {
isEndEventDateTime?: boolean,
noEndTime?: boolean,
multiDay?: boolean,
testId?: string,
}

/**
Expand All @@ -37,6 +38,7 @@ function DateTime({
isEndEventDateTime,
noEndTime,
multiDay,
testId,
}: IPropsDateTime) {
const {gettext} = superdeskApi.localization;
const dateFormat = appConfig.planning.dateformat;
Expand Down Expand Up @@ -78,7 +80,7 @@ function DateTime({
const tz = timeUtils.getTimeZoneAbbreviation(date.format('z')) + ' ';

return (
<time className={!padLeft ? 'Datetime' : null} title={tz + displayDate}>
<time className={!padLeft ? 'Datetime' : null} title={tz + displayDate} data-test-id={testId}>
{displayDate}
</time>
);
Expand Down
46 changes: 25 additions & 21 deletions client/components/UI/Form/DateInput/DateInputPopup.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import React from 'react';
import PropTypes from 'prop-types';
import moment from 'moment-timezone';
import {Popup, Content, Header, Footer} from '../../Popup';
import {Button} from '../../';
Expand All @@ -11,14 +10,35 @@ import {gettext} from '../../utils';

import './style.scss';

interface IProps {
value?: string | moment.Moment;
onChange(value: moment.Moment): void;
close(): void;
target: string;
maxMode?: string;
yearRange?: number;
popupContainer(): HTMLElement;
onPopupOpen?(): void;
onPopupClose?(): void;
remoteTimeZone?: string;
}

interface IState {
mode: 'day' | 'month' | 'year';
modeTitle: string;
currentDate: moment.Moment;
selectedDate: moment.Moment;
}

/**
* @ngdoc react
* @name DateInputPopup
* @description Main Popup Component of DatePicker
*/
export class DateInputPopup extends React.Component {
export class DateInputPopup extends React.Component<IProps, IState> {
constructor(props) {
super(props);

const currentDate = props.remoteTimeZone ?
moment.tz(props.remoteTimeZone) :
moment();
Expand All @@ -27,7 +47,7 @@ export class DateInputPopup extends React.Component {
mode: 'day',
modeTitle: this.getModeTitle(currentDate, 'day'),
currentDate: currentDate,
selectedDate: currentDate,
selectedDate: currentDate.clone(),
};

this.handleModeChange = this.handleModeChange.bind(this);
Expand Down Expand Up @@ -148,7 +168,7 @@ export class DateInputPopup extends React.Component {
* @description handleSelectChange changes mode from days-months-year
*/
handleSelectChange(newDate) {
let nextMode = '';
let nextMode;

switch (this.state.mode) {
case 'month':
Expand Down Expand Up @@ -253,20 +273,4 @@ export class DateInputPopup extends React.Component {
</Popup>
);
}
}

DateInputPopup.propTypes = {
value: PropTypes.oneOfType([
PropTypes.string,
PropTypes.instanceOf(moment),
]),
onChange: PropTypes.func.isRequired,
close: PropTypes.func.isRequired,
target: PropTypes.string.isRequired,
maxMode: PropTypes.string,
yearRange: PropTypes.number,
popupContainer: PropTypes.func,
onPopupOpen: PropTypes.func,
onPopupClose: PropTypes.func,
remoteTimeZone: PropTypes.string,
};
}
40 changes: 20 additions & 20 deletions client/components/UI/Form/DateInput/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ interface IProps {
remoteTimeZone?: string;
isLocalTimeZoneDifferent?: boolean;
inputAsLabel?: boolean;
dateOnly?: boolean;

onChange(field: string, value: moment.Moment): void;
popupContainer(): HTMLElement;
Expand Down Expand Up @@ -63,14 +64,14 @@ export class DateInput extends React.Component<IProps, IState> {
viewValue: this.props.value != null && moment.isMoment(this.props.value) ?
this.props.value.format(appConfig.planning.dateformat) :
'',
previousValidValue: null,
previousValidValue: undefined,
};
this.dom = {inputField: null};

this.validateDateText = this.validateDateText.bind(this);
this.onInputChange = this.onInputChange.bind(this);
this.handleInputBlur = this.handleInputBlur.bind(this);
this.toggleOpenDatePicker = this.toggleOpenDatePicker.bind(this);
this.onChange = this.onChange.bind(this);
this.onPopupChange = this.onPopupChange.bind(this);
}

componentWillReceiveProps(nextProps) {
Expand Down Expand Up @@ -104,22 +105,18 @@ export class DateInput extends React.Component<IProps, IState> {
}

/**
* @ngdoc method
* @name DateInput#validateDateText
* @description validateDateText sets validate-state after text-input of dates
* sets validate-state after text-input of dates
*/
validateDateText(field, val) {
const valMoment = this.props.remoteTimeZone ?
moment.tz(val, appConfig.planning.dateformat, true, this.props.remoteTimeZone) :
moment(val, appConfig.planning.dateformat, true);
onInputChange(field, val) {
const valMoment = moment(val, appConfig.planning.dateformat, true);

if (valMoment.isValid()) {
this.setState({
invalid: false,
viewValue: valMoment.format(appConfig.planning.dateformat),
previousValidValue: valMoment,
});
this.onChange(valMoment);
this.onPopupChange(valMoment);
} else {
this.setState({
invalid: true,
Expand All @@ -146,15 +143,17 @@ export class DateInput extends React.Component<IProps, IState> {
}
}

onChange(newValue) {
onPopupChange(newValue: moment.Moment) {
const {value, onChange, field, remoteTimeZone} = this.props;
let newMoment = newValue;
const newMoment = remoteTimeZone ? moment.tz(newValue, remoteTimeZone) : moment(newValue);

if (!moment.isMoment(newMoment)) {
newMoment = moment.tz(newValue, remoteTimeZone);
}
this.setState({
invalid: false,
viewValue: newMoment.format(appConfig.planning.dateformat),
previousValidValue: newMoment,
});

if (newMoment.isValid() && (!newMoment.isSame(value) || !value)) {
if (newMoment.isValid() && (value == null || !newMoment.isSame(value))) {
onChange(field, newMoment);
}
}
Expand All @@ -178,9 +177,10 @@ export class DateInput extends React.Component<IProps, IState> {
} = this.props;

let {message, invalid} = this.props;
const eventTimeZoneString = timeUtils.getDateInRemoteTimeZone(value, remoteTimeZone).format('z');
let displayDateString;

const eventTimeZoneString = value ? timeUtils.getDateInRemoteTimeZone(value, remoteTimeZone).format('z') : null;

if (moment.isMoment(value) && isLocalTimeZoneDifferent) {
const displayDate = timeUtils.getDateInRemoteTimeZone(value, timeUtils.localTimeZone());

Expand Down Expand Up @@ -217,7 +217,7 @@ export class DateInput extends React.Component<IProps, IState> {
field={field}
value={this.state.viewValue}
placeholder={placeholder || gettext('Date')}
onChange={this.validateDateText}
onChange={this.onInputChange}
onFocus={onFocus}
onBlur={this.handleInputBlur}
type="text"
Expand All @@ -241,7 +241,7 @@ export class DateInput extends React.Component<IProps, IState> {
{this.state.openDatePicker && (
<DateInputPopup
value={value}
onChange={this.onChange}
onChange={this.onPopupChange}
close={this.toggleOpenDatePicker}
target="icon-calendar"
popupContainer={popupContainer}
Expand Down
Loading

0 comments on commit 8c985de

Please sign in to comment.