@capillarytech/creatives-library 8.0.263 → 8.0.265
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/assets/Android.png +0 -0
- package/assets/iOS.png +0 -0
- package/constants/unified.js +1 -3
- package/initialReducer.js +0 -2
- package/package.json +1 -1
- package/services/api.js +0 -15
- package/services/tests/api.test.js +0 -34
- package/tests/integration/TemplateCreation/TemplateCreation.integration.test.js +35 -17
- package/tests/integration/TemplateCreation/api-response.js +1 -31
- package/tests/integration/TemplateCreation/msw-handler.js +0 -2
- package/utils/common.js +0 -11
- package/utils/commonUtils.js +5 -28
- package/utils/tests/commonUtil.test.js +0 -224
- package/utils/tests/transformerUtils.test.js +0 -297
- package/utils/transformTemplateConfig.js +10 -0
- package/utils/transformerUtils.js +0 -40
- package/v2Components/CapDeviceContent/index.js +56 -61
- package/v2Components/CapImageUpload/constants.js +0 -2
- package/v2Components/CapImageUpload/index.js +16 -65
- package/v2Components/CapImageUpload/index.scss +1 -4
- package/v2Components/CapImageUpload/messages.js +1 -5
- package/v2Components/CapTagList/index.js +1 -6
- package/v2Components/CapTagListWithInput/index.js +1 -5
- package/v2Components/CapTagListWithInput/messages.js +1 -1
- package/v2Components/CapWhatsappCTA/tests/index.test.js +0 -5
- package/v2Components/ErrorInfoNote/index.js +72 -402
- package/v2Components/ErrorInfoNote/messages.js +6 -32
- package/v2Components/ErrorInfoNote/style.scss +6 -278
- package/v2Components/FormBuilder/tests/index.test.js +4 -13
- package/v2Components/HtmlEditor/HTMLEditor.js +99 -418
- package/v2Components/HtmlEditor/__tests__/HTMLEditor.test.js +133 -1882
- package/v2Components/HtmlEditor/__tests__/index.lazy.test.js +16 -27
- package/v2Components/HtmlEditor/_htmlEditor.scss +45 -108
- package/v2Components/HtmlEditor/_index.lazy.scss +1 -0
- package/v2Components/HtmlEditor/components/CodeEditorPane/_codeEditorPane.scss +102 -23
- package/v2Components/HtmlEditor/components/CodeEditorPane/index.js +140 -148
- package/v2Components/HtmlEditor/components/DeviceToggle/_deviceToggle.scss +1 -2
- package/v2Components/HtmlEditor/components/DeviceToggle/index.js +3 -3
- package/v2Components/HtmlEditor/components/EditorToolbar/_editorToolbar.scss +1 -9
- package/v2Components/HtmlEditor/components/EditorToolbar/index.js +6 -31
- package/v2Components/HtmlEditor/components/FullscreenModal/_fullscreenModal.scss +0 -22
- package/v2Components/HtmlEditor/components/InAppPreviewPane/DeviceFrame.js +7 -4
- package/v2Components/HtmlEditor/components/InAppPreviewPane/__tests__/DeviceFrame.test.js +45 -35
- package/v2Components/HtmlEditor/components/InAppPreviewPane/_inAppPreviewPane.scss +3 -1
- package/v2Components/HtmlEditor/components/InAppPreviewPane/constants.js +33 -33
- package/v2Components/HtmlEditor/components/InAppPreviewPane/index.js +6 -7
- package/v2Components/HtmlEditor/components/PreviewPane/_previewPane.scss +10 -7
- package/v2Components/HtmlEditor/components/PreviewPane/index.js +43 -22
- package/v2Components/HtmlEditor/components/SplitContainer/_splitContainer.scss +1 -1
- package/v2Components/HtmlEditor/components/ValidationErrorDisplay/__tests__/index.test.js +152 -0
- package/v2Components/HtmlEditor/components/ValidationErrorDisplay/_validationErrorDisplay.scss +0 -18
- package/v2Components/HtmlEditor/components/ValidationErrorDisplay/index.js +31 -36
- package/v2Components/HtmlEditor/components/ValidationPanel/_validationPanel.scss +34 -46
- package/v2Components/HtmlEditor/components/ValidationPanel/index.js +46 -52
- package/v2Components/HtmlEditor/constants.js +20 -45
- package/v2Components/HtmlEditor/hooks/__tests__/useInAppContent.test.js +16 -373
- package/v2Components/HtmlEditor/hooks/__tests__/useValidation.test.js +16 -351
- package/v2Components/HtmlEditor/hooks/useEditorContent.js +2 -5
- package/v2Components/HtmlEditor/hooks/useInAppContent.js +146 -88
- package/v2Components/HtmlEditor/hooks/useValidation.js +56 -213
- package/v2Components/HtmlEditor/index.js +1 -1
- package/v2Components/HtmlEditor/messages.js +94 -102
- package/v2Components/HtmlEditor/utils/__tests__/htmlValidator.enhanced.test.js +45 -214
- package/v2Components/HtmlEditor/utils/__tests__/validationAdapter.test.js +0 -134
- package/v2Components/HtmlEditor/utils/contentSanitizer.js +41 -40
- package/v2Components/HtmlEditor/utils/htmlValidator.js +72 -71
- package/v2Components/HtmlEditor/utils/liquidTemplateSupport.js +124 -158
- package/v2Components/HtmlEditor/utils/properSyntaxHighlighting.js +25 -23
- package/v2Components/HtmlEditor/utils/validationAdapter.js +41 -66
- package/v2Components/MobilePushPreviewV2/index.js +7 -33
- package/v2Components/TemplatePreview/_templatePreview.scss +24 -55
- package/v2Components/TemplatePreview/index.js +32 -47
- package/v2Components/TemplatePreview/messages.js +0 -4
- package/v2Components/TestAndPreviewSlidebox/_testAndPreviewSlidebox.scss +0 -1
- package/v2Containers/App/constants.js +0 -5
- package/v2Containers/BeeEditor/index.js +90 -172
- package/v2Containers/CreativesContainer/SlideBoxContent.js +53 -184
- package/v2Containers/CreativesContainer/SlideBoxFooter.js +13 -163
- package/v2Containers/CreativesContainer/SlideBoxHeader.js +1 -3
- package/v2Containers/CreativesContainer/constants.js +0 -4
- package/v2Containers/CreativesContainer/index.js +46 -408
- package/v2Containers/CreativesContainer/messages.js +0 -12
- package/v2Containers/CreativesContainer/tests/SlideBoxContent.test.js +0 -210
- package/v2Containers/CreativesContainer/tests/SlideBoxFooter.test.js +2 -11
- package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxContent.test.js.snap +50 -342
- package/v2Containers/CreativesContainer/tests/__snapshots__/index.test.js.snap +0 -103
- package/v2Containers/Email/actions.js +0 -7
- package/v2Containers/Email/constants.js +1 -5
- package/v2Containers/Email/index.js +36 -237
- package/v2Containers/Email/messages.js +0 -32
- package/v2Containers/Email/reducer.js +1 -12
- package/v2Containers/Email/sagas.js +7 -61
- package/v2Containers/Email/tests/__snapshots__/reducer.test.js.snap +0 -2
- package/v2Containers/Email/tests/reducer.test.js +0 -46
- package/v2Containers/Email/tests/sagas.test.js +29 -320
- package/v2Containers/EmailWrapper/components/EmailWrapperView.js +21 -211
- package/v2Containers/EmailWrapper/components/HTMLEditorTesting.js +74 -40
- package/v2Containers/EmailWrapper/components/__tests__/HTMLEditorTesting.test.js +67 -2
- package/v2Containers/EmailWrapper/constants.js +0 -2
- package/v2Containers/EmailWrapper/hooks/useEmailWrapper.js +77 -629
- package/v2Containers/EmailWrapper/index.js +23 -103
- package/v2Containers/EmailWrapper/messages.js +1 -65
- package/v2Containers/EmailWrapper/tests/EmailWrapperView.test.js +214 -0
- package/v2Containers/EmailWrapper/tests/useEmailWrapper.test.js +77 -594
- package/v2Containers/InApp/actions.js +0 -7
- package/v2Containers/InApp/constants.js +4 -20
- package/v2Containers/InApp/index.js +359 -802
- package/v2Containers/InApp/index.scss +3 -4
- package/v2Containers/InApp/messages.js +3 -7
- package/v2Containers/InApp/reducer.js +3 -21
- package/v2Containers/InApp/sagas.js +9 -29
- package/v2Containers/InApp/selectors.js +5 -25
- package/v2Containers/InApp/tests/index.test.js +50 -154
- package/v2Containers/InApp/tests/reducer.test.js +0 -34
- package/v2Containers/InApp/tests/sagas.test.js +9 -61
- package/v2Containers/Line/Container/ImageCarousel/tests/__snapshots__/content.test.js.snap +0 -3
- package/v2Containers/Line/Container/ImageCarousel/tests/__snapshots__/index.test.js.snap +0 -2
- package/v2Containers/Line/Container/Wrapper/tests/__snapshots__/index.test.js.snap +0 -2
- package/v2Containers/Line/Container/tests/__snapshots__/index.test.js.snap +0 -9
- package/v2Containers/Rcs/tests/__snapshots__/index.test.js.snap +0 -12
- package/v2Containers/SmsTrai/Edit/tests/__snapshots__/index.test.js.snap +0 -4
- package/v2Containers/TagList/index.js +19 -62
- package/v2Containers/Templates/ChannelTypeIllustration.js +1 -13
- package/v2Containers/Templates/_templates.scss +1 -265
- package/v2Containers/Templates/actions.js +1 -2
- package/v2Containers/Templates/constants.js +0 -1
- package/v2Containers/Templates/index.js +38 -363
- package/v2Containers/Templates/messages.js +0 -28
- package/v2Containers/Templates/reducer.js +0 -2
- package/v2Containers/Templates/tests/index.test.js +0 -10
- package/v2Containers/TemplatesV2/TemplatesV2.style.js +2 -4
- package/v2Containers/TemplatesV2/index.js +7 -15
- package/v2Containers/TemplatesV2/messages.js +0 -4
- package/v2Containers/Whatsapp/tests/__snapshots__/index.test.js.snap +0 -34
- package/utils/imageUrlUpload.js +0 -141
- package/v2Components/CapImageUrlUpload/constants.js +0 -26
- package/v2Components/CapImageUrlUpload/index.js +0 -365
- package/v2Components/CapImageUrlUpload/index.scss +0 -35
- package/v2Components/CapImageUrlUpload/messages.js +0 -47
- package/v2Components/ErrorInfoNote/constants.js +0 -1
- package/v2Components/HtmlEditor/__tests__/HTMLEditor.apiErrors.test.js +0 -870
- package/v2Components/HtmlEditor/components/ValidationPanel/constants.js +0 -6
- package/v2Components/HtmlEditor/components/ValidationTabs/_validationTabs.scss +0 -281
- package/v2Components/HtmlEditor/components/ValidationTabs/index.js +0 -295
- package/v2Components/HtmlEditor/components/ValidationTabs/messages.js +0 -51
- package/v2Components/HtmlEditor/utils/validationConstants.js +0 -38
- package/v2Components/MobilePushPreviewV2/constants.js +0 -6
- package/v2Containers/BeePopupEditor/_beePopupEditor.scss +0 -14
- package/v2Containers/BeePopupEditor/constants.js +0 -10
- package/v2Containers/BeePopupEditor/index.js +0 -194
- package/v2Containers/BeePopupEditor/tests/index.test.js +0 -627
- package/v2Containers/EmailWrapper/components/EmailHTMLEditor.js +0 -1246
- package/v2Containers/EmailWrapper/components/__tests__/EmailHTMLEditor.test.js +0 -2472
- package/v2Containers/EmailWrapper/components/__tests__/EmailWrapperView.test.js +0 -520
- package/v2Containers/EmailWrapper/tests/useEmailWrapper.edgeCases.test.js +0 -956
- package/v2Containers/InApp/__tests__/InAppHTMLEditor.test.js +0 -376
- package/v2Containers/InApp/__tests__/sagas.test.js +0 -363
- package/v2Containers/InApp/tests/selectors.test.js +0 -612
- package/v2Containers/InAppWrapper/components/InAppWrapperView.js +0 -151
- package/v2Containers/InAppWrapper/components/__tests__/InAppWrapperView.test.js +0 -267
- package/v2Containers/InAppWrapper/components/inAppWrapperView.scss +0 -23
- package/v2Containers/InAppWrapper/constants.js +0 -16
- package/v2Containers/InAppWrapper/hooks/__tests__/useInAppWrapper.test.js +0 -473
- package/v2Containers/InAppWrapper/hooks/useInAppWrapper.js +0 -198
- package/v2Containers/InAppWrapper/index.js +0 -148
- package/v2Containers/InAppWrapper/messages.js +0 -49
- package/v2Containers/InappAdvance/index.js +0 -1099
- package/v2Containers/InappAdvance/index.scss +0 -10
- package/v2Containers/InappAdvance/tests/index.test.js +0 -448
- package/v2Containers/WebPush/Create/components/BrandIconSection.js +0 -108
- package/v2Containers/WebPush/Create/components/ButtonForm.js +0 -172
- package/v2Containers/WebPush/Create/components/ButtonItem.js +0 -101
- package/v2Containers/WebPush/Create/components/ButtonList.js +0 -145
- package/v2Containers/WebPush/Create/components/ButtonsLinksSection.js +0 -164
- package/v2Containers/WebPush/Create/components/ButtonsLinksSection.test.js +0 -463
- package/v2Containers/WebPush/Create/components/FormActions.js +0 -54
- package/v2Containers/WebPush/Create/components/FormActions.test.js +0 -163
- package/v2Containers/WebPush/Create/components/MediaSection.js +0 -142
- package/v2Containers/WebPush/Create/components/MediaSection.test.js +0 -341
- package/v2Containers/WebPush/Create/components/MessageSection.js +0 -103
- package/v2Containers/WebPush/Create/components/MessageSection.test.js +0 -268
- package/v2Containers/WebPush/Create/components/NotificationTitleSection.js +0 -87
- package/v2Containers/WebPush/Create/components/NotificationTitleSection.test.js +0 -210
- package/v2Containers/WebPush/Create/components/TemplateNameSection.js +0 -54
- package/v2Containers/WebPush/Create/components/TemplateNameSection.test.js +0 -143
- package/v2Containers/WebPush/Create/components/__snapshots__/ButtonsLinksSection.test.js.snap +0 -86
- package/v2Containers/WebPush/Create/components/__snapshots__/FormActions.test.js.snap +0 -16
- package/v2Containers/WebPush/Create/components/__snapshots__/MediaSection.test.js.snap +0 -41
- package/v2Containers/WebPush/Create/components/__snapshots__/MessageSection.test.js.snap +0 -54
- package/v2Containers/WebPush/Create/components/__snapshots__/NotificationTitleSection.test.js.snap +0 -37
- package/v2Containers/WebPush/Create/components/__snapshots__/TemplateNameSection.test.js.snap +0 -21
- package/v2Containers/WebPush/Create/components/_buttons.scss +0 -246
- package/v2Containers/WebPush/Create/components/tests/ButtonForm.test.js +0 -554
- package/v2Containers/WebPush/Create/components/tests/ButtonItem.test.js +0 -607
- package/v2Containers/WebPush/Create/components/tests/ButtonList.test.js +0 -633
- package/v2Containers/WebPush/Create/components/tests/__snapshots__/ButtonForm.test.js.snap +0 -666
- package/v2Containers/WebPush/Create/components/tests/__snapshots__/ButtonItem.test.js.snap +0 -74
- package/v2Containers/WebPush/Create/components/tests/__snapshots__/ButtonList.test.js.snap +0 -78
- package/v2Containers/WebPush/Create/hooks/useButtonManagement.js +0 -138
- package/v2Containers/WebPush/Create/hooks/useButtonManagement.test.js +0 -406
- package/v2Containers/WebPush/Create/hooks/useCharacterCount.js +0 -30
- package/v2Containers/WebPush/Create/hooks/useCharacterCount.test.js +0 -151
- package/v2Containers/WebPush/Create/hooks/useImageUpload.js +0 -104
- package/v2Containers/WebPush/Create/hooks/useImageUpload.test.js +0 -538
- package/v2Containers/WebPush/Create/hooks/useTagManagement.js +0 -122
- package/v2Containers/WebPush/Create/hooks/useTagManagement.test.js +0 -633
- package/v2Containers/WebPush/Create/index.js +0 -1148
- package/v2Containers/WebPush/Create/index.scss +0 -134
- package/v2Containers/WebPush/Create/messages.js +0 -211
- package/v2Containers/WebPush/Create/preview/DevicePreviewContent.js +0 -228
- package/v2Containers/WebPush/Create/preview/NotificationContainer.js +0 -294
- package/v2Containers/WebPush/Create/preview/PreviewContent.js +0 -90
- package/v2Containers/WebPush/Create/preview/PreviewControls.js +0 -305
- package/v2Containers/WebPush/Create/preview/PreviewDisclaimer.js +0 -25
- package/v2Containers/WebPush/Create/preview/WebPushPreview.js +0 -155
- package/v2Containers/WebPush/Create/preview/assets/Light.svg +0 -53
- package/v2Containers/WebPush/Create/preview/assets/Top.svg +0 -5
- package/v2Containers/WebPush/Create/preview/assets/android-arrow-down.svg +0 -9
- package/v2Containers/WebPush/Create/preview/assets/android-arrow-up.svg +0 -9
- package/v2Containers/WebPush/Create/preview/assets/chrome-icon.png +0 -0
- package/v2Containers/WebPush/Create/preview/assets/edge-icon.png +0 -0
- package/v2Containers/WebPush/Create/preview/assets/firefox-icon.svg +0 -106
- package/v2Containers/WebPush/Create/preview/assets/iOS.svg +0 -26
- package/v2Containers/WebPush/Create/preview/assets/macos-arrow-down-icon.svg +0 -9
- package/v2Containers/WebPush/Create/preview/assets/macos-triple-dot-icon.svg +0 -9
- package/v2Containers/WebPush/Create/preview/assets/opera-icon.svg +0 -18
- package/v2Containers/WebPush/Create/preview/assets/safari-icon.svg +0 -29
- package/v2Containers/WebPush/Create/preview/assets/windows-close-icon.svg +0 -9
- package/v2Containers/WebPush/Create/preview/assets/windows-triple-dot-icon.svg +0 -9
- package/v2Containers/WebPush/Create/preview/components/AndroidMobileChromeHeader.js +0 -51
- package/v2Containers/WebPush/Create/preview/components/AndroidMobileExpanded.js +0 -145
- package/v2Containers/WebPush/Create/preview/components/IOSHeader.js +0 -45
- package/v2Containers/WebPush/Create/preview/components/NotificationExpandedContent.js +0 -68
- package/v2Containers/WebPush/Create/preview/components/NotificationHeader.js +0 -61
- package/v2Containers/WebPush/Create/preview/components/WindowsChromeExpanded.js +0 -99
- package/v2Containers/WebPush/Create/preview/components/tests/AndroidMobileExpanded.test.js +0 -733
- package/v2Containers/WebPush/Create/preview/components/tests/WindowsChromeExpanded.test.js +0 -571
- package/v2Containers/WebPush/Create/preview/components/tests/__snapshots__/AndroidMobileExpanded.test.js.snap +0 -85
- package/v2Containers/WebPush/Create/preview/components/tests/__snapshots__/WindowsChromeExpanded.test.js.snap +0 -81
- package/v2Containers/WebPush/Create/preview/config/notificationMappings.js +0 -50
- package/v2Containers/WebPush/Create/preview/constants.js +0 -637
- package/v2Containers/WebPush/Create/preview/notification-container.scss +0 -79
- package/v2Containers/WebPush/Create/preview/preview.scss +0 -358
- package/v2Containers/WebPush/Create/preview/styles/_android-mobile-chrome.scss +0 -370
- package/v2Containers/WebPush/Create/preview/styles/_android-mobile-edge.scss +0 -12
- package/v2Containers/WebPush/Create/preview/styles/_android-mobile-firefox.scss +0 -12
- package/v2Containers/WebPush/Create/preview/styles/_android-mobile-opera.scss +0 -12
- package/v2Containers/WebPush/Create/preview/styles/_android-tablet-chrome.scss +0 -47
- package/v2Containers/WebPush/Create/preview/styles/_android-tablet-edge.scss +0 -11
- package/v2Containers/WebPush/Create/preview/styles/_android-tablet-firefox.scss +0 -11
- package/v2Containers/WebPush/Create/preview/styles/_android-tablet-opera.scss +0 -11
- package/v2Containers/WebPush/Create/preview/styles/_base.scss +0 -207
- package/v2Containers/WebPush/Create/preview/styles/_ios.scss +0 -153
- package/v2Containers/WebPush/Create/preview/styles/_ipados.scss +0 -107
- package/v2Containers/WebPush/Create/preview/styles/_macos-chrome.scss +0 -101
- package/v2Containers/WebPush/Create/preview/styles/_windows-chrome.scss +0 -229
- package/v2Containers/WebPush/Create/preview/tests/DevicePreviewContent.test.js +0 -909
- package/v2Containers/WebPush/Create/preview/tests/NotificationContainer.test.js +0 -1081
- package/v2Containers/WebPush/Create/preview/tests/PreviewControls.test.js +0 -723
- package/v2Containers/WebPush/Create/preview/tests/WebPushPreview.test.js +0 -1327
- package/v2Containers/WebPush/Create/preview/tests/__snapshots__/DevicePreviewContent.test.js.snap +0 -131
- package/v2Containers/WebPush/Create/preview/tests/__snapshots__/NotificationContainer.test.js.snap +0 -112
- package/v2Containers/WebPush/Create/preview/tests/__snapshots__/PreviewControls.test.js.snap +0 -144
- package/v2Containers/WebPush/Create/preview/tests/__snapshots__/WebPushPreview.test.js.snap +0 -129
- package/v2Containers/WebPush/Create/utils/payloadBuilder.js +0 -96
- package/v2Containers/WebPush/Create/utils/payloadBuilder.test.js +0 -396
- package/v2Containers/WebPush/Create/utils/previewUtils.js +0 -89
- package/v2Containers/WebPush/Create/utils/urlValidation.js +0 -115
- package/v2Containers/WebPush/Create/utils/urlValidation.test.js +0 -449
- package/v2Containers/WebPush/Create/utils/validation.js +0 -75
- package/v2Containers/WebPush/Create/utils/validation.test.js +0 -283
- package/v2Containers/WebPush/actions.js +0 -60
- package/v2Containers/WebPush/constants.js +0 -132
- package/v2Containers/WebPush/index.js +0 -2
- package/v2Containers/WebPush/reducer.js +0 -104
- package/v2Containers/WebPush/sagas.js +0 -119
- package/v2Containers/WebPush/selectors.js +0 -65
- package/v2Containers/WebPush/tests/reducer.test.js +0 -863
- package/v2Containers/WebPush/tests/sagas.test.js +0 -566
- package/v2Containers/WebPush/tests/selectors.test.js +0 -960
|
@@ -15,13 +15,13 @@
|
|
|
15
15
|
* - Filters dangerous protocols (javascript:, data:, vbscript:)
|
|
16
16
|
* - Variant-aware sanitization (EMAIL vs INAPP with different security levels)
|
|
17
17
|
* - Iframe sandbox uses "allow-scripts" only (no allow-same-origin for security)
|
|
18
|
-
* - Content delivered via
|
|
18
|
+
* - Content delivered via blob URLs to isolate iframe from parent origin
|
|
19
19
|
*
|
|
20
20
|
* Previous Security Issues (FIXED):
|
|
21
21
|
* - Removed insecure manual sanitizeJavaScript function that only escaped </script> tags
|
|
22
22
|
* - Replaced with robust DOMPurify-based sanitization for full XSS protection
|
|
23
23
|
* - Removed "allow-same-origin" from iframe sandbox to prevent same-origin access
|
|
24
|
-
* -
|
|
24
|
+
* - Implemented blob URL delivery to maintain isolation while allowing script execution
|
|
25
25
|
*/
|
|
26
26
|
|
|
27
27
|
import React, { useMemo, useEffect, useRef } from 'react';
|
|
@@ -55,7 +55,7 @@ const PreviewPane = ({
|
|
|
55
55
|
className = '',
|
|
56
56
|
isFullscreenMode = false,
|
|
57
57
|
isModalContext = false,
|
|
58
|
-
layoutType = LAYOUT_TYPES.MODAL
|
|
58
|
+
layoutType = LAYOUT_TYPES.MODAL
|
|
59
59
|
}) => {
|
|
60
60
|
const { content, layout, variant } = useEditorContext();
|
|
61
61
|
|
|
@@ -103,25 +103,36 @@ const PreviewPane = ({
|
|
|
103
103
|
return sanitizationResult.sanitized;
|
|
104
104
|
}, [contentValue, variant]);
|
|
105
105
|
|
|
106
|
-
//
|
|
107
|
-
//
|
|
108
|
-
|
|
109
|
-
const
|
|
110
|
-
|
|
111
|
-
|
|
106
|
+
// Create blob URL for secure iframe content delivery
|
|
107
|
+
// This isolates the iframe content from the parent origin while allowing script execution
|
|
108
|
+
const blobUrlRef = useRef(null);
|
|
109
|
+
const blobUrl = useMemo(() => {
|
|
110
|
+
// Clean up previous blob URL to prevent memory leaks
|
|
111
|
+
if (blobUrlRef.current) {
|
|
112
|
+
URL.revokeObjectURL(blobUrlRef.current);
|
|
113
|
+
blobUrlRef.current = null;
|
|
112
114
|
}
|
|
113
115
|
|
|
114
|
-
//
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
return null;
|
|
116
|
+
// Create new blob URL if we have content
|
|
117
|
+
if (combinedContent) {
|
|
118
|
+
const blob = new Blob([combinedContent], { type: 'text/html' });
|
|
119
|
+
blobUrlRef.current = URL.createObjectURL(blob);
|
|
120
|
+
return blobUrlRef.current;
|
|
120
121
|
}
|
|
121
122
|
|
|
122
|
-
return
|
|
123
|
+
return null;
|
|
123
124
|
}, [combinedContent]);
|
|
124
125
|
|
|
126
|
+
// Cleanup blob URL on unmount
|
|
127
|
+
useEffect(() => {
|
|
128
|
+
return () => {
|
|
129
|
+
if (blobUrlRef.current) {
|
|
130
|
+
URL.revokeObjectURL(blobUrlRef.current);
|
|
131
|
+
blobUrlRef.current = null;
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
}, []);
|
|
135
|
+
|
|
125
136
|
// Generate CSS classes based on view mode
|
|
126
137
|
const getIframeClasses = () => {
|
|
127
138
|
const baseClass = 'preview-pane__iframe';
|
|
@@ -143,15 +154,15 @@ const PreviewPane = ({
|
|
|
143
154
|
// Use layout.mobileWidth or fallback to 375px
|
|
144
155
|
const width = mobileWidth || 375;
|
|
145
156
|
baseStyles.width = `${width}px`;
|
|
157
|
+
baseStyles.height = '100%'; // Fill container height
|
|
146
158
|
}
|
|
147
|
-
|
|
159
|
+
|
|
148
160
|
return baseStyles;
|
|
149
161
|
};
|
|
150
162
|
|
|
151
163
|
const renderDeviceFrame = () => (
|
|
152
164
|
<iframe
|
|
153
|
-
src={
|
|
154
|
-
srcDoc={iframeContent || undefined}
|
|
165
|
+
src={blobUrl || 'about:blank'}
|
|
155
166
|
title={intl.formatMessage(messages.htmlPreview)}
|
|
156
167
|
className={getIframeClasses()}
|
|
157
168
|
style={getPreviewStyles()}
|
|
@@ -162,7 +173,17 @@ const PreviewPane = ({
|
|
|
162
173
|
const renderEmptyState = () => (
|
|
163
174
|
<div className="preview-empty">
|
|
164
175
|
<div className="empty-content">
|
|
165
|
-
<
|
|
176
|
+
<div className="empty-icon">📝</div>
|
|
177
|
+
<p>{intl.formatMessage(messages.startTypingHtml)}</p>
|
|
178
|
+
<p className="preview-mode-info">
|
|
179
|
+
{intl.formatMessage(messages.previewMode)}: {
|
|
180
|
+
viewMode === PREVIEW_MODES.DESKTOP
|
|
181
|
+
? intl.formatMessage(messages.desktop)
|
|
182
|
+
: viewMode === PREVIEW_MODES.MOBILE
|
|
183
|
+
? intl.formatMessage(messages.mobile)
|
|
184
|
+
: intl.formatMessage(messages.mobileDevice)
|
|
185
|
+
}
|
|
186
|
+
</p>
|
|
166
187
|
</div>
|
|
167
188
|
</div>
|
|
168
189
|
);
|
|
@@ -191,7 +212,7 @@ const PreviewPane = ({
|
|
|
191
212
|
</CapRow>
|
|
192
213
|
|
|
193
214
|
<CapRow className="preview-pane__content">
|
|
194
|
-
{
|
|
215
|
+
{blobUrl ? renderDeviceFrame() : renderEmptyState()}
|
|
195
216
|
</CapRow>
|
|
196
217
|
</div>
|
|
197
218
|
);
|
|
@@ -202,7 +223,7 @@ PreviewPane.propTypes = {
|
|
|
202
223
|
className: PropTypes.string,
|
|
203
224
|
isFullscreenMode: PropTypes.bool,
|
|
204
225
|
isModalContext: PropTypes.bool,
|
|
205
|
-
layoutType: PropTypes.oneOf(Object.values(LAYOUT_TYPES))
|
|
226
|
+
layoutType: PropTypes.oneOf(Object.values(LAYOUT_TYPES))
|
|
206
227
|
};
|
|
207
228
|
|
|
208
229
|
export default injectIntl(PreviewPane);
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ValidationErrorDisplay Component Tests
|
|
3
|
+
*
|
|
4
|
+
* Tests for the ValidationErrorDisplay component that integrates with ErrorInfoNote.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import React from 'react';
|
|
8
|
+
import { render, screen } from '@testing-library/react';
|
|
9
|
+
import '@testing-library/jest-dom';
|
|
10
|
+
import ValidationErrorDisplay from '../index';
|
|
11
|
+
|
|
12
|
+
// Mock ErrorInfoNote component
|
|
13
|
+
jest.mock('../../../../ErrorInfoNote', () => {
|
|
14
|
+
return function MockErrorInfoNote({ errorMessages }) {
|
|
15
|
+
const liquidErrors = errorMessages?.LIQUID_ERROR_MSG || [];
|
|
16
|
+
const standardErrors = errorMessages?.STANDARD_ERROR_MSG || [];
|
|
17
|
+
const hasErrors = liquidErrors.length > 0 || standardErrors.length > 0;
|
|
18
|
+
|
|
19
|
+
if (!hasErrors) return null;
|
|
20
|
+
|
|
21
|
+
return (
|
|
22
|
+
<div data-testid="error-info-note">
|
|
23
|
+
{liquidErrors.map((msg, index) => (
|
|
24
|
+
<div key={`liquid-${index}`} data-testid="error-message">
|
|
25
|
+
{msg}
|
|
26
|
+
</div>
|
|
27
|
+
))}
|
|
28
|
+
{standardErrors.map((msg, index) => (
|
|
29
|
+
<div key={`standard-${index}`} data-testid="error-message">
|
|
30
|
+
{msg}
|
|
31
|
+
</div>
|
|
32
|
+
))}
|
|
33
|
+
</div>
|
|
34
|
+
);
|
|
35
|
+
};
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
describe('ValidationErrorDisplay', () => {
|
|
39
|
+
it('renders standard errors when validation has issues', () => {
|
|
40
|
+
const mockValidation = {
|
|
41
|
+
getAllIssues: () => [
|
|
42
|
+
{ message: 'Missing closing tag', severity: 'error', line: 5, column: 10 },
|
|
43
|
+
{ message: 'Invalid attribute', severity: 'error', line: 7 }
|
|
44
|
+
],
|
|
45
|
+
isClean: () => false,
|
|
46
|
+
isValidating: false
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
render(<ValidationErrorDisplay validation={mockValidation} />);
|
|
50
|
+
|
|
51
|
+
expect(screen.getByTestId('error-info-note')).toBeInTheDocument();
|
|
52
|
+
const errorMessages = screen.getAllByTestId('error-message');
|
|
53
|
+
expect(errorMessages).toHaveLength(2);
|
|
54
|
+
expect(errorMessages[0]).toHaveTextContent('Missing closing tag Line 5, Char 10.');
|
|
55
|
+
expect(errorMessages[1]).toHaveTextContent('Invalid attribute Line 7.');
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it('renders liquid errors separately', () => {
|
|
59
|
+
const mockValidation = {
|
|
60
|
+
getAllIssues: () => [
|
|
61
|
+
{ message: 'Invalid liquid syntax', severity: 'error', source: 'liquid-validator', line: 3 },
|
|
62
|
+
{ message: 'HTML error', severity: 'error', source: 'htmlhint', line: 10 }
|
|
63
|
+
],
|
|
64
|
+
isClean: () => false,
|
|
65
|
+
isValidating: false
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
render(<ValidationErrorDisplay validation={mockValidation} />);
|
|
69
|
+
|
|
70
|
+
expect(screen.getByTestId('error-info-note')).toBeInTheDocument();
|
|
71
|
+
const errorMessages = screen.getAllByTestId('error-message');
|
|
72
|
+
expect(errorMessages).toHaveLength(2);
|
|
73
|
+
// First should be liquid error, second should be standard error
|
|
74
|
+
expect(errorMessages[0]).toHaveTextContent('Invalid liquid syntax Line 3.');
|
|
75
|
+
expect(errorMessages[1]).toHaveTextContent('HTML error Line 10.');
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it('does not render when validation has no errors', () => {
|
|
79
|
+
const mockValidation = {
|
|
80
|
+
getAllIssues: () => [],
|
|
81
|
+
isClean: () => true,
|
|
82
|
+
isValidating: false
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
const { container } = render(<ValidationErrorDisplay validation={mockValidation} />);
|
|
86
|
+
|
|
87
|
+
expect(screen.queryByTestId('error-info-note')).not.toBeInTheDocument();
|
|
88
|
+
expect(container.firstChild).toBeNull();
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
it('does not render when validation is null', () => {
|
|
92
|
+
const { container } = render(<ValidationErrorDisplay validation={null} />);
|
|
93
|
+
|
|
94
|
+
expect(screen.queryByTestId('error-info-note')).not.toBeInTheDocument();
|
|
95
|
+
expect(container.firstChild).toBeNull();
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
it('does not render when validation is in progress', () => {
|
|
99
|
+
const mockValidation = {
|
|
100
|
+
getAllIssues: () => [],
|
|
101
|
+
isClean: () => false,
|
|
102
|
+
isValidating: true
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
const { container } = render(<ValidationErrorDisplay validation={mockValidation} />);
|
|
106
|
+
|
|
107
|
+
expect(screen.queryByTestId('error-info-note')).not.toBeInTheDocument();
|
|
108
|
+
expect(container.firstChild).toBeNull();
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
it('applies custom className', () => {
|
|
112
|
+
const mockValidation = {
|
|
113
|
+
getAllIssues: () => [{ message: 'Error', severity: 'error' }],
|
|
114
|
+
isClean: () => false,
|
|
115
|
+
isValidating: false
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
const { container } = render(
|
|
119
|
+
<ValidationErrorDisplay validation={mockValidation} className="custom-class" />
|
|
120
|
+
);
|
|
121
|
+
|
|
122
|
+
const wrapper = container.querySelector('.validation-error-display');
|
|
123
|
+
expect(wrapper).toHaveClass('custom-class');
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
it('handles inapp variant correctly', () => {
|
|
127
|
+
const mockValidation = {
|
|
128
|
+
getAllIssues: () => [{ message: 'Mobile error', severity: 'error' }],
|
|
129
|
+
isClean: () => false,
|
|
130
|
+
isValidating: false
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
render(<ValidationErrorDisplay validation={mockValidation} variant="inapp" />);
|
|
134
|
+
|
|
135
|
+
expect(screen.getByTestId('error-info-note')).toBeInTheDocument();
|
|
136
|
+
expect(screen.getByTestId('error-message')).toHaveTextContent('Mobile error');
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
it('includes rule information in error messages when available', () => {
|
|
140
|
+
const mockValidation = {
|
|
141
|
+
getAllIssues: () => [
|
|
142
|
+
{ message: 'Alt attribute required', severity: 'error', rule: 'alt-require', line: 5 }
|
|
143
|
+
],
|
|
144
|
+
isClean: () => false,
|
|
145
|
+
isValidating: false
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
render(<ValidationErrorDisplay validation={mockValidation} />);
|
|
149
|
+
|
|
150
|
+
expect(screen.getByTestId('error-message')).toHaveTextContent('Alt attribute required Line 5. • alt-require');
|
|
151
|
+
});
|
|
152
|
+
});
|
package/v2Components/HtmlEditor/components/ValidationErrorDisplay/_validationErrorDisplay.scss
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* ValidationErrorDisplay Styles
|
|
3
|
-
*
|
|
4
|
-
* When collapsed, panel sticks to footer (header bar only visible).
|
|
5
3
|
*/
|
|
6
4
|
|
|
7
5
|
@import '~@capillarytech/cap-ui-library/styles/_variables.scss';
|
|
@@ -11,18 +9,10 @@
|
|
|
11
9
|
flex-direction: column;
|
|
12
10
|
width: 100%;
|
|
13
11
|
margin-bottom: 1rem;
|
|
14
|
-
flex-shrink: 0;
|
|
15
12
|
|
|
16
13
|
// Ensure proper spacing when used in different contexts
|
|
17
14
|
&:last-child {
|
|
18
15
|
margin-bottom: 0;
|
|
19
|
-
padding-bottom: 0.25rem;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
// Collapsed: panel stays in footer as a slim bar (tabs + expand arrow only)
|
|
23
|
-
&--collapsed {
|
|
24
|
-
margin-bottom: 0;
|
|
25
|
-
padding-bottom: 0.25rem;
|
|
26
16
|
}
|
|
27
17
|
|
|
28
18
|
// Integration with ErrorInfoNote component
|
|
@@ -33,17 +23,9 @@
|
|
|
33
23
|
// Responsive adjustments
|
|
34
24
|
@media (max-width: 768px) {
|
|
35
25
|
margin-bottom: 0.75rem;
|
|
36
|
-
|
|
37
|
-
&.validation-error-display--collapsed {
|
|
38
|
-
margin-bottom: 0;
|
|
39
|
-
}
|
|
40
26
|
}
|
|
41
27
|
|
|
42
28
|
@media (max-width: 576px) {
|
|
43
29
|
margin-bottom: 0.5rem;
|
|
44
|
-
|
|
45
|
-
&.validation-error-display--collapsed {
|
|
46
|
-
margin-bottom: 0;
|
|
47
|
-
}
|
|
48
30
|
}
|
|
49
31
|
}
|
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* ValidationErrorDisplay - HTML Editor validation
|
|
2
|
+
* ValidationErrorDisplay - HTML Editor validation using ErrorInfoNote
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* This component integrates the existing ErrorInfoNote component with the HTML Editor's
|
|
5
|
+
* validation system, providing a consistent error display that matches the Figma design.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import React
|
|
8
|
+
import React from 'react';
|
|
9
9
|
import PropTypes from 'prop-types';
|
|
10
10
|
|
|
11
|
-
import
|
|
12
|
-
import
|
|
11
|
+
import CapRow from '@capillarytech/cap-ui-library/CapRow';
|
|
12
|
+
import ErrorInfoNote from '../../../ErrorInfoNote';
|
|
13
|
+
|
|
14
|
+
import { transformValidationToErrorInfo, hasValidationErrors } from '../../utils/validationAdapter';
|
|
15
|
+
import { HTML_EDITOR_VARIANTS } from '../../constants';
|
|
13
16
|
|
|
14
17
|
// Styles
|
|
15
18
|
import './_validationErrorDisplay.scss';
|
|
@@ -17,59 +20,51 @@ import './_validationErrorDisplay.scss';
|
|
|
17
20
|
/**
|
|
18
21
|
* ValidationErrorDisplay Component
|
|
19
22
|
*
|
|
20
|
-
* Displays validation
|
|
23
|
+
* Displays validation errors using the existing ErrorInfoNote component
|
|
21
24
|
*/
|
|
22
25
|
const ValidationErrorDisplay = ({
|
|
23
26
|
validation,
|
|
27
|
+
variant = HTML_EDITOR_VARIANTS.EMAIL,
|
|
24
28
|
onErrorClick,
|
|
25
|
-
className = ''
|
|
29
|
+
className = ''
|
|
26
30
|
}) => {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
const handleToggleCollapse = () => {
|
|
30
|
-
setIsCollapsed((prev) => !prev);
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
// Expand panel when user clicks redirection (so panel does not stay stuck to footer)
|
|
34
|
-
const handleExpand = () => {
|
|
35
|
-
setIsCollapsed(false);
|
|
36
|
-
};
|
|
37
|
-
|
|
31
|
+
// Don't render if no validation or no errors
|
|
38
32
|
if (!hasValidationErrors(validation)) {
|
|
39
33
|
return null;
|
|
40
34
|
}
|
|
41
35
|
|
|
36
|
+
// Transform validation data to ErrorInfoNote format
|
|
37
|
+
const errorData = transformValidationToErrorInfo(validation, variant);
|
|
38
|
+
const { errorMessages } = errorData || {};
|
|
39
|
+
|
|
40
|
+
// Handle error click if provided
|
|
41
|
+
const handleErrorClick = (error) => {
|
|
42
|
+
onErrorClick?.(error);
|
|
43
|
+
};
|
|
44
|
+
|
|
42
45
|
return (
|
|
43
|
-
<
|
|
44
|
-
className={`validation-error-display ${
|
|
46
|
+
<CapRow
|
|
47
|
+
className={`validation-error-display ${className}`}
|
|
45
48
|
role="alert"
|
|
46
49
|
aria-live="polite"
|
|
47
50
|
aria-label="Validation errors"
|
|
48
51
|
>
|
|
49
|
-
<
|
|
50
|
-
|
|
51
|
-
onErrorClick={
|
|
52
|
-
isCollapsed={isCollapsed}
|
|
53
|
-
onToggleCollapse={handleToggleCollapse}
|
|
54
|
-
onExpand={handleExpand}
|
|
52
|
+
<ErrorInfoNote
|
|
53
|
+
errorMessages={errorMessages}
|
|
54
|
+
onErrorClick={handleErrorClick}
|
|
55
55
|
/>
|
|
56
|
-
</
|
|
56
|
+
</CapRow>
|
|
57
57
|
);
|
|
58
58
|
};
|
|
59
59
|
|
|
60
60
|
ValidationErrorDisplay.propTypes = {
|
|
61
61
|
validation: PropTypes.shape({
|
|
62
62
|
isValidating: PropTypes.bool,
|
|
63
|
-
getAllIssues: PropTypes.func
|
|
63
|
+
getAllIssues: PropTypes.func
|
|
64
64
|
}),
|
|
65
|
+
variant: PropTypes.oneOf(Object.values(HTML_EDITOR_VARIANTS)),
|
|
65
66
|
onErrorClick: PropTypes.func,
|
|
66
|
-
className: PropTypes.string
|
|
67
|
-
};
|
|
68
|
-
|
|
69
|
-
ValidationErrorDisplay.defaultProps = {
|
|
70
|
-
validation: null,
|
|
71
|
-
onErrorClick: null,
|
|
72
|
-
className: '',
|
|
67
|
+
className: PropTypes.string
|
|
73
68
|
};
|
|
74
69
|
|
|
75
70
|
export default ValidationErrorDisplay;
|
|
@@ -5,17 +5,17 @@
|
|
|
5
5
|
@import '~@capillarytech/cap-ui-library/styles/_variables.scss';
|
|
6
6
|
|
|
7
7
|
.validation-panel {
|
|
8
|
-
border: 1px solid
|
|
9
|
-
border-radius:
|
|
10
|
-
background:
|
|
8
|
+
border: 1px solid #d9d9d9;
|
|
9
|
+
border-radius: 6px;
|
|
10
|
+
background: #fff;
|
|
11
11
|
|
|
12
12
|
&--loading {
|
|
13
|
-
padding:
|
|
13
|
+
padding: 16px;
|
|
14
14
|
text-align: center;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
&--clean {
|
|
18
|
-
padding:
|
|
18
|
+
padding: 16px;
|
|
19
19
|
text-align: center;
|
|
20
20
|
background: #f6ffed;
|
|
21
21
|
border-color: #b7eb8f;
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
display: flex;
|
|
26
26
|
align-items: center;
|
|
27
27
|
justify-content: center;
|
|
28
|
-
gap:
|
|
28
|
+
gap: 8px;
|
|
29
29
|
color: #666;
|
|
30
30
|
font-size: 14px;
|
|
31
31
|
}
|
|
@@ -34,36 +34,36 @@
|
|
|
34
34
|
display: flex;
|
|
35
35
|
align-items: center;
|
|
36
36
|
justify-content: center;
|
|
37
|
-
gap:
|
|
37
|
+
gap: 8px;
|
|
38
38
|
color: #52c41a;
|
|
39
39
|
font-size: 14px;
|
|
40
|
-
font-weight:
|
|
40
|
+
font-weight: 500;
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
&__summary {
|
|
44
44
|
display: flex;
|
|
45
|
-
gap:
|
|
46
|
-
padding:
|
|
47
|
-
background:
|
|
48
|
-
border-bottom: 1px solid
|
|
49
|
-
border-radius:
|
|
45
|
+
gap: 16px;
|
|
46
|
+
padding: 12px 16px;
|
|
47
|
+
background: #fafafa;
|
|
48
|
+
border-bottom: 1px solid #d9d9d9;
|
|
49
|
+
border-radius: 6px 6px 0 0;
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
&__summary-item {
|
|
53
53
|
display: flex;
|
|
54
54
|
align-items: center;
|
|
55
|
-
gap:
|
|
56
|
-
font-size:
|
|
55
|
+
gap: 4px;
|
|
56
|
+
font-size: 12px;
|
|
57
57
|
color: #666;
|
|
58
58
|
|
|
59
59
|
&--security {
|
|
60
60
|
color: #ff4d4f;
|
|
61
|
-
font-weight:
|
|
61
|
+
font-weight: 500;
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
span:first-of-type {
|
|
65
65
|
font-weight: 600;
|
|
66
|
-
margin-left:
|
|
66
|
+
margin-left: 2px;
|
|
67
67
|
}
|
|
68
68
|
}
|
|
69
69
|
|
|
@@ -72,7 +72,7 @@
|
|
|
72
72
|
border: none;
|
|
73
73
|
|
|
74
74
|
&:last-child {
|
|
75
|
-
border-radius: 0 0
|
|
75
|
+
border-radius: 0 0 6px 6px;
|
|
76
76
|
}
|
|
77
77
|
}
|
|
78
78
|
|
|
@@ -123,8 +123,8 @@
|
|
|
123
123
|
&__title {
|
|
124
124
|
display: flex;
|
|
125
125
|
align-items: center;
|
|
126
|
-
gap:
|
|
127
|
-
font-weight:
|
|
126
|
+
gap: 8px;
|
|
127
|
+
font-weight: 500;
|
|
128
128
|
}
|
|
129
129
|
|
|
130
130
|
&__issues {
|
|
@@ -133,41 +133,41 @@
|
|
|
133
133
|
}
|
|
134
134
|
|
|
135
135
|
&__sanitization {
|
|
136
|
-
border-top: 1px solid
|
|
136
|
+
border-top: 1px solid #d9d9d9;
|
|
137
137
|
background: #f9f9f9;
|
|
138
138
|
}
|
|
139
139
|
|
|
140
140
|
&__sanitization-header {
|
|
141
141
|
display: flex;
|
|
142
142
|
align-items: center;
|
|
143
|
-
gap:
|
|
144
|
-
padding:
|
|
145
|
-
font-weight:
|
|
143
|
+
gap: 8px;
|
|
144
|
+
padding: 12px 16px;
|
|
145
|
+
font-weight: 500;
|
|
146
146
|
color: #666;
|
|
147
147
|
font-size: 13px;
|
|
148
148
|
}
|
|
149
149
|
|
|
150
150
|
&__sanitization-list {
|
|
151
|
-
padding: 0
|
|
151
|
+
padding: 0 16px 12px;
|
|
152
152
|
}
|
|
153
153
|
|
|
154
154
|
&__sanitization-item {
|
|
155
|
-
padding:
|
|
156
|
-
font-size:
|
|
155
|
+
padding: 4px 0;
|
|
156
|
+
font-size: 12px;
|
|
157
157
|
color: #8c8c8c;
|
|
158
158
|
}
|
|
159
159
|
}
|
|
160
160
|
|
|
161
161
|
.validation-issue {
|
|
162
162
|
display: flex;
|
|
163
|
-
gap:
|
|
164
|
-
padding:
|
|
163
|
+
gap: 12px;
|
|
164
|
+
padding: 12px 16px;
|
|
165
165
|
border-bottom: 1px solid #f0f0f0;
|
|
166
166
|
cursor: pointer;
|
|
167
167
|
transition: background-color 0.2s;
|
|
168
168
|
|
|
169
169
|
&:hover {
|
|
170
|
-
background:
|
|
170
|
+
background: #fafafa;
|
|
171
171
|
}
|
|
172
172
|
|
|
173
173
|
&:last-child {
|
|
@@ -189,18 +189,6 @@
|
|
|
189
189
|
&__icon {
|
|
190
190
|
flex-shrink: 0;
|
|
191
191
|
margin-top: 2px;
|
|
192
|
-
|
|
193
|
-
&--error {
|
|
194
|
-
color: #ff4d4f;
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
&--info {
|
|
198
|
-
color: #1890ff;
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
&--security {
|
|
202
|
-
color: #ff4d4f;
|
|
203
|
-
}
|
|
204
192
|
}
|
|
205
193
|
|
|
206
194
|
&__content {
|
|
@@ -212,14 +200,14 @@
|
|
|
212
200
|
font-size: 13px;
|
|
213
201
|
line-height: 1.4;
|
|
214
202
|
color: #262626;
|
|
215
|
-
margin-bottom:
|
|
203
|
+
margin-bottom: 4px;
|
|
216
204
|
word-break: break-word;
|
|
217
205
|
}
|
|
218
206
|
|
|
219
207
|
&__meta {
|
|
220
208
|
display: flex;
|
|
221
209
|
flex-wrap: wrap;
|
|
222
|
-
gap:
|
|
210
|
+
gap: 8px;
|
|
223
211
|
font-size: 11px;
|
|
224
212
|
color: #8c8c8c;
|
|
225
213
|
}
|
|
@@ -242,9 +230,9 @@
|
|
|
242
230
|
&__source {
|
|
243
231
|
display: flex;
|
|
244
232
|
align-items: center;
|
|
245
|
-
gap:
|
|
233
|
+
gap: 4px;
|
|
246
234
|
background: #f0f0f0;
|
|
247
|
-
padding:
|
|
235
|
+
padding: 2px 6px;
|
|
248
236
|
border-radius: 3px;
|
|
249
237
|
}
|
|
250
238
|
}
|