@eintrek/erp-shell 0.1.49 → 0.1.51
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/index.esm.js +33 -14
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +33 -14
- package/dist/index.js.map +1 -1
- package/dist/lib/plan-features.d.ts +7 -1
- package/dist/navigation/app-sidebar.d.ts +3 -1
- package/dist/navigation/nav-main.d.ts +7 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -977,18 +977,35 @@ const PLAN_FEATURES = {
|
|
|
977
977
|
MODULE_INVENTORY: "module.inventory",
|
|
978
978
|
MODULE_PROJECT: "module.project",
|
|
979
979
|
MODULE_SECRETARIAT: "module.secretariat",
|
|
980
|
+
/** AI pack (paid or trial): AI calls on AntNiti's key while credits remain. */
|
|
981
|
+
AI: "ai",
|
|
980
982
|
};
|
|
981
|
-
/**
|
|
983
|
+
/** Keys the Accounx add-on carries with it (same alias as org_effective_features). */
|
|
984
|
+
const ACCOUNTING_SUB_KEYS = [
|
|
985
|
+
PLAN_FEATURES.MODULE_SALES,
|
|
986
|
+
PLAN_FEATURES.MODULE_PURCHASING,
|
|
987
|
+
PLAN_FEATURES.MODULE_SECRETARIAT,
|
|
988
|
+
];
|
|
989
|
+
/**
|
|
990
|
+
* True when plan features include key. Aliases, mirroring the backend:
|
|
991
|
+
* legacy basic_accounting_hr → module.hr + module.accounting (+ its sub-keys);
|
|
992
|
+
* module.accounting → module.sales, module.purchasing, module.secretariat.
|
|
993
|
+
*/
|
|
982
994
|
function hasPlanFeature(features, feature) {
|
|
983
995
|
if (!features?.length)
|
|
984
996
|
return false;
|
|
985
997
|
if (features.includes(feature))
|
|
986
998
|
return true;
|
|
987
999
|
if ((feature === PLAN_FEATURES.MODULE_HR ||
|
|
988
|
-
feature === PLAN_FEATURES.MODULE_ACCOUNTING
|
|
1000
|
+
feature === PLAN_FEATURES.MODULE_ACCOUNTING ||
|
|
1001
|
+
ACCOUNTING_SUB_KEYS.includes(feature)) &&
|
|
989
1002
|
features.includes(PLAN_FEATURES.BASIC_ACCOUNTING_HR)) {
|
|
990
1003
|
return true;
|
|
991
1004
|
}
|
|
1005
|
+
if (ACCOUNTING_SUB_KEYS.includes(feature) &&
|
|
1006
|
+
features.includes(PLAN_FEATURES.MODULE_ACCOUNTING)) {
|
|
1007
|
+
return true;
|
|
1008
|
+
}
|
|
992
1009
|
if (feature === PLAN_FEATURES.BASIC_ACCOUNTING_HR &&
|
|
993
1010
|
features.includes(PLAN_FEATURES.MODULE_HR) &&
|
|
994
1011
|
features.includes(PLAN_FEATURES.MODULE_ACCOUNTING)) {
|
|
@@ -1012,35 +1029,36 @@ const APPS = [
|
|
|
1012
1029
|
id: "platform",
|
|
1013
1030
|
label: "แพลตฟอร์ม",
|
|
1014
1031
|
icon: jsxRuntime.jsx(lucideReact.Building2, { className: "h-4 w-4 shrink-0" }),
|
|
1015
|
-
|
|
1032
|
+
features: null,
|
|
1016
1033
|
baseUrl: () => normaliseBase(process.env.NEXT_PUBLIC_PLATFORM_URL, "https://platform.antniti.com"),
|
|
1017
1034
|
},
|
|
1018
1035
|
{
|
|
1019
1036
|
id: "accounx",
|
|
1020
1037
|
label: "Accounx",
|
|
1021
1038
|
icon: jsxRuntime.jsx(lucideReact.Calculator, { className: "h-4 w-4 shrink-0" }),
|
|
1022
|
-
|
|
1039
|
+
features: [PLAN_FEATURES.MODULE_ACCOUNTING],
|
|
1023
1040
|
baseUrl: () => normaliseBase(process.env.NEXT_PUBLIC_ACCOUNTING_URL, "https://accounx.antniti.com"),
|
|
1024
1041
|
},
|
|
1025
1042
|
{
|
|
1026
1043
|
id: "invenx",
|
|
1027
1044
|
label: "Invenx",
|
|
1028
1045
|
icon: jsxRuntime.jsx(lucideReact.Warehouse, { className: "h-4 w-4 shrink-0" }),
|
|
1029
|
-
|
|
1046
|
+
features: [PLAN_FEATURES.MODULE_INVENTORY],
|
|
1030
1047
|
baseUrl: () => normaliseBase(process.env.NEXT_PUBLIC_INVENX_URL, "https://invenx.antniti.com"),
|
|
1031
1048
|
},
|
|
1032
1049
|
{
|
|
1033
1050
|
id: "plannex",
|
|
1034
1051
|
label: "Plannex",
|
|
1035
1052
|
icon: jsxRuntime.jsx(lucideReact.FolderKanban, { className: "h-4 w-4 shrink-0" }),
|
|
1036
|
-
|
|
1053
|
+
// Tasks, day-logs and work records are free with HR; projects need the add-on.
|
|
1054
|
+
features: [PLAN_FEATURES.MODULE_HR, PLAN_FEATURES.MODULE_PROJECT],
|
|
1037
1055
|
baseUrl: () => normaliseBase(process.env.NEXT_PUBLIC_PLANNEX_URL, "https://plannex.antniti.com"),
|
|
1038
1056
|
},
|
|
1039
1057
|
{
|
|
1040
1058
|
id: "peoplx",
|
|
1041
1059
|
label: "Peoplx",
|
|
1042
1060
|
icon: jsxRuntime.jsx(lucideReact.Users, { className: "h-4 w-4 shrink-0" }),
|
|
1043
|
-
|
|
1061
|
+
features: [PLAN_FEATURES.MODULE_HR],
|
|
1044
1062
|
baseUrl: () => normaliseBase(process.env.NEXT_PUBLIC_HR_URL, "https://peoplx.antniti.com"),
|
|
1045
1063
|
},
|
|
1046
1064
|
];
|
|
@@ -1055,8 +1073,8 @@ function buildSystemLinks({ orgCode, activeApp, features, }) {
|
|
|
1055
1073
|
if (!orgCode)
|
|
1056
1074
|
return [];
|
|
1057
1075
|
return APPS.filter(app => app.id === activeApp ||
|
|
1058
|
-
app.
|
|
1059
|
-
hasPlanFeature(features,
|
|
1076
|
+
app.features === null ||
|
|
1077
|
+
app.features.some(key => hasPlanFeature(features, key))).map(app => ({
|
|
1060
1078
|
label: app.label,
|
|
1061
1079
|
icon: app.icon,
|
|
1062
1080
|
// Same-app link stays relative so it never leaves the current origin.
|
|
@@ -1090,7 +1108,7 @@ function samePage(pathname, url) {
|
|
|
1090
1108
|
const strip = (p) => (p.length > 1 ? p.replace(/\/+$/, "") : p);
|
|
1091
1109
|
return strip(pathname) === strip(url);
|
|
1092
1110
|
}
|
|
1093
|
-
function NavMain({ items, orgCode, closeOnNavigation = false, approvalCounts, chrome = "brand", }) {
|
|
1111
|
+
function NavMain({ items, orgCode, closeOnNavigation = false, approvalCounts, chrome = "brand", highlightActiveModule = false, }) {
|
|
1094
1112
|
const workspace = chrome === "workspace";
|
|
1095
1113
|
const params = navigation.useParams();
|
|
1096
1114
|
const pathname = navigation.usePathname();
|
|
@@ -1122,8 +1140,9 @@ function NavMain({ items, orgCode, closeOnNavigation = false, approvalCounts, ch
|
|
|
1122
1140
|
isPathActive(pathname, subPage.url)));
|
|
1123
1141
|
// Parent only active when path matches its URL exactly AND no child
|
|
1124
1142
|
// is active (so parent+child don't both light up).
|
|
1125
|
-
const isItemActive = (
|
|
1126
|
-
|
|
1143
|
+
const isItemActive = (highlightActiveModule && !item.subModules?.length && !!item.isActive) ||
|
|
1144
|
+
((workspace ? samePage(pathname, itemUrl) : pathname === itemUrl) &&
|
|
1145
|
+
!hasActiveSubItem);
|
|
1127
1146
|
return { itemUrl, activeSubItemUrl, hasActiveSubItem, isItemActive };
|
|
1128
1147
|
});
|
|
1129
1148
|
// A group opens when its page becomes current and otherwise stays as the
|
|
@@ -1282,7 +1301,7 @@ function SidebarHeader({ children, className }) {
|
|
|
1282
1301
|
return jsxRuntime.jsx("div", { className: erpTheme.cn("px-2 py-3", className), children: children });
|
|
1283
1302
|
}
|
|
1284
1303
|
|
|
1285
|
-
function AppSidebar({ modules, tools, activeModule, orgCode, approvalCounts, closeOnNavigation = false, header, footer, bottom, chrome = "brand", className, }) {
|
|
1304
|
+
function AppSidebar({ modules, tools, activeModule, orgCode, approvalCounts, closeOnNavigation = false, highlightActiveModule = false, header, footer, bottom, chrome = "brand", className, }) {
|
|
1286
1305
|
const { open } = useSidebar();
|
|
1287
1306
|
const modulesWithActiveState = React__namespace.useMemo(() => modules.map(m => ({
|
|
1288
1307
|
...m,
|
|
@@ -1293,7 +1312,7 @@ function AppSidebar({ modules, tools, activeModule, orgCode, approvalCounts, clo
|
|
|
1293
1312
|
if (chrome === "workspace") {
|
|
1294
1313
|
return (jsxRuntime.jsxs("div", { className: erpTheme.cn("flex h-screen w-[244px] shrink-0 flex-col overflow-hidden border-r border-sidebar-border bg-sidebar text-sidebar-foreground",
|
|
1295
1314
|
// As a drawer (≤1024px) it floats over the page and needs the lift.
|
|
1296
|
-
"max-[1024px]:shadow-2xl", className), children: [header ? jsxRuntime.jsx("div", { className: "shrink-0 px-[18px] pt-8 pb-6", children: header }) : null, jsxRuntime.jsxs(SidebarContent, { className: "flex-1 overflow-y-auto px-[18px]", children: [jsxRuntime.jsx(NavMain, { items: modulesWithActiveState, orgCode: orgCode, approvalCounts: approvalCounts, closeOnNavigation: closeOnNavigation, chrome: "workspace" }), jsxRuntime.jsx(NavTools, { tools: tools, closeOnNavigation: closeOnNavigation })] }), bottom ? jsxRuntime.jsx("div", { className: "shrink-0 px-[18px] pt-6", children: bottom }) : null, jsxRuntime.jsx("div", { className: "shrink-0 px-[18px] pb-3", children: footer })] }));
|
|
1315
|
+
"max-[1024px]:shadow-2xl", className), children: [header ? jsxRuntime.jsx("div", { className: "shrink-0 px-[18px] pt-8 pb-6", children: header }) : null, jsxRuntime.jsxs(SidebarContent, { className: "flex-1 overflow-y-auto px-[18px]", children: [jsxRuntime.jsx(NavMain, { items: modulesWithActiveState, orgCode: orgCode, approvalCounts: approvalCounts, closeOnNavigation: closeOnNavigation, chrome: "workspace", highlightActiveModule: highlightActiveModule }), jsxRuntime.jsx(NavTools, { tools: tools, closeOnNavigation: closeOnNavigation })] }), bottom ? jsxRuntime.jsx("div", { className: "shrink-0 px-[18px] pt-6", children: bottom }) : null, jsxRuntime.jsx("div", { className: "shrink-0 px-[18px] pb-3", children: footer })] }));
|
|
1297
1316
|
}
|
|
1298
1317
|
return (jsxRuntime.jsxs("div", { className: erpTheme.cn("bg-sidebar shrink-0 flex flex-col overflow-hidden shadow-2xl h-screen w-[var(--sidebar-width-mobile)]", "!w-76 xl:rounded-b-4xl xl:rounded-tl-4xl xl:m-5 xl:h-[calc(100vh-2.5rem)]", className), children: [jsxRuntime.jsx(SidebarHeader, { children: header }), jsxRuntime.jsxs(SidebarContent, { className: "pl-2 pr-2 flex-1 overflow-y-auto", children: [jsxRuntime.jsx(NavMain, { items: modulesWithActiveState, orgCode: orgCode, approvalCounts: approvalCounts, closeOnNavigation: closeOnNavigation }), jsxRuntime.jsx(NavTools, { tools: tools, closeOnNavigation: closeOnNavigation })] }), jsxRuntime.jsx(SidebarFooter, { className: "pl-2 pr-2", children: footer })] }));
|
|
1299
1318
|
}
|