Browse Source

Merge pull request #11491 from logseq/refactor/journal-title

fix: old journal titles should be updated after changing the title format
Tienson Qin 1 year ago
parent
commit
aff566e479

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

@@ -12,6 +12,10 @@
     :schema {:properties [:logseq.task/status :logseq.task/priority :logseq.task/deadline]}}
 
    :logseq.class/Card {:title "Card"}
+
+   :logseq.class/Journal {:title "Journal"
+                          :properties {:logseq.property.journal/title-format "MMM do, yyyy"}}
+
    ;; TODO: Add more classes such as :book, :paper, :movie, :music, :project
    })
 

+ 28 - 10
deps/db/src/logseq/db/frontend/entity_plus.cljc

@@ -10,11 +10,33 @@
             [datascript.impl.entity :as entity :refer [Entity]]
             [logseq.db.frontend.content :as db-content]
             [logseq.db.frontend.property :as db-property]
-            [logseq.db.frontend.entity-util :as entity-util]))
+            [logseq.db.frontend.entity-util :as entity-util]
+            [logseq.common.util.date-time :as date-time-util]
+            [datascript.core :as d]))
 
 (def db-based-graph? entity-util/db-based-graph?)
 
 (def lookup-entity @#'entity/lookup-entity)
+
+(defn- get-journal-title
+  [db e]
+  (date-time-util/int->journal-title (:block/journal-day e)
+                                     (:logseq.property.journal/title-format (d/entity db :logseq.class/Journal))))
+
+(defn- get-block-title
+  [^Entity e k default-value]
+  (let [db (.-db e)]
+    (if (and (db-based-graph? db) (= "journal" (:block/type e)))
+      (get-journal-title db e)
+      (or
+       (get (.-kv e) k)
+       (let [result (lookup-entity e k default-value)]
+         (or
+          (if (string? result)
+            (db-content/special-id-ref->page-ref result (:block/refs e))
+            result)
+          default-value))))))
+
 (defn lookup-kv-then-entity
   ([e k] (lookup-kv-then-entity e k nil))
   ([^Entity e k default-value]
@@ -22,7 +44,10 @@
      (when k
        (case k
          :block/raw-title
-         (lookup-entity e :block/title default-value)
+         (let [db (.-db e)]
+           (if (and (db-based-graph? db) (= "journal" (:block/type e)))
+             (get-journal-title db e)
+             (lookup-entity e :block/title default-value)))
 
          :block/properties
          (let [db (.-db e)]
@@ -34,14 +59,7 @@
              (lookup-entity e :block/properties nil)))
 
          :block/title
-         (or
-          (get (.-kv e) k)
-          (let [result (lookup-entity e k default-value)]
-            (or
-             (if (string? result)
-               (db-content/special-id-ref->page-ref result (:block/refs e))
-               result)
-             default-value)))
+         (get-block-title e k default-value)
 
          :block/_parent
          (->> (lookup-entity e k default-value)

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

@@ -91,6 +91,26 @@
                                   :schema {:type :map
                                            :hide? true}}
 
+   ;; Journal props
+   :logseq.property.journal/title-format {:title "Title format"
+                                          :schema
+                                          {:type :string
+                                           :public? false}}
+
+   ;; TODO: should we replace block/journal-day with those separate props?
+   ;; :logseq.property.journal/year {:title "Journal year"
+   ;;                                :schema
+   ;;                                {:type :raw-number
+   ;;                                 :public? false}}
+   ;; :logseq.property.journal/month {:title "Journal month"
+   ;;                                 :schema
+   ;;                                 {:type :raw-number
+   ;;                                  :public? false}}
+   ;; :logseq.property.journal/day {:title "Journal day"
+   ;;                               :schema
+   ;;                               {:type :raw-number
+   ;;                                :public? false}}
+
    ;; Task props
    :logseq.task/status
    {:title "Status"

+ 3 - 1
deps/db/src/logseq/db/frontend/property/type.cljs

@@ -12,7 +12,7 @@
 
 (def internal-built-in-property-types
   "Valid property types only for use by internal built-in-properties"
-  #{:keyword :map :coll :any :entity})
+  #{:keyword :map :coll :any :entity :string :raw-number})
 
 (def user-built-in-property-types
   "Valid property types for users in order they appear in the UI"
@@ -135,6 +135,8 @@
    ;; Internal usage
    ;; ==============
 
+   :string   string?
+   :raw-number number?
    :entity   entity?
    :keyword  keyword?
    :map      map?

+ 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 12)
+(def version 13)
 ;; A page is a special block, a page can corresponds to multiple files with the same ":block/name".
 (def ^:large-vars/data-var schema
   {:db/ident        {:db/unique :db.unique/identity}

+ 17 - 10
deps/db/src/logseq/db/sqlite/create_graph.cljs

@@ -80,26 +80,33 @@
                          (vec conflicting-idents))
                     {:idents conflicting-idents}))))
 
-(defn- build-initial-classes [db-ident->properties]
+(defn build-initial-classes*
+  [built-in-classes db-ident->properties]
   (map
-   (fn [[db-ident {:keys [schema title]}]]
+   (fn [[db-ident {:keys [properties schema title]}]]
      (let [title' (or title (name db-ident))]
        (mark-block-as-built-in
         (sqlite-util/build-new-class
-         (let [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))]
+         (let [schema-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))]
            (cond->
             {:block/title title'
              :block/name (common-util/page-name-sanity-lc title')
              :db/ident db-ident
              :block/uuid (common-uuid/gen-uuid :db-ident-block-uuid db-ident)}
+             (seq schema-properties)
+             (assoc :class/schema.properties schema-properties)
              (seq properties)
-             (assoc :class/schema.properties properties)))))))
-   db-class/built-in-classes))
+             (merge properties)))))))
+   built-in-classes))
+
+(defn- build-initial-classes
+  [db-ident->properties]
+  (build-initial-classes* db-class/built-in-classes db-ident->properties))
 
 (defn build-db-initial-data
   "Builds tx of initial data for a new graph including key values, initial files,

+ 1 - 1
deps/outliner/src/logseq/outliner/core.cljs

@@ -312,7 +312,7 @@
               (validate-unique-by-name-tag-and-block-type db (:block/title m*) block-entity))
           m (cond-> m*
               db-based?
-              (dissoc :block/priority :block/marker :block/properties-order))]
+              (dissoc :block/pre-block? :block/priority :block/marker :block/properties-order))]
       ;; Ensure block UUID never changes
       (let [e (d/entity db db-id)]
         (when (and e block-uuid)

+ 4 - 4
src/main/frontend/commands.cljs

@@ -156,7 +156,7 @@
                                      "square-asterisk")]
                           [command (->marker m) (str "Set status to " m) icon]))))]
     (when (seq result)
-      (update result 0 (fn [v] (conj v "TASK"))))))
+      (map (fn [v] (conj v "TASK")) result))))
 
 (defn file-based-priorities
   []
@@ -183,10 +183,10 @@
                            (if db-based?
                              (str "priorityLvl" item)
                              (str "circle-letter-" (util/safe-lower-case item)))])))
