@capillarytech/creatives-library 7.17.113 → 7.17.114

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@capillarytech/creatives-library",
3
3
  "author": "meharaj",
4
- "version": "7.17.113",
4
+ "version": "7.17.114",
5
5
  "description": "Capillary creatives ui",
6
6
  "main": "./index.js",
7
7
  "module": "./index.es.js",
package/reducers.js CHANGED
@@ -21,6 +21,7 @@ import emailReducer from 'containers/Email/reducer';
21
21
  import ebillReducer from 'containers/Ebill/reducer';
22
22
  import ftpReducer from 'v2Containers/FTP/reducer';
23
23
  import galleryReducer from './v2Containers/Assets/Gallery/reducer';
24
+ import CapCollapsibleLeftNavigationReducer from '@capillarytech/cap-ui-library/CapCollapsibleLeftNavigation/reducer';
24
25
  /*
25
26
  * routeReducer
26
27
  *
@@ -68,6 +69,7 @@ export default function createReducer(asyncReducers) {
68
69
  facebookPreview: CapFacebookPreviewReducer,
69
70
  FTP: ftpReducer,
70
71
  gallery: galleryReducer,
72
+ navigationConfig: CapCollapsibleLeftNavigationReducer,
71
73
  ...asyncReducers,
72
74
  });
73
75
  }
package/routes.js CHANGED
@@ -13,7 +13,6 @@ import * as emailSagas from 'containers/Email/sagas';
13
13
  import * as templateSagas from 'containers/Templates/sagas';
14
14
  import * as lineSagas from 'containers/Line/Create/sagas';
15
15
  import * as languageSaga from './v2Containers/LanguageProvider/sagas';
16
-
17
16
  import pathConfig from './config/path';
18
17
 
19
18
  import {updateCharCount} from './utils/smsCharCountV2';
@@ -38,6 +37,7 @@ export default function createRoutes(store) {
38
37
  const { injectReducer, injectSagas } = getAsyncInjectors(store); // eslint-disable-line no-unused-vars
39
38
  injectSagas(rootSaga.default);
40
39
  injectSagas(languageSaga.default);
40
+
41
41
  return [
42
42
  {
43
43
  path: '/',
@@ -669,6 +669,8 @@ export default function createRoutes(store) {
669
669
  import('v2Containers/InApp/reducer'),
670
670
  import('v2Containers/Rcs/sagas'),
671
671
  import('v2Containers/Rcs/reducer'),
672
+ import('@capillarytech/cap-ui-library/CapCollapsibleLeftNavigation/saga'),
673
+ import('@capillarytech/cap-ui-library/CapCollapsibleLeftNavigation/reducer'),
672
674
  ]);
673
675
 
674
676
  const renderRoute = loadModule(cb);
@@ -696,6 +698,7 @@ export default function createRoutes(store) {
696
698
  zaloSagas, zaloReducer,
697
699
  inAppSagas, inAppReducer,
698
700
  rcsSagas, rcsReducer,
701
+ navigationSaga, navigationReducer,
699
702
  ]) => {
700
703
  injectReducer('templates', reducer.default);
701
704
  injectReducer('cap', capReducer.default);
@@ -719,6 +722,7 @@ export default function createRoutes(store) {
719
722
  injectReducer('zalo', zaloReducer.default);
720
723
  injectReducer('inapp', inAppReducer.default);
721
724
  injectReducer('rcs', rcsReducer.default);
725
+ injectReducer('navigationBar', navigationReducer.default);
722
726
  injectSagas(gallerySagas.default);
723
727
  injectSagas(sagas.default);
724
728
  injectSagas(capSagas.default);
@@ -741,6 +745,7 @@ export default function createRoutes(store) {
741
745
  injectSagas(zaloSagas.default);
742
746
  injectSagas(inAppSagas.default);
743
747
  injectSagas(rcsSagas.default);
748
+ injectSagas(navigationSaga.default);
744
749
  renderRoute(component);
745
750
  });
746
751
  importModules.catch(errorLoading);
package/services/api.js CHANGED
@@ -525,3 +525,8 @@ export const getSupportVideosConfig = () => {
525
525
  const url = `${ARYA_ENDPOINT}/support_videos/?product=Creatives`;
526
526
  return request(url, getAPICallObject('GET'));
527
527
  };
528
+
529
+ export const getNavigationConfigApi = async () => {
530
+ const url = `${ARYA_ENDPOINT}/navigations`;
531
+ return await request(url, getAPICallObject('GET'));
532
+ };
@@ -5,6 +5,7 @@ import {
5
5
  createWhatsappTemplate,
6
6
  getMetaTags,
7
7
  getSupportVideosConfig,
8
+ getNavigationConfigApi,
8
9
  } from '../api';
9
10
  import { mockData } from './mockData';
10
11
  const sampleFile = require('../../assets/line.png');
@@ -77,3 +78,8 @@ describe('getSupportVideosConfig -- Test with valid responses', () => {
77
78
  it('Should return correct response', () =>
78
79
  expect(getSupportVideosConfig()).toEqual(Promise.resolve()));
79
80
  });
81
+
82
+ describe('getNavigationConfigApi -- Test with valid responses', () => {
83
+ it('Should return correct response', () =>
84
+ expect(getNavigationConfigApi()).toEqual(Promise.resolve()));
85
+ });
@@ -83,6 +83,14 @@
83
83
  color: #333333;
84
84
  }
85
85
 
86
+ .contet-width-collapse {
87
+ margin-left: 17rem;
88
+ }
89
+
90
+ .content-width-expanded {
91
+ margin-left: 4.475rem;
92
+ }
93
+
86
94
  .breadcrumbs{
87
95
  color: $blue-cloud-burst-54;
88
96
  margin: 16px 10px 12px 10px;
@@ -166,3 +174,9 @@
166
174
  html {
167
175
  font-size: 16px !important;
168
176
  }
177
+
178
+ .cap-collapsible-new-nav, .l1-enabled-popover-container {
179
+ .l2-quick-links-icon {
180
+ margin-top: 0.5rem;
181
+ }
182
+ }
@@ -0,0 +1 @@
1
+ export const EMBEDDED = 'embedded';
@@ -7,26 +7,22 @@
7
7
  import React from 'react';
8
8
  import PropTypes from 'prop-types';
9
9
  import styled from 'styled-components';
10
- import { isEmpty, forEach } from 'lodash';
11
10
  import { loadItem } from 'services/localStorageApi';
12
11
  import { intlShape, injectIntl } from 'react-intl';
13
- import { FONT_COLOR_04 } from '@capillarytech/cap-ui-library/styled/variables';
14
- import TopBar from '../TopBar';
15
12
  import messages from './messages';
16
13
  import { LOYALTY } from '../../v2Containers/App/constants';
17
14
  import {
18
15
  HELP_URL,
19
16
  LOYALTY_HELP_URL,
20
17
  ENABLE_AI_SUGGESTIONS,
18
+ ENABLE_NEW_LEFT_NAVIGATION,
19
+ DEFAULT_MODULE,
21
20
  } from '../../v2Containers/Cap/constants';
22
- const PRODUCT_MASTERS = 'masters';
23
- const EMBEDDED = 'embedded';
24
-
25
- const AppWrapper = styled.div`
26
- .navigation-setting-icon {
27
- color: ${FONT_COLOR_04};
28
- }
29
- `;
21
+ import CapNavigation from '@capillarytech/cap-ui-library/CapNavigation';
22
+ import configPath from '../../config/path';
23
+ import * as Api from '../../services/api';
24
+ import {CapLeftNavigatioOpenCss, CapLeftNavigationCss} from './style';
25
+ import { EMBEDDED } from './constants';
30
26
 
31
27
  const CapWrapper = styled.div`
32
28
  position: absolute;
@@ -104,56 +100,6 @@ export class NavigationBar extends React.Component {
104
100
  }
105
101
  };
106
102
 
107
- getProxyOrgList = () => {
108
- const { userData } = this.props;
109
- const proxyOrgList = [];
110
- if (userData && userData.user && userData.user !== '') {
111
- const defaultOrgName = userData.user.orgName;
112
- const defaultOrgId = userData.user.orgID;
113
- proxyOrgList.push({ label: defaultOrgName, value: defaultOrgId, key: defaultOrgId });
114
- const orgList = userData.user.proxyOrgList;
115
- if (!isEmpty(orgList)) {
116
- forEach(orgList, (item) => {
117
- const id = item.orgID;
118
- const name = item.orgName;
119
- if (id !== defaultOrgId) {
120
- proxyOrgList.push({ label: name, value: id, key: id });
121
- }
122
- });
123
- }
124
- }
125
- return proxyOrgList;
126
- };
127
-
128
- getProductsList = () => {
129
- const { formatMessage } = this.props.intl;
130
- const { currentOrgDetails } = this.props.userData;
131
- const productsList = [];
132
- if (!isEmpty(currentOrgDetails)) {
133
- forEach(currentOrgDetails.module_details, (module = {}) => {
134
- if ((module.name || '').toLowerCase() !== PRODUCT_MASTERS) {
135
- const productName = module.code;
136
- const intlProductName = messages[productName];
137
- const moduleName = intlProductName ? formatMessage(intlProductName) : (module.name || '').toLowerCase();
138
- productsList.push({
139
- value: moduleName,
140
- url: module.url,
141
- key: module.code,
142
- });
143
- }
144
- });
145
- //below changes are temporary and should be fixed once we get correct modules list
146
- //changing campaigns module name to engage+
147
- //adding insights+ to module list
148
- productsList.push({
149
- value: formatMessage(messages.insights),
150
- url: 'analytics/v2/',
151
- key: 'analytics/v2/',
152
- });
153
- }
154
- return productsList;
155
- };
156
-
157
103
  getTopbarIcons = (showDocumentationBot = false) => {
158
104
  const {settingsIcon} = this.state;
159
105
  const ICONS = [
@@ -183,10 +129,6 @@ export class NavigationBar extends React.Component {
183
129
  ];
184
130
  };
185
131
 
186
- handleTopbarMenuChange = (option) => {
187
- window.location.pathname = option.link;
188
- };
189
-
190
132
  handleOrgChange = (orgId) => {
191
133
  const selectedOrg = loadItem('orgID');
192
134
  if (selectedOrg !== orgId) {
@@ -194,55 +136,60 @@ export class NavigationBar extends React.Component {
194
136
  }
195
137
  };
196
138
 
197
- handleProductChange = (product) => {
198
- const { location } = this.props;
199
- const { basename } = location;
200
- this.setState({ selectedProduct: product.value }, () => {
201
- if (product.url !== `${basename}/index`) {
202
- window.location.pathname = product.url;
203
- }
204
- });
205
- };
206
-
207
139
  render() {
208
140
  const {
209
141
  topbarMenuData,
210
- loggedIn,
211
142
  type,
212
143
  userData,
144
+ intl,
145
+ handleLeftNavBarExpanded,
146
+ leftNavbarExpandedProp,
213
147
  } = this.props;
214
148
  const showDocumentationBot = userData?.currentOrgDetails?.accessibleFeatures?.includes(ENABLE_AI_SUGGESTIONS);
215
- const productsList = this.getProductsList();
216
- const proxyOrgList = this.getProxyOrgList();
217
- const selectedOrg = loadItem('orgID');
218
149
  const dropdownMenuProps = this.getDropdownMenu();
219
150
  const topbarIcons = this.getTopbarIcons(showDocumentationBot);
220
- const { selectedProduct } = this.state;
221
- const customTopBarProps = {};
151
+ const {
152
+ currentOrgDetails: {
153
+ accessibleFeatures = [],
154
+ } = {},
155
+ } = userData || {};
156
+ const isLatestLeftNavigationEnabled = accessibleFeatures?.includes(
157
+ ENABLE_NEW_LEFT_NAVIGATION,
158
+ );
159
+ const topbarMenuDataModified = isLatestLeftNavigationEnabled ? [] : topbarMenuData;
160
+ const headerOverideCss = isLatestLeftNavigationEnabled && (leftNavbarExpandedProp ? CapLeftNavigatioOpenCss : CapLeftNavigationCss);
222
161
  return (
223
- <AppWrapper>
224
- {loggedIn && type !== EMBEDDED &&
225
- <TopBar
226
- productsList={productsList}
227
- selectedProduct={selectedProduct}
228
- handleProductChange={this.handleProductChange}
229
- proxyOrgList={proxyOrgList}
230
- selectedOrg={selectedOrg}
231
- handleOrgChange={this.handleOrgChange}
232
- topbarMenuData={topbarMenuData}
233
- handleTopbarMenuChange={this.handleTopbarMenuChange}
234
- dropdownMenuProps={dropdownMenuProps}
235
- topbarIcons={topbarIcons}
236
- showDocumentationBot={showDocumentationBot}
237
- {...customTopBarProps}
238
- />
239
- }
240
- <CapWrapper isEmbedded={type === EMBEDDED}>
241
- <ComponentWrapper>
242
- {React.Children.toArray(this.props.children)}
243
- </ComponentWrapper>
244
- </CapWrapper>
245
- </AppWrapper>
162
+ <CapNavigation
163
+ className="creatives-main-container"
164
+ showContent
165
+ userData={userData}
166
+ loadStorageItem={loadItem}
167
+ changeOrgEntity={this.handleOrgChange}
168
+ topbarMenuData={topbarMenuDataModified}
169
+ topbarSelectedMenuData={[DEFAULT_MODULE]}
170
+ dropdownMenuProps={dropdownMenuProps}
171
+ topbarIcons={topbarIcons}
172
+ sidebarMenuData={[]}
173
+ sidebarMenuItemsPosition={null}
174
+ defaultSelectedProduct={intl.formatMessage(messages.selectedProductDefault)}
175
+ skipStateForStorage
176
+ selectOrganization={intl.formatMessage(messages.selectOrganization)}
177
+ isLatestLeftNavigationEnabled={isLatestLeftNavigationEnabled}
178
+ history={history}
179
+ publicPath={configPath.publicPath}
180
+ getNavigationConfigApi={Api.getNavigationConfigApi}
181
+ showDocumentationBot={showDocumentationBot}
182
+ setLeftNavbarExpandedProp={handleLeftNavBarExpanded}
183
+ headerOverideCss={headerOverideCss}
184
+ >
185
+ <div data-testid="cap-wrapper">
186
+ <CapWrapper isEmbedded={type === EMBEDDED}>
187
+ <ComponentWrapper>
188
+ {React.Children.toArray(this.props.children)}
189
+ </ComponentWrapper>
190
+ </CapWrapper>
191
+ </div>
192
+ </CapNavigation>
246
193
  );
247
194
  }
248
195
  }
@@ -255,10 +202,11 @@ NavigationBar.propTypes = {
255
202
  settingsUrl: PropTypes.string,
256
203
  children: PropTypes.node,
257
204
  orgSettingsUrl: PropTypes.string,
258
- loggedIn: PropTypes.bool,
259
205
  intl: intlShape.isRequired,
260
206
  location: PropTypes.object,
261
207
  type: PropTypes.string,
208
+ handleLeftNavBarExpanded: PropTypes.func,
209
+ leftNavbarExpandedProp: PropTypes.bool,
262
210
  };
263
211
 
264
212
  export default injectIntl(NavigationBar);
@@ -62,4 +62,8 @@ export default defineMessages({
62
62
  defaultMessage:
63
63
  'There are no product settings. Organisation settings are available under profile on the right.',
64
64
  },
65
+ "selectOrganization": {
66
+ id: `${scope}.selectOrganization`,
67
+ defaultMessage: 'Select organization',
68
+ },
65
69
  });
@@ -0,0 +1,9 @@
1
+ export const CapLeftNavigationCss = {
2
+ 'width': '75.770rem',
3
+ 'margin-left': 'calc((100vw - 70.063rem)/2 + 1.6rem)',
4
+ };
5
+
6
+ export const CapLeftNavigatioOpenCss = {
7
+ 'width': '71.063rem',
8
+ 'margin-left': 'calc((100vw - 70.063rem)/2 + 8rem)',
9
+ };
@@ -37,7 +37,7 @@ describe('NavigationBar', () => {
37
37
 
38
38
  it('Show aria documentation bot icon if showDocumentationBot is true', () => {
39
39
  renderComponent(props);
40
- const ariaBotIcon = screen.getByLabelText('aria bot icon');
40
+ const ariaBotIcon = screen.getByLabelText('open-aira');
41
41
  expect(ariaBotIcon).toBeInTheDocument();
42
42
  });
43
43
 
@@ -45,7 +45,7 @@ describe('NavigationBar', () => {
45
45
  const updatedProps = cloneDeep(props);
46
46
  delete updatedProps.userData.currentOrgDetails.accessibleFeatures;
47
47
  renderComponent(updatedProps);
48
- const ariaBotIcon = screen.queryByLabelText('aria bot icon');
48
+ const ariaBotIcon = screen.queryByLabelText('open-aira');
49
49
  expect(ariaBotIcon).toBeNull();
50
50
  });
51
51
  });
@@ -40,6 +40,7 @@ export const ORG_CHANGED = 'ORG_CHANGED';
40
40
 
41
41
  export const ENABLE_AI_SUGGESTIONS = 'ENABLE_AI_SUGGESTIONS';
42
42
  export const ERROR_IN_FETCHING_TAGS = 'Error in fetching tags';
43
+ export const ENABLE_NEW_LEFT_NAVIGATION = 'ENABLE_NEW_LEFT_NAVIGATION';
43
44
 
44
45
  export const GET_SUPPORT_VIDEOS_CONFIG_REQUEST =
45
46
  'cap/GET_SUPPORT_VIDEOS_CONFIG_REQUEST';
@@ -54,3 +55,4 @@ export const FAILURE = 'FAILURE';
54
55
 
55
56
  export const ENABLE_PRODUCT_SUPPORT_VIDEOS = 'ENABLE_PRODUCT_SUPPORT_VIDEOS';
56
57
  export const DEFAULT = 'default';
58
+ export const DEFAULT_MODULE = 'creatives';
@@ -31,6 +31,7 @@ import {
31
31
  REQUEST,
32
32
  DEFAULT,
33
33
  ENABLE_PRODUCT_SUPPORT_VIDEOS,
34
+ ENABLE_NEW_LEFT_NAVIGATION,
34
35
  } from './constants';
35
36
  import './_cap.scss';
36
37
  const gtm = window.dataLayer || [];
@@ -55,6 +56,17 @@ const CapWrapper = styled.div`
55
56
  `;
56
57
  GA.initialize({ accessKey: GTM_TRACKING_ID, trackUIError: true, trackLoadPerformance: 'creatives' });
57
58
 
59
+ const MainWrapper = styled.div`
60
+ position: relative;
61
+ min-height: calc(100vh - 5.29rem);
62
+ top: ${(props) => (props.isLatestLeftNavigationEnabled ? '1.72rem' : '5.29rem')};
63
+ `;
64
+
65
+ const ContentWrapper = styled.div`
66
+ && {
67
+ margin-left: ${(props) => (props.isLatestLeftNavigationEnabled ? (props.leftNavbarExpanded ? '17rem' : '4.475rem') : 0)};
68
+ }
69
+ `;
58
70
 
59
71
  export class Cap extends React.Component { // eslint-disable-line react/prefer-stateless-function
60
72
 
@@ -68,6 +80,7 @@ export class Cap extends React.Component { // eslint-disable-line react/prefer-s
68
80
  showRefreshModal: false,
69
81
  showOrgChangeModal: false,
70
82
  localStorageOrgInfo: { oldValue: null, newValue: null },
83
+ leftNavbarExpanded: false,
71
84
  };
72
85
  this.changeOrg = this.changeOrg.bind(this);
73
86
  this.logout = this.logout.bind(this);
@@ -458,6 +471,10 @@ export class Cap extends React.Component { // eslint-disable-line react/prefer-s
458
471
  return wrapperComponent;
459
472
  }
460
473
 
474
+ handleLeftNavBarExpanded = (leftNavbarExpandedProp) => {
475
+ this.setState({leftNavbarExpanded: leftNavbarExpandedProp})
476
+ }
477
+
461
478
  render() {
462
479
  const { Global, location } = this.props;
463
480
  const { topbarMenuData, isLoggedIn, currentOrgDetails = {}, getUserDataStatus, getUserDataCode } = Global;
@@ -465,7 +482,9 @@ export class Cap extends React.Component { // eslint-disable-line react/prefer-s
465
482
  const type = this.props.location.query.type;
466
483
  const toastMessages = this.props.Global.messages;
467
484
  const { isCreativesAccessible, showOrgChangeModal, showRefreshModal } = this.state;
468
-
485
+ const isLatestLeftNavigationEnabled = currentOrgDetails?.accessibleFeatures?.includes(
486
+ ENABLE_NEW_LEFT_NAVIGATION,
487
+ );
469
488
  return (
470
489
  <CapWrapper>
471
490
  { this.props.loader.localeLoading || this.props.Global.fetching_userdata ?
@@ -501,13 +520,19 @@ export class Cap extends React.Component { // eslint-disable-line react/prefer-s
501
520
  topbarMenuData={topbarMenuDataOptions}
502
521
  location={location}
503
522
  campaignOrgV2Status={currentOrgDetails.org_campaign_v2_status}
523
+ handleLeftNavBarExpanded={this.handleLeftNavBarExpanded}
524
+ leftNavbarExpandedProp={this.state.leftNavbarExpanded}
504
525
  />) : ''}
505
- <div className="main" style={{minHeight: 'calc(100vh - 74px', position: 'relative', top: '74px'}}>
526
+ <MainWrapper isLatestLeftNavigationEnabled={isLatestLeftNavigationEnabled} className="main">
506
527
 
507
- <div className="main-content">
528
+ <ContentWrapper
529
+ className={`main-content ${this.state.leftNavbarExpanded ? "contet-width-collapse" : "content-width-expanded"}`}
530
+ isLatestLeftNavigationEnabled={isLatestLeftNavigationEnabled}
531
+ leftNavbarExpanded={this.state.leftNavbarExpanded}
532
+ >
508
533
  {React.Children.toArray(this.props.children)}
509
- </div>
510
- </div>
534
+ </ContentWrapper>
535
+ </MainWrapper>
511
536
  </div>
512
537
  {(toastMessages && toastMessages.length > 0) &&
513
538
  toastMessages.map((message) => {