@campfire-interactive/shell-header 0.8.10 → 0.8.13

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 CHANGED
@@ -21,12 +21,16 @@ interface AppDefinition {
21
21
  */
22
22
  byline?: string;
23
23
  /**
24
- * Which launcher section the app appears under. `'apps'` (default) is the
25
- * user's product apps; `'admin'` groups admin surfaces (Master Data, User
26
- * Management) into a separate section that the launcher hides entirely when
27
- * the user can see none of them. Launcher-only.
24
+ * Which launcher section the app appears under, by persona. Product apps use
25
+ * a persona group (`'sales'` / `'sourcing'` / `'planning'` / `'engineering'`);
26
+ * `'admin'` groups admin surfaces (Master Data, User Management) the
27
+ * launcher hides that section entirely when the user can see none of them, and
28
+ * the AppSwitcher pins admin apps to the end. `'apps'` is the legacy/default
29
+ * bucket for anything untagged. Launcher renders one section per group, in
30
+ * the launcher's defined group order; the AppSwitcher renders in catalog
31
+ * array order (non-admin, then admin).
28
32
  */
29
- group?: 'apps' | 'admin';
33
+ group?: 'apps' | 'sales' | 'sourcing' | 'planning' | 'engineering' | 'admin';
30
34
  /** Local dev port (e.g., 3000). Omit if the app doesn't run locally. */
31
35
  localPort?: number;
32
36
  /**
package/dist/index.js CHANGED
@@ -28,6 +28,29 @@ styleInject(".cfi-sh-header {\n display: flex;\n align-items: center;\n heigh
28
28
 
29
29
  // src/appCatalog.ts
30
30
  var appCatalog = [
31
+ // ── Sales & Commercial ──────────────────────────────────────────────────
32
+ {
33
+ id: "omsf",
34
+ name: "Opportunity Management",
35
+ icon: "FileText",
36
+ letter: "O",
37
+ color: "#0ea5e9",
38
+ byline: "Automate RFQ intake, submit to OEMs in one click, & quickly handover awards.",
39
+ group: "sales",
40
+ localPort: 3500
41
+ },
42
+ {
43
+ id: "cpq",
44
+ name: "CPQ",
45
+ fullName: "Cost, Price, Quote",
46
+ icon: "Calculator",
47
+ letter: "C",
48
+ color: "#4f46e5",
49
+ byline: "Know exactly what products cost & make pricing decisions with confidence.",
50
+ group: "sales",
51
+ localPort: 3400
52
+ },
53
+ // ── Sourcing & Supply ───────────────────────────────────────────────────
31
54
  {
32
55
  id: "si",
33
56
  name: "Supplier Intelligence",
@@ -35,19 +58,21 @@ var appCatalog = [
35
58
  letter: "S",
36
59
  color: "#6366f1",
37
60
  byline: "Monitor supplier performance and risk across your supply base.",
61
+ group: "sourcing",
38
62
  localPort: 3e3
39
63
  },
40
64
  {
41
- id: "masterdata",
42
- name: "Master Data",
43
- icon: "Database",
44
- letter: "M",
65
+ id: "pim",
66
+ name: "Price Index",
67
+ fullName: "Price Index Management",
68
+ icon: "BarChart3",
69
+ letter: "P",
45
70
  color: "#f97316",
46
- byline: "Define it once, use it everywhere \u2014 the canonical records every app reads from.",
47
- group: "admin",
48
- requiresRole: ["admin", "owner"],
49
- localPort: 3100
71
+ byline: "Every escalation, automated & accurate. Monitor commodity and material pricing, recover margin when indices move.",
72
+ group: "sourcing",
73
+ localPort: 3300
50
74
  },
75
+ // ── Planning ────────────────────────────────────────────────────────────
51
76
  {
52
77
  id: "forecast",
53
78
  name: "Volume Intelligence",
@@ -55,36 +80,32 @@ var appCatalog = [
55
80
  letter: "V",
56
81
  color: "#10b981",
57
82
  byline: "Know what you'll build before you bid. AI-driven production-volume forecasts you can plan revenue and quotes around.",
83
+ group: "planning",
58
84
  localPort: 3200
59
85
  },
86
+ // ── Engineering ─────────────────────────────────────────────────────────
60
87
  {
61
- id: "pim",
62
- name: "Price Index",
63
- fullName: "Price Index Management",
64
- icon: "BarChart3",
65
- letter: "P",
66
- color: "#f97316",
67
- byline: "Every escalation, automated & accurate. Monitor commodity and material pricing, recover margin when indices move.",
68
- localPort: 3300
69
- },
70
- {
71
- id: "cpq",
72
- name: "CPQ",
73
- fullName: "Cost, Price, Quote",
74
- icon: "Calculator",
75
- letter: "C",
76
- color: "#4f46e5",
77
- byline: "Know exactly what products cost & make pricing decisions with confidence.",
78
- localPort: 3400
88
+ id: "bom",
89
+ name: "BOM",
90
+ fullName: "BOM Management",
91
+ icon: "Network",
92
+ letter: "B",
93
+ color: "#0d9488",
94
+ byline: "Control bill of materials and costs across the program lifecycle.",
95
+ group: "engineering",
96
+ localPort: 3700
79
97
  },
98
+ // ── Admin (role-gated; pinned to the end of both surfaces) ──────────────
80
99
  {
81
- id: "omsf",
82
- name: "Opportunity Management",
83
- icon: "FileText",
84
- letter: "O",
85
- color: "#0ea5e9",
86
- byline: "Automate RFQ intake, submit to OEMs in one click, & quickly handover awards.",
87
- localPort: 3500
100
+ id: "masterdata",
101
+ name: "Master Data",
102
+ icon: "Database",
103
+ letter: "M",
104
+ color: "#f97316",
105
+ byline: "Define it once, use it everywhere \u2014 the canonical records every app reads from.",
106
+ group: "admin",
107
+ requiresRole: ["admin", "owner"],
108
+ localPort: 3100
88
109
  },
89
110
  {
90
111
  id: "identity",
@@ -97,16 +118,6 @@ var appCatalog = [
97
118
  requiresRole: ["admin", "owner"],
98
119
  localPort: 3600,
99
120
  path: "/admin/users"
100
- },
101
- {
102
- id: "bom",
103
- name: "BOM",
104
- fullName: "BOM Management",
105
- icon: "Network",
106
- letter: "B",
107
- color: "#0d9488",
108
- byline: "Control bill of materials and costs across the program lifecycle.",
109
- localPort: 3700
110
121
  }
111
122
  ];
112
123
  function getAppUrl(app) {
@@ -177,6 +188,10 @@ function AppSwitcher({ currentAppId, authorizedApps, currentTenantRole }) {
177
188
  const visibleApps = appCatalog.filter(
178
189
  (a) => authorizedApps.includes(a.id) && (!a.requiresRole || currentTenantRole !== void 0 && a.requiresRole.includes(currentTenantRole))
179
190
  );
191
+ const orderedApps = [
192
+ ...visibleApps.filter((a) => a.group !== "admin"),
193
+ ...visibleApps.filter((a) => a.group === "admin")
194
+ ];
180
195
  useEffect(() => {
181
196
  function handleClickOutside(e) {
182
197
  if (ref.current && !ref.current.contains(e.target)) {
@@ -198,7 +213,7 @@ function AppSwitcher({ currentAppId, authorizedApps, currentTenantRole }) {
198
213
  children: /* @__PURE__ */ jsx2(GridIcon, { size: 20 })
199
214
  }
200
215
  ),
201
- open && /* @__PURE__ */ jsx2("div", { className: "cfi-sh-app-grid", children: visibleApps.map((app) => {
216
+ open && /* @__PURE__ */ jsx2("div", { className: "cfi-sh-app-grid", children: orderedApps.map((app) => {
202
217
  const Icon = getIcon(app.icon);
203
218
  const isCurrent = app.id === currentAppId;
204
219
  return /* @__PURE__ */ jsxs2(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@campfire-interactive/shell-header",
3
- "version": "0.8.10",
3
+ "version": "0.8.13",
4
4
  "description": "Shared shell header with app switcher for Campfire Suite",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",