@mantajs/dashboard 0.1.6 → 0.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/app.js CHANGED
@@ -100375,7 +100375,7 @@ var init_user_menu2 = __esm({
100375
100375
  });
100376
100376
 
100377
100377
  // src/components/layout/main-layout/main-layout.tsx
100378
- var import_icons10, import_ui14, import_radix_ui5, import_react_i18next10, import_react_router_dom9, import_jsx_runtime22, MainLayout, MainSidebar, Logout2, Header, useCoreRoutes, Searchbar, CoreRouteSection, MAIN_MENU_PATHS, ExtensionRouteSection, UtilitySection, UserSection;
100378
+ var import_icons10, import_ui14, import_radix_ui5, import_react_i18next10, import_react_router_dom9, import_menu_config, import_jsx_runtime22, ICON_MAP, MainLayout, MainSidebar, Logout2, Header, getDefaultMedusaRoutes, useCoreRoutes, Searchbar, CoreRouteSection, getMainMenuPaths, MAIN_MENU_PATHS, ExtensionRouteSection, UtilitySection, UserSection;
100379
100379
  var init_main_layout = __esm({
100380
100380
  "src/components/layout/main-layout/main-layout.tsx"() {
100381
100381
  "use strict";
@@ -100394,7 +100394,19 @@ var init_main_layout = __esm({
100394
100394
  init_search_provider2();
100395
100395
  init_user_menu2();
100396
100396
  init_use_document_direction();
100397
+ import_menu_config = __toESM(require("virtual:dashboard/menu-config"));
100397
100398
  import_jsx_runtime22 = require("react/jsx-runtime");
100399
+ ICON_MAP = {
100400
+ ShoppingCart: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_icons10.ShoppingCart, {}),
100401
+ Tag: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_icons10.Tag, {}),
100402
+ Buildings: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_icons10.Buildings, {}),
100403
+ Users: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_icons10.Users, {}),
100404
+ ReceiptPercent: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_icons10.ReceiptPercent, {}),
100405
+ CurrencyDollar: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_icons10.CurrencyDollar, {}),
100406
+ BuildingStorefront: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_icons10.BuildingStorefront, {}),
100407
+ CogSixTooth: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_icons10.CogSixTooth, {}),
100408
+ SquaresPlus: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_icons10.SquaresPlus, {})
100409
+ };
100398
100410
  MainLayout = () => {
100399
100411
  return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Shell, { children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(MainSidebar, {}) });
100400
100412
  };
@@ -100509,74 +100521,37 @@ var init_main_layout = __esm({
100509
100521
  }
100510
100522
  ) });
100511
100523
  };
