mirror of https://github.com/logseq/logseq
Use new tables for all pages
parent
5fa81817de
commit
d523948803
|
@ -106,11 +106,13 @@
|
|||
prop)
|
||||
children]))
|
||||
|
||||
;; FIXME: sticky header
|
||||
(rum/defc table-header < rum/static
|
||||
[& prop-and-children]
|
||||
(let [[prop children] (get-prop-and-children prop-and-children)]
|
||||
[:div.flex.flex-row.items-center.w-fit
|
||||
(merge {:class "border-y transition-colors bg-gray-01"}
|
||||
(merge {:class "border-y transition-colors bg-gray-01"
|
||||
:style {:z-index 100}}
|
||||
prop)
|
||||
children]))
|
||||
|
||||
|
|
|
@ -131,7 +131,6 @@
|
|||
(def table-option table-core/table-option)
|
||||
(def table table-core/table)
|
||||
(def table-header table-core/table-header)
|
||||
(def table-head table-core/table-head)
|
||||
(def table-row table-core/table-row)
|
||||
(def table-cell table-core/table-cell)
|
||||
(def table-get-selection-rows table-core/get-selection-rows)
|
||||
|
|
|
@ -1,230 +1,126 @@
|
|||
(ns frontend.components.all-pages
|
||||
"All pages"
|
||||
(:require [logseq.shui.ui :as shui]
|
||||
[rum.core :as rum]
|
||||
[frontend.util :as util]
|
||||
[frontend.ui :as ui]
|
||||
[clojure.string :as string]
|
||||
(:require [clojure.string :as string]
|
||||
[frontend.components.block :as component-block]
|
||||
[frontend.components.page :as component-page]
|
||||
[frontend.components.views :as views]
|
||||
[frontend.handler.page :as page-handler]
|
||||
[frontend.state :as state]
|
||||
[frontend.date :as date]
|
||||
[goog.object :as gobj]
|
||||
[goog.dom :as gdom]
|
||||
[cljs-bean.core :as bean]
|
||||
[promesa.core :as p]
|
||||
[logseq.db :as ldb]
|
||||
[frontend.search.fuzzy :as fuzzy-search]))
|
||||
|
||||
;; columns:
|
||||
;; page name, tags, backlinks, created at updated at
|
||||
;; default sort: updated at
|
||||
|
||||
(defn header-checkbox [{:keys [selected-all? selected-some? toggle-selected-all!]}]
|
||||
(shui/checkbox
|
||||
{:checked (or selected-all? (and selected-some? "indeterminate"))
|
||||
:on-checked-change toggle-selected-all!
|
||||
:aria-label "Select all"}))
|
||||
|
||||
(defn row-checkbox [{:keys [row-selected? row-toggle-selected!]} row _column]
|
||||
(shui/checkbox
|
||||
{:checked (row-selected? row)
|
||||
:on-checked-change (fn [v] (row-toggle-selected! row v))
|
||||
:aria-label "Select row"}))
|
||||
|
||||
(defn- header-cp
|
||||
[{:keys [column-toggle-sorting! state]} column]
|
||||
(let [sorting (:sorting state)
|
||||
[asc?] (some (fn [item] (when (= (:id item) (:id column))
|
||||
(when-some [asc? (:asc? item)]
|
||||
[asc?]))) sorting)]
|
||||
(shui/button
|
||||
{:variant "text"
|
||||
:class "!pl-0 hover:text-foreground"
|
||||
:onClick #(column-toggle-sorting! column)}
|
||||
(:name column)
|
||||
(case asc?
|
||||
true
|
||||
(ui/icon "arrow-up")
|
||||
false
|
||||
(ui/icon "arrow-down")
|
||||
nil))))
|
||||
|
||||
(comment
|
||||
(defn- default-cell-cp
|
||||
[_table row column]
|
||||
(str (get row (:id column)))))
|
||||
|
||||
(defn- timestamp-cell-cp
|
||||
[_table row column]
|
||||
(some-> (get row (:id column))
|
||||
date/int->local-time-2))
|
||||
[promesa.core :as p]
|
||||
[rum.core :as rum]))
|
||||
|
||||
(def columns
|
||||
[{:id :select
|
||||
:name "Select"
|
||||
:header (fn [table _column] (header-checkbox table))
|
||||
:cell (fn [table row column] (row-checkbox table row column))
|
||||
:column-list? false}
|
||||
{:id :block/original-name
|
||||
[{:id :block/original-name
|
||||
:name "Page name"
|
||||
:header header-cp
|
||||
:cell (fn [_table row _column]
|
||||
(component-block/page-cp {} row))}
|
||||
(component-block/page-cp {} row))
|
||||
:type :string}
|
||||
{:id :block/type
|
||||
:name "Type"
|
||||
:header header-cp
|
||||
:cell (fn [_table row _column] [:div.capitalize (string/join ", " (get row :block/type))])
|
||||
:get-value (fn [row] (string/join ", " (get row :block/type)))}
|
||||
:get-value (fn [row] (string/join ", " (get row :block/type)))
|
||||
:type :string}
|
||||
{:id :block/tags
|
||||
:name "Tags"
|
||||
:header header-cp
|
||||
:cell (fn [_table row _column]
|
||||
(component-block/tags {} row))
|
||||
:get-value (fn [row] (string/join ", " (map :block/original-name (get row :block/tags))))}
|
||||
:name "Tags"}
|
||||
{:id :block.temp/refs-count
|
||||
:name "Backlinks"
|
||||
:header header-cp
|
||||
:cell (fn [_table row _column] (:block.temp/refs-count row))}
|
||||
{:id :block/created-at
|
||||
:name "Created At"
|
||||
:header header-cp
|
||||
:cell timestamp-cell-cp}
|
||||
{:id :block/updated-at
|
||||
:name "Updated At"
|
||||
:header header-cp
|
||||
:cell timestamp-cell-cp}])
|
||||
:cell (fn [_table row _column] (:block.temp/refs-count row))
|
||||
:type :number}])
|
||||
|
||||
(defn- get-all-pages
|
||||
[]
|
||||
(->> (page-handler/get-all-pages (state/get-current-repo))
|
||||
(map (fn [p] (assoc p :id (:db/id p))))))
|
||||
|
||||
(rum/defc columns-select
|
||||
[columns {:keys [column-visible? column-toggle-visibility]}]
|
||||
(shui/dropdown-menu
|
||||
(shui/dropdown-menu-trigger
|
||||
{:asChild true}
|
||||
(shui/button
|
||||
{:variant "outline" :size :sm
|
||||
:class "text-muted-foreground"}
|
||||
"Columns"
|
||||
(ui/icon "chevron-down")))
|
||||
(shui/dropdown-menu-content
|
||||
{:align "end"}
|
||||
(for [column (remove #(false? (:column-list? %)) columns)]
|
||||
(shui/dropdown-menu-checkbox-item
|
||||
{:key (str (:id column))
|
||||
:className "capitalize"
|
||||
:checked (column-visible? column)
|
||||
:onCheckedChange #(column-toggle-visibility column %)}
|
||||
(:name column))))))
|
||||
|
||||
(defn table-header
|
||||
[table columns]
|
||||
(shui/table-row
|
||||
{:class "bg-gray-01 shadow"}
|
||||
(for [column columns]
|
||||
(let [style (case (:id column)
|
||||
:block/original-name
|
||||
{}
|
||||
:select
|
||||
{:width 32}
|
||||
{:width 180})]
|
||||
(shui/table-head
|
||||
{:key (str (:id column))
|
||||
:style style}
|
||||
(let [header-fn (:header column)]
|
||||
(if (fn? header-fn)
|
||||
(header-fn table column)
|
||||
header-fn)))))))
|
||||
|
||||
(defn table-row
|
||||
[{:keys [row-selected?] :as table} rows columns props]
|
||||
(let [idx (gobj/get props "data-index")
|
||||
row (nth rows idx)]
|
||||
(shui/table-row
|
||||
(merge
|
||||
(bean/->clj props)
|
||||
{:key (str (:id row))
|
||||
:data-state (when (row-selected? row) "selected")})
|
||||
(for [column columns]
|
||||
(let [id (str (:id row) "-" (:id column))
|
||||
render (get column :cell)]
|
||||
(shui/table-cell
|
||||
{:key id}
|
||||
(render table row column)))))))
|
||||
|
||||
(rum/defc all-pages < rum/static
|
||||
[]
|
||||
(let [[input set-input!] (rum/use-state "")
|
||||
[sorting set-sorting!] (rum/use-state [{:id :block/updated-at, :asc? false}])
|
||||
[row-filter set-row-filter!] (rum/use-state nil)
|
||||
[visible-columns set-visible-columns!] (rum/use-state {:block/type false})
|
||||
[row-selection set-row-selection!] (rum/use-state {})
|
||||
[data set-data!] (rum/use-state (get-all-pages))
|
||||
_ (rum/use-effect!
|
||||
(fn []
|
||||
(when-let [^js worker @state/*db-worker]
|
||||
(p/let [result-str (.get-page-refs-count worker (state/get-current-repo))
|
||||
result (ldb/read-transit-str result-str)
|
||||
data (map (fn [row] (assoc row :block.temp/refs-count (get result (:db/id row) 0))) data)]
|
||||
(set-data! data))))
|
||||
[])
|
||||
table (shui/table-option {:data data
|
||||
:columns columns
|
||||
:state {:sorting sorting
|
||||
:row-filter row-filter
|
||||
:row-selection row-selection
|
||||
:visible-columns visible-columns}
|
||||
:data-fns {:set-sorting! set-sorting!
|
||||
:set-visible-columns! set-visible-columns!
|
||||
:set-row-selection! set-row-selection!}})
|
||||
selected-rows (shui/table-get-selection-rows row-selection (:rows table))
|
||||
selected-rows-count (count selected-rows)
|
||||
selected? (pos? selected-rows-count)]
|
||||
[:div.w-full
|
||||
[:div.flex.items-center.pb-4.justify-between
|
||||
[:div.ml-1
|
||||
(when selected?
|
||||
(shui/button {:variant :destructive
|
||||
:class "text-red-500"
|
||||
:size :sm
|
||||
:on-click #(shui/dialog-open!
|
||||
(component-page/batch-delete-dialog selected-rows false (fn [] (set-data! (get-all-pages)))))}
|
||||
(ui/icon "trash-x")))]
|
||||
[:div.flex.items-center.gap-2
|
||||
(shui/input
|
||||
{:placeholder "Search pages"
|
||||
:value input
|
||||
:onChange (fn [e]
|
||||
(let [value (util/evalue e)]
|
||||
(set-input! value)
|
||||
(set-row-filter! (fn []
|
||||
(let [[data set-data!] (rum/use-state (get-all-pages))
|
||||
columns (views/build-columns {} columns
|
||||
{:with-object-name? false})]
|
||||
(rum/use-effect!
|
||||
(fn []
|
||||
(when-let [^js worker @state/*db-worker]
|
||||
(p/let [result-str (.get-page-refs-count worker (state/get-current-repo))
|
||||
result (ldb/read-transit-str result-str)
|
||||
data (map (fn [row] (assoc row :block.temp/refs-count (get result (:db/id row) 0))) data)]
|
||||
(set-data! data))))
|
||||
[])
|
||||
[:div.ls-all-pages.max-w-fit.m-auto
|
||||
(views/view nil {:data data
|
||||
:set-data! set-data!
|
||||
:columns columns})]))
|
||||
|
||||
(comment
|
||||
(rum/defc all-pages < rum/static
|
||||
[]
|
||||
(let [[input set-input!] (rum/use-state "")
|
||||
[sorting set-sorting!] (rum/use-state [{:id :block/updated-at, :asc? false}])
|
||||
[row-filter set-row-filter!] (rum/use-state nil)
|
||||
[visible-columns set-visible-columns!] (rum/use-state {:block/type false})
|
||||
[row-selection set-row-selection!] (rum/use-state {})
|
||||
[data set-data!] (rum/use-state (get-all-pages))
|
||||
_ (rum/use-effect!
|
||||
(fn []
|
||||
(when-let [^js worker @state/*db-worker]
|
||||
(p/let [result-str (.get-page-refs-count worker (state/get-current-repo))
|
||||
result (ldb/read-transit-str result-str)
|
||||
data (map (fn [row] (assoc row :block.temp/refs-count (get result (:db/id row) 0))) data)]
|
||||
(set-data! data))))
|
||||
[])
|
||||
table (shui/table-option {:data data
|
||||
:columns columns
|
||||
:state {:sorting sorting
|
||||
:row-filter row-filter
|
||||
:row-selection row-selection
|
||||
:visible-columns visible-columns}
|
||||
:data-fns {:set-sorting! set-sorting!
|
||||
:set-visible-columns! set-visible-columns!
|
||||
:set-row-selection! set-row-selection!}})
|
||||
selected-rows (shui/table-get-selection-rows row-selection (:rows table))
|
||||
selected-rows-count (count selected-rows)
|
||||
selected? (pos? selected-rows-count)]
|
||||
[:div.w-full
|
||||
[:div.flex.items-center.pb-4.justify-between
|
||||
[:div.ml-1
|
||||
(when selected?
|
||||
(shui/button {:variant :destructive
|
||||
:class "text-red-500"
|
||||
:size :sm
|
||||
:on-click #(shui/dialog-open!
|
||||
(component-page/batch-delete-dialog selected-rows false (fn [] (set-data! (get-all-pages)))))}
|
||||
(ui/icon "trash-x")))]
|
||||
[:div.flex.items-center.gap-2
|
||||
(shui/input
|
||||
{:placeholder "Search pages"
|
||||
:value input
|
||||
:onChange (fn [e]
|
||||
(let [value (util/evalue e)]
|
||||
(set-input! value)
|
||||
(set-row-filter! (fn []
|
||||
;; Returns a fn here.
|
||||
;; https://stackoverflow.com/questions/55621212/is-it-possible-to-react-usestate-in-react
|
||||
(fn [row]
|
||||
(if (string/blank? value)
|
||||
true
|
||||
(when row
|
||||
(pos? (fuzzy-search/score (string/lower-case value) (:block/name row))))))))))
|
||||
:class "max-w-sm !h-7 !py-0"})
|
||||
(columns-select columns table)]]
|
||||
(let [columns' (:columns table)
|
||||
rows (:rows table)]
|
||||
[:div.rounded-md.border
|
||||
(ui/virtualized-table
|
||||
{:custom-scroll-parent (gdom/getElement "main-content-container")
|
||||
:total-count (count rows)
|
||||
:fixedHeaderContent (fn [] (table-header table columns'))
|
||||
:components {:Table (fn [props]
|
||||
(shui/table {}
|
||||
(.-children props)))
|
||||
:TableRow (fn [props] (table-row table rows columns' props))}})])
|
||||
(fn [row]
|
||||
(if (string/blank? value)
|
||||
true
|
||||
(when row
|
||||
(pos? (fuzzy-search/score (string/lower-case value) (:block/name row))))))))))
|
||||
:class "max-w-sm !h-7 !py-0"})
|
||||
(columns-select columns table)]]
|
||||
(let [columns' (:columns table)
|
||||
rows (:rows table)]
|
||||
[:div.rounded-md.border
|
||||
(ui/virtualized-table
|
||||
{:custom-scroll-parent (gdom/getElement "main-content-container")
|
||||
:total-count (count rows)
|
||||
:fixedHeaderContent (fn [] (table-header table columns'))
|
||||
:components {:Table (fn [props]
|
||||
(shui/table {}
|
||||
(.-children props)))
|
||||
:TableRow (fn [props] (table-row table rows columns' props))}})])
|
||||
|
||||
(let [rows-count (count (:rows table))]
|
||||
[:div.flex.items-center.justify-end.space-x-2.py-4
|
||||
[:div.flex-1.text-sm.text-muted-foreground
|
||||
(if (pos? selected-rows-count)
|
||||
(str selected-rows-count " of " rows-count " row(s) selected.")
|
||||
(str "Total: " rows-count))]])]))
|
||||
(let [rows-count (count (:rows table))]
|
||||
[:div.flex.items-center.justify-end.space-x-2.py-4
|
||||
[:div.flex-1.text-sm.text-muted-foreground
|
||||
(if (pos? selected-rows-count)
|
||||
(str selected-rows-count " of " rows-count " row(s) selected.")
|
||||
(str "Total: " rows-count))]])])))
|
||||
|
|
|
@ -75,10 +75,10 @@
|
|||
(cond
|
||||
(uuid? entity)
|
||||
(db-property/property-value-content (db/entity [:block/uuid entity]))
|
||||
(map? entity)
|
||||
(de/entity? entity)
|
||||
(db-property/property-value-content entity)
|
||||
:else
|
||||
(str entity))))
|
||||
entity)))
|
||||
|
||||
(defn- get-property-value-for-search
|
||||
[block property]
|
||||
|
@ -95,42 +95,56 @@
|
|||
(string/join ", " col))))
|
||||
|
||||
(defn build-columns
|
||||
[config properties]
|
||||
[config properties & {:keys [with-object-name?]
|
||||
:or {with-object-name? true}}]
|
||||
(let [container-id (state/get-next-container-id)]
|
||||
(concat
|
||||
[{:id :select
|
||||
:name "Select"
|
||||
:header (fn [table _column] (header-checkbox table))
|
||||
:cell (fn [table row column]
|
||||
(row-checkbox table row column))
|
||||
:column-list? false}
|
||||
{:id :object/name
|
||||
:name "Name"
|
||||
:type :string
|
||||
:header header-cp
|
||||
:cell (fn [_table row _column]
|
||||
(component-block/block-container (assoc config :table? true) row))
|
||||
:disable-hide? true}]
|
||||
(map
|
||||
(fn [property]
|
||||
{:id (:db/ident property)
|
||||
:name (:block/original-name property)
|
||||
:header header-cp
|
||||
:cell (fn [_table row _column]
|
||||
(pv/property-value row property (get row (:db/ident property)) {:container-id container-id}))
|
||||
:get-value (fn [row] (get-property-value-for-search row property))})
|
||||
properties)
|
||||
(->> (concat
|
||||
[{:id :select
|
||||
:name "Select"
|
||||
:header (fn [table _column] (header-checkbox table))
|
||||
:cell (fn [table row column]
|
||||
(row-checkbox table row column))
|
||||
:column-list? false}
|
||||
(when with-object-name?
|
||||
{:id :object/name
|
||||
:name "Name"
|
||||
:type :string
|
||||
:header header-cp
|
||||
:cell (fn [_table row _column]
|
||||
(component-block/block-container (assoc config :table? true) row))
|
||||
:disable-hide? true})]
|
||||
(map
|
||||
(fn [property]
|
||||
(let [ident (or (:id property) (:db/ident property))
|
||||
property (if (de/entity? property)
|
||||
property
|
||||
(or (db/entity ident) property))]
|
||||
{:id ident
|
||||
:name (or (:name property)
|
||||
(:block/original-name property))
|
||||
:header (or (:header property)
|
||||
header-cp)
|
||||
:cell (or (:cell property)
|
||||
(when (de/entity? property)
|
||||
(fn [_table row _column]
|
||||
(pv/property-value row property (get row (:db/ident property)) {:container-id container-id}))))
|
||||
:get-value (or (:get-value property)
|
||||
(when (de/entity? property)
|
||||
(fn [row] (get-property-value-for-search row property))))
|
||||
:type (:type property)}))
|
||||
properties)
|
||||
|
||||
[{:id :block/created-at
|
||||
:name "Created At"
|
||||
:type :date-time
|
||||
:header header-cp
|
||||
:cell timestamp-cell-cp}
|
||||
{:id :block/updated-at
|
||||
:name "Updated At"
|
||||
:type :date-time
|
||||
:header header-cp
|
||||
:cell timestamp-cell-cp}])))
|
||||
[{:id :block/created-at
|
||||
:name "Created At"
|
||||
:type :date-time
|
||||
:header header-cp
|
||||
:cell timestamp-cell-cp}
|
||||
{:id :block/updated-at
|
||||
:name "Updated At"
|
||||
:type :date-time
|
||||
:header header-cp
|
||||
:cell timestamp-cell-cp}])
|
||||
(remove nil?))))
|
||||
|
||||
(defn- sort-columns
|
||||
[columns ordered-column-ids]
|
||||
|
@ -177,7 +191,7 @@
|
|||
[column]
|
||||
(case (:id column)
|
||||
:select 32
|
||||
:object/name 360
|
||||
(:object/name :block/original-name :block/name :block/content) 360
|
||||
(:block/created-at :block/updated-at) 160
|
||||
180))
|
||||
|
||||
|
@ -204,8 +218,9 @@
|
|||
[{:keys [row-selected?] :as table} rows columns props]
|
||||
(let [idx (gobj/get props "data-index")
|
||||
row (nth rows idx)
|
||||
row (db/sub-block (:id row))
|
||||
row (assoc row :id (:db/id row))]
|
||||
row' (db/sub-block (:id row))
|
||||
;; merge entity temporal attributes
|
||||
row (reduce (fn [e [k v]] (assoc e k v)) row' (.-kv ^js row))]
|
||||
(shui/table-row
|
||||
(merge
|
||||
(bean/->clj props)
|
||||
|
@ -312,6 +327,7 @@
|
|||
(rum/defc filter-property < rum/static
|
||||
[columns {:keys [data-fns] :as table}]
|
||||
(let [[property set-property!] (rum/use-state nil)
|
||||
schema (:schema (db/get-db))
|
||||
timestamp? (timestamp-property? (:db/ident property))
|
||||
set-filters! (:set-filters! data-fns)
|
||||
filters (get-in table [:state :filters])
|
||||
|
@ -328,8 +344,11 @@
|
|||
(let [id (:id column)
|
||||
property (db/entity id)
|
||||
internal-property {:db/ident (:id column)
|
||||
:block/original-name (:name column)}]
|
||||
(if (or property (timestamp-property? id))
|
||||
:block/original-name (:name column)
|
||||
:block/schema {:type (:type column)}}]
|
||||
(if (or property
|
||||
(= :db.cardinality/many (:db/cardinality (get schema id)))
|
||||
(not= (:type column) :string))
|
||||
(set-property! (or property internal-property))
|
||||
(do
|
||||
(shui/popup-hide!)
|
||||
|
@ -364,8 +383,11 @@
|
|||
:input-default-placeholder (if property (:block/original-name property) "Select")
|
||||
:multiple-choices? true
|
||||
:on-chosen (fn [_value _selected? selected]
|
||||
(let [filters' (if (seq selected)
|
||||
(conj filters [(:db/ident property) :is selected])
|
||||
(let [selected-value (if (de/entity? (first selected))
|
||||
(set (map :block/uuid selected))
|
||||
selected)
|
||||
filters' (if (seq selected)
|
||||
(conj filters [(:db/ident property) :is selected-value])
|
||||
filters)]
|
||||
(set-filters! filters')))})))
|
||||
:else
|
||||
|
@ -598,7 +620,7 @@
|
|||
(filter-value-select table property value operator idx))))
|
||||
|
||||
(rum/defc filters-row < rum/static
|
||||
[{:keys [data-fns] :as table}]
|
||||
[{:keys [data-fns columns] :as table}]
|
||||
(let [filters (get-in table [:state :filters])
|
||||
{:keys [set-filters!]} data-fns]
|
||||
(when (seq filters)
|
||||
|
@ -609,7 +631,10 @@
|
|||
property (if (= property-ident :object/name)
|
||||
{:db/ident property-ident
|
||||
:block/original-name "Name"}
|
||||
(db/entity property-ident))]
|
||||
(or (db/entity property-ident)
|
||||
(some (fn [column] (when (= (:id column) property-ident)
|
||||
{:db/ident (:id column)
|
||||
:block/original-name (:name column)})) columns)))]
|
||||
[:div.flex.flex-row.items-center.border.rounded
|
||||
(shui/button
|
||||
{:class "!px-2 rounded-none border-r"
|
||||
|
@ -650,26 +675,30 @@
|
|||
(set? value) value
|
||||
(nil? value) #{}
|
||||
:else #{value})
|
||||
entity? (de/entity? (first value'))
|
||||
result
|
||||
(case operator
|
||||
:is
|
||||
(if (boolean? match)
|
||||
(= (boolean (get-property-value-content (get row property-ident))) match)
|
||||
(if (and (empty? match) (empty? value))
|
||||
(if (and (empty? match) (empty? value'))
|
||||
true
|
||||
(when (coll? value)
|
||||
(boolean (seq (set/intersection (set (map :block/uuid value')) match))))))
|
||||
(if entity?
|
||||
(boolean (seq (set/intersection (set (map :block/uuid value')) match)))
|
||||
(boolean (seq (set/intersection (set value') match))))))
|
||||
|
||||
:is-not
|
||||
(if (boolean? match)
|
||||
(not= (boolean (get-property-value-content (get row property-ident))) match)
|
||||
(cond
|
||||
(and (empty? match) (seq value))
|
||||
(and (empty? match) (seq value'))
|
||||
true
|
||||
(and (seq match) (empty? value))
|
||||
(and (seq match) (empty? value'))
|
||||
true
|
||||
(coll? value)
|
||||
(boolean (empty? (set/intersection (set (map :block/uuid value')) match)))))
|
||||
:else
|
||||
(if entity?
|
||||
(boolean (empty? (set/intersection (set (map :block/uuid value')) match)))
|
||||
(boolean (empty? (set/intersection (set value') match))))))
|
||||
|
||||
:text-contains
|
||||
(some #(fuzzy-matched? match (get-property-value-content %)) value')
|
||||
|
@ -751,29 +780,31 @@
|
|||
filters))
|
||||
|
||||
(defn- db-set-table-state!
|
||||
[entity {:keys [set-sorting! set-filters! set-visible-columns! set-ordered-columns!]}]
|
||||
(let [repo (state/get-current-repo)]
|
||||
{:set-sorting!
|
||||
(fn [sorting]
|
||||
(set-sorting! sorting)
|
||||
(property-handler/set-block-property! repo (:db/id entity) :logseq.property/table-sorting sorting))
|
||||
:set-filters!
|
||||
(fn [filters]
|
||||
(let [filters (table-filters->persist-state filters)]
|
||||
(set-filters! filters)
|
||||
(property-handler/set-block-property! repo (:db/id entity) :logseq.property/table-filters filters)))
|
||||
:set-visible-columns!
|
||||
(fn [columns]
|
||||
(let [hidden-columns (vec (keep (fn [[column visible?]]
|
||||
(when (false? visible?)
|
||||
column)) columns))]
|
||||
(set-visible-columns! columns)
|
||||
(property-handler/set-block-property! repo (:db/id entity) :logseq.property/table-hidden-columns hidden-columns)))
|
||||
:set-ordered-columns!
|
||||
(fn [ordered-columns]
|
||||
(let [ids (vec (remove #{:select} ordered-columns))]
|
||||
(set-ordered-columns! ordered-columns)
|
||||
(property-handler/set-block-property! repo (:db/id entity) :logseq.property/table-ordered-columns ids)))}))
|
||||
[entity {:keys [set-sorting! set-filters! set-visible-columns! set-ordered-columns!] :as option}]
|
||||
(if entity
|
||||
(let [repo (state/get-current-repo)]
|
||||
{:set-sorting!
|
||||
(fn [sorting]
|
||||
(set-sorting! sorting)
|
||||
(property-handler/set-block-property! repo (:db/id entity) :logseq.property/table-sorting sorting))
|
||||
:set-filters!
|
||||
(fn [filters]
|
||||
(let [filters (table-filters->persist-state filters)]
|
||||
(set-filters! filters)
|
||||
(property-handler/set-block-property! repo (:db/id entity) :logseq.property/table-filters filters)))
|
||||
:set-visible-columns!
|
||||
(fn [columns]
|
||||
(let [hidden-columns (vec (keep (fn [[column visible?]]
|
||||
(when (false? visible?)
|
||||
column)) columns))]
|
||||
(set-visible-columns! columns)
|
||||
(property-handler/set-block-property! repo (:db/id entity) :logseq.property/table-hidden-columns hidden-columns)))
|
||||
:set-ordered-columns!
|
||||
(fn [ordered-columns]
|
||||
(let [ids (vec (remove #{:select} ordered-columns))]
|
||||
(set-ordered-columns! ordered-columns)
|
||||
(property-handler/set-block-property! repo (:db/id entity) :logseq.property/table-ordered-columns ids)))})
|
||||
option))
|
||||
|
||||
(rum/defc view < rum/static
|
||||
[view-entity {:keys [data set-data! columns add-new-object!]}]
|
||||
|
@ -841,13 +872,14 @@
|
|||
(let [columns' (:columns table)
|
||||
rows (:rows table)]
|
||||
[:div.ls-table-rows.rounded-md.content.overflow-x-auto.force-visible-scrollbar
|
||||
(table-header table columns')
|
||||
[:div.relative
|
||||
(table-header table columns')
|
||||
|
||||
(ui/virtualized-table
|
||||
{:custom-scroll-parent (gdom/getElement "main-content-container")
|
||||
:total-count (count rows)
|
||||
:components {:Table (fn [props]
|
||||
(shui/table {}
|
||||
(.-children props)))
|
||||
:TableRow (fn [props] (table-row table rows columns' props))}})
|
||||
(when add-new-object! (add-new-row table))])]))
|
||||
(ui/virtualized-table
|
||||
{:custom-scroll-parent (gdom/getElement "main-content-container")
|
||||
:total-count (count rows)
|
||||
:components {:Table (fn [props]
|
||||
(shui/table {}
|
||||
(.-children props)))
|
||||
:TableRow (fn [props] (table-row table rows columns' props))}})
|
||||
(when add-new-object! (add-new-row table))]])]))
|
||||
|
|
Loading…
Reference in New Issue