@capillarytech/creatives-library 7.17.81 → 7.17.82-alpha.1

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 (38) hide show
  1. package/containers/Cap/sagas.js +7 -5
  2. package/containers/Cap/tests/saga.test.js +81 -1
  3. package/package.json +3 -2
  4. package/services/api.js +5 -0
  5. package/services/tests/api.test.js +9 -1
  6. package/v2Components/CapWhatsappQuickReply/index.js +243 -0
  7. package/v2Components/CapWhatsappQuickReply/index.scss +43 -0
  8. package/v2Components/CapWhatsappQuickReply/messages.js +24 -0
  9. package/v2Components/TemplatePreview/_templatePreview.scss +23 -0
  10. package/v2Components/TemplatePreview/index.js +51 -1
  11. package/v2Components/TemplatePreview/messages.js +4 -0
  12. package/v2Components/TemplatePreview/tests/__snapshots__/index.test.js.snap +0 -14
  13. package/v2Containers/CreativesContainer/index.js +22 -2
  14. package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxContent.test.js.snap +2 -0
  15. package/v2Containers/Templates/index.js +5 -2
  16. package/v2Containers/Templates/tests/__snapshots__/index.test.js.snap +6 -0
  17. package/v2Containers/Whatsapp/actions.js +16 -0
  18. package/v2Containers/Whatsapp/constants.js +22 -0
  19. package/v2Containers/Whatsapp/index.js +699 -187
  20. package/v2Containers/Whatsapp/index.scss +55 -1
  21. package/v2Containers/Whatsapp/messages.js +37 -0
  22. package/v2Containers/Whatsapp/reducer.js +19 -0
  23. package/v2Containers/Whatsapp/sagas.js +40 -1
  24. package/v2Containers/Whatsapp/styles.scss +29 -0
  25. package/v2Containers/Whatsapp/tests/__snapshots__/index.test.js.snap +40962 -24255
  26. package/v2Containers/Whatsapp/tests/__snapshots__/utils.test.js.snap +12 -0
  27. package/v2Containers/Whatsapp/tests/actions.test.js +21 -0
  28. package/v2Containers/Whatsapp/tests/index.test.js +8 -0
  29. package/v2Containers/Whatsapp/tests/mockData.js +6 -0
  30. package/v2Containers/Whatsapp/tests/reducer.test.js +67 -0
  31. package/v2Containers/Whatsapp/tests/saga.test.js +90 -0
  32. package/v2Containers/Whatsapp/tests/utils.test.js +11 -0
  33. package/v2Containers/Whatsapp/utils.js +45 -3
  34. package/v2Containers/mockdata.js +105 -4
  35. package/v2Containers/InApp/constants.js +0 -0
  36. package/v2Containers/InApp/index.js +0 -499
  37. package/v2Containers/InApp/index.scss +0 -0
  38. package/v2Containers/InApp/messages.js +0 -0
@@ -1,4 +1,5 @@
1
1
  import { fork, take, call, put, cancelled, cancel, takeLatest } from 'redux-saga/effects';
2
+ import { getRedirectionUrl } from '@capillarytech/cap-ui-utils/utils/logoutUtil';
2
3
  import { LOCATION_CHANGE } from 'react-router-redux';
3
4
  // import { normalize } from 'normalizr';
4
5
  import * as Api from '../../services/api';
@@ -51,18 +52,19 @@ export function* loginFlow() {
51
52
  }
52
53
  }
53
54
 
