Merge pull request #1820 from Dokploy/1818-supporting-non-english-letters-in-the-title-when-creating-an-application-service

Refactor appName generation in dashboard components
This commit is contained in:
Mauricio Siu 2025-05-04 20:19:54 -06:00 committed by GitHub
commit b84b4549a0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 23 additions and 18 deletions

View File

@ -145,10 +145,8 @@ export const AddApplication = ({ projectId, projectName }: Props) => {
{...field} {...field}
onChange={(e) => { onChange={(e) => {
const val = e.target.value?.trim() || ""; const val = e.target.value?.trim() || "";
form.setValue( const serviceName = slugify(val);
"appName", form.setValue("appName", `${slug}-${serviceName}`);
`${slug}-${val.toLowerCase().replaceAll(" ", "-")}`,
);
field.onChange(val); field.onChange(val);
}} }}
/> />

View File

@ -152,10 +152,8 @@ export const AddCompose = ({ projectId, projectName }: Props) => {
{...field} {...field}
onChange={(e) => { onChange={(e) => {
const val = e.target.value?.trim() || ""; const val = e.target.value?.trim() || "";
form.setValue( const serviceName = slugify(val);
"appName", form.setValue("appName", `${slug}-${serviceName}`);
`${slug}-${val.toLowerCase()}`,
);
field.onChange(val); field.onChange(val);
}} }}
/> />

View File

@ -363,10 +363,8 @@ export const AddDatabase = ({ projectId, projectName }: Props) => {
{...field} {...field}
onChange={(e) => { onChange={(e) => {
const val = e.target.value?.trim() || ""; const val = e.target.value?.trim() || "";
form.setValue( const serviceName = slugify(val);
"appName", form.setValue("appName", `${slug}-${serviceName}`);
`${slug}-${val.toLowerCase()}`,
);
field.onChange(val); field.onChange(val);
}} }}
/> />

View File

@ -33,12 +33,23 @@ import { z } from "zod";
const AddProjectSchema = z.object({ const AddProjectSchema = z.object({
name: z name: z
.string() .string()
.min(1, { .min(1, "Project name is required")
message: "Name is required", .refine(
}) (name) => {
.regex(/^[a-zA-Z]/, { const trimmedName = name.trim();
const validNameRegex =
/^[\p{L}\p{N}_-][\p{L}\p{N}\s_-]*[\p{L}\p{N}_-]$/u;
return validNameRegex.test(trimmedName);
},
{
message:
"Project name must start and end with a letter, number, hyphen or underscore. Spaces are allowed in between.",
},
)
.refine((name) => !/^\d/.test(name.trim()), {
message: "Project name cannot start with a number", message: "Project name cannot start with a number",
}), })
.transform((name) => name.trim()),
description: z.string().optional(), description: z.string().optional(),
}); });

View File

@ -5,7 +5,7 @@ export const slugify = (text: string | undefined) => {
return ""; return "";
} }
const cleanedText = text.trim().replace(/[^a-zA-Z0-9\s]/g, ""); const cleanedText = text.trim().replace(/[^a-zA-Z0-9\s]/g, "") || "service";
return slug(cleanedText, { return slug(cleanedText, {
lower: true, lower: true,