Improve configuration instructions (#322)
* Add helper texts * Add instruction components * Add changeset * Fix new tab opening * Update and move id generation to the single location * Remove unused code * Apply suggestions from code review Co-authored-by: Dawid <tarasiukdawid@gmail.com> --------- Co-authored-by: Dawid <tarasiukdawid@gmail.com>
This commit is contained in:
parent
14ac6144c0
commit
9d625fc405
13 changed files with 232 additions and 13 deletions
5
.changeset/cold-bugs-remember.md
Normal file
5
.changeset/cold-bugs-remember.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
"saleor-app-emails-and-messages": patch
|
||||
---
|
||||
|
||||
Improve instructions for the app configuration
|
10
apps/emails-and-messages/src/lib/generate-random-id.ts
Normal file
10
apps/emails-and-messages/src/lib/generate-random-id.ts
Normal file
|
@ -0,0 +1,10 @@
|
|||
/**
|
||||
* Generates a random id containing current time and random string.
|
||||
*/
|
||||
export const generateRandomId = () => {
|
||||
const date = new Date();
|
||||
const offsetInMinutes = date.getTimezoneOffset();
|
||||
const randomDate = date.setMinutes(date.getMinutes() + offsetInMinutes).valueOf();
|
||||
const randomString = (Math.random() + 1).toString(36).substring(7);
|
||||
return `${randomDate}${randomString}`;
|
||||
};
|
|
@ -6,6 +6,7 @@ import { AppColumnsLayout } from "../../ui/app-columns-layout";
|
|||
import { trpcClient } from "../../trpc/trpc-client";
|
||||
import SideMenu from "./side-menu";
|
||||
import { LoadingIndicator } from "../../ui/loading-indicator";
|
||||
import { Instructions } from "./instructions";
|
||||
|
||||
const useStyles = makeStyles((theme) => {
|
||||
return {
|
||||
|
@ -142,6 +143,7 @@ export const ChannelsConfigurationTab = () => {
|
|||
</>
|
||||
)}
|
||||
</div>
|
||||
<Instructions />
|
||||
</AppColumnsLayout>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
import { Paper, Typography } from "@material-ui/core";
|
||||
import { makeStyles } from "@saleor/macaw-ui";
|
||||
|
||||
const useStyles = makeStyles((theme) => {
|
||||
return {
|
||||
instructionsContainer: {
|
||||
padding: 15,
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
export const Instructions = () => {
|
||||
const styles = useStyles();
|
||||
|
||||
return (
|
||||
<Paper elevation={0} className={styles.instructionsContainer}>
|
||||
<Typography paragraph variant="h4">
|
||||
Welcome to Emails and Messages App!
|
||||
</Typography>
|
||||
<Typography paragraph>
|
||||
The application will allow you to send emails and messages to your customers using different
|
||||
services.
|
||||
</Typography>
|
||||
|
||||
<Typography paragraph variant="h4">
|
||||
How to configure the app
|
||||
</Typography>
|
||||
<Typography paragraph>
|
||||
Start by creating a new configuration for provider of your choice. You can create multiple
|
||||
configurations and then assign them to channels. Navigate to the relevant tab to configure the provider.
|
||||
</Typography>
|
||||
</Paper>
|
||||
);
|
||||
};
|
|
@ -1,8 +1,7 @@
|
|||
import { messageEventTypes } from "../../event-handlers/message-event-types";
|
||||
import { MjmlConfig as MjmlConfigurationRoot, MjmlConfiguration } from "./mjml-config";
|
||||
import { defaultMjmlTemplates, defaultMjmlSubjectTemplates } from "../default-templates";
|
||||
|
||||
export const generateMjmlConfigurationId = () => Date.now().toString();
|
||||
import { generateRandomId } from "../../../lib/generate-random-id";
|
||||
|
||||
export const getDefaultEventsConfiguration = (): MjmlConfiguration["events"] =>
|
||||
messageEventTypes.map((eventType) => ({
|
||||
|
@ -77,7 +76,7 @@ const createConfiguration =
|
|||
// for creating a new configurations, the ID has to be generated
|
||||
const newConfiguration = {
|
||||
...mjmlConfiguration,
|
||||
id: generateMjmlConfigurationId(),
|
||||
id: generateRandomId(),
|
||||
events: getDefaultEventsConfiguration(),
|
||||
};
|
||||
mjmlConfigNormalized.configurations.push(newConfiguration);
|
||||
|
|
|
@ -136,7 +136,9 @@ export const MjmlConfigurationForm = (props: Props) => {
|
|||
value={value}
|
||||
onChange={onChange}
|
||||
error={!!error}
|
||||
helperText={error?.message}
|
||||
helperText={
|
||||
error?.message || "Name of the configuration, for example 'Production' or 'Test'"
|
||||
}
|
||||
{...CommonFieldProps}
|
||||
/>
|
||||
)}
|
||||
|
@ -182,7 +184,7 @@ export const MjmlConfigurationForm = (props: Props) => {
|
|||
<TextField
|
||||
label="Sender name"
|
||||
error={!!error}
|
||||
helperText={error?.message}
|
||||
helperText={error?.message || "Name which will be presented as author of the email"}
|
||||
value={value}
|
||||
onChange={onChange}
|
||||
{...CommonFieldProps}
|
||||
|
@ -198,7 +200,7 @@ export const MjmlConfigurationForm = (props: Props) => {
|
|||
<TextField
|
||||
label="Sender email"
|
||||
value={value}
|
||||
helperText={error?.message}
|
||||
helperText={error?.message || "Email which will be presented as author of the email"}
|
||||
error={!!error}
|
||||
onChange={onChange}
|
||||
{...CommonFieldProps}
|
||||
|
@ -221,7 +223,10 @@ export const MjmlConfigurationForm = (props: Props) => {
|
|||
label="SMTP server host"
|
||||
value={value}
|
||||
onChange={onChange}
|
||||
helperText={error?.message}
|
||||
helperText={
|
||||
error?.message ||
|
||||
"Address of the SMTP server, without the protocol. For example 'smtp.example.com'"
|
||||
}
|
||||
error={!!error}
|
||||
{...CommonFieldProps}
|
||||
/>
|
||||
|
|
|
@ -13,6 +13,7 @@ import { MjmlConfiguration } from "../mjml-config";
|
|||
import { LoadingIndicator } from "../../../ui/loading-indicator";
|
||||
import { Add } from "@material-ui/icons";
|
||||
import { useQueryClient } from "@tanstack/react-query";
|
||||
import { MjmlInstructions } from "./mjml-instructions";
|
||||
|
||||
const useStyles = makeStyles((theme) => {
|
||||
return {
|
||||
|
@ -165,6 +166,7 @@ export const MjmlConfigurationTab = ({ configurationId }: MjmlConfigurationTabPr
|
|||
</>
|
||||
)}
|
||||
</div>
|
||||
<MjmlInstructions />
|
||||
</AppColumnsLayout>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
import { Link, Paper, Typography } from "@material-ui/core";
|
||||
import { actions, useAppBridge } from "@saleor/app-sdk/app-bridge";
|
||||
import { makeStyles } from "@saleor/macaw-ui";
|
||||
|
||||
const useStyles = makeStyles((theme) => {
|
||||
return {
|
||||
instructionsContainer: {
|
||||
padding: 15,
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
export const MjmlInstructions = () => {
|
||||
const styles = useStyles();
|
||||
|
||||
const { appBridge } = useAppBridge();
|
||||
|
||||
return (
|
||||
<Paper elevation={0} className={styles.instructionsContainer}>
|
||||
<Typography paragraph variant="h4">
|
||||
MJML Provider
|
||||
</Typography>
|
||||
<Typography paragraph>
|
||||
You can use this provider to send emails using MJML as a template language. The emails are
|
||||
then sent using the SMTP.
|
||||
</Typography>
|
||||
|
||||
<Typography paragraph>
|
||||
<Link
|
||||
href="https://mjml.io/"
|
||||
onClick={(event) => {
|
||||
event.preventDefault();
|
||||
appBridge?.dispatch(
|
||||
actions.Redirect({
|
||||
to: "https://mjml.io/",
|
||||
newContext: true,
|
||||
})
|
||||
);
|
||||
}}
|
||||
>
|
||||
Visit the MJML Homepage
|
||||
</Link>
|
||||
</Typography>
|
||||
<Typography paragraph variant="h4">
|
||||
How to configure
|
||||
</Typography>
|
||||
<Typography paragraph>
|
||||
Create a new configuration and fill in the required fields. After the configuration is
|
||||
saved, you will be able to modify the email templates.
|
||||
</Typography>
|
||||
</Paper>
|
||||
);
|
||||
};
|
|
@ -1,11 +1,10 @@
|
|||
import { generateRandomId } from "../../../lib/generate-random-id";
|
||||
import { messageEventTypes } from "../../event-handlers/message-event-types";
|
||||
import {
|
||||
SendgridConfig as SendgridConfigurationRoot,
|
||||
SendgridConfiguration,
|
||||
} from "./sendgrid-config";
|
||||
|
||||
export const generateSendgridConfigurationId = () => Date.now().toString();
|
||||
|
||||
export const getDefaultEventsConfiguration = (): SendgridConfiguration["events"] =>
|
||||
messageEventTypes.map((eventType) => ({
|
||||
active: true,
|
||||
|
@ -75,7 +74,7 @@ const createConfiguration =
|
|||
// for creating a new configurations, the ID has to be generated
|
||||
const newConfiguration = {
|
||||
...sendgridConfiguration,
|
||||
id: generateSendgridConfigurationId(),
|
||||
id: generateRandomId(),
|
||||
events: getDefaultEventsConfiguration(),
|
||||
};
|
||||
sendgridConfigNormalized.configurations.push(newConfiguration);
|
||||
|
|
|
@ -177,7 +177,9 @@ export const SendgridConfigurationForm = (props: Props) => {
|
|||
value={value}
|
||||
onChange={onChange}
|
||||
error={!!error}
|
||||
helperText={error?.message}
|
||||
helperText={
|
||||
error?.message || "Name of the configuration, for example 'Production' or 'Test'"
|
||||
}
|
||||
{...CommonFieldProps}
|
||||
/>
|
||||
)}
|
||||
|
@ -224,7 +226,10 @@ export const SendgridConfigurationForm = (props: Props) => {
|
|||
label="Sendgrid API key"
|
||||
value={value}
|
||||
onChange={onChange}
|
||||
helperText={error?.message}
|
||||
helperText={
|
||||
error?.message ||
|
||||
"The API key can be generated at Sendgrid dashboard, in the Settings / API Keys section"
|
||||
}
|
||||
error={!!error}
|
||||
{...CommonFieldProps}
|
||||
/>
|
||||
|
|
|
@ -13,6 +13,7 @@ import { Add } from "@material-ui/icons";
|
|||
import { useQueryClient } from "@tanstack/react-query";
|
||||
import { sendgridUrls } from "../../urls";
|
||||
import { SendgridTemplatesCard } from "./sendgrid-templates-card";
|
||||
import { SendgridInstructions } from "./sendgrid-instructions";
|
||||
|
||||
const useStyles = makeStyles((theme) => {
|
||||
return {
|
||||
|
@ -170,6 +171,7 @@ export const SendgridConfigurationTab = ({ configurationId }: SendgridConfigurat
|
|||
</>
|
||||
)}
|
||||
</div>
|
||||
<SendgridInstructions />
|
||||
</AppColumnsLayout>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -0,0 +1,103 @@
|
|||
import { Link, Paper, Typography } from "@material-ui/core";
|
||||
import { actions, useAppBridge } from "@saleor/app-sdk/app-bridge";
|
||||
import { makeStyles } from "@saleor/macaw-ui";
|
||||
|
||||
const useStyles = makeStyles((theme) => {
|
||||
return {
|
||||
instructionsContainer: {
|
||||
padding: 15,
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
export const SendgridInstructions = () => {
|
||||
const styles = useStyles();
|
||||
|
||||
const { appBridge } = useAppBridge();
|
||||
|
||||
return (
|
||||
<Paper elevation={0} className={styles.instructionsContainer}>
|
||||
<Typography paragraph variant="h4">
|
||||
Sendgrid Provider
|
||||
</Typography>
|
||||
<Typography paragraph>
|
||||
The integration uses dynamic email templates to send the messages to your customers.
|
||||
</Typography>
|
||||
|
||||
<Typography paragraph>
|
||||
<Link
|
||||
href="https://sendgrid.com/"
|
||||
onClick={(event) => {
|
||||
event.preventDefault();
|
||||
appBridge?.dispatch(
|
||||
actions.Redirect({
|
||||
to: "https://sendgrid.com/",
|
||||
newContext: true,
|
||||
})
|
||||
);
|
||||
}}
|
||||
>
|
||||
Visit the Sendgrid Homepage
|
||||
</Link>
|
||||
</Typography>
|
||||
<Typography paragraph variant="h4">
|
||||
How to configure
|
||||
</Typography>
|
||||
|
||||
<Typography paragraph>
|
||||
Before configuring the app, make sure you have a Sendgrid account set up. To proceed you
|
||||
will need:
|
||||
<br />
|
||||
<Link
|
||||
href="https://app.sendgrid.com/settings/api_keys"
|
||||
onClick={(event) => {
|
||||
event.preventDefault();
|
||||
appBridge?.dispatch(
|
||||
actions.Redirect({
|
||||
to: "https://app.sendgrid.com/settings/api_keys",
|
||||
newContext: true,
|
||||
})
|
||||
);
|
||||
}}
|
||||
>
|
||||
API key which can be generated in the Sendgrid dashboard
|
||||
</Link>
|
||||
<br />
|
||||
<Link
|
||||
href="https://app.sendgrid.com/settings/sender_auth"
|
||||
onClick={(event) => {
|
||||
event.preventDefault();
|
||||
appBridge?.dispatch(
|
||||
actions.Redirect({
|
||||
to: "https://app.sendgrid.com/settings/sender_auth",
|
||||
newContext: true,
|
||||
})
|
||||
);
|
||||
}}
|
||||
>
|
||||
Verified sender account
|
||||
</Link>
|
||||
<br />
|
||||
<Link
|
||||
href="https://mc.sendgrid.com/dynamic-templates"
|
||||
onClick={(event) => {
|
||||
event.preventDefault();
|
||||
appBridge?.dispatch(
|
||||
actions.Redirect({
|
||||
to: "https://mc.sendgrid.com/dynamic-templates",
|
||||
newContext: true,
|
||||
})
|
||||
);
|
||||
}}
|
||||
>
|
||||
Created dynamic email templates
|
||||
</Link>
|
||||
</Typography>
|
||||
|
||||
<Typography paragraph>
|
||||
Create a new configuration and fill in the required fields. After the configuration is
|
||||
saved, you will be able to assign the email template to each of the events.
|
||||
</Typography>
|
||||
</Paper>
|
||||
);
|
||||
};
|
|
@ -4,7 +4,7 @@ import { PropsWithChildren } from "react";
|
|||
const useStyles = makeStyles((theme) => ({
|
||||
root: {
|
||||
display: "grid",
|
||||
gridTemplateColumns: "280px auto",
|
||||
gridTemplateColumns: "280px auto 400px",
|
||||
alignItems: "start",
|
||||
gap: theme.spacing(3),
|
||||
padding: "20px 0",
|
||||
|
|
Loading…
Reference in a new issue