chore: spreadsheet layout improvement (#2677)

* style: spreadsheet column width fix

* style: spreadsheet label column styling

* chore: spreadsheet layout issue properties improvement

* fix: build error
This commit is contained in:
Anmol Singh Bhatia 2023-11-07 15:58:00 +05:30 committed by GitHub
parent 98974fdc50
commit 93d03f82b4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 77 additions and 23 deletions

View File

@ -110,7 +110,7 @@ export const IssuePropertyEstimates: React.FC<IIssuePropertyEstimates> = observe
<button <button
ref={setReferenceElement} ref={setReferenceElement}
type="button" type="button"
className={`flex items-center justify-between gap-1 w-full text-xs px-2.5 py-1 rounded border-[0.5px] border-custom-border-300 duration-300 focus:outline-none ${ className={`flex items-center justify-between gap-1 w-full text-xs px-2.5 py-1 rounded border-[0.5px] border-custom-border-300 ${
disabled ? "cursor-not-allowed text-custom-text-200" : "cursor-pointer hover:bg-custom-background-80" disabled ? "cursor-not-allowed text-custom-text-200" : "cursor-pointer hover:bg-custom-background-80"
} ${buttonClassName}`} } ${buttonClassName}`}
> >

View File

@ -37,8 +37,8 @@ export const IssuePropertyLabels: React.FC<IIssuePropertyLabels> = observer((pro
disabled, disabled,
hideDropdownArrow = false, hideDropdownArrow = false,
className, className,
buttonClassName, buttonClassName = "",
optionsClassName, optionsClassName = "",
placement, placement,
maxRender = 2, maxRender = 2,
noLabelBorder = false, noLabelBorder = false,
@ -93,7 +93,7 @@ export const IssuePropertyLabels: React.FC<IIssuePropertyLabels> = observer((pro
}); });
const label = ( const label = (
<div className="flex items-center gap-2 text-custom-text-200 h-full"> <div className="flex items-center gap-2 text-custom-text-200">
{value.length > 0 ? ( {value.length > 0 ? (
value.length <= maxRender ? ( value.length <= maxRender ? (
<> <>

View File

@ -18,7 +18,7 @@ export const SpreadsheetAttachmentColumn: React.FC<Props> = (props) => {
return ( return (
<> <>
<div className="flex items-center justify-center text-xs h-full w-full"> <div className="flex items-center px-2.5 py-1 text-xs h-full w-full">
{issue.attachment_count} {issue.attachment_count === 1 ? "attachment" : "attachments"} {issue.attachment_count} {issue.attachment_count === 1 ? "attachment" : "attachments"}
</div> </div>

View File

@ -24,8 +24,7 @@ export const SpreadsheetDueDateColumn: React.FC<Props> = ({ issue, onChange, exp
<ViewDueDateSelect <ViewDueDateSelect
issue={issue} issue={issue}
onChange={(val) => onChange({ target_date: val })} onChange={(val) => onChange({ target_date: val })}
className="!h-full !w-full max-w-full px-2.5 py-1 flex items-center" className="flex items-center px-2.5 py-1 !h-full !w-full max-w-full"
buttonClassName="!h-full !w-full !shadow-none px-2.5"
noBorder noBorder
disabled={disabled} disabled={disabled}
/> />

View File

@ -29,7 +29,7 @@ export const SpreadsheetLabelColumn: React.FC<Props> = (props) => {
value={issue.labels} value={issue.labels}
onChange={(data) => onChange({ labels: data })} onChange={(data) => onChange({ labels: data })}
className="h-full w-full" className="h-full w-full"
buttonClassName="!shadow-none !border-0 h-full w-full px-2.5 py-1 " buttonClassName="px-2.5 h-full"
noLabelBorder noLabelBorder
hideDropdownArrow hideDropdownArrow
maxRender={1} maxRender={1}

View File

@ -18,7 +18,7 @@ export const SpreadsheetLinkColumn: React.FC<Props> = (props) => {
return ( return (
<> <>
<div className="flex items-center justify-center text-xs h-full w-full"> <div className="flex items-center px-2.5 py-1 text-xs h-full w-full">
{issue.link_count} {issue.link_count === 1 ? "link" : "links"} {issue.link_count} {issue.link_count === 1 ? "link" : "links"}
</div> </div>

View File

@ -24,8 +24,7 @@ export const SpreadsheetStartDateColumn: React.FC<Props> = ({ issue, onChange, e
<ViewStartDateSelect <ViewStartDateSelect
issue={issue} issue={issue}
onChange={(val) => onChange({ start_date: val })} onChange={(val) => onChange({ start_date: val })}
className="!h-full !w-full max-w-full px-2.5 py-1 flex items-center" className="flex items-center px-2.5 py-1 !h-full !w-full max-w-full"
buttonClassName="!h-full !w-full !shadow-none px-2.5"
noBorder noBorder
disabled={disabled} disabled={disabled}
/> />

View File

@ -18,7 +18,7 @@ export const SpreadsheetSubIssueColumn: React.FC<Props> = (props) => {
return ( return (
<> <>
<div className="flex items-center justify-center text-xs h-full w-full"> <div className="flex items-center px-2.5 py-1 text-xs h-full w-full">
{issue.sub_issues_count} {issue.sub_issues_count === 1 ? "sub-issue" : "sub-issues"} {issue.sub_issues_count} {issue.sub_issues_count === 1 ? "sub-issue" : "sub-issues"}
</div> </div>

View File

@ -84,7 +84,7 @@ export const SpreadsheetColumn: React.FC<Props> = (props) => {
const propertyDetails = SPREADSHEET_PROPERTY_DETAILS[property]; const propertyDetails = SPREADSHEET_PROPERTY_DETAILS[property];
return ( return (
<div className="relative flex flex-col h-max w-full bg-custom-background-100"> <div className="relative flex flex-col h-max w-full max-w-max bg-custom-background-100">
<div className="flex items-center min-w-[8rem] px-4 py-1 text-sm font-medium z-[1] h-11 w-full sticky top-0 bg-custom-background-90 border border-l-0 border-custom-border-100"> <div className="flex items-center min-w-[8rem] px-4 py-1 text-sm font-medium z-[1] h-11 w-full sticky top-0 bg-custom-background-90 border border-l-0 border-custom-border-100">
<CustomMenu <CustomMenu
customButtonClassName="!w-full" customButtonClassName="!w-full"

View File

@ -1,8 +1,14 @@
// ui // ui
import { CustomDatePicker } from "components/ui"; import { CustomDatePicker } from "components/ui";
import { Tooltip } from "@plane/ui"; import { Tooltip } from "@plane/ui";
import { CalendarDays } from "lucide-react";
// helpers // helpers
import { findHowManyDaysLeft, renderShortDateWithYearFormat } from "helpers/date-time.helper"; import {
findHowManyDaysLeft,
renderShortDate,
renderShortDateWithYearFormat,
renderShortMonthDate,
} from "helpers/date-time.helper";
// types // types
import { IIssue } from "types"; import { IIssue } from "types";
@ -13,7 +19,6 @@ type Props = {
handleOnClose?: () => void; handleOnClose?: () => void;
tooltipPosition?: "top" | "bottom"; tooltipPosition?: "top" | "bottom";
className?: string; className?: string;
buttonClassName?: string;
noBorder?: boolean; noBorder?: boolean;
disabled: boolean; disabled: boolean;
}; };
@ -25,13 +30,16 @@ export const ViewDueDateSelect: React.FC<Props> = ({
handleOnClose, handleOnClose,
tooltipPosition = "top", tooltipPosition = "top",
className = "", className = "",
buttonClassName = "",
noBorder = false, noBorder = false,
disabled, disabled,
}) => { }) => {
const minDate = issue.start_date ? new Date(issue.start_date) : null; const minDate = issue.start_date ? new Date(issue.start_date) : null;
minDate?.setDate(minDate.getDate()); minDate?.setDate(minDate.getDate());
const today = new Date();
const endDate = new Date(issue.target_date ?? "");
const areYearsEqual = endDate.getFullYear() === today.getFullYear();
return ( return (
<Tooltip <Tooltip
tooltipHeading="Due date" tooltipHeading="Due date"
@ -48,10 +56,32 @@ export const ViewDueDateSelect: React.FC<Props> = ({
}`} }`}
> >
<CustomDatePicker <CustomDatePicker
placeholder="Due date"
value={issue?.target_date} value={issue?.target_date}
onChange={onChange} onChange={onChange}
className={`bg-transparent ${issue?.target_date ? "w-[6.5rem]" : "w-[5rem] text-center"} ${buttonClassName}`} className={`bg-transparent ${issue?.target_date ? "w-[6.5rem]" : "w-[5rem] text-center"}`}
customInput={
<div
className={`flex items-center justify-center gap-2 px-2 py-1 text-xs cursor-pointer rounded border border-custom-border-200 shadow-sm duration-200 hover:bg-custom-background-80 ${
issue.target_date ? "pr-6 text-custom-text-300" : "text-custom-text-400"
}`}
>
{issue.target_date ? (
<>
<CalendarDays className="h-3.5 w-3.5 flex-shrink-0" />
<span>
{areYearsEqual
? renderShortDate(issue.target_date ?? "", "_ _")
: renderShortMonthDate(issue.target_date ?? "", "_ _")}
</span>
</>
) : (
<>
<CalendarDays className="h-3.5 w-3.5 flex-shrink-0" />
<span>Due Date</span>
</>
)}
</div>
}
minDate={minDate ?? undefined} minDate={minDate ?? undefined}
noBorder={noBorder} noBorder={noBorder}
handleOnOpen={handleOnOpen} handleOnOpen={handleOnOpen}

View File

@ -1,8 +1,9 @@
// ui // ui
import { CustomDatePicker } from "components/ui"; import { CustomDatePicker } from "components/ui";
import { Tooltip } from "@plane/ui"; import { Tooltip } from "@plane/ui";
import { CalendarDays } from "lucide-react";
// helpers // helpers
import { renderShortDateWithYearFormat } from "helpers/date-time.helper"; import { renderShortDate, renderShortDateWithYearFormat, renderShortMonthDate } from "helpers/date-time.helper";
// types // types
import { IIssue } from "types"; import { IIssue } from "types";
@ -13,7 +14,6 @@ type Props = {
handleOnClose?: () => void; handleOnClose?: () => void;
tooltipPosition?: "top" | "bottom"; tooltipPosition?: "top" | "bottom";
className?: string; className?: string;
buttonClassName?: string;
noBorder?: boolean; noBorder?: boolean;
disabled: boolean; disabled: boolean;
}; };
@ -25,12 +25,14 @@ export const ViewStartDateSelect: React.FC<Props> = ({
handleOnClose, handleOnClose,
tooltipPosition = "top", tooltipPosition = "top",
className = "", className = "",
buttonClassName = "",
noBorder = false, noBorder = false,
disabled, disabled,
}) => { }) => {
const maxDate = issue.target_date ? new Date(issue.target_date) : null; const maxDate = issue.target_date ? new Date(issue.target_date) : null;
maxDate?.setDate(maxDate.getDate()); maxDate?.setDate(maxDate.getDate());
const today = new Date();
const startDate = new Date(issue.start_date ?? "");
const areYearsEqual = startDate.getFullYear() === today.getFullYear();
return ( return (
<Tooltip <Tooltip
@ -40,13 +42,34 @@ export const ViewStartDateSelect: React.FC<Props> = ({
> >
<div className={`group flex-shrink-0 relative max-w-[6.5rem] ${className}`}> <div className={`group flex-shrink-0 relative max-w-[6.5rem] ${className}`}>
<CustomDatePicker <CustomDatePicker
placeholder="Start date"
value={issue?.start_date} value={issue?.start_date}
onChange={onChange} onChange={onChange}
className={`bg-inherit ${issue?.start_date ? "w-[6.5rem]" : "w-[5rem] text-center"} ${buttonClassName}`}
maxDate={maxDate ?? undefined} maxDate={maxDate ?? undefined}
noBorder={noBorder} noBorder={noBorder}
handleOnOpen={handleOnOpen} handleOnOpen={handleOnOpen}
customInput={
<div
className={`flex items-center justify-center gap-2 px-2 py-1 text-xs cursor-pointer rounded border border-custom-border-200 shadow-sm duration-200 hover:bg-custom-background-80 ${
issue?.start_date ? "pr-6 text-custom-text-300" : "text-custom-text-400"
}`}
>
{issue?.start_date ? (
<>
<CalendarDays className="h-3.5 w-3.5 flex-shrink-0" />
<span>
{areYearsEqual
? renderShortDate(issue?.start_date, "_ _")
: renderShortMonthDate(issue?.start_date, "_ _")}
</span>
</>
) : (
<>
<CalendarDays className="h-3.5 w-3.5 flex-shrink-0" />
<span>Start Date</span>
</>
)}
</div>
}
handleOnClose={handleOnClose} handleOnClose={handleOnClose}
disabled={disabled} disabled={disabled}
/> />

View File

@ -10,6 +10,7 @@ type Props = {
onChange: (val: string | null) => void; onChange: (val: string | null) => void;
handleOnOpen?: () => void; handleOnOpen?: () => void;
handleOnClose?: () => void; handleOnClose?: () => void;
customInput?: React.ReactNode;
placeholder?: string; placeholder?: string;
displayShortForm?: boolean; displayShortForm?: boolean;
error?: boolean; error?: boolean;
@ -35,6 +36,7 @@ export const CustomDatePicker: React.FC<Props> = ({
className = "", className = "",
isClearable = true, isClearable = true,
disabled = false, disabled = false,
customInput,
maxDate, maxDate,
minDate, minDate,
}) => ( }) => (
@ -48,6 +50,7 @@ export const CustomDatePicker: React.FC<Props> = ({
onCalendarOpen={handleOnOpen} onCalendarOpen={handleOnOpen}
onCalendarClose={handleOnClose} onCalendarClose={handleOnClose}
wrapperClassName={wrapperClassName} wrapperClassName={wrapperClassName}
customInput={customInput}
className={`${ className={`${
renderAs === "input" renderAs === "input"
? "block px-2 py-2 text-sm focus:outline-none" ? "block px-2 py-2 text-sm focus:outline-none"