@burdenoff/microfe-devportal 2026.728.2 → 2026.801.1

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.
Files changed (81) hide show
  1. package/dist/__tests__/utils/renderWithProviders.d.ts +1 -1
  2. package/dist/__tests__/utils/renderWithProviders.d.ts.map +1 -1
  3. package/dist/devportal/AdminDevportalRoutes.js +14 -14
  4. package/dist/devportal/AdminDevportalRoutes.js.map +1 -1
  5. package/dist/devportal/DevportalRoutes.js +115 -115
  6. package/dist/devportal/DevportalRoutes.js.map +1 -1
  7. package/dist/devportal/components/SectionNav.js +0 -1
  8. package/dist/devportal/components/SectionNav.js.map +1 -1
  9. package/dist/devportal/components/TelemetryErrorBoundary.js +7 -7
  10. package/dist/devportal/components/TelemetryErrorBoundary.js.map +1 -1
  11. package/dist/devportal/pages/AnalyticsDashboardPage.js +41 -41
  12. package/dist/devportal/pages/AnalyticsDashboardPage.js.map +1 -1
  13. package/dist/devportal/pages/AppLogsPage.js +27 -27
  14. package/dist/devportal/pages/AppLogsPage.js.map +1 -1
  15. package/dist/devportal/pages/ApplicationDetailPage.js +929 -929
  16. package/dist/devportal/pages/ApplicationDetailPage.js.map +1 -1
  17. package/dist/devportal/pages/ApplicationVersionsPage.js +39 -39
  18. package/dist/devportal/pages/ApplicationVersionsPage.js.map +1 -1
  19. package/dist/devportal/pages/CreateWebhookPage.js +55 -55
  20. package/dist/devportal/pages/CreateWebhookPage.js.map +1 -1
  21. package/dist/devportal/pages/EditApplicationPage.js +36 -36
  22. package/dist/devportal/pages/EditApplicationPage.js.map +1 -1
  23. package/dist/devportal/pages/EditPhysicalItemPage.js +40 -40
  24. package/dist/devportal/pages/EditPhysicalItemPage.js.map +1 -1
  25. package/dist/devportal/pages/InvitationDecisionPage.js +25 -25
  26. package/dist/devportal/pages/InvitationDecisionPage.js.map +1 -1
  27. package/dist/devportal/pages/ListingPreviewPage.js +36 -36
  28. package/dist/devportal/pages/ListingPreviewPage.js.map +1 -1
  29. package/dist/devportal/pages/OAuthCallbackPage.js +10 -10
  30. package/dist/devportal/pages/OAuthCallbackPage.js.map +1 -1
  31. package/dist/devportal/pages/OAuthClientDetailPage.js +27 -27
  32. package/dist/devportal/pages/OAuthClientDetailPage.js.map +1 -1
  33. package/dist/devportal/pages/OrganizationDetailPage.js +329 -329
  34. package/dist/devportal/pages/OrganizationDetailPage.js.map +1 -1
  35. package/dist/devportal/pages/OrganizationMembersPage.js +181 -181
  36. package/dist/devportal/pages/OrganizationMembersPage.js.map +1 -1
  37. package/dist/devportal/pages/PublishPage.js +43 -43
  38. package/dist/devportal/pages/PublishPage.js.map +1 -1
  39. package/dist/devportal/pages/RevenueDashboardPage.js +65 -65
  40. package/dist/devportal/pages/RevenueDashboardPage.js.map +1 -1
  41. package/dist/devportal/pages/StoreSubmissionPage.js +126 -126
  42. package/dist/devportal/pages/StoreSubmissionPage.js.map +1 -1
  43. package/dist/devportal/pages/WebhookDetailPage.js +28 -28
  44. package/dist/devportal/pages/WebhookDetailPage.js.map +1 -1
  45. package/dist/devportal/pages/WebhooksPage.js +47 -47
  46. package/dist/devportal/pages/WebhooksPage.js.map +1 -1
  47. package/dist/devportal/providers/DevportalProvider.js +12 -12
  48. package/dist/devportal/providers/DevportalProvider.js.map +1 -1
  49. package/dist/node_modules/react-router/dist/production/lib/components.js +124 -0
  50. package/dist/node_modules/react-router/dist/production/lib/components.js.map +1 -0
  51. package/dist/node_modules/react-router/dist/production/lib/context.js +32 -0
  52. package/dist/node_modules/react-router/dist/production/lib/context.js.map +1 -0
  53. package/dist/node_modules/react-router/dist/production/lib/dom/dom.js +83 -0
  54. package/dist/node_modules/react-router/dist/production/lib/dom/dom.js.map +1 -0
  55. package/dist/node_modules/react-router/dist/production/lib/dom/lib.js +358 -0
  56. package/dist/node_modules/react-router/dist/production/lib/dom/lib.js.map +1 -0
  57. package/dist/node_modules/react-router/dist/production/lib/dom/ssr/components.js +188 -0
  58. package/dist/node_modules/react-router/dist/production/lib/dom/ssr/components.js.map +1 -0
  59. package/dist/node_modules/react-router/dist/production/lib/dom/ssr/invariant.js +8 -0
  60. package/dist/node_modules/react-router/dist/production/lib/dom/ssr/invariant.js.map +1 -0
  61. package/dist/node_modules/react-router/dist/production/lib/dom/ssr/links.js +75 -0
  62. package/dist/node_modules/react-router/dist/production/lib/dom/ssr/links.js.map +1 -0
  63. package/dist/node_modules/react-router/dist/production/lib/dom/ssr/markup.js +15 -0
  64. package/dist/node_modules/react-router/dist/production/lib/dom/ssr/markup.js.map +1 -0
  65. package/dist/node_modules/react-router/dist/production/lib/dom/ssr/routeModules.js +18 -0
  66. package/dist/node_modules/react-router/dist/production/lib/dom/ssr/routeModules.js.map +1 -0
  67. package/dist/node_modules/react-router/dist/production/lib/dom/ssr/single-fetch.js +10 -0
  68. package/dist/node_modules/react-router/dist/production/lib/dom/ssr/single-fetch.js.map +1 -0
  69. package/dist/node_modules/react-router/dist/production/lib/errors.js +19 -0
  70. package/dist/node_modules/react-router/dist/production/lib/errors.js.map +1 -0
  71. package/dist/node_modules/react-router/dist/production/lib/hooks.js +296 -0
  72. package/dist/node_modules/react-router/dist/production/lib/hooks.js.map +1 -0
  73. package/dist/node_modules/react-router/dist/production/lib/router/history.js +166 -0
  74. package/dist/node_modules/react-router/dist/production/lib/router/history.js.map +1 -0
  75. package/dist/node_modules/react-router/dist/production/lib/router/router.js +33 -0
  76. package/dist/node_modules/react-router/dist/production/lib/router/router.js.map +1 -0
  77. package/dist/node_modules/react-router/dist/production/lib/router/url.js +9 -0
  78. package/dist/node_modules/react-router/dist/production/lib/router/url.js.map +1 -0
  79. package/dist/node_modules/react-router/dist/production/lib/router/utils.js +236 -0
  80. package/dist/node_modules/react-router/dist/production/lib/router/utils.js.map +1 -0
  81. package/package.json +3 -3
