refactor: unify frontend category collection

This commit is contained in:
Dariusz L
2026-08-06 23:43:58 +02:00
parent 57568f1d0f
commit 277268c055
4 changed files with 90 additions and 49 deletions
+28 -1
View File
@@ -24,7 +24,10 @@ import {
toResolverContextModel,
} from '../web/resolver/node_context_menu.js';
import { startSplitterDrag } from '../web/resolver/utils/splitter_drag.js';
import { normalizeDownloadCategoryValue } from '../web/resolver/utils/category_utils.js';
import {
collectNormalizedCategoryValues,
normalizeDownloadCategoryValue,
} from '../web/resolver/utils/category_utils.js';
import {
CATEGORY_ALIASES,
normalizeCategoryToken,
@@ -48,6 +51,7 @@ import {
} from '../web/resolver/custom_nodes/registry.js';
void normalizeDownloadCategoryValue;
void collectNormalizedCategoryValues;
void CATEGORY_ALIASES;
void normalizeCategoryToken;
void normalizeSha256;
@@ -6627,6 +6631,29 @@ test('missing model categories preserve node priority and fallback order', () =>
);
});
test('missing browser folder categories normalize, filter, and deduplicate values', () => {
const getMissingSupportedFolderCategories = eval(
`(${extractMethod(missingBrowserMethodsSource, 'getMissingSupportedFolderCategories')})`
);
const dialog = {
normalizeDownloadCategory(value = '') {
const normalized = String(value || '').trim().toLowerCase();
return normalized.replace(/\s+/g, '_');
},
getMissingSupportedDownloadCategories() {
return [];
},
};
assert.deepEqual(
getMissingSupportedFolderCategories.call(dialog, {
category_hints: ['Checkpoints, loras', 'unknown'],
category: 'vae|loras',
}),
['checkpoints', 'loras', 'vae']
);
});
test('download category normalization maps select safetensors alias to diffusion models', () => {
const normalizeDownloadCategory = eval(`(${extractMethod(downloadTargetMethodsSource, 'normalizeDownloadCategory')})`);
+9 -19
View File
@@ -1,7 +1,10 @@
import { getSvgIcon } from "../../utils/icon_utils.js";
import { getCustomNodeModelCategory } from "../custom_nodes/registry.js";
import { createFloatingTreePicker } from "../utils/tree_picker.js";
import { normalizeDownloadCategoryValue } from "../utils/category_utils.js";
import {
collectNormalizedCategoryValues,
normalizeDownloadCategoryValue,
} from "../utils/category_utils.js";
import { safeStorage } from "../utils/html_utils.js";
import { getSha256Field } from "../utils/hash_utils.js";
import { joinPathPreservingStyle } from "../utils/path_utils.js";
@@ -112,24 +115,11 @@ export const downloadTargetMethods = {
getMissingSupportedDownloadCategories(missing = {}) {
const knownCategories = this.getKnownDownloadCategorySet();
const collectCategories = (...values) => {
const categories = [];
const addCategory = (value) => {
if (value === undefined || value === null || String(value).trim() === '') return;
if (Array.isArray(value)) {
value.forEach(addCategory);
return;
}
String(value).split(/[,|;]/).forEach(part => {
const normalized = this.normalizeDownloadCategory(part);
if (normalized && knownCategories.has(normalized) && !categories.includes(normalized)) {
categories.push(normalized);
}
});
};
values.forEach(addCategory);
return categories;
};
const collectCategories = (...values) => collectNormalizedCategoryValues(
values,
value => this.normalizeDownloadCategory(value),
{ allowedCategories: knownCategories },
);
const chooseSupported = (supported = []) => {
if (!supported.length) return [];
const nodeCategory = this.getMissingNodeTypeDownloadCategory(missing);
+33
View File
@@ -10,3 +10,36 @@ export function normalizeDownloadCategoryValue(
: CATEGORY_ALIASES;
return categoryAliases[token] || token || 'checkpoints';
}
export function collectNormalizedCategoryValues(
values = [],
normalizeCategory,
{ allowedCategories = null, excludedCategories = [] } = {},
) {
const categories = [];
const allowed = allowedCategories instanceof Set ? allowedCategories : null;
const excluded = new Set(excludedCategories);
const addCategory = (value) => {
if (value === undefined || value === null || String(value).trim() === '') return;
if (Array.isArray(value)) {
value.forEach(addCategory);
return;
}
String(value).split(/[,|;]/).forEach(part => {
if (String(part || '').trim() === '') return;
const normalized = normalizeCategory(part);
if (
!normalized
|| excluded.has(normalized)
|| (allowed && !allowed.has(normalized))
|| categories.includes(normalized)
) {
return;
}
categories.push(normalized);
});
};
values.forEach(addCategory);
return categories;
}
+20 -29
View File
@@ -6,6 +6,7 @@ import { safeStorage, normalizePathIdentity } from "../utils/html_utils.js";
import { matchesWorkflowModelReference } from "../node_context_menu.js";
import { classifyLocalMatches } from "../utils/local_match_utils.js";
import { joinPathPreservingStyle } from "../utils/path_utils.js";
import { collectNormalizedCategoryValues } from "../utils/category_utils.js";
const MISSING_ROW_FALLBACK_HEIGHT = 70;
const MISSING_VIRTUAL_INITIAL_ROWS = 24;
@@ -96,36 +97,26 @@ export const missingBrowserMethods = {
},
getMissingSupportedFolderCategories(missing = {}) {
const categories = [];
const addCategory = (value) => {
if (value === undefined || value === null || String(value).trim() === '') return;
if (Array.isArray(value)) {
value.forEach(addCategory);
return;
}
String(value).split(/[,|;]/).forEach(part => {
const normalized = this.normalizeDownloadCategory?.(part) || String(part || '').trim();
if (
normalized
&& normalized !== 'unknown'
&& !categories.includes(normalized)
) {
categories.push(normalized);
}
});
};
const normalizeCategory = value => (
this.normalizeDownloadCategory?.(value) || String(value || '').trim()
);
const options = { excludedCategories: ['unknown'] };
const supported = collectNormalizedCategoryValues(
[this.getMissingSupportedDownloadCategories?.(missing) || []],
normalizeCategory,
options,
);
if (supported.length) return supported;
addCategory(this.getMissingSupportedDownloadCategories?.(missing) || []);
if (!categories.length) {
addCategory(missing.category_hints);
addCategory(missing.categoryHints);
addCategory(missing.model_widget_category_hints);
addCategory(missing.modelWidgetCategoryHints);
addCategory(missing.supported_categories);
addCategory(missing.supportedCategories);
addCategory(missing.category);
}
return categories;
return collectNormalizedCategoryValues([
missing.category_hints,
missing.categoryHints,
missing.model_widget_category_hints,
missing.modelWidgetCategoryHints,
missing.supported_categories,
missing.supportedCategories,
missing.category,
], normalizeCategory, options);
},
getMissingSupportedFolderKeys(missing = {}) {