mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-02 01:10:23 +08:00
fix(frontend): 优化 OAuth 身份徽章优先级并避免 Kiro 订阅标签重复
- getOAuthOrgBadge 优先展示 organization id, 其次回落到 account_id 或 account_user_id, 不再使用 account_name 作为徽章文案 - Kiro provider 的订阅标签仅在与 OAuth plan 标签不一致时显示, 避免重复徽章 - 补充 getOAuthOrgBadge 的单元测试覆盖组织优先与回落场景
This commit is contained in:
@@ -315,12 +315,12 @@
|
|||||||
</Badge>
|
</Badge>
|
||||||
<!-- Kiro 订阅类型标签 -->
|
<!-- Kiro 订阅类型标签 -->
|
||||||
<Badge
|
<Badge
|
||||||
v-if="provider.provider_type === 'kiro' && getKiroSubscriptionTitle(key)"
|
v-if="shouldShowKiroSubscriptionBadge(key)"
|
||||||
variant="outline"
|
variant="outline"
|
||||||
class="text-[10px] px-1.5 py-0 shrink-0"
|
class="text-[10px] px-1.5 py-0 shrink-0"
|
||||||
:class="getOAuthPlanTypeClass(formatKiroSubscription(getKiroSubscriptionTitle(key)))"
|
:class="getOAuthPlanTypeClass(getKiroSubscriptionBadgeLabel(key))"
|
||||||
>
|
>
|
||||||
{{ formatKiroSubscription(getKiroSubscriptionTitle(key)) }}
|
{{ getKiroSubscriptionBadgeLabel(key) }}
|
||||||
</Badge>
|
</Badge>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center gap-1">
|
<div class="flex items-center gap-1">
|
||||||
@@ -2074,6 +2074,22 @@ function getKiroSubscriptionTitle(key: EndpointAPIKey): string | undefined {
|
|||||||
return getKiroQuotaDisplay(key)?.subscription_title
|
return getKiroQuotaDisplay(key)?.subscription_title
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getKiroSubscriptionBadgeLabel(key: EndpointAPIKey): string {
|
||||||
|
return formatKiroSubscription(getKiroSubscriptionTitle(key))
|
||||||
|
}
|
||||||
|
|
||||||
|
function shouldShowKiroSubscriptionBadge(key: EndpointAPIKey): boolean {
|
||||||
|
if (provider.value?.provider_type !== 'kiro') return false
|
||||||
|
|
||||||
|
const kiroLabel = getKiroSubscriptionBadgeLabel(key)
|
||||||
|
if (!kiroLabel) return false
|
||||||
|
|
||||||
|
const oauthPlanLabel = formatOAuthPlanType(key.oauth_plan_type)
|
||||||
|
if (!oauthPlanLabel) return true
|
||||||
|
|
||||||
|
return oauthPlanLabel.trim().toLowerCase() !== kiroLabel.trim().toLowerCase()
|
||||||
|
}
|
||||||
|
|
||||||
function shouldAutoRefreshCodexQuota(): boolean {
|
function shouldAutoRefreshCodexQuota(): boolean {
|
||||||
if (provider.value?.provider_type !== 'codex') return false
|
if (provider.value?.provider_type !== 'codex') return false
|
||||||
const now = Math.floor(Date.now() / 1000)
|
const now = Math.floor(Date.now() / 1000)
|
||||||
|
|||||||
43
frontend/src/utils/__tests__/oauthIdentity.spec.ts
Normal file
43
frontend/src/utils/__tests__/oauthIdentity.spec.ts
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
import { describe, expect, it } from 'vitest'
|
||||||
|
|
||||||
|
import { getOAuthOrgBadge } from '../oauthIdentity'
|
||||||
|
|
||||||
|
describe('getOAuthOrgBadge', () => {
|
||||||
|
it('prefers organization identity over account display name', () => {
|
||||||
|
const badge = getOAuthOrgBadge({
|
||||||
|
oauth_account_id: 'acct-demo-001',
|
||||||
|
oauth_account_name: 'Workspace Alpha',
|
||||||
|
oauth_account_user_id: 'user-1__acct-demo-001',
|
||||||
|
oauth_organizations: [
|
||||||
|
{ id: 'org-personal-1234', title: 'Personal', is_default: true },
|
||||||
|
],
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(badge).toEqual({
|
||||||
|
id: 'org-personal-1234',
|
||||||
|
label: 'org:org-pe...1234',
|
||||||
|
title: 'name: Workspace Alpha | account_id: acct-demo-001 | account_user_id: user-1__acct-demo-001 | org_id: org-personal-1234 | org_title: Personal',
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('falls back to short account id when no organization is available', () => {
|
||||||
|
const badge = getOAuthOrgBadge({
|
||||||
|
oauth_account_id: 'acct-demo-001',
|
||||||
|
oauth_account_name: 'Workspace Alpha',
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(badge).toEqual({
|
||||||
|
id: 'acct-demo-001',
|
||||||
|
label: 'acct-dem',
|
||||||
|
title: 'name: Workspace Alpha | account_id: acct-demo-001',
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('does not create an identity badge from account name alone', () => {
|
||||||
|
const badge = getOAuthOrgBadge({
|
||||||
|
oauth_account_name: 'Free',
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(badge).toBeNull()
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -26,6 +26,10 @@ function formatOAuthAccountBadge(accountId: string): string {
|
|||||||
return accountId.slice(0, 8)
|
return accountId.slice(0, 8)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function formatOAuthAccountUserBadge(accountUserId: string): string {
|
||||||
|
return formatOAuthIdentityShort(accountUserId, 8, 6)
|
||||||
|
}
|
||||||
|
|
||||||
function getPrimaryOAuthOrganization(
|
function getPrimaryOAuthOrganization(
|
||||||
value: OAuthIdentityDisplayValue,
|
value: OAuthIdentityDisplayValue,
|
||||||
): { id: string; title: string } | null {
|
): { id: string; title: string } | null {
|
||||||
@@ -61,10 +65,14 @@ export function getOAuthOrgBadge(
|
|||||||
const accountName = readStr(value?.oauth_account_name)
|
const accountName = readStr(value?.oauth_account_name)
|
||||||
const accountUserId = readStr(value?.oauth_account_user_id)
|
const accountUserId = readStr(value?.oauth_account_user_id)
|
||||||
|
|
||||||
const badgeId = accountId || org?.id || ''
|
const badgeId = org?.id || accountId || accountUserId || ''
|
||||||
const label = accountName
|
const label = org?.id
|
||||||
|| (accountId ? formatOAuthAccountBadge(accountId) : '')
|
? `org:${formatOAuthIdentityShort(org.id, 6, 4)}`
|
||||||
|| (org?.id ? `org:${formatOAuthIdentityShort(org.id, 6, 4)}` : '')
|
: accountId
|
||||||
|
? formatOAuthAccountBadge(accountId)
|
||||||
|
: accountUserId
|
||||||
|
? formatOAuthAccountUserBadge(accountUserId)
|
||||||
|
: ''
|
||||||
if (!badgeId || !label) return null
|
if (!badgeId || !label) return null
|
||||||
|
|
||||||
const titleParts = [
|
const titleParts = [
|
||||||
|
|||||||
Reference in New Issue
Block a user