From a025883a5d5c441ff9a5df3e4f368e474517c935 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Mon, 23 May 2022 16:48:17 +0200 Subject: [PATCH] create event by selecting a calendar range --- .../RemoteCalendarProxyController.php | 18 ++++++----- .../ChillCalendarBundle/Entity/Calendar.php | 1 + .../Entity/CalendarRange.php | 6 ++-- .../ChillCalendarBundle/Form/CalendarType.php | 20 +++++++++---- .../Resources/public/vuejs/Calendar/App.vue | 15 ++++++++++ .../public/vuejs/Calendar/store/actions.js | 14 +++++---- .../public/vuejs/Calendar/store/getters.js | 30 +++++++++++++++++-- .../public/vuejs/Calendar/store/mutations.js | 18 +++++++++++ .../public/vuejs/Calendar/store/utils.js | 3 ++ .../Tests/Form/CalendarTypeTest.php | 4 +-- 10 files changed, 101 insertions(+), 28 deletions(-) diff --git a/src/Bundle/ChillCalendarBundle/Controller/RemoteCalendarProxyController.php b/src/Bundle/ChillCalendarBundle/Controller/RemoteCalendarProxyController.php index e1926cdfe..4792660e0 100644 --- a/src/Bundle/ChillCalendarBundle/Controller/RemoteCalendarProxyController.php +++ b/src/Bundle/ChillCalendarBundle/Controller/RemoteCalendarProxyController.php @@ -22,18 +22,19 @@ use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Serializer\SerializerInterface; +use function count; /** * Contains method to get events (Calendar) from remote calendar. */ class RemoteCalendarProxyController { + private PaginatorFactory $paginatorFactory; + private RemoteCalendarConnectorInterface $remoteCalendarConnector; private SerializerInterface $serializer; - private PaginatorFactory $paginatorFactory; - public function __construct(PaginatorFactory $paginatorFactory, RemoteCalendarConnectorInterface $remoteCalendarConnector, SerializerInterface $serializer) { $this->paginatorFactory = $paginatorFactory; @@ -51,9 +52,9 @@ class RemoteCalendarProxyController } if (false === $dateFrom = DateTimeImmutable::createFromFormat( - DateTimeImmutable::ATOM, - $request->query->get('dateFrom') - )) { + DateTimeImmutable::ATOM, + $request->query->get('dateFrom') + )) { throw new BadRequestHttpException('dateFrom not parsable'); } @@ -62,14 +63,15 @@ class RemoteCalendarProxyController } if (false === $dateTo = DateTimeImmutable::createFromFormat( - DateTimeImmutable::ATOM, - $request->query->get('dateTo') - )) { + DateTimeImmutable::ATOM, + $request->query->get('dateTo') + )) { throw new BadRequestHttpException('dateTo not parsable'); } $events = $this->remoteCalendarConnector->listEventsForUser($user, $dateFrom, $dateTo); $paginator = $this->paginatorFactory->create(count($events)); + if (count($events) > 0) { $paginator->setItemsPerPage($paginator->getTotalItems()); } diff --git a/src/Bundle/ChillCalendarBundle/Entity/Calendar.php b/src/Bundle/ChillCalendarBundle/Entity/Calendar.php index 1a4fb02b4..426827701 100644 --- a/src/Bundle/ChillCalendarBundle/Entity/Calendar.php +++ b/src/Bundle/ChillCalendarBundle/Entity/Calendar.php @@ -64,6 +64,7 @@ class Calendar implements TrackCreationInterface, TrackUpdateInterface /** * @ORM\ManyToOne(targetEntity="CalendarRange", inversedBy="calendars") + * @Serializer\Groups({"calendar:read", "read"}) */ private ?CalendarRange $calendarRange = null; diff --git a/src/Bundle/ChillCalendarBundle/Entity/CalendarRange.php b/src/Bundle/ChillCalendarBundle/Entity/CalendarRange.php index 114acf7aa..a255970c3 100644 --- a/src/Bundle/ChillCalendarBundle/Entity/CalendarRange.php +++ b/src/Bundle/ChillCalendarBundle/Entity/CalendarRange.php @@ -42,7 +42,7 @@ class CalendarRange implements TrackCreationInterface, TrackUpdateInterface /** * @ORM\Column(type="datetimetz_immutable") - * @groups({"read", "write"}) + * @groups({"read", "write", "calendar:read"}) */ private ?DateTimeImmutable $endDate = null; @@ -56,13 +56,13 @@ class CalendarRange implements TrackCreationInterface, TrackUpdateInterface /** * @ORM\Column(type="datetimetz_immutable") - * @groups({"read", "write"}) + * @groups({"read", "write", "calendar:read"}) */ private ?DateTimeImmutable $startDate = null; /** * @ORM\ManyToOne(targetEntity="Chill\MainBundle\Entity\User") - * @groups({"read", "write"}) + * @groups({"read", "write", "calendar:read"}) */ private ?User $user = null; diff --git a/src/Bundle/ChillCalendarBundle/Form/CalendarType.php b/src/Bundle/ChillCalendarBundle/Form/CalendarType.php index 37bb97c1d..65c7d1320 100644 --- a/src/Bundle/ChillCalendarBundle/Form/CalendarType.php +++ b/src/Bundle/ChillCalendarBundle/Form/CalendarType.php @@ -91,15 +91,19 @@ class CalendarType extends AbstractType ->addModelTransformer(new CallbackTransformer( static function (?DateTimeImmutable $dateTimeImmutable): string { if (null !== $dateTimeImmutable) { - $res = date_format($dateTimeImmutable, 'Y-m-d H:i:s'); + $res = date_format($dateTimeImmutable, DateTimeImmutable::ATOM); } else { $res = ''; } return $res; }, - static function (?string $dateAsString): DateTimeImmutable { - return new DateTimeImmutable($dateAsString); + static function (?string $dateAsString): ?DateTimeImmutable { + if ('' === $dateAsString) { + return null; + } + + return DateTimeImmutable::createFromFormat(DateTimeImmutable::ATOM, $dateAsString); } )); @@ -108,15 +112,19 @@ class CalendarType extends AbstractType ->addModelTransformer(new CallbackTransformer( static function (?DateTimeImmutable $dateTimeImmutable): string { if (null !== $dateTimeImmutable) { - $res = date_format($dateTimeImmutable, 'Y-m-d H:i:s'); + $res = date_format($dateTimeImmutable, DateTimeImmutable::ATOM); } else { $res = ''; } return $res; }, - static function (?string $dateAsString): DateTimeImmutable { - return new DateTimeImmutable($dateAsString); + static function (?string $dateAsString): ?DateTimeImmutable { + if ('' === $dateAsString) { + return null; + } + + return DateTimeImmutable::createFromFormat(DateTimeImmutable::ATOM, $dateAsString); } )); diff --git a/src/Bundle/ChillCalendarBundle/Resources/public/vuejs/Calendar/App.vue b/src/Bundle/ChillCalendarBundle/Resources/public/vuejs/Calendar/App.vue index b513d549d..010550b43 100644 --- a/src/Bundle/ChillCalendarBundle/Resources/public/vuejs/Calendar/App.vue +++ b/src/Bundle/ChillCalendarBundle/Resources/public/vuejs/Calendar/App.vue @@ -152,6 +152,20 @@ export default { this.$store.dispatch('updateEvent', payload); }, onEventClick(payload) { + console.log('onEventClick', payload); + + console.log('extendedProps', payload.event.extendedProps); + console.log('isRange', payload.event.extendedProps.is === 'range'); + + if (payload.event.extendedProps.is !== 'range') { + // do nothing when clicking on remote + return; + } + + this.$store.dispatch('associateCalendarToRange', {range: payload.event}); + + + /* this.previousSelectedEvent = this.selectedEvent; this.previousSelectedEventColor = payload.event.extendedProps.sourceColor; this.selectedEvent = payload.event; @@ -160,6 +174,7 @@ export default { payload.event.setProp('borderColor', '#3788d8'); payload.event.setProp('title', 'Choisir cette plage'); payload.event.setProp('textColor', '#ffffff'); + */ }, onEventMouseEnter(payload) { payload.event.setProp('borderColor', '#444444'); diff --git a/src/Bundle/ChillCalendarBundle/Resources/public/vuejs/Calendar/store/actions.js b/src/Bundle/ChillCalendarBundle/Resources/public/vuejs/Calendar/store/actions.js index 052c58ffd..31f50407e 100644 --- a/src/Bundle/ChillCalendarBundle/Resources/public/vuejs/Calendar/store/actions.js +++ b/src/Bundle/ChillCalendarBundle/Resources/public/vuejs/Calendar/store/actions.js @@ -8,6 +8,7 @@ import { fetchCalendarRangeForUser, fetchCalendarRemoteForUser, } from './../api'; +import {datetimeToISO} from 'ChillMainAssets/chill/js/date'; export default { setCurrentDatesView({ commit, dispatch }, {start, end}) { @@ -106,19 +107,20 @@ export default { //mainUserInput.value = payload.users.logged.id; commit('setEvents', payload); }, - updateEvent({ commit, dispatch }, payload) { - console.log('### action updateEvent', payload); + associateCalendarToRange({ commit, dispatch }, {range}) { + console.log('### action associateCAlendarToRange', range); let startDateInput = document.getElementById("chill_activitybundle_activity_startDate"); - startDateInput.value = payload.event.start.toISOString(); + startDateInput.value = datetimeToISO(range.start); let endDateInput = document.getElementById("chill_activitybundle_activity_endDate"); - endDateInput.value = payload.event.end.toISOString(); + endDateInput.value = datetimeToISO(range.end); let calendarRangeInput = document.getElementById("chill_activitybundle_activity_calendarRange"); - calendarRangeInput.value = Number(payload.event.extendedProps.calendarRangeId); + calendarRangeInput.value = Number(range.extendedProps.calendarRangeId); //dispatch('setMainUser', payload.event.source); //let mainUserInput = document.getElementById("chill_activitybundle_activity_mainUser"); //mainUserInput.value = Number(payload.event.source.id); - commit('setEvents', payload); + commit('associateCalendarToRange', {range}); + return Promise.resolve(); }, setMainUser({ commit }, mainUser) { console.log('rawMainuser', toRaw(mainUser)); diff --git a/src/Bundle/ChillCalendarBundle/Resources/public/vuejs/Calendar/store/getters.js b/src/Bundle/ChillCalendarBundle/Resources/public/vuejs/Calendar/store/getters.js index 3365fa181..90fcef224 100644 --- a/src/Bundle/ChillCalendarBundle/Resources/public/vuejs/Calendar/store/getters.js +++ b/src/Bundle/ChillCalendarBundle/Resources/public/vuejs/Calendar/store/getters.js @@ -26,11 +26,33 @@ export default { * Compute the event sources to show on the FullCalendar * * @param state - * @returns {*[]} + * @param getters + * @returns {[]} */ - getEventSources(state) { + getEventSources(state, getters) { let sources = []; + // current calendar + if (state.activity.startDate !== null && state.activity.endDate !== null) { + const s = { + id: 'current', + backgroundColor: '#3788d8', + borderColor: '#3788d8', + textColor: '#ffffff', + events: [ + { + title: "Rendez-vous", + start: state.activity.startDate, + end: state.activity.endDate, + allDay: false, + } + ], + editable: state.activity.calendarRange === null, + }; + + sources.push(s); + } + for (const [userId, kinds] of state.currentView.users.entries()) { if (!state.usersData.has(userId)) { console.log('try to get events on a user which not exists', userId); @@ -40,9 +62,11 @@ export default { const userData = state.usersData.get(userId); if (kinds.ranges && userData.calendarRanges.length > 0) { + console.log('first range', userData.calendarRanges[0]); + console.log('state activity', state.activity); const s = { id: `ranges_${userId}`, - events: userData.calendarRanges, + events: userData.calendarRanges.filter(r => state.activity.calendarRange === null || r.calendarRangeId !== state.activity.calendarRange.calendarRangeId), color: userData.mainColor, backgroundColor: 'white', textColor: 'black', diff --git a/src/Bundle/ChillCalendarBundle/Resources/public/vuejs/Calendar/store/mutations.js b/src/Bundle/ChillCalendarBundle/Resources/public/vuejs/Calendar/store/mutations.js index 364393fc4..5fabaa870 100644 --- a/src/Bundle/ChillCalendarBundle/Resources/public/vuejs/Calendar/store/mutations.js +++ b/src/Bundle/ChillCalendarBundle/Resources/public/vuejs/Calendar/store/mutations.js @@ -27,6 +27,24 @@ export default { } ); }, + associateCalendarToRange(state, {range}) { + console.log('userId', range.extendedProps.userId); + + const r = state.usersData.get(range.extendedProps.userId).calendarRanges + .find(r => r.calendarRangeId === range.extendedProps.calendarRangeId); + + if (typeof r === 'undefined') { + throw Error('Could not find managed calendar range'); + } + + console.log('range found', r); + + state.activity.startDate = range.start; + state.activity.endDate = range.end; + state.activity.calendarRange = r; + + console.log('activity', state.activity); + }, // ConcernedGroups addPersonsInvolved(state, payload) { diff --git a/src/Bundle/ChillCalendarBundle/Resources/public/vuejs/Calendar/store/utils.js b/src/Bundle/ChillCalendarBundle/Resources/public/vuejs/Calendar/store/utils.js index da6d14ace..75cf65f04 100644 --- a/src/Bundle/ChillCalendarBundle/Resources/public/vuejs/Calendar/store/utils.js +++ b/src/Bundle/ChillCalendarBundle/Resources/public/vuejs/Calendar/store/utils.js @@ -43,6 +43,8 @@ const calendarRangeToFullCalendarEvent = (entity) => { end: entity.endDate.datetime8601, allDay: false, userId: entity.user.id, + calendarRangeId: entity.id, + is: 'range', }; } @@ -53,6 +55,7 @@ const remoteToFullCalendarEvent = (entity) => { start: entity.startDate.datetime8601, end: entity.endDate.datetime8601, allDay: false, + is: 'remote', }; } diff --git a/src/Bundle/ChillCalendarBundle/Tests/Form/CalendarTypeTest.php b/src/Bundle/ChillCalendarBundle/Tests/Form/CalendarTypeTest.php index eb8b78d94..8adc0599c 100644 --- a/src/Bundle/ChillCalendarBundle/Tests/Form/CalendarTypeTest.php +++ b/src/Bundle/ChillCalendarBundle/Tests/Form/CalendarTypeTest.php @@ -107,8 +107,8 @@ final class CalendarTypeTest extends TypeTestCase $this->assertEquals(8, $calendar->getCalendarRange()->getId()); $this->assertEquals(9, $calendar->getLocation()->getId()); $this->assertEquals(true, $calendar->getSendSMS()); - $this->assertContains(2, $calendar->getUsers()->map(function (User $u) { return $u->getId(); })); - $this->assertContains(3, $calendar->getUsers()->map(function (User $u) { return $u->getId(); })); + $this->assertContains(2, $calendar->getUsers()->map(static function (User $u) { return $u->getId(); })); + $this->assertContains(3, $calendar->getUsers()->map(static function (User $u) { return $u->getId(); })); } protected function getExtensions()