feat(dashboard,admin-vite-plugin,admin-bundler,admin-sdk): Rework admin extensions and introduce custom fields API (#9338)
This commit is contained in:
committed by
GitHub
parent
35e69d32f2
commit
d71343d6ab
@@ -0,0 +1,40 @@
|
||||
import {
|
||||
PRODUCT_CUSTOM_FIELD_DISPLAY_PATHS,
|
||||
PRODUCT_CUSTOM_FIELD_DISPLAY_ZONES,
|
||||
PRODUCT_CUSTOM_FIELD_FORM_CONFIG_PATHS,
|
||||
PRODUCT_CUSTOM_FIELD_FORM_FIELD_PATHS,
|
||||
PRODUCT_CUSTOM_FIELD_FORM_TABS,
|
||||
PRODUCT_CUSTOM_FIELD_FORM_ZONES,
|
||||
PRODUCT_CUSTOM_FIELD_LINK_PATHS,
|
||||
PRODUCT_CUSTOM_FIELD_MODEL,
|
||||
} from "./product"
|
||||
|
||||
export const CUSTOM_FIELD_MODELS = [PRODUCT_CUSTOM_FIELD_MODEL] as const
|
||||
|
||||
export const CUSTOM_FIELD_CONTAINER_ZONES = [
|
||||
...PRODUCT_CUSTOM_FIELD_DISPLAY_ZONES,
|
||||
] as const
|
||||
|
||||
export const CUSTOM_FIELD_FORM_ZONES = [
|
||||
...PRODUCT_CUSTOM_FIELD_FORM_ZONES,
|
||||
] as const
|
||||
|
||||
export const CUSTOM_FIELD_FORM_TABS = [
|
||||
...PRODUCT_CUSTOM_FIELD_FORM_TABS,
|
||||
] as const
|
||||
|
||||
export const CUSTOM_FIELD_FORM_CONFIG_PATHS = [
|
||||
...PRODUCT_CUSTOM_FIELD_FORM_CONFIG_PATHS,
|
||||
] as const
|
||||
|
||||
export const CUSTOM_FIELD_FORM_FIELD_PATHS = [
|
||||
...PRODUCT_CUSTOM_FIELD_FORM_FIELD_PATHS,
|
||||
] as const
|
||||
|
||||
export const CUSTOM_FIELD_DISPLAY_PATHS = [
|
||||
...PRODUCT_CUSTOM_FIELD_DISPLAY_PATHS,
|
||||
] as const
|
||||
|
||||
export const CUSTOM_FIELD_LINK_PATHS = [
|
||||
...PRODUCT_CUSTOM_FIELD_LINK_PATHS,
|
||||
] as const
|
||||
@@ -0,0 +1,3 @@
|
||||
export * from "./product"
|
||||
export * from "./types"
|
||||
export * from "./utils"
|
||||
@@ -0,0 +1,48 @@
|
||||
export const PRODUCT_CUSTOM_FIELD_MODEL = "product" as const
|
||||
|
||||
export const PRODUCT_CUSTOM_FIELD_FORM_ZONES = [
|
||||
"create",
|
||||
"edit",
|
||||
"organize",
|
||||
"attributes",
|
||||
] as const
|
||||
|
||||
export const PRODUCT_CUSTOM_FIELD_CREATE_FORM_TABS = [
|
||||
"general",
|
||||
"organize",
|
||||
] as const
|
||||
export const PRODUCT_CUSTOM_FIELD_FORM_TABS = [
|
||||
...PRODUCT_CUSTOM_FIELD_CREATE_FORM_TABS,
|
||||
] as const
|
||||
|
||||
export const PRODUCT_CUSTOM_FIELD_DISPLAY_ZONES = [
|
||||
"general",
|
||||
"organize",
|
||||
"attributes",
|
||||
] as const
|
||||
|
||||
export const PRODUCT_CUSTOM_FIELD_LINK_PATHS = [
|
||||
`${PRODUCT_CUSTOM_FIELD_MODEL}.$link`,
|
||||
] as const
|
||||
|
||||
export const PRODUCT_CUSTOM_FIELD_FORM_CONFIG_PATHS = [
|
||||
...PRODUCT_CUSTOM_FIELD_FORM_ZONES.map(
|
||||
(form) => `${PRODUCT_CUSTOM_FIELD_MODEL}.${form}.$config`
|
||||
),
|
||||
] as const
|
||||
|
||||
export const PRODUCT_CUSTOM_FIELD_FORM_FIELD_PATHS = [
|
||||
...PRODUCT_CUSTOM_FIELD_FORM_ZONES.flatMap((form) => {
|
||||
return form === "create"
|
||||
? PRODUCT_CUSTOM_FIELD_CREATE_FORM_TABS.map(
|
||||
(tab) => `${PRODUCT_CUSTOM_FIELD_MODEL}.${form}.${tab}.$field`
|
||||
)
|
||||
: [`${PRODUCT_CUSTOM_FIELD_MODEL}.${form}.$field`]
|
||||
}),
|
||||
] as const
|
||||
|
||||
export const PRODUCT_CUSTOM_FIELD_DISPLAY_PATHS = [
|
||||
...PRODUCT_CUSTOM_FIELD_DISPLAY_ZONES.map(
|
||||
(id) => `${PRODUCT_CUSTOM_FIELD_MODEL}.${id}.$display`
|
||||
),
|
||||
] as const
|
||||
@@ -0,0 +1,10 @@
|
||||
import {
|
||||
PRODUCT_CUSTOM_FIELD_DISPLAY_ZONES,
|
||||
PRODUCT_CUSTOM_FIELD_FORM_TABS,
|
||||
PRODUCT_CUSTOM_FIELD_FORM_ZONES,
|
||||
} from "./constants"
|
||||
|
||||
export type ProductFormZone = (typeof PRODUCT_CUSTOM_FIELD_FORM_ZONES)[number]
|
||||
export type ProductFormTab = (typeof PRODUCT_CUSTOM_FIELD_FORM_TABS)[number]
|
||||
export type ProductDisplayZone =
|
||||
(typeof PRODUCT_CUSTOM_FIELD_DISPLAY_ZONES)[number]
|
||||
@@ -0,0 +1,48 @@
|
||||
import {
|
||||
CUSTOM_FIELD_CONTAINER_ZONES,
|
||||
CUSTOM_FIELD_FORM_TABS,
|
||||
CUSTOM_FIELD_FORM_ZONES,
|
||||
CUSTOM_FIELD_MODELS,
|
||||
} from "./constants"
|
||||
import type {
|
||||
ProductDisplayZone,
|
||||
ProductFormTab,
|
||||
ProductFormZone,
|
||||
} from "./product"
|
||||
|
||||
export type CustomFieldModel = (typeof CUSTOM_FIELD_MODELS)[number]
|
||||
|
||||
export type CustomFieldFormZone = (typeof CUSTOM_FIELD_FORM_ZONES)[number]
|
||||
|
||||
export type CustomFieldFormTab = (typeof CUSTOM_FIELD_FORM_TABS)[number]
|
||||
|
||||
export type CustomFieldContainerZone =
|
||||
(typeof CUSTOM_FIELD_CONTAINER_ZONES)[number]
|
||||
|
||||
export type CustomFieldZone = CustomFieldFormZone | CustomFieldContainerZone
|
||||
|
||||
export type CustomFieldImportType = "display" | "field" | "link" | "config"
|
||||
|
||||
export interface CustomFieldModelFormMap {
|
||||
product: ProductFormZone
|
||||
}
|
||||
|
||||
export interface CustomFieldModelContainerMap {
|
||||
product: ProductDisplayZone
|
||||
}
|
||||
|
||||
export type CustomFieldModelFormTabsMap = {
|
||||
product: {
|
||||
create: ProductFormTab
|
||||
edit: never
|
||||
organize: never
|
||||
attributes: never
|
||||
}
|
||||
customer: {
|
||||
create: never
|
||||
edit: never
|
||||
}
|
||||
}
|
||||
|
||||
export type CustomFieldFormKeys<T extends CustomFieldModel> =
|
||||
CustomFieldModelFormMap[T]
|
||||
@@ -0,0 +1,54 @@
|
||||
import {
|
||||
CUSTOM_FIELD_CONTAINER_ZONES,
|
||||
CUSTOM_FIELD_DISPLAY_PATHS,
|
||||
CUSTOM_FIELD_FORM_CONFIG_PATHS,
|
||||
CUSTOM_FIELD_FORM_FIELD_PATHS,
|
||||
CUSTOM_FIELD_FORM_TABS,
|
||||
CUSTOM_FIELD_FORM_ZONES,
|
||||
CUSTOM_FIELD_LINK_PATHS,
|
||||
CUSTOM_FIELD_MODELS,
|
||||
} from "./constants"
|
||||
import {
|
||||
CustomFieldContainerZone,
|
||||
CustomFieldFormTab,
|
||||
CustomFieldFormZone,
|
||||
CustomFieldModel,
|
||||
} from "./types"
|
||||
|
||||
// Validators for individual segments of the custom field extension system
|
||||
|
||||
export function isValidCustomFieldModel(id: any): id is CustomFieldModel {
|
||||
return CUSTOM_FIELD_MODELS.includes(id)
|
||||
}
|
||||
|
||||
export function isValidCustomFieldFormZone(id: any): id is CustomFieldFormZone {
|
||||
return CUSTOM_FIELD_FORM_ZONES.includes(id)
|
||||
}
|
||||
|
||||
export function isValidCustomFieldFormTab(id: any): id is CustomFieldFormTab {
|
||||
return CUSTOM_FIELD_FORM_TABS.includes(id)
|
||||
}
|
||||
|
||||
export function isValidCustomFieldDisplayZone(
|
||||
id: any
|
||||
): id is CustomFieldContainerZone {
|
||||
return CUSTOM_FIELD_CONTAINER_ZONES.includes(id)
|
||||
}
|
||||
|
||||
// Validators for full paths of custom field extensions
|
||||
|
||||
export function isValidCustomFieldDisplayPath(id: any): id is string {
|
||||
return CUSTOM_FIELD_DISPLAY_PATHS.includes(id)
|
||||
}
|
||||
|
||||
export function isValidCustomFieldFormConfigPath(id: any): id is string {
|
||||
return CUSTOM_FIELD_FORM_CONFIG_PATHS.includes(id)
|
||||
}
|
||||
|
||||
export function isValidCustomFieldFormFieldPath(id: any): id is string {
|
||||
return CUSTOM_FIELD_FORM_FIELD_PATHS.includes(id)
|
||||
}
|
||||
|
||||
export function isValidCustomFieldLinkPath(id: any): id is string {
|
||||
return CUSTOM_FIELD_LINK_PATHS.includes(id)
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
export const ROUTE_IMPORTS = ["routes/pages", "routes/links"] as const
|
||||
@@ -1,3 +0,0 @@
|
||||
import { ROUTE_IMPORTS } from "./constants"
|
||||
|
||||
export type RouteImport = (typeof ROUTE_IMPORTS)[number]
|
||||
@@ -1,40 +0,0 @@
|
||||
import { ROUTE_IMPORTS } from "../routes"
|
||||
import { INJECTION_ZONES } from "../widgets"
|
||||
import { getVirtualId, getWidgetImport, resolveVirtualId } from "./utils"
|
||||
|
||||
const VIRTUAL_WIDGET_MODULES = INJECTION_ZONES.map((zone) => {
|
||||
return getVirtualId(getWidgetImport(zone))
|
||||
})
|
||||
|
||||
const VIRTUAL_ROUTE_MODULES = ROUTE_IMPORTS.map((route) => {
|
||||
return getVirtualId(route)
|
||||
})
|
||||
|
||||
/**
|
||||
* All virtual modules that are used in the admin panel. Virtual modules are used
|
||||
* to inject custom widgets, routes and settings. A virtual module is imported using
|
||||
* a string that corresponds to the id of the virtual module.
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* import ProductDetailsBefore from "virtual:medusa/widgets/product/details/before"
|
||||
* ```
|
||||
*/
|
||||
export const VIRTUAL_MODULES = [
|
||||
...VIRTUAL_WIDGET_MODULES,
|
||||
...VIRTUAL_ROUTE_MODULES,
|
||||
]
|
||||
|
||||
/**
|
||||
* Reolved paths to all virtual widget modules.
|
||||
*/
|
||||
export const RESOLVED_WIDGET_MODULES = VIRTUAL_WIDGET_MODULES.map((id) => {
|
||||
return resolveVirtualId(id)
|
||||
})
|
||||
|
||||
/**
|
||||
* Reolved paths to all virtual route modules.
|
||||
*/
|
||||
export const RESOLVED_ROUTE_MODULES = VIRTUAL_ROUTE_MODULES.map((id) => {
|
||||
return resolveVirtualId(id)
|
||||
})
|
||||
@@ -1,2 +0,0 @@
|
||||
export * from "./constants"
|
||||
export * from "./utils"
|
||||
@@ -1,25 +0,0 @@
|
||||
import { InjectionZone } from "../widgets"
|
||||
|
||||
const PREFIX = "virtual:medusa/"
|
||||
|
||||
export const getVirtualId = (name: string) => {
|
||||
return `${PREFIX}${name}`
|
||||
}
|
||||
|
||||
export const resolveVirtualId = (id: string) => {
|
||||
return `\0${id}`
|
||||
}
|
||||
|
||||
export const getWidgetImport = (zone: InjectionZone) => {
|
||||
return `widgets/${zone.replace(/\./g, "/")}`
|
||||
}
|
||||
|
||||
export const getWidgetZone = (resolvedId: string): InjectionZone => {
|
||||
const virtualPrefix = `\0${PREFIX}widgets/`
|
||||
|
||||
const zone = resolvedId
|
||||
.replace(virtualPrefix, "")
|
||||
.replace(/\//g, ".") as InjectionZone
|
||||
|
||||
return zone as InjectionZone
|
||||
}
|
||||
Reference in New Issue
Block a user