@grafana/plugin-ui 0.11.0 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. package/README.md +20 -0
  2. package/dist/cjs/index.cjs +79 -122
  3. package/dist/cjs/index.cjs.map +1 -1
  4. package/dist/cjs/index.d.cts +9 -17
  5. package/dist/esm/components/QueryEditor/CatalogSelector.js +0 -1
  6. package/dist/esm/components/QueryEditor/CatalogSelector.js.map +1 -1
  7. package/dist/esm/components/QueryEditor/DatasetSelector.js +9 -4
  8. package/dist/esm/components/QueryEditor/DatasetSelector.js.map +1 -1
  9. package/dist/esm/components/QueryEditor/QueryEditor.js +5 -2
  10. package/dist/esm/components/QueryEditor/QueryEditor.js.map +1 -1
  11. package/dist/esm/components/QueryEditor/QueryHeader.js +35 -49
  12. package/dist/esm/components/QueryEditor/QueryHeader.js.map +1 -1
  13. package/dist/esm/components/QueryEditor/TableSelector.js +3 -6
  14. package/dist/esm/components/QueryEditor/TableSelector.js.map +1 -1
  15. package/dist/esm/components/QueryEditor/types.js.map +1 -1
  16. package/dist/esm/components/QueryEditor/utils/sql.utils.js +7 -9
  17. package/dist/esm/components/QueryEditor/utils/sql.utils.js.map +1 -1
  18. package/dist/esm/components/QueryEditor/utils/useSqlChange.js +7 -1
  19. package/dist/esm/components/QueryEditor/utils/useSqlChange.js.map +1 -1
  20. package/dist/esm/components/SQLEditor/types.js.map +1 -1
  21. package/dist/esm/components/SQLEditor/utils/tokenUtils.js +2 -0
  22. package/dist/esm/components/SQLEditor/utils/tokenUtils.js.map +1 -1
  23. package/dist/esm/components/VisualQueryBuilder/components/QueryOptionGroup.js +11 -2
  24. package/dist/esm/components/VisualQueryBuilder/components/QueryOptionGroup.js.map +1 -1
  25. package/dist/esm/index.d.ts +9 -17
  26. package/dist/esm/index.js +0 -1
  27. package/dist/esm/index.js.map +1 -1
  28. package/package.json +2 -1
  29. package/dist/esm/components/QueryEditor/SchemaSelector.js +0 -56
  30. package/dist/esm/components/QueryEditor/SchemaSelector.js.map +0 -1
