Explorar o código

Merge pull request #9235 from logseq/feat/custom-children-list-style

feat(ui): Ordered(number) list
Tienson Qin %!s(int64=2) %!d(string=hai) anos
pai
achega
d2b53c3d3e

+ 1 - 0
.clj-kondo/config.edn

@@ -64,6 +64,7 @@
              frontend.handler.common.plugin plugin-common-handler
              frontend.handler.common.developer dev-common-handler
              frontend.handler.config config-handler
+             frontend.handler.editor.property editor-property
              frontend.handler.events events
              frontend.handler.global-config global-config-handler
              frontend.handler.ui ui-handler

+ 1 - 1
deps/graph-parser/src/logseq/graph_parser/property.cljs

@@ -64,7 +64,7 @@
      :created-at :updated-at :last-modified-at :created_at :last_modified_at
      :query-table :query-properties :query-sort-by :query-sort-desc :ls-type
      :hl-type :hl-page :hl-stamp :hl-color :logseq.macro-name :logseq.macro-arguments
-     :logseq.tldraw.page :logseq.tldraw.shape
+     :logseq.order-list-type :logseq.tldraw.page :logseq.tldraw.shape
      ; task markers
      :todo :doing :now :later :done}
    @built-in-extended-properties))

+ 19 - 1
src/main/frontend/commands.cljs

@@ -147,6 +147,7 @@
    "Tomorrow" "TIME & DATE"
    "LATER" "TASK"
    "A" "PRIORITY"
+   "Number list" "LIST TYPE"
    "Query" "ADVANCED"
    "Quote" "ORG-MODE"})
 
@@ -250,9 +251,14 @@
      ["Current time" #(date/get-current-time) "Insert current time"]
      ["Date picker" [[:editor/show-date-picker]] "Pick a date and insert here"]]
 
+    ;; order list
+    [["Number list" [[:editor/clear-current-slash]
+                     [:editor/toggle-own-number-list]] "Number list"]
+     ["Number children" [[:editor/clear-current-slash]
+                         [:editor/toggle-children-number-list]] "Number children"]]
+
     ;; task management
     (get-preferred-workflow)
-
     [["DONE" (->marker "DONE")]
      ["WAITING" (->marker "WAITING")]
      ["CANCELED" (->marker "CANCELED")]
@@ -654,6 +660,18 @@
         macro (youtube/gen-youtube-ts-macro)]
     (insert! input-id macro {})))
 
