ucsc-xena-client
Version:
UCSC Xena Client. Functional genomics visualizations.
213 lines (171 loc) • 9.13 kB
JavaScript
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;
;