mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
407 lines
12 KiB
Vue
407 lines
12 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" />
|
|
</div>
|
|
<pick-entity
|
|
:multiple="false"
|
|
:types="['user']"
|
|
:uniqid="'main_user_calendar'"
|
|
:picked="null !== this.$store.getters.getMainUser ? [this.$store.getters.getMainUser] : []"
|
|
:removable-if-set="false"
|
|
:display-picked="false"
|
|
:suggested="this.suggestedUsers"
|
|
:label="'main_user'"
|
|
@add-new-entity="setMainUser"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</teleport>
|
|
|
|
<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 />
|
|
|
|
|
|
|
|
<teleport to="#fullCalendar">
|
|
<div class="calendar-actives">
|
|
<template
|
|
v-for="u in getActiveUsers"
|
|
:key="u.id"
|
|
>
|
|
<calendar-active
|
|
:user="u"
|
|
:invite="this.$store.getters.getInviteForUser(u)"
|
|
/>
|
|
</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 #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>
|