[WEB-1111] chore: added a helper function to check if issue is peeked (#4305)

* chore: added a helper function to check if issue is peeked

* chore: make the kanban block observer

* chore: rename isIssuePeekd helper function
This commit is contained in:
Aaryan Khandelwal 2024-04-30 17:20:02 +05:30 committed by GitHub
parent e5681534d7
commit 1b79517f07
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 39 additions and 55 deletions

View File

@ -36,7 +36,7 @@ export const GanttChartBlock: React.FC<Props> = observer((props) => {
} = props; } = props;
// store hooks // store hooks
const { updateActiveBlockId, isBlockActive } = useGanttChart(); const { updateActiveBlockId, isBlockActive } = useGanttChart();
const { peekIssue } = useIssueDetail(); const { getIsIssuePeeked } = useIssueDetail();
const isBlockVisibleOnChart = block.start_date && block.target_date; const isBlockVisibleOnChart = block.start_date && block.target_date;
@ -81,8 +81,9 @@ export const GanttChartBlock: React.FC<Props> = observer((props) => {
<div <div
className={cn("relative h-full", { className={cn("relative h-full", {
"bg-custom-background-80": isBlockActive(block.id), "bg-custom-background-80": isBlockActive(block.id),
"rounded-l border border-r-0 border-custom-primary-70 hover:border-custom-primary-70": "rounded-l border border-r-0 border-custom-primary-70 hover:border-custom-primary-70": getIsIssuePeeked(
peekIssue?.issueId === block.data.id, block.data.id
),
})} })}
onMouseEnter={() => updateActiveBlockId(block.id)} onMouseEnter={() => updateActiveBlockId(block.id)}
onMouseLeave={() => updateActiveBlockId(null)} onMouseLeave={() => updateActiveBlockId(null)}

View File

@ -25,7 +25,7 @@ export const IssuesSidebarBlock: React.FC<Props> = observer((props) => {
const { block, enableReorder, provided, snapshot } = props; const { block, enableReorder, provided, snapshot } = props;
// store hooks // store hooks
const { updateActiveBlockId, isBlockActive } = useGanttChart(); const { updateActiveBlockId, isBlockActive } = useGanttChart();
const { peekIssue } = useIssueDetail(); const { getIsIssuePeeked } = useIssueDetail();
const duration = findTotalDaysInRange(block.start_date, block.target_date); const duration = findTotalDaysInRange(block.start_date, block.target_date);
@ -33,8 +33,9 @@ export const IssuesSidebarBlock: React.FC<Props> = observer((props) => {
<div <div
className={cn({ className={cn({
"rounded bg-custom-background-80": snapshot.isDragging, "rounded bg-custom-background-80": snapshot.isDragging,
"rounded-l border border-r-0 border-custom-primary-70 hover:border-custom-primary-70": "rounded-l border border-r-0 border-custom-primary-70 hover:border-custom-primary-70": getIsIssuePeeked(
peekIssue?.issueId === block.data.id, block.data.id
),
})} })}
onMouseEnter={() => updateActiveBlockId(block.id)} onMouseEnter={() => updateActiveBlockId(block.id)}
onMouseLeave={() => updateActiveBlockId(null)} onMouseLeave={() => updateActiveBlockId(null)}

View File

@ -27,7 +27,7 @@ export const CalendarIssueBlock: React.FC<Props> = observer((props) => {
} = useApplication(); } = useApplication();
const { getProjectIdentifierById } = useProject(); const { getProjectIdentifierById } = useProject();
const { getProjectStates } = useProjectState(); const { getProjectStates } = useProjectState();
const { peekIssue, setPeekIssue } = useIssueDetail(); const { getIsIssuePeeked, setPeekIssue } = useIssueDetail();
const { isMobile } = usePlatformOS(); const { isMobile } = usePlatformOS();
// states // states
const [isMenuActive, setIsMenuActive] = useState(false); const [isMenuActive, setIsMenuActive] = useState(false);
@ -41,7 +41,7 @@ export const CalendarIssueBlock: React.FC<Props> = observer((props) => {
issue && issue &&
issue.project_id && issue.project_id &&
issue.id && issue.id &&
peekIssue?.issueId !== issue.id && !getIsIssuePeeked(issue.id) &&
setPeekIssue({ workspaceSlug, projectId: issue.project_id, issueId: issue.id }); setPeekIssue({ workspaceSlug, projectId: issue.project_id, issueId: issue.id });
useOutsideClickDetector(menuActionRef, () => setIsMenuActive(false)); useOutsideClickDetector(menuActionRef, () => setIsMenuActive(false));
@ -82,10 +82,8 @@ export const CalendarIssueBlock: React.FC<Props> = observer((props) => {
"group/calendar-block flex h-10 md:h-8 w-full items-center justify-between gap-1.5 rounded border-b md:border-[0.5px] border-custom-border-200 hover:border-custom-border-400 md:px-1 px-4 py-1.5 ", "group/calendar-block flex h-10 md:h-8 w-full items-center justify-between gap-1.5 rounded border-b md:border-[0.5px] border-custom-border-200 hover:border-custom-border-400 md:px-1 px-4 py-1.5 ",
{ {
"bg-custom-background-90 shadow-custom-shadow-rg border-custom-primary-100": isDragging, "bg-custom-background-90 shadow-custom-shadow-rg border-custom-primary-100": isDragging,
}, "bg-custom-background-100 hover:bg-custom-background-90": !isDragging,
{ "bg-custom-background-100 hover:bg-custom-background-90": !isDragging }, "border border-custom-primary-70 hover:border-custom-primary-70": getIsIssuePeeked(issue.id),
{
"border border-custom-primary-70 hover:border-custom-primary-70": peekIssue?.issueId === issue.id,
} }
)} )}
> >

View File

@ -20,7 +20,7 @@ export const IssueGanttBlock: React.FC<Props> = observer((props) => {
const { getProjectStates } = useProjectState(); const { getProjectStates } = useProjectState();
const { const {
issue: { getIssueById }, issue: { getIssueById },
peekIssue, getIsIssuePeeked,
setPeekIssue, setPeekIssue,
} = useIssueDetail(); } = useIssueDetail();
// derived values // derived values
@ -32,7 +32,7 @@ export const IssueGanttBlock: React.FC<Props> = observer((props) => {
workspaceSlug && workspaceSlug &&
issueDetails && issueDetails &&
!issueDetails.tempId && !issueDetails.tempId &&
peekIssue?.issueId !== issueDetails.id && !getIsIssuePeeked(issueDetails.id) &&
setPeekIssue({ workspaceSlug, projectId: issueDetails.project_id, issueId: issueDetails.id }); setPeekIssue({ workspaceSlug, projectId: issueDetails.project_id, issueId: issueDetails.id });
const { isMobile } = usePlatformOS(); const { isMobile } = usePlatformOS();

View File

@ -1,4 +1,4 @@
import { MutableRefObject, memo, useEffect, useRef, useState } from "react"; import { MutableRefObject, useEffect, useRef, useState } from "react";
import { combine } from "@atlaskit/pragmatic-drag-and-drop/combine"; import { combine } from "@atlaskit/pragmatic-drag-and-drop/combine";
import { draggable, dropTargetForElements } from "@atlaskit/pragmatic-drag-and-drop/element/adapter"; import { draggable, dropTargetForElements } from "@atlaskit/pragmatic-drag-and-drop/element/adapter";
import { observer } from "mobx-react-lite"; import { observer } from "mobx-react-lite";
@ -17,7 +17,6 @@ import { WithDisplayPropertiesHOC } from "../properties/with-display-properties-
// helper // helper
interface IssueBlockProps { interface IssueBlockProps {
peekIssueId?: string;
issueId: string; issueId: string;
issuesMap: IIssueMap; issuesMap: IIssueMap;
displayProperties: IIssueDisplayProperties | undefined; displayProperties: IIssueDisplayProperties | undefined;
@ -89,9 +88,8 @@ const KanbanIssueDetailsBlock: React.FC<IssueDetailsBlockProps> = observer((prop
); );
}); });
export const KanbanIssueBlock: React.FC<IssueBlockProps> = memo((props) => { export const KanbanIssueBlock: React.FC<IssueBlockProps> = observer((props) => {
const { const {
peekIssueId,
issueId, issueId,
issuesMap, issuesMap,
displayProperties, displayProperties,
@ -107,14 +105,14 @@ export const KanbanIssueBlock: React.FC<IssueBlockProps> = memo((props) => {
const { const {
router: { workspaceSlug }, router: { workspaceSlug },
} = useApplication(); } = useApplication();
const { peekIssue, setPeekIssue } = useIssueDetail(); const { getIsIssuePeeked, setPeekIssue } = useIssueDetail();
const handleIssuePeekOverview = (issue: TIssue) => const handleIssuePeekOverview = (issue: TIssue) =>
workspaceSlug && workspaceSlug &&
issue && issue &&
issue.project_id && issue.project_id &&
issue.id && issue.id &&
peekIssue?.issueId !== issue.id && !getIsIssuePeeked(issue.id) &&
setPeekIssue({ workspaceSlug, projectId: issue.project_id, issueId: issue.id }); setPeekIssue({ workspaceSlug, projectId: issue.project_id, issueId: issue.id });
const issue = issuesMap[issueId]; const issue = issuesMap[issueId];
@ -184,9 +182,11 @@ export const KanbanIssueBlock: React.FC<IssueBlockProps> = memo((props) => {
ref={cardRef} ref={cardRef}
className={cn( className={cn(
"block rounded border-[0.5px] outline-[0.5px] outline-transparent w-full border-custom-border-200 bg-custom-background-100 text-sm transition-all hover:border-custom-border-400", "block rounded border-[0.5px] outline-[0.5px] outline-transparent w-full border-custom-border-200 bg-custom-background-100 text-sm transition-all hover:border-custom-border-400",
{ "hover:cursor-pointer": isDragAllowed }, {
{ "border border-custom-primary-70 hover:border-custom-primary-70": peekIssueId === issue.id }, "hover:cursor-pointer": isDragAllowed,
{ "bg-custom-background-80 z-[100]": isCurrentBlockDragging } "border border-custom-primary-70 hover:border-custom-primary-70": getIsIssuePeeked(issue.id),
"bg-custom-background-80 z-[100]": isCurrentBlockDragging,
}
)} )}
target="_blank" target="_blank"
onClick={() => handleIssuePeekOverview(issue)} onClick={() => handleIssuePeekOverview(issue)}

View File

@ -8,7 +8,6 @@ interface IssueBlocksListProps {
sub_group_id: string; sub_group_id: string;
columnId: string; columnId: string;
issuesMap: IIssueMap; issuesMap: IIssueMap;
peekIssueId?: string;
issueIds: string[]; issueIds: string[];
displayProperties: IIssueDisplayProperties | undefined; displayProperties: IIssueDisplayProperties | undefined;
isDragDisabled: boolean; isDragDisabled: boolean;
@ -23,7 +22,6 @@ const KanbanIssueBlocksListMemo: React.FC<IssueBlocksListProps> = (props) => {
sub_group_id, sub_group_id,
columnId, columnId,
issuesMap, issuesMap,
peekIssueId,
issueIds, issueIds,
displayProperties, displayProperties,
isDragDisabled, isDragDisabled,
@ -47,7 +45,6 @@ const KanbanIssueBlocksListMemo: React.FC<IssueBlocksListProps> = (props) => {
return ( return (
<KanbanIssueBlock <KanbanIssueBlock
key={draggableId} key={draggableId}
peekIssueId={peekIssueId}
issueId={issueId} issueId={issueId}
issuesMap={issuesMap} issuesMap={issuesMap}
displayProperties={displayProperties} displayProperties={displayProperties}

View File

@ -14,16 +14,7 @@ import {
} from "@plane/types"; } from "@plane/types";
// constants // constants
// hooks // hooks
import { import { useCycle, useKanbanView, useLabel, useMember, useModule, useProject, useProjectState } from "@/hooks/store";
useCycle,
useIssueDetail,
useKanbanView,
useLabel,
useMember,
useModule,
useProject,
useProjectState,
} from "@/hooks/store";
// types // types
// parent components // parent components
import { getGroupByColumns, isWorkspaceLevel } from "../utils"; import { getGroupByColumns, isWorkspaceLevel } from "../utils";
@ -95,7 +86,6 @@ const GroupByKanBan: React.FC<IGroupByKanBan> = observer((props) => {
const cycle = useCycle(); const cycle = useCycle();
const moduleInfo = useModule(); const moduleInfo = useModule();
const projectState = useProjectState(); const projectState = useProjectState();
const { peekIssue } = useIssueDetail();
const list = getGroupByColumns( const list = getGroupByColumns(
group_by as GroupByColumnTypes, group_by as GroupByColumnTypes,
@ -176,7 +166,6 @@ const GroupByKanBan: React.FC<IGroupByKanBan> = observer((props) => {
groupId={subList.id} groupId={subList.id}
issuesMap={issuesMap} issuesMap={issuesMap}
issueIds={issueIds} issueIds={issueIds}
peekIssueId={peekIssue?.issueId ?? ""}
displayProperties={displayProperties} displayProperties={displayProperties}
sub_group_by={sub_group_by} sub_group_by={sub_group_by}
group_by={group_by} group_by={group_by}

View File

@ -23,7 +23,6 @@ import { KanbanIssueBlocksList, KanBanQuickAddIssueForm } from ".";
interface IKanbanGroup { interface IKanbanGroup {
groupId: string; groupId: string;
issuesMap: IIssueMap; issuesMap: IIssueMap;
peekIssueId?: string;
issueIds: TGroupedIssues | TSubGroupedIssues | TUnGroupedIssues; issueIds: TGroupedIssues | TSubGroupedIssues | TUnGroupedIssues;
displayProperties: IIssueDisplayProperties | undefined; displayProperties: IIssueDisplayProperties | undefined;
sub_group_by: TIssueGroupByOptions | undefined; sub_group_by: TIssueGroupByOptions | undefined;
@ -56,7 +55,6 @@ export const KanbanGroup = (props: IKanbanGroup) => {
issuesMap, issuesMap,
displayProperties, displayProperties,
issueIds, issueIds,
peekIssueId,
isDragDisabled, isDragDisabled,
updateIssue, updateIssue,
quickActions, quickActions,
@ -176,7 +174,6 @@ export const KanbanGroup = (props: IKanbanGroup) => {
sub_group_id={sub_group_id} sub_group_id={sub_group_id}
columnId={groupId} columnId={groupId}
issuesMap={issuesMap} issuesMap={issuesMap}
peekIssueId={peekIssueId}
issueIds={(issueIds as TGroupedIssues)?.[groupId] || []} issueIds={(issueIds as TGroupedIssues)?.[groupId] || []}
displayProperties={displayProperties} displayProperties={displayProperties}
isDragDisabled={isDragDisabled} isDragDisabled={isDragDisabled}

View File

@ -27,14 +27,14 @@ export const IssueBlock: React.FC<IssueBlockProps> = observer((props: IssueBlock
router: { workspaceSlug }, router: { workspaceSlug },
} = useApplication(); } = useApplication();
const { getProjectIdentifierById } = useProject(); const { getProjectIdentifierById } = useProject();
const { peekIssue, setPeekIssue } = useIssueDetail(); const { getIsIssuePeeked, setPeekIssue } = useIssueDetail();
const handleIssuePeekOverview = (issue: TIssue) => const handleIssuePeekOverview = (issue: TIssue) =>
workspaceSlug && workspaceSlug &&
issue && issue &&
issue.project_id && issue.project_id &&
issue.id && issue.id &&
peekIssue?.issueId !== issue.id && !getIsIssuePeeked(issue.id) &&
setPeekIssue({ workspaceSlug, projectId: issue.project_id, issueId: issue.id }); setPeekIssue({ workspaceSlug, projectId: issue.project_id, issueId: issue.id });
const issue = issuesMap[issueId]; const issue = issuesMap[issueId];
@ -49,8 +49,8 @@ export const IssueBlock: React.FC<IssueBlockProps> = observer((props: IssueBlock
className={cn( className={cn(
"min-h-12 relative flex flex-col md:flex-row md:items-center gap-3 bg-custom-background-100 p-3 text-sm", "min-h-12 relative flex flex-col md:flex-row md:items-center gap-3 bg-custom-background-100 p-3 text-sm",
{ {
"border border-custom-primary-70 hover:border-custom-primary-70": peekIssue && peekIssue.issueId === issue.id, "border border-custom-primary-70 hover:border-custom-primary-70": getIsIssuePeeked(issue.id),
"last:border-b-transparent": peekIssue?.issueId !== issue.id, "last:border-b-transparent": !getIsIssuePeeked(issue.id),
} }
)} )}
> >

View File

@ -148,7 +148,7 @@ const IssueRowDetails = observer((props: IssueRowDetailsProps) => {
const { workspaceSlug } = router.query; const { workspaceSlug } = router.query;
//hooks //hooks
const { getProjectIdentifierById } = useProject(); const { getProjectIdentifierById } = useProject();
const { peekIssue, setPeekIssue } = useIssueDetail(); const { getIsIssuePeeked, setPeekIssue } = useIssueDetail();
const { isMobile } = usePlatformOS(); const { isMobile } = usePlatformOS();
// states // states
const [isMenuActive, setIsMenuActive] = useState(false); const [isMenuActive, setIsMenuActive] = useState(false);
@ -159,7 +159,7 @@ const IssueRowDetails = observer((props: IssueRowDetailsProps) => {
issue && issue &&
issue.project_id && issue.project_id &&
issue.id && issue.id &&
peekIssue?.issueId !== issue.id && !getIsIssuePeeked(issue.id) &&
setPeekIssue({ workspaceSlug: workspaceSlug.toString(), projectId: issue.project_id, issueId: issue.id }); setPeekIssue({ workspaceSlug: workspaceSlug.toString(), projectId: issue.project_id, issueId: issue.id });
const { subIssues: subIssuesStore, issue } = useIssueDetail(); const { subIssues: subIssuesStore, issue } = useIssueDetail();
@ -200,12 +200,8 @@ const IssueRowDetails = observer((props: IssueRowDetailsProps) => {
className={cn( className={cn(
"sticky group left-0 h-11 w-[28rem] flex items-center bg-custom-background-100 text-sm after:absolute border-r-[0.5px] z-10 border-custom-border-200", "sticky group left-0 h-11 w-[28rem] flex items-center bg-custom-background-100 text-sm after:absolute border-r-[0.5px] z-10 border-custom-border-200",
{ {
"border-b-[0.5px]": peekIssue?.issueId !== issueDetail.id, "border-b-[0.5px]": !getIsIssuePeeked(issueDetail.id),
}, "border border-custom-primary-70 hover:border-custom-primary-70": getIsIssuePeeked(issueDetail.id),
{
"border border-custom-primary-70 hover:border-custom-primary-70": peekIssue?.issueId === issueDetail.id,
},
{
"shadow-[8px_22px_22px_10px_rgba(0,0,0,0.05)]": isScrolled.current, "shadow-[8px_22px_22px_10px_rgba(0,0,0,0.05)]": isScrolled.current,
} }
)} )}

View File

@ -42,7 +42,7 @@ export const IssueListItem: React.FC<ISubIssues> = observer((props) => {
} = props; } = props;
const { const {
peekIssue, getIsIssuePeeked,
setPeekIssue, setPeekIssue,
issue: { getIssueById }, issue: { getIssueById },
subIssues: { subIssueHelpersByIssueId, setSubIssueHelpers }, subIssues: { subIssueHelpersByIssueId, setSubIssueHelpers },
@ -65,7 +65,7 @@ export const IssueListItem: React.FC<ISubIssues> = observer((props) => {
issue && issue &&
issue.project_id && issue.project_id &&
issue.id && issue.id &&
peekIssue?.issueId !== issue.id && !getIsIssuePeeked(issue.id) &&
setPeekIssue({ workspaceSlug, projectId: issue.project_id, issueId: issue.id }); setPeekIssue({ workspaceSlug, projectId: issue.project_id, issueId: issue.id });
if (!issue) return <></>; if (!issue) return <></>;

View File

@ -54,6 +54,8 @@ export interface IIssueDetail
isDeleteAttachmentModalOpen: boolean; isDeleteAttachmentModalOpen: boolean;
// computed // computed
isAnyModalOpen: boolean; isAnyModalOpen: boolean;
// helper actions
getIsIssuePeeked: (issueId: string) => boolean;
// actions // actions
setPeekIssue: (peekIssue: TPeekIssue | undefined) => void; setPeekIssue: (peekIssue: TPeekIssue | undefined) => void;
toggleCreateIssueModal: (value: boolean) => void; toggleCreateIssueModal: (value: boolean) => void;
@ -156,6 +158,9 @@ export class IssueDetail implements IIssueDetail {
); );
} }
// helper actions
getIsIssuePeeked = (issueId: string) => this.peekIssue?.issueId === issueId;
// actions // actions
setPeekIssue = (peekIssue: TPeekIssue | undefined) => (this.peekIssue = peekIssue); setPeekIssue = (peekIssue: TPeekIssue | undefined) => (this.peekIssue = peekIssue);
toggleCreateIssueModal = (value: boolean) => (this.isCreateIssueModalOpen = value); toggleCreateIssueModal = (value: boolean) => (this.isCreateIssueModalOpen = value);