@bigbinary/neeto-rules-frontend 2.7.22 → 2.7.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/app/javascript/src/translations/en.json +1 -0
  2. package/dist/.ready +1 -1
  3. package/dist/NeetoRulesBuilder.js +2 -2
  4. package/dist/NeetoRulesForm.js +2 -2
  5. package/dist/cjs/NeetoRulesBuilder.js +2 -2
  6. package/dist/cjs/NeetoRulesForm.js +2 -2
  7. package/dist/cjs/index.js +2 -2
  8. package/dist/cjs/v2/NeetoRulesBuilder.js +343 -170
  9. package/dist/cjs/v2/NeetoRulesBuilder.js.map +1 -1
  10. package/dist/cjs/v2/NeetoRulesForm.js +2 -2
  11. package/dist/cjs/v2/index.js +3 -2
  12. package/dist/cjs/v2/index.js.map +1 -1
  13. package/dist/{index-49edM85x.js → index-25TjDISc.js} +2 -2
  14. package/dist/{index-49edM85x.js.map → index-25TjDISc.js.map} +1 -1
  15. package/dist/{index-CcbW7H2S.js → index-CvpoP63h.js} +3 -3
  16. package/dist/{index-CcbW7H2S.js.map → index-CvpoP63h.js.map} +1 -1
  17. package/dist/{index-BZYwFjcS.js → index-D76EZ1AZ.js} +2 -2
  18. package/dist/{index-BZYwFjcS.js.map → index-D76EZ1AZ.js.map} +1 -1
  19. package/dist/{index-Fukq1VSN.js → index-puRtNWZV.js} +3 -2
  20. package/dist/{index-Fukq1VSN.js.map → index-puRtNWZV.js.map} +1 -1
  21. package/dist/index.js +2 -2
  22. package/dist/keyboardShortcuts-CRInJJOU.js +96 -0
  23. package/dist/{keyboardShortcuts-DtnjcivY.js.map → keyboardShortcuts-CRInJJOU.js.map} +1 -1
  24. package/dist/keyboardShortcuts-DwgF8Mcu.js +92 -0
  25. package/dist/{keyboardShortcuts-_OrtgF0A.js.map → keyboardShortcuts-DwgF8Mcu.js.map} +1 -1
  26. package/dist/v2/NeetoRulesBuilder.js +350 -177
  27. package/dist/v2/NeetoRulesBuilder.js.map +1 -1
  28. package/dist/v2/NeetoRulesForm.js +2 -2
  29. package/dist/v2/index.js +3 -2
  30. package/dist/v2/index.js.map +1 -1
  31. package/package.json +3 -3
  32. package/dist/keyboardShortcuts-DtnjcivY.js +0 -96
  33. package/dist/keyboardShortcuts-_OrtgF0A.js +0 -92
@@ -2,7 +2,7 @@
2
2
 
3
3
  var _defineProperty = require('@babel/runtime/helpers/defineProperty');
4
4
  var _objectDestructuringEmpty = require('@babel/runtime/helpers/objectDestructuringEmpty');
5
- var keyboardShortcuts = require('../../keyboardShortcuts-DtnjcivY.js');
5
+ var keyboardShortcuts = require('../../keyboardShortcuts-CRInJJOU.js');
6
6
  var shallow = require('zustand/shallow');
7
7
  var react = require('react');
8
8
  var neetoAtoms = require('@bigbinary/neeto-atoms');
@@ -13,7 +13,7 @@ var neetoCist = require('@bigbinary/neeto-cist');
13
13
  var Container = require('@bigbinary/neeto-molecules/v2/Container');
14
14
  var Header = require('@bigbinary/neeto-molecules/v2/Header');
15
15
  var reactI18next = require('react-i18next');
16
- var index = require('../../index-Fukq1VSN.js');
16
+ var index = require('../../index-puRtNWZV.js');
17
17
  var useCustomDataStore = require('../../useCustomDataStore-DPmWkEhs.js');
18
18
  var useUtilityStore = require('../../useUtilityStore-gtPhFvpI.js');
19
19
  var _toConsumableArray = require('@babel/runtime/helpers/toConsumableArray');
@@ -32,6 +32,7 @@ var utils = require('@bigbinary/neeto-commons-frontend/v2/utils');
32
32
  var utils$1 = require('../../utils-B3roKiff.js');
33
33
  var Up = require('@bigbinary/neeto-icons/Up');
34
34
  var Down = require('@bigbinary/neeto-icons/Down');
35
+ var Info = require('@bigbinary/neeto-icons/Info');
35
36
  require('@babel/runtime/helpers/typeof');
36
37
  require('../../useAutomationRulesApi-C1T2E1AN.js');
37
38
  require('@tanstack/react-query');
@@ -504,31 +505,54 @@ var hasAction = function hasAction(rule) {
504
505
  return action === null || action === void 0 ? void 0 : action.name;
505
506
  });
506
507
  };