+(defmethod handle-step :editor/toggle-children-number-list [[_]]
+  (when-let [block (state/get-edit-block)]
+    (state/pub-event! [:editor/toggle-children-number-list block])))
+
+(defmethod handle-step :editor/toggle-own-number-list [[_]]
+  (when-let [block (state/get-edit-block)]
+    (state/pub-event! [:editor/toggle-own-number-list block])))
+
+(defmethod handle-step :editor/remove-own-number-list [[_]]
+  (when-let [block (state/get-edit-block)]
+    (state/pub-event! [:editor/remove-own-number-list block])))
+
 (defmethod handle-step :editor/show-date-picker [[_ type]]
   (if (and
        (contains? #{:scheduled :deadline} type)

+ 66 - 43
src/main/frontend/components/block.cljs

@@ -1693,10 +1693,10 @@
 
 (rum/defc block-children < rum/reactive
   [config block children collapsed?]
-  (let [ref? (:ref? config)
-        query? (:custom-query? config)
-        children (when (coll? children)
-                   (remove nil? children))]
+  (let [ref?        (:ref? config)
+        query?      (:custom-query? config)
+        children    (when (coll? children)
+                      (remove nil? children))]
     (when (and (coll? children)
                (seq children)
                (not collapsed?))
@@ -1730,13 +1730,18 @@
 
 (rum/defcs block-control < rum/reactive
   [state config block uuid block-id collapsed? *control-show? edit?]
-  (let [doc-mode? (state/sub :document/mode?)
-        control-show? (util/react *control-show?)
-        ref? (:ref? config)
-        empty-content? (block-content-empty? block)
+  (let [doc-mode?          (state/sub :document/mode?)
+        control-show?      (util/react *control-show?)
+        ref?               (:ref? config)
+        empty-content?     (block-content-empty? block)
         fold-button-right? (state/enable-fold-button-right?)
-        collapsable? (editor-handler/collapsable? uuid {:semantic? true})]
+        own-number-list?   (:own-order-number-list? config)
+        order-list?        (boolean own-number-list?)
+        order-list-idx     (:own-order-list-index config)
+        collapsable?       (editor-handler/collapsable? uuid {:semantic? true})]
     [:div.block-control-wrap.mr-1.flex.flex-row.items-center.sm:mr-2
+     {:class (util/classnames [{:is-order-list order-list?
+                                :bullet-closed collapsed?}])}
      (when (or (not fold-button-right?) collapsable?)
        [:a.block-control
         {:id       (str "control-" uuid)
@@ -1748,13 +1753,15 @@
                        (if collapsed?
                          (editor-handler/expand-block! uuid)
                          (editor-handler/collapse-block! uuid))))}
-        [:span {:class (if (and control-show?
-                                (or collapsed?
-                                    (editor-handler/collapsable? uuid {:semantic? true}))) "control-show cursor-pointer" "control-hide")}
+        [:span {:class (if (or (and control-show?
+                                    (or collapsed?
+                                        (editor-handler/collapsable? uuid {:semantic? true})))
+                               (and collapsed? order-list?))
+                         "control-show cursor-pointer"
+                         "control-hide")}
          (ui/rotating-arrow collapsed?)]])
 
-     (let [bullet [:a {:on-click (fn [event]
-                                   (bullet-on-click event block uuid))}
+     (let [bullet [:a.bullet-link-wrap {:on-click #(bullet-on-click % block uuid)}
                    [:span.bullet-container.cursor
                     {:id (str "dot-" uuid)
                      :draggable true
@@ -1762,11 +1769,14 @@
                                       (bullet-drag-start event block uuid block-id))
                      :blockid (str uuid)
                      :class (str (when collapsed? "bullet-closed")
-                                 " "
                                  (when (and (:document/mode? config)
                                             (not collapsed?))
-                                   "hide-inner-bullet"))}
-                    [:span.bullet {:blockid (str uuid)}]]]]
+                                   " hide-inner-bullet")
+                                 (when order-list? " as-order-list typed-list"))}
+
+                    [:span.bullet {:blockid (str uuid)}
+                     (when order-list?
+                       [:label (str order-list-idx ".")])]]]]
        (cond
          (and (or (mobile-util/native-platform?)
                   (:ui/show-empty-bullets? (state/get-config)))
@@ -1774,14 +1784,14 @@
          bullet
 
          (or
-          (and empty-content?
-               (not edit?)
-               (not (:block/top? block))
-               (not (:block/bottom? block))
-               (not (util/react *control-show?)))
-          (and doc-mode?
-               (not collapsed?)
-               (not (util/react *control-show?))))
+           (and empty-content?
+                (not edit?)
+                (not (:block/top? block))
+                (not (:block/bottom? block))
+                (not (util/react *control-show?)))
+           (and doc-mode?
+                (not collapsed?)
+                (not (util/react *control-show?))))
          ;; hidden
          [:span.bullet-container]
 
@@ -2768,6 +2778,7 @@
         config (if (nil? (:query-result config))
                  (assoc config :query-result (atom nil))
                  config)
+        config (if ref? (block-handler/attach-order-list-state config block) config)
         heading? (:heading properties)
         *control-show? (get state ::control-show?)
         db-collapsed? (util/collapsed? block)
@@ -2868,6 +2879,12 @@
 
      (dnd-separator-wrapper block block-id slide? false false)]))
 
+(defn- attach-order-list-state!
+  [cp-state]
+  (let [args (:rum/args cp-state)]
+    (assoc cp-state
+      :rum/args (assoc (vec args) 0 (block-handler/attach-order-list-state (first args) (second args))))))
+
 (rum/defcs block-container < rum/reactive
   (rum/local false ::show-block-left-menu?)
   (rum/local false ::show-block-right-menu?)
@@ -2884,20 +2901,26 @@
 
                :else
                nil)
-             (assoc state
-                    ::control-show? (atom false)
-                    ::navigating-block (atom (:block/uuid block)))))
+             (-> (assoc state
+                   ::control-show? (atom false)
+                   ::navigating-block (atom (:block/uuid block)))
+                 (attach-order-list-state!))))
+
+   :will-remount (fn [_old-state new-state]
+                   (-> new-state
+                       (attach-order-list-state!)))
+
    :should-update (fn [old-state new-state]
-                    (let [compare-keys [:block/uuid :block/content :block/parent :block/collapsed?
-                                        :block/properties :block/left :block/children :block/_refs :block/bottom? :block/top?]
-                          config-compare-keys [:show-cloze?]
-                          b1 (second (:rum/args old-state))
-                          b2 (second (:rum/args new-state))
-                          result (or
-                                  (not= (select-keys b1 compare-keys)
-                                        (select-keys b2 compare-keys))
-                                  (not= (select-keys (first (:rum/args old-state)) config-compare-keys)
-                                        (select-keys (first (:rum/args new-state)) config-compare-keys)))]
+                    (let [compare-keys        [:block/uuid :block/content :block/parent :block/collapsed?
+                                               :block/properties :block/left :block/children :block/_refs :block/bottom? :block/top?]
+                          config-compare-keys [:show-cloze? :own-order-list-type :own-order-list-index]
+                          b1                  (second (:rum/args old-state))
+                          b2                  (second (:rum/args new-state))
+                          result              (or
+                                                (not= (select-keys b1 compare-keys)
+                                                      (select-keys b2 compare-keys))
+                                                (not= (select-keys (first (:rum/args old-state)) config-compare-keys)
+                                                      (select-keys (first (:rum/args new-state)) config-compare-keys)))]
                       (boolean result)))
    :will-unmount (fn [state]
                    ;; restore root block's collapsed state
@@ -2907,8 +2930,8 @@
                        (state/set-collapsed-block! block-id nil)))
                    state)}
   [state config block]
-  (let [repo (state/get-current-repo)
-        ref? (:ref? config)
+  (let [repo          (state/get-current-repo)
+        ref?          (:ref? config)
         custom-query? (boolean (:custom-query? config))]
     (if (and (or ref? custom-query?) (not (:ref-query-child? config)))
       (ui/lazy-visible
@@ -2918,11 +2941,11 @@
 
 (defn divide-lists
   [[f & l]]
-  (loop [l l
+  (loop [l        l
          ordered? (:ordered f)
-         result [[f]]]
+         result   [[f]]]
     (if (seq l)
-      (let [cur (first l)
+      (let [cur          (first l)
             cur-ordered? (:ordered cur)]
         (if (= ordered? cur-ordered?)
           (recur

+ 37 - 10
src/main/frontend/components/block.css

@@ -116,6 +116,7 @@
       position: relative;
       top: 4px;
     }
+
     a {
       color: var(--ls-primary-text-color);
 
@@ -202,6 +203,10 @@
 .block-control-wrap {
   height: 24px;
   margin-top: 0;
+
+  &.is-order-list {
+    @apply relative right-0 mr-0;
+  }
 }
 
 .block-control, .block-control:hover {
@@ -525,25 +530,47 @@
     background-color: var(--ls-block-bullet-color, #8fbc8f);
   }
 
+  &.as-order-list {
+    @apply w-[28px] whitespace-nowrap justify-start;
+  }
+
   .bullet {
-    border-radius: 50%;
-    width: 6px;
-    height: 6px;
+    @apply rounded-full w-[6px] h-[6px];
+
     background-color: var(--ls-block-bullet-color, #394b59);
     transition: transform 0.2s;
+
+    > * {
+      @apply cursor-pointer;
+    }
   }
 
-  &.bullet-closed {
-    background-color: var(--ls-block-bullet-border-color, #ced9e0);
+  &:not(.typed-list) {
+    &.bullet-closed {
+      background-color: var(--ls-block-bullet-border-color, #ced9e0);
+    }
   }
-}
 
-a:hover > .bullet-container .bullet {
-  transform: scale(1.4);
+  &.typed-list:not(:focus-within) {
+    .bullet {
+      background-color: unset;
+      height: unset;
+      width: unset;
+      box-shadow: none;
+    }
+  }
 }
 
-a:hover > .bullet-container {
-  background-color: var(--ls-block-bullet-border-color, #ced9e0);
+.bullet-link-wrap {
+  color: var(--ls-primary-text-color);
+
+  &:hover > .bullet-container .bullet {
+    transform: scale(1.4);
+  }
+
+  &:hover > .bullet-container:not(.typed-list) {
+    background-color: var(--ls-block-bullet-border-color, #ced9e0);
+  }
 }
 
 .content.doc-mode {

+ 21 - 7
src/main/frontend/components/content.cljs

@@ -10,6 +10,7 @@
             [frontend.extensions.srs :as srs]
             [frontend.handler.common :as common-handler]
             [frontend.handler.editor :as editor-handler]
+            [frontend.handler.editor.property :as editor-property]
             [frontend.handler.image :as image-handler]
             [frontend.handler.notification :as notification]
             [frontend.handler.page :as page-handler]
@@ -31,8 +32,8 @@
 (rum/defc custom-context-menu-content
   []
   [:.menu-links-wrapper
-   (ui/menu-background-color #(editor-handler/batch-add-block-property! (state/get-selection-block-ids) :background-color %)
-                             #(editor-handler/batch-remove-block-property! (state/get-selection-block-ids) :background-color))
+   (ui/menu-background-color #(editor-property/batch-add-block-property! (state/get-selection-block-ids) :background-color %)
+                             #(editor-property/batch-remove-block-property! (state/get-selection-block-ids) :background-color))
 
    (ui/menu-heading #(editor-handler/batch-set-heading! (state/get-selection-block-ids) %)
                     #(editor-handler/batch-set-heading! (state/get-selection-block-ids) true)
@@ -84,6 +85,12 @@
       (t :context-menu/make-a-flashcard)
       nil))
 
+   (ui/menu-link
+     {:key "Toggle number list"
+      :on-click #(state/pub-event! [:editor/toggle-own-number-list (state/get-selection-block-ids)])}
+     (t :context-menu/toggle-number-list)
+     nil)
+
    (ui/menu-link
     {:key "cycle todos"
      :on-click editor-handler/cycle-todos!}
@@ -151,9 +158,9 @@
                                         [:p (t :context-menu/template-exists-warning)]
                                         :error)
                                        (do
-                                         (editor-handler/set-block-property! block-id :template title)
+                                         (editor-property/set-block-property! block-id :template title)
                                          (when (false? template-including-parent?)
-                                           (editor-handler/set-block-property! block-id :template-including-parent false))
+                                           (editor-property/set-block-property! block-id :template-including-parent false))
                                          (state/hide-custom-context-menu!)))))))]
          [:hr.menu-separator]])
       (ui/menu-link
@@ -170,8 +177,8 @@
     (when-let [block (db/entity [:block/uuid block-id])]
       (let [heading (-> block :block/properties :heading (or false))]
         [:.menu-links-wrapper
-         (ui/menu-background-color #(editor-handler/set-block-property! block-id :background-color %)
-                                   #(editor-handler/remove-block-property! block-id :background-color))
+         (ui/menu-background-color #(editor-property/set-block-property! block-id :background-color %)
+                                   #(editor-property/remove-block-property! block-id :background-color))
 
          (ui/menu-heading heading
                           #(editor-handler/set-heading! block-id %)
@@ -255,6 +262,12 @@
            :else
            nil)
 
+         (ui/menu-link
+           {:key "Toggle number list"
+            :on-click #(state/pub-event! [:editor/toggle-own-number-list (state/get-selection-block-ids)])}
+           (t :context-menu/toggle-number-list)
+           nil)
+
          [:hr.menu-separator]
 
          (ui/menu-link
@@ -353,7 +366,8 @@
      (mixins/listen state js/window "contextmenu"
                     (fn [e]
                       (let [target (gobj/get e "target")
-                            block-id (d/attr target "blockid")
+                            block-el (.closest target ".bullet-container[blockid]")
+                            block-id (some-> block-el (.getAttribute "blockid"))
                             {:keys [block block-ref]} (state/sub :block-ref/context)
                             {:keys [page]} (state/sub :page-title/context)]
                         (cond

+ 3 - 2
src/main/frontend/components/query.cljs

@@ -12,6 +12,7 @@
             [lambdaisland.glogi :as log]
             [frontend.extensions.sci :as sci]
             [frontend.handler.editor :as editor-handler]
+            [frontend.handler.editor.property :as editor-property]
             [logseq.graph-parser.util :as gp-util]))
 
 (defn built-in-custom-query?
@@ -206,12 +207,12 @@
                (when (and current-block (not view-f) (nil? table-view?) (not page-list?))
                  (if table?
                    [:a.flex.ml-1.fade-link {:title "Switch to list view"
-                                            :on-click (fn [] (editor-handler/set-block-property! current-block-uuid
+                                            :on-click (fn [] (editor-property/set-block-property! current-block-uuid
                                                                                                  "query-table"
                                                                                                  false))}
                     (ui/icon "list" {:style {:font-size 20}})]
                    [:a.flex.ml-1.fade-link {:title "Switch to table view"
-                                            :on-click (fn [] (editor-handler/set-block-property! current-block-uuid
+                                            :on-click (fn [] (editor-property/set-block-property! current-block-uuid
                                                                                                  "query-table"
                                                                                                  true))}
                     (ui/icon "table" {:style {:font-size 20}})]))

+ 3 - 3
src/main/frontend/components/query_table.cljs

@@ -4,7 +4,7 @@
             [frontend.db :as db]
             [frontend.db.query-dsl :as query-dsl]
             [frontend.handler.common :as common-handler]
-            [frontend.handler.editor :as editor-handler]
+            [frontend.handler.editor.property :as editor-property]
             [frontend.state :as state]
             [frontend.util :as util]
             [frontend.util.clock :as clock]
@@ -80,8 +80,8 @@
   [title column {:keys [sort-by-column sort-desc?]} block-id]
   [:th.whitespace-nowrap
    [:a {:on-click (fn []
-                    (editor-handler/set-block-property! block-id :query-sort-by (name column))
-                    (editor-handler/set-block-property! block-id :query-sort-desc (not sort-desc?)))}
+                    (editor-property/set-block-property! block-id :query-sort-by (name column))
+                    (editor-property/set-block-property! block-id :query-sort-desc (not sort-desc?)))}
     [:div.flex.items-center
      [:span.mr-1 title]
      (when (= sort-by-column column)

+ 1 - 0
src/main/frontend/dicts.cljc

@@ -171,6 +171,7 @@
         :content/open-in-sidebar "Open in sidebar"
         :content/click-to-edit "Click to edit"
         :context-menu/make-a-flashcard "Make a Flashcard"
+        :context-menu/toggle-number-list "Toggle number list"
         :context-menu/preview-flashcard "Preview Flashcard"
         :context-menu/make-a-template "Make a Template"
         :context-menu/input-template-name "What's the template's name?"

+ 2 - 1
src/main/frontend/extensions/pdf/assets.cljs

@@ -6,6 +6,7 @@
             [frontend.db.utils :as db-utils]
             [frontend.fs :as fs]
             [frontend.handler.editor :as editor-handler]
+            [frontend.handler.editor.property :as editor-property]
             [frontend.handler.page :as page-handler]
             [frontend.handler.assets :as assets-handler]
             [frontend.handler.notification :as notification]
@@ -132,7 +133,7 @@
                                (get-in highlight [:content :image])
                                (js/Date.now))
                    :hl-color (get-in highlight [:properties :color])}]
-      (editor-handler/set-block-property! (:block/uuid block) k v))))
+      (editor-property/set-block-property! (:block/uuid block) k v))))
 
 (defn unlink-hl-area-image$
   [^js _viewer current hl]

+ 2 - 1
src/main/frontend/extensions/srs.cljs

@@ -13,6 +13,7 @@
             [frontend.db-mixins :as db-mixins]
             [frontend.state :as state]
             [frontend.handler.editor :as editor-handler]
+            [frontend.handler.editor.property :as editor-property]
             [frontend.components.block :as component-block]
             [frontend.components.macro :as component-macro]
             [frontend.components.select :as component-select]
@@ -483,7 +484,7 @@
                                    :on-click   (fn []
                                                  (score-and-next-card 1 card card-index finished? phase review-records cb)
                                                  (let [tomorrow (tc/to-string (t/plus (t/today) (t/days 1)))]
-                                                   (editor-handler/set-block-property! root-block-id card-next-schedule-property tomorrow)))})
+                                                   (editor-property/set-block-property! root-block-id card-next-schedule-property tomorrow)))})
 
                (btn-with-shortcut {:btn-text (if (util/mobile?) "Hard" "Took a while to recall")
                                    :shortcut "t"

+ 2 - 2
src/main/frontend/fs/watcher_handler.cljs

@@ -7,7 +7,7 @@
             [frontend.db.model :as model]
             [frontend.fs :as fs]
             [logseq.common.path :as path]
-            [frontend.handler.editor :as editor]
+            [frontend.handler.editor.property :as editor-property]
             [frontend.handler.file :as file-handler]
             [frontend.handler.page :as page-handler]
             [frontend.handler.ui :as ui-handler]
@@ -33,7 +33,7 @@
                            nil))]
         (let [id-property (:id (:block/properties block))]
           (when-not (= (str id-property) (str block-id))
-            (editor/set-block-property! block-id "id" block-id)))))))
+            (editor-property/set-block-property! block-id "id" block-id)))))))
 
 (defn- handle-add-and-change!
   [repo path content db-content mtime backup?]

+ 35 - 0
src/main/frontend/handler/block.cljs

@@ -291,3 +291,38 @@
                               (recur parent (conj result parent))
                               result))))]
       (distinct (mapcat get-parents filtered-ref-blocks)))))
+
+(defn get-idx-of-order-list-block
+  [block order-list-type]
+  (let [order-block-fn? #(some-> % :block/properties :logseq.order-list-type (= order-list-type))
+        prev-block-fn   #(some->> (:db/id %) (db-model/get-prev-sibling (state/get-current-repo)))
+        prev-block      (prev-block-fn block)]
+    (letfn [(page-fn? [b] (some-> b :block/name some?))
+            (order-sibling-list [b]
+              (lazy-seq
+                (when (and (not (page-fn? b)) (order-block-fn? b))
+                  (cons b (order-sibling-list (prev-block-fn b))))))
+            (order-parent-list [b]
+              (lazy-seq
+                (when (and (not (page-fn? b)) (order-block-fn? b))
+                  (cons b (order-parent-list (db-model/get-block-parent (:block/uuid b)))))))]
+      (let [idx           (if prev-block
+                            (count (order-sibling-list block)) 1)
+            order-parents-count (dec (count (order-parent-list block)))
+            delta (if (neg? order-parents-count) 0 (mod order-parents-count 3))]
+        (cond
+          (zero? delta) idx
+
+          (= delta 1)
+          (some-> (util/convert-to-letters idx) util/safe-lower-case)
+
+          :else
+          (util/convert-to-roman idx))))))
+
+(defn attach-order-list-state
+  [config block]
+  (let [own-order-list-type  (some-> block :block/properties :logseq.order-list-type str string/lower-case)
+        own-order-list-index (some->> own-order-list-type (get-idx-of-order-list-block block))]
+    (assoc config :own-order-list-type own-order-list-type
+                  :own-order-list-index own-order-list-index
+                  :own-order-number-list? (= own-order-list-type "number"))))

+ 2 - 1
src/main/frontend/handler/dnd.cljs

@@ -1,6 +1,7 @@
 (ns frontend.handler.dnd
   "Provides fns for drag n drop"
   (:require [frontend.handler.editor :as editor-handler]
+            [frontend.handler.editor.property :as editor-property]
             [frontend.modules.outliner.core :as outliner-core]
             [frontend.modules.outliner.tree :as tree]
             [frontend.modules.outliner.transaction :as outliner-tx]
@@ -20,7 +21,7 @@
       ;; alt pressed, make a block-ref
       (and alt-key? (= (count blocks) 1))
       (do
-        (editor-handler/set-block-property! (:block/uuid first-block)
+        (editor-property/set-block-property! (:block/uuid first-block)
                                             :id
                                             (str (:block/uuid first-block)))
         (editor-handler/api-insert-new-block!

+ 69 - 141
src/main/frontend/handler/editor.cljs

@@ -19,6 +19,7 @@
             [frontend.handler.assets :as assets-handler]
             [frontend.handler.block :as block-handler]
             [frontend.handler.common :as common-handler]
+            [frontend.handler.editor.property :as editor-property]
             [frontend.handler.export.html :as export-html]
             [frontend.handler.export.text :as export-text]
             [frontend.handler.notification :as notification]
@@ -62,6 +63,41 @@
 (defonce *asset-uploading? (atom false))
 (defonce *asset-uploading-process (atom 0))
 
+(def clear-selection! editor-property/clear-selection!)
+(def edit-block! editor-property/edit-block!)
+
+(defn get-block-own-order-list-type
+  [block]
+  (some-> block :block/properties :logseq.order-list-type))
+
+(defn set-block-own-order-list-type!
+  [block type]
+  (when-let [uuid (:block/uuid block)]
+    (editor-property/set-block-property! uuid :logseq.order-list-type (name type))))
+
+(defn remove-block-own-order-list-type!
+  [block]
+  (when-let [uuid (:block/uuid block)]
+    (editor-property/remove-block-property! uuid :logseq.order-list-type)))
+
+(defn own-order-number-list?
+  [block]
+  (= (get-block-own-order-list-type block) "number"))
+
+(defn make-block-as-own-order-list!
+  [block]
+  (some-> block (set-block-own-order-list-type! "number")))
+
+(defn toggle-blocks-as-own-order-list!
+  [blocks]
+  (when (seq blocks)
+    (let [has-ordered?    (some own-order-number-list? blocks)
+          blocks-uuids    (some->> blocks (map :block/uuid) (remove nil?))
+          order-list-prop :logseq.order-list-type]
+      (if has-ordered?
+        (editor-property/batch-remove-block-property! blocks-uuids order-list-prop)
+        (editor-property/batch-add-block-property! blocks-uuids order-list-prop "number")))))
+
 (defn get-selection-and-format
   []
   (when-let [block (state/get-edit-block)]
@@ -197,69 +233,7 @@
     (doseq [block blocks]
       (gdom-classes/remove block "block-highlight"))))
 
-(defn- get-edit-input-id-with-block-id
-  [block-id]
-  (when-let [first-block (util/get-first-block-by-id block-id)]
-    (string/replace (gobj/get first-block "id")
-                    "ls-block"
-                    "edit-block")))
-
-(defn clear-selection!
-  []
-  (state/clear-selection!))
-
-(defn- text-range-by-lst-fst-line [content [direction pos]]
-  (case direction
-    :up
-    (let [last-new-line (or (string/last-index-of content \newline) -1)
-          end (+ last-new-line pos 1)]
-      (subs content 0 end))
-    :down
-    (-> (string/split-lines content)
-        first
-        (or "")
-        (subs 0 pos))))
-
 ;; id: block dom id, "ls-block-counter-uuid"
-(defn edit-block!
-  ([block pos id]
-   (edit-block! block pos id nil))
-  ([block pos id {:keys [custom-content tail-len move-cursor? retry-times]
-                  :or {tail-len 0
-                       move-cursor? true
-                       retry-times 0}
-                  :as opts}]
-   (when-not (> retry-times 2)
-     (when-not config/publishing?
-       (when-let [block-id (:block/uuid block)]
-         (let [block (or (db/pull [:block/uuid block-id]) block)
-               edit-input-id (if (uuid? id)
-                               (get-edit-input-id-with-block-id id)
-                               (-> (str (subs id 0 (- (count id) 36)) block-id)
-                                   (string/replace "ls-block" "edit-block")))
-               content (or custom-content (:block/content block) "")
-               content-length (count content)
-               text-range (cond
-                            (vector? pos)
-                            (text-range-by-lst-fst-line content pos)
-
-                            (and (> tail-len 0) (>= (count content) tail-len))
-                            (subs content 0 (- (count content) tail-len))
-
-                            (or (= :max pos) (<= content-length pos))
-                            content
-
-                            :else
-                            (subs content 0 pos))
-               content (-> (property/remove-built-in-properties (:block/format block)
-                                                                content)
-                           (drawer/remove-logbook))]
-           (clear-selection!)
-           (if edit-input-id
-             (state/set-editing! edit-input-id content block text-range move-cursor?)
-             ;; Block may not be rendered yet
-             (js/setTimeout (fn [] (edit-block! block pos id (update opts :retry-times inc))) 10))))))))
-
 (defn- another-block-with-same-id-exists?
   [current-id block-id]
   (when-let [id (and (string? block-id) (parse-uuid block-id))]
@@ -877,72 +851,6 @@
        :block/properties-order (or (keys properties) [])
        :block/content content})))
 
-(defn- batch-set-block-property!
-  "col: a collection of [block-id property-key property-value]."
-  [col]
-  #_:clj-kondo/ignore
-  (when-let [repo (state/get-current-repo)]
-    (let [col' (group-by first col)]
-      (outliner-tx/transact!
-       {:outliner-op :save-block}
-        (doseq [[block-id items] col']
-          (let [block-id (if (string? block-id) (uuid block-id) block-id)
-                new-properties (zipmap (map second items)
-                                (map last items))]
-            (when-let [block (db/entity [:block/uuid block-id])]
-              (let [format (:block/format block)
-                    content (:block/content block)
-                    properties (:block/properties block)
-                    properties-text-values (:block/properties-text-values block)
-                    properties (-> (merge properties new-properties)
-                                   gp-util/remove-nils-non-nested)
-                    properties-text-values (-> (merge properties-text-values new-properties)
-                                               gp-util/remove-nils-non-nested)
-                    property-ks (->> (concat (:block/properties-order block)
-                                             (map second items))
-                                     (filter (set (keys properties)))
-                                     distinct
-                                     vec)
-                    content (property/remove-properties format content)
-                    kvs (for [key property-ks] [key (or (get properties-text-values key)
-                                                        (get properties key))])
-                    content (property/insert-properties format content kvs)
-                    content (property/remove-empty-properties content)
-                    block {:block/uuid block-id
-                           :block/properties properties
-                           :block/properties-order property-ks
-                           :block/properties-text-values properties-text-values
-                           :block/content content}]
-                (outliner-core/save-block! block)))))))
-
-    (let [block-id (ffirst col)
-          block-id (if (string? block-id) (uuid block-id) block-id)
-          input-pos (or (state/get-edit-pos) :max)]
-      ;; update editing input content
-      (when-let [editing-block (state/get-edit-block)]
-        (when (= (:block/uuid editing-block) block-id)
-          (edit-block! editing-block
-                       input-pos
-                       (state/get-edit-input-id)))))))
-
-(defn batch-add-block-property!
-  [block-ids property-key property-value]
-  (batch-set-block-property! (map #(vector % property-key property-value) block-ids)))
-
-(defn batch-remove-block-property!
-  [block-ids property-key]
-  (batch-set-block-property! (map #(vector % property-key nil) block-ids)))
-
-(defn remove-block-property!
-  [block-id key]
-  (let [key (keyword key)]
-    (batch-set-block-property! [[block-id key nil]])))
-
-(defn set-block-property!
-  [block-id key value]
-  (let [key (keyword key)]
-    (batch-set-block-property! [[block-id key value]])))
-
 (defn set-block-query-properties!
   [block-id all-properties key add?]
   (when-let [block (db/entity [:block/uuid block-id])]
@@ -956,8 +864,8 @@
                              (remove #{key} query-properties))
           query-properties (vec query-properties)]
       (if (seq query-properties)
-        (set-block-property! block-id :query-properties (str query-properties))
-        (remove-block-property! block-id :query-properties)))))
+        (editor-property/set-block-property! block-id :query-properties (str query-properties))
+        (editor-property/remove-block-property! block-id :query-properties)))))
 
 (defn set-block-timestamp!
   [block-id key value]
@@ -1001,7 +909,7 @@
                        [block-id :id (str block-id)])))
                  block-ids)
         col (remove nil? col)]
-    (batch-set-block-property! col)))
+    (editor-property/batch-set-block-property! col)))
 
 (defn copy-block-ref!
   ([block-id]
@@ -1910,14 +1818,23 @@
 
 (defn handle-last-input []
   (let [input           (state/get-input)
+        input-id        (state/get-edit-input-id)
+        edit-block      (state/get-edit-block)
         pos             (cursor/pos input)
-        last-input-char (util/nth-safe (.-value input) (dec pos))
-        last-prev-input-char (util/nth-safe (.-value input) (dec (dec pos)))
-        prev-prev-input-char (util/nth-safe (.-value input) (- pos 3))]
+        content         (.-value input)
+        last-input-char (util/nth-safe content (dec pos))
+        last-prev-input-char (util/nth-safe content (dec (dec pos)))
+        prev-prev-input-char (util/nth-safe content (- pos 3))]
 
     ;; TODO: is it cross-browser compatible?
     ;; (not= (gobj/get native-e "inputType") "insertFromPaste")
     (cond
+      (and (= content "1. ") (= last-input-char " ") input-id edit-block
+           (not (own-order-number-list? edit-block)))
+      (do
+        (state/pub-event! [:editor/toggle-own-number-list edit-block])
+        (state/set-edit-content! input-id ""))
+
       (and (= last-input-char (state/get-editor-command-trigger))
            (or (re-find #"(?m)^/" (str (.-value input))) (start-of-new-word? input pos)))
       (do
@@ -1985,9 +1902,9 @@
                         :command :block-ref})
 
       ;; Save it so it'll be parsed correctly in the future
-      (set-block-property! (:block/uuid chosen)
-                           :id
-                           uuid-string)
+      (editor-property/set-block-property! (:block/uuid chosen)
+                                           :id
+                                           uuid-string)
 
       (when-let [input (gdom/getElement id)]
         (.focus input)))))
@@ -2450,6 +2367,7 @@
     (let [{:keys [block config]} (get-state)]
       (when block
         (let [input (state/get-input)
+              config (assoc config :keydown-new-block true)
               content (gobj/get input "value")
               pos (cursor/pos input)
               current-node (outliner-core/block block)
@@ -2492,6 +2410,12 @@
               "list-item" (dwim-in-list)
               "properties-drawer" (dwim-in-properties state))
 
+            (and (string/blank? content)
+                 (own-order-number-list? block)
+                 (not (some-> (db-model/get-block-parent (:block/uuid block))
+                              (own-order-number-list?))))
+            (remove-block-own-order-list-type! block)
+
             (and
              (string/blank? content)
              (not has-right?)
@@ -2739,7 +2663,11 @@
                    (not root-block?)
                    (not single-block?)
                    (not custom-query?))
-          (delete-block! repo false)))
+          (if (own-order-number-list? block)
+            (do
+              (save-current-block!)
+              (remove-block-own-order-list-type! block))
+            (delete-block! repo false))))
 
       (and (> current-pos 1)
            (= (util/nth-safe value (dec current-pos)) (state/get-editor-command-trigger)))
@@ -3177,7 +3105,7 @@
     (and (state/editing?) (util/input-text-selected?
                            (gdom/getElement (state/get-edit-input-id))))
     (keydown-backspace-handler true e)
-    
+
     (whiteboard?)
     (.cut (state/active-tldraw-app))
 
@@ -3497,7 +3425,7 @@
 
      (whiteboard?)
      (.setCollapsed (.-api ^js (state/active-tldraw-app)) false)
-     
+
      :else
      ;; expand one level
      (let [blocks-with-level (all-blocks-with-level {})
@@ -3531,7 +3459,7 @@
                        collapse-block!)))
             doall)
        (and clear-selection? (clear-selection!)))
