mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
Merge branch 'foldlist_in_entity' of gitlab.com:Chill-Projet/chill-bundles into foldlist_in_entity
This commit is contained in:
commit
932d0e86d9
@ -25,6 +25,7 @@ use Iterator;
|
||||
use RuntimeException;
|
||||
use Symfony\Component\Serializer\Annotation as Serializer;
|
||||
use function count;
|
||||
use function is_array;
|
||||
|
||||
/**
|
||||
* @ORM\Entity
|
||||
@ -51,7 +52,6 @@ class EntityWorkflow implements TrackCreationInterface, TrackUpdateInterface
|
||||
* @ORM\Id
|
||||
* @ORM\GeneratedValue
|
||||
* @ORM\Column(type="integer")
|
||||
* @Serializer\Groups({"read"})
|
||||
*/
|
||||
private ?int $id = null;
|
||||
|
||||
@ -73,6 +73,11 @@ class EntityWorkflow implements TrackCreationInterface, TrackUpdateInterface
|
||||
*/
|
||||
private Collection $steps;
|
||||
|
||||
/**
|
||||
* @var null|array|EntityWorkflowStep[]
|
||||
*/
|
||||
private ?array $stepsChainedCache = null;
|
||||
|
||||
/**
|
||||
* @ORM\ManyToMany(targetEntity=User::class)
|
||||
* @ORM\JoinTable(name="chill_main_workflow_entity_subscriber_to_final")
|
||||
@ -130,10 +135,6 @@ class EntityWorkflow implements TrackCreationInterface, TrackUpdateInterface
|
||||
if (!$this->steps->contains($step)) {
|
||||
$this->steps[] = $step;
|
||||
$step->setEntityWorkflow($this);
|
||||
|
||||
if ($this->isFinalize()) {
|
||||
$step->setFinalizeAfter(true);
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
@ -254,27 +255,33 @@ class EntityWorkflow implements TrackCreationInterface, TrackUpdateInterface
|
||||
|
||||
public function getStepsChained(): array
|
||||
{
|
||||
if (is_array($this->stepsChainedCache)) {
|
||||
return $this->stepsChainedCache;
|
||||
}
|
||||
|
||||
$iterator = $this->steps->getIterator();
|
||||
$previous = $next = $current = null;
|
||||
$current = null;
|
||||
$steps = [];
|
||||
|
||||
$iterator->rewind();
|
||||
|
||||
while ($iterator->valid()) {
|
||||
do {
|
||||
$previous = $current;
|
||||
$steps[] = $current = $iterator->current();
|
||||
$current = $iterator->current();
|
||||
$steps[] = $current;
|
||||
|
||||
$current->setPrevious($previous);
|
||||
|
||||
$iterator->next();
|
||||
|
||||
if ($iterator->valid()) {
|
||||
$next = $iterator->current();
|
||||
$current->setNext($iterator->current());
|
||||
} else {
|
||||
$next = null;
|
||||
$current->setNext(null);
|
||||
}
|
||||
} while ($iterator->valid());
|
||||
|
||||
$current->setNext($next);
|
||||
}
|
||||
$this->stepsChainedCache = $steps;
|
||||
|
||||
return $steps;
|
||||
}
|
||||
@ -309,7 +316,7 @@ class EntityWorkflow implements TrackCreationInterface, TrackUpdateInterface
|
||||
return $this->workflowName;
|
||||
}
|
||||
|
||||
public function isFinalize(): bool
|
||||
public function isFinal(): bool
|
||||
{
|
||||
$steps = $this->getStepsChained();
|
||||
|
||||
@ -321,7 +328,7 @@ class EntityWorkflow implements TrackCreationInterface, TrackUpdateInterface
|
||||
/** @var EntityWorkflowStep $last */
|
||||
$last = end($steps);
|
||||
|
||||
return $last->getPrevious()->isFinalizeAfter();
|
||||
return $last->isFinal();
|
||||
}
|
||||
|
||||
public function isFreeze(): bool
|
||||
|
@ -53,11 +53,6 @@ class EntityWorkflowStep
|
||||
*/
|
||||
private ?EntityWorkflow $entityWorkflow = null;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="boolean", options={"default": false})
|
||||
*/
|
||||
private bool $finalizeAfter = false;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="boolean", options={"default": false})
|
||||
*/
|
||||
@ -70,6 +65,11 @@ class EntityWorkflowStep
|
||||
*/
|
||||
private ?int $id = null;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="boolean", options={"default": false})
|
||||
*/
|
||||
private bool $isFinal = false;
|
||||
|
||||
/**
|
||||
* filled by @see{EntityWorkflow::getStepsChained}.
|
||||
*/
|
||||
@ -187,9 +187,9 @@ class EntityWorkflowStep
|
||||
return $this->transitionByEmail;
|
||||
}
|
||||
|
||||
public function isFinalizeAfter(): bool
|
||||
public function isFinal(): bool
|
||||
{
|
||||
return $this->finalizeAfter;
|
||||
return $this->isFinal;
|
||||
}
|
||||
|
||||
public function isFreezeAfter(): bool
|
||||
@ -244,16 +244,16 @@ class EntityWorkflowStep
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setFinalizeAfter(bool $finalizeAfter): EntityWorkflowStep
|
||||
public function setFreezeAfter(bool $freezeAfter): EntityWorkflowStep
|
||||
{
|
||||
$this->finalizeAfter = $finalizeAfter;
|
||||
$this->freezeAfter = $freezeAfter;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setFreezeAfter(bool $freezeAfter): EntityWorkflowStep
|
||||
public function setIsFinal(bool $isFinal): EntityWorkflowStep
|
||||
{
|
||||
$this->freezeAfter = $freezeAfter;
|
||||
$this->isFinal = $isFinal;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
@ -15,6 +15,7 @@ use Chill\MainBundle\Entity\Workflow\EntityWorkflow;
|
||||
use Chill\MainBundle\Entity\Workflow\EntityWorkflowStep;
|
||||
use Chill\MainBundle\Form\Type\ChillTextareaType;
|
||||
use Chill\MainBundle\Form\Type\PickUserDynamicType;
|
||||
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
|
||||
use Chill\MainBundle\Workflow\EntityWorkflowManager;
|
||||
use LogicException;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
@ -24,6 +25,7 @@ use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
use Symfony\Component\Workflow\Registry;
|
||||
use Symfony\Component\Workflow\Transition;
|
||||
use function array_key_exists;
|
||||
|
||||
class WorkflowStepType extends AbstractType
|
||||
{
|
||||
@ -31,10 +33,13 @@ class WorkflowStepType extends AbstractType
|
||||
|
||||
private Registry $registry;
|
||||
|
||||
public function __construct(EntityWorkflowManager $entityWorkflowManager, Registry $registry)
|
||||
private TranslatableStringHelperInterface $translatableStringHelper;
|
||||
|
||||
public function __construct(EntityWorkflowManager $entityWorkflowManager, Registry $registry, TranslatableStringHelperInterface $translatableStringHelper)
|
||||
{
|
||||
$this->entityWorkflowManager = $entityWorkflowManager;
|
||||
$this->registry = $registry;
|
||||
$this->translatableStringHelper = $translatableStringHelper;
|
||||
}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||
@ -42,6 +47,7 @@ class WorkflowStepType extends AbstractType
|
||||
/** @var \Chill\MainBundle\Entity\Workflow\EntityWorkflow $entityWorkflow */
|
||||
$entityWorkflow = $options['entity_workflow'];
|
||||
$handler = $this->entityWorkflowManager->getHandler($entityWorkflow);
|
||||
$workflow = $this->registry->get($entityWorkflow, $entityWorkflow->getWorkflowName());
|
||||
|
||||
if (true === $options['transition']) {
|
||||
if (null === $options['entity_workflow']) {
|
||||
@ -53,20 +59,49 @@ class WorkflowStepType extends AbstractType
|
||||
->getEnabledTransitions($entityWorkflow);
|
||||
|
||||
$choices = array_combine(
|
||||
array_map(static function (Transition $transition) { return $transition->getName(); }, $transitions),
|
||||
array_map(
|
||||
static function (Transition $transition) {
|
||||
return $transition->getName();
|
||||
},
|
||||
$transitions
|
||||
),
|
||||
$transitions
|
||||
);
|
||||
|
||||
$builder
|
||||
->add('transition', ChoiceType::class, [
|
||||
'label' => 'workflow.Transition',
|
||||
'label' => 'workflow.Transition to apply',
|
||||
'mapped' => false,
|
||||
'multiple' => false,
|
||||
'expanded' => true,
|
||||
'choices' => $choices,
|
||||
'choice_label' => static function (Transition $transition) {
|
||||
return implode(', ', $transition->getTos());
|
||||
},
|
||||
'choice_label' => function (Transition $transition) use ($workflow) {
|
||||
$meta = $workflow->getMetadataStore()->getTransitionMetadata($transition);
|
||||
|
||||
if (array_key_exists('label', $meta)) {
|
||||
return $this->translatableStringHelper->localize($meta['label']);
|
||||
}
|
||||
|
||||
return $transition->getName();
|
||||
},
|
||||
'choice_attr' => static function (Transition $transition) use ($workflow) {
|
||||
$toFinal = true;
|
||||
|
||||
foreach ($transition->getTos() as $to) {
|
||||
$meta = $workflow->getMetadataStore()->getPlaceMetadata($to);
|
||||
|
||||
if (
|
||||
!array_key_exists('isFinal', $meta) || false === $meta['isFinal']
|
||||
) {
|
||||
$toFinal = false;
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
'data-is-transition' => 'data-is-transition',
|
||||
'data-to-final' => $toFinal ? '1' : '0',
|
||||
];
|
||||
},
|
||||
])
|
||||
->add('future_dest_users', PickUserDynamicType::class, [
|
||||
'label' => 'workflow.dest for next steps',
|
||||
@ -88,11 +123,6 @@ class WorkflowStepType extends AbstractType
|
||||
}
|
||||
|
||||
$builder
|
||||
->add('finalizeAfter', CheckboxType::class, [
|
||||
'required' => false,
|
||||
'label' => 'workflow.Finalize',
|
||||
'help' => 'workflow.The workflow will be finalized',
|
||||
])
|
||||
->add('comment', ChillTextareaType::class, [
|
||||
'required' => false,
|
||||
'label' => 'Comment',
|
||||
|
@ -5,6 +5,19 @@
|
||||
</div>
|
||||
<div class="list-group-item" v-for="w in workflows">
|
||||
{{ w.id }}
|
||||
|
||||
Etape actuelle: {{ w.currentStep.currentStep.text }}
|
||||
|
||||
<ul>
|
||||
<li v-for="w in w.steps">
|
||||
Etape: {{ w.currentStep.text }},
|
||||
<span v-if="w.transitionPrevious != null">
|
||||
transition pour arriver à cette étape : {{ w.transitionPrevious.text }},
|
||||
par: {{ w.transitionPreviousBy.text }}, le {{ w.transitionPreviousAt.datetime }}
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<ul class="record_actions">
|
||||
<li>
|
||||
<a class="btn btn-sm btn-outline-primary"
|
||||
@ -33,4 +46,4 @@ export default {
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</script>
|
||||
|
@ -5,14 +5,10 @@
|
||||
|
||||
{{ form_row(transition_form.transition) }}
|
||||
|
||||
<div id="finalizeAfter">
|
||||
{{ form_row(transition_form.finalizeAfter) }}
|
||||
</div>
|
||||
|
||||
{% if transition_form.freezeAfter is defined %}
|
||||
{{ form_row(transition_form.freezeAfter) }}
|
||||
{% endif %}
|
||||
|
||||
|
||||
<div id="futureDestUsers">
|
||||
{{ form_row(transition_form.future_dest_users) }}
|
||||
</div>
|
||||
@ -31,7 +27,7 @@
|
||||
{% else %}
|
||||
<div class="alert alert-chill-yellow">
|
||||
|
||||
{% if entity_workflow.currentStep.isFinalizeAfter %}
|
||||
{% if entity_workflow.currentStep.isFinal %}
|
||||
<p>{{ 'workflow.This workflow is finalized'|trans }}</p>
|
||||
{% else %}
|
||||
<p>{{ 'workflow.You are not allowed to apply a transition on this workflow'|trans }}</p>
|
||||
|
@ -2,15 +2,18 @@
|
||||
|
||||
<div class="flex-table">
|
||||
{% for step in entity_workflow.stepsChained %}
|
||||
{% set place_labels = workflow_metadata(entity_workflow, 'label', step.currentStep) %}
|
||||
{% set place_label = place_labels is null ? step.currentStep : place_labels|localize_translatable_string %}
|
||||
|
||||
<div class="item-bloc {{ 'bloc' ~ step.id }} {% if loop.first %}initial{% endif %}">
|
||||
<div class="item-row">
|
||||
|
||||
|
||||
{% if loop.first and step.next is null %}
|
||||
<div class="item-col">
|
||||
{{ 'workflow.No transitions'|trans }}
|
||||
</div>
|
||||
{% else %}
|
||||
|
||||
|
||||
<div class="item-col">
|
||||
{% if step.previous is not null and step.previous.freezeAfter == true %}
|
||||
<i class="fa fa-snowflake-o fa-sm me-1" title="{{ 'workflow.Freezed'|trans }}"></i>
|
||||
@ -18,10 +21,7 @@
|
||||
</div>
|
||||
<div class="item-col flex-column align-items-end">
|
||||
<div class="decided">
|
||||
{% if not loop.first %}
|
||||
<i class="fa fa-check fa-fw text-success"></i>
|
||||
{% endif %}
|
||||
{{ step.currentStep }}
|
||||
{{ place_label }}
|
||||
</div>
|
||||
{#
|
||||
<div class="decided">
|
||||
@ -31,9 +31,13 @@
|
||||
#}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
|
||||
</div>
|
||||
{% if step.next is not null %}
|
||||
{% set transition = chill_workflow_transition_by_string(step.entityWorkflow, step.transitionAfter) %}
|
||||
{% set transition_labels = workflow_metadata(step.entityWorkflow, 'label', transition) %}
|
||||
{% set transition_label = transition_labels is null ? step.transitionAfter : transition_labels|localize_translatable_string %}
|
||||
{% set forward = workflow_metadata(step.entityWorkflow, 'isForward', transition) %}
|
||||
<div class="item-row separator">
|
||||
<div class="item-col" style="width: inherit;">
|
||||
{% if step.transitionBy is not null %}
|
||||
@ -48,7 +52,12 @@
|
||||
<div class="item-col flex-column align-items-end">
|
||||
<div class="to-decision">
|
||||
<i class="fa fa-share fa-fw text-secondary" title="transféré"></i>
|
||||
{{ step.next.currentStep }}
|
||||
{% if forward %}
|
||||
<i class="fa fa-check fa-fw text-success"></i>
|
||||
{% else %}
|
||||
<i class="fa fa-times fa-fw text-danger"></i>
|
||||
{% endif %}
|
||||
{{ transition_label }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,13 +1,24 @@
|
||||
{% macro popoverContent(step) %}
|
||||
<ul class="small_in_title">
|
||||
<li>
|
||||
<span class="item-key">{{ 'By'|trans ~ ' : ' }}</span>
|
||||
<b>{{ step.transitionBy|chill_entity_render_box }}</b>
|
||||
</li>
|
||||
<li>
|
||||
<span class="item-key">{{ 'Le'|trans ~ ' : ' }}</span>
|
||||
<b>{{ step.transitionAt|format_datetime('short', 'short') }}</b>
|
||||
</li>
|
||||
{% if step.previous is not null %}
|
||||
<li>
|
||||
<span class="item-key">{{ 'By'|trans ~ ' : ' }}</span>
|
||||
<b>{{ step.previous.transitionBy|chill_entity_render_box }}</b>
|
||||
</li>
|
||||
<li>
|
||||
<span class="item-key">{{ 'Le'|trans ~ ' : ' }}</span>
|
||||
<b>{{ step.previous.transitionAt|format_datetime('short', 'short') }}</b>
|
||||
</li>
|
||||
{% else %}
|
||||
<li>
|
||||
<span class="item-key">{{ 'workflow.Created by'|trans ~ ' : ' }}</span>
|
||||
<b>{{ step.entityWorkflow.createdBy|chill_entity_render_box }}</b>
|
||||
</li>
|
||||
<li>
|
||||
<span class="item-key">{{ 'Le'|trans ~ ' : ' }}</span>
|
||||
<b>{{ step.entityWorkflow.createdAt|format_datetime('short', 'short') }}</b>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
{% endmacro %}
|
||||
|
||||
@ -15,18 +26,21 @@
|
||||
{% if step.previous is not null and step.previous.freezeAfter == true %}
|
||||
<i class="fa fa-snowflake-o fa-sm me-1" title="{{ 'workflow.Freezed'|trans }}"></i>
|
||||
{% endif %}
|
||||
{{ step.currentStep }}
|
||||
{% if step.previous is not null %}
|
||||
{% set transition = chill_workflow_transition_by_string(step.entityWorkflow, step.previous.transitionAfter) %}
|
||||
{% set labels = workflow_metadata(step.entityWorkflow, 'label', transition) %}
|
||||
{% set label = labels is null ? step.previous.transitionAfter : labels|localize_translatable_string %}
|
||||
{{ label }}
|
||||
{% endif %}
|
||||
{% endmacro %}
|
||||
|
||||
{% macro breadcrumb(_ctx) %}
|
||||
<div class="breadcrumb">
|
||||
{% for step in _ctx.entity_workflow.stepsChained %}
|
||||
{% set labels = workflow_metadata(_ctx.entity_workflow, 'label', step.currentStep) %}
|
||||
{% set label = labels is null ? step.currentStep : labels|localize_translatable_string %}
|
||||
{% set popTitle = _self.popoverTitle(step) %}
|
||||
{% if step.previous is null %}
|
||||
{% set popContent = _self.popoverContent(step) %}
|
||||
{% else %}
|
||||
{% set popContent = _self.popoverContent(step.previous) %}
|
||||
{% endif %}
|
||||
{% set popContent = _self.popoverContent(step) %}
|
||||
<span class="mx-2"
|
||||
tabindex="0"
|
||||
data-bs-trigger="focus hover"
|
||||
@ -42,7 +56,7 @@
|
||||
{% if step.previous is not null and step.previous.freezeAfter == true %}
|
||||
<i class="fa fa-snowflake-o fa-sm me-1" title="{{ 'workflow.Freezed'|trans }}"></i>
|
||||
{% endif %}
|
||||
{{ step.currentStep }}
|
||||
{{ label }}
|
||||
</span>
|
||||
{% if not loop.last %}
|
||||
→
|
||||
|
@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Chill\MainBundle\Serializer\Normalizer;
|
||||
|
||||
use Chill\MainBundle\Entity\Workflow\EntityWorkflow;
|
||||
use Chill\MainBundle\Workflow\Helper\MetadataExtractor;
|
||||
use Symfony\Component\Serializer\Normalizer\NormalizerAwareInterface;
|
||||
use Symfony\Component\Serializer\Normalizer\NormalizerAwareTrait;
|
||||
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
|
||||
use Symfony\Component\Workflow\Registry;
|
||||
|
||||
class EntityWorkflowNormalizer implements NormalizerInterface, NormalizerAwareInterface
|
||||
{
|
||||
use NormalizerAwareTrait;
|
||||
|
||||
private MetadataExtractor $metadataExtractor;
|
||||
|
||||
private Registry $registry;
|
||||
|
||||
public function __construct(MetadataExtractor $metadataExtractor, Registry $registry)
|
||||
{
|
||||
$this->metadataExtractor = $metadataExtractor;
|
||||
$this->registry = $registry;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param EntityWorkflow $object
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function normalize($object, ?string $format = null, array $context = [])
|
||||
{
|
||||
$workflow = $this->registry->get($object, $object->getWorkflowName());
|
||||
|
||||
return [
|
||||
'type' => 'entity_workflow',
|
||||
'id' => $object->getId(),
|
||||
'relatedEntityClass' => $object->getRelatedEntityClass(),
|
||||
'relatedEntityId' => $object->getRelatedEntityId(),
|
||||
'workflow' => $this->metadataExtractor->buildArrayPresentationForWorkflow($workflow),
|
||||
'currentStep' => $this->normalizer->normalize($object->getCurrentStep(), $format, $context),
|
||||
'steps' => $this->normalizer->normalize($object->getStepsChained(), $format, $context),
|
||||
];
|
||||
}
|
||||
|
||||
public function supportsNormalization($data, ?string $format = null): bool
|
||||
{
|
||||
return $data instanceof EntityWorkflow && 'json' === $format;
|
||||
}
|
||||
}
|
@ -0,0 +1,87 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Chill\MainBundle\Serializer\Normalizer;
|
||||
|
||||
use Chill\MainBundle\Entity\Workflow\EntityWorkflowStep;
|
||||
use Chill\MainBundle\Workflow\Helper\MetadataExtractor;
|
||||
use Symfony\Component\Serializer\Normalizer\NormalizerAwareInterface;
|
||||
use Symfony\Component\Serializer\Normalizer\NormalizerAwareTrait;
|
||||
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
|
||||
|
||||
class EntityWorkflowStepNormalizer implements NormalizerAwareInterface, NormalizerInterface
|
||||
{
|
||||
use NormalizerAwareTrait;
|
||||
|
||||
private MetadataExtractor $metadataExtractor;
|
||||
|
||||
public function __construct(MetadataExtractor $metadataExtractor)
|
||||
{
|
||||
$this->metadataExtractor = $metadataExtractor;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param EntityWorkflowStep $object
|
||||
*/
|
||||
public function normalize($object, ?string $format = null, array $context = []): array
|
||||
{
|
||||
$data = [
|
||||
'type' => 'entity_workflow_step',
|
||||
'id' => $object->getId(),
|
||||
'comment' => $object->getComment(),
|
||||
'currentStep' => $this->metadataExtractor->buildArrayPresentationForPlace($object->getEntityWorkflow(), $object),
|
||||
'isFinal' => $object->isFinal(),
|
||||
'isFreezed' => false,
|
||||
'isFinalized' => false,
|
||||
'transitionPrevious' => null,
|
||||
'transitionAfter' => null,
|
||||
'previousId' => null,
|
||||
'nextId' => null,
|
||||
'transitionPreviousBy' => null,
|
||||
'transitionPreviousAt' => null,
|
||||
];
|
||||
|
||||
if (null !== $previous = $object->getPrevious()) {
|
||||
$data['transitionPrevious'] = $this->metadataExtractor
|
||||
->buildArrayPresentationForTransition($object->getEntityWorkflow(), $object->getPrevious()->getTransitionAfter());
|
||||
$data['previousId'] = $previous->getId();
|
||||
$data['isFreezed'] = $previous->isFreezeAfter();
|
||||
$data['transitionPreviousBy'] = $this->normalizer->normalize(
|
||||
$previous->getTransitionBy(),
|
||||
$format,
|
||||
$context
|
||||
);
|
||||
$data['transitionPreviousAt'] = $this->normalizer->normalize(
|
||||
$previous->getTransitionAt(),
|
||||
$format,
|
||||
$context
|
||||
);
|
||||
}
|
||||
|
||||
if (null !== $next = $object->getNext()) {
|
||||
$data['nextId'] = $next->getId();
|
||||
}
|
||||
|
||||
if (null !== $object->getTransitionAfter()) {
|
||||
$data['transitionAfter'] = $this->metadataExtractor->buildArrayPresentationForTransition(
|
||||
$object->getEntityWorkflow(),
|
||||
$object->getTransitionAfter()
|
||||
);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function supportsNormalization($data, ?string $format = null): bool
|
||||
{
|
||||
return $data instanceof EntityWorkflowStep && 'json' === $format;
|
||||
}
|
||||
}
|
@ -21,6 +21,7 @@ use Symfony\Component\Security\Core\Security;
|
||||
use Symfony\Component\Workflow\Event\Event;
|
||||
use Symfony\Component\Workflow\Event\GuardEvent;
|
||||
use Symfony\Component\Workflow\TransitionBlocker;
|
||||
use function array_key_exists;
|
||||
|
||||
class EntityWorkflowTransitionEventSubscriber implements EventSubscriberInterface
|
||||
{
|
||||
@ -44,6 +45,7 @@ class EntityWorkflowTransitionEventSubscriber implements EventSubscriberInterfac
|
||||
{
|
||||
return [
|
||||
'workflow.transition' => 'onTransition',
|
||||
'workflow.completed' => 'onCompleted',
|
||||
'workflow.guard' => [
|
||||
['guardEntityWorkflow', 0],
|
||||
],
|
||||
@ -59,7 +61,7 @@ class EntityWorkflowTransitionEventSubscriber implements EventSubscriberInterfac
|
||||
/** @var EntityWorkflow $entityWorkflow */
|
||||
$entityWorkflow = $event->getSubject();
|
||||
|
||||
if ($entityWorkflow->isFinalize()) {
|
||||
if ($entityWorkflow->isFinal()) {
|
||||
$event->addTransitionBlocker(
|
||||
new TransitionBlocker(
|
||||
'workflow.The workflow is finalized',
|
||||
@ -88,7 +90,25 @@ class EntityWorkflowTransitionEventSubscriber implements EventSubscriberInterfac
|
||||
}
|
||||
}
|
||||
|
||||
public function onTransition(Event $event)
|
||||
public function onCompleted(Event $event): void
|
||||
{
|
||||
if (!$event->getSubject() instanceof EntityWorkflow) {
|
||||
return;
|
||||
}
|
||||
|
||||
/** @var EntityWorkflow $entityWorkflow */
|
||||
$entityWorkflow = $event->getSubject();
|
||||
$step = $entityWorkflow->getCurrentStep();
|
||||
|
||||
$placeMetadata = $event->getWorkflow()->getMetadataStore()
|
||||
->getPlaceMetadata($step->getCurrentStep());
|
||||
|
||||
if (array_key_exists('isFinal', $placeMetadata) && true === $placeMetadata['isFinal']) {
|
||||
$step->setIsFinal(true);
|
||||
}
|
||||
}
|
||||
|
||||
public function onTransition(Event $event): void
|
||||
{
|
||||
if (!$event->getSubject() instanceof EntityWorkflow) {
|
||||
return;
|
||||
|
@ -61,7 +61,7 @@ class NotificationOnTransition implements EventSubscriberInterface
|
||||
|
||||
$dests = array_merge(
|
||||
$entityWorkflow->getSubscriberToStep()->toArray(),
|
||||
$entityWorkflow->isFinalize() ? $entityWorkflow->getSubscriberToFinal()->toArray() : [],
|
||||
$entityWorkflow->isFinal() ? $entityWorkflow->getSubscriberToFinal()->toArray() : [],
|
||||
$entityWorkflow->getCurrentStep()->getDestUser()->toArray()
|
||||
);
|
||||
|
||||
|
@ -12,6 +12,7 @@ declare(strict_types=1);
|
||||
namespace Chill\MainBundle\Workflow\Helper;
|
||||
|
||||
use Chill\MainBundle\Entity\Workflow\EntityWorkflow;
|
||||
use Chill\MainBundle\Entity\Workflow\EntityWorkflowStep;
|
||||
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
|
||||
use Symfony\Component\Workflow\Registry;
|
||||
use Symfony\Component\Workflow\WorkflowInterface;
|
||||
@ -51,16 +52,37 @@ class MetadataExtractor
|
||||
return $workflowsList;
|
||||
}
|
||||
|
||||
public function buildArrayPresentationForPlace(EntityWorkflow $entityWorkflow): array
|
||||
public function buildArrayPresentationForPlace(EntityWorkflow $entityWorkflow, ?EntityWorkflowStep $step = null): array
|
||||
{
|
||||
$workflow = $this->registry->get($entityWorkflow, $entityWorkflow->getWorkflowName());
|
||||
$step ??= $entityWorkflow->getCurrentStep();
|
||||
|
||||
$markingMetadata = $workflow->getMetadataStore()->getPlaceMetadata($entityWorkflow->getCurrentStep()->getCurrentStep());
|
||||
$markingMetadata = $workflow->getMetadataStore()->getPlaceMetadata($step->getCurrentStep());
|
||||
|
||||
$text = array_key_exists('label', $markingMetadata) ?
|
||||
$this->translatableStringHelper->localize($markingMetadata['label']) : $entityWorkflow->getCurrentStep()->getCurrentStep();
|
||||
$this->translatableStringHelper->localize($markingMetadata['label']) : $step->getCurrentStep();
|
||||
|
||||
return ['name' => $entityWorkflow->getCurrentStep()->getCurrentStep(), 'text' => $text];
|
||||
return ['name' => $step->getCurrentStep(), 'text' => $text];
|
||||
}
|
||||
|
||||
public function buildArrayPresentationForTransition(EntityWorkflow $entityWorkflow, string $transitionName): array
|
||||
{
|
||||
$workflow = $this->registry->get($entityWorkflow, $entityWorkflow->getWorkflowName());
|
||||
$transitions = $workflow->getDefinition()->getTransitions();
|
||||
|
||||
foreach ($transitions as $transition) {
|
||||
if ($transition->getName() === $transitionName) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
$metadata = $workflow->getMetadataStore()->getTransitionMetadata($transition);
|
||||
|
||||
return [
|
||||
'name' => $transition->getName(),
|
||||
'text' => array_key_exists('label', $metadata) ?
|
||||
$this->translatableStringHelper->localize($metadata['label']) : $transition->getName(),
|
||||
'isForward' => $metadata['isForward'] ?? null,
|
||||
];
|
||||
}
|
||||
|
||||
public function buildArrayPresentationForWorkflow(WorkflowInterface $workflow): array
|
||||
|
@ -24,6 +24,10 @@ class WorkflowTwigExtension extends AbstractExtension
|
||||
[WorkflowTwigExtensionRuntime::class, 'listWorkflows'],
|
||||
['needs_environment' => true, 'is_safe' => ['html']]
|
||||
),
|
||||
new TwigFunction(
|
||||
'chill_workflow_transition_by_string',
|
||||
[WorkflowTwigExtensionRuntime::class, 'getTransitionByString']
|
||||
),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -17,6 +17,7 @@ use Chill\MainBundle\Workflow\EntityWorkflowManager;
|
||||
use Chill\MainBundle\Workflow\Helper\MetadataExtractor;
|
||||
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
|
||||
use Symfony\Component\Workflow\Registry;
|
||||
use Symfony\Component\Workflow\Transition;
|
||||
use Twig\Environment;
|
||||
use Twig\Extension\RuntimeExtensionInterface;
|
||||
|
||||
@ -46,6 +47,20 @@ class WorkflowTwigExtensionRuntime implements RuntimeExtensionInterface
|
||||
$this->normalizer = $normalizer;
|
||||
}
|
||||
|
||||
public function getTransitionByString(EntityWorkflow $entityWorkflow, string $key): ?Transition
|
||||
{
|
||||
$workflow = $this->registry->get($entityWorkflow, $entityWorkflow->getWorkflowName());
|
||||
$transitions = $workflow->getDefinition()->getTransitions();
|
||||
|
||||
foreach ($transitions as $transition) {
|
||||
if ($transition->getName() === $key) {
|
||||
return $transition;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function listWorkflows(Environment $environment, string $relatedEntityClass, int $relatedEntityId, array $options = []): string
|
||||
{
|
||||
$blankEntityWorkflow = new EntityWorkflow();
|
||||
|
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Chill\Migrations\Main;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
|
||||
final class Version20220128211748 extends AbstractMigration
|
||||
{
|
||||
public function down(Schema $schema): void
|
||||
{
|
||||
$this->addSql('ALTER TABLE chill_main_workflow_entity_step RENAME COLUMN isFinal TO finalizeAfter;');
|
||||
}
|
||||
|
||||
public function getDescription(): string
|
||||
{
|
||||
return 'rename workflow entity step from finalizeAfter to isFinal';
|
||||
}
|
||||
|
||||
public function up(Schema $schema): void
|
||||
{
|
||||
$this->addSql('ALTER TABLE chill_main_workflow_entity_step RENAME COLUMN finalizeAfter TO isFinal;');
|
||||
}
|
||||
}
|
@ -368,7 +368,7 @@ Workflow history: Historique de la décision
|
||||
|
||||
workflow:
|
||||
Created by: Créé par
|
||||
Transition: Prochaine étape
|
||||
Transition to apply: Ma décision
|
||||
dest for next steps: Utilisateurs qui valideront la prochaine étape
|
||||
Freeze: Geler
|
||||
Freezed: Gelé
|
||||
|
Loading…
x
Reference in New Issue
Block a user