docs: updates to admin customization docs (#7493)

* updated admin docs

* re-add navigation and parameters sections

* update injection zones

* update cli scripts docs

* added list of injection zones

* add details about widget props

* restructure admin injection zones
This commit is contained in:
Shahed Nasser
2024-05-29 13:50:19 +03:00
committed by GitHub
parent 72b57e2ae4
commit 130de74d6d
15 changed files with 1647 additions and 2917 deletions
File diff suppressed because one or more lines are too long
@@ -4,19 +4,12 @@ export const metadata = {
# {metadata.title}
<Note type="soon">
Admin customizations are coming soon.
</Note>
In the next chapters, you'll learn more about possible admin customizations.
You can customize the admin dashboard by:
- Adding new sections to existing pages using Widgets.
- Adding new pages using UI Routes.
- Adding new pages to the Settings section of the admin dashboard using Setting Pages.
---
@@ -1,152 +0,0 @@
export const metadata = {
title: `${pageNumber} Admin Setting Pages`,
}
# {metadata.title}
<Note type="soon">
Admin customizations are coming soon.
</Note>
In this chapter, youll learn how to create a setting page in the admin dashboard.
## What is a Setting Page?
A setting page is a React component that adds a new page to the settings panel of the admin dashboard.
For example, you may create a setting page to manage configurations related to your custom functionalities.
---
## How to Create a Setting Page?
A setting page is created in a file named `page.tsx` under the `src/admin/settings` directory. The files default export must be the React component, and it must also export a configuration object.
For example, you can create the file `src/admin/settings/custom/page.tsx` with the following content:
```tsx title="src/admin/settings/custom/page.tsx"
import type { SettingConfig } from "@medusajs/admin"
import { ChatBubbleLeftRight } from "@medusajs/icons"
const CustomSettingPage = () => {
return (
<div>
<h1>Custom Setting Page</h1>
</div>
)
}
export const config: SettingConfig = {
card: {
label: "Custom",
description: "Manage your custom settings",
// optional
icon: ChatBubbleLeftRight,
},
}
export default CustomSettingPage
```
The new setting pages path is the files path relative to `src/admin/settings` and prefixed with `/a/settings`. So, the above UI route is a new page added at the path `localhost:7001/a/settings/custom`.
The setting page is shown on the Settings panel as a card. In the exported configuration object, you configure the cards label, description, and optionally icon. In this example, you use an icon from [Medusas UI Icons package](https://docs.medusajs.com/ui/icons/overview).
### Test the Setting Page
To test the setting page, start the Medusa application:
```bash npm2yarn
npm run dev
```
Then, open the Settings page of the admin dashboard. Youll find a new card that links to your setting page.
---
## Using UI Components
Similar to other admin customizations, its highly recommended that you use the [Medusa UI package](https://docs.medusajs.com/ui) to match your pages design with the rest of the Medusa Admin.
For example, you can rewrite the above UI route to the following:
```tsx title="src/admin/settings/custom/page.tsx"
import type { SettingConfig } from "@medusajs/admin"
import { ChatBubbleLeftRight } from "@medusajs/icons"
import { Container, Heading } from "@medusajs/ui"
const CustomSettingPage = () => {
return (
<Container>
<Heading level="h1">Custom Setting Page</Heading>
</Container>
)
}
export const config: SettingConfig = {
card: {
label: "Custom",
description: "Manage your custom settings",
icon: ChatBubbleLeftRight,
},
}
export default CustomSettingPage
```
---
## Setting Page Props
A setting page receives a `notify` prop, which is an object having the following properties:
- `success`: a function that shows a success toast message.
- `error`: a function that shows an error toast message.
- `warn`: a function that shows a warning toast message.
- `info`: a function that shows an info toast message.
Each of these functions accepts two parameters: the messages title and the messages content.
For example:
```tsx title="src/admin/settings/custom/page.tsx" highlights={[["11", "success", "Show a success toast message on the click of a button."]]}
import type { RouteProps, SettingConfig } from "@medusajs/admin"
import { ChatBubbleLeftRight } from "@medusajs/icons"
import { Container, Heading, Button } from "@medusajs/ui"
const CustomSettingPage = ({ notify }: RouteProps) => {
return (
<Container>
<Heading level="h1">Custom Setting Page</Heading>
<Button
onClick={() =>
notify.success("Success!", "You clicked the button!")
}
className="mt-3"
>
Click me
</Button>
</Container>
)
}
export const config: SettingConfig = {
card: {
label: "Custom",
description: "Manage your custom settings",
icon: ChatBubbleLeftRight,
},
}
export default CustomSettingPage
```
If you click the button on your setting page, a toast message will show with the title and message you specified.
<Note title="Tip">
Admin UI Routes support [Tailwind CSS](https://tailwindcss.com/) out of the box.
</Note>
@@ -4,22 +4,8 @@ export const metadata = {
# {metadata.title}
<Note type="soon">
Admin customizations are coming soon.
</Note>
In this chapter, you'll find some tips for your admin development.
## Sending Requests to API Routes
To send requests to your API routes in your admin customizations, its highly recommended to use the Medusa React or Medusa JS Client packages.
Check out their references for more details on available hooks or methods and how to use them.
---
## Routing Functionalities
To navigate or link to other pages, or use other routing functionalities, use the [react-router-dom](https://reactrouter.com/en/main) package:
@@ -30,40 +16,34 @@ npm install react-router-dom
For example:
```tsx title="src/admin/widgets/product-widget.tsx" highlights={[["18", "Link", "Add a link to another page."]]}
import type {
WidgetConfig,
ProductDetailsWidgetProps,
} from "@medusajs/admin"
import { Container, Heading, Button } from "@medusajs/ui"
export const highlights = [
["9", "Link", "Add a link to another page"],
["9", '"/orders', "Add the path without the `/app` prefix."]
]
```tsx title="src/admin/widgets/product-widget.tsx" highlights={highlights}
import { defineWidgetConfig } from "@medusajs/admin-shared"
import { Container } from "@medusajs/ui"
import { Link } from "react-router-dom"
// The widget
const ProductWidget = ({
product,
}: ProductDetailsWidgetProps) => {
const ProductWidget = () => {
return (
<Container>
<Heading level="h2">
Product Widget {product.title}
</Heading>
<Button className="mt-3" variant="transparent">
<Link to={"/a/orders"}>View Orders</Link>
</Button>
<Link to={"/orders"}>View Orders</Link>
</Container>
)
}
// The widget's configurations
export const config: WidgetConfig = {
export const config = defineWidgetConfig({
zone: "product.details.after",
}
})
export default ProductWidget
```
This adds a widget in a product's details page with a link to the Orders page.
This adds a widget in a product's details page with a link to the Orders page. The link's path must be without the `/app` prefix.
<Note title="Learn more">
@@ -4,17 +4,11 @@ export const metadata = {
# {metadata.title}
<Note type="soon">
Admin customizations are coming soon.
</Note>
In this chapter, youll learn how to create a UI route in the admin dashboard.
## What is a UI Route?
A UI route is a React Component that adds a custom new page to your admin dashboard. The UI Route can be shown in the sidebar or added as a nested page.
A UI route is a React Component that adds a new page to your admin dashboard. The UI Route can be shown in the sidebar or added as a nested page.
For example, you may add a new page to manage product reviews.
@@ -34,7 +28,7 @@ const CustomPage = () => {
export default CustomPage
```
The new pages path is the files path relative to `src/admin/routes` and prefixed with `/a`. So, the above UI route is a new page added at the path `localhost:7001/a/custom`.
The new pages path is the files path relative to `src/admin/routes`. So, the above UI route is a new page added at the path `localhost:9000/app/custom`.
### Test the UI Route
@@ -44,7 +38,43 @@ To test the UI route, start the Medusa application:
npm run dev
```
Then, after logging into the admin dashboard, open the page `localhost:7001/a/custom` to see your custom page.
Then, after logging into the admin dashboard, open the page `localhost:9000/app/custom` to see your custom page.
---
## Show UI Route in the Sidebar
A UI route file can export a configuration object that indicates a new item must be added in the sidebar linking to the new UI route.
For example:
export const highlights = [
["14", "label", "The label of the UI route's sidebar item."],
["15", "icon", "The icon of the UI route's sidebar item."]
]
```tsx title="src/admin/routes/custom/page.tsx" highlights={[["21"], ["22"], ["23"], ["24"], ["25"], ["26"]]}
import { defineRouteConfig } from "@medusajs/admin-shared";
import { ChatBubbleLeftRight } from "@medusajs/icons"
const CustomPage = () => {
return <div>This is my custom route</div>
}
export const config = defineRouteConfig({
label: "Custom Route",
icon: ChatBubbleLeftRight,
})
export default CustomPage
```
The configuration object is creaetd by the `defineRouteConfig` function imported from `@medusajs/admin-shared`. It accepts the following properties:
- `label`: the new sidebar items label.
- `icon`: an optional React component that acts as an icon in the sidebar.
The above example adds a new sidebar item with the label `Custom Route` and an icon from the [Medusa UI Icons package](!ui!/icons/overview).
---
@@ -55,104 +85,50 @@ Similar to Widgets, its highly recommended that you use the [Medusa UI packag
For example, you can rewrite the above UI route to the following:
```tsx title="src/admin/routes/custom/page.tsx"
import { defineRouteConfig } from "@medusajs/admin-shared"
import { ChatBubbleLeftRight } from "@medusajs/icons"
import { Container } from "@medusajs/ui"
const CustomPage = () => {
return <Container>This is my custom route</Container>
}
export const config = defineRouteConfig({
label: "Custom Route",
icon: ChatBubbleLeftRight,
})
export default CustomPage
```
---
## UI Route Props
## Create Settings Page
A UI Route receives a `notify` prop, which is an object having the following properties:
- `success`: a function that shows a success toast message.
- `error`: a function that shows an error toast message.
- `warn`: a function that shows a warning toast message.
- `info`: a function that shows an info toast message.
Each of these functions accepts two parameters: the messages title and the messages content.
To create a page under the settings section of the admin dashboard, create the UI route file under the path `src/admin/routes/settings`.
For example:
```tsx title="src/admin/routes/custom/page.tsx" highlights={[["10", "success", "Show a success toast message on the click of a button."]]}
import { RouteProps } from "@medusajs/admin"
import { Container, Text, Button } from "@medusajs/ui"
```tsx title="src/admin/routes/settings/custom/page.tsx"
import { defineRouteConfig } from "@medusajs/admin-shared"
import { Container, Heading } from "@medusajs/ui"
const CustomPage = ({ notify }: RouteProps) => {
const CustomSettingPage = () => {
return (
<Container>
<Text>This is my custom route</Text>
<Button
onClick={() =>
notify.success("Success!", "You clicked the button!")
}
className="mt-3"
>
Click me
</Button>
<Heading level="h1">Custom Setting Page</Heading>
</Container>
)
}
export default CustomPage
export const config = defineRouteConfig({
label: "Custom",
})
export default CustomSettingPage;
```
<Note title="Tip">
Admin UI Routes support [Tailwind CSS](https://tailwindcss.com/) out of the box.
</Note>
---
## Show UI Route in the Sidebar
A UI route file can export a configuration object that indicates a new item must be added in the sidebar linking to the new UI route.
The configuration object has the property `link`, which is an object having the following properties:
- `label`: the new sidebar items label.
- `icon`: an optional React component that acts as an icon in the sidebar. If not provided, a default icon is used.
For example:
```tsx title="src/admin/routes/custom/page.tsx" highlights={[["21"], ["22"], ["23"], ["24"], ["25"], ["26"]]}
import { RouteConfig, RouteProps } from "@medusajs/admin"
import { Container, Text, Button } from "@medusajs/ui"
import { ChatBubbleLeftRight } from "@medusajs/icons"
const CustomPage = ({ notify }: RouteProps) => {
return (
<Container>
<Text>This is my custom route</Text>
<Button
onClick={() =>
notify.success("Success!", "You clicked the button!")
}
className="mt-3"
>
Click me
</Button>
</Container>
)
}
export const config: RouteConfig = {
link: {
label: "Custom Route",
icon: ChatBubbleLeftRight,
},
}
export default CustomPage
```
This adds a new sidebar item with the label `Custom Route` and an icon from the [Medusa UI Icons package](https://docs.medusajs.com/ui/icons/overview).
This adds a page under the path `/app/settings/custom`. An item is also added to the settings sidebar with the label `Custom`.
---
@@ -179,4 +155,6 @@ const CustomPage = () => {
}
export default CustomPage
```
```
If you run the Medusa application and go to `localhost:9000/app/custom/123`, you'll see `123` printed in the page.
@@ -6,12 +6,6 @@ export const metadata = {
# {metadata.title}
<Note type="soon">
Admin customizations are coming soon.
</Note>
In this chapter, youll learn more about widgets and how to use them.
## What is an Admin Widget?
@@ -28,8 +22,13 @@ A widget is created in a file under the `src/admin/widgets` directory. The file
For example, create the file `src/admin/widgets/product-widget.tsx` with the following content:
```tsx title="src/admin/widgets/product-widget.tsx" highlights={[["4", "ProductWidget", "The React component of the product widget."], ["14", "", "The zone to inject the widget to."]]}
import type { WidgetConfig } from "@medusajs/admin"
export const widgetHighlights = [
["4", "ProductWidget", "The React component of the product widget."],
["14", "zone", "The zone to inject the widget to."]
]
```tsx title="src/admin/widgets/product-widget.tsx" highlights={widgetHighlights}
import { defineWidgetConfig } from "@medusajs/admin-shared"
// The widget
const ProductWidget = () => {
@@ -41,16 +40,20 @@ const ProductWidget = () => {
}
// The widget's configurations
export const config: WidgetConfig = {
export const config = defineWidgetConfig({
zone: "product.details.after",
}
})
export default ProductWidget
```
The widget only shows the heading `Product Widget`.
In the exported widgets configurations, you must specify the zone to inject the widget into. The `zone` property can be a string or an array of strings, each being the name of the injection zone.
Use the `defineWidgetConfig` function imported from `@medusajs/admin-shared` to create and export the widget's configurations.
The function accepts as a parameter an object with the following property:
- `zone`: A string or an array of strings, each being the name of the zone to inject the widget into.
In the example above, the widget is injected after a products details.
@@ -66,6 +69,37 @@ Then, open a products details page. Youll find your custom widget at the b
---
## Detail Widget Props
Widgets that are injected into a details page (for example, `product.details.after`) receive a `data` prop, which is the main data of the details page (for example, the product object).
For example:
```tsx title="src/admin/widgets/product-widget.tsx" highlights={[["5"]]}
import { defineWidgetConfig } from "@medusajs/admin-shared"
import { DetailWidgetProps, AdminProduct } from "@medusajs/types"
const ProductWidget = ({
data
}: DetailWidgetProps<AdminProduct>) => {
return (
<div>
<h2>Product Widget {data.title}</h2>
</div>
)
}
export const config = defineWidgetConfig({
zone: "product.details.after",
})
export default ProductWidget
```
Notice that the type of the props is `DetailWidgetProps`, which accepts as a type argument the expected type of the data.
---
## Using UI Components
Its highly recommended that you use the [Medusa UI package](https://docs.medusajs.com/ui) to match your widgets design with the rest of the Medusa Admin.
@@ -73,7 +107,7 @@ Its highly recommended that you use the [Medusa UI package](https://docs.medu
For example, you can rewrite the above component to the following:
```tsx title="src/admin/widgets/product-widget.tsx"
import type { WidgetConfig } from "@medusajs/admin"
import { defineWidgetConfig } from "@medusajs/admin-shared"
import { Container, Heading } from "@medusajs/ui"
const ProductWidget = () => {
@@ -84,72 +118,16 @@ const ProductWidget = () => {
)
}
export const config: WidgetConfig = {
export const config: WidgetConfig = defineWidgetConfig({
zone: "product.details.after",
}
})
export default ProductWidget
```
---
## Widget Props
A widget receives a `notify` prop, which is an object having the following properties:
- `success`: a function that shows a success toast message.
- `error`: a function that shows an error toast message.
- `warn`: a function that shows a warning toast message.
- `info`: a function that shows an info toast message.
Each of these functions accepts two parameters: the messages title, and the messages content.
In addition, some injection zones provide additional props based on the pages context.
For example, you can rewrite the above widget to the following:
```tsx title="src/admin/widgets/product-widget.tsx" highlights={[["14", "product.title", "Show the product's title."], ["18", "success", "Show a success toast message on the click of a button."]]}
import type {
WidgetConfig,
ProductDetailsWidgetProps,
} from "@medusajs/admin"
import { Container, Heading, Button } from "@medusajs/ui"
const ProductWidget = ({
notify,
product,
}: ProductDetailsWidgetProps) => {
return (
<Container>
<Heading level="h2">
Product Widget {product.title}
</Heading>
<Button
onClick={() =>
notify.success("Success!", "You clicked the button!")
}
className="mt-3"
>
Click me
</Button>
</Container>
)
}
export const config: WidgetConfig = {
zone: "product.details.after",
}
export default ProductWidget
```
Since the widget is in the products details page, it receives the product as a prop. The widget now shows the title of the product in the header.
It also shows a button that, when you click, shows a success toast message.
<Note title="Tip">
Admin Widgets support [Tailwind CSS](https://tailwindcss.com/) out of the box.
Admin Widgets also support [Tailwind CSS](https://tailwindcss.com/) out of the box.
</Note>