@@ -223,6 +223,7 @@ interface TableDefinition {
223
223
  interface TableIdentifier {
224
224
  table?: string;
225
225
  schema?: string;
226
+ catalog?: string;
226
227
  }
227
228
  interface SQLCompletionItemProvider extends Omit<monacoTypes.languages.CompletionItemProvider, 'provideCompletionItems'> {
228
229
  /**
@@ -536,7 +537,6 @@ interface SQLQuery extends DataQuery {
536
537
  rawSql?: string;
537
538
  dataset?: string;
538
539
  catalog?: string;
539
- schema?: string;
540
540
  table?: string;
541
541
  sql?: SQLExpression;
542
542
  editorMode?: EditorMode;
@@ -597,9 +597,8 @@ interface Aggregate {
597
597
  }
598
598
  interface DB {
599
599
  init?: (datasourceId?: string) => Promise<boolean>;
600
- datasets: () => Promise<string[]>;
600
+ datasets: (catalog?: string) => Promise<string[]>;
601
601
  catalogs?: () => Promise<string[]>;
602
- schemas?: (catalog?: string) => Promise<string[]>;
603
602
  tables: (dataset?: string, catalog?: string, schema?: string) => Promise<string[]>;
604
603
  fields: (query: SQLQuery, order?: boolean) => Promise<SQLSelectableValue[]>;
605
604
  validateQuery: (query: SQLQuery, range?: TimeRange) => Promise<ValidationResults>;
@@ -808,14 +807,17 @@ declare const RunQueryButton: ({ ariaLabel, queryRunning, queryInvalid, invalidQ
808
807
 
809
808
  interface DatasetSelectorProps extends ResourceSelectorProps {
810
809
  db: DB;
811
- dataset: string;
810
+ dataset?: string;
811
+ catalog?: string;
812
812
  value: string | null;
813
813
  applyDefault?: boolean;
814
814
  disabled?: boolean;
815
815
  onChange: (v: SelectableValue) => void;
816
816
  inputId?: string;
817
+ enableCatalogs?: boolean;
818
+ 'data-testid'?: string;
817
819
  }
818
- declare const DatasetSelector: ({ db, dataset, value, onChange, disabled, className, applyDefault, inputId, }: DatasetSelectorProps) => react_jsx_runtime.JSX.Element;
820
+ declare const DatasetSelector: ({ db, dataset, catalog, value, onChange, disabled, className, applyDefault, inputId, enableCatalogs, "data-testid": dataTestId, }: DatasetSelectorProps) => react_jsx_runtime.JSX.Element;
819
821
 
820
822
  interface CatalogSelectorProps {
821
823
  db: DB;
@@ -825,27 +827,17 @@ interface CatalogSelectorProps {
825
827
  }
826
828
  declare const CatalogSelector: ({ db, inputId, value, onChange }: CatalogSelectorProps) => react_jsx_runtime.JSX.Element;
827
829
 
828
- interface SchemaSelectorProps {
829
- db: DB;
830
- inputId?: string;
831
- catalog?: string;
832
- value: string | null;
833
- onChange: (schema: string | null) => void;
834
- }
835
- declare const SchemaSelector: ({ db, inputId, catalog, value, onChange }: SchemaSelectorProps) => react_jsx_runtime.JSX.Element;
836
-
837
830
  interface TableSelectorProps extends ResourceSelectorProps {
838
831
  db: DB;
839
832
  dataset?: string;
840
833
  catalog?: string;
841
- schema?: string;
842
834
  value: string | null;
843
835
  query: QueryWithDefaults;
844
836
  onChange: (v: SelectableValue) => void;
845
837
  inputId?: string;
846
838
  enableCatalogs?: boolean;
847
839
  }
848
- declare const TableSelector: ({ db, dataset, catalog, schema, value, className, onChange, inputId, enableCatalogs, }: TableSelectorProps) => react_jsx_runtime.JSX.Element;
840
+ declare const TableSelector: ({ db, dataset, catalog, value, className, onChange, inputId, enableCatalogs, }: TableSelectorProps) => react_jsx_runtime.JSX.Element;
849
841
 
850
842
  type Props$o = Omit<React.ComponentProps<typeof InlineLabel>, 'children' | 'onChange'> & {
851
843
  dataSourceConfig: DataSourceSettings<any, any>;
@@ -1323,4 +1315,4 @@ declare const openSelect: (container: HTMLElement, optionLabel?: string) => void
1323
1315
  declare const selectOption: (container: HTMLElement, optionLabel: string, typeOptionLabel?: boolean) => Promise<void>;
1324
1316
  declare const generateOptions: () => Array<SelectableValue<string>>;
1325
1317
 
1326
- export { AccessoryButton, AdvancedHttpSettings, type Aggregate, Auth, AuthMethod, type Props$c as AuthProps, BINARY_OPERATIONS_KEY, CatalogSelector, type ColumnDefinition, CompletionItemInsertTextRule, CompletionItemKind, CompletionItemPriority, ConfigDescriptionLink, ConfigSection, ConfigSubSection, ConnectionSettings, CustomHeadersSettings, type DB, DataLink, type DataLinkConfig, DataLinks, DataSourceDescription, DataSourcePicker, DatasetSelector, DatePicker, type DatePickerProps, DatePickerWithInput, type DatePickerWithInputProps, DebounceInput, type DebounceInputProps, EditorField, EditorFieldGroup, EditorHeader, EditorList, EditorMode, EditorRow, EditorRows, EditorStack, EditorSwitch, FlexItem, GroupByRow, InlineSelect, InputGroup, LabelFilters, type LanguageCompletionProvider, type LanguageDefinition, LinkedToken, MacroType, type MetaDefinition, type NameValue, OperationExplainedBox, OperationList, OperationListExplained, OperationsEditorRow, OperatorType, type PositionContext, type Props$s as Props, QUERY_FORMAT_OPTIONS, QueryBuilderHints, type QueryBuilderLabelFilter, type QueryBuilderOperation, type QueryBuilderOperationDefinition, type QueryBuilderOperationParamDef, type QueryBuilderOperationParamEditorProps, type QueryBuilderOperationParamValue, QueryEditorMode, QueryEditorModeToggle, type QueryEditorProps, QueryEditorRow, QueryFormat, QueryHeaderSwitch, QueryModellerBase, QueryOptionGroup, type QueryRowFilter, type QueryStats, type RAQBFieldTypes, RawQuery, type ResourceSelectorProps, type ResponseParser, RunQueryButton, type SQLConnectionLimits, SQLEditor, SQLEditorMode, SQLEditorTestUtils, type SQLExpression, type SQLFilters, type SQLMonarchLanguage, type SQLOptions, type SQLQuery, type SQLSelectableValue, type SchemaDefinition, SchemaSelector, SecureSocksProxyToggle, Segment, type SegmentProps, Space, SqlDatasource, SqlQueryEditor, type SqlQueryForInterpolation, type SqlQueryModel, type State$1 as State, type StatementPlacementProvider, StatementPosition, SuggestionKind, type SuggestionKindProvider, TLSSettings, type Props$f as TLSSettingsProps, type TableDefinition, type TableFieldSchema, type TableIdentifier, type TableSchema, TableSelector, type TestQueryModel, TokenType, type ValidationResults, type VisualQuery, type VisualQueryBinary, type VisualQueryModeller, convertLegacyAuthProps, formatDate, generateArrayOf, generateBoolean, generateOptions, getStandardSQLCompletionProvider, language as grafanaStandardSQLLanguage, conf as grafanaStandardSQLLanguageConf, mockDataQuery, mockDataSourcePluginMeta, mockDatasource, mockDatasourceInstanceSettings, mockLoadingState, mockPluginDependencies, mockPluginInclude, mockPluginIncludeType, mockPluginMeta, mockPluginMetaInfo, mockPluginSignatureStatus, mockPluginState, mockPluginType, mockQueryEditorProps, mockTimeRange, openSelect, selectOption, toOption, undefinedOr };
1318
+ export { AccessoryButton, AdvancedHttpSettings, type Aggregate, Auth, AuthMethod, type Props$c as AuthProps, BINARY_OPERATIONS_KEY, CatalogSelector, type ColumnDefinition, CompletionItemInsertTextRule, CompletionItemKind, CompletionItemPriority, ConfigDescriptionLink, ConfigSection, ConfigSubSection, ConnectionSettings, CustomHeadersSettings, type DB, DataLink, type DataLinkConfig, DataLinks, DataSourceDescription, DataSourcePicker, DatasetSelector, DatePicker, type DatePickerProps, DatePickerWithInput, type DatePickerWithInputProps, DebounceInput, type DebounceInputProps, EditorField, EditorFieldGroup, EditorHeader, EditorList, EditorMode, EditorRow, EditorRows, EditorStack, EditorSwitch, FlexItem, GroupByRow, InlineSelect, InputGroup, LabelFilters, type LanguageCompletionProvider, type LanguageDefinition, LinkedToken, MacroType, type MetaDefinition, type NameValue, OperationExplainedBox, OperationList, OperationListExplained, OperationsEditorRow, OperatorType, type PositionContext, type Props$s as Props, QUERY_FORMAT_OPTIONS, QueryBuilderHints, type QueryBuilderLabelFilter, type QueryBuilderOperation, type QueryBuilderOperationDefinition, type QueryBuilderOperationParamDef, type QueryBuilderOperationParamEditorProps, type QueryBuilderOperationParamValue, QueryEditorMode, QueryEditorModeToggle, type QueryEditorProps, QueryEditorRow, QueryFormat, QueryHeaderSwitch, QueryModellerBase, QueryOptionGroup, type QueryRowFilter, type QueryStats, type RAQBFieldTypes, RawQuery, type ResourceSelectorProps, type ResponseParser, RunQueryButton, type SQLConnectionLimits, SQLEditor, SQLEditorMode, SQLEditorTestUtils, type SQLExpression, type SQLFilters, type SQLMonarchLanguage, type SQLOptions, type SQLQuery, type SQLSelectableValue, type SchemaDefinition, SecureSocksProxyToggle, Segment, type SegmentProps, Space, SqlDatasource, SqlQueryEditor, type SqlQueryForInterpolation, type SqlQueryModel, type State$1 as State, type StatementPlacementProvider, StatementPosition, SuggestionKind, type SuggestionKindProvider, TLSSettings, type Props$f as TLSSettingsProps, type TableDefinition, type TableFieldSchema, type TableIdentifier, type TableSchema, TableSelector, type TestQueryModel, TokenType, type ValidationResults, type VisualQuery, type VisualQueryBinary, type VisualQueryModeller, convertLegacyAuthProps, formatDate, generateArrayOf, generateBoolean, generateOptions, getStandardSQLCompletionProvider, language as grafanaStandardSQLLanguage, conf as grafanaStandardSQLLanguageConf, mockDataQuery, mockDataSourcePluginMeta, mockDatasource, mockDatasourceInstanceSettings, mockLoadingState, mockPluginDependencies, mockPluginInclude, mockPluginIncludeType, mockPluginMeta, mockPluginMetaInfo, mockPluginSignatureStatus, mockPluginState, mockPluginType, mockQueryEditorProps, mockTimeRange, openSelect, selectOption, toOption, undefinedOr };
@@ -44,7 +44,6 @@ const CatalogSelector = ({ db, inputId, value, onChange }) => {
44
44
  placeholder: "Select catalog",
45
45
  isClearable: true,
46
46
  allowCustomValue: true,
47
- disabled: isLoading,
48
47
  menuShouldPortal: true
49
48
  }
50
49
  );
@@ -1 +1 @@
1
- {"version":3,"file":"CatalogSelector.js","sources":["../../../../src/components/QueryEditor/CatalogSelector.tsx"],"sourcesContent":["import { useState, useEffect, useCallback } from 'react';\nimport { Select } from '@grafana/ui';\nimport { type SelectableValue } from '@grafana/data';\nimport { type DB } from './types';\n\nexport interface CatalogSelectorProps {\n db: DB;\n inputId?: string;\n value: string | null;\n onChange: (catalog: string | null) => void;\n}\n\nexport const CatalogSelector = ({ db, inputId, value, onChange }: CatalogSelectorProps) => {\n const [catalogs, setCatalogs] = useState<Array<SelectableValue<string>>>([]);\n const [isLoading, setIsLoading] = useState(false);\n\n const loadCatalogs = useCallback(async () => {\n if (!db.catalogs) {\n return;\n }\n\n setIsLoading(true);\n try {\n const catalogList = await db.catalogs();\n const catalogOptions = catalogList.map((catalog) => ({\n label: catalog,\n value: catalog,\n }));\n setCatalogs(catalogOptions);\n } catch (error) {\n console.error('Error loading catalogs:', error);\n setCatalogs([]);\n } finally {\n setIsLoading(false);\n }\n }, [db]);\n\n useEffect(() => {\n loadCatalogs();\n }, [db, loadCatalogs]);\n\n const handleChange = (selectable: SelectableValue<string>) => {\n onChange(selectable?.value || null);\n };\n\n const selectedValue = catalogs.find((catalog) => catalog.value === value) || null;\n\n return (\n <Select\n inputId={inputId}\n options={catalogs}\n value={selectedValue}\n onChange={handleChange}\n isLoading={isLoading}\n placeholder=\"Select catalog\"\n isClearable\n allowCustomValue\n disabled={isLoading}\n menuShouldPortal={true}\n />\n );\n};\n"],"names":[],"mappings":";;;;;;AAYO,MAAM,kBAAkB,CAAC,EAAE,IAAI,OAAS,EAAA,KAAA,EAAO,UAAqC,KAAA;AACzF,EAAA,MAAM,CAAC,QAAU,EAAA,WAAW,CAAI,GAAA,QAAA,CAAyC,EAAE,CAAA;AAC3E,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAI,SAAS,KAAK,CAAA;AAEhD,EAAM,MAAA,YAAA,GAAe,YAAY,YAAY;AAC3C,IAAI,IAAA,CAAC,GAAG,QAAU,EAAA;AAChB,MAAA;AAAA;AAGF,IAAA,YAAA,CAAa,IAAI,CAAA;AACjB,IAAI,IAAA;AACF,MAAM,MAAA,WAAA,GAAc,MAAM,EAAA,CAAG,QAAS,EAAA;AACtC,MAAA,MAAM,cAAiB,GAAA,WAAA,CAAY,GAAI,CAAA,CAAC,OAAa,MAAA;AAAA,QACnD,KAAO,EAAA,OAAA;AAAA,QACP,KAAO,EAAA;AAAA,OACP,CAAA,CAAA;AACF,MAAA,WAAA,CAAY,cAAc,CAAA;AAAA,aACnB,KAAO,EAAA;AACd,MAAQ,OAAA,CAAA,KAAA,CAAM,2BAA2B,KAAK,CAAA;AAC9C,MAAA,WAAA,CAAY,EAAE,CAAA;AAAA,KACd,SAAA;AACA,MAAA,YAAA,CAAa,KAAK,CAAA;AAAA;AACpB,GACF,EAAG,CAAC,EAAE,CAAC,CAAA;AAEP,EAAA,SAAA,CAAU,MAAM;AACd,IAAa,YAAA,EAAA;AAAA,GACZ,EAAA,CAAC,EAAI,EAAA,YAAY,CAAC,CAAA;AAErB,EAAM,MAAA,YAAA,GAAe,CAAC,UAAwC,KAAA;AAC5D,IAAS,QAAA,CAAA,CAAA,UAAA,IAAA,IAAA,GAAA,SAAA,GAAA,UAAA,CAAY,UAAS,IAAI,CAAA;AAAA,GACpC;AAEA,EAAM,MAAA,aAAA,GAAgB,SAAS,IAAK,CAAA,CAAC,YAAY,OAAQ,CAAA,KAAA,KAAU,KAAK,CAAK,IAAA,IAAA;AAE7E,EACE,uBAAA,GAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACC,OAAA;AAAA,MACA,OAAS,EAAA,QAAA;AAAA,MACT,KAAO,EAAA,aAAA;AAAA,MACP,QAAU,EAAA,YAAA;AAAA,MACV,SAAA;AAAA,MACA,WAAY,EAAA,gBAAA;AAAA,MACZ,WAAW,EAAA,IAAA;AAAA,MACX,gBAAgB,EAAA,IAAA;AAAA,MAChB,QAAU,EAAA,SAAA;AAAA,MACV,gBAAkB,EAAA;AAAA;AAAA,GACpB;AAEJ;;;;"}
1
+ {"version":3,"file":"CatalogSelector.js","sources":["../../../../src/components/QueryEditor/CatalogSelector.tsx"],"sourcesContent":["import { useState, useEffect, useCallback } from 'react';\nimport { Select } from '@grafana/ui';\nimport { type SelectableValue } from '@grafana/data';\nimport { type DB } from './types';\n\nexport interface CatalogSelectorProps {\n db: DB;\n inputId?: string;\n value: string | null;\n onChange: (catalog: string | null) => void;\n}\n\nexport const CatalogSelector = ({ db, inputId, value, onChange }: CatalogSelectorProps) => {\n const [catalogs, setCatalogs] = useState<Array<SelectableValue<string>>>([]);\n const [isLoading, setIsLoading] = useState(false);\n\n const loadCatalogs = useCallback(async () => {\n if (!db.catalogs) {\n return;\n }\n\n setIsLoading(true);\n try {\n const catalogList = await db.catalogs();\n const catalogOptions = catalogList.map((catalog) => ({\n label: catalog,\n value: catalog,\n }));\n setCatalogs(catalogOptions);\n } catch (error) {\n console.error('Error loading catalogs:', error);\n setCatalogs([]);\n } finally {\n setIsLoading(false);\n }\n }, [db]);\n\n useEffect(() => {\n loadCatalogs();\n }, [db, loadCatalogs]);\n\n const handleChange = (selectable: SelectableValue<string>) => {\n onChange(selectable?.value || null);\n };\n\n const selectedValue = catalogs.find((catalog) => catalog.value === value) || null;\n\n return (\n <Select\n inputId={inputId}\n options={catalogs}\n value={selectedValue}\n onChange={handleChange}\n isLoading={isLoading}\n placeholder=\"Select catalog\"\n isClearable\n allowCustomValue\n menuShouldPortal={true}\n />\n );\n};\n"],"names":[],"mappings":";;;;;;AAYO,MAAM,kBAAkB,CAAC,EAAE,IAAI,OAAS,EAAA,KAAA,EAAO,UAAqC,KAAA;AACzF,EAAA,MAAM,CAAC,QAAU,EAAA,WAAW,CAAI,GAAA,QAAA,CAAyC,EAAE,CAAA;AAC3E,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAI,SAAS,KAAK,CAAA;AAEhD,EAAM,MAAA,YAAA,GAAe,YAAY,YAAY;AAC3C,IAAI,IAAA,CAAC,GAAG,QAAU,EAAA;AAChB,MAAA;AAAA;AAGF,IAAA,YAAA,CAAa,IAAI,CAAA;AACjB,IAAI,IAAA;AACF,MAAM,MAAA,WAAA,GAAc,MAAM,EAAA,CAAG,QAAS,EAAA;AACtC,MAAA,MAAM,cAAiB,GAAA,WAAA,CAAY,GAAI,CAAA,CAAC,OAAa,MAAA;AAAA,QACnD,KAAO,EAAA,OAAA;AAAA,QACP,KAAO,EAAA;AAAA,OACP,CAAA,CAAA;AACF,MAAA,WAAA,CAAY,cAAc,CAAA;AAAA,aACnB,KAAO,EAAA;AACd,MAAQ,OAAA,CAAA,KAAA,CAAM,2BAA2B,KAAK,CAAA;AAC9C,MAAA,WAAA,CAAY,EAAE,CAAA;AAAA,KACd,SAAA;AACA,MAAA,YAAA,CAAa,KAAK,CAAA;AAAA;AACpB,GACF,EAAG,CAAC,EAAE,CAAC,CAAA;AAEP,EAAA,SAAA,CAAU,MAAM;AACd,IAAa,YAAA,EAAA;AAAA,GACZ,EAAA,CAAC,EAAI,EAAA,YAAY,CAAC,CAAA;AAErB,EAAM,MAAA,YAAA,GAAe,CAAC,UAAwC,KAAA;AAC5D,IAAS,QAAA,CAAA,CAAA,UAAA,IAAA,IAAA,GAAA,SAAA,GAAA,UAAA,CAAY,UAAS,IAAI,CAAA;AAAA,GACpC;AAEA,EAAM,MAAA,aAAA,GAAgB,SAAS,IAAK,CAAA,CAAC,YAAY,OAAQ,CAAA,KAAA,KAAU,KAAK,CAAK,IAAA,IAAA;AAE7E,EACE,uBAAA,GAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACC,OAAA;AAAA,MACA,OAAS,EAAA,QAAA;AAAA,MACT,KAAO,EAAA,aAAA;AAAA,MACP,QAAU,EAAA,YAAA;AAAA,MACV,SAAA;AAAA,MACA,WAAY,EAAA,gBAAA;AAAA,MACZ,WAAW,EAAA,IAAA;AAAA,MACX,gBAAgB,EAAA,IAAA;AAAA,MAChB,gBAAkB,EAAA;AAAA;AAAA,GACpB;AAEJ;;;;"}
@@ -8,21 +8,24 @@ import { toOption } from './types.js';
8
8
  const DatasetSelector = ({
9
9
  db,
10
10
  dataset,
11
+ catalog,
11
12
  value,
12
13
  onChange,
13
14
  disabled,
14
15
  className,
15
16
  applyDefault,
16
- inputId
17
+ inputId,
18
+ enableCatalogs,
19
+ "data-testid": dataTestId
17
20
  }) => {
18
21
  const state = useAsync(async () => {
19
22
  if (dataset) {
20
23
  onChange(toOption(dataset));
21
24
  return [toOption(dataset)];
22
25
  }
23
- const datasets = await db.datasets();
26
+ const datasets = await db.datasets(catalog);
24
27
  return datasets.map(toOption);
25
- }, []);
28
+ }, [catalog]);
26
29
  useEffect(() => {
27
30
  if (!applyDefault) {
28
31
  return;
@@ -50,7 +53,9 @@ const DatasetSelector = ({
50
53
  onChange,
51
54
  disabled,
52
55
  isLoading: state.loading,
53
- menuShouldPortal: true
56
+ menuShouldPortal: true,
57
+ "data-testid": dataTestId,
58
+ placeholder: enableCatalogs ? "Select schema" : "Select dataset"
54
59
  }
55
60
  );
56
61
  };
@@ -1 +1 @@
1
- {"version":3,"file":"DatasetSelector.js","sources":["../../../../src/components/QueryEditor/DatasetSelector.tsx"],"sourcesContent":["import { useEffect } from 'react';\nimport { useAsync } from 'react-use';\n\nimport { type SelectableValue } from '@grafana/data';\nimport { Select } from '@grafana/ui';\n\nimport { type DB, type ResourceSelectorProps, toOption } from './types';\n\ninterface DatasetSelectorProps extends ResourceSelectorProps {\n db: DB;\n dataset: string;\n value: string | null;\n applyDefault?: boolean;\n disabled?: boolean;\n onChange: (v: SelectableValue) => void;\n inputId?: string;\n}\n\nexport const DatasetSelector = ({\n db,\n dataset,\n value,\n onChange,\n disabled,\n className,\n applyDefault,\n inputId,\n}: DatasetSelectorProps) => {\n const state = useAsync(async () => {\n if (dataset) {\n onChange(toOption(dataset));\n return [toOption(dataset)];\n }\n\n const datasets = await db.datasets();\n return datasets.map(toOption);\n }, []);\n\n useEffect(() => {\n if (!applyDefault) {\n return;\n }\n // Set default dataset when values are fetched\n if (!value) {\n if (state.value && state.value[0]) {\n onChange(state.value[0]);\n }\n } else {\n if (state.value && state.value.find((v) => v.value === value) === undefined) {\n // if value is set and newly fetched values does not contain selected value\n if (state.value.length > 0) {\n onChange(state.value[0]);\n }\n }\n }\n }, [state.value, value, applyDefault, onChange]);\n\n return (\n <Select\n inputId={inputId}\n className={className}\n aria-label=\"Dataset selector\"\n value={value}\n options={state.value}\n onChange={onChange}\n disabled={disabled}\n isLoading={state.loading}\n menuShouldPortal={true}\n />\n );\n};\n"],"names":[],"mappings":";;;;;;;AAkBO,MAAM,kBAAkB,CAAC;AAAA,EAC9B,EAAA;AAAA,EACA,OAAA;AAAA,EACA,KAAA;AAAA,EACA,QAAA;AAAA,EACA,QAAA;AAAA,EACA,SAAA;AAAA,EACA,YAAA;AAAA,EACA;AACF,CAA4B,KAAA;AAC1B,EAAM,MAAA,KAAA,GAAQ,SAAS,YAAY;AACjC,IAAA,IAAI,OAAS,EAAA;AACX,MAAS,QAAA,CAAA,QAAA,CAAS,OAAO,CAAC,CAAA;AAC1B,MAAO,OAAA,CAAC,QAAS,CAAA,OAAO,CAAC,CAAA;AAAA;AAG3B,IAAM,MAAA,QAAA,GAAW,MAAM,EAAA,CAAG,QAAS,EAAA;AACnC,IAAO,OAAA,QAAA,CAAS,IAAI,QAAQ,CAAA;AAAA,GAC9B,EAAG,EAAE,CAAA;AAEL,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,CAAC,YAAc,EAAA;AACjB,MAAA;AAAA;AAGF,IAAA,IAAI,CAAC,KAAO,EAAA;AACV,MAAA,IAAI,KAAM,CAAA,KAAA,IAAS,KAAM,CAAA,KAAA,CAAM,CAAC,CAAG,EAAA;AACjC,QAAS,QAAA,CAAA,KAAA,CAAM,KAAM,CAAA,CAAC,CAAC,CAAA;AAAA;AACzB,KACK,MAAA;AACL,MAAI,IAAA,KAAA,CAAM,KAAS,IAAA,KAAA,CAAM,KAAM,CAAA,IAAA,CAAK,CAAC,CAAA,KAAM,CAAE,CAAA,KAAA,KAAU,KAAK,CAAA,KAAM,SAAW,EAAA;AAE3E,QAAI,IAAA,KAAA,CAAM,KAAM,CAAA,MAAA,GAAS,CAAG,EAAA;AAC1B,UAAS,QAAA,CAAA,KAAA,CAAM,KAAM,CAAA,CAAC,CAAC,CAAA;AAAA;AACzB;AACF;AACF,KACC,CAAC,KAAA,CAAM,OAAO,KAAO,EAAA,YAAA,EAAc,QAAQ,CAAC,CAAA;AAE/C,EACE,uBAAA,GAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACC,OAAA;AAAA,MACA,SAAA;AAAA,MACA,YAAW,EAAA,kBAAA;AAAA,MACX,KAAA;AAAA,MACA,SAAS,KAAM,CAAA,KAAA;AAAA,MACf,QAAA;AAAA,MACA,QAAA;AAAA,MACA,WAAW,KAAM,CAAA,OAAA;AAAA,MACjB,gBAAkB,EAAA;AAAA;AAAA,GACpB;AAEJ;;;;"}
1
+ {"version":3,"file":"DatasetSelector.js","sources":["../../../../src/components/QueryEditor/DatasetSelector.tsx"],"sourcesContent":["import { useEffect } from 'react';\nimport { useAsync } from 'react-use';\n\nimport { type SelectableValue } from '@grafana/data';\nimport { Select } from '@grafana/ui';\n\nimport { type DB, type ResourceSelectorProps, toOption } from './types';\n\ninterface DatasetSelectorProps extends ResourceSelectorProps {\n db: DB;\n dataset?: string;\n catalog?: string; // When provided, fetch schemas instead of datasets\n value: string | null;\n applyDefault?: boolean;\n disabled?: boolean;\n onChange: (v: SelectableValue) => void;\n inputId?: string;\n enableCatalogs?: boolean;\n 'data-testid'?: string;\n}\n\nexport const DatasetSelector = ({\n db,\n dataset,\n catalog,\n value,\n onChange,\n disabled,\n className,\n applyDefault,\n inputId,\n enableCatalogs,\n 'data-testid': dataTestId,\n}: DatasetSelectorProps) => {\n const state = useAsync(async () => {\n // If a default dataset is provided, use it\n if (dataset) {\n onChange(toOption(dataset));\n return [toOption(dataset)];\n }\n\n // Fetch datasets - when catalog is provided, db.datasets(catalog) returns schemas for that catalog\n const datasets = await db.datasets(catalog);\n return datasets.map(toOption);\n }, [catalog]);\n\n useEffect(() => {\n if (!applyDefault) {\n return;\n }\n // Set default dataset when values are fetched\n if (!value) {\n if (state.value && state.value[0]) {\n onChange(state.value[0]);\n }\n } else {\n if (state.value && state.value.find((v) => v.value === value) === undefined) {\n // if value is set and newly fetched values does not contain selected value\n if (state.value.length > 0) {\n onChange(state.value[0]);\n }\n }\n }\n }, [state.value, value, applyDefault, onChange]);\n\n return (\n <Select\n inputId={inputId}\n className={className}\n aria-label=\"Dataset selector\"\n value={value}\n options={state.value}\n onChange={onChange}\n disabled={disabled}\n isLoading={state.loading}\n menuShouldPortal={true}\n data-testid={dataTestId}\n placeholder={enableCatalogs ? 'Select schema' : 'Select dataset'}\n />\n );\n};\n"],"names":[],"mappings":";;;;;;;AAqBO,MAAM,kBAAkB,CAAC;AAAA,EAC9B,EAAA;AAAA,EACA,OAAA;AAAA,EACA,OAAA;AAAA,EACA,KAAA;AAAA,EACA,QAAA;AAAA,EACA,QAAA;AAAA,EACA,SAAA;AAAA,EACA,YAAA;AAAA,EACA,OAAA;AAAA,EACA,cAAA;AAAA,EACA,aAAe,EAAA;AACjB,CAA4B,KAAA;AAC1B,EAAM,MAAA,KAAA,GAAQ,SAAS,YAAY;AAEjC,IAAA,IAAI,OAAS,EAAA;AACX,MAAS,QAAA,CAAA,QAAA,CAAS,OAAO,CAAC,CAAA;AAC1B,MAAO,OAAA,CAAC,QAAS,CAAA,OAAO,CAAC,CAAA;AAAA;AAI3B,IAAA,MAAM,QAAW,GAAA,MAAM,EAAG,CAAA,QAAA,CAAS,OAAO,CAAA;AAC1C,IAAO,OAAA,QAAA,CAAS,IAAI,QAAQ,CAAA;AAAA,GAC9B,EAAG,CAAC,OAAO,CAAC,CAAA;AAEZ,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,CAAC,YAAc,EAAA;AACjB,MAAA;AAAA;AAGF,IAAA,IAAI,CAAC,KAAO,EAAA;AACV,MAAA,IAAI,KAAM,CAAA,KAAA,IAAS,KAAM,CAAA,KAAA,CAAM,CAAC,CAAG,EAAA;AACjC,QAAS,QAAA,CAAA,KAAA,CAAM,KAAM,CAAA,CAAC,CAAC,CAAA;AAAA;AACzB,KACK,MAAA;AACL,MAAI,IAAA,KAAA,CAAM,KAAS,IAAA,KAAA,CAAM,KAAM,CAAA,IAAA,CAAK,CAAC,CAAA,KAAM,CAAE,CAAA,KAAA,KAAU,KAAK,CAAA,KAAM,SAAW,EAAA;AAE3E,QAAI,IAAA,KAAA,CAAM,KAAM,CAAA,MAAA,GAAS,CAAG,EAAA;AAC1B,UAAS,QAAA,CAAA,KAAA,CAAM,KAAM,CAAA,CAAC,CAAC,CAAA;AAAA;AACzB;AACF;AACF,KACC,CAAC,KAAA,CAAM,OAAO,KAAO,EAAA,YAAA,EAAc,QAAQ,CAAC,CAAA;AAE/C,EACE,uBAAA,GAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACC,OAAA;AAAA,MACA,SAAA;AAAA,MACA,YAAW,EAAA,kBAAA;AAAA,MACX,KAAA;AAAA,MACA,SAAS,KAAM,CAAA,KAAA;AAAA,MACf,QAAA;AAAA,MACA,QAAA;AAAA,MACA,WAAW,KAAM,CAAA,OAAA;AAAA,MACjB,gBAAkB,EAAA,IAAA;AAAA,MAClB,aAAa,EAAA,UAAA;AAAA,MACb,WAAA,EAAa,iBAAiB,eAAkB,GAAA;AAAA;AAAA,GAClD;AAEJ;;;;"}
@@ -66,14 +66,17 @@ function SqlQueryEditor({ datasource, query, onChange, onRunQuery, range }) {
66
66
  if (loading || error) {
67
67
  return null;
68
68
  }
69
+ const catalogsEnabled = db.disableCatalogs === false;
70
+ const datasetsEnabled = !db.disableDatasets;
71
+ const effectiveEnableDatasets = catalogsEnabled ? true : datasetsEnabled;
69
72
  return /* @__PURE__ */ jsxs(Fragment, { children: [
70
73
  /* @__PURE__ */ jsx(
71
74
  QueryHeader,
72
75
  {
73
76
  db,
74
77
  defaultDataset: defaultDataset || "",
75
- enableDatasets: !db.disableDatasets,
76
- enableCatalogs: db.disableCatalogs === false,
78
+ enableDatasets: effectiveEnableDatasets,
79
+ enableCatalogs: catalogsEnabled,
77
80
  onChange: onQueryHeaderChange,
78
81
  onRunQuery,
79
82
  onQueryRowChange: setQueryRowFilter,
@@ -1 +1 @@
1
- {"version":3,"file":"QueryEditor.js","sources":["../../../../src/components/QueryEditor/QueryEditor.tsx"],"sourcesContent":["import { useCallback, useEffect, useState } from 'react';\nimport { useAsync } from 'react-use';\n\nimport { type QueryEditorProps } from '@grafana/data';\n\nimport { applyQueryDefaults } from './defaults';\nimport { type SQLQuery, type QueryRowFilter, type SQLOptions, EditorMode } from './types';\nimport { haveColumns } from './utils/sql.utils';\n\nimport { QueryHeader } from './QueryHeader';\nimport { RawEditor } from './query-editor-raw/RawEditor';\nimport { VisualEditor } from './visual-query-builder/VisualEditor';\n\nimport { type SqlDatasource } from '../../datasource/SqlDatasource';\nimport { Space } from './Space';\n\ninterface Props extends QueryEditorProps<SqlDatasource, SQLQuery, SQLOptions> {}\n\nexport function SqlQueryEditor({ datasource, query, onChange, onRunQuery, range }: Props) {\n const [isQueryRunnable, setIsQueryRunnable] = useState(true);\n const db = datasource.getDB();\n const defaultDataset = datasource.dataset;\n\n const { loading, error } = useAsync(async () => {\n return () => {\n if (datasource.getDB(datasource.id).init !== undefined) {\n datasource.getDB(datasource.id).init!();\n }\n };\n }, [datasource]);\n\n const queryWithDefaults = applyQueryDefaults(query);\n const [queryRowFilter, setQueryRowFilter] = useState<QueryRowFilter>({\n filter: !!queryWithDefaults.sql?.whereString,\n group: !!queryWithDefaults.sql?.groupBy?.[0]?.property.name,\n order: !!queryWithDefaults.sql?.orderBy?.property.name,\n preview: true,\n });\n const [queryToValidate, setQueryToValidate] = useState(queryWithDefaults);\n\n useEffect(() => {\n return () => {\n if (datasource.getDB(datasource.id).dispose !== undefined) {\n datasource.getDB(datasource.id).dispose!();\n }\n };\n }, [datasource]);\n\n const processQuery = useCallback(\n (q: SQLQuery) => {\n if (isQueryValid(q) && onRunQuery) {\n onRunQuery();\n }\n },\n [onRunQuery]\n );\n\n const onQueryChange = (q: SQLQuery, process = true) => {\n setQueryToValidate(q);\n onChange(q);\n\n if (haveColumns(q.sql?.columns) && q.sql?.columns.some((c) => c.name) && !queryRowFilter.group) {\n setQueryRowFilter({ ...queryRowFilter, group: true });\n }\n\n if (process) {\n processQuery(q);\n }\n };\n\n const onQueryHeaderChange = (q: SQLQuery) => {\n setQueryToValidate(q);\n onChange(q);\n };\n\n if (loading || error) {\n return null;\n }\n\n return (\n <>\n <QueryHeader\n db={db}\n defaultDataset={defaultDataset || ''}\n enableDatasets={!db.disableDatasets}\n enableCatalogs={db.disableCatalogs === false}\n onChange={onQueryHeaderChange}\n onRunQuery={onRunQuery}\n onQueryRowChange={setQueryRowFilter}\n queryRowFilter={queryRowFilter}\n query={queryWithDefaults}\n isQueryRunnable={isQueryRunnable}\n labels={datasource.getDB(datasource.id)?.labels}\n />\n\n <Space v={0.5} />\n\n {queryWithDefaults.editorMode !== EditorMode.Code && (\n <VisualEditor\n db={db}\n query={queryWithDefaults}\n onChange={(q: SQLQuery) => onQueryChange(q, false)}\n queryRowFilter={queryRowFilter}\n onValidate={setIsQueryRunnable}\n range={range}\n />\n )}\n\n {queryWithDefaults.editorMode === EditorMode.Code && (\n <RawEditor\n db={db}\n query={queryWithDefaults}\n queryToValidate={queryToValidate}\n onChange={onQueryChange}\n onRunQuery={onRunQuery}\n onValidate={setIsQueryRunnable}\n range={range}\n />\n )}\n </>\n );\n}\n\nconst isQueryValid = (q: SQLQuery) => {\n return Boolean(q.rawSql);\n};\n"],"names":["_a","_b"],"mappings":"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"}
1
+ {"version":3,"file":"QueryEditor.js","sources":["../../../../src/components/QueryEditor/QueryEditor.tsx"],"sourcesContent":["import { useCallback, useEffect, useState } from 'react';\nimport { useAsync } from 'react-use';\n\nimport { type QueryEditorProps } from '@grafana/data';\n\nimport { applyQueryDefaults } from './defaults';\nimport { type SQLQuery, type QueryRowFilter, type SQLOptions, EditorMode } from './types';\nimport { haveColumns } from './utils/sql.utils';\n\nimport { QueryHeader } from './QueryHeader';\nimport { RawEditor } from './query-editor-raw/RawEditor';\nimport { VisualEditor } from './visual-query-builder/VisualEditor';\n\nimport { type SqlDatasource } from '../../datasource/SqlDatasource';\nimport { Space } from './Space';\n\ninterface Props extends QueryEditorProps<SqlDatasource, SQLQuery, SQLOptions> {}\n\nexport function SqlQueryEditor({ datasource, query, onChange, onRunQuery, range }: Props) {\n const [isQueryRunnable, setIsQueryRunnable] = useState(true);\n const db = datasource.getDB();\n const defaultDataset = datasource.dataset;\n\n const { loading, error } = useAsync(async () => {\n return () => {\n if (datasource.getDB(datasource.id).init !== undefined) {\n datasource.getDB(datasource.id).init!();\n }\n };\n }, [datasource]);\n\n const queryWithDefaults = applyQueryDefaults(query);\n const [queryRowFilter, setQueryRowFilter] = useState<QueryRowFilter>({\n filter: !!queryWithDefaults.sql?.whereString,\n group: !!queryWithDefaults.sql?.groupBy?.[0]?.property.name,\n order: !!queryWithDefaults.sql?.orderBy?.property.name,\n preview: true,\n });\n const [queryToValidate, setQueryToValidate] = useState(queryWithDefaults);\n\n useEffect(() => {\n return () => {\n if (datasource.getDB(datasource.id).dispose !== undefined) {\n datasource.getDB(datasource.id).dispose!();\n }\n };\n }, [datasource]);\n\n const processQuery = useCallback(\n (q: SQLQuery) => {\n if (isQueryValid(q) && onRunQuery) {\n onRunQuery();\n }\n },\n [onRunQuery]\n );\n\n const onQueryChange = (q: SQLQuery, process = true) => {\n setQueryToValidate(q);\n onChange(q);\n\n if (haveColumns(q.sql?.columns) && q.sql?.columns.some((c) => c.name) && !queryRowFilter.group) {\n setQueryRowFilter({ ...queryRowFilter, group: true });\n }\n\n if (process) {\n processQuery(q);\n }\n };\n\n const onQueryHeaderChange = (q: SQLQuery) => {\n setQueryToValidate(q);\n onChange(q);\n };\n\n if (loading || error) {\n return null;\n }\n\n const catalogsEnabled = db.disableCatalogs === false;\n const datasetsEnabled = !db.disableDatasets;\n\n // When catalogs are enabled, datasets MUST be enabled (they act as schema selector)\n const effectiveEnableDatasets = catalogsEnabled ? true : datasetsEnabled;\n\n return (\n <>\n <QueryHeader\n db={db}\n defaultDataset={defaultDataset || ''}\n enableDatasets={effectiveEnableDatasets}\n enableCatalogs={catalogsEnabled}\n onChange={onQueryHeaderChange}\n onRunQuery={onRunQuery}\n onQueryRowChange={setQueryRowFilter}\n queryRowFilter={queryRowFilter}\n query={queryWithDefaults}\n isQueryRunnable={isQueryRunnable}\n labels={datasource.getDB(datasource.id)?.labels}\n />\n\n <Space v={0.5} />\n\n {queryWithDefaults.editorMode !== EditorMode.Code && (\n <VisualEditor\n db={db}\n query={queryWithDefaults}\n onChange={(q: SQLQuery) => onQueryChange(q, false)}\n queryRowFilter={queryRowFilter}\n onValidate={setIsQueryRunnable}\n range={range}\n />\n )}\n\n {queryWithDefaults.editorMode === EditorMode.Code && (\n <RawEditor\n db={db}\n query={queryWithDefaults}\n queryToValidate={queryToValidate}\n onChange={onQueryChange}\n onRunQuery={onRunQuery}\n onValidate={setIsQueryRunnable}\n range={range}\n />\n )}\n </>\n );\n}\n\nconst isQueryValid = (q: SQLQuery) => {\n return Boolean(q.rawSql);\n};\n"],"names":["_a","_b"],"mappings":"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"}
@@ -5,7 +5,6 @@ import '@grafana/data';
5
5
  import { ConfirmModal } from './ConfirmModal.js';
6
6
  import { DatasetSelector } from './DatasetSelector.js';
7
7
  import { CatalogSelector } from './CatalogSelector.js';
8
- import { SchemaSelector } from './SchemaSelector.js';
9
8
  import { TableSelector } from './TableSelector.js';
10
9
  import { InlineSwitch, RadioButtonGroup } from '@grafana/ui';
11
10
  import { EditorMode, QUERY_FORMAT_OPTIONS, QueryFormat } from './types.js';
@@ -41,6 +40,7 @@ function QueryHeader({
41
40
  const toRawSql = getRawSqlFn(db);
42
41
  const htmlId = useId();
43
42
  const catalogsEnabled = enableCatalogs != null ? enableCatalogs : db.disableCatalogs === false;
43
+ const effectiveEnableDatasets = catalogsEnabled ? true : enableDatasets;
44
44
  const onEditorModeChange = useCallback(
45
45
  (newEditorMode) => {
46
46
  if (editorMode === EditorMode.Code) {
@@ -56,12 +56,13 @@ function QueryHeader({
56
56
  onChange(next);
57
57
  };
58
58
  const onDatasetChange = (e) => {
59
- if (e.value === query.dataset) {
59
+ const datasetValue = e.value || undefined;
60
+ if (datasetValue === query.dataset) {
60
61
  return;
61
62
  }
62
63
  const next = {
63
64
  ...query,
64
- dataset: e.value,
65
+ dataset: datasetValue,
65
66
  table: undefined,
66
67
  sql: undefined,
67
68
  rawSql: ""
@@ -69,26 +70,15 @@ function QueryHeader({
69
70
  onChange(next);
70
71
  };
71
72
  const onCatalogChange = (catalog) => {
72
- if (catalog === query.catalog) {
73
+ const catalogValue = catalog || undefined;
74
+ if (catalogValue === query.catalog) {
73
75
  return;
74
76
  }
75
77
  const next = {
76
78
  ...query,
77
- catalog: catalog || undefined,
78
- schema: undefined,
79
- table: undefined,
80
- sql: undefined,
81
- rawSql: ""
82
- };
83
- onChange(next);
84
- };
85
- const onSchemaChange = (schema) => {
86
- if (schema === query.schema) {
87
- return;
88
- }
89
- const next = {
90
- ...query,
91
- schema: schema || undefined,
79
+ catalog: catalogValue,
80
+ dataset: undefined,
81
+ // Reset dataset (which acts as schema when catalog is present)
92
82
  table: undefined,
93
83
  sql: undefined,
94
84
  rawSql: ""
@@ -197,45 +187,41 @@ function QueryHeader({
197
187
  editorMode === EditorMode.Builder && /* @__PURE__ */ jsxs(Fragment, { children: [
198
188
  /* @__PURE__ */ jsx(Space, { v: 0.5 }),
199
189
  /* @__PURE__ */ jsxs(EditorRow, { children: [
200
- enableDatasets === true && !catalogsEnabled && /* @__PURE__ */ jsx(EditorField, { label: labels.get("dataset") || "Dataset", width: 25, children: /* @__PURE__ */ jsx(
201
- DatasetSelector,
190
+ catalogsEnabled && /* @__PURE__ */ jsx(EditorField, { label: labels.get("catalog") || "Catalog", width: 25, children: /* @__PURE__ */ jsx(
191
+ CatalogSelector,
202
192
  {
203
193
  db,
204
- inputId: `sql-dataset-${htmlId}`,
205
- dataset: defaultDataset,
206
- value: query.dataset === undefined ? null : query.dataset,
207
- onChange: onDatasetChange
194
+ inputId: `sql-catalog-${htmlId}`,
195
+ value: query.catalog === undefined ? null : query.catalog,
196
+ onChange: onCatalogChange
208
197
  }
209
198
  ) }),
210
- catalogsEnabled && /* @__PURE__ */ jsxs(Fragment, { children: [
211
- /* @__PURE__ */ jsx(EditorField, { label: labels.get("catalog") || "Catalog", width: 25, children: /* @__PURE__ */ jsx(
212
- CatalogSelector,
213
- {
214
- db,
215
- inputId: `sql-catalog-${htmlId}`,
216
- value: query.catalog === undefined ? null : query.catalog,
217
- onChange: onCatalogChange
218
- }
219
- ) }),
220
- /* @__PURE__ */ jsx(EditorField, { label: labels.get("schema") || "Schema", width: 25, children: /* @__PURE__ */ jsx(
221
- SchemaSelector,
222
- {
223
- db,
224
- inputId: `sql-schema-${htmlId}`,
225
- catalog: query.catalog,
226
- value: query.schema === undefined ? null : query.schema,
227
- onChange: onSchemaChange
228
- }
229
- ) })
230
- ] }),
231
- /* @__PURE__ */ jsx(EditorField, { label: "Table", width: 25, children: /* @__PURE__ */ jsx(
199
+ effectiveEnableDatasets && /* @__PURE__ */ jsx(
200
+ EditorField,
201
+ {
202
+ label: catalogsEnabled ? labels.get("schema") || "Schema" : labels.get("dataset") || "Dataset",
203
+ width: 25,
204
+ children: /* @__PURE__ */ jsx(
205
+ DatasetSelector,
206
+ {
207
+ db,
208
+ inputId: catalogsEnabled ? `sql-schema-${htmlId}` : `sql-dataset-${htmlId}`,
209
+ "data-testid": catalogsEnabled ? "schema-selector" : "dataset-selector",
210
+ dataset: catalogsEnabled ? undefined : defaultDataset,
211
+ value: query.dataset === undefined ? null : query.dataset,
212
+ onChange: onDatasetChange,
213
+ catalog: catalogsEnabled ? query.catalog : undefined
214
+ }
215
+ )
216
+ }
217
+ ),
218
+ /* @__PURE__ */ jsx(EditorField, { label: labels.get("table") || "Table", width: 25, children: /* @__PURE__ */ jsx(
232
219
  TableSelector,
233
220
  {
234
221
  db,
235
222
  inputId: `sql-table-${htmlId}`,
236
- dataset: catalogsEnabled ? undefined : query.dataset || defaultDataset,
223
+ dataset: query.dataset || (catalogsEnabled ? undefined : defaultDataset),
237
224
  catalog: catalogsEnabled ? query.catalog : undefined,
238
- schema: catalogsEnabled ? query.schema : undefined,
239
225
  query,
240
226
  value: query.table === undefined ? null : query.table,
241
227
  onChange: onTableChange,
@@ -1 +1 @@
1
- {"version":3,"file":"QueryHeader.js","sources":["../../../../src/components/QueryEditor/QueryHeader.tsx"],"sourcesContent":["import { useCallback, useState, useId } from 'react';\nimport { useCopyToClipboard } from 'react-use';\n\nimport { type SelectableValue } from '@grafana/data';\n\nimport { ConfirmModal } from './ConfirmModal';\nimport { DatasetSelector } from './DatasetSelector';\nimport { CatalogSelector } from './CatalogSelector';\nimport { SchemaSelector } from './SchemaSelector';\nimport { TableSelector } from './TableSelector';\nimport { InlineSwitch, RadioButtonGroup } from '@grafana/ui';\nimport { type QueryWithDefaults } from './defaults';\nimport { EditorField } from './EditorField';\nimport { EditorHeader } from './EditorHeader';\nimport { EditorRow } from './EditorRow';\nimport { FlexItem } from './FlexItem';\nimport { InlineSelect } from './InlineSelect';\nimport { Space } from './Space';\nimport { RunQueryButton } from './RunQueryButton';\nimport { type DB, type SQLQuery, type QueryRowFilter, EditorMode, QueryFormat, QUERY_FORMAT_OPTIONS } from './types';\nimport { getRawSqlFn } from './utils/sql.utils';\n\ninterface QueryHeaderProps {\n db: DB;\n defaultDataset: string;\n enableDatasets: boolean;\n enableCatalogs?: boolean;\n query: QueryWithDefaults;\n onChange: (query: SQLQuery) => void;\n onRunQuery: () => void;\n onQueryRowChange: (queryRowFilter: QueryRowFilter) => void;\n queryRowFilter: QueryRowFilter;\n isQueryRunnable: boolean;\n labels?: Map<string, string>;\n}\n\nconst editorModes = [\n { label: 'Builder', value: EditorMode.Builder },\n { label: 'Code', value: EditorMode.Code },\n];\n\nexport function QueryHeader({\n db,\n defaultDataset,\n enableDatasets,\n enableCatalogs,\n query,\n queryRowFilter,\n onChange,\n onRunQuery,\n onQueryRowChange,\n isQueryRunnable,\n labels = new Map([['dataset', 'Dataset']]),\n}: QueryHeaderProps) {\n const { editorMode } = query;\n const [_, copyToClipboard] = useCopyToClipboard();\n const [showConfirm, setShowConfirm] = useState(false);\n const toRawSql = getRawSqlFn(db);\n const htmlId = useId();\n\n // Derive enableCatalogs from db.disableCatalogs when not explicitly provided\n // Catalogs are disabled by default (when disableCatalogs is undefined or true)\n const catalogsEnabled = enableCatalogs ?? db.disableCatalogs === false;\n\n const onEditorModeChange = useCallback(\n (newEditorMode: EditorMode) => {\n if (editorMode === EditorMode.Code) {\n setShowConfirm(true);\n return;\n }\n onChange({ ...query, editorMode: newEditorMode });\n },\n [editorMode, onChange, query]\n );\n\n const onFormatChange = (e: SelectableValue) => {\n const next = { ...query, format: e.value !== undefined ? e.value : QueryFormat.Table };\n onChange(next);\n };\n\n const onDatasetChange = (e: SelectableValue) => {\n if (e.value === query.dataset) {\n return;\n }\n\n const next = {\n ...query,\n dataset: e.value,\n table: undefined,\n sql: undefined,\n rawSql: '',\n };\n\n onChange(next);\n };\n\n const onCatalogChange = (catalog: string | null) => {\n if (catalog === query.catalog) {\n return;\n }\n\n const next: SQLQuery = {\n ...query,\n catalog: catalog || undefined,\n schema: undefined,\n table: undefined,\n sql: undefined,\n rawSql: '',\n };\n onChange(next);\n };\n\n const onSchemaChange = (schema: string | null) => {\n if (schema === query.schema) {\n return;\n }\n\n const next: SQLQuery = {\n ...query,\n schema: schema || undefined,\n table: undefined,\n sql: undefined,\n rawSql: '',\n };\n onChange(next);\n };\n\n const onTableChange = (e: SelectableValue) => {\n if (e.value === query.table) {\n return;\n }\n\n const next: SQLQuery = {\n ...query,\n table: e.value,\n sql: undefined,\n rawSql: '',\n };\n onChange(next);\n };\n\n return (\n <>\n <EditorHeader>\n <InlineSelect\n label=\"Format\"\n value={query.format}\n placeholder=\"Select format\"\n menuShouldPortal\n onChange={onFormatChange}\n options={QUERY_FORMAT_OPTIONS}\n />\n {editorMode === EditorMode.Builder && (\n <>\n <InlineSwitch\n id={`sql-filter-${htmlId}`}\n label=\"Filter\"\n transparent={true}\n showLabel={true}\n value={queryRowFilter.filter}\n onChange={(ev) =>\n ev.target instanceof HTMLInputElement &&\n onQueryRowChange({ ...queryRowFilter, filter: ev.target.checked })\n }\n />\n\n <InlineSwitch\n id={`sql-group-${htmlId}`}\n label=\"Group\"\n transparent={true}\n showLabel={true}\n value={queryRowFilter.group}\n onChange={(ev) =>\n ev.target instanceof HTMLInputElement &&\n onQueryRowChange({ ...queryRowFilter, group: ev.target.checked })\n }\n />\n\n <InlineSwitch\n id={`sql-order-${htmlId}`}\n label=\"Order\"\n transparent={true}\n showLabel={true}\n value={queryRowFilter.order}\n onChange={(ev) =>\n ev.target instanceof HTMLInputElement &&\n onQueryRowChange({ ...queryRowFilter, order: ev.target.checked })\n }\n />\n\n <InlineSwitch\n id={`sql-preview-${htmlId}`}\n label=\"Preview\"\n transparent={true}\n showLabel={true}\n value={queryRowFilter.preview}\n onChange={(ev) =>\n ev.target instanceof HTMLInputElement &&\n onQueryRowChange({ ...queryRowFilter, preview: ev.target.checked })\n }\n />\n </>\n )}\n\n <FlexItem grow={1} />\n\n <RunQueryButton queryInvalid={!isQueryRunnable} onClick={() => onRunQuery()} />\n\n <RadioButtonGroup options={editorModes} size=\"sm\" value={editorMode} onChange={onEditorModeChange} />\n\n <ConfirmModal\n isOpen={showConfirm}\n onCopy={() => {\n setShowConfirm(false);\n copyToClipboard(query.rawSql!);\n onChange({\n ...query,\n rawSql: toRawSql(query),\n editorMode: EditorMode.Builder,\n });\n }}\n onDiscard={() => {\n setShowConfirm(false);\n onChange({\n ...query,\n rawSql: toRawSql(query),\n editorMode: EditorMode.Builder,\n });\n }}\n onCancel={() => setShowConfirm(false)}\n />\n </EditorHeader>\n\n {editorMode === EditorMode.Builder && (\n <>\n <Space v={0.5} />\n\n <EditorRow>\n {enableDatasets === true && !catalogsEnabled && (\n <EditorField label={labels.get('dataset') || 'Dataset'} width={25}>\n <DatasetSelector\n db={db}\n inputId={`sql-dataset-${htmlId}`}\n dataset={defaultDataset}\n value={query.dataset === undefined ? null : query.dataset}\n onChange={onDatasetChange}\n />\n </EditorField>\n )}\n\n {catalogsEnabled && (\n <>\n <EditorField label={labels.get('catalog') || 'Catalog'} width={25}>\n <CatalogSelector\n db={db}\n inputId={`sql-catalog-${htmlId}`}\n value={query.catalog === undefined ? null : query.catalog}\n onChange={onCatalogChange}\n />\n </EditorField>\n\n <EditorField label={labels.get('schema') || 'Schema'} width={25}>\n <SchemaSelector\n db={db}\n inputId={`sql-schema-${htmlId}`}\n catalog={query.catalog}\n value={query.schema === undefined ? null : query.schema}\n onChange={onSchemaChange}\n />\n </EditorField>\n </>\n )}\n\n <EditorField label=\"Table\" width={25}>\n <TableSelector\n db={db}\n inputId={`sql-table-${htmlId}`}\n dataset={catalogsEnabled ? undefined : query.dataset || defaultDataset}\n catalog={catalogsEnabled ? query.catalog : undefined}\n schema={catalogsEnabled ? query.schema : undefined}\n query={query}\n value={query.table === undefined ? null : query.table}\n onChange={onTableChange}\n enableCatalogs={catalogsEnabled}\n applyDefault\n />\n </EditorField>\n </EditorRow>\n </>\n )}\n </>\n );\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"QueryHeader.js","sources":["../../../../src/components/QueryEditor/QueryHeader.tsx"],"sourcesContent":["import { useCallback, useState, useId } from 'react';\nimport { useCopyToClipboard } from 'react-use';\n\nimport { type SelectableValue } from '@grafana/data';\n\nimport { ConfirmModal } from './ConfirmModal';\nimport { DatasetSelector } from './DatasetSelector';\nimport { CatalogSelector } from './CatalogSelector';\nimport { TableSelector } from './TableSelector';\nimport { InlineSwitch, RadioButtonGroup } from '@grafana/ui';\nimport { type QueryWithDefaults } from './defaults';\nimport { EditorField } from './EditorField';\nimport { EditorHeader } from './EditorHeader';\nimport { EditorRow } from './EditorRow';\nimport { FlexItem } from './FlexItem';\nimport { InlineSelect } from './InlineSelect';\nimport { Space } from './Space';\nimport { RunQueryButton } from './RunQueryButton';\nimport { type DB, type SQLQuery, type QueryRowFilter, EditorMode, QueryFormat, QUERY_FORMAT_OPTIONS } from './types';\nimport { getRawSqlFn } from './utils/sql.utils';\n\ninterface QueryHeaderProps {\n db: DB;\n defaultDataset: string;\n enableDatasets: boolean;\n enableCatalogs?: boolean;\n query: QueryWithDefaults;\n onChange: (query: SQLQuery) => void;\n onRunQuery: () => void;\n onQueryRowChange: (queryRowFilter: QueryRowFilter) => void;\n queryRowFilter: QueryRowFilter;\n isQueryRunnable: boolean;\n labels?: Map<string, string>;\n}\n\nconst editorModes = [\n { label: 'Builder', value: EditorMode.Builder },\n { label: 'Code', value: EditorMode.Code },\n];\n\nexport function QueryHeader({\n db,\n defaultDataset,\n enableDatasets,\n enableCatalogs,\n query,\n queryRowFilter,\n onChange,\n onRunQuery,\n onQueryRowChange,\n isQueryRunnable,\n labels = new Map([['dataset', 'Dataset']]),\n}: QueryHeaderProps) {\n const { editorMode } = query;\n const [_, copyToClipboard] = useCopyToClipboard();\n const [showConfirm, setShowConfirm] = useState(false);\n const toRawSql = getRawSqlFn(db);\n const htmlId = useId();\n\n // Derive enableCatalogs from db.disableCatalogs when not explicitly provided\n // Catalogs are disabled by default (when disableCatalogs is undefined or true)\n const catalogsEnabled = enableCatalogs ?? db.disableCatalogs === false;\n\n // When catalogs are enabled, datasets MUST be enabled (they act as schema selector)\n // This ensures the dataset selector is shown to select schemas\n const effectiveEnableDatasets = catalogsEnabled ? true : enableDatasets;\n\n const onEditorModeChange = useCallback(\n (newEditorMode: EditorMode) => {\n if (editorMode === EditorMode.Code) {\n setShowConfirm(true);\n return;\n }\n onChange({ ...query, editorMode: newEditorMode });\n },\n [editorMode, onChange, query]\n );\n\n const onFormatChange = (e: SelectableValue) => {\n const next = { ...query, format: e.value !== undefined ? e.value : QueryFormat.Table };\n onChange(next);\n };\n\n const onDatasetChange = (e: SelectableValue) => {\n // dataset field has dual meaning:\n // - When catalogs enabled: dataset = schema\n // - When catalogs disabled: dataset = dataset\n const datasetValue = e.value || undefined;\n if (datasetValue === query.dataset) {\n return;\n }\n const next: SQLQuery = {\n ...query,\n dataset: datasetValue,\n table: undefined,\n sql: undefined,\n rawSql: '',\n };\n onChange(next);\n };\n\n const onCatalogChange = (catalog: string | null) => {\n const catalogValue = catalog || undefined;\n if (catalogValue === query.catalog) {\n return;\n }\n\n const next: SQLQuery = {\n ...query,\n catalog: catalogValue,\n dataset: undefined, // Reset dataset (which acts as schema when catalog is present)\n table: undefined,\n sql: undefined,\n rawSql: '',\n };\n onChange(next);\n };\n\n const onTableChange = (e: SelectableValue) => {\n if (e.value === query.table) {\n return;\n }\n\n const next: SQLQuery = {\n ...query,\n table: e.value,\n sql: undefined,\n rawSql: '',\n };\n onChange(next);\n };\n\n return (\n <>\n <EditorHeader>\n <InlineSelect\n label=\"Format\"\n value={query.format}\n placeholder=\"Select format\"\n menuShouldPortal\n onChange={onFormatChange}\n options={QUERY_FORMAT_OPTIONS}\n />\n {editorMode === EditorMode.Builder && (\n <>\n <InlineSwitch\n id={`sql-filter-${htmlId}`}\n label=\"Filter\"\n transparent={true}\n showLabel={true}\n value={queryRowFilter.filter}\n onChange={(ev) =>\n ev.target instanceof HTMLInputElement &&\n onQueryRowChange({ ...queryRowFilter, filter: ev.target.checked })\n }\n />\n\n <InlineSwitch\n id={`sql-group-${htmlId}`}\n label=\"Group\"\n transparent={true}\n showLabel={true}\n value={queryRowFilter.group}\n onChange={(ev) =>\n ev.target instanceof HTMLInputElement &&\n onQueryRowChange({ ...queryRowFilter, group: ev.target.checked })\n }\n />\n\n <InlineSwitch\n id={`sql-order-${htmlId}`}\n label=\"Order\"\n transparent={true}\n showLabel={true}\n value={queryRowFilter.order}\n onChange={(ev) =>\n ev.target instanceof HTMLInputElement &&\n onQueryRowChange({ ...queryRowFilter, order: ev.target.checked })\n }\n />\n\n <InlineSwitch\n id={`sql-preview-${htmlId}`}\n label=\"Preview\"\n transparent={true}\n showLabel={true}\n value={queryRowFilter.preview}\n onChange={(ev) =>\n ev.target instanceof HTMLInputElement &&\n onQueryRowChange({ ...queryRowFilter, preview: ev.target.checked })\n }\n />\n </>\n )}\n\n <FlexItem grow={1} />\n\n <RunQueryButton queryInvalid={!isQueryRunnable} onClick={() => onRunQuery()} />\n\n <RadioButtonGroup options={editorModes} size=\"sm\" value={editorMode} onChange={onEditorModeChange} />\n\n <ConfirmModal\n isOpen={showConfirm}\n onCopy={() => {\n setShowConfirm(false);\n copyToClipboard(query.rawSql!);\n onChange({\n ...query,\n rawSql: toRawSql(query),\n editorMode: EditorMode.Builder,\n });\n }}\n onDiscard={() => {\n setShowConfirm(false);\n onChange({\n ...query,\n rawSql: toRawSql(query),\n editorMode: EditorMode.Builder,\n });\n }}\n onCancel={() => setShowConfirm(false)}\n />\n </EditorHeader>\n\n {editorMode === EditorMode.Builder && (\n <>\n <Space v={0.5} />\n\n <EditorRow>\n {/* Catalog selector: only when catalogs are not disabled */}\n {catalogsEnabled && (\n <EditorField label={labels.get('catalog') || 'Catalog'} width={25}>\n <CatalogSelector\n db={db}\n inputId={`sql-catalog-${htmlId}`}\n value={query.catalog === undefined ? null : query.catalog}\n onChange={onCatalogChange}\n />\n </EditorField>\n )}\n\n {/* Schema selector when catalogs enabled, dataset selector otherwise */}\n {effectiveEnableDatasets && (\n <EditorField\n label={catalogsEnabled ? labels.get('schema') || 'Schema' : labels.get('dataset') || 'Dataset'}\n width={25}\n >\n <DatasetSelector\n db={db}\n inputId={catalogsEnabled ? `sql-schema-${htmlId}` : `sql-dataset-${htmlId}`}\n data-testid={catalogsEnabled ? 'schema-selector' : 'dataset-selector'}\n dataset={catalogsEnabled ? undefined : defaultDataset}\n value={query.dataset === undefined ? null : query.dataset}\n onChange={onDatasetChange}\n catalog={catalogsEnabled ? query.catalog : undefined}\n />\n </EditorField>\n )}\n\n {/* Table selector: always shown */}\n <EditorField label={labels.get('table') || 'Table'} width={25}>\n <TableSelector\n db={db}\n inputId={`sql-table-${htmlId}`}\n dataset={query.dataset || (catalogsEnabled ? undefined : defaultDataset)}\n catalog={catalogsEnabled ? query.catalog : undefined}\n query={query}\n value={query.table === undefined ? null : query.table}\n onChange={onTableChange}\n enableCatalogs={catalogsEnabled}\n applyDefault\n />\n </EditorField>\n </EditorRow>\n </>\n )}\n </>\n );\n}\n"],"names":[],"mappings":"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"}
@@ -9,7 +9,6 @@ const TableSelector = ({
9
9
  db,
10
10
  dataset,
11
11
  catalog,
12
- schema,
13
12
  value,
14
13
  className,
15
14
  onChange,
@@ -20,19 +19,17 @@ const TableSelector = ({
20
19
  if (!dataset && !catalog) {
21
20
  return [];
22
21
  }
23
- if (enableCatalogs && (!catalog || !schema)) {
22
+ if (enableCatalogs && (!catalog || !dataset)) {
24
23
  return [];
25
24
  }
26
- const tables = await db.tables(dataset, catalog, schema);
25
+ const tables = await db.tables(dataset, catalog);
27
26
  return tables.map(toOption);
28
- }, [dataset, catalog, schema, enableCatalogs]);
29
- const isDisabled = state.loading || enableCatalogs && (!catalog || !schema);
27
+ }, [dataset, catalog, enableCatalogs]);
30
28
  return /* @__PURE__ */ jsx(
31
29
  Select,
32
30
  {
33
31
  inputId,
34
32
  className,
35
- disabled: isDisabled,
36
33
  "aria-label": "Table selector",
37
34
  value,
38
35
  options: state.value,
@@ -1 +1 @@
1
- {"version":3,"file":"TableSelector.js","sources":["../../../../src/components/QueryEditor/TableSelector.tsx"],"sourcesContent":["import { useAsync } from 'react-use';\n\nimport { type SelectableValue, toOption } from '@grafana/data';\nimport { Select } from '@grafana/ui';\nimport { type DB, type ResourceSelectorProps } from './types';\nimport { type QueryWithDefaults } from './defaults';\n\ninterface TableSelectorProps extends ResourceSelectorProps {\n db: DB;\n dataset?: string;\n catalog?: string;\n schema?: string;\n value: string | null;\n query: QueryWithDefaults;\n onChange: (v: SelectableValue) => void;\n inputId?: string;\n enableCatalogs?: boolean;\n}\n\nexport const TableSelector = ({\n db,\n dataset,\n catalog,\n schema,\n value,\n className,\n onChange,\n inputId,\n enableCatalogs,\n}: TableSelectorProps) => {\n const state = useAsync(async () => {\n if (!dataset && !catalog) {\n return [];\n }\n\n // When catalogs are enabled, we need both catalog and schema to load tables\n if (enableCatalogs && (!catalog || !schema)) {\n return [];\n }\n\n const tables = await db.tables(dataset, catalog, schema);\n return tables.map(toOption);\n }, [dataset, catalog, schema, enableCatalogs]);\n\n // Determine if the selector should be disabled\n const isDisabled = state.loading || (enableCatalogs && (!catalog || !schema));\n\n return (\n <Select\n inputId={inputId}\n className={className}\n disabled={isDisabled}\n aria-label=\"Table selector\"\n value={value}\n options={state.value}\n onChange={onChange}\n isLoading={state.loading}\n menuShouldPortal={true}\n placeholder={state.loading ? 'Loading tables' : 'Select table'}\n />\n );\n};\n"],"names":[],"mappings":";;;;;;;AAmBO,MAAM,gBAAgB,CAAC;AAAA,EAC5B,EAAA;AAAA,EACA,OAAA;AAAA,EACA,OAAA;AAAA,EACA,MAAA;AAAA,EACA,KAAA;AAAA,EACA,SAAA;AAAA,EACA,QAAA;AAAA,EACA,OAAA;AAAA,EACA;AACF,CAA0B,KAAA;AACxB,EAAM,MAAA,KAAA,GAAQ,SAAS,YAAY;AACjC,IAAI,IAAA,CAAC,OAAW,IAAA,CAAC,OAAS,EAAA;AACxB,MAAA,OAAO,EAAC;AAAA;AAIV,IAAA,IAAI,cAAmB,KAAA,CAAC,OAAW,IAAA,CAAC,MAAS,CAAA,EAAA;AAC3C,MAAA,OAAO,EAAC;AAAA;AAGV,IAAA,MAAM,SAAS,MAAM,EAAA,CAAG,MAAO,CAAA,OAAA,EAAS,SAAS,MAAM,CAAA;AACvD,IAAO,OAAA,MAAA,CAAO,IAAI,QAAQ,CAAA;AAAA,KACzB,CAAC,OAAA,EAAS,OAAS,EAAA,MAAA,EAAQ,cAAc,CAAC,CAAA;AAG7C,EAAA,MAAM,aAAa,KAAM,CAAA,OAAA,IAAY,cAAmB,KAAA,CAAC,WAAW,CAAC,MAAA,CAAA;AAErE,EACE,uBAAA,GAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACC,OAAA;AAAA,MACA,SAAA;AAAA,MACA,QAAU,EAAA,UAAA;AAAA,MACV,YAAW,EAAA,gBAAA;AAAA,MACX,KAAA;AAAA,MACA,SAAS,KAAM,CAAA,KAAA;AAAA,MACf,QAAA;AAAA,MACA,WAAW,KAAM,CAAA,OAAA;AAAA,MACjB,gBAAkB,EAAA,IAAA;AAAA,MAClB,WAAA,EAAa,KAAM,CAAA,OAAA,GAAU,gBAAmB,GAAA;AAAA;AAAA,GAClD;AAEJ;;;;"}
1
+ {"version":3,"file":"TableSelector.js","sources":["../../../../src/components/QueryEditor/TableSelector.tsx"],"sourcesContent":["import { useAsync } from 'react-use';\n\nimport { type SelectableValue, toOption } from '@grafana/data';\nimport { Select } from '@grafana/ui';\nimport { type DB, type ResourceSelectorProps } from './types';\nimport { type QueryWithDefaults } from './defaults';\n\ninterface TableSelectorProps extends ResourceSelectorProps {\n db: DB;\n dataset?: string; // When catalog is present, this represents the schema. Otherwise, it's the dataset.\n catalog?: string;\n value: string | null;\n query: QueryWithDefaults;\n onChange: (v: SelectableValue) => void;\n inputId?: string;\n enableCatalogs?: boolean;\n}\n\nexport const TableSelector = ({\n db,\n dataset,\n catalog,\n value,\n className,\n onChange,\n inputId,\n enableCatalogs,\n}: TableSelectorProps) => {\n const state = useAsync(async () => {\n if (!dataset && !catalog) {\n return [];\n }\n\n // When catalogs are enabled, we need both catalog and dataset (acting as schema) to load tables\n if (enableCatalogs && (!catalog || !dataset)) {\n return [];\n }\n\n // db.tables(dataset, catalog)\n // dataset acts as schema when catalog is present, otherwise it's the dataset\n const tables = await db.tables(dataset, catalog);\n return tables.map(toOption);\n }, [dataset, catalog, enableCatalogs]);\n\n return (\n <Select\n inputId={inputId}\n className={className}\n aria-label=\"Table selector\"\n value={value}\n options={state.value}\n onChange={onChange}\n isLoading={state.loading}\n menuShouldPortal={true}\n placeholder={state.loading ? 'Loading tables' : 'Select table'}\n />\n );\n};\n"],"names":[],"mappings":";;;;;;;AAkBO,MAAM,gBAAgB,CAAC;AAAA,EAC5B,EAAA;AAAA,EACA,OAAA;AAAA,EACA,OAAA;AAAA,EACA,KAAA;AAAA,EACA,SAAA;AAAA,EACA,QAAA;AAAA,EACA,OAAA;AAAA,EACA;AACF,CAA0B,KAAA;AACxB,EAAM,MAAA,KAAA,GAAQ,SAAS,YAAY;AACjC,IAAI,IAAA,CAAC,OAAW,IAAA,CAAC,OAAS,EAAA;AACxB,MAAA,OAAO,EAAC;AAAA;AAIV,IAAA,IAAI,cAAmB,KAAA,CAAC,OAAW,IAAA,CAAC,OAAU,CAAA,EAAA;AAC5C,MAAA,OAAO,EAAC;AAAA;AAKV,IAAA,MAAM,MAAS,GAAA,MAAM,EAAG,CAAA,MAAA,CAAO,SAAS,OAAO,CAAA;AAC/C,IAAO,OAAA,MAAA,CAAO,IAAI,QAAQ,CAAA;AAAA,GACzB,EAAA,CAAC,OAAS,EAAA,OAAA,EAAS,cAAc,CAAC,CAAA;AAErC,EACE,uBAAA,GAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACC,OAAA;AAAA,MACA,SAAA;AAAA,MACA,YAAW,EAAA,gBAAA;AAAA,MACX,KAAA;AAAA,MACA,SAAS,KAAM,CAAA,KAAA;AAAA,MACf,QAAA;AAAA,MACA,WAAW,KAAM,CAAA,OAAA;AAAA,MACjB,gBAAkB,EAAA,IAAA;AAAA,MAClB,WAAA,EAAa,KAAM,CAAA,OAAA,GAAU,gBAAmB,GAAA;AAAA;AAAA,GAClD;AAEJ;;;;"}
@@ -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;\n catalog?: string;\n schema?: 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: () => Promise<string[]>;\n catalogs?: () => Promise<string[]>;\n schemas?: (catalog?: string) => 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;AAiDY,IAAA,WAAA,qBAAAA,YAAL,KAAA;AACL,EAAAA,YAAA,CAAA,YAAA,CAAA,YAAA,CAAA,GAAA,CAAA,CAAA,GAAA,YAAA;AACA,EAAAA,YAAA,CAAA,YAAA,CAAA,OAAA,CAAA,GAAA,CAAA,CAAA,GAAA,OAAA;AACA,EAAAA,YAAA,CAAA,YAAA,CAAA,MAAA,CAAA,GAAA,CAAA,CAAA,GAAA,MAAA;AACA,EAAAA,YAAA,CAAA,YAAA,CAAA,OAAA,CAAA,GAAA,CAAA,CAAA,GAAA,OAAA;AACA,EAAAA,YAAA,CAAA,YAAA,CAAA,aAAA,CAAA,GAAA,CAAA,CAAA,GAAA,aAAA;AALU,EAAAA,OAAAA,YAAAA;AAAA,CAAA,EAAA,WAAA,IAAA,EAAA;AAQA,IAAA,UAAA,qBAAAC,WAAL,KAAA;AACL,EAAAA,YAAA,SAAU,CAAA,GAAA,SAAA;AACV,EAAAA,YAAA,MAAO,CAAA,GAAA,MAAA;AAFG,EAAAA,OAAAA,WAAAA;AAAA,CAAA,EAAA,UAAA,IAAA,EAAA;AAyDL,MAAM,oBAAuB,GAAA;AAAA,EAClC,EAAE,KAAA,EAAO,aAAe,EAAA,KAAA,EAAO,CAAuB,mBAAA;AAAA,EACtD,EAAE,KAAA,EAAO,OAAS,EAAA,KAAA,EAAO,CAAkB;AAC7C;AAEA,MAAM,mBAAmB,CAAC,KAAA,MAAmB,EAAE,KAAA,EAAO,OAAO,KAAM,EAAA,CAAA;AAE5D,MAAM,YAAW,EAAoB,GAAAC,UAAA,KAAA,IAAA,GAAA,EAAA,GAAA;;;;"}
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;AAiDY,IAAA,WAAA,qBAAAA,YAAL,KAAA;AACL,EAAAA,YAAA,CAAA,YAAA,CAAA,YAAA,CAAA,GAAA,CAAA,CAAA,GAAA,YAAA;AACA,EAAAA,YAAA,CAAA,YAAA,CAAA,OAAA,CAAA,GAAA,CAAA,CAAA,GAAA,OAAA;AACA,EAAAA,YAAA,CAAA,YAAA,CAAA,MAAA,CAAA,GAAA,CAAA,CAAA,GAAA,MAAA;AACA,EAAAA,YAAA,CAAA,YAAA,CAAA,OAAA,CAAA,GAAA,CAAA,CAAA,GAAA,OAAA;AACA,EAAAA,YAAA,CAAA,YAAA,CAAA,aAAA,CAAA,GAAA,CAAA,CAAA,GAAA,aAAA;AALU,EAAAA,OAAAA,YAAAA;AAAA,CAAA,EAAA,WAAA,IAAA,EAAA;AAQA,IAAA,UAAA,qBAAAC,WAAL,KAAA;AACL,EAAAA,YAAA,SAAU,CAAA,GAAA,SAAA;AACV,EAAAA,YAAA,MAAO,CAAA,GAAA,MAAA;AAFG,EAAAA,OAAAA,WAAAA;AAAA,CAAA,EAAA,UAAA,IAAA,EAAA;AAwDL,MAAM,oBAAuB,GAAA;AAAA,EAClC,EAAE,KAAA,EAAO,aAAe,EAAA,KAAA,EAAO,CAAuB,mBAAA;AAAA,EACtD,EAAE,KAAA,EAAO,OAAS,EAAA,KAAA,EAAO,CAAkB;AAC7C;AAEA,MAAM,mBAAmB,CAAC,KAAA,MAAmB,EAAE,KAAA,EAAO,OAAO,KAAM,EAAA,CAAA;AAE5D,MAAM,YAAW,EAAoB,GAAAC,UAAA,KAAA,IAAA,GAAA,EAAA,GAAA;;;;"}
@@ -5,21 +5,19 @@ import '../types.js';
5
5
  function getRawSqlFn(db) {
6
6
  return db.toRawSql ? db.toRawSql : (query) => toRawSql(query, Boolean(db.disableDatasets));
7
7
  }
8
- function toRawSql({ sql, dataset, table }, disableDatasets) {
8
+ function toRawSql({ sql, dataset, catalog, table }, disableDatasets) {
9
9
  var _a, _b, _c, _d;
10
10
  let rawQuery = "";
11
11
  if (!sql || !haveColumns(sql.columns)) {
12
12
  return rawQuery;
13
13
  }
14
14
  rawQuery += createSelectClause(sql.columns);
15
- if (disableDatasets) {
16
- if (table) {
17
- rawQuery += `FROM ${table} `;
18
- }
19
- } else {
20
- if (dataset && table) {
21
- rawQuery += `FROM ${dataset}.${table} `;
22
- }
15
+ if (catalog && dataset && table) {
16
+ rawQuery += `FROM ${catalog}.${dataset}.${table} `;
17
+ } else if (!disableDatasets && dataset && table) {
18
+ rawQuery += `FROM ${dataset}.${table} `;
19
+ } else if (table) {
20
+ rawQuery += `FROM ${table} `;
23
21
  }
24
22
  if (sql.whereString) {
25
23
  rawQuery += `WHERE ${sql.whereString} `;
@@ -1 +1 @@
1
- {"version":3,"file":"sql.utils.js","sources":["../../../../../src/components/QueryEditor/utils/sql.utils.ts"],"sourcesContent":["import { isEmpty } from 'lodash';\n\nimport {\n QueryEditorExpressionType,\n type QueryEditorFunctionExpression,\n type QueryEditorGroupByExpression,\n type QueryEditorPropertyExpression,\n QueryEditorPropertyType,\n} from '../expressions';\nimport { type SQLQuery, type SQLExpression, type DB } from '../types';\n\nexport function getRawSqlFn(db: DB) {\n return db.toRawSql ? db.toRawSql : (query: SQLQuery) => toRawSql(query, Boolean(db.disableDatasets));\n}\n\nexport function toRawSql({ sql, dataset, table }: SQLQuery, disableDatasets: boolean): string {\n let rawQuery = '';\n\n if (!sql || !haveColumns(sql.columns)) {\n return rawQuery;\n }\n\n rawQuery += createSelectClause(sql.columns);\n\n if (disableDatasets) {\n if (table) {\n rawQuery += `FROM ${table} `;\n }\n } else {\n if (dataset && table) {\n rawQuery += `FROM ${dataset}.${table} `;\n }\n }\n\n if (sql.whereString) {\n rawQuery += `WHERE ${sql.whereString} `;\n }\n\n if (sql.groupBy?.[0]?.property.name) {\n const groupBy = sql.groupBy.map((g) => g.property.name).filter((g) => !isEmpty(g));\n rawQuery += `GROUP BY ${groupBy.join(', ')} `;\n }\n\n if (sql.orderBy?.property.name) {\n rawQuery += `ORDER BY ${sql.orderBy.property.name} `;\n }\n\n if (sql.orderBy?.property.name && sql.orderByDirection) {\n rawQuery += `${sql.orderByDirection} `;\n }\n\n if (sql.limit !== undefined && sql.limit >= 0) {\n rawQuery += `LIMIT ${sql.limit} `;\n }\n return rawQuery;\n}\n\nfunction createSelectClause(sqlColumns: NonNullable<SQLExpression['columns']>): string {\n const columns = sqlColumns.map((c) => {\n let rawColumn = '';\n if (c.name) {\n rawColumn += `${c.name}(${c.parameters?.map((p) => `${p.name}`)})`;\n } else {\n rawColumn += `${c.parameters?.map((p) => `${p.name}`)}`;\n }\n return rawColumn;\n });\n return `SELECT ${columns.join(', ')} `;\n}\n\nexport function haveColumns(columns: SQLExpression['columns']): columns is NonNullable<SQLExpression['columns']> {\n if (!columns) {\n return false;\n }\n\n const haveColumn = columns.some((c) => c.parameters?.length || c.parameters?.some((p) => p.name));\n const haveFunction = columns.some((c) => c.name);\n return haveColumn || haveFunction;\n}\n\n/**\n * Creates a GroupByExpression for a specified field\n */\nexport function setGroupByField(field?: string): QueryEditorGroupByExpression {\n return {\n type: QueryEditorExpressionType.GroupBy,\n property: {\n type: QueryEditorPropertyType.String,\n name: field,\n },\n };\n}\n\n/**\n * Creates a PropertyExpression for a specified field\n */\nexport function setPropertyField(field?: string): QueryEditorPropertyExpression {\n return {\n type: QueryEditorExpressionType.Property,\n property: {\n type: QueryEditorPropertyType.String,\n name: field,\n },\n };\n}\n\nexport function createFunctionField(functionName?: string): QueryEditorFunctionExpression {\n return {\n type: QueryEditorExpressionType.Function,\n name: functionName,\n parameters: [],\n };\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sql.utils.js","sources":["../../../../../src/components/QueryEditor/utils/sql.utils.ts"],"sourcesContent":["import { isEmpty } from 'lodash';\n\nimport {\n QueryEditorExpressionType,\n type QueryEditorFunctionExpression,\n type QueryEditorGroupByExpression,\n type QueryEditorPropertyExpression,\n QueryEditorPropertyType,\n} from '../expressions';\nimport { type SQLQuery, type SQLExpression, type DB } from '../types';\n\nexport function getRawSqlFn(db: DB) {\n return db.toRawSql ? db.toRawSql : (query: SQLQuery) => toRawSql(query, Boolean(db.disableDatasets));\n}\n\n/**\n * Converts a SQLQuery object into a raw SQL string.\n *\n * Table reference naming:\n * - When catalog is present: catalog.dataset.table (dataset acts as schema)\n * - When catalog is absent: dataset.table (dataset acts as dataset/schema)\n * - When both are disabled: just table\n *\n * Note: Semantically, the dataset field has dual meaning:\n * - With catalog: dataset = schema (Unity Catalog: catalog.schema.table)\n * - Without catalog: dataset = dataset (Legacy: dataset.table)\n */\nexport function toRawSql({ sql, dataset, catalog, table }: SQLQuery, disableDatasets: boolean): string {\n let rawQuery = '';\n\n if (!sql || !haveColumns(sql.columns)) {\n return rawQuery;\n }\n\n rawQuery += createSelectClause(sql.columns);\n\n // Three-part naming: catalog.dataset.table (dataset acts as schema when catalog is present)\n if (catalog && dataset && table) {\n rawQuery += `FROM ${catalog}.${dataset}.${table} `;\n }\n // Two-part naming: dataset.table (legacy style, only if catalogs not used)\n else if (!disableDatasets && dataset && table) {\n rawQuery += `FROM ${dataset}.${table} `;\n }\n // Just table name (when datasets are disabled or neither catalog nor dataset is present)\n else if (table) {\n rawQuery += `FROM ${table} `;\n }\n\n if (sql.whereString) {\n rawQuery += `WHERE ${sql.whereString} `;\n }\n\n if (sql.groupBy?.[0]?.property.name) {\n const groupBy = sql.groupBy.map((g) => g.property.name).filter((g) => !isEmpty(g));\n rawQuery += `GROUP BY ${groupBy.join(', ')} `;\n }\n\n if (sql.orderBy?.property.name) {\n rawQuery += `ORDER BY ${sql.orderBy.property.name} `;\n }\n\n if (sql.orderBy?.property.name && sql.orderByDirection) {\n rawQuery += `${sql.orderByDirection} `;\n }\n\n if (sql.limit !== undefined && sql.limit >= 0) {\n rawQuery += `LIMIT ${sql.limit} `;\n }\n\n return rawQuery;\n}\n\nfunction createSelectClause(sqlColumns: NonNullable<SQLExpression['columns']>): string {\n const columns = sqlColumns.map((c) => {\n let rawColumn = '';\n if (c.name) {\n rawColumn += `${c.name}(${c.parameters?.map((p) => `${p.name}`)})`;\n } else {\n rawColumn += `${c.parameters?.map((p) => `${p.name}`)}`;\n }\n return rawColumn;\n });\n return `SELECT ${columns.join(', ')} `;\n}\n\nexport function haveColumns(columns: SQLExpression['columns']): columns is NonNullable<SQLExpression['columns']> {\n if (!columns) {\n return false;\n }\n\n const haveColumn = columns.some((c) => c.parameters?.length || c.parameters?.some((p) => p.name));\n const haveFunction = columns.some((c) => c.name);\n return haveColumn || haveFunction;\n}\n\n/**\n * Creates a GroupByExpression for a specified field\n */\nexport function setGroupByField(field?: string): QueryEditorGroupByExpression {\n return {\n type: QueryEditorExpressionType.GroupBy,\n property: {\n type: QueryEditorPropertyType.String,\n name: field,\n },\n };\n}\n\n/**\n * Creates a PropertyExpression for a specified field\n */\nexport function setPropertyField(field?: string): QueryEditorPropertyExpression {\n return {\n type: QueryEditorExpressionType.Property,\n property: {\n type: QueryEditorPropertyType.String,\n name: field,\n },\n };\n}\n\nexport function createFunctionField(functionName?: string): QueryEditorFunctionExpression {\n return {\n type: QueryEditorExpressionType.Function,\n name: functionName,\n parameters: [],\n };\n}\n"],"names":[],"mappings":"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"}