(ns auto-ap.views.components.invoice-table (:require [re-frame.core :as re-frame] [auto-ap.subs :as subs] [auto-ap.views.utils :refer [date->str]] [auto-ap.views.components.paginator :refer [paginator]] [auto-ap.views.components.sorter :refer [sorted-column]] [reagent.core :as reagent] [clojure.string :as str] [cljs-time.format :as format] [goog.string :as gstring])) ;; TODO graphql schema enforcement ;; TODO postgres constraints for data integrity ;; TODO performance ;; TODO refactor graphql (defn query [params] {:venia/queries [[:invoice_page (assoc params :company-id (:id @(re-frame/subscribe [::subs/company]))) [[:invoices [:id :total :outstanding-balance :invoice-number :date [:vendor [:name :id]] [:company [:name :id]] [:checks [:amount [:check [:amount :s3_url :check_number ]]]]]] :total :start :end]]]}) (defn invoice-table [{:keys [id invoice-page status on-params-change vendors params check-boxes checked on-check-changed]}] (let [state (reagent/atom (or @params {})) opc (fn [p] (swap! state merge p) (on-params-change p))] (fn [{:keys [id invoice-page status on-params-change vendors checked]}] (let [{:keys [sort-by asc]} @state {:keys [invoices start end count total]} @invoice-page] [:div [paginator {:start start :end end :count count :total total :on-change (fn [p ] (on-params-change (swap! state merge p)))}] "Showing " (inc start) "-" end "/" total [:table.table.is-fullwidth [:thead [:tr (when check-boxes [:th {:style {"width" "20px"}}]) [sorted-column {:on-sort opc :style {:width "33%" :cursor "pointer"} :sort-key "vendor" :sort-by sort-by :asc asc} "Vendor"] [sorted-column {:on-sort opc :style {:width "33%" :cursor "pointer"} :sort-key "company" :sort-by sort-by :asc asc} "Company"] [sorted-column {:on-sort opc :style {:width "33%" :cursor "pointer"} :sort-key "invoice-number" :sort-by sort-by :asc asc} "Invoice #"] [sorted-column {:on-sort opc :style {:width "8em" :cursor "pointer"} :sort-key "date" :sort-by sort-by :asc asc} "Date"] [sorted-column {:on-sort opc :style {:width "8em" :cursor "pointer"} :sort-key "total" :sort-by sort-by :asc asc} "Amount"] [sorted-column {:on-sort opc :style {:width "10em" :cursor "pointer"} :sort-key "outstanding" :sort-by sort-by :asc asc} "Outstanding"] [:th {:style {:width "10em"}} "" ]]] [:tbody (if (:loading @status) [:tr [:td {:col-span 5} [:i.fa.fa-spin.fa-spinner]]] (for [{:keys [company checks invoice-number date total outstanding-balance id vendor] :as i} (:invoices @invoice-page)] ^{:key id} [:tr (when check-boxes [:td [:input.checkbox {:type "checkbox" :checked (if (get checked id) "checked" "") :on-change (fn [x e] (when on-check-changed (on-check-changed id)))} ]]) [:td (:name vendor)] [:td (:name company)] [:td invoice-number] [:td (date->str date) ] [:td (gstring/format "$%.2f" total )] [:td (gstring/format "$%.2f" outstanding-balance )] [:td (for [check checks] ^{:key (:id check)} [:a.tag {:href (:s3-url (:check check)) :target "_new"} [:i.fa.fa-money-check] [:span.icon [:i.fa.fa-money]] (str " " (:check-number (:check check)) " (" (gstring/format "$%.2f" (:amount check) ) ")")])]]))]]]))))