style: revamp of the issue details sidebar (#2014)

This commit is contained in:
Aaryan Khandelwal 2023-08-29 20:15:12 +05:30 committed by GitHub
parent d8bbdc14ac
commit 168e79d6df
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 219 additions and 234 deletions

View File

@ -48,10 +48,10 @@ export const SidebarAssigneeSelect: React.FC<Props> = ({ value, onChange, disabl
{value && value.length > 0 && Array.isArray(value) ? ( {value && value.length > 0 && Array.isArray(value) ? (
<div className="-my-0.5 flex items-center gap-2"> <div className="-my-0.5 flex items-center gap-2">
<AssigneesList userIds={value} length={3} showLength={false} /> <AssigneesList userIds={value} length={3} showLength={false} />
<span className="text-custom-text-100 text-sm">{value.length} Assignees</span> <span className="text-custom-text-100 text-xs">{value.length} Assignees</span>
</div> </div>
) : ( ) : (
<button type="button" className="bg-custom-background-80 px-2.5 py-0.5 text-sm rounded"> <button type="button" className="bg-custom-background-80 px-2.5 py-0.5 text-xs rounded">
No assignees No assignees
</button> </button>
)} )}

View File

@ -18,7 +18,6 @@ type Props = {
issueId?: string; issueId?: string;
submitChanges: (formData: Partial<IIssue>) => void; submitChanges: (formData: Partial<IIssue>) => void;
watch: UseFormWatch<IIssue>; watch: UseFormWatch<IIssue>;
userAuth: UserAuth;
disabled?: boolean; disabled?: boolean;
}; };
@ -26,7 +25,6 @@ export const SidebarBlockedSelect: React.FC<Props> = ({
issueId, issueId,
submitChanges, submitChanges,
watch, watch,
userAuth,
disabled = false, disabled = false,
}) => { }) => {
const [isBlockedModalOpen, setIsBlockedModalOpen] = useState(false); const [isBlockedModalOpen, setIsBlockedModalOpen] = useState(false);
@ -73,8 +71,6 @@ export const SidebarBlockedSelect: React.FC<Props> = ({
handleClose(); handleClose();
}; };
const isNotAllowed = userAuth.isGuest || userAuth.isViewer || disabled;
return ( return (
<> <>
<ExistingIssuesListModal <ExistingIssuesListModal
@ -128,11 +124,11 @@ export const SidebarBlockedSelect: React.FC<Props> = ({
</div> </div>
<button <button
type="button" type="button"
className={`flex w-full text-custom-text-200 ${ className={`bg-custom-background-80 text-xs rounded px-2.5 py-0.5 ${
isNotAllowed ? "cursor-not-allowed" : "cursor-pointer hover:bg-custom-background-80" disabled ? "cursor-not-allowed" : "cursor-pointer hover:bg-custom-background-80"
} items-center justify-between gap-1 rounded-md border border-custom-border-200 px-2 py-1 text-xs shadow-sm duration-300 focus:outline-none`} }`}
onClick={() => setIsBlockedModalOpen(true)} onClick={() => setIsBlockedModalOpen(true)}
disabled={isNotAllowed} disabled={disabled}
> >
Select issues Select issues
</button> </button>

View File

@ -18,7 +18,6 @@ type Props = {
issueId?: string; issueId?: string;
submitChanges: (formData: Partial<IIssue>) => void; submitChanges: (formData: Partial<IIssue>) => void;
watch: UseFormWatch<IIssue>; watch: UseFormWatch<IIssue>;
userAuth: UserAuth;
disabled?: boolean; disabled?: boolean;
}; };
@ -26,7 +25,6 @@ export const SidebarBlockerSelect: React.FC<Props> = ({
issueId, issueId,
submitChanges, submitChanges,
watch, watch,
userAuth,
disabled = false, disabled = false,
}) => { }) => {
const [isBlockerModalOpen, setIsBlockerModalOpen] = useState(false); const [isBlockerModalOpen, setIsBlockerModalOpen] = useState(false);
@ -73,8 +71,6 @@ export const SidebarBlockerSelect: React.FC<Props> = ({
handleClose(); handleClose();
}; };
const isNotAllowed = userAuth.isGuest || userAuth.isViewer || disabled;
return ( return (
<> <>
<ExistingIssuesListModal <ExistingIssuesListModal
@ -130,11 +126,11 @@ export const SidebarBlockerSelect: React.FC<Props> = ({
</div> </div>
<button <button
type="button" type="button"
className={`flex w-full text-custom-text-200 ${ className={`bg-custom-background-80 text-xs rounded px-2.5 py-0.5 ${
isNotAllowed ? "cursor-not-allowed" : "cursor-pointer hover:bg-custom-background-80" disabled ? "cursor-not-allowed" : "cursor-pointer hover:bg-custom-background-80"
} items-center justify-between gap-1 rounded-md border border-custom-border-200 px-2 py-1 text-xs shadow-sm duration-300 focus:outline-none`} }`}
onClick={() => setIsBlockerModalOpen(true)} onClick={() => setIsBlockerModalOpen(true)}
disabled={isNotAllowed} disabled={disabled}
> >
Select issues Select issues
</button> </button>

View File

@ -11,24 +11,20 @@ import cyclesService from "services/cycles.service";
import { Spinner, CustomSelect, Tooltip } from "components/ui"; import { Spinner, CustomSelect, Tooltip } from "components/ui";
// helper // helper
import { truncateText } from "helpers/string.helper"; import { truncateText } from "helpers/string.helper";
// icons
import { ContrastIcon } from "components/icons";
// types // types
import { ICycle, IIssue, UserAuth } from "types"; import { ICycle, IIssue } from "types";
// fetch-keys // fetch-keys
import { CYCLE_ISSUES, INCOMPLETE_CYCLES_LIST, ISSUE_DETAILS } from "constants/fetch-keys"; import { CYCLE_ISSUES, INCOMPLETE_CYCLES_LIST, ISSUE_DETAILS } from "constants/fetch-keys";
type Props = { type Props = {
issueDetail: IIssue | undefined; issueDetail: IIssue | undefined;
handleCycleChange: (cycle: ICycle) => void; handleCycleChange: (cycle: ICycle) => void;
userAuth: UserAuth;
disabled?: boolean; disabled?: boolean;
}; };
export const SidebarCycleSelect: React.FC<Props> = ({ export const SidebarCycleSelect: React.FC<Props> = ({
issueDetail, issueDetail,
handleCycleChange, handleCycleChange,
userAuth,
disabled = false, disabled = false,
}) => { }) => {
const router = useRouter(); const router = useRouter();
@ -63,59 +59,56 @@ export const SidebarCycleSelect: React.FC<Props> = ({
const issueCycle = issueDetail?.issue_cycle; const issueCycle = issueDetail?.issue_cycle;
const isNotAllowed = userAuth.isGuest || userAuth.isViewer || disabled;
return ( return (
<div className="flex flex-wrap items-center py-2"> <CustomSelect
<div className="flex items-center gap-x-2 text-sm text-custom-text-200 sm:basis-1/2"> customButton={
<ContrastIcon className="h-4 w-4 flex-shrink-0" /> <Tooltip
<p>Cycle</p> position="left"
</div> tooltipContent={`${issueCycle ? issueCycle.cycle_detail.name : "No cycle"}`}
<div className="space-y-1 sm:basis-1/2">
<CustomSelect
label={
<Tooltip
position="left"
tooltipContent={`${issueCycle ? issueCycle.cycle_detail.name : "No cycle"}`}
>
<span className="w-full max-w-[125px] truncate text-left sm:block">
<span className={`${issueCycle ? "text-custom-text-100" : "text-custom-text-200"}`}>
{issueCycle ? truncateText(issueCycle.cycle_detail.name, 15) : "No cycle"}
</span>
</span>
</Tooltip>
}
value={issueCycle ? issueCycle.cycle_detail.id : null}
onChange={(value: any) => {
!value
? removeIssueFromCycle(issueCycle?.id ?? "", issueCycle?.cycle ?? "")
: handleCycleChange(incompleteCycles?.find((c) => c.id === value) as ICycle);
}}
width="w-full"
position="right"
maxHeight="rg"
disabled={isNotAllowed}
> >
{incompleteCycles ? ( <button
incompleteCycles.length > 0 ? ( type="button"
<> className={`bg-custom-background-80 text-xs rounded px-2.5 py-0.5 w-full flex ${
{incompleteCycles.map((option) => ( disabled ? "cursor-not-allowed" : ""
<CustomSelect.Option key={option.id} value={option.id}> }`}
<Tooltip position="left-bottom" tooltipContent={option.name}> >
<span className="w-full truncate">{truncateText(option.name, 25)}</span> <span
</Tooltip> className={`truncate ${issueCycle ? "text-custom-text-100" : "text-custom-text-200"}`}
</CustomSelect.Option> >
))} {issueCycle ? issueCycle.cycle_detail.name : "No cycle"}
<CustomSelect.Option value={null}>None</CustomSelect.Option> </span>
</> </button>
) : ( </Tooltip>
<div className="text-center">No cycles found</div> }
) value={issueCycle ? issueCycle.cycle_detail.id : null}
) : ( onChange={(value: any) => {
<Spinner /> !value
)} ? removeIssueFromCycle(issueCycle?.id ?? "", issueCycle?.cycle ?? "")
</CustomSelect> : handleCycleChange(incompleteCycles?.find((c) => c.id === value) as ICycle);
</div> }}
</div> width="w-full"
position="right"
maxHeight="rg"
disabled={disabled}
>
{incompleteCycles ? (
incompleteCycles.length > 0 ? (
<>
{incompleteCycles.map((option) => (
<CustomSelect.Option key={option.id} value={option.id}>
<Tooltip position="left-bottom" tooltipContent={option.name}>
<span className="w-full truncate">{truncateText(option.name, 25)}</span>
</Tooltip>
</CustomSelect.Option>
))}
<CustomSelect.Option value={null}>None</CustomSelect.Option>
</>
) : (
<div className="text-center">No cycles found</div>
)
) : (
<Spinner />
)}
</CustomSelect>
); );
}; };

View File

@ -14,9 +14,7 @@ type Props = {
}; };
export const SidebarEstimateSelect: React.FC<Props> = ({ value, onChange, disabled = false }) => { export const SidebarEstimateSelect: React.FC<Props> = ({ value, onChange, disabled = false }) => {
const { isEstimateActive, estimatePoints } = useEstimateOption(); const { estimatePoints } = useEstimateOption();
if (!isEstimateActive) return null;
return ( return (
<CustomSelect <CustomSelect

View File

@ -10,24 +10,20 @@ import modulesService from "services/modules.service";
import { Spinner, CustomSelect, Tooltip } from "components/ui"; import { Spinner, CustomSelect, Tooltip } from "components/ui";
// helper // helper
import { truncateText } from "helpers/string.helper"; import { truncateText } from "helpers/string.helper";
// icons
import { RectangleGroupIcon } from "@heroicons/react/24/outline";
// types // types
import { IIssue, IModule, UserAuth } from "types"; import { IIssue, IModule } from "types";
// fetch-keys // fetch-keys
import { ISSUE_DETAILS, MODULE_ISSUES, MODULE_LIST } from "constants/fetch-keys"; import { ISSUE_DETAILS, MODULE_ISSUES, MODULE_LIST } from "constants/fetch-keys";
type Props = { type Props = {
issueDetail: IIssue | undefined; issueDetail: IIssue | undefined;
handleModuleChange: (module: IModule) => void; handleModuleChange: (module: IModule) => void;
userAuth: UserAuth;
disabled?: boolean; disabled?: boolean;
}; };
export const SidebarModuleSelect: React.FC<Props> = ({ export const SidebarModuleSelect: React.FC<Props> = ({
issueDetail, issueDetail,
handleModuleChange, handleModuleChange,
userAuth,
disabled = false, disabled = false,
}) => { }) => {
const router = useRouter(); const router = useRouter();
@ -57,66 +53,60 @@ export const SidebarModuleSelect: React.FC<Props> = ({
const issueModule = issueDetail?.issue_module; const issueModule = issueDetail?.issue_module;
const isNotAllowed = userAuth.isGuest || userAuth.isViewer || disabled;
return ( return (
<div className="flex flex-wrap items-center py-2"> <CustomSelect
<div className="flex items-center gap-x-2 text-sm text-custom-text-200 sm:basis-1/2"> customButton={
<RectangleGroupIcon className="h-4 w-4 flex-shrink-0" /> <Tooltip
<p>Module</p> position="left"
</div> tooltipContent={`${
<div className="space-y-1 sm:basis-1/2"> modules?.find((m) => m.id === issueModule?.module)?.name ?? "No module"
<CustomSelect }`}
label={ >
<Tooltip <button
position="left" type="button"
tooltipContent={`${ className={`bg-custom-background-80 text-xs rounded px-2.5 py-0.5 w-full flex ${
modules?.find((m) => m.id === issueModule?.module)?.name ?? "No module" disabled ? "cursor-not-allowed" : ""
}`}
>
<span
className={`truncate ${
issueModule ? "text-custom-text-100" : "text-custom-text-200"
}`} }`}
> >
<span className="w-full max-w-[125px] truncate text-left sm:block"> {modules?.find((m) => m.id === issueModule?.module)?.name ?? "No module"}
<span </span>
className={`${issueModule ? "text-custom-text-100" : "text-custom-text-200"}`} </button>
> </Tooltip>
{truncateText( }
`${modules?.find((m) => m.id === issueModule?.module)?.name ?? "No module"}`, value={issueModule ? issueModule.module_detail?.id : null}
15 onChange={(value: any) => {
)} !value
</span> ? removeIssueFromModule(issueModule?.id ?? "", issueModule?.module ?? "")
</span> : handleModuleChange(modules?.find((m) => m.id === value) as IModule);
</Tooltip> }}
} width="w-full"
value={issueModule ? issueModule.module_detail?.id : null} position="right"
onChange={(value: any) => { maxHeight="rg"
!value disabled={disabled}
? removeIssueFromModule(issueModule?.id ?? "", issueModule?.module ?? "") >
: handleModuleChange(modules?.find((m) => m.id === value) as IModule); {modules ? (
}} modules.length > 0 ? (
width="w-full" <>
position="right" {modules.map((option) => (
maxHeight="rg" <CustomSelect.Option key={option.id} value={option.id}>
disabled={isNotAllowed} <Tooltip position="left-bottom" tooltipContent={option.name}>
> <span className="w-full truncate">{truncateText(option.name, 25)}</span>
{modules ? ( </Tooltip>
modules.length > 0 ? ( </CustomSelect.Option>
<> ))}
{modules.map((option) => ( <CustomSelect.Option value={null}>None</CustomSelect.Option>
<CustomSelect.Option key={option.id} value={option.id}> </>
<Tooltip position="left-bottom" tooltipContent={option.name}> ) : (
<span className="w-full truncate">{truncateText(option.name, 25)}</span> <div className="text-center">No modules found</div>
</Tooltip> )
</CustomSelect.Option> ) : (
))} <Spinner />
<CustomSelect.Option value={null}>None</CustomSelect.Option> )}
</> </CustomSelect>
) : (
<div className="text-center">No modules found</div>
)
) : (
<Spinner />
)}
</CustomSelect>
</div>
</div>
); );
}; };

View File

@ -2,8 +2,6 @@ import React, { useState } from "react";
import { useRouter } from "next/router"; import { useRouter } from "next/router";
// icons
import { UserIcon } from "@heroicons/react/24/outline";
// components // components
import { ParentIssuesListModal } from "components/issues"; import { ParentIssuesListModal } from "components/issues";
// types // types
@ -12,14 +10,12 @@ import { IIssue, ISearchIssueResponse, UserAuth } from "types";
type Props = { type Props = {
onChange: (value: string) => void; onChange: (value: string) => void;
issueDetails: IIssue | undefined; issueDetails: IIssue | undefined;
userAuth: UserAuth;
disabled?: boolean; disabled?: boolean;
}; };
export const SidebarParentSelect: React.FC<Props> = ({ export const SidebarParentSelect: React.FC<Props> = ({
onChange, onChange,
issueDetails, issueDetails,
userAuth,
disabled = false, disabled = false,
}) => { }) => {
const [isParentModalOpen, setIsParentModalOpen] = useState(false); const [isParentModalOpen, setIsParentModalOpen] = useState(false);
@ -28,42 +24,34 @@ export const SidebarParentSelect: React.FC<Props> = ({
const router = useRouter(); const router = useRouter();
const { projectId, issueId } = router.query; const { projectId, issueId } = router.query;
const isNotAllowed = userAuth.isGuest || userAuth.isViewer || disabled;
return ( return (
<div className="flex flex-wrap items-center py-2"> <>
<div className="flex items-center gap-x-2 text-sm text-custom-text-200 sm:basis-1/2"> <ParentIssuesListModal
<UserIcon className="h-4 w-4 flex-shrink-0" /> isOpen={isParentModalOpen}
<p>Parent</p> handleClose={() => setIsParentModalOpen(false)}
</div> onChange={(issue) => {
<div className="sm:basis-1/2"> onChange(issue.id);
<ParentIssuesListModal setSelectedParentIssue(issue);
isOpen={isParentModalOpen} }}
handleClose={() => setIsParentModalOpen(false)} issueId={issueId as string}
onChange={(issue) => { projectId={projectId as string}
onChange(issue.id); />
setSelectedParentIssue(issue); <button
}} type="button"
issueId={issueId as string} className={`bg-custom-background-80 text-xs rounded px-2.5 py-0.5 ${
projectId={projectId as string} disabled ? "cursor-not-allowed" : "cursor-pointer "
/> }`}
<button onClick={() => setIsParentModalOpen(true)}
type="button" disabled={disabled}
className={`flex w-full ${ >
isNotAllowed ? "cursor-not-allowed" : "cursor-pointer hover:bg-custom-background-80" {selectedParentIssue && issueDetails?.parent ? (
} items-center justify-between gap-1 rounded-md border border-custom-border-200 px-2 py-1 text-xs shadow-sm duration-300 focus:outline-none`} `${selectedParentIssue.project__identifier}-${selectedParentIssue.sequence_id}`
onClick={() => setIsParentModalOpen(true)} ) : !selectedParentIssue && issueDetails?.parent ? (
disabled={isNotAllowed} `${issueDetails.parent_detail?.project_detail.identifier}-${issueDetails.parent_detail?.sequence_id}`
> ) : (
{selectedParentIssue && issueDetails?.parent ? ( <span className="text-custom-text-200">Select issue</span>
`${selectedParentIssue.project__identifier}-${selectedParentIssue.sequence_id}` )}
) : !selectedParentIssue && issueDetails?.parent ? ( </button>
`${issueDetails.parent_detail?.project_detail.identifier}-${issueDetails.parent_detail?.sequence_id}` </>
) : (
<span className="text-custom-text-200">Select issue</span>
)}
</button>
</div>
</div>
); );
}; };

View File

@ -18,7 +18,7 @@ export const SidebarPrioritySelect: React.FC<Props> = ({ value, onChange, disabl
customButton={ customButton={
<button <button
type="button" type="button"
className={`flex items-center gap-1.5 text-left text-sm capitalize rounded px-2.5 py-0.5 ${ className={`flex items-center gap-1.5 text-left text-xs capitalize rounded px-2.5 py-0.5 ${
value === "urgent" value === "urgent"
? "border-red-500/20 bg-red-500/20 text-red-500" ? "border-red-500/20 bg-red-500/20 text-red-500"
: value === "high" : value === "high"

View File

@ -39,7 +39,7 @@ export const SidebarStateSelect: React.FC<Props> = ({ value, onChange, disabled
return ( return (
<CustomSelect <CustomSelect
customButton={ customButton={
<button type="button" className="bg-custom-background-80 text-sm rounded px-2.5 py-0.5"> <button type="button" className="bg-custom-background-80 text-xs rounded px-2.5 py-0.5">
{selectedState ? ( {selectedState ? (
<div className="flex items-center gap-1.5 text-left text-custom-text-100"> <div className="flex items-center gap-1.5 text-left text-custom-text-100">
{getStateGroupIcon( {getStateGroupIcon(

View File

@ -10,6 +10,7 @@ import { Controller, UseFormWatch } from "react-hook-form";
import useToast from "hooks/use-toast"; import useToast from "hooks/use-toast";
import useUserAuth from "hooks/use-user-auth"; import useUserAuth from "hooks/use-user-auth";
import useUserIssueNotificationSubscription from "hooks/use-issue-notification-subscription"; import useUserIssueNotificationSubscription from "hooks/use-issue-notification-subscription";
import useEstimateOption from "hooks/use-estimate-option";
// services // services
import issuesService from "services/issues.service"; import issuesService from "services/issues.service";
import modulesService from "services/modules.service"; import modulesService from "services/modules.service";
@ -42,6 +43,8 @@ import {
ChartBarIcon, ChartBarIcon,
UserGroupIcon, UserGroupIcon,
PlayIcon, PlayIcon,
UserIcon,
RectangleGroupIcon,
} from "@heroicons/react/24/outline"; } from "@heroicons/react/24/outline";
// helpers // helpers
import { copyTextToClipboard } from "helpers/string.helper"; import { copyTextToClipboard } from "helpers/string.helper";
@ -49,6 +52,7 @@ import { copyTextToClipboard } from "helpers/string.helper";
import type { ICycle, IIssue, IIssueLink, linkDetails, IModule } from "types"; import type { ICycle, IIssue, IIssueLink, linkDetails, IModule } from "types";
// fetch-keys // fetch-keys
import { ISSUE_DETAILS } from "constants/fetch-keys"; import { ISSUE_DETAILS } from "constants/fetch-keys";
import { ContrastIcon } from "components/icons";
type Props = { type Props = {
control: any; control: any;
@ -93,6 +97,8 @@ export const IssueDetailsSidebar: React.FC<Props> = ({
const { user } = useUserAuth(); const { user } = useUserAuth();
const { isEstimateActive } = useEstimateOption();
const { loading, handleSubscribe, handleUnsubscribe, subscribed } = const { loading, handleSubscribe, handleUnsubscribe, subscribed } =
useUserIssueNotificationSubscription(workspaceSlug, projectId, issueId); useUserIssueNotificationSubscription(workspaceSlug, projectId, issueId);
@ -403,22 +409,51 @@ export const IssueDetailsSidebar: React.FC<Props> = ({
</div> </div>
</div> </div>
)} )}
{(fieldsToShow.includes("all") || fieldsToShow.includes("estimate")) && ( {(fieldsToShow.includes("all") || fieldsToShow.includes("estimate")) &&
isEstimateActive && (
<div className="flex flex-wrap items-center py-2">
<div className="flex items-center gap-x-2 text-sm text-custom-text-200 sm:basis-1/2">
<PlayIcon className="h-4 w-4 flex-shrink-0 -rotate-90" />
<p>Estimate</p>
</div>
<div className="sm:basis-1/2">
<Controller
control={control}
name="estimate_point"
render={({ field: { value } }) => (
<SidebarEstimateSelect
value={value}
onChange={(val: number | null) =>
submitChanges({ estimate_point: val })
}
disabled={memberRole.isGuest || memberRole.isViewer || uneditable}
/>
)}
/>
</div>
</div>
)}
</div>
)}
{showSecondSection && (
<div className="py-1">
{(fieldsToShow.includes("all") || fieldsToShow.includes("parent")) && (
<div className="flex flex-wrap items-center py-2"> <div className="flex flex-wrap items-center py-2">
<div className="flex items-center gap-x-2 text-sm text-custom-text-200 sm:basis-1/2"> <div className="flex items-center gap-x-2 text-sm text-custom-text-200 sm:basis-1/2">
<PlayIcon className="h-4 w-4 flex-shrink-0 -rotate-90" /> <UserIcon className="h-4 w-4 flex-shrink-0" />
<p>Estimate</p> <p>Parent</p>
</div> </div>
<div className="sm:basis-1/2"> <div className="sm:basis-1/2">
<Controller <Controller
control={control} control={control}
name="estimate_point" name="parent"
render={({ field: { value } }) => ( render={({ field: { onChange } }) => (
<SidebarEstimateSelect <SidebarParentSelect
value={value} onChange={(val: string) => {
onChange={(val: number | null) => submitChanges({ parent: val });
submitChanges({ estimate_point: val }) onChange(val);
} }}
issueDetails={issueDetail}
disabled={memberRole.isGuest || memberRole.isViewer || uneditable} disabled={memberRole.isGuest || memberRole.isViewer || uneditable}
/> />
)} )}
@ -426,34 +461,12 @@ export const IssueDetailsSidebar: React.FC<Props> = ({
</div> </div>
</div> </div>
)} )}
</div>
)}
{showSecondSection && (
<div className="py-1">
{(fieldsToShow.includes("all") || fieldsToShow.includes("parent")) && (
<Controller
control={control}
name="parent"
render={({ field: { onChange } }) => (
<SidebarParentSelect
onChange={(val: string) => {
submitChanges({ parent: val });
onChange(val);
}}
issueDetails={issueDetail}
userAuth={memberRole}
disabled={uneditable}
/>
)}
/>
)}
{(fieldsToShow.includes("all") || fieldsToShow.includes("blocker")) && ( {(fieldsToShow.includes("all") || fieldsToShow.includes("blocker")) && (
<SidebarBlockerSelect <SidebarBlockerSelect
issueId={issueId as string} issueId={issueId as string}
submitChanges={submitChanges} submitChanges={submitChanges}
watch={watchIssue} watch={watchIssue}
userAuth={memberRole} disabled={memberRole.isGuest || memberRole.isViewer || uneditable}
disabled={uneditable}
/> />
)} )}
{(fieldsToShow.includes("all") || fieldsToShow.includes("blocked")) && ( {(fieldsToShow.includes("all") || fieldsToShow.includes("blocked")) && (
@ -461,8 +474,7 @@ export const IssueDetailsSidebar: React.FC<Props> = ({
issueId={issueId as string} issueId={issueId as string}
submitChanges={submitChanges} submitChanges={submitChanges}
watch={watchIssue} watch={watchIssue}
userAuth={memberRole} disabled={memberRole.isGuest || memberRole.isViewer || uneditable}
disabled={uneditable}
/> />
)} )}
{(fieldsToShow.includes("all") || fieldsToShow.includes("startDate")) && ( {(fieldsToShow.includes("all") || fieldsToShow.includes("startDate")) && (
@ -484,8 +496,7 @@ export const IssueDetailsSidebar: React.FC<Props> = ({
start_date: val, start_date: val,
}) })
} }
className="bg-custom-background-100" className="bg-custom-background-80 border-none"
wrapperClassName="w-full"
maxDate={maxDate ?? undefined} maxDate={maxDate ?? undefined}
disabled={isNotAllowed || uneditable} disabled={isNotAllowed || uneditable}
/> />
@ -513,8 +524,7 @@ export const IssueDetailsSidebar: React.FC<Props> = ({
target_date: val, target_date: val,
}) })
} }
className="bg-custom-background-100" className="bg-custom-background-80 border-none"
wrapperClassName="w-full"
minDate={minDate ?? undefined} minDate={minDate ?? undefined}
disabled={isNotAllowed || uneditable} disabled={isNotAllowed || uneditable}
/> />
@ -528,20 +538,34 @@ export const IssueDetailsSidebar: React.FC<Props> = ({
{showThirdSection && ( {showThirdSection && (
<div className="py-1"> <div className="py-1">
{(fieldsToShow.includes("all") || fieldsToShow.includes("cycle")) && ( {(fieldsToShow.includes("all") || fieldsToShow.includes("cycle")) && (
<SidebarCycleSelect <div className="flex flex-wrap items-center py-2">
issueDetail={issueDetail} <div className="flex items-center gap-x-2 text-sm text-custom-text-200 sm:w-1/2">
handleCycleChange={handleCycleChange} <ContrastIcon className="h-4 w-4 flex-shrink-0" />
userAuth={memberRole} <p>Cycle</p>
disabled={uneditable} </div>
/> <div className="space-y-1 sm:w-1/2">
<SidebarCycleSelect
issueDetail={issueDetail}
handleCycleChange={handleCycleChange}
disabled={memberRole.isGuest || memberRole.isViewer || uneditable}
/>
</div>
</div>
)} )}
{(fieldsToShow.includes("all") || fieldsToShow.includes("module")) && ( {(fieldsToShow.includes("all") || fieldsToShow.includes("module")) && (
<SidebarModuleSelect <div className="flex flex-wrap items-center py-2">
issueDetail={issueDetail} <div className="flex items-center gap-x-2 text-sm text-custom-text-200 sm:w-1/2">
handleModuleChange={handleModuleChange} <RectangleGroupIcon className="h-4 w-4 flex-shrink-0" />
userAuth={memberRole} <p>Module</p>
disabled={uneditable} </div>
/> <div className="space-y-1 sm:w-1/2">
<SidebarModuleSelect
issueDetail={issueDetail}
handleModuleChange={handleModuleChange}
disabled={memberRole.isGuest || memberRole.isViewer || uneditable}
/>
</div>
</div>
)} )}
</div> </div>
)} )}