UNPKG

@bigfishtv/cockpit

Version:

560 lines (464 loc) 20.1 kB
'use strict'; exports.__esModule = true; exports.default = exports.DefaultFolderEditModal = exports.DefaultFolderSidebarToolbar = undefined; 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, _temp2, _class3, _temp3; var _react = require('react'); var _react2 = _interopRequireDefault(_react); var _reactForms = require('@bigfishtv/react-forms'); var _deepEqual = require('deep-equal'); var _deepEqual2 = _interopRequireDefault(_deepEqual); var _classnames = require('classnames'); var _classnames2 = _interopRequireDefault(_classnames); var _get2 = require('lodash/get'); var _get3 = _interopRequireDefault(_get2); var _truncate2 = require('lodash/truncate'); var _truncate3 = _interopRequireDefault(_truncate2); var _xhrUtils = require('../../api/xhrUtils'); var xhrUtils = _interopRequireWildcard(_xhrUtils); var _promptUtils = require('../../utils/promptUtils'); var _stringUtils = require('../../utils/stringUtils'); var _ModalHost = require('../modal/ModalHost'); var _treeUtils = require('../../utils/treeUtils'); var _modalFormValueContext = require('../../decorators/modalFormValueContext'); var _modalFormValueContext2 = _interopRequireDefault(_modalFormValueContext); var _AutoTableIndex = require('./AutoTableIndex'); var _MainContent = require('../container/MainContent'); var _MainContent2 = _interopRequireDefault(_MainContent); var _Bulkhead = require('../page/Bulkhead'); var _Bulkhead2 = _interopRequireDefault(_Bulkhead); var _Panel = require('../container/panel/Panel'); var _Panel2 = _interopRequireDefault(_Panel); var _Tree = require('../tree/Tree'); var _Tree2 = _interopRequireDefault(_Tree); var _Field = require('../form/Field'); var _Field2 = _interopRequireDefault(_Field); var _Modal = require('../modal/Modal'); var _Modal2 = _interopRequireDefault(_Modal); var _TreeSelectModal = require('../modal/TreeSelectModal'); var _TreeSelectModal2 = _interopRequireDefault(_TreeSelectModal); var _Button = require('../button/Button'); var _Button2 = _interopRequireDefault(_Button); var _DropdownItem = require('../button/dropdown/DropdownItem'); var _DropdownItem2 = _interopRequireDefault(_DropdownItem); var _DropdownItemDivider = require('../button/dropdown/DropdownItemDivider'); var _DropdownItemDivider2 = _interopRequireDefault(_DropdownItemDivider); var _DropdownButton = require('../button/dropdown/DropdownButton'); var _DropdownButton2 = _interopRequireDefault(_DropdownButton); var _Icon = require('../Icon'); var _Icon2 = _interopRequireDefault(_Icon); var _TreeModal = require('../modal/TreeModal'); var _TreeModal2 = _interopRequireDefault(_TreeModal); 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 DefaultBulkheadToolbar = function DefaultBulkheadToolbar(_ref) { var modelLabel = _ref.modelLabel, model = _ref.model, addUrl = _ref.addUrl; return _react2.default.createElement(_Button2.default, { text: 'New ' + (0, _stringUtils.titleCase)(modelLabel || model), onClick: function onClick() { return window.location.href = addUrl; }, style: 'primary', size: 'large' }); }; // used in sidebar var DefaultTreeCell = function DefaultTreeCell(props) { var id = props.id, title = props.title, locked = props.locked, isCollapsed = props.isCollapsed, showIndicator = props.showIndicator, onIndicatorClick = props.onIndicatorClick, onIndicatorDoubleClick = props.onIndicatorDoubleClick, isOver = props.isOver, position = props.position, onClick = props.onClick, onDoubleClick = props.onDoubleClick, selected = props.selected, data = props.data; var items = id === null ? data : data.filter(function (_ref2) { var folder_id = _ref2.folder_id; return id === '_unsorted' ? folder_id === null : folder_id === id; }); return _react2.default.createElement( 'div', { className: (0, _classnames2.default)('tree-item', isOver && 'drag-' + position) }, _react2.default.createElement( 'div', { className: (0, _classnames2.default)('tree-cell tree-cell-small', { selected: selected }), onClick: onClick, onDoubleClick: onDoubleClick }, showIndicator ? _react2.default.createElement( 'div', { className: (0, _classnames2.default)('tree-cell-icon', isCollapsed && 'collapsed'), onClick: onIndicatorClick, onDoubleClick: onIndicatorDoubleClick }, _react2.default.createElement(_Icon2.default, { name: 'chevron-' + (isCollapsed ? 'right' : 'down'), size: 18 }) ) : _react2.default.createElement('div', { className: 'tree-cell-icon' }), locked && _react2.default.createElement( 'div', { className: 'tree-cell-icon' }, _react2.default.createElement(_Icon2.default, { name: 'lock', size: 12 }) ), _react2.default.createElement( 'div', { className: 'tree-cell-title' }, (0, _truncate3.default)(title, { length: 45 }), ' (', items.length, ')' ) ) ); }; // used in sidebar var DefaultTray = function DefaultTray(props) { var onFolderAdd = props.onFolderAdd, onFolderDelete = props.onFolderDelete, onEdit = props.onEdit, currentFolderId = props.currentFolderId; return _react2.default.createElement( 'div', { className: 'finder-menu-footer' }, _react2.default.createElement(_Button2.default, { size: 'small', text: 'Add Folder', onClick: onFolderAdd }), _react2.default.createElement(_Button2.default, { size: 'small', text: 'Delete', onClick: onFolderDelete }), _react2.default.createElement(_Button2.default, { size: 'small', text: 'Edit', onClick: onEdit, disabled: currentFolderId === null }) ); }; var DefaultFolderSidebarToolbar = exports.DefaultFolderSidebarToolbar = function DefaultFolderSidebarToolbar(props) { return _react2.default.createElement( _DropdownButton2.default, { style: 'icon', caret: false, pullRight: true, text: _react2.default.createElement(_Icon2.default, { name: 'hamburger' }) }, _react2.default.createElement(_DropdownItem2.default, { text: 'New Folder', icon: 'folder-new', onClick: props.handleFolderAdd }), _react2.default.createElement(_DropdownItem2.default, { text: 'Edit', icon: 'edit', onClick: props.handleFolderEdit, disabled: !props.currentFolderId }), _react2.default.createElement(_DropdownItemDivider2.default, null), _react2.default.createElement(_DropdownItem2.default, { text: 'Remove', icon: 'remove', onClick: props.handleFolderDelete, disabled: !props.currentFolderId }) ); }; var DefaultFolderEditModal = exports.DefaultFolderEditModal = (0, _modalFormValueContext2.default)(_class = (_temp2 = _class2 = function (_Component) { _inherits(DefaultFolderEditModal, _Component); function DefaultFolderEditModal() { var _temp, _this, _ret; _classCallCheck(this, DefaultFolderEditModal); for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } return _ret = (_temp = (_this = _possibleConstructorReturn(this, _Component.call.apply(_Component, [this].concat(args))), _this), _this.handleSave = function () { _this.props.onSave(_this.props.formValue, _this.props.isNew); }, _this.handleClose = function () { var didSave = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; _this.props.onClose(_this.props.formValue, didSave, _this.props.isNew); }, _temp), _possibleConstructorReturn(_this, _ret); } DefaultFolderEditModal.prototype.render = function render() { var foldersUrl = this.props.foldersUrl; var title = this.props.formValue.value.title; return _react2.default.createElement( _Modal2.default, _extends({}, this.props, { title: title || 'New Folder', size: 'small', onClose: this.handleClose, onSave: this.handleSave }), _react2.default.createElement( _reactForms.Fieldset, { formValue: this.props.formValue }, _react2.default.createElement(_Field2.default, { select: 'title', label: 'Title', placeholder: 'Title', autoFocus: true }), _react2.default.createElement( _Field2.default, { select: 'parent', label: 'Parent Folder' }, _react2.default.createElement(_TreeSelectModal2.default, { buttonText: 'Select Folder', modalProps: { url: foldersUrl, title: 'Select Parent Folder', primaryActionText: 'Select Parent Folder', filterData: function filterData(data, user) { return (0, _treeUtils.sortByKey)(data, 'title'); } } }) ) ) ); }; return DefaultFolderEditModal; }(_react.Component), _class2.defaultProps = { isNew: false }, _temp2)) || _class; var AutoFolderTableIndex = (_temp3 = _class3 = function (_Component2) { _inherits(AutoFolderTableIndex, _Component2); function AutoFolderTableIndex(props) { _classCallCheck(this, AutoFolderTableIndex); var _this2 = _possibleConstructorReturn(this, _Component2.call(this, props)); _this2.handleFolderSelection = function (ids, handleFilterChange) { var currentFolderId = ids[0]; _this2.setState({ currentFolderId: currentFolderId }, function () { return handleFilterChange && handleFilterChange('folder_id', currentFolderId == '_unsorted' ? function (val) { return val === null; } : currentFolderId); }); }; _this2.handleFolderCollapse = function (collapsedIds) { _this2.setState({ collapsedIds: collapsedIds }); }; _this2.handleFolderAdd = function () { console.log('opening folder add modal'); _ModalHost.modalHandler.add({ Component: _this2.props.FolderEditModal, props: { isNew: true, defaultValue: _this2.props.newFolderDefaultValue, foldersUrl: _this2.props.foldersUrl, onSave: _this2.handleFolderEditSave.bind(_this2, {}), onClose: _this2.handleFolderEditClose.bind(_this2, {}) } }); }; _this2.handleFolderEdit = function () { var _this2$state = _this2.state, foldersData = _this2$state.foldersData, currentFolderId = _this2$state.currentFolderId; if (!currentFolderId) return; // because folder data is threaded we gotta flatten it to find current selection and set its parent var folder = (0, _treeUtils.flatten)(foldersData).filter(function (item) { return item.id === currentFolderId; })[0]; folder.parent = (0, _treeUtils.getParentByChildId)(currentFolderId, foldersData); _ModalHost.modalHandler.add({ Component: _this2.props.FolderEditModal, props: { defaultValue: folder, foldersUrl: _this2.props.foldersUrl, onSave: _this2.handleFolderEditSave.bind(_this2, folder), onClose: _this2.handleFolderEditClose.bind(_this2, folder) } }); }; _this2.handleFolderEditSave = function (oldRowValue, newRowValue, isNew) { newRowValue = newRowValue.value; if (!(0, _deepEqual2.default)(oldRowValue, newRowValue)) { var postUrl = _this2.props.getFolderSubmitUrl({ id: isNew ? false : newRowValue.id }); var hasNewParent = (0, _get3.default)(newRowValue, 'parent.id', null) != (0, _get3.default)(oldRowValue, 'parent.id'); if (hasNewParent) newRowValue.parent_id = (0, _get3.default)(newRowValue, 'parent.id', null); xhrUtils.post({ url: postUrl, data: newRowValue, callback: function callback(folder) { var foldersData = _this2.state.foldersData; if (isNew) { foldersData = (0, _treeUtils.appendChildToParent)(foldersData, folder.parent_id, folder); foldersData = (0, _treeUtils.sortByKey)(foldersData, 'title'); } else { if (hasNewParent) { foldersData = (0, _treeUtils.pruneTree)(foldersData, 'id', folder.id); foldersData = (0, _treeUtils.appendChildToParent)(foldersData, folder.parent_id, folder); foldersData = (0, _treeUtils.sortByKey)(foldersData, 'title'); } else { foldersData = (0, _treeUtils.replaceChild)(_this2.state.foldersData, folder); } } _this2.setState({ foldersData: foldersData }); _this2.handleFolderSelection([folder.id]); } }); } else { console.log('Nothing edited, not saving.'); } }; _this2.handleFolderEditClose = function (oldRowValue, newFormValue, isNew) { console.log('MODAL CLOSED, W/E'); }; _this2.handleFolderDelete = function () { var _this2$state2 = _this2.state, foldersData = _this2$state2.foldersData, currentFolderId = _this2$state2.currentFolderId; (0, _promptUtils.showDeletePrompt)({ subject: 'email template folder', queryUrl: _this2.props.folderDeleteUrl, style: 'error', selectedIds: [currentFolderId], data: (0, _treeUtils.flatten)(foldersData).filter(function (item) { return item.id === currentFolderId; }), callback: function callback(response) { _this2.setState({ foldersData: (0, _treeUtils.pruneTree)(foldersData, 'id', [currentFolderId]), currentFolderId: null }); } }); }; _this2.handleMove = function (selectedItems, updateCallback) { _ModalHost.modalHandler.add({ Component: _TreeModal2.default, props: { title: 'Select Folder', primaryActionText: 'Confirm', url: _this2.props.foldersUrl, onClose: function onClose() {}, onSave: function onSave(folder) { if (folder) { var selectedIds = selectedItems.map(function (_ref3) { var id = _ref3.id; return id; }); xhrUtils.post({ url: _this2.props.moveUrl + '?folder_id=' + folder.id, data: { id: selectedIds }, successMessage: selectedItems.length + ' item' + (selectedItems.length > 1 ? 's' : '') + ' moved to ' + folder.title, failureMessage: 'There was an error moving items', callback: function callback() { var updateDataFunc = function updateDataFunc(data) { return data.map(function (item) { return ~selectedIds.indexOf(item.id) ? _extends({}, item, { folder_id: folder.id }) : item; }); }; updateCallback(updateDataFunc); } }); } } } }); }; _this2.state = { foldersData: props.folders || [], currentFolderId: null, collapsedFolderIds: [] }; return _this2; } AutoFolderTableIndex.prototype.render = function render() { var _this3 = this; var _props = this.props, SidebarToolbar = _props.SidebarToolbar, BulkheadToolbar = _props.BulkheadToolbar, _TreeCell = _props.TreeCell, sidebarTitle = _props.sidebarTitle; var _state = this.state, collapsedFolderIds = _state.collapsedFolderIds, currentFolderId = _state.currentFolderId, foldersData = _state.foldersData; var sidebarProps = { currentFolderId: currentFolderId, handleFolderAdd: this.handleFolderAdd, handleFolderEdit: this.handleFolderEdit, handleFolderDelete: this.handleFolderDelete }; var _foldersData = [{ id: null, title: '[All]' }, { id: '_unsorted', title: '[Unsorted]' }].concat(foldersData); return _react2.default.createElement( _AutoTableIndex.AutoTableIndexContainer, _extends({}, this.props, { defaultValue: this.props.data, movable: !!this.props.moveUrl, onMove: this.handleMove }), function (props) { var model = props.model, panelProps = props.panelProps, handleFilterChange = props.handleFilterChange, originalData = props.originalData; return _react2.default.createElement( _MainContent2.default, null, _react2.default.createElement(_Bulkhead2.default, { title: (0, _stringUtils.titleCase)(model), Toolbar: function Toolbar() { return _react2.default.createElement(BulkheadToolbar, _extends({}, props, panelProps)); } }), _react2.default.createElement( 'div', { className: 'finder' }, _react2.default.createElement( 'div', { className: 'finder-menu' }, _react2.default.createElement( _Panel2.default, { title: sidebarTitle || 'Folders', PanelToolbar: function PanelToolbar() { return _react2.default.createElement(SidebarToolbar, sidebarProps); } }, _react2.default.createElement(_Tree2.default, { value: _foldersData, TreeCell: function TreeCell(props) { return _react2.default.createElement(_TreeCell, _extends({}, props, { data: originalData })); }, dropTargetType: 'TANK_FOLDER', treeItemTarget: treeItemTarget(_this3), treeItemSource: treeItemSource(_this3), onSelectItem: _this3.handleFolderEdit, selectedIds: [currentFolderId], collapsedIds: collapsedFolderIds, onSelectionChange: function onSelectionChange(ids) { return _this3.handleFolderSelection(ids, handleFilterChange); }, onCollapseChange: _this3.handleFolderCollapse, onCombinationChange: function onCombinationChange() { return console.log('HANDLE COMBINATION CHANGE'); } }) ) ), _react2.default.createElement( 'div', { className: 'finder-content', ref: 'finderContent' }, _react2.default.createElement(_AutoTableIndex.AutoTableIndexBase, props) ) ) ); } ); }; return AutoFolderTableIndex; }(_react.Component), _class3.defaultProps = { Tray: DefaultTray, TreeCell: DefaultTreeCell, BulkheadToolbar: DefaultBulkheadToolbar, SidebarToolbar: DefaultFolderSidebarToolbar, FolderEditModal: DefaultFolderEditModal, foldersUrl: '/tank/folders.json', folderDeleteUrl: '/tank/folders/delete.json', getFolderSubmitUrl: function getFolderSubmitUrl(data) { return '/tank/folders/' + (data.id ? 'edit/' + data.id : 'add') + '.json'; }, componentResolver: function componentResolver() {}, attributeModified: function attributeModified() {}, newFolderDefaultValue: {} }, _temp3); // drag source & target configs for allowing projects to be dropped into sector folders exports.default = AutoFolderTableIndex; var treeItemSource = function treeItemSource(parent) { return { beginDrag: function beginDrag(props, monitor, component) { return { id: props.id }; } }; }; var treeItemTarget = function treeItemTarget(parent) { return { drop: function drop(props, monitor, component) { if (monitor.isOver({ shallow: true })) { if (!props.selected) { var sectorId = monitor.getItem().id; var parentId = props.id; parent.onMoveSector(parentId, sectorId); } else { console.log('no need to move asset into already opened folder'); } } }, hover: function hover(props, monitor, component) { if (monitor.isOver({ shallow: true })) { var ownId = props.id; var draggedId = monitor.getItem().id; if (draggedId === ownId) return; component.setState({ position: 'into' }); } } }; };