forked from github/plane
refactor: issue search (#1607)
This commit is contained in:
parent
4424d67073
commit
0e5c0fe31e
@ -42,7 +42,6 @@ export const ExistingIssuesListModal: React.FC<Props> = ({
|
|||||||
}) => {
|
}) => {
|
||||||
const [searchTerm, setSearchTerm] = useState("");
|
const [searchTerm, setSearchTerm] = useState("");
|
||||||
const [issues, setIssues] = useState<ISearchIssueResponse[]>([]);
|
const [issues, setIssues] = useState<ISearchIssueResponse[]>([]);
|
||||||
const [isLoading, setIsLoading] = useState(false);
|
|
||||||
const [isSearching, setIsSearching] = useState(false);
|
const [isSearching, setIsSearching] = useState(false);
|
||||||
const [selectedIssues, setSelectedIssues] = useState<ISearchIssueResponse[]>([]);
|
const [selectedIssues, setSelectedIssues] = useState<ISearchIssueResponse[]>([]);
|
||||||
const [isSubmitting, setIsSubmitting] = useState(false);
|
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||||
@ -97,31 +96,18 @@ export const ExistingIssuesListModal: React.FC<Props> = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!workspaceSlug || !projectId) return;
|
if (!isOpen || !workspaceSlug || !projectId) return;
|
||||||
|
|
||||||
setIsLoading(true);
|
setIsSearching(true);
|
||||||
|
|
||||||
if (debouncedSearchTerm) {
|
projectService
|
||||||
setIsSearching(true);
|
.projectIssuesSearch(workspaceSlug as string, projectId as string, {
|
||||||
|
search: debouncedSearchTerm,
|
||||||
projectService
|
...searchParams,
|
||||||
.projectIssuesSearch(workspaceSlug as string, projectId as string, {
|
})
|
||||||
search: debouncedSearchTerm,
|
.then((res) => setIssues(res))
|
||||||
...searchParams,
|
.finally(() => setIsSearching(false));
|
||||||
})
|
}, [debouncedSearchTerm, isOpen, projectId, searchParams, workspaceSlug]);
|
||||||
.then((res) => {
|
|
||||||
setIssues(res);
|
|
||||||
})
|
|
||||||
.finally(() => {
|
|
||||||
setIsLoading(false);
|
|
||||||
setIsSearching(false);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
setIssues([]);
|
|
||||||
setIsLoading(false);
|
|
||||||
setIsSearching(false);
|
|
||||||
}
|
|
||||||
}, [debouncedSearchTerm, workspaceSlug, projectId, searchParams]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@ -169,7 +155,7 @@ export const ExistingIssuesListModal: React.FC<Props> = ({
|
|||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
/>
|
/>
|
||||||
<Combobox.Input
|
<Combobox.Input
|
||||||
className="h-12 w-full border-0 bg-transparent pl-11 pr-4 text-custom-text-100 outline-none focus:ring-0 sm:text-sm"
|
className="h-12 w-full border-0 bg-transparent pl-11 pr-4 text-custom-text-100 outline-none focus:ring-0 sm:text-sm placeholder:text-custom-text-400"
|
||||||
placeholder="Type to search..."
|
placeholder="Type to search..."
|
||||||
value={searchTerm}
|
value={searchTerm}
|
||||||
onChange={(e) => setSearchTerm(e.target.value)}
|
onChange={(e) => setSearchTerm(e.target.value)}
|
||||||
@ -206,20 +192,20 @@ export const ExistingIssuesListModal: React.FC<Props> = ({
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Combobox.Options static className="max-h-80 scroll-py-2 overflow-y-auto mt-2">
|
<Combobox.Options static className="max-h-80 scroll-py-2 overflow-y-auto">
|
||||||
{debouncedSearchTerm !== "" && (
|
{searchTerm !== "" && (
|
||||||
<h5 className="text-[0.825rem] text-custom-text-200 mx-2">
|
<h5 className="text-[0.825rem] text-custom-text-200 mx-2">
|
||||||
Search results for{" "}
|
Search results for{" "}
|
||||||
<span className="text-custom-text-100">
|
<span className="text-custom-text-100">
|
||||||
{'"'}
|
{'"'}
|
||||||
{debouncedSearchTerm}
|
{searchTerm}
|
||||||
{'"'}
|
{'"'}
|
||||||
</span>{" "}
|
</span>{" "}
|
||||||
in project:
|
in project:
|
||||||
</h5>
|
</h5>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{!isLoading &&
|
{!isSearching &&
|
||||||
issues.length === 0 &&
|
issues.length === 0 &&
|
||||||
searchTerm !== "" &&
|
searchTerm !== "" &&
|
||||||
debouncedSearchTerm !== "" && (
|
debouncedSearchTerm !== "" && (
|
||||||
@ -235,7 +221,7 @@ export const ExistingIssuesListModal: React.FC<Props> = ({
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{isLoading || isSearching ? (
|
{isSearching ? (
|
||||||
<Loader className="space-y-3 p-3">
|
<Loader className="space-y-3 p-3">
|
||||||
<Loader.Item height="40px" />
|
<Loader.Item height="40px" />
|
||||||
<Loader.Item height="40px" />
|
<Loader.Item height="40px" />
|
||||||
|
@ -24,7 +24,6 @@ type Props = {
|
|||||||
onChange: (issue: ISearchIssueResponse) => void;
|
onChange: (issue: ISearchIssueResponse) => void;
|
||||||
projectId: string;
|
projectId: string;
|
||||||
issueId?: string;
|
issueId?: string;
|
||||||
customDisplay?: JSX.Element;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const ParentIssuesListModal: React.FC<Props> = ({
|
export const ParentIssuesListModal: React.FC<Props> = ({
|
||||||
@ -34,11 +33,9 @@ export const ParentIssuesListModal: React.FC<Props> = ({
|
|||||||
onChange,
|
onChange,
|
||||||
projectId,
|
projectId,
|
||||||
issueId,
|
issueId,
|
||||||
customDisplay,
|
|
||||||
}) => {
|
}) => {
|
||||||
const [searchTerm, setSearchTerm] = useState("");
|
const [searchTerm, setSearchTerm] = useState("");
|
||||||
const [issues, setIssues] = useState<ISearchIssueResponse[]>([]);
|
const [issues, setIssues] = useState<ISearchIssueResponse[]>([]);
|
||||||
const [isLoading, setIsLoading] = useState(false);
|
|
||||||
const [isSearching, setIsSearching] = useState(false);
|
const [isSearching, setIsSearching] = useState(false);
|
||||||
|
|
||||||
const debouncedSearchTerm: string = useDebounce(searchTerm, 500);
|
const debouncedSearchTerm: string = useDebounce(searchTerm, 500);
|
||||||
@ -52,32 +49,19 @@ export const ParentIssuesListModal: React.FC<Props> = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!workspaceSlug || !projectId) return;
|
if (!isOpen || !workspaceSlug || !projectId) return;
|
||||||
|
|
||||||
setIsLoading(true);
|
setIsSearching(true);
|
||||||
|
|
||||||
if (debouncedSearchTerm) {
|
projectService
|
||||||
setIsSearching(true);
|
.projectIssuesSearch(workspaceSlug as string, projectId as string, {
|
||||||
|
search: debouncedSearchTerm,
|
||||||
projectService
|
parent: true,
|
||||||
.projectIssuesSearch(workspaceSlug as string, projectId as string, {
|
issue_id: issueId,
|
||||||
search: debouncedSearchTerm,
|
})
|
||||||
parent: true,
|
.then((res) => setIssues(res))
|
||||||
issue_id: issueId,
|
.finally(() => setIsSearching(false));
|
||||||
})
|
}, [debouncedSearchTerm, isOpen, issueId, projectId, workspaceSlug]);
|
||||||
.then((res) => {
|
|
||||||
setIssues(res);
|
|
||||||
})
|
|
||||||
.finally(() => {
|
|
||||||
setIsLoading(false);
|
|
||||||
setIsSearching(false);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
setIssues([]);
|
|
||||||
setIsLoading(false);
|
|
||||||
setIsSearching(false);
|
|
||||||
}
|
|
||||||
}, [debouncedSearchTerm, workspaceSlug, projectId, issueId]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@ -124,28 +108,27 @@ export const ParentIssuesListModal: React.FC<Props> = ({
|
|||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
/>
|
/>
|
||||||
<Combobox.Input
|
<Combobox.Input
|
||||||
className="h-12 w-full border-0 bg-transparent pl-11 pr-4 text-custom-text-100 outline-none focus:ring-0 sm:text-sm"
|
className="h-12 w-full border-0 bg-transparent pl-11 pr-4 text-custom-text-100 outline-none focus:ring-0 sm:text-sm placeholder:text-custom-text-400"
|
||||||
placeholder="Type to search..."
|
placeholder="Type to search..."
|
||||||
value={searchTerm}
|
value={searchTerm}
|
||||||
onChange={(e) => setSearchTerm(e.target.value)}
|
onChange={(e) => setSearchTerm(e.target.value)}
|
||||||
displayValue={() => ""}
|
displayValue={() => ""}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{customDisplay && <div className="p-2">{customDisplay}</div>}
|
|
||||||
<Combobox.Options static className="max-h-80 scroll-py-2 overflow-y-auto mt-2">
|
<Combobox.Options static className="max-h-80 scroll-py-2 overflow-y-auto mt-2">
|
||||||
{debouncedSearchTerm !== "" && (
|
{searchTerm !== "" && (
|
||||||
<h5 className="text-[0.825rem] text-custom-text-200 mx-2">
|
<h5 className="text-[0.825rem] text-custom-text-200 mx-2">
|
||||||
Search results for{" "}
|
Search results for{" "}
|
||||||
<span className="text-custom-text-100">
|
<span className="text-custom-text-100">
|
||||||
{'"'}
|
{'"'}
|
||||||
{debouncedSearchTerm}
|
{searchTerm}
|
||||||
{'"'}
|
{'"'}
|
||||||
</span>{" "}
|
</span>{" "}
|
||||||
in project:
|
in project:
|
||||||
</h5>
|
</h5>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{!isLoading &&
|
{!isSearching &&
|
||||||
issues.length === 0 &&
|
issues.length === 0 &&
|
||||||
searchTerm !== "" &&
|
searchTerm !== "" &&
|
||||||
debouncedSearchTerm !== "" && (
|
debouncedSearchTerm !== "" && (
|
||||||
@ -161,7 +144,7 @@ export const ParentIssuesListModal: React.FC<Props> = ({
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{isLoading || isSearching ? (
|
{isSearching ? (
|
||||||
<Loader className="space-y-3 p-3">
|
<Loader className="space-y-3 p-3">
|
||||||
<Loader.Item height="40px" />
|
<Loader.Item height="40px" />
|
||||||
<Loader.Item height="40px" />
|
<Loader.Item height="40px" />
|
||||||
|
Loading…
Reference in New Issue
Block a user