@grafana/plugin-ui 0.13.1 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -3
- package/dist/cjs/index.cjs +3196 -168
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/index.d.cts +102 -39
- package/dist/cjs/test-utils.cjs +7880 -61
- package/dist/cjs/test-utils.cjs.map +1 -1
- package/dist/cjs/test-utils.d.cts +23 -23
- package/dist/esm/_virtual/chance.js +6 -0
- package/dist/esm/_virtual/chance.js.map +1 -0
- package/dist/esm/_virtual/chance2.js +4 -0
- package/dist/esm/_virtual/chance2.js.map +1 -0
- package/dist/esm/_virtual/index.js +6 -0
- package/dist/esm/_virtual/index.js.map +1 -0
- package/dist/esm/_virtual/re.js +4 -0
- package/dist/esm/_virtual/re.js.map +1 -0
- package/dist/esm/async-query-data/DatasourceWithAsyncBackend.js +155 -0
- package/dist/esm/async-query-data/DatasourceWithAsyncBackend.js.map +1 -0
- package/dist/esm/async-query-data/RunQueryButtons.js +52 -0
- package/dist/esm/async-query-data/RunQueryButtons.js.map +1 -0
- package/dist/esm/async-query-data/requestLooper.js +74 -0
- package/dist/esm/async-query-data/requestLooper.js.map +1 -0
- package/dist/esm/components/QueryEditor/InlineSelect.js +1 -1
- package/dist/esm/components/QueryEditor/InlineSelect.js.map +1 -1
- package/dist/esm/components/QueryEditor/QueryEditor.js +3 -1
- package/dist/esm/components/QueryEditor/QueryEditor.js.map +1 -1
- package/dist/esm/components/QueryEditor/QueryHeader.js +2 -2
- package/dist/esm/components/QueryEditor/QueryHeader.js.map +1 -1
- package/dist/esm/components/QueryEditor/TableSelector.js +0 -1
- package/dist/esm/components/QueryEditor/TableSelector.js.map +1 -1
- package/dist/esm/components/QueryEditor/defaults.js.map +1 -1
- package/dist/esm/components/QueryEditor/query-editor-raw/QueryEditorRaw.js +10 -2
- package/dist/esm/components/QueryEditor/query-editor-raw/QueryEditorRaw.js.map +1 -1
- package/dist/esm/components/QueryEditor/query-editor-raw/QueryToolbox.js +6 -1
- package/dist/esm/components/QueryEditor/query-editor-raw/QueryToolbox.js.map +1 -1
- package/dist/esm/components/QueryEditor/query-editor-raw/RawEditor.js +11 -1
- package/dist/esm/components/QueryEditor/query-editor-raw/RawEditor.js.map +1 -1
- package/dist/esm/components/QueryEditor/types.js +0 -1
- package/dist/esm/components/QueryEditor/types.js.map +1 -1
- package/dist/esm/components/QueryEditor/utils/formatSQL.js +15 -4
- package/dist/esm/components/QueryEditor/utils/formatSQL.js.map +1 -1
- package/dist/esm/components/QueryEditor/visual-query-builder/Preview.js +2 -2
- package/dist/esm/components/QueryEditor/visual-query-builder/Preview.js.map +1 -1
- package/dist/esm/components/QueryEditor/visual-query-builder/SQLGroupByRow.js +0 -1
- package/dist/esm/components/QueryEditor/visual-query-builder/SQLGroupByRow.js.map +1 -1
- package/dist/esm/components/QueryEditor/visual-query-builder/SQLOrderByRow.js +0 -1
- package/dist/esm/components/QueryEditor/visual-query-builder/SQLOrderByRow.js.map +1 -1
- package/dist/esm/components/QueryEditor/visual-query-builder/SQLSelectRow.js +0 -1
- package/dist/esm/components/QueryEditor/visual-query-builder/SQLSelectRow.js.map +1 -1
- package/dist/esm/components/QueryEditor/visual-query-builder/SQLWhereRow.js +0 -1
- package/dist/esm/components/QueryEditor/visual-query-builder/SQLWhereRow.js.map +1 -1
- package/dist/esm/components/QueryEditor/visual-query-builder/VisualEditor.js +10 -2
- package/dist/esm/components/QueryEditor/visual-query-builder/VisualEditor.js.map +1 -1
- package/dist/esm/components/SQLEditor/components/SQLEditor.js.map +1 -1
- package/dist/esm/components/SQLEditor/hooks/useLatestCallback.js +1 -1
- package/dist/esm/components/SQLEditor/hooks/useLatestCallback.js.map +1 -1
- package/dist/esm/components/SQLEditor/standardSql/definition.js +0 -6
- package/dist/esm/components/SQLEditor/standardSql/definition.js.map +1 -1
- package/dist/esm/components/SQLEditor/standardSql/getStatementPosition.js +2 -1
- package/dist/esm/components/SQLEditor/standardSql/getStatementPosition.js.map +1 -1
- package/dist/esm/components/SQLEditor/standardSql/statementPositionResolversRegistry.js +2 -1
- package/dist/esm/components/SQLEditor/standardSql/statementPositionResolversRegistry.js.map +1 -1
- package/dist/esm/components/SQLEditor/types.js +1 -17
- package/dist/esm/components/SQLEditor/types.js.map +1 -1
- package/dist/esm/components/SQLEditor/utils/LinkedToken.js +1 -1
- package/dist/esm/components/SQLEditor/utils/LinkedToken.js.map +1 -1
- package/dist/esm/components/SQLEditor/utils/linkedTokenBuilder.js +2 -2
- package/dist/esm/components/SQLEditor/utils/tokenType.js +18 -0
- package/dist/esm/components/SQLEditor/utils/tokenType.js.map +1 -0
- package/dist/esm/components/SQLEditor/utils/tokenUtils.js +1 -1
- package/dist/esm/components/VisualQueryBuilder/components/OperationEditorBody.js +1 -1
- package/dist/esm/components/VisualQueryBuilder/components/OperationList.js +1 -1
- package/dist/esm/components/VisualQueryBuilder/components/OperationParamEditor.js +1 -1
- package/dist/esm/components/VisualQueryBuilder/components/OperationsEditorRow.js +1 -1
- package/dist/esm/components/VisualQueryBuilder/components/QueryHeaderSwitch.js +1 -1
- package/dist/esm/components/VisualQueryBuilder/components/QueryOptionGroup.js +1 -1
- package/dist/esm/index.d.ts +102 -39
- package/dist/esm/index.js +5 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/node_modules/chance/chance.js +7820 -0
- package/dist/esm/node_modules/chance/chance.js.map +1 -0
- package/dist/esm/node_modules/semver/classes/comparator.js +160 -0
- package/dist/esm/node_modules/semver/classes/comparator.js.map +1 -0
- package/dist/esm/node_modules/semver/classes/range.js +575 -0
- package/dist/esm/node_modules/semver/classes/range.js.map +1 -0
- package/dist/esm/node_modules/semver/classes/semver.js +349 -0
- package/dist/esm/node_modules/semver/classes/semver.js.map +1 -0
- package/dist/esm/node_modules/semver/functions/clean.js +20 -0
- package/dist/esm/node_modules/semver/functions/clean.js.map +1 -0
- package/dist/esm/node_modules/semver/functions/cmp.js +71 -0
- package/dist/esm/node_modules/semver/functions/cmp.js.map +1 -0
- package/dist/esm/node_modules/semver/functions/coerce.js +76 -0
- package/dist/esm/node_modules/semver/functions/coerce.js.map +1 -0
- package/dist/esm/node_modules/semver/functions/compare-build.js +21 -0
- package/dist/esm/node_modules/semver/functions/compare-build.js.map +1 -0
- package/dist/esm/node_modules/semver/functions/compare-loose.js +17 -0
- package/dist/esm/node_modules/semver/functions/compare-loose.js.map +1 -0
- package/dist/esm/node_modules/semver/functions/compare.js +19 -0
- package/dist/esm/node_modules/semver/functions/compare.js.map +1 -0
- package/dist/esm/node_modules/semver/functions/diff.js +72 -0
- package/dist/esm/node_modules/semver/functions/diff.js.map +1 -0
- package/dist/esm/node_modules/semver/functions/eq.js +17 -0
- package/dist/esm/node_modules/semver/functions/eq.js.map +1 -0
- package/dist/esm/node_modules/semver/functions/gt.js +17 -0
- package/dist/esm/node_modules/semver/functions/gt.js.map +1 -0
- package/dist/esm/node_modules/semver/functions/gte.js +17 -0
- package/dist/esm/node_modules/semver/functions/gte.js.map +1 -0
- package/dist/esm/node_modules/semver/functions/inc.js +33 -0
- package/dist/esm/node_modules/semver/functions/inc.js.map +1 -0
- package/dist/esm/node_modules/semver/functions/lt.js +17 -0
- package/dist/esm/node_modules/semver/functions/lt.js.map +1 -0
- package/dist/esm/node_modules/semver/functions/lte.js +17 -0
- package/dist/esm/node_modules/semver/functions/lte.js.map +1 -0
- package/dist/esm/node_modules/semver/functions/major.js +17 -0
- package/dist/esm/node_modules/semver/functions/major.js.map +1 -0
- package/dist/esm/node_modules/semver/functions/minor.js +17 -0
- package/dist/esm/node_modules/semver/functions/minor.js.map +1 -0
- package/dist/esm/node_modules/semver/functions/neq.js +17 -0
- package/dist/esm/node_modules/semver/functions/neq.js.map +1 -0
- package/dist/esm/node_modules/semver/functions/parse.js +30 -0
- package/dist/esm/node_modules/semver/functions/parse.js.map +1 -0
- package/dist/esm/node_modules/semver/functions/patch.js +17 -0
- package/dist/esm/node_modules/semver/functions/patch.js.map +1 -0
- package/dist/esm/node_modules/semver/functions/prerelease.js +20 -0
- package/dist/esm/node_modules/semver/functions/prerelease.js.map +1 -0
- package/dist/esm/node_modules/semver/functions/rcompare.js +17 -0
- package/dist/esm/node_modules/semver/functions/rcompare.js.map +1 -0
- package/dist/esm/node_modules/semver/functions/rsort.js +17 -0
- package/dist/esm/node_modules/semver/functions/rsort.js.map +1 -0
- package/dist/esm/node_modules/semver/functions/satisfies.js +24 -0
- package/dist/esm/node_modules/semver/functions/satisfies.js.map +1 -0
- package/dist/esm/node_modules/semver/functions/sort.js +17 -0
- package/dist/esm/node_modules/semver/functions/sort.js.map +1 -0
- package/dist/esm/node_modules/semver/functions/valid.js +20 -0
- package/dist/esm/node_modules/semver/functions/valid.js.map +1 -0
- package/dist/esm/node_modules/semver/index.js +143 -0
- package/dist/esm/node_modules/semver/index.js.map +1 -0
- package/dist/esm/node_modules/semver/internal/constants.js +47 -0
- package/dist/esm/node_modules/semver/internal/constants.js.map +1 -0
- package/dist/esm/node_modules/semver/internal/debug.js +21 -0
- package/dist/esm/node_modules/semver/internal/debug.js.map +1 -0
- package/dist/esm/node_modules/semver/internal/identifiers.js +39 -0
- package/dist/esm/node_modules/semver/internal/identifiers.js.map +1 -0
- package/dist/esm/node_modules/semver/internal/lrucache.js +52 -0
- package/dist/esm/node_modules/semver/internal/lrucache.js.map +1 -0
- package/dist/esm/node_modules/semver/internal/parse-options.js +27 -0
- package/dist/esm/node_modules/semver/internal/parse-options.js.map +1 -0
- package/dist/esm/node_modules/semver/internal/re.js +238 -0
- package/dist/esm/node_modules/semver/internal/re.js.map +1 -0
- package/dist/esm/node_modules/semver/ranges/gtr.js +18 -0
- package/dist/esm/node_modules/semver/ranges/gtr.js.map +1 -0
- package/dist/esm/node_modules/semver/ranges/intersects.js +21 -0
- package/dist/esm/node_modules/semver/ranges/intersects.js.map +1 -0
- package/dist/esm/node_modules/semver/ranges/ltr.js +18 -0
- package/dist/esm/node_modules/semver/ranges/ltr.js.map +1 -0
- package/dist/esm/node_modules/semver/ranges/max-satisfying.js +40 -0
- package/dist/esm/node_modules/semver/ranges/max-satisfying.js.map +1 -0
- package/dist/esm/node_modules/semver/ranges/min-satisfying.js +39 -0
- package/dist/esm/node_modules/semver/ranges/min-satisfying.js.map +1 -0
- package/dist/esm/node_modules/semver/ranges/min-version.js +77 -0
- package/dist/esm/node_modules/semver/ranges/min-version.js.map +1 -0
- package/dist/esm/node_modules/semver/ranges/outside.js +101 -0
- package/dist/esm/node_modules/semver/ranges/outside.js.map +1 -0
- package/dist/esm/node_modules/semver/ranges/simplify.js +62 -0
- package/dist/esm/node_modules/semver/ranges/simplify.js.map +1 -0
- package/dist/esm/node_modules/semver/ranges/subset.js +264 -0
- package/dist/esm/node_modules/semver/ranges/subset.js.map +1 -0
- package/dist/esm/node_modules/semver/ranges/to-comparators.js +22 -0
- package/dist/esm/node_modules/semver/ranges/to-comparators.js.map +1 -0
- package/dist/esm/node_modules/semver/ranges/valid.js +25 -0
- package/dist/esm/node_modules/semver/ranges/valid.js.map +1 -0
- package/dist/esm/test/mocks/DataQuery.js +5 -5
- package/dist/esm/test/mocks/DataQuery.js.map +1 -1
- package/dist/esm/test/mocks/Datasource.js +21 -21
- package/dist/esm/test/mocks/Datasource.js.map +1 -1
- package/dist/esm/test/mocks/Plugin.js +29 -29
- package/dist/esm/test/mocks/Plugin.js.map +1 -1
- package/dist/esm/test/mocks/QueryEditorProps.js +6 -6
- package/dist/esm/test/mocks/QueryEditorProps.js.map +1 -1
- package/dist/esm/test/mocks/utils.js +4 -4
- package/dist/esm/test/mocks/utils.js.map +1 -1
- package/dist/esm/test-utils.d.ts +23 -23
- package/package.json +80 -87
|
@@ -3,38 +3,38 @@ import { DataSourceInstanceSettings, DataQuery, DataSourcePluginMeta, PluginMeta
|
|
|
3
3
|
import { DataSourceWithBackend } from '@grafana/runtime';
|
|
4
4
|
|
|
5
5
|
declare class DatasourceMock extends DataSourceWithBackend {
|
|
6
|
-
query: jest.Mock<any, any>;
|
|
6
|
+
query: jest.Mock<any, any, any>;
|
|
7
7
|
filterQuery: any;
|
|
8
|
-
applyTemplateVariables: jest.Mock<any, any>;
|
|
9
|
-
getResource: jest.Mock<any, any>;
|
|
10
|
-
postResource: jest.Mock<any, any>;
|
|
11
|
-
callHealthCheck: jest.Mock<any, any>;
|
|
12
|
-
testDatasource: jest.Mock<any, any>;
|
|
8
|
+
applyTemplateVariables: jest.Mock<any, any, any>;
|
|
9
|
+
getResource: jest.Mock<any, any, any>;
|
|
10
|
+
postResource: jest.Mock<any, any, any>;
|
|
11
|
+
callHealthCheck: jest.Mock<any, any, any>;
|
|
12
|
+
testDatasource: jest.Mock<any, any, any>;
|
|
13
13
|
uid: string;
|
|
14
14
|
name: string;
|
|
15
15
|
id: number;
|
|
16
16
|
type: string;
|
|
17
17
|
interval: string;
|
|
18
|
-
importQueries: jest.Mock<any, any>;
|
|
19
|
-
init: jest.Mock<any, any>;
|
|
20
|
-
getQueryHints: jest.Mock<any, any>;
|
|
21
|
-
getQueryDisplayText: jest.Mock<any, any>;
|
|
22
|
-
metricFindQuery: jest.Mock<any, any>;
|
|
23
|
-
getTagKeys: jest.Mock<any, any>;
|
|
24
|
-
getTagValues: jest.Mock<any, any>;
|
|
18
|
+
importQueries: jest.Mock<any, any, any>;
|
|
19
|
+
init: jest.Mock<any, any, any>;
|
|
20
|
+
getQueryHints: jest.Mock<any, any, any>;
|
|
21
|
+
getQueryDisplayText: jest.Mock<any, any, any>;
|
|
22
|
+
metricFindQuery: jest.Mock<any, any, any>;
|
|
23
|
+
getTagKeys: jest.Mock<any, any, any>;
|
|
24
|
+
getTagValues: jest.Mock<any, any, any>;
|
|
25
25
|
components: {};
|
|
26
26
|
meta: _grafana_data.DataSourcePluginMeta<{}>;
|
|
27
|
-
targetContainsTemplate: jest.Mock<any, any>;
|
|
28
|
-
modifyQuery: jest.Mock<any, any>;
|
|
29
|
-
getHighlighterExpression: jest.Mock<any, any>;
|
|
30
|
-
languageProvider: jest.Mock<any, any>;
|
|
31
|
-
getVersion: jest.Mock<any, any>;
|
|
32
|
-
interpolateVariablesInQueries: jest.Mock<any, any>;
|
|
27
|
+
targetContainsTemplate: jest.Mock<any, any, any>;
|
|
28
|
+
modifyQuery: jest.Mock<any, any, any>;
|
|
29
|
+
getHighlighterExpression: jest.Mock<any, any, any>;
|
|
30
|
+
languageProvider: jest.Mock<any, any, any>;
|
|
31
|
+
getVersion: jest.Mock<any, any, any>;
|
|
32
|
+
interpolateVariablesInQueries: jest.Mock<any, any, any>;
|
|
33
33
|
annotations: {};
|
|
34
|
-
annotationQuery: jest.Mock<any, any>;
|
|
35
|
-
streamOptionsProvider: jest.Mock<any, any>;
|
|
36
|
-
getRef: jest.Mock<any, any>;
|
|
37
|
-
protected getRequestHeaders: jest.Mock<any, any>;
|
|
34
|
+
annotationQuery: jest.Mock<any, any, any>;
|
|
35
|
+
streamOptionsProvider: jest.Mock<any, any, any>;
|
|
36
|
+
getRef: jest.Mock<any, any, any>;
|
|
37
|
+
protected getRequestHeaders: jest.Mock<any, any, any>;
|
|
38
38
|
}
|
|
39
39
|
declare const mockDatasource: () => DatasourceMock;
|
|
40
40
|
declare const mockDatasourceInstanceSettings: () => DataSourceInstanceSettings;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chance.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chance2.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"re.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import { DataSourceWithBackend, config, getBackendSrv, toDataQueryResponse } from '@grafana/runtime';
|
|
2
|
+
import { of, merge } from 'rxjs';
|
|
3
|
+
import { map, catchError } from 'rxjs/operators';
|
|
4
|
+
import { s as semverExports } from '../_virtual/index.js';
|
|
5
|
+
import { getRequestLooper } from './requestLooper.js';
|
|
6
|
+
|
|
7
|
+
var __defProp = Object.defineProperty;
|
|
8
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
9
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
10
|
+
const RUNNING_STATUSES = ["started", "submitted", "running"];
|
|
11
|
+
const isRunning = (status = "") => RUNNING_STATUSES.includes(status);
|
|
12
|
+
const isCustomMeta = (meta) => {
|
|
13
|
+
return !!(typeof meta === "object" && (meta == null ? undefined : meta.hasOwnProperty("queryID")) && (meta == null ? undefined : meta.hasOwnProperty("status")));
|
|
14
|
+
};
|
|
15
|
+
class DatasourceWithAsyncBackend extends DataSourceWithBackend {
|
|
16
|
+
constructor(instanceSettings) {
|
|
17
|
+
var _a;
|
|
18
|
+
super(instanceSettings);
|
|
19
|
+
__publicField(this, "runningQueries", {});
|
|
20
|
+
__publicField(this, "requestCounter", 100);
|
|
21
|
+
__publicField(this, "requestIdPrefix");
|
|
22
|
+
// cancel sets shouldCancel to tell requestLooper to cancel the query
|
|
23
|
+
__publicField(this, "cancel", (target) => {
|
|
24
|
+
this.storeQuery(target, { shouldCancel: true });
|
|
25
|
+
});
|
|
26
|
+
this.requestIdPrefix = (_a = instanceSettings.uid) != null ? _a : instanceSettings.id;
|
|
27
|
+
}
|
|
28
|
+
query(request) {
|
|
29
|
+
const targets = this.filterQuery ? request.targets.filter(this.filterQuery) : request.targets;
|
|
30
|
+
if (!targets.length) {
|
|
31
|
+
return of({ data: [] });
|
|
32
|
+
}
|
|
33
|
+
const all = [];
|
|
34
|
+
for (let target of targets) {
|
|
35
|
+
if (target.hide) {
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
all.push(this.doSingle(target, request));
|
|
39
|
+
}
|
|
40
|
+
return merge(...all);
|
|
41
|
+
}
|
|
42
|
+
storeQuery(target, queryInfo) {
|
|
43
|
+
const key = JSON.stringify(target);
|
|
44
|
+
const existingQueryInfo = this.runningQueries[key] || {};
|
|
45
|
+
this.runningQueries[key] = { ...existingQueryInfo, ...queryInfo };
|
|
46
|
+
}
|
|
47
|
+
getQuery(target) {
|
|
48
|
+
const key = JSON.stringify(target);
|
|
49
|
+
return this.runningQueries[key] || {};
|
|
50
|
+
}
|
|
51
|
+
removeQuery(target) {
|
|
52
|
+
const key = JSON.stringify(target);
|
|
53
|
+
delete this.runningQueries[key];
|
|
54
|
+
}
|
|
55
|
+
doSingle(target, request) {
|
|
56
|
+
let queryID = undefined;
|
|
57
|
+
let status = undefined;
|
|
58
|
+
let allData = [];
|
|
59
|
+
return getRequestLooper(
|
|
60
|
+
{ ...request, targets: [target], requestId: `${this.requestIdPrefix}_${this.requestCounter++}` },
|
|
61
|
+
{
|
|
62
|
+
/**
|
|
63
|
+
* Additional query to execute if the current query is still in a running state
|
|
64
|
+
*/
|
|
65
|
+
getNextQuery: (rsp) => {
|
|
66
|
+
var _a, _b;
|
|
67
|
+
if ((_a = rsp.data) == null ? undefined : _a.length) {
|
|
68
|
+
const first = rsp.data[0];
|
|
69
|
+
const meta = (_b = first.meta) == null ? undefined : _b.custom;
|
|
70
|
+
if (isCustomMeta(meta) && isRunning(meta.status)) {
|
|
71
|
+
queryID = meta.queryID;
|
|
72
|
+
status = meta.status;
|
|
73
|
+
this.storeQuery(target, { queryID });
|
|
74
|
+
return { ...target, queryID };
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
this.removeQuery(target);
|
|
78
|
+
return undefined;
|
|
79
|
+
},
|
|
80
|
+
/**
|
|
81
|
+
* The original request
|
|
82
|
+
*/
|
|
83
|
+
query: (request2) => {
|
|
84
|
+
const { range, targets, requestId, intervalMs, maxDataPoints } = request2;
|
|
85
|
+
const [_query] = targets;
|
|
86
|
+
const query = {
|
|
87
|
+
..._query,
|
|
88
|
+
meta: { queryFlow: "async" },
|
|
89
|
+
intervalMs,
|
|
90
|
+
maxDataPoints,
|
|
91
|
+
// getRef optionally chained to support < v8.3.x of Grafana
|
|
92
|
+
datasource: this == null ? undefined : this.getRef(),
|
|
93
|
+
datasourceId: this.id,
|
|
94
|
+
...this.applyTemplateVariables(_query, request2.scopedVars)
|
|
95
|
+
};
|
|
96
|
+
const cachingDisabled = !config.featureToggles.awsAsyncQueryCaching;
|
|
97
|
+
if (cachingDisabled && isRunning(status)) {
|
|
98
|
+
const requestSkipQueryCacheUnsupported = semverExports.lt(config.buildInfo.version, "10.2.3");
|
|
99
|
+
if (requestSkipQueryCacheUnsupported) {
|
|
100
|
+
return getBackendSrv().fetch({
|
|
101
|
+
method: "POST",
|
|
102
|
+
url: "/api/ds/query",
|
|
103
|
+
headers: { "X-Cache-Skip": true },
|
|
104
|
+
requestId,
|
|
105
|
+
data: {
|
|
106
|
+
queries: [query],
|
|
107
|
+
range,
|
|
108
|
+
from: range.from.valueOf().toString(),
|
|
109
|
+
to: range.to.valueOf().toString()
|
|
110
|
+
}
|
|
111
|
+
}).pipe(
|
|
112
|
+
map((result) => ({ data: toDataQueryResponse(result).data })),
|
|
113
|
+
catchError((err) => of(toDataQueryResponse(err)))
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
return super.query({ ...request2, targets: [query], skipQueryCache: true });
|
|
117
|
+
}
|
|
118
|
+
return super.query({ ...request2, targets: [query] });
|
|
119
|
+
},
|
|
120
|
+
/**
|
|
121
|
+
* Process the results
|
|
122
|
+
*/
|
|
123
|
+
process: (data) => {
|
|
124
|
+
for (const frame of data) {
|
|
125
|
+
if (frame.fields.length > 0) {
|
|
126
|
+
allData.push(frame);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return allData;
|
|
130
|
+
},
|
|
131
|
+
shouldCancel: () => {
|
|
132
|
+
const { shouldCancel } = this.getQuery(target);
|
|
133
|
+
return !!shouldCancel;
|
|
134
|
+
},
|
|
135
|
+
/**
|
|
136
|
+
* Callback that gets executed when unsubscribed
|
|
137
|
+
*/
|
|
138
|
+
onCancel: () => {
|
|
139
|
+
if (queryID) {
|
|
140
|
+
this.removeQuery(target);
|
|
141
|
+
this.postResource("cancel", {
|
|
142
|
+
queryId: queryID
|
|
143
|
+
}).catch((err) => {
|
|
144
|
+
err.isHandled = true;
|
|
145
|
+
console.error(`error cancelling query ID: ${queryID}`, err);
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
export { DatasourceWithAsyncBackend };
|
|
155
|
+
//# sourceMappingURL=DatasourceWithAsyncBackend.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DatasourceWithAsyncBackend.js","sources":["../../../src/async-query-data/DatasourceWithAsyncBackend.ts"],"sourcesContent":["import type {\n DataFrame,\n DataQuery,\n DataQueryRequest,\n DataQueryResponse,\n DataSourceInstanceSettings,\n DataSourceJsonData,\n} from '@grafana/data';\nimport {\n DataSourceWithBackend,\n config,\n getBackendSrv,\n toDataQueryResponse,\n type BackendDataSourceResponse,\n} from '@grafana/runtime';\nimport { merge, of, type Observable } from 'rxjs';\nimport { catchError, map } from 'rxjs/operators';\nimport { lt } from 'semver';\nimport { getRequestLooper } from './requestLooper';\n\nexport interface CustomMeta {\n queryID: string;\n status: string;\n}\n\nexport interface RunningQueryInfo {\n queryID?: string;\n shouldCancel?: boolean;\n}\n\ninterface DataQueryMeta {\n meta?: { queryFlow?: 'async' | 'sync' };\n}\n\nconst RUNNING_STATUSES = ['started', 'submitted', 'running'];\nconst isRunning = (status = '') => RUNNING_STATUSES.includes(status);\nconst isCustomMeta = (meta: unknown): meta is CustomMeta => {\n return !!(typeof meta === 'object' && meta?.hasOwnProperty('queryID') && meta?.hasOwnProperty('status'));\n};\n\nexport class DatasourceWithAsyncBackend<\n TQuery extends DataQuery = DataQuery,\n TOptions extends DataSourceJsonData = DataSourceJsonData,\n> extends DataSourceWithBackend<TQuery, TOptions> {\n private runningQueries: { [hash: string]: RunningQueryInfo } = {};\n private requestCounter = 100;\n private requestIdPrefix: number | string;\n\n constructor(instanceSettings: DataSourceInstanceSettings<TOptions>) {\n super(instanceSettings);\n this.requestIdPrefix = instanceSettings.uid ?? instanceSettings.id;\n }\n\n query(request: DataQueryRequest<TQuery>): Observable<DataQueryResponse> {\n const targets = this.filterQuery ? request.targets.filter(this.filterQuery) : request.targets;\n if (!targets.length) {\n return of({ data: [] });\n }\n const all: Array<Observable<DataQueryResponse>> = [];\n for (let target of targets) {\n if (target.hide) {\n continue;\n }\n all.push(this.doSingle(target, request));\n }\n return merge(...all);\n }\n\n storeQuery(target: TQuery, queryInfo: RunningQueryInfo) {\n const key = JSON.stringify(target);\n const existingQueryInfo = this.runningQueries[key] || {};\n this.runningQueries[key] = { ...existingQueryInfo, ...queryInfo };\n }\n\n getQuery(target: TQuery) {\n const key = JSON.stringify(target);\n return this.runningQueries[key] || {};\n }\n\n removeQuery(target: TQuery) {\n const key = JSON.stringify(target);\n delete this.runningQueries[key];\n }\n\n doSingle(target: TQuery, request: DataQueryRequest<TQuery>): Observable<DataQueryResponse> {\n let queryID: string | undefined = undefined;\n let status: string | undefined = undefined;\n let allData: DataFrame[] = [];\n\n return getRequestLooper(\n { ...request, targets: [target], requestId: `${this.requestIdPrefix}_${this.requestCounter++}` },\n {\n /**\n * Additional query to execute if the current query is still in a running state\n */\n getNextQuery: (rsp: DataQueryResponse) => {\n if (rsp.data?.length) {\n const first: DataFrame = rsp.data[0];\n const meta = first.meta?.custom;\n\n if (isCustomMeta(meta) && isRunning(meta.status)) {\n queryID = meta.queryID;\n status = meta.status;\n this.storeQuery(target, { queryID });\n return { ...target, queryID };\n }\n }\n\n this.removeQuery(target);\n return undefined;\n },\n\n /**\n * The original request\n */\n query: (request: DataQueryRequest<TQuery>) => {\n const { range, targets, requestId, intervalMs, maxDataPoints } = request;\n const [_query] = targets;\n const query: TQuery & DataQueryMeta = {\n ..._query,\n meta: { queryFlow: 'async' },\n intervalMs,\n maxDataPoints,\n // getRef optionally chained to support < v8.3.x of Grafana\n datasource: this?.getRef(),\n datasourceId: this.id,\n ...this.applyTemplateVariables(_query, request.scopedVars),\n };\n\n // Manually bypass the query cache for running queries if the caching service is not enabled.\n // The caching service handles bypassing the query cache automatically when it is enabled.\n const cachingDisabled = !config.featureToggles.awsAsyncQueryCaching;\n if (cachingDisabled && isRunning(status)) {\n const requestSkipQueryCacheUnsupported = lt(config.buildInfo.version, '10.2.3');\n if (requestSkipQueryCacheUnsupported) {\n return getBackendSrv()\n .fetch<BackendDataSourceResponse>({\n method: 'POST',\n url: '/api/ds/query',\n headers: { 'X-Cache-Skip': true },\n requestId,\n data: {\n queries: [query],\n range: range,\n from: range.from.valueOf().toString(),\n to: range.to.valueOf().toString(),\n },\n })\n .pipe(\n map((result) => ({ data: toDataQueryResponse(result).data })),\n catchError((err) => of(toDataQueryResponse(err)))\n );\n }\n\n return super.query({ ...request, targets: [query], skipQueryCache: true });\n }\n\n return super.query({ ...request, targets: [query] });\n },\n\n /**\n * Process the results\n */\n process: (data: DataFrame[]) => {\n for (const frame of data) {\n if (frame.fields.length > 0) {\n allData.push(frame);\n }\n }\n\n return allData;\n },\n\n shouldCancel: () => {\n const { shouldCancel } = this.getQuery(target);\n return !!shouldCancel;\n },\n\n /**\n * Callback that gets executed when unsubscribed\n */\n onCancel: () => {\n if (queryID) {\n this.removeQuery(target);\n this.postResource('cancel', {\n queryId: queryID,\n }).catch((err) => {\n err.isHandled = true; // avoid the popup\n console.error(`error cancelling query ID: ${queryID}`, err);\n });\n }\n },\n }\n );\n }\n\n // cancel sets shouldCancel to tell requestLooper to cancel the query\n cancel = (target: TQuery) => {\n this.storeQuery(target, { shouldCancel: true });\n };\n}\n"],"names":["request","lt"],"mappings":"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"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import React, { useState } from 'react';
|
|
2
|
+
import { Button } from '@grafana/ui';
|
|
3
|
+
import { LoadingState } from '@grafana/data';
|
|
4
|
+
|
|
5
|
+
const RunQueryButtons = (props) => {
|
|
6
|
+
const { state } = props;
|
|
7
|
+
const [running, setRunning] = useState(false);
|
|
8
|
+
const [stopping, setStopping] = useState(false);
|
|
9
|
+
const [prevState, setPrevState] = useState(state);
|
|
10
|
+
const [lastQuery, setLastQuery] = useState(props.query);
|
|
11
|
+
if (state !== prevState) {
|
|
12
|
+
setPrevState(state);
|
|
13
|
+
if (state && state !== LoadingState.Loading) {
|
|
14
|
+
setRunning(false);
|
|
15
|
+
setStopping(false);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
const onRunQuery = () => {
|
|
19
|
+
setRunning(true);
|
|
20
|
+
setLastQuery(props.query);
|
|
21
|
+
props.onRunQuery();
|
|
22
|
+
};
|
|
23
|
+
const onCancelQuery = props.onCancelQuery ? () => {
|
|
24
|
+
var _a;
|
|
25
|
+
(_a = props.onCancelQuery) == null ? undefined : _a.call(props, lastQuery);
|
|
26
|
+
setStopping(true);
|
|
27
|
+
} : undefined;
|
|
28
|
+
return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(
|
|
29
|
+
Button,
|
|
30
|
+
{
|
|
31
|
+
variant: props.enableRun ? "primary" : "secondary",
|
|
32
|
+
size: "sm",
|
|
33
|
+
onClick: onRunQuery,
|
|
34
|
+
icon: running && !stopping ? "fa fa-spinner" : undefined,
|
|
35
|
+
disabled: state === LoadingState.Loading || !props.enableRun
|
|
36
|
+
},
|
|
37
|
+
"Run query"
|
|
38
|
+
), /* @__PURE__ */ React.createElement(
|
|
39
|
+
Button,
|
|
40
|
+
{
|
|
41
|
+
variant: running && !stopping ? "primary" : "secondary",
|
|
42
|
+
size: "sm",
|
|
43
|
+
disabled: !running || stopping,
|
|
44
|
+
icon: stopping ? "fa fa-spinner" : undefined,
|
|
45
|
+
onClick: onCancelQuery
|
|
46
|
+
},
|
|
47
|
+
"Stop query"
|
|
48
|
+
));
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
export { RunQueryButtons };
|
|
52
|
+
//# sourceMappingURL=RunQueryButtons.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RunQueryButtons.js","sources":["../../../src/async-query-data/RunQueryButtons.tsx"],"sourcesContent":["import React, { useState } from 'react';\nimport { Button } from '@grafana/ui';\nimport { type DataQuery, LoadingState } from '@grafana/data';\n\nexport interface RunQueryButtonsProps<TQuery extends DataQuery> {\n enableRun?: boolean;\n onRunQuery: () => void;\n onCancelQuery: (query: TQuery) => void;\n query: TQuery;\n state?: LoadingState;\n}\n\nexport const RunQueryButtons = <TQuery extends DataQuery>(props: RunQueryButtonsProps<TQuery>) => {\n const { state } = props;\n const [running, setRunning] = useState(false);\n const [stopping, setStopping] = useState(false);\n const [prevState, setPrevState] = useState(state);\n const [lastQuery, setLastQuery] = useState(props.query);\n\n if (state !== prevState) {\n setPrevState(state);\n if (state && state !== LoadingState.Loading) {\n setRunning(false);\n setStopping(false);\n }\n }\n\n const onRunQuery = () => {\n setRunning(true);\n setLastQuery(props.query);\n props.onRunQuery();\n };\n\n const onCancelQuery = props.onCancelQuery\n ? () => {\n props.onCancelQuery?.(lastQuery);\n setStopping(true);\n }\n : undefined;\n\n return (\n <>\n <Button\n variant={props.enableRun ? 'primary' : 'secondary'}\n size=\"sm\"\n onClick={onRunQuery}\n icon={running && !stopping ? 'fa fa-spinner' : undefined}\n disabled={state === LoadingState.Loading || !props.enableRun}\n >\n Run query\n </Button>\n <Button\n variant={running && !stopping ? 'primary' : 'secondary'}\n size=\"sm\"\n disabled={!running || stopping}\n icon={stopping ? 'fa fa-spinner' : undefined}\n onClick={onCancelQuery}\n >\n Stop query\n </Button>\n </>\n );\n};\n"],"names":[],"mappings":";;;;AAYa,MAAA,eAAA,GAAkB,CAA2B,KAAwC,KAAA;AAChG,EAAM,MAAA,EAAE,OAAU,GAAA,KAAA;AAClB,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAI,SAAS,KAAK,CAAA;AAC5C,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAI,SAAS,KAAK,CAAA;AAC9C,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAI,SAAS,KAAK,CAAA;AAChD,EAAA,MAAM,CAAC,SAAW,EAAA,YAAY,CAAI,GAAA,QAAA,CAAS,MAAM,KAAK,CAAA;AAEtD,EAAA,IAAI,UAAU,SAAW,EAAA;AACvB,IAAA,YAAA,CAAa,KAAK,CAAA;AAClB,IAAI,IAAA,KAAA,IAAS,KAAU,KAAA,YAAA,CAAa,OAAS,EAAA;AAC3C,MAAA,UAAA,CAAW,KAAK,CAAA;AAChB,MAAA,WAAA,CAAY,KAAK,CAAA;AAAA;AACnB;AAGF,EAAA,MAAM,aAAa,MAAM;AACvB,IAAA,UAAA,CAAW,IAAI,CAAA;AACf,IAAA,YAAA,CAAa,MAAM,KAAK,CAAA;AACxB,IAAA,KAAA,CAAM,UAAW,EAAA;AAAA,GACnB;AAEA,EAAM,MAAA,aAAA,GAAgB,KAAM,CAAA,aAAA,GACxB,MAAM;AAlCZ,IAAA,IAAA,EAAA;AAmCQ,IAAA,CAAA,EAAA,GAAA,KAAA,CAAM,kBAAN,IAAsB,GAAA,SAAA,GAAA,EAAA,CAAA,IAAA,CAAA,KAAA,EAAA,SAAA,CAAA;AACtB,IAAA,WAAA,CAAY,IAAI,CAAA;AAAA,GAElB,GAAA,SAAA;AAEJ,EAAA,uBAEI,KAAA,CAAA,aAAA,CAAA,KAAA,CAAA,QAAA,EAAA,IAAA,kBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACC,OAAA,EAAS,KAAM,CAAA,SAAA,GAAY,SAAY,GAAA,WAAA;AAAA,MACvC,IAAK,EAAA,IAAA;AAAA,MACL,OAAS,EAAA,UAAA;AAAA,MACT,IAAM,EAAA,OAAA,IAAW,CAAC,QAAA,GAAW,eAAkB,GAAA,SAAA;AAAA,MAC/C,QAAU,EAAA,KAAA,KAAU,YAAa,CAAA,OAAA,IAAW,CAAC,KAAM,CAAA;AAAA,KAAA;AAAA,IACpD;AAAA,GAGD,kBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACC,OAAS,EAAA,OAAA,IAAW,CAAC,QAAA,GAAW,SAAY,GAAA,WAAA;AAAA,MAC5C,IAAK,EAAA,IAAA;AAAA,MACL,QAAA,EAAU,CAAC,OAAW,IAAA,QAAA;AAAA,MACtB,IAAA,EAAM,WAAW,eAAkB,GAAA,SAAA;AAAA,MACnC,OAAS,EAAA;AAAA,KAAA;AAAA,IACV;AAAA,GAGH,CAAA;AAEJ;;;;"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { LoadingState } from '@grafana/data';
|
|
2
|
+
import { Observable } from 'rxjs';
|
|
3
|
+
|
|
4
|
+
const DELAY_INTERVAL_MS = 10;
|
|
5
|
+
const MAX_NEXT_REQUEST_DELAY = 1e4 / DELAY_INTERVAL_MS;
|
|
6
|
+
function getRequestLooper(req, options) {
|
|
7
|
+
return new Observable((subscriber) => {
|
|
8
|
+
let nextQuery = undefined;
|
|
9
|
+
let subscription = undefined;
|
|
10
|
+
let loadingState = LoadingState.Loading;
|
|
11
|
+
let nextRequestDelay = 1;
|
|
12
|
+
let count = 1;
|
|
13
|
+
let shouldCancel = false;
|
|
14
|
+
const observer = {
|
|
15
|
+
next: (rsp) => {
|
|
16
|
+
loadingState = rsp.state;
|
|
17
|
+
let checkstate = false;
|
|
18
|
+
if (loadingState !== LoadingState.Error) {
|
|
19
|
+
nextQuery = options.getNextQuery(rsp);
|
|
20
|
+
const _shouldCancel = options.shouldCancel();
|
|
21
|
+
if (nextQuery && _shouldCancel) {
|
|
22
|
+
shouldCancel = _shouldCancel;
|
|
23
|
+
nextQuery = undefined;
|
|
24
|
+
}
|
|
25
|
+
checkstate = true;
|
|
26
|
+
}
|
|
27
|
+
const data = options.process(rsp.data);
|
|
28
|
+
if (checkstate) {
|
|
29
|
+
if (nextQuery) {
|
|
30
|
+
if (data.length && data[0].length) {
|
|
31
|
+
loadingState = LoadingState.Streaming;
|
|
32
|
+
} else {
|
|
33
|
+
loadingState = LoadingState.Loading;
|
|
34
|
+
}
|
|
35
|
+
nextRequestDelay = nextRequestDelay * 2 > MAX_NEXT_REQUEST_DELAY ? MAX_NEXT_REQUEST_DELAY : nextRequestDelay * 2;
|
|
36
|
+
} else {
|
|
37
|
+
loadingState = LoadingState.Done;
|
|
38
|
+
nextRequestDelay = 0;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
subscriber.next({ ...rsp, data, state: loadingState, key: req.requestId });
|
|
42
|
+
},
|
|
43
|
+
error: (err) => {
|
|
44
|
+
subscriber.error(err);
|
|
45
|
+
},
|
|
46
|
+
complete: () => {
|
|
47
|
+
if (subscription) {
|
|
48
|
+
subscription.unsubscribe();
|
|
49
|
+
subscription = undefined;
|
|
50
|
+
}
|
|
51
|
+
if (nextQuery) {
|
|
52
|
+
const next = nextQuery;
|
|
53
|
+
setTimeout(() => {
|
|
54
|
+
subscription = options.query({ ...req, requestId: `${req.requestId}.${++count}`, targets: [next] }).subscribe(observer);
|
|
55
|
+
nextQuery = undefined;
|
|
56
|
+
}, nextRequestDelay * DELAY_INTERVAL_MS);
|
|
57
|
+
} else {
|
|
58
|
+
subscriber.complete();
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
subscription = options.query(req).subscribe(observer);
|
|
63
|
+
return function unsubscribe() {
|
|
64
|
+
observer.complete();
|
|
65
|
+
if (nextQuery || shouldCancel) {
|
|
66
|
+
options.onCancel();
|
|
67
|
+
}
|
|
68
|
+
nextQuery = undefined;
|
|
69
|
+
};
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export { getRequestLooper };
|
|
74
|
+
//# sourceMappingURL=requestLooper.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"requestLooper.js","sources":["../../../src/async-query-data/requestLooper.ts"],"sourcesContent":["import {\n LoadingState,\n type DataFrame,\n type DataQuery,\n type DataQueryRequest,\n type DataQueryResponse,\n} from '@grafana/data';\nimport { Observable, type Subscription, type Observer } from 'rxjs';\n\nexport interface RequestLoopOptions<TQuery extends DataQuery = DataQuery> {\n /**\n * If the response needs an additional request to execute, return it here\n */\n getNextQuery: (rsp: DataQueryResponse) => TQuery | undefined;\n\n /**\n * The datasource execute method\n */\n query: (req: DataQueryRequest<TQuery>) => Observable<DataQueryResponse>;\n\n /**\n * Process the results\n */\n process: (data: DataFrame[]) => DataFrame[];\n\n /**\n * Check if the query should be cancelled\n */\n shouldCancel: () => boolean;\n\n /**\n * Callback that gets executed when unsubscribed\n */\n onCancel: () => void;\n}\n\nconst DELAY_INTERVAL_MS = 10;\nconst MAX_NEXT_REQUEST_DELAY = 10000 / DELAY_INTERVAL_MS; // 10 seconds maximum delay between requests\n\n/**\n * Continue executing requests as long as `getNextQuery` returns a query\n */\nexport function getRequestLooper<T extends DataQuery = DataQuery>(\n req: DataQueryRequest<T>,\n options: RequestLoopOptions<T>\n): Observable<DataQueryResponse> {\n return new Observable<DataQueryResponse>((subscriber) => {\n let nextQuery: T | undefined = undefined;\n let subscription: Subscription | undefined = undefined;\n let loadingState: LoadingState | undefined = LoadingState.Loading;\n let nextRequestDelay = 1; // number of DELAY_INTERVAL_MS to wait before the next request\n let count = 1;\n let shouldCancel = false;\n\n // Single observer gets reused for each request\n const observer: Observer<DataQueryResponse> = {\n next: (rsp: DataQueryResponse) => {\n loadingState = rsp.state;\n let checkstate = false;\n if (loadingState !== LoadingState.Error) {\n nextQuery = options.getNextQuery(rsp);\n const _shouldCancel = options.shouldCancel();\n\n if (nextQuery && _shouldCancel) {\n // `shouldCancel` is set here only if there is a `nextQuery`, otherwise\n // we would try to cancel a finished query in the cleanup function\n shouldCancel = _shouldCancel;\n nextQuery = undefined;\n }\n\n checkstate = true;\n }\n const data = options.process(rsp.data);\n\n // Set the loading status to show a spinner if loading or to show data if streaming.\n if (checkstate) {\n if (nextQuery) {\n if (data.length && data[0].length) {\n loadingState = LoadingState.Streaming;\n } else {\n loadingState = LoadingState.Loading;\n }\n // Calculate the number of DELAY_INTERVAL_MS to wait before the next request.\n // Caps it so the delay is not more than 10s\n nextRequestDelay =\n nextRequestDelay * 2 > MAX_NEXT_REQUEST_DELAY ? MAX_NEXT_REQUEST_DELAY : nextRequestDelay * 2;\n } else {\n loadingState = LoadingState.Done;\n nextRequestDelay = 0;\n }\n }\n subscriber.next({ ...rsp, data, state: loadingState, key: req.requestId });\n },\n error: (err) => {\n subscriber.error(err);\n },\n complete: () => {\n // We unsubscribe from the internal subscription after completing a request\n if (subscription) {\n subscription.unsubscribe();\n subscription = undefined;\n }\n\n // Queues up a new request if the current query is still in a running state.\n // The timeout is set in the `next` callback.\n if (nextQuery) {\n const next = nextQuery;\n setTimeout(() => {\n subscription = options\n .query({ ...req, requestId: `${req.requestId}.${++count}`, targets: [next] })\n .subscribe(observer);\n nextQuery = undefined;\n }, nextRequestDelay * DELAY_INTERVAL_MS);\n } else {\n subscriber.complete();\n }\n },\n };\n\n // This runs the initial query, subsequent queries are run in the `complete` callback of the observer.\n subscription = options.query(req).subscribe(observer);\n\n // Cleanup function\n return function unsubscribe() {\n observer.complete();\n if (nextQuery || shouldCancel) {\n options.onCancel();\n }\n nextQuery = undefined;\n };\n });\n}\n"],"names":[],"mappings":";;;AAoCA,MAAM,iBAAoB,GAAA,EAAA;AAC1B,MAAM,yBAAyB,GAAQ,GAAA,iBAAA;AAKvB,SAAA,gBAAA,CACd,KACA,OAC+B,EAAA;AAC/B,EAAO,OAAA,IAAI,UAA8B,CAAA,CAAC,UAAe,KAAA;AACvD,IAAA,IAAI,SAA2B,GAAA,SAAA;AAC/B,IAAA,IAAI,YAAyC,GAAA,SAAA;AAC7C,IAAA,IAAI,eAAyC,YAAa,CAAA,OAAA;AAC1D,IAAA,IAAI,gBAAmB,GAAA,CAAA;AACvB,IAAA,IAAI,KAAQ,GAAA,CAAA;AACZ,IAAA,IAAI,YAAe,GAAA,KAAA;AAGnB,IAAA,MAAM,QAAwC,GAAA;AAAA,MAC5C,IAAA,EAAM,CAAC,GAA2B,KAAA;AAChC,QAAA,YAAA,GAAe,GAAI,CAAA,KAAA;AACnB,QAAA,IAAI,UAAa,GAAA,KAAA;AACjB,QAAI,IAAA,YAAA,KAAiB,aAAa,KAAO,EAAA;AACvC,UAAY,SAAA,GAAA,OAAA,CAAQ,aAAa,GAAG,CAAA;AACpC,UAAM,MAAA,aAAA,GAAgB,QAAQ,YAAa,EAAA;AAE3C,UAAA,IAAI,aAAa,aAAe,EAAA;AAG9B,YAAe,YAAA,GAAA,aAAA;AACf,YAAY,SAAA,GAAA,SAAA;AAAA;AAGd,UAAa,UAAA,GAAA,IAAA;AAAA;AAEf,QAAA,MAAM,IAAO,GAAA,OAAA,CAAQ,OAAQ,CAAA,GAAA,CAAI,IAAI,CAAA;AAGrC,QAAA,IAAI,UAAY,EAAA;AACd,UAAA,IAAI,SAAW,EAAA;AACb,YAAA,IAAI,IAAK,CAAA,MAAA,IAAU,IAAK,CAAA,CAAC,EAAE,MAAQ,EAAA;AACjC,cAAA,YAAA,GAAe,YAAa,CAAA,SAAA;AAAA,aACvB,MAAA;AACL,cAAA,YAAA,GAAe,YAAa,CAAA,OAAA;AAAA;AAI9B,YAAA,gBAAA,GACE,gBAAmB,GAAA,CAAA,GAAI,sBAAyB,GAAA,sBAAA,GAAyB,gBAAmB,GAAA,CAAA;AAAA,WACzF,MAAA;AACL,YAAA,YAAA,GAAe,YAAa,CAAA,IAAA;AAC5B,YAAmB,gBAAA,GAAA,CAAA;AAAA;AACrB;AAEF,QAAW,UAAA,CAAA,IAAA,CAAK,EAAE,GAAG,GAAK,EAAA,IAAA,EAAM,OAAO,YAAc,EAAA,GAAA,EAAK,GAAI,CAAA,SAAA,EAAW,CAAA;AAAA,OAC3E;AAAA,MACA,KAAA,EAAO,CAAC,GAAQ,KAAA;AACd,QAAA,UAAA,CAAW,MAAM,GAAG,CAAA;AAAA,OACtB;AAAA,MACA,UAAU,MAAM;AAEd,QAAA,IAAI,YAAc,EAAA;AAChB,UAAA,YAAA,CAAa,WAAY,EAAA;AACzB,UAAe,YAAA,GAAA,SAAA;AAAA;AAKjB,QAAA,IAAI,SAAW,EAAA;AACb,UAAA,MAAM,IAAO,GAAA,SAAA;AACb,UAAA,UAAA,CAAW,MAAM;AACf,YAAe,YAAA,GAAA,OAAA,CACZ,MAAM,EAAE,GAAG,KAAK,SAAW,EAAA,CAAA,EAAG,IAAI,SAAS,CAAA,CAAA,EAAI,EAAE,KAAK,CAAA,CAAA,EAAI,SAAS,CAAC,IAAI,GAAG,CAAA,CAC3E,UAAU,QAAQ,CAAA;AACrB,YAAY,SAAA,GAAA,SAAA;AAAA,WACd,EAAG,mBAAmB,iBAAiB,CAAA;AAAA,SAClC,MAAA;AACL,UAAA,UAAA,CAAW,QAAS,EAAA;AAAA;AACtB;AACF,KACF;AAGA,IAAA,YAAA,GAAe,OAAQ,CAAA,KAAA,CAAM,GAAG,CAAA,CAAE,UAAU,QAAQ,CAAA;AAGpD,IAAA,OAAO,SAAS,WAAc,GAAA;AAC5B,MAAA,QAAA,CAAS,QAAS,EAAA;AAClB,MAAA,IAAI,aAAa,YAAc,EAAA;AAC7B,QAAA,OAAA,CAAQ,QAAS,EAAA;AAAA;AAEnB,MAAY,SAAA,GAAA,SAAA;AAAA,KACd;AAAA,GACD,CAAA;AACH;;;;"}
|
|
@@ -11,7 +11,7 @@ function InlineSelect({ label: labelProp, ...props }) {
|
|
|
11
11
|
ValueContainer,
|
|
12
12
|
SingleValue: ValueContainer
|
|
13
13
|
};
|
|
14
|
-
return /* @__PURE__ */ React.createElement("div", { className: styles.root }, labelProp && /* @__PURE__ */ React.createElement("label", { className: styles.label, htmlFor: id }, labelProp, ":", "\xA0"), /* @__PURE__ */ React.createElement(Select, {
|
|
14
|
+
return /* @__PURE__ */ React.createElement("div", { className: styles.root }, labelProp && /* @__PURE__ */ React.createElement("label", { className: styles.label, htmlFor: id }, labelProp, ":", "\xA0"), /* @__PURE__ */ React.createElement(Select, { inputId: id, ...props, components }));
|
|
15
15
|
}
|
|
16
16
|
const SelectContainer = (props) => {
|
|
17
17
|
const { children } = props;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InlineSelect.js","sources":["../../../../src/components/QueryEditor/InlineSelect.tsx"],"sourcesContent":["import React, { useState } from 'react';\nimport { css, cx } from '@emotion/css';\nimport { type GroupBase } from 'react-select';\n\nimport { type GrafanaTheme2 } from '@grafana/data';\nimport {\n Select,\n type SelectCommonProps,\n type SelectContainerProps,\n SelectContainer as BaseSelectContainer,\n useStyles2,\n} from '@grafana/ui';\n\ninterface InlineSelectProps<T> extends SelectCommonProps<T> {\n label?: string;\n}\n\nexport function InlineSelect<T>({ label: labelProp, ...props }: InlineSelectProps<T>) {\n const [id] = useState(() => Math.random().toString(16).slice(2));\n const styles = useStyles2(getSelectStyles);\n const components = {\n SelectContainer,\n ValueContainer,\n SingleValue: ValueContainer,\n };\n\n return (\n <div className={styles.root}>\n {labelProp && (\n <label className={styles.label} htmlFor={id}>\n {labelProp}\n {':'} \n </label>\n )}\n <Select
|
|
1
|
+
{"version":3,"file":"InlineSelect.js","sources":["../../../../src/components/QueryEditor/InlineSelect.tsx"],"sourcesContent":["import React, { useState } from 'react';\nimport { css, cx } from '@emotion/css';\nimport { type GroupBase } from 'react-select';\n\nimport { type GrafanaTheme2 } from '@grafana/data';\nimport {\n Select,\n type SelectCommonProps,\n type SelectContainerProps,\n SelectContainer as BaseSelectContainer,\n useStyles2,\n} from '@grafana/ui';\n\ninterface InlineSelectProps<T> extends SelectCommonProps<T> {\n label?: string;\n}\n\nexport function InlineSelect<T>({ label: labelProp, ...props }: InlineSelectProps<T>) {\n const [id] = useState(() => Math.random().toString(16).slice(2));\n const styles = useStyles2(getSelectStyles);\n const components = {\n SelectContainer,\n ValueContainer,\n SingleValue: ValueContainer,\n };\n\n return (\n <div className={styles.root}>\n {labelProp && (\n <label className={styles.label} htmlFor={id}>\n {labelProp}\n {':'} \n </label>\n )}\n <Select inputId={id} {...props} components={components} />\n </div>\n );\n}\n\nconst SelectContainer = <Option, isMulti extends boolean, Group extends GroupBase<Option>>(\n props: SelectContainerProps<Option, isMulti, Group>\n) => {\n const { children } = props;\n\n const styles = useStyles2(getSelectStyles);\n\n return (\n <BaseSelectContainer {...props} className={cx(props.className, styles.container)}>\n {children}\n </BaseSelectContainer>\n );\n};\n\nconst ValueContainer = <Option, isMulti extends boolean, Group extends GroupBase<Option>>(\n props: SelectContainerProps<Option, isMulti, Group>\n) => {\n const { className, children } = props;\n const styles = useStyles2(getSelectStyles);\n\n return <div className={cx(className, styles.valueContainer)}>{children}</div>;\n};\n\nconst getSelectStyles = (theme: GrafanaTheme2) => ({\n root: css({\n display: 'flex',\n fontSize: 12,\n alignItems: 'center',\n }),\n\n label: css({\n color: theme.colors.text.secondary,\n whiteSpace: 'nowrap',\n }),\n\n container: css({\n background: 'none',\n borderColor: 'transparent',\n }),\n\n valueContainer: css({\n display: 'flex',\n alignItems: 'center',\n flex: 'initial',\n color: theme.colors.text.secondary,\n fontSize: 12,\n }),\n});\n"],"names":["BaseSelectContainer"],"mappings":";;;;;AAiBO,SAAS,aAAgB,EAAE,KAAA,EAAO,SAAW,EAAA,GAAG,OAA+B,EAAA;AACpF,EAAA,MAAM,CAAC,EAAE,CAAI,GAAA,QAAA,CAAS,MAAM,IAAA,CAAK,MAAO,EAAA,CAAE,QAAS,CAAA,EAAE,CAAE,CAAA,KAAA,CAAM,CAAC,CAAC,CAAA;AAC/D,EAAM,MAAA,MAAA,GAAS,WAAW,eAAe,CAAA;AACzC,EAAA,MAAM,UAAa,GAAA;AAAA,IACjB,eAAA;AAAA,IACA,cAAA;AAAA,IACA,WAAa,EAAA;AAAA,GACf;AAEA,EACE,uBAAA,KAAA,CAAA,aAAA,CAAC,KAAI,EAAA,EAAA,SAAA,EAAW,MAAO,CAAA,IAAA,EAAA,EACpB,6BACE,KAAA,CAAA,aAAA,CAAA,OAAA,EAAA,EAAM,SAAW,EAAA,MAAA,CAAO,KAAO,EAAA,OAAA,EAAS,MACtC,SACA,EAAA,GAAA,EAAI,MACP,CAAA,kBAED,KAAA,CAAA,aAAA,CAAA,MAAA,EAAA,EAAO,SAAS,EAAK,EAAA,GAAG,KAAO,EAAA,UAAA,EAAwB,CAC1D,CAAA;AAEJ;AAEA,MAAM,eAAA,GAAkB,CACtB,KACG,KAAA;AACH,EAAM,MAAA,EAAE,UAAa,GAAA,KAAA;AAErB,EAAM,MAAA,MAAA,GAAS,WAAW,eAAe,CAAA;AAEzC,EACE,uBAAA,KAAA,CAAA,aAAA,CAACA,iBAAqB,EAAA,EAAA,GAAG,KAAO,EAAA,SAAA,EAAW,EAAG,CAAA,KAAA,CAAM,SAAW,EAAA,MAAA,CAAO,SAAS,CAAA,EAAA,EAC5E,QACH,CAAA;AAEJ,CAAA;AAEA,MAAM,cAAA,GAAiB,CACrB,KACG,KAAA;AACH,EAAM,MAAA,EAAE,SAAW,EAAA,QAAA,EAAa,GAAA,KAAA;AAChC,EAAM,MAAA,MAAA,GAAS,WAAW,eAAe,CAAA;AAEzC,EAAO,uBAAA,KAAA,CAAA,aAAA,CAAC,SAAI,SAAW,EAAA,EAAA,CAAG,WAAW,MAAO,CAAA,cAAc,KAAI,QAAS,CAAA;AACzE,CAAA;AAEA,MAAM,eAAA,GAAkB,CAAC,KAA0B,MAAA;AAAA,EACjD,MAAM,GAAI,CAAA;AAAA,IACR,OAAS,EAAA,MAAA;AAAA,IACT,QAAU,EAAA,EAAA;AAAA,IACV,UAAY,EAAA;AAAA,GACb,CAAA;AAAA,EAED,OAAO,GAAI,CAAA;AAAA,IACT,KAAA,EAAO,KAAM,CAAA,MAAA,CAAO,IAAK,CAAA,SAAA;AAAA,IACzB,UAAY,EAAA;AAAA,GACb,CAAA;AAAA,EAED,WAAW,GAAI,CAAA;AAAA,IACb,UAAY,EAAA,MAAA;AAAA,IACZ,WAAa,EAAA;AAAA,GACd,CAAA;AAAA,EAED,gBAAgB,GAAI,CAAA;AAAA,IAClB,OAAS,EAAA,MAAA;AAAA,IACT,UAAY,EAAA,QAAA;AAAA,IACZ,IAAM,EAAA,SAAA;AAAA,IACN,KAAA,EAAO,KAAM,CAAA,MAAA,CAAO,IAAK,CAAA,SAAA;AAAA,IACzB,QAAU,EAAA;AAAA,GACX;AACH,CAAA,CAAA;;;;"}
|
|
@@ -12,7 +12,7 @@ import 'rxjs/operators';
|
|
|
12
12
|
import '@grafana/runtime';
|
|
13
13
|
import { Space } from './Space.js';
|
|
14
14
|
|
|
15
|
-
function SqlQueryEditor({ datasource, query, onChange, onRunQuery, range }) {
|
|
15
|
+
function SqlQueryEditor({ datasource, query, onChange, onRunQuery, range, language = "sql" }) {
|
|
16
16
|
var _a, _b, _c, _d, _e, _f, _g;
|
|
17
17
|
const [isQueryRunnable, setIsQueryRunnable] = useState(true);
|
|
18
18
|
const db = datasource.getDB();
|
|
@@ -88,6 +88,7 @@ function SqlQueryEditor({ datasource, query, onChange, onRunQuery, range }) {
|
|
|
88
88
|
{
|
|
89
89
|
db,
|
|
90
90
|
query: queryWithDefaults,
|
|
91
|
+
language,
|
|
91
92
|
onChange: (q) => onQueryChange(q, false),
|
|
92
93
|
queryRowFilter,
|
|
93
94
|
onValidate: setIsQueryRunnable,
|
|
@@ -97,6 +98,7 @@ function SqlQueryEditor({ datasource, query, onChange, onRunQuery, range }) {
|
|
|
97
98
|
RawEditor,
|
|
98
99
|
{
|
|
99
100
|
db,
|
|
101
|
+
language,
|
|
100
102
|
query: queryWithDefaults,
|
|
101
103
|
queryToValidate,
|
|
102
104
|
onChange: onQueryChange,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"QueryEditor.js","sources":["../../../../src/components/QueryEditor/QueryEditor.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useState } from 'react';\nimport { useAsync } from 'react-use';\n\nimport { type QueryEditorProps } from '@grafana/data';\n\nimport { applyQueryDefaults } from './defaults';\nimport { type SQLQuery, type QueryRowFilter, type SQLOptions, EditorMode } from './types';\nimport { haveColumns } from './utils/sql.utils';\n\nimport { QueryHeader } from './QueryHeader';\nimport { RawEditor } from './query-editor-raw/RawEditor';\nimport { VisualEditor } from './visual-query-builder/VisualEditor';\n\nimport { type SqlDatasource } from '../../datasource/SqlDatasource';\nimport { Space } from './Space';\n\ninterface Props extends QueryEditorProps<SqlDatasource, SQLQuery, SQLOptions> {}\n\nexport function SqlQueryEditor({ datasource, query, onChange, onRunQuery, range }: Props) {\n const [isQueryRunnable, setIsQueryRunnable] = useState(true);\n const db = datasource.getDB();\n const defaultDataset = datasource.dataset;\n\n const { loading, error } = useAsync(async () => {\n return () => {\n if (datasource.getDB(datasource.id).init !== undefined) {\n datasource.getDB(datasource.id).init!();\n }\n };\n }, [datasource]);\n\n const queryWithDefaults = applyQueryDefaults(query);\n const [queryRowFilter, setQueryRowFilter] = useState<QueryRowFilter>({\n filter: !!queryWithDefaults.sql?.whereString,\n group: !!queryWithDefaults.sql?.groupBy?.[0]?.property.name,\n order: !!queryWithDefaults.sql?.orderBy?.property.name,\n preview: true,\n });\n const [queryToValidate, setQueryToValidate] = useState(queryWithDefaults);\n\n useEffect(() => {\n return () => {\n if (datasource.getDB(datasource.id).dispose !== undefined) {\n datasource.getDB(datasource.id).dispose!();\n }\n };\n }, [datasource]);\n\n const processQuery = useCallback(\n (q: SQLQuery) => {\n if (isQueryValid(q) && onRunQuery) {\n onRunQuery();\n }\n },\n [onRunQuery]\n );\n\n const onQueryChange = (q: SQLQuery, process = true) => {\n setQueryToValidate(q);\n onChange(q);\n\n if (haveColumns(q.sql?.columns) && q.sql?.columns.some((c) => c.name) && !queryRowFilter.group) {\n setQueryRowFilter({ ...queryRowFilter, group: true });\n }\n\n if (process) {\n processQuery(q);\n }\n };\n\n const onQueryHeaderChange = (q: SQLQuery) => {\n setQueryToValidate(q);\n onChange(q);\n };\n\n if (loading || error) {\n return null;\n }\n\n const catalogsEnabled = db.disableCatalogs === false;\n const datasetsEnabled = !db.disableDatasets;\n\n // When catalogs are enabled, datasets MUST be enabled (they act as schema selector)\n const effectiveEnableDatasets = catalogsEnabled ? true : datasetsEnabled;\n\n return (\n <>\n <QueryHeader\n db={db}\n defaultDataset={defaultDataset || ''}\n enableDatasets={effectiveEnableDatasets}\n enableCatalogs={catalogsEnabled}\n onChange={onQueryHeaderChange}\n onRunQuery={onRunQuery}\n onQueryRowChange={setQueryRowFilter}\n queryRowFilter={queryRowFilter}\n query={queryWithDefaults}\n isQueryRunnable={isQueryRunnable}\n labels={datasource.getDB(datasource.id)?.labels}\n />\n\n <Space v={0.5} />\n\n {queryWithDefaults.editorMode !== EditorMode.Code && (\n <VisualEditor\n db={db}\n query={queryWithDefaults}\n onChange={(q: SQLQuery) => onQueryChange(q, false)}\n queryRowFilter={queryRowFilter}\n onValidate={setIsQueryRunnable}\n range={range}\n />\n )}\n\n {queryWithDefaults.editorMode === EditorMode.Code && (\n <RawEditor\n db={db}\n query={queryWithDefaults}\n queryToValidate={queryToValidate}\n onChange={onQueryChange}\n onRunQuery={onRunQuery}\n onValidate={setIsQueryRunnable}\n range={range}\n />\n )}\n </>\n );\n}\n\nconst isQueryValid = (q: SQLQuery) => {\n return Boolean(q.rawSql);\n};\n"],"names":["_a","_b"],"mappings":";;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"QueryEditor.js","sources":["../../../../src/components/QueryEditor/QueryEditor.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useState } from 'react';\nimport { useAsync } from 'react-use';\n\nimport { type QueryEditorProps } from '@grafana/data';\n\nimport { applyQueryDefaults } from './defaults';\nimport { type SQLQuery, type QueryRowFilter, type SQLOptions, EditorMode } from './types';\nimport { haveColumns } from './utils/sql.utils';\n\nimport { QueryHeader } from './QueryHeader';\nimport { RawEditor } from './query-editor-raw/RawEditor';\nimport { VisualEditor } from './visual-query-builder/VisualEditor';\n\nimport { type SqlDatasource } from '../../datasource/SqlDatasource';\nimport { Space } from './Space';\nimport type { SqlLanguage } from 'sql-formatter';\n\ninterface Props extends QueryEditorProps<SqlDatasource, SQLQuery, SQLOptions> {\n language?: SqlLanguage;\n}\n\nexport function SqlQueryEditor({ datasource, query, onChange, onRunQuery, range, language = 'sql' }: Props) {\n const [isQueryRunnable, setIsQueryRunnable] = useState(true);\n const db = datasource.getDB();\n const defaultDataset = datasource.dataset;\n\n const { loading, error } = useAsync(async () => {\n return () => {\n if (datasource.getDB(datasource.id).init !== undefined) {\n datasource.getDB(datasource.id).init!();\n }\n };\n }, [datasource]);\n\n const queryWithDefaults = applyQueryDefaults(query);\n const [queryRowFilter, setQueryRowFilter] = useState<QueryRowFilter>({\n filter: !!queryWithDefaults.sql?.whereString,\n group: !!queryWithDefaults.sql?.groupBy?.[0]?.property.name,\n order: !!queryWithDefaults.sql?.orderBy?.property.name,\n preview: true,\n });\n const [queryToValidate, setQueryToValidate] = useState(queryWithDefaults);\n\n useEffect(() => {\n return () => {\n if (datasource.getDB(datasource.id).dispose !== undefined) {\n datasource.getDB(datasource.id).dispose!();\n }\n };\n }, [datasource]);\n\n const processQuery = useCallback(\n (q: SQLQuery) => {\n if (isQueryValid(q) && onRunQuery) {\n onRunQuery();\n }\n },\n [onRunQuery]\n );\n\n const onQueryChange = (q: SQLQuery, process = true) => {\n setQueryToValidate(q);\n onChange(q);\n\n if (haveColumns(q.sql?.columns) && q.sql?.columns.some((c) => c.name) && !queryRowFilter.group) {\n setQueryRowFilter({ ...queryRowFilter, group: true });\n }\n\n if (process) {\n processQuery(q);\n }\n };\n\n const onQueryHeaderChange = (q: SQLQuery) => {\n setQueryToValidate(q);\n onChange(q);\n };\n\n if (loading || error) {\n return null;\n }\n\n const catalogsEnabled = db.disableCatalogs === false;\n const datasetsEnabled = !db.disableDatasets;\n\n // When catalogs are enabled, datasets MUST be enabled (they act as schema selector)\n const effectiveEnableDatasets = catalogsEnabled ? true : datasetsEnabled;\n\n return (\n <>\n <QueryHeader\n db={db}\n defaultDataset={defaultDataset || ''}\n enableDatasets={effectiveEnableDatasets}\n enableCatalogs={catalogsEnabled}\n onChange={onQueryHeaderChange}\n onRunQuery={onRunQuery}\n onQueryRowChange={setQueryRowFilter}\n queryRowFilter={queryRowFilter}\n query={queryWithDefaults}\n isQueryRunnable={isQueryRunnable}\n labels={datasource.getDB(datasource.id)?.labels}\n />\n\n <Space v={0.5} />\n\n {queryWithDefaults.editorMode !== EditorMode.Code && (\n <VisualEditor\n db={db}\n query={queryWithDefaults}\n language={language}\n onChange={(q: SQLQuery) => onQueryChange(q, false)}\n queryRowFilter={queryRowFilter}\n onValidate={setIsQueryRunnable}\n range={range}\n />\n )}\n\n {queryWithDefaults.editorMode === EditorMode.Code && (\n <RawEditor\n db={db}\n language={language}\n query={queryWithDefaults}\n queryToValidate={queryToValidate}\n onChange={onQueryChange}\n onRunQuery={onRunQuery}\n onValidate={setIsQueryRunnable}\n range={range}\n />\n )}\n </>\n );\n}\n\nconst isQueryValid = (q: SQLQuery) => {\n return Boolean(q.rawSql);\n};\n"],"names":["_a","_b"],"mappings":"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"}
|
|
@@ -6,8 +6,6 @@ import { DatasetSelector } from './DatasetSelector.js';
|
|
|
6
6
|
import { CatalogSelector } from './CatalogSelector.js';
|
|
7
7
|
import { TableSelector } from './TableSelector.js';
|
|
8
8
|
import { InlineSwitch, RadioButtonGroup } from '@grafana/ui';
|
|
9
|
-
import { EditorMode, QUERY_FORMAT_OPTIONS, QueryFormat } from './types.js';
|
|
10
|
-
import { getRawSqlFn } from './utils/sql.utils.js';
|
|
11
9
|
import { EditorField } from './EditorField.js';
|
|
12
10
|
import { EditorHeader } from './EditorHeader.js';
|
|
13
11
|
import { EditorRow } from './EditorRow.js';
|
|
@@ -15,6 +13,8 @@ import { FlexItem } from './FlexItem.js';
|
|
|
15
13
|
import { InlineSelect } from './InlineSelect.js';
|
|
16
14
|
import { Space } from './Space.js';
|
|
17
15
|
import { RunQueryButton } from './RunQueryButton.js';
|
|
16
|
+
import { EditorMode, QUERY_FORMAT_OPTIONS, QueryFormat } from './types.js';
|
|
17
|
+
import { getRawSqlFn } from './utils/sql.utils.js';
|
|
18
18
|
|
|
19
19
|
const editorModes = [
|
|
20
20
|
{ label: "Builder", value: EditorMode.Builder },
|