100524
+ getDefaultMedusaRoutes = (t5) => [
100525
+ { icon: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_icons10.ShoppingCart, {}), label: t5("orders.domain"), to: "/orders", items: [] },
100526
+ { icon: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_icons10.Tag, {}), label: t5("products.domain"), to: "/products", items: [
100527
+ { label: t5("collections.domain"), to: "/collections" },
100528
+ { label: t5("categories.domain"), to: "/categories" }
100529
+ ] },
100530
+ { icon: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_icons10.Buildings, {}), label: t5("inventory.domain"), to: "/inventory", items: [
100531
+ { label: t5("reservations.domain"), to: "/reservations" }
100532
+ ] },
100533
+ { icon: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_icons10.Users, {}), label: t5("customers.domain"), to: "/customers", items: [
100534
+ { label: t5("customerGroups.domain"), to: "/customer-groups" }
100535
+ ] },
100536
+ { icon: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_icons10.ReceiptPercent, {}), label: t5("promotions.domain"), to: "/promotions", items: [
100537
+ { label: t5("campaigns.domain"), to: "/campaigns" }
100538
+ ] },
100539
+ { icon: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_icons10.CurrencyDollar, {}), label: t5("priceLists.domain"), to: "/price-lists" }
100540
+ ];
100512
100541
  useCoreRoutes = () => {
100513
100542
  const { t: t5 } = (0, import_react_i18next10.useTranslation)();
100514
- return [
100515
- {
100516
- icon: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_icons10.BuildingStorefront, {}),
100517
- label: "Companies",
100518
- to: "/companies",
100519
- items: [
100520
- {
100521
- label: "Employees",
100522
- to: "/employees"
100523
- }
100524
- ]
100525
- },
100526
- {
100527
- icon: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_icons10.ShoppingCart, {}),
100528
- label: t5("orders.domain"),
100529
- to: "/orders",
100530
- items: []
100531
- },
100532
- {
100533
- icon: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_icons10.Tag, {}),
100534
- label: t5("products.domain"),
100535
- to: "/products",
100536
- items: [
100537
- {
100538
- label: t5("collections.domain"),
100539
- to: "/collections"
100540
- },
100541
- {
100542
- label: t5("categories.domain"),
100543
- to: "/categories"
100544
- }
100545
- // TODO: Enable when domin is introduced
100546
- // {
100547
- // label: t("giftCards.domain"),
100548
- // to: "/gift-cards",
100549
- // },
100550
- ]
100551
- },
100552
- {
100553
- icon: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_icons10.Buildings, {}),
100554
- label: t5("inventory.domain"),
100555
- to: "/inventory",
100556
- items: [
100557
- {
100558
- label: t5("reservations.domain"),
100559
- to: "/reservations"
100560
- }
100561
- ]
100562
- },
100563
- {
100564
- icon: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_icons10.ReceiptPercent, {}),
100565
- label: t5("promotions.domain"),
100566
- to: "/promotions",
100567
- items: [
100568
- {
100569
- label: t5("campaigns.domain"),
100570
- to: "/campaigns"
100571
- }
100572
- ]
100573
- },
100574
- {
100575
- icon: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_icons10.CurrencyDollar, {}),
100576
- label: t5("priceLists.domain"),
100577
- to: "/price-lists"
100578
- }
100579
- ];
100543
+ if (!import_menu_config.default) {
100544
+ return getDefaultMedusaRoutes(t5);
100545
+ }
100546
+ return import_menu_config.default.items.map((item) => ({
100547
+ icon: ICON_MAP[item.icon] || /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_icons10.SquaresPlus, {}),
100548
+ label: item.useTranslation ? t5(item.label) : item.label,
100549
+ to: item.to,
100550
+ items: item.items?.map((sub2) => ({
100551
+ label: sub2.useTranslation ? t5(sub2.label) : sub2.label,
100552
+ to: sub2.to
100553
+ }))
100554
+ }));
100580
100555
  };
100581
100556
  Searchbar = () => {
100582
100557
  const { t: t5 } = (0, import_react_i18next10.useTranslation)();
@@ -100617,7 +100592,17 @@ var init_main_layout = __esm({
100617
100592
  })
100618
100593
  ] });
100619
100594
  };
100620
- MAIN_MENU_PATHS = ["/companies", "/employees"];
100595
+ getMainMenuPaths = () => {
100596
+ if (!import_menu_config.default) return [];
100597
+ const config = import_menu_config.default;
100598
+ const paths = [];
100599
+ config.items.forEach((item) => {
100600
+ paths.push(item.to);
100601
+ item.items?.forEach((sub2) => paths.push(sub2.to));
100602
+ });
100603
+ return paths;
100604
+ };
100605
+ MAIN_MENU_PATHS = getMainMenuPaths();
100621
100606
  ExtensionRouteSection = () => {
100622
100607
  const { t: t5 } = (0, import_react_i18next10.useTranslation)();
100623
100608
  const { getMenu } = useExtension();
package/dist/app.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  DashboardApp
3
- } from "./chunk-EZVEBD35.mjs";
3
+ } from "./chunk-ZQVS3F3X.mjs";
4
4
  import "./chunk-2SSUH2HJ.mjs";
5
5
  import "./chunk-ONB3JEHR.mjs";
6
6
  import "./chunk-YCDDT44O.mjs";
@@ -94528,7 +94528,8 @@ import {
94528
94528
  ReceiptPercent,
94529
94529
  ShoppingCart,
94530
94530
  SquaresPlus,
94531
- Tag
94531
+ Tag,
94532
+ Users
94532
94533
  } from "@medusajs/icons";
94533
94534
  import { Avatar as Avatar2, Divider, DropdownMenu as DropdownMenu3, Text as Text5, clx as clx6 } from "@medusajs/ui";
94534
94535
  import { Collapsible as RadixCollapsible2 } from "radix-ui";
