feat(domain): improve domain form UX

- Make name field optional (defaults to domain if empty)
- Simplify domain placeholder and error messages
- Add test connection button for credential validation before save
This commit is contained in:
2026-03-12 11:03:52 +08:00
parent 8b0805bebf
commit c903733f2c
7 changed files with 289 additions and 36 deletions

View File

@@ -64,11 +64,23 @@ const DomainForm: React.FC<DomainFormProps> = ({ open, onClose, domainId }) => {
try {
const values = await form.validateFields();
// Process domain: remove protocol prefix and trailing slashes
let processedDomain = values.domain.trim();
if (processedDomain.startsWith("https://")) {
processedDomain = processedDomain.slice(8);
} else if (processedDomain.startsWith("http://")) {
processedDomain = processedDomain.slice(7);
}
processedDomain = processedDomain.replace(/\/+$/, "");
// Use domain as name if name is empty
const name = values.name?.trim() || processedDomain;
if (isEdit && editingDomain) {
const params: UpdateDomainParams = {
id: domainId,
name: values.name,
domain: values.domain,
name,
domain: processedDomain,
username: values.username,
authType: values.authType,
apiToken:
@@ -89,8 +101,8 @@ const DomainForm: React.FC<DomainFormProps> = ({ open, onClose, domainId }) => {
}
} else {
const params: CreateDomainParams = {
name: values.name,
domain: values.domain,
name,
domain: processedDomain,
username: values.username,
password: values.password,
authType: values.authType,
@@ -112,6 +124,48 @@ const DomainForm: React.FC<DomainFormProps> = ({ open, onClose, domainId }) => {
};
const authType = Form.useWatch("authType", form);
const [testing, setTesting] = React.useState(false);
// Test connection with current form values
const handleTestConnection = async () => {
try {
const values = await form.validateFields([
"domain",
"username",
"authType",
"password",
"apiToken",
]);
// Process domain
let processedDomain = values.domain.trim();
if (processedDomain.startsWith("https://")) {
processedDomain = processedDomain.slice(8);
} else if (processedDomain.startsWith("http://")) {
processedDomain = processedDomain.slice(7);
}
processedDomain = processedDomain.replace(/\/+$/, "");
setTesting(true);
const result = await window.api.testDomainConnection({
domain: processedDomain,
username: values.username,
authType: values.authType,
password: values.authType === "password" ? values.password : undefined,
apiToken: values.authType === "api_token" ? values.apiToken : undefined,
});
if (result.success) {
message.success("连接成功");
} else {
message.error(result.error || "连接失败");
}
} catch (error) {
console.error("Test connection failed:", error);
} finally {
setTesting(false);
}
};
return (
<Modal
@@ -128,13 +182,8 @@ const DomainForm: React.FC<DomainFormProps> = ({ open, onClose, domainId }) => {
className={styles.form}
initialValues={{ authType: "password" }}
>
<Form.Item
name="name"
label="名称"
rules={[{ required: true, message: "请输入名称" }]}
>
<Input placeholder="例如:生产环境" />
</Form.Item>
<Form.Item name="name" label="名称" style={{ marginTop: 8 }}>
<Input placeholder="可选,留空则使用域名" />
<Form.Item
name="domain"
@@ -142,23 +191,35 @@ const DomainForm: React.FC<DomainFormProps> = ({ open, onClose, domainId }) => {
rules={[
{ required: true, message: "请输入域名" },
{
pattern: /^[\w.-]+$/,
message: "请输入有效的域名例如company.kintone.com",
validator: (_, value) => {
if (!value) return Promise.resolve();
// Allow https:// or http:// prefix
let domain = value.trim();
if (domain.startsWith("https://")) {
domain = domain.slice(8);
} else if (domain.startsWith("http://")) {
domain = domain.slice(7);
}
// Remove trailing slashes
domain = domain.replace(/\/+$/, "");
// Validate domain format
if (/^[\w.-]+$/.test(domain)) {
return Promise.resolve();
}
return Promise.reject(new Error("请输入有效的域名"));
},
},
]}
>
<Input placeholder="例如:company.kintone.com" />
<Input placeholder="https://company.kintone.com" />
</Form.Item>
<Form.Item
name="username"
label="用户名"
rules={[
{ required: true, message: "请输入用户名" },
{ type: "email", message: "请输入有效的邮箱地址" },
]}
rules={[{ required: true, message: "请输入用户名" }]}
>
<Input placeholder="登录 Kintone 的邮箱地址" />
<Input placeholder="登录 Kintone 的用户名" />
</Form.Item>
<Form.Item
@@ -197,6 +258,9 @@ const DomainForm: React.FC<DomainFormProps> = ({ open, onClose, domainId }) => {
<Form.Item style={{ marginTop: 24, marginBottom: 0 }}>
<Space style={{ width: "100%", justifyContent: "flex-end" }}>
<Button onClick={onClose}></Button>
<Button onClick={handleTestConnection} loading={testing}>
</Button>
<Button type="primary" onClick={handleSubmit} loading={loading}>
{isEdit ? "更新" : "创建"}
</Button>