forked from github/plane
feat: issue filters dropdown created (#441)
This commit is contained in:
parent
0117ccfca2
commit
bcd2ac1317
@ -8,5 +8,4 @@ export * from "./issues-view-filter";
|
||||
export * from "./issues-view";
|
||||
export * from "./link-modal";
|
||||
export * from "./not-authorized-view";
|
||||
export * from "./multi-level-select";
|
||||
export * from "./image-picker-popover";
|
||||
|
@ -2,6 +2,12 @@ import React from "react";
|
||||
|
||||
import { useRouter } from "next/router";
|
||||
|
||||
import useSWR from "swr";
|
||||
|
||||
// services
|
||||
import projectService from "services/project.service";
|
||||
import issuesService from "services/issues.service";
|
||||
import stateService from "services/state.service";
|
||||
// hooks
|
||||
import useIssuesProperties from "hooks/use-issue-properties";
|
||||
import useIssueView from "hooks/use-issue-view";
|
||||
@ -14,10 +20,14 @@ import { ChevronDownIcon, ListBulletIcon } from "@heroicons/react/24/outline";
|
||||
import { Squares2X2Icon } from "@heroicons/react/20/solid";
|
||||
// helpers
|
||||
import { replaceUnderscoreIfSnakeCase } from "helpers/string.helper";
|
||||
import { getStatesList } from "helpers/state.helper";
|
||||
// types
|
||||
import { IIssue, Properties } from "types";
|
||||
// common
|
||||
import { IIssue, IIssueLabels, Properties } from "types";
|
||||
// fetch-keys
|
||||
import { PROJECT_ISSUE_LABELS, PROJECT_MEMBERS, STATE_LIST } from "constants/fetch-keys";
|
||||
// constants
|
||||
import { GROUP_BY_OPTIONS, ORDER_BY_OPTIONS, FILTER_ISSUE_OPTIONS } from "constants/issue";
|
||||
import { PRIORITIES } from "constants/project";
|
||||
|
||||
type Props = {
|
||||
issues?: IIssue[];
|
||||
@ -46,6 +56,28 @@ export const IssuesFilterView: React.FC<Props> = ({ issues }) => {
|
||||
projectId as string
|
||||
);
|
||||
|
||||
const { data: states } = useSWR(
|
||||
workspaceSlug && projectId ? STATE_LIST(projectId as string) : null,
|
||||
workspaceSlug && projectId
|
||||
? () => stateService.getStates(workspaceSlug as string, projectId as string)
|
||||
: null
|
||||
);
|
||||
const statesList = getStatesList(states ?? {});
|
||||
|
||||
const { data: members } = useSWR(
|
||||
projectId ? PROJECT_MEMBERS(projectId as string) : null,
|
||||
workspaceSlug && projectId
|
||||
? () => projectService.projectMembers(workspaceSlug as string, projectId as string)
|
||||
: null
|
||||
);
|
||||
|
||||
const { data: issueLabels } = useSWR<IIssueLabels[]>(
|
||||
workspaceSlug && projectId ? PROJECT_ISSUE_LABELS(projectId as string) : null,
|
||||
workspaceSlug && projectId
|
||||
? () => issuesService.getIssueLabels(workspaceSlug as string, projectId as string)
|
||||
: null
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
{issues && issues.length > 0 && (
|
||||
@ -70,6 +102,42 @@ export const IssuesFilterView: React.FC<Props> = ({ issues }) => {
|
||||
<Squares2X2Icon className="h-4 w-4" />
|
||||
</button>
|
||||
</div>
|
||||
<CustomMenu
|
||||
label={
|
||||
<span className="flex items-center gap-2 rounded-md py-1 text-xs font-medium text-gray-500 hover:bg-gray-100 hover:text-gray-900 focus:outline-none">
|
||||
Filters
|
||||
</span>
|
||||
}
|
||||
>
|
||||
<h4 className="px-1 py-2 font-medium">Status</h4>
|
||||
{statesList?.map((state) => (
|
||||
<CustomMenu.MenuItem onClick={() => {}}>
|
||||
<>{state.name}</>
|
||||
</CustomMenu.MenuItem>
|
||||
))}
|
||||
<h4 className="px-1 py-2 font-medium">Members</h4>
|
||||
{members?.map((member) => (
|
||||
<CustomMenu.MenuItem onClick={() => {}}>
|
||||
<>
|
||||
{member.member.first_name && member.member.first_name !== ""
|
||||
? member.member.first_name + " " + member.member.last_name
|
||||
: member.member.email}
|
||||
</>
|
||||
</CustomMenu.MenuItem>
|
||||
))}
|
||||
<h4 className="px-1 py-2 font-medium">Labels</h4>
|
||||
{issueLabels?.map((label) => (
|
||||
<CustomMenu.MenuItem onClick={() => {}}>
|
||||
<>{label.name}</>
|
||||
</CustomMenu.MenuItem>
|
||||
))}
|
||||
<h4 className="px-1 py-2 font-medium">Priority</h4>
|
||||
{PRIORITIES?.map((priority) => (
|
||||
<CustomMenu.MenuItem onClick={() => {}}>
|
||||
<span className="capitalize">{priority ?? "None"}</span>
|
||||
</CustomMenu.MenuItem>
|
||||
))}
|
||||
</CustomMenu>
|
||||
<Popover className="relative">
|
||||
{({ open }) => (
|
||||
<>
|
||||
|
@ -11,6 +11,7 @@ export * from "./empty-space";
|
||||
export * from "./header-button";
|
||||
export * from "./loader";
|
||||
export * from "./multi-input";
|
||||
export * from "./multi-level-select";
|
||||
export * from "./outline-button";
|
||||
export * from "./progress-bar";
|
||||
export * from "./spinner";
|
||||
|
@ -1,7 +1,8 @@
|
||||
import React, { useState } from "react";
|
||||
|
||||
// headless ui
|
||||
import { Listbox, Transition } from "@headlessui/react";
|
||||
|
||||
// icons
|
||||
import { CheckIcon, ChevronUpDownIcon } from "@heroicons/react/20/solid";
|
||||
|
||||
type TSelectOption = {
|
||||
@ -23,9 +24,13 @@ type TMultipleSelectProps = {
|
||||
direction?: "left" | "right";
|
||||
};
|
||||
|
||||
export const MultiLevelSelect: React.FC<TMultipleSelectProps> = (props) => {
|
||||
const { options, selected, setSelected, label, direction = "right" } = props;
|
||||
|
||||
export const MultiLevelSelect: React.FC<TMultipleSelectProps> = ({
|
||||
options,
|
||||
selected,
|
||||
setSelected,
|
||||
label,
|
||||
direction = "right",
|
||||
}) => {
|
||||
const [openChildFor, setOpenChildFor] = useState<TSelectOption | null>(null);
|
||||
|
||||
return (
|
Loading…
Reference in New Issue
Block a user