Skip to content

Commit

Permalink
Support default time in DateTimePicker #3465
Browse files Browse the repository at this point in the history
  • Loading branch information
alansemenov committed Feb 20, 2024
1 parent 0f35727 commit e42d53e
Show file tree
Hide file tree
Showing 8 changed files with 135 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {AdditionalValidationRecord} from '../../AdditionalValidationRecord';
import {InputTypeManager} from '../InputTypeManager';
import {Class} from '../../../Class';
import {InputTypeName} from '../../InputTypeName';
import {TimeHM} from '../../../util/TimeHM';

declare const Date: DateConstructor;

Expand All @@ -24,6 +25,8 @@ export class DateTimeRange
private useTimezone: boolean;
private from: DateTime | LocalDateTime;
private to: DateTime | LocalDateTime;
private defaultStartTime: TimeHM;
private defaultEndTime: TimeHM;

private errors: {
noStart: string
Expand Down Expand Up @@ -167,6 +170,18 @@ export class DateTimeRange
startEqualsEnd: this.readConfigValue(inputConfig, 'errorStartEqualsEnd') ||
i18n('field.dateTimeRange.errors.startEqualsEnd', this.labels.start, this.labels.end)
};

this.defaultStartTime = this.getDefaultTimeFromConfig(inputConfig, 'defaultStartTime');
this.defaultEndTime = this.getDefaultTimeFromConfig(inputConfig, 'defaultEndTime');
}

private getDefaultTimeFromConfig(inputConfig: Record<string, string>, name: string): TimeHM {
const time: string = this.readConfigValue(inputConfig, name);
if (!time) {
return null;
}
const timeArray: string[] = time.split(':');
return new TimeHM(parseInt(timeArray[0] || '0'), parseInt(timeArray[1] || '0'));
}

