@campfire-interactive/shell-header 0.15.0 → 0.15.2

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
@@ -39,6 +39,12 @@ interface AppDefinition {
39
39
  * admin-style apps (e.g. User Management → ['admin', 'owner']).
40
40
  */
41
41
  requiresRole?: string[];
42
+ /**
43
+ * When true, the app is omitted from launcher surfaces — the AppSwitcher
44
+ * dropdown (and the /home launcher should honor it too). For apps reached
45
+ * another way: e.g. DMS, surfaced via the user-menu "Documents" link.
46
+ */
47
+ hideFromLauncher?: boolean;
42
48
  /**
43
49
  * Optional path to append to the app's origin when building tile links
44
50
  * (and the localhost fallback). Omit for apps whose root URL is the
package/dist/index.js CHANGED
@@ -97,15 +97,18 @@ var appCatalog = [
97
97
  },
98
98
  // ── Platform services (available to everyone; no role gate) ─────────────
99
99
  {
100
+ // Header title uses `name`; DMS wants its full name there, and it's hidden
101
+ // from the launcher (reached via the user-menu "Documents" link instead),
102
+ // so `name` carries the full title and `fullName` is dropped (would equal it).
100
103
  id: "dms",
101
- name: "Documents",
102
- fullName: "Document Management",
104
+ name: "Document Management",
103
105
  icon: "Files",
104
106
  letter: "D",
105
107
  color: "#64748b",
106
108
  byline: "Every file in one place \u2014 the platform document store every app reads from and writes to.",
107
109
  group: "apps",
108
- localPort: 3800
110
+ localPort: 3800,
111
+ hideFromLauncher: true
109
112
  },
110
113
  // ── Admin (role-gated; pinned to the end of both surfaces) ──────────────
111
114
  {
@@ -207,7 +210,7 @@ function AppSwitcher({ currentAppId, authorizedApps, currentTenantRole }) {
207
210
  const [open, setOpen] = useState(false);
208
211
  const ref = useRef(null);
209
212
  const visibleApps = appCatalog.filter(
210
- (a) => authorizedApps.includes(a.id) && (!a.requiresRole || currentTenantRole !== void 0 && a.requiresRole.includes(currentTenantRole))
213
+ (a) => authorizedApps.includes(a.id) && !a.hideFromLauncher && (!a.requiresRole || currentTenantRole !== void 0 && a.requiresRole.includes(currentTenantRole))
211
214
  );
212
215
  const orderedApps = [
213
216
  ...visibleApps.filter((a) => a.group !== "admin"),
@@ -840,8 +843,13 @@ async function captureTabScreenshot() {
840
843
  var MAX_ENTRIES = 50;
841
844
  var MAX_MESSAGE_CHARS = 500;
842
845
  var consoleBuffer = [];
843
- var networkBuffer = [];
846
+ var networkFailureBuffer = [];
847
+ var networkSuccessBuffer = [];
844
848
  var installed = false;
849
+ function stripQuery(url) {
850
+ const i = url.indexOf("?");
851
+ return i === -1 ? url : url.slice(0, i);
852
+ }
845
853
  function push(buffer, entry) {
846
854
  buffer.push(entry);
847
855
  if (buffer.length > MAX_ENTRIES) buffer.shift();
@@ -890,7 +898,7 @@ function installBugReportCapture() {
890
898
  try {
891
899
  const res = await originalFetch(input, init);
892
900
  if (!res.ok) {
893
- push(networkBuffer, {
901
+ push(networkFailureBuffer, {
894
902
  at: (/* @__PURE__ */ new Date()).toISOString(),
895
903
  method: method.toUpperCase(),
896
904
  url,
@@ -898,10 +906,19 @@ function installBugReportCapture() {
898
906
  durationMs: Math.round(performance.now() - started),
899
907
  requestId: res.headers.get("x-request-id") ?? void 0
900
908
  });
909
+ } else {
910
+ push(networkSuccessBuffer, {
911
+ at: (/* @__PURE__ */ new Date()).toISOString(),
912
+ method: method.toUpperCase(),
913
+ url: stripQuery(url),
914
+ status: res.status,
915
+ durationMs: Math.round(performance.now() - started),
916
+ requestId: res.headers.get("x-request-id") ?? void 0
917
+ });
901
918
  }
902
919
  return res;
903
920
  } catch (err) {
904
- push(networkBuffer, {
921
+ push(networkFailureBuffer, {
905
922
  at: (/* @__PURE__ */ new Date()).toISOString(),
906
923
  method: method.toUpperCase(),
907
924
  url,
@@ -913,7 +930,10 @@ function installBugReportCapture() {
913
930
  };
914
931
  }
915
932
  function snapshotBugReportCapture() {
916
- return { console: [...consoleBuffer], network: [...networkBuffer] };
933
+ const network = [...networkFailureBuffer, ...networkSuccessBuffer].sort(
934
+ (a, b) => a.at.localeCompare(b.at)
935
+ );
936
+ return { console: [...consoleBuffer], network };
917
937
  }
918
938
 
919
939
  // src/BugReportModal.tsx
@@ -1391,14 +1411,16 @@ function useBugReportShortcut(enabled, onShortcut) {
1391
1411
  function handleKeyDown(e) {
1392
1412
  const platformMod = e.ctrlKey || e.metaKey;
1393
1413
  if (!platformMod || !e.altKey || e.shiftKey) return;
1394
- if (e.code !== "KeyB" && e.key.toLowerCase() !== "b") return;
1414
+ const isB = e.code === "KeyB" || e.key.toLowerCase() === "b";
1415
+ const isS = e.code === "KeyS" || e.key.toLowerCase() === "s";
1416
+ if (!isB && !isS) return;
1395
1417
  const target = e.target;
1396
1418
  if (target) {
1397
1419
  const tag = target.tagName;
1398
1420
  if (tag === "INPUT" || tag === "TEXTAREA" || target.isContentEditable) return;
1399
1421
  }
1400
1422
  e.preventDefault();
1401
- handlerRef.current();
1423
+ handlerRef.current(isS ? "screenshot" : "plain");
1402
1424
  }
1403
1425
  document.addEventListener("keydown", handleKeyDown);
1404
1426
  return () => document.removeEventListener("keydown", handleKeyDown);
@@ -1447,12 +1469,17 @@ function ShellHeader({
1447
1469
  const [bugOpen, setBugOpen] = useState7(false);
1448
1470
  const [bugShot, setBugShot] = useState7(null);
1449
1471
  const bugCaptureBusy = useRef6(false);
1450
- useBugReportShortcut(bugReport !== void 0, () => {
1472
+ useBugReportShortcut(bugReport !== void 0, (variant) => {
1451
1473
  if (bugOpen) {
1452
1474
  setBugOpen(false);
1453
1475
  return;
1454
1476
  }
1455
1477
  if (bugCaptureBusy.current) return;
1478
+ if (variant === "plain") {
1479
+ setBugShot(null);
1480
+ setBugOpen(true);
1481
+ return;
1482
+ }
1456
1483
  bugCaptureBusy.current = true;
1457
1484
  captureTabScreenshot().then((shot) => setBugShot(shot)).catch(() => setBugShot(null)).finally(() => {
1458
1485
  bugCaptureBusy.current = false;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@campfire-interactive/shell-header",
3
- "version": "0.15.0",
3
+ "version": "0.15.2",
4
4
  "description": "Shared shell header with app switcher for Campfire Suite",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",