@@ -95391,7 +95392,19 @@ var UserItem = () => {
95391
95392
  };
95392
95393
 
95393
95394
  // src/components/layout/main-layout/main-layout.tsx
95395
+ import menuConfig from "virtual:dashboard/menu-config";
95394
95396
  import { jsx as jsx13, jsxs as jsxs8 } from "react/jsx-runtime";
95397
+ var ICON_MAP = {
95398
+ ShoppingCart: /* @__PURE__ */ jsx13(ShoppingCart, {}),
95399
+ Tag: /* @__PURE__ */ jsx13(Tag, {}),
95400
+ Buildings: /* @__PURE__ */ jsx13(Buildings, {}),
95401
+ Users: /* @__PURE__ */ jsx13(Users, {}),
95402
+ ReceiptPercent: /* @__PURE__ */ jsx13(ReceiptPercent, {}),
95403
+ CurrencyDollar: /* @__PURE__ */ jsx13(CurrencyDollar, {}),
95404
+ BuildingStorefront: /* @__PURE__ */ jsx13(BuildingStorefront, {}),
95405
+ CogSixTooth: /* @__PURE__ */ jsx13(CogSixTooth, {}),
95406
+ SquaresPlus: /* @__PURE__ */ jsx13(SquaresPlus, {})
95407
+ };
95395
95408
  var MainLayout = () => {
95396
95409
  return /* @__PURE__ */ jsx13(Shell, { children: /* @__PURE__ */ jsx13(MainSidebar, {}) });
95397
95410
  };
@@ -95506,74 +95519,37 @@ var Header = () => {
95506
95519
  }
95507
95520
  ) });
95508
95521
  };
95522
+ var getDefaultMedusaRoutes = (t2) => [
95523
+ { icon: /* @__PURE__ */ jsx13(ShoppingCart, {}), label: t2("orders.domain"), to: "/orders", items: [] },
95524
+ { icon: /* @__PURE__ */ jsx13(Tag, {}), label: t2("products.domain"), to: "/products", items: [
95525
+ { label: t2("collections.domain"), to: "/collections" },
95526
+ { label: t2("categories.domain"), to: "/categories" }
95527
+ ] },
95528
+ { icon: /* @__PURE__ */ jsx13(Buildings, {}), label: t2("inventory.domain"), to: "/inventory", items: [
95529
+ { label: t2("reservations.domain"), to: "/reservations" }
95530
+ ] },
95531
+ { icon: /* @__PURE__ */ jsx13(Users, {}), label: t2("customers.domain"), to: "/customers", items: [
95532
+ { label: t2("customerGroups.domain"), to: "/customer-groups" }
95533
+ ] },
95534
+ { icon: /* @__PURE__ */ jsx13(ReceiptPercent, {}), label: t2("promotions.domain"), to: "/promotions", items: [
95535
+ { label: t2("campaigns.domain"), to: "/campaigns" }
95536
+ ] },
95537
+ { icon: /* @__PURE__ */ jsx13(CurrencyDollar, {}), label: t2("priceLists.domain"), to: "/price-lists" }
95538
+ ];
95509
95539
  var useCoreRoutes = () => {
95510
95540
  const { t: t2 } = useTranslation9();
95511
- return [
95512
- {
95513
- icon: /* @__PURE__ */ jsx13(BuildingStorefront, {}),
95514
- label: "Companies",
95515
- to: "/companies",
95516
- items: [
95517
- {
95518
- label: "Employees",
95519
- to: "/employees"
95520
- }
95521
- ]
95522
- },
95523
- {
95524
- icon: /* @__PURE__ */ jsx13(ShoppingCart, {}),
95525
- label: t2("orders.domain"),
95526
- to: "/orders",
95527
- items: []
95528
- },
95529
- {
95530
- icon: /* @__PURE__ */ jsx13(Tag, {}),
95531
- label: t2("products.domain"),
95532
- to: "/products",
95533
- items: [
95534
- {
95535
- label: t2("collections.domain"),
95536
- to: "/collections"
95537
- },
95538
- {
95539
- label: t2("categories.domain"),
95540
- to: "/categories"
95541
- }
95542
- // TODO: Enable when domin is introduced
95543
- // {
95544
- // label: t("giftCards.domain"),
95545
- // to: "/gift-cards",
95546
- // },
95547
- ]
95548
- },
95549
- {
95550
- icon: /* @__PURE__ */ jsx13(Buildings, {}),
95551
- label: t2("inventory.domain"),
95552
- to: "/inventory",
95553
- items: [
95554
- {
95555
- label: t2("reservations.domain"),
95556
- to: "/reservations"
95557
- }
95558
- ]
95559
- },
95560
- {
95561
- icon: /* @__PURE__ */ jsx13(ReceiptPercent, {}),
95562
- label: t2("promotions.domain"),
95563
- to: "/promotions",
95564
- items: [
95565
- {
95566
- label: t2("campaigns.domain"),
95567
- to: "/campaigns"
95568
- }
95569
- ]
95570
- },
95571
- {
95572
- icon: /* @__PURE__ */ jsx13(CurrencyDollar, {}),
95573
- label: t2("priceLists.domain"),
95574
- to: "/price-lists"
95575
- }
95576
- ];
95541
+ if (!menuConfig) {
95542
+ return getDefaultMedusaRoutes(t2);
95543
+ }
95544
+ return menuConfig.items.map((item) => ({
95545
+ icon: ICON_MAP[item.icon] || /* @__PURE__ */ jsx13(SquaresPlus, {}),
95546
+ label: item.useTranslation ? t2(item.label) : item.label,
95547
+ to: item.to,
95548
+ items: item.items?.map((sub) => ({
95549
+ label: sub.useTranslation ? t2(sub.label) : sub.label,
95550
+ to: sub.to
95551
+ }))
95552
+ }));
95577
95553
  };
