| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153 |
- (ns frontend.components.db-based.page
- "Page components only for DB graphs"
- (:require [frontend.components.block :as component-block]
- [frontend.components.editor :as editor]
- [frontend.components.class :as class-component]
- [frontend.components.property :as property-component]
- [frontend.config :as config]
- [frontend.db :as db]
- [logseq.outliner.property :as outliner-property]
- [frontend.ui :as ui]
- [frontend.state :as state]
- [rum.core :as rum]
- [logseq.shui.ui :as shui]
- [frontend.util :as util]
- [clojure.set :as set]
- [clojure.string :as string]
- [logseq.db.frontend.property :as db-property]))
- (rum/defc page-properties
- "This component is called by page-inner and within configure/info modal. This should not
- be displaying properties from both components at the same time"
- < rum/reactive
- [page {:keys [mode configure?]}]
- (let [edit-input-id-prefix (str "edit-block-" (:block/uuid page))
- configure-opts {:selected? false
- :page-configure? configure?}
- has-viewable-properties? (outliner-property/block-has-viewable-properties? page)
- hide-properties? (db-property/property-value-content (:logseq.property/hide-properties? page))]
- (when (or configure? (and (not hide-properties?) has-viewable-properties?))
- [:div.ls-page-properties
- {:class (util/classnames [{:no-properties (not has-viewable-properties?)}])}
- (if configure?
- (cond
- (= mode :class)
- (component-block/db-properties-cp {:editor-box editor/box}
- page
- (str edit-input-id-prefix "-schema")
- (assoc configure-opts :class-schema? true))
- (= mode :page)
- (component-block/db-properties-cp {:editor-box editor/box}
- page
- (str edit-input-id-prefix "-page")
- (assoc configure-opts :class-schema? false :page? true)))
- ;; default view for page-inner
- (component-block/db-properties-cp {:editor-box editor/box}
- page
- (str edit-input-id-prefix "-page")
- (assoc configure-opts :class-schema? false :page? true)))])))
- (rum/defcs page-configure < rum/reactive
- [state page *mode]
- (let [*mode *mode
- mode (rum/react *mode)
- type (:block/type page)
- class? (= type "class")
- property? (= type "property")
- page-opts {:configure? true}]
- (when (nil? mode)
- (reset! *mode (cond
- class? :class
- property? :property
- :else :page)))
- [:div.flex.flex-col.gap-1.pb-4
- (case mode
- :property
- (property-component/property-config page {:inline-text component-block/inline-text})
- :class
- [:div.mt-2.flex.flex-col.gap-2
- (class-component/configure page {:show-title? false})
- (page-properties page (assoc page-opts :mode mode))]
- (page-properties page (assoc page-opts :mode mode)))]))
- (rum/defc mode-switch < rum/reactive
- [type *mode]
- (let [current-mode (rum/react *mode)
- class? (= type "class")
- property? (= type "property")
- modes (->
- (cond
- property?
- ["Property"]
- class?
- ["Class"]
- :else
- [])
- (conj "Page"))]
- [:div.flex.flex-row.items-center.gap-1
- (for [mode modes]
- (let [mode' (keyword (string/lower-case mode))
- selected? (and (= mode' current-mode) (> (count modes) 1))]
- (shui/button {:class (when-not selected? "opacity-70")
- :variant (if selected? :outline :ghost)
- :size :sm
- :on-click (fn [e]
- (util/stop-propagation e)
- (reset! *mode mode'))}
- mode)))]))
- (rum/defcs page-info < rum/reactive
- (rum/local false ::hover?)
- (rum/local nil ::mode)
- [state page *show-info?]
- (let [page (db/sub-block (:db/id page))
- *hover? (::hover? state)
- *mode (::mode state)
- type (:block/type page)
- class? (= type "class")
- collapsed? (not @*show-info?)
- has-properties? (or
- (seq (:block/tags page))
- (seq (:block/alias page))
- (seq (remove (set (keys db-property/built-in-properties))
- (keys (:block/properties page)))))
- show-info? (or @*show-info? has-properties?)]
- (when (if config/publishing?
- ;; Since publishing is read-only, hide this component if it has no info to show
- ;; as it creates a fair amount of empty vertical space
- (some? type)
- show-info?)
- [:div.page-info
- {:class (util/classnames [{:is-collapsed collapsed?}])}
- [:div {:class (if (or @*hover? (not collapsed?))
- "border rounded"
- "border rounded border-transparent")}
- (when-not collapsed?
- [:div.info-title.cursor.p-1
- {:on-mouse-over #(reset! *hover? true)
- :on-mouse-leave #(when-not (state/dropdown-opened?)
- (reset! *hover? false))
- :on-click (if config/publishing?
- (fn [_]
- (when (contains? #{"class" "property"} type)
- (swap! *show-info? not)))
- #(do
- (swap! *show-info? not)
- (swap! *hover? not)))}
- [:<>
- [:div.flex.flex-row.items-center.gap-1
- (mode-switch type *mode)]
- [:div.absolute.right-1.top-1
- (shui/button
- {:variant :ghost :size :sm
- :class "px-1 py-1 h-6 w-6"}
- (ui/icon "x"))]]])
- (if collapsed?
- (when (or (seq (:block/properties page))
- (and class? (seq (:class/schema.properties page))))
- (page-properties page {:mode @*mode}))
- [:div.px-3
- (page-configure page *mode)])]])))
|