Unify progress section rendering
This commit is contained in:
@@ -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, '<')
|
||||
.replace(/>/g, '>')
|
||||
.replace(/"/g, '"')
|
||||
.replace(/'/g, ''');
|
||||
}
|
||||
};
|
||||
|
||||
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 <A>/);
|
||||
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 <step>/);
|
||||
assert.match(loaded, /Node <A>/);
|
||||
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)
|
||||
|
||||
@@ -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 = '') {
|
||||
|
||||
Reference in New Issue
Block a user