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

enhance: store url property value in :block/title

So that url can be written using the block editor.
Tienson Qin 1 год назад
Родитель
Сommit
385b4937e1

+ 4 - 0
deps/db/src/logseq/db/frontend/property.cljs

@@ -52,6 +52,10 @@
                             :schema {:type :node
                                      :public? true
                                      :view-context :page}}
+   ;; :logseq.property/default-value {:title "Default value"
+   ;;                                 :schema {:type :any
+   ;;                                          :public? true
+   ;;                                          :view-context :property}}
    :logseq.property.class/properties {:title "Tag Properties"
                                       :schema {:type :property
                                                :cardinality :many

+ 6 - 4
deps/db/src/logseq/db/frontend/property/type.cljs

@@ -4,7 +4,8 @@
   (:require [datascript.core :as d]
             [clojure.set :as set]
             [logseq.common.util.macro :as macro-util]
-            [logseq.db.frontend.entity-util :as entity-util]))
+            [logseq.db.frontend.entity-util :as entity-util]
+            [clojure.string :as string]))
 
 ;; Config vars
 ;; ===========
@@ -37,7 +38,7 @@
   "Property value ref types where the refed entity stores its value in
   :property.value/content e.g. :number is stored as a number. new value-ref-property-types
   should default to this as it allows for more querying power"
-  #{:number :url})
+  #{:number})
 
 (def value-ref-property-types
   "Property value ref types where the refed entities either store their value in
@@ -82,12 +83,13 @@
   (macro-util/macro? s))
 
 (defn- url-entity?
+  "Empty string, url or macro url"
   [db val {:keys [new-closed-value?]}]
   (if new-closed-value?
     (or (url? val) (macro-url? val))
     (when-let [ent (d/entity db val)]
-      (or (url? (:property.value/content ent))
-          (macro-url? (:property.value/content ent))))))
+      (let [title (:block/title ent)]
+        (or (string/blank? title) (url? title) (macro-url? title))))))
 
 (defn- entity?
   [db id]

+ 1 - 1
deps/db/src/logseq/db/frontend/schema.cljs

@@ -2,7 +2,7 @@
   "Main datascript schemas for the Logseq app"
   (:require [clojure.set :as set]))
 
