@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.
Files changed (191) hide show
  1. package/dist/components/ComboboxMenu.cjs +5 -1
  2. package/dist/components/ComboboxMenu.cjs.map +1 -1
  3. package/dist/components/ComboboxMenu.d.ts.map +1 -1
  4. package/dist/components/ComboboxMenu.js +5 -1
  5. package/dist/components/ComboboxMenu.js.map +1 -1
  6. package/dist/components/EndpointSelector.model.cjs +96 -0
  7. package/dist/components/EndpointSelector.model.cjs.map +1 -0
  8. package/dist/components/EndpointSelector.model.d.ts +2 -0
  9. package/dist/components/EndpointSelector.model.d.ts.map +1 -1
  10. package/dist/components/EndpointSelector.model.js +96 -0
  11. package/dist/components/EndpointSelector.model.js.map +1 -0
  12. package/dist/components/FilterBar.cjs +52 -2
  13. package/dist/components/FilterBar.cjs.map +1 -1
  14. package/dist/components/FilterBar.d.ts +20 -2
  15. package/dist/components/FilterBar.d.ts.map +1 -1
  16. package/dist/components/FilterBar.js +52 -2
  17. package/dist/components/FilterBar.js.map +1 -1
  18. package/dist/components/JSONPathField.cjs +87 -66
  19. package/dist/components/JSONPathField.cjs.map +1 -1
  20. package/dist/components/JSONPathField.d.ts +26 -9
  21. package/dist/components/JSONPathField.d.ts.map +1 -1
  22. package/dist/components/JSONPathField.js +88 -67
  23. package/dist/components/JSONPathField.js.map +1 -1
  24. package/dist/components/JSONPathPlayground.cjs +225 -0
  25. package/dist/components/JSONPathPlayground.cjs.map +1 -0
  26. package/dist/components/JSONPathPlayground.d.ts +59 -0
  27. package/dist/components/JSONPathPlayground.d.ts.map +1 -0
  28. package/dist/components/JSONPathPlayground.js +225 -0
  29. package/dist/components/JSONPathPlayground.js.map +1 -0
  30. package/dist/components/OnePasswordSelector.cjs +178 -0
  31. package/dist/components/OnePasswordSelector.cjs.map +1 -0
  32. package/dist/components/OnePasswordSelector.d.ts +8 -0
  33. package/dist/components/OnePasswordSelector.d.ts.map +1 -0
  34. package/dist/components/OnePasswordSelector.js +178 -0
  35. package/dist/components/OnePasswordSelector.js.map +1 -0
  36. package/dist/components/OnePasswordSelector.model.cjs +31 -0
  37. package/dist/components/OnePasswordSelector.model.cjs.map +1 -0
  38. package/dist/components/OnePasswordSelector.model.d.ts +27 -0
  39. package/dist/components/OnePasswordSelector.model.d.ts.map +1 -0
  40. package/dist/components/OnePasswordSelector.model.js +31 -0
  41. package/dist/components/OnePasswordSelector.model.js.map +1 -0
  42. package/dist/components/SecretFormField.cjs +142 -0
  43. package/dist/components/SecretFormField.cjs.map +1 -0
  44. package/dist/components/SecretFormField.d.ts +9 -0
  45. package/dist/components/SecretFormField.d.ts.map +1 -0
  46. package/dist/components/SecretFormField.js +142 -0
  47. package/dist/components/SecretFormField.js.map +1 -0
  48. package/dist/components/SecretKeySelector.cjs +20 -14
  49. package/dist/components/SecretKeySelector.cjs.map +1 -1
  50. package/dist/components/SecretKeySelector.d.ts +4 -1
  51. package/dist/components/SecretKeySelector.d.ts.map +1 -1
  52. package/dist/components/SecretKeySelector.js +20 -14
  53. package/dist/components/SecretKeySelector.js.map +1 -1
  54. package/dist/components/TreePickerField.cjs +55 -29
  55. package/dist/components/TreePickerField.cjs.map +1 -1
  56. package/dist/components/TreePickerField.d.ts +10 -1
  57. package/dist/components/TreePickerField.d.ts.map +1 -1
  58. package/dist/components/TreePickerField.js +56 -30
  59. package/dist/components/TreePickerField.js.map +1 -1
  60. package/dist/components/combobox-types.d.ts +9 -0
  61. package/dist/components/combobox-types.d.ts.map +1 -1
  62. package/dist/components/filter-bar-utils.cjs +7 -0
  63. package/dist/components/filter-bar-utils.cjs.map +1 -1
  64. package/dist/components/filter-bar-utils.d.ts.map +1 -1
  65. package/dist/components/filter-bar-utils.js +7 -0
  66. package/dist/components/filter-bar-utils.js.map +1 -1
  67. package/dist/components/jotai-bindings-core.cjs.map +1 -1
  68. package/dist/components/jotai-bindings-core.d.ts +4 -1
  69. package/dist/components/jotai-bindings-core.d.ts.map +1 -1
  70. package/dist/components/jotai-bindings-core.js.map +1 -1
  71. package/dist/components/json-schema-form-render.cjs +2 -1
  72. package/dist/components/json-schema-form-render.cjs.map +1 -1
  73. package/dist/components/json-schema-form-render.d.ts.map +1 -1
  74. package/dist/components/json-schema-form-render.js +2 -1
  75. package/dist/components/json-schema-form-render.js.map +1 -1
  76. package/dist/components/json-schema-form-types.d.ts +9 -0
  77. package/dist/components/json-schema-form-types.d.ts.map +1 -1
  78. package/dist/components/jsonPathTree.cjs +189 -0
  79. package/dist/components/jsonPathTree.cjs.map +1 -0
  80. package/dist/components/jsonPathTree.d.ts +92 -0
  81. package/dist/components/jsonPathTree.d.ts.map +1 -0
  82. package/dist/components/jsonPathTree.js +189 -0
  83. package/dist/components/jsonPathTree.js.map +1 -0
  84. package/dist/components/secret-form-extension.cjs +30 -0
  85. package/dist/components/secret-form-extension.cjs.map +1 -0
  86. package/dist/components/secret-form-extension.d.ts +23 -0
  87. package/dist/components/secret-form-extension.d.ts.map +1 -0
  88. package/dist/components/secret-form-extension.js +30 -0
  89. package/dist/components/secret-form-extension.js.map +1 -0
  90. package/dist/components.cjs +16 -0
  91. package/dist/components.cjs.map +1 -1
  92. package/dist/components.d.ts +6 -0
  93. package/dist/components.d.ts.map +1 -1
  94. package/dist/components.js +16 -0
  95. package/dist/components.js.map +1 -1
  96. package/dist/data/TaskExecDetails.cjs +40 -0
  97. package/dist/data/TaskExecDetails.cjs.map +1 -0
  98. package/dist/data/TaskExecDetails.d.ts +5 -0
  99. package/dist/data/TaskExecDetails.d.ts.map +1 -0
  100. package/dist/data/TaskExecDetails.js +40 -0
  101. package/dist/data/TaskExecDetails.js.map +1 -0
  102. package/dist/data/TaskProgress.cjs +9 -3
  103. package/dist/data/TaskProgress.cjs.map +1 -1
  104. package/dist/data/TaskProgress.d.ts.map +1 -1
  105. package/dist/data/TaskProgress.js +9 -3
  106. package/dist/data/TaskProgress.js.map +1 -1
  107. package/dist/data/TaskSnapshot.cjs.map +1 -1
  108. package/dist/data/TaskSnapshot.d.ts +12 -1
  109. package/dist/data/TaskSnapshot.d.ts.map +1 -1
  110. package/dist/data/TaskSnapshot.js.map +1 -1
  111. package/dist/data/TreeNode.cjs +3 -0
  112. package/dist/data/TreeNode.cjs.map +1 -1
  113. package/dist/data/TreeNode.d.ts.map +1 -1
  114. package/dist/data/TreeNode.js +3 -0
  115. package/dist/data/TreeNode.js.map +1 -1
  116. package/dist/data/data-table-filter-values.cjs +20 -0
  117. package/dist/data/data-table-filter-values.cjs.map +1 -1
  118. package/dist/data/data-table-filter-values.d.ts +16 -0
  119. package/dist/data/data-table-filter-values.d.ts.map +1 -1
  120. package/dist/data/data-table-filter-values.js +20 -0
  121. package/dist/data/data-table-filter-values.js.map +1 -1
  122. package/dist/data/data-table-server-filters.cjs +23 -29
  123. package/dist/data/data-table-server-filters.cjs.map +1 -1
  124. package/dist/data/data-table-server-filters.d.ts.map +1 -1
  125. package/dist/data/data-table-server-filters.js +21 -27
  126. package/dist/data/data-table-server-filters.js.map +1 -1
  127. package/dist/data/query-browser/QueryBrowser.cjs +129 -157
  128. package/dist/data/query-browser/QueryBrowser.cjs.map +1 -1
  129. package/dist/data/query-browser/QueryBrowser.d.ts +1 -71
  130. package/dist/data/query-browser/QueryBrowser.d.ts.map +1 -1
  131. package/dist/data/query-browser/QueryBrowser.editor.cjs +88 -0
  132. package/dist/data/query-browser/QueryBrowser.editor.cjs.map +1 -0
  133. package/dist/data/query-browser/QueryBrowser.editor.d.ts +12 -0
  134. package/dist/data/query-browser/QueryBrowser.editor.d.ts.map +1 -0
  135. package/dist/data/query-browser/QueryBrowser.editor.js +88 -0
  136. package/dist/data/query-browser/QueryBrowser.editor.js.map +1 -0
  137. package/dist/data/query-browser/QueryBrowser.js +130 -158
  138. package/dist/data/query-browser/QueryBrowser.js.map +1 -1
  139. package/dist/data/query-browser/QueryBrowser.types.cjs +11 -0
  140. package/dist/data/query-browser/QueryBrowser.types.cjs.map +1 -0
  141. package/dist/data/query-browser/QueryBrowser.types.d.ts +92 -0
  142. package/dist/data/query-browser/QueryBrowser.types.d.ts.map +1 -0
  143. package/dist/data/query-browser/QueryBrowser.types.js +11 -0
  144. package/dist/data/query-browser/QueryBrowser.types.js.map +1 -0
  145. package/dist/data/query-browser/QueryBrowserDiagnosticsPanel.cjs +56 -0
  146. package/dist/data/query-browser/QueryBrowserDiagnosticsPanel.cjs.map +1 -0
  147. package/dist/data/query-browser/QueryBrowserDiagnosticsPanel.d.ts +5 -0
  148. package/dist/data/query-browser/QueryBrowserDiagnosticsPanel.d.ts.map +1 -0
  149. package/dist/data/query-browser/QueryBrowserDiagnosticsPanel.js +56 -0
  150. package/dist/data/query-browser/QueryBrowserDiagnosticsPanel.js.map +1 -0
  151. package/dist/data/query-browser/QueryBrowserResults.cjs +80 -0
  152. package/dist/data/query-browser/QueryBrowserResults.cjs.map +1 -0
  153. package/dist/data/query-browser/QueryBrowserResults.d.ts +16 -0
  154. package/dist/data/query-browser/QueryBrowserResults.d.ts.map +1 -0
  155. package/dist/data/query-browser/QueryBrowserResults.js +80 -0
  156. package/dist/data/query-browser/QueryBrowserResults.js.map +1 -0
  157. package/dist/data/query-browser/index.d.ts +2 -1
  158. package/dist/data/query-browser/index.d.ts.map +1 -1
  159. package/dist/data/task-exec-details.cjs +9 -0
  160. package/dist/data/task-exec-details.cjs.map +1 -0
  161. package/dist/data/task-exec-details.d.ts +3 -0
  162. package/dist/data/task-exec-details.d.ts.map +1 -0
  163. package/dist/data/task-exec-details.js +9 -0
  164. package/dist/data/task-exec-details.js.map +1 -0
  165. package/dist/data/version-info.cjs +3 -3
  166. package/dist/data/version-info.js +3 -3
  167. package/dist/data.cjs +2 -0
  168. package/dist/data.cjs.map +1 -1
  169. package/dist/data.d.ts +1 -1
  170. package/dist/data.d.ts.map +1 -1
  171. package/dist/data.js +2 -0
  172. package/dist/data.js.map +1 -1
  173. package/dist/index.cjs +18 -0
  174. package/dist/index.cjs.map +1 -1
  175. package/dist/index.js +18 -0
  176. package/dist/index.js.map +1 -1
  177. package/dist/rpc/FilterForm.cjs +20 -0
  178. package/dist/rpc/FilterForm.cjs.map +1 -1
  179. package/dist/rpc/FilterForm.js +20 -0
  180. package/dist/rpc/FilterForm.js.map +1 -1
  181. package/dist/rpc/formMetadata.cjs +34 -0
  182. package/dist/rpc/formMetadata.cjs.map +1 -1
  183. package/dist/rpc/formMetadata.d.ts.map +1 -1
  184. package/dist/rpc/formMetadata.js +35 -1
  185. package/dist/rpc/formMetadata.js.map +1 -1
  186. package/dist/rpc/types.cjs.map +1 -1
  187. package/dist/rpc/types.d.ts +9 -1
  188. package/dist/rpc/types.d.ts.map +1 -1
  189. package/dist/rpc/types.js.map +1 -1
  190. package/dist/styles.css +1 -1
  191. package/package.json +1 -1
