Add descriptions to secret folders

This commit is contained in:
carlosmonastyrski
2025-03-04 10:11:20 -03:00
parent c29841fbcf
commit a0029ab469
13 changed files with 164 additions and 45 deletions
@@ -128,13 +128,14 @@ export const ActionBar = ({
const { currentWorkspace } = useWorkspace();
const handleFolderCreate = async (folderName: string) => {
const handleFolderCreate = async (folderName: string, description: string | undefined) => {
try {
await createFolder({
name: folderName,
path: secretPath,
environment,
projectId: workspaceId
projectId: workspaceId,
description
});
handlePopUpClose("addFolder");
createNotification({
@@ -1,16 +1,22 @@
import { useRef } from "react";
import { Controller, useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { z } from "zod";
import { Button, FormControl, Input, ModalClose } from "@app/components/v2";
import { TextArea } from "@app/components/v2/TextArea/TextArea";
type Props = {
onCreateFolder?: (folderName: string) => Promise<void>;
onUpdateFolder?: (folderName: string) => Promise<void>;
onCreateFolder?: (folderName: string, description: string | undefined) => Promise<void>;
onUpdateFolder?: (folderName: string, description: string | undefined) => Promise<void>;
isEdit?: boolean;
defaultFolderName?: string;
defaultDescription?: string;
showDescriptionOverwriteWarning?: boolean;
};
const descriptionOverwriteWarningMessage = "Warning: Any changes made here will overwrite any custom edits in individual environment folders."
const formSchema = z.object({
name: z
.string()
@@ -18,15 +24,20 @@ const formSchema = z.object({
.regex(
/^[a-zA-Z0-9-_]+$/,
"Folder name can only contain letters, numbers, dashes, and underscores"
)
),
description: z
.string()
.optional()
});
type TFormData = z.infer<typeof formSchema>;
export const FolderForm = ({
isEdit,
defaultFolderName,
defaultDescription,
onCreateFolder,
onUpdateFolder
onUpdateFolder,
showDescriptionOverwriteWarning = false
}: Props): JSX.Element => {
const {
control,
@@ -36,15 +47,32 @@ export const FolderForm = ({
} = useForm<TFormData>({
resolver: zodResolver(formSchema),
defaultValues: {
name: defaultFolderName
name: defaultFolderName,
description:defaultDescription
}
});
const onSubmit = async ({ name }: TFormData) => {
const descriptionRef = useRef<HTMLTextAreaElement>(null);
const handleInput = () => {
const textarea = descriptionRef.current;
if (textarea) {
const lines = textarea.value.split("\n");
const maxDescriptionLines = 10;
if (lines.length > maxDescriptionLines) {
textarea.value = lines.slice(0, maxDescriptionLines).join("\n");
}
}
};
const onSubmit = async ({ name, description }: TFormData) => {
const descriptionShaped = description?.trim() === "" ? undefined : description;
if (isEdit) {
await onUpdateFolder?.(name);
await onUpdateFolder?.(name, descriptionShaped);
} else {
await onCreateFolder?.(name);
await onCreateFolder?.(name, descriptionShaped);
}
reset();
};
@@ -61,6 +89,31 @@ export const FolderForm = ({
</FormControl>
)}
/>
<Controller
control={control}
name="description"
defaultValue=""
render={({ field, fieldState: { error } }) => (
<FormControl
label="Folder Description"
isError={Boolean(error)}
tooltipText={showDescriptionOverwriteWarning ? descriptionOverwriteWarningMessage : undefined}
isOptional
errorText={error?.message}
className="flex-1"
>
<TextArea
placeholder="Folder description"
{...field}
rows={3}
ref={descriptionRef}
onInput={handleInput}
className="thin-scrollbar w-full !resize-none bg-mineshaft-900"
maxLength={255}
/>
</FormControl>
)}
/>
<div className="mt-8 flex items-center">
<Button className="mr-4" type="submit" isDisabled={isSubmitting} isLoading={isSubmitting}>
{isEdit ? "Save" : "Create"}
@@ -11,6 +11,7 @@ import { ProjectPermissionActions, ProjectPermissionSub } from "@app/context";
import { usePopUp } from "@app/hooks";
import { useDeleteFolder, useUpdateFolder } from "@app/hooks/api";
import { TSecretFolder } from "@app/hooks/api/secretFolders/types";
import { Tooltip } from "@app/components/v2/Tooltip/Tooltip";
import { FolderForm } from "../ActionBar/FolderForm";
@@ -42,7 +43,7 @@ export const FolderListView = ({
const { mutateAsync: updateFolder } = useUpdateFolder();
const { mutateAsync: deleteFolder } = useDeleteFolder();
const handleFolderUpdate = async (newFolderName: string) => {
const handleFolderUpdate = async (newFolderName: string, newFolderDescription: string | undefined) => {
try {
const { id: folderId } = popUp.updateFolder.data as TSecretFolder;
await updateFolder({
@@ -50,7 +51,8 @@ export const FolderListView = ({
name: newFolderName,
path: secretPath,
environment,
projectId: workspaceId
projectId: workspaceId,
description: newFolderDescription
});
handlePopUpClose("updateFolder");
createNotification({
@@ -98,7 +100,7 @@ export const FolderListView = ({
return (
<>
{folders.map(({ name, id }) => (
{folders.map(({ name, id, description }) => (
<div
key={id}
className="group flex cursor-pointer border-b border-mineshaft-600 hover:bg-mineshaft-700"
@@ -115,8 +117,14 @@ export const FolderListView = ({
}}
onClick={() => handleFolderClick(name)}
>
{name}
</div>
<Tooltip
position="right"
className="flex items-center space-x-4 max-w-lg py-4 whitespace-pre-wrap"
content={description}
>
<div>{name}</div>
</Tooltip>
</div>
<div className="flex items-center space-x-4 border-l border-mineshaft-600 px-3 py-3">
<ProjectPermissionCan
I={ProjectPermissionActions.Edit}
@@ -130,7 +138,7 @@ export const FolderListView = ({
variant="plain"
size="sm"
className="p-0 opacity-0 group-hover:opacity-100"
onClick={() => handlePopUpOpen("updateFolder", { id, name })}
onClick={() => handlePopUpOpen("updateFolder", { id, name, description })}
isDisabled={!isAllowed}
>
<FontAwesomeIcon icon={faPencilSquare} size="lg" />
@@ -167,6 +175,7 @@ export const FolderListView = ({
<FolderForm
isEdit
defaultFolderName={(popUp.updateFolder?.data as TSecretFolder)?.name}
defaultDescription={(popUp.updateFolder?.data as TSecretFolder)?.description}
onUpdateFolder={handleFolderUpdate}
/>
</ModalContent>