feat: create label option in create issue modal (#281)

This commit is contained in:
Aaryan Khandelwal
2023-02-14 20:05:32 +05:30
committed by GitHub
parent fcba332589
commit 6f0539f01d
20 changed files with 580 additions and 478 deletions

View File

@@ -16,8 +16,9 @@ import {
IssueStateSelect,
} from "components/issues/select";
import { CycleSelect as IssueCycleSelect } from "components/cycles/select";
import { CreateUpdateStateModal } from "components/states";
import { CreateStateModal } from "components/states";
import CreateUpdateCycleModal from "components/project/cycles/create-update-cycle-modal";
import { CreateLabelModal } from "components/labels";
// ui
import { Button, CustomDatePicker, CustomMenu, Input, Loader } from "components/ui";
// icons
@@ -74,6 +75,7 @@ export const IssueForm: FC<IssueFormProps> = ({
const [mostSimilarIssue, setMostSimilarIssue] = useState<IIssue | undefined>();
const [cycleModal, setCycleModal] = useState(false);
const [stateModal, setStateModal] = useState(false);
const [labelModal, setLabelModal] = useState(false);
const [parentIssueListModalOpen, setParentIssueListModalOpen] = useState(false);
const router = useRouter();
@@ -121,7 +123,7 @@ export const IssueForm: FC<IssueFormProps> = ({
<>
{projectId && (
<>
<CreateUpdateStateModal
<CreateStateModal
isOpen={stateModal}
handleClose={() => setStateModal(false)}
projectId={projectId}
@@ -131,6 +133,11 @@ export const IssueForm: FC<IssueFormProps> = ({
setIsOpen={setCycleModal}
projectId={projectId}
/>
<CreateLabelModal
isOpen={labelModal}
handleClose={() => setLabelModal(false)}
projectId={projectId}
/>
</>
)}
<form onSubmit={handleSubmit(handleCreateUpdateIssue)}>
@@ -281,7 +288,12 @@ export const IssueForm: FC<IssueFormProps> = ({
control={control}
name="labels_list"
render={({ field: { value, onChange } }) => (
<IssueLabelSelect value={value} onChange={onChange} projectId={projectId} />
<IssueLabelSelect
setIsOpen={setLabelModal}
value={value}
onChange={onChange}
projectId={projectId}
/>
)}
/>
<div>

View File

@@ -1,15 +1,13 @@
import React, { useEffect, useState } from "react";
import React, { useState } from "react";
import { useRouter } from "next/router";
import useSWR from "swr";
// react-hook-form
import { useForm } from "react-hook-form";
// headless ui
import { Combobox, Transition } from "@headlessui/react";
// icons
import { RectangleGroupIcon, TagIcon } from "@heroicons/react/24/outline";
import { PlusIcon, RectangleGroupIcon, TagIcon } from "@heroicons/react/24/outline";
// services
import issuesServices from "services/issues.service";
// types
@@ -18,55 +16,26 @@ import type { IIssueLabels } from "types";
import { PROJECT_ISSUE_LABELS } from "constants/fetch-keys";
type Props = {
setIsOpen: React.Dispatch<React.SetStateAction<boolean>>;
value: string[];
onChange: (value: string[]) => void;
projectId: string;
};
const defaultValues: Partial<IIssueLabels> = {
name: "",
};
export const IssueLabelSelect: React.FC<Props> = ({ value, onChange, projectId }) => {
export const IssueLabelSelect: React.FC<Props> = ({ setIsOpen, value, onChange, projectId }) => {
// states
const [query, setQuery] = useState("");
const router = useRouter();
const { workspaceSlug } = router.query;
const [isOpen, setIsOpen] = useState(false);
const { data: issueLabels, mutate: issueLabelsMutate } = useSWR<IIssueLabels[]>(
const { data: issueLabels } = useSWR<IIssueLabels[]>(
projectId ? PROJECT_ISSUE_LABELS(projectId) : null,
workspaceSlug && projectId
? () => issuesServices.getIssueLabels(workspaceSlug as string, projectId)
: null
);
const onSubmit = async (data: IIssueLabels) => {
if (!projectId || !workspaceSlug || isSubmitting) return;
await issuesServices
.createIssueLabel(workspaceSlug as string, projectId as string, data)
.then((response) => {
issueLabelsMutate((prevData) => [...(prevData ?? []), response], false);
setIsOpen(false);
reset(defaultValues);
})
.catch((error) => {
console.log(error);
});
};
const {
formState: { isSubmitting },
setFocus,
reset,
} = useForm<IIssueLabels>({ defaultValues });
useEffect(() => {
isOpen && setFocus("name");
}, [isOpen, setFocus]);
const filteredOptions =
query === ""
? issueLabels
@@ -175,48 +144,14 @@ export const IssueLabelSelect: React.FC<Props> = ({ value, onChange, projectId }
) : (
<p className="text-xs text-gray-500 px-2">Loading...</p>
)}
{/* <div className="cursor-default select-none p-2 hover:bg-indigo-50 hover:text-gray-900">
{isOpen ? (
<div className="flex items-center gap-x-1">
<Input
id="name"
name="name"
type="text"
placeholder="Title"
className="w-full"
autoComplete="off"
register={register}
validations={{
required: true,
}}
/>
<button
type="button"
className="grid place-items-center text-green-600"
disabled={isSubmitting}
onClick={handleSubmit(onSubmit)}
>
<PlusIcon className="h-4 w-4" />
</button>
<button
type="button"
className="grid place-items-center text-red-600"
onClick={() => setIsOpen(false)}
>
<XMarkIcon className="h-4 w-4" aria-hidden="true" />
</button>
</div>
) : (
<button
type="button"
className="flex items-center gap-2 w-full"
onClick={() => setIsOpen(true)}
>
<PlusIcon className="h-4 w-4 text-gray-400" aria-hidden="true" />
<span className="text-xs whitespace-nowrap">Create label</span>
</button>
)}
</div> */}
<button
type="button"
className="flex select-none w-full items-center gap-2 p-2 text-gray-400 outline-none hover:bg-indigo-50 hover:text-gray-900"
onClick={() => setIsOpen(true)}
>
<PlusIcon className="h-3 w-3 text-gray-400" aria-hidden="true" />
<span className="text-xs whitespace-nowrap">Create label</span>
</button>
</div>
</Combobox.Options>
</Transition>