Preserve unsaved options across docking

This commit is contained in:
Dariusz L
2026-10-05 16:42:44 +02:00
parent d1f308a7e6
commit 500a5af382
6 changed files with 42 additions and 8 deletions
+1 -1
View File
@@ -5,7 +5,7 @@ export const selectionMethods = {
handleOutsideClick(e) {
// Close if click is on the backdrop (not on the dialog itself)
if (e.target === this.backdrop) {
this.close();
this.requestClose();
}
},
+9 -2
View File
@@ -794,9 +794,16 @@ export class ModelResolver {
const button = target?.closest(`.${this.sidebarTabId}-tab-button`);
if (!(button instanceof HTMLElement)) return;
if (!this.dialog?.isVisible()) return;
if (this.dialog.pendingDockToSidebar) return;
const wasDocked = this.dialog.docked;
this.dialog.close({ collapseSidebar: false });
const didClose = this.dialog.requestClose({ collapseSidebar: false });
if (didClose === false) {
event.preventDefault();
event.stopPropagation();
event.stopImmediatePropagation?.();
return;
}
if (!wasDocked) {
event.preventDefault();
@@ -823,7 +830,7 @@ export class ModelResolver {
if (this.dialog.shouldOpenFromSidebarFloating()) {
if (this.dialog.isVisible() && !this.dialog.docked) {
this.dialog.close();
if (this.dialog.requestClose() === false) return;
this.dialog.closeComfySidebar(element);
return;
}
+1 -1
View File
@@ -83,7 +83,7 @@ export const dialogShellMethods = {
className: "mr-window-btn mr-window-btn--close",
innerHTML: getSvgIcon('x', 'currentColor', 'mr-window-btn-icon'),
ariaLabel: "Close Model Resolver",
onclick: () => this.close()
onclick: () => this.requestClose()
})
])
])
+10 -4
View File
@@ -2,16 +2,18 @@ import { app } from "../../../../../scripts/app.js";
import { safeStorage } from "../utils/html_utils.js";
export const lifecycleGraphMethods = {
async show(workflow = null) {
const preserveCurrentView = this.isVisible();
this.undockToFloating({ persist: false });
await this.showContent(workflow, { restoreFullscreen: true });
await this.showContent(workflow, { restoreFullscreen: true, preserveCurrentView });
},
async showDocked(container, workflow = null) {
const preserveCurrentView = this.isVisible();
this.dockTo(container);
await this.showContent(workflow, { restoreFullscreen: false });
await this.showContent(workflow, { restoreFullscreen: false, preserveCurrentView });
},
async showContent(workflow = null, { restoreFullscreen = true } = {}) {
async showContent(workflow = null, { restoreFullscreen = true, preserveCurrentView = false } = {}) {
this.backdrop.style.display = "none";
this.element.style.display = "flex";
void this.loadFooterVersion();
@@ -41,12 +43,16 @@ export const lifecycleGraphMethods = {
// Attach drag handle event listener (only once)
this.attachDragHandleIfNeeded();
this.activeTab = this.restoreActiveTab();
if (!preserveCurrentView) {
this.activeTab = this.restoreActiveTab();
}
this.updateTabButtonStates();
this.updateQueueVisibility();
this.syncWorkflowScopedQueue(workflow || this.getCurrentWorkflow());
await this.restoreActiveDownloadsFromBackend?.();
if (preserveCurrentView) return;
if (this.activeTab === 'missing') {
await this.loadWorkflowData(workflow);
} else if (this.activeTab === 'loaded') {
+14
View File
@@ -4,6 +4,20 @@ import { escapeHtml, pollBackgroundTask, safeStorage } from "../utils/html_utils
const SETTINGS_MAP = [];
export const optionsMethods = {
confirmDiscardOptionsChanges() {
if (this.activeTab !== 'options') return true;
const status = this.contentElement?.querySelector('#mr-options-status');
if (!status?.classList.contains('is-dirty')) return true;
return window.confirm('You have unsaved options. Are you sure you want to leave without saving?');
},
requestClose(...args) {
if (!this.confirmDiscardOptionsChanges()) return false;
return this.close(...args);
},
buildLocalModelContext(item = {}, contextSource = '', extraFields = {}) {
const modelLabel = item.relative_path || item.filename || item.model_path || 'Model';
const modelPath = item.model_path || '';
@@ -37,6 +37,13 @@ export const tabsLoadedMethods = {
switchTab(tab, { force = false } = {}) {
const nextTab = this.getValidTab(tab);
const nextTabButton = this.getTabButton(nextTab);
if (
this.activeTab === 'options'
&& nextTab !== 'options'
&& !this.confirmDiscardOptionsChanges()
) {
return null;
}
if (!force && nextTab === this.activeTab && nextTabButton?.classList.contains('mr-tab-active')) {
this.hideTooltip();
this.updateQueueVisibility();