@capillarytech/creatives-library 9.0.65 → 9.0.66
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
|
@@ -52,6 +52,17 @@ const formatSafe = (intl, descriptor) => (intl?.formatMessage ? intl.formatMessa
|
|
|
52
52
|
// Classic gates every field-error display on checkValidation (pre-save silence).
|
|
53
53
|
const shouldShowError = (renderContext, error) => Boolean(renderContext?.checkValidation && error);
|
|
54
54
|
|
|
55
|
+
const isEmptyValue = (value) => !value || !/\S/.test(String(value));
|
|
56
|
+
|
|
57
|
+
// Classic (Classic.js:2881-2885) only defers the "empty/required" error until
|
|
58
|
+
// Save/Update/Done (checkValidation); brace/personalization/tag errors show live
|
|
59
|
+
// as soon as they're detected. Title/Message fields need that same two-tier gate.
|
|
60
|
+
const shouldShowFieldError = (renderContext, error, value) => {
|
|
61
|
+
if (!error) return false;
|
|
62
|
+
const isEmptyRequiredError = error === true && isEmptyValue(value);
|
|
63
|
+
return isEmptyRequiredError ? Boolean(renderContext?.checkValidation) : true;
|
|
64
|
+
};
|
|
65
|
+
|
|
55
66
|
/** Classic input-case error message: personalization > brace > schema errorMessage. */
|
|
56
67
|
const resolveInputMessage = (field, value, error, renderContext) => {
|
|
57
68
|
const { intl, restrictPersonalization } = renderContext || {};
|
|
@@ -67,7 +78,7 @@ const resolveInputMessage = (field, value, error, renderContext) => {
|
|
|
67
78
|
export const MpushInputField = ({
|
|
68
79
|
field, value, error, onChange, onBlur, renderContext,
|
|
69
80
|
}) => {
|
|
70
|
-
const showError =
|
|
81
|
+
const showError = shouldShowFieldError(renderContext, error, value);
|
|
71
82
|
const message = showError ? resolveInputMessage(field, value, error, renderContext) : '';
|
|
72
83
|
return (
|
|
73
84
|
<CapColumn key={field.id} span={field.width} offset={field.offset} style={field.style || {}}>
|
|
@@ -95,13 +106,9 @@ export const MpushTextAreaField = ({
|
|
|
95
106
|
}) => {
|
|
96
107
|
let aiDisabled = true;
|
|
97
108
|
try { aiDisabled = isAiContentBotDisabled(); } catch (e) { console.error(e); aiDisabled = true; }
|
|
98
|
-
// Classic
|
|
99
|
-
//
|
|
100
|
-
|
|
101
|
-
// states where Classic can hold a non-false errorType, so gating display on it
|
|
102
|
-
// reproduces Classic's typing silence and also keeps the initial-hydrate
|
|
103
|
-
// errorData (computed for the parent validity emission) from leaking into the UI.
|
|
104
|
-
const showError = shouldShowError(renderContext, error);
|
|
109
|
+
// Classic shows brace/tag/personalization errors live while typing and only
|
|
110
|
+
// defers the empty/required error until Save/Update/Done (Classic.js:2881-2885).
|
|
111
|
+
const showError = shouldShowFieldError(renderContext, error, value);
|
|
105
112
|
// MPUSH keeps the inline message even though the channel is liquid-supported
|
|
106
113
|
// (Classic.js:2908-2915). Personalization gets its own message (2877-2879).
|
|
107
114
|
const inlineMessage = showError ? resolveInputMessage(field, value, error, renderContext) : '';
|
|
@@ -26,7 +26,7 @@ const kids = (el) => {
|
|
|
26
26
|
describe('MpushInputField', () => {
|
|
27
27
|
const field = { id: 'secondary-cta-0-label', width: 18, errorMessage: 'Label required' };
|
|
28
28
|
|
|
29
|
-
it('message resolution: personalization > brace > schema errorMessage; hidden without checkValidation', () => {
|
|
29
|
+
it('message resolution: personalization > brace > schema errorMessage; empty-required error hidden without checkValidation', () => {
|
|
30
30
|
const base = { field, onChange: () => {}, renderContext: { checkValidation: true, intl } };
|
|
31
31
|
expect(kids(MpushInputField({ ...base, value: '', error: true }))[0].props.errorMessage)
|
|
32
32
|
.toBe('Label required');
|
|
@@ -42,12 +42,20 @@ describe('MpushInputField', () => {
|
|
|
42
42
|
...base, value: '', error: true, renderContext: { checkValidation: false, intl },
|
|
43
43
|
}))[0].props.errorMessage).toBe('');
|
|
44
44
|
});
|
|
45
|
+
|
|
46
|
+
it('shows brace/tag errors live, before checkValidation (Save/Update/Done) is set', () => {
|
|
47
|
+
const el = MpushInputField({
|
|
48
|
+
field, value: 'a {{b', error: ERROR_VALUE.BRACKET, onChange: () => {}, renderContext: { checkValidation: false, intl },
|
|
49
|
+
});
|
|
50
|
+
expect(kids(el)[0].props.errorMessage).toContain('curly braces');
|
|
51
|
+
expect(kids(el)[0].props.className).toContain('error');
|
|
52
|
+
});
|
|
45
53
|
});
|
|
46
54
|
|
|
47
55
|
describe('MpushTextAreaField', () => {
|
|
48
56
|
const field = { id: 'message-editor', width: 18, errorMessage: 'Message required' };
|
|
49
57
|
|
|
50
|
-
it('inline message shows only under checkValidation; AskAira renders when AI enabled', () => {
|
|
58
|
+
it('empty-required inline message shows only under checkValidation; AskAira renders when AI enabled', () => {
|
|
51
59
|
const base = { field, onChange: jest.fn(), renderContext: { checkValidation: true, intl } };
|
|
52
60
|
expect(kids(MpushTextAreaField({ ...base, value: '', error: true }))[0].props.errorMessage)
|
|
53
61
|
.toBe('Message required');
|
|
@@ -66,6 +74,18 @@ describe('MpushTextAreaField', () => {
|
|
|
66
74
|
});
|
|
67
75
|
expect(kids(el).length).toBe(1); // textarea only, no bot
|
|
68
76
|
});
|
|
77
|
+
|
|
78
|
+
it('shows brace/tag errors live, before checkValidation (Save/Update/Done) is set', () => {
|
|
79
|
+
const el = MpushTextAreaField({
|
|
80
|
+
field,
|
|
81
|
+
value: 'hi {{name',
|
|
82
|
+
error: ERROR_VALUE.BRACKET,
|
|
83
|
+
onChange: () => {},
|
|
84
|
+
renderContext: { checkValidation: false, intl },
|
|
85
|
+
});
|
|
86
|
+
expect(kids(el)[0].props.errorMessage).toContain('curly braces');
|
|
87
|
+
expect(kids(el)[0].props.className).toContain('error-form-builder');
|
|
88
|
+
});
|
|
69
89
|
});
|
|
70
90
|
|
|
71
91
|
describe('MpushCheckboxField', () => {
|