-     
+
      (whiteboard?)
      (.setCollapsed (.-api ^js (state/active-tldraw-app)) true)
 

+ 141 - 0
src/main/frontend/handler/editor/property.cljs

@@ -0,0 +1,141 @@
+(ns frontend.handler.editor.property
+  "Property related fns for the editor"
+  (:require [clojure.string :as string]
+            [frontend.config :as config]
+            [frontend.db :as db]
+            [frontend.modules.outliner.core :as outliner-core]
+            [frontend.modules.outliner.transaction :as outliner-tx]
+            [frontend.state :as state]
+            [frontend.util :as util]
+            [frontend.util.drawer :as drawer]
+            [frontend.util.property :as property]
+            [goog.object :as gobj]
+            [logseq.graph-parser.util :as gp-util]))
+
+(defn clear-selection!
+  []
+  (state/clear-selection!))
+
+(defn- get-edit-input-id-with-block-id
+  [block-id]
+  (when-let [first-block (util/get-first-block-by-id block-id)]
+    (string/replace (gobj/get first-block "id")
+                    "ls-block"
+                    "edit-block")))
+
+(defn- text-range-by-lst-fst-line [content [direction pos]]
+  (case direction
+    :up
+    (let [last-new-line (or (string/last-index-of content \newline) -1)
+          end (+ last-new-line pos 1)]
+      (subs content 0 end))
+    :down
+    (-> (string/split-lines content)
+        first
+        (or "")
+        (subs 0 pos))))
+
+(defn edit-block!
+  ([block pos id]
+   (edit-block! block pos id nil))
+  ([block pos id {:keys [custom-content tail-len move-cursor? retry-times]
+                  :or {tail-len 0
+                       move-cursor? true
+                       retry-times 0}
+                  :as opts}]
+   (when-not (> retry-times 2)
+     (when-not config/publishing?
+       (when-let [block-id (:block/uuid block)]
+         (let [block (or (db/pull [:block/uuid block-id]) block)
+               edit-input-id (if (uuid? id)
+                               (get-edit-input-id-with-block-id id)
+                               (-> (str (subs id 0 (- (count id) 36)) block-id)
+                                   (string/replace "ls-block" "edit-block")))
+               content (or custom-content (:block/content block) "")
+               content-length (count content)
+               text-range (cond
+                            (vector? pos)
+                            (text-range-by-lst-fst-line content pos)
+
+                            (and (> tail-len 0) (>= (count content) tail-len))
+                            (subs content 0 (- (count content) tail-len))
+
+                            (or (= :max pos) (<= content-length pos))
+                            content
+
+                            :else
+                            (subs content 0 pos))
+               content (-> (property/remove-built-in-properties (:block/format block)
+                                                                content)
+                           (drawer/remove-logbook))]
+           (clear-selection!)
+           (if edit-input-id
+             (state/set-editing! edit-input-id content block text-range move-cursor?)
+             ;; Block may not be rendered yet
+             (js/setTimeout (fn [] (edit-block! block pos id (update opts :retry-times inc))) 10))))))))
+
+(defn batch-set-block-property!
+  "col: a collection of [block-id property-key property-value]."
+  [col]
+  #_:clj-kondo/ignore
+  (when-let [repo (state/get-current-repo)]
+    (let [col' (group-by first col)]
+      (outliner-tx/transact!
+       {:outliner-op :save-block}
+       (doseq [[block-id items] col']
+         (let [block-id (if (string? block-id) (uuid block-id) block-id)
+               new-properties (zipmap (map second items)
+                                      (map last items))]
+           (when-let [block (db/entity [:block/uuid block-id])]
+             (let [format (:block/format block)
+                   content (:block/content block)
+                   properties (:block/properties block)
+                   properties-text-values (:block/properties-text-values block)
+                   properties (-> (merge properties new-properties)
+                                  gp-util/remove-nils-non-nested)
+                   properties-text-values (-> (merge properties-text-values new-properties)
+                                              gp-util/remove-nils-non-nested)
+                   property-ks (->> (concat (:block/properties-order block)
+                                            (map second items))
+                                    (filter (set (keys properties)))
+                                    distinct
+                                    vec)
+                   content (property/remove-properties format content)
+                   kvs (for [key property-ks] [key (or (get properties-text-values key)
+                                                       (get properties key))])
+                   content (property/insert-properties format content kvs)
+                   content (property/remove-empty-properties content)
+                   block {:block/uuid block-id
+                          :block/properties properties
+                          :block/properties-order property-ks
+                          :block/properties-text-values properties-text-values
+                          :block/content content}]
+               (outliner-core/save-block! block)))))))
+
+    (let [block-id (ffirst col)
+          block-id (if (string? block-id) (uuid block-id) block-id)
+          input-pos (or (state/get-edit-pos) :max)]
+      ;; update editing input content
+      (when-let [editing-block (state/get-edit-block)]
+        (when (= (:block/uuid editing-block) block-id)
+          (edit-block! editing-block
+                       input-pos
+                       (state/get-edit-input-id)))))))
+
+(defn batch-add-block-property!
+  [block-ids property-key property-value]
+  (batch-set-block-property! (map #(vector % property-key property-value) block-ids)))
+
+(defn batch-remove-block-property!
+  [block-ids property-key]
+  (batch-set-block-property! (map #(vector % property-key nil) block-ids)))
+
+(defn remove-block-property!
+  [block-id key]
+  (let [key (keyword key)]
+    (batch-set-block-property! [[block-id key nil]])))
+
+(defn set-block-property!
+  [block-id key value]
+  (let [key (keyword key)]
+    (batch-set-block-property! [[block-id key value]])))

+ 20 - 0
src/main/frontend/handler/events.cljs

@@ -948,6 +948,26 @@
 (defmethod handle :editor/quick-capture [[_ args]]
   (quick-capture/quick-capture args))
 
+(defmethod handle :editor/toggle-own-number-list [[_ blocks]]
+  (let [batch? (sequential? blocks)
+        blocks (cond->> blocks
+                  batch?
+                  (map #(cond-> % (or (uuid? %) (string? %)) (db-model/get-block-by-uuid))))]
+    (if (and batch? (> (count blocks) 1))
+      (editor-handler/toggle-blocks-as-own-order-list! blocks)
+      (when-let [block (cond-> blocks batch? (first))]
+        (if (editor-handler/own-order-number-list? block)
+          (editor-handler/remove-block-own-order-list-type! block)
+          (editor-handler/make-block-as-own-order-list! block))))))
+
+(defmethod handle :editor/remove-own-number-list [[_ block]]
+  (when (some-> block (editor-handler/own-order-number-list?))
+    (editor-handler/remove-block-own-order-list-type! block)))
+
+(defmethod handle :editor/toggle-children-number-list [[_ block]]
+  (when-let [blocks (and block (db-model/get-block-immediate-children (state/get-current-repo) (:block/uuid block)))]
+    (editor-handler/toggle-blocks-as-own-order-list! blocks)))
+
 (defn run!
   []
   (let [chan (state/get-events-chan)]

+ 18 - 1
src/main/frontend/modules/outliner/core.cljs

@@ -12,6 +12,7 @@
             [frontend.modules.outliner.utils :as outliner-u]
             [frontend.state :as state]
             [frontend.util :as util]
+            [frontend.util.property :as property]
             [logseq.graph-parser.util :as gp-util]
             [cljs.spec.alpha :as s]))
 
@@ -409,6 +410,21 @@
            last
            rest))))
 
+(defn blocks-with-ordered-list-props
+  [blocks target-block sibling?]
+  (let [target-block (if sibling? target-block (some-> target-block :db/id db/pull block tree/-get-down :data))]
+    (letfn [(list-type-fn [b] (some-> b :block/properties :logseq.order-list-type))]
+      (if-let [list-type (and target-block (list-type-fn target-block))]
+        (mapv
+          (fn [{:block/keys [content format] :as block}]
+            (cond-> block
+              (and (some? (:block/uuid block))
+                   (nil? (list-type-fn block)))
+              (-> (update :block/properties #(assoc % :logseq.order-list-type list-type))
+                  (assoc :block/content (property/insert-property format content :logseq.order-list-type list-type)))))
+          blocks)
+        blocks))))
+
 ;;; ### insert-blocks, delete-blocks, move-blocks
 
 (defn fix-top-level-blocks
@@ -519,6 +535,7 @@
                                      (> (count blocks) 1)
                                      (not move?)))
         blocks' (blocks-with-level blocks)
+        blocks' (blocks-with-ordered-list-props blocks' target-block sibling?)
         blocks' (if (= outliner-op :paste)
                   (fix-top-level-blocks blocks')
                   blocks')
@@ -560,7 +577,7 @@
         (when (and replace-empty-target? (state/editing?))
           (state/set-edit-content! (state/get-edit-input-id) (:block/content (first blocks))))
         {:tx-data full-tx
-         :blocks tx}))))
+         :blocks  tx}))))
 
 (defn- build-move-blocks-next-tx
   [blocks non-consecutive-blocks?]

+ 5 - 0
src/main/frontend/modules/shortcut/config.cljs

@@ -331,6 +331,9 @@
                                     :fn      editor-handler/zoom-out!}
 
    :editor/toggle-undo-redo-mode   {:fn      undo-redo/toggle-undo-redo-mode!}
