Merge ticket 051: allow deleting a declared metric

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XFUNZwCvz3kcod3352ZR2o
This commit is contained in:
Hugh Kaznowski
2026-09-06 09:44:05 +01:00
co-authored by Claude Sonnet 5
6 changed files with 312 additions and 72 deletions
+29 -6
View File
@@ -3,6 +3,7 @@ import type { TimeRange, TimeRangePresetId } from './LogTimeline'
import {
ApiError,
declareMetric,
deleteMetric,
fetchMetricBucketValues,
fetchMetricDeclarations,
fetchParamDeclarations,
@@ -166,6 +167,19 @@ export function Metrics({ range, activePreset }: { range: TimeRange | null; acti
editMetric(metric)
}
// No confirm-before-delete dialog — matches the rest of this settings UI (e.g. CSS entry / profile
// deletion in NavMenu.tsx), which also deletes directly on click rather than prompting first.
async function handleDelete(metricName: string) {
try {
await deleteMetric(metricName)
if (selected === metricName) setSelected(null)
if (editingName === metricName) resetForm()
await loadMetrics()
} catch {
// best-effort; the declared-metrics list simply keeps showing it if the delete failed
}
}
async function handleSubmit(e: React.FormEvent) {
e.preventDefault()
setSubmitError(null)
@@ -312,18 +326,27 @@ export function Metrics({ range, activePreset }: { range: TimeRange | null; acti
<div className="mb-3 flex flex-wrap gap-1">
{metrics.length === 0 && <span className="text-xs text-text-faint">No metrics declared yet.</span>}
{metrics.map((m) => (
<button
<div
key={m.name}
onClick={() => selectMetric(m)}
className={`rounded border px-2 py-1 text-xs ${
className={`flex items-center gap-0.5 rounded border pl-2 pr-1 py-1 text-xs ${
selected === m.name
? 'border-accent bg-accent/10 text-accent-text'
: 'border-border-soft text-text-secondary hover:bg-surface-2'
}`}
title={m.message_match_regex}
>
{m.name} ({m.label_params.join(', ') || 'no params'})
</button>
<button type="button" onClick={() => selectMetric(m)} title={m.message_match_regex}>
{m.name} ({m.label_params.join(', ') || 'no params'})
</button>
<button
type="button"
onClick={() => handleDelete(m.name)}
className="rounded px-1 text-text-faint hover:bg-danger-bg/50 hover:text-danger-text"
aria-label={`Delete metric ${m.name}`}
title={`Delete metric "${m.name}"`}
>
×
</button>
</div>
))}
</div>