@sis-cc/dotstatsuite-components 15.0.21 → 16.0.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.
Files changed (161) hide show
  1. package/lib/rules/src/index.js +1 -145
  2. package/lib/rules/src/table/index.js +0 -42
  3. package/lib/rules2/src/constants.js +3 -1
  4. package/lib/rules2/src/enhanceObservations.js +98 -0
  5. package/lib/rules2/src/getAttributesSeries.js +33 -0
  6. package/lib/rules2/src/getCombinationDefinitions.js +48 -0
  7. package/lib/rules2/src/getHeaderCombinations.js +42 -0
  8. package/lib/rules2/src/getHeaderSubtitle.js +41 -0
  9. package/lib/rules2/src/getManyValuesDimensions.js +39 -0
  10. package/lib/rules2/src/getOneValueDimensions.js +46 -0
  11. package/lib/rules2/src/hasCellMetadata.js +1 -1
  12. package/lib/rules2/src/index.js +186 -18
  13. package/lib/rules2/src/parseAttributes.js +50 -0
  14. package/lib/rules2/src/parseCombinations.js +54 -0
  15. package/lib/rules2/src/prepareData.js +74 -0
  16. package/lib/{rules/src/table/preparators/getAttributeValue.js → rules2/src/refineAttributes.js} +13 -11
  17. package/lib/rules2/src/table/getCells.js +74 -0
  18. package/lib/rules2/src/table/getCellsAttributesIds.js +63 -0
  19. package/lib/rules2/src/table/getCombinationDimensionsData.js +47 -0
  20. package/lib/rules2/src/table/getCuratedCells.js +28 -0
  21. package/lib/rules2/src/table/getFlagsAndNotes.js +28 -0
  22. package/lib/rules2/src/table/getIndexedCombinationsByDisplay.js +31 -0
  23. package/lib/rules2/src/table/getLayout.js +93 -0
  24. package/lib/rules2/src/table/getLayoutData.js +202 -0
  25. package/lib/{rules/src/table/factories → rules2/src/table}/getSortedLayoutIndexes.js +55 -40
  26. package/lib/rules2/src/table/getTableProps.js +64 -0
  27. package/lib/rules2/src/table/parseValueHierarchy.js +55 -0
  28. package/lib/{rules/src/table/factories → rules2/src/table}/refineLayoutSize.js +17 -8
  29. package/lib/rules2/src/{hasLayoutEntryMetadata.js → utils.js} +9 -6
  30. package/package.json +1 -1
  31. package/src/rules/src/index.js +1 -19
  32. package/src/rules/src/table/index.js +0 -4
  33. package/src/rules2/src/constants.js +2 -0
  34. package/src/rules2/src/enhanceObservations.js +88 -0
  35. package/src/rules2/src/getAttributesSeries.js +29 -0
  36. package/src/rules2/src/getCombinationDefinitions.js +29 -0
  37. package/src/rules2/src/getHeaderCombinations.js +39 -0
  38. package/src/rules2/src/getHeaderSubtitle.js +34 -0
  39. package/src/rules2/src/getManyValuesDimensions.js +34 -0
  40. package/src/rules2/src/getOneValueDimensions.js +33 -0
  41. package/src/rules2/src/hasCellMetadata.js +1 -1
  42. package/src/rules2/src/index.js +21 -6
  43. package/src/rules2/src/parseAttributes.js +36 -0
  44. package/src/rules2/src/parseCombinations.js +36 -0
  45. package/src/rules2/src/prepareData.js +50 -0
  46. package/src/rules2/src/refineAttributes.js +16 -0
  47. package/src/rules2/src/table/getCells.js +72 -0
  48. package/src/rules2/src/table/getCellsAttributesIds.js +38 -0
  49. package/src/rules2/src/table/getCombinationDimensionsData.js +38 -0
  50. package/src/rules2/src/table/getCuratedCells.js +33 -0
  51. package/src/rules2/src/table/getFlagsAndNotes.js +21 -0
  52. package/src/rules2/src/table/getIndexedCombinationsByDisplay.js +16 -0
  53. package/src/rules2/src/table/getLayout.js +80 -0
  54. package/src/rules2/src/table/getLayoutData.js +183 -0
  55. package/src/rules2/src/table/getSortedLayoutIndexes.js +119 -0
  56. package/src/rules2/src/table/getTableProps.js +36 -0
  57. package/src/rules2/src/table/parseValueHierarchy.js +27 -0
  58. package/src/{rules/src/table/factories → rules2/src/table}/refineLayoutSize.js +24 -8
  59. package/src/rules2/src/utils.js +12 -0
  60. package/test/enhanceObservations2.test.js +219 -0
  61. package/test/getAttributesSeries.test.js +58 -0
  62. package/test/getCells.test.js +6 -40
  63. package/test/getCombinationDimensionsData.test.js +48 -0
  64. package/test/getSortedLayoutIndexes.test.js +1025 -3
  65. package/test/parseAttributes.test.js +17 -62
  66. package/test/parseValueHierarchy.test.js +88 -0
  67. package/test/refineLayoutSize.test.js +2621 -1
  68. package/lib/rules/src/table/factories/getCells.js +0 -97
  69. package/lib/rules/src/table/factories/getConfirmedSeriesAttributesIds.js +0 -26
  70. package/lib/rules/src/table/factories/getCuratedCells.js +0 -45
  71. package/lib/rules/src/table/factories/getLayoutData.js +0 -168
  72. package/lib/rules/src/table/factories/getLayoutWithFlags.js +0 -133
  73. package/lib/rules/src/table/factories/getTableCells.js +0 -24
  74. package/lib/rules/src/table/factories/getTableData.js +0 -98
  75. package/lib/rules/src/table/preparators/getDimensionsAttributesRegisters.js +0 -43
  76. package/lib/rules/src/table/preparators/getManyValuesDimensions.js +0 -33
  77. package/lib/rules/src/table/preparators/getOneValueDimensions.js +0 -24
  78. package/lib/rules/src/table/preparators/getUniqValuesAttributes.js +0 -36
  79. package/lib/rules/src/table/preparators/parseAttributes.js +0 -84
  80. package/lib/rules/src/table/preparators/parseAttributesValuesFromObservations.js +0 -22
  81. package/lib/rules/src/table/preparators/parseDimensionsIds.js +0 -22
  82. package/lib/rules/src/table/preparators/prepareData.js +0 -191
  83. package/lib/rules/src/table/preparators/refineObservationsAttributesValues.js +0 -31
  84. package/lib/rules/src/table/preparators/refineSeriesAttributesValues.js +0 -23
  85. package/lib/rules/src/table/units/appendUnitsInLayoutData.js +0 -82
  86. package/lib/rules/src/table/units/appendUnitsInLayoutDataEntry.js +0 -45
  87. package/lib/rules/src/table/units/cleanUnitsInLayoutData.js +0 -66
  88. package/lib/rules/src/table/units/getAttachmentSeriesIndexes.js +0 -25
  89. package/lib/rules/src/table/units/getHeaderUnits.js +0 -35
  90. package/lib/rules/src/table/units/getUnitsArtefacts.js +0 -85
  91. package/lib/rules/src/table/units/getUnitsCodes.js +0 -23
  92. package/lib/rules/src/table/units/getUnitsDefinition.js +0 -33
  93. package/lib/rules/src/table/units/getUnitsDisplay.js +0 -33
  94. package/lib/rules/src/table/units/getUnitsSerieIndexes.js +0 -23
  95. package/lib/rules/src/table/units/getUnitsSeries.js +0 -49
  96. package/lib/rules/src/table/units/getUnitsinLayout.js +0 -74
  97. package/lib/rules/src/table/units/refineDimSeriesUnits.js +0 -44
  98. package/lib/rules2/src/getAdvancedAttributes.js +0 -124
  99. package/lib/rules2/src/invertTime.js +0 -33
  100. package/src/rules/src/table/factories/getCells.js +0 -102
  101. package/src/rules/src/table/factories/getConfirmedSeriesAttributesIds.js +0 -27
  102. package/src/rules/src/table/factories/getCuratedCells.js +0 -40
  103. package/src/rules/src/table/factories/getLayoutData.js +0 -171
  104. package/src/rules/src/table/factories/getLayoutWithFlags.js +0 -137
  105. package/src/rules/src/table/factories/getSortedLayoutIndexes.js +0 -108
  106. package/src/rules/src/table/factories/getTableCells.js +0 -16
  107. package/src/rules/src/table/factories/getTableData.js +0 -86
  108. package/src/rules/src/table/preparators/getAttributeValue.js +0 -17
  109. package/src/rules/src/table/preparators/getDimensionsAttributesRegisters.js +0 -51
  110. package/src/rules/src/table/preparators/getManyValuesDimensions.js +0 -19
  111. package/src/rules/src/table/preparators/getOneValueDimensions.js +0 -17
  112. package/src/rules/src/table/preparators/getUniqValuesAttributes.js +0 -24
  113. package/src/rules/src/table/preparators/parseAttributes.js +0 -113
  114. package/src/rules/src/table/preparators/parseAttributesValuesFromObservations.js +0 -16
  115. package/src/rules/src/table/preparators/parseDimensionsIds.js +0 -17
  116. package/src/rules/src/table/preparators/prepareData.js +0 -197
  117. package/src/rules/src/table/preparators/refineObservationsAttributesValues.js +0 -22
  118. package/src/rules/src/table/preparators/refineSeriesAttributesValues.js +0 -11
  119. package/src/rules/src/table/units/appendUnitsInLayoutData.js +0 -56
  120. package/src/rules/src/table/units/appendUnitsInLayoutDataEntry.js +0 -38
  121. package/src/rules/src/table/units/cleanUnitsInLayoutData.js +0 -65
  122. package/src/rules/src/table/units/getAttachmentSeriesIndexes.js +0 -27
  123. package/src/rules/src/table/units/getHeaderUnits.js +0 -32
  124. package/src/rules/src/table/units/getUnitsArtefacts.js +0 -90
  125. package/src/rules/src/table/units/getUnitsCodes.js +0 -22
  126. package/src/rules/src/table/units/getUnitsDefinition.js +0 -34
  127. package/src/rules/src/table/units/getUnitsDisplay.js +0 -19
  128. package/src/rules/src/table/units/getUnitsSerieIndexes.js +0 -12
  129. package/src/rules/src/table/units/getUnitsSeries.js +0 -41
  130. package/src/rules/src/table/units/getUnitsinLayout.js +0 -71
  131. package/src/rules/src/table/units/refineDimSeriesUnits.js +0 -26
  132. package/src/rules2/src/getAdvancedAttributes.js +0 -111
  133. package/src/rules2/src/hasLayoutEntryMetadata.js +0 -9
  134. package/src/rules2/src/invertTime.js +0 -22
  135. package/test/advanced-attributes-parsing-perf.test.js +0 -16
  136. package/test/appendUnitsInLayoutDataEntry.test.js +0 -65
  137. package/test/cleanUnitsInLayoutData.test.js +0 -85
  138. package/test/enhanceObservations.test.js +0 -340
  139. package/test/getAttachmentSeriesIndexes.test.js +0 -35
  140. package/test/getConfirmedSeriesAttributesIds.test.js +0 -27
  141. package/test/getDataflowAdvancedAttributes.test.js +0 -32
  142. package/test/getHeaderUnits.test.js +0 -51
  143. package/test/getLayoutData.test.js +0 -206
  144. package/test/getLayoutDataWithFlags.test.js +0 -142
  145. package/test/getOneValueDimensions.test.js +0 -26
  146. package/test/getSeriesAdvancedAttributes.test.js +0 -32
  147. package/test/getSubtitleFlags.test.js +0 -42
  148. package/test/getTableData.test.js +0 -1317
  149. package/test/getUnitsArtefacts.test.js +0 -117
  150. package/test/getUnitsDefinition.test.js +0 -37
  151. package/test/getUnitsInLayout.test.js +0 -77
  152. package/test/getUnitsSeries.test.js +0 -154
  153. package/test/invertTime.test.js +0 -77
  154. package/test/parseAttributesValuesFromObservations.test.js +0 -45
  155. package/test/parseDimensionsIds.test.js +0 -20
  156. package/test/prepareData.test.js +0 -29
  157. package/test/refineObservationsAttributesValues.test.js +0 -33
  158. package/test/table-invert-time-perf.test.js +0 -11
  159. package/test/table-layout-perf.test.js +0 -74
  160. package/test/table-prep-duplicate-perf.test.js +0 -15
  161. package/test/table-prep-perf.test.js +0 -61