54
- function* logoutFlow() {
55
+ export function* logoutFlow() {
55
56
  try {
56
57
  const serverLogout = yield call(Api.logout);
57
58
  if (serverLogout.success && serverLogout.success === true) {
58
- const loginUrl = (process.env.NODE_ENV === 'production') ?
59
- `${config.production.login_url}` : `${config.development.login_url}`;
59
+ const redirectUrl = getRedirectionUrl({
60
+ redirectUri: serverLogout?.redirectUri,
61
+ });
60
62
  yield [put({type: types.LOGOUT_SUCCESS})];
61
63
  yield call(LocalStorage.clearItem, 'token');
62
64
  yield call(LocalStorage.clearItem, 'orgID');
63
65
  yield call(LocalStorage.clearItem, 'user');
64
66
  yield call(LocalStorage.clearItem, 'isLoggedIn');
65
- window.location.href = `${window.location.origin}${loginUrl}`;
67
+ window.location.href = redirectUrl;
66
68
  }
67
69
  } catch (error) {
68
70
  yield put({ type: types.LOGOUT_FAILURE, error });
@@ -128,7 +130,7 @@ function* watchForOrgChange() {
128
130
  yield takeLatest(types.SWITCH_ORG_REQUEST, switchOrg);
129
131
  }
130
132
 
131
- function* watchForLogoutFlow() {
133
+ export function* watchForLogoutFlow() {
132
134
  yield takeLatest(types.LOGOUT_REQUEST, logoutFlow);
133
135
  }
134
136
 
@@ -1,10 +1,18 @@
1
+ import { expectSaga } from 'redux-saga-test-plan';
2
+ import { throwError } from 'redux-saga-test-plan/providers';
3
+ import * as matchers from 'redux-saga-test-plan/matchers';
1
4
  import { authorize, loginFlow } from '../sagas';
2
- import { take, fork, cancel } from 'redux-saga/effects';
5
+ import * as api from '../../../services/api';
6
+ import { take, fork, cancel, takeLatest } from 'redux-saga/effects';
3
7
  import {
4
8
  LOGIN_REQUEST,
5
9
  LOGIN_FAILURE,
6
10
  LOGOUT_REQUEST,
11
+ LOGOUT_SUCCESS,
12
+ LOGOUT_FAILURE,
7
13
  } from '../constants';
14
+ import {logoutFlow, watchForLogoutFlow } from '../sagas';
15
+ const error = new Error('error');
8
16
  describe('loginFlow', () => {
9
17
  it('should handle the login flow', () => {
10
18
  const generator = loginFlow();
@@ -28,4 +36,76 @@ describe('loginFlow', () => {
28
36
  }
29
37
  catch{}
30
38
  });
39
+ });
40
+ describe('logoutFlow [Unit Test]', () => {
41
+ describe('logoutFlow saga', () => {
42
+ it('handle valid response from api', async () => {
43
+ expectSaga(logoutFlow)
44
+ .provide([
45
+ [
46
+ matchers.call.fn(api.logout),
47
+ {
48
+ success: true,
49
+ message: 'message',
50
+ },
51
+ ],
52
+ ])
53
+ .put({
54
+ type: LOGOUT_SUCCESS,
55
+ result: 'message',
56
+ })
57
+ .run();
58
+ });
59
+
60
+ it('handle invalid response from api', async () => {
61
+ expectSaga(logoutFlow)
62
+ .provide([
63
+ [
64
+ matchers.call.fn(api.logout),
65
+ {
66
+ success: false,
67
+ message: 'message',
68
+ },
69
+ ],
70
+ ])
71
+ .run();
72
+ });
73
+
74
+ it('handle error response from api', async () => {
75
+ expectSaga(logoutFlow)
76
+ .provide([
77
+ [
78
+ matchers.call.fn(api.logout),
79
+ {
80
+ success: false,
81
+ error,
82
+ },
83
+ ],
84
+ ])
85
+ .put({
86
+ type: LOGOUT_FAILURE,
87
+ error,
88
+ })
89
+ .run();
90
+ });
91
+
92
+ it('handles error thrown from api', async () => {
93
+ expectSaga(logoutFlow)
94
+ .provide([[matchers.call.fn(api.logout), throwError(error)]])
95
+ .put({
96
+ type: LOGOUT_FAILURE,
97
+ error,
98
+ })
99
+ .run();
100
+ });
101
+ });
102
+
103
+ describe('watchForLogoutFlow saga', () => {
104
+ const generator = watchForLogoutFlow();
105
+ it('should call watchers functions', async () => {
106
+ expect(generator.next().value).toEqual(
107
+ takeLatest(LOGOUT_REQUEST, logoutFlow),
108
+ );
109
+ });
110
+ });
31
111
  });
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@capillarytech/creatives-library",
3
3
  "author": "meharaj",
4
- "version": "7.17.81",
4
+ "version": "7.17.82-alpha.1",
5
5
  "description": "Capillary creatives ui",
6
6
  "main": "./index.js",
7
7
  "module": "./index.es.js",
@@ -15,7 +15,7 @@
15
15
  "@babel/polyfill": "7.4.3",
16
16
  "@bugsnag/js": "^7.2.1",
17
17
  "@bugsnag/plugin-react": "^7.2.1",
18
- "@capillarytech/cap-ui-utils": "1.4.2",
18
+ "@capillarytech/cap-ui-utils": "1.4.24",
19
19
  "@mailupinc/bee-plugin": "^1.2.0",
20
20
  "babel-cli": "^6.26.0",
21
21
  "chalk": "1.1.3",
@@ -25,6 +25,7 @@
25
25
  "jest-date-mock": "^1.0.8",
26
26
  "jquery": "^3.3.1",
27
27
  "load-script": "^1.0.0",
28
+ "ml-matrix": "6.10.8",
28
29
  "node-html-parser": "^5.4.2-0",
29
30
  "normalizr": "^3.2.3",
30
31
  "papaparse": "^5.3.1",
package/services/api.js CHANGED
@@ -504,3 +504,8 @@ export const getTemplateInfoById = ({id, username, oa_id, token}) => {
504
504
  const url = `${API_ENDPOINT}/templates/${id}/Zalo?username=${username}&oa_id=${oa_id}&token=${token}`;
505
505
  return request(url, getAPICallObject('GET'));
506
506
  };
507
+
508
+ export const getMetaTags = ({previewUrl}) => {
509
+ const url = `${API_ENDPOINT}/common/getMetaTags?url=${previewUrl}`;
510
+ return request(url, getAPICallObject('GET'));
511
+ };
@@ -2,7 +2,8 @@ import {
2
2
  getSenderDetails,
3
3
  uploadFile,
4
4
  getCdnTransformationConfig,
5
- createWhatsappTemplate
5
+ createWhatsappTemplate,
6
+ getMetaTags,
6
7
  } from '../api';
7
8
  import { mockData } from './mockData';
8
9
  const sampleFile = require('../../assets/line.png');
@@ -44,3 +45,10 @@ describe('createWhatsappTemplate -- Test with valid responses', () => {
44
45
  createWhatsappTemplate(sampleFile, mockData.createWhatsappPayload),
45
46
  ).toEqual(Promise.resolve()));
46
47
  });
48
+
49
+ describe('getMetaTags -- Test with valid responses', () => {
50
+ it('Should return correct response', () =>
51
+ expect(
52
+ getMetaTags({previewUrl: 'https://capillarytech.com'}),
53
+ ).toEqual(Promise.resolve()));
54
+ });
@@ -0,0 +1,243 @@
1
+ import React from "react";
2
+ import PropTypes from 'prop-types';
3
+ import { injectIntl, intlShape } from "react-intl";
4
+ import cloneDeep from "lodash/cloneDeep";
5
+ import CapRow from "@capillarytech/cap-ui-library/CapRow";
6
+ import CapHeader from "@capillarytech/cap-ui-library/CapHeader";
7
+ import CapHeading from "@capillarytech/cap-ui-library/CapHeading";
8
+ import CapTooltipWithInfo from "@capillarytech/cap-ui-library/CapTooltipWithInfo";
9
+ import CapInput from "@capillarytech/cap-ui-library/CapInput";
10
+ import CapError from "@capillarytech/cap-ui-library/CapError";
11
+ import CapTooltip from "@capillarytech/cap-ui-library/CapTooltip";
12
+ import CapButton from "@capillarytech/cap-ui-library/CapButton";
13
+ import CapColumn from "@capillarytech/cap-ui-library/CapColumn";
14
+ import CapIcon from "@capillarytech/cap-ui-library/CapIcon";
15
+ import CapLabel from "@capillarytech/cap-ui-library/CapLabel";
16
+ import messages from "./messages";
17
+ import "./index.scss";
18
+ import globalMessages from "../../v2Containers/Cap/messages";
19
+ import { BUTTON_TEXT, INITIAL_QUICK_REPLY_DATA } from "../../v2Containers/Whatsapp/constants";
20
+ import ctaMessages from "../CapWhatsappCTA/messages";
21
+
22
+ export const CapWhatsappQuickReply = (props) => {
23
+ const { quickReplyData = [], renderMessageLength, setQuickReplyData, isEditFlow, intl } = props;
24
+ const { TextArea } = CapInput;
25
+ const { formatMessage } = intl;
26
+ const quickReplyDataLength = quickReplyData?.length;
27
+ //this function is used for handle text field value change
28
+ const handleTextChange = ({target: {value = ''} = {}}, index) => {
29
+ let error = false;
30
+ if (value?.length > 20) {
31
+ error = formatMessage(messages.templateButtonTextLengthError);
32
+ }
33
+ //this check is for same repeated value is not allowed in another text field of quick reply
34
+ const checkIsValueAvailable = quickReplyData?.find((reply) => reply?.text === value);
35
+ if (checkIsValueAvailable) {
36
+ error = formatMessage(messages.templateButtonTextSameValue);
37
+ }
38
+ setQuickReplyData(
39
+ quickReplyData?.map((quickReply) => {
40
+ if (quickReply?.index === index) {
41
+ return {
42
+ ...quickReply,
43
+ text: value,
44
+ error,
45
+ };
46
+ }
47
+ return quickReply;
48
+ })
49
+ );
50
+ };
51
+
52
+ //this function is used for save the quick reply text field data and same edit the data
53
+ const handleSaveAndEditBtn = (index, value) => {
54
+ setQuickReplyData(
55
+ quickReplyData.map((quickReply) => {
56
+ if (quickReply?.index === index) {
57
+ return {
58
+ ...quickReply,
59
+ isSaved: value,
60
+ };
61
+ }
62
+ return quickReply;
63
+ })
64
+ );
65
+ };
66
+
67
+ //This function is used for delete the quick reply data for a row
68
+ const handleDelete = (index) => {
69
+ setQuickReplyData((prevState) => {
70
+ const clonedQuickReplyData = cloneDeep(prevState);
71
+ const filteredQuickReplyData = clonedQuickReplyData.filter(
72
+ (i) => i?.index !== index
73
+ );
74
+ return filteredQuickReplyData.map((quickReply, i) => ({
75
+ ...quickReply,
76
+ index: i,
77
+ }));
78
+ });
79
+ };
80
+
81
+ const addQuickReply = () => {
82
+ INITIAL_QUICK_REPLY_DATA[0].index = quickReplyDataLength || 0;
83
+ const clonedQuickReplyData = [
84
+ ...quickReplyData,
85
+ ...INITIAL_QUICK_REPLY_DATA,
86
+ ];
87
+ setQuickReplyData(clonedQuickReplyData);
88
+ };
89
+
90
+ const isQuickReplyDisable =
91
+ quickReplyDataLength === 1 && !quickReplyData?.[0]?.isSaved;
92
+ return (
93
+ <>
94
+ {quickReplyDataLength > 0 && !isEditFlow && (
95
+ <CapRow>
96
+ {quickReplyData?.map(({ index, isSaved, text, error }) => {
97
+ if (!isSaved) {
98
+ //this section is render textfield when its not saved or in edit condition
99
+ return (
100
+ <CapRow className="cap-whatsapp-quick-reply">
101
+ <CapRow
102
+ className="whatsapp-button-text-container"
103
+ key={index}
104
+ >
105
+ <CapHeader
106
+ title={
107
+ <CapHeading
108
+ type="h4"
109
+ className="whatsapp-button-text-heading"
110
+ >
111
+ {formatMessage(messages.buttonText)}
112
+ <CapTooltipWithInfo
113
+ placement="right"
114
+ className="whatsapp-button-text-tooltip"
115
+ autoAdjustOverflow
116
+ />
117
+ </CapHeading>
118
+ }
119
+ />
120
+ <CapRow className="whatsapp-button-text-input">
121
+ <TextArea
122
+ autosize={{ minRows: 1, maxRows: 5 }}
123
+ placeholder={formatMessage(
124
+ messages.buttonTextPlaceholder
125
+ )}
126
+ onChange={(e) => handleTextChange(e, index)}
127
+ errorMessage={
128
+ error && (
129
+ <CapError className="whatsapp-template-message-error">
130
+ {error}
131
+ </CapError>
132
+ )
133
+ }
134
+ value={text || ""}
135
+ />
136
+ </CapRow>
137
+ {renderMessageLength(BUTTON_TEXT, text?.length || 0)}
138
+ {/* it render save and delete button */}
139
+ <CapRow className="whatsapp-cta-save-delete-btn">
140
+ <CapTooltip
141
+ title={
142
+ (text === "" || error)
143
+ && formatMessage(ctaMessages.ctaSaveDisabled)
144
+ }
145
+ placement={"bottom"}
146
+ >
147
+ <div className="button-disabled-tooltip-wrapper">
148
+ <CapButton
149
+ onClick={() => {
150
+ handleSaveAndEditBtn(index, true);
151
+ }}
152
+ disabled={text === "" || error}
153
+ className="whatsapp-cta-save-btn"
154
+ >
155
+ {formatMessage(globalMessages.save)}
156
+ </CapButton>
157
+ </div>
158
+ </CapTooltip>
159
+ <CapButton
160
+ onClick={() => {
161
+ handleDelete(index);
162
+ }}
163
+ className="whatsapp-cta-delete-btn whatsapp-quick-reply-delete-button"
164
+ type="secondary"
165
+ >
166
+ {formatMessage(globalMessages.delete)}
167
+ </CapButton>
168
+ </CapRow>
169
+ </CapRow>
170
+ </CapRow>
171
+ );
172
+ }
173
+ return (
174
+ //this section render when data is saved and user can edit it
175
+ <CapRow className="cap-whatsapp-quick-reply">
176
+ <CapRow className="whatsapp-quick-reply-save-container">
177
+ <CapColumn>
178
+ <CapIcon type="six-dots" />
179
+ </CapColumn>
180
+ <CapColumn className="text-conatiner">{text}</CapColumn>
181
+ <CapColumn className="quick-reply-icon">
182
+ <CapIcon
183
+ onClick={() => handleSaveAndEditBtn(index, false)}
184
+ type="edit"
185
+ data-testid="quick-reply-edit"
186
+ />
187
+ <CapIcon
188
+ onClick={() => handleDelete(index)}
189
+ type="delete"
190
+ data-testid="quick-reply-delete"
191
+ />
192
+ </CapColumn>
193
+ </CapRow>
194
+ </CapRow>
195
+ );
196
+ })}
197
+ </CapRow>
198
+ )}
199
+ {/* this section render in edit mode from campaign side */}
200
+ {quickReplyDataLength > 0 && isEditFlow &&
201
+ quickReplyData.map(({text, index}) => (
202
+ <CapRow className="cap-whatsapp-quick-reply whatsapp-quick-reply-edit-container" key={index}>
203
+ <CapLabel type="label16">{text}</CapLabel>
204
+ </CapRow>
205
+ ))
206
+ }
207
+ {/* this section render add button section with condition */}
208
+ {quickReplyDataLength < 3 && !isEditFlow && (
209
+ <CapRow>
210
+ <CapTooltip
211
+ title={
212
+ isQuickReplyDisable ? formatMessage(ctaMessages.ctaAddDisabled) : ""
213
+ }
214
+ placement={"right"}
215
+ >
216
+ <div className="button-disabled-tooltip-wrapper">
217
+ <CapButton
218
+ type="flat"
219
+ id="whatsapp-quick-reply-add-button"
220
+ disabled={isQuickReplyDisable}
221
+ className="margin-t-12 margin-l-24"
222
+ isAddBtn
223
+ onClick={addQuickReply}
224
+ >
225
+ {formatMessage(ctaMessages.addButton)}
226
+ </CapButton>
227
+ </div>
228
+ </CapTooltip>
229
+ </CapRow>
230
+ )}
231
+ </>
232
+ );
233
+ };
234
+
235
+ CapWhatsappQuickReply.propTypes = {
236
+ quickReplyData: PropTypes.array,
237
+ renderMessageLength: PropTypes.func,
238
+ setQuickReplyData: PropTypes.func,
239
+ isEditFlow: PropTypes.func,
240
+ intl: intlShape.isRequired,
241
+ };
242
+
243
+ export default injectIntl(CapWhatsappQuickReply);
@@ -0,0 +1,43 @@
1
+ @import "~@capillarytech/cap-ui-library/styles/_variables";
2
+
3
+ .cap-whatsapp-quick-reply {
4
+ border: solid 0.063rem $CAP_G06;
5
+ margin-left: $CAP_SPACE_24;
6
+ margin-top: $CAP_SPACE_24;
7
+ border-radius: 0.285rem;
8
+ .whatsapp-button-text-container {
9
+ padding: $CAP_SPACE_16 $CAP_SPACE_24;
10
+ }
11
+ .whatsapp-button-text-heading {
12
+ display: flex;
13
+ text-align: center;
14
+ }
15
+ .whatsapp-quick-reply-delete-button {
16
+ margin-left: $CAP_SPACE_12;
17
+ }
18
+ .whatsapp-button-text-input {
19
+ margin-top: $CAP_SPACE_08;
20
+ margin-bottom: $CAP_SPACE_12;
21
+ }
22
+ .whatsapp-quick-reply-save-container {
23
+ display: flex;
24
+ align-items: center;
25
+ padding: $CAP_SPACE_08 $CAP_SPACE_12;
26
+ .text-conatiner {
27
+ padding-left: $CAP_SPACE_12;
28
+ }
29
+ .quick-reply-icon {
30
+ position: absolute;
31
+ right: $CAP_SPACE_12;
32
+ }
33
+ }
34
+ .whatsapp-button-text-tooltip {
35
+ margin-left: $CAP_SPACE_04;
36
+ }
37
+ }
38
+
39
+ .whatsapp-quick-reply-edit-container {
40
+ padding: $CAP_SPACE_12;
41
+ margin-left: 0;
42
+ margin-top: $CAP_SPACE_16;
43
+ }
@@ -0,0 +1,24 @@
1
+ import { defineMessages } from 'react-intl';
2
+ const prefix = `creatives.componentsV2.CapWhatsappQuickReply`;
3
+ export default defineMessages({
4
+ buttonText: {
5
+ id: `${prefix}.buttonText`,
6
+ defaultMessage: 'Button text',
7
+ },
8
+ buttonTextPlaceholder: {
9
+ id: `${prefix}.buttonTextPlaceholder`,
10
+ defaultMessage: 'Enter button text',
11
+ },
12
+ templateButtonTextError: {
13
+ id: `${prefix}.templateButtonTextError`,
14
+ defaultMessage: 'Template footer length cannot exceed 20',
15
+ },
16
+ templateButtonTextLengthError: {
17
+ id: `${prefix}.templateButtonTextLengthError`,
18
+ defaultMessage: 'Text field length cannot exceed 20',
19
+ },
20
+ templateButtonTextSameValue: {
21
+ id: `${prefix}.templateButtonTextSameValue`,
22
+ defaultMessage: 'Text field value cannot be same with other text fields',
23
+ },
24
+ });
@@ -276,6 +276,9 @@
276
276
  align-content: center;
277
277
  justify-content: center;
278
278
  margin-bottom: 4px;
279
+ svg {
280
+ margin-right: $CAP_SPACE_04;
281
+ }
279
282
  }
280
283
  .whatsapp-message-container{
281
284
  max-height: 292px;
@@ -517,4 +520,24 @@
517
520
  .zalo-preview-container-campaign {
518
521
  padding-left: 0px;
519
522
  padding-right: 4.563rem;
523
+ }
524
+
525
+ .url-preview-image {
526
+ width: 100%;
527
+ height: 100%;
528
+ background-color: hsl(0, 0%, 90%);
529
+ }
530
+
531
+ .url-preview-description {
532
+ font-size: 0.6rem;
533
+ font-weight: $FONT_WEIGHT_REGULAR;
534
+ color: $FONT_COLOR_01;
535
+ margin: 0.13rem 0;
536
+ }
537
+
538
+ .url-preview {
539
+ font-size: 0.5rem;
540
+ font-weight: $FONT_WEIGHT_REGULAR;
541
+ color: $FONT_COLOR_02;
542
+ margin-bottom: $CAP_SPACE_08;
520
543
  }
@@ -11,6 +11,7 @@ import _ from 'lodash';
11
11
  import { injectIntl, FormattedMessage, intlShape } from 'react-intl';
12
12
  // import styled from 'styled-components';
13
13
  import { CapColumn, CapRow, CapHeading, CapIcon, CapButton, CapImage, CapLabel, CapDivider, CapTooltip } from '@capillarytech/cap-ui-library';
14
+ import { isEmpty } from 'lodash';
14
15
  import './_templatePreview.scss';
15
16
  import {updateCharCount} from '../../utils/smsCharCountV2';
16
17
  import messages from './messages';
@@ -53,6 +54,8 @@ import {
53
54
  import { TEMPLATE, IMAGE_CAROUSEL, IMAGE, STICKER, TEXT, IMAGE_MAP, VIDEO } from '../../v2Containers/Line/Container/constants';
54
55
  import CapFacebookPreview from '../../v2Containers/CapFacebookPreview';
55
56
  import WhatsappStatusContainer from '../WhatsappStatusContainer';
57
+ import { getWhatsappQuickReply } from '../../v2Containers/Whatsapp/utils';
58
+ import { QUICK_REPLY } from '../../v2Containers/Whatsapp/constants';
56
59
 
57
60
  export class TemplatePreview extends React.Component { // eslint-disable-line react/prefer-stateless-function
58
61
  onPreviewContentClicked = (channel) => {
@@ -319,7 +322,6 @@ export class TemplatePreview extends React.Component { // eslint-disable-line re
319
322
  (ctaType || type) === 'PHONE_NUMBER' ? 'call' : 'launch'
320
323
  }
321
324
  size="xs"
322
- svgProps={{ style: { marginRight: '4px' } }}
323
325
  />
324
326
  {text}
325
327
  </CapLabel>,
@@ -330,6 +332,48 @@ export class TemplatePreview extends React.Component { // eslint-disable-line re
330
332
  return renderArray;
331
333
  };
332
334
 
335
+ const renderQuickReplyPreview = () => {
336
+ const { quickReplyData = [] } = content || {};
337
+ return getWhatsappQuickReply(
338
+ {
339
+ buttons: quickReplyData,
340
+ buttonType: QUICK_REPLY,
341
+ },
342
+ true
343
+ );
344
+ };
345
+
346
+ const renderUrlPreview = (metaTags) => {
347
+ const renderArray = [];
348
+ if (!isEmpty(metaTags)) {
349
+ if (metaTags?.image) {
350
+ renderArray.push(
351
+ <CapImage
352
+ src={metaTags?.image}
353
+ alt={formatMessage(messages.previewUrlMetaImage)}
354
+ className="url-preview-image"
355
+ />
356
+ );
357
+ }
358
+ if (metaTags?.title) {
359
+ renderArray.push(
360
+ <CapLabel type="label8">{metaTags?.title}</CapLabel>
361
+ );
362
+ }
363
+ if (metaTags?.description) {
364
+ renderArray.push(
365
+ <CapLabel className="url-preview-description">{metaTags?.description}</CapLabel>
366
+ );
367
+ }
368
+ if (metaTags?.url) {
369
+ renderArray.push(
370
+ <CapLabel className="url-preview">{metaTags?.url}</CapLabel>
371
+ );
372
+ }
373
+ }
374
+ return renderArray;
375
+ };
376
+
333
377
  const handlePreview = () => {
334
378
  const {templatePreviewUrl = ''} = templateData;
335
379
  handlePreviewInNewTab(templatePreviewUrl);
@@ -744,6 +788,9 @@ export class TemplatePreview extends React.Component { // eslint-disable-line re
744
788
  <div className="msg-container whatsapp-message-container">
745
789
  <div className="message-pop align-left" style={whatsappSectionStyle}>
746
790
  <div className="whatsapp-content">
791
+ {content?.isPreviewUrl && (
792
+ renderUrlPreview(content?.metaTagsDetails)
793
+ )}
747
794
  {content?.whatsappImageSrc && (
748
795
  <CapImage
749
796
  src={content.whatsappImageSrc}
@@ -772,8 +819,11 @@ export class TemplatePreview extends React.Component { // eslint-disable-line re
772
819
  {content?.docPreview}
773
820
  </div>
774
821
  )}
822
+ {content?.templateHeaderPreview || ''}
775
823
  {content?.templateMsg || ''}
824
+ {content?.templateFooterPreview || ''}
776
825
  {renderWhatsappCtaPreview()}
826
+ {renderQuickReplyPreview()}
777
827
  </div>
778
828
  </div>
779
829
  </div>
@@ -82,4 +82,8 @@ export default defineMessages({
82
82
  id: 'creatives.componentsV2.TemplatePreview.videoPreviewTooltip',
83
83
  defaultMessage: "This is just for preview purposes, video cannot be played here",
84
84
  },
85
+ previewUrlMetaImage: {
86
+ id: 'creatives.componentsV2.TemplatePreview.previewUrlMetaImage',
87
+ defaultMessage: 'Preview url meta image',
88
+ },
85
89
  });
@@ -98,13 +98,6 @@ exports[`Test Templates container Should render correct preview component for wh
98
98
  >
99
99
  <CapIcon
100
100
  size="xs"
101
- svgProps={
102
- Object {
103
- "style": Object {
104
- "marginRight": "4px",
105
- },
106
- }
107
- }
108
101
  type="call"
109
102
  />
110
103
  Call
@@ -115,13 +108,6 @@ exports[`Test Templates container Should render correct preview component for wh
115
108
  >
116
109
  <CapIcon
117
110
  size="xs"
118
- svgProps={
119
- Object {
120
- "style": Object {
121
- "marginRight": "4px",
122
- },
123
- }
124
- }
125
111
  type="launch"
126
112
  />
127
113
  Visit