QueryModal: History-Integration und initiale SQL

Query-Editor trackt jetzt alle Ausfuehrungen im HistoryManager
(Laufzeit, Zeilenanzahl). Akzeptiert optionale initiale SQL
fuer Template- und Favoriten-Integration.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Luca Oelfke 2026-02-12 11:24:20 +01:00
parent 3d0519db8f
commit df3bddeaeb

View file

@ -3,15 +3,20 @@ import { QueryConfig, TimeRange, EventType } 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, toMarkdownTable } from '../viz/table-renderer'; import { renderTable, toMarkdownTable } from '../viz/table-renderer';
import { HistoryManager } from '../management/history';
export class QueryModal extends Modal { export class QueryModal extends Modal {
private editorEl!: HTMLTextAreaElement; private editorEl!: HTMLTextAreaElement;
private resultEl!: HTMLElement; private resultEl!: HTMLElement;
private modeToggle!: HTMLButtonElement; private modeToggle!: HTMLButtonElement;
private mode: 'shorthand' | 'sql' = 'shorthand'; private mode: 'shorthand' | 'sql' = 'shorthand';
private historyManager?: HistoryManager;
private initialSql?: string;
constructor(app: App, private db: DatabaseManager) { constructor(app: App, private db: DatabaseManager, historyManager?: HistoryManager, initialSql?: string) {
super(app); super(app);
this.historyManager = historyManager;
this.initialSql = initialSql;
} }
onOpen(): void { onOpen(): void {
@ -76,6 +81,14 @@ export class QueryModal extends Modal {
// Results // Results
this.resultEl = contentEl.createDiv({ cls: 'logfire-qm-results' }); this.resultEl = contentEl.createDiv({ cls: 'logfire-qm-results' });
// Initial SQL setzen
if (this.initialSql) {
this.mode = 'sql';
this.modeToggle.textContent = 'Modus: SQL';
this.editorEl.value = this.initialSql;
this.editorEl.placeholder = 'SELECT * FROM events\nWHERE type = \'file:create\'\nORDER BY timestamp DESC\nLIMIT 50';
}
} }
onClose(): void { onClose(): void {
@ -91,8 +104,11 @@ export class QueryModal extends Modal {
this.resultEl.empty(); this.resultEl.empty();
const startTime = Date.now();
try { try {
let rows: Record<string, unknown>[]; let rows: Record<string, unknown>[];
let executedSql = input;
if (this.mode === 'sql') { if (this.mode === 'sql') {
// Raw SQL mode // Raw SQL mode
@ -109,9 +125,13 @@ export class QueryModal extends Modal {
// Shorthand mode // Shorthand mode
const config = parseShorthand(input); const config = parseShorthand(input);
const { sql, params } = buildQuery(config); const { sql, params } = buildQuery(config);
executedSql = sql;
rows = this.db.queryReadOnly(sql, params) as Record<string, unknown>[]; rows = this.db.queryReadOnly(sql, params) as Record<string, unknown>[];
} }
const elapsed = Date.now() - startTime;
this.historyManager?.addEntry(executedSql, elapsed, rows.length);
this.lastRows = rows; this.lastRows = rows;
this.lastKeys = rows.length > 0 ? Object.keys(rows[0]) : []; this.lastKeys = rows.length > 0 ? Object.keys(rows[0]) : [];