diff --git a/src/Bundle/ChillPersonBundle/Controller/HouseholdMemberController.php b/src/Bundle/ChillPersonBundle/Controller/HouseholdMemberController.php index c6fd4dd59..e55fb3e9f 100644 --- a/src/Bundle/ChillPersonBundle/Controller/HouseholdMemberController.php +++ b/src/Bundle/ChillPersonBundle/Controller/HouseholdMemberController.php @@ -2,6 +2,9 @@ namespace Chill\PersonBundle\Controller; +use Chill\PersonBundle\Entity\Household\Position; +use Chill\PersonBundle\Security\Authorization\PersonVoter; +use Chill\PersonBundle\Entity\Person; use Symfony\Component\HttpFoundation\Exception\BadRequestException; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; @@ -15,7 +18,7 @@ class HouseholdMemberController extends ApiController /** * @Route( * "/api/1.0/person/household/members/move.{_format}", - * name="chill_person_household_members_move" + * name="chill_api_person_household_members_move" * ) */ public function move(Request $request, $_format): Response @@ -27,7 +30,6 @@ class HouseholdMemberController extends ApiController } catch (Exception\InvalidArgumentException | Exception\UnexpectedValueException $e) { throw new BadRequestException("Deserialization error: {$e->getMessage()}", 45896, $e); } - dump($editor); // TODO ACL // // TODO validation @@ -44,7 +46,52 @@ class HouseholdMemberController extends ApiController $em->flush(); $em->commit(); - return $this->json($editor->getHousehold(), Response::HTTP_OK, ["groups" => ["read"]]); } + + /** + * @Route( + * "/{_locale}/person/household/members/editor", + * name="chill_person_household_members_editor" + * ) + */ + public function editor(Request $request) + { + if ($request->query->has('persons')) { + $ids = $request->query->get('persons', []); + + if (0 === count($ids)) { + throw new BadRequestExceptions("parameters persons in query ". + "is not an array or empty"); + } + + $persons = $this->getDoctrine()->getManager() + ->getRepository(Person::class) + ->findById($ids) + ; + + foreach ($persons as $person) { + $this->denyAccessUnlessGranted(PersonVoter::SEE, $person, + "You are not allowed to see person with id {$person->getId()}" + ); + } + } + + $positions = $this->getDoctrine()->getManager() + ->getRepository(Position::class) + ->findAll() + ; + + $data = [ + 'persons' => $persons ?? false ? + $this->getSerializer()->normalize($persons, 'json', [ 'groups' => [ 'read' ]]): [], + 'household' => null, + 'positions' => + $this->getSerializer()->normalize($positions, 'json', [ 'groups' => [ 'read' ]]) + ]; + + return $this->render('@ChillPerson/Household/members_editor.html.twig', [ + 'data' => $data + ]); + } } diff --git a/src/Bundle/ChillPersonBundle/Entity/Household/Position.php b/src/Bundle/ChillPersonBundle/Entity/Household/Position.php index 156631b63..db8e32134 100644 --- a/src/Bundle/ChillPersonBundle/Entity/Household/Position.php +++ b/src/Bundle/ChillPersonBundle/Entity/Household/Position.php @@ -7,7 +7,7 @@ use Doctrine\ORM\Mapping as ORM; use Symfony\Component\Serializer\Annotation as Serializer; /** - * @ORM\Entity(repositoryClass=PositionRepository::class) + * @ORM\Entity * @ORM\Table(name="chill_person_household_position") * @Serializer\DiscriminatorMap(typeProperty="type", mapping={ * "household_position"=Position::class @@ -25,21 +25,25 @@ class Position /** * @ORM\Column(type="json") + * @Serializer\Groups({ "read" }) */ private $label = []; /** * @ORM\Column(type="boolean") + * @Serializer\Groups({ "read" }) */ private $shareHouseHold; /** * @ORM\Column(type="boolean") + * @Serializer\Groups({ "read" }) */ private $allowHolder; /** * @ORM\Column(type="float") + * @Serializer\Groups({ "read" }) */ private $ordering; diff --git a/src/Bundle/ChillPersonBundle/Repository/Household/PositionRepository.php b/src/Bundle/ChillPersonBundle/Repository/Household/PositionRepository.php index 6d07f791e..a02de20dd 100644 --- a/src/Bundle/ChillPersonBundle/Repository/Household/PositionRepository.php +++ b/src/Bundle/ChillPersonBundle/Repository/Household/PositionRepository.php @@ -3,8 +3,10 @@ namespace Chill\PersonBundle\Repository\Household; use Chill\PersonBundle\Entity\Household\Position; -use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; -use Doctrine\Persistence\ManagerRegistry; +//use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; +//use Doctrine\Persistence\ManagerRegistry; +use Doctrine\ORM\EntityManagerInterface; +use Doctrine\ORM\EntityRepository; /** * @method Position|null find($id, $lockMode = null, $lockVersion = null) @@ -12,11 +14,20 @@ use Doctrine\Persistence\ManagerRegistry; * @method Position[] findAll() * @method Position[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null) */ -class PositionRepository extends ServiceEntityRepository +final class PositionRepository { - public function __construct(ManagerRegistry $registry) + private EntityRepository $repository; + + public function __construct(EntityManagerInterface $entityManager) { - parent::__construct($registry, Position::class); + $this->repository = $entityManager->getRepository(Position::class); } + /** + * @return Position[] + */ + public function findAll(): array + { + return $this->repository->findAll(); + } } diff --git a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/HouseholdMembersEditor/App.vue b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/HouseholdMembersEditor/App.vue new file mode 100644 index 000000000..a658a06db --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/HouseholdMembersEditor/App.vue @@ -0,0 +1,23 @@ + + + diff --git a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/HouseholdMembersEditor/components/Concerned.vue b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/HouseholdMembersEditor/components/Concerned.vue new file mode 100644 index 000000000..05e999350 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/HouseholdMembersEditor/components/Concerned.vue @@ -0,0 +1,118 @@ + + + + + diff --git a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/HouseholdMembersEditor/index.js b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/HouseholdMembersEditor/index.js new file mode 100644 index 000000000..c9f5bb111 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/HouseholdMembersEditor/index.js @@ -0,0 +1,16 @@ +import { createApp } from 'vue'; +import { _createI18n } from 'ChillMainAssets/vuejs/_js/i18n'; +import { appMessages } from './js/i18n'; +import { store } from './store'; + +import App from './App.vue'; + +const i18n = _createI18n(appMessages); + +const app = createApp({ + template: ``, +}) +.use(store) +.use(i18n) +.component('app', App) +.mount('#household_members_editor'); diff --git a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/HouseholdMembersEditor/js/i18n.js b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/HouseholdMembersEditor/js/i18n.js new file mode 100644 index 000000000..d297ba1d7 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/HouseholdMembersEditor/js/i18n.js @@ -0,0 +1,20 @@ + +import { personMessages } from 'ChillPersonAssets/vuejs/_js/i18n' + +const appMessages = { + fr: { + household_members_editor: { + concerned: { + title: "Personnes concernées", + add_persons: "Ajouter d'autres usagers", + search: "Rechercher des usagers", + } + } + } +}; + +Object.assign(appMessages.fr, personMessages.fr); + +export { + appMessages +}; diff --git a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/HouseholdMembersEditor/store/index.js b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/HouseholdMembersEditor/store/index.js new file mode 100644 index 000000000..257a46e57 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/HouseholdMembersEditor/store/index.js @@ -0,0 +1,74 @@ +import { createStore } from 'vuex'; + +const debug = process.env.NODE_ENV !== 'production'; + +const concerned = window.household_members_editor_data.persons.map(p => { + return { + person: p, + position: null, + start_date: null + }; +}); + +const store = createStore({ + strict: debug, + state: { + concerned, + household: window.household_members_editor_data.household, + positions: window.household_members_editor_data.positions, + }, + getters: { + persons(state) { + return state.concerned.map(conc => conc.person); + }, + personsUnpositionned(state) { + return state.concerned + .filter(conc => conc.position === null) + .map(conc => conc.person) + ; + }, + personByPosition: (state) => (position_id) => { + return state.concerned + .filter(conc => + conc.position !== null ? conc.position.id === position_id : false + ) + .map(conc => conc.person) + ; + }, + positions(state) { + return state.positions; + } + }, + mutations: { + addConcerned(state, person) { + console.log('from mutation addConcerned'); + state.concerned.push({ person, position: null, start_date: null }); + }, + markPosition(state, { person_id, position_id}) { + console.log('from mutation markPosition'); + console.log('person_id', person_id); + console.log('position_id', position_id); + console.log('state', state.concerned); + let + position = state.positions.find(pos => pos.id === position_id), + conc = state.concerned.find(c => c.person.id === person_id); + console.log(position); + console.log(conc); + conc.position = position; + } + }, + actions: { + addConcerned({ commit }, person) { + console.log('from actions addConcerned'); + commit('addConcerned', person); + }, + markPosition({ commit, state }, { person_id, position_id }) { + console.log('from action markPosition'); + console.log('person_id', person_id); + console.log('position_id', position_id); + commit('markPosition', { person_id, position_id }); + } + } +}); + +export { store }; diff --git a/src/Bundle/ChillPersonBundle/Resources/views/Household/members_editor.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/Household/members_editor.html.twig new file mode 100644 index 000000000..f0433a812 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Resources/views/Household/members_editor.html.twig @@ -0,0 +1,17 @@ +{% extends '@ChillMain/layout.html.twig' %} + +{% block content %} +

Editor

+
+{% endblock %} + +{% block js %} + + {{ encore_entry_script_tags('household_members_editor') }} +{% endblock %} + +{% block css %} + {{ encore_entry_link_tags('household_members_editor') }} +{% endblock %} diff --git a/src/Bundle/ChillPersonBundle/chill.webpack.config.js b/src/Bundle/ChillPersonBundle/chill.webpack.config.js index 53aed5d91..60ca5501a 100644 --- a/src/Bundle/ChillPersonBundle/chill.webpack.config.js +++ b/src/Bundle/ChillPersonBundle/chill.webpack.config.js @@ -9,4 +9,5 @@ module.exports = function(encore, entries) }); encore.addEntry('accompanying_course', __dirname + '/Resources/public/vuejs/AccompanyingCourse/index.js'); + encore.addEntry('household_members_editor', __dirname + '/Resources/public/vuejs/HouseholdMembersEditor/index.js'); };