Просмотр исходного кода

enhance(ux): more intuitive ux for tag properties

1. Tag properties are now displayed vertically with their description for
improved readability.

2. Adding a property from a tag page now creates a tag property (not a page property). Previously, this caused confusion as users expected properties to be inherited by tagged nodes.

3. Fixed a flickering issue when reordering properties.

Users can still add page properties by using cmd+p.
Tienson Qin 8 месяцев назад
Родитель
Сommit
cada172521

+ 45 - 41
src/main/frontend/components/property.cljs

@@ -410,16 +410,21 @@
 (rum/defcs new-property < rum/reactive
   [state block opts]
   (when-not config/publishing?
-    [: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 15})
-       [:div.ml-1 {:style {:margin-top 1}}
-        "Add property"]]]]))
+    (let [add-new-property! (fn [e]
+                              (state/pub-event! [:editor/new-property (merge opts {:block block
+                                                                                   :target (.-target e)})]))]
+      [:div.ls-new-property {:style {:margin-left 7 :margin-top 1 :font-size 15}}
+       [:a.flex.jtrigger
+        {:tab-index 0
+         :on-click add-new-property!
+         :on-key-press (fn [e]
+                         (when (contains? #{"Enter" " "} (util/ekey e))
+                           (.preventDefault e)
+                           (add-new-property! e)))}
+        [:div.flex.flex-row.items-center.shrink-0
+         (ui/icon "plus" {:size 15 :class "opacity-50"})
+         [:div.ml-1 {:style {:margin-top 1}}
+          "Add property"]]]])))
 
 (defn- resolve-linked-block-if-exists
   "Properties will be updated for the linked page instead of the refed block.
@@ -471,6 +476,7 @@
          (let [property-desc (when-not (= (:db/ident property) :logseq.property/description)
                                (:logseq.property/description property))]
            [:div.ls-block.property-value-container.flex.flex-row.gap-1.items-center
+
             (when-not (or block? (and property-desc (:class-schema? opts)))
               [:div {:class "pl-1.5 -mr-[3px] opacity-60"}
                [:span.bullet-container [:span.bullet]]])
@@ -480,23 +486,9 @@
                 (pv/property-value property (db/entity :logseq.property/description) opts)
                 (pv/property-value block property opts))]]])]))))
 
