mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
283 lines
9.1 KiB
Vue
283 lines
9.1 KiB
Vue
<template>
|
|
<div>
|
|
<h2 class="chill-red">{{ $t('edit_your_calendar_range') }}</h2>
|
|
|
|
<div class="form-check">
|
|
<input type="checkbox" id="myCalendar" class="form-check-input" v-model="showMyCalendarWidget" />
|
|
<label class="form-check-label" for="myCalendar">{{ $t('show_my_calendar') }}</label>
|
|
</div>
|
|
<div class="form-check">
|
|
<input type="checkbox" id="weekends" class="form-check-input" @click="toggleWeekends" />
|
|
<label class="form-check-label" for="weekends">{{ $t('show_weekends') }}</label>
|
|
</div>
|
|
|
|
<FullCalendar ref="fullCalendar" :options="{...calendarOptions, eventSources: [this.rangeSource, this.appointmentSource]}">
|
|
<template v-slot:eventContent='arg' >
|
|
<span class='calendarRangeItems'>
|
|
<b v-if="arg.event.extendedProps.myCalendar" style="text-decoration: underline" >{{ arg.timeText }}</b>
|
|
<b v-else-if="!arg.event.extendedProps.myCalendar && arg.event.extendedProps.toDelete" style="text-decoration: line-through red" >{{ arg.timeText }}</b>
|
|
<b v-else >{{ arg.timeText }}</b>
|
|
<i> {{ arg.event.title }}</i>
|
|
<a v-if=!arg.event.extendedProps.myCalendar class="fa fa-fw fa-times"
|
|
@click.prevent="onClickDelete(arg.event)">
|
|
</a>
|
|
</span>
|
|
</template>
|
|
</FullCalendar>
|
|
|
|
<div id="copy-widget">
|
|
<h4 class="chill-red" style="margin-top: 2rem;">{{ $t('copy_range_from_to') }}</h4>
|
|
<div style="display: flex; justify-content: space-between; margin-top: 1rem;">
|
|
<label class="col-form-label">{{ $t('dateFrom') }}</label>
|
|
<div class="col-sm-3">
|
|
<input class="form-control" type="date" v-model="copyFrom" />
|
|
</div>
|
|
<label class="col-form-label">{{ $t('dateTo') }}</label>
|
|
<div class="col-sm-3">
|
|
<input class="form-control" type="date" v-model="copyTo" />
|
|
</div>
|
|
<button class="btn btn-action" @click="copyDay">
|
|
{{ $t('copy_range')}}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<teleport to="body">
|
|
<modal v-if="modal.showModal"
|
|
:modalDialogClass="modal.modalDialogClass"
|
|
@close="modal.showModal = false">
|
|
|
|
<template v-slot:header>
|
|
<h2 class="modal-title">{{ this.renderEventDate() }}</h2>
|
|
</template>
|
|
|
|
<template v-slot:body>
|
|
<p>{{ $t('by')}} {{this.myCalendarClickedEvent.user.username }}</p>
|
|
<p>{{ $t('main_user_concerned') }} : {{ this.myCalendarClickedEvent.mainUser.username }}</p>
|
|
<p v-if="myCalendarClickedEvent.comment.length > 0" >{{ this.myCalendarClickedEvent.comment }}</p>
|
|
</template>
|
|
|
|
<template v-slot:footer>
|
|
<ul class="record_actions">
|
|
<li>
|
|
<a
|
|
class="btn btn-show"
|
|
:href=myCalendarEventShowLink() >
|
|
</a>
|
|
</li>
|
|
<li>
|
|
<a
|
|
class="btn btn-update"
|
|
:href=myCalendarEventUpdateLink() >
|
|
</a>
|
|
</li>
|
|
<li>
|
|
<a
|
|
class="btn btn-delete"
|
|
:href=myCalendarEventDeleteLink() >
|
|
</a>
|
|
</li>
|
|
</ul>
|
|
</template>
|
|
|
|
</modal>
|
|
</teleport>
|
|
</template>
|
|
|
|
<script>
|
|
import '@fullcalendar/core/vdom'; // solves problem with Vite
|
|
import frLocale from '@fullcalendar/core/locales/fr';
|
|
import FullCalendar from '@fullcalendar/vue3';
|
|
import dayGridPlugin from '@fullcalendar/daygrid';
|
|
import interactionPlugin from '@fullcalendar/interaction';
|
|
import timeGridPlugin from '@fullcalendar/timegrid';
|
|
import Modal from 'ChillMainAssets/vuejs/_components/Modal';
|
|
import { fetchCalendarRangesByUser, postCalendarRange } from '../_api/api';
|
|
import { mapGetters, mapActions, mapState } from 'vuex';
|
|
import { vShow } from 'vue';
|
|
|
|
export default {
|
|
name: "App",
|
|
components: {
|
|
FullCalendar,
|
|
Modal
|
|
},
|
|
data() {
|
|
return {
|
|
errorMsg: [],
|
|
copyFrom: null,
|
|
copyTo: null,
|
|
modal: {
|
|
showModal: false,
|
|
modalDialogClass: "modal-dialog-scrollable modal-m"
|
|
},
|
|
flag: {
|
|
loading: false
|
|
},
|
|
userId: window.userId,
|
|
showMyCalendar: true,
|
|
myCalendarClickedEvent: null,
|
|
lastNewDate: null,
|
|
disableCopyDayButton: true,
|
|
calendarOptions: {
|
|
locale: frLocale,
|
|
plugins: [ dayGridPlugin, interactionPlugin, timeGridPlugin ],
|
|
initialView: 'timeGridWeek',
|
|
initialDate: window.startDate !== undefined ? window.startDate : new Date(),
|
|
selectable: true,
|
|
select: this.onDateSelect,
|
|
eventChange: this.onEventChange,
|
|
eventDrop: this.onEventDropOrResize,
|
|
eventResize: this.onEventDropOrResize,
|
|
eventClick: this.onEventClick,
|
|
selectMirror: false,
|
|
editable: true,
|
|
weekends: false,
|
|
slotDuration: '00:15:00',
|
|
slotMinTime: "08:00:00",
|
|
slotMaxTime: "19:00:00",
|
|
contentHeight: 500,
|
|
headerToolbar: {
|
|
left: 'prev,next today',
|
|
center: 'title',
|
|
right: 'dayGridMonth timeGridWeek timeGridDay'
|
|
},
|
|
},
|
|
}
|
|
},
|
|
computed: {
|
|
...mapState({
|
|
rangesToCopy: state => state.rangesToCopy
|
|
}),
|
|
...mapGetters(['rangeSource', 'appointmentSource']),
|
|
showMyCalendarWidget: {
|
|
set(value) {
|
|
this.toggleMyCalendar(value);
|
|
},
|
|
get() {
|
|
return this.showMyCalendar;
|
|
}
|
|
}
|
|
},
|
|
methods: {
|
|
...mapActions([
|
|
'fetchRanges',
|
|
'fetchAppointments',
|
|
'postRange',
|
|
'patchRange',
|
|
'deleteRange'
|
|
]),
|
|
openModal() {
|
|
this.modal.showModal = true;
|
|
},
|
|
myCalendarEventShowLink() {
|
|
return `/fr/calendar/calendar/${this.myCalendarClickedEvent.id}/show?user_id=${ this.userId }`
|
|
},
|
|
myCalendarEventUpdateLink() {
|
|
return `/fr/calendar/calendar/${this.myCalendarClickedEvent.id}/edit?user_id=${ this.userId }`
|
|
},
|
|
myCalendarEventDeleteLink() {
|
|
return `/fr/calendar/calendar/${this.myCalendarClickedEvent.id}/delete?user_id=${ this.userId }`
|
|
},
|
|
toggleMyCalendar(value) {
|
|
this.showMyCalendar = value;
|
|
},
|
|
toggleWeekends: function() {
|
|
this.calendarOptions.weekends = !this.calendarOptions.weekends;
|
|
},
|
|
replaceDate(from, to) {
|
|
|
|
const fromDate = new Date(from)
|
|
const toDate = new Date(to);
|
|
|
|
let newDate = fromDate.setDate(toDate.getDate());
|
|
newDate = new Date(newDate).setMonth(toDate.getMonth());
|
|
newDate = new Date(newDate).setFullYear(toDate.getFullYear());
|
|
|
|
newDate = `${new Date(newDate).toISOString().split('.')[0]}+0000`;
|
|
|
|
return newDate;
|
|
},
|
|
onDateSelect(payload) {
|
|
const newRange = {
|
|
user: {
|
|
type: 'user',
|
|
id: window.userId,
|
|
},
|
|
startDate: {
|
|
datetime: `${payload.start.toISOString().split('.')[0]}+0000`, //should be like "2021-08-20T15:00:00+0200",
|
|
},
|
|
endDate: {
|
|
datetime: `${payload.end.toISOString().split('.')[0]}+0000`, // TODO check if OK with time zone
|
|
},
|
|
}
|
|
this.postRange(newRange);
|
|
},
|
|
onEventClick(payload) {
|
|
if (payload.event.extendedProps.myCalendar) {
|
|
this.myCalendarClickedEvent = {
|
|
id: payload.event.extendedProps.calendarId,
|
|
start: payload.event.start,
|
|
end: payload.event.end,
|
|
user: payload.event.extendedProps.user,
|
|
mainUser: payload.event.extendedProps.mainUser,
|
|
persons: payload.event.extendedProps.persons,
|
|
professionals: payload.event.extendedProps.professionals,
|
|
comment: payload.event.extendedProps.comment
|
|
};
|
|
this.openModal();
|
|
}
|
|
},
|
|
onClickDelete(payload) {
|
|
if (payload.extendedProps.hasOwnProperty("calendarRangeId")) {
|
|
this.deleteRange(payload.extendedProps.calendarRangeId)
|
|
}
|
|
},
|
|
onEventDropOrResize(payload) {
|
|
const changedEvent = payload.event;
|
|
this.patchRange(changedEvent);
|
|
},
|
|
copyDay() {
|
|
const payload = {
|
|
userId: this.userId,
|
|
dateToCopy: new Date(this.copyFrom).toISOString()
|
|
}
|
|
this.fetchRanges(payload).then(
|
|
r => {
|
|
r.forEach((range) => {
|
|
this.postRange({
|
|
user: {
|
|
type: 'user',
|
|
id: range.user.id,
|
|
},
|
|
startDate: {
|
|
datetime: this.replaceDate(range.startDate.datetime, this.copyTo), //should be like "2021-08-20T15:00:00+0200",
|
|
},
|
|
endDate: {
|
|
datetime: this.replaceDate(range.endDate.datetime, this.copyTo),
|
|
},
|
|
})
|
|
})
|
|
}
|
|
)
|
|
},
|
|
renderEventDate() {
|
|
let start = this.myCalendarClickedEvent.start;
|
|
let end = this.myCalendarClickedEvent.end;
|
|
return start.getDate() === end.getDate() ?
|
|
`${start.toLocaleDateString()}, ${start.toLocaleTimeString()} - ${end.toLocaleTimeString()}` :
|
|
`${start.toLocaleString()} - ${end.toLocaleString()}`;
|
|
}
|
|
},
|
|
mounted() {
|
|
this.fetchRanges()
|
|
|
|
if (this.showMyCalendar) {
|
|
this.fetchAppointments(this.userId)
|
|
}
|
|
}
|
|
}
|
|
</script>
|