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
5 changes: 5 additions & 0 deletions 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
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
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
80 changes: 47 additions & 33 deletions src/home/components/HomePage/HomePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,17 +46,19 @@ const useStyles = makeStyles(

export interface HomePageProps extends UserPermissionProps {
activities: Home_activities_edges_node[];
orders: number;
ordersToCapture: number;
ordersToFulfill: number;
orders: number | null;
ordersToCapture: number | null;
ordersToFulfill: number | null;
productsOutOfStock: number;
sales: Home_salesToday_gross;
topProducts: Home_productTopToday_edges_node[];
topProducts: Home_productTopToday_edges_node[] | null;
userName: string;
onCreateNewChannelClick: () => void;
onOrdersToCaptureClick: () => void;
onOrdersToFulfillClick: () => void;
onProductClick: (productId: string, variantId: string) => void;
onProductsOutOfStockClick: () => void;
noChannel: boolean;
}

const HomePage: React.FC<HomePageProps> = props => {
Expand All @@ -67,13 +69,15 @@ const HomePage: React.FC<HomePageProps> = props => {
topProducts,
onProductClick,
activities,
onCreateNewChannelClick,
onOrdersToCaptureClick,
onOrdersToFulfillClick,
onProductsOutOfStockClick,
ordersToCapture,
ordersToFulfill,
productsOutOfStock,
userPermissions
ordersToCapture = 0,
ordersToFulfill = 0,
productsOutOfStock = 0,
userPermissions = [],
noChannel
} = props;

const classes = useStyles(props);
Expand All @@ -99,7 +103,9 @@ const HomePage: React.FC<HomePageProps> = props => {
/>
}
>
{sales ? (
{noChannel ? (
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe if there are three outcomes here, it'd be worth to just move it to a function? Chaining conditions makes it less readable. Also, would rather see this in positive, like channelExists + negation

0
) : sales ? (
<Money money={sales} />
) : (
<Skeleton style={{ width: "5em" }} />
Expand All @@ -115,46 +121,54 @@ const HomePage: React.FC<HomePageProps> = props => {
/>
}
>
{orders === undefined ? (
<Skeleton style={{ width: "5em" }} />
) : (
{noChannel ? (
0
) : orders !== undefined ? (
orders
) : (
<Skeleton style={{ width: "5em" }} />
)}
</HomeAnalyticsCard>
</div>
</RequirePermissions>
<HomeNotificationTable
onCreateNewChannelClick={onCreateNewChannelClick}
onOrdersToCaptureClick={onOrdersToCaptureClick}
onOrdersToFulfillClick={onOrdersToFulfillClick}
onProductsOutOfStockClick={onProductsOutOfStockClick}
ordersToCapture={ordersToCapture}
ordersToFulfill={ordersToFulfill}
productsOutOfStock={productsOutOfStock}
userPermissions={userPermissions}
noChannel={noChannel}
/>
<CardSpacer />
<RequirePermissions
userPermissions={userPermissions}
requiredPermissions={[
PermissionEnum.MANAGE_ORDERS,
PermissionEnum.MANAGE_PRODUCTS
]}
>
<HomeProductListCard
onRowClick={onProductClick}
topProducts={topProducts}
/>
<CardSpacer />
</RequirePermissions>
</div>
<div>
<RequirePermissions
userPermissions={userPermissions}
requiredPermissions={[PermissionEnum.MANAGE_ORDERS]}
>
<HomeActivityCard activities={activities} />
</RequirePermissions>
{topProducts && (
<RequirePermissions
userPermissions={userPermissions}
requiredPermissions={[
PermissionEnum.MANAGE_ORDERS,
PermissionEnum.MANAGE_PRODUCTS
]}
>
<HomeProductListCard
onRowClick={onProductClick}
topProducts={topProducts}
/>
<CardSpacer />
</RequirePermissions>
)}
</div>
{activities && (
<div>
<RequirePermissions
userPermissions={userPermissions}
requiredPermissions={[PermissionEnum.MANAGE_ORDERS]}
>
<HomeActivityCard activities={activities} />
</RequirePermissions>
</div>
)}
</Grid>
</Container>
);
Expand Down
7 changes: 4 additions & 3 deletions src/home/queries.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import makeQuery from "@saleor/hooks/makeQuery";
import gql from "graphql-tag";

import { TypedQuery } from "../queries";
import { Home } from "./types/Home";
import { Home, HomeVariables } from "./types/Home";

const home = gql`
query Home($channel: String!) {
Expand Down Expand Up @@ -80,4 +80,5 @@ const home = gql`
}
}
`;
export const HomePageQuery = TypedQuery<Home, {}>(home);

export const useHomePage = makeQuery<Home, HomeVariables>(home);
Loading