developer.cljs 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. (ns frontend.handler.common.developer
  2. "Common fns for developer related functionality"
  3. (:require [cljs.pprint :as pprint]
  4. [clojure.edn :as edn]
  5. [datascript.impl.entity :as de]
  6. [frontend.config :as config]
  7. [frontend.db :as db]
  8. [frontend.format.mldoc :as mldoc]
  9. [frontend.handler.notification :as notification]
  10. [frontend.handler.ui :as ui-handler]
  11. [frontend.persist-db :as persist-db]
  12. [frontend.state :as state]
  13. [frontend.ui :as ui]
  14. [frontend.util :as util]
  15. [frontend.util.page :as page-util]
  16. [logseq.db.frontend.property :as db-property]
  17. [logseq.db.sqlite.export :as sqlite-export]
  18. [logseq.shui.ui :as shui]
  19. [promesa.core :as p]))
  20. ;; Fns used between menus and commands
  21. (defn show-entity-data
  22. [eid]
  23. (let [result* (db/pull eid)
  24. entity (db/entity eid)
  25. result (cond-> result*
  26. (and (seq (:block/properties entity)) (config/db-based-graph? (state/get-current-repo)))
  27. (assoc :block.debug/properties
  28. (->> (:block/properties entity)
  29. (map (fn [[k v]]
  30. [k
  31. (cond
  32. (de/entity? v)
  33. (db-property/property-value-content v)
  34. (and (set? v) (every? de/entity? v))
  35. (set (map db-property/property-value-content v))
  36. :else
  37. v)]))
  38. (into {})))
  39. (seq (:block/refs result*))
  40. (assoc :block.debug/refs
  41. (mapv #(or (:block/title (db/entity (:db/id %))) %) (:block/refs result*))))
  42. pull-data (with-out-str (pprint/pprint result))]
  43. (println pull-data)
  44. (notification/show!
  45. [:div.ls-wrap-widen
  46. [:pre.code pull-data]
  47. [:br]
  48. (ui/button "Copy to clipboard"
  49. :on-click #(.writeText js/navigator.clipboard pull-data))]
  50. :success
  51. false)))
  52. (defn show-content-ast
  53. [content format]
  54. (let [ast-data (-> (mldoc/->edn content format)
  55. pprint/pprint
  56. with-out-str)]
  57. (println ast-data)
  58. (notification/show!
  59. [:div.ls-wrap-widen
  60. ;; Show clipboard at top since content is really long for pages
  61. (ui/button "Copy to clipboard"
  62. :on-click #(.writeText js/navigator.clipboard ast-data))
  63. [:br]
  64. [:pre.code ast-data]]
  65. :success
  66. false)))
  67. (defn- import-submit [import-inputs _e]
  68. (let [export-map (try (edn/read-string (:import-data @import-inputs)) (catch :default _err ::invalid-import))
  69. import-block? (:build/block export-map)
  70. block (when import-block?
  71. (if-let [eid (:block-id (first (state/get-editor-args)))]
  72. (db/entity [:block/uuid eid])
  73. (notification/show! "No block found" :warning)))]
  74. (if (= ::invalid-import export-map)
  75. (notification/show! "The submitted EDN data is invalid! Fix and try again." :warning)
  76. (let [{:keys [init-tx block-props-tx error] :as txs}
  77. (sqlite-export/build-import (db/get-db)
  78. (when block {:current-block block})
  79. export-map)]
  80. (pprint/pprint txs)
  81. (if error
  82. (notification/show! error :error)
  83. (p/do
  84. ;; TODO: Use metadata that supports undo
  85. (db/transact! (state/get-current-repo) init-tx
  86. (if import-block? {:save-block true} {::sqlite-export/imported-data? true}))
  87. (when (seq block-props-tx)
  88. (db/transact! (state/get-current-repo) block-props-tx
  89. (if import-block? {:save-block true} {::sqlite-export/imported-data? true})))
  90. (when-not import-block?
  91. (state/clear-async-query-state!)
  92. (ui-handler/re-render-root!)
  93. (notification/show! "Import successful!" :success))))
  94. ;; Also close cmd-k
  95. (shui/dialog-close-all!)))))
  96. ;; Public Commands
  97. (defn ^:export show-block-data []
  98. ;; Use editor state to locate most recent block
  99. (if-let [block-uuid (:block-id (first (state/get-editor-args)))]
  100. (show-entity-data [:block/uuid block-uuid])
  101. (notification/show! "No block found" :warning)))
  102. (defn ^:export show-block-ast []
  103. (if-let [{:block/keys [title format]} (:block (first (state/get-editor-args)))]
  104. (show-content-ast title (or format :markdown))
  105. (notification/show! "No block found" :warning)))
  106. (defn ^:export show-page-data []
  107. (if-let [page-id (page-util/get-current-page-id)]
  108. (show-entity-data page-id)
  109. (notification/show! "No page found" :warning)))
  110. (defn ^:export show-page-ast []
  111. (if (config/db-based-graph? (state/get-current-repo))
  112. (notification/show! "Command not available yet for DB graphs" :warning)
  113. (let [page-data (db/pull '[:block/format {:block/file [:file/content]}]
  114. (page-util/get-current-page-id))]
  115. (if (get-in page-data [:block/file :file/content])
  116. (show-content-ast (get-in page-data [:block/file :file/content])
  117. (get page-data :block/format :markdown))
  118. (notification/show! "No page found" :warning)))))
  119. (defn ^:export export-block-data []
  120. ;; Use editor state to locate most recent block
  121. (if-let [block-uuid (:block-id (first (state/get-editor-args)))]
  122. (let [result (sqlite-export/build-block-export (db/get-db) [:block/uuid block-uuid])
  123. pull-data (with-out-str (pprint/pprint result))]
  124. (.writeText js/navigator.clipboard pull-data)
  125. (println pull-data)
  126. (notification/show! "Copied block's data!" :success))
  127. (notification/show! "No block found" :warning)))
  128. (defn ^:export export-page-data []
  129. (if-let [page-id (page-util/get-current-page-id)]
  130. (let [result (sqlite-export/build-page-export (db/get-db) page-id)
  131. pull-data (with-out-str (pprint/pprint result))]
  132. (.writeText js/navigator.clipboard pull-data)
  133. (println pull-data)
  134. (notification/show! "Copied page's data!" :success))
  135. (notification/show! "No page found" :warning)))
  136. (defn ^:export export-graph-ontology-data []
  137. (let [result (sqlite-export/build-graph-ontology-export (db/get-db))
  138. pull-data (with-out-str (pprint/pprint result))]
  139. (.writeText js/navigator.clipboard pull-data)
  140. (println pull-data)
  141. (js/console.log (str "Exported " (count (:classes result)) " classes and "
  142. (count (:properties result)) " properties"))
  143. (notification/show! "Copied graphs's ontology data!" :success)))
  144. (defn ^:export import-edn-data
  145. []
  146. (let [import-inputs (atom {:import-data "" :import-block? false})]
  147. (shui/dialog-open!
  148. [:div
  149. [:label.flex.my-2.text-lg "Import EDN Data"]
  150. #_[:label.block.flex.items-center.py-3
  151. (shui/checkbox {:on-checked-change #(swap! import-inputs update :import-block? not)})
  152. [:small.pl-2 (str "Import into current block")]]
  153. (shui/textarea {:placeholder "{}"
  154. :class "overflow-y-auto"
  155. :rows 10
  156. :auto-focus true
  157. :on-change (fn [^js e] (swap! import-inputs assoc :import-data (util/evalue e)))})
  158. (shui/button {:class "mt-3"
  159. :on-click (partial import-submit import-inputs)}
  160. "Import")])))
  161. (defn ^:export validate-db []
  162. (when-let [^Object worker @state/*db-worker]
  163. (.validate-db worker (state/get-current-repo))))
  164. (defn import-chosen-graph
  165. [repo]
  166. (p/let [_ (persist-db/<unsafe-delete repo)]
  167. (notification/show! (str "Graph updated! Switching to graph ...") :success)
  168. (state/pub-event! [:graph/switch repo])))
  169. (defn ^:export replace-graph-with-db-file []
  170. (state/pub-event! [:dialog-select/db-graph-replace]))