@eintrek/erp-shell 0.1.38 → 0.1.39
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.d.ts +2 -0
- package/dist/index.esm.js +111 -2
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +112 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/plan-features.d.ts +25 -0
- package/dist/navigation/app-registry.d.ts +19 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -921,6 +921,115 @@ function NavUser({ organization, avatarSrc, profileHref, selectOrganizationHref
|
|
|
921
921
|
reactDom.createPortal(dropdownContent, document.body)] }) }));
|
|
922
922
|
}
|
|
923
923
|
|
|
924
|
+
/**
|
|
925
|
+
* Plan feature keys (billable entitlements). Mirror of platform-apis plan.go.
|
|
926
|
+
*
|
|
927
|
+
* This lives in the shell because every app gates on the same keys, and five
|
|
928
|
+
* private copies of the same list drift: the app-switcher list did exactly
|
|
929
|
+
* that before it moved here.
|
|
930
|
+
*/
|
|
931
|
+
const PLAN_FEATURES = {
|
|
932
|
+
ORG_CHART: "org_chart",
|
|
933
|
+
APPROVAL_WORKFLOW: "approval_workflow",
|
|
934
|
+
API_ACCESS: "api_access",
|
|
935
|
+
SSO: "sso",
|
|
936
|
+
BASIC_ACCOUNTING_HR: "basic_accounting_hr",
|
|
937
|
+
MODULE_PLATFORM: "module.platform",
|
|
938
|
+
MODULE_HR: "module.hr",
|
|
939
|
+
MODULE_ACCOUNTING: "module.accounting",
|
|
940
|
+
MODULE_SALES: "module.sales",
|
|
941
|
+
MODULE_PURCHASING: "module.purchasing",
|
|
942
|
+
MODULE_INVENTORY: "module.inventory",
|
|
943
|
+
MODULE_PROJECT: "module.project",
|
|
944
|
+
MODULE_SECRETARIAT: "module.secretariat",
|
|
945
|
+
};
|
|
946
|
+
/** True when plan features include key (with legacy basic_accounting_hr alias). */
|
|
947
|
+
function hasPlanFeature(features, feature) {
|
|
948
|
+
if (!features?.length)
|
|
949
|
+
return false;
|
|
950
|
+
if (features.includes(feature))
|
|
951
|
+
return true;
|
|
952
|
+
if ((feature === PLAN_FEATURES.MODULE_HR ||
|
|
953
|
+
feature === PLAN_FEATURES.MODULE_ACCOUNTING) &&
|
|
954
|
+
features.includes(PLAN_FEATURES.BASIC_ACCOUNTING_HR)) {
|
|
955
|
+
return true;
|
|
956
|
+
}
|
|
957
|
+
if (feature === PLAN_FEATURES.BASIC_ACCOUNTING_HR &&
|
|
958
|
+
features.includes(PLAN_FEATURES.MODULE_HR) &&
|
|
959
|
+
features.includes(PLAN_FEATURES.MODULE_ACCOUNTING)) {
|
|
960
|
+
return true;
|
|
961
|
+
}
|
|
962
|
+
return false;
|
|
963
|
+
}
|
|
964
|
+
|
|
965
|
+
function normaliseBase(value, fallback) {
|
|
966
|
+
return (value ?? fallback).replace(/\/$/, "");
|
|
967
|
+
}
|
|
968
|
+
/**
|
|
969
|
+
* One list, in display order, for the whole suite.
|
|
970
|
+
*
|
|
971
|
+
* It used to be copied into every app's own nav-user.tsx, which is how Invenx
|
|
972
|
+
* shipped without a link to Plannex: five copies, one of them edited by hand.
|
|
973
|
+
* Adding the sixth app is now a change here plus a version bump.
|
|
974
|
+
*/
|
|
975
|
+
const APPS = [
|
|
976
|
+
{
|
|
977
|
+
id: "platform",
|
|
978
|
+
label: "แพลตฟอร์ม",
|
|
979
|
+
icon: jsxRuntime.jsx(lucideReact.Building2, { className: "h-4 w-4 shrink-0" }),
|
|
980
|
+
feature: null,
|
|
981
|
+
baseUrl: () => normaliseBase(process.env.NEXT_PUBLIC_PLATFORM_URL, "https://platform.antniti.com"),
|
|
982
|
+
},
|
|
983
|
+
{
|
|
984
|
+
id: "accounx",
|
|
985
|
+
label: "Accounx",
|
|
986
|
+
icon: jsxRuntime.jsx(lucideReact.Calculator, { className: "h-4 w-4 shrink-0" }),
|
|
987
|
+
feature: PLAN_FEATURES.MODULE_ACCOUNTING,
|
|
988
|
+
baseUrl: () => normaliseBase(process.env.NEXT_PUBLIC_ACCOUNTING_URL, "https://accounx.antniti.com"),
|
|
989
|
+
},
|
|
990
|
+
{
|
|
991
|
+
id: "invenx",
|
|
992
|
+
label: "Invenx",
|
|
993
|
+
icon: jsxRuntime.jsx(lucideReact.Warehouse, { className: "h-4 w-4 shrink-0" }),
|
|
994
|
+
feature: PLAN_FEATURES.MODULE_INVENTORY,
|
|
995
|
+
baseUrl: () => normaliseBase(process.env.NEXT_PUBLIC_INVENX_URL, "https://invenx.antniti.com"),
|
|
996
|
+
},
|
|
997
|
+
{
|
|
998
|
+
id: "plannex",
|
|
999
|
+
label: "Plannex",
|
|
1000
|
+
icon: jsxRuntime.jsx(lucideReact.FolderKanban, { className: "h-4 w-4 shrink-0" }),
|
|
1001
|
+
feature: PLAN_FEATURES.MODULE_PROJECT,
|
|
1002
|
+
baseUrl: () => normaliseBase(process.env.NEXT_PUBLIC_PLANNEX_URL, "https://plannex.antniti.com"),
|
|
1003
|
+
},
|
|
1004
|
+
{
|
|
1005
|
+
id: "peoplx",
|
|
1006
|
+
label: "Peoplx",
|
|
1007
|
+
icon: jsxRuntime.jsx(lucideReact.Users, { className: "h-4 w-4 shrink-0" }),
|
|
1008
|
+
feature: PLAN_FEATURES.MODULE_HR,
|
|
1009
|
+
baseUrl: () => normaliseBase(process.env.NEXT_PUBLIC_HR_URL, "https://peoplx.antniti.com"),
|
|
1010
|
+
},
|
|
1011
|
+
];
|
|
1012
|
+
/**
|
|
1013
|
+
* Builds the cross-app link list for <NavUser systemLinks>.
|
|
1014
|
+
*
|
|
1015
|
+
* The current app is always present even when the org's plan no longer covers
|
|
1016
|
+
* it — the user is looking at it, so hiding the link would only make the menu
|
|
1017
|
+
* disagree with the screen.
|
|
1018
|
+
*/
|
|
1019
|
+
function buildSystemLinks({ orgCode, activeApp, features, }) {
|
|
1020
|
+
if (!orgCode)
|
|
1021
|
+
return [];
|
|
1022
|
+
return APPS.filter(app => app.id === activeApp ||
|
|
1023
|
+
app.feature === null ||
|
|
1024
|
+
hasPlanFeature(features, app.feature)).map(app => ({
|
|
1025
|
+
label: app.label,
|
|
1026
|
+
icon: app.icon,
|
|
1027
|
+
// Same-app link stays relative so it never leaves the current origin.
|
|
1028
|
+
href: app.id === activeApp ? `/${orgCode}` : `${app.baseUrl()}/${orgCode}`,
|
|
1029
|
+
...(app.id === activeApp ? { active: true } : {}),
|
|
1030
|
+
}));
|
|
1031
|
+
}
|
|
1032
|
+
|
|
924
1033
|
// Helper function to check if pathname matches a URL pattern
|
|
925
1034
|
// This prevents false matches like /reports/sales matching /sales
|
|
926
1035
|
// Handles paths with or without [code] prefix
|
|
@@ -2035,6 +2144,7 @@ exports.NavMain = NavMain;
|
|
|
2035
2144
|
exports.NavTools = NavTools;
|
|
2036
2145
|
exports.NavUser = NavUser;
|
|
2037
2146
|
exports.OrganizationSwitcher = OrganizationSwitcher;
|
|
2147
|
+
exports.PLAN_FEATURES = PLAN_FEATURES;
|
|
2038
2148
|
exports.PermissionGateShell = PermissionGateShell;
|
|
2039
2149
|
exports.PermissionProvider = PermissionProvider;
|
|
2040
2150
|
exports.PermissionRulesProvider = PermissionRulesProvider;
|
|
@@ -2049,6 +2159,7 @@ exports.SidebarTrigger = SidebarTrigger;
|
|
|
2049
2159
|
exports.TapMenu = TapMenu;
|
|
2050
2160
|
exports.ThemeProvider = ThemeProvider;
|
|
2051
2161
|
exports.axiosInstance = instance;
|
|
2162
|
+
exports.buildSystemLinks = buildSystemLinks;
|
|
2052
2163
|
exports.buildUrlWithCode = buildUrlWithCode;
|
|
2053
2164
|
exports.canAccessNavPermissionRoute = canAccessNavPermissionRoute;
|
|
2054
2165
|
exports.clearAccessTokenCache = clearAccessTokenCache;
|
|
@@ -2063,6 +2174,7 @@ exports.getAxiosErrorMessage = getAxiosErrorMessage;
|
|
|
2063
2174
|
exports.getOrganizationId = getOrganizationId;
|
|
2064
2175
|
exports.getQueryClientConfig = getQueryClientConfig;
|
|
2065
2176
|
exports.getRequiredChildGroups = getRequiredChildGroups;
|
|
2177
|
+
exports.hasPlanFeature = hasPlanFeature;
|
|
2066
2178
|
exports.isLikelyTransientNetworkError = isLikelyTransientNetworkError;
|
|
2067
2179
|
exports.isPathActive = isPathActive;
|
|
2068
2180
|
exports.normalizePathnameForPermissionRules = normalizePathnameForPermissionRules;
|