UNPKG

@bigfishtv/cockpit

Version:

277 lines (237 loc) 9.72 kB
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; var _class, _class2, _temp; function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; } 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; } import PropTypes from 'prop-types'; import React, { Component } from 'react'; import { withFormValue, update } from '@bigfishtv/react-forms'; import deepDuplicate from '../../utils/deepDuplicate'; import newId from '../../utils/newId'; import { modalHandler } from '../modal/ModalHost'; import Breadcrumb from '../breadcrumb/Breadcrumb'; import SectionTray from '../SectionTray'; import Section from '../container/Section'; import ReorderableCellsModal from '../modal/ReorderableCellsModal'; import SectionsPublishModal from '../modal/SectionsPublishModal'; /* Section types data format: [ { property: 'example_sections', title: 'Example Section Title', icon: 'example-icon', component: ExampleSection, } ] */ // we define this because react-docgen fails when defaultProp directly references an imported component var DefaultSectionTray = function DefaultSectionTray(props) { return React.createElement(SectionTray, props); }; var Sections = withFormValue(_class = (_temp = _class2 = function (_Component) { _inherits(Sections, _Component); function Sections() { _classCallCheck(this, Sections); var _this = _possibleConstructorReturn(this, _Component.call(this)); _this.addSection = function (sectionType) { var _this$props = _this.props, formValue = _this$props.formValue, getBlankSection = _this$props.getBlankSection; if (!sectionType.property) { console.warn("sectionType.property doesn't exist for " + sectionType.title); return; } var values = formValue.select(sectionType.property); var value = values.value && values.value.length ? values.value.slice() : []; value.push(_extends({}, getBlankSection(sectionType, formValue), { id: newId(), order: _this.getNextOrderId(), isNew: true })); values.update(value); }; _this.handleReorder = function (newList) { var formValue = _this.props.formValue; formValue.update(newList.reduce(function (acc, item, order) { return update(acc, [item.property, item.index, 'order'], order); }, formValue.value)); }; _this.renderSection = function (_ref, i, allSections) { var sectionType = _ref.sectionType, section = _ref.section, index = _ref.index; var _this$props2 = _this.props, SectionTypes = _this$props2.SectionTypes, formValue = _this$props2.formValue, select = _this$props2.select, props = _objectWithoutProperties(_this$props2, ['SectionTypes', 'formValue', 'select']); var sectionFormValue = formValue.select([sectionType.property, index]); return React.createElement( Breadcrumb, { title: section.title || sectionType.title, key: '' + sectionType.property + index + (_this.state.collapsed ? 'a' : 'b') }, React.createElement(Section, _extends({}, props, { Component: sectionType.component, icon: sectionType.icon, sectionProperty: sectionType.property, formValue: sectionFormValue, collapsed: _this.state.collapsed, onToggleCollapsed: function onToggleCollapsed() { return _this.setState({ collapsed: !_this.state.collapsed }); }, onDuplicate: function onDuplicate() { return _this.duplicateSection(sectionType, index); }, onRemove: function onRemove() { return _this.removeSection(sectionType, index); }, onReorder: function onReorder() { return _this.reorderSections(section); }, onPublishEdit: function onPublishEdit() { return _this.publishSections(sectionFormValue, allSections); }, isNew: section.isNew, allSections: allSections })) ); }; _this.state = { collapsed: false }; return _this; } Sections.prototype.duplicateSection = function duplicateSection(sectionType, index) { var formValue = this.props.formValue; var value = formValue.value; // update order for all sections greater duplicated section var order = value[sectionType.property][index].order; this.getSections().filter(function (_s) { return _s.section.order > order; }).forEach(function (_s) { var path = [_s.sectionType.property, _s.index, 'order']; value = update(value, path, formValue.select(path).value + 1); }); // duplicate the section var sections = formValue.select(sectionType.property).value; var section = _extends({}, deepDuplicate(sections[index]), { order: order + 1 // splice new section into existing array });sections = [].concat(sections.slice(0, index + 1), [section], sections.slice(index + 1)); // update sections array into value value = update(value, [sectionType.property], sections); // update formValue in one fell swoop formValue.update(value); }; Sections.prototype.removeSection = function removeSection(sectionType, index) { if (!confirm('Are you sure you want to remove this?')) { return; } var values = this.props.formValue.select(sectionType.property); var value = values.value.filter(function (val, i) { return i !== index; }); values.update(value); }; Sections.prototype.reorderSections = function reorderSections(selectedSection) { var _this2 = this; var sections = this.getSections().map(function (section) { return { id: section.sectionType.property + section.index, index: section.index, property: section.sectionType.property, title: _this2.props.getSectionTitle(section.section, section.sectionType) }; }); modalHandler.add({ Component: ReorderableCellsModal, props: { value: sections, onSave: this.handleReorder, onClose: function onClose() {} } }); }; Sections.prototype.publishSections = function publishSections(formValue, sections) { modalHandler.add({ Component: SectionsPublishModal, props: { formValue: formValue, sections: sections } }); }; Sections.prototype.getNextOrderId = function getNextOrderId() { var sections = this.getSections(); return sections.length ? sections[sections.length - 1].section.order + 1 : 0; }; /** * Combine all sections into a single array of objects with { sectionType, section, index } keys * ordered by section.order * * It ignores section types that don't have a property or component value. * * @return array The array of sections */ Sections.prototype.getSections = function getSections() { var _props = this.props, SectionTypes = _props.SectionTypes, formValue = _props.formValue; var val = formValue.value; var typesByProperty = {}; // filter out duplicate section types or types without components, etc SectionTypes.forEach(function (sectionType) { if (sectionType.component && sectionType.property && !typesByProperty[sectionType.property] && val && val[sectionType.property] && val[sectionType.property].length) { typesByProperty[sectionType.property] = sectionType; } }); // join sections together and sort return Object.keys(typesByProperty).reduce(function (acc, sectionTypeProperty) { var sectionType = typesByProperty[sectionTypeProperty]; return acc.concat(val[sectionType.property].map(function (section, index) { return { sectionType: sectionType, section: section, index: index }; })); }, []).sort(function (a, b) { return a.section.order - b.section.order; }); }; Sections.prototype.render = function render() { var _props2 = this.props, SectionTypes = _props2.SectionTypes, SectionTray = _props2.SectionTray, showTray = _props2.showTray; return React.createElement( 'div', null, this.getSections().map(this.renderSection), showTray && React.createElement(SectionTray, { SectionTypes: SectionTypes, addSection: this.addSection }) ); }; return Sections; }(Component), _class2.propTypes = { SectionTypes: PropTypes.array, formValue: PropTypes.object, showTray: PropTypes.bool }, _class2.defaultProps = { collapsible: true, reorderable: true, removable: true, duplicable: true, publishable: false, showTray: true, getBlankSection: function getBlankSection(sectionType, formValue) { return {}; }, SectionTray: DefaultSectionTray, getSectionTitle: function getSectionTitle(section, sectionType) { return section.title || section.name || section.label || React.createElement( 'em', null, sectionType.title ); } }, _temp)) || _class; export { Sections as default };