From cbc3ee68b5c2b12af4d3b17eff5af0ee5e3fc187 Mon Sep 17 00:00:00 2001 From: nobohan Date: Tue, 21 Mar 2023 15:11:18 +0100 Subject: [PATCH 01/18] Feature: Add new field ccuser in workflow step entity --- .../Entity/Workflow/EntityWorkflowStep.php | 28 ++++++++++++++++ .../migrations/Version20230321134155.php | 32 +++++++++++++++++++ 2 files changed, 60 insertions(+) create mode 100644 src/Bundle/ChillMainBundle/migrations/Version20230321134155.php diff --git a/src/Bundle/ChillMainBundle/Entity/Workflow/EntityWorkflowStep.php b/src/Bundle/ChillMainBundle/Entity/Workflow/EntityWorkflowStep.php index 4bff7a3f5..8c27d0c3e 100644 --- a/src/Bundle/ChillMainBundle/Entity/Workflow/EntityWorkflowStep.php +++ b/src/Bundle/ChillMainBundle/Entity/Workflow/EntityWorkflowStep.php @@ -32,6 +32,12 @@ class EntityWorkflowStep */ private string $accessKey; + /** + * @ORM\ManyToMany(targetEntity=User::class) + * @ORM\JoinTable(name="chill_main_workflow_entity_step_cc_user") + */ + private Collection $ccUser; + /** * @ORM\Column(type="text", options={"default": ""}) */ @@ -114,6 +120,7 @@ class EntityWorkflowStep public function __construct() { + $this->ccUser = new ArrayCollection(); $this->destUser = new ArrayCollection(); $this->destUserByAccessKey = new ArrayCollection(); $this->accessKey = bin2hex(openssl_random_pseudo_bytes(32)); @@ -128,6 +135,15 @@ class EntityWorkflowStep return $this; } + public function addCcUser(User $user): self + { + if (!$this->ccUser->contains($user)) { + $this->ccUser[] = $user; + } + + return $this; + } + public function addDestUser(User $user): self { if (!$this->destUser->contains($user)) { @@ -167,6 +183,11 @@ class EntityWorkflowStep ); } + public function getCcUser(): Collection + { + return $this->ccUser; + } + public function getComment(): string { return $this->comment; @@ -261,6 +282,13 @@ class EntityWorkflowStep return true; } + public function removeCcUser(User $user): self + { + $this->ccUser->removeElement($user); + + return $this; + } + public function removeDestEmail(string $email): self { $this->destEmail = array_filter($this->destEmail, static function (string $existing) use ($email) { diff --git a/src/Bundle/ChillMainBundle/migrations/Version20230321134155.php b/src/Bundle/ChillMainBundle/migrations/Version20230321134155.php new file mode 100644 index 000000000..801d49e58 --- /dev/null +++ b/src/Bundle/ChillMainBundle/migrations/Version20230321134155.php @@ -0,0 +1,32 @@ +addSql('ALTER TABLE chill_main_workflow_entity_step_cc_user DROP CONSTRAINT FK_9FC79037E6AF9D4'); + $this->addSql('ALTER TABLE chill_main_workflow_entity_step_cc_user DROP CONSTRAINT FK_9FC7903A76ED395'); + $this->addSql('DROP TABLE chill_main_workflow_entity_step_cc_user'); + } + + public function getDescription(): string + { + return 'Add cc User to workflow step'; + } + + public function up(Schema $schema): void + { + $this->addSql('CREATE TABLE chill_main_workflow_entity_step_cc_user (entityworkflowstep_id INT NOT NULL, user_id INT NOT NULL, PRIMARY KEY(entityworkflowstep_id, user_id))'); + $this->addSql('CREATE INDEX IDX_9FC79037E6AF9D4 ON chill_main_workflow_entity_step_cc_user (entityworkflowstep_id)'); + $this->addSql('CREATE INDEX IDX_9FC7903A76ED395 ON chill_main_workflow_entity_step_cc_user (user_id)'); + $this->addSql('ALTER TABLE chill_main_workflow_entity_step_cc_user ADD CONSTRAINT FK_9FC79037E6AF9D4 FOREIGN KEY (entityworkflowstep_id) REFERENCES chill_main_workflow_entity_step (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE'); + $this->addSql('ALTER TABLE chill_main_workflow_entity_step_cc_user ADD CONSTRAINT FK_9FC7903A76ED395 FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE'); + } +} From 2b3d7f34fc433f744626fa53325658f1311b05cd Mon Sep 17 00:00:00 2001 From: nobohan Date: Tue, 21 Mar 2023 16:08:26 +0100 Subject: [PATCH 02/18] Feature: Add new field ccuser in workflow step form --- .../ChillMainBundle/Controller/WorkflowController.php | 1 + .../ChillMainBundle/Entity/Workflow/EntityWorkflow.php | 7 +++++++ src/Bundle/ChillMainBundle/Form/WorkflowStepType.php | 5 +++++ .../Resources/views/Workflow/_decision.html.twig | 2 ++ src/Bundle/ChillMainBundle/translations/messages.fr.yml | 1 + src/Bundle/ChillMainBundle/translations/messages.nl.yml | 1 + 6 files changed, 17 insertions(+) diff --git a/src/Bundle/ChillMainBundle/Controller/WorkflowController.php b/src/Bundle/ChillMainBundle/Controller/WorkflowController.php index 0f00a177f..0de77b81e 100644 --- a/src/Bundle/ChillMainBundle/Controller/WorkflowController.php +++ b/src/Bundle/ChillMainBundle/Controller/WorkflowController.php @@ -330,6 +330,7 @@ class WorkflowController extends AbstractController } // TODO symfony 5: add those "future" on context ($workflow->apply($entityWorkflow, $transition, $context) + $entityWorkflow->futureCcUsers = $transitionForm['future_cc_users']->getData(); $entityWorkflow->futureDestUsers = $transitionForm['future_dest_users']->getData(); $entityWorkflow->futureDestEmails = $transitionForm['future_dest_emails']->getData(); diff --git a/src/Bundle/ChillMainBundle/Entity/Workflow/EntityWorkflow.php b/src/Bundle/ChillMainBundle/Entity/Workflow/EntityWorkflow.php index e4683f24b..73f4c2b04 100644 --- a/src/Bundle/ChillMainBundle/Entity/Workflow/EntityWorkflow.php +++ b/src/Bundle/ChillMainBundle/Entity/Workflow/EntityWorkflow.php @@ -41,6 +41,13 @@ class EntityWorkflow implements TrackCreationInterface, TrackUpdateInterface use TrackUpdateTrait; + /** + * a list of future cc users for the next steps. + * + * @var array|User[] + */ + public array $futureCcUsers = []; + /** * a list of future dest emails for the next steps. * diff --git a/src/Bundle/ChillMainBundle/Form/WorkflowStepType.php b/src/Bundle/ChillMainBundle/Form/WorkflowStepType.php index 1b18b3ef8..7019eeaf4 100644 --- a/src/Bundle/ChillMainBundle/Form/WorkflowStepType.php +++ b/src/Bundle/ChillMainBundle/Form/WorkflowStepType.php @@ -156,6 +156,11 @@ class WorkflowStepType extends AbstractType 'mapped' => false, 'suggested' => $options['suggested_users'], ]) + ->add('future_cc_users', PickUserDynamicType::class, [ + 'label' => 'workflow.cc for next steps', + 'multiple' => true, + 'mapped' => false, + ]) ->add('future_dest_emails', ChillCollectionType::class, [ 'label' => 'workflow.dest by email', 'help' => 'workflow.dest by email help', diff --git a/src/Bundle/ChillMainBundle/Resources/views/Workflow/_decision.html.twig b/src/Bundle/ChillMainBundle/Resources/views/Workflow/_decision.html.twig index bd9274739..021b7e933 100644 --- a/src/Bundle/ChillMainBundle/Resources/views/Workflow/_decision.html.twig +++ b/src/Bundle/ChillMainBundle/Resources/views/Workflow/_decision.html.twig @@ -65,6 +65,8 @@
{{ form_row(transition_form.future_dest_users) }} + {{ form_row(transition_form.future_cc_users) }} + {{ form_row(transition_form.future_dest_emails) }}
diff --git a/src/Bundle/ChillMainBundle/translations/messages.fr.yml b/src/Bundle/ChillMainBundle/translations/messages.fr.yml index f01976e87..5eb6c1d49 100644 --- a/src/Bundle/ChillMainBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillMainBundle/translations/messages.fr.yml @@ -447,6 +447,7 @@ workflow: Created by: Créé par My decision: Ma décision Next step: Prochaine étape + cc for next steps: Utilisateurs en copie dest for next steps: Utilisateurs qui valideront la prochaine étape Freeze: Geler Freezed: Gelé diff --git a/src/Bundle/ChillMainBundle/translations/messages.nl.yml b/src/Bundle/ChillMainBundle/translations/messages.nl.yml index 97341dd3c..b585c3822 100644 --- a/src/Bundle/ChillMainBundle/translations/messages.nl.yml +++ b/src/Bundle/ChillMainBundle/translations/messages.nl.yml @@ -373,6 +373,7 @@ workflow: Created by: Créé par My decision: Ma décision Next step: Prochaine étape + cc for next steps: Utilisateurs en copie dest for next steps: Utilisateurs qui valideront la prochaine étape Freeze: Geler Freezed: Gelé From 1789a752161aa9c365e9e8ade36c34067b3698ac Mon Sep 17 00:00:00 2001 From: nobohan Date: Tue, 21 Mar 2023 20:14:11 +0100 Subject: [PATCH 03/18] Feature: send notification on ccuser for workflows --- .../EntityWorkflowTransitionEventSubscriber.php | 4 ++++ .../Workflow/EventSubscriber/NotificationOnTransition.php | 4 +++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/Bundle/ChillMainBundle/Workflow/EventSubscriber/EntityWorkflowTransitionEventSubscriber.php b/src/Bundle/ChillMainBundle/Workflow/EventSubscriber/EntityWorkflowTransitionEventSubscriber.php index 1729d0daa..192ca0712 100644 --- a/src/Bundle/ChillMainBundle/Workflow/EventSubscriber/EntityWorkflowTransitionEventSubscriber.php +++ b/src/Bundle/ChillMainBundle/Workflow/EventSubscriber/EntityWorkflowTransitionEventSubscriber.php @@ -50,6 +50,10 @@ class EntityWorkflowTransitionEventSubscriber implements EventSubscriberInterfac /** @var EntityWorkflow $entityWorkflow */ $entityWorkflow = $event->getSubject(); + foreach ($entityWorkflow->futureCcUsers as $user) { + $entityWorkflow->getCurrentStep()->addCcUser($user); + } + foreach ($entityWorkflow->futureDestUsers as $user) { $entityWorkflow->getCurrentStep()->addDestUser($user); } diff --git a/src/Bundle/ChillMainBundle/Workflow/EventSubscriber/NotificationOnTransition.php b/src/Bundle/ChillMainBundle/Workflow/EventSubscriber/NotificationOnTransition.php index 7d2cadc37..f02341ff7 100644 --- a/src/Bundle/ChillMainBundle/Workflow/EventSubscriber/NotificationOnTransition.php +++ b/src/Bundle/ChillMainBundle/Workflow/EventSubscriber/NotificationOnTransition.php @@ -85,7 +85,9 @@ class NotificationOnTransition implements EventSubscriberInterface // the subscriber to final, only if final $entityWorkflow->isFinal() ? $entityWorkflow->getSubscriberToFinal()->toArray() : [], // the dests for the current step - $entityWorkflow->getCurrentStep()->getDestUser()->toArray() + $entityWorkflow->getCurrentStep()->getDestUser()->toArray(), + // the cc users for the current step + $entityWorkflow->getCurrentStep()->getCcUser()->toArray() ) as $dest) { $dests[spl_object_hash($dest)] = $dest; } From a992c45720b521c97ce80cb0f0080f6d5909a986 Mon Sep 17 00:00:00 2001 From: nobohan Date: Thu, 23 Mar 2023 10:14:40 +0100 Subject: [PATCH 04/18] Feature: create a new API endpoint for my workflows in Cc --- .../Controller/WorkflowApiController.php | 39 +++++++++++++++++++ .../Workflow/EntityWorkflowRepository.php | 39 +++++++++++++++++++ .../ChillMainBundle/chill.api.specs.yaml | 16 ++++++++ 3 files changed, 94 insertions(+) diff --git a/src/Bundle/ChillMainBundle/Controller/WorkflowApiController.php b/src/Bundle/ChillMainBundle/Controller/WorkflowApiController.php index b451e9209..f0e728252 100644 --- a/src/Bundle/ChillMainBundle/Controller/WorkflowApiController.php +++ b/src/Bundle/ChillMainBundle/Controller/WorkflowApiController.php @@ -93,6 +93,45 @@ class WorkflowApiController ); } + /** + * Return a list of workflow which are waiting an action for the user. + * + * @Route("/api/1.0/main/workflow/my-cc", methods={"GET"}) + */ + public function myWorkflowCc(Request $request): JsonResponse + { + if (!$this->security->isGranted('ROLE_USER') || !$this->security->getUser() instanceof User) { + throw new AccessDeniedException(); + } + + $total = $this->entityWorkflowRepository->countByCc($this->security->getUser()); + + if ($request->query->getBoolean('countOnly', false)) { + return new JsonResponse( + $this->serializer->serialize(new Counter($total), 'json'), + JsonResponse::HTTP_OK, + [], + true + ); + } + + $paginator = $this->paginatorFactory->create($total); + + $workflows = $this->entityWorkflowRepository->findByCc( + $this->security->getUser(), + ['id' => 'DESC'], + $paginator->getItemsPerPage(), + $paginator->getCurrentPageFirstItemNumber() + ); + + return new JsonResponse( + $this->serializer->serialize(new Collection($workflows, $paginator), 'json', ['groups' => ['read']]), + JsonResponse::HTTP_OK, + [], + true + ); + } + /** * @Route("/api/1.0/main/workflow/{id}/subscribe", methods={"POST"}) */ diff --git a/src/Bundle/ChillMainBundle/Repository/Workflow/EntityWorkflowRepository.php b/src/Bundle/ChillMainBundle/Repository/Workflow/EntityWorkflowRepository.php index 1fc309d6e..a304ff6d7 100644 --- a/src/Bundle/ChillMainBundle/Repository/Workflow/EntityWorkflowRepository.php +++ b/src/Bundle/ChillMainBundle/Repository/Workflow/EntityWorkflowRepository.php @@ -27,6 +27,13 @@ class EntityWorkflowRepository implements ObjectRepository $this->repository = $entityManager->getRepository(EntityWorkflow::class); } + public function countByCc(User $user): int + { + $qb = $this->buildQueryByCc($user)->select('count(ew)'); + + return (int) $qb->getQuery()->getSingleScalarResult(); + } + public function countByDest(User $user): int { $qb = $this->buildQueryByDest($user)->select('count(ew)'); @@ -103,6 +110,19 @@ class EntityWorkflowRepository implements ObjectRepository return $this->repository->findBy($criteria, $orderBy, $limit, $offset); } + public function findByCc(User $user, ?array $orderBy = null, $limit = null, $offset = null): array + { + $qb = $this->buildQueryByCc($user)->select('ew'); + + foreach ($orderBy as $key => $sort) { + $qb->addOrderBy('ew.' . $key, $sort); + } + + $qb->setMaxResults($limit)->setFirstResult($offset); + + return $qb->getQuery()->getResult(); + } + public function findByDest(User $user, ?array $orderBy = null, $limit = null, $offset = null): array { $qb = $this->buildQueryByDest($user)->select('ew'); @@ -165,6 +185,25 @@ class EntityWorkflowRepository implements ObjectRepository return EntityWorkflow::class; } + private function buildQueryByCc(User $user): QueryBuilder + { + $qb = $this->repository->createQueryBuilder('ew'); + + $qb->join('ew.steps', 'step'); + + $qb->where( + $qb->expr()->andX( + $qb->expr()->isMemberOf(':user', 'step.ccUser'), + $qb->expr()->isNull('step.transitionAfter'), + $qb->expr()->eq('step.isFinal', "'FALSE'") + ) + ); + + $qb->setParameter('user', $user); + + return $qb; + } + private function buildQueryByDest(User $user): QueryBuilder { $qb = $this->repository->createQueryBuilder('ew'); diff --git a/src/Bundle/ChillMainBundle/chill.api.specs.yaml b/src/Bundle/ChillMainBundle/chill.api.specs.yaml index 133345a6f..98e0e915e 100644 --- a/src/Bundle/ChillMainBundle/chill.api.specs.yaml +++ b/src/Bundle/ChillMainBundle/chill.api.specs.yaml @@ -826,4 +826,20 @@ paths: $ref: '#/components/schemas/Workflow' 403: description: "Unauthorized" + /1.0/main/workflow/my-cc: + get: + tags: + - workflow + summary: Return a list of workflows for which user was notified in Cc + responses: + 200: + description: "ok" + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/Workflow' + 403: + description: "Unauthorized" From 7580565e08ca1bd7d023ae28229fa2fbae864e27 Mon Sep 17 00:00:00 2001 From: nobohan Date: Thu, 23 Mar 2023 10:15:31 +0100 Subject: [PATCH 05/18] Feature: show my workflows in Cc in homepage vue widget --- .../vuejs/HomepageWidget/MyWorkflows.vue | 81 ++---------------- .../vuejs/HomepageWidget/MyWorkflowsTable.vue | 83 +++++++++++++++++++ .../public/vuejs/HomepageWidget/js/i18n.js | 3 +- .../public/vuejs/HomepageWidget/js/store.js | 32 ++++--- 4 files changed, 115 insertions(+), 84 deletions(-) create mode 100644 src/Bundle/ChillMainBundle/Resources/public/vuejs/HomepageWidget/MyWorkflowsTable.vue diff --git a/src/Bundle/ChillMainBundle/Resources/public/vuejs/HomepageWidget/MyWorkflows.vue b/src/Bundle/ChillMainBundle/Resources/public/vuejs/HomepageWidget/MyWorkflows.vue index 1272a3c19..51bda315e 100644 --- a/src/Bundle/ChillMainBundle/Resources/public/vuejs/HomepageWidget/MyWorkflows.vue +++ b/src/Bundle/ChillMainBundle/Resources/public/vuejs/HomepageWidget/MyWorkflows.vue @@ -1,88 +1,25 @@ - - + \ No newline at end of file diff --git a/src/Bundle/ChillMainBundle/Resources/public/vuejs/HomepageWidget/MyWorkflowsTable.vue b/src/Bundle/ChillMainBundle/Resources/public/vuejs/HomepageWidget/MyWorkflowsTable.vue new file mode 100644 index 000000000..f98d7a5cb --- /dev/null +++ b/src/Bundle/ChillMainBundle/Resources/public/vuejs/HomepageWidget/MyWorkflowsTable.vue @@ -0,0 +1,83 @@ + + + + + diff --git a/src/Bundle/ChillMainBundle/Resources/public/vuejs/HomepageWidget/js/i18n.js b/src/Bundle/ChillMainBundle/Resources/public/vuejs/HomepageWidget/js/i18n.js index edc781087..697074671 100644 --- a/src/Bundle/ChillMainBundle/Resources/public/vuejs/HomepageWidget/js/i18n.js +++ b/src/Bundle/ChillMainBundle/Resources/public/vuejs/HomepageWidget/js/i18n.js @@ -24,7 +24,8 @@ const appMessages = { }, my_workflows: { tab: "Mes workflows", - description: "Liste des workflows en attente d'une action." + description: "Liste des workflows en attente d'une action.", + description_cc: "Liste des workflows dont je suis en copie." }, opening_date: "Date d'ouverture", social_issues: "Problématiques sociales", diff --git a/src/Bundle/ChillMainBundle/Resources/public/vuejs/HomepageWidget/js/store.js b/src/Bundle/ChillMainBundle/Resources/public/vuejs/HomepageWidget/js/store.js index 44127da1c..088cb93b7 100644 --- a/src/Bundle/ChillMainBundle/Resources/public/vuejs/HomepageWidget/js/store.js +++ b/src/Bundle/ChillMainBundle/Resources/public/vuejs/HomepageWidget/js/store.js @@ -22,6 +22,7 @@ const store = createStore({ accompanyingCourses: {}, notifications: {}, workflows: {}, + workflowsCc: {}, errorMsg: [], loading: false }, @@ -87,6 +88,9 @@ const store = createStore({ addWorkflows(state, workflows) { state.workflows = workflows; }, + addWorkflowsCc(state, workflows) { + state.workflowsCc = workflows; + }, setLoading(state, bool) { state.loading = bool; }, @@ -195,17 +199,23 @@ const store = createStore({ case 'MyWorkflows': if (!getters.isWorflowsLoaded) { commit('setLoading', true); - const url = '/api/1.0/main/workflow/my'; - makeFetch('GET', url) - .then((response) => { - console.log('workflows', response) - commit('addWorkflows', response); - commit('setLoading', false); - }) - .catch((error) => { - commit('catchError', error); - throw error; - }); + makeFetch('GET', '/api/1.0/main/workflow/my') + .then((response) => { + commit('addWorkflows', response); + makeFetch('GET', '/api/1.0/main/workflow/my-cc') + .then((response) => { + commit('addWorkflowsCc', response); + commit('setLoading', false); + }) + .catch((error) => { + commit('catchError', error); + throw error; + }); + }) + .catch((error) => { + commit('catchError', error); + throw error; + }); } break; default: From 35174e42416a0c666d794b61e64ed2f40a867d22 Mon Sep 17 00:00:00 2001 From: nobohan Date: Thu, 23 Mar 2023 10:47:52 +0100 Subject: [PATCH 06/18] Feature: show my workflows in Cc in my workflow page --- .../Controller/WorkflowController.php | 28 +++++++++++++++++++ .../Resources/views/Workflow/list.html.twig | 8 +++++- .../translations/messages.fr.yml | 1 + .../translations/messages.nl.yml | 1 + 4 files changed, 37 insertions(+), 1 deletion(-) diff --git a/src/Bundle/ChillMainBundle/Controller/WorkflowController.php b/src/Bundle/ChillMainBundle/Controller/WorkflowController.php index 0de77b81e..4dd4fa6ea 100644 --- a/src/Bundle/ChillMainBundle/Controller/WorkflowController.php +++ b/src/Bundle/ChillMainBundle/Controller/WorkflowController.php @@ -228,6 +228,34 @@ class WorkflowController extends AbstractController ); } + + /** + * @Route("/{_locale}/main/workflow/list/cc", name="chill_main_workflow_list_cc") + */ + public function myWorkflowsCc(Request $request): Response + { + $this->denyAccessUnlessGranted('IS_AUTHENTICATED_REMEMBERED'); + + $total = $this->entityWorkflowRepository->countByDest($this->getUser()); + $paginator = $this->paginatorFactory->create($total); + + $workflows = $this->entityWorkflowRepository->findByCc( + $this->getUser(), + ['createdAt' => 'DESC'], + $paginator->getItemsPerPage(), + $paginator->getCurrentPageFirstItemNumber() + ); + + return $this->render( + '@ChillMain/Workflow/list.html.twig', + [ + 'workflows' => $this->buildHandler($workflows), + 'paginator' => $paginator, + 'step' => 'cc', + ] + ); + } + /** * @Route("/{_locale}/main/workflow/list/dest", name="chill_main_workflow_list_dest") */ diff --git a/src/Bundle/ChillMainBundle/Resources/views/Workflow/list.html.twig b/src/Bundle/ChillMainBundle/Resources/views/Workflow/list.html.twig index 85a521d2a..1099d8452 100644 --- a/src/Bundle/ChillMainBundle/Resources/views/Workflow/list.html.twig +++ b/src/Bundle/ChillMainBundle/Resources/views/Workflow/list.html.twig @@ -7,7 +7,7 @@ {% endblock %} {% block content %} -
+

