Merge pull request #2738 from langbot-app/fix/plan-credits-copy-and-upgrade-button

fix(web): outline the plan upgrade control and call the grant 模型积分
This commit is contained in:
RockChinQ
2026-10-21 18:41:27 +08:00
committed by GitHub
10 changed files with 28 additions and 10 deletions
@@ -2173,9 +2173,9 @@ export default function HomeSidebar({
<Tooltip>
<TooltipTrigger asChild>
<Button
variant="ghost"
variant="outline"
size="icon"
className="size-9 shrink-0 text-muted-foreground hover:text-foreground group-data-[collapsible=icon]:hidden"
className="size-9 shrink-0 group-data-[collapsible=icon]:hidden"
aria-label={t('workspace.upgradePlan')}
onClick={() => setCloudPlansOpen(true)}
>
+1 -1
View File
@@ -102,7 +102,7 @@ const enUS = {
retentionLabel: 'Message history retention',
retentionHelp:
'Message history is automatically removed after this period.',
credits: '{{count}} credits every month',
credits: '{{count}} model credits every month',
creditsLabel: 'Model credits',
creditsHelp:
'Credits are granted each subscription month, including on yearly plans. When credits run out, you can still use your own configured model providers.',
+1 -1
View File
@@ -100,7 +100,7 @@ const esES = {
retentionLabel: 'Retención del historial',
retentionHelp:
'El historial se elimina automáticamente al superar este periodo.',
credits: '{{count}} créditos al mes',
credits: '{{count}} créditos de modelo al mes',
creditsLabel: 'Créditos mensuales',
creditsHelp:
'Los créditos se conceden cada mes de suscripción, también en los planes anuales.',
+1 -1
View File
@@ -101,7 +101,7 @@ const jaJP = {
retention: 'メッセージ履歴 · {{count}} 日間',
retentionLabel: 'メッセージ履歴の保存期間',
retentionHelp: '保存期間を過ぎた履歴は自動的に削除されます。',
credits: '毎月 {{count}} クレジット',
credits: '毎月 {{count}} モデルクレジット',
creditsLabel: 'モデルクレジット',
creditsHelp:
'年払いでも、契約の各月にクレジットが付与されます。クレジットが不足しても、独自に設定したモデルプロバイダーを引き続き利用できます。',
+1 -1
View File
@@ -100,7 +100,7 @@ const ruRU = {
retentionLabel: 'Срок хранения сообщений',
retentionHelp:
'По истечении этого срока сообщения автоматически удаляются.',
credits: '{{count}} кредитов в месяц',
credits: '{{count}} кредитов модели в месяц',
creditsLabel: 'Ежемесячные кредиты',
creditsHelp:
'Кредиты начисляются каждый месяц подписки, в том числе при годовой оплате.',
+1 -1
View File
@@ -98,7 +98,7 @@ const thTH = {
retention: 'ประวัติข้อความ · {{count}} วัน',
retentionLabel: 'ระยะเวลาเก็บประวัติข้อความ',
retentionHelp: 'ประวัติข้อความจะถูกลบโดยอัตโนมัติเมื่อเกินระยะเวลานี้',
credits: '{{count}} เครดิตต่อเดือน',
credits: '{{count}} เครดิตโมเดลต่อเดือน',
creditsLabel: 'เครดิตรายเดือน',
creditsHelp: 'ได้รับเครดิตทุกเดือนของการสมัคร รวมถึงแผนรายปี',
platforms: 'รองรับแพลตฟอร์มหลัก',
+1 -1
View File
@@ -100,7 +100,7 @@ const viVN = {
retention: 'Lịch sử tin nhắn · {{count}} ngày',
retentionLabel: 'Thời gian lưu tin nhắn',
retentionHelp: 'Tin nhắn được tự động xóa sau thời gian này.',
credits: '{{count}} tín dụng mỗi tháng',
credits: '{{count}} tín dụng mô hình mỗi tháng',
creditsLabel: 'Tín dụng hàng tháng',
creditsHelp: 'Tín dụng được cấp mỗi tháng đăng ký, kể cả gói năm.',
platforms: 'Hỗ trợ nền tảng phổ biến',
+1 -1
View File
@@ -97,7 +97,7 @@ const zhHans = {
retention: '消息记录保留 {{count}} 天',
retentionLabel: '消息记录保留时长',
retentionHelp: '超过保留时长的消息记录会自动清理。',
credits: '每月赠送 {{count}} 积分',
credits: '每月赠送 {{count}} 模型积分',
creditsLabel: '模型积分',
creditsHelp:
'每个订阅月自动发放,年付计划同样按月发放。积分用尽后,仍可接入自行配置的模型供应商继续使用。',
+1 -1
View File
@@ -97,7 +97,7 @@ const zhHant = {
retention: '訊息記錄保留 {{count}} 天',
retentionLabel: '訊息記錄保留時間',
retentionHelp: '超過保留時間的訊息記錄會自動清理。',
credits: '每月贈送 {{count}} 積分',
credits: '每月贈送 {{count}} 模型積分',
creditsLabel: '每月贈送積分',
creditsHelp: '每個訂閱月自動發放,年付方案同樣按月發放。',
platforms: '支援主流平台',
+18
View File
@@ -91,6 +91,24 @@ for (const scenario of [
Math.abs(upgradeBox!.x + upgradeBox!.width - navBox!.x - navBox!.width),
).toBeLessThanOrEqual(1);
await expect(upgrade).toBeVisible();
// The upgrade control is deliberately styled like the workspace switcher:
// same height, same visible outline, so the two read as one control row.
expect(
Math.abs(upgradeBox!.height - triggerBox!.height),
).toBeLessThanOrEqual(1);
for (const control of [trigger, upgrade]) {
const outline = await control.evaluate((element) => {
const style = getComputedStyle(element);
return {
width: parseFloat(style.borderTopWidth),
color: style.borderTopColor,
style: style.borderTopStyle,
};
});
expect(outline.style).not.toBe('none');
expect(outline.width).toBeGreaterThan(0);
expect(outline.color).not.toBe('rgba(0, 0, 0, 0)');
}
await trigger.click();
const row = page
.getByRole('menuitem')