Add / Edit / Delete activity from Accompanying Course

This commit is contained in:
Jean-Francois Monfort 2021-05-20 15:56:34 +02:00
parent c59cf3f0df
commit 8fe00b4c2b
24 changed files with 795 additions and 433 deletions

View File

@ -23,10 +23,12 @@
namespace Chill\ActivityBundle\Controller; namespace Chill\ActivityBundle\Controller;
use Chill\MainBundle\Security\Authorization\AuthorizationHelper; use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
use Chill\PersonBundle\Entity\AccompanyingPeriod;
use Chill\PersonBundle\Entity\Person; use Chill\PersonBundle\Entity\Person;
use Chill\PersonBundle\Privacy\PrivacyEvent; use Chill\PersonBundle\Privacy\PrivacyEvent;
use Psr\Log\LoggerInterface; use Psr\Log\LoggerInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\Form\Form;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Form\Extension\Core\Type\SubmitType; use Symfony\Component\Form\Extension\Core\Type\SubmitType;
@ -61,46 +63,57 @@ class ActivityController extends AbstractController
/** /**
* Lists all Activity entities. * Lists all Activity entities.
*/ */
public function listAction($person_id): Response public function listAction(Request $request): Response
{ {
$em = $this->getDoctrine()->getManager(); $em = $this->getDoctrine()->getManager();
$person = $em->getRepository('ChillPersonBundle:Person')->find($person_id); $view = null;
if ($person === NULL) { [$person, $accompanyingPeriod] = $this->getEntity($request);
throw $this->createNotFoundException('Person not found');
if ($person instanceof Person) {
$reachableScopes = $this->authorizationHelper
->getReachableCircles($this->getUser(), new Role('CHILL_ACTIVITY_SEE'),
$person->getCenter());
$activities = $em->getRepository('ChillActivityBundle:Activity')->findBy(
['person' => $person, 'scope' => $reachableScopes],
['date' => 'DESC'],
);
$event = new PrivacyEvent($person, array(
'element_class' => Activity::class,
'action' => 'list'
));
$this->eventDispatcher->dispatch(PrivacyEvent::PERSON_PRIVACY_EVENT, $event);
$view = 'ChillActivityBundle:Activity:listPerson.html.twig';
} elseif ($accompanyingPeriod instanceof AccompanyingPeriod) {
$activities = $em->getRepository('ChillActivityBundle:Activity')->findBy(
['accompanyingPeriod' => $accompanyingPeriod],
['date' => 'DESC'],
);
$view = 'ChillActivityBundle:Activity:listAccompanyingCourse.html.twig';
} }
$this->denyAccessUnlessGranted('CHILL_PERSON_SEE', $person); return $this->render($view, array(
$reachableScopes = $this->authorizationHelper
->getReachableCircles($this->getUser(), new Role('CHILL_ACTIVITY_SEE'),
$person->getCenter());
$activities = $em->getRepository('ChillActivityBundle:Activity')
->findBy(
array('person' => $person, 'scope' => $reachableScopes),
array('date' => 'DESC')
);
$event = new PrivacyEvent($person, array(
'element_class' => Activity::class,
'action' => 'list'
));
$this->eventDispatcher->dispatch(PrivacyEvent::PERSON_PRIVACY_EVENT, $event);
return $this->render('ChillActivityBundle:Activity:list.html.twig', array(
'activities' => $activities, 'activities' => $activities,
'person' => $person 'person' => $person,
'accompanyingCourse' => $accompanyingPeriod,
)); ));
} }
public function selectTypeAction(int $person_id): Response public function selectTypeAction(Request $request): Response
{ {
$em = $this->getDoctrine()->getManager(); $em = $this->getDoctrine()->getManager();
$person = $em->getRepository(Person::class)->find($person_id); $view = null;
if ($person === NULL) { [$person, $accompanyingPeriod] = $this->getEntity($request);
throw $this->createNotFoundException('Person not found');
if ($accompanyingPeriod instanceof AccompanyingPeriod) {
$view = 'ChillActivityBundle:Activity:selectTypeAccompanyingCourse.html.twig';
} elseif ($person instanceof Person) {
$view = 'ChillActivityBundle:Activity:selectTypePerson.html.twig';
} }
$data = []; $data = [];
@ -118,19 +131,27 @@ class ActivityController extends AbstractController
]; ];
} }
return $this->render('ChillActivityBundle:Activity:selectType.html.twig', [ if ($view === null) {
'person' => $person, throw $this->createNotFoundException('Template not found');
}
return $this->render($view, [
'person' => $person,
'accompanyingCourse' => $accompanyingPeriod,
'data' => $data, 'data' => $data,
]); ]);
} }
public function newAction($person_id, Request $request): Response public function newAction(Request $request): Response
{ {
$em = $this->getDoctrine()->getManager(); $em = $this->getDoctrine()->getManager();
$person = $em->getRepository('ChillPersonBundle:Person')->find($person_id);
if (null === $person) { [$person, $accompanyingPeriod] = $this->getEntity($request);
throw $this->createNotFoundException('Person not found');
if ($accompanyingPeriod instanceof AccompanyingPeriod) {
$view = 'ChillActivityBundle:Activity:newAccompanyingCourse.html.twig';
} elseif ($person instanceof Person) {
$view = 'ChillActivityBundle:Activity:newPerson.html.twig';
} }
$activityType_id = $request->get('activityType_id', 0); $activityType_id = $request->get('activityType_id', 0);
@ -139,20 +160,27 @@ class ActivityController extends AbstractController
if (!$activityType instanceof \Chill\ActivityBundle\Entity\ActivityType || if (!$activityType instanceof \Chill\ActivityBundle\Entity\ActivityType ||
!$activityType->isActive()) { !$activityType->isActive()) {
return $this->redirectToRoute('chill_activity_activity_select_type', [
'person_id' => $person->getId(),
]);
}
$this->denyAccessUnlessGranted('CHILL_PERSON_SEE', $person); $params = $this->buildParamsToUrl($person, $accompanyingPeriod);
return $this->redirectToRoute('chill_activity_activity_select_type', $params);
}
$entity = new Activity(); $entity = new Activity();
$entity->setUser($this->getUser()); $entity->setUser($this->getUser());
$entity->setPerson($person);
if ($person instanceof Person) {
$entity->setPerson($person);
}
if ($accompanyingPeriod instanceof AccompanyingPeriod) {
$entity->setAccompanyingPeriod($accompanyingPeriod);
}
$entity->setType($activityType); $entity->setType($activityType);
$entity->setDate(new \DateTime('now')); $entity->setDate(new \DateTime('now'));
$this->denyAccessUnlessGranted('CHILL_ACTIVITY_CREATE', $entity); // TODO revoir le Voter de Activity pour tenir compte qu'une activité peut appartenir a une période
// $this->denyAccessUnlessGranted('CHILL_ACTIVITY_CREATE', $entity);
$form = $this->createForm(ActivityType::class, $entity, [ $form = $this->createForm(ActivityType::class, $entity, [
'center' => $entity->getCenter(), 'center' => $entity->getCenter(),
@ -166,49 +194,64 @@ class ActivityController extends AbstractController
$this->addFlash('success', $this->get('translator')->trans('Success : activity created!')); $this->addFlash('success', $this->get('translator')->trans('Success : activity created!'));
return $this->redirectToRoute('chill_activity_activity_show', [ $params = $this->buildParamsToUrl($person, $accompanyingPeriod);
'id' => $entity->getId(), $params['id'] = $entity->getId();
'person_id' => $person_id
]); return $this->redirectToRoute('chill_activity_activity_show', $params);
} }
return $this->render('ChillActivityBundle:Activity:new.html.twig', array( if ($view === null) {
throw $this->createNotFoundException('Template not found');
}
return $this->render($view, [
'person' => $person, 'person' => $person,
'accompanyingCourse' => $accompanyingPeriod,
'entity' => $entity, 'entity' => $entity,
'form' => $form->createView(), 'form' => $form->createView(),
)); ]);
} }
public function showAction($person_id, $id): Response public function showAction(Request $request, $id): Response
{ {
$em = $this->getDoctrine()->getManager(); $em = $this->getDoctrine()->getManager();
$person = $em->getRepository('ChillPersonBundle:Person')->find($person_id);
if (!$person) { [$person, $accompanyingPeriod] = $this->getEntity($request);
throw $this->createNotFoundException('person not found');
if ($accompanyingPeriod instanceof AccompanyingPeriod) {
$view = 'ChillActivityBundle:Activity:showAccompanyingCourse.html.twig';
} elseif ($person instanceof Person) {
$view = 'ChillActivityBundle:Activity:showPerson.html.twig';
} }
$this->denyAccessUnlessGranted('CHILL_PERSON_SEE', $person);
$entity = $em->getRepository('ChillActivityBundle:Activity')->find($id); $entity = $em->getRepository('ChillActivityBundle:Activity')->find($id);
if (!$entity) { if (!$entity) {
throw $this->createNotFoundException('Unable to find Activity entity.'); throw $this->createNotFoundException('Unable to find Activity entity.');
} }
$this->denyAccessUnlessGranted('CHILL_ACTIVITY_SEE', $entity); // TODO revoir le Voter de Activity pour tenir compte qu'une activité peut appartenir a une période
// $this->denyAccessUnlessGranted('CHILL_ACTIVITY_SEE', $entity);
$deleteForm = $this->createDeleteForm($id, $person); $deleteForm = $this->createDeleteForm($id, $person, $accompanyingPeriod);
// TODO
/*
$event = new PrivacyEvent($person, array( $event = new PrivacyEvent($person, array(
'element_class' => Activity::class, 'element_class' => Activity::class,
'element_id' => $entity->getId(), 'element_id' => $entity->getId(),
'action' => 'show' 'action' => 'show'
)); ));
$this->eventDispatcher->dispatch(PrivacyEvent::PERSON_PRIVACY_EVENT, $event); $this->eventDispatcher->dispatch(PrivacyEvent::PERSON_PRIVACY_EVENT, $event);
*/
return $this->render('ChillActivityBundle:Activity:show.html.twig', array( if ($view === null) {
throw $this->createNotFoundException('Template not found');
}
return $this->render($view, array(
'person' => $person, 'person' => $person,
'accompanyingCourse' => $accompanyingPeriod,
'entity' => $entity, 'entity' => $entity,
'delete_form' => $deleteForm->createView(), 'delete_form' => $deleteForm->createView(),
)); ));
@ -218,24 +261,26 @@ class ActivityController extends AbstractController
* Displays a form to edit an existing Activity entity. * Displays a form to edit an existing Activity entity.
* *
*/ */
public function editAction($person_id, $id, Request $request): Response public function editAction($id, Request $request): Response
{ {
$em = $this->getDoctrine()->getManager(); $em = $this->getDoctrine()->getManager();
$person = $em->getRepository('ChillPersonBundle:Person')->find($person_id);
if (!$person) { [$person, $accompanyingPeriod] = $this->getEntity($request);
throw $this->createNotFoundException('person not found');
if ($accompanyingPeriod instanceof AccompanyingPeriod) {
$view = 'ChillActivityBundle:Activity:editAccompanyingCourse.html.twig';
} elseif ($person instanceof Person) {
$view = 'ChillActivityBundle:Activity:editPerson.html.twig';
} }
$this->denyAccessUnlessGranted('CHILL_PERSON_SEE', $person);
$entity = $em->getRepository('ChillActivityBundle:Activity')->find($id); $entity = $em->getRepository('ChillActivityBundle:Activity')->find($id);
if (!$entity) { if (!$entity) {
throw $this->createNotFoundException('Unable to find Activity entity.'); throw $this->createNotFoundException('Unable to find Activity entity.');
} }
$this->denyAccessUnlessGranted('CHILL_ACTIVITY_UPDATE', $entity); // TODO
// $this->denyAccessUnlessGranted('CHILL_ACTIVITY_UPDATE', $entity);
$form = $this->createForm(ActivityType::class, $entity, [ $form = $this->createForm(ActivityType::class, $entity, [
'center' => $entity->getCenter(), 'center' => $entity->getCenter(),
@ -249,23 +294,29 @@ class ActivityController extends AbstractController
$this->addFlash('success', $this->get('translator')->trans('Success : activity updated!')); $this->addFlash('success', $this->get('translator')->trans('Success : activity updated!'));
return $this->redirect($this->generateUrl('chill_activity_activity_show', array('id' => $id, 'person_id' => $person_id))); $params = $this->buildParamsToUrl($person, $accompanyingPeriod);
$params['id'] = $id;
return $this->redirectToRoute('chill_activity_activity_show', $params);
} }
$deleteForm = $this->createDeleteForm($id, $person); $deleteForm = $this->createDeleteForm($id, $person, $accompanyingPeriod);
/*
* TODO
$event = new PrivacyEvent($person, array( $event = new PrivacyEvent($person, array(
'element_class' => Activity::class, 'element_class' => Activity::class,
'element_id' => $entity->getId(), 'element_id' => $entity->getId(),
'action' => 'edit' 'action' => 'edit'
)); ));
$this->eventDispatcher->dispatch(PrivacyEvent::PERSON_PRIVACY_EVENT, $event); $this->eventDispatcher->dispatch(PrivacyEvent::PERSON_PRIVACY_EVENT, $event);
*/
return $this->render('ChillActivityBundle:Activity:edit.html.twig', array( return $this->render($view, array(
'entity' => $entity, 'entity' => $entity,
'edit_form' => $form->createView(), 'edit_form' => $form->createView(),
'delete_form' => $deleteForm->createView(), 'delete_form' => $deleteForm->createView(),
'person' => $person 'person' => $person,
'accompanyingCourse' => $accompanyingPeriod,
)); ));
} }
@ -273,22 +324,29 @@ class ActivityController extends AbstractController
* Deletes a Activity entity. * Deletes a Activity entity.
* *
*/ */
public function deleteAction(Request $request, $id, $person_id) public function deleteAction(Request $request, $id)
{ {
$em = $this->getDoctrine()->getManager(); $em = $this->getDoctrine()->getManager();
[$person, $accompanyingPeriod] = $this->getEntity($request);
if ($accompanyingPeriod instanceof AccompanyingPeriod) {
$view = 'ChillActivityBundle:Activity:confirm_deleteAccompanyingCourse.html.twig';
} elseif ($person instanceof Person) {
$view = 'ChillActivityBundle:Activity:confirm_deletePerson.html.twig';
}
/* @var $activity Activity */ /* @var $activity Activity */
$activity = $em->getRepository('ChillActivityBundle:Activity') $activity = $em->getRepository('ChillActivityBundle:Activity')->find($id);
->find($id);
$person = $activity->getPerson();
if (!$activity) { if (!$activity) {
throw $this->createNotFoundException('Unable to find Activity entity.'); throw $this->createNotFoundException('Unable to find Activity entity.');
} }
$this->denyAccessUnlessGranted('CHILL_ACTIVITY_DELETE', $activity); // TODO
// $this->denyAccessUnlessGranted('CHILL_ACTIVITY_DELETE', $activity);
$form = $this->createDeleteForm($id, $person); $form = $this->createDeleteForm($id, $person, $accompanyingPeriod);
if ($request->getMethod() === Request::METHOD_DELETE) { if ($request->getMethod() === Request::METHOD_DELETE) {
$form->handleRequest($request); $form->handleRequest($request);
@ -298,14 +356,14 @@ class ActivityController extends AbstractController
$this->logger->notice("An activity has been removed", array( $this->logger->notice("An activity has been removed", array(
'by_user' => $this->getUser()->getUsername(), 'by_user' => $this->getUser()->getUsername(),
'activity_id' => $activity->getId(), 'activity_id' => $activity->getId(),
'person_id' => $activity->getPerson()->getId(), 'person_id' => $activity->getPerson() ? $activity->getPerson()->getId() : null,
'comment' => $activity->getComment()->getComment(), 'comment' => $activity->getComment()->getComment(),
'scope_id' => $activity->getScope()->getId(), 'scope_id' => $activity->getScope() ? $activity->getScope()->getId() : null,
'reasons_ids' => $activity->getReasons() 'reasons_ids' => $activity->getReasons()
->map(function ($ar) { return $ar->getId(); }) ->map(function ($ar) { return $ar->getId(); })
->toArray(), ->toArray(),
'type_id' => $activity->getType()->getId(), 'type_id' => $activity->getType()->getId(),
'duration' => $activity->getDurationTime()->format('U'), 'duration' => $activity->getDurationTime() ? $activity->getDurationTime()->format('U') : null,
'date' => $activity->getDate()->format('Y-m-d'), 'date' => $activity->getDate()->format('Y-m-d'),
'attendee' => $activity->getAttendee() 'attendee' => $activity->getAttendee()
)); ));
@ -316,37 +374,82 @@ class ActivityController extends AbstractController
$this->addFlash('success', $this->get('translator') $this->addFlash('success', $this->get('translator')
->trans("The activity has been successfully removed.")); ->trans("The activity has been successfully removed."));
return $this->redirect($this->generateUrl( $params = $this->buildParamsToUrl($person, $accompanyingPeriod);
'chill_activity_activity_list', array( return $this->redirectToRoute('chill_activity_activity_list', $params);
'person_id' => $person_id
)));
} }
} }
return $this->render('ChillActivityBundle:Activity:confirm_delete.html.twig', array( return $this->render($view, array(
'activity' => $activity, 'activity' => $activity,
'delete_form' => $form->createView() 'delete_form' => $form->createView(),
'person' => $person,
'accompanyingCourse' => $accompanyingPeriod,
)); ));
} }
/** /**
* Creates a form to delete a Activity entity by id. * Creates a form to delete a Activity entity by id.
*
* @param mixed $id The entity id
*
* @return \Symfony\Component\Form\Form The form
*/ */
private function createDeleteForm($id, $person) private function createDeleteForm(int $id, ?Person $person, ?AccompanyingPeriod $accompanyingPeriod): Form
{ {
$params = $this->buildParamsToUrl($person, $accompanyingPeriod);
$params['id'] = $id;
return $this->createFormBuilder() return $this->createFormBuilder()
->setAction($this->generateUrl( ->setAction($this->generateUrl('chill_activity_activity_delete', $params))
'chill_activity_activity_delete',
array('id' => $id, 'person_id' => $person->getId())))
->setMethod('DELETE') ->setMethod('DELETE')
->add('submit', SubmitType::class, array('label' => 'Delete')) ->add('submit', SubmitType::class, array('label' => 'Delete'))
->getForm() ->getForm()
; ;
} }
private function getEntity(Request $request): array
{
$em = $this->getDoctrine()->getManager();
$person = $accompanyingPeriod = null;
if ($request->query->has('person_id')) {
$person_id = $request->get('person_id');
$person = $em->getRepository(Person::class)->find($person_id);
if ($person === null) {
throw $this->createNotFoundException('Person not found');
}
$this->denyAccessUnlessGranted('CHILL_PERSON_SEE', $person);
} elseif ($request->query->has('accompanying_period_id')) {
$accompanying_period_id = $request->get('accompanying_period_id');
$accompanyingPeriod = $em->getRepository(AccompanyingPeriod::class)->find($accompanying_period_id);
if ($accompanyingPeriod === null) {
throw $this->createNotFoundException('Accompanying Period not found');
}
// TODO Add permission
// $this->denyAccessUnlessGranted('CHILL_PERSON_SEE', $person);
} else {
throw $this->createNotFoundException("Person or Accompanying Period not found");
}
return [
$person, $accompanyingPeriod
];
}
private function buildParamsToUrl(
?Person $person,
?AccompanyingPeriod $accompanyingPeriod
): array {
$params = [];
if ($person) {
$params['person_id'] = $person->getId();
}
if ($accompanyingPeriod) {
$params['accompanying_period_id'] = $accompanyingPeriod->getId();
}
return $params;
}
} }

View File

@ -22,6 +22,7 @@ namespace Chill\ActivityBundle\Entity;
use Chill\DocStoreBundle\Entity\Document; use Chill\DocStoreBundle\Entity\Document;
use Chill\MainBundle\Entity\Embeddable\CommentEmbeddable; use Chill\MainBundle\Entity\Embeddable\CommentEmbeddable;
use Chill\PersonBundle\Entity\AccompanyingPeriod;
use Chill\ThirdPartyBundle\Entity\ThirdParty; use Chill\ThirdPartyBundle\Entity\ThirdParty;
use Doctrine\ORM\Mapping as ORM; use Doctrine\ORM\Mapping as ORM;
use Chill\MainBundle\Entity\Scope; use Chill\MainBundle\Entity\Scope;
@ -41,11 +42,16 @@ use Chill\MainBundle\Validator\Constraints\Entity\UserCircleConsistency;
* @ORM\Entity() * @ORM\Entity()
* @ORM\Table(name="activity") * @ORM\Table(name="activity")
* @ORM\HasLifecycleCallbacks() * @ORM\HasLifecycleCallbacks()
*/
/*
* TODO : revoir
* @UserCircleConsistency( * @UserCircleConsistency(
* "CHILL_ACTIVITY_SEE_DETAILS", * "CHILL_ACTIVITY_SEE_DETAILS",
* getUserFunction="getUser", * getUserFunction="getUser",
* path="scope") * path="scope")
*/ */
class Activity implements HasCenterInterface, HasScopeInterface class Activity implements HasCenterInterface, HasScopeInterface
{ {
const SENTRECEIVED_SENT = 'sent'; const SENTRECEIVED_SENT = 'sent';
@ -101,7 +107,12 @@ class Activity implements HasCenterInterface, HasScopeInterface
/** /**
* @ORM\ManyToOne(targetEntity="Chill\PersonBundle\Entity\Person") * @ORM\ManyToOne(targetEntity="Chill\PersonBundle\Entity\Person")
*/ */
private Person $person; private ?Person $person = null;
/**
* @ORM\ManyToOne(targetEntity="Chill\PersonBundle\Entity\AccompanyingPeriod")
*/
private ?AccompanyingPeriod $accompanyingPeriod = null;
/** /**
* @ORM\Embedded(class="Chill\MainBundle\Entity\Embeddable\CommentEmbeddable", columnPrefix="comment_") * @ORM\Embedded(class="Chill\MainBundle\Entity\Embeddable\CommentEmbeddable", columnPrefix="comment_")
@ -261,25 +272,41 @@ class Activity implements HasCenterInterface, HasScopeInterface
return $this->scope; return $this->scope;
} }
public function setPerson(Person $person): self public function setPerson(?Person $person): self
{ {
$this->person = $person; $this->person = $person;
return $this; return $this;
} }
public function getPerson(): Person public function getPerson(): ?Person
{ {
return $this->person; return $this->person;
} }
public function getAccompanyingPeriod(): ?AccompanyingPeriod
{
return $this->accompanyingPeriod;
}
public function setAccompanyingPeriod(?AccompanyingPeriod $accompanyingPeriod): self
{
$this->accompanyingPeriod = $accompanyingPeriod;
return $this;
}
/** /**
* get the center * get the center
* center is extracted from person * center is extracted from person
*/ */
public function getCenter(): Center public function getCenter(): ?Center
{ {
return $this->person->getCenter(); if ($this->person instanceof Person) {
return $this->person->getCenter();
}
return null;
} }
public function getComment(): CommentEmbeddable public function getComment(): CommentEmbeddable
@ -422,4 +449,3 @@ class Activity implements HasCenterInterface, HasScopeInterface
return $this; return $this;
} }
} }

