Skip to content
Permalink
4966fdb459
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Go to file
 
 
Cannot retrieve contributors at this time
340 lines (308 sloc) 10.7 KB
(ns ulysses.pages.builder
(:require [re-frame.core :as re-frame :refer [subscribe dispatch]]
[re-com.core :refer [selection-list]]
[ulysses.components.basic :refer [hink
link
loading-or-no-results
fa
tabs
range-slider
text-input]]
[ulysses.components.misc :refer [grant-op-meta]]
[ulysses.components.word-cloud :refer [word-cloud]]
[ulysses.utils :refer [map-subels map-lookup str->int classes-attr]]
[ulysses.lib.packer :as packer]
[reagent.core :as r]
[clojure.string :as string]
[cljs.pprint :as pprint]
[ulysses.extra :refer [select_values]]))
;; ----------------------------------------------------------------------------
; helpers
;; ----------------------------------------------------------------------------
(defn- get-grant-op-id [page-with-args]
(-> page-with-args second :grant-op-id str->int))
;; ----------------------------------------------------------------------------
; components
;; ----------------------------------------------------------------------------
(defn faculty-years-uconn
[{:keys [faculty-years-uconn]}]
[:select
{:value faculty-years-uconn
:on-change (fn [e]
(dispatch [:builder-filter-faculty-years-uconn
(->> e
(.-target)
(select_values)
(js->clj))]))}
(map-subels
(fn [t] [:option {:value t} (str t "+")])
(range 0 (inc 30)))])
(defn faculty-title-multiselect
[faculty-titles {:keys [faculty-title-set]}]
[selection-list
:multi-select? true
:hide-border? true
:required? true
:max-height "200px"
:choices
(mapv #(hash-map :id % :label %) faculty-titles)
:model
faculty-title-set
:on-change
(fn [v]
(dispatch [:builder-filter-faculty-title-set v]))])
(defn metric-slider
[metric filters]
(let [value (get-in filters [:metrics metric])]
[:div.relative
[:div.absolute.small.color-gray.right-below-bottom value "%"]
[range-slider
:min 0 :max 100 :value value
:on-change
(fn [v]
(dispatch [:builder-filter-faculty-metric metric v]))]]))
(defn sidebar-section
[title & body]
[:div.builder-panel-sidebar-section
[:h4 title]
(into [:div] body)])
(defn sidebar-slider-section
[filters title filter-name]
[sidebar-section
title
[metric-slider
filter-name
filters]])
(defn sidebar
[faculty-titles filters]
[:div.builder-panel-sidebar
[:h3 "Filters"]
[sidebar-section
"Titles"
[faculty-title-multiselect
faculty-titles
filters]]
[sidebar-section
"Years at UConn"
[faculty-years-uconn
filters]]
[sidebar-slider-section
filters
"Publication Count"
:publicationCount]
[sidebar-slider-section
filters
"Grant Count"
:grantCount]
[sidebar-slider-section
filters
"Grant Funds"
:grantFunds]
[sidebar-slider-section
filters
"Recent Grant Count"
:recentGrantCount]
[sidebar-slider-section
filters
"Recent Grant Funds"
:recentGrantFunds]
[:br]])
(defn workspace-row [faculty]
(let [{:keys [id name title year_hired]} faculty]
[:tr.faculty-row
{:on-mouse-over #(dispatch [:builder-workspace-faculty-hover id])
:on-mouse-leave #(dispatch [:nil-builder-workspace-faculty-hover])}
[:td.first-col
[hink
(partial dispatch [:remove-working-faculty id])
{:class :g-plus}
[fa :minus-square-o]]]
[:td name]
[:td (string/capitalize title)]
[:td year_hired]]))
(defn workspace [faculties]
(if (empty? faculties)
[loading-or-no-results
:not-found-message
"Your workspace is empty. Add faculty from the pool to the right."]
[:div.faculties-pool.table-responsive
[:table.table.table-striped.table-bordered.table-sm
[:thead
[:tr [:th nil] [:th "Name"] [:th "Title"] [:th "Year Hired"]]]
[:tbody
(map-subels workspace-row faculties)]]]))
(defn workspace-header-tabs [workspaces workspace-current]
[tabs
(map
(fn [{:keys [id name]}]
; make tab-map
{:name (if-not (string/blank? name) name (str "untitled #" id))
:on-click #(dispatch [:workspace-switch id])
:is-active (= id (:id workspace-current))})
workspaces)])
(defn workspace-header [workspaces workspace-current]
(let [btn-attrs (classes-attr :btn :btn-sm :btn-primary)]
[:div
[:div.workspace-header-first
[:h3 "Working Team"]
[:div.workspace-actions
[hink #(dispatch [:workspace-new-blank]) btn-attrs "New Blank"]
[hink #(dispatch [:workspace-new-default]) btn-attrs "New from Default"]
[hink #(dispatch [:workspace-new-duplicate]) btn-attrs "Duplicate"]]]
[workspace-header-tabs workspaces workspace-current]]))
(defn workspace-rename [workspace-current]
(let [new-name (r/atom (str))]
(fn [workspace-current]
[hink
(fn []
(reset! new-name (:name workspace-current))
(dispatch
[:modal
{:title [:span "Rename Workspace " [:i (:name workspace-current)]]
:action-label "Rename"
:on-action #(dispatch [:workspace-rename @new-name])
:children
[:div
[text-input
:placeholder "Name"
:value new-name]]}]))
(classes-attr :btn :btn-sm :btn-info)
"Rename"])))
(defn workspace-save []
[hink
(partial dispatch [:workspace-save])
(classes-attr :btn :btn-sm :btn-primary)
"Save"])
(defn workspace-delete [workspace-current]
[hink
(fn []
(dispatch
[:modal
{:title [:span "Delete Workspace " [:i (:name workspace-current)]]
:action-label "Delete"
:action-brand :danger
:on-action #(dispatch [:workspace-delete])
:children "Are you sure you want to delete this workspace?"}]))
(classes-attr :btn :btn-sm :btn-danger)
"Delete"])
(defn workspace-footer [workspace-current]
(when workspace-current
[:div.workspace-footer
[workspace-rename workspace-current]
[workspace-delete workspace-current]
[workspace-save]]))
(defn pool-row [fam]
(let [{:keys [faculty fundingCoverageScore]} fam
{:keys [id name title year_hired]} faculty]
[:tr.faculty-row
[:td.first-col
[hink
(partial dispatch [:add-working-faculty id])
{:class :g-plus}
[fa :plus-square-o]]]
[:td name]
[:td (string/capitalize title)]
[:td year_hired]
[:td (pprint/cl-format nil "~,4f" fundingCoverageScore)]
[:td
[link [:profile :person-id id] {}
[:span.label.label-default "View Profile"]]]]))
(defn pool [faculties-and-metrics]
(if (empty? faculties-and-metrics)
[loading-or-no-results]
[:div.faculties-pool.table-responsive
[:table.table.table-striped.table-bordered.table-sm
[:thead
[:tr [:th nil] [:th "Name"] [:th "Title"] [:th "Year Hired"] [:th "Score"] [:th ""]]]
[:tbody
(map-subels pool-row faculties-and-metrics)]]]))
(defn builder-panel
[op
faculties faculty-titles faculties-pool
workspaces workspace-current workspace-faculty-hover
filters]
[:div.builder-panel
[sidebar faculty-titles filters]
[:div.builder-panel-main
[:div.builder-panel-half-section
[:div.inner
[workspace-header workspaces workspace-current]
[workspace (map-lookup faculties (or (:faculties workspace-current) []))]
[workspace-footer workspace-current]]
[:div.inner
[:h3 "Word Cloud"]
(when workspace-faculty-hover
[word-cloud 20 (:keywords workspace-faculty-hover)])]]
[:div.builder-panel-half-section
[:div.inner
[:h3 "Results"]
[pool faculties-pool]]
[:div.inner
[:h3 "Word Cloud"]]]]])
(defn builder-header
[{:keys [title purpose] :as op}]
[:div.builder-header
[:div.container-fluid
[:div.row
[:div.col-md-12
[:h3.text-xs-center.mb-15 title]
[:div.text-xs-center
[grant-op-meta true op]]
[:p purpose]]]]])
;; ----------------------------------------------------------------------------
;; main
;; ----------------------------------------------------------------------------
(defn main []
(let [page-with-args (subscribe [:page-with-args])
grant-op (subscribe [:builder-grant-op])
faculties (subscribe [:faculties])
faculty-titles (subscribe [:faculty-titles])
faculties-pool (subscribe [:builder-faculties-pool-filtered])
workspaces (subscribe [:workspaces-current])
workspace (subscribe [:builder-workspace])
workspace-faculty-hover (subscribe [:builder-workspace-faculty-hover])
filters (subscribe [:builder-filters])
last-id (atom nil)]
(r/create-class
{:component-will-mount
(fn []
(let [id (get-grant-op-id @page-with-args)]
(reset! last-id id)
(dispatch [:nil-builder])
(dispatch [:request-faculty-titles])
; common with will-update:
(dispatch [:request-builder-grant-op id])
(dispatch [:workspace-load-from-op id])
(dispatch [:request-faculties-pool])))
:component-will-update
(fn []
(let [pwa @page-with-args
id (get-grant-op-id pwa)]
(when (and (not= id @last-id) (= :builder (first pwa)))
(dispatch [:nil-builder])
(dispatch [:request-builder-grant-op id])
(dispatch [:workspace-load-from-op id])
(dispatch [:request-faculties-pool]))
(reset! last-id id)))
:component-will-unmount
(fn []
(dispatch [:nil-builder]))
:reagent-render
(fn []
(let [op @grant-op
_ @page-with-args]
(if op
[:div
[builder-header op]
[builder-panel
op
@faculties
@faculty-titles
@faculties-pool
@workspaces
@workspace
@workspace-faculty-hover
@filters]]
[loading-or-no-results
:not-found-message
"The requested grant opportunity was not found."])))})))