@grafana/plugin-ui 0.14.0-dev.1 → 0.14.1-dsconfig.032cfc4

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 (285) hide show
  1. package/dist/cjs/index.cjs +2803 -185
  2. package/dist/cjs/index.cjs.map +1 -1
  3. package/dist/cjs/index.d.cts +694 -39
  4. package/dist/cjs/schemas.cjs +25 -0
  5. package/dist/cjs/schemas.cjs.map +1 -0
  6. package/dist/cjs/schemas.d.cts +448 -0
  7. package/dist/cjs/test-utils.d.cts +23 -23
  8. package/dist/cjs/useDatasourceSchema-CxPGD2-b.js +17125 -0
  9. package/dist/cjs/useDatasourceSchema-CxPGD2-b.js.map +1 -0
  10. package/dist/esm/components/ConfigEditor/ConfigSection/ConfigDescriptionLink.js +2 -2
  11. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/DatasourceConfigWizard.js +234 -0
  12. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/DatasourceConfigWizard.js.map +1 -0
  13. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/DatasourceErrorBoundary.js +27 -0
  14. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/DatasourceErrorBoundary.js.map +1 -0
  15. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/SchemaField.js +71 -0
  16. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/SchemaField.js.map +1 -0
  17. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/SidebarNav.js +54 -0
  18. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/SidebarNav.js.map +1 -0
  19. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/TabLayout.js +181 -0
  20. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/TabLayout.js.map +1 -0
  21. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/cel.js +75 -0
  22. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/cel.js.map +1 -0
  23. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/config.js +258 -0
  24. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/config.js.map +1 -0
  25. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/datasource.js +354 -0
  26. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/datasource.js.map +1 -0
  27. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/fieldUtils.js +138 -0
  28. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/fieldUtils.js.map +1 -0
  29. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/hooks/useDatasourceConfigForm.js +326 -0
  30. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/hooks/useDatasourceConfigForm.js.map +1 -0
  31. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/hooks/useHealthChecks.js +106 -0
  32. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/hooks/useHealthChecks.js.map +1 -0
  33. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/inputs/AuthorizationHeaderField.js +51 -0
  34. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/inputs/AuthorizationHeaderField.js.map +1 -0
  35. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/inputs/ComplexFieldNote.js +26 -0
  36. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/inputs/ComplexFieldNote.js.map +1 -0
  37. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/inputs/FileUploadField.js +106 -0
  38. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/inputs/FileUploadField.js.map +1 -0
  39. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/inputs/IndexedPairEditor.js +124 -0
  40. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/inputs/IndexedPairEditor.js.map +1 -0
  41. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/inputs/ObjectArrayEditor.js +190 -0
  42. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/inputs/ObjectArrayEditor.js.map +1 -0
  43. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/inputs/PdcFieldNote.js +31 -0
  44. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/inputs/PdcFieldNote.js.map +1 -0
  45. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/inputs/SecureFieldInput.js +59 -0
  46. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/inputs/SecureFieldInput.js.map +1 -0
  47. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/inputs/StringArrayInput.js +80 -0
  48. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/inputs/StringArrayInput.js.map +1 -0
  49. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/renderFieldInput.js +141 -0
  50. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/renderFieldInput.js.map +1 -0
  51. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/resolvePluginName.js +30 -0
  52. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/resolvePluginName.js.map +1 -0
  53. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/styles.js +360 -0
  54. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/styles.js.map +1 -0
  55. package/dist/esm/components/DataLinks/DataLink.js +2 -2
  56. package/dist/esm/components/DataLinks/DataLinks.js +2 -2
  57. package/dist/esm/components/DataSourcePicker/DataSourcePicker.js +7 -7
  58. package/dist/esm/components/DatePicker/styles.js +2 -2
  59. package/dist/esm/components/DatePickerWithInput/styles.js +2 -2
  60. package/dist/esm/components/QueryEditor/EditorField.js +2 -2
  61. package/dist/esm/components/QueryEditor/EditorHeader.js +2 -2
  62. package/dist/esm/components/QueryEditor/EditorRow.js +2 -2
  63. package/dist/esm/components/QueryEditor/EditorSwitch.js +2 -2
  64. package/dist/esm/components/QueryEditor/InlineSelect.js +1 -1
  65. package/dist/esm/components/QueryEditor/InlineSelect.js.map +1 -1
  66. package/dist/esm/components/QueryEditor/InputGroup.js +2 -2
  67. package/dist/esm/components/QueryEditor/QueryEditor.js +3 -1
  68. package/dist/esm/components/QueryEditor/QueryEditor.js.map +1 -1
  69. package/dist/esm/components/QueryEditor/QueryHeader.js +2 -2
  70. package/dist/esm/components/QueryEditor/QueryHeader.js.map +1 -1
  71. package/dist/esm/components/QueryEditor/Space.js +2 -2
  72. package/dist/esm/components/QueryEditor/TableSelector.js +0 -1
  73. package/dist/esm/components/QueryEditor/TableSelector.js.map +1 -1
  74. package/dist/esm/components/QueryEditor/defaults.js.map +1 -1
  75. package/dist/esm/components/QueryEditor/query-editor-raw/QueryEditorRaw.js +10 -2
  76. package/dist/esm/components/QueryEditor/query-editor-raw/QueryEditorRaw.js.map +1 -1
  77. package/dist/esm/components/QueryEditor/query-editor-raw/QueryToolbox.js +6 -1
  78. package/dist/esm/components/QueryEditor/query-editor-raw/QueryToolbox.js.map +1 -1
  79. package/dist/esm/components/QueryEditor/query-editor-raw/RawEditor.js +13 -3
  80. package/dist/esm/components/QueryEditor/query-editor-raw/RawEditor.js.map +1 -1
  81. package/dist/esm/components/QueryEditor/types.js +0 -1
  82. package/dist/esm/components/QueryEditor/types.js.map +1 -1
  83. package/dist/esm/components/QueryEditor/utils/formatSQL.js +15 -4
  84. package/dist/esm/components/QueryEditor/utils/formatSQL.js.map +1 -1
  85. package/dist/esm/components/QueryEditor/visual-query-builder/EditorField.js +2 -2
  86. package/dist/esm/components/QueryEditor/visual-query-builder/EditorRow.js +2 -2
  87. package/dist/esm/components/QueryEditor/visual-query-builder/Preview.js +4 -4
  88. package/dist/esm/components/QueryEditor/visual-query-builder/Preview.js.map +1 -1
  89. package/dist/esm/components/QueryEditor/visual-query-builder/SQLGroupByRow.js +0 -1
  90. package/dist/esm/components/QueryEditor/visual-query-builder/SQLGroupByRow.js.map +1 -1
  91. package/dist/esm/components/QueryEditor/visual-query-builder/SQLOrderByRow.js +0 -1
  92. package/dist/esm/components/QueryEditor/visual-query-builder/SQLOrderByRow.js.map +1 -1
  93. package/dist/esm/components/QueryEditor/visual-query-builder/SQLSelectRow.js +0 -1
  94. package/dist/esm/components/QueryEditor/visual-query-builder/SQLSelectRow.js.map +1 -1
  95. package/dist/esm/components/QueryEditor/visual-query-builder/SQLWhereRow.js +0 -1
  96. package/dist/esm/components/QueryEditor/visual-query-builder/SQLWhereRow.js.map +1 -1
  97. package/dist/esm/components/QueryEditor/visual-query-builder/SelectRow.js +2 -2
  98. package/dist/esm/components/QueryEditor/visual-query-builder/VisualEditor.js +10 -2
  99. package/dist/esm/components/QueryEditor/visual-query-builder/VisualEditor.js.map +1 -1
  100. package/dist/esm/components/SQLEditor/components/SQLEditor.js.map +1 -1
  101. package/dist/esm/components/SQLEditor/standardSql/definition.js +0 -6
  102. package/dist/esm/components/SQLEditor/standardSql/definition.js.map +1 -1
  103. package/dist/esm/components/SQLEditor/standardSql/getStatementPosition.js +2 -1
  104. package/dist/esm/components/SQLEditor/standardSql/getStatementPosition.js.map +1 -1
  105. package/dist/esm/components/SQLEditor/standardSql/statementPositionResolversRegistry.js +2 -1
  106. package/dist/esm/components/SQLEditor/standardSql/statementPositionResolversRegistry.js.map +1 -1
  107. package/dist/esm/components/SQLEditor/types.js +1 -17
  108. package/dist/esm/components/SQLEditor/types.js.map +1 -1
  109. package/dist/esm/components/SQLEditor/utils/LinkedToken.js +1 -1
  110. package/dist/esm/components/SQLEditor/utils/LinkedToken.js.map +1 -1
  111. package/dist/esm/components/SQLEditor/utils/linkedTokenBuilder.js +2 -2
  112. package/dist/esm/components/SQLEditor/utils/tokenType.js +18 -0
  113. package/dist/esm/components/SQLEditor/utils/tokenType.js.map +1 -0
  114. package/dist/esm/components/SQLEditor/utils/tokenUtils.js +1 -1
  115. package/dist/esm/components/VisualQueryBuilder/components/OperationEditorBody.js +1 -1
  116. package/dist/esm/components/VisualQueryBuilder/components/OperationList.js +1 -1
  117. package/dist/esm/components/VisualQueryBuilder/components/OperationParamEditor.js +1 -1
  118. package/dist/esm/components/VisualQueryBuilder/components/OperationsEditorRow.js +1 -1
  119. package/dist/esm/components/VisualQueryBuilder/components/QueryHeaderSwitch.js +1 -1
  120. package/dist/esm/components/VisualQueryBuilder/components/QueryOptionGroup.js +1 -1
  121. package/dist/esm/datasource/SqlDatasource.js +10 -10
  122. package/dist/esm/index.d.ts +694 -39
  123. package/dist/esm/index.js +13 -1
  124. package/dist/esm/index.js.map +1 -1
  125. package/dist/esm/schema/registry/alertmanager.schema.json.js +77 -0
  126. package/dist/esm/schema/registry/alertmanager.schema.json.js.map +1 -0
  127. package/dist/esm/schema/registry/cloudwatch.schema.json.js +384 -0
  128. package/dist/esm/schema/registry/cloudwatch.schema.json.js.map +1 -0
  129. package/dist/esm/schema/registry/elasticsearch.schema.json.js +597 -0
  130. package/dist/esm/schema/registry/elasticsearch.schema.json.js.map +1 -0
  131. package/dist/esm/schema/registry/grafana-adobeanalytics-datasource.schema.json.js +95 -0
  132. package/dist/esm/schema/registry/grafana-adobeanalytics-datasource.schema.json.js.map +1 -0
  133. package/dist/esm/schema/registry/grafana-amazonprometheus-datasource.schema.json.js +166 -0
  134. package/dist/esm/schema/registry/grafana-amazonprometheus-datasource.schema.json.js.map +1 -0
  135. package/dist/esm/schema/registry/grafana-appdynamics-datasource.schema.json.js +145 -0
  136. package/dist/esm/schema/registry/grafana-appdynamics-datasource.schema.json.js.map +1 -0
  137. package/dist/esm/schema/registry/grafana-astradb-datasource.schema.json.js +123 -0
  138. package/dist/esm/schema/registry/grafana-astradb-datasource.schema.json.js.map +1 -0
  139. package/dist/esm/schema/registry/grafana-athena-datasource.schema.json.js +158 -0
  140. package/dist/esm/schema/registry/grafana-athena-datasource.schema.json.js.map +1 -0
  141. package/dist/esm/schema/registry/grafana-atlassianstatuspage-datasource.schema.json.js +43 -0
  142. package/dist/esm/schema/registry/grafana-atlassianstatuspage-datasource.schema.json.js.map +1 -0
  143. package/dist/esm/schema/registry/grafana-azure-data-explorer-datasource.schema.json.js +204 -0
  144. package/dist/esm/schema/registry/grafana-azure-data-explorer-datasource.schema.json.js.map +1 -0
  145. package/dist/esm/schema/registry/grafana-azure-monitor-datasource.schema.json.js +300 -0
  146. package/dist/esm/schema/registry/grafana-azure-monitor-datasource.schema.json.js.map +1 -0
  147. package/dist/esm/schema/registry/grafana-azuredevops-datasource.schema.json.js +101 -0
  148. package/dist/esm/schema/registry/grafana-azuredevops-datasource.schema.json.js.map +1 -0
  149. package/dist/esm/schema/registry/grafana-azureprometheus-datasource.schema.json.js +125 -0
  150. package/dist/esm/schema/registry/grafana-azureprometheus-datasource.schema.json.js.map +1 -0
  151. package/dist/esm/schema/registry/grafana-bigquery-datasource.schema.json.js +508 -0
  152. package/dist/esm/schema/registry/grafana-bigquery-datasource.schema.json.js.map +1 -0
  153. package/dist/esm/schema/registry/grafana-catchpoint-datasource.schema.json.js +42 -0
  154. package/dist/esm/schema/registry/grafana-catchpoint-datasource.schema.json.js.map +1 -0
  155. package/dist/esm/schema/registry/grafana-clickhouse-datasource.schema.json.js +1400 -0
  156. package/dist/esm/schema/registry/grafana-clickhouse-datasource.schema.json.js.map +1 -0
  157. package/dist/esm/schema/registry/grafana-cloudflare-datasource.schema.json.js +42 -0
  158. package/dist/esm/schema/registry/grafana-cloudflare-datasource.schema.json.js.map +1 -0
  159. package/dist/esm/schema/registry/grafana-cockroachdb-datasource.schema.json.js +302 -0
  160. package/dist/esm/schema/registry/grafana-cockroachdb-datasource.schema.json.js.map +1 -0
  161. package/dist/esm/schema/registry/grafana-databricks-datasource.schema.json.js +291 -0
  162. package/dist/esm/schema/registry/grafana-databricks-datasource.schema.json.js.map +1 -0
  163. package/dist/esm/schema/registry/grafana-datadog-datasource.schema.json.js +155 -0
  164. package/dist/esm/schema/registry/grafana-datadog-datasource.schema.json.js.map +1 -0
  165. package/dist/esm/schema/registry/grafana-drone-datasource.schema.json.js +64 -0
  166. package/dist/esm/schema/registry/grafana-drone-datasource.schema.json.js.map +1 -0
  167. package/dist/esm/schema/registry/grafana-dynatrace-datasource.schema.json.js +179 -0
  168. package/dist/esm/schema/registry/grafana-dynatrace-datasource.schema.json.js.map +1 -0
  169. package/dist/esm/schema/registry/grafana-falconlogscale-datasource.schema.json.js +134 -0
  170. package/dist/esm/schema/registry/grafana-falconlogscale-datasource.schema.json.js.map +1 -0
  171. package/dist/esm/schema/registry/grafana-github-datasource.schema.json.js +156 -0
  172. package/dist/esm/schema/registry/grafana-github-datasource.schema.json.js.map +1 -0
  173. package/dist/esm/schema/registry/grafana-gitlab-datasource.schema.json.js +84 -0
  174. package/dist/esm/schema/registry/grafana-gitlab-datasource.schema.json.js.map +1 -0
  175. package/dist/esm/schema/registry/grafana-googlesheets-datasource.schema.json.js +231 -0
  176. package/dist/esm/schema/registry/grafana-googlesheets-datasource.schema.json.js.map +1 -0
  177. package/dist/esm/schema/registry/grafana-honeycomb-datasource.schema.json.js +87 -0
  178. package/dist/esm/schema/registry/grafana-honeycomb-datasource.schema.json.js.map +1 -0
  179. package/dist/esm/schema/registry/grafana-iot-sitewise-datasource.schema.json.js +159 -0
  180. package/dist/esm/schema/registry/grafana-iot-sitewise-datasource.schema.json.js.map +1 -0
  181. package/dist/esm/schema/registry/grafana-jira-datasource.schema.json.js +188 -0
  182. package/dist/esm/schema/registry/grafana-jira-datasource.schema.json.js.map +1 -0
  183. package/dist/esm/schema/registry/grafana-logicmonitor-datasource.schema.json.js +63 -0
  184. package/dist/esm/schema/registry/grafana-logicmonitor-datasource.schema.json.js.map +1 -0
  185. package/dist/esm/schema/registry/grafana-looker-datasource.schema.json.js +82 -0
  186. package/dist/esm/schema/registry/grafana-looker-datasource.schema.json.js.map +1 -0
  187. package/dist/esm/schema/registry/grafana-mongodb-datasource.schema.json.js +278 -0
  188. package/dist/esm/schema/registry/grafana-mongodb-datasource.schema.json.js.map +1 -0
  189. package/dist/esm/schema/registry/grafana-mqtt-datasource.schema.json.js +168 -0
  190. package/dist/esm/schema/registry/grafana-mqtt-datasource.schema.json.js.map +1 -0
  191. package/dist/esm/schema/registry/grafana-netlify-datasource.schema.json.js +42 -0
  192. package/dist/esm/schema/registry/grafana-netlify-datasource.schema.json.js.map +1 -0
  193. package/dist/esm/schema/registry/grafana-newrelic-datasource.schema.json.js +129 -0
  194. package/dist/esm/schema/registry/grafana-newrelic-datasource.schema.json.js.map +1 -0
  195. package/dist/esm/schema/registry/grafana-odbc-datasource.schema.json.js +56 -0
  196. package/dist/esm/schema/registry/grafana-odbc-datasource.schema.json.js.map +1 -0
  197. package/dist/esm/schema/registry/grafana-opensearch-datasource.schema.json.js +212 -0
  198. package/dist/esm/schema/registry/grafana-opensearch-datasource.schema.json.js.map +1 -0
  199. package/dist/esm/schema/registry/grafana-oracle-datasource.schema.json.js +186 -0
  200. package/dist/esm/schema/registry/grafana-oracle-datasource.schema.json.js.map +1 -0
  201. package/dist/esm/schema/registry/grafana-pagerduty-datasource.schema.json.js +85 -0
  202. package/dist/esm/schema/registry/grafana-pagerduty-datasource.schema.json.js.map +1 -0
  203. package/dist/esm/schema/registry/grafana-postgresql-datasource.schema.json.js +411 -0
  204. package/dist/esm/schema/registry/grafana-postgresql-datasource.schema.json.js.map +1 -0
  205. package/dist/esm/schema/registry/grafana-pyroscope-datasource.schema.json.js +41 -0
  206. package/dist/esm/schema/registry/grafana-pyroscope-datasource.schema.json.js.map +1 -0
  207. package/dist/esm/schema/registry/grafana-redshift-datasource.schema.json.js +201 -0
  208. package/dist/esm/schema/registry/grafana-redshift-datasource.schema.json.js.map +1 -0
  209. package/dist/esm/schema/registry/grafana-salesforce-datasource.schema.json.js +248 -0
  210. package/dist/esm/schema/registry/grafana-salesforce-datasource.schema.json.js.map +1 -0
  211. package/dist/esm/schema/registry/grafana-saphana-datasource.schema.json.js +208 -0
  212. package/dist/esm/schema/registry/grafana-saphana-datasource.schema.json.js.map +1 -0
  213. package/dist/esm/schema/registry/grafana-sentry-datasource.schema.json.js +94 -0
  214. package/dist/esm/schema/registry/grafana-sentry-datasource.schema.json.js.map +1 -0
  215. package/dist/esm/schema/registry/grafana-servicenow-datasource.schema.json.js +179 -0
  216. package/dist/esm/schema/registry/grafana-servicenow-datasource.schema.json.js.map +1 -0
  217. package/dist/esm/schema/registry/grafana-snowflake-datasource.schema.json.js +304 -0
  218. package/dist/esm/schema/registry/grafana-snowflake-datasource.schema.json.js.map +1 -0
  219. package/dist/esm/schema/registry/grafana-solarwinds-datasource.schema.json.js +77 -0
  220. package/dist/esm/schema/registry/grafana-solarwinds-datasource.schema.json.js.map +1 -0
  221. package/dist/esm/schema/registry/grafana-splunk-datasource.schema.json.js +690 -0
  222. package/dist/esm/schema/registry/grafana-splunk-datasource.schema.json.js.map +1 -0
  223. package/dist/esm/schema/registry/grafana-splunkobservability-datasource.schema.json.js +90 -0
  224. package/dist/esm/schema/registry/grafana-splunkobservability-datasource.schema.json.js.map +1 -0
  225. package/dist/esm/schema/registry/grafana-strava-datasource.schema.json.js +74 -0
  226. package/dist/esm/schema/registry/grafana-strava-datasource.schema.json.js.map +1 -0
  227. package/dist/esm/schema/registry/grafana-sumologic-datasource.schema.json.js +102 -0
  228. package/dist/esm/schema/registry/grafana-sumologic-datasource.schema.json.js.map +1 -0
  229. package/dist/esm/schema/registry/grafana-surrealdb-datasource.schema.json.js +92 -0
  230. package/dist/esm/schema/registry/grafana-surrealdb-datasource.schema.json.js.map +1 -0
  231. package/dist/esm/schema/registry/grafana-timestream-datasource.schema.json.js +145 -0
  232. package/dist/esm/schema/registry/grafana-timestream-datasource.schema.json.js.map +1 -0
  233. package/dist/esm/schema/registry/grafana-vercel-datasource.schema.json.js +62 -0
  234. package/dist/esm/schema/registry/grafana-vercel-datasource.schema.json.js.map +1 -0
  235. package/dist/esm/schema/registry/grafana-wavefront-datasource.schema.json.js +80 -0
  236. package/dist/esm/schema/registry/grafana-wavefront-datasource.schema.json.js.map +1 -0
  237. package/dist/esm/schema/registry/grafana-x-ray-datasource.schema.json.js +112 -0
  238. package/dist/esm/schema/registry/grafana-x-ray-datasource.schema.json.js.map +1 -0
  239. package/dist/esm/schema/registry/grafana-yugabyte-datasource.schema.json.js +114 -0
  240. package/dist/esm/schema/registry/grafana-yugabyte-datasource.schema.json.js.map +1 -0
  241. package/dist/esm/schema/registry/grafana-zendesk-datasource.schema.json.js +76 -0
  242. package/dist/esm/schema/registry/grafana-zendesk-datasource.schema.json.js.map +1 -0
  243. package/dist/esm/schema/registry/graphite.schema.json.js +104 -0
  244. package/dist/esm/schema/registry/graphite.schema.json.js.map +1 -0
  245. package/dist/esm/schema/registry/index.js +157 -0
  246. package/dist/esm/schema/registry/index.js.map +1 -0
  247. package/dist/esm/schema/registry/influxdb.schema.json.js +717 -0
  248. package/dist/esm/schema/registry/influxdb.schema.json.js.map +1 -0
  249. package/dist/esm/schema/registry/jaeger.schema.json.js +59 -0
  250. package/dist/esm/schema/registry/jaeger.schema.json.js.map +1 -0
  251. package/dist/esm/schema/registry/loki.schema.json.js +545 -0
  252. package/dist/esm/schema/registry/loki.schema.json.js.map +1 -0
  253. package/dist/esm/schema/registry/marcusolsson-csv-datasource.schema.json.js +45 -0
  254. package/dist/esm/schema/registry/marcusolsson-csv-datasource.schema.json.js.map +1 -0
  255. package/dist/esm/schema/registry/marcusolsson-json-datasource.schema.json.js +36 -0
  256. package/dist/esm/schema/registry/marcusolsson-json-datasource.schema.json.js.map +1 -0
  257. package/dist/esm/schema/registry/mssql.schema.json.js +292 -0
  258. package/dist/esm/schema/registry/mssql.schema.json.js.map +1 -0
  259. package/dist/esm/schema/registry/mysql.schema.json.js +304 -0
  260. package/dist/esm/schema/registry/mysql.schema.json.js.map +1 -0
  261. package/dist/esm/schema/registry/opentsdb.schema.json.js +113 -0
  262. package/dist/esm/schema/registry/opentsdb.schema.json.js.map +1 -0
  263. package/dist/esm/schema/registry/prometheus.schema.json.js +783 -0
  264. package/dist/esm/schema/registry/prometheus.schema.json.js.map +1 -0
  265. package/dist/esm/schema/registry/stackdriver.schema.json.js +224 -0
  266. package/dist/esm/schema/registry/stackdriver.schema.json.js.map +1 -0
  267. package/dist/esm/schema/registry/tempo.schema.json.js +664 -0
  268. package/dist/esm/schema/registry/tempo.schema.json.js.map +1 -0
  269. package/dist/esm/schema/registry/yesoreyeram-infinity-datasource.schema.json.js +1073 -0
  270. package/dist/esm/schema/registry/yesoreyeram-infinity-datasource.schema.json.js.map +1 -0
  271. package/dist/esm/schema/registry/zipkin.schema.json.js +40 -0
  272. package/dist/esm/schema/registry/zipkin.schema.json.js.map +1 -0
  273. package/dist/esm/schema/utils/dsconfig.js +97 -0
  274. package/dist/esm/schema/utils/dsconfig.js.map +1 -0
  275. package/dist/esm/schema/utils/llm.js +54 -0
  276. package/dist/esm/schema/utils/llm.js.map +1 -0
  277. package/dist/esm/schema/utils/provisioning.js +434 -0
  278. package/dist/esm/schema/utils/provisioning.js.map +1 -0
  279. package/dist/esm/schema/utils/useDatasourceSchema.js +16 -0
  280. package/dist/esm/schema/utils/useDatasourceSchema.js.map +1 -0
  281. package/dist/esm/schemas.d.ts +448 -0
  282. package/dist/esm/schemas.js +6 -0
  283. package/dist/esm/schemas.js.map +1 -0
  284. package/dist/esm/test-utils.d.ts +23 -23
  285. package/package.json +52 -16