-                 (with-no-priority)
-                 (vec))]
+                (with-no-priority)
+                (vec))]
     (when (seq result)
-      (update result 0 (fn [v] (conj v "PRIORITY"))))))
+      (map (fn [v] (conj v "PRIORITY")) result))))
 
 ;; Credits to roamresearch.com
 

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

@@ -3698,9 +3698,8 @@
         (when alias? [:span.text-sm.font-medium.opacity-50 " Alias"])]
        (for [[parent blocks] parent-blocks]
          (let [blocks' (map (fn [b]
-                              ;; Block might be a datascript entity
                               (if (e/entity? b)
-                                (db/pull (:db/id b))
+                                b
                                 (update b :block/children
                                         (fn [col]
                                           (tree/non-consecutive-blocks->vec-tree col))))) blocks)]

+ 1 - 1
src/main/frontend/components/content.cljs

@@ -339,7 +339,7 @@
               (shui/dropdown-menu-item
                {:key "(Dev) Show block AST"
                 :on-click (fn []
-                            (let [block (db/pull [:block/uuid block-id])]
+                            (let [block (db/entity [:block/uuid block-id])]
                               (dev-common-handler/show-content-ast (:block/title block) (:block/format block))))}
                (t :dev/show-block-ast))
               (shui/dropdown-menu-item

+ 67 - 56
src/main/frontend/components/editor.cljs

@@ -35,6 +35,16 @@
             [rum.core :as rum]
             [frontend.config :as config]))
 
