Add item tree and info box refresh API (#4850)
For APIs that have lifecycle control, e.g. item pane section, the `update` is passed in the init hook. For APIs without lifecycle, we can't pass a value. Instead, we provide a method to refresh in the API instance.
This commit is contained in:
parent
8e2ec86e56
commit
f5b653e7fd
5 changed files with 75 additions and 15 deletions
|
@ -488,7 +488,7 @@
|
|||
//
|
||||
notify(event, type, ids) {
|
||||
if (event == 'refresh' && type == 'infobox' && this.item?.id) {
|
||||
this.renderCustomRows();
|
||||
this.renderCustomRows(ids);
|
||||
return;
|
||||
}
|
||||
if (event == 'modify' && this.item?.id && ids.includes(this.item.id)) {
|
||||
|
@ -863,11 +863,6 @@
|
|||
|
||||
this.restoreCustomRowElements();
|
||||
|
||||
// Update custom row data
|
||||
for (let rowElem of this._infoTable.querySelectorAll('.meta-row[data-custom-row-id]')) {
|
||||
this.updateCustomRowData(rowElem);
|
||||
}
|
||||
|
||||
// Set focus on the last focused field
|
||||
this._restoreFieldFocus();
|
||||
// Make sure that any opened popup closes
|
||||
|
@ -876,8 +871,18 @@
|
|||
});
|
||||
}
|
||||
|
||||
renderCustomRows() {
|
||||
renderCustomRows(rowIDs) {
|
||||
let { options: targetRows, updateID } = Zotero.ItemPaneManager.customInfoRowData;
|
||||
|
||||
// If rowIDs are provided, always update them
|
||||
if (rowIDs?.length > 0) {
|
||||
for (let rowID of rowIDs) {
|
||||
let rowElem = this._infoTable.querySelector(`[data-custom-row-id="${rowID}"]`);
|
||||
if (!rowElem) continue;
|
||||
this.updateCustomRowData(rowElem);
|
||||
}
|
||||
}
|
||||
|
||||
if (this._lastUpdateCustomRows == updateID) return;
|
||||
this._lastUpdateCustomRows = updateID;
|
||||
|
||||
|
@ -890,8 +895,15 @@
|
|||
|
||||
// Add rows that are in the target rows but not in the current rows
|
||||
for (let row of targetRows) {
|
||||
if (this._infoTable.querySelector(`[data-custom-row-id="${row.rowID}"]`)) continue;
|
||||
let rowElem = document.createElement("div");
|
||||
let rowElem = this._infoTable.querySelector(`[data-custom-row-id="${row.rowID}"]`);
|
||||
if (rowElem) {
|
||||
// If the row is already in the table, and not already updated, update it
|
||||
if (!rowIDs?.includes(row.rowID)) {
|
||||
this.updateCustomRowData(rowElem);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
rowElem = document.createElement("div");
|
||||
rowElem.dataset.customRowId = row.rowID;
|
||||
let position = row.position || "end";
|
||||
rowElem.dataset.position = position;
|
||||
|
@ -933,6 +945,7 @@
|
|||
|
||||
this.updateCustomRowProperty(rowElem);
|
||||
|
||||
// The row is new, always update the data
|
||||
this.updateCustomRowData(rowElem);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -301,6 +301,13 @@
|
|||
},
|
||||
};
|
||||
}
|
||||
|
||||
refresh(rowID) {
|
||||
if (!this._optionsCache[rowID]) {
|
||||
return;
|
||||
}
|
||||
this._refresh([rowID]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -329,6 +336,10 @@
|
|||
return this._infoRowManager.unregister(rowID);
|
||||
}
|
||||
|
||||
refreshInfoRow(rowID) {
|
||||
return this._infoRowManager.refresh(rowID);
|
||||
}
|
||||
|
||||
get customInfoRowData() {
|
||||
return this._infoRowManager.data;
|
||||
}
|
||||
|
|
|
@ -158,6 +158,10 @@ import { COLUMNS } from 'zotero/itemTreeColumns';
|
|||
|
||||
return super._validate(option);
|
||||
}
|
||||
|
||||
refresh() {
|
||||
this._refresh();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -332,6 +336,10 @@ import { COLUMNS } from 'zotero/itemTreeColumns';
|
|||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
refreshColumns() {
|
||||
this._columnManager.refresh();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -121,7 +121,7 @@ class PluginAPIBase {
|
|||
return false;
|
||||
}
|
||||
this._addPluginShutdownObserver();
|
||||
this._update();
|
||||
this._refresh();
|
||||
return mainKey;
|
||||
}
|
||||
|
||||
|
@ -135,7 +135,7 @@ class PluginAPIBase {
|
|||
if (!success) {
|
||||
return false;
|
||||
}
|
||||
this._update();
|
||||
this._refresh();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -322,14 +322,14 @@ class PluginAPIBase {
|
|||
/**
|
||||
* Notify the receiver to update
|
||||
*/
|
||||
async _update() {
|
||||
async _refresh(ids = [], extraData = {}) {
|
||||
this._lastUpdateID = `${new Date().getTime()}-${lazy.Zotero.Utilities.randomString()}`;
|
||||
await lazy.Zotero.DB.executeTransaction(async () => {
|
||||
lazy.Zotero.Notifier.queue(
|
||||
this._config.notifyAction,
|
||||
this._config.notifyType,
|
||||
[],
|
||||
{},
|
||||
ids,
|
||||
extraData,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
@ -347,7 +347,7 @@ class PluginAPIBase {
|
|||
// Remove the registrations one by one
|
||||
paneIDs.forEach(id => this._remove(id));
|
||||
this._log(`Registrations for plugin ${pluginID} are unregistered due to shutdown`);
|
||||
await this._update();
|
||||
await this._refresh();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -359,6 +359,34 @@ describe("Plugin API", function () {
|
|||
|
||||
await waitForUnregister(rowID);
|
||||
});
|
||||
|
||||
it("should refresh custom row value", async function () {
|
||||
let item = new Zotero.Item('book');
|
||||
await item.saveTx();
|
||||
await ZoteroPane.selectItem(item.id);
|
||||
|
||||
let rowID = await waitForRegister(defaultOption);
|
||||
|
||||
let rowElem = infoSection.querySelector(`[data-custom-row-id="${rowID}"]`);
|
||||
let valueElem = rowElem.querySelector(".value");
|
||||
|
||||
let oldValue = valueElem.value;
|
||||
|
||||
// Since this row does not have `onSetData`, changing value does not do anything
|
||||
// We just want to test if the value can be refreshed by calling `updateInfoRow`
|
||||
let newValue = "TEST CUSTOM ROW EDITED";
|
||||
valueElem.value = newValue;
|
||||
|
||||
let notifyPromise = waitForNotifierEvent("refresh", "infobox");
|
||||
|
||||
// Manually refresh the row
|
||||
Zotero.ItemPaneManager.refreshInfoRow(rowID);
|
||||
await notifyPromise;
|
||||
|
||||
assert.equal(oldValue, valueElem.value);
|
||||
|
||||
await waitForUnregister(rowID);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Item tree custom column", function () {
|
||||
|
|
Loading…
Reference in a new issue