@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
JavaScript
'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;