+(defn filter-commands
+  [page? commands]
+  (if page?
+    (filter (fn [item]
+              (or
+               (= "Add new property" (first item))
+               (when (= (count item) 5)
+                 (contains? #{"TASK" "PRIORITY"} (last item))))) commands)
+    commands))
+
 (rum/defcs commands < rum/reactive
   (rum/local [] ::matched-commands)
   [s id format]
@@ -42,63 +52,64 @@
         *matched (::matched-commands s)
         _ (when (state/get-editor-action)
             (reset! *matched matched'))
-        matched @*matched]
+        page? (db/page? (db/entity (:db/id (state/get-edit-block))))
+        matched (filter-commands page? @*matched)]
     (ui/auto-complete
-      matched
-      {:get-group-name
-       (fn [item]
-         (when (= (count item) 5) (last item)))
-
-       :item-render
-       (fn [item]
-         (let [command-name (first item)
-               command-doc (get item 2)
-               plugin-id (get-in item [1 1 1 :pid])
-               doc (when (state/show-command-doc?) command-doc)
-               options (some-> item (get 3))
-               icon-name (some-> (if (map? options) (:icon options) options) (name))
-               command-name (if icon-name
-                              [:span.flex.items-center.gap-1
-                               (shui/tabler-icon icon-name)
-                               [:strong.font-normal command-name]]
-                              command-name)]
-           (cond
-             (or plugin-id (vector? doc))
-             [:div.has-help
-              {:title plugin-id}
-              command-name
-              (when doc (ui/tippy
-                          {:html doc
-                           :interactive true
-                           :fixed-position? true
-                           :position "right"}
-
-                          [:small (svg/help-circle)]))]
-
-             (string? doc)
-             [:div {:title doc}
-              command-name]
-
-             :else
-             [:div command-name])))
-
-       :on-chosen
-       (fn [chosen-item]
-         (let [command (first chosen-item)]
-           (reset! commands/*current-command command)
-           (let [command-steps (get (into {} matched) command)
-                 restore-slash? (or
-                                  (contains? #{"Today" "Yesterday" "Tomorrow" "Current time"} command)
-                                  (and
-                                    (not (fn? command-steps))
-                                    (not (contains? (set (map first command-steps)) :editor/input))
-                                    (not (contains? #{"Date picker" "Template" "Deadline" "Scheduled" "Upload an image"} command))))]
-             (editor-handler/insert-command! id command-steps
-               format
-               {:restore? restore-slash?
-                :command command}))))
-       :class
-       "cp__commands-slash"})))
+     matched
+     {:get-group-name
+      (fn [item]
+        (when (= (count item) 5) (last item)))
+
+      :item-render
+      (fn [item]
+        (let [command-name (first item)
+              command-doc (get item 2)
+              plugin-id (get-in item [1 1 1 :pid])
+              doc (when (state/show-command-doc?) command-doc)
+              options (some-> item (get 3))
+              icon-name (some-> (if (map? options) (:icon options) options) (name))
+              command-name (if icon-name
+                             [:span.flex.items-center.gap-1
+                              (shui/tabler-icon icon-name)
+                              [:strong.font-normal command-name]]
+                             command-name)]
+          (cond
+            (or plugin-id (vector? doc))
+            [:div.has-help
+             {:title plugin-id}
+             command-name
+             (when doc (ui/tippy
+                        {:html doc
+                         :interactive true
+                         :fixed-position? true
+                         :position "right"}
+
+                        [:small (svg/help-circle)]))]
+
+            (string? doc)
+            [:div {:title doc}
+             command-name]
+
+            :else
+            [:div command-name])))
+
+      :on-chosen
+      (fn [chosen-item]
+        (let [command (first chosen-item)]
+          (reset! commands/*current-command command)
+          (let [command-steps (get (into {} matched) command)
+                restore-slash? (or
+                                (contains? #{"Today" "Yesterday" "Tomorrow" "Current time"} command)
+                                (and
+                                 (not (fn? command-steps))
+                                 (not (contains? (set (map first command-steps)) :editor/input))
+                                 (not (contains? #{"Date picker" "Template" "Deadline" "Scheduled" "Upload an image"} command))))]
+            (editor-handler/insert-command! id command-steps
+                                            format
+                                            {:restore? restore-slash?
+                                             :command command}))))
+      :class
+      "cp__commands-slash"})))
 
 (defn- page-on-chosen-handler
   [embed? input id q pos format]

+ 24 - 11
src/main/frontend/components/settings.cljs

@@ -1,10 +1,10 @@
 (ns frontend.components.settings
   (:require [clojure.string :as string]
             [electron.ipc :as ipc]
-            [logseq.shui.ui :as shui]
             [frontend.colors :as colors]
             [frontend.components.assets :as assets]
             [frontend.components.file-sync :as fs]
+            [frontend.components.shortcut :as shortcut]
             [frontend.components.svg :as svg]
             [frontend.config :as config]
             [frontend.context.i18n :refer [t]]
@@ -12,18 +12,18 @@
             [frontend.db :as db]
             [frontend.dicts :as dicts]
             [frontend.handler.config :as config-handler]
+            [frontend.handler.db-based.rtc :as rtc-handler]
             [frontend.handler.file-sync :as file-sync-handler]
             [frontend.handler.global-config :as global-config-handler]
             [frontend.handler.notification :as notification]
             [frontend.handler.plugin :as plugin-handler]
+            [frontend.handler.property :as property-handler]
             [frontend.handler.route :as route-handler]
             [frontend.handler.ui :as ui-handler]
             [frontend.handler.user :as user-handler]
-            [frontend.handler.db-based.rtc :as rtc-handler]
             [frontend.mobile.util :as mobile-util]
             [frontend.modules.instrumentation.core :as instrument]
             [frontend.modules.shortcut.data-helper :as shortcut-helper]
-            [frontend.components.shortcut :as shortcut]
             [frontend.spec.storage :as storage-spec]
             [frontend.state :as state]
             [frontend.storage :as storage]
@@ -32,10 +32,11 @@
             [frontend.version :as fv]
             [goog.object :as gobj]
             [goog.string :as gstring]
+            [logseq.db :as ldb]
+            [logseq.shui.ui :as shui]
             [promesa.core :as p]
             [reitit.frontend.easy :as rfe]
-            [rum.core :as rum]
-            [logseq.db :as ldb]))
+            [rum.core :as rum]))
 
 (defn toggle
   [label-for name state on-toggle & [detail-text]]
@@ -439,14 +440,26 @@
      [:select.form-select.is-small
       {:value     preferred-date-format
        :on-change (fn [e]
-                    (let [format (util/evalue e)]
+                    (let [repo (state/get-current-repo)
+                          format (util/evalue e)
+                          db-based? (config/db-based-graph? repo)]
                       (when-not (string/blank? format)
-                        (config-handler/set-config! :journal/page-title-format format)
-                        (notification/show!
-                          [:div (t :settings-page/custom-date-format-notification)]
-                          :warning false)
+                        (if db-based?
+                          (p/do!
+                            (property-handler/set-block-property! repo
+                                                                :logseq.class/Journal
+                                                                :logseq.property.journal/title-format
+                                                                format)
+                            (notification/show! "Please refresh the app for this change to take effect"))
+                          (do
+                            (config-handler/set-config! :journal/page-title-format format)
+                            (notification/show!
+                             [:div (t :settings-page/custom-date-format-notification)]
+                             :warning false)))
+
                         (state/close-modal!)
-                        (route-handler/redirect! {:to :graphs}))))}
+                        (shui/dialog-close-all!)
+                        (when-not db-based? (route-handler/redirect! {:to :graphs})))))}
       (for [format (sort (date/journal-title-formatters))]
         [:option {:key format} format])]]]])
 

+ 21 - 31
src/main/frontend/db/conn.cljs

@@ -3,7 +3,6 @@
   (:require [clojure.string :as string]
             [frontend.util :as util]
             [frontend.mobile.util :as mobile-util]
-            [frontend.state :as state]
             [frontend.config :as config]
             [frontend.util.text :as text-util]
             [logseq.graph-parser.text :as text]
@@ -11,14 +10,26 @@
             [datascript.core :as d]
             [logseq.db :as ldb]
             [logseq.common.util :as common-util]
-            [logseq.db.frontend.schema :as db-schema]))
+            [logseq.db.frontend.schema :as db-schema]
+            [frontend.db.conn-state :as db-conn-state]
+            [frontend.state :as state]))
 
-(defonce conns (atom {}))
+(defonce conns db-conn-state/conns)
+(def get-repo-path db-conn-state/get-repo-path)
 
-(defn get-repo-path
-  [url]
-  (assert (string? url) (str "url is not a string: " (type url)))
-  url)
+(defn get-db
+  ([]
+   (get-db (state/get-current-repo) true))
+  ([repo-or-deref?]
+   (if (boolean? repo-or-deref?)
+     (get-db (state/get-current-repo) repo-or-deref?)
+     (get-db repo-or-deref? true)))
+  ([repo deref?]
+   (when-let [repo (or repo (state/get-current-repo))]
+     (when-let [conn (db-conn-state/get-conn repo)]
+       (if deref?
+         @conn
+         conn)))))
 
 (defn get-repo-name
   [repo-url]
@@ -30,7 +41,7 @@
     (config/get-local-dir repo-url)
 
     :else
-    (get-repo-path repo-url)))
+    (db-conn-state/get-repo-path repo-url)))
 
 (defn get-short-repo-name
   "repo-name: from get-repo-name. Dir/Name => Name"
@@ -48,30 +59,9 @@
       (string/replace-first repo-name' config/db-version-prefix "")
       repo-name')))
 
-(defn datascript-db
-  [repo]
-  (when repo
-    (let [path (get-repo-path repo)]
-      (str (if (util/electron?) "" config/idb-db-prefix)
-           path))))
-
-(defn get-db
-  ([]
-   (get-db (state/get-current-repo) true))
-  ([repo-or-deref?]
-   (if (boolean? repo-or-deref?)
-     (get-db (state/get-current-repo) repo-or-deref?)
-     (get-db repo-or-deref? true)))
-  ([repo deref?]
-   (let [repo (if repo repo (state/get-current-repo))]
-     (when-let [conn (get @conns (datascript-db repo))]
-       (if deref?
-         @conn
-         conn)))))
-
 (defn remove-conn!
   [repo]
-  (swap! conns dissoc (datascript-db repo)))
+  (swap! conns dissoc (db-conn-state/get-repo-path repo)))
 
 (if util/node-test?
   (defn transact!
@@ -89,7 +79,7 @@
   ([repo]
    (start! repo {}))
   ([repo {:keys [listen-handler]}]
-   (let [db-name (datascript-db repo)
+   (let [db-name (db-conn-state/get-repo-path repo)
          db-conn (if (config/db-based-graph? repo)
                    (d/create-conn db-schema/schema-for-db-based-graph)
                    (gp-db/start-conn))]

+ 13 - 0
src/main/frontend/db/conn_state.cljs

@@ -0,0 +1,13 @@
+(ns frontend.db.conn-state
+  "Datascript db connections.")
+
+(defonce conns (atom {}))
+
+(defn get-repo-path
+  [url]
+  (assert (string? url) (str "url is not a string: " (type url)))
+  url)
+
+(defn get-conn
+  [repo]
+  (get @conns (get-repo-path repo)))

+ 3 - 3
src/main/frontend/db/persist.cljs

@@ -28,7 +28,7 @@
 
 (defn delete-graph!
   [graph]
-  (let [key (db-conn/datascript-db graph)
+  (let [key (db-conn/get-repo-path graph)
         db-based? (config/db-based-graph? graph)]
     (p/let [_ (persist-db/<unsafe-delete graph)]
       (if (util/electron?)
@@ -37,8 +37,8 @@
 
 (defn rename-graph!
   [old-repo new-repo]
-  (let [old-key (db-conn/datascript-db old-repo)
-        new-key (db-conn/datascript-db new-repo)]
+  (let [old-key (db-conn/get-repo-path old-repo)
+        new-key (db-conn/get-repo-path new-repo)]
     (if (util/electron?)
       (do
         (js/console.error "rename-graph! is not supported in electron")

+ 1 - 1
src/main/frontend/db/restore.cljs

@@ -21,7 +21,7 @@
                  (catch :default e
                    (js/console.error e)
                    (throw e)))
-          db-name (db-conn/datascript-db repo)
+          db-name (db-conn/get-repo-path repo)
           _ (swap! db-conn/conns assoc db-name conn)
           end-time (t/now)]
 

+ 1 - 21
src/main/frontend/handler.cljs

@@ -1,8 +1,7 @@
 (ns frontend.handler
   "Main ns that handles application startup. Closest ns that we have to a
   system. Contains a couple of small system components"
-  (:require [cljs.reader :refer [read-string]]
-            [electron.ipc :as ipc]
+  (:require [electron.ipc :as ipc]
             [electron.listener :as el]
             [frontend.components.block :as block]
             [frontend.components.editor :as editor]
@@ -12,7 +11,6 @@
             [frontend.config :as config]
             [frontend.context.i18n :as i18n]
             [frontend.db.restore :as db-restore]
-            [frontend.db.conn :as conn]
             [frontend.db.react :as react]
             [frontend.error :as error]
             [frontend.handler.command-palette :as command-palette]
@@ -112,22 +110,6 @@
   (js/window.addEventListener "online" handle-connection-change)
   (js/window.addEventListener "offline" handle-connection-change))
 
-(defn enable-datalog-console
-  "Enables datalog console in browser provided by https://github.com/homebaseio/datalog-console"
-  []
-  (js/document.documentElement.setAttribute "__datalog-console-remote-installed__" true)
-  (.addEventListener js/window "message"
-                     (fn [event]
-                       (let [db (conn/get-db)]
-                         (when-let [devtool-message (gobj/getValueByKeys event "data" ":datalog-console.client/devtool-message")]
-                           (let [msg-type (:type (read-string devtool-message))]
-                             (case msg-type
-
-                               :datalog-console.client/request-whole-database-as-string
-                               (.postMessage js/window #js {":datalog-console.remote/remote-message" (pr-str db)} "*")
-
-                               nil)))))))
-
 (defn- register-components-fns!
   []
   (state/set-page-blocks-cp! page/page-cp)
@@ -200,8 +182,6 @@
 
    (util/<app-wake-up-from-sleep-loop (atom false))
 
-   (when config/dev?
-     (enable-datalog-console))
    (persist-var/load-vars)))
 
 (defn stop! []

+ 10 - 2
src/main/frontend/state.cljs

@@ -21,7 +21,9 @@
             [rum.core :as rum]
             [frontend.rum :as r]
             [logseq.db.sqlite.util :as sqlite-util]
-            [clojure.set :as set]))
+            [clojure.set :as set]
+            [frontend.db.conn-state :as db-conn-state]
+            [datascript.core :as d]))
 
 (defonce *profile-state
   (atom {}))
@@ -591,7 +593,13 @@ should be done through this fn in order to get global config and config defaults
 
 (defn get-date-formatter
   []
-  (common-config/get-date-formatter (get-config)))
+  (let [repo (get-current-repo)]
+    (if (sqlite-util/db-based-graph? repo)
+      (when-let [conn (db-conn-state/get-conn repo)]
+        (get (d/entity @conn :logseq.class/Journal)
+           :logseq.property.journal/title-format
+           "MMM do, yyyy"))
+      (common-config/get-date-formatter (get-config)))))
 
 (defn shortcuts []
   (:shortcuts (get-config)))

+ 20 - 19
src/main/frontend/ui.cljs

@@ -513,7 +513,8 @@
            item-render
            class
            header]}]
-  (let [*current-idx (get state ::current-idx)]
+  (let [*current-idx (get state ::current-idx)
+        *groups (atom #{})]
     [:div#ui__ac {:class class}
      (if (seq matched)
        [:div#ui__ac-inner.hide-scrollbar
@@ -528,26 +529,26 @@
                    :on-mouse-move  #(reset! *current-idx idx)}
                   (let [chosen? (= @*current-idx idx)]
                     (menu-link
-                      {:id (str "ac-" idx)
-                       :tab-index "0"
-                       :class (when chosen? "chosen")
+                     {:id (str "ac-" idx)
+                      :tab-index "0"
+                      :class (when chosen? "chosen")
                        ;; TODO: should have more tests on touch devices
                        ;:on-pointer-down #(util/stop %)
-                       :on-click (fn [e]
-                                   (util/stop e)
-                                   (if (and (gobj/get e "shiftKey") on-shift-chosen)
-                                     (on-shift-chosen item)
-                                     (on-chosen item e)))}
-                      (if item-render (item-render item chosen?) item)))]]
-
-             (if get-group-name
-               (if-let [group-name (get-group-name item)]
-                 [:div
-                  [:div.ui__ac-group-name group-name]
-                  item-cp]
-                 item-cp)
-
-               item-cp))])]
+                      :on-click (fn [e]
+                                  (util/stop e)
+                                  (if (and (gobj/get e "shiftKey") on-shift-chosen)
+                                    (on-shift-chosen item)
+                                    (on-chosen item e)))}
+                     (if item-render (item-render item chosen?) item)))]]
+
+             (let [group-name (and (fn? get-group-name) (get-group-name item))]
+               (if (and group-name (not (contains? @*groups group-name)))
+                 (do
+                   (swap! *groups conj group-name)
+                   [:div
+                    [:div.ui__ac-group-name group-name]
+                    item-cp])
+                 item-cp)))])]
        (when empty-placeholder
          empty-placeholder))]))
 

+ 14 - 4
src/main/frontend/worker/db/migrate.cljs

@@ -3,6 +3,7 @@
   (:require [datascript.core :as d]
             [logseq.db.sqlite.create-graph :as sqlite-create-graph]
             [logseq.db.frontend.property :as db-property]
+            [logseq.db.frontend.class :as db-class]
             [logseq.db :as ldb]
             [logseq.db.frontend.schema :as db-schema]
             [frontend.worker.search :as search]
@@ -176,7 +177,9 @@
    [9 {:fix update-task-ident}]
    [10 {:fix update-table-properties}]
    [11 {:fix property-checkbox-type-non-ref}]
-   [12 {:fix update-block-type-many->one}]])
+   [12 {:fix update-block-type-many->one}]
+   [13 {:classes [:logseq.class/Journal]
+        :properties [:logseq.property.journal/title-format]}]])
 
 (let [max-schema-version (apply max (map first schema-version->updates))]
   (assert (<= db-schema/version max-schema-version))
@@ -206,8 +209,6 @@
                               updates))
                           schema-version->updates)
             properties (mapcat :properties updates)
-            ;; TODO: add classes migration support
-            ;; classes (mapcat :classes updates)
             new-properties (->> (select-keys db-property/built-in-properties properties)
                                 ;; property already exists, this should never happen
                                 (remove (fn [[k _]]
@@ -216,12 +217,21 @@
                                 (into {})
                                 sqlite-create-graph/build-initial-properties*
                                 (map (fn [b] (assoc b :logseq.property/built-in? true))))
+            classes (mapcat :classes updates)
+            new-classes (->> (select-keys db-class/built-in-classes classes)
+                             ;; class already exists, this should never happen
+                             (remove (fn [[k _]]
+                                       (when (d/entity db k)
+                                         (assert (str "DB migration: class already exists " k)))))
+                             (into {})
+                             (#(sqlite-create-graph/build-initial-classes* % {}))
+                             (map (fn [b] (assoc b :logseq.property/built-in? true))))
             fixes (mapcat
                    (fn [update]
                      (when-let [fix (:fix update)]
                        (when (fn? fix)
                          (fix conn search-db)))) updates)
-            tx-data' (if db-based? (concat new-properties fixes) fixes)]
+            tx-data' (if db-based? (concat new-properties new-classes fixes) fixes)]
         (when (seq tx-data')
           (let [tx-data' (concat tx-data' [(sqlite-create-graph/kv :logseq.kv/schema-version db-schema/version)])]
             (ldb/transact! conn tx-data' {:db-migrate? true}))

+ 1 - 1
src/main/frontend/worker/handler/page.cljs

@@ -36,7 +36,7 @@
   TODO: Add other options"
   [repo conn config title & {:as options}]
   (if (ldb/db-based-graph? @conn)
-    (db-worker-page/create! conn config title options)
+    (db-worker-page/create! conn title options)
     (file-worker-page/create! repo conn config title options)))
 
 (defn db-refs->page

+ 2 - 3
src/main/frontend/worker/handler/page/db_based/page.cljs

@@ -7,7 +7,6 @@
             [clojure.string :as string]
             [logseq.graph-parser.text :as text]
             [logseq.common.util :as common-util]
-            [logseq.common.config :as common-config]
             [logseq.db.frontend.order :as db-order]
             [logseq.db.frontend.property.util :as db-property-util]
             [logseq.db.frontend.property.build :as db-property-build]
@@ -65,14 +64,14 @@
        :block/format format})]))
 
 (defn create!
-  [conn config title
+  [conn title
    {:keys [create-first-block? properties uuid persist-op? whiteboard? class? today-journal?]
     :or   {create-first-block?      true
            properties               nil
            uuid                     nil
            persist-op?              true}
     :as options}]
-  (let [date-formatter (common-config/get-date-formatter config)
+  (let [date-formatter (:logseq.property.journal/title-format (d/entity @conn :logseq.class/Journal))
         [title page-name] (get-title-and-pagename title)
         type (cond class?
                    "class"

+ 1 - 1
src/test/frontend/db/db_based_model_test.cljs

@@ -24,7 +24,7 @@
   (let [opts {:redirect? false :create-first-block? false :class? true}
         _ (test-helper/create-page! "class1" opts)
         _ (test-helper/create-page! "class2" opts)]
-    (is (= ["Card" "Root tag" "Task" "class1" "class2"] (sort (map :block/title (model/get-all-classes repo)))))))
+    (is (= ["Card" "Journal" "Root tag" "Task" "class1" "class2"] (sort (map :block/title (model/get-all-classes repo)))))))
 
 (deftest ^:fix-me get-class-objects-test
   (let [opts {:redirect? false :create-first-block? false :class? true}

+ 1 - 1
src/test/frontend/test/fixtures.cljs

@@ -15,7 +15,7 @@
 
 (defn- reset-datascript
   [repo]
-  (let [db-name (conn/datascript-db repo)
+  (let [db-name (conn/get-repo-path repo)
         db-conn (d/create-conn db-schema/schema)]
     (state/set-current-repo! repo)
     (swap! conn/conns assoc db-name db-conn)))