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
This commit is contained in:
@@ -16,13 +16,13 @@
|
||||
"@click" (format "$dispatch('sorted', {key: '%s'})" (:sort-key params))
|
||||
:style (:style params)}]
|
||||
(if (:sort-key params)
|
||||
[(into [:a {:href "#"} ] rest)]
|
||||
[(into [:a {:href "#"}] rest)]
|
||||
rest)))
|
||||
|
||||
(defn sort-header- [params & rest]
|
||||
[:th.px-4.py-3 {:scope "col" :class (:class params)
|
||||
"@click" (format "$dispatch('sorted', {key: '%s'})" (:sort-key params)) }
|
||||
(into [:a {:href "#"} ] rest)])
|
||||
"@click" (format "$dispatch('sorted', {key: '%s'})" (:sort-key params))}
|
||||
(into [:a {:href "#"}] rest)])
|
||||
|
||||
(defn row- [params & rest]
|
||||
(into [:tr (update params
|
||||
@@ -31,11 +31,11 @@
|
||||
(defn cell- [params & rest]
|
||||
(into [:td.px-4.py-2 (update params
|
||||
:class #(str (-> ""
|
||||
(hh/add-class (or % ""))))) ]
|
||||
(hh/add-class (or % "")))))]
|
||||
rest))
|
||||
|
||||
(defn right-stack-cell- [params & rest]
|
||||
(cell- params (into [:div.flex.flex-row-reverse.items-center.justify-between
|
||||
(cell- params (into [:div.flex.flex-row-reverse.items-center.justify-between
|
||||
rest])))
|
||||
|
||||
(defn checkbox-header- [params & rest]
|
||||
@@ -46,17 +46,17 @@
|
||||
|
||||
(defn data-grid-
|
||||
[{:keys [headers thead-params id] :as params} & rest]
|
||||
[:div.shrink.overflow-y-scroll
|
||||
[:div.shrink.overflow-y-scroll
|
||||
[:table (merge {:class "w-full text-sm text-left text-gray-500 dark:text-gray-400 shrink"}
|
||||
(dissoc params :headers :thead-params))
|
||||
[:thead (update thead-params :class #(-> "text-xs text-gray-800 uppercase bg-gray-50 dark:bg-gray-700 dark:text-gray-400 group-[.raw]:sticky group-[.raw]:z-10 group-[.raw]:top-0"
|
||||
(hh/add-class (or % ""))))
|
||||
(into
|
||||
[:tr]
|
||||
headers)]
|
||||
(into
|
||||
[:tbody {}]
|
||||
rest)]])
|
||||
(into
|
||||
[:tr]
|
||||
headers)]
|
||||
(into
|
||||
[:tbody {}]
|
||||
rest)]])
|
||||
|
||||
;; needed for tailwind
|
||||
;; lg:table-cell md:table-cell
|
||||
@@ -81,35 +81,35 @@
|
||||
rows] :as params} & children]
|
||||
(let [card (if raw? raw-table-card content-card-)]
|
||||
(card
|
||||
(cond-> { :id id :class (cond-> "group" raw? (hh/add-class "raw h-full flex flex-col overflow-hidden")) }
|
||||
root-params (merge root-params)
|
||||
route (assoc
|
||||
:hx-get (bidi/path-for ssr-routes/only-routes
|
||||
route
|
||||
:request-method :get)
|
||||
:hx-trigger "clientSelected from:body, invalidated from:body"
|
||||
:hx-swap "outerHTML swap:300ms"))
|
||||
[:div {:class " flex flex-col px-4 py-3 space-y-3 lg:flex-row lg:items-baseline lg:justify-between lg:space-y-0 lg:space-x-4 text-gray-800 dark:text-gray-100"}
|
||||
[:h1.text-2xl.mb-3.font-bold title]
|
||||
[:div {:class "flex items-center flex-1 space-x-4"}
|
||||
[:h5
|
||||
(when subtitle
|
||||
[:span subtitle])]]
|
||||
(into [:div {:class "group-[.raw]:hidden flex flex-col flex-shrink-0 space-y-3 md:flex-row md:items-center lg:justify-end md:space-y-0 md:space-x-3"}]
|
||||
action-buttons)]
|
||||
[:div {:class "overflow-x-auto contents"}
|
||||
(data-grid- {:headers headers
|
||||
:thead-params thead-params}
|
||||
rows)]
|
||||
(cond-> {:id id :class (cond-> "group" raw? (hh/add-class "raw h-full flex flex-col overflow-hidden"))}
|
||||
root-params (merge root-params)
|
||||
route (assoc
|
||||
:hx-get (bidi/path-for ssr-routes/only-routes
|
||||
route
|
||||
:request-method :get)
|
||||
:hx-trigger "clientSelected from:body, invalidated from:body"
|
||||
:hx-swap "outerHTML swap:300ms"))
|
||||
[:div {:class " flex flex-col px-4 py-3 space-y-3 lg:flex-row lg:items-baseline lg:justify-between lg:space-y-0 lg:space-x-4 text-gray-800 dark:text-gray-100"}
|
||||
[:h1.text-2xl.mb-3.font-bold title]
|
||||
[:div {:class "flex items-center flex-1 space-x-4"}
|
||||
[:h5
|
||||
(when subtitle
|
||||
[:span subtitle])]]
|
||||
(into [:div {:class "group-[.raw]:hidden flex flex-col flex-shrink-0 space-y-3 md:flex-row md:items-center lg:justify-end md:space-y-0 md:space-x-3"}]
|
||||
action-buttons)]
|
||||
[:div {:class "overflow-x-auto contents"}
|
||||
(data-grid- {:headers headers
|
||||
:thead-params thead-params}
|
||||
rows)]
|
||||
|
||||
(when (or paginate?
|
||||
(nil? paginate?))
|
||||
[:div {:class "contents group-[.raw]:block"}
|
||||
(paginator- {:start start
|
||||
:end (Math/min (+ start per-page) total)
|
||||
:per-page per-page
|
||||
:total total
|
||||
:a-params (fn [page]
|
||||
(when (or paginate?
|
||||
(nil? paginate?))
|
||||
[:div {:class "contents group-[.raw]:block"}
|
||||
(paginator- {:start start
|
||||
:end (Math/min (+ start per-page) total)
|
||||
:per-page per-page
|
||||
:total total
|
||||
:a-params (fn [page]
|
||||
;; TODO it might be good to have a more global form defined in the specific page
|
||||
;; with elements that are part of item
|
||||
;; that way this is not deeply coupled
|
||||
@@ -117,44 +117,43 @@
|
||||
;; TODO the other way to think about this is that we want the request to include
|
||||
;; all of the correct parameters, not parameters to merge with the current ones.
|
||||
;; think sorting, filters, pagination
|
||||
{:hx-get (hu/url (bidi/path-for ssr-routes/only-routes
|
||||
route
|
||||
:request-method :get)
|
||||
{:start (* page per-page)})
|
||||
:hx-target (str "#" id)
|
||||
:hx-swap "outerHTML show:#app:top"
|
||||
:hx-indicator (str "#" id)})
|
||||
:per-page-params {:hx-get (hu/url (bidi/path-for ssr-routes/only-routes
|
||||
{:hx-get (hu/url (bidi/path-for ssr-routes/only-routes
|
||||
route
|
||||
:request-method :get))
|
||||
:hx-trigger "change"
|
||||
:hx-include "this"
|
||||
:hx-target (str "#" id) ;
|
||||
:request-method :get)
|
||||
{:start (* page per-page)})
|
||||
:hx-target (str "#" id)
|
||||
:hx-swap "outerHTML show:#app:top"
|
||||
:hx-indicator (str "#" id)}})])
|
||||
children
|
||||
[:div {:class "htmx-indicator absolute -translate-x-1/2 -translate-y-1/2 top-2/4 left-1/2 overflow-hidden w-full h-full"}
|
||||
[:div {:class "flex items-center justify-center w-full h-full border border-gray-200 rounded-lg bg-gray-50 dark:bg-gray-800 dark:border-gray-700 bg-opacity-50" }
|
||||
[:div {:class "px-3 py-1 text-xs font-medium leading-none text-center text-blue-800 bg-blue-200 rounded-full animate-pulse dark:bg-blue-900 dark:text-blue-200"} "loading..."]]])))
|
||||
:hx-indicator (str "#" id)})
|
||||
:per-page-params {:hx-get (hu/url (bidi/path-for ssr-routes/only-routes
|
||||
route
|
||||
:request-method :get))
|
||||
:hx-trigger "change"
|
||||
:hx-include "this"
|
||||
:hx-target (str "#" id) ;
|
||||
:hx-swap "outerHTML show:#app:top"
|
||||
:hx-indicator (str "#" id)}})])
|
||||
children
|
||||
[:div {:class "htmx-indicator absolute -translate-x-1/2 -translate-y-1/2 top-2/4 left-1/2 overflow-hidden w-full h-full"}
|
||||
[:div {:class "flex items-center justify-center w-full h-full border border-gray-200 rounded-lg bg-gray-50 dark:bg-gray-800 dark:border-gray-700 bg-opacity-50"}
|
||||
[:div {:class "px-3 py-1 text-xs font-medium leading-none text-center text-blue-800 bg-blue-200 rounded-full animate-pulse dark:bg-blue-900 dark:text-blue-200"} "loading..."]]])))
|
||||
|
||||
(defn new-row- [{:keys [index colspan tr-params row-offset] :as params} & content]
|
||||
(row-
|
||||
(merge {:class "new-row"
|
||||
"x-on:htmx:after-settle.camel" "let options=$el.parentNode.querySelectorAll('tr'); let target=options[options.length-2]; $nextTick(() => $focus.within(target).first())"
|
||||
(merge {:class "new-row"
|
||||
"x-on:htmx:after-settle.camel" "let options=$el.parentNode.querySelectorAll('tr'); let target=options[options.length-2]; $nextTick(() => $focus.within(target).first())"
|
||||
|
||||
:x-data (hx/json {:newRowIndex index
|
||||
:offset (or row-offset 0)}) }
|
||||
tr-params)
|
||||
(cell- {:colspan colspan
|
||||
:class "bg-gray-100"}
|
||||
[:div.flex.justify-center
|
||||
(a-button- (merge
|
||||
(dissoc params :index :colspan)
|
||||
{"@click.prevent" "$dispatch('newRow', {index: (newRowIndex++)})"
|
||||
:color :secondary
|
||||
:hx-trigger "newRow"
|
||||
:hx-vals (hiccup/raw "js:{index: event.detail.index }")
|
||||
:hx-target "closest .new-row"
|
||||
:hx-swap "beforebegin"
|
||||
})
|
||||
content)])))
|
||||
:x-data (hx/json {:newRowIndex index
|
||||
:offset (or row-offset 0)})}
|
||||
tr-params)
|
||||
(cell- {:colspan colspan
|
||||
:class "bg-gray-100"}
|
||||
[:div.flex.justify-center
|
||||
(a-button- (merge
|
||||
(dissoc params :index :colspan)
|
||||
{"@click.prevent" "$dispatch('newRow', {index: (newRowIndex++)})"
|
||||
:color :secondary
|
||||
:hx-trigger "newRow"
|
||||
:hx-vals (hiccup/raw "js:{index: event.detail.index }")
|
||||
:hx-target "closest .new-row"
|
||||
:hx-swap "beforebegin"})
|
||||
content)])))
|
||||
|
||||
Reference in New Issue
Block a user