refactor: 移除共享设置操作相关代码,优化侧边栏布局和样式
This commit is contained in:
@@ -57,11 +57,6 @@
|
|||||||
'row-step-execution-range',
|
'row-step-execution-range',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
'shared-settings-actions': {
|
|
||||||
id: 'shared-settings-actions',
|
|
||||||
label: '\u8bbe\u7f6e\u64cd\u4f5c',
|
|
||||||
rowIds: ['row-settings-actions'],
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
function buildFlowDefinitions() {
|
function buildFlowDefinitions() {
|
||||||
|
|||||||
+1
-1
@@ -34,7 +34,7 @@
|
|||||||
stepDefinitionMode: 'grok',
|
stepDefinitionMode: 'grok',
|
||||||
targetSelectorLabel: '来源',
|
targetSelectorLabel: '来源',
|
||||||
},
|
},
|
||||||
baseGroups: ['grok-runtime-status', 'shared-auto-run', 'shared-settings-actions'],
|
baseGroups: ['grok-runtime-status', 'shared-auto-run'],
|
||||||
targets: {
|
targets: {
|
||||||
webchat2api: {
|
webchat2api: {
|
||||||
id: 'webchat2api',
|
id: 'webchat2api',
|
||||||
|
|||||||
+1
-2
@@ -40,8 +40,7 @@
|
|||||||
},
|
},
|
||||||
"baseGroups": [
|
"baseGroups": [
|
||||||
"kiro-runtime-status",
|
"kiro-runtime-status",
|
||||||
"shared-auto-run",
|
"shared-auto-run"
|
||||||
"shared-settings-actions"
|
|
||||||
],
|
],
|
||||||
"targets": {
|
"targets": {
|
||||||
"kiro-rs": {
|
"kiro-rs": {
|
||||||
|
|||||||
@@ -47,8 +47,7 @@
|
|||||||
"openai-phone",
|
"openai-phone",
|
||||||
"shared-auto-run",
|
"shared-auto-run",
|
||||||
"openai-oauth",
|
"openai-oauth",
|
||||||
"openai-step6",
|
"openai-step6"
|
||||||
"shared-settings-actions"
|
|
||||||
],
|
],
|
||||||
"targets": {
|
"targets": {
|
||||||
"cpa": {
|
"cpa": {
|
||||||
|
|||||||
+50
-27
@@ -40,6 +40,10 @@
|
|||||||
|
|
||||||
--radius-sm: 6px;
|
--radius-sm: 6px;
|
||||||
--radius-md: 8px;
|
--radius-md: 8px;
|
||||||
|
--data-label-width: 76px;
|
||||||
|
--data-row-gap: 8px;
|
||||||
|
--data-field-height: 34px;
|
||||||
|
--data-inline-action-min-width: 64px;
|
||||||
--transition: 150ms ease;
|
--transition: 150ms ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -893,7 +897,8 @@ header {
|
|||||||
.data-row {
|
.data-row {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 8px;
|
gap: var(--data-row-gap);
|
||||||
|
min-width: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#settings-card .data-row.module-divider-start {
|
#settings-card .data-row.module-divider-start {
|
||||||
@@ -919,7 +924,24 @@ header {
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
flex: 1;
|
flex: 1 1 0;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.data-inline > .data-input,
|
||||||
|
.data-inline > .data-select,
|
||||||
|
.data-inline > .editable-list-picker,
|
||||||
|
.data-inline > .input-with-icon {
|
||||||
|
flex: 1 1 0;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.data-inline > .auto-delay-input {
|
||||||
|
flex: 0 0 72px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.data-inline > .data-value {
|
||||||
|
flex: 1 1 0;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1247,41 +1269,37 @@ header {
|
|||||||
|
|
||||||
.input-with-icon {
|
.input-with-icon {
|
||||||
position: relative;
|
position: relative;
|
||||||
flex: 1;
|
flex: 1 1 0;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.data-label {
|
.data-label {
|
||||||
width: 56px;
|
flex: 0 0 var(--data-label-width);
|
||||||
|
width: var(--data-label-width);
|
||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
color: var(--text-muted);
|
color: var(--text-muted);
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
letter-spacing: 0.06em;
|
letter-spacing: 0.06em;
|
||||||
flex-shrink: 0;
|
min-width: 0;
|
||||||
}
|
|
||||||
|
|
||||||
#row-codex2api-url .data-label,
|
|
||||||
#row-codex2api-admin-key .data-label {
|
|
||||||
width: 76px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#row-flow-selector .data-label,
|
#row-flow-selector .data-label,
|
||||||
#row-source-selector .data-label,
|
#row-source-selector .data-label {
|
||||||
|
text-transform: none;
|
||||||
|
letter-spacing: 0.02em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#row-codex2api-url .data-label,
|
||||||
|
#row-codex2api-admin-key .data-label,
|
||||||
#row-grok-webchat2api-url .data-label,
|
#row-grok-webchat2api-url .data-label,
|
||||||
#row-grok-webchat2api-key .data-label,
|
#row-grok-webchat2api-key .data-label,
|
||||||
#row-grok-register-status .data-label,
|
#row-grok-register-status .data-label,
|
||||||
#row-grok-sso-status .data-label,
|
#row-grok-sso-status .data-label,
|
||||||
#row-grok-webchat2api-upload-status .data-label,
|
#row-grok-webchat2api-upload-status .data-label,
|
||||||
#row-grok-sso-settings .data-label {
|
#row-grok-sso-settings .data-label {
|
||||||
width: 76px;
|
|
||||||
text-transform: none;
|
|
||||||
letter-spacing: 0.02em;
|
|
||||||
}
|
|
||||||
|
|
||||||
#row-codex2api-url .data-label {
|
|
||||||
font-size: 10px;
|
font-size: 10px;
|
||||||
letter-spacing: 0.02em;
|
letter-spacing: 0.02em;
|
||||||
text-transform: none;
|
text-transform: none;
|
||||||
@@ -1364,7 +1382,10 @@ header {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.data-input {
|
.data-input {
|
||||||
flex: 1;
|
flex: 1 1 0;
|
||||||
|
width: 100%;
|
||||||
|
min-width: 0;
|
||||||
|
min-height: var(--data-field-height);
|
||||||
padding: 7px 10px;
|
padding: 7px 10px;
|
||||||
background: var(--bg-field);
|
background: var(--bg-field);
|
||||||
border: 1px solid var(--border);
|
border: 1px solid var(--border);
|
||||||
@@ -1374,7 +1395,6 @@ header {
|
|||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
outline: none;
|
outline: none;
|
||||||
transition: border-color var(--transition), box-shadow var(--transition);
|
transition: border-color var(--transition), box-shadow var(--transition);
|
||||||
min-width: 0;
|
|
||||||
}
|
}
|
||||||
.data-input::placeholder { color: var(--text-muted); }
|
.data-input::placeholder { color: var(--text-muted); }
|
||||||
.data-input:focus { border-color: var(--blue); box-shadow: 0 0 0 3px var(--blue-soft); }
|
.data-input:focus { border-color: var(--blue); box-shadow: 0 0 0 3px var(--blue-soft); }
|
||||||
@@ -1446,7 +1466,8 @@ header {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.choice-group {
|
.choice-group {
|
||||||
flex: 1;
|
flex: 1 1 0;
|
||||||
|
width: 100%;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@@ -1526,15 +1547,14 @@ header {
|
|||||||
color: var(--text-secondary);
|
color: var(--text-secondary);
|
||||||
}
|
}
|
||||||
|
|
||||||
#btn-fetch-email,
|
#btn-fetch-email {
|
||||||
#btn-save-settings {
|
|
||||||
padding-inline: 10px;
|
padding-inline: 10px;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.data-inline-btn {
|
.data-inline-btn {
|
||||||
flex-shrink: 0;
|
flex: 0 0 auto;
|
||||||
min-width: 56px;
|
min-width: var(--data-inline-action-min-width);
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2072,7 +2092,10 @@ header {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.data-select {
|
.data-select {
|
||||||
flex: 1;
|
flex: 1 1 0;
|
||||||
|
width: 100%;
|
||||||
|
min-width: 0;
|
||||||
|
min-height: var(--data-field-height);
|
||||||
padding: 7px 10px;
|
padding: 7px 10px;
|
||||||
background: var(--bg-field);
|
background: var(--bg-field);
|
||||||
border: 1px solid var(--border);
|
border: 1px solid var(--border);
|
||||||
@@ -2083,7 +2106,6 @@ header {
|
|||||||
outline: none;
|
outline: none;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: border-color var(--transition);
|
transition: border-color var(--transition);
|
||||||
min-width: 0;
|
|
||||||
}
|
}
|
||||||
.data-select:focus { border-color: var(--blue); box-shadow: 0 0 0 3px var(--blue-soft); }
|
.data-select:focus { border-color: var(--blue); box-shadow: 0 0 0 3px var(--blue-soft); }
|
||||||
[data-theme="dark"] .data-select { color-scheme: dark; }
|
[data-theme="dark"] .data-select { color-scheme: dark; }
|
||||||
@@ -2105,7 +2127,8 @@ header {
|
|||||||
|
|
||||||
.editable-list-picker {
|
.editable-list-picker {
|
||||||
position: relative;
|
position: relative;
|
||||||
flex: 1;
|
flex: 1 1 0;
|
||||||
|
width: 100%;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+24
-24
@@ -405,9 +405,11 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="data-row" id="row-plus-hosted-checkout-oauth-delay" style="display:none;">
|
<div class="data-row" id="row-plus-hosted-checkout-oauth-delay" style="display:none;">
|
||||||
<span class="data-label">成功等待</span>
|
<span class="data-label">成功等待</span>
|
||||||
<input type="number" id="input-plus-hosted-checkout-oauth-delay-seconds" class="data-input auto-delay-input"
|
<div class="data-inline">
|
||||||
value="3" min="0" max="120" step="1" />
|
<input type="number" id="input-plus-hosted-checkout-oauth-delay-seconds" class="data-input auto-delay-input"
|
||||||
<span class="setting-caption">支付成功页出现后再继续账号接入</span>
|
value="3" min="0" max="120" step="1" />
|
||||||
|
<span class="setting-caption">支付成功页出现后再继续账号接入</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="data-row" id="row-gpc-helper-api" style="display:none;">
|
<div class="data-row" id="row-gpc-helper-api" style="display:none;">
|
||||||
<span class="data-label">GPC API</span>
|
<span class="data-label">GPC API</span>
|
||||||
@@ -469,13 +471,15 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="data-row" id="row-gpc-helper-local-sms-enabled" style="display:none;">
|
<div class="data-row" id="row-gpc-helper-local-sms-enabled" style="display:none;">
|
||||||
<span class="data-label">本地 OTP</span>
|
<span class="data-label">本地 OTP</span>
|
||||||
<label class="toggle-switch">
|
<div class="data-inline">
|
||||||
<input type="checkbox" id="input-gpc-helper-local-sms-enabled" />
|
<label class="toggle-switch">
|
||||||
<span class="toggle-switch-track" aria-hidden="true">
|
<input type="checkbox" id="input-gpc-helper-local-sms-enabled" />
|
||||||
<span class="toggle-switch-thumb"></span>
|
<span class="toggle-switch-track" aria-hidden="true">
|
||||||
</span>
|
<span class="toggle-switch-thumb"></span>
|
||||||
</label>
|
</span>
|
||||||
<span class="setting-caption">从本机 helper 读取当前通道 OTP,开启后不弹手动验证码</span>
|
</label>
|
||||||
|
<span class="setting-caption">从本机 helper 读取当前通道 OTP,开启后不弹手动验证码</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="data-row" id="row-gpc-helper-local-sms-url" style="display:none;">
|
<div class="data-row" id="row-gpc-helper-local-sms-url" style="display:none;">
|
||||||
<span class="data-label">OTP 接口</span>
|
<span class="data-label">OTP 接口</span>
|
||||||
@@ -770,12 +774,6 @@
|
|||||||
<span id="display-localhost-url" class="data-value data-value-fill mono truncate">等待中...</span>
|
<span id="display-localhost-url" class="data-value data-value-fill mono truncate">等待中...</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="data-row module-divider-start" id="row-settings-actions">
|
|
||||||
<span class="data-label">设置</span>
|
|
||||||
<div class="data-inline data-value-actions">
|
|
||||||
<button id="btn-save-settings" class="btn btn-outline btn-sm data-inline-btn" type="button">保存</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div id="cloudflare-temp-email-section" class="data-card hotmail-card" style="display:none;">
|
<div id="cloudflare-temp-email-section" class="data-card hotmail-card" style="display:none;">
|
||||||
<div class="section-mini-header">
|
<div class="section-mini-header">
|
||||||
@@ -1452,14 +1450,16 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="data-row" id="row-phone-signup-relogin-after-bind-email" style="display:none;">
|
<div class="data-row" id="row-phone-signup-relogin-after-bind-email" style="display:none;">
|
||||||
<span class="data-label">绑定后重登</span>
|
<span class="data-label">绑定后重登</span>
|
||||||
<label class="toggle-switch" for="input-phone-signup-relogin-after-bind-email"
|
<div class="data-inline">
|
||||||
title="手机号注册绑定邮箱后,跳过绑定邮箱验证码,重新刷新 OAuth 并使用绑定邮箱登录">
|
<label class="toggle-switch" for="input-phone-signup-relogin-after-bind-email"
|
||||||
<input type="checkbox" id="input-phone-signup-relogin-after-bind-email" />
|
title="手机号注册绑定邮箱后,跳过绑定邮箱验证码,重新刷新 OAuth 并使用绑定邮箱登录">
|
||||||
<span class="toggle-switch-track" aria-hidden="true">
|
<input type="checkbox" id="input-phone-signup-relogin-after-bind-email" />
|
||||||
<span class="toggle-switch-thumb"></span>
|
<span class="toggle-switch-track" aria-hidden="true">
|
||||||
</span>
|
<span class="toggle-switch-thumb"></span>
|
||||||
</label>
|
</span>
|
||||||
<span class="data-value">绑定邮箱后切入邮箱注册模式 OAuth 尾部</span>
|
</label>
|
||||||
|
<span class="data-value">绑定邮箱后切入邮箱注册模式 OAuth 尾部</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="data-row" id="row-account-run-history-helper-base-url" style="display:none;">
|
<div class="data-row" id="row-account-run-history-helper-base-url" style="display:none;">
|
||||||
<span class="data-label">同步服务</span>
|
<span class="data-label">同步服务</span>
|
||||||
|
|||||||
+5
-17
@@ -60,7 +60,6 @@ const btnToggleVpsUrl = document.getElementById('btn-toggle-vps-url');
|
|||||||
const btnToggleVpsPassword = document.getElementById('btn-toggle-vps-password');
|
const btnToggleVpsPassword = document.getElementById('btn-toggle-vps-password');
|
||||||
const btnFetchEmail = document.getElementById('btn-fetch-email');
|
const btnFetchEmail = document.getElementById('btn-fetch-email');
|
||||||
const btnTogglePassword = document.getElementById('btn-toggle-password');
|
const btnTogglePassword = document.getElementById('btn-toggle-password');
|
||||||
const btnSaveSettings = document.getElementById('btn-save-settings');
|
|
||||||
const btnStop = document.getElementById('btn-stop');
|
const btnStop = document.getElementById('btn-stop');
|
||||||
const btnReset = document.getElementById('btn-reset');
|
const btnReset = document.getElementById('btn-reset');
|
||||||
const btnContributionMode = document.getElementById('btn-contribution-mode');
|
const btnContributionMode = document.getElementById('btn-contribution-mode');
|
||||||
@@ -10976,13 +10975,11 @@ function markSettingsDirty(isDirty = true) {
|
|||||||
if (isDirty) {
|
if (isDirty) {
|
||||||
settingsSaveRevision += 1;
|
settingsSaveRevision += 1;
|
||||||
}
|
}
|
||||||
updateSaveButtonState();
|
updateSettingsSaveState();
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateSaveButtonState() {
|
function updateSettingsSaveState() {
|
||||||
btnSaveSettings.disabled = settingsSaveInFlight || !settingsDirty;
|
|
||||||
updateConfigMenuControls();
|
updateConfigMenuControls();
|
||||||
btnSaveSettings.textContent = settingsSaveInFlight ? '保存中' : '保存';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function isEditableElementInSettingsCard(element) {
|
function isEditableElementInSettingsCard(element) {
|
||||||
@@ -11019,7 +11016,7 @@ async function saveSettings(options = {}) {
|
|||||||
const payload = collectSettingsPayload();
|
const payload = collectSettingsPayload();
|
||||||
const saveRevision = settingsSaveRevision;
|
const saveRevision = settingsSaveRevision;
|
||||||
settingsSaveInFlight = true;
|
settingsSaveInFlight = true;
|
||||||
updateSaveButtonState();
|
updateSettingsSaveState();
|
||||||
|
|
||||||
const shouldSkipStateApplyForFocusedEditor = (() => {
|
const shouldSkipStateApplyForFocusedEditor = (() => {
|
||||||
if (!silent || source !== 'autosave') {
|
if (!silent || source !== 'autosave') {
|
||||||
@@ -11067,7 +11064,7 @@ async function saveSettings(options = {}) {
|
|||||||
throw err;
|
throw err;
|
||||||
} finally {
|
} finally {
|
||||||
settingsSaveInFlight = false;
|
settingsSaveInFlight = false;
|
||||||
updateSaveButtonState();
|
updateSettingsSaveState();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -15359,14 +15356,6 @@ hotmailServiceModeButtons.forEach((button) => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
btnSaveSettings.addEventListener('click', async () => {
|
|
||||||
if (!settingsDirty) {
|
|
||||||
showToast('配置已是最新', 'info', 1400);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
await saveSettings({ silent: false }).catch(() => { });
|
|
||||||
});
|
|
||||||
|
|
||||||
btnStop.addEventListener('click', async () => {
|
btnStop.addEventListener('click', async () => {
|
||||||
btnStop.disabled = true;
|
btnStop.disabled = true;
|
||||||
await chrome.runtime.sendMessage({ type: 'STOP_FLOW', source: 'sidepanel', payload: {} });
|
await chrome.runtime.sendMessage({ type: 'STOP_FLOW', source: 'sidepanel', payload: {} });
|
||||||
@@ -18823,8 +18812,7 @@ if (typeof initPhoneVerificationSectionExpandedState === 'function') {
|
|||||||
initPhoneVerificationSectionExpandedState();
|
initPhoneVerificationSectionExpandedState();
|
||||||
}
|
}
|
||||||
applyPhoneSmsProviderOrderSelection([], { ensureDefault: false, syncProvider: false });
|
applyPhoneSmsProviderOrderSelection([], { ensureDefault: false, syncProvider: false });
|
||||||
updateSaveButtonState();
|
updateSettingsSaveState();
|
||||||
updateConfigMenuControls();
|
|
||||||
setLocalCpaStep9Mode(DEFAULT_LOCAL_CPA_STEP9_MODE);
|
setLocalCpaStep9Mode(DEFAULT_LOCAL_CPA_STEP9_MODE);
|
||||||
setMail2925Mode(DEFAULT_MAIL_2925_MODE);
|
setMail2925Mode(DEFAULT_MAIL_2925_MODE);
|
||||||
setCloudflareTempEmailLookupMode(DEFAULT_CLOUDFLARE_TEMP_EMAIL_LOOKUP_MODE);
|
setCloudflareTempEmailLookupMode(DEFAULT_CLOUDFLARE_TEMP_EMAIL_LOOKUP_MODE);
|
||||||
|
|||||||
@@ -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.flowCapabilities.contributionAdapterIds, ['kiro-builder-id']);
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
capabilityState.visibleGroupIds,
|
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.flowCapabilities.contributionAdapterIds, []);
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
capabilityState.visibleGroupIds,
|
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.equal(flowRegistry.normalizeTargetId('grok', 'anything-else'), 'webchat2api');
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
flowRegistry.getVisibleGroupIds('openai', 'cpa'),
|
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(
|
assert.deepEqual(
|
||||||
flowRegistry.getVisibleGroupIds('kiro', 'kiro-rs'),
|
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(
|
assert.deepEqual(
|
||||||
flowRegistry.getVisibleGroupIds('grok', 'webchat2api'),
|
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(
|
assert.deepEqual(
|
||||||
flowRegistry.getTargetOptions('openai').map((entry) => entry.id),
|
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,
|
flowRegistry.getSettingsGroupDefinition('shared-auto-run')?.rowIds,
|
||||||
['row-shared-auto-run', 'row-auto-run-thread-interval', 'row-step-execution-range']
|
['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.getPublicationTargetDefinition('kiro', 'kiro-rs')?.label, 'kiro.rs');
|
||||||
assert.equal(flowRegistry.getFlowCapabilities('openai').supportsAccountContribution, true);
|
assert.equal(flowRegistry.getFlowCapabilities('openai').supportsAccountContribution, true);
|
||||||
assert.equal(flowRegistry.getFlowCapabilities('kiro').supportsAccountContribution, true);
|
assert.equal(flowRegistry.getFlowCapabilities('kiro').supportsAccountContribution, true);
|
||||||
|
|||||||
@@ -367,7 +367,7 @@ function clearTimeout(value) {
|
|||||||
async function persistSignupPhoneInputForAction() {
|
async function persistSignupPhoneInputForAction() {
|
||||||
phonePersistCalls += 1;
|
phonePersistCalls += 1;
|
||||||
}
|
}
|
||||||
function updateSaveButtonState() {}
|
function updateSettingsSaveState() {}
|
||||||
function collectSettingsPayload() {
|
function collectSettingsPayload() {
|
||||||
return { luckmailApiKey: 'autofilled-key' };
|
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-shared-auto-run"',
|
||||||
'id="row-auto-run-thread-interval"',
|
'id="row-auto-run-thread-interval"',
|
||||||
'id="row-oauth-callback"',
|
'id="row-oauth-callback"',
|
||||||
'id="row-settings-actions"',
|
|
||||||
'id="row-kiro-rs-url"',
|
'id="row-kiro-rs-url"',
|
||||||
'id="btn-open-kiro-rs-github"',
|
'id="btn-open-kiro-rs-github"',
|
||||||
'id="row-kiro-rs-key"',
|
'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 stepRangeIndex = html.indexOf('id="row-step-execution-range"');
|
||||||
const oauthDisplayIndex = html.indexOf('id="row-oauth-display"');
|
const oauthDisplayIndex = html.indexOf('id="row-oauth-display"');
|
||||||
const oauthCallbackIndex = html.indexOf('id="row-oauth-callback"');
|
const oauthCallbackIndex = html.indexOf('id="row-oauth-callback"');
|
||||||
const settingsActionsIndex = html.indexOf('id="row-settings-actions"');
|
|
||||||
|
|
||||||
assert.notEqual(step6CookieIndex, -1);
|
assert.notEqual(step6CookieIndex, -1);
|
||||||
assert.notEqual(sharedAutoRunIndex, -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(stepRangeIndex, -1);
|
||||||
assert.notEqual(oauthDisplayIndex, -1);
|
assert.notEqual(oauthDisplayIndex, -1);
|
||||||
assert.notEqual(oauthCallbackIndex, -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(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(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 > 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(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(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', () => {
|
test('sidepanel operation delay state is always normalized back to enabled', () => {
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ function markSettingsDirty(value = true) {
|
|||||||
function applySettingsState() {
|
function applySettingsState() {
|
||||||
applyCalls += 1;
|
applyCalls += 1;
|
||||||
}
|
}
|
||||||
function updateSaveButtonState() {}
|
function updateSettingsSaveState() {}
|
||||||
function updatePanelModeUI() {}
|
function updatePanelModeUI() {}
|
||||||
function updateMailProviderUI() {}
|
function updateMailProviderUI() {}
|
||||||
function updateButtonStates() {}
|
function updateButtonStates() {}
|
||||||
|
|||||||
Reference in New Issue
Block a user