507
- var isRuleComplete = function isRuleComplete(rule) {
508
- return hasTrigger(rule) && hasAction(rule);
508
+ var isTriggerEnabled = function isTriggerEnabled(schema) {
509
+ var _schema$triggers2;
510
+ return (schema === null || schema === void 0 || (_schema$triggers2 = schema.triggers) === null || _schema$triggers2 === void 0 ? void 0 : _schema$triggers2.enabled) !== false;
511
+ };
512
+ var isTriggerSatisfied = function isTriggerSatisfied(_ref14) {
513
+ var rule = _ref14.rule,
514
+ schema = _ref14.schema;
515
+ return !isTriggerEnabled(schema) || hasTrigger(rule);
516
+ };
517
+ var hasRequiredConditions = function hasRequiredConditions(_ref15) {
518
+ var _schema$conditions5;
519
+ var rule = _ref15.rule,
520
+ schema = _ref15.schema;
521
+ return (schema === null || schema === void 0 || (_schema$conditions5 = schema.conditions) === null || _schema$conditions5 === void 0 ? void 0 : _schema$conditions5.allowEmpty) === false ? neetoCist.isNotEmpty((rule === null || rule === void 0 ? void 0 : rule.conditions) || []) : true;
522
+ };
523
+ var isRuleComplete = function isRuleComplete(_ref16) {
524
+ var rule = _ref16.rule,
525
+ schema = _ref16.schema;
526
+ return isTriggerSatisfied({
527
+ rule: rule,
528
+ schema: schema
529
+ }) && hasRequiredConditions({
530
+ rule: rule,
531
+ schema: schema
532
+ }) && hasAction(rule);
509
533
  };
510
- var scopeOptionFor = function scopeOptionFor(_ref14) {
534
+ var scopeOptionFor = function scopeOptionFor(_ref17) {
511
535
  var _item$value, _schema$scope;
512
- var schema = _ref14.schema,
513
- item = _ref14.item;
536
+ var schema = _ref17.schema,
537
+ item = _ref17.item;
514
538
  var value = (_item$value = item === null || item === void 0 ? void 0 : item.value) !== null && _item$value !== void 0 ? _item$value : item;
515
539
  return ((schema === null || schema === void 0 || (_schema$scope = schema.scope) === null || _schema$scope === void 0 ? void 0 : _schema$scope.options) || []).find(function (candidate) {
516
540
  var _candidate$value2;
517
541
  return ((_candidate$value2 = candidate.value) !== null && _candidate$value2 !== void 0 ? _candidate$value2 : candidate.id) === value;
518
542
  });
519
543
  };
520
- var scopePhoneFields = function scopePhoneFields(_ref15) {
521
- var _ref16, _item$phoneFields, _scopeOptionFor;
522
- var schema = _ref15.schema,
523
- item = _ref15.item;
524
- return (_ref16 = (_item$phoneFields = item === null || item === void 0 ? void 0 : item.phoneFields) !== null && _item$phoneFields !== void 0 ? _item$phoneFields : (_scopeOptionFor = scopeOptionFor({
544
+ var scopePhoneFields = function scopePhoneFields(_ref18) {
545
+ var _ref19, _item$phoneFields, _scopeOptionFor;
546
+ var schema = _ref18.schema,
547
+ item = _ref18.item;
548
+ return (_ref19 = (_item$phoneFields = item === null || item === void 0 ? void 0 : item.phoneFields) !== null && _item$phoneFields !== void 0 ? _item$phoneFields : (_scopeOptionFor = scopeOptionFor({
525
549
  schema: schema,
526
550
  item: item
527
- })) === null || _scopeOptionFor === void 0 ? void 0 : _scopeOptionFor.phoneFields) !== null && _ref16 !== void 0 ? _ref16 : null;
551
+ })) === null || _scopeOptionFor === void 0 ? void 0 : _scopeOptionFor.phoneFields) !== null && _ref19 !== void 0 ? _ref19 : null;
528
552
  };
529
- var effectiveScopePhoneField = function effectiveScopePhoneField(_ref17) {
530
- var schema = _ref17.schema,
531
- item = _ref17.item;
553
+ var effectiveScopePhoneField = function effectiveScopePhoneField(_ref20) {
554
+ var schema = _ref20.schema,
555
+ item = _ref20.item;
532
556
  if (item !== null && item !== void 0 && item.phoneField) return item.phoneField;
533
557
  var phoneFields = scopePhoneFields({
534
558
  schema: schema,
@@ -536,14 +560,14 @@ var effectiveScopePhoneField = function effectiveScopePhoneField(_ref17) {
536
560
  });
537
561
  return (phoneFields === null || phoneFields === void 0 ? void 0 : phoneFields.length) === 1 ? phoneFields[0].value : undefined;
538
562
  };
539
- var invalidScopeIndexes = function invalidScopeIndexes(_ref18) {
563
+ var invalidScopeIndexes = function invalidScopeIndexes(_ref21) {
540
564
  var _scope$requiresPhone;
541
- var rule = _ref18.rule,
542
- schema = _ref18.schema;
565
+ var rule = _ref21.rule,
566
+ schema = _ref21.schema;
543
567
  var scope = schema === null || schema === void 0 ? void 0 : schema.scope;
544
568
  if (!(scope !== null && scope !== void 0 && scope.enabled) || !((_scope$requiresPhone = scope.requiresPhone) !== null && _scope$requiresPhone !== void 0 && _scope$requiresPhone.call(scope, (rule === null || rule === void 0 ? void 0 : rule.actions) || []))) return [];
545
569
  return ((rule === null || rule === void 0 ? void 0 : rule.scope) || []).reduce(function (indexes, item, index) {
546
- var _ref19, _item$hasPhoneField;
570
+ var _ref22, _item$hasPhoneField;
547
571
  var option = scopeOptionFor({
548
572
  schema: schema,
549
573
  item: item
@@ -552,15 +576,15 @@ var invalidScopeIndexes = function invalidScopeIndexes(_ref18) {
552
576
  schema: schema,
553
577
  item: item
554
578
  });
555
- var hasPhoneField = (_ref19 = (_item$hasPhoneField = item === null || item === void 0 ? void 0 : item.hasPhoneField) !== null && _item$hasPhoneField !== void 0 ? _item$hasPhoneField : option === null || option === void 0 ? void 0 : option.hasPhoneField) !== null && _ref19 !== void 0 ? _ref19 : phoneFields ? phoneFields.length > 0 : undefined;
579
+ var hasPhoneField = (_ref22 = (_item$hasPhoneField = item === null || item === void 0 ? void 0 : item.hasPhoneField) !== null && _item$hasPhoneField !== void 0 ? _item$hasPhoneField : option === null || option === void 0 ? void 0 : option.hasPhoneField) !== null && _ref22 !== void 0 ? _ref22 : phoneFields ? phoneFields.length > 0 : undefined;
556
580
  if (hasPhoneField === false) indexes.push(index);
557
581
  return indexes;
558
582
  }, []);
559
583
  };
560
- var invalidScopePhoneFieldIndexes = function invalidScopePhoneFieldIndexes(_ref20) {
584
+ var invalidScopePhoneFieldIndexes = function invalidScopePhoneFieldIndexes(_ref23) {
561
585
  var _scope$requiresPhone2;
562
- var rule = _ref20.rule,
563
- schema = _ref20.schema;
586
+ var rule = _ref23.rule,
587
+ schema = _ref23.schema;
564
588
  var scope = schema === null || schema === void 0 ? void 0 : schema.scope;
565
589
  if (!(scope !== null && scope !== void 0 && scope.enabled) || !((_scope$requiresPhone2 = scope.requiresPhone) !== null && _scope$requiresPhone2 !== void 0 && _scope$requiresPhone2.call(scope, (rule === null || rule === void 0 ? void 0 : rule.actions) || []))) return [];
566
590
  return ((rule === null || rule === void 0 ? void 0 : rule.scope) || []).reduce(function (indexes, item, index) {
@@ -597,9 +621,9 @@ var minutesToParts = function minutesToParts(minutes) {
597
621
  unit: "minutes"
598
622
  };
599
623
  };
600
- var partsToMinutes = function partsToMinutes(_ref21) {
601
- var value = _ref21.value,
602
- unit = _ref21.unit;
624
+ var partsToMinutes = function partsToMinutes(_ref24) {
625
+ var value = _ref24.value,
626
+ unit = _ref24.unit;
603
627
  return (
604
628
  // eslint-disable-next-line security/detect-object-injection
605
629
  (Number(value) || 0) * (UNIT_MINUTES[unit] || 1)
@@ -609,8 +633,8 @@ var leadTimeExceedsMax = function leadTimeExceedsMax(minutes) {
609
633
  return minutesToParts(minutes).value > MAX_LEAD_TIME_VALUE;
610
634
  };
611
635
  var leadTimeValidationSchema = function leadTimeValidationSchema(schema) {
612
- var _schema$triggers2;
613
- var fieldKey = schema === null || schema === void 0 || (_schema$triggers2 = schema.triggers) === null || _schema$triggers2 === void 0 || (_schema$triggers2 = _schema$triggers2.leadTime) === null || _schema$triggers2 === void 0 ? void 0 : _schema$triggers2.fieldKey;
636
+ var _schema$triggers3;
637
+ var fieldKey = schema === null || schema === void 0 || (_schema$triggers3 = schema.triggers) === null || _schema$triggers3 === void 0 || (_schema$triggers3 = _schema$triggers3.leadTime) === null || _schema$triggers3 === void 0 ? void 0 : _schema$triggers3.fieldKey;
614
638
  if (!fieldKey) return yup__namespace.object();
615
639
  return yup__namespace.object().shape(_defineProperty({}, fieldKey, yup__namespace.object().shape({
616
640
  // yup 0.32 can only concat schemas of the same type, and the host's
@@ -654,25 +678,25 @@ var modeFromJoinType = function modeFromJoinType(joinType) {
654
678
  };
655
679
 
656
680
  // eslint-disable-next-line security/detect-object-injection
657
- var valueAt = function valueAt(_ref22) {
681
+ var valueAt = function valueAt(_ref25) {
658
682
  var _values$key;
659
- var values = _ref22.values,
660
- key = _ref22.key;
683
+ var values = _ref25.values,
684
+ key = _ref25.key;
661
685
  return values === null || values === void 0 || (_values$key = values[key]) === null || _values$key === void 0 ? void 0 : _values$key.value;
662
686
  };
663
687
  var asArray = function asArray(maybeArray) {
664
688
  return Array.isArray(maybeArray) ? maybeArray : [];
665
689
  };
666
690
  var fieldKeysFromSchema = function fieldKeysFromSchema() {
667
- var _schema$triggers3, _schema$actor2, _schema$conditions5, _schema$actions3, _schema$delay, _schema$triggers4, _schema$scope2;
691
+ var _schema$triggers4, _schema$actor2, _schema$conditions6, _schema$actions3, _schema$delay, _schema$triggers5, _schema$scope2;
668
692
  var schema = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
669
693
  return {
670
- triggers: ((_schema$triggers3 = schema.triggers) === null || _schema$triggers3 === void 0 ? void 0 : _schema$triggers3.fieldKey) || "events",
694
+ triggers: ((_schema$triggers4 = schema.triggers) === null || _schema$triggers4 === void 0 ? void 0 : _schema$triggers4.fieldKey) || "events",
671
695
  performer: ((_schema$actor2 = schema.actor) === null || _schema$actor2 === void 0 ? void 0 : _schema$actor2.fieldKey) || "performer",
672
- conditions: ((_schema$conditions5 = schema.conditions) === null || _schema$conditions5 === void 0 ? void 0 : _schema$conditions5.fieldKey) || "conditions",
696
+ conditions: ((_schema$conditions6 = schema.conditions) === null || _schema$conditions6 === void 0 ? void 0 : _schema$conditions6.fieldKey) || "conditions",
673
697
  actions: ((_schema$actions3 = schema.actions) === null || _schema$actions3 === void 0 ? void 0 : _schema$actions3.fieldKey) || "actions",
674
698
  delay: ((_schema$delay = schema.delay) === null || _schema$delay === void 0 ? void 0 : _schema$delay.fieldKey) || "execution_delay",
675
- leadTime: (_schema$triggers4 = schema.triggers) === null || _schema$triggers4 === void 0 || (_schema$triggers4 = _schema$triggers4.leadTime) === null || _schema$triggers4 === void 0 ? void 0 : _schema$triggers4.fieldKey,
699
+ leadTime: (_schema$triggers5 = schema.triggers) === null || _schema$triggers5 === void 0 || (_schema$triggers5 = _schema$triggers5.leadTime) === null || _schema$triggers5 === void 0 ? void 0 : _schema$triggers5.fieldKey,
676
700
  scope: ((_schema$scope2 = schema.scope) === null || _schema$scope2 === void 0 ? void 0 : _schema$scope2.fieldKey) || "meetingIds",
677
701
  status: "status",
678
702
  name: "name"
@@ -680,11 +704,11 @@ var fieldKeysFromSchema = function fieldKeysFromSchema() {
680
704
  };
681
705
  var valuesToRuleModel = function valuesToRuleModel() {
682
706
  var _valueAt, _conditions$;
683
- var _ref23 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
684
- _ref23$values = _ref23.values,
685
- values = _ref23$values === void 0 ? {} : _ref23$values,
686
- _ref23$schema = _ref23.schema,
687
- schema = _ref23$schema === void 0 ? {} : _ref23$schema;
707
+ var _ref26 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
708
+ _ref26$values = _ref26.values,
709
+ values = _ref26$values === void 0 ? {} : _ref26$values,
710
+ _ref26$schema = _ref26.schema,
711
+ schema = _ref26$schema === void 0 ? {} : _ref26$schema;
688
712
  var keys = fieldKeysFromSchema(schema);
689
713
  var conditions = asArray(valueAt({
690
714
  values: values,
@@ -728,42 +752,42 @@ var valuesToRuleModel = function valuesToRuleModel() {
728
752
  }))
729
753
  };
730
754
  };
731
- var setTriggers = function setTriggers(_ref24) {
732
- var schema = _ref24.schema,
733
- triggers = _ref24.triggers;
755
+ var setTriggers = function setTriggers(_ref27) {
756
+ var schema = _ref27.schema,
757
+ triggers = _ref27.triggers;
734
758
  return {
735
759
  path: "".concat(fieldKeysFromSchema(schema).triggers, ".value"),
736
760
  value: triggers
737
761
  };
738
762
  };
739
- var setPerformer = function setPerformer(_ref25) {
740
- var schema = _ref25.schema,
741
- performer = _ref25.performer;
763
+ var setPerformer = function setPerformer(_ref28) {
764
+ var schema = _ref28.schema,
765
+ performer = _ref28.performer;
742
766
  return {
743
767
  path: "".concat(fieldKeysFromSchema(schema).performer, ".value"),
744
768
  value: performer
745
769
  };
746
770
  };
747
- var setActions = function setActions(_ref26) {
748
- var schema = _ref26.schema,
749
- actions = _ref26.actions;
771
+ var setActions = function setActions(_ref29) {
772
+ var schema = _ref29.schema,
773
+ actions = _ref29.actions;
750
774
  return {
751
775
  path: "".concat(fieldKeysFromSchema(schema).actions, ".value"),
752
776
  value: actions
753
777
  };
754
778
  };
755
- var setConditions = function setConditions(_ref27) {
756
- var schema = _ref27.schema,
757
- conditions = _ref27.conditions;
779
+ var setConditions = function setConditions(_ref30) {
780
+ var schema = _ref30.schema,
781
+ conditions = _ref30.conditions;
758
782
  return {
759
783
  path: "".concat(fieldKeysFromSchema(schema).conditions, ".value"),
760
784
  value: conditions
761
785
  };
762
786
  };
763
- var setConditionMode = function setConditionMode(_ref28) {
764
- var schema = _ref28.schema,
765
- conditions = _ref28.conditions,
766
- joinType = _ref28.joinType;
787
+ var setConditionMode = function setConditionMode(_ref31) {
788
+ var schema = _ref31.schema,
789
+ conditions = _ref31.conditions,
790
+ joinType = _ref31.joinType;
767
791
  return setConditions({
768
792
  schema: schema,
769
793
  conditions: conditions.map(function (condition) {
@@ -771,34 +795,34 @@ var setConditionMode = function setConditionMode(_ref28) {
771
795
  })
772
796
  });
773
797
  };
774
- var setDelay = function setDelay(_ref29) {
775
- var schema = _ref29.schema,
776
- delay = _ref29.delay;
798
+ var setDelay = function setDelay(_ref32) {
799
+ var schema = _ref32.schema,
800
+ delay = _ref32.delay;
777
801
  return {
778
802
  path: "".concat(fieldKeysFromSchema(schema).delay, ".value"),
779
803
  value: delay !== null && delay !== void 0 ? delay : {}
780
804
  };
781
805
  };
782
- var setActive = function setActive(_ref30) {
783
- var schema = _ref30.schema,
784
- active = _ref30.active;
806
+ var setActive = function setActive(_ref33) {
807
+ var schema = _ref33.schema,
808
+ active = _ref33.active;
785
809
  return {
786
810
  path: "".concat(fieldKeysFromSchema(schema).status, ".value"),
787
811
  value: active ? STATUS_KEYS.ENABLED : STATUS_KEYS.DISABLED
788
812
  };
789
813
  };
790
- var setScope = function setScope(_ref31) {
791
- var schema = _ref31.schema,
792
- scope = _ref31.scope;
814
+ var setScope = function setScope(_ref34) {
815
+ var schema = _ref34.schema,
816
+ scope = _ref34.scope;
793
817
  return {
794
818
  path: "".concat(fieldKeysFromSchema(schema).scope, ".value"),
795
819
  value: scope
796
820
  };
797
821
  };
798
- var removeArrayItem = function removeArrayItem(_ref32) {
799
- var values = _ref32.values,
800
- fieldKey = _ref32.fieldKey,
801
- index = _ref32.index;
822
+ var removeArrayItem = function removeArrayItem(_ref35) {
823
+ var values = _ref35.values,
824
+ fieldKey = _ref35.fieldKey,
825
+ index = _ref35.index;
802
826
  var list = asArray(valueAt({
803
827
  values: values,
804
828
  key: fieldKey
@@ -825,9 +849,9 @@ var removeArrayItem = function removeArrayItem(_ref32) {
825
849
  }
826
850
  return result;
827
851
  };
828
- var clearArrayItems = function clearArrayItems(_ref33) {
829
- var values = _ref33.values,
830
- fieldKey = _ref33.fieldKey;
852
+ var clearArrayItems = function clearArrayItems(_ref36) {
853
+ var values = _ref36.values,
854
+ fieldKey = _ref36.fieldKey;
831
855
  var list = asArray(valueAt({
832
856
  values: values,
833
857
  key: fieldKey
@@ -903,13 +927,13 @@ var ConditionRow = function ConditionRow(_ref) {
903
927
  className: "mb-sentence",
904
928
  children: [isFirst ? /*#__PURE__*/jsxRuntime.jsx("span", {
905
929
  className: "mb-fixed",
906
- children: t("neetoRules.operators.and")
930
+ children: isTriggerEnabled(schema) ? t("neetoRules.operators.and") : t("neetoRules.common.when")
907
931
  }) : /*#__PURE__*/jsxRuntime.jsx(Token, {
908
932
  active: isActive({
909
933
  type: BUILDER_ANCHORS.COND_CONNECTOR,
910
934
  index: index
911
935
  }),
912
- className: "mb-tok-muted",
936
+ className: "mb-tok-connector",
913
937
  dataTestid: "cond-connector-".concat(index),
914
938
  onClick: handleToken && function () {
915
939
  return handleToken({
@@ -1132,8 +1156,8 @@ var MetaBlock = function MetaBlock(_ref) {
1132
1156
  className: "mb-meta-label",
1133
1157
  children: t("neetoRules.builder.automationName")
1134
1158
  }), /*#__PURE__*/jsxRuntime.jsxs("div", {
1135
- ref: nameRef,
1136
1159
  "data-testid": "rule-name-edit",
1160
+ ref: nameRef,
1137
1161
  role: handleEditName ? "button" : undefined,
1138
1162
  tabIndex: handleEditName ? 0 : undefined,
1139
1163
  className: classNames("mb-meta-input-wrap", {
@@ -1406,7 +1430,10 @@ var ActionRow = function ActionRow(_ref) {
1406
1430
  paramKind = _actionParts.paramKind,
1407
1431
  valueNoun = _actionParts.valueNoun,
1408
1432
  valueNounPlural = _actionParts.valueNounPlural;
1409
- var hasParamTail = paramKind === PARAM_KIND.ENUM_SINGLE || paramKind === PARAM_KIND.ENUM_MULTI;
1433
+
1434
+ // A separator-less action still needs a value slot when the host declares a
1435
+ // placeholder for it, otherwise its chosen value never reaches the canvas.
1436
+ var hasParamTail = paramKind === PARAM_KIND.ENUM_SINGLE || paramKind === PARAM_KIND.ENUM_MULTI || !!configValuePlaceholder || !!configValue;
1410
1437
  var multiPlaceholder = valueNounPlural ? t("neetoRules.builder.selectNoun", {
1411
1438
  noun: valueNounPlural
1412
1439
  }) : t("neetoRules.form.selectValues");
@@ -1424,12 +1451,66 @@ var ActionRow = function ActionRow(_ref) {
1424
1451
  index: index
1425
1452
  });
1426
1453
  var configLabel = mediumLabel || sentencify(option === null || option === void 0 ? void 0 : option.placeholder);
1454
+ // A host may declare two separators: the first introduces the recipient
1455
+ // ("whose email is"), the second the configured value ("with the following").
1456
+ var _ref2 = Array.isArray(separator) ? separator : [null, separator],
1457
+ _ref3 = _slicedToArray(_ref2, 2),
1458
+ recipientSeparator = _ref3[0],
1459
+ configSeparator = _ref3[1];
1427
1460
  var isConfigured = neetoCist.isNotEmpty(action === null || action === void 0 ? void 0 : action.metadata);
1428
1461
  // A host that shows no value label still needs the token to read as filled.
1429
1462
  var configState = configValue || isConfigured ? TOKEN_STATE.FILLED : TOKEN_STATE.MUTED;
1430
1463
  var _useClearingHover = useClearingHover(),
1431
1464
  clearing = _useClearingHover.clearing,
1432
1465
  clearingHoverProps = _useClearingHover.clearingHoverProps;
1466
+ var configToken = configSeparator ? /*#__PURE__*/jsxRuntime.jsxs(react.Fragment, {
1467
+ children: [/*#__PURE__*/jsxRuntime.jsx("span", {
1468
+ className: "mb-fixed",
1469
+ children: configSeparator
1470
+ }), /*#__PURE__*/jsxRuntime.jsx(Token, {
1471
+ active: isActive({
1472
+ type: BUILDER_ANCHORS.ACTION_CONFIG,
1473
+ index: index
1474
+ }),
1475
+ dataTestid: "action-config-value-".concat(index),
1476
+ state: configState,
1477
+ invalid: isInvalid({
1478
+ type: BUILDER_ANCHORS.ACTION_CONFIG,
1479
+ index: index
1480
+ }),
1481
+ onClick: handleToken && function () {
1482
+ return handleToken({
1483
+ type: BUILDER_ANCHORS.ACTION_CONFIG,
1484
+ index: index
1485
+ });
1486
+ },
1487
+ children: configValue || sentencify(configValuePlaceholder) || t("neetoRules.builder.selectFallback")
1488
+ })]
1489
+ }, "config") : null;
1490
+ var recipientToken = needsRecipient ? /*#__PURE__*/jsxRuntime.jsxs(react.Fragment, {
1491
+ children: [/*#__PURE__*/jsxRuntime.jsx("span", {
1492
+ className: "mb-fixed",
1493
+ children: recipientSeparator || t("neetoRules.common.to")
1494
+ }), /*#__PURE__*/jsxRuntime.jsx(Token, {
1495
+ dataTestid: "action-recipient-".concat(index),
1496
+ state: recipient ? TOKEN_STATE.FILLED : TOKEN_STATE.MUTED,
1497
+ active: isActive({
1498
+ type: BUILDER_ANCHORS.ACTION_RECIPIENT,
1499
+ index: index
1500
+ }),
1501
+ invalid: isInvalid({
1502
+ type: BUILDER_ANCHORS.ACTION_RECIPIENT,
1503
+ index: index
1504
+ }),
1505
+ onClick: handleToken && function () {
1506
+ return handleToken({
1507
+ type: BUILDER_ANCHORS.ACTION_RECIPIENT,
1508
+ index: index
1509
+ });
1510
+ },
1511
+ children: recipient ? String(recipientLabel).toLowerCase() : t("neetoRules.builder.selectRecipient")
1512
+ })]
1513
+ }, "recipient") : null;
1433
1514
  return /*#__PURE__*/jsxRuntime.jsxs("div", {
1434
1515
  className: classNames("mb-row mb-row-draggable", {
1435
1516
  clearing: clearing
@@ -1439,7 +1520,7 @@ var ActionRow = function ActionRow(_ref) {
1439
1520
  children: [/*#__PURE__*/jsxRuntime.jsx("span", {
1440
1521
  className: "mb-fixed",
1441
1522
  children: connector
1442
- }), separator ? /*#__PURE__*/jsxRuntime.jsxs(Token, {
1523
+ }), configSeparator ? /*#__PURE__*/jsxRuntime.jsxs(Token, {
1443
1524
  active: isVerbActive,
1444
1525
  className: "mb-tok-medium",
1445
1526
  dataTestid: "action-verb-".concat(index),
@@ -1480,7 +1561,7 @@ var ActionRow = function ActionRow(_ref) {
1480
1561
  index: index
1481
1562
  });
1482
1563
  },
1483
- children: configValue || paramPlaceholder
1564
+ children: configValue || sentencify(configValuePlaceholder) || paramPlaceholder
1484
1565
  }) : configLabel && /*#__PURE__*/jsxRuntime.jsxs(Token, {
1485
1566
  className: "mb-tok-medium",
1486
1567
  dataTestid: "action-config-".concat(index),
@@ -1503,53 +1584,7 @@ var ActionRow = function ActionRow(_ref) {
1503
1584
  size: 14
1504
1585
  }), configLabel]
1505
1586
  })]
1506
- }), separator && /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
1507
- children: [/*#__PURE__*/jsxRuntime.jsx("span", {
1508
- className: "mb-fixed",
1509
- children: separator
1510
- }), /*#__PURE__*/jsxRuntime.jsx(Token, {
1511
- active: isActive({
1512
- type: BUILDER_ANCHORS.ACTION_CONFIG,
1513
- index: index
1514
- }),
1515
- dataTestid: "action-config-value-".concat(index),
1516
- state: configState,
1517
- invalid: isInvalid({
1518
- type: BUILDER_ANCHORS.ACTION_CONFIG,
1519
- index: index
1520
- }),
1521
- onClick: handleToken && function () {
1522
- return handleToken({
1523
- type: BUILDER_ANCHORS.ACTION_CONFIG,
1524
- index: index
1525
- });
1526
- },
1527
- children: configValue || sentencify(configValuePlaceholder) || t("neetoRules.builder.selectFallback")
1528
- })]
1529
- }), needsRecipient && /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
1530
- children: [/*#__PURE__*/jsxRuntime.jsx("span", {
1531
- className: "mb-fixed",
1532
- children: t("neetoRules.common.to")
1533
- }), /*#__PURE__*/jsxRuntime.jsx(Token, {
1534
- dataTestid: "action-recipient-".concat(index),
1535
- state: recipient ? TOKEN_STATE.FILLED : TOKEN_STATE.MUTED,
1536
- active: isActive({
1537
- type: BUILDER_ANCHORS.ACTION_RECIPIENT,
1538
- index: index
1539
- }),
1540
- invalid: isInvalid({
1541
- type: BUILDER_ANCHORS.ACTION_RECIPIENT,
1542
- index: index
1543
- }),
1544
- onClick: handleToken && function () {
1545
- return handleToken({
1546
- type: BUILDER_ANCHORS.ACTION_RECIPIENT,
1547
- index: index
1548
- });
1549
- },
1550
- children: recipient ? String(recipientLabel).toLowerCase() : t("neetoRules.builder.selectRecipient")
1551
- })]
1552
- })]
1587
+ }), recipientSeparator ? [recipientToken, configToken] : [configToken, recipientToken]]
1553
1588
  }), /*#__PURE__*/jsxRuntime.jsxs("div", {
1554
1589
  className: "mb-row-actions",
1555
1590
  children: [handleAddAction && /*#__PURE__*/jsxRuntime.jsx(neetoAtoms.Button, {
@@ -1605,7 +1640,10 @@ var ThenBlock = function ThenBlock(_ref) {
1605
1640
  return (action === null || action === void 0 ? void 0 : action.channel) || (action === null || action === void 0 ? void 0 : action.name);
1606
1641
  });
1607
1642
  if (ramda.isEmpty(named)) {
1608
- var isTriggerSet = hasTrigger(rule);
1643
+ var isTriggerSet = isTriggerSatisfied({
1644
+ rule: rule,
1645
+ schema: schema
1646
+ });
1609
1647
  return /*#__PURE__*/jsxRuntime.jsx("div", {
1610
1648
  className: "mb-row",
1611
1649
  children: /*#__PURE__*/jsxRuntime.jsx("div", {
@@ -1697,6 +1735,21 @@ var WhenBlock = function WhenBlock(_ref) {
1697
1735
  var _schema$triggers;
1698
1736
  return ((schema === null || schema === void 0 || (_schema$triggers = schema.triggers) === null || _schema$triggers === void 0 || (_schema$triggers = _schema$triggers.leadTime) === null || _schema$triggers === void 0 ? void 0 : _schema$triggers.appliesTo) || []).includes(name);
1699
1737
  };
1738
+ if (!isTriggerEnabled(schema)) {
1739
+ if (!ramda.isEmpty(rule.conditions)) return null;
1740
+ return /*#__PURE__*/jsxRuntime.jsx("div", {
1741
+ className: "mb-row",
1742
+ children: /*#__PURE__*/jsxRuntime.jsx("div", {
1743
+ className: "mb-sentence",
1744
+ children: /*#__PURE__*/jsxRuntime.jsx(Token, {
1745
+ dataTestid: "condition-add",
1746
+ state: TOKEN_STATE.PLACEHOLDER_NEXT,
1747
+ onClick: handleAddCondition || undefined,
1748
+ children: t("neetoRules.builder.whenThisIsTrue")
1749
+ })
1750
+ })
1751
+ });
1752
+ }
1700
1753
  if (ramda.isEmpty(triggers)) {
1701
1754
  return /*#__PURE__*/jsxRuntime.jsx("div", {
1702
1755
  className: "mb-row",
@@ -2384,13 +2437,18 @@ var descriptorFor = function descriptorFor(_ref15) {
2384
2437
  subtitle: isSwap ? i18next.t("neetoRules.builder.panes.actionSwapSubtitle") : i18next.t("neetoRules.builder.panes.actionAddSubtitle"),
2385
2438
  cascade: true,
2386
2439
  options: sourceOptions.map(function (option) {
2440
+ var _option$disabled;
2387
2441
  var value = optionValue(option);
2388
2442
  var meta = channelMetaFor(value);
2389
2443
  return {
2390
2444
  label: isSwap ? meta.channelLabel || option.label : option.label,
2391
2445
  value: value,
2392
2446
  category: option.category,
2393
- disabled: !!option.disabled,
2447
+ // Hosts mark unavailable actions with isDisabled; without carrying
2448
+ // the reason across, the picker disables them with no explanation.
2449
+ disabled: !!((_option$disabled = option.disabled) !== null && _option$disabled !== void 0 ? _option$disabled : option.isDisabled),
2450
+ disabledReason: option.disabledReason,
2451
+ disabledPopover: option.disabledPopover,
2394
2452
  icon: (isSwap ? meta.icon : option.icon) || option.icon
2395
2453
  };
2396
2454
  }),
@@ -2438,7 +2496,10 @@ var descriptorFor = function descriptorFor(_ref15) {
2438
2496
  selectedValues: [recipientOf({
2439
2497
  schema: schema,
2440
2498
  action: action
2441
- })]
2499
+ })],
2500
+ // Confirming a recipient always offers Continue; whether that chains
2501
+ // onward or just closes is decided by continueTargetFor.
2502
+ cascade: true
2442
2503
  };
2443
2504
  }
2444
2505
  case BUILDER_ANCHORS.SCOPE:
@@ -2455,14 +2516,16 @@ var descriptorFor = function descriptorFor(_ref15) {
2455
2516
  subtitle: sc.paneSubtitle || i18next.t("neetoRules.builder.panes.scopeSubtitle"),
2456
2517
  multi: true,
2457
2518
  options: (sc.options || []).map(function (option) {
2519
+ var _option$disabled2;
2458
2520
  var value = optionValue(option);
2459
2521
  var blockedNoPhone = requiresPhone && option.hasPhoneField === false;
2460
2522
  var isSelected = selected.includes(value);
2461
2523
  return {
2462
2524
  label: option.label,
2463
2525
  value: value,
2464
- disabled: (!!option.disabled || blockedNoPhone) && !isSelected,
2465
- disabledReason: blockedNoPhone && sc.disabledReason,
2526
+ disabled: (!!((_option$disabled2 = option.disabled) !== null && _option$disabled2 !== void 0 ? _option$disabled2 : option.isDisabled) || blockedNoPhone) && !isSelected,
2527
+ disabledReason: blockedNoPhone ? sc.disabledReason : option.disabledReason,
2528
+ disabledPopover: option.disabledPopover,
2466
2529
  disabledTooltip: blockedNoPhone && sc.disabledTooltip
2467
2530
  };
2468
2531
  }),
@@ -2619,7 +2682,8 @@ var continueTargetFor = function continueTargetFor(_ref17) {
2619
2682
  var anchor = _ref17.anchor,
2620
2683
  schema = _ref17.schema,
2621
2684
  rule = _ref17.rule,
2622
- index = _ref17.index;
2685
+ index = _ref17.index,
2686
+ configPending = _ref17.configPending;
2623
2687
  switch (anchor) {
2624
2688
  case BUILDER_ANCHORS.TRIGGER_ADD:
2625
2689
  case BUILDER_ANCHORS.TRIGGER_REPLACE:
@@ -2675,6 +2739,9 @@ var continueTargetFor = function continueTargetFor(_ref17) {
2675
2739
  }
2676
2740
  };
2677
2741
  }
2742
+
2743
+ // Reached here only because the action has no config yet — its name is
2744
+ // still unresolved — so the recipient pane owes us that step afterwards.
2678
2745
  return channelMetaOf({
2679
2746
  schema: schema,
2680
2747
  action: action
@@ -2682,12 +2749,30 @@ var continueTargetFor = function continueTargetFor(_ref17) {
2682
2749
  type: BUILDER_PANEL_TYPES.RECIPIENT,
2683
2750
  data: {
2684
2751
  index: index,
2685
- anchor: BUILDER_ANCHORS.ACTION_RECIPIENT
2752
+ anchor: BUILDER_ANCHORS.ACTION_RECIPIENT,
2753
+ configPending: true
2686
2754
  }
2687
2755
  } : null;
2688
2756
  }
2689
2757
  case BUILDER_ANCHORS.ACTION_RECIPIENT:
2690
- return null;
2758
+ {
2759
+ // Only chain onward when config was skipped on the way in; arriving from
2760
+ // the config pane or from the token means this is the last step.
2761
+ var _action = actionAt({
2762
+ rule: rule,
2763
+ index: index
2764
+ });
2765
+ return configPending && actionHasConfig({
2766
+ schema: schema,
2767
+ action: _action
2768
+ }) ? {
2769
+ type: BUILDER_PANEL_TYPES.ACTION_CONFIG,
2770
+ data: {
2771
+ index: index,
2772
+ anchor: BUILDER_ANCHORS.ACTION_CONFIG
2773
+ }
2774
+ } : null;
2775
+ }
2691
2776
  default:
2692
2777
  return null;
2693
2778
  }
@@ -2803,7 +2888,7 @@ var applyPreview = function applyPreview(_ref19) {
2803
2888
  function ownKeys$3(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
2804
2889
  function _objectSpread$3(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$3(Object(t), true).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$3(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
2805
2890
  var Canvas = function Canvas(_ref) {
2806
- var _schema$scope, _schema$triggers, _schema$delay, _schema$meta$showName, _schema$meta;
2891
+ var _schema$actor2, _ref6, _actorOptions$0$value, _schema$scope, _schema$conditions, _schema$triggers, _schema$delay, _schema$meta$showName, _schema$meta;
2807
2892
  var schema = _ref.schema;
2808
2893
  var _useTranslation = reactI18next.useTranslation(),
2809
2894
  t = _useTranslation.t;
@@ -2858,7 +2943,10 @@ var Canvas = function Canvas(_ref) {
2858
2943
  react.useEffect(function () {
2859
2944
  if (submitCount <= lastSubmitCount.current) return undefined;
2860
2945
  lastSubmitCount.current = submitCount;
2861
- if (ramda.isEmpty(flatErrors) && isRuleComplete(rule) && ramda.isEmpty(invalidScopeIndexes({
2946
+ if (ramda.isEmpty(flatErrors) && isRuleComplete({
2947
+ rule: rule,
2948
+ schema: schema
2949
+ }) && ramda.isEmpty(invalidScopeIndexes({
2862
2950
  rule: rule,
2863
2951
  schema: schema
2864
2952
  })) && ramda.isEmpty(invalidScopePhoneFieldIndexes({
@@ -3022,7 +3110,15 @@ var Canvas = function Canvas(_ref) {
3022
3110
  });
3023
3111
  setDelay(null);
3024
3112
  };
3025
- var isTriggerSet = hasTrigger(rule);
3113
+
3114
+ // An actor with a single choice is not a choice; leaving it unset only makes
3115
+ // the user open a one-option pane to say the obvious.
3116
+ var actorOptions = schema !== null && schema !== void 0 && (_schema$actor2 = schema.actor) !== null && _schema$actor2 !== void 0 && _schema$actor2.enabled ? schema.actor.options || [] : [];
3117
+ var soleActorOption = actorOptions.length === 1 ? (_ref6 = (_actorOptions$0$value = actorOptions[0].value) !== null && _actorOptions$0$value !== void 0 ? _actorOptions$0$value : actorOptions[0].id) !== null && _ref6 !== void 0 ? _ref6 : actorOptions[0] : null;
3118
+ var isTriggerSet = isTriggerSatisfied({
3119
+ rule: rule,
3120
+ schema: schema
3121
+ });
3026
3122
  var hasAction = rule.actions.some(function (action) {
3027
3123
  return (action === null || action === void 0 ? void 0 : action.channel) || (action === null || action === void 0 ? void 0 : action.name);
3028
3124
  });
@@ -3041,11 +3137,16 @@ var Canvas = function Canvas(_ref) {
3041
3137
  rule: rule
3042
3138
  });
3043
3139
  var canAddCondition = neetoCist.isNotEmpty(conditionFields);
3140
+ var canRemoveCondition = (schema === null || schema === void 0 || (_schema$conditions = schema.conditions) === null || _schema$conditions === void 0 ? void 0 : _schema$conditions.allowEmpty) !== false || displayRule.conditions.length > 1;
3044
3141
  var leadTimeAppliesTo = (schema === null || schema === void 0 || (_schema$triggers = schema.triggers) === null || _schema$triggers === void 0 || (_schema$triggers = _schema$triggers.leadTime) === null || _schema$triggers === void 0 ? void 0 : _schema$triggers.appliesTo) || [];
3045
3142
  var hasLeadTimeTrigger = rule.triggers.some(function (trigger) {
3046
3143
  return leadTimeAppliesTo.includes(trigger.name);
3047
3144
  });
3048
3145
  var isDelayEnabled = (schema === null || schema === void 0 || (_schema$delay = schema.delay) === null || _schema$delay === void 0 ? void 0 : _schema$delay.enabled) && !hasLeadTimeTrigger;
3146
+ react.useEffect(function () {
3147
+ if (soleActorOption && !rule.performer) setPerformer(soleActorOption);
3148
+ // eslint-disable-next-line react-hooks/exhaustive-deps
3149
+ }, [soleActorOption, rule.performer]);
3049
3150
  react.useEffect(function () {
3050
3151
  if (hasLeadTimeTrigger && rule.delay) setDelay(null);
3051
3152
  // eslint-disable-next-line react-hooks/exhaustive-deps
@@ -3062,10 +3163,10 @@ var Canvas = function Canvas(_ref) {
3062
3163
  });
3063
3164
  };
3064
3165
  var handleClearTrigger = function handleClearTrigger() {
3065
- var _schema$actor2;
3166
+ var _schema$actor3;
3066
3167
  clearTriggers();
3067
3168
  // Hosts without an actor pane can never re-set it, and null fails its validation.
3068
- if ((_schema$actor2 = schema.actor) !== null && _schema$actor2 !== void 0 && _schema$actor2.enabled) setPerformer(null);
3169
+ if ((_schema$actor3 = schema.actor) !== null && _schema$actor3 !== void 0 && _schema$actor3.enabled) setPerformer(soleActorOption);
3069
3170
  clearConditions();
3070
3171
  setDelay(null);
3071
3172
  clearActions();
@@ -3093,7 +3194,7 @@ var Canvas = function Canvas(_ref) {
3093
3194
  className: "neeto-rules-builder nrb-atoms",
3094
3195
  children: /*#__PURE__*/jsxRuntime.jsxs("div", {
3095
3196
  className: "mb-canvas neeto-rules-main-card",
3096
- children: [/*#__PURE__*/jsxRuntime.jsx(WhenBlock, {
3197
+ children: [renderSlot("beforeWhen"), /*#__PURE__*/jsxRuntime.jsx(WhenBlock, {
3097
3198
  isActive: isActive,
3098
3199
  isInvalid: isInvalid,
3099
3200
  schema: schema,
@@ -3111,11 +3212,11 @@ var Canvas = function Canvas(_ref) {
3111
3212
  schema: schema,
3112
3213
  key: (_condition$id = condition.id) !== null && _condition$id !== void 0 ? _condition$id : index,
3113
3214
  rule: displayRule,
3114
- onRemove: function onRemove() {
3115
- return handleRemoveCondition(index);
3116
- },
3117
3215
  onToken: openPane,
3118
- onAddCondition: canAddCondition && index === displayRule.conditions.length - 1 && handleAddCondition
3216
+ onAddCondition: canAddCondition && index === displayRule.conditions.length - 1 && handleAddCondition,
3217
+ onRemove: canRemoveCondition && function () {
3218
+ return handleRemoveCondition(index);
3219
+ }
3119
3220
  });
3120
3221
  }), renderSlot("afterConditions"), /*#__PURE__*/jsxRuntime.jsx(Connector, {
3121
3222
  active: isTriggerSet
@@ -3187,6 +3288,7 @@ var Canvas = function Canvas(_ref) {
3187
3288
 
3188
3289
  var ACTION_CONFIG_TYPES = {
3189
3290
  emailChannel: "emailChannel",
3291
+ sendToApi: "sendToApi",
3190
3292
  multiSelect: "multiSelect",
3191
3293
  dropdown: "dropdown",
3192
3294
  note: "note",
@@ -3213,7 +3315,9 @@ var ActionConfigFields = function ActionConfigFields(_ref) {
3213
3315
  option = _ref.option,
3214
3316
  action = _ref.action,
3215
3317
  _ref$searchTerm = _ref.searchTerm,
3216
- searchTerm = _ref$searchTerm === void 0 ? "" : _ref$searchTerm;
3318
+ searchTerm = _ref$searchTerm === void 0 ? "" : _ref$searchTerm,
3319
+ _ref$hasRecipientFiel = _ref.hasRecipientField,
3320
+ hasRecipientField = _ref$hasRecipientFiel === void 0 ? false : _ref$hasRecipientFiel;
3217
3321
  var _useTranslation = reactI18next.useTranslation(),
3218
3322
  t = _useTranslation.t;
3219
3323
  var _useFormikContext = formik.useFormikContext(),
@@ -3255,19 +3359,42 @@ var ActionConfigFields = function ActionConfigFields(_ref) {
3255
3359
  "data-testid": "pane-no-matches",
3256
3360
  children: t("neetoRules.builder.noMatches")
3257
3361
  });
3362
+ if (type === ACTION_CONFIG_TYPES.sendToApi) {
3363
+ return /*#__PURE__*/jsxRuntime.jsx(index.ApiFields, {
3364
+ name: name,
3365
+ selectedField: option
3366
+ });
3367
+ }
3258
3368
  if (type === ACTION_CONFIG_TYPES.emailChannel) {
3259
- var _getIn, _action$metadata;
3369
+ var _getIn, _getIn2, _action$metadata;
3260
3370
  var subjectPath = "".concat(name, ".subject");
3261
3371
  var bodyPath = "".concat(name, ".body");
3372
+ // Hosts whose email action picks its recipient from a list keep that
3373
+ // choice in the same pane as the message.
3374
+ var hasRecipientList = neetoCist.isNotEmpty(options) && !hasRecipientField;
3262
3375
  return /*#__PURE__*/jsxRuntime.jsxs("div", {
3263
3376
  className: "flex flex-col gap-4",
3264
- children: [!(option !== null && option !== void 0 && option.hideSubject) && /*#__PURE__*/jsxRuntime.jsx(neetoAtoms.Input, {
3377
+ children: [hasRecipientList && /*#__PURE__*/jsxRuntime.jsx(neetoAtoms.Select, {
3378
+ options: options,
3379
+ required: true,
3380
+ error: fieldError(valuePath),
3381
+ placeholder: option === null || option === void 0 ? void 0 : option.valuePlaceholder,
3382
+ size: "large",
3383
+ value: (_getIn = formik.getIn(values, valuePath)) !== null && _getIn !== void 0 ? _getIn : undefined,
3384
+ label: (option === null || option === void 0 ? void 0 : option.recipientLabel) || t("neetoRules.builder.config.recipient"),
3385
+ onBlur: function onBlur() {
3386
+ return setFieldTouched(valuePath, true);
3387
+ },
3388
+ onChange: function onChange(value) {
3389
+ return setFieldValue(valuePath, value);
3390
+ }
3391
+ }), !(option !== null && option !== void 0 && option.hideSubject) && /*#__PURE__*/jsxRuntime.jsx(neetoAtoms.Input, {
3265
3392
  required: true,
3266
3393
  error: fieldError(subjectPath),
3267
3394
  label: t("neetoRules.builder.config.subject"),
3268
3395
  placeholder: t("neetoRules.builder.config.subjectPlaceholder"),
3269
3396
  size: "large",
3270
- value: (_getIn = formik.getIn(values, subjectPath)) !== null && _getIn !== void 0 ? _getIn : "",
3397
+ value: (_getIn2 = formik.getIn(values, subjectPath)) !== null && _getIn2 !== void 0 ? _getIn2 : "",
3271
3398
  onBlur: function onBlur() {
3272
3399
  return setFieldTouched(subjectPath, true);
3273
3400
  },
@@ -3319,9 +3446,6 @@ var ActionConfigFields = function ActionConfigFields(_ref) {
3319
3446
  error: fieldError(valuePath),
3320
3447
  orientation: "vertical",
3321
3448
  value: String(_current !== null && _current !== void 0 ? _current : ""),
3322
- onBlur: function onBlur() {
3323
- return setFieldTouched(valuePath, true);
3324
- },
3325
3449
  onValueChange: function onValueChange(value) {
3326
3450
  var picked = options.find(function (item) {
3327
3451
  return String(item.value) === value;
@@ -3359,14 +3483,14 @@ var ActionConfigFields = function ActionConfigFields(_ref) {
3359
3483
  });
3360
3484
  }
3361
3485
  if (type === ACTION_CONFIG_TYPES.textarea || type === ACTION_CONFIG_TYPES.number) {
3362
- var _getIn2, _getIn3;
3486
+ var _getIn3, _getIn4;
3363
3487
  return type === ACTION_CONFIG_TYPES.number ? /*#__PURE__*/jsxRuntime.jsx(neetoAtoms.Input, {
3364
3488
  required: true,
3365
3489
  error: fieldError(valuePath),
3366
3490
  label: t("neetoRules.builder.config.value"),
3367
3491
  size: "large",
3368
3492
  type: "number",
3369
- value: (_getIn2 = formik.getIn(values, valuePath)) !== null && _getIn2 !== void 0 ? _getIn2 : "",
3493
+ value: (_getIn3 = formik.getIn(values, valuePath)) !== null && _getIn3 !== void 0 ? _getIn3 : "",
3370
3494
  onBlur: function onBlur() {
3371
3495
  return setFieldTouched(valuePath, true);
3372
3496
  },
@@ -3379,7 +3503,7 @@ var ActionConfigFields = function ActionConfigFields(_ref) {
3379
3503
  label: t("neetoRules.builder.config.message"),
3380
3504
  rows: 5,
3381
3505
  size: "large",
3382
- value: (_getIn3 = formik.getIn(values, valuePath)) !== null && _getIn3 !== void 0 ? _getIn3 : "",
3506
+ value: (_getIn4 = formik.getIn(values, valuePath)) !== null && _getIn4 !== void 0 ? _getIn4 : "",
3383
3507
  onBlur: function onBlur() {
3384
3508
  return setFieldTouched(valuePath, true);
3385
3509
  },
@@ -3389,7 +3513,7 @@ var ActionConfigFields = function ActionConfigFields(_ref) {
3389
3513
  });
3390
3514
  }
3391
3515
  if (type === ACTION_CONFIG_TYPES.text || type === ACTION_CONFIG_TYPES.regex || type === ACTION_CONFIG_TYPES.decimal) {
3392
- var _getIn4;
3516
+ var _getIn5;
3393
3517
  return /*#__PURE__*/jsxRuntime.jsxs("div", {
3394
3518
  className: "flex flex-col gap-2",
3395
3519
  children: [/*#__PURE__*/jsxRuntime.jsx(neetoAtoms.Input, {
@@ -3398,7 +3522,7 @@ var ActionConfigFields = function ActionConfigFields(_ref) {
3398
3522
  label: t("neetoRules.builder.config.value"),
3399
3523
  placeholder: option === null || option === void 0 ? void 0 : option.valuePlaceholder,
3400
3524
  size: "large",
3401
- value: (_getIn4 = formik.getIn(values, valuePath)) !== null && _getIn4 !== void 0 ? _getIn4 : "",
3525
+ value: (_getIn5 = formik.getIn(values, valuePath)) !== null && _getIn5 !== void 0 ? _getIn5 : "",
3402
3526
  onBlur: function onBlur() {
3403
3527
  return setFieldTouched(valuePath, true);
3404
3528
  },
@@ -3509,7 +3633,7 @@ var usePaneValidation = function usePaneValidation(prefix) {
3509
3633
  function _regenerator() { /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/babel/babel/blob/main/packages/babel-helpers/LICENSE */ var e, t, r = "function" == typeof Symbol ? Symbol : {}, n = r.iterator || "@@iterator", o = r.toStringTag || "@@toStringTag"; function i(r, n, o, i) { var c = n && n.prototype instanceof Generator ? n : Generator, u = Object.create(c.prototype); return _regeneratorDefine2(u, "_invoke", function (r, n, o) { var i, c, u, f = 0, p = o || [], y = false, G = { p: 0, n: 0, v: e, a: d, f: d.bind(e, 4), d: function d(t, r) { return i = t, c = 0, u = e, G.n = r, a; } }; function d(r, n) { for (c = r, u = n, t = 0; !y && f && !o && t < p.length; t++) { var o, i = p[t], d = G.p, l = i[2]; r > 3 ? (o = l === n) && (u = i[(c = i[4]) ? 5 : (c = 3, 3)], i[4] = i[5] = e) : i[0] <= d && ((o = r < 2 && d < i[1]) ? (c = 0, G.v = n, G.n = i[1]) : d < l && (o = r < 3 || i[0] > n || n > l) && (i[4] = r, i[5] = n, G.n = l, c = 0)); } if (o || r > 1) return a; throw y = true, n; } return function (o, p, l) { if (f > 1) throw TypeError("Generator is already running"); for (y && 1 === p && d(p, l), c = p, u = l; (t = c < 2 ? e : u) || !y;) { i || (c ? c < 3 ? (c > 1 && (G.n = -1), d(c, u)) : G.n = u : G.v = u); try { if (f = 2, i) { if (c || (o = "next"), t = i[o]) { if (!(t = t.call(i, u))) throw TypeError("iterator result is not an object"); if (!t.done) return t; u = t.value, c < 2 && (c = 0); } else 1 === c && (t = i["return"]) && t.call(i), c < 2 && (u = TypeError("The iterator does not provide a '" + o + "' method"), c = 1); i = e; } else if ((t = (y = G.n < 0) ? u : r.call(n, G)) !== a) break; } catch (t) { i = e, c = 1, u = t; } finally { f = 1; } } return { value: t, done: y }; }; }(r, o, i), true), u; } var a = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} t = Object.getPrototypeOf; var c = [][n] ? t(t([][n]())) : (_regeneratorDefine2(t = {}, n, function () { return this; }), t), u = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(c); function f(e) { return Object.setPrototypeOf ? Object.setPrototypeOf(e, GeneratorFunctionPrototype) : (e.__proto__ = GeneratorFunctionPrototype, _regeneratorDefine2(e, o, "GeneratorFunction")), e.prototype = Object.create(u), e; } return GeneratorFunction.prototype = GeneratorFunctionPrototype, _regeneratorDefine2(u, "constructor", GeneratorFunctionPrototype), _regeneratorDefine2(GeneratorFunctionPrototype, "constructor", GeneratorFunction), GeneratorFunction.displayName = "GeneratorFunction", _regeneratorDefine2(GeneratorFunctionPrototype, o, "GeneratorFunction"), _regeneratorDefine2(u), _regeneratorDefine2(u, o, "Generator"), _regeneratorDefine2(u, n, function () { return this; }), _regeneratorDefine2(u, "toString", function () { return "[object Generator]"; }), (_regenerator = function _regenerator() { return { w: i, m: f }; })(); }
3510
3634
  function _regeneratorDefine2(e, r, n, t) { var i = Object.defineProperty; try { i({}, "", {}); } catch (e) { i = 0; } _regeneratorDefine2 = function _regeneratorDefine(e, r, n, t) { function o(r, n) { _regeneratorDefine2(e, r, function (e) { return this._invoke(r, n, e); }); } r ? i ? i(e, r, { value: n, enumerable: !t, configurable: !t, writable: !t }) : e[r] = n : (o("next", 0), o("throw", 1), o("return", 2)); }, _regeneratorDefine2(e, r, n, t); }
3511
3635
  var ConfigPane = function ConfigPane(_ref) {
3512
- var _schema$actions, _schema$actions$optio, _schema$actions2, _schema$actions2$opti, _schema$actions3, _schema$actions4, _schema$actions4$opti, _hostRenderConfig;
3636
+ var _schema$actions, _schema$actions$optio, _schema$actions2, _schema$actions2$opti, _action$recipient, _schema$actions3, _schema$actions3$acti, _concat$find, _schema$actions4, _schema$actions5, _schema$actions6, _schema$actions7, _schema$actions7$opti, _hostRenderConfig;
3513
3637
  var schema = _ref.schema,
3514
3638
  index$1 = _ref.index;
3515
3639
  var _useTranslation = reactI18next.useTranslation(),
@@ -3544,14 +3668,24 @@ var ConfigPane = function ConfigPane(_ref) {
3544
3668
  configSubtitle = _actionParts.configSubtitle;
3545
3669
  var name = "".concat(base, ".metadata");
3546
3670
  var flatOption = ((_schema$actions = schema.actions) === null || _schema$actions === void 0 || (_schema$actions$optio = _schema$actions.optionForName) === null || _schema$actions$optio === void 0 ? void 0 : _schema$actions$optio.call(_schema$actions, action.name)) || ((_schema$actions2 = schema.actions) === null || _schema$actions2 === void 0 || (_schema$actions2$opti = _schema$actions2.optionForChannel) === null || _schema$actions2$opti === void 0 ? void 0 : _schema$actions2$opti.call(_schema$actions2, channel)) || option;
3671
+
3672
+ // When the chosen recipient declares its own field, the recipient pane
3673
+ // renders it; showing the same picker here too would just duplicate it.
3674
+ var recipientValue = (_action$recipient = action.recipient) !== null && _action$recipient !== void 0 ? _action$recipient : (_schema$actions3 = schema.actions) === null || _schema$actions3 === void 0 || (_schema$actions3$acti = _schema$actions3.actionForName) === null || _schema$actions3$acti === void 0 || (_schema$actions3$acti = _schema$actions3$acti.call(_schema$actions3, action.name)) === null || _schema$actions3$acti === void 0 ? void 0 : _schema$actions3$acti.recipient;
3675
+ var hasRecipientField = !!((_concat$find = (((_schema$actions4 = schema.actions) === null || _schema$actions4 === void 0 ? void 0 : _schema$actions4.recipients) || []).concat((((_schema$actions5 = schema.actions) === null || _schema$actions5 === void 0 ? void 0 : _schema$actions5.options) || []).flatMap(function (o) {
3676
+ return o.recipients || [];
3677
+ })).find(function (item) {
3678
+ var _item$value;
3679
+ return ((_item$value = item.value) !== null && _item$value !== void 0 ? _item$value : item.id) === recipientValue;
3680
+ })) !== null && _concat$find !== void 0 && _concat$find.field);
3547
3681
  var isSms = SMS_TYPES.includes(flatOption === null || flatOption === void 0 ? void 0 : flatOption.type);
3548
3682
  var disabledReason = (flatOption === null || flatOption === void 0 ? void 0 : flatOption.isDisabled) && flatOption.disabledReason;
3549
- var hostRenderConfig = (flatOption === null || flatOption === void 0 ? void 0 : flatOption.renderConfig) || (flatOption === null || flatOption === void 0 ? void 0 : flatOption.component) || ((_schema$actions3 = schema.actions) === null || _schema$actions3 === void 0 ? void 0 : _schema$actions3.renderConfig);
3683
+ var hostRenderConfig = (flatOption === null || flatOption === void 0 ? void 0 : flatOption.renderConfig) || (flatOption === null || flatOption === void 0 ? void 0 : flatOption.component) || ((_schema$actions6 = schema.actions) === null || _schema$actions6 === void 0 ? void 0 : _schema$actions6.renderConfig);
3550
3684
  var showSearch = normalizeOptions(flatOption === null || flatOption === void 0 ? void 0 : flatOption.dropdownOptions).length >= PANE_SEARCH_THRESHOLD;
3551
3685
  var shouldAdvanceToRecipient = !!needsRecipient;
3552
3686
  var _usePaneValidation = usePaneValidation(name),
3553
3687
  validate = _usePaneValidation.validate;
3554
- var channelRepName = (_schema$actions4 = schema.actions) === null || _schema$actions4 === void 0 || (_schema$actions4$opti = _schema$actions4.optionForChannel) === null || _schema$actions4$opti === void 0 || (_schema$actions4$opti = _schema$actions4$opti.call(_schema$actions4, channel)) === null || _schema$actions4$opti === void 0 ? void 0 : _schema$actions4$opti.value;
3688
+ var channelRepName = (_schema$actions7 = schema.actions) === null || _schema$actions7 === void 0 || (_schema$actions7$opti = _schema$actions7.optionForChannel) === null || _schema$actions7$opti === void 0 || (_schema$actions7$opti = _schema$actions7$opti.call(_schema$actions7, channel)) === null || _schema$actions7$opti === void 0 ? void 0 : _schema$actions7$opti.value;
3555
3689
  var unnamedOnOpen = react.useRef(!action.name);
3556
3690
  react.useEffect(function () {
3557
3691
  if (!unnamedOnOpen.current || !channelRepName) return undefined;
@@ -3670,6 +3804,7 @@ var ConfigPane = function ConfigPane(_ref) {
3670
3804
  searchTerm: searchTerm
3671
3805
  })) !== null && _hostRenderConfig !== void 0 ? _hostRenderConfig : /*#__PURE__*/jsxRuntime.jsx(ActionConfigFields, {
3672
3806
  action: action,
3807
+ hasRecipientField: hasRecipientField,
3673
3808
  name: name,
3674
3809
  searchTerm: searchTerm,
3675
3810
  option: flatOption
@@ -4008,7 +4143,9 @@ var OptionsPane = function OptionsPane(_ref) {
4008
4143
  anchor = _ref.anchor,
4009
4144
  index$1 = _ref.index,
4010
4145
  _ref$belowContent = _ref.belowContent,
4011
- belowContent = _ref$belowContent === void 0 ? null : _ref$belowContent;
4146
+ belowContent = _ref$belowContent === void 0 ? null : _ref$belowContent,
4147
+ _ref$configPending = _ref.configPending,
4148
+ configPending = _ref$configPending === void 0 ? false : _ref$configPending;
4012
4149
  var _useTranslation = reactI18next.useTranslation(),
4013
4150
  t = _useTranslation.t;
4014
4151
  var _useFormikContext = formik.useFormikContext(),
@@ -4114,7 +4251,8 @@ var OptionsPane = function OptionsPane(_ref) {
4114
4251
  anchor: anchor,
4115
4252
  schema: schema,
4116
4253
  rule: rule,
4117
- index: index$1
4254
+ index: index$1,
4255
+ configPending: configPending
4118
4256
  });
4119
4257
  if (target) openType({
4120
4258
  type: target.type,
@@ -4128,21 +4266,53 @@ var OptionsPane = function OptionsPane(_ref) {
4128
4266
  });
4129
4267
  var optionLabel = function optionLabel(option) {
4130
4268
  var Icon = option.icon;
4131
- if (!Icon && !option.disabledReason) return option.label;
4269
+ // Short text sits inline as a pill; anything needing more room is a
4270
+ // standard popover behind an info icon.
4271
+ var reason = typeof option.disabledReason === "function" ? option.disabledReason() : option.disabledReason;
4272
+ var isTextReason = typeof reason === "string";
4273
+ // Only a node can be rendered as popover content; a host handing back a
4274
+ // plain object would otherwise crash the pane.
4275
+ var isNodeReason = /*#__PURE__*/react.isValidElement(reason) || Array.isArray(reason);
4276
+ var popover = option.disabledPopover || (isNodeReason ? {
4277
+ description: reason
4278
+ } : null);
4279
+ if (!Icon && !isTextReason && !popover) return option.label;
4132
4280
  return /*#__PURE__*/jsxRuntime.jsxs("span", {
4133
4281
  className: "mb-pane-option",
4134
4282
  children: [Icon && /*#__PURE__*/jsxRuntime.jsx(Icon, {
4135
4283
  size: 20
4136
- }), option.label, option.disabledReason && (option.disabledTooltip ? /*#__PURE__*/jsxRuntime.jsx(neetoAtoms.Tooltip, {
4284
+ }), option.label, popover && /*#__PURE__*/jsxRuntime.jsxs(neetoAtoms.Popover, {
4285
+ position: "top",
4286
+ trigger: /*#__PURE__*/jsxRuntime.jsx("span", {
4287
+ className: "mb-pane-info",
4288
+ onClick: function onClick(event) {
4289
+ return event.preventDefault();
4290
+ },
4291
+ children: /*#__PURE__*/jsxRuntime.jsx(Info, {
4292
+ size: 14
4293
+ })
4294
+ }),
4295
+ children: [popover.title && /*#__PURE__*/jsxRuntime.jsx(neetoAtoms.Popover.Title, {
4296
+ children: popover.title
4297
+ }), /*#__PURE__*/jsxRuntime.jsx(neetoAtoms.Typography, {
4298
+ color: "muted",
4299
+ variant: "body2",
4300
+ children: popover.description
4301
+ }), popover.helpLinkProps && /*#__PURE__*/jsxRuntime.jsx(neetoAtoms.Button, _objectSpread$2(_objectSpread$2({}, popover.helpLinkProps), {}, {
4302
+ className: "h-auto self-start p-0",
4303
+ size: "sm",
4304
+ variant: "link"
4305
+ }))]
4306
+ }), !popover && reason && isTextReason && (option.disabledTooltip ? /*#__PURE__*/jsxRuntime.jsx(neetoAtoms.Tooltip, {
4137
4307
  content: option.disabledTooltip,
4138
4308
  position: "top",
4139
4309
  children: /*#__PURE__*/jsxRuntime.jsx("span", {
4140
4310
  className: "mb-pane-warn",
4141
- children: option.disabledReason
4311
+ children: reason
4142
4312
  })
4143
4313
  }) : /*#__PURE__*/jsxRuntime.jsx("span", {
4144
4314
  className: "mb-pane-warn",
4145
- children: option.disabledReason
4315
+ children: reason
4146
4316
  }))]
4147
4317
  });
4148
4318
  };
@@ -4313,7 +4483,9 @@ var RecipientField = function RecipientField(_ref) {
4313
4483
  var RecipientPane = function RecipientPane(_ref) {
4314
4484
  var _schema$actions, _schema$actions$actio, _action$recipient, _schema$actions2, _schema$actions2$acti, _schema$actions3, _schema$actions3$rend, _schema$actions4, _schema$actions4$opti, _schema$actions5, _schema$actions5$opti, _schema$actions6, _schema$actions7, _schema$actions$rende, _schema$actions8, _schema$actions8$rend, _action$metadata, _schema$actions9;
4315
4485
  var schema = _ref.schema,
4316
- index$1 = _ref.index;
4486
+ index$1 = _ref.index,
4487
+ _ref$configPending = _ref.configPending,
4488
+ configPending = _ref$configPending === void 0 ? false : _ref$configPending;
4317
4489
  var _useTranslation = reactI18next.useTranslation(),
4318
4490
  t = _useTranslation.t;
4319
4491
  var _useRuleModel = useRuleModel(schema),
@@ -4388,6 +4560,7 @@ var RecipientPane = function RecipientPane(_ref) {
4388
4560
  if (!editor) {
4389
4561
  return /*#__PURE__*/jsxRuntime.jsx(OptionsPane, {
4390
4562
  belowContent: belowContent,
4563
+ configPending: configPending,
4391
4564
  index: index$1,
4392
4565
  schema: schema,
4393
4566
  anchor: BUILDER_ANCHORS.ACTION_RECIPIENT
@@ -4513,9 +4686,6 @@ var ConditionValueFields = function ConditionValueFields(_ref) {
4513
4686
  error: fieldError(valuePath),
4514
4687
  orientation: "vertical",
4515
4688
  value: String(_current2 !== null && _current2 !== void 0 ? _current2 : ""),
4516
- onBlur: function onBlur() {
4517
- return setFieldTouched(valuePath, true);
4518
- },
4519
4689
  onValueChange: function onValueChange(value) {
4520
4690
  return setFieldValue(valuePath, value);
4521
4691
  },
@@ -4740,7 +4910,10 @@ var Form = function Form(_ref) {
4740
4910
  values: values,
4741
4911
  schema: schema
4742
4912
  });
4743
- if (!isRuleComplete(rule) || invalidScopeIndexes({
4913
+ if (!isRuleComplete({
4914
+ rule: rule,
4915
+ schema: schema
4916
+ }) || invalidScopeIndexes({
4744
4917
  rule: rule,
4745
4918
  schema: schema
4746
4919
  }).length || invalidScopePhoneFieldIndexes({