mirror of
https://github.com/logseq/logseq.git
synced 2026-05-25 05:04:24 +00:00
167 lines
7.9 KiB
Clojure
167 lines
7.9 KiB
Clojure
(ns frontend.components.reference
|
|
(:require [rum.core :as rum]
|
|
[frontend.util :as util]
|
|
[frontend.state :as state]
|
|
[clojure.string :as string]
|
|
[frontend.db :as db]
|
|
[frontend.components.block :as block]
|
|
[frontend.ui :as ui]
|
|
[frontend.components.content :as content]
|
|
[frontend.date :as date]
|
|
[frontend.components.editor :as editor]
|
|
[frontend.db-mixins :as db-mixins]
|
|
[clojure.string :as string]
|
|
[frontend.config :as config]
|
|
[frontend.components.svg :as svg]
|
|
[frontend.handler.page :as page-handler]
|
|
[frontend.handler.block :as block-handler]
|
|
[medley.core :as medley]))
|
|
|
|
(rum/defc filter-dialog-inner < rum/reactive
|
|
[close-fn references page-name]
|
|
(let [filter-state (page-handler/get-filters page-name)]
|
|
[:div.filters
|
|
[:div.sm:flex.sm:items-start
|
|
[:div.mx-auto.flex-shrink-0.flex.items-center.justify-center.h-12.w-12.rounded-full.bg-gray-200.text-gray-500.sm:mx-0.sm:h-10.sm:w-10
|
|
(svg/filter-icon)]
|
|
[:div.mt-3.text-center.sm:mt-0.sm:ml-4.sm:text-left
|
|
[:h3#modal-headline.text-lg.leading-6.font-medium "Filter"]
|
|
[:span.text-xs
|
|
"Click to include and shift-click to exclude. Click again to remove."]]]
|
|
(when (seq references)
|
|
[:div.mt-5.sm:mt-4.sm:flex.sm.gap-1.flex-wrap
|
|
(for [reference references]
|
|
(let [lc-reference (string/lower-case reference)
|
|
filtered (get (rum/react filter-state) lc-reference)
|
|
color (condp = filtered
|
|
true "text-green-400"
|
|
false "text-red-400"
|
|
nil)]
|
|
[:button.border.rounded.px-1.mb-1.mr-1 {:key reference :class color :style {:border-color "currentColor"}
|
|
:on-click (fn [e]
|
|
(swap! filter-state #(if (nil? (get @filter-state lc-reference))
|
|
(assoc % lc-reference (not (.-shiftKey e)))
|
|
(dissoc % lc-reference)))
|
|
(page-handler/save-filter! page-name @filter-state))}
|
|
reference]))])]))
|
|
|
|
(defn filter-dialog
|
|
[references page-name]
|
|
(fn [close-fn]
|
|
(filter-dialog-inner close-fn references page-name)))
|
|
|
|
(rum/defc references < rum/reactive
|
|
[page-name marker? priority?]
|
|
(when page-name
|
|
(let [block? (util/uuid-string? page-name)
|
|
block-id (and block? (uuid page-name))
|
|
page-name (string/lower-case page-name)
|
|
journal? (date/valid-journal-title? (string/capitalize page-name))
|
|
repo (state/get-current-repo)
|
|
ref-blocks (cond
|
|
priority?
|
|
(db/get-blocks-by-priority repo page-name)
|
|
|
|
marker?
|
|
(db/get-marker-blocks repo page-name)
|
|
block-id
|
|
(db/get-block-referenced-blocks block-id)
|
|
:else
|
|
(db/get-page-referenced-blocks page-name))
|
|
ref-pages (map (comp :block/original-name first) ref-blocks)
|
|
scheduled-or-deadlines (if (and journal?
|
|
(not (true? (state/scheduled-deadlines-disabled?)))
|
|
(= page-name (string/lower-case (date/journal-name))))
|
|
(db/get-date-scheduled-or-deadlines (string/capitalize page-name))
|
|
nil)
|
|
references (db/get-page-linked-refs-refed-pages repo page-name)
|
|
references (->> (concat ref-pages references)
|
|
(remove nil?)
|
|
(distinct))
|
|
filters (page-handler/get-filters page-name)
|
|
filter-state (rum/react filters)
|
|
filters (when (seq filter-state)
|
|
(->> (group-by second filter-state)
|
|
(medley/map-vals #(map first %))))
|
|
filtered-ref-blocks (block-handler/filter-blocks repo ref-blocks filters true)
|
|
n-ref (count filtered-ref-blocks)]
|
|
(when (or (> n-ref 0)
|
|
(seq scheduled-or-deadlines)
|
|
(seq filter-state))
|
|
[:div.references.mt-6.flex-1.flex-row
|
|
[:div.content
|
|
(when (seq scheduled-or-deadlines)
|
|
(ui/foldable
|
|
[:h2.font-bold.opacity-50 "SCHEDULED AND DEADLINE"]
|
|
[:div.references-blocks.mb-6
|
|
(let [ref-hiccup (block/->hiccup scheduled-or-deadlines
|
|
{:id (str page-name "-agenda")
|
|
:ref? true
|
|
:group-by-page? true
|
|
:editor-box editor/box}
|
|
{})]
|
|
(content/content page-name
|
|
{:hiccup ref-hiccup}))]))
|
|
|
|
(ui/foldable
|
|
[:div.flex.flex-row.flex-1.justify-between
|
|
[:h2.font-bold.opacity-50 (let []
|
|
(str n-ref " Linked Reference"
|
|
(if (> n-ref 1) "s")))]
|
|
[:a.opacity-50.hover:opacity-100
|
|
{:title "Filter"
|
|
:on-click #(state/set-modal! (filter-dialog references page-name))}
|
|
(svg/filter-icon (cond
|
|
(empty? filter-state) nil
|
|
(every? true? (vals filter-state)) "text-green-400"
|
|
(every? false? (vals filter-state)) "text-red-400"
|
|
:else "text-yellow-400"))]]
|
|
|
|
[:div.references-blocks
|
|
(let [ref-hiccup (block/->hiccup filtered-ref-blocks
|
|
{:id page-name
|
|
:ref? true
|
|
:breadcrumb-show? true
|
|
:group-by-page? true
|
|
:editor-box editor/box
|
|
:filters filters}
|
|
{})]
|
|
(content/content page-name
|
|
{:hiccup ref-hiccup}))])]]))))
|
|
|
|
(rum/defcs unlinked-references-aux
|
|
< rum/reactive db-mixins/query
|
|
{:will-mount (fn [state]
|
|
(let [[page-name n-ref] (:rum/args state)
|
|
ref-blocks (db/get-page-unlinked-references page-name)]
|
|
(reset! n-ref (count ref-blocks))
|
|
(assoc state ::ref-blocks ref-blocks)))}
|
|
[state page-name n-ref]
|
|
(let [ref-blocks (::ref-blocks state)]
|
|
[:div.references-blocks
|
|
(let [ref-hiccup (block/->hiccup ref-blocks
|
|
{:id (str page-name "-unlinked-")
|
|
:ref? true
|
|
:group-by-page? true
|
|
:editor-box editor/box}
|
|
{})]
|
|
(content/content page-name
|
|
{:hiccup ref-hiccup}))]))
|
|
|
|
(rum/defcs unlinked-references < rum/reactive
|
|
(rum/local nil ::n-ref)
|
|
[state page-name]
|
|
(let [n-ref (get state ::n-ref)]
|
|
(when page-name
|
|
(let [page-name (string/lower-case page-name)]
|
|
[:div.references.mt-6.flex-1.flex-row
|
|
[:div.content.flex-1
|
|
(ui/foldable
|
|
[:h2.font-bold {:style {:opacity "0.3"}}
|
|
(if @n-ref
|
|
(str @n-ref " Unlinked Reference" (if (> @n-ref 1)
|
|
"s"))
|
|
"Unlinked References")]
|
|
(fn [] (unlinked-references-aux page-name n-ref))
|
|
true)]]))))
|