UNPKG

ucsc-xena-client

Version:

UCSC Xena Client. Functional genomics visualizations.

213 lines (171 loc) 9.13 kB
'use strict'; 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 _menu = require('react-toolbox/lib/menu'); var _button = require('react-toolbox/lib/button'); var _link = require('react-toolbox/lib/link'); var _link2 = _interopRequireDefault(_link); var _tooltip = require('react-toolbox/lib/tooltip'); var _tooltip2 = _interopRequireDefault(_tooltip); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 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; } var React = require('react'); //var config = require('../config'); var _ = require('../underscore_ext'); var Rx = require('../rx'); var _require = require('../bookmark'), createBookmark = _require.createBookmark; var classNames = require('classnames'); var compStyles = require('./BookmarkMenu.module.css'); // XXX This is a horrible work-around for react-toolbox menu limitations. // We want the Bookmark MenuItem to not close the menu. Menu closes when // a MenuItem is clicked by intercepting the onClick handler. However, it // only intercepts onClick handlers of MenuItem children. By simply wrapping // MenuItem, we avoid this. var NoCloseMenuItem = function (_React$Component) { _inherits(NoCloseMenuItem, _React$Component); function NoCloseMenuItem() { _classCallCheck(this, NoCloseMenuItem); return _possibleConstructorReturn(this, (NoCloseMenuItem.__proto__ || Object.getPrototypeOf(NoCloseMenuItem)).apply(this, arguments)); } _createClass(NoCloseMenuItem, [{ key: 'render', value: function render() { var _props = this.props, tooltip = _props.tooltip, otherProps = _objectWithoutProperties(_props, ['tooltip']); return React.createElement(_menu.MenuItem, otherProps); } }]); return NoCloseMenuItem; }(React.Component); var TooltipNoCloseMenuItem = (0, _tooltip2.default)(NoCloseMenuItem); var privateWarning = 'Unable to create bookmark link due to private data in view. Use export instead'; var BookmarkMenu = function (_React$Component2) { _inherits(BookmarkMenu, _React$Component2); function BookmarkMenu() { var _ref; var _temp, _this2, _ret; _classCallCheck(this, BookmarkMenu); for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } return _ret = (_temp = (_this2 = _possibleConstructorReturn(this, (_ref = BookmarkMenu.__proto__ || Object.getPrototypeOf(BookmarkMenu)).call.apply(_ref, [this].concat(args))), _this2), _this2.state = { loading: false, open: false }, _this2.onBookmark = function () { var getState = _this2.props.getState; _this2.setState({ loading: true }); Rx.Observable.ajax({ method: 'POST', url: '/api/bookmarks/bookmark', responseType: 'text', headers: { 'X-CSRFToken': document.cookie.replace(/.*csrftoken=([0-9a-z]+)/, '$1'), 'Content-Type': 'application/x-www-form-urlencoded' }, body: 'content=' + encodeURIComponent(createBookmark(getState())) }).subscribe(_this2.onSetBookmark, function () { return _this2.setState({ loading: false }); }); }, _this2.onSetBookmark = function (resp) { var _JSON$parse = JSON.parse(resp.response), id = _JSON$parse.id; _this2.setState({ bookmark: location.href + '?bookmark=' + id, loading: false }); }, _this2.onResetBookmark = function () { _this2.setState({ bookmark: null }); }, _this2.onCopyBookmarkToClipboard = function () { _this2.bookmarkEl.select(); document.execCommand('copy'); }, _this2.onExport = function () { var getState = _this2.props.getState; var url = URL.createObjectURL(new Blob([JSON.stringify(getState())], { type: 'application/json' })); var a = document.createElement('a'); var filename = 'xenaState.json'; _.extend(a, { id: filename, download: filename, href: url }); document.body.appendChild(a); a.click(); document.body.removeChild(a); }, _this2.onImport = function () { _this2.refs.import.click(); }, _this2.onImportSelected = function (ev) { var file = ev.target.files[0], reader = new FileReader(), onImport = _this2.props.onImport; reader.onload = function () { return onImport(reader.result); }; reader.readAsText(file); ev.target.value = null; }, _this2.resetBookmark = function () { _this2.setState({ bookmark: null }); }, _this2.onClick = function () { _this2.setState({ open: !_this2.state.open }); }, _this2.handleMenuHide = function () { _this2.setState({ open: false }); if (_this2.props.onHide) { _this2.props.onHide(); } }, _temp), _possibleConstructorReturn(_this2, _ret); } _createClass(BookmarkMenu, [{ key: 'render', value: function render() { var _this3 = this; var _state = this.state, bookmark = _state.bookmark, loading = _state.loading, open = _state.open, isPublic = this.props.isPublic, BookmarkElement = isPublic ? NoCloseMenuItem : TooltipNoCloseMenuItem; // min-width specified on first MenuItem of bookmark menu is a hack to // force menu items to extend full width for both no bookmark and // bookmark states. RTB positions and clips the menu content according // to the initial menu item content which causes problems when we move // from the "Your Bookmark is Loading" to "Copy to Clipboard" states. // Do not remove this inline style! // // In similar fashion, it's important to render a placeholder for the // eventual 'Copy' item. Otherwise it will be clipped, because Menu // does not re-compute clipping when children change. return React.createElement( 'div', { style: { display: 'inline', position: 'relative' } }, React.createElement( _button.Button, { onClick: this.onClick }, 'Bookmark' ), React.createElement( _menu.Menu, { position: 'auto', active: open, onHide: this.handleMenuHide, className: compStyles.iconBookmark, iconRipple: false, onShow: this.resetBookmark }, React.createElement(BookmarkElement, { tooltip: privateWarning, style: { minWidth: 218, pointerEvents: 'all' /* override MenuItem 'disabled' class */ }, disabled: !isPublic, onClick: this.onBookmark, caption: 'Bookmark' }), React.createElement(_menu.MenuItem, { onClick: this.onExport, title: null, caption: 'Export' }), React.createElement(_menu.MenuItem, { onClick: this.onImport, title: null, caption: 'Import' }), React.createElement(_link2.default, { className: compStyles.help, target: '_blank', href: 'http://xena.ucsc.edu/bookmarks/', label: 'Help' }), React.createElement(_menu.MenuDivider, null), React.createElement(_menu.MenuItem, { onClick: bookmark ? this.onCopyBookmarkToClipboard : undefined, caption: bookmark ? 'Copy Bookmark' : 'Your Bookmark is Loading', disabled: !bookmark, className: bookmark || loading ? '' : compStyles.placeholder }), React.createElement( 'p', { className: classNames(compStyles.warning, bookmark ? '' : compStyles.placeholder) }, 'Note: bookmarks are only guaranteed for 3 months after creation' ), React.createElement('input', { className: compStyles.bookmarkInput, ref: function ref(input) { return _this3.bookmarkEl = input; }, value: bookmark || '' }), React.createElement('input', { className: compStyles.importInput, ref: 'import', id: 'import', onChange: this.onImportSelected, type: 'file' }) ) ); } }]); return BookmarkMenu; }(React.Component); module.exports = BookmarkMenu;