Fix storage location deletion bug with special characters

- Created getLocationId() helper function to normalize location names to IDs
- Function removes special characters (apostrophes, etc.) before converting to ID
- Both rendering and action handlers now use same ID generation logic
- Fixes issue where locations with apostrophes couldn't be deleted
- Example: "Dottore's Study" now properly generates ID "Dottores-Study"
- Commented out debug logging
This commit is contained in:
Spicy_Marinara
2025-10-19 20:47:12 +02:00
parent dcbc788aa2
commit 6d105482c3
3 changed files with 49 additions and 20 deletions
+8 -8
View File
@@ -558,16 +558,16 @@ jQuery(async () => {
try { try {
const conflicts = detectConflictingRegexScripts(st_extension_settings); const conflicts = detectConflictingRegexScripts(st_extension_settings);
if (conflicts.length > 0) { if (conflicts.length > 0) {
console.warn('[RPG Companion] ⚠️ Detected old manual formatting regex scripts that may conflict:'); console.log('[RPG Companion] ⚠️ Detected old manual formatting regex scripts that may conflict:');
conflicts.forEach(name => console.warn(` - ${name}`)); conflicts.forEach(name => console.log(` - ${name}`));
console.warn('[RPG Companion] Consider disabling these regexes as the extension now handles formatting automatically.'); console.log('[RPG Companion] Consider disabling these regexes as the extension now handles formatting automatically.');
// Show user-friendly warning (non-blocking) // Show user-friendly warning (non-blocking)
toastr.warning( // toastr.warning(
`Found ${conflicts.length} old RPG formatting regex script(s). These may conflict with the extension. Check console for details.`, // `Found ${conflicts.length} old RPG formatting regex script(s). These may conflict with the extension. Check console for details.`,
'RPG Companion Warning', // 'RPG Companion Warning',
{ timeOut: 8000 } // { timeOut: 8000 }
); // );
} }
} catch (error) { } catch (error) {
console.error('[RPG Companion] Conflict detection failed:', error); console.error('[RPG Companion] Conflict detection failed:', error);
+29 -11
View File
@@ -6,7 +6,7 @@
import { extensionSettings, lastGeneratedData } from '../../core/state.js'; import { extensionSettings, lastGeneratedData } from '../../core/state.js';
import { saveSettings, saveChatData, updateMessageSwipeData } from '../../core/persistence.js'; import { saveSettings, saveChatData, updateMessageSwipeData } from '../../core/persistence.js';
import { buildInventorySummary } from '../generation/promptBuilder.js'; import { buildInventorySummary } from '../generation/promptBuilder.js';
import { renderInventory } from '../rendering/inventory.js'; import { renderInventory, getLocationId } from '../rendering/inventory.js';
import { parseItems, serializeItems } from '../../utils/itemParser.js'; import { parseItems, serializeItems } from '../../utils/itemParser.js';
// Type imports // Type imports
@@ -53,7 +53,7 @@ export function showAddItemForm(field, location) {
let inputId; let inputId;
if (field === 'stored') { if (field === 'stored') {
const locationId = location.replace(/\s+/g, '-'); const locationId = getLocationId(location);
formId = `rpg-add-item-form-stored-${locationId}`; formId = `rpg-add-item-form-stored-${locationId}`;
inputId = `.rpg-location-item-input[data-location="${location}"]`; inputId = `.rpg-location-item-input[data-location="${location}"]`;
} else { } else {
@@ -78,7 +78,7 @@ export function hideAddItemForm(field, location) {
let inputId; let inputId;
if (field === 'stored') { if (field === 'stored') {
const locationId = location.replace(/\s+/g, '-'); const locationId = getLocationId(location);
formId = `rpg-add-item-form-stored-${locationId}`; formId = `rpg-add-item-form-stored-${locationId}`;
inputId = `.rpg-location-item-input[data-location="${location}"]`; inputId = `.rpg-location-item-input[data-location="${location}"]`;
} else { } else {
@@ -154,6 +154,8 @@ export function saveAddItem(field, location) {
export function removeItem(field, itemIndex, location) { export function removeItem(field, itemIndex, location) {
const inventory = extensionSettings.userStats.inventory; const inventory = extensionSettings.userStats.inventory;
// console.log('[RPG Companion] DEBUG removeItem called:', { field, itemIndex, location });
// Get current items, remove the one at index, serialize back // Get current items, remove the one at index, serialize back
let currentString; let currentString;
if (field === 'stored') { if (field === 'stored') {
@@ -162,9 +164,16 @@ export function removeItem(field, itemIndex, location) {
currentString = inventory[field] || 'None'; currentString = inventory[field] || 'None';
} }
// console.log('[RPG Companion] DEBUG currentString before removal:', currentString);
const items = parseItems(currentString); const items = parseItems(currentString);
// console.log('[RPG Companion] DEBUG items array before removal:', items);
items.splice(itemIndex, 1); // Remove item at index items.splice(itemIndex, 1); // Remove item at index
// console.log('[RPG Companion] DEBUG items array after removal:', items);
const newString = serializeItems(items); const newString = serializeItems(items);
// console.log('[RPG Companion] DEBUG newString after removal:', newString);
// Save back to inventory // Save back to inventory
if (field === 'stored') { if (field === 'stored') {
@@ -173,6 +182,8 @@ export function removeItem(field, itemIndex, location) {
inventory[field] = newString; inventory[field] = newString;
} }
// console.log('[RPG Companion] DEBUG inventory after save:', inventory);
updateLastGeneratedDataInventory(); updateLastGeneratedDataInventory();
saveSettings(); saveSettings();
saveChatData(); saveChatData();
@@ -180,9 +191,7 @@ export function removeItem(field, itemIndex, location) {
// Re-render // Re-render
renderInventory(); renderInventory();
} }/**
/**
* Shows the inline form for adding a new storage location. * Shows the inline form for adding a new storage location.
*/ */
export function showAddLocationForm() { export function showAddLocationForm() {
@@ -241,11 +250,17 @@ export function saveAddLocation() {
* @param {string} locationName - Name of location to remove * @param {string} locationName - Name of location to remove
*/ */
export function showRemoveConfirmation(locationName) { export function showRemoveConfirmation(locationName) {
const confirmId = `rpg-remove-confirm-${locationName.replace(/\s+/g, '-')}`; // console.log('[RPG Companion] DEBUG showRemoveConfirmation called for:', locationName);
const confirmId = `rpg-remove-confirm-${getLocationId(locationName)}`;
// console.log('[RPG Companion] DEBUG confirmId:', confirmId);
const confirmUI = $(`#${confirmId}`); const confirmUI = $(`#${confirmId}`);
// console.log('[RPG Companion] DEBUG confirmUI element found:', confirmUI.length);
if (confirmUI.length > 0) { if (confirmUI.length > 0) {
confirmUI.show(); confirmUI.show();
// console.log('[RPG Companion] DEBUG confirmation shown');
} else {
console.warn('[RPG Companion] DEBUG confirmation element not found!');
} }
} }
@@ -254,7 +269,7 @@ export function showRemoveConfirmation(locationName) {
* @param {string} locationName - Name of location * @param {string} locationName - Name of location
*/ */
export function hideRemoveConfirmation(locationName) { export function hideRemoveConfirmation(locationName) {
const confirmId = `rpg-remove-confirm-${locationName.replace(/\s+/g, '-')}`; const confirmId = `rpg-remove-confirm-${getLocationId(locationName)}`;
const confirmUI = $(`#${confirmId}`); const confirmUI = $(`#${confirmId}`);
if (confirmUI.length > 0) { if (confirmUI.length > 0) {
@@ -267,8 +282,12 @@ export function hideRemoveConfirmation(locationName) {
* @param {string} locationName - Name of location to remove * @param {string} locationName - Name of location to remove
*/ */
export function confirmRemoveLocation(locationName) { export function confirmRemoveLocation(locationName) {
// console.log('[RPG Companion] DEBUG confirmRemoveLocation called for:', locationName);
const inventory = extensionSettings.userStats.inventory; const inventory = extensionSettings.userStats.inventory;
// console.log('[RPG Companion] DEBUG inventory.stored before deletion:', inventory.stored);
delete inventory.stored[locationName]; delete inventory.stored[locationName];
// console.log('[RPG Companion] DEBUG inventory.stored after deletion:', inventory.stored);
// Remove from collapsed list if present // Remove from collapsed list if present
const index = collapsedLocations.indexOf(locationName); const index = collapsedLocations.indexOf(locationName);
@@ -282,10 +301,9 @@ export function confirmRemoveLocation(locationName) {
updateMessageSwipeData(); updateMessageSwipeData();
// Re-render inventory UI // Re-render inventory UI
// console.log('[RPG Companion] DEBUG calling renderInventory()');
renderInventory(); renderInventory();
} }/**
/**
* Toggles the collapsed state of a storage location section. * Toggles the collapsed state of a storage location section.
* @param {string} locationName - Name of location to toggle * @param {string} locationName - Name of location to toggle
*/ */
+12 -1
View File
@@ -10,6 +10,17 @@ import { parseItems } from '../../utils/itemParser.js';
// Type imports // Type imports
/** @typedef {import('../../types/inventory.js').InventoryV2} InventoryV2 */ /** @typedef {import('../../types/inventory.js').InventoryV2} InventoryV2 */
/**
* Converts a location name to a safe ID for use in HTML element IDs.
* Must match the logic used in inventoryActions.js.
* @param {string} locationName - The location name
* @returns {string} Safe ID string
*/
export function getLocationId(locationName) {
// Remove all non-alphanumeric characters except spaces, then replace spaces with hyphens
return locationName.replace(/[^a-zA-Z0-9\s]/g, '').replace(/\s+/g, '-');
}
/** /**
* Renders the inventory sub-tab navigation (On Person, Stored, Assets) * Renders the inventory sub-tab navigation (On Person, Stored, Assets)
* @param {string} activeTab - Currently active sub-tab ('onPerson', 'stored', 'assets') * @param {string} activeTab - Currently active sub-tab ('onPerson', 'stored', 'assets')
@@ -160,7 +171,7 @@ export function renderStoredView(stored, collapsedLocations = [], viewMode = 'li
const itemString = stored[location]; const itemString = stored[location];
const items = parseItems(itemString); const items = parseItems(itemString);
const isCollapsed = collapsedLocations.includes(location); const isCollapsed = collapsedLocations.includes(location);
const locationId = escapeHtml(location).replace(/\s+/g, '-'); const locationId = getLocationId(location);
let itemsHtml = ''; let itemsHtml = '';
if (items.length === 0) { if (items.length === 0) {