@capillarytech/creatives-library 8.0.282-alpha.1 → 8.0.283
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
|
@@ -47,6 +47,17 @@ import TestAndPreviewSlidebox from '../../../v2Components/TestAndPreviewSlidebox
|
|
|
47
47
|
const PrefixWrapper = styled.div`
|
|
48
48
|
margin-right: 16px;
|
|
49
49
|
`;
|
|
50
|
+
|
|
51
|
+
const safeParseDeeplinkConfig = (value) => {
|
|
52
|
+
if (!value || typeof value !== 'string') return [];
|
|
53
|
+
try {
|
|
54
|
+
const parsed = JSON.parse(value);
|
|
55
|
+
return Array.isArray(parsed) ? parsed : [];
|
|
56
|
+
} catch {
|
|
57
|
+
return [];
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
|
|
50
61
|
export class Edit extends React.Component { // eslint-disable-line react/prefer-stateless-function
|
|
51
62
|
constructor(props) {
|
|
52
63
|
super(props);
|
|
@@ -96,11 +107,12 @@ export class Edit extends React.Component { // eslint-disable-line react/prefer-
|
|
|
96
107
|
if (!_.isEmpty(this.state.schema)) {
|
|
97
108
|
this.injectEvents(this.state.schema);
|
|
98
109
|
}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
110
|
+
const templateId = get(this, "props.params.id");
|
|
111
|
+
const hasTemplateData = !_.isEmpty(this.props.templateData);
|
|
112
|
+
if (this.props.location?.query && (templateId || hasTemplateData)) {
|
|
113
|
+
if (templateId && templateId !== 'temp') {
|
|
102
114
|
this.props.actions.getTemplateDetails(templateId);
|
|
103
|
-
} else {
|
|
115
|
+
} else if (hasTemplateData) {
|
|
104
116
|
this.props.actions.setTemplateDetails(this.props.templateData);
|
|
105
117
|
}
|
|
106
118
|
}
|
|
@@ -176,7 +188,9 @@ export class Edit extends React.Component { // eslint-disable-line react/prefer-
|
|
|
176
188
|
this.props.actions.getMobilepushTemplatesList('mobilepush', params);
|
|
177
189
|
}
|
|
178
190
|
if (nextProps.metaEntities && nextProps.metaEntities.layouts && nextProps.metaEntities.layouts.length > 0 && _.isEmpty(this.state.fullSchema)) {
|
|
179
|
-
|
|
191
|
+
const definition = nextProps.metaEntities.layouts[0].definition;
|
|
192
|
+
const initialSchema = definition?.textSchema || definition?.imageSchema || {};
|
|
193
|
+
this.setState({fullSchema: definition, schema: initialSchema}, () => {
|
|
180
194
|
// Use this.props (latest) in callback to avoid race: templateDetails may have arrived by now
|
|
181
195
|
const latestSelectedAccount = this.getSelectedWeChatAccountFromProps(this.props);
|
|
182
196
|
this.handleEditSchemaOnPropsChange(this.props, latestSelectedAccount);
|
|
@@ -240,7 +254,10 @@ export class Edit extends React.Component { // eslint-disable-line react/prefer-
|
|
|
240
254
|
newFormData[this.state.currentTab - 1][`secondary-cta-${this.state.currentTab - 1}-action2`] = get(templateCta, 'ctaTemplateDetails[1].buttonText');
|
|
241
255
|
}
|
|
242
256
|
}
|
|
243
|
-
|
|
257
|
+
const newAccount = newFormData["mobilepush-accounts"];
|
|
258
|
+
const currentAccount = this.state.formData["mobilepush-accounts"];
|
|
259
|
+
const isExplicitAccountChange = newAccount !== undefined && newAccount !== currentAccount;
|
|
260
|
+
if (isExplicitAccountChange) {
|
|
244
261
|
this.setMobilePushAccountOptions(this.props.Edit.weCrmAccounts, newFormData["mobilepush-accounts"]);
|
|
245
262
|
delete newFormData['mobilepush-template'];
|
|
246
263
|
delete newFormData['template-name'];
|
|
@@ -250,6 +267,8 @@ export class Edit extends React.Component { // eslint-disable-line react/prefer-
|
|
|
250
267
|
if (!_.isEmpty(newFormData[1])) {
|
|
251
268
|
delete newFormData[1];
|
|
252
269
|
}
|
|
270
|
+
} else if (newAccount === undefined && currentAccount !== undefined) {
|
|
271
|
+
newFormData["mobilepush-accounts"] = currentAccount;
|
|
253
272
|
}
|
|
254
273
|
if (this.state.isSchemaChanged) {
|
|
255
274
|
this.setState({isSchemaChanged: false});
|
|
@@ -281,7 +300,7 @@ export class Edit extends React.Component { // eslint-disable-line react/prefer-
|
|
|
281
300
|
if (isEmbeddedEditOrPreview(queryType, mode)) {
|
|
282
301
|
selectedWeChatAccount = !_.isEmpty(editSelectedWeChatAccount)
|
|
283
302
|
? editSelectedWeChatAccount
|
|
284
|
-
: templateSelectedWeChatAccount;
|
|
303
|
+
: (templateSelectedWeChatAccount || {});
|
|
285
304
|
} else if (!_.isEmpty(templateSelectedWeChatAccount)) {
|
|
286
305
|
selectedWeChatAccount = templateSelectedWeChatAccount;
|
|
287
306
|
}
|
|
@@ -296,7 +315,7 @@ export class Edit extends React.Component { // eslint-disable-line react/prefer-
|
|
|
296
315
|
const id = field.id;
|
|
297
316
|
const fieldIndex = findIndex(inputFields, {identifier: id});
|
|
298
317
|
const ck = selectedWeChatAccount?.configs ? !!selectedWeChatAccount.configs.deeplink : false;
|
|
299
|
-
const deepLinkOptions = _.map(
|
|
318
|
+
const deepLinkOptions = _.map(safeParseDeeplinkConfig(ck ? selectedWeChatAccount.configs.deeplink : '[]'), (link) => ({label: link.name, value: link.link, title: link.link }) );
|
|
300
319
|
// let inputId = deeplinkValue && deeplinkValue.toLowerCase() === "deeplink" ? `${id}-select` : `${id}-text`;
|
|
301
320
|
// if (field.id === "cta-deeplink-secondary-cta-1" && (tabIndex > 1 || this.state.currentTab > 1)) {
|
|
302
321
|
// inputId = `${inputId}${tabIndex || this.state.currentTab}`;
|
|
@@ -668,7 +687,7 @@ export class Edit extends React.Component { // eslint-disable-line react/prefer-
|
|
|
668
687
|
getLinkName = (link) => {
|
|
669
688
|
const selectedWeChatAccount = this.getWeChatAccount();
|
|
670
689
|
const ck = selectedWeChatAccount?.configs ? !!selectedWeChatAccount.configs.deeplink : false;
|
|
671
|
-
const deepLinkOptions = _.filter(
|
|
690
|
+
const deepLinkOptions = _.filter(safeParseDeeplinkConfig(ck ? selectedWeChatAccount.configs.deeplink : '[]'), (l) => l.link === link);
|
|
672
691
|
if (deepLinkOptions[0]) {
|
|
673
692
|
return deepLinkOptions[0].name;
|
|
674
693
|
}
|
|
@@ -766,6 +785,7 @@ export class Edit extends React.Component { // eslint-disable-line react/prefer-
|
|
|
766
785
|
|
|
767
786
|
|
|
768
787
|
setEditState(data, schema) {
|
|
788
|
+
if (!data?.versions?.base || typeof data.versions.base !== 'object') return;
|
|
769
789
|
const tabCount = Object.keys(data.versions.base).length;
|
|
770
790
|
const formData = {};
|
|
771
791
|
if (this.props.location.query.type === 'embedded' && this.props.location.query.module === "loyalty") {
|
|
@@ -1115,7 +1135,7 @@ export class Edit extends React.Component { // eslint-disable-line react/prefer-
|
|
|
1115
1135
|
const schema = inputSchema ? _.cloneDeep(inputSchema) : _.cloneDeep(this.state.schema);
|
|
1116
1136
|
const selectedWeChatAccount = this.getWeChatAccount();
|
|
1117
1137
|
const ck = selectedWeChatAccount?.configs ? !!selectedWeChatAccount.configs.deeplink : false;
|
|
1118
|
-
const deepLinkOptions = _.map(
|
|
1138
|
+
const deepLinkOptions = _.map(safeParseDeeplinkConfig(ck ? selectedWeChatAccount.configs.deeplink : '[]'), (link) => ({label: link.name, value: link.link, title: link.link }) );
|
|
1119
1139
|
|
|
1120
1140
|
const inputFields = get(schema, `containers[0].panes[${currentTab - 1}].sections[0].childSections[0].childSections[0].inputFields`);
|
|
1121
1141
|
forEach(inputFields, (inputField, fieldIndex) => {
|
|
@@ -1267,7 +1287,7 @@ export class Edit extends React.Component { // eslint-disable-line react/prefer-
|
|
|
1267
1287
|
}
|
|
1268
1288
|
if (child.inputFields[fieldIndex] && child.inputFields[fieldIndex].id === "cta-deeplink-select-section") {
|
|
1269
1289
|
const ck = selectedWeChatAccount?.configs ? !!selectedWeChatAccount.configs.deeplink : false;
|
|
1270
|
-
const configkeys = selectedWeChatAccount ? _.filter(
|
|
1290
|
+
const configkeys = selectedWeChatAccount ? _.filter(safeParseDeeplinkConfig(ck ? selectedWeChatAccount.configs.deeplink : '[]'), (dl) => dl.link === selectedDeeplink) : [];
|
|
1271
1291
|
if (configkeys.length) {
|
|
1272
1292
|
const options = configkeys[0].keys;
|
|
1273
1293
|
_.forEach(options, (opt) => {
|
|
@@ -1379,7 +1399,7 @@ export class Edit extends React.Component { // eslint-disable-line react/prefer-
|
|
|
1379
1399
|
}
|
|
1380
1400
|
if (child.inputFields[fieldIndex] && child.inputFields[fieldIndex].id === "cta-deeplink-select-section") {
|
|
1381
1401
|
const ck = selectedWeChatAccount?.configs ? !!selectedWeChatAccount.configs.deeplink : false;
|
|
1382
|
-
const configkeys = selectedWeChatAccount ? _.filter(
|
|
1402
|
+
const configkeys = selectedWeChatAccount ? _.filter(safeParseDeeplinkConfig(ck ? selectedWeChatAccount.configs.deeplink : '[]'), (dl) => dl.link === selectedDeeplink) : [];
|
|
1383
1403
|
|
|
1384
1404
|
if (configkeys.length) {
|
|
1385
1405
|
const options = configkeys[0].keys;
|
|
@@ -1733,7 +1753,7 @@ export class Edit extends React.Component { // eslint-disable-line react/prefer-
|
|
|
1733
1753
|
const fieldIndex = findIndex(inputFields, {identifier: id});
|
|
1734
1754
|
const formDataKey = id.replace("-show-keys", "");
|
|
1735
1755
|
const ck = selectedWeChatAccount?.configs ? !!selectedWeChatAccount.configs.deeplink : false;
|
|
1736
|
-
let keys = selectedWeChatAccount ? _.filter(
|
|
1756
|
+
let keys = selectedWeChatAccount ? _.filter(safeParseDeeplinkConfig(ck ? selectedWeChatAccount.configs.deeplink : '[]'), (dl) => dl.link === formData[currentTab - 1][formDataKey]) : [];
|
|
1737
1757
|
if (keys[0]) {
|
|
1738
1758
|
keys = keys[0].keys;
|
|
1739
1759
|
}
|
|
@@ -1763,7 +1783,7 @@ export class Edit extends React.Component { // eslint-disable-line react/prefer-
|
|
|
1763
1783
|
inputFields.splice(fieldIndex + index + 1, 0, row);
|
|
1764
1784
|
});
|
|
1765
1785
|
if (!tabIndex) { // removes the existing selected options keys so that newly selected options keys can be added.
|
|
1766
|
-
const configkeys = _.filter(
|
|
1786
|
+
const configkeys = _.filter(safeParseDeeplinkConfig(ck ? selectedWeChatAccount.configs.deeplink : '[]'), (dl) => dl.link === this.state.formData[currentTab - 1][field.id]);
|
|
1767
1787
|
if (configkeys.length) {
|
|
1768
1788
|
const options = configkeys[0].keys;
|
|
1769
1789
|
inputFields = inputFields.slice(0, fieldIndex + 1).concat(inputFields.slice(fieldIndex + options.length + 1, inputFields.length));
|
|
@@ -1783,7 +1803,7 @@ export class Edit extends React.Component { // eslint-disable-line react/prefer-
|
|
|
1783
1803
|
const id = field.id;
|
|
1784
1804
|
const schema = inputSchema ? _.cloneDeep(inputSchema) : _.cloneDeep(this.state.schema);
|
|
1785
1805
|
const ck = selectedWeChatAccount?.configs ? !!selectedWeChatAccount.configs.deeplink : false;
|
|
1786
|
-
const deepLinkOptions = selectedWeChatAccount ? _.map(
|
|
1806
|
+
const deepLinkOptions = selectedWeChatAccount ? _.map(safeParseDeeplinkConfig(ck ? selectedWeChatAccount?.configs?.deeplink : '[]'), (link) => ({label: link.name, value: link.link, title: link.link }) ) : [];
|
|
1787
1807
|
// const eventsMap = _.cloneDeep(this.state.eventsMap);
|
|
1788
1808
|
const tabIndex = currentTab || this.state.currentTab;
|
|
1789
1809
|
const inputFields = get(schema, `containers[0].panes[${tabIndex - 1}].sections[0].childSections[0].childSections[0].inputFields`);
|
|
@@ -1814,7 +1834,7 @@ export class Edit extends React.Component { // eslint-disable-line react/prefer-
|
|
|
1814
1834
|
const schema = inputSchema ? _.cloneDeep(inputSchema) : _.cloneDeep(this.state.schema);
|
|
1815
1835
|
const selectedWeChatAccount = this.getWeChatAccount();
|
|
1816
1836
|
const ck = selectedWeChatAccount?.configs ? !!selectedWeChatAccount.configs.deeplink : false;
|
|
1817
|
-
const deepLinkOptions = selectedWeChatAccount ? _.map(
|
|
1837
|
+
const deepLinkOptions = selectedWeChatAccount ? _.map(safeParseDeeplinkConfig(ck ? selectedWeChatAccount.configs.deeplink : '[]'), (link) => ({label: link.name, value: link.link, title: link.link }) ) : [];
|
|
1818
1838
|
const inputFields = get(schema, `containers[0].panes[${tabIndex - 1}].sections[0].childSections[0].childSections[0].inputFields`);
|
|
1819
1839
|
const fieldIndex = findIndex(inputFields, {identifier: id});
|
|
1820
1840
|
let newInputFields;
|
|
@@ -2030,49 +2050,94 @@ export class Edit extends React.Component { // eslint-disable-line react/prefer-
|
|
|
2030
2050
|
}
|
|
2031
2051
|
|
|
2032
2052
|
handleEditSchemaOnPropsChange = (nextProps, selectedWeChatAccount) => {
|
|
2053
|
+
const templateDetails = nextProps.templateDetails || nextProps.templateData;
|
|
2033
2054
|
const queryType = String(get(this.props, 'location.query.type', ''))?.toLowerCase();
|
|
2034
2055
|
const isEmbeddedLibrary = queryType === EMBEDDED && !nextProps.isFullMode;
|
|
2035
2056
|
const canSetAccountFromTemplate =
|
|
2036
|
-
!selectedWeChatAccount &&
|
|
2037
|
-
|
|
2057
|
+
(_.isEmpty(selectedWeChatAccount) || !selectedWeChatAccount?.configs) &&
|
|
2058
|
+
templateDetails?.definition?.accountId &&
|
|
2038
2059
|
nextProps.Edit?.weCrmAccounts?.length > 0;
|
|
2039
|
-
const
|
|
2060
|
+
const hasAccountOrEmbedded =
|
|
2061
|
+
!_.isEmpty(selectedWeChatAccount) ||
|
|
2062
|
+
isEmbeddedLibrary ||
|
|
2063
|
+
canSetAccountFromTemplate ||
|
|
2064
|
+
!nextProps.isFullMode ||
|
|
2065
|
+
queryType === EMBEDDED;
|
|
2066
|
+
const hasTemplateDetails = !_.isEmpty(templateDetails);
|
|
2067
|
+
const hasEditData = !_.isEmpty(this.state.editData);
|
|
2068
|
+
const hasFullSchema = !_.isEmpty(this.state.fullSchema);
|
|
2069
|
+
const locationCheck = (this.props.location.query.type !== 'embedded' || this.props.isFullMode === false || queryType === EMBEDDED);
|
|
2040
2070
|
const canPopulateForm =
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2071
|
+
hasTemplateDetails &&
|
|
2072
|
+
!hasEditData &&
|
|
2073
|
+
hasFullSchema &&
|
|
2074
|
+
locationCheck &&
|
|
2075
|
+
hasAccountOrEmbedded;
|
|
2046
2076
|
if (canPopulateForm) {
|
|
2047
2077
|
this.props = nextProps;
|
|
2048
2078
|
if (canSetAccountFromTemplate) {
|
|
2049
|
-
this.setMobilePushAccountOptions(nextProps.Edit.weCrmAccounts,
|
|
2079
|
+
this.setMobilePushAccountOptions(nextProps.Edit.weCrmAccounts, templateDetails.definition.accountId);
|
|
2050
2080
|
}
|
|
2051
|
-
const mode =
|
|
2081
|
+
const mode = templateDetails.definition ? templateDetails.definition.mode : templateDetails.mode;
|
|
2052
2082
|
const schema = mode === "text" ? this.state.fullSchema?.textSchema : this.state.fullSchema?.imageSchema;
|
|
2053
|
-
|
|
2054
|
-
const
|
|
2083
|
+
if (!schema) return;
|
|
2084
|
+
const configs = nextProps.Templates?.selectedWeChatAccount?.configs || {};
|
|
2085
|
+
const hasExplicitConfigs = !_.isEmpty(configs) && ('android' in configs || 'ios' in configs);
|
|
2086
|
+
const isAndroidSupported = hasExplicitConfigs ? configs.android === '1' : true;
|
|
2087
|
+
const isIosSupported = hasExplicitConfigs ? configs.ios === '1' : true;
|
|
2055
2088
|
if (!isAndroidSupported) {
|
|
2056
2089
|
const androidField = get(schema, "containers[0].panes[0]");
|
|
2057
|
-
androidField
|
|
2058
|
-
|
|
2059
|
-
|
|
2090
|
+
if (androidField) {
|
|
2091
|
+
androidField.isSupported = false;
|
|
2092
|
+
this.setState({currentTab: 2});
|
|
2093
|
+
set(schema, "containers[0].panes[0]", androidField);
|
|
2094
|
+
}
|
|
2060
2095
|
}
|
|
2061
2096
|
if (!isIosSupported) {
|
|
2062
2097
|
const iosField = get(schema, "containers[0].panes[1]");
|
|
2063
|
-
iosField
|
|
2064
|
-
|
|
2065
|
-
|
|
2098
|
+
if (iosField) {
|
|
2099
|
+
iosField.isSupported = false;
|
|
2100
|
+
set(schema, "containers[0].panes[1]", iosField);
|
|
2101
|
+
}
|
|
2066
2102
|
}
|
|
2067
|
-
this.
|
|
2068
|
-
|
|
2103
|
+
const dataToUse = this.normalizeTemplateDataForEdit(templateDetails);
|
|
2104
|
+
if (dataToUse?.versions?.base) {
|
|
2105
|
+
this.setEditState(dataToUse, schema);
|
|
2106
|
+
this.getTags();
|
|
2107
|
+
} else {
|
|
2108
|
+
console.warn('[MobliPushEdit] Skipped setEditState - dataToUse.versions.base missing', { dataToUse });
|
|
2109
|
+
}
|
|
2110
|
+
}
|
|
2111
|
+
};
|
|
2112
|
+
|
|
2113
|
+
normalizeTemplateDataForEdit = (data) => {
|
|
2114
|
+
if (!data) return null;
|
|
2115
|
+
if (data.versions?.base) return data;
|
|
2116
|
+
if (data.content?.versions?.base) {
|
|
2117
|
+
return { ...data, versions: data.content.versions };
|
|
2069
2118
|
}
|
|
2119
|
+
const baseContent = data.content || {};
|
|
2120
|
+
if (baseContent.ANDROID || baseContent.IOS) {
|
|
2121
|
+
return {
|
|
2122
|
+
...data,
|
|
2123
|
+
versions: { base: baseContent },
|
|
2124
|
+
name: data.name || data.templateName || '',
|
|
2125
|
+
definition: data.definition || {},
|
|
2126
|
+
mode: data.mode || data.definition?.mode || 'text',
|
|
2127
|
+
};
|
|
2128
|
+
}
|
|
2129
|
+
return data;
|
|
2070
2130
|
}
|
|
2071
2131
|
|
|
2072
2132
|
render() {
|
|
2133
|
+
const queryType = String(get(this.props, 'location.query.type', ''))?.toLowerCase();
|
|
2134
|
+
const isEmbeddedOrLibrary = queryType === 'embedded' || this.props.isFullMode === false;
|
|
2135
|
+
const hasFormContent = !_.isEmpty(this.state.formData) && !_.isEmpty(this.state.schema);
|
|
2136
|
+
const showFormBuilder = !this.props.isLoadingMetaEntities || hasFormContent;
|
|
2073
2137
|
const schema = this.state.schema;
|
|
2074
2138
|
const loadingContentEdit = this.state.loadingContentEdit || (this.props.location.query.module === 'dvs' && _.isEmpty(this.state.schema));
|
|
2075
|
-
const
|
|
2139
|
+
const metaEntitiesBlockSpinner = hasFormContent;
|
|
2140
|
+
const spinning = get(this.props, "Edit.fetchingWeCrmAccounts") || (!metaEntitiesBlockSpinner && this.props.isLoadingMetaEntities) || loadingContentEdit || this.props.Edit.fetchingDefaultTemplates || this.props.Edit.assetUploading || this.state.loading || (this.props.Edit && (("getTemplateDetailsInProgress" in this.props.Edit && this.props.Edit.getTemplateDetailsInProgress) || ("editTemplateInProgress" in this.props.Edit && this.props.Edit.editTemplateInProgress)));
|
|
2076
2141
|
let tags = this.props.metaEntities && this.props.metaEntities.tags ? this.props.metaEntities.tags.standard : [];
|
|
2077
2142
|
if (this.props.supportedTags) {
|
|
2078
2143
|
tags = this.props.supportedTags;
|
|
@@ -2082,7 +2147,11 @@ export class Edit extends React.Component { // eslint-disable-line react/prefer-
|
|
|
2082
2147
|
<CapSpin spinning={spinning}>
|
|
2083
2148
|
<CapRow>
|
|
2084
2149
|
<CapColumn>
|
|
2085
|
-
{
|
|
2150
|
+
{(() => {
|
|
2151
|
+
if (isEmbeddedOrLibrary && !showFormBuilder && hasFormContent) {
|
|
2152
|
+
console.warn('[MobliPushEdit] FormBuilder HIDDEN (isLoadingMetaEntities=true) but formData+schema exist');
|
|
2153
|
+
}
|
|
2154
|
+
return showFormBuilder && <FormBuilder
|
|
2086
2155
|
channel={MOBILE_PUSH}
|
|
2087
2156
|
schema={schema}
|
|
2088
2157
|
showLiquidErrorInFooter={this.props.showLiquidErrorInFooter}
|
|
@@ -2117,7 +2186,8 @@ export class Edit extends React.Component { // eslint-disable-line react/prefer-
|
|
|
2117
2186
|
hideTestAndPreviewBtn={this.props.hideTestAndPreviewBtn}
|
|
2118
2187
|
isFullMode={this.props.isFullMode}
|
|
2119
2188
|
eventContextTags={this.props?.eventContextTags}
|
|
2120
|
-
|
|
2189
|
+
/>;
|
|
2190
|
+
})()}
|
|
2121
2191
|
</CapColumn>
|
|
2122
2192
|
{this.props.iosCtasData && this.state.showIosCtaTable &&
|
|
2123
2193
|
<CapSlideBox
|