@@ -0,0 +1,88 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const autocomplete = require("@codemirror/autocomplete");
4
+ const commands = require("@codemirror/commands");
5
+ const langJson = require("@codemirror/lang-json");
6
+ const langSql = require("@codemirror/lang-sql");
7
+ const view = require("@codemirror/view");
8
+ const QueryBrowser_completion = require("./QueryBrowser.completion.cjs");
9
+ const MAX_HISTORY = 50;
10
+ function historyKey(id) {
11
+ return `clicky-ui:query-browser:${id}:history`;
12
+ }
13
+ function readQueryBrowserHistory(id) {
14
+ if (typeof window === "undefined") return [];
15
+ try {
16
+ const value = JSON.parse(
17
+ window.localStorage.getItem(historyKey(id)) ?? "[]"
18
+ );
19
+ return Array.isArray(value) ? value.slice(0, MAX_HISTORY) : [];
20
+ } catch {
21
+ return [];
22
+ }
23
+ }
24
+ function rememberQueryBrowserQuery(id, query) {
25
+ const entries = readQueryBrowserHistory(id).filter(
26
+ (entry) => entry.query !== query
27
+ );
28
+ const next = [{ query, at: Date.now() }, ...entries].slice(0, MAX_HISTORY);
29
+ if (typeof window !== "undefined") {
30
+ window.localStorage.setItem(historyKey(id), JSON.stringify(next));
31
+ }
32
+ return next;
33
+ }
34
+ function queryBrowserEditorExtensions(execute, onQueryChange, languageExtension) {
35
+ return [
36
+ commands.history(),
37
+ view.keymap.of([
38
+ {
39
+ key: "Mod-Enter",
40
+ run: () => {
41
+ execute();
42
+ return true;
43
+ }
44
+ },
45
+ ...commands.historyKeymap
46
+ ]),
47
+ view.EditorView.lineWrapping,
48
+ view.EditorView.updateListener.of((update) => {
49
+ if (update.docChanged) onQueryChange(update.state.doc.toString());
50
+ }),
51
+ view.EditorView.theme({
52
+ "&": { height: "100%", fontSize: "13px", background: "transparent" },
53
+ ".cm-scroller": {
54
+ fontFamily: "ui-monospace, SFMono-Regular, Menlo, monospace"
55
+ },
56
+ ".cm-content": { padding: "12px 0" },
57
+ ".cm-gutters": { background: "transparent", border: "none" },
58
+ "&.cm-focused": { outline: "none" }
59
+ }),
60
+ languageExtension
61
+ ];
62
+ }
63
+ function queryBrowserLanguageExtension(language, completion) {
64
+ if (language === "sql") {
65
+ if ((completion == null ? void 0 : completion.kind) !== "sql") return langSql.sql();
66
+ return langSql.sql({
67
+ dialect: QueryBrowser_completion.dialectFor(completion.dialect),
68
+ schema: QueryBrowser_completion.sqlCompletionNamespace(completion.schemas),
69
+ upperCaseKeywords: true,
70
+ ...completion.defaultSchema ? { defaultSchema: completion.defaultSchema } : {}
71
+ });
72
+ }
73
+ if (language === "json") {
74
+ if ((completion == null ? void 0 : completion.kind) !== "json-fields") return langJson.json();
75
+ return [
76
+ langJson.json(),
77
+ autocomplete.autocompletion({
78
+ override: [QueryBrowser_completion.openSearchJSONCompletionSource(completion.fields)]
79
+ })
80
+ ];
81
+ }
82
+ return [];
83
+ }
84
+ exports.queryBrowserEditorExtensions = queryBrowserEditorExtensions;
85
+ exports.queryBrowserLanguageExtension = queryBrowserLanguageExtension;
86
+ exports.readQueryBrowserHistory = readQueryBrowserHistory;
87
+ exports.rememberQueryBrowserQuery = rememberQueryBrowserQuery;
88
+ //# sourceMappingURL=QueryBrowser.editor.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"QueryBrowser.editor.cjs","sources":["../../../src/data/query-browser/QueryBrowser.editor.ts"],"sourcesContent":["import { autocompletion } from \"@codemirror/autocomplete\";\nimport { history, historyKeymap } from \"@codemirror/commands\";\nimport { json } from \"@codemirror/lang-json\";\nimport { sql } from \"@codemirror/lang-sql\";\nimport type { Extension } from \"@codemirror/state\";\nimport { EditorView, keymap } from \"@codemirror/view\";\nimport {\n dialectFor,\n openSearchJSONCompletionSource,\n sqlCompletionNamespace,\n type QueryBrowserCompletion,\n} from \"./QueryBrowser.completion\";\n\nexport type QueryBrowserLanguage = \"sql\" | \"json\" | \"text\";\nexport type QueryBrowserHistoryEntry = { query: string; at: number };\n\nconst MAX_HISTORY = 50;\n\nfunction historyKey(id: string) {\n return `clicky-ui:query-browser:${id}:history`;\n}\n\nexport function readQueryBrowserHistory(\n id: string,\n): QueryBrowserHistoryEntry[] {\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\nexport function rememberQueryBrowserQuery(\n id: string,\n query: string,\n): QueryBrowserHistoryEntry[] {\n const entries = readQueryBrowserHistory(id).filter(\n (entry) => entry.query !== query,\n );\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\nexport function queryBrowserEditorExtensions(\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\nexport function queryBrowserLanguageExtension(\n language: QueryBrowserLanguage,\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"],"names":["history","keymap","historyKeymap","EditorView","sql","dialectFor","sqlCompletionNamespace","json","autocompletion","openSearchJSONCompletionSource"],"mappings":";;;;;;;;AAgBA,MAAM,cAAc;AAEpB,SAAS,WAAW,IAAY;AAC9B,SAAO,2BAA2B,EAAE;AACtC;AAEO,SAAS,wBACd,IAC4B;AAC5B,MAAI,OAAO,WAAW,YAAa,QAAO,CAAA;AAC1C,MAAI;AACF,UAAM,QAAQ,KAAK;AAAA,MACjB,OAAO,aAAa,QAAQ,WAAW,EAAE,CAAC,KAAK;AAAA,IAAA;AAEjD,WAAO,MAAM,QAAQ,KAAK,IAAI,MAAM,MAAM,GAAG,WAAW,IAAI,CAAA;AAAA,EAC9D,QAAQ;AACN,WAAO,CAAA;AAAA,EACT;AACF;AAEO,SAAS,0BACd,IACA,OAC4B;AAC5B,QAAM,UAAU,wBAAwB,EAAE,EAAE;AAAA,IAC1C,CAAC,UAAU,MAAM,UAAU;AAAA,EAAA;AAE7B,QAAM,OAAO,CAAC,EAAE,OAAO,IAAI,KAAK,MAAI,GAAK,GAAG,OAAO,EAAE,MAAM,GAAG,WAAW;AACzE,MAAI,OAAO,WAAW,aAAa;AACjC,WAAO,aAAa,QAAQ,WAAW,EAAE,GAAG,KAAK,UAAU,IAAI,CAAC;AAAA,EAClE;AACA,SAAO;AACT;AAEO,SAAS,6BACd,SACA,eACA,mBACA;AACA,SAAO;AAAA,IACLA,iBAAA;AAAA,IACAC,KAAAA,OAAO,GAAG;AAAA,MACR;AAAA,QACE,KAAK;AAAA,QACL,KAAK,MAAM;AACT,kBAAA;AACA,iBAAO;AAAA,QACT;AAAA,MAAA;AAAA,MAEF,GAAGC,SAAAA;AAAAA,IAAA,CACJ;AAAA,IACDC,KAAAA,WAAW;AAAA,IACXA,KAAAA,WAAW,eAAe,GAAG,CAAC,WAAW;AACvC,UAAI,OAAO,WAAY,eAAc,OAAO,MAAM,IAAI,UAAU;AAAA,IAClE,CAAC;AAAA,IACDA,KAAAA,WAAW,MAAM;AAAA,MACf,KAAK,EAAE,QAAQ,QAAQ,UAAU,QAAQ,YAAY,cAAA;AAAA,MACrD,gBAAgB;AAAA,QACd,YAAY;AAAA,MAAA;AAAA,MAEd,eAAe,EAAE,SAAS,SAAA;AAAA,MAC1B,eAAe,EAAE,YAAY,eAAe,QAAQ,OAAA;AAAA,MACpD,gBAAgB,EAAE,SAAS,OAAA;AAAA,IAAO,CACnC;AAAA,IACD;AAAA,EAAA;AAEJ;AAEO,SAAS,8BACd,UACA,YACW;AACX,MAAI,aAAa,OAAO;AACtB,SAAI,yCAAY,UAAS,MAAO,QAAOC,QAAAA,IAAA;AACvC,WAAOA,YAAI;AAAA,MACT,SAASC,wBAAAA,WAAW,WAAW,OAAO;AAAA,MACtC,QAAQC,wBAAAA,uBAAuB,WAAW,OAAO;AAAA,MACjD,mBAAmB;AAAA,MACnB,GAAI,WAAW,gBACX,EAAE,eAAe,WAAW,cAAA,IAC5B,CAAA;AAAA,IAAC,CACN;AAAA,EACH;AACA,MAAI,aAAa,QAAQ;AACvB,SAAI,yCAAY,UAAS,cAAe,QAAOC,SAAAA,KAAA;AAC/C,WAAO;AAAA,MACLA,cAAA;AAAA,MACAC,4BAAe;AAAA,QACb,UAAU,CAACC,wBAAAA,+BAA+B,WAAW,MAAM,CAAC;AAAA,MAAA,CAC7D;AAAA,IAAA;AAAA,EAEL;AACA,SAAO,CAAA;AACT;;;;;"}
@@ -0,0 +1,12 @@
1
+ import { Extension } from '@codemirror/state';
2
+ import { QueryBrowserCompletion } from './QueryBrowser.completion';
3
+ export type QueryBrowserLanguage = "sql" | "json" | "text";
4
+ export type QueryBrowserHistoryEntry = {
5
+ query: string;
6
+ at: number;
7
+ };
8
+ export declare function readQueryBrowserHistory(id: string): QueryBrowserHistoryEntry[];
9
+ export declare function rememberQueryBrowserQuery(id: string, query: string): QueryBrowserHistoryEntry[];
10
+ export declare function queryBrowserEditorExtensions(execute: () => void, onQueryChange: (query: string) => void, languageExtension: Extension): Extension[];
11
+ export declare function queryBrowserLanguageExtension(language: QueryBrowserLanguage, completion?: QueryBrowserCompletion): Extension;
12
+ //# sourceMappingURL=QueryBrowser.editor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"QueryBrowser.editor.d.ts","sourceRoot":"","sources":["../../../src/data/query-browser/QueryBrowser.editor.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAEnD,OAAO,EAIL,KAAK,sBAAsB,EAC5B,MAAM,2BAA2B,CAAC;AAEnC,MAAM,MAAM,oBAAoB,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,CAAC;AAC3D,MAAM,MAAM,wBAAwB,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC;AAQrE,wBAAgB,uBAAuB,CACrC,EAAE,EAAE,MAAM,GACT,wBAAwB,EAAE,CAU5B;AAED,wBAAgB,yBAAyB,CACvC,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,MAAM,GACZ,wBAAwB,EAAE,CAS5B;AAED,wBAAgB,4BAA4B,CAC1C,OAAO,EAAE,MAAM,IAAI,EACnB,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,EACtC,iBAAiB,EAAE,SAAS,eA6B7B;AAED,wBAAgB,6BAA6B,CAC3C,QAAQ,EAAE,oBAAoB,EAC9B,UAAU,CAAC,EAAE,sBAAsB,GAClC,SAAS,CAsBX"}
@@ -0,0 +1,88 @@
1
+ import { autocompletion } from "@codemirror/autocomplete";
2
+ import { history, historyKeymap } from "@codemirror/commands";
3
+ import { json } from "@codemirror/lang-json";
4
+ import { sql } from "@codemirror/lang-sql";
5
+ import { EditorView, keymap } from "@codemirror/view";
6
+ import { sqlCompletionNamespace, dialectFor, openSearchJSONCompletionSource } from "./QueryBrowser.completion.js";
7
+ const MAX_HISTORY = 50;
8
+ function historyKey(id) {
9
+ return `clicky-ui:query-browser:${id}:history`;
10
+ }
11
+ function readQueryBrowserHistory(id) {
12
+ if (typeof window === "undefined") return [];
13
+ try {
14
+ const value = JSON.parse(
15
+ window.localStorage.getItem(historyKey(id)) ?? "[]"
16
+ );
17
+ return Array.isArray(value) ? value.slice(0, MAX_HISTORY) : [];
18
+ } catch {
19
+ return [];
20
+ }
21
+ }
22
+ function rememberQueryBrowserQuery(id, query) {
23
+ const entries = readQueryBrowserHistory(id).filter(
24
+ (entry) => entry.query !== query
25
+ );
26
+ const next = [{ query, at: Date.now() }, ...entries].slice(0, MAX_HISTORY);
27
+ if (typeof window !== "undefined") {
28
+ window.localStorage.setItem(historyKey(id), JSON.stringify(next));
29
+ }
30
+ return next;
31
+ }
32
+ function queryBrowserEditorExtensions(execute, onQueryChange, languageExtension) {
33
+ return [
34
+ history(),
35
+ keymap.of([
36
+ {
37
+ key: "Mod-Enter",
38
+ run: () => {
39
+ execute();
40
+ return true;
41
+ }
42
+ },
43
+ ...historyKeymap
44
+ ]),
45
+ EditorView.lineWrapping,
46
+ EditorView.updateListener.of((update) => {
47
+ if (update.docChanged) onQueryChange(update.state.doc.toString());
48
+ }),
49
+ EditorView.theme({
50
+ "&": { height: "100%", fontSize: "13px", background: "transparent" },
51
+ ".cm-scroller": {
52
+ fontFamily: "ui-monospace, SFMono-Regular, Menlo, monospace"
53
+ },
54
+ ".cm-content": { padding: "12px 0" },
55
+ ".cm-gutters": { background: "transparent", border: "none" },
56
+ "&.cm-focused": { outline: "none" }
57
+ }),
58
+ languageExtension
59
+ ];
60
+ }
61
+ function queryBrowserLanguageExtension(language, completion) {
62
+ if (language === "sql") {
63
+ if ((completion == null ? void 0 : completion.kind) !== "sql") return sql();
64
+ return sql({
65
+ dialect: dialectFor(completion.dialect),
66
+ schema: sqlCompletionNamespace(completion.schemas),
67
+ upperCaseKeywords: true,
68
+ ...completion.defaultSchema ? { defaultSchema: completion.defaultSchema } : {}
69
+ });
70
+ }
71
+ if (language === "json") {
72
+ if ((completion == null ? void 0 : completion.kind) !== "json-fields") return json();
73
+ return [
74
+ json(),
75
+ autocompletion({
76
+ override: [openSearchJSONCompletionSource(completion.fields)]
77
+ })
78
+ ];
79
+ }
80
+ return [];
81
+ }
82
+ export {
83
+ queryBrowserEditorExtensions,
84
+ queryBrowserLanguageExtension,
85
+ readQueryBrowserHistory,
86
+ rememberQueryBrowserQuery
87
+ };
88
+ //# sourceMappingURL=QueryBrowser.editor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"QueryBrowser.editor.js","sources":["../../../src/data/query-browser/QueryBrowser.editor.ts"],"sourcesContent":["import { autocompletion } from \"@codemirror/autocomplete\";\nimport { history, historyKeymap } from \"@codemirror/commands\";\nimport { json } from \"@codemirror/lang-json\";\nimport { sql } from \"@codemirror/lang-sql\";\nimport type { Extension } from \"@codemirror/state\";\nimport { EditorView, keymap } from \"@codemirror/view\";\nimport {\n dialectFor,\n openSearchJSONCompletionSource,\n sqlCompletionNamespace,\n type QueryBrowserCompletion,\n} from \"./QueryBrowser.completion\";\n\nexport type QueryBrowserLanguage = \"sql\" | \"json\" | \"text\";\nexport type QueryBrowserHistoryEntry = { query: string; at: number };\n\nconst MAX_HISTORY = 50;\n\nfunction historyKey(id: string) {\n return `clicky-ui:query-browser:${id}:history`;\n}\n\nexport function readQueryBrowserHistory(\n id: string,\n): QueryBrowserHistoryEntry[] {\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\nexport function rememberQueryBrowserQuery(\n id: string,\n query: string,\n): QueryBrowserHistoryEntry[] {\n const entries = readQueryBrowserHistory(id).filter(\n (entry) => entry.query !== query,\n );\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\nexport function queryBrowserEditorExtensions(\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\nexport function queryBrowserLanguageExtension(\n language: QueryBrowserLanguage,\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"],"names":[],"mappings":";;;;;;AAgBA,MAAM,cAAc;AAEpB,SAAS,WAAW,IAAY;AAC9B,SAAO,2BAA2B,EAAE;AACtC;AAEO,SAAS,wBACd,IAC4B;AAC5B,MAAI,OAAO,WAAW,YAAa,QAAO,CAAA;AAC1C,MAAI;AACF,UAAM,QAAQ,KAAK;AAAA,MACjB,OAAO,aAAa,QAAQ,WAAW,EAAE,CAAC,KAAK;AAAA,IAAA;AAEjD,WAAO,MAAM,QAAQ,KAAK,IAAI,MAAM,MAAM,GAAG,WAAW,IAAI,CAAA;AAAA,EAC9D,QAAQ;AACN,WAAO,CAAA;AAAA,EACT;AACF;AAEO,SAAS,0BACd,IACA,OAC4B;AAC5B,QAAM,UAAU,wBAAwB,EAAE,EAAE;AAAA,IAC1C,CAAC,UAAU,MAAM,UAAU;AAAA,EAAA;AAE7B,QAAM,OAAO,CAAC,EAAE,OAAO,IAAI,KAAK,MAAI,GAAK,GAAG,OAAO,EAAE,MAAM,GAAG,WAAW;AACzE,MAAI,OAAO,WAAW,aAAa;AACjC,WAAO,aAAa,QAAQ,WAAW,EAAE,GAAG,KAAK,UAAU,IAAI,CAAC;AAAA,EAClE;AACA,SAAO;AACT;AAEO,SAAS,6BACd,SACA,eACA,mBACA;AACA,SAAO;AAAA,IACL,QAAA;AAAA,IACA,OAAO,GAAG;AAAA,MACR;AAAA,QACE,KAAK;AAAA,QACL,KAAK,MAAM;AACT,kBAAA;AACA,iBAAO;AAAA,QACT;AAAA,MAAA;AAAA,MAEF,GAAG;AAAA,IAAA,CACJ;AAAA,IACD,WAAW;AAAA,IACX,WAAW,eAAe,GAAG,CAAC,WAAW;AACvC,UAAI,OAAO,WAAY,eAAc,OAAO,MAAM,IAAI,UAAU;AAAA,IAClE,CAAC;AAAA,IACD,WAAW,MAAM;AAAA,MACf,KAAK,EAAE,QAAQ,QAAQ,UAAU,QAAQ,YAAY,cAAA;AAAA,MACrD,gBAAgB;AAAA,QACd,YAAY;AAAA,MAAA;AAAA,MAEd,eAAe,EAAE,SAAS,SAAA;AAAA,MAC1B,eAAe,EAAE,YAAY,eAAe,QAAQ,OAAA;AAAA,MACpD,gBAAgB,EAAE,SAAS,OAAA;AAAA,IAAO,CACnC;AAAA,IACD;AAAA,EAAA;AAEJ;AAEO,SAAS,8BACd,UACA,YACW;AACX,MAAI,aAAa,OAAO;AACtB,SAAI,yCAAY,UAAS,MAAO,QAAO,IAAA;AACvC,WAAO,IAAI;AAAA,MACT,SAAS,WAAW,WAAW,OAAO;AAAA,MACtC,QAAQ,uBAAuB,WAAW,OAAO;AAAA,MACjD,mBAAmB;AAAA,MACnB,GAAI,WAAW,gBACX,EAAE,eAAe,WAAW,cAAA,IAC5B,CAAA;AAAA,IAAC,CACN;AAAA,EACH;AACA,MAAI,aAAa,QAAQ;AACvB,SAAI,yCAAY,UAAS,cAAe,QAAO,KAAA;AAC/C,WAAO;AAAA,MACL,KAAA;AAAA,MACA,eAAe;AAAA,QACb,UAAU,CAAC,+BAA+B,WAAW,MAAM,CAAC;AAAA,MAAA,CAC7D;AAAA,IAAA;AAAA,EAEL;AACA,SAAO,CAAA;AACT;"}
@@ -1,96 +1,21 @@
1
1
  import { jsxs, jsx } from "react/jsx-runtime";
