Compare commits

...

9 Commits

14 changed files with 101 additions and 15 deletions

View File

@@ -0,0 +1,6 @@
kind: Feature
body: Show filters on list pages unfolded by default
time: 2025-07-22T15:50:39.338057044+02:00
custom:
Issue: "399"
SchemaChange: No schema change

View File

@@ -0,0 +1,6 @@
kind: Feature
body: Add 45 and 60 min calendar ranges
time: 2025-08-11T15:21:54.209009751+02:00
custom:
Issue: "409"
SchemaChange: No schema change

View File

@@ -0,0 +1,6 @@
kind: Fixed
body: adjust display logic for accompanying period dates, include closing date if period is closed.
time: 2025-08-06T13:46:09.241584292+02:00
custom:
Issue: "382"
SchemaChange: No schema change

View File

@@ -0,0 +1,6 @@
kind: Fixed
body: add min and step attributes to integer field in DateIntervalType
time: 2025-08-06T17:35:27.413787704+02:00
custom:
Issue: "384"
SchemaChange: No schema change

View File

@@ -0,0 +1,6 @@
kind: Fixed
body: fix date formatting in calendar range display
time: 2025-08-11T15:52:12.949078671+02:00
custom:
Issue: ""
SchemaChange: No schema change

View File

@@ -0,0 +1,6 @@
kind: UX
body: Limit display of participations in event list
time: 2025-07-22T13:26:37.500656935+02:00
custom:
Issue: ""
SchemaChange: No schema change

View File

@@ -70,6 +70,8 @@
<option value="00:10:00">10 minutes</option> <option value="00:10:00">10 minutes</option>
<option value="00:15:00">15 minutes</option> <option value="00:15:00">15 minutes</option>
<option value="00:30:00">30 minutes</option> <option value="00:30:00">30 minutes</option>
<option value="00:45:00">45 minutes</option>
<option value="00:60:00">60 minutes</option>
</select> </select>
<label class="input-group-text" for="slotMinTime">De</label> <label class="input-group-text" for="slotMinTime">De</label>
<select <select

View File

