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.
This commit is contained in:
Julien Fastré 2025-04-10 15:33:22 +02:00
parent d58acff541
commit 203a098054
Signed by: julienfastre
GPG Key ID: BDE2190974723FCB
7 changed files with 229 additions and 140 deletions

View 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

View File

@ -13,44 +13,44 @@
{% endif %} {% endif %}
<div class="item-row"> <div class="item-row">
<div class="item-col" style="width: unset"> <div class="item-two-col-grid">
{% if document.isPending %} <div class="title">
<div class="badge text-bg-info" data-docgen-is-pending="{{ document.id }}">{{ 'docgen.Doc generation is pending'|trans }}</div> {% if document.isPending %}
{% elseif document.isFailure %} <div class="badge text-bg-info" data-docgen-is-pending="{{ document.id }}">{{ 'docgen.Doc generation is pending'|trans }}</div>
<div class="badge text-bg-warning">{{ 'docgen.Doc generation failed'|trans }}</div> {% elseif document.isFailure %}
{% endif %} <div class="badge text-bg-warning">{{ 'docgen.Doc generation failed'|trans }}</div>
<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>&nbsp;
{% endif %} {% endif %}
<div class="badge-activity-type">
<span class="title_label"></span> <div>
<span class="title_action"> <div>
{{ activity.type.name | localize_translatable_string }} <div class="badge-activity-type-simple">
{{ activity.type.name | localize_translatable_string }}
</div>
{% if activity.emergency %} {% if activity.emergency %}
<span class="badge bg-danger rounded-pill fs-6 float-end">{{ 'Emergency'|trans|upper }}</span> <span class="badge bg-danger rounded-pill fs-6 float-end">{{ 'Emergency'|trans|upper }}</span>
{% endif %} {% endif %}
</span> </div>
</div> </div>
</div> <div class="denomination h2">
<div class="denomination h2"> {{ document.title|chill_print_or_message("No title") }}
{{ document.title|chill_print_or_message("No title") }}
</div>
{% if document.hasTemplate %}
<div>
<p>{{ document.template.name|localize_translatable_string }}</p>
</div> </div>
{% endif %} {% if document.hasTemplate %}
</div> <div>
<p>{{ document.template.name|localize_translatable_string }}</p>
<div class="item-col"> </div>
<div class="container"> {% endif %}
</div>
<div class="aside">
<div class="dates row text-end"> <div class="dates row text-end">
<span>{{ document.createdAt|format_date('short') }}</span> <span>{{ document.createdAt|format_date('short') }}</span>
</div> </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>&nbsp;
</div>
{% endif %}
</div> </div>
</div> </div>
</div> </div>

View File

