@capillarytech/creatives-library 8.0.125-alpha.6 → 8.0.126

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 (105) hide show
  1. package/config/app.js +6 -0
  2. package/containers/App/constants.js +0 -1
  3. package/containers/Email/index.js +5 -5
  4. package/containers/WeChat/RichmediaTemplates/Create/index.js +1 -1
  5. package/initialReducer.js +2 -0
  6. package/package.json +1 -1
  7. package/services/api.js +94 -1
  8. package/services/tests/api.test.js +191 -0
  9. package/tests/integration/TemplateCreation/TemplateCreation.integration.test.js +3 -8
  10. package/tests/integration/TemplateCreation/api-response.js +0 -5
  11. package/tests/integration/TemplateCreation/msw-handler.js +63 -42
  12. package/utils/common.js +0 -7
  13. package/utils/commonUtils.js +6 -2
  14. package/v2Components/CapImageUpload/index.js +45 -51
  15. package/v2Components/CapInAppCTA/index.js +0 -1
  16. package/v2Components/CapTagList/index.js +120 -177
  17. package/v2Components/CapVideoUpload/constants.js +0 -3
  18. package/v2Components/CapVideoUpload/index.js +110 -167
  19. package/v2Components/CapVideoUpload/messages.js +0 -16
  20. package/v2Components/Carousel/index.js +13 -15
  21. package/v2Components/CustomerSearchSection/_customerSearch.scss +309 -0
  22. package/v2Components/CustomerSearchSection/constants.js +5 -0
  23. package/v2Components/CustomerSearchSection/index.js +362 -0
  24. package/v2Components/CustomerSearchSection/messages.js +20 -0
  25. package/v2Components/CustomerSearchSection/tests/utils.test.js +334 -0
  26. package/v2Components/CustomerSearchSection/utils.js +49 -0
  27. package/v2Components/ErrorInfoNote/style.scss +0 -1
  28. package/v2Components/MobilePushPreviewV2/index.js +5 -37
  29. package/v2Components/TemplatePreview/_templatePreview.scss +72 -114
  30. package/v2Components/TemplatePreview/index.js +50 -178
  31. package/v2Components/TemplatePreview/messages.js +0 -4
  32. package/v2Components/TestAndPreviewSlidebox/_testAndPreviewSlidebox.scss +543 -0
  33. package/v2Components/TestAndPreviewSlidebox/actions.js +67 -0
  34. package/v2Components/TestAndPreviewSlidebox/constants.js +67 -0
  35. package/v2Components/TestAndPreviewSlidebox/index.js +771 -0
  36. package/v2Components/TestAndPreviewSlidebox/messages.js +147 -0
  37. package/v2Components/TestAndPreviewSlidebox/reducer.js +233 -0
  38. package/v2Components/TestAndPreviewSlidebox/sagas.js +258 -0
  39. package/v2Components/TestAndPreviewSlidebox/selectors.js +142 -0
  40. package/v2Components/TestAndPreviewSlidebox/tests/actions.test.js +80 -0
  41. package/v2Components/TestAndPreviewSlidebox/tests/reducer.test.js +367 -0
  42. package/v2Components/TestAndPreviewSlidebox/tests/saga.rtl.test.js +192 -0
  43. package/v2Components/TestAndPreviewSlidebox/tests/saga.test.js +652 -0
  44. package/v2Components/TestAndPreviewSlidebox/tests/selector.test.js +182 -0
  45. package/v2Containers/CreativesContainer/SlideBoxContent.js +21 -9
  46. package/v2Containers/CreativesContainer/SlideBoxFooter.js +23 -2
  47. package/v2Containers/CreativesContainer/index.js +160 -195
  48. package/v2Containers/CreativesContainer/messages.js +4 -0
  49. package/v2Containers/CreativesContainer/tests/__snapshots__/index.test.js.snap +21 -0
  50. package/v2Containers/Email/index.js +18 -6
  51. package/v2Containers/EmailWrapper/hooks/useEmailWrapper.js +10 -0
  52. package/v2Containers/EmailWrapper/index.js +6 -0
  53. package/v2Containers/InApp/constants.js +0 -1
  54. package/v2Containers/InApp/index.js +13 -13
  55. package/v2Containers/Line/Container/ImageCarousel/tests/__snapshots__/content.test.js.snap +3 -0
  56. package/v2Containers/Line/Container/ImageCarousel/tests/__snapshots__/index.test.js.snap +2 -0
  57. package/v2Containers/Line/Container/Wrapper/tests/__snapshots__/index.test.js.snap +2 -0
  58. package/v2Containers/Line/Container/tests/__snapshots__/index.test.js.snap +9 -0
  59. package/v2Containers/MobilePush/Create/index.js +0 -1
  60. package/v2Containers/MobilePush/commonMethods.js +14 -7
  61. package/v2Containers/Rcs/tests/__snapshots__/index.test.js.snap +23 -5
  62. package/v2Containers/SmsTrai/Edit/tests/__snapshots__/index.test.js.snap +4 -0
  63. package/v2Containers/TagList/index.js +10 -56
  64. package/v2Containers/Templates/_templates.scss +1 -101
  65. package/v2Containers/Templates/index.js +35 -147
  66. package/v2Containers/Templates/messages.js +0 -8
  67. package/v2Containers/Templates/sagas.js +0 -2
  68. package/v2Containers/WeChat/RichmediaTemplates/Create/index.js +1 -1
  69. package/v2Containers/Whatsapp/constants.js +0 -1
  70. package/v2Containers/Whatsapp/tests/__snapshots__/index.test.js.snap +35 -0
  71. package/utils/createPayload.js +0 -270
  72. package/utils/tests/createPayload.test.js +0 -761
  73. package/v2Components/CapMpushCTA/constants.js +0 -25
  74. package/v2Components/CapMpushCTA/index.js +0 -332
  75. package/v2Components/CapMpushCTA/index.scss +0 -95
  76. package/v2Components/CapMpushCTA/messages.js +0 -89
  77. package/v2Components/TemplatePreview/assets/images/Android _ With date and time.svg +0 -29
  78. package/v2Components/TemplatePreview/assets/images/android.svg +0 -9
  79. package/v2Components/TemplatePreview/assets/images/iOS _ With date and time.svg +0 -26
  80. package/v2Components/TemplatePreview/assets/images/ios.svg +0 -9
  81. package/v2Containers/Email/tests/index.test.js +0 -35
  82. package/v2Containers/MobilePushNew/actions.js +0 -116
  83. package/v2Containers/MobilePushNew/components/CtaButtons.js +0 -170
  84. package/v2Containers/MobilePushNew/components/MediaUploaders.js +0 -686
  85. package/v2Containers/MobilePushNew/components/PlatformContentFields.js +0 -279
  86. package/v2Containers/MobilePushNew/components/index.js +0 -5
  87. package/v2Containers/MobilePushNew/components/tests/CtaButtons.test.js +0 -779
  88. package/v2Containers/MobilePushNew/components/tests/MediaUploaders.test.js +0 -2114
  89. package/v2Containers/MobilePushNew/components/tests/PlatformContentFields.test.js +0 -343
  90. package/v2Containers/MobilePushNew/constants.js +0 -115
  91. package/v2Containers/MobilePushNew/hooks/tests/usePlatformSync.test.js +0 -1299
  92. package/v2Containers/MobilePushNew/hooks/tests/useUpload.test.js +0 -1223
  93. package/v2Containers/MobilePushNew/hooks/usePlatformSync.js +0 -246
  94. package/v2Containers/MobilePushNew/hooks/useUpload.js +0 -709
  95. package/v2Containers/MobilePushNew/index.js +0 -2170
  96. package/v2Containers/MobilePushNew/index.scss +0 -308
  97. package/v2Containers/MobilePushNew/messages.js +0 -226
  98. package/v2Containers/MobilePushNew/reducer.js +0 -160
  99. package/v2Containers/MobilePushNew/sagas.js +0 -198
  100. package/v2Containers/MobilePushNew/selectors.js +0 -55
  101. package/v2Containers/MobilePushNew/tests/reducer.test.js +0 -741
  102. package/v2Containers/MobilePushNew/tests/sagas.test.js +0 -863
  103. package/v2Containers/MobilePushNew/tests/selectors.test.js +0 -425
  104. package/v2Containers/MobilePushNew/tests/utils.test.js +0 -322
  105. package/v2Containers/MobilePushNew/utils.js +0 -33
