From fb65bcadfd4c628de65282da515dd360d006b1ea Mon Sep 17 00:00:00 2001 From: Camille Simiand <camille.simiand@tetras-libre.fr> Date: Mon, 21 Feb 2022 12:07:02 +0100 Subject: [PATCH] Have a better UI - Split group creation --- assets/styles/app.scss | 5 +- src/Controller/CapsuleGroupController.php | 139 ++++++++++++------ src/Form/DeleteGroupFormType.php | 37 +++++ ...dit.html.twig => capsule_groups.html.twig} | 18 +-- templates/capsule/groups/create.html.twig | 2 +- templates/capsule/groups/delete.html.twig | 34 +++++ .../capsule/groups/user_groups.html.twig | 66 +++++++++ templates/layout.html.twig | 9 +- .../functional/CapsuleGroupControllerTest.php | 17 +-- translations/messages.en.yaml | 10 +- translations/messages.fr.yaml | 8 + 11 files changed, 270 insertions(+), 75 deletions(-) create mode 100644 src/Form/DeleteGroupFormType.php rename templates/capsule/groups/{edit.html.twig => capsule_groups.html.twig} (78%) create mode 100644 templates/capsule/groups/delete.html.twig create mode 100644 templates/capsule/groups/user_groups.html.twig diff --git a/assets/styles/app.scss b/assets/styles/app.scss index cf68905..764d94d 100644 --- a/assets/styles/app.scss +++ b/assets/styles/app.scss @@ -95,16 +95,15 @@ button[type=submit]{ .standard-button { line-height: 40px; - margin: 30px 0 0 0; padding: 0.5em 2em; - font-size: 14px; - text-transform: uppercase; + font-size: 16px; font-weight: bold; border: none; color: #FFF !important; border-radius: 3px; background: #49AD9A; box-shadow: 0 -2px 0 #3B8C7E inset; + flex-basis: auto; } .standard-button:hover { diff --git a/src/Controller/CapsuleGroupController.php b/src/Controller/CapsuleGroupController.php index d488c5d..6c672ae 100755 --- a/src/Controller/CapsuleGroupController.php +++ b/src/Controller/CapsuleGroupController.php @@ -6,6 +6,7 @@ use App\Entity\Capsule; use App\Entity\Group; use App\Entity\User; use App\Form\CreateCapsuleGroupsFormType; +use App\Form\DeleteGroupFormType; use App\Form\RemoveGroupFormType; use App\Form\SelectCapsuleGroupsFormType; use App\Repository\CapsuleRepository; @@ -38,9 +39,9 @@ class CapsuleGroupController extends AbstractController } /** - * @Route("/capsule/{capsule_id}/groups/edit", name="edit_capsule_groups") + * @Route("/my_groups", name="edit_user_groups") */ - public function edit(int $capsule_id, Request $request): Response + public function editUserGroups(): Response { $current_user = $this->getUser(); @@ -48,58 +49,105 @@ class CapsuleGroupController extends AbstractController return $this->redirectToRoute('app_logout'); } - $capsule = $this->capsule_repository->findOneBy(['id' => $capsule_id]); + $groups = $current_user->getGroups()->toArray(); - if (! $capsule instanceof Capsule) { - throw new \Exception("Capsule does not exist"); + return $this->render('capsule/groups/user_groups.html.twig', [ + 'groups' => $groups + ]); + } + + /** + * @Route("my_groups/create", name="create_group") + */ + public function create(Request $request): Response + { + $current_user = $this->getUser(); + + if (! $current_user instanceof User) { + return $this->redirectToRoute('app_logout'); } - $capsule_groups_by_author = $current_user->getGroupsByCapsule($capsule); - $author_capsule_groups_not_added = $capsule->getNotAddedGroupsByAuthor($current_user); + $group = new Group(); + $group->setAuthor($current_user); - $form = $this->createForm( - SelectCapsuleGroupsFormType::class, - ['groups' => $author_capsule_groups_not_added] - ); + $form = $this->createForm(CreateCapsuleGroupsFormType::class, $group); $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { - $capsule_groups = $this->addGroups($form, $capsule); + $group = $this->createAGroup($form, $group); - $groups_names = []; + $this->addFlash( + 'success', + $this->translator->trans( + 'groups.create.success', + [ + 'group_name' => $group->getName() + ] + ) + ); - foreach ($capsule_groups as $group) { - $groups_names[] = $group->getName(); + return $this->redirectToRoute('edit_user_groups'); + } + + return $this->render('capsule/groups/create.html.twig', [ + 'createCapsuleGroupsForm' => $form->createView() + ]); + } + + /** + * @Route("/my_groups/{group_id}/delete", name="delete_group") + */ + public function deleteGroup(int $group_id, Request $request): Response + { + $current_user = $this->getUser(); + if (! $current_user instanceof User) { + return $this->redirectToRoute('app_logout'); + } + + $group = $this->group_repository->findOneBy(['id' => $group_id]); + if (! $group instanceof Group) { + throw new \Exception('Group not found'); + } + + $form = $this->createForm(DeleteGroupFormType::class); + $form->handleRequest($request); + + if ($form->isSubmitted() && $form->isValid()) { + $capsules = $group->getCapsules()->toArray(); + foreach ($capsules as $capsule) { + $capsule->removeGroup($group); + $this->entity_manager->persist($capsule); } + $current_user->removeGroup($group); + $this->entity_manager->persist($current_user); + + $this->entity_manager->remove($group); + $this->entity_manager->flush(); + $this->addFlash( 'success', $this->translator->trans( - 'groups.add.success', + 'groups.general.delete.success', [ - 'groups_names' => implode(",", $groups_names), - 'capsule_name' => $capsule->getName() + 'group_name' => $group->getName() ] ) ); - return $this->redirectToRoute('edit_capsule_groups', [ - 'capsule_id' => $capsule_id - ]); + return $this->redirectToRoute('edit_user_groups'); } - return $this->render('capsule/groups/edit.html.twig', [ - 'selectCapsuleGroupsForm' => $form->createView(), - 'capsule' => $capsule, - 'groups' => $capsule_groups_by_author, - 'groups_not_added' => $author_capsule_groups_not_added + return $this->render('capsule/groups/delete.html.twig', [ + 'deleteGroupForm' => $form->createView(), + 'group_name' => $group->getName() ]); } /** - * @Route("capsule/{capsule_id}/groups/create", name="create_group") + * @Route("/capsule/{capsule_id}/groups/edit", name="edit_capsule_groups") */ - public function create(int $capsule_id, Request $request): Response + public function edit(int $capsule_id, Request $request): Response { $current_user = $this->getUser(); @@ -113,21 +161,31 @@ class CapsuleGroupController extends AbstractController throw new \Exception("Capsule does not exist"); } - $group = new Group(); - $group->setAuthor($current_user); + $capsule_groups_by_author = $current_user->getGroupsByCapsule($capsule); + $author_capsule_groups_not_added = $capsule->getNotAddedGroupsByAuthor($current_user); - $form = $this->createForm(CreateCapsuleGroupsFormType::class, $group); + $form = $this->createForm( + SelectCapsuleGroupsFormType::class, + ['groups' => $author_capsule_groups_not_added] + ); $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { - $group = $this->createAGroup($form, $capsule, $group); + $capsule_groups = $this->addGroups($form, $capsule); + + $groups_names = []; + + foreach ($capsule_groups as $group) { + $groups_names[] = $group->getName(); + } $this->addFlash( 'success', $this->translator->trans( - 'groups.create.success', + 'groups.add.success', [ - 'group_name' => $group->getName() + 'groups_names' => implode(",", $groups_names), + 'capsule_name' => $capsule->getName() ] ) ); @@ -137,9 +195,11 @@ class CapsuleGroupController extends AbstractController ]); } - return $this->render('capsule/groups/create.html.twig', [ - 'createCapsuleGroupsForm' => $form->createView(), - 'capsule' => $capsule + return $this->render('capsule/groups/capsule_groups.html.twig', [ + 'selectCapsuleGroupsForm' => $form->createView(), + 'capsule' => $capsule, + 'groups' => $capsule_groups_by_author, + 'groups_not_added' => $author_capsule_groups_not_added ]); } @@ -228,16 +288,11 @@ class CapsuleGroupController extends AbstractController private function createAGroup( FormInterface $form, - Capsule $capsule, Group $group ): Group { $group_name = $form->get('name')->getData(); $group->setName($group_name); $this->entity_manager->persist($group); - - $capsule->addGroup($group); - $this->entity_manager->persist($capsule); - $this->entity_manager->flush(); return $group; diff --git a/src/Form/DeleteGroupFormType.php b/src/Form/DeleteGroupFormType.php new file mode 100644 index 0000000..20b0ef3 --- /dev/null +++ b/src/Form/DeleteGroupFormType.php @@ -0,0 +1,37 @@ +<?php + +namespace App\Form; + +use App\Entity\Group; +use Symfony\Component\Form\AbstractType; +use Symfony\Component\Form\Extension\Core\Type\ButtonType; +use Symfony\Component\Form\Extension\Core\Type\SubmitType; +use Symfony\Component\Form\FormBuilderInterface; +use Symfony\Component\OptionsResolver\OptionsResolver; + +class DeleteGroupFormType extends AbstractType +{ + public function buildForm(FormBuilderInterface $builder, array $options): void + { + $builder + ->add( + 'cancel', + ButtonType::class, + ['label' => 'general.cancel_button', + 'attr' => ['class' => 'button-cancel'] + ] + ) + ->add( + 'delete', + SubmitType::class, + ['label' => 'general.delete'] + ); + } + + public function configureOptions(OptionsResolver $resolver): void + { + $resolver->setDefaults([ + 'data_class' => Group::class, + ]); + } +} diff --git a/templates/capsule/groups/edit.html.twig b/templates/capsule/groups/capsule_groups.html.twig similarity index 78% rename from templates/capsule/groups/edit.html.twig rename to templates/capsule/groups/capsule_groups.html.twig index fc833d2..5129485 100644 --- a/templates/capsule/groups/edit.html.twig +++ b/templates/capsule/groups/capsule_groups.html.twig @@ -39,12 +39,14 @@ <ul class="ps-0"> {% for group in groups %} {% if group.getName() != 'groups.filter.no_filter'|trans %} - <li class="text-capitalize text-secondary list-unstyled p-1"> - {{ group.getName() }} + <li class="text-secondary list-unstyled p-1"> + <span class="text-capitalize"> + {{ group.getName() }} + </span> - - <a href="/capsule/{{ capsule.getId() }}/groups/{{ group.getId() }}/remove" class="remove-link"> - {{ 'groups.remove.link'|trans }} - </a> + <a href="/capsule/{{ capsule.getId() }}/groups/{{ group.getId() }}/remove" class="remove-link"> + {{ 'groups.remove.link'|trans }} + </a> </li> {% endif %} {% endfor %} @@ -53,12 +55,6 @@ </div> <div class="d-flex flex-column justify-content-center order-md-2 mb-4 col-sm-8 col-md-6 col-lg-5 col-xl-4"> - <h5 class="mb-5"> - <a href="/capsule/{{ capsule.getId() }}/groups/create" class="list-unstyled"> - {{ 'groups.create.title'|trans }} - </a> - </h5> - {% if groups_not_added is not empty %} <div class="d-flex flex-column justify-content-center mb-4"> {{ form_start(selectCapsuleGroupsForm, {'attr': {novalidate: 'novalidate'}}) }} diff --git a/templates/capsule/groups/create.html.twig b/templates/capsule/groups/create.html.twig index c590d3a..aa0da53 100644 --- a/templates/capsule/groups/create.html.twig +++ b/templates/capsule/groups/create.html.twig @@ -23,7 +23,7 @@ <div class="d-flex flex-column flex-sm-row justify-content-center align-items-center align-items-sm-start"> {{ form_row(createCapsuleGroupsForm.validate, {'row_attr': {'class' : 'me-sm-3 mb-3'}}) }} - <a href="/capsule/{{ capsule.getId() }}/groups/edit"> + <a href="/my_groups"> {{ form_row(createCapsuleGroupsForm.go_back) }} </a> </div> diff --git a/templates/capsule/groups/delete.html.twig b/templates/capsule/groups/delete.html.twig new file mode 100644 index 0000000..80dcb3e --- /dev/null +++ b/templates/capsule/groups/delete.html.twig @@ -0,0 +1,34 @@ +{% extends 'layout.html.twig' %} + +{% block title %} + {{ 'groups.general.delete.title'|trans }} +{% endblock %} + +{% block body %} + + <div> + <div class="row w-100 gx-0"> + <div class="row-title-box"> + <h3 class="row-title"> + {{ 'groups.general.delete.title'|trans }} + </h3> + </div> + </div> + + <div class="d-flex flex-column justify-content-center align-items-center"> + + <p class="text-secondary fs-5 mb-5"> + {{ 'groups.general.delete.text'|trans({'%group_name%': group_name}) }} + </p> + + {{ form_start(deleteGroupForm, {'attr': {novalidate: 'novalidate', 'class': 'd-flex flex-row justify-content-center'}}) }} + {{ form_row(deleteGroupForm.delete, {'row_attr': {'class' : 'm-auto mb-2 me-3'}}) }} + <a href="/my_groups"> + {{ form_row(deleteGroupForm.cancel, {'row_attr': {'class' : 'm-auto mb-2 bg-secondary rounded ms-3'}}) }} + </a> + {{ form_end(deleteGroupForm) }} + </div> + + </div> + +{% endblock %} \ No newline at end of file diff --git a/templates/capsule/groups/user_groups.html.twig b/templates/capsule/groups/user_groups.html.twig new file mode 100644 index 0000000..db6848f --- /dev/null +++ b/templates/capsule/groups/user_groups.html.twig @@ -0,0 +1,66 @@ +{% extends 'layout.html.twig' %} + +{% block title %} + {{ 'groups.general.title'|trans }} + - + {{ parent() }} +{% endblock %} + +{% block body %} + <div> + <div class="row w-100 gx-0"> + <div class="row-title-box"> + <h3 class="row-title"> + {{ 'groups.general.title'|trans }} + </h3> + </div> + </div> + + {% for flashWarning in app.flashes('warning') %} + <div class="text-center alert alert-warning col-5 mx-auto my-5 mt-2" role="alert"> + {{ flashWarning }} + </div> + {% endfor %} + + {% for flashSuccess in app.flashes('success') %} + <div class="text-center alert alert-success col-5 mx-auto my-5 mt-2" role="alert"> + {{ flashSuccess }} + </div> + {% endfor %} + + <div class="d-flex flex-md-row flex-column justify-content-center"> + + <div class="d-flex flex-row pe-md-5 fw-normal me-0 me-md-5"> + <div class="pe-3 pe-md-4 text-nowrap"> + <h5> + {{ 'groups.general.all'|trans }} + </h5> + <ul class="ps-0"> + {% for group in groups %} + {% if group.getName() != 'groups.filter.no_filter'|trans %} + <li class="text-secondary list-unstyled p-1"> + <span class="text-capitalize"> + {{ group.getName() }} + </span> + - + <a href="/my_groups/{{ group.getId() }}/delete" class="remove-link"> + {{ 'general.delete'|trans }} + </a> + </li> + {% endif %} + {% endfor %} + </ul> + </div> + </div> + + <div class="d-flex align-items-center mt-3 mt-md-0"> + <button type="submit" class="p-2"> + <a href="/my_groups/create" class="list-unstyled text-decoration-none text-white"> + {{ 'groups.create.title'|trans }} + </a> + </button> + </div> + + </div> + </div> +{% endblock %} \ No newline at end of file diff --git a/templates/layout.html.twig b/templates/layout.html.twig index deb0ae7..a202620 100644 --- a/templates/layout.html.twig +++ b/templates/layout.html.twig @@ -25,9 +25,14 @@ </a> {% if is_granted("IS_AUTHENTICATED_REMEMBERED") %} - <div id="user-block"> + <div id="user-block" class="d-flex flex-column"> <div id="user-block-nom">{{ app.user.firstName }} {{ app.user.lastName }}</div> - <a href="{{ path('show_profile') }}" class="text-decoration-none fs-5">My profile</a> + <a href="{{ path('show_profile') }}" class="text-decoration-none fs-5"> + {{ 'user.profile.title'|trans }} + </a> + <a href="{{ path('edit_user_groups') }}" class="text-decoration-none fs-5"> + {{ 'groups.general.title'|trans }} + </a> <form> <button class="btn btn-primary" formaction="/logout"> {{ 'general.log_out'|trans }} diff --git a/tests/functional/CapsuleGroupControllerTest.php b/tests/functional/CapsuleGroupControllerTest.php index 601fca5..ac32fb8 100644 --- a/tests/functional/CapsuleGroupControllerTest.php +++ b/tests/functional/CapsuleGroupControllerTest.php @@ -23,7 +23,6 @@ class CapsuleGroupControllerTest extends WebTestCase private User $user_2; private Group $group_pop_own_by_user_1; private Group $group_rock_own_by_user_1; - private Capsule $capsule; protected function setUp(): void { @@ -40,7 +39,6 @@ class CapsuleGroupControllerTest extends WebTestCase $this->group_repository = $this->object_manager->getRepository(Group::class); $this->setUsers(); - $this->setCapsule(); $this->setCapsuleGroupPop(); $this->setCapsuleGroupRock(); } @@ -54,7 +52,7 @@ class CapsuleGroupControllerTest extends WebTestCase public function testUserShouldNotBeAbleToCreateACapsuleGroupWithExistingGroupName(): void { $this->client->loginUser($this->user_1); - $uri = '/capsule/' . $this->capsule->getId() . '/groups/create'; + $uri = '/my_groups/create'; $crawler = $this->client->request('GET', $uri); $this->assertResponseIsSuccessful(); @@ -72,7 +70,7 @@ class CapsuleGroupControllerTest extends WebTestCase public function testUserShouldBeAbleToCreateACapsuleGroupWithTheSameGroupNameUsedByAnotherUser(): void { $this->client->loginUser($this->user_2); - $uri = '/capsule/' . $this->capsule->getId() . '/groups/create'; + $uri = '/my_groups/create'; $crawler = $this->client->request('GET', $uri); $this->assertResponseIsSuccessful(); @@ -108,17 +106,6 @@ class CapsuleGroupControllerTest extends WebTestCase $this->user_2 = $user_2; } - private function setCapsule(): void - { - $capsule = $this->capsule_repository->findOneBy(['name' => 'Pomme']); - - if (! $capsule instanceof Capsule) { - throw new \Exception("Capsule does not exist."); - } - - $this->capsule = $capsule; - } - private function setCapsuleGroupPop(): void { $group_pop = $this->group_repository->findOneBy(['name' => 'Pop', 'author' => $this->user_1]); diff --git a/translations/messages.en.yaml b/translations/messages.en.yaml index 0ca87ae..637a19c 100644 --- a/translations/messages.en.yaml +++ b/translations/messages.en.yaml @@ -9,6 +9,7 @@ general: greeting: Cheers! validate: Validate save: Save + delete: Delete login: account_disabled_feedback: Your user account is disabled. Please click on the link your receive by email to validate your registration. @@ -159,6 +160,13 @@ editors: If you want to remove the capsule from your list, go to the capsule list page and click on "delete capsule" groups: + general: + title: My groups + all: All groups + delete: + title: Delete + text: Do you really want to delete group %group_name%? + success: Group group_name deleted successfully list: title: Capsule groups edit: @@ -169,7 +177,7 @@ groups: success: Group group_name has been created and added to the capsule successfully name: Choose a new group name validate: Create a new group - go_back: Go back to capsule groups + go_back: Go back to my groups add: success: Group(s) groups_names has/have been added successfully to capsule capsule_name validate: Add theses groups to the capsule diff --git a/translations/messages.fr.yaml b/translations/messages.fr.yaml index 258d7ce..b4fef15 100644 --- a/translations/messages.fr.yaml +++ b/translations/messages.fr.yaml @@ -9,6 +9,7 @@ general: greeting: Salutation ! validate: Valider save: Enregistrer + delete: Supprimer login: account_disabled_feedback: Le compte utilisateur a été désactivé. Veuillez cliquer sur le lien pour recevoir un courriel de validation @@ -158,6 +159,13 @@ editors: Si vous voulez enlever la capsule de votre liste, allez sur la page qui affiche la liste de vos capsules et cliquer sur "supprimer la capsule" groups: + general: + title: Mes groupes + all: Tous les groupes + delete: + title: Supprimer le groupe + text: Souhaitez-vous vraiment supprimer le groupe %group_name% ? + success: Le groupe group_name a bien été supprimé list: title: Groupes de la capsule edit: -- GitLab