+   
+   :editor/toggle-number-list      {:binding "t n"
+                                    :fn #(state/pub-event! [:editor/toggle-own-number-list (state/get-selection-block-ids)])}
 
    :ui/toggle-brackets             {:binding "mod+c mod+b"
                                     :fn      config-handler/toggle-ui-show-brackets!}
@@ -688,6 +691,7 @@
                           :editor/zoom-in
                           :editor/zoom-out
                           :editor/toggle-undo-redo-mode
+                          :editor/toggle-number-list
                           :editor/undo
                           :editor/redo
                           :ui/toggle-brackets
@@ -847,6 +851,7 @@
    [:ui/toggle-help
     :editor/toggle-open-blocks
     :editor/toggle-undo-redo-mode
+    :editor/toggle-number-list
     :ui/toggle-wide-mode
     :ui/toggle-cards
     :ui/toggle-document-mode

+ 1 - 0
src/main/frontend/modules/shortcut/dicts.cljc

@@ -79,6 +79,7 @@
    :editor/zoom-in                 "Zoom in editing block / Forwards otherwise"
    :editor/zoom-out                "Zoom out editing block / Backwards otherwise"
    :editor/toggle-undo-redo-mode   "Toggle undo redo mode (global or page only)"
+   :editor/toggle-number-list      "Toggle number list"
    :whiteboard/select              "Select tool"
    :whiteboard/pan                 "Pan tool"
    :whiteboard/portal              "Portal tool"

+ 2 - 0
src/main/frontend/util.cljc

@@ -58,6 +58,8 @@
                (gdom/getElementByClass "sidebar-item-list")
                (app-scroll-container-node))))))
 #?(:cljs (defonce el-visible-in-viewport? utils/elementIsVisibleInViewport))
