87 lines
2.7 KiB
JavaScript
87 lines
2.7 KiB
JavaScript
import Component from '@glimmer/component';
|
|
import { action } from '@ember/object';
|
|
import { isArray } from '@ember/array';
|
|
import { DateTime } from 'luxon';
|
|
import { tracked } from '@glimmer/tracking';
|
|
|
|
export default class CreateOptionsDates extends Component {
|
|
@tracked calendarCenter =
|
|
this.selectedDays.length >= 1 ? this.selectedDays[0] : DateTime.local();
|
|
|
|
get selectedDays() {
|
|
// Options may contain the same date multiple times with different ime
|
|
// Must filter out those duplicates as otherwise unselect would only
|
|
// remove one entry but not all duplicates.
|
|
return this.args.options
|
|
.map(({ value }) => DateTime.fromISO(value).toISODate())
|
|
.uniq()
|
|
.map((isoDate) => DateTime.fromISO(isoDate));
|
|
}
|
|
|
|
get calendarCenterNext() {
|
|
return this.calendarCenter.plus({ months: 1 });
|
|
}
|
|
|
|
@action
|
|
handleSelectedDaysChange({ datetime: newDatesAsLuxonDateTime }) {
|
|
if (!isArray(newDatesAsLuxonDateTime)) {
|
|
// special case: all options are unselected
|
|
this.args.updateOptions([]);
|
|
return;
|
|
}
|
|
|
|
// A date has either been added or removed. If it has been removed, we must
|
|
// remove all options for that date. It may be multiple options with
|
|
// different times at that date.
|
|
|
|
// If any date received as an input argument is _not_ yet in the list of
|
|
// dates, it has been added.
|
|
const dateAdded = newDatesAsLuxonDateTime.find((newDateAsLuxonDateTime) => {
|
|
return !this.selectedDays.some(
|
|
(selectedDay) =>
|
|
selectedDay.toISODate() === newDateAsLuxonDateTime.toISODate()
|
|
);
|
|
});
|
|
|
|
if (dateAdded) {
|
|
this.args.updateOptions(
|
|
[
|
|
...this.args.options.map(({ value }) => value),
|
|
dateAdded.toISODate(),
|
|
].sort()
|
|
);
|
|
return;
|
|
}
|
|
|
|
// If no date has been added, one date must have been removed. It has been
|
|
// removed if there is one date in current selectedDays but not in the new
|
|
// dates received as input argument to the function.
|
|
const dateRemoved = this.selectedDays.find((selectedDay) => {
|
|
return !newDatesAsLuxonDateTime.some(
|
|
(newDateAsLuxonDateTime) =>
|
|
newDateAsLuxonDateTime.toISODate() === selectedDay.toISODate()
|
|
);
|
|
});
|
|
|
|
if (dateRemoved) {
|
|
this.args.updateOptions(
|
|
this.args.options
|
|
.filter(
|
|
({ value }) =>
|
|
DateTime.fromISO(value).toISODate() !== dateRemoved.toISODate()
|
|
)
|
|
.map(({ value }) => value)
|
|
);
|
|
return;
|
|
}
|
|
|
|
throw new Error(
|
|
'No date has been added or removed. This cannot be the case. Something spooky is going on.'
|
|
);
|
|
}
|
|
|
|
@action
|
|
updateCalenderCenter(diff) {
|
|
this.calendarCenter = this.calendarCenter.add(diff, 'months');
|
|
}
|
|
}
|