AutobinDialog.js 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  1. 'use strict';
  2. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  3. 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; }
  4. 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; }
  5. /**
  6. * Licensed Materials - Property of IBM
  7. * IBM Cognos Products: Dashboard (C) Copyright IBM Corp. 2018, 2020
  8. * US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
  9. */
  10. define(['../lib/@waca/core-client/js/core-client/ui/core/View', 'underscore', '../widgets/livewidget/nls/StringResources', 'react', 'react-dom', 'ca-ui-toolkit'], function (View, _, stringResources, React, ReactDOM, Toolkit) {
  11. /* eslint react/prop-types: 0 */ // TODO: Remove once we have prop-types brought in from glass.
  12. var ToggleSwitch = Toolkit.ToggleSwitch;
  13. var Label = Toolkit.Label;
  14. var NumberInput = Toolkit.NumberInput;
  15. var minNumberOfBins = 5;
  16. var maxNumberOfBins = 100;
  17. var TitleDiv = function (_React$Component) {
  18. _inherits(TitleDiv, _React$Component);
  19. function TitleDiv() {
  20. _classCallCheck(this, TitleDiv);
  21. return _possibleConstructorReturn(this, _React$Component.apply(this, arguments));
  22. }
  23. TitleDiv.prototype.componentDidUpdate = function componentDidUpdate() {
  24. this.props.setFocusOnNumberInput();
  25. };
  26. TitleDiv.prototype.render = function render() {
  27. var _this2 = this;
  28. var titleLabel = stringResources.get('autoBinActionText');
  29. var binCountLabel = stringResources.get('propAutoBinCount');
  30. var titleId = 'ag-toggle-switch';
  31. var binCountId = 'ag-number-input';
  32. var toggle = React.createElement(ToggleSwitch, {
  33. checked: this.props.toggleChecked,
  34. onChange: this.props.onToggleChange,
  35. small: true,
  36. 'aria-labelledby': titleId
  37. });
  38. var numberInput = React.createElement(NumberInput, {
  39. className: 'numberOfBinsInput',
  40. value: this.props.numberOfBins,
  41. max: maxNumberOfBins,
  42. min: minNumberOfBins,
  43. hasValidationError: !this.props.validateNumberOfBinsInput(this.props.numberOfBins),
  44. onChange: function onChange(n) {
  45. return _this2.props.numberOfBinsChanged(n);
  46. },
  47. disabled: !this.props.toggleChecked,
  48. ref: this.props.numberInputRef
  49. });
  50. return React.createElement(
  51. 'div',
  52. { className: 'content' },
  53. React.createElement(
  54. 'div',
  55. { className: 'selectionRow' },
  56. React.createElement(Label, {
  57. id: titleId,
  58. className: 'selectionlabel',
  59. label: titleLabel
  60. }),
  61. toggle
  62. ),
  63. React.createElement(
  64. 'div',
  65. { className: 'selectionRow' },
  66. React.createElement(Label, {
  67. id: binCountId,
  68. className: 'selectionlabel',
  69. label: binCountLabel
  70. }),
  71. numberInput
  72. )
  73. );
  74. };
  75. return TitleDiv;
  76. }(React.Component);
  77. /*
  78. * Class to render the react flyout components
  79. */
  80. var ReactComponents = function (_React$Component2) {
  81. _inherits(ReactComponents, _React$Component2);
  82. /*
  83. * The props hold a state that should be used as this classes state.
  84. * When the state changes the component gets re-rendered. So when the
  85. * toggle state or checkbox state changes we update the state to re-render
  86. * the component while also calling a callback to tell the parent flyout
  87. * of the event.
  88. */
  89. function ReactComponents(props) {
  90. _classCallCheck(this, ReactComponents);
  91. var _this3 = _possibleConstructorReturn(this, _React$Component2.call(this, props));
  92. _this3.state = _.clone(props.state);
  93. _this3.debouncedAutobinTrigger = _this3.props.getDebouncedAutobinTrigger();
  94. return _this3;
  95. }
  96. /*
  97. * Toggle switch state changed.
  98. */
  99. ReactComponents.prototype.toggleChanged = function toggleChanged() {
  100. var newState = _.extend({}, this.state, { toggleChecked: !this.state.toggleChecked });
  101. this.setState(newState);
  102. this.props.onToggleStateChanged(newState);
  103. };
  104. ReactComponents.prototype.validateNumberOfBinsInput = function validateNumberOfBinsInput(newNumber) {
  105. if (this.toggleChecked === false) {
  106. return true;
  107. }
  108. var parsed = parseInt(newNumber, 10);
  109. if (isNaN(parsed)) {
  110. return false;
  111. }
  112. if (parsed > maxNumberOfBins || parsed < minNumberOfBins) {
  113. return false;
  114. }
  115. return true;
  116. };
  117. ReactComponents.prototype.numberOfBinsChanged = function numberOfBinsChanged(newNumber) {
  118. if (this.state.toggleChecked == false) {
  119. return;
  120. }
  121. var parsed = parseInt(newNumber, 10);
  122. if (isNaN(parsed)) {
  123. return;
  124. }
  125. if (this.state.numberOfBins != parsed) {
  126. this.setState({ numberOfBins: parsed });
  127. if (parsed <= maxNumberOfBins && parsed >= minNumberOfBins) {
  128. this.debouncedAutobinTrigger(parsed);
  129. }
  130. }
  131. this.props.setFocusOnNumberInput();
  132. };
  133. ReactComponents.prototype.render = function render() {
  134. var _this4 = this;
  135. return React.createElement(TitleDiv, { onToggleChange: function onToggleChange() {
  136. return _this4.toggleChanged();
  137. },
  138. setFocusOnNumberInput: function setFocusOnNumberInput() {
  139. return _this4.props.setFocusOnNumberInput();
  140. },
  141. numberInputRef: this.props.numberInputRef,
  142. toggleChecked: this.state.toggleChecked,
  143. numberOfBins: this.state.numberOfBins,
  144. validateNumberOfBinsInput: this.validateNumberOfBinsInput,
  145. numberOfBinsChanged: function numberOfBinsChanged(newNumber) {
  146. return _this4.numberOfBinsChanged(newNumber);
  147. } });
  148. };
  149. return ReactComponents;
  150. }(React.Component);
  151. /**
  152. * @classdesc Creates an autobin dialog
  153. *
  154. * @public
  155. *
  156. * @param {object} options.slot - The data slot
  157. * @param {object} options.widget - The widget
  158. */
  159. var AutobinView = function (_View) {
  160. _inherits(AutobinView, _View);
  161. function AutobinView() {
  162. _classCallCheck(this, AutobinView);
  163. for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
  164. args[_key] = arguments[_key];
  165. }
  166. var _this5 = _possibleConstructorReturn(this, _View.call.apply(_View, [this].concat(args)));
  167. var options = args[0] || {};
  168. _this5._iHeight = '212';
  169. _this5._iWidth = '290';
  170. _this5.height = options.state.height;
  171. _this5.width = options.state.width;
  172. _this5.defaultNumberOfBins = options.state.defaultNumberOfBins;
  173. _this5.autoBinEventHandler = options.actions.apply;
  174. _this5.numberInputRef = React.createRef();
  175. var binning = options.state.binningStateCb();
  176. if (binning && binning.bins) {
  177. _this5.binningState = {
  178. numberOfBins: binning.bins
  179. };
  180. }
  181. return _this5;
  182. }
  183. AutobinView.prototype.remove = function remove() {
  184. if (this.$el) {
  185. ReactDOM.unmountComponentAtNode(this.$el[0]);
  186. }
  187. this.viewState = null;
  188. return _View.prototype.remove.call(this);
  189. };
  190. AutobinView.prototype.render = function render() {
  191. var _this6 = this;
  192. this.$el.addClass('popoverDialogContainer autoBinAction').height(this._iHeight + 'px').width(this._iWidth + 'px');
  193. var numberOfBins;
  194. if (this.binningState && this.binningState.numberOfBins) {
  195. numberOfBins = this.binningState.numberOfBins;
  196. } else {
  197. numberOfBins = this.defaultNumberOfBins;
  198. }
  199. this.reactComponents = ReactDOM.render(React.createElement(ReactComponents, {
  200. state: {
  201. 'toggleChecked': this.binningState ? true : false,
  202. 'numberOfBins': numberOfBins
  203. },
  204. numberInputRef: this.numberInputRef,
  205. onToggleStateChanged: function onToggleStateChanged(newState) {
  206. return _this6.onToggleChange(newState);
  207. },
  208. setFocusOnNumberInput: function setFocusOnNumberInput() {
  209. return _this6._setFocusOnNumberInput();
  210. },
  211. getDebouncedAutobinTrigger: function getDebouncedAutobinTrigger() {
  212. return _this6.getDebouncedAutobinTrigger();
  213. } }), this.$el[0]);
  214. return this;
  215. };
  216. /**
  217. * @override overrides the setFocus from authoring toolbar class that is invoked from Flyout class
  218. * focus will be set in the input if the auto group is in enabled state (see _setFocusOnNumberInput)
  219. */
  220. AutobinView.prototype.setFocus = function setFocus() {
  221. this._setFocusOnNumberInput();
  222. };
  223. AutobinView.prototype.onToggleChange = function onToggleChange(reactState) {
  224. if (this.binningState) {
  225. this.binningState = null;
  226. } else {
  227. this.binningState = {
  228. numberOfBins: reactState.numberOfBins
  229. };
  230. }
  231. if (this.binningState) {
  232. this.autoBinEventHandler(this.binningState);
  233. } else {
  234. this.autoBinEventHandler(null);
  235. }
  236. };
  237. AutobinView.prototype.getDebouncedAutobinTrigger = function getDebouncedAutobinTrigger() {
  238. var _this7 = this;
  239. return _.debounce(function (numberOfBins) {
  240. return _this7.numberOfBinsChanged(numberOfBins);
  241. }, 500);
  242. };
  243. AutobinView.prototype.numberOfBinsChanged = function numberOfBinsChanged(numberOfBins) {
  244. if (this.binningState) {
  245. this.binningState.numberOfBins = numberOfBins;
  246. this.autoBinEventHandler(this.binningState);
  247. }
  248. };
  249. /**
  250. * calls focus from toolkit NumberInput component if the auto-group is enabled
  251. */
  252. AutobinView.prototype._setFocusOnNumberInput = function _setFocusOnNumberInput() {
  253. if (this.binningState) {
  254. this.numberInputRef && this.numberInputRef.current.focus();
  255. }
  256. };
  257. return AutobinView;
  258. }(View);
  259. return AutobinView;
  260. });
  261. //# sourceMappingURL=AutobinDialog.js.map