Merge branch '616_rapid-action' into 'master'

Flash menu rapid action in search results

See merge request Chill-Projet/chill-bundles!441
This commit is contained in:
Julien Fastré 2024-06-13 10:32:30 +00:00
commit f66ac50571
14 changed files with 211 additions and 41 deletions

View File

@ -0,0 +1,6 @@
kind: Feature
body: Add flash menu buttons in search results, to open directly a new calendar, or
a new activity in an accompanying period
time: 2024-06-13T12:21:02.602847716+02:00
custom:
Issue: ""

View File

@ -0,0 +1,51 @@
<?php
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ActivityBundle\Menu;
use Chill\ActivityBundle\Security\Authorization\ActivityVoter;
use Chill\MainBundle\Routing\LocalMenuBuilderInterface;
use Knp\Menu\MenuItem;
use Symfony\Component\Security\Core\Security;
final readonly class AccompanyingCourseQuickMenuBuilder implements LocalMenuBuilderInterface
{
public function __construct(private Security $security)
{
}
public static function getMenuIds(): array
{
return ['accompanying_course_quick_menu'];
}
public function buildMenu($menuId, MenuItem $menu, array $parameters)
{
/** @var \Chill\PersonBundle\Entity\AccompanyingPeriod $accompanyingCourse */
$accompanyingCourse = $parameters['accompanying-course'];
if ($this->security->isGranted(ActivityVoter::CREATE, $accompanyingCourse)) {
$menu
->addChild('Create a new activity in accompanying course', [
'route' => 'chill_activity_activity_new',
'routeParameters' => [
// 'activityType_id' => '',
'accompanying_period_id' => $accompanyingCourse->getId(),
],
])
->setExtras([
'order' => 10,
'icon' => 'plus',
])
;
}
}
}

View File

