cap-creatives-ui 8.0.280 → 8.0.321
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/.github/workflows/pr-title-check.yml +88 -0
- package/app/constants/unified.js +21 -1
- package/app/containers/App/constants.js +0 -1
- package/app/containers/Login/test/index.test.js +123 -0
- package/app/containers/Login/test/selectors.test.js +165 -0
- package/app/initialState.js +0 -2
- package/app/services/api.js +6 -0
- package/app/services/tests/api.test.js +7 -0
- package/app/services/tests/getSchema.test.js +95 -0
- package/app/utils/common.js +23 -9
- package/app/utils/commonUtils.js +64 -93
- package/app/utils/tagValidations.js +83 -219
- package/app/utils/templateVarUtils.js +172 -0
- package/app/utils/tests/common.test.js +265 -323
- package/app/utils/tests/commonUtil.test.js +461 -118
- package/app/utils/tests/commonUtils.test.js +581 -0
- package/app/utils/tests/messageUtils.test.js +95 -0
- package/app/utils/tests/smsCharCount.test.js +304 -0
- package/app/utils/tests/smsCharCountV2.test.js +213 -10
- package/app/utils/tests/tagValidations.test.js +474 -357
- package/app/utils/tests/templateVarUtils.test.js +160 -0
- package/app/v2Components/CapDeviceContent/index.js +10 -7
- package/app/v2Components/CapTagList/index.js +32 -24
- package/app/v2Components/CapTagList/style.scss +48 -0
- package/app/v2Components/CapTagListWithInput/__tests__/CapTagListWithInput.test.js +63 -0
- package/app/v2Components/CapTagListWithInput/index.js +8 -0
- package/app/v2Components/CapWhatsappCTA/index.js +2 -0
- package/app/v2Components/CapWhatsappCarouselButton/index.js +32 -14
- package/app/v2Components/CapWhatsappCarouselButton/tests/index.test.js +120 -2
- package/app/v2Components/CommonTestAndPreview/CustomValuesEditor.js +70 -49
- package/app/v2Components/CommonTestAndPreview/DeliverySettings/DeliverySettings.scss +39 -0
- package/app/v2Components/CommonTestAndPreview/DeliverySettings/ModifyDeliverySettings.js +606 -0
- package/app/v2Components/CommonTestAndPreview/DeliverySettings/ModifyDeliverySettings.scss +36 -0
- package/app/v2Components/CommonTestAndPreview/DeliverySettings/constants.js +79 -0
- package/app/v2Components/CommonTestAndPreview/DeliverySettings/index.js +314 -0
- package/app/v2Components/CommonTestAndPreview/DeliverySettings/messages.js +141 -0
- package/app/v2Components/CommonTestAndPreview/DeliverySettings/utils/parseSenderDetailsResponse.js +156 -0
- package/app/v2Components/CommonTestAndPreview/SendTestMessage.js +57 -1
- package/app/v2Components/CommonTestAndPreview/UnifiedPreview/_unifiedPreview.scss +20 -1
- package/app/v2Components/CommonTestAndPreview/UnifiedPreview/index.js +133 -4
- package/app/v2Components/CommonTestAndPreview/_commonTestAndPreview.scss +210 -4
- package/app/v2Components/CommonTestAndPreview/actions.js +20 -0
- package/app/v2Components/CommonTestAndPreview/constants.js +57 -1
- package/app/v2Components/CommonTestAndPreview/index.js +878 -156
- package/app/v2Components/CommonTestAndPreview/messages.js +41 -3
- package/app/v2Components/CommonTestAndPreview/previewApiUtils.js +59 -0
- package/app/v2Components/CommonTestAndPreview/reducer.js +47 -0
- package/app/v2Components/CommonTestAndPreview/sagas.js +75 -5
- package/app/v2Components/CommonTestAndPreview/selectors.js +51 -0
- package/app/v2Components/CommonTestAndPreview/tests/CustomValuesEditor.test.js +352 -0
- package/app/v2Components/CommonTestAndPreview/tests/DeliverySettings/ModifyDeliverySettings.test.js +1156 -0
- package/app/v2Components/CommonTestAndPreview/tests/DeliverySettings/index.test.js +334 -0
- package/app/v2Components/CommonTestAndPreview/tests/DeliverySettings/utils/parseSenderDetailsResponse.test.js +576 -0
- package/app/v2Components/CommonTestAndPreview/tests/SendTestMessage.test.js +156 -0
- package/app/v2Components/CommonTestAndPreview/tests/UnifiedPreview/index.test.js +199 -1
- package/app/v2Components/CommonTestAndPreview/tests/actions.test.js +50 -0
- package/app/v2Components/CommonTestAndPreview/tests/constants.test.js +18 -7
- package/app/v2Components/CommonTestAndPreview/tests/index.test.js +914 -5
- package/app/v2Components/CommonTestAndPreview/tests/previewApiUtils.test.js +67 -0
- package/app/v2Components/CommonTestAndPreview/tests/reducer.test.js +118 -0
- package/app/v2Components/CommonTestAndPreview/tests/sagas.test.js +146 -378
- package/app/v2Components/CommonTestAndPreview/tests/selectors.test.js +146 -0
- package/app/v2Components/ErrorInfoNote/index.js +24 -26
- package/app/v2Components/FormBuilder/index.js +182 -204
- package/app/v2Components/FormBuilder/messages.js +4 -8
- package/app/v2Components/HtmlEditor/HTMLEditor.js +7 -6
- package/app/v2Components/HtmlEditor/__tests__/HTMLEditor.apiErrors.test.js +1 -1
- package/app/v2Components/HtmlEditor/__tests__/HTMLEditor.test.js +928 -17
- package/app/v2Components/HtmlEditor/components/CodeEditorPane/index.js +4 -2
- package/app/v2Components/HtmlEditor/hooks/__tests__/useValidation.test.js +452 -3
- package/app/v2Components/HtmlEditor/hooks/useValidation.js +12 -9
- package/app/v2Components/HtmlEditor/utils/__tests__/htmlValidator.enhanced.test.js +132 -0
- package/app/v2Components/HtmlEditor/utils/htmlValidator.js +4 -2
- package/app/v2Components/SmsFallback/SmsFallbackLocalSelector.js +87 -0
- package/app/v2Components/SmsFallback/constants.js +73 -0
- package/app/v2Components/SmsFallback/index.js +956 -0
- package/app/v2Components/SmsFallback/index.scss +265 -0
- package/app/v2Components/SmsFallback/messages.js +78 -0
- package/app/v2Components/SmsFallback/smsFallbackUtils.js +107 -0
- package/app/v2Components/SmsFallback/tests/SmsFallbackLocalSelector.test.js +50 -0
- package/app/v2Components/SmsFallback/tests/rcsSmsFallback.acceptance.test.js +147 -0
- package/app/v2Components/SmsFallback/tests/smsFallbackHandlers.test.js +304 -0
- package/app/v2Components/SmsFallback/tests/smsFallbackUi.test.js +197 -0
- package/app/v2Components/SmsFallback/tests/smsFallbackUtils.test.js +261 -0
- package/app/v2Components/SmsFallback/tests/useLocalTemplateList.test.js +422 -0
- package/app/v2Components/SmsFallback/useLocalTemplateList.js +92 -0
- package/app/v2Components/TestAndPreviewSlidebox/index.js +22 -1
- package/app/v2Components/TestAndPreviewSlidebox/sagas.js +11 -4
- package/app/v2Components/TestAndPreviewSlidebox/tests/saga.test.js +3 -1
- package/app/v2Components/VarSegmentMessageEditor/constants.js +2 -0
- package/app/v2Components/VarSegmentMessageEditor/index.js +125 -0
- package/app/v2Components/VarSegmentMessageEditor/index.scss +46 -0
- package/app/v2Containers/BeeEditor/index.js +3 -0
- package/app/v2Containers/BeePopupEditor/index.js +9 -2
- package/app/v2Containers/Cap/mockData.js +0 -14
- package/app/v2Containers/Cap/reducer.js +3 -55
- package/app/v2Containers/Cap/tests/reducer.test.js +0 -102
- package/app/v2Containers/CommunicationFlow/CommunicationFlow.js +291 -0
- package/app/v2Containers/CommunicationFlow/CommunicationFlow.scss +25 -0
- package/app/v2Containers/CommunicationFlow/Tests/CommunicationFlow.test.js +255 -0
- package/app/v2Containers/CommunicationFlow/constants.js +200 -0
- package/app/v2Containers/CommunicationFlow/index.js +102 -0
- package/app/v2Containers/CommunicationFlow/messages.js +346 -0
- package/app/v2Containers/CommunicationFlow/steps/ChannelSelectionStep/ChannelSelectionStep.js +522 -0
- package/app/v2Containers/CommunicationFlow/steps/ChannelSelectionStep/ChannelSelectionStep.scss +170 -0
- package/app/v2Containers/CommunicationFlow/steps/ChannelSelectionStep/Tests/ChannelSelectionStep.test.js +796 -0
- package/app/v2Containers/CommunicationFlow/steps/ChannelSelectionStep/index.js +5 -0
- package/app/v2Containers/CommunicationFlow/steps/CommunicationStrategyStep/CommunicationStrategyStep.js +95 -0
- package/app/v2Containers/CommunicationFlow/steps/CommunicationStrategyStep/Tests/CommunicationStrategyStep.test.js +133 -0
- package/app/v2Containers/CommunicationFlow/steps/CommunicationStrategyStep/index.js +5 -0
- package/app/v2Containers/CommunicationFlow/steps/DeliverySettingsStep/DeliverySettingsSection.js +289 -0
- package/app/v2Containers/CommunicationFlow/steps/DeliverySettingsStep/DeliverySettingsSection.scss +70 -0
- package/app/v2Containers/CommunicationFlow/steps/DeliverySettingsStep/SenderDetails.js +319 -0
- package/app/v2Containers/CommunicationFlow/steps/DeliverySettingsStep/SenderDetails.scss +69 -0
- package/app/v2Containers/CommunicationFlow/steps/DeliverySettingsStep/Tests/DeliverySettingsSection.test.js +616 -0
- package/app/v2Containers/CommunicationFlow/steps/DeliverySettingsStep/Tests/SenderDetails.test.js +577 -0
- package/app/v2Containers/CommunicationFlow/steps/DeliverySettingsStep/Tests/deliverySettingsConfig.test.js +1111 -0
- package/app/v2Containers/CommunicationFlow/steps/DeliverySettingsStep/deliverySettingsConfig.js +696 -0
- package/app/v2Containers/CommunicationFlow/steps/DeliverySettingsStep/index.js +7 -0
- package/app/v2Containers/CommunicationFlow/steps/DynamicControlsStep/DynamicControlsStep.js +102 -0
- package/app/v2Containers/CommunicationFlow/steps/DynamicControlsStep/DynamicControlsStep.scss +36 -0
- package/app/v2Containers/CommunicationFlow/steps/DynamicControlsStep/Tests/DynamicControlsStep.test.js +91 -0
- package/app/v2Containers/CommunicationFlow/steps/DynamicControlsStep/index.js +5 -0
- package/app/v2Containers/CommunicationFlow/steps/MessageTypeStep/MessageTypeStep.js +86 -0
- package/app/v2Containers/CommunicationFlow/steps/MessageTypeStep/Tests/MessageTypeStep.test.js +100 -0
- package/app/v2Containers/CommunicationFlow/steps/MessageTypeStep/index.js +5 -0
- package/app/v2Containers/CommunicationFlow/utils/getEnabledSteps.js +30 -0
- package/app/v2Containers/CreativesContainer/CreativesSlideBoxWrapper.js +43 -0
- package/app/v2Containers/CreativesContainer/SlideBoxContent.js +127 -11
- package/app/v2Containers/CreativesContainer/SlideBoxFooter.js +62 -9
- package/app/v2Containers/CreativesContainer/SlideBoxHeader.js +29 -4
- package/app/v2Containers/CreativesContainer/constants.js +24 -0
- package/app/v2Containers/CreativesContainer/embeddedSlideboxUtils.js +67 -0
- package/app/v2Containers/CreativesContainer/index.js +346 -71
- package/app/v2Containers/CreativesContainer/index.scss +51 -1
- package/app/v2Containers/CreativesContainer/messages.js +12 -0
- package/app/v2Containers/CreativesContainer/tests/SlideBoxContent.localTemplates.test.js +90 -0
- package/app/v2Containers/CreativesContainer/tests/SlideBoxContent.test.js +69 -1
- package/app/v2Containers/CreativesContainer/tests/SlideBoxFooter.test.js +443 -0
- package/app/v2Containers/CreativesContainer/tests/SlideBoxHeader.test.js +110 -0
- package/app/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxContent.test.js.snap +147 -4
- package/app/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxHeader.test.js.snap +363 -0
- package/app/v2Containers/CreativesContainer/tests/__snapshots__/index.test.js.snap +57 -10
- package/app/v2Containers/CreativesContainer/tests/embeddedSlideboxUtils.test.js +258 -0
- package/app/v2Containers/CreativesContainer/tests/index.test.js +71 -9
- package/app/v2Containers/CreativesContainer/tests/useLocalTemplatesProp.test.js +125 -0
- package/app/v2Containers/Email/index.js +2 -5
- package/app/v2Containers/EmailWrapper/components/EmailHTMLEditor.js +58 -77
- package/app/v2Containers/EmailWrapper/components/EmailWrapperView.js +3 -0
- package/app/v2Containers/EmailWrapper/components/__tests__/EmailHTMLEditor.test.js +158 -89
- package/app/v2Containers/EmailWrapper/components/__tests__/EmailWrapperView.test.js +16 -1
- package/app/v2Containers/EmailWrapper/hooks/useEmailWrapper.js +17 -12
- package/app/v2Containers/EmailWrapper/index.js +4 -0
- package/app/v2Containers/EmailWrapper/tests/useEmailWrapper.edgeCases.test.js +1 -0
- package/app/v2Containers/EmailWrapper/tests/useEmailWrapper.test.js +133 -0
- package/app/v2Containers/FTP/index.js +2 -51
- package/app/v2Containers/FTP/messages.js +0 -4
- package/app/v2Containers/InApp/__tests__/InAppHTMLEditor.test.js +110 -155
- package/app/v2Containers/InApp/index.js +297 -118
- package/app/v2Containers/InApp/tests/index.test.js +17 -6
- package/app/v2Containers/InApp/tests/mockData.js +1 -1
- package/app/v2Containers/InAppWrapper/hooks/__tests__/useInAppWrapper.test.js +19 -0
- package/app/v2Containers/InAppWrapper/hooks/useInAppWrapper.js +3 -0
- package/app/v2Containers/InAppWrapper/index.js +3 -0
- package/app/v2Containers/InappAdvance/index.js +5 -104
- package/app/v2Containers/InappAdvance/tests/index.test.js +2 -0
- package/app/v2Containers/Line/Container/ImageCarousel/tests/__snapshots__/content.test.js.snap +24 -3
- package/app/v2Containers/Line/Container/Text/index.js +0 -1
- package/app/v2Containers/MobilePush/Create/index.js +105 -28
- package/app/v2Containers/MobilePush/Create/messages.js +4 -0
- package/app/v2Containers/MobilePush/Edit/index.js +250 -68
- package/app/v2Containers/MobilePush/Edit/messages.js +4 -0
- package/app/v2Containers/MobilePushNew/components/PlatformContentFields.js +36 -12
- package/app/v2Containers/MobilePushNew/components/tests/PlatformContentFields.test.js +68 -27
- package/app/v2Containers/MobilePushNew/index.js +78 -35
- package/app/v2Containers/MobilePushNew/messages.js +8 -0
- package/app/v2Containers/MobilepushWrapper/index.js +11 -1
- package/app/v2Containers/Rcs/constants.js +32 -1
- package/app/v2Containers/Rcs/index.js +963 -916
- package/app/v2Containers/Rcs/index.scss +85 -6
- package/app/v2Containers/Rcs/messages.js +10 -1
- package/app/v2Containers/Rcs/rcsLibraryHydrationUtils.js +205 -0
- package/app/v2Containers/Rcs/tests/__snapshots__/index.test.js.snap +41136 -1566
- package/app/v2Containers/Rcs/tests/__snapshots__/utils.test.js.snap +0 -5
- package/app/v2Containers/Rcs/tests/index.test.js +41 -38
- package/app/v2Containers/Rcs/tests/mockData.js +38 -0
- package/app/v2Containers/Rcs/tests/rcsLibraryHydrationUtils.test.js +251 -0
- package/app/v2Containers/Rcs/tests/utils.test.js +379 -1
- package/app/v2Containers/Rcs/utils.js +358 -10
- package/app/v2Containers/Sms/Create/index.js +122 -39
- package/app/v2Containers/Sms/Create/messages.js +4 -0
- package/app/v2Containers/Sms/Edit/index.js +37 -3
- package/app/v2Containers/Sms/commonMethods.js +3 -6
- package/app/v2Containers/Sms/smsFormDataHelpers.js +67 -0
- package/app/v2Containers/Sms/tests/commonMethods.test.js +122 -0
- package/app/v2Containers/Sms/tests/smsFormDataHelpers.test.js +253 -0
- package/app/v2Containers/SmsTrai/Create/index.js +9 -4
- package/app/v2Containers/SmsTrai/Create/index.scss +1 -1
- package/app/v2Containers/SmsTrai/Edit/constants.js +2 -0
- package/app/v2Containers/SmsTrai/Edit/index.js +667 -160
- package/app/v2Containers/SmsTrai/Edit/index.scss +121 -0
- package/app/v2Containers/SmsTrai/Edit/messages.js +9 -4
- package/app/v2Containers/SmsTrai/Edit/tests/__snapshots__/index.test.js.snap +4590 -2436
- package/app/v2Containers/SmsWrapper/index.js +41 -8
- package/app/v2Containers/TagList/index.js +63 -2
- package/app/v2Containers/TagList/messages.js +8 -0
- package/app/v2Containers/TagList/tests/TagList.test.js +122 -20
- package/app/v2Containers/TagList/tests/mockdata.js +17 -0
- package/app/v2Containers/Templates/TemplatesActionBar.js +101 -0
- package/app/v2Containers/Templates/_templates.scss +61 -2
- package/app/v2Containers/Templates/actions.js +11 -0
- package/app/v2Containers/Templates/constants.js +2 -0
- package/app/v2Containers/Templates/index.js +90 -40
- package/app/v2Containers/Templates/reducer.js +3 -1
- package/app/v2Containers/Templates/sagas.js +57 -12
- package/app/v2Containers/Templates/tests/TemplatesActionBar.test.js +120 -0
- package/app/v2Containers/Templates/tests/__snapshots__/index.test.js.snap +1043 -1079
- package/app/v2Containers/Templates/tests/reducer.test.js +12 -0
- package/app/v2Containers/Templates/tests/sagas.test.js +193 -12
- package/app/v2Containers/Templates/tests/smsTemplatesListApi.test.js +180 -0
- package/app/v2Containers/Templates/utils/smsTemplatesListApi.js +79 -0
- package/app/v2Containers/TemplatesV2/TemplatesV2.style.js +72 -1
- package/app/v2Containers/TemplatesV2/index.js +147 -49
- package/app/v2Containers/TemplatesV2/tests/TemplatesV2.localTemplates.test.js +131 -0
- package/app/v2Containers/Viber/index.js +9 -10
- package/app/v2Containers/Viber/index.scss +1 -1
- package/app/v2Containers/WebPush/Create/components/BrandIconSection.test.js +264 -0
- package/app/v2Containers/WebPush/Create/components/MessageSection.js +78 -19
- package/app/v2Containers/WebPush/Create/components/MessageSection.test.js +82 -0
- package/app/v2Containers/WebPush/Create/components/__snapshots__/BrandIconSection.test.js.snap +187 -0
- package/app/v2Containers/WebPush/Create/components/__snapshots__/MessageSection.test.js.snap +25 -17
- package/app/v2Containers/WebPush/Create/hooks/useAiraTriggerPosition.js +80 -0
- package/app/v2Containers/WebPush/Create/hooks/useAiraTriggerPosition.test.js +210 -0
- package/app/v2Containers/WebPush/Create/hooks/useTagManagement.js +1 -5
- package/app/v2Containers/WebPush/Create/hooks/useTagManagement.test.js +0 -7
- package/app/v2Containers/WebPush/Create/index.js +36 -6
- package/app/v2Containers/WebPush/Create/index.scss +5 -0
- package/app/v2Containers/WebPush/Create/messages.js +8 -1
- package/app/v2Containers/WebPush/Create/preview/tests/NotificationContainer.test.js +269 -0
- package/app/v2Containers/WebPush/Create/utils/validation.js +31 -15
- package/app/v2Containers/WebPush/Create/utils/validation.test.js +72 -24
- package/app/v2Containers/Whatsapp/index.js +28 -53
- package/app/v2Containers/Whatsapp/tests/__snapshots__/index.test.js.snap +26939 -3982
- package/app/v2Containers/Whatsapp/tests/index.test.js +172 -0
- package/app/v2Containers/Zalo/index.js +5 -11
- package/package.json +2 -2
- package/version +9 -0
|
@@ -14,6 +14,8 @@ import CapRow from "@capillarytech/cap-ui-library/CapRow";
|
|
|
14
14
|
import CapColumn from "@capillarytech/cap-ui-library/CapColumn";
|
|
15
15
|
import CapButton from "@capillarytech/cap-ui-library/CapButton";
|
|
16
16
|
import CapNotification from "@capillarytech/cap-ui-library/CapNotification";
|
|
17
|
+
import CapTab from "@capillarytech/cap-ui-library/CapTab";
|
|
18
|
+
import CapInput from "@capillarytech/cap-ui-library/CapInput";
|
|
17
19
|
import { makeSelectInApp, makeSelectAccount, makeSelectGetTemplateDetailsInProgress } from "./selectors";
|
|
18
20
|
import * as globalActions from '../Cap/actions';
|
|
19
21
|
import {
|
|
@@ -31,7 +33,6 @@ import creativesMessages from '../CreativesContainer/messages';
|
|
|
31
33
|
import withCreatives from "../../hoc/withCreatives";
|
|
32
34
|
import UnifiedPreview from "../../v2Components/CommonTestAndPreview/UnifiedPreview";
|
|
33
35
|
import TestAndPreviewSlidebox from '../../v2Components/TestAndPreviewSlidebox';
|
|
34
|
-
import { validateTags } from "../../utils/tagValidations";
|
|
35
36
|
import injectReducer from '../../utils/injectReducer';
|
|
36
37
|
import v2InAppReducer from './reducer';
|
|
37
38
|
import { v2InAppSagas } from './sagas';
|
|
@@ -51,19 +52,22 @@ import {
|
|
|
51
52
|
LAYOUT_RADIO_OPTIONS,
|
|
52
53
|
IOS_CAPITAL,
|
|
53
54
|
} from "./constants";
|
|
54
|
-
import { INAPP, SMS } from "../CreativesContainer/constants";
|
|
55
|
+
import { GENERIC, INAPP, SMS } from "../CreativesContainer/constants";
|
|
55
56
|
import {
|
|
56
57
|
ALL, TAG, EMBEDDED, DEFAULT, FULL, LIBRARY,
|
|
57
58
|
} from "../Whatsapp/constants";
|
|
58
59
|
import { getCdnUrl } from "../../utils/cdnTransformation";
|
|
59
60
|
import { getCtaObject, hasAnyErrors, getSingleTab } from "./utils";
|
|
60
61
|
import { validateInAppContent } from "../../utils/commonUtils";
|
|
61
|
-
import {
|
|
62
|
+
import { validateTags } from "../../utils/tagValidations";
|
|
63
|
+
import { hasNewEditorFlowInAppEnabled, isAiContentBotDisabled } from "../../utils/common";
|
|
62
64
|
import formBuilderMessages from "../../v2Components/FormBuilder/messages";
|
|
63
65
|
import HTMLEditor from "../../v2Components/HtmlEditor";
|
|
64
66
|
import { HTML_EDITOR_VARIANTS } from "../../v2Components/HtmlEditor/constants";
|
|
65
67
|
import { INAPP_EDITOR_TYPES } from "../InAppWrapper/constants";
|
|
66
68
|
import InappAdvanced from "../InappAdvance/index";
|
|
69
|
+
import CapDeviceContent from "../../v2Components/CapDeviceContent";
|
|
70
|
+
import capDeviceContentMessages from "../../v2Components/CapDeviceContent/messages";
|
|
67
71
|
import { ErrorInfoNote } from "../../v2Components/ErrorInfoNote";
|
|
68
72
|
|
|
69
73
|
let editContent = {};
|
|
@@ -74,6 +78,7 @@ export const InApp = (props) => {
|
|
|
74
78
|
actions,
|
|
75
79
|
globalActions,
|
|
76
80
|
isFullMode,
|
|
81
|
+
isLoyaltyModule,
|
|
77
82
|
onCreateComplete,
|
|
78
83
|
params,
|
|
79
84
|
templateData = {},
|
|
@@ -878,7 +883,7 @@ export const InApp = (props) => {
|
|
|
878
883
|
// Use 'html editor template' as title for HTML editor to differentiate from BEE editor
|
|
879
884
|
title: isHTMLTemplate ? 'html editor template' : titleAndroid,
|
|
880
885
|
message: androidMessage,
|
|
881
|
-
bodyType:
|
|
886
|
+
bodyType: bodyTypeForBackend,
|
|
882
887
|
expandableDetails: {
|
|
883
888
|
style: androidExpandableStyle,
|
|
884
889
|
message: androidMessage,
|
|
@@ -1079,39 +1084,55 @@ export const InApp = (props) => {
|
|
|
1079
1084
|
};
|
|
1080
1085
|
|
|
1081
1086
|
// Validation middleware for tag validation (both liquid and non-liquid flow)
|
|
1087
|
+
// Liquid validation (extractTags) runs only in library mode
|
|
1082
1088
|
const validationMiddleWare = async () => {
|
|
1083
|
-
//
|
|
1089
|
+
// Normalize validator bucket keys to component state keys (ANDROID, IOS_CAPITAL, GENERIC)
|
|
1090
|
+
// so we don't merge e.g. 'android'/'ios'/'generic' with ANDROID/IOS/GENERIC and get duplicate/stale keys
|
|
1091
|
+
const normalizeErrorBuckets = (errors) => {
|
|
1092
|
+
const normalized = {
|
|
1093
|
+
[ANDROID]: [],
|
|
1094
|
+
[IOS_CAPITAL]: [],
|
|
1095
|
+
[GENERIC]: [],
|
|
1096
|
+
};
|
|
1097
|
+
if (!errors || typeof errors !== 'object') return normalized;
|
|
1098
|
+
const keyMap = {
|
|
1099
|
+
ANDROID,
|
|
1100
|
+
android: ANDROID,
|
|
1101
|
+
[IOS_CAPITAL]: IOS_CAPITAL,
|
|
1102
|
+
[IOS]: IOS_CAPITAL,
|
|
1103
|
+
ios: IOS_CAPITAL,
|
|
1104
|
+
GENERIC,
|
|
1105
|
+
generic: GENERIC,
|
|
1106
|
+
};
|
|
1107
|
+
for (const [key, value] of Object.entries(errors)) {
|
|
1108
|
+
const targetKey = keyMap[key];
|
|
1109
|
+
if (targetKey != null && Array.isArray(value)) {
|
|
1110
|
+
normalized[targetKey] = value;
|
|
1111
|
+
}
|
|
1112
|
+
}
|
|
1113
|
+
return normalized;
|
|
1114
|
+
};
|
|
1084
1115
|
const onError = ({ standardErrors, liquidErrors }) => {
|
|
1085
1116
|
setErrorMessage((prev) => ({
|
|
1086
|
-
STANDARD_ERROR_MSG: { ...prev.STANDARD_ERROR_MSG, ...standardErrors },
|
|
1087
|
-
LIQUID_ERROR_MSG: { ...prev.LIQUID_ERROR_MSG, ...liquidErrors },
|
|
1117
|
+
STANDARD_ERROR_MSG: { ...prev.STANDARD_ERROR_MSG, ...normalizeErrorBuckets(standardErrors) },
|
|
1118
|
+
LIQUID_ERROR_MSG: { ...prev.LIQUID_ERROR_MSG, ...normalizeErrorBuckets(liquidErrors) },
|
|
1088
1119
|
}));
|
|
1089
1120
|
};
|
|
1090
1121
|
const onSuccess = () => {
|
|
1091
|
-
// Proceed with submission when validation is successful
|
|
1092
1122
|
onDoneCallback();
|
|
1093
1123
|
};
|
|
1094
1124
|
|
|
1095
|
-
//
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
// For liquid flow, use validateInAppContent
|
|
1099
|
-
if (isLiquidFlow && hasTags) {
|
|
1100
|
-
// Validate the INAPP content
|
|
1125
|
+
// Library mode: run extractTags validation (always, so we catch liquid errors even when tags not loaded)
|
|
1126
|
+
if (!isFullMode) {
|
|
1101
1127
|
const payload = createPayload();
|
|
1102
1128
|
validateInAppContent(payload, {
|
|
1103
|
-
currentTab: panes === ANDROID ? 1 : 2,
|
|
1129
|
+
currentTab: panes === ANDROID ? 1 : 2,
|
|
1104
1130
|
onError,
|
|
1105
1131
|
onSuccess,
|
|
1106
1132
|
getLiquidTags: (content, callback) => globalActions.getLiquidTags(content, callback),
|
|
1107
1133
|
formatMessage,
|
|
1108
1134
|
messages: formBuilderMessages,
|
|
1109
|
-
tagLookupMap: metaEntities?.tagLookupMap || {},
|
|
1110
|
-
eventContextTags: metaEntities?.eventContextTags || [],
|
|
1111
|
-
isLiquidFlow,
|
|
1112
|
-
forwardedTags: {},
|
|
1113
1135
|
skipTags: (tag) => {
|
|
1114
|
-
// Skip certain tags if needed
|
|
1115
1136
|
const skipRegexes = [
|
|
1116
1137
|
/dynamic_expiry_date_after_\d+_days\.FORMAT_\d/,
|
|
1117
1138
|
/unsubscribe\(#[a-zA-Z\d]{6}\)/,
|
|
@@ -1119,101 +1140,15 @@ export const InApp = (props) => {
|
|
|
1119
1140
|
/SURVEY.*\.TOKEN/,
|
|
1120
1141
|
/^[A-Za-z].*\([a-zA-Z\d]*\)/,
|
|
1121
1142
|
];
|
|
1122
|
-
|
|
1123
1143
|
return skipRegexes.some((regex) => regex.test(tag));
|
|
1124
1144
|
},
|
|
1125
1145
|
singleTab: getSingleTab(accountData),
|
|
1126
1146
|
});
|
|
1127
|
-
} else if (hasTags) {
|
|
1128
|
-
// For non-liquid flow, validate tags using validateTags (only if tags are available)
|
|
1129
|
-
const androidContent = htmlContentAndroid || '';
|
|
1130
|
-
const iosContent = htmlContentIos || '';
|
|
1131
|
-
|
|
1132
|
-
const androidSupported = get(accountData, 'selectedWeChatAccount.configs.android') === DEVICE_SUPPORTED || get(editContent, 'ANDROID.deviceType') === ANDROID;
|
|
1133
|
-
const iosSupported = get(accountData, 'selectedWeChatAccount.configs.ios') === DEVICE_SUPPORTED || get(editContent, 'IOS.deviceType') === IOS_CAPITAL;
|
|
1134
|
-
|
|
1135
|
-
let hasErrors = false;
|
|
1136
|
-
const newErrors = {
|
|
1137
|
-
STANDARD_ERROR_MSG: {
|
|
1138
|
-
ANDROID: [],
|
|
1139
|
-
IOS: [],
|
|
1140
|
-
GENERIC: [],
|
|
1141
|
-
},
|
|
1142
|
-
LIQUID_ERROR_MSG: {
|
|
1143
|
-
ANDROID: [],
|
|
1144
|
-
IOS: [],
|
|
1145
|
-
GENERIC: [],
|
|
1146
|
-
},
|
|
1147
|
-
};
|
|
1148
|
-
|
|
1149
|
-
// Validate Android content
|
|
1150
|
-
if (androidSupported && androidContent && androidContent?.trim() !== '') {
|
|
1151
|
-
const validationResponse = validateTags({
|
|
1152
|
-
content: androidContent,
|
|
1153
|
-
tagsParam: tags,
|
|
1154
|
-
injectedTagsParams: injectedTags || {},
|
|
1155
|
-
location,
|
|
1156
|
-
tagModule: getDefaultTags,
|
|
1157
|
-
eventContextTags: metaEntities?.eventContextTags || [],
|
|
1158
|
-
}) || {};
|
|
1159
|
-
|
|
1160
|
-
if (validationResponse?.unsupportedTags?.length > 0) {
|
|
1161
|
-
hasErrors = true;
|
|
1162
|
-
newErrors.LIQUID_ERROR_MSG.ANDROID.push(
|
|
1163
|
-
formatMessage(globalMessages.unsupportedTagsValidationError, {
|
|
1164
|
-
unsupportedTags: validationResponse.unsupportedTags.join(", "),
|
|
1165
|
-
})
|
|
1166
|
-
);
|
|
1167
|
-
}
|
|
1168
|
-
if (validationResponse?.isBraceError) {
|
|
1169
|
-
hasErrors = true;
|
|
1170
|
-
newErrors.LIQUID_ERROR_MSG.ANDROID.push(
|
|
1171
|
-
formatMessage(globalMessages.unbalanacedCurlyBraces)
|
|
1172
|
-
);
|
|
1173
|
-
}
|
|
1174
|
-
}
|
|
1175
|
-
|
|
1176
|
-
// Validate iOS content
|
|
1177
|
-
if (iosSupported && iosContent && iosContent?.trim() !== '') {
|
|
1178
|
-
const validationResponse = validateTags({
|
|
1179
|
-
content: iosContent,
|
|
1180
|
-
tagsParam: tags,
|
|
1181
|
-
injectedTagsParams: injectedTags || {},
|
|
1182
|
-
location,
|
|
1183
|
-
tagModule: getDefaultTags,
|
|
1184
|
-
eventContextTags: metaEntities?.eventContextTags || [],
|
|
1185
|
-
}) || {};
|
|
1186
|
-
|
|
1187
|
-
if (validationResponse?.unsupportedTags?.length > 0) {
|
|
1188
|
-
hasErrors = true;
|
|
1189
|
-
newErrors.LIQUID_ERROR_MSG.IOS.push(
|
|
1190
|
-
formatMessage(globalMessages.unsupportedTagsValidationError, {
|
|
1191
|
-
unsupportedTags: validationResponse.unsupportedTags.join(", "),
|
|
1192
|
-
})
|
|
1193
|
-
);
|
|
1194
|
-
}
|
|
1195
|
-
if (validationResponse?.isBraceError) {
|
|
1196
|
-
hasErrors = true;
|
|
1197
|
-
newErrors.LIQUID_ERROR_MSG.IOS.push(
|
|
1198
|
-
formatMessage(globalMessages.unbalanacedCurlyBraces)
|
|
1199
|
-
);
|
|
1200
|
-
}
|
|
1201
|
-
}
|
|
1202
|
-
|
|
1203
|
-
if (hasErrors) {
|
|
1204
|
-
setErrorMessage(newErrors);
|
|
1205
|
-
} else {
|
|
1206
|
-
// No errors, proceed with submission
|
|
1207
|
-
onSuccess();
|
|
1208
|
-
}
|
|
1209
1147
|
} else {
|
|
1210
|
-
// No tags available, skip validation and proceed directly
|
|
1211
1148
|
onSuccess();
|
|
1212
1149
|
}
|
|
1213
1150
|
};
|
|
1214
1151
|
|
|
1215
|
-
const isLiquidFlow = hasLiquidSupportFeature();
|
|
1216
|
-
|
|
1217
1152
|
// Check template data to determine editor type (for render decision)
|
|
1218
1153
|
const templateDetails = isFullMode ? editData?.templateDetails : templateData;
|
|
1219
1154
|
const versions = templateDetails?.versions || {};
|
|
@@ -1238,11 +1173,13 @@ export const InApp = (props) => {
|
|
|
1238
1173
|
&& !isBEEeditor
|
|
1239
1174
|
&& !isBeeFreeTemplate;
|
|
1240
1175
|
|
|
1176
|
+
const isNewEditorFlowEnabled = !isLoyaltyModule && hasNewEditorFlowInAppEnabled();
|
|
1177
|
+
|
|
1241
1178
|
// Use state if available, otherwise fall back to direct data check
|
|
1242
|
-
const shouldUseHTMLEditor = isHTMLTemplate || isHTMLTemplateFromData;
|
|
1179
|
+
const shouldUseHTMLEditor = isNewEditorFlowEnabled && (isHTMLTemplate || isHTMLTemplateFromData);
|
|
1243
1180
|
|
|
1244
1181
|
// Only route to Bee editor if it's explicitly a Bee editor AND not an HTML template
|
|
1245
|
-
const shouldUseBeeEditor = (isBEEeditor || isBeeFreeTemplate) && !shouldUseHTMLEditor;
|
|
1182
|
+
const shouldUseBeeEditor = isNewEditorFlowEnabled && (isBEEeditor || isBeeFreeTemplate) && !shouldUseHTMLEditor;
|
|
1246
1183
|
|
|
1247
1184
|
// Early returns to avoid nested ternary
|
|
1248
1185
|
if (isEditInApp && getTemplateDetailsInProgress) {
|
|
@@ -1278,10 +1215,222 @@ export const InApp = (props) => {
|
|
|
1278
1215
|
);
|
|
1279
1216
|
}
|
|
1280
1217
|
|
|
1218
|
+
// ── Old-flow helpers (used by CapDeviceContent when flag is disabled) ──────
|
|
1219
|
+
const aiContentBotDisabled = isAiContentBotDisabled();
|
|
1220
|
+
|
|
1221
|
+
/**
|
|
1222
|
+
* Clears stored API/liquid errors for a specific device (and GENERIC) so
|
|
1223
|
+
* hasAnyErrors() goes false and Done can be re-clicked after editing.
|
|
1224
|
+
* Does NOT clear errors that belong only to the *other* device.
|
|
1225
|
+
*/
|
|
1226
|
+
const clearDeviceErrors = useCallback((platform) => {
|
|
1227
|
+
const key = platform === IOS ? IOS_CAPITAL : ANDROID;
|
|
1228
|
+
setErrorMessage((prev) => ({
|
|
1229
|
+
STANDARD_ERROR_MSG: {
|
|
1230
|
+
...prev.STANDARD_ERROR_MSG,
|
|
1231
|
+
[key]: [],
|
|
1232
|
+
GENERIC: [],
|
|
1233
|
+
},
|
|
1234
|
+
LIQUID_ERROR_MSG: {
|
|
1235
|
+
...prev.LIQUID_ERROR_MSG,
|
|
1236
|
+
[key]: [],
|
|
1237
|
+
GENERIC: [],
|
|
1238
|
+
},
|
|
1239
|
+
}));
|
|
1240
|
+
}, [IOS_CAPITAL, ANDROID]);
|
|
1241
|
+
|
|
1242
|
+
const setTitleAndroidWithClear = useCallback((value) => {
|
|
1243
|
+
clearDeviceErrors(ANDROID);
|
|
1244
|
+
setTitleAndroid(value);
|
|
1245
|
+
}, [clearDeviceErrors]);
|
|
1246
|
+
|
|
1247
|
+
const setTitleIosWithClear = useCallback((value) => {
|
|
1248
|
+
clearDeviceErrors(IOS);
|
|
1249
|
+
setTitleIos(value);
|
|
1250
|
+
}, [clearDeviceErrors]);
|
|
1251
|
+
|
|
1252
|
+
const setTemplateMessageAndroidWithClear = useCallback((value) => {
|
|
1253
|
+
clearDeviceErrors(ANDROID);
|
|
1254
|
+
setTemplateMessageAndroid(value);
|
|
1255
|
+
}, [clearDeviceErrors]);
|
|
1256
|
+
|
|
1257
|
+
const setTemplateMessageIosWithClear = useCallback((value) => {
|
|
1258
|
+
clearDeviceErrors(IOS);
|
|
1259
|
+
setTemplateMessageIos(value);
|
|
1260
|
+
}, [clearDeviceErrors]);
|
|
1261
|
+
|
|
1262
|
+
const templateDescErrorHandler = (value) => {
|
|
1263
|
+
const { unsupportedTags, isBraceError } = validateTags({
|
|
1264
|
+
content: value,
|
|
1265
|
+
tagsParam: tags,
|
|
1266
|
+
injectedTagsParams: injectedTags,
|
|
1267
|
+
location,
|
|
1268
|
+
tagModule: getDefaultTags,
|
|
1269
|
+
isFullMode,
|
|
1270
|
+
}) || {};
|
|
1271
|
+
if (unsupportedTags?.length > 0) {
|
|
1272
|
+
return formatMessage(globalMessages.unsupportedTagsValidationError, { unsupportedTags });
|
|
1273
|
+
}
|
|
1274
|
+
if (isBraceError) {
|
|
1275
|
+
return formatMessage(globalMessages.unbalanacedCurlyBraces);
|
|
1276
|
+
}
|
|
1277
|
+
return '';
|
|
1278
|
+
};
|
|
1279
|
+
|
|
1280
|
+
/** Same rules as CapDeviceContent onTitleChange / onTemplateMessageChange */
|
|
1281
|
+
const computeInAppTemplateFieldError = (value) => {
|
|
1282
|
+
let error = templateDescErrorHandler(value);
|
|
1283
|
+
if (value === '') {
|
|
1284
|
+
error = formatMessage(capDeviceContentMessages.emptyTemplateMessageErrorMessage);
|
|
1285
|
+
}
|
|
1286
|
+
return error;
|
|
1287
|
+
};
|
|
1288
|
+
|
|
1289
|
+
const onCopyTitleAndContent = () => {
|
|
1290
|
+
if (panes === ANDROID) {
|
|
1291
|
+
clearDeviceErrors(ANDROID);
|
|
1292
|
+
setTitleAndroid(titleIos);
|
|
1293
|
+
setTemplateMessageAndroid(templateMessageIos);
|
|
1294
|
+
setTemplateTitleErrorAndroid(computeInAppTemplateFieldError(titleIos));
|
|
1295
|
+
setTemplateMessageErrorAndroid(computeInAppTemplateFieldError(templateMessageIos));
|
|
1296
|
+
setInAppImageSrcAndroid(inAppImageSrcIos);
|
|
1297
|
+
} else {
|
|
1298
|
+
clearDeviceErrors(IOS);
|
|
1299
|
+
setTitleIos(titleAndroid);
|
|
1300
|
+
setTemplateMessageIos(templateMessageAndroid);
|
|
1301
|
+
setTemplateTitleErrorIos(computeInAppTemplateFieldError(titleAndroid));
|
|
1302
|
+
setTemplateMessageErrorIos(computeInAppTemplateFieldError(templateMessageAndroid));
|
|
1303
|
+
setInAppImageSrcIos(inAppImageSrcAndroid);
|
|
1304
|
+
}
|
|
1305
|
+
};
|
|
1306
|
+
|
|
1307
|
+
const onTagSelect = (value, index) => {
|
|
1308
|
+
const tag = `{{${value}}}`;
|
|
1309
|
+
if (panes === ANDROID) {
|
|
1310
|
+
clearDeviceErrors(ANDROID);
|
|
1311
|
+
const nextTitle = index === 0 ? titleAndroid + tag : titleAndroid;
|
|
1312
|
+
const nextMessage = index === 0 ? templateMessageAndroid : templateMessageAndroid + tag;
|
|
1313
|
+
if (index === 0) setTitleAndroid(nextTitle);
|
|
1314
|
+
else setTemplateMessageAndroid(nextMessage);
|
|
1315
|
+
setTemplateTitleErrorAndroid(computeInAppTemplateFieldError(nextTitle));
|
|
1316
|
+
setTemplateMessageErrorAndroid(computeInAppTemplateFieldError(nextMessage));
|
|
1317
|
+
} else {
|
|
1318
|
+
clearDeviceErrors(IOS);
|
|
1319
|
+
const nextTitle = index === 0 ? titleIos + tag : titleIos;
|
|
1320
|
+
const nextMessage = index === 0 ? templateMessageIos : templateMessageIos + tag;
|
|
1321
|
+
if (index === 0) setTitleIos(nextTitle);
|
|
1322
|
+
else setTemplateMessageIos(nextMessage);
|
|
1323
|
+
setTemplateTitleErrorIos(computeInAppTemplateFieldError(nextTitle));
|
|
1324
|
+
setTemplateMessageErrorIos(computeInAppTemplateFieldError(nextMessage));
|
|
1325
|
+
}
|
|
1326
|
+
};
|
|
1327
|
+
|
|
1328
|
+
// Device support flags (same derivation as InappAdvance)
|
|
1329
|
+
const isAndroidSupported = get(accountData, 'selectedWeChatAccount.configs.android') === DEVICE_SUPPORTED || get(editContent, 'ANDROID.deviceType') === ANDROID;
|
|
1330
|
+
const isIosSupported = get(accountData, 'selectedWeChatAccount.configs.ios') === DEVICE_SUPPORTED || get(editContent, 'IOS.deviceType') === IOS_CAPITAL;
|
|
1331
|
+
|
|
1332
|
+
// CapDeviceContent tab panes (old flow)
|
|
1333
|
+
const DEVICE_PANES = [
|
|
1334
|
+
{
|
|
1335
|
+
content: (
|
|
1336
|
+
<CapDeviceContent
|
|
1337
|
+
panes={ANDROID}
|
|
1338
|
+
actions={actions}
|
|
1339
|
+
editData={editData}
|
|
1340
|
+
isFullMode={isFullMode}
|
|
1341
|
+
inAppImageSrc={inAppImageSrcAndroid}
|
|
1342
|
+
setInAppImageSrc={setInAppImageSrcAndroid}
|
|
1343
|
+
isEditFlow={isEditFlow}
|
|
1344
|
+
ctaData={ctaDataAndroid}
|
|
1345
|
+
setCtaData={setCtaDataAndroid}
|
|
1346
|
+
buttonType={buttonTypeAndroid}
|
|
1347
|
+
setButtonType={setButtonTypeAndroid}
|
|
1348
|
+
templateMediaType={templateMediaType}
|
|
1349
|
+
setTemplateMediaType={setTemplateMediaType}
|
|
1350
|
+
title={titleAndroid}
|
|
1351
|
+
setTitle={setTitleAndroidWithClear}
|
|
1352
|
+
templateMessageError={templateMessageErrorAndroid}
|
|
1353
|
+
templateMessage={templateMessageAndroid}
|
|
1354
|
+
setTemplateMessage={setTemplateMessageAndroidWithClear}
|
|
1355
|
+
setTemplateMessageError={setTemplateMessageErrorAndroid}
|
|
1356
|
+
addActionLink={addActionLinkAndroid}
|
|
1357
|
+
setAddActionLink={setAddActionLinkAndroid}
|
|
1358
|
+
deepLink={deepLink}
|
|
1359
|
+
deepLinkValue={deepLinkValueAndroid}
|
|
1360
|
+
setDeepLinkValue={setDeepLinkValueAndroid}
|
|
1361
|
+
onCopyTitleAndContent={onCopyTitleAndContent}
|
|
1362
|
+
isOtherDeviceSupported={isIosSupported}
|
|
1363
|
+
tags={tags}
|
|
1364
|
+
onTagSelect={onTagSelect}
|
|
1365
|
+
handleOnTagsContextChange={handleOnTagsContextChange}
|
|
1366
|
+
templateDescErrorHandler={templateDescErrorHandler}
|
|
1367
|
+
templateTitleError={templateTitleErrorAndroid}
|
|
1368
|
+
setTemplateTitleError={setTemplateTitleErrorAndroid}
|
|
1369
|
+
isAiContentBotDisabled={aiContentBotDisabled}
|
|
1370
|
+
injectedTags={injectedTags}
|
|
1371
|
+
selectedOfferDetails={selectedOfferDetails}
|
|
1372
|
+
location={location}
|
|
1373
|
+
/>
|
|
1374
|
+
),
|
|
1375
|
+
tab: <FormattedMessage {...messages.Android} />,
|
|
1376
|
+
key: ANDROID,
|
|
1377
|
+
isSupported: isAndroidSupported,
|
|
1378
|
+
},
|
|
1379
|
+
{
|
|
1380
|
+
content: (
|
|
1381
|
+
<CapDeviceContent
|
|
1382
|
+
panes={IOS}
|
|
1383
|
+
actions={actions}
|
|
1384
|
+
editData={editData}
|
|
1385
|
+
isFullMode={isFullMode}
|
|
1386
|
+
inAppImageSrc={inAppImageSrcIos}
|
|
1387
|
+
setInAppImageSrc={setInAppImageSrcIos}
|
|
1388
|
+
isEditFlow={isEditFlow}
|
|
1389
|
+
ctaData={ctaDataIos}
|
|
1390
|
+
setCtaData={setCtaDataIos}
|
|
1391
|
+
buttonType={buttonTypeIos}
|
|
1392
|
+
setButtonType={setButtonTypeIos}
|
|
1393
|
+
templateMediaType={templateMediaType}
|
|
1394
|
+
setTemplateMediaType={setTemplateMediaType}
|
|
1395
|
+
title={titleIos}
|
|
1396
|
+
setTitle={setTitleIosWithClear}
|
|
1397
|
+
templateMessageError={templateMessageErrorIos}
|
|
1398
|
+
templateMessage={templateMessageIos}
|
|
1399
|
+
setTemplateMessage={setTemplateMessageIosWithClear}
|
|
1400
|
+
setTemplateMessageError={setTemplateMessageErrorIos}
|
|
1401
|
+
addActionLink={addActionLinkIos}
|
|
1402
|
+
setAddActionLink={setAddActionLinkIos}
|
|
1403
|
+
deepLink={deepLink}
|
|
1404
|
+
deepLinkValue={deepLinkValueIos}
|
|
1405
|
+
setDeepLinkValue={setDeepLinkValueIos}
|
|
1406
|
+
onCopyTitleAndContent={onCopyTitleAndContent}
|
|
1407
|
+
isOtherDeviceSupported={isAndroidSupported}
|
|
1408
|
+
tags={tags}
|
|
1409
|
+
onTagSelect={onTagSelect}
|
|
1410
|
+
handleOnTagsContextChange={handleOnTagsContextChange}
|
|
1411
|
+
templateDescErrorHandler={templateDescErrorHandler}
|
|
1412
|
+
templateTitleError={templateTitleErrorIos}
|
|
1413
|
+
setTemplateTitleError={setTemplateTitleErrorIos}
|
|
1414
|
+
isAiContentBotDisabled={aiContentBotDisabled}
|
|
1415
|
+
injectedTags={injectedTags}
|
|
1416
|
+
selectedOfferDetails={selectedOfferDetails}
|
|
1417
|
+
location={location}
|
|
1418
|
+
/>
|
|
1419
|
+
),
|
|
1420
|
+
tab: <FormattedMessage {...messages.Ios} />,
|
|
1421
|
+
key: IOS,
|
|
1422
|
+
isSupported: isIosSupported,
|
|
1423
|
+
},
|
|
1424
|
+
];
|
|
1425
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
1426
|
+
|
|
1427
|
+
// Calculate column span: HTML editor = 18, everything else = 24
|
|
1428
|
+
const editorColumnSpan = shouldUseHTMLEditor ? 18 : 24;
|
|
1429
|
+
|
|
1281
1430
|
return (
|
|
1282
1431
|
<CapSpin spinning={spin || fetchingLiquidValidation} tip={fetchingLiquidValidation ? <FormattedMessage {...formBuilderMessages.liquidSpinText} /> : ""}>
|
|
1283
1432
|
<CapRow className="cap-inapp-creatives">
|
|
1284
|
-
<CapColumn span={
|
|
1433
|
+
<CapColumn span={editorColumnSpan}>
|
|
1285
1434
|
{/* Creative layout type */}
|
|
1286
1435
|
{shouldUseHTMLEditor && (
|
|
1287
1436
|
<>
|
|
@@ -1302,7 +1451,7 @@ export const InApp = (props) => {
|
|
|
1302
1451
|
/>
|
|
1303
1452
|
</>
|
|
1304
1453
|
)}
|
|
1305
|
-
{shouldUseHTMLEditor
|
|
1454
|
+
{shouldUseHTMLEditor && (
|
|
1306
1455
|
<HTMLEditor
|
|
1307
1456
|
key={`inapp-html-editor-v${htmlEditorContentVersion}`}
|
|
1308
1457
|
variant={HTML_EDITOR_VARIANTS.INAPP}
|
|
@@ -1318,19 +1467,16 @@ export const InApp = (props) => {
|
|
|
1318
1467
|
location={location}
|
|
1319
1468
|
selectedOfferDetails={selectedOfferDetails}
|
|
1320
1469
|
onTagSelect={() => {
|
|
1321
|
-
// Tag insertion
|
|
1322
|
-
// Content updates will be propagated via onContentChange callback
|
|
1470
|
+
// Tag insertion handled by HTMLEditor's CodeEditorPane at cursor position
|
|
1323
1471
|
}}
|
|
1324
|
-
// Don't pass globalActions to prevent duplicate API calls
|
|
1325
|
-
// HTMLEditor will use onContextChange instead
|
|
1326
1472
|
onContextChange={handleOnTagsContextChange}
|
|
1327
|
-
// Pass validation errors to HTMLEditor for display
|
|
1328
1473
|
errors={errorMessage}
|
|
1329
1474
|
isFullMode={isFullMode}
|
|
1330
1475
|
data-test="inapp-html-editor"
|
|
1331
1476
|
style={{ width: '138%' }}
|
|
1332
1477
|
/>
|
|
1333
|
-
)
|
|
1478
|
+
)}
|
|
1479
|
+
{!shouldUseHTMLEditor && isNewEditorFlowEnabled && (
|
|
1334
1480
|
<InappAdvanced
|
|
1335
1481
|
getFormData={getFormData}
|
|
1336
1482
|
setIsLoadingContent={setIsLoadingContent}
|
|
@@ -1355,11 +1501,44 @@ export const InApp = (props) => {
|
|
|
1355
1501
|
onCreateComplete={onCreateComplete}
|
|
1356
1502
|
/>
|
|
1357
1503
|
)}
|
|
1504
|
+
{!shouldUseHTMLEditor && !isNewEditorFlowEnabled && (
|
|
1505
|
+
<>
|
|
1506
|
+
<CapInput
|
|
1507
|
+
label={<FormattedMessage {...messages.creativeName} />}
|
|
1508
|
+
onChange={({ target: { value } }) => setTempName(value)}
|
|
1509
|
+
value={tempName}
|
|
1510
|
+
labelPosition="top"
|
|
1511
|
+
size="default"
|
|
1512
|
+
/>
|
|
1513
|
+
<CapRow>
|
|
1514
|
+
<CapHeading type="h4">
|
|
1515
|
+
<FormattedMessage {...messages.creativeLayout} />
|
|
1516
|
+
</CapHeading>
|
|
1517
|
+
<CapHeading type="h6" className="inapp-creative-layout-desc">
|
|
1518
|
+
<FormattedMessage {...messages.creativeLayoutDesc} />
|
|
1519
|
+
</CapHeading>
|
|
1520
|
+
</CapRow>
|
|
1521
|
+
<CapRadioGroup
|
|
1522
|
+
id="inapp-layout-radio"
|
|
1523
|
+
options={LAYOUT_RADIO_OPTIONS}
|
|
1524
|
+
value={templateLayoutType}
|
|
1525
|
+
onChange={onTemplateLayoutTypeChange}
|
|
1526
|
+
className="inapp-layout-radio"
|
|
1527
|
+
/>
|
|
1528
|
+
<CapTab
|
|
1529
|
+
panes={DEVICE_PANES.filter((devicePane) => devicePane?.isSupported === true)}
|
|
1530
|
+
onChange={(value) => setPanes(value)}
|
|
1531
|
+
activeKey={panes}
|
|
1532
|
+
defaultActiveKey={panes}
|
|
1533
|
+
className="inapp-template-device-tab"
|
|
1534
|
+
/>
|
|
1535
|
+
</>
|
|
1536
|
+
)}
|
|
1358
1537
|
</CapColumn>
|
|
1359
1538
|
</CapRow>
|
|
1360
|
-
{/* Footer with Done/Update button -
|
|
1539
|
+
{/* Footer with Done/Update button - show for HTML editor and old CapDeviceContent flow */}
|
|
1361
1540
|
{
|
|
1362
|
-
shouldUseHTMLEditor && (
|
|
1541
|
+
(shouldUseHTMLEditor || !isNewEditorFlowEnabled) && (
|
|
1363
1542
|
<>
|
|
1364
1543
|
{hasAnyErrors(errorMessage) && (
|
|
1365
1544
|
<ErrorInfoNote
|
|
@@ -21,18 +21,16 @@ import { getCtaObject } from '../utils';
|
|
|
21
21
|
jest.mock('redux-auth-wrapper/history4/redirect', () => ({
|
|
22
22
|
connectedRouterRedirect: jest.fn((config) => (Component) => Component),
|
|
23
23
|
}));
|
|
24
|
+
import * as commonUtils from '../../../utils/commonUtils';
|
|
24
25
|
|
|
25
26
|
const mockActions = {
|
|
26
27
|
getTemplateInfoById: jest.fn(),
|
|
27
28
|
resetEditTemplate: jest.fn(),
|
|
28
|
-
getTemplateDetails: jest.fn((id,
|
|
29
|
+
getTemplateDetails: jest.fn((id, setSpin) => {
|
|
29
30
|
// Simulate successful template details fetch to prevent loading state
|
|
30
31
|
// The callback is setSpin function, call it with false to stop spinner
|
|
31
|
-
if (
|
|
32
|
-
|
|
33
|
-
setTimeout(() => {
|
|
34
|
-
callback(false);
|
|
35
|
-
}, 0);
|
|
32
|
+
if (setSpin && typeof setSpin === 'function') {
|
|
33
|
+
setTimeout(() => setSpin(false), 0);
|
|
36
34
|
}
|
|
37
35
|
}),
|
|
38
36
|
editTemplate: jest.fn(),
|
|
@@ -41,6 +39,9 @@ const mockActions = {
|
|
|
41
39
|
};
|
|
42
40
|
const mockGlobalActions = {
|
|
43
41
|
fetchSchemaForEntity: jest.fn(),
|
|
42
|
+
getLiquidTags: jest.fn((content, callback) =>
|
|
43
|
+
callback({ askAiraResponse: { data: [], errors: [] }, isError: false }),
|
|
44
|
+
),
|
|
44
45
|
};
|
|
45
46
|
|
|
46
47
|
jest.mock('../../../v2Containers/TagList/index.js', () => ({
|
|
@@ -66,7 +67,17 @@ const renderComponent = (props) =>
|
|
|
66
67
|
);
|
|
67
68
|
|
|
68
69
|
describe('Test activity inApp container', () => {
|
|
70
|
+
afterEach(() => {
|
|
71
|
+
jest.restoreAllMocks();
|
|
72
|
+
});
|
|
73
|
+
|
|
69
74
|
it('test case for inApp template update flow', async () => {
|
|
75
|
+
jest
|
|
76
|
+
.spyOn(commonUtils, 'validateInAppContent')
|
|
77
|
+
.mockImplementation((payload, options) => {
|
|
78
|
+
options.onSuccess();
|
|
79
|
+
return Promise.resolve(true);
|
|
80
|
+
});
|
|
70
81
|
renderComponent({
|
|
71
82
|
actions: mockActions,
|
|
72
83
|
globalActions: mockGlobalActions,
|
|
@@ -78,6 +78,7 @@ describe('useInAppWrapper', () => {
|
|
|
78
78
|
onPreviewContentClicked: jest.fn(),
|
|
79
79
|
onTestContentClicked: jest.fn(),
|
|
80
80
|
eventContextTags: {},
|
|
81
|
+
waitEventContextTags: {},
|
|
81
82
|
onCreateComplete: jest.fn(),
|
|
82
83
|
handleClose: jest.fn(),
|
|
83
84
|
templateData: null,
|
|
@@ -424,6 +425,24 @@ describe('useInAppWrapper', () => {
|
|
|
424
425
|
|
|
425
426
|
expect(capturedState.inAppProps.getDefaultTags).toBe('defaultTags');
|
|
426
427
|
});
|
|
428
|
+
|
|
429
|
+
it('passes waitEventContextTags through to inAppProps', () => {
|
|
430
|
+
const waitMap = { block1: { eventName: 'E', blockName: 'B', tags: [] } };
|
|
431
|
+
let capturedState = null;
|
|
432
|
+
render(
|
|
433
|
+
<TestComponent
|
|
434
|
+
hookProps={{
|
|
435
|
+
...defaultHookProps,
|
|
436
|
+
waitEventContextTags: waitMap,
|
|
437
|
+
}}
|
|
438
|
+
onStateChange={(state) => {
|
|
439
|
+
capturedState = state;
|
|
440
|
+
}}
|
|
441
|
+
/>
|
|
442
|
+
);
|
|
443
|
+
|
|
444
|
+
expect(capturedState.inAppProps.waitEventContextTags).toEqual(waitMap);
|
|
445
|
+
});
|
|
427
446
|
});
|
|
428
447
|
|
|
429
448
|
describe('isShowInAppCreate', () => {
|
|
@@ -33,6 +33,7 @@ const useInAppWrapper = ({
|
|
|
33
33
|
onPreviewContentClicked,
|
|
34
34
|
onTestContentClicked,
|
|
35
35
|
eventContextTags,
|
|
36
|
+
waitEventContextTags,
|
|
36
37
|
onCreateComplete,
|
|
37
38
|
handleClose,
|
|
38
39
|
templateData,
|
|
@@ -149,6 +150,7 @@ const useInAppWrapper = ({
|
|
|
149
150
|
onPreviewContentClicked,
|
|
150
151
|
onTestContentClicked,
|
|
151
152
|
eventContextTags,
|
|
153
|
+
waitEventContextTags,
|
|
152
154
|
onCreateComplete,
|
|
153
155
|
handleClose,
|
|
154
156
|
};
|
|
@@ -173,6 +175,7 @@ const useInAppWrapper = ({
|
|
|
173
175
|
onPreviewContentClicked,
|
|
174
176
|
onTestContentClicked,
|
|
175
177
|
eventContextTags,
|
|
178
|
+
waitEventContextTags,
|
|
176
179
|
onCreateComplete,
|
|
177
180
|
handleClose,
|
|
178
181
|
]);
|
|
@@ -36,6 +36,7 @@ const InAppWrapper = (props) => {
|
|
|
36
36
|
onPreviewContentClicked,
|
|
37
37
|
onTestContentClicked,
|
|
38
38
|
eventContextTags,
|
|
39
|
+
waitEventContextTags,
|
|
39
40
|
onCreateComplete,
|
|
40
41
|
handleClose,
|
|
41
42
|
templateData,
|
|
@@ -78,6 +79,7 @@ const InAppWrapper = (props) => {
|
|
|
78
79
|
onPreviewContentClicked,
|
|
79
80
|
onTestContentClicked,
|
|
80
81
|
eventContextTags,
|
|
82
|
+
waitEventContextTags,
|
|
81
83
|
onCreateComplete,
|
|
82
84
|
handleClose,
|
|
83
85
|
templateData,
|
|
@@ -124,6 +126,7 @@ InAppWrapper.propTypes = {
|
|
|
124
126
|
onPreviewContentClicked: PropTypes.func,
|
|
125
127
|
onTestContentClicked: PropTypes.func,
|
|
126
128
|
eventContextTags: PropTypes.array,
|
|
129
|
+
waitEventContextTags: PropTypes.object,
|
|
127
130
|
onCreateComplete: PropTypes.func,
|
|
128
131
|
handleClose: PropTypes.func,
|
|
129
132
|
templateData: PropTypes.object,
|