Display custom Apps' logos (#3749)

* wip

* implement logo in all contexts

* fix types

* Improve icons rendering

* Reuse App Header in Manage App page

* Remove loading fallback icon for official Saleor apps. It will be fetched with manifest now

* Imprve app fallback icon

* wip fix tests

* Remove useless test

* Add sizes for logos queries

* Fix thumbnail size
This commit is contained in:
Lukasz Ostrowski 2023-06-15 16:06:08 +02:00 committed by GitHub
parent 549fc57884
commit 8ba29059a2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
22 changed files with 787 additions and 266 deletions

View file

@ -2,39 +2,33 @@ import { AppLogo } from "@dashboard/apps/types";
import { Box, GenericAppIcon } from "@saleor/macaw-ui/next";
import React from "react";
const avatarSize = 8;
export const AppAvatar: React.FC<{
logo?: AppLogo | undefined;
}> = ({ logo }) => {
if (logo?.source) {
return (
<Box
__backgroundColor={logo?.color}
padding={1}
width={avatarSize}
height={avatarSize}
borderRadius={2}
display="flex"
placeItems="center"
>
<Box as="img" src={logo.source} />
</Box>
);
} else {
return (
<Box
__backgroundColor={logo?.color}
backgroundColor="surfaceNeutralSubdued"
padding={1}
width={avatarSize}
height={avatarSize}
display="flex"
placeItems="center"
borderRadius={2}
>
<GenericAppIcon size="large" color="iconNeutralSubdued" />
</Box>
);
}
};
size?: 8 | 12;
}> = ({ logo, size = 8 }) =>
logo ? (
<Box
width={size}
height={size}
display="flex"
placeItems="center"
borderRadius={2}
>
<Box as="img" src={logo.source} width={"100%"} />
</Box>
) : (
<Box
padding={1}
backgroundColor="surfaceNeutralSubdued"
width={size}
height={size}
display="flex"
placeItems="center"
borderRadius={2}
borderWidth={1}
borderColor={"neutralPlain"}
borderStyle={"solid"}
>
<GenericAppIcon size="large" color="iconNeutralSubdued" />
</Box>
);

View file

@ -1,90 +0,0 @@
import { appDetails } from "@dashboard/apps/fixtures";
import { render } from "@testing-library/react";
import React from "react";
import Header from "./Header";
const mockHeaderOptions = jest.fn();
const mockTopNav = jest.fn();
jest.mock("@dashboard/components/AppLayout/TopNav", () => ({
TopNav: props => {
mockTopNav(props);
return <>{props.children}</>;
},
}));
jest.mock("../DeactivatedText", () => () => "deactivated");
jest.mock("react-intl", () => ({
useIntl: jest.fn(() => ({
formatMessage: jest.fn(x => x.defaultMessage),
})),
defineMessages: jest.fn(x => x),
FormattedMessage: ({ defaultMessage }) => <>{defaultMessage}</>,
}));
jest.mock("./HeaderOptions", () => props => {
mockHeaderOptions(props);
return <></>;
});
beforeEach(() => {
mockHeaderOptions.mockClear();
mockTopNav.mockClear();
});
describe("Apps AppDetailsPage Header", () => {
it("displays app details options when active app data passed", () => {
// Arrange
const onAppActivateOpen = jest.fn();
const onAppDeactivateOpen = jest.fn();
const onAppDeleteOpen = jest.fn();
// Act
render(
<Header
data={appDetails}
onAppActivateOpen={onAppActivateOpen}
onAppDeactivateOpen={onAppDeactivateOpen}
onAppDeleteOpen={onAppDeleteOpen}
/>,
);
const title = render(mockTopNav.mock.calls[0][0].title);
// Assert
expect(mockHeaderOptions).toHaveBeenCalledWith({
data: appDetails,
onAppActivateOpen,
onAppDeactivateOpen,
onAppDeleteOpen,
});
expect(mockTopNav).toHaveBeenCalled();
expect(title.container).toHaveTextContent(appDetails.name as string);
});
it("displays app details options when inactive app data passed", () => {
// Arrange
const onAppActivateOpen = jest.fn();
const onAppDeactivateOpen = jest.fn();
const onAppDeleteOpen = jest.fn();
// Act
render(
<Header
data={{ ...appDetails, isActive: false }}
onAppActivateOpen={onAppActivateOpen}
onAppDeactivateOpen={onAppDeactivateOpen}
onAppDeleteOpen={onAppDeleteOpen}
/>,
);
const title = render(mockTopNav.mock.calls[0][0].title);
// Assert
expect(mockHeaderOptions).toHaveBeenCalledWith({
data: { ...appDetails, isActive: false },
onAppActivateOpen,
onAppDeactivateOpen,
onAppDeleteOpen,
});
expect(mockTopNav).toHaveBeenCalled();
expect(title.container).toHaveTextContent(`${appDetails.name} deactivated`);
});
});

View file

