mirror of
https://github.com/Dokploy/dokploy.git
synced 2026-09-12 19:51:00 +05:00
Merge d9039c822c into 853ca33659
This commit is contained in:
commit
8addbcebd7
@ -0,0 +1,93 @@
|
||||
import { type ReactNode, useState } from "react";
|
||||
import {
|
||||
AlertDialog,
|
||||
AlertDialogAction,
|
||||
AlertDialogCancel,
|
||||
AlertDialogContent,
|
||||
AlertDialogDescription,
|
||||
AlertDialogFooter,
|
||||
AlertDialogHeader,
|
||||
AlertDialogTitle,
|
||||
} from "@/components/ui/alert-dialog";
|
||||
import { Button } from "@/components/ui/button";
|
||||
|
||||
interface Props {
|
||||
onConfirm: () => void;
|
||||
needsConfirmation: boolean;
|
||||
onValidate?: () => Promise<boolean> | boolean;
|
||||
isLoading?: boolean;
|
||||
disabled?: boolean;
|
||||
children?: ReactNode;
|
||||
}
|
||||
|
||||
export const ConfirmableProviderSave = ({
|
||||
onConfirm,
|
||||
needsConfirmation,
|
||||
onValidate,
|
||||
isLoading,
|
||||
disabled,
|
||||
children = "Save",
|
||||
}: Props) => {
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
if (!needsConfirmation) {
|
||||
return (
|
||||
<Button
|
||||
type="submit"
|
||||
className="w-fit"
|
||||
isLoading={isLoading}
|
||||
disabled={disabled}
|
||||
>
|
||||
{children}
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
|
||||
const handleClick = async () => {
|
||||
if (onValidate) {
|
||||
const valid = await onValidate();
|
||||
if (!valid) return;
|
||||
}
|
||||
setOpen(true);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Button
|
||||
type="button"
|
||||
className="w-fit"
|
||||
isLoading={isLoading}
|
||||
disabled={disabled}
|
||||
onClick={handleClick}
|
||||
>
|
||||
{children}
|
||||
</Button>
|
||||
<AlertDialog open={open} onOpenChange={setOpen}>
|
||||
<AlertDialogContent>
|
||||
<AlertDialogHeader>
|
||||
<AlertDialogTitle>
|
||||
Switch provider and disable preview deployments?
|
||||
</AlertDialogTitle>
|
||||
<AlertDialogDescription>
|
||||
Preview deployments only run on the GitHub provider. Switching
|
||||
will disable preview deployments for this application; existing
|
||||
previews will stop receiving updates.
|
||||
</AlertDialogDescription>
|
||||
</AlertDialogHeader>
|
||||
<AlertDialogFooter>
|
||||
<AlertDialogCancel>Cancel</AlertDialogCancel>
|
||||
<AlertDialogAction
|
||||
variant="destructive"
|
||||
onClick={() => {
|
||||
setOpen(false);
|
||||
onConfirm();
|
||||
}}
|
||||
>
|
||||
Confirm
|
||||
</AlertDialogAction>
|
||||
</AlertDialogFooter>
|
||||
</AlertDialogContent>
|
||||
</AlertDialog>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@ -48,6 +48,7 @@ import {
|
||||
} from "@/components/ui/tooltip";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { api } from "@/utils/api";
|
||||
import { ConfirmableProviderSave } from "./confirmable-provider-save";
|
||||
|
||||
const BitbucketProviderSchema = z.object({
|
||||
buildPath: z.string().min(1, "Path is required").default("/"),
|
||||
@ -74,9 +75,10 @@ interface Props {
|
||||
}
|
||||
|
||||
export const SaveBitbucketProvider = ({ applicationId }: Props) => {
|
||||
const utils = api.useUtils();
|
||||
const { data: bitbucketProviders } =
|
||||
api.bitbucket.bitbucketProviders.useQuery();
|
||||
const { data, refetch } = api.application.one.useQuery({ applicationId });
|
||||
const { data } = api.application.one.useQuery({ applicationId });
|
||||
|
||||
const { mutateAsync, isPending: isSavingBitbucketProvider } =
|
||||
api.application.saveBitbucketProvider.useMutation();
|
||||
@ -162,7 +164,7 @@ export const SaveBitbucketProvider = ({ applicationId }: Props) => {
|
||||
})
|
||||
.then(async () => {
|
||||
toast.success("Service Provider Saved");
|
||||
await refetch();
|
||||
await utils.application.one.invalidate({ applicationId });
|
||||
})
|
||||
.catch(() => {
|
||||
toast.error("Error saving the Bitbucket provider");
|
||||
@ -519,13 +521,17 @@ export const SaveBitbucketProvider = ({ applicationId }: Props) => {
|
||||
/>
|
||||
</div>
|
||||
<div className="flex w-full justify-end">
|
||||
<Button
|
||||
<ConfirmableProviderSave
|
||||
needsConfirmation={
|
||||
data?.sourceType === "github" &&
|
||||
data?.isPreviewDeploymentsActive === true
|
||||
}
|
||||
isLoading={isSavingBitbucketProvider}
|
||||
type="submit"
|
||||
className="w-fit"
|
||||
onValidate={() => form.trigger()}
|
||||
onConfirm={form.handleSubmit(onSubmit)}
|
||||
>
|
||||
Save
|
||||
</Button>
|
||||
</ConfirmableProviderSave>
|
||||
</div>
|
||||
</form>
|
||||
</Form>
|
||||
|
||||
@ -3,7 +3,6 @@ import { useEffect } from "react";
|
||||
import { useForm } from "react-hook-form";
|
||||
import { toast } from "sonner";
|
||||
import { z } from "zod";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import {
|
||||
Form,
|
||||
FormControl,
|
||||
@ -14,6 +13,7 @@ import {
|
||||
} from "@/components/ui/form";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { api } from "@/utils/api";
|
||||
import { ConfirmableProviderSave } from "./confirmable-provider-save";
|
||||
|
||||
const DockerProviderSchema = z.object({
|
||||
dockerImage: z.string().min(1, {
|
||||
@ -31,7 +31,8 @@ interface Props {
|
||||
}
|
||||
|
||||
export const SaveDockerProvider = ({ applicationId }: Props) => {
|
||||
const { data, refetch } = api.application.one.useQuery({ applicationId });
|
||||
const utils = api.useUtils();
|
||||
const { data } = api.application.one.useQuery({ applicationId });
|
||||
|
||||
const { mutateAsync } = api.application.saveDockerProvider.useMutation();
|
||||
const form = useForm<DockerProvider>({
|
||||
@ -65,7 +66,7 @@ export const SaveDockerProvider = ({ applicationId }: Props) => {
|
||||
})
|
||||
.then(async () => {
|
||||
toast.success("Docker Provider Saved");
|
||||
await refetch();
|
||||
await utils.application.one.invalidate({ applicationId });
|
||||
})
|
||||
.catch(() => {
|
||||
toast.error("Error saving the Docker provider");
|
||||
@ -149,13 +150,17 @@ export const SaveDockerProvider = ({ applicationId }: Props) => {
|
||||
</div>
|
||||
|
||||
<div className="flex flex-row justify-end">
|
||||
<Button
|
||||
type="submit"
|
||||
className="w-fit"
|
||||
<ConfirmableProviderSave
|
||||
needsConfirmation={
|
||||
data?.sourceType === "github" &&
|
||||
data?.isPreviewDeploymentsActive === true
|
||||
}
|
||||
isLoading={form.formState.isSubmitting}
|
||||
onValidate={() => form.trigger()}
|
||||
onConfirm={form.handleSubmit(onSubmit)}
|
||||
>
|
||||
Save{" "}
|
||||
</Button>
|
||||
Save
|
||||
</ConfirmableProviderSave>
|
||||
</div>
|
||||
</form>
|
||||
</Form>
|
||||
|
||||
@ -16,13 +16,15 @@ import {
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { api } from "@/utils/api";
|
||||
import { type UploadFile, uploadFileSchema } from "@/utils/schema";
|
||||
import { ConfirmableProviderSave } from "./confirmable-provider-save";
|
||||
|
||||
interface Props {
|
||||
applicationId: string;
|
||||
}
|
||||
|
||||
export const SaveDragNDrop = ({ applicationId }: Props) => {
|
||||
const { data, refetch } = api.application.one.useQuery({ applicationId });
|
||||
const utils = api.useUtils();
|
||||
const { data } = api.application.one.useQuery({ applicationId });
|
||||
|
||||
const { mutateAsync, isPending } =
|
||||
api.application.dropDeployment.useMutation();
|
||||
@ -53,7 +55,7 @@ export const SaveDragNDrop = ({ applicationId }: Props) => {
|
||||
await mutateAsync(formData)
|
||||
.then(async () => {
|
||||
toast.success("Deployment saved");
|
||||
await refetch();
|
||||
await utils.application.one.invalidate({ applicationId });
|
||||
})
|
||||
.catch(() => {
|
||||
toast.error("Error saving the deployment");
|
||||
@ -126,14 +128,18 @@ export const SaveDragNDrop = ({ applicationId }: Props) => {
|
||||
</div>
|
||||
|
||||
<div className="flex flex-row justify-end">
|
||||
<Button
|
||||
type="submit"
|
||||
className="w-fit"
|
||||
<ConfirmableProviderSave
|
||||
needsConfirmation={
|
||||
data?.sourceType === "github" &&
|
||||
data?.isPreviewDeploymentsActive === true
|
||||
}
|
||||
isLoading={isPending}
|
||||
disabled={!zip || isPending}
|
||||
onValidate={() => form.trigger()}
|
||||
onConfirm={form.handleSubmit(onSubmit)}
|
||||
>
|
||||
Deploy{" "}
|
||||
</Button>
|
||||
Deploy
|
||||
</ConfirmableProviderSave>
|
||||
</div>
|
||||
</form>
|
||||
</Form>
|
||||
|
||||
@ -36,6 +36,7 @@ import {
|
||||
TooltipTrigger,
|
||||
} from "@/components/ui/tooltip";
|
||||
import { api } from "@/utils/api";
|
||||
import { ConfirmableProviderSave } from "./confirmable-provider-save";
|
||||
|
||||
const GitProviderSchema = z.object({
|
||||
buildPath: z.string().min(1, "Path is required").default("/"),
|
||||
@ -58,7 +59,8 @@ interface Props {
|
||||
}
|
||||
|
||||
export const SaveGitProvider = ({ applicationId }: Props) => {
|
||||
const { data, refetch } = api.application.one.useQuery({ applicationId });
|
||||
const utils = api.useUtils();
|
||||
const { data } = api.application.one.useQuery({ applicationId });
|
||||
const { data: sshKeys } = api.sshKey.allForApps.useQuery();
|
||||
const router = useRouter();
|
||||
|
||||
@ -102,7 +104,7 @@ export const SaveGitProvider = ({ applicationId }: Props) => {
|
||||
})
|
||||
.then(async () => {
|
||||
toast.success("Git Provider Saved");
|
||||
await refetch();
|
||||
await utils.application.one.invalidate({ applicationId });
|
||||
})
|
||||
.catch(() => {
|
||||
toast.error("Error saving the Git provider");
|
||||
@ -316,9 +318,17 @@ export const SaveGitProvider = ({ applicationId }: Props) => {
|
||||
</div>
|
||||
|
||||
<div className="flex flex-row justify-end">
|
||||
<Button type="submit" className="w-fit" isLoading={isPending}>
|
||||
<ConfirmableProviderSave
|
||||
needsConfirmation={
|
||||
data?.sourceType === "github" &&
|
||||
data?.isPreviewDeploymentsActive === true
|
||||
}
|
||||
isLoading={isPending}
|
||||
onValidate={() => form.trigger()}
|
||||
onConfirm={form.handleSubmit(onSubmit)}
|
||||
>
|
||||
Save
|
||||
</Button>
|
||||
</ConfirmableProviderSave>
|
||||
</div>
|
||||
</form>
|
||||
</Form>
|
||||
|
||||
@ -48,6 +48,7 @@ import {
|
||||
} from "@/components/ui/tooltip";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { api } from "@/utils/api";
|
||||
import { ConfirmableProviderSave } from "./confirmable-provider-save";
|
||||
|
||||
interface GiteaRepository {
|
||||
name: string;
|
||||
@ -89,8 +90,9 @@ interface Props {
|
||||
}
|
||||
|
||||
export const SaveGiteaProvider = ({ applicationId }: Props) => {
|
||||
const utils = api.useUtils();
|
||||
const { data: giteaProviders } = api.gitea.giteaProviders.useQuery();
|
||||
const { data, refetch } = api.application.one.useQuery({ applicationId });
|
||||
const { data } = api.application.one.useQuery({ applicationId });
|
||||
|
||||
const { mutateAsync, isPending: isSavingGiteaProvider } =
|
||||
api.application.saveGiteaProvider.useMutation();
|
||||
@ -177,7 +179,7 @@ export const SaveGiteaProvider = ({ applicationId }: Props) => {
|
||||
})
|
||||
.then(async () => {
|
||||
toast.success("Service Provider Saved");
|
||||
await refetch();
|
||||
await utils.application.one.invalidate({ applicationId });
|
||||
})
|
||||
.catch(() => {
|
||||
toast.error("Error saving the Gitea provider");
|
||||
@ -548,13 +550,17 @@ export const SaveGiteaProvider = ({ applicationId }: Props) => {
|
||||
/>
|
||||
</div>
|
||||
<div className="flex w-full justify-end">
|
||||
<Button
|
||||
<ConfirmableProviderSave
|
||||
needsConfirmation={
|
||||
data?.sourceType === "github" &&
|
||||
data?.isPreviewDeploymentsActive === true
|
||||
}
|
||||
isLoading={isSavingGiteaProvider}
|
||||
type="submit"
|
||||
className="w-fit"
|
||||
onValidate={() => form.trigger()}
|
||||
onConfirm={form.handleSubmit(onSubmit)}
|
||||
>
|
||||
Save
|
||||
</Button>
|
||||
</ConfirmableProviderSave>
|
||||
</div>
|
||||
</form>
|
||||
</Form>
|
||||
|
||||
@ -74,8 +74,9 @@ interface Props {
|
||||
}
|
||||
|
||||
export const SaveGithubProvider = ({ applicationId }: Props) => {
|
||||
const utils = api.useUtils();
|
||||
const { data: githubProviders } = api.github.githubProviders.useQuery();
|
||||
const { data, refetch } = api.application.one.useQuery({ applicationId });
|
||||
const { data } = api.application.one.useQuery({ applicationId });
|
||||
|
||||
const { mutateAsync, isPending: isSavingGithubProvider } =
|
||||
api.application.saveGithubProvider.useMutation();
|
||||
@ -160,7 +161,7 @@ export const SaveGithubProvider = ({ applicationId }: Props) => {
|
||||
})
|
||||
.then(async () => {
|
||||
toast.success("Service Provider Saved");
|
||||
await refetch();
|
||||
await utils.application.one.invalidate({ applicationId });
|
||||
})
|
||||
.catch(() => {
|
||||
toast.error("Error saving the github provider");
|
||||
|
||||
@ -48,6 +48,7 @@ import {
|
||||
} from "@/components/ui/tooltip";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { api } from "@/utils/api";
|
||||
import { ConfirmableProviderSave } from "./confirmable-provider-save";
|
||||
|
||||
const GitlabProviderSchema = z.object({
|
||||
buildPath: z.string().min(1, "Path is required").default("/"),
|
||||
@ -75,8 +76,9 @@ interface Props {
|
||||
}
|
||||
|
||||
export const SaveGitlabProvider = ({ applicationId }: Props) => {
|
||||
const utils = api.useUtils();
|
||||
const { data: gitlabProviders } = api.gitlab.gitlabProviders.useQuery();
|
||||
const { data, refetch } = api.application.one.useQuery({ applicationId });
|
||||
const { data } = api.application.one.useQuery({ applicationId });
|
||||
|
||||
const { mutateAsync, isPending: isSavingGitlabProvider } =
|
||||
api.application.saveGitlabProvider.useMutation();
|
||||
@ -172,7 +174,7 @@ export const SaveGitlabProvider = ({ applicationId }: Props) => {
|
||||
})
|
||||
.then(async () => {
|
||||
toast.success("Service Provider Saved");
|
||||
await refetch();
|
||||
await utils.application.one.invalidate({ applicationId });
|
||||
})
|
||||
.catch(() => {
|
||||
toast.error("Error saving the gitlab provider");
|
||||
@ -538,13 +540,17 @@ export const SaveGitlabProvider = ({ applicationId }: Props) => {
|
||||
/>
|
||||
</div>
|
||||
<div className="flex w-full justify-end">
|
||||
<Button
|
||||
<ConfirmableProviderSave
|
||||
needsConfirmation={
|
||||
data?.sourceType === "github" &&
|
||||
data?.isPreviewDeploymentsActive === true
|
||||
}
|
||||
isLoading={isSavingGitlabProvider}
|
||||
type="submit"
|
||||
className="w-fit"
|
||||
onValidate={() => form.trigger()}
|
||||
onConfirm={form.handleSubmit(onSubmit)}
|
||||
>
|
||||
Save
|
||||
</Button>
|
||||
</ConfirmableProviderSave>
|
||||
</div>
|
||||
</form>
|
||||
</Form>
|
||||
|
||||
@ -257,11 +257,12 @@ const Service = (
|
||||
Deployments
|
||||
</TabsTrigger>
|
||||
)}
|
||||
{permissions?.deployment.read && (
|
||||
<TabsTrigger value="preview-deployments">
|
||||
Preview Deployments
|
||||
</TabsTrigger>
|
||||
)}
|
||||
{permissions?.deployment.read &&
|
||||
data?.sourceType === "github" && (
|
||||
<TabsTrigger value="preview-deployments">
|
||||
Preview Deployments
|
||||
</TabsTrigger>
|
||||
)}
|
||||
{permissions?.schedule.read && (
|
||||
<TabsTrigger value="schedules">Schedules</TabsTrigger>
|
||||
)}
|
||||
@ -398,13 +399,19 @@ const Service = (
|
||||
</div>
|
||||
</TabsContent>
|
||||
)}
|
||||
{permissions?.deployment.read && (
|
||||
<TabsContent value="preview-deployments" className="w-full">
|
||||
<div className="flex flex-col gap-4 pt-2.5">
|
||||
<ShowPreviewDeployments applicationId={applicationId} />
|
||||
</div>
|
||||
</TabsContent>
|
||||
)}
|
||||
{permissions?.deployment.read &&
|
||||
data?.sourceType === "github" && (
|
||||
<TabsContent
|
||||
value="preview-deployments"
|
||||
className="w-full"
|
||||
>
|
||||
<div className="flex flex-col gap-4 pt-2.5">
|
||||
<ShowPreviewDeployments
|
||||
applicationId={applicationId}
|
||||
/>
|
||||
</div>
|
||||
</TabsContent>
|
||||
)}
|
||||
{permissions?.domain.read && (
|
||||
<TabsContent value="domains" className="w-full">
|
||||
<div className="flex flex-col gap-4 pt-2.5">
|
||||
|
||||
@ -578,6 +578,7 @@ export const applicationRouter = createTRPCRouter({
|
||||
gitlabPathNamespace: input.gitlabPathNamespace,
|
||||
watchPaths: input.watchPaths,
|
||||
enableSubmodules: input.enableSubmodules,
|
||||
isPreviewDeploymentsActive: false,
|
||||
});
|
||||
const application = await findApplicationById(input.applicationId);
|
||||
await audit(ctx, {
|
||||
@ -605,6 +606,7 @@ export const applicationRouter = createTRPCRouter({
|
||||
bitbucketId: input.bitbucketId,
|
||||
watchPaths: input.watchPaths,
|
||||
enableSubmodules: input.enableSubmodules,
|
||||
isPreviewDeploymentsActive: false,
|
||||
});
|
||||
const application = await findApplicationById(input.applicationId);
|
||||
await audit(ctx, {
|
||||
@ -631,6 +633,7 @@ export const applicationRouter = createTRPCRouter({
|
||||
giteaId: input.giteaId,
|
||||
watchPaths: input.watchPaths,
|
||||
enableSubmodules: input.enableSubmodules,
|
||||
isPreviewDeploymentsActive: false,
|
||||
});
|
||||
const application = await findApplicationById(input.applicationId);
|
||||
await audit(ctx, {
|
||||
@ -654,6 +657,7 @@ export const applicationRouter = createTRPCRouter({
|
||||
sourceType: "docker",
|
||||
applicationStatus: "idle",
|
||||
registryUrl: input.registryUrl,
|
||||
isPreviewDeploymentsActive: false,
|
||||
});
|
||||
const application = await findApplicationById(input.applicationId);
|
||||
await audit(ctx, {
|
||||
@ -679,6 +683,7 @@ export const applicationRouter = createTRPCRouter({
|
||||
applicationStatus: "idle",
|
||||
watchPaths: input.watchPaths,
|
||||
enableSubmodules: input.enableSubmodules,
|
||||
isPreviewDeploymentsActive: false,
|
||||
});
|
||||
const application = await findApplicationById(input.applicationId);
|
||||
await audit(ctx, {
|
||||
@ -934,6 +939,7 @@ export const applicationRouter = createTRPCRouter({
|
||||
await updateApplication(applicationId, {
|
||||
sourceType: "drop",
|
||||
dropBuildPath: dropBuildPath || "",
|
||||
isPreviewDeploymentsActive: false,
|
||||
});
|
||||
|
||||
await unzipDrop(zipFile, app);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user