@capillarytech/creatives-library 7.7.24 → 7.7.26
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 +5 -1
- package/package.json +1 -1
- package/translations/en.json +3 -0
- package/translations/zh.json +3 -0
- package/v2Components/NavigationBar/index.js +63 -29
- package/v2Components/NavigationBar/messages.js +5 -0
- package/v2Containers/App/constants.js +23 -3
- package/v2Containers/Cap/actions.js +2 -2
- package/v2Containers/Cap/constants.js +3 -2
- package/v2Containers/Cap/index.js +18 -18
- package/v2Containers/Cap/messages.js +8 -0
- package/v2Containers/Cap/sagas.js +18 -6
- package/v2Containers/CapFacebookPreview/constants.js +4 -0
- package/v2Containers/CapFacebookPreview/index.js +92 -67
- package/v2Containers/CapFacebookPreview/reducer.js +19 -10
- package/v2Containers/Line/Container/Drawer/index.js +1 -1
- package/v2Containers/TemplatesV2/index.js +6 -3
package/app.js
CHANGED
|
@@ -102,7 +102,11 @@ export const BugsnagClient = Bugsnag;
|
|
|
102
102
|
const rootRoute = {
|
|
103
103
|
component: (props) => {
|
|
104
104
|
// eslint-disable-next-line react/prop-types
|
|
105
|
-
if (
|
|
105
|
+
if (
|
|
106
|
+
props.location.pathname === 'v2' ||
|
|
107
|
+
props.location.pathname === 'v2/' ||
|
|
108
|
+
props.location.pathname === 'v2/loyalty'
|
|
109
|
+
) {
|
|
106
110
|
return <CapV2 {...props} />;
|
|
107
111
|
}
|
|
108
112
|
return <Cap {...props} />;
|
package/package.json
CHANGED
package/translations/en.json
CHANGED
|
@@ -176,6 +176,7 @@
|
|
|
176
176
|
"creatives.componentsV2.NavigationBar.logout": "Logout",
|
|
177
177
|
"creatives.componentsV2.NavigationBar.loyaltyProgram": "Loyalty+",
|
|
178
178
|
"creatives.componentsV2.NavigationBar.memberCare": "Member Care",
|
|
179
|
+
"creatives.componentsV2.NavigationBar.noProductSetting": "There are no product settings. Organisation settings are available under profile on the right.",
|
|
179
180
|
"creatives.componentsV2.NavigationBar.orgSettings": "Organisation settings",
|
|
180
181
|
"creatives.componentsV2.NavigationBar.selectedProductDefault": "Engage+",
|
|
181
182
|
"creatives.componentsV2.NavigationBar.storeCare": "Store Care",
|
|
@@ -1698,6 +1699,8 @@
|
|
|
1698
1699
|
"creatives.containersV2.orgChangeText": "Changing from <b>{oldOrgName}</b> to <b>{newOrgName}</b> will change the organisation for applications open in other tabs as well.<br/>Do you want to make the change to <b>{newOrgName}</b>?",
|
|
1699
1700
|
"creatives.containersV2.orgChangedText": "Organization changed to",
|
|
1700
1701
|
"creatives.containersV2.orgRefreshHeading": "Org refresh",
|
|
1702
|
+
"creatives.containersV2.programs": "Programs",
|
|
1703
|
+
"creatives.containersV2.promotions": "Promotions",
|
|
1701
1704
|
"creatives.containersV2.refreshOrgText": "Refreshing this page & changing the Org from <b>{oldOrgName}</b> to <b>{newOrgName}</b>. At a time only one Org can be selected on the browser.",
|
|
1702
1705
|
"creatives.containersV2.refreshText": "Refreshing in {time}...",
|
|
1703
1706
|
"creatives.containersV2.richMedia.Create.Anyone": "Anyone",
|
package/translations/zh.json
CHANGED
|
@@ -176,6 +176,7 @@
|
|
|
176
176
|
"creatives.componentsV2.NavigationBar.logout": "",
|
|
177
177
|
"creatives.componentsV2.NavigationBar.loyaltyProgram": "",
|
|
178
178
|
"creatives.componentsV2.NavigationBar.memberCare": "",
|
|
179
|
+
"creatives.componentsV2.NavigationBar.noProductSetting": "",
|
|
179
180
|
"creatives.componentsV2.NavigationBar.orgSettings": "",
|
|
180
181
|
"creatives.componentsV2.NavigationBar.selectedProductDefault": "",
|
|
181
182
|
"creatives.componentsV2.NavigationBar.storeCare": "",
|
|
@@ -1698,6 +1699,8 @@
|
|
|
1698
1699
|
"creatives.containersV2.orgChangeText": "",
|
|
1699
1700
|
"creatives.containersV2.orgChangedText": "",
|
|
1700
1701
|
"creatives.containersV2.orgRefreshHeading": "",
|
|
1702
|
+
"creatives.containersV2.programs": "",
|
|
1703
|
+
"creatives.containersV2.promotions": "",
|
|
1701
1704
|
"creatives.containersV2.refreshOrgText": "",
|
|
1702
1705
|
"creatives.containersV2.refreshText": "",
|
|
1703
1706
|
"creatives.containersV2.richMedia.Create.Anyone": "",
|
|
@@ -10,11 +10,23 @@ import styled from 'styled-components';
|
|
|
10
10
|
import { isEmpty, forEach } from 'lodash';
|
|
11
11
|
import { loadItem } from 'services/localStorageApi';
|
|
12
12
|
import { intlShape, injectIntl } from 'react-intl';
|
|
13
|
+
import { FONT_COLOR_04 } from '@capillarytech/cap-ui-library/styled/variables';
|
|
13
14
|
import TopBar from '../TopBar';
|
|
14
15
|
import messages from './messages';
|
|
16
|
+
import { LOYALTY } from '../../v2Containers/App/constants';
|
|
17
|
+
import {
|
|
18
|
+
HELP_URL,
|
|
19
|
+
LOYALTY_HELP_URL,
|
|
20
|
+
} from '../../v2Containers/Cap/constants';
|
|
15
21
|
const PRODUCT_MASTERS = 'masters';
|
|
16
22
|
const EMBEDDED = 'embedded';
|
|
17
23
|
|
|
24
|
+
const AppWrapper = styled.div`
|
|
25
|
+
.navigation-setting-icon {
|
|
26
|
+
color: ${FONT_COLOR_04};
|
|
27
|
+
}
|
|
28
|
+
`;
|
|
29
|
+
|
|
18
30
|
const CapWrapper = styled.div`
|
|
19
31
|
position: absolute;
|
|
20
32
|
padding: 0;
|
|
@@ -34,9 +46,37 @@ const ComponentWrapper = styled.div`
|
|
|
34
46
|
class NavigationBar extends React.Component {
|
|
35
47
|
constructor(props) {
|
|
36
48
|
super(props);
|
|
37
|
-
this.state =
|
|
38
|
-
|
|
39
|
-
|
|
49
|
+
this.state = this.initializeSelectedProduct();
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
initializeSelectedProduct = () => {
|
|
53
|
+
const {location, intl: {formatMessage}} = this.props;
|
|
54
|
+
const { pathname } = location;
|
|
55
|
+
const parentModule = pathname.substring(pathname.lastIndexOf('/') + 1);
|
|
56
|
+
switch (parentModule) {
|
|
57
|
+
case LOYALTY:
|
|
58
|
+
return {
|
|
59
|
+
selectedProduct: formatMessage(messages.loyaltyProgram),
|
|
60
|
+
helpUrl: LOYALTY_HELP_URL,
|
|
61
|
+
settingsIcon: {
|
|
62
|
+
iconType: 'settings',
|
|
63
|
+
key: 'settings',
|
|
64
|
+
placement: 'bottomRight',
|
|
65
|
+
className: 'navigation-setting-icon',
|
|
66
|
+
toolTip: formatMessage(messages.noProductSetting),
|
|
67
|
+
},
|
|
68
|
+
};
|
|
69
|
+
default:
|
|
70
|
+
return {
|
|
71
|
+
selectedProduct: formatMessage(messages.selectedProductDefault),
|
|
72
|
+
helpUrl: HELP_URL,
|
|
73
|
+
settingsIcon: {
|
|
74
|
+
iconType: 'settings',
|
|
75
|
+
key: 'settings',
|
|
76
|
+
onClickHandler: this.onSettingsIconClick,
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
}
|
|
40
80
|
}
|
|
41
81
|
|
|
42
82
|
onOrgSettingsClick = () => {
|
|
@@ -57,7 +97,7 @@ class NavigationBar extends React.Component {
|
|
|
57
97
|
};
|
|
58
98
|
|
|
59
99
|
onHelpIconClick = () => {
|
|
60
|
-
const {
|
|
100
|
+
const {helpUrl} = this.state;
|
|
61
101
|
if (helpUrl) {
|
|
62
102
|
window.open(helpUrl, '_blank');
|
|
63
103
|
}
|
|
@@ -113,18 +153,17 @@ class NavigationBar extends React.Component {
|
|
|
113
153
|
return productsList;
|
|
114
154
|
};
|
|
115
155
|
|
|
116
|
-
getTopbarIcons = () =>
|
|
117
|
-
{
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
];
|
|
156
|
+
getTopbarIcons = () => {
|
|
157
|
+
const {settingsIcon} = this.state;
|
|
158
|
+
return [
|
|
159
|
+
{
|
|
160
|
+
iconType: 'help',
|
|
161
|
+
key: 'help',
|
|
162
|
+
onClickHandler: this.onHelpIconClick,
|
|
163
|
+
},
|
|
164
|
+
settingsIcon,
|
|
165
|
+
];
|
|
166
|
+
}
|
|
128
167
|
|
|
129
168
|
getDropdownMenu = () => {
|
|
130
169
|
const { formatMessage } = this.props.intl;
|
|
@@ -168,7 +207,6 @@ class NavigationBar extends React.Component {
|
|
|
168
207
|
topbarMenuData,
|
|
169
208
|
loggedIn,
|
|
170
209
|
type,
|
|
171
|
-
intl,
|
|
172
210
|
} = this.props;
|
|
173
211
|
const productsList = this.getProductsList();
|
|
174
212
|
const proxyOrgList = this.getProxyOrgList();
|
|
@@ -178,14 +216,11 @@ class NavigationBar extends React.Component {
|
|
|
178
216
|
const { selectedProduct } = this.state;
|
|
179
217
|
const customTopBarProps = {};
|
|
180
218
|
return (
|
|
181
|
-
<
|
|
219
|
+
<AppWrapper>
|
|
182
220
|
{loggedIn && type !== EMBEDDED &&
|
|
183
221
|
<TopBar
|
|
184
222
|
productsList={productsList}
|
|
185
|
-
selectedProduct={
|
|
186
|
-
selectedProduct ||
|
|
187
|
-
intl.formatMessage(messages.selectedProductDefault)
|
|
188
|
-
}
|
|
223
|
+
selectedProduct={selectedProduct}
|
|
189
224
|
handleProductChange={this.handleProductChange}
|
|
190
225
|
proxyOrgList={proxyOrgList}
|
|
191
226
|
selectedOrg={selectedOrg}
|
|
@@ -197,12 +232,12 @@ class NavigationBar extends React.Component {
|
|
|
197
232
|
{...customTopBarProps}
|
|
198
233
|
/>
|
|
199
234
|
}
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
</
|
|
235
|
+
<CapWrapper isEmbedded={type === EMBEDDED}>
|
|
236
|
+
<ComponentWrapper>
|
|
237
|
+
{React.Children.toArray(this.props.children)}
|
|
238
|
+
</ComponentWrapper>
|
|
239
|
+
</CapWrapper>
|
|
240
|
+
</AppWrapper>
|
|
206
241
|
);
|
|
207
242
|
}
|
|
208
243
|
}
|
|
@@ -214,7 +249,6 @@ NavigationBar.propTypes = {
|
|
|
214
249
|
changeOrg: PropTypes.func,
|
|
215
250
|
settingsUrl: PropTypes.string,
|
|
216
251
|
children: PropTypes.node,
|
|
217
|
-
helpUrl: PropTypes.string,
|
|
218
252
|
orgSettingsUrl: PropTypes.string,
|
|
219
253
|
loggedIn: PropTypes.bool,
|
|
220
254
|
intl: intlShape.isRequired,
|
|
@@ -57,4 +57,9 @@ export default defineMessages({
|
|
|
57
57
|
id: `${scope}.storeCare`,
|
|
58
58
|
defaultMessage: 'Store Care',
|
|
59
59
|
},
|
|
60
|
+
"noProductSetting": {
|
|
61
|
+
id: `${scope}.noProductSetting`,
|
|
62
|
+
defaultMessage:
|
|
63
|
+
'There are no product settings. Organisation settings are available under profile on the right.',
|
|
64
|
+
},
|
|
60
65
|
});
|
|
@@ -13,6 +13,25 @@ export const getTopbarMenuDataValue = () => ([
|
|
|
13
13
|
{ label: <FormattedMessage {...globalMessages.creatives} />, link: '/creatives/ui/v2', key: 'creatives' },
|
|
14
14
|
]);
|
|
15
15
|
|
|
16
|
+
export const getLoyaltyTopbarMenuDataValue = () => [
|
|
17
|
+
{
|
|
18
|
+
label: <FormattedMessage {...globalMessages.programs} />,
|
|
19
|
+
link: 'loyalty/ui/',
|
|
20
|
+
key: 'programs',
|
|
21
|
+
},
|
|
22
|
+
//commented as promotions are not supported in loyalty v2 flow
|
|
23
|
+
// {
|
|
24
|
+
// label: <FormattedMessage {...globalMessages.promotions} />,
|
|
25
|
+
// link: 'loyalty/ui/promotions/',
|
|
26
|
+
// key: 'promotions',
|
|
27
|
+
// },
|
|
28
|
+
{
|
|
29
|
+
label: <FormattedMessage {...globalMessages.creatives} />,
|
|
30
|
+
link: '/creatives/ui/v2/loyalty',
|
|
31
|
+
key: 'creatives',
|
|
32
|
+
},
|
|
33
|
+
];
|
|
34
|
+
|
|
16
35
|
export const TRACK_CREATE_SMS = 'createSms';
|
|
17
36
|
export const TRACK_CREATE_EMAIL = 'createEmail';
|
|
18
37
|
export const TRACK_CREATE_MPUSH = 'createMpush';
|
|
@@ -46,7 +65,7 @@ export const CHANNEL_CREATE_TRACK_MAPPING = {
|
|
|
46
65
|
gallery: TRACK_CREATE_IMAGE,
|
|
47
66
|
line: TRACK_CREATE_LINE,
|
|
48
67
|
viber: TRACK_CREATE_VIBER,
|
|
49
|
-
facebook: TRACK_CREATE_FACEBOOK
|
|
68
|
+
facebook: TRACK_CREATE_FACEBOOK,
|
|
50
69
|
};
|
|
51
70
|
|
|
52
71
|
export const CHANNEL_EDIT_TRACK_MAPPING = {
|
|
@@ -57,7 +76,7 @@ export const CHANNEL_EDIT_TRACK_MAPPING = {
|
|
|
57
76
|
gallery: TRACK_EDIT_IMAGE,
|
|
58
77
|
line: TRACK_EDIT_LINE,
|
|
59
78
|
viber: TRACK_EDIT_VIBER,
|
|
60
|
-
facebook: TRACK_EDIT_FACEBOOK
|
|
79
|
+
facebook: TRACK_EDIT_FACEBOOK,
|
|
61
80
|
};
|
|
62
81
|
export const GTM_TRACKING_ID = 'UA-110024621-2';
|
|
63
82
|
export const BEE_PLUGIN = 'BEE_PLUGIN';
|
|
@@ -85,4 +104,5 @@ export const FB_AD_CALL_TO_ACTION = {
|
|
|
85
104
|
};
|
|
86
105
|
|
|
87
106
|
|
|
88
|
-
export const CREATIVES = 'creatives';
|
|
107
|
+
export const CREATIVES = 'creatives';
|
|
108
|
+
export const LOYALTY = 'loyalty';
|
|
@@ -45,7 +45,6 @@ export function getUserData(callback) {
|
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
export function fetchSchemaForEntity(queryParams) {
|
|
48
|
-
|
|
49
48
|
return {
|
|
50
49
|
type: types.GET_SCHEMA_FOR_ENTITY_REQUEST, queryParams,
|
|
51
50
|
};
|
|
@@ -62,8 +61,9 @@ export function setInjectedTags(injectedTags) {
|
|
|
62
61
|
};
|
|
63
62
|
}
|
|
64
63
|
|
|
65
|
-
export function getTopbarMenuData() {
|
|
64
|
+
export function getTopbarMenuData(parentModule) {
|
|
66
65
|
return {
|
|
66
|
+
parentModule,
|
|
67
67
|
type: types.GET_TOPBAR_MENU_DATA_REQUEST,
|
|
68
68
|
};
|
|
69
69
|
}
|
|
@@ -31,7 +31,8 @@ export const CLEAR_TOPBAR_MENU_DATA = 'creatives/cap/CLEAR_TOPBAR_MENU_DATA';
|
|
|
31
31
|
export const CAMPAIGN_SETTINGS_URL = '/creatives/settings/message';
|
|
32
32
|
export const ORG_SETTINGS_URL = '/org/index';
|
|
33
33
|
export const HELP_URL = 'https://support.capillarytech.com/en/support/solutions/4000007853';
|
|
34
|
+
export const LOYALTY_HELP_URL = 'https://support.capillarytech.com/en/support/solutions/97443';
|
|
34
35
|
|
|
35
|
-
export const ORG_REFRESH_SEC = 10;
|
|
36
|
-
export const ORG_CHANGED = 'ORG_CHANGED';
|
|
36
|
+
export const ORG_REFRESH_SEC = 10;
|
|
37
|
+
export const ORG_CHANGED = 'ORG_CHANGED';
|
|
37
38
|
|
|
@@ -22,11 +22,10 @@ import { engagePlusPublicPath } from '../../config/path';
|
|
|
22
22
|
import { GTM_TRACKING_ID, CREATIVES_UI_VIEW } from '../App/constants';
|
|
23
23
|
import { makeSelectLocale } from '../../v2Containers/LanguageProvider/selectors';
|
|
24
24
|
import {
|
|
25
|
-
HELP_URL,
|
|
26
25
|
ORG_SETTINGS_URL,
|
|
27
26
|
CAMPAIGN_SETTINGS_URL,
|
|
28
27
|
ORG_REFRESH_SEC,
|
|
29
|
-
ORG_CHANGED
|
|
28
|
+
ORG_CHANGED,
|
|
30
29
|
} from './constants';
|
|
31
30
|
import './_cap.scss';
|
|
32
31
|
|
|
@@ -73,6 +72,8 @@ export class Cap extends React.Component { // eslint-disable-line react/prefer-s
|
|
|
73
72
|
}
|
|
74
73
|
|
|
75
74
|
componentWillMount() {
|
|
75
|
+
const { pathname } = this.props.location;
|
|
76
|
+
const parentModule = pathname.substring(pathname.lastIndexOf('/') + 1);
|
|
76
77
|
this.props.actions.getUserData((userData) => {
|
|
77
78
|
if (!userData.accessiblePermissions.includes(CREATIVES_UI_VIEW)) {
|
|
78
79
|
this.setState({ isCreativesAccessible: false });
|
|
@@ -81,7 +82,7 @@ export class Cap extends React.Component { // eslint-disable-line react/prefer-s
|
|
|
81
82
|
this.setDimensionData(userGtmData);
|
|
82
83
|
gtm.push({...userGtmData, event: 'userAuthenticated'});
|
|
83
84
|
});
|
|
84
|
-
this.props.actions.getTopbarMenuData();
|
|
85
|
+
this.props.actions.getTopbarMenuData(parentModule);
|
|
85
86
|
if (this.props.Global.orgID !== undefined) {
|
|
86
87
|
gtm.push({orgId: this.props.Global.orgID});
|
|
87
88
|
}
|
|
@@ -101,7 +102,7 @@ export class Cap extends React.Component { // eslint-disable-line react/prefer-s
|
|
|
101
102
|
}
|
|
102
103
|
locale = this.getMappedLocale(locale);
|
|
103
104
|
//locale = 'zh';
|
|
104
|
-
|
|
105
|
+
|
|
105
106
|
moment.locale(locale);
|
|
106
107
|
window.addEventListener('storage', this.handleStorageChange, false);
|
|
107
108
|
document.addEventListener(
|
|
@@ -167,7 +168,7 @@ export class Cap extends React.Component { // eslint-disable-line react/prefer-s
|
|
|
167
168
|
tabOnloadEventHandler = () => {
|
|
168
169
|
logNewTab();
|
|
169
170
|
}
|
|
170
|
-
|
|
171
|
+
|
|
171
172
|
setDimensionData(userGtmData) {
|
|
172
173
|
Object.values(userGtmData).forEach((value, index) => {
|
|
173
174
|
GA.setCustomDimension({ [`dimension${index + 1}`]: value });
|
|
@@ -175,23 +176,23 @@ export class Cap extends React.Component { // eslint-disable-line react/prefer-s
|
|
|
175
176
|
}
|
|
176
177
|
getUserGtmData(props) {
|
|
177
178
|
const selectedProps = props || this.props;
|
|
178
|
-
const { user: userData,
|
|
179
|
+
const { user: userData, orgID} = selectedProps?.Global || {};
|
|
179
180
|
if (userData) {
|
|
180
181
|
const {
|
|
181
182
|
attributes: {
|
|
182
|
-
USERNAME
|
|
183
|
-
EMAIL
|
|
183
|
+
USERNAME: userName,
|
|
184
|
+
EMAIL: userEmail,
|
|
184
185
|
} = {},
|
|
185
|
-
proxyOrgList =[],
|
|
186
|
+
proxyOrgList = [],
|
|
186
187
|
isCapUser,
|
|
187
188
|
refID,
|
|
188
189
|
orgName: userOrgName,
|
|
189
190
|
} = userData;
|
|
190
|
-
const { orgName } = _.find(proxyOrgList, { orgID
|
|
191
|
+
const { orgName } = _.find(proxyOrgList, { orgID }) || {
|
|
191
192
|
orgName: userOrgName,
|
|
192
193
|
};
|
|
193
194
|
const gtmData = {
|
|
194
|
-
isCapUser
|
|
195
|
+
isCapUser,
|
|
195
196
|
orgId: orgID,
|
|
196
197
|
orgName,
|
|
197
198
|
userId: refID,
|
|
@@ -272,7 +273,7 @@ export class Cap extends React.Component { // eslint-disable-line react/prefer-s
|
|
|
272
273
|
refreshSeconds === ORG_REFRESH_SEC
|
|
273
274
|
) {
|
|
274
275
|
const timer = setInterval(() => {
|
|
275
|
-
this.setState(prevState => ({
|
|
276
|
+
this.setState((prevState) => ({
|
|
276
277
|
refreshSeconds: prevState.refreshSeconds - 1,
|
|
277
278
|
}));
|
|
278
279
|
}, 1000);
|
|
@@ -286,13 +287,13 @@ export class Cap extends React.Component { // eslint-disable-line react/prefer-s
|
|
|
286
287
|
|
|
287
288
|
handleStorageChange = (e) => {
|
|
288
289
|
const { oldValue, newValue } = e;
|
|
289
|
-
|
|
290
|
+
if (utilsHandleStorageChange(e, 'orgID')) {
|
|
290
291
|
const localStorageOrgInfo = { oldValue, newValue };
|
|
291
292
|
this.setState({ showRefreshModal: true, localStorageOrgInfo });
|
|
292
293
|
}
|
|
293
294
|
};
|
|
294
295
|
|
|
295
|
-
getOrgNameFromId = orgId => {
|
|
296
|
+
getOrgNameFromId = (orgId) => {
|
|
296
297
|
const {
|
|
297
298
|
Global: {
|
|
298
299
|
user: {
|
|
@@ -352,11 +353,11 @@ export class Cap extends React.Component { // eslint-disable-line react/prefer-s
|
|
|
352
353
|
renderOrgChangeModal = () => {
|
|
353
354
|
const { selectedOrgId, showOrgChangeModal } = this.state;
|
|
354
355
|
const {
|
|
355
|
-
Global: {
|
|
356
|
+
Global: {
|
|
356
357
|
currentOrgDetails: { basic_details: { name: oldOrgName } = {} } = {},
|
|
357
358
|
},
|
|
358
359
|
intl: { formatMessage } = {},
|
|
359
|
-
} = this.props;
|
|
360
|
+
} = this.props;
|
|
360
361
|
const newOrgName = this.getOrgNameFromId(selectedOrgId);
|
|
361
362
|
// some users do not have entry for their default org in proxyOrgList.
|
|
362
363
|
// getOrgNameFromId returns back orgID if no matching entry is present in proxyOrgList
|
|
@@ -399,7 +400,7 @@ export class Cap extends React.Component { // eslint-disable-line react/prefer-s
|
|
|
399
400
|
const type = this.props.location.query.type;
|
|
400
401
|
const toastMessages = this.props.Global.messages;
|
|
401
402
|
const { isCreativesAccessible, showOrgChangeModal, showRefreshModal } = this.state;
|
|
402
|
-
|
|
403
|
+
|
|
403
404
|
return (
|
|
404
405
|
<CapWrapper>
|
|
405
406
|
{ this.props.loader.localeLoading || this.props.Global.fetching_userdata ?
|
|
@@ -425,7 +426,6 @@ export class Cap extends React.Component { // eslint-disable-line react/prefer-s
|
|
|
425
426
|
logout={this.logout}
|
|
426
427
|
settingsUrl={`${engagePlusPublicPath}${CAMPAIGN_SETTINGS_URL}`}
|
|
427
428
|
orgSettingsUrl={ORG_SETTINGS_URL}
|
|
428
|
-
helpUrl={HELP_URL}
|
|
429
429
|
loggedIn={isLoggedIn}
|
|
430
430
|
topbarMenuData={topbarMenuDataOptions}
|
|
431
431
|
location={location}
|
|
@@ -72,6 +72,14 @@ export default defineMessages({
|
|
|
72
72
|
id: 'creatives.containersV2.incentive',
|
|
73
73
|
defaultMessage: 'Incentive',
|
|
74
74
|
},
|
|
75
|
+
"programs": {
|
|
76
|
+
id: `creatives.containersV2.programs`,
|
|
77
|
+
defaultMessage: 'Programs',
|
|
78
|
+
},
|
|
79
|
+
"promotions": {
|
|
80
|
+
id: `creatives.containersV2.promotions`,
|
|
81
|
+
defaultMessage: 'Promotions',
|
|
82
|
+
},
|
|
75
83
|
|
|
76
84
|
//refresh due to org change messages
|
|
77
85
|
|
|
@@ -6,7 +6,11 @@ import * as LocalStorage from '../../services/localStorageApi';
|
|
|
6
6
|
import * as types from './constants';
|
|
7
7
|
import config from '../../config/app';
|
|
8
8
|
//import pathConfig from '../../config/path';
|
|
9
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
getTopbarMenuDataValue,
|
|
11
|
+
getLoyaltyTopbarMenuDataValue,
|
|
12
|
+
LOYALTY,
|
|
13
|
+
} from '../../v2Containers/App/constants';
|
|
10
14
|
// import {makeSelectOrgId} from './selectors';
|
|
11
15
|
|
|
12
16
|
function* authorize(user) {
|
|
@@ -106,9 +110,8 @@ export function* fetchUserInfo(option) {
|
|
|
106
110
|
|
|
107
111
|
export function* fetchSchemaForEntity(queryParams) {
|
|
108
112
|
try {
|
|
109
|
-
|
|
110
113
|
const result = yield call(Api.fetchSchemaForEntity, queryParams);
|
|
111
|
-
|
|
114
|
+
|
|
112
115
|
// const sidebar = result.response.sidebar;
|
|
113
116
|
yield put({ type: types.GET_SCHEMA_FOR_ENTITY_SUCCESS, data: result.response, statusCode: result.status ? result.status.code : '', entityType: queryParams.queryParams.type });
|
|
114
117
|
} catch (error) {
|
|
@@ -116,11 +119,21 @@ export function* fetchSchemaForEntity(queryParams) {
|
|
|
116
119
|
}
|
|
117
120
|
}
|
|
118
121
|
|
|
119
|
-
|
|
122
|
+
const getTopbarData = (parentModule) => {
|
|
123
|
+
switch (parentModule) {
|
|
124
|
+
case LOYALTY:
|
|
125
|
+
return getLoyaltyTopbarMenuDataValue();
|
|
126
|
+
default:
|
|
127
|
+
return getTopbarMenuDataValue();
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
function* getTopbarMenuData(params) {
|
|
132
|
+
const {parentModule} = params;
|
|
120
133
|
try {
|
|
121
134
|
yield put({
|
|
122
135
|
type: types.GET_TOPBAR_MENU_DATA_SUCCESS,
|
|
123
|
-
data:
|
|
136
|
+
data: getTopbarData(parentModule),
|
|
124
137
|
});
|
|
125
138
|
} catch (error) {
|
|
126
139
|
yield put({ type: types.GET_TOPBAR_MENU_DATA_FAILURE, error });
|
|
@@ -129,7 +142,6 @@ function* getTopbarMenuData() {
|
|
|
129
142
|
|
|
130
143
|
|
|
131
144
|
function* watchFetchSchemaForEntity() {
|
|
132
|
-
|
|
133
145
|
const watcher = yield takeLatest(types.GET_SCHEMA_FOR_ENTITY_REQUEST, fetchSchemaForEntity);
|
|
134
146
|
yield take(LOCATION_CHANGE);
|
|
135
147
|
yield cancel(watcher);
|
|
@@ -11,3 +11,7 @@ export const GENERATE_PREVIEW_FAILURE = 'app/CapFacebookPreview/GET_PREVIEW_FAIL
|
|
|
11
11
|
|
|
12
12
|
export const CLEAR_PREVIEW = 'app/CapFacebookPreview/CLEAR_PREVIEW';
|
|
13
13
|
|
|
14
|
+
export const PREVIEW_NOT_REQUESTED = "PreviewNotRequested";
|
|
15
|
+
export const FETCH_PREVIEW_REQUESTED = "PreviewRequested";
|
|
16
|
+
export const FETCH_PREVIEW_SUCCESS = "PreviewRequestSuccess";
|
|
17
|
+
export const FETCH_PREVIEW_FAILURE = "PreviewRequestFailure";
|
|
@@ -30,6 +30,11 @@ import {
|
|
|
30
30
|
CAROUSEL,
|
|
31
31
|
NO_CALL_TO_ACTION,
|
|
32
32
|
} from '../../v2Containers/Facebook/Advertisement/constant';
|
|
33
|
+
import {
|
|
34
|
+
FETCH_PREVIEW_REQUESTED,
|
|
35
|
+
FETCH_PREVIEW_SUCCESS,
|
|
36
|
+
PREVIEW_NOT_REQUESTED,
|
|
37
|
+
} from './constants';
|
|
33
38
|
import './index.scss';
|
|
34
39
|
|
|
35
40
|
export const CapFacebookPreview = (props) => {
|
|
@@ -55,7 +60,10 @@ export const CapFacebookPreview = (props) => {
|
|
|
55
60
|
const [disableAfterPreviewGenerate, setDisableAfterPreviewGenerate] = useState(false);
|
|
56
61
|
const [random, setRandom] = useState(0);
|
|
57
62
|
const {pageAccessToken, pageId} = orgUnitFacebookPageSettingsMap;
|
|
58
|
-
const {previewIframe = "",
|
|
63
|
+
const {previewIframe = "", fetchPreviewStatus = PREVIEW_NOT_REQUESTED, previewIframeError = ""} = facebookPreviewData;
|
|
64
|
+
const [previewLoaded, setPreviewLoaded] = useState(false);
|
|
65
|
+
const [isRefreshing, setIsRefreshing] = useState(false);
|
|
66
|
+
let isSpinning = false;
|
|
59
67
|
const facebookAdOptions = [
|
|
60
68
|
{
|
|
61
69
|
value: "DESKTOP_FEED_STANDARD",
|
|
@@ -284,9 +292,17 @@ export const CapFacebookPreview = (props) => {
|
|
|
284
292
|
};
|
|
285
293
|
|
|
286
294
|
const resetIframe = () => {
|
|
295
|
+
previewLoaded && setPreviewLoaded(false);
|
|
296
|
+
!isRefreshing && setIsRefreshing(true);
|
|
287
297
|
const r = random + 1;
|
|
288
298
|
setRandom(r);
|
|
289
299
|
};
|
|
300
|
+
const unsetLoader = () => {
|
|
301
|
+
setTimeout(function() {
|
|
302
|
+
!previewLoaded && setPreviewLoaded(true);
|
|
303
|
+
isRefreshing && setIsRefreshing(false);
|
|
304
|
+
}.bind(this), 5000);
|
|
305
|
+
}
|
|
290
306
|
const getIframe = (iframe) => {
|
|
291
307
|
const divTag = document.createElement('div');
|
|
292
308
|
divTag.innerHTML = iframe;
|
|
@@ -295,13 +311,16 @@ export const CapFacebookPreview = (props) => {
|
|
|
295
311
|
<iframe
|
|
296
312
|
src={src}
|
|
297
313
|
key={random}
|
|
298
|
-
style={{border: "none"}}
|
|
314
|
+
style={{ border: "none" }}
|
|
299
315
|
width={"600px"}
|
|
300
316
|
scrolling="no"
|
|
301
317
|
height={"1000px"}
|
|
302
318
|
className="cap-facebook-ad-iframe"
|
|
319
|
+
onLoad={
|
|
320
|
+
unsetLoader()
|
|
321
|
+
}
|
|
303
322
|
/>
|
|
304
|
-
|
|
323
|
+
</>);
|
|
305
324
|
};
|
|
306
325
|
|
|
307
326
|
const showRefreshButton = () => {
|
|
@@ -340,74 +359,80 @@ export const CapFacebookPreview = (props) => {
|
|
|
340
359
|
}
|
|
341
360
|
}, [previewIframeError]);
|
|
342
361
|
return (
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
362
|
+
<>
|
|
363
|
+
{isSpinning = (fetchPreviewStatus === FETCH_PREVIEW_REQUESTED) ||
|
|
364
|
+
((fetchPreviewStatus === FETCH_PREVIEW_SUCCESS) && !previewLoaded) ||
|
|
365
|
+
isRefreshing}
|
|
366
|
+
<CapSpin
|
|
367
|
+
spinning={isSpinning}>
|
|
368
|
+
<div style={{ display: 'inline-block' }}>
|
|
369
|
+
<CapSelect
|
|
370
|
+
label={formatMessage(messages.previewBasedonAdPlacement)}
|
|
371
|
+
key={"select-previewBasedonAdPlacement"}
|
|
372
|
+
onChange={onChangeAdPreviewFormat}
|
|
373
|
+
style={{ width: '328px', paddingBottom: 16 }}
|
|
374
|
+
options={adOptions}
|
|
375
|
+
value={adPreviewFormat}
|
|
376
|
+
>
|
|
377
|
+
</CapSelect>
|
|
378
|
+
</div>
|
|
379
|
+
{!hideInfoText && <CapLabel
|
|
380
|
+
type="label1"
|
|
381
|
+
style={{ paddingBottom: 16, textAlign: 'left', width: 392 }}
|
|
352
382
|
>
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
383
|
+
{formatMessage(messages.previewAdDesc)}
|
|
384
|
+
</CapLabel>}
|
|
385
|
+
<div style={{ marginBottom: 16 }}>
|
|
386
|
+
{(disablePreviewButton || disableAfterPreviewGenerate) ?
|
|
387
|
+
<CapTooltip title={formatMessage(messages.generatePreviewDisableToolTip)}>
|
|
388
|
+
<div className="button-disabled-tooltip-wrapper">
|
|
389
|
+
<CapButton
|
|
390
|
+
type="secondary"
|
|
391
|
+
disabled
|
|
358
392
|
>
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
</div>
|
|
372
|
-
</CapTooltip> :
|
|
373
|
-
<CapButton
|
|
393
|
+
<FormattedMessage {...messages.generatePreview} />
|
|
394
|
+
</CapButton>
|
|
395
|
+
</div>
|
|
396
|
+
</CapTooltip> :
|
|
397
|
+
<CapButton
|
|
398
|
+
type="secondary"
|
|
399
|
+
onClick={generatePreview}
|
|
400
|
+
>
|
|
401
|
+
<FormattedMessage {...messages.generatePreview} />
|
|
402
|
+
</CapButton>}
|
|
403
|
+
{isRefreshButton && (<CapButton
|
|
404
|
+
onClick={resetIframe}
|
|
374
405
|
type="secondary"
|
|
375
|
-
|
|
406
|
+
style={{ marginLeft: 16 }}
|
|
376
407
|
>
|
|
377
|
-
|
|
378
|
-
</CapButton>}
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
</
|
|
404
|
-
|
|
405
|
-
src={facebookEmptyPlaceholder}
|
|
406
|
-
alt="default"
|
|
407
|
-
width="316px"
|
|
408
|
-
height="392px"
|
|
409
|
-
/> : getIframe(previewIframe)}
|
|
410
|
-
</CapSpin>
|
|
408
|
+
{formatMessage(messages.refreshPreview)}
|
|
409
|
+
</CapButton>)}
|
|
410
|
+
</div>
|
|
411
|
+
{isRefreshButton && <div style={{ marginBottom: 16 }}>
|
|
412
|
+
<CapIcon
|
|
413
|
+
type="info"
|
|
414
|
+
svgProps={{
|
|
415
|
+
width: 16,
|
|
416
|
+
height: 16,
|
|
417
|
+
}}
|
|
418
|
+
>
|
|
419
|
+
</CapIcon>
|
|
420
|
+
<CapLabel.CapLabelInline
|
|
421
|
+
type="label1"
|
|
422
|
+
size="s"
|
|
423
|
+
style={{ marginBottom: 16, width: 392 }}
|
|
424
|
+
>
|
|
425
|
+
{formatMessage(messages.videoNotePreview)}
|
|
426
|
+
</CapLabel.CapLabelInline>
|
|
427
|
+
</div>}
|
|
428
|
+
{previewIframe === "" ? <CapImage
|
|
429
|
+
src={facebookEmptyPlaceholder}
|
|
430
|
+
alt="default"
|
|
431
|
+
width="316px"
|
|
432
|
+
height="392px"
|
|
433
|
+
/> : getIframe(previewIframe)}
|
|
434
|
+
</CapSpin>
|
|
435
|
+
</>
|
|
411
436
|
);
|
|
412
437
|
};
|
|
413
438
|
|
|
@@ -6,29 +6,38 @@
|
|
|
6
6
|
|
|
7
7
|
import { fromJS } from 'immutable';
|
|
8
8
|
import get from 'lodash/get';
|
|
9
|
-
import
|
|
9
|
+
import {
|
|
10
|
+
GENERATE_PREVIEW_REQUEST,
|
|
11
|
+
GENERATE_PREVIEW_SUCCESS,
|
|
12
|
+
GENERATE_PREVIEW_FAILURE,
|
|
13
|
+
CLEAR_PREVIEW,
|
|
14
|
+
FETCH_PREVIEW_REQUESTED,
|
|
15
|
+
FETCH_PREVIEW_SUCCESS,
|
|
16
|
+
FETCH_PREVIEW_FAILURE,
|
|
17
|
+
PREVIEW_NOT_REQUESTED,
|
|
18
|
+
} from './constants';
|
|
10
19
|
|
|
11
20
|
const initialState = fromJS({
|
|
12
|
-
|
|
21
|
+
fetchPreviewStatus: PREVIEW_NOT_REQUESTED,
|
|
13
22
|
previewIframe: "",
|
|
14
23
|
previewIframeError: "",
|
|
15
24
|
});
|
|
16
25
|
|
|
17
26
|
function capFacebookPreviewReducer(state = initialState, action) {
|
|
18
27
|
switch (action.type) {
|
|
19
|
-
case
|
|
20
|
-
return state.set('
|
|
28
|
+
case GENERATE_PREVIEW_REQUEST:
|
|
29
|
+
return state.set('fetchPreviewStatus', FETCH_PREVIEW_REQUESTED)
|
|
21
30
|
.set('previewIframe', "")
|
|
22
31
|
.set("previewIframeError", "");
|
|
23
|
-
case
|
|
24
|
-
return state.set('
|
|
32
|
+
case GENERATE_PREVIEW_SUCCESS:
|
|
33
|
+
return state.set('fetchPreviewStatus', FETCH_PREVIEW_SUCCESS)
|
|
25
34
|
.set('previewIframe', get(action, 'payload.fbPreview[0].body', ""));
|
|
26
|
-
case
|
|
27
|
-
return state.set('
|
|
35
|
+
case GENERATE_PREVIEW_FAILURE:
|
|
36
|
+
return state.set('fetchPreviewStatus', FETCH_PREVIEW_FAILURE)
|
|
28
37
|
.set('previewIframe', "")
|
|
29
38
|
.set("previewIframeError", get(action, 'payload.message', ""));
|
|
30
|
-
case
|
|
31
|
-
return state.set('
|
|
39
|
+
case CLEAR_PREVIEW:
|
|
40
|
+
return state.set('fetchPreviewStatus', PREVIEW_NOT_REQUESTED)
|
|
32
41
|
.set('previewIframe', "")
|
|
33
42
|
.set("previewIframeError", "");
|
|
34
43
|
default:
|
|
@@ -28,7 +28,7 @@ import FTP from '../FTP';
|
|
|
28
28
|
import Gallery from '../Assets/Gallery';
|
|
29
29
|
import withStyles from '../../hoc/withStyles';
|
|
30
30
|
import styles, { CapTabStyle } from './TemplatesV2.style';
|
|
31
|
-
import { CREATIVES_UI_VIEW } from '../App/constants';
|
|
31
|
+
import { CREATIVES_UI_VIEW, LOYALTY} from '../App/constants';
|
|
32
32
|
import AccessForbidden from '../../v2Components/AccessForbidden';
|
|
33
33
|
|
|
34
34
|
const {CapCustomCardList} = CapCustomCard;
|
|
@@ -39,6 +39,9 @@ export class TemplatesV2 extends React.Component { // eslint-disable-line react/
|
|
|
39
39
|
constructor(props) {
|
|
40
40
|
super(props);
|
|
41
41
|
let defaultChannel = get(this, 'props.channel') || get(this, 'props.params.channel') || 'sms';
|
|
42
|
+
if (defaultChannel === LOYALTY) {
|
|
43
|
+
defaultChannel = 'sms';
|
|
44
|
+
}
|
|
42
45
|
const {
|
|
43
46
|
intl,
|
|
44
47
|
channelsToHide = [],
|
|
@@ -158,9 +161,9 @@ export class TemplatesV2 extends React.Component { // eslint-disable-line react/
|
|
|
158
161
|
);
|
|
159
162
|
|
|
160
163
|
getFacebookComponent = () => {
|
|
161
|
-
const { messageDetails, cap, onFacebookSubmit,
|
|
164
|
+
const { messageDetails, cap, onFacebookSubmit,
|
|
162
165
|
messageStrategy,
|
|
163
|
-
showDisabledFBInfo,
|
|
166
|
+
showDisabledFBInfo,
|
|
164
167
|
orgUnitId,
|
|
165
168
|
onSelectTemplate } = this.props;
|
|
166
169
|
return (
|