Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add AI Assistant and Settings to Dokploy #1070

Closed
wants to merge 9 commits into from
Closed
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,19 @@ import {
FormMessage,
} from "@/components/ui/form";
import { Input } from "@/components/ui/input";
import { api } from "@/utils/api";
import { zodResolver } from "@hookform/resolvers/zod";
import React, { useEffect } from "react";
import { useForm } from "react-hook-form";
import { toast } from "sonner";
import { z } from "zod";
import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
} from "@/components/ui/tooltip";
import { api } from "@/utils/api";
import { zodResolver } from "@hookform/resolvers/zod";
import { InfoIcon } from "lucide-react";
import React, { useEffect } from "react";
import { useForm } from "react-hook-form";
import { toast } from "sonner";
import { z } from "zod";

const addResourcesApplication = z.object({
memoryReservation: z.number().nullable().optional(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,7 @@ export const AddDomain = ({

const dictionary = {
success: domainId ? "Domain Updated" : "Domain Created",
error: domainId
? "Error updating the domain"
: "Error creating the domain",
error: domainId ? "Error updating the domain" : "Error creating the domain",
submit: domainId ? "Update" : "Create",
dialogDescription: domainId
? "In this section you can edit a domain"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,7 @@ export const AddPreviewDomain = ({

const dictionary = {
success: domainId ? "Domain Updated" : "Domain Created",
error: domainId
? "Error updating the domain"
: "Error creating the domain",
error: domainId ? "Error updating the domain" : "Error creating the domain",
submit: domainId ? "Update" : "Create",
dialogDescription: domainId
? "In this section you can edit a domain"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,9 +126,7 @@ export const AddDomainCompose = ({

const dictionary = {
success: domainId ? "Domain Updated" : "Domain Created",
error: domainId
? "Error updating the domain"
: "Error creating the domain",
error: domainId ? "Error updating the domain" : "Error creating the domain",
submit: domainId ? "Update" : "Create",
dialogDescription: domainId
? "In this section you can edit a domain"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@ import {
FormMessage,
} from "@/components/ui/form";
import { Input } from "@/components/ui/input";
import { api } from "@/utils/api";
import { zodResolver } from "@hookform/resolvers/zod";
import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
TooltipContent,
Tooltip,
} from "@/components/ui/tooltip";
import { api } from "@/utils/api";
import { zodResolver } from "@hookform/resolvers/zod";
import { InfoIcon } from "lucide-react";
import React, { useEffect } from "react";
import { useForm } from "react-hook-form";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,16 @@ import {
FormMessage,
} from "@/components/ui/form";
import { Input } from "@/components/ui/input";
import { api } from "@/utils/api";
import { zodResolver } from "@hookform/resolvers/zod";
import React, { useEffect } from "react";
import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
TooltipContent,
Tooltip,
} from "@/components/ui/tooltip";
import { api } from "@/utils/api";
import { zodResolver } from "@hookform/resolvers/zod";
import { InfoIcon } from "lucide-react";
import React, { useEffect } from "react";
import { useForm } from "react-hook-form";
import { toast } from "sonner";
import { z } from "zod";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,17 @@ import {
FormMessage,
} from "@/components/ui/form";
import { Input } from "@/components/ui/input";
import { api } from "@/utils/api";
import { zodResolver } from "@hookform/resolvers/zod";
import React, { useEffect } from "react";
import { useForm } from "react-hook-form";
import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
TooltipContent,
Tooltip,
} from "@/components/ui/tooltip";
import { api } from "@/utils/api";
import { zodResolver } from "@hookform/resolvers/zod";
import { InfoIcon } from "lucide-react";
import React, { useEffect } from "react";
import { useForm } from "react-hook-form";
import { toast } from "sonner";
import { z } from "zod";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,18 @@ import {
FormMessage,
} from "@/components/ui/form";
import { Input } from "@/components/ui/input";
import { api } from "@/utils/api";
import { zodResolver } from "@hookform/resolvers/zod";
import React, { useEffect } from "react";
import { useForm } from "react-hook-form";
import { toast } from "sonner";
import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
TooltipContent,
Tooltip,
} from "@/components/ui/tooltip";
import { api } from "@/utils/api";
import { zodResolver } from "@hookform/resolvers/zod";
import { InfoIcon } from "lucide-react";
import React, { useEffect } from "react";
import { useForm } from "react-hook-form";
import { toast } from "sonner";
import { z } from "zod";

const addResourcesPostgres = z.object({
Expand Down
10 changes: 10 additions & 0 deletions apps/dokploy/components/dashboard/project/add-ai-assistant.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { TemplateGenerator } from "@/components/dashboard/project/ai/template-generator";

interface Props {
projectId: string;
projectName?: string;
}

export const AddAiAssistant = ({ projectId }: Props) => {
return <TemplateGenerator projectId={projectId} />;
};
92 changes: 92 additions & 0 deletions apps/dokploy/components/dashboard/project/ai/step-four.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import { Button } from "@/components/ui/button";
import { ScrollArea } from "@/components/ui/scroll-area";
import dynamic from "next/dynamic";
import ReactMarkdown from "react-markdown";

const MonacoEditor = dynamic(() => import("@monaco-editor/react"), {
ssr: false,
});

export function StepFour({
prevStep,
templateInfo,
setOpen,
setTemplateInfo,
}: any) {
const handleSubmit = () => {
setTemplateInfo(templateInfo); // Update the template info
setOpen(false);
};

return (
<div className="flex flex-col h-full">
<div className="flex-grow">
<div className="space-y-6 pb-20">
<h2 className="text-lg font-semibold">Step 4: Review and Finalize</h2>
<ScrollArea className="h-[400px] p-5">
<div className="space-y-4">
<div className="p-4">
<ReactMarkdown className="prose dark:prose-invert">
{templateInfo.details.description}
</ReactMarkdown>
</div>
<div>
<h3 className="text-md font-semibold">Name</h3>
<p>{templateInfo.name}</p>
</div>
<div>
<h3 className="text-md font-semibold">Server</h3>
<p>{templateInfo.server || "localhost"}</p>
</div>
<div>
<h3 className="text-md font-semibold">Docker Compose</h3>
<MonacoEditor
height="200px"
language="yaml"
theme="vs-dark"
value={templateInfo.details.dockerCompose}
options={{
minimap: { enabled: false },
scrollBeyondLastLine: false,
fontSize: 14,
lineNumbers: "on",
readOnly: true,
wordWrap: "on",
automaticLayout: true,
}}
/>
</div>
<div>
<h3 className="text-md font-semibold">Environment Variables</h3>
<ul className="list-disc pl-5">
{templateInfo.details.envVariables.map(
(
env: {
name: string;
value: string;
},
index: number,
) => (
<li key={index}>
<strong>{env.name}</strong>:
<span className="ml-2 font-mono">{env.value}</span>
</li>
),
)}
</ul>
</div>
</div>
</ScrollArea>
</div>
</div>
<div className="sticky bottom-0 bg-background pt-2 border-t">
<div className="flex justify-between">
<Button onClick={prevStep} variant="outline">
Back
</Button>
<Button onClick={handleSubmit}>Create</Button>
</div>
</div>
</div>
);
}
69 changes: 69 additions & 0 deletions apps/dokploy/components/dashboard/project/ai/step-one.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
"use client";

import { Button } from "@/components/ui/button";
import { Label } from "@/components/ui/label";
import { Textarea } from "@/components/ui/textarea";
import { useState } from "react";

const examples = [
"Make a personal blog",
"Add a photo studio portfolio",
"Create a personal ad blocker",
"Build a social media dashboard",
"Sendgrid service opensource analogue",
];

export function StepOne({ nextStep, setTemplateInfo, templateInfo }: any) {
const [userInput, setUserInput] = useState(templateInfo.userInput);

const handleNext = () => {
setTemplateInfo({ ...templateInfo, userInput });
nextStep();
};

const handleExampleClick = (example: string) => {
setUserInput(example);
};

return (
<div className="flex flex-col h-full">
<div className="flex-grow overflow-auto">
<div className="space-y-4 pb-20">
<h2 className="text-lg font-semibold">Step 1: Describe Your Needs</h2>
<div className="space-y-2">
<Label htmlFor="user-needs">Describe your template needs</Label>
<Textarea
id="user-needs"
placeholder="Describe the type of template you need, its purpose, and any specific features you'd like to include."
value={userInput}
onChange={(e) => setUserInput(e.target.value)}
className="min-h-[100px]"
/>
</div>
<div className="space-y-2">
<Label>Examples:</Label>
<div className="flex flex-wrap gap-2">
{examples.map((example, index) => (
<Button
key={index}
variant="outline"
size="sm"
onClick={() => handleExampleClick(example)}
>
{example}
</Button>
))}
</div>
</div>
</div>
</div>
<div className="sticky bottom-0 bg-background pt-2 border-t">
<div className="flex justify-end">
<Button onClick={handleNext} disabled={!userInput.trim()}>
Next
</Button>
</div>
</div>
</div>
);
}
Loading
Loading