@contrail/data-grouping 1.0.52 → 1.0.53-alpha.1
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/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,14 @@ Versioning follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- `DataGroupingProperty.valueFilter` (`{ mode: 'include' | 'exclude'; values: string[] }`): an optional, caller-supplied rule that restricts a multi-select grouping property's frames to the filter-selected values. Applied in `buildChildDataGroups` via the new `applyGroupingValueFilter` after `getDistinctValues` — pruning the fan-out to the included values (or dropping the excluded ones), while preserving the `(empty)` bucket. No-op for separate-frame mode (`groupMultiSelectInSeparateFrame`) and for non-multi-select grouping. Keeps this package decoupled from `@contrail/filters`: the caller translates its filter criteria into the rule. (VIBE-10759)
|
|
13
|
+
|
|
14
|
+
### Fixed
|
|
15
|
+
|
|
16
|
+
- `(empty)` group membership now uses the same emptiness test as the distinct-value pass (extracted as `isEmptyGroupingValue`). The two previously diverged: items whose grouping value was an empty array or a whitespace-only string were dropped entirely (they created the `(empty)` frame but no item matched into it), and `false`/`0` values double-counted into `(empty)` on top of their own group. Only observable with `displayItemsWithEmptyGroupingValues = true`. (VIBE-10759)
|
|
17
|
+
|
|
10
18
|
## [1.0.50] - (initial changelog entry)
|
|
11
19
|
|
|
12
20
|
- Initial changelog. Prior releases did not include a changelog.
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { DataGroup, DataGroupStructure, DataGroupingProperty } from '../interfaces';
|
|
2
2
|
import { TypePropertySortOrder } from '@contrail/types';
|
|
3
3
|
export declare class DataGroupGenerator {
|
|
4
|
+
static isEmptyGroupingValue(value: any): boolean;
|
|
4
5
|
static getDistinctValues(data: any, rootIndex: any, slugIndex?: any, rootAltIndex?: any, slugAltIndex?: any, groupMultiSelectInSeparateFrame?: boolean, sortOptions?: {
|
|
5
6
|
sortOrder: TypePropertySortOrder;
|
|
6
7
|
options: any;
|
|
@@ -8,6 +9,7 @@ export declare class DataGroupGenerator {
|
|
|
8
9
|
isDate: boolean;
|
|
9
10
|
isNumber: boolean;
|
|
10
11
|
}, displayItemsWithEmptyGroupingValues?: boolean, displayOptionFrameWithNoData?: boolean): any[];
|
|
12
|
+
static applyGroupingValueFilter(distinctValues: Array<any>, groupingProperty: DataGroupingProperty, groupMultiSelectInSeparateFrame: boolean): Array<any>;
|
|
11
13
|
static buildChildDataGroups(data: any, parentGroup: DataGroup, groupingProperties: Array<DataGroupingProperty>, leafNodeDataCount: any, currentDepth: any, groupMultiSelectInSeparateFrame?: boolean, displayItemsWithEmptyGroupingValues?: boolean, displayOptionFrameWithNoData?: boolean): void;
|
|
12
14
|
static buildDataGroupStructure(data: Array<any>, groupingProperties: Array<DataGroupingProperty>, leafNodeDataCount: number, groupMultiSelectInSeparateFrame?: boolean, displayItemsWithEmptyGroupingValues?: boolean, displayOptionFrameWithNoData?: boolean): DataGroupStructure;
|
|
13
15
|
static createPartitionedGroupsFromData(parentGroup: DataGroup, data: Array<any>, leafNodeDataCount: number): Array<DataGroup>;
|
|
@@ -4,6 +4,15 @@ exports.DataGroupGenerator = void 0;
|
|
|
4
4
|
const util_1 = require("@contrail/util");
|
|
5
5
|
const types_1 = require("@contrail/types");
|
|
6
6
|
class DataGroupGenerator {
|
|
7
|
+
static isEmptyGroupingValue(value) {
|
|
8
|
+
return ((value === undefined ||
|
|
9
|
+
value === null ||
|
|
10
|
+
value === '' ||
|
|
11
|
+
(Array.isArray(value) && value.length === 0) ||
|
|
12
|
+
(typeof value === 'string' && value.trim() === '') ||
|
|
13
|
+
(typeof value === 'number' && isNaN(value))) &&
|
|
14
|
+
value !== false);
|
|
15
|
+
}
|
|
7
16
|
static getDistinctValues(data, rootIndex, slugIndex = null, rootAltIndex = null, slugAltIndex = null, groupMultiSelectInSeparateFrame = false, sortOptions = { sortOrder: types_1.TypePropertySortOrder.ASCENDING, options: null }, propertyTypeOptions = { isDate: false, isNumber: false }, displayItemsWithEmptyGroupingValues = false, displayOptionFrameWithNoData = false) {
|
|
8
17
|
const sortOrder = (sortOptions === null || sortOptions === void 0 ? void 0 : sortOptions.sortOrder) || types_1.TypePropertySortOrder.ASCENDING;
|
|
9
18
|
const options = (sortOptions === null || sortOptions === void 0 ? void 0 : sortOptions.options) || null;
|
|
@@ -23,13 +32,7 @@ class DataGroupGenerator {
|
|
|
23
32
|
}
|
|
24
33
|
}
|
|
25
34
|
let value = key;
|
|
26
|
-
const isEmptyValue = (value
|
|
27
|
-
value === null ||
|
|
28
|
-
value === '' ||
|
|
29
|
-
(Array.isArray(value) && value.length === 0) ||
|
|
30
|
-
(typeof value === 'string' && value.trim() === '') ||
|
|
31
|
-
(typeof value === 'number' && isNaN(value))) &&
|
|
32
|
-
value !== false;
|
|
35
|
+
const isEmptyValue = DataGroupGenerator.isEmptyGroupingValue(value);
|
|
33
36
|
if (isEmptyValue) {
|
|
34
37
|
if (displayItemsWithEmptyGroupingValues) {
|
|
35
38
|
hasEmptyValues = true;
|
|
@@ -111,6 +114,24 @@ class DataGroupGenerator {
|
|
|
111
114
|
}
|
|
112
115
|
return distinctValues;
|
|
113
116
|
}
|
|
117
|
+
static applyGroupingValueFilter(distinctValues, groupingProperty, groupMultiSelectInSeparateFrame) {
|
|
118
|
+
var _a;
|
|
119
|
+
const rule = groupingProperty === null || groupingProperty === void 0 ? void 0 : groupingProperty.valueFilter;
|
|
120
|
+
if (!rule ||
|
|
121
|
+
!rule.values ||
|
|
122
|
+
rule.values.length === 0 ||
|
|
123
|
+
groupMultiSelectInSeparateFrame ||
|
|
124
|
+
((_a = groupingProperty === null || groupingProperty === void 0 ? void 0 : groupingProperty.propertyDefinition) === null || _a === void 0 ? void 0 : _a.propertyType) !== types_1.PropertyType.MultiSelect) {
|
|
125
|
+
return distinctValues;
|
|
126
|
+
}
|
|
127
|
+
const ruleValues = new Set(rule.values);
|
|
128
|
+
return distinctValues.filter((value) => {
|
|
129
|
+
if (value === '(empty)') {
|
|
130
|
+
return true;
|
|
131
|
+
}
|
|
132
|
+
return rule.mode === 'exclude' ? !ruleValues.has(value) : ruleValues.has(value);
|
|
133
|
+
});
|
|
134
|
+
}
|
|
114
135
|
static buildChildDataGroups(data, parentGroup, groupingProperties, leafNodeDataCount, currentDepth, groupMultiSelectInSeparateFrame = false, displayItemsWithEmptyGroupingValues = false, displayOptionFrameWithNoData = false) {
|
|
115
136
|
var _a, _b, _c, _d, _e;
|
|
116
137
|
const groupingProperty = groupingProperties[currentDepth];
|
|
@@ -128,11 +149,12 @@ class DataGroupGenerator {
|
|
|
128
149
|
const sort = groupingProperty.sort || types_1.TypePropertySortOrder.ASCENDING;
|
|
129
150
|
const options = ((_e = (_d = groupingProperty.propertyDefinition) === null || _d === void 0 ? void 0 : _d.options) === null || _e === void 0 ? void 0 : _e.map((x) => x.value)) || null;
|
|
130
151
|
let distinctValues = this.getDistinctValues(data, rootIndex, slugIndex, rootAltIndex, slugAltIndex, groupMultiSelectInSeparateFrame, { sortOrder: sort, options }, propertyTypeOptions, displayItemsWithEmptyGroupingValues, displayOptionFrameWithNoData);
|
|
152
|
+
distinctValues = this.applyGroupingValueFilter(distinctValues, groupingProperty, groupMultiSelectInSeparateFrame);
|
|
131
153
|
for (let val of distinctValues) {
|
|
132
154
|
const groupData = data.filter((obj) => {
|
|
133
155
|
const objVal = util_1.ObjectUtil.getBySlugs(obj, rootIndex, slugIndex) || util_1.ObjectUtil.getBySlugs(obj, rootAltIndex, slugAltIndex);
|
|
134
156
|
if (val === '(empty)') {
|
|
135
|
-
return
|
|
157
|
+
return DataGroupGenerator.isEmptyGroupingValue(objVal);
|
|
136
158
|
}
|
|
137
159
|
if (propertyTypeOptions.isDate) {
|
|
138
160
|
const objDate = objVal ? new Date(objVal).toISOString().split('T')[0] : null;
|
package/lib/interfaces.d.ts
CHANGED
package/package.json
CHANGED