diff --git a/frontend/src/app/main/ui/ds/controls/shared/options_dropdown.cljs b/frontend/src/app/main/ui/ds/controls/shared/options_dropdown.cljs index f8a5dd3a68..0191891398 100644 --- a/frontend/src/app/main/ui/ds/controls/shared/options_dropdown.cljs +++ b/frontend/src/app/main/ui/ds/controls/shared/options_dropdown.cljs @@ -62,6 +62,7 @@ (case type :group [:li {:class (stl/css :group-option) + :role "presentation" :key (weak-key option)} [:> icon* {:icon-id i/arrow-down @@ -74,7 +75,7 @@ [:hr {:key (weak-key option) :class (stl/css :option-separator)}] :empty - [:li {:key (weak-key option) :class (stl/css :option-empty)} + [:li {:key (weak-key option) :class (stl/css :option-empty) :role "presentation"} (get option :label)] ;; Token option diff --git a/frontend/src/app/main/ui/workspace/tokens/management/forms/controls/token_parsing.cljs b/frontend/src/app/main/ui/workspace/tokens/management/forms/controls/token_parsing.cljs index 46c4548caf..f94cd4e565 100644 --- a/frontend/src/app/main/ui/workspace/tokens/management/forms/controls/token_parsing.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/management/forms/controls/token_parsing.cljs @@ -18,39 +18,52 @@ last-close (str/last-index-of text-before "}")] (when (and last-open (or (nil? last-close) (> last-open last-close))) {:start last-open + :end (or (str/index-of value "}" last-open) cursor) :partial (subs text-before (inc last-open))}))) -;; (defn replace-active-token -;; [value cursor new-name] -;; -;; (let [before (subs value 0 cursor) -;; last-open (str/last-index-of before "{") -;; last-close (str/last-index-of before "}")] -;; -;; (if (and last-open -;; (or (nil? last-close) -;; (> last-open last-close))) -;; -;; (let [after-start (subs value last-open) -;; close-pos (str/index-of after-start "}") -;; end (if close-pos -;; (+ last-open close-pos 1) -;; cursor)] -;; (str (subs value 0 last-open) -;; "{" new-name "}" -;; (subs value end))) -;; (str (subs value 0 cursor) -;; "{" new-name "}" -;; (subs value cursor))))) +(defn find-active-token-range + "Returns {:start :end} for the token surrounding the cursor. + A token starts with '{', contains no spaces, and may be incomplete. + Returns nil if no valid token is active." + [value cursor] + (let [start (.lastIndexOf value "{" cursor)] + (when (>= start 0) + (let [between (subs value (inc start) cursor)] + (when-not (re-find #"\s" between) + (let [after (subs value (inc start)) + close-index (.indexOf after "}") + close-pos (when (>= close-index 0) + (+ (inc start) close-index)) + space-index (.indexOf after " ") + space-pos (when (>= space-index 0) + (+ (inc start) space-index)) + + end (cond + (and close-pos + (or (nil? space-pos) + (< close-pos space-pos))) + (inc close-pos) + + space-pos + space-pos + + :else + cursor)] + + {:start start + :end end})))))) (defn replace-active-token + "Replaces the token at the cursor with `{new-name}`. + If no valid token is active, inserts the new token at the cursor position." [value cursor new-name] - (if-let [{:keys [start]} (extract-partial-token value cursor)] - ;; Hay token activo + (if-let [{:keys [start end]} + (find-active-token-range value cursor)] + (str (subs value 0 start) "{" new-name "}" - (subs value cursor)) - ;; No hay token activo → insertar en cursor + (subs value end)) + (str (subs value 0 cursor) "{" new-name "}" (subs value cursor))))