Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- (ns pantrack.routes.tasks
- (:require [reagent.core :as r]
- [reagent.session :as session]
- [secretary.core :as secretary :include-macros true]
- [pantrack.env :as env :refer [navigate! component]]
- [pantrack.util :as util]
- [pantrack.db :as db]
- [pantrack.hunt :as hunt]
- [dommy.core :refer-macros [sel sel1]]
- [cljsjs.recharts]
- [cljsjs.moment]
- [clojure.string :as str]))
- (def table-state
- (r/atom
- {:column nil
- :per-page 12
- :cur-page nil
- :all-data nil
- :page-data nil
- :direction nil
- :page-count nil
- :message-hidden true}))
- (defn init-table-state []
- (let [all-data (map #(assoc % :desc (or (:short-desc %) (:long-desc %)))
- (if (contains? @hunt/search-results :tickets)
- (:tickets @hunt/search-results)
- @db/tickets))]
- (swap! table-state assoc
- :all-data all-data
- :page-data (vec (take 12 all-data))
- :page-count (js/Math.ceil
- (/ (count all-data)
- (:per-page @table-state)))
- :message-hidden true
- :cur-page 0)))
- (add-watch
- db/tickets :notify-change
- (fn [_ _ old new]
- (js/console.debug "notifying of tasks change")
- (letfn [(get-ticket [n]
- (-> #(== n (:number %))
- (filter new)
- first))
- (update-all-data [i m]
- (swap! table-state assoc
- :all-data (assoc (:all-data @table-state)
- i (get-ticket (:number m)))))
- (update-page-data [i m]
- (swap! table-state assoc
- :page-data (assoc (:page-data @table-state)
- i (get-ticket (:number m)))))]
- (cond
- (not (empty? @hunt/search-filters)) (do (hunt/update-search-results! @hunt/search-filters "")
- (init-table-state))
- (zero? (count (:all-data @table-state))) (init-table-state)
- (not= (count (:all-data @table-state)) (count new)) (swap! table-state assoc
- :message-hidden false)
- :else (do (js/console.debug "updating tasks in-place")
- (doall (map-indexed update-page-data (:page-data @table-state)))
- (doall (map-indexed update-all-data (:all-data @table-state))))))))
- (add-watch
- hunt/search-results :notify-change
- (fn [_ _ old new]
- (init-table-state)))
- (defn sort-table [k]
- (let [{:keys [column per-page cur-page direction all-data]} @table-state
- sorted-data (sort-by k all-data)]
- (if (not= column k)
- (swap! table-state assoc
- :column k
- :direction "ascending"
- :page-data (take per-page
- (drop (* cur-page per-page)
- sorted-data)))
- (swap! table-state assoc
- :page-data (take per-page
- (drop (* cur-page per-page)
- (if (= direction "ascending")
- (reverse sorted-data)
- sorted-data)))
- :direction (if (= direction "ascending")
- "descending"
- "ascending")))))
- (defn get-page [n]
- (let [{:keys [column direction per-page cur-page all-data]} @table-state
- sorted-data (if (and (some? direction) (some? column))
- (let [sorted (sort-by column all-data)]
- (if (= direction "ascending")
- sorted
- (reverse sorted)))
- all-data)]
- (swap! table-state assoc
- :cur-page n
- :page-data (take per-page
- (drop (* n per-page)
- sorted-data)))))
- (defn my-header-cell
- ([heading k]
- (let [t-header-cell (component "Table" "HeaderCell")]
- [:> t-header-cell
- {:style {:border-left "0px"}
- :sorted (if (= (:column @table-state) k)
- (:direction @table-state)
- nil)
- :onClick #(sort-table k)}
- heading]))
- ([heading]
- (my-header-cell
- heading
- (keyword
- (str/lower-case
- (str/replace
- heading #" " "-"))))))
- (defn search-filters []
- (when (not (empty? @hunt/search-filters))
- (let [label (component "Label")
- f (fn [[k v]]
- ^{:key (name k)}
- [:> label
- {:onClick #(do
- (swap! hunt/search-filters dissoc k)
- (hunt/update-search-results!
- @hunt/search-filters
- (.-value (sel1 "input#searchbar.prompt"))))}
- (str (str/capitalize (name k)) ": " v)])]
- [:div {:id "search-filters"}
- (map f @hunt/search-filters)])))
- (defn sortable-table []
- (let [table (component "Table")
- t-header (component "Table" "Header")
- t-row (component "Table" "Row")
- t-header-cell (component "Table" "HeaderCell")
- t-body (component "Table" "Body")
- t-cell (component "Table" "Cell")
- t-footer (component "Table" "Footer")
- icon (component "Icon")
- pagination (component "Pagination")
- label (component "Label")
- button (component "Button")]
- [:> table {:sortable true
- :compact true :striped true
- :style {:margin-top "50px"}
- :selectable true :basic "very"
- :unstackable true}
- [:> t-header
- [:> t-row
- [my-header-cell "Number"]
- [my-header-cell "Requested by" :requestor]
- [my-header-cell "Description" :desc]
- [my-header-cell "Status"]
- [my-header-cell "Assigned to"]
- [my-header-cell "Last Updated"]]]
- [:> t-body
- (map-indexed
- (fn [i d]
- ^{:key (str i)}
- [:> t-row {:onClick #(navigate! (str "/ticket/" (:number d)))}
- [:> t-cell
- [:> icon
- (case (:priority d)
- "Urgent" {:name "angle double up" :color "red"}
- "High" {:name "angle up" :color "orange"}
- "Routine" {:name "angle down"}
- "Low" {:name "angle double down" :color "blue"})]
- (:number d)]
- [:> t-cell (:requestor d)]
- [:> t-cell [:div.truncate (or (:short-desc d) (:long-desc d))]]
- [:> t-cell (:status d)]
- [:> t-cell (:assigned-to d)]
- [:> t-cell (:last-updated d)]])
- (:page-data @table-state))]
- [:> t-footer
- [:> t-row
- [:> t-header-cell {:colSpan 5}
- [:> pagination {:activePage (inc (:cur-page @table-state))
- :totalPages (:page-count @table-state)
- :onPageChange #(get-page (dec (.-activePage %2)))
- :floated "right"}]]
- [:> t-header-cell
- [:> button {:floated "right" :circular true
- :icon "plus" :size "big"
- :disabled (nil? @db/logged-in-user)
- :onClick #(navigate! "/add-task")}]]]]]))
- (defn tasks-page []
- (let [message (component "Message")
- statistic-group (component "Statistic" "Group")
- statistic-value (component "Statistic" "Value")
- statistic-label (component "Statistic" "Label")
- statistic (component "Statistic")
- icon (component "Icon")
- _ (init-table-state)]
- (fn []
- (let [priorities (frequencies
- (map :priority
- (filter (fn [t]
- (not-any? #(= (:status t) %)
- [:completed :denied]))
- (:all-data @table-state))))]
- [:div
- [search-filters]
- [:> statistic-group {:widths "four"
- :style {:padding-top "30px"}}
- [:> statistic {:color "red"}
- [:> statistic-value
- [:> icon {:name "angle double up"}]
- (or (get priorities "Urgent") 0)]
- [:> statistic-label "Urgent"]]
- [:> statistic {:color "orange"}
- [:> statistic-value
- [:> icon {:name "angle up"}]
- (or (get priorities "High") 0)]
- [:> statistic-label "High"]]
- [:> statistic
- [:> statistic-value
- [:> icon {:name "angle down"}]
- (or (get priorities "Routine") 0)]
- [:> statistic-label "Routine"]]
- [:> statistic {:color "blue"}
- [:> statistic-value
- [:> icon {:name "angle double down"}]
- (or (get priorities "Low") 0)]
- [:> statistic-label "Low"]]]
- [:> message {:hidden (:message-hidden @table-state)
- :onClick init-table-state
- :icon "ticket"
- :header "New tickets are available for viewing"
- :content "Click to reload tickets"}]
- [sortable-table]]))))
- (swap! env/pages assoc :tasks #'tasks-page)
- (secretary/defroute "/tasks" []
- (session/put! :page :tasks))
Add Comment
Please, Sign In to add comment