Merge pull request #1105 from ae-utbm/accordions

Remove jquery-ui accordions
This commit is contained in:
Bartuccio Antoine 2025-06-05 18:09:45 +02:00 committed by GitHub
commit 861447ae36
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 311 additions and 247 deletions

View File

@ -0,0 +1,25 @@
const setMaxHeight = (element: HTMLDetailsElement) => {
element.setAttribute("style", `max-height: ${element.scrollHeight}px`);
};
// Initialize max-height at load
window.addEventListener("DOMContentLoaded", () => {
for (const el of document.querySelectorAll("details.accordion")) {
setMaxHeight(el as HTMLDetailsElement);
}
});
// Accordion opened
new MutationObserver((mutations: MutationRecord[]) => {
for (const mutation of mutations) {
const target = mutation.target as HTMLDetailsElement;
if (target.tagName !== "DETAILS" || !target.classList.contains("accordion")) {
continue;
}
setMaxHeight(target);
}
}).observe(document.body, {
attributes: true,
attributeFilter: ["open"],
subtree: true,
});

View File

@ -0,0 +1,55 @@
details.accordion>summary {
margin: 2px 0 0 0;
padding: .5em .5em .5em .7em;
cursor: pointer;
user-select: none;
display: block;
border-top-right-radius: 3px;
border-top-left-radius: 3px;
}
details[open].accordion>summary {
border: 1px solid #003eff;
background: #007fff;
color: #ffffff;
}
details:not([open]).accordion>summary {
border-bottom-right-radius: 3px;
border-bottom-left-radius: 3px;
border: 1px solid #c5c5c5;
background: #f6f6f6;
color: #454545;
}
details.accordion>summary::before {
font-family: FontAwesome;
content: '\f0da';
margin-right: 5px;
transition: 700ms;
font-size: 0.8em;
}
details[open]>summary::before {
font-family: FontAwesome;
content: '\f0d7';
}
// ::details-content isn't available on firefox yet
// we use .accordion-content as a workaround
details.accordion>.accordion-content {
background: #ffffff;
color: #333333;
padding: 1em 2.2em;
overflow: auto;
border: 1px solid #dddddd;
border-bottom-right-radius: 3px;
border-bottom-left-radius: 3px;
}
details.accordion {
transition: max-height 300ms ease-in-out;
}

View File

