mirror of https://github.com/logseq/logseq
fix: load all pages initially
There're still some issues when loading partial pages initially, let's improve the performance during the test.experiment/tanstack-table
parent
119b519e2a
commit
5c965e5235
|
@ -36,14 +36,15 @@
|
|||
"logseq/custom.js"]]
|
||||
(map #(d/pull db '[*] [:file/path %]) files))))
|
||||
|
||||
(defn get-all-pages
|
||||
[db exclude-page-ids]
|
||||
(->> (d/datoms db :avet :block/name)
|
||||
(keep (fn [e]
|
||||
(when-not (contains? exclude-page-ids (:e e))
|
||||
(d/pull db '[:db/id :db/ident :block/uuid :block/name :block/original-name :block/alias :block/type :block/journal-day
|
||||
:block/created-at :block/updated-at]
|
||||
(:e e)))))))
|
||||
(comment
|
||||
(defn get-all-pages
|
||||
[db exclude-page-ids]
|
||||
(->> (d/datoms db :avet :block/name)
|
||||
(keep (fn [e]
|
||||
(when-not (contains? exclude-page-ids (:e e))
|
||||
(d/pull db '[:db/id :db/ident :block/uuid :block/name :block/original-name :block/alias :block/type :block/journal-day
|
||||
:block/created-at :block/updated-at]
|
||||
(:e e))))))))
|
||||
|
||||
(defn get-all-files
|
||||
[db]
|
||||
|
@ -205,13 +206,30 @@
|
|||
(mapcat (fn [p]
|
||||
(d/datoms db :eavt (:db/id p)))))))
|
||||
|
||||
(defn get-all-pages
|
||||
[db]
|
||||
(let [datoms (d/datoms db :avet :block/name)]
|
||||
(mapcat (fn [d] (d/datoms db :eavt (:e d))) datoms)))
|
||||
|
||||
(defn get-page->refs-count
|
||||
[db]
|
||||
(let [datoms (d/datoms db :avet :block/name)]
|
||||
(->>
|
||||
(map (fn [d]
|
||||
[(:e d)
|
||||
(count (:block/_refs (d/entity db (:e d))))]) datoms)
|
||||
(into {}))))
|
||||
|
||||
(defn get-structured-datoms
|
||||
[db]
|
||||
(mapcat (fn [type]
|
||||
(->> (d/datoms db :avet :block/type type)
|
||||
(mapcat (fn [d]
|
||||
(d/datoms db :eavt (:e d))))))
|
||||
["property" "class" "closed value"]))
|
||||
[
|
||||
;; property and class pages are pulled from `get-all-pages` already
|
||||
;; "property" "class"
|
||||
"closed value"]))
|
||||
|
||||
(defn get-favorites
|
||||
"Favorites page and its blocks"
|
||||
|
@ -242,9 +260,11 @@
|
|||
favorites (when db-graph? (get-favorites db))
|
||||
latest-journals (get-latest-journals db 1)
|
||||
all-files (get-all-files db)
|
||||
all-pages (get-all-pages db)
|
||||
structured-datoms (when db-graph?
|
||||
(get-structured-datoms db))
|
||||
data (concat idents
|
||||
all-pages
|
||||
structured-datoms
|
||||
favorites
|
||||
latest-journals
|
||||
|
|
|
@ -1,14 +0,0 @@
|
|||
(ns logseq.shui.tanstack-table.core
|
||||
(:require [rum.core :as rum]
|
||||
[logseq.shui.util :as util]))
|
||||
|
||||
(def table (util/lsui-wrap "Table"))
|
||||
(def table-header (util/lsui-wrap "TableHeader"))
|
||||
(def table-body (util/lsui-wrap "TableBody"))
|
||||
(def table-footer (util/lsui-wrap "TableFooter"))
|
||||
(def table-head (util/lsui-wrap "TableHead"))
|
||||
(def table-row (util/lsui-wrap "TableRow"))
|
||||
(def table-cell (util/lsui-wrap "TableCell"))
|
||||
(def table-caption (util/lsui-wrap "TableCaption"))
|
||||
|
||||
(def ^js tanStackReact (util/lsui-get "tanStackReact"))
|
|
@ -4,12 +4,12 @@
|
|||
[logseq.shui.shortcut.v1 :as shui.shortcut.v1]
|
||||
[logseq.shui.toaster.core :as toaster-core]
|
||||
[logseq.shui.select.core :as select-core]
|
||||
[logseq.shui.tanstack-table.core :as tanstack-table-core]
|
||||
[logseq.shui.select.multi :as select-multi]
|
||||
[logseq.shui.dialog.core :as dialog-core]
|
||||
[logseq.shui.popup.core :as popup-core]
|
||||
[logseq.shui.base.core :as base-core]
|
||||
[logseq.shui.form.core :as form-core]))
|
||||
[logseq.shui.form.core :as form-core]
|
||||
[logseq.shui.table.core :as table-core]))
|
||||
|
||||
(def button base-core/button)
|
||||
(def link base-core/link)
|
||||
|
@ -52,15 +52,6 @@
|
|||
(def card-content (util/lsui-wrap "CardContent"))
|
||||
(def card-footer (util/lsui-wrap "CardFooter"))
|
||||
|
||||
(def table tanstack-table-core/table)
|
||||
(def table-header tanstack-table-core/table-header)
|
||||
(def table-body tanstack-table-core/table-body)
|
||||
(def table-footer tanstack-table-core/table-footer)
|
||||
(def table-head tanstack-table-core/table-head)
|
||||
(def table-row tanstack-table-core/table-row)
|
||||
(def table-cell tanstack-table-core/table-cell)
|
||||
(def table-caption tanstack-table-core/table-caption)
|
||||
(def ^js tanStackReact tanstack-table-core/tanStackReact)
|
||||
|
||||
(def form-provider form-core/form-provider)
|
||||
(def form-item form-core/form-item)
|
||||
|
@ -137,3 +128,12 @@
|
|||
(def popup-hide-all! popup-core/hide-all!)
|
||||
|
||||
(def multi-select-content select-multi/x-select-content)
|
||||
|
||||
(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-body table-core/table-body)
|
||||
(def table-row table-core/table-row)
|
||||
(def table-cell table-core/table-cell)
|
||||
(def table-get-selection-rows-count table-core/get-selection-rows-count)
|
||||
|
|
|
@ -84,15 +84,15 @@
|
|||
[visible-columns set-visible-columns!] (rum/use-state {})
|
||||
[row-selection set-row-selection!] (rum/use-state {})
|
||||
{:keys [column-visible? column-toggle-visiblity row-selected?]
|
||||
:as table} (table/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!}})]
|
||||
:as 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!}})]
|
||||
[:div.w-full
|
||||
[:div.flex.items-center.py-4
|
||||
(shui/input
|
||||
|
@ -127,35 +127,35 @@
|
|||
(:name column)))))]
|
||||
(let [columns' (:columns table)]
|
||||
[:div.rounded-md.border
|
||||
(table/table
|
||||
(table/table-header
|
||||
(table/table-row
|
||||
(shui/table
|
||||
(shui/table-header
|
||||
(shui/table-row
|
||||
(for [column columns']
|
||||
(table/table-head
|
||||
(shui/table-head
|
||||
{:key (:id column)}
|
||||
(let [header-fn (:header column)]
|
||||
(if (fn? header-fn)
|
||||
(header-fn table column)
|
||||
header-fn))))))
|
||||
(table/table-body
|
||||
(shui/table-body
|
||||
(let [rows (:rows table)]
|
||||
(if (pos? (count rows))
|
||||
(for [row rows]
|
||||
(table/table-row
|
||||
(shui/table-row
|
||||
{: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)]
|
||||
(table/table-cell
|
||||
(shui/table-cell
|
||||
{:key id}
|
||||
(render table row column))))))
|
||||
(table/table-row
|
||||
(table/table-cell
|
||||
(shui/table-row
|
||||
(shui/table-cell
|
||||
{:colSpan (count columns)
|
||||
:className "h-24 text-center"}
|
||||
"No results."))))))])
|
||||
(let [selected-rows-count (table/get-selection-rows-count row-selection (:rows table))
|
||||
(let [selected-rows-count (shui/table-get-selection-rows-count row-selection (:rows table))
|
||||
rows-count (count (:rows table))]
|
||||
[:div.flex.items-center.justify-end.space-x-2.py-4
|
||||
[:div.flex-1.text-sm.text-muted-foreground
|
||||
|
|
|
@ -1,188 +0,0 @@
|
|||
(ns frontend.components.all-pages2
|
||||
"All pages"
|
||||
(:require [logseq.shui.ui :as shui]
|
||||
[rum.core :as rum]
|
||||
[cljs-bean.core :refer [->js ->clj]]
|
||||
[frontend.util :as util]
|
||||
[goog.object :as gobj]
|
||||
[frontend.ui :as ui]))
|
||||
|
||||
(def useReactTable (gobj/get shui/tanStackReact "useReactTable"))
|
||||
(def getCoreRowModel (gobj/get shui/tanStackReact "getCoreRowModel"))
|
||||
(def getSortedRowModel (gobj/get shui/tanStackReact "getSortedRowModel"))
|
||||
(def getFilteredRowModel (gobj/get shui/tanStackReact "getFilteredRowModel"))
|
||||
(def getPaginationRowModel (gobj/get shui/tanStackReact "getPaginationRowModel"))
|
||||
(def flexRender (gobj/get shui/tanStackReact "flexRender"))
|
||||
|
||||
|
||||
(def data
|
||||
[{:id "m5gr84i9" :amount 316 :status "success" :email "ken99@yahoo.com"}
|
||||
{:id "3u1reuv4" :amount 242 :status "success" :email "Abe45@gmail.com"}
|
||||
{:id "derv1ws0" :amount 837 :status "processing" :email "Monserrat44@gmail.com"}
|
||||
{:id "5kma53ae" :amount 874 :status "success" :email "Silas22@gmail.com"}
|
||||
{:id "bhqecj4p" :amount 721 :status "failed" :email "carmella@hotmail.com"}])
|
||||
|
||||
(def rows data)
|
||||
|
||||
(defn header-checkbox [^js table]
|
||||
(shui/checkbox
|
||||
{:checked (or (.getIsAllPageRowsSelected table)
|
||||
(and (.getIsSomePageRowsSelected table) "indeterminate"))
|
||||
:on-checked-change #(.toggleAllPageRowsSelected table %)
|
||||
:aria-label "Select all"}))
|
||||
|
||||
(defn row-checkbox [^js row]
|
||||
(shui/checkbox
|
||||
{:checked (.getIsSelected row)
|
||||
:on-checked-change (fn [v] (.toggleSelected row v))
|
||||
:aria-label "Select row"}))
|
||||
|
||||
(def columns
|
||||
[{:id "select"
|
||||
:header (fn [opts] (header-checkbox (.-table opts)))
|
||||
:cell (fn [opts] (row-checkbox (.-row opts)))
|
||||
:enableSorting false
|
||||
:enableHiding false}
|
||||
{:accessorKey "status"
|
||||
:header "Status"
|
||||
:cell (fn [^js opts]
|
||||
(.getValue (.-row opts) "status"))}
|
||||
{:accessorKey "email"
|
||||
:header (fn [^js opts]
|
||||
(shui/button
|
||||
{:variant "ghost"
|
||||
:onClick #(.toggleSorting ^js (.-column opts) (= "asc" (.getIsSorted ^js (.-column opts))))}
|
||||
"Email"
|
||||
(ui/icon "arrows-up-down")))
|
||||
:cell (fn [opts] (.getValue (.-row opts) "email"))}
|
||||
{:accessorKey "amount"
|
||||
:header (fn [_opts] "Amount")
|
||||
:cell (fn [opts]
|
||||
(let [amount (.getValue (.-row opts) "amount")
|
||||
formatted (.format (js/Intl.NumberFormat. "en-US" #js {:style "currency" :currency "USD"}) amount)]
|
||||
formatted))}
|
||||
{:id "actions"
|
||||
:enableHiding false
|
||||
:cell (fn [opts]
|
||||
(let [payment (.-original (.-row opts))]
|
||||
(shui/dropdown-menu
|
||||
(shui/dropdown-menu-trigger
|
||||
{:asChild true}
|
||||
(shui/button
|
||||
{:variant "ghost" :className "h-8 w-8 p-0"}
|
||||
[:span.sr-only "Open menu"]
|
||||
(ui/icon "dots")))
|
||||
(shui/dropdown-menu-content
|
||||
(shui/dropdown-menu-label
|
||||
"Actions")
|
||||
(shui/dropdown-menu-item
|
||||
{:onClick #(js/navigator.clipboard.writeText (.-id payment))}
|
||||
"Copy payment ID")
|
||||
(shui/dropdown-menu-separator)
|
||||
(shui/dropdown-menu-item
|
||||
"View customer")
|
||||
(shui/dropdown-menu-item
|
||||
"View payment details")))))}])
|
||||
|
||||
(rum/defc all-pages < rum/static
|
||||
[]
|
||||
(let [[sorting set-sorting!] (rum/use-state #js [])
|
||||
[column-filters set-column-filters!] (rum/use-state #js [])
|
||||
[column-visibility set-column-visibility!] (rum/use-state #js {})
|
||||
[row-selection set-row-selection!] (rum/use-state #js {})
|
||||
_ (prn :debug row-selection)
|
||||
^js table (useReactTable #js {:columns (->js columns)
|
||||
:data (->js data)
|
||||
:state (->js
|
||||
{:sorting sorting
|
||||
:columnFilters column-filters
|
||||
:columnVisibility column-visibility
|
||||
:rowSelection row-selection})
|
||||
:getCoreRowModel (getCoreRowModel)
|
||||
:getSortedRowModel (getSortedRowModel)
|
||||
:getFilteredRowModel (getFilteredRowModel)
|
||||
:getPaginationRowModel (getPaginationRowModel)
|
||||
:onSortingChange set-sorting!
|
||||
:onColumnFiltersChange set-column-filters!
|
||||
:onColumnVisibilityChange set-column-visibility!
|
||||
:onRowSelectionChange set-row-selection!})]
|
||||
[:div.w-full
|
||||
[:div.flex.items-center.py-4
|
||||
(shui/input
|
||||
{:placeholder "Filter emails..."
|
||||
:value (or
|
||||
(when-let [^js column (.getColumn table "email")]
|
||||
(try
|
||||
(str (.getFilterValue column))
|
||||
(catch :default _
|
||||
nil)))
|
||||
"")
|
||||
:onChange (fn [e]
|
||||
(when-let [^js column (.getColumn table "email")]
|
||||
(.setFilterValue column (util/evalue e))))
|
||||
:className "max-w-sm"})
|
||||
(shui/dropdown-menu
|
||||
(shui/dropdown-menu-trigger
|
||||
{:asChild true}
|
||||
(shui/button
|
||||
{:variant "outline" :className "ml-auto"}
|
||||
"Columns"
|
||||
(ui/icon "chevron-down")))
|
||||
(shui/dropdown-menu-content
|
||||
{:align "end"}
|
||||
(for [^js column (.getAllColumns table)]
|
||||
(shui/dropdown-menu-checkbox-item
|
||||
{:key (.-id column)
|
||||
:className "capitalize"
|
||||
:checked (.getIsVisible column)
|
||||
:onCheckedChange #(.toggleVisibility column %)}
|
||||
(.-id column)))))]
|
||||
[:div.rounded-md.border
|
||||
(shui/table
|
||||
(shui/table-header
|
||||
(for [^js headerGroup (.getHeaderGroups table)]
|
||||
(shui/table-row
|
||||
{:key (.-id headerGroup)}
|
||||
(for [^js header (.-headers headerGroup)]
|
||||
(shui/table-head
|
||||
{:key (.-id header)}
|
||||
(when-not (.-isPlaceholder header)
|
||||
(flexRender
|
||||
(-> header .-column .-columnDef .-header)
|
||||
(.getContext header))))))))
|
||||
(shui/table-body
|
||||
(let [^js rows (.-rows (.getRowModel table))]
|
||||
(if (pos? (count rows))
|
||||
(for [^js row rows]
|
||||
(shui/table-row
|
||||
{:key (.-id row)
|
||||
:data-state (when (.getIsSelected row) "selected")}
|
||||
(for [^js cell (.getVisibleCells row)]
|
||||
(shui/table-cell
|
||||
{:key (.-id cell)}
|
||||
(flexRender
|
||||
(-> cell .-column .-columnDef .-cell)
|
||||
(.getContext cell))))))
|
||||
(shui/table-row
|
||||
(shui/table-cell
|
||||
{:colSpan (count columns)
|
||||
:className "h-24 text-center"}
|
||||
"No results."))))))]
|
||||
[:div.flex.items-center.justify-end.space-x-2.py-4
|
||||
[:div.flex-1.text-sm.text-muted-foreground
|
||||
(let [selected-rows (.-rows ^js (.getFilteredSelectedRowModel table))
|
||||
filter-rows (.-rows ^js (.getFilteredRowModel table))]
|
||||
(str (count selected-rows)
|
||||
" of "
|
||||
(count filter-rows) " row(s) selected."))]
|
||||
[:div.space-x-2
|
||||
(shui/button {:variant "outline"
|
||||
:size "sm"
|
||||
:onClick #(.previousPage table)
|
||||
:disabled (not (.getCanPreviousPage table))}
|
||||
"Previous")
|
||||
(shui/button {:variant "outline"
|
||||
:size "sm"
|
||||
:onClick #(.nextPage table)
|
||||
:disabled (not (.getCanNextPage table))}
|
||||
"Next")]]]))
|
|
@ -7,9 +7,7 @@
|
|||
[promesa.core :as p]
|
||||
[cljs-time.core :as t]
|
||||
[logseq.db.sqlite.common-db :as sqlite-common-db]
|
||||
[datascript.transit :as dt]
|
||||
[frontend.db.async :as db-async]
|
||||
[clojure.core.async :as async]))
|
||||
[datascript.transit :as dt]))
|
||||
|
||||
(defn restore-graph!
|
||||
"Restore db from SQLite"
|
||||
|
@ -33,6 +31,7 @@
|
|||
(state/set-state! :graph/loading? false)
|
||||
(react/clear-query-state!)
|
||||
(state/pub-event! [:ui/re-render-root])
|
||||
(async/go
|
||||
(async/<! (async/timeout 100))
|
||||
(db-async/<fetch-all-pages repo))))
|
||||
;; (async/go
|
||||
;; (async/<! (async/timeout 100))
|
||||
;; (db-async/<fetch-all-pages repo))
|
||||
))
|
||||
|
|
|
@ -421,19 +421,25 @@
|
|||
(when-let [conn (worker-state/get-datascript-conn repo)]
|
||||
(ldb/write-transit-str (sqlite-common-db/get-initial-data @conn))))
|
||||
|
||||
(get-page-refs-count
|
||||
[_this repo]
|
||||
(when-let [conn (worker-state/get-datascript-conn repo)]
|
||||
(ldb/write-transit-str (sqlite-common-db/get-page->refs-count @conn))))
|
||||
|
||||
(fetch-all-pages
|
||||
[_this repo exclude-page-ids-str]
|
||||
(when-let [conn (worker-state/get-datascript-conn repo)]
|
||||
(async/go
|
||||
(let [all-pages (sqlite-common-db/get-all-pages @conn (ldb/read-transit-str exclude-page-ids-str))
|
||||
partitioned-data (map-indexed (fn [idx p] [idx p]) (partition-all 2000 all-pages))]
|
||||
(doseq [[idx tx-data] partitioned-data]
|
||||
(worker-util/post-message :sync-db-changes {:repo repo
|
||||
:tx-data tx-data
|
||||
:tx-meta {:initial-pages? true
|
||||
:end? (= idx (dec (count partitioned-data)))}})
|
||||
(async/<! (async/timeout 100)))))
|
||||
nil))
|
||||
;; (when-let [conn (worker-state/get-datascript-conn repo)]
|
||||
;; (async/go
|
||||
;; (let [all-pages (sqlite-common-db/get-all-pages @conn (ldb/read-transit-str exclude-page-ids-str))
|
||||
;; partitioned-data (map-indexed (fn [idx p] [idx p]) (partition-all 2000 all-pages))]
|
||||
;; (doseq [[idx tx-data] partitioned-data]
|
||||
;; (worker-util/post-message :sync-db-changes {:repo repo
|
||||
;; :tx-data tx-data
|
||||
;; :tx-meta {:initial-pages? true
|
||||
;; :end? (= idx (dec (count partitioned-data)))}})
|
||||
;; (async/<! (async/timeout 100)))))
|
||||
;; nil)
|
||||
)
|
||||
|
||||
(closeDB
|
||||
[_this repo]
|
||||
|
|
Loading…
Reference in New Issue