Application Marketplace available in dashboard (#2054)
* Add marketplace * Update messages * Extract styles * Update test env * Update config and rename uri * Update template * Trigger CI * Possible fix * Update deploy yml * Add marketplace to staging * Fix responsiveness * Trigger CI * Fix navigation tests (#2081) * fix navigate through shop * wait for progress bar not to exist * simplify code * add wait * Fix navigate through shop (#2076) * fix navigate through shop * wait for progress bar not to exist * simplify code * Refine App about section (#2056) * Trigger CI * Trigger CI * Trigger CI * Trigger CI * Fix app activation/deactivation * Hide configuration url and policy if theres none * Remove about and support links * Remove unused code * Update stories and tests * Update messages * Fix privacy policy * Fix activation and "open app" * Update tests Co-authored-by: Karolina Rakoczy <rakoczy.karolina@gmail.com>
This commit is contained in:
parent
a8b584a9d6
commit
c922dfb6fe
25 changed files with 201 additions and 174 deletions
1
.github/PULL_REQUEST_TEMPLATE.md
vendored
1
.github/PULL_REQUEST_TEMPLATE.md
vendored
|
@ -25,3 +25,4 @@ greatly reduce the amount of work needed to review your work. -->
|
|||
Modify API_URI if you want test instance to use custom backend. CYPRESS_API_URI is optional, use when necessary. -->
|
||||
|
||||
API_URI=https://automation-dashboard.staging.saleor.cloud/graphql/
|
||||
MARKETPLACE_URL=https://marketplace-gray.vercel.app/
|
||||
|
|
1
.github/workflows/deploy-master-staging.yaml
vendored
1
.github/workflows/deploy-master-staging.yaml
vendored
|
@ -10,6 +10,7 @@ jobs:
|
|||
runs-on: ubuntu-20.04
|
||||
env:
|
||||
API_URI: /graphql/
|
||||
MARKETPLACE_URL: "https://marketplace-gray.vercel.app/"
|
||||
APP_MOUNT_URI: /dashboard/
|
||||
STATIC_URL: /dashboard/static/
|
||||
SENTRY_ORG: saleor
|
||||
|
|
11
.github/workflows/test-env-deploy.yml
vendored
11
.github/workflows/test-env-deploy.yml
vendored
|
@ -57,11 +57,21 @@ jobs:
|
|||
pattern: (http|https)://[a-zA-Z0-9.-]+/graphql/?
|
||||
run: |
|
||||
echo "::set-output name=custom_api_uri::$(echo $pull_request_body | grep -Eo "$prefix$pattern" | sed s/$prefix// | head -n 1)"
|
||||
- name: Get MARKETPLACE_URL
|
||||
id: marketplace_url
|
||||
# Search for MARKETPLACE_URL in PR description
|
||||
env:
|
||||
pull_request_body: ${{ github.event.pull_request.body }}
|
||||
prefix: MARKETPLACE_URL=
|
||||
pattern: (http|https)://[a-zA-Z0-9.-]+/?
|
||||
run: |
|
||||
echo "::set-output name=custom_marketplace_url::$(echo $pull_request_body | grep -Eo "$prefix$pattern" | sed s/$prefix// | head -n 1)"
|
||||
|
||||
- name: Run build
|
||||
env:
|
||||
# Use custom API_URI or the default one
|
||||
API_URI: ${{ steps.api_uri.outputs.custom_api_uri || 'https://qa.staging.saleor.cloud/graphql/' }}
|
||||
MARKETPLACE_URL: ${{ steps.marketplace_url.outputs.custom_marketplace_url }}
|
||||
APP_MOUNT_URI: /
|
||||
STATIC_URL: /
|
||||
IS_CLOUD_INSTANCE: true
|
||||
|
@ -113,7 +123,6 @@ jobs:
|
|||
env_url: https://${{ steps.set-domain.outputs.domain }}/storybook/index.html
|
||||
deployment_id: ${{ steps.storybook-deployment.outputs.deployment_id }}
|
||||
|
||||
|
||||
cypress-run-critical:
|
||||
needs: deploy
|
||||
runs-on: ubuntu-latest
|
||||
|
|
|
@ -5,11 +5,12 @@ RUN npm install
|
|||
COPY . .
|
||||
ARG APP_MOUNT_URI
|
||||
ARG API_URI
|
||||
ARG MARKETPLACE_URL
|
||||
ARG STATIC_URL
|
||||
ENV API_URI ${API_URI:-http://localhost:8000/graphql/}
|
||||
ENV APP_MOUNT_URI ${APP_MOUNT_URI:-/dashboard/}
|
||||
ENV STATIC_URL ${STATIC_URL:-/dashboard/}
|
||||
RUN STATIC_URL=${STATIC_URL} API_URI=${API_URI} APP_MOUNT_URI=${APP_MOUNT_URI} npm run build
|
||||
RUN STATIC_URL=${STATIC_URL} API_URI=${API_URI} MARKETPLACE_URL=${MARKETPLACE_URL} APP_MOUNT_URI=${APP_MOUNT_URI} npm run build
|
||||
|
||||
FROM nginx:stable
|
||||
WORKDIR /app
|
||||
|
|
|
@ -5,6 +5,7 @@ RUN npm install
|
|||
COPY . .
|
||||
ARG APP_MOUNT_URI
|
||||
ARG API_URI
|
||||
ARG MARKETPLACE_URL
|
||||
ARG STATIC_URL
|
||||
ENV API_URI ${API_URI:-http://localhost:8000/graphql/}
|
||||
ENV APP_MOUNT_URI ${APP_MOUNT_URI:-/}
|
||||
|
|
|
@ -5,6 +5,7 @@ export const LEFT_MENU_SELECTORS = {
|
|||
home: "[data-test='menu-item-label'][data-test-id='home']",
|
||||
orders: "[data-test='menu-item-label'][data-test-id='orders']",
|
||||
discounts: "[data-test='menu-item-label'][data-test-id='discounts']",
|
||||
appSection: "[data-test='menu-item-label'][data-test-id='apps_section']",
|
||||
app: "[data-test='menu-item-label'][data-test-id='apps']",
|
||||
translations: "[data-test='menu-item-label'][data-test-id='translations']",
|
||||
customers: "[data-test='menu-item-label'][data-test-id='customers']"
|
||||
|
@ -22,3 +23,9 @@ export const CATALOG = {
|
|||
categories: "[data-test='submenu-item-label'][data-test-id='categories']",
|
||||
collections: "[data-test='submenu-item-label'][data-test-id='collections']"
|
||||
};
|
||||
|
||||
export const APP_MENU_SELECTORS = {
|
||||
app: "[data-test='submenu-item-label'][data-test-id='apps']"
|
||||
};
|
||||
|
||||
export const appCommonSelector = "[data-test-id*='apps']";
|
||||
|
|
|
@ -7,9 +7,6 @@ const configurationAsParent = {
|
|||
};
|
||||
|
||||
export const PERMISSIONS = {
|
||||
app: {
|
||||
permissionSelectors: [menuSelectors.LEFT_MENU_SELECTORS.app]
|
||||
},
|
||||
channel: {
|
||||
parent: configurationAsParent,
|
||||
permissionSelectors: [CONFIGURATION_SELECTORS.channels]
|
||||
|
|
|
@ -9,7 +9,7 @@ export const PERMISSIONS_OPTIONS = {
|
|||
},
|
||||
app: {
|
||||
user: ONE_PERMISSION_USERS.app,
|
||||
permissions: [PERMISSIONS.app],
|
||||
permissions: [],
|
||||
testCase: "TC: SALEOR_3402"
|
||||
},
|
||||
channel: {
|
||||
|
|
|
@ -1,17 +1,55 @@
|
|||
/// <reference types="cypress"/>
|
||||
/// <reference types="../support"/>
|
||||
|
||||
import {
|
||||
APP_MENU_SELECTORS,
|
||||
appCommonSelector,
|
||||
LEFT_MENU_SELECTORS
|
||||
} from "../elements/account/left-menu/left-menu-selectors";
|
||||
import { PERMISSIONS_OPTIONS } from "../fixtures/permissionsUsers";
|
||||
import filterTests from "../support/filterTests";
|
||||
import * as permissionsSteps from "../support/pages/permissionsPage";
|
||||
|
||||
describe("As a staff user I want to navigate through shop using different permissions", () => {
|
||||
Object.keys(PERMISSIONS_OPTIONS).forEach(key => {
|
||||
const permissionsOptions = PERMISSIONS_OPTIONS;
|
||||
|
||||
before(() => {
|
||||
cy.loginUserViaRequest()
|
||||
.visit("/")
|
||||
.get(appCommonSelector)
|
||||
.should("be.visible")
|
||||
.get("body")
|
||||
.then($body => {
|
||||
// This will be deleted when Marketplace is released
|
||||
// Consider this solution as temporary
|
||||
|
||||
let appPermissions;
|
||||
|
||||
if ($body.find(LEFT_MENU_SELECTORS.appSection).length) {
|
||||
appPermissions = {
|
||||
parent: {
|
||||
parentMenuSelector: LEFT_MENU_SELECTORS.appSection,
|
||||
parentSelectors: [APP_MENU_SELECTORS]
|
||||
},
|
||||
permissionSelectors: [APP_MENU_SELECTORS.app]
|
||||
};
|
||||
} else {
|
||||
appPermissions = {
|
||||
permissionSelectors: [LEFT_MENU_SELECTORS.app]
|
||||
};
|
||||
}
|
||||
|
||||
permissionsOptions.all.permissions.push(appPermissions);
|
||||
permissionsOptions.app.permissions = [appPermissions];
|
||||
});
|
||||
});
|
||||
|
||||
Object.keys(permissionsOptions).forEach(key => {
|
||||
const tags =
|
||||
key === "all" ? ["critical", "all", "refactored"] : ["all", "refactored"];
|
||||
filterTests({ definedTags: tags }, () => {
|
||||
it(`should be able to navigate through shop as a staff member using ${key} permission. ${PERMISSIONS_OPTIONS[key].testCase}`, () => {
|
||||
const permissionOption = PERMISSIONS_OPTIONS[key];
|
||||
it(`should be able to navigate through shop as a staff member using ${key} permission. ${permissionsOptions[key].testCase}`, () => {
|
||||
const permissionOption = permissionsOptions[key];
|
||||
const permissions = permissionOption.permissions;
|
||||
cy.clearSessionData();
|
||||
permissionsSteps.navigateToAllAvailablePageAndCheckIfDisplayed(
|
||||
|
|
|
@ -1218,10 +1218,6 @@
|
|||
"context": "WarehouseSettings public stock label",
|
||||
"string": "Public Stock"
|
||||
},
|
||||
"89PSdB": {
|
||||
"context": "link",
|
||||
"string": "Edit settings"
|
||||
},
|
||||
"8B8E+3": {
|
||||
"context": "navigator placeholder",
|
||||
"string": "Order Number"
|
||||
|
@ -1929,6 +1925,10 @@
|
|||
"context": "date time attribute type",
|
||||
"string": "Date Time"
|
||||
},
|
||||
"E+M17x": {
|
||||
"context": "marketplace section name",
|
||||
"string": "Marketplace"
|
||||
},
|
||||
"E22x4H": {
|
||||
"context": "no card defuned alert message",
|
||||
"string": "You haven’t defined a gift card product!"
|
||||
|
@ -5700,10 +5700,6 @@
|
|||
"hX5PAb": {
|
||||
"string": "No results found"
|
||||
},
|
||||
"hdcGSJ": {
|
||||
"context": "button",
|
||||
"string": "Support/FAQ"
|
||||
},
|
||||
"hkENym": {
|
||||
"string": "Customer"
|
||||
},
|
||||
|
@ -6204,10 +6200,6 @@
|
|||
"llBnr+": {
|
||||
"string": "Warehouse Name"
|
||||
},
|
||||
"llC1q8": {
|
||||
"context": "button",
|
||||
"string": "App home page"
|
||||
},
|
||||
"lm9NSK": {
|
||||
"context": "password reset, button",
|
||||
"string": "Send an email with reset link"
|
||||
|
|
|
@ -9,7 +9,6 @@ const props: AppDetailsPageProps = {
|
|||
data: appDetails,
|
||||
loading: false,
|
||||
navigateToApp: () => undefined,
|
||||
navigateToAppSettings: () => undefined,
|
||||
onAppActivateOpen: () => undefined,
|
||||
onAppDeactivateOpen: () => undefined
|
||||
};
|
||||
|
|
|
@ -16,7 +16,6 @@ import { FormattedMessage, useIntl } from "react-intl";
|
|||
import ReactMarkdown from "react-markdown";
|
||||
|
||||
import activateIcon from "../../../../assets/images/activate-icon.svg";
|
||||
import settingsIcon from "../../../../assets/images/settings-icon.svg";
|
||||
import supportIcon from "../../../../assets/images/support-icon.svg";
|
||||
import { useStyles } from "../../styles";
|
||||
import DeactivatedText from "../DeactivatedText";
|
||||
|
@ -25,7 +24,6 @@ export interface AppDetailsPageProps {
|
|||
loading: boolean;
|
||||
data: AppQuery["app"];
|
||||
navigateToApp: () => void;
|
||||
navigateToAppSettings: () => void;
|
||||
onAppActivateOpen: () => void;
|
||||
onAppDeactivateOpen: () => void;
|
||||
}
|
||||
|
@ -34,7 +32,6 @@ export const AppDetailsPage: React.FC<AppDetailsPageProps> = ({
|
|||
data,
|
||||
loading,
|
||||
navigateToApp,
|
||||
navigateToAppSettings,
|
||||
onAppActivateOpen,
|
||||
onAppDeactivateOpen
|
||||
}) => {
|
||||
|
@ -76,20 +73,6 @@ export const AppDetailsPage: React.FC<AppDetailsPageProps> = ({
|
|||
description="link"
|
||||
/>
|
||||
</ExternalLink>
|
||||
{data.configurationUrl && (
|
||||
<ButtonBase
|
||||
className={classes.headerLinkContainer}
|
||||
disableRipple
|
||||
onClick={navigateToAppSettings}
|
||||
>
|
||||
<SVG src={settingsIcon} />
|
||||
<FormattedMessage
|
||||
id="89PSdB"
|
||||
defaultMessage="Edit settings"
|
||||
description="link"
|
||||
/>
|
||||
</ButtonBase>
|
||||
)}
|
||||
<ButtonBase
|
||||
className={classes.headerLinkContainer}
|
||||
disableRipple
|
||||
|
@ -163,18 +146,17 @@ export const AppDetailsPage: React.FC<AppDetailsPageProps> = ({
|
|||
</Card>
|
||||
<CardSpacer />
|
||||
|
||||
<Card>
|
||||
<CardTitle
|
||||
title={intl.formatMessage({
|
||||
id: "a55zOn",
|
||||
defaultMessage: "Data privacy",
|
||||
description: "section header"
|
||||
})}
|
||||
/>
|
||||
<CardContent>
|
||||
{!loading ? (
|
||||
<>
|
||||
<Typography>{data?.dataPrivacy}</Typography>
|
||||
{(loading || data?.dataPrivacyUrl) && (
|
||||
<Card>
|
||||
<CardTitle
|
||||
title={intl.formatMessage({
|
||||
id: "a55zOn",
|
||||
defaultMessage: "Data privacy",
|
||||
description: "section header"
|
||||
})}
|
||||
/>
|
||||
<CardContent>
|
||||
{!loading ? (
|
||||
<ExternalLink
|
||||
className={classes.linkContainer}
|
||||
href={data?.dataPrivacyUrl}
|
||||
|
@ -186,12 +168,12 @@ export const AppDetailsPage: React.FC<AppDetailsPageProps> = ({
|
|||
description="app privacy policy link"
|
||||
/>
|
||||
</ExternalLink>
|
||||
</>
|
||||
) : (
|
||||
<Skeleton />
|
||||
)}
|
||||
</CardContent>
|
||||
</Card>
|
||||
) : (
|
||||
<Skeleton />
|
||||
)}
|
||||
</CardContent>
|
||||
</Card>
|
||||
)}
|
||||
<CardSpacer />
|
||||
</Container>
|
||||
);
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import useShop from "@saleor/hooks/useShop";
|
||||
import { useTheme } from "@saleor/macaw-ui";
|
||||
import clsx from "clsx";
|
||||
import React from "react";
|
||||
import urlJoin from "url-join";
|
||||
|
||||
|
@ -10,6 +11,7 @@ interface Props {
|
|||
src: string;
|
||||
appToken: string;
|
||||
appId: string;
|
||||
className?: string;
|
||||
onLoad?(): void;
|
||||
onError?(): void;
|
||||
}
|
||||
|
@ -20,6 +22,7 @@ export const AppFrame: React.FC<Props> = ({
|
|||
src,
|
||||
appToken,
|
||||
appId,
|
||||
className,
|
||||
onLoad,
|
||||
onError
|
||||
}) => {
|
||||
|
@ -55,7 +58,7 @@ export const AppFrame: React.FC<Props> = ({
|
|||
src={urlJoin(src, `?domain=${shop.domain.host}&id=${appId}`)}
|
||||
onError={onError}
|
||||
onLoad={handleLoad}
|
||||
className={classes.iframe}
|
||||
className={clsx(classes.iframe, className)}
|
||||
sandbox="allow-same-origin allow-forms allow-scripts"
|
||||
/>
|
||||
);
|
||||
|
|
|
@ -70,32 +70,6 @@ export const AppPage: React.FC<AppPageProps> = ({
|
|||
description="button"
|
||||
/>
|
||||
</Button>
|
||||
<Button
|
||||
component="a"
|
||||
href={data?.homepageUrl}
|
||||
variant="primary"
|
||||
data-tc="open-app"
|
||||
target="_blank"
|
||||
>
|
||||
<FormattedMessage
|
||||
id="llC1q8"
|
||||
defaultMessage="App home page"
|
||||
description="button"
|
||||
/>
|
||||
</Button>
|
||||
<Button
|
||||
component="a"
|
||||
href={data?.supportUrl}
|
||||
variant="primary"
|
||||
data-tc="open-support"
|
||||
target="_blank"
|
||||
>
|
||||
<FormattedMessage
|
||||
id="hdcGSJ"
|
||||
defaultMessage="Support/FAQ"
|
||||
description="button"
|
||||
/>
|
||||
</Button>
|
||||
</div>
|
||||
</Grid>
|
||||
<CardSpacer />
|
||||
|
|
|
@ -55,9 +55,6 @@ export const appInstallUrl = appInstallPath;
|
|||
export const appDetailsUrl = (id: string, params?: AppDetailsUrlQueryParams) =>
|
||||
appDetailsPath(encodeURIComponent(id)) + "?" + stringifyQs(params);
|
||||
|
||||
export const appSettingsUrl = (id: string, params?: AppDetailsUrlQueryParams) =>
|
||||
appSettingsPath(encodeURIComponent(id)) + "?" + stringifyQs(params);
|
||||
|
||||
export const appUrl = (id: string, params?: AppDetailsUrlQueryParams) =>
|
||||
appPath(encodeURIComponent(id)) + "?" + stringifyQs(params);
|
||||
export const appDeepUrl = (
|
||||
|
|
|
@ -16,9 +16,9 @@ import AppActivateDialog from "../../components/AppActivateDialog";
|
|||
import AppDeactivateDialog from "../../components/AppDeactivateDialog";
|
||||
import AppDetailsPage from "../../components/AppDetailsPage";
|
||||
import {
|
||||
appDetailsUrl,
|
||||
AppDetailsUrlDialog,
|
||||
AppDetailsUrlQueryParams,
|
||||
appSettingsUrl,
|
||||
appsListPath,
|
||||
appUrl
|
||||
} from "../../urls";
|
||||
|
@ -88,7 +88,7 @@ export const AppDetails: React.FC<AppDetailsProps> = ({ id, params }) => {
|
|||
const [openModal, closeModal] = createDialogActionHandlers<
|
||||
AppDetailsUrlDialog,
|
||||
AppDetailsUrlQueryParams
|
||||
>(navigate, params => appUrl(id, params), params);
|
||||
>(navigate, params => appDetailsUrl(id, params), params);
|
||||
|
||||
const handleActivateConfirm = () => {
|
||||
activateApp(mutationOpts);
|
||||
|
@ -121,7 +121,6 @@ export const AppDetails: React.FC<AppDetailsProps> = ({ id, params }) => {
|
|||
data={data?.app}
|
||||
loading={loading}
|
||||
navigateToApp={() => navigate(appUrl(id))}
|
||||
navigateToAppSettings={() => navigate(appSettingsUrl(id))}
|
||||
onAppActivateOpen={() => openModal("app-activate")}
|
||||
onAppDeactivateOpen={() => openModal("app-deactivate")}
|
||||
/>
|
||||
|
|
|
@ -11,12 +11,14 @@ import {
|
|||
extensionMountPoints,
|
||||
useExtensions
|
||||
} from "@saleor/apps/useExtensions";
|
||||
import { MARKETPLACE_URL } from "@saleor/config";
|
||||
import { configurationMenuUrl } from "@saleor/configuration";
|
||||
import { getConfigMenuItemsPermissions } from "@saleor/configuration/utils";
|
||||
import { giftCardListUrl } from "@saleor/giftCards/urls";
|
||||
import { PermissionEnum, UserFragment } from "@saleor/graphql";
|
||||
import { commonMessages, sectionNames } from "@saleor/intl";
|
||||
import { SidebarMenuItem } from "@saleor/macaw-ui";
|
||||
import { marketplaceUrl } from "@saleor/marketplace/urls";
|
||||
import { pageListPath } from "@saleor/pages/urls";
|
||||
import { IntlShape } from "react-intl";
|
||||
|
||||
|
@ -55,6 +57,42 @@ function useMenuStructure(
|
|||
label: intl.formatMessage(sectionNames.appExtensions)
|
||||
};
|
||||
|
||||
// This will be deleted when Marketplace is released
|
||||
// Consider this solution as temporary
|
||||
const getAppSection = () => {
|
||||
if (MARKETPLACE_URL) {
|
||||
return {
|
||||
ariaLabel: "apps_section",
|
||||
iconSrc: appsIcon,
|
||||
label: intl.formatMessage(sectionNames.apps),
|
||||
permissions: [PermissionEnum.MANAGE_APPS],
|
||||
id: "apps_section",
|
||||
children: [
|
||||
{
|
||||
label: intl.formatMessage(sectionNames.apps),
|
||||
id: "apps",
|
||||
url: appsListPath
|
||||
},
|
||||
{
|
||||
ariaLabel: "marketplace",
|
||||
label: intl.formatMessage(sectionNames.marketplace),
|
||||
id: "marketplace",
|
||||
url: marketplaceUrl
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
ariaLabel: "apps",
|
||||
iconSrc: appsIcon,
|
||||
label: intl.formatMessage(sectionNames.apps),
|
||||
permissions: [PermissionEnum.MANAGE_APPS],
|
||||
id: "apps",
|
||||
url: appsListPath
|
||||
};
|
||||
};
|
||||
|
||||
const menuItems: FilterableMenuItem[] = [
|
||||
{
|
||||
ariaLabel: "home",
|
||||
|
@ -202,14 +240,7 @@ function useMenuStructure(
|
|||
id: "pages",
|
||||
url: pageListPath
|
||||
},
|
||||
{
|
||||
ariaLabel: "apps",
|
||||
iconSrc: appsIcon,
|
||||
label: intl.formatMessage(sectionNames.apps),
|
||||
permissions: [PermissionEnum.MANAGE_APPS],
|
||||
id: "apps",
|
||||
url: appsListPath
|
||||
},
|
||||
getAppSection(),
|
||||
{
|
||||
ariaLabel: "translations",
|
||||
children: extensions.NAVIGATION_TRANSLATIONS.length > 0 && [
|
||||
|
|
|
@ -8,6 +8,7 @@ export const APP_DEFAULT_URI = "/";
|
|||
export const API_URI = process.env.API_URI;
|
||||
export const SW_INTERVAL = parseInt(process.env.SW_INTERVAL, 10);
|
||||
export const IS_CLOUD_INSTANCE = process.env.IS_CLOUD_INSTANCE === "true";
|
||||
export const MARKETPLACE_URL = process.env.MARKETPLACE_URL;
|
||||
|
||||
export const DEFAULT_INITIAL_SEARCH_DATA: SearchVariables = {
|
||||
after: null,
|
||||
|
|
|
@ -47,6 +47,8 @@ import { giftCardsSectionUrlName } from "./giftCards/urls";
|
|||
import { apolloClient, saleorClient } from "./graphql/client";
|
||||
import HomePage from "./home";
|
||||
import { commonMessages } from "./intl";
|
||||
import MarketplaceSection from "./marketplace";
|
||||
import { marketplaceUrl } from "./marketplace/urls";
|
||||
import NavigationSection from "./navigation";
|
||||
import { navigationSection } from "./navigation/urls";
|
||||
import { NotFound } from "./NotFound";
|
||||
|
@ -250,6 +252,11 @@ const Routes: React.FC = () => {
|
|||
path={appsSection}
|
||||
component={AppsSection}
|
||||
/>
|
||||
<SectionRoute
|
||||
permissions={[PermissionEnum.MANAGE_APPS]}
|
||||
path={marketplaceUrl}
|
||||
component={MarketplaceSection}
|
||||
/>
|
||||
<SectionRoute
|
||||
permissions={[PermissionEnum.MANAGE_PRODUCTS]}
|
||||
path={warehouseSection}
|
||||
|
|
|
@ -382,6 +382,11 @@ export const sectionNames = defineMessages({
|
|||
defaultMessage: "Home",
|
||||
description: "home section name"
|
||||
},
|
||||
marketplace: {
|
||||
id: "E+M17x",
|
||||
defaultMessage: "Marketplace",
|
||||
description: "marketplace section name"
|
||||
},
|
||||
navigation: {
|
||||
id: "9C7PZE",
|
||||
defaultMessage: "Navigation",
|
||||
|
|
38
src/marketplace/index.tsx
Normal file
38
src/marketplace/index.tsx
Normal file
|
@ -0,0 +1,38 @@
|
|||
import { Container } from "@material-ui/core";
|
||||
import { AppFrame } from "@saleor/apps/components/AppFrame";
|
||||
import NotFoundPage from "@saleor/components/NotFoundPage";
|
||||
import { WindowTitle } from "@saleor/components/WindowTitle";
|
||||
import { MARKETPLACE_URL } from "@saleor/config";
|
||||
import useNavigator from "@saleor/hooks/useNavigator";
|
||||
import { sectionNames } from "@saleor/intl";
|
||||
import React from "react";
|
||||
import { useIntl } from "react-intl";
|
||||
|
||||
import { useStyles } from "./styles";
|
||||
|
||||
const Component = () => {
|
||||
const classes = useStyles();
|
||||
const intl = useIntl();
|
||||
const navigate = useNavigator();
|
||||
|
||||
if (!MARKETPLACE_URL) {
|
||||
return <NotFoundPage onBack={() => navigate("/")} />;
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<WindowTitle title={intl.formatMessage(sectionNames.marketplace)} />
|
||||
<Container>
|
||||
<AppFrame
|
||||
src={MARKETPLACE_URL}
|
||||
// Marketplace doesn't require app token nor id
|
||||
appToken=""
|
||||
appId=""
|
||||
className={classes.iframe}
|
||||
/>
|
||||
</Container>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default Component;
|
15
src/marketplace/styles.ts
Normal file
15
src/marketplace/styles.ts
Normal file
|
@ -0,0 +1,15 @@
|
|||
import { makeStyles } from "@saleor/macaw-ui";
|
||||
|
||||
const useStyles = makeStyles(
|
||||
() => ({
|
||||
iframe: {
|
||||
height: "100vh",
|
||||
position: "sticky"
|
||||
}
|
||||
}),
|
||||
{
|
||||
name: "marketplaceStyles"
|
||||
}
|
||||
);
|
||||
|
||||
export { useStyles };
|
3
src/marketplace/urls.ts
Normal file
3
src/marketplace/urls.ts
Normal file
|
@ -0,0 +1,3 @@
|
|||
const marketplaceSection = "/marketplace/";
|
||||
|
||||
export const marketplaceUrl = marketplaceSection;
|
|
@ -24699,34 +24699,6 @@ exports[`Storyshots Views / Apps / App default 1`] = `
|
|||
About
|
||||
</span>
|
||||
</button>
|
||||
<a
|
||||
aria-disabled="false"
|
||||
class="MuiButtonBase-root-id MuiButton-root-id MuiButton-contained-id MuiButton-containedPrimary-id"
|
||||
data-tc="open-app"
|
||||
href="http://localhost:8888/homepage"
|
||||
tabindex="0"
|
||||
target="_blank"
|
||||
>
|
||||
<span
|
||||
class="MuiButton-label-id"
|
||||
>
|
||||
App home page
|
||||
</span>
|
||||
</a>
|
||||
<a
|
||||
aria-disabled="false"
|
||||
class="MuiButtonBase-root-id MuiButton-root-id MuiButton-contained-id MuiButton-containedPrimary-id"
|
||||
data-tc="open-support"
|
||||
href="http://localhost:8888/support"
|
||||
tabindex="0"
|
||||
target="_blank"
|
||||
>
|
||||
<span
|
||||
class="MuiButton-label-id"
|
||||
>
|
||||
Support/FAQ
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
|
@ -24806,13 +24778,6 @@ exports[`Storyshots Views / Apps / App details default 1`] = `
|
|||
Get Support
|
||||
</div>
|
||||
</a>
|
||||
<button
|
||||
class="MuiButtonBase-root-id AppList-headerLinkContainer-id"
|
||||
tabindex="0"
|
||||
type="button"
|
||||
>
|
||||
Edit settings
|
||||
</button>
|
||||
<button
|
||||
class="MuiButtonBase-root-id AppList-headerLinkContainer-id"
|
||||
tabindex="0"
|
||||
|
@ -24910,11 +24875,6 @@ exports[`Storyshots Views / Apps / App details default 1`] = `
|
|||
<div
|
||||
class="MuiCardContent-root-id"
|
||||
>
|
||||
<div
|
||||
class="MuiTypography-root-id MuiTypography-body1-id"
|
||||
>
|
||||
Lorem ipsum
|
||||
</div>
|
||||
<a
|
||||
class="ExternalLink-link-id"
|
||||
href="http://localhost:8888/app-data-privacy"
|
||||
|
@ -24993,13 +24953,6 @@ exports[`Storyshots Views / Apps / App details loading 1`] = `
|
|||
Get Support
|
||||
</div>
|
||||
</a>
|
||||
<button
|
||||
class="MuiButtonBase-root-id AppList-headerLinkContainer-id"
|
||||
tabindex="0"
|
||||
type="button"
|
||||
>
|
||||
Edit settings
|
||||
</button>
|
||||
<button
|
||||
class="MuiButtonBase-root-id AppList-headerLinkContainer-id"
|
||||
tabindex="0"
|
||||
|
@ -25144,34 +25097,6 @@ exports[`Storyshots Views / Apps / App settings 1`] = `
|
|||
About
|
||||
</span>
|
||||
</button>
|
||||
<a
|
||||
aria-disabled="false"
|
||||
class="MuiButtonBase-root-id MuiButton-root-id MuiButton-contained-id MuiButton-containedPrimary-id"
|
||||
data-tc="open-app"
|
||||
href="http://localhost:8888/homepage"
|
||||
tabindex="0"
|
||||
target="_blank"
|
||||
>
|
||||
<span
|
||||
class="MuiButton-label-id"
|
||||
>
|
||||
App home page
|
||||
</span>
|
||||
</a>
|
||||
<a
|
||||
aria-disabled="false"
|
||||
class="MuiButtonBase-root-id MuiButton-root-id MuiButton-contained-id MuiButton-containedPrimary-id"
|
||||
data-tc="open-support"
|
||||
href="http://localhost:8888/support"
|
||||
tabindex="0"
|
||||
target="_blank"
|
||||
>
|
||||
<span
|
||||
class="MuiButton-label-id"
|
||||
>
|
||||
Support/FAQ
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
|
|
|
@ -38,6 +38,7 @@ const htmlWebpackPlugin = new HtmlWebpackPlugin({
|
|||
});
|
||||
const environmentPlugin = new webpack.EnvironmentPlugin({
|
||||
API_URI: "",
|
||||
MARKETPLACE_URL: "",
|
||||
APP_MOUNT_URI: "/",
|
||||
DEMO_MODE: false,
|
||||
ENVIRONMENT: "",
|
||||
|
|
Loading…
Reference in a new issue