Make multiple choice filters work

This commit is contained in:
dominik-zeglen 2019-09-05 15:05:12 +02:00
parent 89fc6245ed
commit 6aadc05322
6 changed files with 101 additions and 28 deletions

View file

@ -466,3 +466,15 @@ export function generateCode(charNum: number) {
} }
return result; return result;
} }
export function findInEnum<TEnum extends object>(
needle: string,
haystack: TEnum
) {
const match = Object.keys(haystack).find(key => key === needle);
if (!!match) {
return haystack[needle as keyof TEnum];
}
throw new Error(`Key ${needle} not found in enum`);
}

View file

@ -6,6 +6,7 @@ import {
BulkAction, BulkAction,
Dialog, Dialog,
Filters, Filters,
FiltersWithMultipleValues,
Pagination, Pagination,
SingleAction SingleAction
} from "../types"; } from "../types";
@ -16,11 +17,14 @@ export const orderListPath = orderSectionUrl;
export enum OrderListUrlFiltersEnum { export enum OrderListUrlFiltersEnum {
dateFrom = "dateFrom", dateFrom = "dateFrom",
dateTo = "dateTo", dateTo = "dateTo",
status = "status",
email = "email", email = "email",
payment = "payment" payment = "payment"
} }
export type OrderListUrlFilters = Filters<OrderListUrlFiltersEnum>; export enum OrderListUrlFiltersWithMultipleValuesEnum {
status = "status"
}
export type OrderListUrlFilters = Filters<OrderListUrlFiltersEnum> &
FiltersWithMultipleValues<OrderListUrlFiltersWithMultipleValuesEnum>;
export type OrderListUrlDialog = "cancel" | "save-search" | "delete-search"; export type OrderListUrlDialog = "cancel" | "save-search" | "delete-search";
export type OrderListUrlQueryParams = BulkAction & export type OrderListUrlQueryParams = BulkAction &
Dialog<OrderListUrlDialog> & Dialog<OrderListUrlDialog> &

View file

@ -229,8 +229,8 @@ export const OrderList: React.StatelessComponent<OrderListProps> = ({
</Button> </Button>
} }
onSearchChange={email => changeFilterField({ email })} onSearchChange={email => changeFilterField({ email })}
onFilterAdd={filter => onFilterAdd={data =>
changeFilterField(createFilter(filter)) changeFilterField(createFilter(params, data))
} }
onFilterSave={() => openModal("save-search")} onFilterSave={() => openModal("save-search")}
onFilterDelete={() => openModal("delete-search")} onFilterDelete={() => openModal("delete-search")}

View file

