adonisjs-server-stats 1.8.0 → 1.10.0

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 (91) hide show
  1. package/dist/core/index.js +24 -22
  2. package/dist/core/log-utils.d.ts +14 -0
  3. package/dist/core/split-pane.d.ts +18 -0
  4. package/dist/core/trace-utils.d.ts +5 -0
  5. package/dist/core/types.d.ts +1 -1
  6. package/dist/react/{CacheSection-D5J5moz7.js → CacheSection-UCMptWyn.js} +1 -1
  7. package/dist/react/{CacheTab-F1MkWSZl.js → CacheTab-CA8LB1J5.js} +1 -1
  8. package/dist/react/{ConfigSection-DerLBu4o.js → ConfigSection-DfFd-WRq.js} +1 -1
  9. package/dist/react/{ConfigTab-Bsj7v9JW.js → ConfigTab-Bdg8YMer.js} +1 -1
  10. package/dist/react/{CustomPaneTab-gzdtDEvz.js → CustomPaneTab-Bxtv_8Rw.js} +1 -1
  11. package/dist/react/{EmailsSection-ndH3cvJk.js → EmailsSection-CM7stSyh.js} +1 -1
  12. package/dist/react/{EmailsTab-DVPHRx0L.js → EmailsTab-BDhEiomM.js} +1 -1
  13. package/dist/react/{EventsSection-ClIByDSk.js → EventsSection-ByQ-9blq.js} +1 -1
  14. package/dist/react/{EventsTab-CCzWEKrk.js → EventsTab-CMfY98Rl.js} +1 -1
  15. package/dist/react/{JobsSection-CVMyAs7O.js → JobsSection-DF3qEv9O.js} +1 -1
  16. package/dist/react/{JobsTab-CATUyb9V.js → JobsTab-BbrBWIOb.js} +1 -1
  17. package/dist/react/LogsSection-DcFTZY7b.js +227 -0
  18. package/dist/react/LogsTab-CicucmVk.js +103 -0
  19. package/dist/react/{OverviewSection-ae5AO2RG.js → OverviewSection-C4T1ur51.js} +1 -1
  20. package/dist/react/{QueriesSection-DFFr9Tbb.js → QueriesSection-PswteoF9.js} +1 -1
  21. package/dist/react/{QueriesTab-GrHRAREt.js → QueriesTab-osLUWd4L.js} +1 -1
  22. package/dist/react/RelatedLogs-DFDOyUMr.js +40 -0
  23. package/dist/react/RequestsSection-Nag30rEA.js +341 -0
  24. package/dist/react/{RoutesSection-F7nANhF0.js → RoutesSection-BUSkM6PY.js} +1 -1
  25. package/dist/react/{RoutesTab-rugjhCPH.js → RoutesTab-DgVzd2PZ.js} +1 -1
  26. package/dist/react/TimelineTab-Covg5weo.js +220 -0
  27. package/dist/react/{index-DDzo1bZk.js → index-Cflz9Ebj.js} +390 -395
  28. package/dist/react/index.js +1 -1
  29. package/dist/react/react/components/shared/JsonViewer.d.ts +2 -1
  30. package/dist/react/react/components/shared/RelatedLogs.d.ts +7 -0
  31. package/dist/react/style.css +1 -1
  32. package/dist/src/controller/debug_controller.js +1 -1
  33. package/dist/src/dashboard/dashboard_controller.js +13 -0
  34. package/dist/src/dashboard/dashboard_store.d.ts +1 -0
  35. package/dist/src/dashboard/dashboard_store.js +88 -41
  36. package/dist/src/dashboard/migrator.js +6 -0
  37. package/dist/src/data/data_access.d.ts +7 -0
  38. package/dist/src/data/data_access.js +32 -1
  39. package/dist/src/debug/trace_collector.d.ts +1 -1
  40. package/dist/src/debug/trace_collector.js +2 -1
  41. package/dist/src/debug/types.d.ts +4 -0
  42. package/dist/src/edge/client/dashboard.js +2 -2
  43. package/dist/src/edge/client/debug-panel-deferred.js +1 -1
  44. package/dist/src/edge/client-vue/dashboard.js +4 -4
  45. package/dist/src/edge/client-vue/debug-panel-deferred.js +3 -3
  46. package/dist/src/middleware/request_tracking_middleware.d.ts +1 -0
  47. package/dist/src/middleware/request_tracking_middleware.js +3 -1
  48. package/dist/src/provider/server_stats_provider.d.ts +3 -3
  49. package/dist/src/provider/server_stats_provider.js +29 -15
  50. package/dist/src/routes/register_routes.js +7 -2
  51. package/dist/src/styles/components.css +162 -0
  52. package/dist/src/styles/debug-panel.css +9 -0
  53. package/dist/src/types.d.ts +1 -1
  54. package/dist/vue/{CacheSection-DDvJ7bs2.js → CacheSection-oFAJL3mo.js} +2 -2
  55. package/dist/vue/{ConfigSection-GTCrvsPr.js → ConfigSection-BhfJ4KqL.js} +1 -1
  56. package/dist/vue/{EmailsSection-Ct5vsLCc.js → EmailsSection-BcNyhyHs.js} +1 -1
  57. package/dist/vue/{EventsSection-CRVhtagq.js → EventsSection-r60Q5Lmu.js} +2 -2
  58. package/dist/vue/{EventsTab-DQ4Nd6AK.js → EventsTab-BBM7olXF.js} +1 -1
  59. package/dist/vue/{JobsSection-B_wH2Co7.js → JobsSection-BHL-hkQw.js} +2 -2
  60. package/dist/vue/{JobsTab-BCvhOARO.js → JobsTab-WFnxPdN7.js} +1 -1
  61. package/dist/vue/{JsonViewer.vue_vue_type_script_setup_true_lang-Vsqar1zx.js → JsonViewer.vue_vue_type_script_setup_true_lang-Bid05zpm.js} +25 -23
  62. package/dist/vue/LogsSection-DRMGzJmg.js +252 -0
  63. package/dist/vue/LogsTab-Bg3o0Mm6.js +147 -0
  64. package/dist/vue/{OverviewSection-BqSwuMKH.js → OverviewSection-CXh6Ja1B.js} +1 -1
  65. package/dist/vue/{QueriesSection-D4Fs0YH6.js → QueriesSection-IodIsCJ-.js} +1 -1
  66. package/dist/vue/RelatedLogs.vue_vue_type_script_setup_true_lang-CB2_TzYW.js +84 -0
  67. package/dist/vue/RequestsSection-BPuMdmMc.js +401 -0
  68. package/dist/vue/{RoutesSection-Ys5dTzvF.js → RoutesSection-NKo3Rbq3.js} +1 -1
  69. package/dist/vue/TimelineTab-zj5Z5OdT.js +338 -0
  70. package/dist/vue/components/Dashboard/sections/RequestsSection.vue.d.ts +4 -0
  71. package/dist/vue/components/DebugPanel/tabs/TimelineTab.vue.d.ts +4 -0
  72. package/dist/vue/components/shared/JsonViewer.vue.d.ts +3 -0
  73. package/dist/vue/components/{Dashboard/sections/TimelineSection.vue.d.ts → shared/RelatedLogs.vue.d.ts} +5 -6
  74. package/dist/vue/index-Dtgysd26.js +1229 -0
  75. package/dist/vue/index.js +1 -1
  76. package/dist/vue/style.css +1 -1
  77. package/package.json +1 -1
  78. package/dist/react/LogsSection-hAsLaKOC.js +0 -212
  79. package/dist/react/LogsTab-QouH4NPQ.js +0 -88
  80. package/dist/react/RequestsSection-DtwnJOnM.js +0 -209
  81. package/dist/react/TimelineSection-F5ThmTdy.js +0 -158
  82. package/dist/react/TimelineTab-Dvpf-I5C.js +0 -193
  83. package/dist/react/WaterfallChart-Cj73WdfM.js +0 -100
  84. package/dist/react/react/components/Dashboard/sections/TimelineSection.d.ts +0 -8
  85. package/dist/vue/LogsSection-C4NRFOpA.js +0 -227
  86. package/dist/vue/LogsTab-DpEQ7euu.js +0 -122
  87. package/dist/vue/RequestsSection-B0A5SKcM.js +0 -243
  88. package/dist/vue/TimelineSection-D38iHB08.js +0 -186
  89. package/dist/vue/TimelineTab-Db6lKKsD.js +0 -250
  90. package/dist/vue/WaterfallChart.vue_vue_type_script_setup_true_lang-tZ13cNj1.js +0 -118
  91. package/dist/vue/index-Bj6pm5g3.js +0 -1235
