diff --git a/src/clj/auto_ap/datomic/users.clj b/src/clj/auto_ap/datomic/users.clj index 1f71939c..bac3ef54 100644 --- a/src/clj/auto_ap/datomic/users.clj +++ b/src/clj/auto_ap/datomic/users.clj @@ -4,23 +4,6 @@ [datomic.api :as dc] [datomic.api :as d])) -(defn add-arg [query name value where & rest] - (let [query (-> query - (update :args conj value) - (update-in [:query :in] conj name) - (update-in [:query :where] conj where))] - (reduce #(update-in %1 [:query :where] conj %2) query rest))) - -(defn get-by-id [id] - (->> [(dc/pull (dc/db conn) - '[* - {:user/clients [*]} - {:user/role [:db/ident]}] - id)] - (map #(update % :user/role :db/ident)) - first)) - - (defn find-or-insert! [{:keys [:user/provider :user/provider-id ] :as new-user}] (let [is-first-user? (not (seq (dc/q [:find '?e :in '$ @@ -43,30 +26,3 @@ user-id) :user/role :db/ident))) -(defn raw-graphql [_] - (->> (dc/q {:find ['(pull ?e [* - {:user/clients [*]} - {:user/role [:db/ident]}])] - :in ['$] - :where ['[?e :user/role]]} - (dc/db conn)) - (map first) - (map #(update % :user/role :db/ident)) - )) - -(defn sort-fn [args] - (cond - (= "client" (:sort-by args)) - #(-> % :payment/client :client/name) - - :else - (keyword "payment" (:sort-by args)))) - -(defn get-graphql [args] - (let [results (raw-graphql args)] - (cond->> results - (:sort-by args) (sort-by (sort-fn args)) - (= (:asc args) false) (reverse) - true (drop (:start args 0)) - true (take (:count args 500))))) - diff --git a/src/clj/auto_ap/graphql.clj b/src/clj/auto_ap/graphql.clj index 7f0498bd..a3501c02 100644 --- a/src/clj/auto_ap/graphql.clj +++ b/src/clj/auto_ap/graphql.clj @@ -1,7 +1,6 @@ (ns auto-ap.graphql (:require [auto-ap.datomic :refer [conn merge-query query2]] - [auto-ap.datomic.users :as d-users] [auto-ap.graphql.accounts :as gq-accounts] [auto-ap.graphql.checks :as gq-checks] [auto-ap.graphql.clients :as gq-clients] @@ -16,7 +15,6 @@ [auto-ap.graphql.sales-orders :as gq-sales-orders] [auto-ap.graphql.transaction-rules :as gq-transaction-rules] [auto-ap.graphql.transactions :as gq-transactions] - [auto-ap.graphql.users :as gq-users] [auto-ap.graphql.utils :refer [assert-admin attach-tracing-resolvers]] [auto-ap.graphql.vendors :as gq-vendors] [auto-ap.graphql.yodlee-merchants :as ym] @@ -353,14 +351,6 @@ :resolve :get-cash-flow} - :account_page {:type :account_page - :args {:name_like {:type 'String} - :numeric_code {:type 'Int} - :start {:type 'Int} - :per_page {:type 'Int} - :sort {:type '(list :sort_item)}} - :resolve :get-accounts} - :all_accounts {:type '(list :account) :args {} :resolve :get-all-accounts} @@ -407,8 +397,7 @@ :per_page {:type 'Int} :sort {:type '(list :sort_item)}} :resolve :get-vendor} - :user {:type '(list :user) - :resolve :get-user} + :vendor_by_id {:type :vendor :args {:id {:type :id}} :resolve :vendor-by-id} @@ -427,12 +416,6 @@ :date_range {:fields {:start {:type :iso_date} :end {:type :iso_date}}} - :edit_user - {:fields {:id {:type :id} - :name {:type 'String} - :role {:type :role} - :clients {:type '(list String)}}} - :add_contact {:fields {:id {:type :id} :name {:type 'String} @@ -574,11 +557,6 @@ :to {:type :id}} :resolve :mutation/merge-vendors} - :edit_user - {:type :user - :args {:edit_user {:type :edit_user}} - :resolve :mutation/edit-user} - :upsert_vendor {:type :vendor :args {:vendor {:type :add_vendor}} @@ -588,11 +566,7 @@ {:type :transaction_rule :args {:transaction_rule {:type :edit_transaction_rule}} :resolve :mutation/upsert-transaction-rule} - - :upsert_account - {:type :account - :args {:account {:type :edit_account}} - :resolve :mutation/upsert-account}}}) + }}) (defn snake->kebab [s] @@ -619,18 +593,6 @@ node)) m)) -(defn get-user [context args _] - (assert-admin (:id context)) - - (let [users (->> (d-users/get-graphql args) - (map (fn [u] - (assoc u :impersonate_jwt - (jwt/sign (auth/user->jwt u "FAKE_TOKEN") - (:jwt-secret env) - {:alg :hs512})))))] - (->graphql users))) - - (defn get-expense-account-stats [_ {:keys [client_id] } _] (let [query (cond-> {:query {:find ['?account '?account-name '(sum ?amount)] @@ -791,7 +753,6 @@ (-> integreat-schema (attach-tracing-resolvers { - :get-accounts gq-accounts/get-graphql :get-all-accounts gq-accounts/get-all-graphql :get-transaction-rule-page gq-transaction-rules/get-transaction-rule-page :get-transaction-rule-matches gq-transaction-rules/get-transaction-rule-matches @@ -802,14 +763,11 @@ :get-intuit-bank-accounts gq-intuit-bank-accounts/get-intuit-bank-accounts :vendor-by-id gq-vendors/get-by-id :account-for-vendor gq-accounts/default-for-vendor - :get-user get-user :mutation/delete-transaction-rule gq-transaction-rules/delete-transaction-rule - :mutation/edit-user gq-users/edit-user :mutation/upsert-transaction-rule gq-transaction-rules/upsert-transaction-rule :test-transaction-rule gq-transaction-rules/test-transaction-rule :run-transaction-rule gq-transaction-rules/run-transaction-rule :mutation/upsert-vendor gq-vendors/upsert-vendor - :mutation/upsert-account gq-accounts/upsert-account :mutation/merge-vendors gq-vendors/merge-vendors :get-vendor gq-vendors/get-graphql :search-vendor gq-vendors/search diff --git a/src/clj/auto_ap/graphql/accounts.clj b/src/clj/auto_ap/graphql/accounts.clj index a9a7d8d3..d2a53263 100644 --- a/src/clj/auto_ap/graphql/accounts.clj +++ b/src/clj/auto_ap/graphql/accounts.clj @@ -18,11 +18,6 @@ [iol-ion.tx :refer [random-tempid]] [com.brunobonacci.mulog :as mu])) -(defn get-graphql [context args _] - (assert-admin (:id context)) - (let [args (assoc args :id (:id context)) - [accounts accounts-count ] (d-accounts/get-graphql (<-graphql args))] - (result->page accounts accounts-count :accounts args))) (defn get-all-graphql [context args _] (assert-admin (:id context)) @@ -35,63 +30,6 @@ (let [result (d-accounts/get-for-vendor (:vendor_id args) (:client_id args))] (->graphql (d-accounts/clientize result (:client_id args))))) -(defn upsert-account [context args _] - (let [{{:keys [id client-overrides numeric-code location applicability account-set name invoice-allowance vendor-allowance type]} :account} (<-graphql args)] - (when-not id - (when (seq (dc/q {:find ['?e] - :in '[$ ?account-set ?numeric-code] - :where ['[?e :account/account-set ?account-set] - '[?e :account/numeric-code ?numeric-code]]} - (dc/db conn) account-set numeric-code)) - - (throw (ex-info (str "Account set " account-set " already has an account for code " numeric-code) - {} )))) - (let [result (audit-transact [[:upsert-entity - (cond-> {:db/id (or id "new-account") - :account/name name - :account/search-terms name - :account/type (keyword "account-type" (clojure.core/name type)) - :account/applicability (or (enum->keyword applicability "account-applicability") - :account-applicability/global) - :account/invoice-allowance (some-> invoice-allowance (enum->keyword "allowance")) - :account/vendor-allowance (some-> vendor-allowance (enum->keyword "allowance")) - :account/default-allowance :allowance/allowed - :account/account-set account-set - :account/location location - :account/numeric-code numeric-code - :account/code (str numeric-code) - :account/client-overrides (mapv - (fn [client-override] - {:db/id (or (:id client-override) (random-tempid)) - :account-client-override/client (:client-id client-override) - :account-client-override/name (:name client-override) - :account-client-override/search-terms (:name client-override)}) - client-overrides)} - id (dissoc :account/numeric-code :account/code))]] - (:id context)) - updated-account (d-accounts/get-by-id (or id (get-in result [:tempids "new-account"])))] - (mu/log ::account-updated :account updated-account) - (solr/index-documents-raw solr/impl - "accounts" - (into [{"id" (:db/id updated-account) - "account_id" (:db/id updated-account) - "name" (:account/name updated-account) - "numeric_code" (:account/numeric-code updated-account) - "location" (:account/location updated-account) - "applicability" (clojure.core/name (:account/applicability updated-account))}] - (for [o (:account/client-overrides updated-account)] - {"id" (:db/id o) - "account_id" (:db/id updated-account) - "name" (:account-client-override/name o) - "numeric_code" (:account/numeric-code updated-account) - "location" (:account/location updated-account) - "applicability" (clojure.core/name (:account/applicability updated-account)) - "client_id" (:db/id (:account-client-override/client o)) - "account_client_override_id" (:db/id o)})) - ) - (->graphql - updated-account)))) - (def search-pattern [:db/id :account/numeric-code :account/location @@ -207,17 +145,3 @@ "numeric_code" (:account/numeric-code result) "location" (:account/location result) "applicability" (name (:db/ident (:account/applicability result)))}))) - -#_(dc/transact conn - [{:db/ident :account-client-override/k2 - :db/valueType :db.type/tuple - :db/tupleAttrs [:account/_client-overrides :account-client-override/client ] - :db/cardinality :db.cardinality/one - :db/unique :db.unique/identity}]) - -#_(dc/q '[:find ?o - :where [_ :account-client-override/k ?o]] - (dc/db conn)) - - -#_(dc/pull (dc/db conn) '[*] [:db/ident :account-client-override/k]) diff --git a/src/clj/auto_ap/graphql/users.clj b/src/clj/auto_ap/graphql/users.clj deleted file mode 100644 index 05ec720d..00000000 --- a/src/clj/auto_ap/graphql/users.clj +++ /dev/null @@ -1,28 +0,0 @@ -(ns auto-ap.graphql.users - (:require [auto-ap.datomic :refer [audit-transact]] - [auto-ap.datomic.users :as d-users] - [auto-ap.graphql.utils :refer [->graphql assert-admin]])) - -(def role->datomic-role {:none :user-role/none - :admin :user-role/admin - :power_user :user-role/power-user - :manager :user-role/manager - :user :user-role/user}) - -(defn edit-user [context {:keys [edit_user]} _] - (assert-admin (:id context)) - (let [user (d-users/get-by-id (:id edit_user)) - new-clients (set (map #(Long/parseLong %) (:clients edit_user))) - clients-to-remove (->> (:user/clients user) - (map :db/id) - (filter #(not (new-clients %)) ))] - - - (audit-transact (-> [{:db/id (:db/id user) - :user/role (role->datomic-role (:role edit_user)) - :user/clients new-clients}] - (into (map (fn [c] [:db/retract (:db/id user) :user/clients c]) clients-to-remove))) - (:id context)) - (->graphql - (d-users/get-by-id (:id edit_user))))) - diff --git a/src/clj/auto_ap/ssr/admin/accounts.clj b/src/clj/auto_ap/ssr/admin/accounts.clj index a28e23df..f87fa63f 100644 --- a/src/clj/auto_ap/ssr/admin/accounts.clj +++ b/src/clj/auto_ap/ssr/admin/accounts.clj @@ -4,6 +4,7 @@ :refer [add-sorter-fields apply-pagination apply-sort-3 + audit-transact conn merge-query pull-many @@ -11,6 +12,7 @@ [auto-ap.query-params :as query-params] [auto-ap.routes.utils :refer [wrap-admin wrap-client-redirect-unauthenticated]] + [auto-ap.solr :as solr] [auto-ap.ssr-routes :as ssr-routes] [auto-ap.ssr.components :as com] [auto-ap.ssr.grid-page-helper :as helper] @@ -31,6 +33,7 @@ [malli.core :as mc] [ring.middleware.nested-params :refer [wrap-nested-params]])) +;; TODO support for new account (defn filters [request] [:form {"hx-trigger" "change delay:500ms, keyup changed from:.hot-filter delay:1000ms" "hx-get" (bidi/path-for ssr-routes/only-routes @@ -168,13 +171,33 @@ (def table* (partial helper/table* grid-page)) (defn account-edit-save [{:keys [params route-params] :as request}] - (let [_ @(dc/transact conn [[:upsert-entity (-> params (assoc :db/id (:db/id route-params)) (dissoc :id))]]) - new-account (some-> route-params :db/id (#(dc/pull (dc/db conn) default-read %)))] - + (let [_ (audit-transact [[:upsert-entity (-> params (assoc :db/id (:db/id route-params)) (dissoc :id))]] + (:identity request)) + updated-account (some-> route-params :db/id (#(dc/pull (dc/db conn) default-read %)))] + + (solr/index-documents-raw solr/impl + "accounts" + (into [{"id" (:db/id updated-account) + "account_id" (:db/id updated-account) + "name" (:account/name updated-account) + "numeric_code" (:account/numeric-code updated-account) + "location" (:account/location updated-account) + "applicability" (clojure.core/name (:account/applicability updated-account))}] + (for [o (:account/client-overrides updated-account)] + {"id" (:db/id o) + "account_id" (:db/id updated-account) + "name" (:account-client-override/name o) + "numeric_code" (:account/numeric-code updated-account) + "location" (:account/location updated-account) + "applicability" (clojure.core/name (:account/applicability updated-account)) + "client_id" (:db/id (:account-client-override/client o)) + "account_client_override_id" (:db/id o)})) + ) + (html-response - (row* identity new-account {:flash? true}) + (row* identity updated-account {:flash? true}) :headers {"hx-trigger" "closeModal" - "hx-retarget" (format "#account-table tr[data-id=\"%d\"]" (:db/id new-account))}))) + "hx-retarget" (format "#account-table tr[data-id=\"%d\"]" (:db/id updated-account))}))) (defn client-override* [override] [:div.flex.gap-2.mb-2.client-override @@ -194,10 +217,7 @@ (defn account-edit-dialog [request] (prn (:route-params request)) - (let [account (some-> request - :route-params - :db/id - (#(dc/pull (dc/db conn) default-read %)))] + (let [account (some-> request :route-params :db/id (#(dc/pull (dc/db conn) default-read %)))] (html-response (com/modal {:modal-class "max-w-4xl"} diff --git a/src/cljc/auto_ap/shared_views/admin/side_bar.cljc b/src/cljc/auto_ap/shared_views/admin/side_bar.cljc index fc4256d1..1d2a0d20 100644 --- a/src/cljc/auto_ap/shared_views/admin/side_bar.cljc +++ b/src/cljc/auto_ap/shared_views/admin/side_bar.cljc @@ -50,7 +50,7 @@ :route :admin-vendors}) (menu-item {:label "Users" :icon-class "icon icon-single-neutral-book" - :test-route #{:admin-users} + :test-route #{:users} :active-route active-route :route :users :icon-style {:font-size "25px"}}) diff --git a/src/cljs/auto_ap/views/main.cljs b/src/cljs/auto_ap/views/main.cljs index b98ddb68..e0963e87 100644 --- a/src/cljs/auto_ap/views/main.cljs +++ b/src/cljs/auto_ap/views/main.cljs @@ -24,13 +24,10 @@ [auto-ap.views.pages.admin :refer [admin-page]] [auto-ap.views.pages.home :refer [home-page]] [auto-ap.views.pages.admin.clients :refer [admin-clients-page]] - [auto-ap.views.pages.admin.accounts :refer [admin-accounts-page]] [auto-ap.views.pages.admin.rules :refer [admin-rules-page]] [auto-ap.views.pages.admin.vendors :refer [admin-vendors-page]] [auto-ap.views.pages.admin.excel-import :refer [admin-excel-import-page]] - [auto-ap.views.pages.admin.users :refer [admin-users-page]] [auto-ap.views.pages.admin.import-batches :refer [import-batches-page]] - [auto-ap.views.pages.company.yodlee2 :as yodlee2] [auto-ap.views.pages.company.other :as company-other])) (defmulti page (fn [active-page] active-page)) @@ -109,9 +106,6 @@ (defmethod page :admin-rules [_] (admin-rules-page)) -(defmethod page :admin-users [_] - (admin-users-page)) - (defmethod page :admin-vendors [_] (admin-vendors-page)) @@ -121,15 +115,10 @@ (defmethod page :admin-jobs [_] [jobs-page]) -(defmethod page :yodlee2 [_] - (yodlee2/admin-yodlee-provider-accounts-page)) (defmethod page :company-other [_] (company-other/company-other-page)) -(defmethod page :admin-accounts [_] - (admin-accounts-page)) - (defmethod page :index [_] (home-page) ) diff --git a/src/cljs/auto_ap/views/pages/admin/accounts.cljs b/src/cljs/auto_ap/views/pages/admin/accounts.cljs deleted file mode 100644 index d821b3ee..00000000 --- a/src/cljs/auto_ap/views/pages/admin/accounts.cljs +++ /dev/null @@ -1,85 +0,0 @@ -(ns auto-ap.views.pages.admin.accounts - (:require - [auto-ap.effects.forward :as forward] - [auto-ap.forms :as forms] - [auto-ap.shared-views.admin.side-bar :refer [admin-side-bar]] - [auto-ap.views.components.buttons :as buttons] - [auto-ap.views.components.layouts - :refer [appearing-side-bar side-bar-layout]] - [auto-ap.views.pages.admin.accounts.form :as account-form] - [auto-ap.views.pages.admin.accounts.side-bar :as side-bar] - [auto-ap.views.pages.admin.accounts.table :as table] - [auto-ap.views.pages.data-page :as data-page] - [auto-ap.views.utils :refer [with-user]] - [clojure.set :as set] - [re-frame.core :as re-frame] - [reagent.core :as reagent] - [vimsical.re-frame.fx.track :as track])) - -(def default-read [:numeric-code :name :location :type :account_set :applicability :invoice-allowance :vendor-allowance :id [:client-overrides [:id :name [:client [:name :id]]]]]) - - - -(re-frame/reg-event-fx - ::params-change - [with-user] - (fn [{:keys [user]} [_ params]] - {:set-uri-params params - :graphql {:token user - :owns-state {:single [::data-page/page ::page]} - :query-obj {:venia/queries [{:query/data [:account_page - {:sort (:sort params) - :start (:start params 0) - :per-page (:per-page params) - :name-like (:name-like params) - :numeric-code (some-> params :numeric-code not-empty js/parseInt (#(if (js/Number.isNaN %) nil %)))} - [[:accounts default-read] - :total - :start - :end]] - :query/alias :result}]} - :on-success (fn [result] - [::data-page/received ::page - (set/rename-keys (:result result) - {:accounts :data})])}})) - - -(re-frame/reg-event-fx - ::unmounted - (fn [_ _] - {::track/dispose {:id ::params} - ::forward/dispose [{:id ::updated}]})) - -(re-frame/reg-event-fx - ::mounted - (fn [_ _] - {::track/register {:id ::params - :subscription [::data-page/params ::page] - :event-fn (fn [params] [::params-change params])} - ::forward/register [{:id ::updated - :events #{::account-form/edited} - :event-fn (fn [[_ edited-account]] - [::data-page/updated-entity ::page (:upsert-account edited-account)])}]})) - -(defn admin-accounts-content [] - [:div - [:h1.title "Accounts"] - [:div.is-pulled-right - [buttons/new-button {:name "Account" - :class "is-primary" - :event [::account-form/editing - {:account-set "default"}]}]] - [table/accounts-table {:data-page ::page}]]) - -(defn admin-accounts-page [] - (reagent/create-class - {:display-name "accounts-page" - :component-will-unmount #(re-frame/dispatch [::unmounted]) - :component-did-mount #(re-frame/dispatch [::mounted]) - :reagent-render - (fn [] - (let [{:keys [active?]} @(re-frame/subscribe [::forms/form ::account-form/form])] - [side-bar-layout {:side-bar [admin-side-bar {} - [side-bar/accounts-side-bar {:data-page ::page}]] - :main [admin-accounts-content] - :right-side-bar [appearing-side-bar {:visible? active?} [account-form/form ]]}]))})) diff --git a/src/cljs/auto_ap/views/pages/admin/accounts/form.cljs b/src/cljs/auto_ap/views/pages/admin/accounts/form.cljs deleted file mode 100644 index 4e95721a..00000000 --- a/src/cljs/auto_ap/views/pages/admin/accounts/form.cljs +++ /dev/null @@ -1,168 +0,0 @@ -(ns auto-ap.views.pages.admin.accounts.form - (:require - [auto-ap.forms :as forms] - [auto-ap.forms.builder :as form-builder] - [auto-ap.schema :as schema] - [auto-ap.subs :as subs] - [auto-ap.views.components :as com] - [auto-ap.views.components.layouts :refer [side-bar]] - [auto-ap.views.components.typeahead :refer [typeahead-v3]] - [auto-ap.views.utils :refer [dispatch-event with-user]] - [clojure.string :as str] - [malli.core :as m] - [re-frame.core :as re-frame] - [vimsical.re-frame.cofx.inject :as inject])) - -(def types [:dividend :expense :asset :liability :equity :revenue]) -(def applicabilities [:global :optional :customized]) -(def allowances [:allowed :denied :warn :admin-only]) - -(re-frame/reg-sub - ::request - :<- [::forms/form ::form] - (fn [{{:keys [id location type client-overrides applicability invoice-allowance vendor-allowance numeric-code name account-set]} :data}] - {:id id - :type (keyword type) - :applicability (keyword applicability) - :invoice-allowance (keyword invoice-allowance) - :vendor-allowance (keyword vendor-allowance) - :location (if (clojure.string/blank? location) - nil - location) - :numeric-code (js/parseInt numeric-code) - :name name - :account-set account-set - :client-overrides (map (fn [client-override] - {:id (:id client-override) - :client-id (:id (:client client-override)) - :name (if (str/blank? (:name client-override)) - nil - (:name client-override))}) - client-overrides)})) - - - -(re-frame/reg-event-db - ::editing - (fn [db [_ which complete-listener]] - (-> db - (forms/start-form ::form which complete-listener)))) - -(re-frame/reg-event-fx - ::edited - [(forms/triggers-saved ::form :upsert-account)] - (fn [_ [_ _]])) - - -(re-frame/reg-event-fx - ::saving - [with-user (re-frame/inject-cofx ::inject/sub [::request]) ] - (fn [{:keys [user] ::keys [request]} _] - (let [_ @(re-frame/subscribe [::forms/form ::form])] - {:graphql - {:owns-state {:single ::form} - :token user - :query-obj {:venia/operation {:operation/type :mutation - :operation/name "UpsertAccount"} - :venia/queries [{:query/data [:upsert-account - {:account request} - [:id :type :name :account-set :numeric-code :location :applicability :invoice-allowance :vendor-allowance [:client-overrides [:name :id [:client [:id :name]]]]]]}]} - :on-success [::edited] - :on-error [::forms/save-error ::form]}}))) - -(def account-customization-schema - (m/schema - [:map [:client schema/reference] - [:name schema/not-empty-string]])) - -(def account-schema - (m/schema - [:map - [:numeric-code schema/integer-code] - [:name schema/not-empty-string] - [:type [:enum :dividend :expense :asset :liability :equity :revenue]] - [:location {:optional true} [:maybe :string]] - [:applicability [:enum :global :optional :customized]] - [:invoice-allowance [:enum :allowed :denied :warn :admin-only]] - [:vendor-allowance [:enum :allowed :denied :warn :admin-only]] - [:client-overrides {:optional true} - [:maybe [:sequential account-customization-schema]]]])) - -(defn form [_] - (let [{account :data } @(re-frame/subscribe [::forms/form ::form])] - [side-bar {:on-close (dispatch-event [::forms/form-closing ::form])} - [form-builder/builder {:change-event [::forms/change ::form] - :submit-event [::saving] - :id ::form - :schema account-schema} - [form-builder/section {:title (if (:id account) - "Edit account" - "Add account")} - [form-builder/field-v2 {:field :numeric-code} - "Code" - [com/number-input - {:disabled (boolean (:id account)) - :auto-focus (not (boolean (:id account))) - :style {:width "9em"}}]] - - [form-builder/field-v2 {:field :name} - "Name" - [:input.input {:type "text" - :auto-focus (boolean (:id account))}]] - - [form-builder/field-v2 {:field :type} - "Account Type" - [com/select-field {:options (map (fn [l] - [l (str/capitalize (name l))]) - types) - :allow-nil? true - :keywordize? true}]] - - - [form-builder/field-v2 {:field :location} - "Location" - [:input.input.known-field.location {:type "text"}]] - - [form-builder/field-v2 {:field :invoice-allowance} - "Invoice Allowance" - [com/select-field {:options (map (fn [l] - [l - (str/capitalize (name l))]) - allowances) - :allow-nil? true - :keywordize? true}]] - - [form-builder/field-v2 {:field :vendor-allowance} - "Vendor Allowance" - [com/select-field {:options (map (fn [l] - [l - (str/capitalize (name l))]) - allowances) - :allow-nil? true - :keywordize? true}]] - - [form-builder/section {:title "Client"} - [:h2.subtitle "Client"] - [form-builder/field-v2 {:field :applicability} - "Applicability" - [com/select-field {:options (map (fn [l] - [l - (str/capitalize (name l))]) - applicabilities) - :allow-nil? true - :keywordize? true}]] - [form-builder/field-v2 {:field :client-overrides} - "Customizations" - [com/multi-field-v2 {:template [[form-builder/raw-field-v2 {:field :client} - [typeahead-v3 {:entities @(re-frame/subscribe [::subs/clients]) - :style {:width "13em"} - :entity->text :name}]] - [form-builder/raw-field-v2 {:field :name} - [:input.input {:type "text" - :style {:width "15em"} - :placeholder "Bubblegum"}]]] - :key-fn :id - :schema [:sequential account-customization-schema]}]]] - [form-builder/error-notification] - - [form-builder/submit-button "Save"]]]])) diff --git a/src/cljs/auto_ap/views/pages/admin/accounts/side_bar.cljs b/src/cljs/auto_ap/views/pages/admin/accounts/side_bar.cljs deleted file mode 100644 index dc07b107..00000000 --- a/src/cljs/auto_ap/views/pages/admin/accounts/side_bar.cljs +++ /dev/null @@ -1,23 +0,0 @@ -(ns auto-ap.views.pages.admin.accounts.side-bar - (:require - [auto-ap.views.pages.data-page :as data-page] - [auto-ap.views.utils :refer [dispatch-value-change]] - [re-frame.core :as re-frame])) - -(defn accounts-side-bar [{:keys [data-page]}] - [:div - [:p.menu-label "Name"] - - [:div.field - [:div.control [:input.input {:placeholder "Food Cost" - :value @(re-frame/subscribe [::data-page/filter data-page :name-like]) - :on-change (dispatch-value-change [::data-page/filter-changed data-page :name-like])} ]]] - - [:p.menu-label "Code"] - - [:div.field - [:div.control [:input.input {:placeholder "11000" - :value @(re-frame/subscribe [::data-page/filter data-page :numeric-code]) - :on-change (dispatch-value-change [::data-page/filter-changed data-page :numeric-code])}]]]]) - - diff --git a/src/cljs/auto_ap/views/pages/admin/accounts/table.cljs b/src/cljs/auto_ap/views/pages/admin/accounts/table.cljs deleted file mode 100644 index 4ae1d38f..00000000 --- a/src/cljs/auto_ap/views/pages/admin/accounts/table.cljs +++ /dev/null @@ -1,36 +0,0 @@ -(ns auto-ap.views.pages.admin.accounts.table - (:require - [auto-ap.views.components.buttons :as buttons] - [auto-ap.views.components.grid :as grid] - [auto-ap.views.pages.admin.accounts.form :as account-form] - [auto-ap.views.pages.data-page :as data-page] - [auto-ap.views.utils :refer [action-cell-width]] - [re-frame.core :as re-frame])) - -(defn accounts-table [{:keys [data-page]}] - (let [{:keys [data]} @(re-frame/subscribe [::data-page/page data-page])] - - [:div - [grid/grid {:data-page data-page - :column-count 5} - [grid/controls data] - [grid/table {:fullwidth true} - [grid/header - [grid/row {} - [grid/header-cell {} "Code"] - [grid/header-cell {} "Name"] - [grid/header-cell {} "Type"] - [grid/header-cell {} "Location"] - [grid/header-cell {:style {:width (action-cell-width 1)}}]]] - [grid/body - (for [{:keys [id numeric-code name type location] :as account} (:data data)] - ^{:key id} - [grid/row {:class (:class account) :id id} - [grid/cell {} numeric-code] - [grid/cell {} name] - [grid/cell {} type] - [grid/cell {} location] - [grid/cell {} - [buttons/fa-icon {:event [::account-form/editing account [::edit-completed]] - :icon "fa-pencil"}]]])]] - [grid/bottom-paginator data]]])) diff --git a/src/cljs/auto_ap/views/pages/admin/users.cljs b/src/cljs/auto_ap/views/pages/admin/users.cljs deleted file mode 100644 index 6b811900..00000000 --- a/src/cljs/auto_ap/views/pages/admin/users.cljs +++ /dev/null @@ -1,91 +0,0 @@ -(ns auto-ap.views.pages.admin.users - (:require - [auto-ap.effects.forward :as forward] - [auto-ap.status :as status] - [auto-ap.utils :refer [replace-by]] - [auto-ap.shared-views.admin.side-bar :refer [admin-side-bar]] - [auto-ap.views.components.grid :as grid] - [auto-ap.views.components.layouts :refer [side-bar-layout]] - [auto-ap.views.pages.admin.users.form :as form] - [auto-ap.views.pages.admin.users.table :as table] - [re-frame.core :as re-frame] - [reagent.core :as reagent])) - -(re-frame/reg-sub - ::params - :<- [::table/params] - (fn [table-params] - table-params)) - -(re-frame/reg-sub - ::users - (fn [db] - (::users db))) - -(re-frame/reg-sub - ::page - :<- [::params] - :<- [::users] - (fn [[params all-users]] - (assoc (grid/virtual-paginate-controls (:start params ) (:per-page params) all-users ) - :data (grid/virtual-paginate (:start params) (:per-page params) all-users)))) - -(re-frame/reg-event-fx - ::mounted - (fn [{:keys [db]} _] - {:graphql {:token (:user db) - :owns-state {:single ::page} - :query-obj {:venia/queries [[:user - [:name - :profile_image_url - :email - :impersonate_jwt - :id - :role - [:clients [:id :name]]]]]} - :on-success [::received]} - ::forward/register {:id ::edited-user - :events #{::form/saved} - :event-fn (fn [[_ query-result]] - [::saved query-result])}})) - -(re-frame/reg-event-fx - ::unmounted - (fn [_ _] - {::forward/dispose {:id ::edited-user}})) - - -(re-frame/reg-event-db - ::saved - (fn [db [_ query-result]] - (-> db - (update ::users - replace-by - :id - (assoc (:edit-user query-result) :class "live-added"))))) - -(re-frame/reg-event-db - ::received - (fn [db [_ d]] - (assoc-in db [::users] (:user d)))) - - -(defn users-table [] - [table/table {:page @(re-frame/subscribe [::page]) - :status @(re-frame/subscribe [::status/single ::page])}]) - - -(defn admin-users-content [] - [:div - [:h1.title "Users"] - [users-table]]) - - -(defn admin-users-page [] - (reagent/create-class - {:component-will-unmount #(re-frame/dispatch [::unmounted]) - :component-did-mount #(re-frame/dispatch [::mounted]) - :reagent-render (fn [] - [side-bar-layout {:side-bar [admin-side-bar {}] - :main [admin-users-content]}])})) - diff --git a/src/cljs/auto_ap/views/pages/admin/users/form.cljs b/src/cljs/auto_ap/views/pages/admin/users/form.cljs deleted file mode 100644 index 8516a9b0..00000000 --- a/src/cljs/auto_ap/views/pages/admin/users/form.cljs +++ /dev/null @@ -1,105 +0,0 @@ -(ns auto-ap.views.pages.admin.users.form - (:require - [auto-ap.forms :as forms] - [auto-ap.forms.builder :as form-builder] - [auto-ap.schema :as schema] - [auto-ap.status :as status] - [auto-ap.subs :as subs] - [auto-ap.views.components :as com] - [auto-ap.views.components.modal :as modal] - [auto-ap.views.utils :refer [dispatch-event with-user]] - [malli.core :as m] - [re-frame.core :as re-frame])) - -(def client-schema - (m/schema [:map [:client schema/reference]])) - -(def user-schema - (m/schema - [:map - [:name schema/not-empty-string] - [:role [:enum :none :user :manager :power_user :admin]] - [:clients {:optional true} - [:maybe - [:sequential client-schema]]]])) - -(re-frame/reg-event-fx - ::saving - [with-user (forms/in-form ::form)] - (fn [{:keys [db user]} [_]] - (if (m/validate user-schema (:data db)) - {:graphql - {:token user - :owns-state {:single ::form} - :query-obj {:venia/operation {:operation/type :mutation - :operation/name "EditUser"} - :venia/queries [{:query/data [:edit-user - {:edit-user (-> (:data db) - (update :clients #(map (comp :id :client) %)) - (select-keys #{:id :name :clients :role}))} - [:id :name :role [:clients [:id :name]]]]}]} - :on-success [::saved]}} - - {:dispatch-n [[::forms/attempted-submit ::form] - [::status/error ::form [{:message "Please fix the errors and try again."}]]]}) - )) - -(re-frame/reg-event-fx - ::saved - (forms/triggers-stop ::form) - (fn [_ _] - {:dispatch [::modal/modal-closed]})) - - - - - -(defn form [] - (let [{:keys [data]} @(re-frame/subscribe [::forms/form ::form]) - clients @(re-frame/subscribe [::subs/clients])] - [:<> - [form-builder/builder {:submit-event [::saving] - :id ::form - :schema user-schema} - [form-builder/field-v2 {:required? true - :field :name} - "Name" - [:input.input {:type "text"}]] - [form-builder/field-v2 {:required? true - :field :role} - "Role" - [com/select-field {:options [[:none "None"] - [:user "User"] - [:manager "Manager"] - [:power_user "Power User"] - [:admin "Admin"]] - :allow-nil? false - :keywordize? true}]] - [form-builder/field-v2 {:field :clients} - (if (= :admin (:role data)) - "Client Assignments" - "Client") - [com/multi-field-v2 {:template [[form-builder/raw-field-v2 {:field :client} - [com/entity-typeahead - {:entities clients - :entity->text :name - :style {:width "13em"}}]]] - :key-fn :id - :schema [:sequential client-schema] - :new-text "Grant access to client"}]] - - [form-builder/hidden-submit-button]]])) - -(re-frame/reg-event-fx - ::editing - (fn [{:keys [db]} [_ d]] - {:db (-> db - (forms/start-form ::form (update d :clients #(mapv (fn [x] {:client x :id (random-uuid)}) %)))) - :dispatch [::modal/modal-requested {:title (str "Edit user " (:name d)) - :body [form] - :cancel? false - :confirm {:value "Save" - :status-from [::status/single ::form] - :class "is-primary" - :on-click (dispatch-event [::saving]) - :close-event [::status/completed ::form]}}]})) diff --git a/src/cljs/auto_ap/views/pages/admin/users/table.cljs b/src/cljs/auto_ap/views/pages/admin/users/table.cljs deleted file mode 100644 index a29209d4..00000000 --- a/src/cljs/auto_ap/views/pages/admin/users/table.cljs +++ /dev/null @@ -1,78 +0,0 @@ -(ns auto-ap.views.pages.admin.users.table - (:require - [auto-ap.views.components.buttons :as buttons] - [auto-ap.views.components.grid :as grid] - [auto-ap.views.pages.admin.users.form :as form] - [auto-ap.views.utils - :refer [action-cell-width dispatch-event with-user]] - [clojure.string :as str] - [re-frame.core :as re-frame])) - -(re-frame/reg-event-fx - ::impersonated - (fn [_ [_ impersonate-jwt]] - (println "SUCCESED") - (.setItem js/localStorage "jwt" impersonate-jwt) - (.removeItem js/localStorage "last-client-id" nil) - (.removeItem js/localStorage "last-selected-clients" nil) - (.reload (.-location js/document ) true) - {})) - -(re-frame/reg-event-fx - ::impersonate - [with-user] - (fn [{:keys [db user]} [_ impersonate-jwt]] - {:http {:method "GET" - :uri (str "/impersonate?jwt=" impersonate-jwt) - :on-success [::impersonated impersonate-jwt]}})) - -(re-frame/reg-event-fx - ::params-changed - (fn [{:keys [db]} [_ p]] - {:db (assoc db ::params p)})) - -(re-frame/reg-sub - ::params - (fn [db] - (-> db ::params))) - -(defn table [{:keys [status page]}] - (let [params @(re-frame/subscribe [::params])] - [grid/grid {:status status - :on-params-change (fn [p] - (re-frame/dispatch [::params-changed p])) - :params params - :column-count 4} - [grid/controls page] - [grid/table {:fullwidth true} - [grid/header - [grid/row {} - [grid/header-cell {} "User"] - [grid/header-cell {} "Email"] - [grid/header-cell {} "Role"] - [grid/header-cell {} "Clients"] - [grid/header-cell {:style {:width (action-cell-width 5)}}]]] - [grid/body - (for [{:keys [id name role clients] :as c} (:data page)] - ^{:key (str name "-" id)} - [grid/row {:class (:class c) :id id} - [grid/cell {} - [:div.level - [:div.level-left - (when-let [url (:profile-image-url c)] - [:div.level-item - [:figure.image.is-24x24 - [:img.is-rounded {:src url - :referrer-policy= "no-referrer"}]]]) - [:div.level-item name]]]] - [grid/cell {} (:email c)] - [grid/cell {} role] - [grid/cell {} (str/join ", " (map :name clients))] - [grid/cell {} - [:a.button {:on-click (dispatch-event [::impersonate (:impersonate-jwt c)])} - "Impersonate"] - - - [buttons/fa-icon {:event [::form/editing c] - :icon "fa-pencil"}]]])]] - ])) diff --git a/test/clj/auto_ap/integration/graphql/users.clj b/test/clj/auto_ap/integration/graphql/users.clj index 2e47e4e3..b50df7bf 100644 --- a/test/clj/auto_ap/integration/graphql/users.clj +++ b/test/clj/auto_ap/integration/graphql/users.clj @@ -2,7 +2,6 @@ (:require [auto-ap.time-reader] [auto-ap.datomic :refer [conn uri]] - [auto-ap.graphql.users :as sut] [auto-ap.integration.util :refer [admin-token user-token wrap-setup]] [clojure.test :as t :refer [deftest is testing use-fixtures]] [com.brunobonacci.mulog :as mu] @@ -11,7 +10,7 @@ (use-fixtures :each wrap-setup) -(deftest edit-user +#_(deftest edit-user (testing "should allow editing a user"