diff --git a/apps/dokploy/__test__/utils/copy-input.test.ts b/apps/dokploy/__test__/utils/copy-input.test.ts new file mode 100644 index 0000000000..90fca63daa --- /dev/null +++ b/apps/dokploy/__test__/utils/copy-input.test.ts @@ -0,0 +1,32 @@ +import copy from "copy-to-clipboard"; +import { toast } from "sonner"; +import { beforeEach, describe, expect, test, vi } from "vitest"; +import { copyToClipboard } from "@/components/shared/copy-input"; + +vi.mock("copy-to-clipboard", () => ({ default: vi.fn() })); +vi.mock("sonner", () => ({ toast: { success: vi.fn() } })); + +describe("copyToClipboard", () => { + beforeEach(() => { + vi.clearAllMocks(); + }); + + test("copies the value to the clipboard", () => { + copyToClipboard("admin"); + expect(copy).toHaveBeenCalledWith("admin"); + }); + + test("shows a success toast", () => { + copyToClipboard("admin"); + expect(toast.success).toHaveBeenCalledWith("Value is copied to clipboard"); + }); + + test("returns the copied value", () => { + expect(copyToClipboard("admin")).toBe("admin"); + }); + + test("falls back to an empty string for undefined", () => { + expect(copyToClipboard(undefined)).toBe(""); + expect(copy).toHaveBeenCalledWith(""); + }); +}); diff --git a/apps/dokploy/components/dashboard/libsql/general/show-internal-libsql-credentials.tsx b/apps/dokploy/components/dashboard/libsql/general/show-internal-libsql-credentials.tsx index 6c13502426..19128fe3c7 100644 --- a/apps/dokploy/components/dashboard/libsql/general/show-internal-libsql-credentials.tsx +++ b/apps/dokploy/components/dashboard/libsql/general/show-internal-libsql-credentials.tsx @@ -1,4 +1,5 @@ import { SelectGroup } from "@radix-ui/react-select"; +import { CopyInput } from "@/components/shared/copy-input"; import { ToggleVisibilityInput } from "@/components/shared/toggle-visibility-input"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Input } from "@/components/ui/input"; @@ -28,7 +29,7 @@ export const ShowInternalLibsqlCredentials = ({ libsqlId }: Props) => {
- +
diff --git a/apps/dokploy/components/dashboard/mariadb/general/show-internal-mariadb-credentials.tsx b/apps/dokploy/components/dashboard/mariadb/general/show-internal-mariadb-credentials.tsx index 04d431fa1e..db90b2c3a1 100644 --- a/apps/dokploy/components/dashboard/mariadb/general/show-internal-mariadb-credentials.tsx +++ b/apps/dokploy/components/dashboard/mariadb/general/show-internal-mariadb-credentials.tsx @@ -1,4 +1,5 @@ import { toast } from "sonner"; +import { CopyInput } from "@/components/shared/copy-input"; import { ToggleVisibilityInput } from "@/components/shared/toggle-visibility-input"; import { UpdateDatabasePassword } from "@/components/shared/update-database-password"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; @@ -25,11 +26,11 @@ export const ShowInternalMariadbCredentials = ({ mariadbId }: Props) => {
- +
- +
diff --git a/apps/dokploy/components/dashboard/mongo/general/show-internal-mongo-credentials.tsx b/apps/dokploy/components/dashboard/mongo/general/show-internal-mongo-credentials.tsx index ef38fe3cbc..ec8769ad60 100644 --- a/apps/dokploy/components/dashboard/mongo/general/show-internal-mongo-credentials.tsx +++ b/apps/dokploy/components/dashboard/mongo/general/show-internal-mongo-credentials.tsx @@ -1,4 +1,5 @@ import { toast } from "sonner"; +import { CopyInput } from "@/components/shared/copy-input"; import { ToggleVisibilityInput } from "@/components/shared/toggle-visibility-input"; import { UpdateDatabasePassword } from "@/components/shared/update-database-password"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; @@ -25,7 +26,7 @@ export const ShowInternalMongoCredentials = ({ mongoId }: Props) => {
- +
diff --git a/apps/dokploy/components/dashboard/mysql/general/show-internal-mysql-credentials.tsx b/apps/dokploy/components/dashboard/mysql/general/show-internal-mysql-credentials.tsx index 39937badde..6c723ba6b9 100644 --- a/apps/dokploy/components/dashboard/mysql/general/show-internal-mysql-credentials.tsx +++ b/apps/dokploy/components/dashboard/mysql/general/show-internal-mysql-credentials.tsx @@ -1,4 +1,5 @@ import { toast } from "sonner"; +import { CopyInput } from "@/components/shared/copy-input"; import { ToggleVisibilityInput } from "@/components/shared/toggle-visibility-input"; import { UpdateDatabasePassword } from "@/components/shared/update-database-password"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; @@ -25,11 +26,11 @@ export const ShowInternalMysqlCredentials = ({ mysqlId }: Props) => {
- +
- +
diff --git a/apps/dokploy/components/dashboard/postgres/general/show-internal-postgres-credentials.tsx b/apps/dokploy/components/dashboard/postgres/general/show-internal-postgres-credentials.tsx index 3d1b1032e8..e120b081b5 100644 --- a/apps/dokploy/components/dashboard/postgres/general/show-internal-postgres-credentials.tsx +++ b/apps/dokploy/components/dashboard/postgres/general/show-internal-postgres-credentials.tsx @@ -1,4 +1,5 @@ import { toast } from "sonner"; +import { CopyInput } from "@/components/shared/copy-input"; import { ToggleVisibilityInput } from "@/components/shared/toggle-visibility-input"; import { UpdateDatabasePassword } from "@/components/shared/update-database-password"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; @@ -25,11 +26,11 @@ export const ShowInternalPostgresCredentials = ({ postgresId }: Props) => {
- +
- +
diff --git a/apps/dokploy/components/dashboard/redis/general/show-internal-redis-credentials.tsx b/apps/dokploy/components/dashboard/redis/general/show-internal-redis-credentials.tsx index 3dd6814a24..0681fcf303 100644 --- a/apps/dokploy/components/dashboard/redis/general/show-internal-redis-credentials.tsx +++ b/apps/dokploy/components/dashboard/redis/general/show-internal-redis-credentials.tsx @@ -1,4 +1,5 @@ import { toast } from "sonner"; +import { CopyInput } from "@/components/shared/copy-input"; import { ToggleVisibilityInput } from "@/components/shared/toggle-visibility-input"; import { UpdateDatabasePassword } from "@/components/shared/update-database-password"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; @@ -25,7 +26,7 @@ export const ShowInternalRedisCredentials = ({ redisId }: Props) => {
- +
diff --git a/apps/dokploy/components/shared/copy-input.tsx b/apps/dokploy/components/shared/copy-input.tsx new file mode 100644 index 0000000000..23ccb1ea8e --- /dev/null +++ b/apps/dokploy/components/shared/copy-input.tsx @@ -0,0 +1,27 @@ +import copy from "copy-to-clipboard"; +import { Clipboard } from "lucide-react"; +import { toast } from "sonner"; +import { Button } from "../ui/button"; +import { Input, type InputProps } from "../ui/input"; + +export const copyToClipboard = (value: string | undefined): string => { + const text = value ?? ""; + copy(text); + toast.success("Value is copied to clipboard"); + return text; +}; + +export const CopyInput = ({ ...props }: InputProps) => { + return ( +
+ + +
+ ); +};