Make multiple choice filters work
This commit is contained in:
parent
89fc6245ed
commit
6aadc05322
6 changed files with 101 additions and 28 deletions
12
src/misc.ts
12
src/misc.ts
|
@ -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`);
|
||||
}
|
||||
|
|
|
@ -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> &
|
||||
|
|
|
@ -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")}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}>;
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue