@capillarytech/creatives-library 9.0.29 → 9.0.31

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 (147) hide show
  1. package/constants/unified.js +29 -0
  2. package/global-styles.js +1 -1
  3. package/package.json +1 -1
  4. package/services/tests/api.test.js +35 -20
  5. package/utils/commonUtils.js +22 -1
  6. package/utils/rcsPayloadUtils.js +102 -0
  7. package/utils/templateVarUtils.js +198 -0
  8. package/utils/tests/rcsPayloadUtils.test.js +295 -0
  9. package/utils/tests/templateVarUtils.test.js +204 -0
  10. package/v2Components/CapActionButton/constants.js +21 -1
  11. package/v2Components/CapActionButton/index.js +261 -144
  12. package/v2Components/CapActionButton/index.scss +245 -14
  13. package/v2Components/CapActionButton/messages.js +32 -3
  14. package/v2Components/CapActionButton/tests/index.test.js +74 -19
  15. package/v2Components/CapImageUpload/index.js +2 -2
  16. package/v2Components/CapTagList/index.js +9 -0
  17. package/v2Components/CommonTestAndPreview/CustomValuesEditor.js +70 -48
  18. package/v2Components/CommonTestAndPreview/DeliverySettings/DeliverySettings.scss +8 -2
  19. package/v2Components/CommonTestAndPreview/DeliverySettings/ModifyDeliverySettings.js +214 -21
  20. package/v2Components/CommonTestAndPreview/DeliverySettings/constants.js +16 -0
  21. package/v2Components/CommonTestAndPreview/DeliverySettings/index.js +83 -9
  22. package/v2Components/CommonTestAndPreview/DeliverySettings/messages.js +30 -0
  23. package/v2Components/CommonTestAndPreview/DeliverySettings/utils/parseSenderDetailsResponse.js +58 -11
  24. package/v2Components/CommonTestAndPreview/SendTestMessage.js +10 -5
  25. package/v2Components/CommonTestAndPreview/UnifiedPreview/RcsPreviewContent.js +186 -22
  26. package/v2Components/CommonTestAndPreview/UnifiedPreview/_unifiedPreview.scss +381 -80
  27. package/v2Components/CommonTestAndPreview/UnifiedPreview/index.js +155 -8
  28. package/v2Components/CommonTestAndPreview/_commonTestAndPreview.scss +11 -0
  29. package/v2Components/CommonTestAndPreview/constants.js +35 -2
  30. package/v2Components/CommonTestAndPreview/index.js +774 -231
  31. package/v2Components/CommonTestAndPreview/messages.js +45 -3
  32. package/v2Components/CommonTestAndPreview/previewApiUtils.js +59 -0
  33. package/v2Components/CommonTestAndPreview/sagas.js +25 -6
  34. package/v2Components/CommonTestAndPreview/tests/CommonTestAndPreview.addTestCustomer.test.js +1 -0
  35. package/v2Components/CommonTestAndPreview/tests/CustomValuesEditor.test.js +412 -257
  36. package/v2Components/CommonTestAndPreview/tests/DeliverySettings/ModifyDeliverySettings.test.js +337 -63
  37. package/v2Components/CommonTestAndPreview/tests/DeliverySettings/index.test.js +118 -5
  38. package/v2Components/CommonTestAndPreview/tests/DeliverySettings/utils/parseSenderDetailsResponse.test.js +341 -0
  39. package/v2Components/CommonTestAndPreview/tests/PreviewSection.test.js +8 -1
  40. package/v2Components/CommonTestAndPreview/tests/SendTestMessage.test.js +108 -15
  41. package/v2Components/CommonTestAndPreview/tests/UnifiedPreview/RcsPreviewContent.test.js +281 -283
  42. package/v2Components/CommonTestAndPreview/tests/UnifiedPreview/index.test.js +199 -1
  43. package/v2Components/CommonTestAndPreview/tests/index.test.js +133 -4
  44. package/v2Components/CommonTestAndPreview/tests/previewApiUtils.test.js +67 -0
  45. package/v2Components/CommonTestAndPreview/tests/sagas.test.js +31 -24
  46. package/v2Components/CommonTestAndPreview/tests/utils.test.js +151 -0
  47. package/v2Components/CommonTestAndPreview/utils.js +84 -0
  48. package/v2Components/SmsFallback/SmsFallbackLocalSelector.js +91 -0
  49. package/v2Components/SmsFallback/constants.js +94 -0
  50. package/v2Components/SmsFallback/index.js +958 -0
  51. package/v2Components/SmsFallback/index.scss +266 -0
  52. package/v2Components/SmsFallback/messages.js +78 -0
  53. package/v2Components/SmsFallback/smsFallbackUtils.js +120 -0
  54. package/v2Components/SmsFallback/tests/SmsFallbackLocalSelector.test.js +50 -0
  55. package/v2Components/SmsFallback/tests/rcsSmsFallback.acceptance.test.js +147 -0
  56. package/v2Components/SmsFallback/tests/smsFallbackHandlers.test.js +304 -0
  57. package/v2Components/SmsFallback/tests/smsFallbackUi.test.js +208 -0
  58. package/v2Components/SmsFallback/tests/smsFallbackUtils.test.js +309 -0
  59. package/v2Components/SmsFallback/tests/useLocalTemplateList.test.js +471 -0
  60. package/v2Components/SmsFallback/useLocalTemplateList.js +92 -0
  61. package/v2Components/TemplatePreview/_templatePreview.scss +45 -25
  62. package/v2Components/TemplatePreview/constants.js +2 -0
  63. package/v2Components/TemplatePreview/index.js +147 -32
  64. package/v2Components/TemplatePreview/tests/index.test.js +142 -0
  65. package/v2Components/TestAndPreviewSlidebox/CustomValuesEditor.js +6 -6
  66. package/v2Components/TestAndPreviewSlidebox/index.js +13 -1
  67. package/v2Components/TestAndPreviewSlidebox/sagas.js +11 -4
  68. package/v2Components/TestAndPreviewSlidebox/tests/saga.test.js +3 -1
  69. package/v2Components/VarSegmentMessageEditor/constants.js +2 -0
  70. package/v2Components/VarSegmentMessageEditor/index.js +125 -0
  71. package/v2Components/VarSegmentMessageEditor/index.scss +46 -0
  72. package/v2Containers/CommunicationFlow/Tests/CommunicationFlow.test.js +4 -1
  73. package/v2Containers/CommunicationFlow/steps/DeliverySettingsStep/Tests/DeliverySettingsSection.test.js +4 -0
  74. package/v2Containers/CommunicationFlow/steps/DeliverySettingsStep/Tests/SenderDetails.test.js +20 -20
  75. package/v2Containers/CreativesContainer/CreativesSlideBoxWrapper.js +27 -0
  76. package/v2Containers/CreativesContainer/SlideBoxContent.js +37 -4
  77. package/v2Containers/CreativesContainer/SlideBoxFooter.js +14 -5
  78. package/v2Containers/CreativesContainer/SlideBoxHeader.js +36 -5
  79. package/v2Containers/CreativesContainer/constants.js +11 -0
  80. package/v2Containers/CreativesContainer/embeddedSlideboxUtils.js +77 -0
  81. package/v2Containers/CreativesContainer/index.js +322 -106
  82. package/v2Containers/CreativesContainer/index.scss +102 -1
  83. package/v2Containers/CreativesContainer/tests/CreativesSlideBoxWrapper.test.js +58 -0
  84. package/v2Containers/CreativesContainer/tests/SlideBoxContent.localTemplates.test.js +90 -0
  85. package/v2Containers/CreativesContainer/tests/SlideBoxContent.smsDltPreview.test.js +73 -0
  86. package/v2Containers/CreativesContainer/tests/SlideBoxContent.test.js +37 -0
  87. package/v2Containers/CreativesContainer/tests/SlideBoxFooter.test.js +103 -34
  88. package/v2Containers/CreativesContainer/tests/SlideBoxHeader.test.js +193 -15
  89. package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxContent.test.js.snap +88 -0
  90. package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxHeader.test.js.snap +549 -57
  91. package/v2Containers/CreativesContainer/tests/__snapshots__/index.test.js.snap +20 -15
  92. package/v2Containers/CreativesContainer/tests/embeddedSlideboxUtils.test.js +258 -0
  93. package/v2Containers/CreativesContainer/tests/index.test.js +71 -9
  94. package/v2Containers/CreativesContainer/tests/useLocalTemplatesProp.test.js +125 -0
  95. package/v2Containers/MobilePush/Create/test/saga.test.js +2 -2
  96. package/v2Containers/Rcs/carouselUtils.js +224 -0
  97. package/v2Containers/Rcs/components/CarouselCard.js +317 -0
  98. package/v2Containers/Rcs/components/CarouselCardButtons.js +113 -0
  99. package/v2Containers/Rcs/components/CarouselCardMedia.js +136 -0
  100. package/v2Containers/Rcs/components/CarouselCharacterCount.js +31 -0
  101. package/v2Containers/Rcs/components/CarouselDimensionSelection.js +80 -0
  102. package/v2Containers/Rcs/constants.js +132 -16
  103. package/v2Containers/Rcs/index.js +1822 -946
  104. package/v2Containers/Rcs/index.scss +443 -8
  105. package/v2Containers/Rcs/messages.js +45 -22
  106. package/v2Containers/Rcs/rcsLibraryHydrationUtils.js +494 -0
  107. package/v2Containers/Rcs/tests/CarouselCard.test.js +464 -0
  108. package/v2Containers/Rcs/tests/CarouselCardButtons.test.js +211 -0
  109. package/v2Containers/Rcs/tests/CarouselCardMedia.test.js +160 -0
  110. package/v2Containers/Rcs/tests/CarouselCharacterCount.test.js +50 -0
  111. package/v2Containers/Rcs/tests/CarouselDimensionSelection.test.js +119 -0
  112. package/v2Containers/Rcs/tests/__snapshots__/index.test.js.snap +74440 -39387
  113. package/v2Containers/Rcs/tests/__snapshots__/utils.test.js.snap +10 -74
  114. package/v2Containers/Rcs/tests/carouselUtils.test.js +916 -0
  115. package/v2Containers/Rcs/tests/index.test.js +275 -40
  116. package/v2Containers/Rcs/tests/mockData.js +38 -0
  117. package/v2Containers/Rcs/tests/rcsLibraryHydrationUtils.test.js +912 -0
  118. package/v2Containers/Rcs/tests/utils.test.js +682 -30
  119. package/v2Containers/Rcs/utils.js +514 -12
  120. package/v2Containers/Sms/Create/index.js +115 -48
  121. package/v2Containers/Sms/smsFormDataHelpers.js +67 -0
  122. package/v2Containers/Sms/tests/smsFormDataHelpers.test.js +253 -0
  123. package/v2Containers/SmsTrai/Create/index.js +9 -4
  124. package/v2Containers/SmsTrai/Edit/constants.js +2 -0
  125. package/v2Containers/SmsTrai/Edit/index.js +678 -169
  126. package/v2Containers/SmsTrai/Edit/index.scss +126 -0
  127. package/v2Containers/SmsTrai/Edit/messages.js +14 -4
  128. package/v2Containers/SmsTrai/Edit/tests/__snapshots__/index.test.js.snap +5615 -3014
  129. package/v2Containers/SmsWrapper/index.js +37 -8
  130. package/v2Containers/TagList/index.js +5 -0
  131. package/v2Containers/Templates/TemplatesActionBar.js +101 -0
  132. package/v2Containers/Templates/_templates.scss +196 -12
  133. package/v2Containers/Templates/actions.js +11 -0
  134. package/v2Containers/Templates/constants.js +2 -0
  135. package/v2Containers/Templates/index.js +131 -59
  136. package/v2Containers/Templates/sagas.js +57 -13
  137. package/v2Containers/Templates/tests/TemplatesActionBar.test.js +129 -0
  138. package/v2Containers/Templates/tests/__snapshots__/index.test.js.snap +1060 -1015
  139. package/v2Containers/Templates/tests/sagas.test.js +199 -16
  140. package/v2Containers/Templates/tests/smsTemplatesListApi.test.js +180 -0
  141. package/v2Containers/Templates/utils/smsTemplatesListApi.js +79 -0
  142. package/v2Containers/TemplatesV2/TemplatesV2.style.js +72 -1
  143. package/v2Containers/TemplatesV2/index.js +88 -25
  144. package/v2Containers/TemplatesV2/tests/TemplatesV2.localTemplates.test.js +131 -0
  145. package/v2Containers/WeChat/MapTemplates/test/saga.test.js +9 -9
  146. package/v2Containers/Whatsapp/index.js +3 -20
  147. package/v2Containers/Whatsapp/tests/__snapshots__/index.test.js.snap +578 -34
