mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-09-13 18:24:58 +00:00
A new attribute `label` has been added to the `pick-entity` component in the Chill Calendar Bundle's Vue.js App. This label, set as 'Utilisateur principal', enhances user interaction and clarity in the main user selection process.
303 lines
11 KiB
Vue
303 lines
11 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"
|
|
:label="'Utilisateur principal'"
|
|
@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>
|