@@ -0,0 +1,147 @@
1
+ /*
2
+ * TestAndPreviewSlidebox Messages
3
+ *
4
+ * This contains all the text for the TestAndPreviewSlidebox component.
5
+ */
6
+ import { defineMessages } from 'react-intl';
7
+
8
+ export const scope = 'app.v2Components.TestAndPreviewSlidebox';
9
+
10
+ export default defineMessages({
11
+ testAndPreviewHeader: {
12
+ id: `${scope}.testAndPreviewHeader`,
13
+ defaultMessage: 'Preview and Test',
14
+ },
15
+ customerSearchTitle: {
16
+ id: `${scope}.customerSearchTitle`,
17
+ defaultMessage: 'Customer',
18
+ },
19
+ enterCustomValuesForTags: {
20
+ id: `${scope}.enterCustomValuesForTags`,
21
+ defaultMessage: 'Enter custom values for tags',
22
+ },
23
+ personalizationTags: {
24
+ id: `${scope}.personalizationTags`,
25
+ defaultMessage: 'Personalization Tags',
26
+ },
27
+ customValues: {
28
+ id: `${scope}.customValues`,
29
+ defaultMessage: 'Custom Values',
30
+ },
31
+ showJSON: {
32
+ id: `${scope}.showJSON`,
33
+ defaultMessage: 'Show JSON',
34
+ },
35
+ discardCustomValues: {
36
+ id: `${scope}.discardCustomValues`,
37
+ defaultMessage: 'Discard custom values',
38
+ },
39
+ updatePreview: {
40
+ id: `${scope}.updatePreview`,
41
+ defaultMessage: 'Update Preview',
42
+ },
43
+ sendTestMessage: {
44
+ id: `${scope}.sendTestMessage`,
45
+ defaultMessage: 'Send Test Message',
46
+ },
47
+ testMessageDescription: {
48
+ id: `${scope}.testMessageDescription`,
49
+ defaultMessage: 'Test out the message before sending to your customers',
50
+ },
51
+ sendTestButton: {
52
+ id: `${scope}.sendTestButton`,
53
+ defaultMessage: 'Send test message',
54
+ },
55
+ emailPreviewTitle: {
56
+ id: `${scope}.emailPreviewTitle`,
57
+ defaultMessage: 'Email Preview',
58
+ },
59
+ extractingTags: {
60
+ id: `${scope}.extractingTags`,
61
+ defaultMessage: 'Extracting tags...',
62
+ },
63
+ noTagsExtracted: {
64
+ id: `${scope}.noTagsExtracted`,
65
+ defaultMessage: 'There are no personalization tags in this message, you can directly send out a test message',
66
+ },
67
+ noTagsFound: {
68
+ id: `${scope}.noTagsFound`,
69
+ defaultMessage: 'No tags found in the template',
70
+ },
71
+ tagName: {
72
+ id: `${scope}.tagName`,
73
+ defaultMessage: 'Tag Name',
74
+ },
75
+ tagValue: {
76
+ id: `${scope}.tagValue`,
77
+ defaultMessage: 'Value',
78
+ },
79
+ enterValue: {
80
+ id: `${scope}.enterValue`,
81
+ defaultMessage: 'Enter value',
82
+ },
83
+ overrideValue: {
84
+ id: `${scope}.overrideValue`,
85
+ defaultMessage: 'Override value (optional)',
86
+ },
87
+ noRequiredTags: {
88
+ id: `${scope}.noRequiredTags`,
89
+ defaultMessage: 'No required personalization tags found. Select a customer to continue.',
90
+ },
91
+ previewTitle: {
92
+ id: `${scope}.previewTitle`,
93
+ defaultMessage: 'Preview',
94
+ },
95
+ previewPlaceholder: {
96
+ id: `${scope}.previewPlaceholder`,
97
+ defaultMessage: 'Click "Update Preview" to see the rendered email.',
98
+ },
99
+ previewFor: {
100
+ id: `${scope}.previewFor`,
101
+ defaultMessage: 'Preview for',
102
+ },
103
+ defaultPreview: {
104
+ id: `${scope}.defaultPreview`,
105
+ defaultMessage: 'Default preview',
106
+ },
107
+ senderName: {
108
+ id: `${scope}.senderName`,
109
+ defaultMessage: 'Capillary Technologies',
110
+ },
111
+ browserAddressBar: {
112
+ id: `${scope}.browserAddressBar`,
113
+ defaultMessage: 'www.yourmail.com',
114
+ },
115
+ testCustomers: {
116
+ id: `${scope}.testCustomers`,
117
+ defaultMessage: 'Test Customers',
118
+ },
119
+ testCustomersPlaceholder: {
120
+ id: `${scope}.testCustomersPlaceholder`,
121
+ defaultMessage: 'Search and select a group or individual test customers',
122
+ },
123
+ updatingPreview: {
124
+ id: `${scope}.updatingPreview`,
125
+ defaultMessage: 'Updating preview with the latest changes',
126
+ },
127
+ valuesMissing: {
128
+ id: `${scope}.valuesMissing`,
129
+ defaultMessage: 'Values missing for some of the personalization tags',
130
+ },
131
+ timeAgo: {
132
+ id: `${scope}.timeAgo`,
133
+ defaultMessage: '0 min ago',
134
+ },
135
+ testMessageSent: {
136
+ id: `${scope}.testMessageSent`,
137
+ defaultMessage: 'Test message sent successfully!',
138
+ },
139
+ testMessageFailed: {
140
+ id: `${scope}.testMessageFailed`,
141
+ defaultMessage: 'Failed to send test message',
142
+ },
143
+ invalidJSON: {
144
+ id: `${scope}.invalidJSON`,
145
+ defaultMessage: 'Invalid JSON input',
146
+ },
147
+ });
@@ -0,0 +1,233 @@
1
+ /**
2
+ * Customer Search Section Reducer
3
+ */
4
+ import { fromJS } from 'immutable';
5
+ import {
6
+ SEARCH_CUSTOMERS_REQUESTED,
7
+ SEARCH_CUSTOMERS_SUCCESS,
8
+ SEARCH_CUSTOMERS_FAILURE,
9
+ EXTRACT_TAGS_REQUEST,
10
+ EXTRACT_TAGS_SUCCESS,
11
+ EXTRACT_TAGS_FAILURE,
12
+ UPDATE_PREVIEW_REQUEST,
13
+ UPDATE_PREVIEW_SUCCESS,
14
+ UPDATE_PREVIEW_FAILURE,
15
+ SEND_TEST_MESSAGE_REQUESTED,
16
+ SEND_TEST_MESSAGE_SUCCESS,
17
+ SEND_TEST_MESSAGE_FAILURE,
18
+ CLEAR_CUSTOMER_SEARCH_STATE,
19
+ CLEAR_SEARCH_RESULTS,
20
+ FETCH_TEST_CUSTOMERS_REQUESTED,
21
+ FETCH_TEST_CUSTOMERS_SUCCESS,
22
+ FETCH_TEST_CUSTOMERS_FAILURE,
23
+ FETCH_TEST_GROUPS_REQUESTED,
24
+ FETCH_TEST_GROUPS_SUCCESS,
25
+ FETCH_TEST_GROUPS_FAILURE,
26
+ CREATE_MESSAGE_META_REQUESTED,
27
+ CREATE_MESSAGE_META_SUCCESS,
28
+ CREATE_MESSAGE_META_FAILURE,
29
+ GET_PREFILLED_VALUES_REQUESTED,
30
+ GET_PREFILLED_VALUES_SUCCESS,
31
+ GET_PREFILLED_VALUES_FAILURE,
32
+ CLEAR_PREFILLED_VALUES,
33
+ } from './constants';
34
+
35
+ const initialState = fromJS({
36
+ // Search state
37
+ searchQuery: '',
38
+ customers: [],
39
+ isSearchingCustomer: false,
40
+ searchError: null,
41
+ hasSearched: false,
42
+
43
+ // Selected customer and tags
44
+ extractedTags: [],
45
+ requiredTags: [],
46
+ optionalTags: [],
47
+ isExtractingTags: false,
48
+ extractTagsError: null,
49
+ apiWarnings: [],
50
+ apiErrors: [],
51
+
52
+ // Preview state
53
+ previewData: null,
54
+ isUpdatingPreview: false,
55
+ updatePreviewError: null,
56
+
57
+ // Test email state
58
+ isSendingTestMessage: false,
59
+ sendTestMessageError: null,
60
+ testMessageResponse: null,
61
+
62
+ tags: {
63
+ loading: false,
64
+ error: null,
65
+ required: [],
66
+ optional: [],
67
+ },
68
+
69
+ // Test Customers
70
+ testCustomers: [],
71
+ isFetchingTestCustomers: false,
72
+ fetchTestCustomersError: null,
73
+
74
+ // Test Groups
75
+ testGroups: [],
76
+ isFetchingTestGroups: false,
77
+ fetchTestGroupsError: null,
78
+
79
+ messageMetaConfigId: null,
80
+ isCreatingMessageMeta: false,
81
+ createMessageMetaError: null,
82
+ prefilledValues: {},
83
+ isFetchingPrefilledValues: false,
84
+ fetchPrefilledValuesError: null,
85
+ });
86
+
87
+ const previewAndTestReducer = (state = initialState, action) => {
88
+ switch (action.type) {
89
+ // Search Customers
90
+ case SEARCH_CUSTOMERS_REQUESTED:
91
+ return state.set('searchQuery', action.payload.query)
92
+ .set('isSearchingCustomer', true)
93
+ .set('searchError', null)
94
+ .set('hasSearched', false);
95
+
96
+ case SEARCH_CUSTOMERS_SUCCESS:
97
+ return state.set('customers', action.payload.customers)
98
+ .set('isSearchingCustomer', false)
99
+ .set('searchError', null)
100
+ .set('hasSearched', true);
101
+
102
+ case SEARCH_CUSTOMERS_FAILURE:
103
+ return state.set('customers', [])
104
+ .set('isSearchingCustomer', false)
105
+ .set('searchError', action.payload.error)
106
+ .set('hasSearched', true);
107
+
108
+ // Extract Tags
109
+ case EXTRACT_TAGS_REQUEST:
110
+ return state.set('isExtractingTags', true)
111
+ .set('extractTagsError', null)
112
+ .set('apiWarnings', [])
113
+ .set('apiErrors', [])
114
+ .set('tags.loading', true)
115
+ .set('tags.error', null);
116
+
117
+ case EXTRACT_TAGS_SUCCESS:
118
+ return state.set('extractedTags', action.payload.extractedtags)
119
+ .set('isExtractingTags', false)
120
+ .set('extractTagsError', null)
121
+ .set('tags.loading', false)
122
+ .set('tags.error', null);
123
+
124
+ case EXTRACT_TAGS_FAILURE:
125
+ return state.set('extractedTags', [])
126
+ .set('isExtractingTags', false)
127
+ .set('extractTagsError', action.payload.error)
128
+ .set('apiWarnings', [])
129
+ .set('apiErrors', [])
130
+ .set('tags.loading', false)
131
+ .set('tags.error', action.payload.error);
132
+
133
+ // Update Preview
134
+ case UPDATE_PREVIEW_REQUEST:
135
+ return state.set('isUpdatingPreview', true)
136
+ .set('updatePreviewError', null);
137
+
138
+ case UPDATE_PREVIEW_SUCCESS:
139
+ return state.set('previewData', action.payload.previewData)
140
+ .set('isUpdatingPreview', false)
141
+ .set('updatePreviewError', null);
142
+
143
+ case UPDATE_PREVIEW_FAILURE:
144
+ return state.set('previewData', null)
145
+ .set('isUpdatingPreview', false)
146
+ .set('updatePreviewError', action.payload.error);
147
+
148
+ // Send Test Email
149
+ case SEND_TEST_MESSAGE_REQUESTED:
150
+ return state.set('isSendingTestMessage', true)
151
+ .set('sendTestMessageError', null)
152
+ .set('testMessageResponse', null);
153
+
154
+ case SEND_TEST_MESSAGE_SUCCESS:
155
+ return state.set('testMessageResponse', action.payload.response)
156
+ .set('isSendingTestMessage', false)
157
+ .set('sendTestMessageError', null);
158
+
159
+ case SEND_TEST_MESSAGE_FAILURE:
160
+ return state.set('testMessageResponse', action.payload.response)
161
+ .set('isSendingTestMessage', false)
162
+ .set('sendTestMessageError', action.payload.error);
163
+
164
+ // Clear Actions
165
+ case CLEAR_SEARCH_RESULTS:
166
+ return state.set('customers', [])
167
+ .set('searchQuery', '')
168
+ .set('hasSearched', false)
169
+ .set('searchError', null);
170
+
171
+ case CLEAR_CUSTOMER_SEARCH_STATE:
172
+ return fromJS(initialState);
173
+
174
+ // Test Customers
175
+ case FETCH_TEST_CUSTOMERS_REQUESTED:
176
+ return state.set('isFetchingTestCustomers', true)
177
+ .set('fetchTestCustomersError', null);
178
+
179
+ case FETCH_TEST_CUSTOMERS_SUCCESS:
180
+ return state.set('isFetchingTestCustomers', false)
181
+ .set('testCustomers', action.payload.customers);
182
+
183
+ case FETCH_TEST_CUSTOMERS_FAILURE:
184
+ return state.set('isFetchingTestCustomers', false)
185
+ .set('fetchTestCustomersError', action.payload.error);
186
+
187
+ // Test Groups
188
+ case FETCH_TEST_GROUPS_REQUESTED:
189
+ return state.set('isFetchingTestGroups', true)
190
+ .set('fetchTestGroupsError', null);
191
+
192
+ case FETCH_TEST_GROUPS_SUCCESS:
193
+ return state.set('isFetchingTestGroups', false)
194
+ .set('testGroups', action.payload.groups);
195
+
196
+ case FETCH_TEST_GROUPS_FAILURE:
197
+ return state.set('isFetchingTestGroups', false)
198
+ .set('fetchTestGroupsError', action.payload.error);
199
+
200
+ // Create Message Meta
201
+ case CREATE_MESSAGE_META_REQUESTED:
202
+ return state.set('isCreatingMessageMeta', true)
203
+ .set('createMessageMetaError', null);
204
+
205
+ case CREATE_MESSAGE_META_SUCCESS:
206
+ return state.set('isCreatingMessageMeta', false)
207
+ .set('messageMetaConfigId', action.payload.response.entity);
208
+
209
+ case CREATE_MESSAGE_META_FAILURE:
210
+ return state.set('isCreatingMessageMeta', false)
211
+ .set('createMessageMetaError', action.payload.error);
212
+
213
+ // Get Prefilled Values
214
+ case GET_PREFILLED_VALUES_REQUESTED:
215
+ return state.set('isFetchingPrefilledValues', true)
216
+ .set('fetchPrefilledValuesError', null);
217
+ case GET_PREFILLED_VALUES_SUCCESS:
218
+ return state.set('isFetchingPrefilledValues', false)
219
+ .set('prefilledValues', fromJS(action.payload.values));
220
+
221
+ case GET_PREFILLED_VALUES_FAILURE:
222
+ return state.set('isFetchingPrefilledValues', false)
223
+ .set('fetchPrefilledValuesError', action.payload.error);
224
+
225
+ case CLEAR_PREFILLED_VALUES:
226
+ return state.set('prefilledValues', fromJS({}));
227
+
228
+ default:
229
+ return state;
230
+ }
231
+ };
232
+
233
+ export default previewAndTestReducer;
@@ -0,0 +1,258 @@
1
+ /**
2
+ * Customer Search Section Sagas
3
+ */
4
+
5
+ import {
6
+ call, put, takeLatest, all,
7
+ } from 'redux-saga/effects';
8
+ import get from 'lodash/get';
9
+ import isEmpty from 'lodash/isEmpty';
10
+ import * as Api from '../../services/api';
11
+ import {
12
+ SEARCH_CUSTOMERS_REQUESTED,
13
+ SEARCH_CUSTOMERS_SUCCESS,
14
+ SEARCH_CUSTOMERS_FAILURE,
15
+ EXTRACT_TAGS_REQUEST,
16
+ EXTRACT_TAGS_SUCCESS,
17
+ EXTRACT_TAGS_FAILURE,
18
+ UPDATE_PREVIEW_REQUEST,
19
+ UPDATE_PREVIEW_SUCCESS,
20
+ UPDATE_PREVIEW_FAILURE,
21
+ SEND_TEST_MESSAGE_REQUESTED,
22
+ SEND_TEST_MESSAGE_SUCCESS,
23
+ SEND_TEST_MESSAGE_FAILURE,
24
+ FETCH_TEST_CUSTOMERS_REQUESTED,
25
+ FETCH_TEST_GROUPS_REQUESTED,
26
+ FETCH_TEST_CUSTOMERS_SUCCESS,
27
+ FETCH_TEST_CUSTOMERS_FAILURE,
28
+ FETCH_TEST_GROUPS_SUCCESS,
29
+ FETCH_TEST_GROUPS_FAILURE,
30
+ CREATE_MESSAGE_META_REQUESTED,
31
+ CREATE_MESSAGE_META_SUCCESS,
32
+ CREATE_MESSAGE_META_FAILURE,
33
+ GET_PREFILLED_VALUES_REQUESTED,
34
+ GET_PREFILLED_VALUES_SUCCESS,
35
+ GET_PREFILLED_VALUES_FAILURE,
36
+ } from './constants';
37
+
38
+ // Search Customers Saga
39
+ export function* searchCustomersSaga(action) {
40
+ try {
41
+ const { query } = action.payload;
42
+ const response = yield call(Api.searchCustomers, { query });
43
+
44
+ if (response.isError) {
45
+ yield put({ type: SEARCH_CUSTOMERS_FAILURE, payload: { error: response.message || 'Failed to search customers' } });
46
+ } else {
47
+ const customers = response?.result?.data || [];
48
+ yield put({ type: SEARCH_CUSTOMERS_SUCCESS, payload: { customers } });
49
+ }
50
+ } catch (error) {
51
+ yield put({ type: SEARCH_CUSTOMERS_FAILURE, payload: { error: error.message || 'Network error occurred' } });
52
+ }
53
+ }
54
+
55
+ // Extract Tags Saga
56
+ export function* extractTagsSaga(action) {
57
+ try {
58
+ const { templateSubject, templateContent } = action.payload;
59
+
60
+ const payload = {
61
+ messageTitle: templateSubject || '',
62
+ messageBody: templateContent || '',
63
+ };
64
+
65
+ const response = yield call(Api.extractTagsWithMetaData, payload);
66
+ if (response?.data?.length > 0) {
67
+ yield put({ type: EXTRACT_TAGS_SUCCESS, payload: { extractedtags: response.data } });
68
+ } else {
69
+ yield put({ type: EXTRACT_TAGS_FAILURE, payload: { error: response.error || 'Failed to extract tags' } });
70
+ }
71
+ } catch (error) {
72
+ yield put({ type: EXTRACT_TAGS_FAILURE, payload: { error: error.message || 'Network error occurred' } });
73
+ }
74
+ }
75
+
76
+ // Update Preview Saga
77
+ export function* updatePreviewSaga(action) {
78
+ try {
79
+ const response = yield call(Api.updateEmailPreview, action.payload);
80
+ if (response?.data) {
81
+ yield put({ type: UPDATE_PREVIEW_SUCCESS, payload: { previewData: response.data } });
82
+ } else {
83
+ yield put({ type: UPDATE_PREVIEW_FAILURE, payload: { error: response.error || 'Failed to update preview' } });
84
+ }
85
+ } catch (error) {
86
+ yield put({ type: UPDATE_PREVIEW_FAILURE, payload: { error: error.message || 'Network error occurred' } });
87
+ }
88
+ }
89
+
90
+ // Send Test Email Saga
91
+ export function* sendTestMessageSaga(action) {
92
+ try {
93
+ const { callback } = action;
94
+ const response = yield call(Api.sendTestMessage, action.payload);
95
+
96
+ if (!response.errors) {
97
+ yield put({ type: SEND_TEST_MESSAGE_SUCCESS, payload: { response: true } });
98
+ callback(true);
99
+ } else {
100
+ yield put({ type: SEND_TEST_MESSAGE_FAILURE, payload: { response: false, error: response.errors || 'Failed to send test email' } });
101
+ callback(false);
102
+ }
103
+ } catch (error) {
104
+ yield put({ type: SEND_TEST_MESSAGE_FAILURE, payload: { response: false, error: error.message || 'Network error occurred' } });
105
+ action.callback(false);
106
+ }
107
+ }
108
+
109
+ export function* getBulkCustomerDetails({fetchedUserIds}) {
110
+ try {
111
+ const bulkCustomerDetails = yield call(Api.getBulkCustomerDetails, {
112
+ userIds: fetchedUserIds,
113
+ });
114
+ const transformedData = get(bulkCustomerDetails, 'result.data').map(
115
+ (item) => {
116
+ const profile = get(item, 'entity.profiles[0]', {});
117
+ if (isEmpty(profile)) {
118
+ throw item?.errors?.[0]?.message;
119
+ }
120
+ const mobileIdentifier = profile?.identifiers?.find(
121
+ (identifier) => identifier.type === 'mobile',
122
+ );
123
+ const emailIdentifier = profile?.identifiers?.find(
124
+ (identifier) => identifier.type === 'email',
125
+ );
126
+ return {
127
+ userId: item?.entity?.id,
128
+ name: `${profile?.firstName} ${profile?.lastName}`,
129
+ mobile: mobileIdentifier?.value,
130
+ email: emailIdentifier?.value,
131
+ };
132
+ },
133
+ );
134
+ yield put({
135
+ type: FETCH_TEST_CUSTOMERS_SUCCESS,
136
+ payload: { customers: transformedData },
137
+ });
138
+ } catch (error) {
139
+ yield put({
140
+ type: FETCH_TEST_CUSTOMERS_FAILURE,
141
+ payload: { error },
142
+ });
143
+ }
144
+ }
145
+
146
+ export function* fetchTestCustomersSaga() {
147
+ try {
148
+ const response = yield call(Api.fetchTestCustomers);
149
+ if (response.entity) {
150
+ const fetchedUserIds = get(response, 'entity.userIds');
151
+ if (Array.isArray(fetchedUserIds) && fetchedUserIds.length > 0) {
152
+ yield call(getBulkCustomerDetails, { fetchedUserIds });
153
+ } else {
154
+ yield put({
155
+ type: FETCH_TEST_CUSTOMERS_FAILURE,
156
+ payload: { error: "No test customers found" },
157
+ });
158
+ }
159
+ } else {
160
+ yield put({ type: FETCH_TEST_CUSTOMERS_FAILURE, payload: { error: response.error || 'Failed to fetch test customers' } });
161
+ }
162
+ } catch (error) {
163
+ yield put({ type: FETCH_TEST_CUSTOMERS_FAILURE, payload: { error: error.message } });
164
+ }
165
+ }
166
+
167
+ export function* fetchTestGroupsSaga() {
168
+ try {
169
+ const response = yield call(Api.fetchTestGroups);
170
+ if (response?.entity) {
171
+ yield put({ type: FETCH_TEST_GROUPS_SUCCESS, payload: { groups: response?.entity?.userGroups } });
172
+ } else {
173
+ yield put({ type: FETCH_TEST_GROUPS_FAILURE, payload: { error: response.error || 'Failed to fetch test groups' } });
174
+ }
175
+ } catch (error) {
176
+ yield put({ type: FETCH_TEST_GROUPS_FAILURE, payload: { error: error.message } });
177
+ }
178
+ }
179
+
180
+ export function* createMessageMetaSaga(action) {
181
+ try {
182
+ const { payload, messageMetaConfigId, callback } = action;
183
+ let response;
184
+ if (messageMetaConfigId) {
185
+ response = yield call(Api.updateTestMessageMeta, { data: payload, messageMetaConfigId });
186
+ } else {
187
+ response = yield call(Api.createTestMessageMeta, payload);
188
+ }
189
+ if (!response.errors) {
190
+ yield put({ type: CREATE_MESSAGE_META_SUCCESS, payload: { response } });
191
+ callback(response);
192
+ } else {
193
+ yield put({ type: CREATE_MESSAGE_META_FAILURE, payload: { error: response.errors || 'Failed to create message meta' } });
194
+ }
195
+ } catch (error) {
196
+ yield put({ type: CREATE_MESSAGE_META_FAILURE, payload: { error } });
197
+ }
198
+ }
199
+
200
+ export function* getPrefilledValuesSaga(action) {
201
+ try {
202
+ const response = yield call(Api.updateEmailPreview, action.payload);
203
+ if (response?.data) {
204
+ yield put({ type: GET_PREFILLED_VALUES_SUCCESS, payload: { values: response?.data?.resolvedTagValues } });
205
+ } else {
206
+ yield put({ type: GET_PREFILLED_VALUES_FAILURE, payload: { error: response.error || 'Failed to fetch prefilled values' } });
207
+ }
208
+ } catch (error) {
209
+ yield put({ type: GET_PREFILLED_VALUES_FAILURE, payload: { error } });
210
+ }
211
+ }
212
+
213
+ // Watcher Sagas
214
+ export function* watchSearchCustomers() {
215
+ yield takeLatest(SEARCH_CUSTOMERS_REQUESTED, searchCustomersSaga);
216
+ }
217
+
218
+ export function* watchExtractTags() {
219
+ yield takeLatest(EXTRACT_TAGS_REQUEST, extractTagsSaga);
220
+ }
221
+
222
+ export function* watchUpdatePreview() {
223
+ yield takeLatest(UPDATE_PREVIEW_REQUEST, updatePreviewSaga);
224
+ }
225
+
226
+ export function* watchSendTestMessage() {
227
+ yield takeLatest(SEND_TEST_MESSAGE_REQUESTED, sendTestMessageSaga);
228
+ }
229
+
230
+ export function* watchFetchTestCustomers() {
231
+ yield takeLatest(FETCH_TEST_CUSTOMERS_REQUESTED, fetchTestCustomersSaga);
232
+ }
233
+
234
+ export function* watchFetchTestGroups() {
235
+ yield takeLatest(FETCH_TEST_GROUPS_REQUESTED, fetchTestGroupsSaga);
236
+ }
237
+
238
+ export function* watchCreateMessageMeta() {
239
+ yield takeLatest(CREATE_MESSAGE_META_REQUESTED, createMessageMetaSaga);
240
+ }
241
+
242
+ export function* watchGetPrefilledValues() {
243
+ yield takeLatest(GET_PREFILLED_VALUES_REQUESTED, getPrefilledValuesSaga);
244
+ }
245
+
246
+ // Root saga
247
+ export function* previewAndTestSaga() {
248
+ yield all([
249
+ watchSearchCustomers(),
250
+ watchExtractTags(),
251
+ watchUpdatePreview(),
252
+ watchSendTestMessage(),
253
+ watchFetchTestCustomers(),
254
+ watchFetchTestGroups(),
255
+ watchCreateMessageMeta(),
256
+ watchGetPrefilledValues(),
257
+ ]);
258
+ }