Skip to content

Commit d04d12a

Browse files
committed
Fix autocomplete
1 parent faaf231 commit d04d12a

File tree

5 files changed

+198
-11
lines changed

5 files changed

+198
-11
lines changed

package-lock.json

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@
3737
"@swc/helpers": "^0.5.0",
3838
"@swc/jest": "^0.2.26",
3939
"@testing-library/jest-dom": "^6.1.4",
40-
"@testing-library/react": "^13.4.0",
41-
"@testing-library/user-event": "^14.4.3",
40+
"@testing-library/react": "^13.4.0",
41+
"@testing-library/user-event": "^14.4.3",
4242
"@types/jest": "^29.5.0",
4343
"@types/lodash": "^4.14.194",
4444
"@types/lucene": "^2.1.7",
@@ -72,6 +72,8 @@
7272
"node": ">=20"
7373
},
7474
"dependencies": {
75+
"@codemirror/commands": "^6.8.1",
76+
"@codemirror/view": "^6.38.1",
7577
"@emotion/css": "^11.11",
7678
"@grafana/data": "^11.3.0",
7779
"@grafana/runtime": "^11.3.0",
Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
import React, { useState } from 'react';
2+
import { LuceneQueryEditor } from './LuceneQueryEditor';
3+
4+
/**
5+
* Simple test component for LuceneQueryEditor keymap functionality
6+
* Add this to your Storybook or use in development
7+
*/
8+
export function LuceneEditorTest() {
9+
const [query, setQuery] = useState('status:error AND level:warn');
10+
const [lastSubmitted, setLastSubmitted] = useState('');
11+
const [events, setEvents] = useState<string[]>([]);
12+
13+
const addEvent = (message: string) => {
14+
const timestamp = new Date().toLocaleTimeString();
15+
setEvents(prev => [`${timestamp}: ${message}`, ...prev.slice(0, 9)]);
16+
};
17+
18+
const mockAutocompleter = async (word: string) => {
19+
addEvent(`🔍 Autocomplete requested for: "${word}"`);
20+
21+
const fields = ['status', 'level', 'message', 'timestamp', 'host', 'service', 'error', 'user_id'];
22+
const filtered = fields.filter(field =>
23+
field.toLowerCase().includes(word.toLowerCase())
24+
);
25+
26+
return {
27+
from: 0,
28+
options: filtered.map(field => ({
29+
label: field,
30+
type: 'variable',
31+
detail: `Field: ${field}`,
32+
}))
33+
};
34+
};
35+
36+
const handleSubmit = (submittedQuery: string) => {
37+
setLastSubmitted(submittedQuery);
38+
addEvent(`✅ Query submitted: "${submittedQuery}"`);
39+
};
40+
41+
const handleChange = (newQuery: string) => {
42+
setQuery(newQuery);
43+
};
44+
45+
return (
46+
<div style={{ padding: '20px', maxWidth: '1000px', fontFamily: 'Arial, sans-serif' }}>
47+
<h2>🎹 Lucene Editor Keymap Test</h2>
48+
49+
<div style={{ display: 'grid', gridTemplateColumns: '2fr 1fr', gap: '20px' }}>
50+
{/* Editor */}
51+
<div>
52+
<h3>Editor</h3>
53+
<div style={{
54+
border: '2px solid #ddd',
55+
borderRadius: '8px',
56+
height: '200px',
57+
backgroundColor: '#1e1e1e'
58+
}}>
59+
<LuceneQueryEditor
60+
value={query}
61+
onChange={handleChange}
62+
onSubmit={handleSubmit}
63+
autocompleter={mockAutocompleter}
64+
placeholder="Type your query and test keyboard shortcuts..."
65+
/>
66+
</div>
67+
68+
<div style={{
69+
marginTop: '15px',
70+
padding: '15px',
71+
background: '#f0f8ff',
72+
borderRadius: '8px',
73+
border: '1px solid #b3d9ff'
74+
}}>
75+
<h4 style={{ margin: '0 0 10px 0' }}>🎯 Instructions:</h4>
76+
<ul style={{ margin: 0, paddingLeft: '20px' }}>
77+
<li><strong>Shift + Enter</strong> → Submit query (should trigger onSubmit)</li>
78+
<li><strong>Ctrl + Enter</strong> → Show autocomplete popup</li>
79+
<li><strong>Type field names</strong> → Get suggestions (status, level, etc.)</li>
80+
</ul>
81+
</div>
82+
</div>
83+
84+
{/* Status Panel */}
85+
<div>
86+
<h3>📊 Status</h3>
87+
88+
<div style={{ marginBottom: '15px' }}>
89+
<strong>Last Submitted:</strong>
90+
<div style={{
91+
padding: '10px',
92+
background: lastSubmitted ? '#e8f5e8' : '#f5f5f5',
93+
border: '1px solid #ddd',
94+
borderRadius: '4px',
95+
marginTop: '5px',
96+
fontFamily: 'monospace',
97+
wordBreak: 'break-all'
98+
}}>
99+
{lastSubmitted || 'None yet'}
100+
</div>
101+
</div>
102+
103+
<div>
104+
<strong>Recent Events:</strong>
105+
<div style={{
106+
height: '200px',
107+
overflow: 'auto',
108+
border: '1px solid #ddd',
109+
borderRadius: '4px',
110+
padding: '10px',
111+
backgroundColor: '#fafafa',
112+
fontFamily: 'monospace',
113+
fontSize: '12px',
114+
marginTop: '5px'
115+
}}>
116+
{events.length === 0 ? (
117+
<div style={{ color: '#888' }}>Events will appear here...</div>
118+
) : (
119+
events.map((event, index) => (
120+
<div key={index} style={{
121+
padding: '2px 0',
122+
borderBottom: index < events.length - 1 ? '1px solid #eee' : 'none'
123+
}}>
124+
{event}
125+
</div>
126+
))
127+
)}
128+
</div>
129+
</div>
130+
131+
<button
132+
onClick={() => setEvents([])}
133+
style={{
134+
marginTop: '10px',
135+
padding: '8px 12px',
136+
backgroundColor: '#007bff',
137+
color: 'white',
138+
border: 'none',
139+
borderRadius: '4px',
140+
cursor: 'pointer',
141+
width: '100%'
142+
}}
143+
>
144+
Clear Events
145+
</button>
146+
</div>
147+
</div>
148+
149+
<div style={{
150+
marginTop: '20px',
151+
padding: '15px',
152+
backgroundColor: '#fff3cd',
153+
border: '1px solid #ffeaa7',
154+
borderRadius: '8px'
155+
}}>
156+
<h4 style={{ margin: '0 0 10px 0' }}>🔧 Debugging Tips:</h4>
157+
<ul style={{ margin: 0, paddingLeft: '20px' }}>
158+
<li>Open browser console to see additional debug messages</li>
159+
<li>Make sure to click in the editor to focus it before testing shortcuts</li>
160+
<li>If Shift+Enter doesn't work, check the console for errors</li>
161+
<li>Ctrl+Enter should show a dropdown with field suggestions</li>
162+
</ul>
163+
</div>
164+
</div>
165+
);
166+
}

src/components/LuceneQueryEditor.tsx

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@ import React, { useRef, useCallback } from "react";
22
import { css } from "@emotion/css";
33

44

5-
import CodeMirror, { ReactCodeMirrorRef, keymap } from '@uiw/react-codemirror';
6-
import {linter, Diagnostic, lintGutter} from "@codemirror/lint"
7-
import {autocompletion, CompletionContext} from "@codemirror/autocomplete"
5+
import CodeMirror, { ReactCodeMirrorRef } from '@uiw/react-codemirror';
6+
import { keymap } from '@codemirror/view';
7+
import { linter, Diagnostic, lintGutter } from "@codemirror/lint"
8+
import { autocompletion, CompletionContext, startCompletion } from "@codemirror/autocomplete"
89
import { LuceneQuery } from "@/utils/lucene";
910

1011

@@ -53,8 +54,26 @@ export function LuceneQueryEditor(props: LuceneQueryEditorProps){
5354
const autocomplete = autocompletion({
5455
override: [datasourceCompletions],
5556
activateOnTyping: false,
57+
closeOnBlur: true,
58+
maxRenderedOptions: 30,
5659
})
5760

61+
const myKeymap = keymap.of([
62+
{
63+
key: 'Shift-Enter',
64+
run: (view) => {
65+
props.onSubmit(view.state.doc.toString());
66+
return true;
67+
}
68+
},
69+
{
70+
key: 'Ctrl-Enter',
71+
run: (view) => {
72+
return startCompletion(view);
73+
}
74+
},
75+
]);
76+
5877
return (<CodeMirror
5978
ref={editorRef}
6079
className={css`height:100%`} // XXX : need to set height for both wrapper elements
@@ -65,12 +84,10 @@ export function LuceneQueryEditor(props: LuceneQueryEditorProps){
6584
onChange={props.onChange}
6685
indentWithTab={false}
6786
extensions={[
68-
queryLinter, lintGutter(),
87+
queryLinter,
88+
lintGutter(),
6989
autocomplete,
70-
keymap.of([{key:'Shift-Enter', run:(target)=>{
71-
props.onSubmit(target.state.doc.toString())
72-
return true;
73-
}}])
90+
myKeymap
7491
]}
7592
/>);
7693
}

src/datasource/utils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ export function useDatasourceFields(datasource: BaseQuickwitDataSource, range: T
5151
suggestions.options = candidateFields.map(f => ({
5252
type: 'variable',
5353
label: f.text,
54-
detail: `${f.value}`
54+
detail: f.value !== undefined ?`${f.value}` : ''
5555
}));
5656
}
5757
return suggestions;

0 commit comments

Comments
 (0)