@sis-cc/dotstatsuite-components 17.20.0 → 17.21.0

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.
@@ -407,4 +407,19 @@ Object.defineProperty(exports, 'parseLayoutIndexesHierarchies', {
407
407
  get: function get() {
408
408
  return _parseSeriesIndexesHierarchies.parseLayoutIndexesHierarchies;
409
409
  }
410
+ });
411
+
412
+ var _getTableLayoutIds = require('./table/getTableLayoutIds');
413
+
414
+ Object.defineProperty(exports, 'getTableLayoutIds', {
415
+ enumerable: true,
416
+ get: function get() {
417
+ return _getTableLayoutIds.getTableLayoutIds;
418
+ }
419
+ });
420
+ Object.defineProperty(exports, 'injectCombinationsInLayout', {
421
+ enumerable: true,
422
+ get: function get() {
423
+ return _getTableLayoutIds.injectCombinationsInLayout;
424
+ }
410
425
  });
@@ -3,15 +3,11 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.getLayout = undefined;
6
+ exports.getLayout = exports.parseCombination = exports.getConceptsSet = undefined;
7
7
 
8
- var _slicedToArray2 = require('babel-runtime/helpers/slicedToArray');
8
+ var _set = require('babel-runtime/core-js/set');
9
9
 
10
- var _slicedToArray3 = _interopRequireDefault(_slicedToArray2);
11
-
12
- var _extends2 = require('babel-runtime/helpers/extends');
13
-
14
- var _extends3 = _interopRequireDefault(_extends2);
10
+ var _set2 = _interopRequireDefault(_set);
15
11
 
16
12
  var _ramda = require('ramda');
17
13
 
@@ -19,71 +15,91 @@ var R = _interopRequireWildcard(_ramda);
19
15
 
20
16
  var _dotstatsuiteSdmxjs = require('@sis-cc/dotstatsuite-sdmxjs');
21
17
 
22
- var _utils = require('../utils');
23
-
24
18
  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
25
19
 
26
20
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
27
21
 
