@capillarytech/creatives-library 7.14.39 → 7.14.41
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/i18n.js +4 -6
- package/package.json +1 -1
- package/reducers.js +2 -0
- package/services/api.js +9 -1
- package/tests/integration/TemplateCreation/TemplateCreation.integration.test.js +420 -0
- package/tests/integration/TemplateCreation/api-response.js +1663 -0
- package/tests/integration/TemplateCreation/helper.js +23 -0
- package/tests/integration/TemplateCreation/mocks/initialState.js +428 -0
- package/tests/integration/TemplateCreation/msw-handler.js +48 -0
- package/v2Components/CapActionButton/index.js +1 -0
- package/v2Components/FormBuilder/index.js +28 -4
- package/v2Containers/Assets/Gallery/index.js +1 -1
- package/v2Containers/CreativesContainer/constants.js +2 -0
- package/v2Containers/CreativesContainer/selectors.js +2 -2
- package/v2Containers/CreativesContainer/tests/__snapshots__/index.test.js.snap +8 -0
- package/v2Containers/Line/Container/ImageCarousel/tests/__snapshots__/content.test.js.snap +3 -0
- package/v2Containers/Line/Container/Text/index.js +3 -2
- package/v2Containers/Line/Container/Wrapper/tests/__snapshots__/index.test.js.snap +4 -0
- package/v2Containers/Line/Container/index.js +1 -1
- package/v2Containers/Rcs/index.js +3 -0
- package/v2Containers/Rcs/tests/__snapshots__/index.test.js.snap +250 -3
- package/v2Containers/Sms/Create/actions.js +9 -0
- package/v2Containers/Sms/Create/constants.js +2 -0
- package/v2Containers/Sms/Create/index.js +12 -0
- package/v2Containers/Sms/Create/sagas.js +19 -3
- package/v2Containers/Sms/Create/tests/sagas.test.js +82 -0
- package/v2Containers/Templates/index.js +26 -11
- package/v2Containers/Templates/tests/__snapshots__/index.test.js.snap +96 -80
- package/v2Containers/TemplatesV2/index.js +1 -1
- package/v2Containers/Viber/index.js +1 -0
- package/v2Containers/Whatsapp/constants.js +27 -8
- package/v2Containers/Whatsapp/index.js +14 -2
- package/v2Containers/Whatsapp/messages.js +21 -4
- package/v2Containers/Whatsapp/styles.scss +3 -0
- package/v2Containers/Whatsapp/tests/__snapshots__/index.test.js.snap +180 -128
- package/v2Containers/Whatsapp/tests/utils.test.js +1 -1
- package/v2Containers/Whatsapp/utils.js +2 -1
- package/v2Containers/mockdata.js +5 -5
|
@@ -25,3 +25,12 @@ export function defaultAction() {
|
|
|
25
25
|
type: types.DEFAULT_ACTION,
|
|
26
26
|
};
|
|
27
27
|
}
|
|
28
|
+
|
|
29
|
+
export function getAiSuggestions(prompt, successCallback, failureCallback) {
|
|
30
|
+
return {
|
|
31
|
+
type: types.GET_AI_SUGGESTIONS,
|
|
32
|
+
prompt,
|
|
33
|
+
successCallback,
|
|
34
|
+
failureCallback,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
@@ -14,3 +14,5 @@ export const CREATE_TEMPLATE_FAILURE = 'app/v2Containers/Sms/Create/CREATE_TEMPL
|
|
|
14
14
|
export const CLEAR_CREATE_RESPONSE_REQUEST = 'app/v2Containers/Sms/Create/CLEAR_CREATE_RESPONSE_REQUEST';
|
|
15
15
|
export const CLEAR_CREATE_RESPONSE_SUCCESS = 'app/v2Containers/Sms/Create/CLEAR_CREATE_RESPONSE_SUCCESS';
|
|
16
16
|
export const CLEAR_CREATE_RESPONSE_FAILURE = 'app/v2Containers/Sms/Create/CLEAR_CREATE_RESPONSE_FAILURE';
|
|
17
|
+
|
|
18
|
+
export const GET_AI_SUGGESTIONS = 'app/v2Containers/Sms/Create/GET_AI_SUGGESTIONS';
|
|
@@ -900,6 +900,17 @@ export class Create extends React.Component { // eslint-disable-line react/prefe
|
|
|
900
900
|
stopValidation = () => {
|
|
901
901
|
this.setState({startValidation: false});
|
|
902
902
|
}
|
|
903
|
+
|
|
904
|
+
getAiSuggestions = (prompt) => {
|
|
905
|
+
return new Promise((resolve, reject) => {
|
|
906
|
+
this.props.actions.getAiSuggestions(prompt, (result) => {
|
|
907
|
+
resolve(result);
|
|
908
|
+
}, (error) => {
|
|
909
|
+
reject(error);
|
|
910
|
+
})
|
|
911
|
+
})
|
|
912
|
+
}
|
|
913
|
+
|
|
903
914
|
saveFormData() {
|
|
904
915
|
//Logic to save in db etc
|
|
905
916
|
const formData = _.cloneDeep(this.state.formData);
|
|
@@ -989,6 +1000,7 @@ export class Create extends React.Component { // eslint-disable-line react/prefe
|
|
|
989
1000
|
selectedOfferDetails={this.props.selectedOfferDetails}
|
|
990
1001
|
onTestContentClicked={this.props.onTestContentClicked}
|
|
991
1002
|
onPreviewContentClicked={this.props.onPreviewContentClicked}
|
|
1003
|
+
fetchAiSuggestions={this.getAiSuggestions}
|
|
992
1004
|
/>
|
|
993
1005
|
</CapColumn>
|
|
994
1006
|
</CapRow>
|
|
@@ -29,7 +29,23 @@ function* watchCreateTemplate() {
|
|
|
29
29
|
yield cancel(watcher);
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
+
export function* getAiSuggestions({ prompt, successCallback, failureCallback }) {
|
|
33
|
+
try {
|
|
34
|
+
const result = yield call(Api.getAiSuggestions, {prompt});
|
|
35
|
+
yield successCallback(result);
|
|
36
|
+
} catch (error) {
|
|
37
|
+
yield failureCallback(error);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function* watchAiSuggestions() {
|
|
42
|
+
const watcher = yield takeLatest(
|
|
43
|
+
types.GET_AI_SUGGESTIONS,
|
|
44
|
+
getAiSuggestions
|
|
45
|
+
);
|
|
46
|
+
yield take(LOCATION_CHANGE);
|
|
47
|
+
yield cancel(watcher);
|
|
48
|
+
}
|
|
49
|
+
|
|
32
50
|
// All sagas to be loaded
|
|
33
|
-
export default [
|
|
34
|
-
watchCreateTemplate,
|
|
35
|
-
];
|
|
51
|
+
export default [watchCreateTemplate, watchAiSuggestions];
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { expectSaga } from "redux-saga-test-plan";
|
|
2
|
+
import { take, cancel, takeLatest } from "redux-saga/effects";
|
|
3
|
+
import * as matchers from "redux-saga-test-plan/matchers";
|
|
4
|
+
import { LOCATION_CHANGE } from "react-router-redux";
|
|
5
|
+
import { throwError } from "redux-saga-test-plan/providers";
|
|
6
|
+
import { createMockTask } from "redux-saga/utils";
|
|
7
|
+
import * as types from "../constants";
|
|
8
|
+
import { watchAiSuggestions, getAiSuggestions } from "../sagas";
|
|
9
|
+
import * as Api from "../../../../services/api";
|
|
10
|
+
|
|
11
|
+
describe("getAiSuggestions saga", () => {
|
|
12
|
+
it("Should handle valid response from api", () => {
|
|
13
|
+
const successCallback = () => {};
|
|
14
|
+
const failureCallback = () => {};
|
|
15
|
+
const action = {
|
|
16
|
+
type: types.GET_AI_SUGGESTIONS,
|
|
17
|
+
prompt: {},
|
|
18
|
+
successCallback,
|
|
19
|
+
failureCallback,
|
|
20
|
+
};
|
|
21
|
+
expectSaga(getAiSuggestions, action)
|
|
22
|
+
.provide([
|
|
23
|
+
[
|
|
24
|
+
matchers.call.fn(Api.getAiSuggestions),
|
|
25
|
+
{
|
|
26
|
+
success: true,
|
|
27
|
+
status: {
|
|
28
|
+
isError: false,
|
|
29
|
+
code: 200,
|
|
30
|
+
message: "success",
|
|
31
|
+
},
|
|
32
|
+
message: "Meta data fetched successfully",
|
|
33
|
+
response: {
|
|
34
|
+
"https://response.com": 1400,
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
],
|
|
38
|
+
[matchers.call.fn(successCallback)],
|
|
39
|
+
])
|
|
40
|
+
.run();
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it("Should handles error thrown from api", () => {
|
|
44
|
+
const successCallback = () => {};
|
|
45
|
+
const failureCallback = () => {};
|
|
46
|
+
const action = {
|
|
47
|
+
type: types.GET_AI_SUGGESTIONS,
|
|
48
|
+
prompt: {},
|
|
49
|
+
successCallback,
|
|
50
|
+
failureCallback,
|
|
51
|
+
};
|
|
52
|
+
expectSaga(getAiSuggestions, action)
|
|
53
|
+
.provide([[matchers.call.fn(Api.getAiSuggestions), throwError()]])
|
|
54
|
+
.run();
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
describe("watchAiSuggestions saga", () => {
|
|
59
|
+
let generator = null;
|
|
60
|
+
beforeEach(() => {
|
|
61
|
+
generator = watchAiSuggestions();
|
|
62
|
+
});
|
|
63
|
+
it("Should handle valid response from api", () => {
|
|
64
|
+
const progress1 = generator.next();
|
|
65
|
+
const mockTask = takeLatest(types.GET_AI_SUGGESTIONS, getAiSuggestions);
|
|
66
|
+
expect(progress1.value).toEqual(mockTask);
|
|
67
|
+
const progress2 = generator.next();
|
|
68
|
+
expect(progress2.value).toEqual(take(LOCATION_CHANGE));
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
it("Should handle LOCATION_CHANGE action and cancel the watcher", () => {
|
|
72
|
+
generator = watchAiSuggestions();
|
|
73
|
+
const mockTask = createMockTask();
|
|
74
|
+
|
|
75
|
+
expect(generator.next().value).toEqual(
|
|
76
|
+
takeLatest(types.GET_AI_SUGGESTIONS, getAiSuggestions)
|
|
77
|
+
);
|
|
78
|
+
expect(generator.next(mockTask).value).toEqual(take(LOCATION_CHANGE));
|
|
79
|
+
expect(generator.next().value).toEqual(cancel(mockTask));
|
|
80
|
+
expect(generator.next().done).toEqual(true);
|
|
81
|
+
});
|
|
82
|
+
});
|
|
@@ -95,7 +95,8 @@ import {
|
|
|
95
95
|
TWILIO_CATEGORY_OPTIONS,
|
|
96
96
|
KARIX_GUPSHUP_CATEGORY_OPTIONS,
|
|
97
97
|
STATUS_OPTIONS,
|
|
98
|
-
CATEGORY
|
|
98
|
+
CATEGORY,
|
|
99
|
+
WHATSAPP_CATEGORIES,
|
|
99
100
|
STATUS as WHATSAPP_STATUS,
|
|
100
101
|
WHATSAPP_STATUSES,
|
|
101
102
|
HOST_TWILIO,
|
|
@@ -786,19 +787,33 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
786
787
|
}
|
|
787
788
|
return true;
|
|
788
789
|
}
|
|
789
|
-
|
|
790
|
+
isCategoryMatching(category, selectedWhatsappCategory) {
|
|
791
|
+
const {utility, transactional, authentication, otp } = WHATSAPP_CATEGORIES;
|
|
792
|
+
if (selectedWhatsappCategory) {
|
|
793
|
+
switch (selectedWhatsappCategory) {
|
|
794
|
+
// older karix & gupshup category, supporting for older template filter in listing page
|
|
795
|
+
case utility: {
|
|
796
|
+
return [selectedWhatsappCategory, transactional].includes(category);
|
|
797
|
+
}
|
|
798
|
+
case authentication: {
|
|
799
|
+
return [selectedWhatsappCategory, otp].includes(category);
|
|
800
|
+
}
|
|
801
|
+
default:
|
|
802
|
+
return selectedWhatsappCategory === category;
|
|
803
|
+
}
|
|
804
|
+
}
|
|
805
|
+
return true;
|
|
806
|
+
}
|
|
790
807
|
filterWhatsappTemplates = (templates) => {
|
|
791
808
|
const { selectedWhatsappStatus, selectedWhatsappCategory } = this.state;
|
|
792
809
|
return templates.filter((template) => {
|
|
793
|
-
const { [
|
|
810
|
+
const { [CATEGORY]: category, [WHATSAPP_STATUS]: status } = template?.versions?.base?.content?.[WHATSAPP_LOWERCASE] || {};
|
|
794
811
|
|
|
795
812
|
// if status or category filter is applied, filter templates which match these filters
|
|
796
813
|
return (
|
|
797
814
|
this.isStatusMatching(status, selectedWhatsappStatus)
|
|
798
815
|
) && (
|
|
799
|
-
selectedWhatsappCategory
|
|
800
|
-
? category === selectedWhatsappCategory
|
|
801
|
-
: true
|
|
816
|
+
this.isCategoryMatching(category, selectedWhatsappCategory)
|
|
802
817
|
);
|
|
803
818
|
});
|
|
804
819
|
}
|
|
@@ -855,8 +870,8 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
855
870
|
/>
|
|
856
871
|
);
|
|
857
872
|
|
|
858
|
-
getTemplateDataForGrid = ({templates=[], handlers, filterContent, channel, isLoading, loadingTip}) => {
|
|
859
|
-
|
|
873
|
+
getTemplateDataForGrid = ({templates = [], handlers, filterContent, channel, isLoading, loadingTip}) => {
|
|
874
|
+
const currentChannel = channel.toUpperCase();
|
|
860
875
|
const {channel: stateChannel} = this.state;
|
|
861
876
|
const channelLowerCase = stateChannel.toLowerCase();
|
|
862
877
|
let filteredTemplates = templates;
|
|
@@ -2358,7 +2373,7 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
2358
2373
|
case WHATSAPP_STATUS:
|
|
2359
2374
|
this.setState({ selectedWhatsappStatus: null });
|
|
2360
2375
|
break;
|
|
2361
|
-
case
|
|
2376
|
+
case CATEGORY:
|
|
2362
2377
|
this.setState({ selectedWhatsappCategory: null });
|
|
2363
2378
|
break;
|
|
2364
2379
|
default:
|
|
@@ -2384,7 +2399,7 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
2384
2399
|
}
|
|
2385
2400
|
{
|
|
2386
2401
|
selectedWhatsappCategory ? (
|
|
2387
|
-
<CapTag closable onClose={() => this.removeWhatsappFilter(
|
|
2402
|
+
<CapTag closable onClose={() => this.removeWhatsappFilter(CATEGORY)}>
|
|
2388
2403
|
{formatMessage(messages.category)}: {getWhatsappCategory(selectedWhatsappCategory, this.state.hostName)?.label || selectedWhatsappCategory}
|
|
2389
2404
|
</CapTag>
|
|
2390
2405
|
) : null
|
|
@@ -2394,7 +2409,7 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
2394
2409
|
<CapLink
|
|
2395
2410
|
onClick={() => {
|
|
2396
2411
|
this.removeWhatsappFilter(WHATSAPP_STATUS);
|
|
2397
|
-
this.removeWhatsappFilter(
|
|
2412
|
+
this.removeWhatsappFilter(CATEGORY);
|
|
2398
2413
|
}}
|
|
2399
2414
|
title={this.props.intl.formatMessage(messages.clearAll)}
|
|
2400
2415
|
/>
|