@capillarytech/creatives-library 8.0.241 → 8.0.242-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 (119) hide show
  1. package/package.json +1 -1
  2. package/sagas/__tests__/assetPolling.test.js +607 -0
  3. package/sagas/assetPolling.js +156 -0
  4. package/services/api.js +16 -0
  5. package/services/tests/api.test.js +124 -0
  6. package/translations/en.json +1 -0
  7. package/utils/assetStatusConstants.js +12 -0
  8. package/utils/asyncAssetUpload.js +161 -0
  9. package/utils/tests/asyncAssetUpload.test.js +292 -0
  10. package/utils/transformerUtils.js +42 -0
  11. package/v2Components/CapImageUpload/constants.js +2 -0
  12. package/v2Components/CapImageUpload/index.js +54 -14
  13. package/v2Components/CapImageUpload/index.scss +4 -1
  14. package/v2Components/CapImageUpload/messages.js +4 -0
  15. package/v2Components/CapImageUrlUpload/constants.js +19 -0
  16. package/v2Components/CapImageUrlUpload/index.js +455 -0
  17. package/v2Components/CapImageUrlUpload/index.scss +35 -0
  18. package/v2Components/CapImageUrlUpload/messages.js +47 -0
  19. package/v2Containers/App/constants.js +5 -0
  20. package/v2Containers/Cap/tests/__snapshots__/index.test.js.snap +1 -0
  21. package/v2Containers/CreativesContainer/SlideBoxContent.js +57 -2
  22. package/v2Containers/CreativesContainer/SlideBoxHeader.js +1 -0
  23. package/v2Containers/CreativesContainer/constants.js +2 -0
  24. package/v2Containers/CreativesContainer/index.js +152 -0
  25. package/v2Containers/CreativesContainer/messages.js +4 -0
  26. package/v2Containers/Line/Container/ImageCarousel/tests/__snapshots__/content.test.js.snap +3 -0
  27. package/v2Containers/Line/Container/ImageCarousel/tests/__snapshots__/index.test.js.snap +2 -0
  28. package/v2Containers/Line/Container/Wrapper/tests/__snapshots__/index.test.js.snap +25 -0
  29. package/v2Containers/Line/Container/tests/__snapshots__/index.test.js.snap +18 -0
  30. package/v2Containers/Rcs/tests/__snapshots__/index.test.js.snap +46 -0
  31. package/v2Containers/SmsTrai/Create/tests/__snapshots__/index.test.js.snap +4 -0
  32. package/v2Containers/SmsTrai/Edit/tests/__snapshots__/index.test.js.snap +8 -0
  33. package/v2Containers/Templates/ChannelTypeIllustration.js +13 -1
  34. package/v2Containers/Templates/_templates.scss +203 -0
  35. package/v2Containers/Templates/actions.js +2 -1
  36. package/v2Containers/Templates/constants.js +1 -0
  37. package/v2Containers/Templates/index.js +273 -30
  38. package/v2Containers/Templates/messages.js +24 -0
  39. package/v2Containers/Templates/reducer.js +2 -0
  40. package/v2Containers/Templates/tests/index.test.js +10 -0
  41. package/v2Containers/TemplatesV2/index.js +3 -2
  42. package/v2Containers/TemplatesV2/messages.js +4 -0
  43. package/v2Containers/WebPush/Create/components/ButtonForm.js +175 -0
  44. package/v2Containers/WebPush/Create/components/ButtonItem.js +101 -0
  45. package/v2Containers/WebPush/Create/components/ButtonList.js +144 -0
  46. package/v2Containers/WebPush/Create/components/_buttons.scss +246 -0
  47. package/v2Containers/WebPush/Create/components/tests/ButtonForm.test.js +554 -0
  48. package/v2Containers/WebPush/Create/components/tests/ButtonItem.test.js +607 -0
  49. package/v2Containers/WebPush/Create/components/tests/ButtonList.test.js +633 -0
  50. package/v2Containers/WebPush/Create/components/tests/__snapshots__/ButtonForm.test.js.snap +666 -0
  51. package/v2Containers/WebPush/Create/components/tests/__snapshots__/ButtonItem.test.js.snap +74 -0
  52. package/v2Containers/WebPush/Create/components/tests/__snapshots__/ButtonList.test.js.snap +80 -0
  53. package/v2Containers/WebPush/Create/index.js +1755 -0
  54. package/v2Containers/WebPush/Create/index.scss +123 -0
  55. package/v2Containers/WebPush/Create/messages.js +199 -0
  56. package/v2Containers/WebPush/Create/preview/DevicePreviewContent.js +241 -0
  57. package/v2Containers/WebPush/Create/preview/NotificationContainer.js +290 -0
  58. package/v2Containers/WebPush/Create/preview/PreviewContent.js +81 -0
  59. package/v2Containers/WebPush/Create/preview/PreviewControls.js +240 -0
  60. package/v2Containers/WebPush/Create/preview/PreviewDisclaimer.js +23 -0
  61. package/v2Containers/WebPush/Create/preview/WebPushPreview.js +144 -0
  62. package/v2Containers/WebPush/Create/preview/assets/Light.svg +53 -0
  63. package/v2Containers/WebPush/Create/preview/assets/Top.svg +5 -0
  64. package/v2Containers/WebPush/Create/preview/assets/chrome-icon.png +0 -0
  65. package/v2Containers/WebPush/Create/preview/assets/edge-icon.png +0 -0
  66. package/v2Containers/WebPush/Create/preview/assets/firefox-icon.svg +106 -0
  67. package/v2Containers/WebPush/Create/preview/assets/iOS.svg +26 -0
  68. package/v2Containers/WebPush/Create/preview/assets/opera-icon.svg +18 -0
  69. package/v2Containers/WebPush/Create/preview/assets/safari-icon.svg +29 -0
  70. package/v2Containers/WebPush/Create/preview/components/AndroidMobileChromeHeader.js +44 -0
  71. package/v2Containers/WebPush/Create/preview/components/AndroidMobileExpanded.js +110 -0
  72. package/v2Containers/WebPush/Create/preview/components/IOSHeader.js +45 -0
  73. package/v2Containers/WebPush/Create/preview/components/NotificationExpandedContent.js +72 -0
  74. package/v2Containers/WebPush/Create/preview/components/NotificationHeader.js +55 -0
  75. package/v2Containers/WebPush/Create/preview/components/WindowsChromeExpanded.js +70 -0
  76. package/v2Containers/WebPush/Create/preview/components/tests/AndroidMobileExpanded.test.js +512 -0
  77. package/v2Containers/WebPush/Create/preview/components/tests/__snapshots__/AndroidMobileExpanded.test.js.snap +77 -0
  78. package/v2Containers/WebPush/Create/preview/config/notificationMappings.js +527 -0
  79. package/v2Containers/WebPush/Create/preview/constants.js +162 -0
  80. package/v2Containers/WebPush/Create/preview/notification-container.scss +104 -0
  81. package/v2Containers/WebPush/Create/preview/preview.scss +409 -0
  82. package/v2Containers/WebPush/Create/preview/styles/_android-mobile-chrome.scss +300 -0
  83. package/v2Containers/WebPush/Create/preview/styles/_android-mobile-edge.scss +12 -0
  84. package/v2Containers/WebPush/Create/preview/styles/_android-mobile-firefox.scss +12 -0
  85. package/v2Containers/WebPush/Create/preview/styles/_android-mobile-opera.scss +12 -0
  86. package/v2Containers/WebPush/Create/preview/styles/_android-tablet-chrome.scss +303 -0
  87. package/v2Containers/WebPush/Create/preview/styles/_android-tablet-edge.scss +11 -0
  88. package/v2Containers/WebPush/Create/preview/styles/_android-tablet-firefox.scss +11 -0
  89. package/v2Containers/WebPush/Create/preview/styles/_android-tablet-opera.scss +11 -0
  90. package/v2Containers/WebPush/Create/preview/styles/_base.scss +188 -0
  91. package/v2Containers/WebPush/Create/preview/styles/_ios.scss +106 -0
  92. package/v2Containers/WebPush/Create/preview/styles/_ipados.scss +107 -0
  93. package/v2Containers/WebPush/Create/preview/styles/_macos-chrome.scss +75 -0
  94. package/v2Containers/WebPush/Create/preview/styles/_windows-chrome.scss +174 -0
  95. package/v2Containers/WebPush/Create/preview/tests/DevicePreviewContent.test.js +909 -0
  96. package/v2Containers/WebPush/Create/preview/tests/NotificationContainer.test.js +1077 -0
  97. package/v2Containers/WebPush/Create/preview/tests/PreviewControls.test.js +723 -0
  98. package/v2Containers/WebPush/Create/preview/tests/WebPushPreview.test.js +943 -0
  99. package/v2Containers/WebPush/Create/preview/tests/__snapshots__/DevicePreviewContent.test.js.snap +128 -0
  100. package/v2Containers/WebPush/Create/preview/tests/__snapshots__/NotificationContainer.test.js.snap +121 -0
  101. package/v2Containers/WebPush/Create/preview/tests/__snapshots__/PreviewControls.test.js.snap +144 -0
  102. package/v2Containers/WebPush/Create/preview/tests/__snapshots__/WebPushPreview.test.js.snap +127 -0
  103. package/v2Containers/WebPush/Create/utils/urlValidation.js +116 -0
  104. package/v2Containers/WebPush/Create/utils/urlValidation.test.js +449 -0
  105. package/v2Containers/WebPush/actions.js +60 -0
  106. package/v2Containers/WebPush/constants.js +108 -0
  107. package/v2Containers/WebPush/index.js +2 -0
  108. package/v2Containers/WebPush/reducer.js +104 -0
  109. package/v2Containers/WebPush/sagas.js +119 -0
  110. package/v2Containers/WebPush/selectors.js +65 -0
  111. package/v2Containers/WebPush/tests/reducer.test.js +863 -0
  112. package/v2Containers/WebPush/tests/sagas.test.js +566 -0
  113. package/v2Containers/WebPush/tests/selectors.test.js +960 -0
  114. package/v2Containers/Whatsapp/constants.js +9 -0
  115. package/v2Containers/Whatsapp/reducer.js +34 -5
  116. package/v2Containers/Whatsapp/sagas.js +61 -10
  117. package/v2Containers/Whatsapp/tests/__snapshots__/index.test.js.snap +132 -0
  118. package/v2Containers/Whatsapp/tests/reducer.test.js +188 -0
  119. package/v2Containers/Whatsapp/tests/saga.test.js +420 -7
