mirror of
https://github.com/makeplane/plane
synced 2024-06-14 14:31:34 +00:00
[WEB-905] chore: kanban card icon color improvement (#4156)
* chore: kanban card icon color improvement * chore: kanban card clickable area improvement
This commit is contained in:
parent
1dac70ecbe
commit
549790ee8a
@ -152,6 +152,7 @@ export const DateDropdown: React.FC<Props> = (props) => {
|
||||
className={cn("h-2.5 w-2.5 flex-shrink-0", clearIconClassName)}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
onChange(null);
|
||||
}}
|
||||
/>
|
||||
|
@ -3,7 +3,7 @@ import { Draggable, DraggableProvided, DraggableStateSnapshot } from "@hello-pan
|
||||
import { observer } from "mobx-react-lite";
|
||||
import { TIssue, IIssueDisplayProperties, IIssueMap } from "@plane/types";
|
||||
// hooks
|
||||
import { Tooltip, ControlLink } from "@plane/ui";
|
||||
import { ControlLink, Tooltip } from "@plane/ui";
|
||||
import RenderIfVisible from "@/components/core/render-if-visible-HOC";
|
||||
import { cn } from "@/helpers/common.helper";
|
||||
import { useApplication, useIssueDetail, useProject } from "@/hooks/store";
|
||||
@ -44,23 +44,16 @@ const KanbanIssueDetailsBlock: React.FC<IssueDetailsBlockProps> = observer((prop
|
||||
// hooks
|
||||
const { isMobile } = usePlatformOS();
|
||||
const { getProjectIdentifierById } = useProject();
|
||||
const {
|
||||
router: { workspaceSlug },
|
||||
} = useApplication();
|
||||
const { peekIssue, setPeekIssue } = useIssueDetail();
|
||||
|
||||
const handleIssuePeekOverview = (issue: TIssue) =>
|
||||
workspaceSlug &&
|
||||
issue &&
|
||||
issue.project_id &&
|
||||
issue.id &&
|
||||
peekIssue?.issueId !== issue.id &&
|
||||
setPeekIssue({ workspaceSlug, projectId: issue.project_id, issueId: issue.id });
|
||||
const handleEventPropagation = (e: React.MouseEvent) => {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<WithDisplayPropertiesHOC displayProperties={displayProperties || {}} displayPropertyKey="key">
|
||||
<div className="relative">
|
||||
<div className="relative" onClick={handleEventPropagation}>
|
||||
<div className="line-clamp-1 text-xs text-custom-text-300">
|
||||
{getProjectIdentifierById(issue.project_id)}-{issue.sequence_id}
|
||||
</div>
|
||||
@ -73,24 +66,13 @@ const KanbanIssueDetailsBlock: React.FC<IssueDetailsBlockProps> = observer((prop
|
||||
<span className="pb-1.5">{issue.name}</span>
|
||||
</Tooltip>
|
||||
) : (
|
||||
<ControlLink
|
||||
id={`issue-${issue.id}`}
|
||||
href={`/${workspaceSlug}/projects/${issue.project_id}/${issue.archived_at ? "archives/" : ""}issues/${
|
||||
issue.id
|
||||
}`}
|
||||
target="_blank"
|
||||
onClick={() => handleIssuePeekOverview(issue)}
|
||||
className="w-full line-clamp-1 cursor-pointer text-sm text-custom-text-100 pb-1.5"
|
||||
disabled={!!issue?.tempId}
|
||||
>
|
||||
<Tooltip tooltipContent={issue.name} isMobile={isMobile}>
|
||||
<span>{issue.name}</span>
|
||||
</Tooltip>
|
||||
</ControlLink>
|
||||
<Tooltip tooltipContent={issue.name} isMobile={isMobile}>
|
||||
<span className="w-full line-clamp-1 cursor-pointer text-sm text-custom-text-100 pb-1.5">{issue.name}</span>
|
||||
</Tooltip>
|
||||
)}
|
||||
|
||||
<IssueProperties
|
||||
className="flex flex-wrap items-center gap-2 whitespace-nowrap"
|
||||
className="flex flex-wrap items-center gap-2 whitespace-nowrap text-custom-text-300"
|
||||
issue={issue}
|
||||
displayProperties={displayProperties}
|
||||
activeLayout="Kanban"
|
||||
@ -118,6 +100,19 @@ export const KanbanIssueBlock: React.FC<IssueBlockProps> = memo((props) => {
|
||||
issueIds,
|
||||
} = props;
|
||||
|
||||
const {
|
||||
router: { workspaceSlug },
|
||||
} = useApplication();
|
||||
const { peekIssue, setPeekIssue } = useIssueDetail();
|
||||
|
||||
const handleIssuePeekOverview = (issue: TIssue) =>
|
||||
workspaceSlug &&
|
||||
issue &&
|
||||
issue.project_id &&
|
||||
issue.id &&
|
||||
peekIssue?.issueId !== issue.id &&
|
||||
setPeekIssue({ workspaceSlug, projectId: issue.project_id, issueId: issue.id });
|
||||
|
||||
const issue = issuesMap[issueId];
|
||||
|
||||
if (!issue) return null;
|
||||
@ -138,32 +133,42 @@ export const KanbanIssueBlock: React.FC<IssueBlockProps> = memo((props) => {
|
||||
{...provided.dragHandleProps}
|
||||
ref={provided.innerRef}
|
||||
>
|
||||
<div
|
||||
className={cn(
|
||||
"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-grab": !isDragDisabled },
|
||||
{ "border-custom-primary-100": snapshot.isDragging },
|
||||
{ "border border-custom-primary-70 hover:border-custom-primary-70": peekIssueId === issue.id }
|
||||
)}
|
||||
<ControlLink
|
||||
id={`issue-${issue.id}`}
|
||||
href={`/${workspaceSlug}/projects/${issue.project_id}/${issue.archived_at ? "archives/" : ""}issues/${
|
||||
issue.id
|
||||
}`}
|
||||
target="_blank"
|
||||
onClick={() => handleIssuePeekOverview(issue)}
|
||||
disabled={!!issue?.tempId}
|
||||
>
|
||||
<RenderIfVisible
|
||||
classNames="space-y-2 px-3 py-2"
|
||||
root={scrollableContainerRef}
|
||||
defaultHeight="100px"
|
||||
horizontalOffset={50}
|
||||
alwaysRender={snapshot.isDragging}
|
||||
pauseHeightUpdateWhileRendering={isDragStarted}
|
||||
changingReference={issueIds}
|
||||
<div
|
||||
className={cn(
|
||||
"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": !isDragDisabled },
|
||||
{ "border-custom-primary-100": snapshot.isDragging },
|
||||
{ "border border-custom-primary-70 hover:border-custom-primary-70": peekIssueId === issue.id }
|
||||
)}
|
||||
>
|
||||
<KanbanIssueDetailsBlock
|
||||
issue={issue}
|
||||
displayProperties={displayProperties}
|
||||
updateIssue={updateIssue}
|
||||
quickActions={quickActions}
|
||||
isReadOnly={!canEditIssueProperties}
|
||||
/>
|
||||
</RenderIfVisible>
|
||||
</div>
|
||||
<RenderIfVisible
|
||||
classNames="space-y-2 px-3 py-2"
|
||||
root={scrollableContainerRef}
|
||||
defaultHeight="100px"
|
||||
horizontalOffset={50}
|
||||
alwaysRender={snapshot.isDragging}
|
||||
pauseHeightUpdateWhileRendering={isDragStarted}
|
||||
changingReference={issueIds}
|
||||
>
|
||||
<KanbanIssueDetailsBlock
|
||||
issue={issue}
|
||||
displayProperties={displayProperties}
|
||||
updateIssue={updateIssue}
|
||||
quickActions={quickActions}
|
||||
isReadOnly={!canEditIssueProperties}
|
||||
/>
|
||||
</RenderIfVisible>
|
||||
</div>
|
||||
</ControlLink>
|
||||
</div>
|
||||
)}
|
||||
</Draggable>
|
||||
|
@ -254,12 +254,17 @@ export const IssueProperties: React.FC<IIssueProperties> = observer((props) => {
|
||||
const maxDate = getDate(issue.target_date);
|
||||
maxDate?.setDate(maxDate.getDate());
|
||||
|
||||
const handleEventPropagation = (e: React.MouseEvent) => {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={className}>
|
||||
{/* basic properties */}
|
||||
{/* state */}
|
||||
<WithDisplayPropertiesHOC displayProperties={displayProperties} displayPropertyKey="state">
|
||||
<div className="h-5">
|
||||
<div className="h-5" onClick={handleEventPropagation}>
|
||||
<StateDropdown
|
||||
buttonContainerClassName="truncate max-w-40"
|
||||
value={issue.state_id}
|
||||
@ -274,7 +279,7 @@ export const IssueProperties: React.FC<IIssueProperties> = observer((props) => {
|
||||
|
||||
{/* priority */}
|
||||
<WithDisplayPropertiesHOC displayProperties={displayProperties} displayPropertyKey="priority">
|
||||
<div className="h-5">
|
||||
<div className="h-5" onClick={handleEventPropagation}>
|
||||
<PriorityDropdown
|
||||
value={issue?.priority || null}
|
||||
onChange={handlePriority}
|
||||
@ -288,19 +293,21 @@ export const IssueProperties: React.FC<IIssueProperties> = observer((props) => {
|
||||
|
||||
{/* label */}
|
||||
<WithDisplayPropertiesHOC displayProperties={displayProperties} displayPropertyKey="labels">
|
||||
<IssuePropertyLabels
|
||||
projectId={issue?.project_id || null}
|
||||
value={issue?.label_ids || null}
|
||||
defaultOptions={defaultLabelOptions}
|
||||
onChange={handleLabel}
|
||||
disabled={isReadOnly}
|
||||
hideDropdownArrow
|
||||
/>
|
||||
<div className="h-5" onClick={handleEventPropagation}>
|
||||
<IssuePropertyLabels
|
||||
projectId={issue?.project_id || null}
|
||||
value={issue?.label_ids || null}
|
||||
defaultOptions={defaultLabelOptions}
|
||||
onChange={handleLabel}
|
||||
disabled={isReadOnly}
|
||||
hideDropdownArrow
|
||||
/>
|
||||
</div>
|
||||
</WithDisplayPropertiesHOC>
|
||||
|
||||
{/* start date */}
|
||||
<WithDisplayPropertiesHOC displayProperties={displayProperties} displayPropertyKey="start_date">
|
||||
<div className="h-5">
|
||||
<div className="h-5" onClick={handleEventPropagation}>
|
||||
<DateDropdown
|
||||
value={issue.start_date ?? null}
|
||||
onChange={handleStartDate}
|
||||
@ -316,7 +323,7 @@ export const IssueProperties: React.FC<IIssueProperties> = observer((props) => {
|
||||
|
||||
{/* target/due date */}
|
||||
<WithDisplayPropertiesHOC displayProperties={displayProperties} displayPropertyKey="due_date">
|
||||
<div className="h-5">
|
||||
<div className="h-5" onClick={handleEventPropagation}>
|
||||
<DateDropdown
|
||||
value={issue?.target_date ?? null}
|
||||
onChange={handleTargetDate}
|
||||
@ -334,7 +341,7 @@ export const IssueProperties: React.FC<IIssueProperties> = observer((props) => {
|
||||
|
||||
{/* assignee */}
|
||||
<WithDisplayPropertiesHOC displayProperties={displayProperties} displayPropertyKey="assignee">
|
||||
<div className="h-5">
|
||||
<div className="h-5" onClick={handleEventPropagation}>
|
||||
<MemberDropdown
|
||||
projectId={issue?.project_id}
|
||||
value={issue?.assignee_ids}
|
||||
@ -353,7 +360,7 @@ export const IssueProperties: React.FC<IIssueProperties> = observer((props) => {
|
||||
{/* modules */}
|
||||
{projectDetails?.module_view && (
|
||||
<WithDisplayPropertiesHOC displayProperties={displayProperties} displayPropertyKey="modules">
|
||||
<div className="h-5">
|
||||
<div className="h-5" onClick={handleEventPropagation}>
|
||||
<ModuleDropdown
|
||||
buttonContainerClassName="truncate max-w-40"
|
||||
projectId={issue?.project_id}
|
||||
@ -372,7 +379,7 @@ export const IssueProperties: React.FC<IIssueProperties> = observer((props) => {
|
||||
{/* cycles */}
|
||||
{projectDetails?.cycle_view && (
|
||||
<WithDisplayPropertiesHOC displayProperties={displayProperties} displayPropertyKey="cycle">
|
||||
<div className="h-5">
|
||||
<div className="h-5" onClick={handleEventPropagation}>
|
||||
<CycleDropdown
|
||||
buttonContainerClassName="truncate max-w-40"
|
||||
projectId={issue?.project_id}
|
||||
@ -389,7 +396,7 @@ export const IssueProperties: React.FC<IIssueProperties> = observer((props) => {
|
||||
{/* estimates */}
|
||||
{areEstimatesEnabledForCurrentProject && (
|
||||
<WithDisplayPropertiesHOC displayProperties={displayProperties} displayPropertyKey="estimate">
|
||||
<div className="h-5">
|
||||
<div className="h-5" onClick={handleEventPropagation}>
|
||||
<EstimateDropdown
|
||||
value={issue.estimate_point}
|
||||
onChange={handleEstimate}
|
||||
@ -411,7 +418,11 @@ export const IssueProperties: React.FC<IIssueProperties> = observer((props) => {
|
||||
>
|
||||
<Tooltip tooltipHeading="Sub-issues" tooltipContent={`${issue.sub_issues_count}`} isMobile={isMobile}>
|
||||
<div
|
||||
onClick={issue.sub_issues_count ? redirectToIssueDetail : () => {}}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
if (issue.sub_issues_count) redirectToIssueDetail();
|
||||
}}
|
||||
className={cn(
|
||||
"flex h-5 flex-shrink-0 items-center justify-center gap-2 overflow-hidden rounded border-[0.5px] border-custom-border-300 px-2.5 py-1",
|
||||
{
|
||||
@ -432,7 +443,10 @@ export const IssueProperties: React.FC<IIssueProperties> = observer((props) => {
|
||||
shouldRenderProperty={(properties) => !!properties.attachment_count && !!issue.attachment_count}
|
||||
>
|
||||
<Tooltip tooltipHeading="Attachments" tooltipContent={`${issue.attachment_count}`} isMobile={isMobile}>
|
||||
<div className="flex h-5 flex-shrink-0 items-center justify-center gap-2 overflow-hidden rounded border-[0.5px] border-custom-border-300 px-2.5 py-1">
|
||||
<div
|
||||
className="flex h-5 flex-shrink-0 items-center justify-center gap-2 overflow-hidden rounded border-[0.5px] border-custom-border-300 px-2.5 py-1"
|
||||
onClick={handleEventPropagation}
|
||||
>
|
||||
<Paperclip className="h-3 w-3 flex-shrink-0" strokeWidth={2} />
|
||||
<div className="text-xs">{issue.attachment_count}</div>
|
||||
</div>
|
||||
@ -446,7 +460,10 @@ export const IssueProperties: React.FC<IIssueProperties> = observer((props) => {
|
||||
shouldRenderProperty={(properties) => !!properties.link && !!issue.link_count}
|
||||
>
|
||||
<Tooltip tooltipHeading="Links" tooltipContent={`${issue.link_count}`} isMobile={isMobile}>
|
||||
<div className="flex h-5 flex-shrink-0 items-center justify-center gap-2 overflow-hidden rounded border-[0.5px] border-custom-border-300 px-2.5 py-1">
|
||||
<div
|
||||
className="flex h-5 flex-shrink-0 items-center justify-center gap-2 overflow-hidden rounded border-[0.5px] border-custom-border-300 px-2.5 py-1"
|
||||
onClick={handleEventPropagation}
|
||||
>
|
||||
<Link className="h-3 w-3 flex-shrink-0" strokeWidth={2} />
|
||||
<div className="text-xs">{issue.link_count}</div>
|
||||
</div>
|
||||
|
@ -143,7 +143,7 @@ export const IssuePropertyLabels: React.FC<IIssuePropertyLabels> = observer((pro
|
||||
query === "" ? options : options?.filter((option) => option.query.toLowerCase().includes(query.toLowerCase()));
|
||||
|
||||
const label = (
|
||||
<div className="flex h-5 w-full flex-wrap items-center gap-2 overflow-hidden text-custom-text-200">
|
||||
<div className="flex h-5 w-full flex-wrap items-center gap-2 overflow-hidden">
|
||||
{value.length > 0 ? (
|
||||
value.length <= maxRender ? (
|
||||
<>
|
||||
@ -232,8 +232,8 @@ export const IssuePropertyLabels: React.FC<IIssuePropertyLabels> = observer((pro
|
||||
disabled
|
||||
? "cursor-not-allowed text-custom-text-200"
|
||||
: value.length <= maxRender
|
||||
? "cursor-pointer"
|
||||
: "cursor-pointer hover:bg-custom-background-80"
|
||||
? "cursor-pointer"
|
||||
: "cursor-pointer hover:bg-custom-background-80"
|
||||
} ${buttonClassName}`}
|
||||
onClick={handleOnClick}
|
||||
>
|
||||
|
Loading…
Reference in New Issue
Block a user