@campfire-interactive/shell-header 0.5.3 → 0.5.6
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 +14 -1
- package/dist/index.js +7 -13
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -10,6 +10,12 @@ interface AppDefinition {
|
|
|
10
10
|
color: string;
|
|
11
11
|
/** Local dev port (e.g., 3000). Omit if the app doesn't run locally. */
|
|
12
12
|
localPort?: number;
|
|
13
|
+
/**
|
|
14
|
+
* If set, the app tile is only visible when the host passes a
|
|
15
|
+
* `currentTenantRole` that matches one of these values. Used to gate
|
|
16
|
+
* admin-style apps (e.g. User Management → ['admin', 'owner']).
|
|
17
|
+
*/
|
|
18
|
+
requiresRole?: string[];
|
|
13
19
|
}
|
|
14
20
|
interface ShellUser {
|
|
15
21
|
name: string;
|
|
@@ -53,6 +59,13 @@ interface ShellHeaderProps {
|
|
|
53
59
|
user: ShellUser;
|
|
54
60
|
/** App IDs the user is authorized to access in the current tenant */
|
|
55
61
|
authorizedApps: string[];
|
|
62
|
+
/**
|
|
63
|
+
* The user's role in their currently-active tenant (e.g. "admin", "owner",
|
|
64
|
+
* "member"). Apps in the catalog with `requiresRole` are shown only when
|
|
65
|
+
* this matches one of the allowed roles. Hosts typically derive this from
|
|
66
|
+
* `user.tenants.find(t => t.id === user.tenant.id)?.role`.
|
|
67
|
+
*/
|
|
68
|
+
currentTenantRole?: string;
|
|
56
69
|
/** Unread count for the bell badge. */
|
|
57
70
|
notificationCount?: number;
|
|
58
71
|
/**
|
|
@@ -116,7 +129,7 @@ interface ShellHeaderProps {
|
|
|
116
129
|
children?: React.ReactNode;
|
|
117
130
|
}
|
|
118
131
|
|
|
119
|
-
declare function ShellHeader({ appId, user, authorizedApps, notificationCount, onNotificationClick, notifications, onMarkRead, onMarkAllRead, onNotificationItemClick, onLogout, locale, supportedLocales, onLocaleChange, tenant, tenants, onTenantSwitch, brandWidth, children, }: ShellHeaderProps): react_jsx_runtime.JSX.Element;
|
|
132
|
+
declare function ShellHeader({ appId, user, authorizedApps, currentTenantRole, notificationCount, onNotificationClick, notifications, onMarkRead, onMarkAllRead, onNotificationItemClick, onLogout, locale, supportedLocales, onLocaleChange, tenant, tenants, onTenantSwitch, brandWidth, children, }: ShellHeaderProps): react_jsx_runtime.JSX.Element;
|
|
120
133
|
|
|
121
134
|
interface LocaleSwitcherProps {
|
|
122
135
|
currentLocale: string;
|
package/dist/index.js
CHANGED
|
@@ -34,7 +34,7 @@ var appCatalog = [
|
|
|
34
34
|
{ id: "pim", name: "Price Index", icon: "BarChart3", letter: "P", color: "#f97316", localPort: 3300 },
|
|
35
35
|
{ id: "cpq", name: "CPQ", icon: "Calculator", letter: "C", color: "#4f46e5", localPort: 3400 },
|
|
36
36
|
{ id: "omsf", name: "OMSF", icon: "FileText", letter: "O", color: "#0ea5e9", localPort: 3500 },
|
|
37
|
-
{ id: "identity", name: "
|
|
37
|
+
{ id: "identity", name: "User Management", icon: "Shield", letter: "U", color: "#8b5cf6", localPort: 3600, requiresRole: ["admin", "owner"] },
|
|
38
38
|
{ id: "bom", name: "BOM", icon: "Network", letter: "B", color: "#0d9488", localPort: 3700 }
|
|
39
39
|
];
|
|
40
40
|
function getAppUrl(app) {
|
|
@@ -97,10 +97,12 @@ function GridIcon({ size = 20 }) {
|
|
|
97
97
|
|
|
98
98
|
// src/AppSwitcher.tsx
|
|
99
99
|
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
100
|
-
function AppSwitcher({ currentAppId, authorizedApps }) {
|
|
100
|
+
function AppSwitcher({ currentAppId, authorizedApps, currentTenantRole }) {
|
|
101
101
|
const [open, setOpen] = useState(false);
|
|
102
102
|
const ref = useRef(null);
|
|
103
|
-
const visibleApps = appCatalog.filter(
|
|
103
|
+
const visibleApps = appCatalog.filter(
|
|
104
|
+
(a) => authorizedApps.includes(a.id) && (!a.requiresRole || currentTenantRole !== void 0 && a.requiresRole.includes(currentTenantRole))
|
|
105
|
+
);
|
|
104
106
|
useEffect(() => {
|
|
105
107
|
function handleClickOutside(e) {
|
|
106
108
|
if (ref.current && !ref.current.contains(e.target)) {
|
|
@@ -310,15 +312,6 @@ function UserMenu({
|
|
|
310
312
|
setTenantExpanded(false);
|
|
311
313
|
return;
|
|
312
314
|
}
|
|
313
|
-
const target = tenants?.find((t) => t.id === tenantId);
|
|
314
|
-
const targetName = target?.name ?? "this tenant";
|
|
315
|
-
const confirmed = window.confirm(
|
|
316
|
-
`Switch to ${targetName}? Other open suite tabs will reload.`
|
|
317
|
-
);
|
|
318
|
-
if (!confirmed) {
|
|
319
|
-
setTenantExpanded(false);
|
|
320
|
-
return;
|
|
321
|
-
}
|
|
322
315
|
setUpdating(true);
|
|
323
316
|
try {
|
|
324
317
|
await onTenantSwitch(tenantId);
|
|
@@ -449,6 +442,7 @@ function ShellHeader({
|
|
|
449
442
|
appId,
|
|
450
443
|
user,
|
|
451
444
|
authorizedApps,
|
|
445
|
+
currentTenantRole,
|
|
452
446
|
notificationCount,
|
|
453
447
|
onNotificationClick,
|
|
454
448
|
notifications,
|
|
@@ -487,7 +481,7 @@ function ShellHeader({
|
|
|
487
481
|
onItemClick: onNotificationItemClick
|
|
488
482
|
}
|
|
489
483
|
),
|
|
490
|
-
/* @__PURE__ */ jsx5(AppSwitcher, { currentAppId: appId, authorizedApps }),
|
|
484
|
+
/* @__PURE__ */ jsx5(AppSwitcher, { currentAppId: appId, authorizedApps, currentTenantRole }),
|
|
491
485
|
/* @__PURE__ */ jsx5(
|
|
492
486
|
UserMenu,
|
|
493
487
|
{
|