Improve notes list UI:
- Show both sections even on search - Add new note creation popups with an option to create from annotations - Hide child notes section if no parent item
This commit is contained in:
parent
d47ec92116
commit
17abf87bcf
4 changed files with 103 additions and 33 deletions
|
@ -51,11 +51,11 @@ const NoteRow = ({ title, body, date, onClick, parentItemType, parentTitle }) =>
|
|||
);
|
||||
};
|
||||
|
||||
const NotesList = forwardRef(({ onClick, onNewChild, onNewStandalone }, ref) => {
|
||||
const NotesList = forwardRef(({ onClick, onAddChildButtonDown, onAddStandaloneButtonDown }, ref) => {
|
||||
const [notes, setNotes] = useState([]);
|
||||
const [expanded, setExpanded] = useState(false);
|
||||
const [searching, setSearching] = useState(false);
|
||||
useImperativeHandle(ref, () => ({ setNotes, setExpanded, setSearching }));
|
||||
const [hasParent, setHasParent] = useState(true);
|
||||
useImperativeHandle(ref, () => ({ setNotes, setExpanded, setHasParent }));
|
||||
|
||||
function handleClickMore() {
|
||||
setExpanded(true);
|
||||
|
@ -65,27 +65,27 @@ const NotesList = forwardRef(({ onClick, onNewChild, onNewStandalone }, ref) =>
|
|||
let allNotes = notes.filter(x => !x.isCurrentChild);
|
||||
return (
|
||||
<div className="notes-list">
|
||||
{(!!childNotes.length || !searching) && <section>
|
||||
{hasParent && <section>
|
||||
<div className="header-row">
|
||||
<h2>{Zotero.getString('pane.context.itemNotes')}</h2>
|
||||
{!searching && <button onClick={onNewChild}>+</button>}
|
||||
<button onMouseDown={onAddChildButtonDown}>+</button>
|
||||
</div>
|
||||
{!childNotes.length && !searching && <div className="empty-row">{Zotero.getString('pane.context.noNotes')}</div>}
|
||||
{!childNotes.length && <div className="empty-row">{Zotero.getString('pane.context.noNotes')}</div>}
|
||||
{childNotes.map(note => <NoteRow key={note.id} {...note} onClick={() => onClick(note.id)}/>)}
|
||||
</section>}
|
||||
{(!!allNotes.length || !searching) && <section>
|
||||
<section>
|
||||
<div className="header-row">
|
||||
<h2>{Zotero.getString('pane.context.allNotes')}</h2>
|
||||
{!searching && <button onClick={onNewStandalone}>+</button>}
|
||||
<button onMouseDown={onAddStandaloneButtonDown}>+</button>
|
||||
</div>
|
||||
{!allNotes.length && !searching && <div className="empty-row">{Zotero.getString('pane.context.noNotes')}</div>}
|
||||
{!allNotes.length && <div className="empty-row">{Zotero.getString('pane.context.noNotes')}</div>}
|
||||
{(expanded ? allNotes : allNotes.slice(0, MAX_ALL_NOTES)).map(note => <NoteRow key={note.id} {...note} onClick={() => onClick(note.id)}/>)}
|
||||
{!expanded && allNotes.length > MAX_ALL_NOTES
|
||||
&& <div className="more-row" onClick={handleClickMore}>{
|
||||
Zotero.getString('general.numMore', Zotero.Utilities.numberFormat([allNotes.length - MAX_ALL_NOTES], 0))
|
||||
}</div>
|
||||
}
|
||||
</section>}
|
||||
</section>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
|
|
@ -369,14 +369,11 @@ var ZoteroContextPane = new function () {
|
|||
|
||||
_panesDeck.append(_itemPaneDeck, _notesPaneDeck);
|
||||
}
|
||||
|
||||
function _getCurrentParentItem() {
|
||||
|
||||
function _getCurrentAttachment() {
|
||||
var reader = Zotero.Reader.getByTabID(Zotero_Tabs.selectedID);
|
||||
if (reader) {
|
||||
var attachment = Zotero.Items.get(reader.itemID);
|
||||
if (attachment) {
|
||||
return attachment.parentItem;
|
||||
}
|
||||
return Zotero.Items.get(reader.itemID);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -408,19 +405,42 @@ var ZoteroContextPane = new function () {
|
|||
var head = document.createElement('hbox');
|
||||
head.style.display = 'flex';
|
||||
|
||||
async function _createNoteFromAnnotations(child) {
|
||||
var attachment = _getCurrentAttachment();
|
||||
if (!attachment) {
|
||||
return;
|
||||
}
|
||||
var note = await Zotero.EditorInstance.createNoteFromAnnotations(
|
||||
attachment.getAnnotations(), child && attachment.parentID
|
||||
);
|
||||
|
||||
function _createNote(parentID) {
|
||||
_updateAddToNote();
|
||||
|
||||
input.value = '';
|
||||
_updateNotesList();
|
||||
|
||||
_setPinnedNote(note.id);
|
||||
}
|
||||
|
||||
function _createNote(child) {
|
||||
contextNode.setAttribute('selectedIndex', 1);
|
||||
var item = new Zotero.Item('note');
|
||||
item.libraryID = libraryID;
|
||||
if (parentID) {
|
||||
item.parentID = parentID;
|
||||
if (child) {
|
||||
var attachment = _getCurrentAttachment();
|
||||
if (!attachment) {
|
||||
return;
|
||||
}
|
||||
item.parentID = attachment.parentID;
|
||||
}
|
||||
editor.mode = 'edit';
|
||||
editor.item = item;
|
||||
editor.parentItem = null;
|
||||
editor.focus();
|
||||
_updateAddToNote();
|
||||
|
||||
input.value = '';
|
||||
_updateNotesList();
|
||||
}
|
||||
|
||||
var vbox = document.createElement('vbox');
|
||||
|
@ -498,11 +518,12 @@ var ZoteroContextPane = new function () {
|
|||
context.cachedNotes = notes;
|
||||
}
|
||||
|
||||
var readerParentItem = _getCurrentParentItem();
|
||||
notesListRef.current.setSearching(query.length);
|
||||
var attachment = _getCurrentAttachment();
|
||||
var parentID = attachment && attachment.parentID;
|
||||
notesListRef.current.setHasParent(!!parentID);
|
||||
notesListRef.current.setNotes(notes.map(note => ({
|
||||
...note,
|
||||
isCurrentChild: readerParentItem && note.parentID == readerParentItem.id
|
||||
isCurrentChild: parentID && note.parentID == parentID
|
||||
})));
|
||||
}
|
||||
|
||||
|
@ -515,21 +536,50 @@ var ZoteroContextPane = new function () {
|
|||
update: Zotero.Utilities.throttle(_updateNotesList, 1000, { leading: false }),
|
||||
updateFromCache: () => _updateNotesList(true)
|
||||
};
|
||||
|
||||
function _handleAddChildNotePopupClick(event) {
|
||||
switch (event.originalTarget.id) {
|
||||
case 'context-pane-add-child-note':
|
||||
_createNote(true);
|
||||
break;
|
||||
|
||||
case 'context-pane-add-child-note-from-annotations':
|
||||
_createNoteFromAnnotations(true);
|
||||
break;
|
||||
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
function _handleAddStandaloneNotePopupClick(event) {
|
||||
switch (event.originalTarget.id) {
|
||||
case 'context-pane-add-standalone-note':
|
||||
_createNote();
|
||||
break;
|
||||
|
||||
case 'context-pane-add-standalone-note-from-annotations':
|
||||
_createNoteFromAnnotations();
|
||||
break;
|
||||
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
ReactDOM.render(
|
||||
<NotesList
|
||||
ref={notesListRef}
|
||||
onClick={(id) => {
|
||||
_setPinnedNote(libraryID, id);
|
||||
_setPinnedNote(id);
|
||||
}}
|
||||
onNewChild={() => {
|
||||
var parentItem = _getCurrentParentItem();
|
||||
if (parentItem) {
|
||||
_createNote(parentItem.id);
|
||||
}
|
||||
onAddChildButtonDown={(event) => {
|
||||
var popup = document.getElementById('context-pane-add-child-note-button-popup');
|
||||
popup.onclick = _handleAddChildNotePopupClick;
|
||||
popup.openPopup(event.target, 'after_end');
|
||||
}}
|
||||
onNewStandalone={() => {
|
||||
_createNote();
|
||||
onAddStandaloneButtonDown={(event) => {
|
||||
var popup = document.getElementById('context-pane-add-standalone-note-button-popup');
|
||||
popup.onclick = _handleAddStandaloneNotePopupClick;
|
||||
popup.openPopup(event.target, 'after_end');
|
||||
}}
|
||||
/>,
|
||||
listInner,
|
||||
|
@ -570,10 +620,13 @@ var ZoteroContextPane = new function () {
|
|||
return true;
|
||||
}
|
||||
|
||||
function _setPinnedNote(libraryID, itemID) {
|
||||
var editable = _isLibraryEditable(libraryID);
|
||||
var context = _getNotesContext(libraryID);
|
||||
function _setPinnedNote(itemID) {
|
||||
var item = Zotero.Items.get(itemID);
|
||||
if (!item) {
|
||||
return;
|
||||
}
|
||||
var editable = _isLibraryEditable(item.libraryID);
|
||||
var context = _getNotesContext(item.libraryID);
|
||||
if (context) {
|
||||
var { editor, node } = context;
|
||||
node.setAttribute('selectedIndex', 1);
|
||||
|
|
|
@ -632,6 +632,18 @@
|
|||
<hbox id="zotero-context-pane-inner" flex="1" zotero-persist="height"/>
|
||||
</vbox>
|
||||
</box>
|
||||
|
||||
<popupset>
|
||||
<menupopup id="context-pane-add-child-note-button-popup">
|
||||
<menuitem id="context-pane-add-child-note" label="&zotero.context.addChildNote;"/>
|
||||
<menuitem id="context-pane-add-child-note-from-annotations" label="&zotero.context.addChildNoteFromAnnotations;"/>
|
||||
</menupopup>
|
||||
|
||||
<menupopup id="context-pane-add-standalone-note-button-popup">
|
||||
<menuitem id="context-pane-add-standalone-note" label="&zotero.context.addStandaloneNote;"/>
|
||||
<menuitem id="context-pane-add-standalone-note-from-annotations" label="&zotero.context.addStandaloneNoteFromAnnotations;"/>
|
||||
</menupopup>
|
||||
</popupset>
|
||||
</hbox>
|
||||
|
||||
<!-- Barrier to prevent tabbing into Zotero pane when busy -->
|
||||
|
|
|
@ -329,3 +329,8 @@
|
|||
<!ENTITY zotero.attachLink.title "Attach Link to URI">
|
||||
<!ENTITY zotero.attachLink.label.link "Link:">
|
||||
<!ENTITY zotero.attachLink.label.title "Title:">
|
||||
|
||||
<!ENTITY zotero.context.addChildNote "Add Item Note">
|
||||
<!ENTITY zotero.context.addChildNoteFromAnnotations "Add Item Note from Annotations">
|
||||
<!ENTITY zotero.context.addStandaloneNote "Add Standalone Note">
|
||||
<!ENTITY zotero.context.addStandaloneNoteFromAnnotations "Add Standalone Note from Annotations">
|
||||
|
|
Loading…
Reference in a new issue