Add auto_open_on_missing setting to control resolver auto-launch
This commit is contained in:
@@ -30,6 +30,7 @@ SETTINGS_SCHEMA: List[Dict[str, Any]] = [
|
||||
{ "serverKey": "auto_fill_base_model", "localKey": "ModelResolver.autoFillBaseModel", "type": "boolean", "default": True },
|
||||
{ "serverKey": "auto_fill_subfolder", "localKey": "ModelResolver.autoFillSubfolder", "type": "boolean", "default": True },
|
||||
{ "serverKey": "auto_refresh_comfy_models_after_apply", "localKey": "ModelResolver.autoRefreshComfyModelsAfterApply", "type": "boolean", "default": True },
|
||||
{ "serverKey": "auto_open_on_missing", "localKey": "ModelResolver.autoOpenOnMissing", "type": "boolean", "default": False },
|
||||
{ "serverKey": "workflow_hash_metadata_enabled", "localKey": "ModelResolver.workflowHashMetadataEnabled", "type": "boolean", "default": True },
|
||||
{ "serverKey": "workflow_dependency_marker_enabled", "localKey": "ModelResolver.workflowDependencyMarkerEnabled", "type": "boolean", "default": False },
|
||||
{ "serverKey": "download_backend", "localKey": "ModelResolver.downloadBackend", "type": "backend", "default": "python" },
|
||||
@@ -192,6 +193,9 @@ def normalize_settings(settings: Optional[Mapping[str, Any]]) -> Dict[str, Any]:
|
||||
data["auto_refresh_comfy_models_after_apply"] = bool_setting(
|
||||
data.get("auto_refresh_comfy_models_after_apply"), True
|
||||
)
|
||||
data["auto_open_on_missing"] = bool_setting(
|
||||
data.get("auto_open_on_missing"), False
|
||||
)
|
||||
data["download_path_mode"] = normalize_download_path_mode(
|
||||
data.get("download_path_mode"), data.get("auto_fill_subfolder")
|
||||
)
|
||||
|
||||
@@ -9,6 +9,14 @@ const queueMethodsSource = fs.readFileSync(
|
||||
path.join(projectRoot, 'web/resolver/actions/queue_methods.js'),
|
||||
'utf8'
|
||||
);
|
||||
const modelResolverSource = fs.readFileSync(
|
||||
path.join(projectRoot, 'web/resolver/model_resolver.js'),
|
||||
'utf8'
|
||||
);
|
||||
const optionsMethodsSource = fs.readFileSync(
|
||||
path.join(projectRoot, 'web/resolver/views/options_methods.js'),
|
||||
'utf8'
|
||||
);
|
||||
const resolveDownloadMethodsSource = fs.readFileSync(
|
||||
path.join(projectRoot, 'web/resolver/actions/resolve_download_methods.js'),
|
||||
'utf8'
|
||||
@@ -662,6 +670,41 @@ test('active download refresh preserves existing cards for hover and tooltip sta
|
||||
assert.match(queueMethodsSource, /patchDownloadsPanelElement\(currentElement, nextElement\)/);
|
||||
});
|
||||
|
||||
test('automatic opening for missing models is disabled by default', () => {
|
||||
const isAutoOpenEnabled = eval(`(${extractMethod(modelResolverSource, 'isAutoOpenEnabled')})`);
|
||||
const previousLocalStorageDescriptor = Object.getOwnPropertyDescriptor(globalThis, 'localStorage');
|
||||
const setStoredValue = value => {
|
||||
Object.defineProperty(globalThis, 'localStorage', {
|
||||
configurable: true,
|
||||
value: { getItem: () => value },
|
||||
});
|
||||
};
|
||||
|
||||
try {
|
||||
setStoredValue(null);
|
||||
assert.equal(isAutoOpenEnabled(), false);
|
||||
|
||||
setStoredValue('false');
|
||||
assert.equal(isAutoOpenEnabled(), false);
|
||||
|
||||
setStoredValue('true');
|
||||
assert.equal(isAutoOpenEnabled(), true);
|
||||
} finally {
|
||||
if (previousLocalStorageDescriptor) {
|
||||
Object.defineProperty(globalThis, 'localStorage', previousLocalStorageDescriptor);
|
||||
} else delete globalThis.localStorage;
|
||||
}
|
||||
});
|
||||
|
||||
test('automatic opening remains conditional on unresolved models', () => {
|
||||
assert.match(
|
||||
modelResolverSource,
|
||||
/if \(data\.total_missing > 0\) \{[\s\S]*?this\.openResolverManager\(\);/
|
||||
);
|
||||
assert.match(optionsMethodsSource, /id="mr-options-auto-open-on-missing"/);
|
||||
assert.match(optionsMethodsSource, /auto_open_on_missing: Boolean\(autoOpenOnMissingInput\?\.checked\)/);
|
||||
});
|
||||
|
||||
test('active workflow label prefers selected ComfyUI workflow tab name over route hash', () => {
|
||||
const cleanWorkflowLabel = eval(`(${extractMethod(queueMethodsSource, 'cleanWorkflowLabel')})`);
|
||||
const getWorkflowLabelFromActiveTabElement = eval(`(${extractMethod(queueMethodsSource, 'getWorkflowLabelFromActiveTabElement')})`);
|
||||
|
||||
@@ -24,6 +24,14 @@ class SettingsTests(unittest.TestCase):
|
||||
]
|
||||
)
|
||||
|
||||
def test_auto_open_on_missing_defaults_to_disabled(self):
|
||||
self.assertFalse(normalize_settings({})["auto_open_on_missing"])
|
||||
self.assertTrue(
|
||||
normalize_settings({"auto_open_on_missing": "true"})[
|
||||
"auto_open_on_missing"
|
||||
]
|
||||
)
|
||||
|
||||
def test_sanitize_folder_name(self):
|
||||
self.assertEqual(sanitize_folder_name("valid_name"), "valid_name")
|
||||
self.assertEqual(sanitize_folder_name("name/with\\slashes"), "name_with_slashes")
|
||||
|
||||
@@ -1066,7 +1066,7 @@ export class ModelResolver {
|
||||
* Check if auto-open preference is enabled
|
||||
*/
|
||||
isAutoOpenEnabled() {
|
||||
return localStorage.getItem('ModelResolver.autoOpenOnMissing') !== 'false';
|
||||
return localStorage.getItem('ModelResolver.autoOpenOnMissing') === 'true';
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -409,6 +409,15 @@ export const optionsMethods = {
|
||||
<span class="mr-options-switch"></span>
|
||||
</span>
|
||||
</label>
|
||||
<label class="mr-options-toggle-row">
|
||||
<div class="mr-options-toggle-copy">
|
||||
<span class="mr-options-toggle-title">Open when a workflow has missing models <span class="mr-tooltip-badge" data-tooltip="When enabled, loading a workflow opens Model Resolver only after analysis detects unresolved models. This option is disabled by default.">?</span></span>
|
||||
</div>
|
||||
<span class="mr-options-toggle-control">
|
||||
<input id="mr-options-auto-open-on-missing" class="mr-options-switch-input" type="checkbox" ${tokens.auto_open_on_missing ? 'checked' : ''}>
|
||||
<span class="mr-options-switch"></span>
|
||||
</span>
|
||||
</label>
|
||||
<label class="mr-options-toggle-row">
|
||||
<div class="mr-options-toggle-copy">
|
||||
<span class="mr-options-toggle-title">Embed workflow hashes <span class="mr-tooltip-badge" data-tooltip="Adds SHA256 metadata for models used in saved workflows and image workflow JSON, so renamed files can be resolved by hash later.">?</span></span>
|
||||
@@ -900,6 +909,7 @@ export const optionsMethods = {
|
||||
const autoFillBaseModelInput = this.contentElement.querySelector('#mr-options-auto-fill-base-model');
|
||||
const autoFillSubfolderInput = this.contentElement.querySelector('#mr-options-auto-fill-subfolder');
|
||||
const autoRefreshComfyModelsInput = this.contentElement.querySelector('#mr-options-auto-refresh-comfy-models');
|
||||
const autoOpenOnMissingInput = this.contentElement.querySelector('#mr-options-auto-open-on-missing');
|
||||
const workflowHashMetadataInput = this.contentElement.querySelector('#mr-options-workflow-hash-metadata');
|
||||
const workflowDependencyMarkerInput = this.contentElement.querySelector('#mr-options-workflow-dependency-marker');
|
||||
const addDependencyNodeBtn = this.contentElement.querySelector('#mr-options-add-dependency-node');
|
||||
@@ -1027,6 +1037,7 @@ export const optionsMethods = {
|
||||
autoFillBaseModelInput,
|
||||
autoFillSubfolderInput,
|
||||
autoRefreshComfyModelsInput,
|
||||
autoOpenOnMissingInput,
|
||||
workflowHashMetadataInput,
|
||||
workflowDependencyMarkerInput,
|
||||
downloadBackendInput,
|
||||
@@ -3425,6 +3436,7 @@ export const optionsMethods = {
|
||||
auto_fill_base_model: Boolean(autoFillBaseModelInput?.checked),
|
||||
auto_fill_subfolder: Boolean(autoFillSubfolderInput?.checked),
|
||||
auto_refresh_comfy_models_after_apply: Boolean(autoRefreshComfyModelsInput?.checked),
|
||||
auto_open_on_missing: Boolean(autoOpenOnMissingInput?.checked),
|
||||
workflow_hash_metadata_enabled: Boolean(workflowHashMetadataInput?.checked),
|
||||
workflow_dependency_marker_enabled: Boolean(workflowDependencyMarkerInput?.checked),
|
||||
download_backend: downloadBackend,
|
||||
|
||||
Reference in New Issue
Block a user