+#?(:cljs (defonce convert-to-roman utils/convertToRoman))
+#?(:cljs (defonce convert-to-letters utils/convertToLetters))
 
 (defn string-join-path
   "Replace all `strings/join` used to construct paths with this function to reduce lint output.

+ 1 - 1
src/main/frontend/util/thingatpt.cljs

@@ -177,7 +177,7 @@
    :block-ref?       true
    :page-ref?        true
    :properties?      true
-   :list?            true})
+   :list?            false})
 
 (defn get-setting [setting]
   (let [value (get-in (state/get-config) [:dwim/settings setting])]

+ 25 - 1
src/main/frontend/utils.js

@@ -406,4 +406,28 @@ export const elementIsVisibleInViewport = (el, partiallyVisible = false) => {
       (bottom > 0 && bottom < innerHeight)) &&
     ((left > 0 && left < innerWidth) || (right > 0 && right < innerWidth))
     : top >= 0 && left >= 0 && bottom <= innerHeight && right <= innerWidth
-}
+}
+
+export const convertToLetters = (num) => {
+  if (!+num) return false
+  let s = '', t
+
+  while (num > 0) {
+    t = (num - 1) % 26
+    s = String.fromCharCode(65 + t) + s
+    num = ((num - t) / 26) | 0
+  }
+
+  return s
+}
+
+export const convertToRoman = (num) => {
+  if (!+num) return false
+  const digits = String(+num).split('')
+  const key = ['','C','CC','CCC','CD','D','DC','DCC','DCCC','CM',
+    '','X','XX','XXX','XL','L','LX','LXX','LXXX','XC',
+    '','I','II','III','IV','V','VI','VII','VIII','IX']
+  let roman = '', i = 3
+  while (i--) roman = (key[+digits.pop() + i * 10] || '') + roman
+  return Array(+digits.join('') + 1).join('M') + roman
+}

