From e35c1d1928565ddce745a3a9ef8cfb645b1eea62 Mon Sep 17 00:00:00 2001 From: Thomas Girod Date: Sun, 6 Apr 2025 12:22:32 +0200 Subject: [PATCH 1/3] move `eboutic/makecommand.js` to bundled directory --- .../makecommand.js => bundled/eboutic/makecommand-index.ts} | 5 +++-- eboutic/templates/eboutic/eboutic_makecommand.jinja | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) rename eboutic/static/{eboutic/js/makecommand.js => bundled/eboutic/makecommand-index.ts} (94%) diff --git a/eboutic/static/eboutic/js/makecommand.js b/eboutic/static/bundled/eboutic/makecommand-index.ts similarity index 94% rename from eboutic/static/eboutic/js/makecommand.js rename to eboutic/static/bundled/eboutic/makecommand-index.ts index 3ccb4280..da2a6f58 100644 --- a/eboutic/static/eboutic/js/makecommand.js +++ b/eboutic/static/bundled/eboutic/makecommand-index.ts @@ -17,12 +17,13 @@ document.addEventListener("alpine:init", () => { data: etData, async fill() { - document.getElementById("bank-submit-button").disabled = true; + const button = document.getElementById("bank-submit-button") as HTMLButtonElement; + button.disabled = true; // biome-ignore lint/correctness/noUndeclaredVariables: defined in eboutic_makecommand.jinja const res = await fetch(etDataUrl); if (res.ok) { this.data = await res.json(); - document.getElementById("bank-submit-button").disabled = false; + button.disabled = false; } }, }); diff --git a/eboutic/templates/eboutic/eboutic_makecommand.jinja b/eboutic/templates/eboutic/eboutic_makecommand.jinja index e18514e9..1846cdd1 100644 --- a/eboutic/templates/eboutic/eboutic_makecommand.jinja +++ b/eboutic/templates/eboutic/eboutic_makecommand.jinja @@ -9,7 +9,7 @@ {% endblock %} {% block additional_js %} - + {% endblock %} {% block content %} From d03c425a17a397f819b69c187c7bf0661415cc58 Mon Sep 17 00:00:00 2001 From: Thomas Girod Date: Sun, 6 Apr 2025 16:25:55 +0200 Subject: [PATCH 2/3] refactor eboutic command page --- .pre-commit-config.yaml | 2 +- eboutic/api.py | 2 +- .../bundled/eboutic/makecommand-index.ts | 91 ++++++++++--------- eboutic/static/eboutic/css/eboutic.css | 1 - .../eboutic/eboutic_makecommand.jinja | 43 ++++----- eboutic/views.py | 4 +- locale/fr/LC_MESSAGES/django.po | 27 ++---- locale/fr/LC_MESSAGES/djangojs.po | 12 ++- 8 files changed, 90 insertions(+), 92 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 8d72985b..b334a7c0 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -9,7 +9,7 @@ repos: # Run the formatter. - id: ruff-format - repo: https://github.com/biomejs/pre-commit - rev: "v0.1.0" # Use the sha / tag you want to point at + rev: v0.6.1 hooks: - id: biome-check additional_dependencies: ["@biomejs/biome@1.9.4"] diff --git a/eboutic/api.py b/eboutic/api.py index 0054c02a..797adf20 100644 --- a/eboutic/api.py +++ b/eboutic/api.py @@ -26,7 +26,7 @@ class EtransactionInfoController(ControllerBase): customer=customer, defaults=info.model_dump(exclude_none=True) ) - @route.get("/data", url_name="etransaction_data", include_in_schema=False) + @route.get("/data", url_name="etransaction_data") def fetch_etransaction_data(self): """Generate the data to pay an eboutic command with paybox. diff --git a/eboutic/static/bundled/eboutic/makecommand-index.ts b/eboutic/static/bundled/eboutic/makecommand-index.ts index da2a6f58..c1e4b52f 100644 --- a/eboutic/static/bundled/eboutic/makecommand-index.ts +++ b/eboutic/static/bundled/eboutic/makecommand-index.ts @@ -1,56 +1,61 @@ -/** - * @readonly - * @enum {number} - */ -const BillingInfoReqState = { - // biome-ignore lint/style/useNamingConvention: this feels more like an enum - SUCCESS: 1, - // biome-ignore lint/style/useNamingConvention: this feels more like an enum - FAILURE: 2, - // biome-ignore lint/style/useNamingConvention: this feels more like an enum - SENDING: 3, -}; +import { exportToHtml } from "#core:utils/globals"; +import { + type BillingInfoSchema, + etransactioninfoFetchEtransactionData, + etransactioninfoPutUserBillingInfo, +} from "#openapi"; + +enum BillingInfoReqState { + Success = "0", + Failure = "1", + Sending = "2", +} + +exportToHtml("BillingInfoReqState", BillingInfoReqState); document.addEventListener("alpine:init", () => { - Alpine.store("billing_inputs", { - // biome-ignore lint/correctness/noUndeclaredVariables: defined in eboutic_makecommand.jinja - data: etData, + Alpine.data("etransactionData", (initialData) => ({ + data: initialData, async fill() { const button = document.getElementById("bank-submit-button") as HTMLButtonElement; button.disabled = true; - // biome-ignore lint/correctness/noUndeclaredVariables: defined in eboutic_makecommand.jinja - const res = await fetch(etDataUrl); - if (res.ok) { - this.data = await res.json(); + const res = await etransactioninfoFetchEtransactionData(); + if (res.response.ok) { + this.data = res.data; button.disabled = false; } }, - }); + })); - Alpine.data("billing_infos", () => ({ + Alpine.data("billing_infos", (userId: number) => ({ /** @type {BillingInfoReqState | null} */ reqState: null, async sendForm() { - this.reqState = BillingInfoReqState.SENDING; + this.reqState = BillingInfoReqState.Sending; const form = document.getElementById("billing_info_form"); - document.getElementById("bank-submit-button").disabled = true; + const submitButton = document.getElementById( + "bank-submit-button", + ) as HTMLButtonElement; + submitButton.disabled = true; const payload = Object.fromEntries( Array.from(form.querySelectorAll("input, select")) - .filter((elem) => elem.type !== "submit" && elem.value) - .map((elem) => [elem.name, elem.value]), + .filter((elem: HTMLInputElement) => elem.type !== "submit" && elem.value) + .map((elem: HTMLInputElement) => [elem.name, elem.value]), ); - // biome-ignore lint/correctness/noUndeclaredVariables: defined in eboutic_makecommand.jinja - const res = await fetch(billingInfoUrl, { - method: "PUT", - body: JSON.stringify(payload), + const res = await etransactioninfoPutUserBillingInfo({ + // biome-ignore lint/style/useNamingConvention: API is snake_case + path: { user_id: userId }, + body: payload as unknown as BillingInfoSchema, }); - this.reqState = res.ok - ? BillingInfoReqState.SUCCESS - : BillingInfoReqState.FAILURE; - if (res.status === 422) { - const errors = (await res.json()).detail.flatMap((err) => err.loc); + this.reqState = res.response.ok + ? BillingInfoReqState.Success + : BillingInfoReqState.Failure; + if (res.response.status === 422) { + const errors = await res.response + .json() + .detail.flatMap((err: Record<"loc", string>) => err.loc); for (const elem of Array.from(form.querySelectorAll("input")).filter((elem) => errors.includes(elem.name), )) { @@ -58,29 +63,27 @@ document.addEventListener("alpine:init", () => { elem.reportValidity(); elem.oninput = () => elem.setCustomValidity(""); } - } else if (res.ok) { - Alpine.store("billing_inputs").fill(); + } else if (res.response.ok) { + this.$dispatch("billing-infos-filled"); } }, getAlertColor() { - if (this.reqState === BillingInfoReqState.SUCCESS) { + if (this.reqState === BillingInfoReqState.Success) { return "green"; } - if (this.reqState === BillingInfoReqState.FAILURE) { + if (this.reqState === BillingInfoReqState.Failure) { return "red"; } return ""; }, getAlertMessage() { - if (this.reqState === BillingInfoReqState.SUCCESS) { - // biome-ignore lint/correctness/noUndeclaredVariables: defined in eboutic_makecommand.jinja - return billingInfoSuccessMessage; + if (this.reqState === BillingInfoReqState.Success) { + return gettext("Billing info registration success"); } - if (this.reqState === BillingInfoReqState.FAILURE) { - // biome-ignore lint/correctness/noUndeclaredVariables: defined in eboutic_makecommand.jinja - return billingInfoFailureMessage; + if (this.reqState === BillingInfoReqState.Failure) { + return gettext("Billing info registration failure"); } return ""; }, diff --git a/eboutic/static/eboutic/css/eboutic.css b/eboutic/static/eboutic/css/eboutic.css index abf121d0..6ca6beef 100644 --- a/eboutic/static/eboutic/css/eboutic.css +++ b/eboutic/static/eboutic/css/eboutic.css @@ -158,4 +158,3 @@ flex-direction: column; } } - diff --git a/eboutic/templates/eboutic/eboutic_makecommand.jinja b/eboutic/templates/eboutic/eboutic_makecommand.jinja index 1846cdd1..82ad4c51 100644 --- a/eboutic/templates/eboutic/eboutic_makecommand.jinja +++ b/eboutic/templates/eboutic/eboutic_makecommand.jinja @@ -9,7 +9,7 @@ {% endblock %} {% block additional_js %} - + {% endblock %} {% block content %} @@ -56,7 +56,7 @@
@@ -70,7 +70,7 @@

{% if billing_infos_state == BillingInfoState.EMPTY %}
- {% trans %}You must fill your billing infos if you want to pay with your credit - card{% endtrans %} + {% trans trimmed %} + You must fill your billing infos if you want to pay with your credit card + {% endtrans %}
{% elif billing_infos_state == BillingInfoState.MISSING_PHONE_NUMBER %}
- {% trans %} + {% trans trimmed %} The Crédit Agricole changed its policy related to the billing information that must be provided in order to pay with a credit card. If you want to pay with your credit card, you must add a phone number @@ -112,8 +113,14 @@ {% endtrans %}
{% endif %} -
-