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

88 lines
2.5 KiB
JavaScript
Raw Normal View History

import classic from 'ember-classic-decorator';
import { action, computed } from '@ember/object';
2018-12-29 01:27:37 +01:00
import { inject as service } from '@ember/service';
import Component from '@ember/component';
2018-12-29 01:27:37 +01:00
import { isArray } from '@ember/array';
import { isPresent } from '@ember/utils';
import moment from 'moment';
@classic
export default class CreateOptionsDates extends Component {
@service('store')
store;
@computed('options.[]')
get selectedDays() {
return this.options
// should be unique
.uniqBy('day')
// raw dates
.map(({ date }) => date)
// filter out invalid
.filter(moment.isMoment)
.toArray();
}
@computed('calendarCenter')
get calendarCenterNext() {
return moment(this.calendarCenter).add(1, 'months');
}
@action
daysSelected({ moment: newMoments }) {
let { options } = this;
if (!isArray(newMoments)) {
// special case: all options are unselected
options.clear();
return;
}
// array of options that represent days missing in updated selection
let removedOptions = options.filter((option) => {
return !newMoments.find((newMoment) => newMoment.format('YYYY-MM-DD') === option.day);
});
// array of moments that aren't represented yet by an option
let addedMoments = newMoments.filter((moment) => {
return !options.find((option) => moment.format('YYYY-MM-DD') === option.day);
});
// remove options that represent deselected days
options.removeObjects(removedOptions);
// add options for newly selected days
let newOptions = addedMoments.map((moment) => {
return this.store.createFragment('option', {
title: moment.format('YYYY-MM-DD'),
})
});
newOptions.forEach((newOption) => {
// options must be insert into options array at correct position
let insertBefore = options.find(({ date }) => {
if (!moment.isMoment(date)) {
// ignore options that do not represent a valid date
return false;
}
return date.isAfter(newOption.date);
});
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] : moment());
}
}