vendor querying step 1.

This commit is contained in:
2022-04-10 20:28:02 -07:00
parent cbc3c00b8e
commit e897443f7d
9 changed files with 308 additions and 67 deletions

View File

@@ -14,8 +14,7 @@
(not (get-in accounts [0 :account :id]))))
(defn default-account [accounts default-account amount locations]
[{:id (get-in accounts [0 :id]
(str "new-" (random-uuid)))
[{:id (str "new-" (random-uuid))
:amount (Math/abs amount)
:amount-percentage 100
:amount-mode "%"

View File

@@ -0,0 +1,134 @@
(ns auto-ap.views.components.typeahead.vendor
(:require
[downshift :as ds :refer [useCombobox]]
[re-frame.core :as re-frame]
[auto-ap.views.utils :refer [with-user]]
[react]))
(set! *warn-on-infer* true)
;; TODO: This avoids the use of inferred externs by using aget. You could just use the ^js tag though
(defn state-reducer [^js/FakeStateObject state ^js/FakeActionsAndChanges actions-and-changes]
(let [useCombobox ^js/Downshift useCombobox]
(cond
(= (.-type actions-and-changes) (.-InputChange (.-stateChangeTypes ^js/Downshift useCombobox)))
(set! (.-selectedItem (.-changes actions-and-changes)) nil)
(and (= (.-type actions-and-changes) (.-InputBlur (.-stateChangeTypes ^js/Downshift useCombobox)))
(not (.-selectedItem state)))
(set! (.-inputValue (.-changes actions-and-changes ))
nil)
:else
nil))
(.-changes actions-and-changes))
(re-frame/reg-event-fx
::search-completed
(fn [_ [_ set-items set-loading-status result]]
(set-loading-status nil)
(set-items (:search-results result))
{}))
(re-frame/reg-event-fx
::search-failed
(fn [_ _]
{}))
(re-frame/reg-event-fx
::input-value-settled
[with-user]
(fn [{:keys [user]} [_ input-value search-query set-items set-loading-status]]
(when (> (count input-value) 2)
(set-loading-status :loading)
{:graphql {:token user
:query-obj {:venia/queries [{:query/data (search-query input-value )
:query/alias :search-results}]}
:on-success [::search-completed set-items set-loading-status]
:on-error [::search-failed set-loading-status]}})))
(re-frame/reg-event-fx
::input-value-changed
(fn [_ [_ input-value search-query set-items set-loading-status]]
(set-items [])
(when (> (count input-value) 2)
(set-loading-status :loading)
{:dispatch-debounce {:event [::input-value-settled input-value search-query set-items set-loading-status]
:time 250
:key ::input-value-settled}})))
(defn typeahead-v3-internal [{:keys [class style ^js entity->text on-change disabled value name search-query auto-focus] :or {disabled false} :as i}]
(let [[items set-items] (react/useState [])
[loading-status set-loading-status] (react/useState false)
[getLabelProps getMenuProps getComboboxProps getToggleButtonProps getInputProps getItemProps isOpen highlightedIndex selectItem selectedItem setInputValue]
(as-> (useCombobox (clj->js {:items items
:defaultHighlightedIndex 0
:defaultSelectedItem value
:onInputValueChange (fn [input]
(re-frame/dispatch [::input-value-changed (aget input "inputValue") search-query set-items set-loading-status])
true)
:stateReducer state-reducer
:onSelectedItemChange (fn [z]
(when on-change
(on-change (js->clj (aget z "selectedItem") :keywordize-keys true))))})) $
(map #(aget $ %) ["getLabelProps" "getMenuProps" "getComboboxProps" "getToggleButtonProps" "getInputProps" "getItemProps" "isOpen" "highlightedIndex" "selectItem" "selectedItem" "setInputValue"]))]
#_(println (getInputProps))
[:<>
[:div.typeahead (assoc (js->clj (getComboboxProps))
:style style)
(cond
selectedItem
^{:key "typeahead"}
[:div.input (assoc (js->clj (getInputProps #js {:disabled (if disabled
"disabled"
"")}))
:on-key-up (fn [e]
(when (= 8 (aget e "keyCode" ))
(selectItem nil)
(setInputValue nil)
(when on-change
(on-change nil))))
:class (if (= :loading loading-status)
"is-loading"
class)
:tab-index "0")
[:div.control
[:div.tags.has-addons
[:span.tag (entity->text (js->clj selectedItem :keywordize-keys true))]
(when name
[:input {:type "hidden" :name name :value (:id (js->clj selectedItem :keywordize-keys true))}])
(when-not disabled
[:a.tag.is-delete {:on-click (fn []
(setInputValue nil)
(selectItem nil)
(when on-change
(on-change nil)))}])]]]
:else
^{:key "typeahead"} [:div.control {:class (when (= :loading loading-status)
"is-loading")}
[:input.input (js->clj
(getInputProps #js {:disabled (if disabled
"disabled"
"")
:autoFocus (if auto-focus
"autoFocus"
"")}))]])
[:div {:class (when (and isOpen (seq items))
"typeahead-menu")}
[:ul (js->clj (getMenuProps))
(if (and isOpen (seq items))
(for [[index item] (map vector (range) (js->clj items :keywordize-keys true))]
^{:key item}
[:li.typeahead-suggestion (assoc (js->clj (getItemProps #js {:item item :index index}))
:class (if (= index highlightedIndex)
"typeahead-highlighted"))
(entity->text item)]))]]]]))
(defn search-backed-typeahead [props]
[:div
[:f> typeahead-v3-internal (assoc props
:entity->text :name
)]])