mirror of
https://github.com/Dokploy/dokploy.git
synced 2026-07-05 22:15:22 +02:00
feat(ui): add default "Dokploy" option to server selection dropdown - Add "Dokploy" as default option in server selection dropdowns - Hide dropdown when only one server is available (servers.length <= 1) - Show dropdown only when multiple servers exist (servers.length > 1) - Update placeholder text from "Select a Server" to "Dokploy" - Fix issue where users couldn't switch back to default server - Update form submission logic to handle "dokploy" default value - Apply changes to all deployment components (application, compose, template, database, certificate, AI) Resolves #1852
This commit is contained in:
@@ -95,7 +95,7 @@ export const AddApplication = ({ projectId, projectName }: Props) => {
|
||||
appName: data.appName,
|
||||
description: data.description,
|
||||
projectId,
|
||||
serverId: data.serverId,
|
||||
serverId: data.serverId === "dokploy" ? undefined : data.serverId,
|
||||
})
|
||||
.then(async () => {
|
||||
toast.success("Service Created");
|
||||
@@ -157,7 +157,7 @@ export const AddApplication = ({ projectId, projectName }: Props) => {
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
{hasServers && (
|
||||
{hasServers && servers.length > 1 && (
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="serverId"
|
||||
@@ -186,13 +186,21 @@ export const AddApplication = ({ projectId, projectName }: Props) => {
|
||||
|
||||
<Select
|
||||
onValueChange={field.onChange}
|
||||
defaultValue={field.value}
|
||||
defaultValue={field.value || "dokploy"}
|
||||
>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="Select a Server" />
|
||||
<SelectValue placeholder="Dokploy" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectGroup>
|
||||
<SelectItem value="dokploy">
|
||||
<span className="flex items-center gap-2 justify-between w-full">
|
||||
<span>Dokploy</span>
|
||||
<span className="text-muted-foreground text-xs self-center">
|
||||
Default
|
||||
</span>
|
||||
</span>
|
||||
</SelectItem>
|
||||
{servers?.map((server) => (
|
||||
<SelectItem
|
||||
key={server.serverId}
|
||||
@@ -206,7 +214,7 @@ export const AddApplication = ({ projectId, projectName }: Props) => {
|
||||
</span>
|
||||
</SelectItem>
|
||||
))}
|
||||
<SelectLabel>Servers ({servers?.length})</SelectLabel>
|
||||
<SelectLabel>Servers ({servers?.length + 1})</SelectLabel>
|
||||
</SelectGroup>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
|
||||
@@ -101,7 +101,7 @@ export const AddCompose = ({ projectId, projectName }: Props) => {
|
||||
projectId,
|
||||
composeType: data.composeType,
|
||||
appName: data.appName,
|
||||
serverId: data.serverId,
|
||||
serverId: data.serverId === "dokploy" ? undefined : data.serverId,
|
||||
})
|
||||
.then(async () => {
|
||||
toast.success("Compose Created");
|
||||
@@ -165,7 +165,7 @@ export const AddCompose = ({ projectId, projectName }: Props) => {
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
{hasServers && (
|
||||
{hasServers && servers.length > 1 && (
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="serverId"
|
||||
@@ -194,13 +194,21 @@ export const AddCompose = ({ projectId, projectName }: Props) => {
|
||||
|
||||
<Select
|
||||
onValueChange={field.onChange}
|
||||
defaultValue={field.value}
|
||||
defaultValue={field.value || "dokploy"}
|
||||
>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="Select a Server" />
|
||||
<SelectValue placeholder="Dokploy" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectGroup>
|
||||
<SelectItem value="dokploy">
|
||||
<span className="flex items-center gap-2 justify-between w-full">
|
||||
<span>Dokploy</span>
|
||||
<span className="text-muted-foreground text-xs self-center">
|
||||
Default
|
||||
</span>
|
||||
</span>
|
||||
</SelectItem>
|
||||
{servers?.map((server) => (
|
||||
<SelectItem
|
||||
key={server.serverId}
|
||||
@@ -214,7 +222,7 @@ export const AddCompose = ({ projectId, projectName }: Props) => {
|
||||
</span>
|
||||
</SelectItem>
|
||||
))}
|
||||
<SelectLabel>Servers ({servers?.length})</SelectLabel>
|
||||
<SelectLabel>Servers ({servers?.length + 1})</SelectLabel>
|
||||
</SelectGroup>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
|
||||
@@ -220,7 +220,7 @@ export const AddDatabase = ({ projectId, projectName }: Props) => {
|
||||
appName: data.appName,
|
||||
dockerImage: defaultDockerImage,
|
||||
projectId,
|
||||
serverId: data.serverId,
|
||||
serverId: data.serverId === "dokploy" ? undefined : data.serverId,
|
||||
description: data.description,
|
||||
};
|
||||
|
||||
@@ -232,7 +232,7 @@ export const AddDatabase = ({ projectId, projectName }: Props) => {
|
||||
|
||||
databaseUser:
|
||||
data.databaseUser || databasesUserDefaultPlaceholder[data.type],
|
||||
serverId: data.serverId,
|
||||
serverId: data.serverId === "dokploy" ? undefined : data.serverId,
|
||||
});
|
||||
} else if (data.type === "mongo") {
|
||||
promise = mongoMutation.mutateAsync({
|
||||
@@ -240,14 +240,14 @@ export const AddDatabase = ({ projectId, projectName }: Props) => {
|
||||
databasePassword: data.databasePassword,
|
||||
databaseUser:
|
||||
data.databaseUser || databasesUserDefaultPlaceholder[data.type],
|
||||
serverId: data.serverId,
|
||||
serverId: data.serverId === "dokploy" ? undefined : data.serverId,
|
||||
replicaSets: data.replicaSets,
|
||||
});
|
||||
} else if (data.type === "redis") {
|
||||
promise = redisMutation.mutateAsync({
|
||||
...commonParams,
|
||||
databasePassword: data.databasePassword,
|
||||
serverId: data.serverId,
|
||||
serverId: data.serverId === "dokploy" ? undefined : data.serverId,
|
||||
projectId,
|
||||
});
|
||||
} else if (data.type === "mariadb") {
|
||||
@@ -258,7 +258,7 @@ export const AddDatabase = ({ projectId, projectName }: Props) => {
|
||||
databaseName: data.databaseName || "mariadb",
|
||||
databaseUser:
|
||||
data.databaseUser || databasesUserDefaultPlaceholder[data.type],
|
||||
serverId: data.serverId,
|
||||
serverId: data.serverId === "dokploy" ? undefined : data.serverId,
|
||||
});
|
||||
} else if (data.type === "mysql") {
|
||||
promise = mysqlMutation.mutateAsync({
|
||||
@@ -268,7 +268,7 @@ export const AddDatabase = ({ projectId, projectName }: Props) => {
|
||||
databaseUser:
|
||||
data.databaseUser || databasesUserDefaultPlaceholder[data.type],
|
||||
databaseRootPassword: data.databaseRootPassword,
|
||||
serverId: data.serverId,
|
||||
serverId: data.serverId === "dokploy" ? undefined : data.serverId,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -398,7 +398,7 @@ export const AddDatabase = ({ projectId, projectName }: Props) => {
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
{hasServers && (
|
||||
{hasServers && servers.length > 1 && (
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="serverId"
|
||||
@@ -407,13 +407,21 @@ export const AddDatabase = ({ projectId, projectName }: Props) => {
|
||||
<FormLabel>Select a Server</FormLabel>
|
||||
<Select
|
||||
onValueChange={field.onChange}
|
||||
defaultValue={field.value || ""}
|
||||
defaultValue={field.value || "dokploy"}
|
||||
>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="Select a Server" />
|
||||
<SelectValue placeholder="Dokploy" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectGroup>
|
||||
<SelectItem value="dokploy">
|
||||
<span className="flex items-center gap-2 justify-between w-full">
|
||||
<span>Dokploy</span>
|
||||
<span className="text-muted-foreground text-xs self-center">
|
||||
Default
|
||||
</span>
|
||||
</span>
|
||||
</SelectItem>
|
||||
{servers?.map((server) => (
|
||||
<SelectItem
|
||||
key={server.serverId}
|
||||
@@ -423,7 +431,7 @@ export const AddDatabase = ({ projectId, projectName }: Props) => {
|
||||
</SelectItem>
|
||||
))}
|
||||
<SelectLabel>
|
||||
Servers ({servers?.length})
|
||||
Servers ({servers?.length + 1})
|
||||
</SelectLabel>
|
||||
</SelectGroup>
|
||||
</SelectContent>
|
||||
|
||||
@@ -427,7 +427,7 @@ export const AddTemplate = ({ projectId, baseUrl }: Props) => {
|
||||
project.
|
||||
</AlertDialogDescription>
|
||||
|
||||
{hasServers && (
|
||||
{hasServers && servers.length > 1 && (
|
||||
<div>
|
||||
<TooltipProvider delayDuration={0}>
|
||||
<Tooltip>
|
||||
@@ -456,12 +456,21 @@ export const AddTemplate = ({ projectId, baseUrl }: Props) => {
|
||||
onValueChange={(e) => {
|
||||
setServerId(e);
|
||||
}}
|
||||
defaultValue="dokploy"
|
||||
>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="Select a Server" />
|
||||
<SelectValue placeholder="Dokploy" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectGroup>
|
||||
<SelectItem value="dokploy">
|
||||
<span className="flex items-center gap-2 justify-between w-full">
|
||||
<span>Dokploy</span>
|
||||
<span className="text-muted-foreground text-xs self-center">
|
||||
Default
|
||||
</span>
|
||||
</span>
|
||||
</SelectItem>
|
||||
{servers?.map((server) => (
|
||||
<SelectItem
|
||||
key={server.serverId}
|
||||
@@ -476,7 +485,7 @@ export const AddTemplate = ({ projectId, baseUrl }: Props) => {
|
||||
</SelectItem>
|
||||
))}
|
||||
<SelectLabel>
|
||||
Servers ({servers?.length})
|
||||
Servers ({servers?.length + 1})
|
||||
</SelectLabel>
|
||||
</SelectGroup>
|
||||
</SelectContent>
|
||||
@@ -491,7 +500,7 @@ export const AddTemplate = ({ projectId, baseUrl }: Props) => {
|
||||
onClick={async () => {
|
||||
const promise = mutateAsync({
|
||||
projectId,
|
||||
serverId: serverId || undefined,
|
||||
serverId: serverId === "dokploy" ? undefined : serverId,
|
||||
id: template.id,
|
||||
baseUrl: customBaseUrl,
|
||||
});
|
||||
|
||||
@@ -48,34 +48,49 @@ export const StepOne = ({ setTemplateInfo, templateInfo }: any) => {
|
||||
/>
|
||||
</div>
|
||||
|
||||
{hasServers && (
|
||||
{hasServers && servers.length > 1 && (
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="server-deploy">
|
||||
Select the server where you want to deploy (optional)
|
||||
</Label>
|
||||
<Select
|
||||
value={templateInfo.server?.serverId}
|
||||
value={templateInfo.server?.serverId || "dokploy"}
|
||||
onValueChange={(value) => {
|
||||
const server = servers?.find((s) => s.serverId === value);
|
||||
if (server) {
|
||||
if (value === "dokploy") {
|
||||
setTemplateInfo({
|
||||
...templateInfo,
|
||||
server: server,
|
||||
server: undefined,
|
||||
});
|
||||
} else {
|
||||
const server = servers?.find((s) => s.serverId === value);
|
||||
if (server) {
|
||||
setTemplateInfo({
|
||||
...templateInfo,
|
||||
server: server,
|
||||
});
|
||||
}
|
||||
}
|
||||
}}
|
||||
>
|
||||
<SelectTrigger className="w-full">
|
||||
<SelectValue placeholder="Select a server" />
|
||||
<SelectValue placeholder="Dokploy" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectGroup>
|
||||
<SelectItem value="dokploy">
|
||||
<span className="flex items-center gap-2 justify-between w-full">
|
||||
<span>Dokploy</span>
|
||||
<span className="text-muted-foreground text-xs self-center">
|
||||
Default
|
||||
</span>
|
||||
</span>
|
||||
</SelectItem>
|
||||
{servers?.map((server) => (
|
||||
<SelectItem key={server.serverId} value={server.serverId}>
|
||||
{server.name}
|
||||
</SelectItem>
|
||||
))}
|
||||
<SelectLabel>Servers ({servers?.length})</SelectLabel>
|
||||
<SelectLabel>Servers ({servers?.length + 1})</SelectLabel>
|
||||
</SelectGroup>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
|
||||
@@ -65,6 +65,7 @@ export const AddCertificate = () => {
|
||||
const { mutateAsync, isError, error, isLoading } =
|
||||
api.certificates.create.useMutation();
|
||||
const { data: servers } = api.server.withSSHKey.useQuery();
|
||||
const hasServers = servers && servers.length > 0;
|
||||
|
||||
const form = useForm<AddCertificate>({
|
||||
defaultValues: {
|
||||
@@ -85,7 +86,7 @@ export const AddCertificate = () => {
|
||||
certificateData: data.certificateData,
|
||||
privateKey: data.privateKey,
|
||||
autoRenew: data.autoRenew,
|
||||
serverId: data.serverId,
|
||||
serverId: data.serverId === "dokploy" ? undefined : data.serverId,
|
||||
organizationId: "",
|
||||
})
|
||||
.then(async () => {
|
||||
@@ -174,52 +175,62 @@ export const AddCertificate = () => {
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="serverId"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<TooltipProvider delayDuration={0}>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<FormLabel className="break-all w-fit flex flex-row gap-1 items-center">
|
||||
Select a Server {!isCloud && "(Optional)"}
|
||||
<HelpCircle className="size-4 text-muted-foreground" />
|
||||
</FormLabel>
|
||||
</TooltipTrigger>
|
||||
</Tooltip>
|
||||
</TooltipProvider>
|
||||
{hasServers && servers.length > 1 && (
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="serverId"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<TooltipProvider delayDuration={0}>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<FormLabel className="break-all w-fit flex flex-row gap-1 items-center">
|
||||
Select a Server {!isCloud && "(Optional)"}
|
||||
<HelpCircle className="size-4 text-muted-foreground" />
|
||||
</FormLabel>
|
||||
</TooltipTrigger>
|
||||
</Tooltip>
|
||||
</TooltipProvider>
|
||||
|
||||
<Select
|
||||
onValueChange={field.onChange}
|
||||
defaultValue={field.value}
|
||||
>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="Select a Server" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectGroup>
|
||||
{servers?.map((server) => (
|
||||
<SelectItem
|
||||
key={server.serverId}
|
||||
value={server.serverId}
|
||||
>
|
||||
<Select
|
||||
onValueChange={field.onChange}
|
||||
defaultValue={field.value || "dokploy"}
|
||||
>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="Dokploy" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectGroup>
|
||||
<SelectItem value="dokploy">
|
||||
<span className="flex items-center gap-2 justify-between w-full">
|
||||
<span>{server.name}</span>
|
||||
<span>Dokploy</span>
|
||||
<span className="text-muted-foreground text-xs self-center">
|
||||
{server.ipAddress}
|
||||
Default
|
||||
</span>
|
||||
</span>
|
||||
</SelectItem>
|
||||
))}
|
||||
<SelectLabel>Servers ({servers?.length})</SelectLabel>
|
||||
</SelectGroup>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
{servers?.map((server) => (
|
||||
<SelectItem
|
||||
key={server.serverId}
|
||||
value={server.serverId}
|
||||
>
|
||||
<span className="flex items-center gap-2 justify-between w-full">
|
||||
<span>{server.name}</span>
|
||||
<span className="text-muted-foreground text-xs self-center">
|
||||
{server.ipAddress}
|
||||
</span>
|
||||
</span>
|
||||
</SelectItem>
|
||||
))}
|
||||
<SelectLabel>Servers ({servers?.length + 1})</SelectLabel>
|
||||
</SelectGroup>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
</form>
|
||||
|
||||
<DialogFooter className="flex w-full flex-row !justify-end">
|
||||
|
||||
Reference in New Issue
Block a user