@ -1,5 +1,7 @@
import { defineMessages, IntlShape } from "react-intl"; import { defineMessages, IntlShape } from "react-intl";
import { findInEnum } from "@saleor/misc";
import { removeAtIndex } from "@saleor/utils/lists";
import { FilterContentSubmitData } from "../../../components/Filter"; import { FilterContentSubmitData } from "../../../components/Filter";
import { Filter } from "../../../components/TableFilter"; import { Filter } from "../../../components/TableFilter";
import { import {
@ -7,8 +9,12 @@ import {
OrderStatusFilter OrderStatusFilter
} from "../../../types/globalTypes"; } from "../../../types/globalTypes";
import { import {
arrayOrUndefined,
arrayOrValue,
createFilterTabUtils, createFilterTabUtils,
createFilterUtils createFilterUtils,
dedupeFilter,
valueOrFirst
} from "../../../utils/filters"; } from "../../../utils/filters";
import { OrderFilterKeys } from "../../components/OrderListFilter"; import { OrderFilterKeys } from "../../components/OrderListFilter";
import { import {
@ -70,22 +76,25 @@ export function getFilterVariables(
lte: params.dateTo lte: params.dateTo
}, },
customer: params.email, customer: params.email,
status: OrderStatusFilter[params.status] status: Array.isArray(params.status)
? params.status.map(status => findInEnum(status, OrderStatusFilter))
: params.status
? [findInEnum(params.status, OrderStatusFilter)]
: undefined
}; };
} }
export function createFilter( export function createFilter(
filter: FilterContentSubmitData filter: OrderListUrlFilters,
data: FilterContentSubmitData
): OrderListUrlFilters { ): OrderListUrlFilters {
const filterName = filter.name; const { name: filterName, value } = data;
if (filterName === OrderFilterKeys.dateEqual.toString()) { if (filterName === OrderFilterKeys.dateEqual.toString()) {
const value = filter.value as string;
return { return {
dateFrom: value, dateFrom: valueOrFirst(value),
dateTo: value dateTo: valueOrFirst(value)
}; };
} else if (filterName === OrderFilterKeys.dateRange.toString()) { } else if (filterName === OrderFilterKeys.dateRange.toString()) {
const { value } = filter;
return { return {
dateFrom: value[0], dateFrom: value[0],
dateTo: value[1] dateTo: value[1]
@ -99,15 +108,17 @@ export function createFilter(
.map(value => value.toString()) .map(value => value.toString())
.includes(filterName) .includes(filterName)
) { ) {
const { value } = filter;
return { return {
dateFrom: value as string, dateFrom: valueOrFirst(value),
dateTo: undefined dateTo: undefined
}; };
} else if (filterName === OrderFilterKeys.fulfillment.toString()) { } else if (filterName === OrderFilterKeys.fulfillment.toString()) {
const { value } = filter;
return { return {
status: value as string status: dedupeFilter(
filter.status
? [...(filter.status as string[]), valueOrFirst(value)]
: arrayOrValue(value)
)
}; };
} }
} }
@ -175,8 +186,18 @@ export function createFilterChips(
} }
if (!!filters.status) { if (!!filters.status) {
filterChips = [ const statusFilterChips = Array.isArray(filters.status)
...filterChips, ? filters.status.map((status, statusIndex) => ({
label: getStatusLabel(status, intl),
onClick: () =>
onFilterDelete({
...filters,
status: arrayOrUndefined(
removeAtIndex(filters.status as string[], statusIndex)
)
})
}))
: [
{ {
label: getStatusLabel(filters.status, intl), label: getStatusLabel(filters.status, intl),
onClick: () => onClick: () =>
@ -186,6 +207,8 @@ export function createFilterChips(
}) })
} }
]; ];
filterChips = [...filterChips, ...statusFilterChips];
} }
return filterChips; return filterChips;

View file

@ -112,6 +112,9 @@ export type ActiveTab<TTab extends string = string> = Partial<{
export type Filters<TFilters extends string> = Partial< export type Filters<TFilters extends string> = Partial<
Record<TFilters, string> Record<TFilters, string>
>; >;
export type FiltersWithMultipleValues<TFilters extends string> = Partial<
Record<TFilters, string | string[]>
>;
export type SingleAction = Partial<{ export type SingleAction = Partial<{
id: string; id: string;
}>; }>;

View file

@ -1,4 +1,7 @@
function createFilterUtils<TQueryParams, TFilters>(filters: object) { function createFilterUtils<
TQueryParams extends object,
TFilters extends object
>(filters: object) {
function getActiveFilters(params: TQueryParams): TFilters { function getActiveFilters(params: TQueryParams): TFilters {
return Object.keys(params) return Object.keys(params)
.filter(key => Object.keys(filters).includes(key)) .filter(key => Object.keys(filters).includes(key))
@ -21,4 +24,32 @@ function createFilterUtils<TQueryParams, TFilters>(filters: object) {
}; };
} }
export function valueOrFirst<T>(value: T | T[]): T {
if (Array.isArray(value)) {
return value[0];
}
return value;
}
export function arrayOrValue<T>(value: T | T[]): T[] {
if (Array.isArray(value)) {
return value;
}
return [value];
}
export function arrayOrUndefined<T>(array: T[]): T[] | undefined {
if (array.length === 0) {
return undefined;
}
return array;
}
export function dedupeFilter<T>(array: T[]): T[] {
return Array.from(new Set(array));
}
export default createFilterUtils; export default createFilterUtils;