Skip to content

Commit

Permalink
Provide relationship (joins) manager in dashboard
Browse files Browse the repository at this point in the history
  • Loading branch information
joshkh committed Jul 25, 2017
1 parent dd80c16 commit 7bbfd72
Show file tree
Hide file tree
Showing 9 changed files with 135 additions and 17 deletions.
2 changes: 1 addition & 1 deletion project.clj
@@ -1,4 +1,4 @@
(defproject intermine/im-tables "0.2.0-SNAPSHOT"
(defproject intermine/im-tables "0.3.0-SNAPSHOT"
:dependencies [[org.clojure/clojure "1.9.0-alpha17"]
[org.clojure/clojurescript "1.9.671"]
[reagent "0.7.0" :exclusions [cljsjs/react]]
Expand Down
2 changes: 1 addition & 1 deletion src/im_tables/core.cljs
Expand Up @@ -26,7 +26,7 @@
{
:service {:root "www.flymine.org/query"}
;:service {:root "yeastmine.yeastgenome.org/yeastmine"}
:query (query/sterilize-query db/list-query)}])
:query (query/sterilize-query db/outer-join-query)}])

(dev-setup)
(mount-root))
7 changes: 4 additions & 3 deletions src/im_tables/db.cljs
Expand Up @@ -31,6 +31,7 @@
"organism.name"
"publications.firstAuthor"
"dataSets.name"]
:joins ["Gene.publications"]
:size 10
:sortOrder [{:path "symbol"
:direction "ASC"}]
Expand All @@ -42,9 +43,9 @@
]})

(def list-query {:title "esyN demo list"
:from "Gene"
:select ["Gene.secondaryIdentifier" "Gene.symbol" "Gene.primaryIdentifier" "Gene.organism.name"]
:where [{:path "Gene", :op "IN", :value "esyN demo list"}]})
:from "Gene"
:select ["Gene.secondaryIdentifier" "Gene.symbol" "Gene.primaryIdentifier" "Gene.organism.name"]
:where [{:path "Gene", :op "IN", :value "esyN demo list"}]})

(def default-db
{
Expand Down
31 changes: 31 additions & 0 deletions src/im_tables/events.cljs
Expand Up @@ -198,6 +198,37 @@
:dispatch [:im-tables.main/run-query loc]
})))


(defn coll-contains? [needle haystack] (some? (some #{needle} haystack)))
(defn without [coll item] (filter (partial not= item) coll))


;;;;; Relationship Manager

; Copy the main query to our cache for editing
(reg-event-db
:rel-manager/reset
(sandbox)
(fn [db [_ loc]]
(assoc-in db [:cache :rel-manager] (get db :query))))

; Copy the edited query from the cache back to the main query and run it
(reg-event-fx
:rel-manager/apply-changes
(sandbox)
(fn [{db :db} [_ loc]]
{:db (assoc db :query (get-in db [:cache :rel-manager]))
:dispatch [:im-tables.main/run-query loc]}))

(reg-event-db
:rel-manager/toggle-relationship
(sandbox)
(fn [db [_ loc view join?]]
(if join?
(update-in db [:cache :rel-manager :joins] conj view)
(update-in db [:cache :rel-manager :joins] without view))))


;;;;; STYLE

(defn swap
Expand Down
5 changes: 5 additions & 0 deletions src/im_tables/subs.cljs
Expand Up @@ -163,3 +163,8 @@
(subscribe [:query/joins loc])])
(fn [[views joins]]
(reduce (fn [total next] (replace-join-views total next)) views joins)))

(reg-sub
:rel-manager/query
(fn [db [_ loc]]
(get-in db (glue loc [:cache :rel-manager]))))
20 changes: 12 additions & 8 deletions src/im_tables/views/dashboard/main.cljs
@@ -1,6 +1,7 @@
(ns im-tables.views.dashboard.main
(:require [im-tables.views.dashboard.pagination :as pager]
[im-tables.views.dashboard.manager.columns.main :as column-manager]
[im-tables.views.dashboard.manager.relationships.main :as rel-manager]
[im-tables.views.dashboard.undo :as undo]
[im-tables.views.dashboard.save :as save]
[im-tables.views.dashboard.exporttable :as exporttable]
Expand All @@ -18,9 +19,12 @@
[:button.btn.btn-default
{:data-toggle "modal"
:data-target "#myModal"}
[:i.fa.fa-columns] " Add Columns"]]
[:i.fa.fa-columns] " Add Columns"]]
[:div.btn-group [rel-manager/main loc]]
[:div.btn-group [save/main loc]]
[:div.btn-group [exporttable/exporttable loc]]]
[:div.btn-group [exporttable/exporttable loc]]

]
]
[:div.col-xs-6
[:div.container-fluid
Expand All @@ -34,9 +38,9 @@
{:style {:padding-right "20px"}}
(when (:iTotalRecords response)
(str "Showing "
(inc (:start pagination)) " to "
(min
(+ (:start pagination) (:limit pagination))
(:iTotalRecords response))
" of "
(.toLocaleString (:iTotalRecords response)) " rows"))]]]]]]]]))
(inc (:start pagination)) " to "
(min
(+ (:start pagination) (:limit pagination))
(:iTotalRecords response))
" of "
(.toLocaleString (:iTotalRecords response)) " rows"))]]]]]]]]))
78 changes: 78 additions & 0 deletions src/im_tables/views/dashboard/manager/relationships/main.cljs
@@ -0,0 +1,78 @@
(ns im-tables.views.dashboard.manager.relationships.main
(:require [re-frame.core :refer [subscribe dispatch]]
[reagent.core :refer [atom]]
[clojure.string :refer [join includes?]]
[inflections.core :refer [plural]]
[imcljs.path :as path]
[oops.core :refer [ocall oget]]))


