Files
integreat/src/clj/auto_ap/ssr/hx.clj
Bryce ba87805d4c Add vendor pre-population for bulk code and individual edit forms
- Add vendor-changed HTMX handlers for both bulk code and individual edit
- Pre-populate default account at 100% when vendor is selected and no accounts exist
- Fix render-accounts-section to render from step-params correctly
- Change bulk code vendor-changed from hx-get to hx-post to include form data
- Add routes for vendor-changed endpoints
- Update e2e tests to cover vendor pre-population
- Run lein cljfmt fix across codebase
2026-05-21 14:45:19 -07:00

95 lines
3.0 KiB
Clojure

(ns auto-ap.ssr.hx
(:require [auto-ap.ssr.hiccup-helper :as hh]
[cheshire.core :as cheshire]
[cheshire.generate :refer [add-encoder]]
[clojure.string :as str]))
(defn vals [m]
(cheshire/generate-string m))
(deftype jsfn [body name])
(defn jsf [t jq]
(.writeString jq (str "__" (.-name t) "__" (.-body t) "__end__")))
(add-encoder jsfn jsf)
(defn json [m]
(let [starting-point (cheshire/generate-string m)]
(if (map? m)
(reduce
(fn [starting-point [k v]]
(if (instance? jsfn v)
(-> (str/replace starting-point (re-pattern (str "(?s)\"__" (.-name v) "__(.*?)__end__\"")) "$1")
(str/replace "\\n" "\n"))
starting-point))
starting-point
m)
starting-point)))
(defn random-alpha-string []
(let [alpha-chars (concat (map char (range 65 91)) ; A-Z
(map char (range 97 123))) ; a-z
random-char (fn [] (rand-nth alpha-chars))]
(apply str (repeatedly 10 random-char))))
(defn js-fn [s]
(jsfn. s (random-alpha-string)))
(defn trigger-field-change [& {:keys [name
from]}]
(format "change[target.name==\"%s\"] %s"
name
(when from (str "from:" from))))
(defn triggers [& triggers]
(str/join ", " triggers))
(defn alpine-appear [m]
(assoc m
"x-transition:enter" "transition-opacity duration-500"
"x-transition:enter-start" "opacity-0"
"x-transition:enter-end" "opacity-100"))
(defn alpine-disappear [m]
(assoc m
"x-transition:leave" "transition duration-500"
"x-transition:leave-start" "opacity-100"
"x-transition:leave-end" "opacity-0"))
(defn alpine-mount-then-appear [{:keys [data-key] :as params}]
(merge (-> {:x-data (json {data-key false})
:x-init (format "$nextTick(() => %s=true)" (name data-key))
:x-show (name data-key)}
alpine-appear
alpine-disappear)
(dissoc params :data-key)))
(defn alpine-mount-then-disappear [{:keys [data-key] :as params :or {data-key "show"}}]
(merge (-> {:x-data (json {data-key true})
:x-init (format "$nextTick(() => %s=false)" (name data-key))
:x-show (name data-key)}
alpine-appear
alpine-disappear)
(dissoc params :data-key)))
(defn bind-alpine-vals [m field->alpine-field]
(assoc m "x-bind:hx-vals"
(format "JSON.stringify({%s})"
(str/join ", "
(map
(fn [[field alpine-field]]
(format "\"%s\": $data.%s || ''" field alpine-field))
field->alpine-field)))))
(defn trigger-click-or-enter [m]
(assoc m :hx-trigger "click, keyup[keyCode==13]"))
(defn htmx-transition-appear [params]
(-> params
(update :class (fn [c]
(-> (or c "")
(hh/add-class "opacity-100 transition htmx-added:opacity-0 duration-300"))))))