Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,18 @@ import { Dialog, Transition } from "@headlessui/react";
// hooks
import useIssuesView from "hooks/use-issues-view";
// components
import { DueDateFilterSelect } from "./due-date-filter-select";
import { DateFilterSelect } from "./date-filter-select";
// ui
import { PrimaryButton, SecondaryButton } from "components/ui";
// icons
import { XMarkIcon } from "@heroicons/react/20/solid";
// helpers
import { renderDateFormat, renderShortDateWithYearFormat } from "helpers/date-time.helper";
import { IIssueFilterOptions } from "types";

type Props = {
title: string;
field: keyof IIssueFilterOptions;
isOpen: boolean;
handleClose: () => void;
};
Expand All @@ -36,7 +39,7 @@ const defaultValues: TFormValues = {
date2: new Date(new Date().getFullYear(), new Date().getMonth() + 1, new Date().getDate()),
};

export const DueDateFilterModal: React.FC<Props> = ({ isOpen, handleClose }) => {
export const DateFilterModal: React.FC<Props> = ({ title, field, isOpen, handleClose }) => {
const { filters, setFilters } = useIssuesView();

const router = useRouter();
Expand All @@ -51,11 +54,11 @@ export const DueDateFilterModal: React.FC<Props> = ({ isOpen, handleClose }) =>

if (filterType === "range") {
setFilters(
{ target_date: [`${renderDateFormat(date1)};after`, `${renderDateFormat(date2)};before`] },
{ [field]: [`${renderDateFormat(date1)};after`, `${renderDateFormat(date2)};before`] },
!Boolean(viewId)
);
} else {
const filteredArray = filters?.target_date?.filter((item) => {
const filteredArray = (filters?.[field] as string[])?.filter((item) => {
if (item?.includes(filterType)) return false;

return true;
Expand All @@ -64,13 +67,13 @@ export const DueDateFilterModal: React.FC<Props> = ({ isOpen, handleClose }) =>
const filterOne = filteredArray && filteredArray?.length > 0 ? filteredArray[0] : null;
if (filterOne)
setFilters(
{ target_date: [filterOne, `${renderDateFormat(date1)};${filterType}`] },
{ [field]: [filterOne, `${renderDateFormat(date1)};${filterType}`] },
!Boolean(viewId)
);
else
setFilters(
{
target_date: [`${renderDateFormat(date1)};${filterType}`],
[field]: [`${renderDateFormat(date1)};${filterType}`],
},
!Boolean(viewId)
);
Expand Down Expand Up @@ -116,7 +119,7 @@ export const DueDateFilterModal: React.FC<Props> = ({ isOpen, handleClose }) =>
control={control}
name="filterType"
render={({ field: { value, onChange } }) => (
<DueDateFilterSelect value={value} onChange={onChange} />
<DateFilterSelect title={title} value={value} onChange={onChange} />
)}
/>
<XMarkIcon
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { CalendarBeforeIcon, CalendarAfterIcon, CalendarMonthIcon } from "compon
// fetch-keys

type Props = {
title: string;
value: string;
onChange: (value: string) => void;
};
Expand All @@ -19,29 +20,31 @@ type DueDate = {

const dueDateRange: DueDate[] = [
{
name: "Due date before",
name: "before",
value: "before",
icon: <CalendarBeforeIcon className="h-4 w-4 " />,
},
{
name: "Due date after",
name: "after",
value: "after",
icon: <CalendarAfterIcon className="h-4 w-4 " />,
},
{
name: "Due date range",
name: "range",
value: "range",
icon: <CalendarMonthIcon className="h-4 w-4 " />,
},
];

export const DueDateFilterSelect: React.FC<Props> = ({ value, onChange }) => (
export const DateFilterSelect: React.FC<Props> = ({ title, value, onChange }) => (
<CustomSelect
value={value}
label={
<div className="flex items-center gap-2 text-xs">
{dueDateRange.find((item) => item.value === value)?.icon}
<span>{dueDateRange.find((item) => item.value === value)?.name}</span>
<span>
{title} {dueDateRange.find((item) => item.value === value)?.name}
</span>
</div>
}
onChange={onChange}
Expand All @@ -50,7 +53,7 @@ export const DueDateFilterSelect: React.FC<Props> = ({ value, onChange }) => (
<CustomSelect.Option key={index} value={option.value}>
<>
<span>{option.icon}</span>
{option.name}
{title} {option.name}
</>
</CustomSelect.Option>
))}
Expand Down
28 changes: 28 additions & 0 deletions apps/app/components/core/filters/filters-list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,34 @@ export const FiltersList: React.FC<Props> = ({
</div>
);
})
: key === "start_date"
? filters.start_date?.map((date: string) => {
if (filters.start_date && filters.start_date.length <= 0) return null;

const splitDate = date.split(";");

return (
<div
key={date}
className="inline-flex items-center gap-x-1 rounded-full border border-custom-border-200 bg-custom-background-100 px-1 py-0.5"
>
<div className="h-1.5 w-1.5 rounded-full" />
<span className="capitalize">
{splitDate[1]} {renderShortDateWithYearFormat(splitDate[0])}
</span>
<span
className="cursor-pointer"
onClick={() =>
setFilters({
start_date: filters.start_date?.filter((d: any) => d !== date),
})
}
>
<XMarkIcon className="h-3 w-3" />
</span>
</div>
);
})
: key === "target_date"
? filters.target_date?.map((date: string) => {
if (filters.target_date && filters.target_date.length <= 0) return null;
Expand Down
4 changes: 2 additions & 2 deletions apps/app/components/core/filters/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export * from "./due-date-filter-modal";
export * from "./due-date-filter-select";
export * from "./date-filter-modal";
export * from "./date-filter-select";
export * from "./filters-list";
export * from "./issues-view-filter";
9 changes: 3 additions & 6 deletions apps/app/components/core/filters/issues-view-filter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -119,14 +119,11 @@ export const IssuesFilterView: React.FC = () => {
onSelect={(option) => {
const key = option.key as keyof typeof filters;

if (key === "target_date") {
const valueExists = checkIfArraysHaveSameElements(
filters.target_date ?? [],
option.value
);
if (key === "start_date" || key === "target_date") {
const valueExists = checkIfArraysHaveSameElements(filters[key] ?? [], option.value);

setFilters({
target_date: valueExists ? null : option.value,
[key]: valueExists ? null : option.value,
});
} else {
const valueExists = filters[key]?.includes(option.value);
Expand Down
1 change: 1 addition & 0 deletions apps/app/components/core/views/issues-view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -478,6 +478,7 @@ export const IssuesView: React.FC<Props> = ({
labels: null,
priority: null,
state: null,
start_date: null,
target_date: null,
type: null,
})
Expand Down
71 changes: 61 additions & 10 deletions apps/app/components/issues/my-issues/my-issues-select-filters.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import useSWR from "swr";
// services
import issuesService from "services/issues.service";
// components
import { DueDateFilterModal } from "components/core";
import { DateFilterModal } from "components/core";
// ui
import { MultiLevelDropdown } from "components/ui";
// icons
Expand All @@ -20,7 +20,7 @@ import { IIssueFilterOptions, IQuery } from "types";
import { WORKSPACE_LABELS } from "constants/fetch-keys";
// constants
import { GROUP_CHOICES, PRIORITIES } from "constants/project";
import { DUE_DATES } from "constants/due-dates";
import { DATE_FILTER_OPTIONS } from "constants/filters";

type Props = {
filters: Partial<IIssueFilterOptions> | IQuery;
Expand All @@ -35,7 +35,14 @@ export const MyIssuesSelectFilters: React.FC<Props> = ({
direction = "right",
height = "md",
}) => {
const [isDueDateFilterModalOpen, setIsDueDateFilterModalOpen] = useState(false);
const [isDateFilterModalOpen, setIsDateFilterModalOpen] = useState(false);
const [dateFilterType, setDateFilterType] = useState<{
title: string;
type: "start_date" | "target_date";
}>({
title: "",
type: "start_date",
});
const [fetchLabels, setFetchLabels] = useState(false);

const router = useRouter();
Expand All @@ -50,10 +57,12 @@ export const MyIssuesSelectFilters: React.FC<Props> = ({

return (
<>
{isDueDateFilterModalOpen && (
<DueDateFilterModal
isOpen={isDueDateFilterModalOpen}
handleClose={() => setIsDueDateFilterModalOpen(false)}
{isDateFilterModalOpen && (
<DateFilterModal
title={dateFilterType.title}
field={dateFilterType.type}
isOpen={isDateFilterModalOpen}
handleClose={() => setIsDateFilterModalOpen(false)}
/>
)}
<MultiLevelDropdown
Expand Down Expand Up @@ -131,13 +140,49 @@ export const MyIssuesSelectFilters: React.FC<Props> = ({
selected: filters?.labels?.includes(label.id),
})),
},
{
id: "start_date",
label: "Start date",
value: DATE_FILTER_OPTIONS,
hasChildren: true,
children: [
...(DATE_FILTER_OPTIONS?.map((option) => ({
id: option.name,
label: option.name,
value: {
key: "start_date",
value: option.value,
},
selected: checkIfArraysHaveSameElements(filters?.start_date ?? [], option.value),
})) ?? []),
{
id: "custom",
label: "Custom",
value: "custom",
element: (
<button
onClick={() => {
setIsDateFilterModalOpen(true);
setDateFilterType({
title: "Start date",
type: "start_date",
});
}}
className="w-full rounded px-1 py-1.5 text-left text-custom-text-200 hover:bg-custom-background-80"
>
Custom
</button>
),
},
],
},
{
id: "target_date",
label: "Due date",
value: DUE_DATES,
value: DATE_FILTER_OPTIONS,
hasChildren: true,
children: [
...(DUE_DATES?.map((option) => ({
...(DATE_FILTER_OPTIONS?.map((option) => ({
id: option.name,
label: option.name,
value: {
Expand All @@ -152,7 +197,13 @@ export const MyIssuesSelectFilters: React.FC<Props> = ({
value: "custom",
element: (
<button
onClick={() => setIsDueDateFilterModalOpen(true)}
onClick={() => {
setIsDateFilterModalOpen(true);
setDateFilterType({
title: "Due date",
type: "target_date",
});
}}
className="w-full rounded px-1 py-1.5 text-left text-custom-text-200 hover:bg-custom-background-80"
>
Custom
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,14 +89,11 @@ export const MyIssuesViewOptions: React.FC = () => {
onSelect={(option) => {
const key = option.key as keyof typeof filters;

if (key === "target_date") {
const valueExists = checkIfArraysHaveSameElements(
filters?.target_date ?? [],
option.value
);
if (key === "start_date" || key === "target_date") {
const valueExists = checkIfArraysHaveSameElements(filters?.[key] ?? [], option.value);

setFilters({
target_date: valueExists ? null : option.value,
[key]: valueExists ? null : option.value,
});
} else {
const valueExists = filters[key]?.includes(option.value);
Expand Down
1 change: 1 addition & 0 deletions apps/app/components/issues/my-issues/my-issues-view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,7 @@ export const MyIssuesView: React.FC<Props> = ({
labels: null,
priority: null,
state_group: null,
start_date: null,
target_date: null,
type: null,
})
Expand Down
9 changes: 3 additions & 6 deletions apps/app/components/profile/profile-issues-view-options.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -115,14 +115,11 @@ export const ProfileIssuesViewOptions: React.FC = () => {
onSelect={(option) => {
const key = option.key as keyof typeof filters;

if (key === "target_date") {
const valueExists = checkIfArraysHaveSameElements(
filters?.target_date ?? [],
option.value
);
if (key === "start_date" || key === "target_date") {
const valueExists = checkIfArraysHaveSameElements(filters?.[key] ?? [], option.value);

setFilters({
target_date: valueExists ? null : option.value,
[key]: valueExists ? null : option.value,
});
} else {
const valueExists = filters[key]?.includes(option.value);
Expand Down
1 change: 1 addition & 0 deletions apps/app/components/profile/profile-issues-view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,7 @@ export const ProfileIssuesView = () => {
labels: null,
priority: null,
state_group: null,
start_date: null,
target_date: null,
type: null,
})
Expand Down
8 changes: 5 additions & 3 deletions apps/app/components/views/form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ export const ViewForm: React.FC<Props> = ({
labels: null,
priority: null,
state: null,
start_date: null,
target_date: null,
type: null,
});
Expand Down Expand Up @@ -155,14 +156,15 @@ export const ViewForm: React.FC<Props> = ({
onSelect={(option) => {
const key = option.key as keyof typeof filters;

if (key === "target_date") {
if (key === "start_date" || key === "target_date") {
const valueExists = checkIfArraysHaveSameElements(
filters?.target_date ?? [],
filters?.[key] ?? [],
option.value
);

setValue("query", {
target_date: valueExists ? null : option.value,
...filters,
[key]: valueExists ? null : option.value,
} as IQuery);
} else {
if (!filters?.[key]?.includes(option.value))
Expand Down
Loading