Skip to content

Commit 8fa28ad

Browse files
xiaojingmingxjm
andauthored
feat(account): add purchase quota and join activity options in account localization (#630)
feat(apiErrors): add activity-related strings for quota management in localization refactor(ErrorCodeManager): simplify error handling for insufficient quota and star required Co-authored-by: xjm <[email protected]>
1 parent 2146891 commit 8fa28ad

File tree

8 files changed

+93
-30
lines changed

8 files changed

+93
-30
lines changed

src/core/costrict/error-code/ErrorCodeManager.ts

Lines changed: 45 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -182,26 +182,10 @@ export class ErrorCodeManager {
182182
message = defaultError["401"].message
183183
solution = defaultError["401"].solution
184184
error.status = status = 401
185-
} else if (code === "ai-gateway.insufficient_quota" || code === "ai-gateway.star_required") {
186-
const hash = await this.hashToken(apiConfiguration.zgsmAccessToken || "")
187-
const baseurl = apiConfiguration.zgsmBaseUrl || ZgsmAuthConfig.getInstance().getDefaultLoginBaseUrl()
188-
const isQuota = code === "ai-gateway.insufficient_quota"
189-
190-
const solution1 = isQuota
191-
? t("apiErrors:solution.ai-gateway.insufficientCredits")
192-
: t("apiErrors:solution.ai-gateway.pleaseStarProject")
193-
const solution2 = isQuota
194-
? t("apiErrors:solution.ai-gateway.quotaAcquisition")
195-
: t("apiErrors:solution.ai-gateway.howToStar")
196-
197-
const checkRemainingQuotaStr = !isQuota
198-
? `${t("apiErrors:solution.quota-check.checkRemainingQuota")} “ <a href='${baseurl}/credit/manager/credits?state=${hash}' style="font-size: 12px;color:#0078d4;text-decoration: none;">${t("apiErrors:solution.quota-check.creditUsageStats")}</a> ” ${t("apiErrors:solution.quota-check.viewDetails")}`
199-
: ""
200-
201-
solution = `
202-
<span style="color:#E64545;font-size: 12px;">${solution1}</span> <a href='${baseurl}/credit/manager/md-preview?state=${hash}' style="font-size: 12px;color:#0078d4;text-decoration: none;">${solution2}</a>
203-
${checkRemainingQuotaStr}
204-
`
185+
} else if (code === "ai-gateway.insufficient_quota") {
186+
solution = await this.handleInsufficientQuotaError(apiConfiguration)
187+
} else if (code === "ai-gateway.star_required") {
188+
solution = await this.handleStarRequiredError(apiConfiguration)
205189
}
206190
TelemetryService.instance.captureError(`ApiError_${code}`)
207191
this.provider.log(`[CoStrict#apiErrors] task ${taskId}.${instanceId} Raw Error: ${rawError}`)
@@ -218,6 +202,47 @@ ${checkRemainingQuotaStr}
218202
this.provider.log(`[CoStrict#apiErrors] task ${taskId}.${instanceId} Raw Error: ${rawError}`)
219203
return `${t("apiErrors:request.error_details")}\n\n${message}\n\n${requestId ? `RequestID: ${requestId}\n\n` : ""}${t("apiErrors:request.solution")}\n${solution}`
220204
}
205+
206+
/**
207+
* Handling insufficient quota errors
208+
* @param apiConfiguration api config
209+
* @returns string
210+
*/
211+
private async handleInsufficientQuotaError(apiConfiguration: any): Promise<string> {
212+
const hash = await this.hashToken(apiConfiguration.zgsmAccessToken || "")
213+
const baseurl = apiConfiguration.zgsmBaseUrl || ZgsmAuthConfig.getInstance().getDefaultLoginBaseUrl()
214+
215+
const solution1 = t("apiErrors:solution.ai-gateway.insufficientCredits")
216+
const solution2 = t("apiErrors:solution.ai-gateway.quotaAcquisition")
217+
218+
const activitiesStr = `${t("apiErrors:solution.activitiesStr.participate")}<a href='${baseurl}/credit/manager/?state=${hash}&tab=activity' style="font-size: 12px;color:#0078d4;text-decoration: none;">${t("apiErrors:solution.activitiesStr.operationalActivities")}</a> ${t("apiErrors:solution.activitiesStr.or")} <a href='${baseurl}/credit/manager/?state=${hash}&tab=subscription' style="font-size: 12px;color:#0078d4;text-decoration: none;">${t("apiErrors:solution.activitiesStr.purchaseQuota")}</a> ${t("apiErrors:solution.activitiesStr.getCreditLimit")}`
219+
220+
return `
221+
<span style="color:#E64545;font-size: 12px;">${solution1}</span> <a href='${baseurl}/credit/manager/md-preview' style="font-size: 12px;color:#0078d4;text-decoration: none;">${solution2}</a>
222+
\n${activitiesStr}
223+
`
224+
}
225+
226+
/**
227+
* Handling errors that require starring
228+
* @param apiConfiguration api config
229+
* @returns string
230+
*/
231+
private async handleStarRequiredError(apiConfiguration: any): Promise<string> {
232+
const hash = await this.hashToken(apiConfiguration.zgsmAccessToken || "")
233+
const baseurl = apiConfiguration.zgsmBaseUrl || ZgsmAuthConfig.getInstance().getDefaultLoginBaseUrl()
234+
235+
const solution1 = t("apiErrors:solution.ai-gateway.pleaseStarProject")
236+
const solution2 = t("apiErrors:solution.ai-gateway.howToStar")
237+
238+
const checkRemainingQuotaStr = `${t("apiErrors:solution.quota-check.checkRemainingQuota")} " <a href='${baseurl}/credit/manager/?state=${hash}&tab=usage' style="font-size: 12px;color:#0078d4;text-decoration: none;">${t("apiErrors:solution.quota-check.creditUsageStats")}</a> " ${t("apiErrors:solution.quota-check.viewDetails")}`
239+
240+
return `
241+
<span style="color:#E64545;font-size: 12px;">${solution1}</span> <a href='${baseurl}/credit/manager/md-preview' style="font-size: 12px;color:#0078d4;text-decoration: none;">${solution2}</a>
242+
\n${checkRemainingQuotaStr}
243+
`
244+
}
245+
221246
private async hashToken(token: string) {
222247
const encoder = new TextEncoder()
223248
const data = encoder.encode(token)

src/i18n/costrict-i18n/locales/en/apiErrors.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,13 @@
3737
"creditUsageStats": "Credit usage statistics",
3838
"viewDetails": "View details"
3939
},
40+
"activitiesStr": {
41+
"participate": "You can participate ",
42+
"operationalActivities": "Operational activities",
43+
"or": "or",
44+
"purchaseQuota": "Purchase quota",
45+
"getCreditLimit": "Get credit limit"
46+
},
4047
"undefined": "1. Check your network connection\n2. Check your proxy/firewall\n3. Contact the administrator",
4148
"unknown": "1. Please try again later\n2. Try switching models\n3. Contact the administrator"
4249
},

