Skip to content

Commit

Permalink
Fix infinite loading state in Discounts (#5099)
Browse files Browse the repository at this point in the history
Co-authored-by: Paweł Chyła <[email protected]>
  • Loading branch information
Cloud11PL and poulch committed Aug 12, 2024
1 parent 0614128 commit 5e3cc3f
Show file tree
Hide file tree
Showing 8 changed files with 45 additions and 29 deletions.
5 changes: 5 additions & 0 deletions .changeset/fresh-bikes-crash.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"saleor-dashboard": patch
---

You can now see a message instead of a loading animation when there are no categories, collections, products or variants assigned in Discounts
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ import TableHead from "@dashboard/components/TableHead";
import { TablePaginationWithContext } from "@dashboard/components/TablePagination";
import TableRowLink from "@dashboard/components/TableRowLink";
import { SaleDetailsFragment, VoucherDetailsFragment } from "@dashboard/graphql";
import { mapEdgesToItems } from "@dashboard/utils/maps";
import { getLoadableList, mapEdgesToItems } from "@dashboard/utils/maps";
import { TableBody, TableCell, TableFooter } from "@material-ui/core";
import { DeleteIcon, IconButton } from "@saleor/macaw-ui";
import { Skeleton } from "@saleor/macaw-ui-next";
import React from "react";
import { FormattedMessage, useIntl } from "react-intl";

import { maybe, renderCollection } from "../../../misc";
import { renderCollection } from "../../../misc";
import { ListActions, ListProps } from "../../../types";
import { messages } from "./messages";
import { useStyles } from "./styles";
Expand Down Expand Up @@ -87,7 +87,7 @@ const DiscountCategories: React.FC<DiscountCategoriesProps> = props => {
</TableFooter>
<TableBody data-test-id="assigned-specific-products-table">
{renderCollection(
mapEdgesToItems(discount?.categories),
getLoadableList(discount?.categories),
category => {
const isSelected = category ? isChecked(category.id) : false;

Expand All @@ -108,10 +108,8 @@ const DiscountCategories: React.FC<DiscountCategoriesProps> = props => {
onChange={() => toggle(category.id)}
/>
</TableCell>
<TableCell>{maybe<React.ReactNode>(() => category.name, <Skeleton />)}</TableCell>
<TableCell className={classes.colProducts}>
{maybe<React.ReactNode>(() => category.products.totalCount, <Skeleton />)}
</TableCell>
<TableCell>{category ? category.name : <Skeleton />}</TableCell>
<TableCell>{category ? category.products.totalCount : <Skeleton />}</TableCell>
<TableCell className={classes.colActions}>
<TableButtonWrapper>
<IconButton
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ import TableHead from "@dashboard/components/TableHead";
import { TablePaginationWithContext } from "@dashboard/components/TablePagination";
import TableRowLink from "@dashboard/components/TableRowLink";
import { SaleDetailsFragment, VoucherDetailsFragment } from "@dashboard/graphql";
import { mapEdgesToItems } from "@dashboard/utils/maps";
import { getLoadableList, mapEdgesToItems } from "@dashboard/utils/maps";
import { TableBody, TableCell, TableFooter } from "@material-ui/core";
import { DeleteIcon, IconButton } from "@saleor/macaw-ui";
import { Skeleton } from "@saleor/macaw-ui-next";
import React from "react";
import { FormattedMessage, useIntl } from "react-intl";

import { maybe, renderCollection } from "../../../misc";
import { renderCollection } from "../../../misc";
import { ListActions, ListProps } from "../../../types";
import { messages } from "./messages";
import { useStyles } from "./styles";
Expand Down Expand Up @@ -85,7 +85,7 @@ const DiscountCollections: React.FC<DiscountCollectionsProps> = props => {
</TableFooter>
<TableBody data-test-id="assigned-specific-products-table">
{renderCollection(
mapEdgesToItems(sale?.collections),
getLoadableList(sale?.collections),
collection => {
const isSelected = collection ? isChecked(collection.id) : false;

Expand All @@ -107,10 +107,10 @@ const DiscountCollections: React.FC<DiscountCollectionsProps> = props => {
/>
</TableCell>
<TableCell className={classes.colName}>
{maybe<React.ReactNode>(() => collection.name, <Skeleton />)}
{collection ? collection.name : <Skeleton />}
</TableCell>
<TableCell className={classes.colProducts}>
{maybe<React.ReactNode>(() => collection.products.totalCount, <Skeleton />)}
{collection ? collection.products.totalCount : <Skeleton />}
</TableCell>
<TableCell className={classes.colActions}>
<TableButtonWrapper>
Expand Down
17 changes: 9 additions & 8 deletions src/discounts/components/DiscountProducts/DiscountProducts.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,29 +11,28 @@ import { TablePaginationWithContext } from "@dashboard/components/TablePaginatio
import TableRowLink from "@dashboard/components/TableRowLink";
import { SaleDetailsFragment, VoucherDetailsFragment } from "@dashboard/graphql";
import { productUrl } from "@dashboard/products/urls";
import { getLoadableList, mapEdgesToItems } from "@dashboard/utils/maps";
import { TableBody, TableCell, TableFooter } from "@material-ui/core";
import { DeleteIcon, IconButton } from "@saleor/macaw-ui";
import { Skeleton } from "@saleor/macaw-ui-next";
import React from "react";
import { FormattedMessage, useIntl } from "react-intl";

import { maybe, renderCollection } from "../../../misc";
import { ListActions, ListProps, RelayToFlat } from "../../../types";
import { ListActions, ListProps } from "../../../types";
import { messages } from "./messages";
import { useStyles } from "./styles";

export interface SaleProductsProps extends ListProps, ListActions {
products:
| RelayToFlat<SaleDetailsFragment["products"]>
| RelayToFlat<VoucherDetailsFragment["products"]>;
discount: SaleDetailsFragment | VoucherDetailsFragment;
onProductAssign: () => void;
onProductUnassign: (id: string) => void;
}

const numberOfColumns = 5;
const DiscountProducts: React.FC<SaleProductsProps> = props => {
const {
products,
discount,
disabled,
onProductAssign,
onProductUnassign,
Expand All @@ -46,6 +45,8 @@ const DiscountProducts: React.FC<SaleProductsProps> = props => {
const classes = useStyles(props);
const intl = useIntl();

const productsList = mapEdgesToItems(discount?.products);

return (
<DashboardCard data-test-id="assign-product-section">
<DashboardCard.Header>
Expand All @@ -71,12 +72,12 @@ const DiscountProducts: React.FC<SaleProductsProps> = props => {
colSpan={numberOfColumns}
selected={selected}
disabled={disabled}
items={products}
items={productsList}
toggleAll={toggleAll}
toolbar={toolbar}
>
<TableCell className={classes.colName}>
<span className={products?.length > 0 && classes.colNameLabel}>
<span className={productsList?.length > 0 && classes.colNameLabel}>
<FormattedMessage {...messages.discountProductsTableProductHeader} />
</span>
</TableCell>
Expand All @@ -95,7 +96,7 @@ const DiscountProducts: React.FC<SaleProductsProps> = props => {
</TableFooter>
<TableBody data-test-id="assigned-specific-products-table">
{renderCollection(
products,
getLoadableList(discount?.products),
product => {
const isSelected = product ? isChecked(product.id) : false;

Expand Down
11 changes: 7 additions & 4 deletions src/discounts/components/DiscountVariants/DiscountVariants.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,27 +10,28 @@ import { TablePaginationWithContext } from "@dashboard/components/TablePaginatio
import TableRowLink from "@dashboard/components/TableRowLink";
import { SaleDetailsFragment } from "@dashboard/graphql";
import { productVariantEditPath } from "@dashboard/products/urls";
import { getLoadableList, mapEdgesToItems } from "@dashboard/utils/maps";
import { TableBody, TableCell, TableFooter } from "@material-ui/core";
import { DeleteIcon, IconButton } from "@saleor/macaw-ui";
import { Skeleton } from "@saleor/macaw-ui-next";
import React from "react";
import { FormattedMessage, useIntl } from "react-intl";

import { maybe, renderCollection } from "../../../misc";
import { ListActions, ListProps, RelayToFlat } from "../../../types";
import { ListActions, ListProps } from "../../../types";
import { messages } from "./messages";
import { useStyles } from "./styles";

export interface SaleVariantsProps extends ListProps, ListActions {
variants: RelayToFlat<SaleDetailsFragment["variants"]> | null;
discount: SaleDetailsFragment;
onVariantAssign: () => void;
onVariantUnassign: (id: string) => void;
}

const numberOfColumns = 5;
const DiscountVariants: React.FC<SaleVariantsProps> = props => {
const {
variants,
discount,
disabled,
onVariantAssign,
onVariantUnassign,
Expand All @@ -43,6 +44,8 @@ const DiscountVariants: React.FC<SaleVariantsProps> = props => {
const classes = useStyles(props);
const intl = useIntl();

const variants = mapEdgesToItems(discount?.variants);

return (
<DashboardCard>
<DashboardCard.Header>
Expand Down Expand Up @@ -91,7 +94,7 @@ const DiscountVariants: React.FC<SaleVariantsProps> = props => {
</TableFooter>
<TableBody>
{renderCollection(
variants,
getLoadableList(discount?.variants),
variant => {
const isSelected = variant ? isChecked(variant.id) : false;

Expand Down
6 changes: 3 additions & 3 deletions src/discounts/components/SaleDetailsPage/SaleDetailsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import {
} from "@dashboard/graphql";
import { SubmitPromise } from "@dashboard/hooks/useForm";
import useNavigator from "@dashboard/hooks/useNavigator";
import { mapEdgesToItems, mapMetadataItemToInput } from "@dashboard/utils/maps";
import { mapMetadataItemToInput } from "@dashboard/utils/maps";
import useMetadataChangeTrigger from "@dashboard/utils/metadata/useMetadataChangeTrigger";
import { sprinkles } from "@saleor/macaw-ui-next";
import React from "react";
Expand Down Expand Up @@ -249,7 +249,7 @@ const SaleDetailsPage: React.FC<SaleDetailsPageProps> = ({
disabled={disabled}
onProductAssign={onProductAssign}
onProductUnassign={onProductUnassign}
products={mapEdgesToItems(sale?.products)}
discount={sale}
isChecked={isChecked}
selected={selected}
toggle={toggle}
Expand All @@ -261,7 +261,7 @@ const SaleDetailsPage: React.FC<SaleDetailsPageProps> = ({
disabled={disabled}
onVariantAssign={onVariantAssign}
onVariantUnassign={onVariantUnassign}
variants={mapEdgesToItems(sale?.variants)}
discount={sale}
isChecked={isChecked}
selected={selected}
toggle={toggle}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import {
import { UseListSettings } from "@dashboard/hooks/useListSettings";
import { LocalPagination } from "@dashboard/hooks/useLocalPaginator";
import useNavigator from "@dashboard/hooks/useNavigator";
import { mapEdgesToItems, mapMetadataItemToInput } from "@dashboard/utils/maps";
import { mapMetadataItemToInput } from "@dashboard/utils/maps";
import useMetadataChangeTrigger from "@dashboard/utils/metadata/useMetadataChangeTrigger";
import { Text } from "@saleor/macaw-ui-next";
import React from "react";
Expand Down Expand Up @@ -324,7 +324,7 @@ const VoucherDetailsPage: React.FC<VoucherDetailsPageProps> = ({
disabled={disabled}
onProductAssign={onProductAssign}
onProductUnassign={onProductUnassign}
products={mapEdgesToItems(voucher?.products)}
discount={voucher}
isChecked={isChecked}
selected={selected}
toggle={toggle}
Expand Down
9 changes: 9 additions & 0 deletions src/utils/maps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,3 +127,12 @@ export function mapPersonNodeToChoice<T extends Person>(nodes: T[]): Option[] {
label: getFullName({ firstName, lastName }),
}));
}

export function getLoadableList<T>(data: Connection<T> | undefined | null): T[] | undefined {
// "undefined" is a loading state
if (typeof data === "undefined") {
return undefined;
}

return mapEdgesToItems(data) ?? [];
}

0 comments on commit 5e3cc3f

Please sign in to comment.