From 167673fcf56f164c6c6adb10b6917ce1199c02fc Mon Sep 17 00:00:00 2001 From: Wolfsblvt Date: Fri, 29 Mar 2024 04:41:16 +0100 Subject: [PATCH] Updated code documentation - Updated code documentation for all methods added/changed with this PR - Expanded tooltip to "bulk edit" to explain how it works --- public/index.html | 2 +- public/scripts/BulkEditOverlay.js | 74 ++++++++++++++++++++++--------- public/scripts/tags.js | 14 +++--- 3 files changed, 63 insertions(+), 27 deletions(-) diff --git a/public/index.html b/public/index.html index 8b2ee23a5..098ceb30d 100644 --- a/public/index.html +++ b/public/index.html @@ -4327,7 +4327,7 @@
- +
diff --git a/public/scripts/BulkEditOverlay.js b/public/scripts/BulkEditOverlay.js index 8da4dc86b..48d95e68b 100644 --- a/public/scripts/BulkEditOverlay.js +++ b/public/scripts/BulkEditOverlay.js @@ -40,7 +40,7 @@ class CharacterContextMenu { * Tag one or more characters, * opens a popup. * - * @param selectedCharacters + * @param {Array} selectedCharacters */ static tag = (selectedCharacters) => { BulkTagPopupHandler.show(selectedCharacters); @@ -49,7 +49,7 @@ class CharacterContextMenu { /** * Duplicate one or more characters * - * @param characterId + * @param {number} characterId * @returns {Promise} */ static duplicate = async (characterId) => { @@ -74,7 +74,7 @@ class CharacterContextMenu { * Favorite a character * and highlight it. * - * @param characterId + * @param {number} characterId * @returns {Promise} */ static favorite = async (characterId) => { @@ -110,7 +110,7 @@ class CharacterContextMenu { * Convert one or more characters to persona, * may open a popup for one or more characters. * - * @param characterId + * @param {number} characterId * @returns {Promise} */ static persona = async (characterId) => await convertCharacterToPersona(characterId); @@ -119,8 +119,8 @@ class CharacterContextMenu { * Delete one or more characters, * opens a popup. * - * @param characterId - * @param deleteChats + * @param {number} characterId + * @param {boolean} [deleteChats] * @returns {Promise} */ static delete = async (characterId, deleteChats = false) => { @@ -234,7 +234,7 @@ class BulkTagPopupHandler { /** * Append and show the tag control * - * @param characterIds - The characters assigned to this control + * @param {Array} characterIds - The characters assigned to this control */ static show(characterIds) { if (characterIds.length == 0) { @@ -250,7 +250,7 @@ class BulkTagPopupHandler { // Print the tag list with all mutuable tags, marking them as removable. That is the initial fill printTagList($('#bulkTagList'), { tags: () => this.getMutualTags(characterIds), tagOptions: { removable: true } }); - // Tag input with empty tags so new tag gets added and it doesn't get emptied on redraw + // Tag input with resolvable list for the mutual tags to get redrawn, so that newly added tags get sorted correctly createTagInput('#bulkTagInput', '#bulkTagList', { tags: () => this.getMutualTags(characterIds), tagOptions: { removable: true }}); document.querySelector('#bulk_tag_popup_reset').addEventListener('click', this.resetTags.bind(this, characterIds)); @@ -258,6 +258,12 @@ class BulkTagPopupHandler { document.querySelector('#bulk_tag_popup_cancel').addEventListener('click', this.hide.bind(this)); } + /** + * Builds a list of all tags that the provided characters have in common. + * + * @param {Array} characterIds - The characters to find mutual tags for + * @returns {Array} A list of mutual tags + */ static getMutualTags(characterIds) { if (characterIds.length == 0) { return []; @@ -293,7 +299,7 @@ class BulkTagPopupHandler { /** * Empty the tag map for the given characters * - * @param characterIds + * @param {Array} characterIds */ static resetTags(characterIds) { for (const characterId of characterIds) { @@ -307,9 +313,9 @@ class BulkTagPopupHandler { } /** - * Empty the tag map for the given characters + * Remove the mutual tags for all given characters * - * @param characterIds + * @param {Array} characterIds */ static removeMutual(characterIds) { const mutualTags = this.getMutualTags(characterIds); @@ -627,6 +633,15 @@ class BulkEditOverlay { this.#cancelNextToggle = false; }; + /** + * When shift click was held down, this function handles the multi select of characters in a single click. + * + * If the last clicked character was deselected, and the current one was deselected too, it will deselect all currently selected characters between those two. + * If the last clicked character was selected, and the current one was selected too, it will select all currently not selected characters between those two. + * If the states do not match, nothing will happen. + * + * @param {HTMLElement} currentCharacter - The html element of the currently toggled character + */ handleShiftClick = (currentCharacter) => { const characterId = currentCharacter.getAttribute('chid'); const select = !this.selectedCharacters.includes(characterId); @@ -634,11 +649,18 @@ class BulkEditOverlay { if (this.lastSelected.characterId && this.lastSelected.select !== undefined) { // Only if select state and the last select state match we execute the range select if (select === this.lastSelected.select) { - this.selectCharactersInRange(currentCharacter, select); + this.toggleCharactersInRange(currentCharacter, select); } } }; + /** + * Toggles the selection of a given characters + * + * @param {HTMLElement} character - The html element of a character + * @param {object} param1 - Optional params + * @param {boolean} [param1.markState] - Whether the toggle of this character should be remembered as the last done toggle + */ toggleSingleCharacter = (character, { markState = true } = {}) => { const characterId = character.getAttribute('chid'); @@ -648,11 +670,11 @@ class BulkEditOverlay { if (select) { character.classList.add(BulkEditOverlay.selectedClass); if (legacyBulkEditCheckbox) legacyBulkEditCheckbox.checked = true; - this.selectCharacter(characterId); + this.#selectedCharacters.push(String(characterId)); } else { character.classList.remove(BulkEditOverlay.selectedClass); if (legacyBulkEditCheckbox) legacyBulkEditCheckbox.checked = false; - this.dismissCharacter(characterId); + this.#selectedCharacters = this.#selectedCharacters.filter(item => String(characterId) !== item) } this.updateSelectedCount(); @@ -663,12 +685,24 @@ class BulkEditOverlay { } }; + /** + * Updates the selected count element with the current count + * + * @param {number} [countOverride] - optional override for a manual number to set + */ updateSelectedCount = (countOverride = undefined) => { const count = countOverride ?? this.selectedCharacters.length; $(`#${BulkEditOverlay.bulkSelectedCountId}`).text(count).attr('title', `${count} characters selected`); }; - selectCharactersInRange = (currentCharacter, select) => { + /** + * Toggles the selection of characters in a given range. + * The range is provided by the given character and the last selected one remembered in the selection state. + * + * @param {HTMLElement} currentCharacter - The html element of the currently toggled character + * @param {boolean} select - true if the characters in the range are to be selected, false if deselected + */ + toggleCharactersInRange = (currentCharacter, select) => { const currentCharacterId = currentCharacter.getAttribute('chid'); const characters = Array.from(document.querySelectorAll('#' + BulkEditOverlay.containerId + ' .' + BulkEditOverlay.characterClass)); @@ -680,8 +714,10 @@ class BulkEditOverlay { const characterId = character.getAttribute('chid'); const isCharacterSelected = this.selectedCharacters.includes(characterId); - if (select && !isCharacterSelected || !select && isCharacterSelected) { - this.toggleSingleCharacter(character, { markState: currentCharacterId == i }); + // Only toggle the character if it wasn't on the state we have are toggling towards. + // Also doing a weird type check, because typescript checker doesn't like the return of 'querySelectorAll'. + if ((select && !isCharacterSelected || !select && isCharacterSelected) && character instanceof HTMLElement) { + this.toggleSingleCharacter(character, { markState: currentCharacterId == characterId }); } } }; @@ -771,10 +807,6 @@ class BulkEditOverlay { addStateChangeCallback = callback => this.stateChangeCallbacks.push(callback); - selectCharacter = characterId => this.selectedCharacters.push(String(characterId)); - - dismissCharacter = characterId => this.#selectedCharacters = this.selectedCharacters.filter(item => String(characterId) !== item); - /** * Clears internal character storage and * removes visual highlight. diff --git a/public/scripts/tags.js b/public/scripts/tags.js index 8895545e8..816087d73 100644 --- a/public/scripts/tags.js +++ b/public/scripts/tags.js @@ -320,7 +320,8 @@ function getTagKey() { /** * Gets the tag key for any provided entity/id/key. If a valid tag key is provided, it just returns this. - * Robust method to find a valid tag key for any entity + * Robust method to find a valid tag key for any entity. + * * @param {object|number|string} entityOrKey An entity with id property (character, group, tag), or directly an id or tag key. * @returns {string} The tag key that can be found. */ @@ -394,9 +395,10 @@ function findTag(request, resolve, listSelector) { } /** - * Select a tag and add it to the list. This function is mostly used as an event handler for the tag selector control. - * @param {*} event - - * @param {*} ui - + * Select a tag and add it to the list. This function is (mostly) used as an event handler for the tag selector control. + * + * @param {*} event - The event that fired on autocomplete select + * @param {*} ui - An Object with label and value properties for the selected option * @param {*} listSelector - The selector of the list to print/add to * @param {PrintTagListOptions} [tagListOptions] - Optional parameters for printing the tag list. Can be set to be consistent with the expected behavior of tags in the list that was defined before. * @returns {boolean} false, to keep the input clear @@ -529,7 +531,8 @@ function createNewTag(tagName) { */ /** - * Prints the list of tags. + * Prints the list of tags + * * @param {JQuery} element - The container element where the tags are to be printed. * @param {PrintTagListOptions} [options] - Optional parameters for printing the tag list. */ @@ -798,6 +801,7 @@ function applyTagsOnGroupSelect() { } /** + * Create a tag input by enabling the autocomplete feature of a given input element. Tags will be added to the given list. * * @param {string} inputSelector - the selector for the tag input control * @param {string} listSelector - the selector for the list of the tags modified by the input control