Zotero: handle subcollections in the tree structure
Signed-off-by: Szymon Kłos <szymon.klos@collabora.com> Change-Id: I93f2a4f77969cf27415d882a8114a644dfced1fb
This commit is contained in:
parent
389ed68493
commit
417be951e6
3 changed files with 85 additions and 21 deletions
|
@ -1260,6 +1260,7 @@ input[type='number']:hover::-webkit-outer-spin-button {
|
|||
#zoterocategory.jsdialog {
|
||||
margin-inline-end: 7px;
|
||||
min-width: 150px !important;
|
||||
overflow-x: scroll;
|
||||
}
|
||||
|
||||
#zoterolist.jsdialog {
|
||||
|
|
|
@ -305,16 +305,6 @@ L.Control.Zotero = L.Control.extend({
|
|||
that.map.fire('jsdialogupdate', dialogUpdateEvent);
|
||||
that.map.fire('jsdialogupdate', that.updateCategories());
|
||||
|
||||
this.getCachedOrFetch('https://api.zotero.org/users/' + this.userID + '/items/top?v=3&key=' + this.apiKey + '&include=data,citation,bib,csljson')
|
||||
.then(function (data) {
|
||||
that.fillItems(data);
|
||||
|
||||
var dialogUpdateEvent = that.updateList([_('Title'), _('Creator(s)'), _('Date')], _('Your library is empty'));
|
||||
|
||||
if (window.mode.isMobile()) window.mobileDialogId = dialogUpdateEvent.data.id;
|
||||
that.map.fire('jsdialogupdate', dialogUpdateEvent);
|
||||
});
|
||||
|
||||
this.getCachedOrFetch('https://api.zotero.org/users/' + this.userID + '/groups?v=3&key=' + this.apiKey + '&include=data,citation,bib,csljson')
|
||||
.then(function (data) {
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
|
@ -329,19 +319,23 @@ L.Control.Zotero = L.Control.extend({
|
|||
}
|
||||
});
|
||||
|
||||
this.getCachedOrFetch('https://api.zotero.org/users/' + this.userID + '/collections?v=3&key=' + this.apiKey + '&include=data,citation,bib,csljson')
|
||||
this.getCachedOrFetch('https://api.zotero.org/users/' + this.userID + '/collections/top?v=3&key=' + this.apiKey + '&include=data,citation,bib,csljson')
|
||||
.then(function (data) {
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
that.collections.push(
|
||||
{
|
||||
columns: [ { text: data[i].data.name } ],
|
||||
id: data[i].data.key,
|
||||
row: data[i].links.self.href + '/items/top?v=3&key=' + that.apiKey + '&include=data,citation,bib,csljson'
|
||||
row: data[i].links.self.href + '/items/top?v=3&key=' + that.apiKey + '&include=data,citation,bib,csljson',
|
||||
children: [ { text: '<dummy>' } ],
|
||||
ondemand: true
|
||||
});
|
||||
that.fillCategories();
|
||||
that.map.fire('jsdialogupdate', that.updateCategories());
|
||||
}
|
||||
});
|
||||
|
||||
this.showItemsForUrl('https://api.zotero.org/users/' + this.userID + '/items/top?v=3&key=' + this.apiKey + '&include=data,citation,bib,csljson');
|
||||
},
|
||||
|
||||
showStyleList: function() {
|
||||
|
@ -359,8 +353,78 @@ L.Control.Zotero = L.Control.extend({
|
|||
});
|
||||
},
|
||||
|
||||
_onAction: function(element, action, data, index) {
|
||||
_findEntryWithUrlImpl: function(entry, url) {
|
||||
if (entry.row === url)
|
||||
return entry;
|
||||
|
||||
for (var i in entry.children) {
|
||||
var found = this._findEntryWithUrlImpl(entry.children[i], url);
|
||||
if (found)
|
||||
return found;
|
||||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
|
||||
_findEntryWithUrl: function(data, url) {
|
||||
for (var i in data.entries) {
|
||||
var found = this._findEntryWithUrlImpl(data.entries[i], url);
|
||||
if (found)
|
||||
return found;
|
||||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
|
||||
_fetchCollectionAndPushTo: function(collectionId, targetCollection) {
|
||||
var that = this;
|
||||
this.getCachedOrFetch('https://api.zotero.org/users/' + this.userID + '/collections/' + collectionId + '/collections/?v=3&key=' + this.apiKey + '&include=data,citation,bib,csljson')
|
||||
.then(function (data) {
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
targetCollection.push(
|
||||
{
|
||||
columns: [ { text: data[i].data.name } ],
|
||||
id: data[i].data.key,
|
||||
row: data[i].links.self.href + '/items/top?v=3&key=' + that.apiKey + '&include=data,citation,bib,csljson',
|
||||
children: [ { text: '<dummy>' } ],
|
||||
ondemand: true
|
||||
});
|
||||
}
|
||||
|
||||
that.fillCategories();
|
||||
that.map.fire('jsdialogupdate', that.updateCategories());
|
||||
});
|
||||
},
|
||||
|
||||
_expandCollection: function(treeViewData, row) {
|
||||
var entry = this._findEntryWithUrl(treeViewData, row);
|
||||
var searchArray = { entries: this.collections };
|
||||
var targetEntry = this._findEntryWithUrl(searchArray, row);
|
||||
|
||||
if (entry && targetEntry) {
|
||||
if (targetEntry.children.length === 1
|
||||
&& targetEntry.children[0].text === '<dummy>') {
|
||||
targetEntry.children = [];
|
||||
targetEntry.ondemand = false;
|
||||
|
||||
this._fetchCollectionAndPushTo(entry.id, targetEntry.children);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
showItemsForUrl: function(url) {
|
||||
var that = this;
|
||||
that.items = [];
|
||||
this.getCachedOrFetch(url)
|
||||
.then(function (data) {
|
||||
that.fillItems(data);
|
||||
var dialogUpdateEvent = that.updateList([_('Title'), _('Creator(s)'), _('Date')], _('Your library is empty'));
|
||||
that.map.fire('jsdialogupdate', dialogUpdateEvent);
|
||||
if (window.mode.isMobile()) window.mobileDialogId = dialogUpdateEvent.data.id;
|
||||
});
|
||||
},
|
||||
|
||||
_onAction: function(element, action, data, index) {
|
||||
if (element === 'dialog' && action === 'close') return;
|
||||
if (element === 'treeview') {
|
||||
if (action == 'keydown')
|
||||
|
@ -369,13 +433,11 @@ L.Control.Zotero = L.Control.extend({
|
|||
var url = index;
|
||||
if (!url)
|
||||
return;
|
||||
that.items = [];
|
||||
this.getCachedOrFetch(url)
|
||||
.then(function (data) {
|
||||
that.fillItems(data);
|
||||
var dialogUpdateEvent = that.updateList([_('Title'), _('Creator(s)'), _('Date')], _('Your library is empty'));
|
||||
that.map.fire('jsdialogupdate', dialogUpdateEvent);
|
||||
});
|
||||
|
||||
if (action === 'expand')
|
||||
this._expandCollection(data, index);
|
||||
|
||||
this.showItemsForUrl(url);
|
||||
return;
|
||||
} else {
|
||||
this.selected = data.entries[parseInt(index) - 1];
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
* type: 'treelistbox',
|
||||
* entries: [
|
||||
* { row: 0, text: 'first entry', children: [ { row: 2, text: 'first subentry' } ] },
|
||||
* { row: 1, text: 'second entry', selected: true, state: false }
|
||||
* { row: 1, text: 'second entry', selected: true, state: false, ondemand: true }
|
||||
* ]
|
||||
* }
|
||||
*
|
||||
|
@ -26,6 +26,7 @@
|
|||
*
|
||||
* 'row' property is used in the callback to differentiate entries
|
||||
* 'state' property defines if entry has the checkbox (false/true), when is missing - no checkbox
|
||||
* 'ondemand' property can be set to provide nodes lazy loading
|
||||
*/
|
||||
|
||||
/* global $ JSDialog */
|
||||
|
|
Loading…
Reference in a new issue