@ -1,9 +1,8 @@
import { AppPageNav } from "@dashboard/apps/components/AppPage/AppPageNav";
import { AppUrls } from "@dashboard/apps/urls";
import { TopNav } from "@dashboard/components/AppLayout/TopNav";
import { AppQuery } from "@dashboard/graphql";
import React from "react";
import DeactivatedText from "../DeactivatedText";
import HeaderOptions from "./HeaderOptions";
interface HeaderProps {
@ -36,14 +35,17 @@ const Header: React.FC<HeaderProps> = ({
return (
<>
<TopNav
href={getBackButtonUrl()}
title={
<>
{data?.name} {!data?.isActive && <DeactivatedText />}
</>
}
<AppPageNav
name={data.name}
supportUrl={data.supportUrl}
homepageUrl={data.homepageUrl}
author={data.author}
appLogoUrl={data.brand?.logo.default}
appId={data.id}
goBackUrl={getBackButtonUrl()}
showMangeAppButton={false}
/>
<HeaderOptions
data={data}
onAppActivateOpen={onAppActivateOpen}

View file

@ -1,4 +1,3 @@
import ExternalLink from "@dashboard/components/ExternalLink";
import Skeleton from "@dashboard/components/Skeleton";
import { AppQuery } from "@dashboard/graphql";
import { buttonMessages } from "@dashboard/intl";
@ -10,8 +9,6 @@ import { FormattedMessage } from "react-intl";
import activateIcon from "../../../../assets/images/activate-icon.svg";
import deleteIcon from "../../../../assets/images/delete.svg";
import supportIcon from "../../../../assets/images/support-icon.svg";
import messages from "./messages";
import { useStyles } from "./styles";
interface HeaderOptionsProps {
@ -41,14 +38,6 @@ const HeaderOptions: React.FC<HeaderOptionsProps> = ({
return (
<Box marginX={7}>
<div className={classes.appHeaderLinks}>
<ExternalLink
className={classes.headerLinkContainer}
href={data.supportUrl || ""}
target="_blank"
>
<SVG src={supportIcon} />
<FormattedMessage {...messages.supportLink} />
</ExternalLink>
<ButtonBase
className={classes.headerLinkContainer}
disableRipple

View file

@ -1,5 +1,7 @@
import saleorDarkLogoSmall from "@assets/images/logo-dark-small.svg";
import plusIcon from "@assets/images/plus-icon.svg";
import saleorLogoDarkMode from "@assets/images/sidebar-deafult-logo-darkMode.png";
import saleorLogoLightMode from "@assets/images/sidebar-default-logo.png";
import { AppAvatar } from "@dashboard/apps/components/AppAvatar/AppAvatar";
import CardSpacer from "@dashboard/components/CardSpacer";
import CardTitle from "@dashboard/components/CardTitle";
import Hr from "@dashboard/components/Hr";
@ -8,14 +10,14 @@ import Skeleton from "@dashboard/components/Skeleton";
import { AppFetchMutation, AppInstallMutation } from "@dashboard/graphql";
import { SubmitPromise } from "@dashboard/hooks/useForm";
import { buttonMessages } from "@dashboard/intl";
import { useTheme } from "@dashboard/theme";
import {
Card,
CardContent,
CircularProgress,
Typography,
} from "@material-ui/core";
import { Box, Button, GenericAppIcon } from "@saleor/macaw-ui/next";
import clsx from "clsx";
import { Box, Button } from "@saleor/macaw-ui/next";
import React from "react";
import { FormattedMessage, useIntl } from "react-intl";
@ -39,6 +41,18 @@ export const AppInstallPage: React.FC<AppInstallPageProps> = ({
}) => {
const intl = useIntl();
const classes = useStyles();
const { theme } = useTheme();
const getSaleorLogoUrl = () => {
switch (theme) {
case "defaultLight":
return saleorLogoLightMode;
case "defaultDark":
return saleorLogoDarkMode;
default:
throw new Error("Invalid theme mode, should not happen.");
}
};
const name = data?.name || "";
@ -62,18 +76,27 @@ export const AppInstallPage: React.FC<AppInstallPageProps> = ({
<CircularProgress />
) : (
<div className={classes.installAppContainer}>
<div
className={clsx(
classes.installIcon,
classes.installSaleorIcon,
)}
<Box
width={12}
height={12}
display="flex"
placeItems="center"
borderRadius={2}
overflow="hidden"
>
<img src={saleorDarkLogoSmall} alt="" />
</div>
<img src={getSaleorLogoUrl()} alt="Saleor" />
</Box>
<img src={plusIcon} alt="" />
<div className={classes.installIcon}>
<GenericAppIcon />
</div>
<AppAvatar
size={12}
logo={
data?.brand?.logo.default
? {
source: data?.brand?.logo.default,
}
: undefined
}
/>
</div>
)}
</CardContent>

View file

@ -29,17 +29,6 @@ export const useStyles = makeStyles(
justifyContent: "center",
position: "relative",
},
installIcon: {
alignItems: "center",
backgroundColor: theme.palette.divider,
border: `1px solid ${theme.palette.divider}`,
borderRadius: "50%",
display: "flex",
height: theme.spacing(9),
justifyContent: "center",
overflow: "hidden",
width: theme.spacing(9),
},
installPermissionTitle: {
fontWeight: 500,
},
@ -51,13 +40,6 @@ export const useStyles = makeStyles(
color: theme.palette.text.hint,
marginTop: theme.spacing(1),
},
installSaleorIcon: {
backgroundColor:
theme.palette.type === "dark"
? theme.palette.saleor.gray.default
: theme.palette.saleor.main[1],
border: "none",
},
installSpacer: {
margin: theme.spacing(2, 0),
},

View file

@ -187,6 +187,7 @@ describe("App List verified installed apps util", () => {
name: "Manage customers.",
},
],
brand: null,
},
{
__typename: "App",
@ -209,6 +210,7 @@ describe("App List verified installed apps util", () => {
name: "Manage customers.",
},
],
brand: null,
},
];
const installableMarketplaceApps: GetV2SaleorAppsResponse.ReleasedSaleorApp[] =
@ -244,10 +246,6 @@ describe("App List verified installed apps util", () => {
{
app: installedApps[0],
isExternal: false,
logo: {
source: "https://www.example.com/logo",
color: "#000000",
},
},
{
app: installedApps[1],
@ -279,6 +277,7 @@ describe("App List verified installable marketplace apps util", () => {
name: "Manage customers.",
},
],
brand: null,
},
{
__typename: "App",
@ -301,6 +300,7 @@ describe("App List verified installable marketplace apps util", () => {
name: "Manage customers.",
},
],
brand: null,
},
];
const installableMarketplaceApps: GetV2SaleorAppsResponse.ReleasedSaleorApp[] =

View file

@ -48,7 +48,6 @@ export const getVerifiedInstalledApps = (
return {
app,
isExternal: !marketplaceApp,
logo: marketplaceApp?.logo,
};
});
@ -65,7 +64,6 @@ export const getVerifiedAppsInstallations = (
return {
appInstallation,
isExternal: !marketplaceApp,
logo: marketplaceApp?.logo,
};
});

View file

@ -1,3 +1,4 @@
import { AppUrls } from "@dashboard/apps/urls";
import {
borderHeight,
topBarHeight,
@ -25,11 +26,13 @@ export const AppPage: React.FC<AppPageProps> = ({
}) => (
<DetailPageLayout gridTemplateColumns={1} withSavebar={false}>
<AppPageNav
goBackUrl={AppUrls.resolveAppListUrl()}
appId={data.id}
name={data?.name}
supportUrl={data?.supportUrl}
homepageUrl={data?.homepageUrl}
author={data?.author}
appLogoUrl={data?.brand?.logo.default}
/>
<DetailPageLayout.Content>
<Box

View file

@ -1,19 +1,25 @@
import { AppAvatar } from "@dashboard/apps/components/AppAvatar/AppAvatar";
import { AppLogo } from "@dashboard/apps/types";
import { AppUrls } from "@dashboard/apps/urls";
import { TopNavLink, TopNavWrapper } from "@dashboard/components/AppLayout";
import { LinkState } from "@dashboard/components/Link";
import useNavigator from "@dashboard/hooks/useNavigator";
import { Box, Button, Text } from "@saleor/macaw-ui/next";
import React from "react";
import React, { useMemo } from "react";
import { FormattedMessage } from "react-intl";
import { useLocation } from "react-router";
interface AppPageNavProps {
name: string | undefined | null;
supportUrl: string | undefined | null;
homepageUrl: string | undefined | null;
author: string | undefined | null;
name?: string | undefined | null;
supportUrl?: string | undefined | null;
homepageUrl?: string | undefined | null;
author?: string | undefined | null;
appId: string;
appLogoUrl?: string | undefined | null;
goBackUrl: string;
/**
* Temporary prop, so the header can be composed with buttons instead hard coding them.
* Component is used on Manage App page too, so the button should be hidden there
*/
showMangeAppButton?: boolean;
}
export const AppPageNav: React.FC<AppPageNavProps> = ({
@ -21,16 +27,27 @@ export const AppPageNav: React.FC<AppPageNavProps> = ({
supportUrl,
homepageUrl,
author,
appLogoUrl,
goBackUrl,
appId,
showMangeAppButton = true,
}) => {
const location = useLocation<LinkState>();
const goBackLink = location.state?.from ?? AppUrls.resolveAppListUrl();
const navigate = useNavigator();
const navigateToManageAppScreen = () => {
navigate(AppUrls.resolveAppDetailsUrl(appId));
};
const logo = useMemo(
(): AppLogo | undefined =>
appLogoUrl
? {
source: appLogoUrl,
}
: undefined,
[appLogoUrl],
);
return (
<TopNavWrapper>
<Box
@ -40,9 +57,9 @@ export const AppPageNav: React.FC<AppPageNavProps> = ({
width="100%"
>
<Box display="flex" gap={4} alignItems="center">
<TopNavLink to={goBackLink} variant="tertiary" />
<TopNavLink to={goBackUrl} variant="tertiary" />
<Box display="flex" gap={2} alignItems="center">
<AppAvatar />
<AppAvatar size={8} logo={logo} />
<Box display="flex" flexDirection="column">
<Text variant="heading">{name}</Text>
<Text
@ -63,18 +80,20 @@ export const AppPageNav: React.FC<AppPageNavProps> = ({
</Box>
</Box>
<Box display="flex" gap={1.5}>
<Button
whiteSpace="nowrap"
variant="secondary"
onClick={navigateToManageAppScreen}
data-test-id="app-settings-button"
>
<FormattedMessage
defaultMessage="Manage app"
id="LwX0Ug"
description="Button with Manage app label"
/>
</Button>
{showMangeAppButton && (
<Button
whiteSpace="nowrap"
variant="secondary"
onClick={navigateToManageAppScreen}
data-test-id="app-settings-button"
>
<FormattedMessage
defaultMessage="Manage app"
id="LwX0Ug"
description="Button with Manage app label"
/>
</Button>
)}
{supportUrl && (
<Button
variant="secondary"

View file

@ -27,7 +27,11 @@ const InstalledAppList: React.FC<InstalledAppListProps> = ({
key={appInstallation.id}
appInstallation={appInstallation}
isExternal={isExternal}
logo={logo}
logo={
appInstallation.brand?.logo.default
? { source: appInstallation.brand.logo.default }
: logo
}
/>
))}
{appList.map(({ app, isExternal, logo }) => (
@ -35,7 +39,9 @@ const InstalledAppList: React.FC<InstalledAppListProps> = ({
key={app.id}
app={app}
isExternal={isExternal}
logo={logo}
logo={
app.brand?.logo.default ? { source: app.brand?.logo.default } : logo
}
/>
))}
</List>

View file

@ -8,13 +8,13 @@ export const useStyles = makeStyles<InstalledApp>(
alignItems: "center",
gap: theme.spacing(2),
},
logo: props => ({
backgroundColor: props.logo?.color || theme.palette.grey[300],
color: props.logo?.color ? "#fff" : theme.palette.grey[600],
logo: {
backgroundColor: theme.palette.grey[300],
color: theme.palette.grey[600],
padding: theme.spacing(1.2),
borderRadius: theme.spacing(1),
borderWidth: 0,
}),
},
name: {
fontWeight: 600,
},

View file

@ -8,13 +8,13 @@ export const useStyles = makeStyles<AppInstallation>(
alignItems: "center",
gap: theme.spacing(2),
},
logo: props => ({
backgroundColor: props.logo?.color || theme.palette.grey[300],
color: props.logo?.color ? "#fff" : theme.palette.grey[600],
logo: {
backgroundColor: theme.palette.grey[300],
color: theme.palette.grey[600],
padding: theme.spacing(1.2),
borderRadius: theme.spacing(1),
borderWidth: 0,
}),
},
name: {
fontWeight: 600,
},

View file

@ -27,6 +27,7 @@ export const activeApp: AppListItemFragment = {
name: "Manage customers.",
},
],
brand: null,
};
export const inactiveApp: AppListItemFragment = {
@ -50,6 +51,7 @@ export const inactiveApp: AppListItemFragment = {
name: "Manage customers.",
},
],
brand: null,
};
export const installedAppsList: AppListItemFragment[] = [
@ -64,6 +66,7 @@ export const failedAppInProgress: AppInstallationFragment = {
manifestUrl: "https://www.released-example.com/manifest",
message: "Failed to connect to app. Try later or contact with app support.",
status: JobStatusEnum.FAILED,
brand: null,
};
export const pendingAppInProgress: AppInstallationFragment = {
@ -73,6 +76,7 @@ export const pendingAppInProgress: AppInstallationFragment = {
manifestUrl: "https://www.released-example.com/manifest",
message: "Pending.",
status: JobStatusEnum.PENDING,
brand: null,
};
export const successAppInProgress: AppInstallationFragment = {
@ -82,6 +86,7 @@ export const successAppInProgress: AppInstallationFragment = {
manifestUrl: "https://www.released-example.com/manifest",
message: "Success.",
status: JobStatusEnum.SUCCESS,
brand: null,
};
export const appsInProgress: AppInstallationFragment[] = [
@ -124,6 +129,7 @@ export const appDetails: NonNullable<AppQuery["app"]> = {
type: AppTypeEnum.THIRDPARTY,
version: "1.0.0",
webhooks: [],
brand: null,
};
export const installApp: AppManifestFragment = {
@ -151,6 +157,7 @@ export const installApp: AppManifestFragment = {
supportUrl: null,
tokenTargetUrl: null,
version: "1.0",
brand: null,
};
export const appAvatar: AppAvatarFragment = {

View file

@ -53,6 +53,11 @@ export const appDetails = gql`
}
dataPrivacy
dataPrivacyUrl
brand {
logo {
default(size: 24, format: WEBP)
}
}
}
}
`;

View file

@ -5,7 +5,6 @@ import {
export interface AppLogo {
source: string | null;
color: string;
}
export interface InstalledApp {

View file

@ -134,6 +134,7 @@ describe("App utils app details", () => {
status: JobStatusEnum.PENDING,
message: "Test message",
manifestUrl: "https://www.example.com/manifest",
brand: null,
};
// Act
@ -200,6 +201,7 @@ describe("App utils app details", () => {
status: JobStatusEnum.FAILED,
message: "Test message",
manifestUrl: "https://www.example.com/manifest",
brand: null,
};
// Act
@ -249,6 +251,7 @@ describe("App utils app details", () => {
status: JobStatusEnum.PENDING,
message: "Test message",
manifestUrl: releasedApp.manifestUrl as string,
brand: null,
};
const appInstallationList: AppInstallationFragment[] = [
releasedAppInstallation,

View file

@ -17,6 +17,11 @@ export const appManifestFragment = gql`
code
name
}
brand {
logo {
default(format: WEBP, size: 64)
}
}
}
`;
@ -34,6 +39,11 @@ export const appFragment = gql`
supportUrl
version
accessToken
brand {
logo {
default(format: WEBP, size: 24)
}
}
privateMetadata {
key
value
@ -60,6 +70,11 @@ export const appInstallationFragment = gql`
appName
manifestUrl
id
brand {
logo {
default(format: WEBP, size: 32)
}
}
}
`;
@ -72,6 +87,11 @@ export const appListItemFragment = gql`
appUrl
manifestUrl
version
brand {
logo {
default(format: WEBP, size: 32)
}
}
permissions {
...AppPermission
}

View file

@ -67,6 +67,7 @@
"MenuItemDeleted",
"MenuItemUpdated",
"MenuUpdated",
"OrderBulkCreated",
"OrderCancelled",
"OrderConfirmed",
"OrderCreated",

View file

@ -22,6 +22,11 @@ export const AppManifestFragmentDoc = gql`
code
name
}
brand {
logo {
default(format: WEBP, size: 64)
}
}
}
`;
export const WebhookFragmentDoc = gql`
@ -49,6 +54,11 @@ export const AppFragmentDoc = gql`
supportUrl
version
accessToken
brand {
logo {
default(format: WEBP, size: 24)
}
}
privateMetadata {
key
value
@ -74,6 +84,11 @@ export const AppInstallationFragmentDoc = gql`
appName
manifestUrl
id
brand {
logo {
default(format: WEBP, size: 32)
}
}
}
`;
export const AppPermissionFragmentDoc = gql`
@ -91,6 +106,11 @@ export const AppListItemFragmentDoc = gql`
appUrl
manifestUrl
version
brand {
logo {
default(format: WEBP, size: 32)
}
}
permissions {
...AppPermission
}
@ -3668,6 +3688,11 @@ export const AppDocument = gql`
}
dataPrivacy
dataPrivacyUrl
brand {
logo {
default(size: 24, format: WEBP)
}
}
}
}
${AppFragmentDoc}`;

File diff suppressed because one or more lines are too long

View file

@ -23,6 +23,8 @@ export type Scalars = {
* [iso8601](https://en.wikipedia.org/wiki/ISO_8601).
*/
DateTime: any;
/** The `Day` scalar type represents number of days by integer value. */
Day: any;
/**
* Custom Decimal implementation.
*
@ -182,7 +184,6 @@ export enum AddressTypeEnum {
* within the channel
*
* PRIORITIZE_HIGH_STOCK - allocate stock in a warehouse with the most stock
*
*/
export enum AllocationStrategyEnum {
PRIORITIZE_SORTING_ORDER = 'PRIORITIZE_SORTING_ORDER',
@ -237,7 +238,6 @@ export enum AppExtensionMountEnum {
*
* POPUP - app's extension will be mounted as a popup window
* APP_PAGE - redirect to app's page
*
*/
export enum AppExtensionTargetEnum {
POPUP = 'POPUP',
@ -307,6 +307,17 @@ export enum AreaUnitsEnum {
SQ_INCH = 'SQ_INCH'
}
export type AttributeBulkTranslateInput = {
/** Attribute ID. */
id?: InputMaybe<Scalars['ID']>;
/** External reference of an attribute. */
externalReference?: InputMaybe<Scalars['String']>;
/** Translation language code. */
languageCode: LanguageCodeEnum;
/** Translation fields. */
translationFields: NameTranslationInput;
};
export enum AttributeChoicesSortField {
/** Sort attribute choice by name. */
NAME = 'NAME',
@ -481,6 +492,14 @@ export type AttributeSortingInput = {
field: AttributeSortField;
};
/** An enumeration. */
export enum AttributeTranslateErrorCode {
GRAPHQL_ERROR = 'GRAPHQL_ERROR',
INVALID = 'INVALID',
NOT_FOUND = 'NOT_FOUND',
REQUIRED = 'REQUIRED'
}
/** An enumeration. */
export enum AttributeTypeEnum {
PRODUCT_TYPE = 'PRODUCT_TYPE',
@ -539,6 +558,17 @@ export type AttributeUpdateInput = {
externalReference?: InputMaybe<Scalars['String']>;
};
export type AttributeValueBulkTranslateInput = {
/** Attribute value ID. */
id?: InputMaybe<Scalars['ID']>;
/** External reference of an attribute value. */
externalReference?: InputMaybe<Scalars['String']>;
/** Translation language code. */
languageCode: LanguageCodeEnum;
/** Translation fields. */
translationFields: AttributeValueTranslationInput;
};
export type AttributeValueCreateInput = {
/** Represent value of the attribute value (e.g. color values for swatch attributes). */
value?: InputMaybe<Scalars['String']>;
@ -578,22 +608,28 @@ export type AttributeValueFilterInput = {
export type AttributeValueInput = {
/** ID of the selected attribute. */
id?: InputMaybe<Scalars['ID']>;
/**
* External ID of this attribute.
*
* Added in Saleor 3.14.
*/
externalReference?: InputMaybe<Scalars['String']>;
/** The value or slug of an attribute to resolve. If the passed value is non-existent, it will be created. This field will be removed in Saleor 4.0. */
values?: InputMaybe<Array<Scalars['String']>>;
/**
* Attribute value ID.
* Attribute value ID or external reference.
*
* Added in Saleor 3.9.
*/
dropdown?: InputMaybe<AttributeValueSelectableTypeInput>;
/**
* Attribute value ID.
* Attribute value ID or external reference.
*
* Added in Saleor 3.9.
*/
swatch?: InputMaybe<AttributeValueSelectableTypeInput>;
/**
* List of attribute value IDs.
* List of attribute value IDs or external references.
*
* Added in Saleor 3.9.
*/
@ -623,17 +659,35 @@ export type AttributeValueInput = {
};
/**
* Represents attribute value. If no ID provided, value will be resolved.
* Represents attribute value.
* 1. If ID is provided, then attribute value will be resolved by ID.
* 2. If externalReference is provided, then attribute value will be resolved by external reference.
* 3. If value is provided, then attribute value will be resolved by value. If this attribute value doesn't exist, then it will be created.
* 4. If externalReference and value is provided then new attribute value will be created.
*
* Added in Saleor 3.9.
*/
export type AttributeValueSelectableTypeInput = {
/** ID of an attribute value. */
id?: InputMaybe<Scalars['ID']>;
/**
* External reference of an attribute value.
*
* Added in Saleor 3.14.
*/
externalReference?: InputMaybe<Scalars['String']>;
/** The value or slug of an attribute to resolve. If the passed value is non-existent, it will be created. */
value?: InputMaybe<Scalars['String']>;
};
/** An enumeration. */
export enum AttributeValueTranslateErrorCode {
GRAPHQL_ERROR = 'GRAPHQL_ERROR',
INVALID = 'INVALID',
NOT_FOUND = 'NOT_FOUND',
REQUIRED = 'REQUIRED'
}
export type AttributeValueTranslationInput = {
name?: InputMaybe<Scalars['String']>;
/**
@ -708,6 +762,12 @@ export type AttributeWhereInput = {
export type BulkAttributeValueInput = {
/** ID of the selected attribute. */
id?: InputMaybe<Scalars['ID']>;
/**
* External ID of this attribute.
*
* Added in Saleor 3.14.
*/
externalReference?: InputMaybe<Scalars['String']>;
/** The value or slug of an attribute to resolve. If the passed value is non-existent, it will be created.This field will be removed in Saleor 4.0. */
values?: InputMaybe<Array<Scalars['String']>>;
/**
@ -995,7 +1055,6 @@ export type CheckoutAddressValidationRules = {
* NONE - the funds are not authorized
* PARTIAL - the cover funds don't cover fully the checkout's total
* FULL - the cover funds covers the checkout's total
*
*/
export enum CheckoutAuthorizeStatusEnum {
NONE = 'NONE',
@ -1018,7 +1077,6 @@ export enum CheckoutAuthorizeStatusEnum {
* PARTIAL - the funds that are charged don't cover the checkout's total
* FULL - the funds that are charged fully cover the checkout's total
* OVERCHARGED - the charged funds are bigger than checkout's total
*
*/
export enum CheckoutChargeStatusEnum {
NONE = 'NONE',
@ -1733,6 +1791,29 @@ export type DateTimeRangeInput = {
lte?: InputMaybe<Scalars['DateTime']>;
};
/**
* Define the filtering options for decimal fields.
*
* Added in Saleor 3.14.
*
* Note: this API is currently in Feature Preview and can be subject to changes at later point.
*/
export type DecimalFilterInput = {
/** The value equal to. */
eq?: InputMaybe<Scalars['Decimal']>;
/** The value included in. */
oneOf?: InputMaybe<Array<Scalars['Decimal']>>;
/** The value in range. */
range?: InputMaybe<DecimalRangeInput>;
};
export type DecimalRangeInput = {
/** Decimal value greater than or equal to. */
gte?: InputMaybe<Scalars['Decimal']>;
/** Decimal value less than or equal to. */
lte?: InputMaybe<Scalars['Decimal']>;
};
export type DigitalContentInput = {
/** Use default digital content settings for this product. */
useDefaultSettings: Scalars['Boolean'];
@ -2266,6 +2347,26 @@ export type GiftCardUpdateInput = {
balanceAmount?: InputMaybe<Scalars['PositiveDecimal']>;
};
/**
* Define the filtering options for foreign key fields.
*
* Added in Saleor 3.14.
*
* Note: this API is currently in Feature Preview and can be subject to changes at later point.
*/
export type GlobalIdFilterInput = {
/** The value equal to. */
eq?: InputMaybe<Scalars['ID']>;
/** The value included in. */
oneOf?: InputMaybe<Array<Scalars['ID']>>;
};
/** Thumbnail formats for icon images. */
export enum IconThumbnailFormatEnum {
ORIGINAL = 'ORIGINAL',
WEBP = 'WEBP'
}
export type IntRangeInput = {
/** Value greater than or equal to. */
gte?: InputMaybe<Scalars['Int']>;
@ -3103,8 +3204,6 @@ export enum LanguageCodeEnum {
*
* PAYMENT_FLOW - new orders marked as paid will receive a
* `Payment` object, that will cover the `order.total`.
*
*
*/
export enum MarkAsPaidStrategyEnum {
TRANSACTION_FLOW = 'TRANSACTION_FLOW',
@ -3358,7 +3457,6 @@ export type OrderAddNoteInput = {
* `order.total`-`order.totalGrantedRefund`
* FULL - the funds that are authorized and charged fully cover the
* `order.total`-`order.totalGrantedRefund`
*
*/
export enum OrderAuthorizeStatusEnum {
NONE = 'NONE',
@ -3366,6 +3464,208 @@ export enum OrderAuthorizeStatusEnum {
FULL = 'FULL'
}
export type OrderBulkCreateDeliveryMethodInput = {
/** The ID of the warehouse. */
warehouseId?: InputMaybe<Scalars['ID']>;
/** The name of the warehouse. */
warehouseName?: InputMaybe<Scalars['String']>;
/** The ID of the shipping method. */
shippingMethodId?: InputMaybe<Scalars['ID']>;
/** The name of the shipping method. */
shippingMethodName?: InputMaybe<Scalars['String']>;
/** The price of the shipping. */
shippingPrice?: InputMaybe<TaxedMoneyInput>;
/** Tax rate of the shipping. */
shippingTaxRate?: InputMaybe<Scalars['PositiveDecimal']>;
/** The ID of the tax class. */
shippingTaxClassId?: InputMaybe<Scalars['ID']>;
/** The name of the tax class. */
shippingTaxClassName?: InputMaybe<Scalars['String']>;
/** Metadata of the tax class. */
shippingTaxClassMetadata?: InputMaybe<Array<MetadataInput>>;
/** Private metadata of the tax class. */
shippingTaxClassPrivateMetadata?: InputMaybe<Array<MetadataInput>>;
};
/** An enumeration. */
export enum OrderBulkCreateErrorCode {
GRAPHQL_ERROR = 'GRAPHQL_ERROR',
REQUIRED = 'REQUIRED',
INVALID = 'INVALID',
NOT_FOUND = 'NOT_FOUND',
UNIQUE = 'UNIQUE',
BULK_LIMIT = 'BULK_LIMIT',
TOO_MANY_IDENTIFIERS = 'TOO_MANY_IDENTIFIERS',
FUTURE_DATE = 'FUTURE_DATE',
INVALID_QUANTITY = 'INVALID_QUANTITY',
PRICE_ERROR = 'PRICE_ERROR',
NOTE_LENGTH = 'NOTE_LENGTH',
INSUFFICIENT_STOCK = 'INSUFFICIENT_STOCK',
NON_EXISTING_STOCK = 'NON_EXISTING_STOCK',
NO_RELATED_ORDER_LINE = 'NO_RELATED_ORDER_LINE',
NEGATIVE_INDEX = 'NEGATIVE_INDEX',
ORDER_LINE_FULFILLMENT_LINE_MISMATCH = 'ORDER_LINE_FULFILLMENT_LINE_MISMATCH',
METADATA_KEY_REQUIRED = 'METADATA_KEY_REQUIRED',
INCORRECT_CURRENCY = 'INCORRECT_CURRENCY'
}
export type OrderBulkCreateFulfillmentInput = {
/** Fulfillment's tracking code. */
trackingCode?: InputMaybe<Scalars['String']>;
/** List of items informing how to fulfill the order. */
lines?: InputMaybe<Array<OrderBulkCreateFulfillmentLineInput>>;
};
export type OrderBulkCreateFulfillmentLineInput = {
/** The ID of the product variant. */
variantId?: InputMaybe<Scalars['ID']>;
/** The SKU of the product variant. */
variantSku?: InputMaybe<Scalars['String']>;
/** The external ID of the product variant. */
variantExternalReference?: InputMaybe<Scalars['String']>;
/** The number of line items to be fulfilled from given warehouse. */
quantity: Scalars['Int'];
/** ID of the warehouse from which the item will be fulfilled. */
warehouse: Scalars['ID'];
/** 0-based index of order line, which the fulfillment line refers to. */
orderLineIndex: Scalars['Int'];
};
export type OrderBulkCreateInput = {
/** External ID of the order. */
externalReference?: InputMaybe<Scalars['String']>;
/** Slug of the channel associated with the order. */
channel: Scalars['String'];
/** The date, when the order was inserted to Saleor database. */
createdAt: Scalars['DateTime'];
/** Status of the order. */
status?: InputMaybe<OrderStatus>;
/** Customer associated with the order. */
user: OrderBulkCreateUserInput;
/** Tracking ID of the customer. */
trackingClientId?: InputMaybe<Scalars['String']>;
/** Billing address of the customer. */
billingAddress: AddressInput;
/** Shipping address of the customer. */
shippingAddress?: InputMaybe<AddressInput>;
/** Currency code. */
currency: Scalars['String'];
/** Metadata of the order. */
metadata?: InputMaybe<Array<MetadataInput>>;
/** Private metadata of the order. */
privateMetadata?: InputMaybe<Array<MetadataInput>>;
/** Note about customer. */
customerNote?: InputMaybe<Scalars['String']>;
/** Notes related to the order. */
notes?: InputMaybe<Array<OrderBulkCreateNoteInput>>;
/** Order language code. */
languageCode: LanguageCodeEnum;
/** Determines whether checkout prices should include taxes, when displayed in a storefront. */
displayGrossPrices?: InputMaybe<Scalars['Boolean']>;
/** Weight of the order in kg. */
weight?: InputMaybe<Scalars['WeightScalar']>;
/** URL of a view, where users should be redirected to see the order details. */
redirectUrl?: InputMaybe<Scalars['String']>;
/** List of order lines. */
lines: Array<OrderBulkCreateOrderLineInput>;
/** The delivery method selected for this order. */
deliveryMethod?: InputMaybe<OrderBulkCreateDeliveryMethodInput>;
/** List of gift card codes associated with the order. */
giftCards?: InputMaybe<Array<Scalars['String']>>;
/** Code of a voucher associated with the order. */
voucher?: InputMaybe<Scalars['String']>;
/** List of discounts. */
discounts?: InputMaybe<Array<OrderDiscountCommonInput>>;
/** Fulfillments of the order. */
fulfillments?: InputMaybe<Array<OrderBulkCreateFulfillmentInput>>;
/** Transactions related to the order. */
transactions?: InputMaybe<Array<TransactionCreateInput>>;
/** Invoices related to the order. */
invoices?: InputMaybe<Array<OrderBulkCreateInvoiceInput>>;
};
export type OrderBulkCreateInvoiceInput = {
/** The date, when the invoice was created. */
createdAt: Scalars['DateTime'];
/** Invoice number. */
number?: InputMaybe<Scalars['String']>;
/** URL of the invoice to download. */
url?: InputMaybe<Scalars['String']>;
/** Metadata of the invoice. */
metadata?: InputMaybe<Array<MetadataInput>>;
/** Private metadata of the invoice. */
privateMetadata?: InputMaybe<Array<MetadataInput>>;
};
export type OrderBulkCreateNoteInput = {
/** Note message. Max characters: 255. */
message: Scalars['String'];
/** The date associated with the message. */
date?: InputMaybe<Scalars['DateTime']>;
/** The user ID associated with the message. */
userId?: InputMaybe<Scalars['ID']>;
/** The user email associated with the message. */
userEmail?: InputMaybe<Scalars['ID']>;
/** The user external ID associated with the message. */
userExternalReference?: InputMaybe<Scalars['ID']>;
/** The app ID associated with the message. */
appId?: InputMaybe<Scalars['ID']>;
};
export type OrderBulkCreateOrderLineInput = {
/** The ID of the product variant. */
variantId?: InputMaybe<Scalars['ID']>;
/** The SKU of the product variant. */
variantSku?: InputMaybe<Scalars['String']>;
/** The external ID of the product variant. */
variantExternalReference?: InputMaybe<Scalars['String']>;
/** The name of the product variant. */
variantName?: InputMaybe<Scalars['String']>;
/** The name of the product. */
productName?: InputMaybe<Scalars['String']>;
/** Translation of the product variant name. */
translatedVariantName?: InputMaybe<Scalars['String']>;
/** Translation of the product name. */
translatedProductName?: InputMaybe<Scalars['String']>;
/** The date, when the order line was created. */
createdAt: Scalars['DateTime'];
/** Determines whether shipping of the order line items is required. */
isShippingRequired: Scalars['Boolean'];
/** Gift card flag. */
isGiftCard: Scalars['Boolean'];
/** Number of items in the order line */
quantity: Scalars['Int'];
/** Price of the order line. */
totalPrice: TaxedMoneyInput;
/** Price of the order line excluding applied discount. */
undiscountedTotalPrice: TaxedMoneyInput;
/** The ID of the warehouse, where the line will be allocated. */
warehouse: Scalars['ID'];
/** Metadata of the order line. */
metadata?: InputMaybe<Array<MetadataInput>>;
/** Private metadata of the order line. */
privateMetadata?: InputMaybe<Array<MetadataInput>>;
/** Tax rate of the order line. */
taxRate?: InputMaybe<Scalars['PositiveDecimal']>;
/** The ID of the tax class. */
taxClassId?: InputMaybe<Scalars['ID']>;
/** The name of the tax class. */
taxClassName?: InputMaybe<Scalars['String']>;
/** Metadata of the tax class. */
taxClassMetadata?: InputMaybe<Array<MetadataInput>>;
/** Private metadata of the tax class. */
taxClassPrivateMetadata?: InputMaybe<Array<MetadataInput>>;
};
export type OrderBulkCreateUserInput = {
/** Customer ID associated with the order. */
id?: InputMaybe<Scalars['ID']>;
/** Customer email associated with the order. */
email?: InputMaybe<Scalars['String']>;
/** Customer external ID associated with the order. */
externalReference?: InputMaybe<Scalars['String']>;
};
/**
* Determine the current charge status for the order.
*
@ -3385,7 +3685,6 @@ export enum OrderAuthorizeStatusEnum {
* `order.total`-`order.totalGrantedRefund`
* OVERCHARGED - the charged funds are bigger than the
* `order.total`-`order.totalGrantedRefund`
*
*/
export enum OrderChargeStatusEnum {
NONE = 'NONE',
@ -3492,7 +3791,7 @@ export enum OrderEventsEmailsEnum {
DIGITAL_LINKS = 'DIGITAL_LINKS'
}
/** The different order event types. */
/** The different order event types. */
export enum OrderEventsEnum {
DRAFT_CREATED = 'DRAFT_CREATED',
DRAFT_CREATED_FROM_REPLACE = 'DRAFT_CREATED_FROM_REPLACE',
@ -3525,10 +3824,10 @@ export enum OrderEventsEnum {
PAYMENT_FAILED = 'PAYMENT_FAILED',
TRANSACTION_EVENT = 'TRANSACTION_EVENT',
TRANSACTION_CHARGE_REQUESTED = 'TRANSACTION_CHARGE_REQUESTED',
/** This field will be removed in Saleor 3.14 (Preview Feature). Use `TRANSACTION_CHARGE_REQUESTED` instead. */
/** This field will be removed in Saleor 3.15 (Preview Feature). Use `TRANSACTION_CHARGE_REQUESTED` instead. */
TRANSACTION_CAPTURE_REQUESTED = 'TRANSACTION_CAPTURE_REQUESTED',
TRANSACTION_REFUND_REQUESTED = 'TRANSACTION_REFUND_REQUESTED',
/** This field will be removed in Saleor 3.14 (Preview Feature). Use `TRANSACTION_CANCEL_REQUESTED` instead. */
/** This field will be removed in Saleor 3.15 (Preview Feature). Use `TRANSACTION_CANCEL_REQUESTED` instead. */
TRANSACTION_VOID_REQUESTED = 'TRANSACTION_VOID_REQUESTED',
TRANSACTION_CANCEL_REQUESTED = 'TRANSACTION_CANCEL_REQUESTED',
TRANSACTION_MARK_AS_PAID_FAILED = 'TRANSACTION_MARK_AS_PAID_FAILED',
@ -3635,6 +3934,14 @@ export type OrderLineCreateInput = {
* Added in Saleor 3.6.
*/
forceNewLine?: InputMaybe<Scalars['Boolean']>;
/**
* Custom price of the item.When the line with the same variant will be provided multiple times, the last price will be used.
*
* Added in Saleor 3.14.
*
* Note: this API is currently in Feature Preview and can be subject to changes at later point.
*/
price?: InputMaybe<Scalars['PositiveDecimal']>;
};
export type OrderLineInput = {
@ -3646,7 +3953,8 @@ export type OrderLineInput = {
export enum OrderOriginEnum {
CHECKOUT = 'CHECKOUT',
DRAFT = 'DRAFT',
REISSUE = 'REISSUE'
REISSUE = 'REISSUE',
BULK_CREATE = 'BULK_CREATE'
}
export type OrderRefundFulfillmentLineInput = {
@ -3723,6 +4031,14 @@ export type OrderSettingsInput = {
* Note: this API is currently in Feature Preview and can be subject to changes at later point.
*/
expireOrdersAfter?: InputMaybe<Scalars['Minute']>;
/**
* The time in days after expired orders will be deleted.Allowed range is from 1 to 120.
*
* Added in Saleor 3.14.
*
* Note: this API is currently in Feature Preview and can be subject to changes at later point.
*/
deleteExpiredOrdersAfter?: InputMaybe<Scalars['Day']>;
/**
* Determine what strategy will be used to mark the order as paid. Based on the chosen option, the proper object will be created and attached to the order when it's manually marked as paid.
* `PAYMENT_FLOW` - [default option] creates the `Payment` object.
@ -4115,6 +4431,7 @@ export enum PermissionEnum {
MANAGE_GIFT_CARD = 'MANAGE_GIFT_CARD',
MANAGE_MENUS = 'MANAGE_MENUS',
MANAGE_ORDERS = 'MANAGE_ORDERS',
MANAGE_ORDERS_IMPORT = 'MANAGE_ORDERS_IMPORT',
MANAGE_PAGES = 'MANAGE_PAGES',
MANAGE_PAGE_TYPES_AND_ATTRIBUTES = 'MANAGE_PAGE_TYPES_AND_ATTRIBUTES',
HANDLE_PAYMENTS = 'HANDLE_PAYMENTS',
@ -5109,6 +5426,53 @@ export type ProductVariantStocksUpdateInput = {
remove?: InputMaybe<Array<Scalars['ID']>>;
};
export type ProductWhereInput = {
metadata?: InputMaybe<Array<MetadataFilter>>;
ids?: InputMaybe<Array<Scalars['ID']>>;
/** Filter by product name. */
name?: InputMaybe<StringFilterInput>;
/** Filter by product slug. */
slug?: InputMaybe<StringFilterInput>;
/** Filter by product type. */
productType?: InputMaybe<GlobalIdFilterInput>;
/** Filter by product category. */
category?: InputMaybe<GlobalIdFilterInput>;
/** Filter by collection. */
collection?: InputMaybe<GlobalIdFilterInput>;
/** Filter by availability for purchase. */
isAvailable?: InputMaybe<Scalars['Boolean']>;
/** Filter by public visibility. */
isPublished?: InputMaybe<Scalars['Boolean']>;
/** Filter by visibility on the channel. */
isVisibleInListing?: InputMaybe<Scalars['Boolean']>;
/** Filter by the publication date. */
publishedFrom?: InputMaybe<Scalars['DateTime']>;
/** Filter by the date of availability for purchase. */
availableFrom?: InputMaybe<Scalars['DateTime']>;
/** Filter by product with category assigned. */
hasCategory?: InputMaybe<Scalars['Boolean']>;
/** Filter by product variant price. */
price?: InputMaybe<DecimalFilterInput>;
/** Filter by the lowest variant price after discounts. */
minimalPrice?: InputMaybe<DecimalFilterInput>;
/** Filter by attributes associated with the product. */
attributes?: InputMaybe<Array<AttributeInput>>;
/** Filter by variants having specific stock status. */
stockAvailability?: InputMaybe<StockAvailability>;
/** Filter by stock of the product variant. */
stocks?: InputMaybe<ProductStockFilterInput>;
/** Filter on whether product is a gift card or not. */
giftCard?: InputMaybe<Scalars['Boolean']>;
/** Filter by product with preordered variants. */
hasPreorderedVariants?: InputMaybe<Scalars['Boolean']>;
/** Filter by when was the most recent update. */
updatedAt?: InputMaybe<DateTimeRangeInput>;
/** List of conditions that must be met. */
AND?: InputMaybe<Array<ProductWhereInput>>;
/** A list of conditions of which at least one must be met. */
OR?: InputMaybe<Array<ProductWhereInput>>;
};
export type PublishableChannelListingInput = {
/** ID of a channel. */
channelId: Scalars['ID'];
@ -5596,6 +5960,19 @@ export type StockUpdateInput = {
quantity: Scalars['Int'];
};
/**
* Determine how stocks should be updated, while processing an order.
*
* SKIP - stocks are not checked and not updated.
* UPDATE - only do update, if there is enough stock.
* FORCE - force update, if there is not enough stock.
*/
export enum StockUpdatePolicyEnum {
SKIP = 'SKIP',
UPDATE = 'UPDATE',
FORCE = 'FORCE'
}
/** Enum representing the type of a payment storage in a gateway. */
export enum StorePaymentMethodEnum {
/** On session storage type. The payment is stored only to be reused when the customer is present in the checkout flow. */
@ -5751,6 +6128,13 @@ export enum TaxExemptionManageErrorCode {
NOT_EDITABLE_ORDER = 'NOT_EDITABLE_ORDER'
}
export type TaxedMoneyInput = {
/** Gross value of an item. */
gross: Scalars['PositiveDecimal'];
/** Net value of an item. */
net: Scalars['PositiveDecimal'];
};
/** An enumeration. */
export enum ThumbnailFormatEnum {
ORIGINAL = 'ORIGINAL',
@ -5782,7 +6166,6 @@ export enum TimePeriodTypeEnum {
* VOID - Represents a void action. This field will be removed
* in Saleor 3.14 (Preview Feature). Use `CANCEL` instead.
* CANCEL - Represents a cancel action. Added in Saleor 3.12.
*
*/
export enum TransactionActionEnum {
CHARGE = 'CHARGE',
@ -5805,13 +6188,13 @@ export type TransactionCreateInput = {
/**
* Status of the transaction.
*
* DEPRECATED: this field will be removed in Saleor 3.14 (Preview Feature). The `status` is not needed. The amounts can be used to define the current status of transactions.
* DEPRECATED: this field will be removed in Saleor 3.15 (Preview Feature). The `status` is not needed. The amounts can be used to define the current status of transactions.
*/
status?: InputMaybe<Scalars['String']>;
/**
* Payment type used for this transaction.
*
* DEPRECATED: this field will be removed in Saleor 3.14 (Preview Feature). Use `name` and `message` instead.
* DEPRECATED: this field will be removed in Saleor 3.15 (Preview Feature). Use `name` and `message` instead.
*/
type?: InputMaybe<Scalars['String']>;
/**
@ -5829,7 +6212,7 @@ export type TransactionCreateInput = {
/**
* Reference of the transaction.
*
* DEPRECATED: this field will be removed in Saleor 3.14 (Preview Feature). Use `pspReference` instead.
* DEPRECATED: this field will be removed in Saleor 3.15 (Preview Feature). Use `pspReference` instead.
*/
reference?: InputMaybe<Scalars['String']>;
/**
@ -5849,7 +6232,7 @@ export type TransactionCreateInput = {
/**
* Amount voided by this transaction.
*
* DEPRECATED: this field will be removed in Saleor 3.14 (Preview Feature). Use `amountCanceled` instead.
* DEPRECATED: this field will be removed in Saleor 3.15 (Preview Feature). Use `amountCanceled` instead.
*/
amountVoided?: InputMaybe<MoneyInput>;
/**
@ -5874,13 +6257,13 @@ export type TransactionEventInput = {
/**
* Current status of the payment transaction.
*
* DEPRECATED: this field will be removed in Saleor 3.14 (Preview Feature). Status will be calculated by Saleor.
* DEPRECATED: this field will be removed in Saleor 3.15 (Preview Feature). Status will be calculated by Saleor.
*/
status?: InputMaybe<TransactionStatus>;
/**
* Reference of the transaction.
*
* DEPRECATED: this field will be removed in Saleor 3.14 (Preview Feature). Use `pspReference` instead.
* DEPRECATED: this field will be removed in Saleor 3.15 (Preview Feature). Use `pspReference` instead.
*/
reference?: InputMaybe<Scalars['String']>;
/**
@ -5892,7 +6275,7 @@ export type TransactionEventInput = {
/**
* Name of the transaction.
*
* DEPRECATED: this field will be removed in Saleor 3.14 (Preview Feature). Use `message` instead. `name` field will be added to `message`.
* DEPRECATED: this field will be removed in Saleor 3.15 (Preview Feature). Use `message` instead. `name` field will be added to `message`.
*/
name?: InputMaybe<Scalars['String']>;
/**
@ -5938,7 +6321,6 @@ export enum TransactionEventReportErrorCode {
* CANCEL_FAILURE - represents failure cancel.
* CANCEL_REQUEST - represents cancel request.
* INFO - represents info event.
*
*/
export enum TransactionEventTypeEnum {
AUTHORIZATION_SUCCESS = 'AUTHORIZATION_SUCCESS',
@ -5966,7 +6348,6 @@ export enum TransactionEventTypeEnum {
*
* AUTHORIZATION - the processed transaction should be only authorized
* CHARGE - the processed transaction should be charged.
*
*/
export enum TransactionFlowStrategyEnum {
AUTHORIZATION = 'AUTHORIZATION',
@ -6019,7 +6400,6 @@ export enum TransactionRequestActionErrorCode {
* SUCCESS - Represents a sucess action.
* FAILURE - Represents a failure action.
* PENDING - Represents a pending action.
*
*/
export enum TransactionStatus {
PENDING = 'PENDING',
@ -6041,13 +6421,13 @@ export type TransactionUpdateInput = {
/**
* Status of the transaction.
*
* DEPRECATED: this field will be removed in Saleor 3.14 (Preview Feature). The `status` is not needed. The amounts can be used to define the current status of transactions.
* DEPRECATED: this field will be removed in Saleor 3.15 (Preview Feature). The `status` is not needed. The amounts can be used to define the current status of transactions.
*/
status?: InputMaybe<Scalars['String']>;
/**
* Payment type used for this transaction.
*
* DEPRECATED: this field will be removed in Saleor 3.14 (Preview Feature). Use `name` and `message` instead.
* DEPRECATED: this field will be removed in Saleor 3.15 (Preview Feature). Use `name` and `message` instead.
*/
type?: InputMaybe<Scalars['String']>;
/**
@ -6065,7 +6445,7 @@ export type TransactionUpdateInput = {
/**
* Reference of the transaction.
*
* DEPRECATED: this field will be removed in Saleor 3.14 (Preview Feature). Use `pspReference` instead.
* DEPRECATED: this field will be removed in Saleor 3.15 (Preview Feature). Use `pspReference` instead.
*/
reference?: InputMaybe<Scalars['String']>;
/**
@ -6085,7 +6465,7 @@ export type TransactionUpdateInput = {
/**
* Amount voided by this transaction.
*
* DEPRECATED: this field will be removed in Saleor 3.14 (Preview Feature). Use `amountCanceled` instead.
* DEPRECATED: this field will be removed in Saleor 3.15 (Preview Feature). Use `amountCanceled` instead.
*/
amountVoided?: InputMaybe<MoneyInput>;
/**
@ -6646,6 +7026,14 @@ export enum WebhookEventTypeAsyncEnum {
* Added in Saleor 3.8.
*/
ORDER_METADATA_UPDATED = 'ORDER_METADATA_UPDATED',
/**
* Orders are imported.
*
* Added in Saleor 3.14.
*
* Note: this API is currently in Feature Preview and can be subject to changes at later point.
*/
ORDER_BULK_CREATED = 'ORDER_BULK_CREATED',
/** A draft order is created. */
DRAFT_ORDER_CREATED = 'DRAFT_ORDER_CREATED',
/** A draft order is updated. */
@ -6977,6 +7365,14 @@ export enum WebhookEventTypeEnum {
* Added in Saleor 3.8.
*/
ORDER_METADATA_UPDATED = 'ORDER_METADATA_UPDATED',
/**
* Orders are imported.
*
* Added in Saleor 3.14.
*
* Note: this API is currently in Feature Preview and can be subject to changes at later point.
*/
ORDER_BULK_CREATED = 'ORDER_BULK_CREATED',
/** A draft order is created. */
DRAFT_ORDER_CREATED = 'DRAFT_ORDER_CREATED',
/** A draft order is updated. */
@ -7353,6 +7749,7 @@ export enum WebhookSampleEventTypeEnum {
ORDER_EXPIRED = 'ORDER_EXPIRED',
ORDER_FULFILLED = 'ORDER_FULFILLED',
ORDER_METADATA_UPDATED = 'ORDER_METADATA_UPDATED',
ORDER_BULK_CREATED = 'ORDER_BULK_CREATED',
DRAFT_ORDER_CREATED = 'DRAFT_ORDER_CREATED',
DRAFT_ORDER_UPDATED = 'DRAFT_ORDER_UPDATED',
DRAFT_ORDER_DELETED = 'DRAFT_ORDER_DELETED',
@ -7498,14 +7895,14 @@ export type AppCreateMutationVariables = Exact<{
}>;
export type AppCreateMutation = { __typename: 'Mutation', appCreate: { __typename: 'AppCreate', authToken: string | null, app: { __typename: 'App', id: string, name: string | null, created: any | null, isActive: boolean | null, type: AppTypeEnum | null, homepageUrl: string | null, appUrl: string | null, manifestUrl: string | null, configurationUrl: string | null, supportUrl: string | null, version: string | null, accessToken: string | null, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, tokens: Array<{ __typename: 'AppToken', authToken: string | null, id: string, name: string | null }> | null, webhooks: Array<{ __typename: 'Webhook', id: string, name: string, isActive: boolean, app: { __typename: 'App', id: string, name: string | null } }> | null } | null, errors: Array<{ __typename: 'AppError', field: string | null, message: string | null, code: AppErrorCode, permissions: Array<PermissionEnum> | null }> } | null };
export type AppCreateMutation = { __typename: 'Mutation', appCreate: { __typename: 'AppCreate', authToken: string | null, app: { __typename: 'App', id: string, name: string | null, created: any | null, isActive: boolean | null, type: AppTypeEnum | null, homepageUrl: string | null, appUrl: string | null, manifestUrl: string | null, configurationUrl: string | null, supportUrl: string | null, version: string | null, accessToken: string | null, brand: { __typename: 'AppBrand', logo: { __typename: 'AppBrandLogo', default: string } } | null, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, tokens: Array<{ __typename: 'AppToken', authToken: string | null, id: string, name: string | null }> | null, webhooks: Array<{ __typename: 'Webhook', id: string, name: string, isActive: boolean, app: { __typename: 'App', id: string, name: string | null } }> | null } | null, errors: Array<{ __typename: 'AppError', field: string | null, message: string | null, code: AppErrorCode, permissions: Array<PermissionEnum> | null }> } | null };
export type AppDeleteMutationVariables = Exact<{
id: Scalars['ID'];
}>;
export type AppDeleteMutation = { __typename: 'Mutation', appDelete: { __typename: 'AppDelete', app: { __typename: 'App', id: string, name: string | null, created: any | null, isActive: boolean | null, type: AppTypeEnum | null, homepageUrl: string | null, appUrl: string | null, manifestUrl: string | null, configurationUrl: string | null, supportUrl: string | null, version: string | null, accessToken: string | null, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, tokens: Array<{ __typename: 'AppToken', authToken: string | null, id: string, name: string | null }> | null, webhooks: Array<{ __typename: 'Webhook', id: string, name: string, isActive: boolean, app: { __typename: 'App', id: string, name: string | null } }> | null } | null, errors: Array<{ __typename: 'AppError', field: string | null, message: string | null, code: AppErrorCode, permissions: Array<PermissionEnum> | null }> } | null };
export type AppDeleteMutation = { __typename: 'Mutation', appDelete: { __typename: 'AppDelete', app: { __typename: 'App', id: string, name: string | null, created: any | null, isActive: boolean | null, type: AppTypeEnum | null, homepageUrl: string | null, appUrl: string | null, manifestUrl: string | null, configurationUrl: string | null, supportUrl: string | null, version: string | null, accessToken: string | null, brand: { __typename: 'AppBrand', logo: { __typename: 'AppBrandLogo', default: string } } | null, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, tokens: Array<{ __typename: 'AppToken', authToken: string | null, id: string, name: string | null }> | null, webhooks: Array<{ __typename: 'Webhook', id: string, name: string, isActive: boolean, app: { __typename: 'App', id: string, name: string | null } }> | null } | null, errors: Array<{ __typename: 'AppError', field: string | null, message: string | null, code: AppErrorCode, permissions: Array<PermissionEnum> | null }> } | null };
export type AppDeleteFailedInstallationMutationVariables = Exact<{
id: Scalars['ID'];
@ -7519,7 +7916,7 @@ export type AppFetchMutationVariables = Exact<{
}>;
export type AppFetchMutation = { __typename: 'Mutation', appFetchManifest: { __typename: 'AppFetchManifest', manifest: { __typename: 'Manifest', identifier: string, version: string, about: string | null, name: string, appUrl: string | null, configurationUrl: string | null, tokenTargetUrl: string | null, dataPrivacy: string | null, dataPrivacyUrl: string | null, homepageUrl: string | null, supportUrl: string | null, permissions: Array<{ __typename: 'Permission', code: PermissionEnum, name: string }> | null } | null, errors: Array<{ __typename: 'AppError', field: string | null, message: string | null, code: AppErrorCode, permissions: Array<PermissionEnum> | null }> } | null };
export type AppFetchMutation = { __typename: 'Mutation', appFetchManifest: { __typename: 'AppFetchManifest', manifest: { __typename: 'Manifest', identifier: string, version: string, about: string | null, name: string, appUrl: string | null, configurationUrl: string | null, tokenTargetUrl: string | null, dataPrivacy: string | null, dataPrivacyUrl: string | null, homepageUrl: string | null, supportUrl: string | null, permissions: Array<{ __typename: 'Permission', code: PermissionEnum, name: string }> | null, brand: { __typename: 'AppManifestBrand', logo: { __typename: 'AppManifestBrandLogo', default: string } } | null } | null, errors: Array<{ __typename: 'AppError', field: string | null, message: string | null, code: AppErrorCode, permissions: Array<PermissionEnum> | null }> } | null };
export type AppInstallMutationVariables = Exact<{
input: AppInstallInput;
@ -7541,7 +7938,7 @@ export type AppUpdateMutationVariables = Exact<{
}>;
export type AppUpdateMutation = { __typename: 'Mutation', appUpdate: { __typename: 'AppUpdate', app: { __typename: 'App', id: string, name: string | null, created: any | null, isActive: boolean | null, type: AppTypeEnum | null, homepageUrl: string | null, appUrl: string | null, manifestUrl: string | null, configurationUrl: string | null, supportUrl: string | null, version: string | null, accessToken: string | null, permissions: Array<{ __typename: 'Permission', code: PermissionEnum, name: string }> | null, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, tokens: Array<{ __typename: 'AppToken', authToken: string | null, id: string, name: string | null }> | null, webhooks: Array<{ __typename: 'Webhook', id: string, name: string, isActive: boolean, app: { __typename: 'App', id: string, name: string | null } }> | null } | null, errors: Array<{ __typename: 'AppError', message: string | null, permissions: Array<PermissionEnum> | null, field: string | null, code: AppErrorCode }> } | null };
export type AppUpdateMutation = { __typename: 'Mutation', appUpdate: { __typename: 'AppUpdate', app: { __typename: 'App', id: string, name: string | null, created: any | null, isActive: boolean | null, type: AppTypeEnum | null, homepageUrl: string | null, appUrl: string | null, manifestUrl: string | null, configurationUrl: string | null, supportUrl: string | null, version: string | null, accessToken: string | null, permissions: Array<{ __typename: 'Permission', code: PermissionEnum, name: string }> | null, brand: { __typename: 'AppBrand', logo: { __typename: 'AppBrandLogo', default: string } } | null, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, tokens: Array<{ __typename: 'AppToken', authToken: string | null, id: string, name: string | null }> | null, webhooks: Array<{ __typename: 'Webhook', id: string, name: string, isActive: boolean, app: { __typename: 'App', id: string, name: string | null } }> | null } | null, errors: Array<{ __typename: 'AppError', message: string | null, permissions: Array<PermissionEnum> | null, field: string | null, code: AppErrorCode }> } | null };
export type AppTokenCreateMutationVariables = Exact<{
input: AppTokenInput;
@ -7581,19 +7978,19 @@ export type AppsListQueryVariables = Exact<{
}>;
export type AppsListQuery = { __typename: 'Query', apps: { __typename: 'AppCountableConnection', totalCount: number | null, pageInfo: { __typename: 'PageInfo', hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null, endCursor: string | null }, edges: Array<{ __typename: 'AppCountableEdge', node: { __typename: 'App', id: string, name: string | null, isActive: boolean | null, type: AppTypeEnum | null, appUrl: string | null, manifestUrl: string | null, version: string | null, permissions: Array<{ __typename: 'Permission', name: string, code: PermissionEnum }> | null } }> } | null };
export type AppsListQuery = { __typename: 'Query', apps: { __typename: 'AppCountableConnection', totalCount: number | null, pageInfo: { __typename: 'PageInfo', hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null, endCursor: string | null }, edges: Array<{ __typename: 'AppCountableEdge', node: { __typename: 'App', id: string, name: string | null, isActive: boolean | null, type: AppTypeEnum | null, appUrl: string | null, manifestUrl: string | null, version: string | null, brand: { __typename: 'AppBrand', logo: { __typename: 'AppBrandLogo', default: string } } | null, permissions: Array<{ __typename: 'Permission', name: string, code: PermissionEnum }> | null } }> } | null };
export type AppsInstallationsQueryVariables = Exact<{ [key: string]: never; }>;
export type AppsInstallationsQuery = { __typename: 'Query', appsInstallations: Array<{ __typename: 'AppInstallation', status: JobStatusEnum, message: string | null, appName: string, manifestUrl: string, id: string }> };
export type AppsInstallationsQuery = { __typename: 'Query', appsInstallations: Array<{ __typename: 'AppInstallation', status: JobStatusEnum, message: string | null, appName: string, manifestUrl: string, id: string, brand: { __typename: 'AppBrand', logo: { __typename: 'AppBrandLogo', default: string } } | null }> };
export type AppQueryVariables = Exact<{
id: Scalars['ID'];
}>;
export type AppQuery = { __typename: 'Query', app: { __typename: 'App', aboutApp: string | null, author: string | null, dataPrivacy: string | null, dataPrivacyUrl: string | null, id: string, name: string | null, created: any | null, isActive: boolean | null, type: AppTypeEnum | null, homepageUrl: string | null, appUrl: string | null, manifestUrl: string | null, configurationUrl: string | null, supportUrl: string | null, version: string | null, accessToken: string | null, permissions: Array<{ __typename: 'Permission', code: PermissionEnum, name: string }> | null, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, tokens: Array<{ __typename: 'AppToken', authToken: string | null, id: string, name: string | null }> | null, webhooks: Array<{ __typename: 'Webhook', id: string, name: string, isActive: boolean, app: { __typename: 'App', id: string, name: string | null } }> | null } | null };
export type AppQuery = { __typename: 'Query', app: { __typename: 'App', aboutApp: string | null, author: string | null, dataPrivacy: string | null, dataPrivacyUrl: string | null, id: string, name: string | null, created: any | null, isActive: boolean | null, type: AppTypeEnum | null, homepageUrl: string | null, appUrl: string | null, manifestUrl: string | null, configurationUrl: string | null, supportUrl: string | null, version: string | null, accessToken: string | null, permissions: Array<{ __typename: 'Permission', code: PermissionEnum, name: string }> | null, brand: { __typename: 'AppBrand', logo: { __typename: 'AppBrandLogo', default: string } } | null, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, tokens: Array<{ __typename: 'AppToken', authToken: string | null, id: string, name: string | null }> | null, webhooks: Array<{ __typename: 'Webhook', id: string, name: string, isActive: boolean, app: { __typename: 'App', id: string, name: string | null } }> | null } | null };
export type ExtensionListQueryVariables = Exact<{
filter: AppExtensionFilterInput;
@ -8325,13 +8722,13 @@ export type FileUploadMutation = { __typename: 'Mutation', fileUpload: { __typen
export type AddressFragment = { __typename: 'Address', city: string, cityArea: string, companyName: string, countryArea: string, firstName: string, id: string, lastName: string, phone: string | null, postalCode: string, streetAddress1: string, streetAddress2: string, country: { __typename: 'CountryDisplay', code: string, country: string } };
export type AppManifestFragment = { __typename: 'Manifest', identifier: string, version: string, about: string | null, name: string, appUrl: string | null, configurationUrl: string | null, tokenTargetUrl: string | null, dataPrivacy: string | null, dataPrivacyUrl: string | null, homepageUrl: string | null, supportUrl: string | null, permissions: Array<{ __typename: 'Permission', code: PermissionEnum, name: string }> | null };
export type AppManifestFragment = { __typename: 'Manifest', identifier: string, version: string, about: string | null, name: string, appUrl: string | null, configurationUrl: string | null, tokenTargetUrl: string | null, dataPrivacy: string | null, dataPrivacyUrl: string | null, homepageUrl: string | null, supportUrl: string | null, permissions: Array<{ __typename: 'Permission', code: PermissionEnum, name: string }> | null, brand: { __typename: 'AppManifestBrand', logo: { __typename: 'AppManifestBrandLogo', default: string } } | null };
export type AppFragment = { __typename: 'App', id: string, name: string | null, created: any | null, isActive: boolean | null, type: AppTypeEnum | null, homepageUrl: string | null, appUrl: string | null, manifestUrl: string | null, configurationUrl: string | null, supportUrl: string | null, version: string | null, accessToken: string | null, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, tokens: Array<{ __typename: 'AppToken', authToken: string | null, id: string, name: string | null }> | null, webhooks: Array<{ __typename: 'Webhook', id: string, name: string, isActive: boolean, app: { __typename: 'App', id: string, name: string | null } }> | null };
export type AppFragment = { __typename: 'App', id: string, name: string | null, created: any | null, isActive: boolean | null, type: AppTypeEnum | null, homepageUrl: string | null, appUrl: string | null, manifestUrl: string | null, configurationUrl: string | null, supportUrl: string | null, version: string | null, accessToken: string | null, brand: { __typename: 'AppBrand', logo: { __typename: 'AppBrandLogo', default: string } } | null, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, tokens: Array<{ __typename: 'AppToken', authToken: string | null, id: string, name: string | null }> | null, webhooks: Array<{ __typename: 'Webhook', id: string, name: string, isActive: boolean, app: { __typename: 'App', id: string, name: string | null } }> | null };
export type AppInstallationFragment = { __typename: 'AppInstallation', status: JobStatusEnum, message: string | null, appName: string, manifestUrl: string, id: string };
export type AppInstallationFragment = { __typename: 'AppInstallation', status: JobStatusEnum, message: string | null, appName: string, manifestUrl: string, id: string, brand: { __typename: 'AppBrand', logo: { __typename: 'AppBrandLogo', default: string } } | null };
export type AppListItemFragment = { __typename: 'App', id: string, name: string | null, isActive: boolean | null, type: AppTypeEnum | null, appUrl: string | null, manifestUrl: string | null, version: string | null, permissions: Array<{ __typename: 'Permission', name: string, code: PermissionEnum }> | null };
export type AppListItemFragment = { __typename: 'App', id: string, name: string | null, isActive: boolean | null, type: AppTypeEnum | null, appUrl: string | null, manifestUrl: string | null, version: string | null, brand: { __typename: 'AppBrand', logo: { __typename: 'AppBrandLogo', default: string } } | null, permissions: Array<{ __typename: 'Permission', name: string, code: PermissionEnum }> | null };
export type AppPermissionFragment = { __typename: 'Permission', name: string, code: PermissionEnum };