feat: 更新步骤状态渲染逻辑,优化状态处理和界面显示
This commit is contained in:
+23
-10
@@ -2378,7 +2378,7 @@ function renderStepsList() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
initializeManualStepActions();
|
initializeManualStepActions();
|
||||||
updateProgressCounter();
|
renderStepStatuses();
|
||||||
updateButtonStates();
|
updateButtonStates();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2399,10 +2399,11 @@ function syncStepDefinitionsForMode(plusModeEnabled = false, options = {}) {
|
|||||||
|
|
||||||
function applySettingsState(state) {
|
function applySettingsState(state) {
|
||||||
if (typeof syncStepDefinitionsForMode === 'function') {
|
if (typeof syncStepDefinitionsForMode === 'function') {
|
||||||
syncStepDefinitionsForMode(Boolean(state?.plusModeEnabled), { render: true });
|
syncStepDefinitionsForMode(Boolean(state?.plusModeEnabled));
|
||||||
}
|
}
|
||||||
syncLatestState(state);
|
syncLatestState(state);
|
||||||
syncAutoRunState(state);
|
syncAutoRunState(state);
|
||||||
|
renderStepStatuses(latestState);
|
||||||
|
|
||||||
inputEmail.value = state?.email || '';
|
inputEmail.value = state?.email || '';
|
||||||
syncPasswordField(state || {});
|
syncPasswordField(state || {});
|
||||||
@@ -3681,9 +3682,6 @@ function updatePanelModeUI() {
|
|||||||
// ============================================================
|
// ============================================================
|
||||||
|
|
||||||
function updateStepUI(step, status) {
|
function updateStepUI(step, status) {
|
||||||
const statusEl = document.querySelector(`.step-status[data-step="${step}"]`);
|
|
||||||
const row = document.querySelector(`.step-row[data-step="${step}"]`);
|
|
||||||
|
|
||||||
syncLatestState({
|
syncLatestState({
|
||||||
stepStatuses: {
|
stepStatuses: {
|
||||||
...getStepStatuses(),
|
...getStepStatuses(),
|
||||||
@@ -3691,16 +3689,31 @@ function updateStepUI(step, status) {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
if (statusEl) statusEl.textContent = STATUS_ICONS[status] || '';
|
renderSingleStepStatus(step, status);
|
||||||
if (row) {
|
|
||||||
row.className = `step-row ${status}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
updateButtonStates();
|
updateButtonStates();
|
||||||
updateProgressCounter();
|
updateProgressCounter();
|
||||||
updateConfigMenuControls();
|
updateConfigMenuControls();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function renderSingleStepStatus(step, status) {
|
||||||
|
const normalizedStatus = status || 'pending';
|
||||||
|
const statusEl = document.querySelector(`.step-status[data-step="${step}"]`);
|
||||||
|
const row = document.querySelector(`.step-row[data-step="${step}"]`);
|
||||||
|
|
||||||
|
if (statusEl) statusEl.textContent = STATUS_ICONS[normalizedStatus] || '';
|
||||||
|
if (row) {
|
||||||
|
row.className = `step-row ${normalizedStatus}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderStepStatuses(state = latestState) {
|
||||||
|
const statuses = getStepStatuses(state);
|
||||||
|
for (const step of STEP_IDS) {
|
||||||
|
renderSingleStepStatus(step, statuses[step]);
|
||||||
|
}
|
||||||
|
updateProgressCounter();
|
||||||
|
}
|
||||||
|
|
||||||
function updateProgressCounter() {
|
function updateProgressCounter() {
|
||||||
const completed = Object.values(getStepStatuses()).filter(isDoneStatus).length;
|
const completed = Object.values(getStepStatuses()).filter(isDoneStatus).length;
|
||||||
stepsProgress.textContent = `${completed} / ${STEP_IDS.length}`;
|
stepsProgress.textContent = `${completed} / ${STEP_IDS.length}`;
|
||||||
|
|||||||
@@ -118,6 +118,59 @@ test('sidepanel html contains contribution mode runtime UI and loads the module
|
|||||||
assert.ok(moduleIndex < sidepanelIndex);
|
assert.ok(moduleIndex < sidepanelIndex);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('sidepanel settings refresh preserves rendered step progress', () => {
|
||||||
|
const applySettingsStateSource = extractFunction('applySettingsState');
|
||||||
|
assert.doesNotMatch(
|
||||||
|
applySettingsStateSource,
|
||||||
|
/syncStepDefinitionsForMode\(Boolean\(state\?\.plusModeEnabled\),\s*\{\s*render:\s*true\s*\}\)/
|
||||||
|
);
|
||||||
|
assert.match(applySettingsStateSource, /renderStepStatuses\(latestState\)/);
|
||||||
|
|
||||||
|
const bundle = [
|
||||||
|
extractFunction('isDoneStatus'),
|
||||||
|
extractFunction('getStepStatuses'),
|
||||||
|
extractFunction('renderSingleStepStatus'),
|
||||||
|
extractFunction('renderStepStatuses'),
|
||||||
|
extractFunction('updateProgressCounter'),
|
||||||
|
].join('\n');
|
||||||
|
|
||||||
|
const api = new Function(`
|
||||||
|
const STATUS_ICONS = {
|
||||||
|
pending: '',
|
||||||
|
running: '',
|
||||||
|
completed: 'C',
|
||||||
|
failed: 'F',
|
||||||
|
stopped: 'S',
|
||||||
|
manual_completed: 'M',
|
||||||
|
skipped: 'K',
|
||||||
|
};
|
||||||
|
let latestState = { stepStatuses: { 1: 'completed', 2: 'running', 3: 'pending' } };
|
||||||
|
let STEP_IDS = [1, 2, 3];
|
||||||
|
let STEP_DEFAULT_STATUSES = { 1: 'pending', 2: 'pending', 3: 'pending' };
|
||||||
|
const rows = new Map(STEP_IDS.map((step) => [step, { className: 'step-row' }]));
|
||||||
|
const statusEls = new Map(STEP_IDS.map((step) => [step, { textContent: '' }]));
|
||||||
|
const document = {
|
||||||
|
querySelector(selector) {
|
||||||
|
const match = selector.match(/data-step="(\\d+)"/);
|
||||||
|
const step = match ? Number(match[1]) : 0;
|
||||||
|
return selector.includes('step-status') ? statusEls.get(step) : rows.get(step);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const stepsProgress = { textContent: '' };
|
||||||
|
${bundle}
|
||||||
|
return { renderStepStatuses, rows, statusEls, stepsProgress };
|
||||||
|
`)();
|
||||||
|
|
||||||
|
api.renderStepStatuses();
|
||||||
|
|
||||||
|
assert.equal(api.rows.get(1).className, 'step-row completed');
|
||||||
|
assert.equal(api.rows.get(2).className, 'step-row running');
|
||||||
|
assert.equal(api.rows.get(3).className, 'step-row pending');
|
||||||
|
assert.equal(api.statusEls.get(1).textContent, 'C');
|
||||||
|
assert.equal(api.statusEls.get(2).textContent, '');
|
||||||
|
assert.equal(api.stepsProgress.textContent, '1 / 3');
|
||||||
|
});
|
||||||
|
|
||||||
test('collectSettingsPayload omits custom password and local sync settings in contribution mode', () => {
|
test('collectSettingsPayload omits custom password and local sync settings in contribution mode', () => {
|
||||||
const bundle = extractFunction('collectSettingsPayload');
|
const bundle = extractFunction('collectSettingsPayload');
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user