@capillarytech/creatives-library 8.0.200 → 8.0.201-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.
@@ -21,6 +21,7 @@ import { intlShape } from "react-intl";
21
21
  import "./index.scss";
22
22
  import { GA } from "@capillarytech/cap-ui-utils";
23
23
  import CapNotification from "@capillarytech/cap-ui-library/CapNotification";
24
+ import { CapModal } from "@capillarytech/cap-react-ui-library";
24
25
  import { DAEMON } from "@capillarytech/vulcan-react-sdk/utils/sagaInjectorTypes";
25
26
  import globalMessages from "../Cap/messages";
26
27
  import * as actions from "./actions";
@@ -529,6 +530,9 @@ const MobilePushNew = ({
529
530
  STANDARD_ERROR_MSG: {},
530
531
  LIQUID_ERROR_MSG: {},
531
532
  });
533
+ // Modal state for single platform confirmation
534
+ const [showModal, setShowModal] = useState(false);
535
+ const [modalContent, setModalContent] = useState({});
532
536
  const [androidContent, setAndroidContent] = useState(INITIAL_CONTENT);
533
537
 
534
538
  const [iosContent, setIosContent] = useState(INITIAL_CONTENT);
@@ -2130,39 +2134,93 @@ const MobilePushNew = ({
2130
2134
  return panes;
2131
2135
  }, [isAndroidSupported, isIosSupported, renderContentFields, formatMessage]);
2132
2136
 
2133
- // Save button disabled logic: only check enabled platforms
2137
+ // Save button disabled logic: require at least one platform to have data
2138
+ const hasAndroidData = isAndroidSupported && androidContent?.title?.trim() && androidContent?.message?.trim();
2139
+ const hasIosData = isIosSupported && iosContent?.title?.trim() && iosContent?.message?.trim();
2140
+ const hasAnyPlatformData = hasAndroidData || hasIosData;
2141
+
2142
+ // Validation checks for save button
2143
+ const carouselErrors = Object.values(carouselLinkErrors).some((error) => error !== null && error !== "");
2144
+ const carouselValid = isCarouselDataValid();
2145
+
2134
2146
  const isSaveDisabled = (
2135
- (isAndroidSupported && (!androidContent?.title?.trim() || !androidContent?.message?.trim()))
2136
- || (isIosSupported && (!iosContent?.title?.trim() || !iosContent?.message?.trim()))
2137
- || templateNameError
2138
- || Object.values(carouselLinkErrors).some((error) => error !== null && error !== "")
2139
- || !isCarouselDataValid()
2147
+ !hasAnyPlatformData // At least one supported platform must have data
2148
+ || (isFullMode && (!templateName || !templateName.trim())) // Template name required in full mode
2149
+ || carouselErrors
2150
+ || !carouselValid
2140
2151
  );
2141
2152
 
