@capillarytech/creatives-library 8.0.46-alpha.1 → 8.0.47

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/app.js CHANGED
@@ -7,6 +7,7 @@ import { Provider } from 'react-redux';
7
7
  // import { useScroll } from 'react-router-scroll';
8
8
  import history from 'utils/history';
9
9
  import CapSomethingWentWrong from '@capillarytech/cap-ui-library/CapSomethingWentWrong';
10
+ import { addLocizeSavedHandler, startStandalone } from 'locize';
10
11
  import Bugsnag from '@bugsnag/js';
11
12
  import BugsnagPluginReact from '@bugsnag/plugin-react';
12
13
  // import { makeSelectLocationState } from 'containers/Cap/selectors';
@@ -120,6 +121,20 @@ if (module.hot) {
120
121
  render(translationMessages);
121
122
  });
122
123
  }
124
+
125
+ // for auto render UI on locize saved, since we cache the translations in redis it can't be update on real time as of now
126
+ // need to comment as of now
127
+ // addLocizeSavedHandler(res => {
128
+ // res.updated.forEach(item => {
129
+ // const { lng, ns, key, data } = item
130
+ // // load the translations somewhere...
131
+ // // and maybe rerender your UI
132
+ // })
133
+ // })
134
+
135
+ // start
136
+ startStandalone();
137
+
123
138
  const openSansObserver = new FontFaceObserver('Roboto', {});
124
139
  // When Open Sans is loaded, add a font-family using Open Sans to the body
