calendar app: set mainUser and options for form

This commit is contained in:
Julien Fastré 2022-05-24 22:45:43 +02:00
parent 352b5b41b0
commit eb8b8c6939
10 changed files with 149 additions and 73 deletions

View File

@ -139,6 +139,10 @@ class CalendarController extends AbstractController
*/ */
public function editAction(Calendar $entity, Request $request): Response public function editAction(Calendar $entity, Request $request): Response
{ {
if (!$this->remoteCalendarConnector->isReady()) {
return $this->remoteCalendarConnector->getMakeReadyResponse($request->getUri());
}
$view = null; $view = null;
$em = $this->getDoctrine()->getManager(); $em = $this->getDoctrine()->getManager();

View File

@ -81,10 +81,8 @@ class CalendarType extends AbstractType
'expanded' => true, 'expanded' => true,
]); ]);
if ($options['data'] instanceof Calendar && $options['data']->getId() === null) { $builder->add('mainUser', HiddenType::class);
$builder->add('mainUser', HiddenType::class); $builder->get('mainUser')->addModelTransformer($this->idToUserDataTransformer);
$builder->get('mainUser')->addModelTransformer($this->idToUserDataTransformer);
}
$builder->add('startDate', HiddenType::class); $builder->add('startDate', HiddenType::class);
$builder->get('startDate') $builder->get('startDate')

View File

