mirror of https://github.com/logseq/logseq
parent
60067cb817
commit
b4c4a5bd96
|
@ -15,7 +15,7 @@
|
|||
[frontend.modules.outliner.tree :as tree]))
|
||||
|
||||
;; Util fns
|
||||
;; ================
|
||||
;; ========
|
||||
(defn- attach-clock-property
|
||||
[result]
|
||||
(let [ks [:block/properties :clock-time]
|
||||
|
@ -27,8 +27,8 @@
|
|||
(map #(medley/dissoc-in % ks) result)
|
||||
result)))
|
||||
|
||||
(defn- sort-by-fn [sort-by-item item]
|
||||
(case sort-by-item
|
||||
(defn- sort-by-fn [sort-by-column item]
|
||||
(case sort-by-column
|
||||
:created-at
|
||||
(:block/created-at item)
|
||||
:updated-at
|
||||
|
@ -37,66 +37,48 @@
|
|||
(:block/content item)
|
||||
:page
|
||||
(:block/name item)
|
||||
(get-in item [:block/properties sort-by-item])))
|
||||
(get-in item [:block/properties sort-by-column])))
|
||||
|
||||
(defn- desc?
|
||||
[*desc? p-desc?]
|
||||
(cond
|
||||
(some? @*desc?)
|
||||
@*desc?
|
||||
(some? p-desc?)
|
||||
p-desc?
|
||||
:else
|
||||
true))
|
||||
|
||||
(defn- get-sort-state
|
||||
"Return current sort direction and column (item) being sorted, respectively
|
||||
:sort-desc? and :sort-by-item. :sort-by-item is nil if no sorting is to be
|
||||
done"
|
||||
[state current-block]
|
||||
(let [*sort-by-item (get state ::sort-by-item)
|
||||
*desc? (get state ::desc?)
|
||||
p-desc? (get-in current-block [:block/properties :query-sort-desc])
|
||||
desc? (desc? *desc? p-desc?)
|
||||
p-sort-by (keyword (get-in current-block [:block/properties :query-sort-by]))
|
||||
sort-by-item (or @*sort-by-item
|
||||
(some-> p-sort-by keyword)
|
||||
(if (query-dsl/query-contains-filter? (:block/content current-block) "sort-by")
|
||||
nil
|
||||
:updated-at))]
|
||||
{:sort-desc? desc?
|
||||
:sort-by-item sort-by-item}))
|
||||
|
||||
(defn- sort-result [result {:keys [sort-by-item sort-desc?]}]
|
||||
(if (some? sort-by-item)
|
||||
(defn- sort-result [result {:keys [sort-by-column sort-desc?]}]
|
||||
(if (some? sort-by-column)
|
||||
(let [comp (if sort-desc? > <)]
|
||||
(sort-by (fn [item]
|
||||
(block/normalize-block (sort-by-fn sort-by-item item)))
|
||||
(block/normalize-block (sort-by-fn sort-by-column item)))
|
||||
comp
|
||||
result))
|
||||
result))
|
||||
|
||||
;; Components and public fns
|
||||
;; =========================
|
||||
(defn- get-sort-state
|
||||
"Return current sort direction and column being sorted, respectively
|
||||
:sort-desc? and :sort-by-column. :sort-by-column is nil if no sorting is to be
|
||||
done"
|
||||
[current-block]
|
||||
(let [p-desc? (get-in current-block [:block/properties :query-sort-desc])
|
||||
desc? (if (some? p-desc?) p-desc? true)
|
||||
p-sort-by (keyword (get-in current-block [:block/properties :query-sort-by]))
|
||||
sort-by-column (or (some-> p-sort-by keyword)
|
||||
(if (query-dsl/query-contains-filter? (:block/content current-block) "sort-by")
|
||||
nil
|
||||
:updated-at))]
|
||||
{:sort-desc? desc?
|
||||
:sort-by-column sort-by-column}))
|
||||
|
||||
;; Components
|
||||
;; ==========
|
||||
(rum/defc sortable-title
|
||||
[title key state {:keys [sort-by-item sort-desc?]} block-id]
|
||||
(let [*sort-by-item (get state ::sort-by-item)
|
||||
*desc? (get state ::desc?)]
|
||||
[:th.whitespace-nowrap
|
||||
[:a {:on-click (fn []
|
||||
;; The two local state atom changes have no effect on
|
||||
;; preserving state. Consider deleting?
|
||||
(reset! *sort-by-item key)
|
||||
(swap! *desc? not)
|
||||
(editor-handler/set-block-property! block-id :query-sort-by (name key))
|
||||
(editor-handler/set-block-property! block-id :query-sort-desc (not sort-desc?)))}
|
||||
[:div.flex.items-center
|
||||
[:span.mr-1 title]
|
||||
(when (= sort-by-item key)
|
||||
[:span
|
||||
(if sort-desc? (svg/caret-down) (svg/caret-up))])]]]))
|
||||
[title column {:keys [sort-by-column sort-desc?]} block-id]
|
||||
[:th.whitespace-nowrap
|
||||
[:a {:on-click (fn []
|
||||
(editor-handler/set-block-property! block-id :query-sort-by (name column))
|
||||
(editor-handler/set-block-property! block-id :query-sort-desc (not sort-desc?)))}
|
||||
[:div.flex.items-center
|
||||
[:span.mr-1 title]
|
||||
(when (= sort-by-column column)
|
||||
[:span
|
||||
(if sort-desc? (svg/caret-down) (svg/caret-up))])]]])
|
||||
|
||||
(defn get-keys
|
||||
"Get keys for a query table result, which are the columns in a table"
|
||||
[result page?]
|
||||
(let [keys (->> (distinct (mapcat keys (map :block/properties result)))
|
||||
(remove (property/built-in-properties))
|
||||
|
@ -105,54 +87,56 @@
|
|||
keys (if page? (distinct (concat keys [:created-at :updated-at])) keys)]
|
||||
keys))
|
||||
|
||||
;; We refer to rows and columns in a table as keys and items.
|
||||
;; TODO: Rename key(s) naming as it conflict with core fns
|
||||
(defn- get-columns [current-block result {:keys [page?]}]
|
||||
(let [query-properties (some-> (get-in current-block [:block/properties :query-properties] "")
|
||||
(common-handler/safe-read-string "Parsing query properties failed"))
|
||||
columns (if (seq query-properties)
|
||||
query-properties
|
||||
(get-keys result page?))
|
||||
included-columns #{:created-at :updated-at}]
|
||||
(distinct
|
||||
(if (some included-columns columns)
|
||||
(concat (remove included-columns columns)
|
||||
(filter included-columns columns)
|
||||
included-columns)
|
||||
columns))))
|
||||
|
||||
;; Table rows are called items
|
||||
(rum/defcs result-table < rum/reactive
|
||||
(rum/local nil ::sort-by-item)
|
||||
(rum/local nil ::desc?)
|
||||
(rum/local false ::select?)
|
||||
[state config current-block result {:keys [page?]} map-inline page-cp ->elem inline-text]
|
||||
(when current-block
|
||||
(let [result (tree/filter-top-level-blocks result)
|
||||
select? (get state ::select?)
|
||||
sort-state (get-sort-state state current-block)
|
||||
;; remove templates
|
||||
result (remove (fn [b] (some? (get-in b [:block/properties :template]))) result)
|
||||
result (if page? result (attach-clock-property result))
|
||||
clock-time-total (when-not page?
|
||||
(->> (map #(get-in % [:block/properties :clock-time] 0) result)
|
||||
(apply +)))
|
||||
query-properties (some-> (get-in current-block [:block/properties :query-properties] "")
|
||||
(common-handler/safe-read-string "Parsing query properties failed"))
|
||||
keys (if (seq query-properties)
|
||||
query-properties
|
||||
(get-keys result page?))
|
||||
included-keys #{:created-at :updated-at}
|
||||
keys (distinct
|
||||
(if (some included-keys keys)
|
||||
(concat (remove included-keys keys)
|
||||
(filter included-keys keys)
|
||||
included-keys)
|
||||
keys))
|
||||
result (sort-result result sort-state)]
|
||||
columns (get-columns current-block result {:page? page?})
|
||||
;; Sort state needs to be in sync between final result and sortable title
|
||||
;; as user needs to know if there result is sorted
|
||||
sort-state (get-sort-state current-block)
|
||||
result' (sort-result result sort-state)]
|
||||
[:div.overflow-x-auto {:on-mouse-down (fn [e] (.stopPropagation e))
|
||||
:style {:width "100%"}
|
||||
:class (when-not page? "query-table")}
|
||||
[:table.table-auto
|
||||
[:thead
|
||||
[:tr.cursor
|
||||
(for [key keys]
|
||||
(let [key-name (if (and (= key :clock-time) (integer? clock-time-total))
|
||||
(for [column columns]
|
||||
(let [title (if (and (= column :clock-time) (integer? clock-time-total))
|
||||
(util/format "clock-time(total: %s)" (clock/minutes->days:hours:minutes
|
||||
clock-time-total))
|
||||
(name key))]
|
||||
(sortable-title key-name key state sort-state (:block/uuid current-block))))]]
|
||||
(name column))]
|
||||
(sortable-title title column sort-state (:block/uuid current-block))))]]
|
||||
[:tbody
|
||||
(for [item result]
|
||||
(for [item result']
|
||||
(let [format (:block/format item)]
|
||||
[:tr.cursor
|
||||
(for [key keys]
|
||||
(let [value (case key
|
||||
(for [column columns]
|
||||
(let [value (case column
|
||||
:page
|
||||
[:string (or (:block/original-name item)
|
||||
(:block/name item))]
|
||||
|
@ -176,7 +160,7 @@
|
|||
[:string (when-let [updated-at (:block/updated-at item)]
|
||||
(date/int->local-time-2 updated-at))]
|
||||
|
||||
[:string (get-in item [:block/properties key])])]
|
||||
[:string (get-in item [:block/properties column])])]
|
||||
[:td.whitespace-nowrap {:on-mouse-down (fn [] (reset! select? false))
|
||||
:on-mouse-move (fn [] (reset! select? true))
|
||||
:on-mouse-up (fn []
|
||||
|
|
Loading…
Reference in New Issue