Permalink
Cannot retrieve contributors at this time
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?
ulysses-front/src/cljs/ulysses/pages/builder.cljs
Go to fileThis commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
340 lines (308 sloc)
10.7 KB
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(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."])))}))) |