diff --git a/deps/graph-parser/src/logseq/graph_parser/exporter.cljs b/deps/graph-parser/src/logseq/graph_parser/exporter.cljs index 439c4b393..82d4a272c 100644 --- a/deps/graph-parser/src/logseq/graph_parser/exporter.cljs +++ b/deps/graph-parser/src/logseq/graph_parser/exporter.cljs @@ -294,12 +294,19 @@ [(:name v) k])) (into {}))) -(def built-in-property-names - "Set of all built-in property names as keywords. Using in-memory property - names because these are legacy names already in a user's file graph" +;; Should this move to logseq.db.frontend.property to be better maintained? +(def db-only-built-in-property-names + "Built-in property names that are are only used by DB graphs" + #{:description :page-tags :hide-properties? :created-from-property + :built-in? :includes :excludes :status :priority :deadline :sorting + :hidden-columns :ordered-columns :view-for :remote-metadata}) + +(def file-built-in-property-names + "Built-in property names for file graphs that are imported. Expressed as set of keywords" (-> built-in-property-name-to-idents keys set ;; :filters is not in built-in-properties because it maps to 2 new properties - (conj :filters))) + (conj :filters) + (set/difference db-only-built-in-property-names))) (defn- update-built-in-property-values [props {:keys [ignored-properties all-idents]} {:block/keys [title name]} options] @@ -433,7 +440,7 @@ {:keys [import-state] :as options}] (let [{:keys [all-idents property-schemas]} import-state get-ident' #(get-ident @all-idents %) - user-properties (apply dissoc props built-in-property-names)] + user-properties (apply dissoc props file-built-in-property-names)] (when (seq user-properties) (swap! (:block-properties-text-values import-state) assoc @@ -444,7 +451,7 @@ (if (contains? props :template) {} (let [props' (-> (update-built-in-property-values - (select-keys props built-in-property-names) + (select-keys props file-built-in-property-names) (select-keys import-state [:ignored-properties :all-idents]) (select-keys block [:block/name :block/title]) (select-keys options [:property-classes])) @@ -479,7 +486,7 @@ class-related-properties)] (->> (apply dissoc properties dissoced-props) (keep (fn [[prop val]] - (if (not (contains? built-in-property-names prop)) + (if (not (contains? file-built-in-property-names prop)) ;; only update user properties (if (string? val) ;; Ignore blank values as they were usually generated by templates @@ -508,7 +515,7 @@ properties-to-infer (if (:template properties') ;; Ignore template properties as they don't consistently have representative property values {} - (apply dissoc properties' built-in-property-names)) + (apply dissoc properties' file-built-in-property-names)) property-changes (->> properties-to-infer (keep (fn [[prop val]] @@ -676,9 +683,22 @@ (not (:block/file %)))) ;; remove file path relative (map #(dissoc % :block/file))) - existing-pages (keep #(ldb/get-page @conn (:block/name %)) all-pages) + existing-pages (keep #(first + ;; don't fetch built-in as that would give the wrong entity if a user used + ;; a db-only built-in property name e.g. description + (d/q '[:find [(pull ?b [*]) ...] + :in $ ?name + :where [?b :block/name ?name] [(missing? $ ?b :logseq.property/built-in?)]] + @conn + (:block/name %))) + all-pages) existing-page-names-to-uuids (into {} (map (juxt :block/name :block/uuid) existing-pages)) - new-pages (remove #(contains? existing-page-names-to-uuids (:block/name %)) all-pages) + new-pages (->> all-pages + (remove #(contains? existing-page-names-to-uuids (:block/name %))) + ;; fix extract incorrectly assigning user properties built-in property uuids + (map #(if (contains? db-only-built-in-property-names (keyword (:block/name %))) + (assoc % :block/uuid (d/squuid)) + %))) page-names-to-uuids (merge existing-page-names-to-uuids (into {} (map (juxt :block/name :block/uuid) new-pages))) all-pages-m (mapv #(handle-page-properties % @conn page-names-to-uuids all-pages options) @@ -701,7 +721,11 @@ (update-page-alias page-names-to-uuids) (:block/tags m) (update-page-tags @conn tag-classes page-names-to-uuids (:all-idents import-state))))) - (build-new-page m @conn tag-classes page-names-to-uuids (:all-idents import-state)))) + (let [m' (if (contains? db-only-built-in-property-names (keyword (:block/name m))) + ;; Use fixed uuid from above + (assoc m :block/uuid (get page-names-to-uuids (:block/name m))) + m)] + (build-new-page m' @conn tag-classes page-names-to-uuids (:all-idents import-state))))) (map :block all-pages-m))] {:pages-tx pages-tx :page-properties-tx (mapcat :properties-tx all-pages-m) @@ -791,10 +815,10 @@ :tag-classes (set (map string/lower-case (:tag-classes user-options))) :property-classes (set/difference (set (map (comp keyword string/lower-case) (:property-classes user-options))) - built-in-property-names) + file-built-in-property-names) :property-parent-classes (set/difference (set (map (comp keyword string/lower-case) (:property-parent-classes user-options))) - built-in-property-names)})) + file-built-in-property-names)})) (defn- split-pages-and-properties-tx "Separates new pages from new properties tx in preparation for properties to