@grafana/plugin-ui 0.14.0-dev.1 → 0.14.1-dsconfig.0d5c985

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 (111) hide show
  1. package/dist/cjs/index.cjs +2932 -377
  2. package/dist/cjs/index.cjs.map +1 -1
  3. package/dist/cjs/index.d.cts +564 -38
  4. package/dist/esm/components/ConfigEditor/ConfigSection/ConfigDescriptionLink.js +2 -2
  5. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/AuthorizationHeaderField.js +53 -0
  6. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/AuthorizationHeaderField.js.map +1 -0
  7. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/ComplexFieldNote.js +24 -0
  8. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/ComplexFieldNote.js.map +1 -0
  9. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/DatasourceConfigWizard.js +229 -0
  10. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/DatasourceConfigWizard.js.map +1 -0
  11. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/IndexedPairEditor.js +124 -0
  12. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/IndexedPairEditor.js.map +1 -0
  13. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/PdcFieldNote.js +34 -0
  14. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/PdcFieldNote.js.map +1 -0
  15. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/SchemaField.js +60 -0
  16. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/SchemaField.js.map +1 -0
  17. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/SecureFieldInput.js +61 -0
  18. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/SecureFieldInput.js.map +1 -0
  19. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/SidebarNav.js +54 -0
  20. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/SidebarNav.js.map +1 -0
  21. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/StringArrayInput.js +84 -0
  22. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/StringArrayInput.js.map +1 -0
  23. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/TabLayout.js +176 -0
  24. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/TabLayout.js.map +1 -0
  25. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/fieldUtils.js +88 -0
  26. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/fieldUtils.js.map +1 -0
  27. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/renderFieldInput.js +106 -0
  28. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/renderFieldInput.js.map +1 -0
  29. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/tabStyles.js +241 -0
  30. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/tabStyles.js.map +1 -0
  31. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/useDatasourceConfigForm.js +284 -0
  32. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/useDatasourceConfigForm.js.map +1 -0
  33. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/wizardStyles.js +124 -0
  34. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/wizardStyles.js.map +1 -0
  35. package/dist/esm/components/DataLinks/DataLink.js +2 -2
  36. package/dist/esm/components/DataLinks/DataLinks.js +2 -2
  37. package/dist/esm/components/DatePicker/styles.js +2 -2
  38. package/dist/esm/components/DatePickerWithInput/styles.js +2 -2
  39. package/dist/esm/components/QueryEditor/EditorField.js +2 -2
  40. package/dist/esm/components/QueryEditor/EditorHeader.js +2 -2
  41. package/dist/esm/components/QueryEditor/EditorRow.js +2 -2
  42. package/dist/esm/components/QueryEditor/EditorSwitch.js +2 -2
  43. package/dist/esm/components/QueryEditor/InlineSelect.js +1 -1
  44. package/dist/esm/components/QueryEditor/InlineSelect.js.map +1 -1
  45. package/dist/esm/components/QueryEditor/InputGroup.js +2 -2
  46. package/dist/esm/components/QueryEditor/QueryEditor.js +3 -1
  47. package/dist/esm/components/QueryEditor/QueryEditor.js.map +1 -1
  48. package/dist/esm/components/QueryEditor/QueryHeader.js +2 -2
  49. package/dist/esm/components/QueryEditor/QueryHeader.js.map +1 -1
  50. package/dist/esm/components/QueryEditor/Space.js +2 -2
  51. package/dist/esm/components/QueryEditor/TableSelector.js +0 -1
  52. package/dist/esm/components/QueryEditor/TableSelector.js.map +1 -1
  53. package/dist/esm/components/QueryEditor/defaults.js.map +1 -1
  54. package/dist/esm/components/QueryEditor/query-editor-raw/QueryEditorRaw.js +10 -2
  55. package/dist/esm/components/QueryEditor/query-editor-raw/QueryEditorRaw.js.map +1 -1
  56. package/dist/esm/components/QueryEditor/query-editor-raw/QueryToolbox.js +6 -1
  57. package/dist/esm/components/QueryEditor/query-editor-raw/QueryToolbox.js.map +1 -1
  58. package/dist/esm/components/QueryEditor/query-editor-raw/RawEditor.js +13 -3
  59. package/dist/esm/components/QueryEditor/query-editor-raw/RawEditor.js.map +1 -1
  60. package/dist/esm/components/QueryEditor/types.js +0 -1
  61. package/dist/esm/components/QueryEditor/types.js.map +1 -1
  62. package/dist/esm/components/QueryEditor/utils/formatSQL.js +15 -4
  63. package/dist/esm/components/QueryEditor/utils/formatSQL.js.map +1 -1
  64. package/dist/esm/components/QueryEditor/visual-query-builder/EditorField.js +2 -2
  65. package/dist/esm/components/QueryEditor/visual-query-builder/EditorRow.js +2 -2
  66. package/dist/esm/components/QueryEditor/visual-query-builder/Preview.js +4 -4
  67. package/dist/esm/components/QueryEditor/visual-query-builder/Preview.js.map +1 -1
  68. package/dist/esm/components/QueryEditor/visual-query-builder/SQLGroupByRow.js +0 -1
  69. package/dist/esm/components/QueryEditor/visual-query-builder/SQLGroupByRow.js.map +1 -1
  70. package/dist/esm/components/QueryEditor/visual-query-builder/SQLOrderByRow.js +0 -1
  71. package/dist/esm/components/QueryEditor/visual-query-builder/SQLOrderByRow.js.map +1 -1
  72. package/dist/esm/components/QueryEditor/visual-query-builder/SQLSelectRow.js +0 -1
  73. package/dist/esm/components/QueryEditor/visual-query-builder/SQLSelectRow.js.map +1 -1
  74. package/dist/esm/components/QueryEditor/visual-query-builder/SQLWhereRow.js +0 -1
  75. package/dist/esm/components/QueryEditor/visual-query-builder/SQLWhereRow.js.map +1 -1
  76. package/dist/esm/components/QueryEditor/visual-query-builder/SelectRow.js +2 -2
  77. package/dist/esm/components/QueryEditor/visual-query-builder/VisualEditor.js +10 -2
  78. package/dist/esm/components/QueryEditor/visual-query-builder/VisualEditor.js.map +1 -1
  79. package/dist/esm/components/SQLEditor/components/SQLEditor.js.map +1 -1
  80. package/dist/esm/components/SQLEditor/standardSql/definition.js +0 -6
  81. package/dist/esm/components/SQLEditor/standardSql/definition.js.map +1 -1
  82. package/dist/esm/components/SQLEditor/standardSql/getStatementPosition.js +2 -1
  83. package/dist/esm/components/SQLEditor/standardSql/getStatementPosition.js.map +1 -1
  84. package/dist/esm/components/SQLEditor/standardSql/statementPositionResolversRegistry.js +2 -1
  85. package/dist/esm/components/SQLEditor/standardSql/statementPositionResolversRegistry.js.map +1 -1
  86. package/dist/esm/components/SQLEditor/types.js +1 -17
  87. package/dist/esm/components/SQLEditor/types.js.map +1 -1
  88. package/dist/esm/components/SQLEditor/utils/LinkedToken.js +1 -1
  89. package/dist/esm/components/SQLEditor/utils/LinkedToken.js.map +1 -1
  90. package/dist/esm/components/SQLEditor/utils/linkedTokenBuilder.js +2 -2
  91. package/dist/esm/components/SQLEditor/utils/tokenType.js +18 -0
  92. package/dist/esm/components/SQLEditor/utils/tokenType.js.map +1 -0
  93. package/dist/esm/components/SQLEditor/utils/tokenUtils.js +1 -1
  94. package/dist/esm/components/VisualQueryBuilder/components/OperationEditorBody.js +1 -1
  95. package/dist/esm/components/VisualQueryBuilder/components/OperationList.js +1 -1
  96. package/dist/esm/components/VisualQueryBuilder/components/OperationParamEditor.js +1 -1
  97. package/dist/esm/components/VisualQueryBuilder/components/OperationsEditorRow.js +1 -1
  98. package/dist/esm/components/VisualQueryBuilder/components/QueryHeaderSwitch.js +1 -1
  99. package/dist/esm/components/VisualQueryBuilder/components/QueryOptionGroup.js +1 -1
  100. package/dist/esm/datasource/schema/config.js +235 -0
  101. package/dist/esm/datasource/schema/config.js.map +1 -0
  102. package/dist/esm/datasource/schema/datasource.js +228 -0
  103. package/dist/esm/datasource/schema/datasource.js.map +1 -0
  104. package/dist/esm/datasource/schema/llmHints.js +54 -0
  105. package/dist/esm/datasource/schema/llmHints.js.map +1 -0
  106. package/dist/esm/datasource/schema/provisioningYaml.js +358 -0
  107. package/dist/esm/datasource/schema/provisioningYaml.js.map +1 -0
  108. package/dist/esm/index.d.ts +564 -38
  109. package/dist/esm/index.js +7 -1
  110. package/dist/esm/index.js.map +1 -1
  111. package/package.json +30 -11
@@ -1 +1 @@
1
- {"version":3,"file":"QueryEditorRaw.js","sources":["../../../../../src/components/QueryEditor/query-editor-raw/QueryEditorRaw.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useRef } from 'react';\n\nimport { type SQLQuery } from '../types';\n\nimport { formatSQL } from '../utils/formatSQL';\nimport { type LanguageCompletionProvider, SQLEditor } from '../../SQLEditor';\n\ntype Props = {\n query: SQLQuery;\n onChange: (value: SQLQuery, processQuery: boolean) => void;\n children?: (props: { formatQuery: () => void }) => React.ReactNode;\n width?: number;\n height?: number;\n completionProvider: LanguageCompletionProvider;\n};\n\nexport function QueryEditorRaw({ children, onChange, query, width, height, completionProvider }: Props) {\n // We need to pass query via ref to SQLEditor as onChange is executed via monacoEditor.onDidChangeModelContent callback, not onChange property\n const queryRef = useRef<SQLQuery>(query);\n useEffect(() => {\n queryRef.current = query;\n }, [query]);\n\n const onRawQueryChange = useCallback(\n (rawSql: string, processQuery: boolean) => {\n const newQuery = {\n ...queryRef.current,\n rawQuery: true,\n rawSql,\n };\n onChange(newQuery, processQuery);\n },\n [onChange]\n );\n\n return (\n <SQLEditor\n width={width}\n height={height}\n query={query.rawSql!}\n onChange={onRawQueryChange}\n language={{ id: 'sql', completionProvider, formatter: formatSQL }}\n >\n {children}\n </SQLEditor>\n );\n}\n"],"names":[],"mappings":";;;;;;;;;AAgBO,SAAS,cAAA,CAAe,EAAE,QAAA,EAAU,QAAA,EAAU,OAAO,KAAA,EAAO,MAAA,EAAQ,oBAAmB,EAAU;AAEtG,EAAA,MAAM,QAAA,GAAW,OAAiB,KAAK,CAAA;AACvC,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,QAAA,CAAS,OAAA,GAAU,KAAA;AAAA,EACrB,CAAA,EAAG,CAAC,KAAK,CAAC,CAAA;AAEV,EAAA,MAAM,gBAAA,GAAmB,WAAA;AAAA,IACvB,CAAC,QAAgB,YAAA,KAA0B;AACzC,MAAA,MAAM,QAAA,GAAW;AAAA,QACf,GAAG,QAAA,CAAS,OAAA;AAAA,QACZ,QAAA,EAAU,IAAA;AAAA,QACV;AAAA,OACF;AACA,MAAA,QAAA,CAAS,UAAU,YAAY,CAAA;AAAA,IACjC,CAAA;AAAA,IACA,CAAC,QAAQ;AAAA,GACX;AAEA,EAAA,uBACE,KAAA,CAAA,aAAA;AAAA,IAAC,SAAA;AAAA,IAAA;AAAA,MACC,KAAA;AAAA,MACA,MAAA;AAAA,MACA,OAAO,KAAA,CAAM,MAAA;AAAA,MACb,QAAA,EAAU,gBAAA;AAAA,MACV,UAAU,EAAE,EAAA,EAAI,KAAA,EAAO,kBAAA,EAAoB,WAAW,SAAA;AAAU,KAAA;AAAA,IAE/D;AAAA,GACH;AAEJ;;;;"}
1
+ {"version":3,"file":"QueryEditorRaw.js","sources":["../../../../../src/components/QueryEditor/query-editor-raw/QueryEditorRaw.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useRef } from 'react';\n\nimport { type SQLQuery } from '../types';\n\nimport { formatSQL } from '../utils/formatSQL';\nimport { type LanguageCompletionProvider, SQLEditor } from '../../SQLEditor';\nimport type { SqlLanguage } from 'sql-formatter';\n\ntype Props = {\n query: SQLQuery;\n onChange: (value: SQLQuery, processQuery: boolean) => void;\n children?: (props: { formatQuery: () => void }) => React.ReactNode;\n width?: number;\n height?: number;\n completionProvider: LanguageCompletionProvider;\n language?: SqlLanguage;\n};\n\nexport function QueryEditorRaw({\n children,\n onChange,\n query,\n width,\n height,\n completionProvider,\n language = 'sql',\n}: Props) {\n // We need to pass query via ref to SQLEditor as onChange is executed via monacoEditor.onDidChangeModelContent callback, not onChange property\n const queryRef = useRef<SQLQuery>(query);\n useEffect(() => {\n queryRef.current = query;\n }, [query]);\n\n const onRawQueryChange = useCallback(\n (rawSql: string, processQuery: boolean) => {\n const newQuery = {\n ...queryRef.current,\n rawQuery: true,\n rawSql,\n };\n onChange(newQuery, processQuery);\n },\n [onChange]\n );\n\n return (\n <SQLEditor\n width={width}\n height={height}\n query={query.rawSql!}\n onChange={onRawQueryChange}\n language={{ id: 'sql', completionProvider, formatter: (q) => formatSQL(q, language) }}\n >\n {children}\n </SQLEditor>\n );\n}\n"],"names":[],"mappings":";;;;;;;;;AAkBO,SAAS,cAAA,CAAe;AAAA,EAC7B,QAAA;AAAA,EACA,QAAA;AAAA,EACA,KAAA;AAAA,EACA,KAAA;AAAA,EACA,MAAA;AAAA,EACA,kBAAA;AAAA,EACA,QAAA,GAAW;AACb,CAAA,EAAU;AAER,EAAA,MAAM,QAAA,GAAW,OAAiB,KAAK,CAAA;AACvC,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,QAAA,CAAS,OAAA,GAAU,KAAA;AAAA,EACrB,CAAA,EAAG,CAAC,KAAK,CAAC,CAAA;AAEV,EAAA,MAAM,gBAAA,GAAmB,WAAA;AAAA,IACvB,CAAC,QAAgB,YAAA,KAA0B;AACzC,MAAA,MAAM,QAAA,GAAW;AAAA,QACf,GAAG,QAAA,CAAS,OAAA;AAAA,QACZ,QAAA,EAAU,IAAA;AAAA,QACV;AAAA,OACF;AACA,MAAA,QAAA,CAAS,UAAU,YAAY,CAAA;AAAA,IACjC,CAAA;AAAA,IACA,CAAC,QAAQ;AAAA,GACX;AAEA,EAAA,uBACE,KAAA,CAAA,aAAA;AAAA,IAAC,SAAA;AAAA,IAAA;AAAA,MACC,KAAA;AAAA,MACA,MAAA;AAAA,MACA,OAAO,KAAA,CAAM,MAAA;AAAA,MACb,QAAA,EAAU,gBAAA;AAAA,MACV,QAAA,EAAU,EAAE,EAAA,EAAI,KAAA,EAAO,kBAAA,EAAoB,SAAA,EAAW,CAAC,CAAA,KAAM,SAAA,CAAU,CAAA,EAAG,QAAQ,CAAA;AAAE,KAAA;AAAA,IAEnF;AAAA,GACH;AAEJ;;;;"}
@@ -2,6 +2,7 @@ import { css } from '@emotion/css';
2
2
  import React, { useState, useMemo } from 'react';
