mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-08-23 08:03:49 +00:00
367 lines
11 KiB
Vue
367 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" />
|
|
</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>
|