@capillarytech/creatives-library 8.0.201 → 8.0.204
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.
- package/constants/unified.js +1 -0
- package/package.json +1 -1
- package/utils/common.js +7 -1
- package/utils/createMobilePushPayload.js +8 -29
- package/utils/tests/createMobilePushPayload.test.js +0 -53
- package/v2Components/FormBuilder/index.js +0 -300
- package/v2Components/TemplatePreview/_templatePreview.scss +4 -3
- package/v2Components/TemplatePreview/index.js +2 -2
- package/v2Containers/BeeEditor/index.js +1 -1
- package/v2Containers/CreativesContainer/SlideBoxContent.js +6 -2
- package/v2Containers/CreativesContainer/index.js +17 -62
- package/v2Containers/CreativesContainer/tests/SlideBoxContent.test.js +0 -317
- package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxContent.test.js.snap +0 -727
- package/v2Containers/Email/index.js +0 -3
- package/v2Containers/MobilePushNew/components/MediaUploaders.js +6 -13
- package/v2Containers/MobilePushNew/components/tests/MediaUploaders.test.js +15 -3
- package/v2Containers/MobilePushNew/index.js +70 -172
- package/v2Containers/MobilePushNew/messages.js +0 -21
- package/v2Containers/MobilePushNew/sagas.js +0 -8
- package/v2Containers/MobilePushNew/tests/sagas.test.js +45 -11
- package/v2Containers/Templates/index.js +15 -11
|
@@ -2516,9 +2516,6 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
|
|
|
2516
2516
|
});
|
|
2517
2517
|
obj.versions.history.push(newdata);
|
|
2518
2518
|
}
|
|
2519
|
-
if (index === "template-subject") {
|
|
2520
|
-
obj.versions.history[0].subject = newdata;
|
|
2521
|
-
}
|
|
2522
2519
|
});
|
|
2523
2520
|
//const data = formData[`${this.state.currentTab - 1}`];
|
|
2524
2521
|
obj.name = formData['template-name'];
|
|
@@ -20,7 +20,6 @@ import CapLabel from "@capillarytech/cap-ui-library/CapLabel";
|
|
|
20
20
|
import CapSelect from "@capillarytech/cap-ui-library/CapSelect";
|
|
21
21
|
import CapInput from "@capillarytech/cap-ui-library/CapInput";
|
|
22
22
|
import CapError from "@capillarytech/cap-ui-library/CapError";
|
|
23
|
-
import CapTooltip from "@capillarytech/cap-ui-library/CapTooltip";
|
|
24
23
|
import CapImageUpload from "../../../v2Components/CapImageUpload";
|
|
25
24
|
import CapVideoUpload from "../../../v2Components/CapVideoUpload";
|
|
26
25
|
import {
|
|
@@ -601,19 +600,13 @@ const MediaUploaders = ({
|
|
|
601
600
|
<FormattedMessage {...messages.optionalText} />
|
|
602
601
|
</CapLabel>
|
|
603
602
|
</CapRow>
|
|
604
|
-
<
|
|
605
|
-
|
|
606
|
-
|
|
603
|
+
<CapCheckbox
|
|
604
|
+
checked={button.actionOnClick}
|
|
605
|
+
onChange={(e) => handleCarouselActionOnClickChange(cardIndex, e.target.checked)}
|
|
606
|
+
className="action-on-click-checkbox"
|
|
607
607
|
>
|
|
608
|
-
<
|
|
609
|
-
|
|
610
|
-
onChange={(e) => handleCarouselActionOnClickChange(cardIndex, e.target.checked)}
|
|
611
|
-
className="action-on-click-checkbox"
|
|
612
|
-
disabled={true}
|
|
613
|
-
>
|
|
614
|
-
<FormattedMessage {...messages.actionOnClickBody} />
|
|
615
|
-
</CapCheckbox>
|
|
616
|
-
</CapTooltip>
|
|
608
|
+
<FormattedMessage {...messages.actionOnClickBody} />
|
|
609
|
+
</CapCheckbox>
|
|
617
610
|
<CapRow>
|
|
618
611
|
<CapLabel className="action-description">
|
|
619
612
|
<FormattedMessage {...messages.actionDescription} />
|
|
@@ -1132,7 +1132,7 @@ describe('MediaUploaders', () => {
|
|
|
1132
1132
|
});
|
|
1133
1133
|
|
|
1134
1134
|
describe('Carousel action link handlers', () => {
|
|
1135
|
-
it('should
|
|
1135
|
+
it('should handle carousel action on click change', () => {
|
|
1136
1136
|
const onCarouselDataChange = jest.fn();
|
|
1137
1137
|
renderComponent({
|
|
1138
1138
|
mediaType: 'CAROUSEL',
|
|
@@ -1151,10 +1151,22 @@ describe('MediaUploaders', () => {
|
|
|
1151
1151
|
onCarouselDataChange,
|
|
1152
1152
|
});
|
|
1153
1153
|
|
|
1154
|
-
//
|
|
1154
|
+
// Find checkbox by class name since it renders with cap-checkbox-v2
|
|
1155
1155
|
const checkbox = document.querySelector('.cap-checkbox-v2 input[type="checkbox"]');
|
|
1156
1156
|
if (checkbox) {
|
|
1157
|
-
|
|
1157
|
+
fireEvent.click(checkbox);
|
|
1158
|
+
expect(onCarouselDataChange).toHaveBeenCalledWith(
|
|
1159
|
+
ANDROID,
|
|
1160
|
+
expect.arrayContaining([
|
|
1161
|
+
expect.objectContaining({
|
|
1162
|
+
buttons: expect.arrayContaining([
|
|
1163
|
+
expect.objectContaining({
|
|
1164
|
+
actionOnClick: true,
|
|
1165
|
+
})
|
|
1166
|
+
])
|
|
1167
|
+
})
|
|
1168
|
+
])
|
|
1169
|
+
);
|
|
1158
1170
|
} else {
|
|
1159
1171
|
// If checkbox not found, just verify component renders
|
|
1160
1172
|
expect(screen.getByTestId('cap-image-upload')).toBeInTheDocument();
|
|
@@ -21,7 +21,6 @@ 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";
|
|
25
24
|
import { DAEMON } from "@capillarytech/vulcan-react-sdk/utils/sagaInjectorTypes";
|
|
26
25
|
import globalMessages from "../Cap/messages";
|
|
27
26
|
import * as actions from "./actions";
|
|
@@ -530,9 +529,6 @@ const MobilePushNew = ({
|
|
|
530
529
|
STANDARD_ERROR_MSG: {},
|
|
531
530
|
LIQUID_ERROR_MSG: {},
|
|
532
531
|
});
|
|
533
|
-
// Modal state for single platform confirmation
|
|
534
|
-
const [showModal, setShowModal] = useState(false);
|
|
535
|
-
const [modalContent, setModalContent] = useState({});
|
|
536
532
|
const [androidContent, setAndroidContent] = useState(INITIAL_CONTENT);
|
|
537
533
|
|
|
538
534
|
const [iosContent, setIosContent] = useState(INITIAL_CONTENT);
|
|
@@ -2134,93 +2130,39 @@ const MobilePushNew = ({
|
|
|
2134
2130
|
return panes;
|
|
2135
2131
|
}, [isAndroidSupported, isIosSupported, renderContentFields, formatMessage]);
|
|
2136
2132
|
|
|
2137
|
-
// Save button disabled logic:
|
|
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
|
-
|
|
2133
|
+
// Save button disabled logic: only check enabled platforms
|
|
2146
2134
|
const isSaveDisabled = (
|
|
2147
|
-
|
|
2148
|
-
|| (
|
|
2149
|
-
||
|
|
2150
|
-
||
|
|
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()
|
|
2151
2140
|
);
|
|
2152
2141
|
|
|
2153
|
-
//
|
|
2154
|
-
const
|
|
2155
|
-
if (
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
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);
|
|
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;
|
|
2173
2150
|
}
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
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
|
-
}
|
|
2151
|
+
if (isIosSupported && (!iosContent?.title?.trim() || !iosContent?.message?.trim())) {
|
|
2152
|
+
CapNotification.error({
|
|
2153
|
+
message: formatMessage(messages.iosValidationError),
|
|
2154
|
+
});
|
|
2155
|
+
if (onValidationFail) onValidationFail();
|
|
2156
|
+
return;
|
|
2199
2157
|
}
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
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
|
-
}
|
|
2158
|
+
if (templateNameError) {
|
|
2159
|
+
CapNotification.error({
|
|
2160
|
+
message: formatMessage(messages.emptyTemplateErrorMessage),
|
|
2161
|
+
});
|
|
2162
|
+
return;
|
|
2219
2163
|
}
|
|
2220
|
-
//
|
|
2221
|
-
//
|
|
2222
|
-
|
|
2223
|
-
// Template name validation - only required in full mode
|
|
2164
|
+
// Only require templateName in full mode
|
|
2165
|
+
// Use ref to get the latest template name value for validation
|
|
2224
2166
|
const currentTemplateName = templateNameRef.current || templateName;
|
|
2225
2167
|
if (isFullMode && !currentTemplateName?.trim()) {
|
|
2226
2168
|
CapNotification.error({
|
|
@@ -2385,8 +2327,6 @@ const MobilePushNew = ({
|
|
|
2385
2327
|
}
|
|
2386
2328
|
|
|
2387
2329
|
// Create payload with enabled platform content and intl
|
|
2388
|
-
// In modal-confirmed flow, we may have intentionally missing platform data
|
|
2389
|
-
const allowSinglePlatform = skipModalValidation;
|
|
2390
2330
|
const payload = createMobilePushPayloadWithIntl({
|
|
2391
2331
|
templateName: finalTemplateName,
|
|
2392
2332
|
androidContent: isAndroidSupported ? processedAndroidContent : undefined,
|
|
@@ -2397,7 +2337,6 @@ const MobilePushNew = ({
|
|
|
2397
2337
|
sameContent,
|
|
2398
2338
|
options: {
|
|
2399
2339
|
mode: params?.mode,
|
|
2400
|
-
allowSinglePlatform,
|
|
2401
2340
|
},
|
|
2402
2341
|
intl,
|
|
2403
2342
|
});
|
|
@@ -2577,68 +2516,6 @@ const MobilePushNew = ({
|
|
|
2577
2516
|
isCarouselDataValid,
|
|
2578
2517
|
isFullMode,
|
|
2579
2518
|
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,
|
|
2642
2519
|
]);
|
|
2643
2520
|
|
|
2644
2521
|
// Helper to sync content between platforms
|
|
@@ -2670,9 +2547,7 @@ const MobilePushNew = ({
|
|
|
2670
2547
|
setTemplateName(value);
|
|
2671
2548
|
// Update ref to always have the latest value
|
|
2672
2549
|
templateNameRef.current = value;
|
|
2673
|
-
|
|
2674
|
-
// In full mode, template name is required only at save time, not during typing
|
|
2675
|
-
const isInvalid = isFullMode && value.trim() === "";
|
|
2550
|
+
const isInvalid = !value || value.trim() === "";
|
|
2676
2551
|
setTemplateNameError(isInvalid);
|
|
2677
2552
|
if (value && onEnterTemplateName) {
|
|
2678
2553
|
onEnterTemplateName();
|
|
@@ -2680,7 +2555,7 @@ const MobilePushNew = ({
|
|
|
2680
2555
|
onRemoveTemplateName();
|
|
2681
2556
|
}
|
|
2682
2557
|
},
|
|
2683
|
-
[onEnterTemplateName, onRemoveTemplateName
|
|
2558
|
+
[onEnterTemplateName, onRemoveTemplateName]
|
|
2684
2559
|
);
|
|
2685
2560
|
|
|
2686
2561
|
// --- Only show template name input in full mode (not library/consumer mode) ---
|
|
@@ -2709,6 +2584,47 @@ const MobilePushNew = ({
|
|
|
2709
2584
|
[isFullMode, formatMessage, templateName, onTemplateNameChange, templateNameError, params?.id]
|
|
2710
2585
|
);
|
|
2711
2586
|
|
|
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
|
+
]);
|
|
2712
2628
|
|
|
2713
2629
|
const isLiquidFlow = hasLiquidSupportFeature();
|
|
2714
2630
|
|
|
@@ -3029,24 +2945,6 @@ const MobilePushNew = ({
|
|
|
3029
2945
|
/>
|
|
3030
2946
|
</CapColumn>
|
|
3031
2947
|
</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>
|
|
3050
2948
|
</CapSpin>
|
|
3051
2949
|
);
|
|
3052
2950
|
};
|
|
@@ -91,10 +91,6 @@ 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
|
-
},
|
|
98
94
|
actionDescription: {
|
|
99
95
|
id: `${scope}.actionDescription`,
|
|
100
96
|
defaultMessage: 'Define where the users will redirect when they click on the body of the push notification',
|
|
@@ -256,10 +252,6 @@ export default defineMessages({
|
|
|
256
252
|
id: `${scope}.contentValidationError`,
|
|
257
253
|
defaultMessage: '{platform} content must have title and message',
|
|
258
254
|
},
|
|
259
|
-
singlePlatformContentMissing: {
|
|
260
|
-
id: `${scope}.singlePlatformContentMissing`,
|
|
261
|
-
defaultMessage: 'At least one platform must have title and message',
|
|
262
|
-
},
|
|
263
255
|
// File validation error messages for useUpload.js
|
|
264
256
|
fileSizeError: {
|
|
265
257
|
id: `${scope}.fileSizeError`,
|
|
@@ -277,17 +269,4 @@ export default defineMessages({
|
|
|
277
269
|
id: `${scope}.gifFileTypeError`,
|
|
278
270
|
defaultMessage: 'Only GIF files are allowed',
|
|
279
271
|
},
|
|
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
|
-
},
|
|
293
272
|
});
|
|
@@ -24,11 +24,7 @@ export function* createTemplate({template, callback}) {
|
|
|
24
24
|
errorMsg,
|
|
25
25
|
});
|
|
26
26
|
} catch (error) {
|
|
27
|
-
// Always dispatch failure action first, then call callback if provided
|
|
28
27
|
yield put({ type: types.CREATE_TEMPLATE_FAILURE, error, errorMsg });
|
|
29
|
-
if (callback) {
|
|
30
|
-
yield call(callback, new Error(errorMsg || error.message || error.toString()));
|
|
31
|
-
}
|
|
32
28
|
}
|
|
33
29
|
}
|
|
34
30
|
export function* uploadAsset(action) {
|
|
@@ -95,11 +91,7 @@ export function* editTemplate({ template, callback }) {
|
|
|
95
91
|
yield call(callback, editResponseData);
|
|
96
92
|
}
|
|
97
93
|
} catch (error) {
|
|
98
|
-
// Always dispatch failure action first, then call callback if provided
|
|
99
94
|
yield put({ type: types.EDIT_TEMPLATE_FAILURE, error, errorMsg });
|
|
100
|
-
if (callback) {
|
|
101
|
-
yield call(callback, new Error(errorMsg || error.message || error.toString()));
|
|
102
|
-
}
|
|
103
95
|
}
|
|
104
96
|
}
|
|
105
97
|
|
|
@@ -87,7 +87,11 @@ describe('MobilePushNew Sagas', () => {
|
|
|
87
87
|
[matchers.call.fn(Api.createMobilePushTemplateV2), mockResponse],
|
|
88
88
|
])
|
|
89
89
|
.call(Api.createMobilePushTemplateV2, template)
|
|
90
|
-
.
|
|
90
|
+
.put({
|
|
91
|
+
type: types.CREATE_TEMPLATE_FAILURE,
|
|
92
|
+
error: 'Bad Request',
|
|
93
|
+
errorMsg: 'Bad Request',
|
|
94
|
+
})
|
|
91
95
|
.run();
|
|
92
96
|
});
|
|
93
97
|
|
|
@@ -121,8 +125,11 @@ describe('MobilePushNew Sagas', () => {
|
|
|
121
125
|
[matchers.call.fn(Api.createMobilePushTemplateV2), throwError(error)],
|
|
122
126
|
])
|
|
123
127
|
.call(Api.createMobilePushTemplateV2, template)
|
|
124
|
-
.put({
|
|
125
|
-
|
|
128
|
+
.put({
|
|
129
|
+
type: types.CREATE_TEMPLATE_FAILURE,
|
|
130
|
+
error,
|
|
131
|
+
errorMsg: undefined,
|
|
132
|
+
})
|
|
126
133
|
.run();
|
|
127
134
|
});
|
|
128
135
|
|
|
@@ -365,7 +372,11 @@ describe('MobilePushNew Sagas', () => {
|
|
|
365
372
|
[matchers.call.fn(Api.createMobilePushTemplateV2), mockResponse],
|
|
366
373
|
])
|
|
367
374
|
.call(Api.createMobilePushTemplateV2, template)
|
|
368
|
-
.
|
|
375
|
+
.put({
|
|
376
|
+
type: types.EDIT_TEMPLATE_FAILURE,
|
|
377
|
+
error: 'Bad Request',
|
|
378
|
+
errorMsg: 'Bad Request',
|
|
379
|
+
})
|
|
369
380
|
.run();
|
|
370
381
|
});
|
|
371
382
|
|
|
@@ -381,7 +392,11 @@ describe('MobilePushNew Sagas', () => {
|
|
|
381
392
|
[matchers.call.fn(Api.createMobilePushTemplateV2), mockResponse],
|
|
382
393
|
])
|
|
383
394
|
.call(Api.createMobilePushTemplateV2, template)
|
|
384
|
-
.
|
|
395
|
+
.put({
|
|
396
|
+
type: types.EDIT_TEMPLATE_FAILURE,
|
|
397
|
+
error: 'Internal Server Error',
|
|
398
|
+
errorMsg: 'Internal Server Error',
|
|
399
|
+
})
|
|
385
400
|
.run();
|
|
386
401
|
});
|
|
387
402
|
|
|
@@ -393,8 +408,11 @@ describe('MobilePushNew Sagas', () => {
|
|
|
393
408
|
[matchers.call.fn(Api.createMobilePushTemplateV2), throwError(error)],
|
|
394
409
|
])
|
|
395
410
|
.call(Api.createMobilePushTemplateV2, template)
|
|
396
|
-
.put({
|
|
397
|
-
|
|
411
|
+
.put({
|
|
412
|
+
type: types.EDIT_TEMPLATE_FAILURE,
|
|
413
|
+
error,
|
|
414
|
+
errorMsg: undefined,
|
|
415
|
+
})
|
|
398
416
|
.run();
|
|
399
417
|
});
|
|
400
418
|
|
|
@@ -441,7 +459,11 @@ describe('MobilePushNew Sagas', () => {
|
|
|
441
459
|
[matchers.call.fn(Api.createMobilePushTemplateV2), mockResponse],
|
|
442
460
|
])
|
|
443
461
|
.call(Api.createMobilePushTemplateV2, template)
|
|
444
|
-
.
|
|
462
|
+
.put({
|
|
463
|
+
type: types.EDIT_TEMPLATE_FAILURE,
|
|
464
|
+
error: 'HTTP Error 400',
|
|
465
|
+
errorMsg: 'HTTP Error 400',
|
|
466
|
+
})
|
|
445
467
|
.run();
|
|
446
468
|
});
|
|
447
469
|
|
|
@@ -457,7 +479,11 @@ describe('MobilePushNew Sagas', () => {
|
|
|
457
479
|
[matchers.call.fn(Api.createMobilePushTemplateV2), mockResponse],
|
|
458
480
|
])
|
|
459
481
|
.call(Api.createMobilePushTemplateV2, template)
|
|
460
|
-
.
|
|
482
|
+
.put({
|
|
483
|
+
type: types.EDIT_TEMPLATE_FAILURE,
|
|
484
|
+
error: 'HTTP Error 404',
|
|
485
|
+
errorMsg: 'HTTP Error 404',
|
|
486
|
+
})
|
|
461
487
|
.run();
|
|
462
488
|
});
|
|
463
489
|
|
|
@@ -473,7 +499,11 @@ describe('MobilePushNew Sagas', () => {
|
|
|
473
499
|
[matchers.call.fn(Api.createMobilePushTemplateV2), mockResponse],
|
|
474
500
|
])
|
|
475
501
|
.call(Api.createMobilePushTemplateV2, template)
|
|
476
|
-
.
|
|
502
|
+
.put({
|
|
503
|
+
type: types.EDIT_TEMPLATE_FAILURE,
|
|
504
|
+
error: 'HTTP Error 422',
|
|
505
|
+
errorMsg: 'HTTP Error 422',
|
|
506
|
+
})
|
|
477
507
|
.run();
|
|
478
508
|
});
|
|
479
509
|
|
|
@@ -489,7 +519,11 @@ describe('MobilePushNew Sagas', () => {
|
|
|
489
519
|
[matchers.call.fn(Api.createMobilePushTemplateV2), mockResponse],
|
|
490
520
|
])
|
|
491
521
|
.call(Api.createMobilePushTemplateV2, template)
|
|
492
|
-
.
|
|
522
|
+
.put({
|
|
523
|
+
type: types.EDIT_TEMPLATE_FAILURE,
|
|
524
|
+
error: 'HTTP Error 403',
|
|
525
|
+
errorMsg: 'HTTP Error 403',
|
|
526
|
+
})
|
|
493
527
|
.run();
|
|
494
528
|
});
|
|
495
529
|
|
|
@@ -1357,16 +1357,19 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
1357
1357
|
break;
|
|
1358
1358
|
}
|
|
1359
1359
|
case MOBILE_PUSH:
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
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 = (
|
|
1370
1373
|
<div className='mobilepush-container'>
|
|
1371
1374
|
<div className="app-header">
|
|
1372
1375
|
<div className="app-header-left">
|
|
@@ -1438,7 +1441,8 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
1438
1441
|
)}
|
|
1439
1442
|
</div>
|
|
1440
1443
|
);
|
|
1441
|
-
|
|
1444
|
+
templateData.isNewMobilePush = commonUtil.hasNewMobilePushFeatureEnabled();
|
|
1445
|
+
}
|
|
1442
1446
|
break;
|
|
1443
1447
|
case INAPP:
|
|
1444
1448
|
templateData.content = template;
|