@capillarytech/creatives-library 7.17.113 → 7.17.114-alpha.0

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.
@@ -16,6 +16,7 @@ export const BADGES_UI_ENABLED = 'BADGES_UI_ENABLED';
16
16
  export const JP_LOCALE_HIDE_FEATURE = 'JP_LOCALE_HIDE_FEATURE';
17
17
  export const ENABLE_WECHAT = 'ENABLE_WECHAT';
18
18
  export const ENABLE_CUSTOMER_BARCODE_TAG = "ENABLE_CUSTOMER_BARCODE_TAG";
19
+ export const EMAIL_UNSUBSCRIBE_TAG_MANDATORY = "EMAIL_UNSUBSCRIBE_TAG_MANDATORY";
19
20
 
20
21
  export const CARD_RELATED_TAGS = [
21
22
  'card_series',
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-alpha.0",
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,17 @@
83
83
  color: #333333;
84
84
  }
85
85
 
86
+ .contet-width-collapse {
87
+ margin-left: 17.438rem;
88
+ .component-wrapper {
89
+ max-width: 70.063rem;
90
+ }
91
+ }
92
+
93
+ .content-width-expanded {
94
+ margin-left: 8.375rem;
95
+ }
96
+
86
97
  .breadcrumbs{
87
98
  color: $blue-cloud-burst-54;
88
99
  margin: 16px 10px 12px 10px;
@@ -166,3 +177,9 @@
166
177
  html {
167
178
  font-size: 16px !important;
168
179
  }
180
+
181
+ .cap-collapsible-new-nav, .l1-enabled-popover-container {
182
+ .l2-quick-links-icon {
183
+ margin-top: 0.5rem;
184
+ }
185
+ }
package/utils/common.js CHANGED
@@ -18,6 +18,7 @@ import {
18
18
  ENABLE_CUSTOMER_BARCODE_TAG,
19
19
  BADGES_UI_ENABLED,
20
20
  BADGES_ENROLL,
21
+ EMAIL_UNSUBSCRIBE_TAG_MANDATORY,
21
22
  BADGES_ISSUE,
22
23
  ENABLE_WECHAT,
23
24
  } from '../containers/App/constants';
@@ -112,6 +113,10 @@ export const hasCustomerBarcodeFeatureEnabled = Auth.hasFeatureAccess.bind(
112
113
  ENABLE_CUSTOMER_BARCODE_TAG,
113
114
  );
114
115
 
116
+ export const hasRemoveEmailUnsubscribeTag = Auth.hasFeatureAccess.bind(
117
+ null,
118
+ EMAIL_UNSUBSCRIBE_TAG_MANDATORY,
119
+ );
115
120
  //filtering tags based on scope
116
121
  export const filterTags = (tagsToFilter, tagsList) => tagsList?.filter(
117
122
  (tag) => !tagsToFilter?.includes(tag?.definition?.value)
@@ -55,6 +55,7 @@ import { AI_SUGGESTION_API_URL, CONTENT_RECOMMENDATION_BOT } from './constants';
55
55
  import { GET_TRANSLATION_MAPPED } from '../../containers/TagList/constants';
56
56
  import moment from 'moment';
57
57
  import { CUSTOMER_BARCODE_TAG , COPY_OF} from '../../containers/App/constants';
58
+ import { hasRemoveEmailUnsubscribeTag } from '../../utils/common';
58
59
  const TabPane = Tabs.TabPane;
59
60
  const {Column} = Table;
60
61
  const {TextArea} = CapInput;
@@ -989,6 +990,9 @@ class FormBuilder extends React.Component { // eslint-disable-line react/prefer-
989
990
  if (tagValidationResponse.isBraceError){
990
991
  errorString += this.props.intl.formatMessage(globalMessages.unbalanacedCurlyBraces);
991
992
  }
993
+ if (tagValidationResponse.isContentEmpty) {
994
+ errorString += this.props.intl.formatMessage(messages.emailBodyEmptyError);
995
+ }
992
996
  }
993
997
  }
994
998
  }