-(def version 44)
+(def version 45)
 
 ;; A page is a special block, a page can corresponds to multiple files with the same ":block/name".
 (def ^:large-vars/data-var schema

+ 16 - 7
deps/outliner/src/logseq/outliner/property.cljs

@@ -18,6 +18,8 @@
             [logseq.outliner.validate :as outliner-validate]
             [malli.error :as me]
             [malli.util :as mu]
+            [malli.core :as m]
+            [malli.error :as me]
             [clojure.set :as set]))
 
 (defn- throw-error-if-read-only-property
@@ -34,8 +36,8 @@
      (let [old-value (get block property-id)
            property (d/entity @conn property-id)
            multiple-values? (= :db.cardinality/many (:db/cardinality property))
-           retract-multiple-values? (and multiple-values? (coll? value))
-           multiple-values-empty? (and (coll? old-value)
+           retract-multiple-values? (and multiple-values? (sequential? value))
+           multiple-values-empty? (and (sequential? old-value)
                                        (= 1 (count old-value))
                                        (= :logseq.property/empty-placeholder (:db/ident (first old-value))))
            block (assoc (outliner-core/block-with-updated-at {:db/id (:db/id block)})
@@ -162,14 +164,21 @@
                        {:outliner-op :new-property})
         (d/entity @conn db-ident')))))
 
-(defn- validate-property-value
+(defn- validate-property-value-aux
   [schema value {:keys [many?]}]
   ;; normalize :many values since most components update them as a single value
-  (let [value' (if (and many? (not (coll? value)))
+  (let [value' (if (and many? (not (sequential? value)))
                  #{value}
                  value)]
     (me/humanize (mu/explain-data schema value'))))
 
+(defn validate-property-value
+  [db property value]
+  (let [property-type (get-in property [:block/schema :type])
+        many? (= :db.cardinality/many (:db/cardinality property))
+        schema (get-property-value-schema db property-type property)]
+    (validate-property-value-aux schema value {:many? many?})))
+
 (defn- ->eid
   [id]
   (if (uuid? id) [:block/uuid id] id))
@@ -183,7 +192,7 @@
         schema (get-property-value-schema @conn property-type property)]
     (if-let [msg (and
                   (not= new-value :logseq.property/empty-placeholder)
-                  (validate-property-value schema new-value {:many? (db-property/many? property)}))]
+                  (validate-property-value-aux schema new-value {:many? (db-property/many? property)}))]
       (let [msg' (str "\"" k-name "\"" " " (if (coll? msg) (first msg) msg))]
         (throw (ex-info "Schema validation failed"
                         {:type :notification
@@ -323,7 +332,7 @@
                      (let [value (get block property-id)
                            entities (cond
                                       (de/entity? value) [value]
-                                      (and (coll? value) (every? de/entity? value)) value
+                                      (and (sequential? value) (every? de/entity? value)) value
                                       :else nil)
                            deleting-entities (filter
                                               (fn [value]
@@ -473,7 +482,7 @@
     (when (contains? db-property-type/closed-value-property-types property-type)
       (let [value' (if (string? value) (string/trim value) value)
             resolved-value (convert-property-input-string (:type property-schema) value')
-            validate-message (validate-property-value
+            validate-message (validate-property-value-aux
                               (get-property-value-schema @conn property-type property {:new-closed-value? true})
                               resolved-value
                               {:many? (db-property/many? property)})]

+ 12 - 1
src/main/frontend/components/block.cljs

@@ -2309,7 +2309,18 @@
       [:span.opacity-50 "Set query title"]
 
       :else
-      (text-block-title config block))))
+      [:span
+       (text-block-title config block)
+       (when-let [property (:logseq.property/created-from-property block)]
+         (when-let [message (when (= :url (get-in property [:block/schema :type]))
+                              (first (outliner-property/validate-property-value (db/get-db) property (:db/id block))))]
+           (ui/tooltip
+            (shui/button
+             {:size :sm
+              :variant :ghost
+              :class "ls-type-warning px-1 !py-0 h-4 ml-1"}
+             (ui/icon "alert-triangle"))
+            [:div.opacity-75 message])))])))
 
 (rum/defc span-comma
   []

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

@@ -969,6 +969,12 @@ html.is-mac {
   height: 18px;
 }
 
+.ls-type-warning svg {
+  color: var(--rx-gray-09);
+  width: 12px;
+  height: 12px;
+}
+
 .ls-page-title .ls-page-icon svg, .ls-page-title .ls-page-icon button {
   width: 38px;
   height: 38px;
@@ -1026,4 +1032,4 @@ html.is-mac {
       @apply opacity-100;
     }
   }
-}
+}

+ 4 - 3
src/main/frontend/components/property.cljs

@@ -112,7 +112,8 @@
                    (p/do!
                     (ui/hide-popups-until-preview-popup!)
                     (pv/<add-property! block (:db/ident property) false {:exit-edit? true}))
-                   (and block (= type :default)
+                   (and block
+                        (contains? #{:default :url} type)
                         (not (seq (:property/closed-values property))))
                    (pv/<create-new-block! block property "")))))))}
 
@@ -209,7 +210,7 @@
              (shui/dialog-close!)
              (pv/<add-property! block (:db/ident property) false {:exit-edit? true}))
 
-            (and (= :default type)
+            (and (contains? #{:default :url} type)
                  (not (seq (:property/closed-values property))))
             (pv/<create-new-block! block property "")
 
@@ -424,7 +425,7 @@
                             (and (coll? v)
                                  (map? (first v))
                                  (:block/page (first v))))
-                        (contains? #{:default} type))
+                        (contains? #{:default :url} type))
             date? (= type :date)
             datetime? (= type :datetime)
             checkbox? (= type :checkbox)

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

@@ -548,9 +548,11 @@
                                             (p/then update-cardinality-fn))
                                         (update-cardinality-fn))))}))
 
-     (let [group' (->> [(when (and (not (contains? #{:logseq.property/parent :logseq.property.class/properties} (:db/ident property)))
+     (let [property-type (get-in property [:block/schema :type])
+           group' (->> [(when (and (not (contains? #{:logseq.property/parent :logseq.property.class/properties} (:db/ident property)))
+                                   (contains? #{:default :number :date :checkbox :node} property-type)
                                    (not
-                                    (and (= :default (get-in property [:block/schema :type]))
+                                    (and (= :default property-type)
                                          (empty? (:property/closed-values property))
                                          (contains? #{nil :properties} (:position property-schema)))))
                           (let [position (:position property-schema)]

+ 6 - 11
src/main/frontend/components/property/value.cljs

@@ -104,7 +104,7 @@
 
 (defn- select-type?
   [property type]
-  (or (contains? #{:node :number :url :date :page :class :property} type)
+  (or (contains? #{:node :number :date :page :class :property} type)
     ;; closed values
       (seq (:property/closed-values property))))
 
@@ -779,12 +779,7 @@
         tag? (or (:tag? opts) (= (:db/ident property) :block/tags))
         inline-text-cp (fn [content]
                          [:div.flex.flex-row.items-center
-                          (inline-text {} :markdown (macro-util/expand-value-if-macro content (state/get-macros)))
-                          (when (and (= type :url) other-position?)
-                            (shui/button {:variant :ghost
-                                          :size :sm
-                                          :class "px-0 py-0 h-4"}
-                                         (ui/icon "edit" {:size 14})))])]
+                          (inline-text {} :markdown (macro-util/expand-value-if-macro content (state/get-macros)))])]
     [:div.select-item.cursor-pointer
      (cond
        (= value :logseq.property/empty-placeholder)
@@ -835,7 +830,7 @@
           popup-content (fn content-fn [_]
                           [:div.property-select
                            (case type
-                             (:number :url :default)
+                             (:number :default)
                              (select block property select-opts' opts)
 
                              (:node :class :property :page :date)
@@ -883,10 +878,10 @@
                   (when (and (= type :default) (nil? value))
                     (<create-new-block! block property "")))}
      (cond
-       (and (= type :default) (nil? (:block/title value)))
+       (and (contains? #{:default :url} type) (nil? (:block/title value)))
        [:div.jtrigger (property-empty-btn-value property)]
 
-       (#{:default :entity} type)
+       (#{:default :url :entity} type)
        (property-block-value value block property page-cp)
 
        :else
@@ -1035,7 +1030,7 @@
                      (properties-cp {} block {:selected? false
                                               :class-schema? true})
 
-                     (and multiple-values? (= type :default) (not closed-values?))
+                     (and multiple-values? (contains? #{:default :url} type) (not closed-values?))
                      (property-normal-block-value block property v)
 
                      multiple-values?

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

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

+ 24 - 1
src/main/frontend/worker/db/migrate.cljs

@@ -182,6 +182,28 @@
     ;; migrate data
     (concat color-update-tx page-update-tx)))
 
+(defn- store-url-value-in-block-title
+  [conn _search-db]
+  (let [db @conn
+        url-properties (->> (d/datoms db :avet :block/type "property")
+                            (keep (fn [datom]
+                                    (let [property (d/entity db (:e datom))
+                                          type (get-in property [:block/schema :type])]
+                                      (when (= type :url)
+                                        property)))))
+        datoms (mapcat
+                (fn [property]
+                  (d/datoms db :avet (:db/ident property)))
+                url-properties)]
+    (mapcat
+     (fn [datom]
+       (if-let [url-block (when (integer? (:v datom)) (d/entity db (:v datom)))]
+         (let [url-value (db-property/property-value-content url-block)]
+           [[:db/retract (:db/id url-block) :property.value/content]
+            [:db/add (:db/id url-block) :block/title url-value]])
+         [[:db/retract (:e datom) (:a datom)]]))
+     datoms)))
+
 (defn- update-block-type-many->one
   [conn _search-db]
   (let [db @conn
@@ -417,7 +439,8 @@
                                  :logseq.property/hl-type :logseq.property.pdf/hl-type})}]
    [43 {:properties [:logseq.property/hide-empty-value]
         :fix set-hide-empty-value}]
-   [44 {:fix update-hl-color-and-page}]])
+   [44 {:fix update-hl-color-and-page}]
+   [45 {:fix store-url-value-in-block-title}]])
 
 (let [max-schema-version (apply max (map first schema-version->updates))]
   (assert (<= db-schema/version max-schema-version))