UNPKG

@attivio/suit

Version:

Attivio SUIT, the Search UI Toolkit, is a library for creating search clients for searching the Attivio platform.

368 lines (311 loc) 12.5 kB
'use strict'; exports.__esModule = true; exports.default = exports.WizardPageState = exports.WizardPageDefinition = undefined; var _class3, _temp; var _react = require('react'); var _react2 = _interopRequireDefault(_react); var _Button = require('react-bootstrap/lib/Button'); var _Button2 = _interopRequireDefault(_Button); var _ButtonToolbar = require('react-bootstrap/lib/ButtonToolbar'); var _ButtonToolbar2 = _interopRequireDefault(_ButtonToolbar); var _Scrollable = require('./Scrollable'); var _Scrollable2 = _interopRequireDefault(_Scrollable); var _WizardSteps = require('./WizardSteps'); var _WizardSteps2 = _interopRequireDefault(_WizardSteps); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 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; } 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; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var WizardPageDefinition = /** * Set to true if this page is not required to be complete for the user to finish * the wizard. Defaults to false. */ /** * Callback used to validate the current state of the page. Returns a * promise so that you may make asynchronous calls to the server * if necessary to validate your fields. This Promise should resolve * to void in the case of the page being valid or to a string * describing the validation error in case it doesn't pass muster, * in which case the method should also deal with any updates to the * page's contents to show the error state to the user. The parameter * to this method is a map containing the values of all of the pages * in the wizard that are visible, in case the page's validation * depends on another page's state. * * If your page is always valid, you can omit this method. */ /** * The title for this page in the wizard. Will be displayed in * the list of pages that lets the user know where they are * in the process of completing the forms. */ exports.WizardPageDefinition = function WizardPageDefinition(key, title, page) { var getValue = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null; var validate = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : null; var aboutToShow = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : null; var optional = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : false; _classCallCheck(this, WizardPageDefinition); this.key = key; this.title = title; this.getValue = getValue; this.page = page; this.optional = optional; this.validate = validate; this.aboutToShow = aboutToShow; } /** * The component to display for the wizard page. */ /** * Callback used to allow the page to update itself based on * the state of the other pages in the wizard. Called right * before the wizard switches to show the page. * * If your page doesn't care, you can omit this method. */ /** * This callback is used to get the object representing the current * value for this page. This value is included in the map of all * values sent to the finish method for the wizard. Ideally, your * page will cache this as the user edits the values in the page's * controls so returning the value is fast. * * If your page updates the value object in the state when it changes, * you don't need to implement this method. In addition, if your * page is purely informational, you can omit this method. */ /** * This is an identifier for this wizard page. It must be * unique among the pages in a given wizard. */ ; var WizardPageState = exports.WizardPageState = function WizardPageState(key) { var value = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; var enabled = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true; var valid = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false; _classCallCheck(this, WizardPageState); this.key = key; this.value = value; this.enabled = enabled; this.valid = valid; }; /** * This component presents a series of pages which are used by the user, in sequence, * to enter data. The pages in the list can be enabled or disabled at any time. */ var Wizard = (_temp = _class3 = function (_React$Component) { _inherits(Wizard, _React$Component); function Wizard(props) { _classCallCheck(this, Wizard); // Set the initial state var _this = _possibleConstructorReturn(this, _React$Component.call(this, props)); var visiblePages = []; _this.props.pages.forEach(function (page) { visiblePages.push(page.key); }); _this.state = { visiblePages: visiblePages, currentKey: _this.props.pages[0].key, currentPage: _this.props.pages[0], currentPageValid: false, currentPageError: null }; _this.cancel = _this.cancel.bind(_this); _this.finish = _this.finish.bind(_this); _this.nextPage = _this.nextPage.bind(_this); _this.previousPage = _this.previousPage.bind(_this); return _this; } Wizard.prototype.componentDidMount = function componentDidMount() { // Try to validate the first page this.validateCurrentPage(); }; Wizard.prototype.getPage = function getPage(pageKey) { var index = this.props.pages.findIndex(function (page) { return page.key === pageKey; }); return this.props.pages[index]; }; Wizard.prototype.getNextPageKey = function getNextPageKey() { var _this2 = this; var currentPageIndex = this.state.visiblePages.findIndex(function (pageKey) { return pageKey === _this2.state.currentKey; }); if (currentPageIndex >= 0) { var nextPageIndex = currentPageIndex + 1; if (nextPageIndex < this.state.visiblePages.length) { return this.state.visiblePages[nextPageIndex]; } } return null; }; Wizard.prototype.getPreviousPageKey = function getPreviousPageKey() { var _this3 = this; var currentPageIndex = this.state.visiblePages.findIndex(function (pageKey) { return pageKey === _this3.state.currentKey; }); if (currentPageIndex >= 1) { var previousPageIndex = currentPageIndex - 1; return this.state.visiblePages[previousPageIndex]; } return null; }; Wizard.prototype.getAllPageValues = function getAllPageValues() { var _this4 = this; var values = new Map(); this.state.visiblePages.forEach(function (visiblePageKey) { var page = _this4.getPage(visiblePageKey); var pageValue = page.getValue ? page.getValue() : {}; values.set(visiblePageKey, pageValue); }); return values; }; Wizard.prototype.validateCurrentPage = function validateCurrentPage() { var _this5 = this; var values = this.getAllPageValues(); if (this.state.currentPage.validate) { this.state.currentPage.validate(values).then(function () { _this5.setState({ currentPageValid: true, currentPageError: null }); }).catch(function (error) { _this5.setState({ currentPageValid: false, currentPageError: error }); }); } else { // No callback = always valid this.setState({ currentPageValid: true, currentPageError: null }); } }; Wizard.prototype.cancel = function cancel() { this.props.onFinish(null); }; Wizard.prototype.finish = function finish() { var values = this.getAllPageValues(); this.props.onFinish(values); }; Wizard.prototype.changePage = function changePage(newPageKey) { var _this6 = this; if (newPageKey) { var newPage = this.getPage(newPageKey); var aboutToShow = newPage.aboutToShow; if (aboutToShow !== null) { aboutToShow(this.getAllPageValues()); } this.setState({ currentKey: newPageKey, currentPage: newPage }, function () { _this6.validateCurrentPage(); }); } }; Wizard.prototype.nextPage = function nextPage() { this.changePage(this.getNextPageKey()); }; Wizard.prototype.previousPage = function previousPage() { this.changePage(this.getPreviousPageKey()); }; Wizard.prototype.doneWithRequired = function doneWithRequired() { var _this7 = this; var currentPageIndex = this.state.visiblePages.indexOf(this.state.currentKey); var remainingPages = this.state.visiblePages.slice(currentPageIndex + 1); if (remainingPages && remainingPages.length) { // There are remaining visible pages... check if any is required. return !remainingPages.some(function (remainingPageKey) { return !_this7.getPage(remainingPageKey).optional; }); } // We're on the last visible page, so we're done! return true; }; Wizard.prototype.render = function render() { var _this8 = this; if (this.props.show) { var steps = []; this.state.visiblePages.forEach(function (visiblePageKey) { var visiblePage = _this8.getPage(visiblePageKey); steps.push(new _WizardSteps.WizardStep(visiblePageKey, visiblePage.title)); }); var previousKey = this.getPreviousPageKey(); var nextKey = this.getNextPageKey(); // We can always go back if there's a previous page var canPrevious = !!previousKey; // We can go forward if there's a next page AND the current one is valid var canNext = !!nextKey && this.state.currentPageValid; // We can finish if there is no next page or the remaining pages are not required // AND the current(last) one is valid var canFinish = !nextKey || this.doneWithRequired(); var finishStyle = canFinish ? 'primary' : 'default'; var nextStyle = canNext && !canFinish ? 'primary' : 'default'; return _react2.default.createElement( 'div', { style: { display: 'flex', flexFlow: 'column', height: '100%' } }, _react2.default.createElement(_WizardSteps2.default, { steps: steps, currentStep: this.state.currentKey, goToPage: function goToPage() {}, style: { flex: '0 1 auto' } }), _react2.default.createElement( _Scrollable2.default, { style: { flex: '1 1 auto' } }, _react2.default.createElement( 'h3', null, this.state.currentPage.title ), this.state.currentPage.page ), _react2.default.createElement( 'div', { style: { flex: '0 1 40px' } }, _react2.default.createElement( _ButtonToolbar2.default, { style: { float: 'right' } }, _react2.default.createElement( _Button2.default, { onClick: this.cancel }, 'Cancel' ), _react2.default.createElement( _Button2.default, { disabled: !canPrevious, onClick: this.previousPage }, 'Previous' ), _react2.default.createElement( _Button2.default, { disabled: !canNext, bsStyle: nextStyle, onClick: this.nextPage }, 'Next' ), _react2.default.createElement( _Button2.default, { disabled: !canFinish, bsStyle: finishStyle, onClick: this.finish }, 'Finish' ) ) ) ); } // Not shown... return null; }; return Wizard; }(_react2.default.Component), _class3.displayName = 'Wizard', _temp); exports.default = Wizard; Wizard.WizardPageDefinition = WizardPageDefinition;