28
- var getLayout = exports.getLayout = function getLayout(layoutIds, dimensions, combinations, isTimeInverted) {
29
- var indexedDimensions = R.pipe(R.indexBy(R.prop('id')), R.map(function (d) {
30
- return (0, _dotstatsuiteSdmxjs.isTimePeriodDimension)(d) && isTimeInverted ? R.assoc('isInverted', true, d) : d;
31
- }))(dimensions);
32
- var indexedHeaderIds = R.indexBy(R.identity, layoutIds.header);
33
- var indexedSectionsIds = R.indexBy(R.identity, layoutIds.sections);
34
- var indexedRowsIds = (0, _extends3.default)({}, indexedSectionsIds, R.indexBy(R.identity, layoutIds.rows));
35
- var layout = { header: [], sections: [], rows: [] };
36
- R.forEach(function (comb) {
37
- if (R.isEmpty(comb.relationship)) {
38
- return;
39
- }
40
-
41
- var _R$partition = R.partition(function (id) {
42
- return R.has(id, indexedHeaderIds);
43
- }, comb.relationship),
44
- _R$partition2 = (0, _slicedToArray3.default)(_R$partition, 2),
45
- idsInHeader = _R$partition2[0],
46
- rest = _R$partition2[1];
47
-
48
- if (R.isEmpty(rest)) {
49
- layout = R.over(R.lensProp('header'), R.append((0, _extends3.default)({}, comb, {
50
- dimensions: (0, _utils.trimedProps)(comb.concepts, indexedDimensions)
51
- })))(layout);
52
- } else if (!R.isEmpty(idsInHeader)) {
53
- return;
22
+ var getConceptsSet = exports.getConceptsSet = function getConceptsSet(ids, indexedCombinations, _upper) {
23
+ var upper = R.isNil(_upper) ? new _set2.default([]) : _upper;
24
+ var res = new _set2.default([]);
25
+ R.forEach(function (id) {
26
+ if (!R.has(id, indexedCombinations)) {
27
+ res.add(id);
54
28
  } else {
55
- var idsNotInSections = R.reject(function (id) {
56
- return R.has(id, indexedSectionsIds);
57
- }, comb.relationship);
58
- if (R.isEmpty(idsNotInSections)) {
59
- layout = R.over(R.lensProp('sections'), R.append((0, _extends3.default)({}, comb, {
60
- dimensions: (0, _utils.trimedProps)(comb.concepts, indexedDimensions)
61
- })))(layout);
62
- } else {
63
- var idsNotInRows = R.reject(function (id) {
64
- return R.has(id, indexedRowsIds);
65
- }, comb.relationship);
66
- if (R.isEmpty(idsNotInRows)) {
67
- layout = R.over(R.lensProp('rows'), R.append((0, _extends3.default)({}, comb, {
68
- dimensions: R.pipe(R.omit(layoutIds.sections), function (o) {
69
- return (0, _utils.trimedProps)(comb.concepts, o);
70
- })(indexedDimensions)
71
- })))(layout);
29
+ var comb = R.prop(id, indexedCombinations);
30
+ R.forEach(function (c) {
31
+ if (!upper.has(c)) {
32
+ res.add(c);
72
33
  }
73
- }
34
+ }, comb.concepts);
74
35
  }
75
- }, combinations);
76
- return R.mapObjIndexed(function (combs, key) {
77
- var conceptIds = R.pipe(R.pluck('concepts'), R.unnest, R.indexBy(R.identity))(combs);
78
- var rest = R.reduce(function (acc, id) {
79
- if (R.has(id, conceptIds)) {
80
- return acc;
81
- }
82
- if (!R.has(id, indexedDimensions)) {
36
+ }, ids);
37
+ return res;
38
+ };
39
+
40
+ var parseCombination = exports.parseCombination = function parseCombination(_upperIds, _excludedIds) {
41
+ return function (comb, indexedDimensions) {
42
+ var upperIds = R.isNil(_upperIds) ? new _set2.default([]) : _upperIds;
43
+ var excludedIds = R.isNil(_excludedIds) ? new _set2.default([]) : _excludedIds;
44
+
45
+ var concepts = comb.concepts,
46
+ relationship = comb.relationship;
47
+
48
+ var dimensions = R.reduce(function (acc, id) {
49
+ if (upperIds.has(id) || !R.has(id, indexedDimensions)) {
83
50
  return acc;
84
51
  }
85
- return R.append(R.prop(id, indexedDimensions), acc);
86
- }, [], layoutIds[key]);
87
- return R.concat(rest, combs);
88
- }, layout);
52
+ var dim = R.prop(id, indexedDimensions);
53
+ return R.append(dim, acc);
54
+ }, [], concepts);
55
+ var excludedDep = R.find(function (i) {
56
+ return excludedIds.has(i);
57
+ }, relationship);
58
+ if (excludedDep) {
59
+ return dimensions;
60
+ }
61
+ return R.assoc('dimensions', dimensions, comb);
62
+ };
63
+ };
64
+
65
+ var getLayout = exports.getLayout = function getLayout(_layoutIds, dimensions, combinations, isTimeInverted) {
66
+ var layoutIds = R.mergeRight({ header: [], sections: [], rows: [] }, _layoutIds);
67
+ var applyInversionOnTimeDim = function applyInversionOnTimeDim(dim) {
68
+ return (0, _dotstatsuiteSdmxjs.isTimePeriodDimension)(dim) && isTimeInverted ? R.assoc('isInverted', true, dim) : dim;
69
+ };
70
+
71
+ var indexedDimensions = R.reduce(function (acc, dim) {
72
+ return R.assoc(dim.id, applyInversionOnTimeDim(dim), acc);
73
+ }, {}, dimensions);
74
+
75
+ var indexedCombinations = R.indexBy(R.prop('id'), combinations);
76
+ var headerConceptsSet = getConceptsSet(layoutIds.header, indexedCombinations);
77
+ var sectionsConceptsSet = getConceptsSet(layoutIds.sections, indexedCombinations);
78
+ var rowsConceptsSet = getConceptsSet(R.concat(layoutIds.sections, layoutIds.rows), indexedCombinations);
79
+
80
+ var getLayoutLevel = function getLayoutLevel(_upperIds, _excludedIds) {
81
+ return function (ids) {
82
+ return R.reduce(function (acc, id) {
83
+ if (R.has(id, indexedDimensions)) {
84
+ var dim = R.prop(id, indexedDimensions);
85
+ return R.append(dim, acc);
86
+ }
87
+ if (!R.has(id, indexedCombinations)) {
88
+ return acc;
89
+ }
90
+ var comb = R.prop(id, indexedCombinations);
91
+ var parsedCombination = parseCombination(_upperIds, _excludedIds)(comb, indexedDimensions);
92
+ if (R.is(Array, parsedCombination)) {
93
+ return R.concat(acc, parsedCombination);
94
+ }
95
+ return R.append(parsedCombination, acc);
96
+ }, [], ids);
97
+ };
98
+ };
99
+
100
+ var header = getLayoutLevel(null, rowsConceptsSet)(layoutIds.header);
101
+ var sections = getLayoutLevel(null, headerConceptsSet)(layoutIds.sections);
102
+ var rows = getLayoutLevel(sectionsConceptsSet, headerConceptsSet)(layoutIds.rows);
103
+
104
+ return { header: header, sections: sections, rows: rows };
89
105
  };
@@ -0,0 +1,222 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.getTableLayoutIds = exports.getLayoutCombinations = exports.getLayoutDimsIds = exports.injectCombinationsInLayout = exports.injectCombination = exports.getLayoutRelationships = exports.getLayoutLevelRelationship = exports.indexCombsRelationships = exports.getCombinationsNotInLayout = undefined;
7
+
8
+ var _extends2 = require('babel-runtime/helpers/extends');
9
+
10
+ var _extends3 = _interopRequireDefault(_extends2);
11
+
12
+ var _slicedToArray2 = require('babel-runtime/helpers/slicedToArray');
13
+
14
+ var _slicedToArray3 = _interopRequireDefault(_slicedToArray2);
15
+
16
+ var _toConsumableArray2 = require('babel-runtime/helpers/toConsumableArray');
17
+
18
+ var _toConsumableArray3 = _interopRequireDefault(_toConsumableArray2);
19
+
20
+ var _set = require('babel-runtime/core-js/set');
21
+
22
+ var _set2 = _interopRequireDefault(_set);
23
+
24
+ var _ramda = require('ramda');
25
+
26
+ var R = _interopRequireWildcard(_ramda);
27
+
28
+ var _dotstatsuiteSdmxjs = require('@sis-cc/dotstatsuite-sdmxjs');
29
+
30
+ function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
31
+
32
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
33
+
34
+ var getCombinationsNotInLayout = exports.getCombinationsNotInLayout = function getCombinationsNotInLayout(combinations, layoutIds) {
35
+ var _layoutIds$header = layoutIds.header,
36
+ header = _layoutIds$header === undefined ? [] : _layoutIds$header,
37
+ _layoutIds$sections = layoutIds.sections,
38
+ sections = _layoutIds$sections === undefined ? [] : _layoutIds$sections,
39
+ _layoutIds$rows = layoutIds.rows,
40
+ rows = _layoutIds$rows === undefined ? [] : _layoutIds$rows;
41
+
42
+ var idsInLayout = new _set2.default([].concat((0, _toConsumableArray3.default)(header), (0, _toConsumableArray3.default)(sections), (0, _toConsumableArray3.default)(rows)));
43
+ return R.reject(function (comb) {
44
+ return idsInLayout.has(comb.id);
45
+ }, combinations);
46
+ };
47
+
48
+ var indexCombsRelationships = exports.indexCombsRelationships = function indexCombsRelationships(combinations) {
49
+ return R.reduce(function (acc, comb) {
50
+ var id = comb.id,
51
+ _comb$relationship = comb.relationship,
52
+ relationship = _comb$relationship === undefined ? [] : _comb$relationship;
53
+
54
+ return R.assoc(id, relationship, acc);
55
+ }, {}, combinations);
56
+ };
57
+
58
+ var getLayoutLevelRelationship = exports.getLayoutLevelRelationship = function getLayoutLevelRelationship(indexedRelationships) {
59
+ return function (ids) {
60
+ return R.reduce(function (acc, id) {
61
+ if (R.has(id, indexedRelationships)) {
62
+ return R.concat(acc, R.prop(id, indexedRelationships));
63
+ }
64
+ return R.append(id, acc);
65
+ }, [], ids);
66
+ };
67
+ };
68
+
69
+ var getLayoutRelationships = exports.getLayoutRelationships = function getLayoutRelationships(indexedRelationships, layoutIds) {
70
+ return R.map(getLayoutLevelRelationship(indexedRelationships), layoutIds);
71
+ };
72
+
73
+ var injectCombination = exports.injectCombination = function injectCombination(combination) {
74
+ return function (ids) {
75
+ var id = combination.id,
76
+ _combination$concepts = combination.concepts,
77
+ concepts = _combination$concepts === undefined ? [] : _combination$concepts;
78
+
79
+ var conceptsSet = new _set2.default(concepts);
80
+ var inject = true;
81
+ var refined = R.reduce(function (acc, i) {
82
+ if (!conceptsSet.has(i)) {
83
+ return R.append(i, acc);
84
+ }
85
+ if (inject) {
86
+ inject = false;
87
+ return R.append(id, acc);
88
+ }
89
+ return acc;
90
+ }, [], ids);
91
+ return inject ? R.append(id, refined) : refined;
92
+ };
93
+ };
94
+
95
+ var injectCombinationsInLayout = exports.injectCombinationsInLayout = function injectCombinationsInLayout(combinations, layoutIds) {
96
+ var notInLayoutCombs = getCombinationsNotInLayout(combinations, layoutIds);
97
+ if (R.isEmpty(notInLayoutCombs)) {
98
+ return layoutIds;
99
+ }
100
+ var indexedCombsRelationships = indexCombsRelationships(combinations);
101
+ var layoutRelationships = getLayoutRelationships(indexedCombsRelationships, layoutIds);
102
+ return R.reduce(function (acc, comb) {
103
+ var _comb$relationship2 = comb.relationship,
104
+ relationship = _comb$relationship2 === undefined ? [] : _comb$relationship2;
105
+
106
+ var idsInHeaderSet = new _set2.default(layoutRelationships.header);
107
+ var idsInSectionsSet = new _set2.default(layoutRelationships.sections);
108
+ var idsInRowsSet = new _set2.default(layoutRelationships.rows);
109
+
110
+ var _R$partition = R.partition(function (i) {
111
+ return idsInHeaderSet.has(i);
112
+ }, relationship),
113
+ _R$partition2 = (0, _slicedToArray3.default)(_R$partition, 2),
114
+ idsInHeader = _R$partition2[0],
115
+ rest = _R$partition2[1];
116
+
117
+ var _R$reduce = R.reduce(function (_acc, id) {
118
+ if (idsInSectionsSet.has(id)) return R.over(R.lensIndex(0), R.append(id), _acc);
119
+ if (idsInRowsSet.has(id)) return R.over(R.lensIndex(1), R.append(id), _acc);
120
+ return R.over(R.lensIndex(2), R.append(id), _acc);
121
+ }, [[], [], []], rest),
122
+ _R$reduce2 = (0, _slicedToArray3.default)(_R$reduce, 3),
123
+ idsInSections = _R$reduce2[0],
124
+ idsInRows = _R$reduce2[1],
125
+ nowhere = _R$reduce2[2];
126
+
127
+ if (!R.isEmpty(idsInHeader) && R.isEmpty(idsInSections) && R.isEmpty(idsInRows)) {
128
+ layoutRelationships.header = R.concat(layoutRelationships.header, relationship);
129
+ var _ids = injectCombination(comb)(acc.header);
130
+ return R.assoc('header', _ids)(acc);
131
+ }
132
+ if (!R.isEmpty(idsInHeader)) {
133
+ return acc;
134
+ }
135
+ if (!R.isEmpty(idsInSections) && R.isEmpty(idsInRows)) {
136
+ layoutRelationships.sections = R.concat(layoutRelationships.sections, relationship);
137
+ var _ids2 = injectCombination(comb)(acc.sections);
138
+ return R.assoc('sections', _ids2)(acc);
139
+ }
140
+ var rowsConcepts = R.concat(idsInRows, nowhere);
141
+ layoutRelationships.rows = R.concat(layoutRelationships.rows, rowsConcepts);
142
+ var ids = injectCombination((0, _extends3.default)({}, comb, { concepts: rowsConcepts }))(acc.rows);
143
+ return R.assoc('rows', ids)(acc);
144
+ }, layoutIds, notInLayoutCombs);
145
+ };
146
+
147
+ var getLayoutDimsIds = exports.getLayoutDimsIds = function getLayoutDimsIds(dimensions) {
148
+ return R.reduce(function (acc, d) {
149
+ return d.header ? acc : acc.add(d.id);
150
+ }, new _set2.default([]), dimensions);
151
+ };
152
+
153
+ var getLayoutCombinations = exports.getLayoutCombinations = function getLayoutCombinations(combinations, layoutDimsIds, attributes) {
154
+ var indexedAttributes = R.indexBy(R.prop('id'), attributes);
155
+ return R.reduce(function (acc, comb) {
156
+ var _R$reduce3 = R.reduce(function (_acc, concept) {
157
+ if (layoutDimsIds.has(concept)) {
158
+ return R.map(R.append(concept), _acc);
159
+ }
160
+ if (R.has(concept, indexedAttributes)) {
161
+ var attr = R.prop(concept, indexedAttributes);
162
+ return attr.series ? (0, _extends3.default)({}, _acc, {
163
+ relationship: R.concat(_acc.relationship, attr.relationship)
164
+ }) : _acc;
165
+ }
166
+ return _acc;
167
+ }, { layoutConcepts: [], relationship: [] }, comb.concepts || []),
168
+ layoutConcepts = _R$reduce3.layoutConcepts,
169
+ relationship = _R$reduce3.relationship;
170
+
171
+ if (R.isEmpty(layoutConcepts)) {
172
+ return acc;
173
+ }
174
+ return R.append((0, _extends3.default)({}, comb, { relationship: relationship, concepts: layoutConcepts }), acc);
175
+ }, [], combinations);
176
+ };
177
+
178
+ var getTableLayoutIds = exports.getTableLayoutIds = function getTableLayoutIds(defaultLayoutIds, dimensions, attributes, combinations) {
179
+ var layoutDimsIds = getLayoutDimsIds(dimensions);
180
+ var layoutCombinations = getLayoutCombinations(combinations, layoutDimsIds, attributes);
181
+ var indexedCombinations = R.indexBy(R.prop('id'), layoutCombinations);
182
+ var filteredLayoutIds = R.map(R.filter(function (id) {
183
+ return R.has(id, indexedCombinations) || layoutDimsIds.has(id);
184
+ }), defaultLayoutIds);
185
+
186
+ var layoutWithCombs = injectCombinationsInLayout(layoutCombinations, filteredLayoutIds);
187
+ var layoutRelationshipsSets = R.map(function (ids) {
188
+ return R.pipe(R.pick(ids, indexedCombsRelationships), R.values, R.unnest, function (i) {
189
+ return new _set2.default(i);
190
+ })(ids);
191
+ }, layoutWithCombs);
192
+ var layoutConceptsSets = R.pipe(R.map(R.reduce(function (acc, id) {
193
+ if (R.has(id, indexedCombinations)) {
194
+ return R.concat(acc, R.path([id, 'relationship'], indexedCombinations));
195
+ }
196
+ return R.append(id, acc);
197
+ }, [])), R.values, R.unnest, function (ids) {
198
+ return new _set2.default(ids);
199
+ })(layoutWithCombs);
200
+
201
+ return R.reduce(function (acc, dim) {
202
+ if (layoutConceptsSets.has(id) || !dim.series) {
203
+ return acc;
204
+ }
205
+ if (layoutRelationshipsSets.header.has(dim.id)) {
206
+ return R.over(R.lensProp('header'), R.append(dim.id))(acc);
207
+ }
208
+ if (layoutRelationshipsSets.sections.has(dim.id)) {
209
+ return R.over(R.lensProp('sections'), R.append(dim.id))(acc);
210
+ }
211
+ if (layoutRelationshipsSets.rows.has(dim.id)) {
212
+ return R.over(R.lensProp('rows'), R.append(dim.id))(acc);
213
+ }
214
+ if ((0, _dotstatsuiteSdmxjs.isTimePeriodDimension)(dim)) {
215
+ return R.over(R.lensProp('header'), R.append(dim.id))(acc);
216
+ }
217
+ if ((0, _dotstatsuiteSdmxjs.isRefAreaDimension)(dim)) {
218
+ return R.over(R.lensProp('rows'), R.append(dim.id))(acc);
219
+ }
220
+ return R.over(R.lensProp('sections'), R.append(dim.id))(acc);
221
+ }, layoutWithCombs, dimensions);
222
+ };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@sis-cc/dotstatsuite-components",
3
3
  "description": "Set components based on React.",
4
- "version": "17.20.0",
4
+ "version": "17.21.0",
5
5
  "main": "lib/index.js",
6
6
  "author": "OECD",
7
7
  "license": "MIT",
@@ -45,3 +45,4 @@ export { getTableProps } from './table/getTableProps';
45
45
  export { getTableLabelAccessor } from './table/getTableLabelAccessor';
46
46
  export { parseValueHierarchy } from './table/parseValueHierarchy';
47
47
  export { parseLayoutIndexesHierarchies } from './table/parseSeriesIndexesHierarchies';
48
+ export { getTableLayoutIds, injectCombinationsInLayout } from './table/getTableLayoutIds';
@@ -1,72 +1,84 @@
1
1
  import * as R from 'ramda';
2
2
  import { isTimePeriodDimension } from '@sis-cc/dotstatsuite-sdmxjs';
3
- import { trimedProps } from '../utils';
4
3
 
5
- export const getLayout = (layoutIds, dimensions, combinations, isTimeInverted) => {
6
- const indexedDimensions = R.pipe(
7
- R.indexBy(R.prop('id')),
8
- R.map(d => (isTimePeriodDimension(d) && isTimeInverted ? R.assoc('isInverted', true, d) : d)),
9
- )(dimensions);
10
- const indexedHeaderIds = R.indexBy(R.identity, layoutIds.header);
11
- const indexedSectionsIds = R.indexBy(R.identity, layoutIds.sections);
12
- const indexedRowsIds = { ...indexedSectionsIds, ...R.indexBy(R.identity, layoutIds.rows) };
13
- let layout = { header: [], sections: [], rows: [] };
14
- R.forEach(comb => {
15
- if (R.isEmpty(comb.relationship)) {
16
- return;
17
- }
18
- const [idsInHeader, rest] = R.partition(id => R.has(id, indexedHeaderIds), comb.relationship);
19
- if (R.isEmpty(rest)) {
20
- layout = R.over(
21
- R.lensProp('header'),
22
- R.append({
23
- ...comb,
24
- dimensions: trimedProps(comb.concepts, indexedDimensions),
25
- }),
26
- )(layout);
27
- } else if (!R.isEmpty(idsInHeader)) {
28
- return;
29
- } else {
30
- const idsNotInSections = R.reject(id => R.has(id, indexedSectionsIds), comb.relationship);
31
- if (R.isEmpty(idsNotInSections)) {
32
- layout = R.over(
33
- R.lensProp('sections'),
34
- R.append({
35
- ...comb,
36
- dimensions: trimedProps(comb.concepts, indexedDimensions),
37
- }),
38
- )(layout);
39
- } else {
40
- const idsNotInRows = R.reject(id => R.has(id, indexedRowsIds), comb.relationship);
41
- if (R.isEmpty(idsNotInRows)) {
42
- layout = R.over(
43
- R.lensProp('rows'),
44
- R.append({
45
- ...comb,
46
- dimensions: R.pipe(R.omit(layoutIds.sections), o => trimedProps(comb.concepts, o))(
47
- indexedDimensions,
48
- ),
49
- }),
50
- )(layout);
51
- }
4
+ export const getConceptsSet = (ids, indexedCombinations, _upper) => {
5
+ const upper = R.isNil(_upper) ? new Set([]) : _upper;
6
+ const res = new Set([]);
7
+ R.forEach(id => {
8
+ if (!R.has(id, indexedCombinations)) {
9
+ res.add(id);
10
+ }
11
+ else {
12
+ const comb = R.prop(id, indexedCombinations);
13
+ R.forEach(c => {
14
+ if (!upper.has(c)) {
15
+ res.add(c);
52
16
  }
53
- }
54
- }, combinations);
55
- return R.mapObjIndexed((combs, key) => {
56
- const conceptIds = R.pipe(R.pluck('concepts'), R.unnest, R.indexBy(R.identity))(combs);
57
- const rest = R.reduce(
58
- (acc, id) => {
59
- if (R.has(id, conceptIds)) {
60
- return acc;
61
- }
62
- if (!R.has(id, indexedDimensions)) {
63
- return acc;
64
- }
65
- return R.append(R.prop(id, indexedDimensions), acc);
66
- },
67
- [],
68
- layoutIds[key],
69
- );
70
- return R.concat(rest, combs);
71
- }, layout);
72
- };
17
+ }, comb.concepts);
18
+ }
19
+ }, ids);
20
+ return res;
21
+ };
22
+
23
+ export const parseCombination = (_upperIds, _excludedIds) => (comb, indexedDimensions) => {
24
+ const upperIds = R.isNil(_upperIds) ? new Set([]) : _upperIds;
25
+ const excludedIds = R.isNil(_excludedIds) ? new Set([]) : _excludedIds;
26
+
27
+ const { concepts, relationship } = comb;
28
+ const dimensions = R.reduce((acc, id) => {
29
+ if (upperIds.has(id) || !R.has(id, indexedDimensions)) {
30
+ return acc
31
+ }
32
+ const dim = R.prop(id, indexedDimensions);
33
+ return R.append(dim, acc);
34
+ }, [], concepts);
35
+ const excludedDep = R.find(i => excludedIds.has(i), relationship);
36
+ if (excludedDep) {
37
+ return dimensions;
38
+ }
39
+ return R.assoc('dimensions', dimensions, comb);
40
+ };
41
+
42
+ export const getLayout = (_layoutIds, dimensions, combinations, isTimeInverted) => {
43
+ const layoutIds = R.mergeRight(
44
+ { header: [], sections: [], rows: [] },
45
+ _layoutIds,
46
+ );
47
+ const applyInversionOnTimeDim = dim =>
48
+ isTimePeriodDimension(dim) && isTimeInverted
49
+ ? R.assoc('isInverted', true, dim)
50
+ : dim;
51
+
52
+ const indexedDimensions = R.reduce(
53
+ (acc, dim) => R.assoc(dim.id, applyInversionOnTimeDim(dim), acc),
54
+ {},
55
+ dimensions,
56
+ );
57
+
58
+ const indexedCombinations = R.indexBy(R.prop('id'), combinations);
59
+ const headerConceptsSet = getConceptsSet(layoutIds.header, indexedCombinations);
60
+ const sectionsConceptsSet = getConceptsSet(layoutIds.sections, indexedCombinations);
61
+ const rowsConceptsSet = getConceptsSet(R.concat(layoutIds.sections, layoutIds.rows), indexedCombinations);
62
+
63
+ const getLayoutLevel = (_upperIds, _excludedIds) => ids => R.reduce((acc, id) => {
64
+ if (R.has(id, indexedDimensions)) {
65
+ const dim = R.prop(id, indexedDimensions);
66
+ return R.append(dim, acc);
67
+ }
68
+ if (!R.has(id, indexedCombinations)) {
69
+ return acc;
70
+ }
71
+ const comb = R.prop(id, indexedCombinations);
72
+ const parsedCombination = parseCombination(_upperIds, _excludedIds)(comb, indexedDimensions);
73
+ if (R.is(Array, parsedCombination)) {
74
+ return R.concat(acc, parsedCombination);
75
+ }
76
+ return R.append(parsedCombination, acc);
77
+ }, [], ids);
78
+
79
+ const header = getLayoutLevel(null, rowsConceptsSet)(layoutIds.header);
80
+ const sections = getLayoutLevel(null, headerConceptsSet)(layoutIds.sections);
81
+ const rows = getLayoutLevel(sectionsConceptsSet, headerConceptsSet)(layoutIds.rows);
82
+
83
+ return ({ header, sections, rows });
84
+ };
@@ -0,0 +1,186 @@
1
+ import * as R from 'ramda';
2
+ import { isTimePeriodDimension, isRefAreaDimension } from '@sis-cc/dotstatsuite-sdmxjs';
3
+
4
+ export const getCombinationsNotInLayout = (combinations, layoutIds) => {
5
+ const { header=[], sections=[], rows=[] } = layoutIds;
6
+ const idsInLayout = new Set([...header, ...sections, ...rows]);
7
+ return R.reject(comb => idsInLayout.has(comb.id), combinations);
8
+ };
9
+
10
+ export const indexCombsRelationships = (combinations) => R.reduce((acc, comb) => {
11
+ const { id, relationship=[] } = comb;
12
+ return R.assoc(id, relationship, acc);
13
+ }, {}, combinations);
14
+
15
+ export const getLayoutLevelRelationship = indexedRelationships => ids => R.reduce((acc, id) => {
16
+ if (R.has(id, indexedRelationships)) {
17
+ return R.concat(acc, R.prop(id, indexedRelationships));
18
+ }
19
+ return R.append(id, acc);
20
+ }, [], ids);
21
+
22
+ export const getLayoutRelationships = (indexedRelationships, layoutIds) => R.map(
23
+ getLayoutLevelRelationship(indexedRelationships),
24
+ layoutIds
25
+ );
26
+
27
+ export const injectCombination = combination => ids => {
28
+ const { id, concepts=[] } = combination;
29
+ const conceptsSet = new Set(concepts);
30
+ let inject = true;
31
+ const refined = R.reduce((acc, i) => {
32
+ if (!conceptsSet.has(i)) {
33
+ return R.append(i, acc);
34
+ }
35
+ if (inject) {
36
+ inject = false;
37
+ return R.append(id, acc);
38
+ }
39
+ return acc;
40
+ }, [], ids);
41
+ return inject ? R.append(id, refined) : refined;
42
+ };
43
+
44
+ export const injectCombinationsInLayout = (combinations, layoutIds) => {
45
+ const notInLayoutCombs = getCombinationsNotInLayout(combinations, layoutIds);
46
+ if (R.isEmpty(notInLayoutCombs)) {
47
+ return layoutIds;
48
+ }
49
+ const indexedCombsRelationships = indexCombsRelationships(combinations);
50
+ let layoutRelationships = getLayoutRelationships(indexedCombsRelationships, layoutIds);
51
+ return R.reduce((acc, comb) => {
52
+ const { relationship=[] } = comb;
53
+ const idsInHeaderSet = new Set(layoutRelationships.header);
54
+ const idsInSectionsSet = new Set(layoutRelationships.sections);
55
+ const idsInRowsSet = new Set(layoutRelationships.rows);
56
+ const [idsInHeader, rest] = R.partition(
57
+ i => idsInHeaderSet.has(i),
58
+ relationship
59
+ );
60
+ const [idsInSections, idsInRows, nowhere] = R.reduce((_acc, id) => {
61
+ if (idsInSectionsSet.has(id))
62
+ return R.over(R.lensIndex(0), R.append(id), _acc);
63
+ if (idsInRowsSet.has(id))
64
+ return R.over(R.lensIndex(1), R.append(id), _acc);
65
+ return R.over(R.lensIndex(2), R.append(id), _acc);
66
+ }, [[], [], []], rest);
67
+ if (!R.isEmpty(idsInHeader) && R.isEmpty(idsInSections) && R.isEmpty(idsInRows)) {
68
+ layoutRelationships.header = R.concat(layoutRelationships.header, relationship);
69
+ const ids = injectCombination(comb)(acc.header);
70
+ return R.assoc('header', ids)(acc);
71
+ }
72
+ if (!R.isEmpty(idsInHeader)) {
73
+ return acc;
74
+ }
75
+ if (!R.isEmpty(idsInSections) && R.isEmpty(idsInRows)) {
76
+ layoutRelationships.sections = R.concat(layoutRelationships.sections, relationship);
77
+ const ids = injectCombination(comb)(acc.sections);
78
+ return R.assoc('sections', ids)(acc);
79
+ }
80
+ const rowsConcepts = R.concat(idsInRows, nowhere);
81
+ layoutRelationships.rows = R.concat(layoutRelationships.rows, rowsConcepts);
82
+ const ids = injectCombination({ ...comb, concepts: rowsConcepts })(acc.rows);
83
+ return R.assoc('rows', ids)(acc);
84
+ }, layoutIds, notInLayoutCombs);
85
+ };
86
+
87
+ export const getLayoutDimsIds = dimensions => R.reduce(
88
+ (acc, d) => (d.header ? acc : acc.add(d.id)),
89
+ new Set([]),
90
+ dimensions,
91
+ );
92
+
93
+ export const getLayoutCombinations = (combinations, layoutDimsIds, attributes) => {
94
+ const indexedAttributes = R.indexBy(R.prop('id'), attributes);
95
+ return R.reduce(
96
+ (acc, comb) => {
97
+ const { layoutConcepts, relationship } = R.reduce(
98
+ (_acc, concept) => {
99
+ if (layoutDimsIds.has(concept)) {
100
+ return R.map(R.append(concept), _acc);
101
+ }
102
+ if (R.has(concept, indexedAttributes)) {
103
+ const attr = R.prop(concept, indexedAttributes);
104
+ return attr.series
105
+ ? {
106
+ ..._acc,
107
+ relationship: R.concat(_acc.relationship, attr.relationship),
108
+ }
109
+ : _acc;
110
+ }
111
+ return _acc;
112
+ },
113
+ { layoutConcepts: [], relationship: [] },
114
+ comb.concepts || [],
115
+ );
116
+ if (R.isEmpty(layoutConcepts)) {
117
+ return acc;
118
+ }
119
+ return R.append({ ...comb, relationship, concepts: layoutConcepts }, acc);
120
+ },
121
+ [],
122
+ combinations,
123
+ );
124
+ };
125
+
126
+ export const getTableLayoutIds = (
127
+ defaultLayoutIds,
128
+ dimensions,
129
+ attributes,
130
+ combinations
131
+ ) => {
132
+ const layoutDimsIds = getLayoutDimsIds(dimensions);
133
+ const layoutCombinations = getLayoutCombinations(
134
+ combinations,
135
+ layoutDimsIds,
136
+ attributes,
137
+ );
138
+ const indexedCombinations = R.indexBy(R.prop('id'), layoutCombinations);
139
+ const filteredLayoutIds = R.map(
140
+ R.filter(id => R.has(id, indexedCombinations) || layoutDimsIds.has(id)),
141
+ defaultLayoutIds,
142
+ );
143
+
144
+ const layoutWithCombs = injectCombinationsInLayout(layoutCombinations, filteredLayoutIds);
145
+ const layoutRelationshipsSets = R.map(ids => R.pipe(
146
+ R.pick(ids, indexedCombsRelationships),
147
+ R.values,
148
+ R.unnest,
149
+ i => new Set(i)
150
+ )(ids),layoutWithCombs);
151
+ const layoutConceptsSets = R.pipe(
152
+ R.map(
153
+ R.reduce((acc, id) => {
154
+ if (R.has(id, indexedCombinations)) {
155
+ return R.concat(acc, R.path([id, 'relationship'], indexedCombinations));
156
+ }
157
+ return R.append(id, acc);
158
+ }, []),
159
+ ),
160
+ R.values,
161
+ R.unnest,
162
+ ids => new Set(ids)
163
+ )(layoutWithCombs);
164
+
165
+ return R.reduce((acc, dim) => {
166
+ if (layoutConceptsSets.has(id) || !dim.series) {
167
+ return acc;
168
+ }
169
+ if (layoutRelationshipsSets.header.has(dim.id)) {
170
+ return R.over(R.lensProp('header'), R.append(dim.id))(acc);
171
+ }
172
+ if (layoutRelationshipsSets.sections.has(dim.id)) {
173
+ return R.over(R.lensProp('sections'), R.append(dim.id))(acc);
174
+ }
175
+ if (layoutRelationshipsSets.rows.has(dim.id)) {
176
+ return R.over(R.lensProp('rows'), R.append(dim.id))(acc);
177
+ }
178
+ if (isTimePeriodDimension(dim)) {
179
+ return R.over(R.lensProp('header'), R.append(dim.id))(acc);
180
+ }
181
+ if (isRefAreaDimension(dim)) {
182
+ return R.over(R.lensProp('rows'), R.append(dim.id))(acc);
183
+ }
184
+ return R.over(R.lensProp('sections'), R.append(dim.id))(acc);
185
+ }, layoutWithCombs, dimensions);
186
+ };
@@ -9,32 +9,44 @@ describe('getLayout tests', () => {
9
9
  { id: 'D2', values: [{ id: 'v1' }, { id: 'v2' }] },
10
10
  { id: 'D3', values: [{ id: 'v1' }, { id: 'v2' }] },
11
11
  { id: 'D4', values: [{ id: 'v1' }, { id: 'v2' }] },
12
+ { id: 'D5', values: [{ id: 'v1' }, { id: 'v2' }] },
12
13
  { id: 'TIME_PERIOD', values: [{ id: 'v1' }, { id: 'v2' }] }
13
14
  ];
14
15
 
15
16
  const layoutIds = {
16
- header: ['TIME_PERIOD'],
17
- sections: ['D1'],
18
- rows: ['D4', 'D2', 'D3']
17
+ header: ['TIME_PERIOD', 'COMB1', 'COMB2'],
18
+ sections: ['D4'],
19
+ rows: ['COMB3', 'COMB4']
19
20
  };
20
21
 
21
22
  const combinations = [
22
- { id: 'COMB1', concepts: ['D2', 'D3'], relationship: [] }, // rejected for empty relationship
23
- { id: 'COMB2', concepts: ['D3', 'D4', 'A1'], relationship: ['D3', 'D4', 'TIME_PERIOD'] }, // rejected because relationship is incompatible with layout
24
- { id: 'COMB3', concepts: ['D1', 'D2', 'A2', 'D5'], relationship: ['D1', 'D2', 'D3'] },
23
+ { id: 'COMB1', concepts: ['D1', 'D2'], relationship: ['D1', 'D2'] },
24
+ { id: 'COMB2', concepts: ['D3', 'A1'], relationship: ['D3', 'D4', 'TIME_PERIOD'] },
25
+ { id: 'COMB3', concepts: ['D4', 'D5'], relationship: ['D4', 'D5'] },
26
+ { id: 'COMB4', concepts: ['A2', 'A3'], relationship: ['D5', 'TIME_PERIOD'] }
25
27
  ];
26
28
 
27
29
  expect(getLayout(layoutIds, dimensions, combinations, isTimeInverted)).to.deep.equal({
28
- header: [{ id: 'TIME_PERIOD', isInverted: true, values: [{ id: 'v1' }, { id: 'v2' }] }],
29
- sections: [{ id: 'D1', values: [{ id: 'v1' }, { id: 'v2' }] }],
30
- rows: [
31
- { id: 'D4', values: [{ id: 'v1' }, { id: 'v2' }] },
30
+ header: [
31
+ { id: 'TIME_PERIOD', isInverted: true, values: [{ id: 'v1' }, { id: 'v2' }] },
32
+ {
33
+ id: 'COMB1',
34
+ concepts: ['D1', 'D2'],
35
+ relationship: ['D1', 'D2'],
36
+ dimensions: [
37
+ { id: 'D1', values: [{ id: 'v1' }, { id: 'v2' }] },
38
+ { id: 'D2', values: [{ id: 'v1' }, { id: 'v2' }] },
39
+ ]
40
+ },
32
41
  { id: 'D3', values: [{ id: 'v1' }, { id: 'v2' }] },
42
+ ],
43
+ sections: [{ id: 'D4', values: [{ id: 'v1' }, { id: 'v2' }] }],
44
+ rows: [
33
45
  {
34
46
  id: 'COMB3',
35
- concepts: ['D1', 'D2', 'A2', 'D5'],
36
- relationship: ['D1', 'D2', 'D3'],
37
- dimensions: [{ id: 'D2', values: [{ id: 'v1' }, { id: 'v2' }] }] // D1 kept at section level
47
+ concepts: ['D4', 'D5'],
48
+ relationship: ['D4', 'D5'],
49
+ dimensions: [{ id: 'D5', values: [{ id: 'v1' }, { id: 'v2' }] }]
38
50
  },
39
51
  ]
40
52
  })
@@ -0,0 +1,31 @@
1
+ import { expect } from 'chai';
2
+ import { injectCombinationsInLayout } from '../src/rules2/src/table/getTableLayoutIds';
3
+
4
+ describe('injectCombinationsInLayout', () => {
5
+ it('complete test', () => {
6
+ const layoutIds = {
7
+ header: ['D1', 'C1', 'D2'],
8
+ sections: ['C5', 'D5', 'D3'],
9
+ rows: ['D4']
10
+ };
11
+
12
+ const combinations = [
13
+ { id: 'C1', concepts: ['D0', 'A2'], relationship: ['D0'] }, // already in header
14
+ { id: 'C2', concepts: ['D1', 'D2', 'A1'], relationship: ['D1', 'D2', 'D0'] }, // concepts are in header and relate to one of C1 concepts
15
+ { id: 'C3', concepts: ['D1', 'D2', 'D3'], relationship: ['D1', 'D2', 'D3'] }, // concepts both in header & sections -> rejected
16
+ { id: 'C4', concepts: ['D1', 'D2', 'D4'], relationship: ['D1', 'D2', 'D4'] }, // concepts both in header & rows -> rejected
17
+ { id: 'C5', concepts: ['D6', 'D7'], relationship: ['D6', 'D7', 'D5'] }, // already in sections
18
+ { id: 'C6', concepts: ['D3', 'D5'], relationship: ['D3', 'D5', 'D7'] }, // concepts in sections and relate to one C5 concept
19
+ { id: 'C7', concepts: ['D3', 'D8'], relationship: ['D3', 'D8'] }, // partial concepts in sections, none in rows
20
+ { id: 'C8', concepts: ['A1', 'A2', 'D9'], relationship: ['D0', 'D9'] }, // partial concepts in header nothing elsewhere
21
+ { id: 'C9', concepts: ['A3', 'D10', 'D11', 'D12'], relationship: ['D10', 'D11', 'D12'] }, // all new concepts
22
+ { id: 'C10', concepts: ['D10', 'D8'], relationship: ['D10', 'D8'] }, // relates to one concept of C7 and to one of C9
23
+ ];
24
+
25
+ expect(injectCombinationsInLayout(combinations, layoutIds)).to.deep.equal({
26
+ header: ['C2', 'C1', 'C8'],
27
+ sections: ['C5', 'C6', 'C7'],
28
+ rows: ['D4', 'C9', 'C10']
29
+ });
30
+ });
31
+ });