Improve limit messages (#1274)

This commit is contained in:
Dominik Żegleń 2021-08-10 10:59:15 +02:00 committed by GitHub
parent 034eea0dcd
commit 6d3e346a19
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 1762 additions and 59 deletions

View file

@ -56,12 +56,18 @@ export const ChannelsListPage: React.FC<ChannelsListPageProps> = ({
</Backlink>
<PageHeader
title={intl.formatMessage(sectionNames.channels)}
limit={
hasLimits(limits, "channels") && {
data: limits,
key: "channels",
text: "channels used"
}
limitText={
hasLimits(limits, "channels") &&
intl.formatMessage(
{
defaultMessage: "{count}/{max} channels used",
description: "created channels counter"
},
{
count: limits.currentUsage.channels,
max: limits.allowedUsage.channels
}
)
}
>
<Button

View file

@ -1,10 +1,8 @@
import { Typography } from "@material-ui/core";
import { LimitInfoFragment } from "@saleor/fragments/types/LimitInfoFragment";
import { makeStyles } from "@saleor/macaw-ui";
import React from "react";
import ExtendedPageHeader from "../ExtendedPageHeader";
import { RefreshLimits_shop_limits } from "../Shop/types/RefreshLimits";
import Skeleton from "../Skeleton";
const useStyles = makeStyles(
@ -40,27 +38,16 @@ const useStyles = makeStyles(
{ name: "PageHeader" }
);
interface LimitInfo {
data: RefreshLimits_shop_limits;
key: keyof LimitInfoFragment;
text: string;
}
interface PageHeaderProps {
children?: React.ReactNode;
className?: string;
inline?: boolean;
limit?: LimitInfo;
limitText?: string;
title?: React.ReactNode;
}
function formatLimit(limit: LimitInfo): string {
return `${limit.data.currentUsage[limit.key]}/${
limit.data.allowedUsage[limit.key]
} ${limit.text}`;
}
const PageHeader: React.FC<PageHeaderProps> = props => {
const { children, className, inline, limit, title } = props;
const { children, className, inline, limitText, title } = props;
const classes = useStyles(props);
@ -76,9 +63,9 @@ const PageHeader: React.FC<PageHeaderProps> = props => {
}
>
<div className={classes.root}>
{limit && (
{limitText && (
<Typography className={classes.limit} color="textSecondary">
{formatLimit(limit)}
{limitText}
</Typography>
)}
{children}

View file

@ -2,6 +2,7 @@ import { Button, Card } from "@material-ui/core";
import Container from "@saleor/components/Container";
import FilterBar from "@saleor/components/FilterBar";
import PageHeader from "@saleor/components/PageHeader";
import { RefreshLimits_shop_limits } from "@saleor/components/Shop/types/RefreshLimits";
import { sectionNames } from "@saleor/intl";
import { OrderDraftListUrlSortField } from "@saleor/orders/urls";
import {
@ -11,11 +12,13 @@ import {
SortPage,
TabPageProps
} from "@saleor/types";
import { hasLimits, isLimitReached } from "@saleor/utils/limits";
import React from "react";
import { FormattedMessage, useIntl } from "react-intl";
import { OrderDraftList_draftOrders_edges_node } from "../../types/OrderDraftList";
import OrderDraftList from "../OrderDraftList";
import OrderLimitReached from "../OrderLimitReached";
import {
createFilterStructure,
OrderDraftFilterKeys,
@ -28,6 +31,7 @@ export interface OrderDraftListPageProps
FilterPageProps<OrderDraftFilterKeys, OrderDraftListFilterOpts>,
SortPage<OrderDraftListUrlSortField>,
TabPageProps {
limits: RefreshLimits_shop_limits;
orders: OrderDraftList_draftOrders_edges_node[];
}
@ -36,6 +40,7 @@ const OrderDraftListPage: React.FC<OrderDraftListPageProps> = ({
disabled,
filterOpts,
initialSearch,
limits,
onAdd,
onAll,
onFilterChange,
@ -48,14 +53,30 @@ const OrderDraftListPage: React.FC<OrderDraftListPageProps> = ({
}) => {
const intl = useIntl();
const structure = createFilterStructure(intl, filterOpts);
const limitsReached = isLimitReached(limits, "orders");
return (
<Container>
<PageHeader title={intl.formatMessage(sectionNames.draftOrders)}>
<PageHeader
title={intl.formatMessage(sectionNames.draftOrders)}
limitText={
hasLimits(limits, "orders") &&
intl.formatMessage(
{
defaultMessage: "{count}/{max} orders",
description: "placed orders counter"
},
{
count: limits.currentUsage.orders,
max: limits.allowedUsage.orders
}
)
}
>
<Button
color="primary"
variant="contained"
disabled={disabled}
disabled={disabled || limitsReached}
onClick={onAdd}
>
<FormattedMessage
@ -64,6 +85,7 @@ const OrderDraftListPage: React.FC<OrderDraftListPageProps> = ({
/>
</Button>
</PageHeader>
{limitsReached && <OrderLimitReached />}
<Card>
<FilterBar
allTabLabel={intl.formatMessage({

View file

@ -0,0 +1,21 @@
import LimitReachedAlert from "@saleor/components/LimitReachedAlert";
import React from "react";
import { FormattedMessage, useIntl } from "react-intl";
export const OrderLimitReached: React.FC = () => {
const intl = useIntl();
return (
<LimitReachedAlert
title={intl.formatMessage({
defaultMessage: "Order limit reached",
description: "alert"
})}
>
<FormattedMessage defaultMessage="You have reached your order limit, you will be billed extra for orders above limit. If you would like to up your limit, contact your administration staff about raising your limits." />
</LimitReachedAlert>
);
};
OrderLimitReached.displayName = "OrderLimitReached";
export default OrderLimitReached;

View file

@ -2,18 +2,18 @@ import { Button, Card } from "@material-ui/core";
import CardMenu from "@saleor/components/CardMenu";
import Container from "@saleor/components/Container";
import FilterBar from "@saleor/components/FilterBar";
import LimitReachedAlert from "@saleor/components/LimitReachedAlert";
import PageHeader from "@saleor/components/PageHeader";
import { RefreshLimits_shop_limits } from "@saleor/components/Shop/types/RefreshLimits";
import { sectionNames } from "@saleor/intl";
import { makeStyles } from "@saleor/macaw-ui";
import { OrderListUrlSortField } from "@saleor/orders/urls";
import { FilterPageProps, PageListProps, SortPage } from "@saleor/types";
import { isLimitReached } from "@saleor/utils/limits";
import { hasLimits, isLimitReached } from "@saleor/utils/limits";
import React from "react";
import { FormattedMessage, useIntl } from "react-intl";
import { OrderList_orders_edges_node } from "../../types/OrderList";
import OrderLimitReached from "../OrderLimitReached";
import OrderList from "../OrderList";
import {
createFilterStructure,
@ -58,10 +58,26 @@ const OrderListPage: React.FC<OrderListPageProps> = ({
const intl = useIntl();
const classes = useStyles({});
const filterStructure = createFilterStructure(intl, filterOpts);
const limitsReached = isLimitReached(limits, "orders");
return (
<Container>
<PageHeader title={intl.formatMessage(sectionNames.orders)}>
<PageHeader
title={intl.formatMessage(sectionNames.orders)}
limitText={
hasLimits(limits, "orders") &&
intl.formatMessage(
{
defaultMessage: "{count}/{max} orders",
description: "placed order counter"
},
{
count: limits.currentUsage.orders,
max: limits.allowedUsage.orders
}
)
}
>
{!!onSettingsOpen && (
<CardMenu
className={classes.settings}
@ -77,6 +93,7 @@ const OrderListPage: React.FC<OrderListPageProps> = ({
/>
)}
<Button
disabled={limitsReached}
color="primary"
variant="contained"
onClick={onAdd}
@ -88,16 +105,7 @@ const OrderListPage: React.FC<OrderListPageProps> = ({
/>
</Button>
</PageHeader>
{isLimitReached(limits, "orders") && (
<LimitReachedAlert
title={intl.formatMessage({
defaultMessage: "Order limit reached",
description: "alert"
})}
>
<FormattedMessage defaultMessage="You have reached your order limit, you will be billed extra for orders above limit. If you would like to up your limit, contact your administration staff about raising your limits." />
</LimitReachedAlert>
)}
{limitsReached && <OrderLimitReached />}
<Card>
<FilterBar
currentTab={currentTab}

View file

@ -7,6 +7,7 @@ import DeleteFilterTabDialog from "@saleor/components/DeleteFilterTabDialog";
import SaveFilterTabDialog, {
SaveFilterTabDialogFormData
} from "@saleor/components/SaveFilterTabDialog";
import { useShopLimitsQuery } from "@saleor/components/Shop/query";
import useBulkActions from "@saleor/hooks/useBulkActions";
import useListSettings from "@saleor/hooks/useListSettings";
import useNavigator from "@saleor/hooks/useNavigator";
@ -81,6 +82,11 @@ export const OrderDraftList: React.FC<OrderDraftListProps> = ({ params }) => {
});
const { channel, availableChannels } = useAppChannel();
const limitOpts = useShopLimitsQuery({
variables: {
orders: true
}
});
const tabs = getFilterTabs();
@ -183,6 +189,7 @@ export const OrderDraftList: React.FC<OrderDraftListProps> = ({ params }) => {
<OrderDraftListPage
currentTab={currentTab}
filterOpts={getFilterOpts(params)}
limits={limitOpts.data?.shop.limits}
initialSearch={params.query || ""}
onSearchChange={handleSearchChange}
onFilterChange={changeFilters}

View file

@ -134,12 +134,18 @@ export const ProductListPage: React.FC<ProductListPageProps> = props => {
<Container>
<PageHeader
title={intl.formatMessage(sectionNames.products)}
limit={
hasLimits(limits, "productVariants") && {
data: limits,
key: "productVariants",
text: "SKUs used"
}
limitText={
hasLimits(limits, "productVariants") &&
intl.formatMessage(
{
defaultMessage: "{count}/{max} SKUs used",
description: "created products counter"
},
{
count: limits.currentUsage.productVariants,
max: limits.allowedUsage.productVariants
}
)
}
>
<CardMenu

View file

@ -64,12 +64,18 @@ const StaffListPage: React.FC<StaffListPageProps> = ({
</Backlink>
<PageHeader
title={intl.formatMessage(sectionNames.staff)}
limit={
hasLimits(limits, "staffUsers") && {
data: limits,
key: "staffUsers",
text: "members"
}
limitText={
hasLimits(limits, "staffUsers") &&
intl.formatMessage(
{
defaultMessage: "{count}/{max} members",
description: "used staff users counter"
},
{
count: limits.currentUsage.staffUsers,
max: limits.allowedUsage.staffUsers
}
)
}
>
<Button

File diff suppressed because it is too large Load diff

View file

@ -4,6 +4,8 @@ import React from "react";
import {
filterPageProps,
limits,
limitsReached,
listActionsProps,
pageListProps,
searchPageProps,
@ -36,6 +38,7 @@ const props: OrderDraftListPageProps = {
value: undefined
}
},
limits,
onAdd: () => undefined,
orders,
sort: {
@ -50,4 +53,7 @@ storiesOf("Views / Orders / Draft order list", module)
.add("loading", () => (
<OrderDraftListPage {...props} disabled orders={undefined} />
))
.add("when no data", () => <OrderDraftListPage {...props} orders={[]} />);
.add("when no data", () => <OrderDraftListPage {...props} orders={[]} />)
.add("limits reached", () => (
<OrderDraftListPage {...props} limits={limitsReached} />
));

View file

@ -65,12 +65,18 @@ export const WarehouseListPage: React.FC<WarehouseListPageProps> = ({
</Backlink>
<PageHeader
title={intl.formatMessage(sectionNames.warehouses)}
limit={
hasLimits(limits, "warehouses") && {
data: limits,
key: "warehouses",
text: "warehouses used"
}
limitText={
hasLimits(limits, "warehouses") &&
intl.formatMessage(
{
defaultMessage: "{count}/{max} warehouses used",
description: "used warehouses counter"
},
{
count: limits.currentUsage.warehouses,
max: limits.allowedUsage.warehouses
}
)
}
>
<Button