@@ -9,6 +9,8 @@ import {
9
9
  CAP_GREEN02,
10
10
  } from '@capillarytech/cap-ui-library/styled/variables';
11
11
  import messages from './messages';
12
+ import { createAsyncAssetUploadConstants } from '../../utils/asyncAssetUpload';
13
+
12
14
  export const UNSUBSCRIBE_TEXT_LENGTH = 36;
13
15
  export const TEMPLATE_MESSAGE_MAX_LENGTH = 1024;
14
16
  export const WHATSAPP = 'WHATSAPP';
@@ -31,6 +33,13 @@ export const UPLOAD_WHATSAPP_ASSET_SUCCESS = `${prefix}/UPLOAD_WHATSAPP_ASSET_SU
31
33
  export const UPLOAD_WHATSAPP_ASSET_FAILURE = `${prefix}/UPLOAD_WHATSAPP_ASSET_FAILURE`;
32
34
  export const CLEAR_WHATSAPP_ASSET = `${prefix}/CLEAR_WHATSAPP_ASSET`;
33
35
 
36
+ // P4.2: Async upload processing actions - Using generic utility for reusability
37
+ const asyncUploadConstants = createAsyncAssetUploadConstants('WHATSAPP', prefix);
38
+ export const UPLOAD_WHATSAPP_ASSET_PROCESSING = asyncUploadConstants.UPLOAD_WHATSAPP_ASSET_PROCESSING;
39
+ export const UPLOAD_WHATSAPP_ASSET_COMPLETED = asyncUploadConstants.UPLOAD_WHATSAPP_ASSET_COMPLETED;
40
+ export const UPLOAD_WHATSAPP_ASSET_FAILED = asyncUploadConstants.UPLOAD_WHATSAPP_ASSET_FAILED;
41
+ export const UPLOAD_WHATSAPP_ASSET_TIMEOUT = asyncUploadConstants.UPLOAD_WHATSAPP_ASSET_TIMEOUT;
42
+
34
43
  //For meta tags
35
44
  export const URL_META_TAGS_REQUEST = `${prefix}/URL_META_TAGS_REQUEST`;
36
45
  export const URL_META_TAGS_SUCCESS = `${prefix}/URL_META_TAGS_SUCCESS`;
@@ -11,12 +11,25 @@ import {
11
11
  UPLOAD_WHATSAPP_ASSET_REQUEST,
12
12
  UPLOAD_WHATSAPP_ASSET_SUCCESS,
13
13
  UPLOAD_WHATSAPP_ASSET_FAILURE,
14
+ UPLOAD_WHATSAPP_ASSET_PROCESSING,
15
+ UPLOAD_WHATSAPP_ASSET_COMPLETED,
16
+ UPLOAD_WHATSAPP_ASSET_FAILED,
17
+ UPLOAD_WHATSAPP_ASSET_TIMEOUT,
14
18
  CLEAR_WHATSAPP_ASSET,
15
19
  URL_META_TAGS_REQUEST,
16
20
  URL_META_TAGS_SUCCESS,
17
21
  URL_META_TAGS_FAILURE,
18
22
  URL_META_TAGS_RESET,
19
23
  } from './constants';
24
+ import { createAsyncAssetUploadReducerCases } from '../../utils/asyncAssetUpload';
25
+
26
+ // Create generic reducer cases for async uploads
27
+ const asyncUploadCases = createAsyncAssetUploadReducerCases({
28
+ PROCESSING: UPLOAD_WHATSAPP_ASSET_PROCESSING,
29
+ COMPLETED: UPLOAD_WHATSAPP_ASSET_COMPLETED,
30
+ FAILED: UPLOAD_WHATSAPP_ASSET_FAILED,
31
+ TIMEOUT: UPLOAD_WHATSAPP_ASSET_TIMEOUT,
32
+ });
20
33
 
21
34
  const initialState = fromJS({
22
35
  uploadedAssetData: {},
@@ -24,6 +37,7 @@ const initialState = fromJS({
24
37
  getMetaTagsRequest: false,
25
38
  metaTagsDetails: {},
26
39
  getMetaTagsError: '',
40
+ assetProcessing: {},
27
41
  });
28
42
 
29
43
  function whatsappReducer(state = initialState, action) {
@@ -93,12 +107,27 @@ function whatsappReducer(state = initialState, action) {
93
107
  return state
94
108
  .set('uploadAssetSuccess', false)
95
109
  .set('assetUploading', false);
110
+ // P4.5: Async upload processing state management - Using generic reducer cases
111
+ case asyncUploadCases.PROCESSING:
112
+ return asyncUploadCases.handleProcessing(state, action);
113
+
114
+ case asyncUploadCases.COMPLETED:
115
+ return asyncUploadCases.handleCompleted(state, action);
116
+
117
+ case asyncUploadCases.FAILED:
118
+ return asyncUploadCases.handleFailed(state, action);
119
+
120
+ case asyncUploadCases.TIMEOUT:
121
+ return asyncUploadCases.handleTimeout(state, action);
122
+
96
123
  case CLEAR_WHATSAPP_ASSET:
97
- return state.delete(
98
- action.templateType !== undefined
99
- ? `uploadedAssetData${action.templateType}`
100
- : 'uploadedAssetData',
101
- );
124
+ return state
125
+ .delete(
126
+ action.templateType !== undefined
127
+ ? `uploadedAssetData${action.templateType}`
128
+ : 'uploadedAssetData',
129
+ )
130
+ .set('assetProcessing', fromJS({})); // Clear processing state
102
131
  default:
103
132
  return state;
104
133
  }
@@ -4,6 +4,9 @@ import {
4
4
  import isEmpty from 'lodash/isEmpty';
5
5
  import get from 'lodash/get';
6
6
  import * as Api from '../../services/api';
7
+ import { pollAssetStatus } from '../../sagas/assetPolling';
8
+ import { createPollingConfig } from '../../utils/asyncAssetUpload';
9
+ import { ASSET_STATUS } from '../../utils/assetStatusConstants';
7
10
  import {
8
11
  TEMPLATE_CREATE_REQUEST,
9
12
  TEMPLATE_CREATE_SUCCESS,
@@ -15,6 +18,10 @@ import {
15
18
  UPLOAD_WHATSAPP_ASSET_REQUEST,
16
19
  UPLOAD_WHATSAPP_ASSET_SUCCESS,
17
20
  UPLOAD_WHATSAPP_ASSET_FAILURE,
21
+ UPLOAD_WHATSAPP_ASSET_PROCESSING,
22
+ UPLOAD_WHATSAPP_ASSET_COMPLETED,
23
+ UPLOAD_WHATSAPP_ASSET_FAILED,
24
+ UPLOAD_WHATSAPP_ASSET_TIMEOUT,
18
25
  URL_META_TAGS_REQUEST,
19
26
  URL_META_TAGS_SUCCESS,
20
27
  URL_META_TAGS_FAILURE,
@@ -23,14 +30,58 @@ import {
23
30
  export function* uploadWhatsappAsset(params) {
24
31
  try {
25
32
  const result = yield call(Api.uploadFile, params);
26
- yield put({
27
- type: UPLOAD_WHATSAPP_ASSET_SUCCESS,
28
- data: result.response.asset,
29
- statusCode: result?.status?.code || '',
30
- templateType: params.templateType,
31
- });
33
+ const responseData = result.response || {};
34
+ const statusCode = result?.status?.code || result?.statusCode || 200;
35
+
36
+ if (statusCode === 202 || responseData?.processingStatus === ASSET_STATUS.PROCESSING) {
37
+ // Async flow - extract assetId first before dispatching any actions
38
+ const assetId = responseData.assetId || responseData.asset?._id;
39
+ const templateType = params.templateType; // Index for reducer state key (e.g., 0)
40
+ // Get asset type from params, fallback to asset response, then default to 'image'
41
+ const assetType = params.assetType || responseData.asset?.type?.toLowerCase() || 'image';
42
+
43
+ if (assetId) {
44
+ // Only dispatch processing action and start polling when we have a valid assetId
45
+ yield put({
46
+ type: UPLOAD_WHATSAPP_ASSET_PROCESSING,
47
+ payload: {
48
+ assetId,
49
+ asset: responseData.asset,
50
+ processingStatus: ASSET_STATUS.PROCESSING
51
+ }
52
+ });
53
+
54
+ // P4.4: Start polling using centralized saga with generic polling config
55
+ const actionTypes = {
56
+ COMPLETED: UPLOAD_WHATSAPP_ASSET_COMPLETED,
57
+ FAILED: UPLOAD_WHATSAPP_ASSET_FAILED,
58
+ TIMEOUT: UPLOAD_WHATSAPP_ASSET_TIMEOUT,
59
+ };
60
+ const pollingConfig = createPollingConfig(assetType, assetId, actionTypes, templateType);
61
+ yield call(pollAssetStatus, pollingConfig);
62
+ } else {
63
+ // No assetId returned - dispatch failure to prevent UI from being stuck in processing state
64
+ const errorMessage = 'Asset upload initiated but no asset ID was returned from the server. Unable to track processing status.';
65
+ yield put({
66
+ type: UPLOAD_WHATSAPP_ASSET_FAILED,
67
+ payload: {
68
+ assetId: undefined,
69
+ error: errorMessage,
70
+ },
71
+ templateType,
72
+ });
73
+ }
74
+ } else {
75
+ // Sync flow (201) - existing behavior unchanged
76
+ yield put({
77
+ type: UPLOAD_WHATSAPP_ASSET_SUCCESS,
78
+ data: responseData.asset,
79
+ statusCode,
80
+ templateType: params.templateType,
81
+ });
82
+ }
32
83
  } catch (error) {
33
- yield put({ UPLOAD_WHATSAPP_ASSET_FAILURE, error });
84
+ yield put({ type: UPLOAD_WHATSAPP_ASSET_FAILURE, error });
34
85
  }
35
86
  }
36
87
  function* watchUploadWhatsappAsset() {
@@ -64,7 +115,7 @@ export function* sendForApprovalCreate({ payload, callback, gupshupMediaFile })
64
115
  type: TEMPLATE_CREATE_SUCCESS,
65
116
  data: result.response,
66
117
  statusCode: result.status ? result.status.code : '',
67
- errorMsg,
118
+ errorMsg
68
119
  });
69
120
  if (callback) {
70
121
  callback(result.response);
@@ -73,7 +124,7 @@ export function* sendForApprovalCreate({ payload, callback, gupshupMediaFile })
73
124
  yield put({
74
125
  type: TEMPLATE_CREATE_FAILURE,
75
126
  error,
76
- errorMsg,
127
+ errorMsg
77
128
  });
78
129
  if (callback) {
79
130
  callback(null, errorMsg);
@@ -113,7 +164,7 @@ export function* getMetaTagsDetails({ previewUrl, callBack }) {
113
164
  if (result?.success) {
114
165
  yield put({
115
166
  type: URL_META_TAGS_SUCCESS,
116
- data: result?.response,
167
+ data: result?.response
117
168
  });
118
169
  } else {
119
170
  if (callBack) {