@grafana/plugin-ui 0.14.1-dsconfig.4bdebf6 → 0.14.1-dsconfig.9143abf
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 +971 -277
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/index.d.cts +91 -6
- package/dist/cjs/schemas.cjs +2340 -883
- package/dist/cjs/schemas.cjs.map +1 -1
- package/dist/cjs/schemas.d.cts +36 -1
- package/dist/cjs/test-utils.d.cts +23 -23
- package/dist/esm/components/ConfigEditor/ConfigSection/ConfigDescriptionLink.js +2 -2
- package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/DatasourceConfigWizard.js +14 -9
- package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/DatasourceConfigWizard.js.map +1 -1
- package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/SchemaField.js +16 -5
- package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/SchemaField.js.map +1 -1
- package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/SidebarNav.js.map +1 -1
- package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/TabLayout.js +9 -4
- package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/TabLayout.js.map +1 -1
- package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/fieldUtils.js +61 -11
- package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/fieldUtils.js.map +1 -1
- package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/{useDatasourceConfigForm.js → hooks/useDatasourceConfigForm.js} +71 -29
- package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/hooks/useDatasourceConfigForm.js.map +1 -0
- package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/hooks/useHealthChecks.js.map +1 -0
- package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/{AuthorizationHeaderField.js → inputs/AuthorizationHeaderField.js} +6 -8
- package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/inputs/AuthorizationHeaderField.js.map +1 -0
- package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/{ComplexFieldNote.js → inputs/ComplexFieldNote.js} +6 -4
- 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/{IndexedPairEditor.js → inputs/IndexedPairEditor.js} +52 -52
- 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/{PdcFieldNote.js → inputs/PdcFieldNote.js} +5 -8
- package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/inputs/PdcFieldNote.js.map +1 -0
- package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/{SecureFieldInput.js → inputs/SecureFieldInput.js} +8 -10
- 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/renderFieldInput.js +76 -41
- package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/renderFieldInput.js.map +1 -1
- package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/tabStyles.js +4 -4
- package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/tabStyles.js.map +1 -1
- package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/wizardStyles.js +3 -3
- package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/wizardStyles.js.map +1 -1
- package/dist/esm/components/DataLinks/DataLink.js +2 -2
- package/dist/esm/components/DataLinks/DataLinks.js +2 -2
- 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/InputGroup.js +2 -2
- package/dist/esm/components/QueryEditor/Space.js +2 -2
- package/dist/esm/components/QueryEditor/query-editor-raw/RawEditor.js +2 -2
- 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 +2 -2
- package/dist/esm/components/QueryEditor/visual-query-builder/SelectRow.js +2 -2
- package/dist/esm/datasource/schema/cel.js +42 -0
- package/dist/esm/datasource/schema/cel.js.map +1 -0
- package/dist/esm/datasource/schema/config.js +37 -14
- package/dist/esm/datasource/schema/config.js.map +1 -1
- package/dist/esm/datasource/schema/datasource.js +129 -3
- package/dist/esm/datasource/schema/datasource.js.map +1 -1
- package/dist/esm/datasource/schema/datasources/cloudwatch.schema.json.js +3 -3
- package/dist/esm/datasource/schema/datasources/grafana-bigquery-datasource.schema.json.js +407 -58
- package/dist/esm/datasource/schema/datasources/grafana-bigquery-datasource.schema.json.js.map +1 -1
- package/dist/esm/datasource/schema/datasources/grafana-clickhouse-datasource.schema.json.js +206 -44
- package/dist/esm/datasource/schema/datasources/grafana-clickhouse-datasource.schema.json.js.map +1 -1
- package/dist/esm/datasource/schema/datasources/grafana-googlesheets-datasource.schema.json.js +103 -107
- package/dist/esm/datasource/schema/datasources/grafana-googlesheets-datasource.schema.json.js.map +1 -1
- package/dist/esm/datasource/schema/datasources/grafana-mqtt-datasource.schema.json.js +3 -3
- package/dist/esm/datasource/schema/datasources/grafana-postgresql-datasource.schema.json.js +170 -223
- package/dist/esm/datasource/schema/datasources/grafana-postgresql-datasource.schema.json.js.map +1 -1
- package/dist/esm/datasource/schema/datasources/influxdb.schema.json.js +22 -8
- package/dist/esm/datasource/schema/datasources/influxdb.schema.json.js.map +1 -1
- package/dist/esm/datasource/schema/datasources/loki.schema.json.js +3 -3
- package/dist/esm/datasource/schema/datasources/mysql.schema.json.js +221 -54
- package/dist/esm/datasource/schema/datasources/mysql.schema.json.js.map +1 -1
- package/dist/esm/datasource/schema/datasources/prometheus.schema.json.js +1 -1
- package/dist/esm/datasource/schema/datasources/stackdriver.schema.json.js +132 -43
- package/dist/esm/datasource/schema/datasources/stackdriver.schema.json.js.map +1 -1
- package/dist/esm/datasource/schema/datasources/tempo.schema.json.js +52 -6
- package/dist/esm/datasource/schema/datasources/tempo.schema.json.js.map +1 -1
- package/dist/esm/datasource/schema/datasources/yesoreyeram-infinity-datasource.schema.json.js +783 -96
- package/dist/esm/datasource/schema/datasources/yesoreyeram-infinity-datasource.schema.json.js.map +1 -1
- package/dist/esm/datasource/schema/dsconfig.js +17 -0
- package/dist/esm/datasource/schema/dsconfig.js.map +1 -0
- package/dist/esm/datasource/schema/{llmHints.js → llm.js} +1 -1
- package/dist/esm/datasource/schema/llm.js.map +1 -0
- package/dist/esm/datasource/schema/{provisioningYaml.js → provisioning.js} +78 -2
- package/dist/esm/datasource/schema/provisioning.js.map +1 -0
- package/dist/esm/index.d.ts +91 -6
- package/dist/esm/index.js +5 -5
- package/dist/esm/schemas.d.ts +36 -1
- package/dist/esm/test-utils.d.ts +23 -23
- package/package.json +9 -6
- package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/AuthorizationHeaderField.js.map +0 -1
- package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/ComplexFieldNote.js.map +0 -1
- package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/IndexedPairEditor.js.map +0 -1
- package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/PdcFieldNote.js.map +0 -1
- package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/SecureFieldInput.js.map +0 -1
- package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/StringArrayInput.js +0 -84
- package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/StringArrayInput.js.map +0 -1
- package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/useDatasourceConfigForm.js.map +0 -1
- package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/useHealthChecks.js.map +0 -1
- package/dist/esm/datasource/schema/llmHints.js.map +0 -1
- package/dist/esm/datasource/schema/provisioningYaml.js.map +0 -1
- /package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/{useHealthChecks.js → hooks/useHealthChecks.js} +0 -0
package/dist/cjs/index.cjs
CHANGED
|
@@ -17,12 +17,13 @@ var AutoSizer = require('react-virtualized-auto-sizer');
|
|
|
17
17
|
var sqlFormatter = require('sql-formatter');
|
|
18
18
|
var rxjs = require('rxjs');
|
|
19
19
|
var operators$1 = require('rxjs/operators');
|
|
20
|
+
var celJs = require('@marcbachmann/cel-js');
|
|
20
21
|
var reactHookForm = require('react-hook-form');
|
|
21
22
|
var dnd = require('@hello-pangea/dnd');
|
|
22
23
|
var reactPopperTooltip = require('react-popper-tooltip');
|
|
23
24
|
var Prism = require('prismjs');
|
|
24
|
-
var yaml = require('js-yaml');
|
|
25
25
|
var schemas = require('./schemas.cjs');
|
|
26
|
+
var yaml = require('js-yaml');
|
|
26
27
|
|
|
27
28
|
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
|
|
28
29
|
|
|
@@ -79,7 +80,7 @@ function Segment(props) {
|
|
|
79
80
|
);
|
|
80
81
|
}
|
|
81
82
|
|
|
82
|
-
const getStyles$
|
|
83
|
+
const getStyles$x = (theme) => {
|
|
83
84
|
const containerBorder = theme.isDark ? theme.v1.palette.dark9 : theme.v1.palette.gray5;
|
|
84
85
|
return {
|
|
85
86
|
container: css.css`
|
|
@@ -229,7 +230,7 @@ const getBodyStyles = (theme) => {
|
|
|
229
230
|
|
|
230
231
|
const DatePicker = React.memo((props) => {
|
|
231
232
|
const theme = ui.useTheme2();
|
|
232
|
-
const styles = getStyles$
|
|
233
|
+
const styles = getStyles$x(theme);
|
|
233
234
|
const { isOpen, onClose } = props;
|
|
234
235
|
if (!isOpen) {
|
|
235
236
|
return null;
|
|
@@ -259,7 +260,7 @@ const Body = React.memo(({ value, onChange }) => {
|
|
|
259
260
|
});
|
|
260
261
|
Body.displayName = "Body";
|
|
261
262
|
|
|
262
|
-
function getStyles$
|
|
263
|
+
function getStyles$w() {
|
|
263
264
|
return {
|
|
264
265
|
input: css.css({
|
|
265
266
|
/* hides the native Calendar picker icon given when using type=date */
|
|
@@ -275,7 +276,7 @@ const formatDate = (date) => date.toISOString().split("T")[0];
|
|
|
275
276
|
const DatePickerWithInput = (props) => {
|
|
276
277
|
const { value, onChange, className, ...rest } = props;
|
|
277
278
|
const [open, setOpen] = React.useState(false);
|
|
278
|
-
const styles = getStyles$
|
|
279
|
+
const styles = getStyles$w();
|
|
279
280
|
return /* @__PURE__ */ React__default.default.createElement(React__default.default.Fragment, null, /* @__PURE__ */ React__default.default.createElement(
|
|
280
281
|
ui.Input,
|
|
281
282
|
{
|
|
@@ -437,7 +438,7 @@ __publicField$4(DataSourcePicker, "defaultProps", {
|
|
|
437
438
|
});
|
|
438
439
|
|
|
439
440
|
const { FormField, Switch } = ui.LegacyForms;
|
|
440
|
-
const getStyles$
|
|
441
|
+
const getStyles$v = ui.stylesFactory(() => ({
|
|
441
442
|
firstRow: css.css`
|
|
442
443
|
display: flex;
|
|
443
444
|
`,
|
|
@@ -454,7 +455,7 @@ const getStyles$t = ui.stylesFactory(() => ({
|
|
|
454
455
|
}));
|
|
455
456
|
const DataLink = (props) => {
|
|
456
457
|
const { value, onChange, onDelete, suggestions, className } = props;
|
|
457
|
-
const styles = getStyles$
|
|
458
|
+
const styles = getStyles$v();
|
|
458
459
|
const [showInternalLink, setShowInternalLink] = useInternalLink(value.datasourceUid);
|
|
459
460
|
const handleChange = (field) => (event) => {
|
|
460
461
|
onChange({
|
|
@@ -571,7 +572,7 @@ function useInternalLink(datasourceUid) {
|
|
|
571
572
|
return [showInternalLink, setShowInternalLink];
|
|
572
573
|
}
|
|
573
574
|
|
|
574
|
-
const getStyles$
|
|
575
|
+
const getStyles$u = (theme) => ({
|
|
575
576
|
infoText: css.css`
|
|
576
577
|
padding-bottom: ${theme.v1.spacing.md};
|
|
577
578
|
color: ${theme.v1.colors.textWeak};
|
|
@@ -583,7 +584,7 @@ const getStyles$s = (theme) => ({
|
|
|
583
584
|
const DataLinks = (props) => {
|
|
584
585
|
const { value, onChange } = props;
|
|
585
586
|
const theme = ui.useTheme2();
|
|
586
|
-
const styles = getStyles$
|
|
587
|
+
const styles = getStyles$u(theme);
|
|
587
588
|
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) => {
|
|
588
589
|
return /* @__PURE__ */ React__default.default.createElement(
|
|
589
590
|
DataLink,
|
|
@@ -5479,7 +5480,7 @@ const getButtonStyles = (theme) => ({
|
|
|
5479
5480
|
});
|
|
5480
5481
|
|
|
5481
5482
|
const InputGroup = ({ children }) => {
|
|
5482
|
-
const styles = ui.useStyles2(getStyles$
|
|
5483
|
+
const styles = ui.useStyles2(getStyles$t);
|
|
5483
5484
|
const modifiedChildren = React.Children.map(children, (child) => {
|
|
5484
5485
|
if (React.isValidElement(child) && child.props.invalid) {
|
|
5485
5486
|
return React.cloneElement(child, { className: css.cx(child.props.className, styles.invalidChild) });
|
|
@@ -5497,7 +5498,7 @@ const borderPriority = [
|
|
|
5497
5498
|
"focused"
|
|
5498
5499
|
// highest priority
|
|
5499
5500
|
];
|
|
5500
|
-
const getStyles$
|
|
5501
|
+
const getStyles$t = () => ({
|
|
5501
5502
|
root: css.css({
|
|
5502
5503
|
display: "flex",
|
|
5503
5504
|
// Style the direct children of the component
|
|
@@ -5580,10 +5581,10 @@ const EditorFieldGroup = ({ children }) => {
|
|
|
5580
5581
|
};
|
|
5581
5582
|
|
|
5582
5583
|
const EditorHeader = ({ children }) => {
|
|
5583
|
-
const styles = ui.useStyles2(getStyles$
|
|
5584
|
+
const styles = ui.useStyles2(getStyles$s);
|
|
5584
5585
|
return /* @__PURE__ */ React__default.default.createElement("div", { className: styles.root }, children);
|
|
5585
5586
|
};
|
|
5586
|
-
const getStyles$
|
|
5587
|
+
const getStyles$s = (theme) => ({
|
|
5587
5588
|
root: css.css({
|
|
5588
5589
|
display: "flex",
|
|
5589
5590
|
flexWrap: "wrap",
|
|
@@ -5596,12 +5597,12 @@ const getStyles$q = (theme) => ({
|
|
|
5596
5597
|
const EditorField$1 = (props) => {
|
|
5597
5598
|
var _a;
|
|
5598
5599
|
const { label, optional, tooltip, tooltipInteractive, children, width, ...fieldProps } = props;
|
|
5599
|
-
const styles = ui.useStyles2(getStyles$
|
|
5600
|
+
const styles = ui.useStyles2(getStyles$r, width);
|
|
5600
5601
|
const childInputId = (fieldProps == null ? void 0 : fieldProps.htmlFor) || ((_a = ui.ReactUtils) == null ? void 0 : _a.getChildId(children));
|
|
5601
5602
|
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 }));
|
|
5602
5603
|
return /* @__PURE__ */ React__default.default.createElement("div", { className: styles.root }, /* @__PURE__ */ React__default.default.createElement(ui.Field, { className: styles.field, label: labelEl, ...fieldProps }, children));
|
|
5603
5604
|
};
|
|
5604
|
-
const getStyles$
|
|
5605
|
+
const getStyles$r = (theme, width) => {
|
|
5605
5606
|
return {
|
|
5606
5607
|
root: css.css({
|
|
5607
5608
|
minWidth: theme.spacing(width != null ? width : 0)
|
|
@@ -5629,10 +5630,10 @@ const getStyles$p = (theme, width) => {
|
|
|
5629
5630
|
};
|
|
5630
5631
|
|
|
5631
5632
|
const EditorRow$1 = ({ children }) => {
|
|
5632
|
-
const styles = ui.useStyles2(getStyles$
|
|
5633
|
+
const styles = ui.useStyles2(getStyles$q);
|
|
5633
5634
|
return /* @__PURE__ */ React__default.default.createElement("div", { className: styles.root }, /* @__PURE__ */ React__default.default.createElement(EditorStack, { gap: 2 }, children));
|
|
5634
5635
|
};
|
|
5635
|
-
const getStyles$
|
|
5636
|
+
const getStyles$q = (theme) => {
|
|
5636
5637
|
return {
|
|
5637
5638
|
root: css.css({
|
|
5638
5639
|
padding: theme.spacing(1),
|
|
@@ -5647,10 +5648,10 @@ const EditorRows$1 = ({ children }) => {
|
|
|
5647
5648
|
};
|
|
5648
5649
|
|
|
5649
5650
|
const EditorSwitch = (props) => {
|
|
5650
|
-
const styles = getStyles$
|
|
5651
|
+
const styles = getStyles$p();
|
|
5651
5652
|
return /* @__PURE__ */ React__default.default.createElement("div", { className: styles.switch }, /* @__PURE__ */ React__default.default.createElement(ui.Switch, { ...props }));
|
|
5652
5653
|
};
|
|
5653
|
-
const getStyles$
|
|
5654
|
+
const getStyles$p = () => {
|
|
5654
5655
|
return {
|
|
5655
5656
|
switch: css.css({
|
|
5656
5657
|
display: "flex",
|
|
@@ -5708,10 +5709,10 @@ const getSelectStyles = (theme) => ({
|
|
|
5708
5709
|
});
|
|
5709
5710
|
|
|
5710
5711
|
const Space = ({ v = 0, h = 0, layout = "block" }) => {
|
|
5711
|
-
const styles = ui.useStyles2(getStyles$
|
|
5712
|
+
const styles = ui.useStyles2(getStyles$o, v, h, layout);
|
|
5712
5713
|
return /* @__PURE__ */ React__default.default.createElement("span", { className: css.cx(styles.wrapper) });
|
|
5713
5714
|
};
|
|
5714
|
-
const getStyles$
|
|
5715
|
+
const getStyles$o = (theme, v, h, layout) => ({
|
|
5715
5716
|
wrapper: css.css([
|
|
5716
5717
|
{
|
|
5717
5718
|
paddingRight: theme.spacing(h != null ? h : 0),
|
|
@@ -6323,7 +6324,7 @@ function RawEditor({
|
|
|
6323
6324
|
language = "sql"
|
|
6324
6325
|
}) {
|
|
6325
6326
|
const theme = ui.useTheme2();
|
|
6326
|
-
const styles = ui.useStyles2(getStyles$
|
|
6327
|
+
const styles = ui.useStyles2(getStyles$n);
|
|
6327
6328
|
const [isExpanded, setIsExpanded] = React.useState(false);
|
|
6328
6329
|
const [toolboxRef, toolboxMeasure] = reactUse.useMeasure();
|
|
6329
6330
|
const [editorRef, editorMeasure] = reactUse.useMeasure();
|
|
@@ -6393,7 +6394,7 @@ function RawEditor({
|
|
|
6393
6394
|
renderEditor(true)
|
|
6394
6395
|
));
|
|
6395
6396
|
}
|
|
6396
|
-
function getStyles$
|
|
6397
|
+
function getStyles$n(theme) {
|
|
6397
6398
|
return {
|
|
6398
6399
|
modal: css.css`
|
|
6399
6400
|
width: 95vw;
|
|
@@ -6408,7 +6409,7 @@ function getStyles$l(theme) {
|
|
|
6408
6409
|
|
|
6409
6410
|
function Preview({ rawSql, language = "sql" }) {
|
|
6410
6411
|
const [_, copyToClipboard] = reactUse.useCopyToClipboard();
|
|
6411
|
-
const styles = ui.useStyles2(getStyles$
|
|
6412
|
+
const styles = ui.useStyles2(getStyles$m);
|
|
6412
6413
|
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" }));
|
|
6413
6414
|
return /* @__PURE__ */ React__default.default.createElement(ui.Field, { label: labelElement, className: styles.grow }, /* @__PURE__ */ React__default.default.createElement(
|
|
6414
6415
|
ui.CodeEditor,
|
|
@@ -6422,7 +6423,7 @@ function Preview({ rawSql, language = "sql" }) {
|
|
|
6422
6423
|
}
|
|
6423
6424
|
));
|
|
6424
6425
|
}
|
|
6425
|
-
function getStyles$
|
|
6426
|
+
function getStyles$m(theme) {
|
|
6426
6427
|
return {
|
|
6427
6428
|
grow: css.css({ flexGrow: 1 }),
|
|
6428
6429
|
label: css.css({ fontSize: 12, fontWeight: theme.typography.fontWeightMedium }),
|
|
@@ -6541,7 +6542,7 @@ function SQLOrderByRow({ fields, query, onQueryChange, db }) {
|
|
|
6541
6542
|
const asteriskValue = { label: "*", value: "*" };
|
|
6542
6543
|
function SelectRow({ sql, columns, onSqlChange, functions }) {
|
|
6543
6544
|
var _a;
|
|
6544
|
-
const styles = ui.useStyles2(getStyles$
|
|
6545
|
+
const styles = ui.useStyles2(getStyles$l);
|
|
6545
6546
|
const columnsWithAsterisk = [asteriskValue, ...columns || []];
|
|
6546
6547
|
const onColumnChange = React.useCallback(
|
|
6547
6548
|
(item, index) => (column) => {
|
|
@@ -6637,7 +6638,7 @@ function SelectRow({ sql, columns, onSqlChange, functions }) {
|
|
|
6637
6638
|
}
|
|
6638
6639
|
));
|
|
6639
6640
|
}
|
|
6640
|
-
const getStyles$
|
|
6641
|
+
const getStyles$l = () => {
|
|
6641
6642
|
return { addButton: css.css({ alignSelf: "flex-start" }) };
|
|
6642
6643
|
};
|
|
6643
6644
|
function getColumnValue({ parameters }) {
|
|
@@ -6983,10 +6984,10 @@ function mapFieldsToTypes(columns) {
|
|
|
6983
6984
|
}
|
|
6984
6985
|
|
|
6985
6986
|
const EditorRow = ({ children }) => {
|
|
6986
|
-
const styles = ui.useStyles2(getStyles$
|
|
6987
|
+
const styles = ui.useStyles2(getStyles$k);
|
|
6987
6988
|
return /* @__PURE__ */ React__default.default.createElement("div", { className: styles.root }, /* @__PURE__ */ React__default.default.createElement(EditorStack, { gap: 2 }, children));
|
|
6988
6989
|
};
|
|
6989
|
-
const getStyles$
|
|
6990
|
+
const getStyles$k = (theme) => {
|
|
6990
6991
|
return {
|
|
6991
6992
|
root: css.css({
|
|
6992
6993
|
padding: theme.spacing(1),
|
|
@@ -7000,12 +7001,12 @@ const EditorField = (props) => {
|
|
|
7000
7001
|
var _a;
|
|
7001
7002
|
const { label, optional, tooltip, children, width, ...fieldProps } = props;
|
|
7002
7003
|
const theme = ui.useTheme2();
|
|
7003
|
-
const styles = getStyles$
|
|
7004
|
+
const styles = getStyles$j(theme, width);
|
|
7004
7005
|
const childInputId = (fieldProps == null ? void 0 : fieldProps.htmlFor) || ((_a = ui.ReactUtils) == null ? void 0 : _a.getChildId(children));
|
|
7005
7006
|
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 }));
|
|
7006
7007
|
return /* @__PURE__ */ React__default.default.createElement("div", { className: styles.root }, /* @__PURE__ */ React__default.default.createElement(ui.Field, { className: styles.field, label: labelEl, ...fieldProps }, children));
|
|
7007
7008
|
};
|
|
7008
|
-
const getStyles$
|
|
7009
|
+
const getStyles$j = ui.stylesFactory((theme, width) => {
|
|
7009
7010
|
return {
|
|
7010
7011
|
root: css.css({
|
|
7011
7012
|
minWidth: theme.spacing(width != null ? width : 0)
|
|
@@ -7455,7 +7456,7 @@ const ConfigSubSection = ({ children, ...props }) => {
|
|
|
7455
7456
|
function ConfigDescriptionLink(props) {
|
|
7456
7457
|
const { description, suffix, feature } = props;
|
|
7457
7458
|
const text = `Learn more about ${feature}`;
|
|
7458
|
-
const styles = ui.useStyles2(getStyles$
|
|
7459
|
+
const styles = ui.useStyles2(getStyles$i);
|
|
7459
7460
|
return /* @__PURE__ */ React__default.default.createElement("span", { className: styles.container }, description, /* @__PURE__ */ React__default.default.createElement(
|
|
7460
7461
|
"a",
|
|
7461
7462
|
{
|
|
@@ -7467,7 +7468,7 @@ function ConfigDescriptionLink(props) {
|
|
|
7467
7468
|
text
|
|
7468
7469
|
));
|
|
7469
7470
|
}
|
|
7470
|
-
const getStyles$
|
|
7471
|
+
const getStyles$i = (theme) => {
|
|
7471
7472
|
return {
|
|
7472
7473
|
container: css.css({
|
|
7473
7474
|
color: theme.colors.text.secondary,
|
|
@@ -8436,6 +8437,44 @@ const AdvancedHttpSettings = ({
|
|
|
8436
8437
|
));
|
|
8437
8438
|
};
|
|
8438
8439
|
|
|
8440
|
+
const exprCache = /* @__PURE__ */ new Map();
|
|
8441
|
+
function getCompiled(expr) {
|
|
8442
|
+
if (exprCache.has(expr)) {
|
|
8443
|
+
return exprCache.get(expr);
|
|
8444
|
+
}
|
|
8445
|
+
try {
|
|
8446
|
+
const compiled = celJs.parse(expr);
|
|
8447
|
+
exprCache.set(expr, compiled);
|
|
8448
|
+
return compiled;
|
|
8449
|
+
} catch (e) {
|
|
8450
|
+
exprCache.set(expr, null);
|
|
8451
|
+
return null;
|
|
8452
|
+
}
|
|
8453
|
+
}
|
|
8454
|
+
function evaluateCelExpression(expr, context, defaultValue = false) {
|
|
8455
|
+
if (!expr || !expr.trim()) {
|
|
8456
|
+
return defaultValue;
|
|
8457
|
+
}
|
|
8458
|
+
const compiled = getCompiled(expr);
|
|
8459
|
+
if (!compiled) {
|
|
8460
|
+
return defaultValue;
|
|
8461
|
+
}
|
|
8462
|
+
try {
|
|
8463
|
+
const result = compiled(context);
|
|
8464
|
+
return !!result;
|
|
8465
|
+
} catch (e) {
|
|
8466
|
+
return defaultValue;
|
|
8467
|
+
}
|
|
8468
|
+
}
|
|
8469
|
+
function extractFieldRefs(expr) {
|
|
8470
|
+
const matches = expr.matchAll(/([\w.]+)\s*(?:==|!=)/g);
|
|
8471
|
+
const refs = /* @__PURE__ */ new Set();
|
|
8472
|
+
for (const m of matches) {
|
|
8473
|
+
refs.add(m[1]);
|
|
8474
|
+
}
|
|
8475
|
+
return [...refs];
|
|
8476
|
+
}
|
|
8477
|
+
|
|
8439
8478
|
function resolveGroups(schema) {
|
|
8440
8479
|
const fieldMap = /* @__PURE__ */ new Map();
|
|
8441
8480
|
for (const f of schema.fields) {
|
|
@@ -8459,18 +8498,18 @@ function resolveGroups(schema) {
|
|
|
8459
8498
|
];
|
|
8460
8499
|
}
|
|
8461
8500
|
function resolveRequiredFieldsGroup(schema) {
|
|
8462
|
-
var _a;
|
|
8501
|
+
var _a, _b;
|
|
8463
8502
|
const fieldMap = /* @__PURE__ */ new Map();
|
|
8464
8503
|
for (const f of schema.fields) {
|
|
8465
8504
|
fieldMap.set(f.id, f);
|
|
8466
8505
|
}
|
|
8467
8506
|
const requiredIds = /* @__PURE__ */ new Set();
|
|
8468
8507
|
for (const f of schema.fields) {
|
|
8469
|
-
if (f.required) {
|
|
8508
|
+
if (f.required || ((_a = f.tags) == null ? void 0 : _a.includes("pinned"))) {
|
|
8470
8509
|
requiredIds.add(f.id);
|
|
8471
8510
|
}
|
|
8472
8511
|
}
|
|
8473
|
-
const authGroup = (
|
|
8512
|
+
const authGroup = (_b = schema.groups) == null ? void 0 : _b.find((g) => g.id === "auth");
|
|
8474
8513
|
if (authGroup) {
|
|
8475
8514
|
for (const ref of authGroup.fieldRefs) {
|
|
8476
8515
|
if (fieldMap.has(ref)) {
|
|
@@ -8486,16 +8525,17 @@ function resolveRequiredFieldsGroup(schema) {
|
|
|
8486
8525
|
includeIds.add(id);
|
|
8487
8526
|
const f = fieldMap.get(id);
|
|
8488
8527
|
if (f == null ? void 0 : f.dependsOn) {
|
|
8489
|
-
const
|
|
8490
|
-
|
|
8491
|
-
|
|
8528
|
+
for (const ref of extractFieldRefs(f.dependsOn)) {
|
|
8529
|
+
if (fieldMap.has(ref)) {
|
|
8530
|
+
includeIds.add(ref);
|
|
8531
|
+
}
|
|
8492
8532
|
}
|
|
8493
8533
|
}
|
|
8494
8534
|
}
|
|
8495
8535
|
for (const f of schema.fields) {
|
|
8496
8536
|
if (f.dependsOn && !includeIds.has(f.id)) {
|
|
8497
|
-
const
|
|
8498
|
-
if (
|
|
8537
|
+
const refs = extractFieldRefs(f.dependsOn);
|
|
8538
|
+
if (refs.some((ref) => requiredIds.has(ref))) {
|
|
8499
8539
|
includeIds.add(f.id);
|
|
8500
8540
|
}
|
|
8501
8541
|
}
|
|
@@ -8507,7 +8547,7 @@ function resolveRequiredFieldsGroup(schema) {
|
|
|
8507
8547
|
return {
|
|
8508
8548
|
group: {
|
|
8509
8549
|
id: "_required",
|
|
8510
|
-
title: "
|
|
8550
|
+
title: "General",
|
|
8511
8551
|
fieldRefs: virtualFields.map((f) => f.id)
|
|
8512
8552
|
},
|
|
8513
8553
|
fields: virtualFields
|
|
@@ -8516,16 +8556,36 @@ function resolveRequiredFieldsGroup(schema) {
|
|
|
8516
8556
|
function formKey(field) {
|
|
8517
8557
|
return field.section ? `${field.section}.${field.key}` : field.key;
|
|
8518
8558
|
}
|
|
8559
|
+
function getWatchedValue(watchedValues, key) {
|
|
8560
|
+
if (key.includes(".")) {
|
|
8561
|
+
const parts = key.split(".");
|
|
8562
|
+
let current = watchedValues;
|
|
8563
|
+
for (const part of parts) {
|
|
8564
|
+
if (current == null || typeof current !== "object") {
|
|
8565
|
+
return watchedValues[key];
|
|
8566
|
+
}
|
|
8567
|
+
current = current[part];
|
|
8568
|
+
}
|
|
8569
|
+
if (current !== void 0) {
|
|
8570
|
+
return current;
|
|
8571
|
+
}
|
|
8572
|
+
return watchedValues[key];
|
|
8573
|
+
}
|
|
8574
|
+
return watchedValues[key];
|
|
8575
|
+
}
|
|
8519
8576
|
function parseDependsOn(expr) {
|
|
8520
8577
|
var _a, _b;
|
|
8521
|
-
const m = expr.match(/^(
|
|
8578
|
+
const m = expr.match(/^([\w.]+)\s*(==|!=)\s*(?:'([^']*)'|"([^"]*)"|(\S+))$/);
|
|
8522
8579
|
if (!m) {
|
|
8523
8580
|
return null;
|
|
8524
8581
|
}
|
|
8525
|
-
return { field: m[1]
|
|
8582
|
+
return { field: m[1], value: ((_b = (_a = m[3]) != null ? _a : m[4]) != null ? _b : m[5]).trim(), negate: m[2] === "!=" };
|
|
8583
|
+
}
|
|
8584
|
+
function evaluateDependsOn(parsed, currentValue) {
|
|
8585
|
+
const matches = String(currentValue != null ? currentValue : "") === parsed.value;
|
|
8586
|
+
return parsed.negate ? !matches : matches;
|
|
8526
8587
|
}
|
|
8527
8588
|
function resolveActiveOverride(field, watchedValues, fieldById) {
|
|
8528
|
-
var _a;
|
|
8529
8589
|
if (!field.overrides || field.overrides.length === 0) {
|
|
8530
8590
|
return void 0;
|
|
8531
8591
|
}
|
|
@@ -8536,7 +8596,7 @@ function resolveActiveOverride(field, watchedValues, fieldById) {
|
|
|
8536
8596
|
}
|
|
8537
8597
|
const depField = fieldById.get(parsed.field);
|
|
8538
8598
|
const depKey = depField ? formKey(depField) : parsed.field;
|
|
8539
|
-
if (
|
|
8599
|
+
if (evaluateDependsOn(parsed, getWatchedValue(watchedValues, depKey))) {
|
|
8540
8600
|
return ov;
|
|
8541
8601
|
}
|
|
8542
8602
|
}
|
|
@@ -8670,6 +8730,52 @@ function computeVirtualFieldValues(schema, existingValues) {
|
|
|
8670
8730
|
}
|
|
8671
8731
|
|
|
8672
8732
|
const SECURE_FIELD_CONFIGURED = "__CONFIGURED__";
|
|
8733
|
+
function resolveSecureKeyTemplate(template, item, index) {
|
|
8734
|
+
return template.replace(/\{index1\}/g, String(index + 1)).replace(/\{index\}/g, String(index)).replace(/\{item\.(\w+)\}/g, (_, key) => {
|
|
8735
|
+
var _a;
|
|
8736
|
+
return String((_a = item[key]) != null ? _a : "");
|
|
8737
|
+
});
|
|
8738
|
+
}
|
|
8739
|
+
function evaluateItemCondition(condition, item) {
|
|
8740
|
+
const trimmed = condition.trim();
|
|
8741
|
+
if (trimmed === "true") {
|
|
8742
|
+
return true;
|
|
8743
|
+
}
|
|
8744
|
+
const match = trimmed.match(/^item\.(\w+)\s*==\s*(.+)$/);
|
|
8745
|
+
if (!match) {
|
|
8746
|
+
return false;
|
|
8747
|
+
}
|
|
8748
|
+
const [, key, rawValue] = match;
|
|
8749
|
+
const actualValue = item[key];
|
|
8750
|
+
const expected = rawValue.trim();
|
|
8751
|
+
if (expected === "true") {
|
|
8752
|
+
return actualValue === true;
|
|
8753
|
+
}
|
|
8754
|
+
if (expected === "false") {
|
|
8755
|
+
return actualValue === false;
|
|
8756
|
+
}
|
|
8757
|
+
const unquoted = expected.replace(/^['"]|['"]$/g, "");
|
|
8758
|
+
return String(actualValue) === unquoted;
|
|
8759
|
+
}
|
|
8760
|
+
function findActiveSecureOverride(itemFields, item, index) {
|
|
8761
|
+
for (const field of itemFields) {
|
|
8762
|
+
if (!field.overrides) {
|
|
8763
|
+
continue;
|
|
8764
|
+
}
|
|
8765
|
+
for (const override of field.overrides) {
|
|
8766
|
+
if (!override.secureKey) {
|
|
8767
|
+
continue;
|
|
8768
|
+
}
|
|
8769
|
+
if (evaluateItemCondition(override.when, item)) {
|
|
8770
|
+
return {
|
|
8771
|
+
fieldKey: field.key,
|
|
8772
|
+
resolvedKey: resolveSecureKeyTemplate(override.secureKey, item, index)
|
|
8773
|
+
};
|
|
8774
|
+
}
|
|
8775
|
+
}
|
|
8776
|
+
}
|
|
8777
|
+
return null;
|
|
8778
|
+
}
|
|
8673
8779
|
function patternToRegex(pattern) {
|
|
8674
8780
|
const escaped = pattern.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
8675
8781
|
return new RegExp("^" + escaped.replace("\\{index\\}", "(\\d+)") + "$");
|
|
@@ -8776,7 +8882,7 @@ function resolveRawPath(ref, ds) {
|
|
|
8776
8882
|
return void 0;
|
|
8777
8883
|
}
|
|
8778
8884
|
async function fetchExistingValues(dsUid, fields) {
|
|
8779
|
-
var _a, _b, _c, _d, _e;
|
|
8885
|
+
var _a, _b, _c, _d, _e, _f;
|
|
8780
8886
|
try {
|
|
8781
8887
|
const ds = await runtime.getBackendSrv().get(`/api/datasources/uid/${dsUid}`, void 0, void 0, {
|
|
8782
8888
|
showErrorAlert: false
|
|
@@ -8817,6 +8923,32 @@ async function fetchExistingValues(dsUid, fields) {
|
|
|
8817
8923
|
}
|
|
8818
8924
|
}
|
|
8819
8925
|
}
|
|
8926
|
+
for (const field of fields) {
|
|
8927
|
+
if (field.valueType !== "array" || !((_f = field.item) == null ? void 0 : _f.fields)) {
|
|
8928
|
+
continue;
|
|
8929
|
+
}
|
|
8930
|
+
const itemFields = field.item.fields;
|
|
8931
|
+
const hasSecureOverride = itemFields.some((f) => {
|
|
8932
|
+
var _a2;
|
|
8933
|
+
return (_a2 = f.overrides) == null ? void 0 : _a2.some((o) => o.secureKey);
|
|
8934
|
+
});
|
|
8935
|
+
if (!hasSecureOverride) {
|
|
8936
|
+
continue;
|
|
8937
|
+
}
|
|
8938
|
+
const fk = formKey(field);
|
|
8939
|
+
const arr = values[fk];
|
|
8940
|
+
if (!Array.isArray(arr)) {
|
|
8941
|
+
continue;
|
|
8942
|
+
}
|
|
8943
|
+
values[fk] = arr.map((item, idx) => {
|
|
8944
|
+
var _a2;
|
|
8945
|
+
const match = findActiveSecureOverride(itemFields, item, idx);
|
|
8946
|
+
if (match && ((_a2 = ds.secureJsonFields) == null ? void 0 : _a2[match.resolvedKey])) {
|
|
8947
|
+
return { ...item, [match.fieldKey]: SECURE_FIELD_CONFIGURED };
|
|
8948
|
+
}
|
|
8949
|
+
return item;
|
|
8950
|
+
});
|
|
8951
|
+
}
|
|
8820
8952
|
return { values, readOnly: !!ds.readOnly };
|
|
8821
8953
|
} catch (err) {
|
|
8822
8954
|
const message = err instanceof Error ? err.message : "Failed to load datasource configuration";
|
|
@@ -8824,7 +8956,7 @@ async function fetchExistingValues(dsUid, fields) {
|
|
|
8824
8956
|
}
|
|
8825
8957
|
}
|
|
8826
8958
|
function buildDatasourceConfigPayload(data, fields, existing, isFieldVisible) {
|
|
8827
|
-
var _a, _b, _c, _d;
|
|
8959
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
8828
8960
|
const rootFields = {};
|
|
8829
8961
|
const jsonData = { ...(_a = existing.jsonData) != null ? _a : {} };
|
|
8830
8962
|
const secureJsonData = {};
|
|
@@ -8873,6 +9005,60 @@ function buildDatasourceConfigPayload(data, fields, existing, isFieldVisible) {
|
|
|
8873
9005
|
break;
|
|
8874
9006
|
}
|
|
8875
9007
|
}
|
|
9008
|
+
for (const field of fields) {
|
|
9009
|
+
if (field.valueType !== "array" || !((_e = field.item) == null ? void 0 : _e.fields) || field.target !== "jsonData") {
|
|
9010
|
+
continue;
|
|
9011
|
+
}
|
|
9012
|
+
const itemFields = field.item.fields;
|
|
9013
|
+
const hasSecureOverride = itemFields.some((f) => {
|
|
9014
|
+
var _a2;
|
|
9015
|
+
return (_a2 = f.overrides) == null ? void 0 : _a2.some((o) => o.secureKey);
|
|
9016
|
+
});
|
|
9017
|
+
if (!hasSecureOverride) {
|
|
9018
|
+
continue;
|
|
9019
|
+
}
|
|
9020
|
+
const arr = field.section ? (_f = jsonData[field.section]) == null ? void 0 : _f[field.key] : jsonData[field.key];
|
|
9021
|
+
if (!Array.isArray(arr)) {
|
|
9022
|
+
continue;
|
|
9023
|
+
}
|
|
9024
|
+
const secureKeyOverrides = [];
|
|
9025
|
+
for (const f of itemFields) {
|
|
9026
|
+
for (const o of (_g = f.overrides) != null ? _g : []) {
|
|
9027
|
+
if (o.secureKey) {
|
|
9028
|
+
secureKeyOverrides.push({ fieldKey: f.key, override: o });
|
|
9029
|
+
}
|
|
9030
|
+
}
|
|
9031
|
+
}
|
|
9032
|
+
const activeSecureKeys = /* @__PURE__ */ new Set();
|
|
9033
|
+
for (let i = 0; i < arr.length; i++) {
|
|
9034
|
+
const item = arr[i];
|
|
9035
|
+
const match = findActiveSecureOverride(itemFields, item, i);
|
|
9036
|
+
if (!match) {
|
|
9037
|
+
continue;
|
|
9038
|
+
}
|
|
9039
|
+
const resolvedKey = match.resolvedKey;
|
|
9040
|
+
activeSecureKeys.add(resolvedKey);
|
|
9041
|
+
const itemValue = item[match.fieldKey];
|
|
9042
|
+
if (itemValue === SECURE_FIELD_CONFIGURED) {
|
|
9043
|
+
secureJsonFields[resolvedKey] = true;
|
|
9044
|
+
} else if (itemValue && itemValue !== "") {
|
|
9045
|
+
secureJsonData[resolvedKey] = String(itemValue);
|
|
9046
|
+
secureJsonFields[resolvedKey] = false;
|
|
9047
|
+
item[match.fieldKey] = "";
|
|
9048
|
+
}
|
|
9049
|
+
}
|
|
9050
|
+
const existingSecureFields = (_h = existing.secureJsonFields) != null ? _h : {};
|
|
9051
|
+
for (const existingKey of Object.keys(existingSecureFields)) {
|
|
9052
|
+
const couldBeFromThisField = secureKeyOverrides.some((sko) => {
|
|
9053
|
+
const staticPrefix = sko.override.secureKey.split("{")[0];
|
|
9054
|
+
return staticPrefix && existingKey.startsWith(staticPrefix);
|
|
9055
|
+
});
|
|
9056
|
+
if (couldBeFromThisField && !activeSecureKeys.has(existingKey)) {
|
|
9057
|
+
secureJsonFields[existingKey] = false;
|
|
9058
|
+
secureJsonData[existingKey] = "";
|
|
9059
|
+
}
|
|
9060
|
+
}
|
|
9061
|
+
}
|
|
8876
9062
|
return { rootFields, jsonData, secureJsonData, secureJsonFields };
|
|
8877
9063
|
}
|
|
8878
9064
|
async function submitDatasourceConfig(dsUid, data, fields, isFieldVisible) {
|
|
@@ -8910,23 +9096,25 @@ function evaluateEffectCondition(when, fieldValue) {
|
|
|
8910
9096
|
const eq = String(fieldValue) === String(target);
|
|
8911
9097
|
return op === "==" ? eq : !eq;
|
|
8912
9098
|
}
|
|
8913
|
-
function isFieldRequired(field, watchedValues, fieldById) {
|
|
8914
|
-
var _a;
|
|
9099
|
+
function isFieldRequired(field, watchedValues, fieldById, celContext) {
|
|
8915
9100
|
if (field.required) {
|
|
8916
9101
|
return true;
|
|
8917
9102
|
}
|
|
8918
9103
|
if (field.requiredWhen) {
|
|
9104
|
+
if (celContext) {
|
|
9105
|
+
return evaluateCelExpression(field.requiredWhen, celContext);
|
|
9106
|
+
}
|
|
8919
9107
|
const parsed = parseDependsOn(field.requiredWhen);
|
|
8920
9108
|
if (parsed) {
|
|
8921
9109
|
const depField = fieldById.get(parsed.field);
|
|
8922
9110
|
const depKey = depField ? formKey(depField) : parsed.field;
|
|
8923
|
-
return
|
|
9111
|
+
return evaluateDependsOn(parsed, getWatchedValue(watchedValues, depKey));
|
|
8924
9112
|
}
|
|
8925
9113
|
}
|
|
8926
9114
|
return false;
|
|
8927
9115
|
}
|
|
8928
9116
|
function buildValidationRules(field, required) {
|
|
8929
|
-
var _a, _b, _c, _d, _e, _f;
|
|
9117
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
8930
9118
|
const rules = {};
|
|
8931
9119
|
const label = (_a = field.label) != null ? _a : field.key;
|
|
8932
9120
|
if (required) {
|
|
@@ -8944,29 +9132,65 @@ function buildValidationRules(field, required) {
|
|
|
8944
9132
|
rules.required = `${label} is required`;
|
|
8945
9133
|
}
|
|
8946
9134
|
}
|
|
9135
|
+
if (field.valueType === "array" && ((_b = field.item) == null ? void 0 : _b.valueType) === "object" && ((_c = field.item.fields) == null ? void 0 : _c.length)) {
|
|
9136
|
+
const requiredItemFields = field.item.fields.filter((f) => f.required);
|
|
9137
|
+
if (requiredItemFields.length > 0) {
|
|
9138
|
+
const existingValidate = rules.validate;
|
|
9139
|
+
rules.validate = (value) => {
|
|
9140
|
+
var _a2;
|
|
9141
|
+
if (existingValidate) {
|
|
9142
|
+
const r = existingValidate(value);
|
|
9143
|
+
if (r !== true) {
|
|
9144
|
+
return r;
|
|
9145
|
+
}
|
|
9146
|
+
}
|
|
9147
|
+
if (!Array.isArray(value)) {
|
|
9148
|
+
return true;
|
|
9149
|
+
}
|
|
9150
|
+
const itemErrors = {};
|
|
9151
|
+
for (let i = 0; i < value.length; i++) {
|
|
9152
|
+
const item = value[i];
|
|
9153
|
+
const missing = [];
|
|
9154
|
+
for (const rf of requiredItemFields) {
|
|
9155
|
+
const v = item[rf.key];
|
|
9156
|
+
if (v === void 0 || v === null || v === "") {
|
|
9157
|
+
missing.push((_a2 = rf.label) != null ? _a2 : rf.key);
|
|
9158
|
+
}
|
|
9159
|
+
}
|
|
9160
|
+
if (missing.length > 0) {
|
|
9161
|
+
itemErrors[i] = `${missing.join(", ")} required`;
|
|
9162
|
+
}
|
|
9163
|
+
}
|
|
9164
|
+
if (Object.keys(itemErrors).length === 0) {
|
|
9165
|
+
return true;
|
|
9166
|
+
}
|
|
9167
|
+
return `__ITEM_ERRORS__${JSON.stringify(itemErrors)}`;
|
|
9168
|
+
};
|
|
9169
|
+
}
|
|
9170
|
+
}
|
|
8947
9171
|
if (field.validations) {
|
|
8948
9172
|
for (const v of field.validations) {
|
|
8949
9173
|
switch (v.type) {
|
|
8950
9174
|
case "pattern":
|
|
8951
9175
|
rules.pattern = {
|
|
8952
9176
|
value: new RegExp(v.pattern),
|
|
8953
|
-
message: (
|
|
9177
|
+
message: (_d = v.message) != null ? _d : `Invalid ${label}`
|
|
8954
9178
|
};
|
|
8955
9179
|
break;
|
|
8956
9180
|
case "range":
|
|
8957
9181
|
if (v.min !== void 0) {
|
|
8958
|
-
rules.min = { value: v.min, message: (
|
|
9182
|
+
rules.min = { value: v.min, message: (_e = v.message) != null ? _e : `Minimum value is ${v.min}` };
|
|
8959
9183
|
}
|
|
8960
9184
|
if (v.max !== void 0) {
|
|
8961
|
-
rules.max = { value: v.max, message: (
|
|
9185
|
+
rules.max = { value: v.max, message: (_f = v.message) != null ? _f : `Maximum value is ${v.max}` };
|
|
8962
9186
|
}
|
|
8963
9187
|
break;
|
|
8964
9188
|
case "length":
|
|
8965
9189
|
if (v.min !== void 0) {
|
|
8966
|
-
rules.minLength = { value: v.min, message: (
|
|
9190
|
+
rules.minLength = { value: v.min, message: (_g = v.message) != null ? _g : `Minimum length is ${v.min}` };
|
|
8967
9191
|
}
|
|
8968
9192
|
if (v.max !== void 0) {
|
|
8969
|
-
rules.maxLength = { value: v.max, message: (
|
|
9193
|
+
rules.maxLength = { value: v.max, message: (_h = v.message) != null ? _h : `Maximum length is ${v.max}` };
|
|
8970
9194
|
}
|
|
8971
9195
|
break;
|
|
8972
9196
|
}
|
|
@@ -8974,16 +9198,24 @@ function buildValidationRules(field, required) {
|
|
|
8974
9198
|
}
|
|
8975
9199
|
return rules;
|
|
8976
9200
|
}
|
|
9201
|
+
const ITEM_ERRORS_PREFIX = "__ITEM_ERRORS__";
|
|
9202
|
+
function parseItemErrors(errorMessage) {
|
|
9203
|
+
if (!errorMessage || !errorMessage.startsWith(ITEM_ERRORS_PREFIX)) {
|
|
9204
|
+
return null;
|
|
9205
|
+
}
|
|
9206
|
+
try {
|
|
9207
|
+
return JSON.parse(errorMessage.slice(ITEM_ERRORS_PREFIX.length));
|
|
9208
|
+
} catch (e) {
|
|
9209
|
+
return null;
|
|
9210
|
+
}
|
|
9211
|
+
}
|
|
8977
9212
|
|
|
8978
|
-
|
|
8979
|
-
enabled,
|
|
8980
|
-
|
|
8981
|
-
configUrl
|
|
8982
|
-
}) {
|
|
8983
|
-
const styles = ui.useStyles2(getStyles$f);
|
|
9213
|
+
const PdcFieldNote = (props) => {
|
|
9214
|
+
const { enabled, description, configUrl } = props;
|
|
9215
|
+
const styles = ui.useStyles2(getStyles$h);
|
|
8984
9216
|
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$
|
|
9217
|
+
};
|
|
9218
|
+
const getStyles$h = (theme) => ({
|
|
8987
9219
|
wrapper: css.css({
|
|
8988
9220
|
display: "flex",
|
|
8989
9221
|
alignItems: "center",
|
|
@@ -9003,18 +9235,14 @@ const getStyles$f = (theme) => ({
|
|
|
9003
9235
|
})
|
|
9004
9236
|
});
|
|
9005
9237
|
|
|
9006
|
-
function SecureFieldInput({
|
|
9007
|
-
formField,
|
|
9008
|
-
placeholder,
|
|
9009
|
-
disabled,
|
|
9010
|
-
label
|
|
9011
|
-
}) {
|
|
9238
|
+
function SecureFieldInput(props) {
|
|
9012
9239
|
var _a;
|
|
9240
|
+
const { formField, placeholder, disabled } = props;
|
|
9013
9241
|
const isConfigured = formField.value === SECURE_FIELD_CONFIGURED;
|
|
9014
9242
|
const [revealed, setRevealed] = React.useState(false);
|
|
9015
9243
|
const styles = ui.useStyles2(getSecureFieldStyles);
|
|
9016
9244
|
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" }),
|
|
9245
|
+
return /* @__PURE__ */ React__default.default.createElement("div", { className: styles.configuredRow }, /* @__PURE__ */ React__default.default.createElement("span", { className: styles.configuredBadge }, /* @__PURE__ */ React__default.default.createElement(ui.Icon, { name: "lock", size: "xs" }), "Configured"), !disabled && /* @__PURE__ */ React__default.default.createElement(ui.Button, { variant: "secondary", fill: "text", size: "sm", onClick: () => formField.onChange(""), type: "button" }, "Reset"));
|
|
9018
9246
|
}
|
|
9019
9247
|
return /* @__PURE__ */ React__default.default.createElement(
|
|
9020
9248
|
ui.Input,
|
|
@@ -9043,7 +9271,8 @@ const getSecureFieldStyles = (theme) => ({
|
|
|
9043
9271
|
configuredRow: css.css({
|
|
9044
9272
|
display: "flex",
|
|
9045
9273
|
alignItems: "center",
|
|
9046
|
-
gap: theme.spacing(1)
|
|
9274
|
+
gap: theme.spacing(1),
|
|
9275
|
+
whiteSpace: "nowrap"
|
|
9047
9276
|
}),
|
|
9048
9277
|
configuredBadge: css.css({
|
|
9049
9278
|
display: "inline-flex",
|
|
@@ -9053,97 +9282,164 @@ const getSecureFieldStyles = (theme) => ({
|
|
|
9053
9282
|
borderRadius: theme.shape.radius.pill,
|
|
9054
9283
|
backgroundColor: theme.colors.success.transparent,
|
|
9055
9284
|
color: theme.colors.success.text,
|
|
9056
|
-
fontSize: theme.typography.bodySmall.fontSize
|
|
9285
|
+
fontSize: theme.typography.bodySmall.fontSize,
|
|
9286
|
+
whiteSpace: "nowrap"
|
|
9057
9287
|
})
|
|
9058
9288
|
});
|
|
9059
9289
|
|
|
9060
|
-
|
|
9061
|
-
|
|
9062
|
-
|
|
9063
|
-
|
|
9064
|
-
|
|
9065
|
-
|
|
9066
|
-
|
|
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({
|
|
9290
|
+
const ComplexFieldNote = (props) => {
|
|
9291
|
+
const { count, label } = props;
|
|
9292
|
+
const styles = ui.useStyles2(getStyles$g);
|
|
9293
|
+
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."));
|
|
9294
|
+
};
|
|
9295
|
+
const getStyles$g = (theme) => ({
|
|
9296
|
+
note: css.css({
|
|
9116
9297
|
display: "inline-flex",
|
|
9117
9298
|
alignItems: "center",
|
|
9118
|
-
gap: theme.spacing(0.
|
|
9119
|
-
padding: `${theme.spacing(0.
|
|
9120
|
-
borderRadius: theme.shape.radius.pill,
|
|
9121
|
-
backgroundColor: theme.colors.background.secondary,
|
|
9122
|
-
border: `1px solid ${theme.colors.border.weak}`,
|
|
9299
|
+
gap: theme.spacing(0.5),
|
|
9300
|
+
padding: `${theme.spacing(0.5)} ${theme.spacing(0.75)}`,
|
|
9123
9301
|
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
9302
|
color: theme.colors.text.secondary,
|
|
9134
|
-
|
|
9303
|
+
backgroundColor: theme.colors.background.secondary,
|
|
9304
|
+
borderRadius: theme.shape.radius.default,
|
|
9305
|
+
border: `1px solid ${theme.colors.border.weak}`
|
|
9135
9306
|
})
|
|
9136
9307
|
});
|
|
9137
9308
|
|
|
9138
|
-
function
|
|
9139
|
-
|
|
9140
|
-
|
|
9141
|
-
|
|
9142
|
-
|
|
9143
|
-
|
|
9144
|
-
|
|
9145
|
-
|
|
9146
|
-
const
|
|
9309
|
+
function FileUploadField(props) {
|
|
9310
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
9311
|
+
const { field, formField, disabled, setValue } = props;
|
|
9312
|
+
const [mode, setModeLocal] = React.useState("upload");
|
|
9313
|
+
const [error, setError] = React.useState(null);
|
|
9314
|
+
const theme = ui.useTheme2();
|
|
9315
|
+
const mapping = (_a = field.ui) == null ? void 0 : _a.fileMapping;
|
|
9316
|
+
const accept = (_c = (_b = field.ui) == null ? void 0 : _b.accept) != null ? _c : [".json"];
|
|
9317
|
+
const setMode = React.useCallback(
|
|
9318
|
+
(next) => {
|
|
9319
|
+
setModeLocal(next);
|
|
9320
|
+
formField.onChange(next);
|
|
9321
|
+
},
|
|
9322
|
+
[formField]
|
|
9323
|
+
);
|
|
9324
|
+
const processJson = React.useCallback(
|
|
9325
|
+
(text) => {
|
|
9326
|
+
const fileMapping = mapping != null ? mapping : {};
|
|
9327
|
+
try {
|
|
9328
|
+
const parsed = JSON.parse(text);
|
|
9329
|
+
if (typeof parsed !== "object" || parsed === null) {
|
|
9330
|
+
setError("Invalid JSON object");
|
|
9331
|
+
return;
|
|
9332
|
+
}
|
|
9333
|
+
const requiredKeys = Object.keys(fileMapping);
|
|
9334
|
+
const missingKeys = requiredKeys.filter((k) => parsed[k] === void 0);
|
|
9335
|
+
if (missingKeys.length > 0) {
|
|
9336
|
+
setError(`Missing keys: ${missingKeys.join(", ")}`);
|
|
9337
|
+
return;
|
|
9338
|
+
}
|
|
9339
|
+
for (const [jsonKey, targetFieldId] of Object.entries(fileMapping)) {
|
|
9340
|
+
if (parsed[jsonKey] !== void 0) {
|
|
9341
|
+
const parts = targetFieldId.split(".");
|
|
9342
|
+
const fk = parts.length === 2 ? parts[1] : targetFieldId;
|
|
9343
|
+
setValue(fk, parsed[jsonKey]);
|
|
9344
|
+
}
|
|
9345
|
+
}
|
|
9346
|
+
setError(null);
|
|
9347
|
+
setModeLocal("manual");
|
|
9348
|
+
formField.onChange("manual");
|
|
9349
|
+
} catch (e) {
|
|
9350
|
+
setError("Invalid JSON");
|
|
9351
|
+
}
|
|
9352
|
+
},
|
|
9353
|
+
[mapping, setValue, formField]
|
|
9354
|
+
);
|
|
9355
|
+
const styles = getStyles$f(theme);
|
|
9356
|
+
if (mode === "manual") {
|
|
9357
|
+
return /* @__PURE__ */ React__default.default.createElement("div", { className: styles.buttonRow }, /* @__PURE__ */ React__default.default.createElement(ui.Button, { type: "button", fill: "outline", size: "sm", onClick: () => setMode("paste"), disabled }, "Paste JWT Token"), /* @__PURE__ */ React__default.default.createElement("span", { className: styles.separator }, "or"), /* @__PURE__ */ React__default.default.createElement(ui.Button, { type: "button", fill: "outline", size: "sm", onClick: () => setMode("upload"), disabled }, "Upload JWT Token"));
|
|
9358
|
+
}
|
|
9359
|
+
if (mode === "paste") {
|
|
9360
|
+
return /* @__PURE__ */ React__default.default.createElement("div", null, /* @__PURE__ */ React__default.default.createElement(
|
|
9361
|
+
ui.TextArea,
|
|
9362
|
+
{
|
|
9363
|
+
placeholder: (_e = (_d = field.ui) == null ? void 0 : _d.placeholder) != null ? _e : "Paste Google JWT token here",
|
|
9364
|
+
rows: (_g = (_f = field.ui) == null ? void 0 : _f.rows) != null ? _g : 10,
|
|
9365
|
+
onBlur: (e) => {
|
|
9366
|
+
const val = e.currentTarget.value;
|
|
9367
|
+
if (val.trim()) {
|
|
9368
|
+
processJson(val);
|
|
9369
|
+
}
|
|
9370
|
+
},
|
|
9371
|
+
disabled
|
|
9372
|
+
}
|
|
9373
|
+
), /* @__PURE__ */ React__default.default.createElement("div", { className: styles.buttonRow }, /* @__PURE__ */ React__default.default.createElement(ui.Button, { type: "button", fill: "outline", size: "sm", onClick: () => setMode("upload"), disabled }, "Upload JWT Token"), /* @__PURE__ */ React__default.default.createElement("span", { className: styles.separator }, "or"), /* @__PURE__ */ React__default.default.createElement(ui.Button, { type: "button", fill: "outline", size: "sm", onClick: () => setMode("manual"), disabled }, "Fill In JWT Token manually")), error && /* @__PURE__ */ React__default.default.createElement("span", { className: styles.error }, error));
|
|
9374
|
+
}
|
|
9375
|
+
return /* @__PURE__ */ React__default.default.createElement("div", null, /* @__PURE__ */ React__default.default.createElement(
|
|
9376
|
+
ui.FileDropzone,
|
|
9377
|
+
{
|
|
9378
|
+
options: { multiple: false, accept: accept.join(",") },
|
|
9379
|
+
readAs: "readAsText",
|
|
9380
|
+
onLoad: (result) => {
|
|
9381
|
+
if (typeof result === "string") {
|
|
9382
|
+
processJson(result);
|
|
9383
|
+
}
|
|
9384
|
+
}
|
|
9385
|
+
}
|
|
9386
|
+
), /* @__PURE__ */ React__default.default.createElement("div", { className: styles.buttonRow }, /* @__PURE__ */ React__default.default.createElement(ui.Button, { type: "button", fill: "outline", size: "sm", onClick: () => setMode("paste"), disabled }, "Paste JWT Token"), /* @__PURE__ */ React__default.default.createElement("span", { className: styles.separator }, "or"), /* @__PURE__ */ React__default.default.createElement(ui.Button, { type: "button", fill: "outline", size: "sm", onClick: () => setMode("manual"), disabled }, "Fill In JWT Token manually")), error && /* @__PURE__ */ React__default.default.createElement("span", { className: styles.error }, error));
|
|
9387
|
+
}
|
|
9388
|
+
function getStyles$f(theme) {
|
|
9389
|
+
return {
|
|
9390
|
+
buttonRow: css.css({
|
|
9391
|
+
marginTop: theme.spacing(1),
|
|
9392
|
+
display: "flex",
|
|
9393
|
+
alignItems: "center",
|
|
9394
|
+
gap: theme.spacing(0.5)
|
|
9395
|
+
}),
|
|
9396
|
+
separator: css.css({
|
|
9397
|
+
padding: `0 ${theme.spacing(0.5)}`,
|
|
9398
|
+
color: theme.colors.text.secondary
|
|
9399
|
+
}),
|
|
9400
|
+
error: css.css({
|
|
9401
|
+
color: theme.colors.error.text,
|
|
9402
|
+
fontSize: theme.typography.bodySmall.fontSize,
|
|
9403
|
+
marginTop: theme.spacing(0.5),
|
|
9404
|
+
display: "block"
|
|
9405
|
+
})
|
|
9406
|
+
};
|
|
9407
|
+
}
|
|
9408
|
+
|
|
9409
|
+
const IndexedPairEditor = (props) => {
|
|
9410
|
+
const { value, onChange, maxItems = 10, disabled, hideControls, itemLabel = "header" } = props;
|
|
9411
|
+
const styles = ui.useStyles2(getStyles$e);
|
|
9412
|
+
const items = Array.isArray(value) ? value : [];
|
|
9413
|
+
const addItem = () => {
|
|
9414
|
+
if (items.length >= maxItems) {
|
|
9415
|
+
return;
|
|
9416
|
+
}
|
|
9417
|
+
onChange([...items, { index: 0, name: "", value: "" }]);
|
|
9418
|
+
};
|
|
9419
|
+
const removeItem = (index) => {
|
|
9420
|
+
onChange(items.filter((_, i) => i !== index));
|
|
9421
|
+
};
|
|
9422
|
+
const updateItem = (index, key, val) => {
|
|
9423
|
+
const updated = items.map((item, i) => i === index ? { ...item, [key]: val } : item);
|
|
9424
|
+
onChange(updated);
|
|
9425
|
+
};
|
|
9426
|
+
return /* @__PURE__ */ React__default.default.createElement(ui.Stack, { direction: "column", gap: 0.5 }, items.map((item, i) => /* @__PURE__ */ React__default.default.createElement(
|
|
9427
|
+
IndexedPairRow,
|
|
9428
|
+
{
|
|
9429
|
+
key: item.index || `new-${i}`,
|
|
9430
|
+
item,
|
|
9431
|
+
index: i,
|
|
9432
|
+
disabled,
|
|
9433
|
+
onUpdate: updateItem,
|
|
9434
|
+
onRemove: removeItem,
|
|
9435
|
+
hideControls,
|
|
9436
|
+
itemLabel
|
|
9437
|
+
}
|
|
9438
|
+
)), !hideControls && items.length < maxItems && /* @__PURE__ */ React__default.default.createElement("div", null, /* @__PURE__ */ React__default.default.createElement(ui.Button, { variant: "secondary", size: "sm", icon: "plus", disabled, onClick: addItem, type: "button" }, "Add ", itemLabel)), !hideControls && items.length >= maxItems && /* @__PURE__ */ React__default.default.createElement("span", { className: styles.limitNote }, "Maximum ", maxItems, " ", itemLabel, "s reached"));
|
|
9439
|
+
};
|
|
9440
|
+
const IndexedPairRow = (props) => {
|
|
9441
|
+
const { item, index, disabled, onUpdate, onRemove, hideControls, itemLabel = "header" } = props;
|
|
9442
|
+
const styles = ui.useStyles2(getStyles$e);
|
|
9147
9443
|
const secureStyles = ui.useStyles2(getSecureFieldStyles);
|
|
9148
9444
|
const isConfigured = item.value === SECURE_FIELD_CONFIGURED;
|
|
9149
9445
|
const [editing, setEditing] = React.useState(false);
|
|
@@ -9152,9 +9448,14 @@ function IndexedPairRow({
|
|
|
9152
9448
|
ui.Input,
|
|
9153
9449
|
{
|
|
9154
9450
|
value: item.name,
|
|
9155
|
-
placeholder: "
|
|
9451
|
+
placeholder: "key",
|
|
9156
9452
|
disabled: disabled || hideControls,
|
|
9157
|
-
onChange: (e) => onUpdate(index, "name", e.currentTarget.value)
|
|
9453
|
+
onChange: (e) => onUpdate(index, "name", e.currentTarget.value),
|
|
9454
|
+
onKeyDown: (e) => {
|
|
9455
|
+
if (e.key === "Enter") {
|
|
9456
|
+
e.preventDefault();
|
|
9457
|
+
}
|
|
9458
|
+
}
|
|
9158
9459
|
}
|
|
9159
9460
|
)), /* @__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
9461
|
ui.Button,
|
|
@@ -9173,10 +9474,15 @@ function IndexedPairRow({
|
|
|
9173
9474
|
ui.Input,
|
|
9174
9475
|
{
|
|
9175
9476
|
value: item.value === SECURE_FIELD_CONFIGURED ? "" : item.value,
|
|
9176
|
-
placeholder:
|
|
9477
|
+
placeholder: `${itemLabel} value`,
|
|
9177
9478
|
disabled,
|
|
9178
9479
|
type: revealed ? "text" : "password",
|
|
9179
9480
|
onChange: (e) => onUpdate(index, "value", e.currentTarget.value),
|
|
9481
|
+
onKeyDown: (e) => {
|
|
9482
|
+
if (e.key === "Enter") {
|
|
9483
|
+
e.preventDefault();
|
|
9484
|
+
}
|
|
9485
|
+
},
|
|
9180
9486
|
suffix: /* @__PURE__ */ React__default.default.createElement(
|
|
9181
9487
|
ui.Button,
|
|
9182
9488
|
{
|
|
@@ -9190,34 +9496,56 @@ function IndexedPairRow({
|
|
|
9190
9496
|
}
|
|
9191
9497
|
)
|
|
9192
9498
|
}
|
|
9193
|
-
)), !hideControls && /* @__PURE__ */ React__default.default.createElement(ui.Tooltip, { content:
|
|
9499
|
+
)), !hideControls && /* @__PURE__ */ React__default.default.createElement(ui.Tooltip, { content: `Remove ${itemLabel}` }, /* @__PURE__ */ React__default.default.createElement(
|
|
9194
9500
|
ui.Button,
|
|
9195
9501
|
{
|
|
9196
9502
|
variant: "secondary",
|
|
9197
9503
|
fill: "text",
|
|
9198
9504
|
size: "sm",
|
|
9199
9505
|
icon: "trash-alt",
|
|
9200
|
-
"aria-label":
|
|
9506
|
+
"aria-label": `Remove ${itemLabel}`,
|
|
9201
9507
|
disabled,
|
|
9202
9508
|
onClick: () => onRemove(index),
|
|
9203
9509
|
type: "button"
|
|
9204
9510
|
}
|
|
9205
9511
|
)));
|
|
9206
|
-
}
|
|
9207
|
-
|
|
9208
|
-
|
|
9209
|
-
|
|
9210
|
-
|
|
9211
|
-
|
|
9212
|
-
|
|
9213
|
-
|
|
9512
|
+
};
|
|
9513
|
+
const getStyles$e = (theme) => ({
|
|
9514
|
+
inputCell: css.css({
|
|
9515
|
+
flex: "1 1 0",
|
|
9516
|
+
minWidth: 0,
|
|
9517
|
+
overflow: "hidden"
|
|
9518
|
+
}),
|
|
9519
|
+
limitNote: css.css({
|
|
9520
|
+
fontSize: theme.typography.bodySmall.fontSize,
|
|
9521
|
+
color: theme.colors.text.secondary
|
|
9522
|
+
})
|
|
9523
|
+
});
|
|
9524
|
+
|
|
9525
|
+
function ObjectArrayEditor(props) {
|
|
9526
|
+
var _a, _b, _c, _d, _e, _f;
|
|
9527
|
+
const { field, value, onChange, disabled, errorMessage } = props;
|
|
9214
9528
|
const styles = ui.useStyles2(getStyles$d);
|
|
9529
|
+
const itemFields = (_b = (_a = field.item) == null ? void 0 : _a.fields) != null ? _b : [];
|
|
9530
|
+
const layoutRows = computeLayoutRows(itemFields);
|
|
9215
9531
|
const items = Array.isArray(value) ? value : [];
|
|
9532
|
+
const maxItems = (_e = (_d = (_c = field.validations) == null ? void 0 : _c.find((v) => v.type === "itemCount")) == null ? void 0 : _d.max) != null ? _e : 20;
|
|
9533
|
+
const label = (_f = field.label) != null ? _f : field.key;
|
|
9534
|
+
const itemErrors = parseItemErrors(errorMessage);
|
|
9216
9535
|
const addItem = () => {
|
|
9536
|
+
var _a2, _b2;
|
|
9217
9537
|
if (items.length >= maxItems) {
|
|
9218
9538
|
return;
|
|
9219
9539
|
}
|
|
9220
|
-
|
|
9540
|
+
const empty = {};
|
|
9541
|
+
for (const f of itemFields) {
|
|
9542
|
+
if (f.valueType === "boolean") {
|
|
9543
|
+
empty[f.key] = (_a2 = f.defaultValue) != null ? _a2 : false;
|
|
9544
|
+
} else {
|
|
9545
|
+
empty[f.key] = (_b2 = f.defaultValue) != null ? _b2 : "";
|
|
9546
|
+
}
|
|
9547
|
+
}
|
|
9548
|
+
onChange([...items, empty]);
|
|
9221
9549
|
};
|
|
9222
9550
|
const removeItem = (index) => {
|
|
9223
9551
|
onChange(items.filter((_, i) => i !== index));
|
|
@@ -9226,78 +9554,241 @@ function IndexedPairEditor({
|
|
|
9226
9554
|
const updated = items.map((item, i) => i === index ? { ...item, [key]: val } : item);
|
|
9227
9555
|
onChange(updated);
|
|
9228
9556
|
};
|
|
9229
|
-
return /* @__PURE__ */ React__default.default.createElement(ui.Stack, { direction: "column", gap:
|
|
9230
|
-
|
|
9557
|
+
return /* @__PURE__ */ React__default.default.createElement(ui.Stack, { direction: "column", gap: 1 }, items.map((item, i) => /* @__PURE__ */ React__default.default.createElement(
|
|
9558
|
+
ObjectArrayItemRow,
|
|
9231
9559
|
{
|
|
9232
|
-
key:
|
|
9560
|
+
key: i,
|
|
9233
9561
|
item,
|
|
9234
9562
|
index: i,
|
|
9235
|
-
|
|
9563
|
+
itemFields,
|
|
9564
|
+
layoutRows,
|
|
9565
|
+
disabled: !!disabled,
|
|
9236
9566
|
onUpdate: updateItem,
|
|
9237
9567
|
onRemove: removeItem,
|
|
9238
|
-
|
|
9568
|
+
showLabels: true,
|
|
9569
|
+
error: itemErrors == null ? void 0 : itemErrors[i]
|
|
9570
|
+
}
|
|
9571
|
+
)), items.length < maxItems && /* @__PURE__ */ React__default.default.createElement("div", null, /* @__PURE__ */ React__default.default.createElement(ui.Button, { variant: "secondary", size: "sm", icon: "plus", disabled, onClick: addItem, type: "button" }, "Add ", label.toLowerCase())), items.length >= maxItems && /* @__PURE__ */ React__default.default.createElement("span", { className: styles.limitNote }, "Maximum ", maxItems, " items reached"));
|
|
9572
|
+
}
|
|
9573
|
+
function computeLayoutRows(fields) {
|
|
9574
|
+
var _a;
|
|
9575
|
+
const hasExplicitRow = fields.some((f) => {
|
|
9576
|
+
var _a2;
|
|
9577
|
+
return ((_a2 = f.ui) == null ? void 0 : _a2.row) !== void 0;
|
|
9578
|
+
});
|
|
9579
|
+
if (!hasExplicitRow) {
|
|
9580
|
+
if (fields.length <= 3) {
|
|
9581
|
+
return [fields];
|
|
9582
|
+
}
|
|
9583
|
+
return fields.map((f) => [f]);
|
|
9584
|
+
}
|
|
9585
|
+
const rowMap = /* @__PURE__ */ new Map();
|
|
9586
|
+
const noRow = [];
|
|
9587
|
+
for (const f of fields) {
|
|
9588
|
+
if (((_a = f.ui) == null ? void 0 : _a.row) !== void 0) {
|
|
9589
|
+
const existing = rowMap.get(f.ui.row);
|
|
9590
|
+
if (existing) {
|
|
9591
|
+
existing.push(f);
|
|
9592
|
+
} else {
|
|
9593
|
+
rowMap.set(f.ui.row, [f]);
|
|
9594
|
+
}
|
|
9595
|
+
} else {
|
|
9596
|
+
noRow.push(f);
|
|
9239
9597
|
}
|
|
9240
|
-
|
|
9598
|
+
}
|
|
9599
|
+
const sortedKeys = [...rowMap.keys()].sort((a, b) => a - b);
|
|
9600
|
+
const rows = sortedKeys.map((k) => rowMap.get(k));
|
|
9601
|
+
for (const f of noRow) {
|
|
9602
|
+
rows.push([f]);
|
|
9603
|
+
}
|
|
9604
|
+
return rows;
|
|
9605
|
+
}
|
|
9606
|
+
function makeItemFormField(item, index, fieldKey, onUpdate) {
|
|
9607
|
+
return {
|
|
9608
|
+
name: `item-${index}-${fieldKey}`,
|
|
9609
|
+
value: item[fieldKey],
|
|
9610
|
+
onChange: (eventOrValue) => {
|
|
9611
|
+
if (eventOrValue != null && typeof eventOrValue === "object" && "target" in eventOrValue) {
|
|
9612
|
+
onUpdate(index, fieldKey, eventOrValue.target.value);
|
|
9613
|
+
} else {
|
|
9614
|
+
onUpdate(index, fieldKey, eventOrValue);
|
|
9615
|
+
}
|
|
9616
|
+
},
|
|
9617
|
+
onBlur: () => {
|
|
9618
|
+
}
|
|
9619
|
+
};
|
|
9620
|
+
}
|
|
9621
|
+
function effectiveItemField(field, isSecure) {
|
|
9622
|
+
if (!isSecure) {
|
|
9623
|
+
return field;
|
|
9624
|
+
}
|
|
9625
|
+
return { ...field, semanticType: "password" };
|
|
9626
|
+
}
|
|
9627
|
+
function ObjectArrayItemRow({
|
|
9628
|
+
item,
|
|
9629
|
+
index,
|
|
9630
|
+
itemFields,
|
|
9631
|
+
layoutRows,
|
|
9632
|
+
disabled,
|
|
9633
|
+
onUpdate,
|
|
9634
|
+
onRemove,
|
|
9635
|
+
showLabels,
|
|
9636
|
+
error
|
|
9637
|
+
}) {
|
|
9638
|
+
const styles = ui.useStyles2(getStyles$d);
|
|
9639
|
+
const secureOverride = findActiveSecureOverride(itemFields, item, index);
|
|
9640
|
+
return /* @__PURE__ */ React__default.default.createElement("div", { className: styles.itemRow }, layoutRows.map((row, rowIdx) => /* @__PURE__ */ React__default.default.createElement(ui.Stack, { key: rowIdx, direction: "row", gap: 1, alignItems: "flex-end", wrap: "wrap" }, row.map((field) => {
|
|
9641
|
+
var _a;
|
|
9642
|
+
const isSecureTarget = (secureOverride == null ? void 0 : secureOverride.fieldKey) === field.key;
|
|
9643
|
+
const eff = effectiveItemField(field, !!isSecureTarget);
|
|
9644
|
+
const formField = makeItemFormField(item, index, field.key, onUpdate);
|
|
9645
|
+
if (isSecureTarget && item[field.key] === SECURE_FIELD_CONFIGURED) {
|
|
9646
|
+
formField.value = SECURE_FIELD_CONFIGURED;
|
|
9647
|
+
}
|
|
9648
|
+
return /* @__PURE__ */ React__default.default.createElement("div", { key: field.key, className: field.valueType === "boolean" ? styles.boolCell : styles.inputCell }, /* @__PURE__ */ React__default.default.createElement("span", { className: styles.cellLabel }, (_a = field.label) != null ? _a : field.key, field.required && /* @__PURE__ */ React__default.default.createElement("span", { className: styles.required }, " *")), renderFieldInput(eff, formField, disabled));
|
|
9649
|
+
}), rowIdx === 0 && /* @__PURE__ */ React__default.default.createElement("div", { className: styles.removeCellWithLabel }, /* @__PURE__ */ React__default.default.createElement(ui.Tooltip, { content: "Remove" }, /* @__PURE__ */ React__default.default.createElement(
|
|
9650
|
+
ui.Button,
|
|
9651
|
+
{
|
|
9652
|
+
variant: "secondary",
|
|
9653
|
+
fill: "text",
|
|
9654
|
+
size: "sm",
|
|
9655
|
+
icon: "trash-alt",
|
|
9656
|
+
"aria-label": "Remove item",
|
|
9657
|
+
disabled,
|
|
9658
|
+
onClick: () => onRemove(index),
|
|
9659
|
+
type: "button"
|
|
9660
|
+
}
|
|
9661
|
+
))))), error && /* @__PURE__ */ React__default.default.createElement("span", { className: styles.itemError }, error));
|
|
9241
9662
|
}
|
|
9242
9663
|
const getStyles$d = (theme) => ({
|
|
9664
|
+
itemRow: css.css({
|
|
9665
|
+
display: "flex",
|
|
9666
|
+
flexDirection: "column",
|
|
9667
|
+
gap: theme.spacing(0.5),
|
|
9668
|
+
padding: theme.spacing(1),
|
|
9669
|
+
borderRadius: theme.shape.radius.default,
|
|
9670
|
+
border: `1px solid ${theme.colors.border.weak}`
|
|
9671
|
+
}),
|
|
9243
9672
|
inputCell: css.css({
|
|
9244
|
-
flex: "1 1
|
|
9245
|
-
minWidth:
|
|
9673
|
+
flex: "1 1 120px",
|
|
9674
|
+
minWidth: 120,
|
|
9246
9675
|
overflow: "hidden"
|
|
9247
9676
|
}),
|
|
9677
|
+
boolCell: css.css({
|
|
9678
|
+
flex: "0 0 auto",
|
|
9679
|
+
minWidth: 0
|
|
9680
|
+
}),
|
|
9681
|
+
cellLabel: css.css({
|
|
9682
|
+
fontSize: theme.typography.bodySmall.fontSize,
|
|
9683
|
+
color: theme.colors.text.secondary,
|
|
9684
|
+
marginBottom: theme.spacing(0.25)
|
|
9685
|
+
}),
|
|
9686
|
+
required: css.css({
|
|
9687
|
+
color: theme.colors.error.text
|
|
9688
|
+
}),
|
|
9689
|
+
removeCellWithLabel: css.css({
|
|
9690
|
+
flex: "0 0 auto",
|
|
9691
|
+
display: "flex",
|
|
9692
|
+
alignItems: "flex-end",
|
|
9693
|
+
paddingBottom: theme.spacing(0.25)
|
|
9694
|
+
}),
|
|
9695
|
+
itemError: css.css({
|
|
9696
|
+
fontSize: theme.typography.bodySmall.fontSize,
|
|
9697
|
+
color: theme.colors.error.text
|
|
9698
|
+
}),
|
|
9248
9699
|
limitNote: css.css({
|
|
9249
9700
|
fontSize: theme.typography.bodySmall.fontSize,
|
|
9250
9701
|
color: theme.colors.text.secondary
|
|
9251
9702
|
})
|
|
9252
9703
|
});
|
|
9253
9704
|
|
|
9254
|
-
|
|
9705
|
+
const StringArrayInput = (props) => {
|
|
9706
|
+
const { value, onChange, placeholder, disabled, itemLabel = "item" } = props;
|
|
9255
9707
|
const styles = ui.useStyles2(getStyles$c);
|
|
9256
|
-
|
|
9257
|
-
|
|
9708
|
+
const items = Array.isArray(value) ? value : [];
|
|
9709
|
+
const lastInputRef = React.useRef(null);
|
|
9710
|
+
const shouldFocusLastRef = React.useRef(false);
|
|
9711
|
+
React.useEffect(() => {
|
|
9712
|
+
if (shouldFocusLastRef.current && lastInputRef.current) {
|
|
9713
|
+
lastInputRef.current.focus();
|
|
9714
|
+
shouldFocusLastRef.current = false;
|
|
9715
|
+
}
|
|
9716
|
+
}, [items.length]);
|
|
9717
|
+
const addItem = () => {
|
|
9718
|
+
shouldFocusLastRef.current = true;
|
|
9719
|
+
onChange([...items, ""]);
|
|
9720
|
+
};
|
|
9721
|
+
const removeItem = (index) => {
|
|
9722
|
+
onChange(items.filter((_, i) => i !== index));
|
|
9723
|
+
};
|
|
9724
|
+
const updateItem = (index, val) => {
|
|
9725
|
+
onChange(items.map((item, i) => i === index ? val : item));
|
|
9726
|
+
};
|
|
9727
|
+
const isItemValid = (index, val) => {
|
|
9728
|
+
const trimmed = val.trim();
|
|
9729
|
+
if (trimmed === "") {
|
|
9730
|
+
return false;
|
|
9731
|
+
}
|
|
9732
|
+
return !items.some((item, i) => i !== index && item.trim() === trimmed);
|
|
9733
|
+
};
|
|
9734
|
+
const handleEnter = (index, currentValue) => {
|
|
9735
|
+
if (!isItemValid(index, currentValue)) {
|
|
9736
|
+
return;
|
|
9737
|
+
}
|
|
9738
|
+
if (index === items.length - 1) {
|
|
9739
|
+
shouldFocusLastRef.current = true;
|
|
9740
|
+
onChange([...items, ""]);
|
|
9741
|
+
}
|
|
9742
|
+
};
|
|
9743
|
+
return /* @__PURE__ */ React__default.default.createElement(ui.Stack, { direction: "column", gap: 0.5 }, items.map((item, i) => /* @__PURE__ */ React__default.default.createElement(ui.Stack, { direction: "row", gap: 1, key: i }, /* @__PURE__ */ React__default.default.createElement("div", { className: styles.inputCell }, /* @__PURE__ */ React__default.default.createElement(
|
|
9744
|
+
ui.Input,
|
|
9745
|
+
{
|
|
9746
|
+
ref: i === items.length - 1 ? lastInputRef : void 0,
|
|
9747
|
+
value: item,
|
|
9748
|
+
placeholder: placeholder != null ? placeholder : itemLabel,
|
|
9749
|
+
disabled,
|
|
9750
|
+
onChange: (e) => updateItem(i, e.currentTarget.value),
|
|
9751
|
+
onKeyDown: (e) => {
|
|
9752
|
+
if (e.key === "Enter") {
|
|
9753
|
+
e.preventDefault();
|
|
9754
|
+
handleEnter(i, e.currentTarget.value);
|
|
9755
|
+
}
|
|
9756
|
+
}
|
|
9757
|
+
}
|
|
9758
|
+
)), !disabled && /* @__PURE__ */ React__default.default.createElement(ui.Tooltip, { content: `Remove ${itemLabel}` }, /* @__PURE__ */ React__default.default.createElement(
|
|
9759
|
+
ui.Button,
|
|
9760
|
+
{
|
|
9761
|
+
variant: "secondary",
|
|
9762
|
+
fill: "text",
|
|
9763
|
+
size: "sm",
|
|
9764
|
+
icon: "trash-alt",
|
|
9765
|
+
"aria-label": `Remove ${itemLabel}`,
|
|
9766
|
+
onClick: () => removeItem(i),
|
|
9767
|
+
type: "button"
|
|
9768
|
+
}
|
|
9769
|
+
)))), !disabled && /* @__PURE__ */ React__default.default.createElement("div", null, /* @__PURE__ */ React__default.default.createElement(ui.Button, { variant: "secondary", size: "sm", icon: "plus", onClick: addItem, type: "button" }, "Add")));
|
|
9770
|
+
};
|
|
9258
9771
|
const getStyles$c = (theme) => ({
|
|
9259
|
-
|
|
9260
|
-
|
|
9261
|
-
|
|
9262
|
-
|
|
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}`
|
|
9772
|
+
inputCell: css.css({
|
|
9773
|
+
flex: "1 1 0",
|
|
9774
|
+
minWidth: 0,
|
|
9775
|
+
overflow: "hidden"
|
|
9269
9776
|
})
|
|
9270
9777
|
});
|
|
9271
9778
|
|
|
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;
|
|
9779
|
+
function renderFieldInput(field, formField, disabled, errorMessage, setValue) {
|
|
9780
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w;
|
|
9274
9781
|
const value = formField.value;
|
|
9275
9782
|
const placeholder = (_a = field.ui) == null ? void 0 : _a.placeholder;
|
|
9276
9783
|
const label = (_b = field.label) != null ? _b : field.key;
|
|
9784
|
+
if (((_c = field.ui) == null ? void 0 : _c.component) === "fileUpload" && field.ui.fileMapping && setValue) {
|
|
9785
|
+
return /* @__PURE__ */ React__default.default.createElement(FileUploadField, { field, formField, disabled, setValue });
|
|
9786
|
+
}
|
|
9277
9787
|
if (field.target === "secureJsonData" || field.semanticType === "password" || field.semanticType === "token") {
|
|
9278
9788
|
return /* @__PURE__ */ React__default.default.createElement(SecureFieldInput, { formField, placeholder: placeholder != null ? placeholder : label, disabled, label });
|
|
9279
9789
|
}
|
|
9280
|
-
if (field.
|
|
9281
|
-
|
|
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) => ({
|
|
9790
|
+
if (((_d = field.ui) == null ? void 0 : _d.component) === "radio") {
|
|
9791
|
+
const options = ((_f = (_e = field.ui) == null ? void 0 : _e.options) != null ? _f : []).map((opt) => ({
|
|
9301
9792
|
label: opt.label,
|
|
9302
9793
|
value: String(opt.value),
|
|
9303
9794
|
description: opt.description
|
|
@@ -9307,13 +9798,20 @@ function renderFieldInput(field, formField, disabled) {
|
|
|
9307
9798
|
{
|
|
9308
9799
|
options,
|
|
9309
9800
|
value: String(value != null ? value : ""),
|
|
9310
|
-
onChange: (v) =>
|
|
9801
|
+
onChange: (v) => {
|
|
9802
|
+
if (field.valueType === "number") {
|
|
9803
|
+
const n = Number(v);
|
|
9804
|
+
formField.onChange(Number.isNaN(n) ? v : n);
|
|
9805
|
+
} else {
|
|
9806
|
+
formField.onChange(v);
|
|
9807
|
+
}
|
|
9808
|
+
},
|
|
9311
9809
|
disabled
|
|
9312
9810
|
}
|
|
9313
9811
|
));
|
|
9314
9812
|
}
|
|
9315
|
-
if (((
|
|
9316
|
-
const options = ((
|
|
9813
|
+
if (((_g = field.ui) == null ? void 0 : _g.component) === "select") {
|
|
9814
|
+
const options = ((_i = (_h = field.ui) == null ? void 0 : _h.options) != null ? _i : []).map((opt) => ({
|
|
9317
9815
|
label: opt.label,
|
|
9318
9816
|
value: String(opt.value),
|
|
9319
9817
|
description: opt.description
|
|
@@ -9328,10 +9826,29 @@ function renderFieldInput(field, formField, disabled) {
|
|
|
9328
9826
|
}
|
|
9329
9827
|
);
|
|
9330
9828
|
}
|
|
9829
|
+
if (field.valueType === "boolean") {
|
|
9830
|
+
return /* @__PURE__ */ React__default.default.createElement(ui.Switch, { value: !!value, onChange: (e) => formField.onChange(e.currentTarget.checked), disabled });
|
|
9831
|
+
}
|
|
9832
|
+
if (field.valueType === "number") {
|
|
9833
|
+
return /* @__PURE__ */ React__default.default.createElement(
|
|
9834
|
+
ui.Input,
|
|
9835
|
+
{
|
|
9836
|
+
...formField,
|
|
9837
|
+
value: value !== void 0 && value !== null ? Number(value) : "",
|
|
9838
|
+
type: "number",
|
|
9839
|
+
placeholder,
|
|
9840
|
+
disabled,
|
|
9841
|
+
onChange: (e) => {
|
|
9842
|
+
const n = e.currentTarget.valueAsNumber;
|
|
9843
|
+
formField.onChange(Number.isNaN(n) ? void 0 : n);
|
|
9844
|
+
}
|
|
9845
|
+
}
|
|
9846
|
+
);
|
|
9847
|
+
}
|
|
9331
9848
|
if (field.semanticType === "url") {
|
|
9332
9849
|
return /* @__PURE__ */ React__default.default.createElement(ui.Input, { ...formField, value: String(value != null ? value : ""), type: "url", placeholder, disabled });
|
|
9333
9850
|
}
|
|
9334
|
-
if (((
|
|
9851
|
+
if (((_j = field.ui) == null ? void 0 : _j.component) === "textarea") {
|
|
9335
9852
|
return /* @__PURE__ */ React__default.default.createElement(
|
|
9336
9853
|
ui.TextArea,
|
|
9337
9854
|
{
|
|
@@ -9339,27 +9856,50 @@ function renderFieldInput(field, formField, disabled) {
|
|
|
9339
9856
|
value: String(value != null ? value : ""),
|
|
9340
9857
|
placeholder,
|
|
9341
9858
|
disabled,
|
|
9342
|
-
rows: (
|
|
9859
|
+
rows: (_l = (_k = field.ui) == null ? void 0 : _k.rows) != null ? _l : 3
|
|
9343
9860
|
}
|
|
9344
9861
|
);
|
|
9345
9862
|
}
|
|
9346
|
-
if (
|
|
9863
|
+
if (((_m = field.storage) == null ? void 0 : _m.type) === "indexedPair") {
|
|
9864
|
+
const items = Array.isArray(value) ? value : [];
|
|
9865
|
+
const maxItems = (_p = (_o = (_n = field.validations) == null ? void 0 : _n.find((v) => v.type === "itemCount")) == null ? void 0 : _o.max) != null ? _p : 10;
|
|
9866
|
+
const itemLabel = (_r = (_q = field.label) == null ? void 0 : _q.toLowerCase().replace(/s$/, "")) != null ? _r : "header";
|
|
9867
|
+
return /* @__PURE__ */ React__default.default.createElement(
|
|
9868
|
+
IndexedPairEditor,
|
|
9869
|
+
{
|
|
9870
|
+
value: items,
|
|
9871
|
+
onChange: formField.onChange,
|
|
9872
|
+
maxItems,
|
|
9873
|
+
disabled,
|
|
9874
|
+
itemLabel
|
|
9875
|
+
}
|
|
9876
|
+
);
|
|
9877
|
+
}
|
|
9878
|
+
if (field.valueType === "array" && ((_s = field.item) == null ? void 0 : _s.valueType) === "string") {
|
|
9347
9879
|
return /* @__PURE__ */ React__default.default.createElement(
|
|
9348
9880
|
StringArrayInput,
|
|
9349
9881
|
{
|
|
9350
9882
|
value: Array.isArray(value) ? value : [],
|
|
9351
9883
|
onChange: formField.onChange,
|
|
9352
|
-
placeholder
|
|
9353
|
-
disabled
|
|
9884
|
+
placeholder,
|
|
9885
|
+
disabled,
|
|
9886
|
+
itemLabel: label.toLowerCase().replace(/s$/, "")
|
|
9354
9887
|
}
|
|
9355
9888
|
);
|
|
9356
9889
|
}
|
|
9357
|
-
if (((
|
|
9358
|
-
|
|
9359
|
-
|
|
9360
|
-
|
|
9890
|
+
if (field.valueType === "array" && ((_t = field.item) == null ? void 0 : _t.valueType) === "object" && ((_u = field.item.fields) == null ? void 0 : _u.length)) {
|
|
9891
|
+
return /* @__PURE__ */ React__default.default.createElement(
|
|
9892
|
+
ObjectArrayEditor,
|
|
9893
|
+
{
|
|
9894
|
+
field,
|
|
9895
|
+
value,
|
|
9896
|
+
onChange: formField.onChange,
|
|
9897
|
+
disabled,
|
|
9898
|
+
errorMessage
|
|
9899
|
+
}
|
|
9900
|
+
);
|
|
9361
9901
|
}
|
|
9362
|
-
if (field.valueType === "object" || field.valueType === "map" || field.valueType === "array" && (((
|
|
9902
|
+
if (field.valueType === "object" || field.valueType === "map" || field.valueType === "array" && (((_v = field.item) == null ? void 0 : _v.valueType) === "object" || ((_w = field.item) == null ? void 0 : _w.valueType) === "map")) {
|
|
9363
9903
|
const count = Array.isArray(value) ? value.length : 0;
|
|
9364
9904
|
return /* @__PURE__ */ React__default.default.createElement(ComplexFieldNote, { count, label });
|
|
9365
9905
|
}
|
|
@@ -9417,8 +9957,8 @@ const getWizardStyles = (theme) => ({
|
|
|
9417
9957
|
color: theme.colors.text.primary
|
|
9418
9958
|
}),
|
|
9419
9959
|
stepCount: css.css({
|
|
9420
|
-
fontSize:
|
|
9421
|
-
fontWeight:
|
|
9960
|
+
fontSize: theme.typography.bodySmall.fontSize,
|
|
9961
|
+
fontWeight: theme.typography.fontWeightRegular,
|
|
9422
9962
|
color: theme.colors.text.secondary
|
|
9423
9963
|
}),
|
|
9424
9964
|
navActions: css.css({
|
|
@@ -9481,12 +10021,22 @@ const getWizardStyles = (theme) => ({
|
|
|
9481
10021
|
minWidth: 0
|
|
9482
10022
|
}),
|
|
9483
10023
|
fieldError: css.css({
|
|
9484
|
-
fontSize:
|
|
10024
|
+
fontSize: theme.typography.bodySmall.fontSize,
|
|
9485
10025
|
color: theme.colors.error.text
|
|
9486
10026
|
})
|
|
9487
10027
|
});
|
|
9488
10028
|
|
|
9489
|
-
function SchemaField({
|
|
10029
|
+
function SchemaField({
|
|
10030
|
+
field,
|
|
10031
|
+
control,
|
|
10032
|
+
errors,
|
|
10033
|
+
disabled,
|
|
10034
|
+
dsUid,
|
|
10035
|
+
watchedValues,
|
|
10036
|
+
fieldById,
|
|
10037
|
+
celContext,
|
|
10038
|
+
setValue
|
|
10039
|
+
}) {
|
|
9490
10040
|
const styles = ui.useStyles2(getWizardStyles);
|
|
9491
10041
|
const activeOverride = resolveActiveOverride(field, watchedValues, fieldById);
|
|
9492
10042
|
const fk = formKey(field);
|
|
@@ -9507,7 +10057,7 @@ function SchemaField({ field, control, errors, disabled, dsUid, watchedValues, f
|
|
|
9507
10057
|
}
|
|
9508
10058
|
);
|
|
9509
10059
|
}
|
|
9510
|
-
const required = isFieldRequired(field, watchedValues, fieldById);
|
|
10060
|
+
const required = isFieldRequired(field, watchedValues, fieldById, celContext);
|
|
9511
10061
|
const validationRules = buildValidationRules(field, required);
|
|
9512
10062
|
return /* @__PURE__ */ React__default.default.createElement(
|
|
9513
10063
|
reactHookForm.Controller,
|
|
@@ -9522,6 +10072,7 @@ function SchemaField({ field, control, errors, disabled, dsUid, watchedValues, f
|
|
|
9522
10072
|
const description = (_c = activeOverride == null ? void 0 : activeOverride.description) != null ? _c : field.description;
|
|
9523
10073
|
const effectiveField = activeOverride ? {
|
|
9524
10074
|
...field,
|
|
10075
|
+
description,
|
|
9525
10076
|
ui: {
|
|
9526
10077
|
...field.ui,
|
|
9527
10078
|
placeholder: (_e = activeOverride.placeholder) != null ? _e : (_d = field.ui) == null ? void 0 : _d.placeholder
|
|
@@ -9529,18 +10080,14 @@ function SchemaField({ field, control, errors, disabled, dsUid, watchedValues, f
|
|
|
9529
10080
|
} : field;
|
|
9530
10081
|
const isReadOnly = !!(activeOverride == null ? void 0 : activeOverride.readOnly);
|
|
9531
10082
|
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)));
|
|
10083
|
+
return /* @__PURE__ */ React__default.default.createElement("div", { className: isBool ? styles.fieldRowCenter : styles.fieldRow }, /* @__PURE__ */ React__default.default.createElement("div", { className: isBool ? styles.fieldLabelRowCompact : styles.fieldLabelRow }, /* @__PURE__ */ React__default.default.createElement("span", { className: styles.fieldLabel }, label, required && /* @__PURE__ */ React__default.default.createElement("span", { className: styles.fieldRequired }, "*")), description && /* @__PURE__ */ React__default.default.createElement(ui.Tooltip, { content: description }, /* @__PURE__ */ React__default.default.createElement(ui.Icon, { name: "info-circle", size: "xs", className: styles.fieldInfoIcon }))), /* @__PURE__ */ React__default.default.createElement("div", { className: styles.fieldInputCol }, renderFieldInput(effectiveField, formField, disabled || isReadOnly, errorMessage, setValue), errorMessage && !parseItemErrors(errorMessage) && /* @__PURE__ */ React__default.default.createElement("span", { className: styles.fieldError }, errorMessage)));
|
|
9533
10084
|
}
|
|
9534
10085
|
}
|
|
9535
10086
|
);
|
|
9536
10087
|
}
|
|
9537
10088
|
|
|
9538
|
-
|
|
9539
|
-
headersFieldKey,
|
|
9540
|
-
control,
|
|
9541
|
-
disabled,
|
|
9542
|
-
watchedValues
|
|
9543
|
-
}) {
|
|
10089
|
+
const AuthorizationHeaderField = (props) => {
|
|
10090
|
+
const { headersFieldKey, control, disabled, watchedValues } = props;
|
|
9544
10091
|
const styles = ui.useStyles2(getWizardStyles);
|
|
9545
10092
|
const items = React.useMemo(
|
|
9546
10093
|
() => Array.isArray(watchedValues[headersFieldKey]) ? watchedValues[headersFieldKey] : [],
|
|
@@ -9578,7 +10125,7 @@ function AuthorizationHeaderField({
|
|
|
9578
10125
|
}
|
|
9579
10126
|
}
|
|
9580
10127
|
);
|
|
9581
|
-
}
|
|
10128
|
+
};
|
|
9582
10129
|
|
|
9583
10130
|
const getTabStyles = (theme) => ({
|
|
9584
10131
|
root: css.css({
|
|
@@ -9628,7 +10175,7 @@ const getTabStyles = (theme) => ({
|
|
|
9628
10175
|
width: 12,
|
|
9629
10176
|
flexShrink: 0,
|
|
9630
10177
|
alignSelf: "flex-start",
|
|
9631
|
-
paddingTop:
|
|
10178
|
+
paddingTop: theme.spacing(0.5)
|
|
9632
10179
|
}),
|
|
9633
10180
|
navDot: css.css({
|
|
9634
10181
|
width: 10,
|
|
@@ -9674,7 +10221,7 @@ const getTabStyles = (theme) => ({
|
|
|
9674
10221
|
}),
|
|
9675
10222
|
navLabel: css.css({
|
|
9676
10223
|
fontSize: theme.typography.body.fontSize,
|
|
9677
|
-
color:
|
|
10224
|
+
color: theme.colors.text.secondary,
|
|
9678
10225
|
lineHeight: 1.4
|
|
9679
10226
|
}),
|
|
9680
10227
|
navLabelActive: css.css({
|
|
@@ -9756,8 +10303,8 @@ const getTabStyles = (theme) => ({
|
|
|
9756
10303
|
textAlign: "left"
|
|
9757
10304
|
}),
|
|
9758
10305
|
sectionBadge: css.css({
|
|
9759
|
-
fontSize:
|
|
9760
|
-
fontWeight:
|
|
10306
|
+
fontSize: theme.typography.bodySmall.fontSize,
|
|
10307
|
+
fontWeight: theme.typography.fontWeightRegular,
|
|
9761
10308
|
color: theme.colors.text.disabled,
|
|
9762
10309
|
border: `1px solid ${theme.colors.border.weak}`,
|
|
9763
10310
|
borderRadius: theme.shape.radius.pill,
|
|
@@ -9875,15 +10422,18 @@ function TabLayout({ form, schema, dsUid, dsName, onRetest, healthError, renderA
|
|
|
9875
10422
|
handleSubmit,
|
|
9876
10423
|
errors,
|
|
9877
10424
|
watchedValues,
|
|
10425
|
+
celContext,
|
|
9878
10426
|
initializing,
|
|
9879
10427
|
fetchError,
|
|
9880
10428
|
submitting,
|
|
9881
10429
|
submitError,
|
|
9882
10430
|
readOnly,
|
|
9883
10431
|
isFieldVisible,
|
|
10432
|
+
isFieldDisabled,
|
|
9884
10433
|
isGroupValid,
|
|
9885
10434
|
groupHasData,
|
|
9886
|
-
onSubmit
|
|
10435
|
+
onSubmit,
|
|
10436
|
+
setValue
|
|
9887
10437
|
} = form;
|
|
9888
10438
|
const displayGroups = React.useMemo(() => resolvedGroups.filter((g) => g.group.id !== "_required"), [resolvedGroups]);
|
|
9889
10439
|
const [expandedSections, setExpandedSections] = React.useState(() => {
|
|
@@ -10011,10 +10561,12 @@ function TabLayout({ form, schema, dsUid, dsName, onRetest, healthError, renderA
|
|
|
10011
10561
|
field,
|
|
10012
10562
|
control,
|
|
10013
10563
|
errors,
|
|
10014
|
-
disabled: allDisabled,
|
|
10564
|
+
disabled: allDisabled || isFieldDisabled(field),
|
|
10015
10565
|
dsUid,
|
|
10016
10566
|
watchedValues,
|
|
10017
|
-
fieldById
|
|
10567
|
+
fieldById,
|
|
10568
|
+
celContext,
|
|
10569
|
+
setValue
|
|
10018
10570
|
}
|
|
10019
10571
|
)), showHeaders && /* @__PURE__ */ React__default.default.createElement(
|
|
10020
10572
|
AuthorizationHeaderField,
|
|
@@ -10128,7 +10680,7 @@ function useDatasourceConfigForm({ schema, dsUid, onSuccess, onSaving }) {
|
|
|
10128
10680
|
return;
|
|
10129
10681
|
}
|
|
10130
10682
|
for (const { sourceKey, effects } of fieldsWithEffects) {
|
|
10131
|
-
const currentVal = watchedValues
|
|
10683
|
+
const currentVal = getWatchedValue(watchedValues, sourceKey);
|
|
10132
10684
|
const prevVal = prevEffectValuesRef.current[sourceKey];
|
|
10133
10685
|
if (currentVal === prevVal) {
|
|
10134
10686
|
continue;
|
|
@@ -10159,6 +10711,7 @@ function useDatasourceConfigForm({ schema, dsUid, onSuccess, onSaving }) {
|
|
|
10159
10711
|
return {
|
|
10160
10712
|
depKey: depField ? formKey(depField) : parsed.field,
|
|
10161
10713
|
depValue: parsed.value,
|
|
10714
|
+
negate: parsed.negate,
|
|
10162
10715
|
defaultValue: ov.defaultValue
|
|
10163
10716
|
};
|
|
10164
10717
|
}).filter(Boolean);
|
|
@@ -10176,42 +10729,70 @@ function useDatasourceConfigForm({ schema, dsUid, onSuccess, onSaving }) {
|
|
|
10176
10729
|
}
|
|
10177
10730
|
for (const { targetKey, fieldDefault, overrides } of fieldsWithOverrideDefaults) {
|
|
10178
10731
|
for (const ov of overrides) {
|
|
10179
|
-
const currentDepVal = String((_a = watchedValues
|
|
10732
|
+
const currentDepVal = String((_a = getWatchedValue(watchedValues, ov.depKey)) != null ? _a : "");
|
|
10180
10733
|
const trackKey = `${targetKey}::${ov.depKey}`;
|
|
10181
10734
|
const prevDepVal = prevOverrideDepRef.current[trackKey];
|
|
10182
10735
|
if (currentDepVal === prevDepVal) {
|
|
10183
10736
|
continue;
|
|
10184
10737
|
}
|
|
10185
10738
|
prevOverrideDepRef.current[trackKey] = currentDepVal;
|
|
10186
|
-
|
|
10739
|
+
const active = evaluateDependsOn({ value: ov.depValue, negate: ov.negate }, currentDepVal);
|
|
10740
|
+
const wasActive = prevDepVal !== void 0 && evaluateDependsOn({ value: ov.depValue, negate: ov.negate }, prevDepVal);
|
|
10741
|
+
if (active) {
|
|
10187
10742
|
setValue(targetKey, ov.defaultValue);
|
|
10188
|
-
} else if (
|
|
10743
|
+
} else if (wasActive && fieldDefault !== void 0) {
|
|
10189
10744
|
setValue(targetKey, fieldDefault);
|
|
10190
10745
|
}
|
|
10191
10746
|
}
|
|
10192
10747
|
}
|
|
10193
10748
|
}, [watchedValues, fieldsWithOverrideDefaults, initializing, setValue]);
|
|
10749
|
+
const celContext = React.useMemo(() => {
|
|
10750
|
+
const ctx = {};
|
|
10751
|
+
for (const f of fieldById.values()) {
|
|
10752
|
+
const fk = formKey(f);
|
|
10753
|
+
const val = getWatchedValue(watchedValues, fk);
|
|
10754
|
+
if (val !== void 0) {
|
|
10755
|
+
const parts = f.id.split(".");
|
|
10756
|
+
let current = ctx;
|
|
10757
|
+
for (let i = 0; i < parts.length - 1; i++) {
|
|
10758
|
+
if (!(parts[i] in current) || typeof current[parts[i]] !== "object" || current[parts[i]] === null) {
|
|
10759
|
+
current[parts[i]] = {};
|
|
10760
|
+
}
|
|
10761
|
+
current = current[parts[i]];
|
|
10762
|
+
}
|
|
10763
|
+
current[parts[parts.length - 1]] = val;
|
|
10764
|
+
}
|
|
10765
|
+
}
|
|
10766
|
+
return ctx;
|
|
10767
|
+
}, [watchedValues, fieldById]);
|
|
10194
10768
|
const isFieldVisible = React.useCallback(
|
|
10195
10769
|
(field) => {
|
|
10196
|
-
|
|
10197
|
-
|
|
10198
|
-
|
|
10199
|
-
|
|
10200
|
-
|
|
10201
|
-
|
|
10202
|
-
|
|
10203
|
-
|
|
10204
|
-
|
|
10205
|
-
|
|
10206
|
-
|
|
10207
|
-
|
|
10208
|
-
|
|
10770
|
+
function check(f, visited) {
|
|
10771
|
+
var _a;
|
|
10772
|
+
if (f.kind === "virtual" && !f.ui) {
|
|
10773
|
+
return false;
|
|
10774
|
+
}
|
|
10775
|
+
if ((_a = f.tags) == null ? void 0 : _a.some((t) => t.startsWith("managed-by:"))) {
|
|
10776
|
+
return false;
|
|
10777
|
+
}
|
|
10778
|
+
if (!f.dependsOn) {
|
|
10779
|
+
return true;
|
|
10780
|
+
}
|
|
10781
|
+
const refs = extractFieldRefs(f.dependsOn);
|
|
10782
|
+
for (const ref of refs) {
|
|
10783
|
+
const depField = fieldById.get(ref);
|
|
10784
|
+
if (depField && !visited.has(depField.id)) {
|
|
10785
|
+
visited.add(f.id);
|
|
10786
|
+
if (!check(depField, visited)) {
|
|
10787
|
+
return false;
|
|
10788
|
+
}
|
|
10789
|
+
}
|
|
10790
|
+
}
|
|
10791
|
+
return evaluateCelExpression(f.dependsOn, celContext);
|
|
10209
10792
|
}
|
|
10210
|
-
|
|
10211
|
-
const depKey = depField ? formKey(depField) : parsed.field;
|
|
10212
|
-
return String((_b = watchedValues[depKey]) != null ? _b : "") === parsed.value;
|
|
10793
|
+
return check(field, /* @__PURE__ */ new Set());
|
|
10213
10794
|
},
|
|
10214
|
-
[
|
|
10795
|
+
[celContext, fieldById]
|
|
10215
10796
|
);
|
|
10216
10797
|
const onSubmit = React.useCallback(
|
|
10217
10798
|
async (data) => {
|
|
@@ -10251,8 +10832,8 @@ function useDatasourceConfigForm({ schema, dsUid, onSuccess, onSaving }) {
|
|
|
10251
10832
|
if (errors[formKey(field)]) {
|
|
10252
10833
|
return false;
|
|
10253
10834
|
}
|
|
10254
|
-
if (isFieldRequired(field, watchedValues, fieldById)) {
|
|
10255
|
-
const val = watchedValues
|
|
10835
|
+
if (isFieldRequired(field, watchedValues, fieldById, celContext)) {
|
|
10836
|
+
const val = getWatchedValue(watchedValues, formKey(field));
|
|
10256
10837
|
if (val === SECURE_FIELD_CONFIGURED) {
|
|
10257
10838
|
continue;
|
|
10258
10839
|
}
|
|
@@ -10263,12 +10844,21 @@ function useDatasourceConfigForm({ schema, dsUid, onSuccess, onSaving }) {
|
|
|
10263
10844
|
}
|
|
10264
10845
|
return true;
|
|
10265
10846
|
},
|
|
10266
|
-
[errors, watchedValues, fieldById, isFieldVisible]
|
|
10847
|
+
[errors, watchedValues, fieldById, celContext, isFieldVisible]
|
|
10848
|
+
);
|
|
10849
|
+
const isFieldDisabled = React.useCallback(
|
|
10850
|
+
(field) => {
|
|
10851
|
+
if (!field.disabledWhen) {
|
|
10852
|
+
return false;
|
|
10853
|
+
}
|
|
10854
|
+
return evaluateCelExpression(field.disabledWhen, celContext);
|
|
10855
|
+
},
|
|
10856
|
+
[celContext]
|
|
10267
10857
|
);
|
|
10268
10858
|
const groupHasData = React.useCallback(
|
|
10269
10859
|
(group) => {
|
|
10270
10860
|
for (const field of group.fields) {
|
|
10271
|
-
const val = watchedValues
|
|
10861
|
+
const val = getWatchedValue(watchedValues, formKey(field));
|
|
10272
10862
|
if (val === void 0 || val === null || val === "" || val === false) {
|
|
10273
10863
|
continue;
|
|
10274
10864
|
}
|
|
@@ -10292,6 +10882,7 @@ function useDatasourceConfigForm({ schema, dsUid, onSuccess, onSaving }) {
|
|
|
10292
10882
|
trigger,
|
|
10293
10883
|
errors,
|
|
10294
10884
|
watchedValues,
|
|
10885
|
+
celContext,
|
|
10295
10886
|
// State
|
|
10296
10887
|
initializing,
|
|
10297
10888
|
fetchError,
|
|
@@ -10300,9 +10891,11 @@ function useDatasourceConfigForm({ schema, dsUid, onSuccess, onSaving }) {
|
|
|
10300
10891
|
readOnly,
|
|
10301
10892
|
// Callbacks
|
|
10302
10893
|
isFieldVisible,
|
|
10894
|
+
isFieldDisabled,
|
|
10303
10895
|
isGroupValid,
|
|
10304
10896
|
groupHasData,
|
|
10305
|
-
onSubmit
|
|
10897
|
+
onSubmit,
|
|
10898
|
+
setValue
|
|
10306
10899
|
};
|
|
10307
10900
|
}
|
|
10308
10901
|
|
|
@@ -10349,13 +10942,16 @@ function WizardLayout({ form, schema, dsUid, dsName, onRetest, healthError, rend
|
|
|
10349
10942
|
trigger,
|
|
10350
10943
|
errors,
|
|
10351
10944
|
watchedValues,
|
|
10945
|
+
celContext,
|
|
10352
10946
|
initializing,
|
|
10353
10947
|
fetchError,
|
|
10354
10948
|
submitting,
|
|
10355
10949
|
submitError,
|
|
10356
10950
|
readOnly,
|
|
10357
10951
|
isFieldVisible,
|
|
10358
|
-
|
|
10952
|
+
isFieldDisabled,
|
|
10953
|
+
onSubmit,
|
|
10954
|
+
setValue
|
|
10359
10955
|
} = form;
|
|
10360
10956
|
const arrowSteps = React.useMemo(() => {
|
|
10361
10957
|
const requiredGroup = resolvedGroups.find((g) => g.group.id === "_required");
|
|
@@ -10401,8 +10997,8 @@ function WizardLayout({ form, schema, dsUid, dsName, onRetest, healthError, rend
|
|
|
10401
10997
|
if (errors[formKey(field)]) {
|
|
10402
10998
|
return false;
|
|
10403
10999
|
}
|
|
10404
|
-
if (isFieldRequired(field, watchedValues, fieldById)) {
|
|
10405
|
-
const val = watchedValues
|
|
11000
|
+
if (isFieldRequired(field, watchedValues, fieldById, celContext)) {
|
|
11001
|
+
const val = getWatchedValue(watchedValues, formKey(field));
|
|
10406
11002
|
if (val === SECURE_FIELD_CONFIGURED) {
|
|
10407
11003
|
continue;
|
|
10408
11004
|
}
|
|
@@ -10412,7 +11008,7 @@ function WizardLayout({ form, schema, dsUid, dsName, onRetest, healthError, rend
|
|
|
10412
11008
|
}
|
|
10413
11009
|
}
|
|
10414
11010
|
return true;
|
|
10415
|
-
}, [currentResolved, errors, visibleFieldsForStep, watchedValues, fieldById]);
|
|
11011
|
+
}, [currentResolved, errors, visibleFieldsForStep, watchedValues, fieldById, celContext]);
|
|
10416
11012
|
const goNext = React.useCallback(async () => {
|
|
10417
11013
|
if (!currentResolved) {
|
|
10418
11014
|
return;
|
|
@@ -10506,10 +11102,12 @@ function WizardLayout({ form, schema, dsUid, dsName, onRetest, healthError, rend
|
|
|
10506
11102
|
field,
|
|
10507
11103
|
control,
|
|
10508
11104
|
errors,
|
|
10509
|
-
disabled: allDisabled,
|
|
11105
|
+
disabled: allDisabled || isFieldDisabled(field),
|
|
10510
11106
|
dsUid,
|
|
10511
11107
|
watchedValues,
|
|
10512
|
-
fieldById
|
|
11108
|
+
fieldById,
|
|
11109
|
+
celContext,
|
|
11110
|
+
setValue
|
|
10513
11111
|
}
|
|
10514
11112
|
)), (currentResolved.group.id === "_required" || currentResolved.group.id === "auth") && httpHeadersField && /* @__PURE__ */ React__default.default.createElement(
|
|
10515
11113
|
AuthorizationHeaderField,
|
|
@@ -12176,6 +12774,21 @@ function generateTroubleshootingFields(schema) {
|
|
|
12176
12774
|
return result;
|
|
12177
12775
|
}
|
|
12178
12776
|
|
|
12777
|
+
const ROOT_CONFIG_FIELDS = [
|
|
12778
|
+
"name",
|
|
12779
|
+
"type",
|
|
12780
|
+
"id",
|
|
12781
|
+
"uid",
|
|
12782
|
+
"access",
|
|
12783
|
+
"url",
|
|
12784
|
+
"basicAuth",
|
|
12785
|
+
"basicAuthUser",
|
|
12786
|
+
"user",
|
|
12787
|
+
"isDefault",
|
|
12788
|
+
"database",
|
|
12789
|
+
"withCredentials"
|
|
12790
|
+
];
|
|
12791
|
+
|
|
12179
12792
|
function yamlIndent(depth) {
|
|
12180
12793
|
return " ".repeat(depth);
|
|
12181
12794
|
}
|
|
@@ -12528,6 +13141,81 @@ function datasourceToProvisioningYaml(ds, schema) {
|
|
|
12528
13141
|
lines.push(" # mySecret: xxxxxx");
|
|
12529
13142
|
return lines.join("\n");
|
|
12530
13143
|
}
|
|
13144
|
+
function getYamlRenderOptions(ds) {
|
|
13145
|
+
var _a, _b, _c;
|
|
13146
|
+
return {
|
|
13147
|
+
jsonDataKeys: Object.keys((_a = ds.jsonData) != null ? _a : {}).sort(),
|
|
13148
|
+
secureKeys: [
|
|
13149
|
+
.../* @__PURE__ */ new Set([
|
|
13150
|
+
...Object.keys((_b = ds.secureJsonData) != null ? _b : {}),
|
|
13151
|
+
...Object.keys((_c = ds.secureJsonFields) != null ? _c : {})
|
|
13152
|
+
])
|
|
13153
|
+
].sort()
|
|
13154
|
+
};
|
|
13155
|
+
}
|
|
13156
|
+
const configToYaml = (ds, options = {}) => {
|
|
13157
|
+
var _a, _b, _c;
|
|
13158
|
+
const { jsonDataKeys, secureKeys } = {
|
|
13159
|
+
...getYamlRenderOptions(ds),
|
|
13160
|
+
...options
|
|
13161
|
+
};
|
|
13162
|
+
const root = {};
|
|
13163
|
+
for (const key of ROOT_CONFIG_FIELDS) {
|
|
13164
|
+
root[key] = (_a = ds[key]) != null ? _a : "";
|
|
13165
|
+
}
|
|
13166
|
+
const jsonData = (_b = ds.jsonData) != null ? _b : {};
|
|
13167
|
+
if (jsonDataKeys.length > 0) {
|
|
13168
|
+
const jsonDataYaml = {};
|
|
13169
|
+
for (const key of jsonDataKeys) {
|
|
13170
|
+
jsonDataYaml[key] = (_c = jsonData[key]) != null ? _c : "";
|
|
13171
|
+
}
|
|
13172
|
+
root.jsonData = jsonDataYaml;
|
|
13173
|
+
}
|
|
13174
|
+
if (secureKeys.length > 0) {
|
|
13175
|
+
const secureJsonData = {};
|
|
13176
|
+
for (const key of secureKeys) {
|
|
13177
|
+
secureJsonData[key] = "********";
|
|
13178
|
+
}
|
|
13179
|
+
root.secureJsonData = secureJsonData;
|
|
13180
|
+
}
|
|
13181
|
+
return yaml__default.default.dump(root, { lineWidth: -1, sortKeys: false, noRefs: true }).trimEnd();
|
|
13182
|
+
};
|
|
13183
|
+
const formatYamlDiff = (existing, body) => {
|
|
13184
|
+
var _a, _b, _c, _d, _e, _f;
|
|
13185
|
+
const updated = { ...existing, ...body };
|
|
13186
|
+
const existingJD = (_a = existing.jsonData) != null ? _a : {};
|
|
13187
|
+
const updatedJD = (_b = updated.jsonData) != null ? _b : {};
|
|
13188
|
+
const jsonDataKeys = [.../* @__PURE__ */ new Set([...Object.keys(existingJD), ...Object.keys(updatedJD)])].sort();
|
|
13189
|
+
const secureKeys = [
|
|
13190
|
+
.../* @__PURE__ */ new Set([
|
|
13191
|
+
...Object.keys((_c = existing.secureJsonData) != null ? _c : {}),
|
|
13192
|
+
...Object.keys((_d = existing.secureJsonFields) != null ? _d : {}),
|
|
13193
|
+
...Object.keys((_e = updated.secureJsonData) != null ? _e : {}),
|
|
13194
|
+
...Object.keys((_f = updated.secureJsonFields) != null ? _f : {})
|
|
13195
|
+
])
|
|
13196
|
+
].sort();
|
|
13197
|
+
const currentYaml = configToYaml(existing, { jsonDataKeys, secureKeys });
|
|
13198
|
+
const updatedYaml = configToYaml(updated, { jsonDataKeys, secureKeys });
|
|
13199
|
+
const oldLines = currentYaml.split("\n");
|
|
13200
|
+
const newLines = updatedYaml.split("\n");
|
|
13201
|
+
const maxLen = Math.max(oldLines.length, newLines.length);
|
|
13202
|
+
const diffLines = [];
|
|
13203
|
+
for (let i = 0; i < maxLen; i++) {
|
|
13204
|
+
const oldLine = oldLines[i];
|
|
13205
|
+
const newLine = newLines[i];
|
|
13206
|
+
if (oldLine === newLine) {
|
|
13207
|
+
diffLines.push(` ${oldLine}`);
|
|
13208
|
+
continue;
|
|
13209
|
+
}
|
|
13210
|
+
if (oldLine !== void 0) {
|
|
13211
|
+
diffLines.push(`-${oldLine}`);
|
|
13212
|
+
}
|
|
13213
|
+
if (newLine !== void 0) {
|
|
13214
|
+
diffLines.push(`+${newLine}`);
|
|
13215
|
+
}
|
|
13216
|
+
}
|
|
13217
|
+
return "```diff\n" + diffLines.join("\n") + "\n```";
|
|
13218
|
+
};
|
|
12531
13219
|
|
|
12532
13220
|
exports.getConfigSchema = schemas.getConfigSchema;
|
|
12533
13221
|
exports.AccessoryButton = AccessoryButton;
|
|
@@ -12602,17 +13290,22 @@ exports.TableSelector = TableSelector;
|
|
|
12602
13290
|
exports.TokenType = TokenType;
|
|
12603
13291
|
exports.buildDatasourceConfigPayload = buildDatasourceConfigPayload;
|
|
12604
13292
|
exports.computeVirtualFieldValues = computeVirtualFieldValues;
|
|
13293
|
+
exports.configToYaml = configToYaml;
|
|
12605
13294
|
exports.convertLegacyAuthProps = convertLegacyAuthProps;
|
|
12606
13295
|
exports.datasourceToProvisioningYaml = datasourceToProvisioningYaml;
|
|
12607
13296
|
exports.evaluateComputedRead = evaluateComputedRead;
|
|
13297
|
+
exports.evaluateDependsOn = evaluateDependsOn;
|
|
12608
13298
|
exports.expandIndexedPair = expandIndexedPair;
|
|
12609
13299
|
exports.fetchExistingValues = fetchExistingValues;
|
|
13300
|
+
exports.findActiveSecureOverride = findActiveSecureOverride;
|
|
12610
13301
|
exports.flattenIndexedPair = flattenIndexedPair;
|
|
12611
13302
|
exports.formKey = formKey;
|
|
12612
13303
|
exports.formatDate = formatDate;
|
|
13304
|
+
exports.formatYamlDiff = formatYamlDiff;
|
|
12613
13305
|
exports.generateLLMHint = generateLLMHint;
|
|
12614
13306
|
exports.generateTroubleshootingFields = generateTroubleshootingFields;
|
|
12615
13307
|
exports.getStandardSQLCompletionProvider = getStandardSQLCompletionProvider;
|
|
13308
|
+
exports.getWatchedValue = getWatchedValue;
|
|
12616
13309
|
exports.grafanaStandardSQLLanguage = language;
|
|
12617
13310
|
exports.grafanaStandardSQLLanguageConf = conf;
|
|
12618
13311
|
exports.parseDependsOn = parseDependsOn;
|
|
@@ -12620,6 +13313,7 @@ exports.resolveActiveOverride = resolveActiveOverride;
|
|
|
12620
13313
|
exports.resolveGroups = resolveGroups;
|
|
12621
13314
|
exports.resolvePluginName = resolvePluginName;
|
|
12622
13315
|
exports.resolveRequiredFieldsGroup = resolveRequiredFieldsGroup;
|
|
13316
|
+
exports.resolveSecureKeyTemplate = resolveSecureKeyTemplate;
|
|
12623
13317
|
exports.submitDatasourceConfig = submitDatasourceConfig;
|
|
12624
13318
|
exports.toOption = toOption;
|
|
12625
13319
|
exports.toProvisioningYaml = toProvisioningYaml;
|