UNPKG

zotero-web-library

Version:

Web library from zotero.org

473 lines (456 loc) 14.8 kB
'use strict'; var log = require('libzotero/lib/Log').Logger('zotero-web-library:ZoteroLibrary'); var React = require('react'); var ReactDOM = require('react-dom'); var ControlPanel = require('./ControlPanel.js'); var FilterGuide = require('./FilterGuide.js'); var Collections = require('./Collections.js'); var Tags = require('./Tags.js'); var FeedLink = require('./FeedLink.js'); var LibrarySearchBox = require('./LibrarySearchBox.js'); var Items = require('./Items.js'); var ItemDetails = require('./ItemDetails.js'); var SendToLibraryDialog = require('./SendToLibraryDialog.js'); var CreateCollectionDialog = require('./CreateCollectionDialog.js'); var UpdateCollectionDialog = require('./UpdateCollectionDialog.js'); var DeleteCollectionDialog = require('./DeleteCollectionDialog.js'); var AddToCollectionDialog = require('./AddToCollectionDialog.js'); var CreateItemDialog = require('./CreateItemDialog.js'); var CiteItemDialog = require('./CiteItemDialog.js'); var UploadAttachmentDialog = require('./UploadAttachmentDialog.js'); var ExportItemsDialog = require('./ExportItemsDialog.js'); var LibrarySettingsDialog = require('./LibrarySettingsDialog.js'); var ChooseSortingDialog = require('./ChooseSortingDialog.js'); Zotero.ui.widgets.library = {}; Zotero.ui.widgets.library.init = function (el) { log.debug('Zotero.ui.widgets.library.init', 3); var library = Zotero.ui.getAssociatedLibrary(el); var reactInstance = ReactDOM.render(React.createElement(ZoteroLibrary, { library: library }), document.getElementById('library-widget')); }; var ZoteroLibrary = React.createClass({ displayName: 'ZoteroLibrary', componentWillMount: function componentWillMount() { //preload library log.debug('ZoteroLibrary componentWillMount', 3); var reactInstance = this; Zotero.reactLibraryInstance = reactInstance; var library = this.props.library; library.loadSettings(); library.listen('deleteIdb', function () { library.idbLibrary.deleteDB(); }); library.listen('indexedDBError', function () { Zotero.ui.jsNotificationMessage('There was an error initializing your library. Some data may not load properly.', 'notice'); }); library.listen('cachedDataLoaded', function () {}); window.addEventListener('resize', function () { if (!window.matchMedia('(min-width: 768px)').matches) { if (reactInstance.state.narrow != true) { reactInstance.setState({ narrow: true }); } } else { if (reactInstance.state.narrow != false) { reactInstance.setState({ narrow: false }); } } }); }, componentDidMount: function componentDidMount() { var reactInstance = this; var library = this.props.library; library.listen('displayedItemsChanged', function () { reactInstance.refs.itemsWidget.loadItems(); }, {}); library.listen('tagsChanged libraryTagsUpdated selectedTagsChanged', function () { reactInstance.refs.tagsWidget.setState({ tags: library.tags }); }); //trigger loading of more items on scroll reaching bottom reactInstance.refs.itemsPanel.addEventListener('scroll', function () { var el = reactInstance.refs.itemsPanel; if (el.scrollTop + el.clientHeight >= el.scrollHeight) { reactInstance.refs.itemsWidget.loadMoreItems(); } }); }, getInitialState: function getInitialState() { var narrow; if (!window.matchMedia('(min-width: 768px)').matches) { log.debug('Library set to narrow', 3); narrow = true; } else { narrow = false; } return { narrow: narrow, activePanel: 'items', deviceSize: 'xs' }; }, showFiltersPanel: function showFiltersPanel(evt) { evt.preventDefault(); this.setState({ activePanel: 'filters' }); }, showItemsPanel: function showItemsPanel(evt) { evt.preventDefault(); this.setState({ activePanel: 'items' }); }, reflowPanelContainer: function reflowPanelContainer() {}, render: function render() { log.debug('ZoteroLibrary render', 3); var reactInstance = this; var library = this.props.library; var user = Zotero.config.loggedInUser; var userDisplayName = user ? user.displayName : null; var base = Zotero.config.baseWebsiteUrl; var settingsUrl = base + '/settings'; var inboxUrl = base + '/messages/inbox'; //TODO var downloadUrl = base + '/download'; var documentationUrl = base + '/support'; var forumsUrl = Zotero.config.baseForumsUrl; //TODO var logoutUrl = base + '/user/logout'; var loginUrl = base + '/user/login'; var homeUrl = base; var staticUrl = function staticUrl(path) { return base + '/static' + path; }; var inboxText = ''; var siteActionsMenu; if (user) { inboxText = user.unreadMessages > 0 ? React.createElement( 'strong', null, 'Inbox (', user.unreadMessages, ')' ) : 'Inbox'; siteActionsMenu = [React.createElement( 'button', { key: 'button', type: 'button', href: '#', className: 'btn btn-default navbar-btn dropdown-toggle', 'data-toggle': 'dropdown', role: 'button', 'aria-expanded': 'false' }, userDisplayName, React.createElement('span', { className: 'caret' }), React.createElement( 'span', { className: 'sr-only' }, 'Toggle Dropdown' ) ), React.createElement( 'ul', { key: 'listEntries', className: 'dropdown-menu', role: 'menu' }, React.createElement( 'li', null, React.createElement( 'a', { href: settingsUrl }, 'Settings' ) ), React.createElement( 'li', null, React.createElement( 'a', { href: inboxUrl }, inboxText ) ), React.createElement( 'li', null, React.createElement( 'a', { href: downloadUrl }, 'Download' ) ), React.createElement('li', { className: 'divider' }), React.createElement( 'li', null, React.createElement( 'a', { href: documentationUrl, className: 'documentation' }, 'Documentation' ) ), React.createElement( 'li', null, React.createElement( 'a', { href: forumsUrl, className: 'forums' }, 'Forums' ) ), React.createElement('li', { className: 'divider' }), React.createElement( 'li', null, React.createElement( 'a', { href: logoutUrl }, 'Log Out' ) ) )]; } else { siteActionsMenu = React.createElement( 'div', { className: 'btn-group' }, React.createElement( 'a', { href: loginUrl, className: 'btn btn-default navbar-btn', role: 'button' }, 'Log In' ), React.createElement( 'button', { type: 'button', href: '#', className: 'btn btn-default navbar-btn dropdown-toggle', 'data-toggle': 'dropdown', role: 'button', 'aria-haspopup': 'true', 'aria-expanded': 'false' }, React.createElement('span', { className: 'caret' }), React.createElement( 'span', { className: 'sr-only' }, 'Toggle Dropdown' ) ), React.createElement( 'ul', { className: 'dropdown-menu', role: 'menu' }, React.createElement( 'li', null, React.createElement( 'a', { href: downloadUrl }, 'Download' ) ), React.createElement( 'li', null, React.createElement( 'a', { href: documentationUrl, className: 'documentation' }, 'Documentation' ) ), React.createElement( 'li', null, React.createElement( 'a', { href: forumsUrl, className: 'forums' }, 'Forums' ) ) ) ); } //figure out panel visibility based on state.activePanel var narrow = reactInstance.state.narrow; var leftPanelVisible = !narrow; var rightPanelVisible = !narrow; var itemsPanelVisible = !narrow; var itemPanelVisible = !narrow; var tagsPanelVisible = !narrow; var collectionsPanelVisible = !narrow; if (narrow) { switch (reactInstance.state.activePanel) { case 'items': rightPanelVisible = true; itemsPanelVisible = true; break; case 'item': rightPanelVisible = true; itemPanelVisible = true; break; case 'tags': leftPanelVisible = true; tagsPanelVisible = true; break; case 'collections': leftPanelVisible = true; collectionsPanelVisible = true; break; case 'filters': leftPanelVisible = true; break; } } return React.createElement( 'div', null, React.createElement( 'nav', { id: 'primarynav', className: 'navbar navbar-default', role: 'navigation' }, React.createElement( 'div', { className: 'container-fluid' }, React.createElement( 'div', { className: 'navbar-header' }, React.createElement( 'button', { type: 'button', className: 'navbar-toggle collapsed', 'data-toggle': 'collapse', 'data-target': '#primary-nav-linklist' }, userDisplayName, React.createElement( 'span', { className: 'sr-only' }, 'Toggle navigation' ), React.createElement('span', { className: 'glyphicons fonticon glyphicons-menu-hamburger' }) ), React.createElement( 'a', { className: 'navbar-brand hidden-sm hidden-xs', href: homeUrl }, React.createElement('img', { src: staticUrl('/images/theme/zotero.png'), alt: 'Zotero', height: '20px' }) ), React.createElement( 'a', { className: 'navbar-brand visible-sm-block visible-xs-block', href: homeUrl }, React.createElement('img', { src: staticUrl('/images/theme/zotero_theme/zotero_48.png'), alt: 'Zotero', height: '24px' }) ) ), React.createElement( 'div', { className: 'collapse navbar-collapse', id: 'primary-nav-linklist' }, React.createElement(ControlPanel, { library: library, editable: Zotero.config.librarySettings.allowEdit, ref: 'controlPanel' }), React.createElement( 'ul', { className: 'nav navbar-nav navbar-right' }, siteActionsMenu ), React.createElement( 'div', { className: 'btn-toolbar hidden-xs navbar-right' }, React.createElement(LibrarySearchBox, { library: library }) ) ) ) ), React.createElement( 'div', { id: 'js-message' }, React.createElement('ul', { id: 'js-message-list' }) ), React.createElement( 'div', { id: 'library', className: 'row' }, React.createElement( 'div', { id: 'panel-container' }, React.createElement( 'div', { id: 'left-panel', hidden: !leftPanelVisible, className: 'panelcontainer-panelcontainer col-xs-12 col-sm-4 col-md-3' }, React.createElement(FilterGuide, { ref: 'filterGuide', library: library }), React.createElement( 'div', { role: 'tabpanel' }, React.createElement( 'ul', { className: 'nav nav-tabs', role: 'tablist' }, React.createElement( 'li', { role: 'presentation', className: 'active' }, React.createElement( 'a', { href: '#collections-panel', 'aria-controls': 'collections-panel', role: 'tab', 'data-toggle': 'tab' }, 'Collections' ) ), React.createElement( 'li', { role: 'presentation' }, React.createElement( 'a', { href: '#tags-panel', 'aria-controls': 'tags-panel', role: 'tab', 'data-toggle': 'tab' }, 'Tags' ) ) ), React.createElement( 'div', { className: 'tab-content' }, React.createElement( 'div', { id: 'collections-panel', role: 'tabpanel', className: 'tab-pane active' }, React.createElement(Collections, { ref: 'collectionsWidget', library: library }) ), React.createElement( 'div', { id: 'tags-panel', role: 'tabpanel', className: 'tab-pane' }, React.createElement(Tags, { ref: 'tagsWidget', library: library }), React.createElement(FeedLink, { ref: 'feedLinkWidget', library: library }) ) ) ) ), React.createElement( 'div', { id: 'right-panel', hidden: !rightPanelVisible, className: 'panelcontainer-panelcontainer col-xs-12 col-sm-8 col-md-9' }, React.createElement( 'div', { hidden: !itemsPanelVisible, ref: 'itemsPanel', id: 'items-panel', className: 'panelcontainer-panel col-sm-12 col-md-7' }, React.createElement( 'div', { className: 'visible-xs library-search-box-container' }, React.createElement(LibrarySearchBox, { library: library }) ), React.createElement(Items, { ref: 'itemsWidget', library: library, narrow: narrow }) ), React.createElement( 'div', { hidden: !itemPanelVisible, id: 'item-panel', className: 'panelcontainer-panel col-sm-12 col-md-5' }, React.createElement( 'div', { id: 'item-widget-div', className: 'item-details-div' }, React.createElement(ItemDetails, { ref: 'itemWidget', library: library }) ) ) ), React.createElement( 'nav', { id: 'panelcontainer-nav', className: 'navbar navbar-default navbar-fixed-bottom visible-xs-block', role: 'navigation' }, React.createElement( 'div', { className: 'container-fluid' }, React.createElement( 'ul', { className: 'nav navbar-nav' }, React.createElement( 'li', { onClick: reactInstance.showFiltersPanel, className: 'filters-nav' }, React.createElement( 'a', { href: '#' }, 'Filters' ) ), React.createElement( 'li', { onClick: reactInstance.showItemsPanel, className: 'items-nav' }, React.createElement( 'a', { href: '#' }, 'Items' ) ) ) ) ), React.createElement(SendToLibraryDialog, { ref: 'sendToLibraryDialogWidget', library: library }), React.createElement(CreateCollectionDialog, { ref: 'createCollectionDialogWidget', library: library }), React.createElement(UpdateCollectionDialog, { library: library }), React.createElement(DeleteCollectionDialog, { library: library }), React.createElement(AddToCollectionDialog, { library: library }), React.createElement(CreateItemDialog, { library: library }), React.createElement(CiteItemDialog, { library: library }), React.createElement(UploadAttachmentDialog, { library: library }), React.createElement(ExportItemsDialog, { library: library }), React.createElement(LibrarySettingsDialog, { library: library }), React.createElement(ChooseSortingDialog, { library: library }) ) ) ); } }); module.exports = ZoteroLibrary;