diff --git a/CHANGELOG.md b/CHANGELOG.md index 7e2691c63..9050e6e1c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,11 @@ and this project adheres to ## Unreleased - +* [Aside activity] Fixes for aside activity + + * categories with child + * fast creation buttons + * add ordering for types ## Test releases diff --git a/src/Bundle/ChillAsideActivityBundle/src/Controller/AdminController.php b/src/Bundle/ChillAsideActivityBundle/src/Controller/AdminController.php deleted file mode 100644 index ae04b2110..000000000 --- a/src/Bundle/ChillAsideActivityBundle/src/Controller/AdminController.php +++ /dev/null @@ -1,20 +0,0 @@ - - * @author Champs Libres - */ -class AdminController extends AbstractController -{ - - public function redirectToAdminIndexAction() - { - return $this->redirectToRoute('chill_main_admin_central'); - } -} \ No newline at end of file diff --git a/src/Bundle/ChillAsideActivityBundle/src/Controller/AsideActivityCategoryController.php b/src/Bundle/ChillAsideActivityBundle/src/Controller/AsideActivityCategoryController.php index 37f10c343..bf062b50d 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Controller/AsideActivityCategoryController.php +++ b/src/Bundle/ChillAsideActivityBundle/src/Controller/AsideActivityCategoryController.php @@ -3,6 +3,9 @@ namespace Chill\AsideActivityBundle\Controller; use Chill\MainBundle\CRUD\Controller\CRUDController; +use Chill\MainBundle\Pagination\PaginatorInterface; +use Doctrine\ORM\QueryBuilder; +use Symfony\Component\HttpFoundation\Request; /** @@ -10,5 +13,12 @@ use Chill\MainBundle\CRUD\Controller\CRUDController; */ class AsideActivityCategoryController extends CRUDController { + protected function orderQuery(string $action, $query, Request $request, PaginatorInterface $paginator) + { + /** @var QueryBuilder $query */ + $query->addOrderBy('e.ordering', 'ASC'); -} \ No newline at end of file + return $query; + } + +} diff --git a/src/Bundle/ChillAsideActivityBundle/src/Entity/AsideActivityCategory.php b/src/Bundle/ChillAsideActivityBundle/src/Entity/AsideActivityCategory.php index e82bb9ec8..09087226c 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Entity/AsideActivityCategory.php +++ b/src/Bundle/ChillAsideActivityBundle/src/Entity/AsideActivityCategory.php @@ -7,6 +7,8 @@ namespace Chill\AsideActivityBundle\Entity; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; use Doctrine\ORM\Mapping as ORM; +use Symfony\Component\Validator\Constraints as Assert; +use Symfony\Component\Validator\Context\ExecutionContextInterface; /** * @ORM\Entity @@ -32,6 +34,12 @@ class AsideActivityCategory */ private bool $isActive = true; + /** + * @var float + * @ORM\Column(type="float", options={"default": 0.00}) + */ + private float $ordering = 0.00; + /** * @ORM\ManyToOne(targetEntity=AsideActivityCategory::class, inversedBy="children") * @ORM\JoinColumn(nullable=true) @@ -77,11 +85,32 @@ class AsideActivityCategory return $this; } - public function getParent(): ?self + public function getParent(): ?self { return $this->parent; } + /** + * + * @Assert\Callback() + */ + public function preventRecursiveParent(ExecutionContextInterface $context, $payload) + { + if (!$this->hasParent()) { + return; + } + + if ($this->getParent() === $this) { + // replace parent with old parent. This prevent recursive loop + // when displaying form + $this->parent = $this->oldParent; + $context->buildViolation('You must not add twice the same category in the parent tree (previous result returned)') + ->atPath('parent') + ->addViolation() + ; + } + } + public function hasParent(): bool { return $this->parent !== null; @@ -89,6 +118,8 @@ class AsideActivityCategory public function setParent(?self $parent): self { + // cache the old result for changing it during validaiton + $this->oldParent = $this->parent; $this->parent = $parent; return $this; @@ -124,4 +155,14 @@ class AsideActivityCategory return $this; } + public function getOrdering(): float + { + return $this->ordering; + } + + public function setOrdering(float $ordering): AsideActivityCategory + { + $this->ordering = $ordering; + return $this; + } } diff --git a/src/Bundle/ChillAsideActivityBundle/src/Form/AsideActivityCategoryType.php b/src/Bundle/ChillAsideActivityBundle/src/Form/AsideActivityCategoryType.php index 39ddc826b..0060ab1b9 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Form/AsideActivityCategoryType.php +++ b/src/Bundle/ChillAsideActivityBundle/src/Form/AsideActivityCategoryType.php @@ -9,11 +9,12 @@ use Chill\MainBundle\Templating\TranslatableStringHelper; use Symfony\Bridge\Doctrine\Form\Type\EntityType; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Extension\Core\Type\ChoiceType; +use Symfony\Component\Form\Extension\Core\Type\NumberType; use Symfony\Component\Form\FormBuilderInterface; final class AsideActivityCategoryType extends AbstractType { - + protected $translatableStringHelper; public function __construct(TranslatableStringHelper $translatableStringHelper, CategoryRender $categoryRender) @@ -31,13 +32,14 @@ final class AsideActivityCategoryType extends AbstractType ->add('parent', EntityType::class, [ 'class' => AsideActivityCategory::class, 'required' => false, - 'label' => 'Type', + 'label' => 'Parent', 'choice_label' => function (AsideActivityCategory $category){ $options = []; return $this->categoryRender->renderString($category, $options); } ]) - ->add('isActive', ChoiceType::class, + ->add('ordering', NumberType::class) + ->add('isActive', ChoiceType::class, [ 'choices' => [ 'Yes' => true, diff --git a/src/Bundle/ChillAsideActivityBundle/src/Form/AsideActivityFormType.php b/src/Bundle/ChillAsideActivityBundle/src/Form/AsideActivityFormType.php index 59bd50874..7c7803816 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Form/AsideActivityFormType.php +++ b/src/Bundle/ChillAsideActivityBundle/src/Form/AsideActivityFormType.php @@ -10,6 +10,7 @@ use Chill\MainBundle\Form\Type\ChillDateType; use Chill\MainBundle\Form\Type\ChillTextareaType; use Chill\MainBundle\Templating\TranslatableStringHelper; use Doctrine\ORM\EntityRepository; +use Doctrine\ORM\QueryBuilder; use Symfony\Bridge\Doctrine\Form\Type\EntityType; use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; use Symfony\Component\Form\AbstractType; @@ -80,6 +81,14 @@ final class AsideActivityFormType extends AbstractType 'required' => true, 'class' => AsideActivityCategory::class, 'placeholder' => 'Choose the activity category', + 'query_builder' => function(EntityRepository $er) { + $qb = $er->createQueryBuilder('ac'); + $qb->where($qb->expr()->eq('ac.isActive', 'TRUE')) + ->addOrderBy('ac.ordering', 'ASC') + ; + + return $qb; + }, 'choice_label' => function (AsideActivityCategory $asideActivityCategory) { $options = []; return $this->categoryRender->renderString($asideActivityCategory, $options); diff --git a/src/Bundle/ChillAsideActivityBundle/src/Menu/AdminMenuBuilder.php b/src/Bundle/ChillAsideActivityBundle/src/Menu/AdminMenuBuilder.php new file mode 100644 index 000000000..ecc1a1f90 --- /dev/null +++ b/src/Bundle/ChillAsideActivityBundle/src/Menu/AdminMenuBuilder.php @@ -0,0 +1,48 @@ +security = $security; + } + + public static function getMenuIds(): array + { + return ['admin_index', 'admin_section', 'admin_aside_activity']; + } + + public function buildMenu($menuId, MenuItem $menu, array $parameters) + { + // all the entries below must have ROLE_ADMIN permissions + if (!$this->security->isGranted('ROLE_ADMIN')) { + return; + } + + if (in_array($menuId, ['admin_index', 'admin_section'])) { + $menu->addChild('Aside activities', [ + 'route' => 'chill_crud_aside_activity_category_index' + ]) + ->setExtras([ + 'order' => 900, + 'explain' => "Configure aside activities categories" + ]); + } else { + $menu + ->addChild('Aside activity categories', [ + 'route' => 'chill_crud_aside_activity_category_index' + ]) + ->setExtras([ + 'order' => '50' + ]); + } + + } +} diff --git a/src/Bundle/ChillAsideActivityBundle/src/Resources/views/Admin/layout_asideactivity.html.twig b/src/Bundle/ChillAsideActivityBundle/src/Resources/views/Admin/layout_asideactivity.html.twig index 08b01cdbd..3f44e432d 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Resources/views/Admin/layout_asideactivity.html.twig +++ b/src/Bundle/ChillAsideActivityBundle/src/Resources/views/Admin/layout_asideactivity.html.twig @@ -1,9 +1,7 @@ {% extends "@ChillMain/Admin/layoutWithVerticalMenu.html.twig" %} {% block vertical_menu_content %} - {{ chill_menu('admin_aside_activity', { - 'layout': '@ChillAsideActivity/Admin/menu_asideactivity.html.twig', - }) }} + {{ chill_menu('admin_aside_activity') }} {% endblock %} {% block layout_wvm_content %} diff --git a/src/Bundle/ChillAsideActivityBundle/src/Resources/views/Admin/menu_asideactivity.html.twig b/src/Bundle/ChillAsideActivityBundle/src/Resources/views/Admin/menu_asideactivity.html.twig deleted file mode 100644 index 34ea309e5..000000000 --- a/src/Bundle/ChillAsideActivityBundle/src/Resources/views/Admin/menu_asideactivity.html.twig +++ /dev/null @@ -1,4 +0,0 @@ -{% extends "@ChillMain/Menu/verticalMenu.html.twig" %} -{% block v_menu_title %} - {{ 'Aside activity configuration menu'|trans }} -{% endblock %} diff --git a/src/Bundle/ChillAsideActivityBundle/src/Resources/views/asideActivityCategory/asideActivityCategory.html.twig b/src/Bundle/ChillAsideActivityBundle/src/Resources/views/Entity/asideActivityCategory.html.twig similarity index 75% rename from src/Bundle/ChillAsideActivityBundle/src/Resources/views/asideActivityCategory/asideActivityCategory.html.twig rename to src/Bundle/ChillAsideActivityBundle/src/Resources/views/Entity/asideActivityCategory.html.twig index 8521b3132..1b31cc765 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Resources/views/asideActivityCategory/asideActivityCategory.html.twig +++ b/src/Bundle/ChillAsideActivityBundle/src/Resources/views/Entity/asideActivityCategory.html.twig @@ -1,7 +1,6 @@ {% set reversed_parents = parents|reverse %} - {# #} + class="chill-entity entity-aside_activity-category"> {%- for p in reversed_parents %} {{ p.title|localize_translatable_string }}{{ options['default.separator'] }} @@ -10,5 +9,4 @@ {{ asideActivityCategory.title|localize_translatable_string }} - {# #} diff --git a/src/Bundle/ChillAsideActivityBundle/src/Resources/views/asideActivity/index.html.twig b/src/Bundle/ChillAsideActivityBundle/src/Resources/views/asideActivity/index.html.twig index a97a29875..6cc45aeaf 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Resources/views/asideActivity/index.html.twig +++ b/src/Bundle/ChillAsideActivityBundle/src/Resources/views/asideActivity/index.html.twig @@ -24,7 +24,7 @@