95578
95554
  var Searchbar = () => {
95579
95555
  const { t: t2 } = useTranslation9();
@@ -95614,7 +95590,17 @@ var CoreRouteSection = () => {
95614
95590
  })
95615
95591
  ] });
95616
95592
  };
95617
- var MAIN_MENU_PATHS = ["/companies", "/employees"];
95593
+ var getMainMenuPaths = () => {
95594
+ if (!menuConfig) return [];
95595
+ const config = menuConfig;
95596
+ const paths = [];
95597
+ config.items.forEach((item) => {
95598
+ paths.push(item.to);
95599
+ item.items?.forEach((sub) => paths.push(sub.to));
95600
+ });
95601
+ return paths;
95602
+ };
95603
+ var MAIN_MENU_PATHS = getMainMenuPaths();
95618
95604
  var ExtensionRouteSection = () => {
95619
95605
  const { t: t2 } = useTranslation9();
95620
95606
  const { getMenu } = useExtension();
@@ -95975,7 +95961,7 @@ function getRouteMap({
95975
95961
  children: [
95976
95962
  {
95977
95963
  path: "create",
95978
- lazy: () => import("./product-create-STUQVGHO.mjs")
95964
+ lazy: () => import("./product-create-P26FHFTZ.mjs")
95979
95965
  },
95980
95966
  {
95981
95967
  path: "import",
@@ -95991,7 +95977,7 @@ function getRouteMap({
95991
95977
  path: ":id",
95992
95978
  errorElement: /* @__PURE__ */ jsx17(ErrorBoundary, {}),
95993
95979
  lazy: async () => {
95994
- const { Breadcrumb, loader } = await import("./product-detail-FXEXDNZQ.mjs");
95980
+ const { Breadcrumb, loader } = await import("./product-detail-6VCLGLEL.mjs");
95995
95981
  return {
95996
95982
  Component: Outlet4,
95997
95983
  loader,
@@ -96003,11 +95989,11 @@ function getRouteMap({
96003
95989
  children: [
96004
95990
  {
96005
95991
  path: "",
96006
- lazy: () => import("./product-detail-FXEXDNZQ.mjs"),
95992
+ lazy: () => import("./product-detail-6VCLGLEL.mjs"),
96007
95993
  children: [
96008
95994
  {
96009
95995
  path: "edit",
96010
- lazy: () => import("./product-edit-HLYORUHR.mjs")
95996
+ lazy: () => import("./product-edit-D75EWPGG.mjs")
96011
95997
  },
96012
95998
  {
96013
95999
  path: "edit-variant",
@@ -96019,11 +96005,11 @@ function getRouteMap({
96019
96005
  },
96020
96006
  {
96021
96007
  path: "attributes",
96022
- lazy: () => import("./product-attributes-LGV7337C.mjs")
96008
+ lazy: () => import("./product-attributes-DZZZDS2K.mjs")
96023
96009
  },
96024
96010
  {
96025
96011
  path: "organization",
96026
- lazy: () => import("./product-organization-O5XFMRUA.mjs")
96012
+ lazy: () => import("./product-organization-FESACGNN.mjs")
96027
96013
  },
96028
96014
  {
96029
96015
  path: "shipping-profile",
@@ -15,7 +15,7 @@ import {
15
15
  import {
16
16
  FormExtensionZone,
17
17
  useExtendableForm
18
- } from "./chunk-EZVEBD35.mjs";
18
+ } from "./chunk-ZQVS3F3X.mjs";
19
19
  import "./chunk-2SSUH2HJ.mjs";
20
20
  import "./chunk-ONB3JEHR.mjs";
21
21
  import "./chunk-YCDDT44O.mjs";
@@ -57,7 +57,7 @@ import {
57
57
  import {
58
58
  FormExtensionZone,
59
59
  useExtendableForm
60
- } from "./chunk-EZVEBD35.mjs";
60
+ } from "./chunk-ZQVS3F3X.mjs";
61
61
  import "./chunk-2SSUH2HJ.mjs";
62
62
  import "./chunk-ONB3JEHR.mjs";
63
63
  import "./chunk-YCDDT44O.mjs";
@@ -17,7 +17,7 @@ import {
17
17
  } from "./chunk-GIZFNLKK.mjs";
18
18
  import {
19
19
  getLinkedFields
20
- } from "./chunk-EZVEBD35.mjs";
20
+ } from "./chunk-ZQVS3F3X.mjs";
21
21
  import "./chunk-2SSUH2HJ.mjs";
22
22
  import "./chunk-ONB3JEHR.mjs";
23
23
  import "./chunk-YCDDT44O.mjs";
@@ -18,7 +18,7 @@ import {
18
18
  import {
19
19
  FormExtensionZone,
20
20
  useExtendableForm
21
- } from "./chunk-EZVEBD35.mjs";
21
+ } from "./chunk-ZQVS3F3X.mjs";
22
22
  import "./chunk-2SSUH2HJ.mjs";
23
23
  import "./chunk-ONB3JEHR.mjs";
24
24
  import "./chunk-YCDDT44O.mjs";
@@ -20,7 +20,7 @@ import {
20
20
  import {
21
21
  FormExtensionZone,
22
22
  useExtendableForm
23
- } from "./chunk-EZVEBD35.mjs";
23
+ } from "./chunk-ZQVS3F3X.mjs";
24
24
  import "./chunk-2SSUH2HJ.mjs";
25
25
  import "./chunk-ONB3JEHR.mjs";
26
26
  import "./chunk-YCDDT44O.mjs";
@@ -0,0 +1,21 @@
1
+ import { Plugin } from 'vite';
2
+
3
+ type MenuNestedItem = {
4
+ label: string;
5
+ to: string;
6
+ useTranslation?: boolean;
7
+ };
8
+ type MenuItem = {
9
+ icon: string;
10
+ label: string;
11
+ to: string;
12
+ useTranslation?: boolean;
13
+ items?: MenuNestedItem[];
14
+ };
15
+ type MenuConfig = {
16
+ items: MenuItem[];
17
+ };
18
+
19
+ declare function menuConfigPlugin(): Plugin;
20
+
21
+ export { type MenuConfig, type MenuItem, type MenuNestedItem, menuConfigPlugin };
@@ -0,0 +1,21 @@
1
+ import { Plugin } from 'vite';
2
+
3
+ type MenuNestedItem = {
4
+ label: string;
5
+ to: string;
6
+ useTranslation?: boolean;
7
+ };
8
+ type MenuItem = {
9
+ icon: string;
10
+ label: string;
11
+ to: string;
12
+ useTranslation?: boolean;
13
+ items?: MenuNestedItem[];
14
+ };
15
+ type MenuConfig = {
16
+ items: MenuItem[];
17
+ };
18
+
19
+ declare function menuConfigPlugin(): Plugin;
20
+
21
+ export { type MenuConfig, type MenuItem, type MenuNestedItem, menuConfigPlugin };
@@ -0,0 +1,68 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/vite-plugin/index.ts
31
+ var index_exports = {};
32
+ __export(index_exports, {
33
+ menuConfigPlugin: () => menuConfigPlugin
34
+ });
35
+ module.exports = __toCommonJS(index_exports);
36
+ var import_path = __toESM(require("path"));
37
+ var import_fs = __toESM(require("fs"));
38
+ var VIRTUAL_MODULE_ID = "virtual:dashboard/menu-config";
39
+ var RESOLVED_ID = "\0" + VIRTUAL_MODULE_ID;
40
+ function menuConfigPlugin() {
41
+ return {
42
+ name: "dashboard-menu-config",
43
+ config() {
44
+ return {
45
+ optimizeDeps: {
46
+ exclude: [VIRTUAL_MODULE_ID]
47
+ }
48
+ };
49
+ },
50
+ resolveId(id) {
51
+ if (id === VIRTUAL_MODULE_ID) return RESOLVED_ID;
52
+ },
53
+ load(id) {
54
+ if (id !== RESOLVED_ID) return;
55
+ const basePath = import_path.default.resolve(process.cwd(), "src/admin/menu.config");
56
+ for (const ext of [".ts", ".js", ".mts", ".mjs"]) {
57
+ if (import_fs.default.existsSync(basePath + ext)) {
58
+ return `export { default } from "${basePath + ext}"`;
59
+ }
60
+ }
61
+ return "export default null";
62
+ }
63
+ };
64
+ }
65
+ // Annotate the CommonJS export names for ESM import in node:
66
+ 0 && (module.exports = {
67
+ menuConfigPlugin
68
+ });
@@ -0,0 +1,33 @@
1
+ // src/vite-plugin/index.ts
2
+ import path from "path";
3
+ import fs from "fs";
4
+ var VIRTUAL_MODULE_ID = "virtual:dashboard/menu-config";
5
+ var RESOLVED_ID = "\0" + VIRTUAL_MODULE_ID;
6
+ function menuConfigPlugin() {
7
+ return {
8
+ name: "dashboard-menu-config",
9
+ config() {
10
+ return {
11
+ optimizeDeps: {
12
+ exclude: [VIRTUAL_MODULE_ID]
13
+ }
14
+ };
15
+ },
16
+ resolveId(id) {
17
+ if (id === VIRTUAL_MODULE_ID) return RESOLVED_ID;
18
+ },
19
+ load(id) {
20
+ if (id !== RESOLVED_ID) return;
21
+ const basePath = path.resolve(process.cwd(), "src/admin/menu.config");
22
+ for (const ext of [".ts", ".js", ".mts", ".mjs"]) {
23
+ if (fs.existsSync(basePath + ext)) {
24
+ return `export { default } from "${basePath + ext}"`;
25
+ }
26
+ }
27
+ return "export default null";
28
+ }
29
+ };
30
+ }
31
+ export {
32
+ menuConfigPlugin
33
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mantajs/dashboard",
3
- "version": "0.1.6",
3
+ "version": "0.1.7",
4
4
  "description": "B2B Admin Dashboard for Medusa - Fork of @medusajs/dashboard",
5
5
  "scripts": {
6
6
  "dev": "vite",
@@ -24,6 +24,11 @@
24
24
  "import": "./dist/app.css",
25
25
  "require": "./dist/app.css"
26
26
  },
27
+ "./vite-plugin": {
28
+ "types": "./dist/vite-plugin/index.d.ts",
29
+ "import": "./dist/vite-plugin/index.mjs",
30
+ "require": "./dist/vite-plugin/index.js"
31
+ },
27
32
  "./root": "./",
28
33
  "./package.json": "./package.json"
29
34
  },
@@ -78,14 +83,15 @@
78
83
  "@medusajs/admin-vite-plugin": "2.13.1",
79
84
  "@medusajs/types": "2.13.1",
80
85
  "@medusajs/ui-preset": "2.13.1",
86
+ "@types/node": "^20.0.0",
81
87
  "@vitejs/plugin-react": "^4.0.0",
88
+ "autoprefixer": "^10.4.16",
89
+ "postcss": "^8.4.31",
90
+ "tailwindcss": "^3.3.5",
82
91
  "tsup": "^8.0.0",
83
92
  "typescript": "^5.6.2",
84
93
  "vite": "^5.4.14",
85
94
  "vite-plugin-inspect": "^0.8.0",
86
- "vitest": "^1.0.0",
87
- "autoprefixer": "^10.4.16",
88
- "postcss": "^8.4.31",
89
- "tailwindcss": "^3.3.5"
95
+ "vitest": "^1.0.0"
90
96
  }
91
97
  }
@@ -12,6 +12,7 @@ import {
12
12
  ShoppingCart,
13
13
  SquaresPlus,
14
14
  Tag,
15
+ Users,
15
16
  } from "@medusajs/icons"
16
17
  import { Avatar, Divider, DropdownMenu, Text, clx } from "@medusajs/ui"
17
18
  import { Collapsible as RadixCollapsible } from "radix-ui"
@@ -29,6 +30,20 @@ import { useExtension } from "../../../providers/extension-provider"
29
30
  import { useSearch } from "../../../providers/search-provider"
30
31
  import { UserMenu } from "../user-menu"
31
32
  import { useDocumentDirection } from "../../../hooks/use-document-direction"
33
+ import menuConfig from "virtual:dashboard/menu-config"
34
+ import type { MenuConfig } from "../../../vite-plugin/types"
35
+
36
+ const ICON_MAP: Record<string, React.ReactNode> = {
37
+ ShoppingCart: <ShoppingCart />,
38
+ Tag: <Tag />,
39
+ Buildings: <Buildings />,
40
+ Users: <Users />,
41
+ ReceiptPercent: <ReceiptPercent />,
42
+ CurrencyDollar: <CurrencyDollar />,
43
+ BuildingStorefront: <BuildingStorefront />,
44
+ CogSixTooth: <CogSixTooth />,
45
+ SquaresPlus: <SquaresPlus />,
46
+ }
32
47
 
33
48
  export const MainLayout = () => {
34
49
  return (
@@ -176,75 +191,40 @@ const Header = () => {
176
191
  )
177
192
  }
178
193
 
194
+ const getDefaultMedusaRoutes = (t: (key: string) => string): Omit<INavItem, "pathname">[] => [
195
+ { icon: <ShoppingCart />, label: t("orders.domain"), to: "/orders", items: [] },
196
+ { icon: <Tag />, label: t("products.domain"), to: "/products", items: [
197
+ { label: t("collections.domain"), to: "/collections" },
198
+ { label: t("categories.domain"), to: "/categories" },
199
+ ]},
200
+ { icon: <Buildings />, label: t("inventory.domain"), to: "/inventory", items: [
201
+ { label: t("reservations.domain"), to: "/reservations" },
202
+ ]},
203
+ { icon: <Users />, label: t("customers.domain"), to: "/customers", items: [
204
+ { label: t("customerGroups.domain"), to: "/customer-groups" },
205
+ ]},
206
+ { icon: <ReceiptPercent />, label: t("promotions.domain"), to: "/promotions", items: [
207
+ { label: t("campaigns.domain"), to: "/campaigns" },
208
+ ]},
209
+ { icon: <CurrencyDollar />, label: t("priceLists.domain"), to: "/price-lists" },
210
+ ]
211
+
179
212
  const useCoreRoutes = (): Omit<INavItem, "pathname">[] => {
180
213
  const { t } = useTranslation()
181
214
 
182
- return [
183
- {
184
- icon: <BuildingStorefront />,
185
- label: "Companies",
186
- to: "/companies",
187
- items: [
188
- {
189
- label: "Employees",
190
- to: "/employees",
191
- },
192
- ],
193
- },
194
- {
195
- icon: <ShoppingCart />,
196
- label: t("orders.domain"),
197
- to: "/orders",
198
- items: [],
199
- },
200
- {
201
- icon: <Tag />,
202
- label: t("products.domain"),
203
- to: "/products",
204
- items: [
205
- {
206
- label: t("collections.domain"),
207
- to: "/collections",
208
- },
209
- {
210
- label: t("categories.domain"),
211
- to: "/categories",
212
- },
213
- // TODO: Enable when domin is introduced
214
- // {
215
- // label: t("giftCards.domain"),
216
- // to: "/gift-cards",
217
- // },
218
- ],
219
- },
220
- {
221
- icon: <Buildings />,
222
- label: t("inventory.domain"),
223
- to: "/inventory",
224
- items: [
225
- {
226
- label: t("reservations.domain"),
227
- to: "/reservations",
228
- },
229
- ],
230
- },
231
- {
232
- icon: <ReceiptPercent />,
233
- label: t("promotions.domain"),
234
- to: "/promotions",
235
- items: [
236
- {
237
- label: t("campaigns.domain"),
238
- to: "/campaigns",
239
- },
240
- ],
241
- },
242
- {
243
- icon: <CurrencyDollar />,
244
- label: t("priceLists.domain"),
245
- to: "/price-lists",
246
- },
247
- ]
215
+ if (!menuConfig) {
216
+ return getDefaultMedusaRoutes(t)
217
+ }
218
+
219
+ return (menuConfig as MenuConfig).items.map((item) => ({
220
+ icon: ICON_MAP[item.icon] || <SquaresPlus />,
221
+ label: item.useTranslation ? t(item.label) : item.label,
222
+ to: item.to,
223
+ items: item.items?.map((sub) => ({
224
+ label: sub.useTranslation ? t(sub.label) : sub.label,
225
+ to: sub.to,
226
+ })),
227
+ }))
248
228
  }
249
229
 
250
230
  const Searchbar = () => {
@@ -301,8 +281,19 @@ const CoreRouteSection = () => {
301
281
  )
302
282
  }
303
283
 
304
- // Paths already in the main menu (to avoid duplication in Extensions)
305
- const MAIN_MENU_PATHS = ["/companies", "/employees"]
284
+ // Derived from config: avoids duplication between custom menu and extensions
285
+ const getMainMenuPaths = (): string[] => {
286
+ if (!menuConfig) return []
287
+ const config = menuConfig as MenuConfig
288
+ const paths: string[] = []
289
+ config.items.forEach((item) => {
290
+ paths.push(item.to)
291
+ item.items?.forEach((sub) => paths.push(sub.to))
292
+ })
293
+ return paths
294
+ }
295
+
296
+ const MAIN_MENU_PATHS = getMainMenuPaths()
306
297
 
307
298
  const ExtensionRouteSection = () => {
308
299
  const { t } = useTranslation()
@@ -0,0 +1,5 @@
1
+ declare module "virtual:dashboard/menu-config" {
2
+ import type { MenuConfig } from "../vite-plugin/types"
3
+ const config: MenuConfig | null
4
+ export default config
5
+ }
@@ -0,0 +1,34 @@
1
+ import { Plugin } from "vite"
2
+ import path from "path"
3
+ import fs from "fs"
4
+
5
+ const VIRTUAL_MODULE_ID = "virtual:dashboard/menu-config"
6
+ const RESOLVED_ID = "\0" + VIRTUAL_MODULE_ID
7
+
8
+ export function menuConfigPlugin(): Plugin {
9
+ return {
10
+ name: "dashboard-menu-config",
11
+ config() {
12
+ return {
13
+ optimizeDeps: {
14
+ exclude: [VIRTUAL_MODULE_ID],
15
+ },
16
+ }
17
+ },
18
+ resolveId(id) {
19
+ if (id === VIRTUAL_MODULE_ID) return RESOLVED_ID
20
+ },
21
+ load(id) {
22
+ if (id !== RESOLVED_ID) return
23
+ const basePath = path.resolve(process.cwd(), "src/admin/menu.config")
24
+ for (const ext of [".ts", ".js", ".mts", ".mjs"]) {
25
+ if (fs.existsSync(basePath + ext)) {
26
+ return `export { default } from "${basePath + ext}"`
27
+ }
28
+ }
29
+ return "export default null"
30
+ },
31
+ }
32
+ }
33
+
34
+ export type { MenuConfig, MenuItem, MenuNestedItem } from "./types"
@@ -0,0 +1,17 @@
1
+ export type MenuNestedItem = {
2
+ label: string
3
+ to: string
4
+ useTranslation?: boolean
5
+ }
6
+
7
+ export type MenuItem = {
8
+ icon: string
9
+ label: string
10
+ to: string
11
+ useTranslation?: boolean
12
+ items?: MenuNestedItem[]
13
+ }
14
+
15
+ export type MenuConfig = {
16
+ items: MenuItem[]
17
+ }