@@ -0,0 +1,136 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import CapHeading from '@capillarytech/cap-ui-library/CapHeading';
4
+ import CapVideoUpload from '../../../v2Components/CapVideoUpload';
5
+ import CapImageUpload from '../../../v2Components/CapImageUpload';
6
+ import {
7
+ RCS,
8
+ RCS_MEDIA_TYPES,
9
+ ALLOWED_EXTENSIONS_VIDEO_REGEX,
10
+ RCS_CAROUSEL_VIDEO_SIZE,
11
+ ALLOWED_IMAGE_EXTENSIONS_REGEX,
12
+ RCS_CAROUSEL_VIDEO_THUMBNAIL_DIMENSIONS,
13
+ RCS_THUMBNAIL_MAX_SIZE,
14
+ RCS_THUMBNAIL_MIN_SIZE,
15
+ RCS_CAROUSEL_IMAGE_DIMENSIONS,
16
+ RCS_CAROUSEL_IMG_SIZE,
17
+ } from '../constants';
18
+ import {
19
+ getCarouselImageAssetIndex,
20
+ getCarouselVideoAssetIndex,
21
+ getCarouselThumbnailAssetIndex,
22
+ } from '../carouselUtils';
23
+ import messages from '../messages';
24
+
25
+ const CarouselCardMedia = ({
26
+ cardIndex,
27
+ card,
28
+ dimKey,
29
+ isFullMode,
30
+ isEditFlow,
31
+ rcsData,
32
+ uploadRcsImage,
33
+ uploadRcsVideo,
34
+ formatMessage,
35
+ onFieldChange,
36
+ }) => {
37
+ if (card.mediaType === RCS_MEDIA_TYPES.VIDEO) {
38
+ return (
39
+ <>
40
+ <CapHeading type="h4" className="rcs-image-dimensions-label">Upload Video</CapHeading>
41
+ <CapVideoUpload
42
+ index={getCarouselVideoAssetIndex(cardIndex)}
43
+ allowedExtensionsRegex={ALLOWED_EXTENSIONS_VIDEO_REGEX}
44
+ videoSize={RCS_CAROUSEL_VIDEO_SIZE}
45
+ isFullMode={isFullMode}
46
+ uploadAsset={uploadRcsVideo}
47
+ uploadedAssetList={card.videoAsset || {}}
48
+ onVideoUploadUpdateAssestList={(_, val) => {
49
+ onFieldChange('videoAsset', val);
50
+ }}
51
+ videoData={rcsData}
52
+ className="cap-custom-video-upload"
53
+ formClassName={"rcs-video-upload"}
54
+ channel={RCS}
55
+ errorMessage={formatMessage(messages.videoErrorMessage)}
56
+ showVideoNameAndDuration={false}
57
+ showReUploadButton={!isEditFlow && isFullMode}
58
+ channelSpecificStyle={!isFullMode}
59
+ />
60
+
61
+ <CapHeading type="h4" className="rcs-image-dimensions-label">Upload Thumbnail</CapHeading>
62
+ <CapImageUpload
63
+ allowedExtensionsRegex={ALLOWED_IMAGE_EXTENSIONS_REGEX}
64
+ imgWidth={RCS_CAROUSEL_VIDEO_THUMBNAIL_DIMENSIONS?.[dimKey]?.width}
65
+ imgHeight={RCS_CAROUSEL_VIDEO_THUMBNAIL_DIMENSIONS?.[dimKey]?.height}
66
+ imgSize={RCS_THUMBNAIL_MAX_SIZE}
67
+ uploadAsset={uploadRcsImage}
68
+ isFullMode={isFullMode}
69
+ imageSrc={card.thumbnailSrc}
70
+ updateImageSrc={(val) => onFieldChange('thumbnailSrc', val)}
71
+ updateOnReUpload={() => onFieldChange('thumbnailSrc', '')}
72
+ minImgSize={RCS_THUMBNAIL_MIN_SIZE}
73
+ index={getCarouselThumbnailAssetIndex(cardIndex)}
74
+ className="cap-custom-image-upload"
75
+ key={`rcs-carousel-thumb-${cardIndex}-${dimKey}`}
76
+ imageData={rcsData}
77
+ channel={RCS}
78
+ channelSpecificStyle={!isFullMode}
79
+ skipDimensionValidation={true}
80
+ showReUploadButton={!isEditFlow && isFullMode}
81
+ disabled={isEditFlow || !isFullMode}
82
+ />
83
+ </>
84
+ );
85
+ }
86
+
87
+ // Default: IMAGE
88
+ return (
89
+ <>
90
+ <CapHeading type="h4" className="rcs-image-dimensions-label">{formatMessage(messages.mediaImage)}</CapHeading>
91
+ <CapImageUpload
92
+ allowedExtensionsRegex={ALLOWED_IMAGE_EXTENSIONS_REGEX}
93
+ imgWidth={RCS_CAROUSEL_IMAGE_DIMENSIONS?.[dimKey]?.width}
94
+ imgHeight={RCS_CAROUSEL_IMAGE_DIMENSIONS?.[dimKey]?.height}
95
+ imgSize={RCS_CAROUSEL_IMG_SIZE}
96
+ uploadAsset={uploadRcsImage}
97
+ isFullMode={isFullMode}
98
+ imageSrc={card.imageSrc}
99
+ updateImageSrc={(val) => onFieldChange('imageSrc', val)}
100
+ updateOnReUpload={() => onFieldChange('imageSrc', '')}
101
+ index={getCarouselImageAssetIndex(cardIndex)}
102
+ className="cap-custom-image-upload"
103
+ key={`rcs-carousel-image-${cardIndex}-${dimKey}`}
104
+ imageData={rcsData}
105
+ channel={RCS}
106
+ channelSpecificStyle={!isFullMode}
107
+ skipDimensionValidation={true}
108
+ showReUploadButton={!isEditFlow && isFullMode}
109
+ disabled={isEditFlow || !isFullMode}
110
+ />
111
+ </>
112
+ );
113
+ };
114
+
115
+ CarouselCardMedia.propTypes = {
116
+ cardIndex: PropTypes.number.isRequired,
117
+ card: PropTypes.object,
118
+ dimKey: PropTypes.string,
119
+ isFullMode: PropTypes.bool,
120
+ isEditFlow: PropTypes.bool,
121
+ rcsData: PropTypes.object,
122
+ uploadRcsImage: PropTypes.func.isRequired,
123
+ uploadRcsVideo: PropTypes.func.isRequired,
124
+ formatMessage: PropTypes.func.isRequired,
125
+ onFieldChange: PropTypes.func.isRequired,
126
+ };
127
+
128
+ CarouselCardMedia.defaultProps = {
129
+ card: {},
130
+ dimKey: '',
131
+ isFullMode: false,
132
+ isEditFlow: false,
133
+ rcsData: {},
134
+ };
135
+
136
+ export default React.memo(CarouselCardMedia);
@@ -0,0 +1,31 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import CapLabel from '@capillarytech/cap-ui-library/CapLabel';
4
+ import messages from '../messages';
5
+
6
+ const CarouselCharacterCount = ({
7
+ formatMessage,
8
+ currentLength,
9
+ maxLength,
10
+ className,
11
+ }) => (
12
+ <CapLabel type="label1" className={className}>
13
+ {formatMessage(messages.templateMessageLength, {
14
+ currentLength,
15
+ maxLength,
16
+ })}
17
+ </CapLabel>
18
+ );
19
+
20
+ CarouselCharacterCount.propTypes = {
21
+ formatMessage: PropTypes.func.isRequired,
22
+ currentLength: PropTypes.number.isRequired,
23
+ maxLength: PropTypes.number.isRequired,
24
+ className: PropTypes.string,
25
+ };
26
+
27
+ CarouselCharacterCount.defaultProps = {
28
+ className: 'rcs-character-count',
29
+ };
30
+
31
+ export default React.memo(CarouselCharacterCount);
@@ -0,0 +1,80 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import CapRow from '@capillarytech/cap-ui-library/CapRow';
4
+ import CapColumn from '@capillarytech/cap-ui-library/CapColumn';
5
+ import CapHeading from '@capillarytech/cap-ui-library/CapHeading';
6
+ import CapLabel from '@capillarytech/cap-ui-library/CapLabel';
7
+ import CapSelect from '@capillarytech/cap-ui-library/CapSelect';
8
+ import { CAROUSEL_HEIGHT_OPTIONS, CAROUSEL_WIDTH_OPTIONS } from '../constants';
9
+
10
+ const CarouselDimensionSelection = ({
11
+ isEditFlow,
12
+ isFullMode,
13
+ selectedCarouselHeight,
14
+ selectedCarouselWidth,
15
+ selectedCarousel,
16
+ onHeightChange,
17
+ onWidthChange,
18
+ }) => (
19
+ <CapRow className="rcs-carousel-dimension-section">
20
+ <CapRow gutter={16} className="rcs-carousel-dimension-row">
21
+ <CapColumn span={12}>
22
+ <CapHeading type="h4" className="rcs-carousel-dimension-label">Card height</CapHeading>
23
+ {isEditFlow ? (
24
+ <CapHeading type="h5" className="rcs-creative-name-value">
25
+ {CAROUSEL_HEIGHT_OPTIONS.find((option) => option.value === selectedCarouselHeight)?.label || '-'}
26
+ </CapHeading>
27
+ ) : (
28
+ <CapSelect
29
+ id="rcs-carousel-height-select"
30
+ value={selectedCarouselHeight}
31
+ onChange={onHeightChange}
32
+ options={CAROUSEL_HEIGHT_OPTIONS}
33
+ disabled={!isFullMode}
34
+ />
35
+ )}
36
+ </CapColumn>
37
+ <CapColumn span={12}>
38
+ <CapHeading type="h4" className="rcs-carousel-dimension-label">Card width</CapHeading>
39
+ {isEditFlow ? (
40
+ <CapHeading type="h5" className="rcs-creative-name-value">
41
+ {CAROUSEL_WIDTH_OPTIONS.find((option) => option.value === selectedCarouselWidth)?.label || '-'}
42
+ </CapHeading>
43
+ ) : (
44
+ <CapSelect
45
+ id="rcs-carousel-width-select"
46
+ value={selectedCarouselWidth}
47
+ onChange={onWidthChange}
48
+ options={CAROUSEL_WIDTH_OPTIONS}
49
+ disabled={!isFullMode}
50
+ />
51
+ )}
52
+ </CapColumn>
53
+ </CapRow>
54
+ {!!selectedCarousel && (
55
+ <CapLabel type="label3" className="rcs-carousel-selected-dimension">
56
+ Selected: {selectedCarousel}
57
+ </CapLabel>
58
+ )}
59
+ </CapRow>
60
+ );
61
+
62
+ CarouselDimensionSelection.propTypes = {
63
+ isEditFlow: PropTypes.bool,
64
+ isFullMode: PropTypes.bool,
65
+ selectedCarouselHeight: PropTypes.string,
66
+ selectedCarouselWidth: PropTypes.string,
67
+ selectedCarousel: PropTypes.string,
68
+ onHeightChange: PropTypes.func.isRequired,
69
+ onWidthChange: PropTypes.func.isRequired,
70
+ };
71
+
72
+ CarouselDimensionSelection.defaultProps = {
73
+ isEditFlow: false,
74
+ isFullMode: false,
75
+ selectedCarouselHeight: '',
76
+ selectedCarouselWidth: '',
77
+ selectedCarousel: '',
78
+ };
79
+
80
+ export default React.memo(CarouselDimensionSelection);
@@ -1,5 +1,6 @@
1
1
  import React from 'react';