@ -6,50 +6,48 @@
<div class="item-row"> <div class="item-row">
<div class="item-col" style="width: unset"> <div class="item-two-col-grid">
{% if document.storedObject.isPending %} <div class="title">
<div class="badge text-bg-info" data-docgen-is-pending="{{ document.storedObject.id }}">{{ 'docgen.Doc generation is pending'|trans }}</div> {% if document.storedObject.isPending %}
{% elseif document.storedObject.isFailure %} <div class="badge text-bg-info" data-docgen-is-pending="{{ document.storedObject.id }}">{{ 'docgen.Doc generation is pending'|trans }}</div>
<div class="badge text-bg-warning">{{ 'docgen.Doc generation failed'|trans }}</div> {% elseif document.storedObject.isFailure %}
{% endif %} <div class="badge text-bg-warning">{{ 'docgen.Doc generation failed'|trans }}</div>
<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>&nbsp;
{% endif %} {% 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> <div>
<p>{{ document.storedObject.template.name|localize_translatable_string }}</p>
</div>
{% endif %}
</div>
<div class="item-col"> <span class="badge-calendar-simple">
<div class="container"> {{ '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"> <div class="dates row text-end">
<span>{{ document.storedObject.createdAt|format_date('short') }}</span> <span>{{ document.storedObject.createdAt|format_date('short') }}</span>
</div> </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>&nbsp;
</div>
{% endif %}
</div> </div>
</div> </div>
</div> </div>

View File

@ -3,54 +3,54 @@
{% import '@ChillPerson/Macro/updatedBy.html.twig' as mmm %} {% import '@ChillPerson/Macro/updatedBy.html.twig' as mmm %}
<div class="item-row"> <div class="item-row">
<div class="item-col" style="width: unset"> <!-- person document or accompanying course document -->
{% if document.object.isPending %} <div class="item-two-col-grid">
<div class="badge text-bg-info" data-docgen-is-pending="{{ document.object.id }}">{{ 'docgen.Doc generation is pending'|trans }}</div> <div class="title">
{% elseif document.object.isFailure %} {% if document.object.isPending %}
<div class="badge text-bg-warning">{{ 'docgen.Doc generation failed'|trans }}</div> <div class="badge text-bg-info" data-docgen-is-pending="{{ document.object.id }}">{{ 'docgen.Doc generation is pending'|trans }}</div>
{% endif %} {% 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 class="denomination h2">
<div> {{ document.title|chill_print_or_message("No title") }}
<span class="badge bg-primary">
<i class="fa fa-random"></i> {{ accompanyingCourse.id }}
</span>&nbsp;
</div> </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> <div>
<span class="badge bg-primary"> <p>{{ document.category.name|localize_translatable_string }}</p>
{{ 'Document from person %name%'|trans({ '%name%': document.person|chill_entity_render_string }) }}
</span>&nbsp;
</div> </div>
{% if document.object.hasTemplate %}
{% endif %} <div>
<div class="denomination h2"> <p>{{ document.object.template.name|localize_translatable_string }}</p>
{{ 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>
</div> </div>
{% endif %} {% endif %}
</div> </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>&nbsp;
</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>&nbsp;
</div>
{% endif %}
</div>
{% endif %}
</div> </div>
</div> </div>
{% if document.description is not empty %} {% if document.description is not empty %}
<div class="item-row"> <div class="item-row">

View File

@ -25,7 +25,34 @@ div.flex-table {
div.item-col:last-child { div.item-col:last-child {
display: flex; 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 { h2, h3, h4, dl, p {

View File

@ -136,6 +136,59 @@
</div> </div>
</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> <h2>Wrap-list</h2>
<p>Une liste inline qui s'aligne, puis glisse sous son titre.</p> <p>Une liste inline qui s'aligne, puis glisse sous son titre.</p>
<div class="wrap-list debug"> <div class="wrap-list debug">

View File

@ -5,44 +5,49 @@
{% set w = document.accompanyingPeriodWorkEvaluation.accompanyingPeriodWork %} {% set w = document.accompanyingPeriodWorkEvaluation.accompanyingPeriodWork %}
<div class="item-row"> <div class="item-row">
<div class="item-col" style="width: unset"> <!-- evaluation document -->
{% if document.storedObject.isPending %} <div class="item-two-col-grid" style="width: unset">
<div class="badge text-bg-info" data-docgen-is-pending="{{ document.storedObject.id }}">{{ 'docgen.Doc generation is pending'|trans }}</div> <div class="title">
{% elseif document.storedObject.isFailure %} {% if document.storedObject.isPending %}
<div class="badge text-bg-warning">{{ 'docgen.Doc generation failed'|trans }}</div> <div class="badge text-bg-info" data-docgen-is-pending="{{ document.storedObject.id }}">{{ 'docgen.Doc generation is pending'|trans }}</div>
{% endif %} {% elseif document.storedObject.isFailure %}
<div> <div class="badge text-bg-warning">{{ 'docgen.Doc generation failed'|trans }}</div>
{% if context == 'person' %}
<span class="badge bg-primary">
<i class="fa fa-random"></i> {{ w.accompanyingPeriod.id }}
</span>&nbsp;
{% endif %} {% 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> <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>&nbsp;
</div>
{% endif %}
</div> </div>
{% endif %} {% 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>
</div> </div>