mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
Merge remote-tracking branch 'refs/remotes/origin/master' into 359-fusion-accompanying-period-work
This commit is contained in:
commit
0581b59dbd
6
.changes/unreleased/DX-20250410-153426.yaml
Normal file
6
.changes/unreleased/DX-20250410-153426.yaml
Normal file
@ -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
|
9
.changes/unreleased/Feature-20250319-090004.yaml
Normal file
9
.changes/unreleased/Feature-20250319-090004.yaml
Normal file
@ -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
|
6
.changes/unreleased/Fixed-20250409-212958.yaml
Normal file
6
.changes/unreleased/Fixed-20250409-212958.yaml
Normal file
@ -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
|
6
.changes/unreleased/Fixed-20250410-153354.yaml
Normal file
6
.changes/unreleased/Fixed-20250410-153354.yaml
Normal file
@ -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
|
@ -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]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -13,44 +13,44 @@
|
||||
{% endif %}
|
||||
|
||||
<div class="item-row">
|
||||
<div class="item-col" style="width: unset">
|
||||
{% if document.isPending %}
|
||||
<div class="badge text-bg-info" data-docgen-is-pending="{{ document.id }}">{{ 'docgen.Doc generation is pending'|trans }}</div>
|
||||
{% elseif document.isFailure %}
|
||||
<div class="badge text-bg-warning">{{ 'docgen.Doc generation failed'|trans }}</div>
|
||||
{% endif %}
|
||||
|
||||
<div>
|
||||
{% if activity.accompanyingPeriod is not null and context == 'person' %}
|
||||
<span class="badge bg-primary">
|
||||
<i class="fa fa-random"></i> {{ activity.accompanyingPeriod.id }}
|
||||
</span>
|
||||
<div class="item-two-col-grid">
|
||||
<div class="title">
|
||||
{% if document.isPending %}
|
||||
<div class="badge text-bg-info" data-docgen-is-pending="{{ document.id }}">{{ 'docgen.Doc generation is pending'|trans }}</div>
|
||||
{% elseif document.isFailure %}
|
||||
<div class="badge text-bg-warning">{{ 'docgen.Doc generation failed'|trans }}</div>
|
||||
{% endif %}
|
||||
<div class="badge-activity-type">
|
||||
<span class="title_label"></span>
|
||||
<span class="title_action">
|
||||
{{ activity.type.name | localize_translatable_string }}
|
||||
|
||||
<div>
|
||||
<div>
|
||||
<div class="badge-activity-type-simple">
|
||||
{{ activity.type.name | localize_translatable_string }}
|
||||
</div>
|
||||
{% if activity.emergency %}
|
||||
<span class="badge bg-danger rounded-pill fs-6 float-end">{{ 'Emergency'|trans|upper }}</span>
|
||||
{% endif %}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="denomination h2">
|
||||
{{ document.title|chill_print_or_message("No title") }}
|
||||
</div>
|
||||
{% if document.hasTemplate %}
|
||||
<div>
|
||||
<p>{{ document.template.name|localize_translatable_string }}</p>
|
||||
<div class="denomination h2">
|
||||
{{ document.title|chill_print_or_message("No title") }}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="item-col">
|
||||
<div class="container">
|
||||
{% if document.hasTemplate %}
|
||||
<div>
|
||||
<p>{{ document.template.name|localize_translatable_string }}</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="aside">
|
||||
<div class="dates row text-end">
|
||||
<span>{{ document.createdAt|format_date('short') }}</span>
|
||||
</div>
|
||||
{% if activity.accompanyingPeriod is not null and context == 'person' %}
|
||||
<div class="text-end">
|
||||
<span class="badge bg-primary">
|
||||
<i class="fa fa-random"></i> {{ activity.accompanyingPeriod.id }}
|
||||
</span>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -6,50 +6,48 @@
|
||||
|
||||
|
||||
<div class="item-row">
|
||||
<div class="item-col" style="width: unset">
|
||||
{% if document.storedObject.isPending %}
|
||||
<div class="badge text-bg-info" data-docgen-is-pending="{{ document.storedObject.id }}">{{ 'docgen.Doc generation is pending'|trans }}</div>
|
||||
{% elseif document.storedObject.isFailure %}
|
||||
<div class="badge text-bg-warning">{{ 'docgen.Doc generation failed'|trans }}</div>
|
||||
{% endif %}
|
||||
|
||||
<div>
|
||||
{% if c.accompanyingPeriod is not null and context == 'person' %}
|
||||
<span class="badge bg-primary">
|
||||
<i class="fa fa-random"></i> {{ c.accompanyingPeriod.id }}
|
||||
</span>
|
||||
<div class="item-two-col-grid">
|
||||
<div class="title">
|
||||
{% if document.storedObject.isPending %}
|
||||
<div class="badge text-bg-info" data-docgen-is-pending="{{ document.storedObject.id }}">{{ 'docgen.Doc generation is pending'|trans }}</div>
|
||||
{% elseif document.storedObject.isFailure %}
|
||||
<div class="badge text-bg-warning">{{ 'docgen.Doc generation failed'|trans }}</div>
|
||||
{% endif %}
|
||||
|
||||
<span class="badge-calendar">
|
||||
<span class="title_label"></span>
|
||||
<span class="title_action">
|
||||
{{ '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 %}
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="denomination h2">
|
||||
{{ document.storedObject.title|chill_print_or_message("No title") }}
|
||||
</div>
|
||||
{% if document.storedObject.hasTemplate %}
|
||||
<div>
|
||||
<p>{{ document.storedObject.template.name|localize_translatable_string }}</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="item-col">
|
||||
<div class="container">
|
||||
<span class="badge-calendar-simple">
|
||||
{{ '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 %}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="denomination h2">
|
||||
{{ document.storedObject.title|chill_print_or_message("No title") }}
|
||||
</div>
|
||||
{% if document.storedObject.hasTemplate %}
|
||||
<div>
|
||||
<p>{{ document.storedObject.template.name|localize_translatable_string }}</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="aside">
|
||||
<div class="dates row text-end">
|
||||
<span>{{ document.storedObject.createdAt|format_date('short') }}</span>
|
||||
</div>
|
||||
{% if c.accompanyingPeriod is not null and context == 'person' %}
|
||||
<div class="text-end">
|
||||
<span class="badge bg-primary">
|
||||
<i class="fa fa-random"></i> {{ c.accompanyingPeriod.id }}
|
||||
</span>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -23,7 +23,7 @@ License * along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
{{ encore_entry_link_tags("mod_document_action_buttons_group") }}
|
||||
{% endblock %} {% block content %}
|
||||
|
||||
<div class="col-md-10 col-xxl">
|
||||
<div class="document-list">
|
||||
<h1>
|
||||
{{ 'Documents for %name%'|trans({ '%name%': person|chill_entity_render_string } ) }}
|
||||
</h1>
|
||||
|
@ -3,54 +3,54 @@
|
||||
{% import '@ChillPerson/Macro/updatedBy.html.twig' as mmm %}
|
||||
|
||||
<div class="item-row">
|
||||
<div class="item-col" style="width: unset">
|
||||
{% if document.object.isPending %}
|
||||
<div class="badge text-bg-info" data-docgen-is-pending="{{ document.object.id }}">{{ 'docgen.Doc generation is pending'|trans }}</div>
|
||||
{% elseif document.object.isFailure %}
|
||||
<div class="badge text-bg-warning">{{ 'docgen.Doc generation failed'|trans }}</div>
|
||||
{% endif %}
|
||||
<!-- person document or accompanying course document -->
|
||||
<div class="item-two-col-grid">
|
||||
<div class="title">
|
||||
{% if document.object.isPending %}
|
||||
<div class="badge text-bg-info" data-docgen-is-pending="{{ document.object.id }}">{{ 'docgen.Doc generation is pending'|trans }}</div>
|
||||
{% elseif document.object.isFailure %}
|
||||
<div class="badge text-bg-warning">{{ 'docgen.Doc generation failed'|trans }}</div>
|
||||
{% endif %}
|
||||
|
||||
{% if context == 'person' and accompanyingCourse is defined %}
|
||||
<div>
|
||||
<span class="badge bg-primary">
|
||||
<i class="fa fa-random"></i> {{ accompanyingCourse.id }}
|
||||
</span>
|
||||
<div class="denomination h2">
|
||||
{{ document.title|chill_print_or_message("No title") }}
|
||||
</div>
|
||||
{% elseif context == 'accompanying-period' and person is defined %}
|
||||
{% if document.object.type is not empty %}
|
||||
<div>
|
||||
{{ mm.mimeIcon(document.object.type) }}
|
||||
</div>
|
||||
{% endif %}
|
||||
<div>
|
||||
<span class="badge bg-primary">
|
||||
{{ 'Document from person %name%'|trans({ '%name%': document.person|chill_entity_render_string }) }}
|
||||
</span>
|
||||
<p>{{ document.category.name|localize_translatable_string }}</p>
|
||||
</div>
|
||||
|
||||
{% endif %}
|
||||
<div class="denomination h2">
|
||||
{{ document.title|chill_print_or_message("No title") }}
|
||||
</div>
|
||||
{% if document.object.type is not empty %}
|
||||
<div>
|
||||
{{ mm.mimeIcon(document.object.type) }}
|
||||
</div>
|
||||
{% endif %}
|
||||
<div>
|
||||
<p>{{ document.category.name|localize_translatable_string }}</p>
|
||||
</div>
|
||||
{% if document.object.hasTemplate %}
|
||||
<div>
|
||||
<p>{{ document.object.template.name|localize_translatable_string }}</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="item-col">
|
||||
<div class="container">
|
||||
{% if document.date is not null %}
|
||||
<div class="dates row text-end">
|
||||
<span>{{ document.date|format_date('short') }}</span>
|
||||
{% if document.object.hasTemplate %}
|
||||
<div>
|
||||
<p>{{ document.object.template.name|localize_translatable_string }}</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% if document.date is not null %}
|
||||
<div class="aside">
|
||||
<div class="dates row text-end">
|
||||
<span>{{ document.date|format_date('short') }}</span>
|
||||
</div>
|
||||
{% if context == 'person' and accompanyingCourse is defined %}
|
||||
<div class="text-end">
|
||||
<span class="badge bg-primary">
|
||||
<i class="fa fa-random"></i> {{ accompanyingCourse.id }}
|
||||
</span>
|
||||
</div>
|
||||
{% elseif context == 'accompanying-period' and person is defined %}
|
||||
<div class="text-end">
|
||||
<span class="badge bg-primary">
|
||||
{{ document.person|chill_entity_render_string }}
|
||||
</span>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
{% if document.description is not empty %}
|
||||
<div class="item-row">
|
||||
|
@ -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 {
|
||||
|
@ -136,6 +136,59 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2>Fix the title in the flex table</h2>
|
||||
|
||||
<p>This will fix the layout of the row, with a "title" element, and an aside element. Using <code>css grid</code>, this is quite safe and won't overflow</p>
|
||||
|
||||
<xmp>
|
||||
<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>
|
||||
</xmp>
|
||||
|
||||
<p>will render:</p>
|
||||
|
||||
<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>
|
||||
|
||||
|
||||
<h2>Wrap-list</h2>
|
||||
<p>Une liste inline qui s'aligne, puis glisse sous son titre.</p>
|
||||
<div class="wrap-list debug">
|
||||
@ -392,4 +445,12 @@ Toutes les classes btn-* de bootstrap sont fonctionnelles
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<h1>Badges</h1>
|
||||
|
||||
<span class="badge-accompanying-work-type-simple">Action d'accompagnement</span>
|
||||
<span class="badge-activity-type-simple">Type d'échange</span>
|
||||
<span class="badge-calendar-simple">Rendez-vous</span>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
]);
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -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');
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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 {
|
||||
|
||||
|
@ -201,7 +201,7 @@
|
||||
{% endif %}
|
||||
|
||||
{% if accompanyingCourse.step != 'DRAFT' %}
|
||||
<div class="mbloc col col-sm-6 col-lg-4">
|
||||
<div class="mbloc col col-sm-6 col-lg-8 col-xxl-4">
|
||||
<div class="notification-counter">
|
||||
<h4 class="item-key">{{ 'notification.Notifications'|trans }}</h4>
|
||||
{% set notif_counter = chill_count_notifications('Chill\\PersonBundle\\Entity\\AccompanyingPeriod', accompanyingCourse.id) %}
|
||||
@ -238,6 +238,31 @@
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if counters.activities > 0 %}
|
||||
<div class="mbloc col col-sm-6 col-lg-4">
|
||||
<div class="count-activities">
|
||||
<div class="count-item">{{ counters.activities }}</div>
|
||||
<div class="count-item-label">
|
||||
{% if counters.activities == 1 %}
|
||||
{{ 'Activity'|trans }}
|
||||
{% else %}
|
||||
{{ 'Activities'|trans }}
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if counters.works > 0 %}
|
||||
<div class="mbloc col col-sm-6 col-lg-4">
|
||||
<div class="count-works">
|
||||
<div class="count-item">{{ counters.openWorks }} / {{ counters.works }}</div>
|
||||
<div class="count-item-label">{{ 'accompanying_course_work.On-going works over total'|trans }}</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
</div>
|
||||
|
||||
<div class="social-actions my-4">
|
||||
|
@ -5,44 +5,49 @@
|
||||
{% set w = document.accompanyingPeriodWorkEvaluation.accompanyingPeriodWork %}
|
||||
|
||||
<div class="item-row">
|
||||
<div class="item-col" style="width: unset">
|
||||
{% if document.storedObject.isPending %}
|
||||
<div class="badge text-bg-info" data-docgen-is-pending="{{ document.storedObject.id }}">{{ 'docgen.Doc generation is pending'|trans }}</div>
|
||||
{% elseif document.storedObject.isFailure %}
|
||||
<div class="badge text-bg-warning">{{ 'docgen.Doc generation failed'|trans }}</div>
|
||||
{% endif %}
|
||||
<div>
|
||||
{% if context == 'person' %}
|
||||
<span class="badge bg-primary">
|
||||
<i class="fa fa-random"></i> {{ w.accompanyingPeriod.id }}
|
||||
</span>
|
||||
<!-- evaluation document -->
|
||||
<div class="item-two-col-grid" style="width: unset">
|
||||
<div class="title">
|
||||
{% if document.storedObject.isPending %}
|
||||
<div class="badge text-bg-info" data-docgen-is-pending="{{ document.storedObject.id }}">{{ 'docgen.Doc generation is pending'|trans }}</div>
|
||||
{% elseif document.storedObject.isFailure %}
|
||||
<div class="badge text-bg-warning">{{ 'docgen.Doc generation failed'|trans }}</div>
|
||||
{% endif %}
|
||||
<div class="badge-accompanying-work-type">
|
||||
<span class="title_label"></span>
|
||||
<span class="title_action">{{ w.socialAction|chill_entity_render_string }} > {{ document.accompanyingPeriodWorkEvaluation.evaluation.title|localize_translatable_string }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="denomination h2">
|
||||
{{ document.title|chill_print_or_message("No title") }}
|
||||
</div>
|
||||
{% if document.storedObject.type is not empty %}
|
||||
<div>
|
||||
{{ mm.mimeIcon(document.storedObject.type) }}
|
||||
<div>
|
||||
<div class="badge-accompanying-work-type-simple">
|
||||
{{ w.socialAction|chill_entity_render_string }} > {{ document.accompanyingPeriodWorkEvaluation.evaluation.title|localize_translatable_string }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="denomination h2">
|
||||
{{ document.title|chill_print_or_message("No title") }}
|
||||
</div>
|
||||
{% if document.storedObject.type is not empty %}
|
||||
<div>
|
||||
{{ mm.mimeIcon(document.storedObject.type) }}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if document.storedObject.hasTemplate %}
|
||||
<div>
|
||||
<p>{{ document.storedObject.template.name|localize_translatable_string }}</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% if document.storedObject.createdAt is not null %}
|
||||
<div class="aside">
|
||||
<div class="dates row text-end">
|
||||
<span>{{ document.storedObject.createdAt|format_date('short') }}</span>
|
||||
</div>
|
||||
{% if context == 'person' %}
|
||||
<div class="text-end">
|
||||
<span class="badge bg-primary">
|
||||
<i class="fa fa-random"></i> {{ w.accompanyingPeriod.id }}
|
||||
</span>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if document.storedObject.hasTemplate %}
|
||||
<div>
|
||||
<p>{{ document.storedObject.template.name|localize_translatable_string }}</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="item-col">
|
||||
<div class="container">
|
||||
<div class="dates row text-end">
|
||||
<span>{{ document.storedObject.createdAt|format_date('short') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -804,7 +804,7 @@ person_admin:
|
||||
|
||||
# specific to accompanying period
|
||||
accompanying_period:
|
||||
deleted: Parcours d'accompagnment supprimé
|
||||
deleted: Parcours d'accompagnement supprimé
|
||||
dates: Période
|
||||
dates_from_%opening_date%: Ouvert depuis le %opening_date%
|
||||
dates_from_%opening_date%_to_%closing_date%: Ouvert du %opening_date% au %closing_date%
|
||||
@ -843,6 +843,7 @@ accompanying_course:
|
||||
administrative_location: Localisation administrative
|
||||
comment is pinned: Le commentaire est épinglé
|
||||
comment is unpinned: Le commentaire est désépinglé
|
||||
|
||||
show: Montrer
|
||||
hide: Masquer
|
||||
closed periods: parcours clôturés
|
||||
@ -851,6 +852,7 @@ Social work configuration: Gestion des actions d'accompagnement social
|
||||
|
||||
# Accompanying Course comments
|
||||
Accompanying Course Comment: Commentaire
|
||||
Accompanying Course Comments: Commentaires
|
||||
Accompanying Course Comment list: Commentaires du parcours
|
||||
pinned: épinglé
|
||||
Pin comment: Épingler
|
||||
@ -919,6 +921,7 @@ accompanying_course_work:
|
||||
date_filter: Filtrer par date
|
||||
types_filter: Filtrer par type d'action
|
||||
user_filter: Filtrer par intervenant
|
||||
On-going works over total: Actions en cours / Actions du parcours
|
||||
|
||||
|
||||
#
|
||||
|
Loading…
x
Reference in New Issue
Block a user