Skip to content

Commit

Permalink
[REFACTOR]: new behavior on accordions at creating a connection (#569)
Browse files Browse the repository at this point in the history
* feat(connections): create helpers

* refactor(connections): add new behaviors to accordion at creating connection

* fix(connections): fix not fill the command value when choose ssh

* chore(version): update to version 1.32.2
  • Loading branch information
rogefm authored Nov 26, 2024
1 parent 0b896f5 commit 024a776
Show file tree
Hide file tree
Showing 10 changed files with 273 additions and 242 deletions.
2 changes: 1 addition & 1 deletion webapp/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "webapp",
"version": "1.32.1",
"version": "1.32.2",
"scripts": {
"ancient": "clojure -Sdeps '{:deps {com.github.liquidz/antq {:mvn/version \"RELEASE\"}}}' -m antq.core",
"genversion": "npx genversion src/webapp/version.js",
Expand Down
52 changes: 31 additions & 21 deletions webapp/src/webapp/components/accordion.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@

[:div {:className "flex space-x-3 items-center"}
(when show-icon? [status-icon status])

[:> ChevronRight {:size 16 :className "text-[--gray-12] transition-transform duration-300 group-data-[state=open]:rotate-90"}]]]]
[:> ChevronRight {:size 16
:className "text-[--gray-12] transition-transform duration-300 group-data-[state=open]:rotate-90"}]]]]

[:> (.-Content Accordion)
[:> Box {:px "5" :py "7" :className "bg-white border-t border-[--gray-a6] rounded-b-6"}
Expand All @@ -68,26 +68,36 @@
:show-icon? - Boolean, if true, displays a status icon (optional, default false)
- id: A unique identifier for the accordion (optional)
- first-open?: Boolean, if true, the first item will be expanded by default (optional, default false)
- initial-open?: Boolean, if true, the first item will be expanded by default (optional)
- trigger-value: Value to trigger opening/closing of a specific accordion item (optional)
Usage example:
[accordion-root {:items [{:value \"item1\"
:title \"Title 1\"
:subtitle \"Subtitle 1\"
:content \"Content of item 1\"}
{:value \"item2\"
:title \"Title 2\"
:content \"Content of item 2\"
:show-icon? true}]
:title \"Title 1\"
:subtitle \"Subtitle 1\"
:content \"Content of item 1\"}
{:value \"item2\"
:title \"Title 2\"
:content \"Content of item 2\"
:show-icon? true}]
:id \"my-accordion\"
:first-open? true}]"
[{:keys [items id first-open?]}]
[:> (.-Root Accordion)
{:className "w-full"
:id id
:defaultValue (when first-open?
(:value (first items)))
:type "single"
:collapsible true}
(for [{:keys [value] :as item} items]
^{:key value} [accordion-item (merge item {:total-items (count items)})])])
:initial-open? true
:trigger-value \"item2\"}]"
[{:keys [items initial-open?]}]
(let [current-value (r/atom nil)]
(when (and initial-open? (seq items) (nil? @current-value))
(reset! current-value (-> items first :value)))

(fn [{:keys [items id trigger-value]}]
(when (and trigger-value (not= trigger-value @current-value))
(reset! current-value trigger-value))

[:> (.-Root Accordion)
{:className "w-full"
:id id
:value @current-value
:onValueChange #(reset! current-value %)
:type "single"
:collapsible true}
(for [{:keys [value] :as item} items]
^{:key value} [accordion-item (merge item {:total-items (count items)})])])))
2 changes: 1 addition & 1 deletion webapp/src/webapp/components/forms.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@
:id (or id "")
:rows (or rows 5)
:name (or name "")
:value value
:value (or value "")
:autoFocus autoFocus
:placeholder placeholder
:on-change on-change
Expand Down
135 changes: 135 additions & 0 deletions webapp/src/webapp/connections/helpers.cljs
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
(ns webapp.connections.helpers
"Helper functions for working with connections in the webapp.
Provides utilities for handling connection names, configurations, and data transformations."
(:require
["unique-names-generator" :as ung] ; Library for generating unique names
[clojure.set :as set]
[clojure.string :as s]
[webapp.connections.constants :as constants]))

