@capillarytech/creatives-library 8.0.281 → 8.0.282-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.
package/package.json
CHANGED
|
@@ -49,10 +49,16 @@ const mockGetValidationState = jest.fn(() => ({
|
|
|
49
49
|
issueCounts: { errors: 0, warnings: 0, total: 0 },
|
|
50
50
|
}));
|
|
51
51
|
|
|
52
|
+
// Ref to capture apiValidationErrors passed to HTMLEditor (for mergedApiValidationErrors tests)
|
|
53
|
+
const capturedApiValidationErrorsRef = { current: null };
|
|
54
|
+
|
|
52
55
|
// Mock HtmlEditor - it exports a lazy-loaded component by default
|
|
53
56
|
jest.mock('../../../../v2Components/HtmlEditor/index.lazy', () => {
|
|
54
57
|
const React = require('react');
|
|
55
58
|
const MockHTMLEditor = React.forwardRef((props, ref) => {
|
|
59
|
+
if (global.__captureApiValidationErrorsRef && props.apiValidationErrors) {
|
|
60
|
+
global.__captureApiValidationErrorsRef.current = props.apiValidationErrors;
|
|
61
|
+
}
|
|
56
62
|
React.useImperativeHandle(ref, () => ({
|
|
57
63
|
getAllIssues: () => mockGetAllIssues(),
|
|
58
64
|
getValidationState: () => mockGetValidationState(),
|
|
@@ -109,6 +115,9 @@ jest.mock('../../../../v2Components/HtmlEditor/index.lazy', () => {
|
|
|
109
115
|
jest.mock('../../../../v2Components/HtmlEditor', () => {
|
|
110
116
|
const React = require('react');
|
|
111
117
|
const MockHTMLEditor = React.forwardRef((props, ref) => {
|
|
118
|
+
if (global.__captureApiValidationErrorsRef && props.apiValidationErrors) {
|
|
119
|
+
global.__captureApiValidationErrorsRef.current = props.apiValidationErrors;
|
|
120
|
+
}
|
|
112
121
|
React.useImperativeHandle(ref, () => ({
|
|
113
122
|
getAllIssues: () => mockGetAllIssues(),
|
|
114
123
|
getValidationState: () => mockGetValidationState(),
|
|
@@ -421,6 +430,86 @@ describe('EmailHTMLEditor', () => {
|
|
|
421
430
|
});
|
|
422
431
|
// Reset hasLiquidSupportFeature mock to return true by default
|
|
423
432
|
mockHasLiquidSupportFeature.mockReturnValue(true);
|
|
433
|
+
capturedApiValidationErrorsRef.current = null;
|
|
434
|
+
});
|
|
435
|
+
|
|
436
|
+
describe('mergedApiValidationErrors (lines 124-125)', () => {
|
|
437
|
+
beforeEach(() => {
|
|
438
|
+
global.__captureApiValidationErrorsRef = capturedApiValidationErrorsRef;
|
|
439
|
+
});
|
|
440
|
+
|
|
441
|
+
afterEach(() => {
|
|
442
|
+
delete global.__captureApiValidationErrorsRef;
|
|
443
|
+
});
|
|
444
|
+
|
|
445
|
+
it('merges tag unsupported errors into standardErrors when tagValidationError has unsupportedTags', async () => {
|
|
446
|
+
validateTags.mockReturnValue({
|
|
447
|
+
valid: false,
|
|
448
|
+
unsupportedTags: ['tagA', 'tagB'],
|
|
449
|
+
});
|
|
450
|
+
renderWithIntl({
|
|
451
|
+
metaEntities: { tags: { standard: [{ name: 'customer.name' }] } },
|
|
452
|
+
tags: [{ name: 'customer.name' }],
|
|
453
|
+
supportedTags: [],
|
|
454
|
+
});
|
|
455
|
+
const changeButton = screen.getByTestId('trigger-content-change');
|
|
456
|
+
await act(async () => {
|
|
457
|
+
fireEvent.click(changeButton);
|
|
458
|
+
});
|
|
459
|
+
await waitFor(() => {
|
|
460
|
+
expect(capturedApiValidationErrorsRef.current).not.toBeNull();
|
|
461
|
+
expect(capturedApiValidationErrorsRef.current.liquidErrors).toEqual([]);
|
|
462
|
+
expect(capturedApiValidationErrorsRef.current.standardErrors).toContain(
|
|
463
|
+
'Unsupported tags are: tagA, tagB',
|
|
464
|
+
);
|
|
465
|
+
});
|
|
466
|
+
});
|
|
467
|
+
|
|
468
|
+
it('merges tag missing errors into standardErrors when tagValidationError has missingTags and unsubscribe not mandatory', async () => {
|
|
469
|
+
isEmailUnsubscribeTagMandatory.mockReturnValue(false);
|
|
470
|
+
validateTags.mockReturnValue({
|
|
471
|
+
valid: false,
|
|
472
|
+
missingTags: ['unsubscribe'],
|
|
473
|
+
});
|
|
474
|
+
renderWithIntl({
|
|
475
|
+
metaEntities: { tags: { standard: [{ name: 'customer.name' }] } },
|
|
476
|
+
tags: [{ name: 'customer.name' }],
|
|
477
|
+
supportedTags: [],
|
|
478
|
+
});
|
|
479
|
+
const changeButton = screen.getByTestId('trigger-content-change');
|
|
480
|
+
await act(async () => {
|
|
481
|
+
fireEvent.click(changeButton);
|
|
482
|
+
});
|
|
483
|
+
await waitFor(() => {
|
|
484
|
+
expect(capturedApiValidationErrorsRef.current).not.toBeNull();
|
|
485
|
+
expect(capturedApiValidationErrorsRef.current.standardErrors).toContain(
|
|
486
|
+
'Missing tags are: unsubscribe',
|
|
487
|
+
);
|
|
488
|
+
});
|
|
489
|
+
});
|
|
490
|
+
|
|
491
|
+
it('uses apiValidationErrors.liquidErrors and concatenates apiValidationErrors.standardErrors with tag messages (merge shape)', async () => {
|
|
492
|
+
// When tag messages exist, mergedApiValidationErrors returns liquidErrors from apiValidationErrors
|
|
493
|
+
// and standardErrors = [...(apiValidationErrors?.standardErrors || []), ...tagMessages] (lines 124-125)
|
|
494
|
+
validateTags.mockReturnValue({
|
|
495
|
+
valid: false,
|
|
496
|
+
unsupportedTags: ['customTag'],
|
|
497
|
+
});
|
|
498
|
+
renderWithIntl({
|
|
499
|
+
metaEntities: { tags: { standard: [{ name: 'customer.name' }] } },
|
|
500
|
+
tags: [{ name: 'customer.name' }],
|
|
501
|
+
});
|
|
502
|
+
const changeButton = screen.getByTestId('trigger-content-change');
|
|
503
|
+
await act(async () => {
|
|
504
|
+
fireEvent.click(changeButton);
|
|
505
|
+
});
|
|
506
|
+
await waitFor(() => {
|
|
507
|
+
expect(capturedApiValidationErrorsRef.current).not.toBeNull();
|
|
508
|
+
const { liquidErrors, standardErrors } = capturedApiValidationErrorsRef.current;
|
|
509
|
+
expect(liquidErrors).toEqual([]);
|
|
510
|
+
expect(standardErrors).toContain('Unsupported tags are: customTag');
|
|
511
|
+
});
|
|
512
|
+
});
|
|
424
513
|
});
|
|
425
514
|
|
|
426
515
|
describe('Default Parameter Values (lines 60-63)', () => {
|
|
@@ -768,6 +768,130 @@ describe('useEmailWrapper', () => {
|
|
|
768
768
|
});
|
|
769
769
|
});
|
|
770
770
|
|
|
771
|
+
describe('templateId resolution (lines 209-213)', () => {
|
|
772
|
+
it('should call getTemplateDetails with templateId from params.id', async () => {
|
|
773
|
+
const templateId = 'from-params-id';
|
|
774
|
+
const editProps = {
|
|
775
|
+
...newFlowMockProps,
|
|
776
|
+
params: { id: templateId },
|
|
777
|
+
location: { pathname: '/email/edit/other', query: {} },
|
|
778
|
+
Email: {
|
|
779
|
+
...newFlowMockProps.Email,
|
|
780
|
+
templateDetails: null,
|
|
781
|
+
getTemplateDetailsInProgress: false,
|
|
782
|
+
},
|
|
783
|
+
};
|
|
784
|
+
|
|
785
|
+
renderHook((props) => useEmailWrapper(props), {
|
|
786
|
+
initialProps: editProps,
|
|
787
|
+
});
|
|
788
|
+
|
|
789
|
+
await waitFor(() => {
|
|
790
|
+
expect(mockEmailActions.getTemplateDetails).toHaveBeenCalledWith(templateId, 'email');
|
|
791
|
+
});
|
|
792
|
+
});
|
|
793
|
+
|
|
794
|
+
it('should call getTemplateDetails with templateId from location.query.id when params.id is missing', async () => {
|
|
795
|
+
const templateId = 'from-query-id';
|
|
796
|
+
const editProps = {
|
|
797
|
+
...newFlowMockProps,
|
|
798
|
+
params: {},
|
|
799
|
+
location: {
|
|
800
|
+
pathname: '/email/edit/something',
|
|
801
|
+
query: { id: templateId },
|
|
802
|
+
},
|
|
803
|
+
Email: {
|
|
804
|
+
...newFlowMockProps.Email,
|
|
805
|
+
templateDetails: null,
|
|
806
|
+
getTemplateDetailsInProgress: false,
|
|
807
|
+
},
|
|
808
|
+
};
|
|
809
|
+
|
|
810
|
+
renderHook((props) => useEmailWrapper(props), {
|
|
811
|
+
initialProps: editProps,
|
|
812
|
+
});
|
|
813
|
+
|
|
814
|
+
await waitFor(() => {
|
|
815
|
+
expect(mockEmailActions.getTemplateDetails).toHaveBeenCalledWith(templateId, 'email');
|
|
816
|
+
});
|
|
817
|
+
});
|
|
818
|
+
|
|
819
|
+
it('should call getTemplateDetails with templateId from location.params.id when params and query id are missing', async () => {
|
|
820
|
+
const templateId = 'from-location-params-id';
|
|
821
|
+
const editProps = {
|
|
822
|
+
...newFlowMockProps,
|
|
823
|
+
params: {},
|
|
824
|
+
location: {
|
|
825
|
+
pathname: '/email/edit/fallback',
|
|
826
|
+
query: {},
|
|
827
|
+
params: { id: templateId },
|
|
828
|
+
},
|
|
829
|
+
Email: {
|
|
830
|
+
...newFlowMockProps.Email,
|
|
831
|
+
templateDetails: null,
|
|
832
|
+
getTemplateDetailsInProgress: false,
|
|
833
|
+
},
|
|
834
|
+
};
|
|
835
|
+
|
|
836
|
+
renderHook((props) => useEmailWrapper(props), {
|
|
837
|
+
initialProps: editProps,
|
|
838
|
+
});
|
|
839
|
+
|
|
840
|
+
await waitFor(() => {
|
|
841
|
+
expect(mockEmailActions.getTemplateDetails).toHaveBeenCalledWith(templateId, 'email');
|
|
842
|
+
});
|
|
843
|
+
});
|
|
844
|
+
|
|
845
|
+
it('should call getTemplateDetails with templateId extracted from pathname /edit/ID when no params or query id', async () => {
|
|
846
|
+
const templateId = 'extracted-from-pathname';
|
|
847
|
+
const editProps = {
|
|
848
|
+
...newFlowMockProps,
|
|
849
|
+
params: {},
|
|
850
|
+
location: {
|
|
851
|
+
pathname: `/email/edit/${templateId}`,
|
|
852
|
+
query: {},
|
|
853
|
+
},
|
|
854
|
+
Email: {
|
|
855
|
+
...newFlowMockProps.Email,
|
|
856
|
+
templateDetails: null,
|
|
857
|
+
getTemplateDetailsInProgress: false,
|
|
858
|
+
},
|
|
859
|
+
};
|
|
860
|
+
|
|
861
|
+
renderHook((props) => useEmailWrapper(props), {
|
|
862
|
+
initialProps: editProps,
|
|
863
|
+
});
|
|
864
|
+
|
|
865
|
+
await waitFor(() => {
|
|
866
|
+
expect(mockEmailActions.getTemplateDetails).toHaveBeenCalledWith(templateId, 'email');
|
|
867
|
+
});
|
|
868
|
+
});
|
|
869
|
+
|
|
870
|
+
it('should not call getTemplateDetails when pathname includes /edit/ but has no id segment', async () => {
|
|
871
|
+
const editProps = {
|
|
872
|
+
...newFlowMockProps,
|
|
873
|
+
params: {},
|
|
874
|
+
location: {
|
|
875
|
+
pathname: '/email/edit/',
|
|
876
|
+
query: {},
|
|
877
|
+
},
|
|
878
|
+
Email: {
|
|
879
|
+
...newFlowMockProps.Email,
|
|
880
|
+
templateDetails: null,
|
|
881
|
+
getTemplateDetailsInProgress: false,
|
|
882
|
+
},
|
|
883
|
+
};
|
|
884
|
+
|
|
885
|
+
renderHook((props) => useEmailWrapper(props), {
|
|
886
|
+
initialProps: editProps,
|
|
887
|
+
});
|
|
888
|
+
|
|
889
|
+
await waitFor(() => {
|
|
890
|
+
expect(mockEmailActions.getTemplateDetails).not.toHaveBeenCalled();
|
|
891
|
+
}, { timeout: 500 });
|
|
892
|
+
});
|
|
893
|
+
});
|
|
894
|
+
|
|
771
895
|
describe('Edit Flow - BEE Editor Template', () => {
|
|
772
896
|
it('should call getTemplateDetails and set BEE editor for BEE template', async () => {
|
|
773
897
|
const templateId = 'bee-template-123';
|
|
@@ -177,9 +177,11 @@ export class Edit extends React.Component { // eslint-disable-line react/prefer-
|
|
|
177
177
|
}
|
|
178
178
|
if (nextProps.metaEntities && nextProps.metaEntities.layouts && nextProps.metaEntities.layouts.length > 0 && _.isEmpty(this.state.fullSchema)) {
|
|
179
179
|
this.setState({fullSchema: nextProps.metaEntities.layouts[0].definition, schema: (nextProps.location.query.module === 'loyalty') ? nextProps.metaEntities.layouts[0].definition.textSchema : {}}, () => {
|
|
180
|
-
this.
|
|
180
|
+
// Use this.props (latest) in callback to avoid race: templateDetails may have arrived by now
|
|
181
|
+
const latestSelectedAccount = this.getSelectedWeChatAccountFromProps(this.props);
|
|
182
|
+
this.handleEditSchemaOnPropsChange(this.props, latestSelectedAccount);
|
|
181
183
|
const templateId = get(this, "props.params.id");
|
|
182
|
-
if (
|
|
184
|
+
if (this.props.location.query.module !== 'loyalty' && templateId && templateId !== 'temp') {
|
|
183
185
|
this.props.actions.getTemplateDetails(templateId);
|
|
184
186
|
}
|
|
185
187
|
if (queryType === EMBEDDED && templateId === 'temp' && _.isEmpty(this.state.formData)) { // when his.props.params.id is temp that means mobile push template content will be passed from post message from parent with startTemplateCreation action
|
|
@@ -293,7 +295,7 @@ export class Edit extends React.Component { // eslint-disable-line react/prefer-
|
|
|
293
295
|
const inputFields = get(schema, `containers[0].panes[${tabIndex - 1}].sections[0].childSections[0].childSections[0].inputFields`);
|
|
294
296
|
const id = field.id;
|
|
295
297
|
const fieldIndex = findIndex(inputFields, {identifier: id});
|
|
296
|
-
const ck = selectedWeChatAccount
|
|
298
|
+
const ck = selectedWeChatAccount?.configs ? !!selectedWeChatAccount.configs.deeplink : false;
|
|
297
299
|
const deepLinkOptions = _.map(JSON.parse(ck ? selectedWeChatAccount.configs.deeplink : '[]'), (link) => ({label: link.name, value: link.link, title: link.link }) );
|
|
298
300
|
// let inputId = deeplinkValue && deeplinkValue.toLowerCase() === "deeplink" ? `${id}-select` : `${id}-text`;
|
|
299
301
|
// if (field.id === "cta-deeplink-secondary-cta-1" && (tabIndex > 1 || this.state.currentTab > 1)) {
|
|
@@ -665,8 +667,8 @@ export class Edit extends React.Component { // eslint-disable-line react/prefer-
|
|
|
665
667
|
|
|
666
668
|
getLinkName = (link) => {
|
|
667
669
|
const selectedWeChatAccount = this.getWeChatAccount();
|
|
668
|
-
const ck = selectedWeChatAccount
|
|
669
|
-
const deepLinkOptions = _.filter(JSON.parse(ck ? selectedWeChatAccount
|
|
670
|
+
const ck = selectedWeChatAccount?.configs ? !!selectedWeChatAccount.configs.deeplink : false;
|
|
671
|
+
const deepLinkOptions = _.filter(JSON.parse(ck ? selectedWeChatAccount?.configs?.deeplink ?? '[]' : '[]'), (l) => l.link === link);
|
|
670
672
|
if (deepLinkOptions[0]) {
|
|
671
673
|
return deepLinkOptions[0].name;
|
|
672
674
|
}
|
|
@@ -727,6 +729,27 @@ export class Edit extends React.Component { // eslint-disable-line react/prefer-
|
|
|
727
729
|
parent.postMessage(JSON.stringify(response), '*');
|
|
728
730
|
};
|
|
729
731
|
|
|
732
|
+
/**
|
|
733
|
+
* Compute selectedWeChatAccount from props (used so we can call with latest props
|
|
734
|
+
* in setState callback to avoid stale closure and intermittent empty form).
|
|
735
|
+
*/
|
|
736
|
+
getSelectedWeChatAccountFromProps = (props) => {
|
|
737
|
+
const queryType = String(get(props, 'location.query.type', ''))?.toLowerCase();
|
|
738
|
+
const creativesMode = String(get(props, 'creativesMode', ''))?.toLowerCase();
|
|
739
|
+
const { Edit: EditProps, Templates } = props || {};
|
|
740
|
+
const { selectedWeChatAccount: editSelectedWeChatAccount } = EditProps || {};
|
|
741
|
+
const { Templates: nextTemplates } = props || {};
|
|
742
|
+
if (isEmbeddedEditOrPreview(queryType, creativesMode)) {
|
|
743
|
+
return !_.isEmpty(editSelectedWeChatAccount)
|
|
744
|
+
? editSelectedWeChatAccount
|
|
745
|
+
: nextTemplates?.selectedWeChatAccount;
|
|
746
|
+
}
|
|
747
|
+
if (!_.isEmpty(Templates?.selectedWeChatAccount)) {
|
|
748
|
+
return Templates?.selectedWeChatAccount;
|
|
749
|
+
}
|
|
750
|
+
return undefined;
|
|
751
|
+
};
|
|
752
|
+
|
|
730
753
|
getFormData = (e) => {
|
|
731
754
|
const response = {
|
|
732
755
|
action: "getFormData",
|
|
@@ -749,6 +772,9 @@ export class Edit extends React.Component { // eslint-disable-line react/prefer-
|
|
|
749
772
|
formData["mobilepush-accounts"] = this.state.formData["mobilepush-accounts"];
|
|
750
773
|
formData['mobilepush-template'] = this.state.formData['mobilepush-template'];
|
|
751
774
|
}
|
|
775
|
+
if (data.definition?.accountId) {
|
|
776
|
+
formData['mobilepush-accounts'] = data.definition.accountId;
|
|
777
|
+
}
|
|
752
778
|
formData['template-name'] = data.name;
|
|
753
779
|
const androidData = data.versions.base.ANDROID;
|
|
754
780
|
const iosData = data.versions.base.IOS;
|
|
@@ -1088,7 +1114,7 @@ export class Edit extends React.Component { // eslint-disable-line react/prefer-
|
|
|
1088
1114
|
const currentTab = tab || this.state.currentTab;
|
|
1089
1115
|
const schema = inputSchema ? _.cloneDeep(inputSchema) : _.cloneDeep(this.state.schema);
|
|
1090
1116
|
const selectedWeChatAccount = this.getWeChatAccount();
|
|
1091
|
-
const ck = selectedWeChatAccount
|
|
1117
|
+
const ck = selectedWeChatAccount?.configs ? !!selectedWeChatAccount.configs.deeplink : false;
|
|
1092
1118
|
const deepLinkOptions = _.map(JSON.parse(ck ? selectedWeChatAccount.configs.deeplink : '[]'), (link) => ({label: link.name, value: link.link, title: link.link }) );
|
|
1093
1119
|
|
|
1094
1120
|
const inputFields = get(schema, `containers[0].panes[${currentTab - 1}].sections[0].childSections[0].childSections[0].inputFields`);
|
|
@@ -1240,7 +1266,7 @@ export class Edit extends React.Component { // eslint-disable-line react/prefer-
|
|
|
1240
1266
|
delete formData[self.state.currentTab - 1][`${id.replace('-delete', '')}`];
|
|
1241
1267
|
}
|
|
1242
1268
|
if (child.inputFields[fieldIndex] && child.inputFields[fieldIndex].id === "cta-deeplink-select-section") {
|
|
1243
|
-
const ck = selectedWeChatAccount
|
|
1269
|
+
const ck = selectedWeChatAccount?.configs ? !!selectedWeChatAccount.configs.deeplink : false;
|
|
1244
1270
|
const configkeys = selectedWeChatAccount ? _.filter(JSON.parse(ck ? selectedWeChatAccount.configs.deeplink : '[]'), (dl) => dl.link === selectedDeeplink) : [];
|
|
1245
1271
|
if (configkeys.length) {
|
|
1246
1272
|
const options = configkeys[0].keys;
|
|
@@ -1352,7 +1378,7 @@ export class Edit extends React.Component { // eslint-disable-line react/prefer-
|
|
|
1352
1378
|
delete formData[self.state.currentTab - 1][`cta-deeplink-${id.replace('delete', 'text')}`];
|
|
1353
1379
|
}
|
|
1354
1380
|
if (child.inputFields[fieldIndex] && child.inputFields[fieldIndex].id === "cta-deeplink-select-section") {
|
|
1355
|
-
const ck = selectedWeChatAccount
|
|
1381
|
+
const ck = selectedWeChatAccount?.configs ? !!selectedWeChatAccount.configs.deeplink : false;
|
|
1356
1382
|
const configkeys = selectedWeChatAccount ? _.filter(JSON.parse(ck ? selectedWeChatAccount.configs.deeplink : '[]'), (dl) => dl.link === selectedDeeplink) : [];
|
|
1357
1383
|
|
|
1358
1384
|
if (configkeys.length) {
|
|
@@ -1706,7 +1732,7 @@ export class Edit extends React.Component { // eslint-disable-line react/prefer-
|
|
|
1706
1732
|
const {id} = field;
|
|
1707
1733
|
const fieldIndex = findIndex(inputFields, {identifier: id});
|
|
1708
1734
|
const formDataKey = id.replace("-show-keys", "");
|
|
1709
|
-
const ck = selectedWeChatAccount
|
|
1735
|
+
const ck = selectedWeChatAccount?.configs ? !!selectedWeChatAccount.configs.deeplink : false;
|
|
1710
1736
|
let keys = selectedWeChatAccount ? _.filter(JSON.parse(ck ? selectedWeChatAccount.configs.deeplink : '[]'), (dl) => dl.link === formData[currentTab - 1][formDataKey]) : [];
|
|
1711
1737
|
if (keys[0]) {
|
|
1712
1738
|
keys = keys[0].keys;
|
|
@@ -1756,7 +1782,7 @@ export class Edit extends React.Component { // eslint-disable-line react/prefer-
|
|
|
1756
1782
|
const selectedWeChatAccount = this.getWeChatAccount();
|
|
1757
1783
|
const id = field.id;
|
|
1758
1784
|
const schema = inputSchema ? _.cloneDeep(inputSchema) : _.cloneDeep(this.state.schema);
|
|
1759
|
-
const ck = selectedWeChatAccount
|
|
1785
|
+
const ck = selectedWeChatAccount?.configs ? !!selectedWeChatAccount.configs.deeplink : false;
|
|
1760
1786
|
const deepLinkOptions = selectedWeChatAccount ? _.map(JSON.parse(ck ? selectedWeChatAccount.configs.deeplink : '[]'), (link) => ({label: link.name, value: link.link, title: link.link }) ) : [];
|
|
1761
1787
|
// const eventsMap = _.cloneDeep(this.state.eventsMap);
|
|
1762
1788
|
const tabIndex = currentTab || this.state.currentTab;
|
|
@@ -1787,7 +1813,7 @@ export class Edit extends React.Component { // eslint-disable-line react/prefer-
|
|
|
1787
1813
|
const formDataCopy = cloneDeep(formData);
|
|
1788
1814
|
const schema = inputSchema ? _.cloneDeep(inputSchema) : _.cloneDeep(this.state.schema);
|
|
1789
1815
|
const selectedWeChatAccount = this.getWeChatAccount();
|
|
1790
|
-
const ck = selectedWeChatAccount
|
|
1816
|
+
const ck = selectedWeChatAccount?.configs ? !!selectedWeChatAccount.configs.deeplink : false;
|
|
1791
1817
|
const deepLinkOptions = selectedWeChatAccount ? _.map(JSON.parse(ck ? selectedWeChatAccount.configs.deeplink : '[]'), (link) => ({label: link.name, value: link.link, title: link.link }) ) : [];
|
|
1792
1818
|
const inputFields = get(schema, `containers[0].panes[${tabIndex - 1}].sections[0].childSections[0].childSections[0].inputFields`);
|
|
1793
1819
|
const fieldIndex = findIndex(inputFields, {identifier: id});
|
|
@@ -2004,8 +2030,23 @@ export class Edit extends React.Component { // eslint-disable-line react/prefer-
|
|
|
2004
2030
|
}
|
|
2005
2031
|
|
|
2006
2032
|
handleEditSchemaOnPropsChange = (nextProps, selectedWeChatAccount) => {
|
|
2007
|
-
|
|
2033
|
+
const queryType = String(get(this.props, 'location.query.type', ''))?.toLowerCase();
|
|
2034
|
+
const isEmbeddedLibrary = queryType === EMBEDDED && !nextProps.isFullMode;
|
|
2035
|
+
const canSetAccountFromTemplate =
|
|
2036
|
+
!selectedWeChatAccount &&
|
|
2037
|
+
nextProps.templateDetails?.definition?.accountId &&
|
|
2038
|
+
nextProps.Edit?.weCrmAccounts?.length > 0;
|
|
2039
|
+
const canPopulateForm =
|
|
2040
|
+
!_.isEmpty(nextProps.templateDetails) &&
|
|
2041
|
+
_.isEmpty(this.state.editData) &&
|
|
2042
|
+
!_.isEmpty(this.state.fullSchema) &&
|
|
2043
|
+
(this.props.location.query.type !== 'embedded' || this.props.isFullMode === false) &&
|
|
2044
|
+
(selectedWeChatAccount || isEmbeddedLibrary || canSetAccountFromTemplate);
|
|
2045
|
+
if (canPopulateForm) {
|
|
2008
2046
|
this.props = nextProps;
|
|
2047
|
+
if (canSetAccountFromTemplate) {
|
|
2048
|
+
this.setMobilePushAccountOptions(nextProps.Edit.weCrmAccounts, nextProps.templateDetails.definition.accountId);
|
|
2049
|
+
}
|
|
2009
2050
|
const mode = nextProps.templateDetails.definition ? nextProps.templateDetails.definition.mode : nextProps.templateDetails.mode;
|
|
2010
2051
|
const schema = mode === "text" ? this.state.fullSchema?.textSchema : this.state.fullSchema?.imageSchema;
|
|
2011
2052
|
const isAndroidSupported = get(this, "props.Templates.selectedWeChatAccount.configs.android") === '1';
|
|
@@ -2040,7 +2081,7 @@ export class Edit extends React.Component { // eslint-disable-line react/prefer-
|
|
|
2040
2081
|
<CapSpin spinning={spinning}>
|
|
2041
2082
|
<CapRow>
|
|
2042
2083
|
<CapColumn>
|
|
2043
|
-
<FormBuilder
|
|
2084
|
+
{!this.props.isLoadingMetaEntities && <FormBuilder
|
|
2044
2085
|
channel={MOBILE_PUSH}
|
|
2045
2086
|
schema={schema}
|
|
2046
2087
|
showLiquidErrorInFooter={this.props.showLiquidErrorInFooter}
|
|
@@ -2075,7 +2116,7 @@ export class Edit extends React.Component { // eslint-disable-line react/prefer-
|
|
|
2075
2116
|
hideTestAndPreviewBtn={this.props.hideTestAndPreviewBtn}
|
|
2076
2117
|
isFullMode={this.props.isFullMode}
|
|
2077
2118
|
eventContextTags={this.props?.eventContextTags}
|
|
2078
|
-
/>
|
|
2119
|
+
/>}
|
|
2079
2120
|
</CapColumn>
|
|
2080
2121
|
{this.props.iosCtasData && this.state.showIosCtaTable &&
|
|
2081
2122
|
<CapSlideBox
|