@ -12,6 +12,7 @@
<link rel="stylesheet" href="{{ static('core/header.scss') }}"> <link rel="stylesheet" href="{{ static('core/header.scss') }}">
<link rel="stylesheet" href="{{ static('core/navbar.scss') }}"> <link rel="stylesheet" href="{{ static('core/navbar.scss') }}">
<link rel="stylesheet" href="{{ static('core/pagination.scss') }}"> <link rel="stylesheet" href="{{ static('core/pagination.scss') }}">
<link rel="stylesheet" href="{{ static('core/accordion.scss') }}">
{% block jquery_css %} {% block jquery_css %}
{# Thile file is quite heavy (around 250kb), so declaring it in a block allows easy removal #} {# Thile file is quite heavy (around 250kb), so declaring it in a block allows easy removal #}
@ -26,6 +27,7 @@
<script type="module" src="{{ static('bundled/htmx-index.js') }}"></script> <script type="module" src="{{ static('bundled/htmx-index.js') }}"></script>
<script type="module" src="{{ static('bundled/country-flags-index.ts') }}"></script> <script type="module" src="{{ static('bundled/country-flags-index.ts') }}"></script>
<script type="module" src="{{ static('bundled/core/tooltips-index.ts') }}"></script> <script type="module" src="{{ static('bundled/core/tooltips-index.ts') }}"></script>
<script type="module" src="{{ static('bundled/core/accordion-index.ts') }}"></script>
<!-- Jquery declared here to be accessible in every django widgets --> <!-- Jquery declared here to be accessible in every django widgets -->
<script src="{{ static('bundled/vendored/jquery.min.js') }}"></script> <script src="{{ static('bundled/vendored/jquery.min.js') }}"></script>

View File

@ -1,7 +1,7 @@
{% extends "core/base.jinja" %} {% extends "core/base.jinja" %}
{% macro monthly(objects) %} {% macro monthly(objects) %}
<div> <div class="accordion-content">
<table> <table>
<thead> <thead>
<tr> <tr>
@ -37,22 +37,28 @@
{% if customer %} {% if customer %}
<h3>{% trans %}User account{% endtrans %}</h3> <h3>{% trans %}User account{% endtrans %}</h3>
<p>{% trans %}Amount: {% endtrans %}{{ customer.amount }} €</p> <p>{% trans %}Amount: {% endtrans %}{{ customer.amount }} €</p>
<div id="drop">
{% if buyings_month %} {% if buyings_month %}
<h5>{% trans %}Account purchases{% endtrans %}</h5> <details class="accordion" name="account" open>
<summary>{% trans %}Account purchases{% endtrans %}</summary>
{{ monthly(buyings_month) }} {{ monthly(buyings_month) }}
</details>
{% endif %} {% endif %}
{% if refilling_month %} {% if refilling_month %}
<h5>{% trans %}Reloads{% endtrans %}</h5> <details class="accordion" name="account">
<summary>{% trans %}Reloads{% endtrans %}</summary>
{{ monthly(refilling_month) }} {{ monthly(refilling_month) }}
</details>
{% endif %} {% endif %}
{% if invoices_month %} {% if invoices_month %}
<h5>{% trans %}Eboutic invoices{% endtrans %}</h5> <details class="accordion" name="account">
<summary>{% trans %}Eboutic invoices{% endtrans %}</summary>
{{ monthly(invoices_month) }} {{ monthly(invoices_month) }}
</details>
{% endif %} {% endif %}
{% if etickets %} {% if etickets %}
<h4>{% trans %}Etickets{% endtrans %}</h4> <details class="accordion" name="account">
<div> <summary>{% trans %}Etickets{% endtrans %}</summary>
<div class="accordion-content">
<ul> <ul>
{% for s in etickets %} {% for s in etickets %}
<li> <li>
@ -63,22 +69,9 @@
{% endfor %} {% endfor %}
</ul> </ul>
</div> </div>
</details>
{% endif %} {% endif %}
</div>
{% else %} {% else %}
<p>{% trans %}User has no account{% endtrans %}</p> <p>{% trans %}User has no account{% endtrans %}</p>
{% endif %} {% endif %}
{% endblock %} {% endblock %}
{% block script %}
{{ super() }}
<script>
$(function(){
$("#drop").accordion({
heightStyle: "content"
});
});
</script>
{% endblock %}

View File

@ -254,13 +254,5 @@
keys.shift(); keys.shift();
} }
}); });
$(function () {
$("#drop_gifts").accordion({
heightStyle: "content",
collapsible: true,
active: false
});
});
</script> </script>
{% endblock %} {% endblock %}

View File

@ -103,7 +103,7 @@ document.addEventListener("alpine:init", () => {
this.customerBalance += Number.parseFloat( this.customerBalance += Number.parseFloat(
(event.detail.target.querySelector("#id_amount") as HTMLInputElement).value, (event.detail.target.querySelector("#id_amount") as HTMLInputElement).value,
); );
document.getElementById("selling-accordion").click(); document.getElementById("selling-accordion").setAttribute("open", "");
this.codeField.widget.focus(); this.codeField.widget.focus();
}, },
@ -139,12 +139,6 @@ document.addEventListener("alpine:init", () => {
}); });
$(() => { $(() => {
/* Accordion UI between basket and refills */
// biome-ignore lint/suspicious/noExplicitAny: dealing with legacy jquery
($("#click-form") as any).accordion({
heightStyle: "content",
activate: () => $(".focus").focus(),
});
// biome-ignore lint/suspicious/noExplicitAny: dealing with legacy jquery // biome-ignore lint/suspicious/noExplicitAny: dealing with legacy jquery
($("#products") as any).tabs(); ($("#products") as any).tabs();
}); });

View File

