decide.nolog.cz/app/components/create-options-dates.js
2023-10-15 20:37:03 +02:00

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');
}
}