- {{ entity.type|chill_entity_render_box }} + {{ entity.type|chill_entity_render_box }}

{% if entity.date %} @@ -46,13 +46,13 @@
  • {{ 'By'|trans }}: - {{ entity.createdBy.usernameCanonical }} + {{ entity.createdBy|chill_entity_render_box }}
  • {{ 'For'|trans }}: - {{ entity.agent.usernameCanonical }} + {{ entity.agent|chill_entity_render_box }}
  • diff --git a/src/Bundle/ChillAsideActivityBundle/src/Resources/views/asideActivityCategory/edit.html.twig b/src/Bundle/ChillAsideActivityBundle/src/Resources/views/asideActivityCategory/edit.html.twig index dacee767c..3fb6fb612 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Resources/views/asideActivityCategory/edit.html.twig +++ b/src/Bundle/ChillAsideActivityBundle/src/Resources/views/asideActivityCategory/edit.html.twig @@ -1,4 +1,4 @@ -{% extends "@ChillActivity/Admin/layout_activity.html.twig" %} +{% extends "@ChillAsideActivity/Admin/layout_asideactivity.html.twig" %} {% block title %} {% include('@ChillMain/CRUD/_edit_title.html.twig') %} diff --git a/src/Bundle/ChillAsideActivityBundle/src/Resources/views/asideActivityCategory/index.html.twig b/src/Bundle/ChillAsideActivityBundle/src/Resources/views/asideActivityCategory/index.html.twig index d8cb67716..2c8373daf 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Resources/views/asideActivityCategory/index.html.twig +++ b/src/Bundle/ChillAsideActivityBundle/src/Resources/views/asideActivityCategory/index.html.twig @@ -1,11 +1,12 @@ {% extends "@ChillAsideActivity/Admin/layout_asideactivity.html.twig" %} {% block admin_content %} -

    {{ 'ActivityType list'|trans }}

    +

    {{ 'Aside Activity Type list'|trans }}

    + @@ -14,7 +15,8 @@ {% for entity in entities %} - + +
    {{ 'Ordering'|trans }} {{ 'Name'|trans }} {{ 'Active'|trans }} {{ 'Actions'|trans }}
    {{ entity.title|localize_translatable_string }}{{ entity.ordering }}{{ entity|chill_entity_render_box }} {%- if entity.isActive -%} diff --git a/src/Bundle/ChillAsideActivityBundle/src/Resources/views/asideActivityCategory/new.html.twig b/src/Bundle/ChillAsideActivityBundle/src/Resources/views/asideActivityCategory/new.html.twig index d7ac89752..3c8ded234 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Resources/views/asideActivityCategory/new.html.twig +++ b/src/Bundle/ChillAsideActivityBundle/src/Resources/views/asideActivityCategory/new.html.twig @@ -1,4 +1,4 @@ -{% extends "@ChillActivity/Admin/layout_activity.html.twig" %} +{% extends "@ChillAsideActivity/Admin/layout_asideactivity.html.twig" %} {% block title %} {% include('@ChillMain/CRUD/_new_title.html.twig') %} diff --git a/src/Bundle/ChillAsideActivityBundle/src/Templating/Entity/CategoryRender.php b/src/Bundle/ChillAsideActivityBundle/src/Templating/Entity/CategoryRender.php index 8bab0986c..902ed7a68 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Templating/Entity/CategoryRender.php +++ b/src/Bundle/ChillAsideActivityBundle/src/Templating/Entity/CategoryRender.php @@ -70,11 +70,11 @@ final class CategoryRender implements ChillEntityRenderInterface $options = array_merge(self::DEFAULT_ARGS, $options); $parents = $this->buildParents($asideActivityCategory); - return $this->engine->render('@ChillAsideActivity/asideActivityCategory/asideActivityCategory.html.twig', + return $this->engine->render('@ChillAsideActivity/Entity/asideActivityCategory.html.twig', [ 'asideActivityCategory' => $asideActivityCategory, 'parents' => $parents, 'options' => $options ]); } -} \ No newline at end of file +} diff --git a/src/Bundle/ChillAsideActivityBundle/src/migrations/Version20211004134012.php b/src/Bundle/ChillAsideActivityBundle/src/migrations/Version20211004134012.php new file mode 100644 index 000000000..42763638e --- /dev/null +++ b/src/Bundle/ChillAsideActivityBundle/src/migrations/Version20211004134012.php @@ -0,0 +1,29 @@ +addSql('ALTER TABLE chill_asideactivity.asideactivitycategory ADD ordering DOUBLE PRECISION NOT NULL DEFAULT 0.00'); + } + + public function down(Schema $schema): void + { + $this->addSql('ALTER TABLE chill_asideactivity.asideactivitycategory DROP ordering'); + } +} diff --git a/src/Bundle/ChillAsideActivityBundle/src/translations/messages.fr.yml b/src/Bundle/ChillAsideActivityBundle/src/translations/messages.fr.yml index 6ee180ad9..c16f6af6a 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/translations/messages.fr.yml +++ b/src/Bundle/ChillAsideActivityBundle/src/translations/messages.fr.yml @@ -49,6 +49,8 @@ Agent: Utilisateur date: Date Duration: Durée Note: Note +Choose the agent for whom this activity is created: Choisissez l'agent pour qui l'activité est créée +Choose the activity category: Choisir la catégorie #Duration minutes: minutes diff --git a/src/Bundle/ChillAsideActivityBundle/src/translations/validators.fr.yaml b/src/Bundle/ChillAsideActivityBundle/src/translations/validators.fr.yaml new file mode 100644 index 000000000..28883568c --- /dev/null +++ b/src/Bundle/ChillAsideActivityBundle/src/translations/validators.fr.yaml @@ -0,0 +1 @@ +You must not add twice the same category in the parent tree (previous result returned): Il est interdit d'indiquer la même entité dans l'arbre des parents. Le résultat précédent a été rétabli diff --git a/src/Bundle/ChillMainBundle/Resources/views/Menu/defaultMenu.html.twig b/src/Bundle/ChillMainBundle/Resources/views/Menu/defaultMenu.html.twig index 67a32b98b..6eada4dd6 100644 --- a/src/Bundle/ChillMainBundle/Resources/views/Menu/defaultMenu.html.twig +++ b/src/Bundle/ChillMainBundle/Resources/views/Menu/defaultMenu.html.twig @@ -1,5 +1,5 @@ {# - * Copyright (C) 2014-2015, Champs Libres Cooperative SCRLFS, + * Copyright (C) 2014-2015, Champs Libres Cooperative SCRLFS, / * * This program is free software: you can redistribute it and/or modify @@ -17,7 +17,7 @@ #} \ No newline at end of file + diff --git a/src/Bundle/ChillMainBundle/Tests/Services/ChillMenuTwigFunctionTest.php b/src/Bundle/ChillMainBundle/Tests/Services/ChillMenuTwigFunctionTest.php deleted file mode 100644 index a85ff9710..000000000 --- a/src/Bundle/ChillMainBundle/Tests/Services/ChillMenuTwigFunctionTest.php +++ /dev/null @@ -1,54 +0,0 @@ - - * Copyright (C) 2014, Champs Libres Cooperative SCRLFS, - * - * 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 . - */ - -namespace Chill\MainBundle\Tests\Services; - -use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase; -use Symfony\Component\DomCrawler\Crawler; - -/** - * Test the Twig function 'chill_menu' - * - * @author Julien Fastré - */ -class ChillMenuTwigFunctionTest extends KernelTestCase -{ - - private static $templating; - - public static function setUpBeforeClass() - { - self::bootKernel(array('environment' => 'test')); - static::$templating = static::$container - ->get('templating'); - $pathToBundle = static::$container->getParameter('kernel.bundles_metadata')['ChillMainBundle']['path']; - //load templates in Tests/Resources/views - static::$container->get('twig.loader') - ->addPath($pathToBundle.'/Resources/test/views/', $namespace = 'tests'); - } - - public function testNormalMenu() - { - $content = static::$templating->render('@tests/menus/normalMenu.html.twig'); - $this->assertContains('ul', $content, - "test that the file contains an ul tag" - ); - } -}