feat: calendar filters (#908)

* feat: hiding unnecessary filters for calendar view

* feat: filters for calendar view

* feat: module and cycle calendar view filters
This commit is contained in:
Anmol Singh Bhatia 2023-04-21 01:42:09 +05:30 committed by GitHub
parent 2ba4594b29
commit 9129a6cde2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 190 additions and 145 deletions

View File

@ -26,7 +26,7 @@ import {
import { Popover, Transition } from "@headlessui/react"; import { Popover, Transition } from "@headlessui/react";
import { DragDropContext, Draggable, DropResult } from "react-beautiful-dnd"; import { DragDropContext, Draggable, DropResult } from "react-beautiful-dnd";
import StrictModeDroppable from "components/dnd/StrictModeDroppable"; import StrictModeDroppable from "components/dnd/StrictModeDroppable";
import { CustomMenu } from "components/ui"; import { CustomMenu, Spinner } from "components/ui";
// icon // icon
import { import {
CheckIcon, CheckIcon,
@ -35,6 +35,8 @@ import {
ChevronRightIcon, ChevronRightIcon,
PlusIcon, PlusIcon,
} from "@heroicons/react/24/outline"; } from "@heroicons/react/24/outline";
// hooks
import useIssuesView from "hooks/use-issues-view";
// services // services
import issuesService from "services/issues.service"; import issuesService from "services/issues.service";
import cyclesService from "services/cycles.service"; import cyclesService from "services/cycles.service";
@ -67,6 +69,8 @@ export const CalendarView: React.FC<Props> = ({ addIssueToDate }) => {
const router = useRouter(); const router = useRouter();
const { workspaceSlug, projectId, cycleId, moduleId } = router.query; const { workspaceSlug, projectId, cycleId, moduleId } = router.query;
const { params } = useIssuesView();
const [calendarDateRange, setCalendarDateRange] = useState<ICalendarRange>({ const [calendarDateRange, setCalendarDateRange] = useState<ICalendarRange>({
startDate: startOfWeek(currentDate), startDate: startOfWeek(currentDate),
endDate: lastDayOfWeek(currentDate), endDate: lastDayOfWeek(currentDate),
@ -82,11 +86,13 @@ export const CalendarView: React.FC<Props> = ({ addIssueToDate }) => {
workspaceSlug && projectId ? PROJECT_CALENDAR_ISSUES(projectId as string) : null, workspaceSlug && projectId ? PROJECT_CALENDAR_ISSUES(projectId as string) : null,
workspaceSlug && projectId workspaceSlug && projectId
? () => ? () =>
issuesService.getIssuesWithParams( issuesService.getIssuesWithParams(workspaceSlug as string, projectId as string, {
workspaceSlug as string, ...params,
projectId as string, target_date: `${renderDateFormat(calendarDateRange.startDate)};after,${renderDateFormat(
targetDateFilter calendarDateRange.endDate
) )};before`,
group_by: null,
})
: null : null
); );
@ -100,7 +106,13 @@ export const CalendarView: React.FC<Props> = ({ addIssueToDate }) => {
workspaceSlug as string, workspaceSlug as string,
projectId as string, projectId as string,
cycleId as string, cycleId as string,
targetDateFilter {
...params,
target_date: `${renderDateFormat(calendarDateRange.startDate)};after,${renderDateFormat(
calendarDateRange.endDate
)};before`,
group_by: null,
}
) )
: null : null
); );
@ -115,7 +127,13 @@ export const CalendarView: React.FC<Props> = ({ addIssueToDate }) => {
workspaceSlug as string, workspaceSlug as string,
projectId as string, projectId as string,
moduleId as string, moduleId as string,
targetDateFilter {
...params,
target_date: `${renderDateFormat(calendarDateRange.startDate)};after,${renderDateFormat(
calendarDateRange.endDate
)};before`,
group_by: null,
}
) )
: null : null
); );
@ -132,7 +150,11 @@ export const CalendarView: React.FC<Props> = ({ addIssueToDate }) => {
const currentViewDays = showWeekEnds ? totalDate : onlyWeekDays; const currentViewDays = showWeekEnds ? totalDate : onlyWeekDays;
const calendarIssues = cycleCalendarIssues ?? moduleCalendarIssues ?? projectCalendarIssues; const calendarIssues = cycleId
? cycleCalendarIssues
: moduleId
? moduleCalendarIssues
: projectCalendarIssues;
const currentViewDaysData = currentViewDays.map((date: Date) => { const currentViewDaysData = currentViewDays.map((date: Date) => {
const filterIssue = const filterIssue =
@ -203,11 +225,11 @@ export const CalendarView: React.FC<Props> = ({ addIssueToDate }) => {
}); });
}; };
return ( return calendarIssues ? (
<DragDropContext onDragEnd={onDragEnd}> <DragDropContext onDragEnd={onDragEnd}>
<div className="h-full overflow-y-auto rounded-lg text-gray-600 -m-2"> <div className="-m-2 h-full overflow-y-auto rounded-lg text-gray-600">
<div className="mb-4 flex items-center justify-between"> <div className="mb-4 flex items-center justify-between">
<div className="relative flex h-full w-full gap-2 items-center justify-start text-sm "> <div className="relative flex h-full w-full items-center justify-start gap-2 text-sm ">
<Popover className="flex h-full items-center justify-start rounded-lg"> <Popover className="flex h-full items-center justify-start rounded-lg">
{({ open }) => ( {({ open }) => (
<> <>
@ -227,8 +249,8 @@ export const CalendarView: React.FC<Props> = ({ addIssueToDate }) => {
leaveFrom="opacity-100 translate-y-0" leaveFrom="opacity-100 translate-y-0"
leaveTo="opacity-0 translate-y-1" leaveTo="opacity-0 translate-y-1"
> >
<Popover.Panel className="absolute top-10 left-0 z-20 w-full max-w-xs flex flex-col transform overflow-hidden bg-brand-surface-2 shadow-lg rounded-[10px]"> <Popover.Panel className="absolute top-10 left-0 z-20 flex w-full max-w-xs transform flex-col overflow-hidden rounded-[10px] bg-brand-surface-2 shadow-lg">
<div className="flex justify-center items-center text-sm gap-5 px-2 py-2"> <div className="flex items-center justify-center gap-5 px-2 py-2 text-sm">
{yearOptions.map((year) => ( {yearOptions.map((year) => (
<button <button
onClick={() => updateDate(updateDateWithYear(year.label, currentDate))} onClick={() => updateDate(updateDateWithYear(year.label, currentDate))}
@ -236,19 +258,19 @@ export const CalendarView: React.FC<Props> = ({ addIssueToDate }) => {
isSameYear(year.value, currentDate) isSameYear(year.value, currentDate)
? "text-sm font-medium text-gray-800" ? "text-sm font-medium text-gray-800"
: "text-xs text-gray-400 " : "text-xs text-gray-400 "
} hover:text-sm hover:text-gray-800 hover:font-medium`} } hover:text-sm hover:font-medium hover:text-gray-800`}
> >
{year.label} {year.label}
</button> </button>
))} ))}
</div> </div>
<div className="grid grid-cols-4 px-2 border-t border-brand-base"> <div className="grid grid-cols-4 border-t border-brand-base px-2">
{monthOptions.map((month) => ( {monthOptions.map((month) => (
<button <button
onClick={() => onClick={() =>
updateDate(updateDateWithMonth(month.value, currentDate)) updateDate(updateDateWithMonth(month.value, currentDate))
} }
className={`text-gray-400 text-xs px-2 py-2 hover:font-medium hover:text-gray-800 ${ className={`px-2 py-2 text-xs text-gray-400 hover:font-medium hover:text-gray-800 ${
isSameMonth(month.value, currentDate) isSameMonth(month.value, currentDate)
? "font-medium text-gray-800" ? "font-medium text-gray-800"
: "" : ""
@ -300,7 +322,7 @@ export const CalendarView: React.FC<Props> = ({ addIssueToDate }) => {
</div> </div>
</div> </div>
<div className="flex w-full gap-2 items-center justify-end"> <div className="flex w-full items-center justify-end gap-2">
<button <button
className="group flex cursor-pointer items-center gap-2 rounded-md border border-brand-base bg-brand-surface-2 px-4 py-1.5 text-sm hover:bg-brand-surface-1 hover:text-brand-base focus:outline-none" className="group flex cursor-pointer items-center gap-2 rounded-md border border-brand-base bg-brand-surface-2 px-4 py-1.5 text-sm hover:bg-brand-surface-1 hover:text-brand-base focus:outline-none"
onClick={() => { onClick={() => {
@ -317,6 +339,7 @@ export const CalendarView: React.FC<Props> = ({ addIssueToDate }) => {
> >
Today{" "} Today{" "}
</button> </button>
<CustomMenu <CustomMenu
customButton={ customButton={
<div <div
@ -397,7 +420,7 @@ export const CalendarView: React.FC<Props> = ({ addIssueToDate }) => {
{weeks.map((date, index) => ( {weeks.map((date, index) => (
<div <div
key={index} key={index}
className={`flex items-center justify-start p-1.5 gap-2 border-brand-base bg-brand-surface-1 text-base font-medium text-gray-600 ${ className={`flex items-center justify-start gap-2 border-brand-base bg-brand-surface-1 p-1.5 text-base font-medium text-gray-600 ${
!isMonthlyView !isMonthlyView
? showWeekEnds ? showWeekEnds
? (index + 1) % 7 === 0 ? (index + 1) % 7 === 0
@ -480,5 +503,9 @@ export const CalendarView: React.FC<Props> = ({ addIssueToDate }) => {
</div> </div>
</div> </div>
</DragDropContext> </DragDropContext>
) : (
<div className="flex h-full w-full items-center justify-center">
<Spinner />
</div>
); );
}; };

View File

@ -137,12 +137,14 @@ export const IssuesFilterView: React.FC = () => {
<Popover.Panel className="absolute right-0 z-20 mt-1 w-screen max-w-xs transform overflow-hidden rounded-lg bg-brand-surface-2 p-3 shadow-lg"> <Popover.Panel className="absolute right-0 z-20 mt-1 w-screen max-w-xs transform overflow-hidden rounded-lg bg-brand-surface-2 p-3 shadow-lg">
<div className="relative divide-y-2 divide-brand-base"> <div className="relative divide-y-2 divide-brand-base">
<div className="space-y-4 pb-3 text-xs"> <div className="space-y-4 pb-3 text-xs">
{issueView !== "calendar" && (
<>
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<h4 className="text-brand-secondary">Group by</h4> <h4 className="text-brand-secondary">Group by</h4>
<CustomMenu <CustomMenu
label={ label={
GROUP_BY_OPTIONS.find((option) => option.key === groupByProperty)?.name ?? GROUP_BY_OPTIONS.find((option) => option.key === groupByProperty)
"Select" ?.name ?? "Select"
} }
width="lg" width="lg"
> >
@ -181,6 +183,8 @@ export const IssuesFilterView: React.FC = () => {
)} )}
</CustomMenu> </CustomMenu>
</div> </div>
</>
)}
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<h4 className="text-brand-secondary">Issue type</h4> <h4 className="text-brand-secondary">Issue type</h4>
<CustomMenu <CustomMenu
@ -204,6 +208,9 @@ export const IssuesFilterView: React.FC = () => {
))} ))}
</CustomMenu> </CustomMenu>
</div> </div>
{issueView !== "calendar" && (
<>
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<h4 className="text-brand-secondary">Show empty states</h4> <h4 className="text-brand-secondary">Show empty states</h4>
<button <button
@ -236,7 +243,10 @@ export const IssuesFilterView: React.FC = () => {
Set as default Set as default
</button> </button>
</div> </div>
</>
)}
</div> </div>
{issueView !== "calendar" && (
<div className="space-y-2 py-3"> <div className="space-y-2 py-3">
<h4 className="text-sm text-brand-secondary">Display Properties</h4> <h4 className="text-sm text-brand-secondary">Display Properties</h4>
<div className="flex flex-wrap items-center gap-2"> <div className="flex flex-wrap items-center gap-2">
@ -260,6 +270,7 @@ export const IssuesFilterView: React.FC = () => {
})} })}
</div> </div>
</div> </div>
)}
</div> </div>
</Popover.Panel> </Popover.Panel>
</Transition> </Transition>

View File

@ -396,7 +396,6 @@ export const IssuesView: React.FC<Props> = ({
handleClose={() => setTransferIssuesModal(false)} handleClose={() => setTransferIssuesModal(false)}
isOpen={transferIssuesModal} isOpen={transferIssuesModal}
/> />
{issueView !== "calendar" && (
<> <>
<div <div
className={`flex items-center justify-between gap-2 ${ className={`flex items-center justify-between gap-2 ${
@ -430,7 +429,7 @@ export const IssuesView: React.FC<Props> = ({
<div className={` ${issueView === "list" ? "mt-4" : "my-4"} border-t`} /> <div className={` ${issueView === "list" ? "mt-4" : "my-4"} border-t`} />
)} )}
</> </>
)}
<DragDropContext onDragEnd={handleOnDragEnd}> <DragDropContext onDragEnd={handleOnDragEnd}>
<StrictModeDroppable droppableId="trashBox"> <StrictModeDroppable droppableId="trashBox">
{(provided, snapshot) => ( {(provided, snapshot) => (

View File

@ -297,6 +297,14 @@ export const IssueViewContextProvider: React.FC<{ children: React.ReactNode }> =
}, },
}); });
} }
if (property === "calendar") {
dispatch({
type: "SET_GROUP_BY_PROPERTY",
payload: {
groupByProperty: null,
},
});
}
if (!workspaceSlug || !projectId) return; if (!workspaceSlug || !projectId) return;