diff --git a/apps/app/components/labels/create-label-modal.tsx b/apps/app/components/labels/create-label-modal.tsx index 7af86888d..190b9e832 100644 --- a/apps/app/components/labels/create-label-modal.tsx +++ b/apps/app/components/labels/create-label-modal.tsx @@ -20,6 +20,7 @@ import { ChevronDownIcon } from "@heroicons/react/24/outline"; import type { ICurrentUserResponse, IIssueLabels, IState } from "types"; // constants import { PROJECT_ISSUE_LABELS } from "constants/fetch-keys"; +import { LABEL_COLOR_OPTIONS, getRandomLabelColor } from "constants/label"; // types type Props = { @@ -52,10 +53,15 @@ export const CreateLabelModal: React.FC = ({ watch, control, reset, + setValue, } = useForm({ defaultValues, }); + useEffect(() => { + if (isOpen) setValue("color", getRandomLabelColor()); + }, [setValue, isOpen]); + const onClose = () => { handleClose(); reset(defaultValues); @@ -156,6 +162,7 @@ export const CreateLabelModal: React.FC = ({ render={({ field: { value, onChange } }) => ( { onChange(value.hex); close(); diff --git a/apps/app/components/labels/create-update-label-inline.tsx b/apps/app/components/labels/create-update-label-inline.tsx index ca4fdf3dc..6306d14ca 100644 --- a/apps/app/components/labels/create-update-label-inline.tsx +++ b/apps/app/components/labels/create-update-label-inline.tsx @@ -22,12 +22,14 @@ import { ChevronDownIcon } from "@heroicons/react/24/outline"; import { IIssueLabels } from "types"; // fetch-keys import { PROJECT_ISSUE_LABELS } from "constants/fetch-keys"; +import { getRandomLabelColor, LABEL_COLOR_OPTIONS } from "constants/label"; type Props = { labelForm: boolean; setLabelForm: React.Dispatch>; isUpdating: boolean; labelToUpdate: IIssueLabels | null; + onClose?: () => void; }; const defaultValues: Partial = { @@ -35,167 +37,180 @@ const defaultValues: Partial = { color: "rgb(var(--color-text-200))", }; -type Ref = HTMLDivElement; +export const CreateUpdateLabelInline = forwardRef( + function CreateUpdateLabelInline(props, ref) { + const { labelForm, setLabelForm, isUpdating, labelToUpdate, onClose } = props; -export const CreateUpdateLabelInline = forwardRef(function CreateUpdateLabelInline( - { labelForm, setLabelForm, isUpdating, labelToUpdate }, - ref -) { - const router = useRouter(); - const { workspaceSlug, projectId } = router.query; + const router = useRouter(); + const { workspaceSlug, projectId } = router.query; - const { user } = useUserAuth(); + const { user } = useUserAuth(); - const { - handleSubmit, - control, - register, - reset, - formState: { errors, isSubmitting }, - watch, - setValue, - } = useForm({ - defaultValues, - }); + const { + handleSubmit, + control, + register, + reset, + formState: { errors, isSubmitting }, + watch, + setValue, + } = useForm({ + defaultValues, + }); - const handleLabelCreate: SubmitHandler = async (formData) => { - if (!workspaceSlug || !projectId || isSubmitting) return; + const handleClose = () => { + setLabelForm(false); + reset(defaultValues); + if (onClose) onClose(); + }; - await issuesService - .createIssueLabel(workspaceSlug as string, projectId as string, formData, user) - .then((res) => { - mutate( - PROJECT_ISSUE_LABELS(projectId as string), - (prevData) => [res, ...(prevData ?? [])], - false + const handleLabelCreate: SubmitHandler = async (formData) => { + if (!workspaceSlug || !projectId || isSubmitting) return; + + await issuesService + .createIssueLabel(workspaceSlug as string, projectId as string, formData, user) + .then((res) => { + mutate( + PROJECT_ISSUE_LABELS(projectId as string), + (prevData) => [res, ...(prevData ?? [])], + false + ); + handleClose(); + }); + }; + + const handleLabelUpdate: SubmitHandler = async (formData) => { + if (!workspaceSlug || !projectId || isSubmitting) return; + + await issuesService + .patchIssueLabel( + workspaceSlug as string, + projectId as string, + labelToUpdate?.id ?? "", + formData, + user + ) + .then(() => { + reset(defaultValues); + mutate( + PROJECT_ISSUE_LABELS(projectId as string), + (prevData) => + prevData?.map((p) => (p.id === labelToUpdate?.id ? { ...p, ...formData } : p)), + false + ); + handleClose(); + }); + }; + + useEffect(() => { + if (!labelForm && isUpdating) return; + + reset(); + }, [labelForm, isUpdating, reset]); + + useEffect(() => { + if (!labelToUpdate) return; + + setValue( + "color", + labelToUpdate.color && labelToUpdate.color !== "" ? labelToUpdate.color : "#000" + ); + setValue("name", labelToUpdate.name); + }, [labelToUpdate, setValue]); + + useEffect(() => { + if (labelToUpdate) { + setValue( + "color", + labelToUpdate.color && labelToUpdate.color !== "" ? labelToUpdate.color : "#000" ); - reset(defaultValues); - setLabelForm(false); - }); - }; + return; + } - const handleLabelUpdate: SubmitHandler = async (formData) => { - if (!workspaceSlug || !projectId || isSubmitting) return; + setValue("color", getRandomLabelColor()); + }, [labelToUpdate, setValue]); - await issuesService - .patchIssueLabel( - workspaceSlug as string, - projectId as string, - labelToUpdate?.id ?? "", - formData, - user - ) - .then(() => { - reset(defaultValues); - mutate( - PROJECT_ISSUE_LABELS(projectId as string), - (prevData) => - prevData?.map((p) => (p.id === labelToUpdate?.id ? { ...p, ...formData } : p)), - false - ); - setLabelForm(false); - }); - }; - - useEffect(() => { - if (!labelForm && isUpdating) return; - - reset(); - }, [labelForm, isUpdating, reset]); - - useEffect(() => { - if (!labelToUpdate) return; - - setValue( - "color", - labelToUpdate.color && labelToUpdate.color !== "" ? labelToUpdate.color : "#000" - ); - setValue("name", labelToUpdate.name); - }, [labelToUpdate, setValue]); - - return ( -
-
- - {({ open }) => ( - <> - - - - - - - ( - onChange(value.hex)} /> - )} - /> - - - - )} - -
-
- -
- { - reset(); - setLabelForm(false); - }} + return ( +
- Cancel - - {isUpdating ? ( - - {isSubmitting ? "Updating" : "Update"} - - ) : ( - - {isSubmitting ? "Adding" : "Add"} - - )} -
- ); -}); +
+ + {({ open }) => ( + <> + + + + + + + ( + onChange(value.hex)} + /> + )} + /> + + + + )} + +
+
+ +
+ handleClose()}>Cancel + {isUpdating ? ( + + {isSubmitting ? "Updating" : "Update"} + + ) : ( + + {isSubmitting ? "Adding" : "Add"} + + )} +
+ ); + } +); diff --git a/apps/app/constants/label.ts b/apps/app/constants/label.ts new file mode 100644 index 000000000..220e56209 --- /dev/null +++ b/apps/app/constants/label.ts @@ -0,0 +1,17 @@ +export const LABEL_COLOR_OPTIONS = [ + "#FF6900", + "#FCB900", + "#7BDCB5", + "#00D084", + "#8ED1FC", + "#0693E3", + "#ABB8C3", + "#EB144C", + "#F78DA7", + "#9900EF", +]; + +export const getRandomLabelColor = () => { + const randomIndex = Math.floor(Math.random() * LABEL_COLOR_OPTIONS.length); + return LABEL_COLOR_OPTIONS[randomIndex]; +}; diff --git a/apps/app/pages/[workspaceSlug]/projects/[projectId]/settings/labels.tsx b/apps/app/pages/[workspaceSlug]/projects/[projectId]/settings/labels.tsx index 3f4495ef5..dc845da68 100644 --- a/apps/app/pages/[workspaceSlug]/projects/[projectId]/settings/labels.tsx +++ b/apps/app/pages/[workspaceSlug]/projects/[projectId]/settings/labels.tsx @@ -133,6 +133,11 @@ const LabelsSettings: NextPage = () => { setLabelForm={setLabelForm} isUpdating={isUpdating} labelToUpdate={labelToUpdate} + onClose={() => { + setLabelForm(false); + setIsUpdating(false); + setLabelToUpdate(null); + }} ref={scrollToRef} /> )}