@@ -11,22 +11,25 @@ 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 useDatasourceSchema = require('./useDatasourceSchema-CxPGD2-b.js');
21
+ var reactHookForm = require('react-hook-form');
22
+ require('@marcbachmann/cel-js');
20
23
  var dnd = require('@hello-pangea/dnd');
21
24
  var reactPopperTooltip = require('react-popper-tooltip');
22
25
  var Prism = require('prismjs');
26
+ require('js-yaml');
23
27
 
24
28
  function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
25
29
 
26
30
  var React__default = /*#__PURE__*/_interopDefaultCompat(React);
27
31
  var Calendar__default = /*#__PURE__*/_interopDefaultCompat(Calendar);
28
32
  var AutoSizer__default = /*#__PURE__*/_interopDefaultCompat(AutoSizer);
29
- var sqlFormatter__default = /*#__PURE__*/_interopDefaultCompat(sqlFormatter);
30
33
  var Prism__default = /*#__PURE__*/_interopDefaultCompat(Prism);
31
34
 
32
35
  const QueryEditorRow = (props) => {
@@ -76,7 +79,7 @@ function Segment(props) {
76
79
  );
77
80
  }
78
81
 
79
- const getStyles$r = (theme) => {
82
+ const getStyles$x = (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$x(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$w() {
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$w();
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$v = 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$v();
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$u = (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$u(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$t);
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$t = () => ({
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$s);
5600
5584
  return /* @__PURE__ */ React__default.default.createElement("div", { className: styles.root }, children);
5601
5585
  };
5602
- const getStyles$m = (theme) => ({
5586
+ const getStyles$s = (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$r, 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$r = (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$q);
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$q = (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$p();
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$p = () => {
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$o, 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$o = (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,14 +6135,33 @@ 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 }) {
6141
- const queryRef = React.useRef(query);
6155
+ function QueryEditorRaw({
6156
+ children,
6157
+ onChange,
6158
+ query,
6159
+ width,
6160
+ height,
6161
+ completionProvider,
6162
+ language = "sql"
6163
+ }) {
6164
+ const queryRef = React.useRef(query);
6142
6165
  React.useEffect(() => {
6143
6166
  queryRef.current = query;
6144
6167
  }, [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$n);
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$n(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$m);
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$m(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$l);
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$l = () => {
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$k);
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$k = (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$j(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$j = 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$i);
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$i = (theme) => {
7424
7471
  return {
7425
7472
  container: css.css({
7426
7473
  color: theme.colors.text.secondary,
@@ -8389,6 +8436,2545 @@ const AdvancedHttpSettings = ({
8389
8436
  ));
8390
8437
  };
8391
8438
 
8439
+ const SECURE_FIELD_CONFIGURED = "__CONFIGURED__";
8440
+ function resolveSecureKeyTemplate(template, item, index) {
8441
+ return template.replace(/\{index1\}/g, String(index + 1)).replace(/\{index\}/g, String(index)).replace(/\{item\.(\w+)\}/g, (_, key) => {
8442
+ var _a;
8443
+ return String((_a = item[key]) != null ? _a : "");
8444
+ });
8445
+ }
8446
+ function evaluateItemCondition(condition, item) {
8447
+ const trimmed = condition.trim();
8448
+ if (trimmed === "true") {
8449
+ return true;
8450
+ }
8451
+ const match = trimmed.match(/^item\.(\w+)\s*==\s*(.+)$/);
8452
+ if (!match) {
8453
+ return false;
8454
+ }
8455
+ const [, key, rawValue] = match;
8456
+ const actualValue = item[key];
8457
+ const expected = rawValue.trim();
8458
+ if (expected === "true") {
8459
+ return actualValue === true;
8460
+ }
8461
+ if (expected === "false") {
8462
+ return actualValue === false;
8463
+ }
8464
+ const unquoted = expected.replace(/^['"]|['"]$/g, "");
8465
+ return String(actualValue) === unquoted;
8466
+ }
8467
+ function findActiveSecureOverride(itemFields, item, index) {
8468
+ for (const field of itemFields) {
8469
+ if (!field.overrides) {
8470
+ continue;
8471
+ }
8472
+ for (const override of field.overrides) {
8473
+ if (!override.secureKey) {
8474
+ continue;
8475
+ }
8476
+ if (evaluateItemCondition(override.when, item)) {
8477
+ return {
8478
+ fieldKey: field.key,
8479
+ resolvedKey: resolveSecureKeyTemplate(override.secureKey, item, index)
8480
+ };
8481
+ }
8482
+ }
8483
+ }
8484
+ return null;
8485
+ }
8486
+ function patternToRegex(pattern) {
8487
+ const escaped = pattern.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
8488
+ return new RegExp("^" + escaped.replace("\\{index\\}", "(\\d+)") + "$");
8489
+ }
8490
+ function findIndicesForPattern(record, pattern) {
8491
+ const re = patternToRegex(pattern);
8492
+ const indices = [];
8493
+ for (const key of Object.keys(record)) {
8494
+ const m = key.match(re);
8495
+ if (m) {
8496
+ const n = Number(m[1]);
8497
+ if (!Number.isNaN(n)) {
8498
+ indices.push(n);
8499
+ }
8500
+ }
8501
+ }
8502
+ return indices.sort((a, b) => a - b);
8503
+ }
8504
+ function expandIndexedPair(field, ds) {
8505
+ var _a, _b, _c;
8506
+ const storage = field.storage;
8507
+ if ((storage == null ? void 0 : storage.type) !== "indexedPair" || !storage.key || !storage.value) {
8508
+ return [];
8509
+ }
8510
+ const source = storage.key.target === "jsonData" ? (_a = ds.jsonData) != null ? _a : {} : ds;
8511
+ const indices = findIndicesForPattern(source, storage.key.pattern);
8512
+ const items = [];
8513
+ for (const i of indices) {
8514
+ const nameKey = storage.key.pattern.replace("{index}", String(i));
8515
+ const valueKey = storage.value.pattern.replace("{index}", String(i));
8516
+ const nameVal = source[nameKey];
8517
+ if (nameVal === void 0 || nameVal === null) {
8518
+ continue;
8519
+ }
8520
+ const hasValue = storage.value.target === "secureJsonData" ? !!((_b = ds.secureJsonFields) == null ? void 0 : _b[valueKey]) : !!((_c = ds.jsonData) == null ? void 0 : _c[valueKey]);
8521
+ items.push({
8522
+ index: i,
8523
+ name: String(nameVal),
8524
+ value: hasValue ? SECURE_FIELD_CONFIGURED : ""
8525
+ });
8526
+ }
8527
+ return items;
8528
+ }
8529
+ function flattenIndexedPair(field, items, jsonData, secureJsonData, secureJsonFields) {
8530
+ var _a;
8531
+ const storage = field.storage;
8532
+ if ((storage == null ? void 0 : storage.type) !== "indexedPair" || !storage.key || !storage.value) {
8533
+ return;
8534
+ }
8535
+ const existingIndices = new Set(
8536
+ storage.key.target === "jsonData" ? findIndicesForPattern(jsonData, storage.key.pattern) : []
8537
+ );
8538
+ const usedIndices = /* @__PURE__ */ new Set();
8539
+ const startIdx = (_a = storage.startIndex) != null ? _a : 1;
8540
+ let nextIndex = existingIndices.size > 0 ? Math.max(...existingIndices) + 1 : startIdx;
8541
+ for (const item of items) {
8542
+ let idx = item.index;
8543
+ if (idx === 0) {
8544
+ idx = nextIndex++;
8545
+ }
8546
+ usedIndices.add(idx);
8547
+ const nameKey = storage.key.pattern.replace("{index}", String(idx));
8548
+ const valueKey = storage.value.pattern.replace("{index}", String(idx));
8549
+ if (storage.key.target === "jsonData") {
8550
+ jsonData[nameKey] = item.name;
8551
+ }
8552
+ if (storage.value.target === "secureJsonData") {
8553
+ if (item.value === SECURE_FIELD_CONFIGURED) {
8554
+ secureJsonFields[valueKey] = true;
8555
+ } else if (item.value) {
8556
+ secureJsonData[valueKey] = item.value;
8557
+ secureJsonFields[valueKey] = false;
8558
+ }
8559
+ } else if (storage.value.target === "jsonData") {
8560
+ jsonData[valueKey] = item.value;
8561
+ }
8562
+ }
8563
+ for (const idx of existingIndices) {
8564
+ if (usedIndices.has(idx)) {
8565
+ continue;
8566
+ }
8567
+ const nameKey = storage.key.pattern.replace("{index}", String(idx));
8568
+ const valueKey = storage.value.pattern.replace("{index}", String(idx));
8569
+ if (storage.key.target === "jsonData") {
8570
+ delete jsonData[nameKey];
8571
+ }
8572
+ if (storage.value.target === "secureJsonData") {
8573
+ delete secureJsonFields[valueKey];
8574
+ delete secureJsonData[valueKey];
8575
+ } else if (storage.value.target === "jsonData") {
8576
+ delete jsonData[valueKey];
8577
+ }
8578
+ }
8579
+ }
8580
+ function resolveRawPath(ref, ds) {
8581
+ var _a;
8582
+ const trimmed = ref.trim();
8583
+ if (trimmed.startsWith("jsonData.")) {
8584
+ return (_a = ds.jsonData) == null ? void 0 : _a[trimmed.slice(9)];
8585
+ }
8586
+ if (trimmed.startsWith("root.")) {
8587
+ return ds[trimmed.slice(5)];
8588
+ }
8589
+ return void 0;
8590
+ }
8591
+ async function fetchExistingValues(dsUid, fields) {
8592
+ var _a, _b, _c, _d, _e, _f;
8593
+ try {
8594
+ const ds = await runtime.getBackendSrv().get(`/api/datasources/uid/${dsUid}`, void 0, void 0, {
8595
+ showErrorAlert: false
8596
+ });
8597
+ const values = {};
8598
+ for (const field of fields) {
8599
+ if (((_a = field.storage) == null ? void 0 : _a.type) === "indexedPair") {
8600
+ values[field.key] = expandIndexedPair(field, ds);
8601
+ continue;
8602
+ }
8603
+ const fk = useDatasourceSchema.formKey(field);
8604
+ switch (field.target) {
8605
+ case "root":
8606
+ if (ds[field.key] !== void 0) {
8607
+ values[fk] = ds[field.key];
8608
+ }
8609
+ break;
8610
+ case "jsonData":
8611
+ if (field.section) {
8612
+ const sectionObj = (_b = ds.jsonData) == null ? void 0 : _b[field.section];
8613
+ if ((sectionObj == null ? void 0 : sectionObj[field.key]) !== void 0) {
8614
+ values[fk] = sectionObj[field.key];
8615
+ }
8616
+ } else if (((_c = ds.jsonData) == null ? void 0 : _c[field.key]) !== void 0) {
8617
+ values[fk] = ds.jsonData[field.key];
8618
+ }
8619
+ break;
8620
+ case "secureJsonData":
8621
+ if ((_d = ds.secureJsonFields) == null ? void 0 : _d[field.key]) {
8622
+ values[fk] = SECURE_FIELD_CONFIGURED;
8623
+ }
8624
+ break;
8625
+ }
8626
+ if (values[fk] === void 0 && ((_e = field.storage) == null ? void 0 : _e.type) === "computed" && field.storage.read) {
8627
+ const fallback = resolveRawPath(field.storage.read, ds);
8628
+ if (fallback !== void 0) {
8629
+ values[fk] = fallback;
8630
+ }
8631
+ }
8632
+ }
8633
+ for (const field of fields) {
8634
+ if (field.valueType !== "array" || !((_f = field.item) == null ? void 0 : _f.fields)) {
8635
+ continue;
8636
+ }
8637
+ const itemFields = field.item.fields;
8638
+ const hasSecureOverride = itemFields.some((f) => {
8639
+ var _a2;
8640
+ return (_a2 = f.overrides) == null ? void 0 : _a2.some((o) => o.secureKey);
8641
+ });
8642
+ if (!hasSecureOverride) {
8643
+ continue;
8644
+ }
8645
+ const fk = useDatasourceSchema.formKey(field);
8646
+ const arr = values[fk];
8647
+ if (!Array.isArray(arr)) {
8648
+ continue;
8649
+ }
8650
+ values[fk] = arr.map((item, idx) => {
8651
+ var _a2;
8652
+ const match = findActiveSecureOverride(itemFields, item, idx);
8653
+ if (match && ((_a2 = ds.secureJsonFields) == null ? void 0 : _a2[match.resolvedKey])) {
8654
+ return { ...item, [match.fieldKey]: SECURE_FIELD_CONFIGURED };
8655
+ }
8656
+ return item;
8657
+ });
8658
+ }
8659
+ return { values, readOnly: !!ds.readOnly };
8660
+ } catch (err) {
8661
+ const message = err instanceof Error ? err.message : "Failed to load datasource configuration";
8662
+ return { values: {}, readOnly: false, error: message };
8663
+ }
8664
+ }
8665
+ function buildDatasourceConfigPayload(data, fields, existing, isFieldVisible) {
8666
+ var _a, _b, _c, _d, _e, _f, _g, _h;
8667
+ const rootFields = {};
8668
+ const jsonData = { ...(_a = existing.jsonData) != null ? _a : {} };
8669
+ const secureJsonData = {};
8670
+ const secureJsonFields = { ...(_b = existing.secureJsonFields) != null ? _b : {} };
8671
+ for (const field of fields) {
8672
+ if (((_c = field.storage) == null ? void 0 : _c.type) === "indexedPair") {
8673
+ const items = Array.isArray(data[field.key]) ? data[field.key] : [];
8674
+ flattenIndexedPair(field, items, jsonData, secureJsonData, secureJsonFields);
8675
+ continue;
8676
+ }
8677
+ const isManagedByEffect = (_d = field.tags) == null ? void 0 : _d.some((t) => t.startsWith("managed-by:"));
8678
+ if (!isManagedByEffect && !isFieldVisible(field)) {
8679
+ continue;
8680
+ }
8681
+ const fk = useDatasourceSchema.formKey(field);
8682
+ const value = data[fk];
8683
+ if (field.target === "secureJsonData") {
8684
+ if (value === SECURE_FIELD_CONFIGURED) {
8685
+ secureJsonFields[field.key] = true;
8686
+ continue;
8687
+ }
8688
+ if (value && value !== "") {
8689
+ secureJsonData[field.key] = String(value);
8690
+ secureJsonFields[field.key] = false;
8691
+ } else {
8692
+ secureJsonFields[field.key] = false;
8693
+ }
8694
+ continue;
8695
+ }
8696
+ if (value === void 0 || value === "") {
8697
+ continue;
8698
+ }
8699
+ switch (field.target) {
8700
+ case "root":
8701
+ rootFields[field.key] = value;
8702
+ break;
8703
+ case "jsonData":
8704
+ if (field.section) {
8705
+ if (!jsonData[field.section] || typeof jsonData[field.section] !== "object") {
8706
+ jsonData[field.section] = {};
8707
+ }
8708
+ jsonData[field.section][field.key] = value;
8709
+ } else {
8710
+ jsonData[field.key] = value;
8711
+ }
8712
+ break;
8713
+ }
8714
+ }
8715
+ for (const field of fields) {
8716
+ if (field.valueType !== "array" || !((_e = field.item) == null ? void 0 : _e.fields) || field.target !== "jsonData") {
8717
+ continue;
8718
+ }
8719
+ const itemFields = field.item.fields;
8720
+ const hasSecureOverride = itemFields.some((f) => {
8721
+ var _a2;
8722
+ return (_a2 = f.overrides) == null ? void 0 : _a2.some((o) => o.secureKey);
8723
+ });
8724
+ if (!hasSecureOverride) {
8725
+ continue;
8726
+ }
8727
+ const arr = field.section ? (_f = jsonData[field.section]) == null ? void 0 : _f[field.key] : jsonData[field.key];
8728
+ if (!Array.isArray(arr)) {
8729
+ continue;
8730
+ }
8731
+ const secureKeyOverrides = [];
8732
+ for (const f of itemFields) {
8733
+ for (const o of (_g = f.overrides) != null ? _g : []) {
8734
+ if (o.secureKey) {
8735
+ secureKeyOverrides.push({ fieldKey: f.key, override: o });
8736
+ }
8737
+ }
8738
+ }
8739
+ const activeSecureKeys = /* @__PURE__ */ new Set();
8740
+ for (let i = 0; i < arr.length; i++) {
8741
+ const item = arr[i];
8742
+ const match = findActiveSecureOverride(itemFields, item, i);
8743
+ if (!match) {
8744
+ continue;
8745
+ }
8746
+ const resolvedKey = match.resolvedKey;
8747
+ activeSecureKeys.add(resolvedKey);
8748
+ const itemValue = item[match.fieldKey];
8749
+ if (itemValue === SECURE_FIELD_CONFIGURED) {
8750
+ secureJsonFields[resolvedKey] = true;
8751
+ } else if (itemValue && itemValue !== "") {
8752
+ secureJsonData[resolvedKey] = String(itemValue);
8753
+ secureJsonFields[resolvedKey] = false;
8754
+ item[match.fieldKey] = "";
8755
+ }
8756
+ }
8757
+ const existingSecureFields = (_h = existing.secureJsonFields) != null ? _h : {};
8758
+ for (const existingKey of Object.keys(existingSecureFields)) {
8759
+ const couldBeFromThisField = secureKeyOverrides.some((sko) => {
8760
+ const staticPrefix = sko.override.secureKey.split("{")[0];
8761
+ return staticPrefix && existingKey.startsWith(staticPrefix);
8762
+ });
8763
+ if (couldBeFromThisField && !activeSecureKeys.has(existingKey)) {
8764
+ secureJsonFields[existingKey] = false;
8765
+ secureJsonData[existingKey] = "";
8766
+ }
8767
+ }
8768
+ }
8769
+ return { rootFields, jsonData, secureJsonData, secureJsonFields };
8770
+ }
8771
+ async function submitDatasourceConfig(dsUid, data, fields, isFieldVisible) {
8772
+ const existing = await runtime.getBackendSrv().get(`/api/datasources/uid/${dsUid}`);
8773
+ const { rootFields, jsonData, secureJsonData, secureJsonFields } = buildDatasourceConfigPayload(
8774
+ data,
8775
+ fields,
8776
+ existing,
8777
+ isFieldVisible
8778
+ );
8779
+ await runtime.getBackendSrv().put(`/api/datasources/uid/${dsUid}`, {
8780
+ ...existing,
8781
+ ...rootFields,
8782
+ jsonData,
8783
+ secureJsonData,
8784
+ secureJsonFields
8785
+ });
8786
+ }
8787
+
8788
+ function evaluateEffectCondition(when, fieldValue) {
8789
+ var _a, _b;
8790
+ const m = when.match(/^value\s*(==|!=)\s*(?:'([^']*)'|"([^"]*)"|(.+))$/);
8791
+ if (!m) {
8792
+ return false;
8793
+ }
8794
+ const op = m[1];
8795
+ let target = (_b = (_a = m[2]) != null ? _a : m[3]) != null ? _b : m[4];
8796
+ if (target === "true") {
8797
+ target = true;
8798
+ } else if (target === "false") {
8799
+ target = false;
8800
+ } else if (typeof target === "string" && /^-?\d+(\.\d+)?$/.test(target)) {
8801
+ target = Number(target);
8802
+ }
8803
+ const eq = String(fieldValue) === String(target);
8804
+ return op === "==" ? eq : !eq;
8805
+ }
8806
+ function isFieldRequired(field, watchedValues, fieldById, celContext) {
8807
+ if (field.required) {
8808
+ return true;
8809
+ }
8810
+ if (field.requiredWhen) {
8811
+ if (celContext) {
8812
+ return useDatasourceSchema.evaluateCelExpression(field.requiredWhen, celContext);
8813
+ }
8814
+ const parsed = useDatasourceSchema.parseDependsOn(field.requiredWhen);
8815
+ if (parsed) {
8816
+ const depField = fieldById.get(parsed.field);
8817
+ const depKey = depField ? useDatasourceSchema.formKey(depField) : parsed.field;
8818
+ return useDatasourceSchema.evaluateDependsOn(parsed, useDatasourceSchema.getWatchedValue(watchedValues, depKey));
8819
+ }
8820
+ }
8821
+ return false;
8822
+ }
8823
+ function buildValidationRules(field, required) {
8824
+ var _a, _b, _c, _d, _e, _f, _g, _h;
8825
+ const rules = {};
8826
+ const label = (_a = field.label) != null ? _a : field.key;
8827
+ if (required) {
8828
+ if (field.target === "secureJsonData") {
8829
+ rules.validate = (value) => {
8830
+ if (value === SECURE_FIELD_CONFIGURED) {
8831
+ return true;
8832
+ }
8833
+ if (!value || value === "") {
8834
+ return `${label} is required`;
8835
+ }
8836
+ return true;
8837
+ };
8838
+ } else {
8839
+ rules.required = `${label} is required`;
8840
+ }
8841
+ }
8842
+ if (field.valueType === "array" && ((_b = field.item) == null ? void 0 : _b.valueType) === "object" && ((_c = field.item.fields) == null ? void 0 : _c.length)) {
8843
+ const requiredItemFields = field.item.fields.filter((f) => f.required);
8844
+ if (requiredItemFields.length > 0) {
8845
+ const existingValidate = rules.validate;
8846
+ rules.validate = (value) => {
8847
+ var _a2;
8848
+ if (existingValidate) {
8849
+ const r = existingValidate(value);
8850
+ if (r !== true) {
8851
+ return r;
8852
+ }
8853
+ }
8854
+ if (!Array.isArray(value)) {
8855
+ return true;
8856
+ }
8857
+ const itemErrors = {};
8858
+ for (let i = 0; i < value.length; i++) {
8859
+ const item = value[i];
8860
+ const missing = [];
8861
+ for (const rf of requiredItemFields) {
8862
+ const v = item[rf.key];
8863
+ if (v === void 0 || v === null || v === "") {
8864
+ missing.push((_a2 = rf.label) != null ? _a2 : rf.key);
8865
+ }
8866
+ }
8867
+ if (missing.length > 0) {
8868
+ itemErrors[i] = `${missing.join(", ")} required`;
8869
+ }
8870
+ }
8871
+ if (Object.keys(itemErrors).length === 0) {
8872
+ return true;
8873
+ }
8874
+ return `__ITEM_ERRORS__${JSON.stringify(itemErrors)}`;
8875
+ };
8876
+ }
8877
+ }
8878
+ if (field.validations) {
8879
+ for (const v of field.validations) {
8880
+ switch (v.type) {
8881
+ case "pattern":
8882
+ rules.pattern = {
8883
+ value: new RegExp(v.pattern),
8884
+ message: (_d = v.message) != null ? _d : `Invalid ${label}`
8885
+ };
8886
+ break;
8887
+ case "range":
8888
+ if (v.min !== void 0) {
8889
+ rules.min = { value: v.min, message: (_e = v.message) != null ? _e : `Minimum value is ${v.min}` };
8890
+ }
8891
+ if (v.max !== void 0) {
8892
+ rules.max = { value: v.max, message: (_f = v.message) != null ? _f : `Maximum value is ${v.max}` };
8893
+ }
8894
+ break;
8895
+ case "length":
8896
+ if (v.min !== void 0) {
8897
+ rules.minLength = { value: v.min, message: (_g = v.message) != null ? _g : `Minimum length is ${v.min}` };
8898
+ }
8899
+ if (v.max !== void 0) {
8900
+ rules.maxLength = { value: v.max, message: (_h = v.message) != null ? _h : `Maximum length is ${v.max}` };
8901
+ }
8902
+ break;
8903
+ }
8904
+ }
8905
+ }
8906
+ return rules;
8907
+ }
8908
+ const ITEM_ERRORS_PREFIX = "__ITEM_ERRORS__";
8909
+ function parseItemErrors(errorMessage) {
8910
+ if (!errorMessage || !errorMessage.startsWith(ITEM_ERRORS_PREFIX)) {
8911
+ return null;
8912
+ }
8913
+ try {
8914
+ return JSON.parse(errorMessage.slice(ITEM_ERRORS_PREFIX.length));
8915
+ } catch (e) {
8916
+ return null;
8917
+ }
8918
+ }
8919
+
8920
+ const PdcFieldNote = (props) => {
8921
+ const { enabled, description, configUrl } = props;
8922
+ const styles = ui.useStyles2(getStyles$h);
8923
+ 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"));
8924
+ };
8925
+ const getStyles$h = (theme) => ({
8926
+ wrapper: css.css({
8927
+ display: "flex",
8928
+ alignItems: "center",
8929
+ justifyContent: "space-between",
8930
+ gap: theme.spacing(1),
8931
+ padding: `${theme.spacing(0.5)} ${theme.spacing(0.75)}`,
8932
+ fontSize: theme.typography.bodySmall.fontSize,
8933
+ color: theme.colors.text.secondary,
8934
+ backgroundColor: theme.colors.background.secondary,
8935
+ borderRadius: theme.shape.radius.default,
8936
+ border: `1px solid ${theme.colors.border.weak}`
8937
+ }),
8938
+ note: css.css({
8939
+ display: "inline-flex",
8940
+ alignItems: "center",
8941
+ gap: theme.spacing(0.5)
8942
+ })
8943
+ });
8944
+
8945
+ function SecureFieldInput(props) {
8946
+ var _a;
8947
+ const { formField, placeholder, disabled } = props;
8948
+ const isConfigured = formField.value === SECURE_FIELD_CONFIGURED;
8949
+ const [revealed, setRevealed] = React.useState(false);
8950
+ const styles = ui.useStyles2(getSecureFieldStyles);
8951
+ if (isConfigured) {
8952
+ 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" }), "Configured"), !disabled && /* @__PURE__ */ React__default.default.createElement(ui.Button, { variant: "secondary", fill: "text", size: "sm", onClick: () => formField.onChange(""), type: "button" }, "Reset"));
8953
+ }
8954
+ return /* @__PURE__ */ React__default.default.createElement(
8955
+ ui.Input,
8956
+ {
8957
+ ...formField,
8958
+ value: String((_a = formField.value) != null ? _a : ""),
8959
+ type: revealed ? "text" : "password",
8960
+ placeholder,
8961
+ disabled,
8962
+ suffix: /* @__PURE__ */ React__default.default.createElement(
8963
+ ui.Button,
8964
+ {
8965
+ variant: "secondary",
8966
+ fill: "text",
8967
+ size: "sm",
8968
+ icon: revealed ? "eye-slash" : "eye",
8969
+ "aria-label": revealed ? "Hide" : "Reveal",
8970
+ onClick: () => setRevealed((r) => !r),
8971
+ type: "button"
8972
+ }
8973
+ )
8974
+ }
8975
+ );
8976
+ }
8977
+ const getSecureFieldStyles = (theme) => ({
8978
+ configuredRow: css.css({
8979
+ display: "flex",
8980
+ alignItems: "center",
8981
+ gap: theme.spacing(1),
8982
+ whiteSpace: "nowrap"
8983
+ }),
8984
+ configuredBadge: css.css({
8985
+ display: "inline-flex",
8986
+ alignItems: "center",
8987
+ gap: theme.spacing(0.5),
8988
+ padding: `${theme.spacing(0.25)} ${theme.spacing(0.75)}`,
8989
+ borderRadius: theme.shape.radius.pill,
8990
+ backgroundColor: theme.colors.success.transparent,
8991
+ color: theme.colors.success.text,
8992
+ fontSize: theme.typography.bodySmall.fontSize,
8993
+ whiteSpace: "nowrap"
8994
+ })
8995
+ });
8996
+
8997
+ const ComplexFieldNote = (props) => {
8998
+ const { count, label } = props;
8999
+ const styles = ui.useStyles2(getStyles$g);
9000
+ 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."));
9001
+ };
9002
+ const getStyles$g = (theme) => ({
9003
+ note: css.css({
9004
+ display: "inline-flex",
9005
+ alignItems: "center",
9006
+ gap: theme.spacing(0.5),
9007
+ padding: `${theme.spacing(0.5)} ${theme.spacing(0.75)}`,
9008
+ fontSize: theme.typography.bodySmall.fontSize,
9009
+ color: theme.colors.text.secondary,
9010
+ backgroundColor: theme.colors.background.secondary,
9011
+ borderRadius: theme.shape.radius.default,
9012
+ border: `1px solid ${theme.colors.border.weak}`
9013
+ })
9014
+ });
9015
+
9016
+ function FileUploadField(props) {
9017
+ var _a, _b, _c, _d, _e, _f, _g;
9018
+ const { field, formField, disabled, setValue } = props;
9019
+ const [mode, setModeLocal] = React.useState("upload");
9020
+ const [error, setError] = React.useState(null);
9021
+ const theme = ui.useTheme2();
9022
+ const mapping = (_a = field.ui) == null ? void 0 : _a.fileMapping;
9023
+ const accept = (_c = (_b = field.ui) == null ? void 0 : _b.accept) != null ? _c : [".json"];
9024
+ const setMode = React.useCallback(
9025
+ (next) => {
9026
+ setModeLocal(next);
9027
+ formField.onChange(next);
9028
+ },
9029
+ [formField]
9030
+ );
9031
+ const processJson = React.useCallback(
9032
+ (text) => {
9033
+ const fileMapping = mapping != null ? mapping : {};
9034
+ try {
9035
+ const parsed = JSON.parse(text);
9036
+ if (typeof parsed !== "object" || parsed === null) {
9037
+ setError("Invalid JSON object");
9038
+ return;
9039
+ }
9040
+ const requiredKeys = Object.keys(fileMapping);
9041
+ const missingKeys = requiredKeys.filter((k) => parsed[k] === void 0);
9042
+ if (missingKeys.length > 0) {
9043
+ setError(`Missing keys: ${missingKeys.join(", ")}`);
9044
+ return;
9045
+ }
9046
+ for (const [jsonKey, targetFieldId] of Object.entries(fileMapping)) {
9047
+ if (parsed[jsonKey] !== void 0) {
9048
+ const parts = targetFieldId.split(".");
9049
+ const fk = parts.length === 2 ? parts[1] : targetFieldId;
9050
+ setValue(fk, parsed[jsonKey]);
9051
+ }
9052
+ }
9053
+ setError(null);
9054
+ setModeLocal("manual");
9055
+ formField.onChange("manual");
9056
+ } catch (e) {
9057
+ setError("Invalid JSON");
9058
+ }
9059
+ },
9060
+ [mapping, setValue, formField]
9061
+ );
9062
+ const styles = getStyles$f(theme);
9063
+ if (mode === "manual") {
9064
+ return /* @__PURE__ */ React__default.default.createElement("div", { className: styles.buttonRow }, /* @__PURE__ */ React__default.default.createElement(ui.Button, { type: "button", fill: "outline", size: "sm", onClick: () => setMode("paste"), disabled }, "Paste JWT Token"), /* @__PURE__ */ React__default.default.createElement("span", { className: styles.separator }, "or"), /* @__PURE__ */ React__default.default.createElement(ui.Button, { type: "button", fill: "outline", size: "sm", onClick: () => setMode("upload"), disabled }, "Upload JWT Token"));
9065
+ }
9066
+ if (mode === "paste") {
9067
+ return /* @__PURE__ */ React__default.default.createElement("div", null, /* @__PURE__ */ React__default.default.createElement(
9068
+ ui.TextArea,
9069
+ {
9070
+ placeholder: (_e = (_d = field.ui) == null ? void 0 : _d.placeholder) != null ? _e : "Paste Google JWT token here",
9071
+ rows: (_g = (_f = field.ui) == null ? void 0 : _f.rows) != null ? _g : 10,
9072
+ onBlur: (e) => {
9073
+ const val = e.currentTarget.value;
9074
+ if (val.trim()) {
9075
+ processJson(val);
9076
+ }
9077
+ },
9078
+ disabled
9079
+ }
9080
+ ), /* @__PURE__ */ React__default.default.createElement("div", { className: styles.buttonRow }, /* @__PURE__ */ React__default.default.createElement(ui.Button, { type: "button", fill: "outline", size: "sm", onClick: () => setMode("upload"), disabled }, "Upload JWT Token"), /* @__PURE__ */ React__default.default.createElement("span", { className: styles.separator }, "or"), /* @__PURE__ */ React__default.default.createElement(ui.Button, { type: "button", fill: "outline", size: "sm", onClick: () => setMode("manual"), disabled }, "Fill In JWT Token manually")), error && /* @__PURE__ */ React__default.default.createElement("span", { className: styles.error }, error));
9081
+ }
9082
+ return /* @__PURE__ */ React__default.default.createElement("div", null, /* @__PURE__ */ React__default.default.createElement(
9083
+ ui.FileDropzone,
9084
+ {
9085
+ options: { multiple: false, accept: accept.join(",") },
9086
+ readAs: "readAsText",
9087
+ onLoad: (result) => {
9088
+ if (typeof result === "string") {
9089
+ processJson(result);
9090
+ }
9091
+ }
9092
+ }
9093
+ ), /* @__PURE__ */ React__default.default.createElement("div", { className: styles.buttonRow }, /* @__PURE__ */ React__default.default.createElement(ui.Button, { type: "button", fill: "outline", size: "sm", onClick: () => setMode("paste"), disabled }, "Paste JWT Token"), /* @__PURE__ */ React__default.default.createElement("span", { className: styles.separator }, "or"), /* @__PURE__ */ React__default.default.createElement(ui.Button, { type: "button", fill: "outline", size: "sm", onClick: () => setMode("manual"), disabled }, "Fill In JWT Token manually")), error && /* @__PURE__ */ React__default.default.createElement("span", { className: styles.error }, error));
9094
+ }
9095
+ function getStyles$f(theme) {
9096
+ return {
9097
+ buttonRow: css.css({
9098
+ marginTop: theme.spacing(1),
9099
+ display: "flex",
9100
+ alignItems: "center",
9101
+ gap: theme.spacing(0.5)
9102
+ }),
9103
+ separator: css.css({
9104
+ padding: `0 ${theme.spacing(0.5)}`,
9105
+ color: theme.colors.text.secondary
9106
+ }),
9107
+ error: css.css({
9108
+ color: theme.colors.error.text,
9109
+ fontSize: theme.typography.bodySmall.fontSize,
9110
+ marginTop: theme.spacing(0.5),
9111
+ display: "block"
9112
+ })
9113
+ };
9114
+ }
9115
+
9116
+ const IndexedPairEditor = (props) => {
9117
+ const { value, onChange, maxItems = 10, disabled, hideControls, itemLabel = "header" } = props;
9118
+ const styles = ui.useStyles2(getStyles$e);
9119
+ const items = Array.isArray(value) ? value : [];
9120
+ const addItem = () => {
9121
+ if (items.length >= maxItems) {
9122
+ return;
9123
+ }
9124
+ onChange([...items, { index: 0, name: "", value: "" }]);
9125
+ };
9126
+ const removeItem = (index) => {
9127
+ onChange(items.filter((_, i) => i !== index));
9128
+ };
9129
+ const updateItem = (index, key, val) => {
9130
+ const updated = items.map((item, i) => i === index ? { ...item, [key]: val } : item);
9131
+ onChange(updated);
9132
+ };
9133
+ return /* @__PURE__ */ React__default.default.createElement(ui.Stack, { direction: "column", gap: 0.5 }, items.map((item, i) => /* @__PURE__ */ React__default.default.createElement(
9134
+ IndexedPairRow,
9135
+ {
9136
+ key: item.index || `new-${i}`,
9137
+ item,
9138
+ index: i,
9139
+ disabled,
9140
+ onUpdate: updateItem,
9141
+ onRemove: removeItem,
9142
+ hideControls,
9143
+ itemLabel
9144
+ }
9145
+ )), !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 ", itemLabel)), !hideControls && items.length >= maxItems && /* @__PURE__ */ React__default.default.createElement("span", { className: styles.limitNote }, "Maximum ", maxItems, " ", itemLabel, "s reached"));
9146
+ };
9147
+ const IndexedPairRow = (props) => {
9148
+ const { item, index, disabled, onUpdate, onRemove, hideControls, itemLabel = "header" } = props;
9149
+ const styles = ui.useStyles2(getStyles$e);
9150
+ const secureStyles = ui.useStyles2(getSecureFieldStyles);
9151
+ const isConfigured = item.value === SECURE_FIELD_CONFIGURED;
9152
+ const [editing, setEditing] = React.useState(false);
9153
+ const [revealed, setRevealed] = React.useState(false);
9154
+ 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(
9155
+ ui.Input,
9156
+ {
9157
+ value: item.name,
9158
+ placeholder: "key",
9159
+ disabled: disabled || hideControls,
9160
+ onChange: (e) => onUpdate(index, "name", e.currentTarget.value),
9161
+ onKeyDown: (e) => {
9162
+ if (e.key === "Enter") {
9163
+ e.preventDefault();
9164
+ }
9165
+ }
9166
+ }
9167
+ )), /* @__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(
9168
+ ui.Button,
9169
+ {
9170
+ variant: "secondary",
9171
+ fill: "text",
9172
+ size: "sm",
9173
+ onClick: () => {
9174
+ setEditing(true);
9175
+ onUpdate(index, "value", "");
9176
+ },
9177
+ type: "button"
9178
+ },
9179
+ "Reset"
9180
+ )) : /* @__PURE__ */ React__default.default.createElement(
9181
+ ui.Input,
9182
+ {
9183
+ value: item.value === SECURE_FIELD_CONFIGURED ? "" : item.value,
9184
+ placeholder: `${itemLabel} value`,
9185
+ disabled,
9186
+ type: revealed ? "text" : "password",
9187
+ onChange: (e) => onUpdate(index, "value", e.currentTarget.value),
9188
+ onKeyDown: (e) => {
9189
+ if (e.key === "Enter") {
9190
+ e.preventDefault();
9191
+ }
9192
+ },
9193
+ suffix: /* @__PURE__ */ React__default.default.createElement(
9194
+ ui.Button,
9195
+ {
9196
+ variant: "secondary",
9197
+ fill: "text",
9198
+ size: "sm",
9199
+ icon: revealed ? "eye-slash" : "eye",
9200
+ "aria-label": revealed ? "Hide" : "Reveal",
9201
+ onClick: () => setRevealed((r) => !r),
9202
+ type: "button"
9203
+ }
9204
+ )
9205
+ }
9206
+ )), !hideControls && /* @__PURE__ */ React__default.default.createElement(ui.Tooltip, { content: `Remove ${itemLabel}` }, /* @__PURE__ */ React__default.default.createElement(
9207
+ ui.Button,
9208
+ {
9209
+ variant: "secondary",
9210
+ fill: "text",
9211
+ size: "sm",
9212
+ icon: "trash-alt",
9213
+ "aria-label": `Remove ${itemLabel}`,
9214
+ disabled,
9215
+ onClick: () => onRemove(index),
9216
+ type: "button"
9217
+ }
9218
+ )));
9219
+ };
9220
+ const getStyles$e = (theme) => ({
9221
+ inputCell: css.css({
9222
+ flex: "1 1 0",
9223
+ minWidth: 0,
9224
+ overflow: "hidden"
9225
+ }),
9226
+ limitNote: css.css({
9227
+ fontSize: theme.typography.bodySmall.fontSize,
9228
+ color: theme.colors.text.secondary
9229
+ })
9230
+ });
9231
+
9232
+ function ObjectArrayEditor(props) {
9233
+ var _a, _b, _c, _d, _e, _f;
9234
+ const { field, value, onChange, disabled, errorMessage } = props;
9235
+ const styles = ui.useStyles2(getStyles$d);
9236
+ const itemFields = (_b = (_a = field.item) == null ? void 0 : _a.fields) != null ? _b : [];
9237
+ const layoutRows = computeLayoutRows(itemFields);
9238
+ const items = Array.isArray(value) ? value : [];
9239
+ const maxItems = (_e = (_d = (_c = field.validations) == null ? void 0 : _c.find((v) => v.type === "itemCount")) == null ? void 0 : _d.max) != null ? _e : 20;
9240
+ const label = (_f = field.label) != null ? _f : field.key;
9241
+ const itemErrors = parseItemErrors(errorMessage);
9242
+ const addItem = () => {
9243
+ var _a2, _b2;
9244
+ if (items.length >= maxItems) {
9245
+ return;
9246
+ }
9247
+ const empty = {};
9248
+ for (const f of itemFields) {
9249
+ if (f.valueType === "boolean") {
9250
+ empty[f.key] = (_a2 = f.defaultValue) != null ? _a2 : false;
9251
+ } else {
9252
+ empty[f.key] = (_b2 = f.defaultValue) != null ? _b2 : "";
9253
+ }
9254
+ }
9255
+ onChange([...items, empty]);
9256
+ };
9257
+ const removeItem = (index) => {
9258
+ onChange(items.filter((_, i) => i !== index));
9259
+ };
9260
+ const updateItem = (index, key, val) => {
9261
+ const updated = items.map((item, i) => i === index ? { ...item, [key]: val } : item);
9262
+ onChange(updated);
9263
+ };
9264
+ return /* @__PURE__ */ React__default.default.createElement(ui.Stack, { direction: "column", gap: 1 }, items.map((item, i) => /* @__PURE__ */ React__default.default.createElement(
9265
+ ObjectArrayItemRow,
9266
+ {
9267
+ key: i,
9268
+ item,
9269
+ index: i,
9270
+ itemFields,
9271
+ layoutRows,
9272
+ disabled: !!disabled,
9273
+ onUpdate: updateItem,
9274
+ onRemove: removeItem,
9275
+ showLabels: true,
9276
+ error: itemErrors == null ? void 0 : itemErrors[i]
9277
+ }
9278
+ )), 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 ", label.toLowerCase())), items.length >= maxItems && /* @__PURE__ */ React__default.default.createElement("span", { className: styles.limitNote }, "Maximum ", maxItems, " items reached"));
9279
+ }
9280
+ function computeLayoutRows(fields) {
9281
+ var _a;
9282
+ const hasExplicitRow = fields.some((f) => {
9283
+ var _a2;
9284
+ return ((_a2 = f.ui) == null ? void 0 : _a2.row) !== void 0;
9285
+ });
9286
+ if (!hasExplicitRow) {
9287
+ if (fields.length <= 3) {
9288
+ return [fields];
9289
+ }
9290
+ return fields.map((f) => [f]);
9291
+ }
9292
+ const rowMap = /* @__PURE__ */ new Map();
9293
+ const noRow = [];
9294
+ for (const f of fields) {
9295
+ if (((_a = f.ui) == null ? void 0 : _a.row) !== void 0) {
9296
+ const existing = rowMap.get(f.ui.row);
9297
+ if (existing) {
9298
+ existing.push(f);
9299
+ } else {
9300
+ rowMap.set(f.ui.row, [f]);
9301
+ }
9302
+ } else {
9303
+ noRow.push(f);
9304
+ }
9305
+ }
9306
+ const sortedKeys = [...rowMap.keys()].sort((a, b) => a - b);
9307
+ const rows = sortedKeys.map((k) => rowMap.get(k));
9308
+ for (const f of noRow) {
9309
+ rows.push([f]);
9310
+ }
9311
+ return rows;
9312
+ }
9313
+ function makeItemFormField(item, index, fieldKey, onUpdate) {
9314
+ return {
9315
+ name: `item-${index}-${fieldKey}`,
9316
+ value: item[fieldKey],
9317
+ onChange: (eventOrValue) => {
9318
+ if (eventOrValue != null && typeof eventOrValue === "object" && "target" in eventOrValue) {
9319
+ onUpdate(index, fieldKey, eventOrValue.target.value);
9320
+ } else {
9321
+ onUpdate(index, fieldKey, eventOrValue);
9322
+ }
9323
+ },
9324
+ onBlur: () => {
9325
+ }
9326
+ };
9327
+ }
9328
+ function effectiveItemField(field, isSecure) {
9329
+ if (!isSecure) {
9330
+ return field;
9331
+ }
9332
+ return { ...field, semanticType: "password" };
9333
+ }
9334
+ function ObjectArrayItemRow({
9335
+ item,
9336
+ index,
9337
+ itemFields,
9338
+ layoutRows,
9339
+ disabled,
9340
+ onUpdate,
9341
+ onRemove,
9342
+ showLabels,
9343
+ error
9344
+ }) {
9345
+ const styles = ui.useStyles2(getStyles$d);
9346
+ const secureOverride = findActiveSecureOverride(itemFields, item, index);
9347
+ return /* @__PURE__ */ React__default.default.createElement("div", { className: styles.itemRow }, layoutRows.map((row, rowIdx) => /* @__PURE__ */ React__default.default.createElement(ui.Stack, { key: rowIdx, direction: "row", gap: 1, alignItems: "flex-end", wrap: "wrap" }, row.map((field) => {
9348
+ var _a;
9349
+ const isSecureTarget = (secureOverride == null ? void 0 : secureOverride.fieldKey) === field.key;
9350
+ const eff = effectiveItemField(field, !!isSecureTarget);
9351
+ const formField = makeItemFormField(item, index, field.key, onUpdate);
9352
+ if (isSecureTarget && item[field.key] === SECURE_FIELD_CONFIGURED) {
9353
+ formField.value = SECURE_FIELD_CONFIGURED;
9354
+ }
9355
+ return /* @__PURE__ */ React__default.default.createElement("div", { key: field.key, className: field.valueType === "boolean" ? styles.boolCell : styles.inputCell }, /* @__PURE__ */ React__default.default.createElement("span", { className: styles.cellLabel }, (_a = field.label) != null ? _a : field.key, field.required && /* @__PURE__ */ React__default.default.createElement("span", { className: styles.required }, " *")), renderFieldInput(eff, formField, disabled));
9356
+ }), rowIdx === 0 && /* @__PURE__ */ React__default.default.createElement("div", { className: styles.removeCellWithLabel }, /* @__PURE__ */ React__default.default.createElement(ui.Tooltip, { content: "Remove" }, /* @__PURE__ */ React__default.default.createElement(
9357
+ ui.Button,
9358
+ {
9359
+ variant: "secondary",
9360
+ fill: "text",
9361
+ size: "sm",
9362
+ icon: "trash-alt",
9363
+ "aria-label": "Remove item",
9364
+ disabled,
9365
+ onClick: () => onRemove(index),
9366
+ type: "button"
9367
+ }
9368
+ ))))), error && /* @__PURE__ */ React__default.default.createElement("span", { className: styles.itemError }, error));
9369
+ }
9370
+ const getStyles$d = (theme) => ({
9371
+ itemRow: css.css({
9372
+ display: "flex",
9373
+ flexDirection: "column",
9374
+ gap: theme.spacing(0.5),
9375
+ padding: theme.spacing(1),
9376
+ borderRadius: theme.shape.radius.default,
9377
+ border: `1px solid ${theme.colors.border.weak}`
9378
+ }),
9379
+ inputCell: css.css({
9380
+ flex: "1 1 120px",
9381
+ minWidth: 120,
9382
+ overflow: "hidden"
9383
+ }),
9384
+ boolCell: css.css({
9385
+ flex: "0 0 auto",
9386
+ minWidth: 0
9387
+ }),
9388
+ cellLabel: css.css({
9389
+ fontSize: theme.typography.bodySmall.fontSize,
9390
+ color: theme.colors.text.secondary,
9391
+ marginBottom: theme.spacing(0.25)
9392
+ }),
9393
+ required: css.css({
9394
+ color: theme.colors.error.text
9395
+ }),
9396
+ removeCellWithLabel: css.css({
9397
+ flex: "0 0 auto",
9398
+ display: "flex",
9399
+ alignItems: "flex-end",
9400
+ paddingBottom: theme.spacing(0.25)
9401
+ }),
9402
+ itemError: css.css({
9403
+ fontSize: theme.typography.bodySmall.fontSize,
9404
+ color: theme.colors.error.text
9405
+ }),
9406
+ limitNote: css.css({
9407
+ fontSize: theme.typography.bodySmall.fontSize,
9408
+ color: theme.colors.text.secondary
9409
+ })
9410
+ });
9411
+
9412
+ const StringArrayInput = (props) => {
9413
+ const { value, onChange, placeholder, disabled, itemLabel = "item" } = props;
9414
+ const styles = ui.useStyles2(getStyles$c);
9415
+ const items = Array.isArray(value) ? value : [];
9416
+ const lastInputRef = React.useRef(null);
9417
+ const shouldFocusLastRef = React.useRef(false);
9418
+ React.useEffect(() => {
9419
+ if (shouldFocusLastRef.current && lastInputRef.current) {
9420
+ lastInputRef.current.focus();
9421
+ shouldFocusLastRef.current = false;
9422
+ }
9423
+ }, [items.length]);
9424
+ const addItem = () => {
9425
+ shouldFocusLastRef.current = true;
9426
+ onChange([...items, ""]);
9427
+ };
9428
+ const removeItem = (index) => {
9429
+ onChange(items.filter((_, i) => i !== index));
9430
+ };
9431
+ const updateItem = (index, val) => {
9432
+ onChange(items.map((item, i) => i === index ? val : item));
9433
+ };
9434
+ const isItemValid = (index, val) => {
9435
+ const trimmed = val.trim();
9436
+ if (trimmed === "") {
9437
+ return false;
9438
+ }
9439
+ return !items.some((item, i) => i !== index && item.trim() === trimmed);
9440
+ };
9441
+ const handleEnter = (index, currentValue) => {
9442
+ if (!isItemValid(index, currentValue)) {
9443
+ return;
9444
+ }
9445
+ if (index === items.length - 1) {
9446
+ shouldFocusLastRef.current = true;
9447
+ onChange([...items, ""]);
9448
+ }
9449
+ };
9450
+ return /* @__PURE__ */ React__default.default.createElement(ui.Stack, { direction: "column", gap: 0.5 }, items.map((item, i) => /* @__PURE__ */ React__default.default.createElement(ui.Stack, { direction: "row", gap: 1, key: i }, /* @__PURE__ */ React__default.default.createElement("div", { className: styles.inputCell }, /* @__PURE__ */ React__default.default.createElement(
9451
+ ui.Input,
9452
+ {
9453
+ ref: i === items.length - 1 ? lastInputRef : void 0,
9454
+ value: item,
9455
+ placeholder: placeholder != null ? placeholder : itemLabel,
9456
+ disabled,
9457
+ onChange: (e) => updateItem(i, e.currentTarget.value),
9458
+ onKeyDown: (e) => {
9459
+ if (e.key === "Enter") {
9460
+ e.preventDefault();
9461
+ handleEnter(i, e.currentTarget.value);
9462
+ }
9463
+ }
9464
+ }
9465
+ )), !disabled && /* @__PURE__ */ React__default.default.createElement(ui.Tooltip, { content: `Remove ${itemLabel}` }, /* @__PURE__ */ React__default.default.createElement(
9466
+ ui.Button,
9467
+ {
9468
+ variant: "secondary",
9469
+ fill: "text",
9470
+ size: "sm",
9471
+ icon: "trash-alt",
9472
+ "aria-label": `Remove ${itemLabel}`,
9473
+ onClick: () => removeItem(i),
9474
+ type: "button"
9475
+ }
9476
+ )))), !disabled && /* @__PURE__ */ React__default.default.createElement("div", null, /* @__PURE__ */ React__default.default.createElement(ui.Button, { variant: "secondary", size: "sm", icon: "plus", onClick: addItem, type: "button" }, "Add")));
9477
+ };
9478
+ const getStyles$c = (theme) => ({
9479
+ inputCell: css.css({
9480
+ flex: "1 1 0",
9481
+ minWidth: 0,
9482
+ overflow: "hidden"
9483
+ })
9484
+ });
9485
+
9486
+ function renderFieldInput(field, formField, disabled, errorMessage, setValue) {
9487
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w;
9488
+ const value = formField.value;
9489
+ const placeholder = (_a = field.ui) == null ? void 0 : _a.placeholder;
9490
+ const label = (_b = field.label) != null ? _b : field.key;
9491
+ if (((_c = field.ui) == null ? void 0 : _c.component) === "fileUpload" && field.ui.fileMapping && setValue) {
9492
+ return /* @__PURE__ */ React__default.default.createElement(FileUploadField, { field, formField, disabled, setValue });
9493
+ }
9494
+ if (field.target === "secureJsonData" || field.semanticType === "password" || field.semanticType === "token") {
9495
+ return /* @__PURE__ */ React__default.default.createElement(SecureFieldInput, { formField, placeholder: placeholder != null ? placeholder : label, disabled, label });
9496
+ }
9497
+ if (((_d = field.ui) == null ? void 0 : _d.component) === "radio") {
9498
+ const options = ((_f = (_e = field.ui) == null ? void 0 : _e.options) != null ? _f : []).map((opt) => ({
9499
+ label: opt.label,
9500
+ value: String(opt.value),
9501
+ description: opt.description
9502
+ }));
9503
+ return /* @__PURE__ */ React__default.default.createElement("div", { style: { display: "flex" } }, /* @__PURE__ */ React__default.default.createElement(
9504
+ ui.RadioButtonGroup,
9505
+ {
9506
+ options,
9507
+ value: String(value != null ? value : ""),
9508
+ onChange: (v) => {
9509
+ if (field.valueType === "number") {
9510
+ const n = Number(v);
9511
+ formField.onChange(Number.isNaN(n) ? v : n);
9512
+ } else {
9513
+ formField.onChange(v);
9514
+ }
9515
+ },
9516
+ disabled
9517
+ }
9518
+ ));
9519
+ }
9520
+ if (((_g = field.ui) == null ? void 0 : _g.component) === "select") {
9521
+ const options = ((_i = (_h = field.ui) == null ? void 0 : _h.options) != null ? _i : []).map((opt) => ({
9522
+ label: opt.label,
9523
+ value: String(opt.value),
9524
+ description: opt.description
9525
+ }));
9526
+ return /* @__PURE__ */ React__default.default.createElement(
9527
+ ui.Select,
9528
+ {
9529
+ options,
9530
+ value: options.find((o) => o.value === String(value != null ? value : "")),
9531
+ onChange: (v) => formField.onChange(v == null ? void 0 : v.value),
9532
+ disabled
9533
+ }
9534
+ );
9535
+ }
9536
+ if (field.valueType === "boolean") {
9537
+ return /* @__PURE__ */ React__default.default.createElement(ui.Switch, { value: !!value, onChange: (e) => formField.onChange(e.currentTarget.checked), disabled });
9538
+ }
9539
+ if (field.valueType === "number") {
9540
+ return /* @__PURE__ */ React__default.default.createElement(
9541
+ ui.Input,
9542
+ {
9543
+ ...formField,
9544
+ value: value !== void 0 && value !== null ? Number(value) : "",
9545
+ type: "number",
9546
+ placeholder,
9547
+ disabled,
9548
+ onChange: (e) => {
9549
+ const n = e.currentTarget.valueAsNumber;
9550
+ formField.onChange(Number.isNaN(n) ? void 0 : n);
9551
+ }
9552
+ }
9553
+ );
9554
+ }
9555
+ if (field.semanticType === "url") {
9556
+ return /* @__PURE__ */ React__default.default.createElement(ui.Input, { ...formField, value: String(value != null ? value : ""), type: "url", placeholder, disabled });
9557
+ }
9558
+ if (((_j = field.ui) == null ? void 0 : _j.component) === "textarea") {
9559
+ return /* @__PURE__ */ React__default.default.createElement(
9560
+ ui.TextArea,
9561
+ {
9562
+ ...formField,
9563
+ value: String(value != null ? value : ""),
9564
+ placeholder,
9565
+ disabled,
9566
+ rows: (_l = (_k = field.ui) == null ? void 0 : _k.rows) != null ? _l : 3
9567
+ }
9568
+ );
9569
+ }
9570
+ if (((_m = field.storage) == null ? void 0 : _m.type) === "indexedPair") {
9571
+ const items = Array.isArray(value) ? value : [];
9572
+ const maxItems = (_p = (_o = (_n = field.validations) == null ? void 0 : _n.find((v) => v.type === "itemCount")) == null ? void 0 : _o.max) != null ? _p : 10;
9573
+ const itemLabel = (_r = (_q = field.label) == null ? void 0 : _q.toLowerCase().replace(/s$/, "")) != null ? _r : "header";
9574
+ return /* @__PURE__ */ React__default.default.createElement(
9575
+ IndexedPairEditor,
9576
+ {
9577
+ value: items,
9578
+ onChange: formField.onChange,
9579
+ maxItems,
9580
+ disabled,
9581
+ itemLabel
9582
+ }
9583
+ );
9584
+ }
9585
+ if (field.valueType === "array" && ((_s = field.item) == null ? void 0 : _s.valueType) === "string") {
9586
+ return /* @__PURE__ */ React__default.default.createElement(
9587
+ StringArrayInput,
9588
+ {
9589
+ value: Array.isArray(value) ? value : [],
9590
+ onChange: formField.onChange,
9591
+ placeholder,
9592
+ disabled,
9593
+ itemLabel: label.toLowerCase().replace(/s$/, "")
9594
+ }
9595
+ );
9596
+ }
9597
+ if (field.valueType === "array" && ((_t = field.item) == null ? void 0 : _t.valueType) === "object" && ((_u = field.item.fields) == null ? void 0 : _u.length)) {
9598
+ return /* @__PURE__ */ React__default.default.createElement(
9599
+ ObjectArrayEditor,
9600
+ {
9601
+ field,
9602
+ value,
9603
+ onChange: formField.onChange,
9604
+ disabled,
9605
+ errorMessage
9606
+ }
9607
+ );
9608
+ }
9609
+ if (field.valueType === "object" || field.valueType === "map" || field.valueType === "array" && (((_v = field.item) == null ? void 0 : _v.valueType) === "object" || ((_w = field.item) == null ? void 0 : _w.valueType) === "map")) {
9610
+ const count = Array.isArray(value) ? value.length : 0;
9611
+ return /* @__PURE__ */ React__default.default.createElement(ComplexFieldNote, { count, label });
9612
+ }
9613
+ return /* @__PURE__ */ React__default.default.createElement(ui.Input, { ...formField, value: String(value != null ? value : ""), placeholder, disabled });
9614
+ }
9615
+
9616
+ const getTabStyles = (theme) => ({
9617
+ root: css.css({
9618
+ display: "flex",
9619
+ gap: theme.spacing(3),
9620
+ position: "relative",
9621
+ background: theme.colors.background.canvas,
9622
+ padding: theme.spacing(2)
9623
+ }),
9624
+ // Sidebar
9625
+ sidebar: css.css({
9626
+ width: 250,
9627
+ flexShrink: 0,
9628
+ position: "sticky",
9629
+ top: theme.spacing(2),
9630
+ alignSelf: "flex-start",
9631
+ [theme.breakpoints.down("sm")]: { display: "none" }
9632
+ }),
9633
+ sidebarTitle: css.css({
9634
+ fontSize: theme.typography.body.fontSize,
9635
+ fontWeight: theme.typography.fontWeightMedium,
9636
+ color: theme.colors.text.primary,
9637
+ padding: `${theme.spacing(1)} 0`,
9638
+ marginBottom: theme.spacing(1)
9639
+ }),
9640
+ navList: css.css({
9641
+ listStyle: "none",
9642
+ margin: 0,
9643
+ padding: 0,
9644
+ position: "relative"
9645
+ }),
9646
+ navItem: css.css({
9647
+ display: "flex",
9648
+ alignItems: "flex-start",
9649
+ gap: theme.spacing(1.5),
9650
+ padding: `${theme.spacing(1)} 0`,
9651
+ cursor: "pointer",
9652
+ position: "relative"
9653
+ }),
9654
+ navItemActive: css.css({}),
9655
+ // Dot container: positions the dot and the connector line
9656
+ navDotWrap: css.css({
9657
+ position: "relative",
9658
+ display: "flex",
9659
+ alignItems: "center",
9660
+ justifyContent: "center",
9661
+ width: 12,
9662
+ flexShrink: 0,
9663
+ alignSelf: "flex-start",
9664
+ paddingTop: theme.spacing(0.5)
9665
+ }),
9666
+ navDot: css.css({
9667
+ width: 10,
9668
+ height: 10,
9669
+ borderRadius: "50%",
9670
+ border: `2px solid ${theme.colors.text.disabled}`,
9671
+ background: theme.colors.background.canvas,
9672
+ position: "relative",
9673
+ zIndex: 1
9674
+ }),
9675
+ navDotOptional: css.css({
9676
+ borderStyle: "dashed"
9677
+ }),
9678
+ navDotActive: css.css({
9679
+ background: theme.colors.primary.main,
9680
+ borderColor: theme.colors.primary.main,
9681
+ borderStyle: "solid"
9682
+ }),
9683
+ navDotValidated: css.css({
9684
+ background: theme.colors.success.main,
9685
+ borderColor: theme.colors.success.main,
9686
+ borderStyle: "solid"
9687
+ }),
9688
+ navDotError: css.css({
9689
+ background: theme.colors.error.main,
9690
+ borderColor: theme.colors.error.main,
9691
+ borderStyle: "solid"
9692
+ }),
9693
+ // Connector line running from dot center downward to next item
9694
+ navConnector: css.css({
9695
+ position: "absolute",
9696
+ left: 5,
9697
+ top: 16,
9698
+ bottom: -16,
9699
+ width: 2,
9700
+ background: theme.colors.border.medium,
9701
+ zIndex: 0
9702
+ }),
9703
+ navConnectorDashed: css.css({
9704
+ background: "none",
9705
+ borderLeft: `2px dashed ${theme.colors.border.weak}`,
9706
+ width: 0
9707
+ }),
9708
+ navLabel: css.css({
9709
+ fontSize: theme.typography.body.fontSize,
9710
+ color: theme.colors.text.secondary,
9711
+ lineHeight: 1.4
9712
+ }),
9713
+ navLabelActive: css.css({
9714
+ fontWeight: theme.typography.fontWeightMedium,
9715
+ color: theme.colors.text.primary
9716
+ }),
9717
+ // Main content
9718
+ main: css.css({
9719
+ flex: 1,
9720
+ minWidth: 0,
9721
+ width: 0,
9722
+ // forces flex child to respect flex-grow and fill remaining space
9723
+ display: "flex",
9724
+ flexDirection: "column",
9725
+ gap: theme.spacing(2)
9726
+ }),
9727
+ form: css.css({
9728
+ display: "flex",
9729
+ flexDirection: "column",
9730
+ gap: theme.spacing(2)
9731
+ }),
9732
+ requiredNotice: css.css({
9733
+ fontSize: theme.typography.bodySmall.fontSize,
9734
+ color: theme.colors.text.secondary,
9735
+ marginBottom: theme.spacing(0.5)
9736
+ }),
9737
+ // Section wrapper — card container around CollapsableSection
9738
+ section: css.css({
9739
+ border: `1px solid ${theme.colors.border.weak}`,
9740
+ borderRadius: theme.shape.radius.default,
9741
+ background: theme.colors.background.secondary,
9742
+ overflow: "hidden"
9743
+ }),
9744
+ // Override Collapse component styling
9745
+ collapseHeader: css.css({
9746
+ borderRadius: theme.shape.radius.default,
9747
+ background: "none",
9748
+ border: "none",
9749
+ marginBottom: 0,
9750
+ // Collapse header button: make label fill remaining space
9751
+ "& > button": {
9752
+ padding: `${theme.spacing(1.5)} ${theme.spacing(2)}`,
9753
+ width: "100%",
9754
+ justifyContent: "flex-start"
9755
+ },
9756
+ "& > button > div": {
9757
+ flex: 1,
9758
+ fontSize: theme.typography.h4.fontSize,
9759
+ fontWeight: theme.typography.fontWeightMedium,
9760
+ textAlign: "left"
9761
+ }
9762
+ }),
9763
+ sectionLabel: css.css({
9764
+ display: "flex",
9765
+ alignItems: "center",
9766
+ flex: 1
9767
+ }),
9768
+ sectionLabelText: css.css({
9769
+ flex: 1
9770
+ }),
9771
+ sectionHeader: css.css({
9772
+ display: "flex",
9773
+ alignItems: "center",
9774
+ gap: theme.spacing(1),
9775
+ padding: `${theme.spacing(1.5)} ${theme.spacing(2)}`,
9776
+ cursor: "pointer",
9777
+ userSelect: "none"
9778
+ }),
9779
+ sectionChevron: css.css({
9780
+ transition: "transform 0.2s ease"
9781
+ }),
9782
+ sectionChevronOpen: css.css({
9783
+ transform: "rotate(90deg)"
9784
+ }),
9785
+ sectionTitle: css.css({
9786
+ fontSize: theme.typography.h4.fontSize,
9787
+ fontWeight: theme.typography.fontWeightMedium,
9788
+ flex: 1,
9789
+ textAlign: "left"
9790
+ }),
9791
+ sectionBadge: css.css({
9792
+ fontSize: theme.typography.bodySmall.fontSize,
9793
+ fontWeight: theme.typography.fontWeightRegular,
9794
+ color: theme.colors.text.disabled,
9795
+ border: `1px solid ${theme.colors.border.weak}`,
9796
+ borderRadius: theme.shape.radius.pill,
9797
+ padding: `1px ${theme.spacing(0.75)}`,
9798
+ whiteSpace: "nowrap"
9799
+ }),
9800
+ sectionDescription: css.css({
9801
+ fontSize: theme.typography.bodySmall.fontSize,
9802
+ color: theme.colors.text.secondary,
9803
+ marginBottom: theme.spacing(1.5)
9804
+ }),
9805
+ sectionBody: css.css({
9806
+ padding: `0 ${theme.spacing(2)} ${theme.spacing(2)}`,
9807
+ display: "flex",
9808
+ flexDirection: "column",
9809
+ gap: theme.spacing(0.75)
9810
+ }),
9811
+ // Form bottom
9812
+ formButtons: css.css({
9813
+ display: "flex",
9814
+ gap: theme.spacing(1),
9815
+ paddingTop: theme.spacing(0.5)
9816
+ }),
9817
+ // Loading / error states
9818
+ loadingContainer: css.css({
9819
+ display: "flex",
9820
+ alignItems: "center",
9821
+ gap: theme.spacing(1),
9822
+ padding: theme.spacing(3),
9823
+ color: theme.colors.text.secondary
9824
+ }),
9825
+ overlay: css.css({
9826
+ position: "absolute",
9827
+ inset: 0,
9828
+ display: "flex",
9829
+ alignItems: "center",
9830
+ justifyContent: "center",
9831
+ gap: theme.spacing(1),
9832
+ background: theme.colors.background.secondary,
9833
+ borderRadius: theme.shape.radius.default,
9834
+ zIndex: 1,
9835
+ fontSize: theme.typography.bodySmall.fontSize,
9836
+ color: theme.colors.text.primary,
9837
+ opacity: 0.95
9838
+ }),
9839
+ readOnlyBanner: css.css({
9840
+ display: "inline-flex",
9841
+ alignItems: "center",
9842
+ gap: theme.spacing(0.5),
9843
+ padding: `${theme.spacing(0.25)} ${theme.spacing(0.75)}`,
9844
+ fontSize: theme.typography.bodySmall.fontSize,
9845
+ color: theme.colors.text.secondary,
9846
+ backgroundColor: theme.colors.background.secondary,
9847
+ borderRadius: theme.shape.radius.default,
9848
+ border: `1px solid ${theme.colors.border.weak}`,
9849
+ marginBottom: theme.spacing(1)
9850
+ })
9851
+ });
9852
+ const getWizardStyles = (theme) => ({
9853
+ container: css.css({
9854
+ position: "relative",
9855
+ display: "flex",
9856
+ flexDirection: "column",
9857
+ gap: theme.spacing(1),
9858
+ padding: theme.spacing(1.5),
9859
+ backgroundColor: theme.colors.background.secondary,
9860
+ borderRadius: theme.shape.radius.default,
9861
+ border: `1px solid ${theme.colors.border.weak}`,
9862
+ overflow: "hidden"
9863
+ }),
9864
+ overlay: css.css({
9865
+ position: "absolute",
9866
+ inset: 0,
9867
+ display: "flex",
9868
+ alignItems: "center",
9869
+ justifyContent: "center",
9870
+ gap: theme.spacing(1),
9871
+ background: theme.colors.background.secondary,
9872
+ borderRadius: theme.shape.radius.default,
9873
+ zIndex: 1,
9874
+ fontSize: theme.typography.bodySmall.fontSize,
9875
+ color: theme.colors.text.primary,
9876
+ opacity: 0.95
9877
+ }),
9878
+ readOnlyBanner: css.css({
9879
+ display: "inline-flex",
9880
+ alignItems: "center",
9881
+ gap: theme.spacing(0.5),
9882
+ padding: `${theme.spacing(0.25)} ${theme.spacing(0.75)}`,
9883
+ fontSize: theme.typography.bodySmall.fontSize,
9884
+ color: theme.colors.text.secondary,
9885
+ backgroundColor: theme.colors.background.secondary,
9886
+ borderRadius: theme.shape.radius.default,
9887
+ border: `1px solid ${theme.colors.border.weak}`
9888
+ }),
9889
+ navBar: css.css({
9890
+ display: "flex",
9891
+ alignItems: "center",
9892
+ justifyContent: "space-between"
9893
+ }),
9894
+ navTitle: css.css({
9895
+ display: "inline-flex",
9896
+ alignItems: "center",
9897
+ gap: theme.spacing(0.5),
9898
+ fontSize: theme.typography.body.fontSize,
9899
+ fontWeight: theme.typography.fontWeightBold,
9900
+ color: theme.colors.text.primary
9901
+ }),
9902
+ stepCount: css.css({
9903
+ fontSize: theme.typography.bodySmall.fontSize,
9904
+ fontWeight: theme.typography.fontWeightRegular,
9905
+ color: theme.colors.text.secondary
9906
+ }),
9907
+ navActions: css.css({
9908
+ display: "flex",
9909
+ alignItems: "center",
9910
+ gap: theme.spacing(0.25)
9911
+ }),
9912
+ form: css.css({
9913
+ display: "flex",
9914
+ flexDirection: "column",
9915
+ gap: theme.spacing(0.75)
9916
+ }),
9917
+ buttons: css.css({
9918
+ display: "flex",
9919
+ gap: theme.spacing(1),
9920
+ paddingTop: theme.spacing(0.25)
9921
+ }),
9922
+ fieldRow: css.css({
9923
+ display: "grid",
9924
+ gridTemplateColumns: "minmax(80px, 1fr) minmax(0, 2fr)",
9925
+ gap: theme.spacing(0.75),
9926
+ alignItems: "start"
9927
+ }),
9928
+ fieldRowCenter: css.css({
9929
+ display: "grid",
9930
+ gridTemplateColumns: "minmax(80px, 1fr) minmax(0, 2fr)",
9931
+ gap: theme.spacing(0.75),
9932
+ alignItems: "center",
9933
+ padding: `${theme.spacing(0.5)} 0`
9934
+ }),
9935
+ fieldLabelRow: css.css({
9936
+ display: "flex",
9937
+ alignItems: "center",
9938
+ gap: theme.spacing(0.5),
9939
+ paddingTop: theme.spacing(0.5)
9940
+ }),
9941
+ fieldLabelRowCompact: css.css({
9942
+ display: "flex",
9943
+ alignItems: "center",
9944
+ gap: theme.spacing(0.5)
9945
+ }),
9946
+ fieldLabel: css.css({
9947
+ fontSize: theme.typography.bodySmall.fontSize,
9948
+ fontWeight: theme.typography.fontWeightMedium,
9949
+ color: theme.colors.text.primary
9950
+ }),
9951
+ fieldRequired: css.css({
9952
+ color: theme.colors.error.text,
9953
+ marginLeft: 2
9954
+ }),
9955
+ fieldInfoIcon: css.css({
9956
+ color: theme.colors.text.disabled,
9957
+ cursor: "help",
9958
+ flexShrink: 0
9959
+ }),
9960
+ fieldInputCol: css.css({
9961
+ display: "flex",
9962
+ flexDirection: "column",
9963
+ gap: theme.spacing(0.25),
9964
+ minWidth: 0
9965
+ }),
9966
+ fieldError: css.css({
9967
+ fontSize: theme.typography.bodySmall.fontSize,
9968
+ color: theme.colors.error.text
9969
+ })
9970
+ });
9971
+
9972
+ function SchemaField({
9973
+ field,
9974
+ control,
9975
+ errors,
9976
+ disabled,
9977
+ dsUid,
9978
+ watchedValues,
9979
+ fieldById,
9980
+ celContext,
9981
+ setValue
9982
+ }) {
9983
+ const styles = ui.useStyles2(getWizardStyles);
9984
+ const activeOverride = useDatasourceSchema.resolveActiveOverride(field, watchedValues, fieldById);
9985
+ const fk = useDatasourceSchema.formKey(field);
9986
+ if (field.key === "pdcInjected" && field.target === "jsonData") {
9987
+ return /* @__PURE__ */ React__default.default.createElement(
9988
+ reactHookForm.Controller,
9989
+ {
9990
+ name: fk,
9991
+ control,
9992
+ render: ({ field: formField }) => /* @__PURE__ */ React__default.default.createElement(
9993
+ PdcFieldNote,
9994
+ {
9995
+ enabled: !!formField.value,
9996
+ description: field.description,
9997
+ configUrl: `/connections/datasources/edit/${dsUid}`
9998
+ }
9999
+ )
10000
+ }
10001
+ );
10002
+ }
10003
+ const required = isFieldRequired(field, watchedValues, fieldById, celContext);
10004
+ const validationRules = buildValidationRules(field, required);
10005
+ return /* @__PURE__ */ React__default.default.createElement(
10006
+ reactHookForm.Controller,
10007
+ {
10008
+ name: fk,
10009
+ control,
10010
+ rules: validationRules,
10011
+ render: ({ field: formField }) => {
10012
+ var _a, _b, _c, _d, _e;
10013
+ const errorMessage = (_a = errors[fk]) == null ? void 0 : _a.message;
10014
+ const label = (_b = field.label) != null ? _b : field.key;
10015
+ const description = (_c = activeOverride == null ? void 0 : activeOverride.description) != null ? _c : field.description;
10016
+ const effectiveField = activeOverride ? {
10017
+ ...field,
10018
+ description,
10019
+ ui: {
10020
+ ...field.ui,
10021
+ placeholder: (_e = activeOverride.placeholder) != null ? _e : (_d = field.ui) == null ? void 0 : _d.placeholder
10022
+ }
10023
+ } : field;
10024
+ const isReadOnly = !!(activeOverride == null ? void 0 : activeOverride.readOnly);
10025
+ const isBool = field.valueType === "boolean";
10026
+ 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, setValue), errorMessage && !parseItemErrors(errorMessage) && /* @__PURE__ */ React__default.default.createElement("span", { className: styles.fieldError }, errorMessage)));
10027
+ }
10028
+ }
10029
+ );
10030
+ }
10031
+
10032
+ const AuthorizationHeaderField = (props) => {
10033
+ const { headersFieldKey, control, disabled, watchedValues } = props;
10034
+ const styles = ui.useStyles2(getWizardStyles);
10035
+ const items = React.useMemo(
10036
+ () => Array.isArray(watchedValues[headersFieldKey]) ? watchedValues[headersFieldKey] : [],
10037
+ [watchedValues, headersFieldKey]
10038
+ );
10039
+ const authEntries = React.useMemo(() => {
10040
+ const entries = [];
10041
+ for (let i = 0; i < items.length; i++) {
10042
+ if (items[i].name.toLowerCase() === "authorization") {
10043
+ entries.push({ item: items[i], originalIdx: i });
10044
+ }
10045
+ }
10046
+ return entries;
10047
+ }, [items]);
10048
+ if (authEntries.length === 0) {
10049
+ return null;
10050
+ }
10051
+ const authItems = authEntries.map((e) => e.item);
10052
+ return /* @__PURE__ */ React__default.default.createElement(
10053
+ reactHookForm.Controller,
10054
+ {
10055
+ name: headersFieldKey,
10056
+ control,
10057
+ render: ({ field: formField }) => {
10058
+ const handleChange = (updatedAuthItems) => {
10059
+ const updated = [...items];
10060
+ for (let i = 0; i < authEntries.length; i++) {
10061
+ if (i < updatedAuthItems.length) {
10062
+ updated[authEntries[i].originalIdx] = updatedAuthItems[i];
10063
+ }
10064
+ }
10065
+ formField.onChange(updated);
10066
+ };
10067
+ 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 })));
10068
+ }
10069
+ }
10070
+ );
10071
+ };
10072
+
10073
+ function SidebarNav({ groups, activeIndex, sectionStates, onSelect }) {
10074
+ const styles = ui.useStyles2(getTabStyles);
10075
+ const visibleGroups = groups.filter((g) => g.group.id !== "_required");
10076
+ 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) => {
10077
+ var _a, _b;
10078
+ const origIndex = groups.indexOf(g);
10079
+ const state = (_a = sectionStates[origIndex]) != null ? _a : "draft";
10080
+ const isActive = origIndex === activeIndex;
10081
+ const isOptional = g.group.optional === true;
10082
+ const isLast = vi === visibleGroups.length - 1;
10083
+ const nextIsOptional = !isLast && ((_b = visibleGroups[vi + 1]) == null ? void 0 : _b.group.optional) === true;
10084
+ return /* @__PURE__ */ React__default.default.createElement("li", { key: g.group.id }, /* @__PURE__ */ React__default.default.createElement(
10085
+ "div",
10086
+ {
10087
+ className: css.cx(styles.navItem, isActive && styles.navItemActive),
10088
+ onClick: () => onSelect(origIndex),
10089
+ role: "button",
10090
+ tabIndex: 0,
10091
+ onKeyDown: (e) => {
10092
+ if (e.key === "Enter" || e.key === " ") {
10093
+ e.preventDefault();
10094
+ onSelect(origIndex);
10095
+ }
10096
+ }
10097
+ },
10098
+ /* @__PURE__ */ React__default.default.createElement("div", { className: styles.navDotWrap }, /* @__PURE__ */ React__default.default.createElement(
10099
+ "span",
10100
+ {
10101
+ className: css.cx(
10102
+ styles.navDot,
10103
+ isOptional && styles.navDotOptional,
10104
+ isActive && styles.navDotActive,
10105
+ state === "validated" && !isActive && styles.navDotValidated,
10106
+ state === "error" && !isActive && styles.navDotError
10107
+ )
10108
+ }
10109
+ ), !isLast && /* @__PURE__ */ React__default.default.createElement(
10110
+ "div",
10111
+ {
10112
+ className: css.cx(styles.navConnector, (isOptional || nextIsOptional) && styles.navConnectorDashed)
10113
+ }
10114
+ )),
10115
+ /* @__PURE__ */ React__default.default.createElement("span", { className: css.cx(styles.navLabel, isActive && styles.navLabelActive) }, g.group.title)
10116
+ ));
10117
+ })));
10118
+ }
10119
+
10120
+ function TabLayout({ form, schema, dsUid, dsName, onRetest, healthError, renderActions }) {
10121
+ const styles = ui.useStyles2(getTabStyles);
10122
+ const sectionRefs = React.useRef(/* @__PURE__ */ new Map());
10123
+ const {
10124
+ resolvedGroups,
10125
+ fieldById,
10126
+ httpHeadersField,
10127
+ control,
10128
+ handleSubmit,
10129
+ errors,
10130
+ watchedValues,
10131
+ celContext,
10132
+ initializing,
10133
+ fetchError,
10134
+ submitting,
10135
+ submitError,
10136
+ readOnly,
10137
+ isFieldVisible,
10138
+ isFieldDisabled,
10139
+ isGroupValid,
10140
+ groupHasData,
10141
+ onSubmit,
10142
+ setValue
10143
+ } = form;
10144
+ const displayGroups = React.useMemo(() => resolvedGroups.filter((g) => g.group.id !== "_required"), [resolvedGroups]);
10145
+ const [expandedSections, setExpandedSections] = React.useState(() => {
10146
+ const expanded = /* @__PURE__ */ new Set();
10147
+ for (let i = 0; i < displayGroups.length; i++) {
10148
+ if (!displayGroups[i].group.optional) {
10149
+ expanded.add(i);
10150
+ }
10151
+ }
10152
+ return expanded;
10153
+ });
10154
+ const hasExpandedForData = React.useRef(false);
10155
+ React.useMemo(() => {
10156
+ if (initializing || hasExpandedForData.current) {
10157
+ return;
10158
+ }
10159
+ hasExpandedForData.current = true;
10160
+ setExpandedSections((prev) => {
10161
+ const next = new Set(prev);
10162
+ for (let i = 0; i < displayGroups.length; i++) {
10163
+ if (groupHasData(displayGroups[i])) {
10164
+ next.add(i);
10165
+ }
10166
+ }
10167
+ return next;
10168
+ });
10169
+ }, [initializing, displayGroups, groupHasData]);
10170
+ const [activeSection, setActiveSection] = React.useState(0);
10171
+ const toggleSection = React.useCallback((index) => {
10172
+ setExpandedSections((prev) => {
10173
+ const next = new Set(prev);
10174
+ if (next.has(index)) {
10175
+ next.delete(index);
10176
+ } else {
10177
+ next.add(index);
10178
+ }
10179
+ return next;
10180
+ });
10181
+ }, []);
10182
+ const scrollToSection = React.useCallback(
10183
+ (index) => {
10184
+ setActiveSection(index);
10185
+ if (!expandedSections.has(index)) {
10186
+ setExpandedSections((prev) => new Set(prev).add(index));
10187
+ }
10188
+ const el = sectionRefs.current.get(index);
10189
+ if (el) {
10190
+ el.scrollIntoView({ behavior: "smooth", block: "start" });
10191
+ }
10192
+ },
10193
+ [expandedSections]
10194
+ );
10195
+ const sectionStates = React.useMemo(() => {
10196
+ return displayGroups.map((g, i) => {
10197
+ if (i === activeSection) {
10198
+ return "active";
10199
+ }
10200
+ if (!isGroupValid(g)) {
10201
+ return "error";
10202
+ }
10203
+ if (groupHasData(g)) {
10204
+ return "validated";
10205
+ }
10206
+ return "draft";
10207
+ });
10208
+ }, [displayGroups, activeSection, isGroupValid, groupHasData]);
10209
+ if (initializing) {
10210
+ return /* @__PURE__ */ React__default.default.createElement("div", { className: styles.loadingContainer }, /* @__PURE__ */ React__default.default.createElement(ui.Spinner, { size: "sm", inline: true }), " Loading configuration\u2026");
10211
+ }
10212
+ if (fetchError) {
10213
+ 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(
10214
+ ui.LinkButton,
10215
+ {
10216
+ variant: "secondary",
10217
+ size: "sm",
10218
+ icon: "external-link-alt",
10219
+ href: `/connections/datasources/edit/${dsUid}`
10220
+ },
10221
+ "Open datasource settings"
10222
+ )));
10223
+ }
10224
+ const allDisabled = submitting || readOnly;
10225
+ 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(
10226
+ SidebarNav,
10227
+ {
10228
+ groups: displayGroups,
10229
+ activeIndex: activeSection,
10230
+ sectionStates,
10231
+ onSelect: scrollToSection
10232
+ }
10233
+ ), /* @__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) => {
10234
+ const visibleFields = g.fields.filter(isFieldVisible);
10235
+ if (visibleFields.length === 0 && !httpHeadersField) {
10236
+ return null;
10237
+ }
10238
+ const showHeaders = httpHeadersField && (g.group.id === "auth" || g.group.id === "url-and-auth" || g.group.id === "_required" || g.group.fieldRefs.includes("httpHeaders"));
10239
+ 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"));
10240
+ return /* @__PURE__ */ React__default.default.createElement(
10241
+ "div",
10242
+ {
10243
+ key: g.group.id,
10244
+ ref: (el) => {
10245
+ if (el) {
10246
+ sectionRefs.current.set(i, el);
10247
+ }
10248
+ },
10249
+ className: styles.section
10250
+ },
10251
+ /* @__PURE__ */ React__default.default.createElement(
10252
+ ui.Collapse,
10253
+ {
10254
+ label: sectionLabel,
10255
+ isOpen: expandedSections.has(i),
10256
+ collapsible: true,
10257
+ onToggle: () => {
10258
+ toggleSection(i);
10259
+ setActiveSection(i);
10260
+ },
10261
+ className: styles.collapseHeader
10262
+ },
10263
+ /* @__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(
10264
+ SchemaField,
10265
+ {
10266
+ key: useDatasourceSchema.formKey(field),
10267
+ field,
10268
+ control,
10269
+ errors,
10270
+ disabled: allDisabled || isFieldDisabled(field),
10271
+ dsUid,
10272
+ watchedValues,
10273
+ fieldById,
10274
+ celContext,
10275
+ setValue
10276
+ }
10277
+ )), showHeaders && /* @__PURE__ */ React__default.default.createElement(
10278
+ AuthorizationHeaderField,
10279
+ {
10280
+ headersFieldKey: useDatasourceSchema.formKey(httpHeadersField),
10281
+ control,
10282
+ disabled: allDisabled,
10283
+ watchedValues
10284
+ }
10285
+ ))
10286
+ )
10287
+ );
10288
+ }), 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 }))))));
10289
+ }
10290
+
10291
+ function useDatasourceConfigForm({ schema, dsUid, onSuccess, onSaving }) {
10292
+ const [submitting, setSubmitting] = React.useState(false);
10293
+ const [submitError, setSubmitError] = React.useState(null);
10294
+ const [initializing, setInitializing] = React.useState(true);
10295
+ const [fetchError, setFetchError] = React.useState(null);
10296
+ const [detectedReadOnly, setDetectedReadOnly] = React.useState(false);
10297
+ const readOnly = detectedReadOnly;
10298
+ const resolvedGroups = React.useMemo(() => {
10299
+ const groups = useDatasourceSchema.resolveGroups(schema);
10300
+ const requiredGroup = useDatasourceSchema.resolveRequiredFieldsGroup(schema);
10301
+ if (!requiredGroup) {
10302
+ return groups;
10303
+ }
10304
+ return [requiredGroup, ...groups];
10305
+ }, [schema]);
10306
+ const fieldById = React.useMemo(() => {
10307
+ const m = /* @__PURE__ */ new Map();
10308
+ for (const f of schema.fields) {
10309
+ m.set(f.id, f);
10310
+ }
10311
+ return m;
10312
+ }, [schema.fields]);
10313
+ const httpHeadersField = React.useMemo(
10314
+ () => {
10315
+ var _a;
10316
+ return (_a = schema.fields.find((f) => {
10317
+ var _a2;
10318
+ return f.key === "httpHeaders" && ((_a2 = f.storage) == null ? void 0 : _a2.type) === "indexedPair";
10319
+ })) != null ? _a : null;
10320
+ },
10321
+ [schema.fields]
10322
+ );
10323
+ const allStorageFields = React.useMemo(
10324
+ () => schema.fields.filter((f) => f.kind !== "virtual" && !f.isItemField && f.target),
10325
+ [schema.fields]
10326
+ );
10327
+ const {
10328
+ control,
10329
+ handleSubmit,
10330
+ watch,
10331
+ reset,
10332
+ trigger,
10333
+ setValue,
10334
+ formState: { errors }
10335
+ } = reactHookForm.useForm({ mode: "onChange" });
10336
+ const fieldsWithEffects = React.useMemo(() => {
10337
+ const result = [];
10338
+ for (const field of schema.fields) {
10339
+ if (!field.effects || field.effects.length === 0) {
10340
+ continue;
10341
+ }
10342
+ const mapped = field.effects.map((eff) => ({
10343
+ when: eff.when,
10344
+ targets: Object.entries(eff.set).map(([targetId, val]) => {
10345
+ const targetField = fieldById.get(targetId);
10346
+ return { key: targetField ? useDatasourceSchema.formKey(targetField) : targetId, value: val };
10347
+ })
10348
+ }));
10349
+ result.push({ sourceKey: useDatasourceSchema.formKey(field), effects: mapped });
10350
+ }
10351
+ return result;
10352
+ }, [schema.fields, fieldById]);
10353
+ React.useEffect(() => {
10354
+ let cancelled = false;
10355
+ fetchExistingValues(dsUid, allStorageFields).then((result) => {
10356
+ if (cancelled) {
10357
+ return;
10358
+ }
10359
+ if (result.error) {
10360
+ setFetchError(result.error);
10361
+ setInitializing(false);
10362
+ return;
10363
+ }
10364
+ if (result.readOnly) {
10365
+ setDetectedReadOnly(true);
10366
+ }
10367
+ const defaults = {};
10368
+ for (const field of allStorageFields) {
10369
+ if (field.defaultValue !== void 0) {
10370
+ defaults[useDatasourceSchema.formKey(field)] = field.defaultValue;
10371
+ }
10372
+ }
10373
+ const merged = { ...defaults, ...result.values };
10374
+ const virtualValues = useDatasourceSchema.computeVirtualFieldValues(schema, merged);
10375
+ reset({ ...merged, ...virtualValues });
10376
+ setInitializing(false);
10377
+ });
10378
+ return () => {
10379
+ cancelled = true;
10380
+ };
10381
+ }, [dsUid, allStorageFields, schema, reset]);
10382
+ const watchedValues = watch();
10383
+ const prevEffectValuesRef = React.useRef({});
10384
+ React.useEffect(() => {
10385
+ if (initializing) {
10386
+ return;
10387
+ }
10388
+ for (const { sourceKey, effects } of fieldsWithEffects) {
10389
+ const currentVal = useDatasourceSchema.getWatchedValue(watchedValues, sourceKey);
10390
+ const prevVal = prevEffectValuesRef.current[sourceKey];
10391
+ if (currentVal === prevVal) {
10392
+ continue;
10393
+ }
10394
+ prevEffectValuesRef.current[sourceKey] = currentVal;
10395
+ for (const eff of effects) {
10396
+ if (evaluateEffectCondition(eff.when, currentVal)) {
10397
+ for (const { key, value } of eff.targets) {
10398
+ setValue(key, value);
10399
+ }
10400
+ break;
10401
+ }
10402
+ }
10403
+ }
10404
+ }, [watchedValues, fieldsWithEffects, initializing, setValue]);
10405
+ const fieldsWithOverrideDefaults = React.useMemo(() => {
10406
+ const result = [];
10407
+ for (const field of schema.fields) {
10408
+ if (!field.overrides || field.overrides.length === 0) {
10409
+ continue;
10410
+ }
10411
+ const ovs = field.overrides.filter((ov) => ov.defaultValue !== void 0).map((ov) => {
10412
+ const parsed = useDatasourceSchema.parseDependsOn(ov.when);
10413
+ if (!parsed) {
10414
+ return null;
10415
+ }
10416
+ const depField = fieldById.get(parsed.field);
10417
+ return {
10418
+ depKey: depField ? useDatasourceSchema.formKey(depField) : parsed.field,
10419
+ depValue: parsed.value,
10420
+ negate: parsed.negate,
10421
+ defaultValue: ov.defaultValue
10422
+ };
10423
+ }).filter(Boolean);
10424
+ if (ovs.length > 0) {
10425
+ result.push({ targetKey: useDatasourceSchema.formKey(field), fieldDefault: field.defaultValue, overrides: ovs });
10426
+ }
10427
+ }
10428
+ return result;
10429
+ }, [schema.fields, fieldById]);
10430
+ const prevOverrideDepRef = React.useRef({});
10431
+ React.useEffect(() => {
10432
+ var _a;
10433
+ if (initializing) {
10434
+ return;
10435
+ }
10436
+ for (const { targetKey, fieldDefault, overrides } of fieldsWithOverrideDefaults) {
10437
+ for (const ov of overrides) {
10438
+ const currentDepVal = String((_a = useDatasourceSchema.getWatchedValue(watchedValues, ov.depKey)) != null ? _a : "");
10439
+ const trackKey = `${targetKey}::${ov.depKey}`;
10440
+ const prevDepVal = prevOverrideDepRef.current[trackKey];
10441
+ if (currentDepVal === prevDepVal) {
10442
+ continue;
10443
+ }
10444
+ prevOverrideDepRef.current[trackKey] = currentDepVal;
10445
+ const active = useDatasourceSchema.evaluateDependsOn({ value: ov.depValue, negate: ov.negate }, currentDepVal);
10446
+ const wasActive = prevDepVal !== void 0 && useDatasourceSchema.evaluateDependsOn({ value: ov.depValue, negate: ov.negate }, prevDepVal);
10447
+ if (active) {
10448
+ setValue(targetKey, ov.defaultValue);
10449
+ } else if (wasActive && fieldDefault !== void 0) {
10450
+ setValue(targetKey, fieldDefault);
10451
+ }
10452
+ }
10453
+ }
10454
+ }, [watchedValues, fieldsWithOverrideDefaults, initializing, setValue]);
10455
+ const celContext = React.useMemo(() => {
10456
+ const ctx = {};
10457
+ for (const f of fieldById.values()) {
10458
+ const fk = useDatasourceSchema.formKey(f);
10459
+ const val = useDatasourceSchema.getWatchedValue(watchedValues, fk);
10460
+ if (val !== void 0) {
10461
+ const parts = f.id.split(".");
10462
+ let current = ctx;
10463
+ for (let i = 0; i < parts.length - 1; i++) {
10464
+ if (!(parts[i] in current) || typeof current[parts[i]] !== "object" || current[parts[i]] === null) {
10465
+ current[parts[i]] = {};
10466
+ }
10467
+ current = current[parts[i]];
10468
+ }
10469
+ current[parts[parts.length - 1]] = val;
10470
+ }
10471
+ }
10472
+ return ctx;
10473
+ }, [watchedValues, fieldById]);
10474
+ const isFieldVisible = React.useCallback(
10475
+ (field) => {
10476
+ function check(f, visited) {
10477
+ var _a;
10478
+ if (f.kind === "virtual" && !f.ui) {
10479
+ return false;
10480
+ }
10481
+ if ((_a = f.tags) == null ? void 0 : _a.some((t) => t.startsWith("managed-by:"))) {
10482
+ return false;
10483
+ }
10484
+ if (!f.dependsOn) {
10485
+ return true;
10486
+ }
10487
+ const refs = useDatasourceSchema.extractFieldRefs(f.dependsOn);
10488
+ for (const ref of refs) {
10489
+ const depField = fieldById.get(ref);
10490
+ if (depField && !visited.has(depField.id)) {
10491
+ visited.add(f.id);
10492
+ if (!check(depField, visited)) {
10493
+ return false;
10494
+ }
10495
+ }
10496
+ }
10497
+ return useDatasourceSchema.evaluateCelExpression(f.dependsOn, celContext);
10498
+ }
10499
+ return check(field, /* @__PURE__ */ new Set());
10500
+ },
10501
+ [celContext, fieldById]
10502
+ );
10503
+ const onSubmit = React.useCallback(
10504
+ async (data) => {
10505
+ setSubmitting(true);
10506
+ setSubmitError(null);
10507
+ onSaving == null ? void 0 : onSaving(true);
10508
+ const minDelay = new Promise((r) => setTimeout(r, 2e3));
10509
+ try {
10510
+ await submitDatasourceConfig(dsUid, data, allStorageFields, isFieldVisible);
10511
+ const [refreshed] = await Promise.all([fetchExistingValues(dsUid, allStorageFields), minDelay]);
10512
+ const defaults = {};
10513
+ for (const field of allStorageFields) {
10514
+ if (field.defaultValue !== void 0) {
10515
+ defaults[useDatasourceSchema.formKey(field)] = field.defaultValue;
10516
+ }
10517
+ }
10518
+ const merged = { ...defaults, ...refreshed.values };
10519
+ const virtualValues = useDatasourceSchema.computeVirtualFieldValues(schema, merged);
10520
+ reset({ ...merged, ...virtualValues });
10521
+ onSuccess("UPDATED", "Configuration saved.");
10522
+ } catch (err) {
10523
+ await minDelay;
10524
+ setSubmitError(err instanceof Error ? err.message : "Failed to update datasource");
10525
+ } finally {
10526
+ setSubmitting(false);
10527
+ onSaving == null ? void 0 : onSaving(false);
10528
+ }
10529
+ },
10530
+ [dsUid, allStorageFields, isFieldVisible, schema, reset, onSuccess, onSaving]
10531
+ );
10532
+ const isGroupValid = React.useCallback(
10533
+ (group) => {
10534
+ for (const field of group.fields) {
10535
+ if (!isFieldVisible(field)) {
10536
+ continue;
10537
+ }
10538
+ if (errors[useDatasourceSchema.formKey(field)]) {
10539
+ return false;
10540
+ }
10541
+ if (isFieldRequired(field, watchedValues, fieldById, celContext)) {
10542
+ const val = useDatasourceSchema.getWatchedValue(watchedValues, useDatasourceSchema.formKey(field));
10543
+ if (val === SECURE_FIELD_CONFIGURED) {
10544
+ continue;
10545
+ }
10546
+ if (val === void 0 || val === null || val === "") {
10547
+ return false;
10548
+ }
10549
+ }
10550
+ }
10551
+ return true;
10552
+ },
10553
+ [errors, watchedValues, fieldById, celContext, isFieldVisible]
10554
+ );
10555
+ const isFieldDisabled = React.useCallback(
10556
+ (field) => {
10557
+ if (!field.disabledWhen) {
10558
+ return false;
10559
+ }
10560
+ return useDatasourceSchema.evaluateCelExpression(field.disabledWhen, celContext);
10561
+ },
10562
+ [celContext]
10563
+ );
10564
+ const groupHasData = React.useCallback(
10565
+ (group) => {
10566
+ for (const field of group.fields) {
10567
+ const val = useDatasourceSchema.getWatchedValue(watchedValues, useDatasourceSchema.formKey(field));
10568
+ if (val === void 0 || val === null || val === "" || val === false) {
10569
+ continue;
10570
+ }
10571
+ if (val === field.defaultValue) {
10572
+ continue;
10573
+ }
10574
+ return true;
10575
+ }
10576
+ return false;
10577
+ },
10578
+ [watchedValues]
10579
+ );
10580
+ return {
10581
+ // Schema
10582
+ resolvedGroups,
10583
+ fieldById,
10584
+ httpHeadersField,
10585
+ // Form
10586
+ control,
10587
+ handleSubmit,
10588
+ trigger,
10589
+ errors,
10590
+ watchedValues,
10591
+ celContext,
10592
+ // State
10593
+ initializing,
10594
+ fetchError,
10595
+ submitting,
10596
+ submitError,
10597
+ readOnly,
10598
+ // Callbacks
10599
+ isFieldVisible,
10600
+ isFieldDisabled,
10601
+ isGroupValid,
10602
+ groupHasData,
10603
+ onSubmit,
10604
+ setValue
10605
+ };
10606
+ }
10607
+
10608
+ function DatasourceConfigWizard(props) {
10609
+ const { schema, dsUid, dsName, onSuccess, onSaving, onRetest, healthError, renderActions, mode = "tab" } = props;
10610
+ const form = useDatasourceConfigForm({ schema, dsUid, onSuccess, onSaving });
10611
+ if (mode === "tab") {
10612
+ return /* @__PURE__ */ React__default.default.createElement(
10613
+ TabLayout,
10614
+ {
10615
+ form,
10616
+ schema,
10617
+ dsUid,
10618
+ dsName,
10619
+ onRetest,
10620
+ healthError,
10621
+ renderActions
10622
+ }
10623
+ );
10624
+ }
10625
+ return /* @__PURE__ */ React__default.default.createElement(
10626
+ WizardLayout,
10627
+ {
10628
+ form,
10629
+ schema,
10630
+ dsUid,
10631
+ dsName,
10632
+ onRetest,
10633
+ healthError,
10634
+ renderActions
10635
+ }
10636
+ );
10637
+ }
10638
+ function WizardLayout({ form, schema, dsUid, dsName, onRetest, healthError, renderActions }) {
10639
+ var _a, _b, _c;
10640
+ const styles = ui.useStyles2(getWizardStyles);
10641
+ const [currentStep, setCurrentStep] = React.useState(0);
10642
+ const {
10643
+ resolvedGroups,
10644
+ fieldById,
10645
+ httpHeadersField,
10646
+ control,
10647
+ handleSubmit,
10648
+ trigger,
10649
+ errors,
10650
+ watchedValues,
10651
+ celContext,
10652
+ initializing,
10653
+ fetchError,
10654
+ submitting,
10655
+ submitError,
10656
+ readOnly,
10657
+ isFieldVisible,
10658
+ isFieldDisabled,
10659
+ onSubmit,
10660
+ setValue
10661
+ } = form;
10662
+ const arrowSteps = React.useMemo(() => {
10663
+ const requiredGroup = resolvedGroups.find((g) => g.group.id === "_required");
10664
+ if (!requiredGroup) {
10665
+ return new Set(resolvedGroups.map((_, i) => i));
10666
+ }
10667
+ const requiredFieldIds = new Set(requiredGroup.fields.map((f) => f.id));
10668
+ const steps = /* @__PURE__ */ new Set();
10669
+ for (let i = 0; i < resolvedGroups.length; i++) {
10670
+ const g = resolvedGroups[i];
10671
+ if (g.group.id === "_required" || g.fields.some((f) => !requiredFieldIds.has(f.id))) {
10672
+ steps.add(i);
10673
+ }
10674
+ }
10675
+ return steps;
10676
+ }, [resolvedGroups]);
10677
+ const currentResolved = resolvedGroups[currentStep];
10678
+ const isFirstStep = React.useMemo(() => {
10679
+ for (let i = 0; i < currentStep; i++) {
10680
+ if (arrowSteps.has(i)) {
10681
+ return false;
10682
+ }
10683
+ }
10684
+ return true;
10685
+ }, [currentStep, arrowSteps]);
10686
+ const isLastStep = React.useMemo(() => {
10687
+ for (let i = currentStep + 1; i < resolvedGroups.length; i++) {
10688
+ if (arrowSteps.has(i)) {
10689
+ return false;
10690
+ }
10691
+ }
10692
+ return true;
10693
+ }, [currentStep, arrowSteps, resolvedGroups.length]);
10694
+ const visibleFieldsForStep = React.useMemo(
10695
+ () => currentResolved ? currentResolved.fields.filter(isFieldVisible) : [],
10696
+ [currentResolved, isFieldVisible]
10697
+ );
10698
+ const currentGroupValid = React.useMemo(() => {
10699
+ if (!currentResolved) {
10700
+ return true;
10701
+ }
10702
+ for (const field of visibleFieldsForStep) {
10703
+ if (errors[useDatasourceSchema.formKey(field)]) {
10704
+ return false;
10705
+ }
10706
+ if (isFieldRequired(field, watchedValues, fieldById, celContext)) {
10707
+ const val = useDatasourceSchema.getWatchedValue(watchedValues, useDatasourceSchema.formKey(field));
10708
+ if (val === SECURE_FIELD_CONFIGURED) {
10709
+ continue;
10710
+ }
10711
+ if (val === void 0 || val === null || val === "") {
10712
+ return false;
10713
+ }
10714
+ }
10715
+ }
10716
+ return true;
10717
+ }, [currentResolved, errors, visibleFieldsForStep, watchedValues, fieldById, celContext]);
10718
+ const goNext = React.useCallback(async () => {
10719
+ if (!currentResolved) {
10720
+ return;
10721
+ }
10722
+ if (!readOnly) {
10723
+ const visibleKeys = visibleFieldsForStep.map((f) => useDatasourceSchema.formKey(f));
10724
+ const valid = await trigger(visibleKeys);
10725
+ if (!valid) {
10726
+ return;
10727
+ }
10728
+ }
10729
+ setCurrentStep((s) => {
10730
+ for (let i = s + 1; i < resolvedGroups.length; i++) {
10731
+ if (arrowSteps.has(i)) {
10732
+ return i;
10733
+ }
10734
+ }
10735
+ return s;
10736
+ });
10737
+ }, [currentResolved, visibleFieldsForStep, trigger, resolvedGroups.length, arrowSteps, readOnly]);
10738
+ const goPrev = React.useCallback(() => {
10739
+ setCurrentStep((s) => {
10740
+ for (let i = s - 1; i >= 0; i--) {
10741
+ if (arrowSteps.has(i)) {
10742
+ return i;
10743
+ }
10744
+ }
10745
+ return s;
10746
+ });
10747
+ }, [arrowSteps]);
10748
+ if (initializing) {
10749
+ return /* @__PURE__ */ React__default.default.createElement("div", { className: styles.container }, /* @__PURE__ */ React__default.default.createElement(ui.Spinner, { size: "sm", inline: true }), " Loading configuration...");
10750
+ }
10751
+ if (fetchError) {
10752
+ 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(
10753
+ ui.LinkButton,
10754
+ {
10755
+ variant: "secondary",
10756
+ size: "sm",
10757
+ icon: "external-link-alt",
10758
+ href: `/connections/datasources/edit/${dsUid}`
10759
+ },
10760
+ "Open datasource settings"
10761
+ )));
10762
+ }
10763
+ const allDisabled = submitting || readOnly;
10764
+ if (resolvedGroups.length === 0) {
10765
+ return null;
10766
+ }
10767
+ const currentGroup = currentResolved == null ? void 0 : currentResolved.group;
10768
+ 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(
10769
+ ui.Button,
10770
+ {
10771
+ variant: "secondary",
10772
+ fill: "text",
10773
+ size: "sm",
10774
+ icon: "angle-left",
10775
+ "aria-label": "Previous",
10776
+ onClick: goPrev,
10777
+ disabled: isFirstStep || submitting,
10778
+ type: "button"
10779
+ }
10780
+ )), /* @__PURE__ */ React__default.default.createElement(
10781
+ ui.Select,
10782
+ {
10783
+ options: resolvedGroups.map((g, i) => ({ label: g.group.title, value: i })),
10784
+ value: currentStep,
10785
+ onChange: (v) => {
10786
+ if (v) {
10787
+ setCurrentStep(v.value);
10788
+ }
10789
+ },
10790
+ disabled: submitting,
10791
+ width: 18
10792
+ }
10793
+ ), /* @__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(
10794
+ ui.Button,
10795
+ {
10796
+ variant: isLastStep || !readOnly && !currentGroupValid ? "secondary" : "primary",
10797
+ size: "sm",
10798
+ icon: "angle-right",
10799
+ "aria-label": "Next",
10800
+ onClick: goNext,
10801
+ disabled: isLastStep || submitting,
10802
+ type: "button"
10803
+ }
10804
+ )))), currentResolved && /* @__PURE__ */ React__default.default.createElement("form", { onSubmit: handleSubmit(onSubmit), className: styles.form }, visibleFieldsForStep.map((field) => /* @__PURE__ */ React__default.default.createElement(
10805
+ SchemaField,
10806
+ {
10807
+ key: useDatasourceSchema.formKey(field),
10808
+ field,
10809
+ control,
10810
+ errors,
10811
+ disabled: allDisabled || isFieldDisabled(field),
10812
+ dsUid,
10813
+ watchedValues,
10814
+ fieldById,
10815
+ celContext,
10816
+ setValue
10817
+ }
10818
+ )), (currentResolved.group.id === "_required" || currentResolved.group.id === "auth") && httpHeadersField && /* @__PURE__ */ React__default.default.createElement(
10819
+ AuthorizationHeaderField,
10820
+ {
10821
+ headersFieldKey: useDatasourceSchema.formKey(httpHeadersField),
10822
+ control,
10823
+ disabled: allDisabled,
10824
+ watchedValues
10825
+ }
10826
+ ), 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 })))));
10827
+ }
10828
+
10829
+ var __defProp$2 = Object.defineProperty;
10830
+ var __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
10831
+ var __publicField$2 = (obj, key, value) => __defNormalProp$2(obj, key + "" , value);
10832
+ class DatasourceErrorBoundary extends React.Component {
10833
+ constructor() {
10834
+ super(...arguments);
10835
+ __publicField$2(this, "state", { error: null });
10836
+ }
10837
+ static getDerivedStateFromError(error) {
10838
+ return { error };
10839
+ }
10840
+ componentDidCatch(error, info) {
10841
+ console.error("[DatasourceConfigWizard] Caught error:", error, info.componentStack);
10842
+ }
10843
+ render() {
10844
+ if (this.state.error) {
10845
+ 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.");
10846
+ }
10847
+ return this.props.children;
10848
+ }
10849
+ }
10850
+
10851
+ const MAX_CONCURRENCY = 5;
10852
+ function useHealthChecks() {
10853
+ const [healthMap, setHealthMap] = React.useState({});
10854
+ const queueRef = React.useRef([]);
10855
+ const activeRef = React.useRef(0);
10856
+ const mountedRef = React.useRef(true);
10857
+ const everQueuedRef = React.useRef(/* @__PURE__ */ new Set());
10858
+ const checkOne = React.useCallback(async (uid) => {
10859
+ if (!mountedRef.current) {
10860
+ return;
10861
+ }
10862
+ setHealthMap((prev) => ({ ...prev, [uid]: { state: "checking" } }));
10863
+ try {
10864
+ const result = await runtime.getBackendSrv().get(
10865
+ `/api/datasources/uid/${uid}/health`,
10866
+ void 0,
10867
+ void 0,
10868
+ { showErrorAlert: false }
10869
+ );
10870
+ if (!mountedRef.current) {
10871
+ return;
10872
+ }
10873
+ setHealthMap((prev) => {
10874
+ var _a;
10875
+ return {
10876
+ ...prev,
10877
+ [uid]: { state: "done", status: (_a = result.status) != null ? _a : "OK", message: result.message }
10878
+ };
10879
+ });
10880
+ } catch (error) {
10881
+ if (!mountedRef.current) {
10882
+ return;
10883
+ }
10884
+ let status = "ERROR";
10885
+ let message = "";
10886
+ if (error && typeof error === "object" && "data" in error) {
10887
+ const data = error.data;
10888
+ if (data == null ? void 0 : data.status) {
10889
+ status = data.status;
10890
+ }
10891
+ if (data == null ? void 0 : data.message) {
10892
+ message = data.message;
10893
+ }
10894
+ }
10895
+ if (!message) {
10896
+ message = error instanceof Error ? error.message : String(error);
10897
+ }
10898
+ setHealthMap((prev) => ({
10899
+ ...prev,
10900
+ [uid]: { state: "done", status, message }
10901
+ }));
10902
+ }
10903
+ }, []);
10904
+ const processQueue = React.useCallback(() => {
10905
+ while (activeRef.current < MAX_CONCURRENCY && queueRef.current.length > 0) {
10906
+ const uid = queueRef.current.shift();
10907
+ activeRef.current++;
10908
+ checkOne(uid).finally(() => {
10909
+ activeRef.current--;
10910
+ processQueue();
10911
+ });
10912
+ }
10913
+ }, [checkOne]);
10914
+ const checkUids = React.useCallback(
10915
+ (uids) => {
10916
+ const toCheck = [];
10917
+ for (const uid of uids) {
10918
+ if (everQueuedRef.current.has(uid)) {
10919
+ continue;
10920
+ }
10921
+ everQueuedRef.current.add(uid);
10922
+ toCheck.push(uid);
10923
+ }
10924
+ if (toCheck.length === 0) {
10925
+ return;
10926
+ }
10927
+ setHealthMap((prev) => {
10928
+ const next = { ...prev };
10929
+ for (const uid of toCheck) {
10930
+ next[uid] = { state: "pending" };
10931
+ }
10932
+ return next;
10933
+ });
10934
+ queueRef.current.push(...toCheck);
10935
+ processQueue();
10936
+ },
10937
+ [processQueue]
10938
+ );
10939
+ const retry = React.useCallback(
10940
+ (uid) => {
10941
+ everQueuedRef.current.delete(uid);
10942
+ everQueuedRef.current.add(uid);
10943
+ setHealthMap((prev) => ({ ...prev, [uid]: { state: "pending" } }));
10944
+ queueRef.current.push(uid);
10945
+ processQueue();
10946
+ },
10947
+ [processQueue]
10948
+ );
10949
+ return { healthMap, checkUids, retry };
10950
+ }
10951
+
10952
+ let pluginNameCache = null;
10953
+ function buildPluginNameCache() {
10954
+ var _a;
10955
+ if (pluginNameCache) {
10956
+ return pluginNameCache;
10957
+ }
10958
+ const map = /* @__PURE__ */ new Map();
10959
+ try {
10960
+ const list = runtime.getDataSourceSrv().getList();
10961
+ for (const ds of list) {
10962
+ if (((_a = ds.meta) == null ? void 0 : _a.name) && ds.type && !map.has(ds.type)) {
10963
+ map.set(ds.type, ds.meta.name);
10964
+ }
10965
+ }
10966
+ } catch (ex) {
10967
+ console.error(ex);
10968
+ }
10969
+ pluginNameCache = map;
10970
+ return map;
10971
+ }
10972
+ function resolvePluginName(pluginType) {
10973
+ var _a;
10974
+ const cache = buildPluginNameCache();
10975
+ return (_a = cache.get(pluginType)) != null ? _a : pluginType;
10976
+ }
10977
+
8392
10978
  var __defProp$1 = Object.defineProperty;
