91 lines
2.6 KiB
JavaScript
91 lines
2.6 KiB
JavaScript
import classic from 'ember-classic-decorator';
|
|
import { action, computed } from '@ember/object';
|
|
import { inject as service } from '@ember/service';
|
|
import Component from '@ember/component';
|
|
import { isArray } from '@ember/array';
|
|
import { isPresent } from '@ember/utils';
|
|
import { DateTime } from "luxon";
|
|
|
|
@classic
|
|
export default class CreateOptionsDates extends Component {
|
|
@service('store')
|
|
store;
|
|
|
|
@computed('options.[]')
|
|
get selectedDays() {
|
|
return this.options
|
|
// should be unique
|
|
.uniqBy('day')
|
|
// filter out invalid
|
|
.filter(({ isDate }) => isDate)
|
|
// raw dates
|
|
.map(({ datetime }) => datetime)
|
|
.toArray();
|
|
}
|
|
|
|
@computed('calendarCenter')
|
|
get calendarCenterNext() {
|
|
return this.calendarCenter.plus({ months: 1 });
|
|
}
|
|
|
|
@action
|
|
daysSelected({ datetime: newDatesAsLuxonDateTime }) {
|
|
let { options } = this;
|
|
|
|
if (!isArray(newDatesAsLuxonDateTime)) {
|
|
// special case: all options are unselected
|
|
options.clear();
|
|
return;
|
|
}
|
|
|
|
const newDates = newDatesAsLuxonDateTime.map((dateAsLuxonDateTime) => {
|
|
return dateAsLuxonDateTime.toISODate();
|
|
});
|
|
|
|
// array of options that represent days missing in updated selection
|
|
let removedOptions = options.filter((option) => {
|
|
return !newDates.find((newDate) => newDate === option.day);
|
|
});
|
|
|
|
// array of dates that aren't represented yet by an option
|
|
let addedDates = newDates.filter((newDate) => {
|
|
return !options.find((option) => newDate === option.day);
|
|
});
|
|
|
|
// remove options that represent deselected days
|
|
options.removeObjects(removedOptions);
|
|
|
|
// add options for newly selected days
|
|
let newOptions = addedDates.map((newDate) => {
|
|
return this.store.createFragment('option', {
|
|
title: newDate,
|
|
})
|
|
});
|
|
newOptions.forEach((newOption) => {
|
|
// options must be insert into options array at correct position
|
|
let insertBefore = options.find((option) => {
|
|
if (!option.isDate) {
|
|
// ignore options that do not represent a valid date
|
|
return false;
|
|
}
|
|
|
|
return option.title > newOption.title;
|
|
});
|
|
let position = isPresent(insertBefore) ? options.indexOf(insertBefore) : options.length;
|
|
options.insertAt(position, newOption);
|
|
});
|
|
}
|
|
|
|
@action
|
|
updateCalenderCenter(diff) {
|
|
this.calendarCenter.add(diff, 'months');
|
|
this.notifyPropertyChange('calenderCenter');
|
|
}
|
|
|
|
init() {
|
|
super.init(arguments);
|
|
|
|
let { selectedDays } = this;
|
|
this.set('calendarCenter', selectedDays.length >= 1 ? selectedDays[0] : DateTime.local());
|
|
}
|
|
}
|