mirror of
				https://gitlab.com/Chill-Projet/chill-bundles.git
				synced 2025-10-31 09:18:24 +00:00 
			
		
		
		
	Compare commits
	
		
			1 Commits
		
	
	
		
			454-evalua
			...
			449-scope-
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 9db1a960db | 
							
								
								
									
										6
									
								
								.changes/unreleased/UX-20251030-153126.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								.changes/unreleased/UX-20251030-153126.yaml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | ||||
| kind: UX | ||||
| body: Remove the label if there is only one scope and no scope picking field is displayed. | ||||
| time: 2025-10-30T15:31:26.807444365+01:00 | ||||
| custom: | ||||
|     Issue: "449" | ||||
|     SchemaChange: No schema change | ||||
| @@ -1,6 +0,0 @@ | ||||
| kind: UX | ||||
| body: Expand timeSpent choices for evaluation document and translate them to user locale or fallback 'fr' | ||||
| time: 2025-10-30T18:09:19.373907522+01:00 | ||||
| custom: | ||||
|     Issue: "" | ||||
|     SchemaChange: No schema change | ||||
| @@ -18,6 +18,7 @@ use Chill\ActivityBundle\Security\Authorization\ActivityVoter; | ||||
| use Chill\DocStoreBundle\Form\CollectionStoredObjectType; | ||||
| use Chill\MainBundle\Entity\Center; | ||||
| use Chill\MainBundle\Entity\Location; | ||||
| use Chill\MainBundle\Entity\Scope; | ||||
| use Chill\MainBundle\Entity\User; | ||||
| use Chill\MainBundle\Form\Type\ChillDateType; | ||||
| use Chill\MainBundle\Form\Type\CommentType; | ||||
| @@ -47,6 +48,7 @@ use Symfony\Component\Form\FormEvent; | ||||
| use Symfony\Component\Form\FormEvents; | ||||
| use Symfony\Component\OptionsResolver\OptionsResolver; | ||||
| use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; | ||||
| use Symfony\Component\Security\Core\Security; | ||||
|  | ||||
| class ActivityType extends AbstractType | ||||
| { | ||||
| @@ -60,6 +62,7 @@ class ActivityType extends AbstractType | ||||
|         protected array $timeChoices, | ||||
|         protected SocialIssueRender $socialIssueRender, | ||||
|         protected SocialActionRender $socialActionRender, | ||||
|         private readonly Security $security, | ||||
|     ) { | ||||
|         if (!$tokenStorage->getToken()->getUser() instanceof User) { | ||||
|             throw new \RuntimeException('you should have a valid user'); | ||||
| @@ -87,10 +90,22 @@ class ActivityType extends AbstractType | ||||
|         $activityType = $options['activityType']; | ||||
|  | ||||
|         if (null !== $options['data']->getPerson()) { | ||||
|  | ||||
|             $reachableScopes = array_values( | ||||
|                 array_filter( | ||||
|                     $this->authorizationHelper->getReachableScopes( | ||||
|                         $this->security->getUser(), | ||||
|                         ActivityVoter::CREATE === (string) $options['role'] ? ActivityVoter::CREATE_PERSON : (string) $options['role'], | ||||
|                         $options['center'] | ||||
|                     ), | ||||
|                     static fn (Scope $s) => $s->isActive() | ||||
|                 ) | ||||
|             ); | ||||
|  | ||||
|             $builder->add('scope', ScopePickerType::class, [ | ||||
|                 'center' => $options['center'], | ||||
|                 'role' => ActivityVoter::CREATE === (string) $options['role'] ? ActivityVoter::CREATE_PERSON : (string) $options['role'], | ||||
|                 'reachable_scopes' => $reachableScopes, | ||||
|                 'required' => true, | ||||
|                 'label' => count($reachableScopes) > 1 ? 'Scope' : false, | ||||
|             ]); | ||||
|         } | ||||
|  | ||||
|   | ||||
| @@ -14,9 +14,11 @@ namespace Chill\DocStoreBundle\Form; | ||||
| use Chill\DocStoreBundle\Entity\Document; | ||||
| use Chill\DocStoreBundle\Entity\DocumentCategory; | ||||
| use Chill\DocStoreBundle\Entity\PersonDocument; | ||||
| use Chill\MainBundle\Entity\Scope; | ||||
| use Chill\MainBundle\Form\Type\ChillDateType; | ||||
| use Chill\MainBundle\Form\Type\ChillTextareaType; | ||||
| use Chill\MainBundle\Form\Type\ScopePickerType; | ||||
| use Chill\MainBundle\Security\Authorization\AuthorizationHelperInterface; | ||||
| use Chill\MainBundle\Security\Resolver\CenterResolverDispatcher; | ||||
| use Chill\MainBundle\Security\Resolver\ScopeResolverDispatcher; | ||||
| use Chill\MainBundle\Templating\TranslatableStringHelperInterface; | ||||
| @@ -27,10 +29,11 @@ use Symfony\Component\Form\AbstractType; | ||||
| use Symfony\Component\Form\Extension\Core\Type\TextType; | ||||
| use Symfony\Component\Form\FormBuilderInterface; | ||||
| use Symfony\Component\OptionsResolver\OptionsResolver; | ||||
| use Symfony\Component\Security\Core\Security; | ||||
|  | ||||
| class PersonDocumentType extends AbstractType | ||||
| { | ||||
|     public function __construct(private readonly TranslatableStringHelperInterface $translatableStringHelper, private readonly ScopeResolverDispatcher $scopeResolverDispatcher, private readonly ParameterBagInterface $parameterBag, private readonly CenterResolverDispatcher $centerResolverDispatcher) {} | ||||
|     public function __construct(private readonly TranslatableStringHelperInterface $translatableStringHelper, private readonly Security $security, private readonly AuthorizationHelperInterface $authorizationHelper, private readonly ScopeResolverDispatcher $scopeResolverDispatcher, private readonly ParameterBagInterface $parameterBag, private readonly CenterResolverDispatcher $centerResolverDispatcher) {} | ||||
|  | ||||
|     public function buildForm(FormBuilderInterface $builder, array $options) | ||||
|     { | ||||
| @@ -56,9 +59,19 @@ class PersonDocumentType extends AbstractType | ||||
|             ]); | ||||
|  | ||||
|         if ($isScopeConcerned && $this->parameterBag->get('chill_main')['acl']['form_show_scopes']) { | ||||
|             $reachableScopes = array_values( | ||||
|                 array_filter( | ||||
|                     $this->authorizationHelper->getReachableScopes( | ||||
|                         $this->security->getUser(), | ||||
|                         $options['role'], | ||||
|                         $this->centerResolverDispatcher->resolveCenter($document) | ||||
|                     ), | ||||
|                     static fn (Scope $s) => $s->isActive() | ||||
|                 ) | ||||
|             ); | ||||
|             $builder->add('scope', ScopePickerType::class, [ | ||||
|                 'center' => $this->centerResolverDispatcher->resolveCenter($document), | ||||
|                 'role' => $options['role'], | ||||
|                 'reachable_scopes' => $reachableScopes, | ||||
|                 'label' => count($reachableScopes) > 1 ? 'Scope' : false, | ||||
|             ]); | ||||
|         } | ||||
|     } | ||||
|   | ||||
| @@ -40,41 +40,39 @@ use Symfony\Component\Security\Core\Security; | ||||
| class ScopePickerType extends AbstractType | ||||
| { | ||||
|     public function __construct( | ||||
|         private readonly AuthorizationHelperInterface $authorizationHelper, | ||||
|         private readonly Security $security, | ||||
|         private readonly TranslatableStringHelperInterface $translatableStringHelper, | ||||
|     ) {} | ||||
|  | ||||
|     public function buildForm(FormBuilderInterface $builder, array $options) | ||||
|     { | ||||
|         $items = array_values( | ||||
|             array_filter( | ||||
|                 $this->authorizationHelper->getReachableScopes( | ||||
|                     $this->security->getUser(), | ||||
|                     $options['role'], | ||||
|                     $options['center'] | ||||
|                 ), | ||||
|                 static fn (Scope $s) => $s->isActive() | ||||
|             ) | ||||
|         ); | ||||
|         /*        $items = array_values( | ||||
|                     array_filter( | ||||
|                         $this->authorizationHelper->getReachableScopes( | ||||
|                             $this->security->getUser(), | ||||
|                             $options['role'], | ||||
|                             $options['center'] | ||||
|                         ), | ||||
|                         static fn (Scope $s) => $s->isActive() | ||||
|                     ) | ||||
|                 );*/ | ||||
|  | ||||
|         if (0 === \count($items)) { | ||||
|         if (0 === \count($options['reachable_scopes'])) { | ||||
|             throw new \RuntimeException('no scopes are reachable. This form should not be shown to user'); | ||||
|         } | ||||
|  | ||||
|         if (1 !== \count($items)) { | ||||
|         if (1 !== \count($options['reachable_scopes'])) { | ||||
|             $builder->add('scope', EntityType::class, [ | ||||
|                 'class' => Scope::class, | ||||
|                 'placeholder' => 'Choose the circle', | ||||
|                 'choice_label' => fn (Scope $c) => $this->translatableStringHelper->localize($c->getName()), | ||||
|                 'choices' => $items, | ||||
|                 'choices' => $options['reachable_scopes'], | ||||
|             ]); | ||||
|             $builder->setDataMapper(new ScopePickerDataMapper()); | ||||
|         } else { | ||||
|             $builder->add('scope', HiddenType::class, [ | ||||
|                 'data' => $items[0]->getId(), | ||||
|                 'data' => $options['reachable_scopes'][0]->getId(), | ||||
|             ]); | ||||
|             $builder->setDataMapper(new ScopePickerDataMapper($items[0])); | ||||
|             $builder->setDataMapper(new ScopePickerDataMapper($options['reachable_scopes'][0])); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @@ -86,11 +84,13 @@ class ScopePickerType extends AbstractType | ||||
|     public function configureOptions(OptionsResolver $resolver) | ||||
|     { | ||||
|         $resolver | ||||
|           // create `center` option | ||||
|             ->setRequired('center') | ||||
|             ->setAllowedTypes('center', [Center::class, 'array', 'null']) | ||||
|           // create ``role` option | ||||
|             ->setRequired('role') | ||||
|             ->setAllowedTypes('role', ['string']); | ||||
|             ->setRequired('reachable_scopes') | ||||
|             ->setAllowedTypes('reachable_scopes', ['array']); | ||||
|         // create `center` option | ||||
|         //            ->setRequired('center') | ||||
|         //            ->setAllowedTypes('center', [Center::class, 'array', 'null']) | ||||
|         // create ``role` option | ||||
|         //            ->setRequired('role') | ||||
|         //            ->setAllowedTypes('role', ['string']); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -11,7 +11,6 @@ declare(strict_types=1); | ||||
|  | ||||
| namespace Form\Type; | ||||
|  | ||||
| use Chill\MainBundle\Entity\Center; | ||||
| use Chill\MainBundle\Entity\Scope; | ||||
| use Chill\MainBundle\Entity\User; | ||||
| use Chill\MainBundle\Form\Type\ScopePickerType; | ||||
| @@ -42,8 +41,7 @@ final class ScopePickerTypeTest extends TypeTestCase | ||||
|     public function estBuildOneScopeIsSuccessful() | ||||
|     { | ||||
|         $form = $this->factory->create(ScopePickerType::class, null, [ | ||||
|             'center' => new Center(), | ||||
|             'role' => 'ONE_SCOPE', | ||||
|             'reachable_scopes' => [new Scope()], | ||||
|         ]); | ||||
|  | ||||
|         $view = $form->createView(); | ||||
| @@ -54,8 +52,7 @@ final class ScopePickerTypeTest extends TypeTestCase | ||||
|     public function testBuildThreeScopesIsSuccessful() | ||||
|     { | ||||
|         $form = $this->factory->create(ScopePickerType::class, null, [ | ||||
|             'center' => new Center(), | ||||
|             'role' => 'THREE_SCOPE', | ||||
|             'reachable_scopes' => [new Scope(), new Scope(), new Scope()], | ||||
|         ]); | ||||
|  | ||||
|         $view = $form->createView(); | ||||
| @@ -66,8 +63,7 @@ final class ScopePickerTypeTest extends TypeTestCase | ||||
|     public function testBuildTwoScopesIsSuccessful() | ||||
|     { | ||||
|         $form = $this->factory->create(ScopePickerType::class, null, [ | ||||
|             'center' => new Center(), | ||||
|             'role' => 'TWO_SCOPE', | ||||
|             'reachable_scopes' => [new Scope(), new Scope()], | ||||
|         ]); | ||||
|  | ||||
|         $view = $form->createView(); | ||||
|   | ||||
| @@ -127,20 +127,6 @@ duration: | ||||
|             few {# minutes} | ||||
|             other {# minutes} | ||||
|         } | ||||
|     hour: >- | ||||
|         {h, plural, | ||||
|             =0 {Aucune durée} | ||||
|             one {# heure} | ||||
|             few {# heures} | ||||
|             other {# heures} | ||||
|         } | ||||
|     day: >- | ||||
|         {d, plural, | ||||
|             =0 {Aucune durée} | ||||
|             one {# jour} | ||||
|             few {# jours} | ||||
|             other {# jours} | ||||
|         } | ||||
|  | ||||
| filter_order: | ||||
|     by_date: | ||||
|   | ||||
| @@ -67,117 +67,37 @@ const store = useStore(); | ||||
|  | ||||
| const $toast = useToast(); | ||||
|  | ||||
| const timeSpentValues = [ | ||||
|     60, | ||||
|     120, | ||||
|     180, | ||||
|     240, | ||||
|     300, | ||||
|     600, | ||||
|     900, | ||||
|     1200, | ||||
|     1500, | ||||
|     1800, | ||||
|     2700, | ||||
|     3600, | ||||
|     4500, | ||||
|     5400, | ||||
|     6300, | ||||
|     7200, | ||||
|     9000, | ||||
|     10800, | ||||
|     12600, | ||||
|     14400, | ||||
|     16200, | ||||
|     18000, | ||||
|     19800, | ||||
|     21600, | ||||
|     23400, | ||||
|     25200, | ||||
|     27000, | ||||
|     28800, | ||||
|     43200, | ||||
|     57600, | ||||
|     72000, | ||||
|     86400, | ||||
|     100800, | ||||
|     115200, | ||||
|     129600, | ||||
|     144000, // goes from 1 minute to 40 hours | ||||
| const timeSpentChoices = [ | ||||
|     { text: "1 minute", value: 60 }, | ||||
|     { text: "2 minutes", value: 120 }, | ||||
|     { text: "3 minutes", value: 180 }, | ||||
|     { text: "4 minutes", value: 240 }, | ||||
|     { text: "5 minutes", value: 300 }, | ||||
|     { text: "10 minutes", value: 600 }, | ||||
|     { text: "15 minutes", value: 900 }, | ||||
|     { text: "20 minutes", value: 1200 }, | ||||
|     { text: "25 minutes", value: 1500 }, | ||||
|     { text: "30 minutes", value: 1800 }, | ||||
|     { text: "45 minutes", value: 2700 }, | ||||
|     { text: "1 hour", value: 3600 }, | ||||
|     { text: "1 hour 15 minutes", value: 4500 }, | ||||
|     { text: "1 hour 30 minutes", value: 5400 }, | ||||
|     { text: "1 hour 45 minutes", value: 6300 }, | ||||
|     { text: "2 hours", value: 7200 }, | ||||
|     { text: "2 hours 30 minutes", value: 9000 }, | ||||
|     { text: "3 hours", value: 10800 }, | ||||
|     { text: "3 hours 30 minutes", value: 12600 }, | ||||
|     { text: "4 hours", value: 14400 }, | ||||
|     { text: "4 hours 30 minutes", value: 16200 }, | ||||
|     { text: "5 hours", value: 18000 }, | ||||
|     { text: "5 hours 30 minutes", value: 19800 }, | ||||
|     { text: "6 hours", value: 21600 }, | ||||
|     { text: "6 hours 30 minutes", value: 23400 }, | ||||
|     { text: "7 hours", value: 25200 }, | ||||
|     { text: "7 hours 30 minutes", value: 27000 }, | ||||
|     { text: "8 hours", value: 28800 }, | ||||
| ]; | ||||
|  | ||||
| const formatDuration = (seconds, locale) => { | ||||
|     const currentLocale = locale || navigator.language || "fr"; | ||||
|  | ||||
|     const totalHours = Math.floor(seconds / 3600); | ||||
|     const remainingMinutes = Math.floor((seconds % 3600) / 60); | ||||
|  | ||||
|     if (totalHours >= 8) { | ||||
|         const days = Math.floor(totalHours / 8); | ||||
|         const remainingHours = totalHours % 8; | ||||
|  | ||||
|         const parts = []; | ||||
|  | ||||
|         if (days > 0) { | ||||
|             parts.push( | ||||
|                 new Intl.NumberFormat(currentLocale, { | ||||
|                     style: "unit", | ||||
|                     unit: "day", | ||||
|                     unitDisplay: "long", | ||||
|                 }).format(days), | ||||
|             ); | ||||
|         } | ||||
|  | ||||
|         if (remainingHours > 0) { | ||||
|             parts.push( | ||||
|                 new Intl.NumberFormat(currentLocale, { | ||||
|                     style: "unit", | ||||
|                     unit: "hour", | ||||
|                     unitDisplay: "long", | ||||
|                 }).format(remainingHours), | ||||
|             ); | ||||
|         } | ||||
|  | ||||
|         return parts.join(" "); | ||||
|     } | ||||
|  | ||||
|     // For less than 8 hours, use hour and minute format | ||||
|     const parts = []; | ||||
|  | ||||
|     if (totalHours > 0) { | ||||
|         parts.push( | ||||
|             new Intl.NumberFormat(currentLocale, { | ||||
|                 style: "unit", | ||||
|                 unit: "hour", | ||||
|                 unitDisplay: "long", | ||||
|             }).format(totalHours), | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     if (remainingMinutes > 0) { | ||||
|         parts.push( | ||||
|             new Intl.NumberFormat(currentLocale, { | ||||
|                 style: "unit", | ||||
|                 unit: "minute", | ||||
|                 unitDisplay: "long", | ||||
|             }).format(remainingMinutes), | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     console.log(parts); | ||||
|     console.log(parts.join(" ")); | ||||
|  | ||||
|     return parts.join(" "); | ||||
| }; | ||||
|  | ||||
| const timeSpentChoices = computed(() => { | ||||
|     const locale = "fr"; | ||||
|     return timeSpentValues.map((value) => ({ | ||||
|         text: formatDuration(value, locale), | ||||
|         value: parseInt(value), | ||||
|     })); | ||||
| }); | ||||
|  | ||||
| const startDate = computed({ | ||||
|     get() { | ||||
|         return props.evaluation.startDate; | ||||
| @@ -274,7 +194,7 @@ function updateWarningInterval(value) { | ||||
| } | ||||
|  | ||||
| function updateTimeSpent(value) { | ||||
|     timeSpent.value = parseInt(value); | ||||
|     timeSpent.value = value; | ||||
| } | ||||
|  | ||||
| function updateComment(value) { | ||||
|   | ||||
| @@ -216,29 +216,9 @@ | ||||
|  | ||||
|                                     {% if e.timeSpent is not null and e.timeSpent > 0 %} | ||||
|                                         <li> | ||||
|                                             {% set totalHours = (e.timeSpent / 3600)|round(0, 'floor') %} | ||||
|                                             {% set totalMinutes = ((e.timeSpent % 3600) / 60)|round(0, 'floor') %} | ||||
|  | ||||
|                                             <span class="item-key">{{ 'accompanying_course_work.timeSpent'|trans ~ ' : ' }}</span> | ||||
|  | ||||
|                                             {% if totalHours >= 8 %} | ||||
|                                                 {% set days = (totalHours / 8)|round(0, 'floor') %} | ||||
|                                                 {% set remainingHours = totalHours % 8 %} | ||||
|  | ||||
|                                                 {% if days > 0 %} | ||||
|                                                     {{ 'duration.day'|trans({ '{d}' : days }) }} | ||||
|                                                 {% endif %} | ||||
|                                                 {% if remainingHours > 0 %} | ||||
|                                                     {{ 'duration.hour'|trans({ '{h}' : remainingHours }) }} | ||||
|                                                 {% endif %} | ||||
|                                             {% else %} | ||||
|                                                 {% if totalHours > 0 %} | ||||
|                                                     {{ 'duration.hour'|trans({ '{h}' : totalHours }) }} | ||||
|                                                 {% endif %} | ||||
|                                                 {% if totalMinutes > 0 %} | ||||
|                                                     {{ 'duration.minute'|trans({ '{m}' : totalMinutes }) }} | ||||
|                                                 {% endif %} | ||||
|                                             {% endif %} | ||||
|                                             {% set minutes = (e.timeSpent / 60) %} | ||||
|                                             <span | ||||
|                                                 class="item-key">{{ 'accompanying_course_work.timeSpent'|trans ~ ' : ' }}</span> {{ 'duration.minute'|trans({ '{m}' : minutes }) }} | ||||
|                                         </li> | ||||
|                                     {% elseif displayContent is defined and displayContent == 'long' %} | ||||
|                                         <li> | ||||
|   | ||||
| @@ -167,10 +167,20 @@ final readonly class PersonContext implements PersonContextInterface | ||||
|         } | ||||
|  | ||||
|         if ($this->isScopeNecessary($entity)) { | ||||
|             $reachableScopes = array_values( | ||||
|                 array_filter( | ||||
|                     $this->authorizationHelper->getReachableScopes( | ||||
|                         $this->security->getUser(), | ||||
|                         PersonDocumentVoter::CREATE, | ||||
|                         $this->centerResolverManager->resolveCenters($entity) | ||||
|                     ), | ||||
|                     static fn (Scope $s) => $s->isActive() | ||||
|                 ) | ||||
|             ); | ||||
|  | ||||
|             $builder->add('scope', ScopePickerType::class, [ | ||||
|                 'center' => $this->centerResolverManager->resolveCenters($entity), | ||||
|                 'role' => PersonDocumentVoter::CREATE, | ||||
|                 'label' => 'Scope', | ||||
|                 'reachable_scopes' => $reachableScopes, | ||||
|                 'label' => count($reachableScopes) > 1 ? 'Scope' : false, | ||||
|             ]); | ||||
|         } | ||||
|     } | ||||
|   | ||||
| @@ -11,11 +11,13 @@ declare(strict_types=1); | ||||
|  | ||||
| namespace Chill\TaskBundle\Form; | ||||
|  | ||||
| use Chill\MainBundle\Entity\Scope; | ||||
| use Chill\MainBundle\Form\Type\ChillDateType; | ||||
| use Chill\MainBundle\Form\Type\ChillTextareaType; | ||||
| use Chill\MainBundle\Form\Type\DateIntervalType; | ||||
| use Chill\MainBundle\Form\Type\ScopePickerType; | ||||
| use Chill\MainBundle\Form\Type\UserPickerType; | ||||
| use Chill\MainBundle\Security\Authorization\AuthorizationHelperInterface; | ||||
| use Chill\MainBundle\Security\Resolver\CenterResolverDispatcherInterface; | ||||
| use Chill\MainBundle\Security\Resolver\ScopeResolverDispatcher; | ||||
| use Chill\TaskBundle\Security\Authorization\TaskVoter; | ||||
| @@ -24,10 +26,18 @@ use Symfony\Component\Form\AbstractType; | ||||
| use Symfony\Component\Form\Extension\Core\Type\TextType; | ||||
| use Symfony\Component\Form\FormBuilderInterface; | ||||
| use Symfony\Component\OptionsResolver\OptionsResolver; | ||||
| use Symfony\Component\Security\Core\Security; | ||||
| use Symfony\Contracts\Translation\TranslatorInterface; | ||||
|  | ||||
| class SingleTaskType extends AbstractType | ||||
| { | ||||
|     public function __construct(private readonly ParameterBagInterface $parameterBag, private readonly CenterResolverDispatcherInterface $centerResolverDispatcher, private readonly ScopeResolverDispatcher $scopeResolverDispatcher) {} | ||||
|     public function __construct( | ||||
|         private readonly ParameterBagInterface $parameterBag, | ||||
|         private readonly CenterResolverDispatcherInterface $centerResolverDispatcher, | ||||
|         private readonly Security $security, | ||||
|         private readonly AuthorizationHelperInterface $authorizationHelper, | ||||
|         private readonly ScopeResolverDispatcher $scopeResolverDispatcher, | ||||
|     ) {} | ||||
|  | ||||
|     public function buildForm(FormBuilderInterface $builder, array $options) | ||||
|     { | ||||
| @@ -62,11 +72,22 @@ class SingleTaskType extends AbstractType | ||||
|             ]); | ||||
|  | ||||
|         if ($isScopeConcerned && $this->parameterBag->get('chill_main')['acl']['form_show_scopes']) { | ||||
|             $reachableScopes = array_values( | ||||
|                 array_filter( | ||||
|                     $this->authorizationHelper->getReachableScopes( | ||||
|                         $this->security->getUser(), | ||||
|                         $options['role'], | ||||
|                         $center | ||||
|                     ), | ||||
|                     static fn (Scope $s) => $s->isActive() | ||||
|                 ) | ||||
|             ); | ||||
|  | ||||
|             $builder | ||||
|                 ->add('circle', ScopePickerType::class, [ | ||||
|                     'center' => $center, | ||||
|                     'role' => $options['role'], | ||||
|                     'reachable_scopes' => $reachableScopes, | ||||
|                     'required' => true, | ||||
|                     'label' => count($reachableScopes) > 1 ? 'Scope' : false, | ||||
|                 ]); | ||||
|         } | ||||
|     } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user