@@ -1,17 +1,17 @@
1
- import { useDevportal as e } from "../providers/DevportalProvider.js";
2
- import { EmptyState as t } from "../components/EmptyState.js";
3
- import { useGetApplicationAuditLogsQuery as n } from "../../generated/global-operations.js";
4
- import { getErrorMessage as r } from "../hooks/useGraphQL.js";
5
- import { PageLayout as i, PageSection as a } from "../components/PageLayout.js";
1
+ import { useParams as e } from "../../node_modules/react-router/dist/production/lib/hooks.js";
2
+ import { useDevportal as t } from "../providers/DevportalProvider.js";
3
+ import { EmptyState as n } from "../components/EmptyState.js";
4
+ import { useGetApplicationAuditLogsQuery as r } from "../../generated/global-operations.js";
5
+ import { getErrorMessage as i } from "../hooks/useGraphQL.js";
6
+ import { PageLayout as a, PageSection as o } from "../components/PageLayout.js";
6
7
  import "../hooks/index.js";
7
- import o from "../../node_modules/date-fns/format.js";
8
- import { useEffect as s, useMemo as c, useState as l } from "react";
9
- import { useI18n as u } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
10
- import { AlertCircle as d, Download as f, Filter as p, Loader2 as m, RefreshCw as h } from "lucide-react";
11
- import { useParams as g } from "react-router-dom";
8
+ import s from "../../node_modules/date-fns/format.js";
9
+ import { useEffect as c, useMemo as l, useState as u } from "react";
10
+ import { useI18n as d } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
11
+ import { AlertCircle as f, Download as p, Filter as m, Loader2 as h, RefreshCw as g } from "lucide-react";
12
12
  import { jsx as _, jsxs as v } from "react/jsx-runtime";
13
13
  //#region src/devportal/pages/AppLogsPage.tsx