View File

@ -82,10 +82,13 @@ class ActivityType extends AbstractType
throw new \InvalidArgumentException('Activity type must be active'); throw new \InvalidArgumentException('Activity type must be active');
} }
$builder->add('scope', ScopePickerType::class, [ // TODO revoir la gestion des center au niveau du form des activité.
'center' => $options['center'], if ($options['center']) {
'role' => $options['role'] $builder->add('scope', ScopePickerType::class, [
]); 'center' => $options['center'],
'role' => $options['role']
]);
}
if ($activityType->isVisible('date')) { if ($activityType->isVisible('date')) {
$builder->add('date', ChillDateType::class, [ $builder->add('date', ChillDateType::class, [
@ -108,7 +111,7 @@ class ActivityType extends AbstractType
$builder->add('travelTime', ChoiceType::class, $durationTimeOptions); $builder->add('travelTime', ChoiceType::class, $durationTimeOptions);
} }
if ($activityType->isVisible('travelTime')) { if ($activityType->isVisible('attendee')) {
$builder->add('attendee', EntityType::class, [ $builder->add('attendee', EntityType::class, [
'label' => $activityType->getLabel('attendee'), 'label' => $activityType->getLabel('attendee'),
'required' => $activityType->isRequired('attendee'), 'required' => $activityType->isRequired('attendee'),
@ -123,7 +126,7 @@ class ActivityType extends AbstractType
]); ]);
} }
if ($activityType->isVisible('user')) { if ($activityType->isVisible('user') && $options['center']) {
$builder->add('user', UserPickerType::class, [ $builder->add('user', UserPickerType::class, [
'label' => $activityType->getLabel('user'), 'label' => $activityType->getLabel('user'),
'required' => $activityType->isRequired('user'), 'required' => $activityType->isRequired('user'),
@ -229,6 +232,10 @@ class ActivityType extends AbstractType
} }
foreach (['durationTime', 'travelTime'] as $fieldName) { foreach (['durationTime', 'travelTime'] as $fieldName) {
if (!$activityType->isVisible($fieldName)) {
continue;
}
$builder->get($fieldName) $builder->get($fieldName)
->addModelTransformer($durationTimeTransformer); ->addModelTransformer($durationTimeTransformer);
@ -279,7 +286,7 @@ class ActivityType extends AbstractType
$resolver $resolver
->setRequired(['center', 'role', 'activityType']) ->setRequired(['center', 'role', 'activityType'])
->setAllowedTypes('center', 'Chill\MainBundle\Entity\Center') ->setAllowedTypes('center', ['null', 'Chill\MainBundle\Entity\Center'])
->setAllowedTypes('role', 'Symfony\Component\Security\Core\Role\Role') ->setAllowedTypes('role', 'Symfony\Component\Security\Core\Role\Role')
->setAllowedTypes('activityType', \Chill\ActivityBundle\Entity\ActivityType::class) ->setAllowedTypes('activityType', \Chill\ActivityBundle\Entity\ActivityType::class)
; ;

View File

@ -0,0 +1,48 @@
<?php
namespace Chill\ActivityBundle\Menu;
use Chill\ActivityBundle\Security\Authorization\ActivityVoter;
use Chill\MainBundle\Routing\LocalMenuBuilderInterface;
use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
use Chill\PersonBundle\Entity\AccompanyingPeriod;
use Knp\Menu\MenuItem;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
class AccompanyingCourseMenuBuilder implements LocalMenuBuilderInterface
{
protected TokenStorageInterface $tokenStorage;
protected AuthorizationHelper $authorizationHelper;
protected TranslatorInterface $translator;
public function __construct(
TokenStorageInterface $tokenStorage,
AuthorizationHelper $authorizationHelper,
TranslatorInterface $translator
) {
$this->translator = $translator;
$this->authorizationHelper = $authorizationHelper;
$this->tokenStorage = $tokenStorage;
}
public static function getMenuIds(): array
{
return ['accompanyingCourse'];
}
public function buildMenu($menuId, MenuItem $menu, array $parameters)
{
$period = $parameters['accompanyingCourse'];
$menu->addChild($this->translator->trans('Add a new activity'), [
'route' => 'chill_activity_activity_select_type',
'routeParameters' => [
'accompanying_period_id' => $period->getId()
]])
->setExtras(['order' => 40]);
}
}

View File

@ -0,0 +1,16 @@
{% extends "@ChillPerson/AccompanyingCourse/layout.html.twig" %}
{% set activeRouteKey = 'chill_activity_activity_list' %}
{% block title 'Remove activity'|trans %}
{% block content %}
{{ include('@ChillMain/Util/confirmation_template.html.twig',
{
'title' : 'Remove activity'|trans,
'confirm_question' : 'Are you sure you want to remove the activity about "%name%" ?'|trans({ '%name%' : accompanyingCourse.id } ),
'cancel_route' : 'chill_activity_activity_list',
'cancel_parameters' : { 'accompanying_course_id' : accompanyingCourse.id, 'id' : activity.id },
'form' : delete_form
} ) }}
{% endblock %}

View File

@ -6,7 +6,6 @@
{% block title 'Remove activity'|trans %} {% block title 'Remove activity'|trans %}
{% block personcontent %} {% block personcontent %}
{{ include('@ChillMain/Util/confirmation_template.html.twig', {{ include('@ChillMain/Util/confirmation_template.html.twig',
{ {
'title' : 'Remove activity'|trans, 'title' : 'Remove activity'|trans,
@ -15,5 +14,4 @@
'cancel_parameters' : { 'person_id' : activity.person.id, 'id' : activity.id }, 'cancel_parameters' : { 'person_id' : activity.person.id, 'id' : activity.id },
'form' : delete_form 'form' : delete_form
} ) }} } ) }}
{% endblock %} {% endblock %}

View File

@ -1,95 +1,75 @@
{# <h1>{{ "Update activity"|trans }}</h1>
* Copyright (C) 2014, Champs Libres Cooperative SCRLFS, <http://www.champs-libres.coop>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
#}
{% extends "@ChillPerson/layout.html.twig" %}
{% set activeRouteKey = 'chill_activity_activity_list' %} {{ form_start(edit_form) }}
{% block title 'Update activity'|trans %}
{% block personcontent %}
<h1>{{ "Update activity"|trans }}</h1>
{{ form_start(edit_form) }}
{%- if edit_form.user is defined -%}
{{ form_row(edit_form.user) }} {{ form_row(edit_form.user) }}
{% endif %}
{%- if edit_form.scope is defined -%}
{{ form_row(edit_form.scope) }} {{ form_row(edit_form.scope) }}
{% endif %}
<h2>{{ 'Activity data'|trans }}</h2> <h2>{{ 'Activity data'|trans }}</h2>
{%- if form.date is defined -%} {%- if form.date is defined -%}
{{ form_row(form.date) }} {{ form_row(form.date) }}
{% endif %} {% endif %}
{%- if form.durationTime is defined -%} {%- if form.durationTime is defined -%}
{{ form_row(form.durationTime) }} {{ form_row(form.durationTime) }}
{% endif %} {% endif %}
{%- if form.travelTime is defined -%} {%- if form.travelTime is defined -%}
{{ form_row(form.travelTime) }} {{ form_row(form.travelTime) }}
{% endif %} {% endif %}
{%- if form.attendee is defined -%} {%- if form.attendee is defined -%}
{{ form_row(form.attendee) }} {{ form_row(form.attendee) }}
{% endif %} {% endif %}
{%- if form.comment is defined -%} {%- if form.comment is defined -%}
{{ form_row(form.comment) }} {{ form_row(form.comment) }}
{% endif %} {% endif %}
{%- if form.reasons is defined -%} {%- if form.reasons is defined -%}
{{ form_row(form.reasons) }} {{ form_row(form.reasons) }}
{% endif %} {% endif %}
{%- if form.persons is defined -%} {%- if form.persons is defined -%}
{{ form_row(form.persons) }} {{ form_row(form.persons) }}
{% endif %} {% endif %}
{%- if form.thirdParties is defined -%} {%- if form.thirdParties is defined -%}
{{ form_row(form.thirdParties) }} {{ form_row(form.thirdParties) }}
{% endif %} {% endif %}
{%- if form.users is defined -%} {%- if form.users is defined -%}
{{ form_row(form.users) }} {{ form_row(form.users) }}
{% endif %} {% endif %}
{%- if form.emergency is defined -%} {%- if form.emergency is defined -%}
{{ form_row(form.emergency) }} {{ form_row(form.emergency) }}
{% endif %} {% endif %}
{%- if form.sentReceived is defined -%} {%- if form.sentReceived is defined -%}
{{ form_row(form.sentReceived) }} {{ form_row(form.sentReceived) }}
{% endif %} {% endif %}
{%- if form.documents is defined -%} {%- if form.documents is defined -%}
{{ form_row(form.documents) }} {{ form_row(form.documents) }}
{% endif %} {% endif %}
{{ form_widget(edit_form) }} {% set person_id = null %}
<ul class="record_actions sticky-form-buttons"> {% if entity.person %}
<li class="cancel"> {% set person_id = entity.person.id %}
<a href="{{ path('chill_activity_activity_show', { 'id': entity.id, 'person_id': entity.person.id } ) }}" class="sc-button bt-cancel"> {% endif %}
{{ 'Cancel'|trans }}
</a>
</li>
<li>
<button class="sc-button bt-update" type="submit">{{ 'Save activity'|trans }}</button>
</li>
</ul>
{{ form_end(edit_form) }}
{# {{ form(delete_form) }} #} {% set accompanying_course_id = null %}
{% endblock %} {% if accompanyingCourse %}
{% set accompanying_course_id = accompanyingCourse.id %}
{% endif %}
{% block js %} {{ form_widget(edit_form) }}
<script src="{{ asset('build/async_upload.js') }}" type="text/javascript"></script> <ul class="record_actions sticky-form-buttons">
<script type="text/javascript"> <li class="cancel">
chill.displayAlertWhenLeavingModifiedForm('form[name="{{ edit_form.vars.form.vars.name }}"]', '{{ "You are going to leave a page with unsubmitted data. Are you sure you want to leave ?"|trans }}'); <a href="{{ path('chill_activity_activity_show', { 'id': entity.id, 'person_id': person_id, 'accompanying_period_id': accompanying_course_id } ) }}" class="sc-button bt-cancel">
</script> {{ 'Cancel'|trans }}
{% endblock %} </a>
</li>
<li>
<button class="sc-button bt-update" type="submit">{{ 'Save activity'|trans }}</button>
</li>
</ul>
{{ form_end(edit_form) }}
{% block css %} {# {{ form(delete_form) }} #}
<link rel="stylesheet" href="{{ asset('build/async_upload.css') }}"/>
{% endblock %}

View File

@ -0,0 +1,20 @@
{% extends "@ChillPerson/AccompanyingCourse/layout.html.twig" %}
{% set activeRouteKey = 'chill_activity_activity_list' %}
{% block title 'Update activity'|trans %}
{% block content %}
{% include 'ChillActivityBundle:Activity:edit.html.twig' %}
{% endblock %}
{% block js %}
<script src="{{ asset('build/async_upload.js') }}" type="text/javascript"></script>
<script type="text/javascript">
chill.displayAlertWhenLeavingModifiedForm('form[name="{{ edit_form.vars.form.vars.name }}"]', '{{ "You are going to leave a page with unsubmitted data. Are you sure you want to leave ?"|trans }}');
</script>
{% endblock %}
{% block css %}
<link rel="stylesheet" href="{{ asset('build/async_upload.css') }}"/>
{% endblock %}

View File

@ -0,0 +1,36 @@
{#
* Copyright (C) 2014, Champs Libres Cooperative SCRLFS, <http://www.champs-libres.coop>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
#}
{% extends "@ChillPerson/layout.html.twig" %}
{% set activeRouteKey = 'chill_activity_activity_list' %}
{% block title 'Update activity'|trans %}
{% block personcontent %}
{% include 'ChillActivityBundle:Activity:edit.html.twig' %}
{% endblock %}
{% block js %}
<script src="{{ asset('build/async_upload.js') }}" type="text/javascript"></script>
<script type="text/javascript">
chill.displayAlertWhenLeavingModifiedForm('form[name="{{ edit_form.vars.form.vars.name }}"]', '{{ "You are going to leave a page with unsubmitted data. Are you sure you want to leave ?"|trans }}');
</script>
{% endblock %}
{% block css %}
<link rel="stylesheet" href="{{ asset('build/async_upload.css') }}"/>
{% endblock %}

View File

@ -1,87 +1,79 @@
{# {% set person_id = null %}
* Copyright (C) 2014, Champs Libres Cooperative SCRLFS, <http://www.champs-libres.coop> {% if person %}
* {% set person_id = person.id %}
* This program is free software: you can redistribute it and/or modify {% endif %}
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
#}
{% extends "@ChillPerson/layout.html.twig" %}
{% set activeRouteKey = 'chill_activity_activity_list' %} {% set accompanying_course_id = null %}
{% if accompanyingCourse %}
{% set accompanying_course_id = accompanyingCourse.id %}
{% endif %}
{% block title %}{{ 'Activity list' |trans }}{% endblock title %} <h2>{{ 'Activity list' |trans }}</h2>
{% block personcontent %} {% if activities|length == 0 %}
<h2>{{ 'Activity list' |trans }}</h2> <p class="chill-no-data-statement">
{{ "There isn't any activities."|trans }}
{% if activities|length == 0 %} <a href="{{ path('chill_activity_activity_new', {'person_id': person_id, 'accompanying_period_id': accompanying_course_id}) }}" class="sc-button bt-create button-small"></a>
<p class="chill-no-data-statement"> </p>
{{ "There isn't any activities."|trans }} {% else %}
<a href="{{ path('chill_activity_activity_new', {'person_id': person.id}) }}" class="sc-button bt-create button-small"></a> <table class="records_list">
</p> <thead>
{% else %} <tr>
<table class="records_list"> <th class="chill-red">{{'Date' | trans }}</th>
<thead> <th class="chill-green">{{'Duration Time' | trans }}</th>
<tr> <th class="chill-orange">{{'Reasons' | trans}}</th>
<th class="chill-red">{{'Date' | trans }}</th> <th>{{'Type' | trans}}</th>
<th class="chill-green">{{'Duration Time' | trans }}</th> <th>&nbsp;</th>
<th class="chill-orange">{{'Reasons' | trans}}</th> </tr>
<th>{{'Type' | trans}}</th> </thead>
<th>&nbsp;</th> <tbody>
</tr> {% for activity in activities %}
</thead> <tr>
<tbody> <td>{% if activity.date %}{{ activity.date|format_date('long') }}{% endif %}</td>
{% for activity in activities %} <td>{{ activity.durationTime|date('H:i') }}</td>
<tr> <td>
<td>{% if activity.date %}{{ activity.date|format_date('long') }}{% endif %}</td> {% if activity.comment.comment is not empty %}
<td>{{ activity.durationTime|date('H:i') }}</td> {{ activity.comment|chill_entity_render_box( { 'limit_lines': 3, 'metadata': false } ) }}
<td> {% endif %}
{% if activity.comment.comment is not empty %} {%- if activity.reasons is empty -%}
{{ activity.comment|chill_entity_render_box( { 'limit_lines': 3, 'metadata': false } ) }} {{ 'No reason associated'|trans }}
{%- else -%}
{% for r in activity.reasons %}{{ r|chill_entity_render_box }} {% endfor %}
{%- endif -%}
</td>
<td>{{ activity.type.name | localize_translatable_string }}</td>
<td>
<ul class="record_actions">
<li>
<a href="{{ path('chill_activity_activity_show', { 'id': activity.id, 'person_id': person_id, 'accompanying_period_id': accompanying_course_id }) }}" class="sc-button bt-show "></a>
</li>
{# TOOD
{% if is_granted('CHILL_ACTIVITY_UPDATE', activity) %}
#}
<li>
<a href="{{ path('chill_activity_activity_edit', { 'id': activity.id, 'person_id': person_id, 'accompanying_period_id': accompanying_course_id }) }}" class="sc-button bt-update "></a>
</li>
{# TOOD
{% endif %} {% endif %}
{%- if activity.reasons is empty -%} {% if is_granted('CHILL_ACTIVITY_DELETE', activity) %}
{{ 'No reason associated'|trans }} #}
{%- else -%} <li>
{% for r in activity.reasons %}{{ r|chill_entity_render_box }} {% endfor %} <a href="{{ path('chill_activity_activity_delete', { 'id': activity.id, 'person_id' : person_id, 'accompanying_period_id': accompanying_course_id } ) }}" class="sc-button bt-delete "></a>
{%- endif -%} </li>
</td> {#
<td>{{ activity.type.name | localize_translatable_string }}</td> {% endif %}
<td> #}
<ul class="record_actions"> </td>
<li> </tr>
<a href="{{ path('chill_activity_activity_show', { 'id': activity.id, 'person_id': person.id }) }}" class="sc-button bt-show "></a> {% endfor %}
</li> </tbody>
{% if is_granted('CHILL_ACTIVITY_UPDATE', activity) %} </table>
<li> {% endif %}
<a href="{{ path('chill_activity_activity_edit', { 'id': activity.id, 'person_id': person.id }) }}" class="sc-button bt-update "></a>
</li>
{% endif %}
{% if is_granted('CHILL_ACTIVITY_DELETE', activity) %}
<li>
<a href="{{ path('chill_activity_activity_delete', { 'id': activity.id, 'person_id' : person.id } ) }}" class="sc-button bt-delete "></a>
</li>
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endif %}
<ul class="record_actions"> <ul class="record_actions">
<li> <li>
<a href="{{ path('chill_activity_activity_new', {'person_id': person.id}) }}" class="sc-button bt-create"> <a href="{{ path('chill_activity_activity_new', {'person_id': person_id, 'accompanying_period_id': accompanying_course_id}) }}" class="sc-button bt-create">
{{ 'Add a new activity' | trans }} {{ 'Add a new activity' | trans }}
</a> </a>
</li> </li>
</ul> </ul>
{% endblock %}

View File

@ -0,0 +1,9 @@
{% extends "@ChillPerson/AccompanyingCourse/layout.html.twig" %}
{% set activeRouteKey = 'chill_activity_activity_list' %}
{% block title %}{{ 'Activity list' |trans }}{% endblock title %}
{% block content %}
{% include 'ChillActivityBundle:Activity:list.html.twig' %}
{% endblock %}

View File

@ -0,0 +1,25 @@
{#
* Copyright (C) 2014, Champs Libres Cooperative SCRLFS, <http://www.champs-libres.coop>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
#}
{% extends "@ChillPerson/layout.html.twig" %}
{% set activeRouteKey = 'chill_activity_activity_list' %}
{% block title %}{{ 'Activity list' |trans }}{% endblock title %}
{% block personcontent %}
{% include 'ChillActivityBundle:Activity:list.html.twig' %}
{% endblock %}

View File

@ -1,87 +1,57 @@
{# <h2 class="chill-red">{{ "Activity creation"|trans }}</h2>
* Copyright (C) 2014, Champs Libres Cooperative SCRLFS, <http://www.champs-libres.coop>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
#}
{% extends "@ChillPerson/layout.html.twig" %}
{% set activeRouteKey = 'chill_activity_activity_new' %} {{ form_start(form) }}
{{ form_errors(form) }}
{% block title 'Activity creation' |trans %}
{% block personcontent %}
<h2 class="chill-red">{{ "Activity creation"|trans }}</h2>
{{ form_start(form) }}
{{ form_errors(form) }}
{%- if form.user is defined -%}
{{ form_row(form.user) }} {{ form_row(form.user) }}
{% endif %}
{%- if form.scope is defined -%}
{{ form_row(form.scope) }} {{ form_row(form.scope) }}
{% endif %}
<h2 class="chill-red">{{ 'Activity data'|trans }}</h2> <h2 class="chill-red">{{ 'Activity data'|trans }}</h2>
{%- if form.date is defined -%} {%- if form.date is defined -%}
{{ form_row(form.date) }} {{ form_row(form.date) }}
{% endif %} {% endif %}
{%- if form.durationTime is defined -%} {%- if form.durationTime is defined -%}
{{ form_row(form.durationTime) }} {{ form_row(form.durationTime) }}
{% endif %} {% endif %}
{%- if form.travelTime is defined -%} {%- if form.travelTime is defined -%}
{{ form_row(form.travelTime) }} {{ form_row(form.travelTime) }}
{% endif %} {% endif %}
{%- if form.attendee is defined -%} {%- if form.attendee is defined -%}
{{ form_row(form.attendee) }} {{ form_row(form.attendee) }}
{% endif %} {% endif %}
{%- if form.comment is defined -%} {%- if form.comment is defined -%}
{{ form_row(form.comment) }} {{ form_row(form.comment) }}
{% endif %} {% endif %}
{%- if form.reasons is defined -%} {%- if form.reasons is defined -%}
{{ form_row(form.reasons) }} {{ form_row(form.reasons) }}
{% endif %} {% endif %}
{%- if form.persons is defined -%} {%- if form.persons is defined -%}
{{ form_row(form.persons) }} {{ form_row(form.persons) }}
{% endif %} {% endif %}
{%- if form.thirdParties is defined -%} {%- if form.thirdParties is defined -%}
{{ form_row(form.thirdParties) }} {{ form_row(form.thirdParties) }}
{% endif %} {% endif %}
{%- if form.users is defined -%} {%- if form.users is defined -%}
{{ form_row(form.users) }} {{ form_row(form.users) }}
{% endif %} {% endif %}
{%- if form.emergency is defined -%} {%- if form.emergency is defined -%}
{{ form_row(form.emergency) }} {{ form_row(form.emergency) }}
{% endif %} {% endif %}
{%- if form.sentReceived is defined -%} {%- if form.sentReceived is defined -%}
{{ form_row(form.sentReceived) }} {{ form_row(form.sentReceived) }}
{% endif %} {% endif %}
{%- if form.documents is defined -%} {%- if form.documents is defined -%}
{{ form_row(form.documents) }} {{ form_row(form.documents) }}
{% endif %} {% endif %}
<div class="grid-12 centered sticky-form-buttons"> <div class="grid-12 centered sticky-form-buttons">
<button class="sc-button green margin-10" type="submit"><i class="fa fa-save"></i> {{ 'Add a new activity'|trans }}</button> <button class="sc-button green margin-10" type="submit"><i class="fa fa-save"></i> {{ 'Add a new activity'|trans }}</button>
</div> </div>
{{ form_end(form) }} {{ form_end(form) }}
{% endblock %}
{% block js %}
<script src="{{ asset('build/async_upload.js') }}" type="text/javascript"></script>
<script type="text/javascript">
chill.displayAlertWhenLeavingUnsubmittedForm('form[name="{{ form.vars.form.vars.name }}"]', '{{ "You are going to leave a page with unsubmitted data. Are you sure you want to leave ?"|trans }}');
</script>
{% endblock %}
{% block css %}
<link rel="stylesheet" href="{{ asset('build/async_upload.css') }}"/>
{% endblock %}

View File

@ -0,0 +1,20 @@
{% extends "@ChillPerson/AccompanyingCourse/layout.html.twig" %}
{% set activeRouteKey = 'chill_activity_activity_new' %}
{% block title 'Activity creation' |trans %}
{% block content %}
{% include 'ChillActivityBundle:Activity:new.html.twig' %}
{% endblock %}
{% block js %}
<script src="{{ asset('build/async_upload.js') }}" type="text/javascript"></script>
<script type="text/javascript">
chill.displayAlertWhenLeavingUnsubmittedForm('form[name="{{ form.vars.form.vars.name }}"]', '{{ "You are going to leave a page with unsubmitted data. Are you sure you want to leave ?"|trans }}');
</script>
{% endblock %}
{% block css %}
<link rel="stylesheet" href="{{ asset('build/async_upload.css') }}"/>
{% endblock %}

View File

@ -0,0 +1,20 @@
{% extends "@ChillPerson/layout.html.twig" %}
{% set activeRouteKey = 'chill_activity_activity_new' %}
{% block title 'Activity creation' |trans %}
{% block personcontent %}
{% include 'ChillActivityBundle:Activity:new.html.twig' %}
{% endblock %}
{% block js %}
<script src="{{ asset('build/async_upload.js') }}" type="text/javascript"></script>
<script type="text/javascript">
chill.displayAlertWhenLeavingUnsubmittedForm('form[name="{{ form.vars.form.vars.name }}"]', '{{ "You are going to leave a page with unsubmitted data. Are you sure you want to leave ?"|trans }}');
</script>
{% endblock %}
{% block css %}
<link rel="stylesheet" href="{{ asset('build/async_upload.css') }}"/>
{% endblock %}

View File

@ -1,24 +1,28 @@
{% extends "@ChillPerson/layout.html.twig" %} <h2 class="chill-red">{{ "Activity creation"|trans }}</h2>
{% set activeRouteKey = 'chill_activity_activity_new' %} {# TODO: refaire l'html css des tuilles #}
{% block title 'Activity creation'|trans %} {% for row in data %}
<h3>{{ row.activityTypeCategory.name|localize_translatable_string }}</h3>
<div style="display:flex;justify-content:center;gap:12px;flex-wrap:wrap;">
{% for activityType in row.activityTypes %}
{% block personcontent %} {% set person_id = null %}
<h2 class="chill-red">{{ "Activity creation"|trans }}</h2> {% if person %}
{% set person_id = person.id %}
{% endif %}
{# TODO: refaire l'html css des tuilles #} {% set accompanying_course_id = null %}
{% if accompanyingCourse %}
{% set accompanying_course_id = accompanyingCourse.id %}
{% endif %}
{% for row in data %} <a href="{{ path('chill_activity_activity_new', {'person_id': person_id, 'activityType_id': activityType.id, 'accompanying_period_id': accompanying_course_id }) }}">
<h3>{{ row.activityTypeCategory.name|localize_translatable_string }}</h3>
<div style="display:flex;justify-content:center;gap:12px;flex-wrap:wrap;"> <div style="width:200px;height:200px;border:1px dotted red;display:flex;justify-content:center;align-items:center;align-content:center;">
{% for activityType in row.activityTypes %} {{ activityType.name|localize_translatable_string }}
<a href="{{ path('chill_activity_activity_new', {'person_id': person.id, 'activityType_id': activityType.id }) }}"> </div>
<div style="width:200px;height:200px;border:1px dotted red;display:flex;justify-content:center;align-items:center;align-content:center;"> </a>
{{ activityType.name|localize_translatable_string }} {% endfor %}
</div> </div>
</a> {% endfor %}
{% endfor %}
</div>
{% endfor %}
{% endblock %}

View File

@ -0,0 +1,9 @@
{% extends "@ChillPerson/AccompanyingCourse/layout.html.twig" %}
{% set activeRouteKey = 'chill_activity_activity_new' %}
{% block title 'Activity creation'|trans %}
{% block content %}
{% include 'ChillActivityBundle:Activity:selectType.html.twig' %}
{% endblock %}

View File

@ -0,0 +1,9 @@
{% extends "@ChillPerson/layout.html.twig" %}
{% set activeRouteKey = 'chill_activity_activity_new' %}
{% block title 'Activity creation'|trans %}
{% block personcontent %}
{% include 'ChillActivityBundle:Activity:selectType.html.twig' %}
{% endblock %}

View File

@ -1,68 +1,77 @@
{% extends "@ChillPerson/layout.html.twig" %} <h1 >{{ "Activity"|trans }}</h1>
{% set activeRouteKey = 'chill_activity_activity_list' %} <dl class="chill_view_data">
<dt class="inline">{{ 'User'|trans }}</dt>
<dd>{{ entity.user }}</dd>
{% block title 'Activity'|trans %} {%- if entity.scope -%}
{% import 'ChillActivityBundle:ActivityReason:macro.html.twig' as m %}
{% block personcontent -%}
<h1 >{{ "Activity"|trans }}</h1>
<dl class="chill_view_data">
<dt class="inline">{{ 'User'|trans }}</dt>
<dd>{{ entity.user }}</dd>
<dt class="inline">{{ 'Scope'|trans }}</dt> <dt class="inline">{{ 'Scope'|trans }}</dt>
<dd><span class="scope">{{ entity.scope.name|localize_translatable_string }}</span></dd> <dd><span class="scope">{{ entity.scope.name|localize_translatable_string }}</span></dd>
{% endif %}
<h2 class="chill-red">{{ 'Activity data'|trans }}</h2> <h2 class="chill-red">{{ 'Activity data'|trans }}</h2>
{%- if entity.person is defined -%}
<dt class="inline">{{ 'Person'|trans }}</dt> <dt class="inline">{{ 'Person'|trans }}</dt>
<dd>{{ entity.person }}</dd> <dd>{{ entity.person }}</dd>
{% endif %}
<dt class="inline">{{ 'Date'|trans }}</dt> <dt class="inline">{{ 'Date'|trans }}</dt>
<dd>{{ entity.date|format_date('long') }}</dd> <dd>{{ entity.date|format_date('long') }}</dd>
<dt class="inline">{{ 'Duration Time'|trans }}</dt> <dt class="inline">{{ 'Duration Time'|trans }}</dt>
<dd>{{ entity.durationTime|date('H:i') }}</dd> <dd>{{ entity.durationTime|date('H:i') }}</dd>
<dt class="inline">{{ 'Type'|trans }}</dt> <dt class="inline">{{ 'Type'|trans }}</dt>
<dd>{{ entity.type.name | localize_translatable_string }}</dd> <dd>{{ entity.type.name | localize_translatable_string }}</dd>
<dt class="inline">{{ 'Attendee'|trans }}</dt> <dt class="inline">{{ 'Attendee'|trans }}</dt>
<dd>{% if entity.attendee is not null %}{% if entity.attendee %}{{ 'present'|trans|capitalize }} {% else %} {{ 'not present'|trans|capitalize }}{% endif %}{% else %}{{ 'None'|trans|capitalize }}{% endif %}</dd> <dd>{% if entity.attendee is not null %}{% if entity.attendee %}{{ 'present'|trans|capitalize }} {% else %} {{ 'not present'|trans|capitalize }}{% endif %}{% else %}{{ 'None'|trans|capitalize }}{% endif %}</dd>
<dt class="inline">{{ 'Reasons'|trans }}</dt> <dt class="inline">{{ 'Reasons'|trans }}</dt>
{%- if entity.reasons is empty -%} {%- if entity.reasons is empty -%}
<dd><span class="chill-no-data-statement">{{ 'No reason associated'|trans }}</span></dd> <dd><span class="chill-no-data-statement">{{ 'No reason associated'|trans }}</span></dd>
{%- else -%} {%- else -%}
<dd>{% for r in entity.reasons %}{{ r|chill_entity_render_box }} {% endfor %}</dd> <dd>{% for r in entity.reasons %}{{ r|chill_entity_render_box }} {% endfor %}</dd>
{%- endif -%} {%- endif -%}
<dt class="inline">{{ 'Comment'|trans }}</dt> <dt class="inline">{{ 'Comment'|trans }}</dt>
{%- if entity.comment is empty -%} {%- if entity.comment is empty -%}
<dd><span class="chill-no-data-statement">{{ 'No comment associated'|trans }}</span></dd> <dd><span class="chill-no-data-statement">{{ 'No comment associated'|trans }}</span></dd>
{%- else -%} {%- else -%}
<dd>{{ entity.comment|chill_entity_render_box }}</dd> <dd>{{ entity.comment|chill_entity_render_box }}</dd>
{%- endif -%} {%- endif -%}
</dl> </dl>
<ul class="record_actions"> {% set person_id = null %}
<li class="cancel"> {% if person %}
<a class="sc-button bt-cancel" href="{{ path('chill_activity_activity_list', { 'person_id': person.id } ) }}"> {% set person_id = person.id %}
{{ 'Back to the list'|trans }} {% endif %}
</a>
</li> {% set accompanying_course_id = null %}
<li> {% if accompanyingCourse %}
<a class="sc-button bt-update" href="{{ path('chill_activity_activity_edit', { 'id': entity.id, 'person_id': person.id }) }}"> {% set accompanying_course_id = accompanyingCourse.id %}
{{ 'Edit the activity'|trans }} {% endif %}
<ul class="record_actions">
<li class="cancel">
<a class="sc-button bt-cancel" href="{{ path('chill_activity_activity_list', { 'person_id': person_id, 'accompanying_period_id': accompanying_course_id } ) }}">
{{ 'Back to the list'|trans }}
</a> </a>
</li> </li>
{% if is_granted('CHILL_ACTIVITY_DELETE', entity) %} <li>
<li> <a class="sc-button bt-update" href="{{ path('chill_activity_activity_edit', { 'id': entity.id, 'person_id': person_id, 'accompanying_period_id': accompanying_course_id }) }}">
<a href="{{ path('chill_activity_activity_delete', { 'id': entity.id, 'person_id' : person.id } ) }}" class="sc-button bt-delete"> {{ 'Edit the activity'|trans }}
{{ 'Delete'|trans }} </a>
</a> </li>
</li> {# TODO
{% endif %} {% if is_granted('CHILL_ACTIVITY_DELETE', entity) %}
</ul> #}
<li>
{% endblock personcontent %} <a href="{{ path('chill_activity_activity_delete', { 'id': entity.id, 'person_id' : person_id, 'accompanying_period_id': accompanying_course_id } ) }}" class="sc-button bt-delete">
{{ 'Delete'|trans }}
</a>
</li>
{#
{% endif %}
#}
</ul>

View File

@ -0,0 +1,11 @@
{% extends "@ChillPerson/AccompanyingCourse/layout.html.twig" %}
{% set activeRouteKey = 'chill_activity_activity_list' %}
{% block title 'Activity'|trans %}
{% import 'ChillActivityBundle:ActivityReason:macro.html.twig' as m %}
{% block content -%}
{% include 'ChillActivityBundle:Activity:show.html.twig' %}
{% endblock content %}

View File

@ -0,0 +1,11 @@
{% extends "@ChillPerson/layout.html.twig" %}
{% set activeRouteKey = 'chill_activity_activity_list' %}
{% block title 'Activity'|trans %}
{% import 'ChillActivityBundle:ActivityReason:macro.html.twig' as m %}
{% block personcontent -%}
{% include 'ChillActivityBundle:Activity:show.html.twig' %}
{% endblock personcontent %}

View File

@ -1,26 +1,26 @@
chill_activity_activity_list: chill_activity_activity_list:
path: /{_locale}/person/{person_id}/activity/ path: /{_locale}/activity/
controller: Chill\ActivityBundle\Controller\ActivityController::listAction controller: Chill\ActivityBundle\Controller\ActivityController::listAction
chill_activity_activity_show: chill_activity_activity_show:
path: /{_locale}/person/{person_id}/activity/{id}/show path: /{_locale}/activity/{id}/show
controller: Chill\ActivityBundle\Controller\ActivityController::showAction controller: Chill\ActivityBundle\Controller\ActivityController::showAction
chill_activity_activity_select_type: chill_activity_activity_select_type:
path: /{_locale}/person/{person_id}/activity/select-type path: /{_locale}/activity/select-type
controller: Chill\ActivityBundle\Controller\ActivityController::selectTypeAction controller: Chill\ActivityBundle\Controller\ActivityController::selectTypeAction
chill_activity_activity_new: chill_activity_activity_new:
path: /{_locale}/person/{person_id}/activity/new path: /{_locale}/activity/new
controller: Chill\ActivityBundle\Controller\ActivityController::newAction controller: Chill\ActivityBundle\Controller\ActivityController::newAction
methods: [POST, GET] methods: [POST, GET]
chill_activity_activity_edit: chill_activity_activity_edit:
path: /{_locale}/person/{person_id}/activity/{id}/edit path: /{_locale}/activity/{id}/edit
controller: Chill\ActivityBundle\Controller\ActivityController::editAction controller: Chill\ActivityBundle\Controller\ActivityController::editAction
methods: [GET, POST, PUT] methods: [GET, POST, PUT]
chill_activity_activity_delete: chill_activity_activity_delete:
path: /{_locale}/person/{person_id}/activity/{id}/delete path: /{_locale}/activity/{id}/delete
controller: Chill\ActivityBundle\Controller\ActivityController::deleteAction controller: Chill\ActivityBundle\Controller\ActivityController::deleteAction
methods: [GET, POST, DELETE] methods: [GET, POST, DELETE]

View File

@ -6,3 +6,11 @@ services:
$translator: '@Symfony\Component\Translation\TranslatorInterface' $translator: '@Symfony\Component\Translation\TranslatorInterface'
tags: tags:
- { name: 'chill.menu_builder' } - { name: 'chill.menu_builder' }
Chill\ActivityBundle\Menu\AccompanyingCourseMenuBuilder:
arguments:
$tokenStorage: '@Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface'
$authorizationHelper: '@Chill\MainBundle\Security\Authorization\AuthorizationHelper'
$translator: '@Symfony\Contracts\Translation\TranslatorInterface'
tags:
- { name: 'chill.menu_builder' }

View File

@ -0,0 +1,31 @@
<?php
declare(strict_types=1);
namespace Chill\Migrations\Activity;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20210520095626 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
$this->addSql('ALTER TABLE activity ADD accompanyingPeriod_id INT DEFAULT NULL');
$this->addSql('ALTER TABLE activity ADD CONSTRAINT FK_AC74095AD7FA8EF0 FOREIGN KEY (accompanyingPeriod_id) REFERENCES chill_person_accompanying_period (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
}
public function down(Schema $schema): void
{
$this->addSql('ALTER TABLE activity DROP CONSTRAINT FK_AC74095AD7FA8EF0');
$this->addSql('ALTER TABLE activity DROP accompanyingPeriod_id');
}
}