diff --git a/resources/public/index.html b/resources/public/index.html
index bb53e1b5..183410d7 100644
--- a/resources/public/index.html
+++ b/resources/public/index.html
@@ -19,6 +19,7 @@
height: 100%;
background-color: #fff;
}
+
body {
animation: scaleUp .7s ease both;
}
@@ -28,6 +29,13 @@
@keyframes appear {
from { opacity: 0; }
}
+ @keyframes slideIn {
+ from {
+ -webkit-transform: translateY(-100%);
+ transform: translateY(-100%);
+ opacity: 0;
+ }
+ }
@keyframes moveToTop {
from { }
@@ -47,7 +55,7 @@
}
}
- tr.live-added {
+ tbody tr.live-added {
animation: flashPrimary 1.0s ease both;
}
.left-nav {
diff --git a/src/cljc/auto_ap/entities/companies.cljc b/src/cljc/auto_ap/entities/companies.cljc
index dc8196e1..9584422b 100644
--- a/src/cljc/auto_ap/entities/companies.cljc
+++ b/src/cljc/auto_ap/entities/companies.cljc
@@ -1,15 +1,13 @@
(ns auto-ap.entities.companies
(:require [clojure.spec.alpha :as s]
+ [auto-ap.entities.shared :as shared]
[clojure.string :as str]
[auto-ap.entities.address :as address]))
(def email-regex #"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,63}$")
(s/def ::id int)
-(s/def ::identifier (s/nilable string?))
-(s/def ::required-identifier (s/and string?
- #(not (str/blank? %))))
-(s/def ::name ::required-identifier)
+(s/def ::name ::shared/required-identifier)
(s/def ::address ::address/address)
(s/def ::email (s/nilable (s/and string? (s/or :is-email #(re-matches email-regex %)
diff --git a/src/cljc/auto_ap/entities/invoice.cljc b/src/cljc/auto_ap/entities/invoice.cljc
new file mode 100644
index 00000000..58182b40
--- /dev/null
+++ b/src/cljc/auto_ap/entities/invoice.cljc
@@ -0,0 +1,16 @@
+(ns auto-ap.entities.invoice
+ (:require [clojure.spec.alpha :as s]
+ [auto-ap.entities.shared :as shared]))
+
+(s/def ::vendor-id int?)
+(s/def ::company-id int?)
+(s/def ::invoice-number ::shared/required-identifier)
+(s/def ::date ::shared/date)
+(s/def ::total ::shared/money)
+
+(s/def ::invoice (s/keys :opt-un [::vendor-id
+ ::company-id
+ ::invoice-number
+ ::date
+ ::total
+ ]))
diff --git a/src/cljc/auto_ap/entities/shared.cljc b/src/cljc/auto_ap/entities/shared.cljc
new file mode 100644
index 00000000..df114d28
--- /dev/null
+++ b/src/cljc/auto_ap/entities/shared.cljc
@@ -0,0 +1,14 @@
+(ns auto-ap.entities.shared
+ (:require [clojure.spec.alpha :as s]
+ [clojure.string :as str]))
+
+(def date-regex #"[0-9]{1,2}/[0-9]{1,2}/[0-9]{4}")
+(def money-regex #"[0-9]+(\.[0-9]{1,2})?$")
+
+(s/def ::identifier (s/nilable string?))
+(s/def ::date (s/and string? #(re-matches date-regex %)))
+(s/def ::required-identifier (s/and string?
+ #(not (str/blank? %))))
+
+(s/def ::money (s/and string?
+ #(re-matches money-regex %)))
diff --git a/src/cljs/auto_ap/views/components/typeahead.cljs b/src/cljs/auto_ap/views/components/typeahead.cljs
index 527c48da..926da9da 100644
--- a/src/cljs/auto_ap/views/components/typeahead.cljs
+++ b/src/cljs/auto_ap/views/components/typeahead.cljs
@@ -2,7 +2,7 @@
(:require [reagent.core :as r]
[clojure.string :as str]))
-(defn typeahead [{:keys [matches on-change field value]}]
+(defn typeahead [{:keys [matches on-change field value class]}]
(let [text (r/atom (or (second (first (filter #(= (first %) value) matches))) ""))
highlighted (r/atom 0)
selected (r/atom (first (first (filter #(= (first %) value) matches))))
@@ -12,19 +12,20 @@
(println [id t])
(when on-change
(on-change id)))]
- (fn [{:keys [matches on-change field value]}]
+ (fn [{:keys [matches on-change field value class]}]
(let [valid-matches (take 5 (for [[[id t :as match] i] (map vector matches (range))
:when (str/includes? (.toLowerCase t) (.toLowerCase @text))]
match))]
[:div.typeahead
(if @selected
- [:div.input
+ [:div.input {:class class}
[:div.control
[:div.tags.has-addons
[:span.tag @text]
[:a.tag.is-delete {:on-click (fn [] (select [nil ""]))}]]]]
[:input.input {:type "text"
+ :class class
:field [:vendor]
:value @text
:on-blur (fn [e]
diff --git a/src/cljs/auto_ap/views/pages/unpaid_invoices.cljs b/src/cljs/auto_ap/views/pages/unpaid_invoices.cljs
index f7351ecd..cc483797 100644
--- a/src/cljs/auto_ap/views/pages/unpaid_invoices.cljs
+++ b/src/cljs/auto_ap/views/pages/unpaid_invoices.cljs
@@ -3,6 +3,7 @@
[reagent.core :as r]
[clojure.string :as str]
[auto-ap.entities.companies :as company]
+ [auto-ap.entities.invoice :as invoice]
[auto-ap.entities.vendors :as vendor]
[auto-ap.views.utils :refer [dispatch-event bind-field horizontal-field]]
[auto-ap.utils :refer [by]]
@@ -280,6 +281,7 @@
:type "typeahead"
:field [:vendor-id]
:event change-event
+ :spec ::invoice/vendor-id
:subscription data}]]]
[horizontal-field
[:label.label "Date"]
@@ -287,6 +289,7 @@
[:input.input {:type "text"
:field [:date]
:event change-event
+ :spec ::invoice/date
:subscription data}]]]
[horizontal-field
@@ -296,6 +299,7 @@
:type "typeahead"
:field [:company-id]
:event change-event
+ :spec ::invoice/company-id
:subscription data}]]]
[horizontal-field
@@ -304,6 +308,7 @@
[:input.input {:type "text"
:field [:invoice-number]
:event change-event
+ :spec ::invoice/invoice-number
:subscription data}]]]
[horizontal-field
@@ -316,6 +321,7 @@
:field [:total]
:event change-event
:subscription data
+ :spec ::invoice/total
:step "0.01"}]]]]]]))
(def unpaid-invoices-page