125
140
  openSansObserver.load().then(() => {
@@ -69,7 +69,7 @@ class Sidebar extends React.Component { // eslint-disable-line react/prefer-stat
69
69
  }
70
70
 
71
71
  selectActiveLinkFromUrl(props) {
72
- const activeRouteName = this.props.history.location.pathname?.split('/')[1];
72
+ const activeRouteName = this.props?.history?.location?.pathname?.split('/')[1];
73
73
  let selectedItem = '';
74
74
  let selectedIndex = -1;
75
75
  _.forEach(props.menuData, (menuItem, menuIndex) => {
@@ -35,7 +35,7 @@ export function* fetchUserList() {
35
35
  const result = yield call(Api.getUserList);
36
36
  yield put({
37
37
  type: types.GET_USER_LIST_SUCCESS,
38
- data: result.data.result,
38
+ data: result?.data?.result,
39
39
  });
40
40
  } catch (error) {
41
41
  yield put({
@@ -32,6 +32,7 @@ import { CREATIVES_UI_VIEW } from '../../v2Containers/App/constants';
32
32
  import AccessForbidden from '../../v2Components/AccessForbidden';
33
33
  import reducer from './reducer';
34
34
  import RenderRoute from '../../v2Components/RenderRoute';
35
+ import { EMBEDDED } from '../../v2Containers/SmsTrai/Edit/constants';
35
36
 
36
37
  const gtm = window.dataLayer || [];
37
38
 
@@ -71,7 +72,7 @@ export class Cap extends React.Component { // eslint-disable-line react/prefer-s
71
72
  gtm.push({ ...userGtmData, event: 'userAuthenticated' });
72
73
  }
73
74
  }
74
- if (!_.isEmpty(this.props.Global.orgID)) {
75
+ if (!_.isEmpty(this.props?.Global?.orgID)) {
75
76
  gtm.push({ orgId: this.props.Global.orgID });
76
77
  }
77
78
  if (this.props.Global.isLoggedIn) {
@@ -173,7 +174,7 @@ export class Cap extends React.Component { // eslint-disable-line react/prefer-s
173
174
  const { user: userData } = props.Global;
174
175
  const userName = userData.attributes.USERNAME;
175
176
  const userEmail = userData.attributes.EMAIL;
176
- const orgObj = _.find(userData.proxyOrgList, { orgID: props.Global.orgID });
177
+ const orgObj = _.find(userData?.proxyOrgList, { orgID: props?.Global?.orgID });
177
178
  const gtmData = {
178
179
  orgId: props.Global.orgID,
179
180
  orgName: orgObj && orgObj.orgName,
@@ -295,7 +296,7 @@ export class Cap extends React.Component { // eslint-disable-line react/prefer-s
295
296
  const { isCreativesAccessible } = this.state;
296
297
  return (
297
298
  <CapWrapper>
298
- {this.props.loader.localeLoading || this.props.Global.fetching_userdata ?
299
+ {this.props?.loader?.localeLoading || this.props?.Global?.fetching_userdata ?
299
300
  <div className="cap-loader-box">
300
301
  <img
301
302
  className="loader-image"
@@ -311,7 +312,7 @@ export class Cap extends React.Component { // eslint-disable-line react/prefer-s
311
312
  ]}
312
313
  />
313
314
  <div className="wrapper">
314
- {loggedIn && type !== 'embedded' ?
315
+ {loggedIn && type !== EMBEDDED ?
315
316
  <TopBar
316
317
  proxyOrgList={proxyOrgList}
317
318
  userName={userName}
@@ -6,6 +6,7 @@ import {
6
6
  } from 'redux-saga/effects';
7
7
  import {
8
8
  authorize, loginFlow, logoutFlow, watchForLogoutFlow, capSaga,
9
+ fetchSchemaForEntity,
9
10
  } from '../sagas';
10
11
  import * as api from '../../../services/api';
11
12
  import {
@@ -14,6 +15,8 @@ import {
14
15
  LOGOUT_REQUEST,
15
16
  LOGOUT_SUCCESS,
16
17
  LOGOUT_FAILURE,
18
+ GET_SCHEMA_FOR_ENTITY_SUCCESS,
19
+ GET_SCHEMA_FOR_ENTITY_FAILURE,
17
20
  } from '../constants';
18
21
 
19
22
  const error = new Error('error');
@@ -117,3 +120,97 @@ describe('logoutFlow [Unit Test]', () => {
117
120
  });
118
121
  });
119
122
  });
123
+
124
+ describe("fetchSchemaForEntity", () => {
125
+ it("handle success response from fetchSchemaForEntity", () => {
126
+ expectSaga(fetchSchemaForEntity, {
127
+ queryParams: {
128
+ type: 'tags'
129
+ },
130
+ })
131
+ .provide([
132
+ [
133
+ matchers.call.fn(api.fetchSchemaForEntity),
134
+ {
135
+ success: true,
136
+ response: {},
137
+ },
138
+ ],
139
+ ])
140
+ .put({
141
+ type: GET_SCHEMA_FOR_ENTITY_SUCCESS,
142
+ data: {},
143
+ statusCode: '',
144
+ entityType: 'tags'
145
+ })
146
+ .run();
147
+ });
148
+
149
+ it("handle success response from fetchSchemaForEntity when metaEntities available", () => {
150
+ expectSaga(fetchSchemaForEntity, {
151
+ queryParams: {
152
+ type: 'tags'
153
+ },
154
+ })
155
+ .provide([
156
+ [
157
+ matchers.call.fn(api.fetchSchemaForEntity),
158
+ {
159
+ response: {
160
+ metaEntities: []
161
+ },
162
+ },
163
+ ],
164
+ ])
165
+ .put({
166
+ type: GET_SCHEMA_FOR_ENTITY_SUCCESS,
167
+ data: {
168
+ metaEntities: []
169
+ },
170
+ statusCode: '',
171
+ entityType: 'tags'
172
+ })
173
+ .run();
174
+ });
175
+
176
+ it("handle when response and query params are empty from fetchSchemaForEntity when metaEntities available", () => {
177
+ expectSaga(fetchSchemaForEntity, {})
178
+ .provide([
179
+ [
180
+ matchers.call.fn(api.fetchSchemaForEntity),
181
+ {
182
+ success: true
183
+ },
184
+ ],
185
+ ])
186
+ .put({
187
+ type: GET_SCHEMA_FOR_ENTITY_SUCCESS,
188
+ data: {},
189
+ statusCode: '',
190
+ entityType: ''
191
+ })
192
+ .run();
193
+ });
194
+
195
+ it("handle error response from fetchSchemaForEntity", () => {
196
+ expectSaga(fetchSchemaForEntity, {
197
+ queryParams: {
198
+ type: 'tags'
199
+ },
200
+ })
201
+ .provide([
202
+ [
203
+ matchers.call.fn(api.fetchSchemaForEntity),
204
+ {
205
+ success: false,
206
+ response: {},
207
+ },
208
+ ],
209
+ ])
210
+ .put({
211
+ type: GET_SCHEMA_FOR_ENTITY_FAILURE,
212
+ error: 'Error in fetching tags'
213
+ })
214
+ .run();
215
+ });
216
+ });
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@capillarytech/creatives-library",
3
3
  "author": "meharaj",
4
- "version": "8.0.46-alpha.1",
4
+ "version": "8.0.47",
5
5
  "description": "Capillary creatives ui",
6
6
  "main": "./index.js",
7
7
  "module": "./index.es.js",
@@ -31,6 +31,7 @@
31
31
  "jest-environment-jsdom": "27.5.1",
32
32
  "jquery": "^3.3.1",
33
33
  "load-script": "^1.0.0",
34
+ "locize": "^3.3.0",
34
35
  "ml-matrix": "6.10.8",
35
36
  "node-html-parser": "^5.4.2-0",
36
37
  "normalizr": "^3.2.3",
@@ -52,7 +52,6 @@ import { v2RcsSagas } from '../Rcs/sagas';
52
52
  import { v2InAppSagas } from '../InApp/sagas';
53
53
  import { v2ViberSagas } from '../Viber/sagas';
54
54
  import { v2FacebookSagas } from '../Facebook/sagas';
55
- import { v2ZaloSagas } from '../Zalo/saga';
56
55
  import createReducer from '../Line/Container/reducer';
57
56
 
58
57
  const gtm = window.dataLayer || [];
@@ -620,7 +619,6 @@ const withWechatMapTemplatesSaga = injectSaga({ key: 'weChatMapTemplate', saga:
620
619
  const withRcsSaga = injectSaga({ key: 'rcs', saga: v2RcsSagas });
621
620
  const withInAppSaga = injectSaga({ key: 'inapp', saga: v2InAppSagas });
622
621
  const withViberSaga = injectSaga({ key: 'viber', saga: v2ViberSagas });
623
- const withZaloSaga = injectSaga({ key: 'zaloSaga', saga: v2ZaloSagas });
624
622
  const withFacebookSaga = injectSaga({ key: 'facebook', saga: v2FacebookSagas });
625
623
  const withLineReducer = injectReducer({ key: 'lineCreate', reducer: createReducer });
626
624
 
@@ -636,7 +634,6 @@ export default compose(
636
634
  withInAppSaga,
637
635
  withViberSaga,
638
636
  withFacebookSaga,
639
- withZaloSaga,
640
637
  withReducer,
641
638
  withZaloReducer,
642
639
  withLineReducer,
@@ -19,7 +19,6 @@ import {
19
19
  GET_LIQUID_TAGS_REQUEST,
20
20
  } from '../constants';
21
21
  import { callback, error, error2, videoConfigData } from '../../mockdata';
22
- import { watchForLogoutFlow } from '../../../containers/Cap/sagas';
23
22
  import { LOGOUT_FAILURE, LOGOUT_REQUEST, LOGOUT_SUCCESS } from '../../../containers/Cap/constants';
24
23
 
25
24
 
@@ -587,6 +587,7 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
587
587
  }
588
588
 
589
589
  onChange = (evt) => {
590
+ const {isFullMode, showTemplateName} = this.props;
590
591
  const formData = _.cloneDeep(this.state.formData);
591
592
 
592
593
  //if (evt.editor.name.indexOf('editor') === -1) {
@@ -609,7 +610,9 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
609
610
  }
610
611
 
611
612
  this.setState({formData, content: evt.editor.getData()}, () => {
612
-
613
+ if (isFullMode && showTemplateName) {
614
+ showTemplateName({formData, onFormDataChange: this.onFormDataChange});
615
+ }
613
616
  });
614
617
  }
615
618
  }
@@ -10,7 +10,7 @@ export function* editTemplate(template) {
10
10
  try {
11
11
  const result = yield call(Api.editTemplate, template);
12
12
  // const sidebar = result.response.sidebar;
13
- if (result.message || result.status.code === 500) {
13
+ if (result?.message || result?.status?.code === 500) {
14
14
  errorMsg = result.message;
15
15
  }
16
16
 
@@ -2,11 +2,54 @@
2
2
  import { expectSaga } from "redux-saga-test-plan";
3
3
 
4
4
  import {
5
+ editTemplate,
5
6
  v2SmsEditSagas,
6
7
  } from "../sagas";
8
+ import * as api from "../../../../services/api";
9
+ import * as types from '../constants';
10
+ import { call } from "redux-saga/effects";
11
+ import { throwError } from "redux-saga-test-plan/providers";
7
12
 
8
13
  describe("v2SmsEditSagas Combined", () => {
9
14
  it("should initialize all v2SmsEditSagas-related watcher sagas without error", () => {
10
15
  return expectSaga(v2SmsEditSagas).run();
11
16
  });
17
+ });
18
+
19
+ describe('editTemplate Saga', () => {
20
+ const template = { id: 1, name: 'Updated Template' };
21
+
22
+ it('handles successful template edit', () => {
23
+ const fakeResponse = {
24
+ response: template,
25
+ status: { code: 200 }
26
+ };
27
+
28
+ return expectSaga(editTemplate, template)
29
+ .provide([
30
+ [call(api.editTemplate, template), fakeResponse]
31
+ ])
32
+ .put({
33
+ type: types.EDIT_TEMPLATE_SUCCESS,
34
+ data: fakeResponse.response,
35
+ statusCode: 200,
36
+ errorMsg: undefined
37
+ })
38
+ .run();
39
+ });
40
+
41
+ it('handles failure in editing a template', () => {
42
+ const error = new Error('Edit failed');
43
+
44
+ return expectSaga(editTemplate, template)
45
+ .provide([
46
+ [call(api.editTemplate, template), throwError(error)]
47
+ ])
48
+ .put({
49
+ type: types.EDIT_TEMPLATE_FAILURE,
50
+ error,
51
+ errorMsg: undefined
52
+ })
53
+ .run();
54
+ });
12
55
  });
@@ -3237,6 +3237,8 @@ function mapDispatchToProps(dispatch) {
3237
3237
 
3238
3238
  const withReducer = injectReducer({ key: 'templates', reducer: v2TemplateReducer });
3239
3239
  const withConnect = connect(mapStateToProps, mapDispatchToProps);
3240
+
3241
+ //injecting Saga in Daemon Mode , so that it doesn't get injected multiple times.
3240
3242
  const withSaga = injectSaga({ key: 'templates', saga: v2TemplateSaga, mode: DAEMON });
3241
3243
 
3242
3244
  export default compose(
@@ -48,9 +48,11 @@ import withCreatives from '../../hoc/withCreatives';
48
48
  import TagList from '../TagList';
49
49
  import { validateTags } from '../../utils/tagValidations';
50
50
  import TemplatePreview from '../../v2Components/TemplatePreview';
51
+ import injectSaga from '../../utils/injectSaga';
51
52
  import injectReducer from '../../utils/injectReducer';
52
53
  import * as globalActions from '../Cap/actions';
53
54
  import v2ZaloReducer from './reducer';
55
+ import { v2ZaloSagas } from './saga';
54
56
 
55
57
  export const Zalo = (props) => {
56
58
  const {
@@ -504,6 +506,7 @@ const mapDispatchToProps = (dispatch) => ({
504
506
 
505
507
 
506
508
  const withReducer = injectReducer({ key: 'zalo', reducer: v2ZaloReducer });
509
+ const withZaloSaga = injectSaga({ key: 'zalo', saga: v2ZaloSagas });
507
510
 
508
511
  export default withCreatives({
509
512
  WrappedComponent: Zalo,
@@ -511,4 +514,5 @@ export default withCreatives({
511
514
  mapDispatchToProps,
512
515
  userAuth: true,
513
516
  reducers: [withReducer],
517
+ sagas: [withZaloSaga],
514
518
  });