@sis-cc/dotstatsuite-components 16.1.0 → 16.1.2
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/lib/rules/src/v8-transformer.js +2 -2
- package/lib/rules2/src/constants.js +2 -1
- package/lib/rules2/src/enhanceObservations.js +5 -4
- package/lib/rules2/src/getAttributesSeries.js +7 -0
- package/lib/rules2/src/getCombinationDefinitions.js +15 -11
- package/lib/rules2/src/getDataflowAttributes.js +34 -0
- package/lib/rules2/src/getHeaderTitle.js +29 -0
- package/lib/rules2/src/getOneValueDimensions.js +3 -1
- package/lib/rules2/src/getSidebarData.js +8 -17
- package/lib/rules2/src/index.js +27 -0
- package/lib/rules2/src/parseCombinations.js +4 -2
- package/lib/rules2/src/prepareData.js +33 -2
- package/lib/rules2/src/table/getCells.js +4 -2
- package/lib/rules2/src/table/getCellsMetadataCoordinates.js +30 -0
- package/lib/rules2/src/table/getCombinationDimensionsData.js +5 -4
- package/lib/rules2/src/table/getLayoutData.js +15 -6
- package/lib/rules2/src/table/parseValueHierarchy.js +9 -8
- package/package.json +1 -1
- package/src/rules/src/v8-transformer.js +2 -2
- package/src/rules2/src/constants.js +1 -0
- package/src/rules2/src/enhanceObservations.js +4 -4
- package/src/rules2/src/getAttributesSeries.js +7 -0
- package/src/rules2/src/getCombinationDefinitions.js +20 -18
- package/src/rules2/src/getDataflowAttributes.js +23 -0
- package/src/rules2/src/getHeaderTitle.js +15 -0
- package/src/rules2/src/getOneValueDimensions.js +2 -1
- package/src/rules2/src/getSidebarData.js +4 -12
- package/src/rules2/src/index.js +3 -0
- package/src/rules2/src/parseCombinations.js +5 -2
- package/src/rules2/src/prepareData.js +22 -4
- package/src/rules2/src/table/getCells.js +4 -2
- package/src/rules2/src/table/getCellsMetadataCoordinates.js +13 -0
- package/src/rules2/src/table/getCombinationDimensionsData.js +5 -4
- package/src/rules2/src/table/getLayoutData.js +13 -5
- package/src/rules2/src/table/parseValueHierarchy.js +7 -8
- package/test/getAttributesSeries.test.js +2 -0
- package/test/getCells.test.js +1 -0
- package/test/getCellsMetadataCoordinates.test.js +40 -0
- package/test/getCombinationDimensionsData.test.js +7 -2
- package/test/getDataflowAttributes.test.js +23 -0
- package/test/getHeaderTitle.test.js +25 -0
- package/test/getLayoutData.test.js +130 -0
- package/test/parseCombinations.test.js +36 -0
- package/test/parseValueHierarchy.test.js +54 -4
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
import * as R from 'ramda';
|
|
2
2
|
|
|
3
|
+
export const parseCombinationDefinition = (title, texts) => R.useWith(
|
|
4
|
+
(titles, texts) =>
|
|
5
|
+
R.addIndex(R.map)((title, index) => {
|
|
6
|
+
const split = R.split(':', title);
|
|
7
|
+
if (R.length(split !== 2)) {
|
|
8
|
+
return null;
|
|
9
|
+
}
|
|
10
|
+
const [id, codes] = split;
|
|
11
|
+
return {
|
|
12
|
+
id,
|
|
13
|
+
concepts: R.split(',', codes),
|
|
14
|
+
name: R.has(locale, texts)
|
|
15
|
+
? R.pipe(R.prop(locale), R.nth(index), R.split(':'), R.last)(texts)
|
|
16
|
+
: `[${id}]`,
|
|
17
|
+
};
|
|
18
|
+
}, titles),
|
|
19
|
+
[R.split(';'), R.map(R.split(';'))],
|
|
20
|
+
)(title, texts);
|
|
21
|
+
|
|
3
22
|
export const getCombinationDefinitions = (annotations, locale) => {
|
|
4
23
|
const annotation = R.find(annot => annot.type === 'COMBINED_CONCEPTS', annotations);
|
|
5
24
|
if (R.isNil(annotation)) {
|
|
@@ -8,22 +27,5 @@ export const getCombinationDefinitions = (annotations, locale) => {
|
|
|
8
27
|
const title = R.propOr('', 'title', annotation);
|
|
9
28
|
const texts = R.propOr({}, 'texts', annotation);
|
|
10
29
|
|
|
11
|
-
return
|
|
12
|
-
(titles, texts) =>
|
|
13
|
-
R.addIndex(R.map)((title, index) => {
|
|
14
|
-
const split = R.split(':', title);
|
|
15
|
-
if (R.length(split !== 2)) {
|
|
16
|
-
return null;
|
|
17
|
-
}
|
|
18
|
-
const [id, codes] = split;
|
|
19
|
-
return {
|
|
20
|
-
id,
|
|
21
|
-
concepts: R.split(',', codes),
|
|
22
|
-
name: R.has(locale, texts)
|
|
23
|
-
? R.pipe(R.prop(locale), R.nth(index), R.split(':'), R.last)(texts)
|
|
24
|
-
: `[${id}]`,
|
|
25
|
-
};
|
|
26
|
-
}, titles),
|
|
27
|
-
[R.split(';'), R.map(R.split(';'))],
|
|
28
|
-
)(title, texts);
|
|
30
|
+
return parseCombinationDefinition(title, texts);
|
|
29
31
|
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import * as R from 'ramda';
|
|
2
|
+
import { REJECTED_VALUE_IDS } from './constants';
|
|
3
|
+
|
|
4
|
+
export const getDataflowAttributes = (attributes, combinations) => {
|
|
5
|
+
const combinationsConceptsIds = R.pipe(R.pluck('concepts'), R.unnest)(combinations);
|
|
6
|
+
return R.reduce(
|
|
7
|
+
(acc, attribute) => {
|
|
8
|
+
if (!R.prop('header', attribute) || !R.isEmpty(attribute.relationship)
|
|
9
|
+
|| R.includes(attribute.id, combinationsConceptsIds)) {
|
|
10
|
+
return acc;
|
|
11
|
+
}
|
|
12
|
+
const value = R.head(attribute.values);
|
|
13
|
+
if (!R.propOr(true, 'display', attribute) || R.isNil(value)
|
|
14
|
+
|| !R.propOr(true, 'display', value) || R.includes(R.prop('id', value), REJECTED_VALUE_IDS)) {
|
|
15
|
+
return acc;
|
|
16
|
+
}
|
|
17
|
+
return R.assoc(attribute.id, { ...R.pick(['id', 'name'], attribute), value }, acc);
|
|
18
|
+
},
|
|
19
|
+
{},
|
|
20
|
+
attributes,
|
|
21
|
+
);
|
|
22
|
+
};
|
|
23
|
+
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import * as R from 'ramda';
|
|
2
|
+
import { dimensionValueDisplay } from '../../rules/src';
|
|
3
|
+
import { getFlagsAndNotes } from './table/getFlagsAndNotes';
|
|
4
|
+
|
|
5
|
+
export const getHeaderTitle = (dataflow, attributes, display, customAttributes) => ({
|
|
6
|
+
label: dimensionValueDisplay(display)(dataflow),
|
|
7
|
+
flags: R.pipe(
|
|
8
|
+
getFlagsAndNotes,
|
|
9
|
+
R.map(entry => ({
|
|
10
|
+
code: entry.code,
|
|
11
|
+
header: `${dimensionValueDisplay(display)(entry)}:`,
|
|
12
|
+
label: dimensionValueDisplay(display)(entry.value),
|
|
13
|
+
})),
|
|
14
|
+
)(attributes, customAttributes),
|
|
15
|
+
});
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as R from 'ramda';
|
|
2
|
+
import { REJECTED_VALUE_IDS } from './constants';
|
|
2
3
|
|
|
3
4
|
export const getOneValueDimensions = (dimensions, attributes) => {
|
|
4
5
|
const indexedRelevantAttributes = R.reduce(
|
|
@@ -7,7 +8,7 @@ export const getOneValueDimensions = (dimensions, attributes) => {
|
|
|
7
8
|
return acc;
|
|
8
9
|
}
|
|
9
10
|
const value = R.path(['values', 0], attr);
|
|
10
|
-
if (R.isNil(value) || !R.prop('display', value)) {
|
|
11
|
+
if (R.isNil(value) || !R.prop('display', value) || R.includes(R.prop('id', value), REJECTED_VALUE_IDS)) {
|
|
11
12
|
return acc;
|
|
12
13
|
}
|
|
13
14
|
const dim = R.head(attr.relationship);
|
|
@@ -1,15 +1,6 @@
|
|
|
1
1
|
import * as R from 'ramda';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const name = R.isNil(data.name) ? `[${data.id}]` : data.name;
|
|
5
|
-
if (display === 'code') {
|
|
6
|
-
return R.prop('id', data);
|
|
7
|
-
}
|
|
8
|
-
if (display === 'both') {
|
|
9
|
-
return `${R.prop('id', data)}: ${name}`;
|
|
10
|
-
}
|
|
11
|
-
return name;
|
|
12
|
-
};
|
|
2
|
+
import { dimensionValueDisplay } from '../../rules/src';
|
|
3
|
+
import { REJECTED_VALUE_IDS } from './constants';
|
|
13
4
|
|
|
14
5
|
const sortByCoordinates = (a, b) => {
|
|
15
6
|
const splitACoord = a.splitCoord;
|
|
@@ -50,7 +41,8 @@ export const getSidebarData = (attributesSeries, metadataSeries, dataflow, dimen
|
|
|
50
41
|
const dim = R.nth(dimIndex, dimensions);
|
|
51
42
|
const values = R.propOr([], 'values', dim || {});
|
|
52
43
|
const value = R.nth(Number(valIndex), values);
|
|
53
|
-
if (!value || !R.propOr(true, 'display', dim) || !R.propOr(true, 'display', value)
|
|
44
|
+
if (!value || !R.propOr(true, 'display', dim) || !R.propOr(true, 'display', value)
|
|
45
|
+
|| R.includes(R.prop('id', value), REJECTED_VALUE_IDS)) {
|
|
54
46
|
return ({ ...acc, split: R.append('', acc.split) });
|
|
55
47
|
}
|
|
56
48
|
const dimLabel = dimensionValueDisplay(options.display)(dim);
|
package/src/rules2/src/index.js
CHANGED
|
@@ -25,6 +25,8 @@ export { enhanceObservations } from './enhanceObservations';
|
|
|
25
25
|
export { getAttributesSeries } from './getAttributesSeries';
|
|
26
26
|
export { getManyValuesDimensions } from './getManyValuesDimensions';
|
|
27
27
|
export { getOneValueDimensions } from './getOneValueDimensions';
|
|
28
|
+
export { getDataflowAttributes } from './getDataflowAttributes';
|
|
29
|
+
export { getHeaderTitle } from './getHeaderTitle';
|
|
28
30
|
export { getHeaderSubtitle } from './getHeaderSubtitle';
|
|
29
31
|
export { getHeaderCombinations } from './getHeaderCombinations';
|
|
30
32
|
export { getLayout } from './table/getLayout';
|
|
@@ -33,6 +35,7 @@ export { refineLayoutSize } from './table/refineLayoutSize';
|
|
|
33
35
|
export { getFlagsAndNotes } from './table/getFlagsAndNotes';
|
|
34
36
|
export { getLayoutData } from './table/getLayoutData';
|
|
35
37
|
export { getCellsAttributesIds } from './table/getCellsAttributesIds';
|
|
38
|
+
export { getCellsMetadataCoordinates } from './table/getCellsMetadataCoordinates';
|
|
36
39
|
export { getIndexedCombinationsByDisplay } from './table/getIndexedCombinationsByDisplay';
|
|
37
40
|
export { getCells } from './table/getCells';
|
|
38
41
|
export { getCuratedCells } from './table/getCuratedCells';
|
|
@@ -17,6 +17,9 @@ export const parseCombinations = (combinations, parsedAttributes, dimensions) =>
|
|
|
17
17
|
ids = { ...ids, [concept]: concept };
|
|
18
18
|
return R.length(values) > 1;
|
|
19
19
|
}
|
|
20
|
+
else if (!R.has(concept, indexedAttributes)) {
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
20
23
|
const attribute = R.prop(concept, indexedAttributes);
|
|
21
24
|
relationship = attribute.series
|
|
22
25
|
? R.pipe(
|
|
@@ -25,10 +28,10 @@ export const parseCombinations = (combinations, parsedAttributes, dimensions) =>
|
|
|
25
28
|
)(attribute.relationship)
|
|
26
29
|
: relationship;
|
|
27
30
|
ids = attribute.series ? { ...ids, ...R.indexBy(R.identity, attribute.relationship) } : ids;
|
|
28
|
-
return
|
|
31
|
+
return attribute.series;
|
|
29
32
|
}, comb.concepts);
|
|
30
33
|
|
|
31
|
-
if (R.isEmpty(seriesConcepts)
|
|
34
|
+
if (R.isEmpty(seriesConcepts)) {
|
|
32
35
|
return { ...comb, header: true };
|
|
33
36
|
}
|
|
34
37
|
return { ...comb, series: true, relationship };
|
|
@@ -2,7 +2,7 @@ import * as R from 'ramda';
|
|
|
2
2
|
import { getObservations } from '../../rules/src';
|
|
3
3
|
import { enhanceObservations } from './enhanceObservations';
|
|
4
4
|
import { parseAttributes } from './parseAttributes';
|
|
5
|
-
import { getCombinationDefinitions } from './getCombinationDefinitions';
|
|
5
|
+
import { getCombinationDefinitions, parseCombinationDefinition } from './getCombinationDefinitions';
|
|
6
6
|
import { parseCombinations } from './parseCombinations';
|
|
7
7
|
import { refineAttributes } from './refineAttributes';
|
|
8
8
|
import { duplicateObs } from './duplicateObservations';
|
|
@@ -12,13 +12,21 @@ import { getManyValuesDimensions } from './getManyValuesDimensions';
|
|
|
12
12
|
import { getOneValueDimensions } from './getOneValueDimensions';
|
|
13
13
|
import { hierarchiseDimensionWithNativeHierarchy } from './hierarchiseDimensionWithNativeHierarchy';
|
|
14
14
|
import { hierarchiseDimensionWithAdvancedHierarchy } from './hierarchiseDimensionWithAdvancedHierarchy';
|
|
15
|
+
import { getDataflowAttributes } from './getDataflowAttributes';
|
|
16
|
+
import { getHeaderTitle } from './getHeaderTitle';
|
|
17
|
+
import { getHeaderSubtitle } from './getHeaderSubtitle';
|
|
18
|
+
import { getHeaderCombinations } from './getHeaderCombinations';
|
|
15
19
|
|
|
16
|
-
export const prepareData = (sdmxJson, customAttributes, locale, hierarchies) => {
|
|
20
|
+
export const prepareData = (sdmxJson, { customAttributes, locale, hierarchies, dataflow, display, defaultCombinations }) => {
|
|
17
21
|
const dimensions = R.pathOr([], ['data', 'structure', 'dimensions', 'observation'], sdmxJson);
|
|
18
22
|
const attributes = R.pathOr([], ['data', 'structure', 'attributes', 'observation'], sdmxJson);
|
|
19
23
|
const annotations = R.pathOr([], ['data', 'structure', 'annotations'], sdmxJson);
|
|
20
24
|
const observations = getObservations(sdmxJson);
|
|
21
|
-
|
|
25
|
+
let combinations = getCombinationDefinitions(annotations, locale);
|
|
26
|
+
if (R.isEmpty(combinations) && !R.isEmpty(defaultCombinations)) {
|
|
27
|
+
const { concepts, names } = defaultCombinations;
|
|
28
|
+
combinations = parseCombinationDefinition(concepts, names);
|
|
29
|
+
}
|
|
22
30
|
const metadataCoordinates = getMetadataCoordinates(sdmxJson);
|
|
23
31
|
|
|
24
32
|
const parsedAttributes = parseAttributes(attributes, dimensions, customAttributes);
|
|
@@ -37,6 +45,11 @@ export const prepareData = (sdmxJson, customAttributes, locale, hierarchies) =>
|
|
|
37
45
|
return hierarchiseDimensionWithAdvancedHierarchy(dim, R.prop(dim.id, hierarchies));
|
|
38
46
|
}, manyValuesDimensions)
|
|
39
47
|
const duplicatedObservations = duplicateObs(R.values(hierarchisedDimensions), enhancedObservations);
|
|
48
|
+
|
|
49
|
+
const dataflowAttributes = getDataflowAttributes(parsedAttributes, parsedCombinations);
|
|
50
|
+
const headerTitle = getHeaderTitle(dataflow, dataflowAttributes, display, customAttributes);
|
|
51
|
+
const headerSubtitle = getHeaderSubtitle(oneValueDimensions, parsedCombinations, customAttributes, display);
|
|
52
|
+
const headerCombinations = getHeaderCombinations(parsedCombinations, oneValueDimensions, refinedAttributes, display);
|
|
40
53
|
|
|
41
54
|
return ({
|
|
42
55
|
observations: duplicatedObservations,
|
|
@@ -45,6 +58,11 @@ export const prepareData = (sdmxJson, customAttributes, locale, hierarchies) =>
|
|
|
45
58
|
oneValueDimensions,
|
|
46
59
|
attributesSeries,
|
|
47
60
|
metadataCoordinates,
|
|
48
|
-
attributes: refinedAttributes
|
|
61
|
+
attributes: refinedAttributes,
|
|
62
|
+
header: {
|
|
63
|
+
title: headerTitle,
|
|
64
|
+
subtitle: headerSubtitle,
|
|
65
|
+
combinations: headerCombinations
|
|
66
|
+
}
|
|
49
67
|
});
|
|
50
68
|
};
|
|
@@ -5,6 +5,9 @@ import { trimedProps } from '../utils';
|
|
|
5
5
|
|
|
6
6
|
export const getCellRelevantAttributes = (attributes, attributesSeries, cellAttributeIds) => R.filter(
|
|
7
7
|
(attr) => {
|
|
8
|
+
if (R.isNil(attr.value)) {
|
|
9
|
+
return false;
|
|
10
|
+
}
|
|
8
11
|
if (R.has(attr.id, cellAttributeIds)) {
|
|
9
12
|
return true;
|
|
10
13
|
}
|
|
@@ -48,9 +51,8 @@ export const getCells = (customAttributes, cellsAttributesId, combinations, attr
|
|
|
48
51
|
return R.mapObjIndexed(
|
|
49
52
|
obs => {
|
|
50
53
|
const relevantAttributes = getCellRelevantAttributes(obs.attributes, attributesSeries, cellsAttributesId);
|
|
51
|
-
const flagsAndNotes = getFlagsAndNotes(relevantAttributes, _customAttributes);
|
|
54
|
+
const flagsAndNotes = getFlagsAndNotes(R.omit(attributesInCellsCombination, relevantAttributes), _customAttributes);
|
|
52
55
|
const combinedAttributes = getCellCombinedAttributes(relevantAttributes, combinations.cells || []);
|
|
53
|
-
|
|
54
56
|
const hasAdvancedAttributes = R.pipe(
|
|
55
57
|
R.omit(R.unnest([_customAttributes.flags || [], _customAttributes.notes || [], attributesInCellsCombination])),
|
|
56
58
|
R.isEmpty,
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import * as R from 'ramda';
|
|
2
|
+
|
|
3
|
+
export const getCellsMetadataCoordinates = (metadataCoordinates, oneValueDimensions, layoutIds) => {
|
|
4
|
+
const oneValueDimsIds = R.pluck('id', oneValueDimensions);
|
|
5
|
+
return R.reject(coordinates => {
|
|
6
|
+
const columnIds = R.concat(layoutIds.header, oneValueDimsIds);
|
|
7
|
+
if (R.isEmpty(R.omit(columnIds, coordinates))) {
|
|
8
|
+
return true;
|
|
9
|
+
}
|
|
10
|
+
const rowsIds = [...layoutIds.sections, ...layoutIds.rows, ...oneValueDimsIds];
|
|
11
|
+
return R.isEmpty(R.omit(rowsIds, coordinates));
|
|
12
|
+
}, metadataCoordinates);
|
|
13
|
+
};
|
|
@@ -13,9 +13,6 @@ export const getCombinationDimensionsData = (indexes, combination, previous, sam
|
|
|
13
13
|
const dimension = R.nth(dimIndex, dimensions);
|
|
14
14
|
const value = R.nth(Math.abs(valIndex), R.propOr([], 'values', dimension));
|
|
15
15
|
hasAdvancedAttributes = !hasAdvancedAttributes ? value.hasAdvancedAttributes : true;
|
|
16
|
-
if (!value) {
|
|
17
|
-
return acc;
|
|
18
|
-
}
|
|
19
16
|
coordinates = R.assoc(dimension.id, value.id, coordinates);
|
|
20
17
|
ids = R.append(`${dimension.id}=${value.id}`, ids);
|
|
21
18
|
const previousValue = R.propOr({}, dimension.id, previous);
|
|
@@ -23,7 +20,11 @@ export const getCombinationDimensionsData = (indexes, combination, previous, sam
|
|
|
23
20
|
return R.assoc(dimension.id, previousValue, acc);
|
|
24
21
|
}
|
|
25
22
|
else {
|
|
26
|
-
const
|
|
23
|
+
const _parsedValue = parseValueHierarchy(value, _sameSerie ? previousValue || {} : {}, dimension.indexedValues);
|
|
24
|
+
const parsedValue = R.over(
|
|
25
|
+
R.lensProp('display'),
|
|
26
|
+
(display=true) => display && R.propOr(true, 'display', dimension)
|
|
27
|
+
)(_parsedValue);
|
|
27
28
|
if (!R.isNil(previous)) {
|
|
28
29
|
_sameSerie = false;
|
|
29
30
|
}
|
|
@@ -3,8 +3,9 @@ import { getFlagsAndNotes } from './getFlagsAndNotes';
|
|
|
3
3
|
import { hasCellMetadata } from '../hasCellMetadata';
|
|
4
4
|
import { getCombinationDimensionsData } from './getCombinationDimensionsData';
|
|
5
5
|
import { parseValueHierarchy } from './parseValueHierarchy';
|
|
6
|
+
import { REJECTED_VALUE_IDS } from '../constants';
|
|
6
7
|
|
|
7
|
-
const getSubLayoutData = (series, _definition, { metadataCoordinates, attributesSeries, customAttributes }) => {
|
|
8
|
+
const getSubLayoutData = (series, _definition, { metadataCoordinates, attributesSeries, customAttributes, topCoordinates={} }) => {
|
|
8
9
|
const getHasAdvancedAttributes = (attrValues) => R.pipe(
|
|
9
10
|
R.omit(R.concat(customAttributes.flags, customAttributes.notes)),
|
|
10
11
|
R.isEmpty,
|
|
@@ -46,7 +47,7 @@ const getSubLayoutData = (series, _definition, { metadataCoordinates, attributes
|
|
|
46
47
|
let sameSerie = true;
|
|
47
48
|
let i = 0;
|
|
48
49
|
let hasAdvancedAttributes = false;
|
|
49
|
-
let coordinates =
|
|
50
|
+
let coordinates = topCoordinates;
|
|
50
51
|
let ids = [];
|
|
51
52
|
while (i < serie.length) {
|
|
52
53
|
const entry = serie[i];
|
|
@@ -117,7 +118,11 @@ const getSubLayoutData = (series, _definition, { metadataCoordinates, attributes
|
|
|
117
118
|
const values = R.reduce(
|
|
118
119
|
(_acc, id) => {
|
|
119
120
|
if (R.has(id, dimValues)) {
|
|
120
|
-
|
|
121
|
+
const value = R.prop(id, dimValues);
|
|
122
|
+
if (!R.propOr(true, 'display', value) || R.includes(R.prop('id', value), REJECTED_VALUE_IDS)) {
|
|
123
|
+
return _acc;
|
|
124
|
+
}
|
|
125
|
+
return R.append(R.dissoc('display', value), _acc);
|
|
121
126
|
}
|
|
122
127
|
if (R.has(id, fixedDimValues)) {
|
|
123
128
|
return R.append(R.prop(id, fixedDimValues), _acc);
|
|
@@ -151,7 +156,7 @@ const getSubLayoutData = (series, _definition, { metadataCoordinates, attributes
|
|
|
151
156
|
? { hasMetadata, hasAdvancedAttributes, coordinates } : null;
|
|
152
157
|
|
|
153
158
|
return {
|
|
154
|
-
res: R.append({ data, key: R.join(':', ids), flags, sideProps }, acc.res),
|
|
159
|
+
res: R.append({ data, key: R.join(':', ids), flags, sideProps, coordinates }, acc.res),
|
|
155
160
|
previous: next,
|
|
156
161
|
};
|
|
157
162
|
},
|
|
@@ -173,7 +178,10 @@ export const getLayoutData = (layoutIndexes, layout, { metadataCoordinates, attr
|
|
|
173
178
|
return [];
|
|
174
179
|
}
|
|
175
180
|
const _sectionsData = getSubLayoutData(sections, layout.sections, opts);
|
|
176
|
-
const rowsData = R.map(
|
|
181
|
+
const rowsData = R.addIndex(R.map)((rows, sectionIndex) => {
|
|
182
|
+
const sectionCoordinates = R.path([sectionIndex, 'coordinates'], _sectionsData);
|
|
183
|
+
return getSubLayoutData(rows, layout.rows, R.assoc('topCoordinates', sectionCoordinates, opts));
|
|
184
|
+
}, sectionsRows);
|
|
177
185
|
|
|
178
186
|
return R.transpose([_sectionsData, rowsData]);
|
|
179
187
|
}
|
|
@@ -7,17 +7,16 @@ export const parseValueHierarchy = (value, previousValue, indexedValues) => {
|
|
|
7
7
|
}
|
|
8
8
|
const _previousParentsIds = R.propOr([], 'parentsIds', previousValue);
|
|
9
9
|
const previousParentsIds = R.isNil(previousValue) ? [] : R.append(R.prop('id', previousValue), _previousParentsIds);
|
|
10
|
-
const [presentIds,
|
|
11
|
-
|
|
10
|
+
const [presentIds, _missingIds] = R.addIndex(R.splitWhen)((val, ind) => R.nth(ind, previousParentsIds) !== val, parentsIds);
|
|
11
|
+
const __previousParentsIds = R.pipe(R.propOr([], 'parents'), R.pluck('id'))(previousValue);
|
|
12
|
+
const missingIds = R.pipe(
|
|
13
|
+
R.takeLastWhile(id => !R.includes(id, __previousParentsIds) && id !== R.prop('id', previousValue)),
|
|
14
|
+
ids => R.concat(ids, _missingIds)
|
|
15
|
+
)(presentIds);
|
|
12
16
|
const _previousParents = R.propOr([], 'parents', previousValue);
|
|
13
17
|
const previousParents = R.isNil(previousValue) ? [] : R.append(R.pick(['id', 'name'], previousValue), _previousParents);
|
|
14
|
-
//console.log('previousParents', previousParents);
|
|
15
18
|
const parents = R.takeWhile(p => R.includes(p.id, presentIds), previousParents);
|
|
16
|
-
const missingParents = R.
|
|
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
|
-
);
|
|
19
|
+
const missingParents = R.props(missingIds, indexedValues);
|
|
21
20
|
return ({
|
|
22
21
|
...value,
|
|
23
22
|
parents,
|
|
@@ -8,6 +8,7 @@ describe('getAttributesSeries tests', () => {
|
|
|
8
8
|
attributes: {
|
|
9
9
|
A: { id: 'A', value: { id: 'A0' }, serieKey: 'd0=v0' },
|
|
10
10
|
B: { id: 'B', value: { id: 'B0' }, serieKey: 'd1=v0' },
|
|
11
|
+
C: { id: 'C', value: null, serieKey: 'd2=v0' },
|
|
11
12
|
}
|
|
12
13
|
},
|
|
13
14
|
b: {
|
|
@@ -38,6 +39,7 @@ describe('getAttributesSeries tests', () => {
|
|
|
38
39
|
attributes: {
|
|
39
40
|
A: { id: 'A', value: { id: 'A0' }, serieKey: 'd0=v0' },
|
|
40
41
|
B: { id: 'B', value: { id: 'B3' }, serieKey: 'd1=v2' },
|
|
42
|
+
C: { id: 'C', value: { id: 'C0' }, serieKey: 'd2=v0' },
|
|
41
43
|
}
|
|
42
44
|
}
|
|
43
45
|
};
|
package/test/getCells.test.js
CHANGED
|
@@ -14,6 +14,7 @@ describe('getCells tests', () => {
|
|
|
14
14
|
value: 33,
|
|
15
15
|
formattedValue: '33',
|
|
16
16
|
attributes: {
|
|
17
|
+
FL1: { id: 'FL1', name: 'Flag 1', Value: null },
|
|
17
18
|
FL2: { id: 'FL2', name: 'Flag 2', value: { id: 'FL2.1', name: 'Flag 2 Value 1' } },
|
|
18
19
|
FT1: { id: 'FT1', name: 'Footnote 1', value: { id: 'FT1.1', name: 'Footnote 1 Value 1' } },
|
|
19
20
|
FT3: { id: 'FT3', name: 'Footnote 3', value: { id: 'FT3.3', name: 'Footnote 3 Value 3' } },
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { expect } from 'chai';
|
|
2
|
+
import { getCellsMetadataCoordinates } from '../src/rules2/src/';
|
|
3
|
+
|
|
4
|
+
describe('getCellsMetadataCoordinates tests', () => {
|
|
5
|
+
it('basic tests', () => {
|
|
6
|
+
const oneValueDimensions = [
|
|
7
|
+
{ id: 'HEADER1' },
|
|
8
|
+
{ id: 'HEADER2' },
|
|
9
|
+
];
|
|
10
|
+
|
|
11
|
+
const layoutIds = {
|
|
12
|
+
header: ['COLUMN1', 'COLUMN2'],
|
|
13
|
+
sections: ['SECTION1', 'SECTION2'],
|
|
14
|
+
rows: ['ROW1', 'ROW2'],
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
const coordinates = [
|
|
18
|
+
{},
|
|
19
|
+
{ HEADER1: 'v' },
|
|
20
|
+
{ HEADER1: 'v', HEADER2: 'v' },
|
|
21
|
+
{ COLUMN1: 'v' },
|
|
22
|
+
{ COLUMN1: 'v', COLUMN2: 'v' },
|
|
23
|
+
{ HEADER1: 'v', COLUMN1: 'v', COLUMN2: 'v' },
|
|
24
|
+
{ SECTION1: 'v' },
|
|
25
|
+
{ SECTION1: 'v', SECTION2: 'v' },
|
|
26
|
+
{ HEADER1: 'v', SECTION1: 'v', SECTION2: 'v' },
|
|
27
|
+
{ ROW1: 'v' },
|
|
28
|
+
{ ROW1: 'v', ROW2: 'v' },
|
|
29
|
+
{ HEADER1: 'v', ROW1: 'v', ROW2: 'v' },
|
|
30
|
+
{ HEADER1: 'v', SECTION1: 'v', SECTION2: 'v', ROW1: 'v', ROW2: 'v' },
|
|
31
|
+
{ ROW1: 'v', HEADER2: 'v', COLUMN2: 'v' },
|
|
32
|
+
{ SECTION1: 'v', ROW2: 'v', COLUMN1: 'v' }
|
|
33
|
+
];
|
|
34
|
+
|
|
35
|
+
expect(getCellsMetadataCoordinates(coordinates, oneValueDimensions, layoutIds)).to.deep.equal([
|
|
36
|
+
{ ROW1: 'v', HEADER2: 'v', COLUMN2: 'v' },
|
|
37
|
+
{ SECTION1: 'v', ROW2: 'v', COLUMN1: 'v' }
|
|
38
|
+
]);
|
|
39
|
+
});
|
|
40
|
+
});
|
|
@@ -16,6 +16,7 @@ describe('getCombinationDimensionsData', () => {
|
|
|
16
16
|
},
|
|
17
17
|
{
|
|
18
18
|
id: 'D1',
|
|
19
|
+
display: false,
|
|
19
20
|
values: [
|
|
20
21
|
{ id: 'v0' },
|
|
21
22
|
{ id: 'v1', hasAdvancedAttributes: true },
|
|
@@ -35,10 +36,14 @@ describe('getCombinationDimensionsData', () => {
|
|
|
35
36
|
|
|
36
37
|
const indexes = [0, 1, -2];
|
|
37
38
|
|
|
38
|
-
const previous = { D0: { id: 'v0' }, D1: { id: 'v0' }, D2: { id: 'v2' } };
|
|
39
|
+
const previous = { D0: { id: 'v0', display: true }, D1: { id: 'v0', display: false }, D2: { id: 'v2', display: true } };
|
|
39
40
|
|
|
40
41
|
expect(getCombinationDimensionsData(indexes, combination, previous, true)).to.deep.equal({
|
|
41
|
-
dimValues: {
|
|
42
|
+
dimValues: {
|
|
43
|
+
D0: { id: 'v0', display: true },
|
|
44
|
+
D1: { id: 'v1', hasAdvancedAttributes: true, display: false },
|
|
45
|
+
D2: { id: 'v2', display: true }
|
|
46
|
+
},
|
|
42
47
|
sameSerie: false,
|
|
43
48
|
coordinates: { D0: 'v0', D1: 'v1', D2: 'v2' },
|
|
44
49
|
ids: ['D0=v0', 'D1=v1', 'D2=v2'],
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { expect } from 'chai';
|
|
2
|
+
import { getDataflowAttributes } from '../src/rules2/src/';
|
|
3
|
+
|
|
4
|
+
describe('getDataflowAttributes tests', () => {
|
|
5
|
+
it('complete case', () => {
|
|
6
|
+
const attributes = [
|
|
7
|
+
{ id: 'HEADER1', header: true, relationship: [], display: false, values: [{ id: 'v' }] },
|
|
8
|
+
{ id: 'HEADER2', header: true, relationship: [], values: [{ id: 'v', display: false }] },
|
|
9
|
+
{ id: 'HEADER3', header: true, relationship: [], values: [{ id: '_Z' }] },
|
|
10
|
+
{ id: 'HEADER4', header: true, relationship: [], values: [] },
|
|
11
|
+
{ id: 'HEADER5', header: true, relationship: [], values: [{ id: 'v' }] },
|
|
12
|
+
{ id: 'HEADER6', header: true, relationship: [], values: [{ id: 'v' }] },
|
|
13
|
+
{ id: 'HEADER7', header: true, relationship: ['DIM1'], values: [{ id: 'v' }] },
|
|
14
|
+
{ id: 'SERIE', series: true, relationship: [], values: [{ id: 'v' }] },
|
|
15
|
+
];
|
|
16
|
+
|
|
17
|
+
const combinations = [{ id: 'COMB', concepts: ['DIM1', 'DIM2', 'HEADER5'] }];
|
|
18
|
+
|
|
19
|
+
expect(getDataflowAttributes(attributes, combinations)).to.deep.equal({
|
|
20
|
+
HEADER6: { id: 'HEADER6', value: { id: 'v' } }
|
|
21
|
+
});
|
|
22
|
+
});
|
|
23
|
+
});
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { expect } from 'chai';
|
|
2
|
+
import { getHeaderTitle } from '../src/rules2/src/';
|
|
3
|
+
|
|
4
|
+
describe('getHeaderTitle tests', () => {
|
|
5
|
+
it('basic case', () => {
|
|
6
|
+
|
|
7
|
+
const dataflow = { id: 'DF', name: 'dataflow' };
|
|
8
|
+
|
|
9
|
+
const attributes = {
|
|
10
|
+
FLAG: { id: 'FLAG', name: 'flag', value: { id: 'v', name: 'flag value' } },
|
|
11
|
+
NOTE: { id: 'NOTE', name: 'note', value: { id: 'v2', name: 'note value' } },
|
|
12
|
+
OTHER: { id: 'OTHER', name: 'other', value: { id: 'v3', name: 'other value' } },
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const customAttributes = { flags: ['FLAG'], notes: ['NOTE'] };
|
|
16
|
+
|
|
17
|
+
expect(getHeaderTitle(dataflow, attributes, 'label', customAttributes)).to.deep.equal({
|
|
18
|
+
label: 'dataflow',
|
|
19
|
+
flags: [
|
|
20
|
+
{ code: 'v', header: 'flag:', label: 'flag value' },
|
|
21
|
+
{ code: undefined, header: 'note:', label: 'note value' },
|
|
22
|
+
]
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
});
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { expect } from 'chai';
|
|
2
|
+
import { getLayoutData } from '../src/rules2/src/';
|
|
3
|
+
|
|
4
|
+
describe('getLayoutData tests', () => {
|
|
5
|
+
it('basic case with combination', () => {
|
|
6
|
+
const layout = {
|
|
7
|
+
header: [],
|
|
8
|
+
sections: [{ id: 'S', values: [{ id: 'S_V1' }, { id: 'S_V2' }] }],
|
|
9
|
+
rows: [{
|
|
10
|
+
id: 'COMB',
|
|
11
|
+
concepts: ['R1', 'R2', 'ATTR'],
|
|
12
|
+
dimensions: [
|
|
13
|
+
{ id: 'R1', values: [{ id: 'R1_V1' }, { id: 'R1_V2' }] },
|
|
14
|
+
{ id: 'R2', values: [{ id: 'R2_V1' }, { id: 'R2_V2', display: false }] },
|
|
15
|
+
]
|
|
16
|
+
}]
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const attributesSeries = {
|
|
20
|
+
'R1=R1_V1:R2=R2_V1': {
|
|
21
|
+
ATTR: { id: 'ATTR', value: { id: 'ATTR_V1' }, coordinates: { R1: 'R1_V1', R2: 'R2_V1' } },
|
|
22
|
+
},
|
|
23
|
+
'R1=R1_V1:R2=R2_V2': {
|
|
24
|
+
ATTR: { id: 'ATTR', value: { id: 'ATTR_V2' }, coordinates: { R1: 'R1_V1', R2: 'R2_V2' } },
|
|
25
|
+
},
|
|
26
|
+
'R1=R1_V2:R2=R2_V1': {
|
|
27
|
+
ATTR: { id: 'ATTR', value: { id: 'ATTR_V3' }, coordinates: { R1: 'R1_V2', R2: 'R2_V1' } },
|
|
28
|
+
},
|
|
29
|
+
'R1=R1_V2:R2=R2_V2': {
|
|
30
|
+
ATTR: { id: 'ATTR', value: { id: 'ATTR_V4' }, coordinates: { R1: 'R1_V2', R2: 'R2_V2' } },
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
const layoutIndexes = {
|
|
35
|
+
header: [],
|
|
36
|
+
sections: [
|
|
37
|
+
[
|
|
38
|
+
[0],
|
|
39
|
+
[
|
|
40
|
+
[[0, 0]],
|
|
41
|
+
[[0, 1]],
|
|
42
|
+
[[1, 0]],
|
|
43
|
+
[[1, 1]],
|
|
44
|
+
]
|
|
45
|
+
],
|
|
46
|
+
[
|
|
47
|
+
[1],
|
|
48
|
+
[
|
|
49
|
+
[[0, 0]],
|
|
50
|
+
[[0, 1]],
|
|
51
|
+
[[1, 0]],
|
|
52
|
+
[[1, 1]],
|
|
53
|
+
]
|
|
54
|
+
]
|
|
55
|
+
]
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
expect(getLayoutData(layoutIndexes, layout, { attributesSeries, metadataCoordinates: [], customAttributes: { flags: [], notes: [] } })).to.deep.equal({
|
|
59
|
+
headerData: [],
|
|
60
|
+
sectionsData: [
|
|
61
|
+
[
|
|
62
|
+
{ data: [{ dimension: { id: 'S' }, value: { id: 'S_V1' } }], key: 'S=S_V1', flags: [], sideProps: null, coordinates: { S: 'S_V1' } },
|
|
63
|
+
[
|
|
64
|
+
{
|
|
65
|
+
data: [{ dimension: { id: 'COMB' }, values: [{ id: 'R1_V1' }, { id: 'R2_V1' }, { id: 'ATTR_V1' }] }],
|
|
66
|
+
key: 'R1=R1_V1:R2=R2_V1',
|
|
67
|
+
coordinates: { R1: 'R1_V1', R2: 'R2_V1', S: 'S_V1' },
|
|
68
|
+
flags: [],
|
|
69
|
+
sideProps: null
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
data: [{ dimension: { id: 'COMB' }, values: [{ id: 'R1_V1' }, { id: 'ATTR_V2' }] }],
|
|
73
|
+
key: 'R1=R1_V1:R2=R2_V2',
|
|
74
|
+
coordinates: { R1: 'R1_V1', R2: 'R2_V2', S: 'S_V1' },
|
|
75
|
+
flags: [],
|
|
76
|
+
sideProps: null
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
data: [{ dimension: { id: 'COMB' }, values: [{ id: 'R1_V2' }, { id: 'R2_V1' }, { id: 'ATTR_V3' }] }],
|
|
80
|
+
key: 'R1=R1_V2:R2=R2_V1',
|
|
81
|
+
coordinates: { R1: 'R1_V2', R2: 'R2_V1', S: 'S_V1' },
|
|
82
|
+
flags: [],
|
|
83
|
+
sideProps: null
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
data: [{ dimension: { id: 'COMB' }, values: [{ id: 'R1_V2' }, { id: 'ATTR_V4' }] }],
|
|
87
|
+
key: 'R1=R1_V2:R2=R2_V2',
|
|
88
|
+
coordinates: { R1: 'R1_V2', R2: 'R2_V2', S: 'S_V1' },
|
|
89
|
+
flags: [],
|
|
90
|
+
sideProps: null
|
|
91
|
+
},
|
|
92
|
+
]
|
|
93
|
+
],
|
|
94
|
+
[
|
|
95
|
+
{ data: [{ dimension: { id: 'S' }, value: { id: 'S_V2' } }], key: 'S=S_V2', flags: [], sideProps: null, coordinates: { S: 'S_V2' } },
|
|
96
|
+
[
|
|
97
|
+
{
|
|
98
|
+
data: [{ dimension: { id: 'COMB' }, values: [{ id: 'R1_V1' }, { id: 'R2_V1' }, { id: 'ATTR_V1' }] }],
|
|
99
|
+
key: 'R1=R1_V1:R2=R2_V1',
|
|
100
|
+
coordinates: { R1: 'R1_V1', R2: 'R2_V1', S: 'S_V2' },
|
|
101
|
+
flags: [],
|
|
102
|
+
sideProps: null
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
data: [{ dimension: { id: 'COMB' }, values: [{ id: 'R1_V1' }, { id: 'ATTR_V2' }] }],
|
|
106
|
+
key: 'R1=R1_V1:R2=R2_V2',
|
|
107
|
+
coordinates: { R1: 'R1_V1', R2: 'R2_V2', S: 'S_V2' },
|
|
108
|
+
flags: [],
|
|
109
|
+
sideProps: null
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
data: [{ dimension: { id: 'COMB' }, values: [{ id: 'R1_V2' }, { id: 'R2_V1' }, { id: 'ATTR_V3' }] }],
|
|
113
|
+
key: 'R1=R1_V2:R2=R2_V1',
|
|
114
|
+
coordinates: { R1: 'R1_V2', R2: 'R2_V1', S: 'S_V2' },
|
|
115
|
+
flags: [],
|
|
116
|
+
sideProps: null
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
data: [{ dimension: { id: 'COMB' }, values: [{ id: 'R1_V2' }, { id: 'ATTR_V4' }] }],
|
|
120
|
+
key: 'R1=R1_V2:R2=R2_V2',
|
|
121
|
+
coordinates: { R1: 'R1_V2', R2: 'R2_V2', S: 'S_V2' },
|
|
122
|
+
flags: [],
|
|
123
|
+
sideProps: null
|
|
124
|
+
},
|
|
125
|
+
]
|
|
126
|
+
]
|
|
127
|
+
]
|
|
128
|
+
})
|
|
129
|
+
});
|
|
130
|
+
});
|