Fix minor bugs in plugin details view
This commit is contained in:
parent
c4d70dde70
commit
48e9fe1366
13 changed files with 244 additions and 150 deletions
|
@ -4,10 +4,7 @@ import Switch from "@material-ui/core/Switch";
|
|||
import React from "react";
|
||||
|
||||
const useStyles = makeStyles(
|
||||
theme => ({
|
||||
label: {
|
||||
marginLeft: theme.spacing(3.5)
|
||||
},
|
||||
() => ({
|
||||
labelText: {
|
||||
fontSize: 14
|
||||
}
|
||||
|
@ -51,7 +48,7 @@ export const ControlledSwitch: React.FC<ControlledSwitchProps> = props => {
|
|||
/>
|
||||
}
|
||||
label={
|
||||
<div className={classes.label}>
|
||||
<div>
|
||||
{uncheckedLabel ? (
|
||||
checked ? (
|
||||
label
|
||||
|
|
|
@ -127,3 +127,10 @@ export const exportErrorFragment = gql`
|
|||
field
|
||||
}
|
||||
`;
|
||||
|
||||
export const pluginErrorFragment = gql`
|
||||
fragment PluginErrorFragment on PluginError {
|
||||
code
|
||||
field
|
||||
}
|
||||
`;
|
||||
|
|
15
src/fragments/types/PluginErrorFragment.ts
Normal file
15
src/fragments/types/PluginErrorFragment.ts
Normal file
|
@ -0,0 +1,15 @@
|
|||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
import { PluginErrorCode } from "./../../types/globalTypes";
|
||||
|
||||
// ====================================================
|
||||
// GraphQL fragment: PluginErrorFragment
|
||||
// ====================================================
|
||||
|
||||
export interface PluginErrorFragment {
|
||||
__typename: "PluginError";
|
||||
code: PluginErrorCode;
|
||||
field: string | null;
|
||||
}
|
|
@ -6,7 +6,10 @@ import CardTitle from "@saleor/components/CardTitle";
|
|||
import ControlledCheckbox from "@saleor/components/ControlledCheckbox";
|
||||
import FormSpacer from "@saleor/components/FormSpacer";
|
||||
import Hr from "@saleor/components/Hr";
|
||||
import { PluginErrorFragment } from "@saleor/fragments/types/PluginErrorFragment";
|
||||
import { commonMessages } from "@saleor/intl";
|
||||
import { PluginErrorCode } from "@saleor/types/globalTypes";
|
||||
import getPluginErrorMessage from "@saleor/utils/errors/plugins";
|
||||
import React from "react";
|
||||
import { FormattedMessage, useIntl } from "react-intl";
|
||||
|
||||
|
@ -15,6 +18,7 @@ import { FormData } from "../PluginsDetailsPage";
|
|||
interface PluginInfoProps {
|
||||
data: FormData;
|
||||
description: string;
|
||||
errors: PluginErrorFragment[];
|
||||
name: string;
|
||||
onChange: (event: React.ChangeEvent<any>) => void;
|
||||
}
|
||||
|
@ -35,11 +39,17 @@ const useStyles = makeStyles(
|
|||
const PluginInfo: React.FC<PluginInfoProps> = ({
|
||||
data,
|
||||
description,
|
||||
errors,
|
||||
name,
|
||||
onChange
|
||||
}) => {
|
||||
const classes = useStyles({});
|
||||
const intl = useIntl();
|
||||
|
||||
const misconfiguredError = errors.find(
|
||||
err => err.code === PluginErrorCode.PLUGIN_MISCONFIGURED
|
||||
);
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<CardTitle
|
||||
|
@ -80,6 +90,11 @@ const PluginInfo: React.FC<PluginInfoProps> = ({
|
|||
checked={data.active}
|
||||
onChange={onChange}
|
||||
/>
|
||||
{misconfiguredError && (
|
||||
<Typography color="error">
|
||||
{getPluginErrorMessage(misconfiguredError, intl)}
|
||||
</Typography>
|
||||
)}
|
||||
</CardContent>
|
||||
</Card>
|
||||
);
|
||||
|
|
|
@ -2,8 +2,11 @@ import Card from "@material-ui/core/Card";
|
|||
import CardContent from "@material-ui/core/CardContent";
|
||||
import makeStyles from "@material-ui/core/styles/makeStyles";
|
||||
import TextField from "@material-ui/core/TextField";
|
||||
import Tooltip from "@material-ui/core/Tooltip";
|
||||
import Typography from "@material-ui/core/Typography";
|
||||
import InfoIcon from "@material-ui/icons/Info";
|
||||
import CardTitle from "@saleor/components/CardTitle";
|
||||
import ControlledCheckbox from "@saleor/components/ControlledCheckbox";
|
||||
import ControlledSwitch from "@saleor/components/ControlledSwitch";
|
||||
import { Plugin_plugin_configuration } from "@saleor/plugins/types/Plugin";
|
||||
import { UserError } from "@saleor/types";
|
||||
import { ConfigurationTypeFieldEnum } from "@saleor/types/globalTypes";
|
||||
|
@ -32,7 +35,9 @@ const useStyles = makeStyles(
|
|||
item: {
|
||||
"&:not(:last-child)": {
|
||||
marginBottom: theme.spacing(3)
|
||||
}
|
||||
},
|
||||
alignItems: "center",
|
||||
display: "flex"
|
||||
},
|
||||
itemLabel: {
|
||||
fontWeight: 500
|
||||
|
@ -71,17 +76,30 @@ const PluginSettings: React.FC<PluginSettingsProps> = ({
|
|||
return (
|
||||
<div className={classes.item} key={field.name}>
|
||||
{fieldData.type === ConfigurationTypeFieldEnum.BOOLEAN ? (
|
||||
<ControlledCheckbox
|
||||
name={field.name}
|
||||
label={fieldData.label}
|
||||
checked={
|
||||
typeof field.value !== "boolean"
|
||||
? field.value === "true"
|
||||
: field.value
|
||||
}
|
||||
onChange={onChange}
|
||||
disabled={disabled}
|
||||
/>
|
||||
<>
|
||||
<ControlledSwitch
|
||||
name={field.name}
|
||||
label={fieldData.label}
|
||||
checked={
|
||||
typeof field.value !== "boolean"
|
||||
? field.value === "true"
|
||||
: field.value
|
||||
}
|
||||
onChange={onChange}
|
||||
disabled={disabled}
|
||||
/>
|
||||
{fieldData.helpText && (
|
||||
<Tooltip
|
||||
title={
|
||||
<Typography variant="body2">
|
||||
{fieldData.helpText}
|
||||
</Typography>
|
||||
}
|
||||
>
|
||||
<InfoIcon />
|
||||
</Tooltip>
|
||||
)}
|
||||
</>
|
||||
) : (
|
||||
<TextField
|
||||
disabled={disabled}
|
||||
|
|
|
@ -9,11 +9,11 @@ import Grid from "@saleor/components/Grid";
|
|||
import Hr from "@saleor/components/Hr";
|
||||
import PageHeader from "@saleor/components/PageHeader";
|
||||
import SaveButtonBar from "@saleor/components/SaveButtonBar";
|
||||
import { PluginErrorFragment } from "@saleor/fragments/types/PluginErrorFragment";
|
||||
import { ChangeEvent } from "@saleor/hooks/useForm";
|
||||
import { sectionNames } from "@saleor/intl";
|
||||
import { maybe } from "@saleor/misc";
|
||||
import { getStringOrPlaceholder } from "@saleor/misc";
|
||||
import { isSecretField } from "@saleor/plugins/utils";
|
||||
import { UserError } from "@saleor/types";
|
||||
import { ConfigurationItemInput } from "@saleor/types/globalTypes";
|
||||
import React from "react";
|
||||
import { useIntl } from "react-intl";
|
||||
|
@ -30,7 +30,7 @@ export interface FormData {
|
|||
|
||||
export interface PluginsDetailsPageProps {
|
||||
disabled: boolean;
|
||||
errors: UserError[];
|
||||
errors: PluginErrorFragment[];
|
||||
plugin: Plugin_plugin;
|
||||
saveButtonBarState: ConfirmButtonTransitionState;
|
||||
onBack: () => void;
|
||||
|
@ -65,15 +65,13 @@ const PluginsDetailsPage: React.FC<PluginsDetailsPageProps> = props => {
|
|||
const classes = useStyles(props);
|
||||
const intl = useIntl();
|
||||
const initialForm: FormData = {
|
||||
active: maybe(() => plugin.active, false),
|
||||
configuration: maybe(() =>
|
||||
plugin.configuration
|
||||
.filter(field => !isSecretField(plugin.configuration, field.name))
|
||||
.map(field => ({
|
||||
...field,
|
||||
value: field.value || ""
|
||||
}))
|
||||
)
|
||||
active: plugin?.active || false,
|
||||
configuration: plugin?.configuration
|
||||
?.filter(field => !isSecretField(plugin?.configuration || [], field.name))
|
||||
.map(field => ({
|
||||
...field,
|
||||
value: field.value || ""
|
||||
}))
|
||||
};
|
||||
|
||||
return (
|
||||
|
@ -108,7 +106,7 @@ const PluginsDetailsPage: React.FC<PluginsDetailsPageProps> = props => {
|
|||
description: "header"
|
||||
},
|
||||
{
|
||||
pluginName: maybe(() => plugin.name, "...")
|
||||
pluginName: getStringOrPlaceholder(plugin?.name)
|
||||
}
|
||||
)}
|
||||
/>
|
||||
|
@ -129,8 +127,9 @@ const PluginsDetailsPage: React.FC<PluginsDetailsPageProps> = props => {
|
|||
</div>
|
||||
<PluginInfo
|
||||
data={data}
|
||||
description={maybe(() => plugin.description, "")}
|
||||
name={maybe(() => plugin.name, "")}
|
||||
description={plugin?.description || ""}
|
||||
errors={errors}
|
||||
name={plugin?.name || ""}
|
||||
onChange={onChange}
|
||||
/>
|
||||
{data.configuration && (
|
||||
|
@ -143,25 +142,17 @@ const PluginsDetailsPage: React.FC<PluginsDetailsPageProps> = props => {
|
|||
description: "section header"
|
||||
})}
|
||||
</Typography>
|
||||
<Typography>
|
||||
{intl.formatMessage({
|
||||
defaultMessage:
|
||||
"This adress will be used to generate invoices and calculate shipping rates. Email adress you provide here will be used as a contact adress for your customers."
|
||||
})}
|
||||
</Typography>
|
||||
</div>
|
||||
<div>
|
||||
<PluginSettings
|
||||
data={data}
|
||||
fields={maybe(() => plugin.configuration, [])}
|
||||
fields={plugin?.configuration || []}
|
||||
errors={errors}
|
||||
disabled={disabled}
|
||||
onChange={onChange}
|
||||
/>
|
||||
{maybe(() =>
|
||||
plugin.configuration.some(field =>
|
||||
isSecretField(plugin.configuration, field.name)
|
||||
)
|
||||
{plugin?.configuration.some(field =>
|
||||
isSecretField(plugin.configuration, field.name)
|
||||
) && (
|
||||
<>
|
||||
<CardSpacer />
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { pluginErrorFragment } from "@saleor/fragments/errors";
|
||||
import { pluginsDetailsFragment } from "@saleor/fragments/plugins";
|
||||
import gql from "graphql-tag";
|
||||
|
||||
|
@ -6,11 +7,11 @@ import { PluginUpdate, PluginUpdateVariables } from "./types/PluginUpdate";
|
|||
|
||||
const pluginUpdate = gql`
|
||||
${pluginsDetailsFragment}
|
||||
${pluginErrorFragment}
|
||||
mutation PluginUpdate($id: ID!, $input: PluginUpdateInput!) {
|
||||
pluginUpdate(id: $id, input: $input) {
|
||||
errors {
|
||||
field
|
||||
message
|
||||
errors: pluginsErrors {
|
||||
...PluginErrorFragment
|
||||
}
|
||||
plugin {
|
||||
...PluginsDetailsFragment
|
||||
|
|
|
@ -2,16 +2,16 @@
|
|||
/* eslint-disable */
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
import { PluginUpdateInput, ConfigurationTypeFieldEnum } from "./../../types/globalTypes";
|
||||
import { PluginUpdateInput, PluginErrorCode, ConfigurationTypeFieldEnum } from "./../../types/globalTypes";
|
||||
|
||||
// ====================================================
|
||||
// GraphQL mutation operation: PluginUpdate
|
||||
// ====================================================
|
||||
|
||||
export interface PluginUpdate_pluginUpdate_errors {
|
||||
__typename: "Error";
|
||||
__typename: "PluginError";
|
||||
code: PluginErrorCode;
|
||||
field: string | null;
|
||||
message: string | null;
|
||||
}
|
||||
|
||||
export interface PluginUpdate_pluginUpdate_plugin_configuration {
|
||||
|
|
|
@ -9,7 +9,6 @@ import createDialogActionHandlers from "@saleor/utils/handlers/dialogActionHandl
|
|||
import React from "react";
|
||||
import { FormattedMessage, useIntl } from "react-intl";
|
||||
|
||||
import { maybe } from "../../misc";
|
||||
import PluginsDetailsPage from "../components/PluginsDetailsPage";
|
||||
import PluginSecretFieldDialog from "../components/PluginSecretFieldDialog";
|
||||
import { TypedPluginUpdate } from "../mutations";
|
||||
|
@ -73,10 +72,7 @@ export const PluginsDetails: React.FC<PluginsDetailsProps> = ({
|
|||
{pluginDetails => (
|
||||
<TypedPluginUpdate onCompleted={handleUpdate}>
|
||||
{(pluginUpdate, pluginUpdateOpts) => {
|
||||
const formErrors = maybe(
|
||||
() => pluginUpdateOpts.data.pluginUpdate.errors,
|
||||
[]
|
||||
);
|
||||
const formErrors = pluginUpdateOpts.data?.pluginUpdate.errors || [];
|
||||
|
||||
const handleFieldUpdate = (value: string) =>
|
||||
pluginUpdate({
|
||||
|
@ -95,16 +91,14 @@ export const PluginsDetails: React.FC<PluginsDetailsProps> = ({
|
|||
|
||||
return (
|
||||
<>
|
||||
<WindowTitle
|
||||
title={maybe(() => pluginDetails.data.plugin.name)}
|
||||
/>
|
||||
<WindowTitle title={pluginDetails.data?.plugin?.name} />
|
||||
<PluginsDetailsPage
|
||||
disabled={pluginDetails.loading}
|
||||
errors={formErrors}
|
||||
saveButtonBarState={
|
||||
!params.action ? pluginUpdateOpts.status : "default"
|
||||
}
|
||||
plugin={maybe(() => pluginDetails.data.plugin)}
|
||||
plugin={pluginDetails.data?.plugin}
|
||||
onBack={() => navigate(pluginListUrl())}
|
||||
onClear={id =>
|
||||
openModal("clear", {
|
||||
|
@ -131,7 +125,7 @@ export const PluginsDetails: React.FC<PluginsDetailsProps> = ({
|
|||
})
|
||||
}
|
||||
/>
|
||||
{maybe(() => pluginDetails.data.plugin.configuration) && (
|
||||
{pluginDetails.data?.plugin?.configuration && (
|
||||
<>
|
||||
<ActionDialog
|
||||
confirmButtonState={
|
||||
|
@ -153,10 +147,8 @@ export const PluginsDetails: React.FC<PluginsDetailsProps> = ({
|
|||
confirmButtonState={
|
||||
!!params.action ? pluginUpdateOpts.status : "default"
|
||||
}
|
||||
field={maybe(() =>
|
||||
pluginDetails.data.plugin.configuration.find(
|
||||
field => field.name === params.id
|
||||
)
|
||||
field={pluginDetails.data?.plugin?.configuration.find(
|
||||
field => field.name === params.id
|
||||
)}
|
||||
onClose={closeModal}
|
||||
onConfirm={formData => handleFieldUpdate(formData.value)}
|
||||
|
|
|
@ -111209,11 +111209,6 @@ exports[`Storyshots Views / Plugins / Plugin details default 1`] = `
|
|||
>
|
||||
Plugin Settings
|
||||
</div>
|
||||
<div
|
||||
class="MuiTypography-root-id MuiTypography-body1-id"
|
||||
>
|
||||
This adress will be used to generate invoices and calculate shipping rates. Email adress you provide here will be used as a contact adress for your customers.
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
|
@ -111335,48 +111330,54 @@ exports[`Storyshots Views / Plugins / Plugin details default 1`] = `
|
|||
class="MuiFormControlLabel-root-id"
|
||||
>
|
||||
<span
|
||||
aria-disabled="false"
|
||||
class="MuiButtonBase-root-id MuiIconButton-root-id PrivateSwitchBase-root-id MuiCheckbox-root-id MuiCheckbox-colorPrimary-id PrivateSwitchBase-checked-id MuiCheckbox-checked-id MuiIconButton-colorPrimary-id"
|
||||
class="MuiSwitch-root-id"
|
||||
>
|
||||
<span
|
||||
class="MuiIconButton-label-id"
|
||||
aria-disabled="false"
|
||||
class="MuiButtonBase-root-id MuiIconButton-root-id PrivateSwitchBase-root-id MuiSwitch-switchBase-id MuiSwitch-colorPrimary-id PrivateSwitchBase-checked-id MuiSwitch-checked-id"
|
||||
>
|
||||
<input
|
||||
checked=""
|
||||
class="PrivateSwitchBase-input-id"
|
||||
data-indeterminate="false"
|
||||
name="Use sandbox"
|
||||
type="checkbox"
|
||||
/>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class="MuiSvgIcon-root-id"
|
||||
focusable="false"
|
||||
role="presentation"
|
||||
viewBox="0 0 24 24"
|
||||
<span
|
||||
class="MuiIconButton-label-id"
|
||||
>
|
||||
<rect
|
||||
fill="currentColor"
|
||||
height="14"
|
||||
width="14"
|
||||
x="5"
|
||||
y="5"
|
||||
<input
|
||||
checked=""
|
||||
class="PrivateSwitchBase-input-id MuiSwitch-input-id"
|
||||
name="Use sandbox"
|
||||
type="checkbox"
|
||||
/>
|
||||
<path
|
||||
clip-rule="evenodd"
|
||||
d="M 16.7527 9.33783 L 10.86618 15.7595 L 8 12.32006 L 8.76822 11.67988 L 10.90204 14.24046 L 16.0155 8.66211 L 16.7527 9.33783 Z"
|
||||
fill="white"
|
||||
fill-rule="evenodd"
|
||||
<span
|
||||
class="MuiSwitch-thumb-id"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
<span
|
||||
class="MuiSwitch-track-id"
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
class="MuiTypography-root-id MuiFormControlLabel-label-id MuiTypography-body1-id"
|
||||
>
|
||||
Use sandbox
|
||||
<div>
|
||||
<span
|
||||
class="ControlledSwitch-labelText-id"
|
||||
>
|
||||
Use sandbox
|
||||
</span>
|
||||
<div />
|
||||
</div>
|
||||
</span>
|
||||
</label>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class="MuiSvgIcon-root-id"
|
||||
focusable="false"
|
||||
role="presentation"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -111660,6 +111661,11 @@ exports[`Storyshots Views / Plugins / Plugin details form errors 1`] = `
|
|||
Set plugin as Active
|
||||
</span>
|
||||
</label>
|
||||
<div
|
||||
class="MuiTypography-root-id MuiTypography-body1-id MuiTypography-colorError-id"
|
||||
>
|
||||
Plugin is misconfigured and cannot be activated
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr
|
||||
|
@ -111671,11 +111677,6 @@ exports[`Storyshots Views / Plugins / Plugin details form errors 1`] = `
|
|||
>
|
||||
Plugin Settings
|
||||
</div>
|
||||
<div
|
||||
class="MuiTypography-root-id MuiTypography-body1-id"
|
||||
>
|
||||
This adress will be used to generate invoices and calculate shipping rates. Email adress you provide here will be used as a contact adress for your customers.
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
|
@ -111797,48 +111798,54 @@ exports[`Storyshots Views / Plugins / Plugin details form errors 1`] = `
|
|||
class="MuiFormControlLabel-root-id"
|
||||
>
|
||||
<span
|
||||
aria-disabled="false"
|
||||
class="MuiButtonBase-root-id MuiIconButton-root-id PrivateSwitchBase-root-id MuiCheckbox-root-id MuiCheckbox-colorPrimary-id PrivateSwitchBase-checked-id MuiCheckbox-checked-id MuiIconButton-colorPrimary-id"
|
||||
class="MuiSwitch-root-id"
|
||||
>
|
||||
<span
|
||||
class="MuiIconButton-label-id"
|
||||
aria-disabled="false"
|
||||
class="MuiButtonBase-root-id MuiIconButton-root-id PrivateSwitchBase-root-id MuiSwitch-switchBase-id MuiSwitch-colorPrimary-id PrivateSwitchBase-checked-id MuiSwitch-checked-id"
|
||||
>
|
||||
<input
|
||||
checked=""
|
||||
class="PrivateSwitchBase-input-id"
|
||||
data-indeterminate="false"
|
||||
name="Use sandbox"
|
||||
type="checkbox"
|
||||
/>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class="MuiSvgIcon-root-id"
|
||||
focusable="false"
|
||||
role="presentation"
|
||||
viewBox="0 0 24 24"
|
||||
<span
|
||||
class="MuiIconButton-label-id"
|
||||
>
|
||||
<rect
|
||||
fill="currentColor"
|
||||
height="14"
|
||||
width="14"
|
||||
x="5"
|
||||
y="5"
|
||||
<input
|
||||
checked=""
|
||||
class="PrivateSwitchBase-input-id MuiSwitch-input-id"
|
||||
name="Use sandbox"
|
||||
type="checkbox"
|
||||
/>
|
||||
<path
|
||||
clip-rule="evenodd"
|
||||
d="M 16.7527 9.33783 L 10.86618 15.7595 L 8 12.32006 L 8.76822 11.67988 L 10.90204 14.24046 L 16.0155 8.66211 L 16.7527 9.33783 Z"
|
||||
fill="white"
|
||||
fill-rule="evenodd"
|
||||
<span
|
||||
class="MuiSwitch-thumb-id"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
<span
|
||||
class="MuiSwitch-track-id"
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
class="MuiTypography-root-id MuiFormControlLabel-label-id MuiTypography-body1-id"
|
||||
>
|
||||
Use sandbox
|
||||
<div>
|
||||
<span
|
||||
class="ControlledSwitch-labelText-id"
|
||||
>
|
||||
Use sandbox
|
||||
</span>
|
||||
<div />
|
||||
</div>
|
||||
</span>
|
||||
</label>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class="MuiSvgIcon-root-id"
|
||||
focusable="false"
|
||||
role="presentation"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -114712,9 +114719,7 @@ exports[`Storyshots Views / Product types / Product type details default 1`] = `
|
|||
<span
|
||||
class="MuiTypography-root-id MuiFormControlLabel-label-id MuiTypography-body1-id"
|
||||
>
|
||||
<div
|
||||
class="ControlledSwitch-label-id"
|
||||
>
|
||||
<div>
|
||||
<span
|
||||
class="ControlledSwitch-labelText-id"
|
||||
>
|
||||
|
@ -115469,9 +115474,7 @@ exports[`Storyshots Views / Product types / Product type details form errors 1`]
|
|||
<span
|
||||
class="MuiTypography-root-id MuiFormControlLabel-label-id MuiTypography-body1-id"
|
||||
>
|
||||
<div
|
||||
class="ControlledSwitch-label-id"
|
||||
>
|
||||
<div>
|
||||
<span
|
||||
class="ControlledSwitch-labelText-id"
|
||||
>
|
||||
|
@ -116013,9 +116016,7 @@ exports[`Storyshots Views / Product types / Product type details loading 1`] = `
|
|||
<span
|
||||
class="MuiTypography-root-id MuiFormControlLabel-label-id MuiFormControlLabel-disabled-id MuiTypography-body1-id"
|
||||
>
|
||||
<div
|
||||
class="ControlledSwitch-label-id"
|
||||
>
|
||||
<div>
|
||||
<span
|
||||
class="ControlledSwitch-labelText-id"
|
||||
>
|
||||
|
@ -116396,9 +116397,7 @@ exports[`Storyshots Views / Product types / Product type details no attributes 1
|
|||
<span
|
||||
class="MuiTypography-root-id MuiFormControlLabel-label-id MuiTypography-body1-id"
|
||||
>
|
||||
<div
|
||||
class="ControlledSwitch-label-id"
|
||||
>
|
||||
<div>
|
||||
<span
|
||||
class="ControlledSwitch-labelText-id"
|
||||
>
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { PluginErrorCode } from "@saleor/types/globalTypes";
|
||||
import { storiesOf } from "@storybook/react";
|
||||
import React from "react";
|
||||
|
||||
|
@ -7,7 +8,6 @@ import PluginsDetailsPage, {
|
|||
} from "../../../plugins/components/PluginsDetailsPage";
|
||||
import { plugin } from "../../../plugins/fixtures";
|
||||
import Decorator from "../../Decorator";
|
||||
import { formError } from "../../misc";
|
||||
|
||||
const props: PluginsDetailsPageProps = {
|
||||
disabled: false,
|
||||
|
@ -29,11 +29,20 @@ storiesOf("Views / Plugins / Plugin details", module)
|
|||
.add("form errors", () => (
|
||||
<PluginsDetailsPage
|
||||
{...props}
|
||||
errors={([
|
||||
"active",
|
||||
"Username or account",
|
||||
"Password or license"
|
||||
] as Array<keyof FormData>).map(formError)}
|
||||
errors={[
|
||||
...(["active", "Username or account", "Password or license"] as Array<
|
||||
keyof FormData
|
||||
>).map(field => ({
|
||||
__typename: "PluginError" as "PluginError",
|
||||
code: PluginErrorCode.INVALID,
|
||||
field
|
||||
})),
|
||||
{
|
||||
__typename: "PluginError" as "PluginError",
|
||||
code: PluginErrorCode.PLUGIN_MISCONFIGURED,
|
||||
field: null
|
||||
}
|
||||
]}
|
||||
/>
|
||||
))
|
||||
.add("not configurable", () => (
|
||||
|
|
|
@ -665,6 +665,15 @@ export enum PermissionGroupSortField {
|
|||
NAME = "NAME",
|
||||
}
|
||||
|
||||
export enum PluginErrorCode {
|
||||
GRAPHQL_ERROR = "GRAPHQL_ERROR",
|
||||
INVALID = "INVALID",
|
||||
NOT_FOUND = "NOT_FOUND",
|
||||
PLUGIN_MISCONFIGURED = "PLUGIN_MISCONFIGURED",
|
||||
REQUIRED = "REQUIRED",
|
||||
UNIQUE = "UNIQUE",
|
||||
}
|
||||
|
||||
export enum PluginSortField {
|
||||
IS_ACTIVE = "IS_ACTIVE",
|
||||
NAME = "NAME",
|
||||
|
|
41
src/utils/errors/plugins.ts
Normal file
41
src/utils/errors/plugins.ts
Normal file
|
@ -0,0 +1,41 @@
|
|||
import { PluginErrorFragment } from "@saleor/fragments/types/PluginErrorFragment";
|
||||
import { commonMessages } from "@saleor/intl";
|
||||
import { PluginErrorCode } from "@saleor/types/globalTypes";
|
||||
import { defineMessages, IntlShape } from "react-intl";
|
||||
|
||||
import commonErrorMessages from "./common";
|
||||
|
||||
const messages = defineMessages({
|
||||
misconfigured: {
|
||||
defaultMessage: "Plugin is misconfigured and cannot be activated"
|
||||
},
|
||||
unique: {
|
||||
defaultMessage: "This field needs to be unique"
|
||||
}
|
||||
});
|
||||
|
||||
function getPluginErrorMessage(
|
||||
err: PluginErrorFragment,
|
||||
intl: IntlShape
|
||||
): string {
|
||||
if (err) {
|
||||
switch (err.code) {
|
||||
case PluginErrorCode.PLUGIN_MISCONFIGURED:
|
||||
return intl.formatMessage(messages.misconfigured);
|
||||
case PluginErrorCode.GRAPHQL_ERROR:
|
||||
return intl.formatMessage(commonErrorMessages.graphqlError);
|
||||
case PluginErrorCode.INVALID:
|
||||
return intl.formatMessage(commonErrorMessages.invalid);
|
||||
case PluginErrorCode.REQUIRED:
|
||||
return intl.formatMessage(commonMessages.requiredField);
|
||||
case PluginErrorCode.UNIQUE:
|
||||
return intl.formatMessage(messages.unique);
|
||||
default:
|
||||
return intl.formatMessage(commonErrorMessages.unknownError);
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export default getPluginErrorMessage;
|
Loading…
Reference in a new issue