[WEB-1254] chore: list layout indentation enhancement and cycle list page ui improvement (#4435)

* chore: list layout indentation improvement

* chore: cycle list layout spacing and date ui updated

* chore: platform ui improvement
This commit is contained in:
Anmol Singh Bhatia 2024-05-11 14:47:56 +05:30 committed by GitHub
parent 2ef3c06da0
commit 3355be9c9c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
20 changed files with 58 additions and 68 deletions

View File

@ -2,7 +2,7 @@ import { FC, MouseEvent, useRef } from "react";
import { observer } from "mobx-react"; import { observer } from "mobx-react";
import Link from "next/link"; import Link from "next/link";
import { useRouter } from "next/router"; import { useRouter } from "next/router";
import { Info } from "lucide-react"; import { CalendarCheck2, CalendarClock, Info, MoveRight } from "lucide-react";
// types // types
import type { TCycleGroups } from "@plane/types"; import type { TCycleGroups } from "@plane/types";
// ui // ui
@ -226,12 +226,14 @@ export const CyclesBoardCard: FC<ICyclesBoardCard> = observer((props) => {
</Tooltip> </Tooltip>
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
{isDateValid ? ( {isDateValid && (
<span className="text-xs text-custom-text-300"> <div className="h-6 flex items-center gap-1.5 text-custom-text-300 border-[0.5px] border-custom-border-300 rounded text-xs px-2 cursor-default">
{renderFormattedDate(startDate) ?? "_ _"} - {renderFormattedDate(endDate) ?? "_ _"} <CalendarClock className="h-3 w-3 flex-shrink-0" />
</span> <span className="flex-grow truncate">{renderFormattedDate(startDate)}</span>
) : ( <MoveRight className="h-3 w-3 flex-shrink-0" />
<span className="text-xs text-custom-text-400">No due date</span> <CalendarCheck2 className="h-3 w-3 flex-shrink-0" />
<span className="flex-grow truncate">{renderFormattedDate(endDate)}</span>
</div>
)} )}
</div> </div>
</div> </div>

View File

@ -1,6 +1,6 @@
import React, { FC, MouseEvent } from "react"; import React, { FC, MouseEvent } from "react";
import { observer } from "mobx-react"; import { observer } from "mobx-react";
import { User2 } from "lucide-react"; import { CalendarCheck2, CalendarClock, MoveRight, User2 } from "lucide-react";
// types // types
import { ICycle, TCycleGroups } from "@plane/types"; import { ICycle, TCycleGroups } from "@plane/types";
// ui // ui
@ -106,9 +106,15 @@ export const CycleListItemAction: FC<Props> = observer((props) => {
return ( return (
<> <>
<div className="text-xs text-custom-text-300 flex-shrink-0"> {renderDate && (
{renderDate && `${renderFormattedDate(startDate) ?? `_ _`} - ${renderFormattedDate(endDate) ?? `_ _`}`} <div className="h-6 flex items-center gap-1.5 text-custom-text-300 border-[0.5px] border-custom-border-300 rounded text-xs px-2 cursor-default">
<CalendarClock className="h-3 w-3 flex-shrink-0" />
<span className="flex-grow truncate">{renderFormattedDate(startDate)}</span>
<MoveRight className="h-3 w-3 flex-shrink-0" />
<CalendarCheck2 className="h-3 w-3 flex-shrink-0" />
<span className="flex-grow truncate">{renderFormattedDate(endDate)}</span>
</div> </div>
)}
{currentCycle && ( {currentCycle && (
<div <div

View File

@ -94,7 +94,7 @@ export const CyclesListItem: FC<TCyclesListItem> = observer((props) => {
) : progress === 100 ? ( ) : progress === 100 ? (
<Check className="h-3 w-3 stroke-[2] text-custom-primary-100" /> <Check className="h-3 w-3 stroke-[2] text-custom-primary-100" />
) : ( ) : (
<span className="text-xs text-custom-text-300">{`${progress}%`}</span> <span className="text-[9px] text-custom-text-300">{`${progress}%`}</span>
)} )}
</CircularProgressIndicator> </CircularProgressIndicator>
} }

View File

@ -281,7 +281,6 @@ export const CycleIssuesHeader: React.FC = observer(() => {
toggleCreateIssueModal(true, EIssuesStoreType.CYCLE); toggleCreateIssueModal(true, EIssuesStoreType.CYCLE);
}} }}
size="sm" size="sm"
prependIcon={<Plus />}
> >
Add Issue Add Issue
</Button> </Button>

View File

@ -61,7 +61,6 @@ export const CyclesHeader: FC = observer(() => {
<Button <Button
variant="primary" variant="primary"
size="sm" size="sm"
prependIcon={<Plus />}
onClick={() => { onClick={() => {
setTrackElement("Cycles page"); setTrackElement("Cycles page");
toggleCreateCycleModal(true); toggleCreateCycleModal(true);

View File

@ -134,8 +134,8 @@ export const GlobalIssuesHeader: React.FC = observer(() => {
</FiltersDropdown> </FiltersDropdown>
</> </>
{isAuthorizedUser && ( {isAuthorizedUser && (
<Button variant="primary" size="sm" prependIcon={<PlusIcon />} onClick={() => setCreateViewModal(true)}> <Button variant="primary" size="sm" onClick={() => setCreateViewModal(true)}>
New View Add View
</Button> </Button>
)} )}
</div> </div>

View File

@ -288,7 +288,6 @@ export const ModuleIssuesHeader: React.FC = observer(() => {
toggleCreateIssueModal(true, EIssuesStoreType.MODULE); toggleCreateIssueModal(true, EIssuesStoreType.MODULE);
}} }}
size="sm" size="sm"
prependIcon={<Plus />}
> >
Add Issue Add Issue
</Button> </Button>

View File

@ -63,7 +63,6 @@ export const ModulesListHeader: React.FC = observer(() => {
<Button <Button
variant="primary" variant="primary"
size="sm" size="sm"
prependIcon={<Plus />}
onClick={() => { onClick={() => {
setTrackElement("Modules page"); setTrackElement("Modules page");
toggleCreateModuleModal(true); toggleCreateModuleModal(true);

View File

@ -79,8 +79,8 @@ export const PageDetailsHeader: FC<IPagesHeaderProps> = observer((props) => {
</div> </div>
{showButton && ( {showButton && (
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<Button variant="primary" prependIcon={<Plus />} size="sm" onClick={() => toggleCreatePageModal(true)}> <Button variant="primary" size="sm" onClick={() => toggleCreatePageModal(true)}>
Create Page Add Page
</Button> </Button>
</div> </div>
)} )}

View File

@ -59,14 +59,13 @@ export const PagesHeader = observer(() => {
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<Button <Button
variant="primary" variant="primary"
prependIcon={<Plus />}
size="sm" size="sm"
onClick={() => { onClick={() => {
setTrackElement("Project pages page"); setTrackElement("Project pages page");
toggleCreatePageModal(true); toggleCreatePageModal(true);
}} }}
> >
Create Page Add Page
</Button> </Button>
</div> </div>
)} )}

View File

@ -70,7 +70,7 @@ export const ProjectInboxHeader: FC = observer(() => {
issue={undefined} issue={undefined}
/> />
<Button variant="primary" prependIcon={<Plus />} size="sm" onClick={() => setCreateIssueModal(true)}> <Button variant="primary" size="sm" onClick={() => setCreateIssueModal(true)}>
Add Issue Add Issue
</Button> </Button>
</div> </div>

View File

@ -229,7 +229,6 @@ export const ProjectIssuesHeader: React.FC = observer(() => {
toggleCreateIssueModal(true, EIssuesStoreType.PROJECT); toggleCreateIssueModal(true, EIssuesStoreType.PROJECT);
}} }}
size="sm" size="sm"
prependIcon={<Plus />}
> >
<div className="hidden sm:block">Add</div> Issue <div className="hidden sm:block">Add</div> Issue
</Button> </Button>

View File

@ -241,7 +241,6 @@ export const ProjectViewIssuesHeader: React.FC = observer(() => {
toggleCreateIssueModal(true, EIssuesStoreType.PROJECT_VIEW); toggleCreateIssueModal(true, EIssuesStoreType.PROJECT_VIEW);
}} }}
size="sm" size="sm"
prependIcon={<Plus />}
> >
Add Issue Add Issue
</Button> </Button>

View File

@ -61,13 +61,8 @@ export const ProjectViewsHeader: React.FC = observer(() => {
<div className="flex flex-shrink-0 items-center gap-2"> <div className="flex flex-shrink-0 items-center gap-2">
<ViewListHeader /> <ViewListHeader />
<div> <div>
<Button <Button variant="primary" size="sm" onClick={() => toggleCreateViewModal(true)}>
variant="primary" Add View
size="sm"
prependIcon={<Plus className="h-3.5 w-3.5 stroke-2" />}
onClick={() => toggleCreateViewModal(true)}
>
Create View
</Button> </Button>
</div> </div>
</div> </div>

View File

@ -167,7 +167,6 @@ export const ProjectsHeader = observer(() => {
</div> </div>
{isAuthorizedUser && ( {isAuthorizedUser && (
<Button <Button
prependIcon={<Plus />}
size="sm" size="sm"
onClick={() => { onClick={() => {
setTrackElement("Projects page"); setTrackElement("Projects page");

View File

@ -80,7 +80,7 @@ export const IssueBlockRoot: FC<Props> = observer((props) => {
canEditProperties={canEditProperties} canEditProperties={canEditProperties}
displayProperties={displayProperties} displayProperties={displayProperties}
nestingLevel={nestingLevel + 1} nestingLevel={nestingLevel + 1}
spacingLeft={spacingLeft + (displayProperties?.key ? 19 : 0)} spacingLeft={spacingLeft + (displayProperties?.key ? 12 : 0)}
containerRef={containerRef} containerRef={containerRef}
/> />
))} ))}

View File

@ -86,26 +86,29 @@ export const IssueBlock: React.FC<IssueBlockProps> = observer((props: IssueBlock
<div <div
ref={parentRef} ref={parentRef}
className={cn( className={cn(
"min-h-[52px] relative flex flex-col md:flex-row md:items-center gap-3 bg-custom-background-100 p-3 pl-8 text-sm", "min-h-11 relative flex flex-col md:flex-row md:items-center gap-3 bg-custom-background-100 p-3 pl-1.5 text-sm",
{ {
"border border-custom-primary-70 hover:border-custom-primary-70": getIsIssuePeeked(issue.id), "border border-custom-primary-70 hover:border-custom-primary-70": getIsIssuePeeked(issue.id),
"last:border-b-transparent": !getIsIssuePeeked(issue.id), "last:border-b-transparent": !getIsIssuePeeked(issue.id),
} }
)} )}
> >
<div className="flex w-full truncate" style={nestingLevel !== 0 ? { paddingLeft } : {}}> <div className="flex w-full truncate" style={issue.parent_id && nestingLevel !== 0 ? { paddingLeft } : {}}>
<div className="flex flex-grow items-center gap-3 truncate"> <div className="flex flex-grow items-center gap-3 truncate">
<div className="flex items-center gap-1.5"> <div className="flex items-center gap-0.5">
<div className="flex h-5 w-5 items-center justify-center"> <div className="flex items-center group">
{subIssuesCount > 0 && ( <span className="size-3.5" />
<div className="flex h-4 w-4 items-center justify-center">
{issue.sub_issues_count > 0 && (
<button <button
className="flex items-center justify-center h-5 w-5 cursor-pointer rounded-sm text-custom-text-400 hover:text-custom-text-300" className="flex items-center justify-center h-4 w-4 cursor-pointer rounded-sm text-custom-text-400 hover:text-custom-text-300"
onClick={handleToggleExpand} onClick={handleToggleExpand}
> >
<ChevronRight className={`h-4 w-4 ${isExpanded ? "rotate-90" : ""}`} /> <ChevronRight className={`h-4 w-4 ${isExpanded ? "rotate-90" : ""}`} />
</button> </button>
)} )}
</div> </div>
</div>
{displayProperties && displayProperties?.key && ( {displayProperties && displayProperties?.key && (
<div className="flex-shrink-0 text-xs font-medium text-custom-text-300"> <div className="flex-shrink-0 text-xs font-medium text-custom-text-300">
{projectIdentifier}-{issue.sequence_id} {projectIdentifier}-{issue.sequence_id}
@ -118,7 +121,7 @@ export const IssueBlock: React.FC<IssueBlockProps> = observer((props: IssueBlock
</div> </div>
{issue?.is_draft ? ( {issue?.is_draft ? (
<Tooltip tooltipContent={issue.name} isMobile={isMobile}> <Tooltip tooltipContent={issue.name} isMobile={isMobile} position="top-left">
<p className="truncate">{issue.name}</p> <p className="truncate">{issue.name}</p>
</Tooltip> </Tooltip>
) : ( ) : (
@ -132,7 +135,7 @@ export const IssueBlock: React.FC<IssueBlockProps> = observer((props: IssueBlock
className="w-full truncate cursor-pointer text-sm text-custom-text-100" className="w-full truncate cursor-pointer text-sm text-custom-text-100"
disabled={!!issue?.tempId} disabled={!!issue?.tempId}
> >
<Tooltip tooltipContent={issue.name} isMobile={isMobile}> <Tooltip tooltipContent={issue.name} isMobile={isMobile} position="top-left">
<p className="truncate">{issue.name}</p> <p className="truncate">{issue.name}</p>
</Tooltip> </Tooltip>
</ControlLink> </ControlLink>
@ -151,7 +154,7 @@ export const IssueBlock: React.FC<IssueBlockProps> = observer((props: IssueBlock
{!issue?.tempId ? ( {!issue?.tempId ? (
<> <>
<IssueProperties <IssueProperties
className="relative flex flex-wrap items-center gap-2 whitespace-nowrap md:flex-shrink-0 md:flex-grow" className="relative flex flex-wrap md:flex-grow md:flex-shrink-0 items-center gap-2 whitespace-nowrap"
issue={issue} issue={issue}
isReadOnly={!canEditIssueProperties} isReadOnly={!canEditIssueProperties}
updateIssue={updateIssue} updateIssue={updateIssue}

View File

@ -133,7 +133,7 @@ const GroupByList: React.FC<IGroupByList> = (props) => {
(_list: IGroupByColumn) => (_list: IGroupByColumn) =>
validateEmptyIssueGroups(is_list ? issueIds : issueIds?.[_list.id]) && ( validateEmptyIssueGroups(is_list ? issueIds : issueIds?.[_list.id]) && (
<div key={_list.id} className={`flex flex-shrink-0 flex-col`}> <div key={_list.id} className={`flex flex-shrink-0 flex-col`}>
<div className="sticky top-0 z-[2] w-full flex-shrink-0 border-b border-custom-border-200 bg-custom-background-90 px-3 py-1"> <div className="sticky top-0 z-[2] w-full flex-shrink-0 border-b border-custom-border-200 bg-custom-background-90 px-3 pl-5 py-1">
<HeaderGroupByCard <HeaderGroupByCard
icon={_list.icon} icon={_list.icon}
title={_list.name || ""} title={_list.name || ""}

View File

@ -25,7 +25,7 @@ export const SaveFilterView: FC<ISaveFilterView> = (props) => {
onClose={() => setViewModal(false)} onClose={() => setViewModal(false)}
/> />
<Button size="sm" prependIcon={<Plus />} onClick={() => setViewModal(true)}> <Button size="sm" onClick={() => setViewModal(true)}>
Save View Save View
</Button> </Button>
</div> </div>

View File

@ -50,24 +50,16 @@ export const BlockItemAction: FC<Props> = observer((props) => {
return ( return (
<> <>
{/* page details */} {/* page details */}
<div className="flex items-center gap-2 text-custom-text-400">
{/* <span className="text-xs">Labels</span>
<Circle className="h-1 w-1 fill-custom-text-300" /> */}
<div className="cursor-default"> <div className="cursor-default">
<Tooltip tooltipHeading="Owned by" tooltipContent={ownerDetails?.display_name}> <Tooltip tooltipHeading="Owned by" tooltipContent={ownerDetails?.display_name}>
<Avatar src={ownerDetails?.avatar} name={ownerDetails?.display_name} /> <Avatar src={ownerDetails?.avatar} name={ownerDetails?.display_name} />
</Tooltip> </Tooltip>
</div> </div>
<Circle className="h-1 w-1 fill-custom-text-300" /> <div className="cursor-default text-custom-text-300">
{/* <span className="text-xs cursor-default">10m read</span>
<Circle className="h-1 w-1 fill-custom-text-300" /> */}
<div className="cursor-default">
<Tooltip tooltipContent={access === 0 ? "Public" : "Private"}> <Tooltip tooltipContent={access === 0 ? "Public" : "Private"}>
{access === 0 ? <Earth className="h-3 w-3" /> : <Lock className="h-3 w-3" />} {access === 0 ? <Earth className="h-4 w-4" /> : <Lock className="h-4 w-4" />}
</Tooltip> </Tooltip>
</div> </div>
</div>
{/* vertical divider */} {/* vertical divider */}
<Minus className="h-5 w-5 text-custom-text-400 rotate-90 -mx-3" strokeWidth={1} /> <Minus className="h-5 w-5 text-custom-text-400 rotate-90 -mx-3" strokeWidth={1} />