feat(ui): show AIStudio models for virtual auth files and adjust Gemini OAuth spacing

This commit is contained in:
LTbinglingfeng
2026-01-02 22:42:20 +08:00
parent 2ae06a8860
commit 8232812ac2
3 changed files with 59 additions and 45 deletions

View File

@@ -719,6 +719,8 @@ export function AuthFilesPage() {
const renderFileCard = (item: AuthFileItem) => { const renderFileCard = (item: AuthFileItem) => {
const fileStats = resolveAuthFileStats(item, keyStats); const fileStats = resolveAuthFileStats(item, keyStats);
const isRuntimeOnly = isRuntimeOnlyAuthFile(item); const isRuntimeOnly = isRuntimeOnlyAuthFile(item);
const isAistudio = (item.type || '').toLowerCase() === 'aistudio';
const showModelsButton = !isRuntimeOnly || isAistudio;
const typeColor = getTypeColor(item.type || 'unknown'); const typeColor = getTypeColor(item.type || 'unknown');
return ( return (
@@ -755,20 +757,20 @@ export function AuthFilesPage() {
{renderStatusBar(item)} {renderStatusBar(item)}
<div className={styles.cardActions}> <div className={styles.cardActions}>
{isRuntimeOnly ? ( {showModelsButton && (
<div className={styles.virtualBadge}>{t('auth_files.type_virtual') || '虚拟认证文件'}</div> <Button
) : ( variant="secondary"
size="sm"
onClick={() => showModels(item)}
className={styles.iconButton}
title={t('auth_files.models_button', { defaultValue: '模型' })}
disabled={disableControls}
>
<IconBot className={styles.actionIcon} size={16} />
</Button>
)}
{!isRuntimeOnly && (
<> <>
<Button
variant="secondary"
size="sm"
onClick={() => showModels(item)}
className={styles.iconButton}
title={t('auth_files.models_button', { defaultValue: '模型' })}
disabled={disableControls}
>
<IconBot className={styles.actionIcon} size={16} />
</Button>
<Button <Button
variant="secondary" variant="secondary"
size="sm" size="sm"
@@ -805,6 +807,9 @@ export function AuthFilesPage() {
</Button> </Button>
</> </>
)} )}
{isRuntimeOnly && (
<div className={styles.virtualBadge}>{t('auth_files.type_virtual') || '虚拟认证文件'}</div>
)}
</div> </div>
</div> </div>
); );

View File

@@ -115,6 +115,13 @@
margin-top: $spacing-sm; margin-top: $spacing-sm;
} }
.geminiProjectField {
:global(.form-group) {
margin-top: $spacing-sm;
gap: $spacing-sm;
}
}
.filePicker { .filePicker {
display: flex; display: flex;
align-items: center; align-items: center;

View File

@@ -327,19 +327,21 @@ export function OAuthPage() {
> >
<div className="hint">{t(provider.hintKey)}</div> <div className="hint">{t(provider.hintKey)}</div>
{provider.id === 'gemini-cli' && ( {provider.id === 'gemini-cli' && (
<Input <div className={styles.geminiProjectField}>
label={t('auth_login.gemini_cli_project_id_label')} <Input
hint={t('auth_login.gemini_cli_project_id_hint')} label={t('auth_login.gemini_cli_project_id_label')}
value={state.projectId || ''} hint={t('auth_login.gemini_cli_project_id_hint')}
error={state.projectIdError} value={state.projectId || ''}
onChange={(e) => error={state.projectIdError}
updateProviderState(provider.id, { onChange={(e) =>
projectId: e.target.value, updateProviderState(provider.id, {
projectIdError: undefined projectId: e.target.value,
}) projectIdError: undefined
} })
placeholder={t('auth_login.gemini_cli_project_id_placeholder')} }
/> placeholder={t('auth_login.gemini_cli_project_id_placeholder')}
/>
</div>
)} )}
{state.url && ( {state.url && (
<div className={`connection-box ${styles.authUrlBox}`}> <div className={`connection-box ${styles.authUrlBox}`}>