Skip to content

Commit

Permalink
enhance(ux): WIP functionality for the dropdown property editor
Browse files Browse the repository at this point in the history
  • Loading branch information
xyhp915 committed Aug 21, 2024
1 parent 75c8f1b commit 8f371a1
Show file tree
Hide file tree
Showing 3 changed files with 139 additions and 36 deletions.
4 changes: 2 additions & 2 deletions src/main/frontend/components/icon.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -417,7 +417,7 @@
(:native (first (:skins @*hover))))]])]]))

(rum/defc icon-picker
[icon-value {:keys [disabled? on-chosen icon-props popup-opts]}]
[icon-value {:keys [empty-label disabled? on-chosen icon-props popup-opts]}]
(let [content-fn
(if config/publishing?
(constantly [])
Expand All @@ -443,4 +443,4 @@
(if has-icon?
[:span {:style {:color (or (:color icon-value) "inherit")}}
(icon icon-value (merge {:size 18} icon-props))]
"Empty")))))
(or empty-label "Empty"))))))
7 changes: 4 additions & 3 deletions src/main/frontend/components/property.css
Original file line number Diff line number Diff line change
Expand Up @@ -334,14 +334,15 @@ a.control-link {
}
}

.ls-property-name-edit-pane {
.ls-property-name-edit-pane,
.ls-base-edit-form {
@apply px-2 pt-2 pb-1;

> .input-wrap {
@apply gap-1.5;

> .ui__button:first-child {
@apply border;
@apply px-0 py-0 !w-9 border overflow-hidden;

> span {
@apply flex items-center;
Expand Down Expand Up @@ -373,7 +374,7 @@ a.control-link {
}

> .ui__button {
@apply px-1.5;
@apply !p-0 !w-7 !h-7 overflow-hidden;
}

> a.del {
Expand Down
164 changes: 133 additions & 31 deletions src/main/frontend/components/property_v2.cljs
Original file line number Diff line number Diff line change
@@ -1,42 +1,97 @@
(ns frontend.components.property-v2
(:require [frontend.components.icon :as icon-component]
(:require [clojure.string :as string]
[frontend.components.icon :as icon-component]
[frontend.handler.db-based.property :as db-property-handler]
[frontend.db :as db]
[frontend.handler.property :as property-handler]
[frontend.handler.route :as route-handler]
[frontend.state :as state]
[frontend.util :as util]
[logseq.db.frontend.property :as db-property]
[logseq.db.frontend.property.type :as db-property-type]
[logseq.shui.ui :as shui]
[logseq.shui.popup.core :as shui-popup]
[promesa.core :as p]
[goog.dom :as gdom]
[rum.core :as rum]))

(defn- re-init-commands!
"Update commands after task status and priority's closed values has been changed"
[property]
(when (contains? #{:logseq.task/status :logseq.task/priority} (:db/ident property))
(state/pub-event! [:init/commands])))

(defn- <upsert-closed-value!
"Create new closed value and returns its block UUID."
[property item]
(p/do!
(db-property-handler/upsert-closed-value! (:db/ident property) item)
(re-init-commands! property)))


(rum/defc name-edit-pane
[property]
(let [title (:block/title property)
icon (:logseq.property/icon property)
*input-ref (rum/use-ref nil)]

(rum/use-effect!
(fn []
(js/console.log "==>>>> name editor SET-UP!", property)
#(js/console.log "==>>>> name editor BYE!"))
[])

[:div.ls-property-name-edit-pane
[:div.flex.items-center.input-wrap
(icon-component/icon-picker icon {:on-chosen (fn [_e icon]
(db-property-handler/upsert-property!
(:db/ident property)
(:block/schema property)
{:properties {:logseq.property/icon icon}}))
:popup-opts {:align "start"}})
:popup-opts {:align "start"}
:empty-label "?"})

(shui/input {:ref *input-ref :size "sm" :default-value title})]
[:div.pt-2 (shui/textarea {:placeholder "description"})]
[:div.pt-2.flex.justify-end
(shui/button {:size "sm" :disabled true
:variant :secondary} "Save")]]))

(rum/defc base-edit-form
[own-property block]
(let [create? (:create? block)
*form-data (rum/use-ref
{:value (or (:block/title block) "")
:icon (:logseq.property/icon block)
:description ""})
[form-data, set-form-data!] (rum/use-state (rum/deref *form-data))
*input-ref (rum/use-ref nil)]

(rum/use-effect!
(fn []
(when create?
(js/setTimeout #(some-> (rum/deref *input-ref) (.focus)) 60)))
[])

[:div.ls-base-edit-form
[:div.flex.items-center.input-wrap
(icon-component/icon-picker
(:icon form-data)
{:on-chosen (fn [_e icon] (set-form-data! (assoc form-data :icon icon)))
:empty-label "?"
:popup-opts {:align "start"}})

(shui/input {:ref *input-ref :size "sm"
:default-value (:value form-data)
:on-change (fn [^js e] (set-form-data! (assoc form-data :value (util/trim-safe (util/evalue e)))))
:placeholder "title"})]
[:div.pt-2 (shui/textarea
{:placeholder "description" :default-value (:description form-data)
:on-change (fn [^js e] (set-form-data! (assoc form-data :description (util/trim-safe (util/evalue e)))))})]
[:div.pt-2.flex.justify-end
(let [dirty? (not= (rum/deref *form-data) form-data)]
(shui/button {:size "sm"
:disabled (not dirty?)
:on-click (fn []
(-> (<upsert-closed-value! own-property form-data)
(p/then #(shui/popup-hide!))
(p/catch #(shui/toast! (str %) :error))))
:variant (if dirty? :default :secondary)}
"Save"))]]))

(defn restore-root-highlight-item!
[id]
(js/setTimeout
Expand All @@ -50,7 +105,8 @@
id1 (str (or id icon (random-uuid)))
id2 (str "d2-" id1)
or-close-menu-sub! (fn []
(when-not (shui-popup/get-popup :ls-icon-picker)
(when (and (not (shui-popup/get-popup :ls-icon-picker))
(not (shui-popup/get-popup :ls-base-edit-form)))
(set-sub-open! false)
(restore-root-highlight-item! id1)))
wrap-menuitem (if submenu-content
Expand Down Expand Up @@ -85,28 +141,58 @@
[:small [:span desc]
(when disabled? (shui/tabler-icon "forbid-2" {:size 15}))]))])))

(rum/defc choices-sub-pane
[_property]
(rum/defc choice-item-content
[property block]
(let [{:block/keys [uuid]} block
delete-choice! (fn []
(p/do!
(db-property-handler/delete-closed-value! (:db/id property) (:db/id block))
(re-init-commands! property)))
update-icon! (fn [icon]
(property-handler/set-block-property!
(state/get-current-repo) (:block/uuid block) :logseq.property/icon
(select-keys icon [:id :type :color])))
icon (:logseq.property/icon block)
value (db-property/closed-value-content block)
property-block? (db-property/property-created-block? block)
page? (db/page? block)]

[:div.ls-property-dropdown-editor.ls-property-choices-sub-pane
[:ul.choices-list
[:li
(shui/tabler-icon "grip-vertical" {:size 14})
(shui/button {:size "sm" :variant :outline} "🔥")
[:strong "fireworks"]
[:a.del (shui/tabler-icon "x" {:size 14})]]
(shui/button {:size "sm" :variant :outline}
(icon-component/icon-picker icon {:on-chosen (fn [_e icon] (update-icon! icon))
:popup-opts {:align "start"}
:empty-label "?"}))
[:strong value]
[:a.del {:on-click delete-choice!
:title "Delete this choice"}
(shui/tabler-icon "x" {:size 14})]]))

[:li
(shui/tabler-icon "grip-vertical" {:size 14})
(shui/button {:size "sm" :variant :outline} "🍄")
[:strong "mushroom"]
[:a.del (shui/tabler-icon "x" {:size 14})]]
]
(rum/defc choices-sub-pane
[property]
(let [values (:property/closed-values property)
choices (doall
(keep (fn [value]
(when-let [block (db/sub-block (:db/id value))]
(let [id (:block/uuid block)]
{:id (str id)
:value id
:content (choice-item-content property block)})))
values))]
[:div.ls-property-dropdown-editor.ls-property-choices-sub-pane
[:ul.choices-list
(for [c choices]
(:content c))]

;; add choice
(dropdown-editor-menuitem
{:icon :plus :title "Add choice"
:item-props {:on-select (fn [] (shui/toast! "+ add choice" :success))}})])
;; add choice
(dropdown-editor-menuitem
{:icon :plus :title "Add choice"
:item-props {:on-click (fn [^js e]
(shui/popup-show! (.-target e)
;; TODO: add existing values
(base-edit-form property {:create? true})
{:id :ls-base-edit-form
:align "start"}))}})]))

(rum/defc ui-position-sub-pane
[_property {:keys [id set-sub-open!]}]
Expand All @@ -121,21 +207,37 @@
(dropdown-editor-menuitem {:icon :layout-align-left :title "End of the block" :item-props item-props})
(dropdown-editor-menuitem {:icon :layout-align-top :title "Below of the block" :item-props item-props})]))

(defn- property-type-label
[property-type]
(case property-type
:default
"Text"
((comp string/capitalize name) property-type)))

(rum/defc dropdown-editor-impl
"popup-id: dropdown popup id
property: block entity"
[_popup-id property]
(let [title (:block/title property)
property-type (get-in property [:block/schema :type])
property-type-label (some-> property-type (property-type-label))
enable-closed-values? (contains? db-property-type/closed-value-property-types
(or property-type :default))
icon (:logseq.property/icon property)
icon (when icon [:span.float-left.w-4.h-4.overflow-hidden.leading-4.relative
{:class "top-0.5 -right-0.5"}
{:class "top-[1px]"}
(icon-component/icon icon {:size 15})])]
[:<>
(dropdown-editor-menuitem {:icon :edit :title "Property name" :desc [:span.flex.items-center.gap-1 icon title]
:submenu-content (fn [] (name-edit-pane property))})
(dropdown-editor-menuitem {:icon :hash :title "Schema type" :desc "Date" :disabled? true})
(dropdown-editor-menuitem {:icon :list :title "Available choices" :desc "4 choices"
:submenu-content (fn [] (choices-sub-pane property))})
(dropdown-editor-menuitem {:icon :hash :title "Schema type" :desc (str property-type-label) :disabled? true})

(when enable-closed-values? (empty? (:property/schema.classes property))
(let [values (:property/closed-values property)]
(dropdown-editor-menuitem {:icon :list :title "Available choices"
:desc (when (seq values) (str (count values) " choices"))
:submenu-content (fn [] (choices-sub-pane property))})))

(dropdown-editor-menuitem {:icon :checks :title "Multiple values" :toggle-checked? true :disabled? true
:on-toggle-checked-change (fn [v] (shui/toast! (str title ": " v)))})

Expand Down

0 comments on commit 8f371a1

Please sign in to comment.