Skip to content

Commit c99a033

Browse files
Plataneclaude
andcommitted
React 19 compatibility for Grafana 13
Externalize react/jsx-runtime and react/jsx-dev-runtime so the plugin works with React 19 in Grafana 13. Closes #169 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent e9197d5 commit c99a033

File tree

8 files changed

+113
-274
lines changed

8 files changed

+113
-274
lines changed

.config/bundler/externals.ts

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*
2+
* ⚠️⚠️⚠️ THIS FILE WAS SCAFFOLDED BY `@grafana/create-plugin`. DO NOT EDIT THIS FILE DIRECTLY. ⚠️⚠️⚠️
3+
*
4+
*/
5+
6+
import type { Configuration, ExternalItemFunctionData } from 'webpack';
7+
8+
type ExternalsType = Configuration['externals'];
9+
10+
export const externals: ExternalsType = [
11+
// Required for dynamic publicPath resolution
12+
{ 'amd-module': 'module' },
13+
'lodash',
14+
'jquery',
15+
'moment',
16+
'slate',
17+
'emotion',
18+
'@emotion/react',
19+
'@emotion/css',
20+
'prismjs',
21+
'slate-plain-serializer',
22+
'@grafana/slate-react',
23+
'react',
24+
'react/jsx-runtime',
25+
'react/jsx-dev-runtime',
26+
'react-dom',
27+
'react-redux',
28+
'redux',
29+
'rxjs',
30+
'i18next',
31+
'react-router',
32+
'd3',
33+
'angular',
34+
/^@grafana\/ui/i,
35+
/^@grafana\/runtime/i,
36+
/^@grafana\/data/i,
37+
38+
// Mark legacy SDK imports as external if their name starts with the "grafana/" prefix
39+
({ request }: ExternalItemFunctionData, callback: (error?: Error, result?: string) => void) => {
40+
const prefix = 'grafana/';
41+
const hasPrefix = (request: string) => request.indexOf(prefix) === 0;
42+
const stripPrefix = (request: string) => request.slice(prefix.length);
43+
44+
if (request && hasPrefix(request)) {
45+
return callback(undefined, stripPrefix(request));
46+
}
47+
48+
callback();
49+
},
50+
];

.config/webpack/webpack.config.ts

Lines changed: 3 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ import { Configuration } from 'webpack';
1616
import { getPackageJson, getPluginJson, hasReadme, getEntries, isWSL } from './utils';
1717
import { SOURCE_DIR, DIST_DIR } from './constants';
1818

19+
import { externals } from '../bundler/externals.ts';
20+
1921
const pluginJson = getPluginJson();
2022

2123
const config = async (env): Promise<Configuration> => {
@@ -33,43 +35,7 @@ const config = async (env): Promise<Configuration> => {
3335

3436
entry: await getEntries(),
3537

36-
externals: [
37-
'lodash',
38-
'jquery',
39-
'moment',
40-
'slate',
41-
'emotion',
42-
'@emotion/react',
43-
'@emotion/css',
44-
'prismjs',
45-
'slate-plain-serializer',
46-
'@grafana/slate-react',
47-
'react',
48-
'react-dom',
49-
'react-redux',
50-
'redux',
51-
'rxjs',
52-
'react-router',
53-
'react-router-dom',
54-
'd3',
55-
'angular',
56-
'@grafana/ui',
57-
'@grafana/runtime',
58-
'@grafana/data',
59-
60-
// Mark legacy SDK imports as external if their name starts with the "grafana/" prefix
61-
({ request }, callback) => {
62-
const prefix = 'grafana/';
63-
const hasPrefix = (request) => request.indexOf(prefix) === 0;
64-
const stripPrefix = (request) => request.substr(prefix.length);
65-
66-
if (hasPrefix(request)) {
67-
return callback(undefined, stripPrefix(request));
68-
}
69-
70-
callback();
71-
},
72-
],
38+
externals,
7339

7440
mode: env.production ? 'production' : 'development',
7541

QA_CHECKLIST.md

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# QA Checklist — Quickwit Grafana Datasource Plugin
2+
3+
## Plugin-owned UI areas
4+
5+
### Config Editor (`/connections/datasources/edit/<uid>`)
6+
7+
- [ ] **Index settings section**
8+
- [ ] Index ID field accepts input and saves
9+
- [ ] Message field name field accepts input and saves
10+
- [ ] Log level field accepts input and saves
11+
- [ ] **Editor settings section**
12+
- [ ] Default logs limit field accepts input and saves
13+
- [ ] **Data links section**
14+
- [ ] Can add a data link
15+
- [ ] Can remove a data link
16+
- [ ] **Save & test** validates connection to Quickwit and reports success/failure
17+
18+
### Query Editor — Explore view (`/explore`)
19+
20+
- [ ] **Query type tabs**
21+
- [ ] Metrics tab loads metric aggregation options
22+
- [ ] Logs tab loads log query options
23+
- [ ] Raw Data tab loads raw query options
24+
- [ ] **Lucene Query input**
25+
- [ ] Can type a query
26+
- [ ] Autocomplete works (Ctrl+Space)
27+
- [ ] Shift+Enter runs the query
28+
- [ ] **Logs config row**
29+
- [ ] Tail count is configurable
30+
- [ ] Sort direction is configurable
31+
- [ ] **Results**
32+
- [ ] Logs volume histogram renders with data
33+
- [ ] Log rows render in the Logs panel
34+
- [ ] Table view toggle works
35+
- [ ] "Scan for older logs" button works
36+
37+
### Query Editor — Dashboard panels
38+
39+
- [ ] **Metrics query type**
40+
- [ ] Date histogram aggregation works
41+
- [ ] Terms aggregation works
42+
- [ ] Metric aggregations (avg, sum, count, etc.) work
43+
- [ ] **Logs query type** renders logs in panel
44+
- [ ] **Ad-hoc filters** can be added and filter results dynamically
45+
46+
## Not owned by the plugin (Grafana built-in)
47+
48+
These are rendered by Grafana itself and do not need plugin-level QA:
49+
50+
- Sidebar navigation
51+
- Time picker
52+
- Log row rendering / expansion
53+
- Chart rendering (histogram, time series)
54+
- Search bar, breadcrumbs, header
55+
- Auth section in config (Basic auth, TLS, OAuth)
56+
- HTTP section in config (URL, Allowed cookies, Timeout)

docker-compose.yaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ services:
1616
build:
1717
context: ./.config
1818
args:
19-
grafana_version: 12.1.0
19+
grafana_version: ${GRAFANA_VERSION:-12.1.0}
20+
grafana_image: ${GRAFANA_IMAGE:-grafana-oss}
2021
ports:
2122
- 3000:3000/tcp
2223
volumes:

src/components/QueryEditor/ElasticsearchQueryContext.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ export const ElasticsearchProvider = withStore(({
5050
app,
5151
datasource,
5252
range,
53-
}: PropsWithChildren<Props>): JSX.Element => {
53+
}: PropsWithChildren<Props>): React.JSX.Element => {
5454

5555
const storeDispatch = useDispatch();
5656
useEffect(()=>{

src/dependencies/DataSourcePicker.tsx

Lines changed: 0 additions & 159 deletions
This file was deleted.

0 commit comments

Comments
 (0)