fix(presets): defer association changes until Save & Apply
- Add isAssociatedWithCurrentPreset() helper to check if entity is associated with the CURRENT preset (not just any preset) - Fix checkbox to correctly reflect association with currently selected preset - Introduce tempAssociation state to track pending association changes - Only save association changes when clicking Save & Apply, not on preset switch - Discard pending association changes when clicking X/Cancel - Auto-update association when switching presets if checkbox was checked - Improve toast messages to clarify when changes will be applied Fixes issue where checkbox showed incorrect state and association was saved immediately without waiting for Save & Apply.
This commit is contained in:
@@ -915,6 +915,17 @@ export function hasPresetAssociation() {
|
|||||||
return entityKey && extensionSettings.presetManager.characterAssociations[entityKey] !== undefined;
|
return entityKey && extensionSettings.presetManager.characterAssociations[entityKey] !== undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the current character/group is associated with the currently active preset
|
||||||
|
* @returns {boolean} True if the current entity is associated with the active preset
|
||||||
|
*/
|
||||||
|
export function isAssociatedWithCurrentPreset() {
|
||||||
|
const entityKey = getCurrentEntityKey();
|
||||||
|
const activePresetId = extensionSettings.presetManager?.activePresetId;
|
||||||
|
if (!entityKey || !activePresetId) return false;
|
||||||
|
return extensionSettings.presetManager.characterAssociations[entityKey] === activePresetId;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Auto-switches to the preset associated with the current character/group
|
* Auto-switches to the preset associated with the current character/group
|
||||||
* Called when character changes. Falls back to default preset if no association.
|
* Called when character changes. Falls back to default preset if no association.
|
||||||
|
|||||||
@@ -21,6 +21,8 @@ import {
|
|||||||
removePresetAssociationForCurrentEntity,
|
removePresetAssociationForCurrentEntity,
|
||||||
getPresetForCurrentEntity,
|
getPresetForCurrentEntity,
|
||||||
hasPresetAssociation,
|
hasPresetAssociation,
|
||||||
|
isAssociatedWithCurrentPreset,
|
||||||
|
getCurrentEntityKey,
|
||||||
getCurrentEntityName,
|
getCurrentEntityName,
|
||||||
exportPresets,
|
exportPresets,
|
||||||
importPresets
|
importPresets
|
||||||
@@ -33,6 +35,8 @@ import { updateFabWidgets } from './mobile.js';
|
|||||||
let $editorModal = null;
|
let $editorModal = null;
|
||||||
let activeTab = 'userStats';
|
let activeTab = 'userStats';
|
||||||
let tempConfig = null; // Temporary config for cancel functionality
|
let tempConfig = null; // Temporary config for cancel functionality
|
||||||
|
let tempAssociation = null; // Temporary association state: { presetId: string|null, entityKey: string|null }
|
||||||
|
let originalAssociation = null; // Original association when editor opened
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize the tracker editor modal
|
* Initialize the tracker editor modal
|
||||||
@@ -104,6 +108,12 @@ export function initTrackerEditor() {
|
|||||||
$(document).on('change', '#rpg-preset-select', function() {
|
$(document).on('change', '#rpg-preset-select', function() {
|
||||||
const presetId = $(this).val();
|
const presetId = $(this).val();
|
||||||
if (presetId && presetId !== getActivePresetId()) {
|
if (presetId && presetId !== getActivePresetId()) {
|
||||||
|
// Check if the current character had an association (either original or pending)
|
||||||
|
const entityKey = getCurrentEntityKey();
|
||||||
|
const wasAssociated = tempAssociation
|
||||||
|
? tempAssociation.presetId !== null
|
||||||
|
: hasPresetAssociation();
|
||||||
|
|
||||||
// Save current changes to the old preset before switching
|
// Save current changes to the old preset before switching
|
||||||
const currentPresetId = getActivePresetId();
|
const currentPresetId = getActivePresetId();
|
||||||
if (currentPresetId) {
|
if (currentPresetId) {
|
||||||
@@ -113,8 +123,17 @@ export function initTrackerEditor() {
|
|||||||
if (loadPreset(presetId)) {
|
if (loadPreset(presetId)) {
|
||||||
tempConfig = JSON.parse(JSON.stringify(extensionSettings.trackerConfig));
|
tempConfig = JSON.parse(JSON.stringify(extensionSettings.trackerConfig));
|
||||||
renderEditorUI();
|
renderEditorUI();
|
||||||
|
|
||||||
|
// If the character was associated with a preset, update temp association to new preset
|
||||||
|
if (wasAssociated && entityKey) {
|
||||||
|
tempAssociation = { presetId: presetId, entityKey: entityKey };
|
||||||
|
const preset = getPreset(presetId);
|
||||||
|
toastr.info(`"${preset?.name || 'Unknown'}" will be associated with ${getCurrentEntityName()} when saved.`);
|
||||||
|
} else {
|
||||||
|
toastr.success(`Switched to preset "${getPreset(presetId)?.name || 'Unknown'}".`);
|
||||||
|
}
|
||||||
|
|
||||||
updatePresetUI();
|
updatePresetUI();
|
||||||
toastr.success(`Switched to preset "${getPreset(presetId)?.name || 'Unknown'}".`);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -162,12 +181,25 @@ export function initTrackerEditor() {
|
|||||||
|
|
||||||
// Associate preset checkbox
|
// Associate preset checkbox
|
||||||
$(document).on('change', '#rpg-preset-associate', function() {
|
$(document).on('change', '#rpg-preset-associate', function() {
|
||||||
|
const activePresetId = getActivePresetId();
|
||||||
|
const preset = getPreset(activePresetId);
|
||||||
|
const entityName = getCurrentEntityName();
|
||||||
|
const entityKey = getCurrentEntityKey();
|
||||||
|
|
||||||
if ($(this).is(':checked')) {
|
if ($(this).is(':checked')) {
|
||||||
associatePresetWithCurrentEntity();
|
// Store pending association (don't save yet)
|
||||||
toastr.info(`This preset will be used for ${getCurrentEntityName()}.`);
|
tempAssociation = { presetId: activePresetId, entityKey: entityKey };
|
||||||
|
toastr.info(`"${preset?.name || 'Unknown'}" will be associated with ${entityName} when saved.`);
|
||||||
} else {
|
} else {
|
||||||
removePresetAssociationForCurrentEntity();
|
// Store pending removal (don't save yet)
|
||||||
toastr.info(`Preset association removed for ${getCurrentEntityName()}.`);
|
tempAssociation = { presetId: null, entityKey: entityKey };
|
||||||
|
const defaultPresetId = getDefaultPresetId();
|
||||||
|
const defaultPreset = getPreset(defaultPresetId);
|
||||||
|
if (defaultPreset && defaultPresetId !== activePresetId) {
|
||||||
|
toastr.info(`Association will be removed when saved. Default preset "${defaultPreset.name}" will apply on next character switch.`);
|
||||||
|
} else {
|
||||||
|
toastr.info(`Association will be removed for ${entityName} when saved.`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -203,7 +235,15 @@ function updatePresetUI() {
|
|||||||
$('#rpg-preset-entity-name').text(entityName);
|
$('#rpg-preset-entity-name').text(entityName);
|
||||||
|
|
||||||
// Update the association checkbox
|
// Update the association checkbox
|
||||||
const isAssociated = hasPresetAssociation();
|
// Use temp state if available, otherwise check actual association with CURRENT preset
|
||||||
|
let isAssociated;
|
||||||
|
if (tempAssociation !== null) {
|
||||||
|
// Use pending state: checked if pending preset matches active preset
|
||||||
|
isAssociated = tempAssociation.presetId === activePresetId;
|
||||||
|
} else {
|
||||||
|
// No pending changes, check actual state
|
||||||
|
isAssociated = isAssociatedWithCurrentPreset();
|
||||||
|
}
|
||||||
$('#rpg-preset-associate').prop('checked', isAssociated);
|
$('#rpg-preset-associate').prop('checked', isAssociated);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -214,6 +254,12 @@ function openTrackerEditor() {
|
|||||||
// Create temporary copy for cancel functionality
|
// Create temporary copy for cancel functionality
|
||||||
tempConfig = JSON.parse(JSON.stringify(extensionSettings.trackerConfig));
|
tempConfig = JSON.parse(JSON.stringify(extensionSettings.trackerConfig));
|
||||||
|
|
||||||
|
// Store original association state for cancel functionality
|
||||||
|
const entityKey = getCurrentEntityKey();
|
||||||
|
const currentAssociatedPreset = getPresetForCurrentEntity();
|
||||||
|
originalAssociation = { presetId: currentAssociatedPreset, entityKey: entityKey };
|
||||||
|
tempAssociation = null; // Reset pending changes
|
||||||
|
|
||||||
// Set theme to match current extension theme
|
// Set theme to match current extension theme
|
||||||
const theme = extensionSettings.theme || 'modern';
|
const theme = extensionSettings.theme || 'modern';
|
||||||
$editorModal.attr('data-theme', theme);
|
$editorModal.attr('data-theme', theme);
|
||||||
@@ -235,6 +281,10 @@ function closeTrackerEditor() {
|
|||||||
tempConfig = null;
|
tempConfig = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Discard pending association changes (cancel = no save)
|
||||||
|
tempAssociation = null;
|
||||||
|
originalAssociation = null;
|
||||||
|
|
||||||
$editorModal.removeClass('is-open').addClass('is-closing');
|
$editorModal.removeClass('is-open').addClass('is-closing');
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
$editorModal.removeClass('is-closing').hide();
|
$editorModal.removeClass('is-closing').hide();
|
||||||
@@ -247,6 +297,21 @@ function closeTrackerEditor() {
|
|||||||
function applyTrackerConfig() {
|
function applyTrackerConfig() {
|
||||||
tempConfig = null; // Clear temp config
|
tempConfig = null; // Clear temp config
|
||||||
|
|
||||||
|
// Apply pending association changes
|
||||||
|
if (tempAssociation) {
|
||||||
|
if (tempAssociation.presetId !== null) {
|
||||||
|
// Associate with the pending preset
|
||||||
|
associatePresetWithCurrentEntity();
|
||||||
|
const preset = getPreset(tempAssociation.presetId);
|
||||||
|
toastr.success(`"${preset?.name || 'Unknown'}" is now associated with ${getCurrentEntityName()}.`);
|
||||||
|
} else {
|
||||||
|
// Remove association
|
||||||
|
removePresetAssociationForCurrentEntity();
|
||||||
|
}
|
||||||
|
tempAssociation = null;
|
||||||
|
}
|
||||||
|
originalAssociation = null;
|
||||||
|
|
||||||
// Save to the current preset
|
// Save to the current preset
|
||||||
const currentPresetId = getActivePresetId();
|
const currentPresetId = getActivePresetId();
|
||||||
if (currentPresetId) {
|
if (currentPresetId) {
|
||||||
|
|||||||
Reference in New Issue
Block a user