@@ -1127,6 +1131,8 @@ class FormBuilder extends React.Component { // eslint-disable-line react/prefer-
1127
1131
  response.missingTags = [];
1128
1132
  response.unsupportedTags = [];
1129
1133
  response.isBraceError = false;
1134
+ response.isContentEmpty = false;
1135
+ const contentForValidation = isEmail ? convert(content) : content ;
1130
1136
  if(tags && tags.length) {
1131
1137
  _.forEach(tags, (tag) => {
1132
1138
  _.forEach(tag.definition.supportedModules, (module) => {
@@ -1144,6 +1150,19 @@ class FormBuilder extends React.Component { // eslint-disable-line react/prefer-
1144
1150
  let matchImg = regexImgSrc.exec(content);
1145
1151
  const regexCustomerBarcode = /{{customer_barcode}}(?![^<]*>)/g;
1146
1152
  let matchCustomerBarcode = regexCustomerBarcode.exec(content);
1153
+ // \S matches anything other than a space, a tab, a newline, or a carriage return.
1154
+ const validString= /\S/.test(contentForValidation);
1155
+ if (hasRemoveEmailUnsubscribeTag() && isEmail) {
1156
+ const missingTagIndex = response.missingTags.indexOf("unsubscribe");
1157
+ if(missingTagIndex != -1) { //skip regex tags for mandatory tags also
1158
+ response.missingTags.splice(missingTagIndex, 1);
1159
+ if (validString) {
1160
+ response.valid = true;
1161
+ } else {
1162
+ response.isContentEmpty = true;
1163
+ }
1164
+ }
1165
+ }
1147
1166
  while (match !== null ) {
1148
1167
  const tagValue = match[0].substring(this.indexOfEnd(match[0], '{{'), match[0].indexOf('}}'));
1149
1168
  match = regex.exec(content);
@@ -1177,7 +1196,6 @@ class FormBuilder extends React.Component { // eslint-disable-line react/prefer-
1177
1196
  }
1178
1197
  }
1179
1198
  }
1180
- const contentForValidation = isEmail ? convert(content) : content ;
1181
1199
  if(!validateIfTagClosed(contentForValidation)){
1182
1200
  response.isBraceError = true;
1183
1201
  response.valid = false;
@@ -86,4 +86,8 @@ export default defineMessages({
86
86
  id: 'creatives.componentsV2.FormBuilder.imageReUpload',
87
87
  defaultMessage: 'Re upload',
88
88
  },
89
+ emailBodyEmptyError: {
90
+ id: 'creatives.componentsV2.FormBuilder.emailBodyEmptyError',
91
+ defaultMessage: 'Email body cannot be empty',
92
+ },
89
93
  });
@@ -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,11 @@
1
+ export const CapLeftNavigationCss = {
2
+ 'padding-right': '1.28rem',
3
+ "width": '71.25rem',
4
+ 'margin-left': '14.9rem',
5
+ };
6
+
7
+ export const CapLeftNavigatioOpenCss = {
8
+ 'padding-left': '0',
9
+ "width": '70.063rem',
10
+ 'margin-left': '18.5rem',
11
+ };
@@ -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,11 @@ 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
+ `;
58
64
 
59
65
  export class Cap extends React.Component { // eslint-disable-line react/prefer-stateless-function
60
66
 
@@ -68,6 +74,7 @@ export class Cap extends React.Component { // eslint-disable-line react/prefer-s
68
74
  showRefreshModal: false,
69
75
  showOrgChangeModal: false,
70
76
  localStorageOrgInfo: { oldValue: null, newValue: null },
77
+ leftNavbarExpanded: false,
71
78
  };
72
79
  this.changeOrg = this.changeOrg.bind(this);
73
80
  this.logout = this.logout.bind(this);
@@ -458,6 +465,10 @@ export class Cap extends React.Component { // eslint-disable-line react/prefer-s
458
465
  return wrapperComponent;
459
466
  }
460
467
 
468
+ handleLeftNavBarExpanded = (leftNavbarExpandedProp) => {
469
+ this.setState({leftNavbarExpanded: leftNavbarExpandedProp})
470
+ }
471
+
461
472
  render() {
462
473
  const { Global, location } = this.props;
463
474
  const { topbarMenuData, isLoggedIn, currentOrgDetails = {}, getUserDataStatus, getUserDataCode } = Global;
@@ -465,7 +476,9 @@ export class Cap extends React.Component { // eslint-disable-line react/prefer-s
465
476
  const type = this.props.location.query.type;
466
477
  const toastMessages = this.props.Global.messages;
467
478
  const { isCreativesAccessible, showOrgChangeModal, showRefreshModal } = this.state;
468
-
479
+ const isLatestLeftNavigationEnabled = currentOrgDetails?.accessibleFeatures?.includes(
480
+ ENABLE_NEW_LEFT_NAVIGATION,
481
+ );
469
482
  return (
470
483
  <CapWrapper>
471
484
  { this.props.loader.localeLoading || this.props.Global.fetching_userdata ?
@@ -501,13 +514,15 @@ export class Cap extends React.Component { // eslint-disable-line react/prefer-s
501
514
  topbarMenuData={topbarMenuDataOptions}
502
515
  location={location}
503
516
  campaignOrgV2Status={currentOrgDetails.org_campaign_v2_status}
517
+ handleLeftNavBarExpanded={this.handleLeftNavBarExpanded}
518
+ leftNavbarExpandedProp={this.state.leftNavbarExpanded}
504
519
  />) : ''}
505
- <div className="main" style={{minHeight: 'calc(100vh - 74px', position: 'relative', top: '74px'}}>
520
+ <MainWrapper isLatestLeftNavigationEnabled={isLatestLeftNavigationEnabled} className="main">
506
521
 
507
- <div className="main-content">
522
+ <div className={`main-content ${this.state.leftNavbarExpanded ? "contet-width-collapse" : "content-width-expanded"}`}>
508
523
  {React.Children.toArray(this.props.children)}
509
524
  </div>
510
- </div>
525
+ </MainWrapper>
511
526
  </div>
512
527
  {(toastMessages && toastMessages.length > 0) &&
513
528
  toastMessages.map((message) => {
@@ -11,7 +11,6 @@ export default css`
11
11
  .component-wrapper {
12
12
  ${(props) => props.isFullMode ? `
13
13
  max-width: 1140px;
14
- margin: 0 auto;
15
14
  width: 100%;
16
15
  padding: ${CAP_SPACE_24} 0;
17
16
  .ant-tabs-content{