feat(admin): add custom admin route ranking feature (#13946)
* ✨ Add custom admin routes ranking * 🐛 Fix sorting * 📝 Update admin ui-routes documentation * ✅ Add admin menu items spec * 🔧 Add changeset * 🐛 Remove redundant undefined initializations * 🔥 🔥 Move the documentation to a separate PR * ♻️ Move sorting logic to utils * 🔧 Update changeset --------- Co-authored-by: Bastien MONTOIS <bqst@bqst-hqckintosh.home>
This commit is contained in:
co-authored by
Bastien MONTOIS
parent
aae92d5447
commit
213c344804
@@ -70,6 +70,7 @@ const expectedMenuItems = `
|
||||
icon: RouteConfig0.icon,
|
||||
path: "/one",
|
||||
nested: undefined,
|
||||
rank: undefined,
|
||||
translationNs: undefined
|
||||
},
|
||||
{
|
||||
@@ -77,6 +78,7 @@ const expectedMenuItems = `
|
||||
icon: undefined,
|
||||
path: "/two",
|
||||
nested: undefined,
|
||||
rank: undefined,
|
||||
translationNs: undefined
|
||||
},
|
||||
{
|
||||
@@ -84,6 +86,7 @@ const expectedMenuItems = `
|
||||
icon: RouteConfig2.icon,
|
||||
path: "/three",
|
||||
nested: "/products",
|
||||
rank: undefined,
|
||||
translationNs: undefined
|
||||
}
|
||||
]
|
||||
@@ -141,6 +144,82 @@ describe("generateMenuItems", () => {
|
||||
)
|
||||
})
|
||||
|
||||
it("should include rank property in generated menu items", async () => {
|
||||
const mockFilesWithRank = [
|
||||
"Users/user/medusa/src/admin/routes/analytics/page.tsx",
|
||||
"Users/user/medusa/src/admin/routes/reports/page.tsx",
|
||||
]
|
||||
|
||||
const mockFileContentsWithRank = [
|
||||
`
|
||||
import { defineRouteConfig } from "@medusajs/admin-sdk"
|
||||
|
||||
const Page = () => {
|
||||
return <div>Analytics</div>
|
||||
}
|
||||
|
||||
export const config = defineRouteConfig({
|
||||
label: "Analytics",
|
||||
icon: "ChartBar",
|
||||
rank: 1,
|
||||
})
|
||||
|
||||
export default Page
|
||||
`,
|
||||
`
|
||||
import { defineRouteConfig } from "@medusajs/admin-sdk"
|
||||
|
||||
const Page = () => {
|
||||
return <div>Reports</div>
|
||||
}
|
||||
|
||||
export const config = defineRouteConfig({
|
||||
label: "Reports",
|
||||
rank: 2,
|
||||
})
|
||||
|
||||
export default Page
|
||||
`,
|
||||
]
|
||||
|
||||
vi.mocked(utils.crawl).mockResolvedValue(mockFilesWithRank)
|
||||
|
||||
vi.mocked(fs.readFile).mockImplementation(async (file) =>
|
||||
Promise.resolve(
|
||||
mockFileContentsWithRank[mockFilesWithRank.indexOf(file as string)]
|
||||
)
|
||||
)
|
||||
|
||||
const result = await generateMenuItems(
|
||||
new Set(["Users/user/medusa/src/admin"])
|
||||
)
|
||||
|
||||
const expectedMenuItemsWithRank = `
|
||||
menuItems: [
|
||||
{
|
||||
label: RouteConfig0.label,
|
||||
icon: RouteConfig0.icon,
|
||||
path: "/analytics",
|
||||
nested: undefined,
|
||||
rank: 1,
|
||||
translationNs: undefined
|
||||
},
|
||||
{
|
||||
label: RouteConfig1.label,
|
||||
icon: undefined,
|
||||
path: "/reports",
|
||||
nested: undefined,
|
||||
rank: 2,
|
||||
translationNs: undefined
|
||||
}
|
||||
]
|
||||
`
|
||||
|
||||
expect(utils.normalizeString(result.code)).toEqual(
|
||||
utils.normalizeString(expectedMenuItemsWithRank)
|
||||
)
|
||||
})
|
||||
|
||||
it("should handle translationNs field", async () => {
|
||||
const mockFileWithTranslation = `
|
||||
import { defineRouteConfig } from "@medusajs/admin-sdk"
|
||||
@@ -176,6 +255,7 @@ describe("generateMenuItems", () => {
|
||||
icon: undefined,
|
||||
path: "/custom",
|
||||
nested: undefined,
|
||||
rank: undefined,
|
||||
translationNs: RouteConfig0.translationNs
|
||||
}
|
||||
]
|
||||
@@ -185,4 +265,99 @@ describe("generateMenuItems", () => {
|
||||
utils.normalizeString(expectedOutput)
|
||||
)
|
||||
})
|
||||
|
||||
it("should handle mixed ranked and unranked routes", async () => {
|
||||
const mockMixedFiles = [
|
||||
"Users/user/medusa/src/admin/routes/first/page.tsx",
|
||||
"Users/user/medusa/src/admin/routes/second/page.tsx",
|
||||
"Users/user/medusa/src/admin/routes/third/page.tsx",
|
||||
]
|
||||
|
||||
const mockMixedContents = [
|
||||
`
|
||||
import { defineRouteConfig } from "@medusajs/admin-sdk"
|
||||
|
||||
const Page = () => {
|
||||
return <div>First</div>
|
||||
}
|
||||
|
||||
export const config = defineRouteConfig({
|
||||
label: "First",
|
||||
rank: 1,
|
||||
})
|
||||
|
||||
export default Page
|
||||
`,
|
||||
`
|
||||
import { defineRouteConfig } from "@medusajs/admin-sdk"
|
||||
|
||||
const Page = () => {
|
||||
return <div>Second</div>
|
||||
}
|
||||
|
||||
export const config = defineRouteConfig({
|
||||
label: "Second",
|
||||
})
|
||||
|
||||
export default Page
|
||||
`,
|
||||
`
|
||||
import { defineRouteConfig } from "@medusajs/admin-sdk"
|
||||
|
||||
const Page = () => {
|
||||
return <div>Third</div>
|
||||
}
|
||||
|
||||
export const config = defineRouteConfig({
|
||||
label: "Third",
|
||||
rank: 0,
|
||||
})
|
||||
|
||||
export default Page
|
||||
`,
|
||||
]
|
||||
|
||||
vi.mocked(utils.crawl).mockResolvedValue(mockMixedFiles)
|
||||
|
||||
vi.mocked(fs.readFile).mockImplementation(async (file) =>
|
||||
Promise.resolve(mockMixedContents[mockMixedFiles.indexOf(file as string)])
|
||||
)
|
||||
|
||||
const result = await generateMenuItems(
|
||||
new Set(["Users/user/medusa/src/admin"])
|
||||
)
|
||||
|
||||
const expectedMixedMenuItems = `
|
||||
menuItems: [
|
||||
{
|
||||
label: RouteConfig0.label,
|
||||
icon: undefined,
|
||||
path: "/first",
|
||||
nested: undefined,
|
||||
rank: 1,
|
||||
translationNs: undefined
|
||||
},
|
||||
{
|
||||
label: RouteConfig1.label,
|
||||
icon: undefined,
|
||||
path: "/second",
|
||||
nested: undefined,
|
||||
rank: undefined,
|
||||
translationNs: undefined
|
||||
},
|
||||
{
|
||||
label: RouteConfig2.label,
|
||||
icon: undefined,
|
||||
path: "/third",
|
||||
nested: undefined,
|
||||
rank: 0,
|
||||
translationNs: undefined
|
||||
}
|
||||
]
|
||||
`
|
||||
|
||||
expect(utils.normalizeString(result.code)).toEqual(
|
||||
utils.normalizeString(expectedMixedMenuItems)
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user