8393
10979
  var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
8394
10980
  var __publicField$1 = (obj, key, value) => __defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
@@ -9842,6 +12428,34 @@ const convertUnits = (queryStats) => {
9842
12428
  return text + suffix;
9843
12429
  };
9844
12430
 
12431
+ exports.ROOT_CONFIG_FIELDS = useDatasourceSchema.ROOT_CONFIG_FIELDS;
12432
+ exports.buildCelContext = useDatasourceSchema.buildCelContext;
12433
+ exports.buildCloneDatasourcePayload = useDatasourceSchema.buildCloneDatasourcePayload;
12434
+ exports.buildCreateDatasourcePayload = useDatasourceSchema.buildCreateDatasourcePayload;
12435
+ exports.buildUpdateDatasourcePayload = useDatasourceSchema.buildUpdateDatasourcePayload;
12436
+ exports.clearExpressionCache = useDatasourceSchema.clearExpressionCache;
12437
+ exports.computeVirtualFieldValues = useDatasourceSchema.computeVirtualFieldValues;
12438
+ exports.configToYaml = useDatasourceSchema.configToYaml;
12439
+ exports.datasourceToProvisioningYaml = useDatasourceSchema.datasourceToProvisioningYaml;
12440
+ exports.evaluateCelDirect = useDatasourceSchema.evaluateCelDirect;
12441
+ exports.evaluateCelExpression = useDatasourceSchema.evaluateCelExpression;
12442
+ exports.evaluateComputedRead = useDatasourceSchema.evaluateComputedRead;
12443
+ exports.evaluateDependsOn = useDatasourceSchema.evaluateDependsOn;
12444
+ exports.extractFieldRefs = useDatasourceSchema.extractFieldRefs;
12445
+ exports.fetchConfigSchema = useDatasourceSchema.fetchConfigSchema;
12446
+ exports.formKey = useDatasourceSchema.formKey;
12447
+ exports.formatYamlDiff = useDatasourceSchema.formatYamlDiff;
12448
+ exports.generateLLMHint = useDatasourceSchema.generateLLMHint;
12449
+ exports.generateTroubleshootingFields = useDatasourceSchema.generateTroubleshootingFields;
12450
+ exports.getConfigSchema = useDatasourceSchema.getConfigSchema;
12451
+ exports.getWatchedValue = useDatasourceSchema.getWatchedValue;
12452
+ exports.isValidCelExpression = useDatasourceSchema.isValidCelExpression;
12453
+ exports.parseDependsOn = useDatasourceSchema.parseDependsOn;
12454
+ exports.resolveActiveOverride = useDatasourceSchema.resolveActiveOverride;
12455
+ exports.resolveGroups = useDatasourceSchema.resolveGroups;
12456
+ exports.resolveRequiredFieldsGroup = useDatasourceSchema.resolveRequiredFieldsGroup;
12457
+ exports.toProvisioningYaml = useDatasourceSchema.toProvisioningYaml;
12458
+ exports.useDatasourceSchema = useDatasourceSchema.useDatasourceSchema;
9845
12459
  exports.AccessoryButton = AccessoryButton;