-(rum/defcs ordered-properties < rum/reactive
-  {:init (fn [state]
-           (assoc state ::properties-order (atom (mapv first (second (:rum/args state))))))
-   :should-update (fn [old-state new-state]
-                    (let [[_ p1 opts1] (:rum/args old-state)
-                          [_ p2 opts2] (:rum/args new-state)
-                          p1-keys (map first p1)
-                          p1-set (set p1-keys)
-                          p1-m (zipmap (map first p1) (map second p1))
-                          p2-m (zipmap (map first p2) (map second p2))
-                          p2-set (set (map first p2))]
-                      (when-not (= p1-set p2-set)
-                        (reset! (::properties-order new-state) (mapv first p2)))
-                      (not= [p1-set (map p1-m p1-keys) opts1] [p2-set (map p2-m p1-keys) opts2])))}
-  [state block properties opts]
-  (let [*properties-order (::properties-order state)
-        properties-order (rum/react *properties-order)
+(rum/defc ordered-properties
+  [block properties opts]
+  (let [[properties-order set-properties-order!] (hooks/use-state (mapv first properties))
         m (zipmap (map first properties) (map second properties))
         properties (mapv (fn [k] [k (get m k)]) properties-order)
         choices (map (fn [[k v]]
@@ -508,6 +500,7 @@
     (dnd/items choices
                {:sort-by-inner-element? true
                 :on-drag-end (fn [properties-order {:keys [active-id over-id direction]}]
+                               (set-properties-order! properties-order)
                                (let [move-down? (= direction :down)
                                      over (db/entity (keyword over-id))
                                      active (db/entity (keyword active-id))
@@ -517,9 +510,6 @@
                                                    (db-order/gen-key over-order next-order))
                                                  (let [prev-order (db-order/get-prev-order (db/get-db) nil (:db/id over))]
                                                    (db-order/gen-key prev-order over-order)))]
-                                 ;; Reset *properties-order without waiting for `db/transact!` so that the UI will not be
-                                 ;; converted back to the old order and then the new order.
-                                 (reset! *properties-order properties-order)
                                  (db/transact! (state/get-current-repo)
                                                [{:db/id (:db/id active)
                                                  :block/order new-order}
@@ -630,12 +620,9 @@
                                         (into result cur-properties)
                                         result)))
                              result))
-        full-properties (cond->
-                         (->> (concat block-own-properties'
-                                      (map (fn [p] [p (get block p)]) class-properties))
-                              remove-built-in-or-other-position-properties)
-                          (and (ldb/class? block) (empty? (:logseq.property.class/properties block)))
-                          (concat [[:logseq.property.class/properties nil]]))]
+        full-properties (->> (concat block-own-properties'
+                                     (map (fn [p] [p (get block p)]) class-properties))
+                             remove-built-in-or-other-position-properties)]
     (cond
       (empty? full-properties)
       (when sidebar-properties?
@@ -643,9 +630,11 @@
 
       :else
       (let [remove-properties #{:logseq.property/icon :logseq.property/query}
-            properties' (remove (fn [[k _v]] (contains? remove-properties k))
-                                full-properties)
-            page? (entity-util/page? block)]
+            properties' (->> (remove (fn [[k _v]] (contains? remove-properties k))
+                                     full-properties)
+                             (remove (fn [[k _v]] (= k :logseq.property.class/properties))))
+            page? (entity-util/page? block)
+            class? (entity-util/class? block)]
         [:div.ls-properties-area
          {:id id
           :class (util/classnames [{:ls-page-properties page?}])
@@ -653,5 +642,20 @@
          [:<>
           (properties-section block properties' opts)
 
-          (when page?
-            (rum/with-key (new-property block opts) (str id "-add-property")))]]))))
+          (when (and page? (not class?))
+            (rum/with-key (new-property block opts) (str id "-add-property")))
+
+          (when class?
+            (let [properties (->> (:logseq.property.class/properties block)
+                                  (map (fn [e] [(:db/ident e)])))
+                  opts' (assoc opts :class-schema? true)]
+              [:div.flex.flex-col.gap-1
+               [:div {:style {:font-size 15}}
+                [:div.property-pair
+                 [:div.property-key.text-sm
+                  (property-key-cp block (db/entity :logseq.property.class/properties) {})]]
+                [:div.text-muted-foreground {:style {:margin-left 26}}
+                 "Tag properties are inherited by all nodes using the tag — for example, each #Task node inherits 'Status' and 'Priority'."]]
+               [:div.ml-4
+                (properties-section block properties opts')
+                (rum/with-key (new-property block opts') (str id "-class-add-property"))]]))]]))))

+ 4 - 5
src/main/frontend/components/property.css

@@ -166,11 +166,6 @@
     @apply w-full;
     margin: 0;
   }
-
-  .property-key a {
-    color: var(--ls-primary-text-color);
-  }
-
   .property-key a:hover {
     color: var(--ls-link-text-hover-color);
   }
@@ -180,6 +175,10 @@
   }
 }
 
+.property-key a, .ls-new-property a {
+    color: var(--ls-primary-text-color);
+}
+
 .ui__button.empty-btn, .empty-text-btn {
   @apply !h-6 !px-0 font-normal opacity-50;
 }

+ 4 - 2
src/main/frontend/components/property/value.cljs

@@ -1044,11 +1044,13 @@
                (str (:db/id block) "-" (:db/id property) "-" (:db/id value-block)))))]
 
         :else
-        [:div.w-full.h-full.jtrigger.ls-empty-text-property
+        [:div.w-full.h-full.jtrigger.ls-empty-text-property.text-muted-foreground.ml-1
          {:tabIndex 0
           :class (if (:table-view? opts) "cursor-pointer" "cursor-text")
           :style {:min-height 20}
-          :on-click #(<create-new-block! block property "")}]))))
+          :on-click #(<create-new-block! block property "")}
+         (when (:class-schema? opts)
+           "Add description")]))))
 
 (rum/defc property-block-value
   [value block property page-cp opts]