Custom component

Resolves #65
This commit is contained in:
Tienson Qin
2020-07-22 10:43:42 +08:00
parent 384a0cef8b
commit ed4fe2eea0
5 changed files with 95 additions and 40 deletions

View File

@@ -28,7 +28,8 @@
[frontend.extensions.sci :as sci]
["/frontend/utils" :as utils]
[frontend.format.block :as block]
[clojure.walk :as walk]))
[clojure.walk :as walk]
[cljs-bean.core :as bean]))
;; local state
(defonce *heading-children
@@ -1014,9 +1015,11 @@
(rum/defcs custom-query < rum/reactive
{:will-mount (fn [state]
(let [[config _options content] (:rum/args state)
query-atom (db/custom-query content)]
(assoc state :query-atom query-atom)))
(let [[config query] (:rum/args state)]
(when (and (not (sci/loaded?)) (:view query))
(sci/load!))
(let [query-atom (db/custom-query query)]
(assoc state :query-atom query-atom))))
:did-mount (fn [state]
(when-let [query (last (:rum/args state))]
(state/add-custom-query-component! query (:rum/react-component state)))
@@ -1026,22 +1029,43 @@
(state/remove-custom-query-component! query)
(db/remove-custom-query! (state/get-current-repo) query))
state)}
[state config options content]
(let [current-heading-uuid (:heading/uuid (:heading config))
;; exclude the current one, otherwise it'll loop forever
remove-headings (if current-heading-uuid [current-heading-uuid] nil)
query-result (if-let [a (:query-atom state)]
(rum/react a))
result (if query-result
(db/custom-query-result-transform query-result remove-headings))]
[:div.custom-query.my-2
(if (seq result)
(->hiccup result (assoc config
:custom-query? true
:group-by-page? true)
{:style {:margin-top "0.25rem"
:margin-left "0.25rem"}})
[:div.text-sm.mt-2 "Empty"])]))
[state config {:keys [title query inputs view] :as q}]
(let [loading? (rum/react sci/*loading?)]
(if loading?
(widgets/loading "loading @borkdude/sci")
(let [current-heading-uuid (:heading/uuid (:heading config))
;; exclude the current one, otherwise it'll loop forever
remove-headings (if current-heading-uuid [current-heading-uuid] nil)
query-result (if-let [a (:query-atom state)]
(rum/react a))
result (if query-result
(db/custom-query-result-transform query-result remove-headings))
view-f (try
(sci/eval-string (pr-str view))
(catch js/Error e
(println "Query: sci eval failed:")
(js/console.error e)))]
[:div.custom-query.my-2
(when title
[:p [:code title]])
(cond
(and (seq result) view-f)
(let [result (sci/call-fn view-f result)]
(util/hiccup-keywordize result))
(and (seq result)
(:heading/uuid (first result)))
(->hiccup result (assoc config
:custom-query? true
:group-by-page? true)
{:style {:margin-top "0.25rem"
:margin-left "0.25rem"}})
(seq result) ;TODO: table
(str result)
:else
[:div.text-sm.mt-2 "Empty"])]))))
(defn admonition
[config type options result]
@@ -1119,8 +1143,9 @@
(latex/html-export content true false)
(latex/latex (str (dc/squuid)) content true false))
["Custom" "query" options result content]
(custom-query config options content)
["Custom" "query" _options result content]
(let [query (reader/read-string content)]
(custom-query config query))
["Custom" "note" options result content]
(admonition config "note" options result)

View File

@@ -85,10 +85,9 @@
(let [queries (state/sub [:config repo :default-queries :journals])]
(when (seq queries)
[:div#today-queries
(for [{:keys [title query]} queries]
(for [{:keys [title] :as query} queries]
[:div {:key (str "query-" title)}
(hiccup/custom-query {:start-level 2} {:query-title title}
query)])]))))
(hiccup/custom-query {:start-level 2} query)])]))))
;; A page is just a logical heading
(rum/defcs page < rum/reactive

View File

@@ -230,8 +230,8 @@
;; TODO: rename :custom to :query/custom
(defn remove-custom-query!
[repo query-string]
(remove-q! [repo :custom query-string]))
[repo query]
(remove-q! [repo :custom query]))
(defn set-new-result!
[k new-result]
@@ -494,16 +494,22 @@
headings))
(defn custom-query
[query-string]
(when-not (string/blank? query-string)
[query]
(when-let [query (cond
(and (string? query)
(not (string/blank? query)))
(reader/read-string query)
(map? query)
query
:else
nil)]
(try
(let [query (reader/read-string query-string)
[query inputs] (if (vector? (first query))
[`~(first query) (rest query)]
[`~query nil])
(let [{:keys [query inputs]} query
inputs (map resolve-input inputs)
repo (state/get-current-repo)
k [:custom query-string]]
k [:custom query]]
(apply q repo k {} query inputs))
(catch js/Error e
(println "Query parsing failed: ")

View File

@@ -3,28 +3,44 @@
[frontend.loader :as loader]
[frontend.components.widgets :as widgets]
[frontend.config :as config]
[goog.object :as gobj]))
[goog.object :as gobj]
[cljs-bean.core :as bean]))
(defn loaded? []
js/window.sci)
(defonce *loading? (atom true))
(defn ->js
[x]
(when (loaded?)
(js/window.sci.toJS x)))
(defn eval-string
[code]
(when loaded?
(when (loaded?)
(js/window.sci.evalString code)))
(defn call-fn
[f & args]
(-> (apply f (bean/->js args))
(->js)
(bean/->clj)))
(defn load!
[]
(loader/load
(config/asset-uri "/static/js/sci.min.js")
(fn []
(reset! *loading? false))))
(rum/defc eval-result < rum/reactive
{:did-mount (fn [state]
(if (loaded?)
(reset! *loading? false)
(do
(reset! *loading? true)
(loader/load
(config/asset-uri "/static/js/sci.min.js")
(fn []
(reset! *loading? false)))))
(load!)))
state)}
[code]
(let [loading? (rum/react *loading?)]

View File

@@ -719,3 +719,12 @@
[s]
(let [tags (string/split s #",")]
(->tags tags)))
(defn hiccup-keywordize
[hiccup]
(walk/postwalk
(fn [f]
(if (and (vector? f) (string? (first f)))
(update f 0 keyword)
f))
hiccup))