private readConfigValue(inputConfig: Record<string, any>, name: string): string {
Expand All @@ -176,7 +191,9 @@ export class DateTimeRange
private createInputAsLocalDateTime(property: Property): DateTimeRangePicker {
const rangeBuilder: DateTimeRangePickerBuilder = new DateTimeRangePickerBuilder()
.setStartLabel(this.labels.start)
.setEndLabel(this.labels.end);
.setEndLabel(this.labels.end)
.setDefaultStartTime(this.defaultStartTime)
.setDefaultEndTime(this.defaultEndTime);

this.setFromTo(rangeBuilder, property);

Expand Down
10 changes: 6 additions & 4 deletions src/main/resources/assets/admin/common/js/ui/time/Calendar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -255,15 +255,17 @@ export class Calendar
}

private handleCalendarDayClicked(event: CalendarDayClickedEvent) {

this.calendarDays.forEach((calendarDay: CalendarDay) => {
calendarDay.setSelectedDay(event.getCalendarDay().equals(calendarDay));
});
this.resetSelectedDays();
this.calendarDays.find((calendarDay) => calendarDay.equals(event.getCalendarDay())).setSelectedDay(true);

this.selectedDate = event.getCalendarDay().getDate();
this.notifySelectedDateChanged(this.selectedDate);
}

resetSelectedDays() {
this.calendarDays.filter((calendarDay) => calendarDay.isSelected()).forEach((calendarDay) => calendarDay.resetSelected());
}

private notifySelectedDateChanged(date: Date) {
let event = new SelectedDateChangedEvent(date);
this.selectedDateChangedListeners.forEach((listener) => {
Expand Down
12 changes: 12 additions & 0 deletions src/main/resources/assets/admin/common/js/ui/time/CalendarDay.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,18 @@ export class CalendarDay
this.refreshSelectedDay();
}

isSelected(): boolean {
return this.selectedDay;
}

resetSelected() {
if (!this.selectedDay) {
return;
}
this.selectedDay = false;
this.removeClass('selected-day');
}

refreshSelectedDay() {
if (this.selectedDay && !this.hasClass('selected-day')) {
this.addClass('selected-day');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,10 @@ export class DatePickerPopup
this.calendar.selectDate(date, silent);
}

resetCalendar() {
this.calendar.resetSelectedDays();
}

getSelectedDate(): Date {
return this.calendar.getSelectedDate();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,13 @@ export class DateTimePickerBuilder

defaultValue: Date;

defaultTime: TimeHM;

setDefaultTime(value: TimeHM): DateTimePickerBuilder {
this.defaultTime = value;
return this;
}

setDefaultValue(value: Date): DateTimePickerBuilder {
this.defaultValue = value;
return this;
Expand Down Expand Up @@ -126,6 +133,9 @@ export class DateTimePicker
.setManageDate(this.builder.manageDate)
.setManageTime(this.builder.manageTime);

if (!this.selectedDateTime) {
popupBuilder.setDefaultTime(this.builder.defaultTime);
}

if (this.builder.timezone) {
popupBuilder.setTimezone(this.builder.timezone);
Expand All @@ -152,9 +162,14 @@ export class DateTimePicker

const newDate: Date = new Date(e.getDate());

if (this.builder.manageTime && this.selectedDateTime) {
newDate.setHours(this.selectedDateTime.getHours());
newDate.setMinutes(this.selectedDateTime.getMinutes());
if (this.builder.manageTime) {
if (this.selectedDateTime) {
newDate.setHours(this.selectedDateTime.getHours());
newDate.setMinutes(this.selectedDateTime.getMinutes());
} else if (this.builder.defaultTime) {
newDate.setHours(this.builder.defaultTime.hours);
newDate.setMinutes(this.builder.defaultTime.minutes);
}
}

this.setDateTime(newDate);
Expand All @@ -180,6 +195,9 @@ export class DateTimePicker
};

const onThisDateTimePickerShown = () => {
if (!this.selectedDateTime) {
this.popup.resetCalendar();
}
new DateTimePickerShownEvent(this).fire();
DateTimePickerShownEvent.on(onAnyDateTimePickerShown);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ export class DateTimePickerPopupBuilder {

timezone: Timezone;

defaultTime: TimeHM;

// use local timezone if timezone value is not initialized
useLocalTimezoneIfNotPresent: boolean = false;

Expand Down Expand Up @@ -66,6 +68,11 @@ export class DateTimePickerPopupBuilder {
return this;
}

setDefaultTime(value: TimeHM): DateTimePickerPopupBuilder {
this.defaultTime = value;
return this;
}

isUseLocalTimezoneIfNotPresent(): boolean {
return this.useLocalTimezoneIfNotPresent;
}
Expand All @@ -87,7 +94,7 @@ export class DateTimePickerPopup

private readonly timePickerPopup?: TimePickerPopup;

private defaultValueButton : Button;
private readonly defaultValueButton : Button;

constructor(builder: DateTimePickerPopupBuilder) {
super('date-time-dialog');
Expand All @@ -110,6 +117,7 @@ export class DateTimePickerPopup
.setTimezone(builder.timezone)
.setUseLocalTimezoneIfNotPresent(builder.useLocalTimezoneIfNotPresent)
.setMinutes(builder.getMinutes())
.setDefaultTime(builder.defaultTime)
.build();
}
}
Expand Down Expand Up @@ -184,4 +192,9 @@ export class DateTimePickerPopup
setSelectedDate(date: Date, silent?: boolean) {
this.datePickerPopup?.setSelectedDate(date, silent);
}

resetCalendar() {
this.datePickerPopup?.resetCalendar();
this.timePickerPopup?.presetTime();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,23 @@ import * as Q from 'q';
import {Timezone} from '../../util/Timezone';
import {DivEl} from '../../dom/DivEl';
import {DateTimePicker, DateTimePickerBuilder} from './DateTimePicker';
import {StringHelper} from '../../util/StringHelper';
import {Element} from '../../dom/Element';
import {LabelEl} from '../../dom/LabelEl';
import {DayOfWeek} from './DayOfWeek';
import {DaysOfWeek} from './DaysOfWeek';
import {SelectedDateChangedEvent} from './SelectedDateChangedEvent';
import {TimeHM} from '../../util/TimeHM';

export class DateTimeRangePickerBuilder {

startDate: Date;

endDate: Date;

defaultStartTime: TimeHM;

defaultEndTime: TimeHM;

startLabel: string;

endLabel: string;
Expand Down Expand Up @@ -68,6 +72,16 @@ export class DateTimeRangePickerBuilder {
return this;
}

setDefaultStartTime(value: TimeHM): DateTimeRangePickerBuilder {
this.defaultStartTime = value;
return this;
}

setDefaultEndTime(value: TimeHM): DateTimeRangePickerBuilder {
this.defaultEndTime = value;
return this;
}

build(): DateTimeRangePicker {
return new DateTimeRangePicker(this);
}
Expand All @@ -76,17 +90,17 @@ export class DateTimeRangePickerBuilder {

export class DateTimeRangePicker
extends DivEl {
private startLabel: string;
private startPicker: DateTimePicker;
private endLabel: string;
private endPicker: DateTimePicker;
private readonly startLabel: string;
private readonly startPicker: DateTimePicker;
private readonly endLabel: string;
private readonly endPicker: DateTimePicker;

constructor(builder: DateTimeRangePickerBuilder) {
super('date-time-range-picker');
this.startLabel = builder.startLabel;
this.startPicker = this.createPicker(builder, 0);
this.startPicker = this.createPicker(builder, 0, builder.defaultStartTime);
this.endLabel = builder.endLabel;
this.endPicker = this.createPicker(builder, 1);
this.endPicker = this.createPicker(builder, 1, builder.defaultEndTime);
}

doRender(): Q.Promise<boolean> {
Expand Down Expand Up @@ -166,7 +180,7 @@ export class DateTimeRangePicker
this.endPicker.clear();
}

private createPicker(builder: DateTimeRangePickerBuilder, index: number = 0): DateTimePicker {
private createPicker(builder: DateTimeRangePickerBuilder, index: number = 0, defaultTime: TimeHM): DateTimePicker {
const b = new DateTimePickerBuilder()
.setStartingDayOfWeek(builder.startingDayOfWeek)
.setCloseOnSelect(builder.closeOnSelect)
Expand All @@ -177,12 +191,16 @@ export class DateTimeRangePicker
case 1:
if (builder.endDate) {
b.setDateTime(builder.endDate);
} else {
b.setDefaultTime(builder.defaultEndTime);
}
break;
case 0:
default:
if (builder.startDate) {
b.setDateTime(builder.startDate);
} else {
b.setDefaultTime(builder.defaultStartTime);
}
break;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ export class TimePickerPopupBuilder {
// use local timezone if timezone value is not initialized
useLocalTimezoneIfNotPresent: boolean = false;

defaultTime: TimeHM;

setHours(value: number): TimePickerPopupBuilder {
this.hours = value;
return this;
Expand Down Expand Up @@ -55,6 +57,15 @@ export class TimePickerPopupBuilder {
return this.useLocalTimezoneIfNotPresent;
}

setDefaultTime(value: TimeHM): TimePickerPopupBuilder {
this.defaultTime = value;
return this;
}

getDefaultTime(): TimeHM {
return this.defaultTime;
}

build(): TimePickerPopup {
return new TimePickerPopup(this);
}
Expand Down Expand Up @@ -82,26 +93,26 @@ export class TimePickerPopup
private useLocalTimezoneIfNotPresent: boolean = false;

private timeChangedListeners: ((time: TimeHM) => void)[] = [];
private builder: TimePickerPopupBuilder;

constructor(builder: TimePickerPopupBuilder) {
super('time-picker-dialog');

this.initElements(builder);
this.builder = builder;
this.initElements();
this.initListeners();
}

protected initElements(builder: TimePickerPopupBuilder): void {
protected initElements(): void {
this.nextHour = new AEl('next');
this.hour = new SpanEl();
this.prevHour = new AEl('prev');
this.nextMinute = new AEl('next');
this.minute = new SpanEl();
this.prevMinute = new AEl('prev');
this.selectedHour = DateHelper.isHoursValid(builder.getHours()) ? builder.getHours() : null;
this.selectedMinute = DateHelper.isMinutesValid(builder.getMinutes()) ? builder.getMinutes() : null;

this.useLocalTimezoneIfNotPresent = builder.useLocalTimezoneIfNotPresent;
this.timezone = builder.timezone;
this.useLocalTimezoneIfNotPresent = this.builder.useLocalTimezoneIfNotPresent;
this.timezone = this.builder.timezone;

if (!this.timezone && this.useLocalTimezoneIfNotPresent) {
this.timezone = Timezone.getLocalTimezone();
Expand All @@ -112,6 +123,12 @@ export class TimePickerPopup
this.timezoneOffset = new SpanEl('timezone-offset').setHtml(this.getUTCString(this.timezone.getOffset()));
}

this.presetTime();
}

presetTime() {
this.selectedHour = this.getDefaultHours(this.builder);
this.selectedMinute = this.getDefaultMinutes(this.builder);
this.hour.setHtml(DateHelper.padNumber(this.selectedHour));
this.minute.setHtml(DateHelper.padNumber(this.selectedMinute));
}
Expand Down Expand Up @@ -181,7 +198,7 @@ export class TimePickerPopup
}

setSelectedTime(time: TimeHM, silent?: boolean): void {
if (DateHelper.isHoursValid(time.hours) && DateHelper.isMinutesValid(time.minutes)) {
if (time && DateHelper.isHoursValid(time.hours) && DateHelper.isMinutesValid(time.minutes)) {
this.selectedHour = time.hours;
this.selectedMinute = time.minutes;
} else {
Expand Down Expand Up @@ -259,6 +276,16 @@ export class TimePickerPopup
});
}

private getDefaultHours(builder: TimePickerPopupBuilder): number {
const hours = builder.getHours() || builder.getDefaultTime()?.hours || 0;
return DateHelper.isHoursValid(hours) ? hours : null;
}

private getDefaultMinutes(builder: TimePickerPopupBuilder): number {
const minutes = builder.getMinutes() || builder.getDefaultTime()?.minutes || 0;
return DateHelper.isMinutesValid(minutes) ? minutes : null;
}

doRender(): Q.Promise<boolean> {
return super.doRender().then((rendered: boolean) => {
const hourContainer: LiEl = new LiEl();
Expand Down

0 comments on commit e42d53e

Please sign in to comment.