diff --git a/public/css/character-group-overlay.css b/public/css/character-group-overlay.css index b0d4b4a14..5327694a8 100644 --- a/public/css/character-group-overlay.css +++ b/public/css/character-group-overlay.css @@ -99,6 +99,6 @@ } #bulk_tag_shadow_popup #bulk_tag_popup #dialogue_popup_controls .menu_button { - width: 100px; + width: unset; padding: 0.25em; } diff --git a/public/script.js b/public/script.js index eed5022e5..d25085430 100644 --- a/public/script.js +++ b/public/script.js @@ -10740,7 +10740,7 @@ jQuery(async function () { } } break; case 'import_tags': { - await importTags(characters[this_chid], { forceShow: true }); + await importTags(characters[this_chid], { importSetting: tag_import_setting.ASK }); } break; /*case 'delete_button': popup_type = "del_ch"; diff --git a/public/scripts/BulkEditOverlay.js b/public/scripts/BulkEditOverlay.js index d121d0fc6..28517d32f 100644 --- a/public/scripts/BulkEditOverlay.js +++ b/public/scripts/BulkEditOverlay.js @@ -18,7 +18,7 @@ import { import { favsToHotswap } from './RossAscends-mods.js'; import { hideLoader, showLoader } from './loader.js'; import { convertCharacterToPersona } from './personas.js'; -import { createTagInput, getTagKeyForEntity, getTagsList, printTagList, tag_map, compareTagsForSort, removeTagFromMap } from './tags.js'; +import { createTagInput, getTagKeyForEntity, getTagsList, printTagList, tag_map, compareTagsForSort, removeTagFromMap, importTags, tag_import_setting } from './tags.js'; /** * Static object representing the actions of the @@ -197,10 +197,10 @@ class BulkTagPopupHandler { #getHtml = () => { const characterData = JSON.stringify({ characterIds: this.characterIds }); return `
-
+

Modify tags of ${this.characterIds.length} characters

- Add or remove the mutual tags of all selected characters. + Add or remove the mutual tags of all selected characters. Import all or existing tags for all selected characters.

@@ -219,6 +219,12 @@ class BulkTagPopupHandler { Mutual
+ +
@@ -254,6 +260,30 @@ class BulkTagPopupHandler { document.querySelector('#bulk_tag_popup_reset').addEventListener('click', this.resetTags.bind(this)); document.querySelector('#bulk_tag_popup_remove_mutual').addEventListener('click', this.removeMutual.bind(this)); document.querySelector('#bulk_tag_popup_cancel').addEventListener('click', this.hide.bind(this)); + document.querySelector('#bulk_tag_popup_import_all_tags').addEventListener('click', this.importAllTags.bind(this)); + document.querySelector('#bulk_tag_popup_import_existing_tags').addEventListener('click', this.importExistingTags.bind(this)); + } + + /** + * Import existing tags for all selected characters + */ + async importExistingTags() { + for (const characterId of this.characterIds) { + await importTags(characters[characterId], { importSetting: tag_import_setting.ONLY_EXISTING }); + } + + $('#bulkTagList').empty(); + } + + /** + * Import all tags for all selected characters + */ + async importAllTags() { + for (const characterId of this.characterIds) { + await importTags(characters[characterId], { importSetting: tag_import_setting.ALL }); + } + + $('#bulkTagList').empty(); } /** @@ -570,7 +600,7 @@ class BulkEditOverlay { this.container.removeEventListener('mouseup', cancelHold); this.container.removeEventListener('touchend', cancelHold); }, - BulkEditOverlay.longPressDelay); + BulkEditOverlay.longPressDelay); }; handleLongPressEnd = (event) => { diff --git a/public/scripts/tags.js b/public/scripts/tags.js index 43b52f74e..642821467 100644 --- a/public/scripts/tags.js +++ b/public/scripts/tags.js @@ -708,12 +708,12 @@ const ANTI_TROLL_MAX_TAGS = 15; * * @param {Character} character - The character * @param {object} [options] - Options - * @param {boolean} [options.forceShow=false] - Whether to force showing the import dialog + * @param {tag_import_setting} [options.importSetting=null] - Force a tag import setting * @returns {Promise} Boolean indicating whether any tag was imported */ -async function importTags(character, { forceShow = false } = {}) { +async function importTags(character, { importSetting = null } = {}) { // Gather the tags to import based on the selected setting - const tagNamesToImport = await handleTagImport(character, { forceShow }); + const tagNamesToImport = await handleTagImport(character, { importSetting }); if (!tagNamesToImport?.length) { console.debug('No tags to import'); return; @@ -732,10 +732,10 @@ async function importTags(character, { forceShow = false } = {}) { * * @param {Character} character - The character * @param {object} [options] - Options - * @param {boolean} [options.forceShow=false] - Whether to force showing the import dialog + * @param {tag_import_setting} [options.importSetting=null] - Force a tag import setting * @returns {Promise} Array of strings representing the tags to import */ -async function handleTagImport(character, { forceShow = false } = {}) { +async function handleTagImport(character, { importSetting = null } = {}) { /** @type {string[]} */ const importTags = character.tags.map(t => t.trim()).filter(t => t) .filter(t => !IMPORT_EXLCUDED_TAGS.includes(t)) @@ -745,9 +745,9 @@ async function handleTagImport(character, { forceShow = false } = {}) { .map(newTag); const folderTags = getOpenBogusFolders(); - // Choose the setting for this dialog. If from settings, verify the setting really exists, otherwise take "ASK". - const setting = forceShow ? tag_import_setting.ASK - : Object.values(tag_import_setting).find(setting => setting === power_user.tag_import_setting) ?? tag_import_setting.ASK; + // Choose the setting for this dialog. First check override, then saved setting or finally use "ASK". + const setting = importSetting ? importSetting : + Object.values(tag_import_setting).find(setting => setting === power_user.tag_import_setting) ?? tag_import_setting.ASK; switch (setting) { case tag_import_setting.ALL: