From e7fd4203c4533cd86791b0077c808f504322f5de Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 4 Nov 2025 15:23:25 +0100 Subject: [PATCH] Improve Model Linker UI: prevent text line-breaking and add resolve button for highest confidence matches --- web/linker.js | 47 ++++++++++++++++++++++++++++++++++++----------- 1 file changed, 36 insertions(+), 11 deletions(-) diff --git a/web/linker.js b/web/linker.js index da87065..a2207c0 100644 --- a/web/linker.js +++ b/web/linker.js @@ -253,6 +253,7 @@ class LinkerManagerDialog extends ComfyDialog { container.innerHTML = html; // Attach event listeners for resolve buttons (use sorted order) + // Note: We need to match the exact same logic as renderMissingModel to find which buttons were rendered sortedMissingModels.forEach((missing, missingIndex) => { const allMatches = missing.matches || []; @@ -261,15 +262,33 @@ class LinkerManagerDialog extends ComfyDialog { // Filter to only 100% matches if available, otherwise use filtered matches (>=70%) const perfectMatches = filteredMatches.filter(m => m.confidence === 100); - const matchesToUse = perfectMatches.length > 0 ? perfectMatches : filteredMatches; + const otherMatches = filteredMatches.filter(m => m.confidence < 100 && m.confidence >= 70); - matchesToUse.forEach((match, matchIndex) => { - const buttonId = `resolve-${missing.node_id}-${missing.widget_index}-${matchIndex}`; - const resolveButton = container.querySelector(`#${buttonId}`); - if (resolveButton) { - resolveButton.addEventListener('click', () => { - this.resolveModel(missing, match.model); - }); + // Match the same logic as renderMissingModel + const matchesToShow = perfectMatches.length > 0 + ? perfectMatches + : otherMatches.sort((a, b) => b.confidence - a.confidence).slice(0, 5); + + // Sort: 100% matches first, then by confidence descending (same as renderMissingModel) + const sortedMatches = matchesToShow.sort((a, b) => { + if (a.confidence === 100 && b.confidence !== 100) return -1; + if (a.confidence !== 100 && b.confidence === 100) return 1; + return b.confidence - a.confidence; + }); + + // Find the highest confidence match (even if not 100%) + const highestConfidenceMatch = sortedMatches.length > 0 ? sortedMatches[0] : null; + + sortedMatches.forEach((match, matchIndex) => { + // Only attach listener if this match would have a button (100% or highest confidence) + if (match.confidence === 100 || match === highestConfidenceMatch) { + const buttonId = `resolve-${missing.node_id}-${missing.widget_index}-${matchIndex}`; + const resolveButton = container.querySelector(`#${buttonId}`); + if (resolveButton) { + resolveButton.addEventListener('click', () => { + this.resolveModel(missing, match.model); + }); + } } }); }); @@ -327,6 +346,9 @@ class LinkerManagerDialog extends ComfyDialog { return b.confidence - a.confidence; }); + // Find the highest confidence match (even if not 100%) + const highestConfidenceMatch = sortedMatches.length > 0 ? sortedMatches[0] : null; + for (let matchIndex = 0; matchIndex < sortedMatches.length; matchIndex++) { const match = sortedMatches[matchIndex]; const buttonId = `resolve-${missing.node_id}-${missing.widget_index}-${matchIndex}`; @@ -335,7 +357,8 @@ class LinkerManagerDialog extends ComfyDialog { html += ` (${match.confidence}% confidence) `; - if (match.confidence === 100) { + // Show resolve button for 100% matches OR for the highest confidence match (even if not 100%) + if (match.confidence === 100 || match === highestConfidenceMatch) { html += `