(defn array->select-options
"Converts an array of values into a format suitable for select options.
Takes an array of values and returns a vector of maps with :value and :label keys.
The label is lowercase with underscores replaced by spaces.
Example:
(array->select-options [\"FOO_BAR\"])
;=> [{\"value\" \"FOO_BAR\" \"label\" \"foo bar\"}]"
[array]
(mapv #(into {} {"value" % "label" (s/lower-case (s/replace % #"_" " "))}) array))

(defn js-select-options->list
"Converts JavaScript select options into a list of values.
Takes an array of objects with 'value' keys and returns a vector of just the values.
Example:
(js-select-options->list [{\"value\" \"foo\"} {\"value\" \"bar\"}])
;=> [\"foo\" \"bar\"]"
[options]
(mapv #(get % "value") options))

(defn random-connection-name
"Generates a random connection name using animal names and Star Wars references.
Returns a string in the format \"<name>-<4 digits>\"
Example: \"wookie-1234\""
[]
(let [numberDictionary (.generate ung/NumberDictionary #js{:length 4})
characterName (ung/uniqueNamesGenerator #js{:dictionaries #js[ung/animals ung/starWars]
:style "lowerCase"
:length 1})]
(str characterName "-" numberDictionary)))

(defn normalize-key
"Converts a key into a normalized keyword format.
Takes a key and returns it as a lowercase keyword.
Example:
(normalize-key :FOO_BAR) ;=> :foo_bar"
[k]
(keyword (clojure.string/lower-case (name k))))

(defn merge-by-key
"Merges two arrays of maps based on their :key values.
Preserves required flags and placeholders from arr1 while merging with values from arr2.
Used to merge connection configuration templates with actual values."
[arr1 arr2]
(let [map1 (into {} (map (fn [x] [(normalize-key (:key x)) x]) arr1))
map2 (into {} (map (fn [x] [(normalize-key (:key x)) x]) arr2))
all-keys (set/union (set (keys map1)) (set (keys map2)))]
(mapv
(fn [k]
(let [val1 (:value (get map1 k))
val2 (:value (get map2 k))
required (:required (get map1 k))
placeholder (:placeholder (get map1 k))
hidden (:hidden (get map1 k))
selected (cond
(and (not (empty? val1)) (empty? val2)) (get map1 k)
(and (empty? val1) (not (empty? val2))) (assoc (get map2 k)
:required required
:hidden hidden
:placeholder placeholder)
:else (if (nil? val1) (assoc (get map2 k)
:required required
:hidden hidden
:placeholder placeholder) (get map1 k)))]
selected))
all-keys)))

(defn get-config-keys
"Gets the required configuration keys for a given connection type.
Takes a key and returns the corresponding configuration from constants/connection-configs-required."
[key]
(get constants/connection-configs-required key))

(defn config->json
"Converts configuration maps to a JSON format with prefixed keys.
Takes a vector of config maps with :key and :value and a prefix string.
Returns a map with prefixed keys and base64 encoded values.
Example:
(config->json [{:key \"foo\" :value \"bar\"}] \"envvar:\")
;=> {\"envvar:FOO\" \"<base64 of bar>\"}"
[configs prefix]
(->> configs
(filter (fn [{:keys [key value]}]
(not (or (s/blank? key) (s/blank? value)))))
(map (fn [{:keys [key value]}] {(str prefix (s/upper-case key)) (js/btoa value)}))
(reduce into {})))

(defn json->config
"Converts a JSON configuration back into the internal config format.
Takes a map of config key/values and returns a vector of maps with :key and :value keys.
Example:
(json->config {\"FOO\" \"bar\"})
;=> [{:key \"FOO\" :value \"bar\"}]"
[configs]
(if (or (s/blank? configs) (nil? configs))
{}
(->> configs
(mapv (fn [[key value]] {:key (name key) :value value})))))

(defn separate-values-from-config-by-prefix
"Separates configuration values by a given prefix (envvar: or filesystem:).
Takes a config map and prefix string. Returns a new map with the prefixes stripped
and values base64 decoded."
[configs prefix]
(let [regex (if (= prefix "envvar")
#"envvar:"
#"filesystem:")]
(->> configs
(filter (fn [[k]]
(s/includes? (name k) prefix)))
(map (fn [[k v]]
{(keyword (s/replace (name k) regex "")) (js/atob v)}))
(reduce into {}))))
60 changes: 0 additions & 60 deletions webapp/src/webapp/connections/utilities.cljs

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
(ns webapp.connections.views.create-update-connection.connection-details-form
(:require ["@radix-ui/themes" :refer [Box Callout Flex Grid Link Switch Text]]
["lucide-react" :refer [ArrowUpRight Star]]
[clojure.string :as s]
[webapp.components.forms :as forms]
[webapp.components.multiselect :as multi-select]
[webapp.connections.dlp-info-types :as dlp-info-types]))

(defn array->select-options [array]
(mapv #(into {} {"value" % "label" (s/lower-case (s/replace % #"_" " "))}) array))
(:require
["@radix-ui/themes" :refer [Box Callout Flex Grid Link Switch Text]]
["lucide-react" :refer [ArrowUpRight Star]]
[webapp.components.forms :as forms]
[webapp.components.multiselect :as multi-select]
[webapp.connections.dlp-info-types :as dlp-info-types]
[webapp.connections.helpers :as helpers]))

(defn main
[{:keys [user-groups
free-license?
connection-name
connection-subtype
form-type
reviews
review-groups
Expand All @@ -24,7 +23,9 @@
[:> Text {:size "4" :weight "bold" :class "text-gray-12"} "Connection information"]
[:> Text {:size "3" :class "text-gray-11"} "Names are used to identify your connection and can't be changed."]]
[:> Box {:class "space-y-radix-5" :grid-column "span 3 / span 3"}
[forms/input {:placeholder "mssql-armadillo-9696"
[forms/input {:placeholder (str (when @connection-subtype
(str @connection-subtype "-"))
(helpers/random-connection-name))
:label "Name"
:required true
:disabled (= form-type :update)
Expand Down Expand Up @@ -63,7 +64,7 @@
"for individual query approvals.")]
(when @reviews
[:> Box {:mt "4"}
[multi-select/main {:options (array->select-options @user-groups)
[multi-select/main {:options (helpers/array->select-options @user-groups)
:id "approval-groups-input"
:name "approval-groups-input"
:required? @reviews
Expand Down Expand Up @@ -95,7 +96,7 @@
"upgrading your plan."]]])
(when @ai-data-masking
[:> Box {:mt "4"}
[multi-select/main {:options (array->select-options dlp-info-types/options)
[multi-select/main {:options (helpers/array->select-options dlp-info-types/options)
:id "data-masking-groups-input"
:name "data-masking-groups-input"
:disabled? (or (not @ai-data-masking) free-license?)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
(ns webapp.connections.views.create-update-connection.connection-environment-form
(:require ["@radix-ui/themes" :refer [Box Button Callout Flex Grid Link Text]]
["lucide-react" :refer [ArrowUpRight Plus]]
[re-frame.core :as rf]
[reagent.core :as r]
[webapp.components.forms :as forms]
[webapp.connections.views.configuration-inputs :as config-inputs]
[webapp.connections.views.create-update-connection.hoop-run-instructions :as instructions]))

(defn js-select-options->list [options]
(mapv #(get % "value") options))
(:require
["@radix-ui/themes" :refer [Box Button Callout Flex Grid Link Text]]
["lucide-react" :refer [ArrowUpRight Plus]]
[webapp.components.forms :as forms]
[webapp.connections.helpers :as helpers]
[webapp.connections.views.configuration-inputs :as config-inputs]
[webapp.connections.views.create-update-connection.hoop-run-instructions :as instructions]))

(defn main []
(fn [{:keys [agents
Expand Down Expand Up @@ -178,6 +175,6 @@
[instructions/run-hoop-connection {:connection-name @connection-name
:connection-subtype @connection-subtype
:review? @reviews
:review-groups (js-select-options->list @review-groups)
:review-groups (helpers/js-select-options->list @review-groups)
:data-masking? @ai-data-masking
:data-masking-fields (js-select-options->list @ai-data-masking-info-types)}]]])])))
:data-masking-fields (helpers/js-select-options->list @ai-data-masking-info-types)}]]])])))
Loading

0 comments on commit 024a776

Please sign in to comment.