9846
12460
  exports.AdvancedHttpSettings = AdvancedHttpSettings;
9847
12461
  exports.Auth = Auth;
@@ -9861,6 +12475,8 @@ exports.DataLinks = DataLinks;
9861
12475
  exports.DataSourceDescription = DataSourceDescription;
9862
12476
  exports.DataSourcePicker = DataSourcePicker;
9863
12477
  exports.DatasetSelector = DatasetSelector;
12478
+ exports.DatasourceConfigWizard = DatasourceConfigWizard;
12479
+ exports.DatasourceErrorBoundary = DatasourceErrorBoundary;
9864
12480
  exports.DatePicker = DatePicker;
9865
12481
  exports.DatePickerWithInput = DatePickerWithInput;
9866
12482
  exports.DebounceInput = DebounceInput;
@@ -9914,5 +12530,7 @@ exports.formatDate = formatDate;
9914
12530
  exports.getStandardSQLCompletionProvider = getStandardSQLCompletionProvider;
9915
12531
  exports.grafanaStandardSQLLanguage = language;
9916
12532
  exports.grafanaStandardSQLLanguageConf = conf;
12533
+ exports.resolvePluginName = resolvePluginName;
9917
12534
  exports.toOption = toOption;
12535
+ exports.useHealthChecks = useHealthChecks;
9918
12536
  //# sourceMappingURL=index.cjs.map