@ethisyscore/plugin-ui 1.127.1 → 1.128.0
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/components/connectors/index.cjs +305 -19
- package/dist/components/connectors/index.cjs.map +1 -1
- package/dist/components/connectors/index.d.cts +2 -2
- package/dist/components/connectors/index.d.ts +2 -2
- package/dist/components/connectors/index.js +305 -19
- package/dist/components/connectors/index.js.map +1 -1
- package/dist/connector-mappings/index.d.cts +2 -2
- package/dist/connector-mappings/index.d.ts +2 -2
- package/dist/{mappingQueryKeys-T-gPzJk1.d.cts → mappingQueryKeys-DsZJn1sk.d.cts} +22 -3
- package/dist/{mappingQueryKeys-T-gPzJk1.d.ts → mappingQueryKeys-DsZJn1sk.d.ts} +22 -3
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { C as ConnectorCanonicalField } from '../../mappingQueryKeys-
|
|
2
|
-
export { a as CONNECTOR_CONTROL_LABEL, b as ConnectorCanonicalFieldKind, c as ConnectorMappingSuggestionResult, d as ConnectorMappingTranslationEditorProps, e as ConnectorMappingTranslationEditorView, M as MappingCompletenessBanner,
|
|
1
|
+
import { C as ConnectorCanonicalField } from '../../mappingQueryKeys-DsZJn1sk.cjs';
|
|
2
|
+
export { a as CONNECTOR_CONTROL_LABEL, b as ConnectorCanonicalFieldKind, c as ConnectorMappingSuggestionResult, d as ConnectorMappingTranslationEditorProps, e as ConnectorMappingTranslationEditorView, f as ConnectorMappingTranslationExtras, M as MappingCompletenessBanner, g as MappingCompletenessBannerProps, h as MappingCompletenessItem, i as MappingCompletenessResult, j as MappingReadiness, P as PLUGIN_PROVIDER_CONTROL_LABEL, k as PROVIDER_CONTROL_LABEL, l as PROVIDER_OPTION_LABEL, S as SUPPRESS_REQUEST_FIELD_VALUE, T as TestToolMappingExtractedField, m as TestToolMappingRequest, n as TestToolMappingResult, o as connectorMappingCompletenessQueryKey, p as connectorMappingsQueryKey, q as connectorMappingsRootQueryKey, r as pluginTargetMappingsQueryKey, s as selectIncompleteOperations, t as selectMappingReadiness, u as selectOptionalIncompleteOperations, v as selectRequiredIncompleteOperations, w as selectRequiredUnmappedOperations } from '../../mappingQueryKeys-DsZJn1sk.cjs';
|
|
3
3
|
import * as react from 'react';
|
|
4
4
|
import { ReactNode } from 'react';
|
|
5
5
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { C as ConnectorCanonicalField } from '../../mappingQueryKeys-
|
|
2
|
-
export { a as CONNECTOR_CONTROL_LABEL, b as ConnectorCanonicalFieldKind, c as ConnectorMappingSuggestionResult, d as ConnectorMappingTranslationEditorProps, e as ConnectorMappingTranslationEditorView, M as MappingCompletenessBanner,
|
|
1
|
+
import { C as ConnectorCanonicalField } from '../../mappingQueryKeys-DsZJn1sk.js';
|
|
2
|
+
export { a as CONNECTOR_CONTROL_LABEL, b as ConnectorCanonicalFieldKind, c as ConnectorMappingSuggestionResult, d as ConnectorMappingTranslationEditorProps, e as ConnectorMappingTranslationEditorView, f as ConnectorMappingTranslationExtras, M as MappingCompletenessBanner, g as MappingCompletenessBannerProps, h as MappingCompletenessItem, i as MappingCompletenessResult, j as MappingReadiness, P as PLUGIN_PROVIDER_CONTROL_LABEL, k as PROVIDER_CONTROL_LABEL, l as PROVIDER_OPTION_LABEL, S as SUPPRESS_REQUEST_FIELD_VALUE, T as TestToolMappingExtractedField, m as TestToolMappingRequest, n as TestToolMappingResult, o as connectorMappingCompletenessQueryKey, p as connectorMappingsQueryKey, q as connectorMappingsRootQueryKey, r as pluginTargetMappingsQueryKey, s as selectIncompleteOperations, t as selectMappingReadiness, u as selectOptionalIncompleteOperations, v as selectRequiredIncompleteOperations, w as selectRequiredUnmappedOperations } from '../../mappingQueryKeys-DsZJn1sk.js';
|
|
3
3
|
import * as react from 'react';
|
|
4
4
|
import { ReactNode } from 'react';
|
|
5
5
|
|
|
@@ -1606,6 +1606,205 @@ function ConnectorMappingView({
|
|
|
1606
1606
|
] }) })
|
|
1607
1607
|
] });
|
|
1608
1608
|
}
|
|
1609
|
+
|
|
1610
|
+
// src/components/connectors/requestTemplates.ts
|
|
1611
|
+
var PLACEHOLDER = /^\{\{([A-Za-z_][A-Za-z0-9_.-]*)\}\}$/;
|
|
1612
|
+
var MAX_REQUEST_TEMPLATES = 4;
|
|
1613
|
+
function parseRequestTemplate(text) {
|
|
1614
|
+
let parsed;
|
|
1615
|
+
try {
|
|
1616
|
+
parsed = JSON.parse(text);
|
|
1617
|
+
} catch {
|
|
1618
|
+
return { value: null, error: "Not valid JSON.", placeholders: [] };
|
|
1619
|
+
}
|
|
1620
|
+
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
1621
|
+
return { value: null, error: "A template must be a JSON object.", placeholders: [] };
|
|
1622
|
+
}
|
|
1623
|
+
const placeholders = [];
|
|
1624
|
+
const embedded = [];
|
|
1625
|
+
walkStrings(parsed, (value) => {
|
|
1626
|
+
const match = PLACEHOLDER.exec(value);
|
|
1627
|
+
if (match) {
|
|
1628
|
+
if (!placeholders.includes(match[1])) placeholders.push(match[1]);
|
|
1629
|
+
} else if (value.includes("{{")) {
|
|
1630
|
+
embedded.push(value);
|
|
1631
|
+
}
|
|
1632
|
+
});
|
|
1633
|
+
return {
|
|
1634
|
+
value: parsed,
|
|
1635
|
+
error: embedded.length > 0 ? `A placeholder must be the whole value, like "{{companyName}}": "${embedded[0]}".` : null,
|
|
1636
|
+
placeholders
|
|
1637
|
+
};
|
|
1638
|
+
}
|
|
1639
|
+
function walkStrings(value, onString) {
|
|
1640
|
+
if (typeof value === "string") {
|
|
1641
|
+
onString(value);
|
|
1642
|
+
} else if (Array.isArray(value)) {
|
|
1643
|
+
value.forEach((item) => walkStrings(item, onString));
|
|
1644
|
+
} else if (value !== null && typeof value === "object") {
|
|
1645
|
+
Object.values(value).forEach((item) => walkStrings(item, onString));
|
|
1646
|
+
}
|
|
1647
|
+
}
|
|
1648
|
+
var MAX_ROW_FIELDS_PER_FIELD = 32;
|
|
1649
|
+
var MAX_ROW_FIELD_TEXT_LENGTH = 256;
|
|
1650
|
+
function rowFieldPathError(path) {
|
|
1651
|
+
const trimmed = path.trim();
|
|
1652
|
+
if (trimmed.length === 0) return null;
|
|
1653
|
+
if (!trimmed.startsWith("$.")) return 'A path must start with "$.", e.g. $.company_domain.';
|
|
1654
|
+
if (trimmed.length > MAX_ROW_FIELD_TEXT_LENGTH) return `A path can be at most ${MAX_ROW_FIELD_TEXT_LENGTH} characters.`;
|
|
1655
|
+
return null;
|
|
1656
|
+
}
|
|
1657
|
+
var REQUEST_TEMPLATES_CAPTION = "The first template whose placeholders all have values is sent as the request. Leave empty to use the field map.";
|
|
1658
|
+
function RequestTemplatesSection({
|
|
1659
|
+
rows,
|
|
1660
|
+
canonicalRequestFields,
|
|
1661
|
+
onChange,
|
|
1662
|
+
onAdd,
|
|
1663
|
+
onRemove,
|
|
1664
|
+
onMove
|
|
1665
|
+
}) {
|
|
1666
|
+
const canonicalNames = new Set(canonicalRequestFields.map((field) => field.name));
|
|
1667
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1668
|
+
/* @__PURE__ */ jsx(Typography, { variant: "h6", component: "h2", className: "mb-2", children: "Request templates" }),
|
|
1669
|
+
/* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-text-secondary mb-3 block", children: REQUEST_TEMPLATES_CAPTION }),
|
|
1670
|
+
rows.length === 0 ? /* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-text-disabled italic mb-3", children: "No request templates configured." }) : /* @__PURE__ */ jsx(Box, { className: "flex flex-col gap-3 mb-3", children: rows.map((row, index) => {
|
|
1671
|
+
const parsed = row.text.trim().length === 0 ? null : parseRequestTemplate(row.text);
|
|
1672
|
+
return /* @__PURE__ */ jsxs(Box, { className: "flex flex-col gap-1", children: [
|
|
1673
|
+
/* @__PURE__ */ jsxs(Box, { className: "flex flex-row items-start gap-2", children: [
|
|
1674
|
+
/* @__PURE__ */ jsxs(FormControl, { variant: "filled", size: "medium", className: "surface mb-0 flex-1", children: [
|
|
1675
|
+
/* @__PURE__ */ jsx(InputLabel, { children: `Template ${index + 1}` }),
|
|
1676
|
+
/* @__PURE__ */ jsx(
|
|
1677
|
+
FilledInput,
|
|
1678
|
+
{
|
|
1679
|
+
multiline: true,
|
|
1680
|
+
minRows: 4,
|
|
1681
|
+
value: row.text,
|
|
1682
|
+
onChange: (e) => onChange(index, e.target.value),
|
|
1683
|
+
inputProps: { "aria-label": `Request template ${index + 1}` },
|
|
1684
|
+
sx: { fontFamily: "monospace" }
|
|
1685
|
+
}
|
|
1686
|
+
)
|
|
1687
|
+
] }),
|
|
1688
|
+
/* @__PURE__ */ jsxs(Box, { className: "flex flex-col", children: [
|
|
1689
|
+
/* @__PURE__ */ jsx(
|
|
1690
|
+
IconButton,
|
|
1691
|
+
{
|
|
1692
|
+
"aria-label": `Move template ${index + 1} up`,
|
|
1693
|
+
color: "inherit",
|
|
1694
|
+
disabled: index === 0,
|
|
1695
|
+
onClick: () => onMove(index, -1),
|
|
1696
|
+
children: /* @__PURE__ */ jsx(NiChevronUpSmall, { size: "small" })
|
|
1697
|
+
}
|
|
1698
|
+
),
|
|
1699
|
+
/* @__PURE__ */ jsx(
|
|
1700
|
+
IconButton,
|
|
1701
|
+
{
|
|
1702
|
+
"aria-label": `Move template ${index + 1} down`,
|
|
1703
|
+
color: "inherit",
|
|
1704
|
+
disabled: index === rows.length - 1,
|
|
1705
|
+
onClick: () => onMove(index, 1),
|
|
1706
|
+
children: /* @__PURE__ */ jsx(NiChevronDownSmall, { size: "small" })
|
|
1707
|
+
}
|
|
1708
|
+
),
|
|
1709
|
+
/* @__PURE__ */ jsx(IconButton, { "aria-label": `Remove template ${index + 1}`, color: "inherit", onClick: () => onRemove(index), children: /* @__PURE__ */ jsx(NiBinEmpty, { size: "small" }) })
|
|
1710
|
+
] })
|
|
1711
|
+
] }),
|
|
1712
|
+
parsed?.error && /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "error", role: "alert", children: parsed.error }),
|
|
1713
|
+
parsed && parsed.placeholders.length > 0 && /* @__PURE__ */ jsx(Box, { className: "flex flex-wrap gap-1", children: parsed.placeholders.map(
|
|
1714
|
+
(name) => canonicalNames.has(name) ? /* @__PURE__ */ jsx(Chip, { label: `{{${name}}}`, size: "small", variant: "outlined" }, name) : /* @__PURE__ */ jsx(
|
|
1715
|
+
Chip,
|
|
1716
|
+
{
|
|
1717
|
+
label: `{{${name}}} is not a request field`,
|
|
1718
|
+
size: "small",
|
|
1719
|
+
color: "error",
|
|
1720
|
+
variant: "outlined"
|
|
1721
|
+
},
|
|
1722
|
+
name
|
|
1723
|
+
)
|
|
1724
|
+
) })
|
|
1725
|
+
] }, row.id);
|
|
1726
|
+
}) }),
|
|
1727
|
+
/* @__PURE__ */ jsx(
|
|
1728
|
+
Button,
|
|
1729
|
+
{
|
|
1730
|
+
variant: "outlined",
|
|
1731
|
+
color: "grey",
|
|
1732
|
+
size: "small",
|
|
1733
|
+
onClick: onAdd,
|
|
1734
|
+
disabled: rows.length >= MAX_REQUEST_TEMPLATES,
|
|
1735
|
+
startIcon: /* @__PURE__ */ jsx(NiPlus, { size: "small" }),
|
|
1736
|
+
sx: { alignSelf: "flex-start" },
|
|
1737
|
+
children: "Add template"
|
|
1738
|
+
}
|
|
1739
|
+
)
|
|
1740
|
+
] });
|
|
1741
|
+
}
|
|
1742
|
+
function RowFieldsSection({ objectFields, rows, onChange, onAdd, onRemove }) {
|
|
1743
|
+
return /* @__PURE__ */ jsx(Fragment, { children: objectFields.map((field) => {
|
|
1744
|
+
const fieldRows = rows[field.name] ?? [];
|
|
1745
|
+
return /* @__PURE__ */ jsxs(Box, { className: "flex flex-col gap-2 mb-3", children: [
|
|
1746
|
+
/* @__PURE__ */ jsx(Typography, { variant: "h6", component: "h2", children: `Row fields \u2014 ${field.name}` }),
|
|
1747
|
+
/* @__PURE__ */ jsxs(Typography, { variant: "caption", className: "text-text-secondary block", children: [
|
|
1748
|
+
"Rename the fields inside each row of this response. Each path is read from one row, e.g.",
|
|
1749
|
+
" ",
|
|
1750
|
+
/* @__PURE__ */ jsx("code", { children: "$.company_domain" }),
|
|
1751
|
+
"; once you list any, the fields you do not list are dropped."
|
|
1752
|
+
] }),
|
|
1753
|
+
fieldRows.map((row, index) => /* @__PURE__ */ jsxs(Box, { className: "flex flex-row items-start gap-3", children: [
|
|
1754
|
+
/* @__PURE__ */ jsxs(FormControl, { variant: "filled", size: "medium", className: "surface mb-0", sx: { width: 200, flexShrink: 0 }, children: [
|
|
1755
|
+
/* @__PURE__ */ jsx(InputLabel, { children: "Row field" }),
|
|
1756
|
+
/* @__PURE__ */ jsx(
|
|
1757
|
+
FilledInput,
|
|
1758
|
+
{
|
|
1759
|
+
value: row.key,
|
|
1760
|
+
onChange: (e) => onChange(field.name, index, { key: e.target.value }),
|
|
1761
|
+
inputProps: { "aria-label": `Row field name ${index + 1} for ${field.name}`, maxLength: MAX_ROW_FIELD_TEXT_LENGTH },
|
|
1762
|
+
placeholder: "e.g. domain"
|
|
1763
|
+
}
|
|
1764
|
+
)
|
|
1765
|
+
] }),
|
|
1766
|
+
/* @__PURE__ */ jsxs(FormControl, { variant: "filled", size: "medium", className: "surface mb-0 flex-1", children: [
|
|
1767
|
+
/* @__PURE__ */ jsx(InputLabel, { children: "JSON path in the row" }),
|
|
1768
|
+
/* @__PURE__ */ jsx(
|
|
1769
|
+
FilledInput,
|
|
1770
|
+
{
|
|
1771
|
+
value: row.path,
|
|
1772
|
+
onChange: (e) => onChange(field.name, index, { path: e.target.value }),
|
|
1773
|
+
inputProps: { "aria-label": `Row field path ${index + 1} for ${field.name}`, maxLength: MAX_ROW_FIELD_TEXT_LENGTH },
|
|
1774
|
+
error: rowFieldPathError(row.path) !== null,
|
|
1775
|
+
placeholder: "e.g. $.company_domain"
|
|
1776
|
+
}
|
|
1777
|
+
),
|
|
1778
|
+
rowFieldPathError(row.path) && /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "error", role: "alert", children: rowFieldPathError(row.path) })
|
|
1779
|
+
] }),
|
|
1780
|
+
/* @__PURE__ */ jsx(
|
|
1781
|
+
IconButton,
|
|
1782
|
+
{
|
|
1783
|
+
"aria-label": `Remove row field ${index + 1} for ${field.name}`,
|
|
1784
|
+
color: "inherit",
|
|
1785
|
+
onClick: () => onRemove(field.name, index),
|
|
1786
|
+
sx: { mt: 1 },
|
|
1787
|
+
children: /* @__PURE__ */ jsx(NiBinEmpty, { size: "small" })
|
|
1788
|
+
}
|
|
1789
|
+
)
|
|
1790
|
+
] }, row.id)),
|
|
1791
|
+
/* @__PURE__ */ jsx(
|
|
1792
|
+
Button,
|
|
1793
|
+
{
|
|
1794
|
+
variant: "outlined",
|
|
1795
|
+
color: "grey",
|
|
1796
|
+
size: "small",
|
|
1797
|
+
onClick: () => onAdd(field.name),
|
|
1798
|
+
startIcon: /* @__PURE__ */ jsx(NiPlus, { size: "small" }),
|
|
1799
|
+
disabled: fieldRows.length >= MAX_ROW_FIELDS_PER_FIELD,
|
|
1800
|
+
sx: { alignSelf: "flex-start" },
|
|
1801
|
+
"aria-label": `Add row field to ${field.name}`,
|
|
1802
|
+
children: "Add row field"
|
|
1803
|
+
}
|
|
1804
|
+
)
|
|
1805
|
+
] }, field.name);
|
|
1806
|
+
}) });
|
|
1807
|
+
}
|
|
1609
1808
|
var SUPPRESS_REQUEST_FIELD_VALUE = "(suppress)";
|
|
1610
1809
|
function isSuppressed(value) {
|
|
1611
1810
|
return value?.trim().toLowerCase() === SUPPRESS_REQUEST_FIELD_VALUE;
|
|
@@ -1623,6 +1822,8 @@ function ConnectorMappingTranslationEditorView({
|
|
|
1623
1822
|
requestFieldMap,
|
|
1624
1823
|
responseFieldPaths,
|
|
1625
1824
|
staticRequestFields,
|
|
1825
|
+
requestTemplates,
|
|
1826
|
+
responseItemFieldPaths,
|
|
1626
1827
|
onSave,
|
|
1627
1828
|
onCancel,
|
|
1628
1829
|
onTestMapping,
|
|
@@ -1650,6 +1851,52 @@ function ConnectorMappingTranslationEditorView({
|
|
|
1650
1851
|
const [rawJsonExpanded, setRawJsonExpanded] = useState(false);
|
|
1651
1852
|
const [suggestionError, setSuggestionError] = useState(null);
|
|
1652
1853
|
const [isSuggesting, setIsSuggesting] = useState(false);
|
|
1854
|
+
const showTemplates = requestTemplates !== void 0;
|
|
1855
|
+
const objectResponseFields = canonicalResponseFields.filter((field) => field.kind === "Object");
|
|
1856
|
+
const showRowFields = responseItemFieldPaths !== void 0 && objectResponseFields.length > 0;
|
|
1857
|
+
const templateRowIdRef = useRef(0);
|
|
1858
|
+
const [templateRows, setTemplateRows] = useState(
|
|
1859
|
+
() => (requestTemplates ?? []).flatMap((template) => {
|
|
1860
|
+
let text;
|
|
1861
|
+
try {
|
|
1862
|
+
text = JSON.stringify(template, null, 2);
|
|
1863
|
+
} catch {
|
|
1864
|
+
text = void 0;
|
|
1865
|
+
}
|
|
1866
|
+
return text === void 0 ? [] : [{ id: templateRowIdRef.current++, text }];
|
|
1867
|
+
})
|
|
1868
|
+
);
|
|
1869
|
+
const rowFieldIdRef = useRef(0);
|
|
1870
|
+
const [rowFieldRows, setRowFieldRows] = useState(
|
|
1871
|
+
() => Object.fromEntries(
|
|
1872
|
+
Object.entries(responseItemFieldPaths ?? {}).map(([field, paths]) => [
|
|
1873
|
+
field,
|
|
1874
|
+
Object.entries(paths).map(([key, path]) => ({ id: rowFieldIdRef.current++, key, path }))
|
|
1875
|
+
])
|
|
1876
|
+
)
|
|
1877
|
+
);
|
|
1878
|
+
const hasInvalidTemplate = showTemplates && templateRows.some((row) => row.text.trim().length > 0 && parseRequestTemplate(row.text).error !== null) || showRowFields && objectResponseFields.some((field) => (rowFieldRows[field.name] ?? []).some((row) => rowFieldPathError(row.path) !== null));
|
|
1879
|
+
const handleTemplateChange = (index, text) => setTemplateRows((prev) => prev.map((row, i) => i === index ? { ...row, text } : row));
|
|
1880
|
+
const handleAddTemplate = () => setTemplateRows(
|
|
1881
|
+
(prev) => prev.length >= MAX_REQUEST_TEMPLATES ? prev : [...prev, { id: templateRowIdRef.current++, text: "" }]
|
|
1882
|
+
);
|
|
1883
|
+
const handleRemoveTemplate = (index) => setTemplateRows((prev) => prev.filter((_, i) => i !== index));
|
|
1884
|
+
const handleMoveTemplate = (index, direction) => setTemplateRows((prev) => {
|
|
1885
|
+
const target = index + direction;
|
|
1886
|
+
if (target < 0 || target >= prev.length) return prev;
|
|
1887
|
+
const next = [...prev];
|
|
1888
|
+
[next[index], next[target]] = [next[target], next[index]];
|
|
1889
|
+
return next;
|
|
1890
|
+
});
|
|
1891
|
+
const handleRowFieldChange = (field, index, patch) => setRowFieldRows((prev) => ({
|
|
1892
|
+
...prev,
|
|
1893
|
+
[field]: (prev[field] ?? []).map((row, i) => i === index ? { ...row, ...patch } : row)
|
|
1894
|
+
}));
|
|
1895
|
+
const handleAddRowField = (field) => setRowFieldRows((prev) => ({
|
|
1896
|
+
...prev,
|
|
1897
|
+
[field]: [...prev[field] ?? [], { id: rowFieldIdRef.current++, key: "", path: "" }]
|
|
1898
|
+
}));
|
|
1899
|
+
const handleRemoveRowField = (field, index) => setRowFieldRows((prev) => ({ ...prev, [field]: (prev[field] ?? []).filter((_, i) => i !== index) }));
|
|
1653
1900
|
const handleRequestChange = (canonicalName, value) => {
|
|
1654
1901
|
setRequestValues((prev) => ({ ...prev, [canonicalName]: value }));
|
|
1655
1902
|
};
|
|
@@ -1675,11 +1922,17 @@ function ConnectorMappingTranslationEditorView({
|
|
|
1675
1922
|
const requestMap = stripEmpty(requestValues);
|
|
1676
1923
|
const responseMap = stripEmpty(responseValues);
|
|
1677
1924
|
const staticMap = staticRowsToMap(staticRows);
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1925
|
+
const request = Object.keys(requestMap).length === 0 ? null : requestMap;
|
|
1926
|
+
const response = Object.keys(responseMap).length === 0 ? null : responseMap;
|
|
1927
|
+
const statics = Object.keys(staticMap).length === 0 ? null : staticMap;
|
|
1928
|
+
if (!showTemplates && !showRowFields) {
|
|
1929
|
+
onSave(request, response, statics);
|
|
1930
|
+
return;
|
|
1931
|
+
}
|
|
1932
|
+
const extras = {};
|
|
1933
|
+
if (showTemplates) extras.requestTemplates = templateRowsToWire(templateRows);
|
|
1934
|
+
if (showRowFields) extras.responseItemFieldPaths = rowFieldRowsToWire(rowFieldRows, objectResponseFields);
|
|
1935
|
+
onSave(request, response, statics, extras);
|
|
1683
1936
|
};
|
|
1684
1937
|
const handleTest = async () => {
|
|
1685
1938
|
if (!onTestMapping) return;
|
|
@@ -1855,6 +2108,33 @@ function ConnectorMappingTranslationEditorView({
|
|
|
1855
2108
|
children: "Add parameter"
|
|
1856
2109
|
}
|
|
1857
2110
|
),
|
|
2111
|
+
showTemplates && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2112
|
+
/* @__PURE__ */ jsx(Divider, { className: "my-4" }),
|
|
2113
|
+
/* @__PURE__ */ jsx(
|
|
2114
|
+
RequestTemplatesSection,
|
|
2115
|
+
{
|
|
2116
|
+
rows: templateRows,
|
|
2117
|
+
canonicalRequestFields,
|
|
2118
|
+
onChange: handleTemplateChange,
|
|
2119
|
+
onAdd: handleAddTemplate,
|
|
2120
|
+
onRemove: handleRemoveTemplate,
|
|
2121
|
+
onMove: handleMoveTemplate
|
|
2122
|
+
}
|
|
2123
|
+
)
|
|
2124
|
+
] }),
|
|
2125
|
+
showRowFields && objectResponseFields.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2126
|
+
/* @__PURE__ */ jsx(Divider, { className: "my-4" }),
|
|
2127
|
+
/* @__PURE__ */ jsx(
|
|
2128
|
+
RowFieldsSection,
|
|
2129
|
+
{
|
|
2130
|
+
objectFields: objectResponseFields,
|
|
2131
|
+
rows: rowFieldRows,
|
|
2132
|
+
onChange: handleRowFieldChange,
|
|
2133
|
+
onAdd: handleAddRowField,
|
|
2134
|
+
onRemove: handleRemoveRowField
|
|
2135
|
+
}
|
|
2136
|
+
)
|
|
2137
|
+
] }),
|
|
1858
2138
|
(onTestMapping || onSuggestTranslation) && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1859
2139
|
/* @__PURE__ */ jsx(Divider, { className: "my-4" }),
|
|
1860
2140
|
/* @__PURE__ */ jsx(Typography, { variant: "h6", component: "h2", className: "mb-2", children: "Test with sample inputs" }),
|
|
@@ -2010,6 +2290,7 @@ function ConnectorMappingTranslationEditorView({
|
|
|
2010
2290
|
color: "primary",
|
|
2011
2291
|
onClick: handleSave,
|
|
2012
2292
|
"data-testid": "save-translation-button",
|
|
2293
|
+
disabled: hasInvalidTemplate,
|
|
2013
2294
|
children: "Save"
|
|
2014
2295
|
}
|
|
2015
2296
|
)
|
|
@@ -2069,22 +2350,27 @@ function FieldRow({
|
|
|
2069
2350
|
] });
|
|
2070
2351
|
}
|
|
2071
2352
|
function stripEmpty(values) {
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
out[key] = value.trim();
|
|
2076
|
-
}
|
|
2077
|
-
}
|
|
2078
|
-
return out;
|
|
2353
|
+
return Object.fromEntries(
|
|
2354
|
+
Object.entries(values).filter(([, value]) => value.trim().length > 0).map(([key, value]) => [key, value.trim()])
|
|
2355
|
+
);
|
|
2079
2356
|
}
|
|
2080
2357
|
function staticRowsToMap(rows) {
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2358
|
+
return Object.fromEntries(rows.filter(({ key }) => key.trim().length > 0).map(({ key, value }) => [key.trim(), value]));
|
|
2359
|
+
}
|
|
2360
|
+
function templateRowsToWire(rows) {
|
|
2361
|
+
const templates = rows.filter((row) => row.text.trim().length > 0).map((row) => parseRequestTemplate(row.text).value).filter((value) => value !== null);
|
|
2362
|
+
return templates.length === 0 ? null : templates;
|
|
2363
|
+
}
|
|
2364
|
+
function rowFieldRowsToWire(rows, objectFields) {
|
|
2365
|
+
const out = Object.fromEntries(
|
|
2366
|
+
objectFields.map((field) => {
|
|
2367
|
+
const paths = Object.fromEntries(
|
|
2368
|
+
(rows[field.name] ?? []).filter(({ key, path }) => key.trim().length > 0 && path.trim().length > 0).map(({ key, path }) => [key.trim(), path.trim()])
|
|
2369
|
+
);
|
|
2370
|
+
return [field.name, paths];
|
|
2371
|
+
}).filter(([, paths]) => Object.keys(paths).length > 0)
|
|
2372
|
+
);
|
|
2373
|
+
return Object.keys(out).length === 0 ? null : out;
|
|
2088
2374
|
}
|
|
2089
2375
|
|
|
2090
2376
|
// src/components/connectors/mappingQueryKeys.ts
|