ALmost done on UI improvements.
This commit is contained in:
@@ -14,7 +14,6 @@
|
|||||||
"rules" :admin-rules
|
"rules" :admin-rules
|
||||||
"accounts" :admin-accounts
|
"accounts" :admin-accounts
|
||||||
"import-batches" :admin-import-batches
|
"import-batches" :admin-import-batches
|
||||||
"reminders" :admin-reminders
|
|
||||||
"vendors" :admin-vendors
|
"vendors" :admin-vendors
|
||||||
"excel-import" :admin-excel-import
|
"excel-import" :admin-excel-import
|
||||||
"yodlee2" :admin-yodlee2}
|
"yodlee2" :admin-yodlee2}
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
(:require
|
(:require
|
||||||
[auto-ap.db :as db]
|
[auto-ap.db :as db]
|
||||||
[auto-ap.routes :as routes]
|
[auto-ap.routes :as routes]
|
||||||
[auto-ap.subs :as subs]
|
|
||||||
[auto-ap.utils :refer [by]]
|
[auto-ap.utils :refer [by]]
|
||||||
[auto-ap.views.utils :refer [with-user parse-jwt]]
|
[auto-ap.views.utils :refer [with-user parse-jwt]]
|
||||||
[bidi.bidi :as bidi]
|
[bidi.bidi :as bidi]
|
||||||
@@ -143,12 +142,12 @@
|
|||||||
(re-frame/reg-event-fx
|
(re-frame/reg-event-fx
|
||||||
::set-active-route
|
::set-active-route
|
||||||
(fn [{:keys [db]} [_ handler params route-params]]
|
(fn [{:keys [db]} [_ handler params route-params]]
|
||||||
(println (:user/role (parse-jwt (:user db))))
|
|
||||||
(cond
|
(cond
|
||||||
(and (not= :login handler) (not (:user db)))
|
(and (not= :login handler) (not (:user db)))
|
||||||
{:redirect (bidi/path-for routes/routes :login)
|
{:redirect (bidi/path-for routes/routes :login)
|
||||||
:db (assoc db :active-route :login
|
:db (assoc db :active-route :login
|
||||||
:active-page :login
|
:active-page :login
|
||||||
|
:menu nil
|
||||||
:page-failure nil)}
|
:page-failure nil)}
|
||||||
|
|
||||||
(and (not= "admin" (:user/role (parse-jwt (:user db))))
|
(and (not= "admin" (:user/role (parse-jwt (:user db))))
|
||||||
@@ -156,11 +155,13 @@
|
|||||||
{:redirect (bidi/path-for routes/routes :index)
|
{:redirect (bidi/path-for routes/routes :index)
|
||||||
:db (assoc db :active-route :index
|
:db (assoc db :active-route :index
|
||||||
:active-page :index
|
:active-page :index
|
||||||
|
:menu nil
|
||||||
:page-failure nil)}
|
:page-failure nil)}
|
||||||
:else
|
:else
|
||||||
{:db (-> db
|
{:db (-> db
|
||||||
(assoc :active-route handler
|
(assoc :active-route handler
|
||||||
:page-failure nil
|
:page-failure nil
|
||||||
|
:menu nil
|
||||||
:query-params params
|
:query-params params
|
||||||
:route-params route-params)
|
:route-params route-params)
|
||||||
(auto-ap.views.pages.data-page/dispose-all))})))
|
(auto-ap.views.pages.data-page/dispose-all))})))
|
||||||
|
|||||||
@@ -1,7 +0,0 @@
|
|||||||
(ns auto-ap.events.admin.reminders
|
|
||||||
(:require [re-frame.core :as re-frame]
|
|
||||||
[auto-ap.db :as db]
|
|
||||||
[auto-ap.routes :as routes]
|
|
||||||
[auto-ap.effects :as effects]))
|
|
||||||
|
|
||||||
|
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
(:require [re-frame.core :as re-frame]
|
(:require [re-frame.core :as re-frame]
|
||||||
[re-frame.interceptor :as i]
|
[re-frame.interceptor :as i]
|
||||||
[auto-ap.status :as status]
|
[auto-ap.status :as status]
|
||||||
[auto-ap.views.utils :refer [dispatch-event bind-field]]
|
[auto-ap.views.utils :refer [dispatch-event]]
|
||||||
[malli.core :as m]))
|
[malli.core :as m]))
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,14 +1,12 @@
|
|||||||
(ns auto-ap.forms.builder
|
(ns auto-ap.forms.builder
|
||||||
(:require
|
(:require
|
||||||
[auto-ap.views.utils :refer [bind-field]]
|
|
||||||
[re-frame.core :as re-frame]
|
[re-frame.core :as re-frame]
|
||||||
[react :as react]
|
[react :as react]
|
||||||
[reagent.core :as r]
|
[reagent.core :as r]
|
||||||
[auto-ap.forms :as forms]
|
[auto-ap.forms :as forms]
|
||||||
[auto-ap.status :as status]
|
[auto-ap.status :as status]
|
||||||
[malli.core :as m]
|
[malli.core :as m]
|
||||||
[malli.error :as me]
|
[malli.error :as me]))
|
||||||
[clojure.string :as str]))
|
|
||||||
|
|
||||||
(defonce ^js/React.Context form-context (react/createContext "default"))
|
(defonce ^js/React.Context form-context (react/createContext "default"))
|
||||||
(def ^js/React.Provider Provider (. form-context -Provider))
|
(def ^js/React.Provider Provider (. form-context -Provider))
|
||||||
@@ -119,28 +117,6 @@
|
|||||||
(into [:<>]
|
(into [:<>]
|
||||||
(r/children (r/current-component)))))))))
|
(r/children (r/current-component)))))))))
|
||||||
|
|
||||||
(defn raw-field []
|
|
||||||
(let [[child] (r/children (r/current-component))]
|
|
||||||
[:> Consumer {}
|
|
||||||
(fn [consume-form]
|
|
||||||
(r/as-element
|
|
||||||
[:> FormScopeConsumer {}
|
|
||||||
(fn [form-scope]
|
|
||||||
(r/as-element
|
|
||||||
[bind-field (-> child
|
|
||||||
(update-in [1 :field] (fn [f]
|
|
||||||
(cond
|
|
||||||
(sequential? f)
|
|
||||||
(into form-scope f)
|
|
||||||
|
|
||||||
f
|
|
||||||
(conj form-scope f)
|
|
||||||
|
|
||||||
:else
|
|
||||||
nil)))
|
|
||||||
|
|
||||||
(assoc-in [1 :subscription] (aget consume-form "data"))
|
|
||||||
(assoc-in [1 :event] (aget consume-form "change-event")))]))]))]))
|
|
||||||
|
|
||||||
(defn change-handler [path re-frame-change-event event-or-value]
|
(defn change-handler [path re-frame-change-event event-or-value]
|
||||||
(re-frame/dispatch (-> re-frame-change-event
|
(re-frame/dispatch (-> re-frame-change-event
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
(ns auto-ap.views.components.address
|
(ns auto-ap.views.components.address
|
||||||
(:require [auto-ap.entities.address :as address]
|
(:require
|
||||||
[auto-ap.views.utils :refer [dispatch-value-change dispatch-event bind-field horizontal-field]]
|
[auto-ap.entities.address :as address]
|
||||||
[auto-ap.forms.builder :as form-builder]
|
[auto-ap.forms.builder :as form-builder]
|
||||||
[auto-ap.views.components.level :as level]))
|
[auto-ap.views.components.level :as level]))
|
||||||
|
|
||||||
(defn address2-field [{:keys [value on-change]}]
|
(defn address2-field [{:keys [value on-change]}]
|
||||||
[form-builder/virtual-builder {:value (or value {})
|
[form-builder/virtual-builder {:value (or value {})
|
||||||
|
|||||||
@@ -1,15 +1,11 @@
|
|||||||
(ns auto-ap.views.components.admin.side-bar
|
(ns auto-ap.views.components.admin.side-bar
|
||||||
(:require [re-frame.core :as re-frame]
|
(:require
|
||||||
[reagent.core :as r]
|
[auto-ap.routes :as routes]
|
||||||
[clojure.string :as str]
|
[auto-ap.subs :as subs]
|
||||||
[clojure.spec.alpha :as s]
|
[auto-ap.views.utils :refer [active-when]]
|
||||||
[cljs-time.core :as c]
|
[bidi.bidi :as bidi]
|
||||||
[goog.string :as gstring]
|
[re-frame.core :as re-frame]
|
||||||
[bidi.bidi :as bidi]
|
[reagent.core :as r]))
|
||||||
[auto-ap.routes :as routes]
|
|
||||||
[auto-ap.views.utils :refer [active-when dispatch-event bind-field horizontal-field date->str str->date pretty standard]]
|
|
||||||
[auto-ap.subs :as subs]
|
|
||||||
[auto-ap.events :as events]))
|
|
||||||
|
|
||||||
(defn admin-side-bar [params ]
|
(defn admin-side-bar [params ]
|
||||||
(let [ap @(re-frame/subscribe [::subs/active-page])]
|
(let [ap @(re-frame/subscribe [::subs/active-page])]
|
||||||
@@ -59,14 +55,6 @@
|
|||||||
|
|
||||||
|
|
||||||
[:ul ]]
|
[:ul ]]
|
||||||
[:p.menu-label "History"]
|
|
||||||
[:ul.menu-list
|
|
||||||
[:li.menu-item
|
|
||||||
[:a {:href (bidi/path-for routes/routes :admin-reminders) , :class (str "item" (active-when ap = :admin-reminders))}
|
|
||||||
[:span {:class "icon"}
|
|
||||||
[:i {:class "fa fa-star-o"}]]
|
|
||||||
|
|
||||||
[:span {:class "name"} "Reminders"]]]]
|
|
||||||
[:p.menu-label "Import"]
|
[:p.menu-label "Import"]
|
||||||
[:ul.menu-list
|
[:ul.menu-list
|
||||||
[:li.menu-item
|
[:li.menu-item
|
||||||
|
|||||||
@@ -10,11 +10,9 @@
|
|||||||
[auto-ap.views.components.percentage-field :refer [percentage-field]]
|
[auto-ap.views.components.percentage-field :refer [percentage-field]]
|
||||||
[auto-ap.views.components.typeahead.vendor
|
[auto-ap.views.components.typeahead.vendor
|
||||||
:refer [search-backed-typeahead]]
|
:refer [search-backed-typeahead]]
|
||||||
[auto-ap.views.utils :refer [->$ bind-field dispatch-event appearing-group]]
|
[auto-ap.views.utils :refer [->$ appearing-group]]
|
||||||
[clojure.string :as str]
|
|
||||||
[goog.string :as gstring]
|
[goog.string :as gstring]
|
||||||
[malli.core :as m]
|
[malli.core :as m]))
|
||||||
[re-frame.core :as re-frame]))
|
|
||||||
|
|
||||||
(defn can-replace-with-default? [accounts]
|
(defn can-replace-with-default? [accounts]
|
||||||
(and (or (not (seq accounts))
|
(and (or (not (seq accounts))
|
||||||
@@ -56,27 +54,6 @@
|
|||||||
|
|
||||||
;; EVENTS
|
;; EVENTS
|
||||||
|
|
||||||
(re-frame/reg-event-fx
|
|
||||||
::add-expense-account
|
|
||||||
(fn [_ [_ event expense-accounts locations]]
|
|
||||||
{:dispatch (conj event (conj expense-accounts
|
|
||||||
{:amount 0 :id (str "new-" (random-uuid))
|
|
||||||
:amount-mode "%"
|
|
||||||
:amount-percentage 0
|
|
||||||
:location (if (= 1 (count locations))
|
|
||||||
(first locations)
|
|
||||||
nil)}))}))
|
|
||||||
|
|
||||||
(re-frame/reg-event-fx
|
|
||||||
::remove-expense-account
|
|
||||||
(fn [_ [_ event expense-accounts id]]
|
|
||||||
{:dispatch (conj event (transduce (filter
|
|
||||||
(fn [ea]
|
|
||||||
(not= (:id ea) id)) )
|
|
||||||
conj
|
|
||||||
[]
|
|
||||||
expense-accounts))}))
|
|
||||||
|
|
||||||
(defn recalculate-amounts [expense-accounts total]
|
(defn recalculate-amounts [expense-accounts total]
|
||||||
(mapv
|
(mapv
|
||||||
(fn [ea]
|
(fn [ea]
|
||||||
@@ -86,146 +63,8 @@
|
|||||||
(* (/ (js/parseFloat (:amount-percentage ea)) 100.0) total)))))
|
(* (/ (js/parseFloat (:amount-percentage ea)) 100.0) total)))))
|
||||||
expense-accounts))
|
expense-accounts))
|
||||||
|
|
||||||
(re-frame/reg-event-fx
|
|
||||||
::spread-evenly
|
|
||||||
(fn [_ [_ event expense-accounts max-value]]
|
|
||||||
{:dispatch (into event [(recalculate-amounts (mapv
|
|
||||||
(fn [ea]
|
|
||||||
(assoc ea :amount-percentage (js/parseFloat
|
|
||||||
(goog.string/format "%.2f"
|
|
||||||
(* 100 (/ 1 (count expense-accounts)))))))
|
|
||||||
expense-accounts)
|
|
||||||
max-value)])}))
|
|
||||||
(re-frame/reg-event-fx
|
|
||||||
::expense-account-changed
|
|
||||||
(fn [_ [_ event expense-accounts max-value field value]]
|
|
||||||
(let [updated-accounts (cond-> expense-accounts
|
|
||||||
true (assoc-in field value)
|
|
||||||
(= (list :account) (drop 1 field)) (assoc-in [(first field) :location] nil)
|
|
||||||
|
|
||||||
(= (list :amount-percentage) (drop 1 field)) (assoc-in [(first field) :amount]
|
|
||||||
(js/parseFloat
|
|
||||||
(goog.string/format "%.2f"
|
|
||||||
(* (/ (cond-> value
|
|
||||||
(not (float? value)) (js/parseFloat )) 100.0)
|
|
||||||
(cond-> max-value
|
|
||||||
(not (float? max-value)) (js/parseFloat)))))))
|
|
||||||
updated-accounts (if-let [location (get-in updated-accounts [(first field) :account :location])]
|
|
||||||
(assoc-in updated-accounts [(first field) :location] location)
|
|
||||||
updated-accounts)]
|
|
||||||
{:dispatch (into event [updated-accounts])})))
|
|
||||||
|
|
||||||
|
|
||||||
;; VIEWS
|
;; VIEWS
|
||||||
(defn expense-accounts-field [{expense-accounts :value client :client max-value :max locations :locations event :event descriptor :descriptor disabled :disabled percentage-only? :percentage-only? :or {percentage-only? false}}]
|
|
||||||
[:div
|
|
||||||
[:div.columns
|
|
||||||
[:div.column
|
|
||||||
[:h1.subtitle.is-4.is-inline (str/capitalize descriptor) "s"]
|
|
||||||
(when-not percentage-only?
|
|
||||||
[:p.help "Remaining" (->$ (- max-value (reduce + 0 (map (comp js/parseFloat :amount) expense-accounts))))])]
|
|
||||||
[:div.column.is-narrow
|
|
||||||
(when-not disabled
|
|
||||||
[:p.buttons
|
|
||||||
[:a.button {:on-click (dispatch-event [::spread-evenly event expense-accounts max-value])} "Spread evenly"]
|
|
||||||
[:a.button {:on-click (dispatch-event [::add-expense-account event expense-accounts locations])} "Add"]])]]
|
|
||||||
|
|
||||||
(for [[index {:keys [account id location amount amount-percentage amount-mode] :as expense-account}] (map vector (range) expense-accounts)]
|
|
||||||
^{:key id}
|
|
||||||
[:div.box
|
|
||||||
[:div.columns
|
|
||||||
[:div.column
|
|
||||||
[:h1.subtitle.is-6 (cond (and account (not percentage-only?))
|
|
||||||
(str (:name account) " - "
|
|
||||||
location ": "
|
|
||||||
(gstring/format "$%.2f" (or amount 0) ))
|
|
||||||
|
|
||||||
account
|
|
||||||
(str (:name account) " - "
|
|
||||||
location ": %"
|
|
||||||
amount-percentage)
|
|
||||||
|
|
||||||
:else
|
|
||||||
[:i "New " descriptor])]]
|
|
||||||
[:div.column.is-narrow
|
|
||||||
(when-not disabled
|
|
||||||
[:a.delete {:on-click (dispatch-event [::remove-expense-account event expense-accounts id])}])]]
|
|
||||||
|
|
||||||
[:div.field
|
|
||||||
[:div.columns
|
|
||||||
[:div.column
|
|
||||||
[:p.help "Account"]
|
|
||||||
[:div.control.is-fullwidth
|
|
||||||
[bind-field
|
|
||||||
^{:key (:id client)}
|
|
||||||
[search-backed-typeahead {:search-query (fn [i]
|
|
||||||
[:search_account
|
|
||||||
{:query i
|
|
||||||
:client-id (:id client)}
|
|
||||||
[:name :id :location]])
|
|
||||||
:type "typeahead-v3"
|
|
||||||
:field [index :account]
|
|
||||||
|
|
||||||
:disabled disabled
|
|
||||||
:event [::expense-account-changed event expense-accounts max-value]
|
|
||||||
:subscription expense-accounts}]]]]
|
|
||||||
[:div.column.is-narrow
|
|
||||||
[:p.help "Location"]
|
|
||||||
[:div.control
|
|
||||||
(if-let [forced-location (:location account)]
|
|
||||||
[:div.select
|
|
||||||
[:select {:disabled "disabled" :style {:width "5em"} :value forced-location} [:option {:value forced-location} forced-location]]]
|
|
||||||
[:div.select
|
|
||||||
[bind-field
|
|
||||||
[:select {:type "select"
|
|
||||||
:disabled (boolean (or (:location account)
|
|
||||||
disabled))
|
|
||||||
:style {:width "5em"}
|
|
||||||
:field [index :location]
|
|
||||||
:allow-nil? true
|
|
||||||
:spec (set locations)
|
|
||||||
:event [::expense-account-changed event expense-accounts max-value]
|
|
||||||
:subscription expense-accounts}
|
|
||||||
(map (fn [l] ^{:key l} [:option {:value l} l]) locations)]]])]]]]
|
|
||||||
|
|
||||||
[:div.field
|
|
||||||
[:p.help "Amount"]
|
|
||||||
[:div.control
|
|
||||||
[:div.field.has-addons.is-extended
|
|
||||||
[:p.control [:span.select
|
|
||||||
[bind-field
|
|
||||||
[:select {:type "select"
|
|
||||||
:disabled (or disabled percentage-only?)
|
|
||||||
:field [index :amount-mode]
|
|
||||||
:allow-nil? false
|
|
||||||
:event [::expense-account-changed event expense-accounts max-value]
|
|
||||||
:subscription expense-accounts}
|
|
||||||
[:option "$"]
|
|
||||||
[:option "%"]]]]]
|
|
||||||
[:p.control
|
|
||||||
(if (= "$" amount-mode)
|
|
||||||
[bind-field
|
|
||||||
[:input.input {:type "number"
|
|
||||||
:field [index :amount]
|
|
||||||
:style {:text-align "right" :width "7em"}
|
|
||||||
:event [::expense-account-changed event expense-accounts max-value]
|
|
||||||
:disabled disabled
|
|
||||||
:subscription expense-accounts
|
|
||||||
:precision 2
|
|
||||||
:value (get-in expense-account [:amount])
|
|
||||||
:max max-value
|
|
||||||
:step "0.01"}]]
|
|
||||||
[bind-field
|
|
||||||
[:input.input {:type "number"
|
|
||||||
:field [index :amount-percentage]
|
|
||||||
:style {:text-align "right" :width "7em"}
|
|
||||||
:disabled disabled
|
|
||||||
:event [::expense-account-changed event expense-accounts max-value]
|
|
||||||
:precision 2
|
|
||||||
:subscription expense-accounts
|
|
||||||
:value (get-in expense-account [:amount-percentage])
|
|
||||||
:max "100"
|
|
||||||
:step "0.01"}]])]]]]])])
|
|
||||||
|
|
||||||
(def schema (m/schema [:sequential [:map
|
(def schema (m/schema [:sequential [:map
|
||||||
[:id :string]
|
[:id :string]
|
||||||
|
|||||||
@@ -3,44 +3,53 @@
|
|||||||
[auto-ap.events :as events]
|
[auto-ap.events :as events]
|
||||||
[auto-ap.routes :as routes]
|
[auto-ap.routes :as routes]
|
||||||
[auto-ap.subs :as subs]
|
[auto-ap.subs :as subs]
|
||||||
[auto-ap.views.components.dropdown :refer [drop-down drop-down-contents]]
|
|
||||||
[auto-ap.views.components.modal :as modal]
|
[auto-ap.views.components.modal :as modal]
|
||||||
[auto-ap.views.components.vendor-dialog :as vendor-dialog]
|
[auto-ap.views.components.vendor-dialog :as vendor-dialog]
|
||||||
[auto-ap.views.utils
|
[auto-ap.views.utils
|
||||||
:refer [active-when appearing bind-field dispatch-event dispatch-event-with-propagation login-url]]
|
:refer [active-when
|
||||||
|
appearing
|
||||||
|
dispatch-event-with-propagation
|
||||||
|
login-url]]
|
||||||
[bidi.bidi :as bidi]
|
[bidi.bidi :as bidi]
|
||||||
[clojure.string :as str]
|
[clojure.string :as str]
|
||||||
[re-frame.core :as re-frame]
|
[re-frame.core :as re-frame]
|
||||||
[reagent.core :as r]))
|
[reagent.core :as r]
|
||||||
|
[auto-ap.forms.builder :as form-builder]
|
||||||
|
[vimsical.re-frame.cofx.inject :as inject]
|
||||||
|
[auto-ap.forms :as forms]))
|
||||||
|
|
||||||
(defn navbar-drop-down-contents [{:keys [id]} children ]
|
(defn navbar-drop-down [{:keys [ class]} _]
|
||||||
(let [toggle-fn (fn [] (re-frame/dispatch [::events/toggle-menu id]))]
|
(let [!child (r/atom nil)]
|
||||||
(r/create-class {:component-did-mount (fn [] (.addEventListener js/document "click" toggle-fn))
|
(r/create-class
|
||||||
:component-will-unmount (fn [] (.removeEventListener js/document "click" toggle-fn))
|
{:reagent-render (fn [{:keys [header id]} child]
|
||||||
:reagent-render
|
(let [menu-active? @(re-frame/subscribe [::subs/menu-active? id])]
|
||||||
(fn [children]
|
[:div { :class (str "navbar-item has-dropdown " (when menu-active? "is-active " ) " " class)
|
||||||
children)})))
|
:ref (fn [n]
|
||||||
|
(reset! !child n))
|
||||||
(defn navbar-drop-down [{:keys [ header id class]} child]
|
:tab-index 0
|
||||||
(r/create-class
|
:onBlur (fn [e]
|
||||||
{:reagent-render (fn [{:keys [header id]} child]
|
(js/setTimeout (fn []
|
||||||
(let [menu-active? @(re-frame/subscribe [::subs/menu-active? id])]
|
(println @!child)
|
||||||
[:div { :class (str "navbar-item has-dropdown " (when menu-active? "is-active " ) " " class)}
|
(println (.-activeElement js/document))
|
||||||
[:a {:class "navbar-link login" :on-click (fn [e]
|
(when-not (.contains @!child (.-activeElement js/document))
|
||||||
(.preventDefault e)
|
(re-frame/dispatch [::events/toggle-menu id])))
|
||||||
(.stopPropagation e)
|
2))
|
||||||
(re-frame/dispatch [::events/toggle-menu id])
|
}
|
||||||
true)} header]
|
[:a {:class "navbar-link login" :on-click (fn [e]
|
||||||
[appearing {:visible? menu-active? :enter-class "appear" :exit-class "disappear" :timeout 200}
|
(.preventDefault e)
|
||||||
[:div {:class "navbar-dropdown"}
|
(.stopPropagation e)
|
||||||
[navbar-drop-down-contents {:id id}
|
(re-frame/dispatch [::events/toggle-menu id])
|
||||||
[:div child]]]]]))}))
|
true)} header]
|
||||||
|
[appearing {:visible? menu-active? :enter-class "appear" :exit-class "disappear" :timeout 200}
|
||||||
|
[:div {:class "navbar-dropdown"}
|
||||||
|
[:div child]]]]))})))
|
||||||
|
|
||||||
(defn login-dropdown []
|
(defn login-dropdown []
|
||||||
(let [user (re-frame/subscribe [::subs/user])]
|
(let [user (re-frame/subscribe [::subs/user])]
|
||||||
(if @user
|
(if @user
|
||||||
[navbar-drop-down {:header [:span [:span.icon [:i.fa.fa-user] ]
|
[navbar-drop-down {:header [:span [:span.icon [:i.fa.fa-user] ]
|
||||||
[:span (:user/name @user)]] :id ::account}
|
[:span (:user/name @user)]]
|
||||||
|
:id ::account}
|
||||||
[:div
|
[:div
|
||||||
[:a {:class "navbar-item"
|
[:a {:class "navbar-item"
|
||||||
:href (bidi/path-for routes/routes :reports)} "My company"]
|
:href (bidi/path-for routes/routes :reports)} "My company"]
|
||||||
@@ -60,8 +69,8 @@
|
|||||||
(re-frame/reg-sub
|
(re-frame/reg-sub
|
||||||
::matching-clients
|
::matching-clients
|
||||||
:<- [::subs/clients]
|
:<- [::subs/clients]
|
||||||
:<- [::client-search]
|
:<- [::forms/form ::client-search]
|
||||||
(fn [[clients {client-search :value}]]
|
(fn [[clients {{client-search :value} :data}]]
|
||||||
(if (empty? client-search)
|
(if (empty? client-search)
|
||||||
clients
|
clients
|
||||||
(if-let [exact-match (first (filter
|
(if-let [exact-match (first (filter
|
||||||
@@ -76,21 +85,46 @@
|
|||||||
(str/includes? (str/lower-case (:name client)) (str/lower-case client-search))))
|
(str/includes? (str/lower-case (:name client)) (str/lower-case client-search))))
|
||||||
clients)))))
|
clients)))))
|
||||||
|
|
||||||
(re-frame/reg-event-db
|
|
||||||
::client-search-changed
|
(re-frame/reg-event-fx
|
||||||
[(re-frame/path [::client-search])]
|
::client-searched
|
||||||
(fn [client-search [_ path value]]
|
[(re-frame/inject-cofx ::inject/sub [::matching-clients])]
|
||||||
(assoc-in client-search path value)))
|
(fn [{::keys [matching-clients]}]
|
||||||
|
{:dispatch-n [[::events/swap-client (first matching-clients)]
|
||||||
|
[::events/toggle-menu ::select-client]]}))
|
||||||
|
|
||||||
|
(defn client-dropdown []
|
||||||
|
(let [client (re-frame/subscribe [::subs/client])
|
||||||
|
matching-clients @(re-frame/subscribe [::matching-clients])]
|
||||||
|
|
||||||
|
[navbar-drop-down {:header (str "Company: " (if @client (:name @client)
|
||||||
|
"All"))
|
||||||
|
:id ::select-client}
|
||||||
|
[:div
|
||||||
|
[:a {:class "navbar-item"
|
||||||
|
:on-click (fn []
|
||||||
|
(re-frame/dispatch [::events/toggle-menu ::select-client])
|
||||||
|
(re-frame/dispatch [::forms/form-closing ::client-search])
|
||||||
|
(re-frame/dispatch [::events/swap-client nil]))} "All" ]
|
||||||
|
[:hr {:class "navbar-divider"}]
|
||||||
|
[form-builder/builder {:id ::client-search
|
||||||
|
:submit-event [::client-searched]}
|
||||||
|
[form-builder/raw-field-v2 {:field :value}
|
||||||
|
[:input.input.navbar-item {:placeholder "Company name"
|
||||||
|
:auto-focus true}]]]
|
||||||
|
(for [{:keys [name id] :as client} (take 8 matching-clients)]
|
||||||
|
^{:key id }
|
||||||
|
[:a {:class "navbar-item"
|
||||||
|
:on-click (fn []
|
||||||
|
(re-frame/dispatch [::events/toggle-menu ::select-client])
|
||||||
|
(re-frame/dispatch [::events/swap-client client]))
|
||||||
|
} name])]]))
|
||||||
|
|
||||||
(defn navbar [ap]
|
(defn navbar [ap]
|
||||||
(let [navbar-menu-shown? (r/atom false)]
|
(let [navbar-menu-shown? (r/atom false)]
|
||||||
(fn [ap]
|
(fn [ap]
|
||||||
(let [user (re-frame/subscribe [::subs/user])
|
(let [user (re-frame/subscribe [::subs/user])
|
||||||
client (re-frame/subscribe [::subs/client])
|
clients (re-frame/subscribe [::subs/clients])
|
||||||
clients (re-frame/subscribe [::subs/clients])
|
|
||||||
matching-clients @(re-frame/subscribe [::matching-clients])
|
|
||||||
menu (re-frame/subscribe [::subs/menu])
|
|
||||||
client-search @(re-frame/subscribe [::client-search])
|
|
||||||
is-initial-loading @(re-frame/subscribe [::subs/is-initial-loading?])]
|
is-initial-loading @(re-frame/subscribe [::subs/is-initial-loading?])]
|
||||||
[:nav {:class "navbar has-shadow is-fixed-top is-grey"}
|
[:nav {:class "navbar has-shadow is-fixed-top is-grey"}
|
||||||
|
|
||||||
@@ -133,33 +167,8 @@
|
|||||||
[:div.navbar-end
|
[:div.navbar-end
|
||||||
|
|
||||||
(when (> (count @clients) 1)
|
(when (> (count @clients) 1)
|
||||||
[navbar-drop-down {:header (str "Company: " (if @client (:name @client)
|
[client-dropdown]
|
||||||
"All"))
|
)])]
|
||||||
:id ::select-client}
|
|
||||||
[:div
|
|
||||||
[:a {:class "navbar-item"
|
|
||||||
:on-click (fn []
|
|
||||||
(re-frame/dispatch [::events/swap-client nil]))} "All" ]
|
|
||||||
[:hr {:class "navbar-divider"}]
|
|
||||||
[bind-field
|
|
||||||
[:input.input.navbar-item {:placeholder "Company name"
|
|
||||||
:auto-focus true
|
|
||||||
:field [:value]
|
|
||||||
:on-key-up (fn [k]
|
|
||||||
(when (= 13 (.-which k))
|
|
||||||
(do
|
|
||||||
(re-frame/dispatch [::events/swap-client (first matching-clients)])
|
|
||||||
(re-frame/dispatch [::events/toggle-menu ::select-client])
|
|
||||||
(re-frame/dispatch [::client-search-changed [:value] nil])))
|
|
||||||
)
|
|
||||||
:event [::client-search-changed]
|
|
||||||
:subscription client-search}]]
|
|
||||||
(for [{:keys [name id] :as client} matching-clients]
|
|
||||||
^{:key id }
|
|
||||||
[:a {:class "navbar-item"
|
|
||||||
:on-click (fn []
|
|
||||||
(re-frame/dispatch [::events/swap-client client]))
|
|
||||||
} name])]])])]
|
|
||||||
(when-not is-initial-loading
|
(when-not is-initial-loading
|
||||||
[login-dropdown])]
|
[login-dropdown])]
|
||||||
|
|
||||||
@@ -167,11 +176,7 @@
|
|||||||
]))))
|
]))))
|
||||||
|
|
||||||
|
|
||||||
(defn footer []
|
|
||||||
[:footer {:style {:padding "1em"}}
|
|
||||||
[:div {:class "content has-text-centered"}
|
|
||||||
[:p
|
|
||||||
[:strong "Integreat"] ]]])
|
|
||||||
|
|
||||||
(defn appearing-side-bar [{:keys [visible?]} ]
|
(defn appearing-side-bar [{:keys [visible?]} ]
|
||||||
[appearing {:visible? visible? :enter-class "slide-in-right" :exit-class "slide-out-right" :timeout 500}
|
[appearing {:visible? visible? :enter-class "slide-in-right" :exit-class "slide-out-right" :timeout 500}
|
||||||
@@ -179,7 +184,7 @@
|
|||||||
(into [:div.sub-main {} ]
|
(into [:div.sub-main {} ]
|
||||||
(r/children (r/current-component)))]])
|
(r/children (r/current-component)))]])
|
||||||
|
|
||||||
(defn side-bar-layout [{:keys [side-bar main ap bottom right-side-bar]}]
|
(defn side-bar-layout [{:keys [side-bar main bottom right-side-bar]}]
|
||||||
(let [ap @(re-frame/subscribe [::subs/active-page])
|
(let [ap @(re-frame/subscribe [::subs/active-page])
|
||||||
client @(re-frame/subscribe [::subs/client])]
|
client @(re-frame/subscribe [::subs/client])]
|
||||||
[:div
|
[:div
|
||||||
@@ -200,7 +205,6 @@
|
|||||||
(when right-side-bar
|
(when right-side-bar
|
||||||
right-side-bar)
|
right-side-bar)
|
||||||
]
|
]
|
||||||
#_[footer]
|
|
||||||
[:div
|
[:div
|
||||||
bottom]
|
bottom]
|
||||||
[:div#dz-hidden]]))
|
[:div#dz-hidden]]))
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
;; TODO just embrace the fact that it will need to be remounted, and use index based keys
|
;; TODO just embrace the fact that it will need to be remounted, and use index based keys
|
||||||
(defn multi-field-v2-internal [{:keys [template key-fn allow-change? disable-new? disable-remove? schema on-change disabled new-text] prop-value :value :as props} ]
|
(defn multi-field-v2-internal [{:keys [template key-fn allow-change? disable-new? disable-remove? schema on-change disabled new-text] prop-value :value :as props} ]
|
||||||
(let [prop-value (if (seq prop-value)
|
(let [prop-value (if (seq prop-value)
|
||||||
prop-value
|
(vec prop-value)
|
||||||
[])]
|
[])]
|
||||||
[form-builder/virtual-builder {:value prop-value
|
[form-builder/virtual-builder {:value prop-value
|
||||||
:schema schema
|
:schema schema
|
||||||
@@ -21,21 +21,18 @@
|
|||||||
[:div {:style {:margin-bottom "0.25em"}}
|
[:div {:style {:margin-bottom "0.25em"}}
|
||||||
(into [(if key-fn
|
(into [(if key-fn
|
||||||
appearing-group
|
appearing-group
|
||||||
[:<>])]
|
:<>)]
|
||||||
(for [[i override] (map vector (range) prop-value)
|
(for [[i override] (map vector (range) prop-value)
|
||||||
:let [extant? (if key-fn
|
:let [extant? (if key-fn
|
||||||
(boolean (key-fn override))
|
(boolean (key-fn override))
|
||||||
true)
|
true)
|
||||||
is-disabled? (boolean (and (= false allow-change?)
|
is-disabled? (boolean (and (= false allow-change?)
|
||||||
extant?))]]
|
extant?))
|
||||||
|
key (or (when key-fn (key-fn override))
|
||||||
^{:key (or (when key-fn (key-fn override))
|
(::key override)
|
||||||
(::key override)
|
i)]]
|
||||||
i)}
|
^{:key key}
|
||||||
[form-builder/with-scope {:scope [i]}
|
[form-builder/with-scope {:scope [i]}
|
||||||
^{:key (or (when key-fn (key-fn override))
|
|
||||||
(::key override)
|
|
||||||
i)}
|
|
||||||
[:div.level {:style {:margin-bottom "0.25em"}}
|
[:div.level {:style {:margin-bottom "0.25em"}}
|
||||||
[:div.level-left {:style {:padding "0.5em 1em"}
|
[:div.level-left {:style {:padding "0.5em 1em"}
|
||||||
:class (when-not extant?
|
:class (when-not extant?
|
||||||
@@ -44,9 +41,9 @@
|
|||||||
(template override)
|
(template override)
|
||||||
template)]
|
template)]
|
||||||
[:fieldset.level-left {:disabled is-disabled?
|
[:fieldset.level-left {:disabled is-disabled?
|
||||||
:style {:padding "0.5em 1em"}
|
:style {:padding "0.5em 1em"}
|
||||||
:class (when-not extant?
|
:class (when-not extant?
|
||||||
"has-background-info-light")}
|
"has-background-info-light")}
|
||||||
(for [[idx template] (map vector (range ) template)]
|
(for [[idx template] (map vector (range ) template)]
|
||||||
^{:key idx}
|
^{:key idx}
|
||||||
[:div.level-item
|
[:div.level-item
|
||||||
@@ -67,6 +64,7 @@
|
|||||||
[:button.button.is-outline
|
[:button.button.is-outline
|
||||||
{:type "button"
|
{:type "button"
|
||||||
:on-click (fn [e]
|
:on-click (fn [e]
|
||||||
|
(println "ADDING" prop-value)
|
||||||
(on-change (conj prop-value {::key (random-uuid)}))
|
(on-change (conj prop-value {::key (random-uuid)}))
|
||||||
(.stopPropagation e)
|
(.stopPropagation e)
|
||||||
(.preventDefault e))}
|
(.preventDefault e))}
|
||||||
|
|||||||
@@ -1,193 +0,0 @@
|
|||||||
(ns auto-ap.views.pages.admin.reminders
|
|
||||||
(:require-macros [cljs.core.async.macros :refer [go]])
|
|
||||||
(:require [re-frame.core :as re-frame]
|
|
||||||
[auto-ap.views.components.paginator :refer [paginator]]
|
|
||||||
[auto-ap.views.components.sorter :refer [sorted-column]]
|
|
||||||
[auto-ap.entities.vendors :as entity]
|
|
||||||
[reagent.core :as reagent]
|
|
||||||
[auto-ap.subs :as subs]
|
|
||||||
[auto-ap.views.utils :refer [login-url dispatch-value-change dispatch-event date-time->str date->str horizontal-field bind-field]]
|
|
||||||
[cljs.reader :as edn]
|
|
||||||
|
|
||||||
[auto-ap.routes :as routes]
|
|
||||||
[bidi.bidi :as bidi]))
|
|
||||||
(re-frame/reg-sub
|
|
||||||
::editing-reminder
|
|
||||||
(fn [db]
|
|
||||||
(::editing-reminder db)))
|
|
||||||
|
|
||||||
(re-frame/reg-sub
|
|
||||||
::reminder-page
|
|
||||||
(fn [db]
|
|
||||||
(::reminder-page db)))
|
|
||||||
|
|
||||||
(re-frame/reg-sub
|
|
||||||
::reminder-params
|
|
||||||
(fn [db]
|
|
||||||
(::reminder-params db)))
|
|
||||||
|
|
||||||
(re-frame/reg-event-db
|
|
||||||
::edit
|
|
||||||
(fn [db [_ which]]
|
|
||||||
(assoc db ::editing-reminder which)))
|
|
||||||
|
|
||||||
(re-frame/reg-event-db
|
|
||||||
::change
|
|
||||||
(fn [db [_ field v]]
|
|
||||||
(assoc-in db (into [::editing-reminder] field) v)))
|
|
||||||
|
|
||||||
(re-frame/reg-event-fx
|
|
||||||
::mounted
|
|
||||||
(fn [{:keys [db]} _]
|
|
||||||
{:db (assoc db ::reminder-params {:start 0})
|
|
||||||
:dispatch [::invalidated]}))
|
|
||||||
|
|
||||||
(re-frame/reg-event-fx
|
|
||||||
::params-changed
|
|
||||||
(fn [{:keys [db]} [_ params]]
|
|
||||||
{:db (update db ::reminder-params merge params)
|
|
||||||
:dispatch [::invalidated]}))
|
|
||||||
|
|
||||||
(re-frame/reg-event-fx
|
|
||||||
::save
|
|
||||||
(fn [{:keys [db]}]
|
|
||||||
(let [edited-reminder (::editing-reminder db)]
|
|
||||||
(println edited-reminder)
|
|
||||||
{:http {:token (:user db)
|
|
||||||
:method :put
|
|
||||||
:body (pr-str (dissoc edited-reminder :sent :scheduled))
|
|
||||||
:headers {"Content-Type" "application/edn"}
|
|
||||||
:uri (str "/api/reminders/" (:id edited-reminder))
|
|
||||||
:on-success [::save-complete]
|
|
||||||
:on-error [::save-error]}})))
|
|
||||||
|
|
||||||
(re-frame/reg-event-fx
|
|
||||||
::save-complete
|
|
||||||
(fn [{:keys [db]}]
|
|
||||||
{:dispatch [::edit nil]}))
|
|
||||||
|
|
||||||
(re-frame/reg-event-fx
|
|
||||||
::save-error
|
|
||||||
(fn [{:keys [db]}]
|
|
||||||
{:dispatch [::change [:error] true]}))
|
|
||||||
|
|
||||||
(re-frame/reg-event-fx
|
|
||||||
::invalidated
|
|
||||||
(fn [{:keys [db]}]
|
|
||||||
{:graphql {:token (:user db)
|
|
||||||
:query-obj {:venia/queries [[:reminder_page
|
|
||||||
(::reminder-params db)
|
|
||||||
|
|
||||||
[[:reminders [:id :email :sent :scheduled :subject :body [:vendor [:name :id]] ]]
|
|
||||||
:total
|
|
||||||
:start
|
|
||||||
:end]]]}
|
|
||||||
|
|
||||||
:on-success [::received]}}))
|
|
||||||
|
|
||||||
|
|
||||||
(re-frame/reg-event-db
|
|
||||||
::received
|
|
||||||
(fn [db [_ reminders]]
|
|
||||||
(assoc db ::reminder-page (first (:reminder-page reminders)))))
|
|
||||||
|
|
||||||
(defn edit-dialog []
|
|
||||||
(let [editing-reminder @(re-frame/subscribe [::editing-reminder])]
|
|
||||||
[:div.modal.is-active
|
|
||||||
[:div.modal-background {:on-click (fn [] (re-frame/dispatch [::edit nil]))}]
|
|
||||||
|
|
||||||
[:div.modal-card
|
|
||||||
[:header.modal-card-head
|
|
||||||
[:p.modal-card-title
|
|
||||||
(str "Reminder for " (:name (:vendor editing-reminder)))]
|
|
||||||
(when (:error editing-reminder)
|
|
||||||
[:span.icon.has-text-danger
|
|
||||||
[:i.fa.fa-exclamation-triangle]])
|
|
||||||
[:button.delete {:on-click (fn [] (re-frame/dispatch [::edit nil]))}]]
|
|
||||||
[:section.modal-card-body
|
|
||||||
[horizontal-field
|
|
||||||
[:label.label "Email"]
|
|
||||||
[:div.control
|
|
||||||
[bind-field
|
|
||||||
[:input.input {:type "text"
|
|
||||||
:field :email
|
|
||||||
:event ::change
|
|
||||||
:subscription editing-reminder}]]]]
|
|
||||||
[horizontal-field
|
|
||||||
[:label.label "Subject"]
|
|
||||||
[:div.control
|
|
||||||
[bind-field
|
|
||||||
[:input.input {:type "text"
|
|
||||||
:field :subject
|
|
||||||
:event ::change
|
|
||||||
:subscription editing-reminder}]]]]
|
|
||||||
|
|
||||||
[horizontal-field
|
|
||||||
[:label.label "Body"]
|
|
||||||
[:div.control
|
|
||||||
|
|
||||||
[bind-field
|
|
||||||
[:textarea.textarea.is-expanded {:type "text"
|
|
||||||
:field :body
|
|
||||||
:event ::change
|
|
||||||
:subscription editing-reminder}]]]]
|
|
||||||
|
|
||||||
(when (:saving? editing-reminder) [:div.is-overlay {:style {"backgroundColor" "rgba(150,150,150, 0.5)"}}])]
|
|
||||||
|
|
||||||
[:footer.modal-card-foot
|
|
||||||
[:button.button.is-primary {:on-click (fn [] (re-frame/dispatch [::save]))
|
|
||||||
#_#_:disabled (when (not (s/valid? ::entity/vendor editing-reminder ))
|
|
||||||
"disabled")}
|
|
||||||
[:span "Save"]
|
|
||||||
(when (:saving? editing-reminder)
|
|
||||||
[:span.icon
|
|
||||||
[:i.fa.fa-spin.fa-spinner]])]]]]))
|
|
||||||
|
|
||||||
(defn reminders-table []
|
|
||||||
(let [{:keys [reminders start end total count]} @(re-frame/subscribe [::reminder-page])
|
|
||||||
{:keys [sort-by asc]} @(re-frame/subscribe [::reminder-params])
|
|
||||||
reminders (or reminders [])]
|
|
||||||
[:div
|
|
||||||
[:div.is-pulled-right
|
|
||||||
[paginator {:start start
|
|
||||||
:end end
|
|
||||||
:total total
|
|
||||||
:count count
|
|
||||||
:on-change (fn [params]
|
|
||||||
(re-frame/dispatch [::params-changed params]))}]]
|
|
||||||
[:table {:class "table", :style {:width "100%"}}
|
|
||||||
[:thead
|
|
||||||
[:tr
|
|
||||||
(for [[sort-key name] [["vendor" "Vendor"]
|
|
||||||
["scheduled" "Scheduled Date"]
|
|
||||||
["sent" "Status"]
|
|
||||||
["email" "Email"]]]
|
|
||||||
^{:key name}
|
|
||||||
[sorted-column {:on-sort (fn [params] (re-frame/dispatch [::params-changed params]))
|
|
||||||
:style {:width "20%" :cursor "pointer"}
|
|
||||||
:sort-key sort-key
|
|
||||||
:sort-by sort-by
|
|
||||||
:asc asc}
|
|
||||||
name])]]
|
|
||||||
[:tbody (for [{:keys [id vendor scheduled sent email ] :as r} reminders]
|
|
||||||
^{:key id}
|
|
||||||
[:tr (when-not sent
|
|
||||||
{:on-click (fn [] (re-frame/dispatch [::edit r])) :style {:cursor "pointer"}})
|
|
||||||
[:td (:name vendor)]
|
|
||||||
[:td (date->str scheduled)]
|
|
||||||
[:td (when sent
|
|
||||||
[:span [:span.icon [:i.fa.fa-check]] "Sent " (date-time->str sent)]) ]
|
|
||||||
[:td email]])]]
|
|
||||||
|
|
||||||
(when @(re-frame/subscribe [::editing-reminder])
|
|
||||||
[edit-dialog])]))
|
|
||||||
|
|
||||||
|
|
||||||
(defn admin-reminders-page []
|
|
||||||
[(with-meta
|
|
||||||
(fn []
|
|
||||||
[:div
|
|
||||||
[:h1.title "Reminders"]
|
|
||||||
[reminders-table]])
|
|
||||||
{:component-did-mount (fn []
|
|
||||||
(re-frame/dispatch [::mounted]))})])
|
|
||||||
@@ -24,18 +24,17 @@
|
|||||||
[:map
|
[:map
|
||||||
[:amount schema/money]]]]]
|
[:amount schema/money]]]]]
|
||||||
[:fn (fn [{:keys [invoices invoice-amounts] :as z}]
|
[:fn (fn [{:keys [invoices invoice-amounts] :as z}]
|
||||||
(println "HERE" z)
|
(if (seq (filter
|
||||||
(when (seq (filter
|
|
||||||
(fn [{:keys [id outstanding-balance]}]
|
(fn [{:keys [id outstanding-balance]}]
|
||||||
(does-amount-exceed-outstanding? (get-in invoice-amounts [id :amount]) outstanding-balance ))
|
(does-amount-exceed-outstanding? (get-in invoice-amounts [id :amount]) outstanding-balance ))
|
||||||
invoices))
|
invoices))
|
||||||
(throw (ex-info "Invalid" {:type ::too-much-invoice}))))]]))
|
(throw (ex-info "Invalid" {:type ::too-much-invoice}))
|
||||||
|
true))]]))
|
||||||
|
|
||||||
(defn form []
|
(defn form []
|
||||||
(let [real-bank-accounts @(re-frame/subscribe [::subs/real-bank-accounts])
|
(let [real-bank-accounts @(re-frame/subscribe [::subs/real-bank-accounts])
|
||||||
{:keys [data]} @(re-frame/subscribe [::forms/form ::form])]
|
{:keys [data]} @(re-frame/subscribe [::forms/form ::form])]
|
||||||
|
|
||||||
(println "TEST?")
|
|
||||||
[form-builder/builder {:submit-event [::try-save]
|
[form-builder/builder {:submit-event [::try-save]
|
||||||
:id ::form
|
:id ::form
|
||||||
:schema advanced-print-schema}
|
:schema advanced-print-schema}
|
||||||
@@ -87,6 +86,7 @@
|
|||||||
::try-save
|
::try-save
|
||||||
[(forms/in-form ::form)]
|
[(forms/in-form ::form)]
|
||||||
(fn [{:keys [db]}]
|
(fn [{:keys [db]}]
|
||||||
|
#_(println (m/explain advanced-print-schema (:data db)))
|
||||||
(if (not (m/validate advanced-print-schema (:data db)))
|
(if (not (m/validate advanced-print-schema (:data db)))
|
||||||
{:dispatch-n [[::status/error ::form [{:message "Please correct any errors and try again"}]]
|
{:dispatch-n [[::status/error ::form [{:message "Please correct any errors and try again"}]]
|
||||||
[::forms/attempted-submit ::form]]}
|
[::forms/attempted-submit ::form]]}
|
||||||
|
|||||||
@@ -375,8 +375,7 @@ NOTE: Please review the transactions we may have question for you here: https://
|
|||||||
:title "Full year"}]]
|
:title "Full year"}]]
|
||||||
[:div
|
[:div
|
||||||
[form-builder/raw-field-v2 {:field :show-advanced?}
|
[form-builder/raw-field-v2 {:field :show-advanced?}
|
||||||
[com/checkbox {:label "Show Advanced"}]
|
[com/checkbox {:label "Show Advanced"}]]]
|
||||||
]]
|
|
||||||
(when (:show-advanced? data)
|
(when (:show-advanced? data)
|
||||||
[form-builder/raw-field-v2 {:field :periods}
|
[form-builder/raw-field-v2 {:field :periods}
|
||||||
[com/multi-field-v2 {:template [[form-builder/raw-field-v2 {:field :start}
|
[com/multi-field-v2 {:template [[form-builder/raw-field-v2 {:field :start}
|
||||||
@@ -479,7 +478,8 @@ NOTE: Please review the transactions we may have question for you here: https://
|
|||||||
:clients (mapv (fn [c] {:client c :id (random-uuid)})
|
:clients (mapv (fn [c] {:client c :id (random-uuid)})
|
||||||
(or (:clients qp)
|
(or (:clients qp)
|
||||||
[(some-> @(re-frame/subscribe [::subs/client]) (select-keys [:name :id]) )]))
|
[(some-> @(re-frame/subscribe [::subs/client]) (select-keys [:name :id]) )]))
|
||||||
:include-deltas false})
|
:include-deltas false
|
||||||
|
:show-advanced? false})
|
||||||
::track/register {:id ::ledger-params
|
::track/register {:id ::ledger-params
|
||||||
:subscription [::data-page/params ::ledger]
|
:subscription [::data-page/params ::ledger]
|
||||||
:event-fn (fn [params] [::ledger-params-change params])}})))
|
:event-fn (fn [params] [::ledger-params-change params])}})))
|
||||||
|
|||||||
@@ -30,7 +30,7 @@
|
|||||||
[(keyword (str "border-" (name b))) "1px solid black"])
|
[(keyword (str "border-" (name b))) "1px solid black"])
|
||||||
)
|
)
|
||||||
(into s))))
|
(into s))))
|
||||||
(:colspan c) (assoc :colspan (:colspan c))
|
(:colspan c) (assoc :col-span (:colspan c))
|
||||||
(:align c) (assoc :align (:align c))
|
(:align c) (assoc :align (:align c))
|
||||||
(= :dollar (:format c)) (assoc :align :right)
|
(= :dollar (:format c)) (assoc :align :right)
|
||||||
(= :percent (:format c)) (assoc :align :right)
|
(= :percent (:format c)) (assoc :align :right)
|
||||||
|
|||||||
Reference in New Issue
Block a user