Files
integreat/src/cljs/auto_ap/forms.cljs
2022-07-26 07:01:18 -07:00

164 lines
4.5 KiB
Clojure

(ns auto-ap.forms
(:require [re-frame.core :as re-frame]
[re-frame.interceptor :as i]
[auto-ap.status :as status]
[malli.core :as m]))
(re-frame/reg-sub
::form
(fn [db [_ x]]
(update (get (-> db ::forms) x)
:visited (fn [v]
(or v #{})))))
(re-frame/reg-sub
::field
(fn [db [_ x f]]
(-> (get (-> db ::forms) x)
:data
(get-in f))))
(defn start-form
([db form data]
(start-form db form data nil))
([db form data complete-listener]
(-> db
(assoc-in [::forms form] {:error nil
:active? true
:id (random-uuid)
:visited #{}
:status nil
:data data
:complete-listener complete-listener})
(assoc-in [::status/status form] nil))))
(re-frame/reg-event-db
::start-form
(fn [db [_ id data]]
(start-form db id data)))
(defn triggers-saved [form data-key]
(i/->interceptor
:id :triggers-saved
:before (fn [context]
context)
:after (fn [context]
(let [db (i/get-coeffect context :db)
result (get-in (i/get-coeffect context :event) [1 data-key])]
(cond-> context
true
(i/assoc-effect :db (update-in db
[::forms form]
assoc :error nil :status nil :data result))
(get-in db [::forms form :complete-listener])
(i/assoc-effect :dispatch (conj (get-in db [::forms form :complete-listener ])
result)))))))
(defn stop-form [db form]
(update db ::forms dissoc form))
(re-frame/reg-event-db
::form-closing
(fn [db [_ f]]
(-> db
(stop-form f))))
(defn in-form
[form-name]
(re-frame/path [::forms form-name]))
(re-frame/reg-event-db
::change
(fn [db [_ form & path-pairs]]
(reduce
(fn [db [path value]]
(assoc-in db (into [::forms form :data] path) value))
db
(partition 2 path-pairs))))
(re-frame/reg-event-db
::reset
(fn [db [_ form v]]
(assoc-in db [::forms form :data] v)))
(re-frame/reg-event-db
::visited
(fn [db [_ form & paths]]
(update-in db [::forms form :visited] (fn [v]
(set (into v paths))))))
(re-frame/reg-event-db
::check-problems
(fn [db [_ form schema]]
(assoc-in db [::forms form :problems]
(when schema (m/explain schema (get-in db [::forms form :data]))))))
(re-frame/reg-event-db
::attempted-submit
(fn [db [_ form ]]
(assoc-in db [::forms form :attempted-submit?] true)))
(defn change-handler [form customize-fn]
(fn [db [_ & path-pairs]]
(reduce
(fn [db [path value]]
(let [updated (assoc-in db (into [::forms form :data] path) value)]
(reduce
(fn [updated [path value ]]
(assoc-in updated (into [::forms form :data] path) value))
updated
(partition 2 (customize-fn (get-in updated [::forms form :data]) path value)))))
db
(partition 2 path-pairs))))
(re-frame/reg-event-db
::save-error
(fn [db [_ form result]]
(println result)
(-> db
(assoc-in [::forms form :status] :error)
(assoc-in [::forms form :error] (or (:message (first result))
result)))))
;; TODO ^:deprecated
(defn loading [db id]
(-> db
(assoc-in [::forms id :status] :loading)
(assoc-in [::forms id :error] nil)))
#_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]}
(defn settles [{:keys [event time key]}]
(i/->interceptor
:id :settles
:before (fn [context]
context)
:after (fn [context]
(i/assoc-effect context :dispatch-debounce {:event event
:time time
:key key}))))
(defn triggers-loading [form]
(re-frame/enrich
(fn [db _]
(loading db form))))
(defn triggers-stop [form]
(re-frame/enrich
(fn [db _]
(stop-form db form))))
(defn triggers-stop-loading [form]
(re-frame/enrich
(fn [db _]
(assoc-in db [::forms form :status] nil))))
(defn save-succeeded [db id]
(-> db
(assoc-in [::forms id :status] nil)
(assoc-in [::forms id :error] nil)))