14
- var y = 25, b = (e) => o(new Date(e), "MMM d, yyyy HH:mm:ss"), x = (e) => e.replace(/_/g, " ").toLowerCase().replace(/\b\w/g, (e) => e.toUpperCase()), S = (e) => {
14
+ var y = 25, b = (e) => s(new Date(e), "MMM d, yyyy HH:mm:ss"), x = (e) => e.replace(/_/g, " ").toLowerCase().replace(/\b\w/g, (e) => e.toUpperCase()), S = (e) => {
15
15
  if (!e) return "";
16
16
  try {
17
17
  return JSON.stringify(e, null, 2);
@@ -19,7 +19,7 @@ var y = 25, b = (e) => o(new Date(e), "MMM d, yyyy HH:mm:ss"), x = (e) => e.repl
19
19
  return "";
20
20
  }
21
21
  }, C = () => {
22
- let { t: o } = u(), { appId: C } = g(), { navigate: w, basePath: T, currentUser: E } = e(), D = (e) => E?.id === e && E.email ? E.email : e, [O, k] = l("all"), [A, j] = l(""), [M, N] = l(1), { data: P, loading: F, error: I, refetch: L } = n({
22
+ let { t: s } = d(), { appId: C } = e(), { navigate: w, basePath: T, currentUser: E } = t(), D = (e) => E?.id === e && E.email ? E.email : e, [O, k] = u("all"), [A, j] = u(""), [M, N] = u(1), { data: P, loading: F, error: I, refetch: L } = r({
23
23
  variables: {
24
24
  applicationId: C || "",
25
25
  limit: y,
@@ -28,13 +28,13 @@ var y = 25, b = (e) => o(new Date(e), "MMM d, yyyy HH:mm:ss"), x = (e) => e.repl
28
28
  skip: !C,
29
29
  fetchPolicy: "cache-and-network"
30
30
  }), R = P?.application;
31
- s(() => {
31
+ c(() => {
32
32
  let e = R?.name;
33
33
  if (!C || !e) return;
34
34
  let t = window.__breadcrumbRegistry;
35
35
  return t?.register(C, e), () => t?.unregister(C);
36
36
  }, [C, R?.name]);
37
- let z = P?.auditLogs?.totalCount ?? 0, B = P?.auditLogs?.edges?.map((e) => e.node) ?? [], V = c(() => Array.from(new Set(B.map((e) => e.action))).sort((e, t) => e.localeCompare(t)), [B]), H = c(() => {
37
+ let z = P?.auditLogs?.totalCount ?? 0, B = P?.auditLogs?.edges?.map((e) => e.node) ?? [], V = l(() => Array.from(new Set(B.map((e) => e.action))).sort((e, t) => e.localeCompare(t)), [B]), H = l(() => {
38
38
  let e = A.trim().toLowerCase();
39
39
  return B.filter((t) => O === "all" || t.action === O ? e ? [
40
40
  t.action,
@@ -48,29 +48,29 @@ var y = 25, b = (e) => o(new Date(e), "MMM d, yyyy HH:mm:ss"), x = (e) => e.repl
48
48
  B,
49
49
  A
50
50
  ]);
51
- return F && !P ? /* @__PURE__ */ _(i, {
51
+ return F && !P ? /* @__PURE__ */ _(a, {
52
52
  title: "Application Activity",
53
53
  description: "Loading application audit history",
54
54
  backLink: C ? `/apps/${C}` : "/apps",
55
55
  backLabel: "Back to Application",
56
56
  children: /* @__PURE__ */ _("div", {
57
57
  className: "flex items-center justify-center py-16 text-text-secondary",
58
- children: /* @__PURE__ */ _(m, { className: "h-8 w-8 animate-spin" })
58
+ children: /* @__PURE__ */ _(h, { className: "h-8 w-8 animate-spin" })
59
59
  })
60
- }) : I || !R ? /* @__PURE__ */ _(i, {
60
+ }) : I || !R ? /* @__PURE__ */ _(a, {
61
61
  title: "Application Activity",
62
62
  description: "Review audit events for this application",
63
63
  backLink: C ? `/apps/${C}` : "/apps",
64
64
  backLabel: "Back to Application",
65
- children: /* @__PURE__ */ _(t, {
66
- icon: /* @__PURE__ */ _(d, {
65
+ children: /* @__PURE__ */ _(n, {
66
+ icon: /* @__PURE__ */ _(f, {
67
67
  size: 32,
68
68
  className: "text-status-error-text"
69
69
  }),
70
70
  title: "Unable to load activity",
71
- description: I ? r(I) : "Application not found"
71
+ description: I ? i(I) : "Application not found"
72
72
  })
73
- }) : /* @__PURE__ */ v(i, {
73
+ }) : /* @__PURE__ */ v(a, {
74
74
  title: "Application Activity",
75
75
  description: `Audit events for ${R.name}`,
76
76
  purpose: "A chronological audit trail of everything that happened to this app — config changes, secret rotations, webhook deliveries, and access events. Use it to debug integrations and to answer 'who changed what, and when?'",
@@ -82,7 +82,7 @@ var y = 25, b = (e) => o(new Date(e), "MMM d, yyyy HH:mm:ss"), x = (e) => e.repl
82
82
  type: "button",
83
83
  onClick: () => void L(),
84
84
  className: "inline-flex items-center gap-2 rounded-md border px-3 py-2 text-sm font-medium hover:bg-accent",
85
- children: [/* @__PURE__ */ _(h, { size: 16 }), "Refresh"]
85
+ children: [/* @__PURE__ */ _(g, { size: 16 }), "Refresh"]
86
86
  }), /* @__PURE__ */ v("button", {
87
87
  type: "button",
88
88
  onClick: () => {
@@ -90,7 +90,7 @@ var y = 25, b = (e) => o(new Date(e), "MMM d, yyyy HH:mm:ss"), x = (e) => e.repl
90
90
  n.href = t, n.download = `${R?.slug || C || "application"}-audit-log.json`, n.click(), URL.revokeObjectURL(t);
91
91
  },
92
92
  className: "inline-flex items-center gap-2 rounded-md border px-3 py-2 text-sm font-medium hover:bg-accent",
93
- children: [/* @__PURE__ */ _(f, { size: 16 }), "Export JSON"]
93
+ children: [/* @__PURE__ */ _(p, { size: 16 }), "Export JSON"]
94
94
  })]
95
95
  }),
96
96
  children: [
@@ -101,7 +101,7 @@ var y = 25, b = (e) => o(new Date(e), "MMM d, yyyy HH:mm:ss"), x = (e) => e.repl
101
101
  className: "grid gap-2 text-sm font-medium",
102
102
  children: [/* @__PURE__ */ v("span", {
103
103
  className: "flex items-center gap-2 text-text-secondary",
104
- children: [/* @__PURE__ */ _(p, { size: 16 }), "Filter by action"]
104
+ children: [/* @__PURE__ */ _(m, { size: 16 }), "Filter by action"]
105
105
  }), /* @__PURE__ */ v("select", {
106
106
  value: O,
107
107
  onChange: (e) => k(e.target.value),
@@ -134,7 +134,7 @@ var y = 25, b = (e) => o(new Date(e), "MMM d, yyyy HH:mm:ss"), x = (e) => e.repl
134
134
  })
135
135
  ]
136
136
  }),
137
- /* @__PURE__ */ _(a, { children: H.length > 0 ? /* @__PURE__ */ _("div", {
137
+ /* @__PURE__ */ _(o, { children: H.length > 0 ? /* @__PURE__ */ _("div", {
138
138
  className: "space-y-3 rounded-card border border-border-seam bg-bg-surface p-4",
139
139
  children: H.map((e) => /* @__PURE__ */ v("article", {
140
140
  className: "rounded-card border border-border-seam bg-bg-surface p-4",
@@ -181,7 +181,7 @@ var y = 25, b = (e) => o(new Date(e), "MMM d, yyyy HH:mm:ss"), x = (e) => e.repl
181
181
  })
182
182
  ]
183
183
  }, e.id))
184
- }) : /* @__PURE__ */ _(t, {
184
+ }) : /* @__PURE__ */ _(n, {
185
185
  illustration: "empty-data",
186
186
  title: "No audit events found",
187
187
  description: "Events will appear here after application or webhook actions are performed through the public gateway."
@@ -192,7 +192,7 @@ var y = 25, b = (e) => o(new Date(e), "MMM d, yyyy HH:mm:ss"), x = (e) => e.repl
192
192
  type: "button",
193
193
  onClick: () => N((e) => e + 1),
194
194
  className: "inline-flex items-center gap-2 rounded-md border px-4 py-2 text-sm font-medium hover:bg-accent",
195
- children: [/* @__PURE__ */ _(h, { size: 16 }), "Next page"]
195
+ children: [/* @__PURE__ */ _(g, { size: 16 }), "Next page"]
196
196
  })
197
197
  })
198
198
  ]
@@ -1 +1 @@
1
- {"version":3,"file":"AppLogsPage.js","names":[],"sources":["../../../src/devportal/pages/AppLogsPage.tsx"],"sourcesContent":["import type { FC } from \"react\";\nimport { useEffect, useMemo, useState } from \"react\";\nimport { useParams } from \"react-router-dom\";\nimport { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell/I18nProvider\";\nimport {\n Download,\n Filter,\n Loader2,\n RefreshCw,\n AlertCircle,\n FileClock,\n} from \"lucide-react\";\nimport { format } from \"date-fns\";\nimport { PageLayout, PageSection } from \"../components/PageLayout\";\nimport { EmptyState } from \"../components/EmptyState\";\nimport { useDevportal } from \"../providers/DevportalProvider\";\nimport {\n type GetApplicationAuditLogsQuery,\n getErrorMessage,\n useGetApplicationAuditLogsQuery,\n} from \"../hooks\";\n\nconst PAGE_SIZE = 25;\ntype AuditLogEntry =\n GetApplicationAuditLogsQuery[\"auditLogs\"][\"edges\"][number][\"node\"];\n\nconst formatTimestamp = (value: string) =>\n format(new Date(value), \"MMM d, yyyy HH:mm:ss\");\n\nconst formatAction = (value: string) =>\n value\n .replace(/_/g, \" \")\n .toLowerCase()\n .replace(/\\b\\w/g, (character) => character.toUpperCase());\n\nconst metadataPreview = (metadata: unknown): string => {\n if (!metadata) return \"\";\n\n try {\n return JSON.stringify(metadata, null, 2);\n } catch {\n return \"\";\n }\n};\n\nexport const AppLogsPage: FC = () => {\n const { t } = useI18n();\n const tr = (key: string, fallback: string): string => {\n const value = t(key);\n return value === key ? fallback : value;\n };\n const { appId } = useParams<{ appId: string }>();\n const { navigate, basePath, currentUser } = useDevportal();\n const resolveActorLabel = (actorId: string): string => {\n if (currentUser?.id === actorId && currentUser.email)\n return currentUser.email;\n return actorId;\n };\n const [actionFilter, setActionFilter] = useState(\"all\");\n const [searchQuery, setSearchQuery] = useState(\"\");\n const [page, setPage] = useState(1);\n\n const { data, loading, error, refetch } = useGetApplicationAuditLogsQuery({\n variables: {\n applicationId: appId || \"\",\n limit: PAGE_SIZE,\n offset: (page - 1) * PAGE_SIZE,\n },\n skip: !appId,\n fetchPolicy: \"cache-and-network\",\n });\n\n const application = data?.application;\n\n useEffect(() => {\n const name = application?.name;\n if (!appId || !name) return;\n const reg = (\n window as unknown as {\n __breadcrumbRegistry?: {\n register: (id: string, name: string) => void;\n unregister: (id: string) => void;\n };\n }\n ).__breadcrumbRegistry;\n reg?.register(appId, name);\n return () => reg?.unregister(appId);\n }, [appId, application?.name]);\n\n const totalCount = data?.auditLogs?.totalCount ?? 0;\n const auditLogs: AuditLogEntry[] =\n data?.auditLogs?.edges?.map(\n (edge: GetApplicationAuditLogsQuery[\"auditLogs\"][\"edges\"][number]) =>\n edge.node,\n ) ?? [];\n\n const availableActions = useMemo(\n () =>\n Array.from(\n new Set(auditLogs.map((entry: AuditLogEntry) => entry.action)),\n ).sort((left, right) => left.localeCompare(right)),\n [auditLogs],\n );\n\n const filteredLogs = useMemo(() => {\n const normalizedQuery = searchQuery.trim().toLowerCase();\n\n return auditLogs.filter((entry: AuditLogEntry) => {\n const matchesAction =\n actionFilter === \"all\" || entry.action === actionFilter;\n if (!matchesAction) return false;\n\n if (!normalizedQuery) return true;\n\n const haystack = [\n entry.action,\n entry.actorId,\n resolveActorLabel(entry.actorId),\n entry.resource,\n metadataPreview(entry.metadata),\n ]\n .join(\" \")\n .toLowerCase();\n\n return haystack.includes(normalizedQuery);\n });\n }, [actionFilter, auditLogs, searchQuery]);\n\n const exportPayload = () => {\n const blob = new Blob([JSON.stringify(filteredLogs, null, 2)], {\n type: \"application/json\",\n });\n const url = URL.createObjectURL(blob);\n const anchor = document.createElement(\"a\");\n anchor.href = url;\n anchor.download = `${application?.slug || appId || \"application\"}-audit-log.json`;\n anchor.click();\n URL.revokeObjectURL(url);\n };\n\n if (loading && !data) {\n return (\n <PageLayout\n title=\"Application Activity\"\n description=\"Loading application audit history\"\n backLink={appId ? `/apps/${appId}` : \"/apps\"}\n backLabel=\"Back to Application\"\n >\n <div className=\"flex items-center justify-center py-16 text-text-secondary\">\n <Loader2 className=\"h-8 w-8 animate-spin\" />\n </div>\n </PageLayout>\n );\n }\n\n if (error || !application) {\n return (\n <PageLayout\n title=\"Application Activity\"\n description=\"Review audit events for this application\"\n backLink={appId ? `/apps/${appId}` : \"/apps\"}\n backLabel=\"Back to Application\"\n >\n <EmptyState\n icon={<AlertCircle size={32} className=\"text-status-error-text\" />}\n title=\"Unable to load activity\"\n description={error ? getErrorMessage(error) : \"Application not found\"}\n />\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n title=\"Application Activity\"\n description={`Audit events for ${application.name}`}\n purpose=\"A chronological audit trail of everything that happened to this app — config changes, secret rotations, webhook deliveries, and access events. Use it to debug integrations and to answer 'who changed what, and when?'\"\n backLink={`/apps/${application.id}`}\n backLabel=\"Back to Application\"\n actions={\n <div className=\"flex flex-wrap gap-2\">\n <button\n type=\"button\"\n onClick={() => void refetch()}\n className=\"inline-flex items-center gap-2 rounded-md border px-3 py-2 text-sm font-medium hover:bg-accent\"\n >\n <RefreshCw size={16} />\n Refresh\n </button>\n <button\n type=\"button\"\n onClick={exportPayload}\n className=\"inline-flex items-center gap-2 rounded-md border px-3 py-2 text-sm font-medium hover:bg-accent\"\n >\n <Download size={16} />\n Export JSON\n </button>\n </div>\n }\n >\n <div className=\"grid gap-4 rounded-card border border-border-seam bg-bg-surface p-4 lg:grid-cols-[220px_minmax(0,1fr)_auto] lg:items-center\">\n <label className=\"grid gap-2 text-sm font-medium\">\n <span className=\"flex items-center gap-2 text-text-secondary\">\n <Filter size={16} />\n Filter by action\n </span>\n <select\n value={actionFilter}\n onChange={(event) => setActionFilter(event.target.value)}\n className=\"rounded-md border bg-bg-surface px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-primary\"\n >\n <option value=\"all\">All actions</option>\n {availableActions.map((action) => (\n <option key={action} value={action}>\n {formatAction(action)}\n </option>\n ))}\n </select>\n </label>\n\n <label className=\"grid gap-2 text-sm font-medium\">\n <span className=\"text-text-secondary\">Search metadata</span>\n <input\n type=\"text\"\n value={searchQuery}\n onChange={(event) => setSearchQuery(event.target.value)}\n placeholder=\"Search actor, action, or metadata\"\n className=\"rounded-md border bg-bg-surface px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-primary\"\n />\n </label>\n\n <div className=\"rounded-full bg-bg-sunken px-3 py-2 text-sm text-text-secondary\">\n {totalCount} total events\n </div>\n </div>\n\n <PageSection>\n {filteredLogs.length > 0 ? (\n <div className=\"space-y-3 rounded-card border border-border-seam bg-bg-surface p-4\">\n {filteredLogs.map((entry: AuditLogEntry) => (\n <article\n key={entry.id}\n className=\"rounded-card border border-border-seam bg-bg-surface p-4\"\n >\n <div className=\"flex flex-col gap-3 lg:flex-row lg:items-start lg:justify-between\">\n <div className=\"space-y-2\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <span className=\"rounded-full bg-action-primary-bg/10 px-2.5 py-1 text-xs font-medium text-primary\">\n {formatAction(entry.action)}\n </span>\n <span className=\"text-xs text-text-secondary\">\n Actor {resolveActorLabel(entry.actorId)}\n </span>\n </div>\n <p className=\"text-sm text-text-secondary\">\n Resource: {entry.resource}\n {entry.resourceId ? ` · ${entry.resourceId}` : \"\"}\n </p>\n </div>\n\n <time className=\"text-xs text-text-secondary\">\n {formatTimestamp(entry.createdAt)}\n </time>\n </div>\n\n {entry.metadata && (\n <pre className=\"mt-3 overflow-x-auto rounded-md bg-bg-sunken p-3 text-xs text-text-primary\">\n {metadataPreview(entry.metadata)}\n </pre>\n )}\n\n {entry.changes && (\n <details className=\"mt-3 rounded-md border bg-bg-surface p-3\">\n <summary className=\"cursor-pointer text-sm font-medium text-text-primary\">\n View captured changes\n </summary>\n <pre className=\"mt-3 overflow-x-auto text-xs text-text-secondary\">\n {metadataPreview(entry.changes)}\n </pre>\n </details>\n )}\n </article>\n ))}\n </div>\n ) : (\n <EmptyState\n illustration=\"empty-data\"\n title=\"No audit events found\"\n description=\"Events will appear here after application or webhook actions are performed through the public gateway.\"\n />\n )}\n </PageSection>\n\n {data.auditLogs?.pageInfo?.hasNextPage && (\n <div className=\"flex justify-center\">\n <button\n type=\"button\"\n onClick={() => setPage((previous) => previous + 1)}\n className=\"inline-flex items-center gap-2 rounded-md border px-4 py-2 text-sm font-medium hover:bg-accent\"\n >\n <RefreshCw size={16} />\n Next page\n </button>\n </div>\n )}\n </PageLayout>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"AppLogsPage.js","names":[],"sources":["../../../src/devportal/pages/AppLogsPage.tsx"],"sourcesContent":["import type { FC } from \"react\";\nimport { useEffect, useMemo, useState } from \"react\";\nimport { useParams } from \"react-router\";\nimport { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell/I18nProvider\";\nimport {\n Download,\n Filter,\n Loader2,\n RefreshCw,\n AlertCircle,\n FileClock,\n} from \"lucide-react\";\nimport { format } from \"date-fns\";\nimport { PageLayout, PageSection } from \"../components/PageLayout\";\nimport { EmptyState } from \"../components/EmptyState\";\nimport { useDevportal } from \"../providers/DevportalProvider\";\nimport {\n type GetApplicationAuditLogsQuery,\n getErrorMessage,\n useGetApplicationAuditLogsQuery,\n} from \"../hooks\";\n\nconst PAGE_SIZE = 25;\ntype AuditLogEntry =\n GetApplicationAuditLogsQuery[\"auditLogs\"][\"edges\"][number][\"node\"];\n\nconst formatTimestamp = (value: string) =>\n format(new Date(value), \"MMM d, yyyy HH:mm:ss\");\n\nconst formatAction = (value: string) =>\n value\n .replace(/_/g, \" \")\n .toLowerCase()\n .replace(/\\b\\w/g, (character) => character.toUpperCase());\n\nconst metadataPreview = (metadata: unknown): string => {\n if (!metadata) return \"\";\n\n try {\n return JSON.stringify(metadata, null, 2);\n } catch {\n return \"\";\n }\n};\n\nexport const AppLogsPage: FC = () => {\n const { t } = useI18n();\n const tr = (key: string, fallback: string): string => {\n const value = t(key);\n return value === key ? fallback : value;\n };\n const { appId } = useParams<{ appId: string }>();\n const { navigate, basePath, currentUser } = useDevportal();\n const resolveActorLabel = (actorId: string): string => {\n if (currentUser?.id === actorId && currentUser.email)\n return currentUser.email;\n return actorId;\n };\n const [actionFilter, setActionFilter] = useState(\"all\");\n const [searchQuery, setSearchQuery] = useState(\"\");\n const [page, setPage] = useState(1);\n\n const { data, loading, error, refetch } = useGetApplicationAuditLogsQuery({\n variables: {\n applicationId: appId || \"\",\n limit: PAGE_SIZE,\n offset: (page - 1) * PAGE_SIZE,\n },\n skip: !appId,\n fetchPolicy: \"cache-and-network\",\n });\n\n const application = data?.application;\n\n useEffect(() => {\n const name = application?.name;\n if (!appId || !name) return;\n const reg = (\n window as unknown as {\n __breadcrumbRegistry?: {\n register: (id: string, name: string) => void;\n unregister: (id: string) => void;\n };\n }\n ).__breadcrumbRegistry;\n reg?.register(appId, name);\n return () => reg?.unregister(appId);\n }, [appId, application?.name]);\n\n const totalCount = data?.auditLogs?.totalCount ?? 0;\n const auditLogs: AuditLogEntry[] =\n data?.auditLogs?.edges?.map(\n (edge: GetApplicationAuditLogsQuery[\"auditLogs\"][\"edges\"][number]) =>\n edge.node,\n ) ?? [];\n\n const availableActions = useMemo(\n () =>\n Array.from(\n new Set(auditLogs.map((entry: AuditLogEntry) => entry.action)),\n ).sort((left, right) => left.localeCompare(right)),\n [auditLogs],\n );\n\n const filteredLogs = useMemo(() => {\n const normalizedQuery = searchQuery.trim().toLowerCase();\n\n return auditLogs.filter((entry: AuditLogEntry) => {\n const matchesAction =\n actionFilter === \"all\" || entry.action === actionFilter;\n if (!matchesAction) return false;\n\n if (!normalizedQuery) return true;\n\n const haystack = [\n entry.action,\n entry.actorId,\n resolveActorLabel(entry.actorId),\n entry.resource,\n metadataPreview(entry.metadata),\n ]\n .join(\" \")\n .toLowerCase();\n\n return haystack.includes(normalizedQuery);\n });\n }, [actionFilter, auditLogs, searchQuery]);\n\n const exportPayload = () => {\n const blob = new Blob([JSON.stringify(filteredLogs, null, 2)], {\n type: \"application/json\",\n });\n const url = URL.createObjectURL(blob);\n const anchor = document.createElement(\"a\");\n anchor.href = url;\n anchor.download = `${application?.slug || appId || \"application\"}-audit-log.json`;\n anchor.click();\n URL.revokeObjectURL(url);\n };\n\n if (loading && !data) {\n return (\n <PageLayout\n title=\"Application Activity\"\n description=\"Loading application audit history\"\n backLink={appId ? `/apps/${appId}` : \"/apps\"}\n backLabel=\"Back to Application\"\n >\n <div className=\"flex items-center justify-center py-16 text-text-secondary\">\n <Loader2 className=\"h-8 w-8 animate-spin\" />\n </div>\n </PageLayout>\n );\n }\n\n if (error || !application) {\n return (\n <PageLayout\n title=\"Application Activity\"\n description=\"Review audit events for this application\"\n backLink={appId ? `/apps/${appId}` : \"/apps\"}\n backLabel=\"Back to Application\"\n >\n <EmptyState\n icon={<AlertCircle size={32} className=\"text-status-error-text\" />}\n title=\"Unable to load activity\"\n description={error ? getErrorMessage(error) : \"Application not found\"}\n />\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n title=\"Application Activity\"\n description={`Audit events for ${application.name}`}\n purpose=\"A chronological audit trail of everything that happened to this app — config changes, secret rotations, webhook deliveries, and access events. Use it to debug integrations and to answer 'who changed what, and when?'\"\n backLink={`/apps/${application.id}`}\n backLabel=\"Back to Application\"\n actions={\n <div className=\"flex flex-wrap gap-2\">\n <button\n type=\"button\"\n onClick={() => void refetch()}\n className=\"inline-flex items-center gap-2 rounded-md border px-3 py-2 text-sm font-medium hover:bg-accent\"\n >\n <RefreshCw size={16} />\n Refresh\n </button>\n <button\n type=\"button\"\n onClick={exportPayload}\n className=\"inline-flex items-center gap-2 rounded-md border px-3 py-2 text-sm font-medium hover:bg-accent\"\n >\n <Download size={16} />\n Export JSON\n </button>\n </div>\n }\n >\n <div className=\"grid gap-4 rounded-card border border-border-seam bg-bg-surface p-4 lg:grid-cols-[220px_minmax(0,1fr)_auto] lg:items-center\">\n <label className=\"grid gap-2 text-sm font-medium\">\n <span className=\"flex items-center gap-2 text-text-secondary\">\n <Filter size={16} />\n Filter by action\n </span>\n <select\n value={actionFilter}\n onChange={(event) => setActionFilter(event.target.value)}\n className=\"rounded-md border bg-bg-surface px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-primary\"\n >\n <option value=\"all\">All actions</option>\n {availableActions.map((action) => (\n <option key={action} value={action}>\n {formatAction(action)}\n </option>\n ))}\n </select>\n </label>\n\n <label className=\"grid gap-2 text-sm font-medium\">\n <span className=\"text-text-secondary\">Search metadata</span>\n <input\n type=\"text\"\n value={searchQuery}\n onChange={(event) => setSearchQuery(event.target.value)}\n placeholder=\"Search actor, action, or metadata\"\n className=\"rounded-md border bg-bg-surface px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-primary\"\n />\n </label>\n\n <div className=\"rounded-full bg-bg-sunken px-3 py-2 text-sm text-text-secondary\">\n {totalCount} total events\n </div>\n </div>\n\n <PageSection>\n {filteredLogs.length > 0 ? (\n <div className=\"space-y-3 rounded-card border border-border-seam bg-bg-surface p-4\">\n {filteredLogs.map((entry: AuditLogEntry) => (\n <article\n key={entry.id}\n className=\"rounded-card border border-border-seam bg-bg-surface p-4\"\n >\n <div className=\"flex flex-col gap-3 lg:flex-row lg:items-start lg:justify-between\">\n <div className=\"space-y-2\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <span className=\"rounded-full bg-action-primary-bg/10 px-2.5 py-1 text-xs font-medium text-primary\">\n {formatAction(entry.action)}\n </span>\n <span className=\"text-xs text-text-secondary\">\n Actor {resolveActorLabel(entry.actorId)}\n </span>\n </div>\n <p className=\"text-sm text-text-secondary\">\n Resource: {entry.resource}\n {entry.resourceId ? ` · ${entry.resourceId}` : \"\"}\n </p>\n </div>\n\n <time className=\"text-xs text-text-secondary\">\n {formatTimestamp(entry.createdAt)}\n </time>\n </div>\n\n {entry.metadata && (\n <pre className=\"mt-3 overflow-x-auto rounded-md bg-bg-sunken p-3 text-xs text-text-primary\">\n {metadataPreview(entry.metadata)}\n </pre>\n )}\n\n {entry.changes && (\n <details className=\"mt-3 rounded-md border bg-bg-surface p-3\">\n <summary className=\"cursor-pointer text-sm font-medium text-text-primary\">\n View captured changes\n </summary>\n <pre className=\"mt-3 overflow-x-auto text-xs text-text-secondary\">\n {metadataPreview(entry.changes)}\n </pre>\n </details>\n )}\n </article>\n ))}\n </div>\n ) : (\n <EmptyState\n illustration=\"empty-data\"\n title=\"No audit events found\"\n description=\"Events will appear here after application or webhook actions are performed through the public gateway.\"\n />\n )}\n </PageSection>\n\n {data.auditLogs?.pageInfo?.hasNextPage && (\n <div className=\"flex justify-center\">\n <button\n type=\"button\"\n onClick={() => setPage((previous) => previous + 1)}\n className=\"inline-flex items-center gap-2 rounded-md border px-4 py-2 text-sm font-medium hover:bg-accent\"\n >\n <RefreshCw size={16} />\n Next page\n </button>\n </div>\n )}\n </PageLayout>\n );\n};\n"],"mappings":"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"}