Processor: Chart-Support und Dashboard-Block-Prozessor
logfire-sql Bloecke unterstuetzen jetzt -- chart: Direktiven fuer Inline-Visualisierung. Neuer logfire-dashboard Block- Prozessor rendert Multi-Widget-Dashboards direkt in Notizen. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
eec66b738d
commit
aba060f3a5
1 changed files with 78 additions and 2 deletions
|
|
@ -3,6 +3,9 @@ import { QueryConfig, TimeRange, EventType, EventCategory } from '../types';
|
||||||
import { buildQuery } from '../core/query-builder';
|
import { buildQuery } from '../core/query-builder';
|
||||||
import { DatabaseManager } from '../core/database';
|
import { DatabaseManager } from '../core/database';
|
||||||
import { renderTable, renderTimeline, renderSummary, renderMetric, renderList, renderHeatmap, formatValue } from '../viz/table-renderer';
|
import { renderTable, renderTimeline, renderSummary, renderMetric, renderList, renderHeatmap, formatValue } from '../viz/table-renderer';
|
||||||
|
import { renderChart, parseChartConfig } from '../viz/chart-renderer';
|
||||||
|
import { parseDashboardBlock, DashboardView, DASHBOARD_VIEW_TYPE } from '../viz/dashboard';
|
||||||
|
import type LogfirePlugin from '../main';
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// Refresh timer management
|
// Refresh timer management
|
||||||
|
|
@ -84,13 +87,20 @@ export function registerLogfireSqlBlock(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const chartConfig = parseChartConfig(source);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const rows = db.queryReadOnly(sql) as Record<string, unknown>[];
|
const rows = db.queryReadOnly(sql) as Record<string, unknown>[];
|
||||||
if (!Array.isArray(rows) || rows.length === 0) {
|
if (!Array.isArray(rows) || rows.length === 0) {
|
||||||
el.createEl('p', { text: 'Keine Ergebnisse.', cls: 'logfire-empty' });
|
el.createEl('p', { text: 'Keine Ergebnisse.', cls: 'logfire-empty' });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
renderTable(el, rows);
|
|
||||||
|
if (chartConfig) {
|
||||||
|
renderChart(el, rows, chartConfig);
|
||||||
|
} else {
|
||||||
|
renderTable(el, rows);
|
||||||
|
}
|
||||||
|
|
||||||
if (refresh && refresh > 0) {
|
if (refresh && refresh > 0) {
|
||||||
setupRefreshTimer(el, () => {
|
setupRefreshTimer(el, () => {
|
||||||
|
|
@ -101,7 +111,11 @@ export function registerLogfireSqlBlock(
|
||||||
el.createEl('p', { text: 'Keine Ergebnisse.', cls: 'logfire-empty' });
|
el.createEl('p', { text: 'Keine Ergebnisse.', cls: 'logfire-empty' });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
renderTable(el, freshRows);
|
if (chartConfig) {
|
||||||
|
renderChart(el, freshRows, chartConfig);
|
||||||
|
} else {
|
||||||
|
renderTable(el, freshRows);
|
||||||
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
renderError(el, err);
|
renderError(el, err);
|
||||||
}
|
}
|
||||||
|
|
@ -113,6 +127,68 @@ export function registerLogfireSqlBlock(
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// `logfire-dashboard` block — Dashboard Code-Block
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
export function registerLogfireDashboardBlock(
|
||||||
|
plugin: LogfirePlugin,
|
||||||
|
db: DatabaseManager,
|
||||||
|
registerFn: (language: string, handler: (source: string, el: HTMLElement, ctx: MarkdownPostProcessorContext) => void) => void,
|
||||||
|
): void {
|
||||||
|
registerFn('logfire-dashboard', (source, el, ctx) => {
|
||||||
|
const dashboard = parseDashboardBlock(source);
|
||||||
|
if (!dashboard) {
|
||||||
|
renderError(el, new Error('Ungültige Dashboard-Definition.'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render dashboard inline
|
||||||
|
const wrapper = el.createDiv({ cls: 'logfire-dash-inline' });
|
||||||
|
|
||||||
|
if (dashboard.name) {
|
||||||
|
wrapper.createDiv({ cls: 'logfire-dash-inline-title', text: dashboard.name });
|
||||||
|
}
|
||||||
|
|
||||||
|
const grid = wrapper.createDiv({ cls: 'logfire-dash-grid' });
|
||||||
|
grid.style.gridTemplateColumns = `repeat(${dashboard.columns}, 1fr)`;
|
||||||
|
|
||||||
|
for (const widget of dashboard.widgets) {
|
||||||
|
const widgetEl = grid.createDiv({ cls: 'logfire-dash-widget' });
|
||||||
|
widgetEl.style.gridColumn = `${widget.position.col + 1} / span ${widget.position.width}`;
|
||||||
|
widgetEl.style.gridRow = `${widget.position.row + 1} / span ${widget.position.height}`;
|
||||||
|
|
||||||
|
if (widget.title) {
|
||||||
|
widgetEl.createDiv({ cls: 'logfire-dash-widget-title', text: widget.title });
|
||||||
|
}
|
||||||
|
|
||||||
|
const content = widgetEl.createDiv({ cls: 'logfire-dash-widget-content' });
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (widget.type === 'text' && widget.text) {
|
||||||
|
content.createDiv({ text: widget.text });
|
||||||
|
} else if (widget.sql) {
|
||||||
|
const rows = db.queryReadOnly(widget.sql) as Record<string, unknown>[];
|
||||||
|
if (rows.length === 0) {
|
||||||
|
content.createDiv({ cls: 'logfire-empty', text: 'Keine Ergebnisse.' });
|
||||||
|
} else if (widget.type === 'chart' && widget.chartConfig) {
|
||||||
|
renderChart(content, rows, widget.chartConfig);
|
||||||
|
} else if (widget.type === 'stat') {
|
||||||
|
renderMetric(content, rows);
|
||||||
|
} else {
|
||||||
|
renderTable(content, rows);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
content.createDiv({
|
||||||
|
cls: 'logfire-error',
|
||||||
|
text: `Fehler: ${err instanceof Error ? err.message : String(err)}`,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// YAML config parsing
|
// YAML config parsing
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue