@hrforte/react-pivottable 1.0.0 → 1.0.1
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/dist/PivotTable.js +72 -0
- package/dist/PivotTable.js.map +1 -0
- package/dist/PivotTableUI.js +1846 -0
- package/dist/PivotTableUI.js.map +1 -0
- package/dist/PlotlyRenderers.js +822 -0
- package/dist/PlotlyRenderers.js.map +1 -0
- package/dist/TableRenderers.js +1067 -0
- package/dist/TableRenderers.js.map +1 -0
- package/dist/Utilities.js +1476 -0
- package/dist/Utilities.js.map +1 -0
- package/dist/__tests__/Utilities-test.js +571 -0
- package/dist/__tests__/Utilities-test.js.map +1 -0
- package/dist/pivottable.css +377 -0
- package/package.json +4 -16
|
@@ -0,0 +1,1846 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.CellFormattingUI = exports.ConditionalFormattingUI = exports.Dropdown = exports.DraggableAttribute = undefined;
|
|
7
|
+
|
|
8
|
+
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
|
|
9
|
+
|
|
10
|
+
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
11
|
+
|
|
12
|
+
var _react = require('react');
|
|
13
|
+
|
|
14
|
+
var _react2 = _interopRequireDefault(_react);
|
|
15
|
+
|
|
16
|
+
var _propTypes = require('prop-types');
|
|
17
|
+
|
|
18
|
+
var _propTypes2 = _interopRequireDefault(_propTypes);
|
|
19
|
+
|
|
20
|
+
var _immutabilityHelper = require('immutability-helper');
|
|
21
|
+
|
|
22
|
+
var _immutabilityHelper2 = _interopRequireDefault(_immutabilityHelper);
|
|
23
|
+
|
|
24
|
+
var _Utilities = require('./Utilities');
|
|
25
|
+
|
|
26
|
+
var _PivotTable = require('./PivotTable');
|
|
27
|
+
|
|
28
|
+
var _PivotTable2 = _interopRequireDefault(_PivotTable);
|
|
29
|
+
|
|
30
|
+
var _reactSortablejs = require('react-sortablejs');
|
|
31
|
+
|
|
32
|
+
var _reactSortablejs2 = _interopRequireDefault(_reactSortablejs);
|
|
33
|
+
|
|
34
|
+
var _reactDraggable = require('react-draggable');
|
|
35
|
+
|
|
36
|
+
var _reactDraggable2 = _interopRequireDefault(_reactDraggable);
|
|
37
|
+
|
|
38
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
39
|
+
|
|
40
|
+
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; }
|
|
41
|
+
|
|
42
|
+
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
43
|
+
|
|
44
|
+
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
|
|
45
|
+
|
|
46
|
+
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
|
47
|
+
|
|
48
|
+
var AGG_KEY_RADIX = 36;
|
|
49
|
+
var AGG_KEY_OFFSET = 2;
|
|
50
|
+
var AGG_KEY_LENGTH = 7;
|
|
51
|
+
|
|
52
|
+
/* eslint-disable react/prop-types */
|
|
53
|
+
// eslint can't see inherited propTypes!
|
|
54
|
+
|
|
55
|
+
var DraggableAttribute = exports.DraggableAttribute = function (_React$Component) {
|
|
56
|
+
_inherits(DraggableAttribute, _React$Component);
|
|
57
|
+
|
|
58
|
+
function DraggableAttribute(props) {
|
|
59
|
+
_classCallCheck(this, DraggableAttribute);
|
|
60
|
+
|
|
61
|
+
var _this = _possibleConstructorReturn(this, (DraggableAttribute.__proto__ || Object.getPrototypeOf(DraggableAttribute)).call(this, props));
|
|
62
|
+
|
|
63
|
+
_this.state = { open: false, filterText: '' };
|
|
64
|
+
return _this;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
_createClass(DraggableAttribute, [{
|
|
68
|
+
key: 'toggleValue',
|
|
69
|
+
value: function toggleValue(value) {
|
|
70
|
+
if (value in this.props.valueFilter) {
|
|
71
|
+
this.props.removeValuesFromFilter(this.props.name, [value]);
|
|
72
|
+
} else {
|
|
73
|
+
this.props.addValuesToFilter(this.props.name, [value]);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}, {
|
|
77
|
+
key: 'matchesFilter',
|
|
78
|
+
value: function matchesFilter(x) {
|
|
79
|
+
return x.toLowerCase().trim().includes(this.state.filterText.toLowerCase().trim());
|
|
80
|
+
}
|
|
81
|
+
}, {
|
|
82
|
+
key: 'selectOnly',
|
|
83
|
+
value: function selectOnly(e, value) {
|
|
84
|
+
e.stopPropagation();
|
|
85
|
+
this.props.setValuesInFilter(this.props.name, Object.keys(this.props.attrValues).filter(function (y) {
|
|
86
|
+
return y !== value;
|
|
87
|
+
}));
|
|
88
|
+
}
|
|
89
|
+
}, {
|
|
90
|
+
key: 'getFilterBox',
|
|
91
|
+
value: function getFilterBox() {
|
|
92
|
+
var _this2 = this;
|
|
93
|
+
|
|
94
|
+
var showMenu = Object.keys(this.props.attrValues).length < this.props.menuLimit;
|
|
95
|
+
|
|
96
|
+
var values = Object.keys(this.props.attrValues);
|
|
97
|
+
var shown = values.filter(this.matchesFilter.bind(this)).sort(this.props.sorter);
|
|
98
|
+
|
|
99
|
+
return _react2.default.createElement(
|
|
100
|
+
_reactDraggable2.default,
|
|
101
|
+
{ handle: '.pvtDragHandle' },
|
|
102
|
+
_react2.default.createElement(
|
|
103
|
+
'div',
|
|
104
|
+
{
|
|
105
|
+
className: 'pvtFilterBox',
|
|
106
|
+
style: {
|
|
107
|
+
display: 'block',
|
|
108
|
+
cursor: 'initial',
|
|
109
|
+
zIndex: this.props.zIndex
|
|
110
|
+
},
|
|
111
|
+
onClick: function onClick() {
|
|
112
|
+
return _this2.props.moveFilterBoxToTop(_this2.props.name);
|
|
113
|
+
}
|
|
114
|
+
},
|
|
115
|
+
_react2.default.createElement(
|
|
116
|
+
'a',
|
|
117
|
+
{ onClick: function onClick() {
|
|
118
|
+
return _this2.setState({ open: false });
|
|
119
|
+
}, className: 'pvtCloseX' },
|
|
120
|
+
'\xD7'
|
|
121
|
+
),
|
|
122
|
+
_react2.default.createElement(
|
|
123
|
+
'span',
|
|
124
|
+
{ className: 'pvtDragHandle' },
|
|
125
|
+
'\u2630'
|
|
126
|
+
),
|
|
127
|
+
_react2.default.createElement(
|
|
128
|
+
'h4',
|
|
129
|
+
null,
|
|
130
|
+
this.props.name
|
|
131
|
+
),
|
|
132
|
+
showMenu || _react2.default.createElement(
|
|
133
|
+
'p',
|
|
134
|
+
null,
|
|
135
|
+
'(too many values to show)'
|
|
136
|
+
),
|
|
137
|
+
showMenu && _react2.default.createElement(
|
|
138
|
+
'p',
|
|
139
|
+
null,
|
|
140
|
+
_react2.default.createElement('input', {
|
|
141
|
+
type: 'text',
|
|
142
|
+
placeholder: 'Filter values',
|
|
143
|
+
className: 'pvtSearch',
|
|
144
|
+
value: this.state.filterText,
|
|
145
|
+
onChange: function onChange(e) {
|
|
146
|
+
return _this2.setState({
|
|
147
|
+
filterText: e.target.value
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
}),
|
|
151
|
+
_react2.default.createElement('br', null),
|
|
152
|
+
_react2.default.createElement(
|
|
153
|
+
'a',
|
|
154
|
+
{
|
|
155
|
+
role: 'button',
|
|
156
|
+
className: 'pvtButton',
|
|
157
|
+
onClick: function onClick() {
|
|
158
|
+
return _this2.props.removeValuesFromFilter(_this2.props.name, Object.keys(_this2.props.attrValues).filter(_this2.matchesFilter.bind(_this2)));
|
|
159
|
+
}
|
|
160
|
+
},
|
|
161
|
+
'Select ',
|
|
162
|
+
values.length === shown.length ? 'All' : shown.length
|
|
163
|
+
),
|
|
164
|
+
' ',
|
|
165
|
+
_react2.default.createElement(
|
|
166
|
+
'a',
|
|
167
|
+
{
|
|
168
|
+
role: 'button',
|
|
169
|
+
className: 'pvtButton',
|
|
170
|
+
onClick: function onClick() {
|
|
171
|
+
return _this2.props.addValuesToFilter(_this2.props.name, Object.keys(_this2.props.attrValues).filter(_this2.matchesFilter.bind(_this2)));
|
|
172
|
+
}
|
|
173
|
+
},
|
|
174
|
+
'Deselect ',
|
|
175
|
+
values.length === shown.length ? 'All' : shown.length
|
|
176
|
+
)
|
|
177
|
+
),
|
|
178
|
+
showMenu && _react2.default.createElement(
|
|
179
|
+
'div',
|
|
180
|
+
{ className: 'pvtCheckContainer' },
|
|
181
|
+
shown.map(function (x) {
|
|
182
|
+
return _react2.default.createElement(
|
|
183
|
+
'p',
|
|
184
|
+
{
|
|
185
|
+
key: x,
|
|
186
|
+
onClick: function onClick() {
|
|
187
|
+
return _this2.toggleValue(x);
|
|
188
|
+
},
|
|
189
|
+
className: x in _this2.props.valueFilter ? '' : 'selected'
|
|
190
|
+
},
|
|
191
|
+
_react2.default.createElement(
|
|
192
|
+
'a',
|
|
193
|
+
{ className: 'pvtOnly', onClick: function onClick(e) {
|
|
194
|
+
return _this2.selectOnly(e, x);
|
|
195
|
+
} },
|
|
196
|
+
'only'
|
|
197
|
+
),
|
|
198
|
+
_react2.default.createElement(
|
|
199
|
+
'a',
|
|
200
|
+
{ className: 'pvtOnlySpacer' },
|
|
201
|
+
'\xA0'
|
|
202
|
+
),
|
|
203
|
+
x === '' ? _react2.default.createElement(
|
|
204
|
+
'em',
|
|
205
|
+
null,
|
|
206
|
+
'null'
|
|
207
|
+
) : x
|
|
208
|
+
);
|
|
209
|
+
})
|
|
210
|
+
)
|
|
211
|
+
)
|
|
212
|
+
);
|
|
213
|
+
}
|
|
214
|
+
}, {
|
|
215
|
+
key: 'toggleFilterBox',
|
|
216
|
+
value: function toggleFilterBox() {
|
|
217
|
+
this.setState({ open: !this.state.open });
|
|
218
|
+
this.props.moveFilterBoxToTop(this.props.name);
|
|
219
|
+
}
|
|
220
|
+
}, {
|
|
221
|
+
key: 'render',
|
|
222
|
+
value: function render() {
|
|
223
|
+
var filtered = Object.keys(this.props.valueFilter).length !== 0 ? 'pvtFilteredAttribute' : '';
|
|
224
|
+
return _react2.default.createElement(
|
|
225
|
+
'li',
|
|
226
|
+
{ 'data-id': this.props.name },
|
|
227
|
+
_react2.default.createElement(
|
|
228
|
+
'span',
|
|
229
|
+
{ className: 'pvtAttr ' + filtered },
|
|
230
|
+
this.props.name,
|
|
231
|
+
_react2.default.createElement(
|
|
232
|
+
'span',
|
|
233
|
+
{
|
|
234
|
+
className: 'pvtTriangle',
|
|
235
|
+
onClick: this.toggleFilterBox.bind(this)
|
|
236
|
+
},
|
|
237
|
+
' ',
|
|
238
|
+
'\u25BE'
|
|
239
|
+
)
|
|
240
|
+
),
|
|
241
|
+
this.state.open ? this.getFilterBox() : null
|
|
242
|
+
);
|
|
243
|
+
}
|
|
244
|
+
}]);
|
|
245
|
+
|
|
246
|
+
return DraggableAttribute;
|
|
247
|
+
}(_react2.default.Component);
|
|
248
|
+
|
|
249
|
+
DraggableAttribute.defaultProps = {
|
|
250
|
+
valueFilter: {}
|
|
251
|
+
};
|
|
252
|
+
|
|
253
|
+
DraggableAttribute.propTypes = {
|
|
254
|
+
name: _propTypes2.default.string.isRequired,
|
|
255
|
+
addValuesToFilter: _propTypes2.default.func.isRequired,
|
|
256
|
+
removeValuesFromFilter: _propTypes2.default.func.isRequired,
|
|
257
|
+
attrValues: _propTypes2.default.objectOf(_propTypes2.default.number).isRequired,
|
|
258
|
+
valueFilter: _propTypes2.default.objectOf(_propTypes2.default.bool),
|
|
259
|
+
moveFilterBoxToTop: _propTypes2.default.func.isRequired,
|
|
260
|
+
sorter: _propTypes2.default.func.isRequired,
|
|
261
|
+
menuLimit: _propTypes2.default.number,
|
|
262
|
+
zIndex: _propTypes2.default.number
|
|
263
|
+
};
|
|
264
|
+
|
|
265
|
+
var Dropdown = exports.Dropdown = function (_React$PureComponent) {
|
|
266
|
+
_inherits(Dropdown, _React$PureComponent);
|
|
267
|
+
|
|
268
|
+
function Dropdown() {
|
|
269
|
+
_classCallCheck(this, Dropdown);
|
|
270
|
+
|
|
271
|
+
return _possibleConstructorReturn(this, (Dropdown.__proto__ || Object.getPrototypeOf(Dropdown)).apply(this, arguments));
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
_createClass(Dropdown, [{
|
|
275
|
+
key: 'render',
|
|
276
|
+
value: function render() {
|
|
277
|
+
var _this4 = this;
|
|
278
|
+
|
|
279
|
+
return _react2.default.createElement(
|
|
280
|
+
'div',
|
|
281
|
+
{ className: 'pvtDropdown', style: { zIndex: this.props.zIndex } },
|
|
282
|
+
_react2.default.createElement(
|
|
283
|
+
'div',
|
|
284
|
+
{
|
|
285
|
+
onClick: function onClick(e) {
|
|
286
|
+
e.stopPropagation();
|
|
287
|
+
_this4.props.toggle();
|
|
288
|
+
},
|
|
289
|
+
className: 'pvtDropdownValue pvtDropdownCurrent ' + (this.props.open ? 'pvtDropdownCurrentOpen' : ''),
|
|
290
|
+
role: 'button'
|
|
291
|
+
},
|
|
292
|
+
_react2.default.createElement(
|
|
293
|
+
'div',
|
|
294
|
+
{ className: 'pvtDropdownIcon' },
|
|
295
|
+
this.props.open ? '×' : '▾'
|
|
296
|
+
),
|
|
297
|
+
this.props.current || _react2.default.createElement(
|
|
298
|
+
'span',
|
|
299
|
+
null,
|
|
300
|
+
'\xA0'
|
|
301
|
+
)
|
|
302
|
+
),
|
|
303
|
+
this.props.open && _react2.default.createElement(
|
|
304
|
+
'div',
|
|
305
|
+
{ className: 'pvtDropdownMenu' },
|
|
306
|
+
this.props.values.map(function (r) {
|
|
307
|
+
return _react2.default.createElement(
|
|
308
|
+
'div',
|
|
309
|
+
{
|
|
310
|
+
key: r,
|
|
311
|
+
role: 'button',
|
|
312
|
+
onClick: function onClick(e) {
|
|
313
|
+
e.stopPropagation();
|
|
314
|
+
if (_this4.props.current === r) {
|
|
315
|
+
_this4.props.toggle();
|
|
316
|
+
} else {
|
|
317
|
+
_this4.props.setValue(r);
|
|
318
|
+
}
|
|
319
|
+
},
|
|
320
|
+
className: 'pvtDropdownValue ' + (r === _this4.props.current ? 'pvtDropdownActiveValue' : '')
|
|
321
|
+
},
|
|
322
|
+
r
|
|
323
|
+
);
|
|
324
|
+
})
|
|
325
|
+
)
|
|
326
|
+
);
|
|
327
|
+
}
|
|
328
|
+
}]);
|
|
329
|
+
|
|
330
|
+
return Dropdown;
|
|
331
|
+
}(_react2.default.PureComponent);
|
|
332
|
+
|
|
333
|
+
var ConditionalFormattingUI = exports.ConditionalFormattingUI = function (_React$Component2) {
|
|
334
|
+
_inherits(ConditionalFormattingUI, _React$Component2);
|
|
335
|
+
|
|
336
|
+
function ConditionalFormattingUI(props) {
|
|
337
|
+
_classCallCheck(this, ConditionalFormattingUI);
|
|
338
|
+
|
|
339
|
+
var _this5 = _possibleConstructorReturn(this, (ConditionalFormattingUI.__proto__ || Object.getPrototypeOf(ConditionalFormattingUI)).call(this, props));
|
|
340
|
+
|
|
341
|
+
_this5.state = {
|
|
342
|
+
open: false
|
|
343
|
+
};
|
|
344
|
+
return _this5;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
_createClass(ConditionalFormattingUI, [{
|
|
348
|
+
key: 'getConditionalFormatting',
|
|
349
|
+
value: function getConditionalFormatting() {
|
|
350
|
+
var tableOptions = this.props.tableOptions || {};
|
|
351
|
+
return tableOptions.conditionalFormatting ? tableOptions.conditionalFormatting : { rules: [] };
|
|
352
|
+
}
|
|
353
|
+
}, {
|
|
354
|
+
key: 'updateConditionalFormatting',
|
|
355
|
+
value: function updateConditionalFormatting(conditionalFormatting) {
|
|
356
|
+
var currentTableOptions = this.props.tableOptions || {};
|
|
357
|
+
var tableOptions = Object.assign({}, currentTableOptions, {
|
|
358
|
+
conditionalFormatting: conditionalFormatting
|
|
359
|
+
});
|
|
360
|
+
this.props.onChange({
|
|
361
|
+
tableOptions: { $set: tableOptions }
|
|
362
|
+
});
|
|
363
|
+
}
|
|
364
|
+
}, {
|
|
365
|
+
key: 'addRule',
|
|
366
|
+
value: function addRule() {
|
|
367
|
+
var cf = this.getConditionalFormatting();
|
|
368
|
+
var newRule = {
|
|
369
|
+
condition: {
|
|
370
|
+
type: 'greaterThan',
|
|
371
|
+
value: 0
|
|
372
|
+
},
|
|
373
|
+
style: {
|
|
374
|
+
backgroundColor: '#FFFFE0'
|
|
375
|
+
}
|
|
376
|
+
};
|
|
377
|
+
this.updateConditionalFormatting({
|
|
378
|
+
rules: cf.rules.slice().concat([newRule])
|
|
379
|
+
});
|
|
380
|
+
}
|
|
381
|
+
}, {
|
|
382
|
+
key: 'removeRule',
|
|
383
|
+
value: function removeRule(index) {
|
|
384
|
+
var cf = this.getConditionalFormatting();
|
|
385
|
+
var newRules = cf.rules.filter(function (_, i) {
|
|
386
|
+
return i !== index;
|
|
387
|
+
});
|
|
388
|
+
this.updateConditionalFormatting({
|
|
389
|
+
rules: newRules
|
|
390
|
+
});
|
|
391
|
+
}
|
|
392
|
+
}, {
|
|
393
|
+
key: 'updateRule',
|
|
394
|
+
value: function updateRule(index, field, value) {
|
|
395
|
+
var cf = this.getConditionalFormatting();
|
|
396
|
+
var newRules = cf.rules.slice();
|
|
397
|
+
if (field.startsWith('condition.')) {
|
|
398
|
+
var conditionField = field.replace('condition.', '');
|
|
399
|
+
var newCondition = Object.assign({}, newRules[index].condition);
|
|
400
|
+
if (value === null) {
|
|
401
|
+
delete newCondition[conditionField];
|
|
402
|
+
} else {
|
|
403
|
+
newCondition[conditionField] = value;
|
|
404
|
+
}
|
|
405
|
+
newRules[index] = Object.assign({}, newRules[index], {
|
|
406
|
+
condition: newCondition
|
|
407
|
+
});
|
|
408
|
+
} else if (field.startsWith('style.')) {
|
|
409
|
+
var styleField = field.replace('style.', '');
|
|
410
|
+
var newStyle = Object.assign({}, newRules[index].style || {});
|
|
411
|
+
if (value === null || value === '') {
|
|
412
|
+
delete newStyle[styleField];
|
|
413
|
+
} else {
|
|
414
|
+
newStyle[styleField] = value;
|
|
415
|
+
}
|
|
416
|
+
newRules[index] = Object.assign({}, newRules[index], {
|
|
417
|
+
style: newStyle
|
|
418
|
+
});
|
|
419
|
+
}
|
|
420
|
+
this.updateConditionalFormatting({
|
|
421
|
+
rules: newRules
|
|
422
|
+
});
|
|
423
|
+
}
|
|
424
|
+
}, {
|
|
425
|
+
key: 'toggle',
|
|
426
|
+
value: function toggle() {
|
|
427
|
+
this.setState({ open: !this.state.open });
|
|
428
|
+
if (this.props.moveToTop) {
|
|
429
|
+
this.props.moveToTop();
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
}, {
|
|
433
|
+
key: 'render',
|
|
434
|
+
value: function render() {
|
|
435
|
+
var _this6 = this;
|
|
436
|
+
|
|
437
|
+
var cf = this.getConditionalFormatting();
|
|
438
|
+
var conditionTypes = [{ value: 'greaterThan', label: 'Greater Than' }, { value: 'lessThan', label: 'Less Than' }, { value: 'greaterThanOrEqual', label: 'Greater Than Or Equal' }, { value: 'lessThanOrEqual', label: 'Less Than Or Equal' }, { value: 'equal', label: 'Equal' }, { value: 'notEqual', label: 'Not Equal' }, { value: 'empty', label: 'Empty' }, { value: 'notEmpty', label: 'Not Empty' }, { value: 'contains', label: 'Contains' }, { value: 'notContains', label: 'Not Contains' }];
|
|
439
|
+
|
|
440
|
+
var needsValue = function needsValue(type) {
|
|
441
|
+
return !['empty', 'notEmpty'].includes(type);
|
|
442
|
+
};
|
|
443
|
+
|
|
444
|
+
return _react2.default.createElement(
|
|
445
|
+
'div',
|
|
446
|
+
null,
|
|
447
|
+
_react2.default.createElement(
|
|
448
|
+
'button',
|
|
449
|
+
{
|
|
450
|
+
type: 'button',
|
|
451
|
+
className: 'pvtButton',
|
|
452
|
+
onClick: function onClick(e) {
|
|
453
|
+
e.stopPropagation();
|
|
454
|
+
_this6.toggle();
|
|
455
|
+
},
|
|
456
|
+
style: { marginTop: '5px' }
|
|
457
|
+
},
|
|
458
|
+
this.state.open ? '▼' : '▶',
|
|
459
|
+
' Conditional Formatting'
|
|
460
|
+
),
|
|
461
|
+
this.state.open && _react2.default.createElement(
|
|
462
|
+
'div',
|
|
463
|
+
{
|
|
464
|
+
className: 'pvtFilterBox',
|
|
465
|
+
style: {
|
|
466
|
+
display: 'block',
|
|
467
|
+
cursor: 'initial',
|
|
468
|
+
zIndex: this.props.zIndex,
|
|
469
|
+
marginTop: '5px',
|
|
470
|
+
minWidth: '400px',
|
|
471
|
+
position: 'relative'
|
|
472
|
+
},
|
|
473
|
+
onClick: function onClick() {
|
|
474
|
+
return _this6.props.moveToTop && _this6.props.moveToTop();
|
|
475
|
+
}
|
|
476
|
+
},
|
|
477
|
+
_react2.default.createElement(
|
|
478
|
+
'a',
|
|
479
|
+
{
|
|
480
|
+
onClick: function onClick() {
|
|
481
|
+
return _this6.setState({ open: false });
|
|
482
|
+
},
|
|
483
|
+
className: 'pvtCloseX'
|
|
484
|
+
},
|
|
485
|
+
'\xD7'
|
|
486
|
+
),
|
|
487
|
+
_react2.default.createElement(
|
|
488
|
+
'h4',
|
|
489
|
+
null,
|
|
490
|
+
'Conditional Formatting Rules'
|
|
491
|
+
),
|
|
492
|
+
cf.rules.length === 0 && _react2.default.createElement(
|
|
493
|
+
'p',
|
|
494
|
+
{ style: { fontStyle: 'italic', color: '#666' } },
|
|
495
|
+
'No rules defined. Add a rule to format cells based on conditions.'
|
|
496
|
+
),
|
|
497
|
+
cf.rules.map(function (rule, index) {
|
|
498
|
+
return _react2.default.createElement(
|
|
499
|
+
'div',
|
|
500
|
+
{
|
|
501
|
+
key: index,
|
|
502
|
+
style: {
|
|
503
|
+
border: '1px solid #c8d4e3',
|
|
504
|
+
padding: '10px',
|
|
505
|
+
marginBottom: '10px',
|
|
506
|
+
backgroundColor: '#f9f9f9'
|
|
507
|
+
}
|
|
508
|
+
},
|
|
509
|
+
_react2.default.createElement(
|
|
510
|
+
'div',
|
|
511
|
+
{
|
|
512
|
+
style: {
|
|
513
|
+
display: 'flex',
|
|
514
|
+
justifyContent: 'space-between',
|
|
515
|
+
marginBottom: '8px'
|
|
516
|
+
}
|
|
517
|
+
},
|
|
518
|
+
_react2.default.createElement(
|
|
519
|
+
'strong',
|
|
520
|
+
null,
|
|
521
|
+
'Rule ',
|
|
522
|
+
index + 1
|
|
523
|
+
),
|
|
524
|
+
_react2.default.createElement(
|
|
525
|
+
'button',
|
|
526
|
+
{
|
|
527
|
+
type: 'button',
|
|
528
|
+
className: 'pvtButton',
|
|
529
|
+
onClick: function onClick(e) {
|
|
530
|
+
e.stopPropagation();
|
|
531
|
+
_this6.removeRule(index);
|
|
532
|
+
},
|
|
533
|
+
style: { fontSize: '10px', padding: '2px 6px' }
|
|
534
|
+
},
|
|
535
|
+
'Remove'
|
|
536
|
+
)
|
|
537
|
+
),
|
|
538
|
+
_react2.default.createElement(
|
|
539
|
+
'div',
|
|
540
|
+
{
|
|
541
|
+
style: { marginBottom: '8px' },
|
|
542
|
+
onClick: function onClick(e) {
|
|
543
|
+
return e.stopPropagation();
|
|
544
|
+
},
|
|
545
|
+
onMouseDown: function onMouseDown(e) {
|
|
546
|
+
return e.stopPropagation();
|
|
547
|
+
}
|
|
548
|
+
},
|
|
549
|
+
_react2.default.createElement(
|
|
550
|
+
'label',
|
|
551
|
+
{
|
|
552
|
+
style: {
|
|
553
|
+
display: 'block',
|
|
554
|
+
marginBottom: '4px',
|
|
555
|
+
fontSize: '11px'
|
|
556
|
+
}
|
|
557
|
+
},
|
|
558
|
+
'Condition Type:'
|
|
559
|
+
),
|
|
560
|
+
_react2.default.createElement(
|
|
561
|
+
'select',
|
|
562
|
+
{
|
|
563
|
+
value: rule.condition.type || 'greaterThan',
|
|
564
|
+
onChange: function onChange(e) {
|
|
565
|
+
e.stopPropagation();
|
|
566
|
+
var newType = e.target.value;
|
|
567
|
+
var cf = _this6.getConditionalFormatting();
|
|
568
|
+
var newRules = cf.rules.slice();
|
|
569
|
+
var newCondition = Object.assign({}, newRules[index].condition, {
|
|
570
|
+
type: newType
|
|
571
|
+
});
|
|
572
|
+
// Remove value field if condition type doesn't need it
|
|
573
|
+
if (!needsValue(newType)) {
|
|
574
|
+
delete newCondition.value;
|
|
575
|
+
}
|
|
576
|
+
newRules[index] = Object.assign({}, newRules[index], {
|
|
577
|
+
condition: newCondition
|
|
578
|
+
});
|
|
579
|
+
_this6.updateConditionalFormatting({
|
|
580
|
+
rules: newRules
|
|
581
|
+
});
|
|
582
|
+
},
|
|
583
|
+
style: { width: '100%', padding: '4px' }
|
|
584
|
+
},
|
|
585
|
+
conditionTypes.map(function (ct) {
|
|
586
|
+
return _react2.default.createElement(
|
|
587
|
+
'option',
|
|
588
|
+
{ key: ct.value, value: ct.value },
|
|
589
|
+
ct.label
|
|
590
|
+
);
|
|
591
|
+
})
|
|
592
|
+
)
|
|
593
|
+
),
|
|
594
|
+
needsValue(rule.condition.type) && _react2.default.createElement(
|
|
595
|
+
'div',
|
|
596
|
+
{ style: { marginBottom: '8px' } },
|
|
597
|
+
_react2.default.createElement(
|
|
598
|
+
'label',
|
|
599
|
+
{
|
|
600
|
+
style: {
|
|
601
|
+
display: 'block',
|
|
602
|
+
marginBottom: '4px',
|
|
603
|
+
fontSize: '11px'
|
|
604
|
+
}
|
|
605
|
+
},
|
|
606
|
+
'Condition Value:'
|
|
607
|
+
),
|
|
608
|
+
_react2.default.createElement('input', {
|
|
609
|
+
type: 'text',
|
|
610
|
+
value: typeof rule.condition.value !== 'undefined' && rule.condition.value !== null ? rule.condition.value : '',
|
|
611
|
+
onChange: function onChange(e) {
|
|
612
|
+
e.stopPropagation();
|
|
613
|
+
var val = e.target.value;
|
|
614
|
+
// Try to parse as number, otherwise use as string
|
|
615
|
+
var numVal = val === '' ? null : isNaN(val) ? val : parseFloat(val);
|
|
616
|
+
_this6.updateRule(index, 'condition.value', numVal);
|
|
617
|
+
},
|
|
618
|
+
placeholder: 'Enter value',
|
|
619
|
+
style: { width: '100%', padding: '4px' }
|
|
620
|
+
})
|
|
621
|
+
),
|
|
622
|
+
_react2.default.createElement(
|
|
623
|
+
'div',
|
|
624
|
+
{ style: { marginBottom: '8px' } },
|
|
625
|
+
_react2.default.createElement(
|
|
626
|
+
'label',
|
|
627
|
+
{
|
|
628
|
+
style: {
|
|
629
|
+
display: 'block',
|
|
630
|
+
marginBottom: '4px',
|
|
631
|
+
fontSize: '11px'
|
|
632
|
+
}
|
|
633
|
+
},
|
|
634
|
+
'Background Color:'
|
|
635
|
+
),
|
|
636
|
+
_react2.default.createElement('input', {
|
|
637
|
+
type: 'color',
|
|
638
|
+
value: rule.style && rule.style.backgroundColor ? rule.style.backgroundColor : '#FFFFFF',
|
|
639
|
+
onChange: function onChange(e) {
|
|
640
|
+
e.stopPropagation();
|
|
641
|
+
_this6.updateRule(index, 'style.backgroundColor', e.target.value);
|
|
642
|
+
},
|
|
643
|
+
style: { width: '100%', padding: '2px' }
|
|
644
|
+
})
|
|
645
|
+
),
|
|
646
|
+
_react2.default.createElement(
|
|
647
|
+
'div',
|
|
648
|
+
{ style: { marginBottom: '8px' } },
|
|
649
|
+
_react2.default.createElement(
|
|
650
|
+
'label',
|
|
651
|
+
{
|
|
652
|
+
style: {
|
|
653
|
+
display: 'block',
|
|
654
|
+
marginBottom: '4px',
|
|
655
|
+
fontSize: '11px'
|
|
656
|
+
}
|
|
657
|
+
},
|
|
658
|
+
'Text Color:'
|
|
659
|
+
),
|
|
660
|
+
_react2.default.createElement('input', {
|
|
661
|
+
type: 'color',
|
|
662
|
+
value: rule.style && rule.style.color ? rule.style.color : '#000000',
|
|
663
|
+
onChange: function onChange(e) {
|
|
664
|
+
e.stopPropagation();
|
|
665
|
+
_this6.updateRule(index, 'style.color', e.target.value);
|
|
666
|
+
},
|
|
667
|
+
style: { width: '100%', padding: '2px' }
|
|
668
|
+
})
|
|
669
|
+
),
|
|
670
|
+
_react2.default.createElement(
|
|
671
|
+
'div',
|
|
672
|
+
{
|
|
673
|
+
style: { marginBottom: '8px' },
|
|
674
|
+
onClick: function onClick(e) {
|
|
675
|
+
return e.stopPropagation();
|
|
676
|
+
},
|
|
677
|
+
onMouseDown: function onMouseDown(e) {
|
|
678
|
+
return e.stopPropagation();
|
|
679
|
+
}
|
|
680
|
+
},
|
|
681
|
+
_react2.default.createElement(
|
|
682
|
+
'label',
|
|
683
|
+
{
|
|
684
|
+
style: {
|
|
685
|
+
display: 'block',
|
|
686
|
+
marginBottom: '4px',
|
|
687
|
+
fontSize: '11px'
|
|
688
|
+
}
|
|
689
|
+
},
|
|
690
|
+
'Font Weight:'
|
|
691
|
+
),
|
|
692
|
+
_react2.default.createElement(
|
|
693
|
+
'select',
|
|
694
|
+
{
|
|
695
|
+
value: rule.style && rule.style.fontWeight ? rule.style.fontWeight : '',
|
|
696
|
+
onChange: function onChange(e) {
|
|
697
|
+
e.stopPropagation();
|
|
698
|
+
_this6.updateRule(index, 'style.fontWeight', e.target.value || null);
|
|
699
|
+
},
|
|
700
|
+
style: { width: '100%', padding: '4px' }
|
|
701
|
+
},
|
|
702
|
+
_react2.default.createElement(
|
|
703
|
+
'option',
|
|
704
|
+
{ value: '' },
|
|
705
|
+
'Normal'
|
|
706
|
+
),
|
|
707
|
+
_react2.default.createElement(
|
|
708
|
+
'option',
|
|
709
|
+
{ value: 'bold' },
|
|
710
|
+
'Bold'
|
|
711
|
+
),
|
|
712
|
+
_react2.default.createElement(
|
|
713
|
+
'option',
|
|
714
|
+
{ value: 'lighter' },
|
|
715
|
+
'Lighter'
|
|
716
|
+
)
|
|
717
|
+
)
|
|
718
|
+
),
|
|
719
|
+
_react2.default.createElement(
|
|
720
|
+
'div',
|
|
721
|
+
{
|
|
722
|
+
style: { marginBottom: '8px' },
|
|
723
|
+
onClick: function onClick(e) {
|
|
724
|
+
return e.stopPropagation();
|
|
725
|
+
},
|
|
726
|
+
onMouseDown: function onMouseDown(e) {
|
|
727
|
+
return e.stopPropagation();
|
|
728
|
+
}
|
|
729
|
+
},
|
|
730
|
+
_react2.default.createElement(
|
|
731
|
+
'label',
|
|
732
|
+
{
|
|
733
|
+
style: {
|
|
734
|
+
display: 'block',
|
|
735
|
+
marginBottom: '4px',
|
|
736
|
+
fontSize: '11px'
|
|
737
|
+
}
|
|
738
|
+
},
|
|
739
|
+
'Font Style:'
|
|
740
|
+
),
|
|
741
|
+
_react2.default.createElement(
|
|
742
|
+
'select',
|
|
743
|
+
{
|
|
744
|
+
value: rule.style && rule.style.fontStyle ? rule.style.fontStyle : '',
|
|
745
|
+
onChange: function onChange(e) {
|
|
746
|
+
e.stopPropagation();
|
|
747
|
+
_this6.updateRule(index, 'style.fontStyle', e.target.value || null);
|
|
748
|
+
},
|
|
749
|
+
style: { width: '100%', padding: '4px' }
|
|
750
|
+
},
|
|
751
|
+
_react2.default.createElement(
|
|
752
|
+
'option',
|
|
753
|
+
{ value: '' },
|
|
754
|
+
'Normal'
|
|
755
|
+
),
|
|
756
|
+
_react2.default.createElement(
|
|
757
|
+
'option',
|
|
758
|
+
{ value: 'italic' },
|
|
759
|
+
'Italic'
|
|
760
|
+
),
|
|
761
|
+
_react2.default.createElement(
|
|
762
|
+
'option',
|
|
763
|
+
{ value: 'oblique' },
|
|
764
|
+
'Oblique'
|
|
765
|
+
)
|
|
766
|
+
)
|
|
767
|
+
)
|
|
768
|
+
);
|
|
769
|
+
}),
|
|
770
|
+
_react2.default.createElement(
|
|
771
|
+
'button',
|
|
772
|
+
{
|
|
773
|
+
type: 'button',
|
|
774
|
+
className: 'pvtButton',
|
|
775
|
+
onClick: function onClick(e) {
|
|
776
|
+
e.stopPropagation();
|
|
777
|
+
_this6.addRule();
|
|
778
|
+
},
|
|
779
|
+
style: { width: '100%', marginTop: '10px' }
|
|
780
|
+
},
|
|
781
|
+
'+ Add Rule'
|
|
782
|
+
)
|
|
783
|
+
)
|
|
784
|
+
);
|
|
785
|
+
}
|
|
786
|
+
}]);
|
|
787
|
+
|
|
788
|
+
return ConditionalFormattingUI;
|
|
789
|
+
}(_react2.default.Component);
|
|
790
|
+
|
|
791
|
+
ConditionalFormattingUI.propTypes = {
|
|
792
|
+
tableOptions: _propTypes2.default.object,
|
|
793
|
+
onChange: _propTypes2.default.func.isRequired,
|
|
794
|
+
moveToTop: _propTypes2.default.func,
|
|
795
|
+
zIndex: _propTypes2.default.number
|
|
796
|
+
};
|
|
797
|
+
|
|
798
|
+
ConditionalFormattingUI.defaultProps = {
|
|
799
|
+
tableOptions: {},
|
|
800
|
+
moveToTop: function moveToTop() {},
|
|
801
|
+
zIndex: 1
|
|
802
|
+
};
|
|
803
|
+
|
|
804
|
+
var CellFormattingUI = exports.CellFormattingUI = function (_React$Component3) {
|
|
805
|
+
_inherits(CellFormattingUI, _React$Component3);
|
|
806
|
+
|
|
807
|
+
function CellFormattingUI(props) {
|
|
808
|
+
_classCallCheck(this, CellFormattingUI);
|
|
809
|
+
|
|
810
|
+
var _this7 = _possibleConstructorReturn(this, (CellFormattingUI.__proto__ || Object.getPrototypeOf(CellFormattingUI)).call(this, props));
|
|
811
|
+
|
|
812
|
+
_this7.state = {
|
|
813
|
+
open: false
|
|
814
|
+
};
|
|
815
|
+
return _this7;
|
|
816
|
+
}
|
|
817
|
+
|
|
818
|
+
_createClass(CellFormattingUI, [{
|
|
819
|
+
key: 'getCellFormatting',
|
|
820
|
+
value: function getCellFormatting() {
|
|
821
|
+
var tableOptions = this.props.tableOptions || {};
|
|
822
|
+
return tableOptions.cellFormatting ? tableOptions.cellFormatting : { rules: [] };
|
|
823
|
+
}
|
|
824
|
+
}, {
|
|
825
|
+
key: 'updateCellFormatting',
|
|
826
|
+
value: function updateCellFormatting(cellFormatting) {
|
|
827
|
+
var currentTableOptions = this.props.tableOptions || {};
|
|
828
|
+
var tableOptions = Object.assign({}, currentTableOptions, {
|
|
829
|
+
cellFormatting: cellFormatting
|
|
830
|
+
});
|
|
831
|
+
this.props.onChange({
|
|
832
|
+
tableOptions: { $set: tableOptions }
|
|
833
|
+
});
|
|
834
|
+
}
|
|
835
|
+
}, {
|
|
836
|
+
key: 'addRule',
|
|
837
|
+
value: function addRule() {
|
|
838
|
+
var cf = this.getCellFormatting();
|
|
839
|
+
var newRule = {
|
|
840
|
+
format: {
|
|
841
|
+
thousandsSep: ',',
|
|
842
|
+
decimalSep: '.',
|
|
843
|
+
decimalPlaces: 2,
|
|
844
|
+
prefix: '',
|
|
845
|
+
suffix: ''
|
|
846
|
+
}
|
|
847
|
+
};
|
|
848
|
+
this.updateCellFormatting({
|
|
849
|
+
rules: cf.rules.slice().concat([newRule])
|
|
850
|
+
});
|
|
851
|
+
}
|
|
852
|
+
}, {
|
|
853
|
+
key: 'removeRule',
|
|
854
|
+
value: function removeRule(index) {
|
|
855
|
+
var cf = this.getCellFormatting();
|
|
856
|
+
var newRules = cf.rules.filter(function (_, i) {
|
|
857
|
+
return i !== index;
|
|
858
|
+
});
|
|
859
|
+
this.updateCellFormatting({
|
|
860
|
+
rules: newRules
|
|
861
|
+
});
|
|
862
|
+
}
|
|
863
|
+
}, {
|
|
864
|
+
key: 'updateRule',
|
|
865
|
+
value: function updateRule(index, field, value) {
|
|
866
|
+
var cf = this.getCellFormatting();
|
|
867
|
+
var newRules = cf.rules.slice();
|
|
868
|
+
if (field.startsWith('format.')) {
|
|
869
|
+
var formatField = field.replace('format.', '');
|
|
870
|
+
var newFormat = Object.assign({}, newRules[index].format || {});
|
|
871
|
+
if (value === null || value === '') {
|
|
872
|
+
delete newFormat[formatField];
|
|
873
|
+
} else {
|
|
874
|
+
newFormat[formatField] = value;
|
|
875
|
+
}
|
|
876
|
+
newRules[index] = Object.assign({}, newRules[index], {
|
|
877
|
+
format: newFormat
|
|
878
|
+
});
|
|
879
|
+
} else {
|
|
880
|
+
newRules[index] = Object.assign({}, newRules[index], _defineProperty({}, field, value));
|
|
881
|
+
}
|
|
882
|
+
this.updateCellFormatting({
|
|
883
|
+
rules: newRules
|
|
884
|
+
});
|
|
885
|
+
}
|
|
886
|
+
}, {
|
|
887
|
+
key: 'toggle',
|
|
888
|
+
value: function toggle() {
|
|
889
|
+
this.setState({ open: !this.state.open });
|
|
890
|
+
if (this.props.moveToTop) {
|
|
891
|
+
this.props.moveToTop();
|
|
892
|
+
}
|
|
893
|
+
}
|
|
894
|
+
}, {
|
|
895
|
+
key: 'render',
|
|
896
|
+
value: function render() {
|
|
897
|
+
var _this8 = this;
|
|
898
|
+
|
|
899
|
+
var cf = this.getCellFormatting();
|
|
900
|
+
|
|
901
|
+
return _react2.default.createElement(
|
|
902
|
+
'div',
|
|
903
|
+
null,
|
|
904
|
+
_react2.default.createElement(
|
|
905
|
+
'button',
|
|
906
|
+
{
|
|
907
|
+
type: 'button',
|
|
908
|
+
className: 'pvtButton',
|
|
909
|
+
onClick: function onClick(e) {
|
|
910
|
+
e.stopPropagation();
|
|
911
|
+
_this8.toggle();
|
|
912
|
+
},
|
|
913
|
+
style: { marginTop: '5px' }
|
|
914
|
+
},
|
|
915
|
+
this.state.open ? '▼' : '▶',
|
|
916
|
+
' Cell Formatting'
|
|
917
|
+
),
|
|
918
|
+
this.state.open && _react2.default.createElement(
|
|
919
|
+
'div',
|
|
920
|
+
{
|
|
921
|
+
className: 'pvtFilterBox',
|
|
922
|
+
style: {
|
|
923
|
+
display: 'block',
|
|
924
|
+
cursor: 'initial',
|
|
925
|
+
zIndex: this.props.zIndex,
|
|
926
|
+
marginTop: '5px',
|
|
927
|
+
minWidth: '400px',
|
|
928
|
+
position: 'relative'
|
|
929
|
+
},
|
|
930
|
+
onClick: function onClick() {
|
|
931
|
+
return _this8.props.moveToTop && _this8.props.moveToTop();
|
|
932
|
+
}
|
|
933
|
+
},
|
|
934
|
+
_react2.default.createElement(
|
|
935
|
+
'a',
|
|
936
|
+
{
|
|
937
|
+
onClick: function onClick() {
|
|
938
|
+
return _this8.setState({ open: false });
|
|
939
|
+
},
|
|
940
|
+
className: 'pvtCloseX'
|
|
941
|
+
},
|
|
942
|
+
'\xD7'
|
|
943
|
+
),
|
|
944
|
+
_react2.default.createElement(
|
|
945
|
+
'h4',
|
|
946
|
+
null,
|
|
947
|
+
'Cell Formatting Rules'
|
|
948
|
+
),
|
|
949
|
+
cf.rules.length === 0 && _react2.default.createElement(
|
|
950
|
+
'p',
|
|
951
|
+
{ style: { fontStyle: 'italic', color: '#666' } },
|
|
952
|
+
'No rules defined. Add a rule to format cell values.'
|
|
953
|
+
),
|
|
954
|
+
cf.rules.map(function (rule, index) {
|
|
955
|
+
return _react2.default.createElement(
|
|
956
|
+
'div',
|
|
957
|
+
{
|
|
958
|
+
key: index,
|
|
959
|
+
style: {
|
|
960
|
+
border: '1px solid #c8d4e3',
|
|
961
|
+
padding: '10px',
|
|
962
|
+
marginBottom: '10px',
|
|
963
|
+
backgroundColor: '#f9f9f9'
|
|
964
|
+
}
|
|
965
|
+
},
|
|
966
|
+
_react2.default.createElement(
|
|
967
|
+
'div',
|
|
968
|
+
{
|
|
969
|
+
style: {
|
|
970
|
+
display: 'flex',
|
|
971
|
+
justifyContent: 'space-between',
|
|
972
|
+
marginBottom: '8px'
|
|
973
|
+
}
|
|
974
|
+
},
|
|
975
|
+
_react2.default.createElement(
|
|
976
|
+
'strong',
|
|
977
|
+
null,
|
|
978
|
+
'Rule ',
|
|
979
|
+
index + 1
|
|
980
|
+
),
|
|
981
|
+
_react2.default.createElement(
|
|
982
|
+
'button',
|
|
983
|
+
{
|
|
984
|
+
type: 'button',
|
|
985
|
+
className: 'pvtButton',
|
|
986
|
+
onClick: function onClick(e) {
|
|
987
|
+
e.stopPropagation();
|
|
988
|
+
_this8.removeRule(index);
|
|
989
|
+
},
|
|
990
|
+
style: { fontSize: '10px', padding: '2px 6px' }
|
|
991
|
+
},
|
|
992
|
+
'Remove'
|
|
993
|
+
)
|
|
994
|
+
),
|
|
995
|
+
_react2.default.createElement(
|
|
996
|
+
'div',
|
|
997
|
+
{ style: { marginBottom: '8px' } },
|
|
998
|
+
_react2.default.createElement(
|
|
999
|
+
'label',
|
|
1000
|
+
{
|
|
1001
|
+
style: {
|
|
1002
|
+
display: 'block',
|
|
1003
|
+
marginBottom: '4px',
|
|
1004
|
+
fontSize: '11px'
|
|
1005
|
+
}
|
|
1006
|
+
},
|
|
1007
|
+
'Thousand Separator (empty = no separator, decimal formatting still applies):'
|
|
1008
|
+
),
|
|
1009
|
+
_react2.default.createElement('input', {
|
|
1010
|
+
type: 'text',
|
|
1011
|
+
value: rule.format && 'thousandsSep' in rule.format ? rule.format.thousandsSep : '',
|
|
1012
|
+
onChange: function onChange(e) {
|
|
1013
|
+
e.stopPropagation();
|
|
1014
|
+
_this8.updateRule(index, 'format.thousandsSep', e.target.value);
|
|
1015
|
+
},
|
|
1016
|
+
placeholder: ',',
|
|
1017
|
+
maxLength: '1',
|
|
1018
|
+
style: { width: '100%', padding: '4px' }
|
|
1019
|
+
})
|
|
1020
|
+
),
|
|
1021
|
+
_react2.default.createElement(
|
|
1022
|
+
'div',
|
|
1023
|
+
{ style: { marginBottom: '8px' } },
|
|
1024
|
+
_react2.default.createElement(
|
|
1025
|
+
'label',
|
|
1026
|
+
{
|
|
1027
|
+
style: {
|
|
1028
|
+
display: 'block',
|
|
1029
|
+
marginBottom: '4px',
|
|
1030
|
+
fontSize: '11px'
|
|
1031
|
+
}
|
|
1032
|
+
},
|
|
1033
|
+
'Decimal Separator:'
|
|
1034
|
+
),
|
|
1035
|
+
_react2.default.createElement('input', {
|
|
1036
|
+
type: 'text',
|
|
1037
|
+
value: rule.format && 'decimalSep' in rule.format ? rule.format.decimalSep : '.',
|
|
1038
|
+
onChange: function onChange(e) {
|
|
1039
|
+
e.stopPropagation();
|
|
1040
|
+
_this8.updateRule(index, 'format.decimalSep', e.target.value);
|
|
1041
|
+
},
|
|
1042
|
+
placeholder: '.',
|
|
1043
|
+
maxLength: '1',
|
|
1044
|
+
style: { width: '100%', padding: '4px' }
|
|
1045
|
+
})
|
|
1046
|
+
),
|
|
1047
|
+
_react2.default.createElement(
|
|
1048
|
+
'div',
|
|
1049
|
+
{ style: { marginBottom: '8px' } },
|
|
1050
|
+
_react2.default.createElement(
|
|
1051
|
+
'label',
|
|
1052
|
+
{
|
|
1053
|
+
style: {
|
|
1054
|
+
display: 'block',
|
|
1055
|
+
marginBottom: '4px',
|
|
1056
|
+
fontSize: '11px'
|
|
1057
|
+
}
|
|
1058
|
+
},
|
|
1059
|
+
'Decimal Places:'
|
|
1060
|
+
),
|
|
1061
|
+
_react2.default.createElement('input', {
|
|
1062
|
+
type: 'number',
|
|
1063
|
+
min: '0',
|
|
1064
|
+
max: '9',
|
|
1065
|
+
value: rule.format && 'decimalPlaces' in rule.format ? rule.format.decimalPlaces : 2,
|
|
1066
|
+
onChange: function onChange(e) {
|
|
1067
|
+
e.stopPropagation();
|
|
1068
|
+
var val = parseInt(e.target.value, 10);
|
|
1069
|
+
_this8.updateRule(index, 'format.decimalPlaces', isNaN(val) ? 2 : val);
|
|
1070
|
+
},
|
|
1071
|
+
placeholder: '2',
|
|
1072
|
+
style: { width: '100%', padding: '4px' }
|
|
1073
|
+
})
|
|
1074
|
+
),
|
|
1075
|
+
_react2.default.createElement(
|
|
1076
|
+
'div',
|
|
1077
|
+
{ style: { marginBottom: '8px' } },
|
|
1078
|
+
_react2.default.createElement(
|
|
1079
|
+
'label',
|
|
1080
|
+
{
|
|
1081
|
+
style: {
|
|
1082
|
+
display: 'block',
|
|
1083
|
+
marginBottom: '4px',
|
|
1084
|
+
fontSize: '11px'
|
|
1085
|
+
}
|
|
1086
|
+
},
|
|
1087
|
+
'Prefix (e.g., $, \u20AC):'
|
|
1088
|
+
),
|
|
1089
|
+
_react2.default.createElement('input', {
|
|
1090
|
+
type: 'text',
|
|
1091
|
+
value: rule.format && 'prefix' in rule.format ? rule.format.prefix : '',
|
|
1092
|
+
onChange: function onChange(e) {
|
|
1093
|
+
e.stopPropagation();
|
|
1094
|
+
_this8.updateRule(index, 'format.prefix', e.target.value);
|
|
1095
|
+
},
|
|
1096
|
+
placeholder: '',
|
|
1097
|
+
style: { width: '100%', padding: '4px' }
|
|
1098
|
+
})
|
|
1099
|
+
),
|
|
1100
|
+
_react2.default.createElement(
|
|
1101
|
+
'div',
|
|
1102
|
+
{ style: { marginBottom: '8px' } },
|
|
1103
|
+
_react2.default.createElement(
|
|
1104
|
+
'label',
|
|
1105
|
+
{
|
|
1106
|
+
style: {
|
|
1107
|
+
display: 'block',
|
|
1108
|
+
marginBottom: '4px',
|
|
1109
|
+
fontSize: '11px'
|
|
1110
|
+
}
|
|
1111
|
+
},
|
|
1112
|
+
'Suffix (e.g., %, units):'
|
|
1113
|
+
),
|
|
1114
|
+
_react2.default.createElement('input', {
|
|
1115
|
+
type: 'text',
|
|
1116
|
+
value: rule.format && 'suffix' in rule.format ? rule.format.suffix : '',
|
|
1117
|
+
onChange: function onChange(e) {
|
|
1118
|
+
e.stopPropagation();
|
|
1119
|
+
_this8.updateRule(index, 'format.suffix', e.target.value);
|
|
1120
|
+
},
|
|
1121
|
+
placeholder: '',
|
|
1122
|
+
style: { width: '100%', padding: '4px' }
|
|
1123
|
+
})
|
|
1124
|
+
),
|
|
1125
|
+
_react2.default.createElement(
|
|
1126
|
+
'div',
|
|
1127
|
+
{ style: { marginBottom: '8px' } },
|
|
1128
|
+
_react2.default.createElement(
|
|
1129
|
+
'label',
|
|
1130
|
+
{
|
|
1131
|
+
style: {
|
|
1132
|
+
display: 'flex',
|
|
1133
|
+
alignItems: 'center',
|
|
1134
|
+
marginBottom: '4px',
|
|
1135
|
+
fontSize: '11px'
|
|
1136
|
+
}
|
|
1137
|
+
},
|
|
1138
|
+
_react2.default.createElement('input', {
|
|
1139
|
+
type: 'checkbox',
|
|
1140
|
+
checked: rule.format && 'showOriginal' in rule.format ? rule.format.showOriginal : false,
|
|
1141
|
+
onChange: function onChange(e) {
|
|
1142
|
+
e.stopPropagation();
|
|
1143
|
+
_this8.updateRule(index, 'format.showOriginal', e.target.checked);
|
|
1144
|
+
},
|
|
1145
|
+
style: { marginRight: '6px' }
|
|
1146
|
+
}),
|
|
1147
|
+
'Show Original Value (no formatting)'
|
|
1148
|
+
)
|
|
1149
|
+
)
|
|
1150
|
+
);
|
|
1151
|
+
}),
|
|
1152
|
+
_react2.default.createElement(
|
|
1153
|
+
'button',
|
|
1154
|
+
{
|
|
1155
|
+
type: 'button',
|
|
1156
|
+
className: 'pvtButton',
|
|
1157
|
+
onClick: function onClick(e) {
|
|
1158
|
+
e.stopPropagation();
|
|
1159
|
+
_this8.addRule();
|
|
1160
|
+
},
|
|
1161
|
+
style: { width: '100%', marginTop: '10px' }
|
|
1162
|
+
},
|
|
1163
|
+
'+ Add Rule'
|
|
1164
|
+
)
|
|
1165
|
+
)
|
|
1166
|
+
);
|
|
1167
|
+
}
|
|
1168
|
+
}]);
|
|
1169
|
+
|
|
1170
|
+
return CellFormattingUI;
|
|
1171
|
+
}(_react2.default.Component);
|
|
1172
|
+
|
|
1173
|
+
CellFormattingUI.propTypes = {
|
|
1174
|
+
tableOptions: _propTypes2.default.object,
|
|
1175
|
+
onChange: _propTypes2.default.func.isRequired,
|
|
1176
|
+
moveToTop: _propTypes2.default.func,
|
|
1177
|
+
zIndex: _propTypes2.default.number
|
|
1178
|
+
};
|
|
1179
|
+
|
|
1180
|
+
CellFormattingUI.defaultProps = {
|
|
1181
|
+
tableOptions: {},
|
|
1182
|
+
moveToTop: function moveToTop() {},
|
|
1183
|
+
zIndex: 1
|
|
1184
|
+
};
|
|
1185
|
+
|
|
1186
|
+
var PivotTableUI = function (_React$PureComponent2) {
|
|
1187
|
+
_inherits(PivotTableUI, _React$PureComponent2);
|
|
1188
|
+
|
|
1189
|
+
function PivotTableUI(props) {
|
|
1190
|
+
_classCallCheck(this, PivotTableUI);
|
|
1191
|
+
|
|
1192
|
+
var _this9 = _possibleConstructorReturn(this, (PivotTableUI.__proto__ || Object.getPrototypeOf(PivotTableUI)).call(this, props));
|
|
1193
|
+
|
|
1194
|
+
_this9.state = {
|
|
1195
|
+
unusedOrder: [],
|
|
1196
|
+
zIndices: {},
|
|
1197
|
+
maxZIndex: 1000,
|
|
1198
|
+
openDropdown: false,
|
|
1199
|
+
attrValues: {},
|
|
1200
|
+
materializedInput: []
|
|
1201
|
+
};
|
|
1202
|
+
return _this9;
|
|
1203
|
+
}
|
|
1204
|
+
|
|
1205
|
+
_createClass(PivotTableUI, [{
|
|
1206
|
+
key: 'componentDidMount',
|
|
1207
|
+
value: function componentDidMount() {
|
|
1208
|
+
this.materializeInput(this.props.data);
|
|
1209
|
+
}
|
|
1210
|
+
}, {
|
|
1211
|
+
key: 'componentDidUpdate',
|
|
1212
|
+
value: function componentDidUpdate() {
|
|
1213
|
+
this.materializeInput(this.props.data);
|
|
1214
|
+
}
|
|
1215
|
+
}, {
|
|
1216
|
+
key: 'materializeInput',
|
|
1217
|
+
value: function materializeInput(nextData) {
|
|
1218
|
+
if (this.state.data === nextData) {
|
|
1219
|
+
return;
|
|
1220
|
+
}
|
|
1221
|
+
var newState = {
|
|
1222
|
+
data: nextData,
|
|
1223
|
+
attrValues: {},
|
|
1224
|
+
materializedInput: []
|
|
1225
|
+
};
|
|
1226
|
+
var recordsProcessed = 0;
|
|
1227
|
+
_Utilities.PivotData.forEachRecord(newState.data, this.props.derivedAttributes, function (record) {
|
|
1228
|
+
newState.materializedInput.push(record);
|
|
1229
|
+
var _iteratorNormalCompletion = true;
|
|
1230
|
+
var _didIteratorError = false;
|
|
1231
|
+
var _iteratorError = undefined;
|
|
1232
|
+
|
|
1233
|
+
try {
|
|
1234
|
+
for (var _iterator = Object.keys(record)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
|
|
1235
|
+
var attr = _step.value;
|
|
1236
|
+
|
|
1237
|
+
if (!(attr in newState.attrValues)) {
|
|
1238
|
+
newState.attrValues[attr] = {};
|
|
1239
|
+
if (recordsProcessed > 0) {
|
|
1240
|
+
newState.attrValues[attr].null = recordsProcessed;
|
|
1241
|
+
}
|
|
1242
|
+
}
|
|
1243
|
+
}
|
|
1244
|
+
} catch (err) {
|
|
1245
|
+
_didIteratorError = true;
|
|
1246
|
+
_iteratorError = err;
|
|
1247
|
+
} finally {
|
|
1248
|
+
try {
|
|
1249
|
+
if (!_iteratorNormalCompletion && _iterator.return) {
|
|
1250
|
+
_iterator.return();
|
|
1251
|
+
}
|
|
1252
|
+
} finally {
|
|
1253
|
+
if (_didIteratorError) {
|
|
1254
|
+
throw _iteratorError;
|
|
1255
|
+
}
|
|
1256
|
+
}
|
|
1257
|
+
}
|
|
1258
|
+
|
|
1259
|
+
for (var _attr in newState.attrValues) {
|
|
1260
|
+
var value = _attr in record ? record[_attr] : 'null';
|
|
1261
|
+
if (!(value in newState.attrValues[_attr])) {
|
|
1262
|
+
newState.attrValues[_attr][value] = 0;
|
|
1263
|
+
}
|
|
1264
|
+
newState.attrValues[_attr][value]++;
|
|
1265
|
+
}
|
|
1266
|
+
recordsProcessed++;
|
|
1267
|
+
});
|
|
1268
|
+
this.setState(newState);
|
|
1269
|
+
}
|
|
1270
|
+
}, {
|
|
1271
|
+
key: 'sendPropUpdate',
|
|
1272
|
+
value: function sendPropUpdate(command) {
|
|
1273
|
+
this.props.onChange((0, _immutabilityHelper2.default)(this.props, command));
|
|
1274
|
+
}
|
|
1275
|
+
}, {
|
|
1276
|
+
key: 'propUpdater',
|
|
1277
|
+
value: function propUpdater(key) {
|
|
1278
|
+
var _this10 = this;
|
|
1279
|
+
|
|
1280
|
+
return function (value) {
|
|
1281
|
+
return _this10.sendPropUpdate(_defineProperty({}, key, { $set: value }));
|
|
1282
|
+
};
|
|
1283
|
+
}
|
|
1284
|
+
}, {
|
|
1285
|
+
key: 'hasExternalAggregations',
|
|
1286
|
+
value: function hasExternalAggregations() {
|
|
1287
|
+
return Array.isArray(this.props.aggregations);
|
|
1288
|
+
}
|
|
1289
|
+
}, {
|
|
1290
|
+
key: 'getCurrentAggregations',
|
|
1291
|
+
value: function getCurrentAggregations() {
|
|
1292
|
+
var _this11 = this;
|
|
1293
|
+
|
|
1294
|
+
var fallbackAggregator = this.props.aggregatorName || Object.keys(this.props.aggregators)[0];
|
|
1295
|
+
var fallbackVals = Array.isArray(this.props.vals) ? this.props.vals.slice() : [];
|
|
1296
|
+
var aggregationsProvided = this.hasExternalAggregations();
|
|
1297
|
+
var defaultAggregations = [{
|
|
1298
|
+
key: 'agg-default',
|
|
1299
|
+
aggregatorName: fallbackAggregator,
|
|
1300
|
+
vals: fallbackVals
|
|
1301
|
+
}];
|
|
1302
|
+
var source = aggregationsProvided ? this.props.aggregations : defaultAggregations;
|
|
1303
|
+
return source.map(function (agg, idx) {
|
|
1304
|
+
var aggregatorName = agg.aggregatorName || fallbackAggregator;
|
|
1305
|
+
var baseVals = Array.isArray(agg.vals) ? agg.vals.slice() : aggregationsProvided ? [] : fallbackVals;
|
|
1306
|
+
return {
|
|
1307
|
+
key: agg.key || 'agg-' + idx,
|
|
1308
|
+
aggregatorName: aggregatorName,
|
|
1309
|
+
vals: _this11.defaultValsForAggregator(aggregatorName, baseVals)
|
|
1310
|
+
};
|
|
1311
|
+
});
|
|
1312
|
+
}
|
|
1313
|
+
}, {
|
|
1314
|
+
key: 'numInputsForAggregator',
|
|
1315
|
+
value: function numInputsForAggregator(name) {
|
|
1316
|
+
if (!name || !(name in this.props.aggregators)) {
|
|
1317
|
+
return 0;
|
|
1318
|
+
}
|
|
1319
|
+
var instance = this.props.aggregators[name]([])();
|
|
1320
|
+
return instance.numInputs || 0;
|
|
1321
|
+
}
|
|
1322
|
+
}, {
|
|
1323
|
+
key: 'getAttributeOptions',
|
|
1324
|
+
value: function getAttributeOptions() {
|
|
1325
|
+
var _this12 = this;
|
|
1326
|
+
|
|
1327
|
+
return Object.keys(this.state.attrValues).filter(function (e) {
|
|
1328
|
+
return !_this12.props.hiddenAttributes.includes(e) && !_this12.props.hiddenFromAggregators.includes(e);
|
|
1329
|
+
});
|
|
1330
|
+
}
|
|
1331
|
+
}, {
|
|
1332
|
+
key: 'defaultValsForAggregator',
|
|
1333
|
+
value: function defaultValsForAggregator(name) {
|
|
1334
|
+
var currentVals = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
|
|
1335
|
+
|
|
1336
|
+
var required = this.numInputsForAggregator(name);
|
|
1337
|
+
if (required === 0) {
|
|
1338
|
+
return [];
|
|
1339
|
+
}
|
|
1340
|
+
var options = this.getAttributeOptions();
|
|
1341
|
+
var next = currentVals.slice(0, required);
|
|
1342
|
+
for (var i = 0; i < required; i++) {
|
|
1343
|
+
if (!next[i]) {
|
|
1344
|
+
next[i] = options[i % options.length] || null;
|
|
1345
|
+
}
|
|
1346
|
+
}
|
|
1347
|
+
return next;
|
|
1348
|
+
}
|
|
1349
|
+
}, {
|
|
1350
|
+
key: 'generateAggregationKey',
|
|
1351
|
+
value: function generateAggregationKey() {
|
|
1352
|
+
var timestamp = Date.now().toString(AGG_KEY_RADIX);
|
|
1353
|
+
var randomPart = Math.random().toString(AGG_KEY_RADIX).slice(AGG_KEY_OFFSET, AGG_KEY_OFFSET + AGG_KEY_LENGTH);
|
|
1354
|
+
return 'agg-' + timestamp + '-' + randomPart;
|
|
1355
|
+
}
|
|
1356
|
+
}, {
|
|
1357
|
+
key: 'updateAggregations',
|
|
1358
|
+
value: function updateAggregations(nextAggregations) {
|
|
1359
|
+
var _this13 = this;
|
|
1360
|
+
|
|
1361
|
+
if (!nextAggregations.length) {
|
|
1362
|
+
return;
|
|
1363
|
+
}
|
|
1364
|
+
var fallbackAggregator = this.props.aggregatorName || Object.keys(this.props.aggregators)[0];
|
|
1365
|
+
var sanitized = nextAggregations.map(function (agg, idx) {
|
|
1366
|
+
var aggregatorName = agg.aggregatorName || fallbackAggregator;
|
|
1367
|
+
return {
|
|
1368
|
+
key: agg.key || 'agg-' + idx,
|
|
1369
|
+
aggregatorName: aggregatorName,
|
|
1370
|
+
vals: _this13.defaultValsForAggregator(aggregatorName, Array.isArray(agg.vals) ? agg.vals.slice() : [])
|
|
1371
|
+
};
|
|
1372
|
+
});
|
|
1373
|
+
var primary = sanitized[0];
|
|
1374
|
+
var command = {
|
|
1375
|
+
aggregations: { $set: sanitized }
|
|
1376
|
+
};
|
|
1377
|
+
if (!this.hasExternalAggregations()) {
|
|
1378
|
+
command.aggregatorName = { $set: primary.aggregatorName };
|
|
1379
|
+
command.vals = { $set: primary.vals };
|
|
1380
|
+
}
|
|
1381
|
+
this.sendPropUpdate(command);
|
|
1382
|
+
}
|
|
1383
|
+
}, {
|
|
1384
|
+
key: 'setAggregationAggregator',
|
|
1385
|
+
value: function setAggregationAggregator(index, aggregatorName) {
|
|
1386
|
+
var aggregations = this.getCurrentAggregations();
|
|
1387
|
+
var next = Object.assign({}, aggregations[index], {
|
|
1388
|
+
aggregatorName: aggregatorName
|
|
1389
|
+
});
|
|
1390
|
+
next.vals = this.defaultValsForAggregator(aggregatorName, next.vals);
|
|
1391
|
+
aggregations[index] = next;
|
|
1392
|
+
this.updateAggregations(aggregations);
|
|
1393
|
+
}
|
|
1394
|
+
}, {
|
|
1395
|
+
key: 'setAggregationVal',
|
|
1396
|
+
value: function setAggregationVal(index, valIndex, value) {
|
|
1397
|
+
var aggregations = this.getCurrentAggregations();
|
|
1398
|
+
var next = Object.assign({}, aggregations[index]);
|
|
1399
|
+
var vals = Array.isArray(next.vals) ? next.vals.slice() : [];
|
|
1400
|
+
vals[valIndex] = value;
|
|
1401
|
+
next.vals = vals;
|
|
1402
|
+
aggregations[index] = next;
|
|
1403
|
+
this.updateAggregations(aggregations);
|
|
1404
|
+
}
|
|
1405
|
+
}, {
|
|
1406
|
+
key: 'setAggregationDisplayMode',
|
|
1407
|
+
value: function setAggregationDisplayMode(mode) {
|
|
1408
|
+
var allowedModes = ['row', 'column'];
|
|
1409
|
+
var normalizedMode = allowedModes.includes(mode) ? mode : 'row';
|
|
1410
|
+
var tableOptions = Object.assign({}, this.props.tableOptions || {}, {
|
|
1411
|
+
aggregationDisplayMode: normalizedMode
|
|
1412
|
+
});
|
|
1413
|
+
this.sendPropUpdate({
|
|
1414
|
+
tableOptions: { $set: tableOptions }
|
|
1415
|
+
});
|
|
1416
|
+
}
|
|
1417
|
+
}, {
|
|
1418
|
+
key: 'addAggregationRow',
|
|
1419
|
+
value: function addAggregationRow() {
|
|
1420
|
+
var aggregations = this.getCurrentAggregations();
|
|
1421
|
+
var defaultAggregator = this.props.aggregatorName || Object.keys(this.props.aggregators)[0];
|
|
1422
|
+
var key = this.generateAggregationKey();
|
|
1423
|
+
aggregations.push({
|
|
1424
|
+
key: key,
|
|
1425
|
+
aggregatorName: defaultAggregator,
|
|
1426
|
+
vals: this.defaultValsForAggregator(defaultAggregator)
|
|
1427
|
+
});
|
|
1428
|
+
this.updateAggregations(aggregations);
|
|
1429
|
+
}
|
|
1430
|
+
}, {
|
|
1431
|
+
key: 'removeAggregationRow',
|
|
1432
|
+
value: function removeAggregationRow(index) {
|
|
1433
|
+
var aggregations = this.getCurrentAggregations();
|
|
1434
|
+
if (aggregations.length === 1) {
|
|
1435
|
+
return;
|
|
1436
|
+
}
|
|
1437
|
+
aggregations.splice(index, 1);
|
|
1438
|
+
this.updateAggregations(aggregations);
|
|
1439
|
+
}
|
|
1440
|
+
}, {
|
|
1441
|
+
key: 'setValuesInFilter',
|
|
1442
|
+
value: function setValuesInFilter(attribute, values) {
|
|
1443
|
+
this.sendPropUpdate({
|
|
1444
|
+
valueFilter: _defineProperty({}, attribute, {
|
|
1445
|
+
$set: values.reduce(function (r, v) {
|
|
1446
|
+
r[v] = true;
|
|
1447
|
+
return r;
|
|
1448
|
+
}, {})
|
|
1449
|
+
})
|
|
1450
|
+
});
|
|
1451
|
+
}
|
|
1452
|
+
}, {
|
|
1453
|
+
key: 'addValuesToFilter',
|
|
1454
|
+
value: function addValuesToFilter(attribute, values) {
|
|
1455
|
+
if (attribute in this.props.valueFilter) {
|
|
1456
|
+
this.sendPropUpdate({
|
|
1457
|
+
valueFilter: _defineProperty({}, attribute, values.reduce(function (r, v) {
|
|
1458
|
+
r[v] = { $set: true };
|
|
1459
|
+
return r;
|
|
1460
|
+
}, {}))
|
|
1461
|
+
});
|
|
1462
|
+
} else {
|
|
1463
|
+
this.setValuesInFilter(attribute, values);
|
|
1464
|
+
}
|
|
1465
|
+
}
|
|
1466
|
+
}, {
|
|
1467
|
+
key: 'removeValuesFromFilter',
|
|
1468
|
+
value: function removeValuesFromFilter(attribute, values) {
|
|
1469
|
+
this.sendPropUpdate({
|
|
1470
|
+
valueFilter: _defineProperty({}, attribute, { $unset: values })
|
|
1471
|
+
});
|
|
1472
|
+
}
|
|
1473
|
+
}, {
|
|
1474
|
+
key: 'moveFilterBoxToTop',
|
|
1475
|
+
value: function moveFilterBoxToTop(attribute) {
|
|
1476
|
+
this.setState((0, _immutabilityHelper2.default)(this.state, {
|
|
1477
|
+
maxZIndex: { $set: this.state.maxZIndex + 1 },
|
|
1478
|
+
zIndices: _defineProperty({}, attribute, { $set: this.state.maxZIndex + 1 })
|
|
1479
|
+
}));
|
|
1480
|
+
}
|
|
1481
|
+
}, {
|
|
1482
|
+
key: 'handleColSort',
|
|
1483
|
+
value: function handleColSort(attr, sortDir) {
|
|
1484
|
+
// Only allow sorting 1 column at a time - clear all other column sorts
|
|
1485
|
+
var colSorts = {};
|
|
1486
|
+
if (sortDir !== null) {
|
|
1487
|
+
colSorts[attr] = sortDir;
|
|
1488
|
+
}
|
|
1489
|
+
this.sendPropUpdate({ colSorts: { $set: colSorts } });
|
|
1490
|
+
}
|
|
1491
|
+
}, {
|
|
1492
|
+
key: 'handleRowSort',
|
|
1493
|
+
value: function handleRowSort(attr, sortDir) {
|
|
1494
|
+
// Only allow sorting 1 row at a time - clear all other row sorts
|
|
1495
|
+
var rowSorts = {};
|
|
1496
|
+
if (sortDir !== null) {
|
|
1497
|
+
rowSorts[attr] = sortDir;
|
|
1498
|
+
}
|
|
1499
|
+
this.sendPropUpdate({ rowSorts: { $set: rowSorts } });
|
|
1500
|
+
}
|
|
1501
|
+
}, {
|
|
1502
|
+
key: 'isOpen',
|
|
1503
|
+
value: function isOpen(dropdown) {
|
|
1504
|
+
return this.state.openDropdown === dropdown;
|
|
1505
|
+
}
|
|
1506
|
+
}, {
|
|
1507
|
+
key: 'makeDnDCell',
|
|
1508
|
+
value: function makeDnDCell(items, onChange, classes) {
|
|
1509
|
+
var _this14 = this;
|
|
1510
|
+
|
|
1511
|
+
return _react2.default.createElement(
|
|
1512
|
+
_reactSortablejs2.default,
|
|
1513
|
+
{
|
|
1514
|
+
options: {
|
|
1515
|
+
group: 'shared',
|
|
1516
|
+
ghostClass: 'pvtPlaceholder',
|
|
1517
|
+
filter: '.pvtFilterBox',
|
|
1518
|
+
preventOnFilter: false
|
|
1519
|
+
},
|
|
1520
|
+
tag: 'td',
|
|
1521
|
+
className: classes,
|
|
1522
|
+
onChange: onChange
|
|
1523
|
+
},
|
|
1524
|
+
items.map(function (x) {
|
|
1525
|
+
return _react2.default.createElement(DraggableAttribute, {
|
|
1526
|
+
name: x,
|
|
1527
|
+
key: x,
|
|
1528
|
+
attrValues: _this14.state.attrValues[x],
|
|
1529
|
+
valueFilter: _this14.props.valueFilter[x] || {},
|
|
1530
|
+
sorter: (0, _Utilities.getSort)(_this14.props.sorters, x, _this14.state.attrValues[x]),
|
|
1531
|
+
menuLimit: _this14.props.menuLimit,
|
|
1532
|
+
setValuesInFilter: _this14.setValuesInFilter.bind(_this14),
|
|
1533
|
+
addValuesToFilter: _this14.addValuesToFilter.bind(_this14),
|
|
1534
|
+
moveFilterBoxToTop: _this14.moveFilterBoxToTop.bind(_this14),
|
|
1535
|
+
removeValuesFromFilter: _this14.removeValuesFromFilter.bind(_this14),
|
|
1536
|
+
zIndex: _this14.state.zIndices[x] || _this14.state.maxZIndex
|
|
1537
|
+
});
|
|
1538
|
+
})
|
|
1539
|
+
);
|
|
1540
|
+
}
|
|
1541
|
+
}, {
|
|
1542
|
+
key: 'render',
|
|
1543
|
+
value: function render() {
|
|
1544
|
+
var _this15 = this;
|
|
1545
|
+
|
|
1546
|
+
var aggregations = this.getCurrentAggregations();
|
|
1547
|
+
var primaryAggregation = aggregations[0];
|
|
1548
|
+
var tableOptions = this.props.tableOptions || {};
|
|
1549
|
+
var aggregationDisplayMode = tableOptions.aggregationDisplayMode === 'column' ? 'column' : 'row';
|
|
1550
|
+
var aggregatorCellOutlet = primaryAggregation && this.props.aggregators[primaryAggregation.aggregatorName] && this.props.aggregators[primaryAggregation.aggregatorName]([])().outlet;
|
|
1551
|
+
|
|
1552
|
+
var rendererName = this.props.rendererName in this.props.renderers ? this.props.rendererName : Object.keys(this.props.renderers)[0];
|
|
1553
|
+
|
|
1554
|
+
var rendererCell = _react2.default.createElement(
|
|
1555
|
+
'td',
|
|
1556
|
+
{ className: 'pvtRenderers' },
|
|
1557
|
+
_react2.default.createElement(Dropdown, {
|
|
1558
|
+
current: rendererName,
|
|
1559
|
+
values: Object.keys(this.props.renderers),
|
|
1560
|
+
open: this.isOpen('renderer'),
|
|
1561
|
+
zIndex: this.isOpen('renderer') ? this.state.maxZIndex + 1 : 1,
|
|
1562
|
+
toggle: function toggle() {
|
|
1563
|
+
return _this15.setState({
|
|
1564
|
+
openDropdown: _this15.isOpen('renderer') ? false : 'renderer'
|
|
1565
|
+
});
|
|
1566
|
+
},
|
|
1567
|
+
setValue: this.propUpdater('rendererName')
|
|
1568
|
+
})
|
|
1569
|
+
);
|
|
1570
|
+
|
|
1571
|
+
var sortIcons = {
|
|
1572
|
+
key_a_to_z: {
|
|
1573
|
+
rowSymbol: '↕',
|
|
1574
|
+
colSymbol: '↔',
|
|
1575
|
+
next: 'value_a_to_z'
|
|
1576
|
+
},
|
|
1577
|
+
value_a_to_z: {
|
|
1578
|
+
rowSymbol: '↓',
|
|
1579
|
+
colSymbol: '→',
|
|
1580
|
+
next: 'value_z_to_a'
|
|
1581
|
+
},
|
|
1582
|
+
value_z_to_a: { rowSymbol: '↑', colSymbol: '←', next: 'key_a_to_z' }
|
|
1583
|
+
};
|
|
1584
|
+
|
|
1585
|
+
var attributeOptions = this.getAttributeOptions();
|
|
1586
|
+
var aggregatorCell = _react2.default.createElement(
|
|
1587
|
+
'td',
|
|
1588
|
+
{ className: 'pvtVals' },
|
|
1589
|
+
aggregations.map(function (agg, idx) {
|
|
1590
|
+
var aggDropdownKey = 'aggregation-' + agg.key + '-agg';
|
|
1591
|
+
var numValsAllowed = _this15.numInputsForAggregator(agg.aggregatorName);
|
|
1592
|
+
var vals = _this15.defaultValsForAggregator(agg.aggregatorName, agg.vals);
|
|
1593
|
+
return _react2.default.createElement(
|
|
1594
|
+
'div',
|
|
1595
|
+
{ className: 'pvtAggregatorRow', key: agg.key || idx },
|
|
1596
|
+
_react2.default.createElement(Dropdown, {
|
|
1597
|
+
current: agg.aggregatorName,
|
|
1598
|
+
values: Object.keys(_this15.props.aggregators),
|
|
1599
|
+
open: _this15.isOpen(aggDropdownKey),
|
|
1600
|
+
zIndex: _this15.isOpen(aggDropdownKey) ? _this15.state.maxZIndex + 1 : 1,
|
|
1601
|
+
toggle: function toggle() {
|
|
1602
|
+
return _this15.setState({
|
|
1603
|
+
openDropdown: _this15.isOpen(aggDropdownKey) ? false : aggDropdownKey
|
|
1604
|
+
});
|
|
1605
|
+
},
|
|
1606
|
+
setValue: function setValue(value) {
|
|
1607
|
+
return _this15.setAggregationAggregator(idx, value);
|
|
1608
|
+
}
|
|
1609
|
+
}),
|
|
1610
|
+
numValsAllowed > 0 && _react2.default.createElement(
|
|
1611
|
+
'div',
|
|
1612
|
+
{ className: 'pvtAggregatorVals' },
|
|
1613
|
+
new Array(numValsAllowed).fill().map(function (n, i) {
|
|
1614
|
+
var valDropdownKey = 'aggregation-' + agg.key + '-val-' + i;
|
|
1615
|
+
return _react2.default.createElement(Dropdown, {
|
|
1616
|
+
key: 'agg-val-' + agg.key + '-' + i,
|
|
1617
|
+
current: vals[i],
|
|
1618
|
+
values: attributeOptions,
|
|
1619
|
+
open: _this15.isOpen(valDropdownKey),
|
|
1620
|
+
zIndex: _this15.isOpen(valDropdownKey) ? _this15.state.maxZIndex + 1 : 1,
|
|
1621
|
+
toggle: function toggle() {
|
|
1622
|
+
return _this15.setState({
|
|
1623
|
+
openDropdown: _this15.isOpen(valDropdownKey) ? false : valDropdownKey
|
|
1624
|
+
});
|
|
1625
|
+
},
|
|
1626
|
+
setValue: function setValue(value) {
|
|
1627
|
+
return _this15.setAggregationVal(idx, i, value);
|
|
1628
|
+
}
|
|
1629
|
+
});
|
|
1630
|
+
})
|
|
1631
|
+
),
|
|
1632
|
+
aggregations.length > 1 && _react2.default.createElement(
|
|
1633
|
+
'button',
|
|
1634
|
+
{
|
|
1635
|
+
type: 'button',
|
|
1636
|
+
className: 'pvtButton pvtRemoveAggregator',
|
|
1637
|
+
onClick: function onClick(e) {
|
|
1638
|
+
e.stopPropagation();
|
|
1639
|
+
_this15.removeAggregationRow(idx);
|
|
1640
|
+
}
|
|
1641
|
+
},
|
|
1642
|
+
'Remove'
|
|
1643
|
+
)
|
|
1644
|
+
);
|
|
1645
|
+
}),
|
|
1646
|
+
_react2.default.createElement(
|
|
1647
|
+
'div',
|
|
1648
|
+
{ className: 'pvtAggregationModeToggle' },
|
|
1649
|
+
_react2.default.createElement(
|
|
1650
|
+
'label',
|
|
1651
|
+
{
|
|
1652
|
+
htmlFor: 'pvtAggregationMode',
|
|
1653
|
+
style: { marginRight: '6px', fontSize: '12px' }
|
|
1654
|
+
},
|
|
1655
|
+
'Aggregation values on:'
|
|
1656
|
+
),
|
|
1657
|
+
_react2.default.createElement(
|
|
1658
|
+
'select',
|
|
1659
|
+
{
|
|
1660
|
+
id: 'pvtAggregationMode',
|
|
1661
|
+
value: aggregationDisplayMode,
|
|
1662
|
+
onChange: function onChange(e) {
|
|
1663
|
+
return _this15.setAggregationDisplayMode(e.target.value);
|
|
1664
|
+
}
|
|
1665
|
+
},
|
|
1666
|
+
_react2.default.createElement(
|
|
1667
|
+
'option',
|
|
1668
|
+
{ value: 'row' },
|
|
1669
|
+
'Rows'
|
|
1670
|
+
),
|
|
1671
|
+
_react2.default.createElement(
|
|
1672
|
+
'option',
|
|
1673
|
+
{ value: 'column' },
|
|
1674
|
+
'Columns'
|
|
1675
|
+
)
|
|
1676
|
+
)
|
|
1677
|
+
),
|
|
1678
|
+
_react2.default.createElement(
|
|
1679
|
+
'button',
|
|
1680
|
+
{
|
|
1681
|
+
type: 'button',
|
|
1682
|
+
className: 'pvtButton pvtAddAggregator',
|
|
1683
|
+
onClick: function onClick(e) {
|
|
1684
|
+
e.stopPropagation();
|
|
1685
|
+
_this15.addAggregationRow();
|
|
1686
|
+
}
|
|
1687
|
+
},
|
|
1688
|
+
'+ Add Value'
|
|
1689
|
+
),
|
|
1690
|
+
_react2.default.createElement(
|
|
1691
|
+
'a',
|
|
1692
|
+
{
|
|
1693
|
+
role: 'button',
|
|
1694
|
+
className: 'pvtRowOrder',
|
|
1695
|
+
onClick: function onClick() {
|
|
1696
|
+
return _this15.propUpdater('rowOrder')(sortIcons[_this15.props.rowOrder].next);
|
|
1697
|
+
}
|
|
1698
|
+
},
|
|
1699
|
+
sortIcons[this.props.rowOrder].rowSymbol
|
|
1700
|
+
),
|
|
1701
|
+
_react2.default.createElement(
|
|
1702
|
+
'a',
|
|
1703
|
+
{
|
|
1704
|
+
role: 'button',
|
|
1705
|
+
className: 'pvtColOrder',
|
|
1706
|
+
onClick: function onClick() {
|
|
1707
|
+
return _this15.propUpdater('colOrder')(sortIcons[_this15.props.colOrder].next);
|
|
1708
|
+
}
|
|
1709
|
+
},
|
|
1710
|
+
sortIcons[this.props.colOrder].colSymbol
|
|
1711
|
+
),
|
|
1712
|
+
aggregatorCellOutlet && aggregatorCellOutlet(this.props.data),
|
|
1713
|
+
_react2.default.createElement(ConditionalFormattingUI, {
|
|
1714
|
+
tableOptions: tableOptions,
|
|
1715
|
+
onChange: this.sendPropUpdate.bind(this),
|
|
1716
|
+
moveToTop: this.moveFilterBoxToTop.bind(this, 'conditionalFormatting'),
|
|
1717
|
+
zIndex: this.state.zIndices.conditionalFormatting || this.state.maxZIndex
|
|
1718
|
+
}),
|
|
1719
|
+
_react2.default.createElement(CellFormattingUI, {
|
|
1720
|
+
tableOptions: tableOptions,
|
|
1721
|
+
onChange: this.sendPropUpdate.bind(this),
|
|
1722
|
+
moveToTop: this.moveFilterBoxToTop.bind(this, 'cellFormatting'),
|
|
1723
|
+
zIndex: this.state.zIndices.cellFormatting || this.state.maxZIndex
|
|
1724
|
+
})
|
|
1725
|
+
);
|
|
1726
|
+
|
|
1727
|
+
var unusedAttrs = Object.keys(this.state.attrValues).filter(function (e) {
|
|
1728
|
+
return !_this15.props.rows.includes(e) && !_this15.props.cols.includes(e) && !_this15.props.hiddenAttributes.includes(e) && !_this15.props.hiddenFromDragDrop.includes(e);
|
|
1729
|
+
}).sort((0, _Utilities.sortAs)(this.state.unusedOrder));
|
|
1730
|
+
|
|
1731
|
+
var unusedLength = unusedAttrs.reduce(function (r, e) {
|
|
1732
|
+
return r + e.length;
|
|
1733
|
+
}, 0);
|
|
1734
|
+
var horizUnused = unusedLength < this.props.unusedOrientationCutoff;
|
|
1735
|
+
|
|
1736
|
+
var unusedAttrsCell = this.makeDnDCell(unusedAttrs, function (order) {
|
|
1737
|
+
return _this15.setState({ unusedOrder: order });
|
|
1738
|
+
}, 'pvtAxisContainer pvtUnused ' + (horizUnused ? 'pvtHorizList' : 'pvtVertList'));
|
|
1739
|
+
|
|
1740
|
+
var colAttrs = this.props.cols.filter(function (e) {
|
|
1741
|
+
return !_this15.props.hiddenAttributes.includes(e) && !_this15.props.hiddenFromDragDrop.includes(e);
|
|
1742
|
+
});
|
|
1743
|
+
|
|
1744
|
+
var colAttrsCell = this.makeDnDCell(colAttrs, this.propUpdater('cols'), 'pvtAxisContainer pvtHorizList pvtCols');
|
|
1745
|
+
|
|
1746
|
+
var rowAttrs = this.props.rows.filter(function (e) {
|
|
1747
|
+
return !_this15.props.hiddenAttributes.includes(e) && !_this15.props.hiddenFromDragDrop.includes(e);
|
|
1748
|
+
});
|
|
1749
|
+
var rowAttrsCell = this.makeDnDCell(rowAttrs, this.propUpdater('rows'), 'pvtAxisContainer pvtVertList pvtRows');
|
|
1750
|
+
var outputCell = _react2.default.createElement(
|
|
1751
|
+
'td',
|
|
1752
|
+
{ className: 'pvtOutput' },
|
|
1753
|
+
_react2.default.createElement(_PivotTable2.default, _extends({}, (0, _immutabilityHelper2.default)(this.props, {
|
|
1754
|
+
data: { $set: this.state.materializedInput }
|
|
1755
|
+
}), {
|
|
1756
|
+
colSorts: this.props.colSorts || {},
|
|
1757
|
+
rowSorts: this.props.rowSorts || {},
|
|
1758
|
+
onColSort: this.handleColSort.bind(this),
|
|
1759
|
+
onRowSort: this.handleRowSort.bind(this)
|
|
1760
|
+
}))
|
|
1761
|
+
);
|
|
1762
|
+
|
|
1763
|
+
if (horizUnused) {
|
|
1764
|
+
return _react2.default.createElement(
|
|
1765
|
+
'table',
|
|
1766
|
+
{ className: 'pvtUi' },
|
|
1767
|
+
_react2.default.createElement(
|
|
1768
|
+
'tbody',
|
|
1769
|
+
{ onClick: function onClick() {
|
|
1770
|
+
return _this15.setState({ openDropdown: false });
|
|
1771
|
+
} },
|
|
1772
|
+
_react2.default.createElement(
|
|
1773
|
+
'tr',
|
|
1774
|
+
null,
|
|
1775
|
+
rendererCell,
|
|
1776
|
+
unusedAttrsCell
|
|
1777
|
+
),
|
|
1778
|
+
_react2.default.createElement(
|
|
1779
|
+
'tr',
|
|
1780
|
+
null,
|
|
1781
|
+
aggregatorCell,
|
|
1782
|
+
colAttrsCell
|
|
1783
|
+
),
|
|
1784
|
+
_react2.default.createElement(
|
|
1785
|
+
'tr',
|
|
1786
|
+
null,
|
|
1787
|
+
rowAttrsCell,
|
|
1788
|
+
outputCell
|
|
1789
|
+
)
|
|
1790
|
+
)
|
|
1791
|
+
);
|
|
1792
|
+
}
|
|
1793
|
+
|
|
1794
|
+
return _react2.default.createElement(
|
|
1795
|
+
'table',
|
|
1796
|
+
{ className: 'pvtUi' },
|
|
1797
|
+
_react2.default.createElement(
|
|
1798
|
+
'tbody',
|
|
1799
|
+
{ onClick: function onClick() {
|
|
1800
|
+
return _this15.setState({ openDropdown: false });
|
|
1801
|
+
} },
|
|
1802
|
+
_react2.default.createElement(
|
|
1803
|
+
'tr',
|
|
1804
|
+
null,
|
|
1805
|
+
rendererCell,
|
|
1806
|
+
aggregatorCell,
|
|
1807
|
+
colAttrsCell
|
|
1808
|
+
),
|
|
1809
|
+
_react2.default.createElement(
|
|
1810
|
+
'tr',
|
|
1811
|
+
null,
|
|
1812
|
+
unusedAttrsCell,
|
|
1813
|
+
rowAttrsCell,
|
|
1814
|
+
outputCell
|
|
1815
|
+
)
|
|
1816
|
+
)
|
|
1817
|
+
);
|
|
1818
|
+
}
|
|
1819
|
+
}]);
|
|
1820
|
+
|
|
1821
|
+
return PivotTableUI;
|
|
1822
|
+
}(_react2.default.PureComponent);
|
|
1823
|
+
|
|
1824
|
+
PivotTableUI.propTypes = Object.assign({}, _PivotTable2.default.propTypes, {
|
|
1825
|
+
onChange: _propTypes2.default.func.isRequired,
|
|
1826
|
+
hiddenAttributes: _propTypes2.default.arrayOf(_propTypes2.default.string),
|
|
1827
|
+
hiddenFromAggregators: _propTypes2.default.arrayOf(_propTypes2.default.string),
|
|
1828
|
+
hiddenFromDragDrop: _propTypes2.default.arrayOf(_propTypes2.default.string),
|
|
1829
|
+
unusedOrientationCutoff: _propTypes2.default.number,
|
|
1830
|
+
menuLimit: _propTypes2.default.number,
|
|
1831
|
+
colSorts: _propTypes2.default.objectOf(_propTypes2.default.oneOf(['ASC', 'DESC'])),
|
|
1832
|
+
rowSorts: _propTypes2.default.objectOf(_propTypes2.default.oneOf(['ASC', 'DESC']))
|
|
1833
|
+
});
|
|
1834
|
+
|
|
1835
|
+
PivotTableUI.defaultProps = Object.assign({}, _PivotTable2.default.defaultProps, {
|
|
1836
|
+
hiddenAttributes: [],
|
|
1837
|
+
hiddenFromAggregators: [],
|
|
1838
|
+
hiddenFromDragDrop: [],
|
|
1839
|
+
unusedOrientationCutoff: 85,
|
|
1840
|
+
menuLimit: 500,
|
|
1841
|
+
colSorts: {},
|
|
1842
|
+
rowSorts: {}
|
|
1843
|
+
});
|
|
1844
|
+
|
|
1845
|
+
exports.default = PivotTableUI;
|
|
1846
|
+
//# sourceMappingURL=PivotTableUI.js.map
|