From 9775e60b9999d0ed8b6b77f1e4ad36af174faece Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Chy=C5=82a?= Date: Mon, 6 Nov 2023 12:31:45 +0100 Subject: [PATCH 01/13] Extract activities --- src/graphql/hooks.generated.ts | 63 ++++++++--- src/graphql/types.generated.ts | 7 +- .../HomeActivityCard/HomeActivityCard.tsx | 107 ++++++++++-------- src/home/components/HomePage/HomePage.tsx | 6 +- src/home/queries.ts | 8 +- src/home/types.ts | 6 +- src/home/views/index.tsx | 30 +++-- 7 files changed, 148 insertions(+), 79 deletions(-) diff --git a/src/graphql/hooks.generated.ts b/src/graphql/hooks.generated.ts index b735fb5fe52..971abb8c209 100644 --- a/src/graphql/hooks.generated.ts +++ b/src/graphql/hooks.generated.ts @@ -8835,7 +8835,42 @@ export const HomeDocument = gql` } } } - activities: homepageEvents(last: 10) @include(if: $hasPermissionToManageOrders) { +} + `; + +/** + * __useHomeQuery__ + * + * To run a query within a React component, call `useHomeQuery` and pass it any options that fit your needs. + * When your component renders, `useHomeQuery` returns an object from Apollo Client that contains loading, error, and data properties + * you can use to render your UI. + * + * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; + * + * @example + * const { data, loading, error } = useHomeQuery({ + * variables: { + * channel: // value for 'channel' + * datePeriod: // value for 'datePeriod' + * hasPermissionToManageProducts: // value for 'hasPermissionToManageProducts' + * hasPermissionToManageOrders: // value for 'hasPermissionToManageOrders' + * }, + * }); + */ +export function useHomeQuery(baseOptions: ApolloReactHooks.QueryHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return ApolloReactHooks.useQuery(HomeDocument, options); + } +export function useHomeLazyQuery(baseOptions?: ApolloReactHooks.LazyQueryHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return ApolloReactHooks.useLazyQuery(HomeDocument, options); + } +export type HomeQueryHookResult = ReturnType; +export type HomeLazyQueryHookResult = ReturnType; +export type HomeQueryResult = Apollo.QueryResult; +export const HomeActivitiesDocument = gql` + query HomeActivities { + activities: homepageEvents(last: 10) { edges { node { amount @@ -8860,35 +8895,31 @@ export const HomeDocument = gql` `; /** - * __useHomeQuery__ + * __useHomeActivitiesQuery__ * - * To run a query within a React component, call `useHomeQuery` and pass it any options that fit your needs. - * When your component renders, `useHomeQuery` returns an object from Apollo Client that contains loading, error, and data properties + * To run a query within a React component, call `useHomeActivitiesQuery` and pass it any options that fit your needs. + * When your component renders, `useHomeActivitiesQuery` returns an object from Apollo Client that contains loading, error, and data properties * you can use to render your UI. * * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; * * @example - * const { data, loading, error } = useHomeQuery({ + * const { data, loading, error } = useHomeActivitiesQuery({ * variables: { - * channel: // value for 'channel' - * datePeriod: // value for 'datePeriod' - * hasPermissionToManageProducts: // value for 'hasPermissionToManageProducts' - * hasPermissionToManageOrders: // value for 'hasPermissionToManageOrders' * }, * }); */ -export function useHomeQuery(baseOptions: ApolloReactHooks.QueryHookOptions) { +export function useHomeActivitiesQuery(baseOptions?: ApolloReactHooks.QueryHookOptions) { const options = {...defaultOptions, ...baseOptions} - return ApolloReactHooks.useQuery(HomeDocument, options); + return ApolloReactHooks.useQuery(HomeActivitiesDocument, options); } -export function useHomeLazyQuery(baseOptions?: ApolloReactHooks.LazyQueryHookOptions) { +export function useHomeActivitiesLazyQuery(baseOptions?: ApolloReactHooks.LazyQueryHookOptions) { const options = {...defaultOptions, ...baseOptions} - return ApolloReactHooks.useLazyQuery(HomeDocument, options); + return ApolloReactHooks.useLazyQuery(HomeActivitiesDocument, options); } -export type HomeQueryHookResult = ReturnType; -export type HomeLazyQueryHookResult = ReturnType; -export type HomeQueryResult = Apollo.QueryResult; +export type HomeActivitiesQueryHookResult = ReturnType; +export type HomeActivitiesLazyQueryHookResult = ReturnType; +export type HomeActivitiesQueryResult = Apollo.QueryResult; export const MenuCreateDocument = gql` mutation MenuCreate($input: MenuCreateInput!) { menuCreate(input: $input) { diff --git a/src/graphql/types.generated.ts b/src/graphql/types.generated.ts index 4d1f7e9adbd..d0cb39ad743 100644 --- a/src/graphql/types.generated.ts +++ b/src/graphql/types.generated.ts @@ -10190,7 +10190,12 @@ export type HomeQueryVariables = Exact<{ }>; -export type HomeQuery = { __typename: 'Query', salesToday: { __typename: 'TaxedMoney', gross: { __typename: 'Money', amount: number, currency: string } } | null, ordersToday: { __typename: 'OrderCountableConnection', totalCount: number | null } | null, ordersToFulfill: { __typename: 'OrderCountableConnection', totalCount: number | null } | null, ordersToCapture: { __typename: 'OrderCountableConnection', totalCount: number | null } | null, productsOutOfStock: { __typename: 'ProductCountableConnection', totalCount: number | null } | null, productTopToday: { __typename: 'ProductVariantCountableConnection', edges: Array<{ __typename: 'ProductVariantCountableEdge', node: { __typename: 'ProductVariant', id: string, quantityOrdered: number | null, revenue: { __typename: 'TaxedMoney', gross: { __typename: 'Money', amount: number, currency: string } } | null, attributes: Array<{ __typename: 'SelectedAttribute', values: Array<{ __typename: 'AttributeValue', id: string, name: string | null }> }>, product: { __typename: 'Product', id: string, name: string, thumbnail: { __typename: 'Image', url: string } | null } } }> } | null, activities: { __typename: 'OrderEventCountableConnection', edges: Array<{ __typename: 'OrderEventCountableEdge', node: { __typename: 'OrderEvent', amount: number | null, composedId: string | null, date: any | null, email: string | null, emailType: OrderEventsEmailsEnum | null, id: string, message: string | null, orderNumber: string | null, oversoldItems: Array | null, quantity: number | null, type: OrderEventsEnum | null, user: { __typename: 'User', id: string, email: string } | null } }> } | null }; +export type HomeQuery = { __typename: 'Query', salesToday: { __typename: 'TaxedMoney', gross: { __typename: 'Money', amount: number, currency: string } } | null, ordersToday: { __typename: 'OrderCountableConnection', totalCount: number | null } | null, ordersToFulfill: { __typename: 'OrderCountableConnection', totalCount: number | null } | null, ordersToCapture: { __typename: 'OrderCountableConnection', totalCount: number | null } | null, productsOutOfStock: { __typename: 'ProductCountableConnection', totalCount: number | null } | null, productTopToday: { __typename: 'ProductVariantCountableConnection', edges: Array<{ __typename: 'ProductVariantCountableEdge', node: { __typename: 'ProductVariant', id: string, quantityOrdered: number | null, revenue: { __typename: 'TaxedMoney', gross: { __typename: 'Money', amount: number, currency: string } } | null, attributes: Array<{ __typename: 'SelectedAttribute', values: Array<{ __typename: 'AttributeValue', id: string, name: string | null }> }>, product: { __typename: 'Product', id: string, name: string, thumbnail: { __typename: 'Image', url: string } | null } } }> } | null }; + +export type HomeActivitiesQueryVariables = Exact<{ [key: string]: never; }>; + + +export type HomeActivitiesQuery = { __typename: 'Query', activities: { __typename: 'OrderEventCountableConnection', edges: Array<{ __typename: 'OrderEventCountableEdge', node: { __typename: 'OrderEvent', amount: number | null, composedId: string | null, date: any | null, email: string | null, emailType: OrderEventsEmailsEnum | null, id: string, message: string | null, orderNumber: string | null, oversoldItems: Array | null, quantity: number | null, type: OrderEventsEnum | null, user: { __typename: 'User', id: string, email: string } | null } }> } | null }; export type MenuCreateMutationVariables = Exact<{ input: MenuCreateInput; diff --git a/src/home/components/HomeActivityCard/HomeActivityCard.tsx b/src/home/components/HomeActivityCard/HomeActivityCard.tsx index 7877d1bd29c..3e9517403e0 100644 --- a/src/home/components/HomeActivityCard/HomeActivityCard.tsx +++ b/src/home/components/HomeActivityCard/HomeActivityCard.tsx @@ -1,8 +1,7 @@ import { DashboardCard } from "@dashboard/components/Card"; import { DateTime } from "@dashboard/components/Date"; -import Skeleton from "@dashboard/components/Skeleton"; import { Activities } from "@dashboard/home/types"; -import { Box, List, Text, useTheme } from "@saleor/macaw-ui-next"; +import { Box, List, Skeleton, Text, useTheme } from "@saleor/macaw-ui-next"; import React from "react"; import { FormattedMessage, useIntl } from "react-intl"; @@ -10,7 +9,11 @@ import { renderCollection } from "../../../misc"; import { getActivityMessage } from "./activityMessages"; interface HomeActivityCardProps { - activities: Activities; + activities: { + data: Activities; + loading: boolean; + error: any; + }; testId?: string; } @@ -31,53 +34,57 @@ export const HomeActivityCard = ({ })} - - {renderCollection( - activities, - (activity, activityId) => ( - - {activity ? ( - <> - - {getActivityMessage(activity, intl)} - - - - - - ) : ( - - - - )} - - ), - () => ( - - - - - - ), - )} - + {activities.loading ? ( + + ) : ( + + {renderCollection( + activities.data, + (activity, activityId) => ( + + {activity ? ( + <> + + {getActivityMessage(activity, intl)} + + + + + + ) : ( + + + + )} + + ), + () => ( + + + + + + ), + )} + + )} ); diff --git a/src/home/components/HomePage/HomePage.tsx b/src/home/components/HomePage/HomePage.tsx index 6ac5b2a0821..8443d3926b0 100644 --- a/src/home/components/HomePage/HomePage.tsx +++ b/src/home/components/HomePage/HomePage.tsx @@ -18,7 +18,11 @@ import { HomeProductList } from "../HomeProductList"; import { homePageMessages } from "./messages"; export interface HomePageProps { - activities: Activities; + activities: { + data: Activities; + loading: boolean; + error: any; + }; orders: number | null; ordersToCapture: number | null; ordersToFulfill: number | null; diff --git a/src/home/queries.ts b/src/home/queries.ts index de097bfa358..8563fdfc4ca 100644 --- a/src/home/queries.ts +++ b/src/home/queries.ts @@ -67,8 +67,12 @@ export const home = gql` } } } - activities: homepageEvents(last: 10) - @include(if: $hasPermissionToManageOrders) { + } +`; + +export const homeActivities = gql` + query HomeActivities { + activities: homepageEvents(last: 10) { edges { node { amount diff --git a/src/home/types.ts b/src/home/types.ts index aca07b69469..6a2846647a7 100644 --- a/src/home/types.ts +++ b/src/home/types.ts @@ -1,7 +1,9 @@ -import { HomeQuery } from "@dashboard/graphql"; +import { HomeActivitiesQuery, HomeQuery } from "@dashboard/graphql"; import { RelayToFlat } from "@dashboard/types"; -export type Activities = RelayToFlat>; +export type Activities = RelayToFlat< + NonNullable +>; export type ProductTopToday = RelayToFlat< NonNullable >; diff --git a/src/home/views/index.tsx b/src/home/views/index.tsx index 30e815a8b27..b618983dba4 100644 --- a/src/home/views/index.tsx +++ b/src/home/views/index.tsx @@ -7,6 +7,7 @@ import { OrderStatusFilter, PermissionEnum, StockAvailability, + useHomeActivitiesQuery, useHomeQuery, } from "@dashboard/graphql"; import { mapEdgesToItems } from "@dashboard/utils/maps"; @@ -24,6 +25,21 @@ const HomeSection = () => { const noChannel = !channel && typeof channel !== "undefined"; const userPermissions = user?.userPermissions || []; + const hasPermissionToManageOrders = hasPermissions(userPermissions, [ + PermissionEnum.MANAGE_ORDERS, + ]); + const hasPermissionToManageProducts = hasPermissions(userPermissions, [ + PermissionEnum.MANAGE_PRODUCTS, + ]); + + const { + data: homeActivities, + loading: homeActivitiesLoading, + error: homeActivitiesError, + } = useHomeActivitiesQuery({ + displayLoader: true, + skip: noChannel || !hasPermissionToManageOrders, + }); const { data } = useHomeQuery({ displayLoader: true, @@ -31,18 +47,18 @@ const HomeSection = () => { variables: { channel: channel?.slug, datePeriod: getDatePeriod(1), - hasPermissionToManageOrders: hasPermissions(userPermissions, [ - PermissionEnum.MANAGE_ORDERS, - ]), - hasPermissionToManageProducts: hasPermissions(userPermissions, [ - PermissionEnum.MANAGE_PRODUCTS, - ]), + hasPermissionToManageOrders, + hasPermissionToManageProducts, }, }); return ( Date: Mon, 6 Nov 2023 12:47:23 +0100 Subject: [PATCH 02/13] Extract top products --- src/graphql/hooks.generated.ts | 89 +++++++++++++------ src/graphql/types.generated.ts | 10 ++- src/home/components/HomePage/HomePage.tsx | 6 +- .../HomeProductList/HomeProductList.tsx | 26 +++++- src/home/queries.ts | 60 +++++++------ src/home/views/index.tsx | 20 ++++- 6 files changed, 145 insertions(+), 66 deletions(-) diff --git a/src/graphql/hooks.generated.ts b/src/graphql/hooks.generated.ts index 971abb8c209..b77b304b17b 100644 --- a/src/graphql/hooks.generated.ts +++ b/src/graphql/hooks.generated.ts @@ -8786,7 +8786,7 @@ export type CustomerGiftCardListQueryHookResult = ReturnType; export type CustomerGiftCardListQueryResult = Apollo.QueryResult; export const HomeDocument = gql` - query Home($channel: String!, $datePeriod: DateRangeInput!, $hasPermissionToManageProducts: Boolean!, $hasPermissionToManageOrders: Boolean!) { + query Home($channel: String!, $datePeriod: DateRangeInput!, $hasPermissionToManageOrders: Boolean!) { salesToday: ordersTotal(period: TODAY, channel: $channel) @include(if: $hasPermissionToManageOrders) { gross { amount @@ -8808,33 +8808,6 @@ export const HomeDocument = gql` ) { totalCount } - productTopToday: reportProductSales(period: TODAY, first: 5, channel: $channel) @include(if: $hasPermissionToManageProducts) { - edges { - node { - id - revenue(period: TODAY) { - gross { - amount - currency - } - } - attributes { - values { - id - name - } - } - product { - id - name - thumbnail { - url - } - } - quantityOrdered - } - } - } } `; @@ -8852,7 +8825,6 @@ export const HomeDocument = gql` * variables: { * channel: // value for 'channel' * datePeriod: // value for 'datePeriod' - * hasPermissionToManageProducts: // value for 'hasPermissionToManageProducts' * hasPermissionToManageOrders: // value for 'hasPermissionToManageOrders' * }, * }); @@ -8920,6 +8892,65 @@ export function useHomeActivitiesLazyQuery(baseOptions?: ApolloReactHooks.LazyQu export type HomeActivitiesQueryHookResult = ReturnType; export type HomeActivitiesLazyQueryHookResult = ReturnType; export type HomeActivitiesQueryResult = Apollo.QueryResult; +export const HomeTopProductsDocument = gql` + query HomeTopProducts($channel: String!) { + productTopToday: reportProductSales(period: TODAY, first: 5, channel: $channel) { + edges { + node { + id + revenue(period: TODAY) { + gross { + amount + currency + } + } + attributes { + values { + id + name + } + } + product { + id + name + thumbnail { + url + } + } + quantityOrdered + } + } + } +} + `; + +/** + * __useHomeTopProductsQuery__ + * + * To run a query within a React component, call `useHomeTopProductsQuery` and pass it any options that fit your needs. + * When your component renders, `useHomeTopProductsQuery` returns an object from Apollo Client that contains loading, error, and data properties + * you can use to render your UI. + * + * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; + * + * @example + * const { data, loading, error } = useHomeTopProductsQuery({ + * variables: { + * channel: // value for 'channel' + * }, + * }); + */ +export function useHomeTopProductsQuery(baseOptions: ApolloReactHooks.QueryHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return ApolloReactHooks.useQuery(HomeTopProductsDocument, options); + } +export function useHomeTopProductsLazyQuery(baseOptions?: ApolloReactHooks.LazyQueryHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return ApolloReactHooks.useLazyQuery(HomeTopProductsDocument, options); + } +export type HomeTopProductsQueryHookResult = ReturnType; +export type HomeTopProductsLazyQueryHookResult = ReturnType; +export type HomeTopProductsQueryResult = Apollo.QueryResult; export const MenuCreateDocument = gql` mutation MenuCreate($input: MenuCreateInput!) { menuCreate(input: $input) { diff --git a/src/graphql/types.generated.ts b/src/graphql/types.generated.ts index d0cb39ad743..fb36de4f579 100644 --- a/src/graphql/types.generated.ts +++ b/src/graphql/types.generated.ts @@ -10185,18 +10185,24 @@ export type CustomerGiftCardListQuery = { __typename: 'Query', giftCards: { __ty export type HomeQueryVariables = Exact<{ channel: Scalars['String']; datePeriod: DateRangeInput; - hasPermissionToManageProducts: Scalars['Boolean']; hasPermissionToManageOrders: Scalars['Boolean']; }>; -export type HomeQuery = { __typename: 'Query', salesToday: { __typename: 'TaxedMoney', gross: { __typename: 'Money', amount: number, currency: string } } | null, ordersToday: { __typename: 'OrderCountableConnection', totalCount: number | null } | null, ordersToFulfill: { __typename: 'OrderCountableConnection', totalCount: number | null } | null, ordersToCapture: { __typename: 'OrderCountableConnection', totalCount: number | null } | null, productsOutOfStock: { __typename: 'ProductCountableConnection', totalCount: number | null } | null, productTopToday: { __typename: 'ProductVariantCountableConnection', edges: Array<{ __typename: 'ProductVariantCountableEdge', node: { __typename: 'ProductVariant', id: string, quantityOrdered: number | null, revenue: { __typename: 'TaxedMoney', gross: { __typename: 'Money', amount: number, currency: string } } | null, attributes: Array<{ __typename: 'SelectedAttribute', values: Array<{ __typename: 'AttributeValue', id: string, name: string | null }> }>, product: { __typename: 'Product', id: string, name: string, thumbnail: { __typename: 'Image', url: string } | null } } }> } | null }; +export type HomeQuery = { __typename: 'Query', salesToday: { __typename: 'TaxedMoney', gross: { __typename: 'Money', amount: number, currency: string } } | null, ordersToday: { __typename: 'OrderCountableConnection', totalCount: number | null } | null, ordersToFulfill: { __typename: 'OrderCountableConnection', totalCount: number | null } | null, ordersToCapture: { __typename: 'OrderCountableConnection', totalCount: number | null } | null, productsOutOfStock: { __typename: 'ProductCountableConnection', totalCount: number | null } | null }; export type HomeActivitiesQueryVariables = Exact<{ [key: string]: never; }>; export type HomeActivitiesQuery = { __typename: 'Query', activities: { __typename: 'OrderEventCountableConnection', edges: Array<{ __typename: 'OrderEventCountableEdge', node: { __typename: 'OrderEvent', amount: number | null, composedId: string | null, date: any | null, email: string | null, emailType: OrderEventsEmailsEnum | null, id: string, message: string | null, orderNumber: string | null, oversoldItems: Array | null, quantity: number | null, type: OrderEventsEnum | null, user: { __typename: 'User', id: string, email: string } | null } }> } | null }; +export type HomeTopProductsQueryVariables = Exact<{ + channel: Scalars['String']; +}>; + + +export type HomeTopProductsQuery = { __typename: 'Query', productTopToday: { __typename: 'ProductVariantCountableConnection', edges: Array<{ __typename: 'ProductVariantCountableEdge', node: { __typename: 'ProductVariant', id: string, quantityOrdered: number | null, revenue: { __typename: 'TaxedMoney', gross: { __typename: 'Money', amount: number, currency: string } } | null, attributes: Array<{ __typename: 'SelectedAttribute', values: Array<{ __typename: 'AttributeValue', id: string, name: string | null }> }>, product: { __typename: 'Product', id: string, name: string, thumbnail: { __typename: 'Image', url: string } | null } } }> } | null }; + export type MenuCreateMutationVariables = Exact<{ input: MenuCreateInput; }>; diff --git a/src/home/components/HomePage/HomePage.tsx b/src/home/components/HomePage/HomePage.tsx index 8443d3926b0..2e26d5de10d 100644 --- a/src/home/components/HomePage/HomePage.tsx +++ b/src/home/components/HomePage/HomePage.tsx @@ -28,7 +28,11 @@ export interface HomePageProps { ordersToFulfill: number | null; productsOutOfStock: number; sales: NonNullable["gross"]; - topProducts: ProductTopToday | null; + topProducts: { + data: ProductTopToday | null; + loading: boolean; + error: any; + }; userName: string; createNewChannelHref: string; ordersToFulfillHref: string; diff --git a/src/home/components/HomeProductList/HomeProductList.tsx b/src/home/components/HomeProductList/HomeProductList.tsx index d82a7c08060..abe6647763c 100644 --- a/src/home/components/HomeProductList/HomeProductList.tsx +++ b/src/home/components/HomeProductList/HomeProductList.tsx @@ -1,8 +1,7 @@ import Money from "@dashboard/components/Money"; -import Skeleton from "@dashboard/components/Skeleton"; import { ProductTopToday } from "@dashboard/home/types"; import { productVariantEditUrl } from "@dashboard/products/urls"; -import { Box, Text } from "@saleor/macaw-ui-next"; +import { Box, Skeleton, Text } from "@saleor/macaw-ui-next"; import React from "react"; import { FormattedMessage, useIntl } from "react-intl"; @@ -12,7 +11,11 @@ import { generateAttributesInfo } from "./variant"; interface HomeProductListProps { testId?: string; - topProducts: ProductTopToday; + topProducts: { + data: ProductTopToday | null; + loading: boolean; + error: any; + }; } export const HomeProductList = ({ @@ -21,6 +24,21 @@ export const HomeProductList = ({ }: HomeProductListProps) => { const intl = useIntl(); + if (topProducts.loading) { + + + {intl.formatMessage({ + id: "e08xWz", + defaultMessage: "Top products", + description: "header", + })} + + + + + ; + } + return ( @@ -32,7 +50,7 @@ export const HomeProductList = ({ {renderCollection( - topProducts, + topProducts.data, variant => ( { skip: noChannel || !hasPermissionToManageOrders, }); + const { + data: homeTopProducts, + loading: homeTopProductsLoading, + error: homeTopProductsError, + } = useHomeTopProductsQuery({ + displayLoader: true, + skip: noChannel || !hasPermissionToManageProducts, + variables: { + channel: channel?.slug, + }, + }); + const { data } = useHomeQuery({ displayLoader: true, skip: noChannel, @@ -48,7 +61,6 @@ const HomeSection = () => { channel: channel?.slug, datePeriod: getDatePeriod(1), hasPermissionToManageOrders, - hasPermissionToManageProducts, }, }); @@ -61,7 +73,11 @@ const HomeSection = () => { }} orders={data?.ordersToday?.totalCount} sales={data?.salesToday?.gross} - topProducts={mapEdgesToItems(data?.productTopToday)} + topProducts={{ + data: mapEdgesToItems(homeTopProducts?.productTopToday), + loading: homeTopProductsLoading, + error: homeTopProductsError, + }} createNewChannelHref={channelsListUrl()} ordersToCaptureHref={orderListUrl({ status: [OrderStatusFilter.READY_TO_CAPTURE], From 5f444ca7e2b8972ec091e5327da619438c0e2756 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Chy=C5=82a?= Date: Mon, 6 Nov 2023 13:30:00 +0100 Subject: [PATCH 03/13] Extract notifications --- src/graphql/hooks.generated.ts | 57 +++++++++++++++---- src/graphql/types.generated.ts | 10 +++- .../HomeNotificationList.tsx | 41 +++++++++---- src/home/components/HomePage/HomePage.tsx | 21 ++++--- .../HomeProductList/HomeProductList.tsx | 29 ++++++---- src/home/queries.ts | 44 ++++++++------ src/home/views/index.tsx | 33 ++++++++--- 7 files changed, 166 insertions(+), 69 deletions(-) diff --git a/src/graphql/hooks.generated.ts b/src/graphql/hooks.generated.ts index b77b304b17b..7ebba1409a9 100644 --- a/src/graphql/hooks.generated.ts +++ b/src/graphql/hooks.generated.ts @@ -8796,18 +8796,6 @@ export const HomeDocument = gql` ordersToday: orders(filter: {created: $datePeriod}, channel: $channel) @include(if: $hasPermissionToManageOrders) { totalCount } - ordersToFulfill: orders(filter: {status: READY_TO_FULFILL}, channel: $channel) @include(if: $hasPermissionToManageOrders) { - totalCount - } - ordersToCapture: orders(filter: {status: READY_TO_CAPTURE}, channel: $channel) @include(if: $hasPermissionToManageOrders) { - totalCount - } - productsOutOfStock: products( - filter: {stockAvailability: OUT_OF_STOCK} - channel: $channel - ) { - totalCount - } } `; @@ -8951,6 +8939,51 @@ export function useHomeTopProductsLazyQuery(baseOptions?: ApolloReactHooks.LazyQ export type HomeTopProductsQueryHookResult = ReturnType; export type HomeTopProductsLazyQueryHookResult = ReturnType; export type HomeTopProductsQueryResult = Apollo.QueryResult; +export const HomeNotificationsDocument = gql` + query homeNotifications($channel: String!, $hasPermissionToManageOrders: Boolean!) { + ordersToFulfill: orders(filter: {status: READY_TO_FULFILL}, channel: $channel) @include(if: $hasPermissionToManageOrders) { + totalCount + } + ordersToCapture: orders(filter: {status: READY_TO_CAPTURE}, channel: $channel) @include(if: $hasPermissionToManageOrders) { + totalCount + } + productsOutOfStock: products( + filter: {stockAvailability: OUT_OF_STOCK} + channel: $channel + ) { + totalCount + } +} + `; + +/** + * __useHomeNotificationsQuery__ + * + * To run a query within a React component, call `useHomeNotificationsQuery` and pass it any options that fit your needs. + * When your component renders, `useHomeNotificationsQuery` returns an object from Apollo Client that contains loading, error, and data properties + * you can use to render your UI. + * + * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; + * + * @example + * const { data, loading, error } = useHomeNotificationsQuery({ + * variables: { + * channel: // value for 'channel' + * hasPermissionToManageOrders: // value for 'hasPermissionToManageOrders' + * }, + * }); + */ +export function useHomeNotificationsQuery(baseOptions: ApolloReactHooks.QueryHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return ApolloReactHooks.useQuery(HomeNotificationsDocument, options); + } +export function useHomeNotificationsLazyQuery(baseOptions?: ApolloReactHooks.LazyQueryHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return ApolloReactHooks.useLazyQuery(HomeNotificationsDocument, options); + } +export type HomeNotificationsQueryHookResult = ReturnType; +export type HomeNotificationsLazyQueryHookResult = ReturnType; +export type HomeNotificationsQueryResult = Apollo.QueryResult; export const MenuCreateDocument = gql` mutation MenuCreate($input: MenuCreateInput!) { menuCreate(input: $input) { diff --git a/src/graphql/types.generated.ts b/src/graphql/types.generated.ts index fb36de4f579..0e22079290b 100644 --- a/src/graphql/types.generated.ts +++ b/src/graphql/types.generated.ts @@ -10189,7 +10189,7 @@ export type HomeQueryVariables = Exact<{ }>; -export type HomeQuery = { __typename: 'Query', salesToday: { __typename: 'TaxedMoney', gross: { __typename: 'Money', amount: number, currency: string } } | null, ordersToday: { __typename: 'OrderCountableConnection', totalCount: number | null } | null, ordersToFulfill: { __typename: 'OrderCountableConnection', totalCount: number | null } | null, ordersToCapture: { __typename: 'OrderCountableConnection', totalCount: number | null } | null, productsOutOfStock: { __typename: 'ProductCountableConnection', totalCount: number | null } | null }; +export type HomeQuery = { __typename: 'Query', salesToday: { __typename: 'TaxedMoney', gross: { __typename: 'Money', amount: number, currency: string } } | null, ordersToday: { __typename: 'OrderCountableConnection', totalCount: number | null } | null }; export type HomeActivitiesQueryVariables = Exact<{ [key: string]: never; }>; @@ -10203,6 +10203,14 @@ export type HomeTopProductsQueryVariables = Exact<{ export type HomeTopProductsQuery = { __typename: 'Query', productTopToday: { __typename: 'ProductVariantCountableConnection', edges: Array<{ __typename: 'ProductVariantCountableEdge', node: { __typename: 'ProductVariant', id: string, quantityOrdered: number | null, revenue: { __typename: 'TaxedMoney', gross: { __typename: 'Money', amount: number, currency: string } } | null, attributes: Array<{ __typename: 'SelectedAttribute', values: Array<{ __typename: 'AttributeValue', id: string, name: string | null }> }>, product: { __typename: 'Product', id: string, name: string, thumbnail: { __typename: 'Image', url: string } | null } } }> } | null }; +export type HomeNotificationsQueryVariables = Exact<{ + channel: Scalars['String']; + hasPermissionToManageOrders: Scalars['Boolean']; +}>; + + +export type HomeNotificationsQuery = { __typename: 'Query', ordersToFulfill: { __typename: 'OrderCountableConnection', totalCount: number | null } | null, ordersToCapture: { __typename: 'OrderCountableConnection', totalCount: number | null } | null, productsOutOfStock: { __typename: 'ProductCountableConnection', totalCount: number | null } | null }; + export type MenuCreateMutationVariables = Exact<{ input: MenuCreateInput; }>; diff --git a/src/home/components/HomeNotificationList/HomeNotificationList.tsx b/src/home/components/HomeNotificationList/HomeNotificationList.tsx index 44caa9c31b6..19092243a38 100644 --- a/src/home/components/HomeNotificationList/HomeNotificationList.tsx +++ b/src/home/components/HomeNotificationList/HomeNotificationList.tsx @@ -1,6 +1,6 @@ import RequirePermissions from "@dashboard/components/RequirePermissions"; import { PermissionEnum } from "@dashboard/graphql"; -import { List } from "@saleor/macaw-ui-next"; +import { Box, List, Skeleton } from "@saleor/macaw-ui-next"; import React from "react"; import { useIntl } from "react-intl"; @@ -13,9 +13,15 @@ import { } from "./utils"; interface HomeNotificationTableProps { - ordersToCapture: number; - ordersToFulfill: number; - productsOutOfStock: number; + notifications: { + data: { + ordersToCapture: number | null; + ordersToFulfill: number | null; + productsOutOfStock: number; + }; + loading: boolean; + error: any; + }; createNewChannelHref: string; ordersToFulfillHref: string; ordersToCaptureHref: string; @@ -24,17 +30,26 @@ interface HomeNotificationTableProps { } export const HomeNotificationList = ({ + notifications, createNewChannelHref, ordersToFulfillHref, ordersToCaptureHref, productsOutOfStockHref, - ordersToCapture, - ordersToFulfill, - productsOutOfStock, + noChannel, }: HomeNotificationTableProps) => { const intl = useIntl(); + if (notifications.loading) { + return ( + + + + + + ); + } + return ( {noChannel && ( @@ -52,14 +67,17 @@ export const HomeNotificationList = ({ linkUrl={ordersToFulfillHref} dataTestId="orders-to-fulfill" > - {getOrderToFulfillText(ordersToFulfill, intl)} + {getOrderToFulfillText(notifications.data.ordersToFulfill ?? 0, intl)} - {getOrdersToCaptureText(ordersToCapture, intl)} + {getOrdersToCaptureText( + notifications.data.ordersToCapture ?? 0, + intl, + )} @@ -70,7 +88,10 @@ export const HomeNotificationList = ({ linkUrl={productsOutOfStockHref} dataTestId="products-out-of-stock" > - {getProductsOutOfStockText(productsOutOfStock, intl)} + {getProductsOutOfStockText( + notifications.data.productsOutOfStock ?? 0, + intl, + )} diff --git a/src/home/components/HomePage/HomePage.tsx b/src/home/components/HomePage/HomePage.tsx index 2e26d5de10d..82b5a90985d 100644 --- a/src/home/components/HomePage/HomePage.tsx +++ b/src/home/components/HomePage/HomePage.tsx @@ -24,15 +24,22 @@ export interface HomePageProps { error: any; }; orders: number | null; - ordersToCapture: number | null; - ordersToFulfill: number | null; - productsOutOfStock: number; + sales: NonNullable["gross"]; topProducts: { data: ProductTopToday | null; loading: boolean; error: any; }; + notifications: { + data: { + ordersToCapture: number | null; + ordersToFulfill: number | null; + productsOutOfStock: number; + }; + loading: boolean; + error: any; + }; userName: string; createNewChannelHref: string; ordersToFulfillHref: string; @@ -52,9 +59,7 @@ const HomePage: React.FC = props => { ordersToFulfillHref, ordersToCaptureHref, productsOutOfStockHref, - ordersToCapture = 0, - ordersToFulfill = 0, - productsOutOfStock = 0, + notifications, noChannel, } = props; const intl = useIntl(); @@ -105,9 +110,7 @@ const HomePage: React.FC = props => { ordersToFulfillHref={ordersToFulfillHref} ordersToCaptureHref={ordersToCaptureHref} productsOutOfStockHref={productsOutOfStockHref} - ordersToCapture={ordersToCapture ?? 0} - ordersToFulfill={ordersToFulfill ?? 0} - productsOutOfStock={productsOutOfStock} + notifications={notifications} noChannel={noChannel} /> diff --git a/src/home/components/HomeProductList/HomeProductList.tsx b/src/home/components/HomeProductList/HomeProductList.tsx index abe6647763c..93ec9bd248f 100644 --- a/src/home/components/HomeProductList/HomeProductList.tsx +++ b/src/home/components/HomeProductList/HomeProductList.tsx @@ -25,18 +25,25 @@ export const HomeProductList = ({ const intl = useIntl(); if (topProducts.loading) { - - - {intl.formatMessage({ - id: "e08xWz", - defaultMessage: "Top products", - description: "header", - })} - - - + return ( + + + {intl.formatMessage({ + id: "e08xWz", + defaultMessage: "Top products", + description: "header", + })} + + + + + + + + + - ; + ); } return ( diff --git a/src/home/queries.ts b/src/home/queries.ts index 8c7a5bd05f2..de9ead38286 100644 --- a/src/home/queries.ts +++ b/src/home/queries.ts @@ -17,24 +17,6 @@ export const home = gql` @include(if: $hasPermissionToManageOrders) { totalCount } - ordersToFulfill: orders( - filter: { status: READY_TO_FULFILL } - channel: $channel - ) @include(if: $hasPermissionToManageOrders) { - totalCount - } - ordersToCapture: orders( - filter: { status: READY_TO_CAPTURE } - channel: $channel - ) @include(if: $hasPermissionToManageOrders) { - totalCount - } - productsOutOfStock: products( - filter: { stockAvailability: OUT_OF_STOCK } - channel: $channel - ) { - totalCount - } } `; @@ -99,3 +81,29 @@ export const homeTopProducts = gql` } } `; + +export const homeNotifications = gql` + query homeNotifications( + $channel: String! + $hasPermissionToManageOrders: Boolean! + ) { + ordersToFulfill: orders( + filter: { status: READY_TO_FULFILL } + channel: $channel + ) @include(if: $hasPermissionToManageOrders) { + totalCount + } + ordersToCapture: orders( + filter: { status: READY_TO_CAPTURE } + channel: $channel + ) @include(if: $hasPermissionToManageOrders) { + totalCount + } + productsOutOfStock: products( + filter: { stockAvailability: OUT_OF_STOCK } + channel: $channel + ) { + totalCount + } + } +`; diff --git a/src/home/views/index.tsx b/src/home/views/index.tsx index 26dcba7c541..29fdc9604a1 100644 --- a/src/home/views/index.tsx +++ b/src/home/views/index.tsx @@ -8,6 +8,7 @@ import { PermissionEnum, StockAvailability, useHomeActivitiesQuery, + useHomeNotificationsQuery, useHomeQuery, useHomeTopProductsQuery, } from "@dashboard/graphql"; @@ -38,7 +39,6 @@ const HomeSection = () => { loading: homeActivitiesLoading, error: homeActivitiesError, } = useHomeActivitiesQuery({ - displayLoader: true, skip: noChannel || !hasPermissionToManageOrders, }); @@ -47,15 +47,25 @@ const HomeSection = () => { loading: homeTopProductsLoading, error: homeTopProductsError, } = useHomeTopProductsQuery({ - displayLoader: true, skip: noChannel || !hasPermissionToManageProducts, variables: { channel: channel?.slug, }, }); + const { + data: homeNotificationsData, + loading: homeNotificationsLoaing, + error: homeNotificationsError, + } = useHomeNotificationsQuery({ + skip: noChannel, + variables: { + channel: channel?.slug, + hasPermissionToManageOrders, + }, + }); + const { data } = useHomeQuery({ - displayLoader: true, skip: noChannel, variables: { channel: channel?.slug, @@ -71,13 +81,23 @@ const HomeSection = () => { loading: homeActivitiesLoading, error: homeActivitiesError, }} - orders={data?.ordersToday?.totalCount} - sales={data?.salesToday?.gross} topProducts={{ data: mapEdgesToItems(homeTopProducts?.productTopToday), loading: homeTopProductsLoading, error: homeTopProductsError, }} + notifications={{ + data: { + ordersToCapture: homeNotificationsData?.ordersToCapture?.totalCount, + ordersToFulfill: homeNotificationsData?.ordersToFulfill?.totalCount, + productsOutOfStock: + homeNotificationsData?.productsOutOfStock.totalCount, + }, + loading: homeNotificationsLoaing, + error: homeNotificationsError, + }} + orders={data?.ordersToday?.totalCount} + sales={data?.salesToday?.gross} createNewChannelHref={channelsListUrl()} ordersToCaptureHref={orderListUrl({ status: [OrderStatusFilter.READY_TO_CAPTURE], @@ -91,9 +111,6 @@ const HomeSection = () => { stockStatus: StockAvailability.OUT_OF_STOCK, channel: channel?.slug, })} - ordersToCapture={data?.ordersToCapture?.totalCount} - ordersToFulfill={data?.ordersToFulfill?.totalCount} - productsOutOfStock={data?.productsOutOfStock.totalCount} userName={getUserName(user, true)} noChannel={noChannel} /> From 169d796477364665f7b71b79e968d834464e454f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Chy=C5=82a?= Date: Mon, 6 Nov 2023 13:42:44 +0100 Subject: [PATCH 04/13] Extract analitics --- src/graphql/hooks.generated.ts | 31 +++++++++++------------ src/graphql/types.generated.ts | 5 ++-- src/home/components/HomePage/HomePage.tsx | 27 +++++++++++--------- src/home/queries.ts | 14 +++------- src/home/views/index.tsx | 21 ++++++++++----- 5 files changed, 51 insertions(+), 47 deletions(-) diff --git a/src/graphql/hooks.generated.ts b/src/graphql/hooks.generated.ts index 7ebba1409a9..7e3d4feae09 100644 --- a/src/graphql/hooks.generated.ts +++ b/src/graphql/hooks.generated.ts @@ -8785,49 +8785,48 @@ export function useCustomerGiftCardListLazyQuery(baseOptions?: ApolloReactHooks. export type CustomerGiftCardListQueryHookResult = ReturnType; export type CustomerGiftCardListLazyQueryHookResult = ReturnType; export type CustomerGiftCardListQueryResult = Apollo.QueryResult; -export const HomeDocument = gql` - query Home($channel: String!, $datePeriod: DateRangeInput!, $hasPermissionToManageOrders: Boolean!) { - salesToday: ordersTotal(period: TODAY, channel: $channel) @include(if: $hasPermissionToManageOrders) { +export const HomeAnaliticsDocument = gql` + query HomeAnalitics($channel: String!, $datePeriod: DateRangeInput!) { + salesToday: ordersTotal(period: TODAY, channel: $channel) { gross { amount currency } } - ordersToday: orders(filter: {created: $datePeriod}, channel: $channel) @include(if: $hasPermissionToManageOrders) { + ordersToday: orders(filter: {created: $datePeriod}, channel: $channel) { totalCount } } `; /** - * __useHomeQuery__ + * __useHomeAnaliticsQuery__ * - * To run a query within a React component, call `useHomeQuery` and pass it any options that fit your needs. - * When your component renders, `useHomeQuery` returns an object from Apollo Client that contains loading, error, and data properties + * To run a query within a React component, call `useHomeAnaliticsQuery` and pass it any options that fit your needs. + * When your component renders, `useHomeAnaliticsQuery` returns an object from Apollo Client that contains loading, error, and data properties * you can use to render your UI. * * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; * * @example - * const { data, loading, error } = useHomeQuery({ + * const { data, loading, error } = useHomeAnaliticsQuery({ * variables: { * channel: // value for 'channel' * datePeriod: // value for 'datePeriod' - * hasPermissionToManageOrders: // value for 'hasPermissionToManageOrders' * }, * }); */ -export function useHomeQuery(baseOptions: ApolloReactHooks.QueryHookOptions) { +export function useHomeAnaliticsQuery(baseOptions: ApolloReactHooks.QueryHookOptions) { const options = {...defaultOptions, ...baseOptions} - return ApolloReactHooks.useQuery(HomeDocument, options); + return ApolloReactHooks.useQuery(HomeAnaliticsDocument, options); } -export function useHomeLazyQuery(baseOptions?: ApolloReactHooks.LazyQueryHookOptions) { +export function useHomeAnaliticsLazyQuery(baseOptions?: ApolloReactHooks.LazyQueryHookOptions) { const options = {...defaultOptions, ...baseOptions} - return ApolloReactHooks.useLazyQuery(HomeDocument, options); + return ApolloReactHooks.useLazyQuery(HomeAnaliticsDocument, options); } -export type HomeQueryHookResult = ReturnType; -export type HomeLazyQueryHookResult = ReturnType; -export type HomeQueryResult = Apollo.QueryResult; +export type HomeAnaliticsQueryHookResult = ReturnType; +export type HomeAnaliticsLazyQueryHookResult = ReturnType; +export type HomeAnaliticsQueryResult = Apollo.QueryResult; export const HomeActivitiesDocument = gql` query HomeActivities { activities: homepageEvents(last: 10) { diff --git a/src/graphql/types.generated.ts b/src/graphql/types.generated.ts index 0e22079290b..f9e25079735 100644 --- a/src/graphql/types.generated.ts +++ b/src/graphql/types.generated.ts @@ -10182,14 +10182,13 @@ export type CustomerGiftCardListQueryVariables = Exact<{ export type CustomerGiftCardListQuery = { __typename: 'Query', giftCards: { __typename: 'GiftCardCountableConnection', edges: Array<{ __typename: 'GiftCardCountableEdge', node: { __typename: 'GiftCard', id: string, last4CodeChars: string, expiryDate: any | null, isActive: boolean, currentBalance: { __typename: 'Money', amount: number, currency: string } } }> } | null }; -export type HomeQueryVariables = Exact<{ +export type HomeAnaliticsQueryVariables = Exact<{ channel: Scalars['String']; datePeriod: DateRangeInput; - hasPermissionToManageOrders: Scalars['Boolean']; }>; -export type HomeQuery = { __typename: 'Query', salesToday: { __typename: 'TaxedMoney', gross: { __typename: 'Money', amount: number, currency: string } } | null, ordersToday: { __typename: 'OrderCountableConnection', totalCount: number | null } | null }; +export type HomeAnaliticsQuery = { __typename: 'Query', salesToday: { __typename: 'TaxedMoney', gross: { __typename: 'Money', amount: number, currency: string } } | null, ordersToday: { __typename: 'OrderCountableConnection', totalCount: number | null } | null }; export type HomeActivitiesQueryVariables = Exact<{ [key: string]: never; }>; diff --git a/src/home/components/HomePage/HomePage.tsx b/src/home/components/HomePage/HomePage.tsx index 82b5a90985d..ca36387844f 100644 --- a/src/home/components/HomePage/HomePage.tsx +++ b/src/home/components/HomePage/HomePage.tsx @@ -3,10 +3,9 @@ import CardSpacer from "@dashboard/components/CardSpacer"; import { DetailPageLayout } from "@dashboard/components/Layouts"; import Money from "@dashboard/components/Money"; import RequirePermissions from "@dashboard/components/RequirePermissions"; -import Skeleton from "@dashboard/components/Skeleton"; -import { HomeQuery, PermissionEnum } from "@dashboard/graphql"; +import { HomeAnaliticsQuery, PermissionEnum } from "@dashboard/graphql"; import { Activities, ProductTopToday } from "@dashboard/home/types"; -import { Box } from "@saleor/macaw-ui-next"; +import { Box, Skeleton } from "@saleor/macaw-ui-next"; import React from "react"; import { useIntl } from "react-intl"; @@ -23,9 +22,14 @@ export interface HomePageProps { loading: boolean; error: any; }; - orders: number | null; - - sales: NonNullable["gross"]; + analitics: { + data: { + orders: number | null; + sales: NonNullable["gross"]; + }; + loading: boolean; + error: any; + }; topProducts: { data: ProductTopToday | null; loading: boolean; @@ -51,8 +55,7 @@ export interface HomePageProps { const HomePage: React.FC = props => { const { userName, - orders, - sales, + analitics, topProducts, activities, createNewChannelHref, @@ -85,8 +88,8 @@ const HomePage: React.FC = props => { > {noChannel ? ( 0 - ) : sales ? ( - + ) : !analitics.loading ? ( + ) : ( )} @@ -97,8 +100,8 @@ const HomePage: React.FC = props => { > {noChannel ? ( 0 - ) : orders !== undefined ? ( - orders + ) : !analitics.loading ? ( + analitics.data.orders ) : ( )} diff --git a/src/home/queries.ts b/src/home/queries.ts index de9ead38286..02d1a354aaf 100644 --- a/src/home/queries.ts +++ b/src/home/queries.ts @@ -1,20 +1,14 @@ import { gql } from "@apollo/client"; -export const home = gql` - query Home( - $channel: String! - $datePeriod: DateRangeInput! - $hasPermissionToManageOrders: Boolean! - ) { - salesToday: ordersTotal(period: TODAY, channel: $channel) - @include(if: $hasPermissionToManageOrders) { +export const homeAnalitics = gql` + query HomeAnalitics($channel: String!, $datePeriod: DateRangeInput!) { + salesToday: ordersTotal(period: TODAY, channel: $channel) { gross { amount currency } } - ordersToday: orders(filter: { created: $datePeriod }, channel: $channel) - @include(if: $hasPermissionToManageOrders) { + ordersToday: orders(filter: { created: $datePeriod }, channel: $channel) { totalCount } } diff --git a/src/home/views/index.tsx b/src/home/views/index.tsx index 29fdc9604a1..5271402e4ca 100644 --- a/src/home/views/index.tsx +++ b/src/home/views/index.tsx @@ -8,8 +8,8 @@ import { PermissionEnum, StockAvailability, useHomeActivitiesQuery, + useHomeAnaliticsQuery, useHomeNotificationsQuery, - useHomeQuery, useHomeTopProductsQuery, } from "@dashboard/graphql"; import { mapEdgesToItems } from "@dashboard/utils/maps"; @@ -65,12 +65,15 @@ const HomeSection = () => { }, }); - const { data } = useHomeQuery({ - skip: noChannel, + const { + data: homeAnaliticsData, + loading: homeAnaliticsLoading, + error: homeAnaliticsError, + } = useHomeAnaliticsQuery({ + skip: noChannel || !hasPermissionToManageOrders, variables: { channel: channel?.slug, datePeriod: getDatePeriod(1), - hasPermissionToManageOrders, }, }); @@ -96,8 +99,14 @@ const HomeSection = () => { loading: homeNotificationsLoaing, error: homeNotificationsError, }} - orders={data?.ordersToday?.totalCount} - sales={data?.salesToday?.gross} + analitics={{ + data: { + orders: homeAnaliticsData?.ordersToday?.totalCount, + sales: homeAnaliticsData?.salesToday?.gross, + }, + loading: homeAnaliticsLoading, + error: homeAnaliticsError, + }} createNewChannelHref={channelsListUrl()} ordersToCaptureHref={orderListUrl({ status: [OrderStatusFilter.READY_TO_CAPTURE], From 671ce386e7b9d80953c8a7fb9d8d5d6f60bd8cc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Chy=C5=82a?= Date: Mon, 6 Nov 2023 13:46:23 +0100 Subject: [PATCH 05/13] Fix stories --- .../HomeActivityCard/activityMessages.ts | 4 +-- .../components/HomePage/HomePage.stories.tsx | 34 +++++++++++++++---- src/home/fixtures.ts | 6 ++-- 3 files changed, 31 insertions(+), 13 deletions(-) diff --git a/src/home/components/HomeActivityCard/activityMessages.ts b/src/home/components/HomeActivityCard/activityMessages.ts index e41d49f795e..adeede757aa 100644 --- a/src/home/components/HomeActivityCard/activityMessages.ts +++ b/src/home/components/HomeActivityCard/activityMessages.ts @@ -1,5 +1,5 @@ // @ts-strict-ignore -import { HomeQuery, OrderEventsEnum } from "@dashboard/graphql"; +import { HomeActivitiesQuery, OrderEventsEnum } from "@dashboard/graphql"; import { defineMessages, IntlShape } from "react-intl"; const messages = defineMessages({ @@ -22,7 +22,7 @@ const messages = defineMessages({ }); export const getActivityMessage = ( - activity: HomeQuery["activities"]["edges"][0]["node"], + activity: HomeActivitiesQuery["activities"]["edges"][0]["node"], intl: IntlShape, ) => { switch (activity.type) { diff --git a/src/home/components/HomePage/HomePage.stories.tsx b/src/home/components/HomePage/HomePage.stories.tsx index 37a5bf7e8b9..9067b9771b9 100644 --- a/src/home/components/HomePage/HomePage.stories.tsx +++ b/src/home/components/HomePage/HomePage.stories.tsx @@ -12,18 +12,38 @@ import HomePageComponent, { HomePageProps } from "./HomePage"; const shop = shopFixture(placeholderImage); const homePageProps: Omit = { - activities: mapEdgesToItems(shop.activities), + activities: { + data: mapEdgesToItems(shop.activities), + loading: false, + error: false, + }, + notifications: { + data: { + ordersToCapture: shop.ordersToCapture.totalCount, + ordersToFulfill: shop.ordersToFulfill.totalCount, + productsOutOfStock: shop.productsOutOfStock.totalCount, + }, + loading: false, + error: false, + }, + analitics: { + data: { + orders: shop.ordersToday.totalCount, + sales: shop.salesToday.gross, + }, + loading: false, + error: false, + }, noChannel: false, createNewChannelHref: "", ordersToFulfillHref: "", ordersToCaptureHref: "", productsOutOfStockHref: "", - orders: shop.ordersToday.totalCount, - ordersToCapture: shop.ordersToCapture.totalCount, - ordersToFulfill: shop.ordersToFulfill.totalCount, - productsOutOfStock: shop.productsOutOfStock.totalCount, - sales: shop.salesToday.gross, - topProducts: mapEdgesToItems(shop.productTopToday), + topProducts: { + data: mapEdgesToItems(shop.productTopToday), + loading: false, + error: false, + }, userName: "admin@example.com", }; diff --git a/src/home/fixtures.ts b/src/home/fixtures.ts index d357a16010a..359c076574b 100644 --- a/src/home/fixtures.ts +++ b/src/home/fixtures.ts @@ -1,9 +1,7 @@ // @ts-strict-ignore -import { HomeQuery, OrderEventsEnum } from "@dashboard/graphql"; +import { OrderEventsEnum } from "@dashboard/graphql"; -export const shop: (placeholderImage: string) => HomeQuery = ( - placeholderImage: string, -) => ({ +export const shop = (placeholderImage: string) => ({ __typename: "Query", activities: { __typename: "OrderEventCountableConnection", From 63120f103e3ff702ff6a93af36ee3818071b6ca3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Chy=C5=82a?= Date: Tue, 7 Nov 2023 09:29:28 +0100 Subject: [PATCH 06/13] Adjust skeletons --- .../HomeActivityCard/HomeActivityCard.tsx | 126 ++++++++++-------- .../HomeNotificationList.tsx | 20 ++- .../HomeNotificationListItem.tsx | 73 +++++++--- .../HomeProductList/HomeProductList.tsx | 42 +++--- 4 files changed, 152 insertions(+), 109 deletions(-) diff --git a/src/home/components/HomeActivityCard/HomeActivityCard.tsx b/src/home/components/HomeActivityCard/HomeActivityCard.tsx index 3e9517403e0..13abff7317b 100644 --- a/src/home/components/HomeActivityCard/HomeActivityCard.tsx +++ b/src/home/components/HomeActivityCard/HomeActivityCard.tsx @@ -23,68 +23,78 @@ export const HomeActivityCard = ({ }: HomeActivityCardProps) => { const intl = useIntl(); const { themeValues } = useTheme(); + const title = intl.formatMessage({ + id: "BXkF8Z", + defaultMessage: "Activity", + description: "header", + }); + + if (activities.loading) { + return ( + + {title} + + + + + + + + + ); + } return ( - - {intl.formatMessage({ - id: "BXkF8Z", - defaultMessage: "Activity", - description: "header", - })} - + {title} - {activities.loading ? ( - - ) : ( - - {renderCollection( - activities.data, - (activity, activityId) => ( - - {activity ? ( - <> - - {getActivityMessage(activity, intl)} - - - - - - ) : ( - - - - )} - - ), - () => ( - - - - - - ), - )} - - )} + + {renderCollection( + activities.data, + (activity, activityId) => ( + + {activity ? ( + <> + + {getActivityMessage(activity, intl)} + + + + + + ) : ( + + + + )} + + ), + () => ( + + + + + + ), + )} + ); diff --git a/src/home/components/HomeNotificationList/HomeNotificationList.tsx b/src/home/components/HomeNotificationList/HomeNotificationList.tsx index 19092243a38..ca2169a316d 100644 --- a/src/home/components/HomeNotificationList/HomeNotificationList.tsx +++ b/src/home/components/HomeNotificationList/HomeNotificationList.tsx @@ -1,6 +1,6 @@ import RequirePermissions from "@dashboard/components/RequirePermissions"; import { PermissionEnum } from "@dashboard/graphql"; -import { Box, List, Skeleton } from "@saleor/macaw-ui-next"; +import { List } from "@saleor/macaw-ui-next"; import React from "react"; import { useIntl } from "react-intl"; @@ -40,23 +40,16 @@ export const HomeNotificationList = ({ }: HomeNotificationTableProps) => { const intl = useIntl(); - if (notifications.loading) { - return ( - - - - - - ); - } - return ( {noChannel && ( - + {intl.formatMessage(messages.createNewChannel)} @@ -64,6 +57,7 @@ export const HomeNotificationList = ({ @@ -71,6 +65,7 @@ export const HomeNotificationList = ({ @@ -85,6 +80,7 @@ export const HomeNotificationList = ({ requiredPermissions={[PermissionEnum.MANAGE_PRODUCTS]} > diff --git a/src/home/components/HomeNotificationList/HomeNotificationListItem.tsx b/src/home/components/HomeNotificationList/HomeNotificationListItem.tsx index ac7a202e035..712eabe908e 100644 --- a/src/home/components/HomeNotificationList/HomeNotificationListItem.tsx +++ b/src/home/components/HomeNotificationList/HomeNotificationListItem.tsx @@ -2,6 +2,7 @@ import { Box, ChevronRightIcon, List, + Skeleton, sprinkles, Text, } from "@saleor/macaw-ui-next"; @@ -12,32 +13,60 @@ interface HomeNotificationListItemProps { dataTestId?: string; linkUrl: string; children: ReactNode; + loading: boolean; } export const HomeNotificationListItem = ({ dataTestId, linkUrl, children, -}: HomeNotificationListItemProps) => ( - - - { + if (loading) { + return ( + + + + + + ); + } + + return ( + + - {children} - - - - -); + + {children} + + + + + ); +}; + +function Listitem({ + children, + dataTestId, +}: { + children: ReactNode; + dataTestId?: string; +}) { + return ( + + {children} + + ); +} diff --git a/src/home/components/HomeProductList/HomeProductList.tsx b/src/home/components/HomeProductList/HomeProductList.tsx index 93ec9bd248f..b4e651cbc12 100644 --- a/src/home/components/HomeProductList/HomeProductList.tsx +++ b/src/home/components/HomeProductList/HomeProductList.tsx @@ -23,24 +23,22 @@ export const HomeProductList = ({ testId, }: HomeProductListProps) => { const intl = useIntl(); + const title = intl.formatMessage({ + id: "e08xWz", + defaultMessage: "Top products", + description: "header", + }); if (topProducts.loading) { return ( - {intl.formatMessage({ - id: "e08xWz", - defaultMessage: "Top products", - description: "header", - })} + {title} - - - - - - - + + + + ); @@ -49,11 +47,7 @@ export const HomeProductList = ({ return ( - {intl.formatMessage({ - id: "e08xWz", - defaultMessage: "Top products", - description: "header", - })} + {title} {renderCollection( @@ -140,3 +134,17 @@ export const HomeProductList = ({ HomeProductList.displayName = "HomeProductList"; export default HomeProductList; + +function ProductListSkeleton() { + return ( + + + + ); +} From 84ee185f1327c5af28f4d59b2797c07519423603 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Chy=C5=82a?= Date: Tue, 7 Nov 2023 09:57:37 +0100 Subject: [PATCH 07/13] Improve typing --- .../HomeActivityCard/HomeActivityCard.tsx | 24 +++++++--- .../HomeNotificationList.tsx | 15 +++---- src/home/components/HomePage/HomePage.tsx | 45 ++++++------------- .../HomeProductList/HomeProductList.tsx | 24 +++++++--- src/home/types.ts | 25 ++++++++++- src/home/views/index.tsx | 8 ++-- 6 files changed, 83 insertions(+), 58 deletions(-) diff --git a/src/home/components/HomeActivityCard/HomeActivityCard.tsx b/src/home/components/HomeActivityCard/HomeActivityCard.tsx index 13abff7317b..1abfebf0499 100644 --- a/src/home/components/HomeActivityCard/HomeActivityCard.tsx +++ b/src/home/components/HomeActivityCard/HomeActivityCard.tsx @@ -1,6 +1,6 @@ import { DashboardCard } from "@dashboard/components/Card"; import { DateTime } from "@dashboard/components/Date"; -import { Activities } from "@dashboard/home/types"; +import { Activities, HomeData } from "@dashboard/home/types"; import { Box, List, Skeleton, Text, useTheme } from "@saleor/macaw-ui-next"; import React from "react"; import { FormattedMessage, useIntl } from "react-intl"; @@ -9,11 +9,7 @@ import { renderCollection } from "../../../misc"; import { getActivityMessage } from "./activityMessages"; interface HomeActivityCardProps { - activities: { - data: Activities; - loading: boolean; - error: any; - }; + activities: HomeData; testId?: string; } @@ -29,6 +25,22 @@ export const HomeActivityCard = ({ description: "header", }); + if (activities.hasError) { + return ( + + {title} + + + + + + + ); + } + if (activities.loading) { return ( diff --git a/src/home/components/HomeNotificationList/HomeNotificationList.tsx b/src/home/components/HomeNotificationList/HomeNotificationList.tsx index ca2169a316d..61f239040b8 100644 --- a/src/home/components/HomeNotificationList/HomeNotificationList.tsx +++ b/src/home/components/HomeNotificationList/HomeNotificationList.tsx @@ -1,5 +1,6 @@ import RequirePermissions from "@dashboard/components/RequirePermissions"; import { PermissionEnum } from "@dashboard/graphql"; +import { HomeData, Notifications } from "@dashboard/home/types"; import { List } from "@saleor/macaw-ui-next"; import React from "react"; import { useIntl } from "react-intl"; @@ -13,15 +14,7 @@ import { } from "./utils"; interface HomeNotificationTableProps { - notifications: { - data: { - ordersToCapture: number | null; - ordersToFulfill: number | null; - productsOutOfStock: number; - }; - loading: boolean; - error: any; - }; + notifications: HomeData; createNewChannelHref: string; ordersToFulfillHref: string; ordersToCaptureHref: string; @@ -40,6 +33,10 @@ export const HomeNotificationList = ({ }: HomeNotificationTableProps) => { const intl = useIntl(); + if (notifications.hasError) { + return null; + } + return ( {noChannel && ( diff --git a/src/home/components/HomePage/HomePage.tsx b/src/home/components/HomePage/HomePage.tsx index ca36387844f..4a023d08b96 100644 --- a/src/home/components/HomePage/HomePage.tsx +++ b/src/home/components/HomePage/HomePage.tsx @@ -3,8 +3,14 @@ import CardSpacer from "@dashboard/components/CardSpacer"; import { DetailPageLayout } from "@dashboard/components/Layouts"; import Money from "@dashboard/components/Money"; import RequirePermissions from "@dashboard/components/RequirePermissions"; -import { HomeAnaliticsQuery, PermissionEnum } from "@dashboard/graphql"; -import { Activities, ProductTopToday } from "@dashboard/home/types"; +import { PermissionEnum } from "@dashboard/graphql"; +import { + Activities, + Analitics, + HomeData, + Notifications, + ProductTopToday, +} from "@dashboard/home/types"; import { Box, Skeleton } from "@saleor/macaw-ui-next"; import React from "react"; import { useIntl } from "react-intl"; @@ -17,33 +23,10 @@ import { HomeProductList } from "../HomeProductList"; import { homePageMessages } from "./messages"; export interface HomePageProps { - activities: { - data: Activities; - loading: boolean; - error: any; - }; - analitics: { - data: { - orders: number | null; - sales: NonNullable["gross"]; - }; - loading: boolean; - error: any; - }; - topProducts: { - data: ProductTopToday | null; - loading: boolean; - error: any; - }; - notifications: { - data: { - ordersToCapture: number | null; - ordersToFulfill: number | null; - productsOutOfStock: number; - }; - loading: boolean; - error: any; - }; + activities: HomeData; + analitics: HomeData; + topProducts: HomeData; + notifications: HomeData; userName: string; createNewChannelHref: string; ordersToFulfillHref: string; @@ -86,7 +69,7 @@ const HomePage: React.FC = props => { title={intl.formatMessage(homePageMessages.salesCardTitle)} testId="sales-analytics" > - {noChannel ? ( + {noChannel || analitics.hasError ? ( 0 ) : !analitics.loading ? ( @@ -98,7 +81,7 @@ const HomePage: React.FC = props => { title={intl.formatMessage(homePageMessages.ordersCardTitle)} testId="orders-analytics" > - {noChannel ? ( + {noChannel || analitics.hasError ? ( 0 ) : !analitics.loading ? ( analitics.data.orders diff --git a/src/home/components/HomeProductList/HomeProductList.tsx b/src/home/components/HomeProductList/HomeProductList.tsx index b4e651cbc12..baf0affbed1 100644 --- a/src/home/components/HomeProductList/HomeProductList.tsx +++ b/src/home/components/HomeProductList/HomeProductList.tsx @@ -1,5 +1,5 @@ import Money from "@dashboard/components/Money"; -import { ProductTopToday } from "@dashboard/home/types"; +import { HomeData, ProductTopToday } from "@dashboard/home/types"; import { productVariantEditUrl } from "@dashboard/products/urls"; import { Box, Skeleton, Text } from "@saleor/macaw-ui-next"; import React from "react"; @@ -11,11 +11,7 @@ import { generateAttributesInfo } from "./variant"; interface HomeProductListProps { testId?: string; - topProducts: { - data: ProductTopToday | null; - loading: boolean; - error: any; - }; + topProducts: HomeData; } export const HomeProductList = ({ @@ -29,6 +25,22 @@ export const HomeProductList = ({ description: "header", }); + if (topProducts.hasError) { + return ( + + + {title} + + + + + + ); + } + if (topProducts.loading) { return ( diff --git a/src/home/types.ts b/src/home/types.ts index 6a2846647a7..56293d0df02 100644 --- a/src/home/types.ts +++ b/src/home/types.ts @@ -1,9 +1,30 @@ -import { HomeActivitiesQuery, HomeQuery } from "@dashboard/graphql"; +import { + HomeActivitiesQuery, + HomeAnaliticsQuery, + HomeTopProductsQuery, +} from "@dashboard/graphql"; import { RelayToFlat } from "@dashboard/types"; export type Activities = RelayToFlat< NonNullable >; export type ProductTopToday = RelayToFlat< - NonNullable + NonNullable >; + +export interface Analitics { + orders: number | null; + sales: NonNullable["gross"]; +} + +export interface Notifications { + ordersToCapture: number | null; + ordersToFulfill: number | null; + productsOutOfStock: number; +} + +export interface HomeData { + data: T; + loading: boolean; + hasError: boolean; +} diff --git a/src/home/views/index.tsx b/src/home/views/index.tsx index 5271402e4ca..4e70857a4cc 100644 --- a/src/home/views/index.tsx +++ b/src/home/views/index.tsx @@ -82,12 +82,12 @@ const HomeSection = () => { activities={{ data: mapEdgesToItems(homeActivities?.activities)?.reverse(), loading: homeActivitiesLoading, - error: homeActivitiesError, + hasError: !!homeActivitiesError, }} topProducts={{ data: mapEdgesToItems(homeTopProducts?.productTopToday), loading: homeTopProductsLoading, - error: homeTopProductsError, + hasError: !!homeTopProductsError, }} notifications={{ data: { @@ -97,7 +97,7 @@ const HomeSection = () => { homeNotificationsData?.productsOutOfStock.totalCount, }, loading: homeNotificationsLoaing, - error: homeNotificationsError, + hasError: !!homeNotificationsError, }} analitics={{ data: { @@ -105,7 +105,7 @@ const HomeSection = () => { sales: homeAnaliticsData?.salesToday?.gross, }, loading: homeAnaliticsLoading, - error: homeAnaliticsError, + hasError: !!homeAnaliticsError, }} createNewChannelHref={channelsListUrl()} ordersToCaptureHref={orderListUrl({ From 3473c412e351862cf43b9f39c7a957be3b42c357 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Chy=C5=82a?= Date: Tue, 7 Nov 2023 10:26:04 +0100 Subject: [PATCH 08/13] Improve stories --- .../components/HomePage/HomePage.stories.tsx | 99 ++- src/home/components/HomePage/HomePage.tsx | 2 +- .../HomeProductList/HomeProductList.tsx | 2 +- src/home/fixtures.ts | 793 +++++++++--------- 4 files changed, 483 insertions(+), 413 deletions(-) diff --git a/src/home/components/HomePage/HomePage.stories.tsx b/src/home/components/HomePage/HomePage.stories.tsx index 9067b9771b9..598f2b8f1ec 100644 --- a/src/home/components/HomePage/HomePage.stories.tsx +++ b/src/home/components/HomePage/HomePage.stories.tsx @@ -2,37 +2,42 @@ import placeholderImage from "@assets/images/placeholder60x60.png"; import { adminUserPermissions } from "@dashboard/fixtures"; import { PermissionEnum } from "@dashboard/graphql"; -import { shop as shopFixture } from "@dashboard/home/fixtures"; +import { + activities, + analitics, + notifications, + topProducts as topProductsFixture, +} from "@dashboard/home/fixtures"; import { mapEdgesToItems } from "@dashboard/utils/maps"; import React from "react"; import { MockedUserProvider } from "../../../../.storybook/helpers"; import HomePageComponent, { HomePageProps } from "./HomePage"; -const shop = shopFixture(placeholderImage); +const productTopToday = topProductsFixture(placeholderImage); const homePageProps: Omit = { activities: { - data: mapEdgesToItems(shop.activities), + data: mapEdgesToItems(activities), loading: false, - error: false, + hasError: false, }, notifications: { data: { - ordersToCapture: shop.ordersToCapture.totalCount, - ordersToFulfill: shop.ordersToFulfill.totalCount, - productsOutOfStock: shop.productsOutOfStock.totalCount, + ordersToCapture: notifications.ordersToCapture.totalCount, + ordersToFulfill: notifications.ordersToFulfill.totalCount, + productsOutOfStock: notifications.productsOutOfStock.totalCount, }, loading: false, - error: false, + hasError: false, }, analitics: { data: { - orders: shop.ordersToday.totalCount, - sales: shop.salesToday.gross, + orders: analitics.ordersToday.totalCount, + sales: analitics.salesToday.gross, }, loading: false, - error: false, + hasError: false, }, noChannel: false, createNewChannelHref: "", @@ -40,9 +45,9 @@ const homePageProps: Omit = { ordersToCaptureHref: "", productsOutOfStockHref: "", topProducts: { - data: mapEdgesToItems(shop.productTopToday), + data: mapEdgesToItems(productTopToday), loading: false, - error: false, + hasError: false, }, userName: "admin@example.com", }; @@ -66,19 +71,69 @@ export const Default = () => ; export const Loading = () => ( +); + +export const Error = () => ( + ); export const NoData = () => ( - + ); export const NoPermissions = () => ( diff --git a/src/home/components/HomePage/HomePage.tsx b/src/home/components/HomePage/HomePage.tsx index 4a023d08b96..56e8eb47ce2 100644 --- a/src/home/components/HomePage/HomePage.tsx +++ b/src/home/components/HomePage/HomePage.tsx @@ -25,7 +25,7 @@ import { homePageMessages } from "./messages"; export interface HomePageProps { activities: HomeData; analitics: HomeData; - topProducts: HomeData; + topProducts: HomeData; notifications: HomeData; userName: string; createNewChannelHref: string; diff --git a/src/home/components/HomeProductList/HomeProductList.tsx b/src/home/components/HomeProductList/HomeProductList.tsx index baf0affbed1..263e96d6483 100644 --- a/src/home/components/HomeProductList/HomeProductList.tsx +++ b/src/home/components/HomeProductList/HomeProductList.tsx @@ -11,7 +11,7 @@ import { generateAttributesInfo } from "./variant"; interface HomeProductListProps { testId?: string; - topProducts: HomeData; + topProducts: HomeData; } export const HomeProductList = ({ diff --git a/src/home/fixtures.ts b/src/home/fixtures.ts index 359c076574b..49836570245 100644 --- a/src/home/fixtures.ts +++ b/src/home/fixtures.ts @@ -1,428 +1,439 @@ // @ts-strict-ignore -import { OrderEventsEnum } from "@dashboard/graphql"; +import { + HomeActivitiesQuery, + HomeAnaliticsQuery, + HomeNotificationsQuery, + HomeTopProductsQuery, + OrderEventsEnum, +} from "@dashboard/graphql"; -export const shop = (placeholderImage: string) => ({ +export const notifications: HomeNotificationsQuery = { __typename: "Query", - activities: { - __typename: "OrderEventCountableConnection", - edges: [ - { - __typename: "OrderEventCountableEdge", - node: { - __typename: "OrderEvent", - amount: null, - composedId: null, - date: "2018-09-14T16:10:27.137126+00:00", - email: null, - emailType: null, - id: "T3JkZXJFdmVudDoxOA==", - message: null, - orderNumber: "15", - oversoldItems: null, - quantity: null, - type: OrderEventsEnum.PLACED_FROM_DRAFT, - user: { - __typename: "User", - email: "admin@example.com", - id: "VXNlcjoyMQ==", - }, + ordersToCapture: { + __typename: "OrderCountableConnection", + totalCount: 0, + }, + ordersToFulfill: { + __typename: "OrderCountableConnection", + totalCount: 1, + }, + + productsOutOfStock: { + __typename: "ProductCountableConnection", + totalCount: 0, + }, +}; + +export const activities: HomeActivitiesQuery["activities"] = { + __typename: "OrderEventCountableConnection", + edges: [ + { + __typename: "OrderEventCountableEdge", + node: { + __typename: "OrderEvent", + amount: null, + composedId: null, + date: "2018-09-14T16:10:27.137126+00:00", + email: null, + emailType: null, + id: "T3JkZXJFdmVudDoxOA==", + message: null, + orderNumber: "15", + oversoldItems: null, + quantity: null, + type: OrderEventsEnum.PLACED_FROM_DRAFT, + user: { + __typename: "User", + email: "admin@example.com", + id: "VXNlcjoyMQ==", }, }, - { - __typename: "OrderEventCountableEdge", - node: { - __typename: "OrderEvent", - amount: null, - composedId: null, - date: "2018-10-03T13:28:46.325279+00:00", - email: null, - emailType: null, - id: "T3JkZXJFdmVudDozNQ==", - message: null, - orderNumber: "15", - oversoldItems: null, - quantity: null, - type: OrderEventsEnum.PLACED, - user: null, - }, + }, + { + __typename: "OrderEventCountableEdge", + node: { + __typename: "OrderEvent", + amount: null, + composedId: null, + date: "2018-10-03T13:28:46.325279+00:00", + email: null, + emailType: null, + id: "T3JkZXJFdmVudDozNQ==", + message: null, + orderNumber: "15", + oversoldItems: null, + quantity: null, + type: OrderEventsEnum.PLACED, + user: null, }, - { - __typename: "OrderEventCountableEdge", - node: { - __typename: "OrderEvent", - amount: null, - composedId: null, - date: "2018-10-03T13:29:01.837496+00:00", - email: null, - emailType: null, - id: "T3JkZXJFdmVudDozNw==", - message: null, - orderNumber: "15", - oversoldItems: null, - quantity: null, - type: OrderEventsEnum.ORDER_FULLY_PAID, - user: null, - }, + }, + { + __typename: "OrderEventCountableEdge", + node: { + __typename: "OrderEvent", + amount: null, + composedId: null, + date: "2018-10-03T13:29:01.837496+00:00", + email: null, + emailType: null, + id: "T3JkZXJFdmVudDozNw==", + message: null, + orderNumber: "15", + oversoldItems: null, + quantity: null, + type: OrderEventsEnum.ORDER_FULLY_PAID, + user: null, }, - { - __typename: "OrderEventCountableEdge", - node: { - __typename: "OrderEvent", - amount: null, - composedId: null, - date: "2018-10-04T01:01:51.243723+00:00", - email: null, - emailType: null, - id: "T3JkZXJFdmVudDo1OA==", - message: null, - orderNumber: "15", - oversoldItems: null, - quantity: null, - type: OrderEventsEnum.PLACED_FROM_DRAFT, - user: { - __typename: "User", - email: "admin@example.com", - id: "VXNlcjoyMQ==", - }, + }, + { + __typename: "OrderEventCountableEdge", + node: { + __typename: "OrderEvent", + amount: null, + composedId: null, + date: "2018-10-04T01:01:51.243723+00:00", + email: null, + emailType: null, + id: "T3JkZXJFdmVudDo1OA==", + message: null, + orderNumber: "15", + oversoldItems: null, + quantity: null, + type: OrderEventsEnum.PLACED_FROM_DRAFT, + user: { + __typename: "User", + email: "admin@example.com", + id: "VXNlcjoyMQ==", }, }, - { - __typename: "OrderEventCountableEdge", - node: { - __typename: "OrderEvent", - amount: null, - composedId: null, - date: "2018-10-04T19:36:18.831561+00:00", - email: null, - emailType: null, - id: "T3JkZXJFdmVudDo2Nw==", - message: null, - orderNumber: "15", - oversoldItems: null, - quantity: null, - type: OrderEventsEnum.PLACED_FROM_DRAFT, - user: { - __typename: "User", - email: "admin@example.com", - id: "VXNlcjoyMQ==", - }, + }, + { + __typename: "OrderEventCountableEdge", + node: { + __typename: "OrderEvent", + amount: null, + composedId: null, + date: "2018-10-04T19:36:18.831561+00:00", + email: null, + emailType: null, + id: "T3JkZXJFdmVudDo2Nw==", + message: null, + orderNumber: "15", + oversoldItems: null, + quantity: null, + type: OrderEventsEnum.PLACED_FROM_DRAFT, + user: { + __typename: "User", + email: "admin@example.com", + id: "VXNlcjoyMQ==", }, }, - { - __typename: "OrderEventCountableEdge", - node: { - __typename: "OrderEvent", - amount: null, - composedId: null, - date: "2018-10-04T19:38:01.420365+00:00", - email: null, - emailType: null, - id: "T3JkZXJFdmVudDo2OA==", - message: null, - orderNumber: "15", - oversoldItems: null, - quantity: null, - type: OrderEventsEnum.PLACED_FROM_DRAFT, - user: { - __typename: "User", - email: "admin@example.com", - id: "VXNlcjoyMQ==", - }, + }, + { + __typename: "OrderEventCountableEdge", + node: { + __typename: "OrderEvent", + amount: null, + composedId: null, + date: "2018-10-04T19:38:01.420365+00:00", + email: null, + emailType: null, + id: "T3JkZXJFdmVudDo2OA==", + message: null, + orderNumber: "15", + oversoldItems: null, + quantity: null, + type: OrderEventsEnum.PLACED_FROM_DRAFT, + user: { + __typename: "User", + email: "admin@example.com", + id: "VXNlcjoyMQ==", }, }, - { - __typename: "OrderEventCountableEdge", - node: { - __typename: "OrderEvent", - amount: null, - composedId: null, - date: "2018-10-05T12:30:57.268592+00:00", - email: null, - emailType: null, - id: "T3JkZXJFdmVudDo3MQ==", - message: null, - orderNumber: "15", - oversoldItems: null, - quantity: null, - type: OrderEventsEnum.PLACED_FROM_DRAFT, - user: { - __typename: "User", - email: "admin@example.com", - id: "VXNlcjoyMQ==", - }, + }, + { + __typename: "OrderEventCountableEdge", + node: { + __typename: "OrderEvent", + amount: null, + composedId: null, + date: "2018-10-05T12:30:57.268592+00:00", + email: null, + emailType: null, + id: "T3JkZXJFdmVudDo3MQ==", + message: null, + orderNumber: "15", + oversoldItems: null, + quantity: null, + type: OrderEventsEnum.PLACED_FROM_DRAFT, + user: { + __typename: "User", + email: "admin@example.com", + id: "VXNlcjoyMQ==", }, }, - { - __typename: "OrderEventCountableEdge", - node: { - __typename: "OrderEvent", - amount: null, - composedId: null, - date: "2018-10-08T09:50:42.622253+00:00", - email: null, - emailType: null, - id: "T3JkZXJFdmVudDo3Mw==", - message: null, - orderNumber: "15", - oversoldItems: null, - quantity: null, - type: OrderEventsEnum.PLACED, - user: null, - }, + }, + { + __typename: "OrderEventCountableEdge", + node: { + __typename: "OrderEvent", + amount: null, + composedId: null, + date: "2018-10-08T09:50:42.622253+00:00", + email: null, + emailType: null, + id: "T3JkZXJFdmVudDo3Mw==", + message: null, + orderNumber: "15", + oversoldItems: null, + quantity: null, + type: OrderEventsEnum.PLACED, + user: null, }, - { - __typename: "OrderEventCountableEdge", - node: { - __typename: "OrderEvent", - amount: null, - composedId: null, - date: "2018-10-12T15:51:11.665838+00:00", - email: null, - emailType: null, - id: "T3JkZXJFdmVudDo3Nw==", - message: null, - orderNumber: "15", - oversoldItems: null, - quantity: null, - type: OrderEventsEnum.PLACED_FROM_DRAFT, - user: { - __typename: "User", - email: "admin@example.com", - id: "VXNlcjoyMQ==", - }, + }, + { + __typename: "OrderEventCountableEdge", + node: { + __typename: "OrderEvent", + amount: null, + composedId: null, + date: "2018-10-12T15:51:11.665838+00:00", + email: null, + emailType: null, + id: "T3JkZXJFdmVudDo3Nw==", + message: null, + orderNumber: "15", + oversoldItems: null, + quantity: null, + type: OrderEventsEnum.PLACED_FROM_DRAFT, + user: { + __typename: "User", + email: "admin@example.com", + id: "VXNlcjoyMQ==", }, }, - { - __typename: "OrderEventCountableEdge", - node: { - __typename: "OrderEvent", - amount: null, - composedId: null, - date: "2018-10-12T15:51:11.665838+00:00", + }, + { + __typename: "OrderEventCountableEdge", + node: { + __typename: "OrderEvent", + amount: null, + composedId: null, + date: "2018-10-12T15:51:11.665838+00:00", + email: null, + emailType: null, + id: "T3JkZXJFdmVudDo3Nw==", + message: null, + orderNumber: "15", + oversoldItems: null, + quantity: null, + type: OrderEventsEnum.PLACED_FROM_DRAFT, + user: { + __typename: "User", email: null, - emailType: null, - id: "T3JkZXJFdmVudDo3Nw==", - message: null, - orderNumber: "15", - oversoldItems: null, - quantity: null, - type: OrderEventsEnum.PLACED_FROM_DRAFT, - user: { - __typename: "User", - email: null, - id: "VXNlcjoyMQ==", - }, + id: "VXNlcjoyMQ==", }, }, - { - __typename: "OrderEventCountableEdge", - node: { - __typename: "OrderEvent", - amount: null, - composedId: null, - date: "2018-10-25T11:25:58.843860+00:00", - email: null, - emailType: null, - id: "T3JkZXJFdmVudDo3OA==", - message: null, - orderNumber: "15", - oversoldItems: null, - quantity: null, - type: OrderEventsEnum.PLACED, - user: null, - }, + }, + { + __typename: "OrderEventCountableEdge", + node: { + __typename: "OrderEvent", + amount: null, + composedId: null, + date: "2018-10-25T11:25:58.843860+00:00", + email: null, + emailType: null, + id: "T3JkZXJFdmVudDo3OA==", + message: null, + orderNumber: "15", + oversoldItems: null, + quantity: null, + type: OrderEventsEnum.PLACED, + user: null, }, - { - __typename: "OrderEventCountableEdge", - node: { - __typename: "OrderEvent", - amount: null, - composedId: null, - date: "2018-10-26T09:34:57.580167+00:00", - email: null, - emailType: null, - id: "T3JkZXJFdmVudDo4MA==", - message: null, - orderNumber: "15", - oversoldItems: null, - quantity: null, - type: OrderEventsEnum.PLACED, - user: null, - }, + }, + { + __typename: "OrderEventCountableEdge", + node: { + __typename: "OrderEvent", + amount: null, + composedId: null, + date: "2018-10-26T09:34:57.580167+00:00", + email: null, + emailType: null, + id: "T3JkZXJFdmVudDo4MA==", + message: null, + orderNumber: "15", + oversoldItems: null, + quantity: null, + type: OrderEventsEnum.PLACED, + user: null, }, - { - __typename: "OrderEventCountableEdge", - node: { - __typename: "OrderEvent", - amount: null, - composedId: null, - date: "2018-10-26T09:38:02.440061+00:00", - email: null, - emailType: null, - id: "T3JkZXJFdmVudDo4Mg==", - message: null, - orderNumber: "15", - oversoldItems: null, - quantity: null, - type: OrderEventsEnum.ORDER_FULLY_PAID, - user: null, - }, + }, + { + __typename: "OrderEventCountableEdge", + node: { + __typename: "OrderEvent", + amount: null, + composedId: null, + date: "2018-10-26T09:38:02.440061+00:00", + email: null, + emailType: null, + id: "T3JkZXJFdmVudDo4Mg==", + message: null, + orderNumber: "15", + oversoldItems: null, + quantity: null, + type: OrderEventsEnum.ORDER_FULLY_PAID, + user: null, }, - { - __typename: "OrderEventCountableEdge", - node: { - __typename: "OrderEvent", - amount: null, - composedId: null, - date: "2018-10-26T09:38:02.467443+00:00", - email: null, - emailType: null, - id: "T3JkZXJFdmVudDo4NA==", - message: null, - orderNumber: "15", - oversoldItems: null, - quantity: null, - type: OrderEventsEnum.ORDER_FULLY_PAID, - user: null, - }, + }, + { + __typename: "OrderEventCountableEdge", + node: { + __typename: "OrderEvent", + amount: null, + composedId: null, + date: "2018-10-26T09:38:02.467443+00:00", + email: null, + emailType: null, + id: "T3JkZXJFdmVudDo4NA==", + message: null, + orderNumber: "15", + oversoldItems: null, + quantity: null, + type: OrderEventsEnum.ORDER_FULLY_PAID, + user: null, }, - ], - }, - ordersToCapture: { - __typename: "OrderCountableConnection", - totalCount: 0, - }, - ordersToFulfill: { - __typename: "OrderCountableConnection", - totalCount: 1, - }, - ordersToday: { - __typename: "OrderCountableConnection", - totalCount: 1, - }, - productTopToday: { - __typename: "ProductVariantCountableConnection", - edges: [ - { - __typename: "ProductVariantCountableEdge", - node: { - __typename: "ProductVariant", - attributes: [ - { - __typename: "SelectedAttribute", - values: [ - { - __typename: "AttributeValue", - id: "QXR0cmlidXRlVmFsdWU6OTI=", - name: "XL", - sortOrder: 0, - }, - ], - }, - ], - id: "UHJvZHVjdFZhcmlhbnQ6NDM=", - product: { - __typename: "Product", - id: "UHJvZHVjdDo4", - name: "Black Hoodie", - thumbnail: { - __typename: "Image", - url: placeholderImage, - }, + }, + ], +}; + +export const topProducts: ( + placeholderImage: string, +) => HomeTopProductsQuery["productTopToday"] = (placeholderImage: string) => ({ + __typename: "ProductVariantCountableConnection", + edges: [ + { + __typename: "ProductVariantCountableEdge", + node: { + __typename: "ProductVariant", + attributes: [ + { + __typename: "SelectedAttribute", + values: [ + { + __typename: "AttributeValue", + id: "QXR0cmlidXRlVmFsdWU6OTI=", + name: "XL", + sortOrder: 0, + }, + ], }, - quantityOrdered: 1, - revenue: { - __typename: "TaxedMoney", - gross: { - __typename: "Money", - amount: 37.65, - currency: "USD", - }, + ], + id: "UHJvZHVjdFZhcmlhbnQ6NDM=", + product: { + __typename: "Product", + id: "UHJvZHVjdDo4", + name: "Black Hoodie", + thumbnail: { + __typename: "Image", + url: placeholderImage, + }, + }, + quantityOrdered: 1, + revenue: { + __typename: "TaxedMoney", + gross: { + __typename: "Money", + amount: 37.65, + currency: "USD", }, }, }, - { - __typename: "ProductVariantCountableEdge", - node: { - __typename: "ProductVariant", - attributes: [ - { - __typename: "SelectedAttribute", - values: [ - { - __typename: "AttributeValue", - id: "QXR0cmlidXRlVmFsdWU6OTI2=", - name: "2l", - sortOrder: 0, - }, - ], - }, - ], - id: "UHJvZHVjdFZhcmlhbnQ6NDM=2", - product: { - __typename: "Product", - id: "UHJvZHVjdDo4", - name: "Bean Juice", - thumbnail: { - __typename: "Image", - url: placeholderImage, - }, + }, + { + __typename: "ProductVariantCountableEdge", + node: { + __typename: "ProductVariant", + attributes: [ + { + __typename: "SelectedAttribute", + values: [ + { + __typename: "AttributeValue", + id: "QXR0cmlidXRlVmFsdWU6OTI2=", + name: "2l", + sortOrder: 0, + }, + ], }, - quantityOrdered: 1, - revenue: { - __typename: "TaxedMoney", - gross: { - __typename: "Money", - amount: 37.65, - currency: "USD", - }, + ], + id: "UHJvZHVjdFZhcmlhbnQ6NDM=2", + product: { + __typename: "Product", + id: "UHJvZHVjdDo4", + name: "Bean Juice", + thumbnail: { + __typename: "Image", + url: placeholderImage, + }, + }, + quantityOrdered: 1, + revenue: { + __typename: "TaxedMoney", + gross: { + __typename: "Money", + amount: 37.65, + currency: "USD", }, }, }, - { - __typename: "ProductVariantCountableEdge", - node: { - __typename: "ProductVariant", - attributes: [ - { - __typename: "SelectedAttribute", - values: [ - { - __typename: "AttributeValue", - id: "QXR0cmlidXRlVmFsdWU6OTI=3", - name: "L", - sortOrder: 0, - }, - ], - }, - ], - id: "UHJvZHVjdFZhcmlhbnQ6NDM=3", - product: { - __typename: "Product", - id: "UHJvZHVjdDo4", - name: "Black Hoodie", - thumbnail: { - __typename: "Image", - url: placeholderImage, - }, + }, + { + __typename: "ProductVariantCountableEdge", + node: { + __typename: "ProductVariant", + attributes: [ + { + __typename: "SelectedAttribute", + values: [ + { + __typename: "AttributeValue", + id: "QXR0cmlidXRlVmFsdWU6OTI=3", + name: "L", + sortOrder: 0, + }, + ], }, - quantityOrdered: 1, - revenue: { - __typename: "TaxedMoney", - gross: { - __typename: "Money", - amount: 37.65, - currency: "USD", - }, + ], + id: "UHJvZHVjdFZhcmlhbnQ6NDM=3", + product: { + __typename: "Product", + id: "UHJvZHVjdDo4", + name: "Black Hoodie", + thumbnail: { + __typename: "Image", + url: placeholderImage, + }, + }, + quantityOrdered: 1, + revenue: { + __typename: "TaxedMoney", + gross: { + __typename: "Money", + amount: 37.65, + currency: "USD", }, }, }, - ], - }, - productsOutOfStock: { - __typename: "ProductCountableConnection", - totalCount: 0, - }, + }, + ], +}); + +export const analitics: HomeAnaliticsQuery = { + __typename: "Query", salesToday: { __typename: "TaxedMoney", gross: { @@ -431,4 +442,8 @@ export const shop = (placeholderImage: string) => ({ currency: "USD", }, }, -}); + ordersToday: { + __typename: "OrderCountableConnection", + totalCount: 1, + }, +}; From 66057d9de528845d5167fe12eceaf7cfc82324ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Chy=C5=82a?= Date: Tue, 7 Nov 2023 10:30:01 +0100 Subject: [PATCH 09/13] Add changeset --- .changeset/funny-badgers-begin.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/funny-badgers-begin.md diff --git a/.changeset/funny-badgers-begin.md b/.changeset/funny-badgers-begin.md new file mode 100644 index 00000000000..ed3c4b47d22 --- /dev/null +++ b/.changeset/funny-badgers-begin.md @@ -0,0 +1,5 @@ +--- +"saleor-dashboard": minor +--- + +Delay home queries to be non-blocking for the UI From deb71c35fd99057f2e470f40681c89a4dafec0d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Chy=C5=82a?= Date: Tue, 7 Nov 2023 10:40:42 +0100 Subject: [PATCH 10/13] Extract messages --- locale/defaultMessages.json | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/locale/defaultMessages.json b/locale/defaultMessages.json index f1898222395..db54ee1655d 100644 --- a/locale/defaultMessages.json +++ b/locale/defaultMessages.json @@ -214,6 +214,9 @@ "context": "section description", "string": "Strategy defines the preference of warehouses for stock allocations and reservations." }, + "/Fa+RP": { + "string": "Couldn't load top products" + }, "/ILyIf": { "context": "tax classes menu header", "string": "Tax class label" @@ -241,6 +244,9 @@ "context": "page label", "string": "Hidden" }, + "/U8FUp": { + "string": "Couldn't load activities" + }, "/V7UOC": { "context": "unassign category from sale and save, button", "string": "Unassign and save" From e42f4d32dc92a9a1739f4a31556e05b0634f5aa6 Mon Sep 17 00:00:00 2001 From: wojteknowacki Date: Thu, 9 Nov 2023 12:51:27 +0100 Subject: [PATCH 11/13] changed await request when logged in to UserDetails --- cypress/support/customCommands/user/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cypress/support/customCommands/user/index.js b/cypress/support/customCommands/user/index.js index 0e62fd78cc6..18717a28c6d 100644 --- a/cypress/support/customCommands/user/index.js +++ b/cypress/support/customCommands/user/index.js @@ -19,10 +19,10 @@ Cypress.Commands.add("loginInShop", () => { }); Cypress.Commands.add("visitHomePageLoggedViaApi", user => { - cy.addAliasToGraphRequest("Home") + cy.addAliasToGraphRequest("UserDetails") .loginUserViaRequest("auth", user) .visit(urlList.homePage) - .waitForRequestAndCheckIfNoErrors("@Home"); + .waitForRequestAndCheckIfNoErrors("@UserDetails"); }); Cypress.Commands.add( From 82f31da4627b9aefc0c2e636cbeab357c6488bf5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Chy=C5=82a?= Date: Thu, 9 Nov 2023 13:18:22 +0100 Subject: [PATCH 12/13] Use permission variables instaed of skip --- src/graphql/hooks.generated.ts | 19 +++++++++++-------- src/graphql/types.generated.ts | 6 +++++- src/home/queries.ts | 24 +++++++++++++++++------- src/home/views/index.tsx | 11 ++++++++--- 4 files changed, 41 insertions(+), 19 deletions(-) diff --git a/src/graphql/hooks.generated.ts b/src/graphql/hooks.generated.ts index ecf93d3a74a..1cd20eac590 100644 --- a/src/graphql/hooks.generated.ts +++ b/src/graphql/hooks.generated.ts @@ -8844,14 +8844,14 @@ export type CustomerGiftCardListQueryHookResult = ReturnType; export type CustomerGiftCardListQueryResult = Apollo.QueryResult; export const HomeAnaliticsDocument = gql` - query HomeAnalitics($channel: String!, $datePeriod: DateRangeInput!) { - salesToday: ordersTotal(period: TODAY, channel: $channel) { + query HomeAnalitics($channel: String!, $datePeriod: DateRangeInput!, $hasPermissionToManageOrders: Boolean!) { + salesToday: ordersTotal(period: TODAY, channel: $channel) @include(if: $hasPermissionToManageOrders) { gross { amount currency } } - ordersToday: orders(filter: {created: $datePeriod}, channel: $channel) { + ordersToday: orders(filter: {created: $datePeriod}, channel: $channel) @include(if: $hasPermissionToManageOrders) { totalCount } } @@ -8871,6 +8871,7 @@ export const HomeAnaliticsDocument = gql` * variables: { * channel: // value for 'channel' * datePeriod: // value for 'datePeriod' + * hasPermissionToManageOrders: // value for 'hasPermissionToManageOrders' * }, * }); */ @@ -8886,8 +8887,8 @@ export type HomeAnaliticsQueryHookResult = ReturnType; export type HomeAnaliticsQueryResult = Apollo.QueryResult; export const HomeActivitiesDocument = gql` - query HomeActivities { - activities: homepageEvents(last: 10) { + query HomeActivities($hasPermissionToManageOrders: Boolean!) { + activities: homepageEvents(last: 10) @include(if: $hasPermissionToManageOrders) { edges { node { amount @@ -8923,10 +8924,11 @@ export const HomeActivitiesDocument = gql` * @example * const { data, loading, error } = useHomeActivitiesQuery({ * variables: { + * hasPermissionToManageOrders: // value for 'hasPermissionToManageOrders' * }, * }); */ -export function useHomeActivitiesQuery(baseOptions?: ApolloReactHooks.QueryHookOptions) { +export function useHomeActivitiesQuery(baseOptions: ApolloReactHooks.QueryHookOptions) { const options = {...defaultOptions, ...baseOptions} return ApolloReactHooks.useQuery(HomeActivitiesDocument, options); } @@ -8938,8 +8940,8 @@ export type HomeActivitiesQueryHookResult = ReturnType; export type HomeActivitiesQueryResult = Apollo.QueryResult; export const HomeTopProductsDocument = gql` - query HomeTopProducts($channel: String!) { - productTopToday: reportProductSales(period: TODAY, first: 5, channel: $channel) { + query HomeTopProducts($channel: String!, $hasPermissionToManageProducts: Boolean!) { + productTopToday: reportProductSales(period: TODAY, first: 5, channel: $channel) @include(if: $hasPermissionToManageProducts) { edges { node { id @@ -8982,6 +8984,7 @@ export const HomeTopProductsDocument = gql` * const { data, loading, error } = useHomeTopProductsQuery({ * variables: { * channel: // value for 'channel' + * hasPermissionToManageProducts: // value for 'hasPermissionToManageProducts' * }, * }); */ diff --git a/src/graphql/types.generated.ts b/src/graphql/types.generated.ts index 0d16da63392..3799b06281c 100644 --- a/src/graphql/types.generated.ts +++ b/src/graphql/types.generated.ts @@ -10280,18 +10280,22 @@ export type CustomerGiftCardListQuery = { __typename: 'Query', giftCards: { __ty export type HomeAnaliticsQueryVariables = Exact<{ channel: Scalars['String']; datePeriod: DateRangeInput; + hasPermissionToManageOrders: Scalars['Boolean']; }>; export type HomeAnaliticsQuery = { __typename: 'Query', salesToday: { __typename: 'TaxedMoney', gross: { __typename: 'Money', amount: number, currency: string } } | null, ordersToday: { __typename: 'OrderCountableConnection', totalCount: number | null } | null }; -export type HomeActivitiesQueryVariables = Exact<{ [key: string]: never; }>; +export type HomeActivitiesQueryVariables = Exact<{ + hasPermissionToManageOrders: Scalars['Boolean']; +}>; export type HomeActivitiesQuery = { __typename: 'Query', activities: { __typename: 'OrderEventCountableConnection', edges: Array<{ __typename: 'OrderEventCountableEdge', node: { __typename: 'OrderEvent', amount: number | null, composedId: string | null, date: any | null, email: string | null, emailType: OrderEventsEmailsEnum | null, id: string, message: string | null, orderNumber: string | null, oversoldItems: Array | null, quantity: number | null, type: OrderEventsEnum | null, user: { __typename: 'User', id: string, email: string } | null } }> } | null }; export type HomeTopProductsQueryVariables = Exact<{ channel: Scalars['String']; + hasPermissionToManageProducts: Scalars['Boolean']; }>; diff --git a/src/home/queries.ts b/src/home/queries.ts index 02d1a354aaf..b831fc0226e 100644 --- a/src/home/queries.ts +++ b/src/home/queries.ts @@ -1,22 +1,29 @@ import { gql } from "@apollo/client"; export const homeAnalitics = gql` - query HomeAnalitics($channel: String!, $datePeriod: DateRangeInput!) { - salesToday: ordersTotal(period: TODAY, channel: $channel) { + query HomeAnalitics( + $channel: String! + $datePeriod: DateRangeInput! + $hasPermissionToManageOrders: Boolean! + ) { + salesToday: ordersTotal(period: TODAY, channel: $channel) + @include(if: $hasPermissionToManageOrders) { gross { amount currency } } - ordersToday: orders(filter: { created: $datePeriod }, channel: $channel) { + ordersToday: orders(filter: { created: $datePeriod }, channel: $channel) + @include(if: $hasPermissionToManageOrders) { totalCount } } `; export const homeActivities = gql` - query HomeActivities { - activities: homepageEvents(last: 10) { + query HomeActivities($hasPermissionToManageOrders: Boolean!) { + activities: homepageEvents(last: 10) + @include(if: $hasPermissionToManageOrders) { edges { node { amount @@ -41,12 +48,15 @@ export const homeActivities = gql` `; export const homeTopProducts = gql` - query HomeTopProducts($channel: String!) { + query HomeTopProducts( + $channel: String! + $hasPermissionToManageProducts: Boolean! + ) { productTopToday: reportProductSales( period: TODAY first: 5 channel: $channel - ) { + ) @include(if: $hasPermissionToManageProducts) { edges { node { id diff --git a/src/home/views/index.tsx b/src/home/views/index.tsx index 4e70857a4cc..4d6e11b52ce 100644 --- a/src/home/views/index.tsx +++ b/src/home/views/index.tsx @@ -39,7 +39,10 @@ const HomeSection = () => { loading: homeActivitiesLoading, error: homeActivitiesError, } = useHomeActivitiesQuery({ - skip: noChannel || !hasPermissionToManageOrders, + skip: noChannel, + variables: { + hasPermissionToManageOrders, + }, }); const { @@ -47,9 +50,10 @@ const HomeSection = () => { loading: homeTopProductsLoading, error: homeTopProductsError, } = useHomeTopProductsQuery({ - skip: noChannel || !hasPermissionToManageProducts, + skip: noChannel, variables: { channel: channel?.slug, + hasPermissionToManageProducts, }, }); @@ -70,10 +74,11 @@ const HomeSection = () => { loading: homeAnaliticsLoading, error: homeAnaliticsError, } = useHomeAnaliticsQuery({ - skip: noChannel || !hasPermissionToManageOrders, + skip: noChannel, variables: { channel: channel?.slug, datePeriod: getDatePeriod(1), + hasPermissionToManageOrders, }, }); From d844128a8491d8a05da5988b0b55e0e4aab6d834 Mon Sep 17 00:00:00 2001 From: wojteknowacki Date: Fri, 10 Nov 2023 08:51:45 +0100 Subject: [PATCH 13/13] removed await request when changing channel --- cypress/support/pages/homePage.js | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/cypress/support/pages/homePage.js b/cypress/support/pages/homePage.js index 09abf4a0cae..f501eafa5e6 100644 --- a/cypress/support/pages/homePage.js +++ b/cypress/support/pages/homePage.js @@ -4,11 +4,9 @@ import { HOMEPAGE_SELECTORS } from "../../elements/homePage/homePage-selectors"; export function changeChannel(channelName) { cy.get(HEADER_SELECTORS.channelSelect) .click() - .addAliasToGraphRequest("Home") .get(HEADER_SELECTORS.channelSelectList) .contains(channelName) - .click() - .wait("@Home"); + .click(); } export function expectWelcomeMessageIncludes(name) { @@ -21,37 +19,37 @@ export function expectWelcomeMessageIncludes(name) { export function getOrdersReadyToFulfillRegex( ordersReadyToFulfillBefore, - quantityOfNewOrders + quantityOfNewOrders, ) { const allOrdersReadyToFulfill = ordersReadyToFulfillBefore + quantityOfNewOrders; const notANumberRegex = "\\D*"; return new RegExp( - `${notANumberRegex}${allOrdersReadyToFulfill}${notANumberRegex}` + `${notANumberRegex}${allOrdersReadyToFulfill}${notANumberRegex}`, ); } export function getOrdersReadyForCaptureRegex( ordersReadyForCaptureBefore, - quantityOfNewOrders + quantityOfNewOrders, ) { const allOrdersReadyForCapture = ordersReadyForCaptureBefore + quantityOfNewOrders; const notANumberRegex = "\\D*"; return new RegExp( - `${notANumberRegex}${allOrdersReadyForCapture}${notANumberRegex}` + `${notANumberRegex}${allOrdersReadyForCapture}${notANumberRegex}`, ); } export function getProductsOutOfStockRegex( productsOutOfStockBefore, - quantityOfNewProducts + quantityOfNewProducts, ) { const allProductsOutOfStock = productsOutOfStockBefore + quantityOfNewProducts; const notANumberRegex = "\\D*"; return new RegExp( - `${notANumberRegex}${allProductsOutOfStock}${notANumberRegex}` + `${notANumberRegex}${allProductsOutOfStock}${notANumberRegex}`, ); } @@ -67,7 +65,7 @@ export function getSalesAmountRegex(salesAmountBefore, addedAmount) { const totalAmountWithSeparators = `${totalAmountIntegerWithThousandsSeparator}${decimalSeparator}${totalAmountDecimalValue}`; const notANumberRegex = "\\D*"; return new RegExp( - `${notANumberRegex}${totalAmountWithSeparators}${notANumberRegex}` + `${notANumberRegex}${totalAmountWithSeparators}${notANumberRegex}`, ); }