@capillarytech/creatives-library 8.0.266 → 8.0.267

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (147) hide show
  1. package/constants/unified.js +0 -1
  2. package/package.json +1 -1
  3. package/services/api.js +0 -5
  4. package/utils/common.js +0 -6
  5. package/utils/tests/transformerUtils.test.js +0 -297
  6. package/utils/transformerUtils.js +0 -40
  7. package/v2Components/CapImageUpload/constants.js +0 -2
  8. package/v2Components/CapImageUpload/index.js +16 -65
  9. package/v2Components/CapImageUpload/index.scss +1 -4
  10. package/v2Components/CapImageUpload/messages.js +1 -5
  11. package/v2Components/CommonTestAndPreview/index.js +15 -4
  12. package/v2Containers/App/constants.js +0 -5
  13. package/v2Containers/CreativesContainer/SlideBoxContent.js +2 -57
  14. package/v2Containers/CreativesContainer/SlideBoxHeader.js +0 -1
  15. package/v2Containers/CreativesContainer/constants.js +0 -3
  16. package/v2Containers/CreativesContainer/index.js +0 -168
  17. package/v2Containers/CreativesContainer/messages.js +0 -4
  18. package/v2Containers/CreativesContainer/tests/SlideBoxContent.test.js +0 -210
  19. package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxContent.test.js.snap +0 -304
  20. package/v2Containers/SmsTrai/Edit/index.js +12 -1
  21. package/v2Containers/SmsTrai/Edit/tests/__snapshots__/index.test.js.snap +648 -36
  22. package/v2Containers/Templates/ChannelTypeIllustration.js +1 -13
  23. package/v2Containers/Templates/_templates.scss +0 -205
  24. package/v2Containers/Templates/actions.js +1 -2
  25. package/v2Containers/Templates/constants.js +0 -1
  26. package/v2Containers/Templates/index.js +34 -274
  27. package/v2Containers/Templates/messages.js +0 -24
  28. package/v2Containers/Templates/reducer.js +0 -2
  29. package/v2Containers/Templates/tests/index.test.js +0 -10
  30. package/v2Containers/TemplatesV2/index.js +7 -15
  31. package/v2Containers/TemplatesV2/messages.js +0 -4
  32. package/utils/imageUrlUpload.js +0 -141
  33. package/v2Components/CapImageUrlUpload/constants.js +0 -26
  34. package/v2Components/CapImageUrlUpload/index.js +0 -365
  35. package/v2Components/CapImageUrlUpload/index.scss +0 -35
  36. package/v2Components/CapImageUrlUpload/messages.js +0 -47
  37. package/v2Containers/WebPush/Create/components/BrandIconSection.js +0 -108
  38. package/v2Containers/WebPush/Create/components/ButtonForm.js +0 -172
  39. package/v2Containers/WebPush/Create/components/ButtonItem.js +0 -101
  40. package/v2Containers/WebPush/Create/components/ButtonList.js +0 -145
  41. package/v2Containers/WebPush/Create/components/ButtonsLinksSection.js +0 -164
  42. package/v2Containers/WebPush/Create/components/ButtonsLinksSection.test.js +0 -463
  43. package/v2Containers/WebPush/Create/components/FormActions.js +0 -54
  44. package/v2Containers/WebPush/Create/components/FormActions.test.js +0 -163
  45. package/v2Containers/WebPush/Create/components/MediaSection.js +0 -142
  46. package/v2Containers/WebPush/Create/components/MediaSection.test.js +0 -341
  47. package/v2Containers/WebPush/Create/components/MessageSection.js +0 -103
  48. package/v2Containers/WebPush/Create/components/MessageSection.test.js +0 -268
  49. package/v2Containers/WebPush/Create/components/NotificationTitleSection.js +0 -87
  50. package/v2Containers/WebPush/Create/components/NotificationTitleSection.test.js +0 -210
  51. package/v2Containers/WebPush/Create/components/TemplateNameSection.js +0 -54
  52. package/v2Containers/WebPush/Create/components/TemplateNameSection.test.js +0 -143
  53. package/v2Containers/WebPush/Create/components/__snapshots__/ButtonsLinksSection.test.js.snap +0 -86
  54. package/v2Containers/WebPush/Create/components/__snapshots__/FormActions.test.js.snap +0 -16
  55. package/v2Containers/WebPush/Create/components/__snapshots__/MediaSection.test.js.snap +0 -41
  56. package/v2Containers/WebPush/Create/components/__snapshots__/MessageSection.test.js.snap +0 -54
  57. package/v2Containers/WebPush/Create/components/__snapshots__/NotificationTitleSection.test.js.snap +0 -37
  58. package/v2Containers/WebPush/Create/components/__snapshots__/TemplateNameSection.test.js.snap +0 -21
  59. package/v2Containers/WebPush/Create/components/_buttons.scss +0 -246
  60. package/v2Containers/WebPush/Create/components/tests/ButtonForm.test.js +0 -554
  61. package/v2Containers/WebPush/Create/components/tests/ButtonItem.test.js +0 -607
  62. package/v2Containers/WebPush/Create/components/tests/ButtonList.test.js +0 -633
  63. package/v2Containers/WebPush/Create/components/tests/__snapshots__/ButtonForm.test.js.snap +0 -666
  64. package/v2Containers/WebPush/Create/components/tests/__snapshots__/ButtonItem.test.js.snap +0 -74
  65. package/v2Containers/WebPush/Create/components/tests/__snapshots__/ButtonList.test.js.snap +0 -78
  66. package/v2Containers/WebPush/Create/hooks/useButtonManagement.js +0 -138
  67. package/v2Containers/WebPush/Create/hooks/useButtonManagement.test.js +0 -406
  68. package/v2Containers/WebPush/Create/hooks/useCharacterCount.js +0 -30
  69. package/v2Containers/WebPush/Create/hooks/useCharacterCount.test.js +0 -151
  70. package/v2Containers/WebPush/Create/hooks/useImageUpload.js +0 -104
  71. package/v2Containers/WebPush/Create/hooks/useImageUpload.test.js +0 -538
  72. package/v2Containers/WebPush/Create/hooks/useTagManagement.js +0 -122
  73. package/v2Containers/WebPush/Create/hooks/useTagManagement.test.js +0 -633
  74. package/v2Containers/WebPush/Create/index.js +0 -1148
  75. package/v2Containers/WebPush/Create/index.scss +0 -134
  76. package/v2Containers/WebPush/Create/messages.js +0 -211
  77. package/v2Containers/WebPush/Create/preview/DevicePreviewContent.js +0 -228
  78. package/v2Containers/WebPush/Create/preview/NotificationContainer.js +0 -294
  79. package/v2Containers/WebPush/Create/preview/PreviewContent.js +0 -90
  80. package/v2Containers/WebPush/Create/preview/PreviewControls.js +0 -305
  81. package/v2Containers/WebPush/Create/preview/PreviewDisclaimer.js +0 -25
  82. package/v2Containers/WebPush/Create/preview/WebPushPreview.js +0 -156
  83. package/v2Containers/WebPush/Create/preview/assets/Light.svg +0 -53
  84. package/v2Containers/WebPush/Create/preview/assets/Top.svg +0 -5
  85. package/v2Containers/WebPush/Create/preview/assets/android-arrow-down.svg +0 -9
  86. package/v2Containers/WebPush/Create/preview/assets/android-arrow-up.svg +0 -9
  87. package/v2Containers/WebPush/Create/preview/assets/chrome-icon.png +0 -0
  88. package/v2Containers/WebPush/Create/preview/assets/edge-icon.png +0 -0
  89. package/v2Containers/WebPush/Create/preview/assets/firefox-icon.svg +0 -106
  90. package/v2Containers/WebPush/Create/preview/assets/iOS.svg +0 -26
  91. package/v2Containers/WebPush/Create/preview/assets/macos-arrow-down-icon.svg +0 -9
  92. package/v2Containers/WebPush/Create/preview/assets/macos-triple-dot-icon.svg +0 -9
  93. package/v2Containers/WebPush/Create/preview/assets/opera-icon.svg +0 -18
  94. package/v2Containers/WebPush/Create/preview/assets/safari-icon.svg +0 -29
  95. package/v2Containers/WebPush/Create/preview/assets/windows-close-icon.svg +0 -9
  96. package/v2Containers/WebPush/Create/preview/assets/windows-triple-dot-icon.svg +0 -9
  97. package/v2Containers/WebPush/Create/preview/components/AndroidMobileChromeHeader.js +0 -51
  98. package/v2Containers/WebPush/Create/preview/components/AndroidMobileExpanded.js +0 -145
  99. package/v2Containers/WebPush/Create/preview/components/IOSHeader.js +0 -45
  100. package/v2Containers/WebPush/Create/preview/components/NotificationExpandedContent.js +0 -68
  101. package/v2Containers/WebPush/Create/preview/components/NotificationHeader.js +0 -61
  102. package/v2Containers/WebPush/Create/preview/components/WindowsChromeExpanded.js +0 -99
  103. package/v2Containers/WebPush/Create/preview/components/tests/AndroidMobileExpanded.test.js +0 -733
  104. package/v2Containers/WebPush/Create/preview/components/tests/WindowsChromeExpanded.test.js +0 -571
  105. package/v2Containers/WebPush/Create/preview/components/tests/__snapshots__/AndroidMobileExpanded.test.js.snap +0 -85
  106. package/v2Containers/WebPush/Create/preview/components/tests/__snapshots__/WindowsChromeExpanded.test.js.snap +0 -81
  107. package/v2Containers/WebPush/Create/preview/config/notificationMappings.js +0 -50
  108. package/v2Containers/WebPush/Create/preview/constants.js +0 -637
  109. package/v2Containers/WebPush/Create/preview/notification-container.scss +0 -79
  110. package/v2Containers/WebPush/Create/preview/preview.scss +0 -358
  111. package/v2Containers/WebPush/Create/preview/styles/_android-mobile-chrome.scss +0 -370
  112. package/v2Containers/WebPush/Create/preview/styles/_android-mobile-edge.scss +0 -12
  113. package/v2Containers/WebPush/Create/preview/styles/_android-mobile-firefox.scss +0 -12
  114. package/v2Containers/WebPush/Create/preview/styles/_android-mobile-opera.scss +0 -12
  115. package/v2Containers/WebPush/Create/preview/styles/_android-tablet-chrome.scss +0 -47
  116. package/v2Containers/WebPush/Create/preview/styles/_android-tablet-edge.scss +0 -11
  117. package/v2Containers/WebPush/Create/preview/styles/_android-tablet-firefox.scss +0 -11
  118. package/v2Containers/WebPush/Create/preview/styles/_android-tablet-opera.scss +0 -11
  119. package/v2Containers/WebPush/Create/preview/styles/_base.scss +0 -207
  120. package/v2Containers/WebPush/Create/preview/styles/_ios.scss +0 -153
  121. package/v2Containers/WebPush/Create/preview/styles/_ipados.scss +0 -107
  122. package/v2Containers/WebPush/Create/preview/styles/_macos-chrome.scss +0 -101
  123. package/v2Containers/WebPush/Create/preview/styles/_windows-chrome.scss +0 -229
  124. package/v2Containers/WebPush/Create/preview/tests/DevicePreviewContent.test.js +0 -906
  125. package/v2Containers/WebPush/Create/preview/tests/NotificationContainer.test.js +0 -1081
  126. package/v2Containers/WebPush/Create/preview/tests/PreviewControls.test.js +0 -723
  127. package/v2Containers/WebPush/Create/preview/tests/WebPushPreview.test.js +0 -1327
  128. package/v2Containers/WebPush/Create/preview/tests/__snapshots__/DevicePreviewContent.test.js.snap +0 -131
  129. package/v2Containers/WebPush/Create/preview/tests/__snapshots__/NotificationContainer.test.js.snap +0 -112
  130. package/v2Containers/WebPush/Create/preview/tests/__snapshots__/PreviewControls.test.js.snap +0 -144
  131. package/v2Containers/WebPush/Create/preview/tests/__snapshots__/WebPushPreview.test.js.snap +0 -129
  132. package/v2Containers/WebPush/Create/utils/payloadBuilder.js +0 -96
  133. package/v2Containers/WebPush/Create/utils/payloadBuilder.test.js +0 -396
  134. package/v2Containers/WebPush/Create/utils/previewUtils.js +0 -89
  135. package/v2Containers/WebPush/Create/utils/urlValidation.js +0 -115
  136. package/v2Containers/WebPush/Create/utils/urlValidation.test.js +0 -449
  137. package/v2Containers/WebPush/Create/utils/validation.js +0 -75
  138. package/v2Containers/WebPush/Create/utils/validation.test.js +0 -283
  139. package/v2Containers/WebPush/actions.js +0 -60
  140. package/v2Containers/WebPush/constants.js +0 -132
  141. package/v2Containers/WebPush/index.js +0 -2
  142. package/v2Containers/WebPush/reducer.js +0 -104
  143. package/v2Containers/WebPush/sagas.js +0 -119
  144. package/v2Containers/WebPush/selectors.js +0 -65
  145. package/v2Containers/WebPush/tests/reducer.test.js +0 -863
  146. package/v2Containers/WebPush/tests/sagas.test.js +0 -566
  147. package/v2Containers/WebPush/tests/selectors.test.js +0 -960
