mirror of https://github.com/logseq/logseq
Merge remote-tracking branch 'upstream/master' into whiteboards
commit
3a732aa4e2
|
@ -2163,9 +2163,10 @@
|
|||
[:div.more (ui/icon "dots-circle-horizontal" {:style {:fontSize 16}})])]])
|
||||
|
||||
(rum/defcs block-content-or-editor < rum/reactive
|
||||
(rum/local true :hide-block-refs?)
|
||||
(rum/local true ::hide-block-refs?)
|
||||
[state config {:block/keys [uuid format] :as block} edit-input-id block-id heading-level edit? hide-block-refs-count?]
|
||||
(let [*hide-block-refs? (get state :hide-block-refs?)
|
||||
(let [*hide-block-refs? (get state ::hide-block-refs?)
|
||||
hide-block-refs? @*hide-block-refs?
|
||||
editor-box (get config :editor-box)
|
||||
editor-id (str "editor-" edit-input-id)
|
||||
slide? (:slide? config)
|
||||
|
@ -2222,7 +2223,7 @@
|
|||
|
||||
(block-refs-count block *hide-block-refs?)])]
|
||||
|
||||
(when (and (not @*hide-block-refs?) (> refs-count 0))
|
||||
(when (and (not hide-block-refs?) (> refs-count 0))
|
||||
(let [refs-cp (state/get-component :block/linked-references)]
|
||||
(refs-cp uuid)))]))))
|
||||
|
||||
|
@ -2468,9 +2469,7 @@
|
|||
*navigating-block (get state ::navigating-block)
|
||||
navigating-block (rum/react *navigating-block)
|
||||
navigated? (and (not= (:block/uuid block) navigating-block) navigating-block)
|
||||
block (if (or navigated?
|
||||
custom-query?
|
||||
(and ref? (:block/uuid config)))
|
||||
block (if navigated?
|
||||
(let [block (db/pull [:block/uuid navigating-block])
|
||||
blocks (db/get-paginated-blocks repo (:db/id block)
|
||||
{:scoped-block-id (:db/id block)})
|
||||
|
@ -2613,7 +2612,7 @@
|
|||
(let [repo (state/get-current-repo)
|
||||
ref? (:ref? config)
|
||||
custom-query? (boolean (:custom-query? config))]
|
||||
(if (and ref? (not custom-query?) (not (:ref-query-child? config)))
|
||||
(if (and (or ref? custom-query?) (not (:ref-query-child? config)))
|
||||
(ui/lazy-visible
|
||||
(fn [] (block-container-inner state repo config block)))
|
||||
(block-container-inner state repo config block))))
|
||||
|
@ -2997,7 +2996,8 @@
|
|||
(ui/block-error "Query Error:" {:content (:query q)})
|
||||
(ui/lazy-visible
|
||||
(fn [] (custom-query* config q))
|
||||
{:debug-id q})))
|
||||
{:debug-id q
|
||||
:trigger-once? false})))
|
||||
|
||||
(defn admonition
|
||||
[config type result]
|
||||
|
@ -3344,7 +3344,7 @@
|
|||
(assoc state
|
||||
::initial-block first-block
|
||||
::navigating-block (atom (:block/uuid first-block)))))}
|
||||
[state blocks config]
|
||||
[state block config]
|
||||
(let [repo (state/get-current-repo)
|
||||
*navigating-block (::navigating-block state)
|
||||
navigating-block (rum/react *navigating-block)
|
||||
|
@ -3357,10 +3357,10 @@
|
|||
(let [block navigating-block-entity]
|
||||
(db/get-paginated-blocks repo (:db/id block)
|
||||
{:scoped-block-id (:db/id block)}))
|
||||
blocks)]
|
||||
[block])]
|
||||
[:div
|
||||
(when (:breadcrumb-show? config)
|
||||
(breadcrumb config (state/get-current-repo) navigating-block
|
||||
(breadcrumb config (state/get-current-repo) (or navigating-block (:block/uuid block))
|
||||
{:show-page? false
|
||||
:navigating-block *navigating-block}))
|
||||
(blocks-container blocks (assoc config
|
||||
|
@ -3375,8 +3375,7 @@
|
|||
(cond-> option
|
||||
(:document/mode? config) (assoc :class "doc-mode"))
|
||||
(cond
|
||||
(and (or (:ref? config) (:custom-query? config))
|
||||
(:group-by-page? config))
|
||||
(and (:custom-query? config) (:group-by-page? config))
|
||||
[:div.flex.flex-col
|
||||
(let [blocks (sort-by (comp :block/journal-day first) > blocks)]
|
||||
(for [[page blocks] blocks]
|
||||
|
@ -3384,8 +3383,7 @@
|
|||
(fn []
|
||||
(let [alias? (:block/alias? page)
|
||||
page (db/entity (:db/id page))
|
||||
blocks (tree/non-consecutive-blocks->vec-tree blocks)
|
||||
parent-blocks (group-by :block/parent blocks)]
|
||||
blocks' (tree/non-consecutive-blocks->vec-tree blocks)]
|
||||
[:div.my-2 (cond-> {:key (str "page-" (:db/id page))}
|
||||
(:ref? config)
|
||||
(assoc :class "color-level px-2 sm:px-7 py-2 rounded"))
|
||||
|
@ -3393,11 +3391,34 @@
|
|||
[:div
|
||||
(page-cp config page)
|
||||
(when alias? [:span.text-sm.font-medium.opacity-50 " Alias"])]
|
||||
(for [[parent blocks] parent-blocks]
|
||||
(for [block blocks']
|
||||
(rum/with-key
|
||||
(breadcrumb-with-container blocks config)
|
||||
(:db/id parent)))
|
||||
{:debug-id page})])))))]
|
||||
(breadcrumb-with-container block config)
|
||||
(:db/id block)))
|
||||
{:debug-id page
|
||||
:trigger-once? false})])))))]
|
||||
|
||||
(and (:ref? config) (:group-by-page? config))
|
||||
[:div.flex.flex-col
|
||||
(let [blocks (sort-by (comp :block/journal-day first) > blocks)]
|
||||
(for [[page parent-blocks] blocks]
|
||||
(ui/lazy-visible
|
||||
(fn []
|
||||
(let [alias? (:block/alias? page)
|
||||
page (db/entity (:db/id page))]
|
||||
[:div.my-2 (cond-> {:key (str "page-" (:db/id page))}
|
||||
(:ref? config)
|
||||
(assoc :class "color-level px-2 sm:px-7 py-2 rounded"))
|
||||
(ui/foldable
|
||||
[:div
|
||||
(page-cp config page)
|
||||
(when alias? [:span.text-sm.font-medium.opacity-50 " Alias"])]
|
||||
(for [block parent-blocks]
|
||||
(let [block' (update block :block/children tree/non-consecutive-blocks->vec-tree)]
|
||||
(rum/with-key
|
||||
(breadcrumb-with-container block' config)
|
||||
(:db/id block'))))
|
||||
{:debug-id page})])))))]
|
||||
|
||||
(and (:group-by-page? config)
|
||||
(vector? (first blocks)))
|
||||
|
|
|
@ -59,7 +59,8 @@
|
|||
(blocks-cp repo page)
|
||||
(ui/lazy-visible
|
||||
(fn [] (blocks-cp repo page))
|
||||
{:debug-id (str "journal-blocks " page)}))
|
||||
{:trigger-once? false
|
||||
:debug-id (str "journal-blocks " page)}))
|
||||
|
||||
{})
|
||||
|
||||
|
|
|
@ -433,7 +433,7 @@
|
|||
(tagged-pages repo page-name))
|
||||
|
||||
;; referenced blocks
|
||||
(when-not whiteboard?
|
||||
(when-not (or block? whiteboard?)
|
||||
[:div {:key "page-references"}
|
||||
(rum/with-key
|
||||
(reference/references route-page-name)
|
||||
|
|
|
@ -10,7 +10,8 @@
|
|||
[frontend.util.property :as property]
|
||||
[frontend.format.block :as block]
|
||||
[medley.core :as medley]
|
||||
[rum.core :as rum]))
|
||||
[rum.core :as rum]
|
||||
[frontend.modules.outliner.tree :as tree]))
|
||||
|
||||
;; TODO: extract to table utils
|
||||
(defn- sort-result-by
|
||||
|
@ -82,7 +83,8 @@
|
|||
(rum/local false ::select?)
|
||||
[state config current-block result {:keys [page?]} map-inline page-cp ->elem inline-text]
|
||||
(when current-block
|
||||
(let [p-sort-by (keyword (get-in current-block [:block/properties :query-sort-by]))
|
||||
(let [result (tree/filter-top-level-blocks result)
|
||||
p-sort-by (keyword (get-in current-block [:block/properties :query-sort-by]))
|
||||
p-desc? (get-in current-block [:block/properties :query-sort-desc])
|
||||
select? (get state ::select?)
|
||||
*sort-by-item (get state ::sort-by-item)
|
||||
|
|
|
@ -13,19 +13,49 @@
|
|||
[frontend.state :as state]
|
||||
[frontend.ui :as ui]
|
||||
[frontend.util :as util]
|
||||
[rum.core :as rum]))
|
||||
[rum.core :as rum]
|
||||
[frontend.modules.outliner.tree :as tree]))
|
||||
|
||||
(defn- frequencies-sort
|
||||
[references]
|
||||
(sort-by second #(> %1 %2) references))
|
||||
|
||||
(defn filtered-refs
|
||||
[page-name filters filters-atom filtered-references]
|
||||
[:div.flex.gap-1.flex-wrap
|
||||
(for [[ref-name ref-count] filtered-references]
|
||||
(when ref-name
|
||||
(let [lc-reference (string/lower-case ref-name)]
|
||||
(ui/button
|
||||
[:span
|
||||
ref-name
|
||||
(when ref-count [:sup " " ref-count])]
|
||||
:on-click (fn [e]
|
||||
(swap! filters-atom #(if (nil? (get filters lc-reference))
|
||||
(assoc % lc-reference (not (.-shiftKey e)))
|
||||
(dissoc % lc-reference)))
|
||||
(page-handler/save-filter! page-name @filters-atom))
|
||||
:small? true
|
||||
:intent "link"
|
||||
:key ref-name))))])
|
||||
|
||||
(rum/defcs filter-dialog-inner < rum/reactive (rum/local "" ::filterSearch)
|
||||
[state filters-atom _close-fn references page-name]
|
||||
[state filters-atom *references page-name]
|
||||
(let [filter-search (get state ::filterSearch)
|
||||
references (rum/react *references)
|
||||
filtered-references (frequencies-sort
|
||||
(if (= @filter-search "")
|
||||
references
|
||||
(search/fuzzy-search references @filter-search :limit 500 :extract-fn first)))]
|
||||
(search/fuzzy-search references @filter-search :limit 500 :extract-fn first)))
|
||||
filters (rum/react filters-atom)
|
||||
includes (keep (fn [[page include?]]
|
||||
(let [page' (model-db/get-page-original-name page)]
|
||||
(when include? [page'])))
|
||||
filters)
|
||||
excludes (keep (fn [[page include?]]
|
||||
(let [page' (model-db/get-page-original-name page)]
|
||||
(when-not include? [page'])))
|
||||
filters)]
|
||||
[:div.ls-filters.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
|
||||
|
@ -34,6 +64,16 @@
|
|||
[: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 filters)
|
||||
[:div.cp__filters.mb-4.ml-2
|
||||
(when (seq includes)
|
||||
[:div.flex.flex-row.flex-wrap.center-items
|
||||
[:div.mr-1.font-medium.py-1 "Includes: "]
|
||||
(filtered-refs page-name filters filters-atom includes)])
|
||||
(when (seq excludes)
|
||||
[:div.flex.flex-row.flex-wrap
|
||||
[:div.mr-1.font-medium.py-1 "Excludes: " ]
|
||||
(filtered-refs page-name filters filters-atom excludes)])])
|
||||
[:div.cp__filters-input-panel.flex
|
||||
(ui/icon "search")
|
||||
[:input.cp__filters-input.w-full
|
||||
|
@ -41,30 +81,17 @@
|
|||
:auto-focus true
|
||||
:on-change (fn [e]
|
||||
(reset! filter-search (util/evalue e)))}]]
|
||||
(when (seq filtered-references)
|
||||
(let [filters (rum/react filters-atom)]
|
||||
[:div.mt-5.sm:mt-4.sm:flex.sm.gap-1.flex-wrap
|
||||
(for [[ref-name ref-count] filtered-references]
|
||||
(when ref-name
|
||||
(let [lc-reference (string/lower-case ref-name)
|
||||
filtered (get filters lc-reference)
|
||||
color (condp = filtered
|
||||
true "text-green-400"
|
||||
false "text-red-400"
|
||||
nil)]
|
||||
[:button.border.rounded.px-1.mb-1.mr-1.select-none
|
||||
{:key ref-name :class color :style {:border-color "currentColor"}
|
||||
:on-click (fn [e]
|
||||
(swap! filters-atom #(if (nil? (get filters lc-reference))
|
||||
(assoc % lc-reference (not (.-shiftKey e)))
|
||||
(dissoc % lc-reference)))
|
||||
(page-handler/save-filter! page-name @filters-atom))}
|
||||
ref-name [:sub " " ref-count]])))]))]))
|
||||
(let [all-filters (set (keys filters))
|
||||
refs (remove (fn [[page _]] (all-filters (util/page-name-sanity-lc page)))
|
||||
filtered-references)]
|
||||
(when (seq refs)
|
||||
[:div.mt-4
|
||||
(filtered-refs page-name filters filters-atom refs)]))]))
|
||||
|
||||
(defn filter-dialog
|
||||
[filters-atom references page-name]
|
||||
(fn [close-fn]
|
||||
(filter-dialog-inner filters-atom close-fn references page-name)))
|
||||
[filters-atom *references page-name]
|
||||
(fn []
|
||||
(filter-dialog-inner filters-atom *references page-name)))
|
||||
|
||||
(rum/defc block-linked-references < rum/reactive db-mixins/query
|
||||
[block-id]
|
||||
|
@ -80,16 +107,10 @@
|
|||
(content/content block-id
|
||||
{:hiccup ref-hiccup})]))
|
||||
|
||||
(rum/defc references-inner < rum/reactive db-mixins/query
|
||||
[page-name block-id filters *filtered-ref-blocks ref-pages]
|
||||
(rum/defc references-inner
|
||||
[page-name filters filtered-ref-blocks]
|
||||
[:div.references-blocks
|
||||
(let [ref-blocks (if block-id
|
||||
(db/get-block-referenced-blocks block-id)
|
||||
(db/get-page-referenced-blocks page-name))
|
||||
filtered-ref-blocks (if block-id
|
||||
ref-blocks
|
||||
(block-handler/get-filtered-ref-blocks ref-blocks filters ref-pages))
|
||||
ref-hiccup (block/->hiccup filtered-ref-blocks
|
||||
(let [ref-hiccup (block/->hiccup filtered-ref-blocks
|
||||
{:id page-name
|
||||
:ref? true
|
||||
:breadcrumb-show? true
|
||||
|
@ -97,24 +118,21 @@
|
|||
:editor-box editor/box
|
||||
:filters filters}
|
||||
{})]
|
||||
(reset! *filtered-ref-blocks filtered-ref-blocks)
|
||||
(content/content page-name {:hiccup ref-hiccup}))])
|
||||
|
||||
(rum/defc references-cp
|
||||
[repo page-entity page-name block-id filters-atom filter-state n-ref]
|
||||
[page-name filters filters-atom filter-state total filter-n filtered-ref-blocks *ref-pages]
|
||||
(let [threshold (state/get-linked-references-collapsed-threshold)
|
||||
default-collapsed? (>= n-ref threshold)
|
||||
filters (when (seq filter-state)
|
||||
(-> (group-by second filter-state)
|
||||
(update-vals #(map first %))))
|
||||
*filtered-ref-blocks (atom nil)
|
||||
*collapsed? (atom nil)
|
||||
ref-pages (when-not block-id
|
||||
(block-handler/get-blocks-refed-pages repo page-entity))]
|
||||
default-collapsed? (>= total threshold)
|
||||
*collapsed? (atom nil)]
|
||||
(ui/foldable
|
||||
[:div.flex.flex-row.flex-1.justify-between.items-center
|
||||
[:h2.font-bold.opacity-50 (str n-ref " Linked Reference"
|
||||
(when (> n-ref 1) "s"))]
|
||||
[:h2.font-bold.opacity-50 (str
|
||||
(when (seq filters)
|
||||
(str filter-n " of "))
|
||||
total
|
||||
" Linked Reference"
|
||||
(when (> total 1) "s"))]
|
||||
[:a.filter.fade-link
|
||||
{:title "Filter"
|
||||
:on-mouse-over (fn [_e]
|
||||
|
@ -124,10 +142,8 @@
|
|||
:on-mouse-down (fn [e]
|
||||
(util/stop-propagation e))
|
||||
:on-click (fn []
|
||||
(let [ref-pages (map :block/original-name ref-pages)
|
||||
references (frequencies ref-pages)]
|
||||
(state/set-modal! (filter-dialog filters-atom references page-name)
|
||||
{:center? true})))}
|
||||
(state/set-modal! (filter-dialog filters-atom *ref-pages page-name)
|
||||
{:center? true}))}
|
||||
(ui/icon "filter" {:class (cond
|
||||
(empty? filter-state)
|
||||
""
|
||||
|
@ -140,36 +156,81 @@
|
|||
:style {:fontSize 24}})]]
|
||||
|
||||
(fn []
|
||||
(references-inner page-name block-id filters *filtered-ref-blocks ref-pages))
|
||||
(references-inner page-name filters filtered-ref-blocks))
|
||||
|
||||
{:default-collapsed? default-collapsed?
|
||||
:title-trigger? true
|
||||
:init-collapsed (fn [collapsed-atom]
|
||||
(reset! *collapsed? collapsed-atom))})))
|
||||
|
||||
(defn- get-filtered-children
|
||||
[block parent->blocks]
|
||||
(let [children (get parent->blocks (:db/id block))]
|
||||
(set
|
||||
(loop [blocks children
|
||||
result (vec children)]
|
||||
(if (empty? blocks)
|
||||
result
|
||||
(let [fb (first blocks)
|
||||
children (get parent->blocks (:db/id fb))]
|
||||
(recur
|
||||
(concat children (rest blocks))
|
||||
(conj result fb))))))))
|
||||
|
||||
(rum/defcs references* < rum/reactive db-mixins/query
|
||||
(rum/local nil ::ref-pages)
|
||||
{:init (fn [state]
|
||||
(let [page-name (first (:rum/args state))
|
||||
filters (when page-name
|
||||
(atom (page-handler/get-filters (string/lower-case page-name))))]
|
||||
(atom (page-handler/get-filters (util/page-name-sanity-lc page-name))))]
|
||||
(assoc state ::filters filters)))}
|
||||
[state page-name]
|
||||
(when page-name
|
||||
(let [page-name (string/lower-case page-name)
|
||||
page-entity (db/entity [:block/name page-name])
|
||||
(let [page-name (util/page-name-sanity-lc page-name)
|
||||
*ref-pages (::ref-pages state)
|
||||
repo (state/get-current-repo)
|
||||
filters-atom (get state ::filters)
|
||||
filter-state (rum/react filters-atom)
|
||||
block-id (parse-uuid page-name)
|
||||
id (if block-id
|
||||
(:db/id (db/pull [:block/uuid block-id]))
|
||||
(:db/id page-entity))
|
||||
n-ref (model-db/get-linked-references-count id)]
|
||||
(when (or (seq filter-state) (> n-ref 0))
|
||||
ref-blocks (db/get-page-referenced-blocks page-name)
|
||||
page-id (:db/id (db/entity repo [:block/name page-name]))
|
||||
aliases (db/page-alias-set repo page-name)
|
||||
aliases-exclude-self (set (remove #{page-id} aliases))
|
||||
top-level-blocks (filter (fn [b] (some aliases (set (map :db/id (:block/refs b))))) ref-blocks)
|
||||
top-level-blocks-ids (set (map :db/id top-level-blocks))
|
||||
filters (when (seq filter-state)
|
||||
(-> (group-by second filter-state)
|
||||
(update-vals #(map first %))))
|
||||
filtered-ref-blocks (block-handler/filter-blocks ref-blocks filters)
|
||||
total (count top-level-blocks)
|
||||
filtered-top-blocks (filter (fn [b] (top-level-blocks-ids (:db/id b))) filtered-ref-blocks)
|
||||
filter-n (count filtered-top-blocks)
|
||||
parent->blocks (group-by (fn [x] (:db/id (x :block/parent))) filtered-ref-blocks)
|
||||
result (->> (group-by :block/page filtered-top-blocks)
|
||||
(map (fn [[page blocks]]
|
||||
(let [blocks (sort-by (fn [b] (not= (:db/id page) (:db/id (:block/parent b)))) blocks)
|
||||
result (map (fn [block]
|
||||
(let [filtered-children (get-filtered-children block parent->blocks)
|
||||
refs (when-not (contains? top-level-blocks-ids (:db/id (:block/parent block)))
|
||||
(block-handler/get-blocks-refed-pages aliases (cons block filtered-children)))
|
||||
block' (assoc (tree/block-entity->map block) :block/children filtered-children)]
|
||||
[block' refs])) blocks)
|
||||
blocks' (map first result)
|
||||
page' (if (contains? aliases-exclude-self (:db/id page))
|
||||
{:db/id (:db/id page)
|
||||
:block/alias? true
|
||||
:block/journal-day (:block/journal-day page)}
|
||||
page)]
|
||||
[[page' blocks'] (mapcat second result)]))))
|
||||
filtered-ref-blocks' (map first result)
|
||||
ref-pages (->>
|
||||
(mapcat second result)
|
||||
(map :block/original-name)
|
||||
frequencies)]
|
||||
(reset! *ref-pages ref-pages)
|
||||
(when (or (seq filter-state) (> filter-n 0))
|
||||
[:div.references.flex-1.flex-row
|
||||
[:div.content.pt-6
|
||||
(references-cp repo page-entity page-name block-id
|
||||
filters-atom filter-state n-ref)]]))))
|
||||
(references-cp page-name filters filters-atom filter-state total filter-n filtered-ref-blocks' *ref-pages)]]))))
|
||||
|
||||
(rum/defc references
|
||||
[page-name]
|
||||
|
@ -178,8 +239,7 @@
|
|||
(ui/lazy-visible
|
||||
(fn []
|
||||
(references* page-name))
|
||||
{:trigger-once? true
|
||||
:debug-id (str page-name " references")})))
|
||||
{:debug-id (str page-name " references")})))
|
||||
|
||||
(rum/defcs unlinked-references-aux
|
||||
< rum/reactive db-mixins/query
|
||||
|
|
|
@ -10,3 +10,11 @@
|
|||
padding-left: 0.5rem;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.references-blocks .breadcrumb {
|
||||
margin-left: 1.5rem;
|
||||
}
|
||||
|
||||
.ls-filters {
|
||||
max-width: 704px;
|
||||
}
|
||||
|
|
|
@ -1206,7 +1206,8 @@
|
|||
(->>
|
||||
(react/q repo
|
||||
[:frontend.db.react/refs page-id]
|
||||
{:query-fn (fn []
|
||||
{:use-cache? false
|
||||
:query-fn (fn []
|
||||
(let [entities (mapcat (fn [id]
|
||||
(:block/_path-refs (db-utils/entity id))) pages)
|
||||
blocks (map (fn [e] {:block/parent (:block/parent e)
|
||||
|
@ -1217,34 +1218,7 @@
|
|||
nil)
|
||||
react
|
||||
:entities
|
||||
(remove (fn [block] (= page-id (:db/id (:block/page block)))))
|
||||
db-utils/group-by-page
|
||||
(map (fn [[k blocks]]
|
||||
(let [k (if (contains? aliases (:db/id k))
|
||||
{:db/id (:db/id k)
|
||||
:block/alias? true
|
||||
:block/journal-day (:block/journal-day k)}
|
||||
k)]
|
||||
[k blocks])))))))))
|
||||
|
||||
(defn get-linked-references-count
|
||||
[id]
|
||||
(when-let [block (db-utils/entity id)]
|
||||
(let [repo (state/get-current-repo)
|
||||
page? (:block/name block)
|
||||
result (if page?
|
||||
(let [pages (page-alias-set repo (:block/name block))]
|
||||
@(react/q repo [:frontend.db.react/refs-count id] {}
|
||||
'[:find [?block ...]
|
||||
:in $ [?ref-page ...] ?id
|
||||
:where
|
||||
[?block :block/refs ?ref-page]
|
||||
[?block :block/page ?p]
|
||||
[(not= ?p ?id)]]
|
||||
pages
|
||||
id))
|
||||
(:block/_refs block))]
|
||||
(count result))))
|
||||
(remove (fn [block] (= page-id (:db/id (:block/page block)))))))))))
|
||||
|
||||
(defn get-date-scheduled-or-deadlines
|
||||
[journal-title]
|
||||
|
|
|
@ -33,10 +33,6 @@
|
|||
;; ::refs
|
||||
;; get BLOCKS referencing PAGE or BLOCK
|
||||
(s/def ::refs (s/tuple #(= ::refs %) int?))
|
||||
;; ::refs-count
|
||||
;; get refs count
|
||||
(s/def ::refs-count int?)
|
||||
|
||||
;; custom react-query
|
||||
(s/def ::custom any?)
|
||||
|
||||
|
@ -46,7 +42,6 @@
|
|||
:journals ::journals
|
||||
:page<-pages ::page<-pages
|
||||
:refs ::refs
|
||||
:refs-count ::refs-count
|
||||
:custom ::custom))
|
||||
|
||||
(s/def ::affected-keys (s/coll-of ::react-query-keys))
|
||||
|
@ -240,7 +235,10 @@
|
|||
(let [blocks (->> (filter (fn [datom] (contains? #{:block/left :block/parent :block/page} (:a datom))) tx-data)
|
||||
(map :v)
|
||||
(distinct))
|
||||
refs (->> (filter (fn [datom] (contains? #{:block/refs :block/path-refs} (:a datom))) tx-data)
|
||||
refs (->> (filter (fn [datom]
|
||||
(when (contains? #{:block/refs :block/path-refs} (:a datom))
|
||||
(not= (:v datom)
|
||||
(:db/id (:block/page (db-utils/entity (:e datom))))))) tx-data)
|
||||
(map :v)
|
||||
(distinct))
|
||||
other-blocks (->> (filter (fn [datom] (= "block" (namespace (:a datom)))) tx-data)
|
||||
|
@ -259,10 +257,9 @@
|
|||
(:db/id (:block/page block)))
|
||||
blocks [[::block (:db/id block)]]
|
||||
path-refs (:block/path-refs block)
|
||||
path-refs' (mapcat (fn [ref]
|
||||
[
|
||||
;; [::refs-count (:db/id ref)]
|
||||
[::refs (:db/id ref)]]) path-refs)
|
||||
path-refs' (keep (fn [ref]
|
||||
(when-not (= (:db/id ref) page-id)
|
||||
[::refs (:db/id ref)])) path-refs)
|
||||
page-blocks (when page-id
|
||||
[[::page-blocks page-id]])]
|
||||
(concat blocks page-blocks path-refs')))
|
||||
|
@ -270,9 +267,7 @@
|
|||
|
||||
(mapcat
|
||||
(fn [ref]
|
||||
[
|
||||
;; [::refs-count (:db/id entity)]
|
||||
[::refs ref]])
|
||||
[[::refs ref]])
|
||||
refs)
|
||||
|
||||
(when-let [current-page-id (:db/id (get-current-page))]
|
||||
|
|
|
@ -13,9 +13,7 @@
|
|||
[frontend.state :as state]
|
||||
[frontend.util :as util]
|
||||
[goog.dom :as gdom]
|
||||
[logseq.graph-parser.block :as gp-block]
|
||||
[frontend.modules.instrumentation.posthog :as posthog]
|
||||
[cljs-bean.core :as bean]))
|
||||
[logseq.graph-parser.block :as gp-block]))
|
||||
|
||||
;; Fns
|
||||
|
||||
|
@ -250,48 +248,31 @@
|
|||
(reset! *swipe nil))
|
||||
|
||||
(defn get-blocks-refed-pages
|
||||
[repo page-entity]
|
||||
(let [pages (db-model/page-alias-set repo (:block/name page-entity))
|
||||
refs (->> pages
|
||||
(mapcat (fn [id] (:block/_path-refs (db/entity id))))
|
||||
(mapcat (fn [b] (conj (:block/path-refs b) (:block/page b))))
|
||||
(remove (fn [r] (= (:db/id page-entity) (:db/id r)))))]
|
||||
[aliases ref-blocks]
|
||||
(let [refs (->> (mapcat (fn [b] (conj (:block/path-refs b) (:block/page b))) ref-blocks)
|
||||
distinct
|
||||
(remove #(aliases (:db/id %))))]
|
||||
(keep (fn [ref]
|
||||
(when (:block/name ref)
|
||||
{:db/id (:db/id ref)
|
||||
:block/name (:block/name ref)
|
||||
:block/original-name (:block/original-name ref)})) refs)))
|
||||
|
||||
(defn- filter-blocks
|
||||
[ref-blocks filters ref-pages]
|
||||
(let [ref-pages (distinct ref-pages)]
|
||||
(if (empty? filters)
|
||||
ref-blocks
|
||||
(let [ref-pages (zipmap (map :block/name ref-pages) (map :db/id ref-pages))
|
||||
exclude-ids (->> (keep (fn [page] (get ref-pages page)) (get filters false))
|
||||
(set))
|
||||
include-ids (->> (keep (fn [page] (get ref-pages page)) (get filters true))
|
||||
(set))]
|
||||
(cond->> ref-blocks
|
||||
(seq exclude-ids)
|
||||
(remove (fn [block]
|
||||
(let [ids (set (map :db/id (:block/path-refs block)))]
|
||||
(seq (set/intersection exclude-ids ids)))))
|
||||
(defn filter-blocks
|
||||
[ref-blocks filters]
|
||||
(if (empty? filters)
|
||||
ref-blocks
|
||||
(let [exclude-ids (->> (keep (fn [page] (:db/id (db/entity [:block/name (util/page-name-sanity-lc page)]))) (get filters false))
|
||||
(set))
|
||||
include-ids (->> (keep (fn [page] (:db/id (db/entity [:block/name (util/page-name-sanity-lc page)]))) (get filters true))
|
||||
(set))]
|
||||
(cond->> ref-blocks
|
||||
(seq exclude-ids)
|
||||
(remove (fn [block]
|
||||
(let [ids (set (map :db/id (:block/path-refs block)))]
|
||||
(seq (set/intersection exclude-ids ids)))))
|
||||
|
||||
(seq include-ids)
|
||||
(remove (fn [block]
|
||||
(let [ids (set (map :db/id (:block/path-refs block)))]
|
||||
(empty? (set/intersection include-ids ids))))))))))
|
||||
|
||||
(defn get-filtered-ref-blocks
|
||||
[ref-blocks filters ref-pages]
|
||||
(try
|
||||
(let [ref-blocks' (doall (mapcat second ref-blocks))
|
||||
filtered-blocks (filter-blocks ref-blocks' filters ref-pages)]
|
||||
(group-by :block/page filtered-blocks))
|
||||
(catch :default e
|
||||
(js/console.error e)
|
||||
(posthog/capture :bad-ref-blocks (bean/->js
|
||||
{:ref-blocks ref-blocks
|
||||
:filters filters
|
||||
:ref-pages ref-pages})))))
|
||||
(seq include-ids)
|
||||
(filter (fn [block]
|
||||
(let [ids (set (map :db/id (:block/path-refs block)))]
|
||||
(set/subset? include-ids ids))))))))
|
||||
|
|
|
@ -757,7 +757,8 @@
|
|||
(remove nil?))]
|
||||
(doseq [id ids]
|
||||
(let [block (db/pull [:block/uuid id])]
|
||||
(set-marker block))))))
|
||||
(when (not-empty (:block/content block))
|
||||
(set-marker block)))))))
|
||||
|
||||
(defn cycle-todo!
|
||||
[]
|
||||
|
|
|
@ -21,12 +21,9 @@
|
|||
;; 1. For each changed block, new-refs = its page + :block/refs + parents :block/refs
|
||||
;; 2. Its children' block/path-refs might need to be updated too.
|
||||
(defn compute-block-path-refs
|
||||
[tx-meta blocks]
|
||||
[{:keys [tx-meta]} blocks]
|
||||
(let [repo (state/get-current-repo)
|
||||
blocks (remove :block/name blocks)
|
||||
blocks (if (= (:outliner-op tx-meta) :insert-blocks)
|
||||
(butlast blocks)
|
||||
blocks)]
|
||||
blocks (remove :block/name blocks)]
|
||||
(when (:outliner-op tx-meta)
|
||||
(when (react/path-refs-need-recalculated? tx-meta)
|
||||
(let [*computed-ids (atom #{})]
|
||||
|
@ -44,13 +41,15 @@
|
|||
refs-changed? (not= old-refs new-refs)
|
||||
children (db-model/get-block-children-ids repo (:block/uuid block))
|
||||
children-refs (map (fn [id]
|
||||
{:db/id (:db/id (db/entity [:block/uuid id]))
|
||||
:block/path-refs (concat
|
||||
(map :db/id (:block/path-refs (db/entity id)))
|
||||
new-refs)}) children)]
|
||||
(let [entity (db/entity [:block/uuid id])]
|
||||
{:db/id (:db/id entity)
|
||||
:block/path-refs (concat
|
||||
(map :db/id (:block/path-refs entity))
|
||||
new-refs)})) children)]
|
||||
(swap! *computed-ids set/union (set (cons (:block/uuid block) children)))
|
||||
(util/concat-without-nil
|
||||
[(when (and refs-changed? (seq new-refs))
|
||||
[(when (and (seq new-refs)
|
||||
refs-changed?)
|
||||
{:db/id (:db/id block)
|
||||
:block/path-refs new-refs})]
|
||||
children-refs))))
|
||||
|
@ -66,7 +65,7 @@
|
|||
repo (state/get-current-repo)
|
||||
refs-tx (util/profile
|
||||
"Compute path refs: "
|
||||
(set (compute-block-path-refs (:tx-meta tx-report) blocks)))
|
||||
(set (compute-block-path-refs tx-report blocks)))
|
||||
truncate-refs-tx (map (fn [m] [:db/retract (:db/id m) :block/path-refs]) refs-tx)
|
||||
tx (util/concat-without-nil truncate-refs-tx refs-tx)
|
||||
tx-report' (if (seq tx)
|
||||
|
|
|
@ -84,20 +84,29 @@
|
|||
(assoc root' :block/children children)
|
||||
root')))
|
||||
|
||||
(defn block-entity->map
|
||||
[e]
|
||||
{:db/id (:db/id e)
|
||||
:block/uuid (:block/uuid e)
|
||||
:block/parent {:db/id (:db/id (:block/parent e))}
|
||||
:block/left {:db/id (:db/id (:block/left e))}
|
||||
:block/page (:block/page e)
|
||||
:block/refs (:block/refs e)})
|
||||
|
||||
(defn filter-top-level-blocks
|
||||
[blocks]
|
||||
(let [id->blocks (zipmap (map :db/id blocks) blocks)]
|
||||
(filter #(nil?
|
||||
(id->blocks
|
||||
(:db/id (:block/parent (id->blocks (:db/id %)))))) blocks)))
|
||||
|
||||
(defn non-consecutive-blocks->vec-tree
|
||||
"`blocks` need to be in the same page."
|
||||
[blocks]
|
||||
(let [blocks (map (fn [e] {:db/id (:db/id e)
|
||||
:block/uuid (:block/uuid e)
|
||||
:block/parent {:db/id (:db/id (:block/parent e))}
|
||||
:block/left {:db/id (:db/id (:block/left e))}
|
||||
:block/page {:db/id (:db/id (:block/page e))}}) blocks)
|
||||
parent->children (group-by :block/parent blocks)
|
||||
id->blocks (zipmap (map :db/id blocks) blocks)
|
||||
top-level-blocks (filter #(nil?
|
||||
(id->blocks
|
||||
(:db/id (:block/parent (id->blocks (:db/id %)))))) blocks)
|
||||
top-level-blocks' (model/try-sort-by-left top-level-blocks (:block/parent (first top-level-blocks)))]
|
||||
(let [blocks (map block-entity->map blocks)
|
||||
top-level-blocks (filter-top-level-blocks blocks)
|
||||
top-level-blocks' (model/try-sort-by-left top-level-blocks (:block/parent (first top-level-blocks)))
|
||||
parent->children (group-by :block/parent blocks)]
|
||||
(map #(tree parent->children %) top-level-blocks')))
|
||||
|
||||
(defn- sort-blocks-aux
|
||||
|
|
|
@ -46,14 +46,16 @@
|
|||
|
||||
(defn normalize-user-keyname
|
||||
[k]
|
||||
(some-> k
|
||||
(util/safe-lower-case)
|
||||
(str/replace #";+" "semicolon")
|
||||
(str/replace #"=+" "equals")
|
||||
(str/replace #"~+" "dash")
|
||||
(str/replace "[" "open-square-bracket")
|
||||
(str/replace "]" "close-square-bracket")
|
||||
(str/replace "'" "single-quote")))
|
||||
(let [keynames {";" "semicolon"
|
||||
"=" "equals"
|
||||
"-" "dash"
|
||||
"[" "open-square-bracket"
|
||||
"]" "close-square-bracket"
|
||||
"'" "single-quote"}]
|
||||
(some-> k
|
||||
(util/safe-lower-case)
|
||||
(str/replace #"[;=-\[\]']" (fn [s]
|
||||
(get keynames s))))))
|
||||
|
||||
;; returns a vector to preserve order
|
||||
(defn binding-by-category [name]
|
||||
|
|
|
@ -147,7 +147,7 @@
|
|||
|
||||
(defn button
|
||||
[text & {:keys [background href class intent on-click small? large?]
|
||||
:or {small? false large? false}
|
||||
:or {small? false large? false}
|
||||
:as option}]
|
||||
(let [klass (when-not intent ".bg-indigo-600.hover:bg-indigo-700.focus:border-indigo-700.active:bg-indigo-700.text-center")
|
||||
klass (if background (string/replace klass "indigo" background) klass)
|
||||
|
@ -947,24 +947,17 @@
|
|||
([content-fn]
|
||||
(lazy-visible content-fn nil))
|
||||
([content-fn {:keys [trigger-once? _debug-id]
|
||||
:or {trigger-once? false}}]
|
||||
:or {trigger-once? true}}]
|
||||
(if (or (util/mobile?) (mobile-util/native-platform?))
|
||||
(content-fn)
|
||||
(let [[visible? set-visible!] (rum/use-state false)
|
||||
[last-changed-time set-last-changed-time!] (rum/use-state nil)
|
||||
inViewState (useInView #js {:rootMargin "100px"
|
||||
:triggerOnce trigger-once?
|
||||
:onChange (fn [in-view? entry]
|
||||
(let [self-top (.-top (.-boundingClientRect entry))
|
||||
time' (util/time-ms)]
|
||||
(when (and
|
||||
(or (and (not visible?) in-view?)
|
||||
;; hide only the components below the current top for better ux
|
||||
(and visible? (not in-view?) (> self-top 0)))
|
||||
(or (nil? last-changed-time)
|
||||
(and (some? last-changed-time)
|
||||
(> (- time' last-changed-time) 50))))
|
||||
(set-last-changed-time! time')
|
||||
(let [self-top (.-top (.-boundingClientRect entry))]
|
||||
(when (or (and (not visible?) in-view?)
|
||||
;; hide only the components below the current top for better ux
|
||||
(and visible? (not in-view?) (> self-top 0)))
|
||||
(set-visible! in-view?))))})
|
||||
ref (.-ref inViewState)]
|
||||
(lazy-visible-inner visible? content-fn ref)))))
|
||||
|
|
Loading…
Reference in New Issue