From 888665783e8bc6a6a7c4c12b01533600e37e38c9 Mon Sep 17 00:00:00 2001 From: Anmol Singh Bhatia <121005188+anmolsinghbhatia@users.noreply.github.com> Date: Tue, 30 Jan 2024 20:12:39 +0530 Subject: [PATCH] feat: issue highlighting (#3514) * chore: kanban issue highlight * chore: issue highlighting added --- .../gantt-chart/blocks/blocks-display.tsx | 12 +++++++++- .../gantt-chart/sidebar/sidebar.tsx | 14 ++++++++++-- .../issue-layouts/calendar/issue-blocks.tsx | 22 +++++++++++++------ .../issues/issue-layouts/kanban/block.tsx | 16 ++++++++++---- .../issue-layouts/kanban/blocks-list.tsx | 3 +++ .../issues/issue-layouts/kanban/default.tsx | 4 +++- .../issue-layouts/kanban/kanban-group.tsx | 3 +++ .../issues/issue-layouts/list/block.tsx | 14 ++++++++++-- .../issues/issue-layouts/list/blocks-list.tsx | 2 +- .../issue-layouts/spreadsheet/issue-row.tsx | 19 +++++++++++++--- .../spreadsheet/spreadsheet-table.tsx | 2 +- 11 files changed, 89 insertions(+), 22 deletions(-) diff --git a/web/components/gantt-chart/blocks/blocks-display.tsx b/web/components/gantt-chart/blocks/blocks-display.tsx index 02d2eb865..e13be116b 100644 --- a/web/components/gantt-chart/blocks/blocks-display.tsx +++ b/web/components/gantt-chart/blocks/blocks-display.tsx @@ -1,9 +1,11 @@ import { FC } from "react"; // hooks +import { useIssueDetail } from "hooks/store"; import { useChart } from "../hooks"; // helpers import { ChartAddBlock, ChartDraggable } from "components/gantt-chart"; import { renderFormattedPayloadDate } from "helpers/date-time.helper"; +import { cn } from "helpers/common.helper"; // types import { IBlockUpdateData, IGanttBlock } from "../types"; @@ -31,6 +33,7 @@ export const GanttChartBlocks: FC = (props) => { } = props; const { activeBlock, dispatch } = useChart(); + const { peekIssue } = useIssueDetail(); // update the active block on hover const updateActiveBlock = (block: IGanttBlock | null) => { @@ -88,7 +91,14 @@ export const GanttChartBlocks: FC = (props) => { return (
updateActiveBlock(block)} onMouseLeave={() => updateActiveBlock(null)} > diff --git a/web/components/gantt-chart/sidebar/sidebar.tsx b/web/components/gantt-chart/sidebar/sidebar.tsx index 062b76451..bca39a0bd 100644 --- a/web/components/gantt-chart/sidebar/sidebar.tsx +++ b/web/components/gantt-chart/sidebar/sidebar.tsx @@ -3,12 +3,14 @@ import { DragDropContext, Draggable, Droppable, DropResult } from "@hello-pangea import { MoreVertical } from "lucide-react"; // hooks import { useChart } from "components/gantt-chart/hooks"; +import { useIssueDetail } from "hooks/store"; // ui import { Loader } from "@plane/ui"; // components import { GanttQuickAddIssueForm, IssueGanttSidebarBlock } from "components/issues"; // helpers import { findTotalDaysInRange } from "helpers/date-time.helper"; +import { cn } from "helpers/common.helper"; // types import { IGanttBlock, IBlockUpdateData } from "components/gantt-chart/types"; import { TIssue } from "@plane/types"; @@ -45,6 +47,7 @@ export const IssueGanttSidebar: React.FC = (props) => { const { cycleId } = router.query; const { activeBlock, dispatch } = useChart(); + const { peekIssue } = useIssueDetail(); // update the active block on hover const updateActiveBlock = (block: IGanttBlock | null) => { @@ -104,7 +107,7 @@ export const IssueGanttSidebar: React.FC = (props) => { {(droppableProvided) => (
@@ -130,7 +133,14 @@ export const IssueGanttSidebar: React.FC = (props) => { > {(provided, snapshot) => (
updateActiveBlock(block)} onMouseLeave={() => updateActiveBlock(null)} ref={provided.innerRef} diff --git a/web/components/issues/issue-layouts/calendar/issue-blocks.tsx b/web/components/issues/issue-layouts/calendar/issue-blocks.tsx index 5711c89f6..f66bf2ec0 100644 --- a/web/components/issues/issue-layouts/calendar/issue-blocks.tsx +++ b/web/components/issues/issue-layouts/calendar/issue-blocks.tsx @@ -6,7 +6,8 @@ import { MoreHorizontal } from "lucide-react"; import { Tooltip, ControlLink } from "@plane/ui"; // hooks import useOutsideClickDetector from "hooks/use-outside-click-detector"; -// ui +// helpers +import { cn } from "helpers/common.helper"; // types import { TIssue, TIssueMap } from "@plane/types"; import { useApplication, useIssueDetail, useProject, useProjectState } from "hooks/store"; @@ -26,7 +27,7 @@ export const CalendarIssueBlocks: React.FC = observer((props) => { } = useApplication(); const { getProjectById } = useProject(); const { getProjectStates } = useProjectState(); - const { setPeekIssue } = useIssueDetail(); + const { peekIssue, setPeekIssue } = useIssueDetail(); // states const [isMenuActive, setIsMenuActive] = useState(false); @@ -84,11 +85,18 @@ export const CalendarIssueBlocks: React.FC = observer((props) => { )}
= observer((prop export const KanbanIssueBlock: React.FC = memo((props) => { const { + peekIssueId, issueId, issuesMap, displayProperties, @@ -121,9 +126,12 @@ export const KanbanIssueBlock: React.FC = memo((props) => {
)}
= (props) => { sub_group_id, columnId, issuesMap, + peekIssueId, issueIds, displayProperties, isDragDisabled, @@ -44,6 +46,7 @@ const KanbanIssueBlocksListMemo: React.FC = (props) => { return ( = observer((props) => { const project = useProject(); const label = useLabel(); const projectState = useProjectState(); + const { peekIssue } = useIssueDetail(); const list = getGroupByColumns(group_by as GroupByColumnTypes, project, label, projectState, member); @@ -120,6 +121,7 @@ const GroupByKanBan: React.FC = observer((props) => { groupId={_list.id} issuesMap={issuesMap} issueIds={issueIds} + peekIssueId={peekIssue?.issueId ?? ""} displayProperties={displayProperties} sub_group_by={sub_group_by} group_by={group_by} diff --git a/web/components/issues/issue-layouts/kanban/kanban-group.tsx b/web/components/issues/issue-layouts/kanban/kanban-group.tsx index 76d456b5e..1a25c563e 100644 --- a/web/components/issues/issue-layouts/kanban/kanban-group.tsx +++ b/web/components/issues/issue-layouts/kanban/kanban-group.tsx @@ -17,6 +17,7 @@ import { EIssueActions } from "../types"; interface IKanbanGroup { groupId: string; issuesMap: IIssueMap; + peekIssueId?: string; issueIds: TGroupedIssues | TSubGroupedIssues | TUnGroupedIssues; displayProperties: IIssueDisplayProperties | undefined; sub_group_by: string | null; @@ -47,6 +48,7 @@ export const KanbanGroup = (props: IKanbanGroup) => { issuesMap, displayProperties, issueIds, + peekIssueId, isDragDisabled, handleIssues, quickActions, @@ -118,6 +120,7 @@ export const KanbanGroup = (props: IKanbanGroup) => { sub_group_id={sub_group_id} columnId={groupId} issuesMap={issuesMap} + peekIssueId={peekIssueId} issueIds={(issueIds as TGroupedIssues)?.[groupId] || []} displayProperties={displayProperties} isDragDisabled={isDragDisabled} diff --git a/web/components/issues/issue-layouts/list/block.tsx b/web/components/issues/issue-layouts/list/block.tsx index da63a834e..b2222a69e 100644 --- a/web/components/issues/issue-layouts/list/block.tsx +++ b/web/components/issues/issue-layouts/list/block.tsx @@ -5,6 +5,8 @@ import { IssueProperties } from "../properties/all-properties"; import { useApplication, useIssueDetail, useProject } from "hooks/store"; // ui import { Spinner, Tooltip, ControlLink } from "@plane/ui"; +// helper +import { cn } from "helpers/common.helper"; // types import { TIssue, IIssueDisplayProperties, TIssueMap } from "@plane/types"; import { EIssueActions } from "../types"; @@ -25,7 +27,7 @@ export const IssueBlock: React.FC = observer((props: IssueBlock router: { workspaceSlug, projectId }, } = useApplication(); const { getProjectById } = useProject(); - const { setPeekIssue } = useIssueDetail(); + const { peekIssue, setPeekIssue } = useIssueDetail(); const updateIssue = (issueToUpdate: TIssue) => { handleIssues(issueToUpdate, EIssueActions.UPDATE); @@ -47,7 +49,15 @@ export const IssueBlock: React.FC = observer((props: IssueBlock return ( <> -
+
{displayProperties && displayProperties?.key && (
{projectDetails?.identifier}-{issue.sequence_id} diff --git a/web/components/issues/issue-layouts/list/blocks-list.tsx b/web/components/issues/issue-layouts/list/blocks-list.tsx index 729cd6c68..5e02d638f 100644 --- a/web/components/issues/issue-layouts/list/blocks-list.tsx +++ b/web/components/issues/issue-layouts/list/blocks-list.tsx @@ -18,7 +18,7 @@ export const IssueBlocksList: FC = (props) => { const { issueIds, issuesMap, handleIssues, quickActions, displayProperties, canEditProperties } = props; return ( -
+
{issueIds && issueIds.length > 0 ? ( issueIds.map((issueId: string) => { if (!issueId) return null; diff --git a/web/components/issues/issue-layouts/spreadsheet/issue-row.tsx b/web/components/issues/issue-layouts/spreadsheet/issue-row.tsx index 602c1a842..579b8863c 100644 --- a/web/components/issues/issue-layouts/spreadsheet/issue-row.tsx +++ b/web/components/issues/issue-layouts/spreadsheet/issue-row.tsx @@ -12,6 +12,8 @@ import { ControlLink, Tooltip } from "@plane/ui"; // hooks import useOutsideClickDetector from "hooks/use-outside-click-detector"; import { useIssueDetail, useProject } from "hooks/store"; +// helper +import { cn } from "helpers/common.helper"; // types import { IIssueDisplayProperties, TIssue } from "@plane/types"; import { EIssueActions } from "../types"; @@ -48,7 +50,7 @@ export const SpreadsheetIssueRow = observer((props: Props) => { const { workspaceSlug } = router.query; //hooks const { getProjectById } = useProject(); - const { setPeekIssue } = useIssueDetail(); + const { peekIssue, setPeekIssue } = useIssueDetail(); // states const [isMenuActive, setIsMenuActive] = useState(false); const [isExpanded, setExpanded] = useState(false); @@ -95,9 +97,20 @@ export const SpreadsheetIssueRow = observer((props: Props) => { return ( <> - + {/* first column/ issue name and key column */} - +
{ } = props; return ( - +