@@ -1,47 +0,0 @@
1
- import { defineMessages } from 'react-intl';
2
-
3
- const scope = 'app.v2Components.CapImageUrlUpload';
4
-
5
- export default defineMessages({
6
- imageUrlPlaceholder: {
7
- id: `${scope}.imageUrlPlaceholder`,
8
- defaultMessage: 'Enter image URL',
9
- },
10
- imageUrlInvalid: {
11
- id: `${scope}.imageUrlInvalid`,
12
- defaultMessage: 'Please enter a valid image URL',
13
- },
14
- imageTypeInvalid: {
15
- id: `${scope}.imageTypeInvalid`,
16
- defaultMessage: 'Invalid image type. Only JPEG, JPG, and PNG formats are allowed',
17
- },
18
- imageSizeInvalid: {
19
- id: `${scope}.imageSizeInvalid`,
20
- defaultMessage: 'Image size exceeds the maximum limit',
21
- },
22
- imageLoadError: {
23
- id: `${scope}.imageLoadError`,
24
- defaultMessage: 'Failed to load image. Please check the URL and try again',
25
- },
26
- validatingUrl: {
27
- id: `${scope}.validatingUrl`,
28
- defaultMessage: 'Validating image URL...',
29
- },
30
- uploadingImage: {
31
- id: `${scope}.uploadingImage`,
32
- defaultMessage: 'Uploading image to gallery...',
33
- },
34
- recommendedDimensions: {
35
- id: `${scope}.recommendedDimensions`,
36
- defaultMessage: 'Recommended dimensions: {dimensions}',
37
- },
38
- sizeLimit: {
39
- id: `${scope}.sizeLimit`,
40
- defaultMessage: 'Size upto: {size}',
41
- },
42
- formatTypes: {
43
- id: `${scope}.formatTypes`,
44
- defaultMessage: 'Format: {formats}',
45
- },
46
- });
47
-
@@ -1,108 +0,0 @@
1
- import React from 'react';
2
- import PropTypes from 'prop-types';
3
- import { FormattedMessage } from 'react-intl';
4
- import CapRow from '@capillarytech/cap-ui-library/CapRow';
5
- import CapHeading from '@capillarytech/cap-ui-library/CapHeading';
6
- import CapRadioGroup from '@capillarytech/cap-ui-library/CapRadioGroup';
7
- import CapDivider from '@capillarytech/cap-ui-library/CapDivider';
8
- import CapImageUpload from '../../../../v2Components/CapImageUpload';
9
- import { WEBPUSH_BRAND_ICON } from '../../../CreativesContainer/constants';
10
- import {
11
- BRAND_ICON_OPTIONS,
12
- ALLOWED_IMAGE_EXTENSIONS_REGEX,
13
- WEBPUSH_BRAND_ICON_SIZE,
14
- WEBPUSH_BRAND_ICON_RECOMMENDED_DIMENSIONS,
15
- } from '../../constants';
16
-
17
- /**
18
- * BrandIconSection component - Brand icon/logo upload options
19
- */
20
- export const BrandIconSection = ({
21
- brandIconOption,
22
- onBrandIconChange,
23
- brandIconUpload,
24
- isLocked,
25
- isAnyUploadActive,
26
- formatMessage,
27
- messages,
28
- webPush,
29
- isFullMode,
30
- }) => {
31
- const {
32
- imageSrc: brandIconSrc,
33
- uploadAsset: uploadBrandIconAsset,
34
- setUpdateImageSrc: setUpdateBrandIconSrc,
35
- updateOnReUpload: updateOnBrandIconReUpload,
36
- } = brandIconUpload;
37
-
38
- const brandIconOptions = [
39
- { value: BRAND_ICON_OPTIONS.DONT_SHOW, label: formatMessage(messages.dontShow) },
40
- { value: BRAND_ICON_OPTIONS.UPLOAD_IMAGE, label: formatMessage(messages.uploadImage) },
41
- // NOTE: Commented out due to technical blocker - "Add image URL" option for Brand icon/logo
42
- // { value: BRAND_ICON_OPTIONS.ADD_IMAGE_URL, label: formatMessage(messages.addImageUrl) },
43
- ];
44
-
45
- return (
46
- <>
47
- <CapRow className="creatives-webpush-brand-icon">
48
- <CapHeading type="h4" className="webpush-brand-icon">
49
- <FormattedMessage {...messages.brandIconLogo} />
50
- </CapHeading>
51
- <CapRadioGroup
52
- options={brandIconOptions}
53
- value={brandIconOption}
54
- onChange={onBrandIconChange}
55
- disabled={isAnyUploadActive}
56
- />
57
- </CapRow>
58
- {brandIconOption === BRAND_ICON_OPTIONS.UPLOAD_IMAGE && (
59
- <CapRow
60
- className="webpush-brand-icon-upload-section"
61
- style={isLocked ? { pointerEvents: 'none', opacity: 0.5 } : undefined}
62
- aria-disabled={isLocked}
63
- >
64
- <CapImageUpload
65
- allowedExtensionsRegex={ALLOWED_IMAGE_EXTENSIONS_REGEX}
66
- imgSize={WEBPUSH_BRAND_ICON_SIZE}
67
- uploadAsset={uploadBrandIconAsset}
68
- isFullMode={isFullMode}
69
- imageSrc={brandIconSrc}
70
- updateImageSrc={setUpdateBrandIconSrc}
71
- updateOnReUpload={updateOnBrandIconReUpload}
72
- index={1}
73
- className="cap-custom-image-upload"
74
- key="webpush-brand-icon-uploaded-image"
75
- imageData={webPush}
76
- channel={WEBPUSH_BRAND_ICON}
77
- showReUploadButton
78
- recommendedDimensions={WEBPUSH_BRAND_ICON_RECOMMENDED_DIMENSIONS}
79
- disabled={isLocked}
80
- />
81
- </CapRow>
82
- )}
83
- <CapDivider />
84
- </>
85
- );
86
- };
87
-
88
- BrandIconSection.propTypes = {
89
- brandIconOption: PropTypes.string.isRequired,
90
- onBrandIconChange: PropTypes.func.isRequired,
91
- brandIconUpload: PropTypes.object.isRequired,
92
- isLocked: PropTypes.bool,
93
- isAnyUploadActive: PropTypes.bool,
94
- formatMessage: PropTypes.func.isRequired,
95
- messages: PropTypes.object.isRequired,
96
- webPush: PropTypes.object,
97
- isFullMode: PropTypes.bool,
98
- };
99
-
100
- BrandIconSection.defaultProps = {
101
- isLocked: false,
102
- isAnyUploadActive: false,
103
- webPush: {},
104
- isFullMode: true,
105
- };
106
-
107
- export default BrandIconSection;
108
-
@@ -1,172 +0,0 @@
1
- import React, { useState, useCallback } from 'react';
2
- import PropTypes from 'prop-types';
3
- import { FormattedMessage } from 'react-intl';
4
- import CapRow from '@capillarytech/cap-ui-library/CapRow';
5
- import CapInput from '@capillarytech/cap-ui-library/CapInput';
6
- import CapButton from '@capillarytech/cap-ui-library/CapButton';
7
- import CapHeading from '@capillarytech/cap-ui-library/CapHeading';
8
- import messages from '../messages';
9
- import { isValidHttpUrl } from '../utils/urlValidation';
10
- import { WEBPUSH_BUTTON_TYPES, BUTTON_TEXT_MAX_LENGTH } from '../../constants';
11
-
12
- const ButtonForm = ({
13
- buttonType, // 'primary' or 'secondary'
14
- formatMessage,
15
- onSave,
16
- onCancel,
17
- initialData,
18
- isEditMode,
19
- }) => {
20
- const [buttonText, setButtonText] = useState(initialData?.text || '');
21
- const [buttonUrl, setButtonUrl] = useState(initialData?.url || '');
22
- const [buttonTextError, setButtonTextError] = useState('');
23
- const [buttonUrlError, setButtonUrlError] = useState('');
24
-
25
- const validateButtonText = useCallback((value) => {
26
- if (!value || value.trim() === '') {
27
- return formatMessage(messages.buttonTextRequired);
28
- }
29
- return '';
30
- }, [formatMessage]);
31
-
32
- const validateButtonUrl = useCallback((value) => {
33
- if (!value || value.trim() === '') {
34
- return formatMessage(messages.buttonUrlRequired);
35
- }
36
-
37
- if (!isValidHttpUrl(value)) {
38
- return formatMessage(messages.buttonUrlInvalid);
39
- }
40
-
41
- return '';
42
- }, [formatMessage]);
43
-
44
- const handleButtonTextChange = useCallback((e) => {
45
- const { value } = e.target;
46
- setButtonText(value);
47
- const nextError = validateButtonText(value);
48
- setButtonTextError((prev) => (prev === nextError ? prev : nextError));
49
- }, [validateButtonText]);
50
-
51
- const handleButtonUrlChange = useCallback((e) => {
52
- const { value } = e.target;
53
- setButtonUrl(value);
54
- const nextError = validateButtonUrl(value);
55
- setButtonUrlError((prev) => (prev === nextError ? prev : nextError));
56
- }, [validateButtonUrl]);
57
-
58
- const handleSave = useCallback(() => {
59
- const textError = validateButtonText(buttonText);
60
- const urlError = validateButtonUrl(buttonUrl);
61
-
62
- if (textError || urlError) {
63
- setButtonTextError(textError);
64
- setButtonUrlError(urlError);
65
- return;
66
- }
67
-
68
- onSave({
69
- text: buttonText.trim(),
70
- url: buttonUrl.trim(),
71
- type: buttonType,
72
- });
73
- }, [buttonText, buttonUrl, buttonType, onSave, validateButtonText, validateButtonUrl]);
74
-
75
- const handleCancel = useCallback(() => {
76
- onCancel();
77
- }, [onCancel]);
78
-
79
- const isSaveDisabled = !buttonText.trim() || !buttonUrl.trim() || buttonTextError || buttonUrlError;
80
-
81
- const renderCharacterCountSuffix = () => {
82
- const currentLength = buttonText.length;
83
- const maxLength = BUTTON_TEXT_MAX_LENGTH;
84
-
85
- return (
86
- <span className="button-character-count-suffix">
87
- {`${currentLength}/${maxLength}`}
88
- </span>
89
- );
90
- };
91
-
92
- const handleKeyDown = useCallback((e) => {
93
- if (e.key === 'Enter' && !isSaveDisabled) {
94
- e.preventDefault();
95
- handleSave();
96
- }
97
- }, [handleSave, isSaveDisabled]);
98
-
99
- return (
100
- <div className="webpush-button-form" onKeyDown={handleKeyDown}>
101
- <CapRow className="button-form-row">
102
- <CapHeading type="h4" className="button-form-heading">
103
- <FormattedMessage {...messages.buttonText} />
104
- </CapHeading>
105
- <div className="button-form-field">
106
- <CapInput
107
- id={`webpush-button-text-input-${buttonType}`}
108
- placeholder={formatMessage(messages.buttonTextPlaceholder)}
109
- value={buttonText}
110
- onChange={handleButtonTextChange}
111
- maxLength={BUTTON_TEXT_MAX_LENGTH}
112
- size="default"
113
- status={buttonTextError ? 'error' : ''}
114
- help={buttonTextError || ''}
115
- suffix={renderCharacterCountSuffix()}
116
- />
117
- </div>
118
- </CapRow>
119
- <CapRow className="button-form-row">
120
- <CapHeading type="h4" className="button-form-heading">
121
- <FormattedMessage {...messages.buttonUrlLabel} />
122
- </CapHeading>
123
- <CapInput
124
- id={`webpush-button-url-input-${buttonType}`}
125
- placeholder={formatMessage(messages.buttonUrlPlaceholder)}
126
- value={buttonUrl}
127
- onChange={handleButtonUrlChange}
128
- size="default"
129
- status={buttonUrlError ? 'error' : ''}
130
- help={buttonUrlError || ''}
131
- />
132
- </CapRow>
133
- <CapRow className="button-form-actions">
134
- <CapButton
135
- type="primary"
136
- onClick={handleSave}
137
- disabled={isSaveDisabled}
138
- className="button-form-save"
139
- >
140
- <FormattedMessage {...messages.saveButton} />
141
- </CapButton>
142
- <CapButton
143
- type="secondary"
144
- onClick={handleCancel}
145
- className="button-form-cancel"
146
- >
147
- <FormattedMessage {...(isEditMode ? messages.cancelButton : messages.deleteButton)} />
148
- </CapButton>
149
- </CapRow>
150
- </div>
151
- );
152
- };
153
-
154
- ButtonForm.propTypes = {
155
- buttonType: PropTypes.oneOf([WEBPUSH_BUTTON_TYPES.PRIMARY, WEBPUSH_BUTTON_TYPES.SECONDARY]).isRequired,
156
- formatMessage: PropTypes.func.isRequired,
157
- onSave: PropTypes.func.isRequired,
158
- onCancel: PropTypes.func.isRequired,
159
- initialData: PropTypes.shape({
160
- text: PropTypes.string,
161
- url: PropTypes.string,
162
- }),
163
- isEditMode: PropTypes.bool,
164
- };
165
-
166
- ButtonForm.defaultProps = {
167
- initialData: null,
168
- isEditMode: false,
169
- };
170
-
171
- export default ButtonForm;
172
-
@@ -1,101 +0,0 @@
1
- import React from 'react';
2
- import PropTypes from 'prop-types';
3
- import CapRow from '@capillarytech/cap-ui-library/CapRow';
4
- import CapColumn from '@capillarytech/cap-ui-library/CapColumn';
5
- import CapIcon from '@capillarytech/cap-ui-library/CapIcon';
6
-
7
- const ButtonItem = ({
8
- button,
9
- index,
10
- onEdit,
11
- onDelete,
12
- onDragStart,
13
- onDragOver,
14
- onDrop,
15
- onDragEnd,
16
- disabled,
17
- }) => {
18
- const handleDragStart = (e) => {
19
- if (disabled) return;
20
- e.dataTransfer.effectAllowed = 'move';
21
- e.dataTransfer.setData('text/html', e.currentTarget);
22
- onDragStart(index);
23
- };
24
-
25
- const handleDragOver = (e) => {
26
- if (disabled) return;
27
- e.preventDefault();
28
- e.dataTransfer.dropEffect = 'move';
29
- onDragOver(index);
30
- };
31
-
32
- const handleDrop = (e) => {
33
- if (disabled) return;
34
- e.preventDefault();
35
- e.stopPropagation();
36
- onDrop(index);
37
- };
38
-
39
- return (
40
- <div
41
- className={`webpush-button-item ${disabled ? 'disabled' : ''}`}
42
- draggable={!disabled}
43
- onDragStart={handleDragStart}
44
- onDragOver={handleDragOver}
45
- onDrop={handleDrop}
46
- onDragEnd={onDragEnd}
47
- >
48
- <CapRow align="middle" className="button-item-content">
49
- <CapColumn span={1} className="button-item-drag-handle">
50
- <CapIcon type="drag" className="drag-icon" />
51
- </CapColumn>
52
- <CapColumn span={1} className="button-item-icon">
53
- <CapIcon type="link" className="link-icon" />
54
- </CapColumn>
55
- <CapColumn span={14} className="button-item-info">
56
- <div className="button-item-text-row">
57
- <span className="button-item-text">{button.text}</span>
58
- </div>
59
- </CapColumn>
60
- <CapColumn span={8} className="button-item-actions">
61
- <div className="button-item-url">{button.url}</div>
62
- <div className="action-icons">
63
- <CapIcon
64
- type="edit"
65
- className="action-icon"
66
- onClick={() => !disabled && onEdit(index)}
67
- />
68
- <CapIcon
69
- type="delete"
70
- className="action-icon delete-icon"
71
- onClick={() => !disabled && onDelete(index)}
72
- />
73
- </div>
74
- </CapColumn>
75
- </CapRow>
76
- </div>
77
- );
78
- };
79
-
80
- ButtonItem.propTypes = {
81
- button: PropTypes.shape({
82
- text: PropTypes.string.isRequired,
83
- url: PropTypes.string.isRequired,
84
- type: PropTypes.string.isRequired,
85
- }).isRequired,
86
- index: PropTypes.number.isRequired,
87
- onEdit: PropTypes.func.isRequired,
88
- onDelete: PropTypes.func.isRequired,
89
- onDragStart: PropTypes.func.isRequired,
90
- onDragOver: PropTypes.func.isRequired,
91
- onDrop: PropTypes.func.isRequired,
92
- onDragEnd: PropTypes.func.isRequired,
93
- disabled: PropTypes.bool,
94
- };
95
-
96
- ButtonItem.defaultProps = {
97
- disabled: false,
98
- };
99
-
100
- export default ButtonItem;
101
-
@@ -1,145 +0,0 @@
1
- import React, { useState } from 'react';
2
- import PropTypes from 'prop-types';
3
- import { FormattedMessage } from 'react-intl';
4
- import CapRow from '@capillarytech/cap-ui-library/CapRow';
5
- import CapButton from '@capillarytech/cap-ui-library/CapButton';
6
- import ButtonItem from './ButtonItem';
7
- import messages from '../messages';
8
-
9
- const ButtonList = ({
10
- buttons,
11
- onEdit,
12
- onDelete,
13
- onReorder,
14
- onAddPrimary,
15
- onAddSecondary,
16
- showAddPrimary,
17
- showAddSecondary,
18
- disabled,
19
- disableSecondaryButton,
20
- isInlineFormVisible,
21
- inlineFormIndex,
22
- renderInlineForm,
23
- }) => {
24
- const [draggedIndex, setDraggedIndex] = useState(null);
25
-
26
- const handleDragStart = (index) => {
27
- if (disabled) return;
28
- setDraggedIndex(index);
29
- };
30
-
31
- const handleDragOver = (index) => {
32
- if (disabled) return;
33
- if (draggedIndex === null || draggedIndex === index) return;
34
-
35
- // Reorder buttons
36
- onReorder(draggedIndex, index);
37
- setDraggedIndex(index);
38
- };
39
-
40
- const handleDrop = () => {
41
- if (disabled) return;
42
- };
43
-
44
- const handleDragEnd = () => {
45
- if (disabled) return;
46
- setDraggedIndex(null);
47
- };
48
-
49
- const shouldRenderInlineForm = isInlineFormVisible
50
- && typeof inlineFormIndex === 'number'
51
- && inlineFormIndex >= 0;
52
-
53
- // Don't render the container if there are no buttons
54
- if (buttons.length === 0) {
55
- return null;
56
- }
57
-
58
- return (
59
- <div className="webpush-button-list">
60
- {buttons.map((button, index) => {
61
- if (shouldRenderInlineForm && inlineFormIndex === index && typeof renderInlineForm === 'function') {
62
- return (
63
- <div key={`button-inline-form-${button.id}`} className="button-inline-form">
64
- {renderInlineForm()}
65
- </div>
66
- );
67
- }
68
- // Only disable items that are not being edited
69
- const isItemDisabled = disabled || (isInlineFormVisible && inlineFormIndex !== null && inlineFormIndex !== index);
70
- return (
71
- <ButtonItem
72
- key={button.id}
73
- button={button}
74
- index={index}
75
- onEdit={onEdit}
76
- onDelete={onDelete}
77
- onDragStart={handleDragStart}
78
- onDragOver={handleDragOver}
79
- onDrop={handleDrop}
80
- onDragEnd={handleDragEnd}
81
- disabled={isItemDisabled}
82
- />
83
- );
84
- })}
85
- {showAddPrimary && (
86
- <CapRow className="button-list-add-button">
87
- <CapButton
88
- type="flat"
89
- onClick={onAddPrimary}
90
- className="add-primary-button button-add-trigger"
91
- icon="plus"
92
- disabled={disabled}
93
- >
94
- <FormattedMessage {...messages.addPrimaryButton} />
95
- </CapButton>
96
- </CapRow>
97
- )}
98
- {showAddSecondary && (
99
- <CapRow className="button-list-add-button">
100
- <CapButton
101
- type="flat"
102
- onClick={onAddSecondary}
103
- className="add-secondary-button button-add-trigger"
104
- icon="plus"
105
- disabled={disableSecondaryButton || disabled}
106
- >
107
- <FormattedMessage {...messages.addSecondaryButton} />
108
- </CapButton>
109
- </CapRow>
110
- )}
111
- </div>
112
- );
113
- };
114
-
115
- ButtonList.propTypes = {
116
- buttons: PropTypes.arrayOf(PropTypes.shape({
117
- id: PropTypes.string.isRequired,
118
- text: PropTypes.string.isRequired,
119
- url: PropTypes.string.isRequired,
120
- type: PropTypes.string.isRequired,
121
- })).isRequired,
122
- onEdit: PropTypes.func.isRequired,
123
- onDelete: PropTypes.func.isRequired,
124
- onReorder: PropTypes.func.isRequired,
125
- onAddPrimary: PropTypes.func.isRequired,
126
- onAddSecondary: PropTypes.func.isRequired,
127
- showAddPrimary: PropTypes.bool.isRequired,
128
- showAddSecondary: PropTypes.bool.isRequired,
129
- disabled: PropTypes.bool,
130
- disableSecondaryButton: PropTypes.bool,
131
- isInlineFormVisible: PropTypes.bool,
132
- inlineFormIndex: PropTypes.number,
133
- renderInlineForm: PropTypes.func,
134
- };
135
-
136
- ButtonList.defaultProps = {
137
- disabled: false,
138
- disableSecondaryButton: false,
139
- isInlineFormVisible: false,
140
- inlineFormIndex: null,
141
- renderInlineForm: null,
142
- };
143
-
144
- export default ButtonList;
145
-