@@ -136,7 +136,7 @@ function H(e) {
136
136
  }
137
137
  } };
138
138
  }
139
- function N(e) {
139
+ function q(e) {
140
140
  let t = !1;
141
141
  const r = H({
142
142
  baseUrl: e.baseUrl,
@@ -164,12 +164,12 @@ function U() {
164
164
  const e = localStorage.getItem(v);
165
165
  return e === "dark" || e === "light" ? e : window.matchMedia?.("(prefers-color-scheme: dark)").matches ? "dark" : "light";
166
166
  }
167
- function q(e) {
167
+ function N(e) {
168
168
  typeof window > "u" || (localStorage.setItem(v, e), window.dispatchEvent(new CustomEvent(M, { detail: e })));
169
169
  }
170
170
  function Ae() {
171
171
  const t = U() === "dark" ? "light" : "dark";
172
- return q(t), t;
172
+ return N(t), t;
173
173
  }
174
174
  function Le(e) {
175
175
  if (typeof window > "u") return () => {
@@ -234,8 +234,8 @@ function De(e, t) {
234
234
  if (e.length < 2) return null;
235
235
  const r = K(t), n = V(e), i = n.max - n.min || 1, s = r.width - r.padding * 2, o = r.height - r.padding * 2, l = r.padding, a = e.length, h = Array.from({ length: a });
236
236
  for (let u = 0; u < a; u++) {
237
- const E = l + u / (a - 1) * s, I = l + o - (e[u] - n.min) / i * o;
238
- h[u] = `${E.toFixed(1)},${I.toFixed(1)}`;
237
+ const E = l + u / (a - 1) * s, O = l + o - (e[u] - n.min) / i * o;
238
+ h[u] = `${E.toFixed(1)},${O.toFixed(1)}`;
239
239
  }
240
240
  const m = h.join(" "), d = (l + s).toFixed(1), f = (l + o).toFixed(1), p = l.toFixed(1), x = `M${h[0]} ` + h.slice(1).map((u) => `L${u}`).join(" ") + ` L${d},${f} L${p},${f} Z`;
241
241
  return {
@@ -268,7 +268,7 @@ function Fe(e) {
268
268
  function D(e) {
269
269
  return /([+-]\d{2}:?\d{2}|Z)\s*$/.test(e) ? e : e + "Z";
270
270
  }
271
- function Oe(e) {
271
+ function Ie(e) {
272
272
  if (!e) return "-";
273
273
  const t = typeof e == "string" ? new Date(D(e)) : new Date(e);
274
274
  return Number.isNaN(t.getTime()) ? "-" : t.toLocaleTimeString("en-US", {
@@ -278,7 +278,7 @@ function Oe(e) {
278
278
  second: "2-digit"
279
279
  }) + "." + String(t.getMilliseconds()).padStart(3, "0");
280
280
  }
281
- function Ie(e) {
281
+ function Oe(e) {
282
282
  if (!e) return "-";
283
283
  const t = typeof e == "string" ? new Date(D(e)).getTime() : e, r = Math.floor((Date.now() - t) / 1e3);
284
284
  return r < 0 ? "just now" : r < 60 ? `${r}s ago` : r < 3600 ? `${Math.floor(r / 60)}m ago` : r < 86400 ? `${Math.floor(r / 3600)}h ago` : `${Math.floor(r / 86400)}d ago`;
@@ -324,10 +324,10 @@ const te = {
324
324
  amber: "--ss-amber-fg",
325
325
  red: "--ss-red-fg"
326
326
  };
327
- function Ne(e) {
327
+ function qe(e) {
328
328
  return e >= 500 ? "red" : e >= 400 ? "amber" : "green";
329
329
  }
330
- function qe(e) {
330
+ function Ne(e) {
331
331
  return e > X ? "very-slow" : e > Q ? "slow" : "normal";
332
332
  }
333
333
  function Ke(e) {
@@ -428,7 +428,7 @@ function Ye(e, t, r = 2) {
428
428
  n.push(o);
429
429
  return s < t - 1 && n.push("..."), t > 1 && n.push(t), n;
430
430
  }
431
- const O = "/admin/api/debug", ne = {
431
+ const I = "/admin/api/debug", ne = {
432
432
  tracing: !1,
433
433
  process: !1,
434
434
  system: !1,
@@ -460,12 +460,12 @@ function se(e) {
460
460
  customPanes: e.customPanes ?? []
461
461
  };
462
462
  }
463
- async function ie(e, t = O) {
463
+ async function ie(e, t = I) {
464
464
  const r = `${t.replace(/\/+$/, "")}/config`;
465
465
  return e.fetch(r);
466
466
  }
467
467
  async function Ze(e) {
468
- const { baseUrl: t = "", debugEndpoint: r = O, authToken: n } = e, i = new T({ baseUrl: t, authToken: n });
468
+ const { baseUrl: t = "", debugEndpoint: r = I, authToken: n } = e, i = new T({ baseUrl: t, authToken: n });
469
469
  try {
470
470
  const s = await ie(i, r);
471
471
  return se(s);
@@ -911,7 +911,7 @@ class st {
911
911
  this.stopped = !1;
912
912
  let t = !1;
913
913
  try {
914
- const r = N({
914
+ const r = q({
915
915
  baseUrl: this.baseUrl,
916
916
  channelName: this.channelName,
917
917
  authToken: this.authToken,
@@ -1756,7 +1756,9 @@ function Tt(e) {
1756
1756
  totalDuration: C(e, "total_duration", "totalDuration") || e.duration || 0,
1757
1757
  spanCount: C(e, "span_count", "spanCount"),
1758
1758
  spans: ye(e.spans),
1759
- warnings: be(e.warnings)
1759
+ warnings: be(e.warnings),
1760
+ logs: e.logs || [],
1761
+ httpRequestId: e.httpRequestId || e.http_request_id || void 0
1760
1762
  };
1761
1763
  }
1762
1764
  const xe = ["password", "secret", "token", "key", "credential", "auth"];
@@ -1892,7 +1894,7 @@ function $e(e) {
1892
1894
  function Ft(e) {
1893
1895
  return $e(e).some((r) => ke.has(r.toLowerCase()));
1894
1896
  }
1895
- const Ot = new RegExp("secret|password|pass(?:word)?|pwd|token|(?:^|[._-])key(?:[._-]|$)|(?<=[a-z])Key|apikey|api_key|auth|credential|private|encryption", "i");
1897
+ const It = new RegExp("secret|password|pass(?:word)?|pwd|token|(?:^|[._-])key(?:[._-]|$)|(?<=[a-z])Key|apikey|api_key|auth|credential|private|encryption", "i");
1896
1898
  export {
1897
1899
  T as ApiClient,
1898
1900
  _ as ApiError,
@@ -1912,7 +1914,7 @@ export {
1912
1914
  k as METRIC_DEFINITIONS,
1913
1915
  Ee as OK_STATUSES,
1914
1916
  j as OVERVIEW_REFRESH_MS,
1915
- Ot as REDACT_PATTERN,
1917
+ It as REDACT_PATTERN,
1916
1918
  G as SECTION_REFRESH_MS,
1917
1919
  Q as SLOW_DURATION_MS,
1918
1920
  le as STALE_MS,
@@ -1943,7 +1945,7 @@ export {
1943
1945
  H as createTransmitSubscription,
1944
1946
  Ze as detectFeatures,
1945
1947
  tt as detectMetricGroupsFromStats,
1946
- qe as durationSeverity,
1948
+ Ne as durationSeverity,
1947
1949
  vt as extractJobStats,
1948
1950
  St as extractJobs,
1949
1951
  ie as fetchFeatures,
@@ -1960,7 +1962,7 @@ export {
1960
1962
  Lt as formatFlatValue,
1961
1963
  $ as formatMb,
1962
1964
  _e as formatStatNum,
1963
- Oe as formatTime,
1965
+ Ie as formatTime,
1964
1966
  ze as formatTtl,
1965
1967
  Y as formatUptime,
1966
1968
  W as generateGradientId,
@@ -1997,11 +1999,11 @@ export {
1997
1999
  dt as resolveLogRequestId,
1998
2000
  ut as resolveLogTimestamp,
1999
2001
  C as resolveTraceField,
2000
- q as setTheme,
2002
+ N as setTheme,
2001
2003
  Ke as shortReqId,
2002
2004
  Ft as shouldRedact,
2003
- Ne as statusColor,
2004
- N as subscribeToChannel,
2005
- Ie as timeAgo,
2005
+ qe as statusColor,
2006
+ q as subscribeToChannel,
2007
+ Oe as timeAgo,
2006
2008
  Ae as toggleTheme
2007
2009
  };
@@ -31,3 +31,17 @@ export declare function getLogLevelCssClass(level: string, prefix?: string): str
31
31
  * The `'error'` filter also includes `'fatal'` entries (matching React behaviour).
32
32
  */
33
33
  export declare function filterLogsByLevel(logs: LogEntry[], level: string): LogEntry[];
34
+ /**
35
+ * Standard Pino / framework keys that should NOT be surfaced as "structured data".
36
+ */
37
+ export declare const STANDARD_LOG_KEYS: Set<string>;
38
+ /**
39
+ * Extract non-standard structured data from a log entry.
40
+ *
41
+ * Handles two data shapes:
42
+ * - **Debug panel** (raw Pino): extra fields live at the top level
43
+ * - **Dashboard** (SQLite): extra fields live inside the `data` JSON blob
44
+ *
45
+ * Returns `null` when there is no structured data to show.
46
+ */
47
+ export declare function getStructuredData(entry: LogEntry): Record<string, unknown> | null;
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Shared split-pane drag logic (framework-agnostic, DOM-based).
3
+ *
4
+ * Sets up vertical resizing between a top pane and bottom pane inside a
5
+ * flex-column container. Uses pointer events with setPointerCapture
6
+ * (same pattern as resizable-columns.ts).
7
+ *
8
+ * Persists the split ratio to localStorage so it survives page reloads.
9
+ */
10
+ export interface SplitPaneOptions {
11
+ container: HTMLElement;
12
+ handle: HTMLElement;
13
+ topPane: HTMLElement;
14
+ bottomPane: HTMLElement;
15
+ storageKey?: string;
16
+ minHeight?: number;
17
+ }
18
+ export declare function initSplitPane(opts: SplitPaneOptions): () => void;
@@ -1,3 +1,4 @@
1
+ import { LogEntry } from './log-utils.js';
1
2
  /**
2
3
  * Raw trace detail as returned by the dashboard API.
3
4
  *
@@ -17,6 +18,8 @@ export interface TraceDetail {
17
18
  span_count?: number;
18
19
  spans: unknown[] | string;
19
20
  warnings: string[] | string;
21
+ logs?: LogEntry[];
22
+ httpRequestId?: string;
20
23
  }
21
24
  /**
22
25
  * Normalized trace with consistent camelCase field names and parsed arrays.
@@ -29,6 +32,8 @@ export interface NormalizedTrace {
29
32
  spanCount: number;
30
33
  spans: unknown[];
31
34
  warnings: string[];
35
+ logs: LogEntry[];
36
+ httpRequestId?: string;
32
37
  }
33
38
  /**
34
39
  * Parse raw span data that may be a JSON string, an array, or undefined.
@@ -256,7 +256,7 @@ export type DebugTab = 'timeline' | 'queries' | 'events' | 'routes' | 'logs' | '
256
256
  *
257
257
  * Known sections are provided for autocomplete; any custom string is also accepted.
258
258
  */
259
- export type DashboardSection = 'overview' | 'requests' | 'queries' | 'events' | 'routes' | 'logs' | 'emails' | 'timeline' | 'cache' | 'jobs' | 'config' | (string & {});
259
+ export type DashboardSection = 'overview' | 'requests' | 'queries' | 'events' | 'routes' | 'logs' | 'emails' | 'cache' | 'jobs' | 'config' | (string & {});
260
260
  /**
261
261
  * Pre-defined time range options for dashboard queries.
262
262
  */
@@ -1,7 +1,7 @@
1
1
  import { jsxs as l, jsx as a } from "react/jsx-runtime";
2
2
  import { useState as i, useCallback as f } from "react";
3
3
  import { formatCacheSize as x, formatTtl as D } from "adonisjs-server-stats/core";
4
- import { a as S, J as V } from "./index-DDzo1bZk.js";
4
+ import { a as S, J as V } from "./index-Cflz9Ebj.js";
5
5
  import { D as F } from "./DataTable-YyShr5B-.js";
6
6
  import { F as L } from "./FilterBar-DQRXpWrb.js";
7
7
  function H({ options: k = {} }) {
@@ -2,7 +2,7 @@ import { jsx as s, jsxs as a } from "react/jsx-runtime";
2
2
  import { useState as b, useMemo as z, useCallback as K } from "react";
3
3
  import { formatTtl as B, formatCacheSize as L } from "adonisjs-server-stats/core";
4
4
  import { u as S } from "./useDashboardApiBase-Bi36pJ2L.js";
5
- import { u as j, J as A } from "./index-DDzo1bZk.js";
5
+ import { u as j, J as A } from "./index-Cflz9Ebj.js";
6
6
  import { u as $ } from "./useResizableTable-CNJmACdt.js";
7
7
  function q({ options: d, dashboardPath: y }) {
8
8
  const { dashApiBase: u, resolvedOptions: f } = S(y, d), { data: t, isLoading: v, error: g } = j("cache", f), [i, k] = b(""), [r, h] = b(null), [p, o] = b(null), n = z(() => {
@@ -1,5 +1,5 @@
1
1
  import { jsx as t } from "react/jsx-runtime";
2
- import { a as i } from "./index-DDzo1bZk.js";
2
+ import { a as i } from "./index-Cflz9Ebj.js";
3
3
  import { C as n } from "./ConfigContent-CnsEI4j3.js";
4
4
  function m({ options: o = {} }) {
5
5
  const { data: a, isLoading: s } = i("config", o);
@@ -1,6 +1,6 @@
1
1
  import { jsxs as i, jsx as n } from "react/jsx-runtime";
2
2
  import { u as f } from "./useDashboardApiBase-Bi36pJ2L.js";
3
- import { u as m } from "./index-DDzo1bZk.js";
3
+ import { u as m } from "./index-Cflz9Ebj.js";
4
4
  import { C as d } from "./ConfigContent-CnsEI4j3.js";
5
5
  function b({ options: r, dashboardPath: o }) {
6
6
  const { resolvedOptions: a } = f(o, r), { data: e, isLoading: t, error: s } = m("config", a);
@@ -1,7 +1,7 @@
1
1
  import { jsxs as o, jsx as s } from "react/jsx-runtime";
2
2
  import { useState as L, useMemo as h } from "react";
3
3
  import { compactPreview as x, formatDuration as A, durationSeverity as f, timeAgo as u, formatTime as p } from "adonisjs-server-stats/core";
4
- import { u as D } from "./index-DDzo1bZk.js";
4
+ import { u as D } from "./index-Cflz9Ebj.js";
5
5
  import { u as M } from "./useResizableTable-CNJmACdt.js";
6
6
  function E({ pane: r, options: g }) {
7
7
  ({
@@ -1,7 +1,7 @@
1
1
  import { jsxs as r, jsx as a, Fragment as i } from "react/jsx-runtime";
2
2
  import { useState as n, useEffect as N, useCallback as C } from "react";
3
3
  import { timeAgo as P, formatTime as A } from "adonisjs-server-stats/core";
4
- import { a as T } from "./index-DDzo1bZk.js";
4
+ import { a as T } from "./index-Cflz9Ebj.js";
5
5
  import { D as j } from "./DataTable-YyShr5B-.js";
6
6
  import { F as $ } from "./FilterBar-DQRXpWrb.js";
7
7
  import { P as F } from "./Pagination-BkmzUDY8.js";
@@ -1,7 +1,7 @@
1
1
  import { jsx as e, jsxs as t } from "react/jsx-runtime";
2
2
  import { useState as n, useMemo as f, useCallback as v } from "react";
3
3
  import { timeAgo as k, formatTime as S } from "adonisjs-server-stats/core";
4
- import { u as A } from "./index-DDzo1bZk.js";
4
+ import { u as A } from "./index-Cflz9Ebj.js";
5
5
  import { u as P } from "./useResizableTable-CNJmACdt.js";
6
6
  function M({ options: i }) {
7
7
  const { data: o, isLoading: N, error: u } = A("emails", i), [c, y] = n(""), [g, b] = n(null), [p, h] = n(null), [x, m] = n(!1), r = f(() => {
@@ -1,7 +1,7 @@
1
1
  import { jsxs as o, jsx as e, Fragment as g } from "react/jsx-runtime";
2
2
  import { useState as d, useEffect as f } from "react";
3
3
  import { timeAgo as y, formatTime as u } from "adonisjs-server-stats/core";
4
- import { a as b, J as N } from "./index-DDzo1bZk.js";
4
+ import { a as b, J as N } from "./index-Cflz9Ebj.js";
5
5
  import { D as x } from "./DataTable-YyShr5B-.js";
6
6
  import { F as P } from "./FilterBar-DQRXpWrb.js";
7
7
  import { P as k } from "./Pagination-BkmzUDY8.js";
@@ -1,7 +1,7 @@
1
1
  import { jsx as e, jsxs as t } from "react/jsx-runtime";
2
2
  import { useState as g, useMemo as u } from "react";
3
3
  import { timeAgo as b, formatTime as p } from "adonisjs-server-stats/core";
4
- import { u as v, J as f } from "./index-DDzo1bZk.js";
4
+ import { u as v, J as f } from "./index-Cflz9Ebj.js";
5
5
  import { u as N } from "./useResizableTable-CNJmACdt.js";
6
6
  function T({ options: c }) {
7
7
  const { data: n, isLoading: o, error: i } = v("events", c), [r, m] = g(""), d = u(() => {
@@ -1,7 +1,7 @@
1
1
  import { jsxs as l, jsx as a, Fragment as C } from "react/jsx-runtime";
2
2
  import { useState as c, useCallback as D } from "react";
3
3
  import { extractJobs as F, extractJobStats as J, JOB_STATUS_FILTERS as T, getJobStatusBadgeColor as A, formatDuration as B, timeAgo as _, formatTime as L } from "adonisjs-server-stats/core";
4
- import { a as R, B as $, J as M } from "./index-DDzo1bZk.js";
4
+ import { a as R, B as $, J as M } from "./index-Cflz9Ebj.js";
5
5
  import { D as O } from "./DataTable-YyShr5B-.js";
6
6
  import { F as U } from "./FilterBar-DQRXpWrb.js";
7
7
  import { P as E } from "./Pagination-BkmzUDY8.js";
@@ -2,7 +2,7 @@ import { jsx as s, jsxs as t } from "react/jsx-runtime";
2
2
  import { useState as u, useMemo as T, useCallback as S } from "react";
3
3
  import { extractJobs as j, extractJobStats as D, JOB_STATUS_FILTERS as J, getJobStatusCssClass as C, formatDuration as R, timeAgo as $, formatTime as B } from "adonisjs-server-stats/core";
4
4
  import { u as k } from "./useDashboardApiBase-Bi36pJ2L.js";
5
- import { u as F, J as L } from "./index-DDzo1bZk.js";
5
+ import { u as F, J as L } from "./index-Cflz9Ebj.js";
6
6
  import { u as P } from "./useResizableTable-CNJmACdt.js";
7
7
  function U({ options: i, dashboardPath: p }) {
8
8
  const { dashApiBase: c, resolvedOptions: N } = k(p, i), { data: d, isLoading: y, error: m } = F("jobs", N), [r, f] = u("all"), [h, b] = u(null), n = T(() => {
@@ -0,0 +1,227 @@
1
+ import { jsxs as a, jsx as s } from "react/jsx-runtime";
2
+ import M, { useState as l, useCallback as c } from "react";
3
+ import { LOG_LEVELS as U, resolveLogLevel as z, resolveLogMessage as H, resolveLogRequestId as Q, resolveLogTimestamp as W, getStructuredData as X, getLogLevelCssClass as Y, timeAgo as Z, formatTime as ee } from "adonisjs-server-stats/core";
4
+ import { a as se, J as te } from "./index-Cflz9Ebj.js";
5
+ import { F as ae } from "./FilterBar-DQRXpWrb.js";
6
+ import { P as le } from "./Pagination-BkmzUDY8.js";
7
+ function he({ options: D = {} }) {
8
+ const [R, i] = l(1), [L, V] = l(""), [r, S] = l("all"), [n, v] = l(""), [p, f] = l(""), [N, k] = l([]), [b, A] = l("level"), [q, K] = l("equals"), [y, _] = l(""), [C, O] = l(null), o = {};
9
+ r !== "all" && (o.level = r), n && (o.request_id = n), N.forEach((e, t) => {
10
+ o[`filter_field_${t}`] = e.field, o[`filter_op_${t}`] = e.operator, o[`filter_value_${t}`] = e.value;
11
+ });
12
+ const { data: x, meta: d, isLoading: j } = se("logs", {
13
+ ...D,
14
+ page: R,
15
+ search: L,
16
+ filters: o
17
+ }), $ = x || [], P = c((e) => {
18
+ v(e), f(e), i(1);
19
+ }, []), J = c(() => {
20
+ const e = p.trim();
21
+ v(e), i(1);
22
+ }, [p]), E = c(() => {
23
+ v(""), f(""), i(1);
24
+ }, []), T = c(() => {
25
+ S("all"), i(1);
26
+ }, []), w = c(() => {
27
+ const e = y.trim();
28
+ e && (k((t) => [
29
+ ...t,
30
+ { field: b, operator: q, value: e }
31
+ ]), _(""));
32
+ }, [b, q, y]), B = c((e) => {
33
+ k((t) => t.filter((I, F) => F !== e));
34
+ }, []), G = r !== "all" || n !== "" || N.length > 0;
35
+ return /* @__PURE__ */ a("div", { children: [
36
+ /* @__PURE__ */ s(
37
+ ae,
38
+ {
39
+ search: L,
40
+ onSearchChange: V,
41
+ placeholder: "Search logs...",
42
+ summary: `${d?.total ?? 0} logs`,
43
+ children: /* @__PURE__ */ a("div", { className: "ss-dash-log-filters", children: [
44
+ U.map((e) => /* @__PURE__ */ s(
45
+ "button",
46
+ {
47
+ type: "button",
48
+ className: `ss-dash-log-filter ${r === e ? "ss-dash-active" : ""}`,
49
+ onClick: () => {
50
+ S(e), i(1);
51
+ },
52
+ children: e
53
+ },
54
+ e
55
+ )),
56
+ /* @__PURE__ */ s(
57
+ "input",
58
+ {
59
+ type: "text",
60
+ className: "ss-dash-filter-input ss-dash-reqid-input",
61
+ placeholder: "Filter by request ID...",
62
+ value: p,
63
+ onChange: (e) => f(e.target.value),
64
+ onKeyDown: (e) => e.key === "Enter" && J()
65
+ }
66
+ ),
67
+ (p || n) && /* @__PURE__ */ s(
68
+ "button",
69
+ {
70
+ type: "button",
71
+ className: "ss-dash-btn ss-dash-reqid-clear",
72
+ onClick: () => {
73
+ E();
74
+ },
75
+ children: "Clear"
76
+ }
77
+ )
78
+ ] })
79
+ }
80
+ ),
81
+ /* @__PURE__ */ a("div", { className: "ss-dash-structured-search", children: [
82
+ /* @__PURE__ */ a(
83
+ "select",
84
+ {
85
+ className: "ss-dash-filter-select",
86
+ value: b,
87
+ onChange: (e) => A(e.target.value),
88
+ children: [
89
+ /* @__PURE__ */ s("option", { value: "level", children: "level" }),
90
+ /* @__PURE__ */ s("option", { value: "message", children: "message" }),
91
+ /* @__PURE__ */ s("option", { value: "request_id", children: "request_id" }),
92
+ /* @__PURE__ */ s("option", { value: "userId", children: "userId" }),
93
+ /* @__PURE__ */ s("option", { value: "email", children: "email" }),
94
+ /* @__PURE__ */ s("option", { value: "path", children: "path" })
95
+ ]
96
+ }
97
+ ),
98
+ /* @__PURE__ */ a(
99
+ "select",
100
+ {
101
+ className: "ss-dash-filter-select",
102
+ value: q,
103
+ onChange: (e) => K(e.target.value),
104
+ children: [
105
+ /* @__PURE__ */ s("option", { value: "equals", children: "equals" }),
106
+ /* @__PURE__ */ s("option", { value: "contains", children: "contains" }),
107
+ /* @__PURE__ */ s("option", { value: "starts_with", children: "starts with" })
108
+ ]
109
+ }
110
+ ),
111
+ /* @__PURE__ */ s(
112
+ "input",
113
+ {
114
+ className: "ss-dash-filter-input",
115
+ placeholder: "Value...",
116
+ value: y,
117
+ onChange: (e) => _(e.target.value),
118
+ onKeyDown: (e) => e.key === "Enter" && w()
119
+ }
120
+ ),
121
+ /* @__PURE__ */ s("button", { type: "button", className: "ss-dash-btn", onClick: w, children: "Add" })
122
+ ] }),
123
+ G && /* @__PURE__ */ a("div", { className: "ss-dash-filter-chips", children: [
124
+ r !== "all" && /* @__PURE__ */ a("span", { className: "ss-dash-filter-chip", children: [
125
+ "level: ",
126
+ r,
127
+ /* @__PURE__ */ s(
128
+ "button",
129
+ {
130
+ type: "button",
131
+ className: "ss-dash-filter-chip-remove",
132
+ onClick: T,
133
+ children: "×"
134
+ }
135
+ )
136
+ ] }),
137
+ n && /* @__PURE__ */ a("span", { className: "ss-dash-filter-chip", children: [
138
+ "requestId: ",
139
+ n.slice(0, 8),
140
+ "...",
141
+ /* @__PURE__ */ s(
142
+ "button",
143
+ {
144
+ type: "button",
145
+ className: "ss-dash-filter-chip-remove",
146
+ onClick: E,
147
+ children: "×"
148
+ }
149
+ )
150
+ ] }),
151
+ N.map((e, t) => /* @__PURE__ */ a("span", { className: "ss-dash-filter-chip", children: [
152
+ e.field,
153
+ " ",
154
+ e.operator,
155
+ ' "',
156
+ e.value,
157
+ '"',
158
+ /* @__PURE__ */ s(
159
+ "button",
160
+ {
161
+ type: "button",
162
+ className: "ss-dash-filter-chip-remove",
163
+ onClick: () => B(t),
164
+ children: "×"
165
+ }
166
+ )
167
+ ] }, t))
168
+ ] }),
169
+ j && !x ? /* @__PURE__ */ s("div", { className: "ss-dash-empty", children: "Loading logs..." }) : $.length === 0 ? /* @__PURE__ */ a("div", { className: "ss-dash-empty", children: [
170
+ "No log entries",
171
+ n ? ` matching request ${n}` : r !== "all" ? ` for ${r}` : ""
172
+ ] }) : /* @__PURE__ */ s("div", { className: "ss-dash-log-entries", children: $.map((e, t) => {
173
+ const I = z(e), F = H(e), h = Q(e), m = W(e), u = X(e);
174
+ return /* @__PURE__ */ a(M.Fragment, { children: [
175
+ /* @__PURE__ */ a(
176
+ "div",
177
+ {
178
+ className: `ss-dash-log-entry${u ? " ss-dash-log-entry-expandable" : ""}`,
179
+ onClick: () => u && O(C === t ? null : t),
180
+ children: [
181
+ /* @__PURE__ */ s(
182
+ "span",
183
+ {
184
+ className: `ss-dash-log-level ${Y(I, "ss-dash-log-level")}`,
185
+ children: I.toUpperCase()
186
+ }
187
+ ),
188
+ /* @__PURE__ */ s("span", { className: "ss-dash-log-time", title: m ? ee(m) : "", children: m ? Z(m) : "-" }),
189
+ h ? /* @__PURE__ */ s(
190
+ "span",
191
+ {
192
+ className: "ss-dash-log-reqid",
193
+ title: h,
194
+ onClick: (g) => {
195
+ g.stopPropagation(), P(h);
196
+ },
197
+ role: "button",
198
+ tabIndex: 0,
199
+ onKeyDown: (g) => {
200
+ g.key === "Enter" && (g.stopPropagation(), P(h));
201
+ },
202
+ children: h.slice(0, 8)
203
+ }
204
+ ) : /* @__PURE__ */ s("span", { className: "ss-dash-log-reqid-empty", children: "--" }),
205
+ u ? /* @__PURE__ */ s("span", { className: `ss-dash-log-expand-icon${C === t ? " ss-dash-log-expand-icon-open" : ""}`, children: "▶" }) : /* @__PURE__ */ s("span", { style: { width: 14 } }),
206
+ /* @__PURE__ */ s("span", { className: "ss-dash-log-msg", children: F })
207
+ ]
208
+ }
209
+ ),
210
+ C === t && u && /* @__PURE__ */ s("div", { className: "ss-dash-log-detail", children: /* @__PURE__ */ s(te, { data: u, classPrefix: "ss-dash", defaultExpanded: !0 }) })
211
+ ] }, e.id || t);
212
+ }) }),
213
+ d && /* @__PURE__ */ s(
214
+ le,
215
+ {
216
+ page: d.page,
217
+ lastPage: d.lastPage,
218
+ total: d.total,
219
+ onPageChange: i
220
+ }
221
+ )
222
+ ] });
223
+ }
224
+ export {
225
+ he as LogsSection,
226
+ he as default
227
+ };