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;
}
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,
Dialog,
Filters,
FiltersWithMultipleValues,
Pagination,
SingleAction
} from "../types";
@ -16,11 +17,14 @@ export const orderListPath = orderSectionUrl;
export enum OrderListUrlFiltersEnum {
dateFrom = "dateFrom",
dateTo = "dateTo",
status = "status",
email = "email",
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 OrderListUrlQueryParams = BulkAction &
Dialog<OrderListUrlDialog> &

View file

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

View file

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

View file

@ -112,6 +112,9 @@ export type ActiveTab<TTab extends string = string> = Partial<{
export type Filters<TFilters extends string> = Partial<
Record<TFilters, string>
>;
export type FiltersWithMultipleValues<TFilters extends string> = Partial<
Record<TFilters, string | string[]>
>;
export type SingleAction = Partial<{
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 {
return Object.keys(params)
.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;