@dhis2/analytics 24.10.12 → 24.11.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.
- package/CHANGELOG.md +14 -0
- package/build/cjs/__demo__/PivotTable.stories.js +38 -0
- package/build/cjs/components/PivotTable/PivotTableTitleRow.js +52 -13
- package/build/cjs/components/PivotTable/PivotTableTitleRows.js +3 -6
- package/build/cjs/components/PivotTable/PivotTableValueCell.js +2 -3
- package/build/cjs/components/PivotTable/styles/PivotTable.style.js +2 -2
- package/build/cjs/modules/renderValue.js +1 -1
- package/build/cjs/modules/valueTypes.js +7 -2
- package/build/es/__demo__/PivotTable.stories.js +38 -0
- package/build/es/components/PivotTable/PivotTableTitleRow.js +52 -14
- package/build/es/components/PivotTable/PivotTableTitleRows.js +3 -6
- package/build/es/components/PivotTable/PivotTableValueCell.js +3 -4
- package/build/es/components/PivotTable/styles/PivotTable.style.js +2 -2
- package/build/es/modules/renderValue.js +2 -2
- package/build/es/modules/valueTypes.js +3 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
# [24.11.0](https://github.com/dhis2/analytics/compare/v24.10.13...v24.11.0) (2024-11-04)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Features
|
|
5
|
+
|
|
6
|
+
* **pivot-table:** truncate title and show full in tooltip ([#1579](https://github.com/dhis2/analytics/issues/1579)) ([#1622](https://github.com/dhis2/analytics/issues/1622)) ([f62b0c2](https://github.com/dhis2/analytics/commit/f62b0c21b76ac4139d451567ff07108160428996))
|
|
7
|
+
|
|
8
|
+
## [24.10.13](https://github.com/dhis2/analytics/compare/v24.10.12...v24.10.13) (2024-06-27)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* apply legend to all numeric and boolean types (DHIS2-17611) [24.x] ([#1687](https://github.com/dhis2/analytics/issues/1687)) ([9e3f166](https://github.com/dhis2/analytics/commit/9e3f1668aaef693393e5a7a46dc839f9aad5bce5))
|
|
14
|
+
|
|
1
15
|
## [24.10.12](https://github.com/dhis2/analytics/compare/v24.10.11...v24.10.12) (2024-06-25)
|
|
2
16
|
|
|
3
17
|
|
|
@@ -1170,4 +1170,42 @@ ResizingPivotTable.propTypes = {
|
|
|
1170
1170
|
data: degsData,
|
|
1171
1171
|
visualization: visualization
|
|
1172
1172
|
}));
|
|
1173
|
+
});
|
|
1174
|
+
(0, _react.storiesOf)('PivotTable', module).add('Truncated header cell', (_, _ref50) => {
|
|
1175
|
+
let {
|
|
1176
|
+
pivotTableOptions
|
|
1177
|
+
} = _ref50;
|
|
1178
|
+
const widths = [250, 200, 500];
|
|
1179
|
+
const [width, setWidth] = (0, _react2.useState)(250);
|
|
1180
|
+
|
|
1181
|
+
const toggleWidth = () => setWidth(currentWidth => {
|
|
1182
|
+
var _widths;
|
|
1183
|
+
|
|
1184
|
+
return (_widths = widths[widths.indexOf(currentWidth) + 1]) !== null && _widths !== void 0 ? _widths : widths[0];
|
|
1185
|
+
});
|
|
1186
|
+
|
|
1187
|
+
const visualization = { ..._narrativeVisualization.default,
|
|
1188
|
+
...visualizationReset,
|
|
1189
|
+
...pivotTableOptions,
|
|
1190
|
+
columns: _narrativeVisualization.default.filters,
|
|
1191
|
+
filters: _narrativeVisualization.default.columns,
|
|
1192
|
+
rowTotals: true,
|
|
1193
|
+
colTotals: true
|
|
1194
|
+
};
|
|
1195
|
+
const data = { ...narrativeData,
|
|
1196
|
+
rows: [narrativeData.rows[0]]
|
|
1197
|
+
};
|
|
1198
|
+
return /*#__PURE__*/_react2.default.createElement("div", {
|
|
1199
|
+
style: {
|
|
1200
|
+
width,
|
|
1201
|
+
height: 600,
|
|
1202
|
+
marginTop: 50,
|
|
1203
|
+
transition: 'width 1s'
|
|
1204
|
+
}
|
|
1205
|
+
}, /*#__PURE__*/_react2.default.createElement("button", {
|
|
1206
|
+
onClick: toggleWidth
|
|
1207
|
+
}, "Toggle width"), /*#__PURE__*/_react2.default.createElement(_index.PivotTable, {
|
|
1208
|
+
data: data,
|
|
1209
|
+
visualization: visualization
|
|
1210
|
+
}));
|
|
1173
1211
|
});
|
|
@@ -7,6 +7,8 @@ exports.PivotTableTitleRow = void 0;
|
|
|
7
7
|
|
|
8
8
|
var _style = _interopRequireDefault(require("styled-jsx/style"));
|
|
9
9
|
|
|
10
|
+
var _ui = require("@dhis2/ui");
|
|
11
|
+
|
|
10
12
|
var _propTypes = _interopRequireDefault(require("prop-types"));
|
|
11
13
|
|
|
12
14
|
var _react = _interopRequireWildcard(require("react"));
|
|
@@ -24,35 +26,73 @@ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj &&
|
|
|
24
26
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
25
27
|
|
|
26
28
|
const PivotTableTitleRow = _ref => {
|
|
29
|
+
var _scrollPosition$x;
|
|
30
|
+
|
|
27
31
|
let {
|
|
28
32
|
title,
|
|
29
33
|
scrollPosition,
|
|
30
|
-
containerWidth
|
|
31
|
-
totalWidth
|
|
34
|
+
containerWidth
|
|
32
35
|
} = _ref;
|
|
36
|
+
const containerRef = (0, _react.useRef)(null);
|
|
37
|
+
const [scrollWidth, setScrollWidth] = (0, _react.useState)(0);
|
|
38
|
+
const [isTitleTruncated, setIsTitleTruncated] = (0, _react.useState)(false);
|
|
33
39
|
const engine = (0, _PivotTableEngineContext.usePivotTableEngine)();
|
|
34
40
|
const columnCount = engine.width + engine.rowDepth;
|
|
35
|
-
const
|
|
41
|
+
const maxWidth = containerWidth - (engine.cellPadding * 2 + 2);
|
|
42
|
+
const marginLeft = Math.max(0, (_scrollPosition$x = scrollPosition === null || scrollPosition === void 0 ? void 0 : scrollPosition.x) !== null && _scrollPosition$x !== void 0 ? _scrollPosition$x : 0);
|
|
36
43
|
(0, _react.useEffect)(() => {
|
|
37
|
-
|
|
38
|
-
|
|
44
|
+
if (containerRef.current) {
|
|
45
|
+
/* Only set `scrollWidth` once, because during a CSS transition
|
|
46
|
+
* the reported value can sometimes be equal to `clientWidth`
|
|
47
|
+
* even though the text doesn't fit. Due to `white-space: nowrap`
|
|
48
|
+
* and `overflow: hidden` the `scrollWidth` should remain constant,
|
|
49
|
+
* so we can assume this initial value is correct. */
|
|
50
|
+
if (!scrollWidth) {
|
|
51
|
+
setScrollWidth(containerRef.current.scrollWidth);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const currentScrollWidth = scrollWidth !== null && scrollWidth !== void 0 ? scrollWidth : containerRef.current.scrollWidth;
|
|
55
|
+
const newIsTitleTruncated = currentScrollWidth > containerRef.current.clientWidth;
|
|
56
|
+
|
|
57
|
+
if (newIsTitleTruncated !== isTitleTruncated) {
|
|
58
|
+
setIsTitleTruncated(newIsTitleTruncated);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}, [containerWidth, scrollWidth, isTitleTruncated]);
|
|
39
62
|
return /*#__PURE__*/_react.default.createElement("tr", {
|
|
40
63
|
className: "jsx-".concat(_PivotTableStyle.cell.__hash)
|
|
41
64
|
}, /*#__PURE__*/_react.default.createElement(_style.default, {
|
|
42
65
|
id: _PivotTableStyle.cell.__hash
|
|
43
66
|
}, _PivotTableStyle.cell), /*#__PURE__*/_react.default.createElement(_PivotTableCell.PivotTableCell, {
|
|
44
67
|
isHeader: true,
|
|
45
|
-
classes: ['column-header', 'title'],
|
|
68
|
+
classes: ['column-header', 'title-cell'],
|
|
46
69
|
colSpan: columnCount
|
|
47
70
|
}, /*#__PURE__*/_react.default.createElement("div", {
|
|
48
71
|
style: {
|
|
49
|
-
marginLeft
|
|
50
|
-
maxWidth
|
|
51
|
-
textAlign: 'center'
|
|
72
|
+
marginLeft,
|
|
73
|
+
maxWidth
|
|
52
74
|
},
|
|
75
|
+
ref: containerRef,
|
|
53
76
|
"data-test": "visualization-title",
|
|
54
|
-
className: "jsx-".concat(_PivotTableStyle.cell.__hash)
|
|
55
|
-
},
|
|
77
|
+
className: "jsx-".concat(_PivotTableStyle.cell.__hash) + " " + "title-cell-content"
|
|
78
|
+
}, isTitleTruncated ? /*#__PURE__*/_react.default.createElement(_ui.Tooltip, {
|
|
79
|
+
content: title
|
|
80
|
+
}, _ref2 => {
|
|
81
|
+
let {
|
|
82
|
+
ref: tooltipRef,
|
|
83
|
+
onMouseOver,
|
|
84
|
+
onMouseOut
|
|
85
|
+
} = _ref2;
|
|
86
|
+
return /*#__PURE__*/_react.default.createElement("div", {
|
|
87
|
+
ref: tooltipRef,
|
|
88
|
+
onMouseOver: onMouseOver,
|
|
89
|
+
onMouseOut: onMouseOut,
|
|
90
|
+
style: {
|
|
91
|
+
maxWidth
|
|
92
|
+
},
|
|
93
|
+
className: "jsx-".concat(_PivotTableStyle.cell.__hash) + " " + "title-cell-content"
|
|
94
|
+
}, title);
|
|
95
|
+
}) : title)));
|
|
56
96
|
};
|
|
57
97
|
|
|
58
98
|
exports.PivotTableTitleRow = PivotTableTitleRow;
|
|
@@ -61,6 +101,5 @@ PivotTableTitleRow.propTypes = {
|
|
|
61
101
|
scrollPosition: _propTypes.default.shape({
|
|
62
102
|
x: _propTypes.default.number.isRequired
|
|
63
103
|
}).isRequired,
|
|
64
|
-
title: _propTypes.default.string.isRequired
|
|
65
|
-
totalWidth: _propTypes.default.number.isRequired
|
|
104
|
+
title: _propTypes.default.string.isRequired
|
|
66
105
|
};
|
|
@@ -28,18 +28,15 @@ const PivotTableTitleRows = _ref => {
|
|
|
28
28
|
return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, engine.options.title ? /*#__PURE__*/_react.default.createElement(_PivotTableTitleRow.PivotTableTitleRow, {
|
|
29
29
|
title: engine.options.title,
|
|
30
30
|
scrollPosition: clippingResult.scrollPosition,
|
|
31
|
-
containerWidth: width
|
|
32
|
-
totalWidth: engine.adaptiveClippingController.columns.totalSize + engine.adaptiveClippingController.columns.headerSize
|
|
31
|
+
containerWidth: width
|
|
33
32
|
}) : null, engine.options.subtitle ? /*#__PURE__*/_react.default.createElement(_PivotTableTitleRow.PivotTableTitleRow, {
|
|
34
33
|
title: engine.options.subtitle,
|
|
35
34
|
scrollPosition: clippingResult.scrollPosition,
|
|
36
|
-
containerWidth: width
|
|
37
|
-
totalWidth: engine.adaptiveClippingController.columns.totalSize + engine.adaptiveClippingController.columns.headerSize
|
|
35
|
+
containerWidth: width
|
|
38
36
|
}) : null, (_engine$visualization = engine.visualization.filters) !== null && _engine$visualization !== void 0 && _engine$visualization.length ? /*#__PURE__*/_react.default.createElement(_PivotTableTitleRow.PivotTableTitleRow, {
|
|
39
37
|
title: (0, _getFilterText.default)(engine.visualization.filters, engine.rawData.metaData),
|
|
40
38
|
scrollPosition: clippingResult.scrollPosition,
|
|
41
|
-
containerWidth: width
|
|
42
|
-
totalWidth: engine.adaptiveClippingController.columns.totalSize + engine.adaptiveClippingController.columns.headerSize
|
|
39
|
+
containerWidth: width
|
|
43
40
|
}) : null);
|
|
44
41
|
};
|
|
45
42
|
|
|
@@ -56,10 +56,9 @@ const PivotTableValueCell = _ref => {
|
|
|
56
56
|
ref: cellRef,
|
|
57
57
|
classes: [cellContent.cellType, isClickable && 'clickable']
|
|
58
58
|
});
|
|
59
|
-
}
|
|
59
|
+
}
|
|
60
60
|
|
|
61
|
-
|
|
62
|
-
const legendStyle = cellContent.cellType === _pivotTableConstants.CELL_TYPE_VALUE && cellContent.valueType === _valueTypes.VALUE_TYPE_NUMBER ? (0, _applyLegendSet.applyLegendSet)(cellContent.rawValue, cellContent.dxDimension, engine) : undefined;
|
|
61
|
+
const legendStyle = cellContent.cellType === _pivotTableConstants.CELL_TYPE_VALUE && ((0, _valueTypes.isNumericValueType)(cellContent.valueType) || (0, _valueTypes.isBooleanValueType)(cellContent.valueType)) ? (0, _applyLegendSet.applyLegendSet)(cellContent.rawValue, cellContent.dxDimension, engine) : undefined;
|
|
63
62
|
const width = engine.adaptiveClippingController.columns.sizes[engine.columnMap[column]].size;
|
|
64
63
|
const height = engine.adaptiveClippingController.rows.sizes[engine.rowMap[row]].size;
|
|
65
64
|
const style = { ...legendStyle,
|
|
@@ -12,9 +12,9 @@ var _pivotTableConstants = require("../../../modules/pivotTable/pivotTableConsta
|
|
|
12
12
|
const table = ["div.pivot-table-container.jsx-3572446209{font-family:'Roboto',Arial,sans-serif;overflow:auto;color:".concat(_ui.colors.grey900, ";}"), "div.pivot-table-container.jsx-3572446209 table{border-spacing:0;white-space:nowrap;box-sizing:border-box;text-align:center;border:1px solid ".concat(_pivotTableConstants.BORDER_COLOR, ";border-width:1px 1px 0 0;}"), "div.pivot-table-container.jsx-3572446209 table.fixed-headers{border-width:0 0 0 1px;}", "div.pivot-table-container.jsx-3572446209 table.fixed-headers tr th,div.pivot-table-container.jsx-3572446209 table.fixed-headers tr td{border-width:0 1px 1px 0;}", "div.pivot-table-container.jsx-3572446209 table.fixed-column-headers{border-width:0 1px 0 0;}", "div.pivot-table-container.jsx-3572446209 table.fixed-column-headers tr th,div.pivot-table-container.jsx-3572446209 table.fixed-column-headers tr td{border-width:0 0 1px 1px;}", "div.pivot-table-container.jsx-3572446209 table.fixed-headers thead tr:first-of-type th,div.pivot-table-container.jsx-3572446209 table.fixed-column-headers thead tr:first-of-type th{border-top:1px solid ".concat(_pivotTableConstants.BORDER_COLOR, ";}"), "div.pivot-table-container.jsx-3572446209 table.fixed-row-headers{border-width:0 0 1px 1px;}", "div.pivot-table-container.jsx-3572446209 table.fixed-row-headers tr th,div.pivot-table-container.jsx-3572446209 table.fixed-row-headers tr td{border-width:1px 1px 0 0;}"];
|
|
13
13
|
exports.table = table;
|
|
14
14
|
table.__hash = "3572446209";
|
|
15
|
-
const cell = ["td.jsx-
|
|
15
|
+
const cell = ["td.jsx-3234356038,th.jsx-3234356038{box-sizing:border-box;font-weight:normal;overflow:hidden;text-overflow:ellipsis;border:1px solid ".concat(_pivotTableConstants.BORDER_COLOR, ";border-width:0 0 1px 1px;cursor:default;}"), "th.fixed-header.jsx-3234356038{position:-webkit-sticky;position:sticky;z-index:1;top:0;left:0;}", ".fontsize-SMALL.jsx-3234356038{font-size:".concat(_pivotTableConstants.FONT_SIZE_SMALL, "px;line-height:").concat(_pivotTableConstants.FONT_SIZE_SMALL, "px;}"), ".fontsize-NORMAL.jsx-3234356038{font-size:".concat(_pivotTableConstants.FONT_SIZE_NORMAL, "px;line-height:").concat(_pivotTableConstants.FONT_SIZE_NORMAL, "px;}"), ".fontsize-LARGE.jsx-3234356038{font-size:".concat(_pivotTableConstants.FONT_SIZE_LARGE, "px;line-height:").concat(_pivotTableConstants.FONT_SIZE_LARGE, "px;}"), ".displaydensity-COMPACT.jsx-3234356038{padding:".concat(_pivotTableConstants.DISPLAY_DENSITY_PADDING_COMPACT, "px;}"), ".displaydensity-NORMAL.jsx-3234356038{padding:".concat(_pivotTableConstants.DISPLAY_DENSITY_PADDING_NORMAL, "px;}"), ".displaydensity-COMFORTABLE.jsx-3234356038{padding:".concat(_pivotTableConstants.DISPLAY_DENSITY_PADDING_COMFORTABLE, "px;}"), ".column-header.jsx-3234356038{background-color:#dae6f8;}", "div.column-header-inner.jsx-3234356038{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;}", ".title-cell.jsx-3234356038{font-weight:bold;background-color:#cddaed;padding:0;}", ".title-cell-content.jsx-3234356038{text-align:center;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}", ".title-cell.displaydensity-COMPACT.jsx-3234356038>.title-cell-content.jsx-3234356038{padding:".concat(_pivotTableConstants.DISPLAY_DENSITY_PADDING_COMPACT, "px;}"), ".title-cell.displaydensity-NORMAL.jsx-3234356038>.title-cell-content.jsx-3234356038{padding:".concat(_pivotTableConstants.DISPLAY_DENSITY_PADDING_NORMAL, "px;}"), ".title-cell.displaydensity-COMFORTABLE.jsx-3234356038>.title-cell-content.jsx-3234356038{padding:".concat(_pivotTableConstants.DISPLAY_DENSITY_PADDING_COMFORTABLE, "px;}"), ".row-header.jsx-3234356038{background-color:#dae6f8;}", ".row-header-hierarchy.jsx-3234356038{text-align:left;}", ".empty-header.jsx-3234356038{background-color:#cddaed;}", ".total-header.jsx-3234356038{background-color:#bac6d8;}", ".value.jsx-3234356038{background-color:#ffffff;text-align:left;}", ".NUMBER.jsx-3234356038,.INTEGER.jsx-3234356038,.INTEGER_POSITIVE.jsx-3234356038,.INTEGER_NEGATIVE.jsx-3234356038,.INTEGER_ZERO_OR_POSITIVE.jsx-3234356038,.UNIT_INTERVAL.jsx-3234356038,.PERCENTAGE.jsx-3234356038,.BOOLEAN.jsx-3234356038,.TRUE_ONLY.jsx-3234356038{text-align:right;}", ".clickable.jsx-3234356038{cursor:pointer;}", ".value.jsx-3234356038:hover{background-color:#f3f3f3;}", ".subtotal.jsx-3234356038{background-color:#f4f4f4;}", ".total.jsx-3234356038{background-color:#d8d8d8;}", ".column-header-label.jsx-3234356038{overflow:hidden;text-overflow:ellipsis;}"];
|
|
16
16
|
exports.cell = cell;
|
|
17
|
-
cell.__hash = "
|
|
17
|
+
cell.__hash = "3234356038";
|
|
18
18
|
const sortIcon = [".fontsize-SMALL.jsx-2877616992{height:".concat(_pivotTableConstants.FONT_SIZE_SMALL, "px;margin-bottom:1px;margin-left:5px;}"), ".fontsize-NORMAL.jsx-2877616992{height:".concat(_pivotTableConstants.FONT_SIZE_NORMAL, "px;max-height:11px;margin-bottom:2px;margin-left:6px;}"), ".fontsize-LARGE.jsx-2877616992{height:".concat(_pivotTableConstants.FONT_SIZE_LARGE, "px;margin-bottom:2px;margin-left:7px;}")];
|
|
19
19
|
exports.sortIcon = sortIcon;
|
|
20
20
|
sortIcon.__hash = "2877616992";
|
|
@@ -63,7 +63,7 @@ const toFixedPrecisionString = (value, skipRounding) => {
|
|
|
63
63
|
};
|
|
64
64
|
|
|
65
65
|
const renderValue = (value, valueType, visualization) => {
|
|
66
|
-
if (!(0, _valueTypes.isNumericValueType)(valueType) || value === undefined) {
|
|
66
|
+
if (!((0, _valueTypes.isNumericValueType)(valueType) || (0, _valueTypes.isBooleanValueType)(valueType)) || value === undefined) {
|
|
67
67
|
return String(value).replace(/[^\S\n]+/, ' ');
|
|
68
68
|
}
|
|
69
69
|
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.isNumericValueType = exports.VALUE_TYPE_USERNAME = exports.VALUE_TYPE_URL = exports.VALUE_TYPE_UNIT_INTERVAL = exports.VALUE_TYPE_TRUE_ONLY = exports.VALUE_TYPE_TIME = exports.VALUE_TYPE_TEXT = exports.VALUE_TYPE_PHONE_NUMBER = exports.VALUE_TYPE_PERCENTAGE = exports.VALUE_TYPE_ORGANISATION_UNIT = exports.VALUE_TYPE_NUMBER = exports.VALUE_TYPE_LONG_TEXT = exports.VALUE_TYPE_LETTER = exports.VALUE_TYPE_INTEGER_ZERO_OR_POSITIVE = exports.VALUE_TYPE_INTEGER_POSITIVE = exports.VALUE_TYPE_INTEGER_NEGATIVE = exports.VALUE_TYPE_INTEGER = exports.VALUE_TYPE_EMAIL = exports.VALUE_TYPE_DATETIME = exports.VALUE_TYPE_DATE = exports.VALUE_TYPE_BOOLEAN = exports.VALUE_TYPE_AGE = void 0;
|
|
6
|
+
exports.isNumericValueType = exports.isBooleanValueType = exports.VALUE_TYPE_USERNAME = exports.VALUE_TYPE_URL = exports.VALUE_TYPE_UNIT_INTERVAL = exports.VALUE_TYPE_TRUE_ONLY = exports.VALUE_TYPE_TIME = exports.VALUE_TYPE_TEXT = exports.VALUE_TYPE_PHONE_NUMBER = exports.VALUE_TYPE_PERCENTAGE = exports.VALUE_TYPE_ORGANISATION_UNIT = exports.VALUE_TYPE_NUMBER = exports.VALUE_TYPE_LONG_TEXT = exports.VALUE_TYPE_LETTER = exports.VALUE_TYPE_INTEGER_ZERO_OR_POSITIVE = exports.VALUE_TYPE_INTEGER_POSITIVE = exports.VALUE_TYPE_INTEGER_NEGATIVE = exports.VALUE_TYPE_INTEGER = exports.VALUE_TYPE_EMAIL = exports.VALUE_TYPE_DATETIME = exports.VALUE_TYPE_DATE = exports.VALUE_TYPE_BOOLEAN = exports.VALUE_TYPE_AGE = void 0;
|
|
7
7
|
|
|
8
8
|
/* These types match the types in the backend
|
|
9
9
|
https://github.com/dhis2/dhis2-core/blob/master/dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/ValueType.java
|
|
@@ -51,7 +51,12 @@ exports.VALUE_TYPE_ORGANISATION_UNIT = VALUE_TYPE_ORGANISATION_UNIT;
|
|
|
51
51
|
const VALUE_TYPE_AGE = 'AGE';
|
|
52
52
|
exports.VALUE_TYPE_AGE = VALUE_TYPE_AGE;
|
|
53
53
|
const NUMERIC_VALUE_TYPES = [VALUE_TYPE_NUMBER, VALUE_TYPE_UNIT_INTERVAL, VALUE_TYPE_PERCENTAGE, VALUE_TYPE_INTEGER, VALUE_TYPE_INTEGER_POSITIVE, VALUE_TYPE_INTEGER_NEGATIVE, VALUE_TYPE_INTEGER_ZERO_OR_POSITIVE];
|
|
54
|
+
const BOOLEAN_VALUE_TYPES = [VALUE_TYPE_BOOLEAN, VALUE_TYPE_TRUE_ONLY];
|
|
54
55
|
|
|
55
56
|
const isNumericValueType = type => NUMERIC_VALUE_TYPES.includes(type);
|
|
56
57
|
|
|
57
|
-
exports.isNumericValueType = isNumericValueType;
|
|
58
|
+
exports.isNumericValueType = isNumericValueType;
|
|
59
|
+
|
|
60
|
+
const isBooleanValueType = type => BOOLEAN_VALUE_TYPES.includes(type);
|
|
61
|
+
|
|
62
|
+
exports.isBooleanValueType = isBooleanValueType;
|
|
@@ -1118,4 +1118,42 @@ storiesOf('PivotTable', module).add('DEGS', (_, _ref49) => {
|
|
|
1118
1118
|
data: degsData,
|
|
1119
1119
|
visualization: visualization
|
|
1120
1120
|
}));
|
|
1121
|
+
});
|
|
1122
|
+
storiesOf('PivotTable', module).add('Truncated header cell', (_, _ref50) => {
|
|
1123
|
+
let {
|
|
1124
|
+
pivotTableOptions
|
|
1125
|
+
} = _ref50;
|
|
1126
|
+
const widths = [250, 200, 500];
|
|
1127
|
+
const [width, setWidth] = useState(250);
|
|
1128
|
+
|
|
1129
|
+
const toggleWidth = () => setWidth(currentWidth => {
|
|
1130
|
+
var _widths;
|
|
1131
|
+
|
|
1132
|
+
return (_widths = widths[widths.indexOf(currentWidth) + 1]) !== null && _widths !== void 0 ? _widths : widths[0];
|
|
1133
|
+
});
|
|
1134
|
+
|
|
1135
|
+
const visualization = { ...narrativeVisualization,
|
|
1136
|
+
...visualizationReset,
|
|
1137
|
+
...pivotTableOptions,
|
|
1138
|
+
columns: narrativeVisualization.filters,
|
|
1139
|
+
filters: narrativeVisualization.columns,
|
|
1140
|
+
rowTotals: true,
|
|
1141
|
+
colTotals: true
|
|
1142
|
+
};
|
|
1143
|
+
const data = { ...narrativeData,
|
|
1144
|
+
rows: [narrativeData.rows[0]]
|
|
1145
|
+
};
|
|
1146
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
1147
|
+
style: {
|
|
1148
|
+
width,
|
|
1149
|
+
height: 600,
|
|
1150
|
+
marginTop: 50,
|
|
1151
|
+
transition: 'width 1s'
|
|
1152
|
+
}
|
|
1153
|
+
}, /*#__PURE__*/React.createElement("button", {
|
|
1154
|
+
onClick: toggleWidth
|
|
1155
|
+
}, "Toggle width"), /*#__PURE__*/React.createElement(PivotTable, {
|
|
1156
|
+
data: data,
|
|
1157
|
+
visualization: visualization
|
|
1158
|
+
}));
|
|
1121
1159
|
});
|
|
@@ -1,45 +1,83 @@
|
|
|
1
1
|
import _JSXStyle from "styled-jsx/style";
|
|
2
|
+
import { Tooltip } from '@dhis2/ui';
|
|
2
3
|
import PropTypes from 'prop-types';
|
|
3
|
-
import React, { useState, useEffect } from 'react';
|
|
4
|
+
import React, { useRef, useState, useEffect } from 'react';
|
|
4
5
|
import { PivotTableCell } from './PivotTableCell.js';
|
|
5
6
|
import { usePivotTableEngine } from './PivotTableEngineContext.js';
|
|
6
7
|
import { cell as cellStyle } from './styles/PivotTable.style.js';
|
|
7
8
|
export const PivotTableTitleRow = _ref => {
|
|
9
|
+
var _scrollPosition$x;
|
|
10
|
+
|
|
8
11
|
let {
|
|
9
12
|
title,
|
|
10
13
|
scrollPosition,
|
|
11
|
-
containerWidth
|
|
12
|
-
totalWidth
|
|
14
|
+
containerWidth
|
|
13
15
|
} = _ref;
|
|
16
|
+
const containerRef = useRef(null);
|
|
17
|
+
const [scrollWidth, setScrollWidth] = useState(0);
|
|
18
|
+
const [isTitleTruncated, setIsTitleTruncated] = useState(false);
|
|
14
19
|
const engine = usePivotTableEngine();
|
|
15
20
|
const columnCount = engine.width + engine.rowDepth;
|
|
16
|
-
const
|
|
21
|
+
const maxWidth = containerWidth - (engine.cellPadding * 2 + 2);
|
|
22
|
+
const marginLeft = Math.max(0, (_scrollPosition$x = scrollPosition === null || scrollPosition === void 0 ? void 0 : scrollPosition.x) !== null && _scrollPosition$x !== void 0 ? _scrollPosition$x : 0);
|
|
17
23
|
useEffect(() => {
|
|
18
|
-
|
|
19
|
-
|
|
24
|
+
if (containerRef.current) {
|
|
25
|
+
/* Only set `scrollWidth` once, because during a CSS transition
|
|
26
|
+
* the reported value can sometimes be equal to `clientWidth`
|
|
27
|
+
* even though the text doesn't fit. Due to `white-space: nowrap`
|
|
28
|
+
* and `overflow: hidden` the `scrollWidth` should remain constant,
|
|
29
|
+
* so we can assume this initial value is correct. */
|
|
30
|
+
if (!scrollWidth) {
|
|
31
|
+
setScrollWidth(containerRef.current.scrollWidth);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const currentScrollWidth = scrollWidth !== null && scrollWidth !== void 0 ? scrollWidth : containerRef.current.scrollWidth;
|
|
35
|
+
const newIsTitleTruncated = currentScrollWidth > containerRef.current.clientWidth;
|
|
36
|
+
|
|
37
|
+
if (newIsTitleTruncated !== isTitleTruncated) {
|
|
38
|
+
setIsTitleTruncated(newIsTitleTruncated);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}, [containerWidth, scrollWidth, isTitleTruncated]);
|
|
20
42
|
return /*#__PURE__*/React.createElement("tr", {
|
|
21
43
|
className: "jsx-".concat(cellStyle.__hash)
|
|
22
44
|
}, /*#__PURE__*/React.createElement(_JSXStyle, {
|
|
23
45
|
id: cellStyle.__hash
|
|
24
46
|
}, cellStyle), /*#__PURE__*/React.createElement(PivotTableCell, {
|
|
25
47
|
isHeader: true,
|
|
26
|
-
classes: ['column-header', 'title'],
|
|
48
|
+
classes: ['column-header', 'title-cell'],
|
|
27
49
|
colSpan: columnCount
|
|
28
50
|
}, /*#__PURE__*/React.createElement("div", {
|
|
29
51
|
style: {
|
|
30
|
-
marginLeft
|
|
31
|
-
maxWidth
|
|
32
|
-
textAlign: 'center'
|
|
52
|
+
marginLeft,
|
|
53
|
+
maxWidth
|
|
33
54
|
},
|
|
55
|
+
ref: containerRef,
|
|
34
56
|
"data-test": "visualization-title",
|
|
35
|
-
className: "jsx-".concat(cellStyle.__hash)
|
|
36
|
-
},
|
|
57
|
+
className: "jsx-".concat(cellStyle.__hash) + " " + "title-cell-content"
|
|
58
|
+
}, isTitleTruncated ? /*#__PURE__*/React.createElement(Tooltip, {
|
|
59
|
+
content: title
|
|
60
|
+
}, _ref2 => {
|
|
61
|
+
let {
|
|
62
|
+
ref: tooltipRef,
|
|
63
|
+
onMouseOver,
|
|
64
|
+
onMouseOut
|
|
65
|
+
} = _ref2;
|
|
66
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
67
|
+
ref: tooltipRef,
|
|
68
|
+
onMouseOver: onMouseOver,
|
|
69
|
+
onMouseOut: onMouseOut,
|
|
70
|
+
style: {
|
|
71
|
+
maxWidth
|
|
72
|
+
},
|
|
73
|
+
className: "jsx-".concat(cellStyle.__hash) + " " + "title-cell-content"
|
|
74
|
+
}, title);
|
|
75
|
+
}) : title)));
|
|
37
76
|
};
|
|
38
77
|
PivotTableTitleRow.propTypes = {
|
|
39
78
|
containerWidth: PropTypes.number.isRequired,
|
|
40
79
|
scrollPosition: PropTypes.shape({
|
|
41
80
|
x: PropTypes.number.isRequired
|
|
42
81
|
}).isRequired,
|
|
43
|
-
title: PropTypes.string.isRequired
|
|
44
|
-
totalWidth: PropTypes.number.isRequired
|
|
82
|
+
title: PropTypes.string.isRequired
|
|
45
83
|
};
|
|
@@ -14,18 +14,15 @@ export const PivotTableTitleRows = _ref => {
|
|
|
14
14
|
return /*#__PURE__*/React.createElement(React.Fragment, null, engine.options.title ? /*#__PURE__*/React.createElement(PivotTableTitleRow, {
|
|
15
15
|
title: engine.options.title,
|
|
16
16
|
scrollPosition: clippingResult.scrollPosition,
|
|
17
|
-
containerWidth: width
|
|
18
|
-
totalWidth: engine.adaptiveClippingController.columns.totalSize + engine.adaptiveClippingController.columns.headerSize
|
|
17
|
+
containerWidth: width
|
|
19
18
|
}) : null, engine.options.subtitle ? /*#__PURE__*/React.createElement(PivotTableTitleRow, {
|
|
20
19
|
title: engine.options.subtitle,
|
|
21
20
|
scrollPosition: clippingResult.scrollPosition,
|
|
22
|
-
containerWidth: width
|
|
23
|
-
totalWidth: engine.adaptiveClippingController.columns.totalSize + engine.adaptiveClippingController.columns.headerSize
|
|
21
|
+
containerWidth: width
|
|
24
22
|
}) : null, (_engine$visualization = engine.visualization.filters) !== null && _engine$visualization !== void 0 && _engine$visualization.length ? /*#__PURE__*/React.createElement(PivotTableTitleRow, {
|
|
25
23
|
title: getFilterText(engine.visualization.filters, engine.rawData.metaData),
|
|
26
24
|
scrollPosition: clippingResult.scrollPosition,
|
|
27
|
-
containerWidth: width
|
|
28
|
-
totalWidth: engine.adaptiveClippingController.columns.totalSize + engine.adaptiveClippingController.columns.headerSize
|
|
25
|
+
containerWidth: width
|
|
29
26
|
}) : null);
|
|
30
27
|
};
|
|
31
28
|
PivotTableTitleRows.propTypes = {
|
|
@@ -2,7 +2,7 @@ import PropTypes from 'prop-types';
|
|
|
2
2
|
import React, { useRef } from 'react';
|
|
3
3
|
import { applyLegendSet } from '../../modules/pivotTable/applyLegendSet.js';
|
|
4
4
|
import { CELL_TYPE_VALUE } from '../../modules/pivotTable/pivotTableConstants.js';
|
|
5
|
-
import {
|
|
5
|
+
import { isNumericValueType, isBooleanValueType } from '../../modules/valueTypes.js';
|
|
6
6
|
import { PivotTableCell } from './PivotTableCell.js';
|
|
7
7
|
import { PivotTableEmptyCell } from './PivotTableEmptyCell.js';
|
|
8
8
|
import { usePivotTableEngine } from './PivotTableEngineContext.js';
|
|
@@ -35,10 +35,9 @@ export const PivotTableValueCell = _ref => {
|
|
|
35
35
|
ref: cellRef,
|
|
36
36
|
classes: [cellContent.cellType, isClickable && 'clickable']
|
|
37
37
|
});
|
|
38
|
-
}
|
|
38
|
+
}
|
|
39
39
|
|
|
40
|
-
|
|
41
|
-
const legendStyle = cellContent.cellType === CELL_TYPE_VALUE && cellContent.valueType === VALUE_TYPE_NUMBER ? applyLegendSet(cellContent.rawValue, cellContent.dxDimension, engine) : undefined;
|
|
40
|
+
const legendStyle = cellContent.cellType === CELL_TYPE_VALUE && (isNumericValueType(cellContent.valueType) || isBooleanValueType(cellContent.valueType)) ? applyLegendSet(cellContent.rawValue, cellContent.dxDimension, engine) : undefined;
|
|
42
41
|
const width = engine.adaptiveClippingController.columns.sizes[engine.columnMap[column]].size;
|
|
43
42
|
const height = engine.adaptiveClippingController.rows.sizes[engine.rowMap[row]].size;
|
|
44
43
|
const style = { ...legendStyle,
|
|
@@ -2,7 +2,7 @@ import { colors } from '@dhis2/ui';
|
|
|
2
2
|
import { BORDER_COLOR, DISPLAY_DENSITY_PADDING_COMPACT, DISPLAY_DENSITY_PADDING_NORMAL, DISPLAY_DENSITY_PADDING_COMFORTABLE, FONT_SIZE_SMALL, FONT_SIZE_NORMAL, FONT_SIZE_LARGE } from '../../../modules/pivotTable/pivotTableConstants.js';
|
|
3
3
|
export const table = ["div.pivot-table-container.jsx-3572446209{font-family:'Roboto',Arial,sans-serif;overflow:auto;color:".concat(colors.grey900, ";}"), "div.pivot-table-container.jsx-3572446209 table{border-spacing:0;white-space:nowrap;box-sizing:border-box;text-align:center;border:1px solid ".concat(BORDER_COLOR, ";border-width:1px 1px 0 0;}"), "div.pivot-table-container.jsx-3572446209 table.fixed-headers{border-width:0 0 0 1px;}", "div.pivot-table-container.jsx-3572446209 table.fixed-headers tr th,div.pivot-table-container.jsx-3572446209 table.fixed-headers tr td{border-width:0 1px 1px 0;}", "div.pivot-table-container.jsx-3572446209 table.fixed-column-headers{border-width:0 1px 0 0;}", "div.pivot-table-container.jsx-3572446209 table.fixed-column-headers tr th,div.pivot-table-container.jsx-3572446209 table.fixed-column-headers tr td{border-width:0 0 1px 1px;}", "div.pivot-table-container.jsx-3572446209 table.fixed-headers thead tr:first-of-type th,div.pivot-table-container.jsx-3572446209 table.fixed-column-headers thead tr:first-of-type th{border-top:1px solid ".concat(BORDER_COLOR, ";}"), "div.pivot-table-container.jsx-3572446209 table.fixed-row-headers{border-width:0 0 1px 1px;}", "div.pivot-table-container.jsx-3572446209 table.fixed-row-headers tr th,div.pivot-table-container.jsx-3572446209 table.fixed-row-headers tr td{border-width:1px 1px 0 0;}"];
|
|
4
4
|
table.__hash = "3572446209";
|
|
5
|
-
export const cell = ["td.jsx-
|
|
6
|
-
cell.__hash = "
|
|
5
|
+
export const cell = ["td.jsx-3234356038,th.jsx-3234356038{box-sizing:border-box;font-weight:normal;overflow:hidden;text-overflow:ellipsis;border:1px solid ".concat(BORDER_COLOR, ";border-width:0 0 1px 1px;cursor:default;}"), "th.fixed-header.jsx-3234356038{position:-webkit-sticky;position:sticky;z-index:1;top:0;left:0;}", ".fontsize-SMALL.jsx-3234356038{font-size:".concat(FONT_SIZE_SMALL, "px;line-height:").concat(FONT_SIZE_SMALL, "px;}"), ".fontsize-NORMAL.jsx-3234356038{font-size:".concat(FONT_SIZE_NORMAL, "px;line-height:").concat(FONT_SIZE_NORMAL, "px;}"), ".fontsize-LARGE.jsx-3234356038{font-size:".concat(FONT_SIZE_LARGE, "px;line-height:").concat(FONT_SIZE_LARGE, "px;}"), ".displaydensity-COMPACT.jsx-3234356038{padding:".concat(DISPLAY_DENSITY_PADDING_COMPACT, "px;}"), ".displaydensity-NORMAL.jsx-3234356038{padding:".concat(DISPLAY_DENSITY_PADDING_NORMAL, "px;}"), ".displaydensity-COMFORTABLE.jsx-3234356038{padding:".concat(DISPLAY_DENSITY_PADDING_COMFORTABLE, "px;}"), ".column-header.jsx-3234356038{background-color:#dae6f8;}", "div.column-header-inner.jsx-3234356038{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;}", ".title-cell.jsx-3234356038{font-weight:bold;background-color:#cddaed;padding:0;}", ".title-cell-content.jsx-3234356038{text-align:center;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}", ".title-cell.displaydensity-COMPACT.jsx-3234356038>.title-cell-content.jsx-3234356038{padding:".concat(DISPLAY_DENSITY_PADDING_COMPACT, "px;}"), ".title-cell.displaydensity-NORMAL.jsx-3234356038>.title-cell-content.jsx-3234356038{padding:".concat(DISPLAY_DENSITY_PADDING_NORMAL, "px;}"), ".title-cell.displaydensity-COMFORTABLE.jsx-3234356038>.title-cell-content.jsx-3234356038{padding:".concat(DISPLAY_DENSITY_PADDING_COMFORTABLE, "px;}"), ".row-header.jsx-3234356038{background-color:#dae6f8;}", ".row-header-hierarchy.jsx-3234356038{text-align:left;}", ".empty-header.jsx-3234356038{background-color:#cddaed;}", ".total-header.jsx-3234356038{background-color:#bac6d8;}", ".value.jsx-3234356038{background-color:#ffffff;text-align:left;}", ".NUMBER.jsx-3234356038,.INTEGER.jsx-3234356038,.INTEGER_POSITIVE.jsx-3234356038,.INTEGER_NEGATIVE.jsx-3234356038,.INTEGER_ZERO_OR_POSITIVE.jsx-3234356038,.UNIT_INTERVAL.jsx-3234356038,.PERCENTAGE.jsx-3234356038,.BOOLEAN.jsx-3234356038,.TRUE_ONLY.jsx-3234356038{text-align:right;}", ".clickable.jsx-3234356038{cursor:pointer;}", ".value.jsx-3234356038:hover{background-color:#f3f3f3;}", ".subtotal.jsx-3234356038{background-color:#f4f4f4;}", ".total.jsx-3234356038{background-color:#d8d8d8;}", ".column-header-label.jsx-3234356038{overflow:hidden;text-overflow:ellipsis;}"];
|
|
6
|
+
cell.__hash = "3234356038";
|
|
7
7
|
export const sortIcon = [".fontsize-SMALL.jsx-2877616992{height:".concat(FONT_SIZE_SMALL, "px;margin-bottom:1px;margin-left:5px;}"), ".fontsize-NORMAL.jsx-2877616992{height:".concat(FONT_SIZE_NORMAL, "px;max-height:11px;margin-bottom:2px;margin-left:6px;}"), ".fontsize-LARGE.jsx-2877616992{height:".concat(FONT_SIZE_LARGE, "px;margin-bottom:2px;margin-left:7px;}")];
|
|
8
8
|
sortIcon.__hash = "2877616992";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { NUMBER_TYPE_ROW_PERCENTAGE, NUMBER_TYPE_COLUMN_PERCENTAGE } from './pivotTable/pivotTableConstants.js';
|
|
2
|
-
import { isNumericValueType } from './valueTypes.js';
|
|
2
|
+
import { isNumericValueType, isBooleanValueType } from './valueTypes.js';
|
|
3
3
|
|
|
4
4
|
const trimTrailingZeros = stringValue => stringValue.replace(/\.?0+$/, '');
|
|
5
5
|
|
|
@@ -53,7 +53,7 @@ const toFixedPrecisionString = (value, skipRounding) => {
|
|
|
53
53
|
};
|
|
54
54
|
|
|
55
55
|
export const renderValue = (value, valueType, visualization) => {
|
|
56
|
-
if (!isNumericValueType(valueType) || value === undefined) {
|
|
56
|
+
if (!(isNumericValueType(valueType) || isBooleanValueType(valueType)) || value === undefined) {
|
|
57
57
|
return String(value).replace(/[^\S\n]+/, ' ');
|
|
58
58
|
}
|
|
59
59
|
|
|
@@ -23,4 +23,6 @@ export const VALUE_TYPE_DATETIME = 'DATETIME';
|
|
|
23
23
|
export const VALUE_TYPE_ORGANISATION_UNIT = 'ORGANISATION_UNIT';
|
|
24
24
|
export const VALUE_TYPE_AGE = 'AGE';
|
|
25
25
|
const NUMERIC_VALUE_TYPES = [VALUE_TYPE_NUMBER, VALUE_TYPE_UNIT_INTERVAL, VALUE_TYPE_PERCENTAGE, VALUE_TYPE_INTEGER, VALUE_TYPE_INTEGER_POSITIVE, VALUE_TYPE_INTEGER_NEGATIVE, VALUE_TYPE_INTEGER_ZERO_OR_POSITIVE];
|
|
26
|
-
|
|
26
|
+
const BOOLEAN_VALUE_TYPES = [VALUE_TYPE_BOOLEAN, VALUE_TYPE_TRUE_ONLY];
|
|
27
|
+
export const isNumericValueType = type => NUMERIC_VALUE_TYPES.includes(type);
|
|
28
|
+
export const isBooleanValueType = type => BOOLEAN_VALUE_TYPES.includes(type);
|