212 lines
6.8 KiB
Clojure
212 lines
6.8 KiB
Clojure
(ns auto-ap.forms
|
|
(:require [re-frame.core :as re-frame]
|
|
[re-frame.interceptor :as i]
|
|
[auto-ap.status :as status]
|
|
[auto-ap.views.utils :refer [dispatch-event bind-field]]))
|
|
|
|
|
|
(re-frame/reg-sub
|
|
::form
|
|
(fn [db [_ x]]
|
|
(get (-> db ::forms) x)))
|
|
|
|
|
|
(re-frame/reg-sub
|
|
::is-loading?
|
|
(fn [db [_ x]]
|
|
(if (#{"loading" :loading} (get-in db [::forms x :status]) )
|
|
true
|
|
false)))
|
|
|
|
(re-frame/reg-sub
|
|
::loading-class
|
|
(fn [db [_ x]]
|
|
(if (#{"loading" :loading} (get-in db [::forms x :status]) )
|
|
"is-loading"
|
|
"")))
|
|
|
|
(defn start-form
|
|
([db form data]
|
|
(start-form db form data nil))
|
|
([db form data complete-listener]
|
|
(assoc-in db [::forms form] {:error nil
|
|
:active? true
|
|
:id (random-uuid)
|
|
:status nil
|
|
:data data
|
|
:complete-listener complete-listener})))
|
|
|
|
(defn ^:depracated saved-form [db form data]
|
|
(update-in db [::forms form]
|
|
assoc :error nil :status nil :data 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))))
|
|
|
|
(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)))))
|
|
|
|
|
|
(defn ^:deprecated side-bar-form [{:keys [form]} children]
|
|
[:div [:a.delete.is-pulled-right {:on-click (dispatch-event [::form-closing form])}] [:div children]])
|
|
|
|
|
|
;; TODO ^:deprecated
|
|
(defn loading [db id]
|
|
(-> db
|
|
(assoc-in [::forms id :status] :loading)
|
|
(assoc-in [::forms id :error] nil)))
|
|
|
|
(defn settles [{:keys [event time key]}]
|
|
(i/->interceptor
|
|
:id :settles
|
|
:befor (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 event]
|
|
(loading db form))))
|
|
|
|
(defn triggers-stop [form]
|
|
(re-frame/enrich
|
|
(fn [db event]
|
|
(stop-form db form))))
|
|
|
|
(defn triggers-stop-loading [form]
|
|
(re-frame/enrich
|
|
(fn [db event]
|
|
(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)))
|
|
|
|
|
|
(defn vertical-form [{:keys [can-submit id change-event submit-event ]}]
|
|
{:form
|
|
(fn [{:keys [title] :as params} & children]
|
|
(let [{:keys [data active? error]} @(re-frame/subscribe [::form id])
|
|
can-submit @(re-frame/subscribe can-submit)]
|
|
|
|
[:form { :on-submit (fn [e]
|
|
(when (.-stopPropagation e)
|
|
(.stopPropagation e)
|
|
(.preventDefault e))
|
|
(when can-submit
|
|
(re-frame/dispatch-sync (vec (conj submit-event params)))))}
|
|
[:h1.title.is-2 title]
|
|
[:<>
|
|
children]]))
|
|
|
|
:form-inline
|
|
(fn [{:keys [title] :as params} children]
|
|
(let [{:keys [data active? error]} @(re-frame/subscribe [::form id])
|
|
can-submit @(re-frame/subscribe can-submit)]
|
|
|
|
[:form { :on-submit (fn [e]
|
|
(when (.-stopPropagation e)
|
|
(.stopPropagation e)
|
|
(.preventDefault e))
|
|
(when can-submit
|
|
(re-frame/dispatch-sync (vec (conj submit-event params)))))}
|
|
(when title
|
|
[:h1.title.is-2 title])
|
|
children]))
|
|
:raw-field (fn [control]
|
|
(let [{:keys [data]} @(re-frame/subscribe [::form id])]
|
|
[bind-field (-> control
|
|
(assoc-in [1 :subscription] data)
|
|
(assoc-in [1 :event] change-event))]))
|
|
:field-holder (fn [label control]
|
|
[:div.field
|
|
(when label [:p.help label])
|
|
[:div.control control]])
|
|
:field ^{:key "field"}
|
|
(fn [label control]
|
|
(let [{:keys [data]} @(re-frame/subscribe [::form id])]
|
|
[:div.field
|
|
(when label [:p.help label])
|
|
[:div.control [bind-field (-> control
|
|
(assoc-in [1 :subscription] data)
|
|
(assoc-in [1 :event] change-event))]]]))
|
|
|
|
:error-notification
|
|
(fn []
|
|
(when-let [error (:error @(re-frame/subscribe [::form id]))]
|
|
^{:key error}
|
|
[:div.has-text-danger.animated.fadeInUp {} error]))
|
|
:submit-button (fn [child]
|
|
(let [error (:error @(re-frame/subscribe [::form id]))
|
|
status @(re-frame/subscribe [::status/single id])
|
|
can-submit @(re-frame/subscribe can-submit)]
|
|
[:button.button.is-medium.is-primary.is-fullwidth {:disabled (or (status/disabled-for status)
|
|
(not can-submit))
|
|
:class (status/class-for status) }
|
|
child]))})
|
|
|