@flanksource/clicky-ui 0.3.18 → 0.3.19
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/dist/components/ComboboxMenu.cjs +5 -1
- package/dist/components/ComboboxMenu.cjs.map +1 -1
- package/dist/components/ComboboxMenu.d.ts.map +1 -1
- package/dist/components/ComboboxMenu.js +5 -1
- package/dist/components/ComboboxMenu.js.map +1 -1
- package/dist/components/EndpointSelector.model.cjs +96 -0
- package/dist/components/EndpointSelector.model.cjs.map +1 -0
- package/dist/components/EndpointSelector.model.d.ts +2 -0
- package/dist/components/EndpointSelector.model.d.ts.map +1 -1
- package/dist/components/EndpointSelector.model.js +96 -0
- package/dist/components/EndpointSelector.model.js.map +1 -0
- package/dist/components/FilterBar.cjs +52 -2
- package/dist/components/FilterBar.cjs.map +1 -1
- package/dist/components/FilterBar.d.ts +20 -2
- package/dist/components/FilterBar.d.ts.map +1 -1
- package/dist/components/FilterBar.js +52 -2
- package/dist/components/FilterBar.js.map +1 -1
- package/dist/components/JSONPathField.cjs +87 -66
- package/dist/components/JSONPathField.cjs.map +1 -1
- package/dist/components/JSONPathField.d.ts +26 -9
- package/dist/components/JSONPathField.d.ts.map +1 -1
- package/dist/components/JSONPathField.js +88 -67
- package/dist/components/JSONPathField.js.map +1 -1
- package/dist/components/JSONPathPlayground.cjs +225 -0
- package/dist/components/JSONPathPlayground.cjs.map +1 -0
- package/dist/components/JSONPathPlayground.d.ts +59 -0
- package/dist/components/JSONPathPlayground.d.ts.map +1 -0
- package/dist/components/JSONPathPlayground.js +225 -0
- package/dist/components/JSONPathPlayground.js.map +1 -0
- package/dist/components/OnePasswordSelector.cjs +178 -0
- package/dist/components/OnePasswordSelector.cjs.map +1 -0
- package/dist/components/OnePasswordSelector.d.ts +8 -0
- package/dist/components/OnePasswordSelector.d.ts.map +1 -0
- package/dist/components/OnePasswordSelector.js +178 -0
- package/dist/components/OnePasswordSelector.js.map +1 -0
- package/dist/components/OnePasswordSelector.model.cjs +31 -0
- package/dist/components/OnePasswordSelector.model.cjs.map +1 -0
- package/dist/components/OnePasswordSelector.model.d.ts +27 -0
- package/dist/components/OnePasswordSelector.model.d.ts.map +1 -0
- package/dist/components/OnePasswordSelector.model.js +31 -0
- package/dist/components/OnePasswordSelector.model.js.map +1 -0
- package/dist/components/SecretFormField.cjs +142 -0
- package/dist/components/SecretFormField.cjs.map +1 -0
- package/dist/components/SecretFormField.d.ts +9 -0
- package/dist/components/SecretFormField.d.ts.map +1 -0
- package/dist/components/SecretFormField.js +142 -0
- package/dist/components/SecretFormField.js.map +1 -0
- package/dist/components/SecretKeySelector.cjs +20 -14
- package/dist/components/SecretKeySelector.cjs.map +1 -1
- package/dist/components/SecretKeySelector.d.ts +4 -1
- package/dist/components/SecretKeySelector.d.ts.map +1 -1
- package/dist/components/SecretKeySelector.js +20 -14
- package/dist/components/SecretKeySelector.js.map +1 -1
- package/dist/components/TreePickerField.cjs +55 -29
- package/dist/components/TreePickerField.cjs.map +1 -1
- package/dist/components/TreePickerField.d.ts +10 -1
- package/dist/components/TreePickerField.d.ts.map +1 -1
- package/dist/components/TreePickerField.js +56 -30
- package/dist/components/TreePickerField.js.map +1 -1
- package/dist/components/combobox-types.d.ts +9 -0
- package/dist/components/combobox-types.d.ts.map +1 -1
- package/dist/components/filter-bar-utils.cjs +7 -0
- package/dist/components/filter-bar-utils.cjs.map +1 -1
- package/dist/components/filter-bar-utils.d.ts.map +1 -1
- package/dist/components/filter-bar-utils.js +7 -0
- package/dist/components/filter-bar-utils.js.map +1 -1
- package/dist/components/jotai-bindings-core.cjs.map +1 -1
- package/dist/components/jotai-bindings-core.d.ts +4 -1
- package/dist/components/jotai-bindings-core.d.ts.map +1 -1
- package/dist/components/jotai-bindings-core.js.map +1 -1
- package/dist/components/json-schema-form-render.cjs +2 -1
- package/dist/components/json-schema-form-render.cjs.map +1 -1
- package/dist/components/json-schema-form-render.d.ts.map +1 -1
- package/dist/components/json-schema-form-render.js +2 -1
- package/dist/components/json-schema-form-render.js.map +1 -1
- package/dist/components/json-schema-form-types.d.ts +9 -0
- package/dist/components/json-schema-form-types.d.ts.map +1 -1
- package/dist/components/jsonPathTree.cjs +189 -0
- package/dist/components/jsonPathTree.cjs.map +1 -0
- package/dist/components/jsonPathTree.d.ts +92 -0
- package/dist/components/jsonPathTree.d.ts.map +1 -0
- package/dist/components/jsonPathTree.js +189 -0
- package/dist/components/jsonPathTree.js.map +1 -0
- package/dist/components/secret-form-extension.cjs +30 -0
- package/dist/components/secret-form-extension.cjs.map +1 -0
- package/dist/components/secret-form-extension.d.ts +23 -0
- package/dist/components/secret-form-extension.d.ts.map +1 -0
- package/dist/components/secret-form-extension.js +30 -0
- package/dist/components/secret-form-extension.js.map +1 -0
- package/dist/components.cjs +16 -0
- package/dist/components.cjs.map +1 -1
- package/dist/components.d.ts +6 -0
- package/dist/components.d.ts.map +1 -1
- package/dist/components.js +16 -0
- package/dist/components.js.map +1 -1
- package/dist/data/TaskExecDetails.cjs +40 -0
- package/dist/data/TaskExecDetails.cjs.map +1 -0
- package/dist/data/TaskExecDetails.d.ts +5 -0
- package/dist/data/TaskExecDetails.d.ts.map +1 -0
- package/dist/data/TaskExecDetails.js +40 -0
- package/dist/data/TaskExecDetails.js.map +1 -0
- package/dist/data/TaskProgress.cjs +9 -3
- package/dist/data/TaskProgress.cjs.map +1 -1
- package/dist/data/TaskProgress.d.ts.map +1 -1
- package/dist/data/TaskProgress.js +9 -3
- package/dist/data/TaskProgress.js.map +1 -1
- package/dist/data/TaskSnapshot.cjs.map +1 -1
- package/dist/data/TaskSnapshot.d.ts +12 -1
- package/dist/data/TaskSnapshot.d.ts.map +1 -1
- package/dist/data/TaskSnapshot.js.map +1 -1
- package/dist/data/TreeNode.cjs +3 -0
- package/dist/data/TreeNode.cjs.map +1 -1
- package/dist/data/TreeNode.d.ts.map +1 -1
- package/dist/data/TreeNode.js +3 -0
- package/dist/data/TreeNode.js.map +1 -1
- package/dist/data/data-table-filter-values.cjs +20 -0
- package/dist/data/data-table-filter-values.cjs.map +1 -1
- package/dist/data/data-table-filter-values.d.ts +16 -0
- package/dist/data/data-table-filter-values.d.ts.map +1 -1
- package/dist/data/data-table-filter-values.js +20 -0
- package/dist/data/data-table-filter-values.js.map +1 -1
- package/dist/data/data-table-server-filters.cjs +23 -29
- package/dist/data/data-table-server-filters.cjs.map +1 -1
- package/dist/data/data-table-server-filters.d.ts.map +1 -1
- package/dist/data/data-table-server-filters.js +21 -27
- package/dist/data/data-table-server-filters.js.map +1 -1
- package/dist/data/query-browser/QueryBrowser.cjs +129 -157
- package/dist/data/query-browser/QueryBrowser.cjs.map +1 -1
- package/dist/data/query-browser/QueryBrowser.d.ts +1 -71
- package/dist/data/query-browser/QueryBrowser.d.ts.map +1 -1
- package/dist/data/query-browser/QueryBrowser.editor.cjs +88 -0
- package/dist/data/query-browser/QueryBrowser.editor.cjs.map +1 -0
- package/dist/data/query-browser/QueryBrowser.editor.d.ts +12 -0
- package/dist/data/query-browser/QueryBrowser.editor.d.ts.map +1 -0
- package/dist/data/query-browser/QueryBrowser.editor.js +88 -0
- package/dist/data/query-browser/QueryBrowser.editor.js.map +1 -0
- package/dist/data/query-browser/QueryBrowser.js +130 -158
- package/dist/data/query-browser/QueryBrowser.js.map +1 -1
- package/dist/data/query-browser/QueryBrowser.types.cjs +11 -0
- package/dist/data/query-browser/QueryBrowser.types.cjs.map +1 -0
- package/dist/data/query-browser/QueryBrowser.types.d.ts +92 -0
- package/dist/data/query-browser/QueryBrowser.types.d.ts.map +1 -0
- package/dist/data/query-browser/QueryBrowser.types.js +11 -0
- package/dist/data/query-browser/QueryBrowser.types.js.map +1 -0
- package/dist/data/query-browser/QueryBrowserDiagnosticsPanel.cjs +56 -0
- package/dist/data/query-browser/QueryBrowserDiagnosticsPanel.cjs.map +1 -0
- package/dist/data/query-browser/QueryBrowserDiagnosticsPanel.d.ts +5 -0
- package/dist/data/query-browser/QueryBrowserDiagnosticsPanel.d.ts.map +1 -0
- package/dist/data/query-browser/QueryBrowserDiagnosticsPanel.js +56 -0
- package/dist/data/query-browser/QueryBrowserDiagnosticsPanel.js.map +1 -0
- package/dist/data/query-browser/QueryBrowserResults.cjs +80 -0
- package/dist/data/query-browser/QueryBrowserResults.cjs.map +1 -0
- package/dist/data/query-browser/QueryBrowserResults.d.ts +16 -0
- package/dist/data/query-browser/QueryBrowserResults.d.ts.map +1 -0
- package/dist/data/query-browser/QueryBrowserResults.js +80 -0
- package/dist/data/query-browser/QueryBrowserResults.js.map +1 -0
- package/dist/data/query-browser/index.d.ts +2 -1
- package/dist/data/query-browser/index.d.ts.map +1 -1
- package/dist/data/task-exec-details.cjs +9 -0
- package/dist/data/task-exec-details.cjs.map +1 -0
- package/dist/data/task-exec-details.d.ts +3 -0
- package/dist/data/task-exec-details.d.ts.map +1 -0
- package/dist/data/task-exec-details.js +9 -0
- package/dist/data/task-exec-details.js.map +1 -0
- package/dist/data/version-info.cjs +3 -3
- package/dist/data/version-info.js +3 -3
- package/dist/data.cjs +2 -0
- package/dist/data.cjs.map +1 -1
- package/dist/data.d.ts +1 -1
- package/dist/data.d.ts.map +1 -1
- package/dist/data.js +2 -0
- package/dist/data.js.map +1 -1
- package/dist/index.cjs +18 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -1
- package/dist/rpc/FilterForm.cjs +20 -0
- package/dist/rpc/FilterForm.cjs.map +1 -1
- package/dist/rpc/FilterForm.js +20 -0
- package/dist/rpc/FilterForm.js.map +1 -1
- package/dist/rpc/formMetadata.cjs +34 -0
- package/dist/rpc/formMetadata.cjs.map +1 -1
- package/dist/rpc/formMetadata.d.ts.map +1 -1
- package/dist/rpc/formMetadata.js +35 -1
- package/dist/rpc/formMetadata.js.map +1 -1
- package/dist/rpc/types.cjs.map +1 -1
- package/dist/rpc/types.d.ts +9 -1
- package/dist/rpc/types.d.ts.map +1 -1
- package/dist/rpc/types.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +1 -1
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
3
|
const jsxRuntime = require("react/jsx-runtime");
|
|
4
|
-
const commands = require("@codemirror/commands");
|
|
5
|
-
const autocomplete = require("@codemirror/autocomplete");
|
|
6
|
-
const langJson = require("@codemirror/lang-json");
|
|
7
|
-
const langSql = require("@codemirror/lang-sql");
|
|
8
4
|
const state = require("@codemirror/state");
|
|
9
5
|
const view = require("@codemirror/view");
|
|
10
6
|
const react = require("react");
|
|
@@ -13,86 +9,15 @@ const JsonSchemaForm = require("../../components/JsonSchemaForm.cjs");
|
|
|
13
9
|
const utils = require("../../lib/utils.cjs");
|
|
14
10
|
const SplitPane = require("../../layout/SplitPane.cjs");
|
|
15
11
|
const Icon = require("../Icon.cjs");
|
|
16
|
-
const DataTable = require("../DataTable.cjs");
|
|
17
12
|
const dataTableUtils = require("../data-table-utils.cjs");
|
|
18
13
|
const dataTableServerFilters = require("../data-table-server-filters.cjs");
|
|
19
14
|
const ErrorDetails = require("../diagnostics/ErrorDetails.cjs");
|
|
20
|
-
const
|
|
21
|
-
const
|
|
15
|
+
const QueryBrowser_editor = require("./QueryBrowser.editor.cjs");
|
|
16
|
+
const QueryBrowserDiagnosticsPanel = require("./QueryBrowserDiagnosticsPanel.cjs");
|
|
17
|
+
const QueryBrowserResults = require("./QueryBrowserResults.cjs");
|
|
18
|
+
const QueryBrowser_types = require("./QueryBrowser.types.cjs");
|
|
19
|
+
const UiDebug = require("../../icons/components/UiDebug.cjs");
|
|
22
20
|
const UiPlay = require("../../icons/components/UiPlay.cjs");
|
|
23
|
-
const MAX_HISTORY = 50;
|
|
24
|
-
function historyKey(id) {
|
|
25
|
-
return `clicky-ui:query-browser:${id}:history`;
|
|
26
|
-
}
|
|
27
|
-
function readHistory(id) {
|
|
28
|
-
if (typeof window === "undefined") return [];
|
|
29
|
-
try {
|
|
30
|
-
const value = JSON.parse(
|
|
31
|
-
window.localStorage.getItem(historyKey(id)) ?? "[]"
|
|
32
|
-
);
|
|
33
|
-
return Array.isArray(value) ? value.slice(0, MAX_HISTORY) : [];
|
|
34
|
-
} catch {
|
|
35
|
-
return [];
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
function rememberQuery(id, query) {
|
|
39
|
-
const entries = readHistory(id).filter((entry) => entry.query !== query);
|
|
40
|
-
const next = [{ query, at: Date.now() }, ...entries].slice(0, MAX_HISTORY);
|
|
41
|
-
if (typeof window !== "undefined") {
|
|
42
|
-
window.localStorage.setItem(historyKey(id), JSON.stringify(next));
|
|
43
|
-
}
|
|
44
|
-
return next;
|
|
45
|
-
}
|
|
46
|
-
function editorExtensions(execute, onQueryChange, languageExtension2) {
|
|
47
|
-
return [
|
|
48
|
-
commands.history(),
|
|
49
|
-
view.keymap.of([
|
|
50
|
-
{
|
|
51
|
-
key: "Mod-Enter",
|
|
52
|
-
run: () => {
|
|
53
|
-
execute();
|
|
54
|
-
return true;
|
|
55
|
-
}
|
|
56
|
-
},
|
|
57
|
-
...commands.historyKeymap
|
|
58
|
-
]),
|
|
59
|
-
view.EditorView.lineWrapping,
|
|
60
|
-
view.EditorView.updateListener.of((update) => {
|
|
61
|
-
if (update.docChanged) onQueryChange(update.state.doc.toString());
|
|
62
|
-
}),
|
|
63
|
-
view.EditorView.theme({
|
|
64
|
-
"&": { height: "100%", fontSize: "13px", background: "transparent" },
|
|
65
|
-
".cm-scroller": {
|
|
66
|
-
fontFamily: "ui-monospace, SFMono-Regular, Menlo, monospace"
|
|
67
|
-
},
|
|
68
|
-
".cm-content": { padding: "12px 0" },
|
|
69
|
-
".cm-gutters": { background: "transparent", border: "none" },
|
|
70
|
-
"&.cm-focused": { outline: "none" }
|
|
71
|
-
}),
|
|
72
|
-
languageExtension2
|
|
73
|
-
];
|
|
74
|
-
}
|
|
75
|
-
function languageExtension(language, completion) {
|
|
76
|
-
if (language === "sql") {
|
|
77
|
-
if ((completion == null ? void 0 : completion.kind) !== "sql") return langSql.sql();
|
|
78
|
-
return langSql.sql({
|
|
79
|
-
dialect: QueryBrowser_completion.dialectFor(completion.dialect),
|
|
80
|
-
schema: QueryBrowser_completion.sqlCompletionNamespace(completion.schemas),
|
|
81
|
-
upperCaseKeywords: true,
|
|
82
|
-
...completion.defaultSchema ? { defaultSchema: completion.defaultSchema } : {}
|
|
83
|
-
});
|
|
84
|
-
}
|
|
85
|
-
if (language === "json") {
|
|
86
|
-
if ((completion == null ? void 0 : completion.kind) !== "json-fields") return langJson.json();
|
|
87
|
-
return [
|
|
88
|
-
langJson.json(),
|
|
89
|
-
autocomplete.autocompletion({
|
|
90
|
-
override: [QueryBrowser_completion.openSearchJSONCompletionSource(completion.fields)]
|
|
91
|
-
})
|
|
92
|
-
];
|
|
93
|
-
}
|
|
94
|
-
return [];
|
|
95
|
-
}
|
|
96
21
|
function QueryBrowser({
|
|
97
22
|
id,
|
|
98
23
|
title,
|
|
@@ -121,7 +46,10 @@ function QueryBrowser({
|
|
|
121
46
|
const [result, setResult] = react.useState(null);
|
|
122
47
|
const [error, setError] = react.useState(null);
|
|
123
48
|
const [pending, setPending] = react.useState(false);
|
|
124
|
-
const [
|
|
49
|
+
const [debug, setDebug] = react.useState(false);
|
|
50
|
+
const [entries, setEntries] = react.useState(
|
|
51
|
+
() => QueryBrowser_editor.readQueryBrowserHistory(id)
|
|
52
|
+
);
|
|
125
53
|
const [filters, setFilters] = react.useState({});
|
|
126
54
|
const lastRun = react.useRef(null);
|
|
127
55
|
const executedFilters = react.useRef({});
|
|
@@ -139,10 +67,15 @@ function QueryBrowser({
|
|
|
139
67
|
lastRun.current = {
|
|
140
68
|
query: request.query,
|
|
141
69
|
options: request.options,
|
|
70
|
+
...request.filters ? { filters: request.filters } : {},
|
|
142
71
|
...next.columns ? { columns: next.columns } : {}
|
|
143
72
|
};
|
|
144
73
|
} catch (err) {
|
|
145
|
-
setError(
|
|
74
|
+
setError({
|
|
75
|
+
message: err instanceof Error ? err.message : String(err),
|
|
76
|
+
query: request.query,
|
|
77
|
+
...err instanceof QueryBrowser_types.QueryBrowserExecutionError && err.diagnostics ? { diagnostics: err.diagnostics } : {}
|
|
78
|
+
});
|
|
146
79
|
} finally {
|
|
147
80
|
setPending(false);
|
|
148
81
|
}
|
|
@@ -161,7 +94,7 @@ function QueryBrowser({
|
|
|
161
94
|
var _a;
|
|
162
95
|
const query = currentQuery().trim();
|
|
163
96
|
if (!query || pending) return;
|
|
164
|
-
setEntries(
|
|
97
|
+
setEntries(QueryBrowser_editor.rememberQueryBrowserQuery(id, query));
|
|
165
98
|
const repeat = ((_a = lastRun.current) == null ? void 0 : _a.query) === query ? lastRun.current : null;
|
|
166
99
|
const carried = repeat ? filters : {};
|
|
167
100
|
if (carried !== filters) setFilters(carried);
|
|
@@ -171,18 +104,42 @@ function QueryBrowser({
|
|
|
171
104
|
query,
|
|
172
105
|
options,
|
|
173
106
|
...Object.keys(carried).length > 0 ? { filters: carried } : {},
|
|
174
|
-
...(repeat == null ? void 0 : repeat.columns) ? { columns: repeat.columns } : {}
|
|
107
|
+
...(repeat == null ? void 0 : repeat.columns) ? { columns: repeat.columns } : {},
|
|
108
|
+
...debug ? { debug: true } : {}
|
|
175
109
|
});
|
|
176
|
-
}, [currentQuery, filters, id, options, pending, runRequest]);
|
|
110
|
+
}, [currentQuery, debug, filters, id, options, pending, runRequest]);
|
|
177
111
|
const rerunWithFilters = react.useCallback(
|
|
178
112
|
async (selection) => {
|
|
179
113
|
const previous = lastRun.current;
|
|
180
114
|
if (!previous) {
|
|
181
|
-
throw new Error(
|
|
115
|
+
throw new Error(
|
|
116
|
+
"QueryBrowser: a filter changed before any query had run"
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
await runRequest({
|
|
120
|
+
...previous,
|
|
121
|
+
filters: selection,
|
|
122
|
+
...(result == null ? void 0 : result.pagination) ? { pagination: { limit: result.pagination.limit } } : {},
|
|
123
|
+
...debug ? { debug: true } : {}
|
|
124
|
+
});
|
|
125
|
+
},
|
|
126
|
+
[debug, result == null ? void 0 : result.pagination, runRequest]
|
|
127
|
+
);
|
|
128
|
+
const rerunAt = react.useCallback(
|
|
129
|
+
async (pagination) => {
|
|
130
|
+
const previous = lastRun.current;
|
|
131
|
+
if (!previous) {
|
|
132
|
+
throw new Error(
|
|
133
|
+
"QueryBrowser: pagination changed before any query had run"
|
|
134
|
+
);
|
|
182
135
|
}
|
|
183
|
-
await runRequest({
|
|
136
|
+
await runRequest({
|
|
137
|
+
...previous,
|
|
138
|
+
pagination,
|
|
139
|
+
...debug ? { debug: true } : {}
|
|
140
|
+
});
|
|
184
141
|
},
|
|
185
|
-
[runRequest]
|
|
142
|
+
[debug, runRequest]
|
|
186
143
|
);
|
|
187
144
|
react.useEffect(() => {
|
|
188
145
|
if (!lastRun.current) return;
|
|
@@ -198,13 +155,15 @@ function QueryBrowser({
|
|
|
198
155
|
parent: editorHost.current,
|
|
199
156
|
state: state.EditorState.create({
|
|
200
157
|
doc: initialQuery,
|
|
201
|
-
extensions:
|
|
158
|
+
extensions: QueryBrowser_editor.queryBrowserEditorExtensions(
|
|
202
159
|
() => executeRef.current(),
|
|
203
160
|
(query) => {
|
|
204
161
|
var _a;
|
|
205
162
|
return (_a = onQueryChangeRef.current) == null ? void 0 : _a.call(onQueryChangeRef, query);
|
|
206
163
|
},
|
|
207
|
-
languageConfig.current.of(
|
|
164
|
+
languageConfig.current.of(
|
|
165
|
+
QueryBrowser_editor.queryBrowserLanguageExtension(language, completion)
|
|
166
|
+
)
|
|
208
167
|
)
|
|
209
168
|
})
|
|
210
169
|
});
|
|
@@ -219,7 +178,7 @@ function QueryBrowser({
|
|
|
219
178
|
if (!view2) return;
|
|
220
179
|
view2.dispatch({
|
|
221
180
|
effects: languageConfig.current.reconfigure(
|
|
222
|
-
|
|
181
|
+
QueryBrowser_editor.queryBrowserLanguageExtension(language, completion)
|
|
223
182
|
)
|
|
224
183
|
});
|
|
225
184
|
}, [completion, language]);
|
|
@@ -241,10 +200,11 @@ function QueryBrowser({
|
|
|
241
200
|
[onOptionsChange]
|
|
242
201
|
);
|
|
243
202
|
react.useEffect(() => {
|
|
244
|
-
setEntries(
|
|
203
|
+
setEntries(QueryBrowser_editor.readQueryBrowserHistory(id));
|
|
245
204
|
setResult(null);
|
|
246
205
|
setError(null);
|
|
247
206
|
setFilters({});
|
|
207
|
+
setDebug(false);
|
|
248
208
|
lastRun.current = null;
|
|
249
209
|
executedFilters.current = {};
|
|
250
210
|
}, [id]);
|
|
@@ -259,7 +219,9 @@ function QueryBrowser({
|
|
|
259
219
|
return (request) => {
|
|
260
220
|
const previous = lastRun.current;
|
|
261
221
|
if (!previous) {
|
|
262
|
-
throw new Error(
|
|
222
|
+
throw new Error(
|
|
223
|
+
"QueryBrowser: a filter lookup ran before any query had"
|
|
224
|
+
);
|
|
263
225
|
}
|
|
264
226
|
return lookupFilterValues({ ...request, ...previous, filters });
|
|
265
227
|
};
|
|
@@ -274,59 +236,53 @@ function QueryBrowser({
|
|
|
274
236
|
[described, filters, lookupValues]
|
|
275
237
|
);
|
|
276
238
|
const serverFiltered = filterConfig.filters.length > 0 || filterConfig.timeRange !== void 0;
|
|
277
|
-
const
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
}
|
|
325
|
-
),
|
|
326
|
-
className: "min-h-0 flex-1"
|
|
327
|
-
}
|
|
328
|
-
) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-md border border-dashed p-6 text-sm text-muted-foreground", children: result.message ?? "Statement completed with no rows." })
|
|
329
|
-
] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid min-h-40 place-items-center text-sm text-muted-foreground", children: "Run a query to see results." });
|
|
239
|
+
const tablePagination = react.useMemo(() => {
|
|
240
|
+
const pagination = result == null ? void 0 : result.pagination;
|
|
241
|
+
if (!pagination) return void 0;
|
|
242
|
+
const shared = {
|
|
243
|
+
pageSize: pagination.limit,
|
|
244
|
+
...pagination.total !== void 0 ? { total: pagination.total } : {},
|
|
245
|
+
...pagination.totalRelation === "eq" || pagination.totalRelation === "gte" ? { totalRelation: pagination.totalRelation } : {},
|
|
246
|
+
hasMore: pagination.hasMore,
|
|
247
|
+
onPageSizeChange: (limit) => void rerunAt({ limit })
|
|
248
|
+
};
|
|
249
|
+
if (pagination.mode === "cursor") {
|
|
250
|
+
return {
|
|
251
|
+
...shared,
|
|
252
|
+
page: 0,
|
|
253
|
+
cursor: {
|
|
254
|
+
...pagination.cursor ? { current: pagination.cursor } : {},
|
|
255
|
+
...pagination.nextCursor ? { next: pagination.nextCursor } : {},
|
|
256
|
+
onCursorChange: (cursor) => void rerunAt({
|
|
257
|
+
limit: pagination.limit,
|
|
258
|
+
...cursor ? { cursor } : {}
|
|
259
|
+
})
|
|
260
|
+
}
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
const page = Math.floor((pagination.offset ?? 0) / pagination.limit);
|
|
264
|
+
return {
|
|
265
|
+
...shared,
|
|
266
|
+
page,
|
|
267
|
+
onPageChange: (nextPage) => void rerunAt({
|
|
268
|
+
limit: pagination.limit,
|
|
269
|
+
offset: nextPage * pagination.limit
|
|
270
|
+
})
|
|
271
|
+
};
|
|
272
|
+
}, [rerunAt, result == null ? void 0 : result.pagination]);
|
|
273
|
+
const defaultResults = /* @__PURE__ */ jsxRuntime.jsx(
|
|
274
|
+
QueryBrowserResults.QueryBrowserResults,
|
|
275
|
+
{
|
|
276
|
+
result,
|
|
277
|
+
pending,
|
|
278
|
+
...title ? { title } : {},
|
|
279
|
+
queryLabel,
|
|
280
|
+
columns,
|
|
281
|
+
filterConfig,
|
|
282
|
+
serverFiltered,
|
|
283
|
+
...tablePagination ? { pagination: tablePagination } : {}
|
|
284
|
+
}
|
|
285
|
+
);
|
|
330
286
|
const workspace = /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-full min-h-0 flex-col overflow-hidden rounded-xl border bg-card", children: [
|
|
331
287
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-2 border-b px-3 py-2", children: [
|
|
332
288
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 flex-1", children: [
|
|
@@ -354,6 +310,19 @@ function QueryBrowser({
|
|
|
354
310
|
]
|
|
355
311
|
}
|
|
356
312
|
),
|
|
313
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
314
|
+
button.Button,
|
|
315
|
+
{
|
|
316
|
+
size: "sm",
|
|
317
|
+
variant: debug ? "secondary" : "outline",
|
|
318
|
+
"aria-pressed": debug,
|
|
319
|
+
onClick: () => setDebug((enabled) => !enabled),
|
|
320
|
+
children: [
|
|
321
|
+
/* @__PURE__ */ jsxRuntime.jsx(Icon.Icon, { icon: UiDebug.UiDebug, className: "size-4" }),
|
|
322
|
+
"Debug"
|
|
323
|
+
]
|
|
324
|
+
}
|
|
325
|
+
),
|
|
357
326
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
358
327
|
button.Button,
|
|
359
328
|
{
|
|
@@ -381,18 +350,21 @@ function QueryBrowser({
|
|
|
381
350
|
}
|
|
382
351
|
) }),
|
|
383
352
|
/* @__PURE__ */ jsxRuntime.jsx("div", { ref: editorHost, className: "h-[34%] min-h-44 border-b" }),
|
|
384
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex min-h-0 flex-1 flex-col overflow-auto p-3", children: error ? /* @__PURE__ */ jsxRuntime.
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
[
|
|
391
|
-
|
|
392
|
-
|
|
353
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex min-h-0 flex-1 flex-col overflow-auto p-3", children: error ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
|
|
354
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
355
|
+
ErrorDetails.ErrorDetails,
|
|
356
|
+
{
|
|
357
|
+
diagnostics: {
|
|
358
|
+
message: error.message,
|
|
359
|
+
context: [
|
|
360
|
+
["Query", error.query],
|
|
361
|
+
["Language", language]
|
|
362
|
+
]
|
|
363
|
+
}
|
|
393
364
|
}
|
|
394
|
-
|
|
395
|
-
|
|
365
|
+
),
|
|
366
|
+
error.diagnostics && /* @__PURE__ */ jsxRuntime.jsx(QueryBrowserDiagnosticsPanel.QueryBrowserDiagnosticsPanel, { diagnostics: error.diagnostics })
|
|
367
|
+
] }) : result && renderResults ? renderResults({ result, defaultView: defaultResults }) : defaultResults })
|
|
396
368
|
] });
|
|
397
369
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: utils.cn("h-[calc(100vh-15rem)] min-h-[32rem]", className), children: navigator ? /* @__PURE__ */ jsxRuntime.jsx(SplitPane.SplitPane, { defaultSplit: 28, left: navigator, right: workspace }) : workspace });
|
|
398
370
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"QueryBrowser.cjs","sources":["../../../src/data/query-browser/QueryBrowser.tsx"],"sourcesContent":["import { history, historyKeymap } from \"@codemirror/commands\";\nimport { autocompletion } from \"@codemirror/autocomplete\";\nimport { json } from \"@codemirror/lang-json\";\nimport { sql } from \"@codemirror/lang-sql\";\nimport { Compartment, EditorState, type Extension } from \"@codemirror/state\";\nimport { EditorView, keymap } from \"@codemirror/view\";\nimport {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n type ReactNode,\n} from \"react\";\nimport { Button } from \"../../components/button\";\nimport { JsonSchemaForm } from \"../../components/JsonSchemaForm\";\nimport type { JsonSchemaObject } from \"../../components/json-schema-form-types\";\nimport { cn } from \"../../lib/utils\";\nimport { SplitPane } from \"../../layout/SplitPane\";\nimport { Icon } from \"../Icon\";\nimport { UiPlay } from \"../../icons\";\nimport { DataTable } from \"../DataTable\";\nimport { inferColumns } from \"../data-table-utils\";\nimport type { DataTableFilterSelection } from \"../data-table-filter-values\";\nimport {\n serverColumnsToDataTableColumns,\n serverFiltersToFilterBar,\n type DataTableFilterLookup,\n type DataTableFilterLookupRequest,\n type DataTableFilterLookupResult,\n type DataTableServerColumn,\n} from \"../data-table-server-filters\";\nimport { ErrorDetails } from \"../diagnostics/ErrorDetails\";\nimport { Properties } from \"../Properties\";\nimport {\n dialectFor,\n openSearchJSONCompletionSource,\n sqlCompletionNamespace,\n type QueryBrowserCompletion,\n} from \"./QueryBrowser.completion\";\n\nexport type QueryBrowserResult = {\n rows?: Record<string, unknown>[];\n /**\n * How the source describes the columns it returned, including which of them\n * it can narrow on. Present columns replace the ones inferred from the rows,\n * so a filterable result is described rather than guessed at.\n */\n columns?: DataTableServerColumn[];\n affectedRows?: number;\n durationMs?: number;\n message?: string;\n truncated?: boolean;\n /** Where a truncated read stopped, so the bound can be named rather than\n * merely hinted at with a trailing \"+\". */\n limit?: number;\n metadata?: Record<string, unknown>;\n};\n\nexport type QueryBrowserRequest = {\n query: string;\n options: Record<string, unknown>;\n /** The filter pills the user picked, if the last result described any. */\n filters?: DataTableFilterSelection;\n /**\n * The columns the last result described, echoed back so a filter binds to\n * what the source offered rather than to whatever the narrowed result\n * describes. Sources that have a catalog of their own ignore it.\n */\n columns?: DataTableServerColumn[];\n};\n\n/**\n * A filter value type-ahead, carrying the context the source needs to scope its\n * suggestions: the last *executed* query and the rest of the selection, so a\n * value list only offers values that would still return rows.\n */\nexport type QueryBrowserFilterLookupRequest = DataTableFilterLookupRequest & {\n query: string;\n options: Record<string, unknown>;\n filters: DataTableFilterSelection;\n columns?: DataTableServerColumn[];\n};\n\nexport type QueryBrowserFilterLookup = (\n request: QueryBrowserFilterLookupRequest,\n) => Promise<DataTableFilterLookupResult>;\n\nexport type QueryBrowserResultContext = {\n result: QueryBrowserResult;\n defaultView: ReactNode;\n};\n\nexport type QueryBrowserProps = {\n id: string;\n title?: string;\n language?: \"sql\" | \"json\" | \"text\";\n initialQuery?: string;\n queryLabel?: string;\n optionsSchema?: JsonSchemaObject;\n initialOptions?: Record<string, unknown>;\n completion?: QueryBrowserCompletion;\n onQueryChange?: (query: string) => void;\n onOptionsChange?: (options: Record<string, unknown>) => void;\n navigator?: ReactNode;\n execute: (request: QueryBrowserRequest) => Promise<QueryBrowserResult>;\n /**\n * Answers a filter's value type-ahead. Absent leaves every described filter\n * showing only the options the result carried.\n */\n lookupFilterValues?: QueryBrowserFilterLookup;\n renderResults?: (context: QueryBrowserResultContext) => ReactNode;\n className?: string;\n};\n\ntype HistoryEntry = { query: string; at: number };\n\nconst MAX_HISTORY = 50;\n\nfunction historyKey(id: string) {\n return `clicky-ui:query-browser:${id}:history`;\n}\n\nfunction readHistory(id: string): HistoryEntry[] {\n if (typeof window === \"undefined\") return [];\n try {\n const value = JSON.parse(\n window.localStorage.getItem(historyKey(id)) ?? \"[]\",\n );\n return Array.isArray(value) ? value.slice(0, MAX_HISTORY) : [];\n } catch {\n return [];\n }\n}\n\nfunction rememberQuery(id: string, query: string): HistoryEntry[] {\n const entries = readHistory(id).filter((entry) => entry.query !== query);\n const next = [{ query, at: Date.now() }, ...entries].slice(0, MAX_HISTORY);\n if (typeof window !== \"undefined\") {\n window.localStorage.setItem(historyKey(id), JSON.stringify(next));\n }\n return next;\n}\n\nfunction editorExtensions(\n execute: () => void,\n onQueryChange: (query: string) => void,\n languageExtension: Extension,\n) {\n return [\n history(),\n keymap.of([\n {\n key: \"Mod-Enter\",\n run: () => {\n execute();\n return true;\n },\n },\n ...historyKeymap,\n ]),\n EditorView.lineWrapping,\n EditorView.updateListener.of((update) => {\n if (update.docChanged) onQueryChange(update.state.doc.toString());\n }),\n EditorView.theme({\n \"&\": { height: \"100%\", fontSize: \"13px\", background: \"transparent\" },\n \".cm-scroller\": {\n fontFamily: \"ui-monospace, SFMono-Regular, Menlo, monospace\",\n },\n \".cm-content\": { padding: \"12px 0\" },\n \".cm-gutters\": { background: \"transparent\", border: \"none\" },\n \"&.cm-focused\": { outline: \"none\" },\n }),\n languageExtension,\n ];\n}\n\nfunction languageExtension(\n language: QueryBrowserProps[\"language\"],\n completion?: QueryBrowserCompletion,\n): Extension {\n if (language === \"sql\") {\n if (completion?.kind !== \"sql\") return sql();\n return sql({\n dialect: dialectFor(completion.dialect),\n schema: sqlCompletionNamespace(completion.schemas),\n upperCaseKeywords: true,\n ...(completion.defaultSchema\n ? { defaultSchema: completion.defaultSchema }\n : {}),\n });\n }\n if (language === \"json\") {\n if (completion?.kind !== \"json-fields\") return json();\n return [\n json(),\n autocompletion({\n override: [openSearchJSONCompletionSource(completion.fields)],\n }),\n ];\n }\n return [];\n}\n\nexport function QueryBrowser({\n id,\n title,\n language = \"text\",\n initialQuery = \"\",\n queryLabel = \"Query\",\n optionsSchema,\n initialOptions,\n completion,\n onQueryChange,\n onOptionsChange,\n navigator,\n execute,\n lookupFilterValues,\n renderResults,\n className,\n}: QueryBrowserProps) {\n const editorHost = useRef<HTMLDivElement | null>(null);\n const editor = useRef<EditorView | null>(null);\n const languageConfig = useRef(new Compartment());\n const executeRef = useRef<() => void>(() => undefined);\n const onQueryChangeRef = useRef(onQueryChange);\n const [options, setOptions] = useState<Record<string, unknown>>(\n initialOptions ?? {},\n );\n const [result, setResult] = useState<QueryBrowserResult | null>(null);\n const [error, setError] = useState<string | null>(null);\n const [pending, setPending] = useState(false);\n const [entries, setEntries] = useState<HistoryEntry[]>(() => readHistory(id));\n const [filters, setFilters] = useState<DataTableFilterSelection>({});\n // What the displayed result came from. A filter re-runs *this*, never the\n // editor's current text — otherwise changing a pill would execute a\n // half-typed edit nobody asked to run.\n const lastRun = useRef<{\n query: string;\n options: Record<string, unknown>;\n columns?: DataTableServerColumn[];\n } | null>(null);\n const executedFilters = useRef<DataTableFilterSelection>({});\n\n // Every run goes through here so the record a filter re-runs from is refreshed\n // in one place: the query, its options, and the columns the source described,\n // which are what a subsequent selection binds to.\n const runRequest = useCallback(\n async (request: QueryBrowserRequest) => {\n setPending(true);\n setError(null);\n const started = performance.now();\n try {\n const next = await execute(request);\n setResult({\n ...next,\n durationMs: next.durationMs ?? performance.now() - started,\n });\n lastRun.current = {\n query: request.query,\n options: request.options,\n ...(next.columns ? { columns: next.columns } : {}),\n };\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err));\n } finally {\n setPending(false);\n }\n },\n [execute],\n );\n\n const currentQuery = useCallback(() => {\n const view = editor.current;\n if (!view) return initialQuery;\n const selection = view.state.selection.main;\n if (!selection.empty)\n return view.state.sliceDoc(selection.from, selection.to);\n return view.state.doc.toString();\n }, [initialQuery]);\n\n const run = useCallback(async () => {\n const query = currentQuery().trim();\n if (!query || pending) return;\n setEntries(rememberQuery(id, query));\n // A different statement is a different result set, so neither its filters\n // nor the columns they bind to survive: both name columns the new query may\n // not return.\n const repeat = lastRun.current?.query === query ? lastRun.current : null;\n const carried = repeat ? filters : {};\n if (carried !== filters) setFilters(carried);\n lastRun.current = { query, options };\n executedFilters.current = carried;\n await runRequest({\n query,\n options,\n ...(Object.keys(carried).length > 0 ? { filters: carried } : {}),\n ...(repeat?.columns ? { columns: repeat.columns } : {}),\n });\n }, [currentQuery, filters, id, options, pending, runRequest]);\n\n // A filter pill is not a draft the way query text is: it commits a discrete\n // value on selection, and the bar already debounces its free-text fields. So\n // a change re-runs the last executed query immediately rather than waiting\n // for Run, which is also how the profile catalog behaves.\n const rerunWithFilters = useCallback(\n async (selection: DataTableFilterSelection) => {\n const previous = lastRun.current;\n if (!previous) {\n throw new Error(\"QueryBrowser: a filter changed before any query had run\");\n }\n await runRequest({ ...previous, filters: selection });\n },\n [runRequest],\n );\n\n useEffect(() => {\n if (!lastRun.current) return;\n if (filters === executedFilters.current) return;\n executedFilters.current = filters;\n void rerunWithFilters(filters);\n }, [filters, rerunWithFilters]);\n\n executeRef.current = () => void run();\n onQueryChangeRef.current = onQueryChange;\n\n useEffect(() => {\n if (!editorHost.current) return;\n const view = new EditorView({\n parent: editorHost.current,\n state: EditorState.create({\n doc: initialQuery,\n extensions: editorExtensions(\n () => executeRef.current(),\n (query) => onQueryChangeRef.current?.(query),\n languageConfig.current.of(languageExtension(language, completion)),\n ),\n }),\n });\n editor.current = view;\n return () => {\n editor.current = null;\n view.destroy();\n };\n }, [id, language]);\n\n useEffect(() => {\n const view = editor.current;\n if (!view) return;\n view.dispatch({\n effects: languageConfig.current.reconfigure(\n languageExtension(language, completion),\n ),\n });\n }, [completion, language]);\n\n useEffect(() => {\n const view = editor.current;\n if (!view || view.state.doc.toString() === initialQuery) return;\n view.dispatch({\n changes: { from: 0, to: view.state.doc.length, insert: initialQuery },\n });\n }, [initialQuery]);\n\n useEffect(() => {\n setOptions(initialOptions ?? {});\n }, [initialOptions]);\n\n const updateOptions = useCallback(\n (next: Record<string, unknown>) => {\n setOptions(next);\n onOptionsChange?.(next);\n },\n [onOptionsChange],\n );\n\n useEffect(() => {\n setEntries(readHistory(id));\n setResult(null);\n setError(null);\n setFilters({});\n lastRun.current = null;\n executedFilters.current = {};\n }, [id]);\n\n const rows = result?.rows ?? [];\n const described = result?.columns ?? [];\n const columns = useMemo(\n () =>\n described.length > 0\n ? serverColumnsToDataTableColumns<Record<string, unknown>>(described)\n : inferColumns(rows, { literalKeys: true }),\n [described, rows],\n );\n const lookupValues = useMemo<DataTableFilterLookup | undefined>(() => {\n if (!lookupFilterValues) return undefined;\n return (request) => {\n const previous = lastRun.current;\n if (!previous) {\n throw new Error(\"QueryBrowser: a filter lookup ran before any query had\");\n }\n return lookupFilterValues({ ...request, ...previous, filters });\n };\n }, [filters, lookupFilterValues]);\n const filterConfig = useMemo(\n () =>\n serverFiltersToFilterBar(\n described,\n filters,\n setFilters,\n lookupValues ? { lookupValues } : {},\n ),\n [described, filters, lookupValues],\n );\n const serverFiltered =\n filterConfig.filters.length > 0 || filterConfig.timeRange !== undefined;\n const defaultResults = result ? (\n <div className=\"flex min-h-0 flex-1 flex-col gap-2\">\n <div className=\"flex flex-wrap items-center gap-3 text-xs text-muted-foreground\">\n <span>\n {rows.length.toLocaleString()} rows{result.truncated ? \"+\" : \"\"}\n </span>\n {/* A \"+\" says there is more without saying the console stopped, which\n reads as a small table rather than a bounded read. Naming the bound\n is what makes the difference visible. */}\n {result.truncated && (\n <span className=\"text-amber-600 [[data-theme=dark]_&]:text-amber-400\">\n stopped at the console's {(result.limit ?? rows.length).toLocaleString()}-row bound;\n narrow the query to see the rest\n </span>\n )}\n {result.affectedRows !== undefined && (\n <span>{result.affectedRows.toLocaleString()} affected</span>\n )}\n {result.durationMs !== undefined && (\n <span>{Math.round(result.durationMs)} ms</span>\n )}\n {result.message && <span>{result.message}</span>}\n </div>\n {/* A described result keeps its table at zero rows: a filter that\n excluded everything must not unmount the bar that would undo it. */}\n {rows.length > 0 || described.length > 0 ? (\n <DataTable\n data={rows}\n columns={columns}\n loading={pending}\n autoFilter={false}\n {...(serverFiltered\n ? {\n manualFilter: true,\n externalFilters: filterConfig.filters,\n ...(filterConfig.timeRange ? { externalTimeRange: filterConfig.timeRange } : {}),\n }\n : { showGlobalFilter: true })}\n showFullscreenControl\n fullscreenTitle={title ?? queryLabel}\n detailStyle=\"dialog\"\n detailDialogTitle=\"Row details\"\n renderExpandedRow={(row) => (\n <Properties\n items={Object.entries(row).map(([key, value]) => ({\n key,\n value,\n }))}\n renderLabel={(key) => key}\n density=\"compact\"\n />\n )}\n className=\"min-h-0 flex-1\"\n />\n ) : (\n <div className=\"rounded-md border border-dashed p-6 text-sm text-muted-foreground\">\n {result.message ?? \"Statement completed with no rows.\"}\n </div>\n )}\n </div>\n ) : (\n <div className=\"grid min-h-40 place-items-center text-sm text-muted-foreground\">\n Run a query to see results.\n </div>\n );\n\n const workspace = (\n <div className=\"flex h-full min-h-0 flex-col overflow-hidden rounded-xl border bg-card\">\n <div className=\"flex flex-wrap items-center gap-2 border-b px-3 py-2\">\n <div className=\"min-w-0 flex-1\">\n {title && <h2 className=\"truncate text-sm font-semibold\">{title}</h2>}\n <p className=\"text-xs text-muted-foreground\">{queryLabel}</p>\n </div>\n {entries.length > 0 && (\n <select\n aria-label=\"Query history\"\n defaultValue=\"\"\n onChange={(event) => {\n const query = event.target.value;\n const view = editor.current;\n if (!view || !query) return;\n view.dispatch({\n changes: { from: 0, to: view.state.doc.length, insert: query },\n });\n event.target.value = \"\";\n }}\n className=\"h-8 max-w-52 rounded-md border bg-background px-2 text-xs\"\n >\n <option value=\"\">History</option>\n {entries.map((entry) => (\n <option key={`${entry.at}:${entry.query}`} value={entry.query}>\n {entry.query.replace(/\\s+/g, \" \").slice(0, 80)}\n </option>\n ))}\n </select>\n )}\n <Button\n size=\"sm\"\n onClick={() => void run()}\n loading={pending}\n loadingLabel={pending ? \"Running\" : undefined}\n >\n <Icon icon={UiPlay} className=\"size-4\" />\n Run\n </Button>\n </div>\n {optionsSchema &&\n Object.keys(optionsSchema.properties ?? {}).length > 0 && (\n <div className=\"border-b px-3 py-2\">\n <JsonSchemaForm\n schema={optionsSchema}\n value={options}\n onChange={updateOptions}\n size=\"sm\"\n inline\n showPreferencesMenu={false}\n persistPreferences={false}\n />\n </div>\n )}\n <div ref={editorHost} className=\"h-[34%] min-h-44 border-b\" />\n <div className=\"flex min-h-0 flex-1 flex-col overflow-auto p-3\">\n {error ? (\n <ErrorDetails\n diagnostics={{\n message: error,\n context: [\n [\"Query\", currentQuery()],\n [\"Language\", language],\n ],\n }}\n />\n ) : result && renderResults ? (\n renderResults({ result, defaultView: defaultResults })\n ) : (\n defaultResults\n )}\n </div>\n </div>\n );\n\n return (\n <div className={cn(\"h-[calc(100vh-15rem)] min-h-[32rem]\", className)}>\n {navigator ? (\n <SplitPane defaultSplit={28} left={navigator} right={workspace} />\n ) : (\n workspace\n )}\n </div>\n );\n}\n"],"names":["languageExtension","history","keymap","historyKeymap","EditorView","sql","dialectFor","sqlCompletionNamespace","json","autocompletion","openSearchJSONCompletionSource","useRef","Compartment","useState","useCallback","view","useEffect","EditorState","useMemo","serverColumnsToDataTableColumns","inferColumns","serverFiltersToFilterBar","jsxs","jsx","DataTable","Properties","Button","Icon","UiPlay","JsonSchemaForm","ErrorDetails","cn","SplitPane"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"QueryBrowser.cjs","sources":["../../../src/data/query-browser/QueryBrowser.tsx"],"sourcesContent":["import { Compartment, EditorState } from \"@codemirror/state\";\nimport { EditorView } from \"@codemirror/view\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { Button } from \"../../components/button\";\nimport { JsonSchemaForm } from \"../../components/JsonSchemaForm\";\nimport { cn } from \"../../lib/utils\";\nimport { SplitPane } from \"../../layout/SplitPane\";\nimport { Icon } from \"../Icon\";\nimport { UiDebug, UiPlay } from \"../../icons\";\nimport type { DataTablePagination } from \"../DataTable\";\nimport { inferColumns } from \"../data-table-utils\";\nimport type { DataTableFilterSelection } from \"../data-table-filter-values\";\nimport {\n serverColumnsToDataTableColumns,\n serverFiltersToFilterBar,\n type DataTableFilterLookup,\n type DataTableServerColumn,\n} from \"../data-table-server-filters\";\nimport { ErrorDetails } from \"../diagnostics/ErrorDetails\";\nimport {\n queryBrowserEditorExtensions,\n queryBrowserLanguageExtension,\n readQueryBrowserHistory,\n rememberQueryBrowserQuery,\n type QueryBrowserHistoryEntry,\n} from \"./QueryBrowser.editor\";\nimport { QueryBrowserDiagnosticsPanel } from \"./QueryBrowserDiagnosticsPanel\";\nimport { QueryBrowserResults } from \"./QueryBrowserResults\";\nimport {\n QueryBrowserExecutionError,\n type QueryBrowserDiagnostics,\n type QueryBrowserProps,\n type QueryBrowserRequest,\n type QueryBrowserResult,\n} from \"./QueryBrowser.types\";\n\nexport function QueryBrowser({\n id,\n title,\n language = \"text\",\n initialQuery = \"\",\n queryLabel = \"Query\",\n optionsSchema,\n initialOptions,\n completion,\n onQueryChange,\n onOptionsChange,\n navigator,\n execute,\n lookupFilterValues,\n renderResults,\n className,\n}: QueryBrowserProps) {\n const editorHost = useRef<HTMLDivElement | null>(null);\n const editor = useRef<EditorView | null>(null);\n const languageConfig = useRef(new Compartment());\n const executeRef = useRef<() => void>(() => undefined);\n const onQueryChangeRef = useRef(onQueryChange);\n const [options, setOptions] = useState<Record<string, unknown>>(\n initialOptions ?? {},\n );\n const [result, setResult] = useState<QueryBrowserResult | null>(null);\n const [error, setError] = useState<{\n message: string;\n query: string;\n diagnostics?: QueryBrowserDiagnostics;\n } | null>(null);\n const [pending, setPending] = useState(false);\n const [debug, setDebug] = useState(false);\n const [entries, setEntries] = useState<QueryBrowserHistoryEntry[]>(() =>\n readQueryBrowserHistory(id),\n );\n const [filters, setFilters] = useState<DataTableFilterSelection>({});\n // What the displayed result came from. A filter re-runs *this*, never the\n // editor's current text — otherwise changing a pill would execute a\n // half-typed edit nobody asked to run.\n const lastRun = useRef<{\n query: string;\n options: Record<string, unknown>;\n filters?: DataTableFilterSelection;\n columns?: DataTableServerColumn[];\n } | null>(null);\n const executedFilters = useRef<DataTableFilterSelection>({});\n\n // Every run goes through here so the record a filter re-runs from is refreshed\n // in one place: the query, its options, and the columns the source described,\n // which are what a subsequent selection binds to.\n const runRequest = useCallback(\n async (request: QueryBrowserRequest) => {\n setPending(true);\n setError(null);\n const started = performance.now();\n try {\n const next = await execute(request);\n setResult({\n ...next,\n durationMs: next.durationMs ?? performance.now() - started,\n });\n lastRun.current = {\n query: request.query,\n options: request.options,\n ...(request.filters ? { filters: request.filters } : {}),\n ...(next.columns ? { columns: next.columns } : {}),\n };\n } catch (err) {\n setError({\n message: err instanceof Error ? err.message : String(err),\n query: request.query,\n ...(err instanceof QueryBrowserExecutionError && err.diagnostics\n ? { diagnostics: err.diagnostics }\n : {}),\n });\n } finally {\n setPending(false);\n }\n },\n [execute],\n );\n\n const currentQuery = useCallback(() => {\n const view = editor.current;\n if (!view) return initialQuery;\n const selection = view.state.selection.main;\n if (!selection.empty)\n return view.state.sliceDoc(selection.from, selection.to);\n return view.state.doc.toString();\n }, [initialQuery]);\n\n const run = useCallback(async () => {\n const query = currentQuery().trim();\n if (!query || pending) return;\n setEntries(rememberQueryBrowserQuery(id, query));\n // A different statement is a different result set, so neither its filters\n // nor the columns they bind to survive: both name columns the new query may\n // not return.\n const repeat = lastRun.current?.query === query ? lastRun.current : null;\n const carried = repeat ? filters : {};\n if (carried !== filters) setFilters(carried);\n lastRun.current = { query, options };\n executedFilters.current = carried;\n await runRequest({\n query,\n options,\n ...(Object.keys(carried).length > 0 ? { filters: carried } : {}),\n ...(repeat?.columns ? { columns: repeat.columns } : {}),\n ...(debug ? { debug: true } : {}),\n });\n }, [currentQuery, debug, filters, id, options, pending, runRequest]);\n\n // A filter pill is not a draft the way query text is: it commits a discrete\n // value on selection, and the bar already debounces its free-text fields. So\n // a change re-runs the last executed query immediately rather than waiting\n // for Run, which is also how the profile catalog behaves.\n const rerunWithFilters = useCallback(\n async (selection: DataTableFilterSelection) => {\n const previous = lastRun.current;\n if (!previous) {\n throw new Error(\n \"QueryBrowser: a filter changed before any query had run\",\n );\n }\n await runRequest({\n ...previous,\n filters: selection,\n ...(result?.pagination\n ? { pagination: { limit: result.pagination.limit } }\n : {}),\n ...(debug ? { debug: true } : {}),\n });\n },\n [debug, result?.pagination, runRequest],\n );\n\n const rerunAt = useCallback(\n async (pagination: NonNullable<QueryBrowserRequest[\"pagination\"]>) => {\n const previous = lastRun.current;\n if (!previous) {\n throw new Error(\n \"QueryBrowser: pagination changed before any query had run\",\n );\n }\n await runRequest({\n ...previous,\n pagination,\n ...(debug ? { debug: true } : {}),\n });\n },\n [debug, runRequest],\n );\n\n useEffect(() => {\n if (!lastRun.current) return;\n if (filters === executedFilters.current) return;\n executedFilters.current = filters;\n void rerunWithFilters(filters);\n }, [filters, rerunWithFilters]);\n\n executeRef.current = () => void run();\n onQueryChangeRef.current = onQueryChange;\n\n useEffect(() => {\n if (!editorHost.current) return;\n const view = new EditorView({\n parent: editorHost.current,\n state: EditorState.create({\n doc: initialQuery,\n extensions: queryBrowserEditorExtensions(\n () => executeRef.current(),\n (query) => onQueryChangeRef.current?.(query),\n languageConfig.current.of(\n queryBrowserLanguageExtension(language, completion),\n ),\n ),\n }),\n });\n editor.current = view;\n return () => {\n editor.current = null;\n view.destroy();\n };\n }, [id, language]);\n\n useEffect(() => {\n const view = editor.current;\n if (!view) return;\n view.dispatch({\n effects: languageConfig.current.reconfigure(\n queryBrowserLanguageExtension(language, completion),\n ),\n });\n }, [completion, language]);\n\n useEffect(() => {\n const view = editor.current;\n if (!view || view.state.doc.toString() === initialQuery) return;\n view.dispatch({\n changes: { from: 0, to: view.state.doc.length, insert: initialQuery },\n });\n }, [initialQuery]);\n\n useEffect(() => {\n setOptions(initialOptions ?? {});\n }, [initialOptions]);\n\n const updateOptions = useCallback(\n (next: Record<string, unknown>) => {\n setOptions(next);\n onOptionsChange?.(next);\n },\n [onOptionsChange],\n );\n\n useEffect(() => {\n setEntries(readQueryBrowserHistory(id));\n setResult(null);\n setError(null);\n setFilters({});\n setDebug(false);\n lastRun.current = null;\n executedFilters.current = {};\n }, [id]);\n\n const rows = result?.rows ?? [];\n const described = result?.columns ?? [];\n const columns = useMemo(\n () =>\n described.length > 0\n ? serverColumnsToDataTableColumns<Record<string, unknown>>(described)\n : inferColumns(rows, { literalKeys: true }),\n [described, rows],\n );\n const lookupValues = useMemo<DataTableFilterLookup | undefined>(() => {\n if (!lookupFilterValues) return undefined;\n return (request) => {\n const previous = lastRun.current;\n if (!previous) {\n throw new Error(\n \"QueryBrowser: a filter lookup ran before any query had\",\n );\n }\n return lookupFilterValues({ ...request, ...previous, filters });\n };\n }, [filters, lookupFilterValues]);\n const filterConfig = useMemo(\n () =>\n serverFiltersToFilterBar(\n described,\n filters,\n setFilters,\n lookupValues ? { lookupValues } : {},\n ),\n [described, filters, lookupValues],\n );\n const serverFiltered =\n filterConfig.filters.length > 0 || filterConfig.timeRange !== undefined;\n const tablePagination = useMemo<DataTablePagination | undefined>(() => {\n const pagination = result?.pagination;\n if (!pagination) return undefined;\n const shared = {\n pageSize: pagination.limit,\n ...(pagination.total !== undefined ? { total: pagination.total } : {}),\n ...(pagination.totalRelation === \"eq\" ||\n pagination.totalRelation === \"gte\"\n ? { totalRelation: pagination.totalRelation }\n : {}),\n hasMore: pagination.hasMore,\n onPageSizeChange: (limit: number) => void rerunAt({ limit }),\n };\n if (pagination.mode === \"cursor\") {\n return {\n ...shared,\n page: 0,\n cursor: {\n ...(pagination.cursor ? { current: pagination.cursor } : {}),\n ...(pagination.nextCursor ? { next: pagination.nextCursor } : {}),\n onCursorChange: (cursor: string | undefined) =>\n void rerunAt({\n limit: pagination.limit,\n ...(cursor ? { cursor } : {}),\n }),\n },\n };\n }\n const page = Math.floor((pagination.offset ?? 0) / pagination.limit);\n return {\n ...shared,\n page,\n onPageChange: (nextPage: number) =>\n void rerunAt({\n limit: pagination.limit,\n offset: nextPage * pagination.limit,\n }),\n };\n }, [rerunAt, result?.pagination]);\n const defaultResults = (\n <QueryBrowserResults\n result={result}\n pending={pending}\n {...(title ? { title } : {})}\n queryLabel={queryLabel}\n columns={columns}\n filterConfig={filterConfig}\n serverFiltered={serverFiltered}\n {...(tablePagination ? { pagination: tablePagination } : {})}\n />\n );\n\n const workspace = (\n <div className=\"flex h-full min-h-0 flex-col overflow-hidden rounded-xl border bg-card\">\n <div className=\"flex flex-wrap items-center gap-2 border-b px-3 py-2\">\n <div className=\"min-w-0 flex-1\">\n {title && <h2 className=\"truncate text-sm font-semibold\">{title}</h2>}\n <p className=\"text-xs text-muted-foreground\">{queryLabel}</p>\n </div>\n {entries.length > 0 && (\n <select\n aria-label=\"Query history\"\n defaultValue=\"\"\n onChange={(event) => {\n const query = event.target.value;\n const view = editor.current;\n if (!view || !query) return;\n view.dispatch({\n changes: { from: 0, to: view.state.doc.length, insert: query },\n });\n event.target.value = \"\";\n }}\n className=\"h-8 max-w-52 rounded-md border bg-background px-2 text-xs\"\n >\n <option value=\"\">History</option>\n {entries.map((entry) => (\n <option key={`${entry.at}:${entry.query}`} value={entry.query}>\n {entry.query.replace(/\\s+/g, \" \").slice(0, 80)}\n </option>\n ))}\n </select>\n )}\n <Button\n size=\"sm\"\n variant={debug ? \"secondary\" : \"outline\"}\n aria-pressed={debug}\n onClick={() => setDebug((enabled) => !enabled)}\n >\n <Icon icon={UiDebug} className=\"size-4\" />\n Debug\n </Button>\n <Button\n size=\"sm\"\n onClick={() => void run()}\n loading={pending}\n loadingLabel={pending ? \"Running\" : undefined}\n >\n <Icon icon={UiPlay} className=\"size-4\" />\n Run\n </Button>\n </div>\n {optionsSchema &&\n Object.keys(optionsSchema.properties ?? {}).length > 0 && (\n <div className=\"border-b px-3 py-2\">\n <JsonSchemaForm\n schema={optionsSchema}\n value={options}\n onChange={updateOptions}\n size=\"sm\"\n inline\n showPreferencesMenu={false}\n persistPreferences={false}\n />\n </div>\n )}\n <div ref={editorHost} className=\"h-[34%] min-h-44 border-b\" />\n <div className=\"flex min-h-0 flex-1 flex-col overflow-auto p-3\">\n {error ? (\n <div className=\"space-y-3\">\n <ErrorDetails\n diagnostics={{\n message: error.message,\n context: [\n [\"Query\", error.query],\n [\"Language\", language],\n ],\n }}\n />\n {error.diagnostics && (\n <QueryBrowserDiagnosticsPanel diagnostics={error.diagnostics} />\n )}\n </div>\n ) : result && renderResults ? (\n renderResults({ result, defaultView: defaultResults })\n ) : (\n defaultResults\n )}\n </div>\n </div>\n );\n\n return (\n <div className={cn(\"h-[calc(100vh-15rem)] min-h-[32rem]\", className)}>\n {navigator ? (\n <SplitPane defaultSplit={28} left={navigator} right={workspace} />\n ) : (\n workspace\n )}\n </div>\n );\n}\n"],"names":["useRef","Compartment","useState","readQueryBrowserHistory","useCallback","QueryBrowserExecutionError","view","rememberQueryBrowserQuery","useEffect","EditorView","EditorState","queryBrowserEditorExtensions","queryBrowserLanguageExtension","useMemo","serverColumnsToDataTableColumns","inferColumns","serverFiltersToFilterBar","jsx","QueryBrowserResults","jsxs","Button","Icon","UiDebug","UiPlay","JsonSchemaForm","ErrorDetails","QueryBrowserDiagnosticsPanel","cn","SplitPane"],"mappings":";;;;;;;;;;;;;;;;;;;;AAoCO,SAAS,aAAa;AAAA,EAC3B;AAAA,EACA;AAAA,EACA,WAAW;AAAA,EACX,eAAe;AAAA,EACf,aAAa;AAAA,EACb;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAsB;AACpB,QAAM,aAAaA,MAAAA,OAA8B,IAAI;AACrD,QAAM,SAASA,MAAAA,OAA0B,IAAI;AAC7C,QAAM,iBAAiBA,MAAAA,OAAO,IAAIC,MAAAA,aAAa;AAC/C,QAAM,aAAaD,aAAmB,MAAM,MAAS;AACrD,QAAM,mBAAmBA,MAAAA,OAAO,aAAa;AAC7C,QAAM,CAAC,SAAS,UAAU,IAAIE,MAAAA;AAAAA,IAC5B,kBAAkB,CAAA;AAAA,EAAC;AAErB,QAAM,CAAC,QAAQ,SAAS,IAAIA,MAAAA,SAAoC,IAAI;AACpE,QAAM,CAAC,OAAO,QAAQ,IAAIA,MAAAA,SAIhB,IAAI;AACd,QAAM,CAAC,SAAS,UAAU,IAAIA,MAAAA,SAAS,KAAK;AAC5C,QAAM,CAAC,OAAO,QAAQ,IAAIA,MAAAA,SAAS,KAAK;AACxC,QAAM,CAAC,SAAS,UAAU,IAAIA,MAAAA;AAAAA,IAAqC,MACjEC,oBAAAA,wBAAwB,EAAE;AAAA,EAAA;AAE5B,QAAM,CAAC,SAAS,UAAU,IAAID,MAAAA,SAAmC,CAAA,CAAE;AAInE,QAAM,UAAUF,MAAAA,OAKN,IAAI;AACd,QAAM,kBAAkBA,MAAAA,OAAiC,EAAE;AAK3D,QAAM,aAAaI,MAAAA;AAAAA,IACjB,OAAO,YAAiC;AACtC,iBAAW,IAAI;AACf,eAAS,IAAI;AACb,YAAM,UAAU,YAAY,IAAA;AAC5B,UAAI;AACF,cAAM,OAAO,MAAM,QAAQ,OAAO;AAClC,kBAAU;AAAA,UACR,GAAG;AAAA,UACH,YAAY,KAAK,cAAc,YAAY,QAAQ;AAAA,QAAA,CACpD;AACD,gBAAQ,UAAU;AAAA,UAChB,OAAO,QAAQ;AAAA,UACf,SAAS,QAAQ;AAAA,UACjB,GAAI,QAAQ,UAAU,EAAE,SAAS,QAAQ,QAAA,IAAY,CAAA;AAAA,UACrD,GAAI,KAAK,UAAU,EAAE,SAAS,KAAK,QAAA,IAAY,CAAA;AAAA,QAAC;AAAA,MAEpD,SAAS,KAAK;AACZ,iBAAS;AAAA,UACP,SAAS,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAAA,UACxD,OAAO,QAAQ;AAAA,UACf,GAAI,eAAeC,mBAAAA,8BAA8B,IAAI,cACjD,EAAE,aAAa,IAAI,gBACnB,CAAA;AAAA,QAAC,CACN;AAAA,MACH,UAAA;AACE,mBAAW,KAAK;AAAA,MAClB;AAAA,IACF;AAAA,IACA,CAAC,OAAO;AAAA,EAAA;AAGV,QAAM,eAAeD,MAAAA,YAAY,MAAM;AACrC,UAAME,QAAO,OAAO;AACpB,QAAI,CAACA,MAAM,QAAO;AAClB,UAAM,YAAYA,MAAK,MAAM,UAAU;AACvC,QAAI,CAAC,UAAU;AACb,aAAOA,MAAK,MAAM,SAAS,UAAU,MAAM,UAAU,EAAE;AACzD,WAAOA,MAAK,MAAM,IAAI,SAAA;AAAA,EACxB,GAAG,CAAC,YAAY,CAAC;AAEjB,QAAM,MAAMF,MAAAA,YAAY,YAAY;;AAClC,UAAM,QAAQ,aAAA,EAAe,KAAA;AAC7B,QAAI,CAAC,SAAS,QAAS;AACvB,eAAWG,oBAAAA,0BAA0B,IAAI,KAAK,CAAC;AAI/C,UAAM,WAAS,aAAQ,YAAR,mBAAiB,WAAU,QAAQ,QAAQ,UAAU;AACpE,UAAM,UAAU,SAAS,UAAU,CAAA;AACnC,QAAI,YAAY,QAAS,YAAW,OAAO;AAC3C,YAAQ,UAAU,EAAE,OAAO,QAAA;AAC3B,oBAAgB,UAAU;AAC1B,UAAM,WAAW;AAAA,MACf;AAAA,MACA;AAAA,MACA,GAAI,OAAO,KAAK,OAAO,EAAE,SAAS,IAAI,EAAE,SAAS,QAAA,IAAY,CAAA;AAAA,MAC7D,IAAI,iCAAQ,WAAU,EAAE,SAAS,OAAO,QAAA,IAAY,CAAA;AAAA,MACpD,GAAI,QAAQ,EAAE,OAAO,SAAS,CAAA;AAAA,IAAC,CAChC;AAAA,EACH,GAAG,CAAC,cAAc,OAAO,SAAS,IAAI,SAAS,SAAS,UAAU,CAAC;AAMnE,QAAM,mBAAmBH,MAAAA;AAAAA,IACvB,OAAO,cAAwC;AAC7C,YAAM,WAAW,QAAQ;AACzB,UAAI,CAAC,UAAU;AACb,cAAM,IAAI;AAAA,UACR;AAAA,QAAA;AAAA,MAEJ;AACA,YAAM,WAAW;AAAA,QACf,GAAG;AAAA,QACH,SAAS;AAAA,QACT,IAAI,iCAAQ,cACR,EAAE,YAAY,EAAE,OAAO,OAAO,WAAW,MAAA,EAAM,IAC/C,CAAA;AAAA,QACJ,GAAI,QAAQ,EAAE,OAAO,SAAS,CAAA;AAAA,MAAC,CAChC;AAAA,IACH;AAAA,IACA,CAAC,OAAO,iCAAQ,YAAY,UAAU;AAAA,EAAA;AAGxC,QAAM,UAAUA,MAAAA;AAAAA,IACd,OAAO,eAA+D;AACpE,YAAM,WAAW,QAAQ;AACzB,UAAI,CAAC,UAAU;AACb,cAAM,IAAI;AAAA,UACR;AAAA,QAAA;AAAA,MAEJ;AACA,YAAM,WAAW;AAAA,QACf,GAAG;AAAA,QACH;AAAA,QACA,GAAI,QAAQ,EAAE,OAAO,SAAS,CAAA;AAAA,MAAC,CAChC;AAAA,IACH;AAAA,IACA,CAAC,OAAO,UAAU;AAAA,EAAA;AAGpBI,QAAAA,UAAU,MAAM;AACd,QAAI,CAAC,QAAQ,QAAS;AACtB,QAAI,YAAY,gBAAgB,QAAS;AACzC,oBAAgB,UAAU;AAC1B,SAAK,iBAAiB,OAAO;AAAA,EAC/B,GAAG,CAAC,SAAS,gBAAgB,CAAC;AAE9B,aAAW,UAAU,MAAM,KAAK,IAAA;AAChC,mBAAiB,UAAU;AAE3BA,QAAAA,UAAU,MAAM;AACd,QAAI,CAAC,WAAW,QAAS;AACzB,UAAMF,SAAO,IAAIG,gBAAW;AAAA,MAC1B,QAAQ,WAAW;AAAA,MACnB,OAAOC,MAAAA,YAAY,OAAO;AAAA,QACxB,KAAK;AAAA,QACL,YAAYC,oBAAAA;AAAAA,UACV,MAAM,WAAW,QAAA;AAAA,UACjB,CAAC,UAAA;;AAAU,0CAAiB,YAAjB,0CAA2B;AAAA;AAAA,UACtC,eAAe,QAAQ;AAAA,YACrBC,oBAAAA,8BAA8B,UAAU,UAAU;AAAA,UAAA;AAAA,QACpD;AAAA,MACF,CACD;AAAA,IAAA,CACF;AACD,WAAO,UAAUN;AACjB,WAAO,MAAM;AACX,aAAO,UAAU;AACjBA,aAAK,QAAA;AAAA,IACP;AAAA,EACF,GAAG,CAAC,IAAI,QAAQ,CAAC;AAEjBE,QAAAA,UAAU,MAAM;AACd,UAAMF,QAAO,OAAO;AACpB,QAAI,CAACA,MAAM;AACX,IAAAA,MAAK,SAAS;AAAA,MACZ,SAAS,eAAe,QAAQ;AAAA,QAC9BM,oBAAAA,8BAA8B,UAAU,UAAU;AAAA,MAAA;AAAA,IACpD,CACD;AAAA,EACH,GAAG,CAAC,YAAY,QAAQ,CAAC;AAEzBJ,QAAAA,UAAU,MAAM;AACd,UAAMF,QAAO,OAAO;AACpB,QAAI,CAACA,SAAQA,MAAK,MAAM,IAAI,SAAA,MAAe,aAAc;AACzD,IAAAA,MAAK,SAAS;AAAA,MACZ,SAAS,EAAE,MAAM,GAAG,IAAIA,MAAK,MAAM,IAAI,QAAQ,QAAQ,aAAA;AAAA,IAAa,CACrE;AAAA,EACH,GAAG,CAAC,YAAY,CAAC;AAEjBE,QAAAA,UAAU,MAAM;AACd,eAAW,kBAAkB,EAAE;AAAA,EACjC,GAAG,CAAC,cAAc,CAAC;AAEnB,QAAM,gBAAgBJ,MAAAA;AAAAA,IACpB,CAAC,SAAkC;AACjC,iBAAW,IAAI;AACf,yDAAkB;AAAA,IACpB;AAAA,IACA,CAAC,eAAe;AAAA,EAAA;AAGlBI,QAAAA,UAAU,MAAM;AACd,eAAWL,oBAAAA,wBAAwB,EAAE,CAAC;AACtC,cAAU,IAAI;AACd,aAAS,IAAI;AACb,eAAW,CAAA,CAAE;AACb,aAAS,KAAK;AACd,YAAQ,UAAU;AAClB,oBAAgB,UAAU,CAAA;AAAA,EAC5B,GAAG,CAAC,EAAE,CAAC;AAEP,QAAM,QAAO,iCAAQ,SAAQ,CAAA;AAC7B,QAAM,aAAY,iCAAQ,YAAW,CAAA;AACrC,QAAM,UAAUU,MAAAA;AAAAA,IACd,MACE,UAAU,SAAS,IACfC,uDAAyD,SAAS,IAClEC,eAAAA,aAAa,MAAM,EAAE,aAAa,KAAA,CAAM;AAAA,IAC9C,CAAC,WAAW,IAAI;AAAA,EAAA;AAElB,QAAM,eAAeF,MAAAA,QAA2C,MAAM;AACpE,QAAI,CAAC,mBAAoB,QAAO;AAChC,WAAO,CAAC,YAAY;AAClB,YAAM,WAAW,QAAQ;AACzB,UAAI,CAAC,UAAU;AACb,cAAM,IAAI;AAAA,UACR;AAAA,QAAA;AAAA,MAEJ;AACA,aAAO,mBAAmB,EAAE,GAAG,SAAS,GAAG,UAAU,SAAS;AAAA,IAChE;AAAA,EACF,GAAG,CAAC,SAAS,kBAAkB,CAAC;AAChC,QAAM,eAAeA,MAAAA;AAAAA,IACnB,MACEG,uBAAAA;AAAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA,eAAe,EAAE,iBAAiB,CAAA;AAAA,IAAC;AAAA,IAEvC,CAAC,WAAW,SAAS,YAAY;AAAA,EAAA;AAEnC,QAAM,iBACJ,aAAa,QAAQ,SAAS,KAAK,aAAa,cAAc;AAChE,QAAM,kBAAkBH,MAAAA,QAAyC,MAAM;AACrE,UAAM,aAAa,iCAAQ;AAC3B,QAAI,CAAC,WAAY,QAAO;AACxB,UAAM,SAAS;AAAA,MACb,UAAU,WAAW;AAAA,MACrB,GAAI,WAAW,UAAU,SAAY,EAAE,OAAO,WAAW,MAAA,IAAU,CAAA;AAAA,MACnE,GAAI,WAAW,kBAAkB,QACjC,WAAW,kBAAkB,QACzB,EAAE,eAAe,WAAW,cAAA,IAC5B,CAAA;AAAA,MACJ,SAAS,WAAW;AAAA,MACpB,kBAAkB,CAAC,UAAkB,KAAK,QAAQ,EAAE,OAAO;AAAA,IAAA;AAE7D,QAAI,WAAW,SAAS,UAAU;AAChC,aAAO;AAAA,QACL,GAAG;AAAA,QACH,MAAM;AAAA,QACN,QAAQ;AAAA,UACN,GAAI,WAAW,SAAS,EAAE,SAAS,WAAW,OAAA,IAAW,CAAA;AAAA,UACzD,GAAI,WAAW,aAAa,EAAE,MAAM,WAAW,WAAA,IAAe,CAAA;AAAA,UAC9D,gBAAgB,CAAC,WACf,KAAK,QAAQ;AAAA,YACX,OAAO,WAAW;AAAA,YAClB,GAAI,SAAS,EAAE,WAAW,CAAA;AAAA,UAAC,CAC5B;AAAA,QAAA;AAAA,MACL;AAAA,IAEJ;AACA,UAAM,OAAO,KAAK,OAAO,WAAW,UAAU,KAAK,WAAW,KAAK;AACnE,WAAO;AAAA,MACL,GAAG;AAAA,MACH;AAAA,MACA,cAAc,CAAC,aACb,KAAK,QAAQ;AAAA,QACX,OAAO,WAAW;AAAA,QAClB,QAAQ,WAAW,WAAW;AAAA,MAAA,CAC/B;AAAA,IAAA;AAAA,EAEP,GAAG,CAAC,SAAS,iCAAQ,UAAU,CAAC;AAChC,QAAM,iBACJI,2BAAAA;AAAAA,IAACC,oBAAAA;AAAAA,IAAA;AAAA,MACC;AAAA,MACA;AAAA,MACC,GAAI,QAAQ,EAAE,MAAA,IAAU,CAAA;AAAA,MACzB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACC,GAAI,kBAAkB,EAAE,YAAY,oBAAoB,CAAA;AAAA,IAAC;AAAA,EAAA;AAI9D,QAAM,YACJC,2BAAAA,KAAC,OAAA,EAAI,WAAU,0EACb,UAAA;AAAA,IAAAA,2BAAAA,KAAC,OAAA,EAAI,WAAU,wDACb,UAAA;AAAA,MAAAA,2BAAAA,KAAC,OAAA,EAAI,WAAU,kBACZ,UAAA;AAAA,QAAA,SAASF,2BAAAA,IAAC,MAAA,EAAG,WAAU,kCAAkC,UAAA,OAAM;AAAA,QAChEA,2BAAAA,IAAC,KAAA,EAAE,WAAU,iCAAiC,UAAA,WAAA,CAAW;AAAA,MAAA,GAC3D;AAAA,MACC,QAAQ,SAAS,KAChBE,2BAAAA;AAAAA,QAAC;AAAA,QAAA;AAAA,UACC,cAAW;AAAA,UACX,cAAa;AAAA,UACb,UAAU,CAAC,UAAU;AACnB,kBAAM,QAAQ,MAAM,OAAO;AAC3B,kBAAMb,QAAO,OAAO;AACpB,gBAAI,CAACA,SAAQ,CAAC,MAAO;AACrB,YAAAA,MAAK,SAAS;AAAA,cACZ,SAAS,EAAE,MAAM,GAAG,IAAIA,MAAK,MAAM,IAAI,QAAQ,QAAQ,MAAA;AAAA,YAAM,CAC9D;AACD,kBAAM,OAAO,QAAQ;AAAA,UACvB;AAAA,UACA,WAAU;AAAA,UAEV,UAAA;AAAA,YAAAW,2BAAAA,IAAC,UAAA,EAAO,OAAM,IAAG,UAAA,WAAO;AAAA,YACvB,QAAQ,IAAI,CAAC,UACZA,2BAAAA,IAAC,UAAA,EAA0C,OAAO,MAAM,OACrD,UAAA,MAAM,MAAM,QAAQ,QAAQ,GAAG,EAAE,MAAM,GAAG,EAAE,EAAA,GADlC,GAAG,MAAM,EAAE,IAAI,MAAM,KAAK,EAEvC,CACD;AAAA,UAAA;AAAA,QAAA;AAAA,MAAA;AAAA,MAGLE,2BAAAA;AAAAA,QAACC,OAAAA;AAAAA,QAAA;AAAA,UACC,MAAK;AAAA,UACL,SAAS,QAAQ,cAAc;AAAA,UAC/B,gBAAc;AAAA,UACd,SAAS,MAAM,SAAS,CAAC,YAAY,CAAC,OAAO;AAAA,UAE7C,UAAA;AAAA,YAAAH,2BAAAA,IAACI,KAAAA,MAAA,EAAK,MAAMC,QAAAA,SAAS,WAAU,UAAS;AAAA,YAAE;AAAA,UAAA;AAAA,QAAA;AAAA,MAAA;AAAA,MAG5CH,2BAAAA;AAAAA,QAACC,OAAAA;AAAAA,QAAA;AAAA,UACC,MAAK;AAAA,UACL,SAAS,MAAM,KAAK,IAAA;AAAA,UACpB,SAAS;AAAA,UACT,cAAc,UAAU,YAAY;AAAA,UAEpC,UAAA;AAAA,YAAAH,2BAAAA,IAACI,KAAAA,MAAA,EAAK,MAAME,OAAAA,QAAQ,WAAU,UAAS;AAAA,YAAE;AAAA,UAAA;AAAA,QAAA;AAAA,MAAA;AAAA,IAE3C,GACF;AAAA,IACC,iBACC,OAAO,KAAK,cAAc,cAAc,CAAA,CAAE,EAAE,SAAS,KACnDN,2BAAAA,IAAC,OAAA,EAAI,WAAU,sBACb,UAAAA,2BAAAA;AAAAA,MAACO,eAAAA;AAAAA,MAAA;AAAA,QACC,QAAQ;AAAA,QACR,OAAO;AAAA,QACP,UAAU;AAAA,QACV,MAAK;AAAA,QACL,QAAM;AAAA,QACN,qBAAqB;AAAA,QACrB,oBAAoB;AAAA,MAAA;AAAA,IAAA,GAExB;AAAA,IAEJP,2BAAAA,IAAC,OAAA,EAAI,KAAK,YAAY,WAAU,6BAA4B;AAAA,IAC5DA,2BAAAA,IAAC,SAAI,WAAU,kDACZ,kBACCE,2BAAAA,KAAC,OAAA,EAAI,WAAU,aACb,UAAA;AAAA,MAAAF,2BAAAA;AAAAA,QAACQ,aAAAA;AAAAA,QAAA;AAAA,UACC,aAAa;AAAA,YACX,SAAS,MAAM;AAAA,YACf,SAAS;AAAA,cACP,CAAC,SAAS,MAAM,KAAK;AAAA,cACrB,CAAC,YAAY,QAAQ;AAAA,YAAA;AAAA,UACvB;AAAA,QACF;AAAA,MAAA;AAAA,MAED,MAAM,eACLR,+BAACS,6BAAAA,8BAAA,EAA6B,aAAa,MAAM,YAAA,CAAa;AAAA,IAAA,GAElE,IACE,UAAU,gBACZ,cAAc,EAAE,QAAQ,aAAa,gBAAgB,IAErD,eAAA,CAEJ;AAAA,EAAA,GACF;AAGF,wCACG,OAAA,EAAI,WAAWC,MAAAA,GAAG,uCAAuC,SAAS,GAChE,UAAA,YACCV,2BAAAA,IAACW,UAAAA,WAAA,EAAU,cAAc,IAAI,MAAM,WAAW,OAAO,UAAA,CAAW,IAEhE,WAEJ;AAEJ;;"}
|
|
@@ -1,73 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { JsonSchemaObject } from '../../components/json-schema-form-types';
|
|
3
|
-
import { DataTableFilterSelection } from '../data-table-filter-values';
|
|
4
|
-
import { DataTableFilterLookupRequest, DataTableFilterLookupResult, DataTableServerColumn } from '../data-table-server-filters';
|
|
5
|
-
import { QueryBrowserCompletion } from './QueryBrowser.completion';
|
|
6
|
-
export type QueryBrowserResult = {
|
|
7
|
-
rows?: Record<string, unknown>[];
|
|
8
|
-
/**
|
|
9
|
-
* How the source describes the columns it returned, including which of them
|
|
10
|
-
* it can narrow on. Present columns replace the ones inferred from the rows,
|
|
11
|
-
* so a filterable result is described rather than guessed at.
|
|
12
|
-
*/
|
|
13
|
-
columns?: DataTableServerColumn[];
|
|
14
|
-
affectedRows?: number;
|
|
15
|
-
durationMs?: number;
|
|
16
|
-
message?: string;
|
|
17
|
-
truncated?: boolean;
|
|
18
|
-
/** Where a truncated read stopped, so the bound can be named rather than
|
|
19
|
-
* merely hinted at with a trailing "+". */
|
|
20
|
-
limit?: number;
|
|
21
|
-
metadata?: Record<string, unknown>;
|
|
22
|
-
};
|
|
23
|
-
export type QueryBrowserRequest = {
|
|
24
|
-
query: string;
|
|
25
|
-
options: Record<string, unknown>;
|
|
26
|
-
/** The filter pills the user picked, if the last result described any. */
|
|
27
|
-
filters?: DataTableFilterSelection;
|
|
28
|
-
/**
|
|
29
|
-
* The columns the last result described, echoed back so a filter binds to
|
|
30
|
-
* what the source offered rather than to whatever the narrowed result
|
|
31
|
-
* describes. Sources that have a catalog of their own ignore it.
|
|
32
|
-
*/
|
|
33
|
-
columns?: DataTableServerColumn[];
|
|
34
|
-
};
|
|
35
|
-
/**
|
|
36
|
-
* A filter value type-ahead, carrying the context the source needs to scope its
|
|
37
|
-
* suggestions: the last *executed* query and the rest of the selection, so a
|
|
38
|
-
* value list only offers values that would still return rows.
|
|
39
|
-
*/
|
|
40
|
-
export type QueryBrowserFilterLookupRequest = DataTableFilterLookupRequest & {
|
|
41
|
-
query: string;
|
|
42
|
-
options: Record<string, unknown>;
|
|
43
|
-
filters: DataTableFilterSelection;
|
|
44
|
-
columns?: DataTableServerColumn[];
|
|
45
|
-
};
|
|
46
|
-
export type QueryBrowserFilterLookup = (request: QueryBrowserFilterLookupRequest) => Promise<DataTableFilterLookupResult>;
|
|
47
|
-
export type QueryBrowserResultContext = {
|
|
48
|
-
result: QueryBrowserResult;
|
|
49
|
-
defaultView: ReactNode;
|
|
50
|
-
};
|
|
51
|
-
export type QueryBrowserProps = {
|
|
52
|
-
id: string;
|
|
53
|
-
title?: string;
|
|
54
|
-
language?: "sql" | "json" | "text";
|
|
55
|
-
initialQuery?: string;
|
|
56
|
-
queryLabel?: string;
|
|
57
|
-
optionsSchema?: JsonSchemaObject;
|
|
58
|
-
initialOptions?: Record<string, unknown>;
|
|
59
|
-
completion?: QueryBrowserCompletion;
|
|
60
|
-
onQueryChange?: (query: string) => void;
|
|
61
|
-
onOptionsChange?: (options: Record<string, unknown>) => void;
|
|
62
|
-
navigator?: ReactNode;
|
|
63
|
-
execute: (request: QueryBrowserRequest) => Promise<QueryBrowserResult>;
|
|
64
|
-
/**
|
|
65
|
-
* Answers a filter's value type-ahead. Absent leaves every described filter
|
|
66
|
-
* showing only the options the result carried.
|
|
67
|
-
*/
|
|
68
|
-
lookupFilterValues?: QueryBrowserFilterLookup;
|
|
69
|
-
renderResults?: (context: QueryBrowserResultContext) => ReactNode;
|
|
70
|
-
className?: string;
|
|
71
|
-
};
|
|
1
|
+
import { QueryBrowserProps } from './QueryBrowser.types';
|
|
72
2
|
export declare function QueryBrowser({ id, title, language, initialQuery, queryLabel, optionsSchema, initialOptions, completion, onQueryChange, onOptionsChange, navigator, execute, lookupFilterValues, renderResults, className, }: QueryBrowserProps): import("react/jsx-runtime").JSX.Element;
|
|
73
3
|
//# sourceMappingURL=QueryBrowser.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"QueryBrowser.d.ts","sourceRoot":"","sources":["../../../src/data/query-browser/QueryBrowser.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"QueryBrowser.d.ts","sourceRoot":"","sources":["../../../src/data/query-browser/QueryBrowser.tsx"],"names":[],"mappings":"AA4BA,OAAO,EAGL,KAAK,iBAAiB,EAGvB,MAAM,sBAAsB,CAAC;AAE9B,wBAAgB,YAAY,CAAC,EAC3B,EAAE,EACF,KAAK,EACL,QAAiB,EACjB,YAAiB,EACjB,UAAoB,EACpB,aAAa,EACb,cAAc,EACd,UAAU,EACV,aAAa,EACb,eAAe,EACf,SAAS,EACT,OAAO,EACP,kBAAkB,EAClB,aAAa,EACb,SAAS,GACV,EAAE,iBAAiB,2CAyYnB"}
|