@@ -32,6 +32,8 @@
<option value="00:10:00">10 minutes</option> <option value="00:10:00">10 minutes</option>
<option value="00:15:00">15 minutes</option> <option value="00:15:00">15 minutes</option>
<option value="00:30:00">30 minutes</option> <option value="00:30:00">30 minutes</option>
<option value="00:45:00">45 minutes</option>
<option value="00:60:00">60 minutes</option>
</select> </select>
<label class="input-group-text" for="slotMinTime">De</label> <label class="input-group-text" for="slotMinTime">De</label>
<select <select
@@ -102,7 +104,7 @@
event.title event.title
}}</b> }}</b>
<b v-else-if="event.extendedProps.is === 'range'" <b v-else-if="event.extendedProps.is === 'range'"
>{{ formatDate(event.startStr) }} - >{{ formatDate(event.startStr) }} - {{ formatDate(event.endStr, 'time') }}:
{{ event.extendedProps.locationName }}</b {{ event.extendedProps.locationName }}</b
> >
<b v-else-if="event.extendedProps.is === 'local'">{{ <b v-else-if="event.extendedProps.is === 'local'">{{
@@ -294,9 +296,26 @@ const nextWeeks = computed((): Weeks[] =>
}), }),
); );
const formatDate = (datetime: string) => { const formatDate = (datetime: string, format: null | 'time' = null) => {
console.log(typeof datetime); const date = ISOToDate(datetime);
return ISOToDate(datetime); if (!date) return '';
if (format === 'time') {
return date.toLocaleTimeString('fr-FR', {
hour: '2-digit',
minute: '2-digit'
});
}
// French date formatting
return date.toLocaleDateString('fr-FR', {
weekday: 'short',
year: 'numeric',
month: 'short',
day: 'numeric',
hour: '2-digit',
minute: '2-digit'
});
}; };
const baseOptions = ref<CalendarOptions>({ const baseOptions = ref<CalendarOptions>({

View File

@@ -54,14 +54,14 @@ block js %}
{% if e.participations|length > 0 %} {% if e.participations|length > 0 %}
<div class="item-row separator"> <div class="item-row separator">
<strong>{{ "Participations" | trans }}&nbsp;: </strong> <strong>{{ "Participations" | trans }}&nbsp;: </strong>
{% for part in e.participations|slice(0, 20) %} {% include {% for part in e.participations|slice(0, 5) %} {% include
'@ChillMain/OnTheFly/_insert_vue_onthefly.html.twig' with { '@ChillMain/OnTheFly/_insert_vue_onthefly.html.twig' with {
targetEntity: { name: 'person', id: part.person.id }, action: targetEntity: { name: 'person', id: part.person.id }, action:
'show', displayBadge: true, buttonText: 'show', displayBadge: true, buttonText:
part.person|chill_entity_render_string, isDead: part.person|chill_entity_render_string, isDead:
part.person.deathdate is not null } %} {% endfor %} {% if part.person.deathdate is not null } %} {% endfor %}
e.participations|length > 20 %} {% if e.participations|length > 5 %}
{{ 'events.and_other_count_participants'|trans({'count': e.participations|length - 20}) }} {{ 'events.and_other_count_participants'|trans({'count': e.participations|length - 5}) }}
{% endif %} {% endif %}
</div> </div>
{% endif %} {% endif %}

View File

@@ -55,6 +55,10 @@ class DateIntervalType extends AbstractType
{ {
$builder $builder
->add('n', IntegerType::class, [ ->add('n', IntegerType::class, [
'attr' => [
'min' => 0,
'step' => 1,
],
'constraints' => [ 'constraints' => [
new GreaterThan([ new GreaterThan([
'value' => 0, 'value' => 0,

View File

@@ -37,8 +37,13 @@ export const ISOToDate = (str: string | null): Date | null => {
return null; return null;
} }
const [year, month, day] = str.split("-").map((p) => parseInt(p)); // If the string already contains time info, use it directly
if (str.includes('T') || str.includes(' ')) {
return new Date(str);
}
// Otherwise, parse date only
const [year, month, day] = str.split("-").map((p) => parseInt(p));
return new Date(year, month - 1, day, 0, 0, 0, 0); return new Date(year, month - 1, day, 0, 0, 0, 0);
}; };

View File

@@ -5,7 +5,7 @@
<strong><i class="fa fa-fw fa-filter"></i>Filtrer la liste</strong> <strong><i class="fa fa-fw fa-filter"></i>Filtrer la liste</strong>
</button> </button>
</h2> </h2>
<div class="accordion-collapse collapse" id="filterOrderCollapse" aria-labelledby="filterOrderHeading" data-bs-parent="#filterOrderAccordion"> <div id="filterOrderCollapse" aria-labelledby="filterOrderHeading" data-bs-parent="#filterOrderAccordion">
{% set btnSubmit = 0 %} {% set btnSubmit = 0 %}
<div class="accordion-body chill_filter_order container-xxl p-5 py-2"> <div class="accordion-body chill_filter_order container-xxl p-5 py-2">
<div class="row my-2"> <div class="row my-2">

View File

@@ -32,10 +32,17 @@
<div class="wl-col list"> <div class="wl-col list">
<div class="d-flex flex-column justify-content-center"> <div class="d-flex flex-column justify-content-center">
{% if app != null %} {% if app != null %}
{% if acp.closingDate != null %}
{{ 'accompanying_period.dates_from_%opening_date%_to_%closing_date%'|trans({
'%opening_date%': acp.openingDate|format_date('long'),
'%closing_date%': acp.closingDate|format_date('long')}
) }}
{% else %}
<div class="date"> <div class="date">
{{ 'Since %date%'|trans({'%date%': app.startDate|format_date('medium') }) }} {{ 'Since %date%'|trans({'%date%': app.startDate|format_date('medium') }) }}
</div> </div>
{% endif %} {% endif %}
{% endif %}
{% set notif_counter = chill_count_notifications('Chill\\PersonBundle\\Entity\\AccompanyingPeriod', acp.id) %} {% set notif_counter = chill_count_notifications('Chill\\PersonBundle\\Entity\\AccompanyingPeriod', acp.id) %}
{% if notif_counter.total > 0 %} {% if notif_counter.total > 0 %}
@@ -70,6 +77,20 @@
</div> </div>
</div> </div>
{% if acp.step == 'CLOSED' and acp.closingMotive is not null %}
<div class="wl-row">
<div class="wl-col title">
<h3 class="closingMotive">{{ 'Closing motive'|trans }}</h3>
</div>
<div class="wl-col list">
<div>
{{ acp.closingMotive.name|localize_translatable_string }}
</div>
</div>
</div>
{% endif %}
{% if acp.user is not null %} {% if acp.user is not null %}
<div class="wl-row"> <div class="wl-row">
<div class="wl-col title"> <div class="wl-col title">

View File

@@ -624,8 +624,7 @@ final class SingleTaskController extends AbstractController
->addCheckbox('status', $statuses, $statuses, $statusTrans); ->addCheckbox('status', $statuses, $statuses, $statusTrans);
$states = $this->singleTaskStateRepository->findAllExistingStates(); $states = $this->singleTaskStateRepository->findAllExistingStates();
$checked = array_values(array_filter($states, fn (string $state) => !in_array($state, ['in_progress', 'closed', 'canceled', 'validated'], true))); $checked = array_values(array_filter($states, fn (string $state) => !in_array($state, ['to_validate', 'in_progress', 'closed', 'canceled', 'validated'], true)));
if ([] !== $states) { if ([] !== $states) {
$filterBuilder $filterBuilder
->addCheckbox('states', $states, $checked); ->addCheckbox('states', $states, $checked);