2
- import { history, historyKeymap } from "@codemirror/commands";
3
- import { autocompletion } from "@codemirror/autocomplete";
4
- import { json } from "@codemirror/lang-json";
5
- import { sql } from "@codemirror/lang-sql";
6
2
  import { Compartment, EditorState } from "@codemirror/state";
7
- import { EditorView, keymap } from "@codemirror/view";
3
+ import { EditorView } from "@codemirror/view";
8
4
  import { useRef, useState, useCallback, useEffect, useMemo } from "react";
9
5
  import { Button } from "../../components/button.js";
10
6
  import { JsonSchemaForm } from "../../components/JsonSchemaForm.js";
11
7
  import { cn } from "../../lib/utils.js";
12
8
  import { SplitPane } from "../../layout/SplitPane.js";
13
9
  import { Icon } from "../Icon.js";
14
- import { DataTable } from "../DataTable.js";
15
10
  import { inferColumns } from "../data-table-utils.js";
16
11
  import { serverColumnsToDataTableColumns, serverFiltersToFilterBar } from "../data-table-server-filters.js";
17
12
  import { ErrorDetails } from "../diagnostics/ErrorDetails.js";
18
- import { Properties } from "../Properties.js";
19
- import { sqlCompletionNamespace, dialectFor, openSearchJSONCompletionSource } from "./QueryBrowser.completion.js";
13
+ import { readQueryBrowserHistory, rememberQueryBrowserQuery, queryBrowserEditorExtensions, queryBrowserLanguageExtension } from "./QueryBrowser.editor.js";
14
+ import { QueryBrowserDiagnosticsPanel } from "./QueryBrowserDiagnosticsPanel.js";
15
+ import { QueryBrowserResults } from "./QueryBrowserResults.js";
16
+ import { QueryBrowserExecutionError } from "./QueryBrowser.types.js";
17
+ import { UiDebug } from "../../icons/components/UiDebug.js";
20
18
  import { UiPlay } from "../../icons/components/UiPlay.js";
