Explorar o código

Merge branch 'feat/db' into feat/capacitor-new

Tienson Qin hai 5 meses
pai
achega
5634b8acf7

+ 1 - 1
.github/workflows/build.yml

@@ -2,7 +2,7 @@ name: CI
 
 on:
   push:
-    branches: [master]
+    branches: [master, "feat/db"]
     paths-ignore:
       - '*.md'
   pull_request:

+ 1 - 1
.github/workflows/db.yml

@@ -3,7 +3,7 @@ name: logseq/db CI
 on:
   # Path filters ensure jobs only kick off if a change is made to db
   push:
-    branches: [master]
+    branches: [master, "feat/db"]
     paths:
       - 'deps/db/**'
       - '.github/workflows/db.yml'

+ 1 - 1
.github/workflows/graph-parser.yml

@@ -4,7 +4,7 @@ on:
   # Path filters ensure jobs only kick off if a change is made to graph-parser or
   # its local dependencies
   push:
-    branches: [master]
+    branches: [master, "feat/db"]
     paths:
       - 'deps/graph-parser/**'
       # db is a local dep that could break functionality in this lib and should trigger this

+ 1 - 1
.github/workflows/logseq-common.yml

@@ -3,7 +3,7 @@ name: logseq/common CI
 on:
   # Path filters ensure jobs only kick off if a change is made to common
   push:
-    branches: [master]
+    branches: [master, "feat/db"]
     paths:
       - 'deps/common/**'
       - '.github/workflows/logseq-common.yml'

+ 1 - 1
.github/workflows/outliner.yml

@@ -4,7 +4,7 @@ on:
   # Path filters ensure jobs only kick off if a change is made to outliner or
   # its local dependencies
   push:
-    branches: [master]
+    branches: [master, "feat/db"]
     paths:
       - 'deps/outliner/**'
       # db is a local dep that could break functionality in this lib and should trigger this

+ 1 - 1
.github/workflows/publishing.yml

@@ -4,7 +4,7 @@ on:
   # Path filters ensure jobs only kick off if a change is made to publishing or
   # its local dependencies
   push:
-    branches: [master]
+    branches: [master, "feat/db"]
     paths:
       - 'deps/publishing/**'
       # db is a local dep that could break functionality in this lib and should trigger this

+ 8 - 1
clj-e2e/dev/user.clj

@@ -13,6 +13,7 @@
             [logseq.e2e.reference-basic-test]
             [logseq.e2e.rtc-basic-test]
             [logseq.e2e.rtc-extra-test]
+            [logseq.e2e.property-basic-test]
             [logseq.e2e.util :as util]
             [wally.main :as w]
             [wally.repl :as repl]))
