@dhis2/analytics 24.10.1 → 25.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/build/cjs/__demo__/CalculationModal.stories.js +448 -0
  3. package/build/cjs/api/analytics/AnalyticsRequest.js +12 -1
  4. package/build/cjs/api/dimensions.js +1 -1
  5. package/build/cjs/api/expression.js +67 -0
  6. package/build/cjs/assets/DimensionItemIcons/CalculationIcon.js +25 -0
  7. package/build/cjs/assets/FormulaIcon.js +40 -0
  8. package/build/cjs/components/DataDimension/Calculation/CalculationModal.js +448 -0
  9. package/build/cjs/components/DataDimension/Calculation/DataElementOption.js +78 -0
  10. package/build/cjs/components/DataDimension/Calculation/DataElementSelector.js +309 -0
  11. package/build/cjs/components/DataDimension/Calculation/DndContext.js +213 -0
  12. package/build/cjs/components/DataDimension/Calculation/DragHandleIcon.js +23 -0
  13. package/build/cjs/components/DataDimension/Calculation/DraggingItem.js +58 -0
  14. package/build/cjs/components/DataDimension/Calculation/DropZone.js +58 -0
  15. package/build/cjs/components/DataDimension/Calculation/FormulaField.js +121 -0
  16. package/build/cjs/components/DataDimension/Calculation/FormulaItem.js +232 -0
  17. package/build/cjs/components/DataDimension/Calculation/MathOperatorSelector.js +58 -0
  18. package/build/cjs/components/DataDimension/Calculation/Operator.js +81 -0
  19. package/build/cjs/components/DataDimension/Calculation/styles/CalculationModal.style.js +13 -0
  20. package/build/cjs/components/DataDimension/Calculation/styles/DataElementOption.style.js +13 -0
  21. package/build/cjs/components/DataDimension/Calculation/styles/DataElementSelector.style.js +13 -0
  22. package/build/cjs/components/DataDimension/Calculation/styles/DraggingItem.style.js +13 -0
  23. package/build/cjs/components/DataDimension/Calculation/styles/DropZone.style.js +13 -0
  24. package/build/cjs/components/DataDimension/Calculation/styles/FormulaField.style.js +13 -0
  25. package/build/cjs/components/DataDimension/Calculation/styles/FormulaItem.style.js +13 -0
  26. package/build/cjs/components/DataDimension/Calculation/styles/MathOperatorSelector.style.js +13 -0
  27. package/build/cjs/components/DataDimension/Calculation/styles/Operator.style.js +13 -0
  28. package/build/cjs/components/DataDimension/DataDimension.js +22 -6
  29. package/build/cjs/components/DataDimension/DataTypeSelector.js +5 -3
  30. package/build/cjs/components/DataDimension/ItemSelector.js +111 -73
  31. package/build/cjs/components/LegendKey/LegendKey.js +1 -1
  32. package/build/cjs/components/TransferOption.js +13 -4
  33. package/build/cjs/components/styles/DimensionSelector.style.js +2 -2
  34. package/build/cjs/components/styles/TransferOption.style.js +2 -2
  35. package/build/cjs/index.js +6 -0
  36. package/build/cjs/locales/en/translations.json +32 -7
  37. package/build/cjs/modules/__tests__/expressions.spec.js +139 -0
  38. package/build/cjs/modules/__tests__/hash.spec.js +92 -0
  39. package/build/cjs/modules/__tests__/parseExpression.spec.js +46 -0
  40. package/build/cjs/modules/dataTypes.js +8 -1
  41. package/build/cjs/modules/dimensionListItem.js +82 -0
  42. package/build/cjs/modules/expressions.js +164 -0
  43. package/build/cjs/modules/hash.js +28 -0
  44. package/build/cjs/visualizations/config/generators/dhis/singleValue.js +112 -58
  45. package/build/es/__demo__/CalculationModal.stories.js +440 -0
  46. package/build/es/api/analytics/AnalyticsRequest.js +11 -1
  47. package/build/es/api/dimensions.js +1 -1
  48. package/build/es/api/expression.js +57 -0
  49. package/build/es/assets/DimensionItemIcons/CalculationIcon.js +13 -0
  50. package/build/es/assets/FormulaIcon.js +30 -0
  51. package/build/es/components/DataDimension/Calculation/CalculationModal.js +419 -0
  52. package/build/es/components/DataDimension/Calculation/DataElementOption.js +61 -0
  53. package/build/es/components/DataDimension/Calculation/DataElementSelector.js +283 -0
  54. package/build/es/components/DataDimension/Calculation/DndContext.js +194 -0
  55. package/build/es/components/DataDimension/Calculation/DragHandleIcon.js +11 -0
  56. package/build/es/components/DataDimension/Calculation/DraggingItem.js +40 -0
  57. package/build/es/components/DataDimension/Calculation/DropZone.js +43 -0
  58. package/build/es/components/DataDimension/Calculation/FormulaField.js +98 -0
  59. package/build/es/components/DataDimension/Calculation/FormulaItem.js +207 -0
  60. package/build/es/components/DataDimension/Calculation/MathOperatorSelector.js +42 -0
  61. package/build/es/components/DataDimension/Calculation/Operator.js +64 -0
  62. package/build/es/components/DataDimension/Calculation/styles/CalculationModal.style.js +4 -0
  63. package/build/es/components/DataDimension/Calculation/styles/DataElementOption.style.js +4 -0
  64. package/build/es/components/DataDimension/Calculation/styles/DataElementSelector.style.js +4 -0
  65. package/build/es/components/DataDimension/Calculation/styles/DraggingItem.style.js +4 -0
  66. package/build/es/components/DataDimension/Calculation/styles/DropZone.style.js +4 -0
  67. package/build/es/components/DataDimension/Calculation/styles/FormulaField.style.js +4 -0
  68. package/build/es/components/DataDimension/Calculation/styles/FormulaItem.style.js +4 -0
  69. package/build/es/components/DataDimension/Calculation/styles/MathOperatorSelector.style.js +4 -0
  70. package/build/es/components/DataDimension/Calculation/styles/Operator.style.js +4 -0
  71. package/build/es/components/DataDimension/DataDimension.js +21 -6
  72. package/build/es/components/DataDimension/DataTypeSelector.js +6 -4
  73. package/build/es/components/DataDimension/ItemSelector.js +111 -73
  74. package/build/es/components/LegendKey/LegendKey.js +1 -1
  75. package/build/es/components/TransferOption.js +14 -5
  76. package/build/es/components/styles/DimensionSelector.style.js +2 -2
  77. package/build/es/components/styles/TransferOption.style.js +2 -2
  78. package/build/es/index.js +1 -1
  79. package/build/es/locales/en/translations.json +32 -7
  80. package/build/es/modules/__tests__/expressions.spec.js +136 -0
  81. package/build/es/modules/__tests__/hash.spec.js +88 -0
  82. package/build/es/modules/__tests__/parseExpression.spec.js +43 -0
  83. package/build/es/modules/dataTypes.js +6 -0
  84. package/build/es/modules/dimensionListItem.js +61 -0
  85. package/build/es/modules/expressions.js +131 -0
  86. package/build/es/modules/hash.js +12 -0
  87. package/build/es/visualizations/config/generators/dhis/singleValue.js +112 -58
  88. package/package.json +6 -1
