reference.cljs 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. (ns frontend.components.reference
  2. (:require [rum.core :as rum]
  3. [frontend.util :as util]
  4. [frontend.state :as state]
  5. [clojure.string :as string]
  6. [frontend.db :as db]
  7. [frontend.components.block :as block]
  8. [frontend.ui :as ui]
  9. [frontend.components.content :as content]
  10. [frontend.date :as date]
  11. [frontend.components.editor :as editor]
  12. [frontend.db-mixins :as db-mixins]
  13. [clojure.string :as string]
  14. [frontend.config :as config]
  15. [frontend.components.svg :as svg]
  16. [frontend.handler.page :as page-handler]
  17. [frontend.handler.block :as block-handler]
  18. [medley.core :as medley]))
  19. (rum/defc filter-dialog-inner < rum/reactive
  20. [filters-atom close-fn references page-name]
  21. [:div.filters
  22. [:div.sm:flex.sm:items-start
  23. [: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
  24. (svg/filter-icon)]
  25. [:div.mt-3.text-center.sm:mt-0.sm:ml-4.sm:text-left
  26. [:h3#modal-headline.text-lg.leading-6.font-medium "Filter"]
  27. [:span.text-xs
  28. "Click to include and shift-click to exclude. Click again to remove."]]]
  29. (when (seq references)
  30. (let [filters (rum/react filters-atom)]
  31. [:div.mt-5.sm:mt-4.sm:flex.sm.gap-1.flex-wrap
  32. (for [reference references]
  33. (let [lc-reference (string/lower-case reference)
  34. filtered (get filters lc-reference)
  35. color (condp = filtered
  36. true "text-green-400"
  37. false "text-red-400"
  38. nil)]
  39. [:button.border.rounded.px-1.mb-1.mr-1 {:key reference :class color :style {:border-color "currentColor"}
  40. :on-click (fn [e]
  41. (swap! filters-atom #(if (nil? (get filters lc-reference))
  42. (assoc % lc-reference (not (.-shiftKey e)))
  43. (dissoc % lc-reference)))
  44. (page-handler/save-filter! page-name @filters-atom))}
  45. reference]))]))])
  46. (defn filter-dialog
  47. [filters-atom references page-name]
  48. (fn [close-fn]
  49. (filter-dialog-inner filters-atom close-fn references page-name)))
  50. (rum/defcs references < rum/reactive
  51. {:init (fn [state]
  52. (let [page-name (first (:rum/args state))
  53. filters (when page-name
  54. (atom (page-handler/get-filters (string/lower-case page-name))))]
  55. (assoc state ::filters filters)))}
  56. [state page-name marker? priority?]
  57. (when page-name
  58. (let [filters-atom (get state ::filters)
  59. block? (util/uuid-string? page-name)
  60. block-id (and block? (uuid page-name))
  61. page-name (string/lower-case page-name)
  62. journal? (date/valid-journal-title? (string/capitalize page-name))
  63. repo (state/get-current-repo)
  64. ref-blocks (cond
  65. block-id
  66. (db/get-block-referenced-blocks block-id)
  67. :else
  68. (db/get-page-referenced-blocks page-name))
  69. ref-pages (map (comp :block/original-name first) ref-blocks)
  70. scheduled-or-deadlines (if (and journal?
  71. (not (true? (state/scheduled-deadlines-disabled?)))
  72. (= page-name (string/lower-case (date/journal-name))))
  73. (db/get-date-scheduled-or-deadlines (string/capitalize page-name))
  74. nil)
  75. references (db/get-page-linked-refs-refed-pages repo page-name)
  76. references (->> (concat ref-pages references)
  77. (remove nil?)
  78. (distinct))
  79. filter-state (rum/react filters-atom)
  80. filters (when (seq filter-state)
  81. (->> (group-by second filter-state)
  82. (medley/map-vals #(map first %))))
  83. filtered-ref-blocks (block-handler/filter-blocks repo ref-blocks filters true)
  84. n-ref (count filtered-ref-blocks)]
  85. (when (or (> n-ref 0)
  86. (seq scheduled-or-deadlines)
  87. (seq filter-state))
  88. [:div.references.mt-6.flex-1.flex-row
  89. [:div.content
  90. (when (seq scheduled-or-deadlines)
  91. (ui/foldable
  92. [:h2.font-bold.opacity-50 "SCHEDULED AND DEADLINE"]
  93. [:div.references-blocks.mb-6
  94. (let [ref-hiccup (block/->hiccup scheduled-or-deadlines
  95. {:id (str page-name "-agenda")
  96. :ref? true
  97. :group-by-page? true
  98. :editor-box editor/box}
  99. {})]
  100. (content/content page-name
  101. {:hiccup ref-hiccup}))]))
  102. (ui/foldable
  103. [:div.flex.flex-row.flex-1.justify-between
  104. [:h2.font-bold.opacity-50 (let []
  105. (str n-ref " Linked Reference"
  106. (if (> n-ref 1) "s")))]
  107. [:a.opacity-50.hover:opacity-100
  108. {:title "Filter"
  109. :on-click #(state/set-modal! (filter-dialog filters-atom references page-name))}
  110. (svg/filter-icon (cond
  111. (empty? filter-state) nil
  112. (every? true? (vals filter-state)) "text-green-400"
  113. (every? false? (vals filter-state)) "text-red-400"
  114. :else "text-yellow-400"))]]
  115. [:div.references-blocks
  116. (let [ref-hiccup (block/->hiccup filtered-ref-blocks
  117. {:id page-name
  118. :ref? true
  119. :breadcrumb-show? true
  120. :group-by-page? true
  121. :editor-box editor/box
  122. :filters filters}
  123. {})]
  124. (content/content page-name
  125. {:hiccup ref-hiccup}))])]]))))
  126. (rum/defcs unlinked-references-aux
  127. < rum/reactive db-mixins/query
  128. {:will-mount (fn [state]
  129. (let [[page-name n-ref] (:rum/args state)
  130. ref-blocks (db/get-page-unlinked-references page-name)]
  131. (reset! n-ref (count ref-blocks))
  132. (assoc state ::ref-blocks ref-blocks)))}
  133. [state page-name n-ref]
  134. (let [ref-blocks (::ref-blocks state)]
  135. [:div.references-blocks
  136. (let [ref-hiccup (block/->hiccup ref-blocks
  137. {:id (str page-name "-unlinked-")
  138. :ref? true
  139. :group-by-page? true
  140. :editor-box editor/box}
  141. {})]
  142. (content/content page-name
  143. {:hiccup ref-hiccup}))]))
  144. (rum/defcs unlinked-references < rum/reactive
  145. (rum/local nil ::n-ref)
  146. [state page-name]
  147. (let [n-ref (get state ::n-ref)]
  148. (when page-name
  149. (let [page-name (string/lower-case page-name)]
  150. [:div.references.mt-6.flex-1.flex-row
  151. [:div.content.flex-1
  152. (ui/foldable
  153. [:h2.font-bold {:style {:opacity "0.3"}}
  154. (if @n-ref
  155. (str @n-ref " Unlinked Reference" (if (> @n-ref 1)
  156. "s"))
  157. "Unlinked References")]
  158. (fn [] (unlinked-references-aux page-name n-ref))
  159. true)]]))))