2142
- // Validation in handleSave: only show errors for enabled platforms
2143
- const handleSave = useCallback(() => {
2144
- if (isAndroidSupported && (!androidContent?.title?.trim() || !androidContent?.message?.trim())) {
2145
- CapNotification.error({
2146
- message: formatMessage(messages.androidValidationError),
2147
- });
2148
- if (onValidationFail) onValidationFail();
2149
- return;
2153
+ // Modal handler functions
2154
+ const setModalContentHandler = useCallback((type) => {
2155
+ if (type === 'ios') {
2156
+ const content = {
2157
+ title: formatMessage(messages.alertMessage),
2158
+ body: formatMessage(messages.iosTemplateNotConfigured),
2159
+ type: 'confirm',
2160
+ id: 'ios',
2161
+ };
2162
+ setModalContent(content);
2163
+ setShowModal(true);
2164
+ } else if (type === 'android') {
2165
+ const content = {
2166
+ title: formatMessage(messages.alertMessage),
2167
+ body: formatMessage(messages.androidTemplateNotConfigured),
2168
+ type: 'confirm',
2169
+ id: 'android',
2170
+ };
2171
+ setModalContent(content);
2172
+ setShowModal(true);
2150
2173
  }
2151
- if (isIosSupported && (!iosContent?.title?.trim() || !iosContent?.message?.trim())) {
2152
- CapNotification.error({
2153
- message: formatMessage(messages.iosValidationError),
2154
- });
2155
- if (onValidationFail) onValidationFail();
2156
- return;
2174
+ }, [formatMessage]);
2175
+
2176
+ const handleCancelModal = useCallback(() => {
2177
+ setShowModal(false);
2178
+ setModalContent({});
2179
+ }, []);
2180
+
2181
+ // Internal save function with optional modal validation skip
2182
+ const handleSaveInternal = useCallback((skipModalValidation = false) => {
2183
+ // Check for single platform data and show modal confirmation (unless skipped)
2184
+ if (!skipModalValidation) {
2185
+ const androidHasData = androidContent?.title?.trim() && androidContent?.message?.trim();
2186
+ const iosHasData = iosContent?.title?.trim() && iosContent?.message?.trim();
2187
+
2188
+ // If both platforms are supported but only one has data, show confirmation modal
2189
+ if (isAndroidSupported && isIosSupported) {
2190
+ if (androidHasData && !iosHasData) {
2191
+ setModalContentHandler('ios'); // Show iOS not configured modal
2192
+ return;
2193
+ }
2194
+ if (iosHasData && !androidHasData) {
2195
+ setModalContentHandler('android'); // Show Android not configured modal
2196
+ return;
2197
+ }
2198
+ }
2157
2199
  }
2158
- if (templateNameError) {
2159
- CapNotification.error({
2160
- message: formatMessage(messages.emptyTemplateErrorMessage),
2161
- });
2162
- return;
2200
+
2201
+ // Only validate platforms that have data or are required
2202
+ // If user confirmed via modal, we allow single platform data
2203
+ if (!skipModalValidation) {
2204
+ // In normal flow, require data for all supported platforms
2205
+ if (isAndroidSupported && (!androidContent?.title?.trim() || !androidContent?.message?.trim())) {
2206
+ CapNotification.error({
2207
+ message: formatMessage(messages.androidValidationError),
2208
+ });
2209
+ if (onValidationFail) onValidationFail();
2210
+ return;
2211
+ }
2212
+ if (isIosSupported && (!iosContent?.title?.trim() || !iosContent?.message?.trim())) {
2213
+ CapNotification.error({
2214
+ message: formatMessage(messages.iosValidationError),
2215
+ });
2216
+ if (onValidationFail) onValidationFail();
2217
+ return;
2218
+ }
2163
2219
  }
2164
- // Only require templateName in full mode
2165
- // Use ref to get the latest template name value for validation
2220
+ // Note: In modal-confirmed flow (skipModalValidation = true), we skip platform validation
2221
+ // since user has already confirmed they want to save with incomplete platform data
2222
+
2223
+ // Template name validation - only required in full mode
2166
2224
  const currentTemplateName = templateNameRef.current || templateName;
2167
2225
  if (isFullMode && !currentTemplateName?.trim()) {
2168
2226
  CapNotification.error({
@@ -2327,6 +2385,8 @@ const MobilePushNew = ({
2327
2385
  }
2328
2386
 
2329
2387
  // Create payload with enabled platform content and intl
2388
+ // In modal-confirmed flow, we may have intentionally missing platform data
2389
+ const allowSinglePlatform = skipModalValidation;
2330
2390
  const payload = createMobilePushPayloadWithIntl({
2331
2391
  templateName: finalTemplateName,
2332
2392
  androidContent: isAndroidSupported ? processedAndroidContent : undefined,
@@ -2337,6 +2397,7 @@ const MobilePushNew = ({
2337
2397
  sameContent,
2338
2398
  options: {
2339
2399
  mode: params?.mode,
2400
+ allowSinglePlatform,
2340
2401
  },
2341
2402
  intl,
2342
2403
  });
@@ -2516,6 +2577,68 @@ const MobilePushNew = ({
2516
2577
  isCarouselDataValid,
2517
2578
  isFullMode,
2518
2579
  templateId,
2580
+ activeTab,
2581
+ setModalContentHandler,
2582
+ ]);
2583
+
2584
+ // Public save function (with modal validation)
2585
+ const handleSave = useCallback(() => {
2586
+ handleSaveInternal(false);
2587
+ }, [handleSaveInternal]);
2588
+
2589
+ // Save function that skips single platform modal validation
2590
+ const handleSaveWithoutModal = useCallback(() => {
2591
+ handleSaveInternal(true);
2592
+ }, [handleSaveInternal]);
2593
+
2594
+ const handleConfirmModal = useCallback(() => {
2595
+ setShowModal(false);
2596
+ setModalContent({});
2597
+ // Proceed with save after modal confirmation - skip single platform validation
2598
+ handleSaveWithoutModal();
2599
+ }, [handleSaveWithoutModal]);
2600
+
2601
+ const liquidMiddleWare = useCallback(() => {
2602
+ const onError = ({ standardErrors, liquidErrors }) => {
2603
+ setErrorMessage((prev) => ({
2604
+ STANDARD_ERROR_MSG: { ...prev.STANDARD_ERROR_MSG, ...standardErrors },
2605
+ LIQUID_ERROR_MSG: { ...prev.LIQUID_ERROR_MSG, ...liquidErrors },
2606
+ }));
2607
+ };
2608
+ const onSuccess = () => handleSave();
2609
+
2610
+ validateMobilePushContent([androidContent, iosContent], {
2611
+ currentTab: activeTab === ANDROID ? 1 : 2,
2612
+ onError,
2613
+ onSuccess,
2614
+ getLiquidTags: globalActionsProps.getLiquidTags,
2615
+ formatMessage,
2616
+ messages: formBuilderMessages,
2617
+ tagLookupMap: metaEntities?.tagLookupMap || {},
2618
+ eventContextTags: metaEntities?.eventContextTags || [],
2619
+ isLiquidFlow: hasLiquidSupportFeature(),
2620
+ forwardedTags: {},
2621
+ skipTags: (tag) => {
2622
+ const skipRegexes = [
2623
+ /dynamic_expiry_date_after_\d+_days\.FORMAT_\d/,
2624
+ /unsubscribe\(#[a-zA-Z\d]{6}\)/,
2625
+ /Link_to_[a-zA-z]/,
2626
+ /SURVEY.*\.TOKEN/,
2627
+ /^[A-Za-z].*\([a-zA-Z\d]*\)/,
2628
+ ];
2629
+ return skipRegexes.some((regex) => regex.test(tag));
2630
+ },
2631
+ singleTab: getSingleTab(accountData),
2632
+ });
2633
+ }, [
2634
+ androidContent,
2635
+ iosContent,
2636
+ activeTab,
2637
+ globalActionsProps,
2638
+ formatMessage,
2639
+ metaEntities,
2640
+ accountData,
2641
+ handleSave,
2519
2642
  ]);
2520
2643
 
2521
2644
  // Helper to sync content between platforms
@@ -2547,7 +2670,9 @@ const MobilePushNew = ({
2547
2670
  setTemplateName(value);
2548
2671
  // Update ref to always have the latest value
2549
2672
  templateNameRef.current = value;
2550
- const isInvalid = !value || value.trim() === "";
2673
+ // Only set error if user has interacted and field is empty
2674
+ // In full mode, template name is required only at save time, not during typing
2675
+ const isInvalid = isFullMode && value.trim() === "";
2551
2676
  setTemplateNameError(isInvalid);
2552
2677
  if (value && onEnterTemplateName) {
2553
2678
  onEnterTemplateName();
@@ -2555,7 +2680,7 @@ const MobilePushNew = ({
2555
2680
  onRemoveTemplateName();
2556
2681
  }
2557
2682
  },
2558
- [onEnterTemplateName, onRemoveTemplateName]
2683
+ [onEnterTemplateName, onRemoveTemplateName, isFullMode]
2559
2684
  );
2560
2685
 
2561
2686
  // --- Only show template name input in full mode (not library/consumer mode) ---
@@ -2584,47 +2709,6 @@ const MobilePushNew = ({
2584
2709
  [isFullMode, formatMessage, templateName, onTemplateNameChange, templateNameError, params?.id]
2585
2710
  );
2586
2711
 
2587
- const liquidMiddleWare = useCallback(() => {
2588
- const onError = ({ standardErrors, liquidErrors }) => {
2589
- setErrorMessage((prev) => ({
2590
- STANDARD_ERROR_MSG: { ...prev.STANDARD_ERROR_MSG, ...standardErrors },
2591
- LIQUID_ERROR_MSG: { ...prev.LIQUID_ERROR_MSG, ...liquidErrors },
2592
- }));
2593
- };
2594
- const onSuccess = () => handleSave();
2595
-
2596
- validateMobilePushContent([androidContent, iosContent], {
2597
- currentTab: activeTab === ANDROID ? 1 : 2,
2598
- onError,
2599
- onSuccess,
2600
- getLiquidTags: globalActionsProps.getLiquidTags,
2601
- formatMessage,
2602
- messages: formBuilderMessages,
2603
- tagLookupMap: metaEntities?.tagLookupMap || {},
2604
- eventContextTags: metaEntities?.eventContextTags || [],
2605
- isLiquidFlow: hasLiquidSupportFeature(),
2606
- forwardedTags: {},
2607
- skipTags: (tag) => {
2608
- const skipRegexes = [
2609
- /dynamic_expiry_date_after_\d+_days\.FORMAT_\d/,
2610
- /unsubscribe\(#[a-zA-Z\d]{6}\)/,
2611
- /Link_to_[a-zA-z]/,
2612
- /SURVEY.*\.TOKEN/,
2613
- /^[A-Za-z].*\([a-zA-Z\d]*\)/,
2614
- ];
2615
- return skipRegexes.some((regex) => regex.test(tag));
2616
- },
2617
- singleTab: getSingleTab(accountData),
2618
- });
2619
- }, [
2620
- androidContent,
2621
- iosContent,
2622
- activeTab,
2623
- globalActionsProps,
2624
- formatMessage,
2625
- metaEntities,
2626
- accountData,
2627
- ]);
2628
2712
 
2629
2713
  const isLiquidFlow = hasLiquidSupportFeature();
2630
2714
 
@@ -2945,6 +3029,24 @@ const MobilePushNew = ({
2945
3029
  />
2946
3030
  </CapColumn>
2947
3031
  </CapRow>
3032
+
3033
+ {/* Modal for single platform confirmation */}
3034
+ <CapModal
3035
+ visible={showModal}
3036
+ title={modalContent.title}
3037
+ onOk={handleConfirmModal}
3038
+ onCancel={handleCancelModal}
3039
+ footer={[
3040
+ <CapButton key="cancel" onClick={handleCancelModal}>
3041
+ No
3042
+ </CapButton>,
3043
+ <CapButton key="confirm" type="primary" onClick={handleConfirmModal}>
3044
+ Yes
3045
+ </CapButton>,
3046
+ ]}
3047
+ >
3048
+ {modalContent.body}
3049
+ </CapModal>
2948
3050
  </CapSpin>
2949
3051
  );
2950
3052
  };
@@ -91,6 +91,10 @@ export default defineMessages({
91
91
  id: `${scope}.actionOnClickBody`,
92
92
  defaultMessage: 'Action on click of notification body',
93
93
  },
94
+ carouselActionDisabledMessage: {
95
+ id: `${scope}.carouselActionDisabledMessage`,
96
+ defaultMessage: 'This section is being revamped. Till then it will remain disabled.',
97
+ },
94
98
  actionDescription: {
95
99
  id: `${scope}.actionDescription`,
96
100
  defaultMessage: 'Define where the users will redirect when they click on the body of the push notification',
@@ -252,6 +256,10 @@ export default defineMessages({
252
256
  id: `${scope}.contentValidationError`,
253
257
  defaultMessage: '{platform} content must have title and message',
254
258
  },
259
+ singlePlatformContentMissing: {
260
+ id: `${scope}.singlePlatformContentMissing`,
261
+ defaultMessage: 'At least one platform must have title and message',
262
+ },
255
263
  // File validation error messages for useUpload.js
256
264
  fileSizeError: {
257
265
  id: `${scope}.fileSizeError`,
@@ -269,4 +277,17 @@ export default defineMessages({
269
277
  id: `${scope}.gifFileTypeError`,
270
278
  defaultMessage: 'Only GIF files are allowed',
271
279
  },
280
+ // Modal confirmation messages for single platform data
281
+ alertMessage: {
282
+ id: `${scope}.alertMessage`,
283
+ defaultMessage: 'Alert',
284
+ },
285
+ androidTemplateNotConfigured: {
286
+ id: `${scope}.androidTemplateNotConfigured`,
287
+ defaultMessage: 'Android template is not configured. Continue save?',
288
+ },
289
+ iosTemplateNotConfigured: {
290
+ id: `${scope}.iosTemplateNotConfigured`,
291
+ defaultMessage: 'IOS template is not configured, Save without IOS template',
292
+ },
272
293
  });
@@ -24,7 +24,12 @@ export function* createTemplate({template, callback}) {
24
24
  errorMsg,
25
25
  });
26
26
  } catch (error) {
27
- yield put({ type: types.CREATE_TEMPLATE_FAILURE, error, errorMsg });
27
+ // Call callback with error if provided, otherwise dispatch failure action
28
+ if (callback) {
29
+ yield call(callback, new Error(errorMsg || error.message || error.toString()));
30
+ } else {
31
+ yield put({ type: types.CREATE_TEMPLATE_FAILURE, error, errorMsg });
32
+ }
28
33
  }
29
34
  }
30
35
  export function* uploadAsset(action) {
@@ -91,7 +96,12 @@ export function* editTemplate({ template, callback }) {
91
96
  yield call(callback, editResponseData);
92
97
  }
93
98
  } catch (error) {
94
- yield put({ type: types.EDIT_TEMPLATE_FAILURE, error, errorMsg });
99
+ // Call callback with error if provided, otherwise dispatch failure action
100
+ if (callback) {
101
+ yield call(callback, new Error(errorMsg || error.message || error.toString()));
102
+ } else {
103
+ yield put({ type: types.EDIT_TEMPLATE_FAILURE, error, errorMsg });
104
+ }
95
105
  }
96
106
  }
97
107
 
@@ -87,11 +87,7 @@ describe('MobilePushNew Sagas', () => {
87
87
  [matchers.call.fn(Api.createMobilePushTemplateV2), mockResponse],
88
88
  ])
89
89
  .call(Api.createMobilePushTemplateV2, template)
90
- .put({
91
- type: types.CREATE_TEMPLATE_FAILURE,
92
- error: 'Bad Request',
93
- errorMsg: 'Bad Request',
94
- })
90
+ .call(callback, new Error('Bad Request'))
95
91
  .run();
96
92
  });
97
93
 
@@ -125,11 +121,7 @@ describe('MobilePushNew Sagas', () => {
125
121
  [matchers.call.fn(Api.createMobilePushTemplateV2), throwError(error)],
126
122
  ])
127
123
  .call(Api.createMobilePushTemplateV2, template)
128
- .put({
129
- type: types.CREATE_TEMPLATE_FAILURE,
130
- error,
131
- errorMsg: undefined,
132
- })
124
+ .call(callback, new Error('Network error'))
133
125
  .run();
134
126
  });
135
127
 
@@ -372,11 +364,7 @@ describe('MobilePushNew Sagas', () => {
372
364
  [matchers.call.fn(Api.createMobilePushTemplateV2), mockResponse],
373
365
  ])
374
366
  .call(Api.createMobilePushTemplateV2, template)
375
- .put({
376
- type: types.EDIT_TEMPLATE_FAILURE,
377
- error: 'Bad Request',
378
- errorMsg: 'Bad Request',
379
- })
367
+ .call(callback, new Error('Bad Request'))
380
368
  .run();
381
369
  });
382
370
 
@@ -392,11 +380,7 @@ describe('MobilePushNew Sagas', () => {
392
380
  [matchers.call.fn(Api.createMobilePushTemplateV2), mockResponse],
393
381
  ])
394
382
  .call(Api.createMobilePushTemplateV2, template)
395
- .put({
396
- type: types.EDIT_TEMPLATE_FAILURE,
397
- error: 'Internal Server Error',
398
- errorMsg: 'Internal Server Error',
399
- })
383
+ .call(callback, new Error('Internal Server Error'))
400
384
  .run();
401
385
  });
402
386
 
@@ -408,11 +392,7 @@ describe('MobilePushNew Sagas', () => {
408
392
  [matchers.call.fn(Api.createMobilePushTemplateV2), throwError(error)],
409
393
  ])
410
394
  .call(Api.createMobilePushTemplateV2, template)
411
- .put({
412
- type: types.EDIT_TEMPLATE_FAILURE,
413
- error,
414
- errorMsg: undefined,
415
- })
395
+ .call(callback, new Error('Network error'))
416
396
  .run();
417
397
  });
418
398
 
@@ -459,11 +439,7 @@ describe('MobilePushNew Sagas', () => {
459
439
  [matchers.call.fn(Api.createMobilePushTemplateV2), mockResponse],
460
440
  ])
461
441
  .call(Api.createMobilePushTemplateV2, template)
462
- .put({
463
- type: types.EDIT_TEMPLATE_FAILURE,
464
- error: 'HTTP Error 400',
465
- errorMsg: 'HTTP Error 400',
466
- })
442
+ .call(callback, new Error('HTTP Error 400'))
467
443
  .run();
468
444
  });
469
445
 
@@ -479,11 +455,7 @@ describe('MobilePushNew Sagas', () => {
479
455
  [matchers.call.fn(Api.createMobilePushTemplateV2), mockResponse],
480
456
  ])
481
457
  .call(Api.createMobilePushTemplateV2, template)
482
- .put({
483
- type: types.EDIT_TEMPLATE_FAILURE,
484
- error: 'HTTP Error 404',
485
- errorMsg: 'HTTP Error 404',
486
- })
458
+ .call(callback, new Error('HTTP Error 404'))
487
459
  .run();
488
460
  });
489
461
 
@@ -499,11 +471,7 @@ describe('MobilePushNew Sagas', () => {
499
471
  [matchers.call.fn(Api.createMobilePushTemplateV2), mockResponse],
500
472
  ])
501
473
  .call(Api.createMobilePushTemplateV2, template)
502
- .put({
503
- type: types.EDIT_TEMPLATE_FAILURE,
504
- error: 'HTTP Error 422',
505
- errorMsg: 'HTTP Error 422',
506
- })
474
+ .call(callback, new Error('HTTP Error 422'))
507
475
  .run();
508
476
  });
509
477
 
@@ -519,11 +487,7 @@ describe('MobilePushNew Sagas', () => {
519
487
  [matchers.call.fn(Api.createMobilePushTemplateV2), mockResponse],
520
488
  ])
521
489
  .call(Api.createMobilePushTemplateV2, template)
522
- .put({
523
- type: types.EDIT_TEMPLATE_FAILURE,
524
- error: 'HTTP Error 403',
525
- errorMsg: 'HTTP Error 403',
526
- })
490
+ .call(callback, new Error('HTTP Error 403'))
527
491
  .run();
528
492
  });
