diff --git a/src/staff/components/StaffListPage/StaffListPage.tsx b/src/staff/components/StaffListPage/StaffListPage.tsx index 6cd2d1211..8182657b2 100644 --- a/src/staff/components/StaffListPage/StaffListPage.tsx +++ b/src/staff/components/StaffListPage/StaffListPage.tsx @@ -6,21 +6,26 @@ import { FormattedMessage, useIntl } from "react-intl"; import AppHeader from "@saleor/components/AppHeader"; import { Container } from "@saleor/components/Container"; import PageHeader from "@saleor/components/PageHeader"; -import SearchBar from "@saleor/components/SearchBar"; +import FilterBar from "@saleor/components/FilterBar"; import { sectionNames } from "@saleor/intl"; import { ListProps, - SearchPageProps, + FilterPageProps, TabPageProps, SortPage } from "@saleor/types"; import { StaffListUrlSortField } from "@saleor/staff/urls"; +import { + StaffFilterKeys, + createFilterStructure +} from "@saleor/staff/views/StaffList/filter"; +import { StaffListFilterOpts } from "@saleor/staff/types"; import { StaffList_staffUsers_edges_node } from "../../types/StaffList"; import StaffList from "../StaffList/StaffList"; export interface StaffListPageProps extends ListProps, - SearchPageProps, + FilterPageProps, SortPage, TabPageProps { staffMembers: StaffList_staffUsers_edges_node[]; @@ -29,11 +34,14 @@ export interface StaffListPageProps } const StaffListPage: React.FC = ({ + currencySymbol, currentTab, + filterOpts, initialSearch, onAdd, onAll, onBack, + onFilterChange, onSearchChange, onTabChange, onTabDelete, @@ -43,6 +51,8 @@ const StaffListPage: React.FC = ({ }) => { const intl = useIntl(); + const structure = createFilterStructure(intl, filterOpts); + return ( @@ -57,18 +67,21 @@ const StaffListPage: React.FC = ({ - ; +} diff --git a/src/staff/urls.ts b/src/staff/urls.ts index 970299df9..35ce6c2a4 100644 --- a/src/staff/urls.ts +++ b/src/staff/urls.ts @@ -15,6 +15,7 @@ const staffSection = "/staff/"; export const staffListPath = staffSection; export enum StaffListUrlFiltersEnum { + status = "status", query = "query" } export type StaffListUrlFilters = Filters; diff --git a/src/staff/views/StaffList/StaffList.tsx b/src/staff/views/StaffList/StaffList.tsx index c4ccefadd..9dfa5be9c 100644 --- a/src/staff/views/StaffList/StaffList.tsx +++ b/src/staff/views/StaffList/StaffList.tsx @@ -23,6 +23,8 @@ import { ListViews } from "@saleor/types"; import { getSortParams } from "@saleor/utils/sort"; import createSortHandler from "@saleor/utils/handlers/sortHandler"; import createDialogActionHandlers from "@saleor/utils/handlers/dialogActionHandlers"; +import { IFilter } from "@saleor/components/Filter"; +import { getFilterQueryParams } from "@saleor/utils/filters"; import StaffAddMemberDialog, { FormData as AddStaffMemberForm } from "../../components/StaffAddMemberDialog"; @@ -33,7 +35,6 @@ import { StaffMemberAdd } from "../../types/StaffMemberAdd"; import { staffListUrl, StaffListUrlDialog, - StaffListUrlFilters, StaffListUrlQueryParams, staffMemberDetailsUrl } from "../../urls"; @@ -43,7 +44,10 @@ import { getActiveFilters, getFilterTabs, getFilterVariables, - saveFilterTab + saveFilterTab, + StaffFilterKeys, + getFilterQueryParam, + getFilterOpts } from "./filter"; import { getSortQueryVariables } from "./sort"; @@ -62,6 +66,7 @@ export const StaffList: React.FC = ({ params }) => { const shop = useShop(); const paginationState = createPaginationState(settings.rowNumber, params); + const currencySymbol = maybe(() => shop.defaultCurrency, "USD"); const queryVariables = React.useMemo( () => ({ ...paginationState, @@ -84,15 +89,32 @@ export const StaffList: React.FC = ({ params }) => { : 0 : parseInt(params.activeTab, 0); - const changeFilterField = (filter: StaffListUrlFilters) => + const changeFilters = (filter: IFilter) => navigate( staffListUrl({ - ...getActiveFilters(params), - ...filter, + ...params, + ...getFilterQueryParams(filter, getFilterQueryParam), activeTab: undefined }) ); + const resetFilters = () => + navigate( + staffListUrl({ + asc: params.asc, + sort: params.sort + }) + ); + + const handleSearchChange = (query: string) => + navigate( + staffListUrl({ + ...params, + activeTab: undefined, + query + }) + ); + const [openModal, closeModal] = createDialogActionHandlers< StaffListUrlDialog, StaffListUrlQueryParams @@ -159,10 +181,13 @@ export const StaffList: React.FC = ({ params }) => { return ( <> changeFilterField({ query })} - onAll={() => navigate(staffListUrl())} + onSearchChange={handleSearchChange} + onFilterChange={changeFilters} + onAll={resetFilters} onTabChange={handleTabChange} onTabDelete={() => openModal("delete-search")} onTabSave={() => openModal("save-search")} diff --git a/src/staff/views/StaffList/filter.ts b/src/staff/views/StaffList/filter.ts index 9223a0372..0adaddf51 100644 --- a/src/staff/views/StaffList/filter.ts +++ b/src/staff/views/StaffList/filter.ts @@ -1,4 +1,9 @@ -import { StaffUserInput } from "@saleor/types/globalTypes"; +import { IntlShape } from "react-intl"; + +import { StaffUserInput, StaffMemberStatus } from "@saleor/types/globalTypes"; +import { maybe, findValueInEnum } from "@saleor/misc"; +import { IFilter, IFilterElement } from "@saleor/components/Filter"; +import { createOptionsField } from "@saleor/utils/filters/fields"; import { createFilterTabUtils, createFilterUtils @@ -8,17 +13,83 @@ import { StaffListUrlFiltersEnum, StaffListUrlQueryParams } from "../../urls"; +import { StaffListFilterOpts } from "../../types"; +import messages from "./messages"; export const STAFF_FILTERS_KEY = "staffFilters"; +export enum StaffFilterKeys { + status = "status" +} + +export function getFilterOpts( + params: StaffListUrlFilters +): StaffListFilterOpts { + return { + status: { + active: maybe(() => params.status !== undefined, false), + value: maybe(() => findValueInEnum(params.status, StaffMemberStatus)) + } + }; +} + +export function createFilterStructure( + intl: IntlShape, + opts: StaffListFilterOpts +): IFilter { + return [ + { + ...createOptionsField( + StaffFilterKeys.status, + intl.formatMessage(messages.status), + [opts.status.value], + false, + [ + { + label: intl.formatMessage(messages.active), + value: StaffMemberStatus.ACTIVE + }, + { + label: intl.formatMessage(messages.deactivated), + value: StaffMemberStatus.DEACTIVATED + } + ] + ), + active: opts.status.active + } + ]; +} + export function getFilterVariables( params: StaffListUrlFilters ): StaffUserInput { return { - search: params.query + search: params.query, + status: params.status + ? findValueInEnum(params.status, StaffMemberStatus) + : null }; } +export function getFilterQueryParam( + filter: IFilterElement +): StaffListUrlFilters { + const { active, name, value } = filter; + + switch (name) { + case StaffFilterKeys.status: + if (!active) { + return { + status: undefined + }; + } + + return { + status: value[0] + }; + } +} + export const { deleteFilterTab, getFilterTabs, diff --git a/src/staff/views/StaffList/messages.ts b/src/staff/views/StaffList/messages.ts new file mode 100644 index 000000000..a6d6f38bb --- /dev/null +++ b/src/staff/views/StaffList/messages.ts @@ -0,0 +1,18 @@ +import { defineMessages } from "react-intl"; + +const messages = defineMessages({ + active: { + defaultMessage: "Active", + description: "staff member's account" + }, + deactivated: { + defaultMessage: "Deactivated", + description: "staff member's account" + }, + status: { + defaultMessage: "Status", + description: "staff member's account" + } +}); + +export default messages; diff --git a/src/storybook/stories/staff/StaffListPage.tsx b/src/storybook/stories/staff/StaffListPage.tsx index 1c3d8c1cc..2ec0552c1 100644 --- a/src/storybook/stories/staff/StaffListPage.tsx +++ b/src/storybook/stories/staff/StaffListPage.tsx @@ -2,11 +2,13 @@ import { storiesOf } from "@storybook/react"; import React from "react"; import { StaffListUrlSortField } from "@saleor/staff/urls"; +import { StaffMemberStatus } from "@saleor/types/globalTypes"; import { pageListProps, searchPageProps, tabPageProps, - sortPageProps + sortPageProps, + filterPageProps } from "../../../fixtures"; import StaffListPage, { StaffListPageProps @@ -19,6 +21,13 @@ const props: StaffListPageProps = { ...searchPageProps, ...sortPageProps, ...tabPageProps, + ...filterPageProps, + filterOpts: { + status: { + active: false, + value: StaffMemberStatus.ACTIVE + } + }, onAdd: undefined, onBack: () => undefined, sort: {