Migrate app view to new-apps (#3161)
This commit is contained in:
parent
c5a25f9cb6
commit
9803202e75
44 changed files with 315 additions and 121 deletions
|
@ -1 +0,0 @@
|
||||||
export * from "./AppPage";
|
|
|
@ -12,10 +12,8 @@ import {
|
||||||
appInstallPath,
|
appInstallPath,
|
||||||
AppInstallUrlQueryParams,
|
AppInstallUrlQueryParams,
|
||||||
AppListUrlQueryParams,
|
AppListUrlQueryParams,
|
||||||
appPath,
|
|
||||||
appsListPath,
|
appsListPath,
|
||||||
} from "./urls";
|
} from "./urls";
|
||||||
import { AppView } from "./views/App";
|
|
||||||
import AppDetailsView from "./views/AppDetails";
|
import AppDetailsView from "./views/AppDetails";
|
||||||
import AppInstallView from "./views/AppInstall";
|
import AppInstallView from "./views/AppInstall";
|
||||||
import AppsListView from "./views/AppsList";
|
import AppsListView from "./views/AppsList";
|
||||||
|
@ -31,10 +29,6 @@ const AppDetails: React.FC<RouteComponentProps<{ id: string }>> = ({
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const App: React.FC<RouteComponentProps<{ id: string }>> = ({ match }) => (
|
|
||||||
<AppView id={decodeURIComponent(match.params.id)} />
|
|
||||||
);
|
|
||||||
|
|
||||||
const AppInstall: React.FC<RouteComponentProps> = props => {
|
const AppInstall: React.FC<RouteComponentProps> = props => {
|
||||||
const qs = parseQs(location.search.substr(1));
|
const qs = parseQs(location.search.substr(1));
|
||||||
const params: AppInstallUrlQueryParams = qs;
|
const params: AppInstallUrlQueryParams = qs;
|
||||||
|
@ -58,7 +52,6 @@ const Component = () => {
|
||||||
<Route exact path={appsListPath} component={AppsList} />
|
<Route exact path={appsListPath} component={AppsList} />
|
||||||
<Route exact path={appInstallPath} component={AppInstall} />
|
<Route exact path={appInstallPath} component={AppInstall} />
|
||||||
<Route exact path={appDetailsPath(":id")} component={AppDetails} />
|
<Route exact path={appDetailsPath(":id")} component={AppDetails} />
|
||||||
<Route path={appPath(":id")} component={App} />
|
|
||||||
<WebhooksRoutes />
|
<WebhooksRoutes />
|
||||||
</Switch>
|
</Switch>
|
||||||
</>
|
</>
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
export * from "./AppView";
|
|
|
@ -1,45 +0,0 @@
|
||||||
import { appMessages } from "@dashboard/apps/messages";
|
|
||||||
import NotFoundPage from "@dashboard/components/NotFoundPage";
|
|
||||||
import { useAppQuery } from "@dashboard/graphql";
|
|
||||||
import useNotifier from "@dashboard/hooks/useNotifier";
|
|
||||||
import React from "react";
|
|
||||||
import { useIntl } from "react-intl";
|
|
||||||
|
|
||||||
import { AppPage } from "../../components/AppPage";
|
|
||||||
import { appsListPath } from "../../urls";
|
|
||||||
|
|
||||||
interface AppSettingsProps {
|
|
||||||
id: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const AppSettings: React.FC<AppSettingsProps> = ({ id }) => {
|
|
||||||
const { data, refetch } = useAppQuery({
|
|
||||||
displayLoader: true,
|
|
||||||
variables: { id },
|
|
||||||
});
|
|
||||||
|
|
||||||
const appExists = data?.app !== null;
|
|
||||||
|
|
||||||
const notify = useNotifier();
|
|
||||||
const intl = useIntl();
|
|
||||||
|
|
||||||
if (!appExists) {
|
|
||||||
return <NotFoundPage backHref={appsListPath} />;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<AppPage
|
|
||||||
data={data?.app ?? null}
|
|
||||||
url={data?.app?.configurationUrl ?? ""}
|
|
||||||
refetch={refetch}
|
|
||||||
onError={() =>
|
|
||||||
notify({
|
|
||||||
status: "error",
|
|
||||||
text: intl.formatMessage(appMessages.failedToFetchAppSettings),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default AppSettings;
|
|
|
@ -1,7 +1,7 @@
|
||||||
import {
|
import {
|
||||||
extensionMountPoints,
|
extensionMountPoints,
|
||||||
useExtensions,
|
useExtensions,
|
||||||
} from "@dashboard/apps/useExtensions";
|
} from "@dashboard/new-apps/hooks/useExtensions";
|
||||||
import { Box, List, sprinkles, Text } from "@saleor/macaw-ui/next";
|
import { Box, List, sprinkles, Text } from "@saleor/macaw-ui/next";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
|
|
|
@ -1,8 +1,4 @@
|
||||||
import { appsListPath } from "@dashboard/apps/urls";
|
import { appsListPath } from "@dashboard/apps/urls";
|
||||||
import {
|
|
||||||
extensionMountPoints,
|
|
||||||
useExtensions,
|
|
||||||
} from "@dashboard/apps/useExtensions";
|
|
||||||
import { useUser } from "@dashboard/auth";
|
import { useUser } from "@dashboard/auth";
|
||||||
import { categoryListUrl } from "@dashboard/categories/urls";
|
import { categoryListUrl } from "@dashboard/categories/urls";
|
||||||
import { collectionListUrl } from "@dashboard/collections/urls";
|
import { collectionListUrl } from "@dashboard/collections/urls";
|
||||||
|
@ -15,6 +11,10 @@ import { giftCardListUrl } from "@dashboard/giftCards/urls";
|
||||||
import { PermissionEnum } from "@dashboard/graphql";
|
import { PermissionEnum } from "@dashboard/graphql";
|
||||||
import { commonMessages, sectionNames } from "@dashboard/intl";
|
import { commonMessages, sectionNames } from "@dashboard/intl";
|
||||||
import { marketplaceUrlResolver } from "@dashboard/marketplace/marketplace-url-resolver";
|
import { marketplaceUrlResolver } from "@dashboard/marketplace/marketplace-url-resolver";
|
||||||
|
import {
|
||||||
|
extensionMountPoints,
|
||||||
|
useExtensions,
|
||||||
|
} from "@dashboard/new-apps/hooks/useExtensions";
|
||||||
import { orderDraftListUrl, orderListUrl } from "@dashboard/orders/urls";
|
import { orderDraftListUrl, orderListUrl } from "@dashboard/orders/urls";
|
||||||
import { pageListPath } from "@dashboard/pages/urls";
|
import { pageListPath } from "@dashboard/pages/urls";
|
||||||
import { productListUrl } from "@dashboard/products/urls";
|
import { productListUrl } from "@dashboard/products/urls";
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { getDashboardUrFromAppCompleteUrl } from "@dashboard/apps/urls";
|
import { getDashboardUrFromAppCompleteUrl } from "@dashboard/apps/urls";
|
||||||
import { Extension } from "@dashboard/apps/useExtensions";
|
|
||||||
import { AppExtensionMountEnum } from "@dashboard/graphql";
|
import { AppExtensionMountEnum } from "@dashboard/graphql";
|
||||||
|
import { Extension } from "@dashboard/new-apps/hooks/useExtensions";
|
||||||
import { orderDraftListUrl, orderListUrl } from "@dashboard/orders/urls";
|
import { orderDraftListUrl, orderListUrl } from "@dashboard/orders/urls";
|
||||||
import { matchPath } from "react-router";
|
import { matchPath } from "react-router";
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,3 @@
|
||||||
import {
|
|
||||||
extensionMountPoints,
|
|
||||||
mapToMenuItemsForCustomerDetails,
|
|
||||||
useExtensions,
|
|
||||||
} from "@dashboard/apps/useExtensions";
|
|
||||||
import { TopNav } from "@dashboard/components/AppLayout/TopNav";
|
import { TopNav } from "@dashboard/components/AppLayout/TopNav";
|
||||||
import { Backlink } from "@dashboard/components/Backlink";
|
import { Backlink } from "@dashboard/components/Backlink";
|
||||||
import CardMenu from "@dashboard/components/CardMenu/CardMenu";
|
import CardMenu from "@dashboard/components/CardMenu/CardMenu";
|
||||||
|
@ -26,6 +21,11 @@ import {
|
||||||
import { SubmitPromise } from "@dashboard/hooks/useForm";
|
import { SubmitPromise } from "@dashboard/hooks/useForm";
|
||||||
import useNavigator from "@dashboard/hooks/useNavigator";
|
import useNavigator from "@dashboard/hooks/useNavigator";
|
||||||
import { sectionNames } from "@dashboard/intl";
|
import { sectionNames } from "@dashboard/intl";
|
||||||
|
import {
|
||||||
|
extensionMountPoints,
|
||||||
|
mapToMenuItemsForCustomerDetails,
|
||||||
|
useExtensions,
|
||||||
|
} from "@dashboard/new-apps/hooks/useExtensions";
|
||||||
import { orderListUrl } from "@dashboard/orders/urls";
|
import { orderListUrl } from "@dashboard/orders/urls";
|
||||||
import { mapEdgesToItems, mapMetadataItemToInput } from "@dashboard/utils/maps";
|
import { mapEdgesToItems, mapMetadataItemToInput } from "@dashboard/utils/maps";
|
||||||
import useMetadataChangeTrigger from "@dashboard/utils/metadata/useMetadataChangeTrigger";
|
import useMetadataChangeTrigger from "@dashboard/utils/metadata/useMetadataChangeTrigger";
|
||||||
|
|
|
@ -1,9 +1,3 @@
|
||||||
import {
|
|
||||||
extensionMountPoints,
|
|
||||||
mapToMenuItems,
|
|
||||||
mapToMenuItemsForCustomerOverviewActions,
|
|
||||||
useExtensions,
|
|
||||||
} from "@dashboard/apps/useExtensions";
|
|
||||||
import { useUserPermissions } from "@dashboard/auth/hooks/useUserPermissions";
|
import { useUserPermissions } from "@dashboard/auth/hooks/useUserPermissions";
|
||||||
import { TopNav } from "@dashboard/components/AppLayout/TopNav";
|
import { TopNav } from "@dashboard/components/AppLayout/TopNav";
|
||||||
import ButtonWithSelect from "@dashboard/components/ButtonWithSelect";
|
import ButtonWithSelect from "@dashboard/components/ButtonWithSelect";
|
||||||
|
@ -16,6 +10,12 @@ import {
|
||||||
import { ListCustomersQuery } from "@dashboard/graphql";
|
import { ListCustomersQuery } from "@dashboard/graphql";
|
||||||
import useNavigator from "@dashboard/hooks/useNavigator";
|
import useNavigator from "@dashboard/hooks/useNavigator";
|
||||||
import { sectionNames } from "@dashboard/intl";
|
import { sectionNames } from "@dashboard/intl";
|
||||||
|
import {
|
||||||
|
extensionMountPoints,
|
||||||
|
mapToMenuItems,
|
||||||
|
mapToMenuItemsForCustomerOverviewActions,
|
||||||
|
useExtensions,
|
||||||
|
} from "@dashboard/new-apps/hooks/useExtensions";
|
||||||
import {
|
import {
|
||||||
FilterPageProps,
|
FilterPageProps,
|
||||||
ListActions,
|
ListActions,
|
||||||
|
|
|
@ -15,7 +15,6 @@ import TagManager from "react-gtm-module";
|
||||||
import { useIntl } from "react-intl";
|
import { useIntl } from "react-intl";
|
||||||
import { BrowserRouter, Route, Switch } from "react-router-dom";
|
import { BrowserRouter, Route, Switch } from "react-router-dom";
|
||||||
|
|
||||||
import { ExternalAppProvider } from "./apps/components/ExternalAppContext";
|
|
||||||
import { useLocationState } from "./apps/hooks/useLocationState";
|
import { useLocationState } from "./apps/hooks/useLocationState";
|
||||||
import AttributeSection from "./attributes";
|
import AttributeSection from "./attributes";
|
||||||
import { attributeSection } from "./attributes/urls";
|
import { attributeSection } from "./attributes/urls";
|
||||||
|
@ -59,6 +58,7 @@ import { marketplaceUrl } from "./marketplace/urls";
|
||||||
import NavigationSection from "./navigation";
|
import NavigationSection from "./navigation";
|
||||||
import { navigationSection } from "./navigation/urls";
|
import { navigationSection } from "./navigation/urls";
|
||||||
import AppsSection from "./new-apps";
|
import AppsSection from "./new-apps";
|
||||||
|
import { ExternalAppProvider } from "./new-apps/components/ExternalAppContext";
|
||||||
import { AppSections } from "./new-apps/urls";
|
import { AppSections } from "./new-apps/urls";
|
||||||
import { NotFound } from "./NotFound";
|
import { NotFound } from "./NotFound";
|
||||||
import OrdersSection from "./orders";
|
import OrdersSection from "./orders";
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import { AppFrame } from "@dashboard/apps/components/AppFrame";
|
|
||||||
import NotFoundPage from "@dashboard/components/NotFoundPage";
|
import NotFoundPage from "@dashboard/components/NotFoundPage";
|
||||||
import PreviewPill from "@dashboard/components/PreviewPill";
|
import PreviewPill from "@dashboard/components/PreviewPill";
|
||||||
import { WindowTitle } from "@dashboard/components/WindowTitle";
|
import { WindowTitle } from "@dashboard/components/WindowTitle";
|
||||||
|
@ -7,6 +6,7 @@ import useNavigator from "@dashboard/hooks/useNavigator";
|
||||||
import { sectionNames } from "@dashboard/intl";
|
import { sectionNames } from "@dashboard/intl";
|
||||||
import { marketplaceUrlResolver } from "@dashboard/marketplace/marketplace-url-resolver";
|
import { marketplaceUrlResolver } from "@dashboard/marketplace/marketplace-url-resolver";
|
||||||
import { marketplaceUrl } from "@dashboard/marketplace/urls";
|
import { marketplaceUrl } from "@dashboard/marketplace/urls";
|
||||||
|
import { AppFrame } from "@dashboard/new-apps/components/AppFrame";
|
||||||
import { Container } from "@material-ui/core";
|
import { Container } from "@material-ui/core";
|
||||||
import React, { useMemo } from "react";
|
import React, { useMemo } from "react";
|
||||||
import { useIntl } from "react-intl";
|
import { useIntl } from "react-intl";
|
||||||
|
|
36
src/new-apps/components/AppDialog/AppDialog.tsx
Normal file
36
src/new-apps/components/AppDialog/AppDialog.tsx
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
import {
|
||||||
|
Dialog,
|
||||||
|
DialogContent,
|
||||||
|
DialogProps,
|
||||||
|
DialogTitle,
|
||||||
|
IconButton,
|
||||||
|
Typography,
|
||||||
|
} from "@material-ui/core";
|
||||||
|
import CloseIcon from "@material-ui/icons/Close";
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
|
import { useStyles } from "./styles";
|
||||||
|
|
||||||
|
interface AppDialogProps extends DialogProps {
|
||||||
|
onClose: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const AppDialog: React.FC<AppDialogProps> = ({ children, ...props }) => {
|
||||||
|
const classes = useStyles();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Dialog aria-labelledby="extension app dialog" {...props}>
|
||||||
|
<DialogTitle disableTypography className={classes.header}>
|
||||||
|
<Typography variant="h6" component="h2">
|
||||||
|
{props.title}
|
||||||
|
</Typography>
|
||||||
|
<IconButton color="inherit" onClick={props.onClose} aria-label="close">
|
||||||
|
<CloseIcon />
|
||||||
|
</IconButton>
|
||||||
|
</DialogTitle>
|
||||||
|
<DialogContent className={classes.content}>{children}</DialogContent>
|
||||||
|
</Dialog>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default AppDialog;
|
1
src/new-apps/components/AppDialog/index.ts
Normal file
1
src/new-apps/components/AppDialog/index.ts
Normal file
|
@ -0,0 +1 @@
|
||||||
|
export * from "./AppDialog";
|
19
src/new-apps/components/AppDialog/styles.ts
Normal file
19
src/new-apps/components/AppDialog/styles.ts
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
import { makeStyles } from "@saleor/macaw-ui";
|
||||||
|
|
||||||
|
export const useStyles = makeStyles(
|
||||||
|
() => ({
|
||||||
|
header: {
|
||||||
|
display: "flex",
|
||||||
|
justifyContent: "space-between",
|
||||||
|
alignItems: "center",
|
||||||
|
},
|
||||||
|
content: {
|
||||||
|
margin: 0,
|
||||||
|
padding: 0,
|
||||||
|
overflow: "hidden",
|
||||||
|
width: 600,
|
||||||
|
height: 600,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
{ name: "AppDialog" },
|
||||||
|
);
|
|
@ -1,10 +1,10 @@
|
||||||
import { useAppDashboardUpdates } from "@dashboard/apps/components/AppFrame/useAppDashboardUpdates";
|
import { useAllFlags } from "@dashboard/hooks/useFlags";
|
||||||
|
import { useAppDashboardUpdates } from "@dashboard/new-apps/components/AppFrame/useAppDashboardUpdates";
|
||||||
import {
|
import {
|
||||||
AppDetailsUrlQueryParams,
|
AppDetailsUrlQueryParams,
|
||||||
|
AppUrls,
|
||||||
prepareFeatureFlagsList,
|
prepareFeatureFlagsList,
|
||||||
resolveAppIframeUrl,
|
} from "@dashboard/new-apps/urls";
|
||||||
} from "@dashboard/apps/urls";
|
|
||||||
import { useAllFlags } from "@dashboard/hooks/useFlags";
|
|
||||||
import { CircularProgress } from "@material-ui/core";
|
import { CircularProgress } from "@material-ui/core";
|
||||||
import { useTheme } from "@saleor/macaw-ui";
|
import { useTheme } from "@saleor/macaw-ui";
|
||||||
import clsx from "clsx";
|
import clsx from "clsx";
|
||||||
|
@ -89,7 +89,7 @@ export const AppFrame: React.FC<Props> = ({
|
||||||
</div>
|
</div>
|
||||||
<iframe
|
<iframe
|
||||||
ref={frameRef}
|
ref={frameRef}
|
||||||
src={resolveAppIframeUrl(appId, src, {
|
src={AppUrls.resolveAppIframeUrl(appId, src, {
|
||||||
...params,
|
...params,
|
||||||
featureFlags: prepareFeatureFlagsList(flags),
|
featureFlags: prepareFeatureFlagsList(flags),
|
||||||
theme: themeType,
|
theme: themeType,
|
|
@ -1,7 +1,7 @@
|
||||||
import { AppActionsHandler } from "@dashboard/apps/components/AppFrame/appActionsHandler";
|
|
||||||
import * as ExternalAppContext from "@dashboard/apps/components/ExternalAppContext/ExternalAppContext";
|
|
||||||
import * as dashboardConfig from "@dashboard/config";
|
import * as dashboardConfig from "@dashboard/config";
|
||||||
import { UseNotifierResult } from "@dashboard/hooks/useNotifier";
|
import { UseNotifierResult } from "@dashboard/hooks/useNotifier";
|
||||||
|
import { AppActionsHandler } from "@dashboard/new-apps/components/AppFrame/appActionsHandler";
|
||||||
|
import * as ExternalAppContext from "@dashboard/new-apps/components/ExternalAppContext/ExternalAppContext";
|
||||||
import { renderHook } from "@testing-library/react-hooks";
|
import { renderHook } from "@testing-library/react-hooks";
|
||||||
import * as ReactIntl from "react-intl";
|
import * as ReactIntl from "react-intl";
|
||||||
import { IntlShape } from "react-intl";
|
import { IntlShape } from "react-intl";
|
|
@ -1,8 +1,8 @@
|
||||||
import { usePostToExtension } from "@dashboard/apps/components/AppFrame/usePostToExtension";
|
|
||||||
import { useExternalApp } from "@dashboard/apps/components/ExternalAppContext/ExternalAppContext";
|
|
||||||
import { getAppMountUri } from "@dashboard/config";
|
import { getAppMountUri } from "@dashboard/config";
|
||||||
import useNavigator from "@dashboard/hooks/useNavigator";
|
import useNavigator from "@dashboard/hooks/useNavigator";
|
||||||
import useNotifier from "@dashboard/hooks/useNotifier";
|
import useNotifier from "@dashboard/hooks/useNotifier";
|
||||||
|
import { usePostToExtension } from "@dashboard/new-apps/components/AppFrame/usePostToExtension";
|
||||||
|
import { useExternalApp } from "@dashboard/new-apps/components/ExternalAppContext/ExternalAppContext";
|
||||||
import { AppUrls } from "@dashboard/new-apps/urls";
|
import { AppUrls } from "@dashboard/new-apps/urls";
|
||||||
import {
|
import {
|
||||||
DispatchResponseEvent,
|
DispatchResponseEvent,
|
|
@ -1,5 +1,5 @@
|
||||||
import { AppActionsHandler } from "@dashboard/apps/components/AppFrame/appActionsHandler";
|
import { AppActionsHandler } from "@dashboard/new-apps/components/AppFrame/appActionsHandler";
|
||||||
import { usePostToExtension } from "@dashboard/apps/components/AppFrame/usePostToExtension";
|
import { usePostToExtension } from "@dashboard/new-apps/components/AppFrame/usePostToExtension";
|
||||||
import { Actions, DispatchResponseEvent } from "@saleor/app-sdk/app-bridge";
|
import { Actions, DispatchResponseEvent } from "@saleor/app-sdk/app-bridge";
|
||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { usePostToExtension } from "@dashboard/apps/components/AppFrame/usePostToExtension";
|
|
||||||
import { getAppDeepPathFromDashboardUrl } from "@dashboard/apps/urls";
|
|
||||||
import useLocale from "@dashboard/hooks/useLocale";
|
import useLocale from "@dashboard/hooks/useLocale";
|
||||||
|
import { usePostToExtension } from "@dashboard/new-apps/components/AppFrame/usePostToExtension";
|
||||||
|
import { AppUrls } from "@dashboard/new-apps/urls";
|
||||||
import { useTheme } from "@saleor/macaw-ui";
|
import { useTheme } from "@saleor/macaw-ui";
|
||||||
import { useEffect } from "react";
|
import { useEffect } from "react";
|
||||||
|
|
||||||
|
@ -51,7 +51,10 @@ export const useAppDashboardUpdates = (
|
||||||
postToExtension({
|
postToExtension({
|
||||||
type: "redirect",
|
type: "redirect",
|
||||||
payload: {
|
payload: {
|
||||||
path: getAppDeepPathFromDashboardUrl(location.pathname, appId),
|
path: AppUrls.resolveAppDeepPathFromDashboardUrl(
|
||||||
|
location.pathname,
|
||||||
|
appId,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}, [appId, enabled, postToExtension]);
|
}, [appId, enabled, postToExtension]);
|
|
@ -35,3 +35,4 @@ export const AppPage: React.FC<AppPageProps> = ({
|
||||||
};
|
};
|
||||||
|
|
||||||
AppPage.displayName = "AppPage";
|
AppPage.displayName = "AppPage";
|
||||||
|
export default AppPage;
|
2
src/new-apps/components/AppPage/index.ts
Normal file
2
src/new-apps/components/AppPage/index.ts
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
export * from "./AppPage";
|
||||||
|
export { default } from "./AppPage";
|
|
@ -2,6 +2,7 @@ import {
|
||||||
AppInstallationFragment,
|
AppInstallationFragment,
|
||||||
AppListItemFragment,
|
AppListItemFragment,
|
||||||
AppManifestFragment,
|
AppManifestFragment,
|
||||||
|
AppQuery,
|
||||||
AppTypeEnum,
|
AppTypeEnum,
|
||||||
JobStatusEnum,
|
JobStatusEnum,
|
||||||
PermissionEnum,
|
PermissionEnum,
|
||||||
|
@ -88,6 +89,41 @@ export const appsInProgress: AppInstallationFragment[] = [
|
||||||
successAppInProgress,
|
successAppInProgress,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
export const appDetails: NonNullable<AppQuery["app"]> = {
|
||||||
|
__typename: "App",
|
||||||
|
aboutApp: "Lorem ipsum",
|
||||||
|
accessToken: "token",
|
||||||
|
appUrl: "http://localhost:8888/app",
|
||||||
|
manifestUrl: "http://localhost:8888/api/manifest",
|
||||||
|
configurationUrl: "htpp://localhost:8888/configuration",
|
||||||
|
created: "2020-06-02T12:24:26.818138+00:00",
|
||||||
|
dataPrivacy: "Lorem ipsum",
|
||||||
|
dataPrivacyUrl: "http://localhost:8888/app-data-privacy",
|
||||||
|
homepageUrl: "http://localhost:8888/homepage",
|
||||||
|
id: "QXBwOjE4MQ==",
|
||||||
|
isActive: true,
|
||||||
|
metadata: [],
|
||||||
|
name: "app1",
|
||||||
|
permissions: [
|
||||||
|
{
|
||||||
|
__typename: "Permission",
|
||||||
|
code: PermissionEnum.MANAGE_ORDERS,
|
||||||
|
name: "Manage orders.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
__typename: "Permission",
|
||||||
|
code: PermissionEnum.MANAGE_USERS,
|
||||||
|
name: "Manage customers.",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
privateMetadata: [],
|
||||||
|
supportUrl: "http://localhost:8888/support",
|
||||||
|
tokens: [],
|
||||||
|
type: AppTypeEnum.THIRDPARTY,
|
||||||
|
version: "1.0.0",
|
||||||
|
webhooks: [],
|
||||||
|
};
|
||||||
|
|
||||||
export const installApp: AppManifestFragment = {
|
export const installApp: AppManifestFragment = {
|
||||||
__typename: "Manifest",
|
__typename: "Manifest",
|
||||||
about: "Lorem ipsum",
|
about: "Lorem ipsum",
|
||||||
|
|
|
@ -8,9 +8,9 @@ import {
|
||||||
import { RelayToFlat } from "@dashboard/types";
|
import { RelayToFlat } from "@dashboard/types";
|
||||||
import { mapEdgesToItems } from "@dashboard/utils/maps";
|
import { mapEdgesToItems } from "@dashboard/utils/maps";
|
||||||
|
|
||||||
import { useExternalApp } from "./components/ExternalAppContext/";
|
import { useExternalApp } from "../components/ExternalAppContext";
|
||||||
import { AppData } from "./components/ExternalAppContext/context";
|
import { AppData } from "../components/ExternalAppContext/context";
|
||||||
import { AppDetailsUrlMountQueryParams } from "./urls";
|
import { AppDetailsUrlMountQueryParams } from "../urls";
|
||||||
|
|
||||||
export interface Extension {
|
export interface Extension {
|
||||||
id: string;
|
id: string;
|
|
@ -2,7 +2,6 @@ import {
|
||||||
AppDetailsUrlQueryParams,
|
AppDetailsUrlQueryParams,
|
||||||
AppInstallUrlQueryParams,
|
AppInstallUrlQueryParams,
|
||||||
} from "@dashboard/apps/urls";
|
} from "@dashboard/apps/urls";
|
||||||
import { AppView } from "@dashboard/apps/views/App";
|
|
||||||
import AppDetailsView from "@dashboard/apps/views/AppDetails";
|
import AppDetailsView from "@dashboard/apps/views/AppDetails";
|
||||||
import AppInstallView from "@dashboard/apps/views/AppInstall";
|
import AppInstallView from "@dashboard/apps/views/AppInstall";
|
||||||
import { sectionNames } from "@dashboard/intl";
|
import { sectionNames } from "@dashboard/intl";
|
||||||
|
@ -14,6 +13,7 @@ import { Route, RouteComponentProps, Switch } from "react-router-dom";
|
||||||
import { WindowTitle } from "../components/WindowTitle";
|
import { WindowTitle } from "../components/WindowTitle";
|
||||||
import { AppListUrlQueryParams, AppPaths } from "./urls";
|
import { AppListUrlQueryParams, AppPaths } from "./urls";
|
||||||
import AppListView from "./views/AppList";
|
import AppListView from "./views/AppList";
|
||||||
|
import AppView from "./views/AppView";
|
||||||
|
|
||||||
const AppDetails: React.FC<RouteComponentProps<{ id: string }>> = ({
|
const AppDetails: React.FC<RouteComponentProps<{ id: string }>> = ({
|
||||||
match,
|
match,
|
||||||
|
|
|
@ -28,6 +28,14 @@ export const appsMessages = defineMessages({
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const appMessages = defineMessages({
|
||||||
|
failedToFetchAppSettings: {
|
||||||
|
id: "ac+Y98",
|
||||||
|
defaultMessage: "Failed to fetch app settings",
|
||||||
|
description: "app settings error",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
export const appInstallationStatusMessages = defineMessages({
|
export const appInstallationStatusMessages = defineMessages({
|
||||||
pending: {
|
pending: {
|
||||||
id: "F1VtFa",
|
id: "F1VtFa",
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
|
import * as config from "@dashboard/config";
|
||||||
import { AppUrls } from "@dashboard/new-apps/urls";
|
import { AppUrls } from "@dashboard/new-apps/urls";
|
||||||
|
import { ThemeType } from "@saleor/app-sdk/app-bridge";
|
||||||
|
|
||||||
describe("AppUrls (apps/urls.ts)", () => {
|
describe("AppUrls (apps/urls.ts)", () => {
|
||||||
describe("isAppDeepUrlChange", () => {
|
describe("isAppDeepUrlChange", () => {
|
||||||
|
@ -17,4 +19,51 @@ describe("AppUrls (apps/urls.ts)", () => {
|
||||||
).toBe(false);
|
).toBe(false);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("resolveAppIframeUrl", () => {
|
||||||
|
afterAll(() => {
|
||||||
|
jest.clearAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("For full URL provided in env", () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
jest
|
||||||
|
.spyOn(config, "getApiUrl")
|
||||||
|
.mockImplementation(() => "https://shop.saleor.cloud/graphql/");
|
||||||
|
});
|
||||||
|
|
||||||
|
it.each<
|
||||||
|
[string, string, Record<string, string> & { theme: ThemeType }, string]
|
||||||
|
>([
|
||||||
|
[
|
||||||
|
"XyZ123",
|
||||||
|
"https://my-app.vercel.app",
|
||||||
|
{ param1: "param1", theme: "light" },
|
||||||
|
"https://my-app.vercel.app?domain=shop.saleor.cloud&saleorApiUrl=https%3A%2F%2Fshop.saleor.cloud%2Fgraphql%2F&id=XyZ123¶m1=param1&theme=light",
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"AbC987",
|
||||||
|
"https://my-app.vercel.app/configuration",
|
||||||
|
{ param1: "param1", param2: "param2", theme: "light" },
|
||||||
|
"https://my-app.vercel.app/configuration?domain=shop.saleor.cloud&saleorApiUrl=https%3A%2F%2Fshop.saleor.cloud%2Fgraphql%2F&id=AbC987¶m1=param1¶m2=param2&theme=light",
|
||||||
|
],
|
||||||
|
])(
|
||||||
|
"Generates valid URL from segments",
|
||||||
|
(id, appUrl, params, expectedUrl) => {
|
||||||
|
const result = AppUrls.resolveAppIframeUrl(id, appUrl, params);
|
||||||
|
|
||||||
|
expect(result).toEqual(expectedUrl);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test this scenario for cloud deployments where origin is computed.
|
||||||
|
*
|
||||||
|
* Current jest is not set up for testing location/URL
|
||||||
|
*/
|
||||||
|
test.todo(
|
||||||
|
"Test if URL is valid when API_URL in env is absolute path like /graphql/",
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,12 +1,51 @@
|
||||||
import { AppDetailsUrlQueryParams, appPath } from "@dashboard/apps/urls";
|
import { getApiUrl } from "@dashboard/config";
|
||||||
|
import { FlagWithName } from "@dashboard/hooks/useFlags/types";
|
||||||
import { stringifyQs } from "@dashboard/utils/urls";
|
import { stringifyQs } from "@dashboard/utils/urls";
|
||||||
|
import { ThemeType } from "@saleor/app-sdk/app-bridge";
|
||||||
import urlJoin from "url-join";
|
import urlJoin from "url-join";
|
||||||
|
|
||||||
import { Dialog, SingleAction } from "../types";
|
import { Dialog, SingleAction } from "../types";
|
||||||
|
|
||||||
|
export const MANIFEST_ATTR = "manifestUrl";
|
||||||
|
|
||||||
export type AppListUrlDialog = "app-installation-remove";
|
export type AppListUrlDialog = "app-installation-remove";
|
||||||
export type AppListUrlQueryParams = Dialog<AppListUrlDialog> & SingleAction;
|
export type AppListUrlQueryParams = Dialog<AppListUrlDialog> & SingleAction;
|
||||||
|
|
||||||
|
export type AppDetailsUrlDialog =
|
||||||
|
| "app-activate"
|
||||||
|
| "app-deactivate"
|
||||||
|
| "app-delete";
|
||||||
|
export interface AppDetailsUrlMountQueryParams {
|
||||||
|
productId?: string;
|
||||||
|
productIds?: string[];
|
||||||
|
orderId?: string;
|
||||||
|
customerId?: string;
|
||||||
|
customerIds?: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
interface FeatureFlagsQueryParams {
|
||||||
|
featureFlags?: Record<string, string>;
|
||||||
|
}
|
||||||
|
export interface AppDetailsCommonParams {
|
||||||
|
theme: ThemeType;
|
||||||
|
}
|
||||||
|
export type AppDetailsUrlQueryParams = Dialog<AppDetailsUrlDialog> &
|
||||||
|
SingleAction &
|
||||||
|
AppDetailsUrlMountQueryParams &
|
||||||
|
FeatureFlagsQueryParams;
|
||||||
|
|
||||||
|
export type AppInstallUrlQueryParams = Partial<{ [MANIFEST_ATTR]: string }>;
|
||||||
|
|
||||||
|
export const prepareFeatureFlagsList = (
|
||||||
|
flags: FlagWithName[],
|
||||||
|
): Record<string, string> =>
|
||||||
|
flags.reduce<Record<string, string>>((acc, flag) => {
|
||||||
|
if (flag.enabled) {
|
||||||
|
acc[flag.name] = `${flag.value || true}`;
|
||||||
|
}
|
||||||
|
return acc;
|
||||||
|
}, {});
|
||||||
|
|
||||||
export const AppSections = {
|
export const AppSections = {
|
||||||
appsSection: "/apps/",
|
appsSection: "/apps/",
|
||||||
};
|
};
|
||||||
|
@ -30,8 +69,60 @@ export const AppUrls = {
|
||||||
resolveAppInstallUrl: (manifestUrl: string) =>
|
resolveAppInstallUrl: (manifestUrl: string) =>
|
||||||
`${AppPaths.appInstallPath}?manifestUrl=${manifestUrl}`,
|
`${AppPaths.appInstallPath}?manifestUrl=${manifestUrl}`,
|
||||||
isAppDeepUrlChange: (appId: string, from: string, to: string) => {
|
isAppDeepUrlChange: (appId: string, from: string, to: string) => {
|
||||||
const appCompletePath = appPath(encodeURIComponent(appId));
|
const appCompletePath = AppPaths.resolveAppPath(encodeURIComponent(appId));
|
||||||
|
|
||||||
return to.startsWith(appCompletePath) && from.startsWith(appCompletePath);
|
return to.startsWith(appCompletePath) && from.startsWith(appCompletePath);
|
||||||
},
|
},
|
||||||
|
resolveAppDeepPathFromDashboardUrl: (dashboardUrl: string, appId: string) => {
|
||||||
|
const deepSubPath = dashboardUrl.replace(
|
||||||
|
AppPaths.resolveAppPath(encodeURIComponent(appId)),
|
||||||
|
"",
|
||||||
|
);
|
||||||
|
return deepSubPath || "/";
|
||||||
|
},
|
||||||
|
resolveAppCompleteUrlFromDashboardUrl: (
|
||||||
|
dashboardUrl: string,
|
||||||
|
appUrl?: string,
|
||||||
|
appId?: string,
|
||||||
|
) => {
|
||||||
|
if (!appUrl || !appId) {
|
||||||
|
return appUrl;
|
||||||
|
}
|
||||||
|
const deepSubPath = dashboardUrl.replace(
|
||||||
|
AppPaths.resolveAppPath(encodeURIComponent(appId)),
|
||||||
|
"",
|
||||||
|
);
|
||||||
|
const appCompleteUrl = urlJoin(appUrl, deepSubPath);
|
||||||
|
return appCompleteUrl;
|
||||||
|
},
|
||||||
|
resolveAppIframeUrl: (
|
||||||
|
appId: string,
|
||||||
|
appUrl: string,
|
||||||
|
params: AppDetailsUrlQueryParams & AppDetailsCommonParams,
|
||||||
|
) => {
|
||||||
|
const apiUrl = new URL(getApiUrl(), window.location.origin).href;
|
||||||
|
/**
|
||||||
|
* Use host to preserve port, in case of multiple Saleors running on localhost
|
||||||
|
*/
|
||||||
|
const apiUrlHost = new URL(apiUrl).host;
|
||||||
|
|
||||||
|
const iframeContextQueryString = `?${stringifyQs(
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @deprecated - domain will be removed in favor of saleorApiUrl.
|
||||||
|
* Current hostname (used as domain) can be extracted from full URL
|
||||||
|
*
|
||||||
|
* Difference will be:
|
||||||
|
* shop.saleor.cloud -> https://shop.saleor.cloud/graphql/
|
||||||
|
*/
|
||||||
|
domain: apiUrlHost,
|
||||||
|
saleorApiUrl: apiUrl,
|
||||||
|
id: appId,
|
||||||
|
...params,
|
||||||
|
},
|
||||||
|
"comma",
|
||||||
|
)}`;
|
||||||
|
|
||||||
|
return urlJoin(appUrl, window.location.search, iframeContextQueryString);
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -3,13 +3,12 @@ import NotFoundPage from "@dashboard/components/NotFoundPage";
|
||||||
import { useAppQuery } from "@dashboard/graphql";
|
import { useAppQuery } from "@dashboard/graphql";
|
||||||
import useNavigator from "@dashboard/hooks/useNavigator";
|
import useNavigator from "@dashboard/hooks/useNavigator";
|
||||||
import useNotifier from "@dashboard/hooks/useNotifier";
|
import useNotifier from "@dashboard/hooks/useNotifier";
|
||||||
|
import AppPage from "@dashboard/new-apps/components/AppPage";
|
||||||
|
import { AppPaths, AppUrls } from "@dashboard/new-apps/urls";
|
||||||
import React, { useCallback } from "react";
|
import React, { useCallback } from "react";
|
||||||
import { useIntl } from "react-intl";
|
import { useIntl } from "react-intl";
|
||||||
import { useLocation } from "react-router";
|
import { useLocation } from "react-router";
|
||||||
|
|
||||||
import { AppPage } from "../../components/AppPage";
|
|
||||||
import { appsListPath, getAppCompleteUrlFromDashboardUrl } from "../../urls";
|
|
||||||
|
|
||||||
interface AppProps {
|
interface AppProps {
|
||||||
id: string;
|
id: string;
|
||||||
}
|
}
|
||||||
|
@ -37,10 +36,10 @@ export const AppView: React.FC<AppProps> = ({ id }) => {
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!appExists) {
|
if (!appExists) {
|
||||||
return <NotFoundPage onBack={() => navigate(appsListPath)} />;
|
return <NotFoundPage onBack={() => navigate(AppPaths.appListPath)} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
const appCompleteUrl = getAppCompleteUrlFromDashboardUrl(
|
const appCompleteUrl = AppUrls.resolveAppCompleteUrlFromDashboardUrl(
|
||||||
location.pathname,
|
location.pathname,
|
||||||
data?.app?.appUrl || "",
|
data?.app?.appUrl || "",
|
||||||
id,
|
id,
|
||||||
|
@ -59,3 +58,4 @@ export const AppView: React.FC<AppProps> = ({ id }) => {
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
export default AppView;
|
2
src/new-apps/views/AppView/index.ts
Normal file
2
src/new-apps/views/AppView/index.ts
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
export * from "./AppView";
|
||||||
|
export { default } from "./AppView";
|
|
@ -1,8 +1,3 @@
|
||||||
import {
|
|
||||||
extensionMountPoints,
|
|
||||||
mapToMenuItemsForOrderDetails,
|
|
||||||
useExtensions,
|
|
||||||
} from "@dashboard/apps/useExtensions";
|
|
||||||
import { TopNav } from "@dashboard/components/AppLayout/TopNav";
|
import { TopNav } from "@dashboard/components/AppLayout/TopNav";
|
||||||
import CardMenu from "@dashboard/components/CardMenu";
|
import CardMenu from "@dashboard/components/CardMenu";
|
||||||
import { CardSpacer } from "@dashboard/components/CardSpacer";
|
import { CardSpacer } from "@dashboard/components/CardSpacer";
|
||||||
|
@ -18,6 +13,11 @@ import {
|
||||||
} from "@dashboard/graphql";
|
} from "@dashboard/graphql";
|
||||||
import { SubmitPromise } from "@dashboard/hooks/useForm";
|
import { SubmitPromise } from "@dashboard/hooks/useForm";
|
||||||
import useNavigator from "@dashboard/hooks/useNavigator";
|
import useNavigator from "@dashboard/hooks/useNavigator";
|
||||||
|
import {
|
||||||
|
extensionMountPoints,
|
||||||
|
mapToMenuItemsForOrderDetails,
|
||||||
|
useExtensions,
|
||||||
|
} from "@dashboard/new-apps/hooks/useExtensions";
|
||||||
import { defaultGraphiQLQuery } from "@dashboard/orders/queries";
|
import { defaultGraphiQLQuery } from "@dashboard/orders/queries";
|
||||||
import { orderListUrl } from "@dashboard/orders/urls";
|
import { orderListUrl } from "@dashboard/orders/urls";
|
||||||
import { playgroundOpenHandler } from "@dashboard/utils/graphql";
|
import { playgroundOpenHandler } from "@dashboard/utils/graphql";
|
||||||
|
|
|
@ -1,8 +1,3 @@
|
||||||
import {
|
|
||||||
extensionMountPoints,
|
|
||||||
mapToMenuItems,
|
|
||||||
useExtensions,
|
|
||||||
} from "@dashboard/apps/useExtensions";
|
|
||||||
import { LimitsInfo } from "@dashboard/components/AppLayout/LimitsInfo";
|
import { LimitsInfo } from "@dashboard/components/AppLayout/LimitsInfo";
|
||||||
import { TopNav } from "@dashboard/components/AppLayout/TopNav";
|
import { TopNav } from "@dashboard/components/AppLayout/TopNav";
|
||||||
import { ButtonWithSelect } from "@dashboard/components/ButtonWithSelect";
|
import { ButtonWithSelect } from "@dashboard/components/ButtonWithSelect";
|
||||||
|
@ -11,6 +6,11 @@ import FilterBar from "@dashboard/components/FilterBar";
|
||||||
import { ListPageLayout } from "@dashboard/components/Layouts";
|
import { ListPageLayout } from "@dashboard/components/Layouts";
|
||||||
import { OrderListQuery, RefreshLimitsQuery } from "@dashboard/graphql";
|
import { OrderListQuery, RefreshLimitsQuery } from "@dashboard/graphql";
|
||||||
import { sectionNames } from "@dashboard/intl";
|
import { sectionNames } from "@dashboard/intl";
|
||||||
|
import {
|
||||||
|
extensionMountPoints,
|
||||||
|
mapToMenuItems,
|
||||||
|
useExtensions,
|
||||||
|
} from "@dashboard/new-apps/hooks/useExtensions";
|
||||||
import { OrderListUrlSortField } from "@dashboard/orders/urls";
|
import { OrderListUrlSortField } from "@dashboard/orders/urls";
|
||||||
import {
|
import {
|
||||||
FilterPageProps,
|
FilterPageProps,
|
||||||
|
|
|
@ -1,9 +1,3 @@
|
||||||
import {
|
|
||||||
extensionMountPoints,
|
|
||||||
mapToMenuItems,
|
|
||||||
mapToMenuItemsForProductOverviewActions,
|
|
||||||
useExtensions,
|
|
||||||
} from "@dashboard/apps/useExtensions";
|
|
||||||
import { LimitsInfo } from "@dashboard/components/AppLayout/LimitsInfo";
|
import { LimitsInfo } from "@dashboard/components/AppLayout/LimitsInfo";
|
||||||
import { TopNav } from "@dashboard/components/AppLayout/TopNav";
|
import { TopNav } from "@dashboard/components/AppLayout/TopNav";
|
||||||
import { ButtonWithSelect } from "@dashboard/components/ButtonWithSelect";
|
import { ButtonWithSelect } from "@dashboard/components/ButtonWithSelect";
|
||||||
|
@ -22,6 +16,12 @@ import {
|
||||||
SearchAvailableInGridAttributesQuery,
|
SearchAvailableInGridAttributesQuery,
|
||||||
} from "@dashboard/graphql";
|
} from "@dashboard/graphql";
|
||||||
import { sectionNames } from "@dashboard/intl";
|
import { sectionNames } from "@dashboard/intl";
|
||||||
|
import {
|
||||||
|
extensionMountPoints,
|
||||||
|
mapToMenuItems,
|
||||||
|
mapToMenuItemsForProductOverviewActions,
|
||||||
|
useExtensions,
|
||||||
|
} from "@dashboard/new-apps/hooks/useExtensions";
|
||||||
import {
|
import {
|
||||||
ChannelProps,
|
ChannelProps,
|
||||||
FetchMoreProps,
|
FetchMoreProps,
|
||||||
|
|
|
@ -1,8 +1,3 @@
|
||||||
import {
|
|
||||||
extensionMountPoints,
|
|
||||||
mapToMenuItemsForProductDetails,
|
|
||||||
useExtensions,
|
|
||||||
} from "@dashboard/apps/useExtensions";
|
|
||||||
import {
|
import {
|
||||||
getReferenceAttributeEntityTypeFromAttribute,
|
getReferenceAttributeEntityTypeFromAttribute,
|
||||||
mergeAttributeValues,
|
mergeAttributeValues,
|
||||||
|
@ -40,6 +35,11 @@ import { SubmitPromise } from "@dashboard/hooks/useForm";
|
||||||
import useNavigator from "@dashboard/hooks/useNavigator";
|
import useNavigator from "@dashboard/hooks/useNavigator";
|
||||||
import useStateFromProps from "@dashboard/hooks/useStateFromProps";
|
import useStateFromProps from "@dashboard/hooks/useStateFromProps";
|
||||||
import { maybe } from "@dashboard/misc";
|
import { maybe } from "@dashboard/misc";
|
||||||
|
import {
|
||||||
|
extensionMountPoints,
|
||||||
|
mapToMenuItemsForProductDetails,
|
||||||
|
useExtensions,
|
||||||
|
} from "@dashboard/new-apps/hooks/useExtensions";
|
||||||
import ProductExternalMediaDialog from "@dashboard/products/components/ProductExternalMediaDialog";
|
import ProductExternalMediaDialog from "@dashboard/products/components/ProductExternalMediaDialog";
|
||||||
import { defaultGraphiQLQuery } from "@dashboard/products/queries";
|
import { defaultGraphiQLQuery } from "@dashboard/products/queries";
|
||||||
import { productImageUrl, productListUrl } from "@dashboard/products/urls";
|
import { productImageUrl, productListUrl } from "@dashboard/products/urls";
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { ExternalAppProvider } from "@dashboard/apps/components/ExternalAppContext";
|
|
||||||
import { Locale, RawLocaleProvider } from "@dashboard/components/Locale";
|
import { Locale, RawLocaleProvider } from "@dashboard/components/Locale";
|
||||||
import { FlagsServiceProvider } from "@dashboard/hooks/useFlags/flagsService";
|
import { FlagsServiceProvider } from "@dashboard/hooks/useFlags/flagsService";
|
||||||
|
import { ExternalAppProvider } from "@dashboard/new-apps/components/ExternalAppContext";
|
||||||
import { paletteOverrides, themeOverrides } from "@dashboard/themeOverrides";
|
import { paletteOverrides, themeOverrides } from "@dashboard/themeOverrides";
|
||||||
import { ThemeProvider } from "@saleor/macaw-ui";
|
import { ThemeProvider } from "@saleor/macaw-ui";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { ExternalAppProvider } from "@dashboard/apps/components/ExternalAppContext";
|
|
||||||
import { Provider as DateProvider } from "@dashboard/components/Date/DateContext";
|
import { Provider as DateProvider } from "@dashboard/components/Date/DateContext";
|
||||||
import { Locale, RawLocaleProvider } from "@dashboard/components/Locale";
|
import { Locale, RawLocaleProvider } from "@dashboard/components/Locale";
|
||||||
import { TimezoneProvider } from "@dashboard/components/Timezone";
|
import { TimezoneProvider } from "@dashboard/components/Timezone";
|
||||||
|
import { ExternalAppProvider } from "@dashboard/new-apps/components/ExternalAppContext";
|
||||||
import { ThemeProvider } from "@saleor/macaw-ui";
|
import { ThemeProvider } from "@saleor/macaw-ui";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { IntlProvider } from "react-intl";
|
import { IntlProvider } from "react-intl";
|
||||||
|
|
Loading…
Reference in a new issue