refactor: 移除共享设置操作相关代码,优化侧边栏布局和样式
This commit is contained in:
@@ -98,7 +98,7 @@ test('flow capability registry exposes Kiro as an independent flow with its own
|
||||
assert.deepEqual(capabilityState.flowCapabilities.contributionAdapterIds, ['kiro-builder-id']);
|
||||
assert.deepEqual(
|
||||
capabilityState.visibleGroupIds,
|
||||
['kiro-runtime-status', 'shared-auto-run', 'shared-settings-actions', 'kiro-target-kiro-rs', 'service-account', 'service-email', 'service-proxy']
|
||||
['kiro-runtime-status', 'shared-auto-run', 'kiro-target-kiro-rs', 'service-account', 'service-email', 'service-proxy']
|
||||
);
|
||||
});
|
||||
|
||||
@@ -128,7 +128,7 @@ test('flow capability registry exposes Grok as an independent SSO flow without O
|
||||
assert.deepEqual(capabilityState.flowCapabilities.contributionAdapterIds, []);
|
||||
assert.deepEqual(
|
||||
capabilityState.visibleGroupIds,
|
||||
['grok-runtime-status', 'shared-auto-run', 'shared-settings-actions', 'grok-target-webchat2api', 'service-account', 'service-email', 'service-proxy']
|
||||
['grok-runtime-status', 'shared-auto-run', 'grok-target-webchat2api', 'service-account', 'service-email', 'service-proxy']
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@@ -46,15 +46,15 @@ test('flow registry exposes canonical flow and target metadata', () => {
|
||||
assert.equal(flowRegistry.normalizeTargetId('grok', 'anything-else'), 'webchat2api');
|
||||
assert.deepEqual(
|
||||
flowRegistry.getVisibleGroupIds('openai', 'cpa'),
|
||||
['openai-plus', 'openai-phone', 'shared-auto-run', 'openai-oauth', 'openai-step6', 'shared-settings-actions', 'openai-target-cpa', 'service-account', 'service-email', 'service-proxy']
|
||||
['openai-plus', 'openai-phone', 'shared-auto-run', 'openai-oauth', 'openai-step6', 'openai-target-cpa', 'service-account', 'service-email', 'service-proxy']
|
||||
);
|
||||
assert.deepEqual(
|
||||
flowRegistry.getVisibleGroupIds('kiro', 'kiro-rs'),
|
||||
['kiro-runtime-status', 'shared-auto-run', 'shared-settings-actions', 'kiro-target-kiro-rs', 'service-account', 'service-email', 'service-proxy']
|
||||
['kiro-runtime-status', 'shared-auto-run', 'kiro-target-kiro-rs', 'service-account', 'service-email', 'service-proxy']
|
||||
);
|
||||
assert.deepEqual(
|
||||
flowRegistry.getVisibleGroupIds('grok', 'webchat2api'),
|
||||
['grok-runtime-status', 'shared-auto-run', 'shared-settings-actions', 'grok-target-webchat2api', 'service-account', 'service-email', 'service-proxy']
|
||||
['grok-runtime-status', 'shared-auto-run', 'grok-target-webchat2api', 'service-account', 'service-email', 'service-proxy']
|
||||
);
|
||||
assert.deepEqual(
|
||||
flowRegistry.getTargetOptions('openai').map((entry) => entry.id),
|
||||
@@ -72,10 +72,6 @@ test('flow registry exposes canonical flow and target metadata', () => {
|
||||
flowRegistry.getSettingsGroupDefinition('shared-auto-run')?.rowIds,
|
||||
['row-shared-auto-run', 'row-auto-run-thread-interval', 'row-step-execution-range']
|
||||
);
|
||||
assert.deepEqual(
|
||||
flowRegistry.getSettingsGroupDefinition('shared-settings-actions')?.rowIds,
|
||||
['row-settings-actions']
|
||||
);
|
||||
assert.equal(flowRegistry.getPublicationTargetDefinition('kiro', 'kiro-rs')?.label, 'kiro.rs');
|
||||
assert.equal(flowRegistry.getFlowCapabilities('openai').supportsAccountContribution, true);
|
||||
assert.equal(flowRegistry.getFlowCapabilities('kiro').supportsAccountContribution, true);
|
||||
|
||||
@@ -367,7 +367,7 @@ function clearTimeout(value) {
|
||||
async function persistSignupPhoneInputForAction() {
|
||||
phonePersistCalls += 1;
|
||||
}
|
||||
function updateSaveButtonState() {}
|
||||
function updateSettingsSaveState() {}
|
||||
function collectSettingsPayload() {
|
||||
return { luckmailApiKey: 'autofilled-key' };
|
||||
}
|
||||
|
||||
@@ -43,7 +43,6 @@ test('sidepanel html exposes flow selector and kiro source fields', () => {
|
||||
'id="row-shared-auto-run"',
|
||||
'id="row-auto-run-thread-interval"',
|
||||
'id="row-oauth-callback"',
|
||||
'id="row-settings-actions"',
|
||||
'id="row-kiro-rs-url"',
|
||||
'id="btn-open-kiro-rs-github"',
|
||||
'id="row-kiro-rs-key"',
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
const test = require('node:test');
|
||||
const assert = require('node:assert/strict');
|
||||
const fs = require('node:fs');
|
||||
|
||||
function lineOf(source, index) {
|
||||
return source.slice(0, index).split(/\r?\n/).length;
|
||||
}
|
||||
|
||||
function readAttr(attrs, name) {
|
||||
return attrs.match(new RegExp(`\\b${name}\\s*=\\s*(["'])(.*?)\\1`, 's'))?.[2] || '';
|
||||
}
|
||||
|
||||
function hasClass(attrs, className) {
|
||||
return readAttr(attrs, 'class').split(/\s+/).includes(className);
|
||||
}
|
||||
|
||||
function collectDataRows(html) {
|
||||
const tagRe = /<\/?([a-zA-Z][\w:-]*)([^>]*)>|<!--[\s\S]*?-->/g;
|
||||
const voidTags = new Set([
|
||||
'area',
|
||||
'base',
|
||||
'br',
|
||||
'col',
|
||||
'embed',
|
||||
'hr',
|
||||
'img',
|
||||
'input',
|
||||
'link',
|
||||
'meta',
|
||||
'param',
|
||||
'source',
|
||||
'track',
|
||||
'wbr',
|
||||
]);
|
||||
const stack = [];
|
||||
const rows = [];
|
||||
|
||||
for (const match of html.matchAll(tagRe)) {
|
||||
const raw = match[0];
|
||||
if (raw.startsWith('<!--')) continue;
|
||||
|
||||
const tag = match[1].toLowerCase();
|
||||
const attrs = match[2] || '';
|
||||
if (raw.startsWith('</')) {
|
||||
while (stack.length) {
|
||||
const node = stack.pop();
|
||||
if (node.tag === tag) {
|
||||
if (node.isDataRow) rows.push(node);
|
||||
break;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
const parent = stack[stack.length - 1];
|
||||
if (parent) {
|
||||
parent.children.push({
|
||||
tag,
|
||||
id: readAttr(attrs, 'id'),
|
||||
className: readAttr(attrs, 'class'),
|
||||
});
|
||||
}
|
||||
|
||||
if (!raw.endsWith('/>') && !voidTags.has(tag)) {
|
||||
stack.push({
|
||||
tag,
|
||||
attrs,
|
||||
line: lineOf(html, match.index),
|
||||
id: readAttr(attrs, 'id'),
|
||||
className: readAttr(attrs, 'class'),
|
||||
children: [],
|
||||
isDataRow: hasClass(attrs, 'data-row'),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return rows;
|
||||
}
|
||||
|
||||
function readCssRuleBlock(css, selector) {
|
||||
const start = css.indexOf(`${selector} {`);
|
||||
assert.notEqual(start, -1, `missing CSS selector: ${selector}`);
|
||||
|
||||
const blockStart = css.indexOf('{', start);
|
||||
const blockEnd = css.indexOf('}', blockStart);
|
||||
assert.notEqual(blockEnd, -1, `missing CSS block end: ${selector}`);
|
||||
return css.slice(blockStart + 1, blockEnd);
|
||||
}
|
||||
|
||||
test('sidepanel data rows use a single control area after the label', () => {
|
||||
const html = fs.readFileSync('sidepanel/sidepanel.html', 'utf8');
|
||||
const rows = collectDataRows(html);
|
||||
const offenders = rows.filter((row) => row.children.length > 2);
|
||||
|
||||
assert.ok(rows.length > 0);
|
||||
assert.deepEqual(
|
||||
offenders.map((row) => ({
|
||||
line: row.line,
|
||||
id: row.id,
|
||||
className: row.className,
|
||||
children: row.children,
|
||||
})),
|
||||
[]
|
||||
);
|
||||
});
|
||||
|
||||
test('sidepanel form controls share one width system', () => {
|
||||
const css = fs.readFileSync('sidepanel/sidepanel.css', 'utf8');
|
||||
const dataLabelBlock = readCssRuleBlock(css, '.data-label');
|
||||
|
||||
assert.match(css, /--data-label-width:\s*76px;/);
|
||||
assert.match(css, /\.data-label\s*\{[\s\S]*flex:\s*0 0 var\(--data-label-width\);/);
|
||||
assert.match(css, /\.data-inline\s*\{[\s\S]*flex:\s*1 1 0;/);
|
||||
assert.match(css, /\.data-inline > \.data-input,[\s\S]*\.data-inline > \.input-with-icon\s*\{[\s\S]*flex:\s*1 1 0;/);
|
||||
assert.match(css, /\.data-inline-btn\s*\{[\s\S]*min-width:\s*var\(--data-inline-action-min-width\);/);
|
||||
assert.doesNotMatch(dataLabelBlock, /width:\s*56px;/);
|
||||
});
|
||||
@@ -51,7 +51,6 @@ test('sidepanel splits shared auto-run controls from openai oauth controls', ()
|
||||
const stepRangeIndex = html.indexOf('id="row-step-execution-range"');
|
||||
const oauthDisplayIndex = html.indexOf('id="row-oauth-display"');
|
||||
const oauthCallbackIndex = html.indexOf('id="row-oauth-callback"');
|
||||
const settingsActionsIndex = html.indexOf('id="row-settings-actions"');
|
||||
|
||||
assert.notEqual(step6CookieIndex, -1);
|
||||
assert.notEqual(sharedAutoRunIndex, -1);
|
||||
@@ -61,13 +60,11 @@ test('sidepanel splits shared auto-run controls from openai oauth controls', ()
|
||||
assert.notEqual(stepRangeIndex, -1);
|
||||
assert.notEqual(oauthDisplayIndex, -1);
|
||||
assert.notEqual(oauthCallbackIndex, -1);
|
||||
assert.notEqual(settingsActionsIndex, -1);
|
||||
assert.ok(sharedAutoRunIndex > step6CookieIndex, 'shared auto-run should render below the openai step6 cookie row');
|
||||
assert.ok(threadIntervalIndex > sharedAutoRunIndex, 'thread interval should be part of the shared auto-run block');
|
||||
assert.ok(stepRangeIndex > threadIntervalIndex, 'step execution range should render below shared thread interval');
|
||||
assert.ok(stepRangeIndex < oauthDisplayIndex, 'step execution range should stay above oauth runtime display');
|
||||
assert.ok(oauthCallbackIndex > oauthDisplayIndex, 'openai callback row should follow the oauth display');
|
||||
assert.ok(settingsActionsIndex > oauthCallbackIndex, 'save settings action should live outside the callback row');
|
||||
});
|
||||
|
||||
test('sidepanel operation delay state is always normalized back to enabled', () => {
|
||||
|
||||
@@ -91,7 +91,7 @@ function markSettingsDirty(value = true) {
|
||||
function applySettingsState() {
|
||||
applyCalls += 1;
|
||||
}
|
||||
function updateSaveButtonState() {}
|
||||
function updateSettingsSaveState() {}
|
||||
function updatePanelModeUI() {}
|
||||
function updateMailProviderUI() {}
|
||||
function updateButtonStates() {}
|
||||
|
||||
Reference in New Issue
Block a user