enable + button on all creator rows
- plus button is enabled on all creator rows, not just the last one - enabled plus button will add an empty unsaved creator row below current creator row. After that, plus button is disabled as long as the next row is unsaved. - the grippy of a newly added unsaved row is disabled - adding an unsaved creator row will remove another unsaved creator row if one exists. That way, only one unsaved row can exist at a time - once the unsaved creator row is added, it is tentatively perceived as the "last" creator row based on its id. That is to avoid shifting all other creators' indicies and saving the item too many times. When the field is blurred, that new creator is moved into its "unsavedIndex" before saving the item
This commit is contained in:
parent
fe01113935
commit
2071a7c4cf
1 changed files with 54 additions and 21 deletions
|
@ -746,10 +746,10 @@
|
|||
field = this._infoTable.querySelector('[fieldName="itemType"]');
|
||||
}
|
||||
if (field) {
|
||||
this._beforeRow = field.closest(".meta-row").nextSibling;
|
||||
this._firstRowBeforeCreators = field.closest(".meta-row").nextSibling;
|
||||
}
|
||||
else {
|
||||
this._beforeRow = this._infoTable.firstChild;
|
||||
this._firstRowBeforeCreators = this._infoTable.firstChild;
|
||||
}
|
||||
|
||||
this._creatorCount = 0;
|
||||
|
@ -763,7 +763,7 @@
|
|||
}
|
||||
for (let i = 0; i < max; i++) {
|
||||
let data = this.item.getCreator(i);
|
||||
this.addCreatorRow(data, data.creatorTypeID);
|
||||
this.addCreatorRow(data, data.creatorTypeID, false);
|
||||
}
|
||||
if (this._draggedCreator) {
|
||||
this._draggedCreator = false;
|
||||
|
@ -799,7 +799,7 @@
|
|||
}
|
||||
else if (this.editable && Zotero.CreatorTypes.itemTypeHasCreators(this.item.itemTypeID)) {
|
||||
// Add default row
|
||||
this.addCreatorRow(false, false, true, true);
|
||||
this.addCreatorRow(false, false, false);
|
||||
}
|
||||
|
||||
|
||||
|
@ -910,8 +910,14 @@
|
|||
|
||||
row.appendChild(label);
|
||||
row.appendChild(value);
|
||||
|
||||
// Special treatment for creator rows if beforeElement is not specified
|
||||
if (!beforeElement && row.querySelector(".creator-type-value, #more-creators-label")) {
|
||||
beforeElement = this._firstRowBeforeCreators;
|
||||
}
|
||||
|
||||
if (beforeElement) {
|
||||
this._infoTable.insertBefore(row, this._beforeRow);
|
||||
this._infoTable.insertBefore(row, beforeElement);
|
||||
}
|
||||
else {
|
||||
this._infoTable.appendChild(row);
|
||||
|
@ -920,7 +926,7 @@
|
|||
return row;
|
||||
}
|
||||
|
||||
addCreatorRow(creatorData, creatorTypeIDOrName, unsaved, defaultRow) {
|
||||
addCreatorRow(creatorData, creatorTypeIDOrName, unsaved, before) {
|
||||
// getCreatorFields(), switchCreatorMode() and handleCreatorAutoCompleteSelect()
|
||||
// may need need to be adjusted if this DOM structure changes
|
||||
|
||||
|
@ -974,8 +980,8 @@
|
|||
labelWrapper.setAttribute('aria-describedby', 'creator-type-label-inner');
|
||||
labelWrapper.setAttribute('id', `creator-${rowIndex}-label`);
|
||||
|
||||
// If not editable or only 1 creator row, hide grippy
|
||||
if (!this.editable || this.item.numCreators() < 2) {
|
||||
// If not editable or only 1 creator row or a row is unsaved, hide grippy
|
||||
if (!this.editable || this.item.numCreators() < 2 || unsaved) {
|
||||
grippy.classList.add("single-creator-grippy");
|
||||
grippy.setAttribute('disabled', true);
|
||||
}
|
||||
|
@ -1030,7 +1036,11 @@
|
|||
addButton.setAttribute("class", "zotero-clicky zotero-clicky-plus show-on-hover no-display");
|
||||
addButton.setAttribute('id', `creator-${rowIndex}-add`);
|
||||
addButton.setAttribute('tooltiptext', Zotero.getString('general.create'));
|
||||
addButton.addEventListener("command", () => this.addCreatorRow(null, typeID, true));
|
||||
addButton.addEventListener("command", (e) => {
|
||||
// + button adds a creator row after the row that was clicked
|
||||
let nextRow = e.target.closest(".meta-row").nextElementSibling;
|
||||
this.addCreatorRow(null, typeID, true, nextRow);
|
||||
});
|
||||
rowData.appendChild(addButton);
|
||||
|
||||
// Options button that opens creator transform menu
|
||||
|
@ -1059,10 +1069,14 @@
|
|||
|
||||
this._creatorCount++;
|
||||
|
||||
|
||||
let row = this.addDynamicRow(rowLabel, rowData, true);
|
||||
// Delete existing unsaved creator row if any
|
||||
let unsavedCreatorData = this._infoTable.querySelector(".creator-type-value[unsaved=true]");
|
||||
if (unsavedCreatorData) {
|
||||
unsavedCreatorData.closest(".meta-row").remove();
|
||||
}
|
||||
|
||||
let row = this.addDynamicRow(rowLabel, rowData, before);
|
||||
|
||||
this._updateCreatorButtonsStatus();
|
||||
this._ensureButtonsFocusable();
|
||||
|
||||
/**
|
||||
|
@ -1132,10 +1146,14 @@
|
|||
|
||||
row.addEventListener("keydown", e => this.handleCreatorRowKeyDown(e));
|
||||
lastNameElem.addEventListener("paste", e => this.handleCreatorPaste(e));
|
||||
// Focus new rows
|
||||
if (unsaved && !defaultRow) {
|
||||
// Focus unsaved empty creator row
|
||||
if (unsaved) {
|
||||
rowData.setAttribute("unsaved", true);
|
||||
lastNameElem.focus();
|
||||
}
|
||||
// Refresh creator buttons status, e.g. to disable + button of a row that just added
|
||||
// a new creator
|
||||
this._updateCreatorButtonsStatus();
|
||||
}
|
||||
|
||||
addMoreCreatorsRow(num) {
|
||||
|
@ -1158,7 +1176,7 @@
|
|||
});
|
||||
rowData.textContent = Zotero.getString('general.numMore', num);
|
||||
|
||||
this.addDynamicRow(rowLabel, rowData, true);
|
||||
this.addDynamicRow(rowLabel, rowData);
|
||||
}
|
||||
|
||||
addDateRow(field, value) {
|
||||
|
@ -1198,7 +1216,6 @@
|
|||
var lastName = creatorNameBox.firstChild;
|
||||
var firstName = creatorNameBox.lastChild;
|
||||
|
||||
let tab;
|
||||
// Switch to single-field mode
|
||||
if (fieldMode == 1) {
|
||||
creatorNameBox.setAttribute('switch-mode-label', Zotero.getString('pane.item.switchFieldMode.two'));
|
||||
|
@ -1718,7 +1735,6 @@
|
|||
// Do nothing from the last empty row
|
||||
if (creatorFields.lastName == "" && creatorFields.firstName == "") return;
|
||||
this.addCreatorRow(false, creatorFields.creatorTypeID, true);
|
||||
this._selectField = `itembox-field-value-creator-${this._creatorCount - 1}-lastName`;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1943,7 +1959,7 @@
|
|||
row = creatorValue.closest(".meta-row");
|
||||
let { lastName, firstName } = this.getCreatorFields(row);
|
||||
let isEmpty = lastName == "" && firstName == "";
|
||||
let isNextRowCreator = row.nextSibling.querySelector(".creator-type-value");
|
||||
let isNextRowUnsavedCreator = row.nextSibling?.querySelector(".creator-type-value[unsaved=true]");
|
||||
let isDefaultEmptyRow = isEmpty && creatorValues.length == 1;
|
||||
|
||||
if (!this.editable) {
|
||||
|
@ -1953,7 +1969,7 @@
|
|||
return;
|
||||
}
|
||||
|
||||
row.querySelector(".zotero-clicky-plus").disabled = isEmpty || isNextRowCreator;
|
||||
row.querySelector(".zotero-clicky-plus").disabled = isEmpty || isNextRowUnsavedCreator;
|
||||
row.querySelector(".zotero-clicky-minus").disabled = isDefaultEmptyRow;
|
||||
}
|
||||
}
|
||||
|
@ -1962,11 +1978,22 @@
|
|||
var typeID = row.querySelector('[typeid]').getAttribute('typeid');
|
||||
var [label1, label2] = row.querySelectorAll('editable-text');
|
||||
var fieldMode = row.querySelector('[fieldMode]')?.getAttribute('fieldMode');
|
||||
var unsavedIndex = null;
|
||||
// Fetch positioning of a newly added unsaved row. It will be the index of
|
||||
// this creator after the item is saved
|
||||
if (row.querySelector("[unsaved=true]")) {
|
||||
let previousRow = row.previousSibling;
|
||||
unsavedIndex = 0;
|
||||
if (previousRow.querySelector(".creator-type-value")) {
|
||||
unsavedIndex = 1 + parseInt(previousRow.querySelector(".creator-type-label").id.split('-')[1]);
|
||||
}
|
||||
}
|
||||
var fields = {
|
||||
lastName: label1.value,
|
||||
firstName: label2.value,
|
||||
fieldMode: fieldMode ? parseInt(fieldMode) : 0,
|
||||
creatorTypeID: parseInt(typeID),
|
||||
unsavedIndex: unsavedIndex,
|
||||
};
|
||||
|
||||
return fields;
|
||||
|
@ -1985,6 +2012,12 @@
|
|||
}
|
||||
return this.item.removeCreator(index);
|
||||
}
|
||||
// If this is a newly added row and there is an unsaved index,
|
||||
// shift all creators and update all indices.
|
||||
if (fields.unsavedIndex) {
|
||||
// Skip saving in this call to avoid extra re-rendering
|
||||
this.moveCreator(index, null, fields.unsavedIndex, true);
|
||||
}
|
||||
|
||||
return this.item.setCreator(index, fields);
|
||||
}
|
||||
|
@ -2106,7 +2139,7 @@
|
|||
/**
|
||||
* @return {Promise}
|
||||
*/
|
||||
moveCreator(index, dir, newIndex) {
|
||||
moveCreator(index, dir, newIndex, skipSave) {
|
||||
return Zotero.spawn(function* () {
|
||||
yield this.blurOpenField();
|
||||
if (index == 0 && dir == 'up') {
|
||||
|
@ -2152,7 +2185,7 @@
|
|||
}
|
||||
this.item.setCreator(i, creators[i]);
|
||||
}
|
||||
if (this.saveOnEdit) {
|
||||
if (this.saveOnEdit && !skipSave) {
|
||||
this.item.saveTx();
|
||||
}
|
||||
}, this);
|
||||
|
|
Loading…
Add table
Reference in a new issue