feat(agents): convert codex auth method selector to segmented radio buttons
This commit is contained in:
1 parent
e25da0c517
commit
76da9b9944
4 files changed
+110
-10
No files matched your search
@@ -1086,7 +1086,7 @@ export const zhCN = {
|
||||
"agents.modify.connectionRepair": "当前接入:CPA 配置需要修复",
|
||||
"agents.modify.authMethod": "接入方式",
|
||||
"agents.modify.authApiKey": "API 密钥",
|
||||
"agents.modify.authOAuth": "OAuth配置方式",
|
||||
"agents.modify.authOAuth": "OAuth 登录方式",
|
||||
"agents.modify.matches": "已保存",
|
||||
"agents.modify.pending": "待应用",
|
||||
"agents.modify.checking": "正在读取配置…",
|
||||
|
||||
@@ -1904,19 +1904,65 @@ export function AgentsPage({ embedded = false, onConfigurationApplied }: AgentsP
|
||||
{selected === 'codex' ? (
|
||||
<div className="agent-codex-options">
|
||||
<div className="agent-auth-method">
|
||||
<div className="agent-signin-label"><label htmlFor="agent-connection-method">{t('agents.modify.authMethod')}</label>
|
||||
<div className="agent-signin-label">
|
||||
<span id="agent-connection-method-label" className="agent-signin-label-title">{t('agents.modify.authMethod')}</span>
|
||||
<button type="button" className="agent-signin-help-toggle" aria-expanded={connectionHelpOpen} aria-controls="agent-signin-hint"
|
||||
onClick={() => updateViewState({ connectionHelpOpen: !connectionHelpOpen })}>
|
||||
{t(connectionHelpOpen ? 'agents.modify.authHelpHide' : 'agents.modify.authHelpShow')}
|
||||
<ChevronDown size={14} aria-hidden="true" />
|
||||
</button>
|
||||
</div>
|
||||
<select id="agent-connection-method" aria-label={t('agents.modify.authMethod')} aria-describedby={connectionHelpOpen ? "agent-signin-hint" : undefined} value={oauthConfiguration ? 'oauth' : 'apikey'}
|
||||
onChange={(event) => void changeOauthConfiguration(event.currentTarget.value === 'oauth')}
|
||||
disabled={busy || loading || modelLoading}>
|
||||
<option value="apikey">{t('agents.modify.authApiKey')}</option>
|
||||
<option value="oauth">{t('agents.modify.authOAuth')}</option>
|
||||
</select>
|
||||
<div
|
||||
id="agent-connection-method"
|
||||
className="agent-auth-segmented"
|
||||
role="radiogroup"
|
||||
aria-labelledby="agent-connection-method-label"
|
||||
aria-describedby={connectionHelpOpen ? "agent-signin-hint" : undefined}
|
||||
onKeyDown={(event) => {
|
||||
if (busy || loading || modelLoading) return;
|
||||
if (event.key === 'ArrowRight' || event.key === 'ArrowDown') {
|
||||
event.preventDefault();
|
||||
if (!oauthConfiguration) void changeOauthConfiguration(true);
|
||||
} else if (event.key === 'ArrowLeft' || event.key === 'ArrowUp') {
|
||||
event.preventDefault();
|
||||
if (oauthConfiguration) void changeOauthConfiguration(false);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
role="radio"
|
||||
className={`agent-auth-segmented-button${!oauthConfiguration ? ' active' : ''}`}
|
||||
aria-checked={!oauthConfiguration}
|
||||
tabIndex={!oauthConfiguration ? 0 : -1}
|
||||
disabled={busy || loading || modelLoading}
|
||||
data-value="apikey"
|
||||
onClick={() => {
|
||||
if (oauthConfiguration) {
|
||||
void changeOauthConfiguration(false);
|
||||
}
|
||||
}}
|
||||
>
|
||||
{t('agents.modify.authApiKey')}
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
role="radio"
|
||||
className={`agent-auth-segmented-button${oauthConfiguration ? ' active' : ''}`}
|
||||
aria-checked={Boolean(oauthConfiguration)}
|
||||
tabIndex={oauthConfiguration ? 0 : -1}
|
||||
disabled={busy || loading || modelLoading}
|
||||
data-value="oauth"
|
||||
onClick={() => {
|
||||
if (!oauthConfiguration) {
|
||||
void changeOauthConfiguration(true);
|
||||
}
|
||||
}}
|
||||
>
|
||||
{busyAction === 'oauth-check' ? <LoaderCircle size={14} className="spin" /> : null}
|
||||
{t('agents.modify.authOAuth')}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{codexCatalogButton}
|
||||
|
||||
@@ -14268,6 +14268,59 @@ body.table-col-resizing * {
|
||||
/* Configuration form and explicit write actions. */
|
||||
.agent-auth-method { display: grid; gap: 6px; flex: 1; min-width: 0; font-size: var(--font-size-meta); }
|
||||
.agent-auth-method select { width: 100%; min-height: 38px; padding: 8px 10px; border: 1px solid var(--theme-e3e1db); border-radius: 8px; color: var(--theme-2d2a26); background: var(--theme-fffdf8); }
|
||||
.agent-auth-segmented {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
align-items: center;
|
||||
gap: 3px;
|
||||
min-height: 38px;
|
||||
height: 38px;
|
||||
padding: 3px;
|
||||
border: 1px solid var(--theme-e3e1db);
|
||||
border-radius: 8px;
|
||||
background: var(--theme-eeece6);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.agent-auth-segmented-button {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 6px;
|
||||
height: 100%;
|
||||
min-width: 0;
|
||||
padding: 0 10px;
|
||||
border: 0;
|
||||
border-radius: 5px;
|
||||
background: transparent;
|
||||
color: var(--theme-7a746c);
|
||||
font-size: var(--font-size-meta);
|
||||
font-weight: 600;
|
||||
font-family: inherit;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
transition: background 140ms ease, color 140ms ease, box-shadow 140ms ease;
|
||||
}
|
||||
.agent-auth-segmented-button:hover:not(:disabled) {
|
||||
background: var(--theme-e8e5dc);
|
||||
color: var(--theme-2d2a26);
|
||||
}
|
||||
.agent-auth-segmented-button.active {
|
||||
background: var(--theme-fffdf8);
|
||||
color: var(--theme-2d2a26);
|
||||
font-weight: 700;
|
||||
box-shadow: 0 1px 3px rgba(45, 42, 38, 0.12);
|
||||
}
|
||||
.agent-auth-segmented-button:disabled {
|
||||
cursor: not-allowed;
|
||||
opacity: 0.55;
|
||||
}
|
||||
.agent-auth-segmented-button:focus-visible {
|
||||
outline: 2px solid var(--theme-2d2a26);
|
||||
outline-offset: -1px;
|
||||
}
|
||||
.agent-model-section .agent-codex-options { margin-top: 16px; align-items: end; }
|
||||
.agent-model-section .agent-codex-catalog-button { min-height: 38px; height: 38px; padding: 8px 10px; }
|
||||
.agent-write-state { margin: 0; font-size: var(--font-size-meta); color: var(--theme-7a746c); }
|
||||
@@ -14307,6 +14360,7 @@ body.table-col-resizing * {
|
||||
.agent-run-controls .agent-launch-button { flex: 0 1 auto; width: auto; min-width: 0; max-width: 100%; }
|
||||
}
|
||||
.agent-signin-label { display: flex; align-items: center; gap: 8px; }
|
||||
.agent-signin-label-title { font-weight: 600; color: var(--theme-2d2a26); }
|
||||
.agent-signin-help-toggle { display: inline-flex; align-items: center; gap: 4px; min-height: 30px; padding: 3px 6px; border: 0; border-radius: 4px; background: transparent; color: var(--theme-7a746c); font: inherit; cursor: pointer; }
|
||||
.agent-signin-help-toggle:hover { color: var(--theme-2d2a26); background: var(--theme-fffdf8); }
|
||||
.agent-signin-help-toggle[aria-expanded="true"] svg { transform: rotate(180deg); }
|
||||
|
||||
@@ -78,10 +78,10 @@ const assert = require('node:assert/strict');
|
||||
await page.locator('.agent-list-items button').filter({ hasText: 'Codex' }).click();
|
||||
await ready(); await expectPending(true);
|
||||
await selectModel('gpt-one'); await expectPending(false);
|
||||
await page.locator('#agent-connection-method').selectOption('oauth');
|
||||
await page.locator('#agent-connection-method [data-value="oauth"]').click();
|
||||
await expectPending(true);
|
||||
await selectModel('gpt-two');
|
||||
await page.locator('#agent-connection-method').selectOption('apikey');
|
||||
await page.locator('#agent-connection-method [data-value="apikey"]').click();
|
||||
await expectPending(true);
|
||||
await selectModel('gpt-one'); await expectPending(false);
|
||||
|
||||
|
||||
Reference in new issue
Block a user