work on create calendar

This commit is contained in:
Julien Fastré 2022-05-13 13:49:24 +02:00
parent 7859439f0b
commit 4be3efc619
10 changed files with 128 additions and 44 deletions

View File

@ -284,12 +284,8 @@ class CalendarController extends AbstractController
$entity = new Calendar(); $entity = new Calendar();
if ($request->query->has('mainUser')) { if ($request->query->has('mainUser')) {
$entity->setMainUser($this->userRepository->find($request->query->getInt('mainUser'))); $entity->setMainUser($this->userRepository->find($request->query->getInt('mainUser')));
} else {
$entity->setMainUser($this->getUser());
} }
dump($entity);
// if ($user instanceof User) { // if ($user instanceof User) {
// $entity->setPerson($user); // $entity->setPerson($user);
// } // }

View File

@ -172,6 +172,29 @@ class Calendar implements TrackCreationInterface, TrackUpdateInterface
return $this; return $this;
} }
public function addUser(User $user): self
{
if (!$this->getUsers()->contains($user)) {
$this->addInvite((new Invite())->setUser($user));
}
return $this;
}
public function removeUser(User $user): self
{
if (!$this->getUsers()->contains($user)) {
return $this;
}
$invite = $this->invites
->filter(function (Invite $invite) use ($user) { return $invite->getUser() === $user; })
->first();
$this->removeInvite($invite);
return $this;
}
public function addPerson(Person $person): self public function addPerson(Person $person): self
{ {
$this->persons[] = $person; $this->persons[] = $person;
@ -309,14 +332,12 @@ class Calendar implements TrackCreationInterface, TrackUpdateInterface
return $this->getProfessionals(); return $this->getProfessionals();
} }
public function getUser(): ?User /**
* @return Collection|User[]
*/
public function getUsers(): Collection
{ {
return $this->user; return $this->getInvites()->map(function (Invite $i) { return $i->getUser(); });
}
public function getusers(): Collection
{
return $this->getInvites(); //TODO get users of the invite
} }
public static function loadValidatorMetadata(ClassMetadata $metadata): void public static function loadValidatorMetadata(ClassMetadata $metadata): void
@ -335,7 +356,9 @@ class Calendar implements TrackCreationInterface, TrackUpdateInterface
public function removeInvite(Invite $invite): self public function removeInvite(Invite $invite): self
{ {
$this->invites->removeElement($invite); if ($this->invites->removeElement($invite)) {
$invite->setCalendar(null);
}
return $this; return $this;
} }

View File

@ -40,14 +40,14 @@ class Invite implements TrackUpdateInterface, TrackCreationInterface
/** /**
* @ORM\ManyToOne(targetEntity=Calendar::class, inversedBy="invites") * @ORM\ManyToOne(targetEntity=Calendar::class, inversedBy="invites")
*/ */
private ?Calendar $calendar; private ?Calendar $calendar = null;
/** /**
* @ORM\Id * @ORM\Id
* @ORM\GeneratedValue * @ORM\GeneratedValue
* @ORM\Column(type="integer") * @ORM\Column(type="integer")
*/ */
private ?int $id; private ?int $id = null;
/** /**
* @ORM\Column(type="text", nullable=false, options={"default": "pending"}) * @ORM\Column(type="text", nullable=false, options={"default": "pending"})
@ -58,7 +58,7 @@ class Invite implements TrackUpdateInterface, TrackCreationInterface
* @ORM\ManyToOne(targetEntity="Chill\MainBundle\Entity\User") * @ORM\ManyToOne(targetEntity="Chill\MainBundle\Entity\User")
* @ORM\JoinColumn(nullable=false) * @ORM\JoinColumn(nullable=false)
*/ */
private ?User $user; private ?User $user = null;
public function getCalendar(): ?Calendar public function getCalendar(): ?Calendar
{ {
@ -82,8 +82,6 @@ class Invite implements TrackUpdateInterface, TrackCreationInterface
/** /**
* @internal use Calendar::addInvite instead * @internal use Calendar::addInvite instead
* @param Calendar|null $calendar
* @return void
*/ */
public function setCalendar(?Calendar $calendar): void public function setCalendar(?Calendar $calendar): void
{ {
@ -99,6 +97,10 @@ class Invite implements TrackUpdateInterface, TrackCreationInterface
public function setUser(?User $user): self public function setUser(?User $user): self
{ {
if ($user instanceof User && $this->user instanceof User && $user !== $this->user) {
throw new \LogicException("Not allowed to associate an invite to a different user");
}
$this->user = $user; $this->user = $user;
return $this; return $this;

View File

@ -70,6 +70,7 @@ class CalendarType extends AbstractType
if ($options['data'] instanceof Calendar && $options['data']->getId() === null) { if ($options['data'] instanceof Calendar && $options['data']->getId() === null) {
$builder->add('mainUser', PickUserDynamicType::class, [ $builder->add('mainUser', PickUserDynamicType::class, [
'multiple' => false,
'required' => true, 'required' => true,
'help' => 'chill_calendar.form.The main user is mandatory. He will organize the appointment.', 'help' => 'chill_calendar.form.The main user is mandatory. He will organize the appointment.',
]); ]);
@ -192,26 +193,6 @@ class CalendarType extends AbstractType
return $this->om->getRepository(Location::class)->findOneBy(['id' => (int) $id]); return $this->om->getRepository(Location::class)->findOneBy(['id' => (int) $id]);
} }
)); ));
$builder->add('invites', HiddenType::class);
$builder->get('invites')
->addModelTransformer(new CallbackTransformer(
static function (iterable $usersAsIterable): string {
$userIds = [];
foreach ($usersAsIterable as $value) {
$userIds[] = $value->getId();
}
return implode(',', $userIds);
},
function (?string $usersAsString): array {
return array_map(
fn (string $id): ?Invite => $this->om->getRepository(Invite::class)->findOneBy(['id' => (int) $id]),
explode(',', $usersAsString)
);
}
));
} }
public function configureOptions(OptionsResolver $resolver) public function configureOptions(OptionsResolver $resolver)