3
3
  import { useTheme2, HorizontalGroup, IconButton, Tooltip, Icon } from '@grafana/ui';
4
4
  import { QueryValidator } from './QueryValidator.js';
5
+ import { reportInteraction } from '@grafana/runtime';
5
6
 
6
7
  function QueryToolbox({ showTools, onFormatCode, onExpand, isExpanded, ...validatorProps }) {
7
8
  const theme = useTheme2();
@@ -39,6 +40,10 @@ function QueryToolbox({ showTools, onFormatCode, onExpand, isExpanded, ...valida
39
40
  if (!showTools && validationResult === void 0) {
40
41
  style = { height: 0, padding: 0, visibility: "hidden" };
41
42
  }
43
+ const onFormatClick = () => {
44
+ reportInteraction("grafana_sql_query_editor_format_click");
45
+ onFormatCode == null ? void 0 : onFormatCode();
46
+ };
42
47
  return /* @__PURE__ */ React.createElement("div", { className: styles.container, style }, /* @__PURE__ */ React.createElement("div", null, validatorProps.onValidate && /* @__PURE__ */ React.createElement(
43
48
  QueryValidator,
44
49
  {
@@ -48,7 +53,7 @@ function QueryToolbox({ showTools, onFormatCode, onExpand, isExpanded, ...valida
48
53
  validatorProps.onValidate(result);
49
54
  }
50
55
  }
51
- )), showTools && /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement(HorizontalGroup, { spacing: "sm" }, onFormatCode && /* @__PURE__ */ React.createElement(IconButton, { onClick: onFormatCode, name: "brackets-curly", size: "xs", tooltip: "Format query" }), onExpand && /* @__PURE__ */ React.createElement(
56
+ )), showTools && /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement(HorizontalGroup, { spacing: "sm" }, onFormatCode && /* @__PURE__ */ React.createElement(IconButton, { onClick: onFormatClick, name: "brackets-curly", size: "xs", tooltip: "Format query" }), onExpand && /* @__PURE__ */ React.createElement(
52
57
  IconButton,
53
58
  {
54
59
  onClick: () => onExpand(!isExpanded),
@@ -1 +1 @@
1
- {"version":3,"file":"QueryToolbox.js","sources":["../../../../../src/components/QueryEditor/query-editor-raw/QueryToolbox.tsx"],"sourcesContent":["import { css } from '@emotion/css';\nimport React, { useMemo, useState } from 'react';\n\nimport { HorizontalGroup, Icon, IconButton, Tooltip, useTheme2 } from '@grafana/ui';\n\nimport { QueryValidator, type QueryValidatorProps } from './QueryValidator';\n\ninterface QueryToolboxProps extends Omit<QueryValidatorProps, 'onValidate'> {\n showTools?: boolean;\n isExpanded?: boolean;\n onFormatCode?: () => void;\n onExpand?: (expand: boolean) => void;\n onValidate?: (isValid: boolean) => void;\n}\n\nexport function QueryToolbox({ showTools, onFormatCode, onExpand, isExpanded, ...validatorProps }: QueryToolboxProps) {\n const theme = useTheme2();\n const [validationResult, setValidationResult] = useState<boolean>();\n\n const styles = useMemo(() => {\n return {\n container: css`\n border: 1px solid ${theme.colors.border.medium};\n border-top: none;\n padding: ${theme.spacing(0.5, 0.5, 0.5, 0.5)};\n display: flex;\n flex-grow: 1;\n justify-content: space-between;\n font-size: ${theme.typography.bodySmall.fontSize};\n `,\n error: css`\n color: ${theme.colors.error.text};\n font-size: ${theme.typography.bodySmall.fontSize};\n font-family: ${theme.typography.fontFamilyMonospace};\n `,\n valid: css`\n color: ${theme.colors.success.text};\n `,\n info: css`\n color: ${theme.colors.text.secondary};\n `,\n hint: css`\n color: ${theme.colors.text.disabled};\n white-space: nowrap;\n cursor: help;\n `,\n };\n }, [theme]);\n\n let style = {};\n\n if (!showTools && validationResult === undefined) {\n style = { height: 0, padding: 0, visibility: 'hidden' };\n }\n\n return (\n <div className={styles.container} style={style}>\n <div>\n {validatorProps.onValidate && (\n <QueryValidator\n {...validatorProps}\n onValidate={(result: boolean) => {\n setValidationResult(result);\n validatorProps.onValidate!(result);\n }}\n />\n )}\n </div>\n {showTools && (\n <div>\n <HorizontalGroup spacing=\"sm\">\n {onFormatCode && (\n <IconButton onClick={onFormatCode} name=\"brackets-curly\" size=\"xs\" tooltip=\"Format query\" />\n )}\n {onExpand && (\n <IconButton\n onClick={() => onExpand(!isExpanded)}\n name={isExpanded ? 'angle-up' : 'angle-down'}\n size=\"xs\"\n tooltip={isExpanded ? 'Collapse editor' : 'Expand editor'}\n />\n )}\n <Tooltip content=\"Hit CTRL/CMD+Return to run query\">\n <Icon className={styles.hint} name=\"keyboard\" />\n </Tooltip>\n </HorizontalGroup>\n </div>\n )}\n </div>\n );\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"QueryToolbox.js","sources":["../../../../../src/components/QueryEditor/query-editor-raw/QueryToolbox.tsx"],"sourcesContent":["import { css } from '@emotion/css';\nimport React, { useMemo, useState } from 'react';\n\nimport { HorizontalGroup, Icon, IconButton, Tooltip, useTheme2 } from '@grafana/ui';\n\nimport { QueryValidator, type QueryValidatorProps } from './QueryValidator';\nimport { reportInteraction } from '@grafana/runtime';\n\ninterface QueryToolboxProps extends Omit<QueryValidatorProps, 'onValidate'> {\n showTools?: boolean;\n isExpanded?: boolean;\n onFormatCode?: () => void;\n onExpand?: (expand: boolean) => void;\n onValidate?: (isValid: boolean) => void;\n}\n\nexport function QueryToolbox({ showTools, onFormatCode, onExpand, isExpanded, ...validatorProps }: QueryToolboxProps) {\n const theme = useTheme2();\n const [validationResult, setValidationResult] = useState<boolean>();\n\n const styles = useMemo(() => {\n return {\n container: css`\n border: 1px solid ${theme.colors.border.medium};\n border-top: none;\n padding: ${theme.spacing(0.5, 0.5, 0.5, 0.5)};\n display: flex;\n flex-grow: 1;\n justify-content: space-between;\n font-size: ${theme.typography.bodySmall.fontSize};\n `,\n error: css`\n color: ${theme.colors.error.text};\n font-size: ${theme.typography.bodySmall.fontSize};\n font-family: ${theme.typography.fontFamilyMonospace};\n `,\n valid: css`\n color: ${theme.colors.success.text};\n `,\n info: css`\n color: ${theme.colors.text.secondary};\n `,\n hint: css`\n color: ${theme.colors.text.disabled};\n white-space: nowrap;\n cursor: help;\n `,\n };\n }, [theme]);\n\n let style = {};\n\n if (!showTools && validationResult === undefined) {\n style = { height: 0, padding: 0, visibility: 'hidden' };\n }\n const onFormatClick = () => {\n reportInteraction('grafana_sql_query_editor_format_click');\n onFormatCode?.();\n };\n\n return (\n <div className={styles.container} style={style}>\n <div>\n {validatorProps.onValidate && (\n <QueryValidator\n {...validatorProps}\n onValidate={(result: boolean) => {\n setValidationResult(result);\n validatorProps.onValidate!(result);\n }}\n />\n )}\n </div>\n {showTools && (\n <div>\n <HorizontalGroup spacing=\"sm\">\n {onFormatCode && (\n <IconButton onClick={onFormatClick} name=\"brackets-curly\" size=\"xs\" tooltip=\"Format query\" />\n )}\n {onExpand && (\n <IconButton\n onClick={() => onExpand(!isExpanded)}\n name={isExpanded ? 'angle-up' : 'angle-down'}\n size=\"xs\"\n tooltip={isExpanded ? 'Collapse editor' : 'Expand editor'}\n />\n )}\n <Tooltip content=\"Hit CTRL/CMD+Return to run query\">\n <Icon className={styles.hint} name=\"keyboard\" />\n </Tooltip>\n </HorizontalGroup>\n </div>\n )}\n </div>\n );\n}\n"],"names":[],"mappings":"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"}
@@ -8,9 +8,18 @@ import { QueryEditorRaw } from './QueryEditorRaw.js';
8
8
  import { QueryToolbox } from './QueryToolbox.js';
9
9
  import '../types.js';
10
10
 
11
- function RawEditor({ db, query, onChange, onRunQuery, onValidate, queryToValidate, range }) {
11
+ function RawEditor({
12
+ db,
13
+ query,
14
+ onChange,
15
+ onRunQuery,
16
+ onValidate,
17
+ queryToValidate,
18
+ range,
19
+ language = "sql"
20
+ }) {
12
21
  const theme = useTheme2();
13
- const styles = useStyles2(getStyles$h);
22
+ const styles = useStyles2(getStyles$l);
14
23
  const [isExpanded, setIsExpanded] = useState(false);
15
24
  const [toolboxRef, toolboxMeasure] = useMeasure();
16
25
  const [editorRef, editorMeasure] = useMeasure();
@@ -22,6 +31,7 @@ function RawEditor({ db, query, onChange, onRunQuery, onValidate, queryToValidat
22
31
  completionProvider,
23
32
  query,
24
33
  width,
34
+ language,
25
35
  height: height ? height - toolboxMeasure.height : void 0,
26
36
  onChange
27
37
  },
@@ -79,7 +89,7 @@ function RawEditor({ db, query, onChange, onRunQuery, onValidate, queryToValidat
79
89
  renderEditor(true)
80
90
  ));
81
91
  }
82
- function getStyles$h(theme) {
92
+ function getStyles$l(theme) {
83
93
  return {
84
94
  modal: css`
85
95
  width: 95vw;
@@ -1 +1 @@
1
- {"version":3,"file":"RawEditor.js","sources":["../../../../../src/components/QueryEditor/query-editor-raw/RawEditor.tsx"],"sourcesContent":["import React, { useMemo, useState } from 'react';\nimport { css } from '@emotion/css';\nimport { useMeasure } from 'react-use';\n// @ts-ignore\nimport AutoSizer from 'react-virtualized-auto-sizer';\nimport { type GrafanaTheme2 } from '@grafana/data';\nimport { Modal, useStyles2, useTheme2 } from '@grafana/ui';\nimport { QueryEditorRaw } from './QueryEditorRaw';\nimport { QueryToolbox } from './QueryToolbox';\nimport { type QueryEditorProps, type SQLQuery } from '../types';\n\ninterface RawEditorProps extends Omit<QueryEditorProps, 'onChange'> {\n onRunQuery: () => void;\n onChange: (q: SQLQuery, processQuery: boolean) => void;\n onValidate: (isValid: boolean) => void;\n queryToValidate: SQLQuery;\n}\n\nexport function RawEditor({ db, query, onChange, onRunQuery, onValidate, queryToValidate, range }: RawEditorProps) {\n const theme = useTheme2();\n const styles = useStyles2(getStyles);\n const [isExpanded, setIsExpanded] = useState(false);\n const [toolboxRef, toolboxMeasure] = useMeasure<HTMLDivElement>();\n const [editorRef, editorMeasure] = useMeasure<HTMLDivElement>();\n\n const completionProvider = useMemo(() => db.getSqlCompletionProvider(), [db]);\n\n const renderQueryEditor = (width?: number, height?: number) => {\n return (\n <QueryEditorRaw\n completionProvider={completionProvider}\n query={query}\n width={width}\n height={height ? height - toolboxMeasure.height : undefined}\n onChange={onChange}\n >\n {({ formatQuery }) => {\n return (\n <div ref={toolboxRef}>\n <QueryToolbox\n db={db}\n query={queryToValidate}\n onValidate={onValidate}\n onFormatCode={formatQuery}\n showTools\n range={range}\n onExpand={setIsExpanded}\n isExpanded={isExpanded}\n />\n </div>\n );\n }}\n </QueryEditorRaw>\n );\n };\n\n interface AutoSizerProps {\n width: number;\n height: number;\n }\n\n const renderEditor = (standalone = false) => {\n return standalone ? (\n <AutoSizer>\n {({ width, height }: AutoSizerProps) => {\n return renderQueryEditor(width, height);\n }}\n </AutoSizer>\n ) : (\n <div ref={editorRef}>{renderQueryEditor()}</div>\n );\n };\n\n const renderPlaceholder = () => {\n return (\n <div\n style={{\n width: editorMeasure.width,\n height: editorMeasure.height,\n background: theme.colors.background.primary,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n }}\n >\n Editing in expanded code editor\n </div>\n );\n };\n\n return (\n <>\n {isExpanded ? renderPlaceholder() : renderEditor()}\n {isExpanded && (\n <Modal\n title={`Query ${query.refId}`}\n closeOnBackdropClick={false}\n closeOnEscape={false}\n className={styles.modal}\n contentClassName={styles.modalContent}\n isOpen={isExpanded}\n onDismiss={() => {\n setIsExpanded(false);\n }}\n >\n {renderEditor(true)}\n </Modal>\n )}\n </>\n );\n}\n\nfunction getStyles(theme: GrafanaTheme2) {\n return {\n modal: css`\n width: 95vw;\n height: 95vh;\n `,\n modalContent: css`\n height: 100%;\n padding-top: 0;\n `,\n };\n}\n"],"names":["getStyles"],"mappings":"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"}
1
+ {"version":3,"file":"RawEditor.js","sources":["../../../../../src/components/QueryEditor/query-editor-raw/RawEditor.tsx"],"sourcesContent":["import React, { useMemo, useState } from 'react';\nimport { css } from '@emotion/css';\nimport { useMeasure } from 'react-use';\n// @ts-ignore\nimport AutoSizer from 'react-virtualized-auto-sizer';\nimport { type GrafanaTheme2 } from '@grafana/data';\nimport { Modal, useStyles2, useTheme2 } from '@grafana/ui';\nimport { QueryEditorRaw } from './QueryEditorRaw';\nimport { QueryToolbox } from './QueryToolbox';\nimport { type QueryEditorProps, type SQLQuery } from '../types';\nimport type { SqlLanguage } from 'sql-formatter';\n\ninterface RawEditorProps extends Omit<QueryEditorProps, 'onChange'> {\n onRunQuery: () => void;\n onChange: (q: SQLQuery, processQuery: boolean) => void;\n onValidate: (isValid: boolean) => void;\n queryToValidate: SQLQuery;\n language?: SqlLanguage;\n}\n\nexport function RawEditor({\n db,\n query,\n onChange,\n onRunQuery,\n onValidate,\n queryToValidate,\n range,\n language = 'sql',\n}: RawEditorProps) {\n const theme = useTheme2();\n const styles = useStyles2(getStyles);\n const [isExpanded, setIsExpanded] = useState(false);\n const [toolboxRef, toolboxMeasure] = useMeasure<HTMLDivElement>();\n const [editorRef, editorMeasure] = useMeasure<HTMLDivElement>();\n\n const completionProvider = useMemo(() => db.getSqlCompletionProvider(), [db]);\n\n const renderQueryEditor = (width?: number, height?: number) => {\n return (\n <QueryEditorRaw\n completionProvider={completionProvider}\n query={query}\n width={width}\n language={language}\n height={height ? height - toolboxMeasure.height : undefined}\n onChange={onChange}\n >\n {({ formatQuery }) => {\n return (\n <div ref={toolboxRef}>\n <QueryToolbox\n db={db}\n query={queryToValidate}\n onValidate={onValidate}\n onFormatCode={formatQuery}\n showTools\n range={range}\n onExpand={setIsExpanded}\n isExpanded={isExpanded}\n />\n </div>\n );\n }}\n </QueryEditorRaw>\n );\n };\n\n interface AutoSizerProps {\n width: number;\n height: number;\n }\n\n const renderEditor = (standalone = false) => {\n return standalone ? (\n <AutoSizer>\n {({ width, height }: AutoSizerProps) => {\n return renderQueryEditor(width, height);\n }}\n </AutoSizer>\n ) : (\n <div ref={editorRef}>{renderQueryEditor()}</div>\n );\n };\n\n const renderPlaceholder = () => {\n return (\n <div\n style={{\n width: editorMeasure.width,\n height: editorMeasure.height,\n background: theme.colors.background.primary,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n }}\n >\n Editing in expanded code editor\n </div>\n );\n };\n\n return (\n <>\n {isExpanded ? renderPlaceholder() : renderEditor()}\n {isExpanded && (\n <Modal\n title={`Query ${query.refId}`}\n closeOnBackdropClick={false}\n closeOnEscape={false}\n className={styles.modal}\n contentClassName={styles.modalContent}\n isOpen={isExpanded}\n onDismiss={() => {\n setIsExpanded(false);\n }}\n >\n {renderEditor(true)}\n </Modal>\n )}\n </>\n );\n}\n\nfunction getStyles(theme: GrafanaTheme2) {\n return {\n modal: css`\n width: 95vw;\n height: 95vh;\n `,\n modalContent: css`\n height: 100%;\n padding-top: 0;\n `,\n };\n}\n"],"names":["getStyles"],"mappings":"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"}
@@ -1,6 +1,5 @@
1
1
  import '@react-awesome-query-builder/ui';
2
2
  import { toOption as toOption$1 } from '@grafana/data';
3
- import 'lodash';
4
3
  import '@grafana/ui';
5
4
  import 'react';
6
5
  import '../SQLEditor/standardSql/language.js';
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sources":["../../../../src/components/QueryEditor/types.ts"],"sourcesContent":["import { type JsonTree } from '@react-awesome-query-builder/ui';\n\nimport {\n type DataFrame,\n type DataSourceJsonData,\n type MetricFindValue,\n type SelectableValue,\n type TimeRange,\n toOption as toOptionFromData,\n} from '@grafana/data';\n\nimport { type DataQuery } from '@grafana/schema';\n\nimport { type QueryWithDefaults } from './defaults';\nimport {\n type QueryEditorFunctionExpression,\n type QueryEditorGroupByExpression,\n type QueryEditorPropertyExpression,\n} from './expressions';\nimport { type CompletionItemKind, type LanguageCompletionProvider } from '../SQLEditor';\n\nexport interface SqlQueryForInterpolation {\n dataset?: string;\n alias?: string;\n format?: QueryFormat;\n rawSql?: string;\n refId: string;\n hide?: boolean;\n}\n\nexport interface SQLConnectionLimits {\n maxOpenConns: number;\n maxIdleConns: number;\n connMaxLifetime: number;\n}\n\nexport interface SQLOptions extends SQLConnectionLimits, DataSourceJsonData {\n tlsAuth: boolean;\n tlsAuthWithCACert: boolean;\n timezone: string;\n tlsSkipVerify: boolean;\n user: string;\n database: string;\n url: string;\n timeInterval: string;\n}\n\n// Match the Enums Expected in SqlUtil and SqlDS\n// https://github.com/grafana/grafana-plugin-sdk-go/blob/main/data/sqlutil/query.go#L18-L29\nexport enum QueryFormat {\n Timeseries,\n Table,\n Logs,\n Trace,\n OptionMulti,\n}\n\nexport enum EditorMode {\n Builder = 'builder',\n Code = 'code',\n}\n\nexport interface SQLQuery extends DataQuery {\n alias?: string;\n format?: QueryFormat;\n rawSql?: string;\n dataset?: string; // When catalog is present, dataset represents the schema. Otherwise, it's the dataset.\n catalog?: string;\n table?: string;\n sql?: SQLExpression;\n editorMode?: EditorMode;\n rawQuery?: boolean;\n}\n\nexport interface NameValue {\n name: string;\n value: string;\n}\n\nexport type SQLFilters = NameValue[];\n\nexport interface SQLExpression {\n columns?: QueryEditorFunctionExpression[];\n whereJsonTree?: JsonTree;\n whereString?: string;\n filters?: SQLFilters;\n groupBy?: QueryEditorGroupByExpression[];\n orderBy?: QueryEditorPropertyExpression;\n orderByDirection?: 'ASC' | 'DESC';\n limit?: number;\n offset?: number;\n}\n\nexport interface TableSchema {\n name?: string;\n schema?: TableFieldSchema[];\n}\n\nexport interface TableFieldSchema {\n name: string;\n description?: string;\n type: string;\n repeated: boolean;\n schema: TableFieldSchema[];\n}\n\nexport interface QueryRowFilter {\n filter: boolean;\n group: boolean;\n order: boolean;\n preview: boolean;\n}\n\nexport const QUERY_FORMAT_OPTIONS = [\n { label: 'Time series', value: QueryFormat.Timeseries },\n { label: 'Table', value: QueryFormat.Table },\n];\n\nconst backWardToOption = (value: string) => ({ label: value, value });\n\nexport const toOption = toOptionFromData ?? backWardToOption;\n\nexport interface ResourceSelectorProps {\n disabled?: boolean;\n className?: string;\n applyDefault?: boolean;\n}\n// React Awesome Query builder field types.\n// These are responsible for rendering the correct UI for the field.\nexport type RAQBFieldTypes = 'text' | 'number' | 'boolean' | 'datetime' | 'date' | 'time';\n\nexport interface SQLSelectableValue extends SelectableValue {\n type?: string;\n raqbFieldType?: RAQBFieldTypes;\n}\n\nexport interface Aggregate {\n id: string;\n name: string;\n description?: string;\n}\n\nexport interface DB {\n init?: (datasourceId?: string) => Promise<boolean>;\n datasets: (catalog?: string) => Promise<string[]>; // When catalog is provided, returns schemas for that catalog\n catalogs?: () => Promise<string[]>;\n tables: (dataset?: string, catalog?: string, schema?: string) => Promise<string[]>;\n fields: (query: SQLQuery, order?: boolean) => Promise<SQLSelectableValue[]>;\n validateQuery: (query: SQLQuery, range?: TimeRange) => Promise<ValidationResults>;\n dsID: () => number;\n dispose?: (dsID?: string) => void;\n lookup: (path?: string) => Promise<Array<{ name: string; completion: string }>>;\n getSqlCompletionProvider: () => LanguageCompletionProvider;\n toRawSql?: (query: SQLQuery) => string;\n functions: () => Promise<Aggregate[]>;\n labels?: Map<'dataset', string>;\n disableDatasets?: boolean;\n disableCatalogs?: boolean;\n}\n\nexport interface QueryEditorProps {\n db: DB;\n query: QueryWithDefaults;\n onChange: (query: SQLQuery) => void;\n range?: TimeRange;\n}\n\nexport interface ValidationResults {\n query: SQLQuery;\n rawSql?: string;\n error: string;\n isError: boolean;\n isValid: boolean;\n statistics?: {\n TotalBytesProcessed: number;\n } | null;\n}\n\nexport interface SqlQueryModel {\n interpolate: () => string;\n quoteLiteral: (v: string) => string;\n}\n\nexport interface ResponseParser {\n transformMetricFindResponse: (frame: DataFrame) => MetricFindValue[];\n}\n\nexport interface MetaDefinition {\n name: string;\n completion?: string;\n kind: CompletionItemKind;\n}\n"],"names":["QueryFormat","EditorMode","toOptionFromData"],"mappings":";;;;;;;;;;;AAAA,IAAA,EAAA;AAiDO,IAAK,WAAA,qBAAAA,YAAAA,KAAL;AACL,EAAAA,YAAAA,CAAAA,YAAAA,CAAA,YAAA,CAAA,GAAA,CAAA,CAAA,GAAA,YAAA;AACA,EAAAA,YAAAA,CAAAA,YAAAA,CAAA,OAAA,CAAA,GAAA,CAAA,CAAA,GAAA,OAAA;AACA,EAAAA,YAAAA,CAAAA,YAAAA,CAAA,MAAA,CAAA,GAAA,CAAA,CAAA,GAAA,MAAA;AACA,EAAAA,YAAAA,CAAAA,YAAAA,CAAA,OAAA,CAAA,GAAA,CAAA,CAAA,GAAA,OAAA;AACA,EAAAA,YAAAA,CAAAA,YAAAA,CAAA,aAAA,CAAA,GAAA,CAAA,CAAA,GAAA,aAAA;AALU,EAAA,OAAAA,YAAAA;AAAA,CAAA,EAAA,WAAA,IAAA,EAAA;AAQL,IAAK,UAAA,qBAAAC,WAAAA,KAAL;AACL,EAAAA,YAAA,SAAA,CAAA,GAAU,SAAA;AACV,EAAAA,YAAA,MAAA,CAAA,GAAO,MAAA;AAFG,EAAA,OAAAA,WAAAA;AAAA,CAAA,EAAA,UAAA,IAAA,EAAA;AAwDL,MAAM,oBAAA,GAAuB;AAAA,EAClC,EAAE,KAAA,EAAO,aAAA,EAAe,KAAA,EAAO,CAAA,mBAAuB;AAAA,EACtD,EAAE,KAAA,EAAO,OAAA,EAAS,KAAA,EAAO,CAAA;AAC3B;AAEA,MAAM,mBAAmB,CAAC,KAAA,MAAmB,EAAE,KAAA,EAAO,OAAO,KAAA,EAAM,CAAA;AAE5D,MAAM,YAAW,EAAA,GAAAC,UAAA,KAAA,IAAA,GAAA,EAAA,GAAoB;;;;"}
1
+ {"version":3,"file":"types.js","sources":["../../../../src/components/QueryEditor/types.ts"],"sourcesContent":["import { type JsonTree } from '@react-awesome-query-builder/ui';\n\nimport {\n type DataFrame,\n type DataSourceJsonData,\n type MetricFindValue,\n type SelectableValue,\n type TimeRange,\n toOption as toOptionFromData,\n} from '@grafana/data';\n\nimport { type DataQuery } from '@grafana/schema';\n\nimport {\n type QueryEditorFunctionExpression,\n type QueryEditorGroupByExpression,\n type QueryEditorPropertyExpression,\n} from './expressions';\nimport { type CompletionItemKind, type LanguageCompletionProvider } from '../SQLEditor';\n\nexport interface SqlQueryForInterpolation {\n dataset?: string;\n alias?: string;\n format?: QueryFormat;\n rawSql?: string;\n refId: string;\n hide?: boolean;\n}\n\nexport interface SQLConnectionLimits {\n maxOpenConns: number;\n maxIdleConns: number;\n connMaxLifetime: number;\n}\n\nexport interface SQLOptions extends SQLConnectionLimits, DataSourceJsonData {\n tlsAuth: boolean;\n tlsAuthWithCACert: boolean;\n timezone: string;\n tlsSkipVerify: boolean;\n user: string;\n database: string;\n url: string;\n timeInterval: string;\n}\n\n// Match the Enums Expected in SqlUtil and SqlDS\n// https://github.com/grafana/grafana-plugin-sdk-go/blob/main/data/sqlutil/query.go#L18-L29\nexport enum QueryFormat {\n Timeseries,\n Table,\n Logs,\n Trace,\n OptionMulti,\n}\n\nexport enum EditorMode {\n Builder = 'builder',\n Code = 'code',\n}\n\nexport interface SQLQuery extends DataQuery {\n alias?: string;\n format?: QueryFormat;\n rawSql?: string;\n dataset?: string; // When catalog is present, dataset represents the schema. Otherwise, it's the dataset.\n catalog?: string;\n table?: string;\n sql?: SQLExpression;\n editorMode?: EditorMode;\n rawQuery?: boolean;\n}\n\nexport interface NameValue {\n name: string;\n value: string;\n}\n\nexport type SQLFilters = NameValue[];\n\nexport interface SQLExpression {\n columns?: QueryEditorFunctionExpression[];\n whereJsonTree?: JsonTree;\n whereString?: string;\n filters?: SQLFilters;\n groupBy?: QueryEditorGroupByExpression[];\n orderBy?: QueryEditorPropertyExpression;\n orderByDirection?: 'ASC' | 'DESC';\n limit?: number;\n offset?: number;\n}\n\nexport interface TableSchema {\n name?: string;\n schema?: TableFieldSchema[];\n}\n\nexport interface TableFieldSchema {\n name: string;\n description?: string;\n type: string;\n repeated: boolean;\n schema: TableFieldSchema[];\n}\n\nexport interface QueryRowFilter {\n filter: boolean;\n group: boolean;\n order: boolean;\n preview: boolean;\n}\n\nexport const QUERY_FORMAT_OPTIONS = [\n { label: 'Time series', value: QueryFormat.Timeseries },\n { label: 'Table', value: QueryFormat.Table },\n];\n\nconst backWardToOption = (value: string) => ({ label: value, value });\n\nexport const toOption = toOptionFromData ?? backWardToOption;\n\nexport interface ResourceSelectorProps {\n disabled?: boolean;\n className?: string;\n applyDefault?: boolean;\n}\n// React Awesome Query builder field types.\n// These are responsible for rendering the correct UI for the field.\nexport type RAQBFieldTypes = 'text' | 'number' | 'boolean' | 'datetime' | 'date' | 'time';\n\nexport interface SQLSelectableValue extends SelectableValue {\n type?: string;\n raqbFieldType?: RAQBFieldTypes;\n}\n\nexport interface Aggregate {\n id: string;\n name: string;\n description?: string;\n}\n\nexport interface DB {\n init?: (datasourceId?: string) => Promise<boolean>;\n datasets: (catalog?: string) => Promise<string[]>; // When catalog is provided, returns schemas for that catalog\n catalogs?: () => Promise<string[]>;\n tables: (dataset?: string, catalog?: string, schema?: string) => Promise<string[]>;\n fields: (query: SQLQuery, order?: boolean) => Promise<SQLSelectableValue[]>;\n validateQuery: (query: SQLQuery, range?: TimeRange) => Promise<ValidationResults>;\n dsID: () => number;\n dispose?: (dsID?: string) => void;\n lookup: (path?: string) => Promise<Array<{ name: string; completion: string }>>;\n getSqlCompletionProvider: () => LanguageCompletionProvider;\n toRawSql?: (query: SQLQuery) => string;\n functions: () => Promise<Aggregate[]>;\n labels?: Map<'dataset', string>;\n disableDatasets?: boolean;\n disableCatalogs?: boolean;\n}\n\nexport interface QueryEditorProps {\n db: DB;\n query: QueryWithDefaults;\n onChange: (query: SQLQuery) => void;\n range?: TimeRange;\n}\n\nexport interface ValidationResults {\n query: SQLQuery;\n rawSql?: string;\n error: string;\n isError: boolean;\n isValid: boolean;\n statistics?: {\n TotalBytesProcessed: number;\n } | null;\n}\n\nexport interface SqlQueryModel {\n interpolate: () => string;\n quoteLiteral: (v: string) => string;\n}\n\nexport interface ResponseParser {\n transformMetricFindResponse: (frame: DataFrame) => MetricFindValue[];\n}\n\nexport interface MetaDefinition {\n name: string;\n completion?: string;\n kind: CompletionItemKind;\n}\n\n/**\n * Represents a query with all default values applied.\n * This is equivalent to SQLQuery since applyQueryDefaults returns SQLQuery.\n */\nexport type QueryWithDefaults = SQLQuery;\n"],"names":["QueryFormat","EditorMode","toOptionFromData"],"mappings":";;;;;;;;;;AAAA,IAAA,EAAA;AAgDO,IAAK,WAAA,qBAAAA,YAAAA,KAAL;AACL,EAAAA,YAAAA,CAAAA,YAAAA,CAAA,YAAA,CAAA,GAAA,CAAA,CAAA,GAAA,YAAA;AACA,EAAAA,YAAAA,CAAAA,YAAAA,CAAA,OAAA,CAAA,GAAA,CAAA,CAAA,GAAA,OAAA;AACA,EAAAA,YAAAA,CAAAA,YAAAA,CAAA,MAAA,CAAA,GAAA,CAAA,CAAA,GAAA,MAAA;AACA,EAAAA,YAAAA,CAAAA,YAAAA,CAAA,OAAA,CAAA,GAAA,CAAA,CAAA,GAAA,OAAA;AACA,EAAAA,YAAAA,CAAAA,YAAAA,CAAA,aAAA,CAAA,GAAA,CAAA,CAAA,GAAA,aAAA;AALU,EAAA,OAAAA,YAAAA;AAAA,CAAA,EAAA,WAAA,IAAA,EAAA;AAQL,IAAK,UAAA,qBAAAC,WAAAA,KAAL;AACL,EAAAA,YAAA,SAAA,CAAA,GAAU,SAAA;AACV,EAAAA,YAAA,MAAA,CAAA,GAAO,MAAA;AAFG,EAAA,OAAAA,WAAAA;AAAA,CAAA,EAAA,UAAA,IAAA,EAAA;AAwDL,MAAM,oBAAA,GAAuB;AAAA,EAClC,EAAE,KAAA,EAAO,aAAA,EAAe,KAAA,EAAO,CAAA,mBAAuB;AAAA,EACtD,EAAE,KAAA,EAAO,OAAA,EAAS,KAAA,EAAO,CAAA;AAC3B;AAEA,MAAM,mBAAmB,CAAC,KAAA,MAAmB,EAAE,KAAA,EAAO,OAAO,KAAA,EAAM,CAAA;AAE5D,MAAM,YAAW,EAAA,GAAAC,UAAA,KAAA,IAAA,GAAA,EAAA,GAAoB;;;;"}
@@ -1,9 +1,20 @@
1
- import sqlFormatter from 'sql-formatter-plus';
1
+ import { format } from 'sql-formatter';
2
2
 
3
- function formatSQL(q) {
4
- return sqlFormatter.format(q).replace(/(\$ \{ .* \})|(\$ __)|(\$ \w+)/g, (m) => {
5
- return m.replace(/\s/g, "");
3
+ function formatSQL(q, language = "sql") {
4
+ const formatted = format(q, {
5
+ language,
6
+ paramTypes: {
7
+ custom: [
8
+ {
9
+ regex: "\\$\\s*\\{[^}]*\\}|\\$\\s*__\\w+(?:\\([^)]*\\))?|\\$\\s*\\w+"
10
+ }
11
+ ]
12
+ }
6
13
  });
14
+ return formatted.replace(
15
+ /(\$\s*\{[^}]*\})|(\$\s*__\w+(?:\([^)]*\))?)|(\$\s*\w+)/g,
16
+ (m) => m.replace(/\s/g, "")
17
+ );
7
18
  }
8
19
 
9
20
  export { formatSQL };
@@ -1 +1 @@
1
- {"version":3,"file":"formatSQL.js","sources":["../../../../../src/components/QueryEditor/utils/formatSQL.ts"],"sourcesContent":["// @ts-ignore\nimport sqlFormatter from 'sql-formatter-plus';\n\nexport function formatSQL(q: string) {\n return sqlFormatter.format(q).replace(/(\\$ \\{ .* \\})|(\\$ __)|(\\$ \\w+)/g, (m: string) => {\n return m.replace(/\\s/g, '');\n });\n}\n"],"names":[],"mappings":";;AAGO,SAAS,UAAU,CAAA,EAAW;AACnC,EAAA,OAAO,aAAa,MAAA,CAAO,CAAC,EAAE,OAAA,CAAQ,iCAAA,EAAmC,CAAC,CAAA,KAAc;AACtF,IAAA,OAAO,CAAA,CAAE,OAAA,CAAQ,KAAA,EAAO,EAAE,CAAA;AAAA,EAC5B,CAAC,CAAA;AACH;;;;"}
1
+ {"version":3,"file":"formatSQL.js","sources":["../../../../../src/components/QueryEditor/utils/formatSQL.ts"],"sourcesContent":["import { format, type SqlLanguage } from 'sql-formatter';\n\n/**\n * Format SQL while preserving Grafana template variable tokens.\n * Treats `${...}`, `$__...`, and `$var` as parameters so the\n * formatter does not split or reflow them, then normalizes any\n * whitespace inside those tokens.\n */\nexport function formatSQL(q: string, language: SqlLanguage = 'sql') {\n const formatted = format(q, {\n language,\n paramTypes: {\n custom: [\n {\n regex: '\\\\$\\\\s*\\\\{[^}]*\\\\}|\\\\$\\\\s*__\\\\w+(?:\\\\([^)]*\\\\))?|\\\\$\\\\s*\\\\w+',\n },\n ],\n },\n });\n return formatted.replace(/(\\$\\s*\\{[^}]*\\})|(\\$\\s*__\\w+(?:\\([^)]*\\))?)|(\\$\\s*\\w+)/g, (m: string) =>\n m.replace(/\\s/g, '')\n );\n}\n"],"names":[],"mappings":";;AAQO,SAAS,SAAA,CAAU,CAAA,EAAW,QAAA,GAAwB,KAAA,EAAO;AAClE,EAAA,MAAM,SAAA,GAAY,OAAO,CAAA,EAAG;AAAA,IAC1B,QAAA;AAAA,IACA,UAAA,EAAY;AAAA,MACV,MAAA,EAAQ;AAAA,QACN;AAAA,UACE,KAAA,EAAO;AAAA;AACT;AACF;AACF,GACD,CAAA;AACD,EAAA,OAAO,SAAA,CAAU,OAAA;AAAA,IAAQ,yDAAA;AAAA,IAA2D,CAAC,CAAA,KACnF,CAAA,CAAE,OAAA,CAAQ,OAAO,EAAE;AAAA,GACrB;AACF;;;;"}
@@ -8,12 +8,12 @@ const EditorField = (props) => {
8
8
  var _a;
9
9
  const { label, optional, tooltip, children, width, ...fieldProps } = props;
10
10
  const theme = useTheme2();
11
- const styles = getStyles$d(theme, width);
11
+ const styles = getStyles$h(theme, width);
12
12
  const childInputId = (fieldProps == null ? void 0 : fieldProps.htmlFor) || ((_a = ReactUtils) == null ? void 0 : _a.getChildId(children));
13
13
  const labelEl = /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("label", { className: styles.label, htmlFor: childInputId }, label, optional && /* @__PURE__ */ React.createElement("span", { className: styles.optional }, " - optional"), tooltip && /* @__PURE__ */ React.createElement(Tooltip, { placement: "top", content: tooltip, theme: "info" }, /* @__PURE__ */ React.createElement(Icon, { name: "info-circle", size: "sm", className: styles.icon }))), /* @__PURE__ */ React.createElement(Space, { v: 0.5 }));
14
14
  return /* @__PURE__ */ React.createElement("div", { className: styles.root }, /* @__PURE__ */ React.createElement(Field, { className: styles.field, label: labelEl, ...fieldProps }, children));
15
15
  };
16
- const getStyles$d = stylesFactory((theme, width) => {
16
+ const getStyles$h = stylesFactory((theme, width) => {
17
17
  return {
18
18
  root: css({
19
19
  minWidth: theme.spacing(width != null ? width : 0)
@@ -5,10 +5,10 @@ import { useStyles2 } from '@grafana/ui';
5
5
  import { EditorStack } from '../EditorStack.js';
6
6
 
7
7
  const EditorRow = ({ children }) => {
8
- const styles = useStyles2(getStyles$e);
8
+ const styles = useStyles2(getStyles$i);
9
9
  return /* @__PURE__ */ React.createElement("div", { className: styles.root }, /* @__PURE__ */ React.createElement(EditorStack, { gap: 2 }, children));
10
10
  };
11
- const getStyles$e = (theme) => {
11
+ const getStyles$i = (theme) => {
12
12
  return {
13
13
  root: css({
14
14
  padding: theme.spacing(1),
@@ -5,23 +5,23 @@ import '@grafana/data';
5
5
  import { useStyles2, IconButton, Field, CodeEditor } from '@grafana/ui';
6
6
  import { formatSQL } from '../utils/formatSQL.js';
7
7
 
8
- function Preview({ rawSql }) {
8
+ function Preview({ rawSql, language = "sql" }) {
9
9
  const [_, copyToClipboard] = useCopyToClipboard();
10
- const styles = useStyles2(getStyles$g);
10
+ const styles = useStyles2(getStyles$k);
11
11
  const labelElement = /* @__PURE__ */ React.createElement("div", { className: styles.labelWrapper }, /* @__PURE__ */ React.createElement("label", { className: styles.label }, "Preview"), /* @__PURE__ */ React.createElement(IconButton, { tooltip: "Copy to clipboard", onClick: () => copyToClipboard(rawSql), name: "copy" }));
12
12
  return /* @__PURE__ */ React.createElement(Field, { label: labelElement, className: styles.grow }, /* @__PURE__ */ React.createElement(
13
13
  CodeEditor,
14
14
  {
15
15
  language: "sql",
16
16
  height: 80,
17
- value: formatSQL(rawSql),
17
+ value: formatSQL(rawSql, language),
18
18
  monacoOptions: { scrollbar: { vertical: "hidden" }, scrollBeyondLastLine: false },
19
19
  readOnly: true,
20
20
  showMiniMap: false
21
21
  }
22
22
  ));
23
23
  }
24
- function getStyles$g(theme) {
24
+ function getStyles$k(theme) {
25
25
  return {
26
26
  grow: css({ flexGrow: 1 }),
27
27
  label: css({ fontSize: 12, fontWeight: theme.typography.fontWeightMedium }),
@@ -1 +1 @@
1
- {"version":3,"file":"Preview.js","sources":["../../../../../src/components/QueryEditor/visual-query-builder/Preview.tsx"],"sourcesContent":["import React from 'react';\nimport { css } from '@emotion/css';\nimport { useCopyToClipboard } from 'react-use';\n\nimport { type GrafanaTheme2 } from '@grafana/data';\nimport { CodeEditor, Field, IconButton, useStyles2 } from '@grafana/ui';\n\nimport { formatSQL } from '../utils/formatSQL';\n\ntype PreviewProps = {\n rawSql: string;\n};\n\nexport function Preview({ rawSql }: PreviewProps) {\n // TODO: use zero index to give feedback about copy success\n const [_, copyToClipboard] = useCopyToClipboard();\n const styles = useStyles2(getStyles);\n\n const labelElement = (\n <div className={styles.labelWrapper}>\n <label className={styles.label}>Preview</label>\n <IconButton tooltip=\"Copy to clipboard\" onClick={() => copyToClipboard(rawSql)} name=\"copy\" />\n </div>\n );\n\n return (\n <Field label={labelElement} className={styles.grow}>\n <CodeEditor\n language=\"sql\"\n height={80}\n value={formatSQL(rawSql)}\n monacoOptions={{ scrollbar: { vertical: 'hidden' }, scrollBeyondLastLine: false }}\n readOnly={true}\n showMiniMap={false}\n />\n </Field>\n );\n}\n\nfunction getStyles(theme: GrafanaTheme2) {\n return {\n grow: css({ flexGrow: 1 }),\n label: css({ fontSize: 12, fontWeight: theme.typography.fontWeightMedium }),\n labelWrapper: css({ display: 'flex', justifyContent: 'space-between', paddingBottom: theme.spacing(0.5) }),\n };\n}\n"],"names":["getStyles"],"mappings":";;;;;;;AAaO,SAAS,OAAA,CAAQ,EAAE,MAAA,EAAO,EAAiB;AAEhD,EAAA,MAAM,CAAC,CAAA,EAAG,eAAe,CAAA,GAAI,kBAAA,EAAmB;AAChD,EAAA,MAAM,MAAA,GAAS,WAAWA,WAAS,CAAA;AAEnC,EAAA,MAAM,YAAA,mBACJ,KAAA,CAAA,aAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,MAAA,CAAO,gCACrB,KAAA,CAAA,aAAA,CAAC,OAAA,EAAA,EAAM,SAAA,EAAW,MAAA,CAAO,KAAA,EAAA,EAAO,SAAO,mBACvC,KAAA,CAAA,aAAA,CAAC,UAAA,EAAA,EAAW,OAAA,EAAQ,mBAAA,EAAoB,OAAA,EAAS,MAAM,gBAAgB,MAAM,CAAA,EAAG,IAAA,EAAK,MAAA,EAAO,CAC9F,CAAA;AAGF,EAAA,2CACG,KAAA,EAAA,EAAM,KAAA,EAAO,YAAA,EAAc,SAAA,EAAW,OAAO,IAAA,EAAA,kBAC5C,KAAA,CAAA,aAAA;AAAA,IAAC,UAAA;AAAA,IAAA;AAAA,MACC,QAAA,EAAS,KAAA;AAAA,MACT,MAAA,EAAQ,EAAA;AAAA,MACR,KAAA,EAAO,UAAU,MAAM,CAAA;AAAA,MACvB,aAAA,EAAe,EAAE,SAAA,EAAW,EAAE,UAAU,QAAA,EAAS,EAAG,sBAAsB,KAAA,EAAM;AAAA,MAChF,QAAA,EAAU,IAAA;AAAA,MACV,WAAA,EAAa;AAAA;AAAA,GAEjB,CAAA;AAEJ;AAEA,SAASA,YAAU,KAAA,EAAsB;AACvC,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,GAAA,CAAI,EAAE,QAAA,EAAU,GAAG,CAAA;AAAA,IACzB,KAAA,EAAO,IAAI,EAAE,QAAA,EAAU,IAAI,UAAA,EAAY,KAAA,CAAM,UAAA,CAAW,gBAAA,EAAkB,CAAA;AAAA,IAC1E,YAAA,EAAc,GAAA,CAAI,EAAE,OAAA,EAAS,MAAA,EAAQ,cAAA,EAAgB,eAAA,EAAiB,aAAA,EAAe,KAAA,CAAM,OAAA,CAAQ,GAAG,CAAA,EAAG;AAAA,GAC3G;AACF;;;;"}
1
+ {"version":3,"file":"Preview.js","sources":["../../../../../src/components/QueryEditor/visual-query-builder/Preview.tsx"],"sourcesContent":["import React from 'react';\nimport { css } from '@emotion/css';\nimport { useCopyToClipboard } from 'react-use';\n\nimport { type GrafanaTheme2 } from '@grafana/data';\nimport { CodeEditor, Field, IconButton, useStyles2 } from '@grafana/ui';\n\nimport { formatSQL } from '../utils/formatSQL';\nimport type { SqlLanguage } from 'sql-formatter';\n\ntype PreviewProps = {\n rawSql: string;\n language?: SqlLanguage;\n};\n\nexport function Preview({ rawSql, language = 'sql' }: PreviewProps) {\n // TODO: use zero index to give feedback about copy success\n const [_, copyToClipboard] = useCopyToClipboard();\n const styles = useStyles2(getStyles);\n\n const labelElement = (\n <div className={styles.labelWrapper}>\n <label className={styles.label}>Preview</label>\n <IconButton tooltip=\"Copy to clipboard\" onClick={() => copyToClipboard(rawSql)} name=\"copy\" />\n </div>\n );\n\n return (\n <Field label={labelElement} className={styles.grow}>\n <CodeEditor\n language=\"sql\"\n height={80}\n value={formatSQL(rawSql, language)}\n monacoOptions={{ scrollbar: { vertical: 'hidden' }, scrollBeyondLastLine: false }}\n readOnly={true}\n showMiniMap={false}\n />\n </Field>\n );\n}\n\nfunction getStyles(theme: GrafanaTheme2) {\n return {\n grow: css({ flexGrow: 1 }),\n label: css({ fontSize: 12, fontWeight: theme.typography.fontWeightMedium }),\n labelWrapper: css({ display: 'flex', justifyContent: 'space-between', paddingBottom: theme.spacing(0.5) }),\n };\n}\n"],"names":["getStyles"],"mappings":";;;;;;;AAeO,SAAS,OAAA,CAAQ,EAAE,MAAA,EAAQ,QAAA,GAAW,OAAM,EAAiB;AAElE,EAAA,MAAM,CAAC,CAAA,EAAG,eAAe,CAAA,GAAI,kBAAA,EAAmB;AAChD,EAAA,MAAM,MAAA,GAAS,WAAWA,WAAS,CAAA;AAEnC,EAAA,MAAM,YAAA,mBACJ,KAAA,CAAA,aAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,MAAA,CAAO,gCACrB,KAAA,CAAA,aAAA,CAAC,OAAA,EAAA,EAAM,SAAA,EAAW,MAAA,CAAO,KAAA,EAAA,EAAO,SAAO,mBACvC,KAAA,CAAA,aAAA,CAAC,UAAA,EAAA,EAAW,OAAA,EAAQ,mBAAA,EAAoB,OAAA,EAAS,MAAM,gBAAgB,MAAM,CAAA,EAAG,IAAA,EAAK,MAAA,EAAO,CAC9F,CAAA;AAGF,EAAA,2CACG,KAAA,EAAA,EAAM,KAAA,EAAO,YAAA,EAAc,SAAA,EAAW,OAAO,IAAA,EAAA,kBAC5C,KAAA,CAAA,aAAA;AAAA,IAAC,UAAA;AAAA,IAAA;AAAA,MACC,QAAA,EAAS,KAAA;AAAA,MACT,MAAA,EAAQ,EAAA;AAAA,MACR,KAAA,EAAO,SAAA,CAAU,MAAA,EAAQ,QAAQ,CAAA;AAAA,MACjC,aAAA,EAAe,EAAE,SAAA,EAAW,EAAE,UAAU,QAAA,EAAS,EAAG,sBAAsB,KAAA,EAAM;AAAA,MAChF,QAAA,EAAU,IAAA;AAAA,MACV,WAAA,EAAa;AAAA;AAAA,GAEjB,CAAA;AAEJ;AAEA,SAASA,YAAU,KAAA,EAAsB;AACvC,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,GAAA,CAAI,EAAE,QAAA,EAAU,GAAG,CAAA;AAAA,IACzB,KAAA,EAAO,IAAI,EAAE,QAAA,EAAU,IAAI,UAAA,EAAY,KAAA,CAAM,UAAA,CAAW,gBAAA,EAAkB,CAAA;AAAA,IAC1E,YAAA,EAAc,GAAA,CAAI,EAAE,OAAA,EAAS,MAAA,EAAQ,cAAA,EAAgB,eAAA,EAAiB,aAAA,EAAe,KAAA,CAAM,OAAA,CAAQ,GAAG,CAAA,EAAG;AAAA,GAC3G;AACF;;;;"}
@@ -2,7 +2,6 @@ import React from 'react';
2
2
  import '@grafana/data';
3
3
  import { GroupByRow } from './GroupByRow.js';
4
4
  import '../types.js';
5
- import 'lodash';
6
5
  import { useSqlChange } from '../utils/useSqlChange.js';
7
6
 
8
7
  function SQLGroupByRow({ fields, query, onQueryChange, db }) {
@@ -1 +1 @@
1
- {"version":3,"file":"SQLGroupByRow.js","sources":["../../../../../src/components/QueryEditor/visual-query-builder/SQLGroupByRow.tsx"],"sourcesContent":["import React from 'react';\nimport { type SelectableValue } from '@grafana/data';\n\nimport { GroupByRow } from './GroupByRow';\nimport { type QueryWithDefaults } from '../defaults';\nimport { type SQLQuery, type DB } from '../types';\nimport { useSqlChange } from '../utils/useSqlChange';\n\ninterface SQLGroupByRowProps {\n fields: SelectableValue[];\n query: QueryWithDefaults;\n onQueryChange: (query: SQLQuery) => void;\n db: DB;\n}\n\nexport function SQLGroupByRow({ fields, query, onQueryChange, db }: SQLGroupByRowProps) {\n const { onSqlChange } = useSqlChange({ query, onQueryChange, db });\n\n return <GroupByRow columns={fields} sql={query.sql!} onSqlChange={onSqlChange} />;\n}\n"],"names":[],"mappings":";;;;;;;AAeO,SAAS,cAAc,EAAE,MAAA,EAAQ,KAAA,EAAO,aAAA,EAAe,IAAG,EAAuB;AACtF,EAAA,MAAM,EAAE,aAAY,GAAI,YAAA,CAAa,EAAE,KAAA,EAAO,aAAA,EAAe,IAAI,CAAA;AAEjE,EAAA,2CAAQ,UAAA,EAAA,EAAW,OAAA,EAAS,QAAQ,GAAA,EAAK,KAAA,CAAM,KAAM,WAAA,EAA0B,CAAA;AACjF;;;;"}
1
+ {"version":3,"file":"SQLGroupByRow.js","sources":["../../../../../src/components/QueryEditor/visual-query-builder/SQLGroupByRow.tsx"],"sourcesContent":["import React from 'react';\nimport { type SelectableValue } from '@grafana/data';\n\nimport { GroupByRow } from './GroupByRow';\nimport { type SQLQuery, type DB, type QueryWithDefaults } from '../types';\nimport { useSqlChange } from '../utils/useSqlChange';\n\ninterface SQLGroupByRowProps {\n fields: SelectableValue[];\n query: QueryWithDefaults;\n onQueryChange: (query: SQLQuery) => void;\n db: DB;\n}\n\nexport function SQLGroupByRow({ fields, query, onQueryChange, db }: SQLGroupByRowProps) {\n const { onSqlChange } = useSqlChange({ query, onQueryChange, db });\n\n return <GroupByRow columns={fields} sql={query.sql!} onSqlChange={onSqlChange} />;\n}\n"],"names":[],"mappings":";;;;;;AAcO,SAAS,cAAc,EAAE,MAAA,EAAQ,KAAA,EAAO,aAAA,EAAe,IAAG,EAAuB;AACtF,EAAA,MAAM,EAAE,aAAY,GAAI,YAAA,CAAa,EAAE,KAAA,EAAO,aAAA,EAAe,IAAI,CAAA;AAEjE,EAAA,2CAAQ,UAAA,EAAA,EAAW,OAAA,EAAS,QAAQ,GAAA,EAAK,KAAA,CAAM,KAAM,WAAA,EAA0B,CAAA;AACjF;;;;"}
@@ -2,7 +2,6 @@ import React from 'react';
2
2
  import '@grafana/data';
3
3
  import { OrderByRow } from './OrderByRow.js';
4
4
  import '../types.js';
5
- import 'lodash';
6
5
  import { useSqlChange } from '../utils/useSqlChange.js';
7
6
 
8
7
  function SQLOrderByRow({ fields, query, onQueryChange, db }) {
@@ -1 +1 @@
1
- {"version":3,"file":"SQLOrderByRow.js","sources":["../../../../../src/components/QueryEditor/visual-query-builder/SQLOrderByRow.tsx"],"sourcesContent":["import React from 'react';\nimport { type SelectableValue } from '@grafana/data';\nimport { OrderByRow } from './OrderByRow';\nimport { type QueryWithDefaults } from '../defaults';\nimport { type SQLQuery, type DB } from '../types';\nimport { useSqlChange } from '../utils/useSqlChange';\n\ntype SQLOrderByRowProps = {\n fields: SelectableValue[];\n query: QueryWithDefaults;\n onQueryChange: (query: SQLQuery) => void;\n db: DB;\n};\n\nexport function SQLOrderByRow({ fields, query, onQueryChange, db }: SQLOrderByRowProps) {\n const { onSqlChange } = useSqlChange({ query, onQueryChange, db });\n let columnsWithIndices: SelectableValue[] = [];\n\n if (fields) {\n const options = query.sql?.columns?.map((c, i) => {\n const value = c.name ? `${c.name}(${c.parameters?.map((p) => p.name)})` : c.parameters?.map((p) => p.name);\n return {\n value,\n label: `${i + 1} - ${value}`,\n };\n });\n columnsWithIndices = [\n {\n value: '',\n label: 'Selected columns',\n options,\n expanded: true,\n },\n ...fields,\n ];\n }\n\n return <OrderByRow sql={query.sql!} onSqlChange={onSqlChange} columns={columnsWithIndices} />;\n}\n"],"names":["_a","_b"],"mappings":";;;;;;;AAcO,SAAS,cAAc,EAAE,MAAA,EAAQ,KAAA,EAAO,aAAA,EAAe,IAAG,EAAuB;AAdxF,EAAA,IAAA,EAAA,EAAA,EAAA;AAeE,EAAA,MAAM,EAAE,aAAY,GAAI,YAAA,CAAa,EAAE,KAAA,EAAO,aAAA,EAAe,IAAI,CAAA;AACjE,EAAA,IAAI,qBAAwC,EAAC;AAE7C,EAAA,IAAI,MAAA,EAAQ;AACV,IAAA,MAAM,OAAA,GAAA,CAAU,iBAAM,GAAA,KAAN,IAAA,GAAA,MAAA,GAAA,EAAA,CAAW,YAAX,IAAA,GAAA,MAAA,GAAA,EAAA,CAAoB,GAAA,CAAI,CAAC,CAAA,EAAG,CAAA,KAAM;AAnBtD,MAAA,IAAAA,GAAAA,EAAAC,GAAAA;AAoBM,MAAA,MAAM,KAAA,GAAQ,CAAA,CAAE,IAAA,GAAO,CAAA,EAAG,CAAA,CAAE,IAAI,CAAA,CAAA,EAAA,CAAID,GAAAA,GAAA,CAAA,CAAE,UAAA,KAAF,IAAA,GAAA,MAAA,GAAAA,GAAAA,CAAc,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,IAAA,CAAK,CAAA,CAAA,CAAA,GAAA,CAAMC,GAAAA,GAAA,CAAA,CAAE,UAAA,KAAF,IAAA,GAAA,MAAA,GAAAA,GAAAA,CAAc,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,IAAA,CAAA;AACrG,MAAA,OAAO;AAAA,QACL,KAAA;AAAA,QACA,KAAA,EAAO,CAAA,EAAG,CAAA,GAAI,CAAC,MAAM,KAAK,CAAA;AAAA,OAC5B;AAAA,IACF,CAAA,CAAA;AACA,IAAA,kBAAA,GAAqB;AAAA,MACnB;AAAA,QACE,KAAA,EAAO,EAAA;AAAA,QACP,KAAA,EAAO,kBAAA;AAAA,QACP,OAAA;AAAA,QACA,QAAA,EAAU;AAAA,OACZ;AAAA,MACA,GAAG;AAAA,KACL;AAAA,EACF;AAEA,EAAA,2CAAQ,UAAA,EAAA,EAAW,GAAA,EAAK,MAAM,GAAA,EAAM,WAAA,EAA0B,SAAS,kBAAA,EAAoB,CAAA;AAC7F;;;;"}
1
+ {"version":3,"file":"SQLOrderByRow.js","sources":["../../../../../src/components/QueryEditor/visual-query-builder/SQLOrderByRow.tsx"],"sourcesContent":["import React from 'react';\nimport { type SelectableValue } from '@grafana/data';\nimport { OrderByRow } from './OrderByRow';\nimport { type SQLQuery, type DB, type QueryWithDefaults } from '../types';\nimport { useSqlChange } from '../utils/useSqlChange';\n\ntype SQLOrderByRowProps = {\n fields: SelectableValue[];\n query: QueryWithDefaults;\n onQueryChange: (query: SQLQuery) => void;\n db: DB;\n};\n\nexport function SQLOrderByRow({ fields, query, onQueryChange, db }: SQLOrderByRowProps) {\n const { onSqlChange } = useSqlChange({ query, onQueryChange, db });\n let columnsWithIndices: SelectableValue[] = [];\n\n if (fields) {\n const options = query.sql?.columns?.map((c, i) => {\n const value = c.name ? `${c.name}(${c.parameters?.map((p) => p.name)})` : c.parameters?.map((p) => p.name);\n return {\n value,\n label: `${i + 1} - ${value}`,\n };\n });\n columnsWithIndices = [\n {\n value: '',\n label: 'Selected columns',\n options,\n expanded: true,\n },\n ...fields,\n ];\n }\n\n return <OrderByRow sql={query.sql!} onSqlChange={onSqlChange} columns={columnsWithIndices} />;\n}\n"],"names":["_a","_b"],"mappings":";;;;;;AAaO,SAAS,cAAc,EAAE,MAAA,EAAQ,KAAA,EAAO,aAAA,EAAe,IAAG,EAAuB;AAbxF,EAAA,IAAA,EAAA,EAAA,EAAA;AAcE,EAAA,MAAM,EAAE,aAAY,GAAI,YAAA,CAAa,EAAE,KAAA,EAAO,aAAA,EAAe,IAAI,CAAA;AACjE,EAAA,IAAI,qBAAwC,EAAC;AAE7C,EAAA,IAAI,MAAA,EAAQ;AACV,IAAA,MAAM,OAAA,GAAA,CAAU,iBAAM,GAAA,KAAN,IAAA,GAAA,MAAA,GAAA,EAAA,CAAW,YAAX,IAAA,GAAA,MAAA,GAAA,EAAA,CAAoB,GAAA,CAAI,CAAC,CAAA,EAAG,CAAA,KAAM;AAlBtD,MAAA,IAAAA,GAAAA,EAAAC,GAAAA;AAmBM,MAAA,MAAM,KAAA,GAAQ,CAAA,CAAE,IAAA,GAAO,CAAA,EAAG,CAAA,CAAE,IAAI,CAAA,CAAA,EAAA,CAAID,GAAAA,GAAA,CAAA,CAAE,UAAA,KAAF,IAAA,GAAA,MAAA,GAAAA,GAAAA,CAAc,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,IAAA,CAAK,CAAA,CAAA,CAAA,GAAA,CAAMC,GAAAA,GAAA,CAAA,CAAE,UAAA,KAAF,IAAA,GAAA,MAAA,GAAAA,GAAAA,CAAc,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,IAAA,CAAA;AACrG,MAAA,OAAO;AAAA,QACL,KAAA;AAAA,QACA,KAAA,EAAO,CAAA,EAAG,CAAA,GAAI,CAAC,MAAM,KAAK,CAAA;AAAA,OAC5B;AAAA,IACF,CAAA,CAAA;AACA,IAAA,kBAAA,GAAqB;AAAA,MACnB;AAAA,QACE,KAAA,EAAO,EAAA;AAAA,QACP,KAAA,EAAO,kBAAA;AAAA,QACP,OAAA;AAAA,QACA,QAAA,EAAU;AAAA,OACZ;AAAA,MACA,GAAG;AAAA,KACL;AAAA,EACF;AAEA,EAAA,2CAAQ,UAAA,EAAA,EAAW,GAAA,EAAK,MAAM,GAAA,EAAM,WAAA,EAA0B,SAAS,kBAAA,EAAoB,CAAA;AAC7F;;;;"}
@@ -3,7 +3,6 @@ import { useAsync } from 'react-use';
3
3
  import { toOption } from '@grafana/data';
4
4
  import { SelectRow } from './SelectRow.js';
5
5
  import '../types.js';
6
- import 'lodash';
7
6
  import { useSqlChange } from '../utils/useSqlChange.js';
8
7
 
9
8
  function SQLSelectRow({ fields, query, onQueryChange, db }) {
@@ -1 +1 @@
1
- {"version":3,"file":"SQLSelectRow.js","sources":["../../../../../src/components/QueryEditor/visual-query-builder/SQLSelectRow.tsx"],"sourcesContent":["import React from 'react';\nimport { useAsync } from 'react-use';\nimport { type SelectableValue, toOption } from '@grafana/data';\nimport { SelectRow } from './SelectRow';\nimport { type QueryWithDefaults } from '../defaults';\nimport { type SQLQuery, type DB } from '../types';\nimport { useSqlChange } from '../utils/useSqlChange';\n\ninterface SQLSelectRowProps {\n fields: SelectableValue[];\n query: QueryWithDefaults;\n onQueryChange: (query: SQLQuery) => void;\n db: DB;\n}\n\nexport function SQLSelectRow({ fields, query, onQueryChange, db }: SQLSelectRowProps) {\n const { onSqlChange } = useSqlChange({ query, onQueryChange, db });\n\n const state = useAsync(async () => {\n const functions = await db.functions();\n return functions.map((f) => toOption(f.name));\n }, [db]);\n\n return <SelectRow columns={fields} sql={query.sql!} functions={state.value} onSqlChange={onSqlChange} />;\n}\n"],"names":[],"mappings":";;;;;;;;AAeO,SAAS,aAAa,EAAE,MAAA,EAAQ,KAAA,EAAO,aAAA,EAAe,IAAG,EAAsB;AACpF,EAAA,MAAM,EAAE,aAAY,GAAI,YAAA,CAAa,EAAE,KAAA,EAAO,aAAA,EAAe,IAAI,CAAA;AAEjE,EAAA,MAAM,KAAA,GAAQ,SAAS,YAAY;AACjC,IAAA,MAAM,SAAA,GAAY,MAAM,EAAA,CAAG,SAAA,EAAU;AACrC,IAAA,OAAO,UAAU,GAAA,CAAI,CAAC,MAAM,QAAA,CAAS,CAAA,CAAE,IAAI,CAAC,CAAA;AAAA,EAC9C,CAAA,EAAG,CAAC,EAAE,CAAC,CAAA;AAEP,EAAA,uBAAO,KAAA,CAAA,aAAA,CAAC,SAAA,EAAA,EAAU,OAAA,EAAS,MAAA,EAAQ,GAAA,EAAK,MAAM,GAAA,EAAM,SAAA,EAAW,KAAA,CAAM,KAAA,EAAO,WAAA,EAA0B,CAAA;AACxG;;;;"}
1
+ {"version":3,"file":"SQLSelectRow.js","sources":["../../../../../src/components/QueryEditor/visual-query-builder/SQLSelectRow.tsx"],"sourcesContent":["import React from 'react';\nimport { useAsync } from 'react-use';\nimport { type SelectableValue, toOption } from '@grafana/data';\nimport { SelectRow } from './SelectRow';\nimport { type SQLQuery, type DB, type QueryWithDefaults } from '../types';\nimport { useSqlChange } from '../utils/useSqlChange';\n\ninterface SQLSelectRowProps {\n fields: SelectableValue[];\n query: QueryWithDefaults;\n onQueryChange: (query: SQLQuery) => void;\n db: DB;\n}\n\nexport function SQLSelectRow({ fields, query, onQueryChange, db }: SQLSelectRowProps) {\n const { onSqlChange } = useSqlChange({ query, onQueryChange, db });\n\n const state = useAsync(async () => {\n const functions = await db.functions();\n return functions.map((f) => toOption(f.name));\n }, [db]);\n\n return <SelectRow columns={fields} sql={query.sql!} functions={state.value} onSqlChange={onSqlChange} />;\n}\n"],"names":[],"mappings":";;;;;;;AAcO,SAAS,aAAa,EAAE,MAAA,EAAQ,KAAA,EAAO,aAAA,EAAe,IAAG,EAAsB;AACpF,EAAA,MAAM,EAAE,aAAY,GAAI,YAAA,CAAa,EAAE,KAAA,EAAO,aAAA,EAAe,IAAI,CAAA;AAEjE,EAAA,MAAM,KAAA,GAAQ,SAAS,YAAY;AACjC,IAAA,MAAM,SAAA,GAAY,MAAM,EAAA,CAAG,SAAA,EAAU;AACrC,IAAA,OAAO,UAAU,GAAA,CAAI,CAAC,MAAM,QAAA,CAAS,CAAA,CAAE,IAAI,CAAC,CAAA;AAAA,EAC9C,CAAA,EAAG,CAAC,EAAE,CAAC,CAAA;AAEP,EAAA,uBAAO,KAAA,CAAA,aAAA,CAAC,SAAA,EAAA,EAAU,OAAA,EAAS,MAAA,EAAQ,GAAA,EAAK,MAAM,GAAA,EAAM,SAAA,EAAW,KAAA,CAAM,KAAA,EAAO,WAAA,EAA0B,CAAA;AACxG;;;;"}
@@ -4,7 +4,6 @@ import '@grafana/data';
4
4
  import './AwesomeQueryBuilder.js';
5
5
  import { WhereRow } from './WhereRow.js';
6
6
  import '../types.js';
7
- import 'lodash';
8
7
  import { useSqlChange } from '../utils/useSqlChange.js';
9
8
 
10
9
  function SQLWhereRow({ query, fields, onQueryChange, db }) {
@@ -1 +1 @@
1
- {"version":3,"file":"SQLWhereRow.js","sources":["../../../../../src/components/QueryEditor/visual-query-builder/SQLWhereRow.tsx"],"sourcesContent":["import React from 'react';\nimport { useAsync } from 'react-use';\nimport { type SelectableValue } from '@grafana/data';\nimport { type Config } from './AwesomeQueryBuilder';\nimport { WhereRow } from './WhereRow';\nimport { type QueryWithDefaults } from '../defaults';\nimport { type SQLQuery, type DB, type SQLExpression, type SQLSelectableValue } from '../types';\nimport { useSqlChange } from '../utils/useSqlChange';\n\ninterface WhereRowProps {\n query: QueryWithDefaults;\n fields: SelectableValue[];\n onQueryChange: (query: SQLQuery) => void;\n db: DB;\n}\n\nexport function SQLWhereRow({ query, fields, onQueryChange, db }: WhereRowProps) {\n const state = useAsync(async () => {\n return mapFieldsToTypes(fields);\n }, [fields]);\n\n const { onSqlChange } = useSqlChange({ query, onQueryChange, db });\n\n return (\n <WhereRow\n // TODO: fix key that's used to force clean render or SQLWhereRow - otherwise it doesn't render operators correctly\n key={JSON.stringify(state.value)}\n config={{ fields: state.value || {} }}\n sql={query.sql!}\n onSqlChange={(val: SQLExpression) => {\n onSqlChange(val);\n }}\n />\n );\n}\n\n// needed for awesome query builder\nfunction mapFieldsToTypes(columns: SQLSelectableValue[]) {\n const fields: Config['fields'] = {};\n for (const col of columns) {\n fields[col.value] = {\n type: col.raqbFieldType || 'text',\n valueSources: ['value'],\n mainWidgetProps: { customProps: { icon: col.icon } },\n };\n }\n return fields;\n}\n"],"names":[],"mappings":";;;;;;;;;AAgBO,SAAS,YAAY,EAAE,KAAA,EAAO,MAAA,EAAQ,aAAA,EAAe,IAAG,EAAkB;AAC/E,EAAA,MAAM,KAAA,GAAQ,SAAS,YAAY;AACjC,IAAA,OAAO,iBAAiB,MAAM,CAAA;AAAA,EAChC,CAAA,EAAG,CAAC,MAAM,CAAC,CAAA;AAEX,EAAA,MAAM,EAAE,aAAY,GAAI,YAAA,CAAa,EAAE,KAAA,EAAO,aAAA,EAAe,IAAI,CAAA;AAEjE,EAAA,uBACE,KAAA,CAAA,aAAA;AAAA,IAAC,QAAA;AAAA,IAAA;AAAA,MAEC,GAAA,EAAK,IAAA,CAAK,SAAA,CAAU,KAAA,CAAM,KAAK,CAAA;AAAA,MAC/B,QAAQ,EAAE,MAAA,EAAQ,KAAA,CAAM,KAAA,IAAS,EAAC,EAAE;AAAA,MACpC,KAAK,KAAA,CAAM,GAAA;AAAA,MACX,WAAA,EAAa,CAAC,GAAA,KAAuB;AACnC,QAAA,WAAA,CAAY,GAAG,CAAA;AAAA,MACjB;AAAA;AAAA,GACF;AAEJ;AAGA,SAAS,iBAAiB,OAAA,EAA+B;AACvD,EAAA,MAAM,SAA2B,EAAC;AAClC,EAAA,KAAA,MAAW,OAAO,OAAA,EAAS;AACzB,IAAA,MAAA,CAAO,GAAA,CAAI,KAAK,CAAA,GAAI;AAAA,MAClB,IAAA,EAAM,IAAI,aAAA,IAAiB,MAAA;AAAA,MAC3B,YAAA,EAAc,CAAC,OAAO,CAAA;AAAA,MACtB,iBAAiB,EAAE,WAAA,EAAa,EAAE,IAAA,EAAM,GAAA,CAAI,MAAK;AAAE,KACrD;AAAA,EACF;AACA,EAAA,OAAO,MAAA;AACT;;;;"}
1
+ {"version":3,"file":"SQLWhereRow.js","sources":["../../../../../src/components/QueryEditor/visual-query-builder/SQLWhereRow.tsx"],"sourcesContent":["import React from 'react';\nimport { useAsync } from 'react-use';\nimport { type SelectableValue } from '@grafana/data';\nimport { type Config } from './AwesomeQueryBuilder';\nimport { WhereRow } from './WhereRow';\nimport { type SQLQuery, type DB, type SQLExpression, type SQLSelectableValue, type QueryWithDefaults } from '../types';\nimport { useSqlChange } from '../utils/useSqlChange';\n\ninterface WhereRowProps {\n query: QueryWithDefaults;\n fields: SelectableValue[];\n onQueryChange: (query: SQLQuery) => void;\n db: DB;\n}\n\nexport function SQLWhereRow({ query, fields, onQueryChange, db }: WhereRowProps) {\n const state = useAsync(async () => {\n return mapFieldsToTypes(fields);\n }, [fields]);\n\n const { onSqlChange } = useSqlChange({ query, onQueryChange, db });\n\n return (\n <WhereRow\n // TODO: fix key that's used to force clean render or SQLWhereRow - otherwise it doesn't render operators correctly\n key={JSON.stringify(state.value)}\n config={{ fields: state.value || {} }}\n sql={query.sql!}\n onSqlChange={(val: SQLExpression) => {\n onSqlChange(val);\n }}\n />\n );\n}\n\n// needed for awesome query builder\nfunction mapFieldsToTypes(columns: SQLSelectableValue[]) {\n const fields: Config['fields'] = {};\n for (const col of columns) {\n fields[col.value] = {\n type: col.raqbFieldType || 'text',\n valueSources: ['value'],\n mainWidgetProps: { customProps: { icon: col.icon } },\n };\n }\n return fields;\n}\n"],"names":[],"mappings":";;;;;;;;AAeO,SAAS,YAAY,EAAE,KAAA,EAAO,MAAA,EAAQ,aAAA,EAAe,IAAG,EAAkB;AAC/E,EAAA,MAAM,KAAA,GAAQ,SAAS,YAAY;AACjC,IAAA,OAAO,iBAAiB,MAAM,CAAA;AAAA,EAChC,CAAA,EAAG,CAAC,MAAM,CAAC,CAAA;AAEX,EAAA,MAAM,EAAE,aAAY,GAAI,YAAA,CAAa,EAAE,KAAA,EAAO,aAAA,EAAe,IAAI,CAAA;AAEjE,EAAA,uBACE,KAAA,CAAA,aAAA;AAAA,IAAC,QAAA;AAAA,IAAA;AAAA,MAEC,GAAA,EAAK,IAAA,CAAK,SAAA,CAAU,KAAA,CAAM,KAAK,CAAA;AAAA,MAC/B,QAAQ,EAAE,MAAA,EAAQ,KAAA,CAAM,KAAA,IAAS,EAAC,EAAE;AAAA,MACpC,KAAK,KAAA,CAAM,GAAA;AAAA,MACX,WAAA,EAAa,CAAC,GAAA,KAAuB;AACnC,QAAA,WAAA,CAAY,GAAG,CAAA;AAAA,MACjB;AAAA;AAAA,GACF;AAEJ;AAGA,SAAS,iBAAiB,OAAA,EAA+B;AACvD,EAAA,MAAM,SAA2B,EAAC;AAClC,EAAA,KAAA,MAAW,OAAO,OAAA,EAAS;AACzB,IAAA,MAAA,CAAO,GAAA,CAAI,KAAK,CAAA,GAAI;AAAA,MAClB,IAAA,EAAM,IAAI,aAAA,IAAiB,MAAA;AAAA,MAC3B,YAAA,EAAc,CAAC,OAAO,CAAA;AAAA,MACtB,iBAAiB,EAAE,WAAA,EAAa,EAAE,IAAA,EAAM,GAAA,CAAI,MAAK;AAAE,KACrD;AAAA,EACF;AACA,EAAA,OAAO,MAAA;AACT;;;;"}
@@ -12,7 +12,7 @@ import { EditorStack } from '../EditorStack.js';
12
12
  const asteriskValue = { label: "*", value: "*" };
13
13
  function SelectRow({ sql, columns, onSqlChange, functions }) {
14
14
  var _a;
15
- const styles = useStyles2(getStyles$f);
15
+ const styles = useStyles2(getStyles$j);
16
16
  const columnsWithAsterisk = [asteriskValue, ...columns || []];
17
17
  const onColumnChange = useCallback(
18
18
  (item, index) => (column) => {
@@ -108,7 +108,7 @@ function SelectRow({ sql, columns, onSqlChange, functions }) {
108
108
  }
109
109
  ));
110
110
  }
111
- const getStyles$f = () => {
111
+ const getStyles$j = () => {
112
112
  return { addButton: css({ alignSelf: "flex-start" }) };
113
113
  };
114
114
  function getColumnValue({ parameters }) {
@@ -12,12 +12,20 @@ import { EditorRow } from './EditorRow.js';
12
12
  import { EditorField } from './EditorField.js';
13
13
  import { EditorRows } from './EditorRows.js';
14
14
 
15
- const VisualEditor = ({ query, db, queryRowFilter, onChange, onValidate, range }) => {
15
+ const VisualEditor = ({
16
+ query,
17
+ db,
18
+ queryRowFilter,
19
+ onChange,
20
+ onValidate,
21
+ language = "sql",
22
+ range
23
+ }) => {
16
24
  const state = useAsync(async () => {
17
25
  const fields = await db.fields(query);
18
26
  return fields;
19
27
  }, [db, query.dataset, query.table]);
20
- return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(EditorRows, null, /* @__PURE__ */ React.createElement(EditorRow, null, /* @__PURE__ */ React.createElement(SQLSelectRow, { fields: state.value || [], query, onQueryChange: onChange, db })), queryRowFilter.filter && /* @__PURE__ */ React.createElement(EditorRow, null, /* @__PURE__ */ React.createElement(EditorField, { label: "Filter by column value", optional: true }, /* @__PURE__ */ React.createElement(SQLWhereRow, { fields: state.value || [], query, onQueryChange: onChange, db }))), queryRowFilter.group && /* @__PURE__ */ React.createElement(EditorRow, null, /* @__PURE__ */ React.createElement(EditorField, { label: "Group by column" }, /* @__PURE__ */ React.createElement(SQLGroupByRow, { fields: state.value || [], query, onQueryChange: onChange, db }))), queryRowFilter.order && /* @__PURE__ */ React.createElement(EditorRow, null, /* @__PURE__ */ React.createElement(SQLOrderByRow, { fields: state.value || [], query, onQueryChange: onChange, db })), queryRowFilter.preview && query.rawSql && /* @__PURE__ */ React.createElement(EditorRow, null, /* @__PURE__ */ React.createElement(Preview, { rawSql: query.rawSql }))), /* @__PURE__ */ React.createElement(QueryToolbox, { db, query, onValidate, range }));
28
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(EditorRows, null, /* @__PURE__ */ React.createElement(EditorRow, null, /* @__PURE__ */ React.createElement(SQLSelectRow, { fields: state.value || [], query, onQueryChange: onChange, db })), queryRowFilter.filter && /* @__PURE__ */ React.createElement(EditorRow, null, /* @__PURE__ */ React.createElement(EditorField, { label: "Filter by column value", optional: true }, /* @__PURE__ */ React.createElement(SQLWhereRow, { fields: state.value || [], query, onQueryChange: onChange, db }))), queryRowFilter.group && /* @__PURE__ */ React.createElement(EditorRow, null, /* @__PURE__ */ React.createElement(EditorField, { label: "Group by column" }, /* @__PURE__ */ React.createElement(SQLGroupByRow, { fields: state.value || [], query, onQueryChange: onChange, db }))), queryRowFilter.order && /* @__PURE__ */ React.createElement(EditorRow, null, /* @__PURE__ */ React.createElement(SQLOrderByRow, { fields: state.value || [], query, onQueryChange: onChange, db })), queryRowFilter.preview && query.rawSql && /* @__PURE__ */ React.createElement(EditorRow, null, /* @__PURE__ */ React.createElement(Preview, { rawSql: query.rawSql, language }))), /* @__PURE__ */ React.createElement(QueryToolbox, { db, query, onValidate, range }));
21
29
  };
22
30
 
23
31
  export { VisualEditor };
@@ -1 +1 @@
1
- {"version":3,"file":"VisualEditor.js","sources":["../../../../../src/components/QueryEditor/visual-query-builder/VisualEditor.tsx"],"sourcesContent":["import React from 'react';\nimport { useAsync } from 'react-use';\nimport { type DB, type QueryEditorProps, type QueryRowFilter, type SQLQuery } from '../types';\nimport { QueryToolbox } from '../query-editor-raw/QueryToolbox';\nimport { Preview } from './Preview';\nimport { SQLGroupByRow } from './SQLGroupByRow';\nimport { SQLOrderByRow } from './SQLOrderByRow';\nimport { SQLSelectRow } from './SQLSelectRow';\nimport { SQLWhereRow } from './SQLWhereRow';\nimport { type TimeRange } from '@grafana/data';\nimport { EditorRow } from './EditorRow';\nimport { EditorField } from './EditorField';\nimport { EditorRows } from './EditorRows';\n\ninterface VisualEditorProps extends QueryEditorProps {\n query: SQLQuery;\n db: DB;\n queryRowFilter: QueryRowFilter;\n onChange: (q: SQLQuery) => void;\n onValidate: (isValid: boolean) => void;\n range?: TimeRange;\n}\n\nexport const VisualEditor = ({ query, db, queryRowFilter, onChange, onValidate, range }: VisualEditorProps) => {\n const state = useAsync(async () => {\n const fields = await db.fields(query);\n return fields;\n }, [db, query.dataset, query.table]);\n\n return (\n <>\n <EditorRows>\n <EditorRow>\n <SQLSelectRow fields={state.value || []} query={query} onQueryChange={onChange} db={db} />\n </EditorRow>\n {queryRowFilter.filter && (\n <EditorRow>\n <EditorField label=\"Filter by column value\" optional>\n <SQLWhereRow fields={state.value || []} query={query} onQueryChange={onChange} db={db} />\n </EditorField>\n </EditorRow>\n )}\n {queryRowFilter.group && (\n <EditorRow>\n <EditorField label=\"Group by column\">\n <SQLGroupByRow fields={state.value || []} query={query} onQueryChange={onChange} db={db} />\n </EditorField>\n </EditorRow>\n )}\n {queryRowFilter.order && (\n <EditorRow>\n <SQLOrderByRow fields={state.value || []} query={query} onQueryChange={onChange} db={db} />\n </EditorRow>\n )}\n {queryRowFilter.preview && query.rawSql && (\n <EditorRow>\n <Preview rawSql={query.rawSql} />\n </EditorRow>\n )}\n </EditorRows>\n <QueryToolbox db={db} query={query} onValidate={onValidate} range={range} />\n </>\n );\n};\n"],"names":[],"mappings":";;;;;;;;;;;;;;AAuBO,MAAM,YAAA,GAAe,CAAC,EAAE,KAAA,EAAO,IAAI,cAAA,EAAgB,QAAA,EAAU,UAAA,EAAY,KAAA,EAAM,KAAyB;AAC7G,EAAA,MAAM,KAAA,GAAQ,SAAS,YAAY;AACjC,IAAA,MAAM,MAAA,GAAS,MAAM,EAAA,CAAG,MAAA,CAAO,KAAK,CAAA;AACpC,IAAA,OAAO,MAAA;AAAA,EACT,GAAG,CAAC,EAAA,EAAI,MAAM,OAAA,EAAS,KAAA,CAAM,KAAK,CAAC,CAAA;AAEnC,EAAA,uBACE,KAAA,CAAA,aAAA,CAAA,KAAA,CAAA,QAAA,EAAA,IAAA,sCACG,UAAA,EAAA,IAAA,kBACC,KAAA,CAAA,aAAA,CAAC,iCACC,KAAA,CAAA,aAAA,CAAC,YAAA,EAAA,EAAa,MAAA,EAAQ,KAAA,CAAM,KAAA,IAAS,IAAI,KAAA,EAAc,aAAA,EAAe,UAAU,EAAA,EAAQ,CAC1F,GACC,cAAA,CAAe,MAAA,oBACd,KAAA,CAAA,aAAA,CAAC,SAAA,EAAA,IAAA,kBACC,KAAA,CAAA,aAAA,CAAC,WAAA,EAAA,EAAY,OAAM,wBAAA,EAAyB,QAAA,EAAQ,wBAClD,KAAA,CAAA,aAAA,CAAC,WAAA,EAAA,EAAY,QAAQ,KAAA,CAAM,KAAA,IAAS,EAAC,EAAG,KAAA,EAAc,aAAA,EAAe,UAAU,EAAA,EAAQ,CACzF,CACF,CAAA,EAED,cAAA,CAAe,yBACd,KAAA,CAAA,aAAA,CAAC,SAAA,EAAA,IAAA,kBACC,KAAA,CAAA,aAAA,CAAC,WAAA,EAAA,EAAY,KAAA,EAAM,iBAAA,EAAA,sCAChB,aAAA,EAAA,EAAc,MAAA,EAAQ,MAAM,KAAA,IAAS,IAAI,KAAA,EAAc,aAAA,EAAe,QAAA,EAAU,EAAA,EAAQ,CAC3F,CACF,GAED,cAAA,CAAe,KAAA,wCACb,SAAA,EAAA,IAAA,kBACC,KAAA,CAAA,aAAA,CAAC,iBAAc,MAAA,EAAQ,KAAA,CAAM,KAAA,IAAS,EAAC,EAAG,KAAA,EAAc,eAAe,QAAA,EAAU,EAAA,EAAQ,CAC3F,CAAA,EAED,cAAA,CAAe,WAAW,KAAA,CAAM,MAAA,oBAC/B,KAAA,CAAA,aAAA,CAAC,SAAA,EAAA,IAAA,kBACC,KAAA,CAAA,aAAA,CAAC,OAAA,EAAA,EAAQ,QAAQ,KAAA,CAAM,MAAA,EAAQ,CACjC,CAEJ,CAAA,kBACA,KAAA,CAAA,aAAA,CAAC,gBAAa,EAAA,EAAQ,KAAA,EAAc,UAAA,EAAwB,KAAA,EAAc,CAC5E,CAAA;AAEJ;;;;"}
1
+ {"version":3,"file":"VisualEditor.js","sources":["../../../../../src/components/QueryEditor/visual-query-builder/VisualEditor.tsx"],"sourcesContent":["import React from 'react';\nimport { useAsync } from 'react-use';\nimport { type DB, type QueryEditorProps, type QueryRowFilter, type SQLQuery } from '../types';\nimport { QueryToolbox } from '../query-editor-raw/QueryToolbox';\nimport { Preview } from './Preview';\nimport { SQLGroupByRow } from './SQLGroupByRow';\nimport { SQLOrderByRow } from './SQLOrderByRow';\nimport { SQLSelectRow } from './SQLSelectRow';\nimport { SQLWhereRow } from './SQLWhereRow';\nimport { type TimeRange } from '@grafana/data';\nimport { EditorRow } from './EditorRow';\nimport { EditorField } from './EditorField';\nimport { EditorRows } from './EditorRows';\nimport type { SqlLanguage } from 'sql-formatter';\n\ninterface VisualEditorProps extends QueryEditorProps {\n query: SQLQuery;\n db: DB;\n queryRowFilter: QueryRowFilter;\n onChange: (q: SQLQuery) => void;\n onValidate: (isValid: boolean) => void;\n language?: SqlLanguage;\n range?: TimeRange;\n}\n\nexport const VisualEditor = ({\n query,\n db,\n queryRowFilter,\n onChange,\n onValidate,\n language = 'sql',\n range,\n}: VisualEditorProps) => {\n const state = useAsync(async () => {\n const fields = await db.fields(query);\n return fields;\n }, [db, query.dataset, query.table]);\n\n return (\n <>\n <EditorRows>\n <EditorRow>\n <SQLSelectRow fields={state.value || []} query={query} onQueryChange={onChange} db={db} />\n </EditorRow>\n {queryRowFilter.filter && (\n <EditorRow>\n <EditorField label=\"Filter by column value\" optional>\n <SQLWhereRow fields={state.value || []} query={query} onQueryChange={onChange} db={db} />\n </EditorField>\n </EditorRow>\n )}\n {queryRowFilter.group && (\n <EditorRow>\n <EditorField label=\"Group by column\">\n <SQLGroupByRow fields={state.value || []} query={query} onQueryChange={onChange} db={db} />\n </EditorField>\n </EditorRow>\n )}\n {queryRowFilter.order && (\n <EditorRow>\n <SQLOrderByRow fields={state.value || []} query={query} onQueryChange={onChange} db={db} />\n </EditorRow>\n )}\n {queryRowFilter.preview && query.rawSql && (\n <EditorRow>\n <Preview rawSql={query.rawSql} language={language} />\n </EditorRow>\n )}\n </EditorRows>\n <QueryToolbox db={db} query={query} onValidate={onValidate} range={range} />\n </>\n );\n};\n"],"names":[],"mappings":";;;;;;;;;;;;;;AAyBO,MAAM,eAAe,CAAC;AAAA,EAC3B,KAAA;AAAA,EACA,EAAA;AAAA,EACA,cAAA;AAAA,EACA,QAAA;AAAA,EACA,UAAA;AAAA,EACA,QAAA,GAAW,KAAA;AAAA,EACX;AACF,CAAA,KAAyB;AACvB,EAAA,MAAM,KAAA,GAAQ,SAAS,YAAY;AACjC,IAAA,MAAM,MAAA,GAAS,MAAM,EAAA,CAAG,MAAA,CAAO,KAAK,CAAA;AACpC,IAAA,OAAO,MAAA;AAAA,EACT,GAAG,CAAC,EAAA,EAAI,MAAM,OAAA,EAAS,KAAA,CAAM,KAAK,CAAC,CAAA;AAEnC,EAAA,uBACE,KAAA,CAAA,aAAA,CAAA,KAAA,CAAA,QAAA,EAAA,IAAA,sCACG,UAAA,EAAA,IAAA,kBACC,KAAA,CAAA,aAAA,CAAC,iCACC,KAAA,CAAA,aAAA,CAAC,YAAA,EAAA,EAAa,MAAA,EAAQ,KAAA,CAAM,KAAA,IAAS,IAAI,KAAA,EAAc,aAAA,EAAe,UAAU,EAAA,EAAQ,CAC1F,GACC,cAAA,CAAe,MAAA,oBACd,KAAA,CAAA,aAAA,CAAC,SAAA,EAAA,IAAA,kBACC,KAAA,CAAA,aAAA,CAAC,WAAA,EAAA,EAAY,OAAM,wBAAA,EAAyB,QAAA,EAAQ,wBAClD,KAAA,CAAA,aAAA,CAAC,WAAA,EAAA,EAAY,QAAQ,KAAA,CAAM,KAAA,IAAS,EAAC,EAAG,KAAA,EAAc,aAAA,EAAe,UAAU,EAAA,EAAQ,CACzF,CACF,CAAA,EAED,cAAA,CAAe,KAAA,wCACb,SAAA,EAAA,IAAA,kBACC,KAAA,CAAA,aAAA,CAAC,WAAA,EAAA,EAAY,KAAA,EAAM,iBAAA,EAAA,kBACjB,KAAA,CAAA,aAAA,CAAC,iBAAc,MAAA,EAAQ,KAAA,CAAM,SAAS,EAAC,EAAG,OAAc,aAAA,EAAe,QAAA,EAAU,EAAA,EAAQ,CAC3F,CACF,CAAA,EAED,eAAe,KAAA,oBACd,KAAA,CAAA,aAAA,CAAC,iCACC,KAAA,CAAA,aAAA,CAAC,aAAA,EAAA,EAAc,QAAQ,KAAA,CAAM,KAAA,IAAS,EAAC,EAAG,KAAA,EAAc,aAAA,EAAe,UAAU,EAAA,EAAQ,CAC3F,GAED,cAAA,CAAe,OAAA,IAAW,MAAM,MAAA,oBAC/B,KAAA,CAAA,aAAA,CAAC,SAAA,EAAA,IAAA,kBACC,KAAA,CAAA,aAAA,CAAC,OAAA,EAAA,EAAQ,MAAA,EAAQ,MAAM,MAAA,EAAQ,QAAA,EAAoB,CACrD,CAEJ,CAAA,kBACA,KAAA,CAAA,aAAA,CAAC,gBAAa,EAAA,EAAQ,KAAA,EAAc,UAAA,EAAwB,KAAA,EAAc,CAC5E,CAAA;AAEJ;;;;"}