decide.nolog.cz/app/components/create-options-dates.js

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