@capillarytech/creatives-library 8.0.126 → 8.0.127-alpha.1

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 (78) hide show
  1. package/containers/App/constants.js +1 -0
  2. package/index.html +3 -1
  3. package/package.json +1 -1
  4. package/services/api.js +4 -4
  5. package/tests/integration/TemplateCreation/TemplateCreation.integration.test.js +8 -3
  6. package/tests/integration/TemplateCreation/api-response.js +5 -0
  7. package/tests/integration/TemplateCreation/msw-handler.js +42 -63
  8. package/utils/common.js +7 -0
  9. package/utils/commonUtils.js +2 -6
  10. package/utils/createPayload.js +272 -0
  11. package/utils/tests/createPayload.test.js +761 -0
  12. package/v2Components/CapImageUpload/index.js +59 -46
  13. package/v2Components/CapInAppCTA/index.js +1 -0
  14. package/v2Components/CapMpushCTA/constants.js +25 -0
  15. package/v2Components/CapMpushCTA/index.js +332 -0
  16. package/v2Components/CapMpushCTA/index.scss +95 -0
  17. package/v2Components/CapMpushCTA/messages.js +89 -0
  18. package/v2Components/CapTagList/index.js +177 -120
  19. package/v2Components/CapVideoUpload/constants.js +3 -0
  20. package/v2Components/CapVideoUpload/index.js +167 -110
  21. package/v2Components/CapVideoUpload/messages.js +16 -0
  22. package/v2Components/Carousel/index.js +15 -13
  23. package/v2Components/CustomerSearchSection/index.js +12 -7
  24. package/v2Components/ErrorInfoNote/style.scss +1 -0
  25. package/v2Components/MobilePushPreviewV2/index.js +37 -5
  26. package/v2Components/TemplatePreview/_templatePreview.scss +114 -72
  27. package/v2Components/TemplatePreview/assets/images/Android _ With date and time.svg +29 -0
  28. package/v2Components/TemplatePreview/assets/images/android.svg +9 -0
  29. package/v2Components/TemplatePreview/assets/images/iOS _ With date and time.svg +26 -0
  30. package/v2Components/TemplatePreview/assets/images/ios.svg +9 -0
  31. package/v2Components/TemplatePreview/index.js +178 -50
  32. package/v2Components/TemplatePreview/messages.js +4 -0
  33. package/v2Components/TestAndPreviewSlidebox/CustomValuesEditor.js +169 -0
  34. package/v2Components/TestAndPreviewSlidebox/LeftPanelContent.js +95 -0
  35. package/v2Components/TestAndPreviewSlidebox/PreviewSection.js +69 -0
  36. package/v2Components/TestAndPreviewSlidebox/SendTestMessage.js +68 -0
  37. package/v2Components/TestAndPreviewSlidebox/index.js +67 -246
  38. package/v2Components/TestAndPreviewSlidebox/tests/CustomValuesEditor.test.js +425 -0
  39. package/v2Components/TestAndPreviewSlidebox/tests/LeftPanelContent.test.js +400 -0
  40. package/v2Components/TestAndPreviewSlidebox/tests/SendTestMessage.test.js +448 -0
  41. package/v2Containers/CreativesContainer/SlideBoxContent.js +9 -9
  42. package/v2Containers/CreativesContainer/index.js +191 -136
  43. package/v2Containers/Email/index.js +15 -2
  44. package/v2Containers/InApp/constants.js +1 -0
  45. package/v2Containers/InApp/index.js +13 -13
  46. package/v2Containers/MobilePush/Create/index.js +1 -0
  47. package/v2Containers/MobilePush/commonMethods.js +7 -14
  48. package/v2Containers/MobilePushNew/actions.js +116 -0
  49. package/v2Containers/MobilePushNew/components/CtaButtons.js +170 -0
  50. package/v2Containers/MobilePushNew/components/MediaUploaders.js +754 -0
  51. package/v2Containers/MobilePushNew/components/PlatformContentFields.js +279 -0
  52. package/v2Containers/MobilePushNew/components/index.js +5 -0
  53. package/v2Containers/MobilePushNew/components/tests/CtaButtons.test.js +779 -0
  54. package/v2Containers/MobilePushNew/components/tests/MediaUploaders.test.js +2114 -0
  55. package/v2Containers/MobilePushNew/components/tests/PlatformContentFields.test.js +343 -0
  56. package/v2Containers/MobilePushNew/constants.js +115 -0
  57. package/v2Containers/MobilePushNew/hooks/tests/usePlatformSync.test.js +1299 -0
  58. package/v2Containers/MobilePushNew/hooks/tests/useUpload.test.js +1223 -0
  59. package/v2Containers/MobilePushNew/hooks/usePlatformSync.js +246 -0
  60. package/v2Containers/MobilePushNew/hooks/useUpload.js +726 -0
  61. package/v2Containers/MobilePushNew/index.js +2280 -0
  62. package/v2Containers/MobilePushNew/index.scss +308 -0
  63. package/v2Containers/MobilePushNew/messages.js +226 -0
  64. package/v2Containers/MobilePushNew/reducer.js +160 -0
  65. package/v2Containers/MobilePushNew/sagas.js +198 -0
  66. package/v2Containers/MobilePushNew/selectors.js +55 -0
  67. package/v2Containers/MobilePushNew/tests/reducer.test.js +741 -0
  68. package/v2Containers/MobilePushNew/tests/sagas.test.js +863 -0
  69. package/v2Containers/MobilePushNew/tests/selectors.test.js +425 -0
  70. package/v2Containers/MobilePushNew/tests/utils.test.js +322 -0
  71. package/v2Containers/MobilePushNew/utils.js +33 -0
  72. package/v2Containers/Rcs/tests/__snapshots__/index.test.js.snap +5 -5
  73. package/v2Containers/TagList/index.js +56 -10
  74. package/v2Containers/Templates/_templates.scss +101 -1
  75. package/v2Containers/Templates/index.js +147 -35
  76. package/v2Containers/Templates/messages.js +8 -0
  77. package/v2Containers/Templates/sagas.js +2 -0
  78. package/v2Containers/Whatsapp/constants.js +1 -0
