Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 33 additions & 36 deletions apps/app/components/core/board-view/all-boards.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
// react-beautiful-dnd
import { DragDropContext, DropResult } from "react-beautiful-dnd";
// hooks
import useIssueView from "hooks/use-issue-view";
// components
Expand All @@ -15,7 +13,7 @@ type Props = {
addIssueToState: (groupTitle: string, stateId: string | null) => void;
openIssuesListModal?: (() => void) | null;
handleDeleteIssue: (issue: IIssue) => void;
handleOnDragEnd: (result: DropResult) => void;
handleTrashBox: (isDragging: boolean) => void;
userAuth: UserAuth;
};

Expand All @@ -27,7 +25,7 @@ export const AllBoards: React.FC<Props> = ({
addIssueToState,
openIssuesListModal,
handleDeleteIssue,
handleOnDragEnd,
handleTrashBox,
userAuth,
}) => {
const { groupedByIssues, groupByProperty: selectedGroup, orderBy } = useIssueView(issues);
Expand All @@ -36,42 +34,41 @@ export const AllBoards: React.FC<Props> = ({
<>
{groupedByIssues ? (
<div className="h-[calc(100vh-157px)] lg:h-[calc(100vh-115px)] w-full">
<DragDropContext onDragEnd={handleOnDragEnd}>
<div className="h-full w-full overflow-hidden">
<div className="h-full w-full">
<div className="flex h-full gap-x-4 overflow-x-auto overflow-y-hidden">
{Object.keys(groupedByIssues).map((singleGroup, index) => {
const stateId =
selectedGroup === "state_detail.name"
? states?.find((s) => s.name === singleGroup)?.id ?? null
: null;
<div className="h-full w-full overflow-hidden">
<div className="h-full w-full">
<div className="flex h-full gap-x-4 overflow-x-auto overflow-y-hidden">
{Object.keys(groupedByIssues).map((singleGroup, index) => {
const stateId =
selectedGroup === "state_detail.name"
? states?.find((s) => s.name === singleGroup)?.id ?? null
: null;

const bgColor =
selectedGroup === "state_detail.name"
? states?.find((s) => s.name === singleGroup)?.color
: "#000000";
const bgColor =
selectedGroup === "state_detail.name"
? states?.find((s) => s.name === singleGroup)?.color
: "#000000";

return (
<SingleBoard
key={index}
type={type}
bgColor={bgColor}
groupTitle={singleGroup}
groupedByIssues={groupedByIssues}
selectedGroup={selectedGroup}
members={members}
addIssueToState={() => addIssueToState(singleGroup, stateId)}
handleDeleteIssue={handleDeleteIssue}
openIssuesListModal={openIssuesListModal ?? null}
orderBy={orderBy}
userAuth={userAuth}
/>
);
})}
</div>
return (
<SingleBoard
key={index}
type={type}
bgColor={bgColor}
groupTitle={singleGroup}
groupedByIssues={groupedByIssues}
selectedGroup={selectedGroup}
members={members}
addIssueToState={() => addIssueToState(singleGroup, stateId)}
handleDeleteIssue={handleDeleteIssue}
openIssuesListModal={openIssuesListModal ?? null}
orderBy={orderBy}
handleTrashBox={handleTrashBox}
userAuth={userAuth}
/>
);
})}
</div>
</div>
</DragDropContext>
</div>
</div>
) : (
<div className="flex h-full w-full items-center justify-center">Loading...</div>
Expand Down
32 changes: 22 additions & 10 deletions apps/app/components/core/board-view/single-board.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ type Props = {
handleDeleteIssue: (issue: IIssue) => void;
openIssuesListModal?: (() => void) | null;
orderBy: NestedKeyOf<IIssue> | "manual" | null;
handleTrashBox: (isDragging: boolean) => void;
userAuth: UserAuth;
};

Expand All @@ -43,6 +44,7 @@ export const SingleBoard: React.FC<Props> = ({
handleDeleteIssue,
openIssuesListModal,
orderBy,
handleTrashBox,
userAuth,
}) => {
// collapse/expand
Expand Down Expand Up @@ -89,17 +91,27 @@ export const SingleBoard: React.FC<Props> = ({
{...provided.droppableProps}
>
{groupedByIssues[groupTitle].map((issue, index: number) => (
<SingleBoardIssue
key={index}
<Draggable
key={issue.id}
draggableId={issue.id}
index={index}
type={type}
issue={issue}
selectedGroup={selectedGroup}
properties={properties}
handleDeleteIssue={handleDeleteIssue}
orderBy={orderBy}
userAuth={userAuth}
/>
isDragDisabled={selectedGroup === "created_by"}
>
{(provided, snapshot) => (
<SingleBoardIssue
key={index}
provided={provided}
snapshot={snapshot}
type={type}
issue={issue}
properties={properties}
handleDeleteIssue={handleDeleteIssue}
orderBy={orderBy}
handleTrashBox={handleTrashBox}
userAuth={userAuth}
/>
)}
</Draggable>
))}
<span
style={{
Expand Down
168 changes: 82 additions & 86 deletions apps/app/components/core/board-view/single-issue.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import React, { useCallback } from "react";
import React, { useCallback, useEffect } from "react";

import Link from "next/link";
import { useRouter } from "next/router";

import useSWR, { mutate } from "swr";
import { mutate } from "swr";

// react-beautiful-dnd
import {
Draggable,
DraggableProvided,
DraggableStateSnapshot,
DraggingStyle,
NotDraggingStyle,
Expand Down Expand Up @@ -37,24 +37,26 @@ import {
import { CYCLE_ISSUES, MODULE_ISSUES, PROJECT_ISSUES_LIST } from "constants/fetch-keys";

type Props = {
index: number;
type?: string;
provided: DraggableProvided;
snapshot: DraggableStateSnapshot;
issue: IIssue;
selectedGroup: NestedKeyOf<IIssue> | null;
properties: Properties;
handleDeleteIssue: (issue: IIssue) => void;
orderBy: NestedKeyOf<IIssue> | "manual" | null;
handleTrashBox: (isDragging: boolean) => void;
userAuth: UserAuth;
};

export const SingleBoardIssue: React.FC<Props> = ({
index,
type,
provided,
snapshot,
issue,
selectedGroup,
properties,
handleDeleteIssue,
orderBy,
handleTrashBox,
userAuth,
}) => {
const router = useRouter();
Expand Down Expand Up @@ -151,90 +153,84 @@ export const SingleBoardIssue: React.FC<Props> = ({

const isNotAllowed = userAuth.isGuest || userAuth.isViewer;

useEffect(() => {
if (snapshot.isDragging) handleTrashBox(snapshot.isDragging);
}, [snapshot, handleTrashBox]);

return (
<Draggable
key={issue.id}
draggableId={issue.id}
index={index}
isDragDisabled={selectedGroup === "created_by"}
<div
className={`rounded border bg-white shadow-sm ${
snapshot.isDragging ? "border-theme bg-indigo-50 shadow-lg" : ""
}`}
ref={provided.innerRef}
{...provided.draggableProps}
{...provided.dragHandleProps}
style={getStyle(provided.draggableProps.style, snapshot)}
>
{(provided, snapshot) => (
<div
className={`rounded border bg-white shadow-sm ${
snapshot.isDragging ? "border-theme bg-indigo-50 shadow-lg" : ""
}`}
ref={provided.innerRef}
{...provided.draggableProps}
{...provided.dragHandleProps}
style={getStyle(provided.draggableProps.style, snapshot)}
>
<div className="group/card relative select-none p-2">
{!isNotAllowed && (
<div className="absolute top-1.5 right-1.5 z-10 opacity-0 group-hover/card:opacity-100">
<button
type="button"
className="grid h-7 w-7 place-items-center rounded bg-white p-1 text-red-500 outline-none duration-300 hover:bg-red-50"
onClick={() => handleDeleteIssue(issue)}
>
<TrashIcon className="h-4 w-4" />
</button>
<div className="group/card relative select-none p-2">
{!isNotAllowed && (
<div className="absolute top-1.5 right-1.5 z-10 opacity-0 group-hover/card:opacity-100">
<button
type="button"
className="grid h-7 w-7 place-items-center rounded bg-white p-1 text-red-500 outline-none duration-300 hover:bg-red-50"
onClick={() => handleDeleteIssue(issue)}
>
<TrashIcon className="h-4 w-4" />
</button>
</div>
)}
<Link href={`/${workspaceSlug}/projects/${issue.project}/issues/${issue.id}`}>
<a>
{properties.key && (
<div className="mb-2 text-xs font-medium text-gray-500">
{issue.project_detail.identifier}-{issue.sequence_id}
</div>
)}
<Link href={`/${workspaceSlug}/projects/${issue.project}/issues/${issue.id}`}>
<a>
{properties.key && (
<div className="mb-2 text-xs font-medium text-gray-500">
{issue.project_detail.identifier}-{issue.sequence_id}
</div>
)}
<h5
className="mb-3 text-sm group-hover:text-theme"
style={{ lineClamp: 3, WebkitLineClamp: 3 }}
>
{issue.name}
</h5>
</a>
</Link>
<div className="flex flex-wrap items-center gap-x-1 gap-y-2 text-xs">
{properties.priority && (
<ViewPrioritySelect
issue={issue}
partialUpdateIssue={partialUpdateIssue}
isNotAllowed={isNotAllowed}
position="left"
/>
)}
{properties.state && (
<ViewStateSelect
issue={issue}
partialUpdateIssue={partialUpdateIssue}
isNotAllowed={isNotAllowed}
/>
)}
{properties.due_date && (
<ViewDueDateSelect
issue={issue}
partialUpdateIssue={partialUpdateIssue}
isNotAllowed={isNotAllowed}
/>
)}
{properties.sub_issue_count && (
<div className="flex flex-shrink-0 items-center gap-1 rounded border px-2 py-1 text-xs shadow-sm duration-300 hover:bg-gray-100 focus:border-indigo-500 focus:outline-none focus:ring-1 focus:ring-indigo-500">
{issue.sub_issues_count}{" "}
{issue.sub_issues_count === 1 ? "sub-issue" : "sub-issues"}
</div>
)}
{properties.assignee && (
<ViewAssigneeSelect
issue={issue}
partialUpdateIssue={partialUpdateIssue}
isNotAllowed={isNotAllowed}
/>
)}
<h5
className="mb-3 text-sm group-hover:text-theme"
style={{ lineClamp: 3, WebkitLineClamp: 3 }}
>
{issue.name}
</h5>
</a>
</Link>
<div className="flex flex-wrap items-center gap-x-1 gap-y-2 text-xs">
{properties.priority && (
<ViewPrioritySelect
issue={issue}
partialUpdateIssue={partialUpdateIssue}
isNotAllowed={isNotAllowed}
position="left"
/>
)}
{properties.state && (
<ViewStateSelect
issue={issue}
partialUpdateIssue={partialUpdateIssue}
isNotAllowed={isNotAllowed}
/>
)}
{properties.due_date && (
<ViewDueDateSelect
issue={issue}
partialUpdateIssue={partialUpdateIssue}
isNotAllowed={isNotAllowed}
/>
)}
{properties.sub_issue_count && (
<div className="flex flex-shrink-0 items-center gap-1 rounded border px-2 py-1 text-xs shadow-sm duration-300 hover:bg-gray-100 focus:border-indigo-500 focus:outline-none focus:ring-1 focus:ring-indigo-500">
{issue.sub_issues_count} {issue.sub_issues_count === 1 ? "sub-issue" : "sub-issues"}
</div>
</div>
)}
{properties.assignee && (
<ViewAssigneeSelect
issue={issue}
partialUpdateIssue={partialUpdateIssue}
isNotAllowed={isNotAllowed}
/>
)}
</div>
)}
</Draggable>
</div>
</div>
);
};
Loading