style: peek overview

This commit is contained in:
Aaryan Khandelwal 2024-06-04 22:13:05 +05:30
parent 0aa02a603d
commit 899d49b1f0
3 changed files with 56 additions and 57 deletions

View File

@ -1,10 +1,9 @@
import React from "react";
import { observer } from "mobx-react-lite";
import { MoveRight } from "lucide-react";
import { Link2, MoveRight } from "lucide-react";
import { Listbox, Transition } from "@headlessui/react";
// ui
import { setToast, TOAST_TYPE } from "@plane/ui";
import { Icon } from "@/components/ui";
import { CenterPanelIcon, FullScreenPanelIcon, setToast, SidePanelIcon, TOAST_TYPE } from "@plane/ui";
// helpers
import { copyTextToClipboard } from "@/helpers/string.helper";
// hooks
@ -18,21 +17,21 @@ type Props = {
issueDetails: IIssue | undefined;
};
const peekModes: {
const PEEK_MODES: {
key: IPeekMode;
icon: string;
icon: any;
label: string;
}[] = [
{ key: "side", icon: "side_navigation", label: "Side Peek" },
{ key: "side", icon: SidePanelIcon, label: "Side Peek" },
{
key: "modal",
icon: "dialogs",
label: "Modal Peek",
icon: CenterPanelIcon,
label: "Modal",
},
{
key: "full",
icon: "nearby",
label: "Full Screen Peek",
icon: FullScreenPanelIcon,
label: "Full Screen",
},
];
@ -47,20 +46,22 @@ export const PeekOverviewHeader: React.FC<Props> = observer((props) => {
copyTextToClipboard(urlToCopy).then(() => {
setToast({
type: TOAST_TYPE.INFO,
type: TOAST_TYPE.SUCCESS,
title: "Link copied!",
message: "Issue link copied to clipboard",
message: "Issue link copied to clipboard.",
});
});
};
const Icon = PEEK_MODES.find((m) => m.key === peekMode)?.icon ?? SidePanelIcon;
return (
<>
<div className="flex items-center justify-between">
<div className="flex items-center gap-4">
{peekMode === "side" && (
<button type="button" onClick={handleClose}>
<MoveRight className="h-4 w-4" strokeWidth={2} />
<button type="button" onClick={handleClose} className="text-custom-text-300 hover:text-custom-text-200">
<MoveRight className="size-4" />
</button>
)}
<Listbox
@ -69,8 +70,10 @@ export const PeekOverviewHeader: React.FC<Props> = observer((props) => {
onChange={(val) => setPeekMode(val)}
className="relative flex-shrink-0 text-left"
>
<Listbox.Button className={`grid place-items-center ${peekMode === "full" ? "rotate-45" : ""}`}>
<Icon iconName={peekModes.find((m) => m.key === peekMode)?.icon ?? ""} className="text-[1rem]" />
<Listbox.Button
className={`grid place-items-center text-custom-text-300 hover:text-custom-text-200 ${peekMode === "full" ? "rotate-45" : ""}`}
>
<Icon className="h-4 w-4 text-custom-text-300 hover:text-custom-text-200" />
</Listbox.Button>
<Transition
@ -84,7 +87,7 @@ export const PeekOverviewHeader: React.FC<Props> = observer((props) => {
>
<Listbox.Options className="absolute left-0 z-10 mt-1 min-w-[8rem] origin-top-left overflow-y-auto whitespace-nowrap rounded-md border border-custom-border-300 bg-custom-background-90 text-xs shadow-lg focus:outline-none">
<div className="space-y-1 p-2">
{peekModes.map((mode) => (
{PEEK_MODES.map((mode) => (
<Listbox.Option
key={mode.key}
value={mode.key}
@ -117,8 +120,13 @@ export const PeekOverviewHeader: React.FC<Props> = observer((props) => {
</div>
{isClipboardWriteAllowed && (peekMode === "side" || peekMode === "modal") && (
<div className="flex flex-shrink-0 items-center gap-2">
<button type="button" onClick={handleCopyLink} className="-rotate-45 focus:outline-none" tabIndex={1}>
<Icon iconName="link" className="text-[1rem]" />
<button
type="button"
onClick={handleCopyLink}
className="focus:outline-none text-custom-text-300 hover:text-custom-text-200"
tabIndex={1}
>
<Link2 className="h-4 w-4 -rotate-45" />
</button>
</div>
)}

View File

@ -16,10 +16,10 @@ export const PeekOverviewIssueDetails: React.FC<Props> = (props) => {
return (
<div className="space-y-2">
<h6 className="font-medium text-custom-text-200">
{issueDetails.project_detail.identifier}-{issueDetails.sequence_id}
<h6 className="text-base font-medium text-custom-text-400">
{issueDetails.project_detail?.identifier}-{issueDetails?.sequence_id}
</h6>
<h4 className="break-words text-2xl font-semibold">{issueDetails.name}</h4>
<h4 className="break-words text-2xl font-medium">{issueDetails.name}</h4>
{description !== "" && description !== "<p></p>" && (
<RichTextReadOnlyEditor
initialValue={

View File

@ -1,10 +1,10 @@
import { CalendarCheck2 } from "lucide-react";
import { CalendarCheck2, Signal } from "lucide-react";
// ui
import { StateGroupIcon, TOAST_TYPE, setToast } from "@plane/ui";
import { DoubleCircleIcon, StateGroupIcon, TOAST_TYPE, setToast } from "@plane/ui";
// components
import { Icon } from "@/components/ui";
// constants
import { issueGroupFilter, issuePriorityFilter } from "@/constants/issue";
import { issuePriorityFilter } from "@/constants/issue";
// helpers
import { cn } from "@/helpers/common.helper";
import { renderFormattedDate } from "@/helpers/date-time.helper";
@ -20,7 +20,6 @@ type Props = {
export const PeekOverviewIssueProperties: React.FC<Props> = ({ issueDetails, mode }) => {
const state = issueDetails.state_detail;
const stateGroup = issueGroupFilter(state.group);
const priority = issueDetails.priority ? issuePriorityFilter(issueDetails.priority) : null;
@ -50,28 +49,22 @@ export const PeekOverviewIssueProperties: React.FC<Props> = ({ issueDetails, mod
</div>
</div>
)}
<div className={`space-y-4 ${mode === "full" ? "pt-3" : ""}`}>
<div className="flex items-center gap-2 text-sm">
<div className="flex w-1/4 flex-shrink-0 items-center gap-2 font-medium">
<Icon iconName="radio_button_checked" className="flex-shrink-0 !text-base" />
<span className="flex-grow truncate">State</span>
<div className={`space-y-2 ${mode === "full" ? "pt-3" : ""}`}>
<div className="flex items-center gap-3 h-8">
<div className="flex items-center gap-1 w-1/4 flex-shrink-0 text-sm text-custom-text-300">
<DoubleCircleIcon className="size-4 flex-shrink-0" />
<span>State</span>
</div>
<div className="w-3/4">
{stateGroup && (
<div className="inline-flex rounded bg-custom-background-80 px-2.5 py-0.5 text-sm">
<div className="flex items-center gap-1.5 text-left text-custom-text-100">
<StateGroupIcon stateGroup={state.group} color={state.color} />
{addSpaceIfCamelCase(state?.name ?? "")}
</div>
</div>
)}
<div className="w-3/4 flex items-center gap-1.5 py-0.5 text-sm">
<StateGroupIcon stateGroup={state.group} color={state.color} />
{addSpaceIfCamelCase(state?.name ?? "")}
</div>
</div>
<div className="flex items-center gap-2 text-sm">
<div className="flex w-1/4 flex-shrink-0 items-center gap-2 font-medium">
<Icon iconName="signal_cellular_alt" className="flex-shrink-0 !text-base" />
<span className="flex-grow truncate">Priority</span>
<div className="flex items-center gap-3 h-8">
<div className="flex items-center gap-1 w-1/4 flex-shrink-0 text-sm text-custom-text-300">
<Signal className="size-4 flex-shrink-0" />
<span>Priority</span>
</div>
<div className="w-3/4">
<div
@ -96,23 +89,21 @@ export const PeekOverviewIssueProperties: React.FC<Props> = ({ issueDetails, mod
</div>
</div>
</div>
<div className="flex items-center gap-2 text-sm">
<div className="flex w-1/4 flex-shrink-0 items-center gap-2 font-medium">
<Icon iconName="calendar_today" className="flex-shrink-0 !text-base" />
<span className="flex-grow truncate">Due date</span>
<div className="flex items-center gap-3 h-8">
<div className="flex items-center gap-1 w-1/4 flex-shrink-0 text-sm text-custom-text-300">
<CalendarCheck2 className="size-4 flex-shrink-0" />
<span>Due date</span>
</div>
<div>
{issueDetails.target_date ? (
<div
className={cn(
"flex h-6 items-center gap-1 rounded border border-custom-border-100 bg-custom-background-80 px-2.5 py-1 text-xs text-custom-text-100",
{
"text-red-500": shouldHighlightIssueDueDate(
issueDetails.target_date,
issueDetails.state_detail.group
),
}
)}
className={cn("flex items-center gap-1.5 rounded py-0.5 text-xs text-custom-text-100", {
"text-red-500": shouldHighlightIssueDueDate(
issueDetails.target_date,
issueDetails.state_detail.group
),
})}
>
<CalendarCheck2 className="size-3" />
{renderFormattedDate(issueDetails.target_date)}