@flanksource/clicky-ui 0.3.56 → 0.3.57
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/components/ErrorWrapper.cjs +15 -4
- package/dist/components/ErrorWrapper.cjs.map +1 -1
- package/dist/components/ErrorWrapper.d.ts +7 -0
- package/dist/components/ErrorWrapper.d.ts.map +1 -1
- package/dist/components/ErrorWrapper.js +15 -4
- package/dist/components/ErrorWrapper.js.map +1 -1
- package/dist/data/ai/PromptCatalog/PromptLayerStrip.cjs +6 -3
- package/dist/data/ai/PromptCatalog/PromptLayerStrip.cjs.map +1 -1
- package/dist/data/ai/PromptCatalog/PromptLayerStrip.js +6 -3
- package/dist/data/ai/PromptCatalog/PromptLayerStrip.js.map +1 -1
- package/dist/data/ai/PromptCatalog/PromptPage.cjs +2 -1
- package/dist/data/ai/PromptCatalog/PromptPage.cjs.map +1 -1
- package/dist/data/ai/PromptCatalog/PromptPage.d.ts.map +1 -1
- package/dist/data/ai/PromptCatalog/PromptPage.js +2 -1
- package/dist/data/ai/PromptCatalog/PromptPage.js.map +1 -1
- package/dist/data/ai/PromptCatalog/PromptPageHeader.cjs +9 -6
- package/dist/data/ai/PromptCatalog/PromptPageHeader.cjs.map +1 -1
- package/dist/data/ai/PromptCatalog/PromptPageHeader.d.ts.map +1 -1
- package/dist/data/ai/PromptCatalog/PromptPageHeader.js +9 -6
- package/dist/data/ai/PromptCatalog/PromptPageHeader.js.map +1 -1
- package/dist/data/ai/PromptCatalog/PromptPageSaveBar.cjs +3 -3
- package/dist/data/ai/PromptCatalog/PromptPageSaveBar.cjs.map +1 -1
- package/dist/data/ai/PromptCatalog/PromptPageSaveBar.d.ts +2 -1
- package/dist/data/ai/PromptCatalog/PromptPageSaveBar.d.ts.map +1 -1
- package/dist/data/ai/PromptCatalog/PromptPageSaveBar.js +3 -3
- package/dist/data/ai/PromptCatalog/PromptPageSaveBar.js.map +1 -1
- package/dist/data/ai/PromptCatalog/prompt-page-model.cjs +4 -3
- package/dist/data/ai/PromptCatalog/prompt-page-model.cjs.map +1 -1
- package/dist/data/ai/PromptCatalog/prompt-page-model.d.ts +1 -1
- package/dist/data/ai/PromptCatalog/prompt-page-model.d.ts.map +1 -1
- package/dist/data/ai/PromptCatalog/prompt-page-model.js +4 -3
- package/dist/data/ai/PromptCatalog/prompt-page-model.js.map +1 -1
- package/dist/data/ai/PromptCatalog/types.d.ts +1 -0
- package/dist/data/ai/PromptCatalog/types.d.ts.map +1 -1
- package/dist/data/traces/index.d.ts +7 -0
- package/dist/data/traces/index.d.ts.map +1 -1
- package/dist/data/traces/otel/OperationList.cjs +64 -0
- package/dist/data/traces/otel/OperationList.cjs.map +1 -0
- package/dist/data/traces/otel/OperationList.d.ts +10 -0
- package/dist/data/traces/otel/OperationList.d.ts.map +1 -0
- package/dist/data/traces/otel/OperationList.js +64 -0
- package/dist/data/traces/otel/OperationList.js.map +1 -0
- package/dist/data/traces/otel/OtelTraceDetail.cjs +781 -0
- package/dist/data/traces/otel/OtelTraceDetail.cjs.map +1 -0
- package/dist/data/traces/otel/OtelTraceDetail.d.ts +7 -0
- package/dist/data/traces/otel/OtelTraceDetail.d.ts.map +1 -0
- package/dist/data/traces/otel/OtelTraceDetail.js +781 -0
- package/dist/data/traces/otel/OtelTraceDetail.js.map +1 -0
- package/dist/data/traces/otel/OtelTraceSearch.cjs +145 -0
- package/dist/data/traces/otel/OtelTraceSearch.cjs.map +1 -0
- package/dist/data/traces/otel/OtelTraceSearch.d.ts +16 -0
- package/dist/data/traces/otel/OtelTraceSearch.d.ts.map +1 -0
- package/dist/data/traces/otel/OtelTraceSearch.js +145 -0
- package/dist/data/traces/otel/OtelTraceSearch.js.map +1 -0
- package/dist/data/traces/otel/OtelTraceTable.cjs +47 -0
- package/dist/data/traces/otel/OtelTraceTable.cjs.map +1 -0
- package/dist/data/traces/otel/OtelTraceTable.d.ts +12 -0
- package/dist/data/traces/otel/OtelTraceTable.d.ts.map +1 -0
- package/dist/data/traces/otel/OtelTraceTable.js +47 -0
- package/dist/data/traces/otel/OtelTraceTable.js.map +1 -0
- package/dist/data/traces/otel/QueryBar.cjs +158 -0
- package/dist/data/traces/otel/QueryBar.cjs.map +1 -0
- package/dist/data/traces/otel/QueryBar.d.ts +12 -0
- package/dist/data/traces/otel/QueryBar.d.ts.map +1 -0
- package/dist/data/traces/otel/QueryBar.js +158 -0
- package/dist/data/traces/otel/QueryBar.js.map +1 -0
- package/dist/data/traces/otel/SpanCards.cjs +264 -0
- package/dist/data/traces/otel/SpanCards.cjs.map +1 -0
- package/dist/data/traces/otel/SpanCards.d.ts +17 -0
- package/dist/data/traces/otel/SpanCards.d.ts.map +1 -0
- package/dist/data/traces/otel/SpanCards.js +261 -0
- package/dist/data/traces/otel/SpanCards.js.map +1 -0
- package/dist/data/traces/otel/SpanCategory.cjs +18 -0
- package/dist/data/traces/otel/SpanCategory.cjs.map +1 -0
- package/dist/data/traces/otel/SpanCategory.d.ts +7 -0
- package/dist/data/traces/otel/SpanCategory.d.ts.map +1 -0
- package/dist/data/traces/otel/SpanCategory.js +18 -0
- package/dist/data/traces/otel/SpanCategory.js.map +1 -0
- package/dist/data/traces/otel/TraceResults.cjs +195 -0
- package/dist/data/traces/otel/TraceResults.cjs.map +1 -0
- package/dist/data/traces/otel/TraceResults.d.ts +19 -0
- package/dist/data/traces/otel/TraceResults.d.ts.map +1 -0
- package/dist/data/traces/otel/TraceResults.js +193 -0
- package/dist/data/traces/otel/TraceResults.js.map +1 -0
- package/dist/data/traces/otel/api.cjs +36 -0
- package/dist/data/traces/otel/api.cjs.map +1 -0
- package/dist/data/traces/otel/api.d.ts +87 -0
- package/dist/data/traces/otel/api.d.ts.map +1 -0
- package/dist/data/traces/otel/api.js +33 -0
- package/dist/data/traces/otel/api.js.map +1 -0
- package/dist/data/traces/otel/fixtures.d.ts +4 -0
- package/dist/data/traces/otel/fixtures.d.ts.map +1 -0
- package/dist/data/traces/otel/metrics.cjs +7 -0
- package/dist/data/traces/otel/metrics.cjs.map +1 -0
- package/dist/data/traces/otel/metrics.d.ts +2 -0
- package/dist/data/traces/otel/metrics.d.ts.map +1 -0
- package/dist/data/traces/otel/metrics.js +7 -0
- package/dist/data/traces/otel/metrics.js.map +1 -0
- package/dist/data/traces/otel/model.cjs +167 -0
- package/dist/data/traces/otel/model.cjs.map +1 -0
- package/dist/data/traces/otel/model.d.ts +81 -0
- package/dist/data/traces/otel/model.d.ts.map +1 -0
- package/dist/data/traces/otel/model.js +154 -0
- package/dist/data/traces/otel/model.js.map +1 -0
- package/dist/data/traces/otel/query.cjs +90 -0
- package/dist/data/traces/otel/query.cjs.map +1 -0
- package/dist/data/traces/otel/query.d.ts +20 -0
- package/dist/data/traces/otel/query.d.ts.map +1 -0
- package/dist/data/traces/otel/query.js +86 -0
- package/dist/data/traces/otel/query.js.map +1 -0
- package/dist/data/traces/otel/result-model.cjs +25 -0
- package/dist/data/traces/otel/result-model.cjs.map +1 -0
- package/dist/data/traces/otel/result-model.d.ts +5 -0
- package/dist/data/traces/otel/result-model.d.ts.map +1 -0
- package/dist/data/traces/otel/result-model.js +24 -0
- package/dist/data/traces/otel/result-model.js.map +1 -0
- package/dist/data/traces/otel/source.cjs +11 -0
- package/dist/data/traces/otel/source.cjs.map +1 -0
- package/dist/data/traces/otel/source.d.ts +5 -0
- package/dist/data/traces/otel/source.d.ts.map +1 -0
- package/dist/data/traces/otel/source.js +10 -0
- package/dist/data/traces/otel/source.js.map +1 -0
- package/dist/data/traces/otel/span-traces.cjs +39 -0
- package/dist/data/traces/otel/span-traces.cjs.map +1 -0
- package/dist/data/traces/otel/span-traces.d.ts +3 -0
- package/dist/data/traces/otel/span-traces.d.ts.map +1 -0
- package/dist/data/traces/otel/span-traces.js +39 -0
- package/dist/data/traces/otel/span-traces.js.map +1 -0
- package/dist/data/version-info.cjs +3 -3
- package/dist/data/version-info.js +3 -3
- package/dist/data.cjs +11 -0
- package/dist/data.js +6 -1
- package/dist/index.cjs +11 -0
- package/dist/index.js +6 -1
- package/dist/profiles/editor/profileEditorSections.cjs +4 -0
- package/dist/profiles/editor/profileEditorSections.cjs.map +1 -1
- package/dist/profiles/editor/profileEditorSections.d.ts.map +1 -1
- package/dist/profiles/editor/profileEditorSections.js +4 -0
- package/dist/profiles/editor/profileEditorSections.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
const require_SegmentedControl = require("../../../components/SegmentedControl.cjs");
|
|
2
|
+
const require_FilterBar = require("../../../components/FilterBar.cjs");
|
|
3
|
+
const require_query = require("./query.cjs");
|
|
4
|
+
const require_source = require("./source.cjs");
|
|
5
|
+
let react_jsx_runtime = require("react/jsx-runtime");
|
|
6
|
+
// src/data/traces/otel/QueryBar.tsx
|
|
7
|
+
function chooseSource(choice) {
|
|
8
|
+
if (choice === "received") return {
|
|
9
|
+
source: "records",
|
|
10
|
+
run: require_source.RECEIVER_RUN,
|
|
11
|
+
index: void 0,
|
|
12
|
+
format: void 0
|
|
13
|
+
};
|
|
14
|
+
return {
|
|
15
|
+
source: choice,
|
|
16
|
+
run: void 0,
|
|
17
|
+
index: void 0,
|
|
18
|
+
format: void 0
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
/** Options for a filter, keeping its selected values listed while the result that suggests them loads. */
|
|
22
|
+
function withSelected(options, selected) {
|
|
23
|
+
const listed = new Set(options.map((option) => option.value));
|
|
24
|
+
return [...options, ...Object.keys(selected ?? {}).filter((value) => !listed.has(value)).map((value) => ({
|
|
25
|
+
value,
|
|
26
|
+
label: value
|
|
27
|
+
}))];
|
|
28
|
+
}
|
|
29
|
+
/** One line of trace filters: source, services, root operations, attributes, status, duration, span count and the time window. */
|
|
30
|
+
function QueryBar({ value, onChange, onError, sources, runs, result, allowRecords = true }) {
|
|
31
|
+
const choice = require_source.sourceChoice(value);
|
|
32
|
+
const connection = sources.find((source) => source.id === value.source && source.id !== "records");
|
|
33
|
+
const multi = (key, label, options, extra = {}) => ({
|
|
34
|
+
...extra,
|
|
35
|
+
key,
|
|
36
|
+
kind: "multi",
|
|
37
|
+
label,
|
|
38
|
+
value: value[key] ?? {},
|
|
39
|
+
onChange: (next) => onChange({ [key]: next }),
|
|
40
|
+
options: withSelected(options, value[key])
|
|
41
|
+
});
|
|
42
|
+
const filters = [
|
|
43
|
+
multi("services", "Service", (result?.services ?? []).map((service) => ({
|
|
44
|
+
value: service,
|
|
45
|
+
label: service
|
|
46
|
+
}))),
|
|
47
|
+
multi("operations", "Root operation", (result?.rootOperations ?? []).map(({ operation }) => ({
|
|
48
|
+
value: operation,
|
|
49
|
+
label: require_query.shortOperation(operation),
|
|
50
|
+
...operation !== require_query.shortOperation(operation) ? { description: operation } : {}
|
|
51
|
+
}))),
|
|
52
|
+
multi("attributes", "Attributes", (result?.attributes ?? []).map(({ value: expr, count }) => ({
|
|
53
|
+
value: expr,
|
|
54
|
+
label: expr,
|
|
55
|
+
description: `${count} traces`
|
|
56
|
+
})), {
|
|
57
|
+
allowCustomValue: true,
|
|
58
|
+
placeholder: "key=value",
|
|
59
|
+
description: "Any span's attribute: key=value, key=prefix*, or a bare key to match its presence."
|
|
60
|
+
}),
|
|
61
|
+
multi("statuses", "Status", [{
|
|
62
|
+
value: "ok",
|
|
63
|
+
label: "OK"
|
|
64
|
+
}, {
|
|
65
|
+
value: "error",
|
|
66
|
+
label: "Error"
|
|
67
|
+
}]),
|
|
68
|
+
{
|
|
69
|
+
key: "duration",
|
|
70
|
+
kind: "duration",
|
|
71
|
+
label: "Duration",
|
|
72
|
+
value: require_query.durationOf(value),
|
|
73
|
+
onChange: (next) => onChange(require_query.durationRequest(next)),
|
|
74
|
+
unit: "s"
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
key: "hide-single",
|
|
78
|
+
kind: "boolean",
|
|
79
|
+
label: "Hide single-span traces",
|
|
80
|
+
value: (value.minSpans ?? 0) >= 2,
|
|
81
|
+
onChange: (hide) => onChange({ minSpans: hide ? 2 : void 0 })
|
|
82
|
+
}
|
|
83
|
+
];
|
|
84
|
+
if (choice === "records") filters.push({
|
|
85
|
+
key: "run",
|
|
86
|
+
kind: "enum",
|
|
87
|
+
label: "Run",
|
|
88
|
+
value: value.run ?? "",
|
|
89
|
+
onChange: (run) => onChange({ run: run || void 0 }),
|
|
90
|
+
options: [{
|
|
91
|
+
value: "",
|
|
92
|
+
label: "Every run"
|
|
93
|
+
}, ...runs.filter((run) => run !== require_source.RECEIVER_RUN).map((run) => ({ value: run }))]
|
|
94
|
+
});
|
|
95
|
+
if (connection) filters.push({
|
|
96
|
+
key: "index",
|
|
97
|
+
kind: "text",
|
|
98
|
+
label: "Index",
|
|
99
|
+
value: value.index ?? "",
|
|
100
|
+
onChange: (index) => onChange({ index: index || void 0 }),
|
|
101
|
+
placement: "overflow"
|
|
102
|
+
}, {
|
|
103
|
+
key: "format",
|
|
104
|
+
kind: "enum",
|
|
105
|
+
label: "Document format",
|
|
106
|
+
value: value.format ?? "",
|
|
107
|
+
onChange: (format) => onChange({ format: format || void 0 }),
|
|
108
|
+
options: [
|
|
109
|
+
{
|
|
110
|
+
value: "",
|
|
111
|
+
label: "Connection default"
|
|
112
|
+
},
|
|
113
|
+
{ value: "flat" },
|
|
114
|
+
{ value: "jaeger" }
|
|
115
|
+
],
|
|
116
|
+
placement: "overflow"
|
|
117
|
+
});
|
|
118
|
+
const range = require_query.rangeOf(value);
|
|
119
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_FilterBar.FilterBar, {
|
|
120
|
+
leading: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_SegmentedControl.SegmentedControl, {
|
|
121
|
+
"aria-label": "Source",
|
|
122
|
+
size: "sm",
|
|
123
|
+
value: choice,
|
|
124
|
+
onChange: (next) => onChange(chooseSource(next)),
|
|
125
|
+
options: [
|
|
126
|
+
...runs.includes("receiver") ? [{
|
|
127
|
+
id: "received",
|
|
128
|
+
label: "Received"
|
|
129
|
+
}] : [],
|
|
130
|
+
...allowRecords ? [{
|
|
131
|
+
id: "records",
|
|
132
|
+
label: "Recorded"
|
|
133
|
+
}] : [],
|
|
134
|
+
...sources.filter((source) => source.id !== "records").map((source) => ({
|
|
135
|
+
id: source.id,
|
|
136
|
+
label: source.name
|
|
137
|
+
}))
|
|
138
|
+
]
|
|
139
|
+
}),
|
|
140
|
+
filters,
|
|
141
|
+
timeRange: {
|
|
142
|
+
from: range.from,
|
|
143
|
+
to: range.to,
|
|
144
|
+
timeEnabled: true,
|
|
145
|
+
emptyLabel: "Last hour",
|
|
146
|
+
onApply: (from, to) => {
|
|
147
|
+
try {
|
|
148
|
+
onChange(require_query.windowOf(from, to, Date.now()));
|
|
149
|
+
} catch (error) {
|
|
150
|
+
onError(error instanceof Error ? error.message : String(error));
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
exports.QueryBar = QueryBar;
|
|
157
|
+
|
|
158
|
+
//# sourceMappingURL=QueryBar.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"QueryBar.cjs","names":["RECEIVER_RUN","sourceChoice","shortOperation","durationOf","durationRequest","rangeOf","FilterBar","SegmentedControl","windowOf"],"sources":["../../../../src/data/traces/otel/QueryBar.tsx"],"sourcesContent":["import { RECEIVER_RUN, sourceChoice } from \"./source\";\nimport { FilterBar, SegmentedControl, type FilterBarFilter, type FilterBarMultiFilter } from \"../../../components\";\nimport type { ModeFilter, Modes, SearchResult, SearchValues, Source } from \"./api\";\nimport { durationOf, durationRequest, MULTI_SPAN, rangeOf, shortOperation, windowOf } from \"./query\";\n\nfunction chooseSource(choice: string): SearchValues {\n if (choice === \"received\") return { source: \"records\", run: RECEIVER_RUN, index: undefined, format: undefined };\n return { source: choice, run: undefined, index: undefined, format: undefined };\n}\n\n/** Options for a filter, keeping its selected values listed while the result that suggests them loads. */\nfunction withSelected(options: { value: string; label: string; description?: string }[], selected: Modes | undefined) {\n const listed = new Set(options.map(option => option.value));\n return [...options, ...Object.keys(selected ?? {}).filter(value => !listed.has(value)).map(value => ({ value, label: value }))];\n}\n\n/** One line of trace filters: source, services, root operations, attributes, status, duration, span count and the time window. */\nexport function QueryBar({ value, onChange, onError, sources, runs, result, allowRecords = true }: {\n value: SearchValues;\n onChange: (next: Partial<SearchValues>) => void;\n onError: (message: string) => void;\n sources: Source[];\n runs: string[];\n result?: SearchResult;\n allowRecords?: boolean;\n}) {\n const choice = sourceChoice(value);\n const connection = sources.find(source => source.id === value.source && source.id !== \"records\");\n const multi = (key: ModeFilter, label: string, options: { value: string; label: string; description?: string }[], extra: Partial<FilterBarMultiFilter> = {}): FilterBarMultiFilter => ({\n ...extra, key, kind: \"multi\", label, value: value[key] ?? {}, onChange: next => onChange({ [key]: next }), options: withSelected(options, value[key]),\n });\n const filters: FilterBarFilter[] = [\n multi(\"services\", \"Service\", (result?.services ?? []).map(service => ({ value: service, label: service }))),\n multi(\"operations\", \"Root operation\", (result?.rootOperations ?? []).map(({ operation }) => ({\n value: operation, label: shortOperation(operation), ...(operation !== shortOperation(operation) ? { description: operation } : {}),\n }))),\n multi(\"attributes\", \"Attributes\", (result?.attributes ?? []).map(({ value: expr, count }) => ({ value: expr, label: expr, description: `${count} traces` })), {\n allowCustomValue: true, placeholder: \"key=value\", description: \"Any span's attribute: key=value, key=prefix*, or a bare key to match its presence.\",\n }),\n multi(\"statuses\", \"Status\", [{ value: \"ok\", label: \"OK\" }, { value: \"error\", label: \"Error\" }]),\n { key: \"duration\", kind: \"duration\", label: \"Duration\", value: durationOf(value), onChange: next => onChange(durationRequest(next)), unit: \"s\" },\n { key: \"hide-single\", kind: \"boolean\", label: \"Hide single-span traces\", value: (value.minSpans ?? 0) >= MULTI_SPAN, onChange: hide => onChange({ minSpans: hide ? MULTI_SPAN : undefined }) },\n ];\n if (choice === \"records\") filters.push({\n key: \"run\", kind: \"enum\", label: \"Run\", value: value.run ?? \"\", onChange: run => onChange({ run: run || undefined }),\n options: [{ value: \"\", label: \"Every run\" }, ...runs.filter(run => run !== RECEIVER_RUN).map(run => ({ value: run }))],\n });\n if (connection) filters.push(\n { key: \"index\", kind: \"text\", label: \"Index\", value: value.index ?? \"\", onChange: index => onChange({ index: index || undefined }), placement: \"overflow\" },\n { key: \"format\", kind: \"enum\", label: \"Document format\", value: value.format ?? \"\", onChange: format => onChange({ format: format || undefined }), options: [{ value: \"\", label: \"Connection default\" }, { value: \"flat\" }, { value: \"jaeger\" }], placement: \"overflow\" },\n );\n const range = rangeOf(value);\n return (\n <FilterBar\n leading={\n <SegmentedControl\n aria-label=\"Source\"\n size=\"sm\"\n value={choice}\n onChange={next => onChange(chooseSource(next))}\n options={[\n ...(runs.includes(RECEIVER_RUN) ? [{ id: \"received\", label: \"Received\" }] : []),\n ...(allowRecords ? [{ id: \"records\", label: \"Recorded\" }] : []),\n ...sources.filter(source => source.id !== \"records\").map(source => ({ id: source.id, label: source.name })),\n ]}\n />\n }\n filters={filters}\n timeRange={{\n from: range.from, to: range.to, timeEnabled: true, emptyLabel: \"Last hour\",\n onApply: (from, to) => {\n try {\n onChange(windowOf(from, to, Date.now()));\n } catch (error) {\n onError(error instanceof Error ? error.message : String(error));\n }\n },\n }}\n />\n );\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { SearchResult, SearchValues, Source } from './api.js';
|
|
2
|
+
/** One line of trace filters: source, services, root operations, attributes, status, duration, span count and the time window. */
|
|
3
|
+
export declare function QueryBar({ value, onChange, onError, sources, runs, result, allowRecords }: {
|
|
4
|
+
value: SearchValues;
|
|
5
|
+
onChange: (next: Partial<SearchValues>) => void;
|
|
6
|
+
onError: (message: string) => void;
|
|
7
|
+
sources: Source[];
|
|
8
|
+
runs: string[];
|
|
9
|
+
result?: SearchResult;
|
|
10
|
+
allowRecords?: boolean;
|
|
11
|
+
}): import("react").JSX.Element;
|
|
12
|
+
//# sourceMappingURL=QueryBar.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"QueryBar.d.ts","sourceRoot":"","sources":["../../../../src/data/traces/otel/QueryBar.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAqB,YAAY,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAcnF,kIAAkI;AAClI,wBAAgB,QAAQ,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,YAAmB,EAAE,EAAE;IACjG,KAAK,EAAE,YAAY,CAAC;IACpB,QAAQ,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,YAAY,CAAC,KAAK,IAAI,CAAC;IAChD,OAAO,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB,+BAuDA"}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import { SegmentedControl } from "../../../components/SegmentedControl.js";
|
|
2
|
+
import { FilterBar } from "../../../components/FilterBar.js";
|
|
3
|
+
import { durationOf, durationRequest, rangeOf, shortOperation, windowOf } from "./query.js";
|
|
4
|
+
import { RECEIVER_RUN, sourceChoice } from "./source.js";
|
|
5
|
+
import { jsx } from "react/jsx-runtime";
|
|
6
|
+
// src/data/traces/otel/QueryBar.tsx
|
|
7
|
+
function chooseSource(choice) {
|
|
8
|
+
if (choice === "received") return {
|
|
9
|
+
source: "records",
|
|
10
|
+
run: RECEIVER_RUN,
|
|
11
|
+
index: void 0,
|
|
12
|
+
format: void 0
|
|
13
|
+
};
|
|
14
|
+
return {
|
|
15
|
+
source: choice,
|
|
16
|
+
run: void 0,
|
|
17
|
+
index: void 0,
|
|
18
|
+
format: void 0
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
/** Options for a filter, keeping its selected values listed while the result that suggests them loads. */
|
|
22
|
+
function withSelected(options, selected) {
|
|
23
|
+
const listed = new Set(options.map((option) => option.value));
|
|
24
|
+
return [...options, ...Object.keys(selected ?? {}).filter((value) => !listed.has(value)).map((value) => ({
|
|
25
|
+
value,
|
|
26
|
+
label: value
|
|
27
|
+
}))];
|
|
28
|
+
}
|
|
29
|
+
/** One line of trace filters: source, services, root operations, attributes, status, duration, span count and the time window. */
|
|
30
|
+
function QueryBar({ value, onChange, onError, sources, runs, result, allowRecords = true }) {
|
|
31
|
+
const choice = sourceChoice(value);
|
|
32
|
+
const connection = sources.find((source) => source.id === value.source && source.id !== "records");
|
|
33
|
+
const multi = (key, label, options, extra = {}) => ({
|
|
34
|
+
...extra,
|
|
35
|
+
key,
|
|
36
|
+
kind: "multi",
|
|
37
|
+
label,
|
|
38
|
+
value: value[key] ?? {},
|
|
39
|
+
onChange: (next) => onChange({ [key]: next }),
|
|
40
|
+
options: withSelected(options, value[key])
|
|
41
|
+
});
|
|
42
|
+
const filters = [
|
|
43
|
+
multi("services", "Service", (result?.services ?? []).map((service) => ({
|
|
44
|
+
value: service,
|
|
45
|
+
label: service
|
|
46
|
+
}))),
|
|
47
|
+
multi("operations", "Root operation", (result?.rootOperations ?? []).map(({ operation }) => ({
|
|
48
|
+
value: operation,
|
|
49
|
+
label: shortOperation(operation),
|
|
50
|
+
...operation !== shortOperation(operation) ? { description: operation } : {}
|
|
51
|
+
}))),
|
|
52
|
+
multi("attributes", "Attributes", (result?.attributes ?? []).map(({ value: expr, count }) => ({
|
|
53
|
+
value: expr,
|
|
54
|
+
label: expr,
|
|
55
|
+
description: `${count} traces`
|
|
56
|
+
})), {
|
|
57
|
+
allowCustomValue: true,
|
|
58
|
+
placeholder: "key=value",
|
|
59
|
+
description: "Any span's attribute: key=value, key=prefix*, or a bare key to match its presence."
|
|
60
|
+
}),
|
|
61
|
+
multi("statuses", "Status", [{
|
|
62
|
+
value: "ok",
|
|
63
|
+
label: "OK"
|
|
64
|
+
}, {
|
|
65
|
+
value: "error",
|
|
66
|
+
label: "Error"
|
|
67
|
+
}]),
|
|
68
|
+
{
|
|
69
|
+
key: "duration",
|
|
70
|
+
kind: "duration",
|
|
71
|
+
label: "Duration",
|
|
72
|
+
value: durationOf(value),
|
|
73
|
+
onChange: (next) => onChange(durationRequest(next)),
|
|
74
|
+
unit: "s"
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
key: "hide-single",
|
|
78
|
+
kind: "boolean",
|
|
79
|
+
label: "Hide single-span traces",
|
|
80
|
+
value: (value.minSpans ?? 0) >= 2,
|
|
81
|
+
onChange: (hide) => onChange({ minSpans: hide ? 2 : void 0 })
|
|
82
|
+
}
|
|
83
|
+
];
|
|
84
|
+
if (choice === "records") filters.push({
|
|
85
|
+
key: "run",
|
|
86
|
+
kind: "enum",
|
|
87
|
+
label: "Run",
|
|
88
|
+
value: value.run ?? "",
|
|
89
|
+
onChange: (run) => onChange({ run: run || void 0 }),
|
|
90
|
+
options: [{
|
|
91
|
+
value: "",
|
|
92
|
+
label: "Every run"
|
|
93
|
+
}, ...runs.filter((run) => run !== RECEIVER_RUN).map((run) => ({ value: run }))]
|
|
94
|
+
});
|
|
95
|
+
if (connection) filters.push({
|
|
96
|
+
key: "index",
|
|
97
|
+
kind: "text",
|
|
98
|
+
label: "Index",
|
|
99
|
+
value: value.index ?? "",
|
|
100
|
+
onChange: (index) => onChange({ index: index || void 0 }),
|
|
101
|
+
placement: "overflow"
|
|
102
|
+
}, {
|
|
103
|
+
key: "format",
|
|
104
|
+
kind: "enum",
|
|
105
|
+
label: "Document format",
|
|
106
|
+
value: value.format ?? "",
|
|
107
|
+
onChange: (format) => onChange({ format: format || void 0 }),
|
|
108
|
+
options: [
|
|
109
|
+
{
|
|
110
|
+
value: "",
|
|
111
|
+
label: "Connection default"
|
|
112
|
+
},
|
|
113
|
+
{ value: "flat" },
|
|
114
|
+
{ value: "jaeger" }
|
|
115
|
+
],
|
|
116
|
+
placement: "overflow"
|
|
117
|
+
});
|
|
118
|
+
const range = rangeOf(value);
|
|
119
|
+
return /* @__PURE__ */ jsx(FilterBar, {
|
|
120
|
+
leading: /* @__PURE__ */ jsx(SegmentedControl, {
|
|
121
|
+
"aria-label": "Source",
|
|
122
|
+
size: "sm",
|
|
123
|
+
value: choice,
|
|
124
|
+
onChange: (next) => onChange(chooseSource(next)),
|
|
125
|
+
options: [
|
|
126
|
+
...runs.includes("receiver") ? [{
|
|
127
|
+
id: "received",
|
|
128
|
+
label: "Received"
|
|
129
|
+
}] : [],
|
|
130
|
+
...allowRecords ? [{
|
|
131
|
+
id: "records",
|
|
132
|
+
label: "Recorded"
|
|
133
|
+
}] : [],
|
|
134
|
+
...sources.filter((source) => source.id !== "records").map((source) => ({
|
|
135
|
+
id: source.id,
|
|
136
|
+
label: source.name
|
|
137
|
+
}))
|
|
138
|
+
]
|
|
139
|
+
}),
|
|
140
|
+
filters,
|
|
141
|
+
timeRange: {
|
|
142
|
+
from: range.from,
|
|
143
|
+
to: range.to,
|
|
144
|
+
timeEnabled: true,
|
|
145
|
+
emptyLabel: "Last hour",
|
|
146
|
+
onApply: (from, to) => {
|
|
147
|
+
try {
|
|
148
|
+
onChange(windowOf(from, to, Date.now()));
|
|
149
|
+
} catch (error) {
|
|
150
|
+
onError(error instanceof Error ? error.message : String(error));
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
export { QueryBar };
|
|
157
|
+
|
|
158
|
+
//# sourceMappingURL=QueryBar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"QueryBar.js","names":[],"sources":["../../../../src/data/traces/otel/QueryBar.tsx"],"sourcesContent":["import { RECEIVER_RUN, sourceChoice } from \"./source\";\nimport { FilterBar, SegmentedControl, type FilterBarFilter, type FilterBarMultiFilter } from \"../../../components\";\nimport type { ModeFilter, Modes, SearchResult, SearchValues, Source } from \"./api\";\nimport { durationOf, durationRequest, MULTI_SPAN, rangeOf, shortOperation, windowOf } from \"./query\";\n\nfunction chooseSource(choice: string): SearchValues {\n if (choice === \"received\") return { source: \"records\", run: RECEIVER_RUN, index: undefined, format: undefined };\n return { source: choice, run: undefined, index: undefined, format: undefined };\n}\n\n/** Options for a filter, keeping its selected values listed while the result that suggests them loads. */\nfunction withSelected(options: { value: string; label: string; description?: string }[], selected: Modes | undefined) {\n const listed = new Set(options.map(option => option.value));\n return [...options, ...Object.keys(selected ?? {}).filter(value => !listed.has(value)).map(value => ({ value, label: value }))];\n}\n\n/** One line of trace filters: source, services, root operations, attributes, status, duration, span count and the time window. */\nexport function QueryBar({ value, onChange, onError, sources, runs, result, allowRecords = true }: {\n value: SearchValues;\n onChange: (next: Partial<SearchValues>) => void;\n onError: (message: string) => void;\n sources: Source[];\n runs: string[];\n result?: SearchResult;\n allowRecords?: boolean;\n}) {\n const choice = sourceChoice(value);\n const connection = sources.find(source => source.id === value.source && source.id !== \"records\");\n const multi = (key: ModeFilter, label: string, options: { value: string; label: string; description?: string }[], extra: Partial<FilterBarMultiFilter> = {}): FilterBarMultiFilter => ({\n ...extra, key, kind: \"multi\", label, value: value[key] ?? {}, onChange: next => onChange({ [key]: next }), options: withSelected(options, value[key]),\n });\n const filters: FilterBarFilter[] = [\n multi(\"services\", \"Service\", (result?.services ?? []).map(service => ({ value: service, label: service }))),\n multi(\"operations\", \"Root operation\", (result?.rootOperations ?? []).map(({ operation }) => ({\n value: operation, label: shortOperation(operation), ...(operation !== shortOperation(operation) ? { description: operation } : {}),\n }))),\n multi(\"attributes\", \"Attributes\", (result?.attributes ?? []).map(({ value: expr, count }) => ({ value: expr, label: expr, description: `${count} traces` })), {\n allowCustomValue: true, placeholder: \"key=value\", description: \"Any span's attribute: key=value, key=prefix*, or a bare key to match its presence.\",\n }),\n multi(\"statuses\", \"Status\", [{ value: \"ok\", label: \"OK\" }, { value: \"error\", label: \"Error\" }]),\n { key: \"duration\", kind: \"duration\", label: \"Duration\", value: durationOf(value), onChange: next => onChange(durationRequest(next)), unit: \"s\" },\n { key: \"hide-single\", kind: \"boolean\", label: \"Hide single-span traces\", value: (value.minSpans ?? 0) >= MULTI_SPAN, onChange: hide => onChange({ minSpans: hide ? MULTI_SPAN : undefined }) },\n ];\n if (choice === \"records\") filters.push({\n key: \"run\", kind: \"enum\", label: \"Run\", value: value.run ?? \"\", onChange: run => onChange({ run: run || undefined }),\n options: [{ value: \"\", label: \"Every run\" }, ...runs.filter(run => run !== RECEIVER_RUN).map(run => ({ value: run }))],\n });\n if (connection) filters.push(\n { key: \"index\", kind: \"text\", label: \"Index\", value: value.index ?? \"\", onChange: index => onChange({ index: index || undefined }), placement: \"overflow\" },\n { key: \"format\", kind: \"enum\", label: \"Document format\", value: value.format ?? \"\", onChange: format => onChange({ format: format || undefined }), options: [{ value: \"\", label: \"Connection default\" }, { value: \"flat\" }, { value: \"jaeger\" }], placement: \"overflow\" },\n );\n const range = rangeOf(value);\n return (\n <FilterBar\n leading={\n <SegmentedControl\n aria-label=\"Source\"\n size=\"sm\"\n value={choice}\n onChange={next => onChange(chooseSource(next))}\n options={[\n ...(runs.includes(RECEIVER_RUN) ? [{ id: \"received\", label: \"Received\" }] : []),\n ...(allowRecords ? [{ id: \"records\", label: \"Recorded\" }] : []),\n ...sources.filter(source => source.id !== \"records\").map(source => ({ id: source.id, label: source.name })),\n ]}\n />\n }\n filters={filters}\n timeRange={{\n from: range.from, to: range.to, timeEnabled: true, emptyLabel: \"Last hour\",\n onApply: (from, to) => {\n try {\n onChange(windowOf(from, to, Date.now()));\n } catch (error) {\n onError(error instanceof Error ? error.message : String(error));\n }\n },\n }}\n />\n );\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
const require_UiSqlQuery = require("../../../icons/components/UiSqlQuery.cjs");
|
|
2
|
+
const require_UiDatabase = require("../../../icons/components/UiDatabase.cjs");
|
|
3
|
+
const require_Icon = require("../../Icon.cjs");
|
|
4
|
+
const require_button = require("../../../components/button.cjs");
|
|
5
|
+
const require_Properties = require("../../Properties.cjs");
|
|
6
|
+
const require_CodeBlock = require("../../CodeBlock.cjs");
|
|
7
|
+
const require_StatStrip = require("../../StatStrip.cjs");
|
|
8
|
+
const require_SpanCategory = require("./SpanCategory.cjs");
|
|
9
|
+
const require_model = require("./model.cjs");
|
|
10
|
+
const require_metrics = require("./metrics.cjs");
|
|
11
|
+
let react = require("react");
|
|
12
|
+
let react_jsx_runtime = require("react/jsx-runtime");
|
|
13
|
+
// src/data/traces/otel/SpanCards.tsx
|
|
14
|
+
var attr = (span, key) => span.attributes?.[key];
|
|
15
|
+
function AgentCard({ index, span }) {
|
|
16
|
+
const cost = require_model.num(attr(span, "captain.cost_usd"));
|
|
17
|
+
const budget = require_model.num(attr(span, "captain.budget.cost_usd"));
|
|
18
|
+
const kids = index.children.get(span.spanId) ?? [];
|
|
19
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
20
|
+
className: "space-y-3",
|
|
21
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_StatStrip.StatStrip, {
|
|
22
|
+
columns: 3,
|
|
23
|
+
items: [
|
|
24
|
+
{
|
|
25
|
+
label: "Iterations",
|
|
26
|
+
value: `${attr(span, "captain.iterations") ?? "—"} / ${attr(span, "captain.max_iterations") ?? "—"}`
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
label: "Stopped",
|
|
30
|
+
value: String(attr(span, "captain.stop_reason") ?? "—"),
|
|
31
|
+
tone: attr(span, "captain.verified") === true ? "success" : "warning",
|
|
32
|
+
sub: attr(span, "captain.verified") === true ? "verified" : "not verified"
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
label: "Cost",
|
|
36
|
+
value: require_metrics.metric(cost, (value) => `$${value.toFixed(5)}`),
|
|
37
|
+
sub: budget && cost !== void 0 ? `${(cost / budget * 100).toFixed(3)}% of $${budget}` : "budget unavailable"
|
|
38
|
+
}
|
|
39
|
+
]
|
|
40
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Properties.Properties, { items: [
|
|
41
|
+
{
|
|
42
|
+
key: "Prompt",
|
|
43
|
+
value: String(attr(span, "gen_ai.agent.name") ?? "—")
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
key: "Scope",
|
|
47
|
+
value: String(attr(span, "captain.scope") ?? "—")
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
key: "Children",
|
|
51
|
+
value: `${kids.length} spans · ${kids.filter((k) => require_model.category(k) === "llm").length} LLM · ${kids.filter((k) => require_model.category(k) === "db").length} DB`
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
key: "Self-time",
|
|
55
|
+
value: `${require_model.duration(require_model.selfTimeMs(index, span))} not covered by a child span`
|
|
56
|
+
}
|
|
57
|
+
] })]
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
function LlmCard({ span }) {
|
|
61
|
+
const n = (key) => require_model.num(attr(span, key));
|
|
62
|
+
const requested = attr(span, "gen_ai.request.model");
|
|
63
|
+
const served = attr(span, "gen_ai.response.model");
|
|
64
|
+
const output = n("gen_ai.usage.output_tokens");
|
|
65
|
+
const outRate = output !== void 0 && span.durationMs > 0 ? output / (span.durationMs / 1e3) : void 0;
|
|
66
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
67
|
+
className: "space-y-3",
|
|
68
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
|
|
69
|
+
className: "text-sm",
|
|
70
|
+
children: [
|
|
71
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
72
|
+
className: "text-muted-foreground",
|
|
73
|
+
children: [String(attr(span, "gen_ai.provider.name") ?? "—"), " · "]
|
|
74
|
+
}),
|
|
75
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("code", { children: String(requested ?? "—") }),
|
|
76
|
+
served !== void 0 && served !== requested && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [" → ", /* @__PURE__ */ (0, react_jsx_runtime.jsx)("code", { children: String(served ?? "—") })] }),
|
|
77
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
78
|
+
className: "text-muted-foreground",
|
|
79
|
+
children: [
|
|
80
|
+
" · ",
|
|
81
|
+
String(attr(span, "captain.mode") ?? "—"),
|
|
82
|
+
" · ",
|
|
83
|
+
String(attr(span, "captain.prompt.source") ?? "—")
|
|
84
|
+
]
|
|
85
|
+
})
|
|
86
|
+
]
|
|
87
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_StatStrip.StatStrip, {
|
|
88
|
+
columns: 4,
|
|
89
|
+
items: [
|
|
90
|
+
{
|
|
91
|
+
label: "Input",
|
|
92
|
+
value: require_metrics.metric(n("gen_ai.usage.input_tokens")),
|
|
93
|
+
sub: `${require_metrics.metric(n("gen_ai.usage.cache_read.input_tokens"))} cached`
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
label: "Output",
|
|
97
|
+
value: require_metrics.metric(n("gen_ai.usage.output_tokens")),
|
|
98
|
+
sub: `${require_metrics.metric(n("gen_ai.usage.reasoning_tokens"))} reasoning`
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
label: "Throughput",
|
|
102
|
+
value: require_metrics.metric(outRate, (value) => value.toFixed(0)),
|
|
103
|
+
sub: "output tok/s"
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
label: "Cost",
|
|
107
|
+
value: require_metrics.metric(n("captain.cost_usd"), (value) => `$${value.toFixed(5)}`)
|
|
108
|
+
}
|
|
109
|
+
]
|
|
110
|
+
})]
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
var PREVIEW_CHARS = 1200;
|
|
114
|
+
function DbCard({ span }) {
|
|
115
|
+
const statement = String(attr(span, "db.statement") ?? "");
|
|
116
|
+
const [full, setFull] = (0, react.useState)(false);
|
|
117
|
+
(0, react.useEffect)(() => setFull(false), [span.spanId]);
|
|
118
|
+
const clipped = statement.length > PREVIEW_CHARS && !full;
|
|
119
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
120
|
+
className: "space-y-3",
|
|
121
|
+
children: [
|
|
122
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
|
|
123
|
+
className: "text-sm",
|
|
124
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
125
|
+
className: "text-muted-foreground",
|
|
126
|
+
children: [String(attr(span, "db.system")), " · "]
|
|
127
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("code", { children: String(attr(span, "db.sql.table") ?? "no table") })]
|
|
128
|
+
}),
|
|
129
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_StatStrip.StatStrip, {
|
|
130
|
+
columns: 2,
|
|
131
|
+
items: [{
|
|
132
|
+
label: "Rows affected",
|
|
133
|
+
value: String(attr(span, "db.rows_affected") ?? "—")
|
|
134
|
+
}, {
|
|
135
|
+
label: "Statement",
|
|
136
|
+
value: `${(statement.length / 1024).toFixed(statement.length > 10240 ? 0 : 1)} KB`,
|
|
137
|
+
sub: span.operation.replace("gorm.", ""),
|
|
138
|
+
tone: statement.length > 10240 ? "warning" : "neutral"
|
|
139
|
+
}]
|
|
140
|
+
}),
|
|
141
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
142
|
+
className: "space-y-1",
|
|
143
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_CodeBlock.CodeBlock, {
|
|
144
|
+
language: "sql",
|
|
145
|
+
source: clipped ? `${statement.slice(0, PREVIEW_CHARS)} …` : statement,
|
|
146
|
+
copyable: true
|
|
147
|
+
}), statement.length > PREVIEW_CHARS && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_button.Button, {
|
|
148
|
+
size: "sm",
|
|
149
|
+
variant: "ghost",
|
|
150
|
+
onClick: () => setFull((on) => !on),
|
|
151
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Icon.Icon, {
|
|
152
|
+
icon: require_UiSqlQuery.UiSqlQuery,
|
|
153
|
+
className: "mr-1"
|
|
154
|
+
}), full ? "Clip statement" : `Show all ${statement.length.toLocaleString()} characters`]
|
|
155
|
+
})]
|
|
156
|
+
})
|
|
157
|
+
]
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
function GroupDetail({ index, spans, onSelect }) {
|
|
161
|
+
const busy = spans.reduce((total, span) => total + span.durationMs, 0);
|
|
162
|
+
const tables = /* @__PURE__ */ new Map();
|
|
163
|
+
for (const span of spans) {
|
|
164
|
+
const key = String(attr(span, "db.sql.table") ?? "—");
|
|
165
|
+
const entry = tables.get(key) ?? {
|
|
166
|
+
calls: 0,
|
|
167
|
+
ms: 0
|
|
168
|
+
};
|
|
169
|
+
tables.set(key, {
|
|
170
|
+
calls: entry.calls + 1,
|
|
171
|
+
ms: entry.ms + span.durationMs
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
const slowest = [...spans].sort((a, b) => b.durationMs - a.durationMs)[0];
|
|
175
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
176
|
+
className: "space-y-4",
|
|
177
|
+
children: [
|
|
178
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("h3", {
|
|
179
|
+
className: "flex items-center gap-2 text-base font-semibold",
|
|
180
|
+
children: [
|
|
181
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_SpanCategory.Tinted, {
|
|
182
|
+
icon: require_UiDatabase.UiDatabase,
|
|
183
|
+
color: require_model.CATEGORY_COLOR.db
|
|
184
|
+
}),
|
|
185
|
+
spans.length,
|
|
186
|
+
" consecutive database calls"
|
|
187
|
+
]
|
|
188
|
+
}),
|
|
189
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_StatStrip.StatStrip, {
|
|
190
|
+
columns: 3,
|
|
191
|
+
items: [
|
|
192
|
+
{
|
|
193
|
+
label: "Busy",
|
|
194
|
+
value: require_model.duration(busy),
|
|
195
|
+
sub: `over ${require_model.duration(index.offsetMs(spans.at(-1)) + spans.at(-1).durationMs - index.offsetMs(spans[0]))} wall`
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
label: "Tables",
|
|
199
|
+
value: String(tables.size)
|
|
200
|
+
},
|
|
201
|
+
{
|
|
202
|
+
label: "Slowest",
|
|
203
|
+
value: require_model.duration(slowest.durationMs),
|
|
204
|
+
sub: `${slowest.operation.replace("gorm.", "")} ${String(attr(slowest, "db.sql.table"))}`
|
|
205
|
+
}
|
|
206
|
+
]
|
|
207
|
+
}),
|
|
208
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("table", {
|
|
209
|
+
className: "w-full text-xs",
|
|
210
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("thead", {
|
|
211
|
+
className: "border-b border-border text-left text-muted-foreground",
|
|
212
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("tr", { children: [
|
|
213
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", {
|
|
214
|
+
className: "py-1 font-medium",
|
|
215
|
+
children: "Call"
|
|
216
|
+
}),
|
|
217
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", {
|
|
218
|
+
className: "py-1 font-medium",
|
|
219
|
+
children: "Table"
|
|
220
|
+
}),
|
|
221
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", {
|
|
222
|
+
className: "py-1 text-right font-medium",
|
|
223
|
+
children: "Rows"
|
|
224
|
+
}),
|
|
225
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", {
|
|
226
|
+
className: "py-1 text-right font-medium",
|
|
227
|
+
children: "Duration"
|
|
228
|
+
})
|
|
229
|
+
] })
|
|
230
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("tbody", {
|
|
231
|
+
className: "divide-y divide-border",
|
|
232
|
+
children: spans.map((span) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("tr", {
|
|
233
|
+
className: "cursor-pointer hover:bg-muted",
|
|
234
|
+
onClick: () => onSelect(span.spanId),
|
|
235
|
+
children: [
|
|
236
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", {
|
|
237
|
+
className: "py-1",
|
|
238
|
+
children: span.operation.replace("gorm.", "")
|
|
239
|
+
}),
|
|
240
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", {
|
|
241
|
+
className: "py-1 text-muted-foreground",
|
|
242
|
+
children: String(attr(span, "db.sql.table") ?? "—")
|
|
243
|
+
}),
|
|
244
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", {
|
|
245
|
+
className: "py-1 text-right tabular-nums",
|
|
246
|
+
children: String(attr(span, "db.rows_affected") ?? "")
|
|
247
|
+
}),
|
|
248
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", {
|
|
249
|
+
className: "py-1 text-right tabular-nums",
|
|
250
|
+
children: require_model.duration(span.durationMs)
|
|
251
|
+
})
|
|
252
|
+
]
|
|
253
|
+
}, span.spanId))
|
|
254
|
+
})]
|
|
255
|
+
})
|
|
256
|
+
]
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
exports.AgentCard = AgentCard;
|
|
260
|
+
exports.DbCard = DbCard;
|
|
261
|
+
exports.GroupDetail = GroupDetail;
|
|
262
|
+
exports.LlmCard = LlmCard;
|
|
263
|
+
|
|
264
|
+
//# sourceMappingURL=SpanCards.cjs.map
|