From b2b4bb5433b6a6d5cc32d68770d7bf89ddaf9304 Mon Sep 17 00:00:00 2001 From: Kenneth Cheung Date: Tue, 24 Mar 2026 17:28:58 -0400 Subject: [PATCH 1/2] update action conditionals view and add migration script --- .../src/schema_migrate/core.clj | 24 ++++-- .../src/schema_migrate/interface.clj | 20 +++-- ...itionals_to_default_heading_if_missing.clj | 77 +++++++++++++++++++ .../src/cljc/behave_cms/queries.cljc | 12 ++- .../components/conditionals/subs.cljs | 8 +- .../components/conditionals/views.cljs | 19 +++-- .../behave_cms/components/entity_form.cljs | 13 ++++ .../components/table_entity_form.cljs | 14 ++-- .../behave_cms/group_variables/views.cljs | 41 +++++++--- 9 files changed, 184 insertions(+), 44 deletions(-) create mode 100644 development/migrations/2026_03_24_add_conditionals_to_default_heading_if_missing.clj diff --git a/components/schema_migrate/src/schema_migrate/core.clj b/components/schema_migrate/src/schema_migrate/core.clj index e09e7c90c..e22e5786d 100644 --- a/components/schema_migrate/src/schema_migrate/core.clj +++ b/components/schema_migrate/src/schema_migrate/core.clj @@ -1,11 +1,11 @@ (ns schema-migrate.core (:require - [clojure.walk :as walk] + [clojure.spec.alpha :as spec] [clojure.string :as s] + [clojure.walk :as walk] [datascript.core :refer [squuid]] - [datomic.api :as d] [datomic-store.main :as ds] - [clojure.spec.alpha :as spec] + [datomic.api :as d] [nano-id.core :refer [nano-id]])) (def @@ -185,6 +185,11 @@ [conn t] (:db/id (t-key->entity conn t))) +(defn t-key->bp-uuid + "Get the db/id using translation-key" + [conn t] + (:bp/uuid (t-key->entity conn t))) + (defn t-key-action-name->eid "Given a translation-key of a group-variable an action's name return the action's entity id" [conn gv-t-key action-name] @@ -344,7 +349,7 @@ (defn ->conditional "Payload for a Conditional." - [_conn {:keys [ttype operator values group-variable-uuid] :as params}] + [conn {:keys [ttype operator values group-variable-uuid sub-conditional-operator sub-conditionals] :as params}] (let [payload (cond-> {} (nil? (:bp/uuid params)) (assoc :bp/uuid (rand-uuid)) (nil? (:bp/nid params)) (assoc :bp/nid (nano-id)) @@ -354,14 +359,16 @@ group-variable-uuid (assoc :conditional/group-variable-uuid group-variable-uuid) ttype (assoc :conditional/type ttype) operator (assoc :conditional/operator operator) - values (assoc :conditional/values values))] + values (assoc :conditional/values values) + sub-conditional-operator (assoc :conditional/sub-conditional-operator sub-conditional-operator) + (seq sub-conditionals) (assoc :conditional/sub-conditionals (map #(->conditional conn %) sub-conditionals)))] (if (spec/valid? :behave/conditional payload) payload (spec/explain :behave/conditional payload)))) (defn ->action "Payload for an Action." - [conn {:keys [nname ttype target-value conditionals] :as params}] + [conn {:keys [nname ttype target-value conditionals conditionals-operator] :as params}] (let [payload (cond-> {} (nil? (:bp/uuid params)) (assoc :bp/uuid (rand-uuid)) (not (:bp/nid params)) (assoc :bp/nid (nano-id)) @@ -371,6 +378,7 @@ nname (assoc :action/name nname) ttype (assoc :action/type ttype) target-value (assoc :action/target-value target-value) + conditionals-operator (assoc :action/conditionals-operator conditionals-operator) conditionals (assoc :action/conditionals (map #(->conditional conn %) conditionals)))] (if (spec/valid? :behave/action payload) payload @@ -378,7 +386,7 @@ (defn ->variable [_conn {:keys [nname domain-uuid list-eid translation-key help-key kind bp6-label bp6-code map-units-convertible? - dimension-uuid native-unit-uuid metric-unit-uuid english-unit-uuid] :as params}] + dimension-uuid native-unit-uuid metric-unit-uuid english-unit-uuid] :as params}] (let [payload (cond-> {} (nil? (:bp/uuid params)) (assoc :bp/uuid (rand-uuid)) (not (:bp/nid params)) (assoc :bp/nid (nano-id)) @@ -406,7 +414,7 @@ "Payload for a new Group Variable." [conn {:keys [parent-group-eid order variable-eid cpp-namespace cpp-class cpp-function cpp-parameter translation-key conditionally-set? actions - hide-result-conditionals hide-result? disable-multi-valued-input-conditionals disable-multi-valued-input-conditional-operator] :as params}] + hide-result-conditionals hide-result? disable-multi-valued-input-conditionals disable-multi-valued-input-conditional-operator] :as params}] (let [payload (if (spec/valid? :behave/group-variable params) params (cond-> {} diff --git a/components/schema_migrate/src/schema_migrate/interface.clj b/components/schema_migrate/src/schema_migrate/interface.clj index 7821f1617..08f5120e3 100644 --- a/components/schema_migrate/src/schema_migrate/interface.clj +++ b/components/schema_migrate/src/schema_migrate/interface.clj @@ -51,12 +51,16 @@ :doc "Get the :db/id using translation-key"} t-key->eid c/t-key->eid) +(def ^{:arglists '([conn t]) + :doc "Get the :bp/uuid using translation-key"} + t-key->bp-uuid c/t-key->bp-uuid) + (def ^{:arglists '([conn t]) :doc "Given a translation-key of a group-variable an action's name return the action's entity id"} t-key-action-name->eid c/t-key-action-name->eid) (def ^{:arglists '([conn bp6-code]) - :doc "Given a Behave6 Variable code (e.g. `vSurfaceFuelCode`), returns the matching variable entity ID."} + :doc "Given a Behave6 Variable code (e.g. `vSurfaceFuelCode`), returns the matching variable entity ID."} bp6-code->variable-eid c/bp6-code->variable-eid) (def ^{:arglists '([conn attr]) @@ -95,15 +99,15 @@ remove-nested-i18ns-tx c/remove-nested-i18ns-tx) (def ^{:arglists '([data]) - :doc "Payload for a new Entity, which adds a :bp/nid and :bp/uuid."} + :doc "Payload for a new Entity, which adds a :bp/nid and :bp/uuid."} ->entity c/->entity) (def ^{:arglists '([uuid operator value]) - :doc "Payload for a Group Variable Conditional."} + :doc "Payload for a Group Variable Conditional."} ->gv-conditional c/->gv-conditional) (def ^{:arglists '([operator values]) - :doc "Payload for a Module Conditional."} + :doc "Payload for a Module Conditional."} ->module-conditional c/->module-conditional) (def ^{:arglists '([conn params]) @@ -111,7 +115,7 @@ ->conditional c/->conditional) (def ^{:arglists '([conn params]) - :doc "Payload for a new Group."} + :doc "Payload for a new Group."} ->group c/->group) (def ^{:arglists '([conn params]) @@ -123,14 +127,14 @@ ->variable c/->variable) (def ^{:arglists '([conn params]) - :doc "Payload for a new Group Variable."} + :doc "Payload for a new Group Variable."} ->group-variable c/->group-variable) (def ^{:arglists '([source-eid destination-eid]) - :doc "Payload for a new Link."} + :doc "Payload for a new Link."} ->link c/->link) -(def ^{:arglists '([migration-name]) +(def ^{:arglists '([migration-name]) :->actiondoc "Payload for a new migration."} ->migration c/->migration) diff --git a/development/migrations/2026_03_24_add_conditionals_to_default_heading_if_missing.clj b/development/migrations/2026_03_24_add_conditionals_to_default_heading_if_missing.clj new file mode 100644 index 000000000..a5af61c05 --- /dev/null +++ b/development/migrations/2026_03_24_add_conditionals_to_default_heading_if_missing.clj @@ -0,0 +1,77 @@ +(ns migrations.2026-03-24-add-conditionals-to-default-heading-if-missing + (:require [behave-cms.server :as cms] + [behave-cms.store :refer [default-conn]] + [datomic.api :as d] + [schema-migrate.interface :as sm])) + +;; =========================================================================================================== +;; Overview +;; =========================================================================================================== + +;; Adds conditionals for when a user forgets to select a direction mode + +;; =========================================================================================================== +;; Initialize +;; =========================================================================================================== + +(cms/init-db!) + +#_{:clj-kondo/ignore [:missing-docstring]} +(def conn (default-conn)) + +;; =========================================================================================================== +;; Payload +;; =========================================================================================================== + +(defn t-key->conditional [conn t-key] + {:ttype :group-variable + :operator :equal + :values #{"true"} + :group-variable-uuid (sm/t-key->bp-uuid conn t-key)}) + +#_{:clj-kondo/ignore [:missing-docstring]} +(def payload + [{:db/id (sm/t-key->eid conn "behaveplus:surface:output:fire_behavior:surface_fire:direction_mode:heading") + :group-variable/actions [(sm/->action + conn + {:nname "Enable if no direction mode is selected and at least one of these outputs are selected" + :ttype :select + :conditionals-operator :and + :conditionals [{:ttype :group-variable + :operator :equal + :values #{"false"} + :group-variable-uuid (sm/t-key->bp-uuid conn "behaveplus:surface:output:fire_behavior:surface_fire:direction_mode:direction_of_interest")} + + {:ttype :group-variable + :operator :equal + :values #{"false"} + :group-variable-uuid (sm/t-key->bp-uuid conn "behaveplus:surface:output:fire_behavior:surface_fire:direction_mode:heading_backing_flanking")} + + {:ttype :group-variable + :operator :equal + :values #{"false"} + :group-variable-uuid (sm/t-key->bp-uuid conn "behaveplus:surface:output:fire_behavior:surface_fire:direction_mode:heading") + :sub-conditional-operator :or + :sub-conditionals [(t-key->conditional conn "behaveplus:surface:output:fire_behavior:surface_fire:rate_of_spread") + (t-key->conditional conn "behaveplus:surface:output:fire_behavior:surface_fire:fireline_intensity") + (t-key->conditional conn "behaveplus:surface:output:fire_behavior:surface_fire:flame_length") + (t-key->conditional conn "behaveplus:surface:output:size:surface___fire_size:fire_perimeter") + (t-key->conditional conn "behaveplus:surface:output:size:surface___fire_size:fire_area") + (t-key->conditional conn "behaveplus:surface:output:size:surface___fire_size:length-to-width-ratio") + (t-key->conditional conn "behaveplus:surface:output:size:surface___fire_size:spread-distance")]}]})]}]) + +;; =========================================================================================================== +;; Transact Payload +;; =========================================================================================================== + +(comment + #_{:clj-kondo/ignore [:missing-docstring]} + (try (def tx-data @(d/transact conn payload)) + (catch Exception e (str "caught exception: " (.getMessage e))))) + +;; =========================================================================================================== +;; In case we need to rollback. +;; =========================================================================================================== + +(comment + (sm/rollback-tx! conn tx-data)) diff --git a/projects/behave_cms/src/cljc/behave_cms/queries.cljc b/projects/behave_cms/src/cljc/behave_cms/queries.cljc index f5bea8a2a..18cdacbfa 100644 --- a/projects/behave_cms/src/cljc/behave_cms/queries.cljc +++ b/projects/behave_cms/src/cljc/behave_cms/queries.cljc @@ -1,7 +1,7 @@ (ns behave-cms.queries - (:require [clojure.string :as str] + (:require [clojure.string :as str] #?(:cljs [datascript.core :as d] - :clj [datahike.api :as d]))) + :clj [datahike.api :as d]))) (def rules '[[(module ?a ?m) [?e :application/modules ?m]] @@ -51,4 +51,12 @@ [(app-root ?a ?s) [?m :module/submodules ?s] + [?a :application/modules ?m]] + + ;; Find app root from an action entity + [(app-root ?a ?action) + [?gv :group-variable/actions ?action] + [?g :group/group-variables ?gv] + [?sm :submodule/groups ?g] + [?m :module/submodules ?sm] [?a :application/modules ?m]]]) diff --git a/projects/behave_cms/src/cljs/behave_cms/components/conditionals/subs.cljs b/projects/behave_cms/src/cljs/behave_cms/components/conditionals/subs.cljs index c5f046556..d93693fbf 100644 --- a/projects/behave_cms/src/cljs/behave_cms/components/conditionals/subs.cljs +++ b/projects/behave_cms/src/cljs/behave_cms/components/conditionals/subs.cljs @@ -1,7 +1,7 @@ (ns behave-cms.components.conditionals.subs - (:require [re-frame.core :refer [reg-sub subscribe]] - [datascript.core :as d] - [behave-cms.store :refer [conn]])) + (:require [re-frame.core :refer [reg-sub subscribe]] + [datascript.core :as d] + [behave-cms.store :refer [conn]])) (reg-sub :conditionals/all-conditionals @@ -21,7 +21,7 @@ module-conditionals (d/q '[:find ?c :in $ ?g ?conditional-attr :where - [?g ?conditionals-attr ?c] + [?g ?conditional-attr ?c] [?c :conditional/type :module]] @@conn eid diff --git a/projects/behave_cms/src/cljs/behave_cms/components/conditionals/views.cljs b/projects/behave_cms/src/cljs/behave_cms/components/conditionals/views.cljs index c5298bc89..051234735 100644 --- a/projects/behave_cms/src/cljs/behave_cms/components/conditionals/views.cljs +++ b/projects/behave_cms/src/cljs/behave_cms/components/conditionals/views.cljs @@ -11,7 +11,7 @@ ;;; Helpers (defn- clear-editor [] - (rf/dispatch [:state/set-state :editors {}])) + (rf/dispatch [:state/update [:editors :conditional] (fn [] nil)])) (defn- clear-show-sub-conditional-editor [] (rf/dispatch [:state/set-state :show-sub-conditional-editor {}])) @@ -138,8 +138,11 @@ (set-field (conj cond-path :conditional/values) nil) (set-field (conj cond-path :conditional/group-variable-uuid) (u/input-value %))) - :options (map (fn [{value :bp/uuid label :variable/name}] - {:value value :label label}) @variables)}] + :options (map (fn [{value :bp/uuid label :variable/name direction :group-variable/direction}] + {:value value + :label (if direction + (str label " (" (name direction) ")") + label)}) @variables)}] [dropdown {:label "Operator:" @@ -298,16 +301,20 @@ gv-id @(rf/subscribe [:bp/lookup gv-uuid]) [module-id] @(rf/subscribe [:group-variable/module-submodule-group gv-id]) module-name @(rf/subscribe [:entity-attr module-id :module/name]) + direction @(rf/subscribe [:entity-attr gv-id :group-variable/direction]) v-name (if (= conditional-type :module) "Module" - @(rf/subscribe [:gv-uuid->variable-name gv-uuid]))] + (let [n @(rf/subscribe [:gv-uuid->variable-name gv-uuid])] + (if direction + (str n " (" (name direction) ")") + n)))] [:div.conditionals-graph__node (when (seq sub-conditionals) [:div.conditionals-graph__operator [:div.edge] [dropdown {:selected "and" - :disabled? true + :disabled? false :options [{:value "and" :label "AND"}]}] [:div.edge]]) [:div {:class ["conditionals-graph__node__group" @@ -351,6 +358,6 @@ [conditionals-graph parent-eid conditional-eid - cond-attr + :conditional/sub-conditionals :conditional/sub-conditional-operator]])]])) (sort-by :variable/name conditionals)))]])))) diff --git a/projects/behave_cms/src/cljs/behave_cms/components/entity_form.cljs b/projects/behave_cms/src/cljs/behave_cms/components/entity_form.cljs index dcfb8cb90..1c66d6f1f 100644 --- a/projects/behave_cms/src/cljs/behave_cms/components/entity_form.cljs +++ b/projects/behave_cms/src/cljs/behave_cms/components/entity_form.cljs @@ -1,5 +1,6 @@ (ns behave-cms.components.entity-form (:require [behave-cms.components.common :refer [dropdown btn-sm]] + [behave-cms.components.conditionals.views :refer [conditionals-graph manage-conditionals]] [behave-cms.components.group-variable-selector :refer [group-variable-selector]] [behave-cms.components.translations :refer [all-translations]] [behave-cms.utils :as u] @@ -371,6 +372,18 @@ [:div.my-3 [all-translations @state]])) +(defmethod field-input :conditionals + [{:keys [label field-key cond-op-attr original]}] + (let [entity-id (:db/id original)] + (when entity-id + [:div.mb-3 + (when label [:label.form-label label]) + [:div.row + [:div.col-9 + [conditionals-graph entity-id entity-id field-key cond-op-attr]] + [:div.col-3 + [manage-conditionals entity-id field-key]]]]))) + ;;; Public Fns (defn entity-form diff --git a/projects/behave_cms/src/cljs/behave_cms/components/table_entity_form.cljs b/projects/behave_cms/src/cljs/behave_cms/components/table_entity_form.cljs index 0c0713197..f33042027 100644 --- a/projects/behave_cms/src/cljs/behave_cms/components/table_entity_form.cljs +++ b/projects/behave_cms/src/cljs/behave_cms/components/table_entity_form.cljs @@ -60,15 +60,19 @@ maps. When an existing entity is selected, renders an [all-translations] table for each attr that has a non-nil value on the entity. + `form-below?` - (optional) when true, renders the entity-form below the table instead + of to the right. Defaults to false. + " - [{:keys [title entity entities table-header-attrs entity-form-fields parent-id parent-field order-attr form-state-path on-select translation-config translation-attrs modify?] + [{:keys [title entity entities table-header-attrs entity-form-fields parent-id parent-field order-attr form-state-path on-select translation-config translation-attrs modify? form-below?] :or {modify? true}}] (r/with-let [entity-id-atom (r/atom nil) show-entity-form? (r/atom false)] - [:div {:style {:display "flex" - :height "100%" - :padding "30px"}} - [:div {:style {:padding-right "10px" + [:div {:style {:display "flex" + :flex-direction (if form-below? "column" "row") + :height "100%" + :padding "30px"}} + [:div {:style {:padding-right (when-not form-below? "10px") :width "100%"}} [simple-table (if (seq table-header-attrs) diff --git a/projects/behave_cms/src/cljs/behave_cms/group_variables/views.cljs b/projects/behave_cms/src/cljs/behave_cms/group_variables/views.cljs index b6cdc6c0f..ec6161e5f 100644 --- a/projects/behave_cms/src/cljs/behave_cms/group_variables/views.cljs +++ b/projects/behave_cms/src/cljs/behave_cms/group_variables/views.cljs @@ -1,18 +1,18 @@ (ns behave-cms.group-variables.views - (:require [re-frame.core :as rf] - [behave-cms.components.common :refer [accordion + (:require [behave-cms.components.common :refer [accordion checkbox dropdown simple-table window]] - [behave-cms.components.actions :refer [actions-table manage-action]] - [behave-cms.components.conditionals.views :refer [conditionals-graph manage-conditionals]] + [behave-cms.components.conditionals.views :refer [conditionals-graph manage-conditionals]] [behave-cms.components.cpp-editor :refer [cpp-editor-form]] + [behave-cms.components.group-variable-selector :refer [group-variable-selector]] [behave-cms.components.sidebar :refer [sidebar sidebar-width]] + [behave-cms.components.table-entity-form :refer [table-entity-form table-entity-form-on-select]] [behave-cms.components.translations :refer [all-translations]] [behave-cms.help.views :refer [help-editor]] [behave-cms.utils :as u] - [behave-cms.components.group-variable-selector :refer [group-variable-selector]])) + [re-frame.core :as rf])) ;;; Constants @@ -103,7 +103,7 @@ gv-id (:db/id @group-variable) is-output? (rf/subscribe [:group-variable/output? gv-id]) actions (:group-variable/actions @group-variable) - action-id (rf/subscribe [:state :action]) + action-id (rf/subscribe [:editors :action]) group (:group/_group-variables @group-variable) variable (get-in @group-variable [:variable/_group-variables 0]) group-variables (rf/subscribe [:sidebar/variables (:db/id group)]) @@ -166,11 +166,30 @@ "Actions" [:div.row [:div.col-12 - [actions-table actions]]] - [:div.row - [:div.col-12 - [manage-action [:bp/nid nid] @action-id @is-output?]]]] - + [table-entity-form + {:entity :action + :form-state-path [:editors :action] + :entities (sort-by :action/name actions) + :on-select (table-entity-form-on-select [:editors :action]) + :parent-id gv-id + :parent-field :group-variable/_actions + :table-header-attrs [:action/name] + :form-below? true + :entity-form-fields [{:label "Name" + :required? true + :field-key :action/name} + + {:label "Action Type" + :required? true + :type :radio + :field-key :action/type + :options [{:label "Select" :value :select} + {:label "Disable" :value :disable}]} + + {:label "Conditionals" + :type :conditionals + :field-key :action/conditionals + :cond-op-attr :action/conditionals-operator}]}]]]] [:hr] [accordion "Hide from Results Conditionals" From c95cbb735ffa99125629caa448375cf73538d5ea Mon Sep 17 00:00:00 2001 From: Kenneth Cheung Date: Thu, 26 Mar 2026 14:20:13 -0400 Subject: [PATCH 2/2] revert disable --- .../src/cljs/behave_cms/components/conditionals/views.cljs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/behave_cms/src/cljs/behave_cms/components/conditionals/views.cljs b/projects/behave_cms/src/cljs/behave_cms/components/conditionals/views.cljs index 051234735..141a85246 100644 --- a/projects/behave_cms/src/cljs/behave_cms/components/conditionals/views.cljs +++ b/projects/behave_cms/src/cljs/behave_cms/components/conditionals/views.cljs @@ -314,7 +314,7 @@ [:div.edge] [dropdown {:selected "and" - :disabled? false + :disabled? true :options [{:value "and" :label "AND"}]}] [:div.edge]]) [:div {:class ["conditionals-graph__node__group"