@capillarytech/creatives-library 8.0.316-alpha.4 → 8.0.317-alpha.0

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 (91) hide show
  1. package/constants/unified.js +1 -0
  2. package/package.json +1 -1
  3. package/services/api.js +6 -0
  4. package/services/tests/api.test.js +7 -0
  5. package/utils/common.js +6 -1
  6. package/utils/tests/tagValidations.test.js +34 -0
  7. package/v2Components/CapTagList/index.js +15 -22
  8. package/v2Components/CapTagList/style.scss +48 -0
  9. package/v2Components/CapTagListWithInput/__tests__/CapTagListWithInput.test.js +63 -0
  10. package/v2Components/CapTagListWithInput/index.js +4 -0
  11. package/v2Components/CapWhatsappCTA/index.js +2 -0
  12. package/v2Components/CommonTestAndPreview/tests/CustomValuesEditor.test.js +180 -0
  13. package/v2Components/CommonTestAndPreview/tests/DeliverySettings/utils/parseSenderDetailsResponse.test.js +96 -0
  14. package/v2Components/CommonTestAndPreview/tests/UnifiedPreview/index.test.js +99 -0
  15. package/v2Components/CommonTestAndPreview/tests/index.test.js +113 -3
  16. package/v2Components/FormBuilder/index.js +7 -0
  17. package/v2Components/HtmlEditor/HTMLEditor.js +6 -1
  18. package/v2Components/HtmlEditor/__tests__/HTMLEditor.apiErrors.test.js +1 -0
  19. package/v2Components/HtmlEditor/__tests__/HTMLEditor.test.js +927 -2
  20. package/v2Components/HtmlEditor/components/CodeEditorPane/index.js +3 -0
  21. package/v2Components/SmsFallback/tests/useLocalTemplateList.test.js +95 -0
  22. package/v2Containers/BeeEditor/index.js +3 -0
  23. package/v2Containers/CommunicationFlow/CommunicationFlow.js +291 -0
  24. package/v2Containers/CommunicationFlow/CommunicationFlow.scss +25 -0
  25. package/v2Containers/CommunicationFlow/Tests/CommunicationFlow.test.js +255 -0
  26. package/v2Containers/CommunicationFlow/constants.js +200 -0
  27. package/v2Containers/CommunicationFlow/index.js +102 -0
  28. package/v2Containers/CommunicationFlow/messages.js +346 -0
  29. package/v2Containers/CommunicationFlow/steps/ChannelSelectionStep/ChannelSelectionStep.js +522 -0
  30. package/v2Containers/CommunicationFlow/steps/ChannelSelectionStep/ChannelSelectionStep.scss +170 -0
  31. package/v2Containers/CommunicationFlow/steps/ChannelSelectionStep/Tests/ChannelSelectionStep.test.js +796 -0
  32. package/v2Containers/CommunicationFlow/steps/ChannelSelectionStep/index.js +5 -0
  33. package/v2Containers/CommunicationFlow/steps/CommunicationStrategyStep/CommunicationStrategyStep.js +95 -0
  34. package/v2Containers/CommunicationFlow/steps/CommunicationStrategyStep/Tests/CommunicationStrategyStep.test.js +133 -0
  35. package/v2Containers/CommunicationFlow/steps/CommunicationStrategyStep/index.js +5 -0
  36. package/v2Containers/CommunicationFlow/steps/DeliverySettingsStep/DeliverySettingsSection.js +289 -0
  37. package/v2Containers/CommunicationFlow/steps/DeliverySettingsStep/DeliverySettingsSection.scss +70 -0
  38. package/v2Containers/CommunicationFlow/steps/DeliverySettingsStep/SenderDetails.js +319 -0
  39. package/v2Containers/CommunicationFlow/steps/DeliverySettingsStep/SenderDetails.scss +69 -0
  40. package/v2Containers/CommunicationFlow/steps/DeliverySettingsStep/Tests/DeliverySettingsSection.test.js +616 -0
  41. package/v2Containers/CommunicationFlow/steps/DeliverySettingsStep/Tests/SenderDetails.test.js +577 -0
  42. package/v2Containers/CommunicationFlow/steps/DeliverySettingsStep/Tests/deliverySettingsConfig.test.js +1111 -0
  43. package/v2Containers/CommunicationFlow/steps/DeliverySettingsStep/deliverySettingsConfig.js +696 -0
  44. package/v2Containers/CommunicationFlow/steps/DeliverySettingsStep/index.js +7 -0
  45. package/v2Containers/CommunicationFlow/steps/DynamicControlsStep/DynamicControlsStep.js +102 -0
  46. package/v2Containers/CommunicationFlow/steps/DynamicControlsStep/DynamicControlsStep.scss +36 -0
  47. package/v2Containers/CommunicationFlow/steps/DynamicControlsStep/Tests/DynamicControlsStep.test.js +91 -0
  48. package/v2Containers/CommunicationFlow/steps/DynamicControlsStep/index.js +5 -0
  49. package/v2Containers/CommunicationFlow/steps/MessageTypeStep/MessageTypeStep.js +86 -0
  50. package/v2Containers/CommunicationFlow/steps/MessageTypeStep/Tests/MessageTypeStep.test.js +100 -0
  51. package/v2Containers/CommunicationFlow/steps/MessageTypeStep/index.js +5 -0
  52. package/v2Containers/CommunicationFlow/utils/getEnabledSteps.js +30 -0
  53. package/v2Containers/CreativesContainer/SlideBoxContent.js +28 -1
  54. package/v2Containers/CreativesContainer/constants.js +3 -0
  55. package/v2Containers/CreativesContainer/index.js +3 -0
  56. package/v2Containers/CreativesContainer/tests/SlideBoxFooter.test.js +104 -0
  57. package/v2Containers/CreativesContainer/tests/SlideBoxHeader.test.js +110 -0
  58. package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxHeader.test.js.snap +363 -0
  59. package/v2Containers/CreativesContainer/tests/embeddedSlideboxUtils.test.js +258 -0
  60. package/v2Containers/Email/index.js +1 -0
  61. package/v2Containers/EmailWrapper/components/EmailHTMLEditor.js +7 -1
  62. package/v2Containers/EmailWrapper/components/EmailWrapperView.js +3 -0
  63. package/v2Containers/EmailWrapper/components/__tests__/EmailHTMLEditor.test.js +20 -2
  64. package/v2Containers/EmailWrapper/components/__tests__/EmailWrapperView.test.js +16 -1
  65. package/v2Containers/EmailWrapper/hooks/useEmailWrapper.js +3 -0
  66. package/v2Containers/EmailWrapper/index.js +4 -0
  67. package/v2Containers/EmailWrapper/tests/useEmailWrapper.edgeCases.test.js +1 -0
  68. package/v2Containers/EmailWrapper/tests/useEmailWrapper.test.js +9 -0
  69. package/v2Containers/InAppWrapper/hooks/__tests__/useInAppWrapper.test.js +19 -0
  70. package/v2Containers/InAppWrapper/hooks/useInAppWrapper.js +3 -0
  71. package/v2Containers/InAppWrapper/index.js +3 -0
  72. package/v2Containers/MobilePush/Create/index.js +2 -0
  73. package/v2Containers/MobilePush/Edit/index.js +2 -0
  74. package/v2Containers/MobilepushWrapper/index.js +3 -1
  75. package/v2Containers/Rcs/index.js +1 -0
  76. package/v2Containers/Sms/Create/index.js +2 -0
  77. package/v2Containers/Sms/Edit/index.js +2 -0
  78. package/v2Containers/Sms/tests/smsFormDataHelpers.test.js +253 -0
  79. package/v2Containers/SmsTrai/Edit/index.js +2 -0
  80. package/v2Containers/SmsWrapper/index.js +2 -0
  81. package/v2Containers/TagList/index.js +41 -2
  82. package/v2Containers/TagList/messages.js +4 -0
  83. package/v2Containers/TagList/tests/TagList.test.js +122 -20
  84. package/v2Containers/TagList/tests/mockdata.js +17 -0
  85. package/v2Containers/Templates/tests/sagas.test.js +83 -0
  86. package/v2Containers/Viber/index.js +5 -0
  87. package/v2Containers/WebPush/Create/hooks/useTagManagement.js +0 -2
  88. package/v2Containers/WebPush/Create/index.js +9 -1
  89. package/v2Containers/Whatsapp/index.js +5 -0
  90. package/v2Containers/Whatsapp/tests/__snapshots__/index.test.js.snap +20 -0
  91. package/v2Containers/Zalo/index.js +2 -0
