From a87460fa3ec13ed5c4465d7900ed95152f2ad036 Mon Sep 17 00:00:00 2001 From: imperosol Date: Tue, 17 Jun 2025 14:39:53 +0200 Subject: [PATCH 01/25] fix: documentation CI/CD --- .github/actions/setup_project/action.yml | 14 ++++++++++++++ .github/workflows/ci.yml | 2 ++ .github/workflows/deploy_docs.yml | 6 +----- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/.github/actions/setup_project/action.yml b/.github/actions/setup_project/action.yml index bb10a2f5..0ec83445 100644 --- a/.github/actions/setup_project/action.yml +++ b/.github/actions/setup_project/action.yml @@ -1,15 +1,24 @@ name: "Setup project" description: "Setup Python and Poetry" +inputs: + full: + description: > + If true, do a full setup, else install + only python, uv and non-xapian python deps + required: false + default: "false" runs: using: composite steps: - name: Install apt packages + if: ${{ inputs.full == 'true' }} uses: awalsh128/cache-apt-pkgs-action@v1.4.3 with: packages: gettext version: 1.0 # increment to reset cache - name: Install Redis + if: ${{ inputs.full == 'true' }} uses: shogo82148/actions-setup-redis@v1 with: redis-version: "7.x" @@ -37,15 +46,20 @@ runs: shell: bash - name: Install Xapian + if: ${{ inputs.full == 'true' }} run: uv run ./manage.py install_xapian shell: bash + # compiling xapian accounts for almost the entirety of the virtualenv setup, + # so we save the virtual environment only on workflows where it has been installed - name: Save cached virtualenv + if: ${{ inputs.full == 'true' }} uses: actions/cache/save@v4 with: key: venv-${{ runner.os }}-${{ hashFiles('.python-version') }}-${{ hashFiles('pyproject.toml') }}-${{ env.CACHE_SUFFIX }} path: .venv - name: Compile gettext messages + if: ${{ inputs.full == 'true' }} run: uv run ./manage.py compilemessages shell: bash diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bbe35a0a..8919d04c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -37,6 +37,8 @@ jobs: - name: Check out repository uses: actions/checkout@v4 - uses: ./.github/actions/setup_project + with: + full: true env: # To avoid race conditions on environment cache CACHE_SUFFIX: ${{ matrix.pytest-mark }} diff --git a/.github/workflows/deploy_docs.yml b/.github/workflows/deploy_docs.yml index a90d84b0..236917a3 100644 --- a/.github/workflows/deploy_docs.yml +++ b/.github/workflows/deploy_docs.yml @@ -2,11 +2,7 @@ name: deploy_docs on: push: branches: - - master -env: - SECRET_KEY: notTheRealOne - DATABASE_URL: sqlite:///db.sqlite3 - CACHE_URL: redis://127.0.0.1:6379/0 + - taiste permissions: contents: write jobs: From b5ebf09fcba1adefb24c19ca39429db6b9a9feb9 Mon Sep 17 00:00:00 2001 From: Sli Date: Tue, 17 Jun 2025 15:31:51 +0200 Subject: [PATCH 02/25] Fix click on navbar --- core/templates/core/base.jinja | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/core/templates/core/base.jinja b/core/templates/core/base.jinja index cbfe4ffb..b1953004 100644 --- a/core/templates/core/base.jinja +++ b/core/templates/core/base.jinja @@ -123,8 +123,11 @@ } }) item.addEventListener("click", (event) => { - // Ignore keyboard clicks - if (event.detail === 0){ + // Don't close when clicking on desktop mode + if ( + event.target.nodeName !== "SUMMARY" + || event.detail === 0 + ){ return; } From f1b69dd47d7c99b4d913e307d7b8501e06bbd98f Mon Sep 17 00:00:00 2001 From: imperosol Date: Tue, 17 Jun 2025 14:57:46 +0200 Subject: [PATCH 03/25] fix: typo in API name --- api/urls.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/urls.py b/api/urls.py index ed58c790..765fe91e 100644 --- a/api/urls.py +++ b/api/urls.py @@ -2,7 +2,7 @@ from ninja_extra import NinjaExtraAPI api = NinjaExtraAPI( title="PICON", - description="Portail Interaction de Communication avec les Services Étudiants", + description="Portail Interactif de Communication avec les Services Étudiants", version="0.2.0", urls_namespace="api", csrf=True, From 0c442a8f03100e07c47a0327c838c143240d40f5 Mon Sep 17 00:00:00 2001 From: imperosol Date: Tue, 17 Jun 2025 15:31:28 +0200 Subject: [PATCH 04/25] fix: select only active club members on `GET /club/{club_id}` --- club/api.py | 10 +++++--- club/tests/test_club_controller.py | 38 +++++++++++++++++++++++------- 2 files changed, 37 insertions(+), 11 deletions(-) diff --git a/club/api.py b/club/api.py index ef46e4c7..2e59d3e5 100644 --- a/club/api.py +++ b/club/api.py @@ -1,6 +1,7 @@ from typing import Annotated from annotated_types import MinLen +from django.db.models import Prefetch from ninja.security import SessionAuth from ninja_extra import ControllerBase, api_controller, paginate, route from ninja_extra.pagination import PageNumberPaginationExtra @@ -8,7 +9,7 @@ from ninja_extra.schemas import PaginatedResponseSchema from api.auth import ApiKeyAuth from api.permissions import CanAccessLookup, HasPerm -from club.models import Club +from club.models import Club, Membership from club.schemas import ClubSchema, SimpleClubSchema @@ -33,6 +34,9 @@ class ClubController(ControllerBase): url_name="fetch_club", ) def fetch_club(self, club_id: int): - return self.get_object_or_exception( - Club.objects.prefetch_related("members", "members__user"), id=club_id + prefetch = Prefetch( + "members", queryset=Membership.objects.ongoing().select_related("user") + ) + return self.get_object_or_exception( + Club.objects.prefetch_related(prefetch), id=club_id ) diff --git a/club/tests/test_club_controller.py b/club/tests/test_club_controller.py index ade8eb4d..18a3aef1 100644 --- a/club/tests/test_club_controller.py +++ b/club/tests/test_club_controller.py @@ -1,7 +1,10 @@ +from datetime import date, timedelta + import pytest from django.test import Client from django.urls import reverse from model_bakery import baker +from model_bakery.recipe import Recipe from pytest_django.asserts import assertNumQueries from club.models import Club, Membership @@ -9,13 +12,32 @@ from core.baker_recipes import subscriber_user @pytest.mark.django_db -def test_fetch_club(client: Client): - club = baker.make(Club) - baker.make(Membership, club=club, _quantity=10, _bulk_create=True) - user = subscriber_user.make() - client.force_login(user) - with assertNumQueries(7): - # - 4 queries for authentication - # - 3 queries for the actual data +class TestFetchClub: + @pytest.fixture() + def club(self): + club = baker.make(Club) + last_month = date.today() - timedelta(days=30) + yesterday = date.today() - timedelta(days=1) + membership_recipe = Recipe(Membership, club=club, start_date=last_month) + membership_recipe.make(end_date=None, _quantity=10, _bulk_create=True) + membership_recipe.make(end_date=yesterday, _quantity=10, _bulk_create=True) + return club + + def test_fetch_club_members(self, client: Client, club: Club): + user = subscriber_user.make() + client.force_login(user) res = client.get(reverse("api:fetch_club", kwargs={"club_id": club.id})) assert res.status_code == 200 + member_ids = {member["user"]["id"] for member in res.json()["members"]} + assert member_ids == set( + club.members.ongoing().values_list("user_id", flat=True) + ) + + def test_fetch_club_nb_queries(self, client: Client, club: Club): + user = subscriber_user.make() + client.force_login(user) + with assertNumQueries(6): + # - 4 queries for authentication + # - 2 queries for the actual data + res = client.get(reverse("api:fetch_club", kwargs={"club_id": club.id})) + assert res.status_code == 200 From 30809a69c92438cebe5bbdb0a9f6c6020ea49eb3 Mon Sep 17 00:00:00 2001 From: Sli Date: Tue, 17 Jun 2025 15:39:35 +0200 Subject: [PATCH 05/25] Move navbar script to dedicated file --- core/static/bundled/core/navbar-index.ts | 36 +++++++++++++++++++++++ core/templates/core/base.jinja | 37 +----------------------- 2 files changed, 37 insertions(+), 36 deletions(-) create mode 100644 core/static/bundled/core/navbar-index.ts diff --git a/core/static/bundled/core/navbar-index.ts b/core/static/bundled/core/navbar-index.ts new file mode 100644 index 00000000..b5330d42 --- /dev/null +++ b/core/static/bundled/core/navbar-index.ts @@ -0,0 +1,36 @@ +import { exportToHtml } from "#core:utils/globals"; + +exportToHtml("showMenu", () => { + const navbar = document.getElementById("navbar-content"); + const current = navbar.getAttribute("mobile-display"); + navbar.setAttribute("mobile-display", current === "hidden" ? "revealed" : "hidden"); +}); + +document.addEventListener("alpine:init", () => { + const menuItems = document.querySelectorAll(".navbar details[name='navbar'].menu"); + const isDesktop = () => { + return window.innerWidth >= 500; + }; + for (const item of menuItems) { + item.addEventListener("mouseover", () => { + if (isDesktop()) { + item.setAttribute("open", ""); + } + }); + item.addEventListener("mouseout", () => { + if (isDesktop()) { + item.removeAttribute("open"); + } + }); + item.addEventListener("click", (event: MouseEvent) => { + // Don't close when clicking on desktop mode + if ((event.target as HTMLElement).nodeName !== "SUMMARY" || event.detail === 0) { + return; + } + + if (isDesktop()) { + event.preventDefault(); + } + }); + } +}); diff --git a/core/templates/core/base.jinja b/core/templates/core/base.jinja index b1953004..9b50463c 100644 --- a/core/templates/core/base.jinja +++ b/core/templates/core/base.jinja @@ -18,6 +18,7 @@ + @@ -107,42 +108,6 @@ {% block script %} + {% endblock %} {% block title %} @@ -15,7 +15,14 @@ {% endblock %} {% block content %} -
+
@@ -89,14 +96,5 @@
- {% endblock %} diff --git a/package-lock.json b/package-lock.json index a0228831..31bddd32 100644 --- a/package-lock.json +++ b/package-lock.json @@ -45,6 +45,8 @@ "@hey-api/openapi-ts": "^0.73.0", "@rollup/plugin-inject": "^5.0.5", "@types/alpinejs": "^3.13.10", + "@types/cytoscape-cxtmenu": "^3.4.4", + "@types/cytoscape-klay": "^3.1.4", "@types/jquery": "^3.5.31", "vite": "^6.2.5", "vite-bundle-visualizer": "^1.2.1", @@ -2819,6 +2821,33 @@ "@types/tern": "*" } }, + "node_modules/@types/cytoscape": { + "version": "3.21.9", + "resolved": "https://registry.npmjs.org/@types/cytoscape/-/cytoscape-3.21.9.tgz", + "integrity": "sha512-JyrG4tllI6jvuISPjHK9j2Xv/LTbnLekLke5otGStjFluIyA9JjgnvgZrSBsp8cEDpiTjwgZUZwpPv8TSBcoLw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/cytoscape-cxtmenu": { + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/@types/cytoscape-cxtmenu/-/cytoscape-cxtmenu-3.4.4.tgz", + "integrity": "sha512-cuv+IdbKekswDRBIrHn97IYOzWS2/UjVr0kDIHCOYvqWy3iZkuGGM4qmHNPQ+63Dn7JgtmD0l3MKW1moyhoaKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/cytoscape": "*" + } + }, + "node_modules/@types/cytoscape-klay": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@types/cytoscape-klay/-/cytoscape-klay-3.1.4.tgz", + "integrity": "sha512-H+tIadpcVjmDGWKFUfibwzIpH/kddfwAFsuhPparjiC+bWBm+MeNqIwwY+19ofkJZWcqWqZL6Jp8lkp+sP8Aig==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/cytoscape": "*" + } + }, "node_modules/@types/estree": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", diff --git a/package.json b/package.json index 9d7cf43a..b1b9f442 100644 --- a/package.json +++ b/package.json @@ -31,6 +31,8 @@ "@rollup/plugin-inject": "^5.0.5", "@types/alpinejs": "^3.13.10", "@types/jquery": "^3.5.31", + "@types/cytoscape-cxtmenu": "^3.4.4", + "@types/cytoscape-klay": "^3.1.4", "vite": "^6.2.5", "vite-bundle-visualizer": "^1.2.1", "vite-plugin-static-copy": "^3.0.2" From 10d5b9d63f35fc398d581f2921f905ca66d28f25 Mon Sep 17 00:00:00 2001 From: Sli Date: Wed, 18 Jun 2025 12:22:30 +0200 Subject: [PATCH 09/25] Add zoom control of family graph --- .../static/bundled/user/family-graph-index.ts | 10 ++++++- .../templates/core/user_godfathers_tree.jinja | 26 +++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/core/static/bundled/user/family-graph-index.ts b/core/static/bundled/user/family-graph-index.ts index e1f9adc4..058d0cbe 100644 --- a/core/static/bundled/user/family-graph-index.ts +++ b/core/static/bundled/user/family-graph-index.ts @@ -16,6 +16,10 @@ type GraphData = ( | { data: { source: number; target: number } } )[]; +function isMobile() { + return window.innerWidth < 500; +} + async function getGraphData( userId: number, godfathersDepth: number, @@ -151,7 +155,6 @@ function createGraph(container: HTMLDivElement, data: GraphData, activeUserId: n cy.on("tap", "node", (tapped) => { onNodeTap(tapped.target); }); - cy.zoomingEnabled(false); /* Add context menu */ cy.cxtmenu({ @@ -200,6 +203,7 @@ document.addEventListener("alpine:init", () => { reverse: initialUrlParams.get("reverse")?.toLowerCase?.() === "true", graph: undefined as cytoscape.Core, graphData: {}, + isZoomEnabled: !isMobile(), getInitialDepth(prop: string) { const value = Number.parseInt(initialUrlParams.get(prop)); @@ -235,6 +239,9 @@ document.addEventListener("alpine:init", () => { await this.reverseGraph(); } }); + this.$watch("isZoomEnabled", () => { + this.graph.userZoomingEnabled(this.isZoomEnabled); + }); await this.fetchGraphData(); }, @@ -279,6 +286,7 @@ document.addEventListener("alpine:init", () => { this.graphData, config.activeUser, ); + this.graph.userZoomingEnabled(this.isZoomEnabled); this.loading = false; }, })); diff --git a/core/templates/core/user_godfathers_tree.jinja b/core/templates/core/user_godfathers_tree.jinja index 218d9ca2..92d54772 100644 --- a/core/templates/core/user_godfathers_tree.jinja +++ b/core/templates/core/user_godfathers_tree.jinja @@ -77,6 +77,7 @@ >
+
@@ -91,6 +92,31 @@ {% trans %}Save{% endtrans %} + +
+ + + + +
From 7d454749e007fac96ccb3202040f09130ae4d4ec Mon Sep 17 00:00:00 2001 From: Sli Date: Wed, 18 Jun 2025 14:10:26 +0200 Subject: [PATCH 10/25] Add style to zoom controls on family graph --- .../static/bundled/user/family-graph-index.ts | 1 + core/static/user/user_godfathers.scss | 40 +++++++++----- .../templates/core/user_godfathers_tree.jinja | 52 +++++++++---------- 3 files changed, 55 insertions(+), 38 deletions(-) diff --git a/core/static/bundled/user/family-graph-index.ts b/core/static/bundled/user/family-graph-index.ts index 058d0cbe..b17c7420 100644 --- a/core/static/bundled/user/family-graph-index.ts +++ b/core/static/bundled/user/family-graph-index.ts @@ -287,6 +287,7 @@ document.addEventListener("alpine:init", () => { config.activeUser, ); this.graph.userZoomingEnabled(this.isZoomEnabled); + this.$refs.graph.prepend(this.$refs.zoomControl); this.loading = false; }, })); diff --git a/core/static/user/user_godfathers.scss b/core/static/user/user_godfathers.scss index 9764ee3e..d350125f 100644 --- a/core/static/user/user_godfathers.scss +++ b/core/static/user/user_godfathers.scss @@ -2,6 +2,12 @@ width: 100%; height: 70vh; display: block; + overflow: clip; +} + +.zoom-control { + float: right; + margin-right: 10px; } .graph-toolbar { @@ -12,7 +18,7 @@ justify-content: space-around; gap: 30px; - .toolbar-column{ + .toolbar-column { display: flex; flex-direction: column; gap: 20px; @@ -34,31 +40,38 @@ .depth-choice { white-space: nowrap; + input[type="number"] { -webkit-appearance: textfield; -moz-appearance: textfield; appearance: textfield; + &::-webkit-inner-spin-button, &::-webkit-outer-spin-button { -webkit-appearance: none; } } + button { background: none; - & > .fa { + + &>.fa { border-radius: 50%; font-size: 12px; padding: 5px; } - &:enabled > .fa { + + &:enabled>.fa { background-color: #354a5f; color: white; } - &:enabled:hover > .fa { + + &:enabled:hover>.fa { color: white; background-color: #35405f; // just a bit darker } - &:disabled > .fa { + + &:disabled>.fa { background-color: gray; color: white; } @@ -74,6 +87,7 @@ @media screen and (max-width: 500px) { flex-direction: column; gap: 20px; + .toolbar-column { min-width: 100%; } @@ -87,14 +101,16 @@ padding: 10px; box-sizing: border-box; - > form { + >form { margin: 0; } } + #family-tree-link { display: inline-block; margin-top: 10px; text-align: center; + @media (min-width: 450px) { margin-right: auto; } @@ -122,10 +138,10 @@ width: 100%; } - > div.mini_profile_link { + >div.mini_profile_link { position: relative; - > a { + >a { &.mini_profile_link { display: flex; flex-direction: column; @@ -140,7 +156,7 @@ max-height: 65px; } - > span { + >span { height: 150px; width: 100%; @@ -149,7 +165,7 @@ width: 80px; } - > img { + >img { width: 100%; max-width: 100%; max-height: 100%; @@ -163,7 +179,7 @@ } } - > em { + >em { box-sizing: border-box; padding: 0 5px; text-align: center; @@ -195,7 +211,7 @@ } } - > a.mini_profile_link { + >a.mini_profile_link { display: none; } } \ No newline at end of file diff --git a/core/templates/core/user_godfathers_tree.jinja b/core/templates/core/user_godfathers_tree.jinja index 92d54772..1e3e0812 100644 --- a/core/templates/core/user_godfathers_tree.jinja +++ b/core/templates/core/user_godfathers_tree.jinja @@ -77,7 +77,6 @@ >
-
@@ -92,33 +91,34 @@ {% trans %}Save{% endtrans %} - -
- - - - -
+ +
+ + + + +
+
From 94bdc5e6156fcfab95d0bc1c61b52bad477b409a Mon Sep 17 00:00:00 2001 From: Sli Date: Wed, 18 Jun 2025 14:13:06 +0200 Subject: [PATCH 11/25] Remove useless closures --- core/templates/core/user_godfathers_tree.jinja | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/core/templates/core/user_godfathers_tree.jinja b/core/templates/core/user_godfathers_tree.jinja index 1e3e0812..88c4709b 100644 --- a/core/templates/core/user_godfathers_tree.jinja +++ b/core/templates/core/user_godfathers_tree.jinja @@ -96,24 +96,24 @@
From ca593c7d813a4fb89fe6550d2ba2d684f06f4f4b Mon Sep 17 00:00:00 2001 From: Sli Date: Wed, 18 Jun 2025 16:09:31 +0200 Subject: [PATCH 12/25] Avoid click on graph when zooming --- core/static/bundled/user/family-graph-index.ts | 1 - core/static/user/user_godfathers.scss | 4 ++-- core/templates/core/user_godfathers_tree.jinja | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/core/static/bundled/user/family-graph-index.ts b/core/static/bundled/user/family-graph-index.ts index b17c7420..058d0cbe 100644 --- a/core/static/bundled/user/family-graph-index.ts +++ b/core/static/bundled/user/family-graph-index.ts @@ -287,7 +287,6 @@ document.addEventListener("alpine:init", () => { config.activeUser, ); this.graph.userZoomingEnabled(this.isZoomEnabled); - this.$refs.graph.prepend(this.$refs.zoomControl); this.loading = false; }, })); diff --git a/core/static/user/user_godfathers.scss b/core/static/user/user_godfathers.scss index d350125f..7c69def7 100644 --- a/core/static/user/user_godfathers.scss +++ b/core/static/user/user_godfathers.scss @@ -2,12 +2,12 @@ width: 100%; height: 70vh; display: block; - overflow: clip; } .zoom-control { - float: right; margin-right: 10px; + display: flex; + justify-content: right; } .graph-toolbar { diff --git a/core/templates/core/user_godfathers_tree.jinja b/core/templates/core/user_godfathers_tree.jinja index 88c4709b..e489fd6e 100644 --- a/core/templates/core/user_godfathers_tree.jinja +++ b/core/templates/core/user_godfathers_tree.jinja @@ -94,7 +94,7 @@
-
+
diff --git a/uv.lock b/uv.lock index b1e3d63e..4b50121e 100644 --- a/uv.lock +++ b/uv.lock @@ -1852,7 +1852,7 @@ dev = [ { name = "ipython", specifier = ">=9.0.2,<10.0.0" }, { name = "pre-commit", specifier = ">=4.1.0,<5.0.0" }, { name = "rjsmin", specifier = ">=1.2.4,<2.0.0" }, - { name = "ruff", specifier = ">=0.11.11,<1.0.0" }, + { name = "ruff", specifier = ">=0.11.13,<1.0.0" }, ] docs = [ { name = "mkdocs", specifier = ">=1.6.1,<2.0.0" }, From 9049d8779cedf875d65f504f6f5c8831fdf253fd Mon Sep 17 00:00:00 2001 From: imperosol Date: Sat, 21 Jun 2025 15:06:08 +0200 Subject: [PATCH 16/25] improve counter admin pages --- counter/admin.py | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/counter/admin.py b/counter/admin.py index 10f04c8d..de1d9d0b 100644 --- a/counter/admin.py +++ b/counter/admin.py @@ -41,6 +41,7 @@ class ProductAdmin(SearchModelAdmin): "profit", "archived", ) + list_select_related = ("product_type",) search_fields = ("name", "code") @@ -81,20 +82,13 @@ class AccountDumpAdmin(admin.ModelAdmin): "customer", "warning_mail_sent_at", "warning_mail_error", - "dump_operation", + "dump_operation__date", "amount", ) + list_select_related = ("customer", "customer__user", "dump_operation") autocomplete_fields = ("customer", "dump_operation") list_filter = ("warning_mail_error",) - def get_queryset(self, request): - # the `amount` property requires to know the customer and the dump_operation - return ( - super() - .get_queryset(request) - .select_related("customer", "customer__user", "dump_operation") - ) - @admin.register(Counter) class CounterAdmin(admin.ModelAdmin): @@ -113,11 +107,14 @@ class RefillingAdmin(SearchModelAdmin): "customer__account_id", "counter__name", ) + list_filter = (("counter", admin.RelatedOnlyFieldListFilter),) + date_hierarchy = "date" @admin.register(Selling) class SellingAdmin(SearchModelAdmin): list_display = ("customer", "label", "unit_price", "quantity", "counter", "date") + list_select_related = ("customer", "customer__user", "counter") search_fields = ( "customer__user__username", "customer__user__first_name", @@ -126,6 +123,8 @@ class SellingAdmin(SearchModelAdmin): "counter__name", ) autocomplete_fields = ("customer", "seller") + list_filter = (("counter", admin.RelatedOnlyFieldListFilter),) + date_hierarchy = "date" @admin.register(Permanency) From f5a822835809896a9c572f6ea649c87c1f442a78 Mon Sep 17 00:00:00 2001 From: Julien Constant Date: Sun, 22 Jun 2025 15:51:00 +0200 Subject: [PATCH 17/25] Rework footer's UX on small devices --- core/static/core/footer.scss | 80 +++++++++++++++++++++++++++ core/static/core/style.scss | 41 -------------- core/templates/core/base.jinja | 20 ++----- core/templates/core/base/footer.jinja | 13 +++++ 4 files changed, 97 insertions(+), 57 deletions(-) create mode 100644 core/static/core/footer.scss create mode 100644 core/templates/core/base/footer.jinja diff --git a/core/static/core/footer.scss b/core/static/core/footer.scss new file mode 100644 index 00000000..be27a2e3 --- /dev/null +++ b/core/static/core/footer.scss @@ -0,0 +1,80 @@ +@import "colors"; +@import "devices"; + +@media (max-width: $small-devices) { + footer { + margin-top: 0.6em; + padding: 1.25em; + background-color: $primary-neutral-dark-color; + + display: flex; + flex-direction: column; + align-items: center; + + gap: 1.25em; + + > div { + + display: flex; + flex-direction: row; + flex-wrap: wrap; + justify-content: center; + gap: 0.8em; + + > a { + color: $white-color !important; + width: auto; + } + } + + > a { + color: $primary-neutral-color !important; + } + + .fa-github { + color: $primary-neutral-color; + } + } +} + +@media (min-width: $small-devices) { + footer { + width: 90%; + margin: 2em auto; + + font-size: 90%; + text-align: center; + vertical-align: middle; + + div { + margin: 0.6em 0; + color: $white-color; + border-radius: 5px; + display: flex; + flex-wrap: wrap; + align-items: center; + background-color: $primary-neutral-dark-color; + box-shadow: $shadow-color 0 0 15px; + + a { + padding: 0.8em; + flex: 1; + font-weight: bold; + color: $white-color !important; + + &:hover { + color: $primary-dark-color; + } + } + } + + > .version { + margin-top: 3px; + color: rgba(0, 0, 0, 0.3); + } + + .fa-github { + color: $githubblack; + } + } +} \ No newline at end of file diff --git a/core/static/core/style.scss b/core/static/core/style.scss index 2cff3dff..2baf42a6 100644 --- a/core/static/core/style.scss +++ b/core/static/core/style.scss @@ -713,47 +713,6 @@ textarea { margin-top: 10px; } -/*--------------------------------FOOTER-------------------------------*/ - -footer { - width: 90%; - margin: 2em auto; - - font-size: 90%; - text-align: center; - vertical-align: middle; - - div { - margin: 0.6em 0; - color: $white-color; - border-radius: 5px; - display: flex; - flex-wrap: wrap; - align-items: center; - background-color: $primary-neutral-dark-color; - box-shadow: $shadow-color 0 0 15px; - - a { - padding: 0.8em; - flex: 1; - font-weight: bold; - color: $white-color !important; - - &:hover { - color: $primary-dark-color; - } - } - } - - >.version { - margin-top: 3px; - color: rgba(0, 0, 0, 0.3); - } - - .fa-github { - color: $githubblack; - } -} .ui-dialog .ui-dialog-buttonpane { diff --git a/core/templates/core/base.jinja b/core/templates/core/base.jinja index 9b50463c..225abcfd 100644 --- a/core/templates/core/base.jinja +++ b/core/templates/core/base.jinja @@ -11,6 +11,7 @@ + @@ -89,22 +90,9 @@
- + {% block footer %} + {% include "core/base/footer.jinja" %} + {% endblock %} {% block script %}