529
493
 
@@ -1357,19 +1357,16 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
1357
1357
  break;
1358
1358
  }
1359
1359
  case MOBILE_PUSH:
1360
- if (!commonUtil.hasNewMobilePushFeatureEnabled()) {
1361
- templateData.content = template;
1362
- } else {
1363
- const mpushData = get(template, 'versions.base', template);
1364
- const androidData = get(mpushData, 'ANDROID') || get(mpushData, 'androidContent');
1365
- const iosData = get(mpushData, 'IOS') || get(mpushData, 'iosContent');
1366
- let mpushListingData = androidData;
1367
- if (isEmpty(androidData) || !androidData?.title) {
1368
- mpushListingData = iosData;
1369
- };
1370
- const { title, message, expandableDetails: { style = '', image, carouselData = [], ctas = [], media = [] } = {} } = mpushListingData || {};
1371
- const {url = ''} = media?.[0] || {};
1372
- templateData.content = (
1360
+ const mpushData = get(template, 'versions.base', template);
1361
+ const androidData = get(mpushData, 'ANDROID') || get(mpushData, 'androidContent');
1362
+ const iosData = get(mpushData, 'IOS') || get(mpushData, 'iosContent');
1363
+ let mpushListingData = androidData;
1364
+ if (isEmpty(androidData) || !androidData?.title) {
1365
+ mpushListingData = iosData;
1366
+ };
1367
+ const { title, message, expandableDetails: { style = '', image, carouselData = [], ctas = [], media = [] } = {} } = mpushListingData || {};
1368
+ const {url = ''} = media?.[0] || {};
1369
+ templateData.content = (
1373
1370
  <div className='mobilepush-container'>
1374
1371
  <div className="app-header">
1375
1372
  <div className="app-header-left">
@@ -1441,8 +1438,7 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
1441
1438
  )}
1442
1439
  </div>
1443
1440
  );
1444
- templateData.isNewMobilePush = commonUtil.hasNewMobilePushFeatureEnabled();
1445
- }
1441
+ templateData.isNewMobilePush = true;
1446
1442
  break;
1447
1443
  case INAPP:
1448
1444
  templateData.content = template;