Refactor product list datagrid to use new hooks (#3845)
This commit is contained in:
parent
d282769fd9
commit
e37c8ce44c
7 changed files with 64 additions and 182 deletions
5
.changeset/tiny-cherries-deny.md
Normal file
5
.changeset/tiny-cherries-deny.md
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
"saleor-dashboard": minor
|
||||||
|
---
|
||||||
|
|
||||||
|
Refactor product list datagrid to use useFilterPresets and useRowSelection hooks
|
|
@ -1,42 +0,0 @@
|
||||||
// @ts-strict-ignore
|
|
||||||
import { render, screen } from "@testing-library/react";
|
|
||||||
import userEvent from "@testing-library/user-event";
|
|
||||||
import React from "react";
|
|
||||||
|
|
||||||
import { ProductListDeleteButton } from "./ProductListDeleteButton";
|
|
||||||
|
|
||||||
jest.mock("react-intl", () => ({
|
|
||||||
FormattedMessage: ({ defaultMessage }) => <>{defaultMessage}</>,
|
|
||||||
}));
|
|
||||||
|
|
||||||
describe("ProductListDeleteButton", () => {
|
|
||||||
it("should return null when show is equal false", () => {
|
|
||||||
// Arrange & Act
|
|
||||||
const { container } = render(
|
|
||||||
<ProductListDeleteButton show={false} onClick={jest.fn()} />,
|
|
||||||
);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
expect(container).toBeEmptyDOMElement();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("should render button", async () => {
|
|
||||||
// Arrange & Act
|
|
||||||
render(<ProductListDeleteButton show onClick={jest.fn()} />);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
expect(screen.getByRole("button")).toBeInTheDocument();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("should fire callback on click", async () => {
|
|
||||||
// Arrange
|
|
||||||
const onClick = jest.fn();
|
|
||||||
|
|
||||||
// Act
|
|
||||||
render(<ProductListDeleteButton show onClick={onClick} />);
|
|
||||||
await userEvent.click(screen.getByRole("button"));
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
expect(onClick).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { Button, Tooltip, TrashBinIcon } from "@saleor/macaw-ui/next";
|
import { Button, Tooltip, TrashBinIcon } from "@saleor/macaw-ui/next";
|
||||||
import React, { forwardRef } from "react";
|
import React, { forwardRef, useState } from "react";
|
||||||
import { FormattedMessage } from "react-intl";
|
import { FormattedMessage } from "react-intl";
|
||||||
|
|
||||||
interface ProductListDeleteButtonProps {
|
interface ProductListDeleteButtonProps {
|
||||||
|
@ -11,15 +11,23 @@ export const ProductListDeleteButton = forwardRef<
|
||||||
HTMLButtonElement,
|
HTMLButtonElement,
|
||||||
ProductListDeleteButtonProps
|
ProductListDeleteButtonProps
|
||||||
>(({ onClick, show = false }, ref) => {
|
>(({ onClick, show = false }, ref) => {
|
||||||
|
const [isTooltipOpen, setIsTooltipOpen] = useState(false);
|
||||||
|
|
||||||
if (!show) {
|
if (!show) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Tooltip>
|
<Tooltip open={isTooltipOpen}>
|
||||||
<Tooltip.Trigger>
|
<Tooltip.Trigger>
|
||||||
<Button
|
<Button
|
||||||
ref={ref}
|
ref={ref}
|
||||||
|
onMouseOver={() => {
|
||||||
|
setIsTooltipOpen(true);
|
||||||
|
}}
|
||||||
|
onMouseLeave={() => {
|
||||||
|
setIsTooltipOpen(false);
|
||||||
|
}}
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
icon={<TrashBinIcon />}
|
icon={<TrashBinIcon />}
|
||||||
variant="secondary"
|
variant="secondary"
|
||||||
|
|
|
@ -61,7 +61,6 @@ const props: ProductListPageProps = {
|
||||||
products,
|
products,
|
||||||
selectedChannelId: "123",
|
selectedChannelId: "123",
|
||||||
selectedProductIds: ["123"],
|
selectedProductIds: ["123"],
|
||||||
setBulkDeleteButtonRef: () => undefined,
|
|
||||||
clearRowSelection: () => undefined,
|
clearRowSelection: () => undefined,
|
||||||
settings: {
|
settings: {
|
||||||
...pageListProps.default.settings,
|
...pageListProps.default.settings,
|
||||||
|
|
|
@ -80,7 +80,6 @@ export interface ProductListPageProps
|
||||||
onProductsDelete: () => void;
|
onProductsDelete: () => void;
|
||||||
onSelectProductIds: (ids: number[], clearSelection: () => void) => void;
|
onSelectProductIds: (ids: number[], clearSelection: () => void) => void;
|
||||||
clearRowSelection: () => void;
|
clearRowSelection: () => void;
|
||||||
setBulkDeleteButtonRef: (ref: HTMLButtonElement) => void;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ProductListViewType = "datagrid" | "tile";
|
export type ProductListViewType = "datagrid" | "tile";
|
||||||
|
@ -117,7 +116,6 @@ export const ProductListPage: React.FC<ProductListPageProps> = props => {
|
||||||
selectedProductIds,
|
selectedProductIds,
|
||||||
onProductsDelete,
|
onProductsDelete,
|
||||||
clearRowSelection,
|
clearRowSelection,
|
||||||
setBulkDeleteButtonRef,
|
|
||||||
...listProps
|
...listProps
|
||||||
} = props;
|
} = props;
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
|
@ -272,7 +270,6 @@ export const ProductListPage: React.FC<ProductListPageProps> = props => {
|
||||||
actions={
|
actions={
|
||||||
<Box display="flex" gap={4}>
|
<Box display="flex" gap={4}>
|
||||||
<ProductListDeleteButton
|
<ProductListDeleteButton
|
||||||
ref={setBulkDeleteButtonRef}
|
|
||||||
onClick={onProductsDelete}
|
onClick={onProductsDelete}
|
||||||
show={selectedProductIds.length > 0}
|
show={selectedProductIds.length > 0}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -4,9 +4,7 @@ import ActionDialog from "@dashboard/components/ActionDialog";
|
||||||
import useAppChannel from "@dashboard/components/AppLayout/AppChannelContext";
|
import useAppChannel from "@dashboard/components/AppLayout/AppChannelContext";
|
||||||
import { useColumnPickerSettings } from "@dashboard/components/Datagrid/ColumnPicker/useColumnPickerSettings";
|
import { useColumnPickerSettings } from "@dashboard/components/Datagrid/ColumnPicker/useColumnPickerSettings";
|
||||||
import DeleteFilterTabDialog from "@dashboard/components/DeleteFilterTabDialog";
|
import DeleteFilterTabDialog from "@dashboard/components/DeleteFilterTabDialog";
|
||||||
import SaveFilterTabDialog, {
|
import SaveFilterTabDialog from "@dashboard/components/SaveFilterTabDialog";
|
||||||
SaveFilterTabDialogFormData,
|
|
||||||
} from "@dashboard/components/SaveFilterTabDialog";
|
|
||||||
import { useShopLimitsQuery } from "@dashboard/components/Shop/queries";
|
import { useShopLimitsQuery } from "@dashboard/components/Shop/queries";
|
||||||
import {
|
import {
|
||||||
DEFAULT_INITIAL_PAGINATION_DATA,
|
DEFAULT_INITIAL_PAGINATION_DATA,
|
||||||
|
@ -31,6 +29,7 @@ import {
|
||||||
} from "@dashboard/graphql";
|
} from "@dashboard/graphql";
|
||||||
import useBackgroundTask from "@dashboard/hooks/useBackgroundTask";
|
import useBackgroundTask from "@dashboard/hooks/useBackgroundTask";
|
||||||
import { useFilterHandlers } from "@dashboard/hooks/useFilterHandlers";
|
import { useFilterHandlers } from "@dashboard/hooks/useFilterHandlers";
|
||||||
|
import { useFilterPresets } from "@dashboard/hooks/useFilterPresets";
|
||||||
import useListSettings from "@dashboard/hooks/useListSettings";
|
import useListSettings from "@dashboard/hooks/useListSettings";
|
||||||
import useNavigator from "@dashboard/hooks/useNavigator";
|
import useNavigator from "@dashboard/hooks/useNavigator";
|
||||||
import useNotifier from "@dashboard/hooks/useNotifier";
|
import useNotifier from "@dashboard/hooks/useNotifier";
|
||||||
|
@ -39,6 +38,7 @@ import usePaginator, {
|
||||||
createPaginationState,
|
createPaginationState,
|
||||||
PaginatorContext,
|
PaginatorContext,
|
||||||
} from "@dashboard/hooks/usePaginator";
|
} from "@dashboard/hooks/usePaginator";
|
||||||
|
import { useRowSelection } from "@dashboard/hooks/useRowSelection";
|
||||||
import { commonMessages } from "@dashboard/intl";
|
import { commonMessages } from "@dashboard/intl";
|
||||||
import ProductExportDialog from "@dashboard/products/components/ProductExportDialog";
|
import ProductExportDialog from "@dashboard/products/components/ProductExportDialog";
|
||||||
import {
|
import {
|
||||||
|
@ -59,33 +59,23 @@ import useCategorySearch from "@dashboard/searches/useCategorySearch";
|
||||||
import useCollectionSearch from "@dashboard/searches/useCollectionSearch";
|
import useCollectionSearch from "@dashboard/searches/useCollectionSearch";
|
||||||
import useProductTypeSearch from "@dashboard/searches/useProductTypeSearch";
|
import useProductTypeSearch from "@dashboard/searches/useProductTypeSearch";
|
||||||
import { ListViews } from "@dashboard/types";
|
import { ListViews } from "@dashboard/types";
|
||||||
import { prepareQs } from "@dashboard/utils/filters/qs";
|
|
||||||
import createDialogActionHandlers from "@dashboard/utils/handlers/dialogActionHandlers";
|
import createDialogActionHandlers from "@dashboard/utils/handlers/dialogActionHandlers";
|
||||||
import { mapEdgesToItems, mapNodeToChoice } from "@dashboard/utils/maps";
|
import { mapEdgesToItems, mapNodeToChoice } from "@dashboard/utils/maps";
|
||||||
import { getSortUrlVariables } from "@dashboard/utils/sort";
|
import { getSortUrlVariables } from "@dashboard/utils/sort";
|
||||||
import { DialogContentText } from "@material-ui/core";
|
import { DialogContentText } from "@material-ui/core";
|
||||||
import isEqual from "lodash/isEqual";
|
import isEqual from "lodash/isEqual";
|
||||||
import { stringify } from "qs";
|
import React, { useCallback, useEffect, useState } from "react";
|
||||||
import React, { useCallback, useEffect, useRef, useState } from "react";
|
|
||||||
import { FormattedMessage, useIntl } from "react-intl";
|
import { FormattedMessage, useIntl } from "react-intl";
|
||||||
|
|
||||||
import ProductListPage from "../../components/ProductListPage";
|
import ProductListPage from "../../components/ProductListPage";
|
||||||
import {
|
import {
|
||||||
deleteFilterTab,
|
|
||||||
getFilterOpts,
|
getFilterOpts,
|
||||||
getFilterQueryParam,
|
getFilterQueryParam,
|
||||||
getFilterTabs,
|
|
||||||
getFilterVariables,
|
getFilterVariables,
|
||||||
saveFilterTab,
|
storageUtils,
|
||||||
updateFilterTab,
|
|
||||||
} from "./filters";
|
} from "./filters";
|
||||||
import { DEFAULT_SORT_KEY, getSortQueryVariables } from "./sort";
|
import { DEFAULT_SORT_KEY, getSortQueryVariables } from "./sort";
|
||||||
import {
|
import { getAvailableProductKinds, getProductKindOpts } from "./utils";
|
||||||
getActiveTabIndexAfterTabDelete,
|
|
||||||
getAvailableProductKinds,
|
|
||||||
getNextUniqueTabName,
|
|
||||||
getProductKindOpts,
|
|
||||||
} from "./utils";
|
|
||||||
|
|
||||||
interface ProductListProps {
|
interface ProductListProps {
|
||||||
params: ProductListUrlQueryParams;
|
params: ProductListUrlQueryParams;
|
||||||
|
@ -96,36 +86,12 @@ export const ProductList: React.FC<ProductListProps> = ({ params }) => {
|
||||||
const notify = useNotifier();
|
const notify = useNotifier();
|
||||||
const { queue } = useBackgroundTask();
|
const { queue } = useBackgroundTask();
|
||||||
|
|
||||||
const [tabIndexToDelete, setTabIndexToDelete] = useState<number | null>(null);
|
|
||||||
const [selectedProductIds, setSelectedProductIds] = useState<string[]>([]);
|
|
||||||
const deleteButtonRef = useRef<HTMLButtonElement>(null);
|
|
||||||
|
|
||||||
const { updateListSettings, settings } = useListSettings<ProductListColumns>(
|
const { updateListSettings, settings } = useListSettings<ProductListColumns>(
|
||||||
ListViews.PRODUCT_LIST,
|
ListViews.PRODUCT_LIST,
|
||||||
);
|
);
|
||||||
|
|
||||||
const { columnPickerSettings, setDynamicColumnsSettings } =
|
const { columnPickerSettings, setDynamicColumnsSettings } =
|
||||||
useColumnPickerSettings("PRODUCT_LIST");
|
useColumnPickerSettings("PRODUCT_LIST");
|
||||||
// Keep reference to clear datagrid selection function
|
|
||||||
const clearRowSelectionCallback = React.useRef<() => void | null>(null);
|
|
||||||
const clearRowSelection = () => {
|
|
||||||
setSelectedProductIds([]);
|
|
||||||
if (clearRowSelectionCallback.current) {
|
|
||||||
clearRowSelectionCallback.current();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Whenever pagination change we need to clear datagrid selection
|
|
||||||
useEffect(() => {
|
|
||||||
clearRowSelection();
|
|
||||||
}, [params.after, params.before]);
|
|
||||||
|
|
||||||
// Remove focus from delete button after delete action
|
|
||||||
useEffect(() => {
|
|
||||||
if (!params.action && deleteButtonRef.current) {
|
|
||||||
deleteButtonRef.current.blur();
|
|
||||||
}
|
|
||||||
}, [params.action]);
|
|
||||||
|
|
||||||
usePaginationReset(productListUrl, params, settings.rowNumber);
|
usePaginationReset(productListUrl, params, settings.rowNumber);
|
||||||
|
|
||||||
|
@ -208,11 +174,31 @@ export const ProductList: React.FC<ProductListProps> = ({ params }) => {
|
||||||
ProductListUrlDialog,
|
ProductListUrlDialog,
|
||||||
ProductListUrlQueryParams
|
ProductListUrlQueryParams
|
||||||
>(navigate, productListUrl, params);
|
>(navigate, productListUrl, params);
|
||||||
|
console.log(params);
|
||||||
|
|
||||||
const tabs = getFilterTabs();
|
const {
|
||||||
|
clearRowSelection,
|
||||||
|
selectedRowIds,
|
||||||
|
setClearDatagridRowSelectionCallback,
|
||||||
|
setSelectedRowIds,
|
||||||
|
} = useRowSelection(params);
|
||||||
|
|
||||||
const currentTab =
|
const {
|
||||||
params.activeTab !== undefined ? parseInt(params.activeTab, 10) : undefined;
|
hasPresetsChange,
|
||||||
|
onPresetChange,
|
||||||
|
onPresetDelete,
|
||||||
|
onPresetSave,
|
||||||
|
onPresetUpdate,
|
||||||
|
presetIdToDelete,
|
||||||
|
presets,
|
||||||
|
selectedPreset,
|
||||||
|
setPresetIdToDelete,
|
||||||
|
} = useFilterPresets({
|
||||||
|
params,
|
||||||
|
getUrl: productListUrl,
|
||||||
|
storageUtils,
|
||||||
|
reset: clearRowSelection,
|
||||||
|
});
|
||||||
|
|
||||||
const countAllProducts = useProductCountQuery({
|
const countAllProducts = useProductCountQuery({
|
||||||
skip: params.action !== "export",
|
skip: params.action !== "export",
|
||||||
|
@ -268,57 +254,6 @@ export const ProductList: React.FC<ProductListProps> = ({ params }) => {
|
||||||
hasSortWithRank: true,
|
hasSortWithRank: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
const handleTabChange = (tab: number) => {
|
|
||||||
clearRowSelection();
|
|
||||||
|
|
||||||
const qs = new URLSearchParams(getFilterTabs()[tab - 1]?.data ?? "");
|
|
||||||
qs.append("activeTab", tab.toString());
|
|
||||||
|
|
||||||
navigate(productListUrl() + qs.toString());
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleFilterTabDelete = () => {
|
|
||||||
deleteFilterTab(tabIndexToDelete);
|
|
||||||
clearRowSelection();
|
|
||||||
|
|
||||||
// When deleting the current tab, navigate to the All products
|
|
||||||
if (tabIndexToDelete === currentTab) {
|
|
||||||
navigate(productListUrl());
|
|
||||||
} else {
|
|
||||||
const currentParams = { ...params };
|
|
||||||
// When deleting a tab that is not the current one, only remove the action param from the query
|
|
||||||
delete currentParams.action;
|
|
||||||
// When deleting a tab that is before the current one, decrease the activeTab param by 1
|
|
||||||
currentParams.activeTab = getActiveTabIndexAfterTabDelete(
|
|
||||||
currentTab,
|
|
||||||
tabIndexToDelete,
|
|
||||||
);
|
|
||||||
navigate(productListUrl() + stringify(currentParams));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleFilterTabSave = (data: SaveFilterTabDialogFormData) => {
|
|
||||||
const { parsedQs } = prepareQs(location.search);
|
|
||||||
|
|
||||||
saveFilterTab(
|
|
||||||
getNextUniqueTabName(
|
|
||||||
data.name,
|
|
||||||
tabs.map(tab => tab.name),
|
|
||||||
),
|
|
||||||
stringify(parsedQs),
|
|
||||||
);
|
|
||||||
handleTabChange(tabs.length + 1);
|
|
||||||
};
|
|
||||||
|
|
||||||
const hanleFilterTabUpdate = (tabName: string) => {
|
|
||||||
const { parsedQs, activeTab } = prepareQs(location.search);
|
|
||||||
|
|
||||||
updateFilterTab(tabName, stringify(parsedQs));
|
|
||||||
parsedQs.activeTab = activeTab;
|
|
||||||
|
|
||||||
navigate(productListUrl() + stringify(parsedQs));
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleSort = (field: ProductListUrlSortField, attributeId?: string) =>
|
const handleSort = (field: ProductListUrlSortField, attributeId?: string) =>
|
||||||
navigate(
|
navigate(
|
||||||
productListUrl({
|
productListUrl({
|
||||||
|
@ -331,9 +266,8 @@ export const ProductList: React.FC<ProductListProps> = ({ params }) => {
|
||||||
|
|
||||||
const handleSubmitBulkDelete = () => {
|
const handleSubmitBulkDelete = () => {
|
||||||
productBulkDelete({
|
productBulkDelete({
|
||||||
variables: { ids: selectedProductIds },
|
variables: { ids: selectedRowIds },
|
||||||
});
|
});
|
||||||
deleteButtonRef.current.blur();
|
|
||||||
clearRowSelection();
|
clearRowSelection();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -377,15 +311,15 @@ export const ProductList: React.FC<ProductListProps> = ({ params }) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const rowsIds = rows.map(row => products[row].id);
|
const rowsIds = rows.map(row => products[row].id);
|
||||||
const haveSaveValues = isEqual(rowsIds, selectedProductIds);
|
const haveSaveValues = isEqual(rowsIds, selectedRowIds);
|
||||||
|
|
||||||
if (!haveSaveValues) {
|
if (!haveSaveValues) {
|
||||||
setSelectedProductIds(rowsIds);
|
setSelectedRowIds(rowsIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
clearRowSelectionCallback.current = clearSelection;
|
setClearDatagridRowSelectionCallback(clearSelection);
|
||||||
},
|
},
|
||||||
[products, selectedProductIds],
|
[products, selectedRowIds],
|
||||||
);
|
);
|
||||||
|
|
||||||
const availableColumnsAttributesOpts =
|
const availableColumnsAttributesOpts =
|
||||||
|
@ -440,17 +374,6 @@ export const ProductList: React.FC<ProductListProps> = ({ params }) => {
|
||||||
channelOpts,
|
channelOpts,
|
||||||
);
|
);
|
||||||
|
|
||||||
const hasPresetsChanged = () => {
|
|
||||||
const activeTab = tabs[currentTab - 1];
|
|
||||||
const { parsedQs } = prepareQs(location.search);
|
|
||||||
|
|
||||||
return (
|
|
||||||
activeTab?.data !== stringify(parsedQs) &&
|
|
||||||
location.search !== "" &&
|
|
||||||
stringify(parsedQs) !== ""
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const paginationValues = usePaginator({
|
const paginationValues = usePaginator({
|
||||||
pageInfo: data?.products?.pageInfo,
|
pageInfo: data?.products?.pageInfo,
|
||||||
paginationState,
|
paginationState,
|
||||||
|
@ -467,7 +390,7 @@ export const ProductList: React.FC<ProductListProps> = ({ params }) => {
|
||||||
}}
|
}}
|
||||||
onSort={handleSort}
|
onSort={handleSort}
|
||||||
currencySymbol={selectedChannel?.currencyCode || ""}
|
currencySymbol={selectedChannel?.currencyCode || ""}
|
||||||
currentTab={currentTab}
|
currentTab={selectedPreset}
|
||||||
defaultSettings={defaultListSettings[ListViews.PRODUCT_LIST]}
|
defaultSettings={defaultListSettings[ListViews.PRODUCT_LIST]}
|
||||||
filterOpts={filterOpts}
|
filterOpts={filterOpts}
|
||||||
gridAttributesOpts={gridAttributesOpts}
|
gridAttributesOpts={gridAttributesOpts}
|
||||||
|
@ -486,26 +409,23 @@ export const ProductList: React.FC<ProductListProps> = ({ params }) => {
|
||||||
onFilterChange={changeFilters}
|
onFilterChange={changeFilters}
|
||||||
onFilterAttributeFocus={setFocusedAttribute}
|
onFilterAttributeFocus={setFocusedAttribute}
|
||||||
onTabSave={() => openModal("save-search")}
|
onTabSave={() => openModal("save-search")}
|
||||||
onTabUpdate={hanleFilterTabUpdate}
|
onTabUpdate={onPresetUpdate}
|
||||||
onTabDelete={(tabIndex: number) => {
|
onTabDelete={(tabIndex: number) => {
|
||||||
setTabIndexToDelete(tabIndex);
|
setPresetIdToDelete(tabIndex);
|
||||||
openModal("delete-search");
|
openModal("delete-search");
|
||||||
}}
|
}}
|
||||||
onProductsDelete={() => openModal("delete")}
|
onProductsDelete={() => openModal("delete")}
|
||||||
onTabChange={handleTabChange}
|
onTabChange={onPresetChange}
|
||||||
hasPresetsChanged={hasPresetsChanged()}
|
hasPresetsChanged={hasPresetsChange()}
|
||||||
initialSearch={params.query || ""}
|
initialSearch={params.query || ""}
|
||||||
tabs={tabs.map(tab => tab.name)}
|
tabs={presets.map(tab => tab.name)}
|
||||||
onExport={() => openModal("export")}
|
onExport={() => openModal("export")}
|
||||||
selectedChannelId={selectedChannel?.id}
|
selectedChannelId={selectedChannel?.id}
|
||||||
columnPickerSettings={columnPickerSettings}
|
columnPickerSettings={columnPickerSettings}
|
||||||
setDynamicColumnSettings={setDynamicColumnsSettings}
|
setDynamicColumnSettings={setDynamicColumnsSettings}
|
||||||
selectedProductIds={selectedProductIds}
|
selectedProductIds={selectedRowIds}
|
||||||
onSelectProductIds={handleSetSelectedProductIds}
|
onSelectProductIds={handleSetSelectedProductIds}
|
||||||
clearRowSelection={clearRowSelection}
|
clearRowSelection={clearRowSelection}
|
||||||
setBulkDeleteButtonRef={(ref: HTMLButtonElement) => {
|
|
||||||
deleteButtonRef.current = ref;
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
<ActionDialog
|
<ActionDialog
|
||||||
open={params.action === "delete"}
|
open={params.action === "delete"}
|
||||||
|
@ -525,8 +445,8 @@ export const ProductList: React.FC<ProductListProps> = ({ params }) => {
|
||||||
defaultMessage="{counter,plural,one{Are you sure you want to delete this product?} other{Are you sure you want to delete {displayQuantity} products?}}"
|
defaultMessage="{counter,plural,one{Are you sure you want to delete this product?} other{Are you sure you want to delete {displayQuantity} products?}}"
|
||||||
description="dialog content"
|
description="dialog content"
|
||||||
values={{
|
values={{
|
||||||
counter: selectedProductIds.length,
|
counter: selectedRowIds.length,
|
||||||
displayQuantity: <strong>{selectedProductIds.length}</strong>,
|
displayQuantity: <strong>{selectedRowIds.length}</strong>,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</DialogContentText>
|
</DialogContentText>
|
||||||
|
@ -550,7 +470,7 @@ export const ProductList: React.FC<ProductListProps> = ({ params }) => {
|
||||||
all: countAllProducts.data?.products?.totalCount,
|
all: countAllProducts.data?.products?.totalCount,
|
||||||
filter: data?.products?.totalCount,
|
filter: data?.products?.totalCount,
|
||||||
}}
|
}}
|
||||||
selectedProducts={selectedProductIds.length}
|
selectedProducts={selectedRowIds.length}
|
||||||
warehouses={mapEdgesToItems(warehouses?.data?.warehouses) || []}
|
warehouses={mapEdgesToItems(warehouses?.data?.warehouses) || []}
|
||||||
channels={availableChannels}
|
channels={availableChannels}
|
||||||
onClose={closeModal}
|
onClose={closeModal}
|
||||||
|
@ -560,7 +480,7 @@ export const ProductList: React.FC<ProductListProps> = ({ params }) => {
|
||||||
input: {
|
input: {
|
||||||
...data,
|
...data,
|
||||||
filter,
|
filter,
|
||||||
ids: selectedProductIds,
|
ids: selectedRowIds,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
@ -570,14 +490,14 @@ export const ProductList: React.FC<ProductListProps> = ({ params }) => {
|
||||||
open={params.action === "save-search"}
|
open={params.action === "save-search"}
|
||||||
confirmButtonState="default"
|
confirmButtonState="default"
|
||||||
onClose={closeModal}
|
onClose={closeModal}
|
||||||
onSubmit={handleFilterTabSave}
|
onSubmit={onPresetSave}
|
||||||
/>
|
/>
|
||||||
<DeleteFilterTabDialog
|
<DeleteFilterTabDialog
|
||||||
open={params.action === "delete-search"}
|
open={params.action === "delete-search"}
|
||||||
confirmButtonState="default"
|
confirmButtonState="default"
|
||||||
onClose={closeModal}
|
onClose={closeModal}
|
||||||
onSubmit={handleFilterTabDelete}
|
onSubmit={onPresetDelete}
|
||||||
tabName={tabs[tabIndexToDelete - 1]?.name ?? "..."}
|
tabName={presets[presetIdToDelete - 1]?.name ?? "..."}
|
||||||
/>
|
/>
|
||||||
<ProductTypePickerDialog
|
<ProductTypePickerDialog
|
||||||
confirmButtonState="success"
|
confirmButtonState="success"
|
||||||
|
|
|
@ -465,12 +465,7 @@ export function getFilterQueryParam(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const {
|
export const storageUtils = createFilterTabUtils<string>(PRODUCT_FILTERS_KEY);
|
||||||
deleteFilterTab,
|
|
||||||
getFilterTabs,
|
|
||||||
saveFilterTab,
|
|
||||||
updateFilterTab,
|
|
||||||
} = createFilterTabUtils<string>(PRODUCT_FILTERS_KEY);
|
|
||||||
|
|
||||||
export const { areFiltersApplied, getActiveFilters, getFiltersCurrentTab } =
|
export const { areFiltersApplied, getActiveFilters, getFiltersCurrentTab } =
|
||||||
createFilterUtils<ProductListUrlQueryParams, ProductListUrlFilters>({
|
createFilterUtils<ProductListUrlQueryParams, ProductListUrlFilters>({
|
||||||
|
|
Loading…
Reference in a new issue