From b9b4fafe14b2c80191128e439fa687fd8b7a00e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Wed, 9 Apr 2025 21:30:41 +0200 Subject: [PATCH 1/5] Adjust cronjob interval to ensure daily execution The interval for `AccompanyingPeriodStepChangeCronjob` was reduced from 24 hours to 23 hours and 45 minutes. This change guarantees at least one execution per day, addressing potential issues with timing overlaps. --- .changes/unreleased/Fixed-20250409-212958.yaml | 6 ++++++ .../Lifecycle/AccompanyingPeriodStepChangeCronjob.php | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 .changes/unreleased/Fixed-20250409-212958.yaml diff --git a/.changes/unreleased/Fixed-20250409-212958.yaml b/.changes/unreleased/Fixed-20250409-212958.yaml new file mode 100644 index 000000000..30b07baf5 --- /dev/null +++ b/.changes/unreleased/Fixed-20250409-212958.yaml @@ -0,0 +1,6 @@ +kind: Fixed +body: Shorten the delay between two execution of AccompanyingPeriodStepChangeCronjob, to ensure at least one execution in a day +time: 2025-04-09T21:29:58.591267777+02:00 +custom: + Issue: "" + SchemaChange: No schema change diff --git a/src/Bundle/ChillPersonBundle/AccompanyingPeriod/Lifecycle/AccompanyingPeriodStepChangeCronjob.php b/src/Bundle/ChillPersonBundle/AccompanyingPeriod/Lifecycle/AccompanyingPeriodStepChangeCronjob.php index 27553444b..80f3a6081 100644 --- a/src/Bundle/ChillPersonBundle/AccompanyingPeriod/Lifecycle/AccompanyingPeriodStepChangeCronjob.php +++ b/src/Bundle/ChillPersonBundle/AccompanyingPeriod/Lifecycle/AccompanyingPeriodStepChangeCronjob.php @@ -26,7 +26,7 @@ readonly class AccompanyingPeriodStepChangeCronjob implements CronJobInterface { $now = $this->clock->now(); - if (null !== $cronJobExecution && $now->sub(new \DateInterval('P1D')) < $cronJobExecution->getLastStart()) { + if (null !== $cronJobExecution && $now->sub(new \DateInterval('PT23H45M')) < $cronJobExecution->getLastStart()) { return false; } From 5858e05a4266f9eebd6292406cde7ef0d26f6ae9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Thu, 10 Apr 2025 15:31:06 +0200 Subject: [PATCH 2/5] Replace grid in person_list document to fit the whole width of the page --- .../Resources/views/GenericDoc/person_list.html.twig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Bundle/ChillDocStoreBundle/Resources/views/GenericDoc/person_list.html.twig b/src/Bundle/ChillDocStoreBundle/Resources/views/GenericDoc/person_list.html.twig index 5bc9f42d1..533a075b6 100644 --- a/src/Bundle/ChillDocStoreBundle/Resources/views/GenericDoc/person_list.html.twig +++ b/src/Bundle/ChillDocStoreBundle/Resources/views/GenericDoc/person_list.html.twig @@ -23,7 +23,7 @@ License * along with this program. If not, see . {{ encore_entry_link_tags("mod_document_action_buttons_group") }} {% endblock %} {% block content %} -
+

{{ 'Documents for %name%'|trans({ '%name%': person|chill_entity_render_string } ) }}

From d58acff54148e0d2fac866d9a66c0dcf7ab4c99f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Thu, 10 Apr 2025 15:33:02 +0200 Subject: [PATCH 3/5] Add css layout for badges for accompanying period work, activity and calendar --- .changes/unreleased/DX-20250410-153426.yaml | 6 ++++ .../Resources/public/chill/chillactivity.scss | 31 ++++++++++++++++ .../Resources/public/chill/scss/badge.scss | 35 ++++++++++++++++++- .../public/chill/scss/calendar-list.scss | 2 +- .../Resources/views/Dev/dev.assets.html.twig | 8 +++++ .../chill/scss/accompanying_period_work.scss | 30 ++++++++++++++++ 6 files changed, 110 insertions(+), 2 deletions(-) create mode 100644 .changes/unreleased/DX-20250410-153426.yaml diff --git a/.changes/unreleased/DX-20250410-153426.yaml b/.changes/unreleased/DX-20250410-153426.yaml new file mode 100644 index 000000000..d86d4dfed --- /dev/null +++ b/.changes/unreleased/DX-20250410-153426.yaml @@ -0,0 +1,6 @@ +kind: DX +body: Add new chill-col style for displaying title and aside in a flex table +time: 2025-04-10T15:34:26.052138894+02:00 +custom: + Issue: "" + SchemaChange: No schema change diff --git a/src/Bundle/ChillActivityBundle/Resources/public/chill/chillactivity.scss b/src/Bundle/ChillActivityBundle/Resources/public/chill/chillactivity.scss index 13de8dfc0..6658656f9 100644 --- a/src/Bundle/ChillActivityBundle/Resources/public/chill/chillactivity.scss +++ b/src/Bundle/ChillActivityBundle/Resources/public/chill/chillactivity.scss @@ -120,3 +120,34 @@ li.document-list-item { vertical-align: baseline; } } + +.badge-activity-type-simple { + @extend .badge; + display: inline-block; + margin: 0.2rem 0; + padding-left: 0; + padding-right: 0.5rem; + + border-left: 20px groove #9acd32; + border-radius: $badge-border-radius; + + color: black; + font-weight: normal; + font-size: unset; + max-width: 100%; + background-color: $gray-100; + + overflow: hidden; + text-overflow: ellipsis; + text-indent: 5px hanging; + text-align: left; + + &::before { + margin-right: 3px; + position: relative; + left: -0.5px; + font-family: ForkAwesome; + content: '\f04b'; + color: #9acd32; + } +} diff --git a/src/Bundle/ChillCalendarBundle/Resources/public/chill/scss/badge.scss b/src/Bundle/ChillCalendarBundle/Resources/public/chill/scss/badge.scss index ffcda8f0f..04d22bfc5 100644 --- a/src/Bundle/ChillCalendarBundle/Resources/public/chill/scss/badge.scss +++ b/src/Bundle/ChillCalendarBundle/Resources/public/chill/scss/badge.scss @@ -1,5 +1,6 @@ -@import '~ChillPersonAssets/chill/scss/mixins.scss'; @import '~ChillMainAssets/module/bootstrap/shared'; +@import '~ChillPersonAssets/chill/scss/mixins.scss'; +@import 'bootstrap/scss/_badge.scss'; .badge-calendar { display: inline-block; @@ -23,3 +24,35 @@ } } +.badge-calendar-simple { + @extend .badge; + display: inline-block; + margin: 0.2rem 0; + padding-left: 0; + padding-right: 0.5rem; + + border-left: 20px groove $chill-l-gray; + border-radius: $badge-border-radius; + + max-width: 100%; + background-color: $gray-100; + + color: black; + font-weight: normal; + overflow: hidden; + font-weight: normal; + font-size: unset; + text-overflow: ellipsis; + text-indent: 5px hanging; + text-align: left; + + &::before { + margin-right: 3px; + position: relative; + left: -0.5px; + font-family: ForkAwesome; + content: '\f04b'; + color: $chill-l-gray; + } +} + diff --git a/src/Bundle/ChillCalendarBundle/Resources/public/chill/scss/calendar-list.scss b/src/Bundle/ChillCalendarBundle/Resources/public/chill/scss/calendar-list.scss index c232b78e2..6fa84f15a 100644 --- a/src/Bundle/ChillCalendarBundle/Resources/public/chill/scss/calendar-list.scss +++ b/src/Bundle/ChillCalendarBundle/Resources/public/chill/scss/calendar-list.scss @@ -16,7 +16,7 @@ div.calendar-list { } & > a.calendar-list__global { - display: inline-block;; + display: inline-block; padding: 0.2rem; min-width: 2rem; border: 1px solid var(--bs-chill-blue); diff --git a/src/Bundle/ChillMainBundle/Resources/views/Dev/dev.assets.html.twig b/src/Bundle/ChillMainBundle/Resources/views/Dev/dev.assets.html.twig index 5aafb6635..6322ca68f 100644 --- a/src/Bundle/ChillMainBundle/Resources/views/Dev/dev.assets.html.twig +++ b/src/Bundle/ChillMainBundle/Resources/views/Dev/dev.assets.html.twig @@ -392,4 +392,12 @@ Toutes les classes btn-* de bootstrap sont fonctionnelles
+
+

Badges

+ + Action d'accompagnement + Type d'échange + Rendez-vous +
+ {% endblock %} diff --git a/src/Bundle/ChillPersonBundle/Resources/public/chill/scss/accompanying_period_work.scss b/src/Bundle/ChillPersonBundle/Resources/public/chill/scss/accompanying_period_work.scss index e82029a1f..017b98961 100644 --- a/src/Bundle/ChillPersonBundle/Resources/public/chill/scss/accompanying_period_work.scss +++ b/src/Bundle/ChillPersonBundle/Resources/public/chill/scss/accompanying_period_work.scss @@ -20,6 +20,36 @@ } } +.badge-accompanying-work-type-simple { + @extend .badge; + display: inline-block; + margin: 0.2rem 0; + padding-left: 0; + padding-right: 0.5rem; + + border-left: 20px groove $orange; + border-radius: $badge-border-radius; + + max-width: 100%; + background-color: $gray-100; + + color: black; + font-weight: normal; + overflow: hidden; + text-overflow: ellipsis; + text-indent: 5px hanging; + text-align: left; + + &::before { + margin-right: 3px; + position: relative; + left: -0.5px; + font-family: ForkAwesome; + content: '\f04b'; + color: #e2793d; + } +} + /// AccompanyingCourse Work Pages div.accompanying-course-work { From 203a0980545338716c2a671d43c6e77005337a00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Thu, 10 Apr 2025 15:33:22 +0200 Subject: [PATCH 4/5] Refactor document row layouts to use CSS grid Replaced the old 'item-col' structure with a 'item-two-col-grid' layout across multiple templates, improving consistency and responsiveness. Introduced CSS grid styles ensuring proper alignment and wrapping of titles and aside elements in different viewport sizes. This enhances the overall readability and maintainability of the views. --- .../unreleased/Fixed-20250410-153354.yaml | 6 ++ .../activity_document_row.html.twig | 58 +++++++------- .../calendar_document_row.html.twig | 72 ++++++++--------- .../views/List/list_item_row.html.twig | 80 +++++++++---------- .../public/chill/scss/flex_table.scss | 27 +++++++ .../Resources/views/Dev/dev.assets.html.twig | 53 ++++++++++++ .../evaluation_document_row.html.twig | 73 +++++++++-------- 7 files changed, 229 insertions(+), 140 deletions(-) create mode 100644 .changes/unreleased/Fixed-20250410-153354.yaml diff --git a/.changes/unreleased/Fixed-20250410-153354.yaml b/.changes/unreleased/Fixed-20250410-153354.yaml new file mode 100644 index 000000000..d5c0b5652 --- /dev/null +++ b/.changes/unreleased/Fixed-20250410-153354.yaml @@ -0,0 +1,6 @@ +kind: Fixed +body: Fix display of title in document list +time: 2025-04-10T15:33:54.660510278+02:00 +custom: + Issue: "102" + SchemaChange: No schema change diff --git a/src/Bundle/ChillActivityBundle/Resources/views/GenericDoc/activity_document_row.html.twig b/src/Bundle/ChillActivityBundle/Resources/views/GenericDoc/activity_document_row.html.twig index 6ca871de1..93bb01f1e 100644 --- a/src/Bundle/ChillActivityBundle/Resources/views/GenericDoc/activity_document_row.html.twig +++ b/src/Bundle/ChillActivityBundle/Resources/views/GenericDoc/activity_document_row.html.twig @@ -13,44 +13,44 @@ {% endif %}
-
- {% if document.isPending %} -
{{ 'docgen.Doc generation is pending'|trans }}
- {% elseif document.isFailure %} -
{{ 'docgen.Doc generation failed'|trans }}
- {% endif %} - -
- {% if activity.accompanyingPeriod is not null and context == 'person' %} - - {{ activity.accompanyingPeriod.id }} -   +
+
+ {% if document.isPending %} +
{{ 'docgen.Doc generation is pending'|trans }}
+ {% elseif document.isFailure %} +
{{ 'docgen.Doc generation failed'|trans }}
{% endif %} -
- - - {{ activity.type.name | localize_translatable_string }} + +
+
+
+ {{ activity.type.name | localize_translatable_string }} +
{% if activity.emergency %} {{ 'Emergency'|trans|upper }} {% endif %} - +
-
-
- {{ document.title|chill_print_or_message("No title") }} -
- {% if document.hasTemplate %} -
-

{{ document.template.name|localize_translatable_string }}

+
+ {{ document.title|chill_print_or_message("No title") }}
- {% endif %} -
- -
-
+ {% if document.hasTemplate %} +
+

{{ document.template.name|localize_translatable_string }}

+
+ {% endif %} +
+
{{ document.createdAt|format_date('short') }}
+ {% if activity.accompanyingPeriod is not null and context == 'person' %} +
+ + {{ activity.accompanyingPeriod.id }} +   +
+ {% endif %}
diff --git a/src/Bundle/ChillCalendarBundle/Resources/views/GenericDoc/calendar_document_row.html.twig b/src/Bundle/ChillCalendarBundle/Resources/views/GenericDoc/calendar_document_row.html.twig index 8cf5bc4ac..8015ac600 100644 --- a/src/Bundle/ChillCalendarBundle/Resources/views/GenericDoc/calendar_document_row.html.twig +++ b/src/Bundle/ChillCalendarBundle/Resources/views/GenericDoc/calendar_document_row.html.twig @@ -6,50 +6,48 @@
-
- {% if document.storedObject.isPending %} -
{{ 'docgen.Doc generation is pending'|trans }}
- {% elseif document.storedObject.isFailure %} -
{{ 'docgen.Doc generation failed'|trans }}
- {% endif %} - -
- {% if c.accompanyingPeriod is not null and context == 'person' %} - - {{ c.accompanyingPeriod.id }} -   +
+
+ {% if document.storedObject.isPending %} +
{{ 'docgen.Doc generation is pending'|trans }}
+ {% elseif document.storedObject.isFailure %} +
{{ 'docgen.Doc generation failed'|trans }}
{% endif %} - - - - {{ 'Calendar'|trans }} - {% if c.endDate.diff(c.startDate).days >= 1 %} - {{ c.startDate|format_datetime('short', 'short') }} - - {{ c.endDate|format_datetime('short', 'short') }} - {% else %} - {{ c.startDate|format_datetime('short', 'short') }} - - {{ c.endDate|format_datetime('none', 'short') }} - {% endif %} - - -
- -
- {{ document.storedObject.title|chill_print_or_message("No title") }} -
- {% if document.storedObject.hasTemplate %}
-

{{ document.storedObject.template.name|localize_translatable_string }}

-
- {% endif %} -
-
-
+ + {{ 'Calendar'|trans }} + {% if c.endDate.diff(c.startDate).days >= 1 %} + {{ c.startDate|format_datetime('short', 'short') }} + - {{ c.endDate|format_datetime('short', 'short') }} + {% else %} + {{ c.startDate|format_datetime('short', 'short') }} + - {{ c.endDate|format_datetime('none', 'short') }} + {% endif %} + +
+ +
+ {{ document.storedObject.title|chill_print_or_message("No title") }} +
+ {% if document.storedObject.hasTemplate %} +
+

{{ document.storedObject.template.name|localize_translatable_string }}

+
+ {% endif %} +
+
{{ document.storedObject.createdAt|format_date('short') }}
+ {% if c.accompanyingPeriod is not null and context == 'person' %} +
+ + {{ c.accompanyingPeriod.id }} +   +
+ {% endif %}
diff --git a/src/Bundle/ChillDocStoreBundle/Resources/views/List/list_item_row.html.twig b/src/Bundle/ChillDocStoreBundle/Resources/views/List/list_item_row.html.twig index 21812c903..a92cea589 100644 --- a/src/Bundle/ChillDocStoreBundle/Resources/views/List/list_item_row.html.twig +++ b/src/Bundle/ChillDocStoreBundle/Resources/views/List/list_item_row.html.twig @@ -3,54 +3,54 @@ {% import '@ChillPerson/Macro/updatedBy.html.twig' as mmm %}
-
- {% if document.object.isPending %} -
{{ 'docgen.Doc generation is pending'|trans }}
- {% elseif document.object.isFailure %} -
{{ 'docgen.Doc generation failed'|trans }}
- {% endif %} + +
+
+ {% if document.object.isPending %} +
{{ 'docgen.Doc generation is pending'|trans }}
+ {% elseif document.object.isFailure %} +
{{ 'docgen.Doc generation failed'|trans }}
+ {% endif %} - {% if context == 'person' and accompanyingCourse is defined %} -
- - {{ accompanyingCourse.id }} -   +
+ {{ document.title|chill_print_or_message("No title") }}
- {% elseif context == 'accompanying-period' and person is defined %} + {% if document.object.type is not empty %} +
+ {{ mm.mimeIcon(document.object.type) }} +
+ {% endif %}
- - {{ 'Document from person %name%'|trans({ '%name%': document.person|chill_entity_render_string }) }} -   +

{{ document.category.name|localize_translatable_string }}

- - {% endif %} -
- {{ document.title|chill_print_or_message("No title") }} -
- {% if document.object.type is not empty %} -
- {{ mm.mimeIcon(document.object.type) }} -
- {% endif %} -
-

{{ document.category.name|localize_translatable_string }}

-
- {% if document.object.hasTemplate %} -
-

{{ document.object.template.name|localize_translatable_string }}

-
- {% endif %} -
- -
-
- {% if document.date is not null %} -
- {{ document.date|format_date('short') }} + {% if document.object.hasTemplate %} +
+

{{ document.object.template.name|localize_translatable_string }}

{% endif %}
+ {% if document.date is not null %} +
+
+ {{ document.date|format_date('short') }} +
+ {% if context == 'person' and accompanyingCourse is defined %} +
+ + {{ accompanyingCourse.id }} +   +
+ {% elseif context == 'accompanying-period' and person is defined %} +
+ + {{ document.person|chill_entity_render_string }} +   +
+ {% endif %} +
+ {% endif %}
+
{% if document.description is not empty %}
diff --git a/src/Bundle/ChillMainBundle/Resources/public/chill/scss/flex_table.scss b/src/Bundle/ChillMainBundle/Resources/public/chill/scss/flex_table.scss index 0adf2b628..7ac52b24e 100644 --- a/src/Bundle/ChillMainBundle/Resources/public/chill/scss/flex_table.scss +++ b/src/Bundle/ChillMainBundle/Resources/public/chill/scss/flex_table.scss @@ -25,7 +25,34 @@ div.flex-table { div.item-col:last-child { display: flex; } + + div.item-two-col-grid { + display: grid; + width: 100%; + justify-content: stretch; + + @include media-breakpoint-up(lg) { + grid-template-areas: + "title aside"; + grid-template-columns: 1fr minmax(8rem, 1fr); + column-gap: 0.5em; + } + @include media-breakpoint-down(lg) { + grid-template-areas: + "aside" + "title"; + } + + & > div.title { + grid-area: title; + } + + & > div.aside { + grid-area: aside; + } + } } + } h2, h3, h4, dl, p { diff --git a/src/Bundle/ChillMainBundle/Resources/views/Dev/dev.assets.html.twig b/src/Bundle/ChillMainBundle/Resources/views/Dev/dev.assets.html.twig index 6322ca68f..927e496f9 100644 --- a/src/Bundle/ChillMainBundle/Resources/views/Dev/dev.assets.html.twig +++ b/src/Bundle/ChillMainBundle/Resources/views/Dev/dev.assets.html.twig @@ -136,6 +136,59 @@
+

Fix the title in the flex table

+ +

This will fix the layout of the row, with a "title" element, and an aside element. Using css grid, this is quite safe and won't overflow

+ + + <div class="flex-table"> + <div class="item-bloc"> + <div class="item-row"> + <div class="item-two-col-grid"> + <div class="title">This is my title</div> + <div class="aside">Aside value</div> + </div> + </div> + </div> + <div class="item-bloc"> + <div class="item-row"> + <div class="item-two-col-grid"> + <div class="title"> + <div><h3>This is my title, which can be very long and take a lot of place. But it is wrapped successfully, and won't disturb the placement of the aside block</h3></div> + <div>This is a second line</div> + </div> + <div class="aside">Aside value</div> + </div> + </div> + </div> + </div> + + +

will render:

+ +
+
+
+
+
This is my title
+
Aside value
+
+
+
+
+
+
+
+

This is my title, which can be very long and take a lot of place. But it is wrapped successfully, and won't disturb the placement of the aside block

+
This is a second line
+
+
Aside value
+
+
+
+
+ +

Wrap-list

Une liste inline qui s'aligne, puis glisse sous son titre.

diff --git a/src/Bundle/ChillPersonBundle/Resources/views/GenericDoc/evaluation_document_row.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/GenericDoc/evaluation_document_row.html.twig index 451857628..50570ddc6 100644 --- a/src/Bundle/ChillPersonBundle/Resources/views/GenericDoc/evaluation_document_row.html.twig +++ b/src/Bundle/ChillPersonBundle/Resources/views/GenericDoc/evaluation_document_row.html.twig @@ -5,44 +5,49 @@ {% set w = document.accompanyingPeriodWorkEvaluation.accompanyingPeriodWork %}
-
- {% if document.storedObject.isPending %} -
{{ 'docgen.Doc generation is pending'|trans }}
- {% elseif document.storedObject.isFailure %} -
{{ 'docgen.Doc generation failed'|trans }}
- {% endif %} -
- {% if context == 'person' %} - - {{ w.accompanyingPeriod.id }} -   + +
+
+ {% if document.storedObject.isPending %} +
{{ 'docgen.Doc generation is pending'|trans }}
+ {% elseif document.storedObject.isFailure %} +
{{ 'docgen.Doc generation failed'|trans }}
{% endif %} -
- - {{ w.socialAction|chill_entity_render_string }} > {{ document.accompanyingPeriodWorkEvaluation.evaluation.title|localize_translatable_string }} -
-
-
- {{ document.title|chill_print_or_message("No title") }} -
- {% if document.storedObject.type is not empty %}
- {{ mm.mimeIcon(document.storedObject.type) }} +
+
+ {{ w.socialAction|chill_entity_render_string }} > {{ document.accompanyingPeriodWorkEvaluation.evaluation.title|localize_translatable_string }} +
+
+
+
+ {{ document.title|chill_print_or_message("No title") }} +
+ {% if document.storedObject.type is not empty %} +
+ {{ mm.mimeIcon(document.storedObject.type) }} +
+ {% endif %} + {% if document.storedObject.hasTemplate %} +
+

{{ document.storedObject.template.name|localize_translatable_string }}

+
+ {% endif %} +
+ {% if document.storedObject.createdAt is not null %} +
+
+ {{ document.storedObject.createdAt|format_date('short') }} +
+ {% if context == 'person' %} +
+ + {{ w.accompanyingPeriod.id }} +   +
+ {% endif %}
{% endif %} - {% if document.storedObject.hasTemplate %} -
-

{{ document.storedObject.template.name|localize_translatable_string }}

-
- {% endif %} -
- -
-
-
- {{ document.storedObject.createdAt|format_date('short') }} -
-
From 40e373a9c7ca4ef4a4cfa863ac2db79b9ee8257d Mon Sep 17 00:00:00 2001 From: juminet Date: Mon, 14 Apr 2025 09:34:02 +0000 Subject: [PATCH 5/5] #365 Add works and activities counter --- .../unreleased/Feature-20250319-090004.yaml | 9 +++++++ .../Menu/AccompanyingCourseMenuBuilder.php | 15 ++++++++--- .../Menu/PersonMenuBuilder.php | 12 +++++++-- .../AccompanyingCourseController.php | 11 +++++--- .../Entity/AccompanyingPeriod.php | 8 ++++++ .../Menu/AccompanyingCourseMenuBuilder.php | 9 ++++--- .../Resources/public/chill/chillperson.scss | 9 +++++++ .../views/AccompanyingCourse/index.html.twig | 27 ++++++++++++++++++- .../translations/messages.fr.yml | 5 +++- 9 files changed, 92 insertions(+), 13 deletions(-) create mode 100644 .changes/unreleased/Feature-20250319-090004.yaml diff --git a/.changes/unreleased/Feature-20250319-090004.yaml b/.changes/unreleased/Feature-20250319-090004.yaml new file mode 100644 index 000000000..3b4528b29 --- /dev/null +++ b/.changes/unreleased/Feature-20250319-090004.yaml @@ -0,0 +1,9 @@ +kind: Feature +body: Add counters of actions and activities, with 2 boxes to (1) show the number + of active actions on total actions and (2) show the number of activities in a accompanying + period, and pills in menus for showing the number of active actions and the number + of activities. +time: 2025-03-19T09:00:04.152359515+01:00 +custom: + Issue: "365" + SchemaChange: No schema change diff --git a/src/Bundle/ChillActivityBundle/Menu/AccompanyingCourseMenuBuilder.php b/src/Bundle/ChillActivityBundle/Menu/AccompanyingCourseMenuBuilder.php index b4990c0e3..5ed606637 100644 --- a/src/Bundle/ChillActivityBundle/Menu/AccompanyingCourseMenuBuilder.php +++ b/src/Bundle/ChillActivityBundle/Menu/AccompanyingCourseMenuBuilder.php @@ -11,6 +11,7 @@ declare(strict_types=1); namespace Chill\ActivityBundle\Menu; +use Chill\ActivityBundle\Entity\Activity; use Chill\ActivityBundle\Security\Authorization\ActivityVoter; use Chill\MainBundle\Routing\LocalMenuBuilderInterface; use Chill\PersonBundle\Entity\AccompanyingPeriod; @@ -23,22 +24,30 @@ use Symfony\Contracts\Translation\TranslatorInterface; */ class AccompanyingCourseMenuBuilder implements LocalMenuBuilderInterface { - public function __construct(protected Security $security, protected TranslatorInterface $translator) {} + public function __construct( + protected Security $security, + protected TranslatorInterface $translator, + private readonly \Doctrine\Persistence\ManagerRegistry $managerRegistry, + ) {} public function buildMenu($menuId, MenuItem $menu, array $parameters) { $period = $parameters['accompanyingCourse']; + $activities = $this->managerRegistry->getManager()->getRepository(Activity::class)->findBy( + ['accompanyingPeriod' => $period] + ); + if ( AccompanyingPeriod::STEP_DRAFT !== $period->getStep() && $this->security->isGranted(ActivityVoter::SEE, $period) ) { - $menu->addChild($this->translator->trans('Activity'), [ + $menu->addChild($this->translator->trans('Activities'), [ 'route' => 'chill_activity_activity_list', 'routeParameters' => [ 'accompanying_period_id' => $period->getId(), ], ]) - ->setExtras(['order' => 40]); + ->setExtras(['order' => 40, 'counter' => count($activities) > 0 ? count($activities) : null]); } } diff --git a/src/Bundle/ChillActivityBundle/Menu/PersonMenuBuilder.php b/src/Bundle/ChillActivityBundle/Menu/PersonMenuBuilder.php index 797d64eb6..5a13c5d65 100644 --- a/src/Bundle/ChillActivityBundle/Menu/PersonMenuBuilder.php +++ b/src/Bundle/ChillActivityBundle/Menu/PersonMenuBuilder.php @@ -11,6 +11,7 @@ declare(strict_types=1); namespace Chill\ActivityBundle\Menu; +use Chill\ActivityBundle\Repository\ActivityACLAwareRepositoryInterface; use Chill\ActivityBundle\Security\Authorization\ActivityVoter; use Chill\MainBundle\Routing\LocalMenuBuilderInterface; use Chill\PersonBundle\Entity\Person; @@ -23,13 +24,20 @@ use Symfony\Contracts\Translation\TranslatorInterface; */ final readonly class PersonMenuBuilder implements LocalMenuBuilderInterface { - public function __construct(private AuthorizationCheckerInterface $authorizationChecker, private TranslatorInterface $translator) {} + public function __construct( + private readonly ActivityACLAwareRepositoryInterface $activityACLAwareRepository, + private AuthorizationCheckerInterface $authorizationChecker, + private TranslatorInterface $translator, + ) {} public function buildMenu($menuId, MenuItem $menu, array $parameters) { /** @var Person $person */ $person = $parameters['person']; + + $count = $this->activityACLAwareRepository->countByPerson($person, ActivityVoter::SEE); + if ($this->authorizationChecker->isGranted(ActivityVoter::SEE, $person)) { $menu->addChild( $this->translator->trans('Activities'), @@ -38,7 +46,7 @@ final readonly class PersonMenuBuilder implements LocalMenuBuilderInterface 'routeParameters' => ['person_id' => $person->getId()], ] ) - ->setExtra('order', 201); + ->setExtras(['order' => 201, 'counter' => $count > 0 ? $count : null]); } } diff --git a/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseController.php b/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseController.php index 754be808a..0cb3c1473 100644 --- a/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseController.php +++ b/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseController.php @@ -204,20 +204,25 @@ final class AccompanyingCourseController extends \Symfony\Bundle\FrameworkBundle ['date' => 'DESC', 'id' => 'DESC'], ); - $activities = \array_slice($activities, 0, 3); - $works = $this->workRepository->findByAccompanyingPeriod( $accompanyingCourse, ['startDate' => 'DESC', 'endDate' => 'DESC'], 3 ); + $counters = [ + 'activities' => count($activities), + 'openWorks' => count($accompanyingCourse->getOpenWorks()), + 'works' => count($works), + ]; + return $this->render('@ChillPerson/AccompanyingCourse/index.html.twig', [ 'accompanyingCourse' => $accompanyingCourse, 'withoutHousehold' => $withoutHousehold, 'participationsByHousehold' => $accompanyingCourse->actualParticipationsByHousehold(), 'works' => $works, - 'activities' => $activities, + 'activities' => \array_slice($activities, 0, 3), + 'counters' => $counters, ]); } diff --git a/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php b/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php index 91c8714bb..d96814e1a 100644 --- a/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php +++ b/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php @@ -511,6 +511,14 @@ class AccompanyingPeriod implements return $this->getParticipationsContainsPerson($person)->count() > 0; } + public function getOpenWorks(): Collection + { + return $this->getWorks()->filter( + static fn (AccompanyingPeriodWork $work): bool => null === $work->getEndDate() + or $work->getEndDate() > new \DateTimeImmutable('today') + ); + } + /** * Open a new participation for a person. */ diff --git a/src/Bundle/ChillPersonBundle/Menu/AccompanyingCourseMenuBuilder.php b/src/Bundle/ChillPersonBundle/Menu/AccompanyingCourseMenuBuilder.php index 79cd19db9..8c93f461d 100644 --- a/src/Bundle/ChillPersonBundle/Menu/AccompanyingCourseMenuBuilder.php +++ b/src/Bundle/ChillPersonBundle/Menu/AccompanyingCourseMenuBuilder.php @@ -71,7 +71,7 @@ class AccompanyingCourseMenuBuilder implements LocalMenuBuilderInterface ->setExtras(['order' => 30]); */ - $menu->addChild($this->translator->trans('Accompanying Course Comment'), [ + $menu->addChild($this->translator->trans('Accompanying Course Comments'), [ 'route' => 'chill_person_accompanying_period_comment_list', 'routeParameters' => [ 'accompanying_period_id' => $period->getId(), @@ -80,12 +80,15 @@ class AccompanyingCourseMenuBuilder implements LocalMenuBuilderInterface } if ($this->security->isGranted(AccompanyingPeriodWorkVoter::SEE, $period)) { - $menu->addChild($this->translator->trans('Accompanying Course Action'), [ + $menu->addChild($this->translator->trans('Accompanying Course Actions'), [ 'route' => 'chill_person_accompanying_period_work_list', 'routeParameters' => [ 'id' => $period->getId(), ], ]) - ->setExtras(['order' => 40]); + ->setExtras([ + 'order' => 40, + 'counter' => count($period->getOpenWorks()) > 0 ? count($period->getOpenWorks()) : null, + ]); } $workflow = $this->registry->get($period, 'accompanying_period_lifecycle'); diff --git a/src/Bundle/ChillPersonBundle/Resources/public/chill/chillperson.scss b/src/Bundle/ChillPersonBundle/Resources/public/chill/chillperson.scss index 24f947100..afa163cf2 100644 --- a/src/Bundle/ChillPersonBundle/Resources/public/chill/chillperson.scss +++ b/src/Bundle/ChillPersonBundle/Resources/public/chill/chillperson.scss @@ -304,5 +304,14 @@ div#dashboards { margin: 0; } } + div.count-item { + font-size: 3rem; + text-align: center; + } + div.count-item-label { + font-size: 90%; + font-variant: all-small-caps; + text-align: center; + } } } diff --git a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourse/index.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourse/index.html.twig index 4ceadf7a1..3637de6c8 100644 --- a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourse/index.html.twig +++ b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourse/index.html.twig @@ -201,7 +201,7 @@ {% endif %} {% if accompanyingCourse.step != 'DRAFT' %} -
+

{{ 'notification.Notifications'|trans }}

{% set notif_counter = chill_count_notifications('Chill\\PersonBundle\\Entity\\AccompanyingPeriod', accompanyingCourse.id) %} @@ -238,6 +238,31 @@
{% endif %} + + {% if counters.activities > 0 %} +
+
+
{{ counters.activities }}
+
+ {% if counters.activities == 1 %} + {{ 'Activity'|trans }} + {% else %} + {{ 'Activities'|trans }} + {% endif %} +
+
+
+ {% endif %} + + {% if counters.works > 0 %} +
+
+
{{ counters.openWorks }} / {{ counters.works }}
+
{{ 'accompanying_course_work.On-going works over total'|trans }}
+
+
+ {% endif %} +