21
- const MAX_HISTORY = 50;
22
- function historyKey(id) {
23
- return `clicky-ui:query-browser:${id}:history`;
24
- }
25
- function readHistory(id) {
26
- if (typeof window === "undefined") return [];
27
- try {
28
- const value = JSON.parse(
29
- window.localStorage.getItem(historyKey(id)) ?? "[]"
30
- );
31
- return Array.isArray(value) ? value.slice(0, MAX_HISTORY) : [];
32
- } catch {
33
- return [];
34
- }
35
- }
36
- function rememberQuery(id, query) {
37
- const entries = readHistory(id).filter((entry) => entry.query !== query);
38
- const next = [{ query, at: Date.now() }, ...entries].slice(0, MAX_HISTORY);
39
- if (typeof window !== "undefined") {
40
- window.localStorage.setItem(historyKey(id), JSON.stringify(next));
41
- }
42
- return next;
43
- }
44
- function editorExtensions(execute, onQueryChange, languageExtension2) {
45
- return [
46
- history(),
47
- keymap.of([
48
- {
49
- key: "Mod-Enter",
50
- run: () => {
51
- execute();
52
- return true;
53
- }
54
- },
55
- ...historyKeymap
56
- ]),
57
- EditorView.lineWrapping,
58
- EditorView.updateListener.of((update) => {
59
- if (update.docChanged) onQueryChange(update.state.doc.toString());
60
- }),
61
- EditorView.theme({
62
- "&": { height: "100%", fontSize: "13px", background: "transparent" },
63
- ".cm-scroller": {
64
- fontFamily: "ui-monospace, SFMono-Regular, Menlo, monospace"
65
- },
66
- ".cm-content": { padding: "12px 0" },
67
- ".cm-gutters": { background: "transparent", border: "none" },
68
- "&.cm-focused": { outline: "none" }
69
- }),
70
- languageExtension2
71
- ];
72
- }
73
- function languageExtension(language, completion) {
74
- if (language === "sql") {
75
- if ((completion == null ? void 0 : completion.kind) !== "sql") return sql();
76
- return sql({
77
- dialect: dialectFor(completion.dialect),
78
- schema: sqlCompletionNamespace(completion.schemas),
79
- upperCaseKeywords: true,
80
- ...completion.defaultSchema ? { defaultSchema: completion.defaultSchema } : {}
81
- });
82
- }
83
- if (language === "json") {
84
- if ((completion == null ? void 0 : completion.kind) !== "json-fields") return json();
85
- return [
86
- json(),
87
- autocompletion({
88
- override: [openSearchJSONCompletionSource(completion.fields)]
89
- })
90
- ];
91
- }
92
- return [];
93
- }
94
19
  function QueryBrowser({
95
20
  id,
96
21
  title,
@@ -119,7 +44,10 @@ function QueryBrowser({
119
44
  const [result, setResult] = useState(null);
120
45
  const [error, setError] = useState(null);
121
46
  const [pending, setPending] = useState(false);
122
- const [entries, setEntries] = useState(() => readHistory(id));
47
+ const [debug, setDebug] = useState(false);
48
+ const [entries, setEntries] = useState(
49
+ () => readQueryBrowserHistory(id)
50
+ );
123
51
  const [filters, setFilters] = useState({});
124
52
  const lastRun = useRef(null);
125
53
  const executedFilters = useRef({});
@@ -137,10 +65,15 @@ function QueryBrowser({
137
65
  lastRun.current = {
138
66
  query: request.query,
139
67
  options: request.options,
68
+ ...request.filters ? { filters: request.filters } : {},
140
69
  ...next.columns ? { columns: next.columns } : {}
141
70
  };
142
71
  } catch (err) {
143
- setError(err instanceof Error ? err.message : String(err));
72
+ setError({
73
+ message: err instanceof Error ? err.message : String(err),
74
+ query: request.query,
75
+ ...err instanceof QueryBrowserExecutionError && err.diagnostics ? { diagnostics: err.diagnostics } : {}
76
+ });
144
77
  } finally {
145
78
  setPending(false);
146
79
  }
@@ -159,7 +92,7 @@ function QueryBrowser({
159
92
  var _a;
160
93
  const query = currentQuery().trim();
161
94
  if (!query || pending) return;
162
- setEntries(rememberQuery(id, query));
95
+ setEntries(rememberQueryBrowserQuery(id, query));
163
96
  const repeat = ((_a = lastRun.current) == null ? void 0 : _a.query) === query ? lastRun.current : null;
164
97
  const carried = repeat ? filters : {};
165
98
  if (carried !== filters) setFilters(carried);
@@ -169,18 +102,42 @@ function QueryBrowser({
169
102
  query,
170
103
  options,
171
104
  ...Object.keys(carried).length > 0 ? { filters: carried } : {},
172
- ...(repeat == null ? void 0 : repeat.columns) ? { columns: repeat.columns } : {}
105
+ ...(repeat == null ? void 0 : repeat.columns) ? { columns: repeat.columns } : {},
106
+ ...debug ? { debug: true } : {}
173
107
  });
174
- }, [currentQuery, filters, id, options, pending, runRequest]);
108
+ }, [currentQuery, debug, filters, id, options, pending, runRequest]);
175
109
  const rerunWithFilters = useCallback(
176
110
  async (selection) => {
177
111
  const previous = lastRun.current;
178
112
  if (!previous) {
179
- throw new Error("QueryBrowser: a filter changed before any query had run");
113
+ throw new Error(
114
+ "QueryBrowser: a filter changed before any query had run"
115
+ );
116
+ }
117
+ await runRequest({
118
+ ...previous,
119
+ filters: selection,
120
+ ...(result == null ? void 0 : result.pagination) ? { pagination: { limit: result.pagination.limit } } : {},
121
+ ...debug ? { debug: true } : {}
122
+ });
123
+ },
124
+ [debug, result == null ? void 0 : result.pagination, runRequest]
125
+ );
126
+ const rerunAt = useCallback(
127
+ async (pagination) => {
128
+ const previous = lastRun.current;
129
+ if (!previous) {
130
+ throw new Error(
131
+ "QueryBrowser: pagination changed before any query had run"
132
+ );
180
133
  }
181
- await runRequest({ ...previous, filters: selection });
134
+ await runRequest({
135
+ ...previous,
136
+ pagination,
137
+ ...debug ? { debug: true } : {}
138
+ });
182
139
  },
183
- [runRequest]
140
+ [debug, runRequest]
184
141
  );
185
142
  useEffect(() => {
186
143
  if (!lastRun.current) return;
@@ -196,13 +153,15 @@ function QueryBrowser({
196
153
  parent: editorHost.current,
197
154
  state: EditorState.create({
198
155
  doc: initialQuery,
199
- extensions: editorExtensions(
156
+ extensions: queryBrowserEditorExtensions(
200
157
  () => executeRef.current(),
201
158
  (query) => {
202
159
  var _a;
203
160
  return (_a = onQueryChangeRef.current) == null ? void 0 : _a.call(onQueryChangeRef, query);
204
161
  },
205
- languageConfig.current.of(languageExtension(language, completion))
162
+ languageConfig.current.of(
163
+ queryBrowserLanguageExtension(language, completion)
164
+ )
206
165
  )
207
166
  })
208
167
  });
@@ -217,7 +176,7 @@ function QueryBrowser({
217
176
  if (!view) return;
218
177
  view.dispatch({
219
178
  effects: languageConfig.current.reconfigure(
220
- languageExtension(language, completion)
179
+ queryBrowserLanguageExtension(language, completion)
221
180
  )
222
181
  });
223
182
  }, [completion, language]);
@@ -239,10 +198,11 @@ function QueryBrowser({
239
198
  [onOptionsChange]
240
199
  );
241
200
  useEffect(() => {
242
- setEntries(readHistory(id));
201
+ setEntries(readQueryBrowserHistory(id));
243
202
  setResult(null);
244
203
  setError(null);
245
204
  setFilters({});
205
+ setDebug(false);
246
206
  lastRun.current = null;
247
207
  executedFilters.current = {};
248
208
  }, [id]);
@@ -257,7 +217,9 @@ function QueryBrowser({
257
217
  return (request) => {
258
218
  const previous = lastRun.current;
259
219
  if (!previous) {
260
- throw new Error("QueryBrowser: a filter lookup ran before any query had");
220
+ throw new Error(
221
+ "QueryBrowser: a filter lookup ran before any query had"
222
+ );
261
223
  }
262
224
  return lookupFilterValues({ ...request, ...previous, filters });
263
225
  };
@@ -272,59 +234,53 @@ function QueryBrowser({
272
234
  [described, filters, lookupValues]
273
235
  );
274
236
  const serverFiltered = filterConfig.filters.length > 0 || filterConfig.timeRange !== void 0;
275
- const defaultResults = result ? /* @__PURE__ */ jsxs("div", { className: "flex min-h-0 flex-1 flex-col gap-2", children: [
276
- /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-3 text-xs text-muted-foreground", children: [
277
- /* @__PURE__ */ jsxs("span", { children: [
278
- rows.length.toLocaleString(),
279
- " rows",
280
- result.truncated ? "+" : ""
281
- ] }),
282
- result.truncated && /* @__PURE__ */ jsxs("span", { className: "text-amber-600 [[data-theme=dark]_&]:text-amber-400", children: [
283
- "stopped at the console's ",
284
- (result.limit ?? rows.length).toLocaleString(),
285
- "-row bound; narrow the query to see the rest"
286
- ] }),
287
- result.affectedRows !== void 0 && /* @__PURE__ */ jsxs("span", { children: [
288
- result.affectedRows.toLocaleString(),
289
- " affected"
290
- ] }),
291
- result.durationMs !== void 0 && /* @__PURE__ */ jsxs("span", { children: [
292
- Math.round(result.durationMs),
293
- " ms"
294
- ] }),
295
- result.message && /* @__PURE__ */ jsx("span", { children: result.message })
296
- ] }),
297
- rows.length > 0 || described.length > 0 ? /* @__PURE__ */ jsx(
298
- DataTable,
299
- {
300
- data: rows,
301
- columns,
302
- loading: pending,
303
- autoFilter: false,
304
- ...serverFiltered ? {
305
- manualFilter: true,
306
- externalFilters: filterConfig.filters,
307
- ...filterConfig.timeRange ? { externalTimeRange: filterConfig.timeRange } : {}
308
- } : { showGlobalFilter: true },
309
- showFullscreenControl: true,
310
- fullscreenTitle: title ?? queryLabel,
311
- detailStyle: "dialog",
312
- detailDialogTitle: "Row details",
313
- renderExpandedRow: (row) => /* @__PURE__ */ jsx(
314
- Properties,
315
- {
316
- items: Object.entries(row).map(([key, value]) => ({
317
- key,
318
- value
319
- })),
320
- renderLabel: (key) => key,
321
- density: "compact"
322
- }
323
- ),
324
- className: "min-h-0 flex-1"
325
- }
326
- ) : /* @__PURE__ */ jsx("div", { className: "rounded-md border border-dashed p-6 text-sm text-muted-foreground", children: result.message ?? "Statement completed with no rows." })
327
- ] }) : /* @__PURE__ */ jsx("div", { className: "grid min-h-40 place-items-center text-sm text-muted-foreground", children: "Run a query to see results." });
237
+ const tablePagination = useMemo(() => {
238
+ const pagination = result == null ? void 0 : result.pagination;
239
+ if (!pagination) return void 0;
240
+ const shared = {
241
+ pageSize: pagination.limit,
242
+ ...pagination.total !== void 0 ? { total: pagination.total } : {},
243
+ ...pagination.totalRelation === "eq" || pagination.totalRelation === "gte" ? { totalRelation: pagination.totalRelation } : {},
244
+ hasMore: pagination.hasMore,
245
+ onPageSizeChange: (limit) => void rerunAt({ limit })
246
+ };
247
+ if (pagination.mode === "cursor") {
248
+ return {
249
+ ...shared,
250
+ page: 0,
251
+ cursor: {
252
+ ...pagination.cursor ? { current: pagination.cursor } : {},
253
+ ...pagination.nextCursor ? { next: pagination.nextCursor } : {},
254
+ onCursorChange: (cursor) => void rerunAt({
255
+ limit: pagination.limit,
256
+ ...cursor ? { cursor } : {}
257
+ })
258
+ }
259
+ };
260
+ }
261
+ const page = Math.floor((pagination.offset ?? 0) / pagination.limit);
262
+ return {
263
+ ...shared,
264
+ page,
265
+ onPageChange: (nextPage) => void rerunAt({
266
+ limit: pagination.limit,
267
+ offset: nextPage * pagination.limit
268
+ })
269
+ };
270
+ }, [rerunAt, result == null ? void 0 : result.pagination]);
271
+ const defaultResults = /* @__PURE__ */ jsx(
272
+ QueryBrowserResults,
273
+ {
274
+ result,
275
+ pending,
276
+ ...title ? { title } : {},
277
+ queryLabel,
278
+ columns,
279
+ filterConfig,
280
+ serverFiltered,
281
+ ...tablePagination ? { pagination: tablePagination } : {}
282
+ }
283
+ );
328
284
  const workspace = /* @__PURE__ */ jsxs("div", { className: "flex h-full min-h-0 flex-col overflow-hidden rounded-xl border bg-card", children: [
329
285
  /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2 border-b px-3 py-2", children: [
330
286
  /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
@@ -352,6 +308,19 @@ function QueryBrowser({
352
308
  ]
353
309
  }
354
310
  ),
311
+ /* @__PURE__ */ jsxs(
312
+ Button,
313
+ {
314
+ size: "sm",
315
+ variant: debug ? "secondary" : "outline",
316
+ "aria-pressed": debug,
317
+ onClick: () => setDebug((enabled) => !enabled),
318
+ children: [
319
+ /* @__PURE__ */ jsx(Icon, { icon: UiDebug, className: "size-4" }),
320
+ "Debug"
321
+ ]
322
+ }
323
+ ),
355
324
  /* @__PURE__ */ jsxs(
356
325
  Button,
357
326
  {
@@ -379,18 +348,21 @@ function QueryBrowser({
379
348
  }
380
349
  ) }),
381
350
  /* @__PURE__ */ jsx("div", { ref: editorHost, className: "h-[34%] min-h-44 border-b" }),
382
- /* @__PURE__ */ jsx("div", { className: "flex min-h-0 flex-1 flex-col overflow-auto p-3", children: error ? /* @__PURE__ */ jsx(
383
- ErrorDetails,
384
- {
385
- diagnostics: {
386
- message: error,
387
- context: [
388
- ["Query", currentQuery()],
389
- ["Language", language]
390
- ]
351
+ /* @__PURE__ */ jsx("div", { className: "flex min-h-0 flex-1 flex-col overflow-auto p-3", children: error ? /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
352
+ /* @__PURE__ */ jsx(
353
+ ErrorDetails,
354
+ {
355
+ diagnostics: {
356
+ message: error.message,
357
+ context: [
358
+ ["Query", error.query],
359
+ ["Language", language]
360
+ ]
361
+ }
391
362
  }
392
- }
393
- ) : result && renderResults ? renderResults({ result, defaultView: defaultResults }) : defaultResults })
363
+ ),
364
+ error.diagnostics && /* @__PURE__ */ jsx(QueryBrowserDiagnosticsPanel, { diagnostics: error.diagnostics })
365
+ ] }) : result && renderResults ? renderResults({ result, defaultView: defaultResults }) : defaultResults })
394
366
  ] });
395
367
  return /* @__PURE__ */ jsx("div", { className: cn("h-[calc(100vh-15rem)] min-h-[32rem]", className), children: navigator ? /* @__PURE__ */ jsx(SplitPane, { defaultSplit: 28, left: navigator, right: workspace }) : workspace });
396
368
  }