diff --git a/package.json b/package.json index 0502acc0..5b8cd708 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,6 @@ "@popperjs/core": "^2.11.5", "downshift": "^6.1.3", "dropzone": "^4.3.0", - "htmx.org": "^1.8.4", "minisearch": "^3.0.2", "prop-types": "^15.7.2", "react": "^17.0.1", diff --git a/src/clj/auto_ap/ssr/admin.clj b/src/clj/auto_ap/ssr/admin.clj index 8e6e10f0..d135464f 100644 --- a/src/clj/auto_ap/ssr/admin.clj +++ b/src/clj/auto_ap/ssr/admin.clj @@ -1,27 +1,17 @@ (ns auto-ap.ssr.admin (:require + [auto-ap.datomic :refer [conn]] + [auto-ap.graphql.utils :refer [assert-admin]] [auto-ap.logging :as alog] + [auto-ap.time :as atime] + [clj-time.coerce :as coerce] [clojure.string :as str] [clojure.tools.logging :as log] - #_{:clj-kondo/ignore [:refer-all]} - [compojure.core :refer [defroutes GET POST context ANY wrap-routes]] - [compojure.route :as route] - [config.core :refer [env]] - [mount.core :as mount] - [ring.middleware.edn :refer [wrap-edn-params]] - [ring.middleware.multipart-params :as mp] - [ring.middleware.params :refer [wrap-params]] - [ring.middleware.reload :refer [wrap-reload]] - [ring.util.response :as response] + [compojure.core :refer [context defroutes GET POST routes]] [datomic.api :as d] - [auto-ap.datomic :refer [conn]] - [clj-time.coerce :as coerce] - [auto-ap.time :as atime] - [hiccup.core :refer [html]] - [hiccup.page :refer [html5]] - [unilog.context :as lc])) + [hiccup2.core :as hiccup])) -(defn base-page [contents] +(defn base-page [request contents] [:html.has-navbar-fixed-top [:head [:meta {:charset "utf-8"}] @@ -43,37 +33,57 @@ :integrity "sha384-wg5Y/JwF7VxGk4zLsJEcAojRtlVp1FKKdGy1qN+OMtdq72WRvX/EdRdqg/LOhYeV" :crossorigin="anonymous"}] [:script {:type "text/javascript", :src "https://cdn.yodlee.com/fastlink/v4/initialize.js", :async "async" }]] + [:script {:type "text/javascript"} + (hiccup/raw + (str + " +window.onload = function () { + document.body.addEventListener(\"htmx:configRequest\", function(event) { + event.detail.headers[\"Authorization\"] = \"Token " (get (:query-params request) "jwt")" \" ; + }); +}"))] + [:body [:div {:id "app"} [:div - [:nav {:class "navbar has-shadow is-fixed-top"} - [:div {:class "container"} - [:div {:class "navbar-brand"} - [:a {:class "navbar-item", :href "../"} - [:img {:src "/img/logo.png"}]]] - [:div {:class "navbar-menu"} - [:div {:class "navbar-burger burger", :data-target "navMenu"} - [:span] - [:span] - [:span]]]]] + [:nav {:class "navbar has-shadow is-fixed-top is-grey"} + + [:div {:class "container"} + [:div {:class "navbar-brand"} + [:a {:class "navbar-item", :href "../"} + [:img {:src "/img/logo.png"}]]] + [:div.navbar-menu {:id "navMenu"} + [:div.navbar-start + [:a.navbar-item {:href "/"} + "Home" ] + [:a.navbar-item {:href "/invoices/"} + "Invoices" ] + [:a.navbar-item {:href "/payments/"} + "Payments" ] + [:a.navbar-item {:href "/pos/sales-orders/"} + "POS" ] + [:a.navbar-item {:href "/transactions/"} + "Transactions" ] + + [:a.navbar-item {:href "/ledger/"} + "Ledger" ]]]]] [:div {:class "columns has-shadow", :id "mail-app", :style "margin-bottom: 0px; height: calc(100vh - 46px);"} [:aside {:class "column aside menu is-2 "} [:div {:class "main left-nav"} [:div]]] [:div {:class "column messages hero ", :id "message-feed", :style "overflow: auto;"} - (into [:div {:class "inbox-messages"}] - contents)]] + [:div {:class "inbox-messages"} + contents]]] [:div] [:div {:id "dz-hidden"}]]]]]) -(defn wrap-html [handler] - (fn [request] - (doto - {:status 200 - :headers {"Content-Type" "text/html"} - :body (handler request) - } - println))) +(defn html-response [hiccup] + {:status 200 + :headers {"Content-Type" "text/html"} + :body (str + (hiccup/html + {} + hiccup))}) (defn inline-add-deletes [history] @@ -121,26 +131,29 @@ (pr-str v))) (comment "_" ) + (defn page-template [& {:keys [table entity-id]}] [:div [:div.columns [:div.column.is-4 [:form.hello {"hx-target" "#history-table" - "hx-post" "/admin/history/search" - "hx-swap" "innerHTML" - "_" (hiccup2.core/raw "on submit toggle @disabled on me then toggle .is-loading on <#dig/> end + "hx-post" "/admin/history/search" + "hx-swap" "innerHTML" + "_" (hiccup/raw "on htmx:beforeRequest toggle @disabled on me then toggle .is-loading on <#dig/> end on htmx:afterRequest toggle @disabled on me then toggle .is-loading on <#dig /> end") } [:div.field.is-grouped [:p.control {} - [:input.input {:type "text" :name "entity-id" :placeholder "Entity id" }]] + [:input.input {:type "text" :name "entity-id" :placeholder "Entity id" :value entity-id}]] [:p.control [:button#dig.button.is-primary {} "Dig"]]]]]] [:div#history-table table]]) -(defn history-search [{:keys [form-params params] :as request}] +(defn history-search [{:keys [form-params params] identity :identity :as request}] + + (assert-admin identity) (log/info ::request request) (try @@ -158,17 +171,18 @@ inline-add-deletes (sort-by (comp :db/txInstant :tx)) vec) - best-guess-entity (->> history - (group-by - (comp - namespace - second) - ) - (map (fn [[k v]] - [k v])) - (sort-by second) - last - first) + best-guess-entity (or (->> history + (group-by + (comp + namespace + second) + ) + (map (fn [[k v]] + [k v])) + (sort-by second) + last + first) + "?") table [:div [:h1.title "History for " (str/capitalize best-guess-entity) " " @@ -181,7 +195,7 @@ [:td {:style "width: 12em"} "Transaction" ] [:td {:style "width: 12em"} "Date"] [:td {:style "width: 12em"} "User"] - [:td {:style "width: 15em"} "Field"] + [:td {:style "width: 10em"} "Field"] [:td "Change"]]] [:tbody (for [[tx a c] history] @@ -193,9 +207,16 @@ (atime/unparse atime/standard-time))] [:td (str (:audit/user tx))] [:td (namespace a) ": " (name a)] - [:td (format-value (:removed c)) - " => " - (format-value (:added c))]])] + [:td + [:div.tags + [:div.tag.is-danger.is-light + [:span + "FROM " + (format-value (:removed c))]] + [:div.tag.is-primary.is-light + [:span + "TO " + (format-value (:added c))]]]]])] ]] [:div.column.is-3 [:div#inspector.card]]]]] @@ -203,23 +224,24 @@ (alog/info ::trace :bge best-guess-entity :headers (:headers request)) - (html (if (= "history-table" - (get (:headers request) "hx-target")) - table - (do - (println "WHOLE PAGOE") - (page-template :table table - :entity-id entity-id))))) + (html-response + (if (get (:headers request) "hx-request") + table + (base-page request + (page-template :table table + :entity-id entity-id))))) (catch NumberFormatException e - (html [:div.notification.is-danger.is-light - "Cannot parse the entity-id " (or (:entity-id form-params) - (:entity-id params)) + (html-response + (str [:div.notification.is-danger.is-light + "Cannot parse the entity-id " (or (:entity-id form-params) + (:entity-id params)) - ". It should be a number."])))) + ". It should be a number."]))))) -(defn inspect [{{:keys [entity-id]} :params :as request}] +(defn inspect [{{:keys [entity-id]} :params identity :identity :as request}] (alog/info ::inspect :request request) + (assert-admin identity) (try (let [entity-id (Long/parseLong entity-id) data (d/pull (d/db conn) @@ -227,34 +249,27 @@ entity-id ) ] - - (html [:div.box [:h1.title "Snapshot of " - entity-id] - [:ul - (for [[k v] data] - [:li [:strong k] ":" v] - )]])) + (html-response + [:div.box [:h1.title "Snapshot of " + entity-id] + [:ul + (for [[k v] data] + [:li [:strong k] ":" v] + )]])) (catch NumberFormatException e - (html [:div.notification.is-danger.is-light - "Cannot parse the entity-id " entity-id ". It should be a number."])))) + (html-response + [:div.notification.is-danger.is-light + "Cannot parse the entity-id " entity-id ". It should be a number."])))) -(defn history [request] - (str "" - (html - (base-page (page-template ))))) - -(defn- with-ignore-trailing-slash [handler] - (fn [request] - (let [uri (request :uri) - clean-uri (str/replace uri #"^(.+?)/+$" "$1")] - (handler (assoc request :uri clean-uri))))) +(defn history [{:keys [identity] :as request}] + (html-response + (base-page request (page-template )))) (defroutes admin-routes - (wrap-routes - (context "/admin" [] - (GET "/history" [] history) - (GET "/history/" [] history) - (POST "/history/search" [] history-search) - #_(GET "/history/:entity-id" [entity-id] history-search) - #_(GET "/history/inspect/:entity-id" [entity-id] inspect)) - with-ignore-trailing-slash)) + (routes + (context "/admin" [] + (GET "/history" [] history) + (GET "/history/" [] history) + (POST "/history/search" [] history-search) + (GET "/history/:entity-id" [entity-id] history-search) + (GET "/history/inspect/:entity-id" [entity-id] inspect)))) diff --git a/src/clj/user.clj b/src/clj/user.clj index 0e31c6b5..1f5bbc93 100644 --- a/src/clj/user.clj +++ b/src/clj/user.clj @@ -381,7 +381,7 @@ #_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]} (defn tx-detail [i] - (map (juxt :e #(d/ident (d/db (d/connect uri)) (:a %)) :v) + (map (juxt :e #(d/ident (d/db (d/connect uri)) (:a %)) :v :added?) (:data (first (d/tx-range (d/log (d/connect uri)) i diff --git a/src/cljs/auto_ap/core.cljs b/src/cljs/auto_ap/core.cljs index fc647c7e..60c6955f 100644 --- a/src/cljs/auto_ap/core.cljs +++ b/src/cljs/auto_ap/core.cljs @@ -27,13 +27,7 @@ (defn ^:export init [] (dev-setup) - (.addEventListener (.-body js/document) - "htmx:configRequest" - (fn [event] - (aset (.-headers (.-detail event)) - "Authorization" - (some->> (.getItem js/localStorage "jwt") - (str "Token "))))) + ;; document.body.addEventListener('htmx:configRequest', function(evt) { diff --git a/src/cljs/auto_ap/views/components/admin/side_bar.cljs b/src/cljs/auto_ap/views/components/admin/side_bar.cljs index 7e4a4ce3..cb0dc0b8 100644 --- a/src/cljs/auto_ap/views/components/admin/side_bar.cljs +++ b/src/cljs/auto_ap/views/components/admin/side_bar.cljs @@ -46,7 +46,7 @@ [:span {:class "icon icon-cog-play-1" :style {:font-size "25px"}}] [:span {:class "name"} "Rules"]]] [:li.menu-item - [:a {:href "/admin/history", :class (str "item" (active-when ap = :admin-history))} + [:a {:href (str "/admin/history?jwt=" (.getItem js/localStorage "jwt")) :class (str "item" (active-when ap = :admin-history))} [:span {:class "icon icon-cog-play-1" :style {:font-size "25px"}}] [:span {:class "name"} "History"]]] [:ul ]] diff --git a/src/cljs/auto_ap/views/main.cljs b/src/cljs/auto_ap/views/main.cljs index 38d70318..51108ed0 100644 --- a/src/cljs/auto_ap/views/main.cljs +++ b/src/cljs/auto_ap/views/main.cljs @@ -12,7 +12,6 @@ [auto-ap.views.pages.error :refer [error-page]] [auto-ap.views.pages.ledger.balance-sheet :refer [balance-sheet-page]] [auto-ap.views.pages.admin.jobs :refer [jobs-page]] - [auto-ap.views.pages.admin.history :refer [history-page]] [auto-ap.views.pages.ledger.external-import :refer [external-import-page]] [auto-ap.views.pages.ledger.external-ledger :refer [external-ledger-page]] [auto-ap.views.pages.ledger.profit-and-loss :refer [profit-and-loss-page]] @@ -155,9 +154,6 @@ [admin-excel-import-page]) -(defmethod page :admin-history [_] - [history-page]) - (defmethod page :initial-error [_] [error-page]) diff --git a/src/cljs/auto_ap/views/pages/admin/history.cljs b/src/cljs/auto_ap/views/pages/admin/history.cljs deleted file mode 100644 index 156c5ed3..00000000 --- a/src/cljs/auto_ap/views/pages/admin/history.cljs +++ /dev/null @@ -1,40 +0,0 @@ -(ns auto-ap.views.pages.admin.history - (:require - [auto-ap.status :as status] - [auto-ap.subs :as subs] - [auto-ap.views.components.admin.side-bar :refer [admin-side-bar]] - [auto-ap.views.components.layouts :refer [side-bar-layout]] - [auto-ap.views.pages.admin.jobs.table :as table] - [auto-ap.views.components.modal :as modal] - [auto-ap.views.components :as com] - [auto-ap.views.pages.data-page :as data-page] - [auto-ap.views.utils :refer [dispatch-event with-user]] - [clojure.set :as set] - [re-frame.core :as re-frame] - [vimsical.re-frame.fx.track :as track] - [auto-ap.forms.builder :as form-builder] - [vimsical.re-frame.cofx.inject :as inject] - [auto-ap.forms :as forms] - [clojure.string :as str] - ["htmx.org" :as htmx] - )) - -;; VIEWS -(def history-content - (let [c (atom nil)] - (with-meta - (fn [] - (println "bothered?") - [:div {"hx-get" (.-pathname (.-location js/document)) - "hx-trigger" "load" - "hx-swap" "outerHTML" - :ref (fn [i] (reset! c i))} - "test"]) - {:should-component-update (fn [] false) - :component-did-mount (fn [] - (.process htmx @c))}))) - -(defn history-page [] - [side-bar-layout {:side-bar [admin-side-bar {}] - :main [history-content]}]) -