nucleus-core-ts 0.9.793 → 0.9.795
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/fe/components/IntegrationsPage/components/FieldMappingRows.js +15 -0
- package/dist/fe/components/IntegrationsPage/components/MappingEditor.d.ts +18 -3
- package/dist/fe/components/IntegrationsPage/components/MappingEditor.js +30 -1
- package/dist/fe/components/IntegrationsPage/components/MappingsTab.js +12 -14
- package/dist/index.js +1 -1
- package/dist/src/Services/Integrations/mapping.d.ts +17 -0
- package/package.json +1 -1
|
@@ -107,6 +107,21 @@ export function FieldMappingRows({ rows, sourceFields, targetFields, disabled, o
|
|
|
107
107
|
}),
|
|
108
108
|
" to take the value from the parent endpoint's record instead of this one."
|
|
109
109
|
]
|
|
110
|
+
}),
|
|
111
|
+
/*#__PURE__*/ _jsxs("p", {
|
|
112
|
+
className: theme.field.hint,
|
|
113
|
+
children: [
|
|
114
|
+
"Name several fields in ",
|
|
115
|
+
/*#__PURE__*/ _jsx("strong", {
|
|
116
|
+
children: '{braces}'
|
|
117
|
+
}),
|
|
118
|
+
" to build one value from them —",
|
|
119
|
+
' ',
|
|
120
|
+
/*#__PURE__*/ _jsx("strong", {
|
|
121
|
+
children: '{companyCode}-{organizationCode}'
|
|
122
|
+
}),
|
|
123
|
+
". Use it when no single field is unique on its own, which is what the deduplication column needs."
|
|
124
|
+
]
|
|
110
125
|
})
|
|
111
126
|
]
|
|
112
127
|
})
|
|
@@ -1,15 +1,30 @@
|
|
|
1
|
+
import type { IntegrationEndpoint } from '../types';
|
|
1
2
|
import { type MappingDraft, type MappingTarget } from './mappingDraft';
|
|
2
3
|
export type MappingEditorProps = {
|
|
3
4
|
/** Starting values. Read once — remount with a new `key` to load another. */
|
|
4
5
|
mapping: MappingDraft;
|
|
5
6
|
targets: MappingTarget[];
|
|
6
7
|
targetsLoading: boolean;
|
|
7
|
-
/**
|
|
8
|
-
|
|
8
|
+
/**
|
|
9
|
+
* The connection's endpoints. A mapping reads from exactly one, and which one
|
|
10
|
+
* is half of what a mapping IS — so it is chosen here rather than inherited
|
|
11
|
+
* from whatever happens to be selected on another tab.
|
|
12
|
+
*/
|
|
13
|
+
endpoints: IntegrationEndpoint[];
|
|
14
|
+
/**
|
|
15
|
+
* The sample taken in this session and the endpoint it describes.
|
|
16
|
+
*
|
|
17
|
+
* Fresher than the endpoint's stored sample, but only for that one endpoint —
|
|
18
|
+
* offering it against any other would suggest columns that never arrive.
|
|
19
|
+
*/
|
|
20
|
+
freshSample: {
|
|
21
|
+
endpointId: string;
|
|
22
|
+
fields: string[];
|
|
23
|
+
} | null;
|
|
9
24
|
saving: boolean;
|
|
10
25
|
deleting: boolean;
|
|
11
26
|
onSave: (draft: MappingDraft) => void;
|
|
12
27
|
onDelete: (id: string) => void;
|
|
13
28
|
onCancel: () => void;
|
|
14
29
|
};
|
|
15
|
-
export declare function MappingEditor({ mapping, targets, targetsLoading,
|
|
30
|
+
export declare function MappingEditor({ mapping, targets, targetsLoading, endpoints, freshSample, saving, deleting, onSave, onDelete, onCancel, }: MappingEditorProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -3,6 +3,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
3
3
|
import { useId, useState } from 'react';
|
|
4
4
|
import { integrationsPageTheme } from '../theme';
|
|
5
5
|
import { FieldMappingRows } from './FieldMappingRows';
|
|
6
|
+
import { endpointLabel, fieldsOfStoredSample } from './formSupport';
|
|
6
7
|
import { MappingWriteModeFields } from './MappingWriteModeFields';
|
|
7
8
|
import { mappingDraftIssues } from './mappingDraft';
|
|
8
9
|
import { Field } from './Primitives';
|
|
@@ -17,7 +18,7 @@ import { CardSkeleton } from './Skeletons';
|
|
|
17
18
|
* Mount it with a `key` of the mapping id so switching rows starts a fresh
|
|
18
19
|
* draft instead of pouring one mapping's edits into another.
|
|
19
20
|
*/ const theme = integrationsPageTheme;
|
|
20
|
-
export function MappingEditor({ mapping, targets, targetsLoading,
|
|
21
|
+
export function MappingEditor({ mapping, targets, targetsLoading, endpoints, freshSample, saving, deleting, onSave, onDelete, onCancel }) {
|
|
21
22
|
const uid = useId();
|
|
22
23
|
const [draft, setDraft] = useState(mapping);
|
|
23
24
|
const patch = (next)=>{
|
|
@@ -45,6 +46,10 @@ export function MappingEditor({ mapping, targets, targetsLoading, sourceFields,
|
|
|
45
46
|
const targetFields = targets.find((option)=>option.entity === draft.targetEntity)?.fields ?? [];
|
|
46
47
|
const issues = mappingDraftIssues(draft);
|
|
47
48
|
const busy = saving || deleting;
|
|
49
|
+
// Follows the endpoint CHOSEN here, so changing it changes the field list
|
|
50
|
+
// rather than leaving the previous endpoint's names on offer.
|
|
51
|
+
const readsFrom = endpoints.find((endpoint)=>endpoint.id === draft.endpointId);
|
|
52
|
+
const sourceFields = freshSample && freshSample.endpointId === draft.endpointId && freshSample.fields.length > 0 ? freshSample.fields : fieldsOfStoredSample(readsFrom?.sampleResponse);
|
|
48
53
|
return /*#__PURE__*/ _jsxs("section", {
|
|
49
54
|
className: theme.card.wrapper,
|
|
50
55
|
children: [
|
|
@@ -58,6 +63,30 @@ export function MappingEditor({ mapping, targets, targetsLoading, sourceFields,
|
|
|
58
63
|
/*#__PURE__*/ _jsxs("div", {
|
|
59
64
|
className: theme.card.body,
|
|
60
65
|
children: [
|
|
66
|
+
/*#__PURE__*/ _jsx(Field, {
|
|
67
|
+
hint: endpoints.length === 0 ? 'This connection has no endpoints yet. Add one on the Endpoints tab.' : readsFrom?.path ?? 'Every mapping reads from exactly one endpoint.',
|
|
68
|
+
htmlFor: `${uid}-endpoint`,
|
|
69
|
+
label: "Reads from",
|
|
70
|
+
children: /*#__PURE__*/ _jsxs("select", {
|
|
71
|
+
className: theme.field.input,
|
|
72
|
+
disabled: busy || endpoints.length === 0,
|
|
73
|
+
id: `${uid}-endpoint`,
|
|
74
|
+
onChange: (event)=>patch({
|
|
75
|
+
endpointId: event.target.value
|
|
76
|
+
}),
|
|
77
|
+
value: draft.endpointId,
|
|
78
|
+
children: [
|
|
79
|
+
/*#__PURE__*/ _jsx("option", {
|
|
80
|
+
value: "",
|
|
81
|
+
children: "Not set"
|
|
82
|
+
}),
|
|
83
|
+
endpoints.map((endpoint)=>/*#__PURE__*/ _jsx("option", {
|
|
84
|
+
value: endpoint.id,
|
|
85
|
+
children: endpointLabel(endpoint)
|
|
86
|
+
}, endpoint.id))
|
|
87
|
+
]
|
|
88
|
+
})
|
|
89
|
+
}),
|
|
61
90
|
/*#__PURE__*/ _jsxs("div", {
|
|
62
91
|
className: "grid grid-cols-1 gap-3 sm:grid-cols-2",
|
|
63
92
|
children: [
|
|
@@ -3,7 +3,6 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
3
3
|
import { useEffect, useEffectEvent, useState } from 'react';
|
|
4
4
|
import { useIntegrationsStore } from '../store';
|
|
5
5
|
import { integrationsPageTheme } from '../theme';
|
|
6
|
-
import { fieldsOfStoredSample } from './formSupport';
|
|
7
6
|
import { MappingEditor } from './MappingEditor';
|
|
8
7
|
import { MappingList } from './MappingList';
|
|
9
8
|
import { blankMappingDraft, toMappingDraft } from './mappingDraft';
|
|
@@ -114,16 +113,14 @@ export function MappingsTab({ actions }) {
|
|
|
114
113
|
});
|
|
115
114
|
};
|
|
116
115
|
const draft = creating ? blankMappingDraft(newMappingEndpointId) : selected ? toMappingDraft(selected) : null;
|
|
117
|
-
// A sample describes ONE endpoint
|
|
118
|
-
//
|
|
119
|
-
//
|
|
120
|
-
//
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
const draftEndpoint = draft ? store.endpoints.find((e)=>e.id === draft.endpointId) : undefined;
|
|
126
|
-
const sourceFields = draft && store.selectedEndpointId === draft.endpointId && store.sample?.fields?.length ? store.sample.fields : fieldsOfStoredSample(draftEndpoint?.sampleResponse);
|
|
116
|
+
// A sample describes ONE endpoint, so it travels with the endpoint it belongs
|
|
117
|
+
// to and the editor matches it against the mapping's own choice. The editor
|
|
118
|
+
// falls back to the endpoint's STORED sample — which is why the sample is
|
|
119
|
+
// persisted at all, and what a connection revisited tomorrow has.
|
|
120
|
+
const freshSample = store.selectedEndpointId && store.sample ? {
|
|
121
|
+
endpointId: store.selectedEndpointId,
|
|
122
|
+
fields: store.sample.fields ?? []
|
|
123
|
+
} : null;
|
|
127
124
|
return /*#__PURE__*/ _jsxs("section", {
|
|
128
125
|
className: "flex flex-col gap-4",
|
|
129
126
|
children: [
|
|
@@ -147,9 +144,9 @@ export function MappingsTab({ actions }) {
|
|
|
147
144
|
]
|
|
148
145
|
}),
|
|
149
146
|
newMappingEndpointId === '' ? /*#__PURE__*/ _jsx(Notice, {
|
|
150
|
-
title: "
|
|
147
|
+
title: "No endpoints to read from",
|
|
151
148
|
tone: "info",
|
|
152
|
-
children: "
|
|
149
|
+
children: "A mapping turns one endpoint's response into rows, so there has to be an endpoint first. Add one on the Endpoints tab and it becomes selectable here."
|
|
153
150
|
}) : null,
|
|
154
151
|
/*#__PURE__*/ _jsxs("div", {
|
|
155
152
|
className: theme.layout.split,
|
|
@@ -168,12 +165,13 @@ export function MappingsTab({ actions }) {
|
|
|
168
165
|
className: theme.layout.main,
|
|
169
166
|
children: draft ? /*#__PURE__*/ _jsx(MappingEditor, {
|
|
170
167
|
deleting: deleting,
|
|
168
|
+
endpoints: store.endpoints,
|
|
169
|
+
freshSample: freshSample,
|
|
171
170
|
mapping: draft,
|
|
172
171
|
onCancel: closeEditor,
|
|
173
172
|
onDelete: remove,
|
|
174
173
|
onSave: save,
|
|
175
174
|
saving: saving,
|
|
176
|
-
sourceFields: sourceFields,
|
|
177
175
|
targets: targets,
|
|
178
176
|
targetsLoading: targetsLoading
|
|
179
177
|
}, draft.id ?? 'new-mapping') : /*#__PURE__*/ _jsx("p", {
|