@capillarytech/creatives-library 9.0.56-betaa.0 → 9.0.56

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 (116) hide show
  1. package/constants/unified.js +9 -4
  2. package/package.json +1 -1
  3. package/services/api.js +25 -4
  4. package/utils/common.js +0 -12
  5. package/utils/templateVarUtils.js +16 -0
  6. package/utils/tests/templateVarUtils.test.js +44 -0
  7. package/v2Components/CapActionButton/index.js +73 -60
  8. package/v2Components/CapActionButton/index.scss +44 -28
  9. package/v2Components/CapActionButton/messages.js +7 -3
  10. package/v2Components/CapActionButton/tests/index.test.js +17 -1
  11. package/v2Components/CapWhatsappCTA/messages.js +4 -0
  12. package/v2Components/CapWhatsappCarouselButton/index.js +42 -33
  13. package/v2Components/CapWhatsappCarouselButton/index.scss +44 -2
  14. package/v2Components/CommonTestAndPreview/UnifiedPreview/index.js +13 -0
  15. package/v2Components/CommonTestAndPreview/actions.js +13 -0
  16. package/v2Components/CommonTestAndPreview/constants.js +8 -0
  17. package/v2Components/CommonTestAndPreview/index.js +55 -3
  18. package/v2Components/CommonTestAndPreview/reducer.js +20 -0
  19. package/v2Components/CommonTestAndPreview/sagas.js +28 -0
  20. package/v2Components/CommonTestAndPreview/selectors.js +6 -0
  21. package/v2Components/CommonTestAndPreview/tests/UnifiedPreview/index.test.js +106 -0
  22. package/v2Components/CommonTestAndPreview/tests/actions.test.js +15 -0
  23. package/v2Components/CommonTestAndPreview/tests/constants.test.js +9 -1
  24. package/v2Components/CommonTestAndPreview/tests/index.test.js +101 -0
  25. package/v2Components/CommonTestAndPreview/tests/reducer.test.js +41 -0
  26. package/v2Components/CommonTestAndPreview/tests/sagas.test.js +84 -0
  27. package/v2Components/CommonTestAndPreview/tests/selectors.test.js +12 -0
  28. package/v2Components/FormBuilder/Functional/FormBuilderShell.js +46 -320
  29. package/v2Components/FormBuilder/Functional/channels/registry.js +0 -2
  30. package/v2Components/FormBuilder/Functional/constants.js +8 -43
  31. package/v2Components/FormBuilder/Functional/core/schema/initializeFormState.js +28 -175
  32. package/v2Components/FormBuilder/Functional/core/store/formReducer.js +6 -75
  33. package/v2Components/FormBuilder/Functional/core/store/toLegacyFormData.js +20 -10
  34. package/v2Components/FormBuilder/Functional/layout/FieldSlot.js +1 -9
  35. package/v2Components/FormBuilder/Functional/layout/SchemaForm.js +3 -20
  36. package/v2Components/FormBuilder/Functional/layout/Section.js +1 -6
  37. package/v2Components/FormBuilder/Functional/tests/fieldSlot.test.js +2 -9
  38. package/v2Components/FormBuilder/Functional/tests/schemaForm.test.js +0 -17
  39. package/v2Components/FormBuilder/index.js +12 -34
  40. package/v2Components/FormBuilder/tests/entryGate.test.js +7 -94
  41. package/v2Components/TestAndPreviewSlidebox/index.js +9 -0
  42. package/v2Containers/CommunicationFlow/CommunicationFlow.js +140 -75
  43. package/v2Containers/CommunicationFlow/CommunicationFlow.scss +18 -2
  44. package/v2Containers/CommunicationFlow/CommunicationFlowCard.js +67 -28
  45. package/v2Containers/CommunicationFlow/Tests/CommunicationFlow.test.js +503 -51
  46. package/v2Containers/CommunicationFlow/Tests/CommunicationFlowCard.test.js +98 -4
  47. package/v2Containers/CommunicationFlow/Tests/constants.test.js +85 -0
  48. package/v2Containers/CommunicationFlow/constants.js +65 -4
  49. package/v2Containers/CommunicationFlow/index.js +16 -23
  50. package/v2Containers/CommunicationFlow/messages.js +11 -3
  51. package/v2Containers/CommunicationFlow/steps/ChannelSelectionStep/ChannelSelectionStep.js +27 -11
  52. package/v2Containers/CommunicationFlow/steps/ChannelSelectionStep/ChannelSelectionStep.scss +4 -0
  53. package/v2Containers/CommunicationFlow/steps/ChannelSelectionStep/Tests/ChannelSelectionStep.test.js +176 -4
  54. package/v2Containers/CommunicationFlow/steps/DeliverySettingsStep/DeliverySettingsSection.js +22 -4
  55. package/v2Containers/CommunicationFlow/steps/DeliverySettingsStep/SenderDetails.js +14 -4
  56. package/v2Containers/CommunicationFlow/steps/DeliverySettingsStep/Tests/DeliverySettingsSection.test.js +11 -0
  57. package/v2Containers/CommunicationFlow/steps/DeliverySettingsStep/Tests/SenderDetails.test.js +51 -0
  58. package/v2Containers/CommunicationFlow/steps/DeliverySettingsStep/Tests/deliverySettingsConfig.test.js +11 -4
  59. package/v2Containers/CommunicationFlow/steps/DeliverySettingsStep/deliverySettingsConfig.js +19 -5
  60. package/v2Containers/CreativesContainer/SlideBoxContent.js +15 -0
  61. package/v2Containers/CreativesContainer/SlideBoxFooter.js +6 -2
  62. package/v2Containers/CreativesContainer/index.js +29 -3
  63. package/v2Containers/CreativesContainer/tests/SlideBoxFooter.test.js +29 -0
  64. package/v2Containers/CreativesContainer/tests/__snapshots__/index.test.js.snap +18 -5
  65. package/v2Containers/CreativesContainer/tests/index.test.js +12 -0
  66. package/v2Containers/MobilePush/Create/index.js +18 -1
  67. package/v2Containers/MobilePush/Create/test/contentValidity.test.js +96 -0
  68. package/v2Containers/MobilePush/Edit/index.js +18 -1
  69. package/v2Containers/MobilePush/Edit/test/contentValidity.test.js +116 -0
  70. package/v2Containers/MobilePush/commonMethods.js +49 -1
  71. package/v2Containers/MobilePushNew/index.js +29 -4
  72. package/v2Containers/MobilePushNew/tests/index.test.js +119 -0
  73. package/v2Containers/MobilePushNew/tests/utils.test.js +82 -0
  74. package/v2Containers/MobilePushNew/utils.js +34 -1
  75. package/v2Containers/MobilepushWrapper/index.js +3 -1
  76. package/v2Containers/Rcs/index.js +34 -0
  77. package/v2Containers/Rcs/index.scss +15 -0
  78. package/v2Containers/Rcs/tests/__snapshots__/index.test.js.snap +115 -19
  79. package/v2Containers/Rcs/tests/index.test.js +67 -0
  80. package/v2Containers/Sms/Create/index.js +3 -1
  81. package/v2Containers/Sms/Edit/index.js +25 -0
  82. package/v2Containers/Sms/Edit/tests/index.test.js +85 -0
  83. package/v2Containers/SmsTrai/Edit/tests/__snapshots__/index.test.js.snap +27 -3
  84. package/v2Containers/Viber/index.js +24 -1
  85. package/v2Containers/Viber/tests/index.test.js +103 -0
  86. package/v2Containers/WebPush/Create/index.js +19 -0
  87. package/v2Containers/WebPush/Create/preview/WebPushPreview.js +17 -12
  88. package/v2Containers/WebPush/Create/preview/tests/WebPushPreview.test.js +5 -0
  89. package/v2Containers/WebPush/Create/tests/contentValidity.test.js +294 -0
  90. package/v2Containers/Whatsapp/index.js +25 -4
  91. package/v2Containers/Whatsapp/tests/__snapshots__/index.test.js.snap +306 -34
  92. package/v2Containers/Whatsapp/tests/index.test.js +115 -0
  93. package/v2Containers/Zalo/index.js +28 -1
  94. package/v2Containers/Zalo/tests/index.test.js +99 -0
  95. package/v2Containers/mockdata.js +25 -0
  96. package/v2Components/FormBuilder/Functional/channels/mobilepush/buildSubmitPayload.js +0 -10
  97. package/v2Components/FormBuilder/Functional/channels/mobilepush/config.js +0 -82
  98. package/v2Components/FormBuilder/Functional/channels/mobilepush/getEditorErrorDescriptor.js +0 -74
  99. package/v2Components/FormBuilder/Functional/channels/mobilepush/index.js +0 -28
  100. package/v2Components/FormBuilder/Functional/channels/mobilepush/modals.js +0 -19
  101. package/v2Components/FormBuilder/Functional/channels/mobilepush/runSubmitPipeline.js +0 -45
  102. package/v2Components/FormBuilder/Functional/channels/mobilepush/tests/getEditorErrorDescriptor.test.js +0 -162
  103. package/v2Components/FormBuilder/Functional/channels/mobilepush/tests/modals.test.js +0 -37
  104. package/v2Components/FormBuilder/Functional/channels/mobilepush/tests/runSubmitPipeline.test.js +0 -70
  105. package/v2Components/FormBuilder/Functional/channels/mobilepush/tests/validate.test.js +0 -274
  106. package/v2Components/FormBuilder/Functional/channels/mobilepush/validate.js +0 -251
  107. package/v2Components/FormBuilder/Functional/layout/TabsContainer.js +0 -89
  108. package/v2Components/FormBuilder/Functional/renderers/mpushRenderers.js +0 -440
  109. package/v2Components/FormBuilder/Functional/tests/mpush.crossFlowParity.test.js +0 -430
  110. package/v2Components/FormBuilder/Functional/tests/mpush.ctaFlows.parity.test.js +0 -282
  111. package/v2Components/FormBuilder/Functional/tests/mpush.editContainer.parity.test.js +0 -141
  112. package/v2Components/FormBuilder/Functional/tests/mpush.engine.test.js +0 -306
  113. package/v2Components/FormBuilder/Functional/tests/mpush.shellEvents.test.js +0 -151
  114. package/v2Components/FormBuilder/Functional/tests/mpushRenderers.test.js +0 -342
  115. package/v2Components/FormBuilder/Functional/tests/tabsContainer.test.js +0 -110
  116. package/v2Components/FormBuilder/tests/mpush.characterization.test.js +0 -459
