@gooddata/sdk-code-convertors 11.51.0-alpha.2 → 11.51.0-alpha.4
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/esm/configs/headlineChart.d.ts.map +1 -1
- package/esm/configs/headlineChart.js +9 -3
- package/esm/configs/types.d.ts +2 -1
- package/esm/configs/types.d.ts.map +1 -1
- package/esm/from/declarativeDashboardToYaml.d.ts.map +1 -1
- package/esm/from/declarativeDashboardToYaml.js +13 -0
- package/esm/from/declarativeVisualisationToYaml.d.ts +2 -27
- package/esm/from/declarativeVisualisationToYaml.d.ts.map +1 -1
- package/esm/from/declarativeVisualisationToYaml.js +132 -556
- package/esm/from/filtersToYaml.d.ts +50 -0
- package/esm/from/filtersToYaml.d.ts.map +1 -0
- package/esm/from/filtersToYaml.js +508 -0
- package/esm/index.d.ts +2 -1
- package/esm/index.d.ts.map +1 -1
- package/esm/index.js +2 -1
- package/esm/sdk-code-convertors.d.ts +33 -5
- package/esm/to/yamlDashboardToDeclarative.d.ts +1 -1
- package/esm/to/yamlDashboardToDeclarative.d.ts.map +1 -1
- package/esm/to/yamlDashboardToDeclarative.js +15 -0
- package/esm/to/yamlVisualisationToDeclarative.d.ts +1 -1
- package/esm/to/yamlVisualisationToDeclarative.d.ts.map +1 -1
- package/esm/to/yamlVisualisationToDeclarative.js +41 -28
- package/esm/utils/configUtils.d.ts +5 -1
- package/esm/utils/configUtils.d.ts.map +1 -1
- package/esm/utils/configUtils.js +25 -13
- package/esm/utils/errors.d.ts +3 -0
- package/esm/utils/errors.d.ts.map +1 -1
- package/esm/utils/errors.js +9 -0
- package/package.json +6 -6
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// (C) 2023-2026 GoodData Corporation
|
|
2
2
|
import { Document, Pair, YAMLMap, YAMLSeq } from "yaml";
|
|
3
|
-
import {
|
|
3
|
+
import { filterLocalIdentifier, isArithmeticMeasureDefinition, isAttribute, isAttributeLocator, isAttributeSort, isBucket, isFilter, isInlineMeasureDefinition, isInsight, isMeasure, isMeasureDefinition, isMeasureLocator, isMeasureSort, isPoPMeasureDefinition, isPreviousPeriodMeasureDefinition, isTotalLocator, } from "@gooddata/sdk-model";
|
|
4
4
|
import { areaChart } from "../configs/areaChart.js";
|
|
5
5
|
import { barChart } from "../configs/barChart.js";
|
|
6
6
|
import { bubbleChart } from "../configs/bubbleChart.js";
|
|
@@ -26,12 +26,11 @@ import { treemapChart } from "../configs/treemapChart.js";
|
|
|
26
26
|
import { waterfallChart } from "../configs/waterfallChart.js";
|
|
27
27
|
import { BucketsType } from "../types.js";
|
|
28
28
|
import { CoreErrorCode, newError, updateErrorContext } from "../utils/errors.js";
|
|
29
|
-
import { matchConditionToYaml, parseDateValues } from "../utils/filterUtils.js";
|
|
30
|
-
import { parseGranularity } from "../utils/granularityUtils.js";
|
|
31
29
|
import { remapLocationAttribute } from "../utils/locationUtils.js";
|
|
32
30
|
import { VISUALISATION_COMMENT } from "../utils/texts.js";
|
|
33
31
|
import { visualizationUrlToYamlVisType } from "../utils/visualisationTypeMap.js";
|
|
34
|
-
import { cleanUpItems,
|
|
32
|
+
import { cleanUpItems, entryWithSpace, fillOptionalMetaFields, getIdentifier } from "../utils/yamlUtils.js";
|
|
33
|
+
import { declarativeFiltersToYaml } from "./filtersToYaml.js";
|
|
35
34
|
/** @public */
|
|
36
35
|
export function declarativeVisualisationToYaml(entities, visualisation, context) {
|
|
37
36
|
const errorContext = updateErrorContext(context, {
|
|
@@ -71,6 +70,12 @@ export function declarativeVisualisationToYaml(entities, visualisation, context)
|
|
|
71
70
|
declarativeVisToYaml(doc, insight.insight, report, entities, updateErrorContext(errorContext, {
|
|
72
71
|
path: ["insight"],
|
|
73
72
|
}));
|
|
73
|
+
report.buckets.assertAllConsumed(errorContext);
|
|
74
|
+
// Only a type whose grammar has `layers:` writes them; any other drops the list whole, and its fields
|
|
75
|
+
// are already merged into `query.fields` by then, left declared and unreferenced.
|
|
76
|
+
if ((insight.insight.layers ?? []).length > 0 && doc.get("layers") === undefined) {
|
|
77
|
+
throw newError(CoreErrorCode.ItemNotSupported, ["layers"], updateErrorContext(errorContext, { path: ["layers"] }));
|
|
78
|
+
}
|
|
74
79
|
return {
|
|
75
80
|
content: doc.toString({
|
|
76
81
|
lineWidth: 0,
|
|
@@ -78,6 +83,30 @@ export function declarativeVisualisationToYaml(entities, visualisation, context)
|
|
|
78
83
|
json: doc.toJSON(),
|
|
79
84
|
};
|
|
80
85
|
}
|
|
86
|
+
/**
|
|
87
|
+
* Every type reads the buckets it writes by looking them up, so one it never looks up is dropped whole,
|
|
88
|
+
* taking its items with it.
|
|
89
|
+
*/
|
|
90
|
+
function bucketRegistry(groups) {
|
|
91
|
+
// Recorded per group, since two groups may share a type and one lookup reaches only the first.
|
|
92
|
+
const consumed = new Set();
|
|
93
|
+
return {
|
|
94
|
+
consume(type) {
|
|
95
|
+
const found = groups.find((group) => group.type === type);
|
|
96
|
+
if (found) {
|
|
97
|
+
consumed.add(found);
|
|
98
|
+
}
|
|
99
|
+
return found;
|
|
100
|
+
},
|
|
101
|
+
// An empty bucket carries nothing to lose, so only one holding items is refused.
|
|
102
|
+
assertAllConsumed(errorContext) {
|
|
103
|
+
const dropped = groups.find((group) => group.items.length > 0 && !consumed.has(group));
|
|
104
|
+
if (dropped) {
|
|
105
|
+
throw newError(CoreErrorCode.ItemNotSupported, [`bucket "${dropped.type}"`], updateErrorContext(errorContext, { path: ["buckets", dropped.type] }));
|
|
106
|
+
}
|
|
107
|
+
},
|
|
108
|
+
};
|
|
109
|
+
}
|
|
81
110
|
function declarativeReportToYaml(entities, def, errorContext) {
|
|
82
111
|
const report = new YAMLMap();
|
|
83
112
|
const { fieldsMap, postProcessors, groups: derivedBuckets, } = declarativeBucketsToYaml(entities, def.buckets, updateErrorContext(errorContext, {
|
|
@@ -117,7 +146,7 @@ function declarativeReportToYaml(entities, def, errorContext) {
|
|
|
117
146
|
});
|
|
118
147
|
return {
|
|
119
148
|
report,
|
|
120
|
-
derivedBuckets,
|
|
149
|
+
buckets: bucketRegistry(derivedBuckets),
|
|
121
150
|
};
|
|
122
151
|
}
|
|
123
152
|
function appendLayerFieldsToReport(fieldsMap, postProcessors, entities, layers, errorContext) {
|
|
@@ -283,6 +312,9 @@ export function declarativeBucketsToYaml(entities, buckets, errorContext) {
|
|
|
283
312
|
filters: [],
|
|
284
313
|
};
|
|
285
314
|
const addField = (local, def, group, { format, axis } = {}) => {
|
|
315
|
+
if (fullFieldsMap.has(local)) {
|
|
316
|
+
throw newError(CoreErrorCode.DuplicateFieldName, [local], errorContext);
|
|
317
|
+
}
|
|
286
318
|
fullFieldsMap.add(new Pair(local, def));
|
|
287
319
|
group.items.push(createBucketGroupItem(local, format, axis));
|
|
288
320
|
};
|
|
@@ -497,481 +529,6 @@ function getShortenedBucket(def) {
|
|
|
497
529
|
}
|
|
498
530
|
return false;
|
|
499
531
|
}
|
|
500
|
-
function detectEmptyValuesFilterType(filter) {
|
|
501
|
-
const attributeElements = filterAttributeElements(filter);
|
|
502
|
-
const items = attributeElements ? getAttributeElementsItems(attributeElements) : [];
|
|
503
|
-
if (items.length !== 1 || items[0] !== "") {
|
|
504
|
-
return undefined;
|
|
505
|
-
}
|
|
506
|
-
return isPositiveAttributeFilter(filter) ? "only" : "exclude";
|
|
507
|
-
}
|
|
508
|
-
function getObjRefGroupingKey(objRef) {
|
|
509
|
-
if (!objRef || typeof objRef !== "object") {
|
|
510
|
-
return undefined;
|
|
511
|
-
}
|
|
512
|
-
if ("identifier" in objRef) {
|
|
513
|
-
const identifier = objRef.identifier;
|
|
514
|
-
if (typeof identifier === "string") {
|
|
515
|
-
return identifier;
|
|
516
|
-
}
|
|
517
|
-
if (identifier && typeof identifier === "object" && "id" in identifier) {
|
|
518
|
-
const id = identifier.id;
|
|
519
|
-
if (typeof id === "string") {
|
|
520
|
-
return id;
|
|
521
|
-
}
|
|
522
|
-
}
|
|
523
|
-
}
|
|
524
|
-
if ("uri" in objRef) {
|
|
525
|
-
const uri = objRef.uri;
|
|
526
|
-
if (typeof uri === "string") {
|
|
527
|
-
return uri;
|
|
528
|
-
}
|
|
529
|
-
}
|
|
530
|
-
if ("localIdentifier" in objRef) {
|
|
531
|
-
const localIdentifier = objRef.localIdentifier;
|
|
532
|
-
if (typeof localIdentifier === "string") {
|
|
533
|
-
return localIdentifier;
|
|
534
|
-
}
|
|
535
|
-
}
|
|
536
|
-
return serializeObjRef(objRef);
|
|
537
|
-
}
|
|
538
|
-
/**
|
|
539
|
-
* Groups date filters with their associated attribute filters. Leaves the rest alone.
|
|
540
|
-
* @param filters
|
|
541
|
-
*/
|
|
542
|
-
function groupFiltersByDateFilter(filters) {
|
|
543
|
-
const dateFilters = [...filters].filter(isDateFilter);
|
|
544
|
-
const nonDateFilters = [...filters].filter((f) => !isDateFilter(f));
|
|
545
|
-
const result = { grouped: {}, rest: [] };
|
|
546
|
-
const getFilterRefDetails = (filter) => {
|
|
547
|
-
const objRef = filterObjRef(filter);
|
|
548
|
-
if (!objRef) {
|
|
549
|
-
return {
|
|
550
|
-
objRef: undefined,
|
|
551
|
-
filterRef: undefined,
|
|
552
|
-
};
|
|
553
|
-
}
|
|
554
|
-
return {
|
|
555
|
-
objRef,
|
|
556
|
-
filterRef: getObjRefGroupingKey(objRef),
|
|
557
|
-
};
|
|
558
|
-
};
|
|
559
|
-
dateFilters.forEach((dateFilter) => {
|
|
560
|
-
const { filterRef: datasetId } = getFilterRefDetails(dateFilter);
|
|
561
|
-
const fi = filters.indexOf(dateFilter);
|
|
562
|
-
if (datasetId === undefined) {
|
|
563
|
-
result.rest.push([dateFilter, fi]);
|
|
564
|
-
return;
|
|
565
|
-
}
|
|
566
|
-
if (result.grouped[datasetId]) {
|
|
567
|
-
result.rest.push([dateFilter, fi]);
|
|
568
|
-
}
|
|
569
|
-
else {
|
|
570
|
-
result.grouped[datasetId] = { dateFilter: [dateFilter, fi], attributeFilters: [] };
|
|
571
|
-
}
|
|
572
|
-
});
|
|
573
|
-
nonDateFilters.forEach((filter) => {
|
|
574
|
-
const { filterRef: filterId } = getFilterRefDetails(filter);
|
|
575
|
-
const fi = filters.indexOf(filter);
|
|
576
|
-
if (filterId === undefined) {
|
|
577
|
-
result.rest.push([filter, fi]);
|
|
578
|
-
return;
|
|
579
|
-
}
|
|
580
|
-
const datasetId = filterId.split(".")[0];
|
|
581
|
-
const group = result.grouped[datasetId];
|
|
582
|
-
if (group) {
|
|
583
|
-
group.attributeFilters.push([filter, fi]);
|
|
584
|
-
}
|
|
585
|
-
else {
|
|
586
|
-
result.rest.push([filter, fi]);
|
|
587
|
-
}
|
|
588
|
-
});
|
|
589
|
-
return result;
|
|
590
|
-
}
|
|
591
|
-
/** @internal */
|
|
592
|
-
export function declarativeFiltersToYaml(entities, filters, errorContext) {
|
|
593
|
-
const filtersArray = [];
|
|
594
|
-
const filtersMap = {};
|
|
595
|
-
const usedKeys = new Set();
|
|
596
|
-
const getUniqueKey = (baseKey) => {
|
|
597
|
-
let key = baseKey;
|
|
598
|
-
let suffix = 2;
|
|
599
|
-
while (usedKeys.has(key)) {
|
|
600
|
-
key = `${baseKey}_${suffix}`;
|
|
601
|
-
suffix += 1;
|
|
602
|
-
}
|
|
603
|
-
usedKeys.add(key);
|
|
604
|
-
return key;
|
|
605
|
-
};
|
|
606
|
-
const filtersGroupedByDateFilter = groupFiltersByDateFilter(filters);
|
|
607
|
-
filtersGroupedByDateFilter.rest.forEach(([filter, fi]) => {
|
|
608
|
-
const result = declarativeFilterToYaml(entities, filter, getUniqueKey, undefined, updateErrorContext(errorContext, {
|
|
609
|
-
path: [fi.toString()],
|
|
610
|
-
}));
|
|
611
|
-
if (!result) {
|
|
612
|
-
return;
|
|
613
|
-
}
|
|
614
|
-
const { key, yaml, filter: originalFilter } = result;
|
|
615
|
-
filtersArray.push(new Pair(key, yaml));
|
|
616
|
-
filtersMap[key] = {
|
|
617
|
-
yaml,
|
|
618
|
-
filter: originalFilter,
|
|
619
|
-
};
|
|
620
|
-
});
|
|
621
|
-
Object.values(filtersGroupedByDateFilter.grouped).forEach(({ dateFilter, attributeFilters }) => {
|
|
622
|
-
const result = declarativeFilterToYaml(entities, dateFilter[0], getUniqueKey, attributeFilters.map(([f]) => f), updateErrorContext(errorContext, {
|
|
623
|
-
path: [dateFilter[1].toString()],
|
|
624
|
-
}));
|
|
625
|
-
if (!result) {
|
|
626
|
-
return;
|
|
627
|
-
}
|
|
628
|
-
const { key, yaml, filter: originalFilter } = result;
|
|
629
|
-
filtersArray.push(new Pair(key, yaml));
|
|
630
|
-
filtersMap[key] = {
|
|
631
|
-
yaml,
|
|
632
|
-
filter: originalFilter,
|
|
633
|
-
};
|
|
634
|
-
});
|
|
635
|
-
return {
|
|
636
|
-
filtersMap,
|
|
637
|
-
filtersArray: filtersArray.reduce((map, filter) => {
|
|
638
|
-
map.add(filter);
|
|
639
|
-
return map;
|
|
640
|
-
}, new YAMLMap()),
|
|
641
|
-
};
|
|
642
|
-
}
|
|
643
|
-
function declarativeFilterToYaml(entities, filter, getUniqueKey, connectedAttributeFilters, errorContext) {
|
|
644
|
-
if (!isFilter(filter)) {
|
|
645
|
-
return null;
|
|
646
|
-
}
|
|
647
|
-
const key = getUniqueKey(createFilterItemKeyName(filter, "date", updateErrorContext(errorContext, {
|
|
648
|
-
path: ["date"],
|
|
649
|
-
})));
|
|
650
|
-
if (isAbsoluteDateFilter(filter)) {
|
|
651
|
-
return {
|
|
652
|
-
key,
|
|
653
|
-
yaml: declarativeAbsoluteDateFilterToYaml(filter.absoluteDateFilter, connectedAttributeFilters, entities, getUniqueKey, updateErrorContext(errorContext, {
|
|
654
|
-
path: ["absoluteDateFilter"],
|
|
655
|
-
})),
|
|
656
|
-
filter,
|
|
657
|
-
};
|
|
658
|
-
}
|
|
659
|
-
if (isRelativeDateFilter(filter)) {
|
|
660
|
-
return {
|
|
661
|
-
key,
|
|
662
|
-
yaml: declarativeRelativeDateFilterToYaml(filter.relativeDateFilter, connectedAttributeFilters, entities, getUniqueKey, updateErrorContext(errorContext, {
|
|
663
|
-
path: ["relativeDateFilter"],
|
|
664
|
-
})),
|
|
665
|
-
filter,
|
|
666
|
-
};
|
|
667
|
-
}
|
|
668
|
-
if (isPositiveAttributeFilter(filter)) {
|
|
669
|
-
return {
|
|
670
|
-
key,
|
|
671
|
-
yaml: declarativePositiveAttributeFilterToYaml(entities, filter.positiveAttributeFilter, updateErrorContext(errorContext, {
|
|
672
|
-
path: ["positiveAttributeFilter"],
|
|
673
|
-
})),
|
|
674
|
-
filter,
|
|
675
|
-
};
|
|
676
|
-
}
|
|
677
|
-
if (isNegativeAttributeFilter(filter)) {
|
|
678
|
-
return {
|
|
679
|
-
key,
|
|
680
|
-
yaml: declarativeNegativeAttributeFilterToYaml(entities, filter.negativeAttributeFilter, updateErrorContext(errorContext, {
|
|
681
|
-
path: ["negativeAttributeFilter"],
|
|
682
|
-
})),
|
|
683
|
-
filter,
|
|
684
|
-
};
|
|
685
|
-
}
|
|
686
|
-
if (isArbitraryAttributeFilter(filter)) {
|
|
687
|
-
return {
|
|
688
|
-
key,
|
|
689
|
-
yaml: declarativeArbitraryAttributeFilterToYaml(filter.arbitraryAttributeFilter, updateErrorContext(errorContext, {
|
|
690
|
-
path: ["arbitraryAttributeFilter"],
|
|
691
|
-
})),
|
|
692
|
-
filter,
|
|
693
|
-
};
|
|
694
|
-
}
|
|
695
|
-
if (isMatchAttributeFilter(filter)) {
|
|
696
|
-
return {
|
|
697
|
-
key,
|
|
698
|
-
yaml: declarativeMatchAttributeFilterToYaml(filter.matchAttributeFilter, updateErrorContext(errorContext, {
|
|
699
|
-
path: ["matchAttributeFilter"],
|
|
700
|
-
})),
|
|
701
|
-
filter,
|
|
702
|
-
};
|
|
703
|
-
}
|
|
704
|
-
if (isMeasureValueFilter(filter)) {
|
|
705
|
-
return {
|
|
706
|
-
key,
|
|
707
|
-
yaml: declarativeMeasureValueFilterToYaml(filter.measureValueFilter, updateErrorContext(errorContext, {
|
|
708
|
-
path: ["measureValueFilter"],
|
|
709
|
-
})),
|
|
710
|
-
filter,
|
|
711
|
-
};
|
|
712
|
-
}
|
|
713
|
-
if (isRankingFilter(filter)) {
|
|
714
|
-
return {
|
|
715
|
-
key,
|
|
716
|
-
yaml: declarativeRankingFilterToYaml(filter.rankingFilter, updateErrorContext(errorContext, {
|
|
717
|
-
path: ["rankingFilter"],
|
|
718
|
-
})),
|
|
719
|
-
filter,
|
|
720
|
-
};
|
|
721
|
-
}
|
|
722
|
-
throw newError(CoreErrorCode.FilterItemTypeNotSupported, [JSON.stringify(filter)], errorContext);
|
|
723
|
-
}
|
|
724
|
-
/**
|
|
725
|
-
* Modifies `map`, adding `empty_filters` and `with` keys, populated from connectedAttributeFilters.
|
|
726
|
-
*/
|
|
727
|
-
function processConnectedAttributeFilters(map, connectedAttributeFilters, entities, getUniqueKey, errorContext) {
|
|
728
|
-
// empty values filter
|
|
729
|
-
const emptyValuesFilter = connectedAttributeFilters.find((filter) => detectEmptyValuesFilterType(filter));
|
|
730
|
-
if (emptyValuesFilter) {
|
|
731
|
-
map.add(new Pair("empty_values", detectEmptyValuesFilterType(emptyValuesFilter)));
|
|
732
|
-
}
|
|
733
|
-
// additional attribute filters
|
|
734
|
-
const additionalAttributeFilters = connectedAttributeFilters.filter((filter) => filter !== emptyValuesFilter);
|
|
735
|
-
if (additionalAttributeFilters.length === 0) {
|
|
736
|
-
return;
|
|
737
|
-
}
|
|
738
|
-
const withMap = new YAMLMap();
|
|
739
|
-
map.add(new Pair("with", withMap));
|
|
740
|
-
additionalAttributeFilters?.forEach((filter) => {
|
|
741
|
-
const converted = declarativeFilterToYaml(entities, filter, getUniqueKey, undefined, errorContext);
|
|
742
|
-
if (!converted) {
|
|
743
|
-
return;
|
|
744
|
-
}
|
|
745
|
-
withMap.add(new Pair(converted.key, converted.yaml));
|
|
746
|
-
});
|
|
747
|
-
}
|
|
748
|
-
/** @internal */
|
|
749
|
-
export function declarativeAbsoluteDateFilterToYaml(absoluteDateFilter, connectedAttributeFilters = [], entities, getUniqueKey, errorContext) {
|
|
750
|
-
const map = new YAMLMap();
|
|
751
|
-
// base date filter attributes
|
|
752
|
-
map.add(new Pair("type", "date_filter"));
|
|
753
|
-
map.add(new Pair("from", absoluteDateFilter.from));
|
|
754
|
-
map.add(new Pair("to", absoluteDateFilter.to));
|
|
755
|
-
const id = getIdentifier(absoluteDateFilter.dataSet, true, updateErrorContext(errorContext, {
|
|
756
|
-
path: ["dateSet"],
|
|
757
|
-
}));
|
|
758
|
-
map.add(new Pair("using", id));
|
|
759
|
-
// connected attribute filters
|
|
760
|
-
processConnectedAttributeFilters(map, connectedAttributeFilters, entities, getUniqueKey, errorContext);
|
|
761
|
-
return map;
|
|
762
|
-
}
|
|
763
|
-
function isRelativeDateFilterAllTime(relativeDateFilter) {
|
|
764
|
-
const { granularity, from, to } = relativeDateFilter;
|
|
765
|
-
// This should be enough to tell the type is IRelativeDateFilterAllTimeBody
|
|
766
|
-
if (granularity === "ALL_TIME_GRANULARITY") {
|
|
767
|
-
return true;
|
|
768
|
-
}
|
|
769
|
-
// But unfortunately AD emits granularity as GDC.time.year for an all time date filter, so we need this check as well
|
|
770
|
-
return granularity === "GDC.time.year" && from === undefined && to === undefined;
|
|
771
|
-
}
|
|
772
|
-
/** @internal */
|
|
773
|
-
export function declarativeRelativeDateFilterToYaml(relativeDateFilter, connectedAttributeFilters = [], entities, getUniqueKey, errorContext) {
|
|
774
|
-
const map = new YAMLMap();
|
|
775
|
-
map.add(new Pair("type", "date_filter"));
|
|
776
|
-
if (isRelativeDateFilterAllTime(relativeDateFilter)) {
|
|
777
|
-
// Do not add anything
|
|
778
|
-
}
|
|
779
|
-
else {
|
|
780
|
-
// Add granularity
|
|
781
|
-
if (relativeDateFilter.granularity) {
|
|
782
|
-
map.add(new Pair("granularity", parseGranularity(relativeDateFilter.granularity)));
|
|
783
|
-
}
|
|
784
|
-
// Add from/to only if both are defined
|
|
785
|
-
if (relativeDateFilter.from !== undefined && relativeDateFilter.to !== undefined) {
|
|
786
|
-
map.add(new Pair("from", relativeDateFilter.from));
|
|
787
|
-
map.add(new Pair("to", relativeDateFilter.to));
|
|
788
|
-
}
|
|
789
|
-
}
|
|
790
|
-
const id = getIdentifier(relativeDateFilter.dataSet, true, updateErrorContext(errorContext, {
|
|
791
|
-
path: ["dataSet"],
|
|
792
|
-
}));
|
|
793
|
-
map.add(new Pair("using", id));
|
|
794
|
-
processConnectedAttributeFilters(map, connectedAttributeFilters, entities, getUniqueKey, errorContext);
|
|
795
|
-
return map;
|
|
796
|
-
}
|
|
797
|
-
/** @internal */
|
|
798
|
-
export function declarativePositiveAttributeFilterToYaml(entities, attributeFilter, errorContext) {
|
|
799
|
-
const map = new YAMLMap();
|
|
800
|
-
map.add(new Pair("type", "attribute_filter"));
|
|
801
|
-
const id = getIdentifier(attributeFilter.displayForm, undefined, updateErrorContext(errorContext, {
|
|
802
|
-
path: ["displayForm"],
|
|
803
|
-
}));
|
|
804
|
-
map.add(new Pair("using", id));
|
|
805
|
-
if (isAttributeElementsByValue(attributeFilter.in)) {
|
|
806
|
-
const ind = attributeFilter.in;
|
|
807
|
-
// Filter out null/undefined but preserve empty strings which are valid attribute values
|
|
808
|
-
const values = ind.values.filter((v) => v !== null && v !== undefined);
|
|
809
|
-
map.add(new Pair("state", new Pair("include", parseDateValues(entities, id, values))));
|
|
810
|
-
}
|
|
811
|
-
return map;
|
|
812
|
-
}
|
|
813
|
-
/** @internal */
|
|
814
|
-
export function declarativeNegativeAttributeFilterToYaml(entities, attributeFilter, errorContext) {
|
|
815
|
-
const map = new YAMLMap();
|
|
816
|
-
map.add(new Pair("type", "attribute_filter"));
|
|
817
|
-
const id = getIdentifier(attributeFilter.displayForm, undefined, updateErrorContext(errorContext, {
|
|
818
|
-
path: ["displayForm"],
|
|
819
|
-
}));
|
|
820
|
-
map.add(new Pair("using", id));
|
|
821
|
-
if (isAttributeElementsByValue(attributeFilter.notIn)) {
|
|
822
|
-
const ind = attributeFilter.notIn;
|
|
823
|
-
// Filter out null/undefined but preserve empty strings which are valid attribute values
|
|
824
|
-
const values = ind.values.filter((v) => v !== null && v !== undefined);
|
|
825
|
-
if (values.length > 0) {
|
|
826
|
-
map.add(new Pair("state", new Pair("exclude", parseDateValues(entities, id, values))));
|
|
827
|
-
}
|
|
828
|
-
}
|
|
829
|
-
return map;
|
|
830
|
-
}
|
|
831
|
-
export function declarativeArbitraryAttributeFilterToYaml(attributeFilter, errorContext) {
|
|
832
|
-
const map = new YAMLMap();
|
|
833
|
-
map.add(new Pair("type", "text_filter"));
|
|
834
|
-
map.add(new Pair("using", getIdentifier(attributeFilter.label, undefined, updateErrorContext(errorContext, {
|
|
835
|
-
path: ["label"],
|
|
836
|
-
}))));
|
|
837
|
-
map.add(new Pair("condition", attributeFilter.negativeSelection ? "isNot" : "is"));
|
|
838
|
-
map.add(new Pair("values", attributeFilter.values));
|
|
839
|
-
return map;
|
|
840
|
-
}
|
|
841
|
-
export function declarativeMatchAttributeFilterToYaml(attributeFilter, errorContext) {
|
|
842
|
-
const map = new YAMLMap();
|
|
843
|
-
map.add(new Pair("type", "text_filter"));
|
|
844
|
-
map.add(new Pair("using", getIdentifier(attributeFilter.label, undefined, updateErrorContext(errorContext, {
|
|
845
|
-
path: ["label"],
|
|
846
|
-
}))));
|
|
847
|
-
map.add(new Pair("condition", matchConditionToYaml(attributeFilter.operator, attributeFilter.negativeSelection)));
|
|
848
|
-
map.add(new Pair("value", attributeFilter.literal));
|
|
849
|
-
if (attributeFilter.caseSensitive !== undefined) {
|
|
850
|
-
map.add(new Pair("case_sensitive", attributeFilter.caseSensitive));
|
|
851
|
-
}
|
|
852
|
-
return map;
|
|
853
|
-
}
|
|
854
|
-
function addSingleConditionToYaml(map, condition) {
|
|
855
|
-
if (isComparisonCondition(condition)) {
|
|
856
|
-
const comp = condition.comparison;
|
|
857
|
-
map.add(new Pair("condition", comp.operator.toUpperCase()));
|
|
858
|
-
map.add(new Pair("value", comp.value));
|
|
859
|
-
map.add(new Pair("null_values_as_zero", comp.treatNullValuesAs !== undefined));
|
|
860
|
-
}
|
|
861
|
-
else if (isRangeCondition(condition)) {
|
|
862
|
-
const range = condition.range;
|
|
863
|
-
map.add(new Pair("condition", range.operator.toUpperCase()));
|
|
864
|
-
map.add(new Pair("from", range.from));
|
|
865
|
-
map.add(new Pair("to", range.to));
|
|
866
|
-
map.add(new Pair("null_values_as_zero", range.treatNullValuesAs !== undefined));
|
|
867
|
-
}
|
|
868
|
-
}
|
|
869
|
-
function addConditionToYamlMap(conditionMap, condition) {
|
|
870
|
-
let hasTreatNullValues = false;
|
|
871
|
-
if (isComparisonCondition(condition)) {
|
|
872
|
-
const comp = condition.comparison;
|
|
873
|
-
conditionMap.add(new Pair("condition", comp.operator.toUpperCase()));
|
|
874
|
-
conditionMap.add(new Pair("value", comp.value));
|
|
875
|
-
if (comp.treatNullValuesAs !== undefined) {
|
|
876
|
-
hasTreatNullValues = true;
|
|
877
|
-
}
|
|
878
|
-
}
|
|
879
|
-
else if (isRangeCondition(condition)) {
|
|
880
|
-
const range = condition.range;
|
|
881
|
-
conditionMap.add(new Pair("condition", range.operator.toUpperCase()));
|
|
882
|
-
conditionMap.add(new Pair("from", range.from));
|
|
883
|
-
conditionMap.add(new Pair("to", range.to));
|
|
884
|
-
if (range.treatNullValuesAs !== undefined) {
|
|
885
|
-
hasTreatNullValues = true;
|
|
886
|
-
}
|
|
887
|
-
}
|
|
888
|
-
return hasTreatNullValues;
|
|
889
|
-
}
|
|
890
|
-
/** @internal */
|
|
891
|
-
export function declarativeMeasureValueFilterToYaml(measureValueFilter, errorContext) {
|
|
892
|
-
const map = new YAMLMap();
|
|
893
|
-
map.add(new Pair("type", "metric_value_filter"));
|
|
894
|
-
if (isLocalIdRef(measureValueFilter.measure)) {
|
|
895
|
-
map.add(new Pair("using", measureValueFilter.measure.localIdentifier));
|
|
896
|
-
}
|
|
897
|
-
else {
|
|
898
|
-
map.add(new Pair("using", getIdentifier(measureValueFilter.measure, undefined, updateErrorContext(errorContext, {
|
|
899
|
-
path: ["measure"],
|
|
900
|
-
}))));
|
|
901
|
-
}
|
|
902
|
-
// Handle multiple conditions (new SDK model feature)
|
|
903
|
-
if (measureValueFilter.conditions && measureValueFilter.conditions.length > 1) {
|
|
904
|
-
// Multiple conditions: use conditions array
|
|
905
|
-
const conditionsSeq = new YAMLSeq();
|
|
906
|
-
let treatNullValuesAsZero = false;
|
|
907
|
-
measureValueFilter.conditions.forEach((cond) => {
|
|
908
|
-
const conditionMap = new YAMLMap();
|
|
909
|
-
if (addConditionToYamlMap(conditionMap, cond)) {
|
|
910
|
-
treatNullValuesAsZero = true;
|
|
911
|
-
}
|
|
912
|
-
conditionsSeq.add(conditionMap);
|
|
913
|
-
});
|
|
914
|
-
map.add(new Pair("conditions", conditionsSeq));
|
|
915
|
-
if (treatNullValuesAsZero) {
|
|
916
|
-
map.add(new Pair("null_values_as_zero", true));
|
|
917
|
-
}
|
|
918
|
-
}
|
|
919
|
-
else if (measureValueFilter.conditions?.length === 1) {
|
|
920
|
-
// Single condition in array: use old format for cleaner output
|
|
921
|
-
addSingleConditionToYaml(map, measureValueFilter.conditions[0]);
|
|
922
|
-
}
|
|
923
|
-
else if (measureValueFilter.condition) {
|
|
924
|
-
// Fallback to single condition field for backward compatibility
|
|
925
|
-
addSingleConditionToYaml(map, measureValueFilter.condition);
|
|
926
|
-
}
|
|
927
|
-
// Handle dimensionality field
|
|
928
|
-
if (measureValueFilter.dimensionality && Array.isArray(measureValueFilter.dimensionality)) {
|
|
929
|
-
const dimensionalitySeq = new YAMLSeq();
|
|
930
|
-
measureValueFilter.dimensionality.forEach((item) => {
|
|
931
|
-
if (isLocalIdRef(item)) {
|
|
932
|
-
dimensionalitySeq.add(item.localIdentifier);
|
|
933
|
-
}
|
|
934
|
-
else {
|
|
935
|
-
dimensionalitySeq.add(getIdentifier(item));
|
|
936
|
-
}
|
|
937
|
-
});
|
|
938
|
-
map.add(new Pair("dimensionality", dimensionalitySeq));
|
|
939
|
-
}
|
|
940
|
-
return map;
|
|
941
|
-
}
|
|
942
|
-
/** @internal */
|
|
943
|
-
export function declarativeRankingFilterToYaml(rankingFilter, errorContext) {
|
|
944
|
-
const map = new YAMLMap();
|
|
945
|
-
map.add(new Pair("type", "ranking_filter"));
|
|
946
|
-
if (isLocalIdRef(rankingFilter.measure)) {
|
|
947
|
-
map.add(new Pair("using", rankingFilter.measure.localIdentifier));
|
|
948
|
-
}
|
|
949
|
-
else {
|
|
950
|
-
map.add(new Pair("using", getIdentifier(rankingFilter.measure, undefined, updateErrorContext(errorContext, {
|
|
951
|
-
path: ["measure"],
|
|
952
|
-
}))));
|
|
953
|
-
}
|
|
954
|
-
if (rankingFilter.operator === "TOP") {
|
|
955
|
-
map.add(new Pair("top", rankingFilter.value));
|
|
956
|
-
}
|
|
957
|
-
if (rankingFilter.operator === "BOTTOM") {
|
|
958
|
-
map.add(new Pair("bottom", rankingFilter.value));
|
|
959
|
-
}
|
|
960
|
-
//NOTE: There can be array, but UI allows only 1 attr now
|
|
961
|
-
if (rankingFilter.attributes?.[0]) {
|
|
962
|
-
const first = rankingFilter.attributes[0];
|
|
963
|
-
if (isLocalIdRef(first)) {
|
|
964
|
-
map.add(new Pair("attribute", first.localIdentifier));
|
|
965
|
-
}
|
|
966
|
-
else {
|
|
967
|
-
map.add(new Pair("attribute", getIdentifier(first)));
|
|
968
|
-
}
|
|
969
|
-
}
|
|
970
|
-
if (rankingFilter.strictLimitOfRows !== undefined) {
|
|
971
|
-
map.add(new Pair("strict_limit_of_rows", rankingFilter.strictLimitOfRows));
|
|
972
|
-
}
|
|
973
|
-
return map;
|
|
974
|
-
}
|
|
975
532
|
/** @internal */
|
|
976
533
|
export function declarativeSortsToYaml(sorts, _errorContext) {
|
|
977
534
|
const sortsArray = [];
|
|
@@ -1033,15 +590,15 @@ export function declarativeMeasureSortToYaml(sort) {
|
|
|
1033
590
|
//visualisations
|
|
1034
591
|
function declarativeVisTableToYaml(doc, def, report, _context) {
|
|
1035
592
|
//buckets
|
|
1036
|
-
const metrics = report.
|
|
593
|
+
const metrics = report.buckets.consume(BucketsType.Measures);
|
|
1037
594
|
if (metrics && metrics.items.length > 0) {
|
|
1038
595
|
doc.add(entryWithSpace("metrics", groupToYaml(metrics)));
|
|
1039
596
|
}
|
|
1040
|
-
const attribute = report.
|
|
597
|
+
const attribute = report.buckets.consume(BucketsType.Attribute);
|
|
1041
598
|
if (attribute && attribute.items.length > 0) {
|
|
1042
599
|
doc.add(entryWithSpace("view_by", groupToYaml(attribute)));
|
|
1043
600
|
}
|
|
1044
|
-
const columns = report.
|
|
601
|
+
const columns = report.buckets.consume(BucketsType.Columns);
|
|
1045
602
|
if (columns && columns.items.length > 0) {
|
|
1046
603
|
doc.add(entryWithSpace("segment_by", groupToYaml(columns)));
|
|
1047
604
|
}
|
|
@@ -1052,15 +609,15 @@ function declarativeVisTableToYaml(doc, def, report, _context) {
|
|
|
1052
609
|
}
|
|
1053
610
|
function declarativeVisBarToYaml(doc, def, report, _errorContext) {
|
|
1054
611
|
//buckets
|
|
1055
|
-
const metrics = report.
|
|
612
|
+
const metrics = report.buckets.consume(BucketsType.Measures);
|
|
1056
613
|
if (metrics && metrics.items.length > 0) {
|
|
1057
614
|
doc.add(entryWithSpace("metrics", groupToYaml(metrics)));
|
|
1058
615
|
}
|
|
1059
|
-
const view = report.
|
|
616
|
+
const view = report.buckets.consume(BucketsType.View);
|
|
1060
617
|
if (view && view.items.length > 0) {
|
|
1061
618
|
doc.add(entryWithSpace("view_by", groupToYaml(view)));
|
|
1062
619
|
}
|
|
1063
|
-
const stack = report.
|
|
620
|
+
const stack = report.buckets.consume(BucketsType.Stack);
|
|
1064
621
|
if (stack && stack.items.length > 0) {
|
|
1065
622
|
doc.add(entryWithSpace("segment_by", groupToYaml(stack)));
|
|
1066
623
|
}
|
|
@@ -1071,15 +628,15 @@ function declarativeVisBarToYaml(doc, def, report, _errorContext) {
|
|
|
1071
628
|
}
|
|
1072
629
|
function declarativeVisColumnToYaml(doc, def, report, _errorContext) {
|
|
1073
630
|
//buckets
|
|
1074
|
-
const metrics = report.
|
|
631
|
+
const metrics = report.buckets.consume(BucketsType.Measures);
|
|
1075
632
|
if (metrics && metrics.items.length > 0) {
|
|
1076
633
|
doc.add(entryWithSpace("metrics", groupToYaml(metrics)));
|
|
1077
634
|
}
|
|
1078
|
-
const view = report.
|
|
635
|
+
const view = report.buckets.consume(BucketsType.View);
|
|
1079
636
|
if (view && view.items.length > 0) {
|
|
1080
637
|
doc.add(entryWithSpace("view_by", groupToYaml(view)));
|
|
1081
638
|
}
|
|
1082
|
-
const stack = report.
|
|
639
|
+
const stack = report.buckets.consume(BucketsType.Stack);
|
|
1083
640
|
if (stack && stack.items.length > 0) {
|
|
1084
641
|
doc.add(entryWithSpace("segment_by", groupToYaml(stack)));
|
|
1085
642
|
}
|
|
@@ -1090,15 +647,15 @@ function declarativeVisColumnToYaml(doc, def, report, _errorContext) {
|
|
|
1090
647
|
}
|
|
1091
648
|
function declarativeVisLineToYaml(doc, def, report, _errorContext) {
|
|
1092
649
|
//buckets
|
|
1093
|
-
const metrics = report.
|
|
650
|
+
const metrics = report.buckets.consume(BucketsType.Measures);
|
|
1094
651
|
if (metrics && metrics.items.length > 0) {
|
|
1095
652
|
doc.add(entryWithSpace("metrics", groupToYaml(metrics)));
|
|
1096
653
|
}
|
|
1097
|
-
const trend = report.
|
|
654
|
+
const trend = report.buckets.consume(BucketsType.Trend);
|
|
1098
655
|
if (trend && trend.items.length > 0) {
|
|
1099
656
|
doc.add(entryWithSpace("view_by", groupToYaml(trend)));
|
|
1100
657
|
}
|
|
1101
|
-
const segment = report.
|
|
658
|
+
const segment = report.buckets.consume(BucketsType.Segment);
|
|
1102
659
|
if (segment && segment.items.length > 0) {
|
|
1103
660
|
doc.add(entryWithSpace("segment_by", groupToYaml(segment)));
|
|
1104
661
|
}
|
|
@@ -1109,15 +666,15 @@ function declarativeVisLineToYaml(doc, def, report, _errorContext) {
|
|
|
1109
666
|
}
|
|
1110
667
|
function declarativeVisRadarToYaml(doc, def, report, _errorContext) {
|
|
1111
668
|
//buckets
|
|
1112
|
-
const metrics = report.
|
|
669
|
+
const metrics = report.buckets.consume(BucketsType.Measures);
|
|
1113
670
|
if (metrics && metrics.items.length > 0) {
|
|
1114
671
|
doc.add(entryWithSpace("metrics", groupToYaml(metrics)));
|
|
1115
672
|
}
|
|
1116
|
-
const trend = report.
|
|
673
|
+
const trend = report.buckets.consume(BucketsType.Trend);
|
|
1117
674
|
if (trend && trend.items.length > 0) {
|
|
1118
675
|
doc.add(entryWithSpace("view_by", groupToYaml(trend)));
|
|
1119
676
|
}
|
|
1120
|
-
const segment = report.
|
|
677
|
+
const segment = report.buckets.consume(BucketsType.Segment);
|
|
1121
678
|
if (segment && segment.items.length > 0) {
|
|
1122
679
|
doc.add(entryWithSpace("segment_by", groupToYaml(segment)));
|
|
1123
680
|
}
|
|
@@ -1128,15 +685,15 @@ function declarativeVisRadarToYaml(doc, def, report, _errorContext) {
|
|
|
1128
685
|
}
|
|
1129
686
|
function declarativeVisAreaToYaml(doc, def, report, _errorContext) {
|
|
1130
687
|
//buckets
|
|
1131
|
-
const metrics = report.
|
|
688
|
+
const metrics = report.buckets.consume(BucketsType.Measures);
|
|
1132
689
|
if (metrics && metrics.items.length > 0) {
|
|
1133
690
|
doc.add(entryWithSpace("metrics", groupToYaml(metrics)));
|
|
1134
691
|
}
|
|
1135
|
-
const view = report.
|
|
692
|
+
const view = report.buckets.consume(BucketsType.View);
|
|
1136
693
|
if (view && view.items.length > 0) {
|
|
1137
694
|
doc.add(entryWithSpace("view_by", groupToYaml(view)));
|
|
1138
695
|
}
|
|
1139
|
-
const stack = report.
|
|
696
|
+
const stack = report.buckets.consume(BucketsType.Stack);
|
|
1140
697
|
if (stack && stack.items.length > 0) {
|
|
1141
698
|
doc.add(entryWithSpace("segment_by", groupToYaml(stack)));
|
|
1142
699
|
}
|
|
@@ -1147,8 +704,8 @@ function declarativeVisAreaToYaml(doc, def, report, _errorContext) {
|
|
|
1147
704
|
}
|
|
1148
705
|
function declarativeVisScatterToYaml(doc, def, report, _errorContext) {
|
|
1149
706
|
//buckets
|
|
1150
|
-
const metrics1 = report.
|
|
1151
|
-
const metrics2 = report.
|
|
707
|
+
const metrics1 = report.buckets.consume(BucketsType.Measures);
|
|
708
|
+
const metrics2 = report.buckets.consume(BucketsType.SecondaryMeasures);
|
|
1152
709
|
const metrics = {
|
|
1153
710
|
items: cleanUpItems([
|
|
1154
711
|
...(metrics1?.items.length ? metrics1.items : [null]),
|
|
@@ -1159,11 +716,11 @@ function declarativeVisScatterToYaml(doc, def, report, _errorContext) {
|
|
|
1159
716
|
if (metrics.items.length > 0) {
|
|
1160
717
|
doc.add(entryWithSpace("metrics", groupToYaml(metrics)));
|
|
1161
718
|
}
|
|
1162
|
-
const attributes = report.
|
|
719
|
+
const attributes = report.buckets.consume(BucketsType.Attribute);
|
|
1163
720
|
if (attributes && attributes.items.length > 0) {
|
|
1164
721
|
doc.add(entryWithSpace("view_by", groupToYaml(attributes)));
|
|
1165
722
|
}
|
|
1166
|
-
const segments = report.
|
|
723
|
+
const segments = report.buckets.consume(BucketsType.Segment);
|
|
1167
724
|
if (segments && segments.items.length > 0) {
|
|
1168
725
|
doc.add(entryWithSpace("segment_by", groupToYaml(segments)));
|
|
1169
726
|
}
|
|
@@ -1174,8 +731,8 @@ function declarativeVisScatterToYaml(doc, def, report, _errorContext) {
|
|
|
1174
731
|
}
|
|
1175
732
|
function declarativeVisBubbleToYaml(doc, def, report, _errorContext) {
|
|
1176
733
|
//buckets
|
|
1177
|
-
const metrics1 = report.
|
|
1178
|
-
const metrics2 = report.
|
|
734
|
+
const metrics1 = report.buckets.consume(BucketsType.Measures);
|
|
735
|
+
const metrics2 = report.buckets.consume(BucketsType.SecondaryMeasures);
|
|
1179
736
|
const metrics = {
|
|
1180
737
|
items: cleanUpItems([
|
|
1181
738
|
...(metrics1?.items.length ? metrics1.items : [null]),
|
|
@@ -1186,11 +743,11 @@ function declarativeVisBubbleToYaml(doc, def, report, _errorContext) {
|
|
|
1186
743
|
if (metrics.items.length > 0) {
|
|
1187
744
|
doc.add(entryWithSpace("metrics", groupToYaml(metrics)));
|
|
1188
745
|
}
|
|
1189
|
-
const view = report.
|
|
746
|
+
const view = report.buckets.consume(BucketsType.View);
|
|
1190
747
|
if (view && view.items.length > 0) {
|
|
1191
748
|
doc.add(entryWithSpace("view_by", groupToYaml(view)));
|
|
1192
749
|
}
|
|
1193
|
-
const tertiaryMetrics = report.
|
|
750
|
+
const tertiaryMetrics = report.buckets.consume(BucketsType.TertiaryMeasures);
|
|
1194
751
|
if (tertiaryMetrics && tertiaryMetrics.items.length > 0) {
|
|
1195
752
|
doc.add(entryWithSpace("segment_by", groupToYaml(tertiaryMetrics)));
|
|
1196
753
|
}
|
|
@@ -1201,11 +758,11 @@ function declarativeVisBubbleToYaml(doc, def, report, _errorContext) {
|
|
|
1201
758
|
}
|
|
1202
759
|
function declarativeVisPieToYaml(doc, def, report, _errorContext) {
|
|
1203
760
|
//buckets
|
|
1204
|
-
const metrics = report.
|
|
761
|
+
const metrics = report.buckets.consume(BucketsType.Measures);
|
|
1205
762
|
if (metrics && metrics.items.length > 0) {
|
|
1206
763
|
doc.add(entryWithSpace("metrics", groupToYaml(metrics)));
|
|
1207
764
|
}
|
|
1208
|
-
const view = report.
|
|
765
|
+
const view = report.buckets.consume(BucketsType.View);
|
|
1209
766
|
if (view && view.items.length > 0) {
|
|
1210
767
|
doc.add(entryWithSpace("view_by", groupToYaml(view)));
|
|
1211
768
|
}
|
|
@@ -1216,11 +773,11 @@ function declarativeVisPieToYaml(doc, def, report, _errorContext) {
|
|
|
1216
773
|
}
|
|
1217
774
|
function declarativeVisDonutToYaml(doc, def, report, _errorContext) {
|
|
1218
775
|
//buckets
|
|
1219
|
-
const metrics = report.
|
|
776
|
+
const metrics = report.buckets.consume(BucketsType.Measures);
|
|
1220
777
|
if (metrics && metrics.items.length > 0) {
|
|
1221
778
|
doc.add(entryWithSpace("metrics", groupToYaml(metrics)));
|
|
1222
779
|
}
|
|
1223
|
-
const view = report.
|
|
780
|
+
const view = report.buckets.consume(BucketsType.View);
|
|
1224
781
|
if (view && view.items.length > 0) {
|
|
1225
782
|
doc.add(entryWithSpace("view_by", groupToYaml(view)));
|
|
1226
783
|
}
|
|
@@ -1231,15 +788,15 @@ function declarativeVisDonutToYaml(doc, def, report, _errorContext) {
|
|
|
1231
788
|
}
|
|
1232
789
|
function declarativeVisTreemapToYaml(doc, def, report, _errorContext) {
|
|
1233
790
|
//buckets
|
|
1234
|
-
const metrics = report.
|
|
791
|
+
const metrics = report.buckets.consume(BucketsType.Measures);
|
|
1235
792
|
if (metrics && metrics.items.length > 0) {
|
|
1236
793
|
doc.add(entryWithSpace("metrics", groupToYaml(metrics)));
|
|
1237
794
|
}
|
|
1238
|
-
const view = report.
|
|
795
|
+
const view = report.buckets.consume(BucketsType.View);
|
|
1239
796
|
if (view && view.items.length > 0) {
|
|
1240
797
|
doc.add(entryWithSpace("view_by", groupToYaml(view)));
|
|
1241
798
|
}
|
|
1242
|
-
const segment = report.
|
|
799
|
+
const segment = report.buckets.consume(BucketsType.Segment);
|
|
1243
800
|
if (segment && segment.items.length > 0) {
|
|
1244
801
|
doc.add(entryWithSpace("segment_by", groupToYaml(segment)));
|
|
1245
802
|
}
|
|
@@ -1250,11 +807,11 @@ function declarativeVisTreemapToYaml(doc, def, report, _errorContext) {
|
|
|
1250
807
|
}
|
|
1251
808
|
function declarativeVisPyramidToYaml(doc, def, report, _errorContext) {
|
|
1252
809
|
//buckets
|
|
1253
|
-
const metrics = report.
|
|
810
|
+
const metrics = report.buckets.consume(BucketsType.Measures);
|
|
1254
811
|
if (metrics && metrics.items.length > 0) {
|
|
1255
812
|
doc.add(entryWithSpace("metrics", groupToYaml(metrics)));
|
|
1256
813
|
}
|
|
1257
|
-
const view = report.
|
|
814
|
+
const view = report.buckets.consume(BucketsType.View);
|
|
1258
815
|
if (view && view.items.length > 0) {
|
|
1259
816
|
doc.add(entryWithSpace("view_by", groupToYaml(view)));
|
|
1260
817
|
}
|
|
@@ -1265,11 +822,11 @@ function declarativeVisPyramidToYaml(doc, def, report, _errorContext) {
|
|
|
1265
822
|
}
|
|
1266
823
|
function declarativeVisFunnelToYaml(doc, def, report, _errorContext) {
|
|
1267
824
|
//buckets
|
|
1268
|
-
const metrics = report.
|
|
825
|
+
const metrics = report.buckets.consume(BucketsType.Measures);
|
|
1269
826
|
if (metrics && metrics.items.length > 0) {
|
|
1270
827
|
doc.add(entryWithSpace("metrics", groupToYaml(metrics)));
|
|
1271
828
|
}
|
|
1272
|
-
const view = report.
|
|
829
|
+
const view = report.buckets.consume(BucketsType.View);
|
|
1273
830
|
if (view && view.items.length > 0) {
|
|
1274
831
|
doc.add(entryWithSpace("view_by", groupToYaml(view)));
|
|
1275
832
|
}
|
|
@@ -1280,15 +837,15 @@ function declarativeVisFunnelToYaml(doc, def, report, _errorContext) {
|
|
|
1280
837
|
}
|
|
1281
838
|
function declarativeVisHeatmapToYaml(doc, def, report, _errorContext) {
|
|
1282
839
|
//buckets
|
|
1283
|
-
const metrics = report.
|
|
840
|
+
const metrics = report.buckets.consume(BucketsType.Measures);
|
|
1284
841
|
if (metrics && metrics.items.length > 0) {
|
|
1285
842
|
doc.add(entryWithSpace("metrics", groupToYaml(metrics)));
|
|
1286
843
|
}
|
|
1287
|
-
const view = report.
|
|
844
|
+
const view = report.buckets.consume(BucketsType.View);
|
|
1288
845
|
if (view && view.items.length > 0) {
|
|
1289
846
|
doc.add(entryWithSpace("view_by", groupToYaml(view)));
|
|
1290
847
|
}
|
|
1291
|
-
const stack = report.
|
|
848
|
+
const stack = report.buckets.consume(BucketsType.Stack);
|
|
1292
849
|
if (stack && stack.items.length > 0) {
|
|
1293
850
|
doc.add(entryWithSpace("segment_by", groupToYaml(stack)));
|
|
1294
851
|
}
|
|
@@ -1299,9 +856,9 @@ function declarativeVisHeatmapToYaml(doc, def, report, _errorContext) {
|
|
|
1299
856
|
}
|
|
1300
857
|
function declarativeVisBulletToYaml(doc, def, report, _errorContext) {
|
|
1301
858
|
//buckets
|
|
1302
|
-
const metrics1 = report.
|
|
1303
|
-
const metrics2 = report.
|
|
1304
|
-
const metrics3 = report.
|
|
859
|
+
const metrics1 = report.buckets.consume(BucketsType.Measures);
|
|
860
|
+
const metrics2 = report.buckets.consume(BucketsType.SecondaryMeasures);
|
|
861
|
+
const metrics3 = report.buckets.consume(BucketsType.TertiaryMeasures);
|
|
1305
862
|
const metrics = {
|
|
1306
863
|
items: cleanUpItems([
|
|
1307
864
|
...(metrics1?.items.length ? metrics1.items : [null]),
|
|
@@ -1313,7 +870,7 @@ function declarativeVisBulletToYaml(doc, def, report, _errorContext) {
|
|
|
1313
870
|
if (metrics.items.length > 0) {
|
|
1314
871
|
doc.add(entryWithSpace("metrics", groupToYaml(metrics)));
|
|
1315
872
|
}
|
|
1316
|
-
const view = report.
|
|
873
|
+
const view = report.buckets.consume(BucketsType.View);
|
|
1317
874
|
if (view && view.items.length > 0) {
|
|
1318
875
|
doc.add(entryWithSpace("view_by", groupToYaml(view)));
|
|
1319
876
|
}
|
|
@@ -1324,11 +881,11 @@ function declarativeVisBulletToYaml(doc, def, report, _errorContext) {
|
|
|
1324
881
|
}
|
|
1325
882
|
function declarativeVisWaterfallToYaml(doc, def, report, _errorContext) {
|
|
1326
883
|
//buckets
|
|
1327
|
-
const metrics = report.
|
|
884
|
+
const metrics = report.buckets.consume(BucketsType.Measures);
|
|
1328
885
|
if (metrics && metrics.items.length > 0) {
|
|
1329
886
|
doc.add(entryWithSpace("metrics", groupToYaml(metrics)));
|
|
1330
887
|
}
|
|
1331
|
-
const view = report.
|
|
888
|
+
const view = report.buckets.consume(BucketsType.View);
|
|
1332
889
|
if (view && view.items.length > 0) {
|
|
1333
890
|
doc.add(entryWithSpace("view_by", groupToYaml(view)));
|
|
1334
891
|
}
|
|
@@ -1339,12 +896,12 @@ function declarativeVisWaterfallToYaml(doc, def, report, _errorContext) {
|
|
|
1339
896
|
}
|
|
1340
897
|
function declarativeVisDependencyWheelToYaml(doc, def, report, _errorContext) {
|
|
1341
898
|
//buckets
|
|
1342
|
-
const metrics = report.
|
|
899
|
+
const metrics = report.buckets.consume(BucketsType.Measures);
|
|
1343
900
|
if (metrics && metrics.items.length > 0) {
|
|
1344
901
|
doc.add(entryWithSpace("metrics", groupToYaml(metrics)));
|
|
1345
902
|
}
|
|
1346
|
-
const from = report.
|
|
1347
|
-
const to = report.
|
|
903
|
+
const from = report.buckets.consume(BucketsType.AttributeFrom);
|
|
904
|
+
const to = report.buckets.consume(BucketsType.AttributeTo);
|
|
1348
905
|
const view = {
|
|
1349
906
|
items: cleanUpItems([
|
|
1350
907
|
...(from?.items.length ? from.items : [null]),
|
|
@@ -1362,12 +919,12 @@ function declarativeVisDependencyWheelToYaml(doc, def, report, _errorContext) {
|
|
|
1362
919
|
}
|
|
1363
920
|
function declarativeVisSankeyToYaml(doc, def, report, _errorContext) {
|
|
1364
921
|
//buckets
|
|
1365
|
-
const metrics = report.
|
|
922
|
+
const metrics = report.buckets.consume(BucketsType.Measures);
|
|
1366
923
|
if (metrics && metrics.items.length > 0) {
|
|
1367
924
|
doc.add(entryWithSpace("metrics", groupToYaml(metrics)));
|
|
1368
925
|
}
|
|
1369
|
-
const from = report.
|
|
1370
|
-
const to = report.
|
|
926
|
+
const from = report.buckets.consume(BucketsType.AttributeFrom);
|
|
927
|
+
const to = report.buckets.consume(BucketsType.AttributeTo);
|
|
1371
928
|
const view = {
|
|
1372
929
|
items: cleanUpItems([
|
|
1373
930
|
...(from?.items.length ? from.items : [null]),
|
|
@@ -1385,8 +942,8 @@ function declarativeVisSankeyToYaml(doc, def, report, _errorContext) {
|
|
|
1385
942
|
}
|
|
1386
943
|
function declarativeVisHeadlineToYaml(doc, def, report, _errorContext) {
|
|
1387
944
|
//buckets
|
|
1388
|
-
const metrics1 = report.
|
|
1389
|
-
const metrics2 = report.
|
|
945
|
+
const metrics1 = report.buckets.consume(BucketsType.Measures);
|
|
946
|
+
const metrics2 = report.buckets.consume(BucketsType.SecondaryMeasures);
|
|
1390
947
|
const metrics = {
|
|
1391
948
|
items: [...(metrics1?.items ?? [null]), ...(metrics2?.items ?? [])],
|
|
1392
949
|
type: BucketsType.Measures,
|
|
@@ -1401,8 +958,8 @@ function declarativeVisHeadlineToYaml(doc, def, report, _errorContext) {
|
|
|
1401
958
|
}
|
|
1402
959
|
function declarativeVisComboToYaml(doc, def, report, _errorContext) {
|
|
1403
960
|
//buckets
|
|
1404
|
-
const metrics1 = addAxisTypeToGroup(report.
|
|
1405
|
-
const metrics2 = addAxisTypeToGroup(report.
|
|
961
|
+
const metrics1 = addAxisTypeToGroup(report.buckets.consume(BucketsType.Measures), "primary");
|
|
962
|
+
const metrics2 = addAxisTypeToGroup(report.buckets.consume(BucketsType.SecondaryMeasures), "secondary");
|
|
1406
963
|
const metrics = {
|
|
1407
964
|
items: [...(metrics1?.items ?? []), ...(metrics2?.items ?? [])],
|
|
1408
965
|
type: BucketsType.Measures,
|
|
@@ -1410,7 +967,7 @@ function declarativeVisComboToYaml(doc, def, report, _errorContext) {
|
|
|
1410
967
|
if (metrics && metrics.items.length > 0) {
|
|
1411
968
|
doc.add(entryWithSpace("metrics", groupToYaml(metrics)));
|
|
1412
969
|
}
|
|
1413
|
-
const view = report.
|
|
970
|
+
const view = report.buckets.consume(BucketsType.View);
|
|
1414
971
|
if (view && view.items.length > 0) {
|
|
1415
972
|
doc.add(entryWithSpace("view_by", groupToYaml(view)));
|
|
1416
973
|
}
|
|
@@ -1419,9 +976,9 @@ function declarativeVisComboToYaml(doc, def, report, _errorContext) {
|
|
|
1419
976
|
doc.add(config);
|
|
1420
977
|
}
|
|
1421
978
|
}
|
|
1422
|
-
function addPushpinBucketsToYaml(target,
|
|
1423
|
-
const sizeBucket =
|
|
1424
|
-
const colorBucket =
|
|
979
|
+
function addPushpinBucketsToYaml(target, buckets) {
|
|
980
|
+
const sizeBucket = buckets.consume(BucketsType.Size);
|
|
981
|
+
const colorBucket = buckets.consume(BucketsType.Color);
|
|
1425
982
|
const metrics = {
|
|
1426
983
|
items: cleanUpItems([
|
|
1427
984
|
...(sizeBucket?.items.length ? sizeBucket.items : [null]),
|
|
@@ -1432,17 +989,17 @@ function addPushpinBucketsToYaml(target, groups) {
|
|
|
1432
989
|
if (metrics.items.length > 0) {
|
|
1433
990
|
target.add(entryWithSpace("metrics", groupToYaml(metrics)));
|
|
1434
991
|
}
|
|
1435
|
-
const location =
|
|
992
|
+
const location = buckets.consume(BucketsType.Location);
|
|
1436
993
|
if (location && location.items.length > 0) {
|
|
1437
994
|
target.add(entryWithSpace("view_by", groupToYaml(location)));
|
|
1438
995
|
}
|
|
1439
|
-
const segment =
|
|
996
|
+
const segment = buckets.consume(BucketsType.Segment);
|
|
1440
997
|
if (segment && segment.items.length > 0) {
|
|
1441
998
|
target.add(entryWithSpace("segment_by", groupToYaml(segment)));
|
|
1442
999
|
}
|
|
1443
1000
|
}
|
|
1444
|
-
function addGeoAreaBucketsToYaml(target,
|
|
1445
|
-
const colorBucket =
|
|
1001
|
+
function addGeoAreaBucketsToYaml(target, buckets) {
|
|
1002
|
+
const colorBucket = buckets.consume(BucketsType.Color);
|
|
1446
1003
|
const metrics = {
|
|
1447
1004
|
items: cleanUpItems([...(colorBucket?.items.length ? colorBucket.items : [null])]),
|
|
1448
1005
|
type: BucketsType.Measures,
|
|
@@ -1450,18 +1007,18 @@ function addGeoAreaBucketsToYaml(target, groups) {
|
|
|
1450
1007
|
if (metrics.items.length > 0) {
|
|
1451
1008
|
target.add(entryWithSpace("metrics", groupToYaml(metrics)));
|
|
1452
1009
|
}
|
|
1453
|
-
const area =
|
|
1010
|
+
const area = buckets.consume(BucketsType.Area);
|
|
1454
1011
|
if (area && area.items.length > 0) {
|
|
1455
1012
|
target.add(entryWithSpace("view_by", groupToYaml(area)));
|
|
1456
1013
|
}
|
|
1457
|
-
const segment =
|
|
1014
|
+
const segment = buckets.consume(BucketsType.Segment);
|
|
1458
1015
|
if (segment && segment.items.length > 0) {
|
|
1459
1016
|
target.add(entryWithSpace("segment_by", groupToYaml(segment)));
|
|
1460
1017
|
}
|
|
1461
1018
|
}
|
|
1462
1019
|
function declarativeVisGeoToYaml(doc, def, report, entities, errorContext) {
|
|
1463
1020
|
//buckets
|
|
1464
|
-
addPushpinBucketsToYaml(doc, report.
|
|
1021
|
+
addPushpinBucketsToYaml(doc, report.buckets);
|
|
1465
1022
|
const config = geoChart.load(def.properties);
|
|
1466
1023
|
if (config) {
|
|
1467
1024
|
doc.add(config);
|
|
@@ -1470,7 +1027,7 @@ function declarativeVisGeoToYaml(doc, def, report, entities, errorContext) {
|
|
|
1470
1027
|
}
|
|
1471
1028
|
function declarativeVisGeoAreaToYaml(doc, def, report, entities, errorContext) {
|
|
1472
1029
|
//buckets
|
|
1473
|
-
addGeoAreaBucketsToYaml(doc, report.
|
|
1030
|
+
addGeoAreaBucketsToYaml(doc, report.buckets);
|
|
1474
1031
|
const config = geoAreaChart.load(def.properties);
|
|
1475
1032
|
if (config) {
|
|
1476
1033
|
doc.add(config);
|
|
@@ -1488,16 +1045,16 @@ function appendLayers(doc, def, entities, errorContext) {
|
|
|
1488
1045
|
}
|
|
1489
1046
|
}
|
|
1490
1047
|
function declarativeVisRepeaterToYaml(doc, def, report, _errorContext) {
|
|
1491
|
-
const columns = report.
|
|
1048
|
+
const columns = report.buckets.consume(BucketsType.Columns);
|
|
1492
1049
|
const columnsMapped = addChartTypeToGroup(columns, def.properties);
|
|
1493
1050
|
if (columnsMapped && columnsMapped.items.length > 0) {
|
|
1494
1051
|
doc.add(entryWithSpace("metrics", groupToYaml(columnsMapped)));
|
|
1495
1052
|
}
|
|
1496
|
-
const view = report.
|
|
1053
|
+
const view = report.buckets.consume(BucketsType.View);
|
|
1497
1054
|
if (view && view.items.length > 0) {
|
|
1498
1055
|
doc.add(entryWithSpace("view_by", groupToYaml(view)));
|
|
1499
1056
|
}
|
|
1500
|
-
const attribute = report.
|
|
1057
|
+
const attribute = report.buckets.consume(BucketsType.Attribute);
|
|
1501
1058
|
if (attribute && attribute.items.length > 0) {
|
|
1502
1059
|
doc.add(entryWithSpace("segment_by", groupToYaml(attribute)));
|
|
1503
1060
|
}
|
|
@@ -1584,10 +1141,28 @@ function addChartTypeToGroup(group, config) {
|
|
|
1584
1141
|
}),
|
|
1585
1142
|
};
|
|
1586
1143
|
}
|
|
1144
|
+
// Each check matches what the emitter would have written, so a value it would have ignored anyway (an
|
|
1145
|
+
// unrecognized filter, a config carrying no label) is not refused.
|
|
1146
|
+
function unrepresentableLayerField(layer) {
|
|
1147
|
+
if (layer.filters?.some(isFilter)) {
|
|
1148
|
+
return "filters";
|
|
1149
|
+
}
|
|
1150
|
+
if (layer.sorts?.length) {
|
|
1151
|
+
return "sorts";
|
|
1152
|
+
}
|
|
1153
|
+
const configs = Object.values(layer.attributeFilterConfigs ?? {});
|
|
1154
|
+
return configs.some((config) => config?.displayAsLabel) ? "attributeFilterConfigs" : null;
|
|
1155
|
+
}
|
|
1587
1156
|
function declarativeLayersToYaml(entities, layersDefinition, errorContext) {
|
|
1588
1157
|
const layers = new YAMLSeq();
|
|
1589
1158
|
layersDefinition.forEach((layer, li) => {
|
|
1590
|
-
|
|
1159
|
+
// A layer's own filters and sorts would read back as the insight's, so they are refused.
|
|
1160
|
+
const unrepresentable = unrepresentableLayerField(layer);
|
|
1161
|
+
if (unrepresentable !== null) {
|
|
1162
|
+
throw newError(CoreErrorCode.ItemNotSupported, [`layer "${layer.id}" own ${unrepresentable}`], updateErrorContext(errorContext, { path: [li.toString(), unrepresentable] }));
|
|
1163
|
+
}
|
|
1164
|
+
const { groups: layerGroups } = declarativeBucketsToYaml(entities, layer.buckets ?? [], updateErrorContext(errorContext, { path: [li.toString(), "buckets"] }));
|
|
1165
|
+
const buckets = bucketRegistry(layerGroups);
|
|
1591
1166
|
const layerKind = resolveLayerExportKind(layer.type, updateErrorContext(errorContext, { path: [li.toString(), "type"] }));
|
|
1592
1167
|
const layerMap = new YAMLMap();
|
|
1593
1168
|
layerMap.add(new Pair("id", layer.id));
|
|
@@ -1597,7 +1172,8 @@ function declarativeLayersToYaml(entities, layersDefinition, errorContext) {
|
|
|
1597
1172
|
if (layer.type) {
|
|
1598
1173
|
layerMap.add(new Pair("type", layer.type));
|
|
1599
1174
|
}
|
|
1600
|
-
appendLayerBucketsForKind(layerMap,
|
|
1175
|
+
appendLayerBucketsForKind(layerMap, buckets, layerKind, updateErrorContext(errorContext, { path: [li.toString()] }));
|
|
1176
|
+
buckets.assertAllConsumed(updateErrorContext(errorContext, { path: [li.toString()] }));
|
|
1601
1177
|
addLayerConfig(layerMap, layerKind, layer.properties);
|
|
1602
1178
|
layers.add(layerMap);
|
|
1603
1179
|
});
|
|
@@ -1612,13 +1188,13 @@ function resolveLayerExportKind(rawLayerType, errorContext) {
|
|
|
1612
1188
|
}
|
|
1613
1189
|
throw newError(CoreErrorCode.LayerTypeNotSupported, [rawLayerType ?? "<missing>"], errorContext);
|
|
1614
1190
|
}
|
|
1615
|
-
function appendLayerBucketsForKind(layerMap,
|
|
1191
|
+
function appendLayerBucketsForKind(layerMap, buckets, kind, errorContext) {
|
|
1616
1192
|
if (kind === "pushpin") {
|
|
1617
|
-
addPushpinBucketsToYaml(layerMap,
|
|
1193
|
+
addPushpinBucketsToYaml(layerMap, buckets);
|
|
1618
1194
|
return;
|
|
1619
1195
|
}
|
|
1620
1196
|
if (kind === "area") {
|
|
1621
|
-
addGeoAreaBucketsToYaml(layerMap,
|
|
1197
|
+
addGeoAreaBucketsToYaml(layerMap, buckets);
|
|
1622
1198
|
return;
|
|
1623
1199
|
}
|
|
1624
1200
|
throw newError(CoreErrorCode.LayerTypeNotSupported, [kind], errorContext);
|