Files
dokploy/components/dashboard/compose/general/compose-file-editor.tsx
Mauricio Siu 7f13fd24ec v0.2.0 (#117)
* feat: add schema for registry and routes

* feat: add docker registry upload

* feat: add show cluster

* refactor: set the registry url in image in case we have a registry asociated

* feat: add update registry and fix the docker url markup

* chore: remove --advertise-ip on swarm script

* refactor: remove listen address of swarm initialize

* feat: add table to show nodes and add dropdown to add manager & workers

* refactor: improve interface for cluster

* refactor: improve UI

* feat: add experimental swarm settings

* refactor: remove comments

* refactor: prettify json of each setting

* refactor: add interface tooltip

* refactor: delete static form self registry

* refactor: allow to se a empty registry

* fix: remove text area warnings

* feat: add network swarm json

* refactor: update ui

* revert: go back to swarm init config

* refactor: remove initialization on server, only on setup script

* Update LICENSE.MD

* feat: appearance theme support system config

* refactor: remove logs

* fix(README-ru): hyperlink-ed docs url

* feat: (#107) webhook listener filter docker events based on image tag.

Fixes #107

* refactor: simplify comparison docker tags

* refactor: remove return in res status

* refactor: prevent to updates download automatically

* feat: support code editor (#105)

* feat: support code editor

* Update codeblock

* refactor: remove unused class

---------

Co-authored-by: Mauricio Siu <47042324+Siumauricio@users.noreply.github.com>

* fix: select the right image from sourcetype (#109)

* chore: bump minor version

* fix: add redirect to https by default (#113)

* Create FUNDING.yml

* 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

* chore: add recomendation to show variables

* chore: add video to contributing templates

* chore: bump version

---------

Co-authored-by: hehehai <riverhohai@gmail.com>
Co-authored-by: Bayram Tagiev <bayram.tagiev.a@gmail.com>
Co-authored-by: Paulo Santana <30875229+hikinine@users.noreply.github.com>
2024-06-02 21:24:56 -06:00

143 lines
3.3 KiB
TypeScript

import { api } from "@/utils/api";
import { useEffect } from "react";
import {
Form,
FormControl,
FormField,
FormItem,
FormMessage,
} from "@/components/ui/form";
import { zodResolver } from "@hookform/resolvers/zod";
import { useForm } from "react-hook-form";
import { z } from "zod";
import { validateAndFormatYAML } from "../../application/advanced/traefik/update-traefik-config";
import { toast } from "sonner";
import { Button } from "@/components/ui/button";
import { RandomizeCompose } from "./randomize-compose";
import { CodeEditor } from "@/components/shared/code-editor";
interface Props {
composeId: string;
}
const AddComposeFile = z.object({
composeFile: z.string(),
});
type AddComposeFile = z.infer<typeof AddComposeFile>;
export const ComposeFileEditor = ({ composeId }: Props) => {
const utils = api.useUtils();
const { data, refetch } = api.compose.one.useQuery(
{
composeId,
},
{ enabled: !!composeId },
);
const { mutateAsync, isLoading, error, isError } =
api.compose.update.useMutation();
const form = useForm<AddComposeFile>({
defaultValues: {
composeFile: "",
},
resolver: zodResolver(AddComposeFile),
});
useEffect(() => {
if (data) {
form.reset({
composeFile: data.composeFile || "",
});
}
}, [form, form.reset, data]);
const onSubmit = async (data: AddComposeFile) => {
const { valid, error } = validateAndFormatYAML(data.composeFile);
if (!valid) {
form.setError("composeFile", {
type: "manual",
message: error || "Invalid YAML",
});
return;
}
form.clearErrors("composeFile");
await mutateAsync({
composeId,
composeFile: data.composeFile,
sourceType: "raw",
})
.then(async () => {
toast.success("Compose config Updated");
refetch();
await utils.compose.allServices.invalidate({
composeId,
});
})
.catch((e) => {
console.log(e);
toast.error("Error to update the compose config");
});
};
return (
<>
<div className="w-full flex flex-col lg:flex-row gap-4 ">
<Form {...form}>
<form
onSubmit={form.handleSubmit(onSubmit)}
className="grid w-full relative gap-4"
>
<FormField
control={form.control}
name="composeFile"
render={({ field }) => (
<FormItem className="overflow-auto">
<FormControl className="">
<div className="flex flex-col gap-4 w-full outline-none focus:outline-none overflow-auto">
<CodeEditor
// disabled
value={field.value}
className="font-mono min-h-[20rem] compose-file-editor"
wrapperClassName="min-h-[20rem]"
placeholder={`version: '3'
services:
web:
image: nginx
ports:
- "80:80"
`}
onChange={(value) => {
field.onChange(value);
}}
/>
</div>
</FormControl>
<pre>
<FormMessage />
</pre>
</FormItem>
)}
/>
<div className="flex justify-between flex-col lg:flex-row gap-2">
<div className="w-full flex flex-col lg:flex-row gap-4 items-end">
<RandomizeCompose composeId={composeId} />
</div>
<Button
type="submit"
isLoading={isLoading}
className="lg:w-fit w-full"
>
Save
</Button>
</div>
</form>
</Form>
</div>
</>
);
};