@ -99,16 +99,18 @@ class MSGraphRemoteCalendarConnector implements RemoteCalendarConnectorInterface
$ids = array_map(function ($item) { return $item['id']; }, $bareEvents['value']); $ids = array_map(function ($item) { return $item['id']; }, $bareEvents['value']);
$existingIdsInRange = $this->calendarRangeRepository->findRemoteIdsPresent($ids); $existingIdsInRange = $this->calendarRangeRepository->findRemoteIdsPresent($ids);
return array_map( return array_values(
function ($item) { array_map(
return $this->remoteEventConverter->convertToRemote($item); function ($item) {
}, return $this->remoteEventConverter->convertToRemote($item);
// filter all event to keep only the one not in range },
array_filter( // filter all event to keep only the one not in range
$bareEvents['value'], array_filter(
function ($item) use ($existingIdsInRange) { $bareEvents['value'],
return (!$existingIdsInRange[$item['id']]) ?? true; function ($item) use ($existingIdsInRange) {
} return (!$existingIdsInRange[$item['id']]) ?? true;
}
)
) )
); );
} catch (ClientExceptionInterface $e) { } catch (ClientExceptionInterface $e) {

View File

@ -1,8 +1,34 @@
<template> <template>
<div class="row">
<div class="col-md-4">
<label>Utilisateur principal</label>
</div>
<div class="col-md-8 align-content-end">
<pick-entity
:multiple="false"
:types="['user']"
:uniqid="'main_user_calendar'"
:picked="[this.$store.getters.getMainUser]"
:removableIfSet="false"
@addNewEntity="setMainUser"
></pick-entity>
</div>
</div>
<div class="row">
<select v-model="this.slotDuration">
<option value="00:05:00">5</option>
<option value="00:10:00">10</option>
<option value="00:15:00">15</option>
<option value="00:30:00">30</option>
</select>
</div>
<div>
<input type="checkbox" v-model="this.hideWeekEnds" /><label>Masquer les week-ends</label>
</div>
<concerned-groups></concerned-groups> <concerned-groups></concerned-groups>
<div> <div>
<template v-for="uid in this.$store.state.currentView.users.keys()" :key="uid"> <template v-for="u in getActiveUsers" :key="u.id">
<calendar-active :user="this.$store.getters.getUserDataById(uid).user" ></calendar-active> <calendar-active :user="u" ></calendar-active>
</template> </template>
</div> </div>
<teleport to="#fullCalendar"> <teleport to="#fullCalendar">
@ -28,7 +54,8 @@ import dayGridPlugin from '@fullcalendar/daygrid';
import interactionPlugin from '@fullcalendar/interaction'; import interactionPlugin from '@fullcalendar/interaction';
import timeGridPlugin from '@fullcalendar/timegrid'; import timeGridPlugin from '@fullcalendar/timegrid';
import CalendarActive from './Components/CalendarActive'; import CalendarActive from './Components/CalendarActive';
// import listPlugin from '@fullcalendar/list'; import PickEntity from 'ChillMainAssets/vuejs/PickEntity/PickEntity.vue';
import {mapGetters} from "vuex";
export default { export default {
name: "App", name: "App",
@ -37,44 +64,25 @@ export default {
Location, Location,
FullCalendar, FullCalendar,
CalendarActive, CalendarActive,
PickEntity,
}, },
data() { data() {
return { return {
errorMsg: [], errorMsg: [],
/*
users: {
loaded: [],
selected: [],
logged: null
},
calendarEvents: {
loaded: [],
selected: [],
user: [],
current: {
events: [{
title: 'plage prévue',
start: window.startDate,
end: window.endDate
}],
id: window.mainUser,
color: '#bbbbbb'
}
},*/
selectedEvent: null,
previousSelectedEvent: null,
previousSelectedEventColor: null,
showMyCalendar: false, showMyCalendar: false,
slotDuration: '00:10:00',
hideWeekEnds: true,
} }
}, },
computed: { computed: {
...mapGetters(['getMainUser']),
events() { events() {
return this.$store.getters.getEventSources; return this.$store.getters.getEventSources;
}, },
calendarOptions() { calendarOptions() {
return { return {
locale: frLocale, locale: frLocale,
plugins: [dayGridPlugin, interactionPlugin, timeGridPlugin], plugins: [dayGridPlugin, interactionPlugin, timeGridPlugin, dayGridPlugin],
initialView: 'timeGridWeek', initialView: 'timeGridWeek',
initialDate: this.$store.getters.initialDate, initialDate: this.$store.getters.initialDate,
eventSources: this.events, eventSources: this.events,
@ -85,29 +93,57 @@ export default {
eventClick: this.onEventClick, eventClick: this.onEventClick,
selectMirror: true, selectMirror: true,
editable: true, editable: true,
weekends: false, weekends: !this.hideWeekEnds,
headerToolbar: { headerToolbar: {
left: 'prev,next today', left: 'prev,next today',
center: 'title', center: 'title',
right: 'dayGridMonth,timeGridWeek,timeGridDay,listMonth,listWeek,listDay' right: 'dayGridMonth,timeGridWeek,dayGridThreeDays,timeGridDay',
} },
views: {
timeGrid: {
slotEventOverlap: false,
slotDuration: this.slotDuration,
scrollTime: '10:00:00',
},
dayGridThreeDays: {
type: 'dayGridWeek',
duration: { days: 3},
buttonText: this.$t('list_three_days'),
},
},
}; };
}, },
getActiveUsers() { getActiveUsers() {
return this.$store.state.currentView.users.keys() const users = [];
.filter(id => this.$store.getters.hasUserDataById(id)) for (const id of this.$store.state.currentView.users.keys()) {
.map(id => this.$store.getters.getUserDataById().user); users.push(this.$store.getters.getUserDataById(id).user);
}
return users;
} }
}, },
methods: { methods: {
init() { setMainUser(user) {
//this.updateEventsSource(); console.log('setMainUser APP', user);
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;
}
}
this.$store.dispatch('setMainUser', user);
this.$store.commit('showUserOnCalendar', {user, ranges: true, remotes: true});
}, },
toggleMyCalendar(value) { removeMainUser(user) {
this.showMyCalendar = value; console.log('removeMainUser APP', user);
},
toggleWeekends: function () { window.alert(this.$t('main_user_is_mandatory'));
this.calendarOptions.weekends = !this.calendarOptions.weekends; return;
}, },
onDatesSet(event) { onDatesSet(event) {
console.log('onDatesSet', event); console.log('onDatesSet', event);
@ -143,7 +179,7 @@ export default {
// show an alert if changing mainUser // show an alert if changing mainUser
if (this.$store.getters.getMainUser !== null if (this.$store.getters.getMainUser !== null
&& payload.event.extendedProps.userId !== this.$store.getMainUser.id) { && payload.event.extendedProps.userId !== this.$store.getters.getMainUser.id) {
if (!window.confirm(this.$t('this_calendar_range_will_change_main_user'))) { if (!window.confirm(this.$t('this_calendar_range_will_change_main_user'))) {
return; return;
} }

View File

@ -13,8 +13,11 @@ const appMessages = {
bloc_thirdparty: "Tiers professionnels", bloc_thirdparty: "Tiers professionnels",
bloc_users: "T(M)S", bloc_users: "T(M)S",
}, },
this_calendar_range_will_change_main_user: "Cette plage de disponibilité n'est pas celle de l'utilisateur principal. Si vous continuez, l'utilisateur principal sera adapté. Êtes-vous sur·e ?", this_calendar_range_will_change_main_user: "Cette plage de disponibilité n'est pas celle de l'utilisateur principal. Si vous continuez, l'utilisateur principal sera adapté. Êtes-vous sûr·e ?",
will_change_main_user_for_me: "Vous ne pouvez pas écrire dans le calendrier d'un autre utilisateur. Voulez-vous être l'utilisateur principal de ce rendez-vous ?", will_change_main_user_for_me: "Vous ne pouvez pas écrire dans le calendrier d'un autre utilisateur. Voulez-vous être l'utilisateur principal de ce rendez-vous ?",
main_user_is_mandatory: "L'utilisateur principal est requis. Vous pouvez le modifier, mais pas le supprimer",
change_main_user_will_reset_event_data: "Modifier l'utilisateur principal nécessite de choisir une autre plage de disponibilité ou un autre horaire. Ces informations seront perdues. Êtes-vous sûr·e de vouloir continuer ?",
list_three_days: 'Liste 3 jours',
} }
} }

View File

@ -135,9 +135,9 @@ export default {
setEventTimes({commit, state, getters}, {start, end}) { setEventTimes({commit, state, getters}, {start, end}) {
console.log('### action createEvent', {start, end}); console.log('### action createEvent', {start, end});
let startDateInput = document.getElementById("chill_activitybundle_activity_startDate"); let startDateInput = document.getElementById("chill_activitybundle_activity_startDate");
startDateInput.value = datetimeToISO(start); startDateInput.value = null !== start ? datetimeToISO(start) : '';
let endDateInput = document.getElementById("chill_activitybundle_activity_endDate"); let endDateInput = document.getElementById("chill_activitybundle_activity_endDate");
endDateInput.value = datetimeToISO(end); endDateInput.value = null !== end ? datetimeToISO(end) : '';
let calendarRangeInput = document.getElementById("chill_activitybundle_activity_calendarRange"); let calendarRangeInput = document.getElementById("chill_activitybundle_activity_calendarRange");
calendarRangeInput.value = ""; calendarRangeInput.value = "";
@ -152,31 +152,40 @@ export default {
associateCalendarToRange({state, commit, dispatch}, {range}) { associateCalendarToRange({state, commit, dispatch}, {range}) {
console.log('### action associateCAlendarToRange', range); console.log('### action associateCAlendarToRange', range);
let startDateInput = document.getElementById("chill_activitybundle_activity_startDate"); let startDateInput = document.getElementById("chill_activitybundle_activity_startDate");
startDateInput.value = datetimeToISO(range.start); startDateInput.value = null !== range ? datetimeToISO(range.start) : "";
let endDateInput = document.getElementById("chill_activitybundle_activity_endDate"); let endDateInput = document.getElementById("chill_activitybundle_activity_endDate");
endDateInput.value = datetimeToISO(range.end); endDateInput.value = null !== range ? datetimeToISO(range.end) : "";
let calendarRangeInput = document.getElementById("chill_activitybundle_activity_calendarRange"); let calendarRangeInput = document.getElementById("chill_activitybundle_activity_calendarRange");
calendarRangeInput.value = Number(range.extendedProps.calendarRangeId); calendarRangeInput.value = null !== range ? Number(range.extendedProps.calendarRangeId) : "";
const userId = range.extendedProps.userId; if (null !== range) {
if (state.activity.mainUser !== null && state.activity.mainUser.id !== userId) { const userId = range.extendedProps.userId;
dispatch('setMainUser', state.usersData.get(userId).user); if (state.activity.mainUser !== null && state.activity.mainUser.id !== userId) {
dispatch('setMainUser', state.usersData.get(userId).user);
// TODO: remove persons involved with this user // TODO: remove persons involved with this user
}
} }
commit('associateCalendarToRange', {range}); commit('associateCalendarToRange', {range});
return Promise.resolve(); return Promise.resolve();
}, },
setMainUser({commit}, mainUser) { setMainUser({commit, dispatch, state}, mainUser) {
console.log('setMainUser', mainUser); console.log('setMainUser', mainUser);
let mainUserInput = document.getElementById("chill_activitybundle_activity_mainUser"); if (state.activity.mainUser.id !== mainUser.id) {
mainUserInput.value = Number(mainUser.id); let mainUserInput = document.getElementById("chill_activitybundle_activity_mainUser");
mainUserInput.value = Number(mainUser.id);
commit('setMainUser', mainUser); if (state.activity.calendarRange !== null || state.activity.startDate !== null || state.acdtivity.endDate !== null) {
dispatch('associateCalendarToRange', { range: null });
}
commit('setMainUser', mainUser);
}
return Promise.resolve();
}, },
// Location // Location
updateLocation({commit}, value) { updateLocation({commit}, value) {
console.log('### action: updateLocation', value); console.log('### action: updateLocation', value);

View File

@ -48,6 +48,16 @@ export default {
* @param range * @param range
*/ */
associateCalendarToRange(state, {range}) { associateCalendarToRange(state, {range}) {
console.log('associateCalendarToRange', range);
if (null === range) {
state.activity.calendarRange = null;
state.activity.startDate = null;
state.activity.endDate = null;
return;
}
console.log('userId', range.extendedProps.userId); console.log('userId', range.extendedProps.userId);
const r = state.usersData.get(range.extendedProps.userId).calendarRanges const r = state.usersData.get(range.extendedProps.userId).calendarRanges

View File

@ -67,6 +67,7 @@ const calendarRangeToFullCalendarEvent = (entity) => {
} }
const remoteToFullCalendarEvent = (entity) => { const remoteToFullCalendarEvent = (entity) => {
console.log(entity);
return { return {
id: `range_${entity.id}`, id: `range_${entity.id}`,
title: entity.title, title: entity.title,

View File

@ -57,7 +57,7 @@ const _fetchAction = (page, uri, params) => {
}, },
}).then(response => { }).then(response => {
if (response.ok) { return response.json(); } if (response.ok) { return response.json(); }
throw Error({ m: response.statusText }); throw new Error({ m: response.statusText });
}); });
}; };

View File

@ -1,5 +1,5 @@
<template> <template>
<ul class="list-suggest remove-items" v-if="picked.length"> <ul :class="listClasses" v-if="picked.length">
<li v-for="p in picked" @click="removeEntity(p)" :key="p.type+p.id"> <li v-for="p in picked" @click="removeEntity(p)" :key="p.type+p.id">
<span class="chill_denomination">{{ p.text }}</span> <span class="chill_denomination">{{ p.text }}</span>
</li> </li>
@ -40,6 +40,10 @@ export default {
uniqid: { uniqid: {
type: String, type: String,
required: true, required: true,
},
removableIfSet: {
type: Boolean,
default: true,
} }
}, },
emits: ['addNewEntity', 'removeEntity'], emits: ['addNewEntity', 'removeEntity'],
@ -78,7 +82,13 @@ export default {
} else { } else {
return appMessages.fr.pick_entity.modal_title_one + trans.join(', '); return appMessages.fr.pick_entity.modal_title_one + trans.join(', ');
} }
} },
listClasses() {
return {
'list-suggest': true,
'remove-items': this.$props.removableIfSet,
};
},
}, },
methods: { methods: {
addNewEntity({ selected, modal }) { addNewEntity({ selected, modal }) {
@ -90,6 +100,9 @@ export default {
modal.showModal = false; modal.showModal = false;
}, },
removeEntity(entity) { removeEntity(entity) {
if (!this.$props.removableIfSet) {
return;
}
this.$emit('removeEntity', entity); this.$emit('removeEntity', entity);
} }
}, },