Files
dokploy/components/dashboard/compose/advanced/add-command.tsx
Mauricio Siu 8f9d21c0f8 Docker compose support (#111)
* feat(WIP): compose implementation

* feat: add volumes, networks, services name hash generate

* feat: add compose config test unique

* feat: add tests for each unique config

* feat: implement lodash for docker compose parsing

* feat: add tests for generating compose file

* refactor: implement logs docker compose

* refactor: composeFile set not empty

* feat: implement providers for compose deployments

* feat: add Files volumes to compose

* feat: add stop compose button

* refactor: change strategie of building compose

* feat: create .env file in composepath

* refactor: simplify git and github function

* chore: update deps

* refactor: update migrations and add badge to recognize compose type

* chore: update lock yaml

* refactor: use code editor

* feat: add monitoring for app types

* refactor: reset stats on change appName

* refactor: add option to clean monitoring folder

* feat: show current command that will run

* feat: add prefix

* fix: add missing types

* refactor: add docker provider and expose by default as false

* refactor: customize error page

* refactor: unified deployments to be a single one

* feat: add vitest to ci/cd

* revert: back to initial version

* refactor: add maxconcurrency vitest

* refactor: add pool forks to vitest

* feat: add pocketbase template

* fix: update path resolution compose

* removed

* feat: add template pocketbase

* feat: add pocketbase template

* feat: add support button

* feat: add plausible template

* feat: add calcom template

* feat: add version to each template

* feat: add code editor to enviroment variables and swarm settings json

* refactor: add loader when download the image

* fix: use base64 to generate keys plausible

* feat: add recognized domain names by enviroment compose

* refactor: show alert to redeploy in each card advanced tab

* refactor: add validation to prevent create compose if not have permissions

* chore: add templates section to contributing

* chore: add example contributing
2024-06-02 15:26:28 -06:00

134 lines
2.9 KiB
TypeScript

import React from "react";
import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from "@/components/ui/card";
import { api } from "@/utils/api";
import { z } from "zod";
import {
Form,
FormControl,
FormDescription,
FormField,
FormItem,
FormLabel,
FormMessage,
} from "@/components/ui/form";
import { toast } from "sonner";
import { zodResolver } from "@hookform/resolvers/zod";
import { useForm } from "react-hook-form";
import { useEffect } from "react";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
interface Props {
composeId: string;
}
const AddRedirectSchema = z.object({
command: z.string(),
});
type AddCommand = z.infer<typeof AddRedirectSchema>;
export const AddCommandCompose = ({ composeId }: Props) => {
const { data } = api.compose.one.useQuery(
{
composeId,
},
{ enabled: !!composeId },
);
const { data: defaultCommand, refetch } =
api.compose.getDefaultCommand.useQuery(
{
composeId,
},
{ enabled: !!composeId },
);
const utils = api.useUtils();
const { mutateAsync, isLoading } = api.compose.update.useMutation();
const form = useForm<AddCommand>({
defaultValues: {
command: "",
},
resolver: zodResolver(AddRedirectSchema),
});
useEffect(() => {
if (data?.command) {
form.reset({
command: data?.command || "",
});
}
}, [form, form.reset, form.formState.isSubmitSuccessful, data?.command]);
const onSubmit = async (data: AddCommand) => {
await mutateAsync({
composeId,
command: data?.command,
})
.then(async () => {
toast.success("Command Updated");
refetch();
await utils.compose.one.invalidate({
composeId,
});
})
.catch(() => {
toast.error("Error to update the command");
});
};
return (
<Card className="bg-background">
<CardHeader className="flex flex-row justify-between">
<div>
<CardTitle className="text-xl">Run Command</CardTitle>
<CardDescription>
Append a custom command to the compose file
</CardDescription>
</div>
</CardHeader>
<CardContent className="flex flex-col gap-4">
<Form {...form}>
<form
onSubmit={form.handleSubmit(onSubmit)}
className="grid w-full gap-4"
>
<div className="flex flex-col gap-4">
<FormField
control={form.control}
name="command"
render={({ field }) => (
<FormItem>
<FormLabel>Command</FormLabel>
<FormControl>
<Input placeholder="Custom command" {...field} />
</FormControl>
<FormDescription>
Default Command ({defaultCommand})
</FormDescription>
<FormMessage />
</FormItem>
)}
/>
</div>
<div className="flex justify-end">
<Button isLoading={isLoading} type="submit" className="w-fit">
Save
</Button>
</div>
</form>
</Form>
</CardContent>
</Card>
);
};