Unify progress section rendering

This commit is contained in:
Dariusz L
2026-08-06 21:22:16 +02:00
parent 335f886a4e
commit b809cf8953
2 changed files with 80 additions and 20 deletions
@@ -124,6 +124,61 @@ const resolverShellCssSource = fs.readFileSync(
'utf8'
);
test('progress renderers preserve their distinct percent and escaping contracts', () => {
const renderProgressBar = eval(`(${extractMethod(renderFormatMethodsSource, 'renderProgressBar')})`);
const getStatusBadge = eval(`(${extractMethod(renderFormatMethodsSource, 'getStatusBadge')})`);
const renderProgressSection = eval(`(${extractMethod(renderFormatMethodsSource, 'renderProgressSection')})`);
const renderAnalysisProgress = eval(`(${extractMethod(renderFormatMethodsSource, 'renderAnalysisProgress')})`);
const renderLoadedModelsProgress = eval(`(${extractMethod(renderFormatMethodsSource, 'renderLoadedModelsProgress')})`);
const dialog = {
renderProgressBar,
getStatusBadge,
renderProgressSection,
escapeHtml(value) {
return String(value)
.replace(/&/g, '&')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;')
.replace(/'/g, '&#39;');
}
};
const analysis = renderAnalysisProgress.call(dialog, {
current: 1,
total: 4,
message: 'Analyzing <step>',
model_name: 'Model <A>'
});
assert.match(analysis, /Analyzing <step>/);
assert.match(analysis, /Model &lt;A&gt;/);
assert.match(analysis, /1 \/ 4/);
assert.match(analysis, /width: 25%/);
const loaded = renderLoadedModelsProgress.call(dialog, {
current: 1,
total: 4,
percent: 73.4,
message: 'Loading <step>',
node_type: 'Node <A>'
});
assert.match(loaded, /Loading &lt;step&gt;/);
assert.match(loaded, /Node &lt;A&gt;/);
assert.match(loaded, /1 \/ 4/);
assert.match(loaded, /width: 73%/);
const shared = renderProgressSection.call(dialog, {
statusLabel: 'Shared',
messageHtml: 'Shared message',
progressHtml: '<div class="shared-progress"></div>',
detailHtml: '<div class="shared-detail"></div>'
});
assert.match(shared, /mr-badge-info">Shared/);
assert.match(shared, /Shared message/);
assert.match(shared, /shared-progress/);
assert.match(shared, /shared-detail/);
});
test('Missing Models rows use fixed-size virtualization for smooth stable scrolling', () => {
const rowRules = Array.from(
resolverMainCssSource.matchAll(/#model-resolver-modal \.mr-missing-list-row\s*\{([^}]+)\}/g)
+25 -20
View File
@@ -171,6 +171,19 @@ export const renderFormatMethods = {
`;
},
renderProgressSection({ statusLabel, messageHtml = '', progressHtml = '', detailHtml = '' } = {}) {
return `
<div class="mr-download-section">
<div class="mr-status-inline">
${this.getStatusBadge(statusLabel, 'info')}
<span class="mr-download-info">${messageHtml}</span>
</div>
${progressHtml}
${detailHtml}
</div>
`;
},
renderAnalysisProgress(progress = {}) {
const current = Number(progress.current) || 0;
const total = Number(progress.total) || 0;
@@ -179,16 +192,12 @@ export const renderFormatMethods = {
const modelName = progress.model_name ? this.escapeHtml(String(progress.model_name)) : '';
const detail = total > 0 ? `${current} / ${total}` : 'Preparing...';
return `
<div class="mr-download-section">
<div class="mr-status-inline">
${this.getStatusBadge('Analyzing', 'info')}
<span class="mr-download-info">${message}</span>
</div>
${this.renderProgressBar(percent, detail, `${percent}%`)}
${modelName ? `<div class="mr-download-info">${modelName}</div>` : ''}
</div>
`;
return this.renderProgressSection({
statusLabel: 'Analyzing',
messageHtml: message,
progressHtml: this.renderProgressBar(percent, detail, `${percent}%`),
detailHtml: modelName ? `<div class="mr-download-info">${modelName}</div>` : '',
});
},
renderLoadedModelsProgress(progress = {}) {
@@ -202,16 +211,12 @@ export const renderFormatMethods = {
const detail = total > 0 ? `${current} / ${total}` : 'Preparing...';
const nodeType = progress.node_type ? this.escapeHtml(String(progress.node_type)) : '';
return `
<div class="mr-download-section">
<div class="mr-status-inline">
${this.getStatusBadge('Loading', 'info')}
<span class="mr-download-info">${this.escapeHtml(message)}</span>
</div>
${this.renderProgressBar(percent, detail, `${percent}%`)}
${nodeType ? `<div class="mr-download-info">${nodeType}</div>` : ''}
</div>
`;
return this.renderProgressSection({
statusLabel: 'Loading',
messageHtml: this.escapeHtml(message),
progressHtml: this.renderProgressBar(percent, detail, `${percent}%`),
detailHtml: nodeType ? `<div class="mr-download-info">${nodeType}</div>` : '',
});
},
patchLoadedModelsProgress(container, renderedHtml = '') {