@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.
Files changed (44) hide show
  1. package/lib/rules/src/v8-transformer.js +2 -2
  2. package/lib/rules2/src/constants.js +2 -1
  3. package/lib/rules2/src/enhanceObservations.js +5 -4
  4. package/lib/rules2/src/getAttributesSeries.js +7 -0
  5. package/lib/rules2/src/getCombinationDefinitions.js +15 -11
  6. package/lib/rules2/src/getDataflowAttributes.js +34 -0
  7. package/lib/rules2/src/getHeaderTitle.js +29 -0
  8. package/lib/rules2/src/getOneValueDimensions.js +3 -1
  9. package/lib/rules2/src/getSidebarData.js +8 -17
  10. package/lib/rules2/src/index.js +27 -0
  11. package/lib/rules2/src/parseCombinations.js +4 -2
  12. package/lib/rules2/src/prepareData.js +33 -2
  13. package/lib/rules2/src/table/getCells.js +4 -2
  14. package/lib/rules2/src/table/getCellsMetadataCoordinates.js +30 -0
  15. package/lib/rules2/src/table/getCombinationDimensionsData.js +5 -4
  16. package/lib/rules2/src/table/getLayoutData.js +15 -6
  17. package/lib/rules2/src/table/parseValueHierarchy.js +9 -8
  18. package/package.json +1 -1
  19. package/src/rules/src/v8-transformer.js +2 -2
  20. package/src/rules2/src/constants.js +1 -0
  21. package/src/rules2/src/enhanceObservations.js +4 -4
  22. package/src/rules2/src/getAttributesSeries.js +7 -0
  23. package/src/rules2/src/getCombinationDefinitions.js +20 -18
  24. package/src/rules2/src/getDataflowAttributes.js +23 -0
  25. package/src/rules2/src/getHeaderTitle.js +15 -0
  26. package/src/rules2/src/getOneValueDimensions.js +2 -1
  27. package/src/rules2/src/getSidebarData.js +4 -12
  28. package/src/rules2/src/index.js +3 -0
  29. package/src/rules2/src/parseCombinations.js +5 -2
  30. package/src/rules2/src/prepareData.js +22 -4
  31. package/src/rules2/src/table/getCells.js +4 -2
  32. package/src/rules2/src/table/getCellsMetadataCoordinates.js +13 -0
  33. package/src/rules2/src/table/getCombinationDimensionsData.js +5 -4
  34. package/src/rules2/src/table/getLayoutData.js +13 -5
  35. package/src/rules2/src/table/parseValueHierarchy.js +7 -8
  36. package/test/getAttributesSeries.test.js +2 -0
  37. package/test/getCells.test.js +1 -0
  38. package/test/getCellsMetadataCoordinates.test.js +40 -0
  39. package/test/getCombinationDimensionsData.test.js +7 -2
  40. package/test/getDataflowAttributes.test.js +23 -0
  41. package/test/getHeaderTitle.test.js +25 -0
  42. package/test/getLayoutData.test.js +130 -0
  43. package/test/parseCombinations.test.js +36 -0
  44. 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 R.useWith(
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
- const dimensionValueDisplay = (display) => data => {
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);
@@ -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 true;
31
+ return attribute.series;
29
32
  }, comb.concepts);
30
33
 
31
- if (R.isEmpty(seriesConcepts) || R.isEmpty(relationship)) {
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
- const combinations = getCombinationDefinitions(annotations, locale);
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 parsedValue = parseValueHierarchy(value, _sameSerie ? previousValue || {} : {}, dimension.indexedValues);
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
- return R.append(R.prop(id, dimValues), _acc);
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(rows => getSubLayoutData(rows, layout.rows, opts), sectionsRows);
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, missingIds] = R.addIndex(R.splitWhen)((val, ind) => R.nth(ind, previousParentsIds) !== val, parentsIds);
11
- //console.log({ presentIds, missingIds });
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.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
- );
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
  };
@@ -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: { D0: { id: 'v0' }, D1: { id: 'v1', hasAdvancedAttributes: true }, D2: { id: 'v2' } },
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
+ });