diff --git a/src/cljs/auto_ap/events.cljs b/src/cljs/auto_ap/events.cljs index 8c58f44c..55a6c480 100644 --- a/src/cljs/auto_ap/events.cljs +++ b/src/cljs/auto_ap/events.cljs @@ -53,9 +53,9 @@ (fn [{:keys [db]} [_ token user]] {:graphql {:token token :query-obj {:venia/queries [[:company - [:id :name [:bank-accounts [:id :number :check-number :name]]]] - [:vendor - [:id :name :default-expense-account]]]} + [:id :name [:bank-accounts [:id :number :check-number :name]]]] + [:vendor + [:id :name :default-expense-account]]]} :on-success [::received-initial]} :db (assoc db :user (assoc user :token token))})) @@ -184,3 +184,38 @@ ::change-form-state (fn [db [_ target value]] (assoc-in db target value))) + +(re-frame/reg-event-db + ::change-nested-form-state + (fn [db [_ form more value]] + (update-in db form + (fn [x] + (assoc-in x more value))))) + +(re-frame/reg-event-fx + ::save-vendor + (fn [{:keys [db]} _] + (let [edited-vendor (get-in db [:user-editing-vendor])] + (if (:id edited-vendor) + {:http {:method :put + :token (:user db) + :body (pr-str edited-vendor) + :headers {"Content-Type" "application/edn"} + :uri (str "/api/vendors/" (:id edited-vendor)) + :on-success [::save-complete] + :on-error [::save-error]}} + + {:http {:method :post + :token (:user db) + :body (pr-str edited-vendor) + :headers {"Content-Type" "application/edn"} + :uri (str "/api/vendors") + :on-success [::save-complete] + :on-error [::save-error]}})))) +(re-frame/reg-event-fx + ::save-complete + (fn [{:keys [db]} [_ vendor]] + {:dispatch [::modal-completed :auto-ap.views.main/user-editing-vendor ] + :db (-> db + (dissoc :user-editing-vendor) + (assoc-in [:vendors (:id vendor)] vendor))})) diff --git a/src/cljs/auto_ap/events/admin/vendors.cljs b/src/cljs/auto_ap/events/admin/vendors.cljs index 7c25f362..84341a71 100644 --- a/src/cljs/auto_ap/events/admin/vendors.cljs +++ b/src/cljs/auto_ap/events/admin/vendors.cljs @@ -5,14 +5,16 @@ [auto-ap.routes :as routes] [auto-ap.effects :as effects] [auto-ap.entities.vendors :as entity] + [auto-ap.events :as events] [bidi.bidi :as bidi])) -(re-frame/reg-event-db +(re-frame/reg-event-fx ::edit - (fn [db [_ vendor-id]] - (assoc-in db [:admin :vendor] - (get (:vendors db) vendor-id)))) + (fn [{:keys [db]} [_ vendor-id]] + {:db (assoc-in db [:admin :vendor] + (get (:vendors db) vendor-id)) + :dispatch [::events/modal-status :auto-ap.views.pages.admin.vendors/admin-vendor {:visible? true}]})) (re-frame/reg-event-db ::new @@ -65,13 +67,14 @@ (-> db (assoc-in [:admin :banner] error)))) -(re-frame/reg-event-db +(re-frame/reg-event-fx ::save-complete - (fn [db [_ vendor]] - (-> db - - (assoc-in [:admin :vendor] nil) - (assoc-in [:vendors (:id vendor)] vendor)))) + (fn [{:keys [db]} [_ vendor]] + {:dispatch [::events/modal-completed :auto-ap.views.pages.admin.vendors/admin-vendor ] + :db (-> db + + (assoc-in [:admin :vendor] nil) + (assoc-in [:vendors (:id vendor)] vendor))})) (re-frame/reg-event-db ::save-error diff --git a/src/cljs/auto_ap/subs.cljs b/src/cljs/auto_ap/subs.cljs index 0e4b627e..af7da345 100644 --- a/src/cljs/auto_ap/subs.cljs +++ b/src/cljs/auto_ap/subs.cljs @@ -46,6 +46,11 @@ (fn [db] (:admin db))) +(re-frame/reg-sub + ::user-editing-vendor + (fn [db] + (-> db :user-editing-vendor))) + (re-frame/reg-sub ::user (fn [db] diff --git a/src/cljs/auto_ap/views/components/vendor_dialog.cljs b/src/cljs/auto_ap/views/components/vendor_dialog.cljs new file mode 100644 index 00000000..91f9cc29 --- /dev/null +++ b/src/cljs/auto_ap/views/components/vendor_dialog.cljs @@ -0,0 +1,159 @@ +(ns auto-ap.views.components.vendor-dialog + (:require [re-frame.core :as re-frame] + [auto-ap.views.utils :refer [dispatch-event horizontal-field bind-field]] + [auto-ap.views.components.modal :refer [action-modal]] + [auto-ap.views.components.address :refer [address-field]] + [auto-ap.views.components.typeahead :refer [typeahead]] + + [auto-ap.expense-accounts :refer [expense-accounts]] + [clojure.spec.alpha :as s] + [auto-ap.entities.vendors :as entity] + [auto-ap.subs :as subs])) + + +(defn vendor-dialog [{:keys [vendor save-event change-event id] {:keys [name]} :vendor}] + (let [companies-by-id @(re-frame/subscribe [::subs/companies-by-id])] + + [action-modal {:id id + :title [:span (if (:id vendor) + (str "Edit " (or name "")) + (str "Add " (or name ""))) + (when (:error vendor) + [:span.icon.has-text-danger + [:i.fa.fa-exclamation-triangle]])] + :action-text "Save" + :save-event save-event} + + [horizontal-field + [:label.label "Name"] + [:div.control + [bind-field + [:input.input {:type "text" + :field :name + :spec ::entity/name + :event change-event + :subscription vendor}]]]] + + [horizontal-field + [:label.label "Code"] + [:div.control + + [bind-field + [:input.input.is-expanded {:type "text" + :field :code + :spec ::entity/code + :event change-event + :subscription vendor}]] + [:p.help "The vendor code is used for invoice parsing. Only one vendor at a time can use a code"]]] + + [:h2.subtitle "Address"] + [address-field {:field [:address] + :event change-event + :subscription vendor}] + + + + [:h2.subtitle "Contact"] + [horizontal-field + [:label.label "Primary"] + [:div.control.has-icons-left + [bind-field + [:input.input.is-expanded {:type "text" + :field :primary-contact + :spec ::entity/primary-contact + :event change-event + :subscription vendor}]] + [:span.icon.is-small.is-left + [:i.fa.fa-user]]] + + [:div.control.has-icons-left + [:span.icon.is-small.is-left + [:i.fa.fa-envelope]] + [bind-field + [:input.input {:type "email" + :field :primary-email + :spec ::entity/primary-email + :event change-event + :subscription vendor}]]] + + [:div.control.has-icons-left + [bind-field + [:input.input {:type "phone" + :field :primary-phone + :spec ::entity/primary-phone + :event change-event + :subscription vendor}]] + [:span.icon.is-small.is-left + [:i.fa.fa-phone]]]] + + [horizontal-field + [:label.label "Secondary"] + [:div.control.has-icons-left + [bind-field + [:input.input.is-expanded {:type "text" + :field :secondary-contact + :spec ::entity/secondary-contact + :event change-event + :subscription vendor}]] + [:span.icon.is-small.is-left + [:i.fa.fa-user]]] + [:div.control.has-icons-left + [:span.icon.is-small.is-left + [:i.fa.fa-envelope]] + [bind-field + [:input.input {:type "email" + :field :secondary-email + :spec ::entity/secondary-email + :event change-event + :subscription vendor}]]] + [:div.control.has-icons-left + [bind-field + [:input.input {:type "phone" + :field :secondary-phone + :spec ::entity/secondary-phone + :event change-event + :subscription vendor}]] + [:span.icon.is-small.is-left + [:i.fa.fa-phone]]]] + + [horizontal-field + [:label.label "Invoice Reminders"] + [:div.control + [:label.radio + [bind-field + [:input {:type "radio" + :name "schedule" + :value "Weekly" + :field :invoice-reminder-schedule + :spec ::entity/invoice-reminder-schedule + :event change-event + :subscription vendor}]] + " Send weekly"] + + [:label.radio + [bind-field + [:input {:type "radio" + :name "schedule" + :value "Never" + :field :invoice-reminder-schedule + :spec ::entity/invoice-reminder-schedule + :event change-event + :subscription vendor}]] + " Never"]]] + + [:h2.subtitle "Expense Accounts"] + [horizontal-field + [:label.label "Default"] + [bind-field + [typeahead {:matches (map (fn [[k v]] [k (:name v)]) expense-accounts) + :type "typeahead" + :field [:default-expense-account] + :spec ::entity/default-expense-account + :event change-event + :subscription vendor}]]] + + + + + + (when (:saving? vendor) [:div.is-overlay {:style {"backgroundColor" "rgba(150,150,150, 0.5)"}}])])) diff --git a/src/cljs/auto_ap/views/main.cljs b/src/cljs/auto_ap/views/main.cljs index 9a0b1611..5b0d422c 100644 --- a/src/cljs/auto_ap/views/main.cljs +++ b/src/cljs/auto_ap/views/main.cljs @@ -5,9 +5,12 @@ [auto-ap.routes :as routes] [auto-ap.subs :as subs] [auto-ap.events :as events] - [auto-ap.views.utils :refer [active-when= login-url]] + [auto-ap.views.utils :refer [active-when= login-url dispatch-event]] [auto-ap.entities.companies :as company] - [auto-ap.views.pages :as pages])) + [auto-ap.views.pages :as pages] + [auto-ap.views.components.vendor-dialog :refer [vendor-dialog]])) + + (defn page->layout [page] ({:login :blank @@ -172,11 +175,11 @@ [:p.menu-label "Accounts Payable"] [:ul.menu-list #_[:li.menu-item - [:a {:href (bidi/path-for routes/routes :import-invoices) , :class (str "item" (active-when= ap :import-invoices))} - [:span {:class "icon"} - [:i {:class "fa fa-star-o"}]] - - [:span {:class "name"} "Upload Invoices"]]] + [:a {:href (bidi/path-for routes/routes :import-invoices) , :class (str "item" (active-when= ap :import-invoices))} + [:span {:class "icon"} + [:i {:class "fa fa-star-o"}]] + + [:span {:class "name"} "Upload Invoices"]]] [:li.menu-item [:a {:href (bidi/path-for routes/routes :unpaid-invoices), :class (str "item" (active-when= ap :unpaid-invoices))} [:span {:class "icon"} @@ -201,9 +204,14 @@ [:i {:class "fa fa-exchange"}]] [:span {:class "name"} "Transactions"]]] - [:ul ]]] + - ] + ] + [:div {:class "compose has-text-centered"} + [:a {:class "button is-danger is-block is-bold" :href (bidi/path-for routes/routes :index) + :on-click (dispatch-event [::events/modal-status ::user-editing-vendor {:visible? true}])} + [:span {:class "compose"} "New Vendor"]]]]] + [:div {:class "column messages hero is-fullheight", :id "message-feed"} ^{:key (str "active-page-" (:name @company))} [:div.inbox-messages @@ -216,7 +224,11 @@ [:p [:a {:class "icon", :href "https://github.com/dansup/bulma-templates"} [:i {:class "fa fa-github"}]]]]]] - [:div#dz-hidden]])) + [:div#dz-hidden] + [vendor-dialog {:vendor @(re-frame/subscribe [::subs/user-editing-vendor]) + :save-event [::events/save-vendor] + :change-event [::events/change-nested-form-state [:user-editing-vendor]] + :id ::user-editing-vendor}]])) (defmethod layout :blank [ap] [:div diff --git a/src/cljs/auto_ap/views/pages/admin/vendors.cljs b/src/cljs/auto_ap/views/pages/admin/vendors.cljs index edb30589..d152090d 100644 --- a/src/cljs/auto_ap/views/pages/admin/vendors.cljs +++ b/src/cljs/auto_ap/views/pages/admin/vendors.cljs @@ -7,6 +7,7 @@ [auto-ap.events.admin.vendors :as events] [auto-ap.entities.vendors :as entity] [auto-ap.views.components.address :refer [address-field]] + [auto-ap.views.components.vendor-dialog :refer [vendor-dialog]] [auto-ap.views.components.modal :refer [modal]] [clojure.spec.alpha :as s] [auto-ap.views.utils :refer [login-url dispatch-value-change dispatch-event bind-field horizontal-field]] @@ -55,7 +56,7 @@ -(defn edit-dialog [] +#_(defn edit-dialog [] (let [editing-vendor (:vendor @(re-frame/subscribe [::subs/admin])) companies-by-id @(re-frame/subscribe [::subs/companies-by-id])] @@ -263,7 +264,9 @@ [:div.is-pulled-right [:a.button.is-primary.is-large {:on-click (dispatch-event [::events/new])} "New vendor"]] - (when editing-vendor - [edit-dialog])])]) + [vendor-dialog {:vendor editing-vendor + :save-event [::events/save] + :change-event ::events/change + :id ::admin-vendor}]])]) {:component-did-mount (fn [] (re-frame/dispatch [::events/mounted]))})])