@@ -35,6 +36,11 @@
   (->> (future (run-tests 'logseq.e2e.commands-basic-test))
        (swap! *futures assoc :commands-test)))
 
+(defn run-property-basic-test
+  []
+  (->> (future (run-tests 'logseq.e2e.property-basic-test))
+       (swap! *futures assoc :property-test)))
+
 (defn run-outliner-test
   []
   (->> (future (run-tests 'logseq.e2e.outliner-basic-test))
@@ -72,7 +78,8 @@
              'logseq.e2e.outliner-basic-test
              'logseq.e2e.rtc-basic-test
              'logseq.e2e.plugins-basic-test
-             'logseq.e2e.reference-basic-test))
+             'logseq.e2e.reference-basic-test
+             'logseq.e2e.property-basic-test))
 
 (defn start
   []

+ 9 - 3
clj-e2e/src/logseq/e2e/page.clj

@@ -1,13 +1,19 @@
 (ns logseq.e2e.page
-  (:require [logseq.e2e.assert :as assert]
+  (:require [logseq.e2e.keyboard :as k]
             [logseq.e2e.util :as util]
             [wally.main :as w]
-            [wally.selectors :as ws]))
+            [wally.selectors :as ws])
+  (:import (com.microsoft.playwright TimeoutError)))
 
 (defn goto-page
   [page-name]
   (assert (string? page-name) page-name)
-  (util/search-and-click page-name))
+  (try
+    (util/search-and-click page-name)
+    (catch TimeoutError _e
+      ;; try one more time
+      (k/esc)
+      (util/search-and-click page-name))))
 
 (defn new-page
   [title]

+ 0 - 11
clj-e2e/test/logseq/e2e/commands_basic_test.clj

@@ -1,7 +1,5 @@
 (ns logseq.e2e.commands-basic-test
   (:require
-   [clj-time.core :as t]
-   [clj-time.local :as tl]
    [clojure.string :as string]
    [clojure.test :refer [deftest testing is use-fixtures]]
    [logseq.e2e.assert :as assert]
@@ -297,12 +295,3 @@
     (util/exit-edit)
     (w/click "a.cloze")
     (w/wait-for "a.cloze-revealed")))
-
-(deftest new-property-test
-  (testing "new property"
-    (b/new-block "")
-    (util/input-command "add new property")
-    (util/input "p1")
-    (w/click "a:has-text(\"+ New option: p1\")")
-    (k/enter)
-    (is (= "p1" (util/get-text "a.property-k")))))

+ 20 - 20
clj-e2e/test/logseq/e2e/custom_report.clj

@@ -13,6 +13,8 @@
 
 (def ^:dynamic *pw-page->console-logs* nil)
 
+(def ^:dynamic *preserve-graph* nil)
+
 (defn screenshot
   [page test-name]
   (println :screenshot test-name)
@@ -22,6 +24,22 @@
        (.setPath (java.nio.file.Paths/get "e2e-dump/"
                                           (into-array [(format "./screenshot-%s-%s.png" test-name (System/currentTimeMillis))]))))))
 
+(defn- collect-info-when-error-or-failed
+  []
+  ;; screenshot for all pw pages when :error
+  (when-let [all-contexts (seq *pw-contexts*)]
+    (doseq [page (mapcat pw-page/get-pages all-contexts)]
+      (screenshot page (string/join "-" (map (comp str :name meta) t/*testing-vars*)))))
+
+  ;; dump console logs
+  (when-let [pw-page->console-logs (some-> *pw-page->console-logs* deref)]
+    (doseq [[_pw-page logs] pw-page->console-logs]
+      (spit (format "e2e-dump/console-logs-%s.txt" (System/currentTimeMillis))
+            (with-out-str (pp/pprint logs)))))
+
+  (when (some? *preserve-graph*)
+    (set! *preserve-graph* true)))
+
 (defmethod t/report :error
   [m]
   ;; copy from default impl
@@ -37,16 +55,7 @@
         (stack/print-cause-trace actual t/*stack-trace-depth*)
         (prn actual))))
 
-  ;; screenshot for all pw pages when :error
-  (when-let [all-contexts (seq *pw-contexts*)]
-    (doseq [page (mapcat pw-page/get-pages all-contexts)]
-      (screenshot page (string/join "-" (map (comp str :name meta) t/*testing-vars*)))))
-
-  ;; dump console logs
-  (when-let [pw-page->console-logs (some-> *pw-page->console-logs* deref)]
-    (doseq [[_pw-page logs] pw-page->console-logs]
-      (spit (format "e2e-dump/console-logs-%s.txt" (System/currentTimeMillis))
-            (with-out-str (pp/pprint logs))))))
+  (collect-info-when-error-or-failed))
 
 (defmethod t/report :fail
   [m]
@@ -58,13 +67,4 @@
     (println "expected:" (pr-str (:expected m)))
     (println "  actual:" (pr-str (:actual m))))
 
-  ;; screenshot for all pw pages when :fail
-  (when-let [all-contexts (seq *pw-contexts*)]
-    (doseq [page (mapcat pw-page/get-pages all-contexts)]
-      (screenshot page (string/join "-" (map (comp str :name meta) t/*testing-vars*)))))
-
-;; dump console logs
-  (when-let [pw-page->console-logs (some-> *pw-page->console-logs* deref)]
-    (doseq [[_pw-page logs] pw-page->console-logs]
-      (spit (format "e2e-dump/console-logs-%s.txt" (System/currentTimeMillis))
-            (with-out-str (pp/pprint logs))))))
+  (collect-info-when-error-or-failed))

+ 51 - 0
clj-e2e/test/logseq/e2e/property_basic_test.clj

@@ -0,0 +1,51 @@
+(ns logseq.e2e.property-basic-test
+  (:require [clojure.test :refer [deftest testing is use-fixtures run-test run-tests]]
+            [logseq.e2e.assert :as assert]
+            [logseq.e2e.block :as b]
+            [logseq.e2e.fixtures :as fixtures]
+            [logseq.e2e.keyboard :as k]
+            [logseq.e2e.locator :as loc]
+            [logseq.e2e.util :as util]
+            [wally.main :as w]))
+
+(use-fixtures :once fixtures/open-page)
+
+(use-fixtures :each
+  fixtures/new-logseq-page
+  fixtures/validate-graph)
+
+(def ^:private property-types ["Text" "Number" "Date" "DateTime" "Checkbox" "Url" "Node"])
+
+(defn add-new-properties
+  [title-prefix]
+  (b/new-blocks (map #(str title-prefix "-" %) property-types))
+  (doseq [property-type property-types]
+    (let [property-name (str "p-" title-prefix "-" property-type)]
+      (w/click (util/get-by-text (str title-prefix "-" property-type) true))
+      (k/press "Control+e")
+      (util/input-command "Add new property")
+      (util/input property-name)
+      (w/click (util/get-by-text "New option:" false))
+      (assert/assert-is-visible (w/get-by-text "Select a property type"))
+      (w/click (loc/and "span" (util/get-by-text property-type true)))
+      (case property-type
+        "Text" (do
+                 (w/click (format ".property-pair:has-text('%s') > .ls-block" property-name))
+                 (util/input "Text"))
+        "Number" (do (assert/assert-is-visible (format "input[placeholder='%s']" (str "Set " property-name)))
+                     (util/input "111")
+                     (w/click (w/get-by-text "New option:")))
+        ("DateTime" "Date") (do
+                              (assert/assert-is-visible ".ls-property-dialog")
+                              (k/enter)
+                              (k/esc))
+        "Checkbox" nil
+        "Url" nil
+        "Node" (do
+                 (w/click (w/get-by-text "Skip choosing tag"))
+                 (util/input (str title-prefix "-Node-value"))
+                 (w/click (w/get-by-text "New option:")))))))
+
+(deftest new-property-test
+  (let [title-prefix "new-property-test"]
+    (add-new-properties title-prefix)))

+ 10 - 34
clj-e2e/test/logseq/e2e/rtc_extra_test.clj

@@ -4,12 +4,14 @@
    [com.climate.claypoole :as cp]
    [logseq.e2e.assert :as assert]
    [logseq.e2e.block :as b]
+   [logseq.e2e.custom-report :as custom-report]
    [logseq.e2e.fixtures :as fixtures :refer [*page1 *page2]]
    [logseq.e2e.graph :as graph]
    [logseq.e2e.keyboard :as k]
    [logseq.e2e.locator :as loc]
    [logseq.e2e.outliner-basic-test :as outliner-basic-test]
    [logseq.e2e.page :as page]
+   [logseq.e2e.property-basic-test :as property-basic-test]
    [logseq.e2e.rtc :as rtc]
    [logseq.e2e.settings :as settings]
    [logseq.e2e.util :as util]
@@ -33,11 +35,13 @@
       (graph/wait-for-remote-graph graph-name)
       (graph/switch-graph graph-name true))
 
-    (f)
-
-    ;; cleanup
-    (w/with-page @*page2
-      (graph/remove-remote-graph graph-name))))
+    (binding [custom-report/*preserve-graph* false]
+      (f)
+      ;; cleanup
+      (if custom-report/*preserve-graph*
+        (println "Don't remove graph: " graph-name)
+        (w/with-page @*page2
+          (graph/remove-remote-graph graph-name))))))
 
 (defn- new-logseq-page
   "new logseq page and switch to this page on both page1 and page2"
@@ -174,41 +178,13 @@
         (validate-task-blocks)
         (validate-2-graphs)))))
 
-(defn- add-new-properties
-  [title-prefix]
-  (b/new-blocks (map #(str title-prefix "-" %) ["Text" "Number" "Date" "DateTime" "Checkbox" "Url" "Node"]))
-  (doseq [property-type ["Text" "Number" "Date" "DateTime" "Checkbox" "Url" "Node"]]
-    (let [property-name (str "p-" title-prefix "-" property-type)]
-      (w/click (util/get-by-text (str title-prefix "-" property-type) true))
-      (k/press "Control+e")
-      (util/input-command "Add new property")
-      (util/input property-name)
-      (w/click (w/get-by-text "New option:"))
-      (assert/assert-is-visible (w/get-by-text "Select a property type"))
-      (w/click (loc/and "span" (util/get-by-text property-type true)))
-      (case property-type
-        "Text" (util/input "Text")
-        "Number" (do (assert/assert-is-visible (format "input[placeholder='%s']" (str "Set " property-name)))
-                     (util/input "111")
-                     (w/click (w/get-by-text "New option:")))
-        ("DateTime" "Date") (do
-                              (assert/assert-is-visible ".ls-property-dialog")
-                              (k/enter)
-                              (k/esc))
-        "Checkbox" nil
-        "Url" nil
-        "Node" (do
-                 (w/click (w/get-by-text "Skip choosing tag"))
-                 (util/input (str title-prefix "-Node-value"))
-                 (w/click (w/get-by-text "New option:")))))))
-
 (deftest rtc-property-test
   (let [insert-new-property-blocks-in-page2
         (fn [*latest-remote-tx title-prefix]
           (w/with-page @*page2
             (let [{:keys [_local-tx remote-tx]}
                   (rtc/with-wait-tx-updated
-                    (add-new-properties title-prefix))]
+                    (property-basic-test/add-new-properties title-prefix))]
               (reset! *latest-remote-tx remote-tx))))]
     (testing "page1: rtc-stop
 page2: create some user properties with different type

+ 9 - 11
src/main/frontend/components/block.cljs

@@ -2691,12 +2691,11 @@
   (let [*hover? (::hover? state)
         *hover-container? (::hover-container? state)
         private-tag? (ldb/private-tags (:db/ident tag))]
-    [:div.block-tag.items-center.relative
+    [:div.block-tag
      {:key (str "tag-" (:db/id tag))
-      :class (if @*hover?
-               (str "bg-gray-03 rounded "
-                    (if private-tag? "px-1" "pr-1"))
-               "pl-2 pr-1")
+      :class (str (when private-tag? "private-tag ")
+                  (when @*hover?
+                    (if private-tag? "!px-1" "!pl-0")))
       :on-mouse-over #(reset! *hover-container? true)
       :on-mouse-out #(reset! *hover-container? false)}
      [:div.flex.items-center
@@ -3074,9 +3073,9 @@
       :data-node-type (some-> (:logseq.property.node/display-type block) name)}
      (when (and db-based? (not table?)) (block-positioned-properties config block :block-left))
      [:div.block-content-or-editor-inner
-      [:div.flex.flex-1.flex-row.gap-1.items-center
+      [:div.block-row.flex.flex-1.flex-row.gap-1.items-center
        (if (and editor-box edit? (not type-block-editor?))
-         [:div.editor-wrapper.flex.flex-1
+         [:div.editor-wrapper.flex.flex-1.w-full
           {:id editor-id
            :class (util/classnames [{:opacity-50 (boolean (or (ldb/built-in? block) (ldb/journal? block)))}])}
           (ui/catch-error
@@ -3117,7 +3116,7 @@
             (block-refs-count block refs-count *hide-block-refs?))])
 
        (when-not (:table-block-title? config)
-         [:div.flex.flex-row.items-center.self-start.gap-1
+         [:div.ls-block-right.flex.flex-row.items-center.self-start.gap-1
           (when (and db-based? (not table?))
             [:div.opacity-70.hover:opacity-100
              (block-positioned-properties config block :block-right)])
@@ -3498,7 +3497,6 @@
         edit-input-id (str "edit-block-" (:block/uuid block))
         container-id (:container-id config*)
         table? (:table? config*)
-        sidebar? (:sidebar? config*)
         property? (:property? config*)
         custom-query? (boolean (:custom-query? config*))
         ref-or-custom-query? (or ref? custom-query?)
@@ -3666,14 +3664,14 @@
                                          :hide-block-refs-count? hide-block-refs-count?
                                          :*show-query? *show-query?}))])]
 
-         (when (and db-based? (not collapsed?) (not (or table? property?)))
+         (when (and db-based? (not collapsed?) (not (or table? property? (:page-title? config))))
            (block-positioned-properties config block :block-below))]
 
         (when (and @*show-right-menu? (not in-whiteboard?) (not (or table? property?)))
           (block-right-menu config block editing?))])
 
      (when (and db-based?
-                (or sidebar? (not collapsed?))
+                (not collapsed?)
                 (not (or table? property?)))
        [:div (when-not (:page-title? config) {:style {:padding-left 45}})
         (db-properties-cp config block {:in-block-container? true})])

+ 42 - 1
src/main/frontend/components/block.css

@@ -540,12 +540,41 @@
 
 .ls-block {
   @apply flex-1 relative py-0.5 transition-[background-color] mx-auto;
+  container-type: inline-size;
+  container-name: ls-block;
 
   &.selected {
     @apply rounded;
   }
 }
 
+#main-content-container, #right-sidebar {
+    container-type: inline-size;
+}
+
+@container (max-width: 600px) {
+    .time-spent, .positioned-properties.block-right, .view-actions, .ls-page-title .block-tags {
+        display: none;
+    }
+
+    .block-row {
+        @apply flex-col gap-0;
+    }
+
+    .ls-block-right {
+        @apply gap-0 -ml-1;
+    }
+    .ls-page-title .ls-block-right {
+        @apply ml-0;
+    }
+}
+
+@container ls-block (max-width: 430px) {
+    .ls-properties-area {
+        display: none;
+    }
+}
+
 .ls-block h1,
 .editor-inner .h1.uniline-block {
   font-size: 2rem;
@@ -992,7 +1021,15 @@ html.is-mac {
 }
 
 .block-tag {
-  @apply flex flex-row items-center;
+  @apply flex relative pl-2 pr-1;
+}
+
+.block-tag.private-tag {
+  @apply pl-1;
+}
+
+.block-tag:hover {
+  @apply bg-gray-03 rounded;
 }
 
 .block-tag a.tag {
@@ -1036,6 +1073,10 @@ html.is-mac {
   height: 16px;
 }
 
+.ls-page-title .positioned-properties, .ls-page-title .time-spent {
+  margin-top: 15px;
+}
+
 .ls-page-title .ls-page-icon button {
   margin-top: 8px;
 }

+ 1 - 1
src/main/frontend/components/icon.css

@@ -167,4 +167,4 @@
 
 .ls-icon-color-wrap em-emoji {
   @apply !w-auto !h-auto;
-}
+}

+ 21 - 18
src/main/frontend/components/property.cljs

@@ -424,15 +424,15 @@
 (rum/defcs new-property < rum/reactive
   [state block opts]
   (when-not config/publishing?
-    [:div.ls-new-property {:style {:margin-left 7 :margin-top 1}}
-     [:a.fade-link.flex.jtrigger
+    [:div.ls-new-property {:style {:margin-left 7 :margin-top 1 :font-size 15}}
+     [:a.flex.jtrigger.text-muted-foreground
       {:tab-index 0
        :on-click (fn [e]
                    (state/pub-event! [:editor/new-property (merge opts {:block block
                                                                         :target (.-target e)})]))}
       [:div.flex.flex-row.items-center.shrink-0
-       (ui/icon "plus" {:size 16})
-       [:div.ml-1
+       (ui/icon "plus" {:size 15})
+       [:div.ml-1 {:style {:margin-top 1}}
         "Add property"]]]]))
 
 (defn- resolve-linked-block-if-exists
@@ -558,7 +558,7 @@
              (assoc state
                     ::id (str (random-uuid))
                     ::block block)))}
-  [state _target-block {:keys [sidebar-properties?] :as opts}]
+  [state _target-block {:keys [sidebar-properties? page-title?] :as opts}]
   (let [id (::id state)
         db-id (:db/id (::block state))
         block (db/sub-block db-id)
@@ -580,7 +580,8 @@
                                ;; TODO: Use ldb/built-in? when intermittent lazy loading issue fixed
                                (get db-property/built-in-properties (:db/ident ent)))
                           ;; other position
-                          (when-not (or (and (:sidebar? opts) (= (:id opts) (str (:block/uuid block))))
+                          (when-not (or sidebar-properties? page-title?
+                                        (and (:sidebar? opts) (= (:id opts) (str (:block/uuid block))))
                                         show-empty-and-hidden-properties?)
                             (outliner-property/property-with-other-position? ent))
 
@@ -596,18 +597,20 @@
         ;; This section produces own-properties and full-hidden-properties
         hide-with-property-id (fn [property-id]
                                 (let [property (db/entity property-id)]
-                                  (cond
-                                    show-empty-and-hidden-properties?
-                                    false
-                                    root-block?
-                                    false
-                                    (and (:logseq.property/hide-empty-value property)
-                                         (nil? (get properties property-id)))
-                                    true
-                                    state-hide-empty-properties?
-                                    (nil? (get block property-id))
-                                    :else
-                                    (boolean (:logseq.property/hide? property)))))
+                                  (boolean
+                                   (when-not (or sidebar-properties? page-title?)
+                                     (cond
+                                       show-empty-and-hidden-properties?
+                                       false
+                                       root-block?
+                                       false
+                                       (and (:logseq.property/hide-empty-value property)
+                                            (nil? (get properties property-id)))
+                                       true
+                                       state-hide-empty-properties?
+                                       (nil? (get block property-id))
+                                       :else
+                                       (boolean (:logseq.property/hide? property)))))))
         property-hide-f (cond
                           config/publishing?
                           ;; Publishing is read only so hide all blank properties as they

+ 6 - 3
src/main/frontend/components/property.css

@@ -181,7 +181,7 @@
 }
 
 .ui__button.empty-btn, .empty-text-btn {
-  @apply !h-6 !px-0 font-normal opacity-50 text-sm;
+  @apply !h-6 !px-0 font-normal opacity-50;
 }
 
 .ui__button.empty-btn:hover, .empty-text-btn:hover {
@@ -300,6 +300,7 @@ a.control-link {
 }
 
 .property-key {
+  font-size: 15px;
   /* Same height with one-line block container */
   min-width: 160px;
   min-height: 28px;
@@ -329,8 +330,10 @@ a.control-link {
 
   .property-icon {
     @apply flex items-center;
-    height: 26px;
-    margin-top: 1px;
+    svg {
+        width: 15px;
+        height: 15px;
+    }
   }
 
   .editor-inner {

+ 1 - 1
src/main/frontend/components/property/value.css

@@ -1,4 +1,4 @@
-.property-value-inner:not([data-type="default"]):not([data-type="url"]):not([data-type="property"]):not([data-type="number"]) {
+.property-value-inner:not([data-type="default"]):not([data-type="url"]):not([data-type="number"]) {
   @apply cursor-pointer;
   &:hover, .as-scalar-value-wrap:hover {
     @apply bg-gray-02 rounded transition-[background-color] duration-300;

+ 12 - 2
src/main/frontend/ui.css

@@ -276,16 +276,26 @@ html.is-mobile {
 }
 
 .ui__icon svg {
-  filter: brightness(0.8);
+  filter: brightness(1);
   transition: filter .15s;
   will-change: filter;
 }
 
 .ui__icon:hover svg {
-  filter: brightness(1);
+  filter: brightness(.8);
   transition-duration: .15s;
 }
 
+.dark-theme {
+    .ui__icon svg {
+        filter: brightness(.8);
+    }
+
+    .ui__icon:hover svg {
+        filter: brightness(1);
+    }
+}
+
 .type-icon {
   @apply text-base text-center flex items-center justify-center rounded border mr-2 relative;