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