addressed all compilation errors.
This commit is contained in:
@@ -2,7 +2,6 @@
|
||||
(:require
|
||||
[clojure.spec.alpha :as s]
|
||||
[auto-ap.entities.invoice :as invoice]
|
||||
[auto-ap.views.components.typeahead :refer [typeahead]]
|
||||
[auto-ap.views.utils :refer [bind-field ->$]]
|
||||
[auto-ap.subs :as subs]
|
||||
[re-frame.core :as re-frame]))
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
(:require
|
||||
[clojure.spec.alpha :as s]
|
||||
[auto-ap.entities.invoice :as invoice]
|
||||
[auto-ap.views.components.typeahead :refer [typeahead]]
|
||||
[auto-ap.views.utils :refer [bind-field date-picker date->str local-now standard]]
|
||||
[cljs-time.core :as t]
|
||||
[re-frame.core :as re-frame]))
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
[auto-ap.subs :as subs]
|
||||
[auto-ap.utils :refer [by]]
|
||||
[auto-ap.views.components.modal :as modal]
|
||||
[auto-ap.views.components.typeahead :refer [typeahead-entity]]
|
||||
[auto-ap.views.components.typeahead :refer [typeahead-v3]]
|
||||
[auto-ap.views.pages.invoices.common :refer [invoice-read]]
|
||||
[auto-ap.views.utils :refer [dispatch-event with-user]]
|
||||
[clojure.string :as str]
|
||||
@@ -124,10 +124,10 @@
|
||||
[:tr
|
||||
[:td.expandable [:div.control
|
||||
(raw-field
|
||||
[typeahead-entity {:matches chooseable-expense-accounts
|
||||
:type "typeahead-entity"
|
||||
:match->text (fn [x] (str (:numeric-code x) " - " (:name x)))
|
||||
:field [:expense-accounts id :account]}])]]
|
||||
[typeahead-v3 {:entities chooseable-expense-accounts
|
||||
:type "typeahead-v3"
|
||||
:entity->text (fn [x] (str (:numeric-code x) " - " (:name x)))
|
||||
:field [:expense-accounts id :account]}])]]
|
||||
|
||||
(when multi-location?
|
||||
[:td
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
(ns auto-ap.views.components.expense-accounts-field
|
||||
(:require [auto-ap.forms :as forms]
|
||||
[auto-ap.subs :as subs]
|
||||
[auto-ap.views.components.typeahead :refer [typeahead typeahead-entity]]
|
||||
[auto-ap.views.components.typeahead :refer [typeahead-v3]]
|
||||
[auto-ap.views.components.money-field :refer [money-field]]
|
||||
[auto-ap.views.utils :refer [bind-field dispatch-event ->$]]
|
||||
[goog.string :as gstring]
|
||||
@@ -162,14 +162,14 @@
|
||||
[:div.control.is-fullwidth
|
||||
[bind-field
|
||||
^{:key (:id client)}
|
||||
[typeahead-entity {:matches chooseable-expense-accounts
|
||||
:match->text (fn [x ]
|
||||
(str (:numeric-code x) " - " (:name x)))
|
||||
:disabled disabled
|
||||
:type "typeahead-entity"
|
||||
:field [index :account]
|
||||
:event [::expense-account-changed event expense-accounts max-value]
|
||||
:subscription expense-accounts}]]]]
|
||||
[typeahead-v3 {:entities chooseable-expense-accounts
|
||||
:entity->text (fn [x ]
|
||||
(str (:numeric-code x) " - " (:name x)))
|
||||
:disabled disabled
|
||||
:type "typeahead-v3"
|
||||
:field [index :account]
|
||||
:event [::expense-account-changed event expense-accounts max-value]
|
||||
:subscription expense-accounts}]]]]
|
||||
[:div.column.is-narrow
|
||||
[:p.help "Location"]
|
||||
[:div.control
|
||||
|
||||
@@ -96,8 +96,8 @@
|
||||
extended-last-page-button
|
||||
[:span.mx-4 (Math/min (inc start) total) "-" end "/" total]
|
||||
[:div.select
|
||||
[:select {:value per-page :on-change (fn [e] (on-change {:start 0
|
||||
:per-page (js/parseInt (.. e -target -value ))}))}
|
||||
[:select {:value per-page :on-change (fn [^js/Event e] (on-change {:start 0
|
||||
:per-page (js/parseInt (.-value ^js/HTMLOptionElement (.-target e )))}))}
|
||||
[:option {:value 20 } "20 per page" ]
|
||||
[:option {:value 50} "50 per page" ]
|
||||
[:option {:value 100} "100 per page" ]
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
[auto-ap.views.components.date-range-filter :refer [date-range-filter]]
|
||||
[auto-ap.views.components.number-filter :refer [number-filter]]
|
||||
[auto-ap.views.components.switch-field :refer [switch-field]]
|
||||
[auto-ap.views.components.typeahead :refer [typeahead-entity]]
|
||||
[auto-ap.views.components.typeahead :refer [typeahead-v3]]
|
||||
[auto-ap.views.pages.data-page :as data-page]
|
||||
[auto-ap.views.utils :refer [active-when dispatch-event dispatch-value-change]]
|
||||
[bidi.bidi :as bidi]
|
||||
@@ -59,12 +59,12 @@
|
||||
[:div
|
||||
[:p.menu-label "Vendor"]
|
||||
[:div
|
||||
[typeahead-entity {:matches @(re-frame/subscribe [::subs/searchable-vendors])
|
||||
:on-change #(re-frame/dispatch [::data-page/filter-changed data-page :vendor %])
|
||||
:match->text :name
|
||||
:type "typeahead-entity"
|
||||
:value @(re-frame/subscribe [::data-page/filter data-page :vendor])
|
||||
:include-keys [:name :id]}]]
|
||||
[typeahead-v3 {:entities-by-id @(re-frame/subscribe [::subs/vendors-by-id])
|
||||
:entity-index @(re-frame/subscribe [::subs/searchable-vendors-index])
|
||||
:on-change #(re-frame/dispatch [::data-page/filter-changed data-page :vendor (some-> % (select-keys [:name :id]))])
|
||||
:entity->text :name
|
||||
:type "typeahead-v3"
|
||||
:value @(re-frame/subscribe [::data-page/filter data-page :vendor])}]]
|
||||
[:p.menu-label "Date Range"]
|
||||
[:div
|
||||
[date-range-filter
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
(:require
|
||||
[clojure.spec.alpha :as s]
|
||||
[auto-ap.entities.invoice :as invoice]
|
||||
[auto-ap.views.components.typeahead :refer [typeahead]]
|
||||
[auto-ap.views.utils :refer [bind-field date-picker date->str local-now standard]]
|
||||
[cljs-time.core :as t]
|
||||
[re-frame.core :as re-frame]))
|
||||
|
||||
@@ -3,238 +3,93 @@
|
||||
[reagent.ratom :as ra]
|
||||
[clojure.string :as str]
|
||||
[clojure.set :as set]
|
||||
#_[memsearch.core :as ms]
|
||||
[memsearch.core :as ms]
|
||||
[downshift :as ds :refer [useCombobox]]
|
||||
[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 [state actions-and-changes]
|
||||
(cond
|
||||
(= (aget actions-and-changes "type") (aget (aget useCombobox "stateChangeTypes" ) "InputChange"))
|
||||
(doto (aget actions-and-changes "changes") (aset "selectedItem" nil))
|
||||
|
||||
(and (= (aget actions-and-changes "type") (aget (aget useCombobox "stateChangeTypes") "InputBlur"))
|
||||
(not (aget state "selectedItem")))
|
||||
(doto (aget actions-and-changes "changes" ) (aset "inputValue" nil))
|
||||
|
||||
(defn get-valid-matches [matches not-found-description not-found-value text]
|
||||
(let [valid-matches (take 15 (for [[[id t :as match] i] (map vector matches (range))
|
||||
:when (str/includes? (or (some-> t .toLowerCase) "") (or (some-> text .toLowerCase) ""))]
|
||||
match))
|
||||
valid-matches (if (and not-found-description text)
|
||||
(concat valid-matches [[:not-found (not-found-description text) (not-found-value text)]])
|
||||
valid-matches)]
|
||||
valid-matches))
|
||||
:else
|
||||
(aget actions-and-changes "changes")))
|
||||
|
||||
(defn typeahead [{:keys [matches on-change field text-field value class not-found-description
|
||||
disabled not-found-value auto-focus]}]
|
||||
(let [text (r/atom (or (second (first (filter #(= (first %) value) matches))) ""))
|
||||
highlighted (r/atom nil)
|
||||
selected (r/atom (first (first (filter #(= (first %) value) matches))))
|
||||
]
|
||||
(r/create-class
|
||||
{:reagent-render (fn [{:keys [matches on-change disabled field text-field value class not-found-description]}]
|
||||
(let [ select (fn [[id text-description text-value]]
|
||||
(reset! selected id)
|
||||
(reset! text text-description)
|
||||
(when on-change
|
||||
(if (= :not-found id)
|
||||
(on-change nil text-description text-value)
|
||||
(on-change id text-description (or text-value text-description)))))
|
||||
text @text
|
||||
valid-matches (get-valid-matches matches not-found-description not-found-value text)]
|
||||
[:div.typeahead
|
||||
(if disabled
|
||||
(defn typeahead-v3-internal [{:keys [class style disabled entities entity->text entities-by-id entity-index on-change disabled value name auto-focus] :or {disabled false} :as i}]
|
||||
(let [[items set-items] (react/useState (map clj->js entities))
|
||||
[getLabelProps getMenuProps getComboboxProps getToggleButtonProps getInputProps getItemProps isOpen highlightedIndex selectItem selectedItem setInputValue]
|
||||
(as-> (useCombobox (clj->js {:items items
|
||||
:defaultHighlightedIndex 0
|
||||
:defaultSelectedItem value
|
||||
:onInputValueChange (fn [input]
|
||||
(if entities-by-id
|
||||
(->> (ms/text-search (aget input "inputValue") entity-index)
|
||||
(sort-by (fn [[k v]]
|
||||
(- (:score v))))
|
||||
(map (fn [[x]]
|
||||
(entities-by-id x)
|
||||
))
|
||||
(take 5)
|
||||
clj->js
|
||||
set-items)
|
||||
|
||||
^{:key (str "typeahead" text) } [:input.input {:disabled "disabled" :value text} ]
|
||||
|
||||
(if @selected
|
||||
^{:key "typeahead"} [:div.input {:class class
|
||||
:tab-index "0"
|
||||
:on-key-up (fn [e]
|
||||
(if (= 8 (.-keyCode e))
|
||||
(do
|
||||
(select [nil "" nil])
|
||||
true)
|
||||
false))}
|
||||
[:div.control
|
||||
[:div.tags.has-addons
|
||||
[:span.tag text]
|
||||
[:a.tag.is-delete {:on-click (fn []
|
||||
(select [nil "" nil]))}]]]]
|
||||
^{:key "typeahead"}
|
||||
[:input.input {:type "text"
|
||||
:class class
|
||||
|
||||
:value text
|
||||
:auto-focus auto-focus
|
||||
:on-blur (fn [e]
|
||||
(cond @selected
|
||||
nil
|
||||
|
||||
(#{"" nil} text)
|
||||
nil
|
||||
|
||||
@highlighted
|
||||
(do (select @highlighted)
|
||||
true)
|
||||
|
||||
:else
|
||||
(do (select [nil ""])
|
||||
true)))
|
||||
:on-key-down (fn [e]
|
||||
(condp = (.-keyCode e)
|
||||
; up
|
||||
38 (do
|
||||
(when-let [new-match (->> valid-matches
|
||||
(take-while #(not= % @highlighted))
|
||||
(last))]
|
||||
(reset! highlighted new-match))
|
||||
true)
|
||||
;; dwon
|
||||
40 (do
|
||||
(when-let [new-match (->> valid-matches
|
||||
(drop-while #(not= % @highlighted))
|
||||
(drop 1)
|
||||
(first))]
|
||||
(reset! highlighted new-match))
|
||||
true)
|
||||
13 (do (.preventDefault e)
|
||||
(when @highlighted
|
||||
|
||||
(select @highlighted)
|
||||
false))
|
||||
true))
|
||||
:on-change (fn [e]
|
||||
(let [new-matches (get-valid-matches matches not-found-description not-found-value (.. e -target -value))]
|
||||
(reset! highlighted (first new-matches)))
|
||||
(select [nil (.. e -target -value)]))}]))
|
||||
|
||||
(cond
|
||||
(and (seq text)
|
||||
(not @selected)
|
||||
(seq valid-matches))
|
||||
(let [[h] @highlighted]
|
||||
[:div.typeahead-menu
|
||||
[:ul
|
||||
(for [[id t :as match] valid-matches]
|
||||
^{:key id} [:li.typeahead-suggestion {:class (if (= id h)
|
||||
"typeahead-highlighted")
|
||||
:on-mouse-down #(do (select match))} t])]])
|
||||
|
||||
:else
|
||||
nil)]))})))
|
||||
|
||||
(defn get-valid-entity-matches [matches not-found-description not-found-value text match->text]
|
||||
(let [valid-matches (->> (for [[match i] (map vector matches (range))
|
||||
:let [t (match->text match)
|
||||
match-index (str/index-of (or (some-> t .toLowerCase) "") (or (some-> text .toLowerCase) ""))]
|
||||
:when match-index]
|
||||
[match match-index ])
|
||||
(sort-by second)
|
||||
(map first)
|
||||
(take 10))
|
||||
valid-matches (if (and not-found-description text)
|
||||
(concat valid-matches [[:not-found (not-found-description text) (not-found-value text)]])
|
||||
valid-matches)]
|
||||
valid-matches))
|
||||
(defn typeahead-entity [{:keys [matches on-change field value class not-found-description
|
||||
disabled not-found-value auto-focus name include-keys]}]
|
||||
(let [text (r/atom (or (second (first (filter #(= (first %) value) matches))) ""))
|
||||
highlighted (r/atom nil)
|
||||
]
|
||||
(r/create-class
|
||||
{:reagent-render (fn [{:keys [matches on-change disabled match->text field value class not-found-description include-keys style]}]
|
||||
(let [select (fn [entity]
|
||||
(when on-change
|
||||
(if (= :not-found entity)
|
||||
(on-change nil)
|
||||
(on-change (cond-> entity
|
||||
(and include-keys entity) (select-keys include-keys))))))
|
||||
text-atom text
|
||||
text (or (when value (match->text value)) @text)
|
||||
valid-matches (get-valid-entity-matches matches not-found-description not-found-value text match->text)]
|
||||
|
||||
[:div.typeahead {:style style}
|
||||
(if disabled
|
||||
|
||||
^{:key (str "typeahead" text) } [:input.input {:disabled "disabled" :value text} ]
|
||||
|
||||
(if value
|
||||
^{:key "typeahead"} [:div.input {:class class
|
||||
:tab-index "0"
|
||||
:on-key-up (fn [e]
|
||||
(if (= 8 (.-keyCode e))
|
||||
(do
|
||||
(select nil)
|
||||
(reset! text-atom nil)
|
||||
true)
|
||||
false))}
|
||||
[:div.control
|
||||
[:div.tags.has-addons
|
||||
[:span.tag text]
|
||||
(when name
|
||||
[:input {:type "hidden" :name name :value (:id @highlighted)}])
|
||||
[:a.tag.is-delete {:on-click (fn []
|
||||
(select nil)
|
||||
(reset! text-atom nil)
|
||||
(reset! highlighted nil))}]]]]
|
||||
^{:key "typeahead"} [:input.input {:type "text"
|
||||
:class class
|
||||
|
||||
:value text
|
||||
:auto-focus auto-focus
|
||||
:on-blur (fn [e]
|
||||
(cond value
|
||||
nil
|
||||
|
||||
(#{"" nil} text)
|
||||
nil
|
||||
|
||||
@highlighted
|
||||
(do (select @highlighted)
|
||||
|
||||
true)
|
||||
|
||||
:else
|
||||
(do (select nil)
|
||||
(reset! highlighted nil)
|
||||
(reset! text-atom nil)
|
||||
true)))
|
||||
:on-key-down (fn [e]
|
||||
(condp = (.-keyCode e)
|
||||
; up
|
||||
38 (do
|
||||
(when-let [new-match (->> valid-matches
|
||||
(take-while #(not= % @highlighted))
|
||||
(last))]
|
||||
(reset! highlighted new-match))
|
||||
true)
|
||||
;; dwon
|
||||
40 (do
|
||||
(when-let [new-match (->> valid-matches
|
||||
(drop-while #(not= % @highlighted))
|
||||
(drop 1)
|
||||
(first))]
|
||||
(reset! highlighted new-match))
|
||||
true)
|
||||
13 (do (.preventDefault e)
|
||||
(when @highlighted
|
||||
|
||||
(select @highlighted)
|
||||
false))
|
||||
true))
|
||||
:on-change (fn [e]
|
||||
(let [new-matches (get-valid-entity-matches matches not-found-description not-found-value (.. e -target -value) match->text)]
|
||||
(reset! highlighted (first new-matches)))
|
||||
(reset! text-atom (.. e -target -value)))}]))
|
||||
|
||||
(cond
|
||||
(and (seq text)
|
||||
(not value)
|
||||
(seq valid-matches))
|
||||
(let [h @highlighted]
|
||||
[:div.typeahead-menu
|
||||
[:ul
|
||||
(for [entity valid-matches]
|
||||
(let [t (match->text entity)]
|
||||
^{:key entity} [:li.typeahead-suggestion {:class (if (= entity h)
|
||||
"typeahead-highlighted")
|
||||
:on-mouse-over (fn [] (reset! highlighted entity))
|
||||
:on-mouse-down #(do (select entity))} t]))]])
|
||||
|
||||
:else
|
||||
nil)]))})))
|
||||
(set-items (map clj->js (take 5 (filter (fn [x] (str/includes? (or (some-> (entity->text x) str/lower-case) "")
|
||||
(or (some-> (aget input "inputValue") str/lower-case) "")))
|
||||
entities))))))
|
||||
: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"]))]
|
||||
[:<>
|
||||
[:div.typeahead (assoc (js->clj (getComboboxProps))
|
||||
:style style)
|
||||
(if 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 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)))}])]]]
|
||||
^{:key "typeahead"} [:input.input (js->clj
|
||||
(getInputProps #js {:disabled (if disabled
|
||||
"disabled"
|
||||
"")
|
||||
:autoFocus (if auto-focus
|
||||
"autoFocus"
|
||||
"")}))])
|
||||
[:div {:class (if (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 typeahead-v3 [{:keys [class disabled entities entity->text entities-by-id entity-index on-change value ] :as props}]
|
||||
[:div
|
||||
[:f> typeahead-v3-internal props]])
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
(:require [re-frame.core :as re-frame]
|
||||
[auto-ap.views.utils :refer [dispatch-event horizontal-field bind-field with-user with-is-admin? active-when account->match-text]]
|
||||
[auto-ap.views.components.address :refer [address-field]]
|
||||
[auto-ap.views.components.typeahead :refer [typeahead-entity]]
|
||||
[auto-ap.views.components.typeahead :refer [typeahead-v3]]
|
||||
[auto-ap.views.components.dropdown :refer [drop-down drop-down-contents]]
|
||||
[auto-ap.events :as events]
|
||||
[clj-fuzzy.metrics :refer [jaccard jaro-winkler]]
|
||||
@@ -154,12 +154,12 @@
|
||||
[:div.columns
|
||||
[:div.column
|
||||
[bind-field
|
||||
[typeahead-entity {:matches clients
|
||||
:match->text :name
|
||||
:type "typeahead-entity"
|
||||
:field [override-key i]
|
||||
:event change-event
|
||||
:subscription data}]]]
|
||||
[typeahead-v3 {:entities clients
|
||||
:entity->text :name
|
||||
:type "typeahead-v3"
|
||||
:field [override-key i]
|
||||
:event change-event
|
||||
:subscription data}]]]
|
||||
|
||||
[:div.column.is-1
|
||||
[:a.button {:on-click (dispatch-event [::removed-override override-key i])} [:span.icon [:span.icon-remove]]]]]))])))
|
||||
@@ -186,12 +186,12 @@
|
||||
[:div.columns
|
||||
[:div.column
|
||||
[bind-field
|
||||
[typeahead-entity {:matches clients
|
||||
:match->text :name
|
||||
:type "typeahead-entity"
|
||||
:field [override-key i :client]
|
||||
:event change-event
|
||||
:subscription data}]]]
|
||||
[typeahead-v3 {:entities clients
|
||||
:entity->text :name
|
||||
:type "typeahead-v3"
|
||||
:field [override-key i :client]
|
||||
:event change-event
|
||||
:subscription data}]]]
|
||||
[:div.column
|
||||
[bind-field
|
||||
(template
|
||||
@@ -215,12 +215,12 @@
|
||||
[:div.columns
|
||||
[:div.column
|
||||
[bind-field
|
||||
[typeahead-entity {:matches clients
|
||||
:match->text :name
|
||||
:type "typeahead-entity"
|
||||
:field [override-key i :client]
|
||||
:event change-event
|
||||
:subscription data}]]]
|
||||
[typeahead-v3 {:entities clients
|
||||
:entity->text :name
|
||||
:type "typeahead-v3"
|
||||
:field [override-key i :client]
|
||||
:event change-event
|
||||
:subscription data}]]]
|
||||
[:div.column
|
||||
[bind-field
|
||||
(template
|
||||
@@ -306,12 +306,12 @@
|
||||
:override-key :account-overrides}
|
||||
(fn [field client]
|
||||
|
||||
[typeahead-entity {:matches @(re-frame/subscribe [::subs/accounts client])
|
||||
:match->text account->match-text
|
||||
:field field
|
||||
:type "typeahead-entity"
|
||||
:event change-event
|
||||
:subscription data}])]
|
||||
[typeahead-v3 {:entities @(re-frame/subscribe [::subs/accounts client])
|
||||
:entity->text account->match-text
|
||||
:field field
|
||||
:type "typeahead-v3"
|
||||
:event change-event
|
||||
:subscription data}])]
|
||||
|
||||
[:h2.subtitle "Address"]
|
||||
[address-field {:field [:address]
|
||||
|
||||
@@ -2,18 +2,6 @@
|
||||
(:require
|
||||
[clojure.spec.alpha :as s]
|
||||
[auto-ap.entities.invoice :as invoice]
|
||||
[auto-ap.views.components.typeahead :refer [typeahead]]
|
||||
[auto-ap.views.utils :refer [bind-field]]))
|
||||
|
||||
(defn vendor-filter [{:keys [value on-change-event vendors]}]
|
||||
[:div.field
|
||||
[:div.control
|
||||
[bind-field
|
||||
[typeahead {:matches (map (fn [x] [(:id x) (:name x)]) vendors)
|
||||
:type "typeahead"
|
||||
:auto-focus true
|
||||
:field [:vendor-id]
|
||||
:text-field [:vendor-name]
|
||||
:event on-change-event
|
||||
:spec (s/nilable ::invoice/vendor-id)
|
||||
:subscription value}]]]])
|
||||
|
||||
|
||||
Reference in New Issue
Block a user