diff --git a/ui/src/ethlance/ui/page/new_invoice.cljs b/ui/src/ethlance/ui/page/new_invoice.cljs index 37de537b..e3fc9538 100644 --- a/ui/src/ethlance/ui/page/new_invoice.cljs +++ b/ui/src/ethlance/ui/page/new_invoice.cljs @@ -2,7 +2,7 @@ (:require [district.ui.component.page :refer [page]] [district.ui.graphql.subs :as gql] - [ethlance.ui.component.icon :refer [c-icon]] + [ethlance.ui.component.button :refer [c-button c-button-label]] [ethlance.ui.component.main-layout :refer [c-main-layout]] [ethlance.ui.component.select-input :refer [c-select-input]] [ethlance.ui.component.textarea-input :refer [c-textarea-input]] @@ -54,7 +54,10 @@ token-display-name (name (or (@job-token :symbol) (@job-token :type) "")) job-token-decimals (get-in @*invoiced-job [:job :token-details :token-detail/decimals]) no-job-selected? (nil? @*invoiced-job) - focus-on-element (fn [id _event] (.focus (.getElementById js/document id)))] + focus-on-element (fn [id _event] (.focus (.getElementById js/document id))) + validations (re/subscribe [:page.new-invoice/validations]) + tx-in-progress? @(re/subscribe [:page.new-invoice/tx-in-progress?]) + button-disabled? (not (every? true? (vals @validations)))] [c-main-layout {:container-opts {:class :new-invoice-main-container}} [:div.title "New Invoice"] [:div.left-form @@ -105,6 +108,7 @@ :on-change #(re/dispatch [:page.new-invoice/set-message %]) :placeholder ""}]] - [:div.button {:on-click #(re/dispatch [:page.new-invoice/send])} - [:div.label "Send"] - [c-icon {:name :ic-arrow-right :size :small}]]])))) + [c-button + {:on-click #(re/dispatch [:page.new-invoice/send]) + :disabled? (or button-disabled? tx-in-progress?)} + [c-button-label "Send"]]])))) diff --git a/ui/src/ethlance/ui/page/new_invoice/events.cljs b/ui/src/ethlance/ui/page/new_invoice/events.cljs index 5d16f6a5..87059059 100644 --- a/ui/src/ethlance/ui/page/new_invoice/events.cljs +++ b/ui/src/ethlance/ui/page/new_invoice/events.cljs @@ -8,11 +8,9 @@ [district.ui.smart-contracts.queries :as smart-contracts.queries] [district.ui.web3-accounts.queries :as accounts-queries] [district.ui.web3-tx.events :as web3-events] - [district.ui.web3.queries :as web3-queries] [ethlance.shared.contract-constants :as contract-constants] [ethlance.shared.utils :refer [base58->hex]] [ethlance.ui.event.utils :as event.utils] - [ethlance.ui.util.tokens :as util.tokens] [re-frame.core :as re])) @@ -44,18 +42,16 @@ (re/reg-event-fx :page.new-invoice/set-hourly-rate (create-assoc-handler :hourly-rate parse-float)) (re/reg-event-fx :page.new-invoice/set-invoice-amount (create-assoc-handler :invoice-amount)) (re/reg-event-fx :page.new-invoice/set-message (create-assoc-handler :message)) +(re/reg-event-fx ::set-tx-in-progress (create-assoc-handler :tx-in-progress?)) (re/reg-event-fx :page.new-invoice/set-invoiced-job (fn [cofx [_ job]] - (let [token-type (get-in job [:job :token-details :token-detail/type]) - updated-cofx {:db (assoc-in (:db cofx) [state-key :invoiced-job] job)} - load-eth-rate [:dispatch [:district.ui.conversion-rates.events/load-conversion-rates - {:from-currencies [token-type] :to-currencies [:USD]}]]] - (if (= token-type :eth) - (assoc updated-cofx :fx [load-eth-rate]) - updated-cofx)))) + (let [token-type (get-in job [:job :token-details :token-detail/type])] + {:db (assoc-in (:db cofx) [state-key :invoiced-job] job) + :fx [[:dispatch [:district.ui.conversion-rates.events/load-conversion-rates + {:from-currencies [token-type] :to-currencies [:USD]}]]]}))) (re/reg-event-fx @@ -68,14 +64,15 @@ :message/text (:message db-invoice) :job/id (-> db-invoice :invoiced-job :job/id) :job-story/id (-> db-invoice :invoiced-job :job-story/id parse-int)}] - {:ipfs/call {:func "add" + {:fx [[:dispatch [::set-tx-in-progress true]]] + :ipfs/call {:func "add" :args [(js/Blob. [ipfs-invoice])] - :on-success [:invoice-to-ipfs-success ipfs-invoice] - :on-error [:invoice-to-ipfs-failure ipfs-invoice]}}))) + :on-success [::invoice-to-ipfs-success ipfs-invoice] + :on-error [::invoice-to-ipfs-failure ipfs-invoice]}}))) (re/reg-event-fx - :invoice-to-ipfs-success + ::invoice-to-ipfs-success (fn [cofx [_event ipfs-job ipfs-event]] (let [invoice-fields (get-in cofx [:db state-key]) job-fields (-> invoice-fields :invoiced-job :job) @@ -106,10 +103,11 @@ :on-tx-error [::send-invoice-tx-error ipfs-job]}]}))) -(re/reg-event-db +(re/reg-event-fx ::invoice-to-ipfs-failure - (fn [_db event] - (println ">>> ethlance.ui.page.new-invoice.events EVENT :invoice-to-ipfs-failure" event))) + (fn [_cofx _event] + {:fx [[:dispatch [::notification.events/show "Error uploading job data to IPFS. Not publishing transaction"]] + [:dispatch [::set-tx-in-progress false]]]})) (re/reg-event-fx @@ -118,20 +116,24 @@ (re/reg-event-fx - ::web3-tx-localstorage - (fn [_db event] (println ">>> ethlance.ui.page.new-invoice.events :web3-tx-localstorage" event))) + ::tx-hash-error + (fn [_cofx _event] + {:fx [[:dispatch [::notification.events/show "Error processing the create invoice transaction"]] + [:dispatch [::set-tx-in-progress false]]]})) (re/reg-event-fx ::send-invoice-tx-success (fn [{:keys [db]} [_event-name ipfs-job _tx-data]] (let [job-story-id (:job-story/id ipfs-job)] - (re/dispatch [::router-events/navigate :route.job/contract {:job-story-id job-story-id}]) - {:dispatch [::notification.events/show "Transaction to create invoice processed successfully"] + {:fx [[:dispatch [::notification.events/show "Transaction to create invoice processed successfully"]] + [:dispatch [::router-events/navigate :route.job/contract {:job-story-id job-story-id}]] + [:dispatch [::set-tx-in-progress false]]] :db (assoc db state-key state-default)}))) -(re/reg-event-db +(re/reg-event-fx ::send-invoice-tx-error - (fn [_db event] - (println ">>> got :create-job-tx-error event:" event))) + (fn [_cofx _event] + {:fx [[:dispatch [::notification.events/show "Error processing the create invoice transaction"]] + [:dispatch [::set-tx-in-progress false]]]})) diff --git a/ui/src/ethlance/ui/page/new_invoice/subscriptions.cljs b/ui/src/ethlance/ui/page/new_invoice/subscriptions.cljs index 4def9a90..7d43eca2 100644 --- a/ui/src/ethlance/ui/page/new_invoice/subscriptions.cljs +++ b/ui/src/ethlance/ui/page/new_invoice/subscriptions.cljs @@ -20,6 +20,7 @@ (re/reg-sub :page.new-invoice/hourly-rate (create-get-handler :hourly-rate)) (re/reg-sub :page.new-invoice/invoice-amount (create-get-handler :invoice-amount)) (re/reg-sub :page.new-invoice/message (create-get-handler :message)) +(re/reg-sub :page.new-invoice/tx-in-progress? (create-get-handler :tx-in-progress?)) (re/reg-sub @@ -53,3 +54,16 @@ (str "Estimated $" (sum-usd) " (1 " (name from-currency) " = " rate " " (name to-currency) ")") :else "")))) + +(re/reg-sub + ::form-fields + (fn [db _] + (select-keys (get db new-invoice.events/state-key) [:invoiced-job :invoice-amount]))) + +(re/reg-sub + :page.new-invoice/validations + :<- [::form-fields] + (fn [{:keys [invoiced-job invoice-amount]}] + {:invoiced-job (not (nil? invoiced-job)) + :invoice-amount (and (not (nil? (get invoice-amount :token-amount))) + (> (:token-amount invoice-amount) 0))}))