Add items to collection via context menu (#2360)
This commit is contained in:
parent
90531ea2a4
commit
f333585d98
4 changed files with 84 additions and 9 deletions
|
@ -1693,16 +1693,19 @@ Zotero.Utilities.Internal = {
|
|||
* Create a libraryOrCollection DOM tree to place in <menupopup> element.
|
||||
* If has no children, returns a <menuitem> element, otherwise <menu>.
|
||||
*
|
||||
* @param {Library/Collection} libraryOrCollection
|
||||
* @param {Node<menupopup>} elem parent element
|
||||
* @param {function} clickAction function to execute on clicking the menuitem.
|
||||
* @param {Library|Collection} libraryOrCollection
|
||||
* @param {Node<menupopup>} elem Parent element
|
||||
* @param {Zotero.Library|Zotero.Collection} currentTarget Currently selected item (displays as checked)
|
||||
* @param {Function} clickAction function to execute on clicking the menuitem.
|
||||
* Receives the event and libraryOrCollection for given item.
|
||||
* @param {Function} disabledPred If provided, called on each library/collection
|
||||
* to determine whether disabled
|
||||
*
|
||||
* @return {Node<menuitem>/Node<menu>} appended node
|
||||
* @return {Node<menuitem>|Node<menu>} appended node
|
||||
*/
|
||||
createMenuForTarget: function(libraryOrCollection, elem, currentTarget, clickAction) {
|
||||
createMenuForTarget: function(libraryOrCollection, elem, currentTarget, clickAction, disabledPred) {
|
||||
var doc = elem.ownerDocument;
|
||||
function _createMenuitem(label, value, icon, command) {
|
||||
function _createMenuitem(label, value, icon, command, disabled) {
|
||||
let menuitem = doc.createElement('menuitem');
|
||||
menuitem.setAttribute("label", label);
|
||||
menuitem.setAttribute("type", "checkbox");
|
||||
|
@ -1711,6 +1714,7 @@ Zotero.Utilities.Internal = {
|
|||
}
|
||||
menuitem.setAttribute("value", value);
|
||||
menuitem.setAttribute("image", icon);
|
||||
menuitem.setAttribute("disabled", disabled);
|
||||
menuitem.addEventListener('command', command);
|
||||
menuitem.classList.add('menuitem-iconic');
|
||||
return menuitem
|
||||
|
@ -1722,7 +1726,11 @@ Zotero.Utilities.Internal = {
|
|||
menu.setAttribute("value", value);
|
||||
menu.setAttribute("image", icon);
|
||||
// Allow click on menu itself to select a target
|
||||
menu.addEventListener('click', command);
|
||||
menu.addEventListener('click', (event) => {
|
||||
if (event.target == menu) {
|
||||
command(event);
|
||||
}
|
||||
});
|
||||
menu.classList.add('menu-iconic');
|
||||
let menupopup = doc.createElement('menupopup');
|
||||
menu.appendChild(menupopup);
|
||||
|
@ -1739,7 +1747,8 @@ Zotero.Utilities.Internal = {
|
|||
imageSrc,
|
||||
function (event) {
|
||||
clickAction(event, libraryOrCollection);
|
||||
}
|
||||
},
|
||||
disabledPred && disabledPred(libraryOrCollection)
|
||||
);
|
||||
|
||||
var collections;
|
||||
|
@ -1769,7 +1778,7 @@ Zotero.Utilities.Internal = {
|
|||
menupopup.appendChild(doc.createElement('menuseparator'));
|
||||
for (let collection of collections) {
|
||||
let collectionMenu = this.createMenuForTarget(
|
||||
collection, elem, currentTarget, clickAction
|
||||
collection, elem, currentTarget, clickAction, disabledPred
|
||||
);
|
||||
menupopup.appendChild(collectionMenu);
|
||||
}
|
||||
|
|
|
@ -2741,6 +2741,7 @@ var ZoteroPane = new function()
|
|||
'sep3',
|
||||
'toggleRead',
|
||||
'duplicateItem',
|
||||
'addToCollection',
|
||||
'removeItems',
|
||||
'restoreToLibrary',
|
||||
'moveToTrash',
|
||||
|
@ -3104,6 +3105,15 @@ var ZoteroPane = new function()
|
|||
disable.add(m[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// Add to collection
|
||||
if (!collectionTreeRow.isFeed()
|
||||
&& collectionTreeRow.editable
|
||||
&& Zotero.Items.keepParents(items).every(item => item.isTopLevelItem())
|
||||
) {
|
||||
menu.childNodes[m.addToCollection].setAttribute('label', Zotero.getString('pane.items.menu.addToCollection'));
|
||||
show.add(m.addToCollection);
|
||||
}
|
||||
|
||||
// Remove from collection
|
||||
if (collectionTreeRow.isCollection() && items.every(item => item.isTopLevelItem())) {
|
||||
|
@ -3147,6 +3157,55 @@ var ZoteroPane = new function()
|
|||
// add locate menu options
|
||||
yield Zotero_LocateMenu.buildContextMenu(menu, true);
|
||||
});
|
||||
|
||||
|
||||
this.buildAddToCollectionMenu = function (event) {
|
||||
if (event.target.id !== 'zotero-add-to-collection-popup') return;
|
||||
|
||||
let popup = document.getElementById('zotero-add-to-collection-popup');
|
||||
let separator = document.getElementById('zotero-add-to-collection-separator');
|
||||
while (popup.childElementCount > 2) {
|
||||
popup.removeChild(popup.lastElementChild);
|
||||
}
|
||||
|
||||
let items = Zotero.Items.keepParents(this.getSelectedItems());
|
||||
let collections = Zotero.Collections.getByLibrary(this.getSelectedLibraryID());
|
||||
for (let col of collections) {
|
||||
let menuItem = Zotero.Utilities.Internal.createMenuForTarget(
|
||||
col,
|
||||
popup,
|
||||
null,
|
||||
(event, collection) => {
|
||||
if (event.target.tagName == 'menuitem') {
|
||||
this.addSelectedItemsToCollection(collection);
|
||||
event.stopPropagation();
|
||||
}
|
||||
},
|
||||
collection => items.every(item => collection.hasItem(item))
|
||||
);
|
||||
popup.append(menuItem);
|
||||
}
|
||||
|
||||
separator.setAttribute('hidden', !collections.length);
|
||||
};
|
||||
|
||||
|
||||
this.addSelectedItemsToCollection = async function (collection, createNew = false) {
|
||||
// Get items first because newCollection() will deselect
|
||||
let items = Zotero.Items.keepParents(this.getSelectedItems());
|
||||
|
||||
if (createNew) {
|
||||
if (collection) {
|
||||
throw new Error('collection must be null if createNew is true');
|
||||
}
|
||||
let id = await this.newCollection();
|
||||
collection = Zotero.Collections.get(id);
|
||||
}
|
||||
|
||||
await Zotero.DB.executeTransaction(
|
||||
() => collection.addItems(items.map(item => item.id)));
|
||||
};
|
||||
|
||||
|
||||
this.onItemTreeActivate = function(event, items) {
|
||||
var viewOnDoubleClick = Zotero.Prefs.get('viewOnDoubleClick');
|
||||
|
|
|
@ -299,6 +299,12 @@
|
|||
<menuseparator/>
|
||||
<menuitem class="menuitem-iconic zotero-menuitem-toggle-read-item" oncommand="ZoteroPane_Local.toggleSelectedItemsRead();"/>
|
||||
<menuitem class="menuitem-iconic zotero-menuitem-duplicate-item" label="&zotero.items.menu.duplicateItem;" oncommand="ZoteroPane_Local.duplicateSelectedItem().done();"/>
|
||||
<menu class="menuitem-iconic zotero-menuitem-add-to-collection">
|
||||
<menupopup id="zotero-add-to-collection-popup" onpopupshowing="ZoteroPane_Local.buildAddToCollectionMenu(event)">
|
||||
<menuitem id="zotero-add-to-new-collection" label="&zotero.toolbar.newCollection.label;" oncommand="ZoteroPane_Local.addSelectedItemsToCollection(null, true)"/>
|
||||
<menuseparator id="zotero-add-to-collection-separator"/>
|
||||
</menupopup>
|
||||
</menu>
|
||||
<menuitem class="menuitem-iconic zotero-menuitem-remove-items" oncommand="ZoteroPane_Local.deleteSelectedItems();"/>
|
||||
<menuitem class="menuitem-iconic zotero-menuitem-restore-to-library" label="&zotero.items.menu.restoreToLibrary;" oncommand="ZoteroPane_Local.restoreSelectedItems();"/>
|
||||
<menuitem class="menuitem-iconic zotero-menuitem-move-to-trash" oncommand="ZoteroPane_Local.deleteSelectedItems(true, true);"/>
|
||||
|
|
|
@ -328,6 +328,7 @@ pane.items.menu.addNoteFromAnnotations = Add Note from Annotations
|
|||
pane.items.menu.addNoteFromAnnotations.multiple = Add Notes from Annotations
|
||||
pane.items.menu.findAvailablePDF = Find Available PDF
|
||||
pane.items.menu.findAvailablePDF.multiple = Find Available PDFs
|
||||
pane.items.menu.addToCollection = Add to Collection
|
||||
pane.items.menu.remove = Remove Item from Collection…
|
||||
pane.items.menu.remove.multiple = Remove Items from Collection…
|
||||
pane.items.menu.removeFromPublications = Remove Item from My Publications…
|
||||
|
|
Loading…
Reference in a new issue