@grafana/plugin-ui 0.15.0 → 0.16.0-dsconfig.a155abe
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/README.md +33 -0
- package/dist/cjs/index.cjs +16764 -9897
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/index.d.cts +719 -2
- package/dist/esm/_virtual/index.js +3 -5
- package/dist/esm/_virtual/index.js.map +1 -1
- package/dist/esm/async-query-data/DatasourceWithAsyncBackend.js +1 -1
- package/dist/esm/async-query-data/RunQueryButtons.js +5 -5
- package/dist/esm/async-query-data/RunQueryButtons.js.map +1 -1
- package/dist/esm/components/ConfigEditor/AdvancedSettings/AdvancedHttpSettings.js +1 -1
- package/dist/esm/components/ConfigEditor/Auth/Auth.js +1 -1
- package/dist/esm/components/ConfigEditor/Auth/auth-method/AuthMethodSettings.js +4 -4
- package/dist/esm/components/ConfigEditor/Auth/auth-method/AuthMethodSettings.js.map +1 -1
- package/dist/esm/components/ConfigEditor/Auth/auth-method/BasicAuth.js +1 -1
- package/dist/esm/components/ConfigEditor/Auth/custom-headers/CustomHeader.js +1 -1
- package/dist/esm/components/ConfigEditor/Auth/custom-headers/CustomHeaders.js +3 -3
- package/dist/esm/components/ConfigEditor/Auth/custom-headers/CustomHeaders.js.map +1 -1
- package/dist/esm/components/ConfigEditor/Auth/tls/SelfSignedCertificate.js +1 -1
- package/dist/esm/components/ConfigEditor/Auth/tls/SkipTLSVerification.js +1 -1
- package/dist/esm/components/ConfigEditor/Auth/tls/TLSClientAuth.js +1 -1
- package/dist/esm/components/ConfigEditor/Auth/tls/TLSSettings.js +1 -1
- package/dist/esm/components/ConfigEditor/Auth/tls/TLSSettingsSection.js +1 -1
- package/dist/esm/components/ConfigEditor/Auth/types.js +1 -1
- package/dist/esm/components/ConfigEditor/Auth/utils.js +1 -1
- package/dist/esm/components/ConfigEditor/ConfigSection/ConfigDescriptionLink.js +1 -1
- package/dist/esm/components/ConfigEditor/ConfigSection/ConfigSection.js +1 -1
- package/dist/esm/components/ConfigEditor/ConfigSection/ConfigSubSection.js +1 -1
- package/dist/esm/components/ConfigEditor/ConfigSection/GenericConfigSection.js +2 -2
- package/dist/esm/components/ConfigEditor/ConfigSection/GenericConfigSection.js.map +1 -1
- package/dist/esm/components/ConfigEditor/Connection/ConnectionSettings.js +1 -1
- package/dist/esm/components/ConfigEditor/DataSourceDescription.js +1 -1
- package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/DatasourceConfigWizard.js +217 -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/FieldInput.js +135 -0
- package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/FieldInput.js.map +1 -0
- package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/SchemaField.js +80 -0
- package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/SchemaField.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/TabLayout.js +155 -0
- package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/TabLayout.js.map +1 -0
- package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/cel.js +75 -0
- package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/cel.js.map +1 -0
- package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/config.js +262 -0
- package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/config.js.map +1 -0
- package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/datasource.js +354 -0
- package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/datasource.js.map +1 -0
- package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/fieldUtils.js +138 -0
- package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/fieldUtils.js.map +1 -0
- package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/hooks/formInterpreter.js +93 -0
- package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/hooks/formInterpreter.js.map +1 -0
- package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/hooks/useDatasourceConfigForm.js +253 -0
- package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/hooks/useDatasourceConfigForm.js.map +1 -0
- package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/hooks/useHealthChecks.js +106 -0
- package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/hooks/useHealthChecks.js.map +1 -0
- package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/inputs/AuthorizationHeaderField.js +52 -0
- package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/inputs/AuthorizationHeaderField.js.map +1 -0
- package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/inputs/ComplexFieldNote.js +26 -0
- package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/inputs/ComplexFieldNote.js.map +1 -0
- package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/inputs/FileUploadField.js +106 -0
- package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/inputs/FileUploadField.js.map +1 -0
- package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/inputs/IndexedPairEditor.js +124 -0
- package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/inputs/IndexedPairEditor.js.map +1 -0
- package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/inputs/ObjectArrayEditor.js +190 -0
- package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/inputs/ObjectArrayEditor.js.map +1 -0
- package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/inputs/PdcFieldNote.js +31 -0
- package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/inputs/PdcFieldNote.js.map +1 -0
- package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/inputs/PrimitiveInputs.js +103 -0
- package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/inputs/PrimitiveInputs.js.map +1 -0
- package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/inputs/SecureFieldInput.js +59 -0
- package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/inputs/SecureFieldInput.js.map +1 -0
- package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/inputs/StringArrayInput.js +80 -0
- package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/inputs/StringArrayInput.js.map +1 -0
- package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/layoutParts.js +82 -0
- package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/layoutParts.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/styles.js +340 -0
- package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/styles.js.map +1 -0
- package/dist/esm/components/ConfigEditor/SecureSocksProxyToggle.js +1 -1
- package/dist/esm/components/CustomHeadersSettings/CustomHeadersSettings.js +2 -2
- package/dist/esm/components/CustomHeadersSettings/CustomHeadersSettings.js.map +1 -1
- package/dist/esm/components/DataLinks/DataLink.js +3 -3
- package/dist/esm/components/DataLinks/DataLink.js.map +1 -1
- package/dist/esm/components/DataLinks/DataLinks.js +1 -1
- package/dist/esm/components/DataSourcePicker/DataSourcePicker.js +2 -2
- package/dist/esm/components/DataSourcePicker/DataSourcePicker.js.map +1 -1
- package/dist/esm/components/DatePicker/DatePicker.js +3 -3
- package/dist/esm/components/DatePicker/DatePicker.js.map +1 -1
- package/dist/esm/components/DatePickerWithInput/DatePickerWithInput.js +2 -2
- package/dist/esm/components/DatePickerWithInput/DatePickerWithInput.js.map +1 -1
- package/dist/esm/components/DebounceInput/DebounceInput.js +4 -4
- package/dist/esm/components/DebounceInput/DebounceInput.js.map +1 -1
- package/dist/esm/components/Plugins/PluginSignatureBadge.js +1 -1
- package/dist/esm/components/QueryEditor/AccessoryButton.js +1 -1
- package/dist/esm/components/QueryEditor/CatalogSelector.js +5 -5
- package/dist/esm/components/QueryEditor/CatalogSelector.js.map +1 -1
- package/dist/esm/components/QueryEditor/ConfirmModal.js +3 -3
- package/dist/esm/components/QueryEditor/ConfirmModal.js.map +1 -1
- package/dist/esm/components/QueryEditor/DatasetSelector.js +2 -2
- package/dist/esm/components/QueryEditor/DatasetSelector.js.map +1 -1
- package/dist/esm/components/QueryEditor/EditorField.js +1 -1
- package/dist/esm/components/QueryEditor/EditorFieldGroup.js +1 -1
- package/dist/esm/components/QueryEditor/EditorHeader.js +1 -1
- package/dist/esm/components/QueryEditor/EditorList.js +2 -2
- package/dist/esm/components/QueryEditor/EditorList.js.map +1 -1
- package/dist/esm/components/QueryEditor/EditorRow.js +1 -1
- package/dist/esm/components/QueryEditor/EditorRows.js +1 -1
- package/dist/esm/components/QueryEditor/EditorStack.js +1 -1
- package/dist/esm/components/QueryEditor/EditorSwitch.js +1 -1
- package/dist/esm/components/QueryEditor/FlexItem.js +1 -1
- package/dist/esm/components/QueryEditor/InlineSelect.js +2 -2
- package/dist/esm/components/QueryEditor/InlineSelect.js.map +1 -1
- package/dist/esm/components/QueryEditor/InputGroup.js +4 -4
- package/dist/esm/components/QueryEditor/InputGroup.js.map +1 -1
- package/dist/esm/components/QueryEditor/QueryEditor.js +6 -6
- package/dist/esm/components/QueryEditor/QueryEditor.js.map +1 -1
- package/dist/esm/components/QueryEditor/QueryHeader.js +4 -4
- package/dist/esm/components/QueryEditor/QueryHeader.js.map +1 -1
- package/dist/esm/components/QueryEditor/RunQueryButton.js +1 -1
- package/dist/esm/components/QueryEditor/Space.js +1 -1
- package/dist/esm/components/QueryEditor/TableSelector.js +1 -1
- package/dist/esm/components/QueryEditor/query-editor-raw/QueryEditorRaw.js +4 -4
- package/dist/esm/components/QueryEditor/query-editor-raw/QueryEditorRaw.js.map +1 -1
- package/dist/esm/components/QueryEditor/query-editor-raw/QueryToolbox.js +3 -3
- package/dist/esm/components/QueryEditor/query-editor-raw/QueryToolbox.js.map +1 -1
- package/dist/esm/components/QueryEditor/query-editor-raw/QueryValidator.js +5 -5
- package/dist/esm/components/QueryEditor/query-editor-raw/QueryValidator.js.map +1 -1
- package/dist/esm/components/QueryEditor/query-editor-raw/RawEditor.js +3 -3
- package/dist/esm/components/QueryEditor/query-editor-raw/RawEditor.js.map +1 -1
- package/dist/esm/components/QueryEditor/types.js +1 -1
- package/dist/esm/components/QueryEditor/utils/useSqlChange.js +2 -2
- package/dist/esm/components/QueryEditor/utils/useSqlChange.js.map +1 -1
- package/dist/esm/components/QueryEditor/visual-query-builder/AwesomeQueryBuilder.js +1 -1
- package/dist/esm/components/QueryEditor/visual-query-builder/EditorField.js +1 -1
- package/dist/esm/components/QueryEditor/visual-query-builder/EditorRow.js +1 -1
- package/dist/esm/components/QueryEditor/visual-query-builder/EditorRows.js +1 -1
- package/dist/esm/components/QueryEditor/visual-query-builder/GroupByRow.js +2 -2
- package/dist/esm/components/QueryEditor/visual-query-builder/GroupByRow.js.map +1 -1
- package/dist/esm/components/QueryEditor/visual-query-builder/OrderByRow.js +5 -5
- package/dist/esm/components/QueryEditor/visual-query-builder/OrderByRow.js.map +1 -1
- package/dist/esm/components/QueryEditor/visual-query-builder/Preview.js +1 -1
- package/dist/esm/components/QueryEditor/visual-query-builder/SQLGroupByRow.js +1 -1
- package/dist/esm/components/QueryEditor/visual-query-builder/SQLOrderByRow.js +1 -1
- package/dist/esm/components/QueryEditor/visual-query-builder/SQLSelectRow.js +1 -1
- package/dist/esm/components/QueryEditor/visual-query-builder/SQLWhereRow.js +1 -1
- package/dist/esm/components/QueryEditor/visual-query-builder/SelectRow.js +5 -5
- package/dist/esm/components/QueryEditor/visual-query-builder/SelectRow.js.map +1 -1
- package/dist/esm/components/QueryEditor/visual-query-builder/VisualEditor.js +1 -1
- package/dist/esm/components/QueryEditor/visual-query-builder/WhereRow.js +6 -6
- package/dist/esm/components/QueryEditor/visual-query-builder/WhereRow.js.map +1 -1
- package/dist/esm/components/QueryEditorRow/QueryEditorRow.js +1 -1
- package/dist/esm/components/SQLEditor/components/SQLEditor.js +6 -6
- package/dist/esm/components/SQLEditor/components/SQLEditor.js.map +1 -1
- package/dist/esm/components/SQLEditor/hooks/useLatestCallback.js +4 -4
- package/dist/esm/components/SQLEditor/hooks/useLatestCallback.js.map +1 -1
- package/dist/esm/components/Segment/Segment.js +4 -4
- package/dist/esm/components/Segment/Segment.js.map +1 -1
- package/dist/esm/components/VisualQueryBuilder/components/LabelFilterItem.js +5 -5
- package/dist/esm/components/VisualQueryBuilder/components/LabelFilterItem.js.map +1 -1
- package/dist/esm/components/VisualQueryBuilder/components/LabelFilters.js +3 -3
- package/dist/esm/components/VisualQueryBuilder/components/LabelFilters.js.map +1 -1
- package/dist/esm/components/VisualQueryBuilder/components/OperationEditor.js +1 -1
- package/dist/esm/components/VisualQueryBuilder/components/OperationEditorBody.js +4 -4
- package/dist/esm/components/VisualQueryBuilder/components/OperationEditorBody.js.map +1 -1
- package/dist/esm/components/VisualQueryBuilder/components/OperationExplainedBox.js +1 -1
- package/dist/esm/components/VisualQueryBuilder/components/OperationHeader.js +3 -3
- package/dist/esm/components/VisualQueryBuilder/components/OperationHeader.js.map +1 -1
- package/dist/esm/components/VisualQueryBuilder/components/OperationInfoButton.js +3 -3
- package/dist/esm/components/VisualQueryBuilder/components/OperationInfoButton.js.map +1 -1
- package/dist/esm/components/VisualQueryBuilder/components/OperationList.js +2 -2
- package/dist/esm/components/VisualQueryBuilder/components/OperationList.js.map +1 -1
- package/dist/esm/components/VisualQueryBuilder/components/OperationListExplained.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/QueryBuilderHints.js +2 -2
- package/dist/esm/components/VisualQueryBuilder/components/QueryBuilderHints.js.map +1 -1
- package/dist/esm/components/VisualQueryBuilder/components/QueryEditorModeToggle.js +1 -1
- package/dist/esm/components/VisualQueryBuilder/components/QueryHeaderSwitch.js +2 -2
- package/dist/esm/components/VisualQueryBuilder/components/QueryHeaderSwitch.js.map +1 -1
- package/dist/esm/components/VisualQueryBuilder/components/QueryOptionGroup.js +1 -1
- package/dist/esm/components/VisualQueryBuilder/components/RawQuery.js +1 -1
- package/dist/esm/components/VisualQueryBuilder/types.js +1 -1
- package/dist/esm/hooks/useDebounce.js +3 -3
- package/dist/esm/hooks/useDebounce.js.map +1 -1
- package/dist/esm/index.d.ts +719 -2
- package/dist/esm/index.js +11 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/node_modules/js-yaml/dist/js-yaml.js +3043 -0
- package/dist/esm/node_modules/js-yaml/dist/js-yaml.js.map +1 -0
- package/dist/esm/node_modules/react-hook-form/dist/index.esm.js +2766 -0
- package/dist/esm/node_modules/react-hook-form/dist/index.esm.js.map +1 -0
- package/dist/esm/node_modules/semver/classes/range.js +24 -4
- package/dist/esm/node_modules/semver/classes/range.js.map +1 -1
- package/dist/esm/node_modules/semver/classes/semver.js +19 -2
- package/dist/esm/node_modules/semver/classes/semver.js.map +1 -1
- package/dist/esm/node_modules/semver/functions/diff.js +1 -1
- package/dist/esm/node_modules/semver/functions/diff.js.map +1 -1
- package/dist/esm/node_modules/semver/functions/truncate.js +62 -0
- package/dist/esm/node_modules/semver/functions/truncate.js.map +1 -0
- package/dist/esm/node_modules/semver/index.js +3 -0
- package/dist/esm/node_modules/semver/index.js.map +1 -1
- package/dist/esm/node_modules/semver/internal/re.js +3 -3
- package/dist/esm/node_modules/semver/internal/re.js.map +1 -1
- package/dist/esm/node_modules/semver/ranges/subset.js +3 -3
- package/dist/esm/node_modules/semver/ranges/subset.js.map +1 -1
- package/dist/esm/node_modules/tslib/tslib.es6.js.map +1 -1
- package/dist/esm/schema/utils/constants.js +4 -0
- package/dist/esm/schema/utils/constants.js.map +1 -0
- package/dist/esm/schema/utils/dsconfig.js +97 -0
- package/dist/esm/schema/utils/dsconfig.js.map +1 -0
- package/dist/esm/schema/utils/llm.js +54 -0
- package/dist/esm/schema/utils/llm.js.map +1 -0
- package/dist/esm/schema/utils/packs.js +113 -0
- package/dist/esm/schema/utils/packs.js.map +1 -0
- package/dist/esm/schema/utils/provisioning.js +434 -0
- package/dist/esm/schema/utils/provisioning.js.map +1 -0
- package/dist/esm/schema/utils/registry.js +30 -0
- package/dist/esm/schema/utils/registry.js.map +1 -0
- package/dist/esm/schema/utils/useDatasourceSchema.js +39 -0
- package/dist/esm/schema/utils/useDatasourceSchema.js.map +1 -0
- package/package.json +15 -10
- package/dist/esm/_virtual/_commonjsHelpers.js +0 -6
- package/dist/esm/_virtual/_commonjsHelpers.js.map +0 -1
- package/dist/esm/_virtual/index2.js +0 -6
- package/dist/esm/_virtual/index2.js.map +0 -1
- package/dist/esm/_virtual/index3.js +0 -4
- package/dist/esm/_virtual/index3.js.map +0 -1
- package/dist/esm/_virtual/react.development.js +0 -4
- package/dist/esm/_virtual/react.development.js.map +0 -1
- package/dist/esm/_virtual/react.production.min.js +0 -4
- package/dist/esm/_virtual/react.production.min.js.map +0 -1
- package/dist/esm/node_modules/react/cjs/react.development.js +0 -2752
- package/dist/esm/node_modules/react/cjs/react.development.js.map +0 -1
- package/dist/esm/node_modules/react/cjs/react.production.min.js +0 -39
- package/dist/esm/node_modules/react/cjs/react.production.min.js.map +0 -1
- package/dist/esm/node_modules/react/index.js +0 -20
- package/dist/esm/node_modules/react/index.js.map +0 -1
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import React, { Component } from 'react';
|
|
2
|
+
import { Alert } from '@grafana/ui';
|
|
3
|
+
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
6
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, key + "" , value);
|
|
7
|
+
class DatasourceErrorBoundary extends Component {
|
|
8
|
+
constructor() {
|
|
9
|
+
super(...arguments);
|
|
10
|
+
__publicField(this, "state", { error: null });
|
|
11
|
+
}
|
|
12
|
+
static getDerivedStateFromError(error) {
|
|
13
|
+
return { error };
|
|
14
|
+
}
|
|
15
|
+
componentDidCatch(error, info) {
|
|
16
|
+
console.error("[DatasourceConfigWizard] Caught error:", error, info.componentStack);
|
|
17
|
+
}
|
|
18
|
+
render() {
|
|
19
|
+
if (this.state.error) {
|
|
20
|
+
return /* @__PURE__ */ React.createElement(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.");
|
|
21
|
+
}
|
|
22
|
+
return this.props.children;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export { DatasourceErrorBoundary };
|
|
27
|
+
//# sourceMappingURL=DatasourceErrorBoundary.js.map
|
package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/DatasourceErrorBoundary.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DatasourceErrorBoundary.js","sources":["../../../../../src/components/ConfigEditor/DatasourceConfigWizard/DatasourceErrorBoundary.tsx"],"sourcesContent":["import React, { Component, type ReactNode, type ErrorInfo } from 'react';\nimport { Alert } from '@grafana/ui';\n\n/** Lightweight error boundary scoped to datasource config widgets — won't crash the host UI. */\nexport class DatasourceErrorBoundary extends Component<\n { children: ReactNode; dsName?: string },\n { error: Error | null }\n> {\n state: { error: Error | null } = { error: null };\n\n static getDerivedStateFromError(error: Error) {\n return { error };\n }\n\n componentDidCatch(error: Error, info: ErrorInfo) {\n console.error('[DatasourceConfigWizard] Caught error:', error, info.componentStack);\n }\n\n render() {\n if (this.state.error) {\n return (\n <Alert severity=\"warning\" title=\"Configuration wizard unavailable\">\n Could not load the configuration wizard\n {this.props.dsName ? ` for ${this.props.dsName}` : ''}. Use the Settings link to configure this datasource\n manually.\n </Alert>\n );\n }\n return this.props.children;\n }\n}\n"],"names":[],"mappings":";;;;;;AAIO,MAAM,gCAAgC,SAG3C,CAAA;AAAA,EAHK,WAAA,GAAA;AAAA,IAAA,KAAA,CAAA,GAAA,SAAA,CAAA;AAIL,IAAiC,aAAA,CAAA,IAAA,EAAA,OAAA,EAAA,EAAE,OAAO,IAAK,EAAA,CAAA;AAAA;AAAA,EAE/C,OAAO,yBAAyB,KAAc,EAAA;AAC5C,IAAA,OAAO,EAAE,KAAM,EAAA;AAAA;AACjB,EAEA,iBAAA,CAAkB,OAAc,IAAiB,EAAA;AAC/C,IAAA,OAAA,CAAQ,KAAM,CAAA,wCAAA,EAA0C,KAAO,EAAA,IAAA,CAAK,cAAc,CAAA;AAAA;AACpF,EAEA,MAAS,GAAA;AACP,IAAI,IAAA,IAAA,CAAK,MAAM,KAAO,EAAA;AACpB,MAAA,2CACG,KAAM,EAAA,EAAA,QAAA,EAAS,SAAU,EAAA,KAAA,EAAM,sCAAmC,yCAEhE,EAAA,IAAA,CAAK,KAAM,CAAA,MAAA,GAAS,QAAQ,IAAK,CAAA,KAAA,CAAM,MAAM,CAAA,CAAA,GAAK,IAAG,gEAExD,CAAA;AAAA;AAGJ,IAAA,OAAO,KAAK,KAAM,CAAA,QAAA;AAAA;AAEtB;;;;"}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { SecureFieldInput } from './inputs/SecureFieldInput.js';
|
|
3
|
+
import { StringArrayInput } from './inputs/StringArrayInput.js';
|
|
4
|
+
import { IndexedPairEditor } from './inputs/IndexedPairEditor.js';
|
|
5
|
+
import { FileUploadField } from './inputs/FileUploadField.js';
|
|
6
|
+
import { ObjectArrayEditor } from './inputs/ObjectArrayEditor.js';
|
|
7
|
+
import { ComplexFieldNote } from './inputs/ComplexFieldNote.js';
|
|
8
|
+
import { RadioInput, SelectInput, BooleanInput, NumberInput, TextAreaInput, TextInput } from './inputs/PrimitiveInputs.js';
|
|
9
|
+
|
|
10
|
+
function resolveFieldInputKind(field, hasSetValue) {
|
|
11
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
|
|
12
|
+
if (((_a = field.ui) == null ? undefined : _a.component) === "fileUpload" && field.ui.fileMapping && hasSetValue) {
|
|
13
|
+
return "fileUpload";
|
|
14
|
+
}
|
|
15
|
+
if (field.target === "secureJsonData") {
|
|
16
|
+
return "secure";
|
|
17
|
+
}
|
|
18
|
+
if (((_b = field.ui) == null ? undefined : _b.component) === "radio") {
|
|
19
|
+
return "radio";
|
|
20
|
+
}
|
|
21
|
+
if (((_c = field.ui) == null ? undefined : _c.component) === "select") {
|
|
22
|
+
return "select";
|
|
23
|
+
}
|
|
24
|
+
if (field.valueType === "boolean") {
|
|
25
|
+
return "boolean";
|
|
26
|
+
}
|
|
27
|
+
if (field.valueType === "number") {
|
|
28
|
+
return "number";
|
|
29
|
+
}
|
|
30
|
+
if (((_d = field.ui) == null ? undefined : _d.component) === "textarea") {
|
|
31
|
+
return "textarea";
|
|
32
|
+
}
|
|
33
|
+
if (((_e = field.storage) == null ? undefined : _e.type) === "indexedPair") {
|
|
34
|
+
return "indexedPair";
|
|
35
|
+
}
|
|
36
|
+
if (field.valueType === "array" && ((_f = field.item) == null ? undefined : _f.valueType) === "string") {
|
|
37
|
+
return "stringArray";
|
|
38
|
+
}
|
|
39
|
+
if (field.valueType === "array" && ((_g = field.item) == null ? undefined : _g.valueType) === "object" && ((_h = field.item.fields) == null ? undefined : _h.length)) {
|
|
40
|
+
return "objectArray";
|
|
41
|
+
}
|
|
42
|
+
if (field.valueType === "object" || field.valueType === "map" || field.valueType === "array" && (((_i = field.item) == null ? undefined : _i.valueType) === "object" || ((_j = field.item) == null ? undefined : _j.valueType) === "map")) {
|
|
43
|
+
return "complex";
|
|
44
|
+
}
|
|
45
|
+
return "text";
|
|
46
|
+
}
|
|
47
|
+
function SecureInput({ field, formField, disabled }) {
|
|
48
|
+
var _a, _b, _c;
|
|
49
|
+
const label = (_a = field.label) != null ? _a : field.key;
|
|
50
|
+
return /* @__PURE__ */ React.createElement(
|
|
51
|
+
SecureFieldInput,
|
|
52
|
+
{
|
|
53
|
+
formField,
|
|
54
|
+
placeholder: (_c = (_b = field.ui) == null ? undefined : _b.placeholder) != null ? _c : label,
|
|
55
|
+
disabled,
|
|
56
|
+
label
|
|
57
|
+
}
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
function FileUploadInput({ field, formField, disabled, setValue }) {
|
|
61
|
+
if (!setValue) {
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
return /* @__PURE__ */ React.createElement(FileUploadField, { field, formField, disabled, setValue });
|
|
65
|
+
}
|
|
66
|
+
function IndexedPairInput({ field, formField, disabled }) {
|
|
67
|
+
var _a, _b, _c, _d, _e;
|
|
68
|
+
const items = Array.isArray(formField.value) ? formField.value : [];
|
|
69
|
+
const maxItems = (_c = (_b = (_a = field.validations) == null ? undefined : _a.find((v) => v.type === "itemCount")) == null ? undefined : _b.max) != null ? _c : 10;
|
|
70
|
+
const itemLabel = (_e = (_d = field.label) == null ? undefined : _d.toLowerCase().replace(/s$/, "")) != null ? _e : "header";
|
|
71
|
+
return /* @__PURE__ */ React.createElement(
|
|
72
|
+
IndexedPairEditor,
|
|
73
|
+
{
|
|
74
|
+
value: items,
|
|
75
|
+
onChange: formField.onChange,
|
|
76
|
+
maxItems,
|
|
77
|
+
disabled,
|
|
78
|
+
itemLabel
|
|
79
|
+
}
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
function StringArrayField({ field, formField, disabled }) {
|
|
83
|
+
var _a, _b;
|
|
84
|
+
const label = (_a = field.label) != null ? _a : field.key;
|
|
85
|
+
return /* @__PURE__ */ React.createElement(
|
|
86
|
+
StringArrayInput,
|
|
87
|
+
{
|
|
88
|
+
value: Array.isArray(formField.value) ? formField.value : [],
|
|
89
|
+
onChange: formField.onChange,
|
|
90
|
+
placeholder: (_b = field.ui) == null ? undefined : _b.placeholder,
|
|
91
|
+
disabled,
|
|
92
|
+
itemLabel: label.toLowerCase().replace(/s$/, "")
|
|
93
|
+
}
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
function ObjectArrayInput({ field, formField, disabled, errorMessage }) {
|
|
97
|
+
return /* @__PURE__ */ React.createElement(
|
|
98
|
+
ObjectArrayEditor,
|
|
99
|
+
{
|
|
100
|
+
field,
|
|
101
|
+
value: formField.value,
|
|
102
|
+
onChange: formField.onChange,
|
|
103
|
+
disabled,
|
|
104
|
+
errorMessage
|
|
105
|
+
}
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
function ComplexInput({ field, formField }) {
|
|
109
|
+
var _a;
|
|
110
|
+
const label = (_a = field.label) != null ? _a : field.key;
|
|
111
|
+
const count = Array.isArray(formField.value) ? formField.value.length : 0;
|
|
112
|
+
return /* @__PURE__ */ React.createElement(ComplexFieldNote, { count, label });
|
|
113
|
+
}
|
|
114
|
+
const FIELD_INPUTS = {
|
|
115
|
+
fileUpload: FileUploadInput,
|
|
116
|
+
secure: SecureInput,
|
|
117
|
+
radio: RadioInput,
|
|
118
|
+
select: SelectInput,
|
|
119
|
+
boolean: BooleanInput,
|
|
120
|
+
number: NumberInput,
|
|
121
|
+
textarea: TextAreaInput,
|
|
122
|
+
indexedPair: IndexedPairInput,
|
|
123
|
+
stringArray: StringArrayField,
|
|
124
|
+
objectArray: ObjectArrayInput,
|
|
125
|
+
complex: ComplexInput,
|
|
126
|
+
text: TextInput
|
|
127
|
+
};
|
|
128
|
+
function FieldInput(props) {
|
|
129
|
+
const kind = resolveFieldInputKind(props.field, props.setValue !== undefined);
|
|
130
|
+
const Component = FIELD_INPUTS[kind];
|
|
131
|
+
return /* @__PURE__ */ React.createElement(Component, { ...props });
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export { FieldInput, resolveFieldInputKind };
|
|
135
|
+
//# sourceMappingURL=FieldInput.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FieldInput.js","sources":["../../../../../src/components/ConfigEditor/DatasourceConfigWizard/FieldInput.tsx"],"sourcesContent":["import React from 'react';\nimport type { ConfigField } from '../../../schema/schema';\nimport type { IndexedPairItem } from './datasource';\nimport type { FieldInputProps } from './inputs/types';\nimport { SecureFieldInput } from './inputs/SecureFieldInput';\nimport { StringArrayInput } from './inputs/StringArrayInput';\nimport { IndexedPairEditor } from './inputs/IndexedPairEditor';\nimport { FileUploadField } from './inputs/FileUploadField';\nimport { ObjectArrayEditor } from './inputs/ObjectArrayEditor';\nimport { ComplexFieldNote } from './inputs/ComplexFieldNote';\nimport { TextInput, NumberInput, BooleanInput, TextAreaInput, SelectInput, RadioInput } from './inputs/PrimitiveInputs';\n\nexport type { FieldInputProps };\n\n/** Discriminant identifying which input component renders a field. */\nexport type FieldInputKind =\n | 'fileUpload'\n | 'secure'\n | 'radio'\n | 'select'\n | 'boolean'\n | 'number'\n | 'textarea'\n | 'indexedPair'\n | 'stringArray'\n | 'objectArray'\n | 'complex'\n | 'text';\n\n/**\n * Resolve a field to its input kind.\n *\n * Order matters: earlier rules win. Cross-cutting storage concerns (secure\n * storage, indexed-pair storage) intentionally take precedence over\n * `valueType`, and an explicit `ui.component` (radio/select/textarea) takes\n * precedence over the type-derived default. `fileUpload` requires `setValue`\n * because it distributes parsed values across sibling fields.\n */\nexport function resolveFieldInputKind(field: ConfigField, hasSetValue: boolean): FieldInputKind {\n if (field.ui?.component === 'fileUpload' && field.ui.fileMapping && hasSetValue) {\n return 'fileUpload';\n }\n if (field.target === 'secureJsonData') {\n return 'secure';\n }\n if (field.ui?.component === 'radio') {\n return 'radio';\n }\n if (field.ui?.component === 'select') {\n return 'select';\n }\n if (field.valueType === 'boolean') {\n return 'boolean';\n }\n if (field.valueType === 'number') {\n return 'number';\n }\n if (field.ui?.component === 'textarea') {\n return 'textarea';\n }\n if (field.storage?.type === 'indexedPair') {\n return 'indexedPair';\n }\n if (field.valueType === 'array' && field.item?.valueType === 'string') {\n return 'stringArray';\n }\n if (field.valueType === 'array' && field.item?.valueType === 'object' && field.item.fields?.length) {\n return 'objectArray';\n }\n if (\n field.valueType === 'object' ||\n field.valueType === 'map' ||\n (field.valueType === 'array' && (field.item?.valueType === 'object' || field.item?.valueType === 'map'))\n ) {\n return 'complex';\n }\n return 'text';\n}\n\n// ── Adapters: map the normalized FieldInputProps onto each leaf component's own API ──\n\n/** Password/token stored in secureJsonData. */\nfunction SecureInput({ field, formField, disabled }: FieldInputProps) {\n const label = field.label ?? field.key;\n return (\n <SecureFieldInput\n formField={formField}\n placeholder={field.ui?.placeholder ?? label}\n disabled={disabled}\n label={label}\n />\n );\n}\n\n/** JSON file upload that distributes parsed keys across sibling fields. */\nfunction FileUploadInput({ field, formField, disabled, setValue }: FieldInputProps) {\n // Only reachable when setValue exists (see resolveFieldInputKind), but guard anyway.\n if (!setValue) {\n return null;\n }\n return <FileUploadField field={field} formField={formField} disabled={disabled} setValue={setValue} />;\n}\n\n/** Editable key/value list backed by indexed storage (e.g. HTTP headers). */\nfunction IndexedPairInput({ field, formField, disabled }: FieldInputProps) {\n const items = Array.isArray(formField.value) ? (formField.value as IndexedPairItem[]) : [];\n const maxItems =\n field.validations?.find((v): v is { type: 'itemCount'; max?: number } => v.type === 'itemCount')?.max ?? 10;\n const itemLabel = field.label?.toLowerCase().replace(/s$/, '') ?? 'header';\n return (\n <IndexedPairEditor\n value={items}\n onChange={formField.onChange}\n maxItems={maxItems}\n disabled={disabled}\n itemLabel={itemLabel}\n />\n );\n}\n\n/** Row-based editor for an array of strings. */\nfunction StringArrayField({ field, formField, disabled }: FieldInputProps) {\n const label = field.label ?? field.key;\n return (\n <StringArrayInput\n value={Array.isArray(formField.value) ? (formField.value as string[]) : []}\n onChange={formField.onChange}\n placeholder={field.ui?.placeholder}\n disabled={disabled}\n itemLabel={label.toLowerCase().replace(/s$/, '')}\n />\n );\n}\n\n/** Inline editor for an array of objects with defined item fields. */\nfunction ObjectArrayInput({ field, formField, disabled, errorMessage }: FieldInputProps) {\n return (\n <ObjectArrayEditor\n field={field}\n value={formField.value}\n onChange={formField.onChange}\n disabled={disabled}\n errorMessage={errorMessage}\n />\n );\n}\n\n/** Read-only note for complex shapes not editable in the wizard. */\nfunction ComplexInput({ field, formField }: FieldInputProps) {\n const label = field.label ?? field.key;\n const count = Array.isArray(formField.value) ? formField.value.length : 0;\n return <ComplexFieldNote count={count} label={label} />;\n}\n\n/** Registry mapping each resolved kind to its renderer. */\nconst FIELD_INPUTS: Record<FieldInputKind, React.ComponentType<FieldInputProps>> = {\n fileUpload: FileUploadInput,\n secure: SecureInput,\n radio: RadioInput,\n select: SelectInput,\n boolean: BooleanInput,\n number: NumberInput,\n textarea: TextAreaInput,\n indexedPair: IndexedPairInput,\n stringArray: StringArrayField,\n objectArray: ObjectArrayInput,\n complex: ComplexInput,\n text: TextInput,\n};\n\n/**\n * Render the appropriate input for a schema field.\n *\n * Replaces the former `renderFieldInput` switch with a resolver + component\n * registry: each input is an independently testable component, and adding a\n * new input means extending the registry rather than editing a growing\n * conditional.\n */\nexport function FieldInput(props: FieldInputProps) {\n const kind = resolveFieldInputKind(props.field, props.setValue !== undefined);\n const Component = FIELD_INPUTS[kind];\n return <Component {...props} />;\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Controller } from '../../../node_modules/react-hook-form/dist/index.esm.js';
|
|
3
|
+
import { useStyles2, Tooltip, Icon } from '@grafana/ui';
|
|
4
|
+
import { resolveActiveOverride, formKey } from './config.js';
|
|
5
|
+
import { isFieldRequired, buildValidationRules, parseItemErrors } from './fieldUtils.js';
|
|
6
|
+
import { PdcFieldNote } from './inputs/PdcFieldNote.js';
|
|
7
|
+
import { FieldInput } from './FieldInput.js';
|
|
8
|
+
import { getFieldStyles } from './styles.js';
|
|
9
|
+
|
|
10
|
+
function SchemaField({
|
|
11
|
+
field,
|
|
12
|
+
control,
|
|
13
|
+
errors,
|
|
14
|
+
disabled,
|
|
15
|
+
dsUid,
|
|
16
|
+
watchedValues,
|
|
17
|
+
fieldById,
|
|
18
|
+
celContext,
|
|
19
|
+
setValue
|
|
20
|
+
}) {
|
|
21
|
+
const styles = useStyles2(getFieldStyles);
|
|
22
|
+
const activeOverride = resolveActiveOverride(field, watchedValues, fieldById);
|
|
23
|
+
const fk = formKey(field);
|
|
24
|
+
if (field.key === "pdcInjected" && field.target === "jsonData") {
|
|
25
|
+
return /* @__PURE__ */ React.createElement(
|
|
26
|
+
Controller,
|
|
27
|
+
{
|
|
28
|
+
name: fk,
|
|
29
|
+
control,
|
|
30
|
+
render: ({ field: formField }) => /* @__PURE__ */ React.createElement(
|
|
31
|
+
PdcFieldNote,
|
|
32
|
+
{
|
|
33
|
+
enabled: !!formField.value,
|
|
34
|
+
description: field.description,
|
|
35
|
+
configUrl: `/connections/datasources/edit/${dsUid}`
|
|
36
|
+
}
|
|
37
|
+
)
|
|
38
|
+
}
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
const required = isFieldRequired(field, watchedValues, fieldById, celContext);
|
|
42
|
+
const validationRules = buildValidationRules(field, required);
|
|
43
|
+
return /* @__PURE__ */ React.createElement(
|
|
44
|
+
Controller,
|
|
45
|
+
{
|
|
46
|
+
name: fk,
|
|
47
|
+
control,
|
|
48
|
+
rules: validationRules,
|
|
49
|
+
render: ({ field: formField }) => {
|
|
50
|
+
var _a, _b, _c, _d, _e;
|
|
51
|
+
const errorMessage = (_a = errors[fk]) == null ? undefined : _a.message;
|
|
52
|
+
const label = (_b = field.label) != null ? _b : field.key;
|
|
53
|
+
const description = (_c = activeOverride == null ? undefined : activeOverride.description) != null ? _c : field.description;
|
|
54
|
+
const effectiveField = activeOverride ? {
|
|
55
|
+
...field,
|
|
56
|
+
description,
|
|
57
|
+
ui: {
|
|
58
|
+
...field.ui,
|
|
59
|
+
placeholder: (_e = activeOverride.placeholder) != null ? _e : (_d = field.ui) == null ? undefined : _d.placeholder
|
|
60
|
+
}
|
|
61
|
+
} : field;
|
|
62
|
+
const isReadOnly = !!(activeOverride == null ? undefined : activeOverride.readOnly);
|
|
63
|
+
const isBool = field.valueType === "boolean";
|
|
64
|
+
return /* @__PURE__ */ React.createElement("div", { className: isBool ? styles.fieldRowCenter : styles.fieldRow }, /* @__PURE__ */ React.createElement("div", { className: isBool ? styles.fieldLabelRowCompact : styles.fieldLabelRow }, /* @__PURE__ */ React.createElement("span", { className: styles.fieldLabel }, label, required && /* @__PURE__ */ React.createElement("span", { className: styles.fieldRequired }, "*")), description && /* @__PURE__ */ React.createElement(Tooltip, { content: description }, /* @__PURE__ */ React.createElement(Icon, { name: "info-circle", size: "xs", className: styles.fieldInfoIcon }))), /* @__PURE__ */ React.createElement("div", { className: styles.fieldInputCol }, /* @__PURE__ */ React.createElement(
|
|
65
|
+
FieldInput,
|
|
66
|
+
{
|
|
67
|
+
field: effectiveField,
|
|
68
|
+
formField,
|
|
69
|
+
disabled: disabled || isReadOnly,
|
|
70
|
+
errorMessage,
|
|
71
|
+
setValue
|
|
72
|
+
}
|
|
73
|
+
), errorMessage && !parseItemErrors(errorMessage) && /* @__PURE__ */ React.createElement("span", { className: styles.fieldError }, errorMessage)));
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export { SchemaField };
|
|
80
|
+
//# sourceMappingURL=SchemaField.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SchemaField.js","sources":["../../../../../src/components/ConfigEditor/DatasourceConfigWizard/SchemaField.tsx"],"sourcesContent":["import React from 'react';\nimport { type useForm, Controller } from 'react-hook-form';\nimport { useStyles2, Icon, Tooltip } from '@grafana/ui';\nimport type { ConfigField } from '../../../schema/schema';\nimport { resolveActiveOverride, formKey } from './config';\nimport type { FormValues } from './datasource';\nimport { isFieldRequired, buildValidationRules, parseItemErrors } from './fieldUtils';\nimport { PdcFieldNote } from './inputs/PdcFieldNote';\nimport { FieldInput } from './FieldInput';\nimport { getFieldStyles } from './styles';\n\nexport type SchemaFieldProps = {\n field: ConfigField;\n control: ReturnType<typeof useForm<FormValues>>['control'];\n errors: ReturnType<typeof useForm<FormValues>>['formState']['errors'];\n disabled?: boolean;\n dsUid: string;\n watchedValues: Record<string, unknown>;\n fieldById: Map<string, ConfigField>;\n celContext?: Record<string, unknown>;\n setValue?: (name: string, value: unknown) => void;\n};\n\nexport function SchemaField({\n field,\n control,\n errors,\n disabled,\n dsUid,\n watchedValues,\n fieldById,\n celContext,\n setValue,\n}: SchemaFieldProps) {\n const styles = useStyles2(getFieldStyles);\n\n const activeOverride = resolveActiveOverride(field, watchedValues, fieldById);\n const fk = formKey(field);\n\n if (field.key === 'pdcInjected' && field.target === 'jsonData') {\n return (\n <Controller\n name={fk}\n control={control}\n render={({ field: formField }) => (\n <PdcFieldNote\n enabled={!!formField.value}\n description={field.description}\n configUrl={`/connections/datasources/edit/${dsUid}`}\n />\n )}\n />\n );\n }\n\n const required = isFieldRequired(field, watchedValues, fieldById, celContext);\n const validationRules = buildValidationRules(field, required);\n\n return (\n <Controller\n name={fk}\n control={control}\n rules={validationRules}\n render={({ field: formField }) => {\n const errorMessage = errors[fk]?.message as string | undefined;\n const label = field.label ?? field.key;\n const description = activeOverride?.description ?? field.description;\n const effectiveField = activeOverride\n ? {\n ...field,\n description,\n ui: {\n ...field.ui,\n placeholder: activeOverride.placeholder ?? field.ui?.placeholder,\n } as ConfigField['ui'],\n }\n : field;\n const isReadOnly = !!activeOverride?.readOnly;\n const isBool = field.valueType === 'boolean';\n\n return (\n <div className={isBool ? styles.fieldRowCenter : styles.fieldRow}>\n <div className={isBool ? styles.fieldLabelRowCompact : styles.fieldLabelRow}>\n <span className={styles.fieldLabel}>\n {label}\n {required && <span className={styles.fieldRequired}>*</span>}\n </span>\n {description && (\n <Tooltip content={description}>\n <Icon name=\"info-circle\" size=\"xs\" className={styles.fieldInfoIcon} />\n </Tooltip>\n )}\n </div>\n <div className={styles.fieldInputCol}>\n <FieldInput\n field={effectiveField}\n formField={formField}\n disabled={disabled || isReadOnly}\n errorMessage={errorMessage}\n setValue={setValue}\n />\n {/* Show global error only if it's NOT a per-item error (those render inline) */}\n {errorMessage && !parseItemErrors(errorMessage) && (\n <span className={styles.fieldError}>{errorMessage}</span>\n )}\n </div>\n </div>\n );\n }}\n />\n );\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { cx } from '@emotion/css';
|
|
3
|
+
import { useStyles2 } from '@grafana/ui';
|
|
4
|
+
import { getTabStyles } from './styles.js';
|
|
5
|
+
|
|
6
|
+
function SidebarNav({ groups, activeIndex, sectionStates, onSelect }) {
|
|
7
|
+
const styles = useStyles2(getTabStyles);
|
|
8
|
+
const visibleGroups = groups.filter((g) => g.group.id !== "_required");
|
|
9
|
+
return /* @__PURE__ */ React.createElement("nav", { className: styles.sidebar }, /* @__PURE__ */ React.createElement("div", { className: styles.sidebarTitle }, "Connect data source"), /* @__PURE__ */ React.createElement("ul", { className: styles.navList }, visibleGroups.map((g, vi) => {
|
|
10
|
+
var _a, _b;
|
|
11
|
+
const origIndex = groups.indexOf(g);
|
|
12
|
+
const state = (_a = sectionStates[origIndex]) != null ? _a : "draft";
|
|
13
|
+
const isActive = origIndex === activeIndex;
|
|
14
|
+
const isOptional = g.group.optional === true;
|
|
15
|
+
const isLast = vi === visibleGroups.length - 1;
|
|
16
|
+
const nextIsOptional = !isLast && ((_b = visibleGroups[vi + 1]) == null ? undefined : _b.group.optional) === true;
|
|
17
|
+
return /* @__PURE__ */ React.createElement("li", { key: g.group.id }, /* @__PURE__ */ React.createElement(
|
|
18
|
+
"div",
|
|
19
|
+
{
|
|
20
|
+
className: cx(styles.navItem, isActive && styles.navItemActive),
|
|
21
|
+
onClick: () => onSelect(origIndex),
|
|
22
|
+
role: "button",
|
|
23
|
+
tabIndex: 0,
|
|
24
|
+
onKeyDown: (e) => {
|
|
25
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
26
|
+
e.preventDefault();
|
|
27
|
+
onSelect(origIndex);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
/* @__PURE__ */ React.createElement("div", { className: styles.navDotWrap }, /* @__PURE__ */ React.createElement(
|
|
32
|
+
"span",
|
|
33
|
+
{
|
|
34
|
+
className: cx(
|
|
35
|
+
styles.navDot,
|
|
36
|
+
isOptional && styles.navDotOptional,
|
|
37
|
+
isActive && styles.navDotActive,
|
|
38
|
+
state === "validated" && !isActive && styles.navDotValidated,
|
|
39
|
+
state === "error" && !isActive && styles.navDotError
|
|
40
|
+
)
|
|
41
|
+
}
|
|
42
|
+
), !isLast && /* @__PURE__ */ React.createElement(
|
|
43
|
+
"div",
|
|
44
|
+
{
|
|
45
|
+
className: cx(styles.navConnector, (isOptional || nextIsOptional) && styles.navConnectorDashed)
|
|
46
|
+
}
|
|
47
|
+
)),
|
|
48
|
+
/* @__PURE__ */ React.createElement("span", { className: cx(styles.navLabel, isActive && styles.navLabelActive) }, g.group.title)
|
|
49
|
+
));
|
|
50
|
+
})));
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export { SidebarNav };
|
|
54
|
+
//# sourceMappingURL=SidebarNav.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SidebarNav.js","sources":["../../../../../src/components/ConfigEditor/DatasourceConfigWizard/SidebarNav.tsx"],"sourcesContent":["import React from 'react';\nimport { cx } from '@emotion/css';\nimport { useStyles2 } from '@grafana/ui';\nimport type { ResolvedGroup } from './hooks/useDatasourceConfigForm';\nimport { getTabStyles } from './styles';\n\nexport type SectionState = 'active' | 'draft' | 'validated' | 'error';\n\ntype SidebarNavProps = {\n groups: ResolvedGroup[];\n activeIndex: number;\n sectionStates: SectionState[];\n onSelect: (index: number) => void;\n};\n\nexport function SidebarNav({ groups, activeIndex, sectionStates, onSelect }: SidebarNavProps) {\n const styles = useStyles2(getTabStyles);\n\n // Filter out _required synthetic group\n const visibleGroups = groups.filter((g) => g.group.id !== '_required');\n\n return (\n <nav className={styles.sidebar}>\n <div className={styles.sidebarTitle}>Connect data source</div>\n <ul className={styles.navList}>\n {visibleGroups.map((g, vi) => {\n // Map back to original index for state/selection\n const origIndex = groups.indexOf(g);\n const state = sectionStates[origIndex] ?? 'draft';\n const isActive = origIndex === activeIndex;\n const isOptional = g.group.optional === true;\n const isLast = vi === visibleGroups.length - 1;\n // Next item determines connector style\n const nextIsOptional = !isLast && visibleGroups[vi + 1]?.group.optional === true;\n\n return (\n <li key={g.group.id}>\n <div\n className={cx(styles.navItem, isActive && styles.navItemActive)}\n onClick={() => onSelect(origIndex)}\n role=\"button\"\n tabIndex={0}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n onSelect(origIndex);\n }\n }}\n >\n <div className={styles.navDotWrap}>\n <span\n className={cx(\n styles.navDot,\n isOptional && styles.navDotOptional,\n isActive && styles.navDotActive,\n state === 'validated' && !isActive && styles.navDotValidated,\n state === 'error' && !isActive && styles.navDotError\n )}\n />\n {!isLast && (\n <div\n className={cx(styles.navConnector, (isOptional || nextIsOptional) && styles.navConnectorDashed)}\n />\n )}\n </div>\n <span className={cx(styles.navLabel, isActive && styles.navLabelActive)}>{g.group.title}</span>\n </div>\n </li>\n );\n })}\n </ul>\n </nav>\n );\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import React, { useRef, useMemo, useState, useCallback } from 'react';
|
|
2
|
+
import { useStyles2, Spinner, Icon, Collapse } from '@grafana/ui';
|
|
3
|
+
import { isAuthGroupId } from './config.js';
|
|
4
|
+
import { FetchErrorState, GroupFields, FormFooter } from './layoutParts.js';
|
|
5
|
+
import { SidebarNav } from './SidebarNav.js';
|
|
6
|
+
import { getTabStyles } from './styles.js';
|
|
7
|
+
|
|
8
|
+
function TabLayout({ form, schema, dsUid, dsName, onRetest, healthError, renderActions }) {
|
|
9
|
+
const styles = useStyles2(getTabStyles);
|
|
10
|
+
const sectionRefs = useRef(/* @__PURE__ */ new Map());
|
|
11
|
+
const {
|
|
12
|
+
resolvedGroups,
|
|
13
|
+
httpHeadersField,
|
|
14
|
+
handleSubmit,
|
|
15
|
+
initializing,
|
|
16
|
+
fetchError,
|
|
17
|
+
submitting,
|
|
18
|
+
readOnly,
|
|
19
|
+
isFieldVisible,
|
|
20
|
+
isGroupValid,
|
|
21
|
+
groupHasData,
|
|
22
|
+
onSubmit
|
|
23
|
+
} = form;
|
|
24
|
+
const displayGroups = useMemo(() => resolvedGroups.filter((g) => g.group.id !== "_required"), [resolvedGroups]);
|
|
25
|
+
const [expandedSections, setExpandedSections] = useState(() => {
|
|
26
|
+
const expanded = /* @__PURE__ */ new Set();
|
|
27
|
+
for (let i = 0; i < displayGroups.length; i++) {
|
|
28
|
+
if (!displayGroups[i].group.optional) {
|
|
29
|
+
expanded.add(i);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return expanded;
|
|
33
|
+
});
|
|
34
|
+
const hasExpandedForData = useRef(false);
|
|
35
|
+
useMemo(() => {
|
|
36
|
+
if (initializing || hasExpandedForData.current) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
hasExpandedForData.current = true;
|
|
40
|
+
setExpandedSections((prev) => {
|
|
41
|
+
const next = new Set(prev);
|
|
42
|
+
for (let i = 0; i < displayGroups.length; i++) {
|
|
43
|
+
if (groupHasData(displayGroups[i])) {
|
|
44
|
+
next.add(i);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return next;
|
|
48
|
+
});
|
|
49
|
+
}, [initializing, displayGroups, groupHasData]);
|
|
50
|
+
const [activeSection, setActiveSection] = useState(0);
|
|
51
|
+
const toggleSection = useCallback((index) => {
|
|
52
|
+
setExpandedSections((prev) => {
|
|
53
|
+
const next = new Set(prev);
|
|
54
|
+
if (next.has(index)) {
|
|
55
|
+
next.delete(index);
|
|
56
|
+
} else {
|
|
57
|
+
next.add(index);
|
|
58
|
+
}
|
|
59
|
+
return next;
|
|
60
|
+
});
|
|
61
|
+
}, []);
|
|
62
|
+
const scrollToSection = useCallback(
|
|
63
|
+
(index) => {
|
|
64
|
+
setActiveSection(index);
|
|
65
|
+
if (!expandedSections.has(index)) {
|
|
66
|
+
setExpandedSections((prev) => new Set(prev).add(index));
|
|
67
|
+
}
|
|
68
|
+
const el = sectionRefs.current.get(index);
|
|
69
|
+
if (el) {
|
|
70
|
+
el.scrollIntoView({ behavior: "smooth", block: "start" });
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
[expandedSections]
|
|
74
|
+
);
|
|
75
|
+
const sectionStates = useMemo(() => {
|
|
76
|
+
return displayGroups.map((g, i) => {
|
|
77
|
+
if (i === activeSection) {
|
|
78
|
+
return "active";
|
|
79
|
+
}
|
|
80
|
+
if (!isGroupValid(g)) {
|
|
81
|
+
return "error";
|
|
82
|
+
}
|
|
83
|
+
if (groupHasData(g)) {
|
|
84
|
+
return "validated";
|
|
85
|
+
}
|
|
86
|
+
return "draft";
|
|
87
|
+
});
|
|
88
|
+
}, [displayGroups, activeSection, isGroupValid, groupHasData]);
|
|
89
|
+
if (initializing) {
|
|
90
|
+
return /* @__PURE__ */ React.createElement("div", { className: styles.loadingContainer }, /* @__PURE__ */ React.createElement(Spinner, { size: "sm", inline: true }), " Loading configuration\u2026");
|
|
91
|
+
}
|
|
92
|
+
if (fetchError) {
|
|
93
|
+
return /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement(FetchErrorState, { error: fetchError, dsUid, buttonClassName: styles.formButtons }));
|
|
94
|
+
}
|
|
95
|
+
return /* @__PURE__ */ React.createElement("div", { className: styles.root }, submitting && /* @__PURE__ */ React.createElement("div", { className: styles.overlay }, /* @__PURE__ */ React.createElement(Spinner, { size: "sm" }), /* @__PURE__ */ React.createElement("span", null, "Saving & testing\u2026")), /* @__PURE__ */ React.createElement(
|
|
96
|
+
SidebarNav,
|
|
97
|
+
{
|
|
98
|
+
groups: displayGroups,
|
|
99
|
+
activeIndex: activeSection,
|
|
100
|
+
sectionStates,
|
|
101
|
+
onSelect: scrollToSection
|
|
102
|
+
}
|
|
103
|
+
), /* @__PURE__ */ React.createElement("div", { className: styles.main }, readOnly && /* @__PURE__ */ React.createElement("div", { className: styles.readOnlyBanner }, /* @__PURE__ */ React.createElement(Icon, { name: "lock", size: "xs" }), /* @__PURE__ */ React.createElement("span", null, "Read-only \u2014 managed externally")), /* @__PURE__ */ React.createElement("div", { className: styles.requiredNotice }, "Fields marked with * are required"), /* @__PURE__ */ React.createElement("form", { onSubmit: handleSubmit(onSubmit), className: styles.form }, displayGroups.map((g, i) => {
|
|
104
|
+
const visibleFields = g.fields.filter(isFieldVisible);
|
|
105
|
+
if (visibleFields.length === 0 && !httpHeadersField) {
|
|
106
|
+
return null;
|
|
107
|
+
}
|
|
108
|
+
const showHeaders = Boolean(
|
|
109
|
+
httpHeadersField && (isAuthGroupId(g.group.id) || g.group.id === "url-and-auth" || g.group.id === "_required" || g.group.fieldRefs.includes("httpHeaders"))
|
|
110
|
+
);
|
|
111
|
+
const sectionLabel = /* @__PURE__ */ React.createElement("span", { className: styles.sectionLabel }, /* @__PURE__ */ React.createElement("span", { className: styles.sectionLabelText }, g.group.title), g.group.optional && /* @__PURE__ */ React.createElement("span", { className: styles.sectionBadge }, "Optional"));
|
|
112
|
+
return /* @__PURE__ */ React.createElement(
|
|
113
|
+
"div",
|
|
114
|
+
{
|
|
115
|
+
key: g.group.id,
|
|
116
|
+
ref: (el) => {
|
|
117
|
+
if (el) {
|
|
118
|
+
sectionRefs.current.set(i, el);
|
|
119
|
+
}
|
|
120
|
+
},
|
|
121
|
+
className: styles.section
|
|
122
|
+
},
|
|
123
|
+
/* @__PURE__ */ React.createElement(
|
|
124
|
+
Collapse,
|
|
125
|
+
{
|
|
126
|
+
label: sectionLabel,
|
|
127
|
+
isOpen: expandedSections.has(i),
|
|
128
|
+
collapsible: true,
|
|
129
|
+
onToggle: () => {
|
|
130
|
+
toggleSection(i);
|
|
131
|
+
setActiveSection(i);
|
|
132
|
+
},
|
|
133
|
+
className: styles.collapseHeader
|
|
134
|
+
},
|
|
135
|
+
/* @__PURE__ */ React.createElement("div", { className: styles.sectionBody }, g.group.description && /* @__PURE__ */ React.createElement("div", { className: styles.sectionDescription }, g.group.description), /* @__PURE__ */ React.createElement(GroupFields, { group: g, form, dsUid, showAuthHeaders: showHeaders }))
|
|
136
|
+
)
|
|
137
|
+
);
|
|
138
|
+
}), /* @__PURE__ */ React.createElement(
|
|
139
|
+
FormFooter,
|
|
140
|
+
{
|
|
141
|
+
form,
|
|
142
|
+
schema,
|
|
143
|
+
dsUid,
|
|
144
|
+
dsName,
|
|
145
|
+
onRetest,
|
|
146
|
+
healthError,
|
|
147
|
+
renderActions,
|
|
148
|
+
saveDisabled: submitting,
|
|
149
|
+
className: styles.formButtons
|
|
150
|
+
}
|
|
151
|
+
))));
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
export { TabLayout };
|
|
155
|
+
//# sourceMappingURL=TabLayout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TabLayout.js","sources":["../../../../../src/components/ConfigEditor/DatasourceConfigWizard/TabLayout.tsx"],"sourcesContent":["import React, { type ReactNode, useCallback, useMemo, useRef, useState } from 'react';\nimport { useStyles2, Icon, Spinner, Collapse } from '@grafana/ui';\nimport type { DatasourceConfigSchema } from '../../../schema/schema';\nimport { isAuthGroupId } from './config';\nimport type { useDatasourceConfigForm } from './hooks/useDatasourceConfigForm';\nimport { GroupFields, FormFooter, FetchErrorState } from './layoutParts';\nimport { SidebarNav, type SectionState } from './SidebarNav';\nimport { getTabStyles } from './styles';\n\ntype TabLayoutProps = {\n form: ReturnType<typeof useDatasourceConfigForm>;\n schema: DatasourceConfigSchema;\n dsUid: string;\n dsName: string;\n onRetest?: () => void;\n healthError?: string;\n renderActions?: (props: { dsUid: string; dsName: string; dsType: string; healthError?: string }) => ReactNode;\n};\n\nexport function TabLayout({ form, schema, dsUid, dsName, onRetest, healthError, renderActions }: TabLayoutProps) {\n const styles = useStyles2(getTabStyles);\n const sectionRefs = useRef<Map<number, HTMLDivElement>>(new Map());\n\n const {\n resolvedGroups,\n httpHeadersField,\n handleSubmit,\n initializing,\n fetchError,\n submitting,\n readOnly,\n isFieldVisible,\n isGroupValid,\n groupHasData,\n onSubmit,\n } = form;\n\n // Filter out _required synthetic group — in tab mode we show all groups from schema directly\n const displayGroups = useMemo(() => resolvedGroups.filter((g) => g.group.id !== '_required'), [resolvedGroups]);\n\n // Expand/collapse state: required or groups with data start expanded, optional start collapsed\n const [expandedSections, setExpandedSections] = useState<Set<number>>(() => {\n const expanded = new Set<number>();\n for (let i = 0; i < displayGroups.length; i++) {\n if (!displayGroups[i].group.optional) {\n expanded.add(i);\n }\n }\n return expanded;\n });\n\n // Re-evaluate on data load: expand sections that have saved data\n const hasExpandedForData = useRef(false);\n useMemo(() => {\n if (initializing || hasExpandedForData.current) {\n return;\n }\n hasExpandedForData.current = true;\n setExpandedSections((prev) => {\n const next = new Set(prev);\n for (let i = 0; i < displayGroups.length; i++) {\n if (groupHasData(displayGroups[i])) {\n next.add(i);\n }\n }\n return next;\n });\n }, [initializing, displayGroups, groupHasData]);\n\n const [activeSection, setActiveSection] = useState(0);\n\n const toggleSection = useCallback((index: number) => {\n setExpandedSections((prev) => {\n const next = new Set(prev);\n if (next.has(index)) {\n next.delete(index);\n } else {\n next.add(index);\n }\n return next;\n });\n }, []);\n\n const scrollToSection = useCallback(\n (index: number) => {\n setActiveSection(index);\n if (!expandedSections.has(index)) {\n setExpandedSections((prev) => new Set(prev).add(index));\n }\n const el = sectionRefs.current.get(index);\n if (el) {\n el.scrollIntoView({ behavior: 'smooth', block: 'start' });\n }\n },\n [expandedSections]\n );\n\n // Compute sidebar states\n const sectionStates: SectionState[] = useMemo(() => {\n return displayGroups.map((g, i) => {\n if (i === activeSection) {\n return 'active';\n }\n if (!isGroupValid(g)) {\n return 'error';\n }\n if (groupHasData(g)) {\n return 'validated';\n }\n return 'draft';\n });\n }, [displayGroups, activeSection, isGroupValid, groupHasData]);\n\n if (initializing) {\n return (\n <div className={styles.loadingContainer}>\n <Spinner size=\"sm\" inline /> Loading configuration…\n </div>\n );\n }\n\n if (fetchError) {\n return (\n <div>\n <FetchErrorState error={fetchError} dsUid={dsUid} buttonClassName={styles.formButtons} />\n </div>\n );\n }\n\n return (\n <div className={styles.root}>\n {submitting && (\n <div className={styles.overlay}>\n <Spinner size=\"sm\" />\n <span>Saving & testing…</span>\n </div>\n )}\n\n <SidebarNav\n groups={displayGroups}\n activeIndex={activeSection}\n sectionStates={sectionStates}\n onSelect={scrollToSection}\n />\n\n <div className={styles.main}>\n {readOnly && (\n <div className={styles.readOnlyBanner}>\n <Icon name=\"lock\" size=\"xs\" />\n <span>Read-only — managed externally</span>\n </div>\n )}\n\n <div className={styles.requiredNotice}>Fields marked with * are required</div>\n\n <form onSubmit={handleSubmit(onSubmit)} className={styles.form}>\n {displayGroups.map((g, i) => {\n const visibleFields = g.fields.filter(isFieldVisible);\n if (visibleFields.length === 0 && !httpHeadersField) {\n return null;\n }\n\n const showHeaders = Boolean(\n httpHeadersField &&\n (isAuthGroupId(g.group.id) ||\n g.group.id === 'url-and-auth' ||\n g.group.id === '_required' ||\n g.group.fieldRefs.includes('httpHeaders'))\n );\n\n const sectionLabel = (\n <span className={styles.sectionLabel}>\n <span className={styles.sectionLabelText}>{g.group.title}</span>\n {g.group.optional && <span className={styles.sectionBadge}>Optional</span>}\n </span>\n );\n\n return (\n <div\n key={g.group.id}\n ref={(el) => {\n if (el) {\n sectionRefs.current.set(i, el);\n }\n }}\n className={styles.section}\n >\n <Collapse\n label={sectionLabel}\n isOpen={expandedSections.has(i)}\n collapsible\n onToggle={() => {\n toggleSection(i);\n setActiveSection(i);\n }}\n className={styles.collapseHeader}\n >\n <div className={styles.sectionBody}>\n {g.group.description && <div className={styles.sectionDescription}>{g.group.description}</div>}\n <GroupFields group={g} form={form} dsUid={dsUid} showAuthHeaders={showHeaders} />\n </div>\n </Collapse>\n </div>\n );\n })}\n\n <FormFooter\n form={form}\n schema={schema}\n dsUid={dsUid}\n dsName={dsName}\n onRetest={onRetest}\n healthError={healthError}\n renderActions={renderActions}\n saveDisabled={submitting}\n className={styles.formButtons}\n />\n </form>\n </div>\n </div>\n );\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { evaluate, parse } from '@marcbachmann/cel-js';
|
|
2
|
+
|
|
3
|
+
const exprCache = /* @__PURE__ */ new Map();
|
|
4
|
+
function getCompiled(expr) {
|
|
5
|
+
if (exprCache.has(expr)) {
|
|
6
|
+
return exprCache.get(expr);
|
|
7
|
+
}
|
|
8
|
+
try {
|
|
9
|
+
const compiled = parse(expr);
|
|
10
|
+
exprCache.set(expr, compiled);
|
|
11
|
+
return compiled;
|
|
12
|
+
} catch (e) {
|
|
13
|
+
exprCache.set(expr, null);
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
function buildCelContext(values) {
|
|
18
|
+
const ctx = {};
|
|
19
|
+
for (const [key, value] of Object.entries(values)) {
|
|
20
|
+
setNestedValue(ctx, key, value);
|
|
21
|
+
}
|
|
22
|
+
return ctx;
|
|
23
|
+
}
|
|
24
|
+
function setNestedValue(obj, path, value) {
|
|
25
|
+
const parts = path.split(".");
|
|
26
|
+
let current = obj;
|
|
27
|
+
for (let i = 0; i < parts.length - 1; i++) {
|
|
28
|
+
const part = parts[i];
|
|
29
|
+
if (!(part in current) || typeof current[part] !== "object" || current[part] === null) {
|
|
30
|
+
current[part] = {};
|
|
31
|
+
}
|
|
32
|
+
current = current[part];
|
|
33
|
+
}
|
|
34
|
+
current[parts[parts.length - 1]] = value;
|
|
35
|
+
}
|
|
36
|
+
function evaluateCelExpression(expr, context, defaultValue = false) {
|
|
37
|
+
if (!expr || !expr.trim()) {
|
|
38
|
+
return defaultValue;
|
|
39
|
+
}
|
|
40
|
+
const compiled = getCompiled(expr);
|
|
41
|
+
if (!compiled) {
|
|
42
|
+
return defaultValue;
|
|
43
|
+
}
|
|
44
|
+
try {
|
|
45
|
+
const result = compiled(context);
|
|
46
|
+
return !!result;
|
|
47
|
+
} catch (e) {
|
|
48
|
+
return defaultValue;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
function evaluateCelDirect(expr, context) {
|
|
52
|
+
return evaluate(expr, context);
|
|
53
|
+
}
|
|
54
|
+
function isValidCelExpression(expr) {
|
|
55
|
+
try {
|
|
56
|
+
parse(expr);
|
|
57
|
+
return true;
|
|
58
|
+
} catch (e) {
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
function extractFieldRefs(expr) {
|
|
63
|
+
const matches = expr.matchAll(/([\w.]+)\s*(?:==|!=)/g);
|
|
64
|
+
const refs = /* @__PURE__ */ new Set();
|
|
65
|
+
for (const m of matches) {
|
|
66
|
+
refs.add(m[1]);
|
|
67
|
+
}
|
|
68
|
+
return [...refs];
|
|
69
|
+
}
|
|
70
|
+
function clearExpressionCache() {
|
|
71
|
+
exprCache.clear();
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export { buildCelContext, clearExpressionCache, evaluateCelDirect, evaluateCelExpression, extractFieldRefs, isValidCelExpression };
|
|
75
|
+
//# sourceMappingURL=cel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cel.js","sources":["../../../../../src/components/ConfigEditor/DatasourceConfigWizard/cel.ts"],"sourcesContent":["/**\n * CEL (Common Expression Language) expression evaluator for schema conditions.\n *\n * Used by `dependsOn`, `requiredWhen`, `disabledWhen`, and `overrides[].when`.\n * Wraps @marcbachmann/cel-js with field-ID-aware context building.\n *\n * Go equivalent: github.com/google/cel-go\n */\n\nimport { evaluate as celEvaluate, parse as celParse } from '@marcbachmann/cel-js';\n\n// ============================================================\n// Expression cache — parse once, evaluate many times\n// ============================================================\n\ntype CompiledExpr = (ctx: Record<string, unknown>) => unknown;\nconst exprCache = new Map<string, CompiledExpr | null>();\n\nfunction getCompiled(expr: string): CompiledExpr | null {\n if (exprCache.has(expr)) {\n return exprCache.get(expr)!;\n }\n try {\n const compiled = celParse(expr);\n exprCache.set(expr, compiled);\n return compiled;\n } catch {\n exprCache.set(expr, null);\n return null;\n }\n}\n\n// ============================================================\n// Context builder — flat field values → nested object for CEL\n// ============================================================\n\n/**\n * Build a nested context object from flat form values keyed by field IDs.\n *\n * CEL interprets dots as property access, so `jsonData.auth_method == 'oauth2'`\n * requires `{ jsonData: { auth_method: 'oauth2' } }`.\n *\n * This function takes flat key-value pairs (from react-hook-form `watch()`)\n * and builds the nested structure CEL expects.\n *\n * @param values - Flat map of form keys to values (e.g. `{ \"auth_method\": \"oauth2\", \"oauth2.oauth2_type\": \"jwt\" }`)\n * @param fieldIdToFormKey - Optional map from field ID to form key for translation\n */\nexport function buildCelContext(values: Record<string, unknown>): Record<string, unknown> {\n const ctx: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(values)) {\n setNestedValue(ctx, key, value);\n }\n\n return ctx;\n}\n\nfunction setNestedValue(obj: Record<string, unknown>, path: string, value: unknown): void {\n const parts = path.split('.');\n let current = obj;\n for (let i = 0; i < parts.length - 1; i++) {\n const part = parts[i];\n if (!(part in current) || typeof current[part] !== 'object' || current[part] === null) {\n current[part] = {};\n }\n current = current[part] as Record<string, unknown>;\n }\n current[parts[parts.length - 1]] = value;\n}\n\n// ============================================================\n// Public API\n// ============================================================\n\n/**\n * Evaluate a CEL expression against a context of field values.\n * Returns the boolean result, or `defaultValue` if the expression is invalid.\n *\n * @example\n * ```ts\n * evaluateCelExpression(\"jsonData.auth_method == 'oauth2'\", { jsonData: { auth_method: 'oauth2' } })\n * // => true\n *\n * evaluateCelExpression(\"auth_method == 'oauth2' && oauth2_type == 'jwt'\", { auth_method: 'oauth2', oauth2_type: 'jwt' })\n * // => true\n * ```\n */\nexport function evaluateCelExpression(expr: string, context: Record<string, unknown>, defaultValue = false): boolean {\n if (!expr || !expr.trim()) {\n return defaultValue;\n }\n\n const compiled = getCompiled(expr);\n if (!compiled) {\n return defaultValue;\n }\n\n try {\n const result = compiled(context);\n return !!result;\n } catch {\n return defaultValue;\n }\n}\n\n/**\n * Evaluate a CEL expression directly using `evaluate` (no caching).\n * Useful for one-off evaluations or testing.\n */\nexport function evaluateCelDirect(expr: string, context: Record<string, unknown>): unknown {\n return celEvaluate(expr, context);\n}\n\n/**\n * Validate that a CEL expression can be parsed without errors.\n * Returns true if valid, false otherwise.\n */\nexport function isValidCelExpression(expr: string): boolean {\n try {\n celParse(expr);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Extract all field ID references from a simple expression.\n * Used by `resolveRequiredFieldsGroup` to find dependency relationships.\n *\n * For simple expressions like `fieldA == 'x'`, returns `['fieldA']`.\n * For compound expressions like `fieldA == 'x' && fieldB == 'y'`, returns `['fieldA', 'fieldB']`.\n *\n * This uses regex extraction (not AST walking) for simplicity and speed.\n */\nexport function extractFieldRefs(expr: string): string[] {\n // Match identifiers (possibly dotted) that precede == or !=\n const matches = expr.matchAll(/([\\w.]+)\\s*(?:==|!=)/g);\n const refs = new Set<string>();\n for (const m of matches) {\n refs.add(m[1]);\n }\n return [...refs];\n}\n\n/**\n * Clear the expression cache. Useful for testing.\n */\nexport function clearExpressionCache(): void {\n exprCache.clear();\n}\n"],"names":["celParse","celEvaluate"],"mappings":"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"}
|