import useAppState from "@saleor/hooks/useAppState"; import { ThemeProvider } from "@saleor/macaw-ui"; import { defaultDataIdFromObject, InMemoryCache } from "apollo-cache-inmemory"; import { ApolloClient } from "apollo-client"; import { ApolloLink } from "apollo-link"; import { BatchHttpLink } from "apollo-link-batch-http"; import { createUploadLink } from "apollo-upload-client"; import React from "react"; import { ApolloProvider } from "react-apollo"; import { render } from "react-dom"; import ErrorBoundary from "react-error-boundary"; import TagManager from "react-gtm-module"; import { useIntl } from "react-intl"; import { BrowserRouter, Route, Switch } from "react-router-dom"; import AppsSection from "./apps"; import { ExternalAppProvider } from "./apps/components/ExternalAppContext"; import { appsSection } from "./apps/urls"; import AttributeSection from "./attributes"; import { attributeSection } from "./attributes/urls"; import Auth from "./auth"; import AuthProvider, { useAuth } from "./auth/AuthProvider"; import LoginLoading from "./auth/components/LoginLoading/LoginLoading"; import SectionRoute from "./auth/components/SectionRoute"; import authLink from "./auth/link"; import { hasPermission } from "./auth/misc"; import CategorySection from "./categories"; import ChannelsSection from "./channels"; import { channelsSection } from "./channels/urls"; import CollectionSection from "./collections"; import AppLayout from "./components/AppLayout"; import useAppChannel, { AppChannelProvider } from "./components/AppLayout/AppChannelContext"; import { DateProvider } from "./components/Date"; import { LocaleProvider } from "./components/Locale"; import MessageManagerProvider from "./components/messages"; import { ShopProvider } from "./components/Shop"; import { WindowTitle } from "./components/WindowTitle"; import { API_URI, APP_MOUNT_URI, GTM_ID } from "./config"; import ConfigurationSection, { createConfigurationMenu } from "./configuration"; import AppStateProvider from "./containers/AppState"; import BackgroundTasksProvider from "./containers/BackgroundTasks"; import ServiceWorker from "./containers/ServiceWorker/ServiceWorker"; import { CustomerSection } from "./customers"; import DiscountSection from "./discounts"; import GiftCardSection from "./giftCards"; import { giftCardsSectionUrlName } from "./giftCards/urls"; import HomePage from "./home"; import { commonMessages } from "./intl"; import NavigationSection from "./navigation"; import { navigationSection } from "./navigation/urls"; import { NotFound } from "./NotFound"; import OrdersSection from "./orders"; import PageSection from "./pages"; import PageTypesSection from "./pageTypes"; import PermissionGroupSection from "./permissionGroups"; import PluginsSection from "./plugins"; import ProductSection from "./products"; import ProductTypesSection from "./productTypes"; import errorTracker from "./services/errorTracking"; import ShippingSection from "./shipping"; import SiteSettingsSection from "./siteSettings"; import StaffSection from "./staff"; import TaxesSection from "./taxes"; import themeOverrides from "./themeOverrides"; import TranslationsSection from "./translations"; import { PermissionEnum } from "./types/globalTypes"; import WarehouseSection from "./warehouses"; import { warehouseSection } from "./warehouses/urls"; if (process.env.GTM_ID) { TagManager.initialize({ gtmId: GTM_ID }); } errorTracker.init(); // DON'T TOUCH THIS // These are separate clients and do not share configs between themselves // so we need to explicitly set them const linkOptions = { credentials: "include", uri: API_URI }; const uploadLink = createUploadLink(linkOptions); const batchLink = new BatchHttpLink({ batchInterval: 100, ...linkOptions }); const link = ApolloLink.split( operation => operation.getContext().useBatching, batchLink, uploadLink ); const apolloClient = new ApolloClient({ cache: new InMemoryCache({ dataIdFromObject: (obj: any) => { // We need to set manually shop's ID, since it is singleton and // API does not return its ID if (obj.__typename === "Shop") { return "shop"; } return defaultDataIdFromObject(obj); } }), link: authLink.concat(link) }); const App: React.FC = () => ( ); const Routes: React.FC = () => { const intl = useIntl(); const [, dispatchAppState] = useAppState(); const { hasToken, isAuthenticated, tokenAuthLoading, tokenVerifyLoading, user } = useAuth(); const { channel } = useAppChannel(false); const channelLoaded = typeof channel !== "undefined"; const homePageLoaded = channelLoaded && isAuthenticated && !tokenAuthLoading && !tokenVerifyLoading; const homePageLoading = (isAuthenticated && !channelLoaded) || (hasToken && tokenVerifyLoading); return ( <> {homePageLoaded ? ( { const errorId = errorTracker.captureException(e); dispatchAppState({ payload: { error: "unhandled", errorId }, type: "displayError" }); }} > {createConfigurationMenu(intl).filter(menu => menu.menuItems.map(item => hasPermission(item.permission, user)) ).length > 0 && ( )} ) : homePageLoading ? ( ) : ( )} ); }; render(, document.querySelector("#dashboard-app"));