fix: property date type UX

This commit is contained in:
Tienson Qin
2023-07-03 17:53:23 +08:00
parent b9a4031bb5
commit cc769225f9
5 changed files with 127 additions and 92 deletions

View File

@@ -16,7 +16,9 @@
[frontend.components.search.highlight :as highlight]
[frontend.components.svg :as svg]
[frontend.modules.shortcut.core :as shortcut]
[medley.core :as medley]))
[medley.core :as medley]
[cljs-time.coerce :as tc]
[frontend.date :as date]))
(rum/defcs property-config <
rum/static
@@ -86,21 +88,67 @@
(defn- exit-edit-property
[*property-key *property-value]
(reset! *property-key nil)
(reset! *property-value nil)
(when *property-key (reset! *property-key nil))
(when *property-value (reset! *property-value nil))
(property-handler/set-editing-new-property! nil))
(defn- add-property!
[block *property-key *property-value]
(let [repo (state/get-current-repo)]
(when (and @*property-key @*property-value)
(when @*property-key
(property-handler/add-property! repo block @*property-key @*property-value))
(exit-edit-property *property-key *property-value)))
(rum/defcs property-key-input < rum/reactive
(rum/defc date-picker
[block property value]
(let [value' (when-not (string/blank? value)
(tc/to-local-date value))
text (if value'
(str value')
"Pick a date")]
(ui/button
text
:icon "calendar"
:intent "border-link"
:on-click (fn []
(state/set-modal!
#(ui/datepicker value' {:on-change (fn [_e date]
(let [repo (state/get-current-repo)]
(property-handler/add-property! repo block
(:block/name property)
date)
(exit-edit-property nil nil)
(state/close-modal!)))}))))))
(rum/defc property-scalar-value
[block property value {:keys [editor-on-click inline-text]}]
(let [property (when property
(if (map? property)
property
(db/entity [:block/name (util/page-name-sanity-lc property)])))]
(case (:type (:block/schema property))
:date
(date-picker block property value)
:checkbox
(ui/checkbox {:checked value
:on-change (fn [_e]
(let [repo (state/get-current-repo)]
(property-handler/add-property! repo block
(:block/name property)
(boolean (not value)))
(exit-edit-property nil nil)))})
;; :object
;; default and others
[:div.flex.flex-1
(when editor-on-click {:on-click editor-on-click})
(when-not (string/blank? (str value))
(inline-text {} :markdown (str value)))])))
(rum/defcs property-input < rum/reactive
(rum/local true ::search?)
shortcut/disable-all-shortcuts
[state entity *property-key *property-value]
[state entity *property-key *property-value block-components-m]
(let [*search? (::search? state)
entity-properties (->> (keys (:block/properties entity))
(map #(:block/original-name (db/entity [:block/uuid %])))
@@ -124,23 +172,27 @@
(list "Tab" "Enter")
(do
(util/stop e)
(when (= (util/ekey e) "Tab")
(util/stop e))
(reset! *property-key (util/evalue e))
(reset! *search? false)
(.focus (js/document.getElementById "add-property-value")))
nil))}]
[:input#add-property-value.form-input.simple-input.block.col-span-1.focus:outline-none
{:placeholder "Value"
:on-change #(reset! *property-value (util/evalue %))
:on-key-down (fn [e]
(case (util/ekey e)
"Enter"
(do
(add-property! entity *property-key *property-value)
(reset! *search? false))
(property-scalar-value entity @*property-key @*property-value {:editor-on-click (fn [e]
(case (util/ekey e)
"Enter"
(do
(add-property! entity *property-key *property-value)
(reset! *search? false))
nil))}]
nil))
:inline-text (:inline-text block-components-m)})
;; [:input#add-property-value.form-input.simple-input.block.col-span-1.focus:outline-none
;; {:placeholder "Value"
;; :on-change #(reset! *property-value (util/evalue %))
;; :on-key-down }]
[:a.close {:on-mouse-down #(exit-edit-property *property-key *property-value)}
svg/close]]
@@ -163,14 +215,15 @@
state
:on-hide (fn []
(property-handler/set-editing-new-property! nil))
:node (js/document.getElementById "edit-new-property"))))
[state repo block edit-input-id properties new-property?]
:node (js/document.getElementById "edit-new-property")
:outside? false)))
[state repo block edit-input-id properties new-property? block-components-m]
(let [*property-key (::property-key state)
*property-value (::property-value state)]
(cond
new-property?
[:div#edit-new-property
(property-key-input block *property-key *property-value)]
(property-input block *property-key *property-value block-components-m)]
(seq properties)
[:a {:title "Add another property"
@@ -180,8 +233,7 @@
(reset! *property-value nil))}
[:div.block {:style {:height 20
:width 20}}
[:a.add-button-link.block {:title "Add another value"
:style {:margin-left -4}}
[:a.add-button-link.block {:style {:margin-left -4}}
(ui/icon "circle-plus")]]])))
(rum/defcs property-key < (rum/local false ::show-close?)
@@ -203,28 +255,6 @@
(property-handler/remove-property! repo block (:block/uuid property)))}
(ui/icon "x")]])]))
(rum/defc property-scalar-value
[block property value {:keys [editor-on-click inline-text]}]
(case (:type (:block/schema property))
:date
(ui/button
(or value "Empty")
:icon :calendar)
:checkbox
(ui/checkbox {:checked value
:on-change (fn [_e]
(let [repo (state/get-current-repo)]
(property-handler/add-property! repo block
(:block/name property)
(boolean (not value)))))})
;; :object
;; default and others
[:div.flex.flex-1
(when editor-on-click {:on-click editor-on-click})
(when-not (string/blank? (str value))
(inline-text {} :markdown (str value)))]))
(rum/defcs multiple-value-item < (rum/local false ::show-close?)
[state entity property item dom-id' editor-id' {:keys [edit-fn page-cp inline-text]}]
(let [*show-close? (::show-close? state)
@@ -232,15 +262,8 @@
block (when object? (db/pull [:block/uuid item]))]
[:div.flex.flex-1.flex-row {:on-mouse-over #(reset! *show-close? true)
:on-mouse-out #(reset! *show-close? false)}
[:div.flex.flex-1.property-value-content
{:id dom-id'
:on-click (fn []
;; (edit-fn editor-id' dom-id' item)
)}
(if block
;; TODO: page/block
(str block)
(inline-text {} :markdown (str item)))]
(property-scalar-value entity property item {:editor-on-click edit-fn
:inline-text inline-text})
(when @*show-close?
[:a.close.fade-in
{:title "Delete this value"
@@ -278,7 +301,7 @@
v' (if (seq v') v' [""])
editor-id' (str editor-id (count v'))
new-editing? (state/sub [:editor/editing? editor-id'])]
[:div.flex.flex-1.flex-col
[:div.flex.flex-1.flex-col.pl-1
[:div.flex.flex-1.flex-col
(for [[idx item] (medley/indexed v')]
(let [dom-id' (str dom-id "-" idx)
@@ -302,7 +325,7 @@
[:div.block {:style {:height 20
:width 20}}
[:a.add-button-link.block {:title "Add another value"
:style {:margin-left -4}}
:style {:margin-left -8}}
(ui/icon "circle-plus")]]]]))]
(when new-editing?
(editor-box editor-args editor-id' {}))])
@@ -328,7 +351,7 @@
(for [[prop-uuid-or-built-in-prop v] properties]
(if (uuid? prop-uuid-or-built-in-prop)
(when-let [property (db/sub-block (:db/id (db/entity [:block/uuid prop-uuid-or-built-in-prop])))]
[:div.grid.grid-cols-4.gap-1
[:div.grid.grid-cols-4.gap-1.items-center
[:div.property-key.col-span-1
(property-key block property)]
[:div.property-value.col-span-3
@@ -338,4 +361,4 @@
[:div
[:a.mr-2 (str prop-uuid-or-built-in-prop)]
[:span v]]))])
(new-property repo block edit-input-id properties new-property?)])))
(new-property repo block edit-input-id properties new-property? block-components-m)])))

View File

@@ -1160,7 +1160,7 @@ independent of format as format specific heading characters are stripped"
[(get m :template) e]))
(into {}))))
(defn get-all-properties
(defn file-based-get-all-properties
[]
(let [db (conn/get-db)
properties (d/q
@@ -1172,12 +1172,21 @@ independent of format as format specific heading characters are stripped"
(->> (map keys properties)
(apply concat)
distinct
(map (fn [k]
(if (uuid? k)
(:block/original-name (d/entity db [:block/uuid k]))
k)))
sort)))
(defn db-based-get-all-properties
[]
(let [db (conn/get-db)
ids (->> (d/datoms db :aevt :block/schema)
(map :e))]
(map #(:block/original-name (db-utils/entity %)) ids)))
(defn get-all-properties
[]
(if (react/db-graph?)
(db-based-get-all-properties)
(file-based-get-all-properties)))
(defn- property-value-for-refs-and-text
"Given a property value's refs and full text, determines the value to
autocomplete"

View File

@@ -371,8 +371,7 @@
(recur))
chan))
(comment
(defn db-graph?
"Whether the current graph is db-only"
[]
(= "db" (sub-key-value :db/type))))
(defn db-graph?
"Whether the current graph is db-only"
[]
(= "db" (sub-key-value :db/type)))

View File

@@ -27,7 +27,9 @@
(def builtin-schema-types
{:default string? ; default, might be mixed with refs, tags
:number number?
:date inst?
:date [:fn
{:error/message "should be a date"}
date-str?]
:checkbox boolean?
:url [:fn
{:error/message "should be a URL"}
@@ -70,7 +72,8 @@
(defn convert-property-input-string
[schema-type v-str]
(if (string? v-str)
(if (boolean? v-str)
v-str
(case schema-type
:default
v-str
@@ -85,34 +88,32 @@
(uuid v-str)
:date
(js/Date. v-str)
(js/Date. v-str) ; inst
:url
v-str)
v-str))
v-str)))
(defn add-property!
[repo block k-name v]
(prn :debug " add-property! " {:k k-name
:v v})
(let [property (db/pull repo '[*] [:block/name (gp-util/page-name-sanity-lc k-name)])
property-uuid (or (:block/uuid property) (random-uuid))
{:keys [type cardinality]} (:block/schema property)
multiple-values? (= cardinality :many)
infer-schema (when-not type (infer-schema-from-input-string v))
property-type (or type infer-schema :default)
schema (get builtin-schema-types property-type)
properties (:block/properties block)
value (get properties property-uuid)]
(when-not (and multiple-values? (string/blank? (str v)))
(let [v* (try
(convert-property-input-string property-type v)
(catch :default e
(notification/show! (str e) :error false)
nil))]
(when (some? v*)
(when v
(let [property (db/pull repo '[*] [:block/name (gp-util/page-name-sanity-lc k-name)])
property-uuid (or (:block/uuid property) (random-uuid))
{:keys [type cardinality]} (:block/schema property)
multiple-values? (= cardinality :many)
infer-schema (when-not type (infer-schema-from-input-string v))
property-type (or type infer-schema :default)
schema (get builtin-schema-types property-type)
properties (:block/properties block)
value (get properties property-uuid)]
(when-not (and multiple-values? (string/blank? (str v)))
(let [v* (try
(convert-property-input-string property-type v)
(catch :default e
(notification/show! (str e) :error false)
nil))]
(defonce debug-v v*)
(when-not (contains? (if (set? value) value #{value}) v*)
(if-let [msg (me/humanize (mu/explain-data schema v))]
(if-let [msg (me/humanize (mu/explain-data schema v*))]
(let [msg' (str "\"" k-name "\"" " " (if (coll? msg) (first msg) msg))]
(notification/show! msg' :warning))
(do

View File

@@ -186,7 +186,10 @@
(->> (db-model/get-all-properties)
(remove (property-edit/hidden-properties))
;; Complete full keyword except the ':'
(map #(subs (str %) 1))))
(map (fn [property]
(if (keyword? property)
(subs (str property) 1)
property)))))
(defn property-search
([q]