import ngModule from '../module'; import Section from 'salix/components/section'; import './style.scss'; class Controller extends Section { constructor($element, $) { super($element, $); this.date = new Date(); this.events = {}; this.buildYearFilter(); } get year() { return this.date.getFullYear(); } set year(value) { const newYear = new Date(); newYear.setFullYear(value); this.date = newYear; this.refresh().then(() => this.repaint()); } get date() { return this._date; } set date(value) { this._date = value; value.setHours(0, 0, 0, 0); const started = new Date(value.getTime()); started.setMonth(0); started.setDate(1); this.started = started; const ended = new Date(value.getTime()); ended.setMonth(12); ended.setDate(0); this.ended = ended; this.months = new Array(12); for (let i = 0; i < this.months.length; i++) { const now = new Date(value.getTime()); now.setDate(1); now.setMonth(i); this.months[i] = now; } } get worker() { return this._worker; } set worker(value) { this._worker = value; if (value) { this.refresh().then(() => this.repaint()); this.getIsSubordinate(); } } buildYearFilter() { const currentYear = new Date().getFullYear(); const minRange = currentYear - 5; const years = []; for (let i = currentYear; i > minRange; i--) years.push({year: i}); this.yearFilter = years; } getIsSubordinate() { this.$http.get(`Workers/${this.worker.id}/isSubordinate`).then(res => this.isSubordinate = res.data ); } onData(data) { this.events = {}; this.calendar = data.calendar; let addEvent = (day, event) => { this.events[new Date(day).getTime()] = event; }; if (data.holidays) { data.holidays.forEach(holiday => { const holidayDetail = holiday.detail && holiday.detail.description; const holidayType = holiday.type && holiday.type.name; const holidayName = holidayDetail || holidayType; addEvent(holiday.dated, { name: holidayName, color: '#ff0' }); }); } if (data.absences) { data.absences.forEach(absence => { let type = absence.absenceType; addEvent(absence.dated, { name: type.name, color: type.rgb, type: type.code, absenceId: absence.id }); }); } } repaint() { let calendars = this.element.querySelectorAll('vn-calendar'); for (let calendar of calendars) calendar.$ctrl.repaint(); } formatDay(day, element) { let event = this.events[day.getTime()]; if (!event) return; let dayNumber = element.firstElementChild; dayNumber.title = event.name; dayNumber.style.backgroundColor = event.color; dayNumber.style.color = 'rgba(0, 0, 0, 0.7)'; } pick(absenceType) { if (!this.isSubordinate) return; if (absenceType == this.absenceType) absenceType = null; this.absenceType = absenceType; } onSelection($event, $days) { if (!this.absenceType) return this.vnApp.showMessage(this.$t('Choose an absence type from the right menu')); if (this.year != new Date().getFullYear()) return this.vnApp.showMessage(this.$t('You can just add absences within the current year')); const day = $days[0]; const stamp = day.getTime(); const event = this.events[stamp]; const calendar = $event.target.closest('vn-calendar').$ctrl; if (event) { if (event.type == this.absenceType.code) this.delete(calendar, day, event); else this.edit(calendar, event); } else this.create(calendar, day); } create(calendar, dated) { const absenceType = this.absenceType; const params = { dated: dated, absenceTypeId: absenceType.id }; const path = `Workers/${this.$params.id}/createAbsence`; this.$http.post(path, params).then(res => { const newEvent = res.data; this.events[dated.getTime()] = { name: absenceType.name, color: absenceType.rgb, type: absenceType.code, absenceId: newEvent.id }; this.repaintCanceller(() => this.refresh().then(calendar.repaint()) ); }); } edit(calendar, event) { const absenceType = this.absenceType; const params = { absenceId: event.absenceId, absenceTypeId: absenceType.id }; const path = `Workers/${this.$params.id}/updateAbsence`; this.$http.patch(path, params).then(() => { event.color = absenceType.rgb; event.name = absenceType.name; event.type = absenceType.code; this.repaintCanceller(() => this.refresh().then(calendar.repaint()) ); }); } delete(calendar, day, event) { const params = {absenceId: event.absenceId}; const path = `Workers/${this.$params.id}/deleteAbsence`; this.$http.delete(path, {params}).then(() => { delete this.events[day.getTime()]; this.repaintCanceller(() => this.refresh().then(calendar.repaint()) ); }); } repaintCanceller(cb) { if (this.canceller) { clearTimeout(this.canceller); this.canceller = null; } this.canceller = setTimeout( () => cb(), 500); } refresh() { const params = { workerFk: this.worker.id, started: this.started, ended: this.ended }; return this.$http.get(`Calendars/absences`, {params}) .then(res => this.onData(res.data)); } } ngModule.vnComponent('vnWorkerCalendar', { template: require('./index.html'), controller: Controller, bindings: { worker: '<' } });