feat(i18n): 安全批量转换 135 文件 — 覆盖率 34%→62%
使用 i18n.t() 全局方式(避免 hook 定位问题): - 288 目标文件中 135 个成功转换 - 2228 处中文替换为 i18n.t() 调用 - 1006 个新翻译 key 添加到 zh-CN.json + en-US.json - 词典总量: 3554 keys (22 namespaces) - tsc 零错误 + Vite 构建成功 - 6 个含代码示例/数据字符串的文件安全回退
This commit is contained in:
1 parent
72bfb0e12d
commit
55f216cfbb
131 files changed
+4049
-1908
No files matched your search
@@ -23,6 +23,7 @@ import { toast } from 'sonner';
|
||||
import { billingApi } from '@/api';
|
||||
import { providerLabels } from './CloudBillingHelpers';
|
||||
import type { JsonData } from '@/types/common';
|
||||
import i18n from '@/i18n';
|
||||
|
||||
const emptyRecord = {
|
||||
provider: 'aliyun',
|
||||
@@ -65,7 +66,7 @@ export function BillingRecordDialog({ open, onOpenChange, editingRecord, onSucce
|
||||
|
||||
const handleSave = async () => {
|
||||
if (!form.provider || !form.billing_date || !form.cost) {
|
||||
toast.error('请填写必填字段');
|
||||
toast.error(i18n.t('cloud.billingrecorddi.sd8a97c17'));
|
||||
return;
|
||||
}
|
||||
setSubmitting(true);
|
||||
@@ -81,7 +82,7 @@ export function BillingRecordDialog({ open, onOpenChange, editingRecord, onSucce
|
||||
onSuccess();
|
||||
toast('保存成功');
|
||||
} catch (e) {
|
||||
toast.error('保存失败', { description: (e as JsonData).message });
|
||||
toast.error(i18n.t('kubernetes.msg.saveFailed'), { description: (e as JsonData).message });
|
||||
} finally {
|
||||
setSubmitting(false);
|
||||
}
|
||||
@@ -91,13 +92,13 @@ export function BillingRecordDialog({ open, onOpenChange, editingRecord, onSucce
|
||||
<Dialog open={open} onOpenChange={onOpenChange}>
|
||||
<DialogContent className="max-w-md">
|
||||
<DialogHeader>
|
||||
<DialogTitle>{editingRecord ? '编辑成本记录' : '记录成本'}</DialogTitle>
|
||||
<DialogDescription>记录一条每日云资源成本</DialogDescription>
|
||||
<DialogTitle>{editingRecord ? i18n.t('cloud.billingrecorddi.s3c91e420') : i18n.t('cloud.recordCost')}</DialogTitle>
|
||||
<DialogDescription> {i18n.t('cloud.billingrecorddi.s09e541fd')} </DialogDescription>
|
||||
</DialogHeader>
|
||||
<div className="space-y-3">
|
||||
<div className="grid grid-cols-2 gap-3">
|
||||
<div>
|
||||
<Label className="text-sm text-[var(--dg-text-secondary)]">厂商 *</Label>
|
||||
<Label className="text-sm text-[var(--dg-text-secondary)]"> {i18n.t('cloud.billingrecorddi.sb11d8416')} </Label>
|
||||
<Select value={form.provider} onValueChange={(v) => setForm({ ...form, provider: v })}>
|
||||
<SelectTrigger className="mt-1"><SelectValue /></SelectTrigger>
|
||||
<SelectContent>
|
||||
@@ -108,37 +109,37 @@ export function BillingRecordDialog({ open, onOpenChange, editingRecord, onSucce
|
||||
</Select>
|
||||
</div>
|
||||
<div>
|
||||
<Label className="text-sm text-[var(--dg-text-secondary)]">日期 *</Label>
|
||||
<Label className="text-sm text-[var(--dg-text-secondary)]"> {i18n.t('cloud.billingrecorddi.s3abdefe2')} </Label>
|
||||
<Input type="date" className="mt-1" value={form.billing_date} onChange={(e) => setForm({ ...form, billing_date: e.target.value })} />
|
||||
</div>
|
||||
</div>
|
||||
<div className="grid grid-cols-2 gap-3">
|
||||
<div>
|
||||
<Label className="text-sm text-[var(--dg-text-secondary)]">费用(元) *</Label>
|
||||
<Label className="text-sm text-[var(--dg-text-secondary)]"> {i18n.t('cloud.billingrecorddi.s6f252687')} </Label>
|
||||
<Input type="number" step="0.01" className="mt-1" placeholder="0.00" value={form.cost} onChange={(e) => setForm({ ...form, cost: e.target.value })} />
|
||||
</div>
|
||||
<div>
|
||||
<Label className="text-sm text-[var(--dg-text-secondary)]">服务</Label>
|
||||
<Label className="text-sm text-[var(--dg-text-secondary)]"> {i18n.t('cloud.colService')} </Label>
|
||||
<Input className="mt-1" placeholder="ECS, RDS..." value={form.service} onChange={(e) => setForm({ ...form, service: e.target.value })} />
|
||||
</div>
|
||||
</div>
|
||||
<div className="grid grid-cols-2 gap-3">
|
||||
<div>
|
||||
<Label className="text-sm text-[var(--dg-text-secondary)]">区域</Label>
|
||||
<Label className="text-sm text-[var(--dg-text-secondary)]"> {i18n.t('cloud.colRegion')} </Label>
|
||||
<Input className="mt-1" placeholder="cn-hangzhou" value={form.region} onChange={(e) => setForm({ ...form, region: e.target.value })} />
|
||||
</div>
|
||||
<div>
|
||||
<Label className="text-sm text-[var(--dg-text-secondary)]">账号名称</Label>
|
||||
<Input className="mt-1" placeholder="主账号" value={form.account_name} onChange={(e) => setForm({ ...form, account_name: e.target.value })} />
|
||||
<Label className="text-sm text-[var(--dg-text-secondary)]"> {i18n.t('cloud.accountName')} </Label>
|
||||
<Input className="mt-1" placeholder={i18n.t('cloud.billingrecorddi.s0010795e')} value={form.account_name} onChange={(e) => setForm({ ...form, account_name: e.target.value })} />
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<Label className="text-sm text-[var(--dg-text-secondary)]">备注</Label>
|
||||
<Input className="mt-1" placeholder="可选" value={form.description} onChange={(e) => setForm({ ...form, description: e.target.value })} />
|
||||
<Label className="text-sm text-[var(--dg-text-secondary)]"> {i18n.t('monitor.contactGroup.notes')} </Label>
|
||||
<Input className="mt-1" placeholder={i18n.t('rbac.jobRole.placeholder.description')} value={form.description} onChange={(e) => setForm({ ...form, description: e.target.value })} />
|
||||
</div>
|
||||
</div>
|
||||
<DialogFooter>
|
||||
<Button variant="outline" onClick={() => onOpenChange(false)}>取消</Button>
|
||||
<Button variant="outline" onClick={() => onOpenChange(false)}> {i18n.t('rbac.jobRole.cancel')} </Button>
|
||||
<Button onClick={handleSave} disabled={submitting}>
|
||||
{submitting && <Loader2 className="h-4 w-4 mr-1 animate-spin" />}
|
||||
保存
|
||||
|
||||
@@ -24,6 +24,7 @@ import { toast } from 'sonner';
|
||||
import { billingApi } from '@/api';
|
||||
import { providerLabels } from './CloudBillingHelpers';
|
||||
import type { JsonData } from '@/types/common';
|
||||
import i18n from '@/i18n';
|
||||
|
||||
const emptyRule = { name: '', provider: '', metric: 'daily', threshold: '', operator: '>', enabled: true };
|
||||
|
||||
@@ -57,7 +58,7 @@ export function BillingRuleDialog({ open, onOpenChange, editingRule, onSuccess }
|
||||
|
||||
const handleSave = async () => {
|
||||
if (!form.name || !form.threshold) {
|
||||
toast.error('请填写规则名称和阈值');
|
||||
toast.error(i18n.t('cloud.billingruledial.sd36855b1'));
|
||||
return;
|
||||
}
|
||||
setSubmitting(true);
|
||||
@@ -72,7 +73,7 @@ export function BillingRuleDialog({ open, onOpenChange, editingRule, onSuccess }
|
||||
onSuccess();
|
||||
toast('保存成功');
|
||||
} catch (e) {
|
||||
toast.error('保存失败', { description: (e as JsonData).message });
|
||||
toast.error(i18n.t('kubernetes.msg.saveFailed'), { description: (e as JsonData).message });
|
||||
} finally {
|
||||
setSubmitting(false);
|
||||
}
|
||||
@@ -82,21 +83,21 @@ export function BillingRuleDialog({ open, onOpenChange, editingRule, onSuccess }
|
||||
<Dialog open={open} onOpenChange={onOpenChange}>
|
||||
<DialogContent className="max-w-md">
|
||||
<DialogHeader>
|
||||
<DialogTitle>{editingRule ? '编辑预警规则' : '添加预警规则'}</DialogTitle>
|
||||
<DialogDescription>设置成本阈值,超标时自动预警</DialogDescription>
|
||||
<DialogTitle>{editingRule ? i18n.t('cloud.billingruledial.sb8cfa0c9') : i18n.t('cloud.billingruledial.sd58c549a')}</DialogTitle>
|
||||
<DialogDescription> {i18n.t('cloud.billingruledial.s75227f20')} </DialogDescription>
|
||||
</DialogHeader>
|
||||
<div className="space-y-3">
|
||||
<div>
|
||||
<Label className="text-sm text-[var(--dg-text-secondary)]">规则名称 *</Label>
|
||||
<Input className="mt-1" placeholder="如:日成本超 500 元预警" value={form.name} onChange={(e) => setForm({ ...form, name: e.target.value })} />
|
||||
<Label className="text-sm text-[var(--dg-text-secondary)]"> {i18n.t('monitor.silenceDialog.ruleNameRequired')} </Label>
|
||||
<Input className="mt-1" placeholder={i18n.t('cloud.billingruledial.sc147ac4f')} value={form.name} onChange={(e) => setForm({ ...form, name: e.target.value })} />
|
||||
</div>
|
||||
<div className="grid grid-cols-2 gap-3">
|
||||
<div>
|
||||
<Label className="text-sm text-[var(--dg-text-secondary)]">厂商</Label>
|
||||
<Label className="text-sm text-[var(--dg-text-secondary)]"> {i18n.t('common.vendor')} </Label>
|
||||
<Select value={form.provider || 'all'} onValueChange={(v) => setForm({ ...form, provider: v === 'all' ? '' : v })}>
|
||||
<SelectTrigger className="mt-1"><SelectValue /></SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="all">全部厂商</SelectItem>
|
||||
<SelectItem value="all"> {i18n.t('cloud.billingruledial.sc356f198')} </SelectItem>
|
||||
{Object.entries(providerLabels).map(([k, v]) => (
|
||||
<SelectItem key={k} value={k}>{v}</SelectItem>
|
||||
))}
|
||||
@@ -104,41 +105,41 @@ export function BillingRuleDialog({ open, onOpenChange, editingRule, onSuccess }
|
||||
</Select>
|
||||
</div>
|
||||
<div>
|
||||
<Label className="text-sm text-[var(--dg-text-secondary)]">指标</Label>
|
||||
<Label className="text-sm text-[var(--dg-text-secondary)]"> {i18n.t('cloud.colMetric')} </Label>
|
||||
<Select value={form.metric} onValueChange={(v) => setForm({ ...form, metric: v })}>
|
||||
<SelectTrigger className="mt-1"><SelectValue /></SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="daily">日成本</SelectItem>
|
||||
<SelectItem value="monthly">月累计</SelectItem>
|
||||
<SelectItem value="daily"> {i18n.t('cloud.dailyCost')} </SelectItem>
|
||||
<SelectItem value="monthly"> {i18n.t('cloud.monthlyAccumulated')} </SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
</div>
|
||||
<div className="grid grid-cols-2 gap-3">
|
||||
<div>
|
||||
<Label className="text-sm text-[var(--dg-text-secondary)]">比较</Label>
|
||||
<Label className="text-sm text-[var(--dg-text-secondary)]"> {i18n.t('cloud.billingruledial.sd7650ece')} </Label>
|
||||
<Select value={form.operator} onValueChange={(v) => setForm({ ...form, operator: v })}>
|
||||
<SelectTrigger className="mt-1"><SelectValue /></SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value=">">大于 ></SelectItem>
|
||||
<SelectItem value=">=">大于等于 ≥</SelectItem>
|
||||
<SelectItem value="<">小于 <</SelectItem>
|
||||
<SelectItem value="<=">小于等于 ≤</SelectItem>
|
||||
<SelectItem value=">"> {i18n.t('cloud.billingruledial.s3dba9756')} </SelectItem>
|
||||
<SelectItem value=">="> {i18n.t('cloud.billingruledial.s8e1e26d1')} </SelectItem>
|
||||
<SelectItem value="<"> {i18n.t('cloud.billingruledial.s0196c18c')} </SelectItem>
|
||||
<SelectItem value="<="> {i18n.t('cloud.billingruledial.s45c301a8')} </SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
<div>
|
||||
<Label className="text-sm text-[var(--dg-text-secondary)]">阈值(元) *</Label>
|
||||
<Label className="text-sm text-[var(--dg-text-secondary)]"> {i18n.t('cloud.billingruledial.s11f9fb4c')} </Label>
|
||||
<Input type="number" step="0.01" className="mt-1" placeholder="500.00" value={form.threshold} onChange={(e) => setForm({ ...form, threshold: e.target.value })} />
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<Switch checked={form.enabled} onCheckedChange={(v) => setForm({ ...form, enabled: v })} />
|
||||
<Label className="text-sm text-[var(--dg-text-secondary)]">启用</Label>
|
||||
<Label className="text-sm text-[var(--dg-text-secondary)]"> {i18n.t('system.userActive')} </Label>
|
||||
</div>
|
||||
</div>
|
||||
<DialogFooter>
|
||||
<Button variant="outline" onClick={() => onOpenChange(false)}>取消</Button>
|
||||
<Button variant="outline" onClick={() => onOpenChange(false)}> {i18n.t('rbac.jobRole.cancel')} </Button>
|
||||
<Button onClick={handleSave} disabled={submitting}>
|
||||
{submitting && <Loader2 className="h-4 w-4 mr-1 animate-spin" />}
|
||||
保存
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import { type ReactNode } from 'react';
|
||||
import { TrendingUp, TrendingDown } from 'lucide-react';
|
||||
import i18n from '@/i18n';
|
||||
|
||||
// 云厂商中文标签(主组件 + 弹窗共享) // Logan.Li
|
||||
export const providerLabels: Record<string, string> = {
|
||||
aliyun: '阿里云',
|
||||
tencent: '腾讯云',
|
||||
aliyun: i18n.t('cloud.aliyun'),
|
||||
tencent: i18n.t('cloud.tencent'),
|
||||
aws: 'AWS',
|
||||
huawei: '华为云',
|
||||
huawei: i18n.t('cloud.huawei'),
|
||||
azure: 'Azure',
|
||||
};
|
||||
|
||||
@@ -69,7 +70,7 @@ export function StatCard({ icon, label, value, trend, trendLabel, alert }: {
|
||||
|
||||
export function TrendChart({ data }: { data: { date: string; cost: number }[] }) {
|
||||
if (data.length === 0) {
|
||||
return <p className="text-sm dg-text-muted py-8 text-center">暂无数据</p>;
|
||||
return <p className="text-sm dg-text-muted py-8 text-center"> {i18n.t('aiops.assistantNoData')} </p>;
|
||||
}
|
||||
const max = Math.max(...data.map((d) => d.cost), 1);
|
||||
const recent = data.slice(-30);
|
||||
|
||||
@@ -36,11 +36,12 @@ import { PageLoading } from '@/components/layout/PageLoading';
|
||||
import { PageEmpty } from '@/components/layout/PageEmpty';
|
||||
import { StatStrip } from '@/components/ui/stat-strip';
|
||||
import type { JsonData } from '@/types/common';
|
||||
import i18n from '@/i18n';
|
||||
|
||||
const typeLabels: Record<string, string> = {
|
||||
public: '公有云',
|
||||
private: '私有云',
|
||||
hybrid: '混合云',
|
||||
public: i18n.t('server.cloudserverimpo.s7ef31abb'),
|
||||
private: i18n.t('cloud.privateCloud'),
|
||||
hybrid: i18n.t('cloud.hybridCloud'),
|
||||
};
|
||||
|
||||
const typeColors: Record<string, string> = {
|
||||
@@ -137,7 +138,7 @@ export function PlatformManager() {
|
||||
<div className="relative w-72">
|
||||
<Search className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 dg-text-muted" />
|
||||
<Input
|
||||
placeholder="搜索平台名称或编码..."
|
||||
placeholder={i18n.t('cloud.platformmanager.s783a513f')}
|
||||
value={searchQuery}
|
||||
onChange={(e) => setSearchQuery(e.target.value)}
|
||||
className="pl-9 h-9 dg-input"
|
||||
@@ -148,10 +149,10 @@ export function PlatformManager() {
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="all">全部类型</SelectItem>
|
||||
<SelectItem value="public">公有云</SelectItem>
|
||||
<SelectItem value="private">私有云</SelectItem>
|
||||
<SelectItem value="hybrid">混合云</SelectItem>
|
||||
<SelectItem value="all"> {i18n.t('k8s.topology.allTypes')} </SelectItem>
|
||||
<SelectItem value="public"> {i18n.t('server.cloudserverimpo.s7ef31abb')} </SelectItem>
|
||||
<SelectItem value="private"> {i18n.t('cloud.privateCloud')} </SelectItem>
|
||||
<SelectItem value="hybrid"> {i18n.t('cloud.hybridCloud')} </SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
@@ -160,16 +161,16 @@ export function PlatformManager() {
|
||||
return (
|
||||
<PageShell
|
||||
variant="list"
|
||||
title="云平台管理"
|
||||
subtitle="管理公有云、私有云与混合云平台信息"
|
||||
title={i18n.t('cloud.title')}
|
||||
subtitle={i18n.t('cloud.platformmanager.s7012045f')}
|
||||
icon={<CloudCog className="h-5 w-5" />}
|
||||
metrics={
|
||||
!loading ? (
|
||||
<StatStrip
|
||||
items={[
|
||||
{ label: '总计', value: stats.total, color: 'blue' },
|
||||
{ label: '启用', value: stats.active, color: 'green' },
|
||||
{ label: '公有云', value: stats.public, color: 'cyan' },
|
||||
{ label: i18n.t('system.auditTotal'), value: stats.total, color: 'blue' },
|
||||
{ label: i18n.t('system.userActive'), value: stats.active, color: 'green' },
|
||||
{ label: i18n.t('server.cloudserverimpo.s7ef31abb'), value: stats.public, color: 'cyan' },
|
||||
]}
|
||||
/>
|
||||
) : undefined
|
||||
@@ -193,7 +194,7 @@ export function PlatformManager() {
|
||||
) : filtered.length === 0 ? (
|
||||
<PageEmpty
|
||||
icon={<CloudCog className="h-12 w-12" />}
|
||||
title="暂无云平台数据"
|
||||
title={i18n.t('cloud.platformmanager.sb9f478da')}
|
||||
action={(
|
||||
<Button size="sm" className="dg-btn-primary" onClick={openCreate}>
|
||||
<Plus className="h-4 w-4 mr-1" />
|
||||
@@ -260,26 +261,26 @@ export function PlatformManager() {
|
||||
<Dialog open={dialogOpen} onOpenChange={setDialogOpen}>
|
||||
<DialogContent>
|
||||
<DialogHeader>
|
||||
<DialogTitle>{editingItem ? '编辑云平台' : '添加云平台'}</DialogTitle>
|
||||
<DialogDescription className="sr-only">描述</DialogDescription>
|
||||
<DialogTitle>{editingItem ? i18n.t('cloud.platformmanager.sf83734ec') : i18n.t('cloud.platformmanager.s3f6f0cf2')}</DialogTitle>
|
||||
<DialogDescription className="sr-only"> {i18n.t('aiops.llmModelDesc')} </DialogDescription>
|
||||
</DialogHeader>
|
||||
<div className="space-y-4 py-2">
|
||||
<div className="grid grid-cols-2 gap-4">
|
||||
<div className="space-y-1.5">
|
||||
<Label>平台名称 *</Label>
|
||||
<Label> {i18n.t('cloud.platformmanager.seac7fc68')} </Label>
|
||||
<Input
|
||||
value={formData.name}
|
||||
onChange={(e) => setFormData({ ...formData, name: e.target.value })}
|
||||
placeholder="如:阿里云"
|
||||
placeholder={i18n.t('cloud.platformmanager.sa39d9635')}
|
||||
className="dg-input"
|
||||
/>
|
||||
</div>
|
||||
<div className="space-y-1.5">
|
||||
<Label>编码 *</Label>
|
||||
<Label> {i18n.t('cloud.platformmanager.se21e278f')} </Label>
|
||||
<Input
|
||||
value={formData.code}
|
||||
onChange={(e) => setFormData({ ...formData, code: e.target.value })}
|
||||
placeholder="如:aliyun"
|
||||
placeholder={i18n.t('cloud.platformmanager.s7b09b049')}
|
||||
className="dg-input"
|
||||
disabled={!!editingItem}
|
||||
/>
|
||||
@@ -287,33 +288,33 @@ export function PlatformManager() {
|
||||
</div>
|
||||
<div className="grid grid-cols-2 gap-4">
|
||||
<div className="space-y-1.5">
|
||||
<Label>类型</Label>
|
||||
<Label> {i18n.t('system.credentialType')} </Label>
|
||||
<Select value={formData.type} onValueChange={(v) => setFormData({ ...formData, type: v })}>
|
||||
<SelectTrigger className="dg-input">
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="public">公有云</SelectItem>
|
||||
<SelectItem value="private">私有云</SelectItem>
|
||||
<SelectItem value="hybrid">混合云</SelectItem>
|
||||
<SelectItem value="public"> {i18n.t('server.cloudserverimpo.s7ef31abb')} </SelectItem>
|
||||
<SelectItem value="private"> {i18n.t('cloud.privateCloud')} </SelectItem>
|
||||
<SelectItem value="hybrid"> {i18n.t('cloud.hybridCloud')} </SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
<div className="space-y-1.5">
|
||||
<Label>状态</Label>
|
||||
<Label> {i18n.t('system.terminalStatus')} </Label>
|
||||
<Select value={formData.status} onValueChange={(v) => setFormData({ ...formData, status: v })}>
|
||||
<SelectTrigger className="dg-input">
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="active">启用</SelectItem>
|
||||
<SelectItem value="inactive">禁用</SelectItem>
|
||||
<SelectItem value="active"> {i18n.t('system.userActive')} </SelectItem>
|
||||
<SelectItem value="inactive"> {i18n.t('system.userInactive')} </SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
</div>
|
||||
<div className="space-y-1.5">
|
||||
<Label>官网地址</Label>
|
||||
<Label> {i18n.t('cloud.platformmanager.saf587eb5')} </Label>
|
||||
<Input
|
||||
value={formData.website}
|
||||
onChange={(e) => setFormData({ ...formData, website: e.target.value })}
|
||||
@@ -322,20 +323,20 @@ export function PlatformManager() {
|
||||
/>
|
||||
</div>
|
||||
<div className="space-y-1.5">
|
||||
<Label>描述</Label>
|
||||
<Label> {i18n.t('aiops.llmModelDesc')} </Label>
|
||||
<Input
|
||||
value={formData.description}
|
||||
onChange={(e) => setFormData({ ...formData, description: e.target.value })}
|
||||
placeholder="平台描述..."
|
||||
placeholder={i18n.t('cloud.platformmanager.sc44dd421')}
|
||||
className="dg-input"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<DialogFooter>
|
||||
<Button variant="ghost" onClick={() => setDialogOpen(false)}>取消</Button>
|
||||
<Button variant="ghost" onClick={() => setDialogOpen(false)}> {i18n.t('rbac.jobRole.cancel')} </Button>
|
||||
<Button onClick={handleSubmit} disabled={submitting || !formData.name.trim() || !formData.code.trim()}>
|
||||
{submitting && <Loader2 className="h-4 w-4 mr-1 animate-spin" />}
|
||||
{editingItem ? '保存' : '创建'}
|
||||
{editingItem ? i18n.t('task.script.save') : i18n.t('rbac.jobRole.create')}
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
@@ -345,13 +346,13 @@ export function PlatformManager() {
|
||||
<Dialog open={deleteId !== null} onOpenChange={(v) => !v && setDeleteId(null)}>
|
||||
<DialogContent className="max-w-sm">
|
||||
<DialogHeader>
|
||||
<DialogTitle>确认删除</DialogTitle>
|
||||
<DialogDescription className="sr-only">描述</DialogDescription>
|
||||
<DialogTitle> {i18n.t('k8s.actionModal.confirmDelete')} </DialogTitle>
|
||||
<DialogDescription className="sr-only"> {i18n.t('aiops.llmModelDesc')} </DialogDescription>
|
||||
</DialogHeader>
|
||||
<p className="text-sm dg-text-secondary">确定删除此云平台?此操作不可撤销。</p>
|
||||
<p className="text-sm dg-text-secondary"> {i18n.t('cloud.platformmanager.s452abbb1')} </p>
|
||||
<DialogFooter>
|
||||
<Button variant="ghost" onClick={() => setDeleteId(null)}>取消</Button>
|
||||
<Button variant="destructive" onClick={confirmDelete}>删除</Button>
|
||||
<Button variant="ghost" onClick={() => setDeleteId(null)}> {i18n.t('rbac.jobRole.cancel')} </Button>
|
||||
<Button variant="destructive" onClick={confirmDelete}> {i18n.t('kubernetes.storage.delete2')} </Button>
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
Reference in new issue
Block a user