makes client selection not contanimate other tabs
This commit is contained in:
@@ -8,6 +8,15 @@ document.addEventListener('alpine:init', () => {
|
|||||||
el.removeEventListener('htmx:configRequest', config);
|
el.removeEventListener('htmx:configRequest', config);
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
Alpine.directive('hx-header', (el, { value, expression }, { evaluateLater, effect, cleanup, evaluate }) => {
|
||||||
|
var config = function(evt) {
|
||||||
|
evt.detail.headers[value] = evaluate(expression); // add a new parameter into the request
|
||||||
|
}
|
||||||
|
el.addEventListener('htmx:configRequest', config);
|
||||||
|
cleanup(() => {
|
||||||
|
el.removeEventListener('htmx:configRequest', config);
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
Alpine.directive('dispatch', (el, { value, expression }, { evaluateLater, effect, cleanup, evaluate }) => {
|
Alpine.directive('dispatch', (el, { value, expression }, { evaluateLater, effect, cleanup, evaluate }) => {
|
||||||
let dependent_properties = evaluateLater(expression)
|
let dependent_properties = evaluateLater(expression)
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
(:require [amazonica.core :refer [defcredential]]
|
(:require [amazonica.core :refer [defcredential]]
|
||||||
[auto-ap.client-routes :as client-routes]
|
[auto-ap.client-routes :as client-routes]
|
||||||
[auto-ap.datomic :refer [conn pull-many]]
|
[auto-ap.datomic :refer [conn pull-many]]
|
||||||
[auto-ap.datomic.clients :as d-clients]
|
|
||||||
[auto-ap.graphql.utils :refer [assert-can-see-client
|
[auto-ap.graphql.utils :refer [assert-can-see-client
|
||||||
limited-clients]]
|
limited-clients]]
|
||||||
[auto-ap.logging :as alog]
|
[auto-ap.logging :as alog]
|
||||||
@@ -16,6 +15,7 @@
|
|||||||
[auto-ap.routes.yodlee2 :as yodlee2]
|
[auto-ap.routes.yodlee2 :as yodlee2]
|
||||||
[auto-ap.ssr-routes :as ssr-routes]
|
[auto-ap.ssr-routes :as ssr-routes]
|
||||||
[auto-ap.ssr.core :as ssr]
|
[auto-ap.ssr.core :as ssr]
|
||||||
|
[auto-ap.ssr.utils :refer [entity-id main-transformer]]
|
||||||
[bidi.bidi :as bidi]
|
[bidi.bidi :as bidi]
|
||||||
[bidi.ring :refer [->ResourcesMaybe make-handler]]
|
[bidi.ring :refer [->ResourcesMaybe make-handler]]
|
||||||
[buddy.auth.backends.session :refer [session-backend]]
|
[buddy.auth.backends.session :refer [session-backend]]
|
||||||
@@ -26,13 +26,14 @@
|
|||||||
[cheshire.core :as cheshire]
|
[cheshire.core :as cheshire]
|
||||||
[clj-time.coerce :as coerce]
|
[clj-time.coerce :as coerce]
|
||||||
[clj-time.core :as time]
|
[clj-time.core :as time]
|
||||||
[clojure.edn :as edn]
|
[clojure.data.json :as json]
|
||||||
[clojure.set :as set]
|
[clojure.set :as set]
|
||||||
[clojure.string :as str]
|
[clojure.string :as str]
|
||||||
[com.brunobonacci.mulog :as mu]
|
[com.brunobonacci.mulog :as mu]
|
||||||
[config.core :refer [env]]
|
[config.core :refer [env]]
|
||||||
[datomic.api :as dc]
|
[datomic.api :as dc]
|
||||||
[hiccup2.core :as hiccup]
|
[hiccup2.core :as hiccup]
|
||||||
|
[malli.core :as mc]
|
||||||
[ring.middleware.edn :refer [wrap-edn-params]]
|
[ring.middleware.edn :refer [wrap-edn-params]]
|
||||||
[ring.middleware.multipart-params :as mp]
|
[ring.middleware.multipart-params :as mp]
|
||||||
[ring.middleware.params :refer [wrap-params]]
|
[ring.middleware.params :refer [wrap-params]]
|
||||||
@@ -110,10 +111,10 @@
|
|||||||
uri
|
uri
|
||||||
:request-method request-method))
|
:request-method request-method))
|
||||||
matched-hx-current-url-route (some->> (get headers "hx-current-url")
|
matched-hx-current-url-route (some->> (get headers "hx-current-url")
|
||||||
url/url
|
url/url
|
||||||
:path
|
:path
|
||||||
(bidi/match-route ssr-routes/only-routes)
|
(bidi/match-route ssr-routes/only-routes)
|
||||||
:handler)]
|
:handler)]
|
||||||
(handler (assoc request
|
(handler (assoc request
|
||||||
:matched-route
|
:matched-route
|
||||||
matched-route
|
matched-route
|
||||||
@@ -135,6 +136,7 @@
|
|||||||
(:uri request)
|
(:uri request)
|
||||||
:request-method (:request-method request)))
|
:request-method (:request-method request)))
|
||||||
|
|
||||||
|
:client-selection (:client-selection request)
|
||||||
:source "request"
|
:source "request"
|
||||||
:query (:uri request)
|
:query (:uri request)
|
||||||
:request-method (:request-method request)
|
:request-method (:request-method request)
|
||||||
@@ -185,10 +187,17 @@
|
|||||||
request (assoc request :hx-query-params query-params)]
|
request (assoc request :hx-query-params query-params)]
|
||||||
(handler request))))
|
(handler request))))
|
||||||
|
|
||||||
|
(def client-selection-schema
|
||||||
|
(mc/schema
|
||||||
|
[:orn
|
||||||
|
[:global [:enum :all :mine]]
|
||||||
|
[:group-name [:map [:group :string]]]
|
||||||
|
[:specific [:map [:selected [:vector entity-id]]]]]))
|
||||||
|
|
||||||
(defn wrap-hydrate-clients
|
(defn wrap-hydrate-clients
|
||||||
[handler]
|
[handler]
|
||||||
(fn [request]
|
(fn [request]
|
||||||
(let [x-clients (-> request :session :client-selection)
|
(let [x-clients (-> request :client-selection)
|
||||||
identity (or (-> request :identity)
|
identity (or (-> request :identity)
|
||||||
(-> request :session :identity))
|
(-> request :session :identity))
|
||||||
ideal-ids (set (cond
|
ideal-ids (set (cond
|
||||||
@@ -202,28 +211,21 @@
|
|||||||
(= :mine x-clients)
|
(= :mine x-clients)
|
||||||
(map :db/id (:user/clients identity))
|
(map :db/id (:user/clients identity))
|
||||||
|
|
||||||
(= :group (first x-clients))
|
(:group x-clients)
|
||||||
(->>
|
(->>
|
||||||
(dc/q '[:find ?c
|
(dc/q '[:find ?c
|
||||||
:in $ ?g
|
:in $ ?g
|
||||||
:where [?c :client/groups ?g]]
|
:where [?c :client/groups ?g]]
|
||||||
(dc/db conn)
|
(dc/db conn)
|
||||||
(str/upper-case (or (second x-clients) "INVALID")))
|
(str/upper-case (or (:group x-clients) "INVALID")))
|
||||||
(map first)
|
(map first)
|
||||||
set)
|
set)
|
||||||
|
|
||||||
(seq x-clients)
|
(seq (:selected x-clients))
|
||||||
(->> x-clients
|
(->> x-clients
|
||||||
(map (fn [c]
|
:selected
|
||||||
(if (string? c)
|
|
||||||
(try
|
|
||||||
(Long/parseLong c)
|
|
||||||
(catch Exception e
|
|
||||||
nil))
|
|
||||||
c)))
|
|
||||||
(filter #(not (nil? %)))
|
(filter #(not (nil? %)))
|
||||||
set)))
|
set)))
|
||||||
|
|
||||||
limited-clients (some->> (limited-clients identity)
|
limited-clients (some->> (limited-clients identity)
|
||||||
(map :db/id)
|
(map :db/id)
|
||||||
set)
|
set)
|
||||||
@@ -241,7 +243,6 @@
|
|||||||
:bank-account/number
|
:bank-account/number
|
||||||
:bank-account/name
|
:bank-account/name
|
||||||
:bank-account/code]}]))]
|
:bank-account/code]}]))]
|
||||||
|
|
||||||
(mu/with-context {:clients (take 10 (map :client/code clients))}
|
(mu/with-context {:clients (take 10 (map :client/code clients))}
|
||||||
(handler (assoc request
|
(handler (assoc request
|
||||||
:clients clients
|
:clients clients
|
||||||
@@ -251,33 +252,22 @@
|
|||||||
(defn wrap-store-client-in-session
|
(defn wrap-store-client-in-session
|
||||||
[handler]
|
[handler]
|
||||||
(fn [{:keys [headers identity] :as request}]
|
(fn [{:keys [headers identity] :as request}]
|
||||||
(let [x-clients (edn/read-string (get headers "x-clients"))
|
(let [client-selection (try (mc/decode client-selection-schema (some-> (get headers "x-clients") not-empty json/read-str) main-transformer)
|
||||||
x-clients (try (if-let [client-id (and x-clients
|
(catch Exception e
|
||||||
(sequential? x-clients)
|
(alog/warn ::cant-access :error e
|
||||||
(first x-clients)
|
:identity identity
|
||||||
(not= :group (first x-clients))
|
:x-clients (pr-str (get headers "x-clients")))
|
||||||
(first x-clients))]
|
nil))
|
||||||
(do
|
|
||||||
(assert-can-see-client identity (cond-> client-id
|
new-request (if client-selection
|
||||||
(string? client-id) (Long/parseLong)))
|
(assoc-in request [:client-selection] client-selection)
|
||||||
[(if (string? client-id)
|
(assoc-in request [:client-selection] (get-in request [:session :client-selection] :all)))]
|
||||||
(Long/parseLong client-id)
|
|
||||||
client-id)])
|
|
||||||
x-clients)
|
|
||||||
(catch Exception e
|
|
||||||
(alog/warn ::cant-access :error e
|
|
||||||
:identity identity
|
|
||||||
:x-clients (pr-str x-clients))
|
|
||||||
:all))
|
|
||||||
new-request (if x-clients
|
|
||||||
(assoc-in request [:session :client-selection] x-clients)
|
|
||||||
request)]
|
|
||||||
(cond-> (handler new-request)
|
(cond-> (handler new-request)
|
||||||
x-clients (update :session
|
client-selection (update :session
|
||||||
(fn [new-session]
|
(fn [new-session]
|
||||||
(-> (:session request)
|
(-> (:session request)
|
||||||
(into new-session)
|
(into new-session)
|
||||||
(assoc :client-selection x-clients))))))))
|
(assoc :client-selection client-selection))))))))
|
||||||
|
|
||||||
(defn wrap-gunzip-jwt
|
(defn wrap-gunzip-jwt
|
||||||
[handler]
|
[handler]
|
||||||
@@ -317,9 +307,9 @@
|
|||||||
(-> route-handler
|
(-> route-handler
|
||||||
(wrap-hx-current-url-params)
|
(wrap-hx-current-url-params)
|
||||||
(wrap-guess-route)
|
(wrap-guess-route)
|
||||||
|
(wrap-logging)
|
||||||
(wrap-hydrate-clients)
|
(wrap-hydrate-clients)
|
||||||
(wrap-store-client-in-session)
|
(wrap-store-client-in-session)
|
||||||
(wrap-logging)
|
|
||||||
(wrap-gunzip-jwt)
|
(wrap-gunzip-jwt)
|
||||||
(wrap-authorization auth-backend)
|
(wrap-authorization auth-backend)
|
||||||
(wrap-authentication auth-backend
|
(wrap-authentication auth-backend
|
||||||
|
|||||||
@@ -193,8 +193,9 @@
|
|||||||
(base-page
|
(base-page
|
||||||
request
|
request
|
||||||
(com/page {:nav com/admin-aside-nav
|
(com/page {:nav com/admin-aside-nav
|
||||||
:client-selection (:client-selection (:session request))
|
:client-selection (:client-selection request)
|
||||||
:client (:client request)
|
:client (:client request)
|
||||||
|
:clients (:clients request)
|
||||||
:identity (:identity request)
|
:identity (:identity request)
|
||||||
:request request
|
:request request
|
||||||
:app-params {:hx-get (bidi/path-for ssr-routes/only-routes
|
:app-params {:hx-get (bidi/path-for ssr-routes/only-routes
|
||||||
|
|||||||
@@ -45,7 +45,7 @@
|
|||||||
(base-page
|
(base-page
|
||||||
request
|
request
|
||||||
(com/page {:nav com/admin-aside-nav
|
(com/page {:nav com/admin-aside-nav
|
||||||
:client-selection (:client-selection (:session request))
|
:client-selection (:client-selection request)
|
||||||
:clients (:clients request)
|
:clients (:clients request)
|
||||||
:client (:client request)
|
:client (:client request)
|
||||||
:identity (:identity request)}
|
:identity (:identity request)}
|
||||||
|
|||||||
@@ -243,7 +243,7 @@
|
|||||||
(base-page
|
(base-page
|
||||||
request
|
request
|
||||||
(com/page {:nav com/admin-aside-nav
|
(com/page {:nav com/admin-aside-nav
|
||||||
:client-selection (:client-selection (:session request))
|
:client-selection (:client-selection request)
|
||||||
:clients (:clients request)
|
:clients (:clients request)
|
||||||
:client (:client request)
|
:client (:client request)
|
||||||
:identity (:identity request)
|
:identity (:identity request)
|
||||||
|
|||||||
@@ -166,8 +166,9 @@
|
|||||||
(some-> route-params (get :entity-id) Long/parseLong))]
|
(some-> route-params (get :entity-id) Long/parseLong))]
|
||||||
(base-page request
|
(base-page request
|
||||||
(com/page {:nav com/admin-aside-nav
|
(com/page {:nav com/admin-aside-nav
|
||||||
:client-selection (:client-selection (:session request))
|
:client-selection (:client-selection request)
|
||||||
:client (:client request)
|
:client (:client request)
|
||||||
|
:clients (:clients request)
|
||||||
:identity (:identity request)
|
:identity (:identity request)
|
||||||
:request request
|
:request request
|
||||||
:app-params {:hx-get (bidi/path-for ssr-routes/only-routes
|
:app-params {:hx-get (bidi/path-for ssr-routes/only-routes
|
||||||
|
|||||||
@@ -131,8 +131,9 @@
|
|||||||
(base-page
|
(base-page
|
||||||
request
|
request
|
||||||
(com/page {:nav com/company-aside-nav
|
(com/page {:nav com/company-aside-nav
|
||||||
:client-selection (:client-selection (:session request))
|
:client-selection (:client-selection request)
|
||||||
:client (:client request)
|
:client (:client request)
|
||||||
|
:clients (:clients request)
|
||||||
:identity (:identity request)
|
:identity (:identity request)
|
||||||
:app-params {:hx-get (bidi/path-for ssr-routes/only-routes
|
:app-params {:hx-get (bidi/path-for ssr-routes/only-routes
|
||||||
:company)
|
:company)
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
(ns auto-ap.ssr.company-dropdown
|
(ns auto-ap.ssr.company-dropdown
|
||||||
(:require [auto-ap.datomic :refer [conn pull-attr pull-many]]
|
(:require [auto-ap.datomic :refer [conn pull-many]]
|
||||||
[auto-ap.graphql.utils :refer [cleanse-query]]
|
[auto-ap.graphql.utils :refer [cleanse-query]]
|
||||||
|
[auto-ap.logging :as alog]
|
||||||
[auto-ap.solr :as solr]
|
[auto-ap.solr :as solr]
|
||||||
[auto-ap.ssr-routes :as ssr-routes]
|
[auto-ap.ssr-routes :as ssr-routes]
|
||||||
[auto-ap.ssr.hx :as hx]
|
[auto-ap.ssr.hx :as hx]
|
||||||
@@ -10,7 +11,9 @@
|
|||||||
[clojure.string :as str]
|
[clojure.string :as str]
|
||||||
[datomic.api :as dc]
|
[datomic.api :as dc]
|
||||||
[hiccup2.core :as hiccup]
|
[hiccup2.core :as hiccup]
|
||||||
[iol-ion.query :refer [can-see-client?]]))
|
[iol-ion.query :refer [can-see-client?]]
|
||||||
|
[clojure.data.json :as json]))
|
||||||
|
|
||||||
|
|
||||||
(defn dropdown-search-results* [{:keys [options]}]
|
(defn dropdown-search-results* [{:keys [options]}]
|
||||||
[:ul
|
[:ul
|
||||||
@@ -25,6 +28,7 @@
|
|||||||
:request-method :put)
|
:request-method :put)
|
||||||
:hx-target "#company-dropdown"
|
:hx-target "#company-dropdown"
|
||||||
:hx-headers (hx/json {"x-clients" (pr-str [:group group])})
|
:hx-headers (hx/json {"x-clients" (pr-str [:group group])})
|
||||||
|
"@click" (format "globalClientSelection={group: %s}" (hx/json group))
|
||||||
:hx-swap "outerHTML"
|
:hx-swap "outerHTML"
|
||||||
:hx-trigger "click"}
|
:hx-trigger "click"}
|
||||||
name]
|
name]
|
||||||
@@ -34,6 +38,7 @@
|
|||||||
:request-method :put)
|
:request-method :put)
|
||||||
:hx-target "#company-dropdown"
|
:hx-target "#company-dropdown"
|
||||||
:hx-headers (format "{\"x-clients\": \"[%d]\"}" id)
|
:hx-headers (format "{\"x-clients\": \"[%d]\"}" id)
|
||||||
|
"@click" (format "globalClientSelection={selected: [%d]}" id)
|
||||||
:hx-swap "outerHTML"
|
:hx-swap "outerHTML"
|
||||||
:hx-trigger "click"}
|
:hx-trigger "click"}
|
||||||
name])]])])
|
name])]])])
|
||||||
@@ -64,11 +69,18 @@
|
|||||||
(dropdown-search-results* {:options (get-clients identity (get (:query-params request) "search-text"))})))
|
(dropdown-search-results* {:options (get-clients identity (get (:query-params request) "search-text"))})))
|
||||||
|
|
||||||
(defn dropdown [{:keys [client-selection client identity clients]}]
|
(defn dropdown [{:keys [client-selection client identity clients]}]
|
||||||
|
(alog/peek ::clients clients)
|
||||||
[:div#company-dropdown
|
[:div#company-dropdown
|
||||||
[:script
|
[:script
|
||||||
(hiccup/raw
|
(hiccup/raw
|
||||||
"localStorage.setItem(\"last-client-id\", \"" (:db/id client) "\")" "\n"
|
"localStorage.setItem(\"last-client-id\", \"" (:db/id client) "\")" "\n"
|
||||||
"localStorage.setItem(\"last-selected-clients\", " (pr-str (pr-str client-selection)) ")")]
|
"localStorage.setItem(\"last-selected-clients\", " (json/write-str (json/write-str client-selection))
|
||||||
|
#_(cond (:group client-selection)
|
||||||
|
(:group client-selection)
|
||||||
|
(:selected client-selection)
|
||||||
|
(:selected client-selection)
|
||||||
|
:else
|
||||||
|
client-selection) ")")]
|
||||||
[:div
|
[:div
|
||||||
[:button#company-dropdown-button {:class "text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm px-4 py-2.5 text-center inline-flex items-center dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800"
|
[:button#company-dropdown-button {:class "text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm px-4 py-2.5 text-center inline-flex items-center dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800"
|
||||||
:type "button"}
|
:type "button"}
|
||||||
@@ -80,7 +92,7 @@
|
|||||||
|
|
||||||
(and client
|
(and client
|
||||||
(= 1 (count clients)))
|
(= 1 (count clients)))
|
||||||
( :client/name client)
|
(:client/name client)
|
||||||
|
|
||||||
:else
|
:else
|
||||||
(str (count clients) " Companies"))
|
(str (count clients) " Companies"))
|
||||||
@@ -116,6 +128,8 @@
|
|||||||
:active-client
|
:active-client
|
||||||
:request-method :put)
|
:request-method :put)
|
||||||
:hx-target "#company-dropdown"
|
:hx-target "#company-dropdown"
|
||||||
|
|
||||||
|
"@click" "globalClientSelection=\"mine\""
|
||||||
:hx-headers "{\"x-clients\": \":mine\"}"
|
:hx-headers "{\"x-clients\": \":mine\"}"
|
||||||
:hx-swap "outerHTML"
|
:hx-swap "outerHTML"
|
||||||
:hx-trigger "click"}
|
:hx-trigger "click"}
|
||||||
@@ -127,6 +141,7 @@
|
|||||||
:active-client
|
:active-client
|
||||||
:request-method :put)
|
:request-method :put)
|
||||||
:hx-target "#company-dropdown"
|
:hx-target "#company-dropdown"
|
||||||
|
"@click" "globalClientSelection=\"all\""
|
||||||
:hx-headers "{\"x-clients\": \":all\"}"
|
:hx-headers "{\"x-clients\": \":all\"}"
|
||||||
:hx-swap "outerHTML"
|
:hx-swap "outerHTML"
|
||||||
:hx-trigger "click"}
|
:hx-trigger "click"}
|
||||||
@@ -161,7 +176,7 @@ function initCompanyDropdown() {
|
|||||||
(defn active-client [{:keys [identity params] :as request}]
|
(defn active-client [{:keys [identity params] :as request}]
|
||||||
(assoc
|
(assoc
|
||||||
(html-response
|
(html-response
|
||||||
(dropdown {:client-selection (:client-selection (:session request))
|
(dropdown {:client-selection (:client-selection request)
|
||||||
:clients (:clients request)
|
:clients (:clients request)
|
||||||
:client (:client request)
|
:client (:client request)
|
||||||
:identity identity}))
|
:identity identity}))
|
||||||
|
|||||||
@@ -27,7 +27,8 @@
|
|||||||
[:li
|
[:li
|
||||||
[:a {:href (bidi/path-for ssr-routes/only-routes :company), :class "block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-gray-600 dark:hover:text-white", :role "menuitem"} "My Company"]]
|
[:a {:href (bidi/path-for ssr-routes/only-routes :company), :class "block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-gray-600 dark:hover:text-white", :role "menuitem"} "My Company"]]
|
||||||
(when (= "admin" (:user/role identity))
|
(when (= "admin" (:user/role identity))
|
||||||
[:a {:href (bidi/path-for ssr-routes/only-routes :auto-ap.routes.admin/page), :class "block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-gray-600 dark:hover:text-white", :role "menuitem"} "Admin"])
|
[:a {:href (bidi/path-for ssr-routes/only-routes :auto-ap.routes.admin/page),
|
||||||
|
:class "block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-gray-600 dark:hover:text-white", :role "menuitem"} "Admin"])
|
||||||
[:li
|
[:li
|
||||||
[:a {:href "#", :class "block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-gray-600 dark:hover:text-white", :role "menuitem"
|
[:a {:href "#", :class "block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-gray-600 dark:hover:text-white", :role "menuitem"
|
||||||
"_" (hiccup/raw "on click toggle .dark on <body />")}
|
"_" (hiccup/raw "on click toggle .dark on <body />")}
|
||||||
|
|||||||
@@ -245,7 +245,7 @@
|
|||||||
(com/page {:nav (:nav grid-spec)
|
(com/page {:nav (:nav grid-spec)
|
||||||
:page-specific (when-let [page-specific-nav (:page-specific-nav grid-spec)]
|
:page-specific (when-let [page-specific-nav (:page-specific-nav grid-spec)]
|
||||||
[:div#page-specific-nav (page-specific-nav request)])
|
[:div#page-specific-nav (page-specific-nav request)])
|
||||||
:client-selection (:client-selection (:session request))
|
:client-selection (:client-selection request)
|
||||||
:clients (:clients request)
|
:clients (:clients request)
|
||||||
:client (:client request)
|
:client (:client request)
|
||||||
:identity (:identity request)
|
:identity (:identity request)
|
||||||
|
|||||||
@@ -421,8 +421,9 @@ invoice_dropzone = new Dropzone(\"#invoice\", {
|
|||||||
(base-page
|
(base-page
|
||||||
request
|
request
|
||||||
(com/page {:nav com/admin-aside-nav
|
(com/page {:nav com/admin-aside-nav
|
||||||
:client-selection (:client-selection (:session request))
|
:client-selection (:client-selection request)
|
||||||
:client (:client request)
|
:client (:client request)
|
||||||
|
:clients (:clients request)
|
||||||
:identity (:identity request)
|
:identity (:identity request)
|
||||||
:app-params {:hx-get (bidi/path-for ssr-routes/only-routes
|
:app-params {:hx-get (bidi/path-for ssr-routes/only-routes
|
||||||
:invoice-glimpse)
|
:invoice-glimpse)
|
||||||
|
|||||||
@@ -120,8 +120,6 @@
|
|||||||
(exact-match-id* request)]])
|
(exact-match-id* request)]])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
(defn fetch-ids [db {:keys [query-params route-params] :as request}]
|
(defn fetch-ids [db {:keys [query-params route-params] :as request}]
|
||||||
(let [valid-clients (extract-client-ids (:clients request)
|
(let [valid-clients (extract-client-ids (:clients request)
|
||||||
(:client-id request)
|
(:client-id request)
|
||||||
@@ -556,10 +554,10 @@
|
|||||||
_ (audit-transact tx identity)]
|
_ (audit-transact tx identity)]
|
||||||
(alog/info ::unvoiding-invoice :transaction :tx)
|
(alog/info ::unvoiding-invoice :transaction :tx)
|
||||||
(html-response
|
(html-response
|
||||||
(row* identity (dc/pull (dc/db conn) default-read id) {:flash? true
|
(row* identity (dc/pull (dc/db conn) default-read id) {:flash? true
|
||||||
:request request})
|
:request request})
|
||||||
:headers (cond-> {"hx-retarget" (format "#entity-table tr[data-id=\"%d\"]" id)
|
:headers (cond-> {"hx-retarget" (format "#entity-table tr[data-id=\"%d\"]" id)
|
||||||
"hx-reswap" "outerHTML"}))))
|
"hx-reswap" "outerHTML"}))))
|
||||||
|
|
||||||
(defn delete [{invoice :entity :as request identity :identity}]
|
(defn delete [{invoice :entity :as request identity :identity}]
|
||||||
(exception->notification
|
(exception->notification
|
||||||
@@ -1137,7 +1135,7 @@
|
|||||||
(->> (dc/q '[:find ?i
|
(->> (dc/q '[:find ?i
|
||||||
:in $ [?i ...]
|
:in $ [?i ...]
|
||||||
:where [?i :invoice/status :invoice-status/unpaid]
|
:where [?i :invoice/status :invoice-status/unpaid]
|
||||||
[?i :invoice/client ?c] ]
|
[?i :invoice/client ?c]]
|
||||||
(dc/db conn)
|
(dc/db conn)
|
||||||
ids)
|
ids)
|
||||||
(map first)))
|
(map first)))
|
||||||
|
|||||||
@@ -251,7 +251,7 @@
|
|||||||
(base-page
|
(base-page
|
||||||
request
|
request
|
||||||
(com/page {:nav com/main-aside-nav
|
(com/page {:nav com/main-aside-nav
|
||||||
:client-selection (:client-selection (:session request))
|
:client-selection (:client-selection request)
|
||||||
:clients (:clients request)
|
:clients (:clients request)
|
||||||
:client (:client request)
|
:client (:client request)
|
||||||
:identity (:identity request)
|
:identity (:identity request)
|
||||||
|
|||||||
@@ -318,8 +318,9 @@
|
|||||||
(base-page
|
(base-page
|
||||||
request
|
request
|
||||||
(com/page {:nav com/main-aside-nav
|
(com/page {:nav com/main-aside-nav
|
||||||
:client-selection (:client-selection (:session request))
|
:client-selection (:client-selection request)
|
||||||
:client (:client request)
|
:client (:client request)
|
||||||
|
:clients (:clients request)
|
||||||
:identity (:identity request)
|
:identity (:identity request)
|
||||||
:app-params {:hx-get (bidi/path-for ssr-routes/only-routes
|
:app-params {:hx-get (bidi/path-for ssr-routes/only-routes
|
||||||
:transaction-insights)
|
:transaction-insights)
|
||||||
|
|||||||
@@ -69,9 +69,10 @@ input::-webkit-inner-spin-button {
|
|||||||
input[type=number] {
|
input[type=number] {
|
||||||
-moz-appearance:textfield; /* Firefox */
|
-moz-appearance:textfield; /* Firefox */
|
||||||
} "]
|
} "]
|
||||||
|
[:body {:hx-ext "disable-submit, class-tools"
|
||||||
|
:x-data (hx/json {:globalClientSelection (or (:client-selection request)
|
||||||
[:body {:hx-ext "disable-submit, class-tools"}
|
:all )}) ;; TODO remove once session is used
|
||||||
|
:x-hx-header:x-clients "JSON.stringify(globalClientSelection)"}
|
||||||
contents
|
contents
|
||||||
[:script {:src "/js/flowbite.min.js"}]
|
[:script {:src "/js/flowbite.min.js"}]
|
||||||
|
|
||||||
|
|||||||
@@ -107,7 +107,7 @@
|
|||||||
(mt2/transformer
|
(mt2/transformer
|
||||||
{:decoders
|
{:decoders
|
||||||
{:map (fn [m]
|
{:map (fn [m]
|
||||||
(if (not (seq (filter identity (vals m))))
|
(if (and (map? m) (not (seq (filter identity (vals m)))))
|
||||||
nil
|
nil
|
||||||
m))
|
m))
|
||||||
:string empty->nil
|
:string empty->nil
|
||||||
|
|||||||
30
src/cljs/auto_ap/client_selection.cljs
Normal file
30
src/cljs/auto_ap/client_selection.cljs
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
(ns auto-ap.client-selection
|
||||||
|
(:require [clojure.string :as str]
|
||||||
|
[malli.core :as mc]
|
||||||
|
[malli.transform :as mt2]))
|
||||||
|
|
||||||
|
;; TODO remove this eventuall
|
||||||
|
(defn str->keyword [s]
|
||||||
|
(if (string? s)
|
||||||
|
(let [[ns k] (str/split s #"/")]
|
||||||
|
(if (and ns k)
|
||||||
|
(keyword ns k)
|
||||||
|
(keyword s)))
|
||||||
|
s))
|
||||||
|
|
||||||
|
(defn keyword->str [k]
|
||||||
|
(subs (str k) 1))
|
||||||
|
(def client-selection-schema
|
||||||
|
(mc/schema
|
||||||
|
[:orn
|
||||||
|
[:global [:enum :all :mine]]
|
||||||
|
[:group-name [:map [:group :string]]]
|
||||||
|
[:specific [:map [:selected [:vector nat-int?]]]]]))
|
||||||
|
|
||||||
|
(def client-selection-transformer
|
||||||
|
(mt2/transformer
|
||||||
|
mt2/json-transformer
|
||||||
|
mt2/string-transformer
|
||||||
|
(mt2/key-transformer {:encode keyword->str :decode str->keyword})))
|
||||||
|
|
||||||
|
;; END TODO
|
||||||
@@ -1,27 +1,25 @@
|
|||||||
(ns auto-ap.effects
|
(ns auto-ap.effects
|
||||||
(:require-macros [cljs.core.async.macros :refer [go]])
|
(:require-macros [cljs.core.async.macros :refer [go]])
|
||||||
(:require
|
(:require [auto-ap.client-selection :refer [client-selection-schema]]
|
||||||
[auto-ap.history :as p]
|
[auto-ap.history :as p]
|
||||||
[auto-ap.status :as status]
|
[auto-ap.status :as status]
|
||||||
[auto-ap.views.utils :refer [date->str standard]]
|
[auto-ap.views.utils :refer [date->str standard]]
|
||||||
[cemerick.url :as url]
|
[cemerick.url :as url]
|
||||||
[cljs-http.client :as http]
|
[cljs-http.client :as http]
|
||||||
[cljs-time.coerce :as c]
|
[cljs-time.coerce :as c]
|
||||||
[cljs-time.core :as time]
|
[cljs-time.core :as time]
|
||||||
[cljs-time.format :as format]
|
[cljs-time.format :as format]
|
||||||
[cljs.core.async :refer [<!] :as async]
|
[cljs.core.async :refer [<!] :as async]
|
||||||
[clojure.string :as str]
|
[clojure.string :as str]
|
||||||
[clojure.walk :as walk]
|
[clojure.walk :as walk]
|
||||||
[pushy.core :as pushy]
|
[malli.core :as mc]
|
||||||
[re-frame.core :as re-frame]
|
[pushy.core :as pushy]
|
||||||
[venia.core :as v]))
|
[re-frame.core :as re-frame]
|
||||||
|
[venia.core :as v]))
|
||||||
|
|
||||||
(defn maybe-add-x-clients [headers]
|
(defn maybe-add-x-clients [headers]
|
||||||
(if (or (and (sequential? (:selected-clients @re-frame.db/app-db)) (every? int? (:selected-clients @re-frame.db/app-db)))
|
(if (mc/validate client-selection-schema (:selected-clients @re-frame.db/app-db))
|
||||||
(and (sequential? (:selected-clients @re-frame.db/app-db)) (every? string? (:selected-clients @re-frame.db/app-db)))
|
(assoc headers "x-clients" (.stringify js/JSON (clj->js (:selected-clients @re-frame.db/app-db))))
|
||||||
(and (sequential? (:selected-clients @re-frame.db/app-db)) (= :group (first (:selected-clients @re-frame.db/app-db))))
|
|
||||||
(keyword? (:selected-clients @re-frame.db/app-db)))
|
|
||||||
(assoc headers "x-clients" (pr-str (:selected-clients @re-frame.db/app-db)))
|
|
||||||
headers))
|
headers))
|
||||||
|
|
||||||
(re-frame/reg-fx
|
(re-frame/reg-fx
|
||||||
|
|||||||
@@ -1,24 +1,24 @@
|
|||||||
(ns auto-ap.events
|
(ns auto-ap.events
|
||||||
(:require
|
(:require [auto-ap.client-selection :refer [client-selection-schema
|
||||||
[auto-ap.db :as db]
|
client-selection-transformer]]
|
||||||
[auto-ap.routes :as routes]
|
[auto-ap.db :as db]
|
||||||
[auto-ap.utils :refer [by]]
|
[auto-ap.routes :as routes]
|
||||||
[auto-ap.views.pages.data-page :as data-page]
|
[auto-ap.ssr-routes :as ssr-routes]
|
||||||
[auto-ap.views.utils :refer [parse-jwt with-user gunzip]]
|
[auto-ap.utils :refer [by]]
|
||||||
[bidi.bidi :as bidi]
|
[auto-ap.views.pages.data-page :as data-page]
|
||||||
[clojure.string :as str]
|
[auto-ap.views.utils :refer [gunzip parse-jwt with-user]]
|
||||||
[clojure.edn :as edn]
|
[bidi.bidi :as bidi]
|
||||||
[goog.crypt.base64 :as b64]
|
[cemerick.url :as url]
|
||||||
[re-frame.core :as re-frame]
|
[clojure.string :as str]
|
||||||
[auto-ap.ssr-routes :as ssr-routes]
|
[goog.crypt.base64 :as b64]
|
||||||
[cemerick.url :as url]
|
[malli.core :as mc]
|
||||||
[auto-ap.subs :as subs]
|
[pako]
|
||||||
[pako]))
|
[re-frame.core :as re-frame]))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
(defn jwt->data [token]
|
(defn jwt->data [token]
|
||||||
(let [raw (js->clj (.parse js/JSON (b64/decodeString (second (str/split token #"\." )))))
|
(let [raw (js->clj (.parse js/JSON (b64/decodeString (second (str/split token #"\.")))))
|
||||||
gz-clients (or (:gz-clients raw)
|
gz-clients (or (:gz-clients raw)
|
||||||
(get raw "gz-clients"))]
|
(get raw "gz-clients"))]
|
||||||
(cond-> raw
|
(cond-> raw
|
||||||
@@ -46,18 +46,22 @@
|
|||||||
[:plaid-account [:name :id :number]]
|
[:plaid-account [:name :id :number]]
|
||||||
[:intuit-bank-account [:name :id :external-id]]
|
[:intuit-bank-account [:name :id :external-id]]
|
||||||
:use-date-instead-of-post-date
|
:use-date-instead-of-post-date
|
||||||
:locations :include-in-reports :current-balance :yodlee-balance-old] ]
|
:locations :include-in-reports :current-balance :yodlee-balance-old]]
|
||||||
[:address [:id :street1 :street2 :city :state :zip]]
|
[:address [:id :street1 :street2 :city :state :zip]]
|
||||||
[:forecasted-transactions [:id :amount :identifier :day-of-month]]]
|
[:forecasted-transactions [:id :amount :identifier :day-of-month]]]
|
||||||
(= "admin" (or (get (jwt->data token) "role") (get (jwt->data token) "user/role")) ) (into [[:yodlee-provider-accounts [:id [:accounts [:id :name :number :available-balance]]]]
|
(= "admin" (or (get (jwt->data token) "role") (get (jwt->data token) "user/role"))) (into [[:yodlee-provider-accounts [:id [:accounts [:id :name :number :available-balance]]]]
|
||||||
[:plaid-items [:id [:accounts [:id :name :number :balance]]]]])))
|
[:plaid-items [:id [:accounts [:id :name :number :balance]]]]])))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
(re-frame/reg-event-fx
|
(re-frame/reg-event-fx
|
||||||
::initialize-db
|
::initialize-db
|
||||||
(fn [{:keys [_]} [_ token]]
|
(fn [{:keys [_]} [_ token]]
|
||||||
(let [handler (:handler (bidi/match-route routes/routes (.. js/window -location -pathname)))
|
(let [handler (:handler (bidi/match-route routes/routes (.. js/window -location -pathname)))
|
||||||
last-client-id (.getItem js/localStorage "last-client-id")
|
last-client-id (.getItem js/localStorage "last-client-id")
|
||||||
last-selected-clients (edn/read-string (.getItem js/localStorage "last-selected-clients"))
|
last-selected-clients (js->clj (.parse js/JSON (.getItem js/localStorage "last-selected-clients")))
|
||||||
|
last-selected-clients (mc/decode client-selection-schema last-selected-clients client-selection-transformer)
|
||||||
jwt-data (some-> token jwt->data)
|
jwt-data (some-> token jwt->data)
|
||||||
selected-client-assignment (cond (and token
|
selected-client-assignment (cond (and token
|
||||||
(= "admin" (get jwt-data "user/role"))
|
(= "admin" (get jwt-data "user/role"))
|
||||||
@@ -70,7 +74,7 @@
|
|||||||
[(js/parseInt last-client-id)]
|
[(js/parseInt last-client-id)]
|
||||||
|
|
||||||
:else
|
:else
|
||||||
nil)]
|
nil) ]
|
||||||
|
|
||||||
|
|
||||||
(cond
|
(cond
|
||||||
@@ -89,7 +93,7 @@
|
|||||||
:selected-clients last-selected-clients
|
:selected-clients last-selected-clients
|
||||||
:user token)}
|
:user token)}
|
||||||
|
|
||||||
(and token (= "none" (or (get jwt-data "role") (get jwt-data "user/role")) ))
|
(and token (= "none" (or (get jwt-data "role") (get jwt-data "user/role"))))
|
||||||
{:redirect "/needs-activation"
|
{:redirect "/needs-activation"
|
||||||
:db (assoc db/default-db
|
:db (assoc db/default-db
|
||||||
:active-route :needs-activation
|
:active-route :needs-activation
|
||||||
@@ -112,7 +116,7 @@
|
|||||||
:on-success [::received-initial]
|
:on-success [::received-initial]
|
||||||
:on-error [::failed-initial]}}
|
:on-error [::failed-initial]}}
|
||||||
selected-client-assignment
|
selected-client-assignment
|
||||||
(assoc :set-local-storage ["last-selected-clients" selected-client-assignment]))))))
|
(assoc :set-local-storage ["last-selected-clients" (.stringify js/JSON selected-client-assignment)]))))))
|
||||||
|
|
||||||
|
|
||||||
(re-frame/reg-event-db
|
(re-frame/reg-event-db
|
||||||
@@ -125,13 +129,13 @@
|
|||||||
::received-initial
|
::received-initial
|
||||||
(fn [{:keys [db]} [_ {clients :client}]]
|
(fn [{:keys [db]} [_ {clients :client}]]
|
||||||
(let [only-one-client (when (= 1 (count clients))
|
(let [only-one-client (when (= 1 (count clients))
|
||||||
(->> clients first :id ))]
|
(->> clients first :id))]
|
||||||
(when only-one-client
|
(when only-one-client
|
||||||
(.setItem js/localStorage "last-client-id" only-one-client)
|
(.setItem js/localStorage "last-client-id" only-one-client)
|
||||||
(.setItem js/localStorage "last-selected-clients"
|
(.setItem js/localStorage "last-selected-clients"
|
||||||
(pr-str [(js/parseInt only-one-client)])))
|
(pr-str [(js/parseInt only-one-client)])))
|
||||||
{:db (cond-> (-> db
|
{:db (cond-> (-> db
|
||||||
(assoc :clients (by :id clients) )
|
(assoc :clients (by :id clients))
|
||||||
(assoc :is-initial-loading? false)
|
(assoc :is-initial-loading? false)
|
||||||
(assoc :client (or only-one-client
|
(assoc :client (or only-one-client
|
||||||
(->> clients
|
(->> clients
|
||||||
@@ -167,30 +171,31 @@
|
|||||||
:active-route :initial-error)))
|
:active-route :initial-error)))
|
||||||
|
|
||||||
(re-frame/reg-event-fx
|
(re-frame/reg-event-fx
|
||||||
::swapped-client
|
::swapped-client
|
||||||
(fn [{:keys [db]} [_ client client-identifier]]
|
(fn [{:keys [db]} [_ client client-identifier]]
|
||||||
(when (:id client)
|
(when (:id client)
|
||||||
(.setItem js/localStorage "last-client-id" (:id client)))
|
(.setItem js/localStorage "last-client-id" (:id client)))
|
||||||
(.setItem js/localStorage "last-selected-clients"
|
(.setItem js/localStorage "last-selected-clients"
|
||||||
(condp = client-identifier
|
(.stringify js/JSON
|
||||||
:all
|
(clj->js (condp = client-identifier
|
||||||
:all
|
:all
|
||||||
|
:all
|
||||||
|
|
||||||
:mine
|
:mine
|
||||||
:mine
|
:mine
|
||||||
|
|
||||||
(pr-str [(js/parseInt (:id client))])))
|
{:selected [(js/parseInt (:id client))]}))))
|
||||||
|
|
||||||
{:db (assoc db :client (:id client)
|
{:db (assoc db :client (:id client)
|
||||||
:selected-clients
|
:selected-clients
|
||||||
(condp = client-identifier
|
(condp = client-identifier
|
||||||
:all
|
:all
|
||||||
:all
|
:all
|
||||||
|
|
||||||
:mine
|
:mine
|
||||||
:mine
|
:mine
|
||||||
|
|
||||||
[(js/parseInt (:id client))]))}))
|
{:selected [(js/parseInt (:id client))]}))}))
|
||||||
|
|
||||||
(re-frame/reg-event-fx
|
(re-frame/reg-event-fx
|
||||||
::swap-client
|
::swap-client
|
||||||
@@ -260,32 +265,32 @@
|
|||||||
:on-success [::yodlee-merchants-received]}}))
|
:on-success [::yodlee-merchants-received]}}))
|
||||||
|
|
||||||
(re-frame/reg-event-fx
|
(re-frame/reg-event-fx
|
||||||
::vendor-preferences-requested
|
::vendor-preferences-requested
|
||||||
[with-user]
|
[with-user]
|
||||||
(fn [{:keys [user]} [_ {:keys [ client-id vendor-id on-success on-failure owns-state]}]]
|
(fn [{:keys [user]} [_ {:keys [client-id vendor-id on-success on-failure owns-state]}]]
|
||||||
{:graphql {:token user
|
{:graphql {:token user
|
||||||
:query-obj {:venia/queries [[:vendor-by-id
|
:query-obj {:venia/queries [[:vendor-by-id
|
||||||
{:id vendor-id}
|
{:id vendor-id}
|
||||||
[[:automatically-paid-when-due [:id]]
|
[[:automatically-paid-when-due [:id]]
|
||||||
[:schedule-payment-dom [[:client [:id]] :dom]]
|
[:schedule-payment-dom [[:client [:id]] :dom]]
|
||||||
[:default-account [:id]]]]
|
[:default-account [:id]]]]
|
||||||
[:account-for-vendor
|
[:account-for-vendor
|
||||||
{:vendor-id vendor-id
|
{:vendor-id vendor-id
|
||||||
:client-id client-id}
|
:client-id client-id}
|
||||||
[:name :id :numeric-code :location]]]}
|
[:name :id :numeric-code :location]]]}
|
||||||
:owns-state owns-state
|
:owns-state owns-state
|
||||||
:on-success (fn [r]
|
:on-success (fn [r]
|
||||||
(let [schedule-payment-dom (->> r
|
(let [schedule-payment-dom (->> r
|
||||||
:vendor-by-id
|
:vendor-by-id
|
||||||
:schedule-payment-dom
|
:schedule-payment-dom
|
||||||
(filter (fn [spd]
|
(filter (fn [spd]
|
||||||
(= (-> spd :client :id)
|
(= (-> spd :client :id)
|
||||||
client-id)))
|
client-id)))
|
||||||
first
|
first
|
||||||
:dom)
|
:dom)
|
||||||
automatically-paid-when-due (boolean ((->> r :vendor-by-id :automatically-paid-when-due (map :id) set) client-id))]
|
automatically-paid-when-due (boolean ((->> r :vendor-by-id :automatically-paid-when-due (map :id) set) client-id))]
|
||||||
(conj on-success {:default-account (:account-for-vendor r)
|
(conj on-success {:default-account (:account-for-vendor r)
|
||||||
:schedule-payment-dom schedule-payment-dom
|
:schedule-payment-dom schedule-payment-dom
|
||||||
:automatically-paid-when-due automatically-paid-when-due
|
:automatically-paid-when-due automatically-paid-when-due
|
||||||
:vendor-autopay? (or automatically-paid-when-due (boolean schedule-payment-dom))})))
|
:vendor-autopay? (or automatically-paid-when-due (boolean schedule-payment-dom))})))
|
||||||
:on-failure on-failure}}))
|
:on-failure on-failure}}))
|
||||||
|
|||||||
@@ -17,7 +17,6 @@
|
|||||||
::client
|
::client
|
||||||
:<- [::selected-clients]
|
:<- [::selected-clients]
|
||||||
(fn [selected-clients]
|
(fn [selected-clients]
|
||||||
(println "SELECTED CLIENTS ARE" selected-clients)
|
|
||||||
(when (= 1 (count selected-clients))
|
(when (= 1 (count selected-clients))
|
||||||
(first selected-clients))))
|
(first selected-clients))))
|
||||||
|
|
||||||
@@ -44,10 +43,6 @@
|
|||||||
:<- [::user]
|
:<- [::user]
|
||||||
:<- [::clients]
|
:<- [::clients]
|
||||||
(fn [[selected-clients user clients]]
|
(fn [[selected-clients user clients]]
|
||||||
(println "SELECTED" selected-clients
|
|
||||||
"USER" user
|
|
||||||
"CLIENTS" (count clients))
|
|
||||||
|
|
||||||
(cond (= :mine selected-clients)
|
(cond (= :mine selected-clients)
|
||||||
(sort-by :name
|
(sort-by :name
|
||||||
(:user/clients user))
|
(:user/clients user))
|
||||||
@@ -58,17 +53,15 @@
|
|||||||
(nil? selected-clients))
|
(nil? selected-clients))
|
||||||
clients
|
clients
|
||||||
|
|
||||||
(= :group (and (sequential? selected-clients)
|
(:group selected-clients)
|
||||||
(first selected-clients)))
|
(let [group (:group selected-clients)]
|
||||||
(let [group (second selected-clients)]
|
|
||||||
(filterv
|
(filterv
|
||||||
(fn [c]
|
(fn [c]
|
||||||
(println "GROUP" group (:groups c))
|
|
||||||
((set (:groups c)) group))
|
((set (:groups c)) group))
|
||||||
clients))
|
clients))
|
||||||
|
|
||||||
(sequential? selected-clients)
|
(:selected selected-clients)
|
||||||
(filter (comp (set (map coerce-string-version selected-clients)) coerce-string-version :id)
|
(filter (comp (set (:selected selected-clients)) coerce-string-version :id)
|
||||||
clients)
|
clients)
|
||||||
|
|
||||||
:else
|
:else
|
||||||
|
|||||||
Reference in New Issue
Block a user