View File

@ -180,8 +180,8 @@ const store = createStore({
startDateInput.value = payload.startStr; startDateInput.value = payload.startStr;
let endDateInput = document.getElementById("chill_activitybundle_activity_endDate"); let endDateInput = document.getElementById("chill_activitybundle_activity_endDate");
endDateInput.value = payload.endStr; endDateInput.value = payload.endStr;
let mainUserInput = document.getElementById("chill_activitybundle_activity_mainUser"); //let mainUserInput = document.getElementById("chill_activitybundle_activity_mainUser");
mainUserInput.value = payload.users.logged.id; //mainUserInput.value = payload.users.logged.id;
commit('setEvents', payload); commit('setEvents', payload);
}, },
updateEvent({ commit }, payload) { updateEvent({ commit }, payload) {
@ -192,8 +192,8 @@ const store = createStore({
endDateInput.value = payload.event.end.toISOString(); endDateInput.value = payload.event.end.toISOString();
let calendarRangeInput = document.getElementById("chill_activitybundle_activity_calendarRange"); let calendarRangeInput = document.getElementById("chill_activitybundle_activity_calendarRange");
calendarRangeInput.value = Number(payload.event.extendedProps.calendarRangeId); calendarRangeInput.value = Number(payload.event.extendedProps.calendarRangeId);
let mainUserInput = document.getElementById("chill_activitybundle_activity_mainUser"); //let mainUserInput = document.getElementById("chill_activitybundle_activity_mainUser");
mainUserInput.value = Number(payload.event.source.id); //mainUserInput.value = Number(payload.event.source.id);
commit('setEvents', payload); commit('setEvents', payload);
}, },

View File

@ -0,0 +1,44 @@
<?php
namespace Chill\CalendarBundle\Tests\Entity;
use Chill\CalendarBundle\Entity\Calendar;
use Chill\MainBundle\Entity\User;
use PHPUnit\Framework\TestCase;
class CalendarTest extends TestCase
{
public function testAddUser()
{
$calendar = new Calendar();
$this->assertCount(0, $calendar->getInvites());
$this->assertCount(0, $calendar->getUsers());
$calendar->addUser($user0 = new User());
$this->assertCount(1, $calendar->getInvites());
$this->assertCount(1, $calendar->getUsers());
$this->assertSame($user0, $calendar->getUsers()->first());
$calendar->addUser($user1 = new User());
$this->assertCount(2, $calendar->getInvites());
$this->assertCount(2, $calendar->getUsers());
$this->assertContains($user0, $calendar->getUsers());
$this->assertContains($user1, $calendar->getUsers());
$calendar->removeUser($user0);
$this->assertCount(1, $calendar->getInvites());
$this->assertCount(1, $calendar->getUsers());
$this->assertNotSame($user0, $calendar->getUsers()->first());
$this->assertSame($user1, $calendar->getUsers()->first());
$calendar->removeUser($user1);
$this->assertCount(0, $calendar->getInvites());
$this->assertCount(0, $calendar->getUsers());
}
}

View File

@ -43,6 +43,9 @@ class EntityToJsonTransformer implements DataTransformerInterface
public function reverseTransform($value) public function reverseTransform($value)
{ {
dump($value);
dump($this->type);
dump($this->multiple);
$denormalized = json_decode($value, true); $denormalized = json_decode($value, true);
if ($this->multiple) { if ($this->multiple) {

View File

@ -13,6 +13,7 @@ namespace Chill\MainBundle\Repository;
use Chill\MainBundle\Entity\Location; use Chill\MainBundle\Entity\Location;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\ORM\Query\ResultSetMappingBuilder;
use Doctrine\Persistence\ManagerRegistry; use Doctrine\Persistence\ManagerRegistry;
/** /**
@ -37,4 +38,18 @@ class LocationRepository extends ServiceEntityRepository
{ {
return $this->findBy(['active' => true, 'availableForUsers' => true]); return $this->findBy(['active' => true, 'availableForUsers' => true]);
} }
/**
* fetch location by name
*
* @return array|Location[]
*/
public function findByName(string $name, string $lang): array
{
$rsm = new ResultSetMappingBuilder($this->getEntityManager());
$rsm->addRootEntityFromClassMetadata(Location::class);
$sql = "SELECT "
}
} }

View File

@ -6,6 +6,7 @@ import { appMessages } from 'ChillMainAssets/vuejs/PickEntity/i18n';
const i18n = _createI18n(appMessages); const i18n = _createI18n(appMessages);
let appsOnPage = new Map(); let appsOnPage = new Map();
let appsPerInput = new Map();
function loadDynamicPicker(element) { function loadDynamicPicker(element) {
@ -23,6 +24,8 @@ function loadDynamicPicker(element) {
null : [ JSON.parse(input.value) ] null : [ JSON.parse(input.value) ]
) )
; ;
console.log('picked at startup', picked);
console.log('input', input);
if (!isMultiple) { if (!isMultiple) {
if (input.value === '[]'){ if (input.value === '[]'){
@ -78,13 +81,14 @@ function loadDynamicPicker(element) {
.mount(el); .mount(el);
appsOnPage.set(uniqId, app); appsOnPage.set(uniqId, app);
appsPerInput.set(input.name, app);
}); });
} }
document.addEventListener('show-hide-show', function(e) { document.addEventListener('show-hide-show', function(e) {
loadDynamicPicker(e.detail.container) loadDynamicPicker(e.detail.container)
}) });
document.addEventListener('show-hide-hide', function(e) { document.addEventListener('show-hide-hide', function(e) {
console.log('hiding event caught') console.log('hiding event caught')
@ -95,7 +99,23 @@ document.addEventListener('show-hide-hide', function(e) {
appsOnPage.delete(uniqId); appsOnPage.delete(uniqId);
} }
}) })
}) });
document.addEventListener('pick-entity-type', function (e) {
console.log('pick entity event', e);
if (!appsPerInput.has(e.detail.name)) {
console.error('no app with this name');
return;
}
const app = appsPerInput.get(e.detail.name);
if (e.detail.action === 'add') {
app.addNewEntity(e.detail.entity);
} else if (e.detail.action === 'remove') {
app.removeEntity(e.detail.entity);
} else {
console.error('action not supported: '+e.detail.action);
}
});
document.addEventListener('DOMContentLoaded', function(e) { document.addEventListener('DOMContentLoaded', function(e) {
loadDynamicPicker(document) loadDynamicPicker(document)

View File

@ -231,6 +231,6 @@
{% endblock %} {% endblock %}
{% block pick_entity_dynamic_widget %} {% block pick_entity_dynamic_widget %}
<input type="hidden" {{ block('widget_attributes') }} {% if value is not empty %}value="{{ value }}" {% endif %} data-input-uniqid="{{ form.vars['uniqid'] }}"/> <input type="hidden" {{ block('widget_attributes') }} {% if value is not empty %}value="{{ value|escape('html_attr') }}" {% endif %} data-input-uniqid="{{ form.vars['uniqid'] }}"/>
<div data-module="pick-dynamic" data-types="{{ form.vars['types']|json_encode }}" data-multiple="{{ form.vars['multiple'] }}" data-uniqid="{{ form.vars['uniqid'] }}"></div> <div data-module="pick-dynamic" data-types="{{ form.vars['types']|json_encode }}" data-multiple="{{ form.vars['multiple'] }}" data-uniqid="{{ form.vars['uniqid'] }}"></div>
{% endblock %} {% endblock %}