appxigon-react
Version:
Appxigon implementation on React JS
343 lines (305 loc) • 15.8 kB
JavaScript
;
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
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; }; }();
var _lodash = require('lodash');
var _react = require('react');
var _react2 = _interopRequireDefault(_react);
var _superagent = require('superagent');
var _superagent2 = _interopRequireDefault(_superagent);
var _redux = require('redux');
var _reactRedux = require('react-redux');
var _traverse = require('traverse');
var _traverse2 = _interopRequireDefault(_traverse);
var _utils = require('../lib/utils');
var _actions = require('../redux/actions');
var Actions = _interopRequireWildcard(_actions);
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
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; }
var kvReplaceToken = ['{', '}'];
// const toastr = require('toastr')
// toastr.options = {
// "closeButton": false,
// "debug": false,
// "newestOnTop": false,
// "progressBar": false,
// "positionClass": "toast-top-center",
// "preventDuplicates": false,
// "onclick": null,
// "showDuration": "300",
// "hideDuration": "1000",
// "timeOut": "5000",
// "extendedTimeOut": "1000",
// "showEasing": "swing",
// "hideEasing": "linear",
// "showMethod": "fadeIn",
// "hideMethod": "fadeOut"
// }
var ActionButton = function (_React$Component) {
_inherits(ActionButton, _React$Component);
function ActionButton(props) {
_classCallCheck(this, ActionButton);
var _this = _possibleConstructorReturn(this, (ActionButton.__proto__ || Object.getPrototypeOf(ActionButton)).call(this, props));
_this.state = {
id: _this.props.id,
schema: _this.props.schema,
// title : _t(get(this.props.schema, 'title')) || startCase(this.props.id),
// classes : get(this.props.AXGClasses, ['action.button'], 'btn btn-default'),
// classes : '',
showMessage: false,
toastr: (0, _lodash.get)(_this.props.schema, 'toastr', {}),
toastrMsg: (0, _lodash.get)(_this.props.schema, 'toastr.default', ''),
updates: (0, _lodash.get)(_this.props, 'schema.updates', '')
};
return _this;
}
_createClass(ActionButton, [{
key: 'showToastr',
value: function showToastr(msg) {
console.log('TODO: showToastr: ' + msg);
// if (msg) {
// toastr.info(msg)
// }
}
}, {
key: 'handleActions',
value: function handleActions() {
var _this2 = this;
var component = this;
var storeActions = component.props.actions;
component.setState({
showMessage: true
});
var actions = (0, _lodash.get)(this, 'state.schema.actions', []);
if (actions.length) {
actions.forEach(function (action) {
if ((typeof action === 'undefined' ? 'undefined' : _typeof(action)) === 'object' && Object.keys(action)[0] === 'set-value') {
var val = component.props.value;
Object.keys(val).forEach(function (k) {
storeActions.setAppxigonState({
// key: get(action, 'set-value.key'),
key: k,
value: val[k]
});
});
}
if ((typeof action === 'undefined' ? 'undefined' : _typeof(action)) === 'object' && Object.keys(action)[0] === 'close-modal') {
storeActions.closeModal();
}
if ((typeof action === 'undefined' ? 'undefined' : _typeof(action)) === 'object' && Object.keys(action)[0] === 'reset') {
// TODO: reset options ?
storeActions.resetInput();
}
if ((typeof action === 'undefined' ? 'undefined' : _typeof(action)) === 'object' && Object.keys(action)[0] === 'link') {
// TODO: condition
var viewId = action['link'];
storeActions.setViewId({ viewId: viewId });
}
if ((typeof action === 'undefined' ? 'undefined' : _typeof(action)) === 'object' && Object.keys(action)[0] === 'modal') {
var _viewId = action['modal'];
var schema = (0, _lodash.get)(_this2.props.appxigonSchema, 'views.' + _viewId);
// let schema = get(this.props.appxigonView, 'modalViewSchema')
storeActions.setModalViewSchema({ schema: schema });
}
if ((typeof action === 'undefined' ? 'undefined' : _typeof(action)) === 'object' && Object.keys(action)[0] === 'call') {
// console.log(`Action API Call: ${JSON.stringify(action)}`)
storeActions.setLoadingState({ loading: true });
var callType = (0, _lodash.get)(action, 'call.type', 'default');
var callRequired = callType !== 'signout' ? true : false;
var callMethod = (0, _lodash.get)(action, 'call.method', 'POST');
var canCall = ['GET', 'POST', 'PUT', 'DELETE', 'HEAD', 'OPTIONS', 'CONNECT'].includes(callMethod);
var endpoint = (0, _lodash.get)(action, 'call.endpoint', '');
var endpointTransform = (0, _lodash.get)(action, 'call.transform');
var postCallLink = (0, _lodash.get)(action, 'call.link');
var postCallAction = (0, _lodash.get)(action, 'call.action');
var callDelay = (0, _lodash.get)(action, 'call.delay', 500);
if (callType === 'signout') {
storeActions.signOut();
}
// delay call to make sure stuff in redux store is actually ready
setTimeout(function () {
// start of ajax call construction
if (callRequired && endpointTransform) {
var keyMap = endpointTransform;
var keyMapTransformed = (0, _lodash.mapValues)(keyMap, function (val) {
return (0, _lodash.get)(component.props, ['appxigonState', '' + val]);
});
// console.log(`keyMap: ${JSON.stringify(keyMap)}`)
// console.log(`keyMapTransformed: ${JSON.stringify(keyMapTransformed)}`)
endpoint = (0, _utils.kvReplace)(endpoint, keyMapTransformed, kvReplaceToken);
}
console.info('__ action.button:call: ' + JSON.stringify(endpoint));
var dataMap = (0, _lodash.get)(action, 'call.request-map', {});
// TODO: generic transform handling. NO hard coding
var integerTransform = (0, _lodash.get)(action, 'call.request-transform.integer', []);
// console.log(`Integer transforms: call: ${JSON.stringify(integerTransform)}`)
var data = (0, _traverse2.default)(dataMap).map(function (node) {
var nodeKey = this.key;
if (this.isLeaf) {
var retval = (0, _lodash.get)(component.props.appxigonState, [node], '');
// console.log(`key: ${nodeKey} : ${retval}`)
if ((0, _lodash.includes)(integerTransform, nodeKey)) {
console.log('key: ' + nodeKey + ' : ' + retval);
retval = parseInt(retval);
}
this.update(retval);
}
});
// console.log(`dataMap: ${JSON.stringify(dataMap)}`)
console.log('__ Request Data: ' + JSON.stringify(data));
callRequired && canCall && _superagent2.default[callMethod.toLowerCase()](endpoint) // REVIEW: default endpoint ?
.send(data).set('Accept', 'application/json').set('token', (0, _utils.getAuthToken)()).end(function (err, res) {
if (res) {
// console.log(`Response: ${JSON.stringify(res.body)}`)
var responseMap = (0, _lodash.get)(action, 'call.response-map', {});
// console.log(`Response Transform Map: ${JSON.stringify(responseMap)}`);
(0, _lodash.keys)(responseMap).forEach(function (k) {
// TODO: add key-value-replace templating
storeActions.setAppxigonState({
key: k,
value: res.body[responseMap[k]]
});
});
storeActions.setAppxigonState({
key: 'api-error',
value: ''
});
storeActions.setLoadingState({ loading: false });
// component.showToastr(get(component.state, 'toastr.success'))
// call type == 'signin'
if (callType === 'signin') {
storeActions.signIn({
error: (0, _lodash.get)(res.body, 'error'),
'error-description': (0, _lodash.get)(res.body, 'errordescription'),
userid: (0, _lodash.get)(res.body, 'email'),
token: (0, _lodash.get)(res.body, 'token'),
'token-expiry': (0, _lodash.get)(res.body, 'expiry')
});
}
// handles post call features
if ((0, _utils.validUserLogin)()) {
if (postCallLink) {
storeActions.setViewId({ viewId: postCallLink });
}
if (postCallAction) {
var callFn = (0, _lodash.get)(window, ['app', 'fn', postCallAction]);
if (typeof callFn == 'function') {
callFn();
} else {
console.error('AXG: ' + postCallAction + ' is undefined or not a function');
}
}
}
}
if (err) {
console.log('Error: ' + JSON.stringify(err));
// component.showToastr(get(component.state, 'toastr.fail'))
storeActions.setAppxigonState({
key: 'api-error',
value: (0, _lodash.get)(err, 'responseJSON.error.details')
});
storeActions.setLoadingState({ loading: false });
}
}); // end of ajax call
}, callDelay);
} // end of 'call' action
});
} else {
var msg = 'No action to handle';
console.log(msg);
// component.showToastr(msg)
}
// setTimeout(function(){
// component.setState({
// showMessage: false,
// })
// }, 1000);
// updates dependent list
// TODO: refactoring with other components
var updates = component.state.updates;
if (updates) {
if ((0, _lodash.isString)(updates)) {
updates = [updates];
}
console.log('Update dependency for: ' + JSON.stringify(updates));
updates.forEach(function (u) {
component.props.actions.setAppxigonState({
key: 'dependency.' + u,
// make it a string. value not important, just for redux value change detection
value: JSON.stringify((0, _lodash.random)(5, true))
});
});
}
}
}, {
key: 'componentWillReceiveProps',
value: function componentWillReceiveProps(nextProps) {
var p = this.props;
// REVIEW: is this a proper way ? Will this trigger unnecessary update?
// REVIEW: also in select.ls
var dependencyKey = 'dependency.' + this.props.AXGKey;
var nextDepencyValue = (0, _lodash.get)(nextProps.appxigonState, dependencyKey, '');
if (nextDepencyValue) {
// quick hack to re-run actions of the button click
// reset dependencyKey to null
p.actions.setAppxigonState({
key: dependencyKey,
// make it a string. value not important, just for redux value change detection
value: null
});
this.handleActions();
}
this.setState({
dependency: nextDepencyValue
});
}
}, {
key: 'render',
value: function render() {
// console.log(`schema: ${JSON.stringify(this.state.schema)}`)
// schema sample: {"type":"action.button","actions":["validate",{"link":"entities-info"}]}
// link: -> link to another view
// show / hide flag handled in parent component: Item
var p = this.props;
var show = this.props.show;
var contextualClasses = (0, _lodash.get)(this.state.schema, 'context', null);
var localClasses = (0, _lodash.get)(this.state.schema, 'classes');
// let buttonClasses = get(this.state.scheme, 'button-classes')
var faIcon = (0, _lodash.get)(this.state.schema, 'fa-icon');
var buttonClasses = (0, _lodash.get)(this.state.schema, 'button-classes');
var buttonClassNames = buttonClasses + (contextualClasses ? ' btn-' + contextualClasses : '') + ('' + (show ? '' : ' hidden')) + ('' + (buttonClasses ? ' ' + buttonClasses : ''));
var iconClasses = (0, _lodash.get)(this.state.schema, 'icon-classes');
var title = _t((0, _lodash.get)(p.schema, 'title')) || (0, _lodash.startCase)(p.id);
return _react2.default.createElement(
'div',
{ className: localClasses },
_react2.default.createElement(
'button',
{
type: 'button',
className: buttonClasses,
onClick: this.handleActions.bind(this) },
faIcon && _react2.default.createElement('i', { className: faIcon + ' ' + iconClasses }),
'\xA0',
!(0, _lodash.isEmpty)(this.state.toastr) && this.state.showMessage ? this.state.toastrMsg : title
)
);
}
}]);
return ActionButton;
}(_react2.default.Component);
function mapStateToProps(state) {
return {
appxigonState: state.AXGState,
appxigonSchema: state.AXGSchema.schema,
appxigonView: state.AXGView
};
}
function mapDispatchToProps(dispatch) {
return {
actions: (0, _redux.bindActionCreators)(Actions, dispatch)
};
}
module.exports = (0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps)(ActionButton);