2
2
  import { FormattedMessage } from 'react-intl';
3
+ import cloneDeep from 'lodash/cloneDeep';
3
4
  import messages from "./messages";
4
5
 
5
6
  export const RCS = 'RCS';
@@ -20,11 +21,6 @@ export const TEMPLATE_HEADER_MAX_LENGTH = 60;
20
21
  export const TEMPLATE_MESSAGE_MAX_LENGTH = 1024;
21
22
  export const UNSUBSCRIBE_TEXT_LENGTH = 36;
22
23
 
23
- export const RCS_DLT_MODE = {
24
- TEMPLATES: 'templates',
25
- EDIT: 'editTemplate',
26
- };
27
-
28
24
  export const RCS_STATUSES = {
29
25
  approved: 'approved',
30
26
  rejected: 'rejected',
@@ -34,18 +30,16 @@ export const RCS_STATUSES = {
34
30
  awaitingApproval: 'awaitingApproval',
35
31
  };
36
32
 
33
+ export const HOST_ICS="rcsicsbulk";
34
+ export const HOST_INFOBIP="rcsinfobipbulk";
35
+
37
36
  export const contentType = {
38
37
  text_message: 'text_message',
39
38
  rich_card: 'rich_card',
40
- carousel: 'carousel',
39
+ carousel: 'CAROUSEL',
41
40
  };
42
41
 
43
42
  export const STATUS_OPTIONS = [
44
- // {
45
- // key: 'created',
46
- // value: RCS_STATUSES.awaitingApproval,
47
- // label: <FormattedMessage {...messages.created} />,
48
- // },
49
43
  {
50
44
  key: 'approved',
51
45
  value: RCS_STATUSES.approved,
@@ -72,12 +66,40 @@ export const RCS_MEDIA_TYPES = {
72
66
  NONE: 'NONE',
73
67
  IMAGE: 'IMAGE',
74
68
  VIDEO: 'VIDEO',
69
+ TEXT: 'TEXT',
75
70
  };
76
71
 
77
- export const rcsVarRegex = /\{\{\w+\}\}/g;
78
- export const rcsVarTestRegex = /\{\{\w+\}\}/;
72
+ /** Match `{{}}` placeholders including Liquid-style names (e.g. `tag.FORMAT_1`). Must align with split + `isAnyTemplateVarToken` / SMS fallback. */
73
+ export const rcsVarRegex = /\{\{[^}]+\}\}/g;
74
+ /** True when the whole string is a single RCS/mustache token (used when testing segment tokens). */
75
+ export const rcsVarTestRegex = /^\{\{[^}]+\}\}$/;
76
+
77
+ /** Matches all `{{N}}` numeric-index variable tokens in a template string (global). */
78
+ export const RCS_NUMERIC_VAR_TOKEN_REGEX = /\{\{(\d+)\}\}/g;
79
+ /** `cardVarMapped` slot keys that are numeric only (legacy ordering). */
80
+ export const RCS_NUMERIC_VAR_NAME_REGEX = /^\d+$/;
81
+ /** Semantic Liquid-style keys on RCS `cardVarMapped` (same class as `{{…}}` inner names in the editor). */
82
+ export const RCS_CARD_VAR_MAPPED_SEMANTIC_KEY_REGEX = /^[\w.]+$/;
83
+ /** Escape all special RegExp characters in an arbitrary string before using it in `new RegExp(...)`. */
84
+ export const REGEX_SPECIAL_CHARS_ESCAPE_PATTERN = /[-/\\^$*+?.()|[\]{}]/g;
85
+ /** Entire string is wrapped in `{{…}}` mustache delimiters (allows any content including `}`). */
86
+ export const RCS_MUSTACHE_WRAPPED_REGEX = /^\{\{[\s\S]*\}\}$/;
87
+ /** Strip leading `{{` and trailing `}}` from a token. */
88
+ export const RCS_STRIP_MUSTACHE_DELIMITERS_REGEX = /^\{\{|\}\}$/g;
89
+
90
+ export const JS_TYPES = {
91
+ STRING: 'string',
92
+ NUMBER: 'number',
93
+ OBJECT: 'object',
94
+ };
95
+
96
+ /** Tag-popover target: title vs description field (matches `onTagSelect` `field` argument). */
97
+ export const RCS_TAG_AREA_FIELD_TITLE = 'title';
98
+ export const RCS_TAG_AREA_FIELD_DESC = 'desc';
99
+
79
100
  export const TEMPLATE_DESC_MAX_LENGTH = 2500;
80
- export const FALLBACK_MESSAGE_MAX_LENGTH = 160;
101
+ /** Resolved SMS fallback body cap. Must allow multi-segment DLT (>160); aligns with TRAI / `TEMPLATE_MESSAGE_MAX_LENGTH`. */
102
+ export const FALLBACK_MESSAGE_MAX_LENGTH = TEMPLATE_MESSAGE_MAX_LENGTH;
81
103
  export const TEMPLATE_TITLE_MAX_LENGTH = 200;
82
104
  export const TEMPLATE_BUTTON_TEXT_MAX_LENGTH = 25;
83
105
  export const CTA = 'CTA';
@@ -92,10 +114,12 @@ export const ALLOWED_IMAGE_EXTENSIONS_REGEX = (/\.(png|jpg|jpeg|gif)$/i);
92
114
  export const RCS_IMG_WIDTH = 1440;
93
115
  export const RCS_IMG_HEIGHT = 1024;
94
116
  export const RCS_IMG_SIZE = 2000000; // 2MB
117
+ export const RCS_CAROUSEL_IMG_SIZE = 1 * 1024 * 1024; // 1MB
95
118
  export const MAX_FILE_SIZE_MB = 10;
96
119
  export const MAX_FILE_SIZE_BYTES = MAX_FILE_SIZE_MB * 1024 * 1024;
97
120
  export const ALLOWED_EXTENSIONS_VIDEO_REGEX = (/\.(mp4)$/i);
98
121
  export const RCS_VIDEO_SIZE = 10 * 1024 * 1024;
122
+ export const RCS_CAROUSEL_VIDEO_SIZE = 5 * 1024 * 1024; // 5MB
99
123
  export const RCS_THUMBNAIL_MIN_SIZE = 40 * 1024;
100
124
  export const RCS_THUMBNAIL_MAX_SIZE = 100 * 1024;
101
125
 
@@ -142,13 +166,38 @@ export const RCS_IMAGE_DIMENSIONS = {
142
166
  },
143
167
  };
