Add search to sales
This commit is contained in:
parent
41e64fe5e8
commit
a18ff0fedc
9 changed files with 335 additions and 131 deletions
|
@ -1,4 +1,3 @@
|
||||||
import Card from "@material-ui/core/Card";
|
|
||||||
import {
|
import {
|
||||||
createStyles,
|
createStyles,
|
||||||
Theme,
|
Theme,
|
||||||
|
@ -83,124 +82,119 @@ const SaleList = withStyles(styles, {
|
||||||
toggleAll,
|
toggleAll,
|
||||||
toolbar
|
toolbar
|
||||||
}: SaleListProps & WithStyles<typeof styles>) => (
|
}: SaleListProps & WithStyles<typeof styles>) => (
|
||||||
<Card>
|
<Table>
|
||||||
<Table>
|
<TableHead
|
||||||
<TableHead
|
colSpan={numberOfColumns}
|
||||||
colSpan={numberOfColumns}
|
selected={selected}
|
||||||
selected={selected}
|
disabled={disabled}
|
||||||
disabled={disabled}
|
items={sales}
|
||||||
items={sales}
|
toggleAll={toggleAll}
|
||||||
toggleAll={toggleAll}
|
toolbar={toolbar}
|
||||||
toolbar={toolbar}
|
>
|
||||||
>
|
<TableCell className={classes.colName}>
|
||||||
<TableCell className={classes.colName}>
|
<FormattedMessage defaultMessage="Name" description="sale name" />
|
||||||
<FormattedMessage defaultMessage="Name" description="sale name" />
|
</TableCell>
|
||||||
</TableCell>
|
<TableCell className={classes.colStart}>
|
||||||
<TableCell className={classes.colStart}>
|
<FormattedMessage
|
||||||
<FormattedMessage
|
defaultMessage="Starts"
|
||||||
defaultMessage="Starts"
|
description="sale start date"
|
||||||
description="sale start date"
|
/>
|
||||||
/>
|
</TableCell>
|
||||||
</TableCell>
|
<TableCell className={classes.colEnd}>
|
||||||
<TableCell className={classes.colEnd}>
|
<FormattedMessage defaultMessage="Ends" description="sale end date" />
|
||||||
<FormattedMessage
|
</TableCell>
|
||||||
defaultMessage="Ends"
|
<TableCell className={classes.colValue}>
|
||||||
description="sale end date"
|
<FormattedMessage defaultMessage="Value" description="sale value" />
|
||||||
/>
|
</TableCell>
|
||||||
</TableCell>
|
</TableHead>
|
||||||
<TableCell className={classes.colValue}>
|
<TableFooter>
|
||||||
<FormattedMessage defaultMessage="Value" description="sale value" />
|
<TableRow>
|
||||||
</TableCell>
|
<TablePagination
|
||||||
</TableHead>
|
colSpan={numberOfColumns}
|
||||||
<TableFooter>
|
settings={settings}
|
||||||
<TableRow>
|
hasNextPage={pageInfo && !disabled ? pageInfo.hasNextPage : false}
|
||||||
<TablePagination
|
onNextPage={onNextPage}
|
||||||
colSpan={numberOfColumns}
|
onUpdateListSettings={onUpdateListSettings}
|
||||||
settings={settings}
|
hasPreviousPage={
|
||||||
hasNextPage={pageInfo && !disabled ? pageInfo.hasNextPage : false}
|
pageInfo && !disabled ? pageInfo.hasPreviousPage : false
|
||||||
onNextPage={onNextPage}
|
}
|
||||||
onUpdateListSettings={onUpdateListSettings}
|
onPreviousPage={onPreviousPage}
|
||||||
hasPreviousPage={
|
/>
|
||||||
pageInfo && !disabled ? pageInfo.hasPreviousPage : false
|
</TableRow>
|
||||||
}
|
</TableFooter>
|
||||||
onPreviousPage={onPreviousPage}
|
<TableBody>
|
||||||
/>
|
{renderCollection(
|
||||||
</TableRow>
|
sales,
|
||||||
</TableFooter>
|
sale => {
|
||||||
<TableBody>
|
const isSelected = sale ? isChecked(sale.id) : false;
|
||||||
{renderCollection(
|
|
||||||
sales,
|
|
||||||
sale => {
|
|
||||||
const isSelected = sale ? isChecked(sale.id) : false;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TableRow
|
<TableRow
|
||||||
className={!!sale ? classes.tableRow : undefined}
|
className={!!sale ? classes.tableRow : undefined}
|
||||||
hover={!!sale}
|
hover={!!sale}
|
||||||
key={sale ? sale.id : "skeleton"}
|
key={sale ? sale.id : "skeleton"}
|
||||||
|
onClick={sale ? onRowClick(sale.id) : undefined}
|
||||||
|
selected={isSelected}
|
||||||
|
>
|
||||||
|
<TableCell padding="checkbox">
|
||||||
|
<Checkbox
|
||||||
|
checked={isSelected}
|
||||||
|
disabled={disabled}
|
||||||
|
disableClickPropagation
|
||||||
|
onChange={() => toggle(sale.id)}
|
||||||
|
/>
|
||||||
|
</TableCell>
|
||||||
|
<TableCell className={classes.colName}>
|
||||||
|
{maybe<React.ReactNode>(() => sale.name, <Skeleton />)}
|
||||||
|
</TableCell>
|
||||||
|
<TableCell className={classes.colStart}>
|
||||||
|
{sale && sale.startDate ? (
|
||||||
|
<Date date={sale.startDate} />
|
||||||
|
) : (
|
||||||
|
<Skeleton />
|
||||||
|
)}
|
||||||
|
</TableCell>
|
||||||
|
<TableCell className={classes.colEnd}>
|
||||||
|
{sale && sale.endDate ? (
|
||||||
|
<Date date={sale.endDate} />
|
||||||
|
) : sale && sale.endDate === null ? (
|
||||||
|
"-"
|
||||||
|
) : (
|
||||||
|
<Skeleton />
|
||||||
|
)}
|
||||||
|
</TableCell>
|
||||||
|
<TableCell
|
||||||
|
className={classes.colValue}
|
||||||
onClick={sale ? onRowClick(sale.id) : undefined}
|
onClick={sale ? onRowClick(sale.id) : undefined}
|
||||||
selected={isSelected}
|
|
||||||
>
|
>
|
||||||
<TableCell padding="checkbox">
|
{sale && sale.type && sale.value ? (
|
||||||
<Checkbox
|
sale.type === SaleType.FIXED ? (
|
||||||
checked={isSelected}
|
<Money
|
||||||
disabled={disabled}
|
money={{
|
||||||
disableClickPropagation
|
amount: sale.value,
|
||||||
onChange={() => toggle(sale.id)}
|
currency: defaultCurrency
|
||||||
/>
|
}}
|
||||||
</TableCell>
|
/>
|
||||||
<TableCell className={classes.colName}>
|
|
||||||
{maybe<React.ReactNode>(() => sale.name, <Skeleton />)}
|
|
||||||
</TableCell>
|
|
||||||
<TableCell className={classes.colStart}>
|
|
||||||
{sale && sale.startDate ? (
|
|
||||||
<Date date={sale.startDate} />
|
|
||||||
) : (
|
) : (
|
||||||
<Skeleton />
|
<Percent amount={sale.value} />
|
||||||
)}
|
)
|
||||||
</TableCell>
|
) : (
|
||||||
<TableCell className={classes.colEnd}>
|
<Skeleton />
|
||||||
{sale && sale.endDate ? (
|
)}
|
||||||
<Date date={sale.endDate} />
|
|
||||||
) : sale && sale.endDate === null ? (
|
|
||||||
"-"
|
|
||||||
) : (
|
|
||||||
<Skeleton />
|
|
||||||
)}
|
|
||||||
</TableCell>
|
|
||||||
<TableCell
|
|
||||||
className={classes.colValue}
|
|
||||||
onClick={sale ? onRowClick(sale.id) : undefined}
|
|
||||||
>
|
|
||||||
{sale && sale.type && sale.value ? (
|
|
||||||
sale.type === SaleType.FIXED ? (
|
|
||||||
<Money
|
|
||||||
money={{
|
|
||||||
amount: sale.value,
|
|
||||||
currency: defaultCurrency
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
) : (
|
|
||||||
<Percent amount={sale.value} />
|
|
||||||
)
|
|
||||||
) : (
|
|
||||||
<Skeleton />
|
|
||||||
)}
|
|
||||||
</TableCell>
|
|
||||||
</TableRow>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
() => (
|
|
||||||
<TableRow>
|
|
||||||
<TableCell colSpan={numberOfColumns}>
|
|
||||||
<FormattedMessage defaultMessage="No sales found" />
|
|
||||||
</TableCell>
|
</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
)
|
);
|
||||||
)}
|
},
|
||||||
</TableBody>
|
() => (
|
||||||
</Table>
|
<TableRow>
|
||||||
</Card>
|
<TableCell colSpan={numberOfColumns}>
|
||||||
|
<FormattedMessage defaultMessage="No sales found" />
|
||||||
|
</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
)
|
||||||
|
)}
|
||||||
|
</TableBody>
|
||||||
|
</Table>
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
SaleList.displayName = "SaleList";
|
SaleList.displayName = "SaleList";
|
||||||
|
|
|
@ -1,22 +1,40 @@
|
||||||
import Button from "@material-ui/core/Button";
|
import Button from "@material-ui/core/Button";
|
||||||
|
import Card from "@material-ui/core/Card";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { FormattedMessage, useIntl } from "react-intl";
|
import { FormattedMessage, useIntl } from "react-intl";
|
||||||
|
|
||||||
import Container from "@saleor/components/Container";
|
import Container from "@saleor/components/Container";
|
||||||
import PageHeader from "@saleor/components/PageHeader";
|
import PageHeader from "@saleor/components/PageHeader";
|
||||||
|
import SearchBar from "@saleor/components/SearchBar";
|
||||||
import { sectionNames } from "@saleor/intl";
|
import { sectionNames } from "@saleor/intl";
|
||||||
import { ListActions, PageListProps } from "@saleor/types";
|
import {
|
||||||
|
ListActions,
|
||||||
|
PageListProps,
|
||||||
|
SearchPageProps,
|
||||||
|
TabPageProps
|
||||||
|
} from "@saleor/types";
|
||||||
import { SaleList_sales_edges_node } from "../../types/SaleList";
|
import { SaleList_sales_edges_node } from "../../types/SaleList";
|
||||||
import SaleList from "../SaleList";
|
import SaleList from "../SaleList";
|
||||||
|
|
||||||
export interface SaleListPageProps extends PageListProps, ListActions {
|
export interface SaleListPageProps
|
||||||
|
extends PageListProps,
|
||||||
|
ListActions,
|
||||||
|
SearchPageProps,
|
||||||
|
TabPageProps {
|
||||||
defaultCurrency: string;
|
defaultCurrency: string;
|
||||||
sales: SaleList_sales_edges_node[];
|
sales: SaleList_sales_edges_node[];
|
||||||
}
|
}
|
||||||
|
|
||||||
const SaleListPage: React.StatelessComponent<SaleListPageProps> = ({
|
const SaleListPage: React.StatelessComponent<SaleListPageProps> = ({
|
||||||
|
currentTab,
|
||||||
|
initialSearch,
|
||||||
onAdd,
|
onAdd,
|
||||||
|
onAll,
|
||||||
|
onSearchChange,
|
||||||
|
onTabChange,
|
||||||
|
onTabDelete,
|
||||||
|
onTabSave,
|
||||||
|
tabs,
|
||||||
...listProps
|
...listProps
|
||||||
}) => {
|
}) => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
|
@ -28,7 +46,22 @@ const SaleListPage: React.StatelessComponent<SaleListPageProps> = ({
|
||||||
<FormattedMessage defaultMessage="Create Sale" description="button" />
|
<FormattedMessage defaultMessage="Create Sale" description="button" />
|
||||||
</Button>
|
</Button>
|
||||||
</PageHeader>
|
</PageHeader>
|
||||||
<SaleList {...listProps} />
|
<Card>
|
||||||
|
<SearchBar
|
||||||
|
currentTab={currentTab}
|
||||||
|
initialSearch={initialSearch}
|
||||||
|
searchPlaceholder={intl.formatMessage({
|
||||||
|
defaultMessage: "Search Sale"
|
||||||
|
})}
|
||||||
|
tabs={tabs}
|
||||||
|
onAll={onAll}
|
||||||
|
onSearchChange={onSearchChange}
|
||||||
|
onTabChange={onTabChange}
|
||||||
|
onTabDelete={onTabDelete}
|
||||||
|
onTabSave={onTabSave}
|
||||||
|
/>
|
||||||
|
<SaleList {...listProps} />
|
||||||
|
</Card>
|
||||||
</Container>
|
</Container>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -166,8 +166,20 @@ export const voucherDetailsFragment = gql`
|
||||||
export const saleList = gql`
|
export const saleList = gql`
|
||||||
${pageInfoFragment}
|
${pageInfoFragment}
|
||||||
${saleFragment}
|
${saleFragment}
|
||||||
query SaleList($after: String, $before: String, $first: Int, $last: Int) {
|
query SaleList(
|
||||||
sales(after: $after, before: $before, first: $first, last: $last) {
|
$after: String
|
||||||
|
$before: String
|
||||||
|
$first: Int
|
||||||
|
$last: Int
|
||||||
|
$filter: SaleFilterInput
|
||||||
|
) {
|
||||||
|
sales(
|
||||||
|
after: $after
|
||||||
|
before: $before
|
||||||
|
first: $first
|
||||||
|
last: $last
|
||||||
|
filter: $filter
|
||||||
|
) {
|
||||||
edges {
|
edges {
|
||||||
node {
|
node {
|
||||||
...SaleFragment
|
...SaleFragment
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
import { SaleType } from "./../../types/globalTypes";
|
import { SaleFilterInput, SaleType } from "./../../types/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL query operation: SaleList
|
// GraphQL query operation: SaleList
|
||||||
|
@ -46,4 +46,5 @@ export interface SaleListVariables {
|
||||||
before?: string | null;
|
before?: string | null;
|
||||||
first?: number | null;
|
first?: number | null;
|
||||||
last?: number | null;
|
last?: number | null;
|
||||||
|
filter?: SaleFilterInput | null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,14 @@
|
||||||
import { stringify as stringifyQs } from "qs";
|
import { stringify as stringifyQs } from "qs";
|
||||||
import urlJoin from "url-join";
|
import urlJoin from "url-join";
|
||||||
|
|
||||||
import { ActiveTab, BulkAction, Dialog, Pagination } from "../types";
|
import {
|
||||||
|
ActiveTab,
|
||||||
|
BulkAction,
|
||||||
|
Dialog,
|
||||||
|
Filters,
|
||||||
|
Pagination,
|
||||||
|
TabActionDialog
|
||||||
|
} from "../types";
|
||||||
import { SaleDetailsPageTab } from "./components/SaleDetailsPage";
|
import { SaleDetailsPageTab } from "./components/SaleDetailsPage";
|
||||||
import { VoucherDetailsPageTab } from "./components/VoucherDetailsPage";
|
import { VoucherDetailsPageTab } from "./components/VoucherDetailsPage";
|
||||||
|
|
||||||
|
@ -9,10 +16,16 @@ export const discountSection = "/discounts/";
|
||||||
|
|
||||||
export const saleSection = urlJoin(discountSection, "sales");
|
export const saleSection = urlJoin(discountSection, "sales");
|
||||||
export const saleListPath = saleSection;
|
export const saleListPath = saleSection;
|
||||||
export type SaleListUrlDialog = "remove";
|
export enum SaleListUrlFiltersEnum {
|
||||||
export type SaleListUrlQueryParams = BulkAction &
|
query = "query"
|
||||||
|
}
|
||||||
|
export type SaleListUrlFilters = Filters<SaleListUrlFiltersEnum>;
|
||||||
|
export type SaleListUrlDialog = "remove" | TabActionDialog;
|
||||||
|
export type SaleListUrlQueryParams = ActiveTab &
|
||||||
|
BulkAction &
|
||||||
Dialog<SaleListUrlDialog> &
|
Dialog<SaleListUrlDialog> &
|
||||||
Pagination;
|
Pagination &
|
||||||
|
SaleListUrlFilters;
|
||||||
export const saleListUrl = (params?: SaleListUrlQueryParams) =>
|
export const saleListUrl = (params?: SaleListUrlQueryParams) =>
|
||||||
saleListPath + "?" + stringifyQs(params);
|
saleListPath + "?" + stringifyQs(params);
|
||||||
export const salePath = (id: string) => urlJoin(saleSection, id);
|
export const salePath = (id: string) => urlJoin(saleSection, id);
|
||||||
|
|
|
@ -5,6 +5,10 @@ import React from "react";
|
||||||
import { FormattedMessage, useIntl } from "react-intl";
|
import { FormattedMessage, useIntl } from "react-intl";
|
||||||
|
|
||||||
import ActionDialog from "@saleor/components/ActionDialog";
|
import ActionDialog from "@saleor/components/ActionDialog";
|
||||||
|
import DeleteFilterTabDialog from "@saleor/components/DeleteFilterTabDialog";
|
||||||
|
import SaveFilterTabDialog, {
|
||||||
|
SaveFilterTabDialogFormData
|
||||||
|
} from "@saleor/components/SaveFilterTabDialog";
|
||||||
import { WindowTitle } from "@saleor/components/WindowTitle";
|
import { WindowTitle } from "@saleor/components/WindowTitle";
|
||||||
import useBulkActions from "@saleor/hooks/useBulkActions";
|
import useBulkActions from "@saleor/hooks/useBulkActions";
|
||||||
import useListSettings from "@saleor/hooks/useListSettings";
|
import useListSettings from "@saleor/hooks/useListSettings";
|
||||||
|
@ -17,16 +21,26 @@ import useShop from "@saleor/hooks/useShop";
|
||||||
import { commonMessages, sectionNames } from "@saleor/intl";
|
import { commonMessages, sectionNames } from "@saleor/intl";
|
||||||
import { getMutationState, maybe } from "@saleor/misc";
|
import { getMutationState, maybe } from "@saleor/misc";
|
||||||
import { ListViews } from "@saleor/types";
|
import { ListViews } from "@saleor/types";
|
||||||
import SaleListPage from "../components/SaleListPage";
|
import SaleListPage from "../../components/SaleListPage";
|
||||||
import { TypedSaleBulkDelete } from "../mutations";
|
import { TypedSaleBulkDelete } from "../../mutations";
|
||||||
import { TypedSaleList } from "../queries";
|
import { TypedSaleList } from "../../queries";
|
||||||
import { SaleBulkDelete } from "../types/SaleBulkDelete";
|
import { SaleBulkDelete } from "../../types/SaleBulkDelete";
|
||||||
import {
|
import {
|
||||||
saleAddUrl,
|
saleAddUrl,
|
||||||
saleListUrl,
|
saleListUrl,
|
||||||
|
SaleListUrlDialog,
|
||||||
|
SaleListUrlFilters,
|
||||||
SaleListUrlQueryParams,
|
SaleListUrlQueryParams,
|
||||||
saleUrl
|
saleUrl
|
||||||
} from "../urls";
|
} from "../../urls";
|
||||||
|
import {
|
||||||
|
areFiltersApplied,
|
||||||
|
deleteFilterTab,
|
||||||
|
getActiveFilters,
|
||||||
|
getFilterTabs,
|
||||||
|
getFilterVariables,
|
||||||
|
saveFilterTab
|
||||||
|
} from "./filter";
|
||||||
|
|
||||||
interface SaleListProps {
|
interface SaleListProps {
|
||||||
params: SaleListUrlQueryParams;
|
params: SaleListUrlQueryParams;
|
||||||
|
@ -47,13 +61,78 @@ export const SaleList: React.StatelessComponent<SaleListProps> = ({
|
||||||
);
|
);
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
|
|
||||||
const closeModal = () => navigate(saleListUrl(), true);
|
const tabs = getFilterTabs();
|
||||||
|
|
||||||
|
const currentTab =
|
||||||
|
params.activeTab === undefined
|
||||||
|
? areFiltersApplied(params)
|
||||||
|
? tabs.length + 1
|
||||||
|
: 0
|
||||||
|
: parseInt(params.activeTab, 0);
|
||||||
|
|
||||||
|
const changeFilterField = (filter: SaleListUrlFilters) => {
|
||||||
|
reset();
|
||||||
|
navigate(
|
||||||
|
saleListUrl({
|
||||||
|
...getActiveFilters(params),
|
||||||
|
...filter,
|
||||||
|
activeTab: undefined
|
||||||
|
})
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const closeModal = () =>
|
||||||
|
navigate(
|
||||||
|
saleListUrl({
|
||||||
|
...params,
|
||||||
|
action: undefined,
|
||||||
|
ids: undefined
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
const openModal = (action: SaleListUrlDialog, ids?: string[]) =>
|
||||||
|
navigate(
|
||||||
|
saleListUrl({
|
||||||
|
...params,
|
||||||
|
action,
|
||||||
|
ids
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleTabChange = (tab: number) => {
|
||||||
|
reset();
|
||||||
|
navigate(
|
||||||
|
saleListUrl({
|
||||||
|
activeTab: tab.toString(),
|
||||||
|
...getFilterTabs()[tab - 1].data
|
||||||
|
})
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleTabDelete = () => {
|
||||||
|
deleteFilterTab(currentTab);
|
||||||
|
reset();
|
||||||
|
navigate(saleListUrl());
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleTabSave = (data: SaveFilterTabDialogFormData) => {
|
||||||
|
saveFilterTab(data.name, getActiveFilters(params));
|
||||||
|
handleTabChange(tabs.length + 1);
|
||||||
|
};
|
||||||
|
|
||||||
const paginationState = createPaginationState(settings.rowNumber, params);
|
const paginationState = createPaginationState(settings.rowNumber, params);
|
||||||
|
const queryVariables = React.useMemo(
|
||||||
|
() => ({
|
||||||
|
...paginationState,
|
||||||
|
filter: getFilterVariables(params)
|
||||||
|
}),
|
||||||
|
[params]
|
||||||
|
);
|
||||||
|
|
||||||
const canOpenBulkActionDialog = maybe(() => params.ids.length > 0);
|
const canOpenBulkActionDialog = maybe(() => params.ids.length > 0);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TypedSaleList displayLoader variables={paginationState}>
|
<TypedSaleList displayLoader variables={queryVariables}>
|
||||||
{({ data, loading, refetch }) => {
|
{({ data, loading, refetch }) => {
|
||||||
const { loadNextPage, loadPreviousPage, pageInfo } = paginate(
|
const { loadNextPage, loadPreviousPage, pageInfo } = paginate(
|
||||||
maybe(() => data.sales.pageInfo),
|
maybe(() => data.sales.pageInfo),
|
||||||
|
@ -91,6 +170,14 @@ export const SaleList: React.StatelessComponent<SaleListProps> = ({
|
||||||
<>
|
<>
|
||||||
<WindowTitle title={intl.formatMessage(sectionNames.sales)} />
|
<WindowTitle title={intl.formatMessage(sectionNames.sales)} />
|
||||||
<SaleListPage
|
<SaleListPage
|
||||||
|
currentTab={currentTab}
|
||||||
|
initialSearch={params.query || ""}
|
||||||
|
onSearchChange={query => changeFilterField({ query })}
|
||||||
|
onAll={() => navigate(saleListUrl())}
|
||||||
|
onTabChange={handleTabChange}
|
||||||
|
onTabDelete={() => openModal("delete-search")}
|
||||||
|
onTabSave={() => openModal("save-search")}
|
||||||
|
tabs={tabs.map(tab => tab.name)}
|
||||||
defaultCurrency={maybe(() => shop.defaultCurrency)}
|
defaultCurrency={maybe(() => shop.defaultCurrency)}
|
||||||
sales={maybe(() => data.sales.edges.map(edge => edge.node))}
|
sales={maybe(() => data.sales.edges.map(edge => edge.node))}
|
||||||
settings={settings}
|
settings={settings}
|
||||||
|
@ -150,6 +237,19 @@ export const SaleList: React.StatelessComponent<SaleListProps> = ({
|
||||||
</DialogContentText>
|
</DialogContentText>
|
||||||
)}
|
)}
|
||||||
</ActionDialog>
|
</ActionDialog>
|
||||||
|
<SaveFilterTabDialog
|
||||||
|
open={params.action === "save-search"}
|
||||||
|
confirmButtonState="default"
|
||||||
|
onClose={closeModal}
|
||||||
|
onSubmit={handleTabSave}
|
||||||
|
/>
|
||||||
|
<DeleteFilterTabDialog
|
||||||
|
open={params.action === "delete-search"}
|
||||||
|
confirmButtonState="default"
|
||||||
|
onClose={closeModal}
|
||||||
|
onSubmit={handleTabDelete}
|
||||||
|
tabName={maybe(() => tabs[currentTab - 1].name, "...")}
|
||||||
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}}
|
}}
|
31
src/discounts/views/SaleList/filter.ts
Normal file
31
src/discounts/views/SaleList/filter.ts
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
import { SaleFilterInput } from "@saleor/types/globalTypes";
|
||||||
|
import {
|
||||||
|
createFilterTabUtils,
|
||||||
|
createFilterUtils
|
||||||
|
} from "../../../utils/filters";
|
||||||
|
import {
|
||||||
|
SaleListUrlFilters,
|
||||||
|
SaleListUrlFiltersEnum,
|
||||||
|
SaleListUrlQueryParams
|
||||||
|
} from "../../urls";
|
||||||
|
|
||||||
|
export const SALE_FILTERS_KEY = "saleFilters";
|
||||||
|
|
||||||
|
export function getFilterVariables(
|
||||||
|
params: SaleListUrlFilters
|
||||||
|
): SaleFilterInput {
|
||||||
|
return {
|
||||||
|
search: params.query
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export const {
|
||||||
|
deleteFilterTab,
|
||||||
|
getFilterTabs,
|
||||||
|
saveFilterTab
|
||||||
|
} = createFilterTabUtils<SaleListUrlFilters>(SALE_FILTERS_KEY);
|
||||||
|
|
||||||
|
export const { areFiltersApplied, getActiveFilters } = createFilterUtils<
|
||||||
|
SaleListUrlQueryParams,
|
||||||
|
SaleListUrlFilters
|
||||||
|
>(SaleListUrlFiltersEnum);
|
2
src/discounts/views/SaleList/index.ts
Normal file
2
src/discounts/views/SaleList/index.ts
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
export { default } from "./SaleList";
|
||||||
|
export * from "./SaleList";
|
|
@ -43,6 +43,12 @@ export enum ConfigurationTypeFieldEnum {
|
||||||
STRING = "STRING",
|
STRING = "STRING",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export enum DiscountStatusEnum {
|
||||||
|
ACTIVE = "ACTIVE",
|
||||||
|
EXPIRED = "EXPIRED",
|
||||||
|
SCHEDULED = "SCHEDULED",
|
||||||
|
}
|
||||||
|
|
||||||
export enum DiscountValueTypeEnum {
|
export enum DiscountValueTypeEnum {
|
||||||
FIXED = "FIXED",
|
FIXED = "FIXED",
|
||||||
PERCENTAGE = "PERCENTAGE",
|
PERCENTAGE = "PERCENTAGE",
|
||||||
|
@ -393,6 +399,11 @@ export interface DateRangeInput {
|
||||||
lte?: any | null;
|
lte?: any | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface DateTimeRangeInput {
|
||||||
|
gte?: any | null;
|
||||||
|
lte?: any | null;
|
||||||
|
}
|
||||||
|
|
||||||
export interface DraftOrderInput {
|
export interface DraftOrderInput {
|
||||||
billingAddress?: AddressInput | null;
|
billingAddress?: AddressInput | null;
|
||||||
user?: string | null;
|
user?: string | null;
|
||||||
|
@ -564,6 +575,13 @@ export interface ReorderInput {
|
||||||
sortOrder?: number | null;
|
sortOrder?: number | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface SaleFilterInput {
|
||||||
|
status?: (DiscountStatusEnum | null)[] | null;
|
||||||
|
saleType?: DiscountValueTypeEnum | null;
|
||||||
|
started?: DateTimeRangeInput | null;
|
||||||
|
search?: string | null;
|
||||||
|
}
|
||||||
|
|
||||||
export interface SaleInput {
|
export interface SaleInput {
|
||||||
name?: string | null;
|
name?: string | null;
|
||||||
type?: DiscountValueTypeEnum | null;
|
type?: DiscountValueTypeEnum | null;
|
||||||
|
|
Loading…
Reference in a new issue