feat(dashboard,medusa): Add updated Metadata Form (#8084)

**What**
- Adds new Metadata form component.
- Adds the Metadata section as an option to the Page layouts

<img width="576" alt="Skærmbillede 2024-07-11 kl  11 34 06" src="https://github.com/medusajs/medusa/assets/45367945/417810ee-26e2-4c8a-86e3-58ef327054af">
<img width="580" alt="Skærmbillede 2024-07-11 kl  11 34 33" src="https://github.com/medusajs/medusa/assets/45367945/437a5e01-01e2-4ff7-8c7e-42a86d1ce2b3">


**Note**
- When Metadata contains non-primitive data, we disable those rows, and show a placeholder value, a tooltip and an alert describing that the row can be edited through the API. I want to add a JSON editor to allow editing these things in admin, but awaiting approval on that.
- This PR only adds the new form to a couple of pages, to keep the PR light, especially since metadata is not implemented correctly in all validators so also needs some changes to the core. This still show some examples of how its used with the new Page layout components. Will follow up with more pages in future PRs. 
- We try to convert the inputs to the best fitting primitive, so if a user types "true" then we save the value as a boolean, "130" as number, "testing" as a string, etc.
This commit is contained in:
Kasper Fabricius Kristensen
2024-07-11 13:54:59 +00:00
committed by GitHub
parent 66acb3023e
commit b5a44ef6b1
28 changed files with 823 additions and 386 deletions
@@ -1,13 +1,27 @@
import { Outlet } from "react-router-dom"
import { JsonViewSection } from "../../../common/json-view-section"
import { MetadataSection } from "../../../common/metadata-section"
import { PageProps } from "../types"
export const SingleColumnPage = <TData,>({
children,
widgets,
/**
* Data of the page which is passed to Widgets, JSON view, and Metadata view.
*/
data,
hasOutlet,
/**
* Whether the page should render an outlet for children routes. Defaults to true.
*/
hasOutlet = true,
/**
* Whether to show JSON view of the data. Defaults to false.
*/
showJSON,
/**
* Whether to show metadata view of the data. Defaults to false.
*/
showMetadata,
}: PageProps<TData>) => {
const { before, after } = widgets
const widgetProps = { data }
@@ -22,6 +36,16 @@ export const SingleColumnPage = <TData,>({
showJSON = false
}
if (showMetadata && !data) {
if (process.env.NODE_ENV === "development") {
console.warn(
"`showMetadata` is true but no data is provided. To display metadata, provide data prop."
)
}
showMetadata = false
}
return (
<div className="flex flex-col gap-y-3">
{before.widgets.map((w, i) => {
@@ -31,6 +55,7 @@ export const SingleColumnPage = <TData,>({
{after.widgets.map((w, i) => {
return <w.Component {...widgetProps} key={i} />
})}
{showMetadata && <MetadataSection data={data!} />}
{showJSON && <JsonViewSection data={data!} />}
{hasOutlet && <Outlet />}
</div>
@@ -2,6 +2,7 @@ import { clx } from "@medusajs/ui"
import { Children, ComponentPropsWithoutRef } from "react"
import { Outlet } from "react-router-dom"
import { JsonViewSection } from "../../../common/json-view-section"
import { MetadataSection } from "../../../common/metadata-section"
import { PageProps, WidgetImport, WidgetProps } from "../types"
interface TwoColumnWidgetProps extends WidgetProps {
@@ -20,13 +21,17 @@ const Root = <TData,>({
*/
widgets,
/**
* Data to be passed to widgets and the JSON view.
* Data to be passed to widgets, JSON view, and Metadata view.
*/
data,
/**
* Whether to show JSON view of the data. Defaults to true.
* Whether to show JSON view of the data. Defaults to false.
*/
showJSON = false,
/**
* Whether to show metadata view of the data. Defaults to false.
*/
showMetadata = false,
/**
* Whether to render an outlet for children routes. Defaults to true.
*/
@@ -45,6 +50,16 @@ const Root = <TData,>({
showJSON = false
}
if (showMetadata && !data) {
if (process.env.NODE_ENV === "development") {
console.warn(
"`showMetadata` is true but no data is provided. To display metadata, provide data prop."
)
}
showMetadata = false
}
const childrenArray = Children.toArray(children)
if (childrenArray.length !== 2) {
@@ -52,9 +67,10 @@ const Root = <TData,>({
}
const [main, sidebar] = childrenArray
const showExtraData = showJSON || showMetadata
return (
<div className="flex flex-col gap-y-2">
<div className="flex flex-col gap-y-3">
{before.widgets.map((w, i) => {
return <w.Component {...widgetProps} key={i} />
})}
@@ -64,9 +80,10 @@ const Root = <TData,>({
{after.widgets.map((w, i) => {
return <w.Component {...widgetProps} key={i} />
})}
{showJSON && (
<div className="hidden xl:block">
<JsonViewSection data={data!} root="product" />
{showExtraData && (
<div className="hidden flex-col gap-y-3 xl:flex">
{showMetadata && <MetadataSection data={data!} />}
{showJSON && <JsonViewSection data={data!} />}
</div>
)}
</div>
@@ -78,9 +95,10 @@ const Root = <TData,>({
{sideAfter.widgets.map((w, i) => {
return <w.Component {...widgetProps} key={i} />
})}
{showJSON && (
<div className="xl:hidden">
<JsonViewSection data={data!} />
{showExtraData && (
<div className="flex flex-col gap-y-3 xl:hidden">
{showMetadata && <MetadataSection data={data!} />}
{showJSON && <JsonViewSection data={data!} />}
</div>
)}
</div>
@@ -18,5 +18,6 @@ export interface PageProps<TData> {
widgets: WidgetProps
data?: TData
showJSON?: boolean
showMetadata?: boolean
hasOutlet?: boolean
}