Make order filters work

This commit is contained in:
dominik-zeglen 2019-12-20 11:44:41 +01:00
parent aafa6b62dc
commit 32cdb56e6f
14 changed files with 208 additions and 589 deletions

View file

@ -26,18 +26,16 @@ const props: MultiAutocompleteSelectFieldProps = {
value: undefined
};
const Story: React.FC<
Partial<
MultiAutocompleteSelectFieldProps & {
enableLoadMore: boolean;
}
>
> = ({ allowCustomValues, enableLoadMore }) => {
const Story: React.FC<Partial<
MultiAutocompleteSelectFieldProps & {
enableLoadMore: boolean;
}
>> = ({ allowCustomValues, enableLoadMore }) => {
const { change, data: countries } = useMultiAutocomplete([suggestions[0]]);
return (
<ChoiceProvider choices={suggestions}>
{({ choices, fetchChoices, fetchMore, hasMore, loading }) => (
{({ choices, fetchChoices, onFetchMore, hasMore, loading }) => (
<MultiAutocompleteSelectField
{...props}
displayValues={countries}
@ -50,7 +48,7 @@ const Story: React.FC<
value={countries.map(country => country.value)}
loading={loading}
hasMore={enableLoadMore ? hasMore : false}
onFetchMore={enableLoadMore ? fetchMore : undefined}
onFetchMore={enableLoadMore ? onFetchMore : undefined}
allowCustomValues={allowCustomValues}
/>
)}

View file

@ -27,20 +27,18 @@ const props: SingleAutocompleteSelectFieldProps = {
value: suggestions[0].value
};
const Story: React.FC<
Partial<
SingleAutocompleteSelectFieldProps & {
enableLoadMore: boolean;
}
>
> = ({ allowCustomValues, emptyOption, enableLoadMore }) => {
const Story: React.FC<Partial<
SingleAutocompleteSelectFieldProps & {
enableLoadMore: boolean;
}
>> = ({ allowCustomValues, emptyOption, enableLoadMore }) => {
const [displayValue, setDisplayValue] = React.useState(suggestions[0].label);
return (
<Form initial={{ country: suggestions[0].value }}>
{({ change, data }) => (
<ChoiceProvider choices={suggestions}>
{({ choices, fetchChoices, fetchMore, hasMore, loading }) => {
{({ choices, fetchChoices, onFetchMore, hasMore, loading }) => {
const handleSelect = createSingleAutocompleteSelectHandler(
change,
setDisplayValue,
@ -58,7 +56,7 @@ const Story: React.FC<
onChange={handleSelect}
value={data.country}
hasMore={enableLoadMore ? hasMore : false}
onFetchMore={enableLoadMore ? fetchMore : undefined}
onFetchMore={enableLoadMore ? onFetchMore : undefined}
allowCustomValues={allowCustomValues}
emptyOption={emptyOption}
/>

View file

@ -115,7 +115,7 @@ export const transformPaymentStatus = (status: string, intl: IntlShape) => {
}
};
const orderStatusMessages = defineMessages({
export const orderStatusMessages = defineMessages({
cancelled: {
defaultMessage: "Cancelled",
description: "order status"

View file

@ -1,169 +0,0 @@
import moment from "moment-timezone";
import React from "react";
import { useIntl } from "react-intl";
import { DateContext } from "@saleor/components/Date/DateContext";
import { FieldType, IFilter } from "@saleor/components/Filter";
import FilterBar from "@saleor/components/FilterBar";
import TimezoneContext from "@saleor/components/Timezone";
import { FilterProps } from "../../../types";
import { OrderStatusFilter } from "../../../types/globalTypes";
type OrderListFilterProps = FilterProps<OrderFilterKeys>;
export enum OrderFilterKeys {
date = "date",
dateEqual = "dateEqual",
dateRange = "dateRange",
dateLastWeek = "dateLastWeek",
dateLastMonth = "dateLastMonth",
dateLastYear = "dateLastYear",
status = "status"
}
const OrderListFilter: React.FC<OrderListFilterProps> = props => {
const date = React.useContext(DateContext);
const tz = React.useContext(TimezoneContext);
const intl = useIntl();
const filterMenu: IFilter<OrderFilterKeys> = [
{
children: [
{
children: [],
data: {
fieldLabel: null,
type: FieldType.hidden,
value: (tz ? moment(date).tz(tz) : moment(date))
.subtract(7, "days")
.toISOString()
.split("T")[0] // Remove timezone
},
label: intl.formatMessage({
defaultMessage: "Last 7 Days"
}),
value: OrderFilterKeys.dateLastWeek
},
{
children: [],
data: {
fieldLabel: null,
type: FieldType.hidden,
value: (tz ? moment(date).tz(tz) : moment(date))
.subtract(30, "days")
.toISOString()
.split("T")[0] // Remove timezone
},
label: intl.formatMessage({
defaultMessage: "Last 30 Days"
}),
value: OrderFilterKeys.dateLastMonth
},
{
children: [],
data: {
fieldLabel: null,
type: FieldType.hidden,
value: (tz ? moment(date).tz(tz) : moment(date))
.subtract(1, "years")
.toISOString()
.split("T")[0] // Remove timezone
},
label: intl.formatMessage({
defaultMessage: "Last Year"
}),
value: OrderFilterKeys.dateLastYear
},
{
children: [],
data: {
additionalText: intl.formatMessage({
defaultMessage: "equals"
}),
fieldLabel: null,
type: FieldType.date
},
label: intl.formatMessage({
defaultMessage: "Specific Date"
}),
value: OrderFilterKeys.dateEqual
},
{
children: [],
data: {
fieldLabel: intl.formatMessage({
defaultMessage: "Range"
}),
type: FieldType.rangeDate
},
label: intl.formatMessage({
defaultMessage: "Range"
}),
value: OrderFilterKeys.dateRange
}
],
data: {
fieldLabel: intl.formatMessage({
defaultMessage: "Date"
}),
type: FieldType.select
},
label: intl.formatMessage({
defaultMessage: "Date"
}),
value: OrderFilterKeys.date
},
{
children: [],
data: {
additionalText: intl.formatMessage({
defaultMessage: "is set as",
description: "date is set as"
}),
fieldLabel: intl.formatMessage({
defaultMessage: "Status",
description: "order fulfillment status"
}),
options: [
{
label: intl.formatMessage({
defaultMessage: "Fulfilled",
description: "order fulfillment status"
}),
value: OrderStatusFilter.FULFILLED.toString()
},
{
label: intl.formatMessage({
defaultMessage: "Partially Fulfilled",
description: "order fulfillment status"
}),
value: OrderStatusFilter.PARTIALLY_FULFILLED.toString()
},
{
label: intl.formatMessage({
defaultMessage: "Unfulfilled",
description: "order fulfillment status"
}),
value: OrderStatusFilter.UNFULFILLED.toString()
},
{
label: intl.formatMessage({
defaultMessage: "Ready to Capture",
description: "order status"
}),
value: OrderStatusFilter.READY_TO_CAPTURE.toString()
}
],
type: FieldType.select
},
label: intl.formatMessage({
defaultMessage: "Order Status"
}),
value: OrderFilterKeys.status
}
];
return <FilterBar {...props} filterMenu={filterMenu} />;
};
OrderListFilter.displayName = "OrderListFilter";
export default OrderListFilter;

View file

@ -1,2 +0,0 @@
export { default } from "./OrderListFilter";
export * from "./OrderListFilter";

View file

@ -14,9 +14,13 @@ import {
SortPage
} from "@saleor/types";
import { OrderListUrlSortField } from "@saleor/orders/urls";
import {
OrderFilterKeys,
createFilterStructure
} from "@saleor/orders/views/OrderList/filters";
import FilterBar from "@saleor/components/FilterBar";
import { OrderList_orders_edges_node } from "../../types/OrderList";
import OrderList from "../OrderList";
import OrderListFilter, { OrderFilterKeys } from "../OrderListFilter";
export interface OrderListPageProps
extends PageListProps,
@ -29,13 +33,12 @@ export interface OrderListPageProps
const OrderListPage: React.FC<OrderListPageProps> = ({
currencySymbol,
currentTab,
filtersList,
initialSearch,
tabs,
onAdd,
onAll,
onSearchChange,
onFilterAdd,
onFilterChange,
onTabChange,
onTabDelete,
onTabSave,
@ -43,6 +46,8 @@ const OrderListPage: React.FC<OrderListPageProps> = ({
}) => {
const intl = useIntl();
const filterStructure = createFilterStructure(intl);
return (
<Container>
<PageHeader title={intl.formatMessage(sectionNames.orders)}>
@ -54,28 +59,25 @@ const OrderListPage: React.FC<OrderListPageProps> = ({
</Button>
</PageHeader>
<Card>
<OrderListFilter
allTabLabel={intl.formatMessage({
defaultMessage: "All Orders",
description: "tab name"
})}
<FilterBar
currencySymbol={currencySymbol}
currentTab={currentTab}
filterLabel={intl.formatMessage({
defaultMessage: "Select all orders where:"
})}
tabs={tabs}
filtersList={filtersList}
initialSearch={initialSearch}
searchPlaceholder={intl.formatMessage({
defaultMessage: "Search Orders..."
})}
onAll={onAll}
onFilterChange={onFilterChange}
onSearchChange={onSearchChange}
onFilterAdd={onFilterAdd}
onTabChange={onTabChange}
onTabDelete={onTabDelete}
onTabSave={onTabSave}
tabs={tabs}
allTabLabel={intl.formatMessage({
defaultMessage: "All Products",
description: "tab name"
})}
filterStructure={filterStructure}
searchPlaceholder={intl.formatMessage({
defaultMessage: "Search Products..."
})}
/>
<OrderList {...listProps} />
</Card>

View file

@ -17,8 +17,8 @@ const orderSectionUrl = "/orders";
export const orderListPath = orderSectionUrl;
export enum OrderListUrlFiltersEnum {
dateFrom = "dateFrom",
dateTo = "dateTo",
createdFrom = "createdFrom",
createdTo = "createdTo",
email = "email",
payment = "payment",
query = "query"

View file

@ -7,7 +7,6 @@ import SaveFilterTabDialog, {
SaveFilterTabDialogFormData
} from "@saleor/components/SaveFilterTabDialog";
import useBulkActions from "@saleor/hooks/useBulkActions";
import useDateLocalize from "@saleor/hooks/useDateLocalize";
import useListSettings from "@saleor/hooks/useListSettings";
import useNavigator from "@saleor/hooks/useNavigator";
import useNotifier from "@saleor/hooks/useNotifier";
@ -20,6 +19,7 @@ import { ListViews } from "@saleor/types";
import createSortHandler from "@saleor/utils/handlers/sortHandler";
import { getSortParams } from "@saleor/utils/sort";
import createDialogActionHandlers from "@saleor/utils/handlers/dialogActionHandlers";
import { IFilter } from "@saleor/components/Filter";
import OrderBulkCancelDialog from "../../components/OrderBulkCancelDialog";
import OrderListPage from "../../components/OrderListPage/OrderListPage";
import {
@ -38,13 +38,13 @@ import {
} from "../../urls";
import {
areFiltersApplied,
createFilter,
createFilterChips,
deleteFilterTab,
getActiveFilters,
getFilterTabs,
getFilterVariables,
saveFilterTab
saveFilterTab,
OrderFilterKeys,
createFilterQueryParams
} from "./filters";
import { getSortQueryVariables } from "./sort";
@ -53,7 +53,6 @@ interface OrderListProps {
}
export const OrderList: React.FC<OrderListProps> = ({ params }) => {
const formatDate = useDateLocalize();
const navigate = useNavigator();
const notify = useNotifier();
const paginate = usePaginator();
@ -90,20 +89,36 @@ export const OrderList: React.FC<OrderListProps> = ({ params }) => {
const changeFilters = (filters: OrderListUrlFilters) => {
reset();
navigate(orderListUrl(filters));
navigate(
orderListUrl({
...params,
...filters
})
);
};
const changeFilterField = (filter: OrderListUrlFilters) => {
const changeFilterField = (filter: IFilter<OrderFilterKeys>) => {
reset();
navigate(
orderListUrl({
...getActiveFilters(params),
...filter,
...params,
...createFilterQueryParams(filter),
activeTab: undefined
})
);
};
const handleSearchChange = (query: string) => {
reset();
navigate(
orderListUrl({
...params,
activeTab: undefined,
query
})
);
};
const [openModal, closeModal] = createDialogActionHandlers<
OrderListUrlDialog,
OrderListUrlQueryParams
@ -183,14 +198,6 @@ export const OrderList: React.FC<OrderListProps> = ({ params }) => {
<OrderListPage
currencySymbol={currencySymbol}
settings={settings}
filtersList={createFilterChips(
params,
{
formatDate
},
changeFilterField,
intl
)}
currentTab={currentTab}
disabled={loading}
orders={maybe(() => data.orders.edges.map(edge => edge.node))}
@ -221,10 +228,8 @@ export const OrderList: React.FC<OrderListProps> = ({ params }) => {
/>
</Button>
}
onSearchChange={query => changeFilterField({ query })}
onFilterAdd={data =>
changeFilterField(createFilter(params, data))
}
onSearchChange={handleSearchChange}
onFilterChange={filter => changeFilterField(filter)}
onTabSave={() => openModal("save-search")}
onTabDelete={() => openModal("delete-search")}
onTabChange={handleTabChange}

View file

@ -1,158 +1,17 @@
import { createIntl } from "react-intl";
import { OrderStatus } from "@saleor/types/globalTypes";
import { getFilterVariables } from "./filters";
import { OrderFilterKeys } from "@saleor/orders/components/OrderListFilter";
import { OrderStatus, OrderStatusFilter } from "@saleor/types/globalTypes";
import { createFilter, createFilterChips, getFilterVariables } from "./filters";
test("Get filter variables", () => {
const filter = getFilterVariables({
createdFrom: "2019-09-01",
createdTo: "2019-09-10",
email: "email@example.com",
query: "24",
status: [
OrderStatus.FULFILLED.toString(),
OrderStatus.PARTIALLY_FULFILLED.toString()
]
});
const mockIntl = createIntl({
locale: "en"
});
describe("Create filter object", () => {
it("with date", () => {
const filter = createFilter(
{},
{
name: OrderFilterKeys.dateEqual,
value: "2019-09-01"
}
);
expect(filter).toMatchSnapshot();
});
it("with date range", () => {
const filter = createFilter(
{},
{
name: OrderFilterKeys.dateRange,
value: ["2019-09-01", "2019-09-10"]
}
);
expect(filter).toMatchSnapshot();
});
it("with date last week", () => {
const filter = createFilter(
{},
{
name: OrderFilterKeys.dateLastWeek,
value: "2019-09-01"
}
);
expect(filter).toMatchSnapshot();
});
it("with date last month", () => {
const filter = createFilter(
{},
{
name: OrderFilterKeys.dateLastMonth,
value: "2019-09-01"
}
);
expect(filter).toMatchSnapshot();
});
it("with date last year", () => {
const filter = createFilter(
{},
{
name: OrderFilterKeys.dateLastYear,
value: "2019-09-01"
}
);
expect(filter).toMatchSnapshot();
});
it("with fulfillment status", () => {
const filter = createFilter(
{},
{
name: OrderFilterKeys.status,
value: OrderStatusFilter.PARTIALLY_FULFILLED
}
);
expect(filter).toMatchSnapshot();
});
it("with multiple values", () => {
const filter = createFilter(
{
status: [OrderStatusFilter.FULFILLED]
},
{
name: OrderFilterKeys.status,
value: OrderStatusFilter.PARTIALLY_FULFILLED
}
);
expect(filter).toMatchSnapshot();
});
it("with multiple deduped values", () => {
const filter = createFilter(
{
status: [OrderStatusFilter.FULFILLED]
},
{
name: OrderFilterKeys.status,
value: OrderStatusFilter.FULFILLED
}
);
expect(filter).toMatchSnapshot();
});
});
test("Crate filter chips", () => {
const chips = createFilterChips(
{
dateFrom: "2019-09-01",
dateTo: "2019-09-10",
email: "email@example.com",
status: [OrderStatus.FULFILLED, OrderStatus.PARTIALLY_FULFILLED]
},
{
formatDate: date => date
},
jest.fn(),
mockIntl as any
);
expect(chips).toMatchSnapshot();
});
describe("Get filter variables", () => {
it("from single status value", () => {
const filter = getFilterVariables({
dateFrom: "2019-09-01",
dateTo: "2019-09-10",
email: "email@example.com",
query: "24",
status: OrderStatus.FULFILLED.toString()
});
expect(filter).toMatchSnapshot();
});
it("from multiple status value", () => {
const filter = getFilterVariables({
dateFrom: "2019-09-01",
dateTo: "2019-09-10",
email: "email@example.com",
query: "24",
status: [
OrderStatus.FULFILLED.toString(),
OrderStatus.PARTIALLY_FULFILLED.toString()
]
});
expect(filter).toMatchSnapshot();
});
expect(filter).toMatchSnapshot();
});

View file

@ -1,78 +1,92 @@
import { defineMessages, IntlShape } from "react-intl";
import { 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 { findInEnum, maybe, orderStatusMessages } from "@saleor/misc";
import {
createDateField,
createOptionsField
} from "@saleor/utils/filters/fields";
import { IFilter, IFilterElement } from "../../../components/Filter";
import {
OrderFilterInput,
OrderStatusFilter
OrderStatusFilter,
OrderStatus
} from "../../../types/globalTypes";
import {
arrayOrUndefined,
arrayOrValue,
createFilterTabUtils,
createFilterUtils,
dedupeFilter,
valueOrFirst
dedupeFilter
} from "../../../utils/filters";
import { OrderFilterKeys } from "../../components/OrderListFilter";
import {
OrderListUrlFilters,
OrderListUrlFiltersEnum,
OrderListUrlFiltersWithMultipleValuesEnum,
OrderListUrlQueryParams
} from "../../urls";
import messages from "./messages";
export const ORDER_FILTERS_KEY = "orderFilters";
const filterMessages = defineMessages({
dateFrom: {
defaultMessage: "Date from {date}",
description: "filter by date"
},
dateIs: {
defaultMessage: "Date is {date}",
description: "filter by date"
},
dateTo: {
defaultMessage: "Date to {date}",
description: "filter by date"
},
fulfilled: {
defaultMessage: "Fulfilled",
description: "order status"
},
partiallyFulfilled: {
defaultMessage: "Partially Fulfilled",
description: "order status"
},
readyToCapture: {
defaultMessage: "Ready to Capture",
description: "order status"
},
unfulfilled: {
defaultMessage: "Unfulfilled",
description: "order status"
}
});
export enum OrderFilterKeys {
created = "created",
status = "status"
}
function getStatusLabel(status: string, intl: IntlShape): string {
switch (status) {
case OrderStatusFilter.FULFILLED.toString():
return intl.formatMessage(filterMessages.fulfilled);
case OrderStatusFilter.PARTIALLY_FULFILLED.toString():
return intl.formatMessage(filterMessages.partiallyFulfilled);
case OrderStatusFilter.UNFULFILLED.toString():
return intl.formatMessage(filterMessages.unfulfilled);
case OrderStatusFilter.READY_TO_CAPTURE.toString():
return intl.formatMessage(filterMessages.readyToCapture);
}
return "";
export function createFilterStructure(
intl: IntlShape,
params: OrderListUrlFilters
): IFilter<OrderFilterKeys> {
return [
{
...createDateField(
OrderFilterKeys.created,
intl.formatMessage(messages.placed),
{
max: maybe(() => params.createdTo, ""),
min: maybe(() => params.createdFrom, "")
}
),
active: maybe(
() =>
[params.createdFrom, params.createdTo].some(
field => field !== undefined
),
false
)
},
{
...createOptionsField(
OrderFilterKeys.status,
intl.formatMessage(messages.status),
maybe(
() =>
dedupeFilter(
params.status.map(status => findInEnum(status, OrderStatusFilter))
),
[]
),
true,
[
{
label: intl.formatMessage(orderStatusMessages.cancelled),
value: OrderStatusFilter.CANCELED
},
{
label: intl.formatMessage(orderStatusMessages.fulfilled),
value: OrderStatusFilter.FULFILLED
},
{
label: intl.formatMessage(orderStatusMessages.partiallyFulfilled),
value: OrderStatusFilter.PARTIALLY_FULFILLED
},
{
label: intl.formatMessage(orderStatusMessages.unfulfilled),
value: OrderStatusFilter.UNFULFILLED
}
]
),
active: maybe(() => params.status !== undefined, false)
}
];
}
export function getFilterVariables(
@ -80,159 +94,47 @@ export function getFilterVariables(
): OrderFilterInput {
return {
created: {
gte: params.dateFrom,
lte: params.dateTo
gte: params.createdFrom,
lte: params.createdTo
},
customer: params.email,
search: params.query,
status: Array.isArray(params.status)
? params.status.map(status => findInEnum(status, OrderStatusFilter))
: params.status
? [findInEnum(params.status, OrderStatusFilter)]
: undefined
status: maybe(() =>
params.status.map(status => findInEnum(status, OrderStatusFilter))
)
};
}
export function createFilter(
filter: OrderListUrlFilters,
data: FilterContentSubmitData<OrderFilterKeys>
export function getFilterQueryParam(
filter: IFilterElement<OrderFilterKeys>
): OrderListUrlFilters {
const { name: filterName, value } = data;
if (filterName === OrderFilterKeys.dateEqual) {
return {
dateFrom: valueOrFirst(value),
dateTo: valueOrFirst(value)
};
} else if (filterName === OrderFilterKeys.dateRange) {
return {
dateFrom: value[0],
dateTo: value[1]
};
} else if (
[
OrderFilterKeys.dateLastWeek,
OrderFilterKeys.dateLastMonth,
OrderFilterKeys.dateLastYear
].includes(filterName)
) {
return {
dateFrom: valueOrFirst(value),
dateTo: undefined
};
} else if (filterName === OrderFilterKeys.status) {
return {
status: dedupeFilter(
filter.status
? [...(filter.status as string[]), valueOrFirst(value)]
: arrayOrValue(value)
)
};
}
}
const { active, name, value } = filter;
interface OrderListChipFormatData {
formatDate: (date: string) => string;
}
export function createFilterChips(
filters: OrderListUrlFilters,
formatData: OrderListChipFormatData,
onFilterDelete: (filters: OrderListUrlFilters) => void,
intl: IntlShape
): Filter[] {
let filterChips: Filter[] = [];
if (active) {
switch (name) {
case OrderFilterKeys.created:
return {
createdFrom: value[0],
createdTo: value[1]
};
if (!!filters.dateFrom || !!filters.dateTo) {
if (filters.dateFrom === filters.dateTo) {
filterChips = [
...filterChips,
{
label: intl.formatMessage(filterMessages.dateIs, {
date: formatData.formatDate(filters.dateFrom)
}),
onClick: () =>
onFilterDelete({
...filters,
dateFrom: undefined,
dateTo: undefined
})
}
];
} else {
if (!!filters.dateFrom) {
filterChips = [
...filterChips,
{
label: intl.formatMessage(filterMessages.dateFrom, {
date: formatData.formatDate(filters.dateFrom)
}),
onClick: () =>
onFilterDelete({
...filters,
dateFrom: undefined
})
}
];
}
if (!!filters.dateTo) {
filterChips = [
...filterChips,
{
label: intl.formatMessage(filterMessages.dateTo, {
date: formatData.formatDate(filters.dateTo)
}),
onClick: () =>
onFilterDelete({
...filters,
dateTo: undefined
})
}
];
}
case OrderFilterKeys.status:
return {
status: value.map(val => findInEnum(val, OrderStatus))
};
}
}
if (!!filters.email) {
filterChips = [
...filterChips,
{
label: filters.email,
onClick: () =>
onFilterDelete({
...filters,
email: undefined
})
}
];
}
if (!!filters.status) {
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;
}
export function createFilterQueryParams(
filter: IFilter<OrderFilterKeys>
): OrderListUrlFilters {
return filter.reduce(
(acc, filterField) => ({
...acc,
...getFilterQueryParam(filterField)
}),
{}
);
}
export const {

View file

@ -0,0 +1,29 @@
import { defineMessages } from "react-intl";
const messages = defineMessages({
fulfilled: {
defaultMessage: "Fulfilled",
description: "order status"
},
partiallyFulfilled: {
defaultMessage: "Partially Fulfilled",
description: "order status"
},
placed: {
defaultMessage: "Placed",
description: "order"
},
readyToCapture: {
defaultMessage: "Ready to Capture",
description: "order status"
},
status: {
defaultMessage: "Order Status"
},
unfulfilled: {
defaultMessage: "Unfulfilled",
description: "order status"
}
});
export default messages;

View file

@ -161,9 +161,6 @@ export const ProductListPage: React.FC<ProductListPageProps> = props => {
description: "tab name"
})}
filterStructure={filterStructure}
filterLabel={intl.formatMessage({
defaultMessage: "Select all products where:"
})}
searchPlaceholder={intl.formatMessage({
defaultMessage: "Search Products..."
})}

View file

@ -13,7 +13,7 @@ import Decorator from "../../Decorator";
const props: FilterContentProps = {
currencySymbol: "USD",
filters: [
createPriceField("price", "Price", "USD", {
createPriceField("price", "Price", {
max: "100.00",
min: "20.00"
}),

View file

@ -136,7 +136,7 @@ export type Filters<TFilters extends string> = Partial<
Record<TFilters, string>
>;
export type FiltersWithMultipleValues<TFilters extends string> = Partial<
Record<TFilters, string | string[]>
Record<TFilters, string[]>
>;
export type SingleAction = Partial<{
id: string;