From a0ae569a681c4602b8f28b0f444823074330c53a Mon Sep 17 00:00:00 2001 From: Aaryan Khandelwal <65252264+aaryan610@users.noreply.github.com> Date: Wed, 21 Jun 2023 17:32:56 +0530 Subject: [PATCH] chore: show inbox applied filters list (#1334) --- .../app/components/inbox/filters-dropdown.tsx | 14 +- apps/app/components/inbox/filters-list.tsx | 126 ++++++++++++++++++ apps/app/components/inbox/index.ts | 1 + .../components/inbox/issues-list-sidebar.tsx | 9 +- apps/app/constants/inbox.ts | 34 ++++- apps/app/contexts/inbox-view-context.tsx | 36 ++++- apps/app/contexts/issue-view.context.tsx | 2 +- apps/app/hooks/use-inbox-view.tsx | 5 +- .../projects/[projectId]/inbox/[inboxId].tsx | 2 +- 9 files changed, 206 insertions(+), 23 deletions(-) create mode 100644 apps/app/components/inbox/filters-list.tsx diff --git a/apps/app/components/inbox/filters-dropdown.tsx b/apps/app/components/inbox/filters-dropdown.tsx index 938e4fc01..b567baed0 100644 --- a/apps/app/components/inbox/filters-dropdown.tsx +++ b/apps/app/components/inbox/filters-dropdown.tsx @@ -6,7 +6,7 @@ import { getPriorityIcon } from "components/icons"; import { IInboxFilterOptions } from "types"; // constants import { PRIORITIES } from "constants/project"; -import { STATUS } from "constants/inbox"; +import { INBOX_STATUS } from "constants/inbox"; type Props = { filters: Partial; @@ -45,16 +45,16 @@ export const FiltersDropdown: React.FC = ({ filters, onSelect, direction, { id: "inbox_status", label: "Status", - value: Object.values(STATUS), + value: INBOX_STATUS.map((status) => status.value), children: [ - ...Object.keys(STATUS).map((status) => ({ - id: status, - label: status, + ...INBOX_STATUS.map((status) => ({ + id: status.key, + label: status.label, value: { key: "inbox_status", - value: STATUS[status], + value: status.value, }, - selected: filters?.inbox_status?.includes(STATUS[status]), + selected: filters?.inbox_status?.includes(status.value), })), ], }, diff --git a/apps/app/components/inbox/filters-list.tsx b/apps/app/components/inbox/filters-list.tsx new file mode 100644 index 000000000..aa8213b2f --- /dev/null +++ b/apps/app/components/inbox/filters-list.tsx @@ -0,0 +1,126 @@ +// hooks +import useInboxView from "hooks/use-inbox-view"; +// icons +import { XMarkIcon } from "@heroicons/react/24/outline"; +import { getPriorityIcon } from "components/icons"; +// helpers +import { replaceUnderscoreIfSnakeCase } from "helpers/string.helper"; +// constants +import { INBOX_STATUS } from "constants/inbox"; + +export const InboxFiltersList = () => { + const { filters, setFilters, clearAllFilters, filtersLength } = useInboxView(); + + if (filtersLength <= 0) return <>; + + return ( +
+ {Object.keys(filters).map((key) => { + const filterKey = key as keyof typeof filters; + + if (filters[filterKey] !== null) + return ( +
+ + {replaceUnderscoreIfSnakeCase(key)}: + + {filters[filterKey] === null || (filters[filterKey]?.length ?? 0) <= 0 ? ( + None + ) : ( +
+ {filterKey === "priority" ? ( +
+ {filters.priority?.map((priority) => ( +
+ {getPriorityIcon(priority)} + +
+ ))} + +
+ ) : filterKey === "inbox_status" ? ( +
+ {filters.inbox_status?.map((status) => ( +
+ {INBOX_STATUS.find((s) => s.value === status)?.label} + +
+ ))} + +
+ ) : ( + (filters[filterKey] as any)?.join(", ") + )} +
+ )} +
+ ); + })} + +
+ ); +}; diff --git a/apps/app/components/inbox/index.ts b/apps/app/components/inbox/index.ts index 3f66790bc..7cdd8ee9d 100644 --- a/apps/app/components/inbox/index.ts +++ b/apps/app/components/inbox/index.ts @@ -1,6 +1,7 @@ export * from "./decline-issue-modal"; export * from "./delete-issue-modal"; export * from "./filters-dropdown"; +export * from "./filters-list"; export * from "./inbox-action-headers"; export * from "./inbox-issue-card"; export * from "./inbox-main-content"; diff --git a/apps/app/components/inbox/issues-list-sidebar.tsx b/apps/app/components/inbox/issues-list-sidebar.tsx index 02181c02a..9f5c85db1 100644 --- a/apps/app/components/inbox/issues-list-sidebar.tsx +++ b/apps/app/components/inbox/issues-list-sidebar.tsx @@ -3,7 +3,7 @@ import { useRouter } from "next/router"; // hooks import useInboxView from "hooks/use-inbox-view"; // components -import { InboxIssueCard } from "components/inbox"; +import { InboxIssueCard, InboxFiltersList } from "components/inbox"; // ui import { Loader } from "components/ui"; @@ -14,10 +14,11 @@ export const IssuesListSidebar = () => { const { issues: inboxIssues } = useInboxView(); return ( - <> +
+ {inboxIssues ? ( inboxIssues.length > 0 ? ( -
+
{inboxIssues.map((issue) => ( { )} - +
); }; diff --git a/apps/app/constants/inbox.ts b/apps/app/constants/inbox.ts index b5731fb89..9bbe8230a 100644 --- a/apps/app/constants/inbox.ts +++ b/apps/app/constants/inbox.ts @@ -1,9 +1,29 @@ -export const STATUS: { [key: string]: number } = { - Pending: -2, - Declined: -1, - Snoozed: 0, - Accepted: 1, - Duplicate: 2, -}; +export const INBOX_STATUS = [ + { + key: "pending", + label: "Pending", + value: -2, + }, + { + key: "declined", + label: "Declined", + value: -1, + }, + { + key: "snoozed", + label: "Snoozed", + value: 0, + }, + { + key: "accepted", + label: "Accepted", + value: 1, + }, + { + key: "duplicate", + label: "Duplicate", + value: 2, + }, +]; export const INBOX_ISSUE_SOURCE = "in-app"; diff --git a/apps/app/contexts/inbox-view-context.tsx b/apps/app/contexts/inbox-view-context.tsx index ff3bebc72..f6201fbb9 100644 --- a/apps/app/contexts/inbox-view-context.tsx +++ b/apps/app/contexts/inbox-view-context.tsx @@ -26,6 +26,7 @@ type ReducerActionType = { type ContextType = InboxViewProps & { setFilters: (filters: Partial) => void; + clearAllFilters: () => void; }; type StateType = { @@ -53,7 +54,7 @@ export const reducer: ReducerFunctionType = (state, action) => { ...state, filters: { ...state.filters, - ...payload, + ...payload?.filters, }, }; @@ -140,6 +141,38 @@ export const InboxViewContextProvider: React.FC<{ children: React.ReactNode }> = [workspaceSlug, projectId, inboxId, mutateInboxDetails, state] ); + const clearAllFilters = useCallback(() => { + dispatch({ + type: "SET_FILTERS", + payload: { + filters: { ...initialState.filters }, + }, + }); + + if (!workspaceSlug || !projectId || !inboxId) return; + + const newViewProps = { + ...state, + filters: { ...initialState.filters }, + }; + + mutateInboxDetails((prevData) => { + if (!prevData) return prevData; + + return { + ...prevData, + view_props: newViewProps, + }; + }, false); + + saveDataToServer( + workspaceSlug.toString(), + projectId.toString(), + inboxId.toString(), + newViewProps + ); + }, [inboxId, mutateInboxDetails, projectId, state, workspaceSlug]); + useEffect(() => { dispatch({ type: "REHYDRATE_THEME", @@ -154,6 +187,7 @@ export const InboxViewContextProvider: React.FC<{ children: React.ReactNode }> = value={{ filters: state.filters, setFilters, + clearAllFilters, }} > diff --git a/apps/app/contexts/issue-view.context.tsx b/apps/app/contexts/issue-view.context.tsx index 6053b8b15..d2a4496c9 100644 --- a/apps/app/contexts/issue-view.context.tsx +++ b/apps/app/contexts/issue-view.context.tsx @@ -168,7 +168,7 @@ export const reducer: ReducerFunctionType = (state, action) => { ...state, filters: { ...state.filters, - ...payload, + ...payload?.filters, }, }; diff --git a/apps/app/hooks/use-inbox-view.tsx b/apps/app/hooks/use-inbox-view.tsx index 4ce6f4859..a5dedc380 100644 --- a/apps/app/hooks/use-inbox-view.tsx +++ b/apps/app/hooks/use-inbox-view.tsx @@ -14,7 +14,7 @@ import { IInboxQueryParams } from "types"; import { INBOX_ISSUES } from "constants/fetch-keys"; const useInboxView = () => { - const { filters, setFilters } = useContext(inboxViewContext); + const { filters, setFilters, clearAllFilters } = useContext(inboxViewContext); const router = useRouter(); const { workspaceSlug, projectId, inboxId } = router.query; @@ -50,10 +50,11 @@ const useInboxView = () => { return { filters, setFilters, + clearAllFilters, + filtersLength, params, issues: inboxIssues, mutate: mutateInboxIssues, - filtersLength, } as const; }; diff --git a/apps/app/pages/[workspaceSlug]/projects/[projectId]/inbox/[inboxId].tsx b/apps/app/pages/[workspaceSlug]/projects/[projectId]/inbox/[inboxId].tsx index c47e79d06..c08925c0f 100644 --- a/apps/app/pages/[workspaceSlug]/projects/[projectId]/inbox/[inboxId].tsx +++ b/apps/app/pages/[workspaceSlug]/projects/[projectId]/inbox/[inboxId].tsx @@ -222,7 +222,7 @@ const ProjectInbox: NextPage = () => { }} onDelete={() => setDeleteIssueModal(true)} /> -
+
{inboxIssueId ? (