chore: cycle & module sidebar improvement (#3251)

* chore: no lead option added in module lead select dropdown

* chore: module lead select dropdown code refactor

* chore: cycle sidebar improvement

* chore: module sidebar improvement

* style: cycle and module sidebar improvement

* style: app sidebar improvement
This commit is contained in:
Anmol Singh Bhatia 2023-12-27 15:16:13 +05:30 committed by GitHub
parent 440cfc0f20
commit 05eb728c40
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 153 additions and 53 deletions

View File

@ -17,7 +17,16 @@ import { CycleDeleteModal } from "components/cycles/delete-modal";
import { CustomRangeDatePicker } from "components/ui";
import { Avatar, CustomMenu, Loader, LayersIcon } from "@plane/ui";
// icons
import { ChevronDown, LinkIcon, Trash2, UserCircle2, AlertCircle, ChevronRight, MoveRight } from "lucide-react";
import {
ChevronDown,
LinkIcon,
Trash2,
UserCircle2,
AlertCircle,
ChevronRight,
CalendarCheck2,
CalendarClock,
} from "lucide-react";
// helpers
import { copyUrlToClipboard } from "helpers/string.helper";
import {
@ -357,8 +366,7 @@ export const CycleDetailsSidebar: React.FC<Props> = observer((props) => {
</div>
</div>
<div className="flex flex-col gap-3">
<h4 className="w-full break-words text-xl font-semibold text-custom-text-100">{cycleDetails.name}</h4>
<div className="flex flex-col gap-3 pt-2">
<div className="flex items-center gap-5">
{currentCycle && (
<span
@ -373,15 +381,39 @@ export const CycleDetailsSidebar: React.FC<Props> = observer((props) => {
: `${currentCycle.label}`}
</span>
)}
<div className="relative flex h-full w-52 items-center gap-2.5">
<Popover className="flex h-full items-center justify-center rounded-lg">
</div>
<h4 className="w-full break-words text-xl font-semibold text-custom-text-100">{cycleDetails.name}</h4>
</div>
{cycleDetails.description && (
<span className="w-full whitespace-normal break-words py-2.5 text-sm leading-5 text-custom-text-200">
{cycleDetails.description}
</span>
)}
<div className="flex flex-col gap-5 pb-6 pt-2.5">
<div className="flex items-center justify-start gap-1">
<div className="flex w-1/2 items-center justify-start gap-2 text-custom-text-300">
<CalendarClock className="h-4 w-4" />
<span className="text-base">Start Date</span>
</div>
<div className="relative flex w-1/2 items-center rounded-sm">
<Popover className="flex h-full w-full items-center justify-center rounded-lg">
<Popover.Button
className={`text-sm font-medium text-custom-text-300 ${
className={`text-sm font-medium text-custom-text-300 w-full rounded-sm cursor-pointer hover:bg-custom-background-80 ${
isEditingAllowed ? "cursor-pointer" : "cursor-not-allowed"
}`}
disabled={isCompleted || !isEditingAllowed}
>
{areYearsEqual ? renderShortDate(startDate, "_ _") : renderShortMonthDate(startDate, "_ _")}
<span
className={`group flex w-full items-center justify-between gap-2 py-1 px-1.5 text-sm ${
watch("start_date") ? "" : "text-custom-text-400"
}`}
>
{areYearsEqual
? renderShortDate(startDate, "No date selected")
: renderShortMonthDate(startDate, "No date selected")}
</span>
</Popover.Button>
<Transition
@ -393,7 +425,7 @@ export const CycleDetailsSidebar: React.FC<Props> = observer((props) => {
leaveFrom="opacity-100 translate-y-0"
leaveTo="opacity-0 translate-y-1"
>
<Popover.Panel className="absolute -right-5 top-10 z-20 transform overflow-hidden">
<Popover.Panel className="absolute right-0 top-10 z-20 transform overflow-hidden">
<CustomRangeDatePicker
value={watch("start_date") ? watch("start_date") : cycleDetails?.start_date}
onChange={(val) => {
@ -410,16 +442,32 @@ export const CycleDetailsSidebar: React.FC<Props> = observer((props) => {
</Popover.Panel>
</Transition>
</Popover>
<MoveRight className="h-4 w-4 text-custom-text-300" />
<Popover className="flex h-full items-center justify-center rounded-lg">
</div>
</div>
<div className="flex items-center justify-start gap-1">
<div className="flex w-1/2 items-center justify-start gap-2 text-custom-text-300">
<CalendarCheck2 className="h-4 w-4" />
<span className="text-base">Target Date</span>
</div>
<div className="relative flex w-1/2 items-center rounded-sm">
<Popover className="flex h-full w-full items-center justify-center rounded-lg">
<>
<Popover.Button
className={`text-sm font-medium text-custom-text-300 ${
className={`text-sm font-medium text-custom-text-300 w-full rounded-sm cursor-pointer hover:bg-custom-background-80 ${
isEditingAllowed ? "cursor-pointer" : "cursor-not-allowed"
}`}
disabled={isCompleted || !isEditingAllowed}
>
{areYearsEqual ? renderShortDate(endDate, "_ _") : renderShortMonthDate(endDate, "_ _")}
<span
className={`group flex w-full items-center justify-between gap-2 py-1 px-1.5 text-sm ${
watch("end_date") ? "" : "text-custom-text-400"
}`}
>
{areYearsEqual
? renderShortDate(endDate, "No date selected")
: renderShortMonthDate(endDate, "No date selected")}
</span>
</Popover.Button>
<Transition
@ -431,7 +479,7 @@ export const CycleDetailsSidebar: React.FC<Props> = observer((props) => {
leaveFrom="opacity-100 translate-y-0"
leaveTo="opacity-0 translate-y-1"
>
<Popover.Panel className="absolute -right-5 top-10 z-20 transform overflow-hidden">
<Popover.Panel className="absolute right-0 top-10 z-20 transform overflow-hidden">
<CustomRangeDatePicker
value={watch("end_date") ? watch("end_date") : cycleDetails?.end_date}
onChange={(val) => {
@ -451,15 +499,7 @@ export const CycleDetailsSidebar: React.FC<Props> = observer((props) => {
</Popover>
</div>
</div>
</div>
{cycleDetails.description && (
<span className="w-full whitespace-normal break-words py-2.5 text-sm leading-5 text-custom-text-200">
{cycleDetails.description}
</span>
)}
<div className="flex flex-col gap-5 pb-6 pt-2.5">
<div className="flex items-center justify-start gap-1">
<div className="flex w-1/2 items-center justify-start gap-2 text-custom-text-300">
<UserCircle2 className="h-4 w-4" />

View File

@ -7,7 +7,7 @@ import { ProjectMemberService } from "services/project";
import { Avatar, CustomSearchSelect } from "@plane/ui";
// icons
import { Combobox } from "@headlessui/react";
import { UserCircle } from "lucide-react";
import { UserCircle, UserCircle2 } from "lucide-react";
// fetch-keys
import { PROJECT_MEMBERS } from "constants/fetch-keys";
@ -65,9 +65,10 @@ export const ModuleLeadSelect: React.FC<Props> = ({ value, onChange }) => {
value=""
className="flex cursor-pointer select-none items-center justify-between gap-2 truncate rounded px-1 py-1.5 text-custom-text-200"
>
<span className="flex items-center justify-start gap-1 text-custom-text-200">
<span>No Lead</span>
</span>
<div className="flex items-center gap-2">
<UserCircle2 className="h-4 w-4" />
No lead
</div>
</Combobox.Option>
}
onChange={onChange}

View File

@ -31,6 +31,17 @@ export const SidebarLeadSelect: FC<Props> = (props) => {
: null
);
const noLeadOption = {
value: "",
query: "No lead",
content: (
<div className="flex items-center gap-2">
<UserCircle2 className="h-4 w-4" />
No lead
</div>
),
};
const options = members?.map((member) => ({
value: member.member.id,
query: member.member.display_name,
@ -42,6 +53,8 @@ export const SidebarLeadSelect: FC<Props> = (props) => {
),
}));
const leadOption = (options || []).concat(noLeadOption);
const selectedOption = members?.find((m) => m.member.id === value)?.member;
return (
@ -69,7 +82,7 @@ export const SidebarLeadSelect: FC<Props> = (props) => {
</div>
)
}
options={options}
options={leadOption}
maxHeight="md"
onChange={onChange}
/>

View File

@ -15,7 +15,17 @@ import ProgressChart from "components/core/sidebar/progress-chart";
import { CustomRangeDatePicker } from "components/ui";
import { CustomMenu, Loader, LayersIcon, CustomSelect, ModuleStatusIcon } from "@plane/ui";
// icon
import { AlertCircle, ChevronDown, ChevronRight, Info, LinkIcon, MoveRight, Plus, Trash2 } from "lucide-react";
import {
AlertCircle,
CalendarCheck2,
CalendarClock,
ChevronDown,
ChevronRight,
Info,
LinkIcon,
Plus,
Trash2,
} from "lucide-react";
// helpers
import {
isDateGreaterThanToday,
@ -227,7 +237,13 @@ export const ModuleDetailsSidebar: React.FC<Props> = observer((props) => {
else newValues.push(value);
}
updateFilters(workspaceSlug.toString(), projectId.toString(), EFilterType.FILTERS, { [key]: newValues }, moduleId);
updateFilters(
workspaceSlug.toString(),
projectId.toString(),
EFilterType.FILTERS,
{ [key]: newValues },
moduleId
);
},
[workspaceSlug, projectId, moduleId, issueFilters, updateFilters]
);
@ -328,8 +344,7 @@ export const ModuleDetailsSidebar: React.FC<Props> = observer((props) => {
</div>
<div className="flex flex-col gap-3">
<h4 className="w-full break-words text-xl font-semibold text-custom-text-100">{moduleDetails.name}</h4>
<div className="flex items-center gap-5">
<div className="flex items-center gap-5 pt-2">
<Controller
control={control}
name="status"
@ -365,16 +380,40 @@ export const ModuleDetailsSidebar: React.FC<Props> = observer((props) => {
</CustomSelect>
)}
/>
</div>
<h4 className="w-full break-words text-xl font-semibold text-custom-text-100">{moduleDetails.name}</h4>
</div>
<div className="relative flex h-full w-52 items-center gap-2.5">
<Popover className="flex h-full items-center justify-center rounded-lg">
{moduleDetails.description && (
<span className="w-full whitespace-normal break-words py-2.5 text-sm leading-5 text-custom-text-200">
{moduleDetails.description}
</span>
)}
<div className="flex flex-col gap-5 pb-6 pt-2.5">
<div className="flex items-center justify-start gap-1">
<div className="flex w-1/2 items-center justify-start gap-2 text-custom-text-300">
<CalendarClock className="h-4 w-4" />
<span className="text-base">Start Date</span>
</div>
<div className="relative flex w-1/2 items-center rounded-sm">
<Popover className="flex h-full w-full items-center justify-center rounded-lg">
<Popover.Button
className={`text-sm font-medium text-custom-text-300 ${
className={`text-sm font-medium text-custom-text-300 w-full rounded-sm cursor-pointer hover:bg-custom-background-80 ${
isEditingAllowed ? "cursor-pointer" : "cursor-not-allowed"
}`}
disabled={!isEditingAllowed}
>
{areYearsEqual ? renderShortDate(startDate, "_ _") : renderShortMonthDate(startDate, "_ _")}
<span
className={`group flex w-full items-center justify-between gap-2 py-1 px-1.5 text-sm ${
watch("start_date") ? "" : "text-custom-text-400"
}`}
>
{areYearsEqual
? renderShortDate(startDate, "No date selected")
: renderShortMonthDate(startDate, "No date selected")}
</span>
</Popover.Button>
<Transition
@ -386,7 +425,7 @@ export const ModuleDetailsSidebar: React.FC<Props> = observer((props) => {
leaveFrom="opacity-100 translate-y-0"
leaveTo="opacity-0 translate-y-1"
>
<Popover.Panel className="absolute -right-5 top-10 z-20 transform overflow-hidden">
<Popover.Panel className="absolute right-0 top-10 z-20 transform overflow-hidden">
<CustomRangeDatePicker
value={watch("start_date") ? watch("start_date") : moduleDetails?.start_date}
onChange={(val) => {
@ -402,16 +441,32 @@ export const ModuleDetailsSidebar: React.FC<Props> = observer((props) => {
</Popover.Panel>
</Transition>
</Popover>
<MoveRight className="h-4 w-4 text-custom-text-300" />
<Popover className="flex h-full items-center justify-center rounded-lg">
</div>
</div>
<div className="flex items-center justify-start gap-1">
<div className="flex w-1/2 items-center justify-start gap-2 text-custom-text-300">
<CalendarCheck2 className="h-4 w-4" />
<span className="text-base">Target Date</span>
</div>
<div className="relative flex w-1/2 items-center rounded-sm">
<Popover className="flex h-full w-full items-center justify-center rounded-lg">
<>
<Popover.Button
className={`text-sm font-medium text-custom-text-300 ${
className={`text-sm font-medium text-custom-text-300 w-full rounded-sm cursor-pointer hover:bg-custom-background-80 ${
isEditingAllowed ? "cursor-pointer" : "cursor-not-allowed"
}`}
disabled={!isEditingAllowed}
>
{areYearsEqual ? renderShortDate(endDate, "_ _") : renderShortMonthDate(endDate, "_ _")}
<span
className={`group flex w-full items-center justify-between gap-2 py-1 px-1.5 text-sm ${
watch("target_date") ? "" : "text-custom-text-400"
}`}
>
{areYearsEqual
? renderShortDate(endDate, "No date selected")
: renderShortMonthDate(endDate, "No date selected")}
</span>
</Popover.Button>
<Transition
@ -423,7 +478,7 @@ export const ModuleDetailsSidebar: React.FC<Props> = observer((props) => {
leaveFrom="opacity-100 translate-y-0"
leaveTo="opacity-0 translate-y-1"
>
<Popover.Panel className="absolute -right-5 top-10 z-20 transform overflow-hidden">
<Popover.Panel className="absolute right-0 top-10 z-20 transform overflow-hidden">
<CustomRangeDatePicker
value={watch("target_date") ? watch("target_date") : moduleDetails?.target_date}
onChange={(val) => {
@ -442,15 +497,6 @@ export const ModuleDetailsSidebar: React.FC<Props> = observer((props) => {
</Popover>
</div>
</div>
</div>
{moduleDetails.description && (
<span className="w-full whitespace-normal break-words py-2.5 text-sm leading-5 text-custom-text-200">
{moduleDetails.description}
</span>
)}
<div className="flex flex-col gap-5 pb-6 pt-2.5">
<Controller
control={control}
name="lead"

View File

@ -138,9 +138,9 @@ export const ProjectSidebarList: FC = observer(() => {
>
Favorites
{open ? (
<ChevronDown className="h-3 w-3 opacity-0 group-hover:opacity-100" />
<ChevronDown className="h-3.5 w-3.5" />
) : (
<ChevronRight className="h-3 w-3 opacity-0 group-hover:opacity-100" />
<ChevronRight className="h-3.5 w-3.5" />
)}
</Disclosure.Button>
{isAuthorizedUser && (
@ -215,9 +215,9 @@ export const ProjectSidebarList: FC = observer(() => {
>
Projects
{open ? (
<ChevronDown className="h-3 w-3 opacity-0 group-hover:opacity-100" />
<ChevronDown className="h-3.5 w-3.5" />
) : (
<ChevronRight className="h-3 w-3 opacity-0 group-hover:opacity-100" />
<ChevronRight className="h-3.5 w-3.5" />
)}
</Disclosure.Button>
{isAuthorizedUser && (