Improve invoices app loading strategy (#253)
* Invoices: Remove initial loading spinner and postpone NotifyReady event * Remove graphql provider * Remove unused Loader component
This commit is contained in:
parent
f8de90b56b
commit
639dfc33ad
8 changed files with 27 additions and 65 deletions
5
.changeset/dirty-olives-search.md
Normal file
5
.changeset/dirty-olives-search.md
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
"saleor-app-invoices": minor
|
||||||
|
---
|
||||||
|
|
||||||
|
App no longer shows initial loading spinner. It renders nothing until initial required data (channels) are fetched. When this happens, AppBridge informs Dashboard (via NotifyReady action) that it can be displayed.
|
5
.changeset/perfect-zoos-notice.md
Normal file
5
.changeset/perfect-zoos-notice.md
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
"saleor-app-invoices": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Removed frontend GraphQL provider, because no frontend queries are used
|
|
@ -7,7 +7,6 @@ import { AddressForm } from "./address-form";
|
||||||
import { ChannelsList } from "./channels-list";
|
import { ChannelsList } from "./channels-list";
|
||||||
import { actions, useAppBridge } from "@saleor/app-sdk/app-bridge";
|
import { actions, useAppBridge } from "@saleor/app-sdk/app-bridge";
|
||||||
import { AppColumnsLayout } from "../../ui/app-columns-layout";
|
import { AppColumnsLayout } from "../../ui/app-columns-layout";
|
||||||
import { Loader } from "../../ui/loader";
|
|
||||||
|
|
||||||
const useStyles = makeStyles((theme) => {
|
const useStyles = makeStyles((theme) => {
|
||||||
return {
|
return {
|
||||||
|
@ -60,7 +59,7 @@ export const ChannelsConfiguration = () => {
|
||||||
}, [channels.data, activeChannelSlug]);
|
}, [channels.data, activeChannelSlug]);
|
||||||
|
|
||||||
if (channels.isLoading || !channels.data) {
|
if (channels.isLoading || !channels.data) {
|
||||||
return <Loader />;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!activeChannel) {
|
if (!activeChannel) {
|
||||||
|
|
|
@ -1,21 +0,0 @@
|
||||||
import { CircularProgress } from "@material-ui/core";
|
|
||||||
import { makeStyles } from "@saleor/macaw-ui";
|
|
||||||
|
|
||||||
const useStyles = makeStyles({
|
|
||||||
root: {
|
|
||||||
display: "flex",
|
|
||||||
alignItems: "center",
|
|
||||||
justifyContent: "center",
|
|
||||||
height: 300,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
export const Loader = () => {
|
|
||||||
const styles = useStyles();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className={styles.root}>
|
|
||||||
<CircularProgress color="primary" />
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
|
@ -4,8 +4,6 @@ import { AppBridge, AppBridgeProvider } from "@saleor/app-sdk/app-bridge";
|
||||||
import { RoutePropagator } from "@saleor/app-sdk/app-bridge/next";
|
import { RoutePropagator } from "@saleor/app-sdk/app-bridge/next";
|
||||||
import React, { useEffect } from "react";
|
import React, { useEffect } from "react";
|
||||||
import { AppProps } from "next/app";
|
import { AppProps } from "next/app";
|
||||||
|
|
||||||
import GraphQLProvider from "../providers/GraphQLProvider";
|
|
||||||
import { ThemeSynchronizer } from "../lib/theme-synchronizer";
|
import { ThemeSynchronizer } from "../lib/theme-synchronizer";
|
||||||
import { NoSSRWrapper } from "../lib/no-ssr-wrapper";
|
import { NoSSRWrapper } from "../lib/no-ssr-wrapper";
|
||||||
import { trpcClient } from "../modules/trpc/trpc-client";
|
import { trpcClient } from "../modules/trpc/trpc-client";
|
||||||
|
@ -15,7 +13,8 @@ import { MacawThemeProvider } from "@saleor/apps-shared";
|
||||||
* Ensure instance is a singleton.
|
* Ensure instance is a singleton.
|
||||||
* TODO: This is React 18 issue, consider hiding this workaround inside app-sdk
|
* TODO: This is React 18 issue, consider hiding this workaround inside app-sdk
|
||||||
*/
|
*/
|
||||||
export const appBridgeInstance = typeof window !== "undefined" ? new AppBridge() : undefined;
|
export const appBridgeInstance =
|
||||||
|
typeof window !== "undefined" ? new AppBridge({ autoNotifyReady: false }) : undefined;
|
||||||
|
|
||||||
function NextApp({ Component, pageProps }: AppProps) {
|
function NextApp({ Component, pageProps }: AppProps) {
|
||||||
/**
|
/**
|
||||||
|
@ -31,13 +30,11 @@ function NextApp({ Component, pageProps }: AppProps) {
|
||||||
return (
|
return (
|
||||||
<NoSSRWrapper>
|
<NoSSRWrapper>
|
||||||
<AppBridgeProvider appBridgeInstance={appBridgeInstance}>
|
<AppBridgeProvider appBridgeInstance={appBridgeInstance}>
|
||||||
<GraphQLProvider>
|
<MacawThemeProvider>
|
||||||
<MacawThemeProvider>
|
<ThemeSynchronizer />
|
||||||
<ThemeSynchronizer />
|
<RoutePropagator />
|
||||||
<RoutePropagator />
|
<Component {...pageProps} />
|
||||||
<Component {...pageProps} />
|
</MacawThemeProvider>
|
||||||
</MacawThemeProvider>
|
|
||||||
</GraphQLProvider>
|
|
||||||
</AppBridgeProvider>
|
</AppBridgeProvider>
|
||||||
</NoSSRWrapper>
|
</NoSSRWrapper>
|
||||||
);
|
);
|
||||||
|
|
|
@ -9,16 +9,15 @@ const ConfigurationPage: NextPage = () => {
|
||||||
const channels = trpcClient.channels.fetch.useQuery();
|
const channels = trpcClient.channels.fetch.useQuery();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
const { appBridge } = useAppBridge();
|
const { appBridge, appBridgeState } = useAppBridge();
|
||||||
|
|
||||||
const openInNewTab = (url: string) => {
|
useEffect(() => {
|
||||||
appBridge?.dispatch(
|
if (channels.isFetched && appBridge && !appBridgeState?.ready) {
|
||||||
actions.Redirect({
|
if (appBridge && channels.isFetched) {
|
||||||
to: url,
|
appBridge.dispatch(actions.NotifyReady());
|
||||||
newContext: true,
|
}
|
||||||
})
|
}
|
||||||
);
|
}, [channels.isFetched, appBridge, appBridgeState?.ready]);
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (channels.isSuccess && channels.data.length === 0) {
|
if (channels.isSuccess && channels.data.length === 0) {
|
||||||
|
|
|
@ -4,7 +4,6 @@ import { useEffect } from "react";
|
||||||
import { useIsMounted } from "usehooks-ts";
|
import { useIsMounted } from "usehooks-ts";
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
import { isInIframe } from "@saleor/apps-shared";
|
import { isInIframe } from "@saleor/apps-shared";
|
||||||
import { Loader } from "../modules/ui/loader";
|
|
||||||
|
|
||||||
const IndexPage: NextPage = () => {
|
const IndexPage: NextPage = () => {
|
||||||
const { appBridgeState } = useAppBridge();
|
const { appBridgeState } = useAppBridge();
|
||||||
|
@ -18,7 +17,7 @@ const IndexPage: NextPage = () => {
|
||||||
}, [isMounted, appBridgeState?.ready]);
|
}, [isMounted, appBridgeState?.ready]);
|
||||||
|
|
||||||
if (isInIframe()) {
|
if (isInIframe()) {
|
||||||
return <Loader />;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -1,21 +0,0 @@
|
||||||
import { useAppBridge } from "@saleor/app-sdk/app-bridge";
|
|
||||||
import { PropsWithChildren } from "react";
|
|
||||||
import { Provider } from "urql";
|
|
||||||
|
|
||||||
import { createClient } from "../lib/graphql";
|
|
||||||
|
|
||||||
function GraphQLProvider(props: PropsWithChildren<{}>) {
|
|
||||||
const { appBridgeState } = useAppBridge();
|
|
||||||
|
|
||||||
if (!appBridgeState?.saleorApiUrl) {
|
|
||||||
return <div {...props}></div>;
|
|
||||||
}
|
|
||||||
|
|
||||||
const client = createClient(appBridgeState?.saleorApiUrl, async () =>
|
|
||||||
Promise.resolve({ token: appBridgeState?.token! })
|
|
||||||
);
|
|
||||||
|
|
||||||
return <Provider value={client} {...props} />;
|
|
||||||
}
|
|
||||||
|
|
||||||
export default GraphQLProvider;
|
|
Loading…
Reference in a new issue