Skip to content

Commit

Permalink
Saleor 1712 dashboard unable to handle empty channel list (#924)
Browse files Browse the repository at this point in the history
* Use query hook on home page

* Handle no channel

* Handle no channel on pages

* Add navigate channels

* Move messages

* Refactor

* Update storybook and locale

* Remove comment

* Refactor

* Update storybook

* Fix skip

* Fix undefined channel

* Update storybook
  • Loading branch information
MarekChoinski authored Jan 13, 2021
1 parent 3f5cacb commit d0be941
Show file tree
Hide file tree
Showing 23 changed files with 272 additions and 406 deletions.
3 changes: 3 additions & 0 deletions locale/defaultMessages.json
Original file line number Diff line number Diff line change
Expand Up @@ -3023,6 +3023,9 @@
"src_dot_home_dot_components_dot_HomeActivityCard_dot_placed": {
"string": "Order #{orderId} was placed"
},
"src_dot_home_dot_components_dot_HomeNotificationTable_dot_createNewChannel": {
"string": "Create new channel"
},
"src_dot_hooks_dot_3382262667": {
"string": "Variant {name} has been set as default."
},
Expand Down
7 changes: 6 additions & 1 deletion src/categories/views/CategoryDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import DeleteIcon from "@material-ui/icons/Delete";
import ActionDialog from "@saleor/components/ActionDialog";
import useAppChannel from "@saleor/components/AppLayout/AppChannelContext";
import NotFoundPage from "@saleor/components/NotFoundPage";
import Skeleton from "@saleor/components/Skeleton";
import { WindowTitle } from "@saleor/components/WindowTitle";
import useBulkActions from "@saleor/hooks/useBulkActions";
import useNavigator from "@saleor/hooks/useNavigator";
Expand Down Expand Up @@ -207,6 +208,10 @@ export const CategoryDetails: React.FC<CategoryDetailsProps> = ({
variables => updatePrivateMetadata({ variables })
);

if (typeof channel === "undefined") {
return <Skeleton />;
}

return (
<>
<WindowTitle title={maybe(() => data.category.name)} />
Expand Down Expand Up @@ -256,7 +261,7 @@ export const CategoryDetails: React.FC<CategoryDetailsProps> = ({
data.category.products.edges.map(edge => edge.node)
)}
saveButtonBarState={updateResult.status}
selectedChannelId={channel.id}
selectedChannelId={channel?.id}
subcategories={maybe(() =>
data.category.children.edges.map(edge => edge.node)
)}
Expand Down
16 changes: 9 additions & 7 deletions src/collections/components/CollectionList/CollectionList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -146,8 +146,8 @@ const CollectionList: React.FC<CollectionListProps> = props => {
collections,
collection => {
const isSelected = collection ? isChecked(collection.id) : false;
const channel = collection?.channelListings.find(
listing => listing.channel.id === selectedChannelId
const channel = collection?.channelListings?.find(
listing => listing?.channel?.id === selectedChannelId
);
return (
<TableRow
Expand Down Expand Up @@ -184,11 +184,13 @@ const CollectionList: React.FC<CollectionListProps> = props => {
{collection && !collection?.channelListings?.length ? (
"-"
) : collection?.channelListings !== undefined ? (
<ChannelsAvailabilityDropdown
allChannelsCount={channelsCount}
currentChannel={channel}
channels={collection?.channelListings}
/>
channel ? (
<ChannelsAvailabilityDropdown
allChannelsCount={channelsCount}
currentChannel={channel}
channels={collection?.channelListings}
/>
) : null
) : (
<Skeleton />
)}
Expand Down
2 changes: 1 addition & 1 deletion src/collections/views/CollectionList/CollectionList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ export const CollectionList: React.FC<CollectionListProps> = ({ params }) => {
toggle={toggle}
toggleAll={toggleAll}
channelsCount={availableChannels?.length}
selectedChannelId={channel.id}
selectedChannelId={channel?.id}
/>
<ActionDialog
open={params.action === "remove" && maybe(() => params.ids.length > 0)}
Expand Down
9 changes: 6 additions & 3 deletions src/components/AppLayout/AppChannelContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export const AppChannelProvider: React.FC = ({ children }) => {
const { data: channelData, refetch } = useChannelsList({
skip: !isAuthenticated
});

const [isPickerActive, setPickerActive] = React.useState(false);
React.useEffect(() => {
if (!selectedChannel) {
Expand All @@ -38,9 +39,10 @@ export const AppChannelProvider: React.FC = ({ children }) => {
}, [channelData]);

const availableChannels = channelData?.channels || [];
const channel = availableChannels.find(
channel => channel.id === selectedChannel
);

const channel =
channelData &&
(availableChannels.find(channel => channel.id === selectedChannel) || null);

return (
<AppChannelContext.Provider
Expand All @@ -57,6 +59,7 @@ export const AppChannelProvider: React.FC = ({ children }) => {
</AppChannelContext.Provider>
);
};

AppChannelProvider.displayName = "AppChannelProvider";

function useAppChannel(enablePicker = true): UseAppChannel {
Expand Down
14 changes: 8 additions & 6 deletions src/components/AppLayout/AppLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -215,12 +215,14 @@ const AppLayout: React.FC<AppLayoutProps> = ({ children }) => {
.includes("mac")}
onClick={() => setNavigatorVisibility(true)}
/>
<AppChannelSelect
channels={availableChannels}
disabled={!isPickerActive}
selectedChannelId={channel.id}
onChannelSelect={setChannel}
/>
{channel && (
<AppChannelSelect
channels={availableChannels}
disabled={!isPickerActive}
selectedChannelId={channel.id}
onChannelSelect={setChannel}
/>
)}
<UserChip
isDarkThemeEnabled={isDark}
user={user}
Expand Down
2 changes: 1 addition & 1 deletion src/discounts/components/SaleCreatePage/SaleCreatePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ const SaleCreatePage: React.FC<SaleCreatePageProps> = ({
triggerChange
);
const formDisabled = data.channelListings?.some(channel =>
validatePrice(channel.discountValue)
validatePrice(channel?.discountValue)
);
return (
<Container>
Expand Down
6 changes: 3 additions & 3 deletions src/discounts/components/SaleSummary/SaleSummary.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,12 @@ const SaleSummary: React.FC<SaleSummaryProps> = ({
sale.type === SaleType.FIXED && channel?.discountValue ? (
<Money
money={{
amount: channel.discountValue,
currency: channel.currency
amount: channel?.discountValue,
currency: channel?.currency
}}
/>
) : channel?.discountValue ? (
<Percent amount={channel.discountValue} />
<Percent amount={channel?.discountValue} />
) : (
"-"
)
Expand Down
6 changes: 3 additions & 3 deletions src/discounts/components/VoucherSummary/VoucherSummary.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,12 @@ const VoucherSummary: React.FC<VoucherSummaryProps> = ({
channel?.discountValue ? (
<Money
money={{
amount: channel.discountValue,
currency: channel.channel.currencyCode
amount: channel?.discountValue,
currency: channel?.channel.currencyCode
}}
/>
) : channel?.discountValue ? (
<Percent amount={channel.discountValue} />
<Percent amount={channel?.discountValue} />
) : (
"-"
)
Expand Down
2 changes: 1 addition & 1 deletion src/discounts/views/SaleList/SaleList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ export const SaleList: React.FC<SaleListProps> = ({ params }) => {
<DeleteIcon />
</IconButton>
}
selectedChannelId={channel.id}
selectedChannelId={channel?.id}
/>
<ActionDialog
confirmButtonState={saleBulkDeleteOpts.status}
Expand Down
2 changes: 1 addition & 1 deletion src/discounts/views/VoucherDetails/VoucherDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ export const VoucherDetails: React.FC<VoucherDetailsProps> = ({
...(updateChannelsOpts.data
?.voucherChannelListingUpdate.errors || [])
]}
selectedChannelId={channel.id}
selectedChannelId={channel?.id}
pageInfo={pageInfo}
onNextPage={loadNextPage}
onPreviousPage={loadPreviousPage}
Expand Down
2 changes: 1 addition & 1 deletion src/discounts/views/VoucherList/VoucherList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ export const VoucherList: React.FC<VoucherListProps> = ({ params }) => {
<DeleteIcon />
</IconButton>
}
selectedChannelId={channel.id}
selectedChannelId={channel?.id}
/>
<ActionDialog
confirmButtonState={voucherBulkDeleteOpts.status}
Expand Down
100 changes: 65 additions & 35 deletions src/home/components/HomeNotificationTable/HomeNotificationTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,40 @@ import Skeleton from "@saleor/components/Skeleton";
import { UserPermissionProps } from "@saleor/types";
import { PermissionEnum } from "@saleor/types/globalTypes";
import React from "react";
import { FormattedMessage } from "react-intl";
import { defineMessages, useIntl } from "react-intl";

const messages = defineMessages({
createNewChannel: {
defaultMessage: "Create new channel"
},
noOrders: {
defaultMessage: "No orders ready to fulfill",
id: "homeNotificationTableNoOrders"
},
noPaymentWaiting: {
defaultMessage: "No payments waiting for capture",
id: "homeNotificationsNoPayments"
},
noProductsOut: {
defaultMessage: "No products out of stock",
id: "homeNotificationsTableNoProducts"
},
orderReady: {
defaultMessage:
"{amount, plural,one {One order is ready to fulfill} other {{amount} Orders are ready to fulfill}}",
id: "homeNotificationTableOrders"
},
paymentCapture: {
defaultMessage:
"{amount, plural,one {One payment to capture}other {{amount} Payments to capture}}",
id: "homeNotificationTablePayments"
},
productOut: {
defaultMessage:
"{amount, plural,one {One product out of stock}other {{amount} Products out of stock}}",
id: "homeNotificationTableProducts"
}
});

const useStyles = makeStyles(
() => ({
Expand All @@ -33,28 +66,46 @@ interface HomeNotificationTableProps extends UserPermissionProps {
ordersToCapture: number;
ordersToFulfill: number;
productsOutOfStock: number;
onCreateNewChannelClick: () => void;
onOrdersToFulfillClick: () => void;
onOrdersToCaptureClick: () => void;
onProductsOutOfStockClick: () => void;
noChannel: boolean;
}

const HomeNotificationTable: React.FC<HomeNotificationTableProps> = props => {
const {
onCreateNewChannelClick,
onOrdersToCaptureClick,
onOrdersToFulfillClick,
onProductsOutOfStockClick,
ordersToCapture,
ordersToFulfill,
productsOutOfStock,
userPermissions
userPermissions,
noChannel
} = props;

const classes = useStyles(props);

const intl = useIntl();

return (
<Card className={classes.tableCard}>
<ResponsiveTable>
<TableBody className={classes.tableRow}>
{noChannel && (
<TableRow hover={true} onClick={onCreateNewChannelClick}>
<TableCell>
<Typography>
{intl.formatMessage(messages.createNewChannel)}
</Typography>
</TableCell>
<TableCell className={classes.arrowIcon}>
<KeyboardArrowRight />
</TableCell>
</TableRow>
)}
<RequirePermissions
userPermissions={userPermissions}
requiredPermissions={[PermissionEnum.MANAGE_ORDERS]}
Expand All @@ -65,20 +116,13 @@ const HomeNotificationTable: React.FC<HomeNotificationTableProps> = props => {
<Skeleton />
) : ordersToFulfill === 0 ? (
<Typography>
<FormattedMessage
defaultMessage="No orders ready to fulfill"
id="homeNotificationTableNoOrders"
/>
{intl.formatMessage(messages.noOrders)}
</Typography>
) : (
<Typography>
<FormattedMessage
defaultMessage="{amount, plural,one {One order is ready to fulfill} other {{amount} Orders are ready to fulfill}}"
id="homeNotificationTableOrders"
values={{
amount: <strong>{ordersToFulfill}</strong>
}}
/>
{intl.formatMessage(messages.orderReady, {
amount: <strong>{ordersToFulfill}</strong>
})}
</Typography>
)}
</TableCell>
Expand All @@ -92,20 +136,13 @@ const HomeNotificationTable: React.FC<HomeNotificationTableProps> = props => {
<Skeleton />
) : ordersToCapture === 0 ? (
<Typography>
<FormattedMessage
defaultMessage="No payments waiting for capture"
id="homeNotificationsNoPayments"
/>
{intl.formatMessage(messages.noPaymentWaiting)}
</Typography>
) : (
<Typography>
<FormattedMessage
defaultMessage="{amount, plural,one {One payment to capture}other {{amount} Payments to capture}}"
id="homeNotificationTablePayments"
values={{
amount: <strong>{ordersToCapture}</strong>
}}
/>
{intl.formatMessage(messages.paymentCapture, {
amount: <strong>{ordersToCapture}</strong>
})}
</Typography>
)}
</TableCell>
Expand All @@ -124,20 +161,13 @@ const HomeNotificationTable: React.FC<HomeNotificationTableProps> = props => {
<Skeleton />
) : productsOutOfStock === 0 ? (
<Typography>
<FormattedMessage
defaultMessage="No products out of stock"
id="homeNotificationsTableNoProducts"
/>
{intl.formatMessage(messages.noProductsOut)}
</Typography>
) : (
<Typography>
<FormattedMessage
defaultMessage="{amount, plural,one {One product out of stock}other {{amount} Products out of stock}}"
id="homeNotificationTableProducts"
values={{
amount: <strong>{productsOutOfStock}</strong>
}}
/>
{intl.formatMessage(messages.productOut, {
amount: <strong>{productsOutOfStock}</strong>
})}
</Typography>
)}
</TableCell>
Expand Down
Loading

0 comments on commit d0be941

Please sign in to comment.