@@ -0,0 +1,309 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+
8
+ var _style = _interopRequireDefault(require("styled-jsx/style"));
9
+
10
+ var _appRuntime = require("@dhis2/app-runtime");
11
+
12
+ var _ui = require("@dhis2/ui");
13
+
14
+ var _sortable = require("@dnd-kit/sortable");
15
+
16
+ var _debounce = require("@react-hook/debounce");
17
+
18
+ var _classnames = _interopRequireDefault(require("classnames"));
19
+
20
+ var _propTypes = _interopRequireDefault(require("prop-types"));
21
+
22
+ var _react = _interopRequireWildcard(require("react"));
23
+
24
+ var _dimensions = require("../../../api/dimensions.js");
25
+
26
+ var _index = _interopRequireDefault(require("../../../locales/index.js"));
27
+
28
+ var _dataTypes = require("../../../modules/dataTypes.js");
29
+
30
+ var _DataElementOption = _interopRequireDefault(require("./DataElementOption.js"));
31
+
32
+ var _DataElementSelectorStyle = _interopRequireDefault(require("./styles/DataElementSelector.style.js"));
33
+
34
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
35
+
36
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
37
+
38
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
39
+
40
+ const getOptions = () => ({
41
+ [_dataTypes.TOTALS]: _index.default.t('Totals only'),
42
+ [_dataTypes.DETAIL]: _index.default.t('Details only')
43
+ });
44
+
45
+ const GroupSelector = _ref => {
46
+ var _dataTypes$DIMENSION_;
47
+
48
+ let {
49
+ currentValue,
50
+ onChange,
51
+ displayNameProp
52
+ } = _ref;
53
+ const dataEngine = (0, _appRuntime.useDataEngine)();
54
+ const [loading, setLoading] = (0, _react.useState)(true);
55
+ const [groups, setGroups] = (0, _react.useState)([]);
56
+ const defaultGroup = (_dataTypes$DIMENSION_ = _dataTypes.dataTypeMap[_dataTypes.DIMENSION_TYPE_DATA_ELEMENT]) === null || _dataTypes$DIMENSION_ === void 0 ? void 0 : _dataTypes$DIMENSION_.defaultGroup;
57
+ (0, _react.useEffect)(() => {
58
+ const fetchGroups = async () => {
59
+ setLoading(true);
60
+ const result = await (0, _dimensions.apiFetchGroups)(dataEngine, _dataTypes.DIMENSION_TYPE_DATA_ELEMENT, displayNameProp);
61
+ setGroups(result);
62
+ setLoading(false);
63
+ };
64
+
65
+ fetchGroups();
66
+ }, [dataEngine, displayNameProp]);
67
+ return /*#__PURE__*/_react.default.createElement("div", {
68
+ className: "jsx-".concat(_DataElementSelectorStyle.default.__hash) + " " + "group-select"
69
+ }, /*#__PURE__*/_react.default.createElement(_ui.SingleSelectField, {
70
+ selected: currentValue,
71
+ onChange: ref => onChange(ref.selected),
72
+ dense: true,
73
+ loading: loading,
74
+ loadingText: _index.default.t('Loading'),
75
+ dataTest: 'data-element-group-select'
76
+ }, defaultGroup ? /*#__PURE__*/_react.default.createElement(_ui.SingleSelectOption, {
77
+ value: defaultGroup.id,
78
+ key: defaultGroup.id,
79
+ label: defaultGroup.getName(),
80
+ dataTest: "data-element-group-select-option-".concat(defaultGroup.id)
81
+ }) : null, !loading ? groups.map(group => /*#__PURE__*/_react.default.createElement(_ui.SingleSelectOption, {
82
+ value: group.id,
83
+ key: group.id,
84
+ label: group.name,
85
+ dataTest: "data-element-group-select-option-".concat(group.id)
86
+ })) : null), /*#__PURE__*/_react.default.createElement(_style.default, {
87
+ id: _DataElementSelectorStyle.default.__hash
88
+ }, _DataElementSelectorStyle.default));
89
+ };
90
+
91
+ GroupSelector.propTypes = {
92
+ currentValue: _propTypes.default.string.isRequired,
93
+ displayNameProp: _propTypes.default.string.isRequired,
94
+ onChange: _propTypes.default.func.isRequired
95
+ };
96
+
97
+ const DisaggregationSelector = _ref2 => {
98
+ let {
99
+ currentValue,
100
+ onChange
101
+ } = _ref2;
102
+ const options = getOptions();
103
+ return /*#__PURE__*/_react.default.createElement("div", {
104
+ className: "jsx-".concat(_DataElementSelectorStyle.default.__hash) + " " + "group-select"
105
+ }, /*#__PURE__*/_react.default.createElement(_ui.SingleSelectField, {
106
+ selected: currentValue,
107
+ onChange: ref => onChange(ref.selected),
108
+ dense: true,
109
+ dataTest: 'data-element-disaggregation-select'
110
+ }, Object.entries(options).map(option => /*#__PURE__*/_react.default.createElement(_ui.SingleSelectOption, {
111
+ value: option[0],
112
+ key: option[0],
113
+ label: option[1],
114
+ dataTest: "data-element-disaggregation-select-option-".concat(option[0])
115
+ }))), /*#__PURE__*/_react.default.createElement(_style.default, {
116
+ id: _DataElementSelectorStyle.default.__hash
117
+ }, _DataElementSelectorStyle.default));
118
+ };
119
+
120
+ DisaggregationSelector.propTypes = {
121
+ currentValue: _propTypes.default.string.isRequired,
122
+ onChange: _propTypes.default.func.isRequired
123
+ };
124
+
125
+ const DataElementSelector = _ref3 => {
126
+ let {
127
+ displayNameProp,
128
+ onDoubleClick
129
+ } = _ref3;
130
+ const dataEngine = (0, _appRuntime.useDataEngine)();
131
+ const [searchTerm, setSearchTerm] = (0, _react.useState)('');
132
+ const [group, setGroup] = (0, _react.useState)(_dataTypes.DIMENSION_TYPE_ALL);
133
+ const [subGroup, setSubGroup] = (0, _react.useState)(_dataTypes.TOTALS);
134
+ const [options, setOptions] = (0, _react.useState)([]);
135
+ const [loading, setLoading] = (0, _react.useState)(true);
136
+ const {
137
+ isSorting
138
+ } = (0, _sortable.useSortable)({});
139
+ const rootRef = (0, _react.useRef)();
140
+ const hasNextPageRef = (0, _react.useRef)(false);
141
+ const searchTermRef = (0, _react.useRef)(searchTerm);
142
+ const pageRef = (0, _react.useRef)(0);
143
+ const filterRef = (0, _react.useRef)({
144
+ dataType: _dataTypes.DIMENSION_TYPE_DATA_ELEMENT,
145
+ group,
146
+ subGroup
147
+ });
148
+
149
+ const fetchData = async scrollToTop => {
150
+ try {
151
+ setLoading(true);
152
+ const result = await (0, _dimensions.apiFetchOptions)({
153
+ dataEngine,
154
+ nameProp: displayNameProp,
155
+ filter: filterRef.current,
156
+ searchTerm: searchTermRef.current,
157
+ page: pageRef.current
158
+ });
159
+
160
+ if (result !== null && result !== void 0 && result.dimensionItems) {
161
+ const newOptions = result.dimensionItems.map(item => ({
162
+ label: item.name,
163
+ value: item.id,
164
+ type: item.dimensionItemType,
165
+ expression: item.expression
166
+ }));
167
+ setOptions(prevOptions => pageRef.current > 1 ? [...prevOptions, ...newOptions] : newOptions);
168
+ setLoading(false);
169
+ }
170
+
171
+ hasNextPageRef.current = result !== null && result !== void 0 && result.nextPage ? true : false;
172
+ } catch (error) {
173
+ // TODO handle errors
174
+ console.log('apiFetchOptions error: ', error);
175
+ } finally {
176
+ if (scrollToTop) {
177
+ rootRef.current.scrollTo({
178
+ top: 0
179
+ });
180
+ }
181
+ }
182
+ };
183
+
184
+ const debouncedFetchData = (0, _debounce.useDebounceCallback)(newSearchTerm => {
185
+ hasNextPageRef.current = false;
186
+ pageRef.current = 1;
187
+ searchTermRef.current = newSearchTerm;
188
+ fetchData(true);
189
+ }, 500);
190
+
191
+ const onSearchChange = _ref4 => {
192
+ let {
193
+ value
194
+ } = _ref4;
195
+ const newSearchTerm = value;
196
+ setSearchTerm(newSearchTerm); // debounce the fetch
197
+
198
+ debouncedFetchData(newSearchTerm);
199
+ };
200
+
201
+ const onFilterChange = newFilter => {
202
+ if (newFilter.group) {
203
+ setGroup(newFilter.group);
204
+ filterRef.current.group = newFilter.group;
205
+ }
206
+
207
+ if (newFilter.subGroup) {
208
+ setSubGroup(newFilter.subGroup);
209
+ filterRef.current.subGroup = newFilter.subGroup;
210
+ }
211
+
212
+ hasNextPageRef.current = false;
213
+ pageRef.current = 1;
214
+ fetchData(true);
215
+ };
216
+
217
+ const onEndReached = _ref5 => {
218
+ let {
219
+ isIntersecting
220
+ } = _ref5;
221
+
222
+ if (isIntersecting) {
223
+ // if hasNextPage is set it means at least 1 request already happened and there is
224
+ // another page, fetch the next page
225
+ if (hasNextPageRef.current) {
226
+ pageRef.current += 1;
227
+ fetchData();
228
+ } else if (pageRef.current === 0) {
229
+ // this is for fetching the initial page
230
+ pageRef.current = 1;
231
+ fetchData();
232
+ }
233
+ }
234
+ };
235
+
236
+ return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("div", {
237
+ className: "jsx-".concat(_DataElementSelectorStyle.default.__hash) + " " + "filter-wrapper"
238
+ }, /*#__PURE__*/_react.default.createElement("h4", {
239
+ className: "jsx-".concat(_DataElementSelectorStyle.default.__hash) + " " + "sub-header"
240
+ }, _index.default.t('Data elements')), /*#__PURE__*/_react.default.createElement(_ui.InputField, {
241
+ value: searchTerm,
242
+ onChange: onSearchChange,
243
+ placeholder: _index.default.t('Search by data element name'),
244
+ dense: true,
245
+ type: 'search',
246
+ dataTest: 'data-element-search'
247
+ }), /*#__PURE__*/_react.default.createElement("div", {
248
+ className: "jsx-".concat(_DataElementSelectorStyle.default.__hash) + " " + "selector-wrapper"
249
+ }, /*#__PURE__*/_react.default.createElement(GroupSelector, {
250
+ currentValue: group,
251
+ onChange: group => onFilterChange({
252
+ group
253
+ }),
254
+ displayNameProp: displayNameProp
255
+ }), /*#__PURE__*/_react.default.createElement(DisaggregationSelector, {
256
+ currentValue: subGroup,
257
+ onChange: subGroup => onFilterChange({
258
+ subGroup
259
+ })
260
+ }))), /*#__PURE__*/_react.default.createElement("div", {
261
+ className: "jsx-".concat(_DataElementSelectorStyle.default.__hash) + " " + "dimension-list-container"
262
+ }, loading && /*#__PURE__*/_react.default.createElement("div", {
263
+ className: "jsx-".concat(_DataElementSelectorStyle.default.__hash) + " " + "dimension-list-overlay"
264
+ }, /*#__PURE__*/_react.default.createElement(_ui.CircularLoader, null)), /*#__PURE__*/_react.default.createElement("div", {
265
+ ref: rootRef,
266
+ onScroll: () => {
267
+ if (isSorting) {
268
+ rootRef.current.scrollTo({
269
+ top: 0
270
+ });
271
+ }
272
+ },
273
+ className: "jsx-".concat(_DataElementSelectorStyle.default.__hash) + " " + "dimension-list-scrollbox"
274
+ }, /*#__PURE__*/_react.default.createElement("div", {
275
+ "data-test": "dimension-list",
276
+ className: "jsx-".concat(_DataElementSelectorStyle.default.__hash) + " " + ((0, _classnames.default)('dimension-list-scroller', {
277
+ loading
278
+ }) || "")
279
+ }, Boolean(options.length) && options.map(_ref6 => {
280
+ let {
281
+ label,
282
+ value
283
+ } = _ref6;
284
+ return /*#__PURE__*/_react.default.createElement(_DataElementOption.default, {
285
+ key: value,
286
+ label: label,
287
+ value: value,
288
+ onDoubleClick: onDoubleClick
289
+ });
290
+ }), !loading && !options.length && /*#__PURE__*/_react.default.createElement("div", {
291
+ className: "jsx-".concat(_DataElementSelectorStyle.default.__hash) + " " + "empty-list"
292
+ }, searchTermRef.current ? _index.default.t('No data elements found for "{{- searchTerm}}"', {
293
+ searchTerm: searchTermRef.current
294
+ }) : _index.default.t('No data elements found')), /*#__PURE__*/_react.default.createElement("div", {
295
+ className: "jsx-".concat(_DataElementSelectorStyle.default.__hash) + " " + "scroll-detector"
296
+ }, /*#__PURE__*/_react.default.createElement(_ui.IntersectionDetector, {
297
+ onChange: onEndReached,
298
+ rootRef: rootRef
299
+ }))))), /*#__PURE__*/_react.default.createElement(_style.default, {
300
+ id: _DataElementSelectorStyle.default.__hash
301
+ }, _DataElementSelectorStyle.default));
302
+ };
303
+
304
+ DataElementSelector.propTypes = {
305
+ displayNameProp: _propTypes.default.string.isRequired,
306
+ onDoubleClick: _propTypes.default.func.isRequired
307
+ };
308
+ var _default = DataElementSelector;
309
+ exports.default = _default;
@@ -0,0 +1,213 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = exports.OPTIONS_PANEL = void 0;
7
+
8
+ var _core = require("@dnd-kit/core");
9
+
10
+ var _propTypes = _interopRequireDefault(require("prop-types"));
11
+
12
+ var _react = _interopRequireWildcard(require("react"));
13
+
14
+ var _DraggingItem = _interopRequireDefault(require("./DraggingItem.js"));
15
+
16
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
17
+
18
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
19
+
20
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
21
+
22
+ function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
23
+
24
+ const OPTIONS_PANEL = 'Sortable';
25
+ exports.OPTIONS_PANEL = OPTIONS_PANEL;
26
+
27
+ const getIntersectionRatio = (entry, target) => {
28
+ const top = Math.max(target.top, entry.top);
29
+ const left = Math.max(target.left, entry.left);
30
+ const right = Math.min(target.left + target.width, entry.left + entry.width);
31
+ const bottom = Math.min(target.top + target.height, entry.top + entry.height);
32
+ const width = right - left;
33
+ const height = bottom - top;
34
+
35
+ if (left < right && top < bottom) {
36
+ const targetArea = target.width * target.height;
37
+ const entryArea = entry.width * entry.height;
38
+ const intersectionArea = width * height;
39
+ const intersectionRatio = intersectionArea / (targetArea + entryArea - intersectionArea);
40
+ return Number(intersectionRatio.toFixed(4));
41
+ } // Rectangles do not overlap, or overlap has an area of zero (edge/corner overlap)
42
+
43
+
44
+ return 0;
45
+ };
46
+
47
+ const sortCollisionsDesc = (_ref, _ref2) => {
48
+ let {
49
+ data: {
50
+ value: a
51
+ }
52
+ } = _ref;
53
+ let {
54
+ data: {
55
+ value: b
56
+ }
57
+ } = _ref2;
58
+ return b - a;
59
+ };
60
+
61
+ const rectIntersectionCustom = _ref3 => {
62
+ let {
63
+ pointerCoordinates,
64
+ droppableContainers
65
+ } = _ref3;
66
+ // create a rect around the pointerCoords for calculating the intersection
67
+ const pointerRectWidth = 40;
68
+ const pointerRectHeight = 40;
69
+ const pointerRect = {
70
+ width: pointerRectWidth,
71
+ height: pointerRectHeight,
72
+ top: pointerCoordinates.y - pointerRectHeight / 2,
73
+ bottom: pointerCoordinates.y + pointerRectHeight / 2,
74
+ left: pointerCoordinates.x - pointerRectWidth / 2,
75
+ right: pointerCoordinates.x + pointerRectWidth / 2
76
+ };
77
+ const collisions = [];
78
+
79
+ for (const droppableContainer of droppableContainers) {
80
+ const {
81
+ id,
82
+ rect: {
83
+ current: rect
84
+ }
85
+ } = droppableContainer;
86
+
87
+ if (rect) {
88
+ const intersectionRatio = getIntersectionRatio(rect, pointerRect);
89
+
90
+ if (intersectionRatio > 0) {
91
+ collisions.push({
92
+ id,
93
+ data: {
94
+ droppableContainer,
95
+ value: intersectionRatio
96
+ }
97
+ });
98
+ }
99
+ }
100
+ }
101
+
102
+ return collisions.sort(sortCollisionsDesc);
103
+ };
104
+
105
+ const isInteractiveElement = el => {
106
+ const interactiveElements = ['button', 'input', 'textarea', 'select', 'option'];
107
+
108
+ if (interactiveElements.includes(el.tagName.toLowerCase())) {
109
+ return true;
110
+ }
111
+
112
+ return false;
113
+ }; // disable dragging if user is in an input
114
+
115
+
116
+ class PointerSensor extends _core.PointerSensor {}
117
+
118
+ _defineProperty(PointerSensor, "activators", [{
119
+ eventName: 'onPointerDown',
120
+ handler: _ref7 => {
121
+ let {
122
+ nativeEvent: event
123
+ } = _ref7;
124
+
125
+ if (!event.isPrimary || event.button !== 0 || isInteractiveElement(event.target)) {
126
+ return false;
127
+ }
128
+
129
+ return true;
130
+ }
131
+ }]);
132
+
133
+ const OuterDndContext = _ref4 => {
134
+ let {
135
+ children,
136
+ onDragEnd,
137
+ onDragStart
138
+ } = _ref4;
139
+ const [draggingItem, setDraggingItem] = (0, _react.useState)(null);
140
+ const sensor = (0, _core.useSensor)(PointerSensor, {
141
+ activationConstraint: {
142
+ distance: 15
143
+ }
144
+ });
145
+ const sensors = (0, _core.useSensors)(sensor);
146
+
147
+ const handleDragStart = _ref5 => {
148
+ let {
149
+ active
150
+ } = _ref5;
151
+ setDraggingItem(active.data.current);
152
+ onDragStart && onDragStart();
153
+ };
154
+
155
+ const handleDragCancel = () => {
156
+ setDraggingItem(null);
157
+ };
158
+
159
+ const handleDragEnd = _ref6 => {
160
+ var _over$data, _over$data$current, _over$data$current$so, _over$data$current2, _over$data$current3;
161
+
162
+ let {
163
+ active,
164
+ over
165
+ } = _ref6;
166
+
167
+ if (!(over !== null && over !== void 0 && over.id) || (over === null || over === void 0 ? void 0 : (_over$data = over.data) === null || _over$data === void 0 ? void 0 : (_over$data$current = _over$data.current) === null || _over$data$current === void 0 ? void 0 : (_over$data$current$so = _over$data$current.sortable) === null || _over$data$current$so === void 0 ? void 0 : _over$data$current$so.containerId) === OPTIONS_PANEL || !active.data.current) {
168
+ // dropped over non-droppable or over options panel
169
+ handleDragCancel();
170
+ return;
171
+ }
172
+
173
+ const item = {
174
+ id: active.id,
175
+ sourceContainerId: active.data.current.sortable.containerId,
176
+ sourceIndex: active.data.current.sortable.index,
177
+ data: {
178
+ label: active.data.current.label,
179
+ value: active.data.current.value,
180
+ type: active.data.current.type
181
+ }
182
+ };
183
+ const destination = {
184
+ containerId: ((_over$data$current2 = over.data.current) === null || _over$data$current2 === void 0 ? void 0 : _over$data$current2.sortable.containerId) || over.id,
185
+ index: (_over$data$current3 = over.data.current) === null || _over$data$current3 === void 0 ? void 0 : _over$data$current3.sortable.index
186
+ };
187
+ onDragEnd({
188
+ item,
189
+ destination
190
+ });
191
+ setDraggingItem(null);
192
+ };
193
+
194
+ return /*#__PURE__*/_react.default.createElement(_core.DndContext, {
195
+ collisionDetection: rectIntersectionCustom,
196
+ onDragStart: handleDragStart,
197
+ onDragEnd: handleDragEnd,
198
+ onDragCancel: handleDragCancel,
199
+ sensors: sensors
200
+ }, children, /*#__PURE__*/_react.default.createElement(_core.DragOverlay, {
201
+ dropAnimation: null
202
+ }, draggingItem ? /*#__PURE__*/_react.default.createElement("span", {
203
+ className: "dragOverlay"
204
+ }, /*#__PURE__*/_react.default.createElement(_DraggingItem.default, draggingItem)) : null));
205
+ };
206
+
207
+ OuterDndContext.propTypes = {
208
+ onDragEnd: _propTypes.default.func.isRequired,
209
+ children: _propTypes.default.node,
210
+ onDragStart: _propTypes.default.func
211
+ };
212
+ var _default = OuterDndContext;
213
+ exports.default = _default;
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+
8
+ var _react = _interopRequireDefault(require("react"));
9
+
10
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
11
+
12
+ var _default = /*#__PURE__*/_react.default.createElement("svg", {
13
+ height: "16",
14
+ viewBox: "0 0 16 16",
15
+ width: "16",
16
+ xmlns: "http://www.w3.org/2000/svg"
17
+ }, /*#__PURE__*/_react.default.createElement("path", {
18
+ d: "M6 11a1 1 0 110 2 1 1 0 010-2zm4 0a1 1 0 110 2 1 1 0 010-2zM6 7a1 1 0 110 2 1 1 0 010-2zm4 0a1 1 0 110 2 1 1 0 010-2zM6 3a1 1 0 110 2 1 1 0 010-2zm4 0a1 1 0 110 2 1 1 0 010-2z",
19
+ fill: "#A0ADBA",
20
+ fillRule: "evenodd"
21
+ }));
22
+
23
+ exports.default = _default;
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+
8
+ var _style = _interopRequireDefault(require("styled-jsx/style"));
9
+
10
+ var _classnames = _interopRequireDefault(require("classnames"));
11
+
12
+ var _propTypes = _interopRequireDefault(require("prop-types"));
13
+
14
+ var _react = _interopRequireDefault(require("react"));
15
+
16
+ var _dataTypes = require("../../../modules/dataTypes.js");
17
+
18
+ var _dimensionListItem = require("../../../modules/dimensionListItem.js");
19
+
20
+ var _expressions = require("../../../modules/expressions.js");
21
+
22
+ var _DraggingItemStyle = _interopRequireDefault(require("./styles/DraggingItem.style.js"));
23
+
24
+ var _FormulaItemStyle = _interopRequireDefault(require("./styles/FormulaItem.style.js"));
25
+
26
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
27
+
28
+ const DraggingItem = _ref => {
29
+ let {
30
+ label,
31
+ type,
32
+ value
33
+ } = _ref;
34
+ const displayLabel = type === _expressions.EXPRESSION_TYPE_NUMBER ? value || label : label;
35
+ return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("div", {
36
+ className: "jsx-".concat(_DraggingItemStyle.default.__hash, " jsx-").concat(_FormulaItemStyle.default.__hash) + " " + ((0, _classnames.default)('dragging', 'content', {
37
+ operator: type === _expressions.EXPRESSION_TYPE_OPERATOR,
38
+ number: type === _expressions.EXPRESSION_TYPE_NUMBER,
39
+ data: type === _expressions.EXPRESSION_TYPE_DATA
40
+ }) || "")
41
+ }, type === _expressions.EXPRESSION_TYPE_DATA && /*#__PURE__*/_react.default.createElement("span", {
42
+ className: "jsx-".concat(_DraggingItemStyle.default.__hash, " jsx-").concat(_FormulaItemStyle.default.__hash) + " " + "icon"
43
+ }, (0, _dimensionListItem.getIcon)(_dataTypes.DIMENSION_TYPE_DATA_ELEMENT)), /*#__PURE__*/_react.default.createElement("span", {
44
+ className: "jsx-".concat(_DraggingItemStyle.default.__hash, " jsx-").concat(_FormulaItemStyle.default.__hash) + " " + "label"
45
+ }, displayLabel)), /*#__PURE__*/_react.default.createElement(_style.default, {
46
+ id: _DraggingItemStyle.default.__hash
47
+ }, _DraggingItemStyle.default), /*#__PURE__*/_react.default.createElement(_style.default, {
48
+ id: _FormulaItemStyle.default.__hash
49
+ }, _FormulaItemStyle.default));
50
+ };
51
+
52
+ DraggingItem.propTypes = {
53
+ label: _propTypes.default.string,
54
+ type: _propTypes.default.string,
55
+ value: _propTypes.default.string
56
+ };
57
+ var _default = DraggingItem;
58
+ exports.default = _default;
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+
8
+ var _style = _interopRequireDefault(require("styled-jsx/style"));
9
+
10
+ var _core = require("@dnd-kit/core");
11
+
12
+ var _classnames = _interopRequireDefault(require("classnames"));
13
+
14
+ var _propTypes = _interopRequireDefault(require("prop-types"));
15
+
16
+ var _react = _interopRequireDefault(require("react"));
17
+
18
+ var _DropZoneStyle = _interopRequireDefault(require("./styles/DropZone.style.js"));
19
+
20
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
21
+
22
+ const DropZone = _ref => {
23
+ let {
24
+ firstElementId,
25
+ overLastDropZone
26
+ } = _ref;
27
+ const {
28
+ isOver,
29
+ setNodeRef,
30
+ active
31
+ } = (0, _core.useDroppable)({
32
+ id: 'firstdropzone'
33
+ });
34
+ let draggingOver = false;
35
+
36
+ if (overLastDropZone && !firstElementId) {
37
+ draggingOver = true;
38
+ } else {
39
+ draggingOver = firstElementId === (active === null || active === void 0 ? void 0 : active.id) ? false : isOver;
40
+ }
41
+
42
+ return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("div", {
43
+ ref: setNodeRef,
44
+ className: "jsx-".concat(_DropZoneStyle.default.__hash) + " " + ((0, _classnames.default)('first-dropzone', {
45
+ 'dragging-over': draggingOver,
46
+ empty: !firstElementId
47
+ }) || "")
48
+ }), /*#__PURE__*/_react.default.createElement(_style.default, {
49
+ id: _DropZoneStyle.default.__hash
50
+ }, _DropZoneStyle.default));
51
+ };
52
+
53
+ DropZone.propTypes = {
54
+ firstElementId: _propTypes.default.string,
55
+ overLastDropZone: _propTypes.default.bool
56
+ };
57
+ var _default = DropZone;
58
+ exports.default = _default;