(defn not-root? "String includes a dot?" [path] (includes? path "."))
(defn coll-contains? "Haystack contains needle?" [needle haystack] (some? (some #{needle} haystack)))
(defn without "Remove item froma collection" [coll item] (filter (partial not= item) coll))

(defn join-with-arrows
"Make a friendly HTML path name: Gene >> Data Sets >> Publications"
[v]
(->> v
(map (fn [n] [:span n]))
(interpose [:span [:i.fa.fa-angle-double-right.fa-fw]])))

(defn relationship []
(fn [loc {:keys [view model joins]}]
(let [is-join? (coll-contains? view joins)]
(let [add-join-fn (fn [] (dispatch [:rel-manager/toggle-relationship loc view true]))
rmv-join-fn (fn [] (dispatch [:rel-manager/toggle-relationship loc view false]))]
[:li.list-group-item
[:div
(into [:span] (join-with-arrows (path/display-name model view)))
[:div.btn-group.pull-right
[:button.btn {:class (if (not is-join?) "btn-primary" "btn-default")
:on-click rmv-join-fn}
"Required"]
[:button.btn {:class (if is-join? "btn-primary" "btn-default")
:on-click add-join-fn}
"Optional"]]]
[:div.clearfix]]))))

(defn relationship-form [loc {:keys [query model]}]
(fn [loc {:keys [query model]}]
(let [relationships (distinct (filter not-root? (map (partial path/trim-to-last-class model) (:select query))))
joins (:joins query)]
(conj (into [:ul.list-group]
(when (and query model)
(->> relationships
(map (fn [view]
^{:key view} [relationship loc {:view view
:joins joins
:model model}])))))))))

(defn modal [loc]
(let [model (subscribe [:assets/model loc])]
(fn [loc query]
[:div#relModal.modal.fade {:role "dialog"}
[:div.modal-dialog
[:div.modal-content
[:div.modal-header [:h3 "Manage Relationships"]]
[:div.modal-body
(when @model [relationship-form loc {:query query :model @model}])]
[:div.modal-footer
[:div.btn-toolbar.pull-right
[:button.btn.btn-default
{:data-dismiss "modal"}
"Cancel"]
[:button.btn.btn-success
{:data-dismiss "modal"
:on-click (fn [] (dispatch [:rel-manager/apply-changes loc]))}
"Apply Changes"]]]]]])))

(defn main [loc]
(let [rel-query (subscribe [:rel-manager/query loc])]
(fn [loc]
[:div.btn-group
[:button.btn.btn-default
{:on-click (fn [] (dispatch [:rel-manager/reset loc]))
:data-toggle "modal"
:data-target "#relModal"}
[:i.fa.fa-share-alt] " Manage Relationships"]
[modal loc @rel-query]])))
4 changes: 2 additions & 2 deletions src/im_tables/views/table/body/main.cljs
Expand Up @@ -64,8 +64,8 @@
remaining])})))


(defn outer-join-table []
(let [model (subscribe [:assets/model])
(defn outer-join-table [loc]
(let [model (subscribe [:assets/model loc])
open? (reagent/atom false)]
(fn [loc data]
(if (> 1 (count (:rows data)))
Expand Down
3 changes: 1 addition & 2 deletions src/im_tables/views/table/head/main.cljs
Expand Up @@ -21,8 +21,7 @@
(and (= idx dragging-over) (< idx dragging-item)) "drag-left"
(and (= idx dragging-over) (> idx dragging-item)) "drag-right")
[class & path] (split header " > ")
display-name (when (and @model view)
(impath/display-name @model view))]
display-name (when (and @model view) (impath/display-name @model view))]
[:th
{:class drag-class
:draggable @draggable?
Expand Down

0 comments on commit 7bbfd72

Please sign in to comment.