toulouse-maelis: templates for bookings (#72935) #100

Merged
lguerin merged 5 commits from wip/72935-toulouse-maelis-templates into main 2023-01-05 16:18:26 +01:00
7 changed files with 576 additions and 566 deletions

View File

@ -1 +1 @@
{% extends 'combo/json/caluire-enfant-agenda.html' %}
{% include "combo/json/enfant-agenda.html" with form_url="famille/gerer-mes-reservations/" cell_prefix="caluire" %}

View File

@ -1,257 +1 @@
{% if json.extra_data %}
<h2>Agenda de l'année scolaire {{ json.extra_data.school_year }}</h2>
<div class="caluire-agenda-cell caluire-agenda-cell-{{ cell.pk }}">
{% with first_monday=json.extra_data.start_date|adjust_to_week_monday %}
{% with last_day=json.extra_data.end_date|adjust_to_week_monday|add_days:6 %}
{% now 'W' as current_week %}
{% spaceless %}
<button class="caluire-agenda-cell--previous-week"></button>
<div class="caluire-agenda-cell--week-list">
<div class="caluire-agenda-cell--slider">
{% for day in first_monday|iterate_days_until:last_day %}
{% if day.weekday == 0 %}
{% with sunday=day|add_days:6 %}
<div class="caluire-agenda-cell--week-title {% if current_week == day|date:"W" %}current{% endif %}"
data-edit-url="{{ eservices_url }}famille/gerer-mes-reservations/tryauth?child_id={{ child_id }}&reference_year={{ first_monday.year }}&current={{ day|adjust_to_week_monday|date:"Y-m-d" }}">
Du {{ day|date:"d/m" }} au {{ sunday|date:"d/m" }}
</div>
{% endwith %}
{% endif %}
<div class="caluire-agenda-cell--day-item" data-weekday="{{ day.weekday }}">
<div class="caluire-agenda-cell--day-title" >
{{ day|date:"l d/m" }}
</div>
{% with day_str=day|date:"Y-m-d" %}
{% for item in json.data %}
{% if item.details.JOURDATE == day_str %}
<div class="caluire-agenda-cell--activity-item {% if item.disabled %}disabled{% endif %}">
<div class="caluire-agenda-cell--activity-status {{ item.details.status_color }}"/></div>
<div class="caluire-agenda-cell--activity-label"/>{{ item.details.activity_label }}</div>
</div>
{% endif %}
{% endfor %}
{% endwith %}
<div class="caluire-agenda-cell--day-no-activity">
Pas d'activité ce jour.
</div>
</div>
{% endfor %}
</div>
</div>
<button class="caluire-agenda-cell--next-week"></button>
<a class="pk-button caluire-agenda-cell--edit-btn">
Modifier l'agenda
</a>
{% endspaceless %}
{% endwith %}
{% endwith %}
<style>
.caluire-agenda-cell {
margin-top: 1em;
display: grid;
grid-template-columns: repeat(3, auto);
grid-template-rows: repeat(2, auto);
justify-items: left;
--min-column-width: 250;
}
.caluire-agenda-cell--previous-week,
.caluire-agenda-cell--next-week {
height: 3em;
width: 3em;
}
.caluire-agenda-cell--next-week {
margin-left: 1rem;
}
.caluire-agenda-cell--edit-btn {
grid-column: 2;
grid-row: 2;
}
.caluire-agenda-cell--week-list {
overflow: hidden;
margin-bottom: 2rem;
width: 100%;
}
.caluire-agenda-cell--slider {
column-gap: 0px;
display: grid;
grid-auto-columns: 0px;
grid-auto-rows: 0px;
grid-auto-flow: column;
position: relative;
}
.caluire-agenda-cell--week-item:nth-child(even) {
background: #fafafa;
}
.caluire-agenda-cell--week-title {
border-bottom: 1px solid #888;
font-weight: bold;
margin-bottom: 1rem;
display: flex;
justify-content: center;
align-items: center;
height: 3.2rem;
}
.caluire-agenda-cell--day-item {
margin: 0 1rem;
}
.caluire-agenda-cell--day-title {
border-bottom: 1px solid #888;
margin: 1rem 0;
font-weight: bold;
}
.caluire-agenda-cell--day-no-activity {
color: #888;
}
.caluire-agenda-cell--activity-item + .caluire-agenda-cell--day-no-activity {
display: none;
}
.caluire-agenda-cell--activity-item {
display: flex;
align-items: baseline;
margin: 0.3rem 0;
}
.caluire-agenda-cell--activty-item.disabled {
color: #888;
}
.caluire-agenda-cell--activity-status {
min-height: calc(0.66rem + 2px);
min-width: calc(0.66rem + 2px);
background: transparent;
border: 1px solid #aaa;
border-radius: 2px;
margin-right: 1rem;
}
.caluire-agenda-cell--activity-label {
flex-grow: 1;
}
.caluire-agenda-cell--activity-status.green {
background: #3c3;
}
.caluire-agenda-cell--activity-status.grey {
background: #aaa;
}
.caluire-agenda-cell--activity-status.orange {
background: orange;
}
.caluire-agenda-cell--activity-status.red {
background: red;
}
.caluire-agenda-cell--activity-status.yellow {
background: yellow;
}
</style>
<script>
function initAgendaCell($cell) {
const $weekList = $('.caluire-agenda-cell--week-list', $cell);
const $slider = $('.caluire-agenda-cell--slider', $cell);
let $currentWeek = $('.caluire-agenda-cell--week-title.current', $cell);
if (!$currentWeek.length) {
$currentWeek = $('.caluire-agenda-cell--week-title:first', $cell);
}
const $nextWeekButton = $('.caluire-agenda-cell--next-week', $cell);
const $previousWeekButton = $('.caluire-agenda-cell--previous-week', $cell);
const $editAgendaBtn = $('.caluire-agenda-cell--edit-btn', $cell);
let $selectedWeek = $currentWeek;
function getPreviousWeek() { return $selectedWeek.prevAll('.caluire-agenda-cell--week-title:first'); }
function getNextWeek() { return $selectedWeek.nextAll('.caluire-agenda-cell--week-title:first'); }
function setCurrentWeek($week, enableTransition) {
if(!$week.length) {
return;
}
const currentOffset = $week[0].offsetLeft;
$slider.css({
'transform': `translate(-${currentOffset}px)`,
'transition': (enableTransition ? 'transform 0.5s' : '')
});
$selectedWeek = $week;
$nextWeekButton.prop('disabled', getNextWeek().length == 0);
$previousWeekButton.prop('disabled', getPreviousWeek().length == 0);
const selectedWeekIsInPast = $selectedWeek.nextAll('.caluire-agenda-cell--week-title.current').length;
$weekToEdit = selectedWeekIsInPast ? $currentWeek : $selectedWeek;
$editAgendaBtn.prop('href', $weekToEdit.attr('data-edit-url'));
}
function setPreviousWeek() { setCurrentWeek(getPreviousWeek(), true); }
function setNextWeek() { setCurrentWeek(getNextWeek(), true); }
$previousWeekButton.on('click', setPreviousWeek);
$nextWeekButton.on('click', setNextWeek);
let touchStartX = 0;
$cell.on('touchstart', (e) => {
touchStartX = e.changedTouches[0].screenX;
});
$cell.on('touchend', (e) => {
const touchEndX = e.changedTouches[0].screenX;
if (touchEndX - touchStartX < -30) {
setNextWeek();
} else if (touchEndX - touchStartX > 30) {
setPreviousWeek();
}
});
function updateColumnsWidth() {
const minWidth = $slider.css('--min-column-width');
const availableWidth = $weekList[0].offsetWidth;
let columnsWidth = availableWidth < minWidth ? availableWidth : availableWidth / Math.floor(availableWidth / minWidth);
$slider.css('grid-template-columns', `repeat(53, ${columnsWidth}px)`);
if($selectedWeek) {
// Update slider offset to bring it at the new position of the selectedWeek
setCurrentWeek($selectedWeek, false);
}
}
function hideEmptyDays() {
let nbRows = 8;
for(let i = 0; i < 7; ++i) {
const $days = $(`.caluire-agenda-cell--day-item[data-weekday=${i}]`, $cell);
const $activities = $('.caluire-agenda-cell--activity-item', $days);
if(!$activities.length) {
$days.css('display', 'none');
nbRows -= 1;
}
$slider.css('grid-template-rows', `repeat(${nbRows}, auto`);
}
}
hideEmptyDays();
new ResizeObserver(updateColumnsWidth).observe($weekList[0]);
addEventListener('resize', updateColumnsWidth);
}
initAgendaCell($('.caluire-agenda-cell-{{ cell.pk }}'));
</script>
</div>
{% endif %}
{% include "combo/json/enfant-agenda.html" with form_url="famille/gerer-mes-reservations/" cell_prefix="caluire" %}

View File

@ -0,0 +1,257 @@
{% if json.extra_data %}
<h2>Agenda de l'année scolaire {{ json.extra_data.school_year }}</h2>
<div class="{{ cell_prefix }}-agenda-cell {{ cell_prefix }}-agenda-cell-{{ cell.pk }}">
{% with first_monday=json.extra_data.start_date|adjust_to_week_monday %}
{% with last_day=json.extra_data.end_date|adjust_to_week_monday|add_days:6 %}
{% now 'W' as current_week %}
{% spaceless %}
<button class="{{ cell_prefix }}-agenda-cell--previous-week"></button>
<div class="{{ cell_prefix }}-agenda-cell--week-list">
<div class="{{ cell_prefix }}-agenda-cell--slider">
{% for day in first_monday|iterate_days_until:last_day %}
{% if day.weekday == 0 %}
{% with sunday=day|add_days:6 %}
<div class="{{ cell_prefix }}-agenda-cell--week-title {% if current_week == day|date:"W" %}current{% endif %}"
data-edit-url="{{ eservices_url }}{{ form_url }}tryauth?child_id={{ child_id }}&reference_year={{ first_monday.year }}&current={{ day|adjust_to_week_monday|date:"Y-m-d" }}">
Du {{ day|date:"d/m" }} au {{ sunday|date:"d/m" }}
</div>
{% endwith %}
{% endif %}
<div class="{{ cell_prefix }}-agenda-cell--day-item" data-weekday="{{ day.weekday }}">
<div class="{{ cell_prefix }}-agenda-cell--day-title" >
{{ day|date:"l d/m" }}
</div>
{% with day_str=day|date:"Y-m-d" %}
{% for item in json.data %}
{% if item.details.JOURDATE == day_str or item.details.day_str == day_str %}
<div class="{{ cell_prefix }}-agenda-cell--activity-item {% if item.disabled %}disabled{% endif %}">
<div class="{{ cell_prefix }}-agenda-cell--activity-status {{ item.details.status_color }}"/></div>
<div class="{{ cell_prefix }}-agenda-cell--activity-label"/>{{ item.details.activity_label }}</div>
</div>
{% endif %}
{% endfor %}
{% endwith %}
<div class="{{ cell_prefix }}-agenda-cell--day-no-activity">
Pas d'activité ce jour.
</div>
</div>
{% endfor %}
</div>
</div>
<button class="{{ cell_prefix }}-agenda-cell--next-week"></button>
<a class="pk-button {{ cell_prefix }}-agenda-cell--edit-btn">
Modifier l'agenda
</a>
{% endspaceless %}
{% endwith %}
{% endwith %}
<style>
.{{ cell_prefix }}-agenda-cell {
margin-top: 1em;
display: grid;
grid-template-columns: repeat(3, auto);
grid-template-rows: repeat(2, auto);
justify-items: left;
--min-column-width: 250;
}
.{{ cell_prefix }}-agenda-cell--previous-week,
.{{ cell_prefix }}-agenda-cell--next-week {
height: 3em;
width: 3em;
}
.{{ cell_prefix }}-agenda-cell--next-week {
margin-left: 1rem;
}
.{{ cell_prefix }}-agenda-cell--edit-btn {
grid-column: 2;
grid-row: 2;
}
.{{ cell_prefix }}-agenda-cell--week-list {
overflow: hidden;
margin-bottom: 2rem;
width: 100%;
}
.{{ cell_prefix }}-agenda-cell--slider {
column-gap: 0px;
display: grid;
grid-auto-columns: 0px;
grid-auto-rows: 0px;
grid-auto-flow: column;
position: relative;
}
.{{ cell_prefix }}-agenda-cell--week-item:nth-child(even) {
background: #fafafa;
}
.{{ cell_prefix }}-agenda-cell--week-title {
border-bottom: 1px solid #888;
font-weight: bold;
margin-bottom: 1rem;
display: flex;
justify-content: center;
align-items: center;
height: 3.2rem;
}
.{{ cell_prefix }}-agenda-cell--day-item {
margin: 0 1rem;
}
.{{ cell_prefix }}-agenda-cell--day-title {
border-bottom: 1px solid #888;
margin: 1rem 0;
font-weight: bold;
}
.{{ cell_prefix }}-agenda-cell--day-no-activity {
color: #888;
}
.{{ cell_prefix }}-agenda-cell--activity-item + .{{ cell_prefix }}-agenda-cell--day-no-activity {
display: none;
}
.{{ cell_prefix }}-agenda-cell--activity-item {
display: flex;
align-items: baseline;
margin: 0.3rem 0;
}
.{{ cell_prefix }}-agenda-cell--activity-item.disabled {
color: #888;
}
.{{ cell_prefix }}-agenda-cell--activity-status {
min-height: calc(0.66rem + 2px);
min-width: calc(0.66rem + 2px);
background: transparent;
border: 1px solid #aaa;
border-radius: 2px;
margin-right: 1rem;
}
.{{ cell_prefix }}-agenda-cell--activity-label {
flex-grow: 1;
}
.{{ cell_prefix }}-agenda-cell--activity-status.green {
background: #3c3;
}
.{{ cell_prefix }}-agenda-cell--activity-status.grey {
background: #aaa;
}
.{{ cell_prefix }}-agenda-cell--activity-status.orange {
background: orange;
}
.{{ cell_prefix }}-agenda-cell--activity-status.red {
background: red;
}
.{{ cell_prefix }}-agenda-cell--activity-status.yellow {
background: yellow;
}
</style>
<script>
function initAgendaCell($cell) {
const $weekList = $('.{{ cell_prefix }}-agenda-cell--week-list', $cell);
const $slider = $('.{{ cell_prefix }}-agenda-cell--slider', $cell);
let $currentWeek = $('.{{ cell_prefix }}-agenda-cell--week-title.current', $cell);
if (!$currentWeek.length) {
$currentWeek = $('.{{ cell_prefix }}-agenda-cell--week-title:first', $cell);
}
const $nextWeekButton = $('.{{ cell_prefix }}-agenda-cell--next-week', $cell);
const $previousWeekButton = $('.{{ cell_prefix }}-agenda-cell--previous-week', $cell);
const $editAgendaBtn = $('.{{ cell_prefix }}-agenda-cell--edit-btn', $cell);
let $selectedWeek = $currentWeek;
function getPreviousWeek() { return $selectedWeek.prevAll('.{{ cell_prefix }}-agenda-cell--week-title:first'); }
function getNextWeek() { return $selectedWeek.nextAll('.{{ cell_prefix }}-agenda-cell--week-title:first'); }
function setCurrentWeek($week, enableTransition) {
if(!$week.length) {
return;
}
const currentOffset = $week[0].offsetLeft;
$slider.css({
'transform': `translate(-${currentOffset}px)`,
'transition': (enableTransition ? 'transform 0.5s' : '')
});
$selectedWeek = $week;
$nextWeekButton.prop('disabled', getNextWeek().length == 0);
$previousWeekButton.prop('disabled', getPreviousWeek().length == 0);
const selectedWeekIsInPast = $selectedWeek.nextAll('.{{ cell_prefix }}-agenda-cell--week-title.current').length;
$weekToEdit = selectedWeekIsInPast ? $currentWeek : $selectedWeek;
$editAgendaBtn.prop('href', $weekToEdit.attr('data-edit-url'));
}
function setPreviousWeek() { setCurrentWeek(getPreviousWeek(), true); }
function setNextWeek() { setCurrentWeek(getNextWeek(), true); }
$previousWeekButton.on('click', setPreviousWeek);
$nextWeekButton.on('click', setNextWeek);
let touchStartX = 0;
$cell.on('touchstart', (e) => {
touchStartX = e.changedTouches[0].screenX;
});
$cell.on('touchend', (e) => {
const touchEndX = e.changedTouches[0].screenX;
if (touchEndX - touchStartX < -30) {
setNextWeek();
} else if (touchEndX - touchStartX > 30) {
setPreviousWeek();
}
});
function updateColumnsWidth() {
const minWidth = $slider.css('--min-column-width');
const availableWidth = $weekList[0].offsetWidth;
let columnsWidth = availableWidth < minWidth ? availableWidth : availableWidth / Math.floor(availableWidth / minWidth);
$slider.css('grid-template-columns', `repeat(53, ${columnsWidth}px)`);
if($selectedWeek) {
// Update slider offset to bring it at the new position of the selectedWeek
setCurrentWeek($selectedWeek, false);
}
}
function hideEmptyDays() {
let nbRows = 8;
for(let i = 0; i < 7; ++i) {
const $days = $(`.{{ cell_prefix }}-agenda-cell--day-item[data-weekday=${i}]`, $cell);
const $activities = $('.{{ cell_prefix }}-agenda-cell--activity-item', $days);
if(!$activities.length) {
$days.css('display', 'none');
nbRows -= 1;
}
$slider.css('grid-template-rows', `repeat(${nbRows}, auto`);
}
}
hideEmptyDays();
new ResizeObserver(updateColumnsWidth).observe($weekList[0]);
addEventListener('resize', updateColumnsWidth);
}
initAgendaCell($('.{{ cell_prefix }}-agenda-cell-{{ cell.pk }}'));
</script>
</div>
{% endif %}

View File

@ -0,0 +1 @@
{% include "combo/json/enfant-agenda.html" with form_url=parameters.form_url cell_prefix="toulouse-maelis" %}

View File

@ -1,312 +1,5 @@
{% extends "qommon/forms/widget.html" %}
{% block widget-control %}
{% with options=widget.get_options|list %}
{% with first_monday=options.0.options.details.JOURDATE|adjust_to_week_monday last_option=options|last %}
{% with last_day=last_option.options.details.JOURDATE|adjust_to_week_monday|add_days:6 %}
{% now 'W' as current_week %}
{% spaceless %}
<button class="previous-week"></button>
<div class="week-list">
<div class="slider">
{% for day in first_monday|iterate_days_until:last_day %}
{% if day.weekday == 0 %}
{% with sunday=day|add_days:6 %}
<div class="week-title {% if form.var.current_day == day|date:"Y-m-d" or not form.var.current_day and current_week == day|date:"W" %}current{% endif %}">
Du {{ day|date:"d/m" }} au {{ sunday|date:"d/m" }}
</div>
{% endwith %}
{% endif %}
<div class="day-item" data-weekday="{{ day.weekday }}">
<div class="day-title">
{{ day|date:"l d/m" }}
</div>
{% with day_str=day|date:"Y-m-d" %}
{% for option in options %}
{% if option.options.details.JOURDATE == day_str %}
<div class="activity-item {% if option.disabled %}disabled{% endif %} {% if widget.readonly %}readonly{% endif %}"
data-activity-type="{{ option.options.details.activity_type }}"
data-activity-id="{{ option.options.details.activity_id }}"
data-date="{{ option.options.details.JOURDATE }}"
{% if widget.readonly and not option.disabled %}
{% if option.selected and not option.options.prefill %}data-has-change
{% elif not option.selected and option.options.prefill %}data-has-change
{% endif %}
{% endif %}
>
<div class="activity-status {{ option.options.details.status_color }}"></div>
<div class="activity-label"/>
<label>
<input
{% if not widget.value and option.options.prefill %}checked="checked"{% endif %}
{% if option.selected %}checked="checked"
{% elif widget.readonly or option.disabled %}disabled{% endif %}
{% for attr in widget.attrs.items %}{{attr.0}}="{{attr.1}}"{% endfor %}
type="checkbox"
{% if widget.readonly %}value="yes" disabled
{% else %}name="{{ option.name }}" value="yes"
{% endif %} />
<span>{{ option.options.details.activity_label }}</span>
</label>
{% if widget.readonly and option.selected %}<input type="hidden" name="{{ option.name }}" value="yes">{% endif %}
</div>
</div>
{% endif %}
{% endfor %}
{% endwith %}
</div>
{% endfor %}
</div>
</div>
<button class="next-week"></button>
{% endspaceless %}
{% endwith %}
{% endwith %}
{% endwith %}
<style>
.template-caluire-reservations-enfant .content {
margin-top: 1em;
display: grid;
grid-template-columns: repeat(3, auto);
grid-template-rows: repeat(2, auto);
justify-items: left;
--min-column-width: 250;
}
.template-caluire-reservations-enfant .previous-week,
.template-caluire-reservations-enfant .next-week {
height: 3em;
width: 3em;
}
.template-caluire-reservations-enfant .next-week {
margin-left: 1rem;
}
.template-caluire-reservations-enfant .edit-btn {
grid-column: 2;
grid-row: 2;
}
.template-caluire-reservations-enfant .week-list {
overflow: hidden;
margin-bottom: 2rem;
width: 100%;
}
.template-caluire-reservations-enfant .slider {
column-gap: 0px;
display: grid;
grid-auto-columns: 0px;
grid-auto-rows: 0px;
grid-auto-flow: column;
position: relative;
}
.template-caluire-reservations-enfant .week-title {
display: block;
height: 3em;
line-height: 3em;
}
.template-caluire-reservations-enfant .week-item:nth-child(even) {
background: #fafafa;
}
.template-caluire-reservations-enfant .week-title {
border-bottom: 1px solid #888;
font-weight: bold;
margin-bottom: 1rem;
display: flex;
justify-content: center;
align-items: center;
height: 3.2rem;
}
.template-caluire-reservations-enfant .day-item {
margin: 0 1rem;
}
.template-caluire-reservations-enfant .day-title {
border-bottom: 1px solid #888;
margin: 1rem 0;
font-weight: bold;
}
.template-caluire-reservations-enfant .activity-item {
display: flex;
align-items: baseline;
margin: 0.3rem 0;
}
.template-caluire-reservations-enfant .activity-item.disabled {
color: #888;
}
.template-caluire-reservations-enfant .activity-status {
min-height: calc(0.66rem + 2px);
min-width: calc(0.66rem + 2px);
background: transparent;
border: 1px solid #aaa;
border-radius: 2px;
margin-right: 1rem;
}
.template-caluire-reservations-enfant .activity-status.green {
background: #3c3;
}
.template-caluire-reservations-enfant .activity-status.grey {
background: #aaa;
}
.template-caluire-reservations-enfant .activity-status.orange {
background: orange;
}
.template-caluire-reservations-enfant .activity-status.red {
background: red;
}
.template-caluire-reservations-enfant .activity-status.yellow {
background: yellow;
}
.template-caluire-reservations-enfant .activity-item[data-has-change] .activity-status:not(.green) {
background: #3f3;
}
.template-caluire-reservations-enfant .activity-item[data-has-change] .activity-status.green {
background: orange;
}
.template-caluire-reservations-enfant .activity-item[data-has-change] label {
font-weight: bold;
}
.template-caluire-reservations-enfant .activity-item:not(.readonly):not(.disabled) .activity-status {
display: none;
}
.template-caluire-reservations-enfant .activity-item input {
flex-shrink: 0;
margin-right: 1rem;
margin-bottom: 0;
}
.template-caluire-reservations-enfant .activity-item input[disabled] {
display: none;
}
.template-caluire-reservations-enfant .activity-label {
flex-grow: 1;
}
.template-caluire-reservations-enfant .activity-label label {
display: flex;
align-items: baseline;
}
</style>
<script>
function initAgendaWidget($widget) {
const $weekList = $('.week-list', $widget);
const $slider = $('.slider', $widget);
let $currentWeek = $('.week-title.current', $widget);
if (!$currentWeek.length) {
$currentWeek = $('.week-title:first', $widget);
}
const $nextWeekButton = $('.next-week', $widget);
const $previousWeekButton = $('.previous-week', $widget);
const $editAgendaBtn = $('.edit-btn', $widget);
let $selectedWeek = $currentWeek;
function getPreviousWeek() { return $selectedWeek.prevAll('.week-title:first'); }
function getNextWeek() { return $selectedWeek.nextAll('.week-title:first'); }
function setCurrentWeek($week, enableTransition) {
if(!$week.length) {
return;
}
const currentOffset = $week[0].offsetLeft;
$slider.css({
'transform': `translate(-${currentOffset}px)`,
'transition': (enableTransition ? 'transform 0.5s' : '')
});
$selectedWeek = $week;
$nextWeekButton.prop('disabled', getNextWeek().length == 0);
$previousWeekButton.prop('disabled', getPreviousWeek().length == 0);
const selectedWeekIsInPast = $selectedWeek.nextAll('.week-title.current').length;
$weekToEdit = selectedWeekIsInPast ? $currentWeek : $selectedWeek;
$editAgendaBtn.prop('href', $weekToEdit.attr('data-edit-url'));
}
function setPreviousWeek() { setCurrentWeek(getPreviousWeek(), true); return false; }
function setNextWeek() { setCurrentWeek(getNextWeek(), true); return false; }
$previousWeekButton.on('click', setPreviousWeek);
$nextWeekButton.on('click', setNextWeek);
let touchStartX = 0;
$widget.on('touchstart', (e) => {
touchStartX = e.changedTouches[0].screenX;
});
$widget.on('touchend', (e) => {
const touchEndX = e.changedTouches[0].screenX
if (touchEndX - touchStartX < -30) {
setNextWeek();
} else if (touchEndX - touchStartX > 30) {
setPreviousWeek();
}
});
function updateColumnsWidth() {
const minWidth = $slider.css('--min-column-width');
const availableWidth = $weekList[0].offsetWidth;
let columnsWidth = availableWidth < minWidth ? availableWidth : availableWidth / Math.floor(availableWidth / minWidth);
$slider.css('grid-template-columns', `repeat(53, ${columnsWidth}px)`);
if($selectedWeek) {
// Update slider offset to bring it at the new position of the selectedWeek
setCurrentWeek($selectedWeek, false);
}
}
function hideEmptyDays() {
let nbRows = 8;
for(let i = 0; i < 7; ++i) {
const $days = $(`.day-item[data-weekday=${i}]`, $widget);
const $activities = $('.activity-item', $days);
if(!$activities.length) {
$days.css('display', 'none');
nbRows -= 1;
}
$slider.css('grid-template-rows', `repeat(${nbRows}, auto`);
}
}
hideEmptyDays();
new ResizeObserver(updateColumnsWidth).observe($weekList[0]);
addEventListener('resize', updateColumnsWidth);
}
initAgendaWidget($('.template-caluire-reservations-enfant'));
$('.template-caluire-reservations-enfant input').on('change', function() {
if ($(this).is(':checked')) {
var $current_item = $(this).parents('.activity-item').first();
$(this).parents('.day-item').find('.activity-item[data-activity-type="' +
$current_item.data('activity-type') + '"][data-date="' +
$current_item.data('date') + '"]:not([data-activity-id="' +
$current_item.data('activity-id') + '"])').find('input').prop('checked', false);
}
});
</script>
{% include "qommon/forms/widgets/reservations-enfant.html" with widget_prefix="caluire" %}
{% endblock %}

View File

@ -0,0 +1,310 @@
{% with options=widget.get_options|list %}
{% firstof options.0.options.details.JOURDATE options.0.options.details.day_str as first_day %}
{% with first_monday=first_day|adjust_to_week_monday last_option=options|last %}
{% firstof last_option.options.details.JOURDATE last_option.options.details.day_str as last_day %}
{% with last_sunday=last_day|adjust_to_week_monday|add_days:6 %}
{% now 'W' as current_week %}
{% spaceless %}
<button class="previous-week"></button>
<div class="week-list">
<div class="slider">
{% for day in first_monday|iterate_days_until:last_sunday %}
{% if day.weekday == 0 %}
{% with sunday=day|add_days:6 %}
<div class="week-title {% if form.var.current_day == day|date:"Y-m-d" or not form.var.current_day and current_week == day|date:"W" %}current{% endif %}">
Du {{ day|date:"d/m" }} au {{ sunday|date:"d/m" }}
</div>
{% endwith %}
{% endif %}
<div class="day-item" data-weekday="{{ day.weekday }}">
<div class="day-title">
{{ day|date:"l d/m" }}
</div>
{% with day_str=day|date:"Y-m-d" %}
{% for option in options %}
{% if option.options.details.JOURDATE == day_str or option.options.details.day_str == day_str %}
<div class="activity-item {% if option.disabled %}disabled{% endif %} {% if widget.readonly %}readonly{% endif %}"
data-activity-type="{{ option.options.details.activity_type }}"
data-activity-id="{{ option.options.details.activity_id }}"
data-date="{% firstof option.options.details.JOURDATE option.options.details.day_str %}"
{% if widget.readonly and not option.disabled %}
{% if option.selected and not option.options.prefill %}data-has-change
{% elif not option.selected and option.options.prefill %}data-has-change
{% endif %}
{% endif %}
>
<div class="activity-status {{ option.options.details.status_color }}"></div>
<div class="activity-label"/>
<label>
<input
{% if not widget.value and option.options.prefill %}checked="checked"{% endif %}
{% if option.selected %}checked="checked"
{% elif widget.readonly or option.disabled %}disabled{% endif %}
{% for attr in widget.attrs.items %}{{attr.0}}="{{attr.1}}"{% endfor %}
type="checkbox"
{% if widget.readonly %}value="yes" disabled
{% else %}name="{{ option.name }}" value="yes"
{% endif %} />
<span>{{ option.options.details.activity_label }}</span>
</label>
{% if widget.readonly and option.selected %}<input type="hidden" name="{{ option.name }}" value="yes">{% endif %}
</div>
</div>
{% endif %}
{% endfor %}
{% endwith %}
</div>
{% endfor %}
</div>
</div>
<button class="next-week"></button>
{% endspaceless %}
{% endwith %}
{% endwith %}
{% endwith %}
<style>
.template-{{ widget_prefix }}-reservations-enfant .content {
margin-top: 1em;
display: grid;
grid-template-columns: repeat(3, auto);
grid-template-rows: repeat(2, auto);
justify-items: left;
--min-column-width: 250;
}
.template-{{ widget_prefix }}-reservations-enfant .previous-week,
.template-{{ widget_prefix }}-reservations-enfant .next-week {
height: 3em;
width: 3em;
}
.template-{{ widget_prefix }}-reservations-enfant .next-week {
margin-left: 1rem;
}
.template-{{ widget_prefix }}-reservations-enfant .edit-btn {
grid-column: 2;
grid-row: 2;
}
.template-{{ widget_prefix }}-reservations-enfant .week-list {
overflow: hidden;
margin-bottom: 2rem;
width: 100%;
}
.template-{{ widget_prefix }}-reservations-enfant .slider {
column-gap: 0px;
display: grid;
grid-auto-columns: 0px;
grid-auto-rows: 0px;
grid-auto-flow: column;
position: relative;
}
.template-{{ widget_prefix }}-reservations-enfant .week-title {
display: block;
height: 3em;
line-height: 3em;
}
.template-{{ widget_prefix }}-reservations-enfant .week-item:nth-child(even) {
background: #fafafa;
}
.template-{{ widget_prefix }}-reservations-enfant .week-title {
border-bottom: 1px solid #888;
font-weight: bold;
margin-bottom: 1rem;
display: flex;
justify-content: center;
align-items: center;
height: 3.2rem;
}
.template-{{ widget_prefix }}-reservations-enfant .day-item {
margin: 0 1rem;
}
.template-{{ widget_prefix }}-reservations-enfant .day-title {
border-bottom: 1px solid #888;
margin: 1rem 0;
font-weight: bold;
}
.template-{{ widget_prefix }}-reservations-enfant .activity-item {
display: flex;
align-items: baseline;
margin: 0.3rem 0;
}
.template-{{ widget_prefix }}-reservations-enfant .activity-item.disabled {
color: #888;
}
.template-{{ widget_prefix }}-reservations-enfant .activity-status {
min-height: calc(0.66rem + 2px);
min-width: calc(0.66rem + 2px);
background: transparent;
border: 1px solid #aaa;
border-radius: 2px;
margin-right: 1rem;
}
.template-{{ widget_prefix }}-reservations-enfant .activity-status.green {
background: #3c3;
}
.template-{{ widget_prefix }}-reservations-enfant .activity-status.grey {
background: #aaa;
}
.template-{{ widget_prefix }}-reservations-enfant .activity-status.orange {
background: orange;
}
.template-{{ widget_prefix }}-reservations-enfant .activity-status.red {
background: red;
}
.template-{{ widget_prefix }}-reservations-enfant .activity-status.yellow {
background: yellow;
}
.template-{{ widget_prefix }}-reservations-enfant .activity-item[data-has-change] .activity-status:not(.green) {
background: #3f3;
}
.template-{{ widget_prefix }}-reservations-enfant .activity-item[data-has-change] .activity-status.green {
background: orange;
}
.template-{{ widget_prefix }}-reservations-enfant .activity-item[data-has-change] label {
font-weight: bold;
}
.template-{{ widget_prefix }}-reservations-enfant .activity-item:not(.readonly):not(.disabled) .activity-status {
display: none;
}
.template-{{ widget_prefix }}-reservations-enfant .activity-item input {
flex-shrink: 0;
margin-right: 1rem;
margin-bottom: 0;
}
.template-{{ widget_prefix }}-reservations-enfant .activity-item input[disabled] {
display: none;
}
.template-{{ widget_prefix }}-reservations-enfant .activity-label {
flex-grow: 1;
}
.template-{{ widget_prefix }}-reservations-enfant .activity-label label {
display: flex;
align-items: baseline;
}
</style>
<script>
function initAgendaWidget($widget) {
const $weekList = $('.week-list', $widget);
const $slider = $('.slider', $widget);
let $currentWeek = $('.week-title.current', $widget);
if (!$currentWeek.length) {
$currentWeek = $('.week-title:first', $widget);
}
const $nextWeekButton = $('.next-week', $widget);
const $previousWeekButton = $('.previous-week', $widget);
const $editAgendaBtn = $('.edit-btn', $widget);
let $selectedWeek = $currentWeek;
function getPreviousWeek() { return $selectedWeek.prevAll('.week-title:first'); }
function getNextWeek() { return $selectedWeek.nextAll('.week-title:first'); }
function setCurrentWeek($week, enableTransition) {
if(!$week.length) {
return;
}
const currentOffset = $week[0].offsetLeft;
$slider.css({
'transform': `translate(-${currentOffset}px)`,
'transition': (enableTransition ? 'transform 0.5s' : '')
});
$selectedWeek = $week;
$nextWeekButton.prop('disabled', getNextWeek().length == 0);
$previousWeekButton.prop('disabled', getPreviousWeek().length == 0);
const selectedWeekIsInPast = $selectedWeek.nextAll('.week-title.current').length;
$weekToEdit = selectedWeekIsInPast ? $currentWeek : $selectedWeek;
$editAgendaBtn.prop('href', $weekToEdit.attr('data-edit-url'));
}
function setPreviousWeek() { setCurrentWeek(getPreviousWeek(), true); return false; }
function setNextWeek() { setCurrentWeek(getNextWeek(), true); return false; }
$previousWeekButton.on('click', setPreviousWeek);
$nextWeekButton.on('click', setNextWeek);
let touchStartX = 0;
$widget.on('touchstart', (e) => {
touchStartX = e.changedTouches[0].screenX;
});
$widget.on('touchend', (e) => {
const touchEndX = e.changedTouches[0].screenX
if (touchEndX - touchStartX < -30) {
setNextWeek();
} else if (touchEndX - touchStartX > 30) {
setPreviousWeek();
}
});
function updateColumnsWidth() {
const minWidth = $slider.css('--min-column-width');
const availableWidth = $weekList[0].offsetWidth;
let columnsWidth = availableWidth < minWidth ? availableWidth : availableWidth / Math.floor(availableWidth / minWidth);
$slider.css('grid-template-columns', `repeat(53, ${columnsWidth}px)`);
if($selectedWeek) {
// Update slider offset to bring it at the new position of the selectedWeek
setCurrentWeek($selectedWeek, false);
}
}
function hideEmptyDays() {
let nbRows = 8;
for(let i = 0; i < 7; ++i) {
const $days = $(`.day-item[data-weekday=${i}]`, $widget);
const $activities = $('.activity-item', $days);
if(!$activities.length) {
$days.css('display', 'none');
nbRows -= 1;
}
$slider.css('grid-template-rows', `repeat(${nbRows}, auto`);
}
}
hideEmptyDays();
new ResizeObserver(updateColumnsWidth).observe($weekList[0]);
addEventListener('resize', updateColumnsWidth);
}
initAgendaWidget($('.template-{{ widget_prefix }}-reservations-enfant'));
$('.template-{{ widget_prefix }}-reservations-enfant input').on('change', function() {
if ($(this).is(':checked')) {
var $current_item = $(this).parents('.activity-item').first();
$(this).parents('.day-item').find('.activity-item[data-activity-type="' +
$current_item.data('activity-type') + '"][data-date="' +
$current_item.data('date') + '"]:not([data-activity-id="' +
$current_item.data('activity-id') + '"])').find('input').prop('checked', false);
}
});
</script>

View File

@ -0,0 +1,5 @@
{% extends "qommon/forms/widget.html" %}
{% block widget-control %}
{% include "qommon/forms/widgets/reservations-enfant.html" with widget_prefix="toulouse-maelis" %}
{% endblock %}