Fix duplicated labels in column picker (#1197)

* Fix duplicated labels in column picker

* Update changelog

* Refactor column picker scroll fetch

* Migrate react-infinite-scroller to react-infinite-scroll-component

* Remove unneeded keys

* Align dialog items to top
This commit is contained in:
Dawid Tarasiuk 2021-07-01 10:21:41 +02:00 committed by GitHub
parent 8e1dc4e12d
commit 909e08f2af
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
18 changed files with 280 additions and 268 deletions

View file

@ -57,6 +57,7 @@ All notable, unreleased changes to this project will be documented in this file.
- Fix breaking select popups in filters - #1193 by @orzechdev
- Create channel filters in product, sales and voucher lists - #1187 by @jwm0
- Add generic filter validation - #1187 by @jwm0
- Fix duplicated labels in column picker - #1197 by @orzechdev
# 2.11.1

13
package-lock.json generated
View file

@ -22656,12 +22656,12 @@
"prop-types": "^15.6.1"
}
},
"react-infinite-scroller": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/react-infinite-scroller/-/react-infinite-scroller-1.2.4.tgz",
"integrity": "sha512-/oOa0QhZjXPqaD6sictN2edFMsd3kkMiE19Vcz5JDgHpzEJVqYcmq+V3mkwO88087kvKGe1URNksHEOt839Ubw==",
"react-infinite-scroll-component": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/react-infinite-scroll-component/-/react-infinite-scroll-component-6.1.0.tgz",
"integrity": "sha512-SQu5nCqy8DxQWpnUVLx7V7b7LcA37aM7tvoWjTLZp1dk6EJibM5/4EJKzOnl07/BsM1Y40sKLuqjCwwH/xV0TQ==",
"requires": {
"prop-types": "^15.5.8"
"throttle-debounce": "^2.1.0"
}
},
"react-inlinesvg": {
@ -26702,8 +26702,7 @@
"throttle-debounce": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/throttle-debounce/-/throttle-debounce-2.3.0.tgz",
"integrity": "sha512-H7oLPV0P7+jgvrk+6mwwwBDmxTaxnu9HMXmloNLXwnNO0ZxZ31Orah2n8lU1eMPvsaowP2CX+USCgyovXfdOFQ==",
"dev": true
"integrity": "sha512-H7oLPV0P7+jgvrk+6mwwwBDmxTaxnu9HMXmloNLXwnNO0ZxZ31Orah2n8lU1eMPvsaowP2CX+USCgyovXfdOFQ=="
},
"throttleit": {
"version": "1.0.0",

View file

@ -65,7 +65,7 @@
"react-error-boundary": "^1.2.5",
"react-gtm-module": "^2.0.11",
"react-helmet": "^6.1.0",
"react-infinite-scroller": "^1.2.4",
"react-infinite-scroll-component": "^6.1.0",
"react-inlinesvg": "^2.1.1",
"react-intl": "^5.10.2",
"react-jss": "^10.0.0",

View file

@ -30,7 +30,7 @@ import { makeStyles } from "@saleor/theme";
import { FetchMoreProps } from "@saleor/types";
import classNames from "classnames";
import React from "react";
import InfiniteScroll from "react-infinite-scroller";
import InfiniteScroll from "react-infinite-scroll-component";
import { FormattedMessage, useIntl } from "react-intl";
const useStyles = makeStyles(
@ -73,6 +73,8 @@ export interface AssignAttributeDialogProps extends FetchMoreProps {
onToggle: (id: string) => void;
}
const scrollableTargetId = "assignAttributeScrollableDialog";
const AssignAttributeDialog: React.FC<AssignAttributeDialogProps> = ({
attributes,
confirmButtonState,
@ -126,19 +128,22 @@ const AssignAttributeDialog: React.FC<AssignAttributeDialogProps> = ({
}}
/>
</DialogContent>
<DialogContent className={classes.scrollArea} ref={anchor}>
<DialogContent
className={classes.scrollArea}
ref={anchor}
id={scrollableTargetId}
>
<InfiniteScroll
pageStart={0}
loadMore={onFetchMore}
dataLength={attributes?.length}
next={onFetchMore}
hasMore={hasMore}
useWindow={false}
scrollThreshold="100px"
loader={
<div className={classes.loadMoreLoaderContainer}>
<CircularProgress size={16} />
</div>
}
threshold={100}
key="infinite-scroll"
scrollableTarget={scrollableTargetId}
>
<ResponsiveTable key="table">
<TableBody>

View file

@ -17,14 +17,13 @@ import useScrollableDialogStyle from "@saleor/styles/useScrollableDialogStyle";
import { makeStyles } from "@saleor/theme";
import { FetchMoreProps, Node } from "@saleor/types";
import React from "react";
import InfiniteScroll from "react-infinite-scroller";
import InfiniteScroll from "react-infinite-scroll-component";
import { FormattedMessage } from "react-intl";
import Checkbox from "../Checkbox";
import ConfirmButton, {
ConfirmButtonTransitionState
} from "../ConfirmButton/ConfirmButton";
import FormSpacer from "../FormSpacer";
export interface FormData {
containers: string[];
@ -80,6 +79,8 @@ function handleContainerAssign(
}
}
const scrollableTargetId = "assignContainerScrollableDialog";
const AssignContainerDialog: React.FC<AssignContainerDialogProps> = props => {
const {
confirmButtonState,
@ -101,12 +102,9 @@ const AssignContainerDialog: React.FC<AssignContainerDialogProps> = props => {
const [selectedContainers, setSelectedContainers] = React.useState<string[]>(
[]
);
const container = React.useRef<HTMLDivElement>();
const handleSubmit = () => onSubmit(selectedContainers);
const containerHeight = container.current?.scrollHeight - 130;
return (
<Dialog
onClose={onClose}
@ -116,10 +114,7 @@ const AssignContainerDialog: React.FC<AssignContainerDialogProps> = props => {
maxWidth="sm"
>
<DialogTitle>{title}</DialogTitle>
<DialogContent
className={scrollableDialogClasses.content}
ref={container}
>
<DialogContent className={scrollableDialogClasses.topArea}>
<TextField
name="query"
value={query}
@ -132,22 +127,22 @@ const AssignContainerDialog: React.FC<AssignContainerDialogProps> = props => {
endAdornment: loading && <CircularProgress size={16} />
}}
/>
<FormSpacer />
<div
</DialogContent>
<DialogContent
className={scrollableDialogClasses.scrollArea}
style={{ height: containerHeight }}
id={scrollableTargetId}
>
<InfiniteScroll
pageStart={0}
loadMore={onFetchMore}
dataLength={containers?.length}
next={onFetchMore}
hasMore={hasMore}
useWindow={false}
scrollThreshold="100px"
loader={
<div className={scrollableDialogClasses.loadMoreLoaderContainer}>
<CircularProgress size={16} />
</div>
}
threshold={10}
scrollableTarget={scrollableTargetId}
>
<ResponsiveTable>
<TableBody>
@ -183,7 +178,6 @@ const AssignContainerDialog: React.FC<AssignContainerDialogProps> = props => {
</TableBody>
</ResponsiveTable>
</InfiniteScroll>
</div>
</DialogContent>
<DialogActions>
<Button onClick={onClose}>

View file

@ -13,7 +13,6 @@ import {
import ConfirmButton, {
ConfirmButtonTransitionState
} from "@saleor/components/ConfirmButton";
import FormSpacer from "@saleor/components/FormSpacer";
import ResponsiveTable from "@saleor/components/ResponsiveTable";
import TableCellAvatar from "@saleor/components/TableCellAvatar";
import useSearchQuery from "@saleor/hooks/useSearchQuery";
@ -24,7 +23,7 @@ import useScrollableDialogStyle from "@saleor/styles/useScrollableDialogStyle";
import { makeStyles } from "@saleor/theme";
import { FetchMoreProps } from "@saleor/types";
import React from "react";
import InfiniteScroll from "react-infinite-scroller";
import InfiniteScroll from "react-infinite-scroll-component";
import { FormattedMessage, useIntl } from "react-intl";
import Checkbox from "../Checkbox";
@ -80,6 +79,8 @@ function handleProductAssign(
}
}
const scrollableTargetId = "assignProductScrollableDialog";
const AssignProductDialog: React.FC<AssignProductDialogProps> = props => {
const {
confirmButtonState,
@ -100,12 +101,9 @@ const AssignProductDialog: React.FC<AssignProductDialogProps> = props => {
const [selectedProducts, setSelectedProducts] = React.useState<
SearchProducts_search_edges_node[]
>([]);
const container = React.useRef<HTMLDivElement>();
const handleSubmit = () => onSubmit(selectedProducts);
const containerHeight = container.current?.scrollHeight - 130;
return (
<Dialog
onClose={onClose}
@ -120,10 +118,7 @@ const AssignProductDialog: React.FC<AssignProductDialogProps> = props => {
description="dialog header"
/>
</DialogTitle>
<DialogContent
className={scrollableDialogClasses.content}
ref={container}
>
<DialogContent className={scrollableDialogClasses.topArea}>
<TextField
name="query"
value={query}
@ -141,22 +136,22 @@ const AssignProductDialog: React.FC<AssignProductDialogProps> = props => {
endAdornment: loading && <CircularProgress size={16} />
}}
/>
<FormSpacer />
<div
</DialogContent>
<DialogContent
className={scrollableDialogClasses.scrollArea}
style={{ height: containerHeight }}
id={scrollableTargetId}
>
<InfiniteScroll
pageStart={0}
loadMore={onFetchMore}
dataLength={products?.length}
next={onFetchMore}
hasMore={hasMore}
useWindow={false}
scrollThreshold="100px"
loader={
<div className={scrollableDialogClasses.loadMoreLoaderContainer}>
<CircularProgress size={16} />
</div>
}
threshold={10}
scrollableTarget={scrollableTargetId}
>
<ResponsiveTable key="table">
<TableBody>
@ -200,7 +195,6 @@ const AssignProductDialog: React.FC<AssignProductDialogProps> = props => {
</TableBody>
</ResponsiveTable>
</InfiniteScroll>
</div>
</DialogContent>
<DialogActions>
<Button onClick={onClose}>

View file

@ -43,7 +43,6 @@ const ColumnPicker: React.FC<ColumnPickerProps> = props => {
hasMore,
initialColumns,
initialOpen = false,
loading,
total,
onFetchMore,
onSave
@ -100,7 +99,6 @@ const ColumnPicker: React.FC<ColumnPickerProps> = props => {
<ColumnPickerContent
columns={columns}
hasMore={hasMore}
loading={loading}
selectedColumns={selectedColumns}
total={total}
onCancel={handleCancel}

View file

@ -12,7 +12,7 @@ import { FetchMoreProps } from "@saleor/types";
import { isSelected } from "@saleor/utils/lists";
import classNames from "classnames";
import React from "react";
import InfiniteScroll from "react-infinite-scroller";
import InfiniteScroll from "react-infinite-scroll-component";
import { FormattedMessage } from "react-intl";
import ControlledCheckbox from "../ControlledCheckbox";
@ -52,12 +52,12 @@ const useStyles = makeStyles(
display: "grid",
gridColumnGap: theme.spacing(3),
gridTemplateColumns: "repeat(3, 1fr)",
maxHeight: 256,
overflowX: "visible",
overflowY: "scroll",
padding: theme.spacing(2, 3)
},
contentContainer: {
maxHeight: 256,
overflowX: "visible",
overflowY: "scroll",
padding: 0
},
dropShadow: {
@ -80,11 +80,12 @@ const useStyles = makeStyles(
{ name: "ColumnPickerContent" }
);
const scrollableTargetId = "columnPickerScrollableDiv";
const ColumnPickerContent: React.FC<ColumnPickerContentProps> = props => {
const {
columns,
hasMore,
loading,
selectedColumns,
total,
onCancel,
@ -118,41 +119,24 @@ const ColumnPickerContent: React.FC<ColumnPickerContentProps> = props => {
</Typography>
</CardContent>
<Hr />
{hasMore && onFetchMore ? (
<InfiniteScroll
pageStart={0}
loadMore={onFetchMore}
hasMore={hasMore}
useWindow={false}
threshold={100}
key="infinite-scroll"
<CardContent
className={classes.contentContainer}
ref={anchor}
id={scrollableTargetId}
>
<CardContent className={classes.contentContainer}>
<div className={classes.content} ref={anchor}>
{columns.map(column => (
<ControlledCheckbox
checked={isSelected(
column.value,
selectedColumns,
(a, b) => a === b
)}
name={column.value}
label={column.label}
onChange={() => onColumnToggle(column.value)}
key={column.value}
/>
))}
{loading && (
<InfiniteScroll
dataLength={columns.length}
next={onFetchMore}
hasMore={hasMore}
scrollThreshold="100px"
loader={
<div className={classes.loadMoreLoaderContainer}>
<CircularProgress size={16} />
</div>
)}
</div>
</CardContent>
</InfiniteScroll>
) : (
<CardContent className={classes.contentContainer}>
<div className={classes.content} ref={anchor}>
}
scrollableTarget={scrollableTargetId}
>
<div className={classes.content}>
{columns.map(column => (
<ControlledCheckbox
checked={isSelected(
@ -167,8 +151,8 @@ const ColumnPickerContent: React.FC<ColumnPickerContentProps> = props => {
/>
))}
</div>
</InfiniteScroll>
</CardContent>
)}
<Hr />
<CardContent
className={classNames(classes.actionBarContainer, {

View file

@ -29,7 +29,7 @@ import { makeStyles } from "@saleor/theme";
import { ChannelProps, FetchMoreProps } from "@saleor/types";
import getOrderErrorMessage from "@saleor/utils/errors/order";
import React from "react";
import InfiniteScroll from "react-infinite-scroller";
import InfiniteScroll from "react-infinite-scroll-component";
import { FormattedMessage, useIntl } from "react-intl";
import {
@ -164,6 +164,8 @@ const onVariantAdd = (
)
: setVariants([...variants, variant]);
const scrollableTargetId = "orderProductAddScrollableDialog";
const OrderProductAddDialog: React.FC<OrderProductAddDialogProps> = props => {
const {
confirmButtonState,
@ -267,18 +269,18 @@ const OrderProductAddDialog: React.FC<OrderProductAddDialogProps> = props => {
}}
/>
</DialogContent>
<DialogContent className={classes.content}>
<DialogContent className={classes.content} id={scrollableTargetId}>
<InfiniteScroll
pageStart={0}
loadMore={onFetchMore}
dataLength={productChoicesWithValidVariants?.length}
next={onFetchMore}
hasMore={hasMore}
useWindow={false}
scrollThreshold="100px"
loader={
<div className={classes.loadMoreLoaderContainer}>
<CircularProgress size={16} />
</div>
}
threshold={10}
scrollableTarget={scrollableTargetId}
>
<ResponsiveTable key="table">
<TableBody>

View file

@ -27,7 +27,7 @@ import { makeStyles } from "@saleor/theme";
import { DialogProps, FetchMoreProps, SearchPageProps } from "@saleor/types";
import classNames from "classnames";
import React from "react";
import InfiniteScroll from "react-infinite-scroller";
import InfiniteScroll from "react-infinite-scroll-component";
import { FormattedMessage, useIntl } from "react-intl";
const useStyles = makeStyles(
@ -47,9 +47,10 @@ const useStyles = makeStyles(
width: 32
},
avatarDefault: {
"& p": {
"& div": {
color: "#fff",
lineHeight: "47px"
lineHeight: 2.8,
fontSize: "0.75rem"
},
background: theme.palette.primary.main,
height: 32,
@ -93,7 +94,11 @@ const useStyles = makeStyles(
scrollArea: {
maxHeight: 400,
overflowY: "scroll",
paddingTop: 0
paddingTop: 0,
paddingBottom: 0
},
table: {
marginBottom: theme.spacing(3)
},
statusText: {
color: "#9E9D9D"
@ -132,6 +137,8 @@ function handleStaffMemberAssign(
}
}
const scrollableTargetId = "assignMembersScrollableDialog";
const AssignMembersDialog: React.FC<AssignMembersDialogProps> = ({
confirmButtonState,
disabled,
@ -187,16 +194,23 @@ const AssignMembersDialog: React.FC<AssignMembersDialogProps> = ({
disabled={disabled}
/>
</DialogContent>
<DialogContent className={classes.scrollArea}>
<DialogContent className={classes.scrollArea} id={scrollableTargetId}>
<InfiniteScroll
pageStart={0}
loadMore={onFetchMore}
dataLength={staffMembers?.length}
next={onFetchMore}
hasMore={hasMore}
useWindow={false}
threshold={100}
key="infinite-scroll"
scrollThreshold="100px"
loader={
<>
{staffMembers?.length > 0 && <CardSpacer />}
<div className={classes.loadMoreLoaderContainer}>
<CircularProgress size={24} />
</div>
</>
}
scrollableTarget={scrollableTargetId}
>
<ResponsiveTable>
<ResponsiveTable className={classes.table}>
<TableBody>
{staffMembers &&
staffMembers.map(member => {
@ -267,14 +281,6 @@ const AssignMembersDialog: React.FC<AssignMembersDialogProps> = ({
})}
</TableBody>
</ResponsiveTable>
{loading && (
<>
{staffMembers?.length > 0 && <CardSpacer />}
<div className={classes.loadMoreLoaderContainer}>
<CircularProgress size={24} />
</div>
</>
)}
</InfiniteScroll>
</DialogContent>
<DialogActions

View file

@ -10,10 +10,8 @@ import PageHeader from "@saleor/components/PageHeader";
import { RefreshLimits_shop_limits } from "@saleor/components/Shop/types/RefreshLimits";
import { ProductListColumns } from "@saleor/config";
import { sectionNames } from "@saleor/intl";
import {
GridAttributes_availableInGrid_edges_node,
GridAttributes_grid_edges_node
} from "@saleor/products/types/GridAttributes";
import { AvailableInGridAttributes_availableInGrid_edges_node } from "@saleor/products/types/AvailableInGridAttributes";
import { GridAttributes_grid_edges_node } from "@saleor/products/types/GridAttributes";
import { ProductList_products_edges_node } from "@saleor/products/types/ProductList";
import { makeStyles } from "@saleor/theme";
import {
@ -44,7 +42,7 @@ export interface ProductListPageProps
SortPage<ProductListUrlSortField>,
ChannelProps {
activeAttributeSortId: string;
availableInGridAttributes: GridAttributes_availableInGrid_edges_node[];
availableInGridAttributes: AvailableInGridAttributes_availableInGrid_edges_node[];
channelsCount: number;
currencySymbol: string;
gridAttributes: GridAttributes_grid_edges_node[];
@ -163,7 +161,6 @@ export const ProductListPage: React.FC<ProductListPageProps> = props => {
columns={columns}
defaultColumns={defaultSettings.columns}
hasMore={hasMore}
loading={loading}
initialColumns={settings.columns}
total={
columns.length -

View file

@ -19,6 +19,10 @@ import {
} from "@saleor/products/types/ProductMediaById";
import gql from "graphql-tag";
import {
AvailableInGridAttributes,
AvailableInGridAttributesVariables
} from "./types/AvailableInGridAttributes";
import {
CreateMultipleVariantsData,
CreateMultipleVariantsDataVariables
@ -362,7 +366,7 @@ export const useProductMediaQuery = makeQuery<
const availableInGridAttributes = gql`
${pageInfoFragment}
query GridAttributes($first: Int!, $after: String, $ids: [ID!]!) {
query AvailableInGridAttributes($first: Int!, $after: String) {
availableInGrid: attributes(
first: $first
after: $after
@ -383,7 +387,15 @@ const availableInGridAttributes = gql`
}
totalCount
}
}
`;
export const useAvailableInGridAttributesQuery = makeQuery<
AvailableInGridAttributes,
AvailableInGridAttributesVariables
>(availableInGridAttributes);
const gridAttributes = gql`
query GridAttributes($ids: [ID!]!) {
grid: attributes(first: 25, filter: { ids: $ids }) {
edges {
node {
@ -394,10 +406,10 @@ const availableInGridAttributes = gql`
}
}
`;
export const useAvailableInGridAttributesQuery = makeQuery<
export const useGridAttributesQuery = makeQuery<
GridAttributes,
GridAttributesVariables
>(availableInGridAttributes);
>(gridAttributes);
const createMultipleVariantsData = gql`
${productVariantAttributesFragment}

View file

@ -0,0 +1,43 @@
/* tslint:disable */
/* eslint-disable */
// @generated
// This file was automatically generated and should not be edited.
// ====================================================
// GraphQL query operation: AvailableInGridAttributes
// ====================================================
export interface AvailableInGridAttributes_availableInGrid_edges_node {
__typename: "Attribute";
id: string;
name: string | null;
}
export interface AvailableInGridAttributes_availableInGrid_edges {
__typename: "AttributeCountableEdge";
node: AvailableInGridAttributes_availableInGrid_edges_node;
}
export interface AvailableInGridAttributes_availableInGrid_pageInfo {
__typename: "PageInfo";
endCursor: string | null;
hasNextPage: boolean;
hasPreviousPage: boolean;
startCursor: string | null;
}
export interface AvailableInGridAttributes_availableInGrid {
__typename: "AttributeCountableConnection";
edges: AvailableInGridAttributes_availableInGrid_edges[];
pageInfo: AvailableInGridAttributes_availableInGrid_pageInfo;
totalCount: number | null;
}
export interface AvailableInGridAttributes {
availableInGrid: AvailableInGridAttributes_availableInGrid | null;
}
export interface AvailableInGridAttributesVariables {
first: number;
after?: string | null;
}

View file

@ -7,32 +7,6 @@
// GraphQL query operation: GridAttributes
// ====================================================
export interface GridAttributes_availableInGrid_edges_node {
__typename: "Attribute";
id: string;
name: string | null;
}
export interface GridAttributes_availableInGrid_edges {
__typename: "AttributeCountableEdge";
node: GridAttributes_availableInGrid_edges_node;
}
export interface GridAttributes_availableInGrid_pageInfo {
__typename: "PageInfo";
endCursor: string | null;
hasNextPage: boolean;
hasPreviousPage: boolean;
startCursor: string | null;
}
export interface GridAttributes_availableInGrid {
__typename: "AttributeCountableConnection";
edges: GridAttributes_availableInGrid_edges[];
pageInfo: GridAttributes_availableInGrid_pageInfo;
totalCount: number | null;
}
export interface GridAttributes_grid_edges_node {
__typename: "Attribute";
id: string;
@ -50,12 +24,9 @@ export interface GridAttributes_grid {
}
export interface GridAttributes {
availableInGrid: GridAttributes_availableInGrid | null;
grid: GridAttributes_grid | null;
}
export interface GridAttributesVariables {
first: number;
after?: string | null;
ids: string[];
}

View file

@ -31,6 +31,7 @@ import {
} from "@saleor/products/components/ProductListPage/utils";
import {
useAvailableInGridAttributesQuery,
useGridAttributesQuery,
useInitialProductFilterAttributesQuery,
useInitialProductFilterCategoriesQuery,
useInitialProductFilterCollectionsQuery,
@ -319,8 +320,11 @@ export const ProductList: React.FC<ProductListProps> = ({ params }) => {
.filter(isAttributeColumnValue)
.map(getAttributeIdFromColumnValue);
}
const attributes = useAvailableInGridAttributesQuery({
variables: { first: 6, ids: filterColumnIds(settings.columns) }
const availableInGridAttributes = useAvailableInGridAttributesQuery({
variables: { first: 24 }
});
const gridAttributes = useGridAttributesQuery({
variables: { ids: filterColumnIds(settings.columns) }
});
const [
@ -376,21 +380,22 @@ export const ProductList: React.FC<ProductListProps> = ({ params }) => {
}}
onSort={handleSort}
availableInGridAttributes={mapEdgesToItems(
attributes?.data?.availableInGrid
availableInGridAttributes?.data?.availableInGrid
)}
currencySymbol={selectedChannel?.currencyCode || ""}
currentTab={currentTab}
defaultSettings={defaultListSettings[ListViews.PRODUCT_LIST]}
filterOpts={filterOpts}
gridAttributes={mapEdgesToItems(attributes?.data?.grid)}
gridAttributes={mapEdgesToItems(gridAttributes?.data?.grid)}
totalGridAttributes={maybe(
() => attributes.data.availableInGrid.totalCount,
() => availableInGridAttributes.data.availableInGrid.totalCount,
0
)}
settings={settings}
loading={attributes.loading}
loading={availableInGridAttributes.loading || gridAttributes.loading}
hasMore={maybe(
() => attributes.data.availableInGrid.pageInfo.hasNextPage,
() =>
availableInGridAttributes.data.availableInGrid.pageInfo.hasNextPage,
false
)}
onAdd={() => navigate(productAddUrl())}
@ -398,7 +403,7 @@ export const ProductList: React.FC<ProductListProps> = ({ params }) => {
limits={limitOpts.data?.shop.limits}
products={mapEdgesToItems(data?.products)}
onFetchMore={() =>
attributes.loadMore(
availableInGridAttributes.loadMore(
(prev, next) => {
if (
prev.availableInGrid.pageInfo.endCursor ===
@ -419,7 +424,9 @@ export const ProductList: React.FC<ProductListProps> = ({ params }) => {
};
},
{
after: attributes.data.availableInGrid.pageInfo.endCursor
after:
availableInGridAttributes.data.availableInGrid.pageInfo
.endCursor
}
)
}

View file

@ -26,7 +26,7 @@ import { makeStyles } from "@saleor/theme";
import { FetchMoreProps } from "@saleor/types";
import React from "react";
import { MutationFetchResult } from "react-apollo";
import InfiniteScroll from "react-infinite-scroller";
import InfiniteScroll from "react-infinite-scroll-component";
import { FormattedMessage, useIntl } from "react-intl";
const useStyles = makeStyles(
@ -89,6 +89,8 @@ const handleProductAssign = (
}
};
const scrollableTargetId = "shippingMethodProductsAddScrollableDialog";
const ShippingMethodProductsAddDialog: React.FC<ShippingMethodProductsAddDialogProps> = props => {
const {
confirmButtonState,
@ -154,18 +156,18 @@ const ShippingMethodProductsAddDialog: React.FC<ShippingMethodProductsAddDialogP
}}
/>
</DialogContent>
<DialogContent className={classes.content}>
<DialogContent className={classes.content} id={scrollableTargetId}>
<InfiniteScroll
pageStart={0}
loadMore={onFetchMore}
dataLength={products?.length}
next={onFetchMore}
hasMore={hasMore}
useWindow={false}
scrollThreshold="100px"
loader={
<div key="loader" className={classes.loadMoreLoaderContainer}>
<CircularProgress size={16} />
</div>
}
threshold={10}
scrollableTarget={scrollableTargetId}
>
<ResponsiveTable key="table">
<TableBody>

View file

@ -42,10 +42,5 @@ storiesOf("Generics / Column picker", module)
.addDecorator(Decorator)
.add("default", () => <ColumnPicker {...props} />)
.add("loading", () => (
<ColumnPicker
{...props}
loading={true}
hasMore={true}
onFetchMore={() => undefined}
/>
<ColumnPicker {...props} hasMore={true} onFetchMore={() => undefined} />
));

View file

@ -2,9 +2,6 @@ import { makeStyles } from "@saleor/theme";
const useScrollableDialogStyle = makeStyles(
theme => ({
content: {
overflowY: "hidden"
},
dialog: {
height: "calc(100% - 64px)",
maxHeight: 700
@ -16,8 +13,13 @@ const useScrollableDialogStyle = makeStyles(
justifyContent: "center",
marginTop: theme.spacing(3)
},
topArea: {
overflowY: "visible"
},
scrollArea: {
overflowY: "scroll"
overflowY: "scroll",
paddingTop: 0,
height: "inherit"
}
}),
{