mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
302 lines
10 KiB
Vue
302 lines
10 KiB
Vue
<template>
|
|
|
|
<teleport to="#mainUser">
|
|
|
|
<h2 class="chill-red">Utilisateur principal</h2>
|
|
<div>
|
|
<div>
|
|
<div v-if="null !== this.$store.getters.getMainUser">
|
|
<calendar-active :user="this.$store.getters.getMainUser" ></calendar-active>
|
|
</div>
|
|
<pick-entity
|
|
:multiple="false"
|
|
:types="['user']"
|
|
:uniqid="'main_user_calendar'"
|
|
:picked="null !== this.$store.getters.getMainUser ? [this.$store.getters.getMainUser] : []"
|
|
:removableIfSet="false"
|
|
:displayPicked="false"
|
|
:suggested="this.suggestedUsers"
|
|
@addNewEntity="setMainUser"
|
|
></pick-entity>
|
|
</div>
|
|
</div>
|
|
</teleport>
|
|
|
|
<concerned-groups></concerned-groups>
|
|
|
|
<teleport to="#schedule">
|
|
<div class="row mb-3" v-if="activity.startDate !== null">
|
|
<label class="col-form-label col-sm-4">Date</label>
|
|
<div class="col-sm-8">
|
|
{{ $d(activity.startDate, 'long') }} - {{ $d(activity.endDate, 'hoursOnly') }}
|
|
<span v-if="activity.calendarRange === null">(Pas de plage de disponibilité sélectionnée)</span>
|
|
<span v-else>(Une plage de disponibilité sélectionnée)</span>
|
|
</div>
|
|
</div>
|
|
</teleport>
|
|
|
|
<location></location>
|
|
|
|
|
|
|
|
<teleport to="#fullCalendar">
|
|
<div class="calendar-actives">
|
|
<template class="" v-for="u in getActiveUsers" :key="u.id">
|
|
<calendar-active :user="u" :invite="this.$store.getters.getInviteForUser(u)"></calendar-active>
|
|
</template>
|
|
</div>
|
|
<div class="display-options row justify-content-between" style="margin-top: 1rem;">
|
|
<div class="col-sm-9 col-xs-12">
|
|
<div class="input-group mb-3">
|
|
<label class="input-group-text" for="slotDuration">Durée des créneaux</label>
|
|
<select v-model="slotDuration" id="slotDuration" class="form-select">
|
|
<option value="00:05:00">5 minutes</option>
|
|
<option value="00:10:00">10 minutes</option>
|
|
<option value="00:15:00">15 minutes</option>
|
|
<option value="00:30:00">30 minutes</option>
|
|
</select>
|
|
<label class="input-group-text" for="slotMinTime">De</label>
|
|
<select v-model="slotMinTime" id="slotMinTime" class="form-select">
|
|
<option value="00:00:00">0h</option>
|
|
<option value="01:00:00">1h</option>
|
|
<option value="02:00:00">2h</option>
|
|
<option value="03:00:00">3h</option>
|
|
<option value="04:00:00">4h</option>
|
|
<option value="05:00:00">5h</option>
|
|
<option value="06:00:00">6h</option>
|
|
<option value="07:00:00">7h</option>
|
|
<option value="08:00:00">8h</option>
|
|
<option value="09:00:00">9h</option>
|
|
<option value="10:00:00">10h</option>
|
|
<option value="11:00:00">11h</option>
|
|
<option value="12:00:00">12h</option>
|
|
</select>
|
|
<label class="input-group-text" for="slotMaxTime">À</label>
|
|
<select v-model="slotMaxTime" id="slotMaxTime" class="form-select">
|
|
<option value="12:00:00">12h</option>
|
|
<option value="13:00:00">13h</option>
|
|
<option value="14:00:00">14h</option>
|
|
<option value="15:00:00">15h</option>
|
|
<option value="16:00:00">16h</option>
|
|
<option value="17:00:00">17h</option>
|
|
<option value="18:00:00">18h</option>
|
|
<option value="19:00:00">19h</option>
|
|
<option value="20:00:00">20h</option>
|
|
<option value="21:00:00">21h</option>
|
|
<option value="22:00:00">22h</option>
|
|
<option value="23:00:00">23h</option>
|
|
<option value="23:59:59">24h</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<div class="col-sm-3 col-xs-12">
|
|
<div class="float-end">
|
|
<div class="form-check input-group">
|
|
<span class="input-group-text">
|
|
<input id="showHideWE" class="mt-0" type="checkbox" v-model="hideWeekends">
|
|
</span>
|
|
<label for="showHideWE" class="form-check-label input-group-text">Week-ends</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<FullCalendar ref="fullCalendar" :options="calendarOptions">
|
|
<template v-slot:eventContent='arg'>
|
|
<span>
|
|
<b v-if="arg.event.extendedProps.is === 'remote'">{{ arg.event.title}}</b>
|
|
<b v-else-if="arg.event.extendedProps.is === 'range'">{{ arg.timeText }} {{ arg.event.extendedProps.locationName }} <small>{{ arg.event.extendedProps.userLabel }}</small></b>
|
|
<b v-else-if="arg.event.extendedProps.is === 'current'">{{ arg.timeText }} {{ $t('current_selected')}} </b>
|
|
<b v-else-if="arg.event.extendedProps.is === 'local'">{{ arg.event.title}}</b>
|
|
<b v-else>{{ arg.timeText }} {{ $t('current_selected')}} </b>
|
|
</span>
|
|
</template>
|
|
</FullCalendar>
|
|
</teleport>
|
|
</template>
|
|
|
|
<script>
|
|
import ConcernedGroups from 'ChillActivityAssets/vuejs/Activity/components/ConcernedGroups.vue';
|
|
import Location from 'ChillActivityAssets/vuejs/Activity/components/Location.vue';
|
|
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 listPlugin from '@fullcalendar/list';
|
|
import CalendarActive from './Components/CalendarActive';
|
|
import PickEntity from 'ChillMainAssets/vuejs/PickEntity/PickEntity.vue';
|
|
import {mapGetters, mapState} from "vuex";
|
|
|
|
export default {
|
|
name: "App",
|
|
components: {
|
|
ConcernedGroups,
|
|
Location,
|
|
FullCalendar,
|
|
CalendarActive,
|
|
PickEntity,
|
|
},
|
|
data() {
|
|
return {
|
|
errorMsg: [],
|
|
showMyCalendar: false,
|
|
slotDuration: '00:05:00',
|
|
slotMinTime: '09:00:00',
|
|
slotMaxTime: '18:00:00',
|
|
hideWeekEnds: true,
|
|
previousUser: [],
|
|
}
|
|
},
|
|
computed: {
|
|
...mapGetters(['getMainUser']),
|
|
...mapState(['activity']),
|
|
events() {
|
|
return this.$store.getters.getEventSources;
|
|
},
|
|
calendarOptions() {
|
|
return {
|
|
locale: frLocale,
|
|
plugins: [dayGridPlugin, interactionPlugin, timeGridPlugin, dayGridPlugin, listPlugin],
|
|
initialView: 'timeGridWeek',
|
|
initialDate: this.$store.getters.getInitialDate,
|
|
eventSources: this.events,
|
|
selectable: true,
|
|
slotMinTime: this.slotMinTime,
|
|
slotMaxTime: this.slotMaxTime,
|
|
scrollTimeReset: false,
|
|
datesSet: this.onDatesSet,
|
|
select: this.onDateSelect,
|
|
eventChange: this.onEventChange,
|
|
eventClick: this.onEventClick,
|
|
selectMirror: true,
|
|
editable: true,
|
|
weekends: !this.hideWeekEnds,
|
|
headerToolbar: {
|
|
left: 'prev,next today',
|
|
center: 'title',
|
|
right: 'timeGridWeek,timeGridDay,listWeek',
|
|
},
|
|
views: {
|
|
timeGrid: {
|
|
slotEventOverlap: false,
|
|
slotDuration: this.slotDuration,
|
|
},
|
|
},
|
|
};
|
|
},
|
|
getActiveUsers() {
|
|
const users = [];
|
|
for (const id of this.$store.state.currentView.users.keys()) {
|
|
users.push(this.$store.getters.getUserDataById(id).user);
|
|
}
|
|
return users;
|
|
},
|
|
suggestedUsers() {
|
|
const suggested = [];
|
|
|
|
this.$data.previousUser.forEach(u => {
|
|
if (u.id !== this.$store.getters.getMainUser.id) {
|
|
suggested.push(u)
|
|
}
|
|
});
|
|
|
|
return suggested;
|
|
},
|
|
},
|
|
methods: {
|
|
setMainUser({entity}) {
|
|
const user = entity;
|
|
console.log('setMainUser APP', entity);
|
|
|
|
if (user.id !== this.$store.getters.getMainUser && (
|
|
this.$store.state.activity.calendarRange !== null
|
|
|| this.$store.state.activity.startDate !== null
|
|
|| this.$store.state.activity.endDate !== null
|
|
)
|
|
) {
|
|
if (!window.confirm(this.$t('change_main_user_will_reset_event_data'))) {
|
|
return;
|
|
}
|
|
}
|
|
|
|
// add the previous user, if any, in the previous user list (in use for suggestion)
|
|
if (null !== this.$store.getters.getMainUser) {
|
|
const suggestedUids = new Set(this.$data.previousUser.map(u => u.id));
|
|
if (!suggestedUids.has(this.$store.getters.getMainUser.id)){
|
|
this.$data.previousUser.push(this.$store.getters.getMainUser);
|
|
}
|
|
}
|
|
|
|
this.$store.dispatch('setMainUser', user);
|
|
this.$store.commit('showUserOnCalendar', {user, ranges: true, remotes: true});
|
|
},
|
|
removeMainUser(user) {
|
|
console.log('removeMainUser APP', user);
|
|
|
|
window.alert(this.$t('main_user_is_mandatory'));
|
|
return;
|
|
},
|
|
onDatesSet(event) {
|
|
console.log('onDatesSet', event);
|
|
this.$store.dispatch('setCurrentDatesView', {start: event.start, end: event.end});
|
|
},
|
|
onDateSelect(payload) {
|
|
console.log('onDateSelect', payload);
|
|
|
|
// show an alert if changing mainUser
|
|
if ((this.$store.getters.getMainUser !== null
|
|
&& this.$store.state.me.id !== this.$store.getters.getMainUser.id)
|
|
|| this.$store.getters.getMainUser === null) {
|
|
if (!window.confirm(this.$t('will_change_main_user_for_me'))) {
|
|
return;
|
|
} else {
|
|
this.$store.commit('showUserOnCalendar', {user: this.$store.state.me, remotes: true, ranges: true})
|
|
}
|
|
}
|
|
|
|
this.$store.dispatch('setEventTimes', {start: payload.start, end: payload.end});
|
|
},
|
|
onEventChange(payload) {
|
|
console.log('onEventChange', payload);
|
|
if (this.$store.state.activity.calendarRange !== null) {
|
|
throw new Error("not allowed to edit a calendar associated with a calendar range");
|
|
}
|
|
this.$store.dispatch('setEventTimes', {start: payload.event.start, end: payload.event.end});
|
|
},
|
|
onEventClick(payload) {
|
|
if (payload.event.extendedProps.is !== 'range') {
|
|
// do nothing when clicking on remote
|
|
return;
|
|
}
|
|
|
|
// show an alert if changing mainUser
|
|
if (this.$store.getters.getMainUser !== null
|
|
&& payload.event.extendedProps.userId !== this.$store.getters.getMainUser.id) {
|
|
if (!window.confirm(this.$t('this_calendar_range_will_change_main_user'))) {
|
|
return;
|
|
}
|
|
}
|
|
|
|
this.$store.dispatch('associateCalendarToRange', {range: payload.event});
|
|
},
|
|
},
|
|
}
|
|
</script>
|
|
|
|
<style>
|
|
.calendar-actives {
|
|
display: flex;
|
|
flex-direction: row;
|
|
flex-wrap: wrap;
|
|
}
|
|
|
|
.display-options {
|
|
margin-top: 1rem;
|
|
}
|
|
|
|
/* for events which are range */
|
|
.fc-event.isrange {
|
|
border-width: 3px;
|
|
}
|
|
</style>
|