@@ -0,0 +1,343 @@
1
+ import React from "react";
2
+ import { render, fireEvent } from "@testing-library/react";
3
+ import "@testing-library/jest-dom";
4
+ import { IntlProvider } from "react-intl";
5
+ import PlatformContentFields from "../PlatformContentFields";
6
+ import {
7
+ ANDROID, IOS, DEEP_LINK, EXTERNAL_LINK,
8
+ } from "../../constants";
9
+
10
+ // Simple mock components
11
+ jest.mock("@capillarytech/cap-ui-library/CapRow", () => ({ children }) => <div>{children}</div>);
12
+ jest.mock("@capillarytech/cap-ui-library/CapColumn", () => ({ children }) => <div>{children}</div>);
13
+ jest.mock("@capillarytech/cap-ui-library/CapInput", () => ({
14
+ value, onChange, errorMessage, ...props
15
+ }) => (
16
+ <div>
17
+ <input value={value || ""} onChange={onChange} {...props} />
18
+ {errorMessage && <div data-testid="error-message">{errorMessage}</div>}
19
+ </div>
20
+ ));
21
+ jest.mock("@capillarytech/cap-ui-library/CapHeading", () => ({ children }) => <div>{children}</div>);
22
+ jest.mock("@capillarytech/cap-ui-library/CapError", () => ({ children }) => <div data-testid="cap-error">{children}</div>);
23
+ jest.mock("@capillarytech/cap-ui-library/CapDivider", () => () => <div data-testid="divider" />);
24
+ jest.mock("@capillarytech/cap-ui-library/CapSelect", () => ({
25
+ CapCustomSelect: ({ value, onChange, options }) => (
26
+ <select value={value} onChange={(e) => onChange && onChange(e.target.value)}>
27
+ {options?.map((option) => (
28
+ <option key={option.value} value={option.value}>
29
+ {option.label}
30
+ </option>
31
+ ))}
32
+ </select>
33
+ ),
34
+ }));
35
+ jest.mock("@capillarytech/cap-ui-library/CapCheckbox", () => ({ checked, onChange, children }) => (
36
+ <div>
37
+ <input type="checkbox" checked={checked} onChange={onChange} data-testid="action-checkbox" />
38
+ <span>{children}</span>
39
+ </div>
40
+ ));
41
+ jest.mock("@capillarytech/cap-ui-library/CapLabel", () => ({ children }) => <label>{children}</label>);
42
+ jest.mock("@capillarytech/cap-ui-library/CapInfoNote", () => ({ message }) => <div data-testid="info-note">{message}</div>);
43
+
44
+ // Mock child components
45
+ jest.mock("../../../TagList", () => () => <div data-testid="tag-list">TagList</div>);
46
+ jest.mock("../MediaUploaders", () => () => <div data-testid="media-uploaders">MediaUploaders</div>);
47
+ jest.mock("../CtaButtons", () => () => <div data-testid="cta-buttons">CtaButtons</div>);
48
+
49
+ // Mock messages
50
+ jest.mock("../../messages", () => ({
51
+ sameContentNote: { id: "sameContentNote", defaultMessage: "Same content note" },
52
+ title: { id: "title", defaultMessage: "Title" },
53
+ titlePlaceholder: { id: "titlePlaceholder", defaultMessage: "Enter title" },
54
+ message: { id: "message", defaultMessage: "Message" },
55
+ messagePlaceholder: { id: "messagePlaceholder", defaultMessage: "Enter message" },
56
+ mediaType: { id: "mediaType", defaultMessage: "Media Type" },
57
+ buttonsAndLinks: { id: "buttonsAndLinks", defaultMessage: "Buttons and Links" },
58
+ optionalText: { id: "optionalText", defaultMessage: "Optional" },
59
+ actionOnClickBody: { id: "actionOnClickBody", defaultMessage: "Action on click" },
60
+ actionDescription: { id: "actionDescription", defaultMessage: "Action description" },
61
+ linkType: { id: "linkType", defaultMessage: "Link Type" },
62
+ selectDeepLink: { id: "selectDeepLink", defaultMessage: "Select deep link" },
63
+ deepLink: { id: "deepLink", defaultMessage: "Deep Link" },
64
+ externalLink: { id: "externalLink", defaultMessage: "External Link" },
65
+ enterExternalLink: { id: "enterExternalLink", defaultMessage: "Enter external link" },
66
+ }));
67
+
68
+ // Mock constants
69
+ jest.mock("../../constants", () => ({
70
+ ANDROID: "android",
71
+ IOS: "ios",
72
+ MEDIA_TYPES_OPTIONS: [
73
+ { value: "IMAGE", label: "Image" },
74
+ { value: "VIDEO", label: "Video" },
75
+ { value: "CAROUSEL", label: "Carousel" },
76
+ ],
77
+ LINK_TYPE_OPTIONS: [
78
+ { value: "DEEP_LINK", label: "Deep Link" },
79
+ { value: "EXTERNAL_LINK", label: "External Link" },
80
+ ],
81
+ DEEP_LINK: "DEEP_LINK",
82
+ EXTERNAL_LINK: "EXTERNAL_LINK",
83
+ }));
84
+
85
+ describe("PlatformContentFields", () => {
86
+ const defaultProps = {
87
+ deviceType: ANDROID,
88
+ content: {
89
+ title: "Test Title",
90
+ message: "Test Message",
91
+ mediaType: "IMAGE",
92
+ actionOnClick: false,
93
+ linkType: DEEP_LINK,
94
+ },
95
+ errors: {
96
+ title: "",
97
+ message: "",
98
+ externalLink: "",
99
+ },
100
+ handlers: {
101
+ handleTitleChange: jest.fn(),
102
+ handleMessageChange: jest.fn(),
103
+ handleMediaTypeChange: jest.fn(),
104
+ handleActionOnClickChange: jest.fn(),
105
+ handleLinkTypeChange: jest.fn(),
106
+ handleDeepLinkChange: jest.fn(),
107
+ handleExternalLinkChange: jest.fn(),
108
+ onTagSelect: jest.fn(),
109
+ handleOnTagsContextChange: jest.fn(),
110
+ },
111
+ tagListProps: {
112
+ tags: ["tag1", "tag2"],
113
+ },
114
+ mediaUploaderProps: {
115
+ uploadProps: "test",
116
+ },
117
+ ctaButtonProps: {
118
+ buttons: [],
119
+ },
120
+ linkProps: {
121
+ deepLink: [
122
+ { value: "link1", label: "Link 1" },
123
+ { value: "link2", label: "Link 2" },
124
+ ],
125
+ deepLinkValue: "link1",
126
+ externalLinkValue: "https://example.com",
127
+ },
128
+ sameContent: false,
129
+ formatMessage: jest.fn((msg) => msg.defaultMessage),
130
+ };
131
+
132
+ const renderComponent = (props = {}) => render(
133
+ <IntlProvider locale="en">
134
+ <PlatformContentFields {...defaultProps} {...props} />
135
+ </IntlProvider>
136
+ );
137
+
138
+ beforeEach(() => {
139
+ jest.clearAllMocks();
140
+ });
141
+
142
+ describe("Basic Rendering", () => {
143
+ it("should render without crashing", () => {
144
+ const { container } = renderComponent();
145
+ expect(container).toBeInTheDocument();
146
+ });
147
+
148
+ it("should render title input with correct value", () => {
149
+ const { container } = renderComponent();
150
+ const titleInput = container.querySelector('input[value="Test Title"]');
151
+ expect(titleInput).toBeInTheDocument();
152
+ });
153
+
154
+ it("should render message input with correct value", () => {
155
+ const { container } = renderComponent();
156
+ const messageInput = container.querySelector('input[value="Test Message"]');
157
+ expect(messageInput).toBeInTheDocument();
158
+ });
159
+
160
+ it("should render MediaUploaders component", () => {
161
+ const { getByTestId } = renderComponent();
162
+ expect(getByTestId("media-uploaders")).toBeInTheDocument();
163
+ });
164
+
165
+ it("should render CtaButtons component", () => {
166
+ const { getByTestId } = renderComponent();
167
+ expect(getByTestId("cta-buttons")).toBeInTheDocument();
168
+ });
169
+
170
+ it("should render TagList components", () => {
171
+ const { getAllByTestId } = renderComponent();
172
+ const tagLists = getAllByTestId("tag-list");
173
+ expect(tagLists).toHaveLength(2);
174
+ });
175
+ });
176
+
177
+ describe("Title Field", () => {
178
+ it("should call title change handler", () => {
179
+ const { container } = renderComponent();
180
+ const titleInput = container.querySelector('input[value="Test Title"]');
181
+
182
+ fireEvent.change(titleInput, { target: { value: "New Title" } });
183
+
184
+ expect(defaultProps.handlers.handleTitleChange).toHaveBeenCalled();
185
+ });
186
+
187
+ it("should display title error when present", () => {
188
+ const { getByTestId } = renderComponent({
189
+ errors: { ...defaultProps.errors, title: "Title is required" },
190
+ });
191
+
192
+ expect(getByTestId("cap-error")).toHaveTextContent("Title is required");
193
+ });
194
+ });
195
+
196
+ describe("Message Field", () => {
197
+ it("should call message change handler", () => {
198
+ const { container } = renderComponent();
199
+ const messageInput = container.querySelector('input[value="Test Message"]');
200
+
201
+ fireEvent.change(messageInput, { target: { value: "New Message" } });
202
+
203
+ expect(defaultProps.handlers.handleMessageChange).toHaveBeenCalled();
204
+ });
205
+
206
+ it("should display message error when present", () => {
207
+ const { getByTestId } = renderComponent({
208
+ errors: { ...defaultProps.errors, message: "Message is required" },
209
+ });
210
+
211
+ expect(getByTestId("cap-error")).toHaveTextContent("Message is required");
212
+ });
213
+ });
214
+
215
+ describe("Media Type Selection", () => {
216
+ it("should call media type change handler", () => {
217
+ const { container } = renderComponent();
218
+ const mediaSelect = container.querySelector('select');
219
+
220
+ fireEvent.change(mediaSelect, { target: { value: "VIDEO" } });
221
+
222
+ expect(defaultProps.handlers.handleMediaTypeChange).toHaveBeenCalled();
223
+ });
224
+ });
225
+
226
+ describe("Action on Click", () => {
227
+ it("should call action on click change handler", () => {
228
+ const { getByTestId } = renderComponent();
229
+ const checkbox = getByTestId("action-checkbox");
230
+
231
+ fireEvent.click(checkbox);
232
+
233
+ expect(defaultProps.handlers.handleActionOnClickChange).toHaveBeenCalled();
234
+ });
235
+
236
+ it("should show action controls when actionOnClick is true", () => {
237
+ const { container } = renderComponent({
238
+ content: { ...defaultProps.content, actionOnClick: true },
239
+ });
240
+
241
+ expect(container.textContent).toContain("Link Type");
242
+ });
243
+
244
+ it("should hide action controls when actionOnClick is false", () => {
245
+ const { container } = renderComponent({
246
+ content: { ...defaultProps.content, actionOnClick: false },
247
+ });
248
+
249
+ expect(container.textContent).not.toContain("Link Type");
250
+ });
251
+ });
252
+
253
+ describe("Device Type Handling", () => {
254
+ it("should render with Android device type", () => {
255
+ const { container } = renderComponent({ deviceType: ANDROID });
256
+ const titleInput = container.querySelector('#mobile-push-title-name-input-android');
257
+ expect(titleInput).toBeInTheDocument();
258
+ });
259
+
260
+ it("should render with iOS device type", () => {
261
+ const { container } = renderComponent({ deviceType: IOS });
262
+ const titleInput = container.querySelector('#mobile-push-title-name-input-ios');
263
+ expect(titleInput).toBeInTheDocument();
264
+ });
265
+ });
266
+
267
+ describe("External Link Input", () => {
268
+ it("should call external link change handler", () => {
269
+ const { container } = renderComponent({
270
+ content: { ...defaultProps.content, actionOnClick: true, linkType: EXTERNAL_LINK },
271
+ });
272
+
273
+ const externalLinkInput = container.querySelector('input[value="https://example.com"]');
274
+
275
+ if (externalLinkInput) {
276
+ fireEvent.change(externalLinkInput, { target: { value: "https://newlink.com" } });
277
+ expect(defaultProps.handlers.handleExternalLinkChange).toHaveBeenCalled();
278
+ }
279
+ });
280
+
281
+ it("should display external link error when present", () => {
282
+ const { getByTestId } = renderComponent({
283
+ content: { ...defaultProps.content, actionOnClick: true, linkType: EXTERNAL_LINK },
284
+ errors: { ...defaultProps.errors, externalLink: "Invalid URL" },
285
+ });
286
+
287
+ expect(getByTestId("cap-error")).toHaveTextContent("Invalid URL");
288
+ });
289
+ });
290
+
291
+ describe("Carousel Media Type", () => {
292
+ it("should hide action controls when mediaType is CAROUSEL", () => {
293
+ const { container } = renderComponent({
294
+ content: { ...defaultProps.content, mediaType: "CAROUSEL" },
295
+ });
296
+
297
+ expect(container.textContent).not.toContain("Buttons and Links");
298
+ });
299
+
300
+ it("should show action controls when mediaType is not CAROUSEL", () => {
301
+ const { container } = renderComponent({
302
+ content: { ...defaultProps.content, mediaType: "IMAGE" },
303
+ });
304
+
305
+ expect(container.textContent).toContain("Buttons and Links");
306
+ });
307
+ });
308
+
309
+ describe("formatMessage Integration", () => {
310
+ it("should call formatMessage with correct arguments", () => {
311
+ renderComponent();
312
+
313
+ expect(defaultProps.formatMessage).toHaveBeenCalledWith(
314
+ expect.objectContaining({
315
+ id: "titlePlaceholder",
316
+ defaultMessage: "Enter title",
317
+ })
318
+ );
319
+ });
320
+ });
321
+
322
+ describe("Error Handling", () => {
323
+ it("should handle missing linkProps gracefully", () => {
324
+ const { container } = renderComponent({
325
+ linkProps: {},
326
+ });
327
+
328
+ expect(container).toBeInTheDocument();
329
+ });
330
+
331
+ it("should handle undefined values gracefully", () => {
332
+ const { container } = renderComponent({
333
+ content: {
334
+ ...defaultProps.content,
335
+ title: undefined,
336
+ message: undefined,
337
+ },
338
+ });
339
+
340
+ expect(container).toBeInTheDocument();
341
+ });
342
+ });
343
+ });
@@ -0,0 +1,115 @@
1
+ export const DEFAULT_ACTION = 'app/Create/DEFAULT_ACTION';
2
+
3
+ export const CREATE_TEMPLATE_REQUEST = 'app/v2Containers/MPUSH_NEW/Create/CREATE_TEMPLATE_REQUEST';
4
+ export const CREATE_TEMPLATE_SUCCESS = 'app/v2Containers/MPUSH_NEW/Create/CREATE_TEMPLATE_SUCCESS';
5
+ export const CREATE_TEMPLATE_FAILURE = 'app/v2Containers/MPUSH_NEW/Create/CREATE_TEMPLATE_FAILURE';
6
+
7
+ export const UPLOAD_ASSET_REQUEST = 'app/v2Containers/MPUSH_NEW/Create/UPLOAD_ASSET_REQUEST';
8
+ export const UPLOAD_ASSET_SUCCESS = 'app/v2Containers/MPUSH_NEW/Create/UPLOAD_ASSET_SUCCESS';
9
+ export const UPLOAD_ASSET_FAILURE = 'app/v2Containers/MPUSH_NEW/Create/UPLOAD_ASSET_FAILURE';
10
+ export const CLEAR_ASSET = 'app/v2Containers/MPUSH_NEW/Create/CLEAR_ASSET';
11
+
12
+ export const CLEAR_CREATE_RESPONSE_REQUEST = 'app/v2Containers/MPUSH_NEW/Create/CLEAR_CREATE_RESPONSE_REQUEST';
13
+ export const CLEAR_CREATE_RESPONSE_SUCCESS = 'app/v2Containers/MPUSH_NEW/Create/CLEAR_CREATE_RESPONSE_SUCCESS';
14
+ export const CLEAR_CREATE_RESPONSE_FAILURE = 'app/v2Containers/MPUSH_NEW/Create/CLEAR_CREATE_RESPONSE_FAILURE';
15
+
16
+ export const GET_IOS_CTAS = 'app/v2Containers/MPUSH_NEW/Create/GET_IOS_CTAS';
17
+ export const GET_IOS_CTAS_SUCCESS = 'app/v2Containers/MPUSH_NEW/Create/GET_IOS_CTAS_SUCCESS';
18
+ export const GET_IOS_CTAS_FAILURE = 'app/v2Containers/MPUSH_NEW/Create/GET_IOS_CTAS_FAILURE';
19
+ export const RESET_STORE = 'app/v2Containers/MPUSH_NEW/Create/RESET_STORE';
20
+ export const GET_TEMPLATE_DETAILS_REQUEST = 'app/v2Containers/MPUSH_NEW/Create/GET_TEMPLATE_DETAILS_REQUEST';
21
+ export const GET_TEMPLATE_DETAILS_SUCCESS = 'app/v2Containers/MPUSH_NEW/Create/GET_TEMPLATE_DETAILS_SUCCESS';
22
+ export const GET_TEMPLATE_DETAILS_FAILURE = 'app/v2Containers/MPUSH_NEW/Create/GET_TEMPLATE_DETAILS_FAILURE';
23
+
24
+ export const EDIT_TEMPLATE_REQUEST = 'app/v2Containers/MPUSH_NEW/Edit/EDIT_TEMPLATE_REQUEST';
25
+ export const EDIT_TEMPLATE_SUCCESS = 'app/v2Containers/MPUSH_NEW/Edit/EDIT_TEMPLATE_SUCCESS';
26
+ export const EDIT_TEMPLATE_FAILURE = 'app/v2Containers/MPUSH_NEW/Edit/EDIT_TEMPLATE_FAILURE';
27
+
28
+ export const CLEAR_EDIT_RESPONSE_REQUEST = 'app/v2Containers/MPUSH_NEW/Edit/CLEAR_EDIT_RESPONSE_REQUEST';
29
+ export const CLEAR_DATA = 'app/v2Containers/MPUSH_NEW/Edit/CLEAR_DATA';
30
+ export const SET_SELECTED_TEMPLATE = 'app/v2Containers/MPUSH_NEW/Edit/SET_SELECTED_TEMPLATE';
31
+
32
+ export const SET_WECHAT_ACCOUNT = "app/v2Containers/MobilePush/SET_WECHAT_ACCOUNT";
33
+ export const GET_WECRM_ACCOUNTS_REQUEST = "app/v2Containers/MobilePush/GET_WECRM_ACCOUNTS_REQUEST";
34
+ export const GET_WECRM_ACCOUNTS_SUCCESS = "app/v2Containers/MobilePush/GET_WECRM_ACCOUNTS_SUCCESS";
35
+ export const GET_WECRM_ACCOUNTS_FAILURE = "app/v2Containers/MobilePush/GET_WECRM_ACCOUNTS_FAILURE";
36
+
37
+ export const GET_MOBILEPUSH_TEMPLATES_LIST_REQUEST = 'app/v2Containers/WeChat/MPUSH_NEW_TEMPLATES_LIST_REQUEST';
38
+ export const GET_MOBILEPUSH_TEMPLATES_LIST_SUCCESS = 'app/v2Containers/WeChat/MPUSH_NEW_TEMPLATES_LIST_SUCCESS';
39
+ export const GET_MOBILEPUSH_TEMPLATES_LIST_FAILURE = 'app/v2Containers/WeChat/MPUSH_NEW_TEMPLATES_LIST_FAILURE';
40
+
41
+ export const MAPP_SDK = 'MAPP_SDK';
42
+
43
+ export const MEDIA_TYPES_OPTIONS = [
44
+ { label: "NONE", value: "NONE" },
45
+ { label: "IMAGE", value: "IMAGE" },
46
+ { label: "VIDEO", value: "VIDEO" },
47
+ { label: "GIF", value: "GIF" },
48
+ { label: "CAROUSEL", value: "CAROUSEL" },
49
+ ];
50
+
51
+ export const MOBILE_PUSH_CHANNEL = "MOBILEPUSH";
52
+ export const ANDROID = "ANDROID";
53
+ export const IOS = "IOS";
54
+ export const ALLOWED_IMAGE_EXTENSIONS_REGEX = /\.(jpe?g|png)$/i;
55
+ export const MPUSH_IMG_SIZE = 2000000; // 2MB
56
+ export const MPUSH_VIDEO_SIZE = 209715200; // 200MB (200 * 1024 * 1024)
57
+ export const ALLOWED_EXTENSIONS_VIDEO_REGEX = /\.(3gp|mp4|mov|m4v)$/i;
58
+ export const ALLOWED_GIF_REGEX = /\.(gif)$/i;
59
+ export const MPUSH_GIF_SIZE = 209715200; // 200MB (200 * 1024 * 1024)
60
+
61
+ // Image dimension limits (in pixels)
62
+ export const MPUSH_IMG_MAX_WIDTH = 2048;
63
+ export const MPUSH_IMG_MAX_HEIGHT = 2048;
64
+
65
+ // File size limits for validation displays
66
+ export const MAX_VIDEO_DURATION = 600; // 10 minutes in seconds
67
+ export const MIN_VIDEO_DURATION = 1; // 1 second minimum
68
+
69
+ export const DEEP_LINK = 'DEEP_LINK';
70
+ export const EXTERNAL_LINK = 'EXTERNAL_LINK';
71
+
72
+ export const LINK_TYPE_OPTIONS = [
73
+ { label: 'Deep Link', value: DEEP_LINK },
74
+ { label: 'External Link', value: EXTERNAL_LINK },
75
+ ];
76
+
77
+ export const EXTERNAL_LINK_LOWERCASE = 'external link';
78
+ export const PRIMARY = 'PRIMARY';
79
+ export const SECONDARY = 'SECONDARY';
80
+
81
+ export const INITIAL_CTA_DATA = [];
82
+
83
+ // Additional validation constants
84
+ export const IMAGE_SIZE_TEXT = '2 MB';
85
+ export const VIDEO_SIZE_TEXT = '200 MB';
86
+ export const GIF_SIZE_TEXT = '200 MB';
87
+ export const IMAGE_FORMAT_TEXT = 'JPEG, PNG';
88
+ export const VIDEO_FORMAT_TEXT = '3GP, MP4, MOV, M4V';
89
+ export const GIF_FORMAT_TEXT = 'GIF';
90
+
91
+ // File size limits for validation
92
+ export const MAX_IMAGE_DIMENSION = 2048; // 2048x2048 pixels
93
+
94
+
95
+ export const IMAGE = "IMAGE";
96
+ export const VIDEO = "VIDEO";
97
+ export const GIF = "GIF";
98
+ export const CAROUSEL = "CAROUSEL";
99
+ export const MANUAL_CAROUSEL = "MANUAL_CAROUSEL";
100
+ export const AUTO_CAROUSEL = "AUTO_CAROUSEL";
101
+ export const FILMSTRIP_CAROUSEL = "FILMSTRIP_CAROUSEL";
102
+ export const TEXT = "TEXT";
103
+ export const BIG_TEXT = "BIG_TEXT";
104
+ export const BIG_PICTURE = "BIG_PICTURE";
105
+ export const INITIAL_CONTENT = {
106
+ title: "",
107
+ message: "",
108
+ mediaType: "NONE",
109
+ buttons: [],
110
+ actionOnClick: false,
111
+ linkType: DEEP_LINK,
112
+ deepLinkValue: "",
113
+ externalLinkValue: "",
114
+ carouselData: [], // Platform-specific carousel data
115
+ };