forked from github/plane
style: added dragging state design
This commit is contained in:
parent
f7e0e257a4
commit
8589ce777f
@ -40,7 +40,7 @@ export const AllBoards: React.FC<Props> = ({
|
||||
<div className="h-[calc(100vh-157px)] lg:h-[calc(100vh-115px)] w-full">
|
||||
<div className="h-full w-full overflow-hidden">
|
||||
<div className="h-full w-full">
|
||||
<div className="flex h-full gap-x-12 overflow-x-auto overflow-y-hidden">
|
||||
<div className="flex h-full gap-x-9 overflow-x-auto overflow-y-hidden">
|
||||
{Object.keys(groupedByIssues).map((singleGroup, index) => {
|
||||
const currentState =
|
||||
selectedGroup === "state_detail.name"
|
||||
|
@ -50,7 +50,7 @@ export const BoardHeader: React.FC<Props> = ({
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`flex justify-between p-3 pb-0 ${
|
||||
className={`flex justify-between px-1 ${
|
||||
!isCollapsed ? "flex-col rounded-md border bg-gray-50" : ""
|
||||
}`}
|
||||
>
|
||||
@ -60,7 +60,7 @@ export const BoardHeader: React.FC<Props> = ({
|
||||
!isCollapsed ? "mb-2 flex-col gap-y-2 py-2" : ""
|
||||
}`}
|
||||
>
|
||||
{currentState && getStateGroupIcon(currentState.group)}
|
||||
{currentState && getStateGroupIcon(currentState.group, "20", "20", bgColor)}
|
||||
<h2
|
||||
className={`text-xl font-semibold capitalize`}
|
||||
style={{
|
||||
@ -82,7 +82,7 @@ export const BoardHeader: React.FC<Props> = ({
|
||||
<div className={`flex items-center ${!isCollapsed ? "flex-col pb-2" : ""}`}>
|
||||
<button
|
||||
type="button"
|
||||
className="grid h-7 w-7 place-items-center rounded p-1 text-gray-700 outline-none duration-300 hover:bg-gray-200"
|
||||
className="grid h-7 w-7 place-items-center rounded p-1 text-gray-700 outline-none duration-300 hover:bg-gray-100"
|
||||
onClick={() => {
|
||||
setIsCollapsed((prevData) => !prevData);
|
||||
}}
|
||||
@ -95,7 +95,7 @@ export const BoardHeader: React.FC<Props> = ({
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
className="grid h-7 w-7 place-items-center rounded p-1 text-gray-700 outline-none duration-300 hover:bg-gray-200"
|
||||
className="grid h-7 w-7 place-items-center rounded p-1 text-gray-700 outline-none duration-300 hover:bg-gray-100"
|
||||
onClick={addIssueToState}
|
||||
>
|
||||
<PlusIcon className="h-4 w-4" />
|
||||
|
@ -13,6 +13,8 @@ import { BoardHeader, SingleBoardIssue } from "components/core";
|
||||
import { CustomMenu } from "components/ui";
|
||||
// icons
|
||||
import { PlusIcon } from "@heroicons/react/24/outline";
|
||||
// helpers
|
||||
import { replaceUnderscoreIfSnakeCase } from "helpers/string.helper";
|
||||
// types
|
||||
import { IIssue, IProjectMember, IState, NestedKeyOf, UserAuth } from "types";
|
||||
|
||||
@ -89,7 +91,7 @@ export const SingleBoard: React.FC<Props> = ({
|
||||
<StrictModeDroppable key={groupTitle} droppableId={groupTitle}>
|
||||
{(provided, snapshot) => (
|
||||
<div
|
||||
className={`relative mt-3 h-full px-3 pb-3 overflow-y-auto ${
|
||||
className={`relative h-full p-1 overflow-y-auto ${
|
||||
snapshot.isDraggingOver ? "bg-indigo-50 bg-opacity-50" : ""
|
||||
} ${!isCollapsed ? "hidden" : "block"}`}
|
||||
ref={provided.innerRef}
|
||||
@ -107,7 +109,7 @@ export const SingleBoard: React.FC<Props> = ({
|
||||
snapshot.isDraggingOver ? "block" : "hidden"
|
||||
} top-1/2 left-1/2 -translate-y-1/2 -translate-x-1/2 text-xs whitespace-nowrap bg-white p-2 rounded pointer-events-none z-[99999999]`}
|
||||
>
|
||||
This board is ordered by {orderBy}
|
||||
This board is ordered by {replaceUnderscoreIfSnakeCase(orderBy ?? "")}
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
@ -151,21 +153,23 @@ export const SingleBoard: React.FC<Props> = ({
|
||||
{type === "issue" ? (
|
||||
<button
|
||||
type="button"
|
||||
className="flex items-center rounded p-2 text-xs font-medium outline-none duration-300 hover:bg-gray-100"
|
||||
className="flex items-center gap-2 text-theme font-medium outline-none"
|
||||
onClick={addIssueToState}
|
||||
>
|
||||
<PlusIcon className="mr-1 h-3 w-3" />
|
||||
Create
|
||||
<PlusIcon className="h-4 w-4" />
|
||||
Add Issue
|
||||
</button>
|
||||
) : (
|
||||
<CustomMenu
|
||||
label={
|
||||
<span className="flex items-center gap-1">
|
||||
<PlusIcon className="h-3 w-3" />
|
||||
Add issue
|
||||
</span>
|
||||
customButton={
|
||||
<button
|
||||
type="button"
|
||||
className="flex items-center gap-2 text-theme font-medium outline-none"
|
||||
>
|
||||
<PlusIcon className="h-4 w-4" />
|
||||
Add Issue
|
||||
</button>
|
||||
}
|
||||
className="mt-1"
|
||||
optionsPosition="left"
|
||||
noBorder
|
||||
>
|
||||
|
@ -185,7 +185,7 @@ export const SingleBoardIssue: React.FC<Props> = ({
|
||||
return (
|
||||
<div
|
||||
className={`rounded bg-white shadow mb-3 ${
|
||||
snapshot.isDragging ? "border-theme bg-indigo-50 shadow-lg" : ""
|
||||
snapshot.isDragging ? "border-2 border-theme shadow-lg" : ""
|
||||
}`}
|
||||
ref={provided.innerRef}
|
||||
{...provided.draggableProps}
|
||||
|
@ -371,13 +371,13 @@ export const IssuesView: React.FC<Props> = ({
|
||||
<div
|
||||
className={`${
|
||||
trashBox ? "opacity-100 pointer-events-auto" : "opacity-0 pointer-events-none"
|
||||
} fixed z-20 top-12 left-1/2 -translate-x-1/2 flex items-center gap-2 bg-red-100 border-2 border-red-500 p-3 text-xs rounded ${
|
||||
} fixed z-20 top-9 right-9 flex justify-center items-center gap-2 bg-red-100 border-2 border-red-500 p-3 w-96 h-28 text-xs italic text-red-500 font-medium rounded ${
|
||||
snapshot.isDraggingOver ? "bg-red-500 text-white" : ""
|
||||
} duration-200`}
|
||||
ref={provided.innerRef}
|
||||
{...provided.droppableProps}
|
||||
>
|
||||
<TrashIcon className="h-3 w-3" />
|
||||
<TrashIcon className="h-4 w-4" />
|
||||
Drop issue here to delete
|
||||
</div>
|
||||
)}
|
||||
|
@ -6,7 +6,7 @@ export const BacklogStateIcon: React.FC<Props> = ({
|
||||
width = "20",
|
||||
height = "20",
|
||||
className,
|
||||
color = "black",
|
||||
color = "#858e96",
|
||||
}) => (
|
||||
<svg
|
||||
width={width}
|
||||
|
78
apps/app/components/icons/cancelled-state-icon.tsx
Normal file
78
apps/app/components/icons/cancelled-state-icon.tsx
Normal file
@ -0,0 +1,78 @@
|
||||
import React from "react";
|
||||
|
||||
import type { Props } from "./types";
|
||||
|
||||
export const CancelledStateIcon: React.FC<Props> = ({
|
||||
width = "20",
|
||||
height = "20",
|
||||
className,
|
||||
color = "#f2655a",
|
||||
}) => (
|
||||
<svg
|
||||
width={width}
|
||||
height={height}
|
||||
className={className}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 84.36 84.36"
|
||||
>
|
||||
<g id="Layer_2" data-name="Layer 2">
|
||||
<g id="Layer_1-2" data-name="Layer 1">
|
||||
<path
|
||||
className="cls-1"
|
||||
fill="none"
|
||||
strokeWidth={3}
|
||||
stroke={color}
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
d="M20.45,7.69a39.74,39.74,0,0,1,43.43.54"
|
||||
/>
|
||||
<path
|
||||
className="cls-1"
|
||||
fill="none"
|
||||
strokeWidth={3}
|
||||
stroke={color}
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
d="M76.67,20.45a39.76,39.76,0,0,1-.53,43.43"
|
||||
/>
|
||||
<path
|
||||
className="cls-1"
|
||||
fill="none"
|
||||
strokeWidth={3}
|
||||
stroke={color}
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
d="M63.92,76.67a39.78,39.78,0,0,1-43.44-.53"
|
||||
/>
|
||||
<path
|
||||
className="cls-1"
|
||||
fill="none"
|
||||
strokeWidth={3}
|
||||
stroke={color}
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
d="M7.69,63.92a39.75,39.75,0,0,1,.54-43.44"
|
||||
/>
|
||||
<circle className="cls-2" fill={color} cx="42.18" cy="42.18" r="31.04" />
|
||||
<path
|
||||
className="cls-3"
|
||||
fill="none"
|
||||
strokeWidth={3}
|
||||
stroke="#ffffff"
|
||||
strokeLinecap="square"
|
||||
strokeMiterlimit={10}
|
||||
d="M32.64,32.44q9.54,9.75,19.09,19.48"
|
||||
/>
|
||||
<path
|
||||
className="cls-3"
|
||||
fill="none"
|
||||
strokeWidth={3}
|
||||
stroke="#ffffff"
|
||||
strokeLinecap="square"
|
||||
strokeMiterlimit={10}
|
||||
d="M32.64,51.92,51.73,32.44"
|
||||
/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
);
|
@ -12,22 +12,58 @@ export const CompletedStateIcon: React.FC<Props> = ({
|
||||
width={width}
|
||||
height={height}
|
||||
className={className}
|
||||
viewBox="0 0 20 20"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 84.36 84.36"
|
||||
>
|
||||
<circle
|
||||
cx="10"
|
||||
cy="10"
|
||||
r="9"
|
||||
<g id="Layer_2" data-name="Layer 2">
|
||||
<g id="Layer_1-2" data-name="Layer 1">
|
||||
<path
|
||||
className="cls-1"
|
||||
fill="none"
|
||||
strokeWidth={3}
|
||||
stroke={color}
|
||||
strokeLinecap="round"
|
||||
strokeDasharray="0 20 0 10"
|
||||
strokeLinejoin="round"
|
||||
d="M20.45,7.69a39.74,39.74,0,0,1,43.43.54"
|
||||
/>
|
||||
<circle cx="10" cy="10" r="7" fill={color} />
|
||||
<path
|
||||
d="M13 8.33328L9 12.3333L7.16666 10.4999L7.63666 10.0299L9 11.3899L12.53 7.86328L13 8.33328Z"
|
||||
fill="white"
|
||||
className="cls-1"
|
||||
fill="none"
|
||||
strokeWidth={3}
|
||||
stroke={color}
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
d="M76.67,20.45a39.76,39.76,0,0,1-.53,43.43"
|
||||
/>
|
||||
<path
|
||||
className="cls-1"
|
||||
fill="none"
|
||||
strokeWidth={3}
|
||||
stroke={color}
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
d="M63.92,76.67a39.78,39.78,0,0,1-43.44-.53"
|
||||
/>
|
||||
<path
|
||||
className="cls-1"
|
||||
fill="none"
|
||||
strokeWidth={3}
|
||||
stroke={color}
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
d="M7.69,63.92a39.75,39.75,0,0,1,.54-43.44"
|
||||
/>
|
||||
<circle className="cls-2" fill={color} cx="42.18" cy="42.18" r="31.04" />
|
||||
<path
|
||||
className="cls-3"
|
||||
fill="none"
|
||||
strokeWidth={3}
|
||||
stroke="#ffffff"
|
||||
strokeLinecap="square"
|
||||
strokeMiterlimit={10}
|
||||
d="M30.45,43.75l6.61,6.61L53.92,34"
|
||||
/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
);
|
||||
|
@ -5,6 +5,7 @@ export * from "./blocker-icon";
|
||||
export * from "./bolt-icon";
|
||||
export * from "./calendar-month-icon";
|
||||
export * from "./cancel-icon";
|
||||
export * from "./cancelled-state-icon";
|
||||
export * from "./clipboard-icon";
|
||||
export * from "./comment-icon";
|
||||
export * from "./completed-cycle-icon";
|
||||
@ -30,6 +31,7 @@ export * from "./started-state-icon";
|
||||
export * from "./state-group-icon";
|
||||
export * from "./tag-icon";
|
||||
export * from "./tune-icon";
|
||||
export * from "./unstarted-state-icon";
|
||||
export * from "./upcoming-cycle-icon";
|
||||
export * from "./user-group-icon";
|
||||
export * from "./user-icon-circle";
|
||||
|
@ -6,31 +6,72 @@ export const StartedStateIcon: React.FC<Props> = ({
|
||||
width = "20",
|
||||
height = "20",
|
||||
className,
|
||||
color = "#fcbe1d",
|
||||
color = "#fbb040",
|
||||
}) => (
|
||||
<svg
|
||||
width={width}
|
||||
height={height}
|
||||
className={className}
|
||||
viewBox="0 0 20 20"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 83.36 83.36"
|
||||
>
|
||||
<circle
|
||||
cx="10"
|
||||
cy="10"
|
||||
r="9"
|
||||
<g id="Layer_2" data-name="Layer 2">
|
||||
<g id="Layer_1-2" data-name="Layer 1">
|
||||
<path
|
||||
className="cls-1"
|
||||
fill="none"
|
||||
stroke={color}
|
||||
strokeLinecap="round"
|
||||
strokeDasharray="0 20 0 10"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth={3}
|
||||
d="M20,7.19a39.74,39.74,0,0,1,43.43.54"
|
||||
/>
|
||||
<path
|
||||
d="M14.2878 4.46695C13.0513 3.5087 11.5294 2.99227 9.96503 3.00009C8.40068 3.0079 6.88403 3.53951 5.65713 4.51006L10 10L14.2878 4.46695Z"
|
||||
fill={color}
|
||||
className="cls-1"
|
||||
fill="none"
|
||||
stroke={color}
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth={3}
|
||||
d="M76.17,20a39.76,39.76,0,0,1-.53,43.43"
|
||||
/>
|
||||
<path
|
||||
d="M5.70047 15.5331C6.93701 16.4913 8.45889 17.0077 10.0232 16.9999C11.5876 16.9921 13.1043 16.4605 14.3312 15.4899L9.98828 10L5.70047 15.5331Z"
|
||||
fill={color}
|
||||
className="cls-1"
|
||||
fill="none"
|
||||
stroke={color}
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth={3}
|
||||
d="M63.42,76.17A39.78,39.78,0,0,1,20,75.64"
|
||||
/>
|
||||
<path
|
||||
className="cls-1"
|
||||
fill="none"
|
||||
stroke={color}
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth={3}
|
||||
d="M7.19,63.42A39.75,39.75,0,0,1,7.73,20"
|
||||
/>
|
||||
<path
|
||||
className="cls-2"
|
||||
fill={color}
|
||||
stroke={color}
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth={3}
|
||||
d="M42.32,41.21q9.57-14.45,19.13-28.9a35.8,35.8,0,0,0-39.09,0Z"
|
||||
/>
|
||||
<path
|
||||
className="cls-2"
|
||||
fill={color}
|
||||
stroke={color}
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth={3}
|
||||
d="M42.32,41.7,61.45,70.6a35.75,35.75,0,0,1-39.09,0Z"
|
||||
/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
);
|
||||
|
@ -1,6 +1,10 @@
|
||||
import { BacklogStateIcon } from "./backlog-state-icon";
|
||||
import { CompletedStateIcon } from "./completed-state-icon";
|
||||
import { StartedStateIcon } from "./started-state-icon";
|
||||
import {
|
||||
BacklogStateIcon,
|
||||
CancelledStateIcon,
|
||||
CompletedStateIcon,
|
||||
StartedStateIcon,
|
||||
UnstartedStateIcon,
|
||||
} from "components/icons";
|
||||
|
||||
export const getStateGroupIcon = (
|
||||
stateGroup: "backlog" | "unstarted" | "started" | "completed" | "cancelled",
|
||||
@ -12,13 +16,13 @@ export const getStateGroupIcon = (
|
||||
case "backlog":
|
||||
return <BacklogStateIcon width={width} height={height} color={color} />;
|
||||
case "unstarted":
|
||||
return <StartedStateIcon width={width} height={height} color={color} />;
|
||||
return <UnstartedStateIcon width={width} height={height} color={color} />;
|
||||
case "started":
|
||||
return <StartedStateIcon width={width} height={height} color={color} />;
|
||||
case "completed":
|
||||
return <CompletedStateIcon width={width} height={height} color={color} />;
|
||||
case "cancelled":
|
||||
return <StartedStateIcon width={width} height={height} color={color} />;
|
||||
return <CancelledStateIcon width={width} height={height} color={color} />;
|
||||
default:
|
||||
return <></>;
|
||||
}
|
||||
|
59
apps/app/components/icons/unstarted-state-icon.tsx
Normal file
59
apps/app/components/icons/unstarted-state-icon.tsx
Normal file
@ -0,0 +1,59 @@
|
||||
import React from "react";
|
||||
|
||||
import type { Props } from "./types";
|
||||
|
||||
export const UnstartedStateIcon: React.FC<Props> = ({
|
||||
width = "20",
|
||||
height = "20",
|
||||
className,
|
||||
color = "#858e96",
|
||||
}) => (
|
||||
<svg
|
||||
width={width}
|
||||
height={height}
|
||||
className={className}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 84.36 84.36"
|
||||
>
|
||||
<g id="Layer_2" data-name="Layer 2">
|
||||
<g id="Layer_1-2" data-name="Layer 1">
|
||||
<path
|
||||
className="cls-1"
|
||||
fill="none"
|
||||
stroke={color}
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth={3}
|
||||
d="M20.45,7.69a39.74,39.74,0,0,1,43.43.54"
|
||||
/>
|
||||
<path
|
||||
className="cls-1"
|
||||
fill="none"
|
||||
stroke={color}
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth={3}
|
||||
d="M76.67,20.45a39.76,39.76,0,0,1-.53,43.43"
|
||||
/>
|
||||
<path
|
||||
className="cls-1"
|
||||
fill="none"
|
||||
stroke={color}
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth={3}
|
||||
d="M63.92,76.67a39.78,39.78,0,0,1-43.44-.53"
|
||||
/>
|
||||
<path
|
||||
className="cls-1"
|
||||
fill="none"
|
||||
stroke={color}
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth={3}
|
||||
d="M7.69,63.92a39.75,39.75,0,0,1,.54-43.44"
|
||||
/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
);
|
@ -15,6 +15,7 @@ type Props = {
|
||||
textAlignment?: "left" | "center" | "right";
|
||||
noBorder?: boolean;
|
||||
optionsPosition?: "left" | "right";
|
||||
customButton?: JSX.Element;
|
||||
};
|
||||
|
||||
type MenuItemProps = {
|
||||
@ -34,8 +35,12 @@ const CustomMenu = ({
|
||||
textAlignment,
|
||||
noBorder = false,
|
||||
optionsPosition = "right",
|
||||
customButton,
|
||||
}: Props) => (
|
||||
<Menu as="div" className={`relative w-min whitespace-nowrap text-left ${className}`}>
|
||||
{customButton ? (
|
||||
<Menu.Button as="div">{customButton}</Menu.Button>
|
||||
) : (
|
||||
<div>
|
||||
{ellipsis ? (
|
||||
<Menu.Button className="relative grid place-items-center rounded p-1 hover:bg-gray-100 focus:outline-none">
|
||||
@ -70,6 +75,7 @@ const CustomMenu = ({
|
||||
</Menu.Button>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<Transition
|
||||
as={React.Fragment}
|
||||
|
@ -44,7 +44,7 @@ const CustomSelect = ({
|
||||
>
|
||||
<div>
|
||||
{customButton ? (
|
||||
customButton
|
||||
<Listbox.Button as="div">{customButton}</Listbox.Button>
|
||||
) : (
|
||||
<Listbox.Button
|
||||
className={`flex w-full ${
|
||||
|
Loading…
Reference in New Issue
Block a user