mirror of
https://github.com/ae-utbm/sith.git
synced 2024-11-22 14:13:21 +00:00
improved feedback when loading ajax content
This commit is contained in:
parent
20c015c312
commit
7ea9a5ca2d
@ -93,6 +93,32 @@ a:not(.button) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[aria-busy] {
|
||||||
|
--loading-size: 50px;
|
||||||
|
--loading-stroke: 5px;
|
||||||
|
--loading-duration: 1s;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
[aria-busy]:after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
width: var(--loading-size);
|
||||||
|
height: var(--loading-size);
|
||||||
|
margin-top: calc(var(--loading-size) / 2 * -1);
|
||||||
|
margin-left: calc(var(--loading-size) / 2 * -1);
|
||||||
|
border: var(--loading-stroke) solid rgba(0, 0, 0, .15);
|
||||||
|
border-radius: 50%;
|
||||||
|
border-top-color: rgba(0, 0, 0, 0.5);
|
||||||
|
animation: rotate calc(var(--loading-duration)) linear infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes rotate {
|
||||||
|
100% { transform: rotate(360deg); }
|
||||||
|
}
|
||||||
|
|
||||||
.ib {
|
.ib {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
padding: 1px;
|
padding: 1px;
|
||||||
|
@ -102,20 +102,10 @@ main {
|
|||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.paginator {
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
gap: 10px;
|
|
||||||
width: -moz-fit-content;
|
|
||||||
width: fit-content;
|
|
||||||
background-color: rgba(0,0,0,.1);
|
|
||||||
border-radius: 10px;
|
|
||||||
padding: 10px;
|
|
||||||
margin: 10px 0 10px auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.photos,
|
.photos,
|
||||||
.albums {
|
.albums {
|
||||||
|
margin: 20px;
|
||||||
|
min-height: 50px; // To contain the aria-busy loading wheel, even if empty
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
|
@ -96,7 +96,7 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody id="dynamic_view_content">
|
<tbody id="dynamic_view_content" :aria-busy="loading">
|
||||||
<template x-for="uv in uvs.results" :key="uv.id">
|
<template x-for="uv in uvs.results" :key="uv.id">
|
||||||
<tr @click="window.location.href = `/pedagogy/uv/${uv.id}`" class="clickable">
|
<tr @click="window.location.href = `/pedagogy/uv/${uv.id}`" class="clickable">
|
||||||
<td><a :href="`/pedagogy/uv/${uv.id}`" x-text="uv.code"></a></td>
|
<td><a :href="`/pedagogy/uv/${uv.id}`" x-text="uv.code"></a></td>
|
||||||
@ -140,6 +140,7 @@
|
|||||||
document.addEventListener("alpine:init", () => {
|
document.addEventListener("alpine:init", () => {
|
||||||
Alpine.data("uv_search", () => ({
|
Alpine.data("uv_search", () => ({
|
||||||
uvs: [],
|
uvs: [],
|
||||||
|
loading: false,
|
||||||
page: parseInt(initialUrlParams.get("page")) || page_default,
|
page: parseInt(initialUrlParams.get("page")) || page_default,
|
||||||
page_size: parseInt(initialUrlParams.get("page_size")) || page_size_default,
|
page_size: parseInt(initialUrlParams.get("page_size")) || page_size_default,
|
||||||
search: initialUrlParams.get("search") || "",
|
search: initialUrlParams.get("search") || "",
|
||||||
@ -171,8 +172,10 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
async fetch_data() {
|
async fetch_data() {
|
||||||
|
this.loading = true;
|
||||||
const url = "{{ url("api:fetch_uvs") }}" + window.location.search;
|
const url = "{{ url("api:fetch_uvs") }}" + window.location.search;
|
||||||
this.uvs = await (await fetch(url)).json();
|
this.uvs = await (await fetch(url)).json();
|
||||||
|
this.loading = false;
|
||||||
},
|
},
|
||||||
|
|
||||||
max_page() {
|
max_page() {
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
{% extends "core/base.jinja" %}
|
{% extends "core/base.jinja" %}
|
||||||
{% from "core/macros.jinja" import paginate %}
|
|
||||||
|
|
||||||
{%- block additional_css -%}
|
{%- block additional_css -%}
|
||||||
<link rel="stylesheet" href="{{ scss('sas/album.scss') }}">
|
<link rel="stylesheet" href="{{ scss('sas/album.scss') }}">
|
||||||
@ -62,7 +61,7 @@
|
|||||||
|
|
||||||
<div x-data="pictures">
|
<div x-data="pictures">
|
||||||
<h4>{% trans %}Pictures{% endtrans %}</h4>
|
<h4>{% trans %}Pictures{% endtrans %}</h4>
|
||||||
<div class="photos">
|
<div class="photos" :aria-busy="loading">
|
||||||
<template x-for="picture in pictures.results">
|
<template x-for="picture in pictures.results">
|
||||||
<a :href="`/sas/picture/${picture.id}#pict`">
|
<a :href="`/sas/picture/${picture.id}#pict`">
|
||||||
<div class="photo" :style="`background-image: url(${picture.thumb_url})`">
|
<div class="photo" :style="`background-image: url(${picture.thumb_url})`">
|
||||||
@ -81,13 +80,24 @@
|
|||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
<nav class="pagination" x-show="nb_pages() > 1">
|
<nav class="pagination" x-show="nb_pages() > 1">
|
||||||
<button @click="page--" :disabled="page <= 1">
|
{# Adding the prevent here is important, because otherwise,
|
||||||
|
clicking on the pagination buttons could submit the picture management form
|
||||||
|
and reload the page #}
|
||||||
|
<button
|
||||||
|
@click.prevent="page--"
|
||||||
|
:disabled="page <= 1"
|
||||||
|
@keyup.right.window="page = Math.min(nb_pages(), page + 1)"
|
||||||
|
>
|
||||||
<i class="fa fa-caret-left"></i>
|
<i class="fa fa-caret-left"></i>
|
||||||
</button>
|
</button>
|
||||||
<template x-for="i in nb_pages()">
|
<template x-for="i in nb_pages()">
|
||||||
<button x-text="i" @click="page = i":class="{active: page === i}"></button>
|
<button x-text="i" @click.prevent="page = i" :class="{active: page === i}"></button>
|
||||||
</template>
|
</template>
|
||||||
<button @click="page++" :disabled="page >= nb_pages()">
|
<button
|
||||||
|
@click.prevent="page++"
|
||||||
|
:disabled="page >= nb_pages()"
|
||||||
|
@keyup.left.window="page = Math.max(1, page - 1)"
|
||||||
|
>
|
||||||
<i class="fa fa-caret-right"></i>
|
<i class="fa fa-caret-right"></i>
|
||||||
</button>
|
</button>
|
||||||
</nav>
|
</nav>
|
||||||
@ -95,9 +105,6 @@
|
|||||||
|
|
||||||
{% if is_sas_admin %}
|
{% if is_sas_admin %}
|
||||||
</form>
|
</form>
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% if user.is_in_group(pk=settings.SITH_GROUP_SAS_ADMIN_ID) %}
|
|
||||||
<form class="add-files" id="upload_form" action="" method="post" enctype="multipart/form-data">
|
<form class="add-files" id="upload_form" action="" method="post" enctype="multipart/form-data">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
<div class="inputs">
|
<div class="inputs">
|
||||||
@ -122,18 +129,24 @@
|
|||||||
Alpine.data("pictures", () => ({
|
Alpine.data("pictures", () => ({
|
||||||
pictures: {},
|
pictures: {},
|
||||||
page: parseInt(initialUrlParams.get("page")) || 1,
|
page: parseInt(initialUrlParams.get("page")) || 1,
|
||||||
|
loading: false,
|
||||||
|
|
||||||
async init() {
|
async init() {
|
||||||
await this.fetch_pictures();
|
await this.fetch_pictures();
|
||||||
this.$watch("page", () => this.fetch_pictures());
|
this.$watch("page", () => {
|
||||||
|
update_query_string("page", this.page === 1 ? null : this.page);
|
||||||
|
this.fetch_pictures()
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
async fetch_pictures() {
|
async fetch_pictures() {
|
||||||
update_query_string("page", this.page === 1 ? null : this.page);
|
this.loading=true;
|
||||||
const url = "{{ url("api:pictures") }}"
|
const url = "{{ url("api:pictures") }}"
|
||||||
+"?album_id={{ album.id }}"
|
+"?album_id={{ album.id }}"
|
||||||
+`&page=${this.page}`
|
+`&page=${this.page}`
|
||||||
+"&page_size={{ settings.SITH_SAS_IMAGES_PER_PAGE }}";
|
+"&page_size={{ settings.SITH_SAS_IMAGES_PER_PAGE }}";
|
||||||
this.pictures = await (await fetch(url)).json();
|
this.pictures = await (await fetch(url)).json();
|
||||||
|
this.loading=false;
|
||||||
},
|
},
|
||||||
|
|
||||||
nb_pages() {
|
nb_pages() {
|
||||||
@ -141,6 +154,7 @@
|
|||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
})
|
})
|
||||||
|
|
||||||
$("form#upload_form").submit(function (event) {
|
$("form#upload_form").submit(function (event) {
|
||||||
let formData = new FormData($(this)[0]);
|
let formData = new FormData($(this)[0]);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user