@ -51,8 +51,9 @@
</div> </div>
<div id="click-form"> <div id="click-form">
<h5 id="selling-accordion">{% trans %}Selling{% endtrans %}</h5> <details class="accordion" id="selling-accordion" name="selling" open>
<div> <summary>{% trans %}Selling{% endtrans %}</summary>
<div class="accordion-content">
{% set counter_click_url = url('counter:click', counter_id=counter.id, user_id=customer.user_id) %} {% set counter_click_url = url('counter:click', counter_id=counter.id, user_id=customer.user_id) %}
<form method="post" action="" <form method="post" action=""
@ -163,16 +164,19 @@
</div> </div>
</form> </form>
</div> </div>
</details>
<details class="accordion" name="selling">
<summary>{% trans %}Refilling{% endtrans %}</summary>
{% if object.type == "BAR" %} {% if object.type == "BAR" %}
<h5>{% trans %}Refilling{% endtrans %}</h5>
{% if refilling_fragment %} {% if refilling_fragment %}
<div <div
class="accordion-content"
@htmx:after-request="onRefillingSuccess" @htmx:after-request="onRefillingSuccess"
> >
{{ refilling_fragment }} {{ refilling_fragment }}
</div> </div>
{% else %} {% else %}
<div> <div class="accordion-content">
<p class="alert alert-yellow"> <p class="alert alert-yellow">
{% trans trimmed %} {% trans trimmed %}
As a barman, you are not able to refill any account on your own. As a barman, you are not able to refill any account on your own.
@ -182,11 +186,14 @@
</p> </p>
</div> </div>
{% endif %} {% endif %}
</details>
{% if student_card_fragment %} {% if student_card_fragment %}
<h5>{% trans %}Student card{% endtrans %}</h3> <details class="accordion" name="selling">
<div> <summary>{% trans %}Student card{% endtrans %}</summary>
<div class="accordion-content">
{{ student_card_fragment }} {{ student_card_fragment }}
</div> </div>
</details>
{% endif %} {% endif %}
{% endif %} {% endif %}

View File

@ -17,6 +17,7 @@ $large-devices: 992px;
margin-bottom: 0; margin-bottom: 0;
margin-top: 0; margin-top: 0;
} }
&.star-checked { &.star-checked {
color: $pedagogy-orange; color: $pedagogy-orange;
margin-bottom: 0; margin-bottom: 0;
@ -32,6 +33,7 @@ $large-devices: 992px;
margin-left: 5px; margin-left: 5px;
margin-right: 5px; margin-right: 5px;
} }
&.star-checked { &.star-checked {
margin-left: 5px; margin-left: 5px;
margin-right: 5px; margin-right: 5px;
@ -42,6 +44,7 @@ $large-devices: 992px;
&.grade-without-star { &.grade-without-star {
display: block; display: block;
} }
&.grade-with-star { &.grade-with-star {
display: none; display: none;
} }
@ -51,10 +54,12 @@ $large-devices: 992px;
font-size: 1.1em; font-size: 1.1em;
overflow-wrap: break-word; overflow-wrap: break-word;
.closed td.title { .closed td.title {
color: lighten($black-color, 10%); color: lighten($black-color, 10%);
font-style: italic; font-style: italic;
} }
td { td {
text-align: center; text-align: center;
border: none; border: none;
@ -131,10 +136,12 @@ $large-devices: 992px;
input[type="checkbox"] { input[type="checkbox"] {
display: none; display: none;
} }
.radio-guide { .radio-guide {
margin-top: 10px; margin-top: 10px;
color: white; color: white;
} }
.radio-guide label { .radio-guide label {
display: inline-block; display: inline-block;
background-color: $pedagogy-blue; background-color: $pedagogy-blue;
@ -143,12 +150,15 @@ $large-devices: 992px;
font-size: 16px; font-size: 16px;
border-radius: 4px; border-radius: 4px;
} }
.radio-guide input[type="radio"]:checked + label {
.radio-guide input[type="radio"]:checked+label {
background-color: $pedagogy-orange; background-color: $pedagogy-orange;
} }
.radio-guide input[type="checkbox"]:checked + label {
.radio-guide input[type="checkbox"]:checked+label {
background-color: $pedagogy-orange; background-color: $pedagogy-orange;
} }
.radio-guide label:hover { .radio-guide label:hover {
background-color: $pedagogy-hover-blue; background-color: $pedagogy-hover-blue;
} }
@ -219,12 +229,7 @@ $large-devices: 992px;
"stars" "stars"
"comment"; "comment";
} }
}
.ui-accordion-content {
background-color: $white-color;
border-color: $pedagogy-orange;
border-right: none;
} }
.form-stars { .form-stars {
@ -235,16 +240,6 @@ $large-devices: 992px;
grid-area: comment; grid-area: comment;
} }
.ui-accordion-header {
background-color: $pedagogy-orange;
color: $pedagogy-white-text;
clip-path: polygon(0 0%, 0 100%, 30% 100%, 33% 0);
@media screen and (max-width: $large-devices) {
clip-path: none;
}
}
.ui-accordion-header-icon { .ui-accordion-header-icon {
color: $pedagogy-white-text; color: $pedagogy-white-text;
margin-right: 10px; margin-right: 10px;
@ -282,7 +277,7 @@ $large-devices: 992px;
background-color: $pedagogy-blue; background-color: $pedagogy-blue;
padding-right: 10px; padding-right: 10px;
> p { >p {
text-align: right; text-align: right;
font-weight: bold; font-weight: bold;
} }
@ -356,7 +351,7 @@ $large-devices: 992px;
.grade-type { .grade-type {
grid-area: grade-type; grid-area: grade-type;
> p { >p {
color: $pedagogy-white-text; color: $pedagogy-white-text;
font-weight: bold; font-weight: bold;
text-align: right; text-align: right;
@ -512,3 +507,20 @@ $large-devices: 992px;
} }
} }
} }
details.accordion summary {
background: $pedagogy-orange !important;
color: $pedagogy-white-text !important;
clip-path: polygon(0 0%, 0 100%, 30% 100%, 33% 0);
@media screen and (max-width: $large-devices) {
clip-path: none;
}
}
details.accordion>.accordion-content {
background-color: $white-color;
border-color: $pedagogy-orange;
border-right: none;
}

