form0-core 0.1.12 → 0.1.13
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 +1 -1
- package/src/utilities/dataset-descriptors.js +193 -18
package/package.json
CHANGED
|
@@ -87,8 +87,11 @@ const QUERY_SEMANTICS_BY_FIELD_TYPE = {
|
|
|
87
87
|
default_operator: 'contains',
|
|
88
88
|
allowed_operators: [
|
|
89
89
|
'contains',
|
|
90
|
+
'not_contains',
|
|
90
91
|
'eq',
|
|
91
92
|
'neq',
|
|
93
|
+
'in',
|
|
94
|
+
'not_in',
|
|
92
95
|
'starts_with',
|
|
93
96
|
'ends_with',
|
|
94
97
|
'is_blank',
|
|
@@ -109,6 +112,8 @@ const QUERY_SEMANTICS_BY_FIELD_TYPE = {
|
|
|
109
112
|
'neq',
|
|
110
113
|
'gt',
|
|
111
114
|
'lt',
|
|
115
|
+
'in',
|
|
116
|
+
'not_in',
|
|
112
117
|
'is_blank',
|
|
113
118
|
'is_not_blank',
|
|
114
119
|
],
|
|
@@ -127,6 +132,8 @@ const QUERY_SEMANTICS_BY_FIELD_TYPE = {
|
|
|
127
132
|
'neq',
|
|
128
133
|
'gt',
|
|
129
134
|
'lt',
|
|
135
|
+
'in',
|
|
136
|
+
'not_in',
|
|
130
137
|
'is_blank',
|
|
131
138
|
'is_not_blank',
|
|
132
139
|
],
|
|
@@ -145,6 +152,8 @@ const QUERY_SEMANTICS_BY_FIELD_TYPE = {
|
|
|
145
152
|
'neq',
|
|
146
153
|
'gt',
|
|
147
154
|
'lt',
|
|
155
|
+
'in',
|
|
156
|
+
'not_in',
|
|
148
157
|
'is_blank',
|
|
149
158
|
'is_not_blank',
|
|
150
159
|
],
|
|
@@ -202,6 +211,8 @@ const getCalculatedFieldSemantics = (field) => {
|
|
|
202
211
|
'neq',
|
|
203
212
|
'gt',
|
|
204
213
|
'lt',
|
|
214
|
+
'in',
|
|
215
|
+
'not_in',
|
|
205
216
|
'is_blank',
|
|
206
217
|
'is_not_blank',
|
|
207
218
|
],
|
|
@@ -223,6 +234,8 @@ const getCalculatedFieldSemantics = (field) => {
|
|
|
223
234
|
'neq',
|
|
224
235
|
'gt',
|
|
225
236
|
'lt',
|
|
237
|
+
'in',
|
|
238
|
+
'not_in',
|
|
226
239
|
'is_blank',
|
|
227
240
|
'is_not_blank',
|
|
228
241
|
],
|
|
@@ -244,6 +257,8 @@ const getCalculatedFieldSemantics = (field) => {
|
|
|
244
257
|
'neq',
|
|
245
258
|
'gt',
|
|
246
259
|
'lt',
|
|
260
|
+
'in',
|
|
261
|
+
'not_in',
|
|
247
262
|
'is_blank',
|
|
248
263
|
'is_not_blank',
|
|
249
264
|
],
|
|
@@ -258,8 +273,11 @@ const getCalculatedFieldSemantics = (field) => {
|
|
|
258
273
|
default_operator: 'contains',
|
|
259
274
|
allowed_operators: [
|
|
260
275
|
'contains',
|
|
276
|
+
'not_contains',
|
|
261
277
|
'eq',
|
|
262
278
|
'neq',
|
|
279
|
+
'in',
|
|
280
|
+
'not_in',
|
|
263
281
|
'starts_with',
|
|
264
282
|
'ends_with',
|
|
265
283
|
'is_blank',
|
|
@@ -293,33 +311,179 @@ const toChoiceValueList = (field) => {
|
|
|
293
311
|
return field.choices.filter((choice) => isRecord(choice));
|
|
294
312
|
};
|
|
295
313
|
|
|
296
|
-
const
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
314
|
+
const isChoicePrimitive = (value) =>
|
|
315
|
+
typeof value === 'string' ||
|
|
316
|
+
typeof value === 'number' ||
|
|
317
|
+
typeof value === 'boolean';
|
|
318
|
+
|
|
319
|
+
const normalizeChoiceEntryValue = (entry) => {
|
|
320
|
+
if (isChoicePrimitive(entry)) {
|
|
321
|
+
return entry;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
if (!isRecord(entry)) {
|
|
325
|
+
return undefined;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
if (isChoicePrimitive(entry.value)) {
|
|
329
|
+
return entry.value;
|
|
300
330
|
}
|
|
301
331
|
|
|
302
|
-
|
|
303
|
-
|
|
332
|
+
if (isChoicePrimitive(entry.label)) {
|
|
333
|
+
return entry.label;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
return undefined;
|
|
337
|
+
};
|
|
338
|
+
|
|
339
|
+
const normalizeChoiceEntryDisplayValue = (entry) => {
|
|
340
|
+
if (isChoicePrimitive(entry)) {
|
|
341
|
+
return entry;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
if (!isRecord(entry)) {
|
|
345
|
+
return undefined;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
if (isChoicePrimitive(entry.label)) {
|
|
349
|
+
return entry.label;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
if (isChoicePrimitive(entry.value)) {
|
|
353
|
+
return entry.value;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
return undefined;
|
|
357
|
+
};
|
|
358
|
+
|
|
359
|
+
const normalizeChoiceEntryLabel = (field, entry) => {
|
|
360
|
+
const normalizedValue = normalizeChoiceEntryValue(entry);
|
|
361
|
+
if (typeof normalizedValue === 'undefined') {
|
|
362
|
+
return undefined;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
const matched = toChoiceValueList(field).find(
|
|
366
|
+
(choice) =>
|
|
367
|
+
Object.prototype.hasOwnProperty.call(choice, 'value') &&
|
|
368
|
+
choice.value === normalizedValue,
|
|
304
369
|
);
|
|
305
|
-
if (
|
|
306
|
-
return
|
|
370
|
+
if (matched) {
|
|
371
|
+
return toTrimmedString(matched.label) ?? normalizedValue;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
if (isRecord(entry) && isChoicePrimitive(entry.label)) {
|
|
375
|
+
return entry.label;
|
|
307
376
|
}
|
|
308
377
|
|
|
309
|
-
return
|
|
378
|
+
return normalizedValue;
|
|
310
379
|
};
|
|
311
380
|
|
|
312
|
-
const
|
|
313
|
-
if (
|
|
381
|
+
const toSingleChoiceSelectionValues = (rawValue) => {
|
|
382
|
+
if (isRecord(rawValue)) {
|
|
383
|
+
const choiceValues = Array.isArray(rawValue.choice)
|
|
384
|
+
? rawValue.choice
|
|
385
|
+
.map((entry) => normalizeChoiceEntryValue(entry))
|
|
386
|
+
.filter((entry) => typeof entry !== 'undefined')
|
|
387
|
+
: [];
|
|
388
|
+
const otherValues = Array.isArray(rawValue.other)
|
|
389
|
+
? rawValue.other
|
|
390
|
+
.map((entry) => normalizeChoiceEntryValue(entry))
|
|
391
|
+
.filter((entry) => typeof entry !== 'undefined')
|
|
392
|
+
: [];
|
|
393
|
+
|
|
394
|
+
return [...choiceValues, ...otherValues];
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
const normalized = normalizeChoiceEntryValue(rawValue);
|
|
398
|
+
return typeof normalized === 'undefined' ? [] : [normalized];
|
|
399
|
+
};
|
|
400
|
+
|
|
401
|
+
const toSingleChoiceDisplayValues = (field, rawValue) => {
|
|
402
|
+
if (isRecord(rawValue)) {
|
|
403
|
+
const choiceLabels = Array.isArray(rawValue.choice)
|
|
404
|
+
? rawValue.choice
|
|
405
|
+
.map((entry) => normalizeChoiceEntryLabel(field, entry))
|
|
406
|
+
.filter((entry) => typeof entry !== 'undefined')
|
|
407
|
+
: [];
|
|
408
|
+
const otherLabels = Array.isArray(rawValue.other)
|
|
409
|
+
? rawValue.other
|
|
410
|
+
.map((entry) => normalizeChoiceEntryDisplayValue(entry))
|
|
411
|
+
.filter((entry) => typeof entry !== 'undefined')
|
|
412
|
+
: [];
|
|
413
|
+
|
|
414
|
+
return [...choiceLabels, ...otherLabels];
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
const normalized = normalizeChoiceEntryLabel(field, rawValue);
|
|
418
|
+
return typeof normalized === 'undefined' ? [] : [normalized];
|
|
419
|
+
};
|
|
420
|
+
|
|
421
|
+
const toMultiChoiceSelectionValues = (rawValue) => {
|
|
422
|
+
if (isRecord(rawValue)) {
|
|
423
|
+
const selectedValues = Array.isArray(rawValue.choices)
|
|
424
|
+
? rawValue.choices
|
|
425
|
+
.map((entry) => normalizeChoiceEntryValue(entry))
|
|
426
|
+
.filter((entry) => typeof entry !== 'undefined')
|
|
427
|
+
: [];
|
|
428
|
+
const otherValues = Array.isArray(rawValue.other)
|
|
429
|
+
? rawValue.other
|
|
430
|
+
.map((entry) => normalizeChoiceEntryValue(entry))
|
|
431
|
+
.filter((entry) => typeof entry !== 'undefined')
|
|
432
|
+
: [];
|
|
433
|
+
|
|
434
|
+
return [...selectedValues, ...otherValues];
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
if (Array.isArray(rawValue)) {
|
|
438
|
+
return rawValue
|
|
439
|
+
.map((entry) => normalizeChoiceEntryValue(entry))
|
|
440
|
+
.filter((entry) => typeof entry !== 'undefined');
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
return [];
|
|
444
|
+
};
|
|
445
|
+
|
|
446
|
+
const toMultiChoiceDisplayValues = (field, rawValue) => {
|
|
447
|
+
if (isRecord(rawValue)) {
|
|
448
|
+
const selectedLabels = Array.isArray(rawValue.choices)
|
|
449
|
+
? rawValue.choices
|
|
450
|
+
.map((entry) => normalizeChoiceEntryLabel(field, entry))
|
|
451
|
+
.filter((entry) => typeof entry !== 'undefined')
|
|
452
|
+
: [];
|
|
453
|
+
const otherLabels = Array.isArray(rawValue.other)
|
|
454
|
+
? rawValue.other
|
|
455
|
+
.map((entry) => normalizeChoiceEntryDisplayValue(entry))
|
|
456
|
+
.filter((entry) => typeof entry !== 'undefined')
|
|
457
|
+
: [];
|
|
458
|
+
|
|
459
|
+
return [...selectedLabels, ...otherLabels];
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
if (Array.isArray(rawValue)) {
|
|
463
|
+
return rawValue
|
|
464
|
+
.map((entry) => normalizeChoiceEntryLabel(field, entry))
|
|
465
|
+
.filter((entry) => typeof entry !== 'undefined');
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
return [];
|
|
469
|
+
};
|
|
470
|
+
|
|
471
|
+
const toSingleChoiceLabel = (field, rawValue) => {
|
|
472
|
+
const labels = toSingleChoiceDisplayValues(field, rawValue);
|
|
473
|
+
if (labels.length === 0) {
|
|
314
474
|
return rawValue;
|
|
315
475
|
}
|
|
316
476
|
|
|
317
|
-
|
|
318
|
-
|
|
477
|
+
return labels.length === 1 ? labels[0] : labels;
|
|
478
|
+
};
|
|
479
|
+
|
|
480
|
+
const toMultiChoiceLabels = (field, rawValue) => {
|
|
481
|
+
const labels = toMultiChoiceDisplayValues(field, rawValue);
|
|
482
|
+
if (labels.length === 0) {
|
|
319
483
|
return rawValue;
|
|
320
484
|
}
|
|
321
485
|
|
|
322
|
-
return
|
|
486
|
+
return labels;
|
|
323
487
|
};
|
|
324
488
|
|
|
325
489
|
const toDisplayValue = (field, rawValue) => {
|
|
@@ -497,7 +661,14 @@ const readFirstAliasValue = (value, aliases) => {
|
|
|
497
661
|
return undefined;
|
|
498
662
|
};
|
|
499
663
|
|
|
500
|
-
const normalizeScalarValue = (value) => {
|
|
664
|
+
const normalizeScalarValue = (field, value) => {
|
|
665
|
+
if (
|
|
666
|
+
field?.field_type === 'SingleChoiceField' ||
|
|
667
|
+
field?.field_type === 'BooleanField'
|
|
668
|
+
) {
|
|
669
|
+
return toSingleChoiceSelectionValues(value)[0];
|
|
670
|
+
}
|
|
671
|
+
|
|
501
672
|
if (Array.isArray(value)) {
|
|
502
673
|
return undefined;
|
|
503
674
|
}
|
|
@@ -505,7 +676,11 @@ const normalizeScalarValue = (value) => {
|
|
|
505
676
|
return value;
|
|
506
677
|
};
|
|
507
678
|
|
|
508
|
-
const normalizeTermValues = (value) => {
|
|
679
|
+
const normalizeTermValues = (field, value) => {
|
|
680
|
+
if (field?.field_type === 'MultiChoiceField') {
|
|
681
|
+
return toMultiChoiceSelectionValues(value);
|
|
682
|
+
}
|
|
683
|
+
|
|
509
684
|
if (!Array.isArray(value)) {
|
|
510
685
|
return [];
|
|
511
686
|
}
|
|
@@ -539,7 +714,7 @@ export function projectDatasetRowValues(descriptor, rowValues) {
|
|
|
539
714
|
displayValues[field.field_id] = toDisplayValue(field, rawValue);
|
|
540
715
|
|
|
541
716
|
if (field.query_kind === 'scalar') {
|
|
542
|
-
const scalarValue = normalizeScalarValue(rawValue);
|
|
717
|
+
const scalarValue = normalizeScalarValue(field, rawValue);
|
|
543
718
|
if (typeof scalarValue !== 'undefined') {
|
|
544
719
|
scalarValues[field.field_id] = scalarValue;
|
|
545
720
|
}
|
|
@@ -547,7 +722,7 @@ export function projectDatasetRowValues(descriptor, rowValues) {
|
|
|
547
722
|
}
|
|
548
723
|
|
|
549
724
|
if (field.query_kind === 'terms') {
|
|
550
|
-
const terms = normalizeTermValues(rawValue);
|
|
725
|
+
const terms = normalizeTermValues(field, rawValue);
|
|
551
726
|
if (terms.length > 0) {
|
|
552
727
|
termValues[field.field_id] = terms;
|
|
553
728
|
}
|