@grafana/plugin-ui 0.14.0-dev.1 → 0.14.1-dsconfig.4bdebf6

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 (253) hide show
  1. package/dist/cjs/index.cjs +3097 -388
  2. package/dist/cjs/index.cjs.map +1 -1
  3. package/dist/cjs/index.d.cts +604 -39
  4. package/dist/cjs/schemas.cjs +13396 -0
  5. package/dist/cjs/schemas.cjs.map +1 -0
  6. package/dist/cjs/schemas.d.cts +338 -0
  7. package/dist/esm/components/ConfigEditor/ConfigSection/ConfigDescriptionLink.js +2 -2
  8. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/AuthorizationHeaderField.js +53 -0
  9. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/AuthorizationHeaderField.js.map +1 -0
  10. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/ComplexFieldNote.js +24 -0
  11. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/ComplexFieldNote.js.map +1 -0
  12. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/DatasourceConfigWizard.js +229 -0
  13. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/DatasourceConfigWizard.js.map +1 -0
  14. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/DatasourceErrorBoundary.js +27 -0
  15. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/DatasourceErrorBoundary.js.map +1 -0
  16. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/IndexedPairEditor.js +124 -0
  17. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/IndexedPairEditor.js.map +1 -0
  18. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/PdcFieldNote.js +34 -0
  19. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/PdcFieldNote.js.map +1 -0
  20. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/SchemaField.js +60 -0
  21. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/SchemaField.js.map +1 -0
  22. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/SecureFieldInput.js +61 -0
  23. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/SecureFieldInput.js.map +1 -0
  24. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/SidebarNav.js +54 -0
  25. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/SidebarNav.js.map +1 -0
  26. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/StringArrayInput.js +84 -0
  27. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/StringArrayInput.js.map +1 -0
  28. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/TabLayout.js +176 -0
  29. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/TabLayout.js.map +1 -0
  30. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/fieldUtils.js +88 -0
  31. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/fieldUtils.js.map +1 -0
  32. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/renderFieldInput.js +106 -0
  33. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/renderFieldInput.js.map +1 -0
  34. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/resolvePluginName.js +30 -0
  35. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/resolvePluginName.js.map +1 -0
  36. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/tabStyles.js +241 -0
  37. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/tabStyles.js.map +1 -0
  38. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/useDatasourceConfigForm.js +284 -0
  39. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/useDatasourceConfigForm.js.map +1 -0
  40. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/useHealthChecks.js +106 -0
  41. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/useHealthChecks.js.map +1 -0
  42. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/wizardStyles.js +124 -0
  43. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/wizardStyles.js.map +1 -0
  44. package/dist/esm/components/DataLinks/DataLink.js +2 -2
  45. package/dist/esm/components/DataLinks/DataLinks.js +2 -2
  46. package/dist/esm/components/DataSourcePicker/DataSourcePicker.js +7 -7
  47. package/dist/esm/components/DatePicker/styles.js +2 -2
  48. package/dist/esm/components/DatePickerWithInput/styles.js +2 -2
  49. package/dist/esm/components/QueryEditor/EditorField.js +2 -2
  50. package/dist/esm/components/QueryEditor/EditorHeader.js +2 -2
  51. package/dist/esm/components/QueryEditor/EditorRow.js +2 -2
  52. package/dist/esm/components/QueryEditor/EditorSwitch.js +2 -2
  53. package/dist/esm/components/QueryEditor/InlineSelect.js +1 -1
  54. package/dist/esm/components/QueryEditor/InlineSelect.js.map +1 -1
  55. package/dist/esm/components/QueryEditor/InputGroup.js +2 -2
  56. package/dist/esm/components/QueryEditor/QueryEditor.js +3 -1
  57. package/dist/esm/components/QueryEditor/QueryEditor.js.map +1 -1
  58. package/dist/esm/components/QueryEditor/QueryHeader.js +2 -2
  59. package/dist/esm/components/QueryEditor/QueryHeader.js.map +1 -1
  60. package/dist/esm/components/QueryEditor/Space.js +2 -2
  61. package/dist/esm/components/QueryEditor/TableSelector.js +0 -1
  62. package/dist/esm/components/QueryEditor/TableSelector.js.map +1 -1
  63. package/dist/esm/components/QueryEditor/defaults.js.map +1 -1
  64. package/dist/esm/components/QueryEditor/query-editor-raw/QueryEditorRaw.js +10 -2
  65. package/dist/esm/components/QueryEditor/query-editor-raw/QueryEditorRaw.js.map +1 -1
  66. package/dist/esm/components/QueryEditor/query-editor-raw/QueryToolbox.js +6 -1
  67. package/dist/esm/components/QueryEditor/query-editor-raw/QueryToolbox.js.map +1 -1
  68. package/dist/esm/components/QueryEditor/query-editor-raw/RawEditor.js +13 -3
  69. package/dist/esm/components/QueryEditor/query-editor-raw/RawEditor.js.map +1 -1
  70. package/dist/esm/components/QueryEditor/types.js +0 -1
  71. package/dist/esm/components/QueryEditor/types.js.map +1 -1
  72. package/dist/esm/components/QueryEditor/utils/formatSQL.js +15 -4
  73. package/dist/esm/components/QueryEditor/utils/formatSQL.js.map +1 -1
  74. package/dist/esm/components/QueryEditor/visual-query-builder/EditorField.js +2 -2
  75. package/dist/esm/components/QueryEditor/visual-query-builder/EditorRow.js +2 -2
  76. package/dist/esm/components/QueryEditor/visual-query-builder/Preview.js +4 -4
  77. package/dist/esm/components/QueryEditor/visual-query-builder/Preview.js.map +1 -1
  78. package/dist/esm/components/QueryEditor/visual-query-builder/SQLGroupByRow.js +0 -1
  79. package/dist/esm/components/QueryEditor/visual-query-builder/SQLGroupByRow.js.map +1 -1
  80. package/dist/esm/components/QueryEditor/visual-query-builder/SQLOrderByRow.js +0 -1
  81. package/dist/esm/components/QueryEditor/visual-query-builder/SQLOrderByRow.js.map +1 -1
  82. package/dist/esm/components/QueryEditor/visual-query-builder/SQLSelectRow.js +0 -1
  83. package/dist/esm/components/QueryEditor/visual-query-builder/SQLSelectRow.js.map +1 -1
  84. package/dist/esm/components/QueryEditor/visual-query-builder/SQLWhereRow.js +0 -1
  85. package/dist/esm/components/QueryEditor/visual-query-builder/SQLWhereRow.js.map +1 -1
  86. package/dist/esm/components/QueryEditor/visual-query-builder/SelectRow.js +2 -2
  87. package/dist/esm/components/QueryEditor/visual-query-builder/VisualEditor.js +10 -2
  88. package/dist/esm/components/QueryEditor/visual-query-builder/VisualEditor.js.map +1 -1
  89. package/dist/esm/components/SQLEditor/components/SQLEditor.js.map +1 -1
  90. package/dist/esm/components/SQLEditor/standardSql/definition.js +0 -6
  91. package/dist/esm/components/SQLEditor/standardSql/definition.js.map +1 -1
  92. package/dist/esm/components/SQLEditor/standardSql/getStatementPosition.js +2 -1
  93. package/dist/esm/components/SQLEditor/standardSql/getStatementPosition.js.map +1 -1
  94. package/dist/esm/components/SQLEditor/standardSql/statementPositionResolversRegistry.js +2 -1
  95. package/dist/esm/components/SQLEditor/standardSql/statementPositionResolversRegistry.js.map +1 -1
  96. package/dist/esm/components/SQLEditor/types.js +1 -17
  97. package/dist/esm/components/SQLEditor/types.js.map +1 -1
  98. package/dist/esm/components/SQLEditor/utils/LinkedToken.js +1 -1
  99. package/dist/esm/components/SQLEditor/utils/LinkedToken.js.map +1 -1
  100. package/dist/esm/components/SQLEditor/utils/linkedTokenBuilder.js +2 -2
  101. package/dist/esm/components/SQLEditor/utils/tokenType.js +18 -0
  102. package/dist/esm/components/SQLEditor/utils/tokenType.js.map +1 -0
  103. package/dist/esm/components/SQLEditor/utils/tokenUtils.js +1 -1
  104. package/dist/esm/components/VisualQueryBuilder/components/OperationEditorBody.js +1 -1
  105. package/dist/esm/components/VisualQueryBuilder/components/OperationList.js +1 -1
  106. package/dist/esm/components/VisualQueryBuilder/components/OperationParamEditor.js +1 -1
  107. package/dist/esm/components/VisualQueryBuilder/components/OperationsEditorRow.js +1 -1
  108. package/dist/esm/components/VisualQueryBuilder/components/QueryHeaderSwitch.js +1 -1
  109. package/dist/esm/components/VisualQueryBuilder/components/QueryOptionGroup.js +1 -1
  110. package/dist/esm/datasource/SqlDatasource.js +10 -10
  111. package/dist/esm/datasource/schema/config.js +235 -0
  112. package/dist/esm/datasource/schema/config.js.map +1 -0
  113. package/dist/esm/datasource/schema/datasource.js +228 -0
  114. package/dist/esm/datasource/schema/datasource.js.map +1 -0
  115. package/dist/esm/datasource/schema/datasources/alertmanager.schema.json.js +77 -0
  116. package/dist/esm/datasource/schema/datasources/alertmanager.schema.json.js.map +1 -0
  117. package/dist/esm/datasource/schema/datasources/cloudwatch.schema.json.js +384 -0
  118. package/dist/esm/datasource/schema/datasources/cloudwatch.schema.json.js.map +1 -0
  119. package/dist/esm/datasource/schema/datasources/elasticsearch.schema.json.js +287 -0
  120. package/dist/esm/datasource/schema/datasources/elasticsearch.schema.json.js.map +1 -0
  121. package/dist/esm/datasource/schema/datasources/grafana-amazonprometheus-datasource.schema.json.js +166 -0
  122. package/dist/esm/datasource/schema/datasources/grafana-amazonprometheus-datasource.schema.json.js.map +1 -0
  123. package/dist/esm/datasource/schema/datasources/grafana-appdynamics-datasource.schema.json.js +145 -0
  124. package/dist/esm/datasource/schema/datasources/grafana-appdynamics-datasource.schema.json.js.map +1 -0
  125. package/dist/esm/datasource/schema/datasources/grafana-astradb-datasource.schema.json.js +123 -0
  126. package/dist/esm/datasource/schema/datasources/grafana-astradb-datasource.schema.json.js.map +1 -0
  127. package/dist/esm/datasource/schema/datasources/grafana-athena-datasource.schema.json.js +158 -0
  128. package/dist/esm/datasource/schema/datasources/grafana-athena-datasource.schema.json.js.map +1 -0
  129. package/dist/esm/datasource/schema/datasources/grafana-azure-data-explorer-datasource.schema.json.js +204 -0
  130. package/dist/esm/datasource/schema/datasources/grafana-azure-data-explorer-datasource.schema.json.js.map +1 -0
  131. package/dist/esm/datasource/schema/datasources/grafana-azure-monitor-datasource.schema.json.js +294 -0
  132. package/dist/esm/datasource/schema/datasources/grafana-azure-monitor-datasource.schema.json.js.map +1 -0
  133. package/dist/esm/datasource/schema/datasources/grafana-azuredevops-datasource.schema.json.js +101 -0
  134. package/dist/esm/datasource/schema/datasources/grafana-azuredevops-datasource.schema.json.js.map +1 -0
  135. package/dist/esm/datasource/schema/datasources/grafana-azureprometheus-datasource.schema.json.js +125 -0
  136. package/dist/esm/datasource/schema/datasources/grafana-azureprometheus-datasource.schema.json.js.map +1 -0
  137. package/dist/esm/datasource/schema/datasources/grafana-bigquery-datasource.schema.json.js +159 -0
  138. package/dist/esm/datasource/schema/datasources/grafana-bigquery-datasource.schema.json.js.map +1 -0
  139. package/dist/esm/datasource/schema/datasources/grafana-clickhouse-datasource.schema.json.js +1238 -0
  140. package/dist/esm/datasource/schema/datasources/grafana-clickhouse-datasource.schema.json.js.map +1 -0
  141. package/dist/esm/datasource/schema/datasources/grafana-cockroachdb-datasource.schema.json.js +302 -0
  142. package/dist/esm/datasource/schema/datasources/grafana-cockroachdb-datasource.schema.json.js.map +1 -0
  143. package/dist/esm/datasource/schema/datasources/grafana-databricks-datasource.schema.json.js +291 -0
  144. package/dist/esm/datasource/schema/datasources/grafana-databricks-datasource.schema.json.js.map +1 -0
  145. package/dist/esm/datasource/schema/datasources/grafana-datadog-datasource.schema.json.js +155 -0
  146. package/dist/esm/datasource/schema/datasources/grafana-datadog-datasource.schema.json.js.map +1 -0
  147. package/dist/esm/datasource/schema/datasources/grafana-dynatrace-datasource.schema.json.js +179 -0
  148. package/dist/esm/datasource/schema/datasources/grafana-dynatrace-datasource.schema.json.js.map +1 -0
  149. package/dist/esm/datasource/schema/datasources/grafana-falconlogscale-datasource.schema.json.js +134 -0
  150. package/dist/esm/datasource/schema/datasources/grafana-falconlogscale-datasource.schema.json.js.map +1 -0
  151. package/dist/esm/datasource/schema/datasources/grafana-github-datasource.schema.json.js +156 -0
  152. package/dist/esm/datasource/schema/datasources/grafana-github-datasource.schema.json.js.map +1 -0
  153. package/dist/esm/datasource/schema/datasources/grafana-gitlab-datasource.schema.json.js +84 -0
  154. package/dist/esm/datasource/schema/datasources/grafana-gitlab-datasource.schema.json.js.map +1 -0
  155. package/dist/esm/datasource/schema/datasources/grafana-googlesheets-datasource.schema.json.js +235 -0
  156. package/dist/esm/datasource/schema/datasources/grafana-googlesheets-datasource.schema.json.js.map +1 -0
  157. package/dist/esm/datasource/schema/datasources/grafana-honeycomb-datasource.schema.json.js +87 -0
  158. package/dist/esm/datasource/schema/datasources/grafana-honeycomb-datasource.schema.json.js.map +1 -0
  159. package/dist/esm/datasource/schema/datasources/grafana-iot-sitewise-datasource.schema.json.js +159 -0
  160. package/dist/esm/datasource/schema/datasources/grafana-iot-sitewise-datasource.schema.json.js.map +1 -0
  161. package/dist/esm/datasource/schema/datasources/grafana-jira-datasource.schema.json.js +188 -0
  162. package/dist/esm/datasource/schema/datasources/grafana-jira-datasource.schema.json.js.map +1 -0
  163. package/dist/esm/datasource/schema/datasources/grafana-looker-datasource.schema.json.js +82 -0
  164. package/dist/esm/datasource/schema/datasources/grafana-looker-datasource.schema.json.js.map +1 -0
  165. package/dist/esm/datasource/schema/datasources/grafana-mongodb-datasource.schema.json.js +278 -0
  166. package/dist/esm/datasource/schema/datasources/grafana-mongodb-datasource.schema.json.js.map +1 -0
  167. package/dist/esm/datasource/schema/datasources/grafana-mqtt-datasource.schema.json.js +168 -0
  168. package/dist/esm/datasource/schema/datasources/grafana-mqtt-datasource.schema.json.js.map +1 -0
  169. package/dist/esm/datasource/schema/datasources/grafana-newrelic-datasource.schema.json.js +129 -0
  170. package/dist/esm/datasource/schema/datasources/grafana-newrelic-datasource.schema.json.js.map +1 -0
  171. package/dist/esm/datasource/schema/datasources/grafana-odbc-datasource.schema.json.js +56 -0
  172. package/dist/esm/datasource/schema/datasources/grafana-odbc-datasource.schema.json.js.map +1 -0
  173. package/dist/esm/datasource/schema/datasources/grafana-opensearch-datasource.schema.json.js +212 -0
  174. package/dist/esm/datasource/schema/datasources/grafana-opensearch-datasource.schema.json.js.map +1 -0
  175. package/dist/esm/datasource/schema/datasources/grafana-oracle-datasource.schema.json.js +186 -0
  176. package/dist/esm/datasource/schema/datasources/grafana-oracle-datasource.schema.json.js.map +1 -0
  177. package/dist/esm/datasource/schema/datasources/grafana-pagerduty-datasource.schema.json.js +85 -0
  178. package/dist/esm/datasource/schema/datasources/grafana-pagerduty-datasource.schema.json.js.map +1 -0
  179. package/dist/esm/datasource/schema/datasources/grafana-postgresql-datasource.schema.json.js +464 -0
  180. package/dist/esm/datasource/schema/datasources/grafana-postgresql-datasource.schema.json.js.map +1 -0
  181. package/dist/esm/datasource/schema/datasources/grafana-pyroscope-datasource.schema.json.js +41 -0
  182. package/dist/esm/datasource/schema/datasources/grafana-pyroscope-datasource.schema.json.js.map +1 -0
  183. package/dist/esm/datasource/schema/datasources/grafana-redshift-datasource.schema.json.js +201 -0
  184. package/dist/esm/datasource/schema/datasources/grafana-redshift-datasource.schema.json.js.map +1 -0
  185. package/dist/esm/datasource/schema/datasources/grafana-salesforce-datasource.schema.json.js +201 -0
  186. package/dist/esm/datasource/schema/datasources/grafana-salesforce-datasource.schema.json.js.map +1 -0
  187. package/dist/esm/datasource/schema/datasources/grafana-saphana-datasource.schema.json.js +208 -0
  188. package/dist/esm/datasource/schema/datasources/grafana-saphana-datasource.schema.json.js.map +1 -0
  189. package/dist/esm/datasource/schema/datasources/grafana-sentry-datasource.schema.json.js +94 -0
  190. package/dist/esm/datasource/schema/datasources/grafana-sentry-datasource.schema.json.js.map +1 -0
  191. package/dist/esm/datasource/schema/datasources/grafana-servicenow-datasource.schema.json.js +179 -0
  192. package/dist/esm/datasource/schema/datasources/grafana-servicenow-datasource.schema.json.js.map +1 -0
  193. package/dist/esm/datasource/schema/datasources/grafana-snowflake-datasource.schema.json.js +304 -0
  194. package/dist/esm/datasource/schema/datasources/grafana-snowflake-datasource.schema.json.js.map +1 -0
  195. package/dist/esm/datasource/schema/datasources/grafana-splunk-datasource.schema.json.js +319 -0
  196. package/dist/esm/datasource/schema/datasources/grafana-splunk-datasource.schema.json.js.map +1 -0
  197. package/dist/esm/datasource/schema/datasources/grafana-splunkobservability-datasource.schema.json.js +90 -0
  198. package/dist/esm/datasource/schema/datasources/grafana-splunkobservability-datasource.schema.json.js.map +1 -0
  199. package/dist/esm/datasource/schema/datasources/grafana-strava-datasource.schema.json.js +74 -0
  200. package/dist/esm/datasource/schema/datasources/grafana-strava-datasource.schema.json.js.map +1 -0
  201. package/dist/esm/datasource/schema/datasources/grafana-sumologic-datasource.schema.json.js +102 -0
  202. package/dist/esm/datasource/schema/datasources/grafana-sumologic-datasource.schema.json.js.map +1 -0
  203. package/dist/esm/datasource/schema/datasources/grafana-surrealdb-datasource.schema.json.js +92 -0
  204. package/dist/esm/datasource/schema/datasources/grafana-surrealdb-datasource.schema.json.js.map +1 -0
  205. package/dist/esm/datasource/schema/datasources/grafana-timestream-datasource.schema.json.js +145 -0
  206. package/dist/esm/datasource/schema/datasources/grafana-timestream-datasource.schema.json.js.map +1 -0
  207. package/dist/esm/datasource/schema/datasources/grafana-wavefront-datasource.schema.json.js +80 -0
  208. package/dist/esm/datasource/schema/datasources/grafana-wavefront-datasource.schema.json.js.map +1 -0
  209. package/dist/esm/datasource/schema/datasources/grafana-x-ray-datasource.schema.json.js +112 -0
  210. package/dist/esm/datasource/schema/datasources/grafana-x-ray-datasource.schema.json.js.map +1 -0
  211. package/dist/esm/datasource/schema/datasources/grafana-yugabyte-datasource.schema.json.js +114 -0
  212. package/dist/esm/datasource/schema/datasources/grafana-yugabyte-datasource.schema.json.js.map +1 -0
  213. package/dist/esm/datasource/schema/datasources/graphite.schema.json.js +104 -0
  214. package/dist/esm/datasource/schema/datasources/graphite.schema.json.js.map +1 -0
  215. package/dist/esm/datasource/schema/datasources/influxdb.schema.json.js +703 -0
  216. package/dist/esm/datasource/schema/datasources/influxdb.schema.json.js.map +1 -0
  217. package/dist/esm/datasource/schema/datasources/jaeger.schema.json.js +59 -0
  218. package/dist/esm/datasource/schema/datasources/jaeger.schema.json.js.map +1 -0
  219. package/dist/esm/datasource/schema/datasources/loki.schema.json.js +545 -0
  220. package/dist/esm/datasource/schema/datasources/loki.schema.json.js.map +1 -0
  221. package/dist/esm/datasource/schema/datasources/marcusolsson-csv-datasource.schema.json.js +45 -0
  222. package/dist/esm/datasource/schema/datasources/marcusolsson-csv-datasource.schema.json.js.map +1 -0
  223. package/dist/esm/datasource/schema/datasources/marcusolsson-json-datasource.schema.json.js +36 -0
  224. package/dist/esm/datasource/schema/datasources/marcusolsson-json-datasource.schema.json.js.map +1 -0
  225. package/dist/esm/datasource/schema/datasources/mssql.schema.json.js +292 -0
  226. package/dist/esm/datasource/schema/datasources/mssql.schema.json.js.map +1 -0
  227. package/dist/esm/datasource/schema/datasources/mysql.schema.json.js +137 -0
  228. package/dist/esm/datasource/schema/datasources/mysql.schema.json.js.map +1 -0
  229. package/dist/esm/datasource/schema/datasources/opentsdb.schema.json.js +113 -0
  230. package/dist/esm/datasource/schema/datasources/opentsdb.schema.json.js.map +1 -0
  231. package/dist/esm/datasource/schema/datasources/prometheus.schema.json.js +783 -0
  232. package/dist/esm/datasource/schema/datasources/prometheus.schema.json.js.map +1 -0
  233. package/dist/esm/datasource/schema/datasources/stackdriver.schema.json.js +135 -0
  234. package/dist/esm/datasource/schema/datasources/stackdriver.schema.json.js.map +1 -0
  235. package/dist/esm/datasource/schema/datasources/tempo.schema.json.js +618 -0
  236. package/dist/esm/datasource/schema/datasources/tempo.schema.json.js.map +1 -0
  237. package/dist/esm/datasource/schema/datasources/yesoreyeram-infinity-datasource.schema.json.js +386 -0
  238. package/dist/esm/datasource/schema/datasources/yesoreyeram-infinity-datasource.schema.json.js.map +1 -0
  239. package/dist/esm/datasource/schema/datasources/zipkin.schema.json.js +40 -0
  240. package/dist/esm/datasource/schema/datasources/zipkin.schema.json.js.map +1 -0
  241. package/dist/esm/datasource/schema/llmHints.js +54 -0
  242. package/dist/esm/datasource/schema/llmHints.js.map +1 -0
  243. package/dist/esm/datasource/schema/provisioningYaml.js +358 -0
  244. package/dist/esm/datasource/schema/provisioningYaml.js.map +1 -0
  245. package/dist/esm/datasource/schema/schemaRegistry.js +139 -0
  246. package/dist/esm/datasource/schema/schemaRegistry.js.map +1 -0
  247. package/dist/esm/index.d.ts +604 -39
  248. package/dist/esm/index.js +11 -1
  249. package/dist/esm/index.js.map +1 -1
  250. package/dist/esm/schemas.d.ts +338 -0
  251. package/dist/esm/schemas.js +2 -0
  252. package/dist/esm/schemas.js.map +1 -0
  253. package/package.json +44 -11
@@ -11,23 +11,26 @@ var e2eSelectors = require('@grafana/e2e-selectors');
11
11
  var runtime = require('@grafana/runtime');
12
12
  var reactUse = require('react-use');
13
13
  var ui$1 = require('@react-awesome-query-builder/ui');
14
- var lodash = require('lodash');
15
14
  var uuid = require('uuid');
15
+ var lodash = require('lodash');
16
16
  var AutoSizer = require('react-virtualized-auto-sizer');
17
- var sqlFormatter = require('sql-formatter-plus');
17
+ var sqlFormatter = require('sql-formatter');
18
18
  var rxjs = require('rxjs');
19
19
  var operators$1 = require('rxjs/operators');
20
+ var reactHookForm = require('react-hook-form');
20
21
  var dnd = require('@hello-pangea/dnd');
21
22
  var reactPopperTooltip = require('react-popper-tooltip');
22
23
  var Prism = require('prismjs');
24
+ var yaml = require('js-yaml');
25
+ var schemas = require('./schemas.cjs');
23
26
 
24
27
  function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
25
28
 
26
29
  var React__default = /*#__PURE__*/_interopDefaultCompat(React);
27
30
  var Calendar__default = /*#__PURE__*/_interopDefaultCompat(Calendar);
28
31
  var AutoSizer__default = /*#__PURE__*/_interopDefaultCompat(AutoSizer);
29
- var sqlFormatter__default = /*#__PURE__*/_interopDefaultCompat(sqlFormatter);
30
32
  var Prism__default = /*#__PURE__*/_interopDefaultCompat(Prism);
33
+ var yaml__default = /*#__PURE__*/_interopDefaultCompat(yaml);
31
34
 
32
35
  const QueryEditorRow = (props) => {
33
36
  var _a, _b;
@@ -76,7 +79,7 @@ function Segment(props) {
76
79
  );
77
80
  }
78
81
 