+ 6 - 5
src/main/logseq/api.cljs

@@ -21,6 +21,7 @@
             [frontend.fs :as fs]
             [frontend.handler.dnd :as editor-dnd-handler]
             [frontend.handler.editor :as editor-handler]
+            [frontend.handler.editor.property :as editor-property]
             [frontend.handler.export :as export-handler]
             [frontend.handler.page :as page-handler]
             [frontend.handler.plugin :as plugin-handler]
@@ -733,11 +734,11 @@
 
 (def ^:export upsert_block_property
   (fn [block-uuid key value]
-    (editor-handler/set-block-property! (sdk-utils/uuid-or-throw-error block-uuid) key value)))
+    (editor-property/set-block-property! (sdk-utils/uuid-or-throw-error block-uuid) key value)))
 
 (def ^:export remove_block_property
   (fn [block-uuid key]
-    (editor-handler/remove-block-property! (sdk-utils/uuid-or-throw-error block-uuid) key)))
+    (editor-property/remove-block-property! (sdk-utils/uuid-or-throw-error block-uuid) key)))
 
 (def ^:export get_block_property
   (fn [block-uuid key]
@@ -986,14 +987,14 @@
           exist? (page-handler/template-exists? template-name)]
       (if (or (not exist?) (true? overwrite))
         (do (when-let [old-target (and exist? (db-model/get-template-by-name template-name))]
-              (editor-handler/remove-block-property! (:block/uuid old-target) :template))
-            (editor-handler/set-block-property! target-uuid :template template-name))
+              (editor-property/remove-block-property! (:block/uuid old-target) :template))
+            (editor-property/set-block-property! target-uuid :template template-name))
         (throw (js/Error. "Template already exists!"))))))
 
 (defn ^:export remove_template
   [name]
   (when-let [target (db-model/get-template-by-name name)]
-    (editor-handler/remove-block-property! (:block/uuid target) :template)))
+    (editor-property/remove-block-property! (:block/uuid target) :template)))
 
 ;; search
 (defn ^:export search