From d8860e1ce3d2a88e2e737d3555005cf915ed5118 Mon Sep 17 00:00:00 2001 From: Rhythm Bhiwani Date: Sun, 3 Mar 2024 02:49:35 +0530 Subject: [PATCH] Disabled submit button when renaming all keys if key name is empty --- frontend/package-lock.json | 2 +- .../SecretRenameRow.tsx | 168 ++++++++++++------ 2 files changed, 114 insertions(+), 56 deletions(-) diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 72607a272..2ec5b5578 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -1,5 +1,5 @@ { - "name": "npm-proj-1709146141702-0.772936286416932EMIzNi", + "name": "frontend", "lockfileVersion": 3, "requires": true, "packages": { diff --git a/frontend/src/views/SecretOverviewPage/components/SecretOverviewTableRow/SecretRenameRow.tsx b/frontend/src/views/SecretOverviewPage/components/SecretOverviewTableRow/SecretRenameRow.tsx index e6e8381db..a2813abee 100644 --- a/frontend/src/views/SecretOverviewPage/components/SecretOverviewTableRow/SecretRenameRow.tsx +++ b/frontend/src/views/SecretOverviewPage/components/SecretOverviewTableRow/SecretRenameRow.tsx @@ -1,9 +1,12 @@ +import { useEffect } from "react"; import { Controller, useForm } from "react-hook-form"; import { subject } from "@casl/ability"; -import { faCheck, faClose } from "@fortawesome/free-solid-svg-icons"; +import { faCheck, faClose, faCopy } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { zodResolver } from "@hookform/resolvers/zod"; import { AnimatePresence, motion } from "framer-motion"; import { twMerge } from "tailwind-merge"; +import { z } from "zod"; import { useNotificationContext } from "@app/components/context/Notifications/NotificationProvider"; import { IconButton, Input, Spinner, Tooltip } from "@app/components/v2"; @@ -13,6 +16,7 @@ import { useProjectPermission, useWorkspace } from "@app/context"; +import { useToggle } from "@app/hooks"; import { useGetUserWsKey, useUpdateSecretV3 } from "@app/hooks/api"; import { DecryptedSecret } from "@app/hooks/api/types"; import { SecretActionType } from "@app/views/SecretMainPage/components/SecretListView/SecretListView.utils"; @@ -24,7 +28,11 @@ type Props = { getSecretByKey: (slug: string, key: string) => DecryptedSecret | undefined; }; -type Form = { key: string }; +export const formSchema = z.object({ + key: z.string().trim().min(1, { message: "Secret key is required" }) +}); + +type TFormSchema = z.infer; function SecretRenameRow({ environments, getSecretByKey, secretKey, secretPath }: Props) { const { currentWorkspace } = useWorkspace(); @@ -59,19 +67,32 @@ function SecretRenameRow({ environments, getSecretByKey, secretKey, secretPath } const { data: decryptFileKey } = useGetUserWsKey(workspaceId); + const [isSecNameCopied, setIsSecNameCopied] = useToggle(false); + const { mutateAsync: updateSecretV3 } = useUpdateSecretV3(); const { handleSubmit, control, reset, - formState: { isDirty, isSubmitting } - } = useForm
({ + trigger, + getValues, + formState: { isDirty, isSubmitting, errors } + } = useForm({ defaultValues: { key: secretKey }, - values: { key: secretKey } + values: { key: secretKey }, + resolver: zodResolver(formSchema) }); - const handleFormSubmit = async (data: Form) => { + useEffect(() => { + let timer: NodeJS.Timeout; + if (isSecNameCopied) { + timer = setTimeout(() => setIsSecNameCopied.off(), 2000); + } + return () => clearTimeout(timer); + }, [isSecNameCopied]); + + const handleFormSubmit = async (data: TFormSchema) => { if (!data.key) { createNotification({ type: "error", @@ -118,6 +139,12 @@ function SecretRenameRow({ environments, getSecretByKey, secretKey, secretPath } }); }; + const copyTokenToClipboard = () => { + const [key] = getValues(["key"]); + navigator.clipboard.writeText(key as string); + setIsSecNameCopied.on(); + }; + return ( ( + render={({ field, fieldState: { error } }) => ( trigger("key")} + isError={Boolean(error)} {...field} - className="w-full px-2 focus:text-bunker-100 focus:ring-transparent" + className="w-full px-2 placeholder:text-red-500 focus:text-bunker-100 focus:ring-transparent" /> )} /> - {(isReadOnly || isOverriden) && ( + + {isReadOnly || isOverriden ? ( Read Only + ) : ( +
+ + {!isDirty ? ( + + + + + + + + ) : ( + + + + {isSubmitting ? ( + + ) : ( + + )} + + + + reset()} + isDisabled={isSubmitting} + > + + + + + )} + +
)} - - {isDirty && ( - - - - {isSubmitting ? ( - - ) : ( - - )} - - - - reset()} - isDisabled={isSubmitting} - > - - - - - )} - ); }