Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Saleor 1712 dashboard unable to handle empty channel list #924

Merged
merged 13 commits into from
Jan 13, 2021
3 changes: 3 additions & 0 deletions locale/defaultMessages.json
Original file line number Diff line number Diff line change
Expand Up @@ -3012,6 +3012,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