
* Add gift cards section to menu and add empty list component * Update messages * Change styling of app wide page header to match design * Add gift cards list table wip * Update prop name for status chip component to make it more consistent with other components * Replace old trash icon with new one * Add Size type based on action dialog sizes to be used app wide * Add delete icon button * Add new sizes option to status chip component * Add / update gift cards list components * Add bulk actions type * Work on gift cards list WIP * Small refactor * Fix styling of gift cards table * Remove temp files * Remove unnecessary type * Add gift cards section to menu and add empty list component * Update schema and types * Add link to gift card update page to gift cards list and add route to gift cards index * Extract order page title with status chip into a separate generic component and use it in order page title * wip * Update money component * Add gift card details card balance section * Refactor gift card details * Add vertical spacer component * Update schema and types * Add gift card tag input component along with necessary queries * Add gift card tag input to gift card update page * Add gift card update details card expiry section WIP * Add time period select field WIP * Post rebase refactor * Add time period select field to gift card update view * Fixes after review * Update schema, types and gift cards query * Add getFullName util function and replace existing manual usages * Add text with select field component * Add gift card update info card and refactor * Fix import * Add displaying order link in gift card update * Refactor * Connect gift card list to api * refactor * Add gift card create dialog * Fix gift card list styles, change location for gift card list query, minor refactor * Fix menu structure data for gift cards * Add channel currencies type to shop * Refactor text with select field * Add gift card expiry select component * Add gift card error type and fragment * Update global types * Add default prop to getFormErrors function * Move gift card details provider to providers dir * Update global utils with mapSingleValueNodeToChoice function * Update gift card tag input * Move and refactor time period field * Update schema * move format money function to other money ulities * Update gift card urls * Add content or skeleton component * Add gift card create util for extracting expiry settings input data * Remove content or skeleton component and move displaying logic to existing skeleton * Move displaying logic of gift card create dialog to list * Refactor * Add hooks for gift card bulk actions and gift card list to be used instead of context directly * Fix types for text with select field + add parsing for number typed field * Add initial currency to gift card create form * Fix gift card create dialog closing animation * Add gift card update info card * Refactor gift card update details card * Add gift card balance dialog * Move gift card update form providers to providers dir * Connect gift card update page to api, add necessary contexts etc. * Refactor * Refactor * Add hooks to use instead of gift card contexts directly * Fix types * Fix text field target name missing in passed event in text with select field * Add minimal value option to text with select field, add to gift card inputs * Fix gift card update balance dialog not changing hasChanged prop after submit * Refactor * Fix update balance dialog crashing the app when enetered wrong amount * Fix gift card list table header styles * Add enable / disable section to gift card update * Refactor * Refactor * Refactor * Add metadata to gift card update * Update messages ids * Refactor * Refactor * Refactor * Refactor * Update types after rebase * Fix types * Fixes after qa * Fix tests
317 lines
11 KiB
TypeScript
317 lines
11 KiB
TypeScript
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 { 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 = () => (
|
|
<ApolloProvider client={apolloClient}>
|
|
<BrowserRouter basename={APP_MOUNT_URI}>
|
|
<ThemeProvider overrides={themeOverrides}>
|
|
<DateProvider>
|
|
<LocaleProvider>
|
|
<MessageManagerProvider>
|
|
<ServiceWorker />
|
|
<BackgroundTasksProvider>
|
|
<AppStateProvider>
|
|
<ShopProvider>
|
|
<AuthProvider>
|
|
<AppChannelProvider>
|
|
<Routes />
|
|
</AppChannelProvider>
|
|
</AuthProvider>
|
|
</ShopProvider>
|
|
</AppStateProvider>
|
|
</BackgroundTasksProvider>
|
|
</MessageManagerProvider>
|
|
</LocaleProvider>
|
|
</DateProvider>
|
|
</ThemeProvider>
|
|
</BrowserRouter>
|
|
</ApolloProvider>
|
|
);
|
|
|
|
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 (
|
|
<>
|
|
<WindowTitle title={intl.formatMessage(commonMessages.dashboard)} />
|
|
{homePageLoaded ? (
|
|
<AppLayout>
|
|
<ErrorBoundary
|
|
onError={e => {
|
|
const errorId = errorTracker.captureException(e);
|
|
|
|
dispatchAppState({
|
|
payload: {
|
|
error: "unhandled",
|
|
errorId
|
|
},
|
|
type: "displayError"
|
|
});
|
|
}}
|
|
>
|
|
<Switch>
|
|
<SectionRoute exact path="/" component={HomePage} />
|
|
<SectionRoute
|
|
permissions={[PermissionEnum.MANAGE_PRODUCTS]}
|
|
path="/categories"
|
|
component={CategorySection}
|
|
/>
|
|
<SectionRoute
|
|
permissions={[PermissionEnum.MANAGE_PRODUCTS]}
|
|
path="/collections"
|
|
component={CollectionSection}
|
|
/>
|
|
<SectionRoute
|
|
permissions={[PermissionEnum.MANAGE_USERS]}
|
|
path="/customers"
|
|
component={CustomerSection}
|
|
/>
|
|
<SectionRoute
|
|
/* add after backend adds the permission to schema */
|
|
// permissions={[]}
|
|
path={giftCardsSectionUrlName}
|
|
component={GiftCardSection}
|
|
/>
|
|
<SectionRoute
|
|
permissions={[PermissionEnum.MANAGE_DISCOUNTS]}
|
|
path="/discounts"
|
|
component={DiscountSection}
|
|
/>
|
|
<SectionRoute
|
|
permissions={[PermissionEnum.MANAGE_PAGES]}
|
|
path="/pages"
|
|
component={PageSection}
|
|
/>
|
|
<SectionRoute
|
|
permissions={[PermissionEnum.MANAGE_PAGES]}
|
|
path="/page-types"
|
|
component={PageTypesSection}
|
|
/>
|
|
<SectionRoute
|
|
permissions={[PermissionEnum.MANAGE_PLUGINS]}
|
|
path="/plugins"
|
|
component={PluginsSection}
|
|
/>
|
|
<SectionRoute
|
|
permissions={[PermissionEnum.MANAGE_ORDERS]}
|
|
path="/orders"
|
|
component={OrdersSection}
|
|
/>
|
|
<SectionRoute
|
|
permissions={[PermissionEnum.MANAGE_PRODUCTS]}
|
|
path="/products"
|
|
component={ProductSection}
|
|
/>
|
|
<SectionRoute
|
|
permissions={[
|
|
PermissionEnum.MANAGE_PRODUCT_TYPES_AND_ATTRIBUTES
|
|
]}
|
|
path="/product-types"
|
|
component={ProductTypesSection}
|
|
/>
|
|
<SectionRoute
|
|
permissions={[PermissionEnum.MANAGE_STAFF]}
|
|
path="/staff"
|
|
component={StaffSection}
|
|
/>
|
|
<SectionRoute
|
|
permissions={[PermissionEnum.MANAGE_STAFF]}
|
|
path="/permission-groups"
|
|
component={PermissionGroupSection}
|
|
/>
|
|
<SectionRoute
|
|
permissions={[PermissionEnum.MANAGE_SETTINGS]}
|
|
path="/site-settings"
|
|
component={SiteSettingsSection}
|
|
/>
|
|
<SectionRoute
|
|
permissions={[PermissionEnum.MANAGE_SETTINGS]}
|
|
path="/taxes"
|
|
component={TaxesSection}
|
|
/>
|
|
<SectionRoute
|
|
permissions={[PermissionEnum.MANAGE_SHIPPING]}
|
|
path="/shipping"
|
|
component={ShippingSection}
|
|
/>
|
|
<SectionRoute
|
|
permissions={[PermissionEnum.MANAGE_TRANSLATIONS]}
|
|
path="/translations"
|
|
component={TranslationsSection}
|
|
/>
|
|
<SectionRoute
|
|
permissions={[PermissionEnum.MANAGE_MENUS]}
|
|
path={navigationSection}
|
|
component={NavigationSection}
|
|
/>
|
|
<SectionRoute
|
|
permissions={[
|
|
PermissionEnum.MANAGE_PRODUCT_TYPES_AND_ATTRIBUTES
|
|
]}
|
|
path={attributeSection}
|
|
component={AttributeSection}
|
|
/>
|
|
<SectionRoute
|
|
permissions={[PermissionEnum.MANAGE_APPS]}
|
|
path={appsSection}
|
|
component={AppsSection}
|
|
/>
|
|
<SectionRoute
|
|
permissions={[PermissionEnum.MANAGE_PRODUCTS]}
|
|
path={warehouseSection}
|
|
component={WarehouseSection}
|
|
/>
|
|
<SectionRoute
|
|
permissions={[PermissionEnum.MANAGE_CHANNELS]}
|
|
path={channelsSection}
|
|
component={ChannelsSection}
|
|
/>
|
|
{createConfigurationMenu(intl).filter(menu =>
|
|
menu.menuItems.map(item => hasPermission(item.permission, user))
|
|
).length > 0 && (
|
|
<SectionRoute
|
|
exact
|
|
path="/configuration"
|
|
component={ConfigurationSection}
|
|
/>
|
|
)}
|
|
<Route component={NotFound} />
|
|
</Switch>
|
|
</ErrorBoundary>
|
|
</AppLayout>
|
|
) : homePageLoading ? (
|
|
<LoginLoading />
|
|
) : (
|
|
<Auth />
|
|
)}
|
|
</>
|
|
);
|
|
};
|
|
|
|
render(<App />, document.querySelector("#dashboard-app"));
|