UNPKG

react-editable-json-tree

Version:
561 lines (494 loc) 20.9 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _promise = require('babel-runtime/core-js/promise'); var _promise2 = _interopRequireDefault(_promise); var _toConsumableArray2 = require('babel-runtime/helpers/toConsumableArray'); var _toConsumableArray3 = _interopRequireDefault(_toConsumableArray2); var _getPrototypeOf = require('babel-runtime/core-js/object/get-prototype-of'); var _getPrototypeOf2 = _interopRequireDefault(_getPrototypeOf); var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck'); var _classCallCheck3 = _interopRequireDefault(_classCallCheck2); var _createClass2 = require('babel-runtime/helpers/createClass'); var _createClass3 = _interopRequireDefault(_createClass2); var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn'); var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2); var _inherits2 = require('babel-runtime/helpers/inherits'); var _inherits3 = _interopRequireDefault(_inherits2); var _react = require('react'); var _react2 = _interopRequireDefault(_react); var _propTypes = require('prop-types'); var _propTypes2 = _interopRequireDefault(_propTypes); var _JsonNode = require('./JsonNode'); var _JsonNode2 = _interopRequireDefault(_JsonNode); var _JsonAddValue = require('./JsonAddValue'); var _JsonAddValue2 = _interopRequireDefault(_JsonAddValue); var _objectTypes = require('../utils/objectTypes'); var _deltaTypes = require('../types/deltaTypes'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /* ************************************* */ /* ******** VARIABLES ******** */ /* ************************************* */ // Prop types /* * Author: Alexandre Havrileck (Oxyno-zeta) * Date: 20/10/16 * Licence: See Readme */ /* ************************************* */ /* ******** IMPORTS ******** */ /* ************************************* */ var propTypes = { data: _propTypes2.default.array.isRequired, name: _propTypes2.default.string.isRequired, isCollapsed: _propTypes2.default.func.isRequired, keyPath: _propTypes2.default.array, deep: _propTypes2.default.number, handleRemove: _propTypes2.default.func, onUpdate: _propTypes2.default.func.isRequired, onDeltaUpdate: _propTypes2.default.func.isRequired, readOnly: _propTypes2.default.func.isRequired, dataType: _propTypes2.default.string, getStyle: _propTypes2.default.func.isRequired, addButtonElement: _propTypes2.default.element, cancelButtonElement: _propTypes2.default.element, editButtonElement: _propTypes2.default.element, inputElementGenerator: _propTypes2.default.func.isRequired, textareaElementGenerator: _propTypes2.default.func.isRequired, minusMenuElement: _propTypes2.default.element, plusMenuElement: _propTypes2.default.element, beforeRemoveAction: _propTypes2.default.func, beforeAddAction: _propTypes2.default.func, beforeUpdateAction: _propTypes2.default.func, logger: _propTypes2.default.object.isRequired, onSubmitValueParser: _propTypes2.default.func.isRequired }; // Default props var defaultProps = { keyPath: [], deep: 0, minusMenuElement: _react2.default.createElement( 'span', null, ' - ' ), plusMenuElement: _react2.default.createElement( 'span', null, ' + ' ) }; /* ************************************* */ /* ******** COMPONENT ******** */ /* ************************************* */ var JsonArray = function (_Component) { (0, _inherits3.default)(JsonArray, _Component); function JsonArray(props) { (0, _classCallCheck3.default)(this, JsonArray); var _this = (0, _possibleConstructorReturn3.default)(this, (JsonArray.__proto__ || (0, _getPrototypeOf2.default)(JsonArray)).call(this, props)); var keyPath = [].concat((0, _toConsumableArray3.default)(props.keyPath), [props.name]); _this.state = { data: props.data, name: props.name, keyPath: keyPath, deep: props.deep, nextDeep: props.deep + 1, collapsed: props.isCollapsed(keyPath, props.deep, props.data), addFormVisible: false }; // Bind _this.handleCollapseMode = _this.handleCollapseMode.bind(_this); _this.handleRemoveItem = _this.handleRemoveItem.bind(_this); _this.handleAddMode = _this.handleAddMode.bind(_this); _this.handleAddValueAdd = _this.handleAddValueAdd.bind(_this); _this.handleAddValueCancel = _this.handleAddValueCancel.bind(_this); _this.handleEditValue = _this.handleEditValue.bind(_this); _this.onChildUpdate = _this.onChildUpdate.bind(_this); _this.renderCollapsed = _this.renderCollapsed.bind(_this); _this.renderNotCollapsed = _this.renderNotCollapsed.bind(_this); return _this; } (0, _createClass3.default)(JsonArray, [{ key: 'componentWillReceiveProps', value: function componentWillReceiveProps(nextProps) { this.setState({ data: nextProps.data }); } }, { key: 'onChildUpdate', value: function onChildUpdate(childKey, childData) { var _state = this.state, data = _state.data, keyPath = _state.keyPath; // Update data data[childKey] = childData; // Put new data this.setState({ data: data }); // Spread var onUpdate = this.props.onUpdate; var size = keyPath.length; onUpdate(keyPath[size - 1], data); } }, { key: 'handleAddMode', value: function handleAddMode() { this.setState({ addFormVisible: true }); } }, { key: 'handleCollapseMode', value: function handleCollapseMode() { this.setState({ collapsed: !this.state.collapsed }); } }, { key: 'handleRemoveItem', value: function handleRemoveItem(index) { var _this2 = this; return function () { var _props = _this2.props, beforeRemoveAction = _props.beforeRemoveAction, logger = _props.logger; var _state2 = _this2.state, data = _state2.data, keyPath = _state2.keyPath, deep = _state2.nextDeep; var oldValue = data[index]; // Before Remove Action beforeRemoveAction(index, keyPath, deep, oldValue).then(function () { var objType = (0, _objectTypes.getObjectType)(data[index]); var deltaUpdateResult = { keyPath: keyPath, deep: deep, key: index, oldValue: oldValue }; if (objType === 'Object' || objType === 'Array') { deltaUpdateResult.type = _deltaTypes.UPDATE_DELTA_TYPE; deltaUpdateResult.newValue = null; data[index] = null; } else { deltaUpdateResult.type = _deltaTypes.REMOVE_DELTA_TYPE; data.splice(index, 1); } _this2.setState({ data: data }); // Spread new update var _props2 = _this2.props, onUpdate = _props2.onUpdate, onDeltaUpdate = _props2.onDeltaUpdate; onUpdate(keyPath[keyPath.length - 1], data); // Spread delta update onDeltaUpdate(deltaUpdateResult); }).catch(logger.error); }; } }, { key: 'handleAddValueAdd', value: function handleAddValueAdd(_ref) { var _this3 = this; var newValue = _ref.newValue; var _state3 = this.state, data = _state3.data, keyPath = _state3.keyPath, deep = _state3.nextDeep; var _props3 = this.props, beforeAddAction = _props3.beforeAddAction, logger = _props3.logger; beforeAddAction(data.length, keyPath, deep, newValue).then(function () { // Update data var newData = [].concat((0, _toConsumableArray3.default)(data), [newValue]); _this3.setState({ data: newData }); // Cancel add to close _this3.handleAddValueCancel(); // Spread new update var _props4 = _this3.props, onUpdate = _props4.onUpdate, onDeltaUpdate = _props4.onDeltaUpdate; onUpdate(keyPath[keyPath.length - 1], newData); // Spread delta update onDeltaUpdate({ type: _deltaTypes.ADD_DELTA_TYPE, keyPath: keyPath, deep: deep, key: newData.length - 1, newValue: newValue }); }).catch(logger.error); } }, { key: 'handleAddValueCancel', value: function handleAddValueCancel() { this.setState({ addFormVisible: false }); } }, { key: 'handleEditValue', value: function handleEditValue(_ref2) { var _this4 = this; var key = _ref2.key, value = _ref2.value; return new _promise2.default(function (resolve, reject) { var beforeUpdateAction = _this4.props.beforeUpdateAction; var _state4 = _this4.state, data = _state4.data, keyPath = _state4.keyPath, deep = _state4.nextDeep; // Old value var oldValue = data[key]; // Before update action beforeUpdateAction(key, keyPath, deep, oldValue, value).then(function () { // Update value data[key] = value; // Set state _this4.setState({ data: data }); // Spread new update var _props5 = _this4.props, onUpdate = _props5.onUpdate, onDeltaUpdate = _props5.onDeltaUpdate; onUpdate(keyPath[keyPath.length - 1], data); // Spread delta update onDeltaUpdate({ type: _deltaTypes.UPDATE_DELTA_TYPE, keyPath: keyPath, deep: deep, key: key, newValue: value, oldValue: oldValue }); // Resolve resolve(); }).catch(reject); }); } }, { key: 'renderCollapsed', value: function renderCollapsed() { var _state5 = this.state, name = _state5.name, data = _state5.data, keyPath = _state5.keyPath, deep = _state5.deep; var _props6 = this.props, handleRemove = _props6.handleRemove, readOnly = _props6.readOnly, getStyle = _props6.getStyle, dataType = _props6.dataType, minusMenuElement = _props6.minusMenuElement; var _getStyle = getStyle(name, data, keyPath, deep, dataType), minus = _getStyle.minus, collapsed = _getStyle.collapsed; var collapseValue = ' [...]'; var numberOfItems = data.length; var minusElement = null; // Check if readOnly is activated if (!readOnly(name, data, keyPath, deep, dataType)) { var minusMenuLayout = _react2.default.cloneElement(minusMenuElement, { onClick: handleRemove, className: 'rejt-minus-menu', style: minus }); minusElement = deep !== -1 ? minusMenuLayout : null; } var itemName = numberOfItems > 1 ? 'items' : 'item'; /* eslint-disable jsx-a11y/no-static-element-interactions */ return _react2.default.createElement( 'span', { className: 'rejt-collapsed' }, _react2.default.createElement( 'span', { className: 'rejt-collapsed-text', style: collapsed, onClick: this.handleCollapseMode }, collapseValue, ' ', numberOfItems, ' ', itemName ), minusElement ); /* eslint-enable */ } }, { key: 'renderNotCollapsed', value: function renderNotCollapsed() { var _this5 = this; var _state6 = this.state, name = _state6.name, data = _state6.data, keyPath = _state6.keyPath, deep = _state6.deep, addFormVisible = _state6.addFormVisible, nextDeep = _state6.nextDeep; var _props7 = this.props, isCollapsed = _props7.isCollapsed, handleRemove = _props7.handleRemove, onDeltaUpdate = _props7.onDeltaUpdate, readOnly = _props7.readOnly, getStyle = _props7.getStyle, dataType = _props7.dataType, addButtonElement = _props7.addButtonElement, cancelButtonElement = _props7.cancelButtonElement, editButtonElement = _props7.editButtonElement, inputElementGenerator = _props7.inputElementGenerator, textareaElementGenerator = _props7.textareaElementGenerator, minusMenuElement = _props7.minusMenuElement, plusMenuElement = _props7.plusMenuElement, beforeRemoveAction = _props7.beforeRemoveAction, beforeAddAction = _props7.beforeAddAction, beforeUpdateAction = _props7.beforeUpdateAction, logger = _props7.logger, onSubmitValueParser = _props7.onSubmitValueParser; var _getStyle2 = getStyle(name, data, keyPath, deep, dataType), minus = _getStyle2.minus, plus = _getStyle2.plus, delimiter = _getStyle2.delimiter, ul = _getStyle2.ul, addForm = _getStyle2.addForm; var minusElement = null; var readOnlyResult = readOnly(name, data, keyPath, deep, dataType); // Check if readOnly is activated if (!readOnlyResult) { var minusMenuLayout = _react2.default.cloneElement(minusMenuElement, { onClick: handleRemove, className: 'rejt-minus-menu', style: minus }); minusElement = deep !== -1 ? minusMenuLayout : null; } var list = data.map(function (item, index) { return _react2.default.createElement(_JsonNode2.default, { key: index, name: '' + index, data: item, keyPath: keyPath, deep: nextDeep, isCollapsed: isCollapsed, handleRemove: _this5.handleRemoveItem(index), handleUpdateValue: _this5.handleEditValue, onUpdate: _this5.onChildUpdate, onDeltaUpdate: onDeltaUpdate, readOnly: readOnly, getStyle: getStyle, addButtonElement: addButtonElement, cancelButtonElement: cancelButtonElement, editButtonElement: editButtonElement, inputElementGenerator: inputElementGenerator, textareaElementGenerator: textareaElementGenerator, minusMenuElement: minusMenuElement, plusMenuElement: plusMenuElement, beforeRemoveAction: beforeRemoveAction, beforeAddAction: beforeAddAction, beforeUpdateAction: beforeUpdateAction, logger: logger, onSubmitValueParser: onSubmitValueParser }); }); var onlyValue = true; var menu = null; // Check if readOnly is activated if (!readOnlyResult) { var plusMenuLayout = _react2.default.cloneElement(plusMenuElement, { onClick: this.handleAddMode, className: 'rejt-plus-menu', style: plus }); menu = addFormVisible ? _react2.default.createElement( 'span', { className: 'rejt-add-form', style: addForm }, _react2.default.createElement(_JsonAddValue2.default, { handleAdd: this.handleAddValueAdd, handleCancel: this.handleAddValueCancel, onlyValue: onlyValue, addButtonElement: addButtonElement, cancelButtonElement: cancelButtonElement, inputElementGenerator: inputElementGenerator, keyPath: keyPath, deep: deep, onSubmitValueParser: onSubmitValueParser }) ) : _react2.default.createElement( 'span', null, plusMenuLayout, ' ', minusElement ); } var startObject = '['; var endObject = ']'; return _react2.default.createElement( 'span', { className: 'rejt-not-collapsed' }, _react2.default.createElement( 'span', { className: 'rejt-not-collapsed-delimiter', style: delimiter }, startObject ), _react2.default.createElement( 'ul', { className: 'rejt-not-collapsed-list', style: ul }, list ), _react2.default.createElement( 'span', { className: 'rejt-not-collapsed-delimiter', style: delimiter }, endObject ), menu ); } }, { key: 'render', value: function render() { var _state7 = this.state, name = _state7.name, collapsed = _state7.collapsed, data = _state7.data, keyPath = _state7.keyPath, deep = _state7.deep; var _props8 = this.props, dataType = _props8.dataType, getStyle = _props8.getStyle; var value = collapsed ? this.renderCollapsed() : this.renderNotCollapsed(); var style = getStyle(name, data, keyPath, deep, dataType); /* eslint-disable jsx-a11y/no-static-element-interactions */ return _react2.default.createElement( 'div', { className: 'rejt-array-node' }, _react2.default.createElement( 'span', { onClick: this.handleCollapseMode }, _react2.default.createElement( 'span', { className: 'rejt-name', style: style.name }, name, ' : ' ) ), value ); /* eslint-enable */ } }]); return JsonArray; }(_react.Component); // Add prop types JsonArray.propTypes = propTypes; // Add default props JsonArray.defaultProps = defaultProps; /* ************************************* */ /* ******** EXPORTS ******** */ /* ************************************* */ exports.default = JsonArray;