From 0b39bc3efc65fa774341e7808091f8817e727ca4 Mon Sep 17 00:00:00 2001 From: kaspazza Date: Tue, 3 Sep 2024 11:48:08 +0200 Subject: [PATCH] 2.0.0 --- .github/workflows/validation_delaguardo.yml | 3 +- ...ation_docker.yml => validation_docker.old} | 0 .zprintrc | 3 +- bb.edn | 20 +- build_config.edn | 42 ++-- deps.edn | 50 ++-- package-lock.json | 227 +++++++++++++++++- package.json | 6 +- pom.xml | 4 +- project.edn | 17 +- resources/company.edn | 11 +- resources/css/main.css | 94 ++++++++ shadow-cljs.edn | 11 +- .../adapters/be/http_response.clj | 4 +- src/clj/automaton_web/duplex/core.clj | 13 +- .../automaton_web/duplex/message_handler.clj | 4 +- src/clj/automaton_web/duplex/routes.clj | 11 +- src/clj/automaton_web/handlers.clj | 9 +- src/clj/automaton_web/i18n/be/translator.clj | 22 +- .../i18n/be/translator/tempura.clj | 37 ++- src/clj/automaton_web/middleware.clj | 38 +-- src/clj/automaton_web/pages/admin.clj | 182 ++++++-------- src/clj/automaton_web/pages/admin/route.clj | 5 +- src/clj/automaton_web/pages/errors.clj | 16 +- src/clj/automaton_web/pages/index.clj | 10 +- .../automaton_web/pages/portfolio/route.clj | 15 +- src/clj/automaton_web/router.clj | 14 +- src/clj/automaton_web/web_server.clj | 6 +- src/cljc/automaton_web/components/button.cljc | 6 +- src/cljc/automaton_web/components/card.cljc | 43 +--- src/cljc/automaton_web/components/common.cljc | 5 +- src/cljc/automaton_web/components/errors.cljc | 40 ++- src/cljc/automaton_web/components/footer.cljc | 69 ++---- .../automaton_web/components/grid_list.cljc | 23 +- src/cljc/automaton_web/components/header.cljc | 9 +- src/cljc/automaton_web/components/icons.cljc | 4 +- src/cljc/automaton_web/components/menu.cljc | 21 +- .../automaton_web/components/menu_item.cljc | 3 +- src/cljc/automaton_web/components/modal.cljc | 78 ------ src/cljc/automaton_web/components/player.cljc | 8 +- .../automaton_web/components/section.cljc | 85 ++----- .../components/simple_select.cljc | 3 +- .../automaton_web/components/structure.cljc | 3 +- src/cljc/automaton_web/components/table.cljc | 21 +- src/cljc/automaton_web/configuration.cljc | 4 +- .../automaton_web/configuration/files.cljc | 6 +- src/cljc/automaton_web/duplex/route.cljc | 7 +- src/cljc/automaton_web/hiccup.cljc | 3 +- src/cljc/automaton_web/i18n/dict/text.cljc | 39 +-- src/cljc/automaton_web/i18n/language.cljc | 8 +- src/cljc/automaton_web/routes.cljc | 10 +- src/cljs/automaton_web/components/cards.cljs | 84 +++++++ .../components/fe_language_select.cljs | 15 +- .../automaton_web/components/file_loader.cljs | 105 ++++---- src/cljs/automaton_web/components/form.cljs | 139 +++++------ src/cljs/automaton_web/components/iframe.cljs | 64 +++-- .../components/init_components.cljs | 66 ----- src/cljs/automaton_web/components/input.cljs | 77 +----- .../automaton_web/components/mailchimp.cljs | 62 ++--- src/cljs/automaton_web/components/modal.cljs | 36 +++ src/cljs/automaton_web/components/todos.cljs | 6 +- .../automaton_web/components/tooltip.cljs | 11 +- src/cljs/automaton_web/duplex/core.cljs | 26 +- .../automaton_web/duplex/message_handler.cljs | 15 +- src/cljs/automaton_web/duplex/router.cljs | 10 +- src/cljs/automaton_web/events/fx.cljs | 3 +- src/cljs/automaton_web/events_proxy.cljs | 5 +- src/cljs/automaton_web/fe/history/reitit.cljs | 14 +- src/cljs/automaton_web/fe/router/reitit.cljs | 12 +- .../i18n/fe/auto_web_translator.cljs | 6 +- .../automaton_web/i18n/fe/translator.cljs | 6 +- .../i18n/fe/translator/tempura.cljs | 9 +- .../automaton_web/log/tracking/sentry.cljs | 7 +- .../portfolio/components/button.cljs | 17 +- .../portfolio/components/card.cljs | 66 ++++- .../portfolio/components/checkbox.cljs | 74 +++--- .../portfolio/components/footer.cljs | 73 +++--- .../portfolio/components/form.cljs | 43 ++-- .../portfolio/components/grid_list.cljs | 3 +- .../portfolio/components/header.cljs | 12 +- .../portfolio/components/icons.cljs | 12 +- .../portfolio/components/input.cljs | 20 +- .../portfolio/components/mailchimp.cljs | 27 +-- .../portfolio/components/menu.cljs | 48 ++-- .../portfolio/components/menu_item.cljs | 9 +- .../portfolio/components/modal.cljs | 71 ++---- .../portfolio/components/navigation.cljs | 3 +- .../portfolio/components/player.cljs | 11 +- .../portfolio/components/section.cljs | 50 +--- .../portfolio/components/select.cljs | 6 +- .../portfolio/components/spinner.cljs | 3 +- .../portfolio/components/structure.cljs | 13 +- .../portfolio/components/table.cljs | 27 +-- .../portfolio/components/tooltip.cljs | 3 +- .../portfolio/components/version.cljs | 3 +- .../automaton_web/portfolio/pages/error.cljs | 10 +- src/cljs/automaton_web/portfolio/proxy.cljs | 22 +- tailwind.config.js | 6 +- .../adapters/be/http_request_test.clj | 3 +- .../adapters/be/http_response_test.clj | 3 +- test/clj/automaton_web/duplex/core_test.clj | 8 +- test/clj/automaton_web/duplex/routes_test.clj | 11 +- .../clj/automaton_web/duplex/session_test.clj | 33 +-- test/clj/automaton_web/handlers_test.clj | 13 +- .../i18n/be/translator/tempura_test.clj | 19 +- .../automaton_web/i18n/be/translator_test.clj | 26 +- .../clj/automaton_web/i18n/language_test.cljc | 5 +- test/clj/automaton_web/middleware_test.clj | 18 +- .../web_elt/string_to_id_test.cljc | 3 +- .../automaton_web/components/common_test.cljc | 12 +- .../automaton_web/i18n/dictionary_test.cljc | 18 +- .../i18n/resource_dict_test.cljc | 18 +- test/cljc/automaton_web/js_interop_test.cljc | 6 +- .../persistence/cookies_test.cljc | 14 +- test/cljc/automaton_web/reagent_test.cljc | 15 +- test/cljc/automaton_web/routes_test.cljc | 6 +- .../components/init_components_test.cljs | 28 --- version.edn | 2 +- 118 files changed, 1361 insertions(+), 1682 deletions(-) rename .github/workflows/{validation_docker.yml => validation_docker.old} (100%) delete mode 100644 src/cljc/automaton_web/components/modal.cljc create mode 100644 src/cljs/automaton_web/components/cards.cljs delete mode 100644 src/cljs/automaton_web/components/init_components.cljs create mode 100644 src/cljs/automaton_web/components/modal.cljs delete mode 100644 test/cljs/automaton_web/components/init_components_test.cljs diff --git a/.github/workflows/validation_delaguardo.yml b/.github/workflows/validation_delaguardo.yml index 4f97ab28..c19fe646 100644 --- a/.github/workflows/validation_delaguardo.yml +++ b/.github/workflows/validation_delaguardo.yml @@ -4,7 +4,8 @@ jobs: clojure: strategy: matrix: - os: [ubuntu-latest, macOS-latest] # , windows-latest There is a path issue + os: [ubuntu-latest] # , windows-latest There is a path issue + # macOS-latest is removed to save github costs runs-on: ${{ matrix.os }} steps: - name: Checkout diff --git a/.github/workflows/validation_docker.yml b/.github/workflows/validation_docker.old similarity index 100% rename from .github/workflows/validation_docker.yml rename to .github/workflows/validation_docker.old diff --git a/.zprintrc b/.zprintrc index 643a3f42..ebbd6af5 100644 --- a/.zprintrc +++ b/.zprintrc @@ -11,4 +11,5 @@ :force-nl? true} :pair {:force-nl? true} :pair-fn {:hang? false} - :comment {:wrap? false}} + :comment {:wrap? false} + :width 100} diff --git a/bb.edn b/bb.edn index 406e0102..8fe36fa3 100644 --- a/bb.edn +++ b/bb.edn @@ -1,21 +1,17 @@ ;; The file is updated automatically -{:deps {org.clojars.hephaistox/automaton-build #:mvn{:version "3.0.0"}} +{:deps {org.clojars.hephaistox/automaton-build #:mvn{:version "3.0.1"}} :paths [] :tasks - {:requires - [[automaton-build.tasks.launcher.bb-entrypoint :as build-task-bb-entrypoint] - [babashka.process :as babahska-process]] + {:requires [[automaton-build.tasks.launcher.bb-entrypoint :as build-task-bb-entrypoint] + [babashka.process :as babahska-process]] heph-task {:doc "Launch an Hephaistox task" - :task (System/exit (build-task-bb-entrypoint/-main - *command-line-args*))} + :task (System/exit (build-task-bb-entrypoint/-main *command-line-args*))} lconnect {:doc "Repl in case automaton-web is failing. Using -f or --force cli arguments to force start if some part are failing" - :task (try (-> (babahska-process/shell - "clojure" - "-M:common-test:env-development-repl:build" - *command-line-args*) + :task (try (-> (babahska-process/shell "clojure" + "-M:common-test:env-development-repl:build" + *command-line-args*) System/exit) (catch Exception e - (println "Repl failed also - error during repl startup" - (ex-message e))))}}} + (println "Repl failed also - error during repl startup" (ex-message e))))}}} diff --git a/build_config.edn b/build_config.edn index 2cbe1b95..bec954c7 100644 --- a/build_config.edn +++ b/build_config.edn @@ -1,27 +1,21 @@ {:app-name "automaton-web" :task-shared {:gha {} - :publication - {:as-lib org.clojars.hephaistox/automaton-web - :deploy-to :clojars - :env {:la {} - :production {}} - :frontend {:css {} - :run-aliases - [:automaton-web-portfolio :browser-test :ltest]} - :license {} - :repo "git@github.com:hephaistox/automaton-web.git"} + :publication {:as-lib org.clojars.hephaistox/automaton-web + :deploy-to :clojars + :env {:la {} + :production {}} + :frontend {:css {} + :run-aliases + [:automaton-web-portfolio :browser-test :ltest]} + :license {} + :repo "git@github.com:hephaistox/automaton-web.git"} :repl-aliases [:common-test :env-development-repl :build]} - :tasks {:clean {:dirs [".cpcache/" - ".clj-kondo/.cache/" - "tmp/" - "target/" - "node_modules/" - ".shadow-cljs/builds/"]} - :lfe-css {} - :lfe-test {} - :lfe-watch {} - :reports {:forbiddenwords-words #{"automaton-build" "landing" "tap>"}} - :update-deps {:exclude-libs - #{"com.taoensso/encore" - "org.clojars.hephaistox/automaton-build@*-*" - "org.clojars.hephaistox/automaton-core@*-*"}}}} + :tasks + {:clean + {:dirs [".cpcache/" ".clj-kondo/.cache/" "tmp/" "target/" "node_modules/" ".shadow-cljs/builds/"]} + :lfe-css {} + :lfe-test {} + :lfe-watch {} + :reports {:forbiddenwords-words #{"automaton-build" "landing" "tap>"}} + :update-deps {:exclude-libs #{"com.taoensso/encore" "org.clojars.hephaistox/automaton-build@*-*" + "org.clojars.hephaistox/automaton-core@*-*"}}}} diff --git a/deps.edn b/deps.edn index d9019645..def46919 100644 --- a/deps.edn +++ b/deps.edn @@ -1,10 +1,8 @@ {:aliases {:antq {:deps {com.github.liquidz/antq {:mvn/version "2.9.1217"}} :main-opts ["-m" "antq.core"]} - :bb-deps {:extra-deps {org.clojars.hephaistox/automaton-build - #:mvn{:version "3.0.0"}}} - :build {:extra-deps {org.clojars.hephaistox/automaton-build - #:mvn{:version "3.0.0"}} + :bb-deps {:extra-deps {org.clojars.hephaistox/automaton-build #:mvn{:version "3.0.1"}}} + :build {:extra-deps {org.clojars.hephaistox/automaton-build #:mvn{:version "3.0.1"}} :ns-default build} :cljs-deps {:extra-deps {binaryage/devtools #:mvn{:version "1.0.7"} clj-commons/pushy #:mvn{:version "0.3.10"} @@ -30,37 +28,27 @@ "test/cljc/" "env/development/src/cljc/" "env/development/src/cljs/"]} - :common-test - {:exec-fn cognitect.test-runner.api/test - :extra-deps {com.cognitect/test-runner - {:git/url "https://github.com/cognitect-labs/test-runner" - :sha "9d36f36ff541dac680a05010e4348c744333f191"} - org.clojure/tools.namespace #:mvn{:version "1.5.0"} - org.clojure/tools.reader #:mvn{:version "1.5.0"}} - :extra-paths ["test/clj/" "test/cljc/" "test/resources/"] - :jvm-opts ["-Dheph-conf=env/test/config.edn,env/common_config.edn"]} - :env-development-repl - {:extra-deps {org.clojars.hephaistox/automaton-core #:mvn{:version - "1.3.0"} - org.clojure/core.async #:mvn{:version "1.6.681"}} - :extra-paths ["env/development/resources/" - "env/development/src/clj/" - "env/development/src/cljc/"] - :jvm-opts ["-Dheph-conf=env/development/config.edn,env/common_config.edn"] - :main-opts ["-m" "automaton-web.repl.entry-point"]} + :common-test {:exec-fn cognitect.test-runner.api/test + :extra-deps {com.cognitect/test-runner + {:git/url "https://github.com/cognitect-labs/test-runner" + :sha "9d36f36ff541dac680a05010e4348c744333f191"} + org.clojure/tools.namespace #:mvn{:version "1.5.0"} + org.clojure/tools.reader #:mvn{:version "1.5.0"}} + :extra-paths ["test/clj/" "test/cljc/" "test/resources/"] + :jvm-opts ["-Dheph-conf=env/test/config.edn,env/common_config.edn"]} + :env-development-repl {:extra-deps {org.clojars.hephaistox/automaton-core #:mvn{:version "1.3.1"} + org.clojure/core.async #:mvn{:version "1.6.681"}} + :extra-paths ["env/development/resources/" + "env/development/src/clj/" + "env/development/src/cljc/"] + :jvm-opts ["-Dheph-conf=env/development/config.edn,env/common_config.edn"] + :main-opts ["-m" "automaton-web.repl.entry-point"]} :env-development-test {:jvm-opts ["-Dclojure.tools.logging.factory=clojure.tools.logging.impl/log4j2-factory" "-Dhephaistox-in-test=true" "-Dlog4j.configurationFile=resources/log_config/appenders.properties,resources/log_config/logging-tests.properties"] - :main-opts ["-m" - "cognitect.test-runner" - "-r" - ".*-test.*" - "-d" - "test/clj" - "-d" - "test/cljc"]}} + :main-opts ["-m" "cognitect.test-runner" "-r" ".*-test.*" "-d" "test/clj" "-d" "test/cljc"]}} :deps {amalloy/ring-gzip-middleware #:mvn{:version "0.1.4"} com.taoensso/sente #:mvn{:version "1.19.2"} hiccup/hiccup #:mvn{:version "2.0.0-RC3"} @@ -69,7 +57,7 @@ metosin/reitit #:mvn{:version "0.7.1"} metosin/ring-http-response #:mvn{:version "0.9.4"} mount/mount #:mvn{:version "0.1.19"} - org.clojars.hephaistox/automaton-core #:mvn{:version "1.3.0"} + org.clojars.hephaistox/automaton-core #:mvn{:version "1.3.1"} ring-cors/ring-cors #:mvn{:version "0.1.13"} ring/ring #:mvn{:version "1.12.2"} ring/ring-anti-forgery #:mvn{:version "1.3.1"} diff --git a/package-lock.json b/package-lock.json index 2192b271..b72875b6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,17 +9,17 @@ "version": "1.0.0", "license": "MIT", "dependencies": { + "@headlessui/react": "^2.1.3", "@sentry/react": "^8.26.0", "autoprefixer": "^10.4.20", "axe-core": "^4.10.0", "create-react-class": "^15.7.0", "react": "^18.3.1", "react-dom": "^18.3.1", - "react-router-dom": "^6.26.1", - "tw-elements": "^2.0.0" + "react-router-dom": "^6.26.1" }, "devDependencies": { - "@hephaistox/tailwind-config": "github:hephaistox/tailwind-config#main", + "@hephaistox/tailwind-config": "github:hephaistox/tailwind-config#f8da71dcc315ac6f3652695a92495ea3f5298d13", "@tailwindcss/forms": "^0.5.7", "highlight.js": "^11.10.0", "karma": "^6.4.4", @@ -54,9 +54,82 @@ "node": ">=0.1.90" } }, + "node_modules/@floating-ui/core": { + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.7.tgz", + "integrity": "sha512-yDzVT/Lm101nQ5TCVeK65LtdN7Tj4Qpr9RTXJ2vPFLqtLxwOrpoxAHAJI8J3yYWUc40J0BDBheaitK5SJmno2g==", + "license": "MIT", + "dependencies": { + "@floating-ui/utils": "^0.2.7" + } + }, + "node_modules/@floating-ui/dom": { + "version": "1.6.10", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.10.tgz", + "integrity": "sha512-fskgCFv8J8OamCmyun8MfjB1Olfn+uZKjOKZ0vhYF3gRmEUXcGOjxWL8bBr7i4kIuPZ2KD2S3EUIOxnjC8kl2A==", + "license": "MIT", + "dependencies": { + "@floating-ui/core": "^1.6.0", + "@floating-ui/utils": "^0.2.7" + } + }, + "node_modules/@floating-ui/react": { + "version": "0.26.23", + "resolved": "https://registry.npmjs.org/@floating-ui/react/-/react-0.26.23.tgz", + "integrity": "sha512-9u3i62fV0CFF3nIegiWiRDwOs7OW/KhSUJDNx2MkQM3LbE5zQOY01sL3nelcVBXvX7Ovvo3A49I8ql+20Wg/Hw==", + "license": "MIT", + "dependencies": { + "@floating-ui/react-dom": "^2.1.1", + "@floating-ui/utils": "^0.2.7", + "tabbable": "^6.0.0" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@floating-ui/react-dom": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.1.tgz", + "integrity": "sha512-4h84MJt3CHrtG18mGsXuLCHMrug49d7DFkU0RMIyshRveBeyV2hmV/pDaF2Uxtu8kgq5r46llp5E5FQiR0K2Yg==", + "license": "MIT", + "dependencies": { + "@floating-ui/dom": "^1.0.0" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@floating-ui/utils": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.7.tgz", + "integrity": "sha512-X8R8Oj771YRl/w+c1HqAC1szL8zWQRwFvgDwT129k9ACdBoud/+/rX9V0qiMl6LWUdP9voC2nDVZYPMQQsb6eA==", + "license": "MIT" + }, + "node_modules/@headlessui/react": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@headlessui/react/-/react-2.1.3.tgz", + "integrity": "sha512-Nt+NlnQbVvMHVZ/QsST6DNyfG8VWqjOYY3eZpp0PrRKpmZw+pzhwQ1F6wtNaW4jnudeC2a5MJC70vbGVcETNIg==", + "license": "MIT", + "dependencies": { + "@floating-ui/react": "^0.26.16", + "@react-aria/focus": "^3.17.1", + "@react-aria/interactions": "^3.21.3", + "@tanstack/react-virtual": "^3.8.1" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "react": "^18", + "react-dom": "^18" + } + }, "node_modules/@hephaistox/tailwind-config": { "version": "1.0.0", - "resolved": "git+ssh://git@github.com/hephaistox/tailwind-config.git#f03b53ac4a04627d9230f80a2382adbb827ffa7b", + "resolved": "git+ssh://git@github.com/hephaistox/tailwind-config.git#f8da71dcc315ac6f3652695a92495ea3f5298d13", + "integrity": "sha512-ICAxs309iLS6HdUpe5eFPnv39LC0CC5gyzl6aOKPGom1DyxmonWhhhvsHcwBRGIA6PVptpBk6PU5xkQxK3Xlyg==", "dev": true, "license": "ISC" }, @@ -265,6 +338,89 @@ "node": ">=14" } }, + "node_modules/@react-aria/focus": { + "version": "3.18.2", + "resolved": "https://registry.npmjs.org/@react-aria/focus/-/focus-3.18.2.tgz", + "integrity": "sha512-Jc/IY+StjA3uqN73o6txKQ527RFU7gnG5crEl5Xy3V+gbYp2O5L3ezAo/E0Ipi2cyMbG6T5Iit1IDs7hcGu8aw==", + "license": "Apache-2.0", + "dependencies": { + "@react-aria/interactions": "^3.22.2", + "@react-aria/utils": "^3.25.2", + "@react-types/shared": "^3.24.1", + "@swc/helpers": "^0.5.0", + "clsx": "^2.0.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/@react-aria/interactions": { + "version": "3.22.2", + "resolved": "https://registry.npmjs.org/@react-aria/interactions/-/interactions-3.22.2.tgz", + "integrity": "sha512-xE/77fRVSlqHp2sfkrMeNLrqf2amF/RyuAS6T5oDJemRSgYM3UoxTbWjucPhfnoW7r32pFPHHgz4lbdX8xqD/g==", + "license": "Apache-2.0", + "dependencies": { + "@react-aria/ssr": "^3.9.5", + "@react-aria/utils": "^3.25.2", + "@react-types/shared": "^3.24.1", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/@react-aria/ssr": { + "version": "3.9.5", + "resolved": "https://registry.npmjs.org/@react-aria/ssr/-/ssr-3.9.5.tgz", + "integrity": "sha512-xEwGKoysu+oXulibNUSkXf8itW0npHHTa6c4AyYeZIJyRoegeteYuFpZUBPtIDE8RfHdNsSmE1ssOkxRnwbkuQ==", + "license": "Apache-2.0", + "dependencies": { + "@swc/helpers": "^0.5.0" + }, + "engines": { + "node": ">= 12" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/@react-aria/utils": { + "version": "3.25.2", + "resolved": "https://registry.npmjs.org/@react-aria/utils/-/utils-3.25.2.tgz", + "integrity": "sha512-GdIvG8GBJJZygB4L2QJP1Gabyn2mjFsha73I2wSe+o4DYeGWoJiMZRM06PyTIxLH4S7Sn7eVDtsSBfkc2VY/NA==", + "license": "Apache-2.0", + "dependencies": { + "@react-aria/ssr": "^3.9.5", + "@react-stately/utils": "^3.10.3", + "@react-types/shared": "^3.24.1", + "@swc/helpers": "^0.5.0", + "clsx": "^2.0.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/@react-stately/utils": { + "version": "3.10.3", + "resolved": "https://registry.npmjs.org/@react-stately/utils/-/utils-3.10.3.tgz", + "integrity": "sha512-moClv7MlVSHpbYtQIkm0Cx+on8Pgt1XqtPx6fy9rQFb2DNc9u1G3AUVnqA17buOkH1vLxAtX4MedlxMWyRCYYA==", + "license": "Apache-2.0", + "dependencies": { + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/@react-types/shared": { + "version": "3.24.1", + "resolved": "https://registry.npmjs.org/@react-types/shared/-/shared-3.24.1.tgz", + "integrity": "sha512-AUQeGYEm/zDTN6zLzdXolDxz3Jk5dDL7f506F07U8tBwxNNI3WRdhU84G0/AaFikOZzDXhOZDr3MhQMzyE7Ydw==", + "license": "Apache-2.0", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" + } + }, "node_modules/@remix-run/router": { "version": "1.19.1", "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.19.1.tgz", @@ -410,6 +566,15 @@ "dev": true, "license": "MIT" }, + "node_modules/@swc/helpers": { + "version": "0.5.12", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.12.tgz", + "integrity": "sha512-KMZNXiGibsW9kvZAO1Pam2JPTDBm+KSHMMHWdsyI/1DbIZjT2A6Gy3hblVXUMEDvUAKq+e0vL0X0o54owWji7g==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.4.0" + } + }, "node_modules/@tailwindcss/forms": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/@tailwindcss/forms/-/forms-0.5.7.tgz", @@ -423,6 +588,33 @@ "tailwindcss": ">=3.0.0 || >= 3.0.0-alpha.1" } }, + "node_modules/@tanstack/react-virtual": { + "version": "3.10.6", + "resolved": "https://registry.npmjs.org/@tanstack/react-virtual/-/react-virtual-3.10.6.tgz", + "integrity": "sha512-xaSy6uUxB92O8mngHZ6CvbhGuqxQ5lIZWCBy+FjhrbHmOwc6BnOnKkYm2FsB1/BpKw/+FVctlMbEtI+F6I1aJg==", + "license": "MIT", + "dependencies": { + "@tanstack/virtual-core": "3.10.6" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/@tanstack/virtual-core": { + "version": "3.10.6", + "resolved": "https://registry.npmjs.org/@tanstack/virtual-core/-/virtual-core-3.10.6.tgz", + "integrity": "sha512-1giLc4dzgEKLMx5pgKjL6HlG5fjZMgCjzlKAlpr7yoUtetVPELgER1NtephAI910nMwfPTHNyWKSFmJdHkz2Cw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, "node_modules/@types/cookie": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz", @@ -974,6 +1166,15 @@ "wrap-ansi": "^7.0.0" } }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -4000,6 +4201,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/tabbable": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz", + "integrity": "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==", + "license": "MIT" + }, "node_modules/tailwindcss": { "version": "3.4.10", "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.10.tgz", @@ -4134,6 +4341,12 @@ "dev": true, "license": "Apache-2.0" }, + "node_modules/tslib": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", + "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==", + "license": "0BSD" + }, "node_modules/tty-browserify": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", @@ -4141,12 +4354,6 @@ "dev": true, "license": "MIT" }, - "node_modules/tw-elements": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/tw-elements/-/tw-elements-2.0.0.tgz", - "integrity": "sha512-aiitkqzmCZIZ9zJr3V6ErVzU/CrKoAkptpv94t0pEKnVn2Ah4jOplXOO/v6Fo9jr3PoTA5dxvlyS4w8rnW/iag==", - "license": "SEE LICENSE IN " - }, "node_modules/type-is": { "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", diff --git a/package.json b/package.json index 94c23675..d73d5abb 100644 --- a/package.json +++ b/package.json @@ -8,18 +8,18 @@ "version": "1.0.0", "author": "Hephaistox ", "dependencies": { + "@headlessui/react": "^2.1.3", "@sentry/react": "^8.26.0", "autoprefixer": "^10.4.20", "axe-core": "^4.10.0", "create-react-class": "^15.7.0", "react": "^18.3.1", "react-dom": "^18.3.1", - "react-router-dom": "^6.26.1", - "tw-elements": "^2.0.0" + "react-router-dom": "^6.26.1" }, "workspaces": [], "devDependencies": { - "@hephaistox/tailwind-config": "github:hephaistox/tailwind-config#main", + "@hephaistox/tailwind-config": "github:hephaistox/tailwind-config#f8da71dcc315ac6f3652695a92495ea3f5298d13", "@tailwindcss/forms": "^0.5.7", "highlight.js": "^11.10.0", "karma": "^6.4.4", diff --git a/pom.xml b/pom.xml index beedf029..73ab6983 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ jar org.clojars.hephaistox automaton-web - 1.3.0 + 2.0.0 automaton-web @@ -30,7 +30,7 @@ org.clojars.hephaistox automaton-core - 1.3.0 + 1.3.1 ring-cors diff --git a/project.edn b/project.edn index 140a4dd6..a0e4e85a 100644 --- a/project.edn +++ b/project.edn @@ -1,11 +1,8 @@ {:app-name "automaton-web" - :code {:forbidden-words #{"DONE" "FIXME" "NOTE" "TODO" "automaton-build" - "landing" "tap>"}} - :deps - {:excluded-libs - [{:name "com.taoensso/encore"} - {:doc - "Updating any of taoensso libs results in cljs warnings comming from taoensso/timbre" - :name "com.taoensso/tempura" - :version "1.5.3"} - {:name "marked"}]}} + :code {:forbidden-words #{"DONE" "FIXME" "NOTE" "TODO" "automaton-build" "landing" "tap>"}} + :deps {:excluded-libs + [{:name "com.taoensso/encore"} + {:doc "Updating any of taoensso libs results in cljs warnings comming from taoensso/timbre" + :name "com.taoensso/tempura" + :version "1.5.3"} + {:name "marked"}]}} diff --git a/resources/company.edn b/resources/company.edn index b252c0af..45ffe56c 100644 --- a/resources/company.edn +++ b/resources/company.edn @@ -1,9 +1,8 @@ -{:activities [{:descriptions - ["Programmation" - "conseil et autres activités informatiques" - "Conseil enarchitecture logicielles" - "Conseil en supply chain, logistique et industrie" - "Formation"] +{:activities [{:descriptions ["Programmation" + "conseil et autres activités informatiques" + "Conseil enarchitecture logicielles" + "Conseil en supply chain, logistique et industrie" + "Formation"] :language "fr"}] :creation-date #inst "2021-11-15T00:00:00.000" :establishments [{:adress "5 RUE SAINT DOMINIQUE 63350 JOZE" diff --git a/resources/css/main.css b/resources/css/main.css index 53d979a9..cc521627 100644 --- a/resources/css/main.css +++ b/resources/css/main.css @@ -4,6 +4,100 @@ @tailwind utilities; @layer components { +.tooltip { + position: relative; + display: inline-block; + cursor: help; +} + +.tooltip .tooltiptext { + visibility: hidden; + width: 120px; + background-color: black; + color: #fff; + text-align: center; + padding: 5px 0; + border-radius: 6px; + + /* Position the tooltip text - see examples below! */ + position: absolute; + z-index: 1; +} + +.tooltip .tooltiptext-left { + top: -5px; + right: 105%; +} + +.tooltip .tooltiptext-right { + top: -5px; + left: 105%; +} + +.tooltip .tooltiptext-top { + width: 120px; + bottom: 100%; + left: 50%; + margin-left: -60px; /* Use half of the width (120/2 = 60), to center the tooltip */ +} + +.tooltip .tooltiptext-bottom { + width: 120px; + top: 100%; + left: 50%; + margin-left: -60px; /* Use half of the width (120/2 = 60), to center the tooltip */ +} + +.tooltip .tooltiptext-top::after { + content: " "; + position: absolute; + top: 100%; /* At the bottom of the tooltip */ + left: 50%; + margin-left: -5px; + border-width: 5px; + border-style: solid; + border-color: black transparent transparent transparent; +} + +.tooltip .tooltiptext-bottom::after { + content: " "; + position: absolute; + bottom: 100%; /* At the top of the tooltip */ + left: 50%; + margin-left: -5px; + border-width: 5px; + border-style: solid; + border-color: transparent transparent black transparent; +} + +.tooltip .tooltiptext-right::after { + content: " "; + position: absolute; + top: 50%; + right: 100%; /* To the left of the tooltip */ + margin-top: -5px; + border-width: 5px; + border-style: solid; + border-color: transparent black transparent transparent; +} + +.tooltip .tooltiptext-left::after { + content: " "; + position: absolute; + top: 50%; + left: 100%; /* To the right of the tooltip */ + margin-top: -5px; + border-width: 5px; + border-style: solid; + border-color: transparent transparent transparent black; +} + +/* Show the tooltip text when you mouse over the tooltip container */ +.tooltip:hover .tooltiptext { + visibility: visible; +} + + /* Fix for ios */ @supports (-webkit-touch-callout: none) { diff --git a/shadow-cljs.edn b/shadow-cljs.edn index 0e271535..baaf9b34 100644 --- a/shadow-cljs.edn +++ b/shadow-cljs.edn @@ -1,9 +1,8 @@ -{:builds {:automaton-web-portfolio - {:asset-path "js/compiled" - :modules {:automaton-web-main - {:init-fn automaton-web.portfolio.portfolio/init}} - :output-dir "resources/public/js/compiled" - :target :browser} +{:builds {:automaton-web-portfolio {:asset-path "js/compiled" + :modules {:automaton-web-main + {:init-fn automaton-web.portfolio.portfolio/init}} + :output-dir "resources/public/js/compiled" + :target :browser} :browser-test {:ns-regexp "-test$" :runner-ns shadow.test.browser :target :browser-test diff --git a/src/clj/automaton_web/adapters/be/http_response.clj b/src/clj/automaton_web/adapters/be/http_response.clj index 52dbffff..1afcde93 100644 --- a/src/clj/automaton_web/adapters/be/http_response.clj +++ b/src/clj/automaton_web/adapters/be/http_response.clj @@ -23,8 +23,6 @@ "405 Method Not Allowed (ClientError)" ring-http-response/method-not-allowed) -(def not-acceptable - "406 Not Acceptable (ClientError)" - ring-http-response/not-acceptable) +(def not-acceptable "406 Not Acceptable (ClientError)" ring-http-response/not-acceptable) (def internal-server-error ring-http-response/internal-server-error) diff --git a/src/clj/automaton_web/duplex/core.clj b/src/clj/automaton_web/duplex/core.clj index d414d77d..2fbc298a 100644 --- a/src/clj/automaton_web/duplex/core.clj +++ b/src/clj/automaton_web/duplex/core.clj @@ -13,11 +13,8 @@ [debug?] (let [{:keys [ch-recv] :as sente-map} - (sente/make-channel-socket! (get-sch-adapter) - {:user-id-fn (constantly 123456)}) - server (sente/start-server-chsk-router! - ch-recv - message-handler/event-msg-handler)] + (sente/make-channel-socket! (get-sch-adapter) {:user-id-fn (constantly 123456)}) + server (sente/start-server-chsk-router! ch-recv message-handler/event-msg-handler)] (when (= :development debug?) (sente/set-min-log-level! :warn)) (assoc sente-map :server server))) @@ -36,10 +33,8 @@ For an example see https://github.com/ptaoussanis/sente/tree/master/example-proj (let [res (start-rt (web-conf/read-param [:env]))] (core-log/trace "Duplex server component is started") res) - (catch Exception e - (core-log/error "Unexpected error during duplex start" e))) - :stop (when @duplex-server - (when-let [server (:server @duplex-server)] (server)))) + (catch Exception e (core-log/error "Unexpected error during duplex start" e))) + :stop (when @duplex-server (when-let [server (:server @duplex-server)] (server)))) (defn ajax-get-or-ws-handshake "Is the handshake handler" diff --git a/src/clj/automaton_web/duplex/message_handler.clj b/src/clj/automaton_web/duplex/message_handler.clj index de83726c..4a1bff6a 100644 --- a/src/clj/automaton_web/duplex/message_handler.clj +++ b/src/clj/automaton_web/duplex/message_handler.clj @@ -26,6 +26,4 @@ add some other defmethod, for all other messages" (core-log/trace "Default faultback realtime: uid=" uid ", session=" session) (when ?reply-fn (?reply-fn {:umatched-event-as-echoed-from-server event})))) -(defmethod -event-msg-handler :yop/test - [{:keys []}] - (core-log/trace "Test successful")) +(defmethod -event-msg-handler :yop/test [{:keys []}] (core-log/trace "Test successful")) diff --git a/src/clj/automaton_web/duplex/routes.clj b/src/clj/automaton_web/duplex/routes.clj index f051695a..d2c5b7cd 100644 --- a/src/clj/automaton_web/duplex/routes.clj +++ b/src/clj/automaton_web/duplex/routes.clj @@ -12,12 +12,11 @@ ([] (routes* (duplex/ajax-get-or-ws-handshake) (duplex/ajax-post))) ([get-handler put-handler] (let [route [duplex-route/duplex-uri {:summary "Realtime channel" - :middleware - [web-middleware/wrap-session - web-middleware/wrap-anti-forgery - web-middleware/parameters-middleware - web-middleware/wrap-keyword-params - web-middleware/wrap-copy-params] + :middleware [web-middleware/wrap-session + web-middleware/wrap-anti-forgery + web-middleware/parameters-middleware + web-middleware/wrap-keyword-params + web-middleware/wrap-copy-params] :get {:handler get-handler} :put {:handler put-handler}}]] route))) diff --git a/src/clj/automaton_web/handlers.clj b/src/clj/automaton_web/handlers.clj index f069f737..63b5f60b 100644 --- a/src/clj/automaton_web/handlers.clj +++ b/src/clj/automaton_web/handlers.clj @@ -40,11 +40,10 @@ * `handler` handler to wrap * `middlewares` is a collection of middlewares, could be a function or compile middlewares" [handler middlewares] - (reduce - (fn [handler middleware] - (if (fn? middleware) (middleware handler) ((:wrap middleware) handler))) - handler - middlewares)) + (reduce (fn [handler middleware] + (if (fn? middleware) (middleware handler) ((:wrap middleware) handler))) + handler + middlewares)) (defn default-handlers [{:keys [not-found not-allowed not-acceptable] diff --git a/src/clj/automaton_web/i18n/be/translator.clj b/src/clj/automaton_web/i18n/be/translator.clj index c56e807f..ec88a36a 100644 --- a/src/clj/automaton_web/i18n/be/translator.clj +++ b/src/clj/automaton_web/i18n/be/translator.clj @@ -42,16 +42,14 @@ * `http-request` request to parse" [web-translator http-request] (let [par-lang (http-request/get-param http-request :lang) - lang-str - (if (or (not (string? par-lang)) (str/blank? par-lang)) - (language-choice-strategy* - par-lang - (delay (http-request/cookies-language http-request)) - (delay (some-> (http-request/accepted-languages http-request) - (subs 0 2))) - (delay (some-> http-request - http-request/tld-language)) - (delay (first (core-translator/default-languages web-translator)))) - (do (core-log/trace "Language `" par-lang "` imposed by parameter") - par-lang))] + lang-str (if (or (not (string? par-lang)) (str/blank? par-lang)) + (language-choice-strategy* + par-lang + (delay (http-request/cookies-language http-request)) + (delay (some-> (http-request/accepted-languages http-request) + (subs 0 2))) + (delay (some-> http-request + http-request/tld-language)) + (delay (first (core-translator/default-languages web-translator)))) + (do (core-log/trace "Language `" par-lang "` imposed by parameter") par-lang))] lang-str)) diff --git a/src/clj/automaton_web/i18n/be/translator/tempura.clj b/src/clj/automaton_web/i18n/be/translator/tempura.clj index 1097f6d6..cb092f92 100644 --- a/src/clj/automaton_web/i18n/be/translator/tempura.clj +++ b/src/clj/automaton_web/i18n/be/translator/tempura.clj @@ -11,10 +11,7 @@ (defrecord TempuraWebTranslator [translator] be-translator/BeTranslator (wrap-translator [this] - (fn [handler] - (tempura/wrap-ring-request (be-translator/wrap-ring-request this - handler) - {}))) + (fn [handler] (tempura/wrap-ring-request (be-translator/wrap-ring-request this handler) {}))) (translate-based-on-request [_ {:keys [locales] :as _http-request} @@ -26,27 +23,23 @@ (wrap-ring-request [web-translator handler] (fn [{:keys [tempura/accept-langs_] :as http-request}] - (let [locales-str [(be-translator/language-choice-strategy - web-translator - http-request)] + (let [locales-str [(be-translator/language-choice-strategy web-translator http-request)] updated-request (-> http-request - (assoc :accept-langs accept-langs_ - :locales locales-str) + (assoc :accept-langs accept-langs_ :locales locales-str) (dissoc :tempura/accept-langs_ :tempura/tr))] (-> updated-request - (assoc - :tr - (fn - ([tr-id resources] - (be-translator/translate-based-on-request web-translator - updated-request - tr-id - resources)) - ([tr-id] - (be-translator/translate-based-on-request web-translator - updated-request - tr-id - nil)))) + (assoc :tr + (fn + ([tr-id resources] + (be-translator/translate-based-on-request web-translator + updated-request + tr-id + resources)) + ([tr-id] + (be-translator/translate-based-on-request web-translator + updated-request + tr-id + nil)))) handler (assoc-in [:headers "locales"] locales-str))))) core-translator/Translator diff --git a/src/clj/automaton_web/middleware.clj b/src/clj/automaton_web/middleware.clj index 98daa950..fab68c02 100644 --- a/src/clj/automaton_web/middleware.clj +++ b/src/clj/automaton_web/middleware.clj @@ -24,8 +24,7 @@ [_] (fn ([_] (throw (AssertionError. "this ERROR is thrown sync on purpose"))) - ([_ _ _] - (throw (AssertionError. "this ERROR is thrown async on purpose"))))) + ([_ _ _] (throw (AssertionError. "this ERROR is thrown async on purpose"))))) (defn wrap-throw-exception "Throws an exception, usefull for testing exception handling." @@ -58,15 +57,12 @@ "Disallow iFrame" [handler] (fn [request] - (let [resp (handler request)] - (ring-response/header resp "X-Frame-Options" "DENY")))) + (let [resp (handler request)] (ring-response/header resp "X-Frame-Options" "DENY")))) (defn wrap-copy-params "Copy in :request-copied key the request For dev only" - ([handler kw] - (fn [request] - (let [response (handler request)] (assoc response kw request)))) + ([handler kw] (fn [request] (let [response (handler request)] (assoc response kw request)))) ([handler] (wrap-copy-params handler :request-copied))) (defn wrap-gzip @@ -79,10 +75,7 @@ [handler & access-control] (apply ring-cors/wrap-cors handler access-control)) -(defn wrap-content-type - "to accept svg" - [handler] - (ring-content-type/wrap-content-type handler)) +(defn wrap-content-type "to accept svg" [handler] (ring-content-type/wrap-content-type handler)) (defn wrap-keyword-params "Translate string keys in the :params to keywords" @@ -101,13 +94,9 @@ "Negotiates a request body based on Content-Type header and response body based on Accept and Accept-Charset headers. Publishes the negotiation results as :muuntaja/request and :muuntaja/response keys into the request." rrmm/format-negotiate-middleware) -(def format-request-middleware - "Request decoding" - rrmm/format-request-middleware) +(def format-request-middleware "Request decoding" rrmm/format-request-middleware) -(def format-response-middleware - "Response encoding" - rrmm/format-response-middleware) +(def format-response-middleware "Response encoding" rrmm/format-response-middleware) (def coerce-exceptions-middleware rrc/coerce-exceptions-middleware) @@ -139,13 +128,10 @@ (defn- wrap-exception-handling* "Core of wrap-exception-handling fn, moved here for readability. Covers both sync and async version." ([handler request body-fn] - (try (handler request) - (catch Exception e - (core-log/error (ex-info "Fail in sync middleware." {:error e})) - (body-fn)) - (catch Error e - (core-log/fatal (ex-info "Fail in sync middleware." {:error e})) - (body-fn)))) + (try + (handler request) + (catch Exception e (core-log/error (ex-info "Fail in sync middleware." {:error e})) (body-fn)) + (catch Error e (core-log/fatal (ex-info "Fail in sync middleware." {:error e})) (body-fn)))) ([handler request respond raise body-fn] (try (handler request respond raise) (catch Exception e @@ -177,9 +163,7 @@ ([handler body] (fn ([request] - (wrap-exception-handling* handler - request - #(http-response/internal-server-error body))) + (wrap-exception-handling* handler request #(http-response/internal-server-error body))) ([request respond raise] (wrap-exception-handling* handler request diff --git a/src/clj/automaton_web/pages/admin.clj b/src/clj/automaton_web/pages/admin.clj index 55675e99..b9622641 100644 --- a/src/clj/automaton_web/pages/admin.clj +++ b/src/clj/automaton_web/pages/admin.clj @@ -94,10 +94,7 @@ :uri "https://hephaistox.sharepoint.com/sites/customers-materials/Documents%20partages/Forms/AllItems.aspx?id=%2Fsites%2Fcustomers%2Dmaterials%2FDocuments%20partages%2FDownloadable%20materials&p=true&ga=1"}]) -(defn sorted-items - "Create categories of menu item" - [m] - (sort (group-by :category m))) +(defn sorted-items "Create categories of menu item" [m] (sort (group-by :category m))) (defn component-graph-deps "Create component graph data from the mount components" @@ -105,16 +102,13 @@ (map (fn [m] (-> m (dissoc :order) - (assoc :status-color - (if (contains? (:status m) :started) :green :red)))) + (assoc :status-color (if (contains? (:status m) :started) :green :red)))) (sort-by :order graph))) (defn main-app-build-config-view [build-config-edn] (let [app-name (:app-name build-config-edn)] - [:div - [:div (str app-name " full build config:")] - (web-table/map->table build-config-edn)])) + [:div [:div (str app-name " full build config:")] (web-table/map->table build-config-edn)])) (defn display-links [items-by-category] @@ -130,110 +124,95 @@ [:a {:class ["cursor-pointer select-none"] :href uri :target "blank"} - [:div {:class - ["flex flex-row border-black border-solid border-2 m-2"]} + [:div {:class ["flex flex-row border-black border-solid border-2 m-2"]} [:div {:class ["m-2 p-2"]} message]]])]]))]) (defn all-apps-links [cust-apps] - (let [admin-maps - (reduce - (fn [acc app] - (let [app-name (:app-name app) - app-repo-link "to be done" - git-repo {:message "Git repo" - :category app-name - :uri app-repo-link} - doc (when (:doc? app) - {:message "TBC Docs" - :category app-name - :uri ""}) - envs (reduce (fn [acc [_ v]] - (conj acc - (when (:web-link v) - {:message (str "web-" (:remote-name v)) - :category app-name - :uri (:web-link v)}) - (when (:log-link v) - {:message (str "log-" (:remote-name v)) - :category app-name - :uri (:log-link v)}))) - [] - (:run-env app))] - (vec (flatten (vec (apply merge (conj acc git-repo doc) envs)))))) - [] - cust-apps) + (let [admin-maps (reduce (fn [acc app] + (let [app-name (:app-name app) + app-repo-link "to be done" + git-repo {:message "Git repo" + :category app-name + :uri app-repo-link} + doc (when (:doc? app) + {:message "TBC Docs" + :category app-name + :uri ""}) + envs (reduce (fn [acc [_ v]] + (conj acc + (when (:web-link v) + {:message (str "web-" (:remote-name v)) + :category app-name + :uri (:web-link v)}) + (when (:log-link v) + {:message (str "log-" (:remote-name v)) + :category app-name + :uri (:log-link v)}))) + [] + (:run-env app))] + (vec (flatten (vec (apply merge (conj acc git-repo doc) envs)))))) + [] + cust-apps) sorted-links (sorted-items admin-maps)] (display-links sorted-links))) -(defn- ignore-error - [fn-try ret-val] - (try (or (fn-try) ret-val) (catch Exception _ ret-val))) +(defn- ignore-error [fn-try ret-val] (try (or (fn-try) ret-val) (catch Exception _ ret-val))) (defn envs-indication [cust-apps] - (let - [gh-token (env-vars/get-env "GH_TOKEN") - rows - (reduce - (fn [acc app] - (let [app-name (get-in app [:app-name]) - local-env (get (version/slurp-version (str app-name "/")) - version/release) - gh-version (ignore-error - #(request/http-get - (str "https://api.github.com/repos/hephaistox/" - app-name - "/contents/version.edn") - {:headers {"Authorization" (str "Bearer " gh-token) - "Accept" - "application/vnd.github.raw+json"}}) - (atom "Error")) - gh-version-waited (ignore-error #(:release (read-string - (:body @gh-version))) - "Error") - prod-env - (ignore-error - #(request/http-get - (str (get-in app [:build-config :run-env :prod-env :web-link]) - "/api/version")) - (atom "Error")) - test-env - (ignore-error - #(request/http-get - (str (get-in app [:build-config :run-env :test-env :web-link]) - "/api/version")) - (atom "Error"))] - (conj - acc - [app-name - local-env - gh-version-waited - (:body @prod-env) - (:body @test-env) - (if (= local-env gh-version prod-env test-env) - (web-icons/icon - {:path-kw :svg/check-circle - :scale 0.03 - :color "green" - :class - ["w-[20px] + (let [gh-token (env-vars/get-env "GH_TOKEN") + rows + (reduce + (fn [acc app] + (let [app-name (get-in app [:app-name]) + local-env (get (version/slurp-version (str app-name "/")) version/release) + gh-version (ignore-error #(request/http-get + (str "https://api.github.com/repos/hephaistox/" + app-name + "/contents/version.edn") + {:headers {"Authorization" (str "Bearer " gh-token) + "Accept" "application/vnd.github.raw+json"}}) + (atom "Error")) + gh-version-waited (ignore-error #(:release (read-string (:body @gh-version))) + "Error") + prod-env (ignore-error #(request/http-get + (str (get-in app + [:build-config :run-env :prod-env :web-link]) + "/api/version")) + (atom "Error")) + test-env (ignore-error #(request/http-get + (str (get-in app + [:build-config :run-env :test-env :web-link]) + "/api/version")) + (atom "Error"))] + (conj + acc + [app-name + local-env + gh-version-waited + (:body @prod-env) + (:body @test-env) + (if (= local-env gh-version prod-env test-env) + (web-icons/icon + {:path-kw :svg/check-circle + :scale 0.03 + :color "green" + :class ["w-[20px] h-[20px]"] - :hover? false}) - (web-icons/icon - {:path-kw :svg/x-circle - :scale 0.03 - :color "red" - :class - ["w-[20px] + :hover? false}) + (web-icons/icon + {:path-kw :svg/x-circle + :scale 0.03 + :color "red" + :class ["w-[20px] h-[20px]"] - :hover? false}))]))) - [] - cust-apps)] - (web-table/table - {:headers ["App name" "Local env" "Github" "Prod env" "Test env" "Status"] - :rows rows}))) + :hover? false}))]))) + [] + cust-apps)] + (web-table/table {:headers ["App name" "Local env" "Github" "Prod env" "Test env" "Status"] + :rows rows}))) (defn current-app-stats [graph] @@ -257,8 +236,7 @@ app-name (web-conf/read-param [:app-name]) build-configs-paths (build-config/search-for-build-configs "") build-configs (map edn-utils/read-edn build-configs-paths) - current-app-config - (first (filter (fn [app] (= (:app-name app) app-name)) build-configs)) + current-app-config (first (filter (fn [app] (= (:app-name app) app-name)) build-configs)) cust-apps (filter (fn [app] (:cust-app? app)) build-configs)] [:div {:id "admin-index" :class ["text-center w-full"]} diff --git a/src/clj/automaton_web/pages/admin/route.clj b/src/clj/automaton_web/pages/admin/route.clj index 6f4f7543..f90cb413 100644 --- a/src/clj/automaton_web/pages/admin/route.clj +++ b/src/clj/automaton_web/pages/admin/route.clj @@ -13,7 +13,6 @@ (let [admin-content (web-admin-index/admin-page)] (http-response/ok {"content-type" "text/html;charset=utf8"} (-> request - (merge {:header-elements - [(web-hiccup/js-script-raw - (web-conf/config-web-reference))]}) + (merge {:header-elements [(web-hiccup/js-script-raw + (web-conf/config-web-reference))]}) (web-pages-index/build admin-content)))))}]) diff --git a/src/clj/automaton_web/pages/errors.clj b/src/clj/automaton_web/pages/errors.clj index fec9c087..cd72b0f8 100644 --- a/src/clj/automaton_web/pages/errors.clj +++ b/src/clj/automaton_web/pages/errors.clj @@ -10,29 +10,25 @@ [{:keys [tr] :or {tr str} :as request}] - (let [title (fallback/always-return #(tr :not-found-page) - "This was unexpected") + (let [title (fallback/always-return #(tr :not-found-page) "This was unexpected") description (fallback/always-return #(tr :not-found-description) "But we are working on it!") back-home (fallback/always-return #(tr :back-home) "Back")] (web-pages-index/build request (web-comp-errors/not-found {:title title :description description - :back-home-text - back-home})))) + :back-home-text back-home})))) (defn internal-error-page "Build default internal error page" [{:keys [tr] :or {tr str} :as request}] - (let [title (fallback/always-return #(tr request :this-is-unexpected) - "This was unexpected") + (let [title (fallback/always-return #(tr request :this-is-unexpected) "This was unexpected") description (fallback/always-return #(tr request :we-are-working-on-it) "But we are working on it!") back-home (fallback/always-return #(tr request :back-home) "Back")] (web-pages-index/build request - (web-comp-errors/internal-error - {:title title - :description description - :back-home-text back-home})))) + (web-comp-errors/internal-error {:title title + :description description + :back-home-text back-home})))) diff --git a/src/clj/automaton_web/pages/index.clj b/src/clj/automaton_web/pages/index.clj index 180e0676..15bbde53 100644 --- a/src/clj/automaton_web/pages/index.clj +++ b/src/clj/automaton_web/pages/index.clj @@ -6,15 +6,7 @@ (defn build "Build a webpage header" [{:keys [header-elements meta-tags]} & body] - (let [{:keys [image - description - title - type - url - twitter-content - twitter-site - author - icon] + (let [{:keys [image description title type url twitter-content twitter-site author icon] :or {icon "/favicon.ico"}} meta-tags meta-title [:meta {:name "title" diff --git a/src/clj/automaton_web/pages/portfolio/route.clj b/src/clj/automaton_web/pages/portfolio/route.clj index 57a8ee7c..d3cdefba 100644 --- a/src/clj/automaton_web/pages/portfolio/route.clj +++ b/src/clj/automaton_web/pages/portfolio/route.clj @@ -10,11 +10,10 @@ {:summary "Show portfolio" :get (fn [request] (http-response/ok {"content-type" "text/html;charset=utf8"} - (web-pages-index/build - request - [:div ""] - [:script {:type "text/javascript" - :src share-js}] - [:script {:type "text/javascript" - :src - "/js/compiled/portfolio.js"}])))}])) + (web-pages-index/build request + [:div ""] + [:script {:type "text/javascript" + :src share-js}] + [:script {:type "text/javascript" + :src + "/js/compiled/portfolio.js"}])))}])) diff --git a/src/clj/automaton_web/router.clj b/src/clj/automaton_web/router.clj index 437df7d3..6b75d4b5 100644 --- a/src/clj/automaton_web/router.clj +++ b/src/clj/automaton_web/router.clj @@ -10,8 +10,7 @@ (defn router [web-routes web-middleware] (reitit-ring/router (vector web-routes - [@duplex-routes/routes - {:compile coercion/compile-request-coercers}]) + [@duplex-routes/routes {:compile coercion/compile-request-coercers}]) {:data {:muuntaja m/instance :middleware web-middleware}})) @@ -23,16 +22,11 @@ * `default-handlers` list of default handlers * `global-middlewares` middlewares common for all routes, default, resource and web * `translator-middlewares` middlewares needed for translator" - [{:keys [web-routes - web-middleware - default-handlers - global-middlewares - translator-middlewares]}] + [{:keys [web-routes web-middleware default-handlers global-middlewares translator-middlewares]}] (reitit-ring/ring-handler (router web-routes web-middleware) (reitit-ring/routes (bewh/resource-handler {}) - (bewh/default-handlers - default-handlers - translator-middlewares)) + (bewh/default-handlers default-handlers + translator-middlewares)) {:middleware global-middlewares :inject-match? true ;; So the `:match` keyword ;; is in the request and diff --git a/src/clj/automaton_web/web_server.clj b/src/clj/automaton_web/web_server.clj index 478ad8c6..564bab25 100644 --- a/src/clj/automaton_web/web_server.clj +++ b/src/clj/automaton_web/web_server.clj @@ -10,8 +10,7 @@ (reify Thread$UncaughtExceptionHandler (uncaughtException [_ thread ex] - (core-log/error (ex-info (str "Uncaught exception on" (.getName thread)) - {:error ex}))))) + (core-log/error (ex-info (str "Uncaught exception on" (.getName thread)) {:error ex}))))) (defn start-server "Generate the server, based on the given handler. @@ -30,7 +29,6 @@ :join? (:dont-block opts-with-defaults)}] (core-log/trace "Params" opts-with-defaults) (try (http-kit/run-server handler webserver-opts) - (catch Exception e - (core-log/error (ex-info "Unable to start server" {:error e})))))) + (catch Exception e (core-log/error (ex-info "Unable to start server" {:error e})))))) (defn stop-server [server] (server) (core-log/info "Server stopped") server) diff --git a/src/cljc/automaton_web/components/button.cljc b/src/cljc/automaton_web/components/button.cljc index c8ca60cd..9e2b4c53 100644 --- a/src/cljc/automaton_web/components/button.cljc +++ b/src/cljc/automaton_web/components/button.cljc @@ -14,9 +14,7 @@ :or {type "button"}}] [:button (merge - {:data-twe-ripple-init true - :data-twe-ripple-color "light" - :type type + {:type type :disabled disabled :class (vec @@ -33,7 +31,7 @@ (merge {:type "button" :class - ["box-content rounded-none border-none hover:no-underline hover:opacity-75 focus:opacity-100 focus:shadow-none focus:outline-none"] + ["box-content rounded-none border-none hover:no-underline hover:opacity-75 focus:opacity-100 focus:shadow-none focus:outline-none cursor-pointer"] :aria-label "Close" :on-click on-click} btn-props) diff --git a/src/cljc/automaton_web/components/card.cljc b/src/cljc/automaton_web/components/card.cljc index 3d02fc36..72458026 100644 --- a/src/cljc/automaton_web/components/card.cljc +++ b/src/cljc/automaton_web/components/card.cljc @@ -1,33 +1,26 @@ (ns automaton-web.components.card "Namespace for card components" (:require - [automaton-web.components.icons :as web-icons] - [automaton-web.components.modal :as web-modal])) + [automaton-web.components.icons :as web-icons])) (defn card "Displaying a clickable card/box with content (image, title, name) and optional linkedin icon" [{:keys [img name title linkedin on-click additional-props dark?]}] [:div - (merge - {:class - ["rounded-2xl px-8 py-10 cursor-pointer flex flex-col text-center h-full" - (if dark? - "bg-theme-light hover:bg-orange-100 drop-shadow-md" - "bg-theme-dark hover:bg-orange-300 drop-shadow-md")] - :data-twe-ripple-init true - :data-twe-ripple-color "light" - :on-click on-click} - additional-props) + (merge {:class ["rounded-2xl px-8 py-10 cursor-pointer flex flex-col text-center h-full" + (if dark? + "bg-theme-light hover:bg-orange-100 drop-shadow-md" + "bg-theme-dark hover:bg-orange-300 drop-shadow-md")] + :on-click on-click} + additional-props) [:img {:class ["mx-auto h-24 w-24 rounded-full"] :src img :alt ""}] - [:h3 {:class ["mt-6 font-bold" - (if dark? "text-theme-dark" "text-theme-light")] + [:h3 {:class ["mt-6 font-bold" (if dark? "text-theme-dark" "text-theme-light")] :style {:fontFamily "'Plus Jakarta Sans'"}} name] - [:p {:class - ["text-sm leading-6" - (if dark? "text-theme-dark-secondary" "text-theme-light-secondary")] + [:p {:class ["text-sm leading-6" + (if dark? "text-theme-dark-secondary" "text-theme-light-secondary")] :style {:fontFamily "'Plus Jakarta Sans'"}} title] [:ul {:class ["mt-6 flex justify-center gap-x-6 grow items-end"] @@ -38,19 +31,3 @@ :size 1.5 :dark? (not dark?) :href linkedin}]])]]) - -(defn generate-clickable-modal-cards - [{:keys [cards dark? on-click modal-id]}] - (doall (for [{:keys [title img name linkedin] - :as card-info} - cards] - (web-modal/wrap-modal-call {:modal-id modal-id - :key (str name)} - [card {:key (str name) - :title title - :name name - :dark? dark? - :linkedin linkedin - :img img - :on-click #(on-click - card-info)}])))) diff --git a/src/cljc/automaton_web/components/common.cljc b/src/cljc/automaton_web/components/common.cljc index c63808d7..61a848a7 100644 --- a/src/cljc/automaton_web/components/common.cljc +++ b/src/cljc/automaton_web/components/common.cljc @@ -3,10 +3,7 @@ (:require [clojure.string :as str])) -(defn combine-classes - "Combine css classes together" - [& args] - (str/join " " args)) +(defn combine-classes "Combine css classes together" [& args] (str/join " " args)) (defn combine-classes-with-custom "Add the default css values diff --git a/src/cljc/automaton_web/components/errors.cljc b/src/cljc/automaton_web/components/errors.cljc index 799e3769..a525d114 100644 --- a/src/cljc/automaton_web/components/errors.cljc +++ b/src/cljc/automaton_web/components/errors.cljc @@ -9,22 +9,16 @@ [{:keys [title description back-home-text back-link] :or {back-link "/"}}] [:main {:class ["relative isolate min-h-full h-full"]} - [:div - {:class - ["before:content-[''] before:absolute before:h-full before:w-full before:bg-black/[.5]"]} + [:div {:class + ["before:content-[''] before:absolute before:h-full before:w-full before:bg-black/[.5]"]} [:img {:src "/images/not_found.jpg" :alt "" - :class - ["absolute inset-0 -z-10 h-full w-full object-cover object-top "]}]] - [:div - {:class - ["absolute left-1/2 top-1/2 text-center -translate-x-1/2 -translate-y-1/2"]} - [:p {:class - ["text-base font-semibold leading-8 text-white text-border-red"]} + :class ["absolute inset-0 -z-10 h-full w-full object-cover object-top "]}]] + [:div {:class ["absolute left-1/2 top-1/2 text-center -translate-x-1/2 -translate-y-1/2"]} + [:p {:class ["text-base font-semibold leading-8 text-white text-border-red"]} "404"] - [:h1 - {:class - ["mt-4 text-3xl font-bold tracking-tight text-white sm:text-5xl text-border-red-thin"]} + [:h1 {:class + ["mt-4 text-3xl font-bold tracking-tight text-white sm:text-5xl text-border-red-thin"]} title] [:p {:class ["mt-4 text-base text-white/70 sm:mt-6 text-border-black"]} description] @@ -37,22 +31,16 @@ [{:keys [title description back-home-text back-link] :or {back-link "/"}}] [:main {:class ["relative isolate min-h-full h-full"]} - [:div - {:class - ["before:content-[''] before:absolute before:h-full before:w-full before:bg-black/[.5]"]} + [:div {:class + ["before:content-[''] before:absolute before:h-full before:w-full before:bg-black/[.5]"]} [:img {:src "/images/not_found.jpg" :alt "" - :class - ["absolute inset-0 -z-10 h-full w-full object-cover object-top "]}]] - [:div - {:class - ["absolute left-1/2 top-1/2 text-center -translate-x-1/2 -translate-y-1/2"]} - [:p {:class - ["text-base font-semibold leading-8 text-white text-border-red"]} + :class ["absolute inset-0 -z-10 h-full w-full object-cover object-top "]}]] + [:div {:class ["absolute left-1/2 top-1/2 text-center -translate-x-1/2 -translate-y-1/2"]} + [:p {:class ["text-base font-semibold leading-8 text-white text-border-red"]} "500"] - [:h1 - {:class - ["mt-4 text-3xl font-bold tracking-tight text-white sm:text-5xl text-border-red-thin"]} + [:h1 {:class + ["mt-4 text-3xl font-bold tracking-tight text-white sm:text-5xl text-border-red-thin"]} title] [:p {:class ["mt-4 text-base text-white/70 sm:mt-6 text-border-black"]} description] diff --git a/src/cljc/automaton_web/components/footer.cljc b/src/cljc/automaton_web/components/footer.cljc index 9068f4c6..ab95060b 100644 --- a/src/cljc/automaton_web/components/footer.cljc +++ b/src/cljc/automaton_web/components/footer.cljc @@ -8,8 +8,7 @@ :as _footer-category} class] [:div {:class class} - [:h3 {:class ["text-base font-medium" - (if dark? "text-theme-light" "text-theme-dark")]} + [:h3 {:class ["text-base font-medium" (if dark? "text-theme-light" "text-theme-dark")]} title] (vec (concat @@ -20,31 +19,26 @@ (if dark? "text-theme-light-secondary hover:text-theme-light" "text-theme-dark-secondary hover:text-theme-dark")]} - [:a {:href href - :class ["text-sm leading-6" - (if disabled? "cursor-not-allowed" "cursor-pointer") - (if dark? - (if disabled? - "text-theme-light" - "text-theme-light-secondary hover:text-theme-light") - (if disabled? - "text-theme-dark" - "text-theme-dark-secondary hover:text-theme-dark"))]} + [:a + {:href href + :class + ["text-sm leading-6" + (if disabled? "cursor-not-allowed" "cursor-pointer") + (if dark? + (if disabled? "text-theme-light" "text-theme-light-secondary hover:text-theme-light") + (if disabled? "text-theme-dark" "text-theme-dark-secondary hover:text-theme-dark"))]} text]])))]) (defn- simple-footer-link [{:keys [title href dark? disabled? on-click]}] [:a (merge (if on-click {:on-click on-click} {:href href}) - {:class ["text-sm leading-6" - (if disabled? "pointer-events-none" "cursor-pointer") - (if dark? - (if disabled? - "text-theme-light" - "text-theme-light-secondary hover:text-theme-light") - (if disabled? - "text-theme-dark" - "text-theme-dark-secondary hover:text-theme-dark"))]}) + {:class + ["text-sm leading-6" + (if disabled? "pointer-events-none" "cursor-pointer") + (if dark? + (if disabled? "text-theme-light" "text-theme-light-secondary hover:text-theme-light") + (if disabled? "text-theme-dark" "text-theme-dark-secondary hover:text-theme-dark"))]}) title]) (defn- social-networks-comp @@ -69,14 +63,7 @@ * and value is an component that will be displayed as an icon * `version` is the string to show the version " - [{:keys [social-networks - footer-lists - title - quotation - badge - company-name - release - dark?]}] + [{:keys [social-networks footer-lists title quotation badge company-name release dark?]}] [:footer {:class [(if dark? "bg-theme-dark" "bg-theme-light")] :aria-labelledby "footer-heading"} [:div {:class ["mx-auto max-w-7xl py-12 px-4 sm:px-6 lg:py-16 lg:px-8"]} @@ -85,10 +72,7 @@ [:img {:src badge :alt company-name :class ["h-10"]}] - [:p {:class ["text-base" - (if dark? - "text-theme-light-secondary" - "text-theme-dark-secondary")]} + [:p {:class ["text-base" (if dark? "text-theme-light-secondary" "text-theme-dark-secondary")]} quotation] (vec (concat [:div {:class ["flex gap-8"]}] (social-networks-comp social-networks dark?)))] @@ -100,14 +84,12 @@ [:div {:class ["md:grid md:grid-cols-2 md:gap-8"]} [footer-link (merge footer3 {:dark? dark?})] [footer-link (merge footer4 {:dark? dark?}) ["mt-12 md:mt-0"]]]])] - [:div {:class - ["mt-12 border-t border-gray-200 pt-8 relative flex items-center"]} + [:div {:class ["mt-12 border-t border-gray-200 pt-8 relative flex items-center"]} (when release [web-version/component {:version release :dark? dark?}]) - [:p {:class - ["text-base xl:text-center w-full" - (if dark? "text-theme-light-secondary" "text-theme-dark-secondary")]} + [:p {:class ["text-base xl:text-center w-full" + (if dark? "text-theme-light-secondary" "text-theme-dark-secondary")]} title]]]]) (defn simple-footer @@ -127,19 +109,16 @@ [{:keys [footer-lists release social-networks title dark?]}] [:footer {:class [(if dark? "bg-theme-dark" "bg-theme-light")]} [:div {:class ["mx-auto max-w-7xl overflow-hidden flex flex-col gap-4"]} - [:nav {:class ["columns-2 sm:justify-center" - "flex flex-col gap-6 text-center md:flex-row"] + [:nav {:class ["columns-2 sm:justify-center" "flex flex-col gap-6 text-center md:flex-row"] :aria-label "Footer"} (for [footer footer-lists] - ^{:key (str "simple-footer-link-" - (web-elt-id/string-to-id (:title footer)))} + ^{:key (str "simple-footer-link-" (web-elt-id/string-to-id (:title footer)))} [simple-footer-link (merge {:dark? dark?} footer)])] (into [:div {:class ["flex justify-center space-x-10 relative"]} (when release [web-version/component {:version release :dark? dark?}])] (social-networks-comp social-networks dark?)) - [:p {:class - ["text-center text-xs leading-5" - (if dark? "text-theme-light-secondary" "text-theme-dark-secondary")]} + [:p {:class ["text-center text-xs leading-5" + (if dark? "text-theme-light-secondary" "text-theme-dark-secondary")]} title]]]) diff --git a/src/cljc/automaton_web/components/grid_list.cljc b/src/cljc/automaton_web/components/grid_list.cljc index f8a49fdc..efa3918c 100644 --- a/src/cljc/automaton_web/components/grid_list.cljc +++ b/src/cljc/automaton_web/components/grid_list.cljc @@ -2,15 +2,14 @@ (defn grid-box [{:keys [size class]} & components] - (into - [:div - {:class - (vec - (concat - ["grid lg:max-w-none gap-x-8 gap-y-16 text-center mx-auto lg:mx-0" - (case size - :sm "grid-cols-1 md:grid-cols-2" - :md "grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 mx-auto" - "grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-6 mx-auto")] - class))}] - (mapv (fn [component] component) components))) + (into [:div + {:class + (vec + (concat + ["grid lg:max-w-none gap-x-8 gap-y-16 text-center mx-auto lg:mx-0" + (case size + :sm "grid-cols-1 md:grid-cols-2" + :md "grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 mx-auto" + "grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-6 mx-auto")] + class))}] + (mapv (fn [component] component) components))) diff --git a/src/cljc/automaton_web/components/header.cljc b/src/cljc/automaton_web/components/header.cljc index 3223bc53..6741b387 100644 --- a/src/cljc/automaton_web/components/header.cljc +++ b/src/cljc/automaton_web/components/header.cljc @@ -10,8 +10,7 @@ (defn- base-header [{:keys [size sticky? border?]} content] [:header {:class [(if sticky? "sticky" "absolute") - (when border? - "border border-solid border-b-theme-dark bg-theme-light") + (when border? "border border-solid border-b-theme-dark bg-theme-light") "inset-x-0 top-0 z-50" "py-2" (if (= :full size) "w-full" "w-full lg:w-1/2")]} @@ -22,8 +21,7 @@ [base-header {:size size :sticky? sticky? :border? border?} - [:nav {:class - ["flex items-center content-between justify-between px-6 lg:px-8"]} + [:nav {:class ["flex items-center content-between justify-between px-6 lg:px-8"]} logo [:div right-section]]]) @@ -33,8 +31,7 @@ [base-header {:size size :sticky? sticky? :border? border?} - [:nav {:class - ["flex items-center content-between justify-between px-6 lg:px-8"]} + [:nav {:class ["flex items-center content-between justify-between px-6 lg:px-8"]} logo [:div {:class ["hidden lg:flex lg:gap-x-12"]} (for [{:keys [title href]} menu-items] diff --git a/src/cljc/automaton_web/components/icons.cljc b/src/cljc/automaton_web/components/icons.cljc index 0c83d070..6fa1b7fb 100644 --- a/src/cljc/automaton_web/components/icons.cljc +++ b/src/cljc/automaton_web/components/icons.cljc @@ -126,9 +126,7 @@ svg [:svg {:stroke "currentColor" :href href :fill fill-color - :class (vec (concat ["relative" - (when hover? "svg-hover-orange")] - class)) + :class (vec (concat ["relative" (when hover? "svg-hover-orange")] class)) :aria-hidden "true" :height (str (* 1 size) "em") :view-box (str "0 0 " original-width " " original-height) diff --git a/src/cljc/automaton_web/components/menu.cljc b/src/cljc/automaton_web/components/menu.cljc index cebd68ab..5830173e 100644 --- a/src/cljc/automaton_web/components/menu.cljc +++ b/src/cljc/automaton_web/components/menu.cljc @@ -16,19 +16,15 @@ "Show the minified - burger version" [{:keys [items burger-position force-burger?]}] [:div {:class ["block h-20 p-4" (when-not force-burger? "xl:hidden")]} - [:div {:class ["absolute" - (if (= :left burger-position) "left-10" "right-10")]} + [:div {:class ["absolute" (if (= :left burger-position) "left-10" "right-10")]} [:div {:class ["overflow-hidden hover:h-fit hover:w-fit w-5 relative h-8"]} - [:div {:class ["flex flex-col absolute" - (if (= :left burger-position) "left-0" "right-0")]} + [:div {:class ["flex flex-col absolute" (if (= :left burger-position) "left-0" "right-0")]} [:div {:class ["cursor-pointer"]} [web-icons/icon {:path-kw :svg/burger}]]] - (vec - (concat - [:div - {:class - ["h-fit flex flex-col mt-10 max-w-[250] border shadow shadow-xl bg-white"]}] - items))]]]) + (vec (concat [:div + {:class + ["h-fit flex flex-col mt-10 max-w-[250] border shadow shadow-xl bg-white"]}] + items))]]]) #_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]} (defn component @@ -48,9 +44,8 @@ (let [menu-match? (when (and (string? path) (string? href)) (let [uri path] (= uri href)))] [menu-item/component - (merge - (assoc item :path path :auto-select? auto-select?) - (when auto-select? {:selected menu-match?}))]))) + (merge (assoc item :path path :auto-select? auto-select?) + (when auto-select? {:selected menu-match?}))]))) params (assoc params :items items)] [:div {:class ["w-full z-10"]} [horizontal-version params] diff --git a/src/cljc/automaton_web/components/menu_item.cljc b/src/cljc/automaton_web/components/menu_item.cljc index ed1aceba..25143891 100644 --- a/src/cljc/automaton_web/components/menu_item.cljc +++ b/src/cljc/automaton_web/components/menu_item.cljc @@ -15,8 +15,7 @@ [{:keys [title href selected on-click]}] [:a (merge {:key (str "menu-" title) - :class ["select-none" - (if selected "cursor-default" "cursor-pointer")]} + :class ["select-none" (if selected "cursor-default" "cursor-pointer")]} (when-not selected (if on-click {:on-click on-click} {:href href}))) [:div {:class diff --git a/src/cljc/automaton_web/components/modal.cljc b/src/cljc/automaton_web/components/modal.cljc deleted file mode 100644 index 82ff1780..00000000 --- a/src/cljc/automaton_web/components/modal.cljc +++ /dev/null @@ -1,78 +0,0 @@ -(ns automaton-web.components.modal - "Namespace for modal components and related." - (:require - [automaton-web.components.button :as web-button])) - -(defn wrap-modal-call - "Wraps component to become a toggle for a modal. - Requires a modal id of a modal to show." - [{:keys [modal-id key]} component] - ^{:key key} - [:span {:data-twe-toggle "modal" - :data-twe-target (str "#" modal-id)} - component]) - -(def close-modal-prop {:data-twe-modal-dismiss true}) - -(defn modal-big - [{:keys [title body id]}] - [:div - {:data-twe-modal-init true - :class - ["fixed left-0 top-0 z-[1055] hidden h-full w-full overflow-y-hidden overflow-x-hidden outline-none"] - :id id - :tabIndex "-1" - :aria-labelledby id - :aria-hidden "true"} - [:div - {:data-twe-modal-dialog-ref true - :class - ["overflow-y-auto pointer-events-none relative h-full w-auto translate-y-[-50px] opacity-0 transition-all duration-300 ease-in-out min-[576px]:mx-auto min-[576px]:mt-7 min-[576px]:h-[calc(100%-3.5rem)] min-[576px]:max-w-[500px] min-[992px]:max-w-[800px]"]} - [:div - {:class - ["pointer-events-auto relative flex h-full lg:h-auto max-h-[100%] w-full flex-col overflow-hidden lg:rounded-md border-none bg-white bg-clip-padding text-current shadow-lg outline-none dark:bg-neutral-600"]} - [:div - {:class - ["flex flex-shrink-0 items-center justify-between rounded-t-md border-b-2 border-neutral-100 border-opacity-100 p-4 dark:border-opacity-50"]} - title - [web-button/x-button {:btn-props close-modal-prop}]] - [:div {:class ["relative overflow-y-auto p-4"]} - body]]]]) - -(defn details-modal - "Modal for displaying something in details with title, description, img and sections. - - Accepts a params map for main parts of the modal described with keys: - :header being composite of name and title. - :body containing image, description and sections - and variable number of maps for displaying sections. - Each map expects :title and :description for the section and :id for reagent" - [{:keys [modal-id name title img description]} & sections] - [modal-big - {:title [:div {:class ["flex gap-4 items-center grid"]} - [:h3 {:class - ["text-2xl font-bold leading-8 tracking-tight text-gray-900"]} - name] - [:div {:class ["text-lg leading-8 tracking-tight text-gray-900"]} - title]] - :body - [:div - {:class - ["relative overflow-y-auto p-4 text-base leading-7 text-gray-700 mb-8"]} - [:img - {:class - ["float-left aspect-[4/5] w-36 flex-none rounded-2xl object-cover mb-1 mr-4"] - :src img - :alt (str name " profile picture")}] - [:p {:class ["text-lg leading-8 float-none"]} - description] - (when (and sections (not (every? nil? sections))) - (doall (for [{:keys [id title description]} sections] - ^{:key (str modal-id "-" id)} - [:div {:class ["mt-8"]} - [:h3 {:class - ["text-xl font-bold tracking-tight text-gray-900"]} - title] - [:div {:class ["mt-4"]} - description]])))] - :id modal-id}]) diff --git a/src/cljc/automaton_web/components/player.cljc b/src/cljc/automaton_web/components/player.cljc index 23eacf2f..c895214e 100644 --- a/src/cljc/automaton_web/components/player.cljc +++ b/src/cljc/automaton_web/components/player.cljc @@ -5,11 +5,9 @@ [automaton-web.components.button :as web-button])) (defn player - [{:keys - [play-fn pause-fn pause? next-fn prev-fn fast-forward-fn fast-backward-fn]}] - [:div - {:class - ["flex flex-col rounded-lg bg-white shadow-xl shadow-black/5 ring-1 ring-slate-700/10"]} + [{:keys [play-fn pause-fn pause? next-fn prev-fn fast-forward-fn fast-backward-fn]}] + [:div {:class + ["flex flex-col rounded-lg bg-white shadow-xl shadow-black/5 ring-1 ring-slate-700/10"]} [:div {:class ["flex items-center justify-center space-x-4 px-6 py-4"]} (when fast-backward-fn [web-button/icon-button {:icon-path :svg/fast-backward diff --git a/src/cljc/automaton_web/components/section.cljc b/src/cljc/automaton_web/components/section.cljc index 5f3a27c9..ebadc916 100644 --- a/src/cljc/automaton_web/components/section.cljc +++ b/src/cljc/automaton_web/components/section.cljc @@ -1,16 +1,12 @@ (ns automaton-web.components.section "Components to visually display and separate content on the page." (:require - [automaton-core.utils.uuid-gen :as uuid-gen] - [automaton-web.components.button :as web-button] - [automaton-web.components.card :as web-card] - [automaton-web.components.grid-list :as web-grid-list] - [automaton-web.components.modal :as web-modal])) + [automaton-core.utils.uuid-gen :as uuid-gen] + [automaton-web.components.button :as web-button])) (defn section-full-container [{:keys [dark? class]} & components] - [:div {:class (vec (concat ["h-fit block p-8" - (if dark? "bg-theme-dark" "bg-theme-light")] + [:div {:class (vec (concat ["h-fit block p-8" (if dark? "bg-theme-dark" "bg-theme-light")] class))} (into [:div {:class ["mx-auto w-full px-6 lg:px-8 self-center"]}] (for [component components] component))]) @@ -18,9 +14,7 @@ (defn section-text-container [{:keys [class]} & components] [:div {:class (vec (concat ["mx-auto max-w-3xl text-base leading-7"] class))} - (into [:div] - (for [component components] - ^{:key (uuid-gen/unguessable)} component))]) + (into [:div] (for [component components] ^{:key (uuid-gen/unguessable)} component))]) (defn section-description [{:keys [title description dark?]}] @@ -28,9 +22,8 @@ [:h2 {:class ["text-3xl font-bold tracking-tight sm:text-4xl" (if dark? "text-theme-light" "text-theme-dark")]} title] - [:p {:class - ["mt-6 max-w-2xl text-lg leading-8 m-auto mt-5" - (if dark? "text-theme-light-secondary" "text-theme-dark-secondary")]} + [:p {:class ["mt-6 max-w-2xl text-lg leading-8 m-auto mt-5" + (if dark? "text-theme-light-secondary" "text-theme-dark-secondary")]} description]]) (defn section-text-button @@ -42,13 +35,9 @@ :dark? boolean for styling to decide if the component should be displayed in dark or light version. :button - optional, to supply whole button component" [{:keys [text button btn-text dark?]}] - [:div - {:class - ["mx-auto grid max-w-7xl grid-cols-1 gap-10 px-6 lg:grid-cols-12 lg:gap-8 lg:px-8"]} - [:div - {:class - ["max-w-xl text-3xl font-bold tracking-tight sm:text-4xl lg:col-span-7 flex" - (if dark? "text-theme-light" "text-theme-dark")]} + [:div {:class ["mx-auto grid max-w-7xl grid-cols-1 gap-10 px-6 lg:grid-cols-12 lg:gap-8 lg:px-8"]} + [:div {:class ["max-w-xl text-3xl font-bold tracking-tight sm:text-4xl lg:col-span-7 flex" + (if dark? "text-theme-light" "text-theme-dark")]} [:p {:class ["inline sm:block lg:inline xl:block m-auto"]} text]] [:div {:class ["m-auto lg:col-span-3 flex justify-center items-center"]} @@ -58,9 +47,8 @@ (defn text-section [{:keys [title description pre-title dark?]} & subsections] - [section-text-container {:class [(if dark? - "text-theme-light-secondary" - "text-theme-dark-secondary")]} + [section-text-container {:class + [(if dark? "text-theme-light-secondary" "text-theme-dark-secondary")]} (when pre-title pre-title) [:h1 {:class ["mt-2 text-3xl font-bold tracking-tight sm:text-4xl" (if dark? "text-theme-light" "text-theme-dark")]} @@ -79,10 +67,9 @@ (defn section-text-video "Section with text on the left and video on the right." [{:keys [title subtitle text btn-props btn-link video-src dark?]}] - [:div - {:class - ["mx-auto max-w-7xl p-0 sm:py-32 lg:flex lg:items-center lg:gap-x-10 lg:px-8 lg:py-40" - (if dark? "bg-theme-dark" "bg-theme-light")]} + [:div {:class + ["mx-auto max-w-7xl p-0 sm:py-32 lg:flex lg:items-center lg:gap-x-10 lg:px-8 lg:py-40" + (if dark? "bg-theme-dark" "bg-theme-light")]} [:div {:class ["flex flex-col gap-8"]} [:div {:class ["justify-self-center pr-4"]} [:div @@ -91,13 +78,9 @@ (if dark? "text-theme-light" "text-theme-dark")]} title] [:figcaption {:class ["mt-8 text-base text-end"]} - [:div {:class ["font-semibold" - (if dark? "text-theme-light" "text-theme-dark")]} + [:div {:class ["font-semibold" (if dark? "text-theme-light" "text-theme-dark")]} subtitle] - [:div {:class ["mt-1" - (if dark? - "text-theme-light-secondary" - "text-theme-dark-secondary")]} + [:div {:class ["mt-1" (if dark? "text-theme-light-secondary" "text-theme-dark-secondary")]} text]]] [web-button/link-button {:link btn-link} (merge btn-props {:class ["hidden lg:block"]})]] @@ -109,39 +92,3 @@ [web-button/link-button {:link btn-link} (merge btn-props {:class ["lg:hidden block w-full mt-8"]})]]) -(defn- card-details-modal - [{:keys [img name description title modal-id sections]}] - [apply - web-modal/details-modal - {:img img - :name name - :description description - :title title - :modal-id modal-id} - sections]) - -(defn section-clickable-cards-modal - "Section with clickable cards, that after click are opened in a modal to display more details. - Params: - * dark? - [optional] color theme - * current-card - Currently displayed card, expects :img :name :title and :description and (optional) :sections to display that information on the details page - * change-card-fn - function to change the currently displayed details card - triggered at card :on-click - * cards - all cards that are displayed in the section, it's a sequence of maps with :title :img :name (optional) :linkedin - * size - section grid size - * modal-id - id of a modal to open - * section - [optional] section description map with :title :description" - [{:keys [dark? current-card change-card-fn cards size section modal-id]}] - [section-full-container {:dark? dark?} - [section-description (merge section {:dark? dark?})] - [web-grid-list/grid-box {:size size - :class ["mt-8"]} - (web-card/generate-clickable-modal-cards {:cards cards - :modal-id modal-id - :on-click change-card-fn - :dark? dark?})] - [card-details-modal {:img (:img current-card) - :name (:name current-card) - :description (:description current-card) - :title (:title current-card) - :sections (:sections current-card) - :modal-id modal-id}]]) diff --git a/src/cljc/automaton_web/components/simple_select.cljc b/src/cljc/automaton_web/components/simple_select.cljc index 14ca0391..e632f20f 100644 --- a/src/cljc/automaton_web/components/simple_select.cljc +++ b/src/cljc/automaton_web/components/simple_select.cljc @@ -32,8 +32,7 @@ (-> select-option automaton-web-reagent/reagent-option (update-select-options id) - (automaton-web-reagent/update-reagent-options - select-option)))] + (automaton-web-reagent/update-reagent-options select-option)))] (fn [] [:select {:id id :name html-name :default-value value diff --git a/src/cljc/automaton_web/components/structure.cljc b/src/cljc/automaton_web/components/structure.cljc index f26295da..b8fe8119 100644 --- a/src/cljc/automaton_web/components/structure.cljc +++ b/src/cljc/automaton_web/components/structure.cljc @@ -2,8 +2,7 @@ (defn structure [{:keys [header footer class]} & components] - [:div {:class (vec (concat class - ["h-fit min-h-screen flex flex-col relative"]))} + [:div {:class (vec (concat class ["h-fit min-h-screen flex flex-col relative"]))} header (into [:div {:class ["grow"]}] (for [comp components] comp)) diff --git a/src/cljc/automaton_web/components/table.cljc b/src/cljc/automaton_web/components/table.cljc index 7cb0e114..8a9ddbb7 100644 --- a/src/cljc/automaton_web/components/table.cljc +++ b/src/cljc/automaton_web/components/table.cljc @@ -37,10 +37,8 @@ ^{:key (str "k: " k)} [:div [:div - (merge - {:class - ["border-spacing-0 border-solid border-gray-500 border-2 p-0 flex"]} - (when (map? v) {:colSpan "2"})) + (merge {:class ["border-spacing-0 border-solid border-gray-500 border-2 p-0 flex"]} + (when (map? v) {:colSpan "2"})) [:div {:class ["p-2 font-bold float-left"]} k] (cond @@ -60,25 +58,20 @@ [:div {:class ["mt-8 flow-root"]} [:div {:class ["-mx-4 -my-2 overflow-x-auto sm:-mx-6 lg:-mx-8"]} [:div {:class ["inline-block min-w-full py-2 align-middle sm:px-6 lg:px-8"]} - [:div - {:class - ["overflow-hidden shadow ring-1 ring-black ring-opacity-5 sm:rounded-lg"]} + [:div {:class ["overflow-hidden shadow ring-1 ring-black ring-opacity-5 sm:rounded-lg"]} [:table {:class ["min-w-full divide-y divide-gray-300"]} [:thead {:class ["bg-gray-50"]} [:tr (for [header headers] ^{:key (uuid-gen/unguessable)} - [:th - {:scope "col" - :class - ["py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6"]} + [:th {:scope "col" + :class ["py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6"]} header])]] [:tbody {:class ["divide-y divide-gray-200 bg-white"]} (for [row rows] [:tr (for [cell row] ^{:key (uuid-gen/unguessable)} - [:td - {:class - ["whitespace-nowrap py-4 pl-4 pr-3 text-sm font-medium text-gray-900 sm:pl-6"]} + [:td {:class + ["whitespace-nowrap py-4 pl-4 pr-3 text-sm font-medium text-gray-900 sm:pl-6"]} cell])])]]]]]]) diff --git a/src/cljc/automaton_web/configuration.cljc b/src/cljc/automaton_web/configuration.cljc index 04c1626b..4d2a5b22 100644 --- a/src/cljc/automaton_web/configuration.cljc +++ b/src/cljc/automaton_web/configuration.cljc @@ -36,9 +36,7 @@ ([key-path default-value] (let [value (core-conf-prot/read-conf-param @conf-state key-path)] (if (nil? value) - (do (prn "Value for " key-path - " is not set, use default value" default-value) - default-value) + (do (prn "Value for " key-path " is not set, use default value" default-value) default-value) (do (prn "Read key-path " key-path " = " value) value)))) ([key-path] (read-param key-path nil))) diff --git a/src/cljc/automaton_web/configuration/files.cljc b/src/cljc/automaton_web/configuration/files.cljc index 3a3e7de7..a2112f0d 100644 --- a/src/cljc/automaton_web/configuration/files.cljc +++ b/src/cljc/automaton_web/configuration/files.cljc @@ -13,8 +13,7 @@ (defn- read-config [] #?(:clj (core-conf-files/read-config) - :cljs (core-keyword/sanitize-map-keys - (js->clj js-var :keywordize-keys true)))) + :cljs (core-keyword/sanitize-map-keys (js->clj js-var :keywordize-keys true)))) (def ^{:doc "A map of configuration variables."} conf (memoize read-config)) @@ -24,5 +23,4 @@ (config [_this] (conf)) web-prot/ConfWeb (config-web-reference [this] - (str "var " js-var - " = " (ws-util/mapToJSmap (core-conf-prot/config this))))) + (str "var " js-var " = " (ws-util/mapToJSmap (core-conf-prot/config this))))) diff --git a/src/cljc/automaton_web/duplex/route.cljc b/src/cljc/automaton_web/duplex/route.cljc index efcf0655..bf10db0c 100644 --- a/src/cljc/automaton_web/duplex/route.cljc +++ b/src/cljc/automaton_web/duplex/route.cljc @@ -1,6 +1,3 @@ -(ns automaton-web.duplex.route - "Namespace to share constants between clj and cljs for servers") +(ns automaton-web.duplex.route "Namespace to share constants between clj and cljs for servers") -(def duplex-uri - "Is used to generate the duplex url, create the server and call it" - "/chsk") +(def duplex-uri "Is used to generate the duplex url, create the server and call it" "/chsk") diff --git a/src/cljc/automaton_web/hiccup.cljc b/src/cljc/automaton_web/hiccup.cljc index 445b66ca..cdfbd34a 100644 --- a/src/cljc/automaton_web/hiccup.cljc +++ b/src/cljc/automaton_web/hiccup.cljc @@ -11,8 +11,7 @@ [:meta {:charset "utf-8"}] [:meta {:content "width=device-width,initial-scale=1" :name "viewport"}] - (when head-elements - (for [header-el head-elements] header-el))] + (when head-elements (for [header-el head-elements] header-el))] [:body (for [el body] el)]])) (defn js-script-raw diff --git a/src/cljc/automaton_web/i18n/dict/text.cljc b/src/cljc/automaton_web/i18n/dict/text.cljc index 025da763..fe3f7d1d 100644 --- a/src/cljc/automaton_web/i18n/dict/text.cljc +++ b/src/cljc/automaton_web/i18n/dict/text.cljc @@ -1,5 +1,4 @@ -(ns automaton-web.i18n.dict.text - "Dictionary for text translation in `automaton-web` components") +(ns automaton-web.i18n.dict.text "Dictionary for text translation in `automaton-web` components") (def dict {:en @@ -12,16 +11,12 @@ :email-structure-invalid "Email should comply with foo@bar.com" :password-required "Password is required to continue" :password-must-be-more-than-12 "Password must be at least 12 characters" - :password-must-contain-uppercase - "Password must contain at least one uppercase letter" - :password-must-contain-lowercase - "Password must contain at least one lowercase letter" + :password-must-contain-uppercase "Password must contain at least one uppercase letter" + :password-must-contain-lowercase "Password must contain at least one lowercase letter" :password-must-contain-number "Password must contain at least one number" - :password-must-contain-special-character - "Password must contain at least one special character" + :password-must-contain-special-character "Password must contain at least one special character" :remember-me "Remember me" - :gdpr-not-accepted - "To subscribe you need to accept the permission. We won't spam you." + :gdpr-not-accepted "To subscribe you need to accept the permission. We won't spam you." :submit "Submit" :email "Email" :password "Password" @@ -30,31 +25,24 @@ :company "Company" :example "e.g. %1" :sign-in "Sign in" - :newsletter-subscribe-and-materials - "Subscribe to newsletter and receive materials" + :newsletter-subscribe-and-materials "Subscribe to newsletter and receive materials" :not-found-page "Page not found" - :not-found-description - "Sorry, we couldn’t find the page you’re looking for." + :not-found-description "Sorry, we couldn’t find the page you’re looking for." :this-is-unexpected "Well, this is unexpected..." :we-are-working-on-it "An error has occured and we are working hard to fix the problem! We'll be running shortly" :back-home "Back to home"} :fr - {:gdpr-required-email - "Le RGPD requiert que vous nous donniez l'autorisation d'envoyer un email" + {:gdpr-required-email "Le RGPD requiert que vous nous donniez l'autorisation d'envoyer un email" :gdpr-mailchimp-email-description "Merci de sélectionner l'option ci-dessus. Vous pouvez vous désinscrire à chaque moment en cliquant sur le lien dans pied de page de vos emails. Nous utilisons mailchimp pour stocker vos informations. En souscrivant à notre lettre vous nous autorisez à transferre votre adresse à Mailchimp. " :first-name-required "Le champ prénom doit être rempli" :last-name-required "Le champ nom doit être rempli" :password-required "Le mot de passe est requis" - :password-must-be-more-than-12 - "Le mot de passe doit comporter au moins 12 caractères" - :password-must-contain-uppercase - "Le mot de passe doit contenir au moins une lettre majuscule" - :password-must-contain-lowercase - "Le mot de passe doit contenir au moins une lettre minuscule" - :password-must-contain-number - "Le mot de passe doit contenir au moins un chiffre" + :password-must-be-more-than-12 "Le mot de passe doit comporter au moins 12 caractères" + :password-must-contain-uppercase "Le mot de passe doit contenir au moins une lettre majuscule" + :password-must-contain-lowercase "Le mot de passe doit contenir au moins une lettre minuscule" + :password-must-contain-number "Le mot de passe doit contenir au moins un chiffre" :password-must-contain-special-character "Le mot de passe doit contenir au moins un caractère spécial" :remember-me "Souviens-toi de moi" @@ -73,8 +61,7 @@ :newsletter-subscribe-and-materials "Souscrivez à la lettre d'information et recevez les documents" :not-found-page "Page non trouvée" - :not-found-description - "Désolé, nous n'avons pas trouvé la page que vous recherchez." + :not-found-description "Désolé, nous n'avons pas trouvé la page que vous recherchez." :this-is-unexpected "Eh bien, c'est inattendu..." :we-are-working-on-it "Une erreur s'est produite et nous travaillons d'arrache-pied pour résoudre le problème ! Nous serons bientôt opérationnels." diff --git a/src/cljc/automaton_web/i18n/language.cljc b/src/cljc/automaton_web/i18n/language.cljc index 2888559f..5378eb11 100644 --- a/src/cljc/automaton_web/i18n/language.cljc +++ b/src/cljc/automaton_web/i18n/language.cljc @@ -60,8 +60,7 @@ core-lang/languages (filter (fn [[_ lang]] (when (every? string? [lang-ui-text (:ui-text lang)]) - (= (str/upper-case lang-ui-text) - (str/upper-case (:ui-text lang)))))) + (= (str/upper-case lang-ui-text) (str/upper-case (:ui-text lang)))))) ffirst))) (defn make-automaton-web-languages @@ -71,9 +70,8 @@ The final map consists in the languages defined in both `selected-languages` `core-lang/base-languages` The language data map are merged, see `merge-languages-map` for details" [& selected-languages-seq] - (->AutomatonWebLanguages (apply core-lang/make-automaton-core-languages - web-languages-map - selected-languages-seq))) + (->AutomatonWebLanguages + (apply core-lang/make-automaton-core-languages web-languages-map selected-languages-seq))) (def automaton-web-languages "Languages available in `automaton-web`, instance of `Languages`" diff --git a/src/cljc/automaton_web/routes.cljc b/src/cljc/automaton_web/routes.cljc index 83e80626..adbb1774 100644 --- a/src/cljc/automaton_web/routes.cljc +++ b/src/cljc/automaton_web/routes.cljc @@ -3,9 +3,7 @@ (:require [automaton-core.utils.map :as utils-map])) -(defn- kw-to-registry-value - [registry val] - (if (keyword? val) (get registry val) val)) +(defn- kw-to-registry-value [registry val] (if (keyword? val) (get registry val) val)) (defn- update-registry [handler-registry handler-map] @@ -25,8 +23,6 @@ (cond (string? routes) routes (and (map? routes) (map? selected-route-data)) - (merge (select-keys routes [:name]) - (update-registry handler-registry selected-route-data)) + (merge (select-keys routes [:name]) (update-registry handler-registry selected-route-data)) (map? routes) (kw-to-registry-value handler-registry selected-route-data) - (vector? routes) (mapv #(parse-routes router-kw % handler-registry) - routes))))) + (vector? routes) (mapv #(parse-routes router-kw % handler-registry) routes))))) diff --git a/src/cljs/automaton_web/components/cards.cljs b/src/cljs/automaton_web/components/cards.cljs new file mode 100644 index 00000000..48aa0438 --- /dev/null +++ b/src/cljs/automaton_web/components/cards.cljs @@ -0,0 +1,84 @@ +(ns automaton-web.components.cards + (:require + [automaton-web.components.card :as web-card] + [automaton-web.components.grid-list :as web-grid-list] + [automaton-web.components.modal :as web-modal] + [automaton-web.components.section :as web-section] + [automaton-web.react-proxy :as web-react])) + +(defn- card-title + [name title] + [:div + {:class + ["flex flex-shrink-0 items-center justify-between rounded-t-md border-b-2 border-neutral-100 border-opacity-100 p-4 dark:border-opacity-50"]} + [:h3 {:class ["text-2xl font-bold leading-8 tracking-tight text-gray-900"]} + name] + [:div {:class ["text-lg leading-8 tracking-tight text-gray-900"]} + title]]) + +(defn- card-description + [img name description & sections] + [:div {:class ["relative overflow-y-auto p-4 text-base leading-7 text-gray-700 mb-8"]} + [:img {:class ["float-left aspect-[4/5] w-36 flex-none rounded-2xl object-cover mb-1 mr-4"] + :src img + :alt (str name " profile picture")}] + [:p {:class ["text-lg leading-8 float-none"]} + description] + (when (and sections (not (every? nil? sections))) + (into [:span] + (for [{:keys [title description]} sections] + [:div {:class ["mt-8"]} + [:h3 {:class ["text-xl font-bold tracking-tight text-gray-900"]} + title] + [:div {:class ["mt-4"]} + description]])))]) + +(defn- card-details-modal + [{:keys [img name description title modal-open? sections]}] + [web-modal/modal {:modal-open? modal-open? + :backdrop? true} + [web-modal/title [card-title name title]] + [apply card-description img name description sections]]) + +(defn- generate-clickable-cards + [{:keys [cards dark? on-click]}] + (doall (for [{:keys [title img name linkedin] + :as card-info} + cards] + [web-card/card {:key (str name) + :title title + :name name + :dark? dark? + :linkedin linkedin + :img img + :on-click (fn [] (on-click card-info))}]))) + +#_{:clj-kondo/ignore [:unused-binding]} +(defn clickable-cards + "Section with clickable cards, that after click are opened in a modal to display more details. + Params: + * dark? - [optional] color theme + * current-card - Currently displayed card, expects :img :name :title and :description and (optional) :sections to display that information on the details page + * change-card-fn - function to change the currently displayed details card - triggered at card :on-click + * cards - all cards that are displayed in the section, it's a sequence of maps with :title :img :name (optional) :linkedin + * size - section grid size + * modal-id - id of a modal to open + * section - [optional] section description map with :title :description" + [{:keys [dark? current-card change-card-fn cards size section modal-open?] + :or {modal-open? (web-react/ratom false)}}] + (fn [{:keys [dark? current-card change-card-fn cards size section]}] + [web-section/section-full-container {:dark? dark?} + [web-section/section-description (merge section {:dark? dark?})] + [web-grid-list/grid-box {:size size + :class ["mt-8"]} + (generate-clickable-cards + {:cards cards + :on-click (fn [card-info] (reset! modal-open? true) (change-card-fn card-info)) + :dark? dark?})] + (when (:name current-card) + [card-details-modal {:img (:img current-card) + :name (:name current-card) + :description (:description current-card) + :title (:title current-card) + :sections (:sections current-card) + :modal-open? modal-open?}])])) diff --git a/src/cljs/automaton_web/components/fe_language_select.cljs b/src/cljs/automaton_web/components/fe_language_select.cljs index 1507bb97..8a4c16cf 100644 --- a/src/cljs/automaton_web/components/fe_language_select.cljs +++ b/src/cljs/automaton_web/components/fe_language_select.cljs @@ -15,11 +15,10 @@ [change-lang-kw ui-languages lang-id-to-str-fn] (let [selected-value (-> (web-events-proxy/subscribe-value [::web-subs/lang]) lang-id-to-str-fn)] - [web-simple-select/simple-select - {:id "lang" - :name "lang" - :on-change #(web-events-proxy/dispatch [change-lang-kw %]) - :value selected-value - :options (map (fn [{:keys [value]}] [:option {:value value} - value]) - ui-languages)}])) + [web-simple-select/simple-select {:id "lang" + :name "lang" + :on-change #(web-events-proxy/dispatch [change-lang-kw %]) + :value selected-value + :options (map (fn [{:keys [value]}] [:option {:value value} + value]) + ui-languages)}])) diff --git a/src/cljs/automaton_web/components/file_loader.cljs b/src/cljs/automaton_web/components/file_loader.cljs index cbb58cf6..8b8e689c 100644 --- a/src/cljs/automaton_web/components/file_loader.cljs +++ b/src/cljs/automaton_web/components/file_loader.cljs @@ -40,13 +40,9 @@ (str/join ", " (for [file @files] (.-name file))) ")"))]) (when @loading? - [:div - {:class - ["flex justify-center items-center inline-block ml-2 float-right"]} - [:div - {:class - ["spinner-border animate-spin inline w-8 h-8 border-4 rounded-full"] - :role "status"}] + [:div {:class ["flex justify-center items-center inline-block ml-2 float-right"]} + [:div {:class ["spinner-border animate-spin inline w-8 h-8 border-4 rounded-full"] + :role "status"}] [:span {:class ["visually-hidden"]} "Loading ..."]])] [:input @@ -74,19 +70,18 @@ file:py-3 file:px-5 file:mr-5 file:text-body-color file:cursor-pointer file:hove :title "Upload error"}])]]) [:div "Error in the component parameters"])) -(web-events-proxy/reg-event-fx - ::files-selected - (fn-traced [{:keys [db]} [_ tag files uri uri-field]] - {:db (assoc-in db - [:file-upload tag] - {:uri uri - :field-name uri-field - :files files}) - :fx [[:dispatch [::trigger-upload tag files]]]})) +(web-events-proxy/reg-event-fx ::files-selected + (fn-traced [{:keys [db]} [_ tag files uri uri-field]] + {:db (assoc-in db + [:file-upload tag] + {:uri uri + :field-name uri-field + :files files}) + :fx [[:dispatch [::trigger-upload tag files]]]})) -(web-events-proxy/reg-event-db - ::file-upload-success - (fn-traced [db [_ tag]] (assoc-in db [:file-upload tag :success] true))) +(web-events-proxy/reg-event-db ::file-upload-success + (fn-traced [db [_ tag]] + (assoc-in db [:file-upload tag :success] true))) (web-events-proxy/reg-event-fx ::trigger-upload @@ -103,57 +98,49 @@ file:py-3 file:px-5 file:mr-5 file:text-body-color file:cursor-pointer file:hove :headers {:x-csrf-token csrf-frontend/?csrf-token} :uri uri :timeout 8000 - :response-format (ajax/json-response-format - {:keywords? true}) + :response-format (ajax/json-response-format {:keywords? true}) :on-success [::loading-success tag] :on-failure [::error-message tag]}}))) -(web-events-proxy/reg-event-fx - ::loading-success - (fn-traced [{:keys [db]} - [_ - tag - {:keys [status _uuid _size _filename] - :as upload-response}]] - (core-log/trace "upload response is " upload-response) - {:db (assoc-in db [:file-upload tag :loading?] false) - :fx [[:dispatch [::reset-selector tag]] - (if (= "done" status) - [:dispatch [::new-file-uploaded tag upload-response]] - [:dispatch [::file-upload-error tag]])]})) +(web-events-proxy/reg-event-fx ::loading-success + (fn-traced [{:keys [db]} + [_ + tag + {:keys [status _uuid _size _filename] + :as upload-response}]] + (core-log/trace "upload response is " upload-response) + {:db (assoc-in db [:file-upload tag :loading?] false) + :fx [[:dispatch [::reset-selector tag]] + (if (= "done" status) + [:dispatch + [::new-file-uploaded tag upload-response]] + [:dispatch [::file-upload-error tag]])]})) (web-events-proxy/reg-event-fx ::error-message - (fn-traced - [{:keys [db]} [_ tag result]] - {:db (if (= 0 (:status result)) - (assoc-in db [:file-upload tag :network-error] (:status-text result)) - (assoc-in db [:file-upload tag :upload-error] (:status-text result))) - :fx [[:dispatch [::stop-loading tag]]]})) + (fn-traced [{:keys [db]} [_ tag result]] + {:db (if (= 0 (:status result)) + (assoc-in db [:file-upload tag :network-error] (:status-text result)) + (assoc-in db [:file-upload tag :upload-error] (:status-text result))) + :fx [[:dispatch [::stop-loading tag]]]})) -(web-events-proxy/reg-event-db - ::reset-selector - (fn-traced [db [_ tag]] - (let [image-upload (. js/document (getElementById "image-upload"))] - (set! (.-value image-upload) "") - (assoc-in db [:file-upload tag :files] nil)))) +(web-events-proxy/reg-event-db ::reset-selector + (fn-traced [db [_ tag]] + (let [image-upload (. js/document + (getElementById "image-upload"))] + (set! (.-value image-upload) "") + (assoc-in db [:file-upload tag :files] nil)))) -(web-events-proxy/reg-event-db - ::file-upload-error - (fn-traced [db [_ tag]] (assoc-in db [:file-upload tag :error?] true))) +(web-events-proxy/reg-event-db ::file-upload-error + (fn-traced [db [_ tag]] + (assoc-in db [:file-upload tag :error?] true))) -(web-events-proxy/reg-sub ::files - (fn [db [_ tag]] - (get-in db [:file-upload tag :files]))) +(web-events-proxy/reg-sub ::files (fn [db [_ tag]] (get-in db [:file-upload tag :files]))) (web-events-proxy/reg-sub ::upload-message - (fn [db [_ tag]] - (get-in db [:file-upload tag :upload-error]))) + (fn [db [_ tag]] (get-in db [:file-upload tag :upload-error]))) (web-events-proxy/reg-sub ::network-error - (fn [db [_ tag]] - (get-in db [:file-upload tag :network-error]))) + (fn [db [_ tag]] (get-in db [:file-upload tag :network-error]))) -(web-events-proxy/reg-sub ::loading? - (fn [db [_ tag]] - (get-in db [:file-upload tag :loading?]))) +(web-events-proxy/reg-sub ::loading? (fn [db [_ tag]] (get-in db [:file-upload tag :loading?]))) diff --git a/src/cljs/automaton_web/components/form.cljs b/src/cljs/automaton_web/components/form.cljs index ab8713f4..84ecf332 100644 --- a/src/cljs/automaton_web/components/form.cljs +++ b/src/cljs/automaton_web/components/form.cljs @@ -15,8 +15,7 @@ :values values :touched (into #{} (keys initial-touched))}] (if-let [user-provided-state state] - (do (swap! user-provided-state (fn [db] (merge initialized-state db))) - user-provided-state) + (do (swap! user-provided-state (fn [db] (merge initialized-state db))) user-provided-state) (web-react/ratom initialized-state)))) (defn element-value @@ -42,25 +41,15 @@ [new-values state] (swap! state #(-> % (update :values merge new-values) - (update :touched - (fn [x y] (apply conj x y)) - (keys new-values))))) + (update :touched (fn [x y] (apply conj x y)) (keys new-values))))) -(defn touched - [state k] - (or (:attempted-submissions @state) (get (:touched @state) k))) +(defn touched [state k] (or (:attempted-submissions @state) (get (:touched @state) k))) -(defn set-touched - [names state] - (swap! state update :touched (fn [x y] (apply conj x y)) names)) +(defn set-touched [names state] (swap! state update :touched (fn [x y] (apply conj x y)) names)) -(defn set-untouched - [names state] - (swap! state update :touched (fn [x y] (apply disj x y)) names)) +(defn set-untouched [names state] (swap! state update :touched (fn [x y] (apply disj x y)) names)) -(defn disable - [state & [ks]] - (swap! state update :disabled? #(apply conj ((fnil into #{}) %) ks))) +(defn disable [state & [ks]] (swap! state update :disabled? #(apply conj ((fnil into #{}) %) ks))) (defn enable [state & [ks]] (swap! state update :disabled? #(apply disj % ks))) @@ -68,8 +57,7 @@ (defn handle-validation [state validation] - (let [resolved (validation state)] - (when-not (every? empty? resolved) resolved))) + (let [resolved (validation state)] (when-not (every? empty? resolved) resolved))) (defn on-change [evt state] @@ -79,8 +67,7 @@ (defn on-blur [evt state] - (let [input-key (element-name evt)] - (swap! state update :touched conj input-key))) + (let [input-key (element-name evt)] (swap! state update :touched conj input-key))) (defn set-on-change [{:keys [value]} state] @@ -89,13 +76,9 @@ val (if (fn? value) (value curr-value) value)] (swap! state assoc-in path val))) -(defn set-on-blur - [{:keys [value]} state] - (swap! state update :touched (if value conj disj))) +(defn set-on-blur [{:keys [value]} state] (swap! state update :touched (if value conj disj))) -(defn dirty - [values initial-values] - (first (clj-data/diff values (or initial-values {})))) +(defn dirty [values initial-values] (first (clj-data/diff values (or initial-values {})))) (defn on-submit [evt {:keys [state on-submit validation reset]}] @@ -106,8 +89,7 @@ (on-submit {:state state :values (:values @state) :dirty (dirty (:values @state) - (merge (:initial-values @state) - (:touched-values @state))) + (merge (:initial-values @state) (:touched-values @state))) :reset reset}))) (defn form @@ -130,46 +112,41 @@ :touched #{}} m)))}] (web-react/create-class - {:component-did-mount #(when-let [on-mount (:component-did-mount props)] - (on-mount handlers)) - :reagent-render - (fn [props component] - (let [validation (when-let [val-fn (:validation props)] - (handle-validation @state val-fn))] - [component - {:props (:props props) - :state state - :form-id form-id - :values (:values @state) - :dirty (dirty (:values @state) - (merge (:initial-values @state) - (:touched-values @state))) - :errors validation - :touched (:touched handlers) - :set-touched (:set-touched handlers) - :set-untouched (:set-untouched handlers) - :attempted-submissions (or (:attempted-submissions @state) 0) - :successful-submissions (or (:successful-submissions @state) 0) - :set-values (:set-values handlers) - :disable (:disable handlers) - :enable (:enable handlers) - :disabled? (:disabled? handlers) - :set-on-change (:set-on-change handlers) - :set-on-blur (:set-on-blur handlers) - :on-change (:on-change handlers) - :on-blur (:on-blur handlers) - :reset (:reset handlers) - :on-submit (fn [evt] - (on-submit evt - (merge props - {:state state - :form-id form-id - :validation validation - :reset (:reset handlers)})))}]))}))) - -(defn append-form - [form-id el] - (.appendChild (.getElementById js/document form-id) el)) + {:component-did-mount #(when-let [on-mount (:component-did-mount props)] (on-mount handlers)) + :reagent-render (fn [props component] + (let [validation (when-let [val-fn (:validation props)] + (handle-validation @state val-fn))] + [component + {:props (:props props) + :state state + :form-id form-id + :values (:values @state) + :dirty (dirty (:values @state) + (merge (:initial-values @state) (:touched-values @state))) + :errors validation + :touched (:touched handlers) + :set-touched (:set-touched handlers) + :set-untouched (:set-untouched handlers) + :attempted-submissions (or (:attempted-submissions @state) 0) + :successful-submissions (or (:successful-submissions @state) 0) + :set-values (:set-values handlers) + :disable (:disable handlers) + :enable (:enable handlers) + :disabled? (:disabled? handlers) + :set-on-change (:set-on-change handlers) + :set-on-blur (:set-on-blur handlers) + :on-change (:on-change handlers) + :on-blur (:on-blur handlers) + :reset (:reset handlers) + :on-submit (fn [evt] + (on-submit evt + (merge props + {:state state + :form-id form-id + :validation validation + :reset (:reset handlers)})))}]))}))) + +(defn append-form [form-id el] (.appendChild (.getElementById js/document form-id) el)) (defn submit-form [form-id] @@ -204,8 +181,7 @@ :target "_blank"})) [:div {:class ["grid grid-cols-1 gap-x-8 gap-y-6 sm:grid-cols-2"]} (for [el elements] ^{:key (str el)} [el props]) - [web-button/button {:disabled (and (seq errors) - (> attempted-submissions 0)) + [web-button/button {:disabled (and (seq errors) (> attempted-submissions 0)) :class ["sm:col-span-2"] :text text :type "submit"}]]])])) @@ -218,24 +194,17 @@ (not (re-matches #".+@.+\..+" email)) (assoc email-name (auto-web-translator/tr :email-structure-invalid)) (empty? email) (assoc email-name (auto-web-translator/tr :email-required)) - (empty? password) (assoc password-name - (auto-web-translator/tr :password-required)) + (empty? password) (assoc password-name (auto-web-translator/tr :password-required)) (< (count password) 12) (assoc password-name - (auto-web-translator/tr - :password-must-be-more-than-12)) + (auto-web-translator/tr :password-must-be-more-than-12)) (nil? (re-find #"[A-Z]" password)) - (assoc password-name - (auto-web-translator/tr :password-must-contain-uppercase)) + (assoc password-name (auto-web-translator/tr :password-must-contain-uppercase)) (nil? (re-find #"[a-z]" password)) - (assoc password-name - (auto-web-translator/tr :password-must-contain-lowercase)) - (nil? (re-find #"[0-9]" password)) (assoc password-name - (auto-web-translator/tr - :password-must-contain-number)) + (assoc password-name (auto-web-translator/tr :password-must-contain-lowercase)) + (nil? (re-find #"[0-9]" password)) + (assoc password-name (auto-web-translator/tr :password-must-contain-number)) (nil? (re-find #"[^\w\*]" password)) - (assoc password-name - (auto-web-translator/tr - :password-must-contain-special-character))))) + (assoc password-name (auto-web-translator/tr :password-must-contain-special-character))))) (defn forgot-password [{:keys [link]}] diff --git a/src/cljs/automaton_web/components/iframe.cljs b/src/cljs/automaton_web/components/iframe.cljs index 8fcfaf10..e214b3a1 100644 --- a/src/cljs/automaton_web/components/iframe.cljs +++ b/src/cljs/automaton_web/components/iframe.cljs @@ -46,40 +46,38 @@ (defn iframe [{:keys [id src]}] (let [initialSH (web-react/ratom 0) - iframeContentHeightObserver - (js/ResizeObserver. (fn [_] - (let [scrollHeight (get-scroll-height id) - new-height (calculate-new-height - scrollHeight)] - (when-not (= @initialSH scrollHeight) - (reset! initialSH new-height) - (set-scroll-height id new-height)))))] + iframeContentHeightObserver (js/ResizeObserver. (fn [_] + (let [scrollHeight (get-scroll-height id) + new-height (calculate-new-height + scrollHeight)] + (when-not (= @initialSH scrollHeight) + (reset! initialSH new-height) + (set-scroll-height id new-height)))))] (web-react/create-class {:component-did-update (fn [_] (new js/Promise (fn [resolve] - (waitForIframeContentAndObserve - {:resolve-fn resolve - :iframe-id id - :observer iframeContentHeightObserver - :path src})))) - :reagent-render - (fn [{:keys [id src sandbox policy] - :or {sandbox "allow-same-origin" - policy "no-referrer"}}] - [:iframe {:class ["h-full w-full overflow-hidden"] - :sandbox sandbox - :referrerPolicy policy - :ref (fn [_] - (new js/Promise - (fn [resolve] - (waitForIframeContentAndObserve - {:resolve-fn resolve - :iframe-id id - :observer iframeContentHeightObserver})))) - :height "100%" - :width "100%" - :frameBorder "0" - :scrolling "no" - :id id - :src src}])}))) + (waitForIframeContentAndObserve {:resolve-fn resolve + :iframe-id id + :observer + iframeContentHeightObserver + :path src})))) + :reagent-render (fn [{:keys [id src sandbox policy] + :or {sandbox "allow-same-origin" + policy "no-referrer"}}] + [:iframe {:class ["h-full w-full overflow-hidden"] + :sandbox sandbox + :referrerPolicy policy + :ref (fn [_] + (new js/Promise + (fn [resolve] + (waitForIframeContentAndObserve + {:resolve-fn resolve + :iframe-id id + :observer iframeContentHeightObserver})))) + :height "100%" + :width "100%" + :frameBorder "0" + :scrolling "no" + :id id + :src src}])}))) diff --git a/src/cljs/automaton_web/components/init_components.cljs b/src/cljs/automaton_web/components/init_components.cljs deleted file mode 100644 index e6cbfd93..00000000 --- a/src/cljs/automaton_web/components/init_components.cljs +++ /dev/null @@ -1,66 +0,0 @@ -(ns automaton-web.components.init-components - "Put here all initialisation needed for components classes (not for each component instance, which should be spread in the code). For instance, everything which is supposed to be done once for each component." - (:require - ["react" :as react] - ["tw-elements" :refer [Modal Ripple Tooltip initTWE]] - [automaton-core.log :as core-log])) - -(defn- for-each-root-rendering - "Init for each root rendering. - List here all: - * tailwind element components." - [document] - (core-log/trace "Starting Tailwind element") - (try (initTWE #js {:Modal Modal - :Ripple Ripple}) - ;;https://github.com/mdbootstrap/Tailwind-Elements/issues/1765#issuecomment-1623821125 - ;;https://tailwind-elements.com/docs/standard/components/tooltip/#docsTabsAPI - ;;tooltips are not initalized yet with initTE despite what - ;;documentation say, but they plan to add it - (let [tooltipTriggerList (.call (.-slice #js []) - (.querySelectorAll - document - "[data-twe-toggle=\"tooltip\"]"))] - (.map tooltipTriggerList - (fn [tooltipTriggerEl] (new Tooltip tooltipTriggerEl)))) - (catch js/Error e - (core-log/error-exception (ex-info "Unexpected tailwind-element issue " - {:error e})))) - (core-log/trace "Ending Tailwind-element") - js/undefined) - -(defn init-rendering - "To be called at the root of components rendering" - ([] (init-rendering js/document)) - ([document] - (core-log/trace "Rendering init for base components") - (react/useEffect #(for-each-root-rendering document)))) - -(defn init-elements-js - "To be called to initialize tw-elements in js" - [document] - (let [script (.createElement document "script") - _add-script-src - (set! - (.-src script) - "https://cdn.jsdelivr.net/npm/tw-elements/js/tw-elements.umd.min.js")] - (.appendChild (aget (.getElementsByTagName document "head") 0) script))) - -(defn init-modal [el] (Modal. el)) - -(defn get-modal [el] (.getInstance Modal el)) - -(defn hide-modal - ([modal-id] (hide-modal js/document modal-id)) - ([document modal-id] - (some-> document - (.getElementById modal-id) - (get-modal) - (.hide)))) - -(defn on-modal-hide - ([modal-id on-hide-fn] (on-modal-hide js/document modal-id on-hide-fn)) - ([document modal-id on-hide-fn] - (some-> document - (.getElementById modal-id) - (.addEventListener "hidden.twe.modal" on-hide-fn)))) diff --git a/src/cljs/automaton_web/components/input.cljs b/src/cljs/automaton_web/components/input.cljs index d3f0af84..da38650e 100644 --- a/src/cljs/automaton_web/components/input.cljs +++ b/src/cljs/automaton_web/components/input.cljs @@ -6,18 +6,8 @@ (defn- input "Input component, passes appropriate values to html input tag and styles it depending on state or props" - [{:keys [type - placeholder - name - autocomplete - id - value - checked - on-blur - on-change - class - disabled? - invalid?] + [{:keys + [type placeholder name autocomplete id value checked on-blur on-change class disabled? invalid?] :or {type "text"}}] (let [disabled? (cond (fn? disabled?) (disabled? name) @@ -43,9 +33,7 @@ ;;Disabled "disabled:cursor-not-allowed disabled:bg-gray-50 disabled:text-gray-500 disabled:ring-gray-200" ;;Invalid - (if invalid? - "text-red-900 ring-red-300 placeholder:text-red-300" - "ring-gray-300")] + (if invalid? "text-red-900 ring-red-300 placeholder:text-red-300" "ring-gray-300")] class))})])) (defn text-field @@ -57,24 +45,12 @@ error-message -> string: for displaying message on invalid component size -> :full for displaying input on two grid cols values-fn -> fn returning string: value of input when component is controlled." - [{:keys [name - text - size - on-change-fn - touched - error-message - errors - type - value - invalid? - required?] + [{:keys [name text size on-change-fn touched error-message errors type value invalid? required?] :as params :or {type "text"}}] (let [invalid? (if (fn? invalid?) (invalid? name) - (or invalid? - (when required? - (and touched (touched name) (get errors name))))) + (or invalid? (when required? (and touched (touched name) (get errors name))))) e-msg (or error-message (get errors name))] [:div {:class [(when (= size :full) "sm:col-span-2")]} [:div {:class ["relative mt-2.5"]} @@ -98,9 +74,7 @@ {:type type :invalid? invalid?})]] (when invalid? - [:div - {:class - ["pointer-events-none absolute inset-y-0 right-0 flex items-center pr-3"]} + [:div {:class ["pointer-events-none absolute inset-y-0 right-0 flex items-center pr-3"]} [web-icons/icon {:class ["icon-red"]}]])] (when invalid? [:p {:class ["ml-2 mt-2 text-sm text-red-600"]} @@ -115,24 +89,12 @@ error-message -> string: for displaying message on invalid component size -> :full for displaying input on two grid cols values-fn -> fn returning string: value of input when component is controlled." - [{:keys [name - text - size - on-change-fn - touched - error-message - errors - type - value - invalid? - required?] + [{:keys [name text size on-change-fn touched error-message errors type value invalid? required?] :as params :or {type "number"}}] (let [invalid? (if (fn? invalid?) (invalid? name) - (or invalid? - (when required? - (and touched (touched name) (get errors name))))) + (or invalid? (when required? (and touched (touched name) (get errors name))))) e-msg (or error-message (get errors name))] [:div {:class [(when (= size :full) "sm:col-span-2")]} [:div {:class ["relative mt-2.5"]} @@ -156,9 +118,7 @@ {:type type :invalid? invalid?})]] (when invalid? - [:div - {:class - ["pointer-events-none absolute inset-y-0 right-0 flex items-center pr-3"]} + [:div {:class ["pointer-events-none absolute inset-y-0 right-0 flex items-center pr-3"]} [web-icons/icon {:class ["icon-red"]}]])] (when invalid? [:p {:class ["ml-2 mt-2 text-sm text-red-600"]} @@ -173,24 +133,11 @@ error-message -> string: for displaying message on invalid component size -> :full for displaying checkbox on two grid cols values -> fn returning boolean: checked of input when component is controlled." - [{:keys [id - title - description - name - size - touched - errors - values - error-message - required? - invalid?] + [{:keys [id title description name size touched errors values error-message required? invalid?] :as params}] - (let [invalid? (or invalid? - (when required? - (and touched (touched name) (get errors name)))) + (let [invalid? (or invalid? (when required? (and touched (touched name) (get errors name)))) error-message (or error-message (get errors name))] - [:div {:class ["relative flex items-start" - (when (= size :full) "sm:col-span-2")]} + [:div {:class ["relative flex items-start" (when (= size :full) "sm:col-span-2")]} [:div {:class ["flex h-6 items-center"]} [input (merge diff --git a/src/cljs/automaton_web/components/mailchimp.cljs b/src/cljs/automaton_web/components/mailchimp.cljs index 92a4c1a1..634685b5 100644 --- a/src/cljs/automaton_web/components/mailchimp.cljs +++ b/src/cljs/automaton_web/components/mailchimp.cljs @@ -1,7 +1,6 @@ (ns automaton-web.components.mailchimp (:require [automaton-web.components.form :as web-form] - [automaton-web.components.init-components :as web-init-components] [automaton-web.components.input :as web-input] [automaton-web.components.modal :as web-modal] [automaton-web.i18n.fe.auto-web-translator :as auto-web-translator])) @@ -17,8 +16,7 @@ [web-input/checkbox (merge props {:title (auto-web-translator/tr :gdpr-required-email) - :description (auto-web-translator/tr - :gdpr-mailchimp-email-description) + :description (auto-web-translator/tr :gdpr-mailchimp-email-description) :size :full :id "gdpr_1240" :name "gdpr[1240]" @@ -31,16 +29,13 @@ lname (get values "LNAME" "") gdpr-accepted (get values "gdpr[1240]")] (cond-> {} - (empty? fname) (assoc "FNAME" - (auto-web-translator/tr :first-name-required)) - (empty? lname) (assoc "LNAME" - (auto-web-translator/tr :last-name-required)) + (empty? fname) (assoc "FNAME" (auto-web-translator/tr :first-name-required)) + (empty? lname) (assoc "LNAME" (auto-web-translator/tr :last-name-required)) (not (re-matches #".+@.+\..+" email)) (assoc "EMAIL" (auto-web-translator/tr :email-structure-invalid)) (empty? email) (assoc "EMAIL" (auto-web-translator/tr :email-required)) (or (not gdpr-accepted) (false? gdpr-accepted)) - (assoc "gdpr[1240]" - (auto-web-translator/tr :mailchimp-validation/gdpr-unaccepted))))) + (assoc "gdpr[1240]" (auto-web-translator/tr :mailchimp-validation/gdpr-unaccepted))))) (defn mailchimp-language-input [document] @@ -50,22 +45,19 @@ input)) (defn mailchimp-newsletter-form - [{:keys [modal-id mailchimp-post-link form-id document] + [{:keys [modal-open? mailchimp-post-link form-id document] :or {document js/document}}] - [web-form/form-basic - {:form-id form-id - :action mailchimp-post-link - :method "post" - :on-submit (fn [_props] - (web-form/append-form form-id - (mailchimp-language-input document)) - (web-form/submit-form form-id) - (web-init-components/hide-modal document modal-id)) - :component-did-mount - (fn [{:keys [reset]}] - (web-init-components/on-modal-hide document modal-id #(reset))) - :validation mailchimp-newsletter-validation - :text (auto-web-translator/tr :submit)} + [web-form/form-basic {:form-id form-id + :action mailchimp-post-link + :method "post" + :on-submit (fn [_props] + (web-form/append-form form-id + (mailchimp-language-input document)) + (web-form/submit-form form-id) + (reset! modal-open? false)) + :component-did-mount (fn [_] (reset! modal-open? false)) + :validation mailchimp-newsletter-validation + :text (auto-web-translator/tr :submit)} #(web-input/email-field (merge % {:id "mailchimp-email" :name "EMAIL" @@ -86,18 +78,16 @@ #(mailchimp-gdpr-compliance %)]) (defn mailchimp-newsletter-modal - [{:keys [modal-id post-link document] + [{:keys [modal-id post-link document modal-open?] :or {modal-id mailchimp-newsletter-modal-id post-link mailchimp-newsletter-post-link document js/document}}] - [web-modal/modal-big - {:title [:h2 - {:class - ["text-3xl font-bold tracking-tight text-gray-900 sm:text-4xl"]} - (auto-web-translator/tr :newsletter-subscribe-and-materials)] - :body [mailchimp-newsletter-form {:modal-id modal-id - :mailchimp-post-link post-link - :document document - :form-id (str modal-id - "-mailchimp-form")}] - :id modal-id}]) + [web-modal/modal {:modal-open? modal-open? + :backdrop? true} + [web-modal/title {} + [:h2 {:class ["text-3xl font-bold tracking-tight text-gray-900 sm:text-4xl"]} + (auto-web-translator/tr :newsletter-subscribe-and-materials)]] + [mailchimp-newsletter-form {:modal-open? modal-open? + :mailchimp-post-link post-link + :document document + :form-id (str modal-id "-mailchimp-form")}]]) diff --git a/src/cljs/automaton_web/components/modal.cljs b/src/cljs/automaton_web/components/modal.cljs new file mode 100644 index 00000000..e642d393 --- /dev/null +++ b/src/cljs/automaton_web/components/modal.cljs @@ -0,0 +1,36 @@ +(ns automaton-web.components.modal + "Namespace for modal components and related." + (:require + ["@headlessui/react" :refer (Dialog DialogBackdrop DialogPanel DialogTitle)])) + +(defn backdrop + [] + [:> + DialogBackdrop + {:transition true + :className + "fixed inset-0 bg-gray-500 bg-opacity-75 transition-opacity data-[closed]:opacity-0 data-[enter]:duration-300 data-[leave]:duration-200 data-[enter]:ease-out data-[leave]:ease-in"}]) + +(defn title [props & els] [:> DialogTitle (or props {}) (into [:span] (for [el els] el))]) + +(defn modal + [{:keys [modal-open? backdrop?] + :or {modal-open? false}} + & + els] + [:> + Dialog + {:open @modal-open? + :className "relative z-10 h-full w-full" + :onClose (fn [] (reset! modal-open? false))} + (when backdrop? [backdrop]) + [:div {:className "fixed inset-0 w-screen overflow-y-auto p-4"} + [:div {:className "flex min-h-full items-center justify-center"} + [:> + DialogPanel + {:transition true + :as "div" + :class + ["overflow-hidden pointer-events-none relative h-full max-w-lg translate-y-[-50px] min-[576px]:mx-auto min-[576px]:mt-7 min-[576px]:h-[calc(100%-3.5rem)] min-[576px]:max-w-[500px] min-[992px]:max-w-[800px] lg:rounded-md border-none bg-white bg-clip-padding text-current shadow-lg outline-none dark:bg-neutral-600" + "transform transition-all data-[closed]:translate-y-4 data-[closed]:opacity-0 data-[enter]:duration-300 data-[leave]:duration-200 data-[enter]:ease-out data-[leave]:ease-in data-[closed]:sm:translate-y-0 data-[closed]:sm:scale-95"]} + (when (and els (not (every? nil? els))) (into [:span] (for [el els] el)))]]]]) diff --git a/src/cljs/automaton_web/components/todos.cljs b/src/cljs/automaton_web/components/todos.cljs index 74f985f4..f753e186 100644 --- a/src/cljs/automaton_web/components/todos.cljs +++ b/src/cljs/automaton_web/components/todos.cljs @@ -9,8 +9,7 @@ (fn [] [:form {:on-submit (fn [e] (.preventDefault e) (on-submit-todo {:desc @new-item - :completed - @new-item-completed}) + :completed @new-item-completed}) (reset! new-item "") (reset! new-item-completed false))} [:input {:type "checkbox" @@ -21,8 +20,7 @@ [:input {:type "text" :value @new-item :placeholder "Add a new item" - :on-change - (fn [e] (reset! new-item (.-value (.-target e))))}]]))) + :on-change (fn [e] (reset! new-item (.-value (.-target e))))}]]))) (defn todo-item [todo] diff --git a/src/cljs/automaton_web/components/tooltip.cljs b/src/cljs/automaton_web/components/tooltip.cljs index 79bf7c69..7b6415ad 100644 --- a/src/cljs/automaton_web/components/tooltip.cljs +++ b/src/cljs/automaton_web/components/tooltip.cljs @@ -6,8 +6,9 @@ [{:keys [text direction] :or {text "Hoover text" direction "top"}} - component] - [:span {:data-twe-toggle "tooltip" - :data-twe-placement direction - :title text} - component]) + & + rest] + [:span {:class ["tooltip"]} + (for [el rest] ^{:key (str (random-uuid))} el) + [:span {:class ["tooltiptext" (str "tooltiptext-" direction)]} + text]]) diff --git a/src/cljs/automaton_web/duplex/core.cljs b/src/cljs/automaton_web/duplex/core.cljs index 30da1b17..599adaf5 100644 --- a/src/cljs/automaton_web/duplex/core.cljs +++ b/src/cljs/automaton_web/duplex/core.cljs @@ -6,27 +6,23 @@ [taoensso.sente :as sente])) (if csrf-frontend/?csrf-token - (core-log/info "Init of realtime component, token is:" - csrf-frontend/?csrf-token) - (core-log/error (ex-info - "Fail during realtime component, CSRF token not found" - {:cause "?csrf-token does not exist" - :data csrf-frontend/?csrf-token}))) + (core-log/info "Init of realtime component, token is:" csrf-frontend/?csrf-token) + (core-log/error (ex-info "Fail during realtime component, CSRF token not found" + {:cause "?csrf-token does not exist" + :data csrf-frontend/?csrf-token}))) -(try (let [{:keys [chsk ch-recv send-fn state]} - (sente/make-channel-socket-client! duplex-route/duplex-uri - csrf-frontend/?csrf-token - {:type :auto ; e/o #{:auto - ; :ajax :ws} - :packer :edn})] +(try (let [{:keys [chsk ch-recv send-fn state]} (sente/make-channel-socket-client! + duplex-route/duplex-uri + csrf-frontend/?csrf-token + {:type :auto ; e/o #{:auto + ; :ajax :ws} + :packer :edn})] (def chsk chsk) (def ch-chsk ch-recv) ; ChannelSocket's receive channel (def chsk-send! send-fn) ; ChannelSocket's send API fn (def chsk-state state) ; Watchable, read-only atom ) (catch js/Object e - (core-log/error (ex-info - "Unexpected error during realtime component init" - {:error e})))) + (core-log/error (ex-info "Unexpected error during realtime component init" {:error e})))) (defn get-chsk [] chsk) diff --git a/src/cljs/automaton_web/duplex/message_handler.cljs b/src/cljs/automaton_web/duplex/message_handler.cljs index ccde5a6a..4b5eb8d9 100644 --- a/src/cljs/automaton_web/duplex/message_handler.cljs +++ b/src/cljs/automaton_web/duplex/message_handler.cljs @@ -29,15 +29,13 @@ (if (vector? ?data) (let [[old-state-map new-state-map] ?data] (if (:first-open? new-state-map) - (core-log/trace "Channel socket successfully established!: " - new-state-map) + (core-log/trace "Channel socket successfully established!: " new-state-map) (do (core-log/trace "Channel socket state change: " old-state-map) (core-log/trace "Channel socket state change: " new-state-map)))) - (core-log/error - (ex-info "Data should be of vector type" - {:message - "Sente realtime engine failed, returned ?data should be a vector" - :data ?data})))) + (core-log/error (ex-info "Data should be of vector type" + {:message + "Sente realtime engine failed, returned ?data should be a vector" + :data ?data})))) (defmethod -event-msg-handler [:chsk/recv :chsk/ws-ping] [{:keys [_?data]}] @@ -46,5 +44,4 @@ (defmethod -event-msg-handler [:chsk/handshake nil] [{:as _ev-msg :keys [?data]}] - (let [[_?uid _?csrf-token _?handshake-data] ?data] - (core-log/trace "Handshake: " ?data))) + (let [[_?uid _?csrf-token _?handshake-data] ?data] (core-log/trace "Handshake: " ?data))) diff --git a/src/cljs/automaton_web/duplex/router.cljs b/src/cljs/automaton_web/duplex/router.cljs index 015c34ce..5eab6509 100644 --- a/src/cljs/automaton_web/duplex/router.cljs +++ b/src/cljs/automaton_web/duplex/router.cljs @@ -7,16 +7,12 @@ (defonce router_ (atom nil)) -(defn stop-router! - "Stop the router component" - [] - (when-let [stop-f @router_] (stop-f))) +(defn stop-router! "Stop the router component" [] (when-let [stop-f @router_] (stop-f))) (defn start-router! "Start the router component" [] (stop-router!) (core-log/trace "Starting realtime router") - (reset! router_ (sente/start-client-chsk-router! - duplex/ch-chsk - message-handler/event-msg-handler))) + (reset! router_ (sente/start-client-chsk-router! duplex/ch-chsk + message-handler/event-msg-handler))) diff --git a/src/cljs/automaton_web/events/fx.cljs b/src/cljs/automaton_web/events/fx.cljs index bdf14f48..3a875c7f 100644 --- a/src/cljs/automaton_web/events/fx.cljs +++ b/src/cljs/automaton_web/events/fx.cljs @@ -8,8 +8,7 @@ (web-events-proxy/reg-fx ::set-cookie (fn [[key lang-id]] - (let [saved-value (-> (web-language/get-web-lang - lang-id) + (let [saved-value (-> (web-language/get-web-lang lang-id) :ui-text)] (core-log/trace "Effect set-cookie" saved-value) (fe-cookies/set-cookie key saved-value)))) diff --git a/src/cljs/automaton_web/events_proxy.cljs b/src/cljs/automaton_web/events_proxy.cljs index 58de33df..11f2cf4e 100644 --- a/src/cljs/automaton_web/events_proxy.cljs +++ b/src/cljs/automaton_web/events_proxy.cljs @@ -29,10 +29,7 @@ (def reg-cofx rfc/reg-cofx) -(defn dispatch - [event] - (core-log/trace "Event `" event "`") - (rfc/dispatch event)) +(defn dispatch [event] (core-log/trace "Event `" event "`") (rfc/dispatch event)) (def dispatch-sync rfc/dispatch-sync) diff --git a/src/cljs/automaton_web/fe/history/reitit.cljs b/src/cljs/automaton_web/fe/history/reitit.cljs index dfc88662..5fce4a29 100644 --- a/src/cljs/automaton_web/fe/history/reitit.cljs +++ b/src/cljs/automaton_web/fe/history/reitit.cljs @@ -28,8 +28,7 @@ * `router` router used by that history * `on-navigate` function called when a route changed. Takes two parameters, `match` and `history`" [router on-navigate] - (->History - (reitit-fe-history/start! router on-navigate {:use-fragment false}))) + (->History (reitit-fe-history/start! router on-navigate {:use-fragment false}))) (defonce controllers-match-storage (atom nil)) @@ -41,9 +40,8 @@ [new-match] (swap! controllers-match-storage (fn [old-match] (when new-match - (assoc - new-match - :controllers - (reitit-fe-controllers/apply-controllers - (:controllers old-match) - new-match)))))) + (assoc new-match + :controllers + (reitit-fe-controllers/apply-controllers + (:controllers old-match) + new-match)))))) diff --git a/src/cljs/automaton_web/fe/router/reitit.cljs b/src/cljs/automaton_web/fe/router/reitit.cljs index e2bebd8f..57d08dcd 100644 --- a/src/cljs/automaton_web/fe/router/reitit.cljs +++ b/src/cljs/automaton_web/fe/router/reitit.cljs @@ -26,13 +26,11 @@ * `gather-route-params-fn` function with no argument returning a map with all data used in the routes" [routes gather-route-params-fn] (let [reitit-router (reitit/router routes - {:conflicts - (fn [conflicts] - (core-log/error - (ex-info - "Conflicts in routes have been found" - {:conflicts conflicts - :routes routes}))) + {:conflicts (fn [conflicts] + (core-log/error + (ex-info "Conflicts in routes have been found" + {:conflicts conflicts + :routes routes}))) :validate rs/validate :exception pretty/exception})] (->ReititRouter reitit-router gather-route-params-fn))) diff --git a/src/cljs/automaton_web/i18n/fe/auto_web_translator.cljs b/src/cljs/automaton_web/i18n/fe/auto_web_translator.cljs index 5d3bda22..a7cb09b5 100644 --- a/src/cljs/automaton_web/i18n/fe/auto_web_translator.cljs +++ b/src/cljs/automaton_web/i18n/fe/auto_web_translator.cljs @@ -8,9 +8,9 @@ [automaton-web.i18n.language :as web-language])) (def fe-components-translator - (fe-tempura-translator/make-fe-tempura-translator - web-language/main-langs - (partial web-language/ui-str-to-id web-language/automaton-web-languages))) + (fe-tempura-translator/make-fe-tempura-translator web-language/main-langs + (partial web-language/ui-str-to-id + web-language/automaton-web-languages))) (defn tr "Translate the `tr-id` with `resources` diff --git a/src/cljs/automaton_web/i18n/fe/translator.cljs b/src/cljs/automaton_web/i18n/fe/translator.cljs index 0780af70..49cbdb80 100644 --- a/src/cljs/automaton_web/i18n/fe/translator.cljs +++ b/src/cljs/automaton_web/i18n/fe/translator.cljs @@ -32,8 +32,7 @@ (do (core-log/debug "Init language " language) language) (let [default-language (-> (default-languages this) first)] - (core-log/warn "No language found in the url, default to " - default-language) + (core-log/warn "No language found in the url, default to " default-language) default-language))) (defn -lang @@ -42,6 +41,5 @@ (try (some-> (web-events-proxy/subscribe [::web-subs/lang]) deref) (catch :default _ - (core-log/warn - "The language event has not been found, default language is used") + (core-log/warn "The language event has not been found, default language is used") (default-languages this)))) diff --git a/src/cljs/automaton_web/i18n/fe/translator/tempura.cljs b/src/cljs/automaton_web/i18n/fe/translator/tempura.cljs index e7f7f8d3..75d863ef 100644 --- a/src/cljs/automaton_web/i18n/fe/translator/tempura.cljs +++ b/src/cljs/automaton_web/i18n/fe/translator/tempura.cljs @@ -19,11 +19,10 @@ (translate [_ tr-id resources] (let [lang (some-> (web-events-proxy/subscribe [::web-subs/lang]) deref) - translated-text - (tempura/tr opts - (vec (concat (when (keyword? lang) [lang]) main-langs)) - [tr-id] - resources)] + translated-text (tempura/tr opts + (vec (concat (when (keyword? lang) [lang]) main-langs)) + [tr-id] + resources)] (core-log/trace "Translate key `" tr-id "`,with locales `" diff --git a/src/cljs/automaton_web/log/tracking/sentry.cljs b/src/cljs/automaton_web/log/tracking/sentry.cljs index 2d8794e7..9549ea16 100644 --- a/src/cljs/automaton_web/log/tracking/sentry.cljs +++ b/src/cljs/automaton_web/log/tracking/sentry.cljs @@ -2,9 +2,7 @@ "Sentry for web" (:require ["@sentry/react" :as Sentry] - ["react-router-dom" :refer (useLocation useNavigationType - createRoutesFromChildren - matchRoutes)] + ["react-router-dom" :refer (useLocation useNavigationType createRoutesFromChildren matchRoutes)] [react :as react])) (defn init-sentry! @@ -19,8 +17,7 @@ #js {:useEffect react/useEffect :useLocation useLocation :useNavigationType useNavigationType - :createRoutesFromChildren - createRoutesFromChildren + :createRoutesFromChildren createRoutesFromChildren :matchRoutes matchRoutes}) (.replayIntegration Sentry)] :replaysSessionSampleRate 0 diff --git a/src/cljs/automaton_web/portfolio/components/button.cljs b/src/cljs/automaton_web/portfolio/components/button.cljs index f6928d5d..23ed39e0 100644 --- a/src/cljs/automaton_web/portfolio/components/button.cljs +++ b/src/cljs/automaton_web/portfolio/components/button.cljs @@ -11,8 +11,7 @@ #_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]} (defscene button (web-proxy/wrap-component [sut/button {:text "Button" - :on-click #(js/alert - "Hello")}])) + :on-click #(js/alert "Hello")}])) #_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]} (defscene disabled-button @@ -21,17 +20,15 @@ #_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]} (defscene styled-button - (web-proxy/wrap-component - [sut/button {:text "Custom" - :class ["text-violet-400 bg-green-400"]}])) + (web-proxy/wrap-component [sut/button {:text "Custom" + :class ["text-violet-400 bg-green-400"]}])) #_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]} (defscene link-button - (web-proxy/wrap-component - [sut/link-button {:link "https://www.wikipedia.com"} - {:text "Underneath I'm same as button, but click me and see"}])) + (web-proxy/wrap-component [sut/link-button {:link "https://www.wikipedia.com"} + {:text + "Underneath I'm same as button, but click me and see"}])) #_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]} (defscene x-button - (web-proxy/wrap-component [sut/x-button {:on-click #(js/alert - "Hello")}])) + (web-proxy/wrap-component [sut/x-button {:on-click #(js/alert "Hello")}])) diff --git a/src/cljs/automaton_web/portfolio/components/card.cljs b/src/cljs/automaton_web/portfolio/components/card.cljs index 0709c350..6c7d0200 100644 --- a/src/cljs/automaton_web/portfolio/components/card.cljs +++ b/src/cljs/automaton_web/portfolio/components/card.cljs @@ -1,9 +1,11 @@ (ns automaton-web.portfolio.components.card (:require - [automaton-web.components.card :as sut] - [automaton-web.portfolio.proxy :as web-proxy] - [portfolio.reagent-18 :as portfolio - :refer-macros [defscene configure-scenes]])) + [automaton-web.components.card :as sut] + [automaton-web.components.cards :as web-cards] + [automaton-web.portfolio.proxy :as web-proxy] + [automaton-web.react-proxy :as web-react] + [portfolio.reagent-18 :as portfolio + :refer-macros [defscene configure-scenes]])) (configure-scenes {:collection :components :title "Cards"}) @@ -17,14 +19,60 @@ :on-click #(js/alert "Clicked!")}) #_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]} -(defscene card - :params - card-params - [params] - (web-proxy/wrap-component [sut/card params])) +(defscene card :params card-params [params] (web-proxy/wrap-component [sut/card params])) (defscene dark-card :params (assoc card-params :dark? true) [params] (web-proxy/wrap-component [sut/card params])) + +(defscene clickable-cards + (web-proxy/wrap-component + [:div "clickable cards will not open properly due to portfolio modal issue"])) + +(def section-clickable-cards-modal-params + {:current-card (web-react/ratom {}) + :cards + [{:img + "https://images.unsplash.com/photo-1494790108377-be9c29b29330?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80" + :name "Mateusz Mazurczak" + :title "Is a real human person, not an alien" + :description "lorem ipsum lorem ipsum" + :linkedin "https://www.linkedin.com/in/mateuszmazurczak/"} + {:img + "https://images.unsplash.com/photo-1494790108377-be9c29b29330?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80" + :name "Bill Gates" + :title "Co-chair, Bill & Melinda Gates Foundation" + :description "lorem ipsum lorem ipsum ipsum ipsum" + :linkedin "https://www.linkedin.com/in/williamhgates/"}]}) + +(def modal-open? (web-react/ratom false)) + +(defscene section-clickable-cards-modal + :params + section-clickable-cards-modal-params + [params] + (web-proxy/wrap-component [web-cards/clickable-cards + {:current-card @(:current-card params) + :change-card-fn (fn [card] + (reset! (:current-card params) card)) + :cards (:cards params) + :section {:title "hello" + :description "more words"} + :size :sm + :modal-open? modal-open?}])) + +(defscene section-clickable-cards-modal-dark + :params + (merge section-clickable-cards-modal-params {:dark? true}) + [params] + (web-proxy/wrap-component [web-cards/clickable-cards + {:current-card @(:current-card params) + :change-card-fn (fn [card] + (reset! (:current-card params) card)) + :cards (:cards params) + :section {:title "hello" + :description "more words"} + :size :sm + :modal-open? modal-open?}])) diff --git a/src/cljs/automaton_web/portfolio/components/checkbox.cljs b/src/cljs/automaton_web/portfolio/components/checkbox.cljs index 693d1584..397d86a5 100644 --- a/src/cljs/automaton_web/portfolio/components/checkbox.cljs +++ b/src/cljs/automaton_web/portfolio/components/checkbox.cljs @@ -19,16 +19,14 @@ (defscene checkbox-title-description (web-proxy/wrap-component [sut/checkbox {:title "Name" - :description - "This is important section to know about etc."}])) + :description "This is important section to know about etc."}])) #_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]} (defscene checkbox-required - (web-proxy/wrap-component - [sut/checkbox {:title "Important to know" - :description - "This is important section to know about etc." - :required? true}])) + (web-proxy/wrap-component [sut/checkbox {:title "Important to know" + :description + "This is important section to know about etc." + :required? true}])) #_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]} (defscene checkbox-invalid (web-proxy/wrap-component [sut/checkbox {:invalid? true}])) @@ -36,18 +34,16 @@ #_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]} (defscene checkbox-required-invalid (web-proxy/wrap-component [sut/checkbox {:title "Invalid" - :description - "This is invalid checkbox" + :description "This is invalid checkbox" :invalid? true :required? true}])) #_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]} (defscene checkbox-error-message - (web-proxy/wrap-component - [sut/checkbox {:title "Invalid checkbox" - :required? true - :invalid? true - :error-message "This needs to be updated!"}])) + (web-proxy/wrap-component [sut/checkbox {:title "Invalid checkbox" + :required? true + :invalid? true + :error-message "This needs to be updated!"}])) #_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]} (defscene checkbox-disabled @@ -69,8 +65,7 @@ (defscene checkboxes-description (web-proxy/wrap-component [sut/checkboxes {:title "Name" - :description - "This is important section to know about etc."} + :description "This is important section to know about etc."} {:title "Name" :description "This is important section to know about etc."} {:title "Name" @@ -81,8 +76,7 @@ (defscene checkboxes-required (web-proxy/wrap-component [sut/checkboxes {:title "Important to know" - :description - "This is important section to know about etc." + :description "This is important section to know about etc." :required? true} {:title "Name" :description "This is important section to know about etc."} @@ -91,31 +85,31 @@ #_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]} (defscene checkboxes-required-invalid - (web-proxy/wrap-component - [sut/checkboxes {:title "Invalid" - :description "This is invalid checkbox" - :invalid? true - :required? true} - {:title "Invalid" - :description "This is invalid checkbox" - :invalid? true - :required? true} - {:title "Name" - :description "This is important section to know about etc."}])) + (web-proxy/wrap-component [sut/checkboxes {:title "Invalid" + :description "This is invalid checkbox" + :invalid? true + :required? true} + {:title "Invalid" + :description "This is invalid checkbox" + :invalid? true + :required? true} + {:title "Name" + :description + "This is important section to know about etc."}])) #_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]} (defscene checkboxes-error-message - (web-proxy/wrap-component - [sut/checkboxes {:title "Invalid checkbox" - :required? true - :invalid? true - :error-message "This needs to be updated!"} - {:title "Invalid checkbox" - :required? true - :invalid? true - :error-message "This needs to be updated!"} - {:title "Name" - :description "This is important section to know about etc."}])) + (web-proxy/wrap-component [sut/checkboxes {:title "Invalid checkbox" + :required? true + :invalid? true + :error-message "This needs to be updated!"} + {:title "Invalid checkbox" + :required? true + :invalid? true + :error-message "This needs to be updated!"} + {:title "Name" + :description + "This is important section to know about etc."}])) #_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]} (defscene checkboxes-disabled diff --git a/src/cljs/automaton_web/portfolio/components/footer.cljs b/src/cljs/automaton_web/portfolio/components/footer.cljs index 37de173d..72b20d0e 100644 --- a/src/cljs/automaton_web/portfolio/components/footer.cljs +++ b/src/cljs/automaton_web/portfolio/components/footer.cljs @@ -13,8 +13,7 @@ {"youtube" [web-icons/icon {:path-kw :svg/youtube :href "https://www.youtube.com/@Hephaistoxsc"}] "linkedin" [web-icons/icon {:path-kw :svg/linkedin - :href - "https://www.linkedin.com/company/hephaistox"}] + :href "https://www.linkedin.com/company/hephaistox"}] "github" [web-icons/icon {:path-kw :svg/github :href "https://github.com/hephaistox"}] "twitter" [web-icons/icon {:path-kw :svg/twitter @@ -73,49 +72,43 @@ :href "#"}]) #_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]} -(defscene - footer - (web-proxy/wrap-component - [sut/footer - {:social-networks social-networks - :footer-lists footer-lists - :quotation - "Making the world a better place through constructing elegant hierarchies." - :badge "https://tailwindui.com/img/logos/mark.svg?color=gray&shade=300" - :company-name "Hephaistox" - :release "2022-1" - :title "© 2022 Hephaistox, Inc. All rights reserved!"}])) +(defscene footer + (web-proxy/wrap-component + [sut/footer {:social-networks social-networks + :footer-lists footer-lists + :quotation + "Making the world a better place through constructing elegant hierarchies." + :badge "https://tailwindui.com/img/logos/mark.svg?color=gray&shade=300" + :company-name "Hephaistox" + :release "2022-1" + :title "© 2022 Hephaistox, Inc. All rights reserved!"}])) #_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]} -(defscene - footer-dark - (web-proxy/wrap-component - [sut/footer - {:dark? true - :social-networks social-networks - :footer-lists footer-lists - :quotation - "Making the world a better place through constructing elegant hierarchies." - :badge "https://tailwindui.com/img/logos/mark.svg?color=gray&shade=300" - :company-name "Hephaistox" - :release "2022-1" - :title "© 2022 Hephaistox, Inc. All rights reserved!"}])) +(defscene footer-dark + (web-proxy/wrap-component + [sut/footer {:dark? true + :social-networks social-networks + :footer-lists footer-lists + :quotation + "Making the world a better place through constructing elegant hierarchies." + :badge "https://tailwindui.com/img/logos/mark.svg?color=gray&shade=300" + :company-name "Hephaistox" + :release "2022-1" + :title "© 2022 Hephaistox, Inc. All rights reserved!"}])) #_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]} (defscene simple-footer - (web-proxy/wrap-component - [sut/simple-footer {:title - "© 2020 Your Company, Inc. All rights reserved." - :footer-lists simple-footer-list - :release "2022-1" - :social-networks social-networks}])) + (web-proxy/wrap-component [sut/simple-footer + {:title "© 2020 Your Company, Inc. All rights reserved." + :footer-lists simple-footer-list + :release "2022-1" + :social-networks social-networks}])) #_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]} (defscene simple-footer-dark - (web-proxy/wrap-component - [sut/simple-footer {:title - "© 2020 Your Company, Inc. All rights reserved." - :footer-lists simple-footer-list - :release "2022-1" - :social-networks social-networks - :dark? true}])) + (web-proxy/wrap-component [sut/simple-footer + {:title "© 2020 Your Company, Inc. All rights reserved." + :footer-lists simple-footer-list + :release "2022-1" + :social-networks social-networks + :dark? true}])) diff --git a/src/cljs/automaton_web/portfolio/components/form.cljs b/src/cljs/automaton_web/portfolio/components/form.cljs index c8929a58..83dfa58b 100644 --- a/src/cljs/automaton_web/portfolio/components/form.cljs +++ b/src/cljs/automaton_web/portfolio/components/form.cljs @@ -22,9 +22,7 @@ (defn initial-value-form [props] - [:div - (view-state props) - [web-input/text-field (merge props {:name "init-text"})]]) + [:div (view-state props) [web-input/text-field (merge props {:name "init-text"})]]) (defn submit-form [{:keys [on-submit] @@ -70,8 +68,7 @@ [{:keys [values]}] (cond-> {} (empty? (get values "name" "")) (assoc "name" "Name required!") - (empty? (get values "last-name" "")) (assoc "last-name" - "Surname required!"))) + (empty? (get values "last-name" "")) (assoc "last-name" "Surname required!"))) (defn validation-form [{:keys [on-submit reset] @@ -114,35 +111,33 @@ #_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]} (defscene form-initial-value - (web-proxy/wrap-component [sut/form {:initial-values {"init-text" - "initated"}} + (web-proxy/wrap-component [sut/form {:initial-values {"init-text" "initated"}} initial-value-form])) #_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]} (defscene form-submittable - (web-proxy/wrap-component - [sut/form {:on-submit (fn [props] (js/alert (str "props:" props)))} - submit-form])) + (web-proxy/wrap-component [sut/form {:on-submit (fn [props] + (js/alert (str "props:" props)))} + submit-form])) #_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]} (defscene form-more-components - (web-proxy/wrap-component - [sut/form {:on-submit (fn [props] (js/alert (str "props:" props)))} - bigger-form])) + (web-proxy/wrap-component [sut/form {:on-submit (fn [props] + (js/alert (str "props:" props)))} + bigger-form])) #_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]} (defscene form-with-validation - (web-proxy/wrap-component - [sut/form {:on-submit (fn [props] (js/alert (str "props:" props))) - :validation validation-fn} - validation-form])) + (web-proxy/wrap-component [sut/form {:on-submit (fn [props] + (js/alert (str "props:" props))) + :validation validation-fn} + validation-form])) (defn validation [{:keys [values]}] (let [email (get values "email" "")] (cond-> {} - (not (re-matches #".+@.+\..+" email)) (assoc "email" - "This is not correct email!") + (not (re-matches #".+@.+\..+" email)) (assoc "email" "This is not correct email!") (empty? email) (assoc "email" "Email needs to be filled") (or (not (get values "checkbox1")) (false? (get values "checkbox1"))) (assoc "checkbox1" "You need to agree")))) @@ -157,9 +152,7 @@ (web-proxy/wrap-component [sut/form-basic {:form-id "full-form basic" :on-submit (fn [props] - (js/alert (str - "I'm your full form basic!" - props))) + (js/alert (str "I'm your full form basic!" props))) :validation validation :text "Show props"} #(web-input/email-field (merge % @@ -184,11 +177,9 @@ (defscene form-login (web-proxy/wrap-component [sut/form-login {:form-id "login-form" - :on-submit-fn - (fn [e] (prn "e: " e))}])) + :on-submit-fn (fn [e] (prn "e: " e))}])) (defscene form-login-forgot-link (web-proxy/wrap-component [sut/form-login {:form-id "login-form" - :on-submit-fn - (fn [e] (prn "e: " e)) + :on-submit-fn (fn [e] (prn "e: " e)) :forgot-link "#"}])) diff --git a/src/cljs/automaton_web/portfolio/components/grid_list.cljs b/src/cljs/automaton_web/portfolio/components/grid_list.cljs index 85c6682c..faf763c8 100644 --- a/src/cljs/automaton_web/portfolio/components/grid_list.cljs +++ b/src/cljs/automaton_web/portfolio/components/grid_list.cljs @@ -3,8 +3,7 @@ [automaton-web.components.grid-list :as sut] [automaton-web.portfolio.proxy :as web-proxy] [portfolio.reagent-18 :as portfolio - :refer-macros [defscene - configure-scenes]])) + :refer-macros [defscene configure-scenes]])) (configure-scenes {:collection :components :title "Grid list"}) diff --git a/src/cljs/automaton_web/portfolio/components/header.cljs b/src/cljs/automaton_web/portfolio/components/header.cljs index 0a55a3a2..d83e2513 100644 --- a/src/cljs/automaton_web/portfolio/components/header.cljs +++ b/src/cljs/automaton_web/portfolio/components/header.cljs @@ -23,13 +23,11 @@ #_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]} (defscene simple-header - (web-proxy/wrap-component [sut/transparent-header - {:logo "I'm your logo" - :right-section "Right content"}])) + (web-proxy/wrap-component [sut/transparent-header {:logo "I'm your logo" + :right-section "Right content"}])) #_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]} (defscene simple-header-full-size - (web-proxy/wrap-component [sut/transparent-header - {:size :full - :logo "I'm your logo" - :right-section "Right content"}])) + (web-proxy/wrap-component [sut/transparent-header {:size :full + :logo "I'm your logo" + :right-section "Right content"}])) diff --git a/src/cljs/automaton_web/portfolio/components/icons.cljs b/src/cljs/automaton_web/portfolio/components/icons.cljs index ede33f54..bfba3831 100644 --- a/src/cljs/automaton_web/portfolio/components/icons.cljs +++ b/src/cljs/automaton_web/portfolio/components/icons.cljs @@ -34,10 +34,8 @@ #_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]} (defscene all-icons - (web-proxy/wrap-component (vec (concat [:div] - (for [i sut/icons-path] - (let [[name] i] - [:div - [:h2 (str "Icon " name)] - [sut/icon {:path-kw - name}]])))))) + (web-proxy/wrap-component + (vec (concat [:div] + (for [i sut/icons-path] + (let [[name] i] + [:div [:h2 (str "Icon " name)] [sut/icon {:path-kw name}]])))))) diff --git a/src/cljs/automaton_web/portfolio/components/input.cljs b/src/cljs/automaton_web/portfolio/components/input.cljs index 524a418e..0adf35d9 100644 --- a/src/cljs/automaton_web/portfolio/components/input.cljs +++ b/src/cljs/automaton_web/portfolio/components/input.cljs @@ -19,17 +19,16 @@ #_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]} (defscene text-field-placeholder (web-proxy/wrap-component [sut/text-field {:text "Name" - :placeholder - "e.g. John"}])) + :placeholder "e.g. John"}])) #_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]} (defscene text-field-value-controlled-outside (let [text-value (r/atom "Initial-text")] (fn [] - (web-proxy/wrap-component - [sut/text-field {:text "Iniated-field" - :on-change-fn (fn [v] (reset! text-value v)) - :value @text-value}])))) + (web-proxy/wrap-component [sut/text-field {:text "Iniated-field" + :on-change-fn (fn [v] + (reset! text-value v)) + :value @text-value}])))) #_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]} (defscene text-field-full @@ -53,11 +52,10 @@ #_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]} (defscene text-field-error-message - (web-proxy/wrap-component - [sut/text-field {:text "Invalid field" - :required? true - :invalid? true - :error-message "This needs to be updated!"}])) + (web-proxy/wrap-component [sut/text-field {:text "Invalid field" + :required? true + :invalid? true + :error-message "This needs to be updated!"}])) #_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]} (defscene text-field-disabled diff --git a/src/cljs/automaton_web/portfolio/components/mailchimp.cljs b/src/cljs/automaton_web/portfolio/components/mailchimp.cljs index 4b49faab..72bd63f7 100644 --- a/src/cljs/automaton_web/portfolio/components/mailchimp.cljs +++ b/src/cljs/automaton_web/portfolio/components/mailchimp.cljs @@ -2,35 +2,28 @@ (:require [automaton-web.components.button :as web-button] [automaton-web.components.mailchimp :as sut] - [automaton-web.components.modal :as web-modal] [automaton-web.portfolio.proxy :as web-proxy] [portfolio.reagent-18 :as portfolio - :refer-macros [defscene - configure-scenes]])) + :refer-macros [defscene configure-scenes]])) (configure-scenes {:collection :components :title "Mailchimp"}) -#_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]} +(defscene mailchimp + (web-proxy/wrap-component + [:div "mailchimp will not open properly due to portfolio modal issue"])) + (defscene mailchimp-failing-newsletter "Mailchimp failing newsletter modal (This will not result in any real mail address added to mailchimp)" - (web-proxy/wrap-component - (web-modal/wrap-modal-call {:modal-id sut/mailchimp-newsletter-modal-id} - [web-button/button {:text "Open modal"}]) - [sut/mailchimp-newsletter-modal {:document (web-proxy/iframe-document)}])) + (web-proxy/wrap-component [web-button/button {:text "Open modal"}] + [sut/mailchimp-newsletter-modal])) -#_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]} (defscene mailchimp-newsletter "Mailchimp successful newsletter modal (Will add email to audience)" - (web-proxy/wrap-component - (web-modal/wrap-modal-call - {:modal-id (str "new-" sut/mailchimp-newsletter-modal-id)} - [web-button/button {:text "Open modal"}]) - [sut/mailchimp-newsletter-modal - {:modal-id (str "new-" sut/mailchimp-newsletter-modal-id) - :document (web-proxy/iframe-document)}])) + (web-proxy/wrap-component [web-button/button {:text "Open modal"}] + [sut/mailchimp-newsletter-modal + {:modal-id (str "new-" sut/mailchimp-newsletter-modal-id)}])) -#_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]} (defscene mailchimp-gdpr-compliance [sut/mailchimp-gdpr-compliance {:lang :en}]) diff --git a/src/cljs/automaton_web/portfolio/components/menu.cljs b/src/cljs/automaton_web/portfolio/components/menu.cljs index 2c4eb435..8a2869ad 100644 --- a/src/cljs/automaton_web/portfolio/components/menu.cljs +++ b/src/cljs/automaton_web/portfolio/components/menu.cljs @@ -22,31 +22,29 @@ #_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]} (defscene menu-auto-select - (web-proxy/wrap-component [sut/component - {:items [{:title "Menu1" - :href "/"} - {:title "Menu2" - :href "/" - :selected true} - {:title "Menu3" - :href "/"} - {:title "Menu4" - :href "/"}] - :path (.. js/window -location -href) - :burger-position :left}])) + (web-proxy/wrap-component [sut/component {:items [{:title "Menu1" + :href "/"} + {:title "Menu2" + :href "/" + :selected true} + {:title "Menu3" + :href "/"} + {:title "Menu4" + :href "/"}] + :path (.. js/window -location -href) + :burger-position :left}])) #_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]} (defscene menu-burger - (web-proxy/wrap-component [sut/component - {:items [{:title "Menu1" - :href "/"} - {:title "Menu2" - :href "/" - :selected true} - {:title "Menu3" - :href "/"} - {:title "Menu4" - :href "/"}] - :path (.. js/window -location -href) - :force-burger? true - :burger-position :left}])) + (web-proxy/wrap-component [sut/component {:items [{:title "Menu1" + :href "/"} + {:title "Menu2" + :href "/" + :selected true} + {:title "Menu3" + :href "/"} + {:title "Menu4" + :href "/"}] + :path (.. js/window -location -href) + :force-burger? true + :burger-position :left}])) diff --git a/src/cljs/automaton_web/portfolio/components/menu_item.cljs b/src/cljs/automaton_web/portfolio/components/menu_item.cljs index 34cbebe6..5f27221a 100644 --- a/src/cljs/automaton_web/portfolio/components/menu_item.cljs +++ b/src/cljs/automaton_web/portfolio/components/menu_item.cljs @@ -3,8 +3,7 @@ [automaton-web.components.menu-item :as sut] [automaton-web.portfolio.proxy :as web-proxy] [portfolio.reagent-18 :as portfolio - :refer-macros [defscene - configure-scenes]])) + :refer-macros [defscene configure-scenes]])) (configure-scenes {:collection :components :title "Menu Item"}) @@ -22,6 +21,6 @@ #_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]} (defscene menu-item-click-action - (web-proxy/wrap-component - [sut/component {:title "Check click action works" - :on-click #(js/alert "Hey, click action works!")}])) + (web-proxy/wrap-component [sut/component {:title "Check click action works" + :on-click #(js/alert + "Hey, click action works!")}])) diff --git a/src/cljs/automaton_web/portfolio/components/modal.cljs b/src/cljs/automaton_web/portfolio/components/modal.cljs index a7e5661a..a1cf2bdd 100644 --- a/src/cljs/automaton_web/portfolio/components/modal.cljs +++ b/src/cljs/automaton_web/portfolio/components/modal.cljs @@ -3,67 +3,32 @@ [automaton-web.components.button :as web-button] [automaton-web.components.modal :as sut] [automaton-web.portfolio.proxy :as web-proxy] + [automaton-web.react-proxy :as web-react] [portfolio.reagent-18 :as portfolio :refer-macros [defscene configure-scenes]])) (configure-scenes {:collection :components :title "Modal"}) -#_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]} -(defscene modal-big - (web-proxy/wrap-component (sut/wrap-modal-call {:modal-id "bigModal"} - [web-button/button - {:text "Call modal"}]) - [sut/modal-big {:title [:div "hello"] - :body [:div "Body"] - :id "bigModal"}])) +(def modal-open? (web-react/ratom false)) -#_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]} -(defscene - modal-detailed - (web-proxy/wrap-component - (sut/wrap-modal-call {:modal-id "basic-modal"} - [web-button/button {:text "Show modal"}]) - [sut/details-modal - {:img - "https://images.unsplash.com/photo-1519345182560-3f2917c472ef?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=8&w=1024&h=1024&q=80" - :name "Arthur Dent" - :description - "Arthur dies in the fifth installment of the book series, Mostly Harmless, in a club called Beta (owned by Stavro Mueller) when the Earth and all its duplicates are seemingly destroyed by the Grebulons. Adams frequently expressed his disdain for this ending in retrospect, claiming that it was too depressing and came about as the result of him having a bad year." - :title "Earthman and Englishman" - :modal-id "basic-modal"}])) +#_{:clj-kondo/ignore [:unused-binding]} +(defn modal + [modal-open?] + (fn [modal-open?] [sut/modal {:modal-open? modal-open?} + [sut/backdrop] + [sut/title {:name "hello" + :title "world"}] + [:div "hello"] + [:div "Body"]])) #_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]} (defscene - modal-detailed-sections + modal-big (web-proxy/wrap-component - (sut/wrap-modal-call {:modal-id "sections-modal"} - [web-button/button {:text "Show modal"}]) - [sut/details-modal - {:img - "https://images.unsplash.com/photo-1519345182560-3f2917c472ef?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=8&w=1024&h=1024&q=80" - :name "Jar Jar Binks" - :description - "Meesa Jar Jar Binks, a lovable Gungan with a heart full of good intentions and a knack for clumsiness. Meesa bringin' laughter and charm to the Star Wars galaxy, always stumbling into adventures and playing an unexpected part in the galaxy's fate. Meesa may not be the most graceful, but meesa always ready to make a difference and spread joy wherever meesa goes." - :title "Gungan military commander and politician" - :modal-id "sections-modal"} - {:id (str "jarjar-1") - :title "The Clumsy Comedian" - :description - "In this section, we delve into Jar Jar Binks' endearing clumsiness and his ability to turn mishaps into moments of humor. From tripping over his own feet to unintentionally causing chaos, Jar Jar's knack for physical comedy brings a lighthearted touch to his character."} - {:id (str "jarjar-2") - :title "Unlikely Hero" - :description - "Here, we explore Jar Jar's unexpected journey from a simple Gungan to an accidental hero. Despite his initial naivety and lack of combat skills, Jar Jar finds himself thrust into critical situations and rises to the occasion, proving that bravery can come from the most unlikely sources."} - {:id (str "jarjar-3") - :title "A Friend to All" - :description - "In this section, we highlight Jar Jar's genuine kindness and his ability to forge connections with characters from different walks of life. Whether it's befriending Qui-Gon Jinn and Obi-Wan Kenobi or bridging the gap between the Gungans and the people of Naboo, Jar Jar's warm-hearted nature makes him a loyal and dedicated friend to those around him."} - {:id (str "jarjar-4") - :title "Navigating a Galaxy in Turmoil" - :description - "Here, we explore Jar Jar's role in the tumultuous events of the Star Wars galaxy. From his involvement in the Trade Federation conflict to his stint as a senator in the Galactic Senate, Jar Jar finds himself amidst political upheaval, striving to bring unity and understanding in a time of division."} - {:id (str "jarjar-5") - :title "Legacy and Controversy" - :description - "This section addresses the lasting impact and mixed reception of Jar Jar Binks. We discuss the character's enduring presence in popular culture and how he has sparked debates among fans. Despite the controversies, Jar Jar remains an iconic figure, reminding us that even the most polarizing characters can leave a lasting legacy."}])) + [:div + "For now modal component is not working with portfolio, due to React Portal that renders itself in the root of the document, which is problematic when iframe is used"] + [web-button/button {:text "Call modal" + :on-click (fn [] (swap! modal-open? not))}] + [:div [modal modal-open?]])) + diff --git a/src/cljs/automaton_web/portfolio/components/navigation.cljs b/src/cljs/automaton_web/portfolio/components/navigation.cljs index 3cfedc9c..140d1133 100644 --- a/src/cljs/automaton_web/portfolio/components/navigation.cljs +++ b/src/cljs/automaton_web/portfolio/components/navigation.cljs @@ -3,8 +3,7 @@ [automaton-web.components.navigation :as sut] [automaton-web.portfolio.proxy :as web-proxy] [portfolio.reagent-18 :as portfolio - :refer-macros [defscene - configure-scenes]])) + :refer-macros [defscene configure-scenes]])) (configure-scenes {:collection :components :title "Navigation"}) diff --git a/src/cljs/automaton_web/portfolio/components/player.cljs b/src/cljs/automaton_web/portfolio/components/player.cljs index 88cf2981..ad427cd4 100644 --- a/src/cljs/automaton_web/portfolio/components/player.cljs +++ b/src/cljs/automaton_web/portfolio/components/player.cljs @@ -17,9 +17,8 @@ [] (let [pause? (web-react/ratom false)] (fn [] - (web-proxy/wrap-component - [sut/player {:play-fn (fn [] (reset! pause? true)) - :pause-fn (fn [] (reset! pause? false)) - :pause? @pause? - :next-fn #(js/alert "next!") - :prev-fn #(js/alert "previous!")}])))) + (web-proxy/wrap-component [sut/player {:play-fn (fn [] (reset! pause? true)) + :pause-fn (fn [] (reset! pause? false)) + :pause? @pause? + :next-fn #(js/alert "next!") + :prev-fn #(js/alert "previous!")}])))) diff --git a/src/cljs/automaton_web/portfolio/components/section.cljs b/src/cljs/automaton_web/portfolio/components/section.cljs index f5a6f6da..8708ea1f 100644 --- a/src/cljs/automaton_web/portfolio/components/section.cljs +++ b/src/cljs/automaton_web/portfolio/components/section.cljs @@ -2,10 +2,8 @@ (:require [automaton-web.components.section :as sut] [automaton-web.portfolio.proxy :as web-proxy] - [automaton-web.react-proxy :as web-react] [portfolio.reagent-18 :as portfolio - :refer-macros [defscene - configure-scenes]])) + :refer-macros [defscene configure-scenes]])) (configure-scenes {:collection :components :title "Section"}) @@ -92,49 +90,3 @@ :video-src "https://www.youtube.com/embed/9EcjWd-O4jI"} [params] (web-proxy/wrap-component [sut/section-text-video params])) - -(def section-clickable-cards-modal-params - {:current-card (web-react/ratom {}) - :cards - [{:img - "https://images.unsplash.com/photo-1494790108377-be9c29b29330?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80" - :name "Mateusz Mazurczak" - :title "Is a real human person, not an alien" - :description "lorem ipsum lorem ipsum" - :linkedin "https://www.linkedin.com/in/mateuszmazurczak/"} - {:img - "https://images.unsplash.com/photo-1494790108377-be9c29b29330?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80" - :name "Bill Gates" - :title "Co-chair, Bill & Melinda Gates Foundation" - :description "lorem ipsum lorem ipsum ipsum ipsum" - :linkedin "https://www.linkedin.com/in/williamhgates/"}]}) - -#_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]} -(defscene section-clickable-cards-modal - :params - section-clickable-cards-modal-params - [params] - (web-proxy/wrap-component - [sut/section-clickable-cards-modal - {:current-card @(:current-card params) - :change-card-fn (fn [card] (reset! (:current-card params) card)) - :cards (:cards params) - :section {:title "hello" - :description "more words"} - :size :sm - :modal-id "card-details-modal"}])) - -#_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]} -(defscene section-clickable-cards-modal-dark - :params - (merge section-clickable-cards-modal-params {:dark? true}) - [params] - (web-proxy/wrap-component - [sut/section-clickable-cards-modal - {:current-card @(:current-card params) - :change-card-fn (fn [card] (reset! (:current-card params) card)) - :cards (:cards params) - :section {:title "hello" - :description "more words"} - :size :sm - :modal-id "card-details-modal"}])) diff --git a/src/cljs/automaton_web/portfolio/components/select.cljs b/src/cljs/automaton_web/portfolio/components/select.cljs index 723907fc..15591e3e 100644 --- a/src/cljs/automaton_web/portfolio/components/select.cljs +++ b/src/cljs/automaton_web/portfolio/components/select.cljs @@ -3,8 +3,7 @@ [automaton-web.components.simple-select :as sut] [automaton-web.portfolio.proxy :as web-proxy] [portfolio.reagent-18 :as portfolio - :refer-macros [defscene - configure-scenes]])) + :refer-macros [defscene configure-scenes]])) (configure-scenes {:collection :components :title "Select"}) @@ -15,8 +14,7 @@ [sut/simple-select {:id "lang-id" :html-name "lang-html" :class ["bg-red-500"] - :on-change #(js/console.log - "On changed happened for lang")} + :on-change #(js/console.log "On changed happened for lang")} [:option {:key :en} "en"] [:option {:key :fr} diff --git a/src/cljs/automaton_web/portfolio/components/spinner.cljs b/src/cljs/automaton_web/portfolio/components/spinner.cljs index cb62d7c1..9b11fb11 100644 --- a/src/cljs/automaton_web/portfolio/components/spinner.cljs +++ b/src/cljs/automaton_web/portfolio/components/spinner.cljs @@ -3,8 +3,7 @@ [automaton-web.components.spinner :as sut] [automaton-web.portfolio.proxy :as web-proxy] [portfolio.reagent-18 :as portfolio - :refer-macros [defscene - configure-scenes]])) + :refer-macros [defscene configure-scenes]])) (configure-scenes {:collection :components :title "Spinner"}) diff --git a/src/cljs/automaton_web/portfolio/components/structure.cljs b/src/cljs/automaton_web/portfolio/components/structure.cljs index ff0e33fe..9ccfd74b 100644 --- a/src/cljs/automaton_web/portfolio/components/structure.cljs +++ b/src/cljs/automaton_web/portfolio/components/structure.cljs @@ -7,8 +7,7 @@ [automaton-web.components.structure :as sut] [automaton-web.portfolio.proxy :as web-proxy] [portfolio.reagent-18 :as portfolio - :refer-macros [defscene - configure-scenes]])) + :refer-macros [defscene configure-scenes]])) (configure-scenes {:collection :components :title "Structure"}) @@ -27,12 +26,10 @@ #_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]} (defscene structure-fancy (web-proxy/wrap-component - [sut/structure {:header [web-header/transparent-header - {:logo "Logo" - :size :full - :right-section [:div "Login"]}] - :footer [web-footer/simple-footer - {:title "Hephaistox footer"}]} + [sut/structure {:header [web-header/transparent-header {:logo "Logo" + :size :full + :right-section [:div "Login"]}] + :footer [web-footer/simple-footer {:title "Hephaistox footer"}]} [:div {:class ["mt-20" "mb-5"]} "Body!"] [web-form/form-basic {} diff --git a/src/cljs/automaton_web/portfolio/components/table.cljs b/src/cljs/automaton_web/portfolio/components/table.cljs index 06656117..2faaae5b 100644 --- a/src/cljs/automaton_web/portfolio/components/table.cljs +++ b/src/cljs/automaton_web/portfolio/components/table.cljs @@ -10,21 +10,18 @@ #_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]} (defscene map-table - (web-proxy/wrap-component [sut/map->table - {:single-kv 1 - :double-kv {:one-el 2} - :another-double-kv {:one-el "Hello" - :two-el "Beboop" - :three-el "I'm third"} - :first-level {:second {:third {:fourth 42} - :third-2 222} - :second-2 10 - :second-3 20}}])) + (web-proxy/wrap-component [sut/map->table {:single-kv 1 + :double-kv {:one-el 2} + :another-double-kv {:one-el "Hello" + :two-el "Beboop" + :three-el "I'm third"} + :first-level {:second {:third {:fourth 42} + :third-2 222} + :second-2 10 + :second-3 20}}])) #_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]} (defscene table - (web-proxy/wrap-component [sut/table {:headers ["one" "two" "three"] - :rows - [["1" "2" "3"] - ["first" "second" "third"] - ["idk" "more" "more"]]}])) + (web-proxy/wrap-component + [sut/table {:headers ["one" "two" "three"] + :rows [["1" "2" "3"] ["first" "second" "third"] ["idk" "more" "more"]]}])) diff --git a/src/cljs/automaton_web/portfolio/components/tooltip.cljs b/src/cljs/automaton_web/portfolio/components/tooltip.cljs index 5cbc230e..f483fd25 100644 --- a/src/cljs/automaton_web/portfolio/components/tooltip.cljs +++ b/src/cljs/automaton_web/portfolio/components/tooltip.cljs @@ -3,8 +3,7 @@ [automaton-web.components.tooltip :as sut] [automaton-web.portfolio.proxy :as web-proxy] [portfolio.reagent-18 :as portfolio - :refer-macros [defscene - configure-scenes]])) + :refer-macros [defscene configure-scenes]])) (configure-scenes {:collection :components :title "Tooltip"}) diff --git a/src/cljs/automaton_web/portfolio/components/version.cljs b/src/cljs/automaton_web/portfolio/components/version.cljs index bad11445..c003450e 100644 --- a/src/cljs/automaton_web/portfolio/components/version.cljs +++ b/src/cljs/automaton_web/portfolio/components/version.cljs @@ -3,8 +3,7 @@ [automaton-web.components.version :as sut] [automaton-web.portfolio.proxy :as web-proxy] [portfolio.reagent-18 :as portfolio - :refer-macros [defscene - configure-scenes]])) + :refer-macros [defscene configure-scenes]])) (configure-scenes {:collection :components :title "Version"}) diff --git a/src/cljs/automaton_web/portfolio/pages/error.cljs b/src/cljs/automaton_web/portfolio/pages/error.cljs index 0274b576..35c6feb6 100644 --- a/src/cljs/automaton_web/portfolio/pages/error.cljs +++ b/src/cljs/automaton_web/portfolio/pages/error.cljs @@ -10,12 +10,10 @@ #_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]} (defscene not-found [:div {:class ["h-full w-full"]} - [sut/not-found - {:back-link "https://www.wikipedia.com" - :title "Page not found" - :description - "Sorry we couldn't find the page you were looking for." - :back-home-text "Back home"}]]) + [sut/not-found {:back-link "https://www.wikipedia.com" + :title "Page not found" + :description "Sorry we couldn't find the page you were looking for." + :back-home-text "Back home"}]]) #_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]} (defscene diff --git a/src/cljs/automaton_web/portfolio/proxy.cljs b/src/cljs/automaton_web/portfolio/proxy.cljs index 7ad80ed2..43735e0d 100644 --- a/src/cljs/automaton_web/portfolio/proxy.cljs +++ b/src/cljs/automaton_web/portfolio/proxy.cljs @@ -1,15 +1,11 @@ (ns automaton-web.portfolio.proxy (:require - [automaton-web.components.init-components :as web-init-components] - [automaton-web.react-proxy :as web-react] - [portfolio.data :as data] - [portfolio.ui :as ui] - [portfolio.ui.search :as search])) + [automaton-core.utils.uuid-gen :as uuid-gen] + [portfolio.data :as data] + [portfolio.ui :as ui] + [portfolio.ui.search :as search])) - -(defn iframe-document - [] - (.-contentDocument (aget (.getElementsByTagName js/document "iframe") 0))) +(defn iframe-document [] (.-contentDocument (aget (.getElementsByTagName js/document "iframe") 0))) (def start! ui/start!) @@ -18,9 +14,7 @@ (def register-collection! data/register-collection!) (defn wrap-component - "A simple wrapper to prevent to spread that code on all scenes" + "A simple wrapper to enable additional code to be added for each scene. + Right now it's empty" [& cmps] - (web-react/as-element [:f> - #(let [_ (web-init-components/init-elements-js - (iframe-document))] - (into [:<>] (doall (for [cmp cmps] cmp))))])) + [:span (doall (for [cmp cmps] ^{:key (str (uuid-gen/unguessable))} cmp))]) diff --git a/tailwind.config.js b/tailwind.config.js index 47efe126..388c1e18 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -5,7 +5,5 @@ module.exports = { // and whatever if it is, to make the minification happens we need to have a // look to only left classes in js content: process.env.NODE_ENV == 'production' ? - ['./resources/public/js/compiled/cljs-runtime/**/*.js', - './node_modules/tw-elements/js/**/*.js'] : - ['./src/**/*.{html,js,clj,cljs,cljc}', - './node_modules/tw-elements/js/**/*.js']} + ['./resources/public/js/compiled/cljs-runtime/**/*.js'] : + ['./src/**/*.{html,js,clj,cljs,cljc}']} diff --git a/test/clj/automaton_web/adapters/be/http_request_test.clj b/test/clj/automaton_web/adapters/be/http_request_test.clj index 4d6927d8..9ee75bda 100644 --- a/test/clj/automaton_web/adapters/be/http_request_test.clj +++ b/test/clj/automaton_web/adapters/be/http_request_test.clj @@ -4,8 +4,7 @@ [clojure.test :refer [deftest is testing]])) (deftest cookies-language-test - (testing "Empty query should pass silently" - (is (nil? (sut/cookies-language {})))) + (testing "Empty query should pass silently" (is (nil? (sut/cookies-language {})))) (testing "Test nil values" (is (nil? (sut/cookies-language {:cookies {:value {"lang" nil}}}))) (is (nil? (sut/cookies-language {:cookies (:value {"lang" "null"})})))) diff --git a/test/clj/automaton_web/adapters/be/http_response_test.clj b/test/clj/automaton_web/adapters/be/http_response_test.clj index d553c3c3..7df5ff29 100644 --- a/test/clj/automaton_web/adapters/be/http_response_test.clj +++ b/test/clj/automaton_web/adapters/be/http_response_test.clj @@ -25,8 +25,7 @@ :headers {} :body "not-found"} (sut/not-found "not-found")))) - (testing - "test method-not-allowed handler is called and returning 405 status" + (testing "test method-not-allowed handler is called and returning 405 status" (is (= {:status 405 :headers {} :body "method-not-allowed"} diff --git a/test/clj/automaton_web/duplex/core_test.clj b/test/clj/automaton_web/duplex/core_test.clj index 9a63350e..f208dcb1 100644 --- a/test/clj/automaton_web/duplex/core_test.clj +++ b/test/clj/automaton_web/duplex/core_test.clj @@ -6,15 +6,13 @@ (deftest server-test (testing "mocking realtime server" - (let [_ (with-out-str (mount/start-with-states - {#'automaton-web.duplex.core/duplex-server - {:start (partial sut/start-rt nil)}}))] + (let [_ (with-out-str (mount/start-with-states {#'automaton-web.duplex.core/duplex-server + {:start (partial sut/start-rt nil)}}))] (testing "Realtime server has an ajax-get-or-ws-handshake-fn" (is (fn? (sut/ajax-get-or-ws-handshake)))) (testing "Realtime server has an ajax-post" (is (fn? (sut/ajax-post)))) (testing "Realtime server has a ch-recv" (is (sut/ch-recv))) (testing "Realtime server has a connected-uids" (is (= clojure.lang.Atom (type (sut/connected-uids))))) - (testing "Realtime server has a send-fn" - (is (not (sut/send-fn 666 [:foo/bar])))) + (testing "Realtime server has a send-fn" (is (not (sut/send-fn 666 [:foo/bar])))) (with-out-str (mount/stop))))) diff --git a/test/clj/automaton_web/duplex/routes_test.clj b/test/clj/automaton_web/duplex/routes_test.clj index 607ea9c0..b605b92e 100644 --- a/test/clj/automaton_web/duplex/routes_test.clj +++ b/test/clj/automaton_web/duplex/routes_test.clj @@ -7,17 +7,14 @@ [reitit.ring :as reitit-ring])) (deftest route2 - (let [router (reitit-ring/router (sut/routes* - (constantly (http-response/ok "stub")) - (constantly (http-response/ok "stub")))) + (let [router (reitit-ring/router (sut/routes* (constantly (http-response/ok "stub")) + (constantly (http-response/ok "stub")))) app (reitit-ring/ring-handler router) page (app {:request-method :get - :query-string - "client-id=d184907d-f1ee-491c-a49f-eb21fed56c1f" + :query-string "client-id=d184907d-f1ee-491c-a49f-eb21fed56c1f" :headers {"accept-encoding" "gzip, deflate, br"} :uri duplex-route/duplex-uri})] (testing "Session are managed" (is (get-in page [:headers "Set-Cookie"]))) - (testing "Antiforgery token" - (is (get-in page [:request-copied :anti-forgery-token]))) + (testing "Antiforgery token" (is (get-in page [:request-copied :anti-forgery-token]))) (testing "Wrap params is keyed wrap-params and wrap-keyword-params" (is (keyword? (ffirst (get-in page [:request-copied :params]))))))) diff --git a/test/clj/automaton_web/duplex/session_test.clj b/test/clj/automaton_web/duplex/session_test.clj index 4ee5d5cb..37042492 100644 --- a/test/clj/automaton_web/duplex/session_test.clj +++ b/test/clj/automaton_web/duplex/session_test.clj @@ -30,8 +30,7 @@ (deftest session-types-test (with-redefs [sut/session-store (atom {})] - (testing "Session is an atom" - (is (= clojure.lang.Atom (type sut/session-store)))) + (testing "Session is an atom" (is (= clojure.lang.Atom (type sut/session-store)))) (testing "Sessions are a map" (is (map? (sut/sessions))) (is (every? string? (keys (sut/sessions))))))) @@ -45,10 +44,8 @@ sut/options {:store mem-store}] (let [app-count (-> handler-count web-middleware/wrap-session)] - (testing "Before first handler call, session is empty" - (is (zero? (count (sut/sessions))))) - (testing - "First handler count call, no cookie, no session, no session key" + (testing "Before first handler call, session is empty" (is (zero? (count (sut/sessions))))) + (testing "First handler count call, no cookie, no session, no session key" (let [first-attempt (app-count {})] (is (= {:status 200 :body "You accessed this page 0 times." @@ -57,9 +54,7 @@ :session/key nil}} (dissoc first-attempt :headers))) (is (get-in first-attempt [:headers "Set-Cookie"])) - (is (nil? (get-in - first-attempt - [:echoed-request :cookies "ring-session" :value]))))) + (is (nil? (get-in first-attempt [:echoed-request :cookies "ring-session" :value]))))) (testing "First handler call has updated sessions" (is (= 1 (count (sut/sessions)))) (is (= 1 @@ -69,29 +64,21 @@ :count)))) (let [key (ffirst (sut/sessions))] (testing "Session can be read" (is (.read-session mem-store key))) - (let [second-attempt - (app-count {:headers {"cookie" (str "ring-session=" key)}})] + (let [second-attempt (app-count {:headers {"cookie" (str "ring-session=" key)}})] (testing "Cookies found" - (is (= key - (get-in - second-attempt - [:echoed-request :cookies "ring-session" :value])))) + (is (= key (get-in second-attempt [:echoed-request :cookies "ring-session" :value])))) (testing "Key is found" - (is (= key - (get-in second-attempt [:echoed-request :session/key])))) + (is (= key (get-in second-attempt [:echoed-request :session/key])))) (testing "Session found" - (is - (= 1 (get-in second-attempt [:echoed-request :session :count])))) + (is (= 1 (get-in second-attempt [:echoed-request :session :count])))) (testing "Second handler count call return the updated content" (is (= {:body "You accessed this page 1 times."} (select-keys second-attempt [:body])))) - (testing - "Second handler call has updated the same session id with an incremented count" + (testing "Second handler call has updated the same session id with an incremented count" (is (= 1 (count (sut/sessions)))) (is (= 2 (-> (sut/sessions) first second :count)))))))) - (testing "Testing should not influence dev env" - (is (= (sut/sessions) before-session-store))))) + (testing "Testing should not influence dev env" (is (= (sut/sessions) before-session-store))))) diff --git a/test/clj/automaton_web/handlers_test.clj b/test/clj/automaton_web/handlers_test.clj index 97291d4d..13fda801 100644 --- a/test/clj/automaton_web/handlers_test.clj +++ b/test/clj/automaton_web/handlers_test.clj @@ -20,9 +20,7 @@ ["/pong" (constantly nil)]]) (sut/default-handlers {:not-found (fn [request] - (assoc (http-response/not-found "kosh") - :tr-present? - (boolean (:tr request)))) + (assoc (http-response/not-found "kosh") :tr-present? (boolean (:tr request)))) :not-allowed (constantly (http-response/method-not-allowed "kosh")) :not-acceptable (constantly (http-response/not-acceptable "kosh"))} (web-middleware/translation-middlewares be-translator-stub)))) @@ -72,9 +70,8 @@ {:foo-r 1})))) (testing "Wrapper are compatible with compiled middlewares" (is (= {:foo 1} - ((sut/apply-middlewares - (fn [request] {:foo (:foo-r request)}) - [automaton-web.middleware/wrap-cookies - {:name :reitit.ring.middleware.parameters/parameters - :wrap automaton-web.middleware/wrap-cookies}]) + ((sut/apply-middlewares (fn [request] {:foo (:foo-r request)}) + [automaton-web.middleware/wrap-cookies + {:name :reitit.ring.middleware.parameters/parameters + :wrap automaton-web.middleware/wrap-cookies}]) {:foo-r 1}))))) diff --git a/test/clj/automaton_web/i18n/be/translator/tempura_test.clj b/test/clj/automaton_web/i18n/be/translator/tempura_test.clj index c14e16cf..aba86399 100644 --- a/test/clj/automaton_web/i18n/be/translator/tempura_test.clj +++ b/test/clj/automaton_web/i18n/be/translator/tempura_test.clj @@ -37,8 +37,7 @@ (deftest default-languages-test (testing "Default language is found" - (is (= default-language - (be-translator/default-languages temp-translator))))) + (is (= default-language (be-translator/default-languages temp-translator))))) (deftest get-middleware-test (testing "Middleware has the expected keys" (is (= #{:tr :accept-langs :locales} @@ -48,13 +47,11 @@ keys set))))) (testing "Test translation based on request" - (is (= - "foo-en" - (be-translator/translate-based-on-request temp-translator {} :foo []))) + (is (= "foo-en" (be-translator/translate-based-on-request temp-translator {} :foo []))) (is (= "foo-fr" - (be-translator/translate-based-on-request - temp-translator - {:headers {"host" "http://www.testify.com?lang=en"} - :locales [:fr]} - :foo - []))))) + (be-translator/translate-based-on-request temp-translator + {:headers {"host" + "http://www.testify.com?lang=en"} + :locales [:fr]} + :foo + []))))) diff --git a/test/clj/automaton_web/i18n/be/translator_test.clj b/test/clj/automaton_web/i18n/be/translator_test.clj index e56058dc..fd6c3a9b 100644 --- a/test/clj/automaton_web/i18n/be/translator_test.clj +++ b/test/clj/automaton_web/i18n/be/translator_test.clj @@ -10,9 +10,7 @@ "Faulty delay, meant to check it is not evaluted" (delay (throw (ex-info "Should not happen" {})))) -(def nd - "Wait for it: Null delay, return delay, but wait for a delay" - (delay nil)) +(def nd "Wait for it: Null delay, return delay, but wait for a delay" (delay nil)) (deftest language-choice-strategy*-test (testing "language in path parameters is higher priority" @@ -28,25 +26,19 @@ (deftest language-choice-strategy-def-test (testing "If parameter is given, this is the priority" - (is (= "fr" - (sut/lang-str-choice-strategy-def web-translator - {:params {:lang "fr"}})))) + (is (= "fr" (sut/lang-str-choice-strategy-def web-translator {:params {:lang "fr"}})))) (testing "If no information is found at all, return default language" (is (= :sk (sut/lang-str-choice-strategy-def web-translator {})))) (testing "Test cookies accepted language is used" (is (= "fr" - (sut/lang-str-choice-strategy-def - web-translator - {:headers {"accept-language" - "fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7"}})))) + (sut/lang-str-choice-strategy-def web-translator + {:headers {"accept-language" + "fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7"}})))) (testing "Cookies language are skipped if unknown" (is (= "pl" - (sut/lang-str-choice-strategy-def - web-translator - {:headers {"accept-language" - "pl-PL,fr;q=0.9,en-US;q=0.8,en;q=0.7"}})))) + (sut/lang-str-choice-strategy-def web-translator + {:headers {"accept-language" + "pl-PL,fr;q=0.9,en-US;q=0.8,en;q=0.7"}})))) (testing "Tld language is used" (is (= "en" - (sut/lang-str-choice-strategy-def web-translator - {:headers {"host" - "hephaistox.en"}}))))) + (sut/lang-str-choice-strategy-def web-translator {:headers {"host" "hephaistox.en"}}))))) diff --git a/test/clj/automaton_web/i18n/language_test.cljc b/test/clj/automaton_web/i18n/language_test.cljc index 80ff5b98..eeef593e 100644 --- a/test/clj/automaton_web/i18n/language_test.cljc +++ b/test/clj/automaton_web/i18n/language_test.cljc @@ -11,9 +11,8 @@ (deftest cors-domain-routes-test (testing "routes are built" (is (= #{".*heph.com$" ".*heph.fr$"} - (->> (sut/cors-domain-routes (sut/make-automaton-web-languages - {:en {} - :fr {}}) + (->> (sut/cors-domain-routes (sut/make-automaton-web-languages {:en {} + :fr {}}) "heph") (map core-regexp/stringify) set))))) diff --git a/test/clj/automaton_web/middleware_test.clj b/test/clj/automaton_web/middleware_test.clj index ed3bcd41..7cb3eb72 100644 --- a/test/clj/automaton_web/middleware_test.clj +++ b/test/clj/automaton_web/middleware_test.clj @@ -8,9 +8,9 @@ (defn middleware-env-mock [middleware] - (reitit-ring/ring-handler - (reitit-ring/router ["/ping" {:get #(select-keys % [:params :query-params])}] - {:data {:middleware middleware}}))) + (reitit-ring/ring-handler (reitit-ring/router ["/ping" + {:get #(select-keys % [:params :query-params])}] + {:data {:middleware middleware}}))) (deftest wrap-deny-frame-test (let [app (sut/wrap-deny-frame handler-test)] @@ -39,20 +39,17 @@ :foo :bar} (app {:bar2 :foo2})))))) -(deftest wrap-session-test - (testing "wrap-session is a function" (is (fn? sut/wrap-session)))) +(deftest wrap-session-test (testing "wrap-session is a function" (is (fn? sut/wrap-session)))) (deftest kw-and-params-test (let [h (middleware-env-mock [sut/parameters-middleware])] - (testing - "(Query) Params handler is working - parameters-middleware contract" + (testing "(Query) Params handler is working - parameters-middleware contract" (is (= {:params {"a" "b"} :query-params {"a" "b"}} (h {:request-method :get :uri "/ping" :query-string "a=b"}))))) - (let [h (middleware-env-mock [sut/wrap-keyword-params - sut/parameters-middleware])] + (let [h (middleware-env-mock [sut/wrap-keyword-params sut/parameters-middleware])] (testing "Params and keyword params are working" (is (= {:params {:a "b"} :query-params {}} @@ -66,8 +63,7 @@ (testing "cookies middleware contract" (is (= {"a" {:value "b"}} resp))))) (deftest wrap-throw-error-test - (testing "wrap-throw-error throws an error" - (is (thrown? Error ((sut/wrap-throw-error {}) {}))))) + (testing "wrap-throw-error throws an error" (is (thrown? Error ((sut/wrap-throw-error {}) {}))))) (deftest wrap-throw-exception-test (testing "wrap-throw-error throws an error" diff --git a/test/clj/automaton_web/web_elt/string_to_id_test.cljc b/test/clj/automaton_web/web_elt/string_to_id_test.cljc index 307cce18..bd5074f2 100644 --- a/test/clj/automaton_web/web_elt/string_to_id_test.cljc +++ b/test/clj/automaton_web/web_elt/string_to_id_test.cljc @@ -7,5 +7,4 @@ (deftest string-to-id-test (testing "testing spaces and accent" (is (= "page-d-accueil" (sut/string-to-id "Page d'accueil")))) - (testing "Empty string gives a uuid" - (is (= 36 (count (sut/string-to-id "")))))) + (testing "Empty string gives a uuid" (is (= 36 (count (sut/string-to-id "")))))) diff --git a/test/cljc/automaton_web/components/common_test.cljc b/test/cljc/automaton_web/components/common_test.cljc index 81523edd..bd7b61ca 100644 --- a/test/cljc/automaton_web/components/common_test.cljc +++ b/test/cljc/automaton_web/components/common_test.cljc @@ -5,18 +5,14 @@ [automaton-web.components.common :as sut])) (deftest combine-classes - (testing "Join classes is separated with strings" - (is (= "a b" (sut/combine-classes "a" "b")))) + (testing "Join classes is separated with strings" (is (= "a b" (sut/combine-classes "a" "b")))) (testing "Only one class works" (is (= "a" (sut/combine-classes "a")))) (testing "No class is ok" (is (= "" (sut/combine-classes))))) (deftest combine-classes-with-custom (testing "Custom classes are higher priority" - (is (= "d e a b c" - (sut/combine-classes-with-custom "a b c" :merge "d" "e")))) + (is (= "d e a b c" (sut/combine-classes-with-custom "a b c" :merge "d" "e")))) (testing "Custom only don't select default at all" - (is (= "a b c" - (sut/combine-classes-with-custom "a b c" :custom-only "d e")))) + (is (= "a b c" (sut/combine-classes-with-custom "a b c" :custom-only "d e")))) (testing "Default only don't select default at all" - (is (= "d e" - (sut/combine-classes-with-custom "a b c" :default-only "d" "e"))))) + (is (= "d e" (sut/combine-classes-with-custom "a b c" :default-only "d" "e"))))) diff --git a/test/cljc/automaton_web/i18n/dictionary_test.cljc b/test/cljc/automaton_web/i18n/dictionary_test.cljc index 4e29d06c..47ec2e2d 100644 --- a/test/cljc/automaton_web/i18n/dictionary_test.cljc +++ b/test/cljc/automaton_web/i18n/dictionary_test.cljc @@ -9,16 +9,12 @@ [clojure.string :as str])) (deftest dictionary-test - (testing - (apply - str - "Dictionary is matching all expected languages. List all languages to expect: " - (str/join " " web-language/get-web-languages-ids)) + (testing (apply str + "Dictionary is matching all expected languages. List all languages to expect: " + (str/join " " web-language/get-web-languages-ids)) (is (= [] - (b-language/key-with-missing-languages - sut/dict - web-language/get-web-languages-ids - #{:tongue/missing-key})))) + (b-language/key-with-missing-languages sut/dict + web-language/get-web-languages-ids + #{:tongue/missing-key})))) (testing "All languages are known languages" - (is (empty? (set/difference (set (keys sut/dict)) - web-language/get-web-languages-ids))))) + (is (empty? (set/difference (set (keys sut/dict)) web-language/get-web-languages-ids))))) diff --git a/test/cljc/automaton_web/i18n/resource_dict_test.cljc b/test/cljc/automaton_web/i18n/resource_dict_test.cljc index 731178fe..3f1e4695 100644 --- a/test/cljc/automaton_web/i18n/resource_dict_test.cljc +++ b/test/cljc/automaton_web/i18n/resource_dict_test.cljc @@ -9,16 +9,12 @@ [clojure.string :as str])) (deftest dictionary-test - (testing - (apply - str - "Dictionary is matching all expected languages. List of languages, expect: " - (str/join " " web-language/get-web-languages-ids)) + (testing (apply str + "Dictionary is matching all expected languages. List of languages, expect: " + (str/join " " web-language/get-web-languages-ids)) (is (= [] - (b-language/key-with-missing-languages - sut/dict - web-language/get-web-languages-ids - #{:tongue/missing-key})))) + (b-language/key-with-missing-languages sut/dict + web-language/get-web-languages-ids + #{:tongue/missing-key})))) (testing "All languages are known languages" - (is (empty? (set/difference (set (keys sut/dict)) - web-language/get-web-languages-ids))))) + (is (empty? (set/difference (set (keys sut/dict)) web-language/get-web-languages-ids))))) diff --git a/test/cljc/automaton_web/js_interop_test.cljc b/test/cljc/automaton_web/js_interop_test.cljc index c853366e..9243fc05 100644 --- a/test/cljc/automaton_web/js_interop_test.cljc +++ b/test/cljc/automaton_web/js_interop_test.cljc @@ -5,10 +5,8 @@ (deftest mapToJSmap (testing "Empty map" (is (= "{}" (sut/mapToJSmap {})))) - (testing "String map" - (is (= "{\"foo\": \"bar\"}" (sut/mapToJSmap {:foo "bar"})))) - (testing "keyword with minus" - (is (= "{\"is_foo\": \"bar\"}" (sut/mapToJSmap {:is-foo "bar"})))) + (testing "String map" (is (= "{\"foo\": \"bar\"}" (sut/mapToJSmap {:foo "bar"})))) + (testing "keyword with minus" (is (= "{\"is_foo\": \"bar\"}" (sut/mapToJSmap {:is-foo "bar"})))) (testing "Integer value" (is (= "{\"foo\": 1}" (sut/mapToJSmap {:foo 1})))) (testing "keyword value" (is (= "{\"foo_from\": \"bar_to\"}" (sut/mapToJSmap {:foo-from :bar-to})))) diff --git a/test/cljc/automaton_web/persistence/cookies_test.cljc b/test/cljc/automaton_web/persistence/cookies_test.cljc index 2eae00c4..622878c9 100644 --- a/test/cljc/automaton_web/persistence/cookies_test.cljc +++ b/test/cljc/automaton_web/persistence/cookies_test.cljc @@ -6,14 +6,10 @@ (deftest parse-cookie (testing "Cookie parse 1 and 2 semi column per line" - (is - (= {"ring-session" "496456e5-2860-4a50-9702-51a7cd13d017" - "Path" "/" - ["HttpOnly"] nil} - (sut/parse-cookie - "ring-session=496456e5-2860-4a50-9702-51a7cd13d017;Path=/;HttpOnly")))) + (is (= {"ring-session" "496456e5-2860-4a50-9702-51a7cd13d017" + "Path" "/" + ["HttpOnly"] nil} + (sut/parse-cookie "ring-session=496456e5-2860-4a50-9702-51a7cd13d017;Path=/;HttpOnly")))) (testing "Cookie parse 1 and 2 semi column per line" (is (= {"a" ["b" "c"]} (sut/parse-cookie "a=b=c")))) - (testing "Cookie parse nil" - (is (nil? (sut/parse-cookie ""))) - (is (nil? (sut/parse-cookie nil))))) + (testing "Cookie parse nil" (is (nil? (sut/parse-cookie ""))) (is (nil? (sut/parse-cookie nil))))) diff --git a/test/cljc/automaton_web/reagent_test.cljc b/test/cljc/automaton_web/reagent_test.cljc index 2c0ca16a..2309a2f0 100644 --- a/test/cljc/automaton_web/reagent_test.cljc +++ b/test/cljc/automaton_web/reagent_test.cljc @@ -39,14 +39,12 @@ (testing "Option map is inserted if it does not exist already" (is (= [:div {:bar :foo}] (sut/add-opt [:div] :bar :foo)))) - (testing - "Option map is inserted with multiple values even if it does not already exist" + (testing "Option map is inserted with multiple values even if it does not already exist" (is (= [:div {:bar :foo :bar2 :foo2 :bar3 :foo3}] (sut/add-opt [:div] :bar :foo :bar2 :foo2 :bar3 :foo3)))) - (testing - "Option map is inserted if it does not exist already even if trailing data exists" + (testing "Option map is inserted if it does not exist already even if trailing data exists" (is (= [:div {:bar :foo} "Am" "I" "still" "here?"] @@ -69,13 +67,11 @@ (testing "Component with no options now have some" (is (= [:div {:foo :bar}] (sut/update-reagent-options {:foo :bar} [:div])))) - (testing - "Component with no options now have some, and preserve one following argument" + (testing "Component with no options now have some, and preserve one following argument" (is (= [:div {:foo :bar} "foo"] (sut/update-reagent-options {:foo :bar} [:div "foo"])))) - (testing - "Component with no component now have some, and preserve two followings arguments" + (testing "Component with no component now have some, and preserve two followings arguments" (is (= [:div {:foo :bar} "foo" "bar"] @@ -84,8 +80,7 @@ (is (= [:div {:foo :bar}] (sut/update-reagent-options {:foo :bar} [:div {:foo2 :bar2}])))) - (testing - "Options of a component are replaced, and preserve one following argument" + (testing "Options of a component are replaced, and preserve one following argument" (is (= [:div {:foo :bar} "foo"] (sut/update-reagent-options {:foo :bar} diff --git a/test/cljc/automaton_web/routes_test.cljc b/test/cljc/automaton_web/routes_test.cljc index c2435252..ee71f222 100644 --- a/test/cljc/automaton_web/routes_test.cljc +++ b/test/cljc/automaton_web/routes_test.cljc @@ -6,8 +6,7 @@ (deftest parse-route-elt-test (testing "Strings are preserved" (is (= "foo" (sut/parse-routes :be "foo")))) - (testing - "If be or fe data isn't a map, so copy it directly (usefull to pass handlers directly)" + (testing "If be or fe data isn't a map, so copy it directly (usefull to pass handlers directly)" (is (= 'clojure.print (sut/parse-routes :be {:name :foo @@ -26,8 +25,7 @@ {:name ::root :be {:page-id :html-page/index} :fe {:panel-id :panels/home}})))) - (testing "Vectors values are treated" - (is (= ["foo" "bar"] (sut/parse-routes :be ["foo" "bar"])))) + (testing "Vectors values are treated" (is (= ["foo" "bar"] (sut/parse-routes :be ["foo" "bar"])))) (testing "Registry replace keywords" (is (= ["" clojure.core/last] (sut/parse-routes :be ["" {:be :foo}] {:foo clojure.core/last}))))) diff --git a/test/cljs/automaton_web/components/init_components_test.cljs b/test/cljs/automaton_web/components/init_components_test.cljs deleted file mode 100644 index 9958c0e0..00000000 --- a/test/cljs/automaton_web/components/init_components_test.cljs +++ /dev/null @@ -1,28 +0,0 @@ -(ns automaton-web.components.init-components-test - (:require - [automaton-web.components.init-components :as sut] - [cljs.test :refer [deftest - is - testing] - :include-macros true] - [goog.object])) - -(defn err->edn - [e] - (into {} - (map (fn [k] [(keyword k) (js->clj (goog.object/get e k))])) - (.getOwnPropertyNames js/Object e))) - -(deftest modal-element-initialized - (comment - (testing "Modal element is returned" - (is (= [:_focustrap - :_ignoreBackdropClick - :_backdrop - :_scrollBar - :_config - :_classes - :_isTransitioning - :_dialog - :_isShown] - (keys (err->edn (sut/init-modal [:div])))))))) diff --git a/version.edn b/version.edn index a22474e2..a8f59fb1 100644 --- a/version.edn +++ b/version.edn @@ -1,2 +1,2 @@ ;; Last generated version, note a failed push consume a number -{:version "1.3.0"} \ No newline at end of file +{:version "2.0.0"} \ No newline at end of file