View File

@ -90,9 +90,9 @@
<p>{% trans %}You already posted a comment on this UV. If you want to comment again, please modify or delete your previous comment.{% endtrans %}</p> <p>{% trans %}You already posted a comment on this UV. If you want to comment again, please modify or delete your previous comment.{% endtrans %}</p>
</div> </div>
{% elif user.has_perm("pedagogy.add_uvcomment") %} {% elif user.has_perm("pedagogy.add_uvcomment") %}
<div id="leave_comment"> <details class="accordion" id="leave_comment">
<h2>{% trans %}Leave comment{% endtrans %}</h2> <summary>{% trans %}Leave comment{% endtrans %}</summary>
<div> <div class="accordion-content">
<form action="{{ url('pedagogy:uv_detail', uv_id=object.id) }}" method="post" enctype="multipart/form-data"> <form action="{{ url('pedagogy:uv_detail', uv_id=object.id) }}" method="post" enctype="multipart/form-data">
{% csrf_token %} {% csrf_token %}
<div class="leave-comment-grid-container"> <div class="leave-comment-grid-container">
@ -142,7 +142,7 @@
<p><input type="submit" value="{% trans %}Comment{% endtrans %}" /></p> <p><input type="submit" value="{% trans %}Comment{% endtrans %}" /></p>
</form> </form>
</div> </div>
</div> </details>
{% endif %} {% endif %}
<br> <br>
@ -221,21 +221,5 @@
<script type="text/javascript"> <script type="text/javascript">
$("#return_noscript").hide(); $("#return_noscript").hide();
$("#return_js").show(); $("#return_js").show();
const icons = {
header: "fa fa-toggle-right",
activeHeader: "fa fa-toggle-down"
};
$(function(){
$("#leave_comment").accordion({
icons: icons,
heightStyle: "content",
active: false,
collapsible: true
});
});
// Remove jquery-ui icons to make fontawesome work
$(document).ready(function(){
$(".ui-accordion-header-icon").first().removeClass("ui-icon");
});
</script> </script>
{% endblock %} {% endblock %}