@capillarytech/creatives-library 8.0.9 → 8.0.11
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/config/app.js +2 -0
- package/containers/App/constants.js +1 -0
- package/initialState.js +3 -0
- package/package.json +1 -1
- package/services/api.js +20 -0
- package/services/tests/api.test.js +148 -0
- package/utils/common.js +7 -0
- package/utils/commonUtils.js +7 -1
- package/utils/tagValidations.js +99 -1
- package/utils/tests/commonUtil.test.js +37 -1
- package/utils/tests/tagValidations.test.js +392 -2
- package/v2Components/Ckeditor/index.js +12 -10
- package/v2Components/ErrorInfoNote/index.js +89 -0
- package/v2Components/ErrorInfoNote/messages.js +29 -0
- package/v2Components/ErrorInfoNote/style.scss +72 -0
- package/v2Components/FormBuilder/_formBuilder.scss +4 -1
- package/v2Components/FormBuilder/index.js +171 -70
- package/v2Components/FormBuilder/messages.js +8 -0
- package/v2Containers/Cap/actions.js +8 -0
- package/v2Containers/Cap/constants.js +4 -0
- package/v2Containers/Cap/mockData.js +74 -0
- package/v2Containers/Cap/reducer.js +12 -0
- package/v2Containers/Cap/sagas.js +28 -1
- package/v2Containers/Cap/selectors.js +5 -0
- package/v2Containers/Cap/tests/__snapshots__/index.test.js.snap +1 -0
- package/v2Containers/Cap/tests/reducer.test.js +50 -0
- package/v2Containers/Cap/tests/saga.test.js +81 -1
- package/v2Containers/CreativesContainer/SlideBoxContent.js +7 -0
- package/v2Containers/CreativesContainer/SlideBoxFooter.js +40 -17
- package/v2Containers/CreativesContainer/constants.js +1 -0
- package/v2Containers/CreativesContainer/index.js +45 -4
- package/v2Containers/CreativesContainer/index.scss +13 -1
- package/v2Containers/CreativesContainer/tests/__snapshots__/index.test.js.snap +16 -0
- package/v2Containers/Email/_email.scss +3 -0
- package/v2Containers/Email/index.js +2 -0
- package/v2Containers/EmailWrapper/index.js +3 -0
- package/v2Containers/Line/Container/Wrapper/tests/__snapshots__/index.test.js.snap +3 -0
- package/v2Containers/Line/Container/sagas.js +1 -1
- package/v2Containers/MobilePush/Edit/constants.js +2 -0
- package/v2Containers/MobilePush/Edit/index.js +91 -24
- package/v2Containers/Rcs/tests/__snapshots__/index.test.js.snap +93 -0
- package/v2Containers/SmsTrai/Edit/tests/__snapshots__/index.test.js.snap +12 -0
- package/v2Containers/Viber/constants.js +1 -1
- package/v2Containers/Viber/index.js +19 -19
- package/v2Containers/Viber/messages.js +0 -4
- package/v2Containers/Whatsapp/tests/__snapshots__/index.test.js.snap +12 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import '@testing-library/jest-dom';
|
|
3
|
-
import { validateIfTagClosed
|
|
3
|
+
import { checkSupport, extractNames, preprocessHtml, validateIfTagClosed,validateTags} from '../tagValidations';
|
|
4
4
|
|
|
5
5
|
describe("check if curly brackets are balanced", () => {
|
|
6
6
|
it("test for balanced curly brackets", () => {
|
|
@@ -26,4 +26,394 @@ describe("check if curly brackets are balanced", () => {
|
|
|
26
26
|
expect(validateIfTagClosed("{{{{Hello}}World}}")).toEqual(false);
|
|
27
27
|
expect(validateIfTagClosed("{{Hello{{World}}")).toEqual(false);
|
|
28
28
|
})
|
|
29
|
-
})
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
describe("validateTags", () => {
|
|
32
|
+
const tagsParam = [
|
|
33
|
+
{
|
|
34
|
+
definition: {
|
|
35
|
+
supportedModules: [{ context: "DEFAULT", mandatory: true }],
|
|
36
|
+
value: "tag1",
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
definition: {
|
|
41
|
+
supportedModules: [{ context: "DEFAULT", mandatory: true }],
|
|
42
|
+
value: "tag2",
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
definition: {
|
|
47
|
+
supportedModules: [{ context: "DEFAULT", mandatory: true }],
|
|
48
|
+
value: "tag3",
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
];
|
|
52
|
+
it("should return valid response when all tags are present", () => {
|
|
53
|
+
const content = "Hello {{tag1}}, {{tag2}}, {{tag3}}";
|
|
54
|
+
|
|
55
|
+
const injectedTagsParams = [];
|
|
56
|
+
const location = { query: { module: "DEFAULT" } };
|
|
57
|
+
const tagModule = null;
|
|
58
|
+
|
|
59
|
+
const result = validateTags({
|
|
60
|
+
content,
|
|
61
|
+
tagsParam,
|
|
62
|
+
injectedTagsParams,
|
|
63
|
+
location,
|
|
64
|
+
tagModule,
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
expect(result.valid).toEqual(true);
|
|
68
|
+
expect(result.missingTags).toEqual([]);
|
|
69
|
+
expect(result.unsupportedTags).toEqual([]);
|
|
70
|
+
expect(result.isBraceError).toEqual(false);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
it("should return invalid response when a mandatory tag is missing", () => {
|
|
74
|
+
const content = "Hello {{tag1}}, {{tag2}}, {{tag3}}";
|
|
75
|
+
const updatedTagsParam = [...tagsParam, {
|
|
76
|
+
definition: {
|
|
77
|
+
supportedModules: [{ context: "DEFAULT", mandatory: true }],
|
|
78
|
+
value: "tag4",
|
|
79
|
+
},
|
|
80
|
+
},];
|
|
81
|
+
const injectedTagsParams = [];
|
|
82
|
+
const location = { query: { module: "DEFAULT" } };
|
|
83
|
+
const tagModule = null;
|
|
84
|
+
|
|
85
|
+
const result = validateTags({
|
|
86
|
+
content,
|
|
87
|
+
updatedTagsParam,
|
|
88
|
+
injectedTagsParams,
|
|
89
|
+
location,
|
|
90
|
+
tagModule,
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
expect(result.valid).toEqual(true);
|
|
94
|
+
expect(result.unsupportedTags).toEqual([]);
|
|
95
|
+
expect(result.isBraceError).toEqual(false);
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
it("should return invalid response when an unsupported tag is present", () => {
|
|
99
|
+
const content = "Hello {{tag1}}, {{tag2}}, {{tag3}}";
|
|
100
|
+
const tagsParam = [
|
|
101
|
+
{
|
|
102
|
+
definition: {
|
|
103
|
+
supportedModules: [{ context: "DEFAULT", mandatory: true }],
|
|
104
|
+
value: "tag1",
|
|
105
|
+
},
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
definition: {
|
|
109
|
+
supportedModules: [{ context: "DEFAULT", mandatory: true }],
|
|
110
|
+
value: "tag2",
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
];
|
|
114
|
+
const injectedTagsParams = [];
|
|
115
|
+
const location = { query: { module: "DEFAULT" } };
|
|
116
|
+
const tagModule = null;
|
|
117
|
+
|
|
118
|
+
const result = validateTags({
|
|
119
|
+
content,
|
|
120
|
+
tagsParam,
|
|
121
|
+
injectedTagsParams,
|
|
122
|
+
location,
|
|
123
|
+
tagModule,
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
expect(result.valid).toEqual(true);
|
|
127
|
+
expect(result.missingTags).toEqual([]);
|
|
128
|
+
expect(result.unsupportedTags).toEqual(["tag3"]);
|
|
129
|
+
expect(result.isBraceError).toEqual(false);
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
it("should return invalid response when there is an unbalanced bracket error", () => {
|
|
133
|
+
const content = "Hello {{tag1}, {{tag2}}, {{tag3}}";
|
|
134
|
+
const tagsParam = [
|
|
135
|
+
{
|
|
136
|
+
definition: {
|
|
137
|
+
supportedModules: [{ context: "DEFAULT", mandatory: true }],
|
|
138
|
+
value: "tag1",
|
|
139
|
+
},
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
definition: {
|
|
143
|
+
supportedModules: [{ context: "DEFAULT", mandatory: true }],
|
|
144
|
+
value: "tag2",
|
|
145
|
+
},
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
definition: {
|
|
149
|
+
supportedModules: [{ context: "DEFAULT", mandatory: true }],
|
|
150
|
+
value: "tag3",
|
|
151
|
+
},
|
|
152
|
+
},
|
|
153
|
+
];
|
|
154
|
+
const injectedTagsParams = [];
|
|
155
|
+
const location = { query: { module: "DEFAULT" } };
|
|
156
|
+
const tagModule = null;
|
|
157
|
+
|
|
158
|
+
const result = validateTags({
|
|
159
|
+
content,
|
|
160
|
+
tagsParam,
|
|
161
|
+
injectedTagsParams,
|
|
162
|
+
location,
|
|
163
|
+
tagModule,
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
expect(result.valid).toEqual(false);
|
|
167
|
+
expect(result.missingTags).toEqual(["tag1"]);
|
|
168
|
+
expect(result.unsupportedTags).toEqual([]);
|
|
169
|
+
expect(result.isBraceError).toEqual(true);
|
|
170
|
+
});
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
describe("extractNames", () => {
|
|
174
|
+
it("should return an empty array when data is empty", () => {
|
|
175
|
+
const data = [];
|
|
176
|
+
const result = extractNames(data);
|
|
177
|
+
expect(result).toEqual([]);
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
it("should return an array of names when data contains nodes with names", () => {
|
|
181
|
+
const data = [
|
|
182
|
+
{
|
|
183
|
+
name: "Node 1",
|
|
184
|
+
children: [
|
|
185
|
+
{
|
|
186
|
+
name: "Node 1.1",
|
|
187
|
+
children: [],
|
|
188
|
+
},
|
|
189
|
+
{
|
|
190
|
+
name: "Node 1.2",
|
|
191
|
+
children: [],
|
|
192
|
+
},
|
|
193
|
+
],
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
name: "Node 2",
|
|
197
|
+
children: [
|
|
198
|
+
{
|
|
199
|
+
name: "Node 2.1",
|
|
200
|
+
children: [],
|
|
201
|
+
},
|
|
202
|
+
],
|
|
203
|
+
},
|
|
204
|
+
];
|
|
205
|
+
const result = extractNames(data);
|
|
206
|
+
expect(result).toEqual([
|
|
207
|
+
"Node 1",
|
|
208
|
+
"Node 1.1",
|
|
209
|
+
"Node 1.2",
|
|
210
|
+
"Node 2",
|
|
211
|
+
"Node 2.1",
|
|
212
|
+
]);
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
it("should ignore nodes without names", () => {
|
|
216
|
+
const data = [
|
|
217
|
+
{
|
|
218
|
+
name: "Node 1",
|
|
219
|
+
children: [
|
|
220
|
+
{
|
|
221
|
+
name: "Node 1.1",
|
|
222
|
+
children: [],
|
|
223
|
+
},
|
|
224
|
+
{
|
|
225
|
+
children: [],
|
|
226
|
+
},
|
|
227
|
+
],
|
|
228
|
+
},
|
|
229
|
+
{
|
|
230
|
+
name: "Node 2",
|
|
231
|
+
children: [
|
|
232
|
+
{
|
|
233
|
+
name: "Node 2.1",
|
|
234
|
+
children: [],
|
|
235
|
+
},
|
|
236
|
+
{
|
|
237
|
+
name: "Node 2.2",
|
|
238
|
+
},
|
|
239
|
+
],
|
|
240
|
+
},
|
|
241
|
+
];
|
|
242
|
+
const result = extractNames(data);
|
|
243
|
+
expect(result).toEqual([
|
|
244
|
+
"Node 1",
|
|
245
|
+
"Node 1.1",
|
|
246
|
+
"Node 2",
|
|
247
|
+
"Node 2.1",
|
|
248
|
+
"Node 2.2",
|
|
249
|
+
]);
|
|
250
|
+
});
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
describe("checkSupport", () => {
|
|
255
|
+
it("should return an empty array when args are empty", () => {
|
|
256
|
+
const result = checkSupport();
|
|
257
|
+
expect(result).toEqual([]);
|
|
258
|
+
});
|
|
259
|
+
it("should return an empty array when response data is empty", () => {
|
|
260
|
+
const response = { data: [] };
|
|
261
|
+
const tagObject = {};
|
|
262
|
+
const result = checkSupport(response, tagObject);
|
|
263
|
+
expect(result).toEqual([]);
|
|
264
|
+
});
|
|
265
|
+
|
|
266
|
+
it("should return an empty array when tagObject is empty", () => {
|
|
267
|
+
const response = {
|
|
268
|
+
data: [{ name: "tag1" }, { name: "tag2" }, { name: "tag3" }],
|
|
269
|
+
};
|
|
270
|
+
const tagObject = {};
|
|
271
|
+
const result = checkSupport(response, tagObject);
|
|
272
|
+
expect(result).toEqual([]);
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
it("should return an array of supported tags", () => {
|
|
276
|
+
const response = {
|
|
277
|
+
data: [{ name: "tag1" }, { name: "tag2" }, { name: "tag3" }],
|
|
278
|
+
};
|
|
279
|
+
const tagObject = {
|
|
280
|
+
tag1: { definition: { subtags: ["tag1.1", "tag1.2"] } },
|
|
281
|
+
tag2: { definition: { subtags: ["tag2.1", "tag2.2"] } },
|
|
282
|
+
tag3: { definition: { subtags: ["tag3.1", "tag3.2"] } },
|
|
283
|
+
};
|
|
284
|
+
const result = checkSupport(response, tagObject);
|
|
285
|
+
expect(result).toEqual(["tag1", "tag2", "tag3"]);
|
|
286
|
+
});
|
|
287
|
+
|
|
288
|
+
it("should return an array of supported tags with subtags", () => {
|
|
289
|
+
const response = {
|
|
290
|
+
data: [{ name: "tag1" }, { name: "tag2" }, { name: "tag3" }],
|
|
291
|
+
};
|
|
292
|
+
const tagObject = {
|
|
293
|
+
tag1: { definition: { subtags: ["tag1.1", "tag1.2"] } },
|
|
294
|
+
tag2: { definition: { subtags: ["tag2.1", "tag2.2"] } },
|
|
295
|
+
tag3: { definition: { subtags: ["tag3.1", "tag3.2"] } },
|
|
296
|
+
"tag1.1": {},
|
|
297
|
+
"tag2.1": {},
|
|
298
|
+
"tag3.1": {},
|
|
299
|
+
};
|
|
300
|
+
const result = checkSupport(response, tagObject);
|
|
301
|
+
expect(result).toEqual(["tag1", "tag2", "tag3"]);
|
|
302
|
+
});
|
|
303
|
+
|
|
304
|
+
it("should return an empty array when no tags are supported", () => {
|
|
305
|
+
const response = {
|
|
306
|
+
data: [{ name: "tag1" }, { name: "tag2" }, { name: "tag3" }],
|
|
307
|
+
};
|
|
308
|
+
const tagObject = {
|
|
309
|
+
tag4: {},
|
|
310
|
+
tag5: {},
|
|
311
|
+
tag6: {},
|
|
312
|
+
};
|
|
313
|
+
const result = checkSupport(response, tagObject);
|
|
314
|
+
expect(result).toEqual([]);
|
|
315
|
+
});
|
|
316
|
+
it("should return an array of supported tags with subtags", () => {
|
|
317
|
+
const response = {
|
|
318
|
+
data: [
|
|
319
|
+
{
|
|
320
|
+
name: "tag1",
|
|
321
|
+
children: [{ name: "tag1.1", children: [{ name: "tag1.2" }] }],
|
|
322
|
+
},
|
|
323
|
+
{ name: "tag2", children: [] },
|
|
324
|
+
{ name: "tag3" },
|
|
325
|
+
],
|
|
326
|
+
};
|
|
327
|
+
const tagObject = {
|
|
328
|
+
tag1: { definition: { subtags: [".1", "tag1.2"] } },
|
|
329
|
+
tag2: { definition: { subtags: ["tag2.1", "tag2.2"] } },
|
|
330
|
+
tag3: { definition: { subtags: ["tag3.1", "tag3.2"] } },
|
|
331
|
+
"tag1.1": {},
|
|
332
|
+
"tag2.1": {},
|
|
333
|
+
"tag3.1": {},
|
|
334
|
+
};
|
|
335
|
+
const result = checkSupport(response, tagObject);
|
|
336
|
+
expect(result).toEqual(["tag1", "tag1.1", "tag2", "tag3"]);
|
|
337
|
+
});
|
|
338
|
+
it("should return an array of supported tags children as an object", () => {
|
|
339
|
+
const response = {
|
|
340
|
+
data: [
|
|
341
|
+
{ name: "tag1", children: [{ name: "tag" }] },
|
|
342
|
+
{ name: "tag2", children: [] },
|
|
343
|
+
{ name: "tag3" },
|
|
344
|
+
],
|
|
345
|
+
};
|
|
346
|
+
const tagObject = {
|
|
347
|
+
tag1: { definition: { subtags: [".1", "tag1.2"] } },
|
|
348
|
+
tag2: { definition: { subtags: ["tag2.1", "tag2.2"] } },
|
|
349
|
+
tag3: { definition: { subtags: ["tag3.1", "tag3.2"] } },
|
|
350
|
+
"tag1.1": {},
|
|
351
|
+
"tag2.1": {},
|
|
352
|
+
"tag3.1": {},
|
|
353
|
+
};
|
|
354
|
+
const result = checkSupport(response, tagObject);
|
|
355
|
+
expect(result).toEqual(["tag1", "tag2", "tag3"]);
|
|
356
|
+
});
|
|
357
|
+
it("should return an empty array if tagObject is empty", () => {
|
|
358
|
+
const response = {
|
|
359
|
+
data: [
|
|
360
|
+
{ name: "tag1", children: [{ name: "tag" }] },
|
|
361
|
+
{ name: "tag2", children: [] },
|
|
362
|
+
{ name: "tag3" },
|
|
363
|
+
],
|
|
364
|
+
};
|
|
365
|
+
const result = checkSupport(response, {});
|
|
366
|
+
expect(result).toEqual([]);
|
|
367
|
+
});
|
|
368
|
+
});
|
|
369
|
+
|
|
370
|
+
describe('preprocessHtml', () => {
|
|
371
|
+
it('should replace HTML entities with their corresponding characters', () => {
|
|
372
|
+
const input = "This & that < those > these 'quotes'";
|
|
373
|
+
const expectedOutput = "This & that < those > these 'quotes'";
|
|
374
|
+
expect(preprocessHtml(input)).toEqual(expectedOutput);
|
|
375
|
+
});
|
|
376
|
+
|
|
377
|
+
it('should replace " with double quotes', () => {
|
|
378
|
+
const input = 'She said, "Hello, World!"';
|
|
379
|
+
const expectedOutput = "She said, 'Hello, World!'";
|
|
380
|
+
expect(preprocessHtml(input)).toEqual(expectedOutput);
|
|
381
|
+
});
|
|
382
|
+
|
|
383
|
+
it('should remove newline characters', () => {
|
|
384
|
+
const input = "Line one\nLine two\nLine three";
|
|
385
|
+
const expectedOutput = "Line oneLine twoLine three";
|
|
386
|
+
expect(preprocessHtml(input)).toEqual(expectedOutput);
|
|
387
|
+
});
|
|
388
|
+
|
|
389
|
+
it('should handle multiple replacements and newlines in the same string', () => {
|
|
390
|
+
const input = "<div>\nContent & More Content\n</div>";
|
|
391
|
+
const expectedOutput = "<div>Content & More Content</div>";
|
|
392
|
+
expect(preprocessHtml(input)).toEqual(expectedOutput);
|
|
393
|
+
});
|
|
394
|
+
|
|
395
|
+
it('should return the same string if there are no matching patterns', () => {
|
|
396
|
+
const input = "No special characters here!";
|
|
397
|
+
const expectedOutput = "No special characters here!";
|
|
398
|
+
expect(preprocessHtml(input)).toEqual(expectedOutput);
|
|
399
|
+
});
|
|
400
|
+
|
|
401
|
+
it('should handle an empty string input', () => {
|
|
402
|
+
const input = "";
|
|
403
|
+
const expectedOutput = "";
|
|
404
|
+
expect(preprocessHtml(input)).toEqual(expectedOutput);
|
|
405
|
+
});
|
|
406
|
+
|
|
407
|
+
it('should handle strings with only newline characters', () => {
|
|
408
|
+
const input = "\n\n\n";
|
|
409
|
+
const expectedOutput = "";
|
|
410
|
+
expect(preprocessHtml(input)).toEqual(expectedOutput);
|
|
411
|
+
});
|
|
412
|
+
|
|
413
|
+
it('should not affect similar but non-matching sequences', () => {
|
|
414
|
+
const input = "This is &lt; not an entity.";
|
|
415
|
+
const expectedOutput = "This is &lt; not an entity.";
|
|
416
|
+
expect(preprocessHtml(input)).toEqual(expectedOutput);
|
|
417
|
+
});
|
|
418
|
+
|
|
419
|
+
});
|
|
@@ -50,16 +50,18 @@ const CKEditorConfig = {
|
|
|
50
50
|
fullPage: true,
|
|
51
51
|
htmlEncodeOutput: true,
|
|
52
52
|
startupFocus: true,
|
|
53
|
-
allowedContent: {
|
|
54
|
-
// Allow all content.
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
},
|
|
53
|
+
// allowedContent: {
|
|
54
|
+
// // Allow all content.
|
|
55
|
+
// $1: {
|
|
56
|
+
// // elements: this.editorInstance.dtd,
|
|
57
|
+
// //elements: window.CKEDITOR.dtd,
|
|
58
|
+
// attributes: true,
|
|
59
|
+
// styles: true,
|
|
60
|
+
// classes: true,
|
|
61
|
+
// },
|
|
62
|
+
// },
|
|
63
|
+
allowedContent: true, // Allow all content, including attributes and styles
|
|
64
|
+
extraAllowedContent: 'img[width,height]',
|
|
63
65
|
disallowedContent: 'script; *[on*]',
|
|
64
66
|
language: locale,
|
|
65
67
|
toolbar_Basic:
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import PropTypes from "prop-types";
|
|
3
|
+
import CapRow from "@capillarytech/cap-ui-library/CapRow";
|
|
4
|
+
import CapButton from "@capillarytech/cap-ui-library/CapButton";
|
|
5
|
+
import CapIcon from "@capillarytech/cap-ui-library/CapIcon";
|
|
6
|
+
import CapLabel from "@capillarytech/cap-ui-library/CapLabel";
|
|
7
|
+
import CapList from "@capillarytech/cap-ui-library/CapList";
|
|
8
|
+
import {
|
|
9
|
+
FormattedMessage,
|
|
10
|
+
FormattedNumber,
|
|
11
|
+
injectIntl,
|
|
12
|
+
intlShape,
|
|
13
|
+
} from "react-intl";
|
|
14
|
+
import "./style.scss";
|
|
15
|
+
import messages from "./messages";
|
|
16
|
+
|
|
17
|
+
export const ErrorInfoNote = (props) => {
|
|
18
|
+
|
|
19
|
+
const { LIQUID_ERROR_MSG = [], STANDARD_ERROR_MSG = [] } = props?.errorMessages || {};
|
|
20
|
+
|
|
21
|
+
const ErrorSection = ({ title = "", errors = [], liquidError = false }) => (
|
|
22
|
+
<>
|
|
23
|
+
<CapRow
|
|
24
|
+
className={`error-header ${!liquidError ? "standard-error-header": ""}`}
|
|
25
|
+
>
|
|
26
|
+
<>
|
|
27
|
+
<CapIcon size="s" type="warning" className="warning-icon" />
|
|
28
|
+
{title}
|
|
29
|
+
</>
|
|
30
|
+
<>
|
|
31
|
+
{liquidError && (
|
|
32
|
+
<CapButton
|
|
33
|
+
type="flat"
|
|
34
|
+
className="add-btn"
|
|
35
|
+
onClick={() =>
|
|
36
|
+
window.open(`https://docs.capillarytech.com/docs/liquid-language-in-messages`, "_blank")
|
|
37
|
+
}
|
|
38
|
+
>
|
|
39
|
+
<FormattedMessage {...messages.liquidDoc} />
|
|
40
|
+
<CapIcon size="s" type="launch" />
|
|
41
|
+
</CapButton>
|
|
42
|
+
)}
|
|
43
|
+
</>
|
|
44
|
+
</CapRow>
|
|
45
|
+
<CapList
|
|
46
|
+
className="error-list"
|
|
47
|
+
size="small"
|
|
48
|
+
dataSource={errors}
|
|
49
|
+
renderItem={(error, index) => (
|
|
50
|
+
<CapList.Item>
|
|
51
|
+
<CapLabel type="label2" className="cap-list-v2-error-item">
|
|
52
|
+
<CapLabel type="label2"><FormattedNumber value={index + 1} />.</CapLabel>
|
|
53
|
+
<CapLabel type="label2">{error}</CapLabel>
|
|
54
|
+
</CapLabel>
|
|
55
|
+
</CapList.Item>
|
|
56
|
+
)}
|
|
57
|
+
/>
|
|
58
|
+
</>
|
|
59
|
+
);
|
|
60
|
+
const liquidErrors = LIQUID_ERROR_MSG?.length;
|
|
61
|
+
return (
|
|
62
|
+
<div className="error-container">
|
|
63
|
+
{STANDARD_ERROR_MSG?.length > 0 && (
|
|
64
|
+
<>
|
|
65
|
+
<ErrorSection
|
|
66
|
+
title={
|
|
67
|
+
<FormattedMessage {...messages.standardErrorHeader} />
|
|
68
|
+
}
|
|
69
|
+
errors={STANDARD_ERROR_MSG}
|
|
70
|
+
/>
|
|
71
|
+
</>
|
|
72
|
+
)}
|
|
73
|
+
{liquidErrors > 0 && (
|
|
74
|
+
<ErrorSection
|
|
75
|
+
title={<FormattedMessage {...messages.dynamicErrorHeader} />}
|
|
76
|
+
errors={LIQUID_ERROR_MSG}
|
|
77
|
+
liquidError={true}
|
|
78
|
+
/>
|
|
79
|
+
)}
|
|
80
|
+
</div>
|
|
81
|
+
);
|
|
82
|
+
};
|
|
83
|
+
ErrorInfoNote.propTypes = {
|
|
84
|
+
errorMessage: PropTypes.string,
|
|
85
|
+
errorType: PropTypes.string,
|
|
86
|
+
intl: intlShape.isRequired,
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
export default injectIntl(ErrorInfoNote);
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* ErrorInfoNote Messages
|
|
3
|
+
*
|
|
4
|
+
* This contains all the text for the ErrorInfoNote component.
|
|
5
|
+
*/
|
|
6
|
+
import { defineMessages } from "react-intl";
|
|
7
|
+
const scope = "creatives.componentsV2.ErrorInfoNote";
|
|
8
|
+
export default defineMessages({
|
|
9
|
+
dynamicErrorHeader: {
|
|
10
|
+
id: `${scope}.dynamicErrorHeader`,
|
|
11
|
+
defaultMessage:
|
|
12
|
+
"Errors found. Recommendations to fix the Liquid expression",
|
|
13
|
+
},
|
|
14
|
+
standardErrorHeader: {
|
|
15
|
+
id: `${scope}.standardErrorHeader`,
|
|
16
|
+
defaultMessage:
|
|
17
|
+
"Error found in Standard Tags",
|
|
18
|
+
},
|
|
19
|
+
liquidDoc: {
|
|
20
|
+
id: `${scope}.liquidDoc`,
|
|
21
|
+
defaultMessage:
|
|
22
|
+
"Liquid documentation",
|
|
23
|
+
},
|
|
24
|
+
ariaFooter: {
|
|
25
|
+
id: `${scope}.ariaFooter`,
|
|
26
|
+
defaultMessage:
|
|
27
|
+
"Aira can make mistakes. Please verify the suggestions before applying them"
|
|
28
|
+
},
|
|
29
|
+
});
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
@import "~@capillarytech/cap-ui-library/styles/_variables.scss";
|
|
2
|
+
|
|
3
|
+
.error-container {
|
|
4
|
+
margin-bottom: $CAP_SPACE_08;
|
|
5
|
+
margin-top: $CAP_SPACE_12;
|
|
6
|
+
background-color: $CAP_COLOR_05;
|
|
7
|
+
border-radius: $CAP_SPACE_04;
|
|
8
|
+
padding: $CAP_SPACE_08 $CAP_SPACE_12 $CAP_SPACE_08 $CAP_SPACE_08;
|
|
9
|
+
gap: $CAP_SPACE_08;
|
|
10
|
+
box-sizing: border-box;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.error-header {
|
|
14
|
+
width: 100%;
|
|
15
|
+
height: $CAP_SPACE_32;
|
|
16
|
+
display: inline-flex;
|
|
17
|
+
align-items: center;
|
|
18
|
+
justify-content: space-between;
|
|
19
|
+
font-weight: 500;
|
|
20
|
+
|
|
21
|
+
.ant-btn.cap-button-v2.flat-btn {
|
|
22
|
+
display: flex;
|
|
23
|
+
margin-left: auto;
|
|
24
|
+
background-color: inherit;
|
|
25
|
+
align-items: center;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.warning-icon {
|
|
29
|
+
vertical-align: text-top;
|
|
30
|
+
margin-right: $CAP_SPACE_04;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.standard-error-header {
|
|
35
|
+
justify-content: flex-start;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.error-list {
|
|
39
|
+
overflow: scroll;
|
|
40
|
+
max-height: $CAP_SPACE_80;
|
|
41
|
+
padding: 0;
|
|
42
|
+
|
|
43
|
+
&.ant-list.cap-list-v2.ant-list-split .ant-list-item {
|
|
44
|
+
padding-top: $CAP_SPACE_04;
|
|
45
|
+
padding-bottom: $CAP_SPACE_04;
|
|
46
|
+
border-bottom: 0;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
&.ant-list .ant-list-item:last-child {
|
|
50
|
+
border-bottom: none;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.cap-list-v2-error-item {
|
|
54
|
+
color: $CAP_G01;
|
|
55
|
+
font-size: $CAP_SPACE_12;
|
|
56
|
+
display: flex;
|
|
57
|
+
margin-left: $CAP_SPACE_04;
|
|
58
|
+
gap: $CAP_SPACE_04;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
.liquid-divider {
|
|
62
|
+
&.ant-divider.cap-divider-v2{
|
|
63
|
+
background: $FONT_COLOR_04;
|
|
64
|
+
}
|
|
65
|
+
margin: $CAP_SPACE_08 0;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
.aria-error-footer {
|
|
69
|
+
display: flex;
|
|
70
|
+
align-items: center;
|
|
71
|
+
gap: $CAP_SPACE_04;
|
|
72
|
+
}
|