- 支持 Windows Agent 构建、安装脚本和统一上报协议 - 增强 RDP 剪贴板、虚拟盘和文件传输能力 - 新增 AIOps 上下文工具、告警 RCA trace 落库和回放接口 - 重构 docs 模块文档并补充终端、堡垒机、监控、AI Agent 设计
103 lines
3.9 KiB
TypeScript
103 lines
3.9 KiB
TypeScript
import { useTranslation } from 'react-i18next';
|
|
import { Input } from '@/components/ui/input';
|
|
import type { Credential } from '@/components/deploy/credential-manager/types';
|
|
|
|
interface ImportCredentialSettingsProps {
|
|
defaultSshPort: string;
|
|
onDefaultSshPortChange: (value: string) => void;
|
|
sshCredentials: Credential[];
|
|
rdpCredentials: Credential[];
|
|
selectedSshCredentialId: string;
|
|
selectedRdpCredentialId: string;
|
|
onSelectedSshCredentialIdChange: (value: string) => void;
|
|
onSelectedRdpCredentialIdChange: (value: string) => void;
|
|
compact?: boolean;
|
|
}
|
|
|
|
function credentialLabel(cred: Credential) {
|
|
return `${cred.name}${cred.summary ? ` · ${cred.summary}` : ''}`;
|
|
}
|
|
|
|
export function ImportCredentialSettings({
|
|
defaultSshPort,
|
|
onDefaultSshPortChange,
|
|
sshCredentials,
|
|
rdpCredentials,
|
|
selectedSshCredentialId,
|
|
selectedRdpCredentialId,
|
|
onSelectedSshCredentialIdChange,
|
|
onSelectedRdpCredentialIdChange,
|
|
compact = false,
|
|
}: ImportCredentialSettingsProps) {
|
|
const { t } = useTranslation();
|
|
const labelClass = compact
|
|
? 'block text-xs font-medium text-[var(--dg-text-secondary)] mb-1'
|
|
: 'block text-sm font-medium text-[var(--dg-text-secondary)] mb-2';
|
|
const panelClass = compact
|
|
? 'grid grid-cols-1 sm:grid-cols-3 gap-4 p-4 rounded-lg bg-[var(--dg-bg-secondary)] border border-[var(--dg-border)]'
|
|
: 'grid grid-cols-1 md:grid-cols-3 gap-4';
|
|
const inputBg = compact ? 'bg-[var(--dg-bg-tertiary)]' : 'bg-[var(--dg-bg-secondary)]';
|
|
|
|
return (
|
|
<div className={panelClass}>
|
|
<div>
|
|
<label className={labelClass}>
|
|
{t('server.importCred.sshPort')}
|
|
<span className="text-[var(--dg-text-muted)] ml-1">{t('server.importCred.linuxDefault')}</span>
|
|
</label>
|
|
<Input
|
|
type="number"
|
|
placeholder="22"
|
|
value={defaultSshPort}
|
|
onChange={(e) => onDefaultSshPortChange(e.target.value)}
|
|
className={`w-32 ${inputBg} border-[var(--dg-border)] text-[var(--dg-text-primary)]`}
|
|
/>
|
|
</div>
|
|
<div>
|
|
<label className={labelClass}>
|
|
{t('server.importCred.sshCredential')}
|
|
<span className="text-[var(--dg-text-muted)] ml-1">{t('server.importCred.optional')}</span>
|
|
</label>
|
|
{sshCredentials.length === 0 ? (
|
|
<p className="text-xs text-[var(--dg-text-muted)] py-2">{t('server.importCred.noSshCred')}</p>
|
|
) : (
|
|
<select
|
|
value={selectedSshCredentialId}
|
|
onChange={(e) => onSelectedSshCredentialIdChange(e.target.value)}
|
|
className={`w-full px-3 py-2 ${inputBg} border border-[var(--dg-border)] rounded-md text-[var(--dg-text-primary)] text-sm`}
|
|
>
|
|
<option value="">{t('server.importCred.noCredential')}</option>
|
|
{sshCredentials.map((cred) => (
|
|
<option key={cred.id} value={String(cred.id)}>
|
|
{credentialLabel(cred)}
|
|
</option>
|
|
))}
|
|
</select>
|
|
)}
|
|
</div>
|
|
<div>
|
|
<label className={labelClass}>
|
|
{t('server.importCred.rdpPassword')}
|
|
<span className="text-[var(--dg-text-muted)] ml-1">{t('server.importCred.optional')}</span>
|
|
</label>
|
|
{rdpCredentials.length === 0 ? (
|
|
<p className="text-xs text-[var(--dg-text-muted)] py-2">{t('server.importCred.noRdpCred')}</p>
|
|
) : (
|
|
<select
|
|
value={selectedRdpCredentialId}
|
|
onChange={(e) => onSelectedRdpCredentialIdChange(e.target.value)}
|
|
className={`w-full px-3 py-2 ${inputBg} border border-[var(--dg-border)] rounded-md text-[var(--dg-text-primary)] text-sm`}
|
|
>
|
|
<option value="">{t('server.importCred.noCredential')}</option>
|
|
{rdpCredentials.map((cred) => (
|
|
<option key={cred.id} value={String(cred.id)}>
|
|
{credentialLabel(cred)}
|
|
</option>
|
|
))}
|
|
</select>
|
|
)}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|