forked from github/plane
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:
parent
440cfc0f20
commit
05eb728c40
@ -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" />
|
||||
|
@ -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}
|
||||
|
@ -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}
|
||||
/>
|
||||
|
@ -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"
|
||||
|
@ -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 && (
|
||||
|
Loading…
Reference in New Issue
Block a user