79
- const getStyles$r = (theme) => {
82
+ const getStyles$v = (theme) => {
80
83
  const containerBorder = theme.isDark ? theme.v1.palette.dark9 : theme.v1.palette.gray5;
81
84
  return {
82
85
  container: css.css`
@@ -226,7 +229,7 @@ const getBodyStyles = (theme) => {
226
229
 
227
230
  const DatePicker = React.memo((props) => {
228
231
  const theme = ui.useTheme2();
229
- const styles = getStyles$r(theme);
232
+ const styles = getStyles$v(theme);
230
233
  const { isOpen, onClose } = props;
231
234
  if (!isOpen) {
232
235
  return null;
@@ -256,7 +259,7 @@ const Body = React.memo(({ value, onChange }) => {
256
259
  });
257
260
  Body.displayName = "Body";
258
261
 
259
- function getStyles$q() {
262
+ function getStyles$u() {
260
263
  return {
261
264
  input: css.css({
262
265
  /* hides the native Calendar picker icon given when using type=date */
@@ -272,7 +275,7 @@ const formatDate = (date) => date.toISOString().split("T")[0];
272
275
  const DatePickerWithInput = (props) => {
273
276
  const { value, onChange, className, ...rest } = props;
274
277
  const [open, setOpen] = React.useState(false);
275
- const styles = getStyles$q();
278
+ const styles = getStyles$u();
276
279
  return /* @__PURE__ */ React__default.default.createElement(React__default.default.Fragment, null, /* @__PURE__ */ React__default.default.createElement(
277
280
  ui.Input,
278
281
  {
@@ -339,15 +342,15 @@ function getSignatureDisplayModel(signature) {
339
342
  }
340
343
  PluginSignatureBadge.displayName = "PluginSignatureBadge";
341
344
 
342
- var __defProp$3 = Object.defineProperty;
343
- var __defNormalProp$3 = (obj, key, value) => key in obj ? __defProp$3(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
344
- var __publicField$3 = (obj, key, value) => __defNormalProp$3(obj, typeof key !== "symbol" ? key + "" : key, value);
345
+ var __defProp$4 = Object.defineProperty;
346
+ var __defNormalProp$4 = (obj, key, value) => key in obj ? __defProp$4(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
347
+ var __publicField$4 = (obj, key, value) => __defNormalProp$4(obj, typeof key !== "symbol" ? key + "" : key, value);
345
348
  class DataSourcePicker extends React.PureComponent {
346
349
  constructor(props) {
347
350
  super(props);
348
- __publicField$3(this, "dataSourceSrv", runtime.getDataSourceSrv());
349
- __publicField$3(this, "state", {});
350
- __publicField$3(this, "onChange", (item) => {
351
+ __publicField$4(this, "dataSourceSrv", runtime.getDataSourceSrv());
352
+ __publicField$4(this, "state", {});
353
+ __publicField$4(this, "onChange", (item) => {
351
354
  const dsSettings = this.dataSourceSrv.getInstanceSettings(item.value);
352
355
  if (dsSettings) {
353
356
  this.props.onChange(dsSettings);
@@ -427,14 +430,14 @@ class DataSourcePicker extends React.PureComponent {
427
430
  ));
428
431
  }
429
432
  }
430
- __publicField$3(DataSourcePicker, "defaultProps", {
433
+ __publicField$4(DataSourcePicker, "defaultProps", {
431
434
  autoFocus: false,
432
435
  openMenuOnFocus: false,
433
436
  placeholder: "Select datasource"
434
437
  });
435
438
 
436
439
  const { FormField, Switch } = ui.LegacyForms;
437
- const getStyles$p = ui.stylesFactory(() => ({
440
+ const getStyles$t = ui.stylesFactory(() => ({
438
441
  firstRow: css.css`
439
442
  display: flex;
440
443
  `,
@@ -451,7 +454,7 @@ const getStyles$p = ui.stylesFactory(() => ({
451
454
  }));
452
455
  const DataLink = (props) => {
453
456
  const { value, onChange, onDelete, suggestions, className } = props;
454
- const styles = getStyles$p();
457
+ const styles = getStyles$t();
455
458
  const [showInternalLink, setShowInternalLink] = useInternalLink(value.datasourceUid);
456
459
  const handleChange = (field) => (event) => {
457
460
  onChange({
@@ -568,7 +571,7 @@ function useInternalLink(datasourceUid) {
568
571
  return [showInternalLink, setShowInternalLink];
569
572
  }
570
573
 
571
- const getStyles$o = (theme) => ({
574
+ const getStyles$s = (theme) => ({
572
575
  infoText: css.css`
573
576
  padding-bottom: ${theme.v1.spacing.md};
574
577
  color: ${theme.v1.colors.textWeak};
@@ -580,7 +583,7 @@ const getStyles$o = (theme) => ({
580
583
  const DataLinks = (props) => {
581
584
  const { value, onChange } = props;
582
585
  const theme = ui.useTheme2();
583
- const styles = getStyles$o(theme);
586
+ const styles = getStyles$s(theme);
584
587
  return /* @__PURE__ */ React__default.default.createElement(React__default.default.Fragment, null, /* @__PURE__ */ React__default.default.createElement("h3", { className: "page-heading" }, "Data links"), /* @__PURE__ */ React__default.default.createElement("div", { className: styles.infoText }, "Add links to existing fields. Links will be shown in log row details next to the field value."), /* @__PURE__ */ React__default.default.createElement("div", { className: "gf-form-group" }, value && value.map((field, index) => {
585
588
  return /* @__PURE__ */ React__default.default.createElement(
586
589
  DataLink,
@@ -641,110 +644,21 @@ var QueryEditorExpressionType = /* @__PURE__ */ ((QueryEditorExpressionType2) =>
641
644
  return QueryEditorExpressionType2;
642
645
  })(QueryEditorExpressionType || {});
643
646
 
644
- function getRawSqlFn(db) {
645
- return db.toRawSql ? db.toRawSql : (query) => toRawSql(query, Boolean(db.disableDatasets));
646
- }
647
- function toRawSql({ sql, dataset, catalog, table }, disableDatasets) {
648
- var _a, _b, _c, _d;
649
- let rawQuery = "";
650
- if (!sql || !haveColumns(sql.columns)) {
651
- return rawQuery;
652
- }
653
- rawQuery += createSelectClause(sql.columns);
654
- if (catalog && dataset && table) {
655
- rawQuery += `FROM ${catalog}.${dataset}.${table} `;
656
- } else if (!disableDatasets && dataset && table) {
657
- rawQuery += `FROM ${dataset}.${table} `;
658
- } else if (table) {
659
- rawQuery += `FROM ${table} `;
660
- }
661
- if (sql.whereString) {
662
- rawQuery += `WHERE ${sql.whereString} `;
663
- }
664
- if ((_b = (_a = sql.groupBy) == null ? void 0 : _a[0]) == null ? void 0 : _b.property.name) {
665
- const groupBy = sql.groupBy.map((g) => g.property.name).filter((g) => !lodash.isEmpty(g));
666
- rawQuery += `GROUP BY ${groupBy.join(", ")} `;
667
- }
668
- if ((_c = sql.orderBy) == null ? void 0 : _c.property.name) {
669
- rawQuery += `ORDER BY ${sql.orderBy.property.name} `;
670
- }
671
- if (((_d = sql.orderBy) == null ? void 0 : _d.property.name) && sql.orderByDirection) {
672
- rawQuery += `${sql.orderByDirection} `;
673
- }
674
- if (sql.limit !== void 0 && sql.limit >= 0) {
675
- rawQuery += `LIMIT ${sql.limit} `;
676
- }
677
- return rawQuery;
678
- }
679
- function createSelectClause(sqlColumns) {
680
- const columns = sqlColumns.map((c) => {
681
- var _a, _b;
682
- let rawColumn = "";
683
- if (c.name) {
684
- rawColumn += `${c.name}(${(_a = c.parameters) == null ? void 0 : _a.map((p) => `${p.name}`)})`;
685
- } else {
686
- rawColumn += `${(_b = c.parameters) == null ? void 0 : _b.map((p) => `${p.name}`)}`;
687
- }
688
- return rawColumn;
689
- });
690
- return `SELECT ${columns.join(", ")} `;
691
- }
692
- function haveColumns(columns) {
693
- if (!columns) {
694
- return false;
695
- }
696
- const haveColumn = columns.some((c) => {
697
- var _a, _b;
698
- return ((_a = c.parameters) == null ? void 0 : _a.length) || ((_b = c.parameters) == null ? void 0 : _b.some((p) => p.name));
699
- });
700
- const haveFunction = columns.some((c) => c.name);
701
- return haveColumn || haveFunction;
702
- }
703
- function setGroupByField(field) {
704
- return {
705
- type: QueryEditorExpressionType.GroupBy,
706
- property: {
707
- type: QueryEditorPropertyType.String,
708
- name: field
709
- }
710
- };
711
- }
712
- function setPropertyField(field) {
713
- return {
714
- type: QueryEditorExpressionType.Property,
715
- property: {
716
- type: QueryEditorPropertyType.String,
717
- name: field
718
- }
719
- };
720
- }
721
- function createFunctionField(functionName) {
722
- return {
723
- type: QueryEditorExpressionType.Function,
724
- name: functionName,
725
- parameters: []
726
- };
727
- }
728
-
729
- function applyQueryDefaults(q) {
730
- let editorMode = (q == null ? void 0 : q.editorMode) || EditorMode.Builder;
731
- if ((q == null ? void 0 : q.editorMode) === void 0 && (q == null ? void 0 : q.rawSql) !== void 0) {
732
- editorMode = EditorMode.Code;
733
- }
734
- const result = {
735
- ...q,
736
- refId: (q == null ? void 0 : q.refId) || "A",
737
- format: (q == null ? void 0 : q.format) !== void 0 ? q.format : QueryFormat.Table,
738
- rawSql: (q == null ? void 0 : q.rawSql) || "",
739
- editorMode,
740
- sql: (q == null ? void 0 : q.sql) || {
741
- columns: [createFunctionField()],
742
- groupBy: [setGroupByField()],
743
- limit: 50
744
- }
745
- };
746
- return result;
747
- }
647
+ var TokenType = /* @__PURE__ */ ((TokenType2) => {
648
+ TokenType2["Parenthesis"] = "delimiter.parenthesis.sql";
649
+ TokenType2["Whitespace"] = "white.sql";
650
+ TokenType2["Keyword"] = "keyword.sql";
651
+ TokenType2["Delimiter"] = "delimiter.sql";
652
+ TokenType2["Operator"] = "operator.sql";
653
+ TokenType2["Identifier"] = "identifier.sql";
654
+ TokenType2["IdentifierQuote"] = "identifier.quote.sql";
655
+ TokenType2["Type"] = "type.sql";
656
+ TokenType2["Function"] = "predefined.sql";
657
+ TokenType2["Number"] = "number.sql";
658
+ TokenType2["String"] = "string.sql";
659
+ TokenType2["Variable"] = "variable.sql";
660
+ return TokenType2;
661
+ })(TokenType || {});
748
662
 
749
663
  class LinkedToken {
750
664
  constructor(type, value, range, previous, next) {
@@ -899,21 +813,6 @@ var MacroType = /* @__PURE__ */ ((MacroType2) => {
899
813
  MacroType2[MacroType2["Table"] = 4] = "Table";
900
814
  return MacroType2;
901
815
  })(MacroType || {});
902
- var TokenType = /* @__PURE__ */ ((TokenType2) => {
903
- TokenType2["Parenthesis"] = "delimiter.parenthesis.sql";
904
- TokenType2["Whitespace"] = "white.sql";
905
- TokenType2["Keyword"] = "keyword.sql";
906
- TokenType2["Delimiter"] = "delimiter.sql";
907
- TokenType2["Operator"] = "operator.sql";
908
- TokenType2["Identifier"] = "identifier.sql";
909
- TokenType2["IdentifierQuote"] = "identifier.quote.sql";
910
- TokenType2["Type"] = "type.sql";
911
- TokenType2["Function"] = "predefined.sql";
912
- TokenType2["Number"] = "number.sql";
913
- TokenType2["String"] = "string.sql";
914
- TokenType2["Variable"] = "variable.sql";
915
- return TokenType2;
916
- })(TokenType || {});
917
816
  var StatementPosition = /* @__PURE__ */ ((StatementPosition2) => {
918
817
  StatementPosition2["Unknown"] = "unknown";
919
818
  StatementPosition2["SelectKeyword"] = "selectKeyword";
@@ -5456,6 +5355,91 @@ const QUERY_FORMAT_OPTIONS = [
5456
5355
  const backWardToOption = (value) => ({ label: value, value });
5457
5356
  const toOption = (_a = data.toOption) != null ? _a : backWardToOption;
5458
5357
 
5358
+ function getRawSqlFn(db) {
5359
+ return db.toRawSql ? db.toRawSql : (query) => toRawSql(query, Boolean(db.disableDatasets));
5360
+ }
5361
+ function toRawSql({ sql, dataset, catalog, table }, disableDatasets) {
5362
+ var _a, _b, _c, _d;
5363
+ let rawQuery = "";
5364
+ if (!sql || !haveColumns(sql.columns)) {
5365
+ return rawQuery;
5366
+ }
5367
+ rawQuery += createSelectClause(sql.columns);
5368
+ if (catalog && dataset && table) {
5369
+ rawQuery += `FROM ${catalog}.${dataset}.${table} `;
5370
+ } else if (!disableDatasets && dataset && table) {
5371
+ rawQuery += `FROM ${dataset}.${table} `;
5372
+ } else if (table) {
5373
+ rawQuery += `FROM ${table} `;
5374
+ }
5375
+ if (sql.whereString) {
5376
+ rawQuery += `WHERE ${sql.whereString} `;
5377
+ }
5378
+ if ((_b = (_a = sql.groupBy) == null ? void 0 : _a[0]) == null ? void 0 : _b.property.name) {
5379
+ const groupBy = sql.groupBy.map((g) => g.property.name).filter((g) => !lodash.isEmpty(g));
5380
+ rawQuery += `GROUP BY ${groupBy.join(", ")} `;
5381
+ }
5382
+ if ((_c = sql.orderBy) == null ? void 0 : _c.property.name) {
5383
+ rawQuery += `ORDER BY ${sql.orderBy.property.name} `;
5384
+ }
5385
+ if (((_d = sql.orderBy) == null ? void 0 : _d.property.name) && sql.orderByDirection) {
5386
+ rawQuery += `${sql.orderByDirection} `;
5387
+ }
5388
+ if (sql.limit !== void 0 && sql.limit >= 0) {
5389
+ rawQuery += `LIMIT ${sql.limit} `;
5390
+ }
5391
+ return rawQuery;
5392
+ }
5393
+ function createSelectClause(sqlColumns) {
5394
+ const columns = sqlColumns.map((c) => {
5395
+ var _a, _b;
5396
+ let rawColumn = "";
5397
+ if (c.name) {
5398
+ rawColumn += `${c.name}(${(_a = c.parameters) == null ? void 0 : _a.map((p) => `${p.name}`)})`;
5399
+ } else {
5400
+ rawColumn += `${(_b = c.parameters) == null ? void 0 : _b.map((p) => `${p.name}`)}`;
5401
+ }
5402
+ return rawColumn;
5403
+ });
5404
+ return `SELECT ${columns.join(", ")} `;
5405
+ }
5406
+ function haveColumns(columns) {
5407
+ if (!columns) {
5408
+ return false;
5409
+ }
5410
+ const haveColumn = columns.some((c) => {
5411
+ var _a, _b;
5412
+ return ((_a = c.parameters) == null ? void 0 : _a.length) || ((_b = c.parameters) == null ? void 0 : _b.some((p) => p.name));
5413
+ });
5414
+ const haveFunction = columns.some((c) => c.name);
5415
+ return haveColumn || haveFunction;
5416
+ }
5417
+ function setGroupByField(field) {
5418
+ return {
5419
+ type: QueryEditorExpressionType.GroupBy,
5420
+ property: {
5421
+ type: QueryEditorPropertyType.String,
5422
+ name: field
5423
+ }
5424
+ };
5425
+ }
5426
+ function setPropertyField(field) {
5427
+ return {
5428
+ type: QueryEditorExpressionType.Property,
5429
+ property: {
5430
+ type: QueryEditorPropertyType.String,
5431
+ name: field
5432
+ }
5433
+ };
5434
+ }
5435
+ function createFunctionField(functionName) {
5436
+ return {
5437
+ type: QueryEditorExpressionType.Function,
5438
+ name: functionName,
5439
+ parameters: []
5440
+ };
5441
+ }
5442
+
5459
5443
  const EditorStack = ({ children, wrap: wrapItems = true, ...props }) => {
5460
5444
  var _a, _b;
5461
5445
  return /* @__PURE__ */ React__default.default.createElement(ui.Stack, { wrap: wrapItems ? "wrap" : void 0, direction: (_a = props.direction) != null ? _a : "row", gap: (_b = props.gap) != null ? _b : 2, ...props }, children);
@@ -5495,7 +5479,7 @@ const getButtonStyles = (theme) => ({
5495
5479
  });
5496
5480
 
5497
5481
  const InputGroup = ({ children }) => {
5498
- const styles = ui.useStyles2(getStyles$n);
5482
+ const styles = ui.useStyles2(getStyles$r);
5499
5483
  const modifiedChildren = React.Children.map(children, (child) => {
5500
5484
  if (React.isValidElement(child) && child.props.invalid) {
5501
5485
  return React.cloneElement(child, { className: css.cx(child.props.className, styles.invalidChild) });
@@ -5513,7 +5497,7 @@ const borderPriority = [
5513
5497
  "focused"
5514
5498
  // highest priority
5515
5499
  ];
5516
- const getStyles$n = () => ({
5500
+ const getStyles$r = () => ({
5517
5501
  root: css.css({
5518
5502
  display: "flex",
5519
5503
  // Style the direct children of the component
@@ -5596,10 +5580,10 @@ const EditorFieldGroup = ({ children }) => {
5596
5580
  };
5597
5581
 
5598
5582
  const EditorHeader = ({ children }) => {
5599
- const styles = ui.useStyles2(getStyles$m);
5583
+ const styles = ui.useStyles2(getStyles$q);
5600
5584
  return /* @__PURE__ */ React__default.default.createElement("div", { className: styles.root }, children);
5601
5585
  };
5602
- const getStyles$m = (theme) => ({
5586
+ const getStyles$q = (theme) => ({
5603
5587
  root: css.css({
5604
5588
  display: "flex",
5605
5589
  flexWrap: "wrap",
@@ -5612,12 +5596,12 @@ const getStyles$m = (theme) => ({
5612
5596
  const EditorField$1 = (props) => {
5613
5597
  var _a;
5614
5598
  const { label, optional, tooltip, tooltipInteractive, children, width, ...fieldProps } = props;
5615
- const styles = ui.useStyles2(getStyles$l, width);
5599
+ const styles = ui.useStyles2(getStyles$p, width);
5616
5600
  const childInputId = (fieldProps == null ? void 0 : fieldProps.htmlFor) || ((_a = ui.ReactUtils) == null ? void 0 : _a.getChildId(children));
5617
5601
  const labelEl = /* @__PURE__ */ React__default.default.createElement(React__default.default.Fragment, null, /* @__PURE__ */ React__default.default.createElement("label", { className: styles.label, htmlFor: childInputId }, label, optional && /* @__PURE__ */ React__default.default.createElement("span", { className: styles.optional }, " - optional"), tooltip && /* @__PURE__ */ React__default.default.createElement(ui.Tooltip, { placement: "top", content: tooltip, theme: "info", interactive: tooltipInteractive }, /* @__PURE__ */ React__default.default.createElement(ui.Icon, { tabIndex: 0, name: "info-circle", size: "sm", className: styles.icon }))), /* @__PURE__ */ React__default.default.createElement(ui.Space, { v: 0.5 }));
5618
5602
  return /* @__PURE__ */ React__default.default.createElement("div", { className: styles.root }, /* @__PURE__ */ React__default.default.createElement(ui.Field, { className: styles.field, label: labelEl, ...fieldProps }, children));
5619
5603
  };
5620
- const getStyles$l = (theme, width) => {
5604
+ const getStyles$p = (theme, width) => {
5621
5605
  return {
5622
5606
  root: css.css({
5623
5607
  minWidth: theme.spacing(width != null ? width : 0)
@@ -5645,10 +5629,10 @@ const getStyles$l = (theme, width) => {
5645
5629
  };
5646
5630
 
5647
5631
  const EditorRow$1 = ({ children }) => {
5648
- const styles = ui.useStyles2(getStyles$k);
5632
+ const styles = ui.useStyles2(getStyles$o);
5649
5633
  return /* @__PURE__ */ React__default.default.createElement("div", { className: styles.root }, /* @__PURE__ */ React__default.default.createElement(EditorStack, { gap: 2 }, children));
5650
5634
  };
5651
- const getStyles$k = (theme) => {
5635
+ const getStyles$o = (theme) => {
5652
5636
  return {
5653
5637
  root: css.css({
5654
5638
  padding: theme.spacing(1),
@@ -5663,10 +5647,10 @@ const EditorRows$1 = ({ children }) => {
5663
5647
  };
5664
5648
 
5665
5649
  const EditorSwitch = (props) => {
5666
- const styles = getStyles$j();
5650
+ const styles = getStyles$n();
5667
5651
  return /* @__PURE__ */ React__default.default.createElement("div", { className: styles.switch }, /* @__PURE__ */ React__default.default.createElement(ui.Switch, { ...props }));
5668
5652
  };
5669
- const getStyles$j = () => {
5653
+ const getStyles$n = () => {
5670
5654
  return {
5671
5655
  switch: css.css({
5672
5656
  display: "flex",
@@ -5688,7 +5672,7 @@ function InlineSelect({ label: labelProp, ...props }) {
5688
5672
  ValueContainer,
5689
5673
  SingleValue: ValueContainer
5690
5674
  };
5691
- return /* @__PURE__ */ React__default.default.createElement("div", { className: styles.root }, labelProp && /* @__PURE__ */ React__default.default.createElement("label", { className: styles.label, htmlFor: id }, labelProp, ":", "\xA0"), /* @__PURE__ */ React__default.default.createElement(ui.Select, { openMenuOnFocus: true, inputId: id, ...props, components }));
5675
+ return /* @__PURE__ */ React__default.default.createElement("div", { className: styles.root }, labelProp && /* @__PURE__ */ React__default.default.createElement("label", { className: styles.label, htmlFor: id }, labelProp, ":", "\xA0"), /* @__PURE__ */ React__default.default.createElement(ui.Select, { inputId: id, ...props, components }));
5692
5676
  }
5693
5677
  const SelectContainer = (props) => {
5694
5678
  const { children } = props;
@@ -5724,10 +5708,10 @@ const getSelectStyles = (theme) => ({
5724
5708
  });
5725
5709
 
5726
5710
  const Space = ({ v = 0, h = 0, layout = "block" }) => {
5727
- const styles = ui.useStyles2(getStyles$i, v, h, layout);
5711
+ const styles = ui.useStyles2(getStyles$m, v, h, layout);
5728
5712
  return /* @__PURE__ */ React__default.default.createElement("span", { className: css.cx(styles.wrapper) });
5729
5713
  };
5730
- const getStyles$i = (theme, v, h, layout) => ({
5714
+ const getStyles$m = (theme, v, h, layout) => ({
5731
5715
  wrapper: css.css([
5732
5716
  {
5733
5717
  paddingRight: theme.spacing(h != null ? h : 0),
@@ -5742,6 +5726,26 @@ const getStyles$i = (theme, v, h, layout) => ({
5742
5726
  ])
5743
5727
  });
5744
5728
 
5729
+ function applyQueryDefaults(q) {
5730
+ let editorMode = (q == null ? void 0 : q.editorMode) || EditorMode.Builder;
5731
+ if ((q == null ? void 0 : q.editorMode) === void 0 && (q == null ? void 0 : q.rawSql) !== void 0) {
5732
+ editorMode = EditorMode.Code;
5733
+ }
5734
+ const result = {
5735
+ ...q,
5736
+ refId: (q == null ? void 0 : q.refId) || "A",
5737
+ format: (q == null ? void 0 : q.format) !== void 0 ? q.format : QueryFormat.Table,
5738
+ rawSql: (q == null ? void 0 : q.rawSql) || "",
5739
+ editorMode,
5740
+ sql: (q == null ? void 0 : q.sql) || {
5741
+ columns: [createFunctionField()],
5742
+ groupBy: [setGroupByField()],
5743
+ limit: 50
5744
+ }
5745
+ };
5746
+ return result;
5747
+ }
5748
+
5745
5749
  function ConfirmModal({ isOpen, onCancel, onDiscard, onCopy }) {
5746
5750
  const buttonRef = React.useRef(null);
5747
5751
  React.useEffect(() => {
@@ -6131,13 +6135,32 @@ function QueryHeader({
6131
6135
  )))));
6132
6136
  }
6133
6137
 
6134
- function formatSQL(q) {
6135
- return sqlFormatter__default.default.format(q).replace(/(\$ \{ .* \})|(\$ __)|(\$ \w+)/g, (m) => {
6136
- return m.replace(/\s/g, "");
6138
+ function formatSQL(q, language = "sql") {
6139
+ const formatted = sqlFormatter.format(q, {
6140
+ language,
6141
+ paramTypes: {
6142
+ custom: [
6143
+ {
6144
+ regex: "\\$\\s*\\{[^}]*\\}|\\$\\s*__\\w+(?:\\([^)]*\\))?|\\$\\s*\\w+"
6145
+ }
6146
+ ]
6147
+ }
6137
6148
  });
6149
+ return formatted.replace(
6150
+ /(\$\s*\{[^}]*\})|(\$\s*__\w+(?:\([^)]*\))?)|(\$\s*\w+)/g,
6151
+ (m) => m.replace(/\s/g, "")
6152
+ );
6138
6153
  }
6139
6154
 
6140
- function QueryEditorRaw({ children, onChange, query, width, height, completionProvider }) {
6155
+ function QueryEditorRaw({
6156
+ children,
6157
+ onChange,
6158
+ query,
6159
+ width,
6160
+ height,
6161
+ completionProvider,
6162
+ language = "sql"
6163
+ }) {
6141
6164
  const queryRef = React.useRef(query);
6142
6165
  React.useEffect(() => {
6143
6166
  queryRef.current = query;
@@ -6160,7 +6183,7 @@ function QueryEditorRaw({ children, onChange, query, width, height, completionPr
6160
6183
  height,
6161
6184
  query: query.rawSql,
6162
6185
  onChange: onRawQueryChange,
6163
- language: { id: "sql", completionProvider, formatter: formatSQL }
6186
+ language: { id: "sql", completionProvider, formatter: (q) => formatSQL(q, language) }
6164
6187
  },
6165
6188
  children
6166
6189
  );
@@ -6265,6 +6288,10 @@ function QueryToolbox({ showTools, onFormatCode, onExpand, isExpanded, ...valida
6265
6288
  if (!showTools && validationResult === void 0) {
6266
6289
  style = { height: 0, padding: 0, visibility: "hidden" };
6267
6290
  }
6291
+ const onFormatClick = () => {
6292
+ runtime.reportInteraction("grafana_sql_query_editor_format_click");
6293
+ onFormatCode == null ? void 0 : onFormatCode();
6294
+ };
6268
6295
  return /* @__PURE__ */ React__default.default.createElement("div", { className: styles.container, style }, /* @__PURE__ */ React__default.default.createElement("div", null, validatorProps.onValidate && /* @__PURE__ */ React__default.default.createElement(
6269
6296
  QueryValidator,
6270
6297
  {
@@ -6274,7 +6301,7 @@ function QueryToolbox({ showTools, onFormatCode, onExpand, isExpanded, ...valida
6274
6301
  validatorProps.onValidate(result);
6275
6302
  }
6276
6303
  }
6277
- )), showTools && /* @__PURE__ */ React__default.default.createElement("div", null, /* @__PURE__ */ React__default.default.createElement(ui.HorizontalGroup, { spacing: "sm" }, onFormatCode && /* @__PURE__ */ React__default.default.createElement(ui.IconButton, { onClick: onFormatCode, name: "brackets-curly", size: "xs", tooltip: "Format query" }), onExpand && /* @__PURE__ */ React__default.default.createElement(
6304
+ )), showTools && /* @__PURE__ */ React__default.default.createElement("div", null, /* @__PURE__ */ React__default.default.createElement(ui.HorizontalGroup, { spacing: "sm" }, onFormatCode && /* @__PURE__ */ React__default.default.createElement(ui.IconButton, { onClick: onFormatClick, name: "brackets-curly", size: "xs", tooltip: "Format query" }), onExpand && /* @__PURE__ */ React__default.default.createElement(
6278
6305
  ui.IconButton,
6279
6306
  {
6280
6307
  onClick: () => onExpand(!isExpanded),
@@ -6285,9 +6312,18 @@ function QueryToolbox({ showTools, onFormatCode, onExpand, isExpanded, ...valida
6285
6312
  ), /* @__PURE__ */ React__default.default.createElement(ui.Tooltip, { content: "Hit CTRL/CMD+Return to run query" }, /* @__PURE__ */ React__default.default.createElement(ui.Icon, { className: styles.hint, name: "keyboard" })))));
6286
6313
  }
6287
6314
 
6288
- function RawEditor({ db, query, onChange, onRunQuery, onValidate, queryToValidate, range }) {
6315
+ function RawEditor({
6316
+ db,
6317
+ query,
6318
+ onChange,
6319
+ onRunQuery,
6320
+ onValidate,
6321
+ queryToValidate,
6322
+ range,
6323
+ language = "sql"
6324
+ }) {
6289
6325
  const theme = ui.useTheme2();
6290
- const styles = ui.useStyles2(getStyles$h);
6326
+ const styles = ui.useStyles2(getStyles$l);
6291
6327
  const [isExpanded, setIsExpanded] = React.useState(false);
6292
6328
  const [toolboxRef, toolboxMeasure] = reactUse.useMeasure();
6293
6329
  const [editorRef, editorMeasure] = reactUse.useMeasure();
@@ -6299,6 +6335,7 @@ function RawEditor({ db, query, onChange, onRunQuery, onValidate, queryToValidat
6299
6335
  completionProvider,
6300
6336
  query,
6301
6337
  width,
6338
+ language,
6302
6339
  height: height ? height - toolboxMeasure.height : void 0,
6303
6340
  onChange
6304
6341
  },
@@ -6356,7 +6393,7 @@ function RawEditor({ db, query, onChange, onRunQuery, onValidate, queryToValidat
6356
6393
  renderEditor(true)
6357
6394
  ));
6358
6395
  }
6359
- function getStyles$h(theme) {
6396
+ function getStyles$l(theme) {
6360
6397
  return {
6361
6398
  modal: css.css`
6362
6399
  width: 95vw;
@@ -6369,23 +6406,23 @@ function getStyles$h(theme) {
6369
6406
  };
6370
6407
  }
6371
6408
 
6372
- function Preview({ rawSql }) {
6409
+ function Preview({ rawSql, language = "sql" }) {
6373
6410
  const [_, copyToClipboard] = reactUse.useCopyToClipboard();
6374
- const styles = ui.useStyles2(getStyles$g);
6411
+ const styles = ui.useStyles2(getStyles$k);
6375
6412
  const labelElement = /* @__PURE__ */ React__default.default.createElement("div", { className: styles.labelWrapper }, /* @__PURE__ */ React__default.default.createElement("label", { className: styles.label }, "Preview"), /* @__PURE__ */ React__default.default.createElement(ui.IconButton, { tooltip: "Copy to clipboard", onClick: () => copyToClipboard(rawSql), name: "copy" }));
6376
6413
  return /* @__PURE__ */ React__default.default.createElement(ui.Field, { label: labelElement, className: styles.grow }, /* @__PURE__ */ React__default.default.createElement(
6377
6414
  ui.CodeEditor,
6378
6415
  {
6379
6416
  language: "sql",
6380
6417
  height: 80,
6381
- value: formatSQL(rawSql),
6418
+ value: formatSQL(rawSql, language),
6382
6419
  monacoOptions: { scrollbar: { vertical: "hidden" }, scrollBeyondLastLine: false },
6383
6420
  readOnly: true,
6384
6421
  showMiniMap: false
6385
6422
  }
6386
6423
  ));
6387
6424
  }
6388
- function getStyles$g(theme) {
6425
+ function getStyles$k(theme) {
6389
6426
  return {
6390
6427
  grow: css.css({ flexGrow: 1 }),
6391
6428
  label: css.css({ fontSize: 12, fontWeight: theme.typography.fontWeightMedium }),
@@ -6504,7 +6541,7 @@ function SQLOrderByRow({ fields, query, onQueryChange, db }) {
6504
6541
  const asteriskValue = { label: "*", value: "*" };
6505
6542
  function SelectRow({ sql, columns, onSqlChange, functions }) {
6506
6543
  var _a;
6507
- const styles = ui.useStyles2(getStyles$f);
6544
+ const styles = ui.useStyles2(getStyles$j);
6508
6545
  const columnsWithAsterisk = [asteriskValue, ...columns || []];
6509
6546
  const onColumnChange = React.useCallback(
6510
6547
  (item, index) => (column) => {
@@ -6600,7 +6637,7 @@ function SelectRow({ sql, columns, onSqlChange, functions }) {
6600
6637
  }
6601
6638
  ));
6602
6639
  }
6603
- const getStyles$f = () => {
6640
+ const getStyles$j = () => {
6604
6641
  return { addButton: css.css({ alignSelf: "flex-start" }) };
6605
6642
  };
6606
6643
  function getColumnValue({ parameters }) {
@@ -6946,10 +6983,10 @@ function mapFieldsToTypes(columns) {
6946
6983
  }
6947
6984
 
6948
6985
  const EditorRow = ({ children }) => {
6949
- const styles = ui.useStyles2(getStyles$e);
6986
+ const styles = ui.useStyles2(getStyles$i);
6950
6987
  return /* @__PURE__ */ React__default.default.createElement("div", { className: styles.root }, /* @__PURE__ */ React__default.default.createElement(EditorStack, { gap: 2 }, children));
6951
6988
  };
6952
- const getStyles$e = (theme) => {
6989
+ const getStyles$i = (theme) => {
6953
6990
  return {
6954
6991
  root: css.css({
6955
6992
  padding: theme.spacing(1),
@@ -6963,12 +7000,12 @@ const EditorField = (props) => {
6963
7000
  var _a;
6964
7001
  const { label, optional, tooltip, children, width, ...fieldProps } = props;
6965
7002
  const theme = ui.useTheme2();
6966
- const styles = getStyles$d(theme, width);
7003
+ const styles = getStyles$h(theme, width);
6967
7004
  const childInputId = (fieldProps == null ? void 0 : fieldProps.htmlFor) || ((_a = ui.ReactUtils) == null ? void 0 : _a.getChildId(children));
6968
7005
  const labelEl = /* @__PURE__ */ React__default.default.createElement(React__default.default.Fragment, null, /* @__PURE__ */ React__default.default.createElement("label", { className: styles.label, htmlFor: childInputId }, label, optional && /* @__PURE__ */ React__default.default.createElement("span", { className: styles.optional }, " - optional"), tooltip && /* @__PURE__ */ React__default.default.createElement(ui.Tooltip, { placement: "top", content: tooltip, theme: "info" }, /* @__PURE__ */ React__default.default.createElement(ui.Icon, { name: "info-circle", size: "sm", className: styles.icon }))), /* @__PURE__ */ React__default.default.createElement(Space, { v: 0.5 }));
6969
7006
  return /* @__PURE__ */ React__default.default.createElement("div", { className: styles.root }, /* @__PURE__ */ React__default.default.createElement(ui.Field, { className: styles.field, label: labelEl, ...fieldProps }, children));
6970
7007
  };
6971
- const getStyles$d = ui.stylesFactory((theme, width) => {
7008
+ const getStyles$h = ui.stylesFactory((theme, width) => {
6972
7009
  return {
6973
7010
  root: css.css({
6974
7011
  minWidth: theme.spacing(width != null ? width : 0)
@@ -6999,12 +7036,20 @@ const EditorRows = ({ children }) => {
6999
7036
  return /* @__PURE__ */ React__default.default.createElement(EditorStack, { gap: 0.5, direction: "column" }, children);
7000
7037
  };
7001
7038
 
7002
- const VisualEditor = ({ query, db, queryRowFilter, onChange, onValidate, range }) => {
7039
+ const VisualEditor = ({
7040
+ query,
7041
+ db,
7042
+ queryRowFilter,
7043
+ onChange,
7044
+ onValidate,
7045
+ language = "sql",
7046
+ range
7047
+ }) => {
7003
7048
  const state = reactUse.useAsync(async () => {
7004
7049
  const fields = await db.fields(query);
7005
7050
  return fields;
7006
7051
  }, [db, query.dataset, query.table]);
7007
- return /* @__PURE__ */ React__default.default.createElement(React__default.default.Fragment, null, /* @__PURE__ */ React__default.default.createElement(EditorRows, null, /* @__PURE__ */ React__default.default.createElement(EditorRow, null, /* @__PURE__ */ React__default.default.createElement(SQLSelectRow, { fields: state.value || [], query, onQueryChange: onChange, db })), queryRowFilter.filter && /* @__PURE__ */ React__default.default.createElement(EditorRow, null, /* @__PURE__ */ React__default.default.createElement(EditorField, { label: "Filter by column value", optional: true }, /* @__PURE__ */ React__default.default.createElement(SQLWhereRow, { fields: state.value || [], query, onQueryChange: onChange, db }))), queryRowFilter.group && /* @__PURE__ */ React__default.default.createElement(EditorRow, null, /* @__PURE__ */ React__default.default.createElement(EditorField, { label: "Group by column" }, /* @__PURE__ */ React__default.default.createElement(SQLGroupByRow, { fields: state.value || [], query, onQueryChange: onChange, db }))), queryRowFilter.order && /* @__PURE__ */ React__default.default.createElement(EditorRow, null, /* @__PURE__ */ React__default.default.createElement(SQLOrderByRow, { fields: state.value || [], query, onQueryChange: onChange, db })), queryRowFilter.preview && query.rawSql && /* @__PURE__ */ React__default.default.createElement(EditorRow, null, /* @__PURE__ */ React__default.default.createElement(Preview, { rawSql: query.rawSql }))), /* @__PURE__ */ React__default.default.createElement(QueryToolbox, { db, query, onValidate, range }));
7052
+ return /* @__PURE__ */ React__default.default.createElement(React__default.default.Fragment, null, /* @__PURE__ */ React__default.default.createElement(EditorRows, null, /* @__PURE__ */ React__default.default.createElement(EditorRow, null, /* @__PURE__ */ React__default.default.createElement(SQLSelectRow, { fields: state.value || [], query, onQueryChange: onChange, db })), queryRowFilter.filter && /* @__PURE__ */ React__default.default.createElement(EditorRow, null, /* @__PURE__ */ React__default.default.createElement(EditorField, { label: "Filter by column value", optional: true }, /* @__PURE__ */ React__default.default.createElement(SQLWhereRow, { fields: state.value || [], query, onQueryChange: onChange, db }))), queryRowFilter.group && /* @__PURE__ */ React__default.default.createElement(EditorRow, null, /* @__PURE__ */ React__default.default.createElement(EditorField, { label: "Group by column" }, /* @__PURE__ */ React__default.default.createElement(SQLGroupByRow, { fields: state.value || [], query, onQueryChange: onChange, db }))), queryRowFilter.order && /* @__PURE__ */ React__default.default.createElement(EditorRow, null, /* @__PURE__ */ React__default.default.createElement(SQLOrderByRow, { fields: state.value || [], query, onQueryChange: onChange, db })), queryRowFilter.preview && query.rawSql && /* @__PURE__ */ React__default.default.createElement(EditorRow, null, /* @__PURE__ */ React__default.default.createElement(Preview, { rawSql: query.rawSql, language }))), /* @__PURE__ */ React__default.default.createElement(QueryToolbox, { db, query, onValidate, range }));
7008
7053
  };
7009
7054
 
7010
7055
  const MACRO_NAMES = [
@@ -7023,20 +7068,20 @@ const MACRO_NAMES = [
7023
7068
  "$__unixEpochGroupAlias"
7024
7069
  ];
7025
7070
 
7026
- var __defProp$2 = Object.defineProperty;
7027
- var __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
7028
- var __publicField$2 = (obj, key, value) => __defNormalProp$2(obj, typeof key !== "symbol" ? key + "" : key, value);
7071
+ var __defProp$3 = Object.defineProperty;
7072
+ var __defNormalProp$3 = (obj, key, value) => key in obj ? __defProp$3(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
7073
+ var __publicField$3 = (obj, key, value) => __defNormalProp$3(obj, typeof key !== "symbol" ? key + "" : key, value);
7029
7074
  class SqlDatasource extends runtime.DataSourceWithBackend {
7030
7075
  constructor(instanceSettings, templateSrv = runtime.getTemplateSrv()) {
7031
7076
  super(instanceSettings);
7032
7077
  this.templateSrv = templateSrv;
7033
- __publicField$2(this, "id");
7034
- __publicField$2(this, "name");
7035
- __publicField$2(this, "interval");
7036
- __publicField$2(this, "db");
7037
- __publicField$2(this, "dataset");
7038
- __publicField$2(this, "annotations", {});
7039
- __publicField$2(this, "interpolateVariable", (value, variable) => {
7078
+ __publicField$3(this, "id");
7079
+ __publicField$3(this, "name");
7080
+ __publicField$3(this, "interval");
7081
+ __publicField$3(this, "db");
7082
+ __publicField$3(this, "dataset");
7083
+ __publicField$3(this, "annotations", {});
7084
+ __publicField$3(this, "interpolateVariable", (value, variable) => {
7040
7085
  if (typeof value === "string") {
7041
7086
  if (variable.multi || variable.includeAll) {
7042
7087
  const result = this.getQueryModel().quoteLiteral(value);
@@ -7186,7 +7231,7 @@ const getSearchFilterScopedVar = (args) => {
7186
7231
  };
7187
7232
  };
7188
7233
 
7189
- function SqlQueryEditor({ datasource, query, onChange, onRunQuery, range }) {
7234
+ function SqlQueryEditor({ datasource, query, onChange, onRunQuery, range, language = "sql" }) {
7190
7235
  var _a, _b, _c, _d, _e, _f, _g;
7191
7236
  const [isQueryRunnable, setIsQueryRunnable] = React.useState(true);
7192
7237
  const db = datasource.getDB();
@@ -7262,6 +7307,7 @@ function SqlQueryEditor({ datasource, query, onChange, onRunQuery, range }) {
7262
7307
  {
7263
7308
  db,
7264
7309
  query: queryWithDefaults,
7310
+ language,
7265
7311
  onChange: (q) => onQueryChange(q, false),
7266
7312
  queryRowFilter,
7267
7313
  onValidate: setIsQueryRunnable,
@@ -7271,6 +7317,7 @@ function SqlQueryEditor({ datasource, query, onChange, onRunQuery, range }) {
7271
7317
  RawEditor,
7272
7318
  {
7273
7319
  db,
7320
+ language,
7274
7321
  query: queryWithDefaults,
7275
7322
  queryToValidate,
7276
7323
  onChange: onQueryChange,
@@ -7408,7 +7455,7 @@ const ConfigSubSection = ({ children, ...props }) => {
7408
7455
  function ConfigDescriptionLink(props) {
7409
7456
  const { description, suffix, feature } = props;
7410
7457
  const text = `Learn more about ${feature}`;
7411
- const styles = ui.useStyles2(getStyles$c);
7458
+ const styles = ui.useStyles2(getStyles$g);
7412
7459
  return /* @__PURE__ */ React__default.default.createElement("span", { className: styles.container }, description, /* @__PURE__ */ React__default.default.createElement(
7413
7460
  "a",
7414
7461
  {
@@ -7420,7 +7467,7 @@ function ConfigDescriptionLink(props) {
7420
7467
  text
7421
7468
  ));
7422
7469
  }
7423
- const getStyles$c = (theme) => {
7470
+ const getStyles$g = (theme) => {
7424
7471
  return {
7425
7472
  container: css.css({
7426
7473
  color: theme.colors.text.secondary,
@@ -8389,225 +8436,2460 @@ const AdvancedHttpSettings = ({
8389
8436
  ));
8390
8437
  };
8391
8438
 
8392
- var __defProp$1 = Object.defineProperty;
8393
- var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
8394
- var __publicField$1 = (obj, key, value) => __defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
8395
- const getCustomHeaderRowStyles = ui.stylesFactory(() => {
8396
- return {
8397
- layout: css.css`
8398
- display: flex;
8399
- align-items: center;
8400
- margin-bottom: 4px;
8401
- > * {
8402
- margin-left: 4px;
8403
- margin-bottom: 0;
8404
- height: 100%;
8405
- &:first-child,
8406
- &:last-child {
8407
- margin-left: 0;
8408
- }
8409
- }
8410
- `
8411
- };
8412
- });
8413
- const CustomHeaderRow = ({ header, onBlur, onChange, onRemove, onReset }) => {
8414
- const styles = getCustomHeaderRowStyles();
8415
- return /* @__PURE__ */ React__default.default.createElement("div", { className: styles.layout }, /* @__PURE__ */ React__default.default.createElement(
8416
- ui.LegacyForms.FormField,
8439
+ function resolveGroups(schema) {
8440
+ const fieldMap = /* @__PURE__ */ new Map();
8441
+ for (const f of schema.fields) {
8442
+ fieldMap.set(f.id, f);
8443
+ }
8444
+ if (schema.groups && schema.groups.length > 0) {
8445
+ return schema.groups.slice().sort((a, b) => {
8446
+ var _a, _b;
8447
+ return ((_a = a.order) != null ? _a : 0) - ((_b = b.order) != null ? _b : 0);
8448
+ }).map((g) => ({
8449
+ group: g,
8450
+ fields: g.fieldRefs.map((ref) => fieldMap.get(ref)).filter((f) => f != null)
8451
+ }));
8452
+ }
8453
+ const allFields = schema.fields.filter((f) => f.kind !== "virtual" && !f.isItemField);
8454
+ return [
8417
8455
  {
8418
- label: "Header",
8419
- name: "name",
8420
- placeholder: "X-Custom-Header",
8421
- labelWidth: 5,
8422
- value: header.name || "",
8423
- onChange: (e) => onChange({ ...header, name: e.target.value }),
8424
- onBlur
8456
+ group: { id: "default", title: "Configuration", fieldRefs: allFields.map((f) => f.id) },
8457
+ fields: allFields
8425
8458
  }
8426
- ), /* @__PURE__ */ React__default.default.createElement(
8427
- ui.LegacyForms.SecretFormField,
8428
- {
8429
- label: "Value",
8430
- "aria-label": "Value",
8431
- name: "value",
8432
- isConfigured: header.configured,
8433
- value: header.value,
8434
- labelWidth: 5,
8435
- inputWidth: header.configured ? 11 : 12,
8436
- placeholder: "Header Value",
8437
- onReset: () => onReset(header.id),
8438
- onChange: (e) => onChange({ ...header, value: e.target.value }),
8439
- onBlur
8459
+ ];
8460
+ }
8461
+ function resolveRequiredFieldsGroup(schema) {
8462
+ var _a;
8463
+ const fieldMap = /* @__PURE__ */ new Map();
8464
+ for (const f of schema.fields) {
8465
+ fieldMap.set(f.id, f);
8466
+ }
8467
+ const requiredIds = /* @__PURE__ */ new Set();
8468
+ for (const f of schema.fields) {
8469
+ if (f.required) {
8470
+ requiredIds.add(f.id);
8440
8471
  }
8441
- ), /* @__PURE__ */ React__default.default.createElement(
8442
- ui.Button,
8443
- {
8444
- type: "button",
8445
- "aria-label": "Remove header",
8446
- variant: "secondary",
8447
- size: "xs",
8448
- onClick: (_e) => onRemove(header.id)
8449
- },
8450
- /* @__PURE__ */ React__default.default.createElement(ui.Icon, { name: "trash-alt" })
8451
- ));
8452
- };
8453
- CustomHeaderRow.displayName = "CustomHeaderRow";
8454
- class CustomHeadersSettings extends React.PureComponent {
8455
- constructor(props) {
8456
- super(props);
8457
- __publicField$1(this, "state", {
8458
- headers: []
8459
- });
8460
- __publicField$1(this, "updateSettings", () => {
8461
- const { headers } = this.state;
8462
- const newJsonData = Object.fromEntries(
8463
- Object.entries(this.props.dataSourceConfig.jsonData).filter(([key, val]) => !key.startsWith("httpHeaderName"))
8464
- );
8465
- const newSecureJsonData = Object.fromEntries(
8466
- Object.entries(this.props.dataSourceConfig.secureJsonData || {}).filter(
8467
- ([key, val]) => !key.startsWith("httpHeaderValue")
8468
- )
8469
- );
8470
- for (const [index, header] of headers.entries()) {
8471
- newJsonData[`httpHeaderName${index + 1}`] = header.name;
8472
- if (!header.configured) {
8473
- newSecureJsonData[`httpHeaderValue${index + 1}`] = header.value;
8474
- }
8472
+ }
8473
+ const authGroup = (_a = schema.groups) == null ? void 0 : _a.find((g) => g.id === "auth");
8474
+ if (authGroup) {
8475
+ for (const ref of authGroup.fieldRefs) {
8476
+ if (fieldMap.has(ref)) {
8477
+ requiredIds.add(ref);
8475
8478
  }
8476
- this.props.onChange({
8477
- ...this.props.dataSourceConfig,
8478
- jsonData: newJsonData,
8479
- secureJsonData: newSecureJsonData
8480
- });
8481
- });
8482
- __publicField$1(this, "onHeaderAdd", () => {
8483
- this.setState((prevState) => {
8484
- return {
8485
- headers: [...prevState.headers, { id: lodash.uniqueId(), name: "", value: "", configured: false }]
8486
- };
8487
- });
8488
- });
8489
- __publicField$1(this, "onHeaderChange", (headerIndex, value) => {
8490
- this.setState(({ headers }) => {
8491
- return {
8492
- headers: headers.map((item, index) => {
8493
- if (headerIndex !== index) {
8494
- return item;
8495
- }
8496
- return { ...value };
8497
- })
8498
- };
8499
- });
8500
- });
8501
- __publicField$1(this, "onHeaderReset", (headerId) => {
8502
- this.setState(({ headers }) => {
8503
- return {
8504
- headers: headers.map((h, i) => {
8505
- if (h.id !== headerId) {
8506
- return h;
8507
- }
8508
- return {
8509
- ...h,
8510
- value: "",
8511
- configured: false
8512
- };
8513
- })
8514
- };
8515
- });
8516
- });
8517
- __publicField$1(this, "onHeaderRemove", (headerId) => {
8518
- this.setState(
8519
- ({ headers }) => ({
8520
- headers: headers.filter((h) => h.id !== headerId)
8521
- }),
8522
- this.updateSettings
8523
- );
8524
- });
8525
- const { jsonData, secureJsonData, secureJsonFields } = this.props.dataSourceConfig;
8526
- this.state = {
8527
- headers: Object.keys(jsonData).sort().filter((key) => key.startsWith("httpHeaderName")).map((key, index) => {
8528
- return {
8529
- id: lodash.uniqueId(),
8530
- name: jsonData[key],
8531
- value: secureJsonData !== void 0 ? secureJsonData[key] : "",
8532
- configured: secureJsonFields && secureJsonFields[`httpHeaderValue${index + 1}`] || false
8533
- };
8534
- })
8535
- };
8479
+ }
8536
8480
  }
8537
- render() {
8538
- const { headers } = this.state;
8539
- return /* @__PURE__ */ React__default.default.createElement("div", { className: "gf-form-group" }, /* @__PURE__ */ React__default.default.createElement("div", { className: "gf-form" }, /* @__PURE__ */ React__default.default.createElement("h6", null, "Custom HTTP Headers")), /* @__PURE__ */ React__default.default.createElement("div", null, headers.map((header, i) => /* @__PURE__ */ React__default.default.createElement(
8540
- CustomHeaderRow,
8541
- {
8542
- key: header.id,
8543
- header,
8544
- onChange: (h) => {
8545
- this.onHeaderChange(i, h);
8546
- },
8547
- onBlur: this.updateSettings,
8548
- onRemove: this.onHeaderRemove,
8549
- onReset: this.onHeaderReset
8481
+ if (requiredIds.size === 0) {
8482
+ return null;
8483
+ }
8484
+ const includeIds = /* @__PURE__ */ new Set();
8485
+ for (const id of requiredIds) {
8486
+ includeIds.add(id);
8487
+ const f = fieldMap.get(id);
8488
+ if (f == null ? void 0 : f.dependsOn) {
8489
+ const parsed = parseDependsOn(f.dependsOn);
8490
+ if (parsed && fieldMap.has(parsed.field)) {
8491
+ includeIds.add(parsed.field);
8550
8492
  }
8551
- ))), /* @__PURE__ */ React__default.default.createElement("div", { className: "gf-form" }, /* @__PURE__ */ React__default.default.createElement(
8552
- ui.Button,
8553
- {
8554
- variant: "secondary",
8555
- icon: "plus",
8556
- type: "button",
8557
- onClick: (e) => {
8558
- this.onHeaderAdd();
8559
- }
8560
- },
8561
- "Add header"
8562
- )));
8493
+ }
8563
8494
  }
8564
- }
8565
-
8566
- var QueryEditorMode = /* @__PURE__ */ ((QueryEditorMode2) => {
8567
- QueryEditorMode2["Code"] = "code";
8568
- QueryEditorMode2["Builder"] = "builder";
8569
- return QueryEditorMode2;
8570
- })(QueryEditorMode || {});
8571
- const BINARY_OPERATIONS_KEY = "Binary operations";
8572
-
8573
- var __defProp = Object.defineProperty;
8574
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
8575
- var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
8576
- class QueryModellerBase {
8577
- constructor(operationDefinitions, innerQueryPlaceholder) {
8578
- __publicField(this, "operationsRegistry");
8579
- __publicField(this, "categories", []);
8580
- __publicField(this, "innerQueryPlaceholder");
8581
- this.operationsRegistry = new data.Registry(() => operationDefinitions);
8582
- this.innerQueryPlaceholder = innerQueryPlaceholder || "<query>";
8495
+ for (const f of schema.fields) {
8496
+ if (f.dependsOn && !includeIds.has(f.id)) {
8497
+ const parsed = parseDependsOn(f.dependsOn);
8498
+ if (parsed && requiredIds.has(parsed.field)) {
8499
+ includeIds.add(f.id);
8500
+ }
8501
+ }
8583
8502
  }
8584
- setOperationCategories(categories) {
8585
- this.categories = categories;
8503
+ const virtualFields = schema.fields.filter((f) => includeIds.has(f.id));
8504
+ if (virtualFields.length === 0) {
8505
+ return null;
8586
8506
  }
8587
- getOperationsForCategory(category) {
8588
- return this.operationsRegistry.list().filter((op) => op.category === category && !op.hideFromList);
8507
+ return {
8508
+ group: {
8509
+ id: "_required",
8510
+ title: "Required",
8511
+ fieldRefs: virtualFields.map((f) => f.id)
8512
+ },
8513
+ fields: virtualFields
8514
+ };
8515
+ }
8516
+ function formKey(field) {
8517
+ return field.section ? `${field.section}.${field.key}` : field.key;
8518
+ }
8519
+ function parseDependsOn(expr) {
8520
+ var _a, _b;
8521
+ const m = expr.match(/^(.+?)\s*==\s*(?:'([^']*)'|"([^"]*)"|(.+))$/);
8522
+ if (!m) {
8523
+ return null;
8589
8524
  }
8590
- getAlternativeOperations(key) {
8591
- return this.operationsRegistry.list().filter((op) => op.alternativesKey && op.alternativesKey === key);
8525
+ return { field: m[1].trim(), value: ((_b = (_a = m[2]) != null ? _a : m[3]) != null ? _b : m[4]).trim() };
8526
+ }
8527
+ function resolveActiveOverride(field, watchedValues, fieldById) {
8528
+ var _a;
8529
+ if (!field.overrides || field.overrides.length === 0) {
8530
+ return void 0;
8592
8531
  }
8593
- getCategories() {
8594
- return this.categories;
8532
+ for (const ov of field.overrides) {
8533
+ const parsed = parseDependsOn(ov.when);
8534
+ if (!parsed) {
8535
+ continue;
8536
+ }
8537
+ const depField = fieldById.get(parsed.field);
8538
+ const depKey = depField ? formKey(depField) : parsed.field;
8539
+ if (String((_a = watchedValues[depKey]) != null ? _a : "") === parsed.value) {
8540
+ return ov;
8541
+ }
8595
8542
  }
8596
- getOperationDefinition(id) {
8597
- return this.operationsRegistry.getIfExists(id);
8543
+ return void 0;
8544
+ }
8545
+ function resolveFieldValue(ref, values, fields) {
8546
+ if (ref in values) {
8547
+ return values[ref];
8598
8548
  }
8599
- hasBinaryOp(query) {
8600
- return query.operations.find((op) => {
8601
- const def = this.getOperationDefinition(op.id);
8602
- return (def == null ? void 0 : def.category) === BINARY_OPERATIONS_KEY;
8603
- }) !== void 0;
8549
+ const field = fields.find((f) => f.id === ref);
8550
+ if (field) {
8551
+ const fk = formKey(field);
8552
+ if (fk in values) {
8553
+ return values[fk];
8554
+ }
8604
8555
  }
8556
+ return void 0;
8605
8557
  }
8606
-
8607
- const CONFLICTING_LABEL_FILTER_ERROR_MESSAGE = "You have conflicting label filters";
8608
- function LabelFilterItem({
8609
- item,
8610
- items,
8558
+ function evaluateComputedRead(expr, values, fields) {
8559
+ function evalExpr(s) {
8560
+ var _a;
8561
+ s = s.trim();
8562
+ if (s.startsWith("(") && findMatchingParen(s, 0) === s.length - 1) {
8563
+ s = s.slice(1, -1).trim();
8564
+ }
8565
+ const qIdx = findTopLevel(s, "?");
8566
+ if (qIdx !== -1) {
8567
+ const condition = s.slice(0, qIdx).trim();
8568
+ const rest = s.slice(qIdx + 1);
8569
+ const cIdx = findTopLevel(rest, ":");
8570
+ if (cIdx !== -1) {
8571
+ const trueExpr = rest.slice(0, cIdx).trim();
8572
+ const falseExpr = rest.slice(cIdx + 1).trim();
8573
+ return evalCondition(condition) ? evalExpr(trueExpr) : evalExpr(falseExpr);
8574
+ }
8575
+ }
8576
+ const strMatch = (_a = s.match(/^'([^']*)'$/)) != null ? _a : s.match(/^"([^"]*)"$/);
8577
+ if (strMatch) {
8578
+ return strMatch[1];
8579
+ }
8580
+ if (s === "true") {
8581
+ return true;
8582
+ }
8583
+ if (s === "false") {
8584
+ return false;
8585
+ }
8586
+ if (/^-?\d+(\.\d+)?$/.test(s)) {
8587
+ return Number(s);
8588
+ }
8589
+ return resolveFieldValue(s, values, fields);
8590
+ }
8591
+ function evalCondition(cond) {
8592
+ const eqMatch = cond.match(/^(.+?)\s*(==|!=)\s*(.+)$/);
8593
+ if (eqMatch) {
8594
+ const left = evalExpr(eqMatch[1]);
8595
+ const right = evalExpr(eqMatch[3]);
8596
+ const eq = String(left) === String(right);
8597
+ return eqMatch[2] === "==" ? eq : !eq;
8598
+ }
8599
+ return !!evalExpr(cond);
8600
+ }
8601
+ function findMatchingParen(s, start) {
8602
+ let depth = 0;
8603
+ for (let i = start; i < s.length; i++) {
8604
+ if (s[i] === "(") {
8605
+ depth++;
8606
+ } else if (s[i] === ")") {
8607
+ depth--;
8608
+ if (depth === 0) {
8609
+ return i;
8610
+ }
8611
+ }
8612
+ }
8613
+ return -1;
8614
+ }
8615
+ function findTopLevel(s, char) {
8616
+ let depth = 0;
8617
+ let inStr = null;
8618
+ for (let i = 0; i < s.length; i++) {
8619
+ const c = s[i];
8620
+ if (inStr) {
8621
+ if (c === inStr) {
8622
+ inStr = null;
8623
+ }
8624
+ continue;
8625
+ }
8626
+ if (c === "'" || c === '"') {
8627
+ inStr = c;
8628
+ continue;
8629
+ }
8630
+ if (c === "(") {
8631
+ depth++;
8632
+ continue;
8633
+ }
8634
+ if (c === ")") {
8635
+ depth--;
8636
+ continue;
8637
+ }
8638
+ if (depth === 0 && c === char) {
8639
+ return i;
8640
+ }
8641
+ }
8642
+ return -1;
8643
+ }
8644
+ try {
8645
+ return evalExpr(expr);
8646
+ } catch (e) {
8647
+ return void 0;
8648
+ }
8649
+ }
8650
+ function computeVirtualFieldValues(schema, existingValues) {
8651
+ var _a;
8652
+ const virtualValues = {};
8653
+ for (const field of schema.fields) {
8654
+ if (field.kind !== "virtual") {
8655
+ continue;
8656
+ }
8657
+ const fk = formKey(field);
8658
+ if (((_a = field.storage) == null ? void 0 : _a.type) === "computed" && field.storage.read) {
8659
+ const val = evaluateComputedRead(field.storage.read, existingValues, schema.fields);
8660
+ if (val !== void 0) {
8661
+ virtualValues[fk] = val;
8662
+ } else if (field.defaultValue !== void 0) {
8663
+ virtualValues[fk] = field.defaultValue;
8664
+ }
8665
+ } else if (field.defaultValue !== void 0) {
8666
+ virtualValues[fk] = field.defaultValue;
8667
+ }
8668
+ }
8669
+ return virtualValues;
8670
+ }
8671
+
8672
+ const SECURE_FIELD_CONFIGURED = "__CONFIGURED__";
8673
+ function patternToRegex(pattern) {
8674
+ const escaped = pattern.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
8675
+ return new RegExp("^" + escaped.replace("\\{index\\}", "(\\d+)") + "$");
8676
+ }
8677
+ function findIndicesForPattern(record, pattern) {
8678
+ const re = patternToRegex(pattern);
8679
+ const indices = [];
8680
+ for (const key of Object.keys(record)) {
8681
+ const m = key.match(re);
8682
+ if (m) {
8683
+ const n = Number(m[1]);
8684
+ if (!Number.isNaN(n)) {
8685
+ indices.push(n);
8686
+ }
8687
+ }
8688
+ }
8689
+ return indices.sort((a, b) => a - b);
8690
+ }
8691
+ function expandIndexedPair(field, ds) {
8692
+ var _a, _b, _c;
8693
+ const storage = field.storage;
8694
+ if ((storage == null ? void 0 : storage.type) !== "indexedPair" || !storage.key || !storage.value) {
8695
+ return [];
8696
+ }
8697
+ const source = storage.key.target === "jsonData" ? (_a = ds.jsonData) != null ? _a : {} : ds;
8698
+ const indices = findIndicesForPattern(source, storage.key.pattern);
8699
+ const items = [];
8700
+ for (const i of indices) {
8701
+ const nameKey = storage.key.pattern.replace("{index}", String(i));
8702
+ const valueKey = storage.value.pattern.replace("{index}", String(i));
8703
+ const nameVal = source[nameKey];
8704
+ if (nameVal === void 0 || nameVal === null) {
8705
+ continue;
8706
+ }
8707
+ const hasValue = storage.value.target === "secureJsonData" ? !!((_b = ds.secureJsonFields) == null ? void 0 : _b[valueKey]) : !!((_c = ds.jsonData) == null ? void 0 : _c[valueKey]);
8708
+ items.push({
8709
+ index: i,
8710
+ name: String(nameVal),
8711
+ value: hasValue ? SECURE_FIELD_CONFIGURED : ""
8712
+ });
8713
+ }
8714
+ return items;
8715
+ }
8716
+ function flattenIndexedPair(field, items, jsonData, secureJsonData, secureJsonFields) {
8717
+ var _a;
8718
+ const storage = field.storage;
8719
+ if ((storage == null ? void 0 : storage.type) !== "indexedPair" || !storage.key || !storage.value) {
8720
+ return;
8721
+ }
8722
+ const existingIndices = new Set(
8723
+ storage.key.target === "jsonData" ? findIndicesForPattern(jsonData, storage.key.pattern) : []
8724
+ );
8725
+ const usedIndices = /* @__PURE__ */ new Set();
8726
+ const startIdx = (_a = storage.startIndex) != null ? _a : 1;
8727
+ let nextIndex = existingIndices.size > 0 ? Math.max(...existingIndices) + 1 : startIdx;
8728
+ for (const item of items) {
8729
+ let idx = item.index;
8730
+ if (idx === 0) {
8731
+ idx = nextIndex++;
8732
+ }
8733
+ usedIndices.add(idx);
8734
+ const nameKey = storage.key.pattern.replace("{index}", String(idx));
8735
+ const valueKey = storage.value.pattern.replace("{index}", String(idx));
8736
+ if (storage.key.target === "jsonData") {
8737
+ jsonData[nameKey] = item.name;
8738
+ }
8739
+ if (storage.value.target === "secureJsonData") {
8740
+ if (item.value === SECURE_FIELD_CONFIGURED) {
8741
+ secureJsonFields[valueKey] = true;
8742
+ } else if (item.value) {
8743
+ secureJsonData[valueKey] = item.value;
8744
+ secureJsonFields[valueKey] = false;
8745
+ }
8746
+ } else if (storage.value.target === "jsonData") {
8747
+ jsonData[valueKey] = item.value;
8748
+ }
8749
+ }
8750
+ for (const idx of existingIndices) {
8751
+ if (usedIndices.has(idx)) {
8752
+ continue;
8753
+ }
8754
+ const nameKey = storage.key.pattern.replace("{index}", String(idx));
8755
+ const valueKey = storage.value.pattern.replace("{index}", String(idx));
8756
+ if (storage.key.target === "jsonData") {
8757
+ delete jsonData[nameKey];
8758
+ }
8759
+ if (storage.value.target === "secureJsonData") {
8760
+ delete secureJsonFields[valueKey];
8761
+ delete secureJsonData[valueKey];
8762
+ } else if (storage.value.target === "jsonData") {
8763
+ delete jsonData[valueKey];
8764
+ }
8765
+ }
8766
+ }
8767
+ function resolveRawPath(ref, ds) {
8768
+ var _a;
8769
+ const trimmed = ref.trim();
8770
+ if (trimmed.startsWith("jsonData.")) {
8771
+ return (_a = ds.jsonData) == null ? void 0 : _a[trimmed.slice(9)];
8772
+ }
8773
+ if (trimmed.startsWith("root.")) {
8774
+ return ds[trimmed.slice(5)];
8775
+ }
8776
+ return void 0;
8777
+ }
8778
+ async function fetchExistingValues(dsUid, fields) {
8779
+ var _a, _b, _c, _d, _e;
8780
+ try {
8781
+ const ds = await runtime.getBackendSrv().get(`/api/datasources/uid/${dsUid}`, void 0, void 0, {
8782
+ showErrorAlert: false
8783
+ });
8784
+ const values = {};
8785
+ for (const field of fields) {
8786
+ if (((_a = field.storage) == null ? void 0 : _a.type) === "indexedPair") {
8787
+ values[field.key] = expandIndexedPair(field, ds);
8788
+ continue;
8789
+ }
8790
+ const fk = formKey(field);
8791
+ switch (field.target) {
8792
+ case "root":
8793
+ if (ds[field.key] !== void 0) {
8794
+ values[fk] = ds[field.key];
8795
+ }
8796
+ break;
8797
+ case "jsonData":
8798
+ if (field.section) {
8799
+ const sectionObj = (_b = ds.jsonData) == null ? void 0 : _b[field.section];
8800
+ if ((sectionObj == null ? void 0 : sectionObj[field.key]) !== void 0) {
8801
+ values[fk] = sectionObj[field.key];
8802
+ }
8803
+ } else if (((_c = ds.jsonData) == null ? void 0 : _c[field.key]) !== void 0) {
8804
+ values[fk] = ds.jsonData[field.key];
8805
+ }
8806
+ break;
8807
+ case "secureJsonData":
8808
+ if ((_d = ds.secureJsonFields) == null ? void 0 : _d[field.key]) {
8809
+ values[fk] = SECURE_FIELD_CONFIGURED;
8810
+ }
8811
+ break;
8812
+ }
8813
+ if (values[fk] === void 0 && ((_e = field.storage) == null ? void 0 : _e.type) === "computed" && field.storage.read) {
8814
+ const fallback = resolveRawPath(field.storage.read, ds);
8815
+ if (fallback !== void 0) {
8816
+ values[fk] = fallback;
8817
+ }
8818
+ }
8819
+ }
8820
+ return { values, readOnly: !!ds.readOnly };
8821
+ } catch (err) {
8822
+ const message = err instanceof Error ? err.message : "Failed to load datasource configuration";
8823
+ return { values: {}, readOnly: false, error: message };
8824
+ }
8825
+ }
8826
+ function buildDatasourceConfigPayload(data, fields, existing, isFieldVisible) {
8827
+ var _a, _b, _c, _d;
8828
+ const rootFields = {};
8829
+ const jsonData = { ...(_a = existing.jsonData) != null ? _a : {} };
8830
+ const secureJsonData = {};
8831
+ const secureJsonFields = { ...(_b = existing.secureJsonFields) != null ? _b : {} };
8832
+ for (const field of fields) {
8833
+ if (((_c = field.storage) == null ? void 0 : _c.type) === "indexedPair") {
8834
+ const items = Array.isArray(data[field.key]) ? data[field.key] : [];
8835
+ flattenIndexedPair(field, items, jsonData, secureJsonData, secureJsonFields);
8836
+ continue;
8837
+ }
8838
+ const isManagedByEffect = (_d = field.tags) == null ? void 0 : _d.some((t) => t.startsWith("managed-by:"));
8839
+ if (!isManagedByEffect && !isFieldVisible(field)) {
8840
+ continue;
8841
+ }
8842
+ const fk = formKey(field);
8843
+ const value = data[fk];
8844
+ if (field.target === "secureJsonData") {
8845
+ if (value === SECURE_FIELD_CONFIGURED) {
8846
+ secureJsonFields[field.key] = true;
8847
+ continue;
8848
+ }
8849
+ if (value && value !== "") {
8850
+ secureJsonData[field.key] = String(value);
8851
+ secureJsonFields[field.key] = false;
8852
+ } else {
8853
+ secureJsonFields[field.key] = false;
8854
+ }
8855
+ continue;
8856
+ }
8857
+ if (value === void 0 || value === "") {
8858
+ continue;
8859
+ }
8860
+ switch (field.target) {
8861
+ case "root":
8862
+ rootFields[field.key] = value;
8863
+ break;
8864
+ case "jsonData":
8865
+ if (field.section) {
8866
+ if (!jsonData[field.section] || typeof jsonData[field.section] !== "object") {
8867
+ jsonData[field.section] = {};
8868
+ }
8869
+ jsonData[field.section][field.key] = value;
8870
+ } else {
8871
+ jsonData[field.key] = value;
8872
+ }
8873
+ break;
8874
+ }
8875
+ }
8876
+ return { rootFields, jsonData, secureJsonData, secureJsonFields };
8877
+ }
8878
+ async function submitDatasourceConfig(dsUid, data, fields, isFieldVisible) {
8879
+ const existing = await runtime.getBackendSrv().get(`/api/datasources/uid/${dsUid}`);
8880
+ const { rootFields, jsonData, secureJsonData, secureJsonFields } = buildDatasourceConfigPayload(
8881
+ data,
8882
+ fields,
8883
+ existing,
8884
+ isFieldVisible
8885
+ );
8886
+ await runtime.getBackendSrv().put(`/api/datasources/uid/${dsUid}`, {
8887
+ ...existing,
8888
+ ...rootFields,
8889
+ jsonData,
8890
+ secureJsonData,
8891
+ secureJsonFields
8892
+ });
8893
+ }
8894
+
8895
+ function evaluateEffectCondition(when, fieldValue) {
8896
+ var _a, _b;
8897
+ const m = when.match(/^value\s*(==|!=)\s*(?:'([^']*)'|"([^"]*)"|(.+))$/);
8898
+ if (!m) {
8899
+ return false;
8900
+ }
8901
+ const op = m[1];
8902
+ let target = (_b = (_a = m[2]) != null ? _a : m[3]) != null ? _b : m[4];
8903
+ if (target === "true") {
8904
+ target = true;
8905
+ } else if (target === "false") {
8906
+ target = false;
8907
+ } else if (typeof target === "string" && /^-?\d+(\.\d+)?$/.test(target)) {
8908
+ target = Number(target);
8909
+ }
8910
+ const eq = String(fieldValue) === String(target);
8911
+ return op === "==" ? eq : !eq;
8912
+ }
8913
+ function isFieldRequired(field, watchedValues, fieldById) {
8914
+ var _a;
8915
+ if (field.required) {
8916
+ return true;
8917
+ }
8918
+ if (field.requiredWhen) {
8919
+ const parsed = parseDependsOn(field.requiredWhen);
8920
+ if (parsed) {
8921
+ const depField = fieldById.get(parsed.field);
8922
+ const depKey = depField ? formKey(depField) : parsed.field;
8923
+ return String((_a = watchedValues[depKey]) != null ? _a : "") === parsed.value;
8924
+ }
8925
+ }
8926
+ return false;
8927
+ }
8928
+ function buildValidationRules(field, required) {
8929
+ var _a, _b, _c, _d, _e, _f;
8930
+ const rules = {};
8931
+ const label = (_a = field.label) != null ? _a : field.key;
8932
+ if (required) {
8933
+ if (field.target === "secureJsonData") {
8934
+ rules.validate = (value) => {
8935
+ if (value === SECURE_FIELD_CONFIGURED) {
8936
+ return true;
8937
+ }
8938
+ if (!value || value === "") {
8939
+ return `${label} is required`;
8940
+ }
8941
+ return true;
8942
+ };
8943
+ } else {
8944
+ rules.required = `${label} is required`;
8945
+ }
8946
+ }
8947
+ if (field.validations) {
8948
+ for (const v of field.validations) {
8949
+ switch (v.type) {
8950
+ case "pattern":
8951
+ rules.pattern = {
8952
+ value: new RegExp(v.pattern),
8953
+ message: (_b = v.message) != null ? _b : `Invalid ${label}`
8954
+ };
8955
+ break;
8956
+ case "range":
8957
+ if (v.min !== void 0) {
8958
+ rules.min = { value: v.min, message: (_c = v.message) != null ? _c : `Minimum value is ${v.min}` };
8959
+ }
8960
+ if (v.max !== void 0) {
8961
+ rules.max = { value: v.max, message: (_d = v.message) != null ? _d : `Maximum value is ${v.max}` };
8962
+ }
8963
+ break;
8964
+ case "length":
8965
+ if (v.min !== void 0) {
8966
+ rules.minLength = { value: v.min, message: (_e = v.message) != null ? _e : `Minimum length is ${v.min}` };
8967
+ }
8968
+ if (v.max !== void 0) {
8969
+ rules.maxLength = { value: v.max, message: (_f = v.message) != null ? _f : `Maximum length is ${v.max}` };
8970
+ }
8971
+ break;
8972
+ }
8973
+ }
8974
+ }
8975
+ return rules;
8976
+ }
8977
+
8978
+ function PdcFieldNote({
8979
+ enabled,
8980
+ description,
8981
+ configUrl
8982
+ }) {
8983
+ const styles = ui.useStyles2(getStyles$f);
8984
+ return /* @__PURE__ */ React__default.default.createElement("div", { className: styles.wrapper }, /* @__PURE__ */ React__default.default.createElement("div", { className: styles.note }, /* @__PURE__ */ React__default.default.createElement(ui.Icon, { name: "shield", size: "xs" }), /* @__PURE__ */ React__default.default.createElement("span", null, "Private data source connect: ", /* @__PURE__ */ React__default.default.createElement("strong", null, enabled ? "Enabled" : "Disabled")), description && /* @__PURE__ */ React__default.default.createElement(ui.Tooltip, { content: description }, /* @__PURE__ */ React__default.default.createElement(ui.Icon, { name: "info-circle", size: "xs" }))), /* @__PURE__ */ React__default.default.createElement(ui.LinkButton, { variant: "secondary", size: "sm", icon: "external-link-alt", href: configUrl }, "Configure in settings"));
8985
+ }
8986
+ const getStyles$f = (theme) => ({
8987
+ wrapper: css.css({
8988
+ display: "flex",
8989
+ alignItems: "center",
8990
+ justifyContent: "space-between",
8991
+ gap: theme.spacing(1),
8992
+ padding: `${theme.spacing(0.5)} ${theme.spacing(0.75)}`,
8993
+ fontSize: theme.typography.bodySmall.fontSize,
8994
+ color: theme.colors.text.secondary,
8995
+ backgroundColor: theme.colors.background.secondary,
8996
+ borderRadius: theme.shape.radius.default,
8997
+ border: `1px solid ${theme.colors.border.weak}`
8998
+ }),
8999
+ note: css.css({
9000
+ display: "inline-flex",
9001
+ alignItems: "center",
9002
+ gap: theme.spacing(0.5)
9003
+ })
9004
+ });
9005
+
9006
+ function SecureFieldInput({
9007
+ formField,
9008
+ placeholder,
9009
+ disabled,
9010
+ label
9011
+ }) {
9012
+ var _a;
9013
+ const isConfigured = formField.value === SECURE_FIELD_CONFIGURED;
9014
+ const [revealed, setRevealed] = React.useState(false);
9015
+ const styles = ui.useStyles2(getSecureFieldStyles);
9016
+ if (isConfigured) {
9017
+ return /* @__PURE__ */ React__default.default.createElement("div", { className: styles.configuredRow }, /* @__PURE__ */ React__default.default.createElement("span", { className: styles.configuredBadge }, /* @__PURE__ */ React__default.default.createElement(ui.Icon, { name: "lock", size: "xs" }), label, " configured"), !disabled && /* @__PURE__ */ React__default.default.createElement(ui.Button, { variant: "secondary", fill: "text", size: "sm", onClick: () => formField.onChange(""), type: "button" }, "Reset"));
9018
+ }
9019
+ return /* @__PURE__ */ React__default.default.createElement(
9020
+ ui.Input,
9021
+ {
9022
+ ...formField,
9023
+ value: String((_a = formField.value) != null ? _a : ""),
9024
+ type: revealed ? "text" : "password",
9025
+ placeholder,
9026
+ disabled,
9027
+ suffix: /* @__PURE__ */ React__default.default.createElement(
9028
+ ui.Button,
9029
+ {
9030
+ variant: "secondary",
9031
+ fill: "text",
9032
+ size: "sm",
9033
+ icon: revealed ? "eye-slash" : "eye",
9034
+ "aria-label": revealed ? "Hide" : "Reveal",
9035
+ onClick: () => setRevealed((r) => !r),
9036
+ type: "button"
9037
+ }
9038
+ )
9039
+ }
9040
+ );
9041
+ }
9042
+ const getSecureFieldStyles = (theme) => ({
9043
+ configuredRow: css.css({
9044
+ display: "flex",
9045
+ alignItems: "center",
9046
+ gap: theme.spacing(1)
9047
+ }),
9048
+ configuredBadge: css.css({
9049
+ display: "inline-flex",
9050
+ alignItems: "center",
9051
+ gap: theme.spacing(0.5),
9052
+ padding: `${theme.spacing(0.25)} ${theme.spacing(0.75)}`,
9053
+ borderRadius: theme.shape.radius.pill,
9054
+ backgroundColor: theme.colors.success.transparent,
9055
+ color: theme.colors.success.text,
9056
+ fontSize: theme.typography.bodySmall.fontSize
9057
+ })
9058
+ });
9059
+
9060
+ function StringArrayInput({
9061
+ value,
9062
+ onChange,
9063
+ placeholder,
9064
+ disabled
9065
+ }) {
9066
+ const [draft, setDraft] = React.useState("");
9067
+ const styles = ui.useStyles2(getStyles$e);
9068
+ const addTag = () => {
9069
+ const trimmed = draft.trim();
9070
+ if (trimmed && !value.includes(trimmed)) {
9071
+ onChange([...value, trimmed]);
9072
+ }
9073
+ setDraft("");
9074
+ };
9075
+ const removeTag = (tag) => {
9076
+ onChange(value.filter((v) => v !== tag));
9077
+ };
9078
+ return /* @__PURE__ */ React__default.default.createElement("div", { className: styles.container }, value.length > 0 && /* @__PURE__ */ React__default.default.createElement("div", { className: styles.tags }, value.map((tag) => /* @__PURE__ */ React__default.default.createElement("span", { key: tag, className: styles.tag }, tag, !disabled && /* @__PURE__ */ React__default.default.createElement(
9079
+ "button",
9080
+ {
9081
+ type: "button",
9082
+ className: styles.tagRemove,
9083
+ onClick: () => removeTag(tag),
9084
+ "aria-label": `Remove ${tag}`
9085
+ },
9086
+ /* @__PURE__ */ React__default.default.createElement(ui.Icon, { name: "times", size: "xs" })
9087
+ )))), /* @__PURE__ */ React__default.default.createElement(
9088
+ ui.Input,
9089
+ {
9090
+ value: draft,
9091
+ onChange: (e) => setDraft(e.currentTarget.value),
9092
+ onKeyDown: (e) => {
9093
+ if (e.key === "Enter") {
9094
+ e.preventDefault();
9095
+ addTag();
9096
+ }
9097
+ },
9098
+ onBlur: addTag,
9099
+ placeholder,
9100
+ disabled
9101
+ }
9102
+ ));
9103
+ }
9104
+ const getStyles$e = (theme) => ({
9105
+ container: css.css({
9106
+ display: "flex",
9107
+ flexDirection: "column",
9108
+ gap: theme.spacing(0.5)
9109
+ }),
9110
+ tags: css.css({
9111
+ display: "flex",
9112
+ flexWrap: "wrap",
9113
+ gap: theme.spacing(0.5)
9114
+ }),
9115
+ tag: css.css({
9116
+ display: "inline-flex",
9117
+ alignItems: "center",
9118
+ gap: theme.spacing(0.25),
9119
+ padding: `${theme.spacing(0.25)} ${theme.spacing(0.75)}`,
9120
+ borderRadius: theme.shape.radius.pill,
9121
+ backgroundColor: theme.colors.background.secondary,
9122
+ border: `1px solid ${theme.colors.border.weak}`,
9123
+ fontSize: theme.typography.bodySmall.fontSize,
9124
+ color: theme.colors.text.primary
9125
+ }),
9126
+ tagRemove: css.css({
9127
+ display: "inline-flex",
9128
+ alignItems: "center",
9129
+ padding: 0,
9130
+ border: "none",
9131
+ backgroundColor: "transparent",
9132
+ cursor: "pointer",
9133
+ color: theme.colors.text.secondary,
9134
+ "&:hover": { color: theme.colors.text.primary }
9135
+ })
9136
+ });
9137
+
9138
+ function IndexedPairRow({
9139
+ item,
9140
+ index,
9141
+ disabled,
9142
+ onUpdate,
9143
+ onRemove,
9144
+ hideControls
9145
+ }) {
9146
+ const styles = ui.useStyles2(getStyles$d);
9147
+ const secureStyles = ui.useStyles2(getSecureFieldStyles);
9148
+ const isConfigured = item.value === SECURE_FIELD_CONFIGURED;
9149
+ const [editing, setEditing] = React.useState(false);
9150
+ const [revealed, setRevealed] = React.useState(false);
9151
+ return /* @__PURE__ */ React__default.default.createElement(ui.Stack, { direction: "row", gap: 1 }, /* @__PURE__ */ React__default.default.createElement("div", { className: styles.inputCell }, /* @__PURE__ */ React__default.default.createElement(
9152
+ ui.Input,
9153
+ {
9154
+ value: item.name,
9155
+ placeholder: "Header name",
9156
+ disabled: disabled || hideControls,
9157
+ onChange: (e) => onUpdate(index, "name", e.currentTarget.value)
9158
+ }
9159
+ )), /* @__PURE__ */ React__default.default.createElement("div", { className: styles.inputCell }, isConfigured && !editing ? /* @__PURE__ */ React__default.default.createElement(ui.Stack, { direction: "row", gap: 1, alignItems: "center" }, /* @__PURE__ */ React__default.default.createElement("span", { className: secureStyles.configuredBadge }, /* @__PURE__ */ React__default.default.createElement(ui.Icon, { name: "lock", size: "xs" }), "Configured"), !disabled && /* @__PURE__ */ React__default.default.createElement(
9160
+ ui.Button,
9161
+ {
9162
+ variant: "secondary",
9163
+ fill: "text",
9164
+ size: "sm",
9165
+ onClick: () => {
9166
+ setEditing(true);
9167
+ onUpdate(index, "value", "");
9168
+ },
9169
+ type: "button"
9170
+ },
9171
+ "Reset"
9172
+ )) : /* @__PURE__ */ React__default.default.createElement(
9173
+ ui.Input,
9174
+ {
9175
+ value: item.value === SECURE_FIELD_CONFIGURED ? "" : item.value,
9176
+ placeholder: "Header value",
9177
+ disabled,
9178
+ type: revealed ? "text" : "password",
9179
+ onChange: (e) => onUpdate(index, "value", e.currentTarget.value),
9180
+ suffix: /* @__PURE__ */ React__default.default.createElement(
9181
+ ui.Button,
9182
+ {
9183
+ variant: "secondary",
9184
+ fill: "text",
9185
+ size: "sm",
9186
+ icon: revealed ? "eye-slash" : "eye",
9187
+ "aria-label": revealed ? "Hide" : "Reveal",
9188
+ onClick: () => setRevealed((r) => !r),
9189
+ type: "button"
9190
+ }
9191
+ )
9192
+ }
9193
+ )), !hideControls && /* @__PURE__ */ React__default.default.createElement(ui.Tooltip, { content: "Remove header" }, /* @__PURE__ */ React__default.default.createElement(
9194
+ ui.Button,
9195
+ {
9196
+ variant: "secondary",
9197
+ fill: "text",
9198
+ size: "sm",
9199
+ icon: "trash-alt",
9200
+ "aria-label": "Remove header",
9201
+ disabled,
9202
+ onClick: () => onRemove(index),
9203
+ type: "button"
9204
+ }
9205
+ )));
9206
+ }
9207
+ function IndexedPairEditor({
9208
+ value,
9209
+ onChange,
9210
+ maxItems = 10,
9211
+ disabled,
9212
+ hideControls
9213
+ }) {
9214
+ const styles = ui.useStyles2(getStyles$d);
9215
+ const items = Array.isArray(value) ? value : [];
9216
+ const addItem = () => {
9217
+ if (items.length >= maxItems) {
9218
+ return;
9219
+ }
9220
+ onChange([...items, { index: 0, name: "", value: "" }]);
9221
+ };
9222
+ const removeItem = (index) => {
9223
+ onChange(items.filter((_, i) => i !== index));
9224
+ };
9225
+ const updateItem = (index, key, val) => {
9226
+ const updated = items.map((item, i) => i === index ? { ...item, [key]: val } : item);
9227
+ onChange(updated);
9228
+ };
9229
+ return /* @__PURE__ */ React__default.default.createElement(ui.Stack, { direction: "column", gap: 0.5 }, items.map((item, i) => /* @__PURE__ */ React__default.default.createElement(
9230
+ IndexedPairRow,
9231
+ {
9232
+ key: item.index || `new-${i}`,
9233
+ item,
9234
+ index: i,
9235
+ disabled,
9236
+ onUpdate: updateItem,
9237
+ onRemove: removeItem,
9238
+ hideControls
9239
+ }
9240
+ )), !hideControls && items.length < maxItems && /* @__PURE__ */ React__default.default.createElement("div", null, /* @__PURE__ */ React__default.default.createElement(ui.Button, { variant: "secondary", size: "sm", icon: "plus", disabled, onClick: addItem, type: "button" }, "Add header")), !hideControls && items.length >= maxItems && /* @__PURE__ */ React__default.default.createElement("span", { className: styles.limitNote }, "Maximum ", maxItems, " headers reached"));
9241
+ }
9242
+ const getStyles$d = (theme) => ({
9243
+ inputCell: css.css({
9244
+ flex: "1 1 0",
9245
+ minWidth: 0,
9246
+ overflow: "hidden"
9247
+ }),
9248
+ limitNote: css.css({
9249
+ fontSize: theme.typography.bodySmall.fontSize,
9250
+ color: theme.colors.text.secondary
9251
+ })
9252
+ });
9253
+
9254
+ function ComplexFieldNote({ count, label }) {
9255
+ const styles = ui.useStyles2(getStyles$c);
9256
+ return /* @__PURE__ */ React__default.default.createElement("div", { className: styles.note }, /* @__PURE__ */ React__default.default.createElement(ui.Icon, { name: "info-circle", size: "xs" }), /* @__PURE__ */ React__default.default.createElement("span", null, count > 0 ? `${count} ${label.toLowerCase()} configured.` : `No ${label.toLowerCase()} configured.`, " Configure in Grafana UI."));
9257
+ }
9258
+ const getStyles$c = (theme) => ({
9259
+ note: css.css({
9260
+ display: "inline-flex",
9261
+ alignItems: "center",
9262
+ gap: theme.spacing(0.5),
9263
+ padding: `${theme.spacing(0.5)} ${theme.spacing(0.75)}`,
9264
+ fontSize: theme.typography.bodySmall.fontSize,
9265
+ color: theme.colors.text.secondary,
9266
+ backgroundColor: theme.colors.background.secondary,
9267
+ borderRadius: theme.shape.radius.default,
9268
+ border: `1px solid ${theme.colors.border.weak}`
9269
+ })
9270
+ });
9271
+
9272
+ function renderFieldInput(field, formField, disabled) {
9273
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r;
9274
+ const value = formField.value;
9275
+ const placeholder = (_a = field.ui) == null ? void 0 : _a.placeholder;
9276
+ const label = (_b = field.label) != null ? _b : field.key;
9277
+ if (field.target === "secureJsonData" || field.semanticType === "password" || field.semanticType === "token") {
9278
+ return /* @__PURE__ */ React__default.default.createElement(SecureFieldInput, { formField, placeholder: placeholder != null ? placeholder : label, disabled, label });
9279
+ }
9280
+ if (field.valueType === "boolean") {
9281
+ return /* @__PURE__ */ React__default.default.createElement(ui.Switch, { value: !!value, onChange: (e) => formField.onChange(e.currentTarget.checked), disabled });
9282
+ }
9283
+ if (field.valueType === "number") {
9284
+ return /* @__PURE__ */ React__default.default.createElement(
9285
+ ui.Input,
9286
+ {
9287
+ ...formField,
9288
+ value: value !== void 0 && value !== null ? Number(value) : "",
9289
+ type: "number",
9290
+ placeholder,
9291
+ disabled,
9292
+ onChange: (e) => {
9293
+ const n = e.currentTarget.valueAsNumber;
9294
+ formField.onChange(Number.isNaN(n) ? void 0 : n);
9295
+ }
9296
+ }
9297
+ );
9298
+ }
9299
+ if (((_c = field.ui) == null ? void 0 : _c.component) === "radio") {
9300
+ const options = ((_e = (_d = field.ui) == null ? void 0 : _d.options) != null ? _e : []).map((opt) => ({
9301
+ label: opt.label,
9302
+ value: String(opt.value),
9303
+ description: opt.description
9304
+ }));
9305
+ return /* @__PURE__ */ React__default.default.createElement("div", { style: { display: "flex" } }, /* @__PURE__ */ React__default.default.createElement(
9306
+ ui.RadioButtonGroup,
9307
+ {
9308
+ options,
9309
+ value: String(value != null ? value : ""),
9310
+ onChange: (v) => formField.onChange(v),
9311
+ disabled
9312
+ }
9313
+ ));
9314
+ }
9315
+ if (((_f = field.ui) == null ? void 0 : _f.component) === "select") {
9316
+ const options = ((_h = (_g = field.ui) == null ? void 0 : _g.options) != null ? _h : []).map((opt) => ({
9317
+ label: opt.label,
9318
+ value: String(opt.value),
9319
+ description: opt.description
9320
+ }));
9321
+ return /* @__PURE__ */ React__default.default.createElement(
9322
+ ui.Select,
9323
+ {
9324
+ options,
9325
+ value: options.find((o) => o.value === String(value != null ? value : "")),
9326
+ onChange: (v) => formField.onChange(v == null ? void 0 : v.value),
9327
+ disabled
9328
+ }
9329
+ );
9330
+ }
9331
+ if (field.semanticType === "url") {
9332
+ return /* @__PURE__ */ React__default.default.createElement(ui.Input, { ...formField, value: String(value != null ? value : ""), type: "url", placeholder, disabled });
9333
+ }
9334
+ if (((_i = field.ui) == null ? void 0 : _i.component) === "textarea") {
9335
+ return /* @__PURE__ */ React__default.default.createElement(
9336
+ ui.TextArea,
9337
+ {
9338
+ ...formField,
9339
+ value: String(value != null ? value : ""),
9340
+ placeholder,
9341
+ disabled,
9342
+ rows: (_k = (_j = field.ui) == null ? void 0 : _j.rows) != null ? _k : 3
9343
+ }
9344
+ );
9345
+ }
9346
+ if (field.valueType === "array" && ((_l = field.item) == null ? void 0 : _l.valueType) === "string") {
9347
+ return /* @__PURE__ */ React__default.default.createElement(
9348
+ StringArrayInput,
9349
+ {
9350
+ value: Array.isArray(value) ? value : [],
9351
+ onChange: formField.onChange,
9352
+ placeholder: placeholder != null ? placeholder : `Add ${label.toLowerCase()}\u2026`,
9353
+ disabled
9354
+ }
9355
+ );
9356
+ }
9357
+ if (((_m = field.storage) == null ? void 0 : _m.type) === "indexedPair") {
9358
+ const items = Array.isArray(value) ? value : [];
9359
+ const maxItems = (_p = (_o = (_n = field.validations) == null ? void 0 : _n.find((v) => v.type === "itemCount")) == null ? void 0 : _o.max) != null ? _p : 10;
9360
+ return /* @__PURE__ */ React__default.default.createElement(IndexedPairEditor, { value: items, onChange: formField.onChange, maxItems, disabled });
9361
+ }
9362
+ if (field.valueType === "object" || field.valueType === "map" || field.valueType === "array" && (((_q = field.item) == null ? void 0 : _q.valueType) === "object" || ((_r = field.item) == null ? void 0 : _r.valueType) === "map")) {
9363
+ const count = Array.isArray(value) ? value.length : 0;
9364
+ return /* @__PURE__ */ React__default.default.createElement(ComplexFieldNote, { count, label });
9365
+ }
9366
+ return /* @__PURE__ */ React__default.default.createElement(ui.Input, { ...formField, value: String(value != null ? value : ""), placeholder, disabled });
9367
+ }
9368
+
9369
+ const getWizardStyles = (theme) => ({
9370
+ container: css.css({
9371
+ position: "relative",
9372
+ display: "flex",
9373
+ flexDirection: "column",
9374
+ gap: theme.spacing(1),
9375
+ padding: theme.spacing(1.5),
9376
+ backgroundColor: theme.colors.background.secondary,
9377
+ borderRadius: theme.shape.radius.default,
9378
+ border: `1px solid ${theme.colors.border.weak}`,
9379
+ overflow: "hidden"
9380
+ }),
9381
+ overlay: css.css({
9382
+ position: "absolute",
9383
+ inset: 0,
9384
+ display: "flex",
9385
+ alignItems: "center",
9386
+ justifyContent: "center",
9387
+ gap: theme.spacing(1),
9388
+ background: theme.colors.background.secondary,
9389
+ borderRadius: theme.shape.radius.default,
9390
+ zIndex: 1,
9391
+ fontSize: theme.typography.bodySmall.fontSize,
9392
+ color: theme.colors.text.primary,
9393
+ opacity: 0.95
9394
+ }),
9395
+ readOnlyBanner: css.css({
9396
+ display: "inline-flex",
9397
+ alignItems: "center",
9398
+ gap: theme.spacing(0.5),
9399
+ padding: `${theme.spacing(0.25)} ${theme.spacing(0.75)}`,
9400
+ fontSize: theme.typography.bodySmall.fontSize,
9401
+ color: theme.colors.text.secondary,
9402
+ backgroundColor: theme.colors.background.secondary,
9403
+ borderRadius: theme.shape.radius.default,
9404
+ border: `1px solid ${theme.colors.border.weak}`
9405
+ }),
9406
+ navBar: css.css({
9407
+ display: "flex",
9408
+ alignItems: "center",
9409
+ justifyContent: "space-between"
9410
+ }),
9411
+ navTitle: css.css({
9412
+ display: "inline-flex",
9413
+ alignItems: "center",
9414
+ gap: theme.spacing(0.5),
9415
+ fontSize: theme.typography.body.fontSize,
9416
+ fontWeight: theme.typography.fontWeightBold,
9417
+ color: theme.colors.text.primary
9418
+ }),
9419
+ stepCount: css.css({
9420
+ fontSize: "11px",
9421
+ fontWeight: "normal",
9422
+ color: theme.colors.text.secondary
9423
+ }),
9424
+ navActions: css.css({
9425
+ display: "flex",
9426
+ alignItems: "center",
9427
+ gap: theme.spacing(0.25)
9428
+ }),
9429
+ form: css.css({
9430
+ display: "flex",
9431
+ flexDirection: "column",
9432
+ gap: theme.spacing(0.75)
9433
+ }),
9434
+ buttons: css.css({
9435
+ display: "flex",
9436
+ gap: theme.spacing(1),
9437
+ paddingTop: theme.spacing(0.25)
9438
+ }),
9439
+ fieldRow: css.css({
9440
+ display: "grid",
9441
+ gridTemplateColumns: "minmax(80px, 1fr) minmax(0, 2fr)",
9442
+ gap: theme.spacing(0.75),
9443
+ alignItems: "start"
9444
+ }),
9445
+ fieldRowCenter: css.css({
9446
+ display: "grid",
9447
+ gridTemplateColumns: "minmax(80px, 1fr) minmax(0, 2fr)",
9448
+ gap: theme.spacing(0.75),
9449
+ alignItems: "center",
9450
+ padding: `${theme.spacing(0.5)} 0`
9451
+ }),
9452
+ fieldLabelRow: css.css({
9453
+ display: "flex",
9454
+ alignItems: "center",
9455
+ gap: theme.spacing(0.5),
9456
+ paddingTop: theme.spacing(0.5)
9457
+ }),
9458
+ fieldLabelRowCompact: css.css({
9459
+ display: "flex",
9460
+ alignItems: "center",
9461
+ gap: theme.spacing(0.5)
9462
+ }),
9463
+ fieldLabel: css.css({
9464
+ fontSize: theme.typography.bodySmall.fontSize,
9465
+ fontWeight: theme.typography.fontWeightMedium,
9466
+ color: theme.colors.text.primary
9467
+ }),
9468
+ fieldRequired: css.css({
9469
+ color: theme.colors.error.text,
9470
+ marginLeft: 2
9471
+ }),
9472
+ fieldInfoIcon: css.css({
9473
+ color: theme.colors.text.disabled,
9474
+ cursor: "help",
9475
+ flexShrink: 0
9476
+ }),
9477
+ fieldInputCol: css.css({
9478
+ display: "flex",
9479
+ flexDirection: "column",
9480
+ gap: theme.spacing(0.25),
9481
+ minWidth: 0
9482
+ }),
9483
+ fieldError: css.css({
9484
+ fontSize: "11px",
9485
+ color: theme.colors.error.text
9486
+ })
9487
+ });
9488
+
9489
+ function SchemaField({ field, control, errors, disabled, dsUid, watchedValues, fieldById }) {
9490
+ const styles = ui.useStyles2(getWizardStyles);
9491
+ const activeOverride = resolveActiveOverride(field, watchedValues, fieldById);
9492
+ const fk = formKey(field);
9493
+ if (field.key === "pdcInjected" && field.target === "jsonData") {
9494
+ return /* @__PURE__ */ React__default.default.createElement(
9495
+ reactHookForm.Controller,
9496
+ {
9497
+ name: fk,
9498
+ control,
9499
+ render: ({ field: formField }) => /* @__PURE__ */ React__default.default.createElement(
9500
+ PdcFieldNote,
9501
+ {
9502
+ enabled: !!formField.value,
9503
+ description: field.description,
9504
+ configUrl: `/connections/datasources/edit/${dsUid}`
9505
+ }
9506
+ )
9507
+ }
9508
+ );
9509
+ }
9510
+ const required = isFieldRequired(field, watchedValues, fieldById);
9511
+ const validationRules = buildValidationRules(field, required);
9512
+ return /* @__PURE__ */ React__default.default.createElement(
9513
+ reactHookForm.Controller,
9514
+ {
9515
+ name: fk,
9516
+ control,
9517
+ rules: validationRules,
9518
+ render: ({ field: formField }) => {
9519
+ var _a, _b, _c, _d, _e;
9520
+ const errorMessage = (_a = errors[fk]) == null ? void 0 : _a.message;
9521
+ const label = (_b = field.label) != null ? _b : field.key;
9522
+ const description = (_c = activeOverride == null ? void 0 : activeOverride.description) != null ? _c : field.description;
9523
+ const effectiveField = activeOverride ? {
9524
+ ...field,
9525
+ ui: {
9526
+ ...field.ui,
9527
+ placeholder: (_e = activeOverride.placeholder) != null ? _e : (_d = field.ui) == null ? void 0 : _d.placeholder
9528
+ }
9529
+ } : field;
9530
+ const isReadOnly = !!(activeOverride == null ? void 0 : activeOverride.readOnly);
9531
+ const isBool = field.valueType === "boolean";
9532
+ return /* @__PURE__ */ React__default.default.createElement("div", { className: isBool ? styles.fieldRowCenter : styles.fieldRow }, /* @__PURE__ */ React__default.default.createElement("div", { className: isBool ? styles.fieldLabelRowCompact : styles.fieldLabelRow }, /* @__PURE__ */ React__default.default.createElement("span", { className: styles.fieldLabel }, label, required && /* @__PURE__ */ React__default.default.createElement("span", { className: styles.fieldRequired }, "*")), description && /* @__PURE__ */ React__default.default.createElement(ui.Tooltip, { content: description }, /* @__PURE__ */ React__default.default.createElement(ui.Icon, { name: "info-circle", size: "xs", className: styles.fieldInfoIcon }))), /* @__PURE__ */ React__default.default.createElement("div", { className: styles.fieldInputCol }, renderFieldInput(effectiveField, formField, disabled || isReadOnly), errorMessage && /* @__PURE__ */ React__default.default.createElement("span", { className: styles.fieldError }, errorMessage)));
9533
+ }
9534
+ }
9535
+ );
9536
+ }
9537
+
9538
+ function AuthorizationHeaderField({
9539
+ headersFieldKey,
9540
+ control,
9541
+ disabled,
9542
+ watchedValues
9543
+ }) {
9544
+ const styles = ui.useStyles2(getWizardStyles);
9545
+ const items = React.useMemo(
9546
+ () => Array.isArray(watchedValues[headersFieldKey]) ? watchedValues[headersFieldKey] : [],
9547
+ [watchedValues, headersFieldKey]
9548
+ );
9549
+ const authEntries = React.useMemo(() => {
9550
+ const entries = [];
9551
+ for (let i = 0; i < items.length; i++) {
9552
+ if (items[i].name.toLowerCase() === "authorization") {
9553
+ entries.push({ item: items[i], originalIdx: i });
9554
+ }
9555
+ }
9556
+ return entries;
9557
+ }, [items]);
9558
+ if (authEntries.length === 0) {
9559
+ return null;
9560
+ }
9561
+ const authItems = authEntries.map((e) => e.item);
9562
+ return /* @__PURE__ */ React__default.default.createElement(
9563
+ reactHookForm.Controller,
9564
+ {
9565
+ name: headersFieldKey,
9566
+ control,
9567
+ render: ({ field: formField }) => {
9568
+ const handleChange = (updatedAuthItems) => {
9569
+ const updated = [...items];
9570
+ for (let i = 0; i < authEntries.length; i++) {
9571
+ if (i < updatedAuthItems.length) {
9572
+ updated[authEntries[i].originalIdx] = updatedAuthItems[i];
9573
+ }
9574
+ }
9575
+ formField.onChange(updated);
9576
+ };
9577
+ return /* @__PURE__ */ React__default.default.createElement("div", { className: styles.fieldRow }, /* @__PURE__ */ React__default.default.createElement("div", { className: styles.fieldLabelRow }, /* @__PURE__ */ React__default.default.createElement("span", { className: styles.fieldLabel }, "Custom HTTP Headers"), /* @__PURE__ */ React__default.default.createElement(ui.Tooltip, { content: "Authorization HTTP header(s) sent with every request." }, /* @__PURE__ */ React__default.default.createElement(ui.Icon, { name: "info-circle", size: "xs", className: styles.fieldInfoIcon }))), /* @__PURE__ */ React__default.default.createElement("div", { className: styles.fieldInputCol }, /* @__PURE__ */ React__default.default.createElement(IndexedPairEditor, { value: authItems, onChange: handleChange, disabled, hideControls: true })));
9578
+ }
9579
+ }
9580
+ );
9581
+ }
9582
+
9583
+ const getTabStyles = (theme) => ({
9584
+ root: css.css({
9585
+ display: "flex",
9586
+ gap: theme.spacing(3),
9587
+ position: "relative",
9588
+ background: theme.colors.background.canvas,
9589
+ padding: theme.spacing(2)
9590
+ }),
9591
+ // Sidebar
9592
+ sidebar: css.css({
9593
+ width: 250,
9594
+ flexShrink: 0,
9595
+ position: "sticky",
9596
+ top: theme.spacing(2),
9597
+ alignSelf: "flex-start",
9598
+ [theme.breakpoints.down("sm")]: { display: "none" }
9599
+ }),
9600
+ sidebarTitle: css.css({
9601
+ fontSize: theme.typography.body.fontSize,
9602
+ fontWeight: theme.typography.fontWeightMedium,
9603
+ color: theme.colors.text.primary,
9604
+ padding: `${theme.spacing(1)} 0`,
9605
+ marginBottom: theme.spacing(1)
9606
+ }),
9607
+ navList: css.css({
9608
+ listStyle: "none",
9609
+ margin: 0,
9610
+ padding: 0,
9611
+ position: "relative"
9612
+ }),
9613
+ navItem: css.css({
9614
+ display: "flex",
9615
+ alignItems: "flex-start",
9616
+ gap: theme.spacing(1.5),
9617
+ padding: `${theme.spacing(1)} 0`,
9618
+ cursor: "pointer",
9619
+ position: "relative"
9620
+ }),
9621
+ navItemActive: css.css({}),
9622
+ // Dot container: positions the dot and the connector line
9623
+ navDotWrap: css.css({
9624
+ position: "relative",
9625
+ display: "flex",
9626
+ alignItems: "center",
9627
+ justifyContent: "center",
9628
+ width: 12,
9629
+ flexShrink: 0,
9630
+ alignSelf: "flex-start",
9631
+ paddingTop: 4
9632
+ }),
9633
+ navDot: css.css({
9634
+ width: 10,
9635
+ height: 10,
9636
+ borderRadius: "50%",
9637
+ border: `2px solid ${theme.colors.text.disabled}`,
9638
+ background: theme.colors.background.canvas,
9639
+ position: "relative",
9640
+ zIndex: 1
9641
+ }),
9642
+ navDotOptional: css.css({
9643
+ borderStyle: "dashed"
9644
+ }),
9645
+ navDotActive: css.css({
9646
+ background: theme.colors.primary.main,
9647
+ borderColor: theme.colors.primary.main,
9648
+ borderStyle: "solid"
9649
+ }),
9650
+ navDotValidated: css.css({
9651
+ background: theme.colors.success.main,
9652
+ borderColor: theme.colors.success.main,
9653
+ borderStyle: "solid"
9654
+ }),
9655
+ navDotError: css.css({
9656
+ background: theme.colors.error.main,
9657
+ borderColor: theme.colors.error.main,
9658
+ borderStyle: "solid"
9659
+ }),
9660
+ // Connector line running from dot center downward to next item
9661
+ navConnector: css.css({
9662
+ position: "absolute",
9663
+ left: 5,
9664
+ top: 16,
9665
+ bottom: -16,
9666
+ width: 2,
9667
+ background: theme.colors.border.medium,
9668
+ zIndex: 0
9669
+ }),
9670
+ navConnectorDashed: css.css({
9671
+ background: "none",
9672
+ borderLeft: `2px dashed ${theme.colors.border.weak}`,
9673
+ width: 0
9674
+ }),
9675
+ navLabel: css.css({
9676
+ fontSize: theme.typography.body.fontSize,
9677
+ color: "rgba(204, 204, 220, 0.65)",
9678
+ lineHeight: 1.4
9679
+ }),
9680
+ navLabelActive: css.css({
9681
+ fontWeight: theme.typography.fontWeightMedium,
9682
+ color: theme.colors.text.primary
9683
+ }),
9684
+ // Main content
9685
+ main: css.css({
9686
+ flex: 1,
9687
+ minWidth: 0,
9688
+ width: 0,
9689
+ // forces flex child to respect flex-grow and fill remaining space
9690
+ display: "flex",
9691
+ flexDirection: "column",
9692
+ gap: theme.spacing(2)
9693
+ }),
9694
+ form: css.css({
9695
+ display: "flex",
9696
+ flexDirection: "column",
9697
+ gap: theme.spacing(2)
9698
+ }),
9699
+ requiredNotice: css.css({
9700
+ fontSize: theme.typography.bodySmall.fontSize,
9701
+ color: theme.colors.text.secondary,
9702
+ marginBottom: theme.spacing(0.5)
9703
+ }),
9704
+ // Section wrapper — card container around CollapsableSection
9705
+ section: css.css({
9706
+ border: `1px solid ${theme.colors.border.weak}`,
9707
+ borderRadius: theme.shape.radius.default,
9708
+ background: theme.colors.background.secondary,
9709
+ overflow: "hidden"
9710
+ }),
9711
+ // Override Collapse component styling
9712
+ collapseHeader: css.css({
9713
+ borderRadius: theme.shape.radius.default,
9714
+ background: "none",
9715
+ border: "none",
9716
+ marginBottom: 0,
9717
+ // Collapse header button: make label fill remaining space
9718
+ "& > button": {
9719
+ padding: `${theme.spacing(1.5)} ${theme.spacing(2)}`,
9720
+ width: "100%",
9721
+ justifyContent: "flex-start"
9722
+ },
9723
+ "& > button > div": {
9724
+ flex: 1,
9725
+ fontSize: theme.typography.h4.fontSize,
9726
+ fontWeight: theme.typography.fontWeightMedium,
9727
+ textAlign: "left"
9728
+ }
9729
+ }),
9730
+ sectionLabel: css.css({
9731
+ display: "flex",
9732
+ alignItems: "center",
9733
+ flex: 1
9734
+ }),
9735
+ sectionLabelText: css.css({
9736
+ flex: 1
9737
+ }),
9738
+ sectionHeader: css.css({
9739
+ display: "flex",
9740
+ alignItems: "center",
9741
+ gap: theme.spacing(1),
9742
+ padding: `${theme.spacing(1.5)} ${theme.spacing(2)}`,
9743
+ cursor: "pointer",
9744
+ userSelect: "none"
9745
+ }),
9746
+ sectionChevron: css.css({
9747
+ transition: "transform 0.2s ease"
9748
+ }),
9749
+ sectionChevronOpen: css.css({
9750
+ transform: "rotate(90deg)"
9751
+ }),
9752
+ sectionTitle: css.css({
9753
+ fontSize: theme.typography.h4.fontSize,
9754
+ fontWeight: theme.typography.fontWeightMedium,
9755
+ flex: 1,
9756
+ textAlign: "left"
9757
+ }),
9758
+ sectionBadge: css.css({
9759
+ fontSize: "11px",
9760
+ fontWeight: "normal",
9761
+ color: theme.colors.text.disabled,
9762
+ border: `1px solid ${theme.colors.border.weak}`,
9763
+ borderRadius: theme.shape.radius.pill,
9764
+ padding: `1px ${theme.spacing(0.75)}`,
9765
+ whiteSpace: "nowrap"
9766
+ }),
9767
+ sectionDescription: css.css({
9768
+ fontSize: theme.typography.bodySmall.fontSize,
9769
+ color: theme.colors.text.secondary,
9770
+ marginBottom: theme.spacing(1.5)
9771
+ }),
9772
+ sectionBody: css.css({
9773
+ padding: `0 ${theme.spacing(2)} ${theme.spacing(2)}`,
9774
+ display: "flex",
9775
+ flexDirection: "column",
9776
+ gap: theme.spacing(0.75)
9777
+ }),
9778
+ // Form bottom
9779
+ formButtons: css.css({
9780
+ display: "flex",
9781
+ gap: theme.spacing(1),
9782
+ paddingTop: theme.spacing(0.5)
9783
+ }),
9784
+ // Loading / error states
9785
+ loadingContainer: css.css({
9786
+ display: "flex",
9787
+ alignItems: "center",
9788
+ gap: theme.spacing(1),
9789
+ padding: theme.spacing(3),
9790
+ color: theme.colors.text.secondary
9791
+ }),
9792
+ overlay: css.css({
9793
+ position: "absolute",
9794
+ inset: 0,
9795
+ display: "flex",
9796
+ alignItems: "center",
9797
+ justifyContent: "center",
9798
+ gap: theme.spacing(1),
9799
+ background: theme.colors.background.secondary,
9800
+ borderRadius: theme.shape.radius.default,
9801
+ zIndex: 1,
9802
+ fontSize: theme.typography.bodySmall.fontSize,
9803
+ color: theme.colors.text.primary,
9804
+ opacity: 0.95
9805
+ }),
9806
+ readOnlyBanner: css.css({
9807
+ display: "inline-flex",
9808
+ alignItems: "center",
9809
+ gap: theme.spacing(0.5),
9810
+ padding: `${theme.spacing(0.25)} ${theme.spacing(0.75)}`,
9811
+ fontSize: theme.typography.bodySmall.fontSize,
9812
+ color: theme.colors.text.secondary,
9813
+ backgroundColor: theme.colors.background.secondary,
9814
+ borderRadius: theme.shape.radius.default,
9815
+ border: `1px solid ${theme.colors.border.weak}`,
9816
+ marginBottom: theme.spacing(1)
9817
+ })
9818
+ });
9819
+
9820
+ function SidebarNav({ groups, activeIndex, sectionStates, onSelect }) {
9821
+ const styles = ui.useStyles2(getTabStyles);
9822
+ const visibleGroups = groups.filter((g) => g.group.id !== "_required");
9823
+ return /* @__PURE__ */ React__default.default.createElement("nav", { className: styles.sidebar }, /* @__PURE__ */ React__default.default.createElement("div", { className: styles.sidebarTitle }, "Connect data source"), /* @__PURE__ */ React__default.default.createElement("ul", { className: styles.navList }, visibleGroups.map((g, vi) => {
9824
+ var _a, _b;
9825
+ const origIndex = groups.indexOf(g);
9826
+ const state = (_a = sectionStates[origIndex]) != null ? _a : "draft";
9827
+ const isActive = origIndex === activeIndex;
9828
+ const isOptional = g.group.optional === true;
9829
+ const isLast = vi === visibleGroups.length - 1;
9830
+ const nextIsOptional = !isLast && ((_b = visibleGroups[vi + 1]) == null ? void 0 : _b.group.optional) === true;
9831
+ return /* @__PURE__ */ React__default.default.createElement("li", { key: g.group.id }, /* @__PURE__ */ React__default.default.createElement(
9832
+ "div",
9833
+ {
9834
+ className: css.cx(styles.navItem, isActive && styles.navItemActive),
9835
+ onClick: () => onSelect(origIndex),
9836
+ role: "button",
9837
+ tabIndex: 0,
9838
+ onKeyDown: (e) => {
9839
+ if (e.key === "Enter" || e.key === " ") {
9840
+ e.preventDefault();
9841
+ onSelect(origIndex);
9842
+ }
9843
+ }
9844
+ },
9845
+ /* @__PURE__ */ React__default.default.createElement("div", { className: styles.navDotWrap }, /* @__PURE__ */ React__default.default.createElement(
9846
+ "span",
9847
+ {
9848
+ className: css.cx(
9849
+ styles.navDot,
9850
+ isOptional && styles.navDotOptional,
9851
+ isActive && styles.navDotActive,
9852
+ state === "validated" && !isActive && styles.navDotValidated,
9853
+ state === "error" && !isActive && styles.navDotError
9854
+ )
9855
+ }
9856
+ ), !isLast && /* @__PURE__ */ React__default.default.createElement(
9857
+ "div",
9858
+ {
9859
+ className: css.cx(styles.navConnector, (isOptional || nextIsOptional) && styles.navConnectorDashed)
9860
+ }
9861
+ )),
9862
+ /* @__PURE__ */ React__default.default.createElement("span", { className: css.cx(styles.navLabel, isActive && styles.navLabelActive) }, g.group.title)
9863
+ ));
9864
+ })));
9865
+ }
9866
+
9867
+ function TabLayout({ form, schema, dsUid, dsName, onRetest, healthError, renderActions }) {
9868
+ const styles = ui.useStyles2(getTabStyles);
9869
+ const sectionRefs = React.useRef(/* @__PURE__ */ new Map());
9870
+ const {
9871
+ resolvedGroups,
9872
+ fieldById,
9873
+ httpHeadersField,
9874
+ control,
9875
+ handleSubmit,
9876
+ errors,
9877
+ watchedValues,
9878
+ initializing,
9879
+ fetchError,
9880
+ submitting,
9881
+ submitError,
9882
+ readOnly,
9883
+ isFieldVisible,
9884
+ isGroupValid,
9885
+ groupHasData,
9886
+ onSubmit
9887
+ } = form;
9888
+ const displayGroups = React.useMemo(() => resolvedGroups.filter((g) => g.group.id !== "_required"), [resolvedGroups]);
9889
+ const [expandedSections, setExpandedSections] = React.useState(() => {
9890
+ const expanded = /* @__PURE__ */ new Set();
9891
+ for (let i = 0; i < displayGroups.length; i++) {
9892
+ if (!displayGroups[i].group.optional) {
9893
+ expanded.add(i);
9894
+ }
9895
+ }
9896
+ return expanded;
9897
+ });
9898
+ const hasExpandedForData = React.useRef(false);
9899
+ React.useMemo(() => {
9900
+ if (initializing || hasExpandedForData.current) {
9901
+ return;
9902
+ }
9903
+ hasExpandedForData.current = true;
9904
+ setExpandedSections((prev) => {
9905
+ const next = new Set(prev);
9906
+ for (let i = 0; i < displayGroups.length; i++) {
9907
+ if (groupHasData(displayGroups[i])) {
9908
+ next.add(i);
9909
+ }
9910
+ }
9911
+ return next;
9912
+ });
9913
+ }, [initializing, displayGroups, groupHasData]);
9914
+ const [activeSection, setActiveSection] = React.useState(0);
9915
+ const toggleSection = React.useCallback((index) => {
9916
+ setExpandedSections((prev) => {
9917
+ const next = new Set(prev);
9918
+ if (next.has(index)) {
9919
+ next.delete(index);
9920
+ } else {
9921
+ next.add(index);
9922
+ }
9923
+ return next;
9924
+ });
9925
+ }, []);
9926
+ const scrollToSection = React.useCallback(
9927
+ (index) => {
9928
+ setActiveSection(index);
9929
+ if (!expandedSections.has(index)) {
9930
+ setExpandedSections((prev) => new Set(prev).add(index));
9931
+ }
9932
+ const el = sectionRefs.current.get(index);
9933
+ if (el) {
9934
+ el.scrollIntoView({ behavior: "smooth", block: "start" });
9935
+ }
9936
+ },
9937
+ [expandedSections]
9938
+ );
9939
+ const sectionStates = React.useMemo(() => {
9940
+ return displayGroups.map((g, i) => {
9941
+ if (i === activeSection) {
9942
+ return "active";
9943
+ }
9944
+ if (!isGroupValid(g)) {
9945
+ return "error";
9946
+ }
9947
+ if (groupHasData(g)) {
9948
+ return "validated";
9949
+ }
9950
+ return "draft";
9951
+ });
9952
+ }, [displayGroups, activeSection, isGroupValid, groupHasData]);
9953
+ if (initializing) {
9954
+ return /* @__PURE__ */ React__default.default.createElement("div", { className: styles.loadingContainer }, /* @__PURE__ */ React__default.default.createElement(ui.Spinner, { size: "sm", inline: true }), " Loading configuration\u2026");
9955
+ }
9956
+ if (fetchError) {
9957
+ return /* @__PURE__ */ React__default.default.createElement("div", null, /* @__PURE__ */ React__default.default.createElement(ui.Alert, { severity: "error", title: "Failed to load configuration" }, fetchError), /* @__PURE__ */ React__default.default.createElement("div", { className: styles.formButtons }, /* @__PURE__ */ React__default.default.createElement(
9958
+ ui.LinkButton,
9959
+ {
9960
+ variant: "secondary",
9961
+ size: "sm",
9962
+ icon: "external-link-alt",
9963
+ href: `/connections/datasources/edit/${dsUid}`
9964
+ },
9965
+ "Open datasource settings"
9966
+ )));
9967
+ }
9968
+ const allDisabled = submitting || readOnly;
9969
+ return /* @__PURE__ */ React__default.default.createElement("div", { className: styles.root }, submitting && /* @__PURE__ */ React__default.default.createElement("div", { className: styles.overlay }, /* @__PURE__ */ React__default.default.createElement(ui.Spinner, { size: "sm" }), /* @__PURE__ */ React__default.default.createElement("span", null, "Saving & testing\u2026")), /* @__PURE__ */ React__default.default.createElement(
9970
+ SidebarNav,
9971
+ {
9972
+ groups: displayGroups,
9973
+ activeIndex: activeSection,
9974
+ sectionStates,
9975
+ onSelect: scrollToSection
9976
+ }
9977
+ ), /* @__PURE__ */ React__default.default.createElement("div", { className: styles.main }, readOnly && /* @__PURE__ */ React__default.default.createElement("div", { className: styles.readOnlyBanner }, /* @__PURE__ */ React__default.default.createElement(ui.Icon, { name: "lock", size: "xs" }), /* @__PURE__ */ React__default.default.createElement("span", null, "Read-only \u2014 managed externally")), /* @__PURE__ */ React__default.default.createElement("div", { className: styles.requiredNotice }, "Fields marked with * are required"), /* @__PURE__ */ React__default.default.createElement("form", { onSubmit: handleSubmit(onSubmit), className: styles.form }, displayGroups.map((g, i) => {
9978
+ const visibleFields = g.fields.filter(isFieldVisible);
9979
+ if (visibleFields.length === 0 && !httpHeadersField) {
9980
+ return null;
9981
+ }
9982
+ const showHeaders = httpHeadersField && (g.group.id === "auth" || g.group.id === "url-and-auth" || g.group.id === "_required" || g.group.fieldRefs.includes("httpHeaders"));
9983
+ const sectionLabel = /* @__PURE__ */ React__default.default.createElement("span", { className: styles.sectionLabel }, /* @__PURE__ */ React__default.default.createElement("span", { className: styles.sectionLabelText }, g.group.title), g.group.optional && /* @__PURE__ */ React__default.default.createElement("span", { className: styles.sectionBadge }, "Optional"));
9984
+ return /* @__PURE__ */ React__default.default.createElement(
9985
+ "div",
9986
+ {
9987
+ key: g.group.id,
9988
+ ref: (el) => {
9989
+ if (el) {
9990
+ sectionRefs.current.set(i, el);
9991
+ }
9992
+ },
9993
+ className: styles.section
9994
+ },
9995
+ /* @__PURE__ */ React__default.default.createElement(
9996
+ ui.Collapse,
9997
+ {
9998
+ label: sectionLabel,
9999
+ isOpen: expandedSections.has(i),
10000
+ collapsible: true,
10001
+ onToggle: () => {
10002
+ toggleSection(i);
10003
+ setActiveSection(i);
10004
+ },
10005
+ className: styles.collapseHeader
10006
+ },
10007
+ /* @__PURE__ */ React__default.default.createElement("div", { className: styles.sectionBody }, g.group.description && /* @__PURE__ */ React__default.default.createElement("div", { className: styles.sectionDescription }, g.group.description), visibleFields.map((field) => /* @__PURE__ */ React__default.default.createElement(
10008
+ SchemaField,
10009
+ {
10010
+ key: formKey(field),
10011
+ field,
10012
+ control,
10013
+ errors,
10014
+ disabled: allDisabled,
10015
+ dsUid,
10016
+ watchedValues,
10017
+ fieldById
10018
+ }
10019
+ )), showHeaders && /* @__PURE__ */ React__default.default.createElement(
10020
+ AuthorizationHeaderField,
10021
+ {
10022
+ headersFieldKey: formKey(httpHeadersField),
10023
+ control,
10024
+ disabled: allDisabled,
10025
+ watchedValues
10026
+ }
10027
+ ))
10028
+ )
10029
+ );
10030
+ }), submitError && /* @__PURE__ */ React__default.default.createElement(ui.Alert, { severity: "error", title: "Error" }, submitError), /* @__PURE__ */ React__default.default.createElement("div", { className: styles.formButtons }, readOnly ? /* @__PURE__ */ React__default.default.createElement(ui.Button, { variant: "primary", size: "sm", icon: "sync", onClick: onRetest, type: "button" }, "Test") : /* @__PURE__ */ React__default.default.createElement(ui.Button, { variant: "primary", size: "sm", disabled: submitting, type: "submit" }, submitting ? "Saving\u2026" : "Save & Test"), healthError && (renderActions == null ? void 0 : renderActions({ dsUid, dsName, dsType: schema.pluginType, healthError }))))));
10031
+ }
10032
+
10033
+ function useDatasourceConfigForm({ schema, dsUid, onSuccess, onSaving }) {
10034
+ const [submitting, setSubmitting] = React.useState(false);
10035
+ const [submitError, setSubmitError] = React.useState(null);
10036
+ const [initializing, setInitializing] = React.useState(true);
10037
+ const [fetchError, setFetchError] = React.useState(null);
10038
+ const [detectedReadOnly, setDetectedReadOnly] = React.useState(false);
10039
+ const readOnly = detectedReadOnly;
10040
+ const resolvedGroups = React.useMemo(() => {
10041
+ const groups = resolveGroups(schema);
10042
+ const requiredGroup = resolveRequiredFieldsGroup(schema);
10043
+ if (!requiredGroup) {
10044
+ return groups;
10045
+ }
10046
+ return [requiredGroup, ...groups];
10047
+ }, [schema]);
10048
+ const fieldById = React.useMemo(() => {
10049
+ const m = /* @__PURE__ */ new Map();
10050
+ for (const f of schema.fields) {
10051
+ m.set(f.id, f);
10052
+ }
10053
+ return m;
10054
+ }, [schema.fields]);
10055
+ const httpHeadersField = React.useMemo(
10056
+ () => {
10057
+ var _a;
10058
+ return (_a = schema.fields.find((f) => {
10059
+ var _a2;
10060
+ return f.key === "httpHeaders" && ((_a2 = f.storage) == null ? void 0 : _a2.type) === "indexedPair";
10061
+ })) != null ? _a : null;
10062
+ },
10063
+ [schema.fields]
10064
+ );
10065
+ const allStorageFields = React.useMemo(
10066
+ () => schema.fields.filter((f) => f.kind !== "virtual" && !f.isItemField && f.target),
10067
+ [schema.fields]
10068
+ );
10069
+ const {
10070
+ control,
10071
+ handleSubmit,
10072
+ watch,
10073
+ reset,
10074
+ trigger,
10075
+ setValue,
10076
+ formState: { errors }
10077
+ } = reactHookForm.useForm({ mode: "onChange" });
10078
+ const fieldsWithEffects = React.useMemo(() => {
10079
+ const result = [];
10080
+ for (const field of schema.fields) {
10081
+ if (!field.effects || field.effects.length === 0) {
10082
+ continue;
10083
+ }
10084
+ const mapped = field.effects.map((eff) => ({
10085
+ when: eff.when,
10086
+ targets: Object.entries(eff.set).map(([targetId, val]) => {
10087
+ const targetField = fieldById.get(targetId);
10088
+ return { key: targetField ? formKey(targetField) : targetId, value: val };
10089
+ })
10090
+ }));
10091
+ result.push({ sourceKey: formKey(field), effects: mapped });
10092
+ }
10093
+ return result;
10094
+ }, [schema.fields, fieldById]);
10095
+ React.useEffect(() => {
10096
+ let cancelled = false;
10097
+ fetchExistingValues(dsUid, allStorageFields).then((result) => {
10098
+ if (cancelled) {
10099
+ return;
10100
+ }
10101
+ if (result.error) {
10102
+ setFetchError(result.error);
10103
+ setInitializing(false);
10104
+ return;
10105
+ }
10106
+ if (result.readOnly) {
10107
+ setDetectedReadOnly(true);
10108
+ }
10109
+ const defaults = {};
10110
+ for (const field of allStorageFields) {
10111
+ if (field.defaultValue !== void 0) {
10112
+ defaults[formKey(field)] = field.defaultValue;
10113
+ }
10114
+ }
10115
+ const merged = { ...defaults, ...result.values };
10116
+ const virtualValues = computeVirtualFieldValues(schema, merged);
10117
+ reset({ ...merged, ...virtualValues });
10118
+ setInitializing(false);
10119
+ });
10120
+ return () => {
10121
+ cancelled = true;
10122
+ };
10123
+ }, [dsUid, allStorageFields, schema, reset]);
10124
+ const watchedValues = watch();
10125
+ const prevEffectValuesRef = React.useRef({});
10126
+ React.useEffect(() => {
10127
+ if (initializing) {
10128
+ return;
10129
+ }
10130
+ for (const { sourceKey, effects } of fieldsWithEffects) {
10131
+ const currentVal = watchedValues[sourceKey];
10132
+ const prevVal = prevEffectValuesRef.current[sourceKey];
10133
+ if (currentVal === prevVal) {
10134
+ continue;
10135
+ }
10136
+ prevEffectValuesRef.current[sourceKey] = currentVal;
10137
+ for (const eff of effects) {
10138
+ if (evaluateEffectCondition(eff.when, currentVal)) {
10139
+ for (const { key, value } of eff.targets) {
10140
+ setValue(key, value);
10141
+ }
10142
+ break;
10143
+ }
10144
+ }
10145
+ }
10146
+ }, [watchedValues, fieldsWithEffects, initializing, setValue]);
10147
+ const fieldsWithOverrideDefaults = React.useMemo(() => {
10148
+ const result = [];
10149
+ for (const field of schema.fields) {
10150
+ if (!field.overrides || field.overrides.length === 0) {
10151
+ continue;
10152
+ }
10153
+ const ovs = field.overrides.filter((ov) => ov.defaultValue !== void 0).map((ov) => {
10154
+ const parsed = parseDependsOn(ov.when);
10155
+ if (!parsed) {
10156
+ return null;
10157
+ }
10158
+ const depField = fieldById.get(parsed.field);
10159
+ return {
10160
+ depKey: depField ? formKey(depField) : parsed.field,
10161
+ depValue: parsed.value,
10162
+ defaultValue: ov.defaultValue
10163
+ };
10164
+ }).filter(Boolean);
10165
+ if (ovs.length > 0) {
10166
+ result.push({ targetKey: formKey(field), fieldDefault: field.defaultValue, overrides: ovs });
10167
+ }
10168
+ }
10169
+ return result;
10170
+ }, [schema.fields, fieldById]);
10171
+ const prevOverrideDepRef = React.useRef({});
10172
+ React.useEffect(() => {
10173
+ var _a;
10174
+ if (initializing) {
10175
+ return;
10176
+ }
10177
+ for (const { targetKey, fieldDefault, overrides } of fieldsWithOverrideDefaults) {
10178
+ for (const ov of overrides) {
10179
+ const currentDepVal = String((_a = watchedValues[ov.depKey]) != null ? _a : "");
10180
+ const trackKey = `${targetKey}::${ov.depKey}`;
10181
+ const prevDepVal = prevOverrideDepRef.current[trackKey];
10182
+ if (currentDepVal === prevDepVal) {
10183
+ continue;
10184
+ }
10185
+ prevOverrideDepRef.current[trackKey] = currentDepVal;
10186
+ if (currentDepVal === ov.depValue) {
10187
+ setValue(targetKey, ov.defaultValue);
10188
+ } else if (prevDepVal === ov.depValue && fieldDefault !== void 0) {
10189
+ setValue(targetKey, fieldDefault);
10190
+ }
10191
+ }
10192
+ }
10193
+ }, [watchedValues, fieldsWithOverrideDefaults, initializing, setValue]);
10194
+ const isFieldVisible = React.useCallback(
10195
+ (field) => {
10196
+ var _a, _b;
10197
+ if (field.kind === "virtual" && !field.ui) {
10198
+ return false;
10199
+ }
10200
+ if ((_a = field.tags) == null ? void 0 : _a.some((t) => t.startsWith("managed-by:"))) {
10201
+ return false;
10202
+ }
10203
+ if (!field.dependsOn) {
10204
+ return true;
10205
+ }
10206
+ const parsed = parseDependsOn(field.dependsOn);
10207
+ if (!parsed) {
10208
+ return true;
10209
+ }
10210
+ const depField = fieldById.get(parsed.field);
10211
+ const depKey = depField ? formKey(depField) : parsed.field;
10212
+ return String((_b = watchedValues[depKey]) != null ? _b : "") === parsed.value;
10213
+ },
10214
+ [watchedValues, fieldById]
10215
+ );
10216
+ const onSubmit = React.useCallback(
10217
+ async (data) => {
10218
+ setSubmitting(true);
10219
+ setSubmitError(null);
10220
+ onSaving == null ? void 0 : onSaving(true);
10221
+ const minDelay = new Promise((r) => setTimeout(r, 2e3));
10222
+ try {
10223
+ await submitDatasourceConfig(dsUid, data, allStorageFields, isFieldVisible);
10224
+ const [refreshed] = await Promise.all([fetchExistingValues(dsUid, allStorageFields), minDelay]);
10225
+ const defaults = {};
10226
+ for (const field of allStorageFields) {
10227
+ if (field.defaultValue !== void 0) {
10228
+ defaults[formKey(field)] = field.defaultValue;
10229
+ }
10230
+ }
10231
+ const merged = { ...defaults, ...refreshed.values };
10232
+ const virtualValues = computeVirtualFieldValues(schema, merged);
10233
+ reset({ ...merged, ...virtualValues });
10234
+ onSuccess("UPDATED", "Configuration saved.");
10235
+ } catch (err) {
10236
+ await minDelay;
10237
+ setSubmitError(err instanceof Error ? err.message : "Failed to update datasource");
10238
+ } finally {
10239
+ setSubmitting(false);
10240
+ onSaving == null ? void 0 : onSaving(false);
10241
+ }
10242
+ },
10243
+ [dsUid, allStorageFields, isFieldVisible, schema, reset, onSuccess, onSaving]
10244
+ );
10245
+ const isGroupValid = React.useCallback(
10246
+ (group) => {
10247
+ for (const field of group.fields) {
10248
+ if (!isFieldVisible(field)) {
10249
+ continue;
10250
+ }
10251
+ if (errors[formKey(field)]) {
10252
+ return false;
10253
+ }
10254
+ if (isFieldRequired(field, watchedValues, fieldById)) {
10255
+ const val = watchedValues[formKey(field)];
10256
+ if (val === SECURE_FIELD_CONFIGURED) {
10257
+ continue;
10258
+ }
10259
+ if (val === void 0 || val === null || val === "") {
10260
+ return false;
10261
+ }
10262
+ }
10263
+ }
10264
+ return true;
10265
+ },
10266
+ [errors, watchedValues, fieldById, isFieldVisible]
10267
+ );
10268
+ const groupHasData = React.useCallback(
10269
+ (group) => {
10270
+ for (const field of group.fields) {
10271
+ const val = watchedValues[formKey(field)];
10272
+ if (val === void 0 || val === null || val === "" || val === false) {
10273
+ continue;
10274
+ }
10275
+ if (val === field.defaultValue) {
10276
+ continue;
10277
+ }
10278
+ return true;
10279
+ }
10280
+ return false;
10281
+ },
10282
+ [watchedValues]
10283
+ );
10284
+ return {
10285
+ // Schema
10286
+ resolvedGroups,
10287
+ fieldById,
10288
+ httpHeadersField,
10289
+ // Form
10290
+ control,
10291
+ handleSubmit,
10292
+ trigger,
10293
+ errors,
10294
+ watchedValues,
10295
+ // State
10296
+ initializing,
10297
+ fetchError,
10298
+ submitting,
10299
+ submitError,
10300
+ readOnly,
10301
+ // Callbacks
10302
+ isFieldVisible,
10303
+ isGroupValid,
10304
+ groupHasData,
10305
+ onSubmit
10306
+ };
10307
+ }
10308
+
10309
+ function DatasourceConfigWizard(props) {
10310
+ const { schema, dsUid, dsName, onSuccess, onSaving, onRetest, healthError, renderActions, mode = "tab" } = props;
10311
+ const form = useDatasourceConfigForm({ schema, dsUid, onSuccess, onSaving });
10312
+ if (mode === "tab") {
10313
+ return /* @__PURE__ */ React__default.default.createElement(
10314
+ TabLayout,
10315
+ {
10316
+ form,
10317
+ schema,
10318
+ dsUid,
10319
+ dsName,
10320
+ onRetest,
10321
+ healthError,
10322
+ renderActions
10323
+ }
10324
+ );
10325
+ }
10326
+ return /* @__PURE__ */ React__default.default.createElement(
10327
+ WizardLayout,
10328
+ {
10329
+ form,
10330
+ schema,
10331
+ dsUid,
10332
+ dsName,
10333
+ onRetest,
10334
+ healthError,
10335
+ renderActions
10336
+ }
10337
+ );
10338
+ }
10339
+ function WizardLayout({ form, schema, dsUid, dsName, onRetest, healthError, renderActions }) {
10340
+ var _a, _b, _c;
10341
+ const styles = ui.useStyles2(getWizardStyles);
10342
+ const [currentStep, setCurrentStep] = React.useState(0);
10343
+ const {
10344
+ resolvedGroups,
10345
+ fieldById,
10346
+ httpHeadersField,
10347
+ control,
10348
+ handleSubmit,
10349
+ trigger,
10350
+ errors,
10351
+ watchedValues,
10352
+ initializing,
10353
+ fetchError,
10354
+ submitting,
10355
+ submitError,
10356
+ readOnly,
10357
+ isFieldVisible,
10358
+ onSubmit
10359
+ } = form;
10360
+ const arrowSteps = React.useMemo(() => {
10361
+ const requiredGroup = resolvedGroups.find((g) => g.group.id === "_required");
10362
+ if (!requiredGroup) {
10363
+ return new Set(resolvedGroups.map((_, i) => i));
10364
+ }
10365
+ const requiredFieldIds = new Set(requiredGroup.fields.map((f) => f.id));
10366
+ const steps = /* @__PURE__ */ new Set();
10367
+ for (let i = 0; i < resolvedGroups.length; i++) {
10368
+ const g = resolvedGroups[i];
10369
+ if (g.group.id === "_required" || g.fields.some((f) => !requiredFieldIds.has(f.id))) {
10370
+ steps.add(i);
10371
+ }
10372
+ }
10373
+ return steps;
10374
+ }, [resolvedGroups]);
10375
+ const currentResolved = resolvedGroups[currentStep];
10376
+ const isFirstStep = React.useMemo(() => {
10377
+ for (let i = 0; i < currentStep; i++) {
10378
+ if (arrowSteps.has(i)) {
10379
+ return false;
10380
+ }
10381
+ }
10382
+ return true;
10383
+ }, [currentStep, arrowSteps]);
10384
+ const isLastStep = React.useMemo(() => {
10385
+ for (let i = currentStep + 1; i < resolvedGroups.length; i++) {
10386
+ if (arrowSteps.has(i)) {
10387
+ return false;
10388
+ }
10389
+ }
10390
+ return true;
10391
+ }, [currentStep, arrowSteps, resolvedGroups.length]);
10392
+ const visibleFieldsForStep = React.useMemo(
10393
+ () => currentResolved ? currentResolved.fields.filter(isFieldVisible) : [],
10394
+ [currentResolved, isFieldVisible]
10395
+ );
10396
+ const currentGroupValid = React.useMemo(() => {
10397
+ if (!currentResolved) {
10398
+ return true;
10399
+ }
10400
+ for (const field of visibleFieldsForStep) {
10401
+ if (errors[formKey(field)]) {
10402
+ return false;
10403
+ }
10404
+ if (isFieldRequired(field, watchedValues, fieldById)) {
10405
+ const val = watchedValues[formKey(field)];
10406
+ if (val === SECURE_FIELD_CONFIGURED) {
10407
+ continue;
10408
+ }
10409
+ if (val === void 0 || val === null || val === "") {
10410
+ return false;
10411
+ }
10412
+ }
10413
+ }
10414
+ return true;
10415
+ }, [currentResolved, errors, visibleFieldsForStep, watchedValues, fieldById]);
10416
+ const goNext = React.useCallback(async () => {
10417
+ if (!currentResolved) {
10418
+ return;
10419
+ }
10420
+ if (!readOnly) {
10421
+ const visibleKeys = visibleFieldsForStep.map((f) => formKey(f));
10422
+ const valid = await trigger(visibleKeys);
10423
+ if (!valid) {
10424
+ return;
10425
+ }
10426
+ }
10427
+ setCurrentStep((s) => {
10428
+ for (let i = s + 1; i < resolvedGroups.length; i++) {
10429
+ if (arrowSteps.has(i)) {
10430
+ return i;
10431
+ }
10432
+ }
10433
+ return s;
10434
+ });
10435
+ }, [currentResolved, visibleFieldsForStep, trigger, resolvedGroups.length, arrowSteps, readOnly]);
10436
+ const goPrev = React.useCallback(() => {
10437
+ setCurrentStep((s) => {
10438
+ for (let i = s - 1; i >= 0; i--) {
10439
+ if (arrowSteps.has(i)) {
10440
+ return i;
10441
+ }
10442
+ }
10443
+ return s;
10444
+ });
10445
+ }, [arrowSteps]);
10446
+ if (initializing) {
10447
+ return /* @__PURE__ */ React__default.default.createElement("div", { className: styles.container }, /* @__PURE__ */ React__default.default.createElement(ui.Spinner, { size: "sm", inline: true }), " Loading configuration...");
10448
+ }
10449
+ if (fetchError) {
10450
+ return /* @__PURE__ */ React__default.default.createElement("div", { className: styles.container }, /* @__PURE__ */ React__default.default.createElement(ui.Alert, { severity: "error", title: "Failed to load configuration" }, fetchError), /* @__PURE__ */ React__default.default.createElement("div", { className: styles.buttons }, /* @__PURE__ */ React__default.default.createElement(
10451
+ ui.LinkButton,
10452
+ {
10453
+ variant: "secondary",
10454
+ size: "sm",
10455
+ icon: "external-link-alt",
10456
+ href: `/connections/datasources/edit/${dsUid}`
10457
+ },
10458
+ "Open datasource settings"
10459
+ )));
10460
+ }
10461
+ const allDisabled = submitting || readOnly;
10462
+ if (resolvedGroups.length === 0) {
10463
+ return null;
10464
+ }
10465
+ const currentGroup = currentResolved == null ? void 0 : currentResolved.group;
10466
+ return /* @__PURE__ */ React__default.default.createElement("div", { className: styles.container }, submitting && /* @__PURE__ */ React__default.default.createElement("div", { className: styles.overlay }, /* @__PURE__ */ React__default.default.createElement(ui.Spinner, { size: "sm" }), /* @__PURE__ */ React__default.default.createElement("span", null, "Saving & testing\u2026")), readOnly && /* @__PURE__ */ React__default.default.createElement("div", { className: styles.readOnlyBanner }, /* @__PURE__ */ React__default.default.createElement(ui.Icon, { name: "lock", size: "xs" }), /* @__PURE__ */ React__default.default.createElement("span", null, "Read-only \u2014 managed externally")), /* @__PURE__ */ React__default.default.createElement("div", { className: styles.navBar }, currentGroup && /* @__PURE__ */ React__default.default.createElement(ui.Tooltip, { content: (_a = currentGroup.description) != null ? _a : currentGroup.title }, /* @__PURE__ */ React__default.default.createElement("span", { className: styles.navTitle }, currentGroup.title, /* @__PURE__ */ React__default.default.createElement("span", { className: styles.stepCount }, currentStep + 1, "/", resolvedGroups.length))), /* @__PURE__ */ React__default.default.createElement("div", { className: styles.navActions }, /* @__PURE__ */ React__default.default.createElement(ui.Tooltip, { content: isFirstStep ? "First step" : `Previous: ${(_b = resolvedGroups[currentStep - 1]) == null ? void 0 : _b.group.title}` }, /* @__PURE__ */ React__default.default.createElement(
10467
+ ui.Button,
10468
+ {
10469
+ variant: "secondary",
10470
+ fill: "text",
10471
+ size: "sm",
10472
+ icon: "angle-left",
10473
+ "aria-label": "Previous",
10474
+ onClick: goPrev,
10475
+ disabled: isFirstStep || submitting,
10476
+ type: "button"
10477
+ }
10478
+ )), /* @__PURE__ */ React__default.default.createElement(
10479
+ ui.Select,
10480
+ {
10481
+ options: resolvedGroups.map((g, i) => ({ label: g.group.title, value: i })),
10482
+ value: currentStep,
10483
+ onChange: (v) => {
10484
+ if (v) {
10485
+ setCurrentStep(v.value);
10486
+ }
10487
+ },
10488
+ disabled: submitting,
10489
+ width: 18
10490
+ }
10491
+ ), /* @__PURE__ */ React__default.default.createElement(ui.Tooltip, { content: isLastStep ? "Last step" : `Next: ${(_c = resolvedGroups[currentStep + 1]) == null ? void 0 : _c.group.title}` }, /* @__PURE__ */ React__default.default.createElement(
10492
+ ui.Button,
10493
+ {
10494
+ variant: isLastStep || !readOnly && !currentGroupValid ? "secondary" : "primary",
10495
+ size: "sm",
10496
+ icon: "angle-right",
10497
+ "aria-label": "Next",
10498
+ onClick: goNext,
10499
+ disabled: isLastStep || submitting,
10500
+ type: "button"
10501
+ }
10502
+ )))), currentResolved && /* @__PURE__ */ React__default.default.createElement("form", { onSubmit: handleSubmit(onSubmit), className: styles.form }, visibleFieldsForStep.map((field) => /* @__PURE__ */ React__default.default.createElement(
10503
+ SchemaField,
10504
+ {
10505
+ key: formKey(field),
10506
+ field,
10507
+ control,
10508
+ errors,
10509
+ disabled: allDisabled,
10510
+ dsUid,
10511
+ watchedValues,
10512
+ fieldById
10513
+ }
10514
+ )), (currentResolved.group.id === "_required" || currentResolved.group.id === "auth") && httpHeadersField && /* @__PURE__ */ React__default.default.createElement(
10515
+ AuthorizationHeaderField,
10516
+ {
10517
+ headersFieldKey: formKey(httpHeadersField),
10518
+ control,
10519
+ disabled: allDisabled,
10520
+ watchedValues
10521
+ }
10522
+ ), submitError && /* @__PURE__ */ React__default.default.createElement(ui.Alert, { severity: "error", title: "Error" }, submitError), /* @__PURE__ */ React__default.default.createElement("div", { className: styles.buttons }, readOnly ? /* @__PURE__ */ React__default.default.createElement(ui.Button, { variant: "primary", size: "sm", icon: "sync", onClick: onRetest, type: "button" }, "Test") : /* @__PURE__ */ React__default.default.createElement(ui.Button, { variant: "primary", size: "sm", disabled: submitting || !currentGroupValid, type: "submit" }, submitting ? "Saving..." : "Save & Test"), healthError && (renderActions == null ? void 0 : renderActions({ dsUid, dsName, dsType: schema.pluginType, healthError })))));
10523
+ }
10524
+
10525
+ var __defProp$2 = Object.defineProperty;
10526
+ var __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
10527
+ var __publicField$2 = (obj, key, value) => __defNormalProp$2(obj, key + "" , value);
10528
+ class DatasourceErrorBoundary extends React.Component {
10529
+ constructor() {
10530
+ super(...arguments);
10531
+ __publicField$2(this, "state", { error: null });
10532
+ }
10533
+ static getDerivedStateFromError(error) {
10534
+ return { error };
10535
+ }
10536
+ componentDidCatch(error, info) {
10537
+ console.error("[DatasourceConfigWizard] Caught error:", error, info.componentStack);
10538
+ }
10539
+ render() {
10540
+ if (this.state.error) {
10541
+ return /* @__PURE__ */ React__default.default.createElement(ui.Alert, { severity: "warning", title: "Configuration wizard unavailable" }, "Could not load the configuration wizard", this.props.dsName ? ` for ${this.props.dsName}` : "", ". Use the Settings link to configure this datasource manually.");
10542
+ }
10543
+ return this.props.children;
10544
+ }
10545
+ }
10546
+
10547
+ const MAX_CONCURRENCY = 5;
10548
+ function useHealthChecks() {
10549
+ const [healthMap, setHealthMap] = React.useState({});
10550
+ const queueRef = React.useRef([]);
10551
+ const activeRef = React.useRef(0);
10552
+ const mountedRef = React.useRef(true);
10553
+ const everQueuedRef = React.useRef(/* @__PURE__ */ new Set());
10554
+ const checkOne = React.useCallback(async (uid) => {
10555
+ if (!mountedRef.current) {
10556
+ return;
10557
+ }
10558
+ setHealthMap((prev) => ({ ...prev, [uid]: { state: "checking" } }));
10559
+ try {
10560
+ const result = await runtime.getBackendSrv().get(
10561
+ `/api/datasources/uid/${uid}/health`,
10562
+ void 0,
10563
+ void 0,
10564
+ { showErrorAlert: false }
10565
+ );
10566
+ if (!mountedRef.current) {
10567
+ return;
10568
+ }
10569
+ setHealthMap((prev) => {
10570
+ var _a;
10571
+ return {
10572
+ ...prev,
10573
+ [uid]: { state: "done", status: (_a = result.status) != null ? _a : "OK", message: result.message }
10574
+ };
10575
+ });
10576
+ } catch (error) {
10577
+ if (!mountedRef.current) {
10578
+ return;
10579
+ }
10580
+ let status = "ERROR";
10581
+ let message = "";
10582
+ if (error && typeof error === "object" && "data" in error) {
10583
+ const data = error.data;
10584
+ if (data == null ? void 0 : data.status) {
10585
+ status = data.status;
10586
+ }
10587
+ if (data == null ? void 0 : data.message) {
10588
+ message = data.message;
10589
+ }
10590
+ }
10591
+ if (!message) {
10592
+ message = error instanceof Error ? error.message : String(error);
10593
+ }
10594
+ setHealthMap((prev) => ({
10595
+ ...prev,
10596
+ [uid]: { state: "done", status, message }
10597
+ }));
10598
+ }
10599
+ }, []);
10600
+ const processQueue = React.useCallback(() => {
10601
+ while (activeRef.current < MAX_CONCURRENCY && queueRef.current.length > 0) {
10602
+ const uid = queueRef.current.shift();
10603
+ activeRef.current++;
10604
+ checkOne(uid).finally(() => {
10605
+ activeRef.current--;
10606
+ processQueue();
10607
+ });
10608
+ }
10609
+ }, [checkOne]);
10610
+ const checkUids = React.useCallback(
10611
+ (uids) => {
10612
+ const toCheck = [];
10613
+ for (const uid of uids) {
10614
+ if (everQueuedRef.current.has(uid)) {
10615
+ continue;
10616
+ }
10617
+ everQueuedRef.current.add(uid);
10618
+ toCheck.push(uid);
10619
+ }
10620
+ if (toCheck.length === 0) {
10621
+ return;
10622
+ }
10623
+ setHealthMap((prev) => {
10624
+ const next = { ...prev };
10625
+ for (const uid of toCheck) {
10626
+ next[uid] = { state: "pending" };
10627
+ }
10628
+ return next;
10629
+ });
10630
+ queueRef.current.push(...toCheck);
10631
+ processQueue();
10632
+ },
10633
+ [processQueue]
10634
+ );
10635
+ const retry = React.useCallback(
10636
+ (uid) => {
10637
+ everQueuedRef.current.delete(uid);
10638
+ everQueuedRef.current.add(uid);
10639
+ setHealthMap((prev) => ({ ...prev, [uid]: { state: "pending" } }));
10640
+ queueRef.current.push(uid);
10641
+ processQueue();
10642
+ },
10643
+ [processQueue]
10644
+ );
10645
+ return { healthMap, checkUids, retry };
10646
+ }
10647
+
10648
+ let pluginNameCache = null;
10649
+ function buildPluginNameCache() {
10650
+ var _a;
10651
+ if (pluginNameCache) {
10652
+ return pluginNameCache;
10653
+ }
10654
+ const map = /* @__PURE__ */ new Map();
10655
+ try {
10656
+ const list = runtime.getDataSourceSrv().getList();
10657
+ for (const ds of list) {
10658
+ if (((_a = ds.meta) == null ? void 0 : _a.name) && ds.type && !map.has(ds.type)) {
10659
+ map.set(ds.type, ds.meta.name);
10660
+ }
10661
+ }
10662
+ } catch (ex) {
10663
+ console.error(ex);
10664
+ }
10665
+ pluginNameCache = map;
10666
+ return map;
10667
+ }
10668
+ function resolvePluginName(pluginType) {
10669
+ var _a;
10670
+ const cache = buildPluginNameCache();
10671
+ return (_a = cache.get(pluginType)) != null ? _a : pluginType;
10672
+ }
10673
+
10674
+ var __defProp$1 = Object.defineProperty;
10675
+ var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
10676
+ var __publicField$1 = (obj, key, value) => __defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
10677
+ const getCustomHeaderRowStyles = ui.stylesFactory(() => {
10678
+ return {
10679
+ layout: css.css`
10680
+ display: flex;
10681
+ align-items: center;
10682
+ margin-bottom: 4px;
10683
+ > * {
10684
+ margin-left: 4px;
10685
+ margin-bottom: 0;
10686
+ height: 100%;
10687
+ &:first-child,
10688
+ &:last-child {
10689
+ margin-left: 0;
10690
+ }
10691
+ }
10692
+ `
10693
+ };
10694
+ });
10695
+ const CustomHeaderRow = ({ header, onBlur, onChange, onRemove, onReset }) => {
10696
+ const styles = getCustomHeaderRowStyles();
10697
+ return /* @__PURE__ */ React__default.default.createElement("div", { className: styles.layout }, /* @__PURE__ */ React__default.default.createElement(
10698
+ ui.LegacyForms.FormField,
10699
+ {
10700
+ label: "Header",
10701
+ name: "name",
10702
+ placeholder: "X-Custom-Header",
10703
+ labelWidth: 5,
10704
+ value: header.name || "",
10705
+ onChange: (e) => onChange({ ...header, name: e.target.value }),
10706
+ onBlur
10707
+ }
10708
+ ), /* @__PURE__ */ React__default.default.createElement(
10709
+ ui.LegacyForms.SecretFormField,
10710
+ {
10711
+ label: "Value",
10712
+ "aria-label": "Value",
10713
+ name: "value",
10714
+ isConfigured: header.configured,
10715
+ value: header.value,
10716
+ labelWidth: 5,
10717
+ inputWidth: header.configured ? 11 : 12,
10718
+ placeholder: "Header Value",
10719
+ onReset: () => onReset(header.id),
10720
+ onChange: (e) => onChange({ ...header, value: e.target.value }),
10721
+ onBlur
10722
+ }
10723
+ ), /* @__PURE__ */ React__default.default.createElement(
10724
+ ui.Button,
10725
+ {
10726
+ type: "button",
10727
+ "aria-label": "Remove header",
10728
+ variant: "secondary",
10729
+ size: "xs",
10730
+ onClick: (_e) => onRemove(header.id)
10731
+ },
10732
+ /* @__PURE__ */ React__default.default.createElement(ui.Icon, { name: "trash-alt" })
10733
+ ));
10734
+ };
10735
+ CustomHeaderRow.displayName = "CustomHeaderRow";
10736
+ class CustomHeadersSettings extends React.PureComponent {
10737
+ constructor(props) {
10738
+ super(props);
10739
+ __publicField$1(this, "state", {
10740
+ headers: []
10741
+ });
10742
+ __publicField$1(this, "updateSettings", () => {
10743
+ const { headers } = this.state;
10744
+ const newJsonData = Object.fromEntries(
10745
+ Object.entries(this.props.dataSourceConfig.jsonData).filter(([key, val]) => !key.startsWith("httpHeaderName"))
10746
+ );
10747
+ const newSecureJsonData = Object.fromEntries(
10748
+ Object.entries(this.props.dataSourceConfig.secureJsonData || {}).filter(
10749
+ ([key, val]) => !key.startsWith("httpHeaderValue")
10750
+ )
10751
+ );
10752
+ for (const [index, header] of headers.entries()) {
10753
+ newJsonData[`httpHeaderName${index + 1}`] = header.name;
10754
+ if (!header.configured) {
10755
+ newSecureJsonData[`httpHeaderValue${index + 1}`] = header.value;
10756
+ }
10757
+ }
10758
+ this.props.onChange({
10759
+ ...this.props.dataSourceConfig,
10760
+ jsonData: newJsonData,
10761
+ secureJsonData: newSecureJsonData
10762
+ });
10763
+ });
10764
+ __publicField$1(this, "onHeaderAdd", () => {
10765
+ this.setState((prevState) => {
10766
+ return {
10767
+ headers: [...prevState.headers, { id: lodash.uniqueId(), name: "", value: "", configured: false }]
10768
+ };
10769
+ });
10770
+ });
10771
+ __publicField$1(this, "onHeaderChange", (headerIndex, value) => {
10772
+ this.setState(({ headers }) => {
10773
+ return {
10774
+ headers: headers.map((item, index) => {
10775
+ if (headerIndex !== index) {
10776
+ return item;
10777
+ }
10778
+ return { ...value };
10779
+ })
10780
+ };
10781
+ });
10782
+ });
10783
+ __publicField$1(this, "onHeaderReset", (headerId) => {
10784
+ this.setState(({ headers }) => {
10785
+ return {
10786
+ headers: headers.map((h, i) => {
10787
+ if (h.id !== headerId) {
10788
+ return h;
10789
+ }
10790
+ return {
10791
+ ...h,
10792
+ value: "",
10793
+ configured: false
10794
+ };
10795
+ })
10796
+ };
10797
+ });
10798
+ });
10799
+ __publicField$1(this, "onHeaderRemove", (headerId) => {
10800
+ this.setState(
10801
+ ({ headers }) => ({
10802
+ headers: headers.filter((h) => h.id !== headerId)
10803
+ }),
10804
+ this.updateSettings
10805
+ );
10806
+ });
10807
+ const { jsonData, secureJsonData, secureJsonFields } = this.props.dataSourceConfig;
10808
+ this.state = {
10809
+ headers: Object.keys(jsonData).sort().filter((key) => key.startsWith("httpHeaderName")).map((key, index) => {
10810
+ return {
10811
+ id: lodash.uniqueId(),
10812
+ name: jsonData[key],
10813
+ value: secureJsonData !== void 0 ? secureJsonData[key] : "",
10814
+ configured: secureJsonFields && secureJsonFields[`httpHeaderValue${index + 1}`] || false
10815
+ };
10816
+ })
10817
+ };
10818
+ }
10819
+ render() {
10820
+ const { headers } = this.state;
10821
+ return /* @__PURE__ */ React__default.default.createElement("div", { className: "gf-form-group" }, /* @__PURE__ */ React__default.default.createElement("div", { className: "gf-form" }, /* @__PURE__ */ React__default.default.createElement("h6", null, "Custom HTTP Headers")), /* @__PURE__ */ React__default.default.createElement("div", null, headers.map((header, i) => /* @__PURE__ */ React__default.default.createElement(
10822
+ CustomHeaderRow,
10823
+ {
10824
+ key: header.id,
10825
+ header,
10826
+ onChange: (h) => {
10827
+ this.onHeaderChange(i, h);
10828
+ },
10829
+ onBlur: this.updateSettings,
10830
+ onRemove: this.onHeaderRemove,
10831
+ onReset: this.onHeaderReset
10832
+ }
10833
+ ))), /* @__PURE__ */ React__default.default.createElement("div", { className: "gf-form" }, /* @__PURE__ */ React__default.default.createElement(
10834
+ ui.Button,
10835
+ {
10836
+ variant: "secondary",
10837
+ icon: "plus",
10838
+ type: "button",
10839
+ onClick: (e) => {
10840
+ this.onHeaderAdd();
10841
+ }
10842
+ },
10843
+ "Add header"
10844
+ )));
10845
+ }
10846
+ }
10847
+
10848
+ var QueryEditorMode = /* @__PURE__ */ ((QueryEditorMode2) => {
10849
+ QueryEditorMode2["Code"] = "code";
10850
+ QueryEditorMode2["Builder"] = "builder";
10851
+ return QueryEditorMode2;
10852
+ })(QueryEditorMode || {});
10853
+ const BINARY_OPERATIONS_KEY = "Binary operations";
10854
+
10855
+ var __defProp = Object.defineProperty;
10856
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
10857
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
10858
+ class QueryModellerBase {
10859
+ constructor(operationDefinitions, innerQueryPlaceholder) {
10860
+ __publicField(this, "operationsRegistry");
10861
+ __publicField(this, "categories", []);
10862
+ __publicField(this, "innerQueryPlaceholder");
10863
+ this.operationsRegistry = new data.Registry(() => operationDefinitions);
10864
+ this.innerQueryPlaceholder = innerQueryPlaceholder || "<query>";
10865
+ }
10866
+ setOperationCategories(categories) {
10867
+ this.categories = categories;
10868
+ }
10869
+ getOperationsForCategory(category) {
10870
+ return this.operationsRegistry.list().filter((op) => op.category === category && !op.hideFromList);
10871
+ }
10872
+ getAlternativeOperations(key) {
10873
+ return this.operationsRegistry.list().filter((op) => op.alternativesKey && op.alternativesKey === key);
10874
+ }
10875
+ getCategories() {
10876
+ return this.categories;
10877
+ }
10878
+ getOperationDefinition(id) {
10879
+ return this.operationsRegistry.getIfExists(id);
10880
+ }
10881
+ hasBinaryOp(query) {
10882
+ return query.operations.find((op) => {
10883
+ const def = this.getOperationDefinition(op.id);
10884
+ return (def == null ? void 0 : def.category) === BINARY_OPERATIONS_KEY;
10885
+ }) !== void 0;
10886
+ }
10887
+ }
10888
+
10889
+ const CONFLICTING_LABEL_FILTER_ERROR_MESSAGE = "You have conflicting label filters";
10890
+ function LabelFilterItem({
10891
+ item,
10892
+ items,
8611
10893
  defaultOp,
8612
10894
  onChange,
8613
10895
  onDelete,
@@ -9842,6 +12124,412 @@ const convertUnits = (queryStats) => {
9842
12124
  return text + suffix;
9843
12125
  };
9844
12126
 
12127
+ function generateLLMHint(schema) {
12128
+ var _a, _b, _c, _d;
12129
+ const hints = [];
12130
+ for (const field of schema.fields) {
12131
+ if (((_a = field.ui) == null ? void 0 : _a.component) !== "select" || field.target !== "jsonData" || field.kind === "virtual") {
12132
+ continue;
12133
+ }
12134
+ const options = (_c = (_b = field.ui) == null ? void 0 : _b.options) != null ? _c : [];
12135
+ const values = options.map((opt) => {
12136
+ const isDefault = field.defaultValue != null && String(opt.value) === String(field.defaultValue);
12137
+ return isDefault ? `"${opt.value}" (default)` : `"${opt.value}"`;
12138
+ }).join(", ");
12139
+ if (values) {
12140
+ hints.push(`- ${(_d = field.label) != null ? _d : field.key}: jsonData.${field.key} \u2014 values: ${values}`);
12141
+ }
12142
+ }
12143
+ return hints.join("\n");
12144
+ }
12145
+ function generateTroubleshootingFields(schema) {
12146
+ var _a, _b, _c;
12147
+ const result = [];
12148
+ for (const field of schema.fields) {
12149
+ if (field.kind === "virtual" || field.isItemField) {
12150
+ continue;
12151
+ }
12152
+ const entry = {
12153
+ label: (_a = field.label) != null ? _a : field.key,
12154
+ key: field.target === "root" ? field.key : `${field.target}.${field.key}`,
12155
+ target: (_b = field.target) != null ? _b : "jsonData",
12156
+ type: field.valueType,
12157
+ required: !!field.required
12158
+ };
12159
+ if (field.description) {
12160
+ entry.description = field.description;
12161
+ }
12162
+ if (field.defaultValue != null) {
12163
+ entry.defaultValue = field.defaultValue;
12164
+ }
12165
+ if (((_c = field.ui) == null ? void 0 : _c.options) && field.ui.options.length > 0) {
12166
+ entry.options = field.ui.options.map((o) => String(o.value));
12167
+ }
12168
+ if (field.section) {
12169
+ entry.section = field.section;
12170
+ }
12171
+ if (field.dependsOn) {
12172
+ entry.dependsOn = field.dependsOn;
12173
+ }
12174
+ result.push(entry);
12175
+ }
12176
+ return result;
12177
+ }
12178
+
12179
+ function yamlIndent(depth) {
12180
+ return " ".repeat(depth);
12181
+ }
12182
+ function yamlString(value) {
12183
+ if (value === null || value === void 0) {
12184
+ return '""';
12185
+ }
12186
+ const s = String(value);
12187
+ if (s === "") {
12188
+ return '""';
12189
+ }
12190
+ return yaml__default.default.dump(s, { lineWidth: -1 }).trimEnd();
12191
+ }
12192
+ function yamlValue(value, depth) {
12193
+ if (value === null || value === void 0) {
12194
+ return '""';
12195
+ }
12196
+ if (typeof value === "boolean") {
12197
+ return value ? "true" : "false";
12198
+ }
12199
+ if (typeof value === "number") {
12200
+ return String(value);
12201
+ }
12202
+ if (typeof value === "string") {
12203
+ return yamlString(value);
12204
+ }
12205
+ if (Array.isArray(value)) {
12206
+ if (value.length === 0) {
12207
+ return "[]";
12208
+ }
12209
+ const lines = value.map((item) => {
12210
+ if (typeof item === "object" && item !== null && !Array.isArray(item)) {
12211
+ const entries = Object.entries(item);
12212
+ if (entries.length === 0) {
12213
+ return `${yamlIndent(depth)}- {}`;
12214
+ }
12215
+ const [firstKey, firstVal] = entries[0];
12216
+ const firstLine = `${yamlIndent(depth)}- ${yamlString(firstKey)}: ${yamlValue(firstVal, depth + 2)}`;
12217
+ const rest = entries.slice(1).map(([k, v]) => `${yamlIndent(depth + 1)}${yamlString(k)}: ${yamlValue(v, depth + 2)}`);
12218
+ return [firstLine, ...rest].join("\n");
12219
+ }
12220
+ return `${yamlIndent(depth)}- ${yamlValue(item, depth + 1)}`;
12221
+ });
12222
+ return "\n" + lines.join("\n");
12223
+ }
12224
+ if (typeof value === "object") {
12225
+ const entries = Object.entries(value);
12226
+ if (entries.length === 0) {
12227
+ return "{}";
12228
+ }
12229
+ const lines = entries.map(([k, v]) => `${yamlIndent(depth)}${yamlString(k)}: ${yamlValue(v, depth + 1)}`);
12230
+ return "\n" + lines.join("\n");
12231
+ }
12232
+ return yamlString(value);
12233
+ }
12234
+ function isCertField(field) {
12235
+ var _a;
12236
+ const k = field.key.toLowerCase();
12237
+ return field.target === "secureJsonData" && (k.includes("cert") || k.includes("key") || ((_a = field.ui) == null ? void 0 : _a.component) === "textarea");
12238
+ }
12239
+ function isExcludedFromProvisioning(field) {
12240
+ var _a, _b;
12241
+ if (field.kind === "virtual") {
12242
+ return true;
12243
+ }
12244
+ if (field.isItemField) {
12245
+ return true;
12246
+ }
12247
+ if (((_a = field.tags) == null ? void 0 : _a.some((t) => t.startsWith("managed-by:"))) && field.target !== "root") {
12248
+ return true;
12249
+ }
12250
+ if (((_b = field.storage) == null ? void 0 : _b.type) === "indexedPair") {
12251
+ return true;
12252
+ }
12253
+ return false;
12254
+ }
12255
+ function secretPlaceholder(field) {
12256
+ if (isCertField(field)) {
12257
+ return "|\n xxxxxx";
12258
+ }
12259
+ return "xxxxxx";
12260
+ }
12261
+ function templateValue(field) {
12262
+ var _a;
12263
+ if (field.defaultValue !== void 0) {
12264
+ return field.defaultValue;
12265
+ }
12266
+ if (((_a = field.ui) == null ? void 0 : _a.options) && field.ui.options.length > 0) {
12267
+ return field.ui.options[0].value;
12268
+ }
12269
+ switch (field.valueType) {
12270
+ case "string":
12271
+ return "";
12272
+ case "number":
12273
+ return 0;
12274
+ case "boolean":
12275
+ return false;
12276
+ case "array":
12277
+ return [];
12278
+ case "object":
12279
+ case "map":
12280
+ return {};
12281
+ default:
12282
+ return "";
12283
+ }
12284
+ }
12285
+ function fieldComment(field, indent) {
12286
+ var _a, _b, _c;
12287
+ const parts = [];
12288
+ const label = (_a = field.label) != null ? _a : field.key;
12289
+ let line = label;
12290
+ if (field.required) {
12291
+ line += " (REQUIRED)";
12292
+ }
12293
+ if (field.description) {
12294
+ line += ` \u2014 ${field.description}`;
12295
+ }
12296
+ parts.push(`${indent}# ${line}`);
12297
+ const options = (_b = field.ui) == null ? void 0 : _b.options;
12298
+ if (options && options.length > 0) {
12299
+ const vals = options.map((o) => String(o.value)).join(", ");
12300
+ parts.push(`${indent}# Allowed values: ${vals}`);
12301
+ }
12302
+ const allowedValuesRule = (_c = field.validations) == null ? void 0 : _c.find(
12303
+ (v) => v.type === "allowedValues"
12304
+ );
12305
+ if (allowedValuesRule && !options) {
12306
+ const vals = allowedValuesRule.values.map((v) => String(v)).join(", ");
12307
+ parts.push(`${indent}# Allowed values: ${vals}`);
12308
+ }
12309
+ if (field.dependsOn) {
12310
+ parts.push(`${indent}# Only when: ${field.dependsOn}`);
12311
+ }
12312
+ return parts.join("\n");
12313
+ }
12314
+ function toProvisioningYaml(schema, values, options) {
12315
+ var _a, _b, _c, _d, _e, _f;
12316
+ const isTemplate = !values;
12317
+ const showComments = (_a = options == null ? void 0 : options.comments) != null ? _a : isTemplate;
12318
+ const indent2 = " ";
12319
+ const indent3 = " ";
12320
+ const groups = resolveGroups(schema);
12321
+ const rootFields = [];
12322
+ const jsonDataFieldsByGroup = [];
12323
+ const secureJsonDataFieldsByGroup = [];
12324
+ const virtualFieldsWithOptions = [];
12325
+ for (const { group, fields } of groups) {
12326
+ const jd = [];
12327
+ const sd = [];
12328
+ for (const field of fields) {
12329
+ if (field.kind === "virtual" && ((_b = field.ui) == null ? void 0 : _b.options) && field.ui.options.length > 0) {
12330
+ virtualFieldsWithOptions.push(field);
12331
+ continue;
12332
+ }
12333
+ if (isExcludedFromProvisioning(field)) {
12334
+ continue;
12335
+ }
12336
+ switch (field.target) {
12337
+ case "root":
12338
+ rootFields.push(field);
12339
+ break;
12340
+ case "jsonData":
12341
+ jd.push(field);
12342
+ break;
12343
+ case "secureJsonData":
12344
+ sd.push(field);
12345
+ break;
12346
+ }
12347
+ }
12348
+ if (jd.length > 0) {
12349
+ jsonDataFieldsByGroup.push({ group, fields: jd });
12350
+ }
12351
+ if (sd.length > 0) {
12352
+ secureJsonDataFieldsByGroup.push({ group, fields: sd });
12353
+ }
12354
+ }
12355
+ const allSecureJsonDataFields = secureJsonDataFieldsByGroup.flatMap((g) => g.fields);
12356
+ const groupedFieldIds = new Set(groups.flatMap(({ group }) => group.fieldRefs));
12357
+ for (const field of schema.fields) {
12358
+ if (field.target === "root" && !groupedFieldIds.has(field.id) && !isExcludedFromProvisioning(field)) {
12359
+ rootFields.push(field);
12360
+ }
12361
+ }
12362
+ const lines = [];
12363
+ lines.push("apiVersion: 1");
12364
+ lines.push("");
12365
+ lines.push("datasources:");
12366
+ lines.push(`${indent2.slice(2)}- name: ${yamlString((_d = (_c = options == null ? void 0 : options.name) != null ? _c : values == null ? void 0 : values.name) != null ? _d : `my-${schema.pluginType}`)}`);
12367
+ lines.push(`${indent2}type: ${schema.pluginType}`);
12368
+ if (!isTemplate && (values == null ? void 0 : values.uid)) {
12369
+ lines.push(`${indent2}uid: ${yamlString(values.uid)}`);
12370
+ }
12371
+ const ALREADY_EMITTED_ROOT = /* @__PURE__ */ new Set(["name", "type", "uid"]);
12372
+ for (const field of rootFields) {
12373
+ if (ALREADY_EMITTED_ROOT.has(field.key)) {
12374
+ continue;
12375
+ }
12376
+ const val = values ? values[field.key] : templateValue(field);
12377
+ if (val === void 0 || val === null) {
12378
+ continue;
12379
+ }
12380
+ if (!isTemplate && val === false) {
12381
+ continue;
12382
+ }
12383
+ if (showComments) {
12384
+ lines.push(fieldComment(field, indent2));
12385
+ }
12386
+ lines.push(`${indent2}${field.key}: ${yamlValue(val, 3)}`);
12387
+ }
12388
+ if (showComments) {
12389
+ for (const vf of virtualFieldsWithOptions) {
12390
+ const label = (_e = vf.label) != null ? _e : vf.key;
12391
+ const opts = vf.ui.options.map((o) => `${String(o.value)} (${o.label})`).join(", ");
12392
+ lines.push(`${indent2}# ${label}: ${opts}`);
12393
+ if (vf.description) {
12394
+ lines.push(`${indent2}# ${vf.description}`);
12395
+ }
12396
+ }
12397
+ }
12398
+ const emittedJsonDataKeys = /* @__PURE__ */ new Set();
12399
+ const emittedSecureJsonDataKeys = /* @__PURE__ */ new Set();
12400
+ const jsonDataValues = values == null ? void 0 : values.jsonData;
12401
+ const hasJsonDataFromSchema = jsonDataFieldsByGroup.length > 0;
12402
+ const hasJsonDataFromValues = !isTemplate && jsonDataValues && Object.keys(jsonDataValues).length > 0;
12403
+ if (hasJsonDataFromSchema || hasJsonDataFromValues) {
12404
+ lines.push(`${indent2}jsonData:`);
12405
+ for (const { group, fields: groupFields } of jsonDataFieldsByGroup) {
12406
+ if (showComments && jsonDataFieldsByGroup.length > 1) {
12407
+ lines.push(`${indent3}# --- ${group.title} ---`);
12408
+ }
12409
+ for (const field of groupFields) {
12410
+ const val = values ? getNestedValue(values, "jsonData", field) : templateValue(field);
12411
+ if (val === void 0 || val === null) {
12412
+ continue;
12413
+ }
12414
+ if (!isTemplate && field.defaultValue !== void 0 && val === field.defaultValue) {
12415
+ continue;
12416
+ }
12417
+ emittedJsonDataKeys.add(field.key);
12418
+ if (showComments) {
12419
+ lines.push(fieldComment(field, indent3));
12420
+ }
12421
+ const rendered = yamlValue(val, 4);
12422
+ if (rendered.startsWith("\n")) {
12423
+ lines.push(`${indent3}${field.key}:${rendered}`);
12424
+ } else {
12425
+ lines.push(`${indent3}${field.key}: ${rendered}`);
12426
+ }
12427
+ }
12428
+ }
12429
+ if (!isTemplate && jsonDataValues) {
12430
+ for (const [key, val] of Object.entries(jsonDataValues)) {
12431
+ if (emittedJsonDataKeys.has(key)) {
12432
+ continue;
12433
+ }
12434
+ if (val === void 0 || val === null) {
12435
+ continue;
12436
+ }
12437
+ const rendered = yamlValue(val, 4);
12438
+ if (rendered.startsWith("\n")) {
12439
+ lines.push(`${indent3}${key}:${rendered}`);
12440
+ } else {
12441
+ lines.push(`${indent3}${key}: ${rendered}`);
12442
+ }
12443
+ }
12444
+ }
12445
+ }
12446
+ const secureJsonFields = (_f = values == null ? void 0 : values.secureJsonFields) != null ? _f : {};
12447
+ const inferredSecureKeys = !isTemplate ? inferSecureJsonDataKeys(jsonDataValues) : [];
12448
+ const activeSecureFields = isTemplate ? allSecureJsonDataFields : allSecureJsonDataFields.filter((f) => secureJsonFields[f.key] === true);
12449
+ if (activeSecureFields.length > 0 || inferredSecureKeys.length > 0) {
12450
+ lines.push(`${indent2}secureJsonData:`);
12451
+ for (const field of activeSecureFields) {
12452
+ emittedSecureJsonDataKeys.add(field.key);
12453
+ if (showComments) {
12454
+ lines.push(fieldComment(field, indent3));
12455
+ }
12456
+ lines.push(`${indent3}${field.key}: ${secretPlaceholder(field)}`);
12457
+ }
12458
+ for (const key of inferredSecureKeys) {
12459
+ if (emittedSecureJsonDataKeys.has(key)) {
12460
+ continue;
12461
+ }
12462
+ lines.push(`${indent3}${key}: xxxxxx`);
12463
+ }
12464
+ }
12465
+ return lines.join("\n");
12466
+ }
12467
+ function inferSecureJsonDataKeys(jsonData) {
12468
+ if (!jsonData) {
12469
+ return [];
12470
+ }
12471
+ const keys = [];
12472
+ for (const key of Object.keys(jsonData)) {
12473
+ const match = key.match(/^httpHeaderName(\d+)$/);
12474
+ if (match) {
12475
+ keys.push(`httpHeaderValue${match[1]}`);
12476
+ }
12477
+ }
12478
+ return keys;
12479
+ }
12480
+ function getNestedValue(values, target, field) {
12481
+ const nested = values[target];
12482
+ if (nested && typeof nested === "object") {
12483
+ return nested[field.key];
12484
+ }
12485
+ return void 0;
12486
+ }
12487
+ function datasourceToProvisioningYaml(ds, schema) {
12488
+ if (schema) {
12489
+ return toProvisioningYaml(schema, ds, { comments: false });
12490
+ }
12491
+ const lines = [];
12492
+ lines.push("apiVersion: 1");
12493
+ lines.push("");
12494
+ lines.push("datasources:");
12495
+ lines.push(` - name: ${yamlString(ds.name)}`);
12496
+ if (ds.uid) {
12497
+ lines.push(` uid: ${yamlString(ds.uid)}`);
12498
+ }
12499
+ lines.push(` type: ${yamlString(ds.type)}`);
12500
+ if (ds.url) {
12501
+ lines.push(` url: ${yamlString(ds.url)}`);
12502
+ }
12503
+ if (ds.database) {
12504
+ lines.push(` database: ${yamlString(ds.database)}`);
12505
+ }
12506
+ if (ds.isDefault) {
12507
+ lines.push(" isDefault: true");
12508
+ }
12509
+ if (ds.basicAuth) {
12510
+ lines.push(" basicAuth: true");
12511
+ if (ds.basicAuthUser) {
12512
+ lines.push(` basicAuthUser: ${yamlString(ds.basicAuthUser)}`);
12513
+ }
12514
+ }
12515
+ const jsonData = ds.jsonData;
12516
+ if (jsonData && Object.keys(jsonData).length > 0) {
12517
+ lines.push(" jsonData:");
12518
+ for (const [key, val] of Object.entries(jsonData)) {
12519
+ const rendered = yamlValue(val, 4);
12520
+ if (rendered.startsWith("\n")) {
12521
+ lines.push(` ${key}:${rendered}`);
12522
+ } else {
12523
+ lines.push(` ${key}: ${rendered}`);
12524
+ }
12525
+ }
12526
+ }
12527
+ lines.push(" # secureJsonData: (secrets are not exported \u2014 add manually)");
12528
+ lines.push(" # mySecret: xxxxxx");
12529
+ return lines.join("\n");
12530
+ }
12531
+
12532
+ exports.getConfigSchema = schemas.getConfigSchema;
9845
12533
  exports.AccessoryButton = AccessoryButton;
9846
12534
  exports.AdvancedHttpSettings = AdvancedHttpSettings;
9847
12535
  exports.Auth = Auth;
@@ -9861,6 +12549,8 @@ exports.DataLinks = DataLinks;
9861
12549
  exports.DataSourceDescription = DataSourceDescription;
9862
12550
  exports.DataSourcePicker = DataSourcePicker;
9863
12551
  exports.DatasetSelector = DatasetSelector;
12552
+ exports.DatasourceConfigWizard = DatasourceConfigWizard;
12553
+ exports.DatasourceErrorBoundary = DatasourceErrorBoundary;
9864
12554
  exports.DatePicker = DatePicker;
9865
12555
  exports.DatePickerWithInput = DatePickerWithInput;
9866
12556
  exports.DebounceInput = DebounceInput;
@@ -9896,6 +12586,7 @@ exports.QueryModellerBase = QueryModellerBase;
9896
12586
  exports.QueryOptionGroup = QueryOptionGroup;
9897
12587
  exports.RawQuery = RawQuery;
9898
12588
  exports.RunQueryButton = RunQueryButton;
12589
+ exports.SECURE_FIELD_CONFIGURED = SECURE_FIELD_CONFIGURED;
9899
12590
  exports.SQLEditor = SQLEditor;
9900
12591
  exports.SQLEditorMode = SQLEditorMode;
9901
12592
  exports.SQLEditorTestUtils = SQLEditorTestUtils;
@@ -9909,10 +12600,28 @@ exports.SuggestionKind = SuggestionKind;
9909
12600
  exports.TLSSettings = TLSSettings;
9910
12601
  exports.TableSelector = TableSelector;
9911
12602
  exports.TokenType = TokenType;
12603
+ exports.buildDatasourceConfigPayload = buildDatasourceConfigPayload;
12604
+ exports.computeVirtualFieldValues = computeVirtualFieldValues;
9912
12605
  exports.convertLegacyAuthProps = convertLegacyAuthProps;
12606
+ exports.datasourceToProvisioningYaml = datasourceToProvisioningYaml;
12607
+ exports.evaluateComputedRead = evaluateComputedRead;
12608
+ exports.expandIndexedPair = expandIndexedPair;
12609
+ exports.fetchExistingValues = fetchExistingValues;
12610
+ exports.flattenIndexedPair = flattenIndexedPair;
12611
+ exports.formKey = formKey;
9913
12612
  exports.formatDate = formatDate;
12613
+ exports.generateLLMHint = generateLLMHint;
12614
+ exports.generateTroubleshootingFields = generateTroubleshootingFields;
9914
12615
  exports.getStandardSQLCompletionProvider = getStandardSQLCompletionProvider;
9915
12616
  exports.grafanaStandardSQLLanguage = language;
9916
12617
  exports.grafanaStandardSQLLanguageConf = conf;
12618
+ exports.parseDependsOn = parseDependsOn;
12619
+ exports.resolveActiveOverride = resolveActiveOverride;
12620
+ exports.resolveGroups = resolveGroups;
12621
+ exports.resolvePluginName = resolvePluginName;
12622
+ exports.resolveRequiredFieldsGroup = resolveRequiredFieldsGroup;
12623
+ exports.submitDatasourceConfig = submitDatasourceConfig;
9917
12624
  exports.toOption = toOption;
12625
+ exports.toProvisioningYaml = toProvisioningYaml;
12626
+ exports.useHealthChecks = useHealthChecks;
9918
12627
  //# sourceMappingURL=index.cjs.map