mirror of
https://github.com/logseq/logseq.git
synced 2026-04-24 22:25:01 +00:00
feat: table columns pinning (#11693)
* Add property :logseq.property.table/pinned-columns * feat: table column pinning * enhance: hide :id column by default --------- Co-authored-by: charlie <xyhp915@qq.com>
This commit is contained in:
4
deps/db/src/logseq/db/frontend/db_ident.cljc
vendored
4
deps/db/src/logseq/db/frontend/db_ident.cljc
vendored
@@ -1,7 +1,7 @@
|
||||
(ns logseq.db.frontend.db-ident
|
||||
"Helper fns for class and property :db/ident"
|
||||
(:require [datascript.core :as d]
|
||||
[clojure.string :as string]))
|
||||
(:require [clojure.string :as string]
|
||||
[datascript.core :as d]))
|
||||
|
||||
(defn ensure-unique-db-ident
|
||||
"Ensures the given db-ident is unique. If a db-ident conflicts, it is made
|
||||
|
||||
10
deps/db/src/logseq/db/frontend/property.cljs
vendored
10
deps/db/src/logseq/db/frontend/property.cljs
vendored
@@ -451,7 +451,15 @@
|
||||
:rtc {:rtc/ignore-attr-when-init-upload true
|
||||
:rtc/ignore-attr-when-init-download true
|
||||
:rtc/ignore-attr-when-syncing true}}
|
||||
|
||||
:logseq.property.table/pinned-columns {:title "Table view pinned columns"
|
||||
:schema
|
||||
{:type :property
|
||||
:cardinality :many
|
||||
:hide? true
|
||||
:public? false}
|
||||
:rtc {:rtc/ignore-attr-when-init-upload true
|
||||
:rtc/ignore-attr-when-init-download true
|
||||
:rtc/ignore-attr-when-syncing true}}
|
||||
:logseq.property/view-for {:title "This view belongs to"
|
||||
:schema
|
||||
{:type :node
|
||||
|
||||
@@ -86,7 +86,6 @@
|
||||
{:block/title value}))
|
||||
common-util/block-with-timestamps)))
|
||||
|
||||
|
||||
(defn build-property-values-tx-m
|
||||
"Builds a map of property names to their property value blocks to be
|
||||
transacted, given a block and a properties map with raw property values. The
|
||||
|
||||
2
deps/db/src/logseq/db/frontend/schema.cljs
vendored
2
deps/db/src/logseq/db/frontend/schema.cljs
vendored
@@ -2,7 +2,7 @@
|
||||
"Main datascript schemas for the Logseq app"
|
||||
(:require [clojure.set :as set]))
|
||||
|
||||
(def version 62)
|
||||
(def version 63)
|
||||
|
||||
;; A page is a special block, a page can corresponds to multiple files with the same ":block/name".
|
||||
(def ^:large-vars/data-var schema
|
||||
|
||||
10
deps/db/src/logseq/db/sqlite/create_graph.cljs
vendored
10
deps/db/src/logseq/db/sqlite/create_graph.cljs
vendored
@@ -147,11 +147,11 @@
|
||||
(mark-block-as-built-in
|
||||
(sqlite-util/build-new-class
|
||||
(let [class-properties (mapv
|
||||
(fn [db-ident]
|
||||
(let [property (get db-ident->properties db-ident)]
|
||||
(assert property (str "Built-in property " db-ident " is not defined yet"))
|
||||
db-ident))
|
||||
(:properties schema))]
|
||||
(fn [db-ident]
|
||||
(let [property (get db-ident->properties db-ident)]
|
||||
(assert property (str "Built-in property " db-ident " is not defined yet"))
|
||||
db-ident))
|
||||
(:properties schema))]
|
||||
(cond->
|
||||
{:block/title title'
|
||||
:block/name (common-util/page-name-sanity-lc title')
|
||||
|
||||
10
deps/graph-parser/script/db_import.cljs
vendored
10
deps/graph-parser/script/db_import.cljs
vendored
@@ -6,6 +6,7 @@
|
||||
["fs/promises" :as fsp]
|
||||
["os" :as os]
|
||||
["path" :as node-path]
|
||||
#_:clj-kondo/ignore
|
||||
[babashka.cli :as cli]
|
||||
[cljs.pprint :as pprint]
|
||||
[clojure.set :as set]
|
||||
@@ -13,7 +14,6 @@
|
||||
[datascript.core :as d]
|
||||
[logseq.common.graph :as common-graph]
|
||||
[logseq.graph-parser.exporter :as gp-exporter]
|
||||
#_:clj-kondo/ignore
|
||||
[logseq.outliner.cli :as outliner-cli]
|
||||
[logseq.outliner.pipeline :as outliner-pipeline]
|
||||
[nbb.classpath :as cp]
|
||||
@@ -24,11 +24,11 @@
|
||||
(def original-transact! d/transact!)
|
||||
(defn dev-transact! [conn tx-data tx-meta]
|
||||
(swap! tx-queue (fn [queue]
|
||||
(let [new-queue (conj queue {:tx-data tx-data :tx-meta tx-meta})]
|
||||
(let [new-queue (conj queue {:tx-data tx-data :tx-meta tx-meta})]
|
||||
;; Only care about last few so vary 10 as needed
|
||||
(if (> (count new-queue) 10)
|
||||
(pop new-queue)
|
||||
new-queue))))
|
||||
(if (> (count new-queue) 10)
|
||||
(pop new-queue)
|
||||
new-queue))))
|
||||
(original-transact! conn tx-data tx-meta))
|
||||
|
||||
(defn- build-graph-files
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
"Script that generates all the permutations of property types and cardinality.
|
||||
Also creates a page of queries that exercises most properties
|
||||
NOTE: This script is also used in CI to confirm graph creation works"
|
||||
(:require ["fs-extra$default" :as fse]
|
||||
["fs" :as fs]
|
||||
(:require ["fs" :as fs]
|
||||
["fs-extra$default" :as fse]
|
||||
["os" :as os]
|
||||
["path" :as node-path]
|
||||
[babashka.cli :as cli]
|
||||
|
||||
@@ -180,22 +180,21 @@
|
||||
(state/pub-event! [:editor/new-property {:block class
|
||||
:class-schema? true}]))
|
||||
;; Objects of built-in classes must not be deleted e.g. Tag, Property and Root
|
||||
:on-delete-rows (when-not (:logseq.property/built-in? class)
|
||||
(fn [table selected-rows]
|
||||
(let [pages (->> selected-rows (filter ldb/page?) (remove :logseq.property/built-in?))
|
||||
blocks (->> selected-rows (remove ldb/page?) (remove :logseq.property/built-in?))]
|
||||
(p/do!
|
||||
(set-data! (get-class-objects class))
|
||||
(when-let [f (get-in table [:data-fns :set-row-selection!])]
|
||||
(f {}))
|
||||
(ui-outliner-tx/transact!
|
||||
{:outliner-op :delete-blocks}
|
||||
(when (seq blocks)
|
||||
(outliner-op/delete-blocks! blocks nil))
|
||||
(let [page-ids (map :db/id pages)
|
||||
tx-data (map (fn [pid] [:db/retract pid :block/tags (:db/id class)]) page-ids)]
|
||||
(when (seq tx-data)
|
||||
(outliner-op/transact! tx-data {:outliner-op :save-block}))))))))}))))
|
||||
:on-delete-rows (fn [table selected-rows]
|
||||
(let [pages (->> selected-rows (filter ldb/page?) (remove :logseq.property/built-in?))
|
||||
blocks (->> selected-rows (remove ldb/page?) (remove :logseq.property/built-in?))]
|
||||
(p/do!
|
||||
(set-data! (get-class-objects class))
|
||||
(when-let [f (get-in table [:data-fns :set-row-selection!])]
|
||||
(f {}))
|
||||
(ui-outliner-tx/transact!
|
||||
{:outliner-op :delete-blocks}
|
||||
(when (seq blocks)
|
||||
(outliner-op/delete-blocks! blocks nil))
|
||||
(let [page-ids (map :db/id pages)
|
||||
tx-data (map (fn [pid] [:db/retract pid :block/tags (:db/id class)]) page-ids)]
|
||||
(when (seq tx-data)
|
||||
(outliner-op/transact! tx-data {:outliner-op :save-block})))))))}))))
|
||||
|
||||
(rum/defcs class-objects < rum/reactive db-mixins/query mixins/container-id
|
||||
[state class {:keys [current-page? sidebar?]}]
|
||||
|
||||
@@ -531,25 +531,25 @@
|
||||
[:span.opacity-60 "effect?"]]]
|
||||
[:div.flex.justify-end.pt-3
|
||||
(shui/button
|
||||
{:on-click (fn []
|
||||
(if (or (string/blank? (util/trim-safe url))
|
||||
(not (string/starts-with? url "https://")))
|
||||
(.focus (rum/deref *input))
|
||||
(let [url (string/replace-first url "https://github.com/" "")
|
||||
matched (re-find #"([^\/]+)/([^\/]+)" url)]
|
||||
(if-let [id (some-> matched (nth 2))]
|
||||
(do
|
||||
(set-pending! true)
|
||||
(-> #js {:id id :repo (first matched)
|
||||
:theme (:theme? opts)
|
||||
:effect (:effect? opts)}
|
||||
(js/window.logseq.api.__install_plugin)
|
||||
(p/then #(shui/dialog-close!))
|
||||
(p/catch #(notification/show! (str %) :error))
|
||||
(p/finally #(set-pending! false))))
|
||||
(notification/show! "Invalid GitHub repo url" :error)))))
|
||||
:disabled pending}
|
||||
(if pending (ui/loading "Installing") "Install"))]]))
|
||||
{:on-click (fn []
|
||||
(if (or (string/blank? (util/trim-safe url))
|
||||
(not (string/starts-with? url "https://")))
|
||||
(.focus (rum/deref *input))
|
||||
(let [url (string/replace-first url "https://github.com/" "")
|
||||
matched (re-find #"([^\/]+)/([^\/]+)" url)]
|
||||
(if-let [id (some-> matched (nth 2))]
|
||||
(do
|
||||
(set-pending! true)
|
||||
(-> #js {:id id :repo (first matched)
|
||||
:theme (:theme? opts)
|
||||
:effect (:effect? opts)}
|
||||
(js/window.logseq.api.__install_plugin)
|
||||
(p/then #(shui/dialog-close!))
|
||||
(p/catch #(notification/show! (str %) :error))
|
||||
(p/finally #(set-pending! false))))
|
||||
(notification/show! "Invalid GitHub repo url" :error)))))
|
||||
:disabled pending}
|
||||
(if pending (ui/loading "Installing") "Install"))]]))
|
||||
|
||||
(rum/defc auto-check-for-updates-control
|
||||
[]
|
||||
@@ -979,7 +979,7 @@
|
||||
(lazy-items-loader load-more-pages!)
|
||||
[:div.flex.items-center.justify-center.py-28.flex-col.gap-2.opacity-30
|
||||
(shui/tabler-icon "list-search" {:size 40})
|
||||
[:span.text-sm "Nothing Founded."]])]]))
|
||||
[:span.text-sm "Nothing Found."]])]]))
|
||||
|
||||
(rum/defcs waiting-coming-updates
|
||||
< rum/reactive
|
||||
|
||||
@@ -356,7 +356,7 @@ a.control-link {
|
||||
.inner-wrap {
|
||||
@apply flex items-center w-full justify-between gap-1 flex-wrap;
|
||||
|
||||
> strong {
|
||||
> .property-setting-title {
|
||||
@apply flex items-center gap-1 font-normal opacity-90;
|
||||
}
|
||||
|
||||
|
||||
@@ -259,7 +259,7 @@
|
||||
item-props)
|
||||
[sub-open? set-sub-open!] (rum/use-state false)
|
||||
toggle? (boolean? toggle-checked?)
|
||||
id1 (str (or id icon (random-uuid)))
|
||||
id1 (str (or id (random-uuid)))
|
||||
id2 (str "d2-" id1)
|
||||
or-close-menu-sub! (fn []
|
||||
(when (and (not (shui-popup/get-popup :ls-icon-picker))
|
||||
@@ -287,7 +287,7 @@
|
||||
(wrap-menuitem
|
||||
[:div.inner-wrap.cursor-pointer
|
||||
{:class (util/classnames [{:disabled disabled?}])}
|
||||
[:strong
|
||||
[:div.property-setting-title
|
||||
(some-> icon (name) (shui/tabler-icon {:size 14
|
||||
:style {:margin-top "-1"}}))
|
||||
[:span title]]
|
||||
@@ -690,11 +690,14 @@
|
||||
:logseq.property/hide?
|
||||
%)}))
|
||||
(when (not (contains? #{:logseq.property/parent :logseq.property.class/properties} (:db/ident property)))
|
||||
(dropdown-editor-menuitem {:icon :eye-off :title "Hide empty value" :toggle-checked? (boolean (:logseq.property/hide-empty-value property))
|
||||
:disabled? config/publishing?
|
||||
:on-toggle-checked-change #(db-property-handler/set-block-property! (:db/id property)
|
||||
:logseq.property/hide-empty-value
|
||||
(not (:logseq.property/hide-empty-value property)))}))]
|
||||
(dropdown-editor-menuitem
|
||||
{:icon :eye-off :title "Hide empty value"
|
||||
:toggle-checked? (boolean (:logseq.property/hide-empty-value property))
|
||||
:disabled? config/publishing?
|
||||
:on-toggle-checked-change (fn []
|
||||
(db-property-handler/set-block-property! (:db/id property)
|
||||
:logseq.property/hide-empty-value
|
||||
(not (:logseq.property/hide-empty-value property))))}))]
|
||||
(remove nil?))]
|
||||
(when (> (count group') 0)
|
||||
(cons (shui/dropdown-menu-separator) group'))))
|
||||
@@ -718,15 +721,16 @@
|
||||
{:icon :checkbox
|
||||
:title (if class-schema? "Show as checkbox on tagged nodes" "Show as checkbox on node")
|
||||
:disabled? config/publishing?
|
||||
:desc (shui/switch
|
||||
{:id "show as checkbox" :size "sm"
|
||||
:checked checked?
|
||||
:on-click util/stop-propagation
|
||||
:on-checked-change
|
||||
(fn [value]
|
||||
(if value
|
||||
(db-property-handler/set-block-property! (:db/id owner-block) :logseq.property/checkbox-display-properties (:db/id property))
|
||||
(db-property-handler/delete-property-value! (:db/id owner-block) :logseq.property/checkbox-display-properties (:db/id property))))})})))))
|
||||
:desc (when owner-block
|
||||
(shui/switch
|
||||
{:id "show as checkbox" :size "sm"
|
||||
:checked checked?
|
||||
:on-click util/stop-propagation
|
||||
:on-checked-change
|
||||
(fn [value]
|
||||
(if value
|
||||
(db-property-handler/set-block-property! (:db/id owner-block) :logseq.property/checkbox-display-properties (:db/id property))
|
||||
(db-property-handler/delete-property-value! (:db/id owner-block) :logseq.property/checkbox-display-properties (:db/id property))))}))})))))
|
||||
|
||||
(when (and owner-block
|
||||
;; Any property should be removable from Tag Properties
|
||||
|
||||
@@ -129,3 +129,13 @@ html.is-resizing-buf {
|
||||
.markdown-table {
|
||||
width: 98%;
|
||||
}
|
||||
|
||||
.sticky-columns {
|
||||
@apply sticky left-0;
|
||||
z-index: 99;
|
||||
background-color: var(--lx-gray-01, var(--ls-primary-background-color, hsl(var(--background))));
|
||||
}
|
||||
|
||||
.table-action-bar {
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
[datascript.impl.entity :as de]
|
||||
[dommy.core :as dom]
|
||||
[frontend.components.dnd :as dnd]
|
||||
[frontend.components.property.config :as property-config]
|
||||
[frontend.components.property.value :as pv]
|
||||
[frontend.components.select :as select]
|
||||
[frontend.config :as config]
|
||||
@@ -15,6 +16,7 @@
|
||||
[frontend.date :as date]
|
||||
[frontend.db :as db]
|
||||
[frontend.db-mixins :as db-mixins]
|
||||
[frontend.handler.db-based.property :as db-property-handler]
|
||||
[frontend.handler.property :as property-handler]
|
||||
[frontend.handler.ui :as ui-handler]
|
||||
[frontend.hooks :as hooks]
|
||||
@@ -79,15 +81,65 @@
|
||||
(if (or show? checked?) "opacity-100" "opacity-0"))})]))
|
||||
|
||||
(defn header-cp
|
||||
[{:keys [column-toggle-sorting! state]} column]
|
||||
[{:keys [view-entity 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)]
|
||||
[asc?]))) sorting)
|
||||
property (db/entity (:id column))
|
||||
pinned? (when property
|
||||
(contains? (set (map :db/id (:logseq.property.table/pinned-columns view-entity)))
|
||||
(:db/id property)))
|
||||
sub-content (fn [{:keys [id]}]
|
||||
[:<>
|
||||
(when property
|
||||
(shui/dropdown-menu-sub
|
||||
(shui/dropdown-menu-sub-trigger
|
||||
[:div.flex.flex-row.items-center.gap-1
|
||||
(ui/icon "settings" {:size 15})
|
||||
[:div "Configure"]])
|
||||
(shui/dropdown-menu-sub-content
|
||||
[:div.ls-property-dropdown-editor.-m-1
|
||||
(property-config/dropdown-editor property nil {})])))
|
||||
(shui/dropdown-menu-sub
|
||||
(shui/dropdown-menu-sub-trigger
|
||||
[:div.flex.flex-row.items-center.gap-1
|
||||
(ui/icon "arrows-down-up" {:size 15})
|
||||
[:div.mr-4 "Set order"]
|
||||
(cond asc? [:span.opacity-50.text-sm "ASC"]
|
||||
(false? asc?) [:span.opacity-50.text-sm "DESC"]
|
||||
:else nil)])
|
||||
(shui/dropdown-menu-sub-content
|
||||
{:on-click #(shui/popup-hide! id)}
|
||||
(shui/dropdown-menu-item
|
||||
{:key "asc"
|
||||
:on-click #(column-toggle-sorting! column)}
|
||||
"ASC")
|
||||
(shui/dropdown-menu-item
|
||||
{:key "desc"
|
||||
:on-click #(column-toggle-sorting! column)}
|
||||
"DESC")))
|
||||
(when property
|
||||
(shui/dropdown-menu-item
|
||||
{:on-click (fn [_e]
|
||||
(if pinned?
|
||||
(db-property-handler/delete-property-value! (:db/id view-entity)
|
||||
:logseq.property.table/pinned-columns
|
||||
(:db/id property))
|
||||
(property-handler/set-block-property! (state/get-current-repo)
|
||||
(:db/id view-entity)
|
||||
:logseq.property.table/pinned-columns
|
||||
(:db/id property)))
|
||||
(shui/popup-hide! id))}
|
||||
[:div.flex.flex-row.items-center.gap-1
|
||||
(ui/icon "pin" {:size 15})
|
||||
[:div (if pinned? "Unpin" "Pin")]]))])]
|
||||
(shui/button
|
||||
{:variant "text"
|
||||
:class "h-8 !pl-4 !px-2 !py-0 hover:text-foreground w-full justify-start"
|
||||
:on-click #(column-toggle-sorting! column)}
|
||||
:on-mouse-up (fn [^js e]
|
||||
(when (string/blank? (some-> (.-target e) (.closest "[aria-roledescription=sortable]") (.-style) (.-transform)))
|
||||
(shui/popup-show! (.-target e) sub-content {:align "start" :as-dropdown? true})))}
|
||||
(let [title (str (:name column))]
|
||||
[:span {:title title
|
||||
:class "max-w-full overflow-hidden text-ellipsis"}
|
||||
@@ -323,7 +375,7 @@
|
||||
(when (fn? on-delete-rows)
|
||||
(shui/button
|
||||
{:variant "ghost"
|
||||
:class "h-8 !pl-4 !px-2 !py-0 hover:text-foreground w-full justify-start"
|
||||
:class "h-8 !pl-0 !px-2 !py-0 text-muted-foreground hover:text-foreground w-full justify-start"
|
||||
:on-click (fn []
|
||||
(on-delete-rows table selected-rows))}
|
||||
(ui/icon "trash")))))
|
||||
@@ -410,47 +462,62 @@
|
||||
{:data-no-dnd true
|
||||
:ref *el}]))
|
||||
|
||||
(defn- table-header
|
||||
[table columns {:keys [show-add-property? add-property!] :as option} selected-rows]
|
||||
(let [set-ordered-columns! (get-in table [:data-fns :set-ordered-columns!])
|
||||
set-sized-columns! (get-in table [:data-fns :set-sized-columns!])
|
||||
(defn- table-header-cell
|
||||
[table column]
|
||||
(let [header-fn (:header column)
|
||||
sized-columns (get-in table [:state :sized-columns])
|
||||
items (mapv (fn [column]
|
||||
{:id (:name column)
|
||||
:value (:id column)
|
||||
:content (let [header-fn (:header column)
|
||||
width (get-column-size column sized-columns)
|
||||
select? (= :select (:id column))]
|
||||
[:div.ls-table-header-cell
|
||||
{:style {:width width
|
||||
:min-width width}
|
||||
:class (when select? "!border-0")}
|
||||
(if (fn? header-fn)
|
||||
(header-fn table column)
|
||||
header-fn)
|
||||
set-sized-columns! (get-in table [:data-fns :set-sized-columns!])
|
||||
width (get-column-size column sized-columns)
|
||||
select? (= :select (:id column))]
|
||||
[:div.ls-table-header-cell
|
||||
{:style {:width width
|
||||
:min-width width}
|
||||
:class (when select? "!border-0")}
|
||||
(if (fn? header-fn)
|
||||
(header-fn table column)
|
||||
header-fn)
|
||||
;; resize handle
|
||||
(when-not (false? (:resizable? column))
|
||||
(column-resizer column
|
||||
(fn [size]
|
||||
(set-sized-columns! (assoc sized-columns (:id column) size)))))])
|
||||
:disabled? (= (:id column) :select)}) columns)
|
||||
items (if show-add-property?
|
||||
(conj items
|
||||
{:id "add property"
|
||||
:prop {:style {:width "-webkit-fill-available"
|
||||
:min-width 160}
|
||||
:on-click (fn [] (when (fn? add-property!) (add-property!)))}
|
||||
:value :add-new-property
|
||||
:content (add-property-button)
|
||||
:disabled? true})
|
||||
items)
|
||||
(when-not (false? (:resizable? column))
|
||||
(column-resizer column
|
||||
(fn [size]
|
||||
(set-sized-columns! (assoc sized-columns (:id column) size)))))]))
|
||||
|
||||
(defn- table-header
|
||||
[table {:keys [show-add-property? add-property!] :as option} selected-rows]
|
||||
(let [set-ordered-columns! (get-in table [:data-fns :set-ordered-columns!])
|
||||
pinned (get-in table [:state :pinned-columns])
|
||||
unpinned (get-in table [:state :unpinned-columns])
|
||||
build-item (fn [column]
|
||||
{:id (:name column)
|
||||
:value (:id column)
|
||||
:content (table-header-cell table column)
|
||||
:disabled? (= (:id column) :select)})
|
||||
pinned-items (mapv build-item pinned)
|
||||
unpinned-items (if show-add-property?
|
||||
(conj (mapv build-item unpinned)
|
||||
{:id "add property"
|
||||
:prop {:style {:width "-webkit-fill-available"
|
||||
:min-width 160}
|
||||
:on-click (fn [] (when (fn? add-property!) (add-property!)))}
|
||||
:value :add-new-property
|
||||
:content (add-property-button)
|
||||
:disabled? true})
|
||||
(mapv build-item unpinned))
|
||||
selection-rows-count (count selected-rows)]
|
||||
(shui/table-header
|
||||
(dnd/items items {:vertical? false
|
||||
:on-drag-end (fn [ordered-columns _m]
|
||||
(set-ordered-columns! ordered-columns))})
|
||||
(when (seq pinned-items)
|
||||
[:div.sticky-columns.flex.flex-row
|
||||
(dnd/items pinned-items {:vertical? false
|
||||
:on-drag-end (fn [ordered-columns _m]
|
||||
(set-ordered-columns! ordered-columns))})])
|
||||
(when (seq unpinned-items)
|
||||
[:div.flex.flex-row
|
||||
(dnd/items unpinned-items
|
||||
{:vertical? false
|
||||
:on-drag-end (fn [ordered-columns _m]
|
||||
(set-ordered-columns! ordered-columns))})])
|
||||
(when (pos? selection-rows-count)
|
||||
[:div.absolute.top-0.left-8
|
||||
[:div.table-action-bar.absolute.top-0.left-8
|
||||
(action-bar table selected-rows option)]))))
|
||||
|
||||
(rum/defc row-cell < rum/static
|
||||
@@ -468,41 +535,46 @@
|
||||
(render table row column)))))
|
||||
|
||||
(rum/defc table-row-inner < rum/static
|
||||
[{:keys [row-selected?] :as table} row columns props {:keys [show-add-property?]}]
|
||||
[{:keys [row-selected?] :as table} row props {:keys [show-add-property?]}]
|
||||
(let [[first-col-rendered? set-first-col-rendered!] (rum/use-state false)
|
||||
columns (if show-add-property?
|
||||
(conj (vec columns)
|
||||
{:id :add-property
|
||||
:cell (fn [_table _row _column])})
|
||||
columns)
|
||||
sized-columns (get-in table [:state :sized-columns])]
|
||||
pinned-columns (get-in table [:state :pinned-columns])
|
||||
unpinned (get-in table [:state :unpinned-columns])
|
||||
unpinned-columns (if show-add-property?
|
||||
(conj (vec unpinned)
|
||||
{:id :add-property
|
||||
:cell (fn [_table _row _column])})
|
||||
unpinned)
|
||||
sized-columns (get-in table [:state :sized-columns])
|
||||
row-cell-f (fn [idx column]
|
||||
(let [idx (inc idx)
|
||||
id (str (:id row) "-" (:id column))
|
||||
render (get column :cell)
|
||||
width (get-column-size column sized-columns)
|
||||
select? (= (:id column) :select)
|
||||
add-property? (= (:id column) :add-property)
|
||||
cell-opts {:key id
|
||||
:select? select?
|
||||
:add-property? add-property?
|
||||
:style {:width width
|
||||
:min-width width}}]
|
||||
(when render
|
||||
(row-cell table row column render cell-opts idx first-col-rendered? set-first-col-rendered!))))]
|
||||
(shui/table-row
|
||||
(merge
|
||||
props
|
||||
{:key (str (:id row))
|
||||
:data-state (when (row-selected? row) "selected")})
|
||||
(map-indexed
|
||||
(fn [idx column]
|
||||
(let [id (str (:id row) "-" (:id column))
|
||||
render (get column :cell)
|
||||
width (get-column-size column sized-columns)
|
||||
select? (= (:id column) :select)
|
||||
add-property? (= (:id column) :add-property)
|
||||
cell-opts {:key id
|
||||
:select? select?
|
||||
:add-property? add-property?
|
||||
:style {:width width
|
||||
:min-width width}}]
|
||||
(when render
|
||||
(row-cell table row column render cell-opts idx first-col-rendered? set-first-col-rendered!))))
|
||||
columns))))
|
||||
[:div.sticky-columns.flex.flex-row
|
||||
(map-indexed row-cell-f pinned-columns)]
|
||||
[:div.flex.flex-row
|
||||
(map-indexed row-cell-f unpinned-columns)])))
|
||||
|
||||
(rum/defc table-row < rum/reactive
|
||||
[table row columns props option]
|
||||
[table row props option]
|
||||
(let [row' (db/sub-block (:id row))
|
||||
;; merge entity temporal attributes
|
||||
row (reduce (fn [e [k v]] (assoc e k v)) row' (.-kv ^js row))]
|
||||
(table-row-inner table row columns props option)))
|
||||
(table-row-inner table row props option)))
|
||||
|
||||
(rum/defc search
|
||||
[input {:keys [on-change set-input!]}]
|
||||
@@ -1091,13 +1163,12 @@
|
||||
[])
|
||||
|
||||
(shui/table
|
||||
(let [columns' (:columns table)
|
||||
rows (:rows table)]
|
||||
(let [rows (:rows table)]
|
||||
[:div.ls-table-rows.content.overflow-x-auto.force-visible-scrollbar
|
||||
{:ref *rows-wrap}
|
||||
(when ready?
|
||||
[:div.relative
|
||||
(table-header table columns' option selected-rows)
|
||||
(table-header table option selected-rows)
|
||||
|
||||
(ui/virtualized-list
|
||||
{:ref #(reset! *scroller-ref %)
|
||||
@@ -1110,7 +1181,7 @@
|
||||
:total-count (count rows)
|
||||
:item-content (fn [idx]
|
||||
(let [row (nth rows idx)]
|
||||
(table-row table row columns' {} option)))})
|
||||
(table-row table row {} option)))})
|
||||
|
||||
(when add-new-object!
|
||||
(shui/table-footer (add-new-row table)))])]))))
|
||||
@@ -1184,7 +1255,7 @@
|
||||
(state/set-state! :editor/virtualized-scroll-fn #(ui-handler/scroll-to-anchor-block @*scroller-ref data' gallery?)))))
|
||||
[sorting data])))
|
||||
|
||||
(rum/defc view-inner < rum/static
|
||||
(rum/defc ^:large-vars/cleanup-todo view-inner < rum/static
|
||||
[view-entity {:keys [data set-data! columns add-new-object! views-title title-key render-empty-title?] :as option
|
||||
:or {render-empty-title? false}}
|
||||
*scroller-ref]
|
||||
@@ -1193,7 +1264,7 @@
|
||||
[sorting set-sorting!] (rum/use-state (or sorting [{:id :block/updated-at, :asc? false}]))
|
||||
filters (:logseq.property.table/filters view-entity)
|
||||
[filters set-filters!] (rum/use-state (or filters []))
|
||||
default-visible-columns (if-let [hidden-columns (:logseq.property.table/hidden-columns view-entity)]
|
||||
default-visible-columns (if-let [hidden-columns (conj (:logseq.property.table/hidden-columns view-entity) :id)]
|
||||
(zipmap hidden-columns (repeat false))
|
||||
;; This case can happen for imported tables
|
||||
(if (seq (:logseq.property.table/ordered-columns view-entity))
|
||||
@@ -1220,7 +1291,20 @@
|
||||
[input-filters set-input-filters!] (rum/use-state [input filters])
|
||||
[row-selection set-row-selection!] (rum/use-state {})
|
||||
columns (sort-columns columns ordered-columns)
|
||||
table-map {:data data
|
||||
select? (first (filter (fn [item] (= (:id item) :select)) columns))
|
||||
id? (first (filter (fn [item] (= (:id item) :id)) columns))
|
||||
pinned-properties (set (cond->> (map :db/ident (:logseq.property.table/pinned-columns view-entity))
|
||||
id?
|
||||
(cons :id)
|
||||
select?
|
||||
(cons :select)))
|
||||
{pinned true unpinned false} (group-by (fn [item]
|
||||
(contains? pinned-properties (:id item)))
|
||||
(remove (fn [column]
|
||||
(false? (get visible-columns (:id column))))
|
||||
columns))
|
||||
table-map {:view-entity view-entity
|
||||
:data data
|
||||
:columns columns
|
||||
:state {:sorting sorting
|
||||
:filters filters
|
||||
@@ -1228,7 +1312,9 @@
|
||||
:row-selection row-selection
|
||||
:visible-columns visible-columns
|
||||
:sized-columns sized-columns
|
||||
:ordered-columns ordered-columns}
|
||||
:ordered-columns ordered-columns
|
||||
:pinned-columns pinned
|
||||
:unpinned-columns unpinned}
|
||||
:data-fns {:set-data! set-data!
|
||||
:set-row-filter! set-row-filter!
|
||||
:set-filters! set-filters!
|
||||
|
||||
@@ -67,7 +67,7 @@
|
||||
"Installs plugin given plugin map with id"
|
||||
[{:keys [id] :as manifest}]
|
||||
(when-not (and (:plugin/installing @state/state)
|
||||
(installed? id))
|
||||
(installed? id))
|
||||
(state/set-state! :plugin/installing manifest)
|
||||
(if (util/electron?)
|
||||
(ipc/ipc :installMarketPlugin manifest)
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
(:require [clojure.string :as string]
|
||||
[datascript.impl.entity :as de]
|
||||
[frontend.db :as db]
|
||||
[frontend.db.async :as db-async]
|
||||
[frontend.handler.common.page :as page-common-handler]
|
||||
[frontend.handler.db-based.property :as db-property-handler]
|
||||
[frontend.handler.editor :as editor-handler]
|
||||
@@ -12,11 +13,10 @@
|
||||
[logseq.common.util.page-ref :as page-ref]
|
||||
[logseq.db]
|
||||
[logseq.db.frontend.class :as db-class]
|
||||
[logseq.outliner.validate :as outliner-validate]
|
||||
[promesa.core :as p]
|
||||
[frontend.db.async :as db-async]
|
||||
[logseq.db.frontend.content :as db-content]
|
||||
[logseq.shui.ui :as shui]))
|
||||
[logseq.outliner.validate :as outliner-validate]
|
||||
[logseq.shui.ui :as shui]
|
||||
[promesa.core :as p]))
|
||||
|
||||
(defn- valid-tag?
|
||||
"Returns a boolean indicating whether the new tag passes all valid checks.
|
||||
@@ -60,25 +60,25 @@
|
||||
(if (db/page-exists? (:block/title page-entity) #{:logseq.class/Page})
|
||||
(notification/show! (str "A page with the name \"" (:block/title page-entity) "\" already exists.") :warning false)
|
||||
(when-not (:logseq.property/built-in? page-entity)
|
||||
(p/let [objects (db-async/<get-tag-objects (state/get-current-repo) (:db/id page-entity))]
|
||||
(let [convert-fn
|
||||
(fn convert-fn []
|
||||
(let [page-txs [[:db/retract (:db/id page-entity) :db/ident]
|
||||
[:db/retract (:db/id page-entity) :block/tags :logseq.class/Tag]
|
||||
[:db/add (:db/id page-entity) :block/tags :logseq.class/Page]]
|
||||
obj-txs (mapcat (fn [obj]
|
||||
(let [tags (map #(db/entity (state/get-current-repo) (:db/id %)) (:block/tags obj))]
|
||||
[{:db/id (:db/id obj)
|
||||
:block/title (db-content/replace-tag-refs-with-page-refs (:block/title obj) tags)}
|
||||
[:db/retract (:db/id obj) :block/tags (:db/id page-entity)]]))
|
||||
objects)
|
||||
txs (concat page-txs obj-txs)]
|
||||
(db/transact! (state/get-current-repo) txs {:outliner-op :save-block})))]
|
||||
(-> (shui/dialog-confirm!
|
||||
"Converting a tag to page also removes tags from any nodes that have that tag. Are you ok with that?"
|
||||
{:id :convert-tag-to-page
|
||||
:data-reminder :ok})
|
||||
(p/then convert-fn)))))))
|
||||
(p/let [objects (db-async/<get-tag-objects (state/get-current-repo) (:db/id page-entity))]
|
||||
(let [convert-fn
|
||||
(fn convert-fn []
|
||||
(let [page-txs [[:db/retract (:db/id page-entity) :db/ident]
|
||||
[:db/retract (:db/id page-entity) :block/tags :logseq.class/Tag]
|
||||
[:db/add (:db/id page-entity) :block/tags :logseq.class/Page]]
|
||||
obj-txs (mapcat (fn [obj]
|
||||
(let [tags (map #(db/entity (state/get-current-repo) (:db/id %)) (:block/tags obj))]
|
||||
[{:db/id (:db/id obj)
|
||||
:block/title (db-content/replace-tag-refs-with-page-refs (:block/title obj) tags)}
|
||||
[:db/retract (:db/id obj) :block/tags (:db/id page-entity)]]))
|
||||
objects)
|
||||
txs (concat page-txs obj-txs)]
|
||||
(db/transact! (state/get-current-repo) txs {:outliner-op :save-block})))]
|
||||
(-> (shui/dialog-confirm!
|
||||
"Converting a tag to page also removes tags from any nodes that have that tag. Are you ok with that?"
|
||||
{:id :convert-tag-to-page
|
||||
:data-reminder :ok})
|
||||
(p/then convert-fn)))))))
|
||||
|
||||
(defn <create-class!
|
||||
"Creates a class page and provides class-specific error handling"
|
||||
|
||||
@@ -676,7 +676,8 @@
|
||||
[61 {:properties [:logseq.property/type :logseq.property/hide? :logseq.property/public? :logseq.property/view-context :logseq.property/ui-position]
|
||||
:fix (rename-properties {:property/schema.classes :logseq.property/classes
|
||||
:property.value/content :logseq.property/value})}]
|
||||
[62 {:fix remove-block-schema}]])
|
||||
[62 {:fix remove-block-schema}]
|
||||
[63 {:properties [:logseq.property.table/pinned-columns]}]])
|
||||
|
||||
(let [max-schema-version (apply max (map first schema-version->updates))]
|
||||
(assert (<= db-schema/version max-schema-version))
|
||||
|
||||
@@ -17,8 +17,8 @@
|
||||
[frontend.fs :as fs]
|
||||
[frontend.handler.code :as code-handler]
|
||||
[frontend.handler.command-palette :as palette-handler]
|
||||
[frontend.handler.common.plugin :as plugin-common-handler]
|
||||
[frontend.handler.common.page :as page-common-handler]
|
||||
[frontend.handler.common.plugin :as plugin-common-handler]
|
||||
[frontend.handler.config :as config-handler]
|
||||
[frontend.handler.db-based.property :as db-property-handler]
|
||||
[frontend.handler.dnd :as editor-dnd-handler]
|
||||
@@ -896,14 +896,14 @@
|
||||
(when-let [k' (and (string? k) (some-> k (sanitize-user-property-name) (keyword)))]
|
||||
(let [prefix (-resolve-property-prefix-for-db plugin)]
|
||||
(p/let [k (if (qualified-keyword? k') k'
|
||||
(api-block/get-db-ident-for-user-property-name (str prefix k)))
|
||||
(api-block/get-db-ident-for-user-property-name (str prefix k)))
|
||||
p (db-utils/pull k)] p))))
|
||||
|
||||
(defn ^:export get_property
|
||||
[k]
|
||||
(this-as this
|
||||
(p/let [prop (-get-property this k)]
|
||||
(bean/->js (sdk-utils/normalize-keyword-for-json prop)))))
|
||||
(p/let [prop (-get-property this k)]
|
||||
(bean/->js (sdk-utils/normalize-keyword-for-json prop)))))
|
||||
|
||||
(defn ^:export upsert_property
|
||||
"schema:
|
||||
@@ -915,87 +915,87 @@
|
||||
"
|
||||
[k ^js schema ^js opts]
|
||||
(this-as this
|
||||
(when-let [k' (and (string? k) (keyword k))]
|
||||
(let [prefix (when (some-> js/window.LSPlugin (.-PluginLocal) (instance? this))
|
||||
(str (.-id this) "."))]
|
||||
(p/let [opts (or (some-> opts (bean/->clj)) {})
|
||||
name (or (:name opts) (some-> (str k) (string/trim)))
|
||||
k (if (qualified-keyword? k') k'
|
||||
(api-block/get-db-ident-for-user-property-name (str prefix k)))
|
||||
schema (or (some-> schema (bean/->clj)
|
||||
(update-keys #(if (contains? #{:hide :public} %)
|
||||
(keyword (str (name %) "?")) %))) {})
|
||||
schema (cond-> schema
|
||||
(string? (:cardinality schema))
|
||||
(update :cardinality keyword)
|
||||
(string? (:type schema))
|
||||
(update :type keyword))
|
||||
p (db-property-handler/upsert-property! k schema
|
||||
(cond-> opts
|
||||
name
|
||||
(assoc :property-name name)))]
|
||||
(bean/->js (sdk-utils/normalize-keyword-for-json p)))))))
|
||||
(when-let [k' (and (string? k) (keyword k))]
|
||||
(let [prefix (when (some-> js/window.LSPlugin (.-PluginLocal) (instance? this))
|
||||
(str (.-id this) "."))]
|
||||
(p/let [opts (or (some-> opts (bean/->clj)) {})
|
||||
name (or (:name opts) (some-> (str k) (string/trim)))
|
||||
k (if (qualified-keyword? k') k'
|
||||
(api-block/get-db-ident-for-user-property-name (str prefix k)))
|
||||
schema (or (some-> schema (bean/->clj)
|
||||
(update-keys #(if (contains? #{:hide :public} %)
|
||||
(keyword (str (name %) "?")) %))) {})
|
||||
schema (cond-> schema
|
||||
(string? (:cardinality schema))
|
||||
(update :cardinality keyword)
|
||||
(string? (:type schema))
|
||||
(update :type keyword))
|
||||
p (db-property-handler/upsert-property! k schema
|
||||
(cond-> opts
|
||||
name
|
||||
(assoc :property-name name)))]
|
||||
(bean/->js (sdk-utils/normalize-keyword-for-json p)))))))
|
||||
|
||||
(defn ^:export remove_property
|
||||
[k]
|
||||
(this-as this
|
||||
(p/let [prop (-get-property this k)]
|
||||
(when-let [uuid (:block/uuid prop)]
|
||||
(page-common-handler/<delete! uuid nil nil)))))
|
||||
(p/let [prop (-get-property this k)]
|
||||
(when-let [uuid (:block/uuid prop)]
|
||||
(page-common-handler/<delete! uuid nil nil)))))
|
||||
|
||||
;; block properties
|
||||
(defn ^:export upsert_block_property
|
||||
[block-uuid keyname value]
|
||||
(this-as this
|
||||
(p/let [keyname (sanitize-user-property-name keyname)
|
||||
block-uuid (sdk-utils/uuid-or-throw-error block-uuid)
|
||||
repo (state/get-current-repo)
|
||||
_ (db-async/<get-block repo block-uuid :children? false)
|
||||
db? (config/db-based-graph? repo)
|
||||
key (-> (if (keyword? key) (name keyname) keyname) (util/safe-lower-case))
|
||||
key (if db?
|
||||
(api-block/get-db-ident-for-user-property-name
|
||||
(str (-resolve-property-prefix-for-db this) key))
|
||||
key)
|
||||
_ (when (and db? (not (db-utils/entity key)))
|
||||
(db-property-handler/upsert-property! key {} {:property-name keyname}))]
|
||||
(property-handler/set-block-property! repo block-uuid key value))))
|
||||
(p/let [keyname (sanitize-user-property-name keyname)
|
||||
block-uuid (sdk-utils/uuid-or-throw-error block-uuid)
|
||||
repo (state/get-current-repo)
|
||||
_ (db-async/<get-block repo block-uuid :children? false)
|
||||
db? (config/db-based-graph? repo)
|
||||
key (-> (if (keyword? key) (name keyname) keyname) (util/safe-lower-case))
|
||||
key (if db?
|
||||
(api-block/get-db-ident-for-user-property-name
|
||||
(str (-resolve-property-prefix-for-db this) key))
|
||||
key)
|
||||
_ (when (and db? (not (db-utils/entity key)))
|
||||
(db-property-handler/upsert-property! key {} {:property-name keyname}))]
|
||||
(property-handler/set-block-property! repo block-uuid key value))))
|
||||
|
||||
(defn ^:export remove_block_property
|
||||
[block-uuid key]
|
||||
(this-as this
|
||||
(p/let [key (sanitize-user-property-name key)
|
||||
block-uuid (sdk-utils/uuid-or-throw-error block-uuid)
|
||||
_ (db-async/<get-block (state/get-current-repo) block-uuid :children? false)
|
||||
db? (config/db-based-graph? (state/get-current-repo))
|
||||
key-ns? (and (keyword? key) (namespace key))
|
||||
key (if key-ns? key (-> (if (keyword? key) (name key) key) (util/safe-lower-case)))
|
||||
key (if (and db? (not key-ns?))
|
||||
(api-block/get-db-ident-for-user-property-name
|
||||
(str (-resolve-property-prefix-for-db this) key))
|
||||
key)]
|
||||
(property-handler/remove-block-property!
|
||||
(state/get-current-repo)
|
||||
block-uuid key))))
|
||||
(p/let [key (sanitize-user-property-name key)
|
||||
block-uuid (sdk-utils/uuid-or-throw-error block-uuid)
|
||||
_ (db-async/<get-block (state/get-current-repo) block-uuid :children? false)
|
||||
db? (config/db-based-graph? (state/get-current-repo))
|
||||
key-ns? (and (keyword? key) (namespace key))
|
||||
key (if key-ns? key (-> (if (keyword? key) (name key) key) (util/safe-lower-case)))
|
||||
key (if (and db? (not key-ns?))
|
||||
(api-block/get-db-ident-for-user-property-name
|
||||
(str (-resolve-property-prefix-for-db this) key))
|
||||
key)]
|
||||
(property-handler/remove-block-property!
|
||||
(state/get-current-repo)
|
||||
block-uuid key))))
|
||||
|
||||
(defn ^:export get_block_property
|
||||
[block-uuid key]
|
||||
(this-as this
|
||||
(p/let [block-uuid (sdk-utils/uuid-or-throw-error block-uuid)
|
||||
_ (db-async/<get-block (state/get-current-repo) block-uuid :children? false)]
|
||||
(when-let [properties (some-> block-uuid (db-model/get-block-by-uuid) (:block/properties))]
|
||||
(when (seq properties)
|
||||
(let [key (sanitize-user-property-name key)
|
||||
property-name (-> (if (keyword? key) (name key) key) (util/safe-lower-case))
|
||||
property-value (or (get properties key)
|
||||
(get properties (keyword property-name))
|
||||
(get properties
|
||||
(api-block/get-db-ident-for-user-property-name
|
||||
(str (-resolve-property-prefix-for-db this) property-name))))
|
||||
property-value (if-let [property-id (:db/id property-value)]
|
||||
(db/pull property-id) property-value)
|
||||
ret (sdk-utils/normalize-keyword-for-json property-value)]
|
||||
(bean/->js ret)))))))
|
||||
(p/let [block-uuid (sdk-utils/uuid-or-throw-error block-uuid)
|
||||
_ (db-async/<get-block (state/get-current-repo) block-uuid :children? false)]
|
||||
(when-let [properties (some-> block-uuid (db-model/get-block-by-uuid) (:block/properties))]
|
||||
(when (seq properties)
|
||||
(let [key (sanitize-user-property-name key)
|
||||
property-name (-> (if (keyword? key) (name key) key) (util/safe-lower-case))
|
||||
property-value (or (get properties key)
|
||||
(get properties (keyword property-name))
|
||||
(get properties
|
||||
(api-block/get-db-ident-for-user-property-name
|
||||
(str (-resolve-property-prefix-for-db this) property-name))))
|
||||
property-value (if-let [property-id (:db/id property-value)]
|
||||
(db/pull property-id) property-value)
|
||||
ret (sdk-utils/normalize-keyword-for-json property-value)]
|
||||
(bean/->js ret)))))))
|
||||
|
||||
(def ^:export get_block_properties
|
||||
(fn [block-uuid]
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
(ns frontend.worker.undo-redo-test
|
||||
(:require [cljs.pprint :as pp]
|
||||
(:require ["fs" :as fs-node]
|
||||
[cljs.pprint :as pp]
|
||||
[clojure.test :as t :refer [deftest is testing use-fixtures]]
|
||||
[clojure.test.check.generators :as gen]
|
||||
[clojure.walk :as walk]
|
||||
@@ -8,13 +9,12 @@
|
||||
[frontend.test.generators :as t.gen]
|
||||
[frontend.test.helper :as test-helper]
|
||||
[frontend.worker.fixtures :as worker-fixtures]
|
||||
[frontend.worker.state :as worker-state]
|
||||
[frontend.worker.undo-redo :as undo-redo]
|
||||
[logseq.db :as ldb]
|
||||
[logseq.db.sqlite.util :as sqlite-util]
|
||||
[logseq.outliner.op :as outliner-op]
|
||||
[logseq.outliner.tree :as otree]
|
||||
[frontend.worker.state :as worker-state]
|
||||
["fs" :as fs-node]
|
||||
[logseq.db.sqlite.util :as sqlite-util]))
|
||||
[logseq.outliner.tree :as otree]))
|
||||
|
||||
(def ^:private page-uuid (random-uuid))
|
||||
(def ^:private init-data (test-helper/initial-test-page-and-blocks {:page-uuid page-uuid}))
|
||||
@@ -30,7 +30,6 @@
|
||||
(worker-fixtures/listen-test-db-fixture [:gen-undo-ops])
|
||||
worker-fixtures/listen-test-db-to-write-tx-log-json-file)
|
||||
|
||||
|
||||
(def ^:private gen-non-exist-block-uuid gen/uuid)
|
||||
|
||||
(defn- gen-block-uuid
|
||||
@@ -116,7 +115,6 @@
|
||||
[?left :block/uuid ?left-uuid]]
|
||||
db))))
|
||||
|
||||
|
||||
(defn- check-block-count
|
||||
[{:keys [op tx]} current-db]
|
||||
(case (first op)
|
||||
@@ -281,8 +279,6 @@
|
||||
(fs-node/writeFileSync "debug.json" (sqlite-util/write-transit-str data))
|
||||
(throw (js/Error "check debug.json"))))))
|
||||
|
||||
|
||||
|
||||
(comment
|
||||
(deftest debug-test
|
||||
(let [{:keys [origin-db db illegal-entity other]}
|
||||
|
||||
Reference in New Issue
Block a user