@@ -6,7 +6,7 @@
6
6
  * - Configured state: shows a two-column CapCard with pen icon, channel preview (left), dynamic controls (right)
7
7
  */
8
8
 
9
- import React, { useState, useCallback } from 'react';
9
+ import React, { useState, useCallback, useEffect } from 'react';
10
10
  import PropTypes from 'prop-types';
11
11
  import { injectIntl } from 'react-intl';
12
12
  import { CAP_G09 } from '@capillarytech/cap-ui-library/styled/variables';
@@ -19,6 +19,7 @@ import CapIcon from '@capillarytech/cap-ui-library/CapIcon';
19
19
  import CapLabel from '@capillarytech/cap-ui-library/CapLabel';
20
20
  import CapHeader from '@capillarytech/cap-ui-library/CapHeader';
21
21
  import CapSlideBox from '@capillarytech/cap-ui-library/CapSlideBox';
22
+ import CapTooltip from '@capillarytech/cap-ui-library/CapTooltip';
22
23
  import CommunicationFlow from './index';
23
24
  import { CHANNELS, DEFAULT_COMMUNICATION_STRATEGY_OPTIONS, DYNAMIC_CONTROLS_CONFIG } from './constants';
24
25
  import {
@@ -41,7 +42,7 @@ const resolveValue = (val) => {
41
42
 
42
43
  const SENDER_ID_RESOLVERS = {
43
44
  [SMS]: (setting) => resolveValue(setting?.gsmSenderId),
44
- [EMAIL]: (setting) => resolveValue(setting?.senderEmail),
45
+ [EMAIL]: (setting) => resolveValue(setting?.senderId),
45
46
  [VIBER]: (setting) => resolveValue(setting?.sender) || resolveValue(setting?.gsmSenderId),
46
47
  [WHATSAPP]: (setting) => resolveValue(setting?.senderMobNum),
47
48
  [RCS]: (setting) => resolveValue(setting?.senderMobNum) || resolveValue(setting?.rcsSender),
@@ -74,11 +75,21 @@ const CommunicationFlowCard = ({
74
75
  onChange,
75
76
  cap,
76
77
  intl,
78
+ disabled,
79
+ disabledTooltip,
77
80
  }) => {
78
81
  const { formatMessage } = intl || {};
79
82
  const [showSlideBox, setShowSlideBox] = useState(false);
80
83
  const [savedData, setSavedData] = useState(initialData || null);
81
84
 
85
+ // On a hard reload of an edit page, initialData is available but savedData is not yet set.
86
+ // This effect ensures that savedData is initialized from initialData in that case.
87
+ useEffect(() => {
88
+ if (initialData && !savedData) {
89
+ setSavedData(initialData);
90
+ }
91
+ }, [initialData]);
92
+
82
93
  const handleSave = useCallback((data) => {
83
94
  setSavedData(data);
84
95
  setShowSlideBox(false);
@@ -91,8 +102,9 @@ const CommunicationFlowCard = ({
91
102
  }, [onCancel]);
92
103
 
93
104
  const handleOpen = useCallback(() => {
105
+ if (disabled) return;
94
106
  setShowSlideBox(true);
95
- }, []);
107
+ }, [disabled]);
96
108
 
97
109
  const firstItem = savedData?.contentItems?.[0];
98
110
  const channelConfig = firstItem
@@ -107,6 +119,9 @@ const CommunicationFlowCard = ({
107
119
  const senderIdValue = getSenderIdValue(firstItem, savedData);
108
120
  const controls = config?.features?.dynamicControlsData?.controls || DYNAMIC_CONTROLS_CONFIG;
109
121
  const dynamicControlKeys = Object.keys(savedData?.dynamicControls || {});
122
+ // Consumers that set showDynamicControls: false render their own "Advanced
123
+ // controls" section elsewhere, so skip this card's redundant control list.
124
+ const showDynamicControls = config?.features?.showDynamicControls !== false;
110
125
  const channel = firstItem.channel?.toUpperCase();
111
126
  const senderLabel = [WHATSAPP, RCS].includes(channel)
112
127
  ? formatMessage(messages.senderNumberLabel)
@@ -120,7 +135,11 @@ const CommunicationFlowCard = ({
120
135
  <CapLabel type="label8">Message:</CapLabel>
121
136
  <CapLabel type="label2">{strategyLabel}</CapLabel>
122
137
  {messageTypeLabel && (
123
- <CapLabel type="label1">({messageTypeLabel})</CapLabel>
138
+ <CapLabel type="label1">
139
+ (
140
+ {messageTypeLabel}
141
+ )
142
+ </CapLabel>
124
143
  )}
125
144
  </CapRow>
126
145
  )}
@@ -135,33 +154,41 @@ const CommunicationFlowCard = ({
135
154
  bodyStyle={{ padding: 0 }}
136
155
  >
137
156
  <CapRow gutter={0} className="card-body-row">
138
- <CapColumn span={12} className="card-body-left-col">
157
+ <CapColumn span={showDynamicControls ? 12 : 24} className="card-body-left-col">
139
158
  <CapRow type="flex" align="middle" className="channel-header-row">
140
159
  <CapIcon type={channelConfig?.iconType || 'sms'} size="s" />
141
160
  <CapLabel type="label8">{channelConfig?.label || firstItem.channel}</CapLabel>
142
161
  {senderIdValue && (
143
- <CapLabel type="label1">({senderLabel}: {senderIdValue})</CapLabel>
162
+ <CapLabel type="label1">
163
+ (
164
+ {senderLabel}
165
+ :
166
+ {senderIdValue}
167
+ )
168
+ </CapLabel>
144
169
  )}
145
170
  </CapRow>
146
171
  {getContentBody(firstItem)}
147
172
  </CapColumn>
148
- <CapColumn span={12} className="card-body-right-col">
149
- <CapLabel type="label8">{formatMessage(messages.dynamicControlsTitle)}</CapLabel>
150
- {dynamicControlKeys.map((key) => {
151
- const controlConfig = controls.find((c) => c.key === key);
152
- if (!controlConfig) return null;
153
- return (
154
- <CapRow key={key} type="flex" justify="space-between" className="control-row">
155
- <CapLabel type="label2">{controlConfig.label}</CapLabel>
156
- <CapLabel type="label2">
157
- {savedData.dynamicControls[key]
158
- ? formatMessage(messages.yes)
159
- : formatMessage(messages.no)}
160
- </CapLabel>
161
- </CapRow>
162
- );
163
- })}
164
- </CapColumn>
173
+ {showDynamicControls && (
174
+ <CapColumn span={12} className="card-body-right-col">
175
+ <CapLabel type="label8">{formatMessage(messages.dynamicControlsTitle)}</CapLabel>
176
+ {dynamicControlKeys.map((key) => {
177
+ const controlConfig = controls.find((control) => control.key === key);
178
+ if (!controlConfig) return null;
179
+ return (
180
+ <CapRow key={key} type="flex" justify="space-between" className="control-row">
181
+ <CapLabel type="label2">{controlConfig.label}</CapLabel>
182
+ <CapLabel type="label2">
183
+ {savedData.dynamicControls[key]
184
+ ? formatMessage(messages.yes)
185
+ : formatMessage(messages.no)}
186
+ </CapLabel>
187
+ </CapRow>
188
+ );
189
+ })}
190
+ </CapColumn>
191
+ )}
165
192
  </CapRow>
166
193
  </CapCard>
167
194
  );
@@ -182,9 +209,17 @@ const CommunicationFlowCard = ({
182
209
  <CapImage src={addCreativesIllustration} />
183
210
  </CapColumn>
184
211
  <CapColumn span={14} className="empty-card-action-col">
185
- <CapButton type="secondary" onClick={handleOpen}>
186
- {formatMessage(messages.addCreatives)}
187
- </CapButton>
212
+ {disabled && disabledTooltip ? (
213
+ <CapTooltip title={disabledTooltip}>
214
+ <CapButton type="secondary" disabled>
215
+ {formatMessage(messages.addCreatives)}
216
+ </CapButton>
217
+ </CapTooltip>
218
+ ) : (
219
+ <CapButton type="secondary" onClick={handleOpen} disabled={disabled}>
220
+ {formatMessage(messages.addCreatives)}
221
+ </CapButton>
222
+ )}
188
223
  </CapColumn>
189
224
  </CapRow>
190
225
  </CapCard>
@@ -196,10 +231,10 @@ const CommunicationFlowCard = ({
196
231
  <CapSlideBox
197
232
  show={showSlideBox}
198
233
  handleClose={handleClose}
199
- size="size-xl"
234
+ size="size-l"
200
235
  header={(
201
236
  <CapHeader
202
- title={formatMessage(messages.addMessage)}
237
+ title={formatMessage(messages.addContent)}
203
238
  handleClose={handleClose}
204
239
  />
205
240
  )}
@@ -227,6 +262,8 @@ CommunicationFlowCard.propTypes = {
227
262
  onChange: PropTypes.func,
228
263
  cap: PropTypes.object,
229
264
  intl: PropTypes.object.isRequired,
265
+ disabled: PropTypes.bool, // Disables the "Add creatives" trigger (e.g. until a consumer-required field is filled)
266
+ disabledTooltip: PropTypes.node, // Shown on hover when disabled is true
230
267
  };
231
268
 
232
269
  CommunicationFlowCard.defaultProps = {
@@ -235,6 +272,8 @@ CommunicationFlowCard.defaultProps = {
235
272
  onCancel: null,
236
273
  onChange: null,
237
274
  cap: null,
275
+ disabled: false,
276
+ disabledTooltip: null,
238
277
  };
239
278
 
240
279
  export default injectIntl(CommunicationFlowCard);