diff --git a/apps/app/components/core/modals/existing-issues-list-modal.tsx b/apps/app/components/core/modals/existing-issues-list-modal.tsx index 71bcef561..f4231fee0 100644 --- a/apps/app/components/core/modals/existing-issues-list-modal.tsx +++ b/apps/app/components/core/modals/existing-issues-list-modal.tsx @@ -13,8 +13,9 @@ import useToast from "hooks/use-toast"; import useIssuesView from "hooks/use-issues-view"; import useDebounce from "hooks/use-debounce"; // ui -import { Loader, PrimaryButton, SecondaryButton } from "components/ui"; +import { Loader, PrimaryButton, SecondaryButton, ToggleSwitch, Tooltip } from "components/ui"; // icons +import { LaunchOutlined } from "@mui/icons-material"; import { MagnifyingGlassIcon, XMarkIcon } from "@heroicons/react/24/outline"; import { LayerDiagonalIcon } from "components/icons"; // types @@ -45,6 +46,7 @@ export const ExistingIssuesListModal: React.FC = ({ const [isSearching, setIsSearching] = useState(false); const [selectedIssues, setSelectedIssues] = useState([]); const [isSubmitting, setIsSubmitting] = useState(false); + const [isWorkspaceLevel, setIsWorkspaceLevel] = useState(false); const debouncedSearchTerm: string = useDebounce(searchTerm, 500); @@ -59,6 +61,7 @@ export const ExistingIssuesListModal: React.FC = ({ onClose(); setSearchTerm(""); setSelectedIssues([]); + setIsWorkspaceLevel(false); }; const onSubmit = async () => { @@ -104,10 +107,11 @@ export const ExistingIssuesListModal: React.FC = ({ .projectIssuesSearch(workspaceSlug as string, projectId as string, { search: debouncedSearchTerm, ...searchParams, + workspace_search: isWorkspaceLevel, }) .then((res) => setIssues(res)) .finally(() => setIsSearching(false)); - }, [debouncedSearchTerm, isOpen, projectId, searchParams, workspaceSlug]); + }, [debouncedSearchTerm, isOpen, isWorkspaceLevel, projectId, searchParams, workspaceSlug]); return ( <> @@ -162,7 +166,7 @@ export const ExistingIssuesListModal: React.FC = ({ /> -
+
{selectedIssues.length > 0 ? (
{selectedIssues.map((issue) => ( @@ -190,6 +194,25 @@ export const ExistingIssuesListModal: React.FC = ({ No issues selected
)} + +
+ setIsWorkspaceLevel((prevData) => !prevData)} + /> + +
+
@@ -242,22 +265,37 @@ export const ExistingIssuesListModal: React.FC = ({ htmlFor={`issue-${issue.id}`} value={issue} className={({ active }) => - `flex w-full cursor-pointer select-none items-center gap-2 rounded-md px-3 py-2 text-custom-text-200 ${ + `group flex items-center justify-between gap-2 w-full cursor-pointer select-none rounded-md px-3 py-2 text-custom-text-200 ${ active ? "bg-custom-background-80 text-custom-text-100" : "" } ${selected ? "text-custom-text-100" : ""}` } > - - - - {issue.project__identifier}-{issue.sequence_id} - - {issue.name} +
+ + + + {issue.project__identifier}-{issue.sequence_id} + + {issue.name} +
+ e.stopPropagation()} + > + + ); })} diff --git a/apps/app/components/issues/form.tsx b/apps/app/components/issues/form.tsx index 02efa8f88..2a17a07a8 100644 --- a/apps/app/components/issues/form.tsx +++ b/apps/app/components/issues/form.tsx @@ -75,6 +75,7 @@ const defaultValues: Partial = { assignees_list: [], labels: [], labels_list: [], + target_date: null, }; export interface IssueFormProps { @@ -271,7 +272,6 @@ export const IssueForm: FC = ({
{watch("parent") && - watch("parent") !== "" && (fieldsToShow.includes("all") || fieldsToShow.includes("parent")) && selectedParentIssue && (
@@ -476,7 +476,7 @@ export const IssueForm: FC = ({ )} {(fieldsToShow.includes("all") || fieldsToShow.includes("parent")) && ( - {watch("parent") && watch("parent") !== "" ? ( + {watch("parent") ? ( <> = ({ ) : null ); + const siblingIssuesList = siblingIssues?.sub_issues.filter((i) => i.id !== issueDetails.id); return ( <>
- {issueDetails?.parent && issueDetails.parent !== "" ? ( + {issueDetails?.parent ? (
- + - {issueDetails.project_detail.identifier}-{issueDetails.parent_detail?.sequence_id} + {issueDetails.parent_detail?.project_detail.identifier}- + {issueDetails.parent_detail?.sequence_id} {issueDetails.parent_detail?.name.substring(0, 50)} @@ -77,29 +81,28 @@ export const IssueMainContent: React.FC = ({ - {siblingIssues && siblingIssues.sub_issues.length > 0 ? ( - <> -

Sibling issues

- {siblingIssues.sub_issues.map((issue) => { - if (issue.id !== issueDetails.id) - return ( - - {issueDetails.project_detail.identifier}-{issue.sequence_id} - - ); - })} - - ) : ( -

- No sibling issues -

- )} + {siblingIssuesList ? ( + siblingIssuesList.length > 0 ? ( + <> +

Sibling issues

+ {siblingIssuesList.map((issue) => ( + + {issueDetails.project_detail.identifier}-{issue.sequence_id} + + ))} + + ) : ( +

+ No sibling issues +

+ ) + ) : null} submitChanges({ parent: null })} diff --git a/apps/app/components/issues/parent-issues-list-modal.tsx b/apps/app/components/issues/parent-issues-list-modal.tsx index 65c67616e..62091511a 100644 --- a/apps/app/components/issues/parent-issues-list-modal.tsx +++ b/apps/app/components/issues/parent-issues-list-modal.tsx @@ -11,8 +11,9 @@ import useDebounce from "hooks/use-debounce"; // components import { LayerDiagonalIcon } from "components/icons"; // ui -import { Loader } from "components/ui"; +import { Loader, ToggleSwitch, Tooltip } from "components/ui"; // icons +import { LaunchOutlined } from "@mui/icons-material"; import { MagnifyingGlassIcon } from "@heroicons/react/24/outline"; // types import { ISearchIssueResponse } from "types"; @@ -37,6 +38,7 @@ export const ParentIssuesListModal: React.FC = ({ const [searchTerm, setSearchTerm] = useState(""); const [issues, setIssues] = useState([]); const [isSearching, setIsSearching] = useState(false); + const [isWorkspaceLevel, setIsWorkspaceLevel] = useState(false); const debouncedSearchTerm: string = useDebounce(searchTerm, 500); @@ -46,6 +48,7 @@ export const ParentIssuesListModal: React.FC = ({ const handleClose = () => { onClose(); setSearchTerm(""); + setIsWorkspaceLevel(false); }; useEffect(() => { @@ -58,10 +61,11 @@ export const ParentIssuesListModal: React.FC = ({ search: debouncedSearchTerm, parent: true, issue_id: issueId, + workspace_search: isWorkspaceLevel, }) .then((res) => setIssues(res)) .finally(() => setIsSearching(false)); - }, [debouncedSearchTerm, isOpen, issueId, projectId, workspaceSlug]); + }, [debouncedSearchTerm, isOpen, issueId, isWorkspaceLevel, projectId, workspaceSlug]); return ( <> @@ -115,7 +119,29 @@ export const ParentIssuesListModal: React.FC = ({ displayValue={() => ""} />
- +
+ +
+ setIsWorkspaceLevel((prevData) => !prevData)} + label="Workspace level" + /> + +
+
+
+ {searchTerm !== "" && (
Search results for{" "} @@ -158,12 +184,12 @@ export const ParentIssuesListModal: React.FC = ({ key={issue.id} value={issue} className={({ active, selected }) => - `flex cursor-pointer select-none items-center gap-2 rounded-md px-3 py-2 text-custom-text-200 ${ + `group flex items-center justify-between gap-2 cursor-pointer select-none rounded-md px-3 py-2 text-custom-text-200 ${ active ? "bg-custom-background-80 text-custom-text-100" : "" } ${selected ? "text-custom-text-100" : ""}` } > - <> +
= ({ {issue.project__identifier}-{issue.sequence_id} {" "} {issue.name} - +
+
e.stopPropagation()} + > + + ))} diff --git a/apps/app/components/issues/sidebar-select/blocked.tsx b/apps/app/components/issues/sidebar-select/blocked.tsx index 792482736..315140ea9 100644 --- a/apps/app/components/issues/sidebar-select/blocked.tsx +++ b/apps/app/components/issues/sidebar-select/blocked.tsx @@ -1,20 +1,18 @@ import React, { useState } from "react"; -import Link from "next/link"; import { useRouter } from "next/router"; // react-hook-form import { UseFormWatch } from "react-hook-form"; // hooks import useToast from "hooks/use-toast"; -import useProjectDetails from "hooks/use-project-details"; // components import { ExistingIssuesListModal } from "components/core"; // icons import { XMarkIcon } from "@heroicons/react/24/outline"; import { BlockedIcon } from "components/icons"; // types -import { BlockeIssue, IIssue, ISearchIssueResponse, UserAuth } from "types"; +import { BlockeIssueDetail, IIssue, ISearchIssueResponse, UserAuth } from "types"; type Props = { issueId?: string; @@ -34,10 +32,9 @@ export const SidebarBlockedSelect: React.FC = ({ const [isBlockedModalOpen, setIsBlockedModalOpen] = useState(false); const { setToastAlert } = useToast(); - const { projectDetails } = useProjectDetails(); const router = useRouter(); - const { workspaceSlug, projectId } = router.query; + const { workspaceSlug } = router.query; const handleClose = () => { setIsBlockedModalOpen(false); @@ -54,11 +51,16 @@ export const SidebarBlockedSelect: React.FC = ({ return; } - const selectedIssues: BlockeIssue[] = data.map((i) => ({ + const selectedIssues: { blocked_issue_detail: BlockeIssueDetail }[] = data.map((i) => ({ blocked_issue_detail: { id: i.id, name: i.name, sequence_id: i.sequence_id, + project_detail: { + id: i.project_id, + identifier: i.project__identifier, + name: i.project__name, + }, }, })); @@ -94,14 +96,15 @@ export const SidebarBlockedSelect: React.FC = ({ key={issue.blocked_issue_detail?.id} className="group flex cursor-pointer items-center gap-1 rounded-2xl border border-custom-border-200 px-1.5 py-0.5 text-xs text-red-500 duration-300 hover:border-red-500/20 hover:bg-red-500/20" > - - - - {`${projectDetails?.identifier}-${issue.blocked_issue_detail?.sequence_id}`} - - + + {`${issue.blocked_issue_detail?.project_detail.identifier}-${issue.blocked_issue_detail?.sequence_id}`} +