144
168
 
169
+ // Carousel image dimensions (pixel values shown in UI). Keys follow `${HEIGHT}_${WIDTH}`.
170
+ // HEIGHT: SHORT|MEDIUM, WIDTH: SMALL|MEDIUM
171
+ export const RCS_CAROUSEL_IMAGE_DIMENSIONS = {
172
+ SHORT_SMALL: {
173
+ width: 1160,
174
+ height: 720,
175
+ description: 'Image (1160 x 720)',
176
+ },
177
+ SHORT_MEDIUM: {
178
+ width: 1800,
179
+ height: 720,
180
+ description: 'Image (1800 x 720)',
181
+ },
182
+ MEDIUM_SMALL: {
183
+ width: 770,
184
+ height: 720,
185
+ description: 'Image (770 x 720)',
186
+ },
187
+ MEDIUM_MEDIUM: {
188
+ width: 1280,
189
+ height: 720,
190
+ description: 'Image (1280 x 720)',
191
+ },
192
+ };
193
+
145
194
  export const RCS_VIDEO_THUMBNAIL_DIMENSIONS = {
146
195
  SHORT_HEIGHT: {
147
- width: 770,
148
- height: 257,
149
196
  type: 'SHORT_HEIGHT',
150
197
  heightType: 'SHORT',
151
198
  label: 'Vertical Short',
199
+ width: 1140,
200
+ height: 448,
152
201
  description: 'Thumbnail (770 x 257)',
153
202
  orientation: 'VERTICAL',
154
203
  maxFileSize: 100 * 1024,
@@ -189,6 +238,29 @@ export const RCS_VIDEO_THUMBNAIL_DIMENSIONS = {
189
238
  },
190
239
  };
191
240
 
241
+ // Carousel thumbnail dimensions for video cards (pixel values shown in UI).
242
+ // Keys follow `${HEIGHT}_${WIDTH}`.
243
+ // Human-readable labels: formatMessage(messages.rcsCarouselVideoThumbnailLabel, { width, height })
244
+ // or formatRcsCarouselVideoThumbnailLabel(formatMessage, entry) from ./utils.
245
+ export const RCS_CAROUSEL_VIDEO_THUMBNAIL_DIMENSIONS = {
246
+ SHORT_SMALL: {
247
+ width: 718,
248
+ height: 448,
249
+ },
250
+ SHORT_MEDIUM: {
251
+ width: 1140,
252
+ height: 448,
253
+ },
254
+ MEDIUM_SMALL: {
255
+ width: 480,
256
+ height: 448,
257
+ },
258
+ MEDIUM_MEDIUM: {
259
+ width: 796,
260
+ height: 448,
261
+ },
262
+ };
263
+
192
264
  const prefix = 'app/v2Containers/Rcs';
193
265
  export const UPLOAD_RCS_ASSET_REQUEST = `${prefix}/UPLOAD_RCS_ASSET_REQUEST`;
194
266
  export const UPLOAD_RCS_ASSET_SUCCESS = `${prefix}/UPLOAD_RCS_ASSET_SUCCESS`;
@@ -215,6 +287,7 @@ export const CLEAR_EDIT_RESPONSE_REQUEST = `${prefix}/Edit/CLEAR_EDIT_RESPONSE_R
215
287
  export const AI_CONTENT_BOT_DISABLED = "AI_CONTENT_BOT_DISABLED";
216
288
 
217
289
  export const RCS_TEXT_MESSAGE_MAX_LENGTH = 160;
290
+ export const RCS_TEXT_MESSAGE_MAX_LENGTH_INFOBIP = 3072;
218
291
  export const RCS_RICH_CARD_MAX_LENGTH = 2000;
219
292
  export const MAX_BUTTONS = 4;
220
293
 
@@ -250,3 +323,46 @@ export const RCS_BUTTON_TYPES = {
250
323
  PHONE_NUMBER: 'PHONE_NUMBER',
251
324
  CTA: 'CTA',
252
325
  };
326
+
327
+ /** Default action row for carousel card 1 (mandatory button UX): phone CTA, unsaved until user completes + Save. */
328
+ export const RCS_CAROUSEL_FIRST_CARD_DEFAULT_SUGGESTIONS = [
329
+ {
330
+ index: 0,
331
+ type: RCS_BUTTON_TYPES.PHONE_NUMBER,
332
+ text: '',
333
+ phoneNumber: '',
334
+ url: null,
335
+ postback: '',
336
+ isSaved: false,
337
+ },
338
+ ];
339
+
340
+ export const MAX_RCS_CAROUSEL_ALLOWED = 10;
341
+ // Uploads for RCS are stored in redux under dynamic keys `uploadedAssetData${index}`.
342
+ // Carousel needs per-card indices; otherwise all cards "restore" the last uploaded asset
343
+ // and show the same media/thumbnail.
344
+ export const RCS_CAROUSEL_ASSET_INDEX_BASE = 10; // keep away from standalone indices 0 (media) and 1 (thumbnail)
345
+
346
+ export const RCS_CAROUSEL_INITIAL_CARD = {
347
+ title: '',
348
+ description: '',
349
+ mediaType: RCS_MEDIA_TYPES.IMAGE, // per-card
350
+ imageSrc: '',
351
+ videoAsset: {}, // CapVideoUpload object shape
352
+ thumbnailSrc: '',
353
+ suggestions: [],
354
+ };
355
+
356
+ export const RCS_CAROUSEL_INITIAL_FIRST_CARD = {
357
+ ...RCS_CAROUSEL_INITIAL_CARD,
358
+ suggestions: cloneDeep(RCS_CAROUSEL_FIRST_CARD_DEFAULT_SUGGESTIONS),
359
+ };
360
+
361
+ export const CAROUSEL_HEIGHT_OPTIONS = [
362
+ { value: 'SHORT', label: 'Short' },
363
+ { value: 'MEDIUM', label: 'Medium' },
364
+ ];
365
+ export const CAROUSEL_WIDTH_OPTIONS = [
366
+ { value: 'SMALL', label: 'Small' },
367
+ { value: 'MEDIUM', label: 'Medium' },
368
+ ];