[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:
Anmol Singh Bhatia 2024-04-10 14:03:22 +05:30 committed by GitHub
parent 1dac70ecbe
commit 549790ee8a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 97 additions and 74 deletions

View File

@ -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);
}}
/>

View File

@ -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>

View File

@ -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>

View File

@ -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}
>