Files
integreat/src/cljs/auto_ap/views/components/layouts.cljs

232 lines
11 KiB
Clojure

(ns auto-ap.views.components.layouts
(:require
[auto-ap.events :as events]
[auto-ap.forms :as forms]
[auto-ap.forms.builder :as form-builder]
[auto-ap.routes :as routes]
[auto-ap.ssr-routes :as ssr-routes]
[auto-ap.subs :as subs]
[auto-ap.views.components.modal :as modal]
[auto-ap.views.components.search :as search]
[auto-ap.views.components.vendor-dialog :as vendor-dialog]
[auto-ap.views.utils
:refer [active-when appearing dispatch-event-with-propagation login-url]]
[bidi.bidi :as bidi]
[clojure.string :as str]
[re-frame.core :as re-frame]
[reagent.core :as r]
[vimsical.re-frame.cofx.inject :as inject]))
(defn navbar-drop-down [{:keys [ class]} _]
(let [!child (r/atom nil)]
(r/create-class
{:reagent-render (fn [{:keys [header id]} child]
(let [menu-active? @(re-frame/subscribe [::subs/menu-active? id])]
[:div { :class (str "navbar-item has-dropdown " (when menu-active? "is-active " ) " " class)
:ref (fn [n]
(reset! !child n))
:tab-index 0
:onBlur (fn [_]
(js/setTimeout (fn []
(println @!child)
(println (.-activeElement js/document))
(when-not (.contains @!child (.-activeElement js/document))
(re-frame/dispatch [::events/toggle-menu id])))
2))}
[:a {:class "navbar-link login" :on-click (fn [e]
(.preventDefault e)
(.stopPropagation e)
(re-frame/dispatch [::events/toggle-menu id])
true)} header]
[appearing {:visible? menu-active? :enter-class "appear" :exit-class "disappear" :timeout 200}
[:div {:class "navbar-dropdown"}
[:div child]]]]))})))
(defn login-dropdown []
(let [user (re-frame/subscribe [::subs/user])]
(if @user
[navbar-drop-down {:header [:span [:span.icon [:i.fa.fa-user]]
[:span (:user/name @user)]]
:id ::account}
[:div
[:a {:class "navbar-item"
:href (bidi/path-for auto-ap.ssr-routes/only-routes :company)} "My company"]
[:a.dropdown-item {:on-click (dispatch-event-with-propagation [::vendor-dialog/started {}])} "New Vendor"]
[:a.dropdown-item {:on-click (dispatch-event-with-propagation [::vendor-dialog/edit {}])} "Edit Vendor"]
(when (= "admin" (:user/role @user))
[:a {:class "navbar-item" :href (bidi/path-for routes/routes :admin)} "Administration"])
[:hr {:class "navbar-divider"}]
[:a.navbar-item {:on-click (fn [e] (.preventDefault e) (re-frame/dispatch [::events/logout]))} "Logout"]]]
[:a.navbar-item {:href (login-url)} "Login"])))
(re-frame/reg-sub
::client-search
(fn [db]
(::client-search db)))
(re-frame/reg-sub
::matching-clients
:<- [::subs/clients]
:<- [::forms/form ::client-search]
(fn [[clients {{client-search :value} :data}]]
(if (empty? client-search)
clients
(if-let [exact-match (first (filter
(fn [client]
(= (str/lower-case (:code client)) (str/lower-case client-search)))
clients))]
[exact-match]
(filter
(fn [client]
(or
(str/includes? (str/lower-case (:code client)) (str/lower-case client-search))
(str/includes? (str/lower-case (:name client)) (str/lower-case client-search))))
clients)))))
(re-frame/reg-event-fx
::client-searched
[(re-frame/inject-cofx ::inject/sub [::matching-clients])]
(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])
clients @(re-frame/subscribe [::subs/selected-clients])
matching-clients @(re-frame/subscribe [::matching-clients])
user (re-frame/subscribe [::subs/user])]
[navbar-drop-down {:header (str "Company: " (cond @client
(:name @client)
:else
(str (count (or clients [])) " Clients")))
: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 :all]))} "All" ]
(when (= "admin" (:user/role @user))
[: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 :mine]))} "Mine" ])
[: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 []
(let [navbar-menu-shown? (r/atom false)]
(fn [ap]
(let [user (re-frame/subscribe [::subs/user])
clients (re-frame/subscribe [::subs/clients])
is-initial-loading @(re-frame/subscribe [::subs/is-initial-loading?])]
[:nav {:class "navbar has-shadow is-fixed-top is-grey"}
[:div {:class "container"}
[:div {:class "navbar-brand"}
[:a {:class "navbar-item", :href "../"}
[:img {:src "/img/logo.png"}]]
[:div {:class "navbar-burger burger", :data-target "navMenu" :on-click (fn [] (swap! navbar-menu-shown? #(not %)))}
[:span]
[:span]
[:span]]]
[:div.navbar-menu {:id "navMenu" :class (if @navbar-menu-shown?
"is-active"
"")}
(when-not is-initial-loading
[:div.navbar-start
[:a.navbar-item {:class [(active-when ap = :index)]
:href (bidi/path-for routes/routes :index)}
"Home" ]
[:a.navbar-item {:class [(active-when ap #{:unpaid-invoices :paid-invoices})]
:href (bidi/path-for routes/routes :unpaid-invoices)}
"Invoices" ]
[:a.navbar-item {:class [(active-when ap = :payments)]
:href (bidi/path-for routes/routes :payments)}
"Payments" ]
(when (= "admin" (:user/role @user))
[:a.navbar-item {:class [(active-when ap = :sales-orders)]
:href (bidi/path-for routes/routes :sales-orders)}
"POS" ])
[:a.navbar-item {:class [(active-when ap = :transactions)]
:href (bidi/path-for routes/routes :transactions)}
"Transactions" ]
(when (not= "manager" (:user/role @user))
[:a.navbar-item {:class [(active-when ap = :ledger)]
:href (bidi/path-for routes/routes :ledger)}
"Ledger" ])])
(when-not is-initial-loading
[:div.navbar-end
(when (> (count @clients) 1)
[client-dropdown])
])]
(when-not is-initial-loading
[login-dropdown])]
(when (= "admin" (:user/role @user))
[:div {:style {:position "fixed" :top "4px" :right "8px"}}
[search/search-button ]])]))))
(defn appearing-side-bar [{:keys [visible?]} ]
[appearing {:visible? visible? :enter-class "slide-in-right" :exit-class "slide-out-right" :timeout 500}
[:aside {:class "column is-4 aside menu" :style {:height "calc(100vh - 46px)" :overflow "auto"}}
(into [:div.sub-main {} ]
(r/children (r/current-component)))]])
(defn side-bar-layout [{:keys [side-bar main bottom right-side-bar]}]
(let [ap @(re-frame/subscribe [::subs/active-page])
client @(re-frame/subscribe [::subs/client])]
[:div
[modal/global-modal]
[navbar ap]
[:div {:class "columns has-shadow", :style {:margin-bottom "0px" :height "calc(100vh - 46px)" } :id "mail-app" }
[:aside {:class "column aside menu is-2 " }
[:div.main.left-nav
[:div side-bar
]]]
[:div {:class "column messages hero " :style { :overflow "auto" }, :id "message-feed"}
^{:key (str "active-page-" (:name client))}
[:div.inbox-messages
(when-let [error @(re-frame/subscribe [::subs/page-failure])]
[:div.notification.is-warning.animated.fadeInUp
error])
main]]
(when right-side-bar
right-side-bar)
]
[:div
bottom]
[:div#dz-hidden]]))
(defn side-bar [{:keys [on-close]} children]
[:div [:a.delete.is-pulled-right {:on-click on-close}] [:div children]])
(defn loading-layout []
[side-bar-layout
{:main [:div.has-text-centered.hero.is-fullheight.is-vertically-centered.is-centered
[:div.hero-body
[:div.container
[:div.column.is-4.is-offset-4.has-text-centered
[:div.loader.is-loading.is-active.big.is-centered]]]]]}])