src/i18n/costrict-i18n/locales/zh-CN/apiErrors.json

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/i18n/costrict-i18n/locales/zh-TW/apiErrors.json

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

webview-ui/src/components/cloud/ZgsmAccountView.tsx

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,6 @@ const QuotaInfoDisplay = memo(
111111
quotaInfo,
112112
showQuotaInfo,
113113
t,
114-
handleGetMoreQuota,
115114
}: {
116115
quotaInfo: QuotaInfo
117116
showQuotaInfo: boolean
@@ -219,11 +218,6 @@ const QuotaInfoDisplay = memo(
219218
<span className="text-xs text-vscode-descriptionForeground font-medium">
220219
{t("cloud:quota.usedQuota")}
221220
</span>
222-
<span
223-
className="text-[10px] font-medium bg-gradient-to-br from-blue-400 to-blue-600 px-1 py-0.5 rounded-full cursor-pointer select-none text-white flex items-center gap-1"
224-
onClick={handleGetMoreQuota}>
225-
{t("cloud:quota.getMoreQuota")} 🎁
226-
</span>
227221
</div>
228222
<div className="flex items-baseline gap-1">
229223
<span className="text-sm font-bold text-vscode-foreground group-hover:text-vscode-focusBorder transition-colors">
@@ -268,7 +262,7 @@ const ZgsmAccountViewComponent = ({ apiConfiguration, onDone }: AccountViewProps
268262
const handleVisitCloudWebsite = useCallback(() => {
269263
// Send telemetry for cloud website visit
270264
telemetryClient.capture(TelemetryEventName.ACCOUNT_CONNECT_CLICKED)
271-
const cloudUrl = `${apiConfiguration?.zgsmBaseUrl?.trim() || "https://zgsm.sangfor.com"}/credit/manager?state=${hash}`
265+
const cloudUrl = `${apiConfiguration?.zgsmBaseUrl?.trim() || "https://zgsm.sangfor.com"}/credit/manager?state=${hash}&tab=usage`
272266
vscode.postMessage({ type: "openExternal", url: cloudUrl })
273267
}, [apiConfiguration?.zgsmBaseUrl, hash])
274268

@@ -282,6 +276,11 @@ const ZgsmAccountViewComponent = ({ apiConfiguration, onDone }: AccountViewProps
282276
vscode.postMessage({ type: "openExternal", url: "https://github.com/zgsm-ai/costrict" })
283277
}, [])
284278

279+
const handlePurchaseQuota = useCallback(() => {
280+
const cloudUrl = `${apiConfiguration?.zgsmBaseUrl?.trim() || "https://zgsm.sangfor.com"}/credit/manager?state=${hash}&tab=subscription`
281+
vscode.postMessage({ type: "openExternal", url: cloudUrl })
282+
}, [apiConfiguration?.zgsmBaseUrl, hash])
283+
285284
const onMessage = useCallback(
286285
(event: MessageEvent) => {
287286
const message: ExtensionMessage = event.data
@@ -409,6 +408,18 @@ const ZgsmAccountViewComponent = ({ apiConfiguration, onDone }: AccountViewProps
409408
</StandardTooltip>
410409
</h2>
411410
)}
411+
<div className="w-full flex gap-2 mt-4 justify-center">
412+
<span
413+
className="text-[10px] font-medium bg-gradient-to-br border border-[var(--vscode-editorWidget-border)] bg-[var(--vscode-editorWidget-background)] text-[var(--vscode-editor-foreground)] px-2 py-1 rounded-full cursor-pointer select-none flex items-center gap-1"
414+
onClick={handlePurchaseQuota}>
415+
{t("account:purchaseQuota")}
416+
</span>
417+
<span
418+
className="text-[10px] font-medium bg-gradient-to-br border border-[var(--vscode-editorWidget-border)] bg-[var(--vscode-editorWidget-background)] text-[var(--vscode-editor-foreground)] px-2 py-1 rounded-full cursor-pointer select-none flex items-center gap-1"
419+
onClick={handleGetMoreQuota}>
420+
{t("account:joinActivityForQuota")}
421+
</span>
422+
</div>
412423
{/* Star status card */}
413424
{quotaInfo?.is_star != null && (
414425
<StarStatusCard quotaInfo={quotaInfo} onStarRepository={handleStarRepository} _t={t} />

webview-ui/src/i18n/costrict-i18n/locales/en/account.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,7 @@
1111
"starThanksDesc": "You have starred the CoStrict repository",
1212
"starProject": "Support CoStrict Project",
1313
"starProjectDesc": "Star our open source project to show support",
14-
"starButton": "Star Now"
14+
"starButton": "Star Now",
15+
"purchaseQuota": "💰 Purchase more quotas",
16+
"joinActivityForQuota": "🎁 Obtain quotas"
1517
}

webview-ui/src/i18n/costrict-i18n/locales/zh-CN/account.json

Lines changed: 3 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

webview-ui/src/i18n/costrict-i18n/locales/zh-TW/account.json

Lines changed: 3 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)