{{ block('title') }}

@@ -25,6 +25,12 @@ {{ 'workflow.dest'|trans }} +
diff --git a/src/Bundle/ChillMainBundle/Resources/views/Notification/show.html.twig b/src/Bundle/ChillMainBundle/Resources/views/Notification/show.html.twig index cce7ebd64..00c88cd50 100644 --- a/src/Bundle/ChillMainBundle/Resources/views/Notification/show.html.twig +++ b/src/Bundle/ChillMainBundle/Resources/views/Notification/show.html.twig @@ -27,7 +27,8 @@ }, 'action_button': false, 'full_content': true, - 'fold_item': false + 'fold_item': false, + 'notification_cc': notificationCc } %}
diff --git a/src/Bundle/ChillMainBundle/translations/messages.fr.yml b/src/Bundle/ChillMainBundle/translations/messages.fr.yml index 051eb0df0..985fb61c1 100644 --- a/src/Bundle/ChillMainBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillMainBundle/translations/messages.fr.yml @@ -525,7 +525,9 @@ notification: list: Notifications Sent: Envoyé to: À + cc: Cc sent_to: Destinataire(s) + sent_cc: En copie from: De received_from: Expéditeur you were notified by %sender%: Vous avez été notifié par %sender% diff --git a/src/Bundle/ChillMainBundle/translations/messages.nl.yml b/src/Bundle/ChillMainBundle/translations/messages.nl.yml index 97a82b371..2e4ee5a88 100644 --- a/src/Bundle/ChillMainBundle/translations/messages.nl.yml +++ b/src/Bundle/ChillMainBundle/translations/messages.nl.yml @@ -446,7 +446,9 @@ notification: list: Notifications Sent: Envoyé to: À + cc: Cc sent_to: Destinataire(s) + sent_cc: En copie from: De received_from: Expéditeur you were notified by %sender%: Vous avez été notifié par %sender% From e45952f28c1635e32d0cb9fc972b31ddfe79ffd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Tue, 28 Mar 2023 13:56:24 +0000 Subject: [PATCH 11/18] Feature: add cc users in workflow: add suggested users in form type --- src/Bundle/ChillMainBundle/Form/WorkflowStepType.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Bundle/ChillMainBundle/Form/WorkflowStepType.php b/src/Bundle/ChillMainBundle/Form/WorkflowStepType.php index f48ae0084..3ef37c03a 100644 --- a/src/Bundle/ChillMainBundle/Form/WorkflowStepType.php +++ b/src/Bundle/ChillMainBundle/Form/WorkflowStepType.php @@ -161,6 +161,7 @@ class WorkflowStepType extends AbstractType 'multiple' => true, 'mapped' => false, 'required' => false, + 'suggested' => $options['suggested_users'], ]) ->add('future_dest_emails', ChillCollectionType::class, [ 'label' => 'workflow.dest by email', From a8c2750ac8990ea28bdd727224b8e8a8adbb3f09 Mon Sep 17 00:00:00 2001 From: nobohan Date: Wed, 29 Mar 2023 11:18:23 +0200 Subject: [PATCH 12/18] Feature: add cc users in workflow: move isNotificationCc to WorkflowNotificationHandler --- .../Controller/NotificationController.php | 23 +--------------- .../NotificationTwigExtensionRuntime.php | 1 - ...extension_list_notifications_for.html.twig | 1 - .../views/Notification/list.html.twig | 2 +- .../views/Notification/show.html.twig | 2 +- .../WorkflowNotificationHandler.php | 27 +++++++++++++++++-- 6 files changed, 28 insertions(+), 28 deletions(-) diff --git a/src/Bundle/ChillMainBundle/Controller/NotificationController.php b/src/Bundle/ChillMainBundle/Controller/NotificationController.php index 5b7fb269b..a6e876b6d 100644 --- a/src/Bundle/ChillMainBundle/Controller/NotificationController.php +++ b/src/Bundle/ChillMainBundle/Controller/NotificationController.php @@ -14,7 +14,6 @@ namespace Chill\MainBundle\Controller; use Chill\MainBundle\Entity\Notification; use Chill\MainBundle\Entity\NotificationComment; use Chill\MainBundle\Entity\User; -use Chill\MainBundle\Entity\Workflow\EntityWorkflow; use Chill\MainBundle\Form\NotificationCommentType; use Chill\MainBundle\Form\NotificationType; use Chill\MainBundle\Notification\Exception\NotificationHandlerNotFound; @@ -22,7 +21,6 @@ use Chill\MainBundle\Notification\NotificationHandlerManager; use Chill\MainBundle\Pagination\PaginatorFactory; use Chill\MainBundle\Repository\NotificationRepository; use Chill\MainBundle\Repository\UserRepository; -use Chill\MainBundle\Repository\Workflow\EntityWorkflowRepository; use Chill\MainBundle\Security\Authorization\NotificationVoter; use Doctrine\ORM\EntityManagerInterface; use Psr\Log\LoggerInterface; @@ -70,8 +68,7 @@ class NotificationController extends AbstractController NotificationHandlerManager $notificationHandlerManager, PaginatorFactory $paginatorFactory, TranslatorInterface $translator, - UserRepository $userRepository, - EntityWorkflowRepository $entityWorkflowRepository + UserRepository $userRepository ) { $this->em = $em; $this->logger = $logger; @@ -82,7 +79,6 @@ class NotificationController extends AbstractController $this->paginatorFactory = $paginatorFactory; $this->translator = $translator; $this->userRepository = $userRepository; - $this->entityWorkflowRepository = $entityWorkflowRepository; } /** @@ -349,7 +345,6 @@ class NotificationController extends AbstractController 'appendCommentForm' => isset($appendCommentForm) ? $appendCommentForm->createView() : null, 'editedCommentForm' => isset($editedCommentForm) ? $editedCommentForm->createView() : null, 'editedCommentId' => $commentId ?? null, - 'notificationCc' => $this->isNotificationCc($notification), ]); // we mark the notification as read after having computed the response @@ -369,21 +364,6 @@ class NotificationController extends AbstractController ]; } - private function isNotificationCc(Notification $notification): bool - { - $notificationCc = false; - - if ($notification->getRelatedEntityClass() === EntityWorkflow::class) { - $relatedEntity = $this->entityWorkflowRepository->findOneBy(['id' => $notification->getRelatedEntityId()]); - - if ($relatedEntity->getCurrentStepCreatedBy() !== $this->security->getUser()) { - $notificationCc = true; - } - } - - return $notificationCc; - } - private function itemsForTemplate(array $notifications): array { $templateData = []; @@ -393,7 +373,6 @@ class NotificationController extends AbstractController 'template' => $this->notificationHandlerManager->getTemplate($notification), 'template_data' => $this->notificationHandlerManager->getTemplateData($notification), 'notification' => $notification, - 'isNotificationCc' => $this->isNotificationCc($notification), ]; } diff --git a/src/Bundle/ChillMainBundle/Notification/Templating/NotificationTwigExtensionRuntime.php b/src/Bundle/ChillMainBundle/Notification/Templating/NotificationTwigExtensionRuntime.php index 5cf4ad084..0720c6da6 100644 --- a/src/Bundle/ChillMainBundle/Notification/Templating/NotificationTwigExtensionRuntime.php +++ b/src/Bundle/ChillMainBundle/Notification/Templating/NotificationTwigExtensionRuntime.php @@ -76,7 +76,6 @@ class NotificationTwigExtensionRuntime implements RuntimeExtensionInterface return $environment->render('@ChillMain/Notification/extension_list_notifications_for.html.twig', [ 'notifications' => $notifications, 'appendCommentForms' => $appendCommentForms, - 'notificationCc' => false, ]); } } diff --git a/src/Bundle/ChillMainBundle/Resources/views/Notification/extension_list_notifications_for.html.twig b/src/Bundle/ChillMainBundle/Resources/views/Notification/extension_list_notifications_for.html.twig index 77d16a6a1..748142ab8 100644 --- a/src/Bundle/ChillMainBundle/Resources/views/Notification/extension_list_notifications_for.html.twig +++ b/src/Bundle/ChillMainBundle/Resources/views/Notification/extension_list_notifications_for.html.twig @@ -6,7 +6,6 @@ 'full_content': true, 'fold_item': true, 'action_button': true, - 'notification_cc': notificationCc, } %}{# #} {% endfor %} diff --git a/src/Bundle/ChillMainBundle/Resources/views/Notification/list.html.twig b/src/Bundle/ChillMainBundle/Resources/views/Notification/list.html.twig index f7ab7f523..6dff67299 100644 --- a/src/Bundle/ChillMainBundle/Resources/views/Notification/list.html.twig +++ b/src/Bundle/ChillMainBundle/Resources/views/Notification/list.html.twig @@ -51,7 +51,7 @@ {% set notification = data.notification %} {% include 'ChillMainBundle:Notification:_list_item.html.twig' with { 'fold_item': true, - 'notification_cc': data.isNotificationCc + 'notification_cc': data.template_data.notificationCc is defined ? data.template_data.notificationCc : false } %} {% endfor %} diff --git a/src/Bundle/ChillMainBundle/Resources/views/Notification/show.html.twig b/src/Bundle/ChillMainBundle/Resources/views/Notification/show.html.twig index 00c88cd50..2f9d5d63f 100644 --- a/src/Bundle/ChillMainBundle/Resources/views/Notification/show.html.twig +++ b/src/Bundle/ChillMainBundle/Resources/views/Notification/show.html.twig @@ -28,7 +28,7 @@ 'action_button': false, 'full_content': true, 'fold_item': false, - 'notification_cc': notificationCc + 'notification_cc': handler.getTemplateData(notification).notificationCc is defined ? handler.getTemplateData(notification).notificationCc : false } %} diff --git a/src/Bundle/ChillMainBundle/Workflow/Notification/WorkflowNotificationHandler.php b/src/Bundle/ChillMainBundle/Workflow/Notification/WorkflowNotificationHandler.php index 0d0c4305b..438e4c0e3 100644 --- a/src/Bundle/ChillMainBundle/Workflow/Notification/WorkflowNotificationHandler.php +++ b/src/Bundle/ChillMainBundle/Workflow/Notification/WorkflowNotificationHandler.php @@ -16,6 +16,7 @@ use Chill\MainBundle\Entity\Workflow\EntityWorkflow; use Chill\MainBundle\Notification\NotificationHandlerInterface; use Chill\MainBundle\Repository\Workflow\EntityWorkflowRepository; use Chill\MainBundle\Workflow\EntityWorkflowManager; +use Symfony\Component\Security\Core\Security; class WorkflowNotificationHandler implements NotificationHandlerInterface { @@ -23,10 +24,17 @@ class WorkflowNotificationHandler implements NotificationHandlerInterface private EntityWorkflowRepository $entityWorkflowRepository; - public function __construct(EntityWorkflowRepository $entityWorkflowRepository, EntityWorkflowManager $entityWorkflowManager) + private Security $security; + + public function __construct( + EntityWorkflowRepository $entityWorkflowRepository, + EntityWorkflowManager $entityWorkflowManager, + Security $security + ) { $this->entityWorkflowRepository = $entityWorkflowRepository; $this->entityWorkflowManager = $entityWorkflowManager; + $this->security = $security; } public function getTemplate(Notification $notification, array $options = []): string @@ -37,13 +45,28 @@ class WorkflowNotificationHandler implements NotificationHandlerInterface public function getTemplateData(Notification $notification, array $options = []): array { $entityWorkflow = $this->entityWorkflowRepository->find($notification->getRelatedEntityId()); - return [ 'entity_workflow' => $entityWorkflow, 'handler' => $this->entityWorkflowManager->getHandler($entityWorkflow), + 'notificationCc' => $this->isNotificationCc($notification), ]; } + private function isNotificationCc(Notification $notification): bool + { + $notificationCc = false; + + if ($notification->getRelatedEntityClass() === EntityWorkflow::class) { + $relatedEntity = $this->entityWorkflowRepository->findOneBy(['id' => $notification->getRelatedEntityId()]); + + if ($relatedEntity->getCurrentStepCreatedBy() !== $this->security->getUser()) { + $notificationCc = true; + } + } + + return $notificationCc; + } + public function supports(Notification $notification, array $options = []): bool { return $notification->getRelatedEntityClass() === EntityWorkflow::class; From 8c37afa3a984eadf8609992311300cc9d2a2e0c7 Mon Sep 17 00:00:00 2001 From: nobohan Date: Wed, 29 Mar 2023 12:09:12 +0200 Subject: [PATCH 13/18] Feature: add cc users in workflow: add constraint validation on EntityWorkflowStep --- .../Entity/Workflow/EntityWorkflowStep.php | 2 + .../Constraints/Entity/WorkflowStepUsers.php | 27 ++++++++++++ .../Entity/WorkflowStepUsersValidator.php | 43 +++++++++++++++++++ 3 files changed, 72 insertions(+) create mode 100644 src/Bundle/ChillMainBundle/Validator/Constraints/Entity/WorkflowStepUsers.php create mode 100644 src/Bundle/ChillMainBundle/Validator/Constraints/Entity/WorkflowStepUsersValidator.php diff --git a/src/Bundle/ChillMainBundle/Entity/Workflow/EntityWorkflowStep.php b/src/Bundle/ChillMainBundle/Entity/Workflow/EntityWorkflowStep.php index e43d524a4..39729aa96 100644 --- a/src/Bundle/ChillMainBundle/Entity/Workflow/EntityWorkflowStep.php +++ b/src/Bundle/ChillMainBundle/Entity/Workflow/EntityWorkflowStep.php @@ -12,6 +12,7 @@ declare(strict_types=1); namespace Chill\MainBundle\Entity\Workflow; use Chill\MainBundle\Entity\User; +use Chill\MainBundle\Validator\Constraints\Entity\WorkflowStepUsers; use DateTimeImmutable; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; @@ -24,6 +25,7 @@ use function in_array; /** * @ORM\Entity * @ORM\Table("chill_main_workflow_entity_step") + * @WorkflowStepUsers() */ class EntityWorkflowStep { diff --git a/src/Bundle/ChillMainBundle/Validator/Constraints/Entity/WorkflowStepUsers.php b/src/Bundle/ChillMainBundle/Validator/Constraints/Entity/WorkflowStepUsers.php new file mode 100644 index 000000000..842df37cf --- /dev/null +++ b/src/Bundle/ChillMainBundle/Validator/Constraints/Entity/WorkflowStepUsers.php @@ -0,0 +1,27 @@ +getCcUser() as $u) { + if ($value->getCcUser()->contains($u)) { + $this->context + ->buildViolation($constraint->message) + ->atPath('ccUsers') + ->addViolation(); + } + } + } +} From 6bf8789f8539bc0fe6d64c5321c5107a1556cd9c Mon Sep 17 00:00:00 2001 From: nobohan Date: Wed, 29 Mar 2023 21:07:25 +0200 Subject: [PATCH 14/18] Feature: add cc users in workflow: correct constraint validation --- .../Validator/Constraints/Entity/WorkflowStepUsersValidator.php | 2 +- src/Bundle/ChillMainBundle/translations/validators.fr.yml | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Bundle/ChillMainBundle/Validator/Constraints/Entity/WorkflowStepUsersValidator.php b/src/Bundle/ChillMainBundle/Validator/Constraints/Entity/WorkflowStepUsersValidator.php index 9f3684575..7a45543f8 100644 --- a/src/Bundle/ChillMainBundle/Validator/Constraints/Entity/WorkflowStepUsersValidator.php +++ b/src/Bundle/ChillMainBundle/Validator/Constraints/Entity/WorkflowStepUsersValidator.php @@ -31,7 +31,7 @@ class WorkflowStepUsersValidator extends ConstraintValidator throw new UnexpectedTypeException($constraint, WorkflowStepUsers::class); } - foreach($value->getCcUser() as $u) { + foreach($value->getDestUser() as $u) { if ($value->getCcUser()->contains($u)) { $this->context ->buildViolation($constraint->message) diff --git a/src/Bundle/ChillMainBundle/translations/validators.fr.yml b/src/Bundle/ChillMainBundle/translations/validators.fr.yml index 690629e44..31d3bdc73 100644 --- a/src/Bundle/ChillMainBundle/translations/validators.fr.yml +++ b/src/Bundle/ChillMainBundle/translations/validators.fr.yml @@ -11,6 +11,8 @@ A permission is already present for the same role and scope: Une permission est #UserCircleConsistency "{{ username }} is not allowed to see entities published in this circle": "{{ username }} n'est pas autorisé à voir l'élément publié dans ce cercle." +The user in cc cannot be a dest user in the same workflow step: Un utilisateur en Cc ne peut pas être un utilisateur qui valide. + #password request This username or email does not exists: Cet utilisateur ou email n'est pas présent dans la base de donnée From 1cd153fb78827d295202d871b2ae73315b47176b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Thu, 13 Apr 2023 09:58:22 +0200 Subject: [PATCH 15/18] DX: fix CS --- .../Workflow/Notification/WorkflowNotificationHandler.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Bundle/ChillMainBundle/Workflow/Notification/WorkflowNotificationHandler.php b/src/Bundle/ChillMainBundle/Workflow/Notification/WorkflowNotificationHandler.php index 438e4c0e3..d3e848d41 100644 --- a/src/Bundle/ChillMainBundle/Workflow/Notification/WorkflowNotificationHandler.php +++ b/src/Bundle/ChillMainBundle/Workflow/Notification/WorkflowNotificationHandler.php @@ -30,8 +30,7 @@ class WorkflowNotificationHandler implements NotificationHandlerInterface EntityWorkflowRepository $entityWorkflowRepository, EntityWorkflowManager $entityWorkflowManager, Security $security - ) - { + ) { $this->entityWorkflowRepository = $entityWorkflowRepository; $this->entityWorkflowManager = $entityWorkflowManager; $this->security = $security; From 63759a940f27c157a1686ac23d14c02b2338a9bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Thu, 13 Apr 2023 12:21:48 +0200 Subject: [PATCH 16/18] Feature: [homepage] group the counter of tasks in warning and alert state into one counter --- .../Resources/public/vuejs/HomepageWidget/App.vue | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Bundle/ChillMainBundle/Resources/public/vuejs/HomepageWidget/App.vue b/src/Bundle/ChillMainBundle/Resources/public/vuejs/HomepageWidget/App.vue index fbf453b47..5f0526729 100644 --- a/src/Bundle/ChillMainBundle/Resources/public/vuejs/HomepageWidget/App.vue +++ b/src/Bundle/ChillMainBundle/Resources/public/vuejs/HomepageWidget/App.vue @@ -46,8 +46,7 @@ :class="{'active': activeTab === 'MyTasks'}" @click="selectTab('MyTasks')"> {{ $t('my_tasks.tab') }} - - +