diff --git a/src/Bundle/ChillMainBundle/DependencyInjection/ChillMainExtension.php b/src/Bundle/ChillMainBundle/DependencyInjection/ChillMainExtension.php index bf041b5b3..4dde2076c 100644 --- a/src/Bundle/ChillMainBundle/DependencyInjection/ChillMainExtension.php +++ b/src/Bundle/ChillMainBundle/DependencyInjection/ChillMainExtension.php @@ -193,11 +193,6 @@ class ChillMainExtension extends Extension implements [] ); - $container->setParameter( - 'chill_main.id_document_kinds', - $config['id_document_kinds'] - ); - $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../config')); $loader->load('services.yaml'); $loader->load('services/doctrine.yaml'); diff --git a/src/Bundle/ChillMainBundle/DependencyInjection/Configuration.php b/src/Bundle/ChillMainBundle/DependencyInjection/Configuration.php index 9c890d9fe..16130f193 100644 --- a/src/Bundle/ChillMainBundle/DependencyInjection/Configuration.php +++ b/src/Bundle/ChillMainBundle/DependencyInjection/Configuration.php @@ -85,6 +85,29 @@ class Configuration implements ConfigurationInterface ->end() ->end() ->end() // end of notifications + ->arrayNode('workflow_signature') + ->children() + ->arrayNode('base_signer') + ->children() + ->arrayNode('document_kinds') + ->arrayPrototype() + ->children() + ->scalarNode('key')->cannotBeEmpty()->end() + ->arrayNode('labels') + ->arrayPrototype() + ->children() + ->scalarNode('lang')->cannotBeEmpty()->end() + ->scalarNode('label')->cannotBeEmpty()->end() + ->end() + ->end() + ->end() + ->end() + ->end() + ->end() + ->end() + ->end() + ->end() + ->end() // end of workflow signature document types ->arrayNode('phone_helper') ->canBeUnset() ->children() @@ -151,28 +174,6 @@ class Configuration implements ConfigurationInterface ->append($this->addWidgetsConfiguration('homepage', $this->containerBuilder)) ->end() // end of widgets/children ->end() // end of widgets - ->arrayNode('id_document_kinds')->defaultValue([]) - ->arrayPrototype() - ->children() - ->scalarNode('key')->isRequired()->cannotBeEmpty() - ->info('the key stored in database') - ->example('id_card') - ->end() - ->arrayNode('labels')->isRequired()->requiresAtLeastOneElement() - ->arrayPrototype() - ->children() - ->scalarNode('lang')->isRequired()->cannotBeEmpty() - ->example('fr') - ->end() - ->scalarNode('label')->isRequired()->cannotBeEmpty() - ->example('Carte de séjour') - ->end() - ->end() - ->end() - ->end() - ->end() - ->end() - ->end() // end of document types ->arrayNode('cruds') ->defaultValue([]) ->arrayPrototype() diff --git a/src/Bundle/ChillMainBundle/Form/WorkflowSignatureMetadataType.php b/src/Bundle/ChillMainBundle/Form/WorkflowSignatureMetadataType.php index 47be9b88c..114a462f6 100644 --- a/src/Bundle/ChillMainBundle/Form/WorkflowSignatureMetadataType.php +++ b/src/Bundle/ChillMainBundle/Form/WorkflowSignatureMetadataType.php @@ -25,7 +25,7 @@ class WorkflowSignatureMetadataType extends AbstractType public function buildForm(FormBuilderInterface $builder, array $options): void { - $documentTypeChoices = $this->parameterBag->get('chill_main.id_document_kinds'); + $documentTypeChoices = $this->parameterBag->get('chill_main')['workflow_signature']['base_signer']['document_kinds']; $choices = []; diff --git a/src/Bundle/ChillMainBundle/Form/WorkflowStepType.php b/src/Bundle/ChillMainBundle/Form/WorkflowStepType.php index 284781d54..a113c62c5 100644 --- a/src/Bundle/ChillMainBundle/Form/WorkflowStepType.php +++ b/src/Bundle/ChillMainBundle/Form/WorkflowStepType.php @@ -17,6 +17,7 @@ use Chill\MainBundle\Form\Type\ChillTextareaType; use Chill\MainBundle\Form\Type\PickUserDynamicType; use Chill\MainBundle\Templating\TranslatableStringHelperInterface; use Chill\MainBundle\Workflow\WorkflowTransitionContextDTO; +use Chill\PersonBundle\Form\Type\PickPersonDynamicType; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Extension\Core\Type\ChoiceType; use Symfony\Component\Form\Extension\Core\Type\EmailType; @@ -102,6 +103,7 @@ class WorkflowStepType extends AbstractType 'choice_attr' => static function (Transition $transition) use ($workflow) { $toFinal = true; $isForward = 'neutral'; + $isSignature = []; $metadata = $workflow->getMetadataStore()->getTransitionMetadata($transition); @@ -121,18 +123,43 @@ class WorkflowStepType extends AbstractType ) { $toFinal = false; } + + if (\array_key_exists('isSignature', $meta)) { + $isSignature = $meta['isSignature']; + } } return [ 'data-is-transition' => 'data-is-transition', 'data-to-final' => $toFinal ? '1' : '0', 'data-is-forward' => $isForward, + 'data-is-signature' => json_encode($isSignature), ]; }, ]) + ->add('isPersonOrUserSignature', ChoiceType::class, [ + 'mapped' => false, + 'multiple' => false, + 'expanded' => true, + 'label' => 'workflow.signature_zone.type of signature', + 'choices' => [ + 'workflow.signature_zone.persons' => 'person', + 'workflow.signature_zone.user' => 'user', + ], + ]) + ->add('futurePersonSignatures', PickPersonDynamicType::class, [ + 'label' => 'workflow.signature_zone.person signatures', + 'multiple' => true, + 'empty_data' => '[]', + ]) + ->add('futureUserSignature', PickUserDynamicType::class, [ + 'label' => 'workflow.signature_zone.user signature', + 'multiple' => false, + ]) ->add('futureDestUsers', PickUserDynamicType::class, [ 'label' => 'workflow.dest for next steps', 'multiple' => true, + 'empty_data' => '[]', 'suggested' => $options['suggested_users'], ]) ->add('futureCcUsers', PickUserDynamicType::class, [ @@ -140,6 +167,8 @@ class WorkflowStepType extends AbstractType 'multiple' => true, 'required' => false, 'suggested' => $options['suggested_users'], + 'empty_data' => '[]', + 'attr' => ['class' => 'future-cc-users'], ]) ->add('futureDestEmails', ChillCollectionType::class, [ 'label' => 'workflow.dest by email', diff --git a/src/Bundle/ChillMainBundle/Resources/public/page/workflow-show/index.js b/src/Bundle/ChillMainBundle/Resources/public/page/workflow-show/index.js index 2f91c7777..1536417b1 100644 --- a/src/Bundle/ChillMainBundle/Resources/public/page/workflow-show/index.js +++ b/src/Bundle/ChillMainBundle/Resources/public/page/workflow-show/index.js @@ -4,38 +4,124 @@ window.addEventListener('DOMContentLoaded', function() { let divTransitions = document.querySelector('#transitions'), futureDestUsersContainer = document.querySelector('#futureDests') - ; - - if (null !== divTransitions) { - new ShowHide({ - load_event: null, - froms: [divTransitions], - container: [futureDestUsersContainer], - test: function(divs, arg2, arg3) { - for (let div of divs) { - for (let input of div.querySelectorAll('input')) { - if (input.checked) { - if (input.dataset.toFinal === "1") { - return false; - } else { - return true; - } - } - } - } - - return true; - }, - }); - } + personSignatureField = document.querySelector('#person-signature-field'); + userSignatureField = document.querySelector('#user-signature-field'); + signatureTypeChoices = document.querySelector('#signature-type-choice'); + personChoice = document.querySelector('#workflow_step_isPersonOrUserSignature_0'); + userChoice = document.querySelector('#workflow_step_isPersonOrUserSignature_1'); + signatureZone = document.querySelector('#signature-zone'); + ; let - transitionFilterContainer = document.querySelector('#transitionFilter'), - transitions = document.querySelector('#transitions') + transitionFilterContainer = document.querySelector('#transitionFilter'), + transitionsContainer = document.querySelector('#transitions') ; + // ShowHide instance for signatureTypeChoices. This should always be present in the DOM and we toggle visibility. + // The field is not mapped and so not submitted with the form. Without it's presence upon DOM loading other show hides do not function well. + signatureTypeChoices.style.display = 'none'; + + + // ShowHide instance for future dest users + new ShowHide({ + debug: false, + load_event: null, + froms: [divTransitions], + container: [futureDestUsersContainer], + test: function(froms, event) { + for (let transition of froms) { + for (let input of transition.querySelectorAll('input')) { + if (input.checked) { + const inputData = JSON.parse(input.getAttribute('data-is-signature')) + if (inputData.includes('person') || inputData.includes('user')) { + signatureTypeChoices.style.display = ''; + return false; + } else { + personChoice.checked = false + userChoice.checked = false + + signatureTypeChoices.style.display = 'none'; + return true; + } + } + } + } + return false; + } + }); + + // ShowHide signature zone + new ShowHide({ + debug: false, + load_event: null, + froms: [divTransitions], + container: [signatureZone], + test: function(froms, event) { + for (let transition of froms) { + for (let input of transition.querySelectorAll('input')) { + if (input.checked) { + const inputData = JSON.parse(input.getAttribute('data-is-signature')) + if (inputData.includes('person') || inputData.includes('user')) { + signatureTypeChoices.style.display = ''; + return true; + } + } + } + } + return false; + } + }); + + // ShowHides for personSignatureField or userSignatureField within signature zone + new ShowHide({ + debug: false, + froms: [signatureTypeChoices], + container: [personSignatureField], + test: function(froms, event) { + for (let container of froms) { + return personChoice.checked; + } + return false; + }, + }); + + new ShowHide({ + debug: false, + froms: [signatureTypeChoices], + container: [userSignatureField], + test: function(froms, event) { + for (let container of froms) { + return userChoice.checked; + } + return false; + }, + }); + + if (null !== divTransitions) { + new ShowHide({ + load_event: null, + froms: [divTransitions], + container: [futureDestUsersContainer], + test: function(divs, arg2, arg3) { + for (let div of divs) { + for (let input of div.querySelectorAll('input')) { + if (input.checked) { + if (input.dataset.toFinal === "1") { + return false; + } else { + return true; + } + } + } + } + + return true; + }, + }); + } + if (null !== transitionFilterContainer) { - transitions.querySelectorAll('.form-check').forEach(function(row) { + transitionsContainer.querySelectorAll('.form-check').forEach(function(row) { const isForward = row.querySelector('input').dataset.isForward; @@ -66,5 +152,4 @@ window.addEventListener('DOMContentLoaded', function() { }); }); } - }); diff --git a/src/Bundle/ChillMainBundle/Resources/views/Workflow/_decision.html.twig b/src/Bundle/ChillMainBundle/Resources/views/Workflow/_decision.html.twig index 35f587e38..ac85525a6 100644 --- a/src/Bundle/ChillMainBundle/Resources/views/Workflow/_decision.html.twig +++ b/src/Bundle/ChillMainBundle/Resources/views/Workflow/_decision.html.twig @@ -58,15 +58,34 @@ {{ form_row(transition_form.transition) }} +
+
+ {{ form_row(transition_form.isPersonOrUserSignature) }} + {{ form_errors(transition_form.isPersonOrUserSignature) }} +
+
+ {{ form_row(transition_form.futureUserSignature) }} + {{ form_errors(transition_form.futureUserSignature) }} +
+
+ {{ form_row(transition_form.futurePersonSignatures) }} + {{ form_errors(transition_form.futurePersonSignatures) }} +
+
+
+
{{ form_row(transition_form.futureDestUsers) }} {{ form_errors(transition_form.futureDestUsers) }} - +
+
{{ form_row(transition_form.futureCcUsers) }} {{ form_errors(transition_form.futureCcUsers) }} - +
+
{{ form_row(transition_form.futureDestEmails) }} {{ form_errors(transition_form.futureDestEmails) }} +

{{ form_label(transition_form.comment) }}

diff --git a/src/Bundle/ChillMainBundle/translations/messages.fr.yml b/src/Bundle/ChillMainBundle/translations/messages.fr.yml index 924ccec3a..9a90b7fa1 100644 --- a/src/Bundle/ChillMainBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillMainBundle/translations/messages.fr.yml @@ -536,6 +536,11 @@ workflow: docType: Type de document docNumber: Numéro de document docExpiration: Date d'expiration + type of signature: Type de signature + person signatures: Selectionner usagers pour signer + user signature: Selectionner utilisateur pour signer + persons: Usagers + user: Utilisateur Subscribe final: Recevoir une notification à l'étape finale