@@ -0,0 +1,72 @@
1
+ import * as R from 'ramda';
2
+ import { getFlagsAndNotes } from './getFlagsAndNotes';
3
+ import { hasCellMetadata } from '../hasCellMetadata';
4
+ import { trimedProps } from '../utils';
5
+
6
+ export const getCellRelevantAttributes = (attributes, attributesSeries, cellAttributeIds) => R.filter(
7
+ (attr) => {
8
+ if (R.has(attr.id, cellAttributeIds)) {
9
+ return true;
10
+ }
11
+ const attrInSerie = R.path([attr.serieKey, attr.id], attributesSeries);
12
+ return R.isNil(attrInSerie);
13
+ },
14
+ attributes
15
+ );
16
+
17
+ export const getCellCombinedAttributes = (attributes, combinations) => R.reduce(
18
+ (acc, comb) => {
19
+ const values = trimedProps(comb.concepts, attributes);
20
+ if (R.isEmpty(values)) {
21
+ return acc;
22
+ }
23
+ return R.append({ ...R.pick(['id', 'name'], comb), values: R.pluck('value', values) }, acc);
24
+ },
25
+ [],
26
+ combinations
27
+ )
28
+
29
+ // combinations = { cells, layout };
30
+ export const getCells = (customAttributes, cellsAttributesId, combinations, attributesSeries, metadataCoordinates) => observations => {
31
+ const attributesInLayoutCombination = R.pipe(
32
+ R.propOr([], 'layout'),
33
+ R.pluck('concepts'),
34
+ R.unnest
35
+ )(combinations);
36
+
37
+ const attributesInCellsCombination = R.pipe(
38
+ R.propOr([], 'cells'),
39
+ R.pluck('concepts'),
40
+ R.unnest
41
+ )(combinations);
42
+
43
+ const _customAttributes = R.over(
44
+ R.lensProp('notes'),
45
+ notes => R.concat(notes || [], attributesInLayoutCombination)
46
+ )(customAttributes);
47
+
48
+ return R.mapObjIndexed(
49
+ obs => {
50
+ const relevantAttributes = getCellRelevantAttributes(obs.attributes, attributesSeries, cellsAttributesId);
51
+ const flagsAndNotes = getFlagsAndNotes(relevantAttributes, _customAttributes);
52
+ const combinedAttributes = getCellCombinedAttributes(relevantAttributes, combinations.cells || []);
53
+
54
+ const hasAdvancedAttributes = R.pipe(
55
+ R.omit(R.unnest([_customAttributes.flags || [], _customAttributes.notes || [], attributesInCellsCombination])),
56
+ R.isEmpty,
57
+ R.not
58
+ )(relevantAttributes);
59
+
60
+ const hasMetadata = hasCellMetadata(metadataCoordinates, obs.indexedDimValIds);
61
+
62
+ return ({
63
+ ...R.pick(['indexedDimValIds', 'key'], obs),
64
+ flags: R.concat(flagsAndNotes, combinedAttributes),
65
+ sideProps: hasAdvancedAttributes || hasMetadata ? { hasAdvancedAttributes, hasMetadata, coordinates: obs.indexedDimValIds } : null,
66
+ intValue: R.is(Number, obs.value) ? obs.value : null,
67
+ value: obs.formattedValue,
68
+ });
69
+ },
70
+ observations
71
+ );
72
+ };
@@ -0,0 +1,38 @@
1
+ import * as R from 'ramda';
2
+
3
+ export const getCellsAttributesIds = (layoutIds, attributes) => {
4
+ return R.reduce(
5
+ (acc, attr) => {
6
+ if (!attr.series) {
7
+ return acc;
8
+ }
9
+ if (R.isEmpty(attr.relationship || [])) {
10
+ return R.assoc(attr.id, attr.id, acc);
11
+ }
12
+ const indexedHeaderIds = R.indexBy(R.identity, layoutIds.header);
13
+ const indexedSectionsIds = R.indexBy(R.identity, layoutIds.sections);
14
+ const indexedRowsIds = { ...indexedSectionsIds, ...R.indexBy(R.identity, layoutIds.rows) };
15
+ const [idsInHeader, rest] = R.partition(
16
+ id => R.has(id, indexedHeaderIds),
17
+ attr.relationship,
18
+ );
19
+ if (R.isEmpty(rest)) {
20
+ return acc;
21
+ } else if (!R.isEmpty(idsInHeader)) {
22
+ return R.assoc(attr.id, attr.id, acc);
23
+ } else {
24
+ const idsNotInSections = R.reject(id => R.has(id, indexedSectionsIds), attr.relationship);
25
+ if (R.isEmpty(idsNotInSections)) {
26
+ return acc;
27
+ }
28
+ const idsNotInRows = R.reject(id => R.has(id, indexedRowsIds), idsNotInSections);
29
+ if (R.isEmpty(idsNotInRows)) {
30
+ return acc;
31
+ }
32
+ }
33
+ return R.assoc(attr.id, attr.id, acc);
34
+ },
35
+ {},
36
+ attributes,
37
+ );
38
+ };
@@ -0,0 +1,38 @@
1
+ import * as R from 'ramda';
2
+ import { parseValueHierarchy } from './parseValueHierarchy';
3
+
4
+ export const getCombinationDimensionsData = (indexes, combination, previous, sameSerie) => {
5
+ let coordinates = {};
6
+ let ids = [];
7
+ let _sameSerie = sameSerie;
8
+ let hasAdvancedAttributes = false;
9
+
10
+ const { dimensions=[] } = combination;
11
+ const dimValues = R.addIndex(R.reduce)(
12
+ (acc, valIndex, dimIndex) => {
13
+ const dimension = R.nth(dimIndex, dimensions);
14
+ const value = R.nth(Math.abs(valIndex), R.propOr([], 'values', dimension));
15
+ hasAdvancedAttributes = !hasAdvancedAttributes ? value.hasAdvancedAttributes : true;
16
+ if (!value) {
17
+ return acc;
18
+ }
19
+ coordinates = R.assoc(dimension.id, value.id, coordinates);
20
+ ids = R.append(`${dimension.id}=${value.id}`, ids);
21
+ const previousValue = R.propOr({}, dimension.id, previous);
22
+ if (value.id === R.prop('id', previousValue || {}) && _sameSerie) {
23
+ return R.assoc(dimension.id, previousValue, acc);
24
+ }
25
+ else {
26
+ const parsedValue = parseValueHierarchy(value, _sameSerie ? previousValue || {} : {}, dimension.indexedValues);
27
+ if (!R.isNil(previous)) {
28
+ _sameSerie = false;
29
+ }
30
+ return R.assoc(dimension.id, parsedValue, acc);
31
+ }
32
+ },
33
+ {},
34
+ indexes
35
+ );
36
+
37
+ return ({ dimValues, coordinates, ids, sameSerie: _sameSerie, hasAdvancedAttributes });
38
+ };
@@ -0,0 +1,33 @@
1
+ import * as R from 'ramda';
2
+
3
+ export const getCuratedCells = (cells, layout) => {
4
+ const layoutIds = R.map(
5
+ R.pipe(
6
+ R.map(entry =>
7
+ R.has('dimensions', entry) ? R.pluck('id', entry.dimensions || []) : entry.id,
8
+ ),
9
+ R.unnest,
10
+ ),
11
+ )(layout);
12
+ return R.pipe(
13
+ R.values,
14
+ R.reduce((acc, cell) => {
15
+ const keys = R.map(
16
+ R.pipe(
17
+ R.map(dim => {
18
+ const val = R.prop(dim, cell.indexedDimValIds);
19
+ return `${dim}=${val}`;
20
+ }),
21
+ R.join(':'),
22
+ ),
23
+ layoutIds,
24
+ );
25
+
26
+ return R.over(
27
+ R.lensPath(R.props(['header', 'sections', 'rows'], keys)),
28
+ cells => (R.isNil(cells) ? [cell] : R.append(cell, cells)),
29
+ acc,
30
+ );
31
+ }, {}),
32
+ )(cells);
33
+ };
@@ -0,0 +1,21 @@
1
+ import * as R from 'ramda';
2
+
3
+ export const getFlagsAndNotes = (attributesValues, customAttributes) => {
4
+ const flagsIds = R.propOr([], 'flags', customAttributes);
5
+ const notesIds = R.propOr([], 'notes', customAttributes);
6
+
7
+ return R.addIndex(R.reduce)(
8
+ (acc, id, index) => {
9
+ if (!R.has(id, attributesValues)) {
10
+ return acc;
11
+ }
12
+ const attr = R.prop(id, attributesValues);
13
+ if (R.isNil(attr.value)) {
14
+ return acc;
15
+ }
16
+ return R.append(index < flagsIds.length ? R.assoc('code', R.path(['value', 'id'], attr), attr) : attr, acc);
17
+ },
18
+ [],
19
+ R.concat(flagsIds, notesIds)
20
+ );
21
+ };
@@ -0,0 +1,16 @@
1
+ import * as R from 'ramda';
2
+
3
+ export const getIndexedCombinationsByDisplay = (layout, combinations) => {
4
+ const layoutIds = R.pipe(
5
+ R.map(R.pluck('id')),
6
+ R.values,
7
+ R.unnest,
8
+ R.indexBy(R.identity),
9
+ )(layout);
10
+
11
+ const [combsInLayout, combsInCells] = R.partition(
12
+ comb => R.has(comb.id, layoutIds),
13
+ combinations,
14
+ );
15
+ return { cells: combsInCells, layout: combsInLayout };
16
+ };
@@ -0,0 +1,80 @@
1
+ import * as R from 'ramda';
2
+ import { isTimePeriodDimension } from '@sis-cc/dotstatsuite-sdmxjs';
3
+ import { trimedProps } from '../utils';
4
+
5
+ export const getLayout = (layoutIds, dimensions, combinations, isTimeInverted, fixedDimensions) => {
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 indexedFixedDimsValues = R.reduce(
11
+ (acc, dim) => {
12
+ const value = R.head(dim.values);
13
+ return !dim.display || !value.display ? acc : R.assoc(dim.id, R.head(dim.values), acc);
14
+ },
15
+ {},
16
+ fixedDimensions,
17
+ );
18
+ const indexedHeaderIds = R.indexBy(R.identity, layoutIds.header);
19
+ const indexedSectionsIds = R.indexBy(R.identity, layoutIds.sections);
20
+ const indexedRowsIds = { ...indexedSectionsIds, ...R.indexBy(R.identity, layoutIds.rows) };
21
+ let layout = { header: [], sections: [], rows: [] };
22
+ R.forEach(comb => {
23
+ if (R.isEmpty(comb.relationship)) {
24
+ return;
25
+ }
26
+ const [idsInHeader, rest] = R.partition(id => R.has(id, indexedHeaderIds), comb.relationship);
27
+ if (R.isEmpty(rest)) {
28
+ layout = R.over(
29
+ R.lensProp('header'),
30
+ R.append({
31
+ ...comb,
32
+ dimensions: trimedProps(comb.concepts, indexedDimensions),
33
+ fixedDimValues: R.pick(comb.concepts, indexedFixedDimsValues),
34
+ }),
35
+ )(layout);
36
+ } else if (!R.isEmpty(idsInHeader)) {
37
+ return;
38
+ } else {
39
+ const idsNotInSections = R.reject(id => R.has(id, indexedSectionsIds), comb.relationship);
40
+ if (R.isEmpty(idsNotInSections)) {
41
+ layout = R.over(
42
+ R.lensProp('sections'),
43
+ R.append({
44
+ ...comb,
45
+ dimensions: trimedProps(comb.concepts, indexedDimensions),
46
+ fixedDimValues: R.pick(comb.concepts, indexedFixedDimsValues),
47
+ }),
48
+ )(layout);
49
+ } else {
50
+ const idsNotInRows = R.reject(id => R.has(id, indexedRowsIds), comb.relationship);
51
+ if (R.isEmpty(idsNotInRows)) {
52
+ layout = R.over(
53
+ R.lensProp('rows'),
54
+ R.append({
55
+ ...comb,
56
+ dimensions: R.pipe(R.omit(layoutIds.sections), o => trimedProps(comb.concepts, o))(
57
+ indexedDimensions,
58
+ ),
59
+ fixedDimValues: R.pick(comb.concepts, indexedFixedDimsValues),
60
+ }),
61
+ )(layout);
62
+ }
63
+ }
64
+ }
65
+ }, combinations);
66
+ return R.mapObjIndexed((combs, key) => {
67
+ const conceptIds = R.pipe(R.pluck('concepts'), R.unnest, R.indexBy(R.identity))(combs);
68
+ const rest = R.reduce(
69
+ (acc, id) => {
70
+ if (R.has(id, conceptIds)) {
71
+ return acc;
72
+ }
73
+ return R.append(R.prop(id, indexedDimensions), acc);
74
+ },
75
+ [],
76
+ layoutIds[key],
77
+ );
78
+ return R.concat(rest, combs);
79
+ }, layout);
80
+ };
@@ -0,0 +1,183 @@
1
+ import * as R from 'ramda';
2
+ import { getFlagsAndNotes } from './getFlagsAndNotes';
3
+ import { hasCellMetadata } from '../hasCellMetadata';
4
+ import { getCombinationDimensionsData } from './getCombinationDimensionsData';
5
+ import { parseValueHierarchy } from './parseValueHierarchy';
6
+
7
+ const getSubLayoutData = (series, _definition, { metadataCoordinates, attributesSeries, customAttributes }) => {
8
+ const getHasAdvancedAttributes = (attrValues) => R.pipe(
9
+ R.omit(R.concat(customAttributes.flags, customAttributes.notes)),
10
+ R.isEmpty,
11
+ R.not
12
+ )(attrValues);
13
+
14
+ const combinationConceptIds = R.reduce(
15
+ (acc, def) => {
16
+ const concepts = R.propOr([], 'concepts', def);
17
+ if (R.isEmpty(concepts)) {
18
+ return acc;
19
+ }
20
+ return R.concat(acc, concepts);
21
+ },
22
+ [],
23
+ _definition
24
+ );
25
+
26
+ const definition = R.map( //used for parseValueHierarchy ...
27
+ (entry) => {
28
+ if (R.has('dimensions', entry)) {
29
+ return ({
30
+ ...entry,
31
+ dimensions: R.map(
32
+ dim => R.assoc('indexedValues', R.indexBy(R.prop('id'), dim.values || []), dim),
33
+ entry.dimensions
34
+ )
35
+ });
36
+ }
37
+ return R.assoc('indexedValues', R.indexBy(R.prop('id'), entry.values || []), entry);
38
+ },
39
+ _definition
40
+ );
41
+
42
+ const { res } = R.reduce(
43
+ (acc, serie) => {
44
+ let data = [];
45
+ let next = [];
46
+ let sameSerie = true;
47
+ let i = 0;
48
+ let hasAdvancedAttributes = false;
49
+ let coordinates = {};
50
+ let ids = [];
51
+ while (i < serie.length) {
52
+ const entry = serie[i];
53
+ if (R.is(Array, entry)) {
54
+ const combination = definition[i];
55
+ const previousDimValues = R.nth(i, acc.previous);
56
+ const combData = getCombinationDimensionsData(entry, combination, previousDimValues, sameSerie);
57
+ data = R.append({
58
+ dimension: R.pick(['id', 'name'], combination),
59
+ dimValues: combData.dimValues
60
+ }, data);
61
+ next = R.append(combData.dimValues, next);
62
+ hasAdvancedAttributes = !hasAdvancedAttributes ? combData.hasAdvancedAttributes : true;
63
+ sameSerie = combData.sameSerie;
64
+ coordinates = { ...coordinates, ...combData.coordinates };
65
+ ids = R.concat(ids, combData.ids);
66
+ }
67
+ else {
68
+ const dimension = definition[i];
69
+ const value = R.nth(Math.abs(entry), dimension.values || []);
70
+ const previousValue = R.nth(i, acc.previous) || {};
71
+ coordinates = R.assoc(dimension.id, value.id, coordinates);
72
+ ids = R.append(`${dimension.id}=${value.id}`, ids);
73
+ if (value.id === R.prop('id', previousValue || {}) && sameSerie) {
74
+ next = R.append(previousValue, next);
75
+ data = R.append({
76
+ dimension: R.pick(['id', 'name', '__index'], dimension),
77
+ value: previousValue,
78
+ }, data);
79
+ }
80
+ else {
81
+ hasAdvancedAttributes = !hasAdvancedAttributes ? value.hasAdvancedAttributes : true;
82
+ const parsedValue = parseValueHierarchy(value, sameSerie ? previousValue || {} : {}, dimension.indexedValues);
83
+ next = R.append(parsedValue, next);
84
+ data = R.append({
85
+ dimension: R.pick(['id', 'name', '__index'], dimension),
86
+ value: parsedValue,
87
+ }, data);
88
+ if (!R.isNil(acc.previous)) {
89
+ sameSerie = false;
90
+ }
91
+ }
92
+ }
93
+ i++;
94
+ }
95
+
96
+ const attributesValues = R.reduce(
97
+ (acc, key) => {
98
+ const splitKey = R.split(':', key);
99
+ const isValid = R.all(entry => {
100
+ const [d, v] = R.split('=', entry);
101
+ return R.propEq(d, v, coordinates);
102
+ }, splitKey);
103
+ return isValid ? { ...acc, ...(R.length(splitKey) === 1 ? R.pick(combinationConceptIds, R.prop(key, attributesSeries)) : R.prop(key, attributesSeries)) } : acc;
104
+ },
105
+ {},
106
+ R.keys(attributesSeries)
107
+ );
108
+
109
+ data = R.addIndex(R.map)(
110
+ (entry, ind) => {
111
+ if (!R.has('dimValues', entry)) {
112
+ return entry;
113
+ }
114
+ const { dimValues, dimension } = entry;
115
+ const def = R.nth(ind, definition);
116
+ const fixedDimValues = R.propOr([], 'fixedDimValues', def);
117
+ const values = R.reduce(
118
+ (_acc, id) => {
119
+ if (R.has(id, dimValues)) {
120
+ return R.append(R.prop(id, dimValues), _acc);
121
+ }
122
+ if (R.has(id, fixedDimValues)) {
123
+ return R.append(R.prop(id, fixedDimValues), _acc);
124
+ }
125
+ if (!R.has(id, attributesValues)) {
126
+ return _acc;
127
+ }
128
+ return R.append(R.path([id, 'value'], attributesValues), _acc);
129
+ },
130
+ [],
131
+ def.concepts
132
+ );
133
+ return ({ dimension, values });
134
+ },
135
+ data
136
+ );
137
+
138
+ const layoutAttrValues = R.pipe(
139
+ R.omit(combinationConceptIds),
140
+ R.reject(R.prop('isObs'))
141
+ )(attributesValues);
142
+
143
+ const flags = getFlagsAndNotes(layoutAttrValues, customAttributes);
144
+ const hasMetadata = hasCellMetadata(metadataCoordinates, coordinates);
145
+
146
+ if (!hasAdvancedAttributes) {
147
+ hasAdvancedAttributes = getHasAdvancedAttributes(layoutAttrValues);
148
+ }
149
+
150
+ const sideProps = hasMetadata || hasAdvancedAttributes
151
+ ? { hasMetadata, hasAdvancedAttributes, coordinates } : null;
152
+
153
+ return {
154
+ res: R.append({ data, key: R.join(':', ids), flags, sideProps }, acc.res),
155
+ previous: next,
156
+ };
157
+ },
158
+ { res: [], previous: [] },
159
+ series
160
+ );
161
+
162
+ return res;
163
+ };
164
+
165
+ export const getLayoutData = (layoutIndexes, layout, { metadataCoordinates, attributesSeries, customAttributes }) => {
166
+ const { header, sections, ...rest } = layoutIndexes;
167
+ const opts = { metadataCoordinates, attributesSeries, customAttributes };
168
+ const headerData = getSubLayoutData(header, layout.header, opts);
169
+ const sectionsData = R.pipe(
170
+ R.transpose,
171
+ ([sections, sectionsRows]) => {
172
+ if (R.isNil(sections)) {
173
+ return [];
174
+ }
175
+ const _sectionsData = getSubLayoutData(sections, layout.sections, opts);
176
+ const rowsData = R.map(rows => getSubLayoutData(rows, layout.rows, opts), sectionsRows);
177
+
178
+ return R.transpose([_sectionsData, rowsData]);
179
+ }
180
+ )(sections);
181
+
182
+ return ({ headerData, sectionsData, ...rest });
183
+ };
@@ -0,0 +1,119 @@
1
+ import * as R from 'ramda';
2
+
3
+ /*
4
+ const layout = {
5
+ header: [
6
+ { id, __index },
7
+ { id: COMB, dimensions: [{ id, __index }] }
8
+ ],
9
+ sections: [],
10
+ rows: []
11
+ }
12
+
13
+ */
14
+
15
+ const getLayoutPivots = layoutEntry => {
16
+ const valIndexGetter = d => R.pipe(
17
+ R.nth(R.prop('__index', d)),
18
+ ind => d.isInverted ? R.negate(ind) : ind
19
+ );
20
+ return indexes => R.map(
21
+ R.ifElse(
22
+ R.has('dimensions'),
23
+ c => R.map(d => valIndexGetter(d)(indexes), R.prop('dimensions', c)),
24
+ d => valIndexGetter(d)(indexes)
25
+ ),
26
+ layoutEntry
27
+ );
28
+ };
29
+
30
+ const comparator = (a, b) => {
31
+ const size = R.length(a);
32
+ let i = 0;
33
+ while (i < size) {
34
+ if (R.is(Array, a[i])) {
35
+ const _a = a[i];
36
+ const _b = b[i];
37
+ const _size = R.length(_a);
38
+ let j = 0;
39
+ while (_a[j] === _b[j] && j < _size) {
40
+ j++;
41
+ }
42
+ if (_a[j] !== _b[j]) {
43
+ return _a[j] - _b[j];
44
+ }
45
+ }
46
+ else if (a[i] !== b[i]) {
47
+ return a[i] - b[i];
48
+ }
49
+ i++;
50
+ }
51
+ return a[i] - b[i];
52
+ };
53
+
54
+ // simple call to ramda uniq method is very slow regarding performance
55
+ const uniqIndexes = (indexes) => R.pipe(
56
+ R.reduce(
57
+ (acc, i) => {
58
+ const key = R.join(':', R.unnest(i));
59
+ if (R.has(key, acc.keys)) {
60
+ return acc;
61
+ }
62
+ return ({
63
+ indexes: R.append(i, acc.indexes),
64
+ keys: R.assoc(key, key, acc.keys)
65
+ });
66
+ },
67
+ { indexes: [], keys: {} },
68
+ ),
69
+ R.prop('indexes')
70
+ )(indexes);
71
+
72
+ export const getSortedLayoutIndexes = (layout, observations) => {
73
+ const dimIndexes = R.pipe(R.values, R.map(R.propOr([], 'orderedDimIndexes')))(observations);
74
+
75
+ const headerPivots = getLayoutPivots(layout.header);
76
+ const sectionsPivots = getLayoutPivots(R.concat(layout.sections, layout.rows));
77
+
78
+ const sectionLength = R.length(layout.sections);
79
+ const { header, sections } = R.pipe(
80
+ R.reduce(
81
+ (acc, indexes) => {
82
+ const headerIndexes = headerPivots(indexes);
83
+ const sectionsIndexes = sectionsPivots(indexes);
84
+
85
+ return ({
86
+ header: R.append(headerIndexes, acc.header),
87
+ sections: R.append(sectionsIndexes, acc.sections)
88
+ });
89
+ },
90
+ { header: [], sections: [] },
91
+ ),
92
+ R.mapObjIndexed(uniqIndexes),
93
+ R.evolve({
94
+ header: R.sort(comparator),
95
+ sections: R.sort(comparator)
96
+ }),
97
+ indexes => ({
98
+ ...indexes,
99
+ sections: R.reduce(
100
+ (acc, i) => {
101
+ const [sectionIndexes, rowIndexes] = R.splitAt(sectionLength, i);
102
+ const previousSecIndexes = R.pipe(R.nth(-1), i => R.isNil(i) ? null : R.head(i))(acc);
103
+ if (R.equals(R.unnest(sectionIndexes), previousSecIndexes ? R.unnest(previousSecIndexes) : null)) { //perhaps a bit dirty ...
104
+ return R.over(
105
+ R.lensIndex(-1),
106
+ R.over(R.lensIndex(1), R.append(rowIndexes))
107
+ )(acc);
108
+ }
109
+
110
+ return R.append([sectionIndexes, [rowIndexes]], acc);
111
+ },
112
+ [],
113
+ indexes.sections
114
+ )
115
+ })
116
+ )(dimIndexes);
117
+
118
+ return ({ header, sections });
119
+ };
@@ -0,0 +1,36 @@
1
+ import * as R from 'ramda';
2
+ import { getLayout } from './getLayout';
3
+ import { getSortedLayoutIndexes } from './getSortedLayoutIndexes';
4
+ import { refineLayoutSize } from './refineLayoutSize';
5
+ import { getLayoutData } from './getLayoutData';
6
+ import { getCellsAttributesIds } from './getCellsAttributesIds';
7
+ import { getIndexedCombinationsByDisplay } from './getIndexedCombinationsByDisplay';
8
+ import { getCells } from './getCells';
9
+ import { getCuratedCells } from './getCuratedCells';
10
+
11
+ export const getTableProps = ({ data, layoutIds, customAttributes, limit, isTimeInverted }) => {
12
+ const {
13
+ observations,
14
+ dimensions,
15
+ combinations,
16
+ oneValueDimensions,
17
+ attributesSeries,
18
+ metadataCoordinates,
19
+ attributes
20
+ } = data;
21
+
22
+ const seriesCombinations = R.filter(R.prop('series'), combinations);
23
+ const layout = getLayout(layoutIds, dimensions, seriesCombinations, isTimeInverted, oneValueDimensions);
24
+ const layoutIndexes = getSortedLayoutIndexes(layout, observations);
25
+ const refinedLayoutIndexes = refineLayoutSize({ layout, observations, limit })(layoutIndexes);
26
+ const layoutData = getLayoutData(refinedLayoutIndexes, layout, { metadataCoordinates, attributesSeries, customAttributes });
27
+
28
+ const cellsAttributesIds = getCellsAttributesIds(layoutIds, attributes);
29
+ const indexedCombinations = getIndexedCombinationsByDisplay(layout, seriesCombinations);
30
+ const cells = getCells(customAttributes, cellsAttributesIds, indexedCombinations, attributesSeries, metadataCoordinates)(observations);
31
+
32
+ return ({
33
+ ...layoutData,
34
+ cells: getCuratedCells(cells, layout)
35
+ });
36
+ };
@@ -0,0 +1,27 @@
1
+ import * as R from 'ramda';
2
+
3
+ export const parseValueHierarchy = (value, previousValue, indexedValues) => {
4
+ const parentsIds = R.propOr([], 'parents', value);
5
+ if (R.isEmpty(parentsIds)) {
6
+ return value;
7
+ }
8
+ const _previousParentsIds = R.propOr([], 'parentsIds', previousValue);
9
+ const previousParentsIds = R.isNil(previousValue) ? [] : R.append(R.prop('id', previousValue), _previousParentsIds);
10
+ const [presentIds, missingIds] = R.addIndex(R.splitWhen)((val, ind) => R.nth(ind, previousParentsIds) !== val, parentsIds);
11
+ //console.log({ presentIds, missingIds });
12
+ const _previousParents = R.propOr([], 'parents', previousValue);
13
+ const previousParents = R.isNil(previousValue) ? [] : R.append(R.pick(['id', 'name'], previousValue), _previousParents);
14
+ //console.log('previousParents', previousParents);
15
+ const parents = R.takeWhile(p => R.includes(p.id, presentIds), previousParents);
16
+ const missingParents = R.concat(
17
+ R.includes(R.prop('id', previousValue), presentIds)
18
+ ? [] : R.takeWhile(p => R.includes(p.id, presentIds), R.propOr([], 'missingParents', previousValue)),
19
+ R.props(missingIds, indexedValues)
20
+ );
21
+ return ({
22
+ ...value,
23
+ parents,
24
+ parentsIds,
25
+ missingParents
26
+ });
27
+ };