From 4b8fb8c1cb21662c1c9ce7b7774b00b57f246da8 Mon Sep 17 00:00:00 2001 From: HighImKevin Date: Sun, 18 Oct 2026 08:46:01 -0400 Subject: [PATCH] Update the Restore Default section functionality to save the section instead of just updating the editor --- configuration/homeScreen-configuration.js | 13 ++-- configuration/homeScreenAdvancedEditor.js | 54 ++++++++++++--- configuration/homeScreenSectionEditor.js | 84 +++++++++++++++++------ 3 files changed, 114 insertions(+), 37 deletions(-) diff --git a/configuration/homeScreen-configuration.js b/configuration/homeScreen-configuration.js index 58fb855..fa0478e 100644 --- a/configuration/homeScreen-configuration.js +++ b/configuration/homeScreen-configuration.js @@ -3212,9 +3212,10 @@ window.KefinTweaksConfig = ${JSON.stringify(configToBackup, null, 2)};`; const editCtxBase = { sectionType, config: currentConfig, - onSave: async (sectionData) => { + onSave: async (sectionData, saveOptions = {}) => { const targetGroupName = sectionData._targetGroupName; delete sectionData._targetGroupName; + const quiet = saveOptions?.quiet === true; const found = findSectionInAllGroups(currentConfig, sectionData.id); const savingToCustom = !found || found.groupType === 'CUSTOM_SECTION_GROUPS' @@ -3239,7 +3240,7 @@ window.KefinTweaksConfig = ${JSON.stringify(configToBackup, null, 2)};`; found.group.sections.splice(found.sectionIndex, 1); addSectionToGroup(currentConfig[found.groupType], targetGroupName, sectionData); await saveConfig(currentConfig); - showToast('Section saved'); + if (!quiet) showToast('Section saved'); refreshMainModal({ focusSectionId: sectionData.id, sectionType: sectionTypeForRow @@ -3247,7 +3248,7 @@ window.KefinTweaksConfig = ${JSON.stringify(configToBackup, null, 2)};`; } else { updateSectionInGroups(currentConfig[found.groupType], sectionData.id, sectionData); await saveConfig(currentConfig); - showToast('Section saved'); + if (!quiet) showToast('Section saved'); if (updateSectionRowInPlace(sectionData, sectionTypeForRow)) { scrollSectionRowIntoView(sectionData.id); } else { @@ -3260,7 +3261,7 @@ window.KefinTweaksConfig = ${JSON.stringify(configToBackup, null, 2)};`; } else { addSectionToGroup(currentConfig.CUSTOM_SECTION_GROUPS, targetGroupName || 'Custom Sections', sectionData); await saveConfig(currentConfig); - showToast('Saved new Home Screen Section'); + if (!quiet) showToast('Saved new Home Screen Section'); refreshMainModal({ focusSectionId: sectionData.id, sectionType: 'custom' @@ -5865,8 +5866,8 @@ window.KefinTweaksConfig = ${JSON.stringify(configToBackup, null, 2)};`; return { items: [], limit: 0, section: previewSection }; } - const limit = withPreviewQueryOptions(queriesToLoad[0]).queryOptions.Limit - || previewSection.itemLimit + const limit = previewSection.itemLimit + || withPreviewQueryOptions(queriesToLoad[0]).queryOptions.Limit || PREVIEW_DEFAULT_LIMIT; allItems = window.cardBuilder.postProcessItems(previewSection, allItems); const limitedItems = allItems.slice(0, parseInt(limit, 10)); diff --git a/configuration/homeScreenAdvancedEditor.js b/configuration/homeScreenAdvancedEditor.js index a926d80..b167aa3 100644 --- a/configuration/homeScreenAdvancedEditor.js +++ b/configuration/homeScreenAdvancedEditor.js @@ -3925,10 +3925,13 @@ const state = modalInstance?._hsaeState; if (!state || !importedSection) return; const current = state.section || {}; - const context = state.context || {}; + const context = { ...(state.context || {}) }; const merged = deepCloneJson(importedSection) || {}; merged.id = current.id || merged.id; if (current.deleted === true) merged.deleted = true; + // Keep collect/export/troubleshoot bases in sync with the applied section + context.originalSection = deepCloneJson(merged); + context.section = merged; const newState = buildEditorStateFromSection(merged, context); modalInstance._hsaeState = newState; const stateHost = modalInstance.dialogContainer || modalInstance.dialogContent; @@ -4147,8 +4150,8 @@ const content = document.createElement('div'); content.innerHTML = `
- Restoring defaults will override the current editor values for this section with the KefinTweaks defaults. - Enabled status and order are kept. You still need to Save to persist. + Restoring defaults will save the KefinTweaks defaults for this section and reload the editor. + Enabled status and order are kept.
${rowsHtml} `; @@ -4178,10 +4181,19 @@ modal.dialogFooter?.querySelector('#hsae-restore-cancel')?.addEventListener('click', () => { window.ModalSystem.close(HSAE_RESTORE_DEFAULTS_MODAL_ID); }); - modal.dialogFooter?.querySelector('#hsae-restore-proceed')?.addEventListener('click', () => { + modal.dialogFooter?.querySelector('#hsae-restore-proceed')?.addEventListener('click', async () => { if (matching) return; - window.ModalSystem.close(HSAE_RESTORE_DEFAULTS_MODAL_ID); - if (typeof onProceed === 'function') onProceed(); + const proceedBtn = modal.dialogFooter?.querySelector('#hsae-restore-proceed'); + const cancelBtn = modal.dialogFooter?.querySelector('#hsae-restore-cancel'); + if (proceedBtn) proceedBtn.disabled = true; + if (cancelBtn) cancelBtn.disabled = true; + try { + window.ModalSystem.close(HSAE_RESTORE_DEFAULTS_MODAL_ID); + if (typeof onProceed === 'function') await onProceed(); + } catch (e) { + console.warn('[HSAE] Restore defaults failed:', e); + showHsaeToast('Failed to restore defaults'); + } }); } }); @@ -4627,13 +4639,29 @@ const current = collectData(dialog, original) || deepCloneJson(state.section) || {}; if (state.section?.id) current.id = state.section.id; const diffs = diffSectionAgainstDefault(current, canonical); - showRestoreDefaultsConfirmModal(modalInstance, diffs, () => { + showRestoreDefaultsConfirmModal(modalInstance, diffs, async () => { const merged = deepCloneJson(canonical) || {}; merged.id = current.id || sectionId; if (Object.prototype.hasOwnProperty.call(current, 'enabled')) merged.enabled = current.enabled; if (Object.prototype.hasOwnProperty.call(current, 'order')) merged.order = current.order; if (current.deleted === true) merged.deleted = true; - applyImportedSection(modalInstance, merged); + + const callbacks = modalInstance._hsaeCallbacks || {}; + const persist = typeof callbacks.persistSection === 'function' + ? callbacks.persistSection + : (typeof callbacks.onSave === 'function' ? callbacks.onSave : null); + + if (persist) { + await persist(merged, { quiet: true }); + if (typeof callbacks.remountAfterPersist === 'function') { + callbacks.remountAfterPersist(merged); + } else { + applyImportedSection(modalInstance, merged); + } + } else { + // No persist path (e.g. create flow): update editor only + applyImportedSection(modalInstance, merged); + } showHsaeToast('Defaults restored'); }); } @@ -4787,7 +4815,12 @@ modalInstance._hsaePreviewInitialized = false; const section = context.section || {}; + // Ensure collect/export/troubleshoot always have a stable original base + if (!context.originalSection) { + context = { ...context, originalSection: deepCloneJson(section) }; + } modalInstance._hsaeState = buildEditorStateFromSection(section, context); + modalInstance._hsaeCallbacks = callbacks || {}; const stateHost = modalInstance.dialogContainer || modalInstance.dialogContent; if (stateHost) stateHost._hsaeState = modalInstance._hsaeState; @@ -4808,10 +4841,11 @@ saveBtn.dataset.listenerAttached = 'true'; saveBtn.addEventListener('click', async () => { const dialog = modalInstance.dialogContainer || modalInstance.dialogContent; - const originalSection = context.originalSection || section; + const liveState = modalInstance._hsaeState; + const originalSection = liveState?.context?.originalSection || context.originalSection || section; const sectionData = collectData(dialog, originalSection); if (!sectionData) return; - sectionData.id = section.id || originalSection.id; + sectionData.id = liveState?.section?.id || section.id || originalSection.id; if (typeof updateSectionInConfig === 'function') { updateSectionInConfig(sectionData); } diff --git a/configuration/homeScreenSectionEditor.js b/configuration/homeScreenSectionEditor.js index 014c9c6..07a63bd 100644 --- a/configuration/homeScreenSectionEditor.js +++ b/configuration/homeScreenSectionEditor.js @@ -3299,6 +3299,56 @@ return null; } + function buildAdvancedAttachContext(section, originalSection) { + const buildCtx = resolveAdvancedEditorBuildContext(section); + return { + section, + originalSection: originalSection || JSON.parse(JSON.stringify(section)), + ...buildCtx, + ...(activeEditCtx?.groupContext || {}) + }; + } + + function buildAdvancedPersistCallbacks(modalInstance) { + return { + persistSection: async (sectionData, options = {}) => { + if (typeof activeEditCtx?.onSave !== 'function') { + throw new Error('No save handler available'); + } + await activeEditCtx.onSave(sectionData, options); + }, + remountAfterPersist: (sectionData) => { + remountOpenSectionEditor(modalInstance, sectionData); + } + }; + } + + function remountOpenSectionEditor(modalInstance, sectionData) { + if (!modalInstance?.dialogContent || !window.KefinHomeScreenAdvancedEditor) return; + const section = JSON.parse(JSON.stringify(sectionData || {})); + const originalSection = JSON.parse(JSON.stringify(section)); + if (activeEditCtx) { + activeEditCtx.originalSection = originalSection; + } + + window.KefinHomeScreenAdvancedEditor.destroyAppearancePickrs?.(modalInstance); + modalInstance.dialogContent.innerHTML = buildSectionEditorHTML(section); + + const titleEl = modalInstance.dialogHeader?.querySelector('.dialogTitle, h2'); + if (titleEl) { + // Keep the "Edit Section:" chrome; badge shows the live name + titleEl.textContent = `Edit Section: ${section.name || 'Unnamed'}`; + } + + // Root listeners stay on dialogContent across innerHTML rebuilds — do not reset + // _hsaeRootListenersAttached or they will double-bind. + window.KefinHomeScreenAdvancedEditor.attachListeners( + modalInstance, + buildAdvancedAttachContext(section, originalSection), + buildAdvancedPersistCallbacks(modalInstance) + ); + } + function openSectionEditorModal(section, ctx) { const modalId = SECTION_EDITOR_MODAL_ID; @@ -3308,6 +3358,8 @@ } const originalSection = ctx.originalSection || JSON.parse(JSON.stringify(section)); + if (ctx) ctx.originalSection = originalSection; + if (activeEditCtx) activeEditCtx.originalSection = originalSection; const content = document.createElement('div'); content.innerHTML = buildSectionEditorHTML(section); @@ -3343,33 +3395,22 @@ onOpen: (modalInstance) => { if (modalInstance.dialogContent?.querySelector('.hsae-root') && window.KefinHomeScreenAdvancedEditor) { window.KefinHomeScreenAdvancedEditor.setupModalHeader(modalInstance); - let currentGroupName = activeEditCtx?.groupContext?.currentGroupName || ''; - if (!currentGroupName && section.id) { - const config = getActiveConfig(); - let found = null; - if (config) { - const groupTypes = ['HOME_SECTION_GROUPS', 'SEASONAL_SECTION_GROUPS', 'DISCOVERY_SECTION_GROUPS', 'CUSTOM_SECTION_GROUPS']; - for (const gt of groupTypes) { - found = findSectionInGroupsForEditor(config[gt] || [], section.id); - if (found) break; - } - } - if (found) currentGroupName = found.group.name || ''; - } - if (!currentGroupName && section._targetGroupName) currentGroupName = section._targetGroupName; - const allGroups = getActiveConfig()?.CUSTOM_SECTION_GROUPS || []; - const existingGroupNames = [...new Set(allGroups.map(g => g.name).filter(Boolean))]; - window.KefinHomeScreenAdvancedEditor.attachListeners(modalInstance, { section, ...(activeEditCtx?.groupContext || {}) }); + window.KefinHomeScreenAdvancedEditor.attachListeners( + modalInstance, + buildAdvancedAttachContext(section, originalSection), + buildAdvancedPersistCallbacks(modalInstance) + ); } // Attach event listeners const saveSectionFromEditor = async () => { - const sectionData = collectSectionEditorData(originalSection); + const liveOriginal = activeEditCtx?.originalSection || originalSection; + const sectionData = collectSectionEditorData(liveOriginal); if (!sectionData) { sectionEditorShowToast('Error collecting section data'); return null; } - sectionData.id = section.id; + sectionData.id = sectionData.id || liveOriginal?.id || section.id; if (typeof ctx.onSave === 'function') { await ctx.onSave(sectionData); } @@ -3438,12 +3479,13 @@ const previewBtn = modalInstance.dialogFooter.querySelector('.section-preview-btn'); if (previewBtn && typeof ctx.onPreview === 'function') { previewBtn.addEventListener('click', async () => { - const sectionData = collectSectionEditorData(originalSection); + const liveOriginal = activeEditCtx?.originalSection || originalSection; + const sectionData = collectSectionEditorData(liveOriginal); if (!sectionData) { sectionEditorShowToast('Error collecting section data for preview'); return; } - sectionData.id = sectionData.id || originalSection?.id || section.id; + sectionData.id = sectionData.id || liveOriginal?.id || section.id; await ctx.onPreview(sectionData, ctx.sectionType, previewBtn); }); }