@capillarytech/creatives-library 9.0.37-alpha.0 → 9.0.37
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/package.json +1 -1
- package/translations/en.json +2 -2
- package/v2Components/AccessForbidden/index.js +3 -5
- package/v2Components/AccessForbidden/messages.js +2 -3
- package/v2Containers/App/constants.js +0 -5
- package/v2Containers/Assets/Gallery/_gallery.scss +0 -6
- package/v2Containers/Assets/Gallery/index.js +10 -34
- package/v2Containers/Cap/index.js +2 -5
- package/v2Containers/Cap/messages.js +0 -4
- package/v2Containers/Cap/tests/__snapshots__/index.test.js.snap +2 -2
- package/v2Containers/Line/Container/ImageCarousel/tests/__snapshots__/content.test.js.snap +6 -6
- package/v2Containers/Line/Container/ImageCarousel/tests/__snapshots__/index.test.js.snap +4 -4
- package/v2Containers/Line/Container/Wrapper/tests/__snapshots__/index.test.js.snap +32 -32
- package/v2Containers/Line/Container/tests/__snapshots__/index.test.js.snap +36 -36
- package/v2Containers/Rcs/tests/__snapshots__/index.test.js.snap +118 -118
- package/v2Containers/SmsTrai/Create/tests/__snapshots__/index.test.js.snap +8 -8
- package/v2Containers/SmsTrai/Edit/tests/__snapshots__/index.test.js.snap +18 -18
- package/v2Containers/Templates/ChannelTypeIllustration.js +1 -10
- package/v2Containers/Templates/_templates.scss +0 -6
- package/v2Containers/Templates/index.js +100 -141
- package/v2Containers/Templates/tests/ChannelTypeIllustration.test.js +0 -7
- package/v2Containers/Templates/tests/__snapshots__/index.test.js.snap +120 -173
- package/v2Containers/TemplatesV2/index.js +5 -16
- package/v2Containers/Whatsapp/tests/__snapshots__/index.test.js.snap +268 -268
- package/utils/permissions.js +0 -59
- package/utils/tests/permissions.test.js +0 -116
- package/v2Components/AccessForbidden/_accessForbidden.scss +0 -14
- package/v2Components/NoPermissionWrapper/_noPermissionWrapper.scss +0 -12
- package/v2Components/NoPermissionWrapper/index.js +0 -26
|
@@ -112,8 +112,8 @@ exports[`Creatives SmsTraiCreate test/> done button should be disabled if blank
|
|
|
112
112
|
"app.v2containers.SmsTrai.Edit.traiEditTitle": "Message",
|
|
113
113
|
"app.v2containers.SmsTrai.Edit.unicodeLabel": "Allow unicode characters",
|
|
114
114
|
"app.v2containers.SmsTrai.Edit.unsupportedTagsValidationError": "Unsupported tags: {unsupportedTags}. Please remove them from this message.",
|
|
115
|
-
"creatives.components.AccessForbidden.forbiddenDesc": "
|
|
116
|
-
"creatives.components.AccessForbidden.forbiddenHeader": "
|
|
115
|
+
"creatives.components.AccessForbidden.forbiddenDesc": "This page access has not been provided to you.",
|
|
116
|
+
"creatives.components.AccessForbidden.forbiddenHeader": "Access Forbidden",
|
|
117
117
|
"creatives.components.BreadCrumbs.header": "This is the BreadCrumbs component !",
|
|
118
118
|
"creatives.components.CapTagList.Cancel": "Cancel",
|
|
119
119
|
"creatives.components.CapTagList.Ok": "Ok",
|
|
@@ -3273,8 +3273,8 @@ exports[`Creatives SmsTraiCreate test/> invalid file drop 1`] = `
|
|
|
3273
3273
|
"app.v2containers.SmsTrai.Edit.traiEditTitle": "Message",
|
|
3274
3274
|
"app.v2containers.SmsTrai.Edit.unicodeLabel": "Allow unicode characters",
|
|
3275
3275
|
"app.v2containers.SmsTrai.Edit.unsupportedTagsValidationError": "Unsupported tags: {unsupportedTags}. Please remove them from this message.",
|
|
3276
|
-
"creatives.components.AccessForbidden.forbiddenDesc": "
|
|
3277
|
-
"creatives.components.AccessForbidden.forbiddenHeader": "
|
|
3276
|
+
"creatives.components.AccessForbidden.forbiddenDesc": "This page access has not been provided to you.",
|
|
3277
|
+
"creatives.components.AccessForbidden.forbiddenHeader": "Access Forbidden",
|
|
3278
3278
|
"creatives.components.BreadCrumbs.header": "This is the BreadCrumbs component !",
|
|
3279
3279
|
"creatives.components.CapTagList.Cancel": "Cancel",
|
|
3280
3280
|
"creatives.components.CapTagList.Ok": "Ok",
|
|
@@ -6417,8 +6417,8 @@ exports[`Creatives SmsTraiCreate test/> renders UI 1`] = `
|
|
|
6417
6417
|
"app.v2containers.SmsTrai.Edit.traiEditTitle": "Message",
|
|
6418
6418
|
"app.v2containers.SmsTrai.Edit.unicodeLabel": "Allow unicode characters",
|
|
6419
6419
|
"app.v2containers.SmsTrai.Edit.unsupportedTagsValidationError": "Unsupported tags: {unsupportedTags}. Please remove them from this message.",
|
|
6420
|
-
"creatives.components.AccessForbidden.forbiddenDesc": "
|
|
6421
|
-
"creatives.components.AccessForbidden.forbiddenHeader": "
|
|
6420
|
+
"creatives.components.AccessForbidden.forbiddenDesc": "This page access has not been provided to you.",
|
|
6421
|
+
"creatives.components.AccessForbidden.forbiddenHeader": "Access Forbidden",
|
|
6422
6422
|
"creatives.components.BreadCrumbs.header": "This is the BreadCrumbs component !",
|
|
6423
6423
|
"creatives.components.CapTagList.Cancel": "Cancel",
|
|
6424
6424
|
"creatives.components.CapTagList.Ok": "Ok",
|
|
@@ -9578,8 +9578,8 @@ exports[`Creatives SmsTraiCreate test/> valid file drop 1`] = `
|
|
|
9578
9578
|
"app.v2containers.SmsTrai.Edit.traiEditTitle": "Message",
|
|
9579
9579
|
"app.v2containers.SmsTrai.Edit.unicodeLabel": "Allow unicode characters",
|
|
9580
9580
|
"app.v2containers.SmsTrai.Edit.unsupportedTagsValidationError": "Unsupported tags: {unsupportedTags}. Please remove them from this message.",
|
|
9581
|
-
"creatives.components.AccessForbidden.forbiddenDesc": "
|
|
9582
|
-
"creatives.components.AccessForbidden.forbiddenHeader": "
|
|
9581
|
+
"creatives.components.AccessForbidden.forbiddenDesc": "This page access has not been provided to you.",
|
|
9582
|
+
"creatives.components.AccessForbidden.forbiddenHeader": "Access Forbidden",
|
|
9583
9583
|
"creatives.components.BreadCrumbs.header": "This is the BreadCrumbs component !",
|
|
9584
9584
|
"creatives.components.CapTagList.Cancel": "Cancel",
|
|
9585
9585
|
"creatives.components.CapTagList.Ok": "Ok",
|
|
@@ -87,8 +87,8 @@ exports[`Creatives SmsTraiEdit test/> should render 1`] = `
|
|
|
87
87
|
"app.v2containers.SmsTrai.Edit.traiEditTitle": "Message",
|
|
88
88
|
"app.v2containers.SmsTrai.Edit.unicodeLabel": "Allow unicode characters",
|
|
89
89
|
"app.v2containers.SmsTrai.Edit.unsupportedTagsValidationError": "Unsupported tags: {unsupportedTags}. Please remove them from this message.",
|
|
90
|
-
"creatives.components.AccessForbidden.forbiddenDesc": "
|
|
91
|
-
"creatives.components.AccessForbidden.forbiddenHeader": "
|
|
90
|
+
"creatives.components.AccessForbidden.forbiddenDesc": "This page access has not been provided to you.",
|
|
91
|
+
"creatives.components.AccessForbidden.forbiddenHeader": "Access Forbidden",
|
|
92
92
|
"creatives.components.BreadCrumbs.header": "This is the BreadCrumbs component !",
|
|
93
93
|
"creatives.components.CapTagList.Cancel": "Cancel",
|
|
94
94
|
"creatives.components.CapTagList.Ok": "Ok",
|
|
@@ -7411,8 +7411,8 @@ FREE GIFTS-
|
|
|
7411
7411
|
"app.v2containers.SmsTrai.Edit.traiEditTitle": "Message",
|
|
7412
7412
|
"app.v2containers.SmsTrai.Edit.unicodeLabel": "Allow unicode characters",
|
|
7413
7413
|
"app.v2containers.SmsTrai.Edit.unsupportedTagsValidationError": "Unsupported tags: {unsupportedTags}. Please remove them from this message.",
|
|
7414
|
-
"creatives.components.AccessForbidden.forbiddenDesc": "
|
|
7415
|
-
"creatives.components.AccessForbidden.forbiddenHeader": "
|
|
7414
|
+
"creatives.components.AccessForbidden.forbiddenDesc": "This page access has not been provided to you.",
|
|
7415
|
+
"creatives.components.AccessForbidden.forbiddenHeader": "Access Forbidden",
|
|
7416
7416
|
"creatives.components.BreadCrumbs.header": "This is the BreadCrumbs component !",
|
|
7417
7417
|
"creatives.components.CapTagList.Cancel": "Cancel",
|
|
7418
7418
|
"creatives.components.CapTagList.Ok": "Ok",
|
|
@@ -9749,8 +9749,8 @@ FREE GIFTS-
|
|
|
9749
9749
|
"app.v2containers.SmsTrai.Edit.traiEditTitle": "Message",
|
|
9750
9750
|
"app.v2containers.SmsTrai.Edit.unicodeLabel": "Allow unicode characters",
|
|
9751
9751
|
"app.v2containers.SmsTrai.Edit.unsupportedTagsValidationError": "Unsupported tags: {unsupportedTags}. Please remove them from this message.",
|
|
9752
|
-
"creatives.components.AccessForbidden.forbiddenDesc": "
|
|
9753
|
-
"creatives.components.AccessForbidden.forbiddenHeader": "
|
|
9752
|
+
"creatives.components.AccessForbidden.forbiddenDesc": "This page access has not been provided to you.",
|
|
9753
|
+
"creatives.components.AccessForbidden.forbiddenHeader": "Access Forbidden",
|
|
9754
9754
|
"creatives.components.BreadCrumbs.header": "This is the BreadCrumbs component !",
|
|
9755
9755
|
"creatives.components.CapTagList.Cancel": "Cancel",
|
|
9756
9756
|
"creatives.components.CapTagList.Ok": "Ok",
|
|
@@ -12238,8 +12238,8 @@ exports[`Creatives SmsTraiEdit test/> should render 2`] = `
|
|
|
12238
12238
|
"app.v2containers.SmsTrai.Edit.traiEditTitle": "Message",
|
|
12239
12239
|
"app.v2containers.SmsTrai.Edit.unicodeLabel": "Allow unicode characters",
|
|
12240
12240
|
"app.v2containers.SmsTrai.Edit.unsupportedTagsValidationError": "Unsupported tags: {unsupportedTags}. Please remove them from this message.",
|
|
12241
|
-
"creatives.components.AccessForbidden.forbiddenDesc": "
|
|
12242
|
-
"creatives.components.AccessForbidden.forbiddenHeader": "
|
|
12241
|
+
"creatives.components.AccessForbidden.forbiddenDesc": "This page access has not been provided to you.",
|
|
12242
|
+
"creatives.components.AccessForbidden.forbiddenHeader": "Access Forbidden",
|
|
12243
12243
|
"creatives.components.BreadCrumbs.header": "This is the BreadCrumbs component !",
|
|
12244
12244
|
"creatives.components.CapTagList.Cancel": "Cancel",
|
|
12245
12245
|
"creatives.components.CapTagList.Ok": "Ok",
|
|
@@ -20936,8 +20936,8 @@ FREE GIFTS-
|
|
|
20936
20936
|
"app.v2containers.SmsTrai.Edit.traiEditTitle": "Message",
|
|
20937
20937
|
"app.v2containers.SmsTrai.Edit.unicodeLabel": "Allow unicode characters",
|
|
20938
20938
|
"app.v2containers.SmsTrai.Edit.unsupportedTagsValidationError": "Unsupported tags: {unsupportedTags}. Please remove them from this message.",
|
|
20939
|
-
"creatives.components.AccessForbidden.forbiddenDesc": "
|
|
20940
|
-
"creatives.components.AccessForbidden.forbiddenHeader": "
|
|
20939
|
+
"creatives.components.AccessForbidden.forbiddenDesc": "This page access has not been provided to you.",
|
|
20940
|
+
"creatives.components.AccessForbidden.forbiddenHeader": "Access Forbidden",
|
|
20941
20941
|
"creatives.components.BreadCrumbs.header": "This is the BreadCrumbs component !",
|
|
20942
20942
|
"creatives.components.CapTagList.Cancel": "Cancel",
|
|
20943
20943
|
"creatives.components.CapTagList.Ok": "Ok",
|
|
@@ -23274,8 +23274,8 @@ FREE GIFTS-
|
|
|
23274
23274
|
"app.v2containers.SmsTrai.Edit.traiEditTitle": "Message",
|
|
23275
23275
|
"app.v2containers.SmsTrai.Edit.unicodeLabel": "Allow unicode characters",
|
|
23276
23276
|
"app.v2containers.SmsTrai.Edit.unsupportedTagsValidationError": "Unsupported tags: {unsupportedTags}. Please remove them from this message.",
|
|
23277
|
-
"creatives.components.AccessForbidden.forbiddenDesc": "
|
|
23278
|
-
"creatives.components.AccessForbidden.forbiddenHeader": "
|
|
23277
|
+
"creatives.components.AccessForbidden.forbiddenDesc": "This page access has not been provided to you.",
|
|
23278
|
+
"creatives.components.AccessForbidden.forbiddenHeader": "Access Forbidden",
|
|
23279
23279
|
"creatives.components.BreadCrumbs.header": "This is the BreadCrumbs component !",
|
|
23280
23280
|
"creatives.components.CapTagList.Cancel": "Cancel",
|
|
23281
23281
|
"creatives.components.CapTagList.Ok": "Ok",
|
|
@@ -25763,8 +25763,8 @@ exports[`Creatives SmsTraiEdit test/> should save 1`] = `
|
|
|
25763
25763
|
"app.v2containers.SmsTrai.Edit.traiEditTitle": "Message",
|
|
25764
25764
|
"app.v2containers.SmsTrai.Edit.unicodeLabel": "Allow unicode characters",
|
|
25765
25765
|
"app.v2containers.SmsTrai.Edit.unsupportedTagsValidationError": "Unsupported tags: {unsupportedTags}. Please remove them from this message.",
|
|
25766
|
-
"creatives.components.AccessForbidden.forbiddenDesc": "
|
|
25767
|
-
"creatives.components.AccessForbidden.forbiddenHeader": "
|
|
25766
|
+
"creatives.components.AccessForbidden.forbiddenDesc": "This page access has not been provided to you.",
|
|
25767
|
+
"creatives.components.AccessForbidden.forbiddenHeader": "Access Forbidden",
|
|
25768
25768
|
"creatives.components.BreadCrumbs.header": "This is the BreadCrumbs component !",
|
|
25769
25769
|
"creatives.components.CapTagList.Cancel": "Cancel",
|
|
25770
25770
|
"creatives.components.CapTagList.Ok": "Ok",
|
|
@@ -33087,8 +33087,8 @@ FREE GIFTS-
|
|
|
33087
33087
|
"app.v2containers.SmsTrai.Edit.traiEditTitle": "Message",
|
|
33088
33088
|
"app.v2containers.SmsTrai.Edit.unicodeLabel": "Allow unicode characters",
|
|
33089
33089
|
"app.v2containers.SmsTrai.Edit.unsupportedTagsValidationError": "Unsupported tags: {unsupportedTags}. Please remove them from this message.",
|
|
33090
|
-
"creatives.components.AccessForbidden.forbiddenDesc": "
|
|
33091
|
-
"creatives.components.AccessForbidden.forbiddenHeader": "
|
|
33090
|
+
"creatives.components.AccessForbidden.forbiddenDesc": "This page access has not been provided to you.",
|
|
33091
|
+
"creatives.components.AccessForbidden.forbiddenHeader": "Access Forbidden",
|
|
33092
33092
|
"creatives.components.BreadCrumbs.header": "This is the BreadCrumbs component !",
|
|
33093
33093
|
"creatives.components.CapTagList.Cancel": "Cancel",
|
|
33094
33094
|
"creatives.components.CapTagList.Ok": "Ok",
|
|
@@ -35425,8 +35425,8 @@ FREE GIFTS-
|
|
|
35425
35425
|
"app.v2containers.SmsTrai.Edit.traiEditTitle": "Message",
|
|
35426
35426
|
"app.v2containers.SmsTrai.Edit.unicodeLabel": "Allow unicode characters",
|
|
35427
35427
|
"app.v2containers.SmsTrai.Edit.unsupportedTagsValidationError": "Unsupported tags: {unsupportedTags}. Please remove them from this message.",
|
|
35428
|
-
"creatives.components.AccessForbidden.forbiddenDesc": "
|
|
35429
|
-
"creatives.components.AccessForbidden.forbiddenHeader": "
|
|
35428
|
+
"creatives.components.AccessForbidden.forbiddenDesc": "This page access has not been provided to you.",
|
|
35429
|
+
"creatives.components.AccessForbidden.forbiddenHeader": "Access Forbidden",
|
|
35430
35430
|
"creatives.components.BreadCrumbs.header": "This is the BreadCrumbs component !",
|
|
35431
35431
|
"creatives.components.CapTagList.Cancel": "Cancel",
|
|
35432
35432
|
"creatives.components.CapTagList.Ok": "Ok",
|
|
@@ -2,9 +2,8 @@ import React, { useMemo } from 'react';
|
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
3
|
import zaloillustration from '@capillarytech/cap-ui-library/assets/images/featureUiNotEnabledIllustration.svg';
|
|
4
4
|
import inAppIllustration from '@capillarytech/cap-ui-library/assets/images/featureUiNotEnabledIllustration.svg';
|
|
5
|
-
import { FormattedMessage
|
|
5
|
+
import { FormattedMessage } from 'react-intl';
|
|
6
6
|
import { CapIllustration } from "@capillarytech/cap-ui-library";
|
|
7
|
-
import globalMessages from '../Cap/messages';
|
|
8
7
|
import emailIllustration from '../Assets/images/emailIllustration.svg';
|
|
9
8
|
import smsIllustration from '../Assets/images/smsIllustration.svg';
|
|
10
9
|
import pushIllustration from '../Assets/images/pushIllustration.svg';
|
|
@@ -80,14 +79,12 @@ const CHANNEL_CONFIG = {
|
|
|
80
79
|
};
|
|
81
80
|
|
|
82
81
|
function ChannelTypeIllustration(props) {
|
|
83
|
-
const intl = useIntl();
|
|
84
82
|
const {
|
|
85
83
|
isFullMode,
|
|
86
84
|
createTemplate,
|
|
87
85
|
currentChannel,
|
|
88
86
|
hostName,
|
|
89
87
|
isArchivedMode,
|
|
90
|
-
canCreate = true,
|
|
91
88
|
} = props;
|
|
92
89
|
|
|
93
90
|
const templateText = useMemo(() => {
|
|
@@ -186,11 +183,6 @@ function ChannelTypeIllustration(props) {
|
|
|
186
183
|
if (config.hasButton) {
|
|
187
184
|
result.buttonLabel = <FormattedMessage {...config.buttonMessage} values={{ template: templateText }} />;
|
|
188
185
|
result.onClick = createTemplate;
|
|
189
|
-
// RBAC: gray out + disable the create button for users without create permission.
|
|
190
|
-
if (!canCreate) {
|
|
191
|
-
result.disabled = true;
|
|
192
|
-
result.buttonTooltip = intl.formatMessage(globalMessages.noPermissionAction);
|
|
193
|
-
}
|
|
194
186
|
}
|
|
195
187
|
|
|
196
188
|
if (config.descriptionMessage) {
|
|
@@ -221,6 +213,5 @@ ChannelTypeIllustration.propTypes = {
|
|
|
221
213
|
currentChannel: PropTypes.string,
|
|
222
214
|
hostName: PropTypes.string,
|
|
223
215
|
isArchivedMode: PropTypes.bool,
|
|
224
|
-
canCreate: PropTypes.bool,
|
|
225
216
|
};
|
|
226
217
|
export default ChannelTypeIllustration;
|
|
@@ -97,9 +97,6 @@ import WhatsappStatusContainer from '../../v2Components/WhatsappStatusContainer'
|
|
|
97
97
|
import WechatRichmediaTemplatePreview from '../../v2Components/TemplatePreview/WechatRichmediaTemplatePreview';
|
|
98
98
|
import CapCustomSkeleton from '../../v2Components/CapCustomSkeleton';
|
|
99
99
|
import ChannelTypeIllustration from './ChannelTypeIllustration';
|
|
100
|
-
import NoPermissionWrapper from '../../v2Components/NoPermissionWrapper';
|
|
101
|
-
import { getUserAccess, hasPermission, PERMISSIONS } from '../../utils/permissions';
|
|
102
|
-
|
|
103
100
|
import TestAndPreviewSlidebox from '../../v2Components/TestAndPreviewSlidebox';
|
|
104
101
|
import creativesMessages from '../CreativesContainer/messages';
|
|
105
102
|
import {
|
|
@@ -1974,7 +1971,7 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
1974
1971
|
}
|
|
1975
1972
|
/>
|
|
1976
1973
|
) : (
|
|
1977
|
-
<ChannelTypeIllustration isFullMode={this.props.isFullMode} createTemplate={this.createTemplate}
|
|
1974
|
+
<ChannelTypeIllustration isFullMode={this.props.isFullMode} createTemplate={this.createTemplate} currentChannel={this.state?.channel?.toUpperCase()} hostName={this.state?.hostName}/>
|
|
1978
1975
|
);
|
|
1979
1976
|
}
|
|
1980
1977
|
|
|
@@ -2108,7 +2105,7 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
2108
2105
|
);
|
|
2109
2106
|
})()
|
|
2110
2107
|
],
|
|
2111
|
-
hoverOption: isArchivedMode
|
|
2108
|
+
hoverOption: isArchivedMode ? null : (
|
|
2112
2109
|
<CapButton
|
|
2113
2110
|
className={
|
|
2114
2111
|
this.props.isFullMode
|
|
@@ -2172,47 +2169,56 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
2172
2169
|
{![WECHAT, WHATSAPP, ZALO].includes(
|
|
2173
2170
|
this.state.channel.toUpperCase()
|
|
2174
2171
|
) &&
|
|
2175
|
-
!isTraiDltFeature && !template.isArchived &&
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2172
|
+
!isTraiDltFeature && !template.isArchived && (
|
|
2173
|
+
<CapMenu.Item
|
|
2174
|
+
className={`duplicate-${channelLowerCase}`}
|
|
2175
|
+
onClick={() => this.duplicateTemplate(template)}
|
|
2176
|
+
>
|
|
2177
|
+
<FormattedMessage {...messages.duplicateButton} />
|
|
2178
|
+
</CapMenu.Item>
|
|
2179
|
+
)}
|
|
2181
2180
|
{/* Archive/Unarchive menu item (full mode only, not for Zalo, not for WhatsApp/RCS awaiting/pending) */}
|
|
2182
2181
|
{commonUtil.hasCreativesArchivalEnabled() && (() => {
|
|
2183
2182
|
const channelUp = this.state.channel.toUpperCase();
|
|
2184
2183
|
if (!this.isChannelArchiveEligible(channelUp, status, rcsStatus)) return null;
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2184
|
+
return !template?.isArchived ? (
|
|
2185
|
+
<CapMenu.Item
|
|
2186
|
+
className={`archive-${channelLowerCase}`}
|
|
2187
|
+
onClick={() => this.handleTemplateArchiveAction({ templateId: template._id, templateName: template.name })}
|
|
2188
|
+
>
|
|
2189
|
+
<FormattedMessage {...messages.archiveButton} />
|
|
2190
|
+
</CapMenu.Item>
|
|
2191
|
+
) : (
|
|
2192
|
+
<CapMenu.Item
|
|
2193
|
+
className={`unarchive-${channelLowerCase}`}
|
|
2194
|
+
onClick={() => this.handleTemplateArchiveAction({ templateId: template._id, templateName: template.name, isUnarchive: true })}
|
|
2195
|
+
>
|
|
2196
|
+
<FormattedMessage {...messages.unarchiveButton} />
|
|
2197
|
+
</CapMenu.Item>
|
|
2198
|
+
);
|
|
2199
2199
|
})()}
|
|
2200
2200
|
{/* Delete/Unmap menu item */}
|
|
2201
2201
|
{(!(
|
|
2202
2202
|
this.state.channel.toUpperCase() === WHATSAPP &&
|
|
2203
2203
|
status === WHATSAPP_STATUSES.approved
|
|
2204
|
-
) && ![ZALO].includes(this.state.channel.toUpperCase())) &&
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2204
|
+
) && ![ZALO].includes(this.state.channel.toUpperCase())) && (
|
|
2205
|
+
<CapMenu.Item
|
|
2206
|
+
className={
|
|
2207
|
+
this.state.channel.toUpperCase() === WECHAT &&
|
|
2208
|
+
!template.definition
|
|
2209
|
+
? `unmap-${channelLowerCase}`
|
|
2210
|
+
: `delete-${channelLowerCase}`
|
|
2211
|
+
}
|
|
2212
|
+
onClick={() => this.toggleDeleteTemplateModal(template)}
|
|
2213
|
+
>
|
|
2214
|
+
{this.state.channel.toUpperCase() === WECHAT &&
|
|
2215
|
+
!template.definition ? (
|
|
2216
|
+
<FormattedMessage {...messages.unMapButton} />
|
|
2217
|
+
) : (
|
|
2218
|
+
<FormattedMessage {...messages.deleteButton} />
|
|
2219
|
+
)}
|
|
2220
|
+
</CapMenu.Item>
|
|
2221
|
+
)}
|
|
2216
2222
|
</CapMenu>
|
|
2217
2223
|
}
|
|
2218
2224
|
>
|
|
@@ -2741,18 +2747,16 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
2741
2747
|
<CapLabel type="label2">
|
|
2742
2748
|
{this.props.intl.formatMessage(messages.templatesSelected, { count: selectedCountLocal })}
|
|
2743
2749
|
</CapLabel>
|
|
2744
|
-
<
|
|
2745
|
-
|
|
2746
|
-
|
|
2747
|
-
|
|
2748
|
-
|
|
2749
|
-
|
|
2750
|
-
>
|
|
2751
|
-
<
|
|
2752
|
-
|
|
2753
|
-
|
|
2754
|
-
</CapButton>
|
|
2755
|
-
</NoPermissionWrapper>
|
|
2750
|
+
<CapButton
|
|
2751
|
+
type="primary"
|
|
2752
|
+
className="archive-template-button"
|
|
2753
|
+
prefix={<CapIcon type="archive" size="s" />}
|
|
2754
|
+
onClick={() => this.handleBulkArchiveAction({ ids: selectedIdsArrayLocal, count: selectedCountLocal, isUnarchive: isArchivedModeLocal })}
|
|
2755
|
+
>
|
|
2756
|
+
<span className="archive-btn-label">
|
|
2757
|
+
<FormattedMessage {...(isArchivedModeLocal ? messages.unarchiveButton : messages.archiveButton)} />
|
|
2758
|
+
</span>
|
|
2759
|
+
</CapButton>
|
|
2756
2760
|
<CapButton type="secondary" onClick={() => this.props.actions.clearTemplateSelection()}>
|
|
2757
2761
|
<FormattedMessage {...messages.archiveConfirmCancel} />
|
|
2758
2762
|
</CapButton>
|
|
@@ -2791,14 +2795,14 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
2791
2795
|
</div> : (
|
|
2792
2796
|
showIllustrationForChannel(MOBILE_PUSH_LOWERCASE) &&
|
|
2793
2797
|
<div style={this.isFullMode() ? { height: "calc(100vh - 325px)", overflow: 'auto'} : {}}>
|
|
2794
|
-
<ChannelTypeIllustration isFullMode={this.props.isFullMode} createTemplate={this.createTemplate}
|
|
2798
|
+
<ChannelTypeIllustration isFullMode={this.props.isFullMode} createTemplate={this.createTemplate} currentChannel={currentChannel} hostName={this.state?.hostName}/>
|
|
2795
2799
|
</div>
|
|
2796
2800
|
)
|
|
2797
2801
|
}
|
|
2798
2802
|
{(showWhatsappIllustration || showZaloIllustration) && !get(this.props, 'Templates.isArchivedMode', false) && (
|
|
2799
2803
|
noLoaderAndSearchText &&
|
|
2800
2804
|
<div style={this.isFullMode() ? { height: "calc(100vh - 325px)", overflow: 'auto' } : {}}>
|
|
2801
|
-
{noWhatsappZaloTemplates && <ChannelTypeIllustration isFullMode={this.props.isFullMode} createTemplate={this.createTemplate}
|
|
2805
|
+
{noWhatsappZaloTemplates && <ChannelTypeIllustration isFullMode={this.props.isFullMode} createTemplate={this.createTemplate} currentChannel={currentChannel} hostName={this.state?.hostName}/>}
|
|
2802
2806
|
{filteredEmptyAndFullModeAs(true) && !isEmpty(templates) && this.state?.hostName && this.whatsappZaloIllustrationText(noFilteredWhatsappZaloTemplatesTitle, noFilteredWhatsappZaloTemplatesDesc)}
|
|
2803
2807
|
{noApprovedWhatsappZaloTemplates && this.whatsappZaloIllustrationText(noApprovedWhatsappZaloTemplatesTitle, showWhatsappIllustration ? noApprovedWhatsappTemplatesDesc : zaloDescIllustration)}
|
|
2804
2808
|
</div>
|
|
@@ -2806,41 +2810,41 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
2806
2810
|
}
|
|
2807
2811
|
{showIllustrationForChannel(RCS_LOWERCASE) &&
|
|
2808
2812
|
<div style={this.isFullMode() ? { height: "calc(100vh - 325px)", overflow: 'auto' } : {}}>
|
|
2809
|
-
<ChannelTypeIllustration isFullMode={this.props.isFullMode} createTemplate={this.createTemplate}
|
|
2813
|
+
<ChannelTypeIllustration isFullMode={this.props.isFullMode} createTemplate={this.createTemplate} currentChannel={currentChannel}/>
|
|
2810
2814
|
{filteredEmptyAndFullModeAs(false) && this.whatsappZaloIllustrationText(noApprovedRcsTemplatesTitle, noApprovedRcsTemplatesDesc)}
|
|
2811
2815
|
</div>
|
|
2812
2816
|
}
|
|
2813
2817
|
{showIllustrationForChannel(INAPP_LOWERCASE) &&
|
|
2814
2818
|
<div className={`${this.isFullMode() ? 'inapp-illustration-parent' : ''}`}>
|
|
2815
|
-
<ChannelTypeIllustration isFullMode={this.props.isFullMode} createTemplate={this.createTemplate}
|
|
2819
|
+
<ChannelTypeIllustration isFullMode={this.props.isFullMode} createTemplate={this.createTemplate} currentChannel={currentChannel} />
|
|
2816
2820
|
</div>
|
|
2817
2821
|
}
|
|
2818
2822
|
|
|
2819
2823
|
{showIllustrationForChannel(VIBER_LOWERCASE) &&
|
|
2820
2824
|
<div className={`${this.isFullMode() ? 'viber-illustration-parent' : ''}`}>
|
|
2821
|
-
<ChannelTypeIllustration isFullMode={this.props.isFullMode} createTemplate={this.createTemplate}
|
|
2825
|
+
<ChannelTypeIllustration isFullMode={this.props.isFullMode} createTemplate={this.createTemplate} currentChannel={currentChannel}/>
|
|
2822
2826
|
</div>
|
|
2823
2827
|
}
|
|
2824
2828
|
{showIllustrationForChannel(FB_LOWERCASE) &&
|
|
2825
2829
|
<div className={`${this.isFullMode() ? 'fb-illustration-parent' : ''}`}>
|
|
2826
|
-
<ChannelTypeIllustration isFullMode={this.props.isFullMode} createTemplate={this.createTemplate}
|
|
2830
|
+
<ChannelTypeIllustration isFullMode={this.props.isFullMode} createTemplate={this.createTemplate} currentChannel={currentChannel}/>
|
|
2827
2831
|
</div>
|
|
2828
2832
|
}
|
|
2829
2833
|
{showIllustrationForChannel(LINE_LOWERCASE) &&
|
|
2830
2834
|
<div className={`${this.isFullMode() ? 'line-illustration-parent' : ''}`}>
|
|
2831
|
-
<ChannelTypeIllustration isFullMode={this.props.isFullMode} createTemplate={this.createTemplate}
|
|
2835
|
+
<ChannelTypeIllustration isFullMode={this.props.isFullMode} createTemplate={this.createTemplate} currentChannel={currentChannel}/>
|
|
2832
2836
|
</div>
|
|
2833
2837
|
}
|
|
2834
2838
|
{showIllustrationForChannel(WEBPUSH_LOWERCASE) &&
|
|
2835
2839
|
<div style={this.isFullMode() ? { height: "calc(100vh - 20.3125rem)", overflow: 'auto' } : {}}>
|
|
2836
|
-
<ChannelTypeIllustration isFullMode={this.props.isFullMode} createTemplate={this.createTemplate}
|
|
2840
|
+
<ChannelTypeIllustration isFullMode={this.props.isFullMode} createTemplate={this.createTemplate} currentChannel={currentChannel} hostName={this.state?.hostName}/>
|
|
2837
2841
|
</div>
|
|
2838
2842
|
}
|
|
2839
2843
|
{get(this.props, 'Templates.isArchivedMode', false) && isEmpty(templates) && !isLoading && !getAllTemplatesInProgress && isEmpty(this.state.searchText) && (
|
|
2840
2844
|
<CapRow className={this.isFullMode() ? 'illustration-scroll-wrapper' : ''}>
|
|
2841
2845
|
<ChannelTypeIllustration
|
|
2842
2846
|
isFullMode={this.props.isFullMode}
|
|
2843
|
-
createTemplate={this.createTemplate}
|
|
2847
|
+
createTemplate={this.createTemplate}
|
|
2844
2848
|
currentChannel={currentChannel}
|
|
2845
2849
|
isArchivedMode
|
|
2846
2850
|
/>
|
|
@@ -3149,36 +3153,7 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
3149
3153
|
}
|
|
3150
3154
|
};
|
|
3151
3155
|
|
|
3152
|
-
canPerform(code) {
|
|
3153
|
-
return hasPermission(getUserAccess(this.props), code);
|
|
3154
|
-
}
|
|
3155
|
-
|
|
3156
|
-
// RBAC: render a dropdown menu item that stays visible but is grayed out,
|
|
3157
|
-
// unclickable, and shows a permission tooltip when the user lacks access
|
|
3158
|
-
// (instead of hiding it, which leaves an empty/no-op 3-dots menu).
|
|
3159
|
-
gatedMenuItem = ({ allowed, className, onClick, label }) => (
|
|
3160
|
-
<CapMenu.Item
|
|
3161
|
-
className={`${className || ''} ${allowed ? '' : 'rbac-disabled'}`.trim()}
|
|
3162
|
-
onClick={() => { if (allowed) onClick(); }}
|
|
3163
|
-
>
|
|
3164
|
-
{allowed ? label : (
|
|
3165
|
-
<CapTooltip title={<FormattedMessage {...globalMessages.noPermissionAction} />}>
|
|
3166
|
-
<span>{label}</span>
|
|
3167
|
-
</CapTooltip>
|
|
3168
|
-
)}
|
|
3169
|
-
</CapMenu.Item>
|
|
3170
|
-
);
|
|
3171
|
-
|
|
3172
|
-
guardWrite(code) {
|
|
3173
|
-
if (this.canPerform(code)) return true;
|
|
3174
|
-
CapNotification.error({
|
|
3175
|
-
message: this.props.intl.formatMessage(globalMessages.noPermissionAction),
|
|
3176
|
-
});
|
|
3177
|
-
return false;
|
|
3178
|
-
}
|
|
3179
|
-
|
|
3180
3156
|
createTemplate(ev) {
|
|
3181
|
-
if (!this.guardWrite(PERMISSIONS.CREATIVE_CREATE)) return;
|
|
3182
3157
|
const type = this.props.location.query.type;
|
|
3183
3158
|
const module = this.props.location.query.module ? this.props.location.query.module : 'default';
|
|
3184
3159
|
const channel = this.state.channel.toLowerCase();
|
|
@@ -3422,7 +3397,6 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
3422
3397
|
}
|
|
3423
3398
|
|
|
3424
3399
|
duplicateTemplate(template) {
|
|
3425
|
-
if (!this.guardWrite(PERMISSIONS.CREATIVE_CREATE)) return;
|
|
3426
3400
|
const duplicateObj = cloneDeep(template);
|
|
3427
3401
|
duplicateObj.name = `${COPY_OF} ${template?.name} ${moment().format('MM-DD-YYYY HH:mm:ss')}`;
|
|
3428
3402
|
delete duplicateObj._id;
|
|
@@ -3529,7 +3503,6 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
3529
3503
|
};
|
|
3530
3504
|
|
|
3531
3505
|
handleEditClick(e, template, modeType, path, options) {
|
|
3532
|
-
if (!this.guardWrite(PERMISSIONS.CREATIVE_EDIT)) return;
|
|
3533
3506
|
if (template && template.isArchived) {
|
|
3534
3507
|
CapNotification.error({ message: this.props.intl.formatMessage(messages.cannotEditArchivedTemplate) });
|
|
3535
3508
|
return;
|
|
@@ -3705,7 +3678,6 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
3705
3678
|
}
|
|
3706
3679
|
|
|
3707
3680
|
toggleDeleteTemplateModal = (template) => {
|
|
3708
|
-
if (!this.guardWrite(PERMISSIONS.CREATIVE_DELETE)) return;
|
|
3709
3681
|
this.setState({actionTemplate: template}, () => {
|
|
3710
3682
|
this.setState({showModal: true});
|
|
3711
3683
|
});
|
|
@@ -3739,7 +3711,6 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
3739
3711
|
}
|
|
3740
3712
|
|
|
3741
3713
|
handleBulkArchiveAction = ({ ids, count, isUnarchive = false }) => {
|
|
3742
|
-
if (!this.guardWrite(PERMISSIONS.CREATIVE_DELETE)) return;
|
|
3743
3714
|
const { intl, actions } = this.props;
|
|
3744
3715
|
const { channel } = this.state;
|
|
3745
3716
|
const title = isUnarchive
|
|
@@ -3759,7 +3730,6 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
3759
3730
|
};
|
|
3760
3731
|
|
|
3761
3732
|
handleTemplateArchiveAction = ({ templateId, templateName, isUnarchive = false }) => {
|
|
3762
|
-
if (!this.guardWrite(PERMISSIONS.CREATIVE_DELETE)) return;
|
|
3763
3733
|
const { intl, actions } = this.props;
|
|
3764
3734
|
const { channel } = this.state;
|
|
3765
3735
|
const title = isUnarchive
|
|
@@ -3992,43 +3962,35 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
3992
3962
|
trigger="click"
|
|
3993
3963
|
content={
|
|
3994
3964
|
<div className="popover-content">
|
|
3995
|
-
|
|
3996
|
-
<
|
|
3997
|
-
|
|
3998
|
-
|
|
3999
|
-
</CapButton>
|
|
4000
|
-
</NoPermissionWrapper>
|
|
3965
|
+
{this.state.channel !== 'wechat' && !template.isArchived && <div className="popover-action-container">
|
|
3966
|
+
<CapButton type="link" onClick={() => this.duplicateTemplate(template)} className="popover-action">
|
|
3967
|
+
{this.props.intl.formatMessage(messages.duplicateButton)}
|
|
3968
|
+
</CapButton>
|
|
4001
3969
|
</div>}
|
|
4002
3970
|
{commonUtil.hasCreativesArchivalEnabled() && this.props.isFullMode && isTemplateArchiveEligible && !template.isArchived && <div className="popover-action-container">
|
|
4003
|
-
<
|
|
4004
|
-
|
|
4005
|
-
|
|
4006
|
-
|
|
4007
|
-
|
|
4008
|
-
|
|
4009
|
-
|
|
4010
|
-
|
|
4011
|
-
</CapButton>
|
|
4012
|
-
</NoPermissionWrapper>
|
|
3971
|
+
<CapButton
|
|
3972
|
+
type="link"
|
|
3973
|
+
onClick={() => this.handleTemplateArchiveAction({ templateId: template._id, templateName: template.name })}
|
|
3974
|
+
className="popover-action popover-archive-action"
|
|
3975
|
+
>
|
|
3976
|
+
<CapIcon type="archive" size="s" />
|
|
3977
|
+
<CapLabel.CapLabelInline type="label1">{this.props.intl.formatMessage(messages.archiveButton)}</CapLabel.CapLabelInline>
|
|
3978
|
+
</CapButton>
|
|
4013
3979
|
</div>}
|
|
4014
3980
|
{commonUtil.hasCreativesArchivalEnabled() && this.props.isFullMode && isTemplateArchiveEligible && template.isArchived && <div className="popover-action-container">
|
|
4015
|
-
<
|
|
4016
|
-
|
|
4017
|
-
|
|
4018
|
-
|
|
4019
|
-
|
|
4020
|
-
|
|
4021
|
-
|
|
4022
|
-
|
|
4023
|
-
</CapButton>
|
|
4024
|
-
</NoPermissionWrapper>
|
|
3981
|
+
<CapButton
|
|
3982
|
+
type="link"
|
|
3983
|
+
onClick={() => this.handleTemplateArchiveAction({ templateId: template._id, templateName: template.name, isUnarchive: true })}
|
|
3984
|
+
className="popover-action popover-archive-action"
|
|
3985
|
+
>
|
|
3986
|
+
<CapIcon type="archive" size="s" />
|
|
3987
|
+
<CapLabel.CapLabelInline type="label1">{this.props.intl.formatMessage(messages.unarchiveButton)}</CapLabel.CapLabelInline>
|
|
3988
|
+
</CapButton>
|
|
4025
3989
|
</div>}
|
|
4026
3990
|
<div className="popover-action-container">
|
|
4027
|
-
<
|
|
4028
|
-
|
|
4029
|
-
|
|
4030
|
-
</CapButton>
|
|
4031
|
-
</NoPermissionWrapper>
|
|
3991
|
+
<CapButton type="link" onClick={() => this.toggleDeleteTemplateModal(template)} className="popover-action">
|
|
3992
|
+
{deleteOption}
|
|
3993
|
+
</CapButton>
|
|
4032
3994
|
</div>
|
|
4033
3995
|
</div>
|
|
4034
3996
|
}
|
|
@@ -4630,26 +4592,23 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
4630
4592
|
&& !this.props.isFullMode
|
|
4631
4593
|
)
|
|
4632
4594
|
? (
|
|
4633
|
-
<
|
|
4634
|
-
|
|
4635
|
-
|
|
4636
|
-
|
|
4637
|
-
|
|
4638
|
-
|
|
4639
|
-
/>
|
|
4640
|
-
</NoPermissionWrapper>
|
|
4595
|
+
<CapLink
|
|
4596
|
+
onClick={this.openCreativesFullMode}
|
|
4597
|
+
title={formatMessage(messages.createNewTemplateLink)}
|
|
4598
|
+
suffix={<CapIcon type="open-in-new" size="s" />}
|
|
4599
|
+
className="create-new-link"
|
|
4600
|
+
/>
|
|
4641
4601
|
)
|
|
4642
4602
|
: this.state?.channel?.toLowerCase() === ZALO_LOWERCASE || (channelLowerCase === WHATSAPP_LOWERCASE && isEmpty(this.state?.hostName)) ? <></> : (
|
|
4643
|
-
<
|
|
4644
|
-
|
|
4645
|
-
|
|
4646
|
-
|
|
4647
|
-
|
|
4648
|
-
|
|
4649
|
-
|
|
4650
|
-
|
|
4651
|
-
|
|
4652
|
-
</NoPermissionWrapper>
|
|
4603
|
+
<CapButton
|
|
4604
|
+
className={`create-new-${channelLowerCase} margin-l-8 margin-b-12`}
|
|
4605
|
+
type={"primary"}
|
|
4606
|
+
isAddBtn
|
|
4607
|
+
disabled={this.isCreateDisabled()}
|
|
4608
|
+
onClick={this.createTemplate}
|
|
4609
|
+
>
|
|
4610
|
+
{ this.props.intl.formatMessage((isTraiDltFeature && channel.toUpperCase() === SMS ) ? messages.uploadTemplate : messages.createNewActionButton) }
|
|
4611
|
+
</CapButton>
|
|
4653
4612
|
);
|
|
4654
4613
|
|
|
4655
4614
|
const isWhatsappCountExeeded = templatesCount >= MAX_WHATSAPP_TEMPLATES;
|
|
@@ -3,13 +3,6 @@ jest.mock('@capillarytech/cap-ui-library', () => ({
|
|
|
3
3
|
CapIllustration: ({ children, ...props }) => <div data-testid="cap-illustration" {...props}>{children}</div>
|
|
4
4
|
}));
|
|
5
5
|
|
|
6
|
-
// The component uses useIntl() (context); this shallow test supplies intl via props, so
|
|
7
|
-
// stub useIntl. FormattedMessage stays real.
|
|
8
|
-
jest.mock('react-intl', () => ({
|
|
9
|
-
...jest.requireActual('react-intl'),
|
|
10
|
-
useIntl: () => ({ formatMessage: m => (m && m.defaultMessage) || '' }),
|
|
11
|
-
}));
|
|
12
|
-
|
|
13
6
|
// Mock all image imports
|
|
14
7
|
jest.mock('../../Assets/images/emailIllustration.svg', () => 'test-file-stub');
|
|
15
8
|
jest.mock('../../Assets/images/smsIllustration.svg', () => 'test-file-stub');
|