refactor missing model filter bindings
This commit is contained in:
@@ -2416,6 +2416,96 @@ test('workflow analysis and loaded model caches stay independent and cloned', ()
|
||||
assert.equal(dialog.workflowAnalysisCaches.get(dialog.workflowKey).data.missing_models.length, 1);
|
||||
});
|
||||
|
||||
test('Missing Models filter toggles persist state and rerender once per change', () => {
|
||||
const bindMissingFilterToggle = eval(
|
||||
`(${extractMethod(missingBrowserMethodsSource, 'bindMissingFilterToggle')})`
|
||||
);
|
||||
const wireMissingModelsBrowser = eval(
|
||||
`(${extractMethod(missingBrowserMethodsSource, 'wireMissingModelsBrowser')})`
|
||||
);
|
||||
const window = new Window();
|
||||
const previousDocument = globalThis.document;
|
||||
const previousElement = globalThis.Element;
|
||||
const previousHTMLElement = globalThis.HTMLElement;
|
||||
const previousLocalStorage = globalThis.localStorage;
|
||||
const localStorageValues = new Map();
|
||||
const container = window.document.createElement('div');
|
||||
container.innerHTML = `
|
||||
<div class="mr-missing-browser">
|
||||
<input id="mr-show-resolved-models" type="checkbox">
|
||||
<input id="mr-show-auto-download-models" type="checkbox">
|
||||
<input id="mr-show-inactive-models" type="checkbox">
|
||||
</div>
|
||||
`;
|
||||
const renderOptions = [];
|
||||
const dialog = {
|
||||
showResolvedModels: false,
|
||||
showAutoDownloadModels: true,
|
||||
showInactiveModels: false,
|
||||
showResolvedModelsStorageKey: 'test_show_resolved_models',
|
||||
showAutoDownloadModelsStorageKey: 'test_show_auto_download_models',
|
||||
showInactiveModelsStorageKey: 'test_show_inactive_models',
|
||||
missingModelsTypeFilterMenuOpen: false,
|
||||
bindMissingFilterToggle,
|
||||
wireMissingBrowserSplitter() {},
|
||||
wireVisibleMissingModelRows() {},
|
||||
setupMissingModelsVirtualizer() {},
|
||||
displayMissingModels(_container, _data, options) {
|
||||
renderOptions.push(options);
|
||||
},
|
||||
};
|
||||
|
||||
globalThis.document = window.document;
|
||||
globalThis.Element = window.Element;
|
||||
globalThis.HTMLElement = window.HTMLElement;
|
||||
globalThis.localStorage = {
|
||||
getItem(key) {
|
||||
return localStorageValues.has(key) ? localStorageValues.get(key) : null;
|
||||
},
|
||||
setItem(key, value) {
|
||||
localStorageValues.set(key, String(value));
|
||||
},
|
||||
removeItem(key) {
|
||||
localStorageValues.delete(key);
|
||||
},
|
||||
};
|
||||
|
||||
try {
|
||||
wireMissingModelsBrowser.call(dialog, container, {}, []);
|
||||
wireMissingModelsBrowser.call(dialog, container, {}, []);
|
||||
|
||||
const resolvedToggle = container.querySelector('#mr-show-resolved-models');
|
||||
const autoDownloadToggle = container.querySelector('#mr-show-auto-download-models');
|
||||
const inactiveToggle = container.querySelector('#mr-show-inactive-models');
|
||||
resolvedToggle.checked = true;
|
||||
autoDownloadToggle.checked = false;
|
||||
inactiveToggle.checked = true;
|
||||
resolvedToggle.dispatchEvent(new window.Event('change'));
|
||||
autoDownloadToggle.dispatchEvent(new window.Event('change'));
|
||||
inactiveToggle.dispatchEvent(new window.Event('change'));
|
||||
|
||||
assert.equal(dialog.showResolvedModels, true);
|
||||
assert.equal(dialog.showAutoDownloadModels, false);
|
||||
assert.equal(dialog.showInactiveModels, true);
|
||||
assert.equal(safeStorage.getItem(dialog.showResolvedModelsStorageKey), '1');
|
||||
assert.equal(safeStorage.getItem(dialog.showAutoDownloadModelsStorageKey), '0');
|
||||
assert.equal(safeStorage.getItem(dialog.showInactiveModelsStorageKey), '1');
|
||||
assert.deepEqual(renderOptions, [
|
||||
{ preserveBrowser: true },
|
||||
{ preserveBrowser: true },
|
||||
{ preserveBrowser: true },
|
||||
]);
|
||||
} finally {
|
||||
safeStorage.removeItem(dialog.showResolvedModelsStorageKey);
|
||||
safeStorage.removeItem(dialog.showAutoDownloadModelsStorageKey);
|
||||
safeStorage.removeItem(dialog.showInactiveModelsStorageKey);
|
||||
globalThis.document = previousDocument;
|
||||
globalThis.Element = previousElement;
|
||||
globalThis.HTMLElement = previousHTMLElement;
|
||||
globalThis.localStorage = previousLocalStorage;
|
||||
}
|
||||
});
|
||||
|
||||
test('node widget changes request a content-preserving Missing Models refresh', async () => {
|
||||
const log = { debug() {} };
|
||||
const refreshForActiveWorkflowChange = eval(
|
||||
|
||||
@@ -1083,6 +1083,19 @@ export const missingBrowserMethods = {
|
||||
});
|
||||
},
|
||||
|
||||
bindMissingFilterToggle(toggle, { boundKey, storageKey, setValue, container, data }) {
|
||||
if (!toggle || toggle.dataset[boundKey] === 'true') return;
|
||||
toggle.dataset[boundKey] = 'true';
|
||||
toggle.addEventListener('change', () => {
|
||||
const value = Boolean(toggle.checked);
|
||||
setValue(value);
|
||||
try {
|
||||
safeStorage.setItem(storageKey, value ? '1' : '0');
|
||||
} catch (_e) {}
|
||||
this.displayMissingModels(container, data, { preserveBrowser: true });
|
||||
});
|
||||
},
|
||||
|
||||
wireMissingModelsBrowser(container, data, sortedMissingModels) {
|
||||
this.wireMissingBrowserSplitter(container);
|
||||
|
||||
@@ -1161,40 +1174,31 @@ export const missingBrowserMethods = {
|
||||
}
|
||||
|
||||
const showResolvedToggle = container.querySelector('#mr-show-resolved-models');
|
||||
if (showResolvedToggle && showResolvedToggle.dataset.mlResolvedBound !== 'true') {
|
||||
showResolvedToggle.dataset.mlResolvedBound = 'true';
|
||||
showResolvedToggle.addEventListener('change', () => {
|
||||
this.showResolvedModels = Boolean(showResolvedToggle.checked);
|
||||
try {
|
||||
safeStorage.setItem(this.showResolvedModelsStorageKey, this.showResolvedModels ? '1' : '0');
|
||||
} catch (_e) {}
|
||||
this.displayMissingModels(container, data, { preserveBrowser: true });
|
||||
});
|
||||
}
|
||||
this.bindMissingFilterToggle(showResolvedToggle, {
|
||||
boundKey: 'mlResolvedBound',
|
||||
storageKey: this.showResolvedModelsStorageKey,
|
||||
setValue: value => { this.showResolvedModels = value; },
|
||||
container,
|
||||
data,
|
||||
});
|
||||
|
||||
const showAutoDownloadToggle = container.querySelector('#mr-show-auto-download-models');
|
||||
if (showAutoDownloadToggle && showAutoDownloadToggle.dataset.mlAutoDownloadBound !== 'true') {
|
||||
showAutoDownloadToggle.dataset.mlAutoDownloadBound = 'true';
|
||||
showAutoDownloadToggle.addEventListener('change', () => {
|
||||
this.showAutoDownloadModels = Boolean(showAutoDownloadToggle.checked);
|
||||
try {
|
||||
safeStorage.setItem(this.showAutoDownloadModelsStorageKey, this.showAutoDownloadModels ? '1' : '0');
|
||||
} catch (_e) {}
|
||||
this.displayMissingModels(container, data, { preserveBrowser: true });
|
||||
});
|
||||
}
|
||||
this.bindMissingFilterToggle(showAutoDownloadToggle, {
|
||||
boundKey: 'mlAutoDownloadBound',
|
||||
storageKey: this.showAutoDownloadModelsStorageKey,
|
||||
setValue: value => { this.showAutoDownloadModels = value; },
|
||||
container,
|
||||
data,
|
||||
});
|
||||
|
||||
const showInactiveToggle = container.querySelector('#mr-show-inactive-models');
|
||||
if (showInactiveToggle && showInactiveToggle.dataset.mlInactiveBound !== 'true') {
|
||||
showInactiveToggle.dataset.mlInactiveBound = 'true';
|
||||
showInactiveToggle.addEventListener('change', () => {
|
||||
this.showInactiveModels = Boolean(showInactiveToggle.checked);
|
||||
try {
|
||||
safeStorage.setItem(this.showInactiveModelsStorageKey, this.showInactiveModels ? '1' : '0');
|
||||
} catch (_e) {}
|
||||
this.displayMissingModels(container, data, { preserveBrowser: true });
|
||||
});
|
||||
}
|
||||
this.bindMissingFilterToggle(showInactiveToggle, {
|
||||
boundKey: 'mlInactiveBound',
|
||||
storageKey: this.showInactiveModelsStorageKey,
|
||||
setValue: value => { this.showInactiveModels = value; },
|
||||
container,
|
||||
data,
|
||||
});
|
||||
|
||||
const getCurrentMissingModels = () => (
|
||||
Array.isArray(this.missingModels)
|
||||
|
||||
Reference in New Issue
Block a user