@@ -0,0 +1,7 @@
1
+ /**
2
+ * DeliverySettingsStep - Entry point
3
+ * Exports: DeliverySettingsSection (integrated in ChannelSelectionStep), SenderDetails
4
+ */
5
+
6
+ export { default as SenderDetails, parseSenderDetailsFromEntity } from './SenderDetails';
7
+ export { default as DeliverySettingsSection } from './DeliverySettingsSection';
@@ -0,0 +1,102 @@
1
+ /**
2
+ * DynamicControlsStep Component
3
+ */
4
+
5
+ import React from 'react';
6
+ import PropTypes from 'prop-types';
7
+ import { injectIntl } from 'react-intl';
8
+ import CapRow from '@capillarytech/cap-ui-library/CapRow';
9
+ import CapHeading from '@capillarytech/cap-ui-library/CapHeading';
10
+ import CapSwitch from '@capillarytech/cap-ui-library/CapSwitch';
11
+ import messages from '../../messages';
12
+ import './DynamicControlsStep.scss';
13
+
14
+ const DynamicControlsStep = ({
15
+ value,
16
+ onChange,
17
+ controls,
18
+ error,
19
+ intl,
20
+ }) => {
21
+ const { formatMessage } = intl || {};
22
+ // formatMessage used for section title only
23
+ const dynamicControls = value?.dynamicControls || {};
24
+
25
+ const handleToggle = (key, checked) => {
26
+ onChange({
27
+ ...value,
28
+ dynamicControls: { ...dynamicControls, [key]: checked },
29
+ });
30
+ };
31
+
32
+ if (!controls?.length) return null;
33
+
34
+ return (
35
+ <CapRow className="dynamic-controls-step">
36
+ <CapHeading type="h3" className="heading-style">
37
+ {formatMessage(messages.dynamicControlsTitle)}
38
+ </CapHeading>
39
+
40
+ {controls.map(({ key, label, description }) => {
41
+ const checked = !!dynamicControls[key];
42
+ const displayLabel = label || key;
43
+
44
+ return (
45
+ <CapRow
46
+ key={key}
47
+ type="flex"
48
+ align="top"
49
+ justify="space-between"
50
+ className="dynamic-controls-step__row"
51
+ >
52
+ <CapRow className="dynamic-controls-step__label-wrap">
53
+ <CapHeading type="h4" className="dynamic-controls-step__label">
54
+ {displayLabel}
55
+ </CapHeading>
56
+ {description && (
57
+ <CapHeading type="label4" className="dynamic-controls-step__desc">
58
+ {description}
59
+ </CapHeading>
60
+ )}
61
+ </CapRow>
62
+ <CapSwitch
63
+ checked={checked}
64
+ onChange={(val) => handleToggle(key, val)}
65
+ className="dynamic-controls-step__switch"
66
+ />
67
+ </CapRow>
68
+ );
69
+ })}
70
+
71
+ {error && (
72
+ <CapRow className="validation-error dynamic-controls-step__error">
73
+ {error}
74
+ </CapRow>
75
+ )}
76
+ </CapRow>
77
+ );
78
+ };
79
+
80
+ DynamicControlsStep.propTypes = {
81
+ value: PropTypes.shape({
82
+ dynamicControls: PropTypes.object,
83
+ }),
84
+ onChange: PropTypes.func.isRequired,
85
+ controls: PropTypes.arrayOf(
86
+ PropTypes.shape({
87
+ key: PropTypes.string.isRequired,
88
+ label: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
89
+ description: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
90
+ }),
91
+ ),
92
+ error: PropTypes.string,
93
+ intl: PropTypes.object.isRequired,
94
+ };
95
+
96
+ DynamicControlsStep.defaultProps = {
97
+ value: {},
98
+ controls: [],
99
+ error: null,
100
+ };
101
+
102
+ export default injectIntl(DynamicControlsStep);
@@ -0,0 +1,36 @@
1
+ @import '~@capillarytech/cap-ui-library/styles/_variables.scss';
2
+
3
+ .dynamic-controls-step {
4
+ flex-direction: column;
5
+
6
+ &__row {
7
+ padding: $CAP_SPACE_16 0;
8
+ align-items: flex-start;
9
+ }
10
+
11
+ &__label-wrap {
12
+ flex-direction: column;
13
+ align-items: flex-start;
14
+ flex: 1;
15
+ padding-right: $CAP_SPACE_24;
16
+ }
17
+
18
+ &__label {
19
+ line-height: $CAP_SPACE_20;
20
+ }
21
+
22
+ &__desc {
23
+ margin-top: $CAP_SPACE_04;
24
+ color: $FONT_COLOR_03;
25
+ }
26
+
27
+ &__switch {
28
+ flex-shrink: 0;
29
+ margin-top: 0.125rem;
30
+ }
31
+
32
+ &__error {
33
+ margin-top: $CAP_SPACE_08;
34
+ color: $CAP_RED;
35
+ }
36
+ }
@@ -0,0 +1,91 @@
1
+ import React, { useState } from 'react';
2
+ import {
3
+ render, screen,
4
+ } from '@testing-library/react';
5
+ import userEvent from '@testing-library/user-event';
6
+ import '@testing-library/jest-dom';
7
+ import { IntlProvider } from 'react-intl';
8
+ import DynamicControlsStep from '../DynamicControlsStep';
9
+
10
+ const SAMPLE_CONTROLS = [
11
+ { key: 'alpha', label: 'Alpha', description: 'Alpha help' },
12
+ { key: 'beta', label: 'Beta', description: 'Beta help' },
13
+ ];
14
+
15
+ function renderWithIntl(ui) {
16
+ return render(
17
+ <IntlProvider locale="en" messages={{}} defaultLocale="en">
18
+ {ui}
19
+ </IntlProvider>,
20
+ );
21
+ }
22
+
23
+ function DynamicControlsHarness({ initialDynamicControls = {} }) {
24
+ const [value, setValue] = useState({ dynamicControls: initialDynamicControls });
25
+ return (
26
+ <DynamicControlsStep
27
+ value={value}
28
+ onChange={setValue}
29
+ controls={SAMPLE_CONTROLS}
30
+ />
31
+ );
32
+ }
33
+
34
+ describe('DynamicControlsStep', () => {
35
+ it('renders nothing when there are no controls', () => {
36
+ const { container } = renderWithIntl(
37
+ <DynamicControlsStep
38
+ value={{}}
39
+ onChange={jest.fn()}
40
+ controls={[]}
41
+ />,
42
+ );
43
+ expect(container.firstChild).toBeNull();
44
+ });
45
+
46
+ it('shows each switch on (true) or off (false) from dynamicControls for every field', () => {
47
+ renderWithIntl(
48
+ <DynamicControlsHarness initialDynamicControls={{ alpha: true, beta: false }} />,
49
+ );
50
+
51
+ expect(screen.getByText('Other controls')).toBeInTheDocument();
52
+ expect(screen.getByText('Alpha')).toBeInTheDocument();
53
+ expect(screen.getByText('Beta')).toBeInTheDocument();
54
+
55
+ const switches = screen.getAllByRole('switch');
56
+ expect(switches).toHaveLength(2);
57
+ expect(switches[0]).toBeChecked();
58
+ expect(switches[1]).not.toBeChecked();
59
+ });
60
+
61
+ it('toggles every control through false and true via onChange', async () => {
62
+ renderWithIntl(
63
+ <DynamicControlsHarness initialDynamicControls={{ alpha: true, beta: false }} />,
64
+ );
65
+ const switches = screen.getAllByRole('switch');
66
+
67
+ await userEvent.click(switches[0]);
68
+ expect(switches[0]).not.toBeChecked();
69
+
70
+ await userEvent.click(switches[1]);
71
+ expect(switches[1]).toBeChecked();
72
+
73
+ await userEvent.click(switches[0]);
74
+ expect(switches[0]).toBeChecked();
75
+
76
+ await userEvent.click(switches[1]);
77
+ expect(switches[1]).not.toBeChecked();
78
+ });
79
+
80
+ it('renders validation error when error is set', () => {
81
+ renderWithIntl(
82
+ <DynamicControlsStep
83
+ value={{ dynamicControls: { alpha: false } }}
84
+ onChange={jest.fn()}
85
+ controls={[SAMPLE_CONTROLS[0]]}
86
+ error="Dynamic controls validation failed"
87
+ />,
88
+ );
89
+ expect(screen.getByText('Dynamic controls validation failed')).toBeInTheDocument();
90
+ });
91
+ });
@@ -0,0 +1,5 @@
1
+ /**
2
+ * DynamicControlsStep - Entry point
3
+ */
4
+
5
+ export { default } from './DynamicControlsStep';
@@ -0,0 +1,86 @@
1
+ /**
2
+ * MessageTypeStep Component
3
+ *
4
+ * Radio group for selecting Message Type: Promotional | Transactional
5
+ */
6
+
7
+ import React from 'react';
8
+ import PropTypes from 'prop-types';
9
+ import { injectIntl } from 'react-intl';
10
+ import CapRadio from '@capillarytech/cap-ui-library/CapRadio';
11
+ import CapRow from '@capillarytech/cap-ui-library/CapRow';
12
+ import CapHeading from '@capillarytech/cap-ui-library/CapHeading';
13
+ import { CAP_SPACE_24 } from '@capillarytech/cap-ui-library/styled/variables';
14
+ import { MESSAGE_TYPES_OPTIONS } from '../../constants';
15
+ import messages from '../../messages';
16
+ import '../../CommunicationFlow.scss';
17
+
18
+ const MessageTypeStep = ({
19
+ value,
20
+ defaultOption,
21
+ options: optionsProp,
22
+ onChange,
23
+ error,
24
+ intl,
25
+ }) => {
26
+ const { formatMessage } = intl || {};
27
+ const options = optionsProp || MESSAGE_TYPES_OPTIONS;
28
+
29
+ // Use defaultOption value if value is null/undefined
30
+ const selectedValue = value || defaultOption?.value;
31
+
32
+ const handleChange = (messageType) => {
33
+ onChange(messageType);
34
+ };
35
+
36
+ return (
37
+ <CapRow className="message-type-step">
38
+ <CapHeading type="h3" className="heading-style">
39
+ {formatMessage(messages.messageTypeHeading)}
40
+ </CapHeading>
41
+
42
+ <CapRow align="middle" type="flex" gap={CAP_SPACE_24}>
43
+ {options?.map((option) => (
44
+ <CapRadio
45
+ key={option?.value}
46
+ checked={selectedValue === option?.value}
47
+ onChange={() => handleChange(option?.value)}
48
+ disabled={option?.disabled}
49
+ >
50
+ {option?.label}
51
+ </CapRadio>
52
+ ))}
53
+ </CapRow>
54
+
55
+ {error && (
56
+ <CapRow className="validation-error">
57
+ {error}
58
+ </CapRow>
59
+ )}
60
+ </CapRow>
61
+ );
62
+ };
63
+
64
+ MessageTypeStep.propTypes = {
65
+ value: PropTypes.oneOf(['promotional', 'transactional']),
66
+ defaultOption: PropTypes.shape({
67
+ value: PropTypes.string.isRequired,
68
+ label: PropTypes.node.isRequired,
69
+ }),
70
+ options: PropTypes.arrayOf(PropTypes.shape({
71
+ value: PropTypes.string.isRequired,
72
+ label: PropTypes.node.isRequired,
73
+ })),
74
+ onChange: PropTypes.func.isRequired,
75
+ error: PropTypes.string,
76
+ intl: PropTypes.object.isRequired,
77
+ };
78
+
79
+ MessageTypeStep.defaultProps = {
80
+ value: null,
81
+ defaultOption: null,
82
+ options: null,
83
+ error: null,
84
+ };
85
+
86
+ export default injectIntl(MessageTypeStep);
@@ -0,0 +1,100 @@
1
+ import React from 'react';
2
+ import { render, screen } from '@testing-library/react';
3
+ import userEvent from '@testing-library/user-event';
4
+ import '@testing-library/jest-dom';
5
+ import { IntlProvider } from 'react-intl';
6
+ import MessageTypeStep from '../MessageTypeStep';
7
+
8
+ const OPTIONS = [
9
+ { value: 'promotional', label: 'Promotional', disabled: false },
10
+ { value: 'transactional', label: 'Transactional', disabled: false },
11
+ ];
12
+
13
+ function renderWithIntl(ui) {
14
+ return render(
15
+ <IntlProvider locale="en" messages={{}} defaultLocale="en">
16
+ {ui}
17
+ </IntlProvider>,
18
+ );
19
+ }
20
+
21
+ describe('MessageTypeStep', () => {
22
+ it('shows the step heading and one radio per option', () => {
23
+ const onChange = jest.fn();
24
+ renderWithIntl(
25
+ <MessageTypeStep
26
+ value="promotional"
27
+ options={OPTIONS}
28
+ defaultOption={{ value: 'promotional', label: 'Promotional' }}
29
+ onChange={onChange}
30
+ />,
31
+ );
32
+
33
+ expect(screen.getByText(/message type/i)).toBeInTheDocument();
34
+ expect(screen.getByRole('radio', { name: /promotional/i })).toBeInTheDocument();
35
+ expect(screen.getByRole('radio', { name: /transactional/i })).toBeInTheDocument();
36
+ expect(screen.getByRole('radio', { name: /promotional/i })).toBeChecked();
37
+ });
38
+
39
+ it('uses defaultOption when value is null so the default appears selected', () => {
40
+ const onChange = jest.fn();
41
+ renderWithIntl(
42
+ <MessageTypeStep
43
+ value={null}
44
+ options={OPTIONS}
45
+ defaultOption={{ value: 'transactional', label: 'Transactional' }}
46
+ onChange={onChange}
47
+ />,
48
+ );
49
+
50
+ expect(screen.getByRole('radio', { name: /transactional/i })).toBeChecked();
51
+ expect(screen.getByRole('radio', { name: /promotional/i })).not.toBeChecked();
52
+ });
53
+
54
+ it('calls onChange with the chosen message type when the user switches radios', async () => {
55
+ const onChange = jest.fn();
56
+ renderWithIntl(
57
+ <MessageTypeStep
58
+ value="promotional"
59
+ options={OPTIONS}
60
+ defaultOption={{ value: 'promotional', label: 'Promotional' }}
61
+ onChange={onChange}
62
+ />,
63
+ );
64
+
65
+ await userEvent.click(screen.getByRole('radio', { name: /transactional/i }));
66
+ expect(onChange).toHaveBeenCalledWith('transactional');
67
+ });
68
+
69
+ it('disables individual options when configured', () => {
70
+ const onChange = jest.fn();
71
+ const withDisabled = [
72
+ { value: 'promotional', label: 'Promotional', disabled: true },
73
+ { value: 'transactional', label: 'Transactional', disabled: false },
74
+ ];
75
+ renderWithIntl(
76
+ <MessageTypeStep
77
+ value="transactional"
78
+ options={withDisabled}
79
+ onChange={onChange}
80
+ />,
81
+ );
82
+
83
+ expect(screen.getByRole('radio', { name: /promotional/i })).toBeDisabled();
84
+ expect(screen.getByRole('radio', { name: /transactional/i })).not.toBeDisabled();
85
+ });
86
+
87
+ it('shows validation error text below the radios', () => {
88
+ const onChange = jest.fn();
89
+ renderWithIntl(
90
+ <MessageTypeStep
91
+ value="promotional"
92
+ options={OPTIONS}
93
+ onChange={onChange}
94
+ error="Please choose a message type"
95
+ />,
96
+ );
97
+
98
+ expect(screen.getByText('Please choose a message type')).toBeInTheDocument();
99
+ });
100
+ });
@@ -0,0 +1,5 @@
1
+ /**
2
+ * MessageTypeStep - Entry point
3
+ */
4
+
5
+ export { default } from './MessageTypeStep';
@@ -0,0 +1,30 @@
1
+ import { STEPS } from '../constants';
2
+
3
+ /**
4
+ * Enabled steps in order from config.features.*.required flags.
5
+ * Channel selection, incentives, delivery, and dynamic controls are toggled independently.
6
+ */
7
+ export const getEnabledSteps = (config) => {
8
+ const { features = {} } = config;
9
+ const steps = [];
10
+
11
+ if (features.messageTypeData?.required) {
12
+ steps.push(STEPS.MESSAGE_TYPE);
13
+ }
14
+ if (features.communicationStrategyData?.required) {
15
+ steps.push(STEPS.COMMUNICATION_STRATEGY);
16
+ }
17
+ if (features.contentTemplateData?.required) {
18
+ steps.push(STEPS.CHANNEL_SELECTION);
19
+ }
20
+ if (features.incentivesData?.required) {
21
+ steps.push(STEPS.INCENTIVES);
22
+ }
23
+ if (features.deliverySettingsData?.required) {
24
+ steps.push(STEPS.DELIVERY_SETTINGS);
25
+ }
26
+ if (features.dynamicControlsData?.required) {
27
+ steps.push(STEPS.DYNAMIC_CONTROLS);
28
+ }
29
+ return steps;
30
+ };
@@ -170,6 +170,7 @@ export function SlideBoxContent(props) {
170
170
  creativesMode,
171
171
  hostName = '',
172
172
  eventContextTags,
173
+ waitEventContextTags,
173
174
  isLoyaltyModule,
174
175
  loyaltyMetaData = {},
175
176
  showTestAndPreviewSlidebox,
@@ -453,6 +454,7 @@ export function SlideBoxContent(props) {
453
454
  selectedOfferDetails,
454
455
  getFormData,
455
456
  eventContextTags,
457
+ waitEventContextTags,
456
458
  };
457
459
 
458
460
  return (
@@ -487,6 +489,7 @@ export function SlideBoxContent(props) {
487
489
  enableNewChannels={enableNewChannels}
488
490
  hideTestAndPreviewBtn={hideTestAndPreviewBtn}
489
491
  eventContextTags={eventContextTags}
492
+ waitEventContextTags={waitEventContextTags}
490
493
  loyaltyMetaData={loyaltyMetaData}
491
494
  isLoyaltyModule={isLoyaltyModule}
492
495
  localTemplatesConfig={localTemplatesConfig}
@@ -591,6 +594,7 @@ export function SlideBoxContent(props) {
591
594
  onCreateComplete={onCreateComplete}
592
595
  smsRegister={smsRegister}
593
596
  eventContextTags={eventContextTags}
597
+ waitEventContextTags={waitEventContextTags}
594
598
  getLiquidTags={getLiquidTags}
595
599
  showTestAndPreviewSlidebox={showTestAndPreviewSlidebox}
596
600
  handleTestAndPreview={handleTestAndPreview}
@@ -634,6 +638,7 @@ export function SlideBoxContent(props) {
634
638
  }}
635
639
  hostName={hostName}
636
640
  eventContextTags={eventContextTags}
641
+ waitEventContextTags={waitEventContextTags}
637
642
  showLiquidErrorInFooter={showLiquidErrorInFooter}
638
643
  showTestAndPreviewSlidebox={showTestAndPreviewSlidebox}
639
644
  handleTestAndPreview={handleTestAndPreview}
@@ -675,6 +680,7 @@ export function SlideBoxContent(props) {
675
680
  eventContextTags={eventContextTags}
676
681
  restrictPersonalization={restrictPersonalization}
677
682
  isAnonymousType={isAnonymousType}
683
+ waitEventContextTags={waitEventContextTags}
678
684
  />
679
685
  )}
680
686
 
@@ -708,6 +714,7 @@ export function SlideBoxContent(props) {
708
714
  moduleType={moduleType}
709
715
  showLiquidErrorInFooter={showLiquidErrorInFooter}
710
716
  eventContextTags={eventContextTags}
717
+ waitEventContextTags={waitEventContextTags}
711
718
  isLoyaltyModule={isLoyaltyModule}
712
719
  showTestAndPreviewSlidebox={showTestAndPreviewSlidebox}
713
720
  handleTestAndPreview={handleTestAndPreview}
@@ -752,6 +759,7 @@ export function SlideBoxContent(props) {
752
759
  moduleType={moduleType}
753
760
  showLiquidErrorInFooter={showLiquidErrorInFooter}
754
761
  eventContextTags={eventContextTags}
762
+ waitEventContextTags={waitEventContextTags}
755
763
  isLoyaltyModule={isLoyaltyModule}
756
764
  showTestAndPreviewSlidebox={showTestAndPreviewSlidebox}
757
765
  handleTestAndPreview={handleTestAndPreview}
@@ -791,6 +799,7 @@ export function SlideBoxContent(props) {
791
799
  moduleType={moduleType}
792
800
  showLiquidErrorInFooter={showLiquidErrorInFooter}
793
801
  eventContextTags={eventContextTags}
802
+ waitEventContextTags={waitEventContextTags}
794
803
  isLoyaltyModule={isLoyaltyModule}
795
804
  showTestAndPreviewSlidebox={showTestAndPreviewSlidebox}
796
805
  handleTestAndPreview={handleTestAndPreview}
@@ -834,6 +843,7 @@ export function SlideBoxContent(props) {
834
843
  hideTestAndPreviewBtn={hideTestAndPreviewBtn}
835
844
  creativesMode={creativesMode}
836
845
  eventContextTags={eventContextTags}
846
+ waitEventContextTags={waitEventContextTags}
837
847
  showLiquidErrorInFooter={showLiquidErrorInFooter}
838
848
  showTestAndPreviewSlidebox={showTestAndPreviewSlidebox}
839
849
  handleTestAndPreview={handleTestAndPreview}
@@ -866,6 +876,7 @@ export function SlideBoxContent(props) {
866
876
  hideTestAndPreviewBtn={hideTestAndPreviewBtn}
867
877
  creativesMode={creativesMode}
868
878
  eventContextTags={eventContextTags}
879
+ waitEventContextTags={waitEventContextTags}
869
880
  showLiquidErrorInFooter={showLiquidErrorInFooter}
870
881
  handleClose={handleClose}
871
882
  restrictPersonalization={restrictPersonalization}
@@ -905,6 +916,7 @@ export function SlideBoxContent(props) {
905
916
  hideTestAndPreviewBtn={hideTestAndPreviewBtn}
906
917
  onTestContentClicked={onTestContentClicked}
907
918
  eventContextTags={eventContextTags}
919
+ waitEventContextTags={waitEventContextTags}
908
920
  showLiquidErrorInFooter={showLiquidErrorInFooter}
909
921
  showTestAndPreviewSlidebox={showTestAndPreviewSlidebox}
910
922
  handleTestAndPreview={handleTestAndPreview}
@@ -943,6 +955,7 @@ export function SlideBoxContent(props) {
943
955
  hideTestAndPreviewBtn={hideTestAndPreviewBtn}
944
956
  onTestContentClicked={onTestContentClicked}
945
957
  eventContextTags={eventContextTags}
958
+ waitEventContextTags={waitEventContextTags}
946
959
  showLiquidErrorInFooter={showLiquidErrorInFooter}
947
960
  onCreateComplete={onCreateComplete}
948
961
  creativesMode={creativesMode}
@@ -968,6 +981,7 @@ export function SlideBoxContent(props) {
968
981
  onSelectTemplate={onSelectTemplate}
969
982
  orgUnitId={orgUnitId}
970
983
  eventContextTags={eventContextTags}
984
+ waitEventContextTags={waitEventContextTags}
971
985
  showLiquidErrorInFooter={showLiquidErrorInFooter}
972
986
  />
973
987
  )
@@ -989,6 +1003,7 @@ export function SlideBoxContent(props) {
989
1003
  fbAdManager={fbAdManager}
990
1004
  onSelectTemplate={onSelectTemplate}
991
1005
  eventContextTags={eventContextTags}
1006
+ waitEventContextTags={waitEventContextTags}
992
1007
  showLiquidErrorInFooter={showLiquidErrorInFooter}
993
1008
  />
994
1009
  )
@@ -1012,6 +1027,7 @@ export function SlideBoxContent(props) {
1012
1027
  handleClose={handleClose}
1013
1028
  selectedOfferDetails={selectedOfferDetails}
1014
1029
  eventContextTags={eventContextTags}
1030
+ waitEventContextTags={waitEventContextTags}
1015
1031
  showLiquidErrorInFooter={showLiquidErrorInFooter}
1016
1032
  />
1017
1033
  )
@@ -1032,6 +1048,7 @@ export function SlideBoxContent(props) {
1032
1048
  handleClose={handleClose}
1033
1049
  selectedOfferDetails={selectedOfferDetails}
1034
1050
  eventContextTags={eventContextTags}
1051
+ waitEventContextTags={waitEventContextTags}
1035
1052
  showLiquidErrorInFooter={showLiquidErrorInFooter}
1036
1053
  />
1037
1054
  )
@@ -1048,6 +1065,7 @@ export function SlideBoxContent(props) {
1048
1065
  templateData={templateData}
1049
1066
  selectedOfferDetails={selectedOfferDetails}
1050
1067
  eventContextTags={eventContextTags}
1068
+ waitEventContextTags={waitEventContextTags}
1051
1069
  showLiquidErrorInFooter={showLiquidErrorInFooter}
1052
1070
  showTestAndPreviewSlidebox={showTestAndPreviewSlidebox}
1053
1071
  handleTestAndPreview={handleTestAndPreview}
@@ -1072,6 +1090,7 @@ export function SlideBoxContent(props) {
1072
1090
  handleTestAndPreview={handleTestAndPreview}
1073
1091
  handleCloseTestAndPreview={handleCloseTestAndPreview}
1074
1092
  eventContextTags={eventContextTags}
1093
+ waitEventContextTags={waitEventContextTags}
1075
1094
  showLiquidErrorInFooter={showLiquidErrorInFooter}
1076
1095
  createNew/> }
1077
1096
 
@@ -1079,6 +1098,7 @@ export function SlideBoxContent(props) {
1079
1098
  isFullMode={isFullMode}
1080
1099
  onCreateComplete={onCreateComplete}
1081
1100
  eventContextTags={eventContextTags}
1101
+ waitEventContextTags={waitEventContextTags}
1082
1102
  handleClose={handleClose}
1083
1103
  showLiquidErrorInFooter={showLiquidErrorInFooter}
1084
1104
  showTestAndPreviewSlidebox={showTestAndPreviewSlidebox}
@@ -1096,6 +1116,7 @@ export function SlideBoxContent(props) {
1096
1116
  forwardedTags={forwardedTags}
1097
1117
  selectedOfferDetails={selectedOfferDetails}
1098
1118
  eventContextTags={eventContextTags}
1119
+ waitEventContextTags={waitEventContextTags}
1099
1120
  showTestAndPreviewSlidebox={showTestAndPreviewSlidebox}
1100
1121
  handleTestAndPreview={handleTestAndPreview}
1101
1122
  handleCloseTestAndPreview={handleCloseTestAndPreview}
@@ -1134,6 +1155,7 @@ export function SlideBoxContent(props) {
1134
1155
  onPreviewContentClicked={onPreviewContentClicked}
1135
1156
  onTestContentClicked={onTestContentClicked}
1136
1157
  eventContextTags={eventContextTags}
1158
+ waitEventContextTags={waitEventContextTags}
1137
1159
  onCreateComplete={onCreateComplete}
1138
1160
  handleClose={handleClose}
1139
1161
  moduleType={moduleType}
@@ -1169,6 +1191,7 @@ export function SlideBoxContent(props) {
1169
1191
  moduleType={moduleType}
1170
1192
  showLiquidErrorInFooter={showLiquidErrorInFooter}
1171
1193
  eventContextTags={eventContextTags}
1194
+ waitEventContextTags={waitEventContextTags}
1172
1195
  onCreateComplete={onCreateComplete}
1173
1196
  handleClose={handleClose}
1174
1197
  getDefaultTags={type}
@@ -1192,6 +1215,7 @@ export function SlideBoxContent(props) {
1192
1215
  onCreateComplete={onCreateComplete}
1193
1216
  selectedOfferDetails={selectedOfferDetails}
1194
1217
  eventContextTags={eventContextTags}
1218
+ waitEventContextTags={waitEventContextTags}
1195
1219
  params={{
1196
1220
  id: templateData._id,
1197
1221
  }}
@@ -1230,6 +1254,7 @@ export function SlideBoxContent(props) {
1230
1254
  eventContextTags={eventContextTags}
1231
1255
  restrictPersonalization={restrictPersonalization}
1232
1256
  isAnonymousType={isAnonymousType}
1257
+ waitEventContextTags={waitEventContextTags}
1233
1258
  />
1234
1259
  )}
1235
1260
  {isCreateRcs && (<Rcs
@@ -1324,6 +1349,8 @@ SlideBoxContent.propTypes = {
1324
1349
  showTestAndPreviewSlidebox: PropTypes.bool,
1325
1350
  handleTestAndPreview: PropTypes.func,
1326
1351
  handleCloseTestAndPreview: PropTypes.func,
1327
- isTestAndPreviewMode: PropTypes.bool
1352
+ isTestAndPreviewMode: PropTypes.bool,
1353
+ waitEventContextTags: PropTypes.object,
1354
+ eventContextTags: PropTypes.array,
1328
1355
  };
1329
1356
  export default SlideBoxContent;
@@ -11,6 +11,7 @@ export const EBILL = "EBILL";
11
11
  export const LINE = "LINE";
12
12
  export const CALL_TASK = "CALL_TASK";
13
13
  export const MOBILE_PUSH = "MOBILEPUSH";
14
+ export const MPUSH = "MPUSH";
14
15
  export const WECHAT = "WECHAT";
15
16
  export const FACEBOOK = "FACEBOOK";
16
17
  export const FTP = "FTP";
@@ -57,6 +58,8 @@ export const COMMON_CHANNELS = ['sms', 'email', 'wechat', 'mobilepush', 'webpush
57
58
  export const NORMALIZED_CHANNEL_ALIASES = {
58
59
  we_chat: WECHAT.toLowerCase(),
59
60
  m_push: MOBILE_PUSH.toLowerCase(),
61
+ // paneKey `inApp` → `in_app`; TemplatesV2 pane uses key INAPP → `inapp` — both must match for channelsToHide
62
+ in_app: INAPP.toLowerCase(),
60
63
  };
61
64
  export const MIXED = "MIXED";
62
65
  export const VISITOR = "VISITOR";