reverted.

This commit is contained in:
2021-05-27 08:25:58 -07:00
parent c7055d7a70
commit 33b45373c2
34 changed files with 443 additions and 2504 deletions

View File

@@ -2,6 +2,7 @@
(: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]))

View File

@@ -2,6 +2,7 @@
(: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]))

View File

@@ -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-v3]]
[auto-ap.views.components.typeahead :refer [typeahead-entity]]
[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-v3 {:entities chooseable-expense-accounts
:type "typeahead-v3"
:entity->text (fn [x] (str (:numeric-code x) " - " (:name x)))
:field [:expense-accounts id :account]}])]]
[typeahead-entity {:matches chooseable-expense-accounts
:type "typeahead-entity"
:match->text (fn [x] (str (:numeric-code x) " - " (:name x)))
:field [:expense-accounts id :account]}])]]
(when multi-location?
[:td

View File

@@ -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-v3]]
[auto-ap.views.components.typeahead :refer [typeahead typeahead-entity]]
[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-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}]]]]
[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}]]]]
[:div.column.is-narrow
[:p.help "Location"]
[:div.control

View File

@@ -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-v3]]
[auto-ap.views.components.typeahead :refer [typeahead-entity]]
[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-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])}]]
[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]}]]
[:p.menu-label "Date Range"]
[:div
[date-range-filter

View File

@@ -2,6 +2,7 @@
(: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]))

View File

@@ -3,106 +3,238 @@
[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]))
(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}]
(println "hello")
(let [[items set-items] (react/useState (map clj->js entities))
state-reducer (fn [state actions-and-changes]
(cond
(= (.-type actions-and-changes) (.-InputChange (.-stateChangeTypes useCombobox)))
(doto (.-changes actions-and-changes) (aset
"selectedItem"
nil))
(and (= (.-type actions-and-changes) (.-InputBlur (.-stateChangeTypes useCombobox)))
(not (.-selectedItem state)))
(doto (.-changes actions-and-changes) (aset
"inputValue"
nil))
:else
(.-changes actions-and-changes)))
[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 (.-inputValue input) entity-index)
(sort-by (fn [[k v]]
(- (:score v))))
(map (fn [[x]]
(entities-by-id x)
))
(take 5)
clj->js
set-items)
(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))
(set-items (map clj->js (take 5 (filter (fn [x] (str/includes? (or (some-> (entity->text x) .toLowerCase) "")
(or (some-> (.-inputValue input) .toLowerCase) "")))
entities))))))
:stateReducer state-reducer
:onSelectedItemChange (fn [z]
(when on-change
(on-change (js->clj (.-selectedItem z) :keywordize-keys true))))})) $
[(.-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 (.-keyCode e))
(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 [{: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
^{: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)]))})))
(defn typeahead-v3 [{:keys [class disabled entities entity->text entities-by-id entity-index on-change value ] :as props}]
(println typeahead-v3-internal)
[:div
[:f> typeahead-v3-internal props]])

View File

@@ -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-v3]]
[auto-ap.views.components.typeahead :refer [typeahead-entity]]
[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-v3 {:entities clients
:entity->text :name
:type "typeahead-v3"
:field [override-key i]
:event change-event
:subscription data}]]]
[typeahead-entity {:matches clients
:match->text :name
:type "typeahead-entity"
: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-v3 {:entities clients
:entity->text :name
:type "typeahead-v3"
:field [override-key i :client]
:event change-event
:subscription data}]]]
[typeahead-entity {:matches clients
:match->text :name
:type "typeahead-entity"
: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-v3 {:entities clients
:entity->text :name
:type "typeahead-v3"
:field [override-key i :client]
:event change-event
:subscription data}]]]
[typeahead-entity {:matches clients
:match->text :name
:type "typeahead-entity"
: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-v3 {:entities @(re-frame/subscribe [::subs/accounts client])
:entity->text account->match-text
:field field
:type "typeahead-v3"
:event change-event
:subscription data}])]
[typeahead-entity {:matches @(re-frame/subscribe [::subs/accounts client])
:match->text account->match-text
:field field
:type "typeahead-entity"
:event change-event
:subscription data}])]
[:h2.subtitle "Address"]
[address-field {:field [:address]

View File

@@ -2,6 +2,18 @@
(: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}]]]])