From 7405241b820fb340304ace7ebf5b2506f71e276d Mon Sep 17 00:00:00 2001 From: Sli Date: Tue, 8 Oct 2024 17:14:22 +0200 Subject: [PATCH] Apply all biomejs fixes --- biome.json | 5 +- com/static/com/js/poster_list.js | 2 +- com/static/com/js/slideshow.js | 63 ++++---- com/templates/com/poster_list.jinja | 2 +- core/static/core/js/script.js | 44 +++--- core/static/core/js/sith-select2.js | 73 ++++----- core/static/user/js/family_graph.js | 124 +++++++++------- core/static/user/js/user_edit.js | 51 +++---- core/static/webpack/alpine-index.js | 2 +- core/static/webpack/easymde-index.js | 41 +++--- core/templates/core/base.jinja | 2 +- core/templates/core/user_edit.jinja | 24 +-- .../templates/core/user_godfathers_tree.jinja | 32 ++-- core/templates/core/user_pictures.jinja | 20 +-- counter/static/counter/js/counter_click.js | 32 ++-- counter/templates/counter/counter_click.jinja | 18 +-- eboutic/static/eboutic/js/eboutic.js | 44 +++--- eboutic/static/eboutic/js/makecommand.js | 38 +++-- eboutic/templates/eboutic/eboutic_main.jinja | 6 +- .../eboutic/eboutic_makecommand.jinja | 28 ++-- pedagogy/templates/pedagogy/guide.jinja | 36 ++--- sas/static/sas/js/viewer.js | 139 ++++++++++-------- sas/templates/sas/album.jinja | 12 +- sas/templates/sas/picture.jinja | 68 ++++----- webpack.config.js | 2 + 25 files changed, 480 insertions(+), 428 deletions(-) diff --git a/biome.json b/biome.json index 5aa03be8..fdfe712a 100644 --- a/biome.json +++ b/biome.json @@ -20,7 +20,10 @@ "linter": { "enabled": true, "rules": { - "recommended": true + "all": true } + }, + "javascript": { + "globals": ["Alpine", "$", "jQuery", "gettext", "interpolate"] } } diff --git a/com/static/com/js/poster_list.js b/com/static/com/js/poster_list.js index 4dde71e7..8ffb97c4 100644 --- a/com/static/com/js/poster_list.js +++ b/com/static/com/js/poster_list.js @@ -1,5 +1,5 @@ $(document).ready(() => { - $("#poster_list #view").click((e) => { + $("#poster_list #view").click(() => { $("#view").removeClass("active"); }); diff --git a/com/static/com/js/slideshow.js b/com/static/com/js/slideshow.js index b5bf401d..952af8b8 100644 --- a/com/static/com/js/slideshow.js +++ b/com/static/com/js/slideshow.js @@ -1,13 +1,11 @@ $(document).ready(() => { - transition_time = 1000; + const transitionTime = 1000; - i = 0; - max = $("#slideshow .slide").length; - - next_trigger = 0; + let i = 0; + const max = $("#slideshow .slide").length; function enterFullscreen() { - element = document.getElementById("slideshow"); + const element = document.getElementById("slideshow"); $(element).addClass("fullscreen"); if (element.requestFullscreen) { element.requestFullscreen(); @@ -21,7 +19,7 @@ $(document).ready(() => { } function exitFullscreen() { - element = document.getElementById("slideshow"); + const element = document.getElementById("slideshow"); $(element).removeClass("fullscreen"); if (document.exitFullscreen) { document.exitFullscreen(); @@ -34,61 +32,59 @@ $(document).ready(() => { } } - function init_progress_bar() { + function initProgressBar() { $("#slideshow #progress_bar").css("transition", "none"); $("#slideshow #progress_bar").removeClass("progress"); $("#slideshow #progress_bar").addClass("init"); } - function start_progress_bar(display_time) { + function startProgressBar(displayTime) { $("#slideshow #progress_bar").removeClass("init"); $("#slideshow #progress_bar").addClass("progress"); - $("#slideshow #progress_bar").css("transition", `width ${display_time}s linear`); + $("#slideshow #progress_bar").css("transition", `width ${displayTime}s linear`); } function next() { - init_progress_bar(); - slide = $($("#slideshow .slide").get(i % max)); + initProgressBar(); + const slide = $($("#slideshow .slide").get(i % max)); slide.removeClass("center"); slide.addClass("left"); - next_slide = $($("#slideshow .slide").get((i + 1) % max)); - next_slide.removeClass("right"); - next_slide.addClass("center"); - display_time = next_slide.attr("display_time") || 2; + const nextSlide = $($("#slideshow .slide").get((i + 1) % max)); + nextSlide.removeClass("right"); + nextSlide.addClass("center"); + const displayTime = nextSlide.attr("display_time") || 2; $("#slideshow .bullet").removeClass("active"); - bullet = $("#slideshow .bullet")[(i + 1) % max]; + const bullet = $("#slideshow .bullet")[(i + 1) % max]; $(bullet).addClass("active"); i = (i + 1) % max; setTimeout(() => { - others_left = $("#slideshow .slide.left"); - others_left.removeClass("left"); - others_left.addClass("right"); + const othersLeft = $("#slideshow .slide.left"); + othersLeft.removeClass("left"); + othersLeft.addClass("right"); - start_progress_bar(display_time); - next_trigger = setTimeout(next, display_time * 1000); - }, transition_time); + startProgressBar(displayTime); + setTimeout(next, displayTime * 1000); + }, transitionTime); } - display_time = $("#slideshow .center").attr("display_time"); - init_progress_bar(); + const displayTime = $("#slideshow .center").attr("display_time"); + initProgressBar(); setTimeout(() => { if (max > 1) { - start_progress_bar(display_time); - setTimeout(next, display_time * 1000); + startProgressBar(displayTime); + setTimeout(next, displayTime * 1000); } }, 10); - $("#slideshow").click((e) => { - if (!$("#slideshow").hasClass("fullscreen")) { - console.log("Entering fullscreen ..."); - enterFullscreen(); - } else { - console.log("Exiting fullscreen ..."); + $("#slideshow").click(() => { + if ($("#slideshow").hasClass("fullscreen")) { exitFullscreen(); + } else { + enterFullscreen(); } }); @@ -96,7 +92,6 @@ $(document).ready(() => { if (e.keyCode === 27) { // escape key maps to keycode `27` e.preventDefault(); - console.log("Exiting fullscreen ..."); exitFullscreen(); } }); diff --git a/com/templates/com/poster_list.jinja b/com/templates/com/poster_list.jinja index 9ff3add4..8c4f5cd1 100644 --- a/com/templates/com/poster_list.jinja +++ b/com/templates/com/poster_list.jinja @@ -27,7 +27,7 @@
- {% if poster_list.count() == 0 %} + {% if poster_list.count() == 0 %}
{% trans %}No posters{% endtrans %}
{% else %} diff --git a/core/static/core/js/script.js b/core/static/core/js/script.js index c0c9e4d8..592164a9 100644 --- a/core/static/core/js/script.js +++ b/core/static/core/js/script.js @@ -13,13 +13,11 @@ $(() => { bottom: "5%", }); target.css("height", "300px"); - console.log(target); }, buttons: [ { text: "Choose", click: function () { - console.log($("#file_id")); $(`input[name=${$(this).attr("name")}]`).attr( "value", $("#file_id").attr("value"), @@ -34,7 +32,6 @@ $(() => { .button() .on("click", function () { const popup = popups.filter(`[name=${$(this).attr("name")}]`); - console.log(popup); popup.html( '
', ); @@ -45,6 +42,7 @@ $(() => { }); }); +// biome-ignore lint/correctness/noUnusedVariables: used in other scripts function createQuickNotif(msg) { const el = document.createElement("li"); el.textContent = msg; @@ -52,6 +50,7 @@ function createQuickNotif(msg) { document.getElementById("quick_notif").appendChild(el); } +// biome-ignore lint/correctness/noUnusedVariables: used in other scripts function deleteQuickNotifs() { const el = document.getElementById("quick_notif"); while (el.firstChild) { @@ -59,7 +58,8 @@ function deleteQuickNotifs() { } } -function display_notif() { +// biome-ignore lint/correctness/noUnusedVariables: used in other scripts +function displayNotif() { $("#header_notif").toggle().parent().toggleClass("white"); } @@ -69,10 +69,13 @@ function display_notif() { // Sadly, getting the cookie is not possible with CSRF_COOKIE_HTTPONLY or CSRF_USE_SESSIONS is True // So, the true workaround is to get the token from the dom // https://docs.djangoproject.com/en/2.0/ref/csrf/#acquiring-the-token-if-csrf-use-sessions-is-true +// biome-ignore lint/style/useNamingConvention: can't find it used anywhere but I will not play with the devil +// biome-ignore lint/correctness/noUnusedVariables: used in other scripts function getCSRFToken() { return $("[name=csrfmiddlewaretoken]").val(); } +// biome-ignore lint/correctness/noUnusedVariables: used in other scripts const initialUrlParams = new URLSearchParams(window.location.search); /** @@ -80,8 +83,11 @@ const initialUrlParams = new URLSearchParams(window.location.search); * @enum {number} */ const History = { + // biome-ignore lint/style/useNamingConvention: this feels more like an enum NONE: 0, + // biome-ignore lint/style/useNamingConvention: this feels more like an enum PUSH: 1, + // biome-ignore lint/style/useNamingConvention: this feels more like an enum REPLACE: 2, }; @@ -91,7 +97,8 @@ const History = { * @param {History} action * @param {URL | null} url */ -function update_query_string(key, value, action = History.REPLACE, url = null) { +// biome-ignore lint/correctness/noUnusedVariables: used in other scripts +function updateQueryString(key, value, action = History.REPLACE, url = null) { let ret = url; if (!ret) { ret = new URL(window.location.href); @@ -125,24 +132,25 @@ function update_query_string(key, value, action = History.REPLACE, url = null) { * @param {string} url The paginated endpoint to fetch * @return {Promise} */ -async function fetch_paginated(url) { - const max_per_page = 199; - const paginated_url = new URL(url, document.location.origin); - paginated_url.searchParams.set("page_size", max_per_page.toString()); - paginated_url.searchParams.set("page", "1"); +// biome-ignore lint/correctness/noUnusedVariables: used in other scripts +async function fetchPaginated(url) { + const maxPerPage = 199; + const paginatedUrl = new URL(url, document.location.origin); + paginatedUrl.searchParams.set("page_size", maxPerPage.toString()); + paginatedUrl.searchParams.set("page", "1"); - const first_page = await (await fetch(paginated_url)).json(); - const results = first_page.results; + const firstPage = await (await fetch(paginatedUrl)).json(); + const results = firstPage.results; - const nb_pictures = first_page.count; - const nb_pages = Math.ceil(nb_pictures / max_per_page); + const nbPictures = firstPage.count; + const nbPages = Math.ceil(nbPictures / maxPerPage); - if (nb_pages > 1) { + if (nbPages > 1) { const promises = []; - for (let i = 2; i <= nb_pages; i++) { - paginated_url.searchParams.set("page", i.toString()); + for (let i = 2; i <= nbPages; i++) { + paginatedUrl.searchParams.set("page", i.toString()); promises.push( - fetch(paginated_url).then((res) => res.json().then((json) => json.results)), + fetch(paginatedUrl).then((res) => res.json().then((json) => json.results)), ); } results.push(...(await Promise.all(promises)).flat()); diff --git a/core/static/core/js/sith-select2.js b/core/static/core/js/sith-select2.js index e332c0c5..4754325f 100644 --- a/core/static/core/js/sith-select2.js +++ b/core/static/core/js/sith-select2.js @@ -15,7 +15,7 @@ * ]; * document.addEventListener("DOMContentLoaded", () => sithSelect2({ * element: document.getElementById("select2-input"), - * data_source: local_data_source(data) + * dataSource: localDataSource(data) * })); * ``` * @@ -29,7 +29,7 @@ * ]; * document.addEventListener("DOMContentLoaded", () => sithSelect2({ * element: document.getElementById("select2-input"), - * data_source: local_data_source(data, { + * dataSource: localDataSource(data, { * excluded: () => data.filter((i) => i.text === "to exclude").map((i) => parseInt(i)) * }) * })); @@ -38,15 +38,15 @@ * # Remote data source * * Select2 with remote data sources are similar to those with local - * data, but with some more parameters, like `result_converter`, + * data, but with some more parameters, like `resultConverter`, * which takes a callback that must return a `Select2Object`. * * ```js * document.addEventListener("DOMContentLoaded", () => sithSelect2({ * element: document.getElementById("select2-input"), - * data_source: remote_data_source("/api/user/search", { + * dataSource: remoteDataSource("/api/user/search", { * excluded: () => [1, 2], // exclude users 1 and 2 from the search - * result_converter: (user) => Object({id: user.id, text: user.first_name}) + * resultConverter: (user) => Object({id: user.id, text: user.firstName}) * }) * })); * ``` @@ -62,8 +62,8 @@ * ```js * document.addEventListener("DOMContentLoaded", () => sithSelect2({ * element: document.getElementById("select2-input"), - * data_source: remote_data_source("/api/user/search", { - * result_converter: (user) => Object({id: user.id, text: user.first_name}), + * dataSource: remoteDataSource("/api/user/search", { + * resultConverter: (user) => Object({id: user.id, text: user.firstName}), * overrides: { * delay: 500 * } @@ -85,15 +85,15 @@ * * Sometimes, you would like to display an image besides * the text on the select items. - * In this case, fill the `picture_getter` option : + * In this case, fill the `pictureGetter` option : * * ```js * document.addEventListener("DOMContentLoaded", () => sithSelect2({ * element: document.getElementById("select2-input"), - * data_source: remote_data_source("/api/user/search", { - * result_converter: (user) => Object({id: user.id, text: user.first_name}) + * dataSource: remoteDataSource("/api/user/search", { + * resultConverter: (user) => Object({id: user.id, text: user.firstName}) * }) - * picture_getter: (user) => user.profile_pict, + * pictureGetter: (user) => user.profilePict, * })); * ``` * @@ -105,8 +105,8 @@ * *
* - *

- *

+ *

+ *

*
* * @@ -114,20 +114,20 @@ * document.addEventListener("alpine:init", () => { * Alpine.data("select2_test", () => ({ * selector: undefined, - * current_select: {id: "", text: ""}, + * currentSelect: {id: "", text: ""}, * * init() { * this.selector = sithSelect2({ * element: $(this.$refs.select), - * data_source: local_data_source( + * dataSource: localDataSource( * [{id: 1, text: "foo"}, {id: 2, text: "bar"}] * ), * }); * this.selector.on("select2:select", (event) => { * // select2 => Alpine signals here - * this.current_select = this.selector.select2("data") + * this.currentSelect = this.selector.select2("data") * }); - * this.$watch("current_selected" (value) => { + * this.$watch("currentSelected" (value) => { * // Alpine => select2 signals here * }); * }, @@ -145,10 +145,10 @@ /** * @typedef Select2Options * @property {Element} element - * @property {Object} data_source - * the data source, built with `local_data_source` or `remote_data_source` + * @property {Object} dataSource + * the data source, built with `localDataSource` or `remoteDataSource` * @property {number[]} excluded A list of ids to exclude from search - * @property {undefined | function(Object): string} picture_getter + * @property {undefined | function(Object): string} pictureGetter * A callback to get the picture field from the API response * @property {Object | undefined} overrides * Any other select2 parameter to apply on the config @@ -157,13 +157,14 @@ /** * @param {Select2Options} options */ +// biome-ignore lint/correctness/noUnusedVariables: used in other scripts function sithSelect2(options) { const elem = $(options.element); return elem.select2({ theme: elem[0].multiple ? "classic" : "default", minimumInputLength: 2, - templateResult: select_item_builder(options.picture_getter), - ...options.data_source, + templateResult: selectItemBuilder(options.pictureGetter), + ...options.dataSource, ...(options.overrides || {}), }); } @@ -179,7 +180,8 @@ function sithSelect2(options) { * @param {Select2Object[]} source The array containing the data * @param {RemoteSourceOptions} options */ -function local_data_source(source, options) { +// biome-ignore lint/correctness/noUnusedVariables: used in other scripts +function localDataSource(source, options) { if (options.excluded) { const ids = options.excluded(); return { data: source.filter((i) => !ids.includes(i.id)) }; @@ -191,7 +193,7 @@ function local_data_source(source, options) { * @typedef RemoteSourceOptions * @property {undefined | function(): number[]} excluded * A callback to the ids to exclude from the search - * @property {undefined | function(): Select2Object} result_converter + * @property {undefined | function(): Select2Object} resultConverter * A converter for a value coming from the remote api * @property {undefined | Object} overrides * Any other select2 parameter to apply on the config @@ -202,7 +204,9 @@ function local_data_source(source, options) { * @param {string} source The url of the endpoint * @param {RemoteSourceOptions} options */ -function remote_data_source(source, options) { + +// biome-ignore lint/correctness/noUnusedVariables: used in other scripts +function remoteDataSource(source, options) { jQuery.ajaxSettings.traditional = true; const params = { url: source, @@ -219,9 +223,9 @@ function remote_data_source(source, options) { }; }, }; - if (options.result_converter) { + if (options.resultConverter) { params.processResults = (data) => ({ - results: data.results.map(options.result_converter), + results: data.results.map(options.resultConverter), }); } if (options.overrides) { @@ -230,7 +234,8 @@ function remote_data_source(source, options) { return { ajax: params }; } -function item_formatter(user) { +// biome-ignore lint/correctness/noUnusedVariables: used in other scripts +function itemFormatter(user) { if (user.loading) { return user.text; } @@ -238,22 +243,22 @@ function item_formatter(user) { /** * Build a function to display the results - * @param {null | function(Object):string} picture_getter + * @param {null | function(Object):string} pictureGetter * @return {function(string): jQuery|HTMLElement} */ -function select_item_builder(picture_getter) { +function selectItemBuilder(pictureGetter) { return (item) => { - const picture = typeof picture_getter === "function" ? picture_getter(item) : null; - const img_html = picture + const picture = typeof pictureGetter === "function" ? pictureGetter(item) : null; + const imgHtml = picture ? `${item.text}` : ""; return $(`
- ${img_html} + ${imgHtml} ${item.text}
`); }; diff --git a/core/static/user/js/family_graph.js b/core/static/user/js/family_graph.js index 5fcb38ab..c8b1f989 100644 --- a/core/static/user/js/family_graph.js +++ b/core/static/user/js/family_graph.js @@ -1,7 +1,7 @@ -async function get_graph_data(url, godfathers_depth, godchildren_depth) { +async function getGraphData(url, godfathersDepth, godchildrenDepth) { const data = await ( await fetch( - `${url}?godfathers_depth=${godfathers_depth}&godchildren_depth=${godchildren_depth}`, + `${url}?godfathers_depth=${godfathersDepth}&godchildren_depth=${godchildrenDepth}`, ) ).json(); return [ @@ -16,7 +16,8 @@ async function get_graph_data(url, godfathers_depth, godchildren_depth) { ]; } -function create_graph(container, data, active_user_id) { +function createGraph(container, data, activeUserId) { + // biome-ignore lint/correctness/noUndeclaredVariables: imported by user_godphaters_tree.jinja const cy = cytoscape({ boxSelectionEnabled: false, autounselectify: true, @@ -83,9 +84,9 @@ function create_graph(container, data, active_user_id) { }, }, }); - const active_user = cy.getElementById(active_user_id).style("shape", "rectangle"); + const activeUser = cy.getElementById(activeUserId).style("shape", "rectangle"); /* Reset graph */ - const reset_graph = () => { + const resetGraph = () => { cy.elements((element) => { if (element.hasClass("traversed")) { element.removeClass("traversed"); @@ -96,10 +97,10 @@ function create_graph(container, data, active_user_id) { }); }; - const on_node_tap = (el) => { - reset_graph(); + const onNodeTap = (el) => { + resetGraph(); /* Create path on graph if selected isn't the targeted user */ - if (el === active_user) { + if (el === activeUser) { return; } cy.elements((element) => { @@ -108,7 +109,7 @@ function create_graph(container, data, active_user_id) { for (const traversed of cy.elements().aStar({ root: el, - goal: active_user, + goal: activeUser, }).path) { traversed.removeClass("not-traversed"); traversed.addClass("traversed"); @@ -116,14 +117,13 @@ function create_graph(container, data, active_user_id) { }; cy.on("tap", "node", (tapped) => { - on_node_tap(tapped.target); + onNodeTap(tapped.target); }); cy.zoomingEnabled(false); /* Add context menu */ if (cy.cxtmenu === undefined) { - console.error("ctxmenu isn't loaded, context menu won't be available on graphs"); - return cy; + throw new Error("ctxmenu isn't loaded, context menu won't be available on graphs"); } cy.cxtmenu({ selector: "node", @@ -139,14 +139,14 @@ function create_graph(container, data, active_user_id) { { content: '', select: (el) => { - on_node_tap(el); + onNodeTap(el); }, }, { content: '', - select: (el) => { - reset_graph(); + select: (_) => { + resetGraph(); }, }, ], @@ -155,73 +155,81 @@ function create_graph(container, data, active_user_id) { return cy; } -/* global api_url, active_user, depth_min, depth_max */ document.addEventListener("alpine:init", () => { /* This needs some constants to be set before the document has been loaded - api_url: base url for fetching the tree as a string - active_user: id of the user to fetch the tree from - depth_min: minimum tree depth for godfathers and godchildren as an int - depth_max: maximum tree depth for godfathers and godchildren as an int + apiUrl: base url for fetching the tree as a string + activeUser: id of the user to fetch the tree from + depthMin: minimum tree depth for godfathers and godchildren as an int + depthMax: maximum tree depth for godfathers and godchildren as an int */ - const default_depth = 2; + const defaultDepth = 2; if ( - typeof api_url === "undefined" || - typeof active_user === "undefined" || - typeof depth_min === "undefined" || - typeof depth_max === "undefined" + // biome-ignore lint/correctness/noUndeclaredVariables: defined by user_godfathers_tree.jinja + typeof apiUrl === "undefined" || + // biome-ignore lint/correctness/noUndeclaredVariables: defined by user_godfathers_tree.jinja + typeof activeUser === "undefined" || + // biome-ignore lint/correctness/noUndeclaredVariables: defined by user_godfathers_tree.jinja + typeof depthMin === "undefined" || + // biome-ignore lint/correctness/noUndeclaredVariables: defined by user_godfathers_tree.jinja + typeof depthMax === "undefined" ) { - console.error( + throw new Error( "Some constants are not set before using the family_graph script, please look at the documentation", ); - return; } - function get_initial_depth(prop) { + function getInitialDepth(prop) { + // biome-ignore lint/correctness/noUndeclaredVariables: defined by script.js const value = Number.parseInt(initialUrlParams.get(prop)); - if (Number.isNaN(value) || value < depth_min || value > depth_max) { - return default_depth; + // biome-ignore lint/correctness/noUndeclaredVariables: defined by user_godfathers_tree.jinja + if (Number.isNaN(value) || value < depthMin || value > depthMax) { + return defaultDepth; } return value; } Alpine.data("graph", () => ({ loading: false, - godfathers_depth: get_initial_depth("godfathers_depth"), - godchildren_depth: get_initial_depth("godchildren_depth"), + godfathersDepth: getInitialDepth("godfathersDepth"), + godchildrenDepth: getInitialDepth("godchildrenDepth"), + // biome-ignore lint/correctness/noUndeclaredVariables: defined by script.js reverse: initialUrlParams.get("reverse")?.toLowerCase?.() === "true", graph: undefined, - graph_data: {}, + graphData: {}, async init() { - const delayed_fetch = Alpine.debounce(async () => { - this.fetch_graph_data(); + const delayedFetch = Alpine.debounce(async () => { + await this.fetchGraphData(); }, 100); - for (const param of ["godfathers_depth", "godchildren_depth"]) { + for (const param of ["godfathersDepth", "godchildrenDepth"]) { this.$watch(param, async (value) => { - if (value < depth_min || value > depth_max) { + // biome-ignore lint/correctness/noUndeclaredVariables: defined by user_godfathers_tree.jinja + if (value < depthMin || value > depthMax) { return; } - update_query_string(param, value, History.REPLACE); - delayed_fetch(); + // biome-ignore lint/correctness/noUndeclaredVariables: defined by script.js + updateQueryString(param, value, History.REPLACE); + await delayedFetch(); }); } this.$watch("reverse", async (value) => { - update_query_string("reverse", value, History.REPLACE); - this.reverse_graph(); + // biome-ignore lint/correctness/noUndeclaredVariables: defined by script.js + updateQueryString("reverse", value, History.REPLACE); + await this.reverseGraph(); }); - this.$watch("graph_data", async () => { - await this.generate_graph(); + this.$watch("graphData", async () => { + await this.generateGraph(); if (this.reverse) { - await this.reverse_graph(); + await this.reverseGraph(); } }); - this.fetch_graph_data(); + await this.fetchGraphData(); }, - async screenshot() { + screenshot() { const link = document.createElement("a"); link.href = this.graph.jpg(); link.download = interpolate( @@ -234,30 +242,32 @@ document.addEventListener("alpine:init", () => { document.body.removeChild(link); }, - async reset() { + reset() { this.reverse = false; - this.godfathers_depth = default_depth; - this.godchildren_depth = default_depth; + this.godfathersDepth = defaultDepth; + this.godchildrenDepth = defaultDepth; }, - async reverse_graph() { + async reverseGraph() { this.graph.elements((el) => { el.position({ x: -el.position().x, y: -el.position().y }); }); this.graph.center(this.graph.elements()); }, - async fetch_graph_data() { - this.graph_data = await get_graph_data( - api_url, - this.godfathers_depth, - this.godchildren_depth, + async fetchGraphData() { + this.graphData = await getGraphData( + // biome-ignore lint/correctness/noUndeclaredVariables: defined by user_godfathers_tree.jinja + apiUrl, + this.godfathersDepth, + this.godchildrenDepth, ); }, - async generate_graph() { + async generateGraph() { this.loading = true; - this.graph = create_graph($(this.$refs.graph), this.graph_data, active_user); + // biome-ignore lint/correctness/noUndeclaredVariables: defined by user_godfathers_tree.jinja + this.graph = await createGraph($(this.$refs.graph), this.graphData, activeUser); this.loading = false; }, })); diff --git a/core/static/user/js/user_edit.js b/core/static/user/js/user_edit.js index 40f503b0..8b5f981c 100644 --- a/core/static/user/js/user_edit.js +++ b/core/static/user/js/user_edit.js @@ -1,23 +1,24 @@ -function alpine_webcam_builder(default_picture, delete_url, can_delete_picture) { +// biome-ignore lint/correctness/noUnusedVariables: used in user_edit.jinja +function alpineWebcamBuilder(defaultPicture, deleteUrl, canDeletePicture) { return () => ({ - can_edit_picture: false, + canEditPicture: false, loading: false, - is_camera_enabled: false, - is_camera_error: false, + isCameraEnabled: false, + isCameraError: false, picture: null, video: null, - picture_form: null, + pictureForm: null, init() { this.video = this.$refs.video; - this.picture_form = this.$refs.form.getElementsByTagName("input"); - if (this.picture_form.length > 0) { - this.picture_form = this.picture_form[0]; - this.can_edit_picture = true; + this.pictureForm = this.$refs.form.getElementsByTagName("input"); + if (this.pictureForm.length > 0) { + this.pictureForm = this.pictureForm[0]; + this.canEditPicture = true; // Link the displayed element to the form input - this.picture_form.onchange = (event) => { + this.pictureForm.onchange = (event) => { const files = event.srcElement.files; if (files.length > 0) { this.picture = (window.URL || window.webkitURL).createObjectURL( @@ -30,45 +31,45 @@ function alpine_webcam_builder(default_picture, delete_url, can_delete_picture) } }, - get_picture() { - return this.picture || default_picture; + getPicture() { + return this.picture || defaultPicture; }, - delete_picture() { + deletePicture() { // Only remove currently displayed picture if (this.picture) { const list = new DataTransfer(); - this.picture_form.files = list.files; - this.picture_form.dispatchEvent(new Event("change")); + this.pictureForm.files = list.files; + this.pictureForm.dispatchEvent(new Event("change")); return; } - if (!can_delete_picture) { + if (!canDeletePicture) { return; } // Remove user picture if correct rights are available - window.open(delete_url, "_self"); + window.open(deleteUrl, "_self"); }, - enable_camera() { + enableCamera() { this.picture = null; this.loading = true; - this.is_camera_error = false; + this.isCameraError = false; navigator.mediaDevices .getUserMedia({ video: true, audio: false }) .then((stream) => { this.loading = false; - this.is_camera_enabled = true; + this.isCameraEnabled = true; this.video.srcObject = stream; this.video.play(); }) .catch((err) => { - this.is_camera_error = true; + this.isCameraError = true; this.loading = false; throw err; }); }, - take_picture() { + takePicture() { const canvas = document.createElement("canvas"); const context = canvas.getContext("2d"); @@ -94,14 +95,14 @@ function alpine_webcam_builder(default_picture, delete_url, can_delete_picture) const list = new DataTransfer(); list.items.add(file); - this.picture_form.files = list.files; + this.pictureForm.files = list.files; // No change event is triggered, we trigger it manually #} - this.picture_form.dispatchEvent(new Event("change")); + this.pictureForm.dispatchEvent(new Event("change")); }, "image/webp"); canvas.remove(); - this.is_camera_enabled = false; + this.isCameraEnabled = false; }, }); } diff --git a/core/static/webpack/alpine-index.js b/core/static/webpack/alpine-index.js index a87b337c..d07e0bf2 100644 --- a/core/static/webpack/alpine-index.js +++ b/core/static/webpack/alpine-index.js @@ -2,6 +2,6 @@ import Alpine from "alpinejs"; window.Alpine = Alpine; -window.addEventListener("DOMContentLoaded", (event) => { +window.addEventListener("DOMContentLoaded", () => { Alpine.start(); }); diff --git a/core/static/webpack/easymde-index.js b/core/static/webpack/easymde-index.js index 6bd46a82..f94bc538 100644 --- a/core/static/webpack/easymde-index.js +++ b/core/static/webpack/easymde-index.js @@ -1,6 +1,7 @@ +// biome-ignore lint/correctness/noUndeclaredDependencies: shipped by easymde import "codemirror/lib/codemirror.css"; import "easymde/src/css/easymde.css"; -import EasyMDE from "easymde"; +import easyMde from "easymde"; // This scripts dependens on Alpine but it should be loaded on every page @@ -9,13 +10,13 @@ import EasyMDE from "easymde"; * @param {HTMLTextAreaElement} textarea to use * @param {string} link to the markdown api **/ -function easymdeFactory(textarea, markdownApiURL) { - const easymde = new EasyMDE({ +function easymdeFactory(textarea, markdownApiUrl) { + const easymde = new easyMde({ element: textarea, spellChecker: false, autoDownloadFontAwesome: false, previewRender: Alpine.debounce(async (plainText, preview) => { - const res = await fetch(markdownApiURL, { + const res = await fetch(markdownApiUrl, { method: "POST", body: JSON.stringify({ text: plainText }), }); @@ -26,25 +27,25 @@ function easymdeFactory(textarea, markdownApiURL) { toolbar: [ { name: "heading-smaller", - action: EasyMDE.toggleHeadingSmaller, + action: easyMde.toggleHeadingSmaller, className: "fa fa-header", title: gettext("Heading"), }, { name: "italic", - action: EasyMDE.toggleItalic, + action: easyMde.toggleItalic, className: "fa fa-italic", title: gettext("Italic"), }, { name: "bold", - action: EasyMDE.toggleBold, + action: easyMde.toggleBold, className: "fa fa-bold", title: gettext("Bold"), }, { name: "strikethrough", - action: EasyMDE.toggleStrikethrough, + action: easyMde.toggleStrikethrough, className: "fa fa-strikethrough", title: gettext("Strikethrough"), }, @@ -77,71 +78,71 @@ function easymdeFactory(textarea, markdownApiURL) { }, { name: "code", - action: EasyMDE.toggleCodeBlock, + action: easyMde.toggleCodeBlock, className: "fa fa-code", title: gettext("Code"), }, "|", { name: "quote", - action: EasyMDE.toggleBlockquote, + action: easyMde.toggleBlockquote, className: "fa fa-quote-left", title: gettext("Quote"), }, { name: "unordered-list", - action: EasyMDE.toggleUnorderedList, + action: easyMde.toggleUnorderedList, className: "fa fa-list-ul", title: gettext("Unordered list"), }, { name: "ordered-list", - action: EasyMDE.toggleOrderedList, + action: easyMde.toggleOrderedList, className: "fa fa-list-ol", title: gettext("Ordered list"), }, "|", { name: "link", - action: EasyMDE.drawLink, + action: easyMde.drawLink, className: "fa fa-link", title: gettext("Insert link"), }, { name: "image", - action: EasyMDE.drawImage, + action: easyMde.drawImage, className: "fa-regular fa-image", title: gettext("Insert image"), }, { name: "table", - action: EasyMDE.drawTable, + action: easyMde.drawTable, className: "fa fa-table", title: gettext("Insert table"), }, "|", { name: "clean-block", - action: EasyMDE.cleanBlock, + action: easyMde.cleanBlock, className: "fa fa-eraser fa-clean-block", title: gettext("Clean block"), }, "|", { name: "preview", - action: EasyMDE.togglePreview, + action: easyMde.togglePreview, className: "fa fa-eye no-disable", title: gettext("Toggle preview"), }, { name: "side-by-side", - action: EasyMDE.toggleSideBySide, + action: easyMde.toggleSideBySide, className: "fa fa-columns no-disable no-mobile", title: gettext("Toggle side by side"), }, { name: "fullscreen", - action: EasyMDE.toggleFullScreen, + action: easyMde.toggleFullScreen, className: "fa fa-expand no-mobile", title: gettext("Toggle fullscreen"), }, @@ -159,7 +160,7 @@ function easymdeFactory(textarea, markdownApiURL) { const parentDiv = textarea.parentElement; let submitPressed = false; - function checkMarkdownInput(e) { + function checkMarkdownInput() { // an attribute is null if it does not exist, else a string const required = textarea.getAttribute("required") != null; const length = textarea.value.trim().length; diff --git a/core/templates/core/base.jinja b/core/templates/core/base.jinja index 8ad76d09..7492276b 100644 --- a/core/templates/core/base.jinja +++ b/core/templates/core/base.jinja @@ -112,7 +112,7 @@ >
- + {% set notification_count = user.notifications.filter(viewed=False).count() %} diff --git a/core/templates/core/user_edit.jinja b/core/templates/core/user_edit.jinja index cb39dedb..173b3e8e 100644 --- a/core/templates/core/user_edit.jinja +++ b/core/templates/core/user_edit.jinja @@ -15,36 +15,36 @@ {% macro profile_picture(field_name) %} {% set this_picture = form.instance[field_name] %}
-
+
{%- trans -%}Profile{%- endtrans -%}
-
+
@@ -56,22 +56,22 @@ @@ -96,10 +96,10 @@
{% endblock %} diff --git a/core/templates/core/user_pictures.jinja b/core/templates/core/user_pictures.jinja index 85baf847..24722b17 100644 --- a/core/templates/core/user_pictures.jinja +++ b/core/templates/core/user_pictures.jinja @@ -21,14 +21,14 @@ {% if user.id == object.id %}
- +
{% endif %} @@ -92,13 +92,13 @@ document.addEventListener("alpine:init", () => { Alpine.data("user_pictures", () => ({ - is_downloading: false, + isDownloading: false, loading: true, pictures: [], albums: {}, async init() { - this.pictures = await fetch_paginated("{{ url("api:pictures") }}" + "?users_identified={{ object.id }}"); + this.pictures = await fetchPaginated("{{ url("api:pictures") }}" + "?users_identified={{ object.id }}"); this.albums = this.pictures.reduce((acc, picture) => { if (!acc[picture.album]){ acc[picture.album] = []; @@ -109,8 +109,8 @@ this.loading = false; }, - async download_zip(){ - this.is_downloading = true; + async downloadZip(){ + this.isDownloading = true; const bar = this.$refs.progress; bar.value = 0; bar.max = this.pictures.length; @@ -124,16 +124,16 @@ const zipWriter = new zip.ZipWriter(await fileHandle.createWritable()); await Promise.all(this.pictures.map(p => { - const img_name = p.album + "/IMG_" + p.date.replaceAll(/[:\-]/g, "_") + p.name.slice(p.name.lastIndexOf(".")); + const imgName = p.album + "/IMG_" + p.date.replaceAll(/[:\-]/g, "_") + p.name.slice(p.name.lastIndexOf(".")); return zipWriter.add( - img_name, + imgName, new zip.HttpReader(p.full_size_url), {level: 9, lastModDate: new Date(p.date), onstart: () => bar.value += 1} ); })); await zipWriter.close(); - this.is_downloading = false; + this.isDownloading = false; } })) }); diff --git a/counter/static/counter/js/counter_click.js b/counter/static/counter/js/counter_click.js index d5df9207..b0ddb42c 100644 --- a/counter/static/counter/js/counter_click.js +++ b/counter/static/counter/js/counter_click.js @@ -1,9 +1,10 @@ document.addEventListener("alpine:init", () => { Alpine.data("counter", () => ({ - basket, + // biome-ignore lint/correctness/noUndeclaredVariables: defined in counter_click.jinja + basket: sessionBasket, errors: [], - sum_basket() { + sumBasket() { if (!this.basket || Object.keys(this.basket).length === 0) { return 0; } @@ -14,23 +15,26 @@ document.addEventListener("alpine:init", () => { return total / 100; }, - async handle_code(event) { + async handleCode(event) { const code = $(event.target).find("#code_field").val().toUpperCase(); if (["FIN", "ANN"].includes(code)) { $(event.target).submit(); } else { - await this.handle_action(event); + await this.handleAction(event); } }, - async handle_action(event) { + async handleAction(event) { const payload = $(event.target).serialize(); - const request = new Request(click_api_url, { + // biome-ignore lint/correctness/noUndeclaredVariables: defined in counter_click.jinja + const request = new Request(clickApiUrl, { method: "POST", body: payload, headers: { + // biome-ignore lint/style/useNamingConvention: this goes into http headers Accept: "application/json", - "X-CSRFToken": csrf_token, + // biome-ignore lint/correctness/noUndeclaredVariables: defined in counter_click.jinja + "X-CSRFToken": csrfToken, }, }); const response = await fetch(request); @@ -44,25 +48,27 @@ document.addEventListener("alpine:init", () => { $(() => { /* Autocompletion in the code field */ - const code_field = $("#code_field"); + const codeField = $("#code_field"); let quantity = ""; - code_field.autocomplete({ + codeField.autocomplete({ select: (event, ui) => { event.preventDefault(); - code_field.val(quantity + ui.item.value); + codeField.val(quantity + ui.item.value); }, focus: (event, ui) => { event.preventDefault(); - code_field.val(quantity + ui.item.value); + codeField.val(quantity + ui.item.value); }, source: (request, response) => { + // biome-ignore lint/performance/useTopLevelRegex: performance impact is minimal const res = /^(\d+x)?(.*)/i.exec(request.term); quantity = res[1] || ""; const search = res[2]; const matcher = new RegExp($.ui.autocomplete.escapeRegex(search), "i"); response( - $.grep(products_autocomplete, (value) => { + // biome-ignore lint/correctness/noUndeclaredVariables: defined in counter_click.jinja + $.grep(productsAutocomplete, (value) => { return matcher.test(value.tags); }), ); @@ -76,5 +82,5 @@ $(() => { }); $("#products").tabs(); - code_field.focus(); + codeField.focus(); }); diff --git a/counter/templates/counter/counter_click.jinja b/counter/templates/counter/counter_click.jinja index 2c725991..cb6bb9cf 100644 --- a/counter/templates/counter/counter_click.jinja +++ b/counter/templates/counter/counter_click.jinja @@ -59,7 +59,7 @@ {# Formulaire pour rechercher un produit en tapant son code dans une barre de recherche #}
+ class="code_form" @submit.prevent="handleCode"> {% csrf_token %} @@ -77,7 +77,7 @@
- {{ paginate_alpine("page", "nb_pages()") }} + {{ paginate_alpine("page", "nbPages()") }}
{% if is_sas_admin %} @@ -116,14 +116,14 @@ loading: false, async init() { - await this.fetch_pictures(); + await this.fetchPictures(); this.$watch("page", () => { - update_query_string("page", + updateQueryString("page", this.page === 1 ? null : this.page, this.pushstate ); this.pushstate = History.PUSH; - this.fetch_pictures(); + this.fetchPictures(); }); window.addEventListener("popstate", () => { @@ -134,7 +134,7 @@ }); }, - async fetch_pictures() { + async fetchPictures() { this.loading=true; const url = "{{ url("api:pictures") }}" +"?album_id={{ album.id }}" @@ -144,7 +144,7 @@ this.loading = false; }, - nb_pages() { + nbPages() { return Math.ceil(this.pictures.count / {{ settings.SITH_SAS_IMAGES_PER_PAGE }}); } })) diff --git a/sas/templates/sas/picture.jinja b/sas/templates/sas/picture.jinja index b9aef1ae..cf6b8475 100644 --- a/sas/templates/sas/picture.jinja +++ b/sas/templates/sas/picture.jinja @@ -17,21 +17,21 @@ {% block content %}
- SAS / {{ print_path(album) }} + SAS / {{ print_path(album) }}
-

-

+

+


-