@ -145,7 +145,7 @@ class ActivityVoter extends AbstractChillVoter implements ProvideRoleHierarchyIn
throw new \RuntimeException('Could not determine context of activity.'); throw new \RuntimeException('Could not determine context of activity.');
} }
} elseif ($subject instanceof AccompanyingPeriod) { } elseif ($subject instanceof AccompanyingPeriod) {
if (AccompanyingPeriod::STEP_CLOSED === $subject->getStep()) { if (AccompanyingPeriod::STEP_CLOSED === $subject->getStep() || AccompanyingPeriod::STEP_DRAFT === $subject->getStep()) {
if (\in_array($attribute, [self::UPDATE, self::CREATE, self::DELETE], true)) { if (\in_array($attribute, [self::UPDATE, self::CREATE, self::DELETE], true)) {
return false; return false;
} }

View File

@ -222,6 +222,7 @@ Documents label: Libellé du champ Documents
# activity type category admin # activity type category admin
ActivityTypeCategory list: Liste des catégories des types d'échange ActivityTypeCategory list: Liste des catégories des types d'échange
Create a new activity type category: Créer une nouvelle catégorie de type d'échange Create a new activity type category: Créer une nouvelle catégorie de type d'échange
Create a new activity in accompanying course: Créer un échange dans le parcours
# activity delete # activity delete
Remove activity: Supprimer un échange Remove activity: Supprimer un échange

View File

@ -0,0 +1,50 @@
<?php
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\CalendarBundle\Menu;
use Chill\CalendarBundle\Security\Voter\CalendarVoter;
use Chill\MainBundle\Routing\LocalMenuBuilderInterface;
use Knp\Menu\MenuItem;
use Symfony\Component\Security\Core\Security;
final readonly class AccompanyingCourseQuickMenuBuilder implements LocalMenuBuilderInterface
{
public function __construct(private Security $security)
{
}
public static function getMenuIds(): array
{
return ['accompanying_course_quick_menu'];
}
public function buildMenu($menuId, MenuItem $menu, array $parameters)
{
/** @var \Chill\PersonBundle\Entity\AccompanyingPeriod $accompanyingCourse */
$accompanyingCourse = $parameters['accompanying-course'];
if ($this->security->isGranted(CalendarVoter::CREATE, $accompanyingCourse)) {
$menu
->addChild('Create a new calendar in accompanying course', [
'route' => 'chill_calendar_calendar_new',
'routeParameters' => [
'accompanying_period_id' => $accompanyingCourse->getId(),
],
])
->setExtras([
'order' => 20,
'icon' => 'plus',
])
;
}
}
}

View File

@ -89,7 +89,7 @@ class CalendarVoter extends AbstractChillVoter implements ProvideRoleHierarchyIn
switch ($attribute) { switch ($attribute) {
case self::SEE: case self::SEE:
case self::CREATE: case self::CREATE:
if (AccompanyingPeriod::STEP_DRAFT === $subject->getStep()) { if (AccompanyingPeriod::STEP_DRAFT === $subject->getStep() || AccompanyingPeriod::STEP_CLOSED === $subject->getStep()) {
return false; return false;
} }

View File

@ -26,6 +26,7 @@ The calendar item has been successfully removed.: Le rendez-vous a été supprim
From the day: Du From the day: Du
to the day: au to the day: au
Transform to activity: Transformer en échange Transform to activity: Transformer en échange
Create a new calendar in accompanying course: Créer un rendez-vous dans le parcours
Will send SMS: Un SMS de rappel sera envoyé Will send SMS: Un SMS de rappel sera envoyé
Will not send SMS: Aucun SMS de rappel ne sera envoyé Will not send SMS: Aucun SMS de rappel ne sera envoyé
SMS already sent: Un SMS a été envoyé SMS already sent: Un SMS a été envoyé

View File

@ -0,0 +1,20 @@
{% if menus|length > 0 %}
<li class="dropdown">
<a class="dropdown-toggle btn btn-sm btn-outline-primary"
href="#"
role="button"
data-bs-toggle="dropdown"
aria-expanded="false">
<i class="fa fa-flash"></i>
</a>
<div class="dropdown-menu">
{% for menu in menus %}
<a class="dropdown-item"
href="{{ menu.uri }}"
><i class="fa fa-{{- menu.extras.icon }} fa-fw"></i>
{{ menu.label|trans }}
</a>
{% endfor %}
</div>
</li>
{% endif %}

View File

@ -11,8 +11,6 @@ declare(strict_types=1);
namespace Chill\MainBundle\Routing; namespace Chill\MainBundle\Routing;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Twig\Environment; use Twig\Environment;
use Twig\Extension\AbstractExtension; use Twig\Extension\AbstractExtension;
use Twig\TwigFunction; use Twig\TwigFunction;
@ -20,10 +18,8 @@ use Twig\TwigFunction;
/** /**
* Add the filter 'chill_menu'. * Add the filter 'chill_menu'.
*/ */
class MenuTwig extends AbstractExtension implements ContainerAwareInterface class MenuTwig extends AbstractExtension
{ {
private ?ContainerInterface $container = null;
/** /**
* the default parameters for chillMenu. * the default parameters for chillMenu.
* *
@ -86,9 +82,4 @@ class MenuTwig extends AbstractExtension implements ContainerAwareInterface
{ {
return 'chill_menu'; return 'chill_menu';
} }
public function setContainer(?ContainerInterface $container = null)
{
$this->container = $container;
}
} }

View File

@ -20,9 +20,5 @@ services:
chill.main.twig.chill_menu: chill.main.twig.chill_menu:
class: Chill\MainBundle\Routing\MenuTwig class: Chill\MainBundle\Routing\MenuTwig
arguments:
- "@chill.main.menu_composer"
calls:
- [setContainer, ["@service_container"]]
tags: tags:
- { name: twig.extension } - { name: twig.extension }

View File

@ -0,0 +1,51 @@
<?php
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\PersonBundle\Menu;
use Chill\MainBundle\Routing\LocalMenuBuilderInterface;
use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter;
use Knp\Menu\MenuItem;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
final readonly class PersonQuickMenuBuilder implements LocalMenuBuilderInterface
{
public function __construct(private AuthorizationCheckerInterface $authorizationChecker)
{
}
public static function getMenuIds(): array
{
return ['person_quick_menu'];
}
public function buildMenu($menuId, MenuItem $menu, array $parameters)
{
/** @var \Chill\PersonBundle\Entity\Person $person */
$person = $parameters['person'];
if ($this->authorizationChecker->isGranted(AccompanyingPeriodVoter::CREATE, $person)) {
$menu->addChild(
'Create Accompanying Course',
[
'route' => 'chill_person_accompanying_course_new',
'routeParameters' => [
'person_id' => [$person->getId()],
],
]
)
->setExtras([
'order' => 10,
'icon' => 'plus',
]);
}
}
}

View File

@ -30,7 +30,7 @@ div.list-with-period {
// override wrap-list // override wrap-list
div.wrap-list.periods-list { div.wrap-list.periods-list {
padding-right: 1rem; padding-right: 0;
div.wl-row { div.wl-row {
flex-wrap: nowrap; flex-wrap: nowrap;
div.wl-col { div.wl-col {

View File

@ -1,13 +1,19 @@
{% macro button_person_before(person) %}
{{ chill_menu('person_quick_menu', {
'layout': '@ChillMain/Menu/quick_menu.html.twig',
'args' : { 'person': person }
}) }}
{% endmacro %}
{% macro button_person_after(person) %} {% macro button_person_after(person) %}
{% set household = person.getCurrentHousehold %} {% set household = person.getCurrentHousehold %}
{% if household is not null and is_granted('CHILL_PERSON_HOUSEHOLD_SEE', household) %} {% if household is not null and is_granted('CHILL_PERSON_HOUSEHOLD_SEE', household) %}
<li> <li>
<a href="{{ path('chill_person_household_summary', { 'household_id': household.id }) }}" class="btn btn-sm btn-chill-beige"><i class="fa fa-home"></i></a> <a href="{{ path('chill_person_household_summary', { 'household_id': household.id }) }}"
</li> class="btn btn-sm btn-chill-beige"
{% endif %} title="{{ 'Show household'|trans }}"
{% if is_granted('CHILL_PERSON_ACCOMPANYING_PERIOD_CREATE', person) %} ><i class="fa fa-home"></i>
<li> </a>
<a href="{{ path('chill_person_accompanying_course_new', { 'person_id': [ person.id ]}) }}" class="btn btn-sm btn-create change-icon" title="{{ 'Create an accompanying period'|trans }}"><i class="fa fa-random"></i></a>
</li> </li>
{% endif %} {% endif %}
{% endmacro %} {% endmacro %}
@ -184,13 +190,20 @@
</div> </div>
{% endif %} {% endif %}
<ul class="record_actions record_actions_column"> <ul class="record_actions">
{{ chill_menu('accompanying_course_quick_menu', {
'layout': '@ChillMain/Menu/quick_menu.html.twig',
'args' : { 'accompanying-course': acp }
}) }}
<li> <li>
<a href="{{ path('chill_person_accompanying_course_index', { 'accompanying_period_id': acp.id }) }}" <a href="{{ path('chill_person_accompanying_course_index', { 'accompanying_period_id': acp.id }) }}"
class="btn btn-sm btn-outline-primary" title="{{ 'See accompanying period'|trans }}"> class="btn btn-sm btn-primary"
<i class="fa fa-random fa-fw"></i> title="{{ 'See accompanying period'|trans }}"
><i class="fa fa-random fa-fw"></i>
</a> </a>
</li> </li>
</ul> </ul>
</div> </div>
</div> </div>
@ -247,7 +260,7 @@
'addAltNames': true, 'addAltNames': true,
'addCenter': true, 'addCenter': true,
'address_multiline': false, 'address_multiline': false,
'customButtons': { 'after': _self.button_person_after(person) } 'customButtons': { 'after': _self.button_person_after(person), 'before': _self.button_person_before((person)) }
}) }} }) }}
{#- 'acps' is for AcCompanyingPeriodS #} {#- 'acps' is for AcCompanyingPeriodS #}

View File

@ -1,19 +1,9 @@
services: services:
Chill\PersonBundle\Menu\: _defaults:
resource: './../../Menu'
autowire: true
tags:
- { name: 'chill.menu_builder' }
# Chill\PersonBundle\Menu\SectionMenuBuilder:
# arguments:
# $authorizationChecker: '@Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface'
# $translator: '@Symfony\Contracts\Translation\TranslatorInterface'
# tags:
# - { name: 'chill.menu_builder' }
#
Chill\PersonBundle\Menu\PersonMenuBuilder:
autowire: true autowire: true
autoconfigure: true autoconfigure: true
Chill\PersonBundle\Menu\:
resource: './../../Menu'
tags: tags:
- { name: 'chill.menu_builder' } - { name: 'chill.menu_builder' }