nucleus-core-ts 0.9.886 → 0.9.887
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/.build-ok +1 -1
- package/dist/fe/components/IntegrationsPage/components/ConnectionDelete.js +2 -1
- package/dist/fe/components/IntegrationsPage/components/ConnectionExport.js +7 -5
- package/dist/fe/components/IntegrationsPage/components/ConnectionForm.js +3 -2
- package/dist/fe/components/IntegrationsPage/components/ConnectionList.js +2 -1
- package/dist/fe/components/IntegrationsPage/components/ConnectionTest.js +3 -2
- package/dist/fe/components/IntegrationsPage/components/ConnectionTransfer.js +7 -5
- package/dist/fe/components/IntegrationsPage/components/CredentialFields.js +6 -5
- package/dist/fe/components/IntegrationsPage/components/CredentialSlotRow.js +2 -1
- package/dist/fe/components/IntegrationsPage/components/EndpointForm.js +5 -4
- package/dist/fe/components/IntegrationsPage/components/EndpointSample.js +2 -1
- package/dist/fe/components/IntegrationsPage/components/FieldMappingRows.js +12 -75
- package/dist/fe/components/IntegrationsPage/components/MappingAccountFields.js +19 -17
- package/dist/fe/components/IntegrationsPage/components/MappingEditor.js +4 -4
- package/dist/fe/components/IntegrationsPage/components/MappingList.js +3 -2
- package/dist/fe/components/IntegrationsPage/components/MappingPasswordField.js +8 -5
- package/dist/fe/components/IntegrationsPage/components/MappingScheduleFields.js +37 -29
- package/dist/fe/components/IntegrationsPage/components/MappingWriteModeFields.js +3 -3
- package/dist/fe/components/IntegrationsPage/components/MappingsTab.js +9 -9
- package/dist/fe/components/IntegrationsPage/components/PaginationFields.js +137 -124
- package/dist/fe/components/IntegrationsPage/components/ReferenceCheckRows.js +42 -39
- package/dist/fe/components/IntegrationsPage/components/RunConfirmStep.js +2 -2
- package/dist/fe/components/IntegrationsPage/components/RunHistory.js +1 -1
- package/dist/fe/components/IntegrationsPage/components/RunHistoryRow.js +4 -2
- package/dist/fe/components/IntegrationsPage/components/RunPanel.js +6 -6
- package/dist/fe/components/IntegrationsPage/components/RunPasswordField.js +4 -2
- package/dist/fe/components/IntegrationsPage/components/RunPlanSuggestions.js +9 -33
- package/dist/fe/components/IntegrationsPage/components/RunPlanSummary.js +1 -1
- package/dist/fe/components/IntegrationsPage/components/RunProgressBar.js +12 -10
- package/dist/fe/components/IntegrationsPage/components/RunRevertConflicts.js +3 -1
- package/dist/fe/components/IntegrationsPage/components/Skeletons.js +4 -3
- package/dist/fe/components/IntegrationsPage/text/index.d.ts +193 -0
- package/dist/fe/components/IntegrationsPage/text/index.js +171 -0
- package/package.json +1 -1
package/dist/.build-ok
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.9.
|
|
1
|
+
0.9.887
|
|
@@ -7,6 +7,7 @@ import { integrationsPageTheme as theme } from '../theme';
|
|
|
7
7
|
import { deleteIsConfirmed } from './deleteIsConfirmed';
|
|
8
8
|
import { Notice } from './Primitives';
|
|
9
9
|
export function ConnectionDelete({ actions, source, onDeleted }) {
|
|
10
|
+
const t = useLabels().errors;
|
|
10
11
|
const labels = useLabels();
|
|
11
12
|
const store = useIntegrationsStore();
|
|
12
13
|
const [asking, setAsking] = useState(false);
|
|
@@ -30,7 +31,7 @@ export function ConnectionDelete({ actions, source, onDeleted }) {
|
|
|
30
31
|
onDeleted?.();
|
|
31
32
|
}).catch((error)=>{
|
|
32
33
|
setBusy(false);
|
|
33
|
-
store.setError(error instanceof Error ? error.message :
|
|
34
|
+
store.setError(error instanceof Error ? error.message : t.requestFailed);
|
|
34
35
|
});
|
|
35
36
|
};
|
|
36
37
|
return /*#__PURE__*/ _jsxs("section", {
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { useState } from 'react';
|
|
4
4
|
import { useIntegrationsStore } from '../store';
|
|
5
|
+
import { useLabels } from '../text/context';
|
|
5
6
|
import { integrationsPageTheme as theme } from '../theme';
|
|
6
7
|
import { Notice } from './Primitives';
|
|
7
8
|
/**
|
|
@@ -29,6 +30,7 @@ import { Notice } from './Primitives';
|
|
|
29
30
|
* is a confusing half hour otherwise.
|
|
30
31
|
*/ /** A filename somebody can still recognise a week later. */ const fileNameFor = (slug)=>`integration-${slug || 'connection'}.json`;
|
|
31
32
|
export function ConnectionExport({ actions, source }) {
|
|
33
|
+
const t = useLabels().transfer;
|
|
32
34
|
const store = useIntegrationsStore();
|
|
33
35
|
const [busy, setBusy] = useState(false);
|
|
34
36
|
const [note, setNote] = useState(null);
|
|
@@ -40,7 +42,7 @@ export function ConnectionExport({ actions, source }) {
|
|
|
40
42
|
actions.exportConnection(source.id).then((document)=>{
|
|
41
43
|
setBusy(false);
|
|
42
44
|
if (!document) {
|
|
43
|
-
store.setError(
|
|
45
|
+
store.setError(t.exportFailed);
|
|
44
46
|
return;
|
|
45
47
|
}
|
|
46
48
|
// Written from the browser rather than served as a download, so the file
|
|
@@ -56,10 +58,10 @@ export function ConnectionExport({ actions, source }) {
|
|
|
56
58
|
link.download = fileNameFor(source.slug);
|
|
57
59
|
link.click();
|
|
58
60
|
URL.revokeObjectURL(url);
|
|
59
|
-
setNote(
|
|
61
|
+
setNote(t.exported);
|
|
60
62
|
}).catch((error)=>{
|
|
61
63
|
setBusy(false);
|
|
62
|
-
store.setError(error instanceof Error ? error.message :
|
|
64
|
+
store.setError(error instanceof Error ? error.message : t.requestFailed);
|
|
63
65
|
});
|
|
64
66
|
};
|
|
65
67
|
return /*#__PURE__*/ _jsxs("section", {
|
|
@@ -70,7 +72,7 @@ export function ConnectionExport({ actions, source }) {
|
|
|
70
72
|
children: [
|
|
71
73
|
/*#__PURE__*/ _jsx("h3", {
|
|
72
74
|
className: theme.card.title,
|
|
73
|
-
children:
|
|
75
|
+
children: t.exportTitle
|
|
74
76
|
}),
|
|
75
77
|
/*#__PURE__*/ _jsx("button", {
|
|
76
78
|
className: theme.button.secondary,
|
|
@@ -89,7 +91,7 @@ export function ConnectionExport({ actions, source }) {
|
|
|
89
91
|
children: "One file holding this connection, its calls and its mappings — enough to rebuild the whole integration in another installation. Bring it in there with Import, on the connections screen."
|
|
90
92
|
}),
|
|
91
93
|
/*#__PURE__*/ _jsx(Notice, {
|
|
92
|
-
title:
|
|
94
|
+
title: t.noSecretsTitle,
|
|
93
95
|
tone: "info",
|
|
94
96
|
children: "Tokens, passwords and keys are left out on purpose. Whatever this connection authenticates with has to be entered again wherever the file lands."
|
|
95
97
|
}),
|
|
@@ -18,6 +18,7 @@ import { CardSkeleton } from './Skeletons';
|
|
|
18
18
|
* of what was stored and what is being typed.
|
|
19
19
|
*/ const theme = integrationsPageTheme;
|
|
20
20
|
export function ConnectionForm({ actions, source, loading = false, onSaved }) {
|
|
21
|
+
const t = useLabels().errors;
|
|
21
22
|
const labels = useLabels();
|
|
22
23
|
const store = useIntegrationsStore();
|
|
23
24
|
const [draft, setDraft] = useState(()=>source ? draftFromSource(source) : emptyConnectionDraft);
|
|
@@ -51,7 +52,7 @@ export function ConnectionForm({ actions, source, loading = false, onSaved }) {
|
|
|
51
52
|
actions.saveSource(draftToSource(draft, source?.id)).then((saved)=>{
|
|
52
53
|
setSaving(false);
|
|
53
54
|
if (!saved) {
|
|
54
|
-
store.setError(
|
|
55
|
+
store.setError(t.connectionNotSaved);
|
|
55
56
|
return;
|
|
56
57
|
}
|
|
57
58
|
// Told about the record BEFORE it is selected. The caller is what puts
|
|
@@ -84,7 +85,7 @@ export function ConnectionForm({ actions, source, loading = false, onSaved }) {
|
|
|
84
85
|
if (!source) store.selectSource(saved.id);
|
|
85
86
|
}).catch((reason)=>{
|
|
86
87
|
setSaving(false);
|
|
87
|
-
store.setError(errorText(reason,
|
|
88
|
+
store.setError(errorText(reason, t.connectionSaveFailed));
|
|
88
89
|
});
|
|
89
90
|
};
|
|
90
91
|
if (loading) return /*#__PURE__*/ _jsx(CardSkeleton, {});
|
|
@@ -20,6 +20,7 @@ import { useInfiniteList } from './useInfiniteList';
|
|
|
20
20
|
const PAGE_SIZE = 20;
|
|
21
21
|
const SEARCH_DEBOUNCE_MS = 300;
|
|
22
22
|
export function ConnectionList({ actions, onNewConnection, reloadToken = 0 }) {
|
|
23
|
+
const t = useLabels().errors;
|
|
23
24
|
const store = useIntegrationsStore();
|
|
24
25
|
const labels = useLabels();
|
|
25
26
|
const search = store.sourcesSearch;
|
|
@@ -200,7 +201,7 @@ export function ConnectionList({ actions, onNewConnection, reloadToken = 0 }) {
|
|
|
200
201
|
}),
|
|
201
202
|
list.loading && list.items.length > 0 ? /*#__PURE__*/ _jsx("p", {
|
|
202
203
|
className: theme.field.hint,
|
|
203
|
-
children:
|
|
204
|
+
children: t.loadingMore
|
|
204
205
|
}) : null
|
|
205
206
|
]
|
|
206
207
|
}));
|
|
@@ -16,6 +16,7 @@ import { CardSkeleton } from './Skeletons';
|
|
|
16
16
|
* sends the operator back to guessing.
|
|
17
17
|
*/ const theme = integrationsPageTheme;
|
|
18
18
|
export function ConnectionTest({ actions, source, loading = false }) {
|
|
19
|
+
const t = useLabels().errors;
|
|
19
20
|
const labels = useLabels();
|
|
20
21
|
const [testing, setTesting] = useState(false);
|
|
21
22
|
const [result, setResult] = useState(null);
|
|
@@ -62,7 +63,7 @@ export function ConnectionTest({ actions, source, loading = false }) {
|
|
|
62
63
|
setTesting(false);
|
|
63
64
|
setResult({
|
|
64
65
|
ok: false,
|
|
65
|
-
error: errorText(reason,
|
|
66
|
+
error: errorText(reason, t.testFailed)
|
|
66
67
|
});
|
|
67
68
|
});
|
|
68
69
|
};
|
|
@@ -115,7 +116,7 @@ export function ConnectionTest({ actions, source, loading = false }) {
|
|
|
115
116
|
tone: "danger",
|
|
116
117
|
children: /*#__PURE__*/ _jsx("p", {
|
|
117
118
|
className: cn(theme.notice.body, 'whitespace-pre-wrap break-words font-mono'),
|
|
118
|
-
children: result.error ??
|
|
119
|
+
children: result.error ?? t.testFailedNoMessage
|
|
119
120
|
})
|
|
120
121
|
}) : null
|
|
121
122
|
]
|
|
@@ -3,6 +3,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
3
3
|
import { useRef, useState } from 'react';
|
|
4
4
|
import { cn } from '../../../utils/cn';
|
|
5
5
|
import { useIntegrationsStore } from '../store';
|
|
6
|
+
import { useLabels } from '../text/context';
|
|
6
7
|
import { integrationsPageTheme } from '../theme';
|
|
7
8
|
import { Notice } from './Primitives';
|
|
8
9
|
/**
|
|
@@ -24,8 +25,9 @@ import { Notice } from './Primitives';
|
|
|
24
25
|
* see ConnectionExport. Importing is the one that belongs here, because
|
|
25
26
|
* importing is what you do when you have nothing chosen yet.
|
|
26
27
|
*/ const theme = integrationsPageTheme;
|
|
27
|
-
const messageOf = (error)=>error instanceof Error ? error.message :
|
|
28
|
+
const messageOf = (error, fallback)=>error instanceof Error ? error.message : fallback;
|
|
28
29
|
export function ConnectionTransfer({ actions, onImported }) {
|
|
30
|
+
const t = useLabels().transfer;
|
|
29
31
|
const store = useIntegrationsStore();
|
|
30
32
|
const fileRef = useRef(null);
|
|
31
33
|
const [busy, setBusy] = useState(false);
|
|
@@ -44,7 +46,7 @@ export function ConnectionTransfer({ actions, onImported }) {
|
|
|
44
46
|
setProblems([
|
|
45
47
|
{
|
|
46
48
|
path: file.name,
|
|
47
|
-
message:
|
|
49
|
+
message: t.notJson
|
|
48
50
|
}
|
|
49
51
|
]);
|
|
50
52
|
return;
|
|
@@ -65,7 +67,7 @@ export function ConnectionTransfer({ actions, onImported }) {
|
|
|
65
67
|
});
|
|
66
68
|
}).catch((error)=>{
|
|
67
69
|
setBusy(false);
|
|
68
|
-
store.setError(messageOf(error));
|
|
70
|
+
store.setError(messageOf(error, t.requestFailed));
|
|
69
71
|
});
|
|
70
72
|
};
|
|
71
73
|
return /*#__PURE__*/ _jsxs("section", {
|
|
@@ -76,7 +78,7 @@ export function ConnectionTransfer({ actions, onImported }) {
|
|
|
76
78
|
disabled: busy,
|
|
77
79
|
onClick: ()=>fileRef.current?.click(),
|
|
78
80
|
type: "button",
|
|
79
|
-
children: busy ?
|
|
81
|
+
children: busy ? t.working : t.importButton
|
|
80
82
|
}),
|
|
81
83
|
/*#__PURE__*/ _jsx("input", {
|
|
82
84
|
accept: "application/json,.json",
|
|
@@ -96,7 +98,7 @@ export function ConnectionTransfer({ actions, onImported }) {
|
|
|
96
98
|
children: note
|
|
97
99
|
}) : null,
|
|
98
100
|
problems.length > 0 ? /*#__PURE__*/ _jsx(Notice, {
|
|
99
|
-
title:
|
|
101
|
+
title: t.cannotImportTitle,
|
|
100
102
|
tone: "danger",
|
|
101
103
|
children: /*#__PURE__*/ _jsx("ul", {
|
|
102
104
|
className: "flex flex-col gap-1",
|
|
@@ -19,6 +19,7 @@ import { CardSkeleton } from './Skeletons';
|
|
|
19
19
|
* button per field.
|
|
20
20
|
*/ const theme = integrationsPageTheme;
|
|
21
21
|
export function CredentialFields({ actions, source, loading = false }) {
|
|
22
|
+
const t = useLabels().errors;
|
|
22
23
|
const labels = useLabels();
|
|
23
24
|
const store = useIntegrationsStore();
|
|
24
25
|
const [values, setValues] = useState({});
|
|
@@ -92,7 +93,7 @@ export function CredentialFields({ actions, source, loading = false }) {
|
|
|
92
93
|
}
|
|
93
94
|
}
|
|
94
95
|
if (filled === 0) {
|
|
95
|
-
setStatus(
|
|
96
|
+
setStatus(t.nothingToSave);
|
|
96
97
|
return;
|
|
97
98
|
}
|
|
98
99
|
setBusy(true);
|
|
@@ -104,10 +105,10 @@ export function CredentialFields({ actions, source, loading = false }) {
|
|
|
104
105
|
// stored can only ever be looked at as the mask below.
|
|
105
106
|
setValues({});
|
|
106
107
|
applyHints(result);
|
|
107
|
-
setStatus(
|
|
108
|
+
setStatus(t.credentialsSaved);
|
|
108
109
|
}).catch((reason)=>{
|
|
109
110
|
setBusy(false);
|
|
110
|
-
store.setError(errorText(reason,
|
|
111
|
+
store.setError(errorText(reason, t.credentialsSaveFailed));
|
|
111
112
|
});
|
|
112
113
|
};
|
|
113
114
|
const handleClear = (slot)=>{
|
|
@@ -128,10 +129,10 @@ export function CredentialFields({ actions, source, loading = false }) {
|
|
|
128
129
|
remember({
|
|
129
130
|
[slot]: hintFromResult(result, slot) ?? null
|
|
130
131
|
});
|
|
131
|
-
setStatus(
|
|
132
|
+
setStatus(t.credentialCleared);
|
|
132
133
|
}).catch((reason)=>{
|
|
133
134
|
setBusy(false);
|
|
134
|
-
store.setError(errorText(reason,
|
|
135
|
+
store.setError(errorText(reason, t.credentialClearFailed));
|
|
135
136
|
});
|
|
136
137
|
};
|
|
137
138
|
return /*#__PURE__*/ _jsxs("section", {
|
|
@@ -16,6 +16,7 @@ import { Badge, Field } from './Primitives';
|
|
|
16
16
|
* accident, roughly once.
|
|
17
17
|
*/ const theme = integrationsPageTheme;
|
|
18
18
|
export function CredentialSlotRow({ slot, source, value, maskedHint, disabled, onChange, onClear }) {
|
|
19
|
+
const t = useLabels().errors;
|
|
19
20
|
const labels = useLabels();
|
|
20
21
|
const id = `credential-${slot}`;
|
|
21
22
|
const label = slotLabel(slot, source);
|
|
@@ -34,7 +35,7 @@ export function CredentialSlotRow({ slot, source, value, maskedHint, disabled, o
|
|
|
34
35
|
disabled: disabled,
|
|
35
36
|
id: id,
|
|
36
37
|
onChange: (event)=>onChange(event.target.value),
|
|
37
|
-
placeholder: stored ?
|
|
38
|
+
placeholder: stored ? t.keepStored : t.nothingStored,
|
|
38
39
|
type: "password",
|
|
39
40
|
value: value
|
|
40
41
|
})
|
|
@@ -19,6 +19,7 @@ import { pathParamNames } from './pathParams';
|
|
|
19
19
|
* a list page arriving in the background.
|
|
20
20
|
*/ const theme = integrationsPageTheme;
|
|
21
21
|
export function EndpointForm({ sourceId, endpoint, actions, onSaved, onDeleted, onCancel }) {
|
|
22
|
+
const t = useLabels().errors;
|
|
22
23
|
const labels = useLabels();
|
|
23
24
|
const store = useIntegrationsStore();
|
|
24
25
|
const [saving, setSaving] = useState(false);
|
|
@@ -106,8 +107,8 @@ export function EndpointForm({ sourceId, endpoint, actions, onSaved, onDeleted,
|
|
|
106
107
|
}).then((saved)=>{
|
|
107
108
|
setSaving(false);
|
|
108
109
|
if (saved) onSaved(saved);
|
|
109
|
-
else store.setError(
|
|
110
|
-
}).catch(fail(
|
|
110
|
+
else store.setError(t.endpointNotReturned);
|
|
111
|
+
}).catch(fail(t.endpointSaveFailed));
|
|
111
112
|
};
|
|
112
113
|
const remove = ()=>{
|
|
113
114
|
if (!endpoint) return;
|
|
@@ -116,8 +117,8 @@ export function EndpointForm({ sourceId, endpoint, actions, onSaved, onDeleted,
|
|
|
116
117
|
actions.deleteEndpoint(endpoint.id).then((ok)=>{
|
|
117
118
|
setDeleting(false);
|
|
118
119
|
if (ok) onDeleted(endpoint.id);
|
|
119
|
-
else store.setError(
|
|
120
|
-
}).catch(fail(
|
|
120
|
+
else store.setError(t.endpointNotDeleted);
|
|
121
|
+
}).catch(fail(t.endpointDeleteFailed));
|
|
121
122
|
};
|
|
122
123
|
return /*#__PURE__*/ _jsxs("form", {
|
|
123
124
|
className: theme.card.wrapper,
|
|
@@ -17,6 +17,7 @@ import { settlementOf } from './settleOwnership';
|
|
|
17
17
|
* their own block here rather than being folded into a generic "no data".
|
|
18
18
|
*/ const theme = integrationsPageTheme;
|
|
19
19
|
export function EndpointSample({ endpoint, actions }) {
|
|
20
|
+
const t = useLabels().errors;
|
|
20
21
|
const labels = useLabels();
|
|
21
22
|
const store = useIntegrationsStore();
|
|
22
23
|
const [values, setValues] = useState({});
|
|
@@ -97,7 +98,7 @@ export function EndpointSample({ endpoint, actions }) {
|
|
|
97
98
|
}).catch((error)=>{
|
|
98
99
|
if (settleElsewhere(mine, requestedFor)) return;
|
|
99
100
|
store.setSample(null, requestedFor);
|
|
100
|
-
store.setError(error instanceof Error ? error.message :
|
|
101
|
+
store.setError(error instanceof Error ? error.message : t.sampleFailed);
|
|
101
102
|
});
|
|
102
103
|
};
|
|
103
104
|
return /*#__PURE__*/ _jsxs("section", {
|
|
@@ -44,13 +44,13 @@ export function FieldMappingRows({ rows, sourceFields, targetFields, disabled, o
|
|
|
44
44
|
type: "button",
|
|
45
45
|
children: labels.mappings.addField
|
|
46
46
|
}),
|
|
47
|
-
purpose:
|
|
47
|
+
purpose: labels.sections.fieldsPurpose,
|
|
48
48
|
title: labels.mappings.fieldsHeading,
|
|
49
49
|
children: [
|
|
50
50
|
sourceFields.length === 0 ? /*#__PURE__*/ _jsx(Notice, {
|
|
51
51
|
title: labels.mappings.sampleFirstTitle,
|
|
52
52
|
tone: "warning",
|
|
53
|
-
children:
|
|
53
|
+
children: labels.mappings.sampleFirstBody
|
|
54
54
|
}) : null,
|
|
55
55
|
/*#__PURE__*/ _jsx("datalist", {
|
|
56
56
|
id: listId,
|
|
@@ -60,7 +60,7 @@ export function FieldMappingRows({ rows, sourceFields, targetFields, disabled, o
|
|
|
60
60
|
}),
|
|
61
61
|
rows.length === 0 ? /*#__PURE__*/ _jsx("p", {
|
|
62
62
|
className: theme.list.empty,
|
|
63
|
-
children:
|
|
63
|
+
children: labels.mappings.nothingMapped
|
|
64
64
|
}) : /*#__PURE__*/ _jsxs(_Fragment, {
|
|
65
65
|
children: [
|
|
66
66
|
/*#__PURE__*/ _jsxs("div", {
|
|
@@ -73,7 +73,7 @@ export function FieldMappingRows({ rows, sourceFields, targetFields, disabled, o
|
|
|
73
73
|
}, column)),
|
|
74
74
|
/*#__PURE__*/ _jsx("span", {
|
|
75
75
|
className: cn(theme.field.label, 'w-28'),
|
|
76
|
-
children:
|
|
76
|
+
children: labels.errors.fieldOrder
|
|
77
77
|
})
|
|
78
78
|
]
|
|
79
79
|
}),
|
|
@@ -92,84 +92,21 @@ export function FieldMappingRows({ rows, sourceFields, targetFields, disabled, o
|
|
|
92
92
|
targetFields: targetFields
|
|
93
93
|
}, `field-mapping-${index}`))
|
|
94
94
|
}),
|
|
95
|
-
/*#__PURE__*/
|
|
95
|
+
/*#__PURE__*/ _jsx("p", {
|
|
96
96
|
className: theme.field.hint,
|
|
97
|
-
children:
|
|
98
|
-
"Prefix a source with ",
|
|
99
|
-
/*#__PURE__*/ _jsx("strong", {
|
|
100
|
-
children: PARENT_PREFIX
|
|
101
|
-
}),
|
|
102
|
-
" to take the value from the parent endpoint's record instead of this one."
|
|
103
|
-
]
|
|
97
|
+
children: labels.hints.parentPrefix(PARENT_PREFIX)
|
|
104
98
|
}),
|
|
105
|
-
/*#__PURE__*/
|
|
99
|
+
/*#__PURE__*/ _jsx("p", {
|
|
106
100
|
className: theme.field.hint,
|
|
107
|
-
children:
|
|
108
|
-
"Name several fields in ",
|
|
109
|
-
/*#__PURE__*/ _jsx("strong", {
|
|
110
|
-
children: '{braces}'
|
|
111
|
-
}),
|
|
112
|
-
" to build one value from them —",
|
|
113
|
-
' ',
|
|
114
|
-
/*#__PURE__*/ _jsx("strong", {
|
|
115
|
-
children: '{companyCode}-{organizationCode}'
|
|
116
|
-
}),
|
|
117
|
-
". Use it when no single field is unique on its own, which is what the deduplication column needs."
|
|
118
|
-
]
|
|
101
|
+
children: labels.hints.braces
|
|
119
102
|
}),
|
|
120
|
-
/*#__PURE__*/
|
|
103
|
+
/*#__PURE__*/ _jsx("p", {
|
|
121
104
|
className: theme.field.hint,
|
|
122
|
-
children:
|
|
123
|
-
"A single field inside the braces can be shaped on its own with ",
|
|
124
|
-
/*#__PURE__*/ _jsx("strong", {
|
|
125
|
-
children: '|'
|
|
126
|
-
}),
|
|
127
|
-
":",
|
|
128
|
-
' ',
|
|
129
|
-
/*#__PURE__*/ _jsx("strong", {
|
|
130
|
-
children: '{companyCode}-{departmentCode|pathLeaf}'
|
|
131
|
-
}),
|
|
132
|
-
" turns ",
|
|
133
|
-
/*#__PURE__*/ _jsx("em", {
|
|
134
|
-
children: "TAT"
|
|
135
|
-
}),
|
|
136
|
-
" and",
|
|
137
|
-
' ',
|
|
138
|
-
/*#__PURE__*/ _jsx("em", {
|
|
139
|
-
children: "050/285/204"
|
|
140
|
-
}),
|
|
141
|
-
" into ",
|
|
142
|
-
/*#__PURE__*/ _jsx("em", {
|
|
143
|
-
children: "TAT-204"
|
|
144
|
-
}),
|
|
145
|
-
". The transform chosen beside the row still applies to the finished value."
|
|
146
|
-
]
|
|
105
|
+
children: labels.hints.perFieldTransform
|
|
147
106
|
}),
|
|
148
|
-
/*#__PURE__*/
|
|
107
|
+
/*#__PURE__*/ _jsx("p", {
|
|
149
108
|
className: theme.field.hint,
|
|
150
|
-
children:
|
|
151
|
-
/*#__PURE__*/ _jsx("strong", {
|
|
152
|
-
children: "Fallback"
|
|
153
|
-
}),
|
|
154
|
-
" takes the same braces, so a record that arrives without an e-mail can still be given one: ",
|
|
155
|
-
/*#__PURE__*/ _jsx("strong", {
|
|
156
|
-
children: '{ad}.{soyad}@example.com'
|
|
157
|
-
}),
|
|
158
|
-
". Pair it with the ",
|
|
159
|
-
/*#__PURE__*/ _jsx("strong", {
|
|
160
|
-
children: "E-mail safe"
|
|
161
|
-
}),
|
|
162
|
-
" transform and ",
|
|
163
|
-
/*#__PURE__*/ _jsx("em", {
|
|
164
|
-
children: "Ayşe Yılmaz"
|
|
165
|
-
}),
|
|
166
|
-
" becomes",
|
|
167
|
-
' ',
|
|
168
|
-
/*#__PURE__*/ _jsx("em", {
|
|
169
|
-
children: "ayse.yilmaz@example.com"
|
|
170
|
-
}),
|
|
171
|
-
". Records that already carry an address keep it."
|
|
172
|
-
]
|
|
109
|
+
children: labels.hints.fallbackBraces
|
|
173
110
|
})
|
|
174
111
|
]
|
|
175
112
|
})
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
3
|
import { useId } from 'react';
|
|
4
|
+
import { useLabels } from '../text/context';
|
|
4
5
|
import { integrationsPageTheme } from '../theme';
|
|
5
6
|
import { Field, Notice, Section } from './Primitives';
|
|
6
7
|
/**
|
|
@@ -22,6 +23,7 @@ import { Field, Notice, Section } from './Primitives';
|
|
|
22
23
|
/** Columns that plausibly hold a password, so the guess is a good one. */ const PASSWORD_LIKE = /password|passwd|sifre|şifre|parola/i;
|
|
23
24
|
/** Columns that plausibly point at the account row. */ const LINK_LIKE = /^(user_?id|account_?id|login_?id)$/i;
|
|
24
25
|
export function MappingAccountFields({ value, targetFields, targets, disabled, onChange }) {
|
|
26
|
+
const t = useLabels().account;
|
|
25
27
|
const uid = useId();
|
|
26
28
|
const accountEntity = targets.find((target)=>target.entity === value?.entity);
|
|
27
29
|
const accountFields = accountEntity?.fields ?? [];
|
|
@@ -59,8 +61,8 @@ export function MappingAccountFields({ value, targetFields, targets, disabled, o
|
|
|
59
61
|
type: "button",
|
|
60
62
|
children: value ? 'Turn off' : 'Turn on'
|
|
61
63
|
}),
|
|
62
|
-
purpose:
|
|
63
|
-
title:
|
|
64
|
+
purpose: t.purpose,
|
|
65
|
+
title: t.title,
|
|
64
66
|
children: value ? /*#__PURE__*/ _jsxs(_Fragment, {
|
|
65
67
|
children: [
|
|
66
68
|
/*#__PURE__*/ _jsxs("div", {
|
|
@@ -68,7 +70,7 @@ export function MappingAccountFields({ value, targetFields, targets, disabled, o
|
|
|
68
70
|
children: [
|
|
69
71
|
/*#__PURE__*/ _jsx(Field, {
|
|
70
72
|
htmlFor: `${uid}-entity`,
|
|
71
|
-
label:
|
|
73
|
+
label: t.livesIn,
|
|
72
74
|
children: /*#__PURE__*/ _jsxs("select", {
|
|
73
75
|
className: theme.field.input,
|
|
74
76
|
disabled: disabled,
|
|
@@ -84,7 +86,7 @@ export function MappingAccountFields({ value, targetFields, targets, disabled, o
|
|
|
84
86
|
children: [
|
|
85
87
|
/*#__PURE__*/ _jsx("option", {
|
|
86
88
|
value: "",
|
|
87
|
-
children:
|
|
89
|
+
children: t.notSet
|
|
88
90
|
}),
|
|
89
91
|
targets.map((target)=>/*#__PURE__*/ _jsx("option", {
|
|
90
92
|
value: target.entity,
|
|
@@ -96,7 +98,7 @@ export function MappingAccountFields({ value, targetFields, targets, disabled, o
|
|
|
96
98
|
/*#__PURE__*/ _jsx(Field, {
|
|
97
99
|
hint: "The column on the account that identifies it.",
|
|
98
100
|
htmlFor: `${uid}-match-column`,
|
|
99
|
-
label:
|
|
101
|
+
label: t.identifiedBy,
|
|
100
102
|
children: /*#__PURE__*/ _jsxs("select", {
|
|
101
103
|
className: theme.field.input,
|
|
102
104
|
disabled: disabled || accountFields.length === 0,
|
|
@@ -108,7 +110,7 @@ export function MappingAccountFields({ value, targetFields, targets, disabled, o
|
|
|
108
110
|
children: [
|
|
109
111
|
/*#__PURE__*/ _jsx("option", {
|
|
110
112
|
value: "",
|
|
111
|
-
children:
|
|
113
|
+
children: t.notSet
|
|
112
114
|
}),
|
|
113
115
|
accountFields.map((field)=>/*#__PURE__*/ _jsx("option", {
|
|
114
116
|
value: field,
|
|
@@ -120,7 +122,7 @@ export function MappingAccountFields({ value, targetFields, targets, disabled, o
|
|
|
120
122
|
/*#__PURE__*/ _jsx(Field, {
|
|
121
123
|
hint: "Where the run's shared password is written.",
|
|
122
124
|
htmlFor: `${uid}-password`,
|
|
123
|
-
label:
|
|
125
|
+
label: t.passwordInto,
|
|
124
126
|
children: /*#__PURE__*/ _jsxs("select", {
|
|
125
127
|
className: theme.field.input,
|
|
126
128
|
disabled: disabled || accountFields.length === 0,
|
|
@@ -132,14 +134,14 @@ export function MappingAccountFields({ value, targetFields, targets, disabled, o
|
|
|
132
134
|
children: [
|
|
133
135
|
/*#__PURE__*/ _jsx("option", {
|
|
134
136
|
value: "",
|
|
135
|
-
children:
|
|
137
|
+
children: t.notSet
|
|
136
138
|
}),
|
|
137
139
|
accountFields.filter((field)=>PASSWORD_LIKE.test(field)).map((field)=>/*#__PURE__*/ _jsx("option", {
|
|
138
140
|
value: field,
|
|
139
141
|
children: field
|
|
140
142
|
}, field)),
|
|
141
143
|
accountFields.filter((field)=>!PASSWORD_LIKE.test(field)).length > 0 ? /*#__PURE__*/ _jsx("optgroup", {
|
|
142
|
-
label:
|
|
144
|
+
label: t.otherColumns,
|
|
143
145
|
children: accountFields.filter((field)=>!PASSWORD_LIKE.test(field)).map((field)=>/*#__PURE__*/ _jsx("option", {
|
|
144
146
|
value: field,
|
|
145
147
|
children: field
|
|
@@ -151,7 +153,7 @@ export function MappingAccountFields({ value, targetFields, targets, disabled, o
|
|
|
151
153
|
/*#__PURE__*/ _jsx(Field, {
|
|
152
154
|
hint: "The imported record's column carrying that same value.",
|
|
153
155
|
htmlFor: `${uid}-match-from`,
|
|
154
|
-
label:
|
|
156
|
+
label: t.matchedFrom,
|
|
155
157
|
children: /*#__PURE__*/ _jsxs("select", {
|
|
156
158
|
className: theme.field.input,
|
|
157
159
|
disabled: disabled,
|
|
@@ -163,7 +165,7 @@ export function MappingAccountFields({ value, targetFields, targets, disabled, o
|
|
|
163
165
|
children: [
|
|
164
166
|
/*#__PURE__*/ _jsx("option", {
|
|
165
167
|
value: "",
|
|
166
|
-
children:
|
|
168
|
+
children: t.notSet
|
|
167
169
|
}),
|
|
168
170
|
targetFields.map((field)=>/*#__PURE__*/ _jsx("option", {
|
|
169
171
|
value: field,
|
|
@@ -175,7 +177,7 @@ export function MappingAccountFields({ value, targetFields, targets, disabled, o
|
|
|
175
177
|
/*#__PURE__*/ _jsx(Field, {
|
|
176
178
|
hint: "Used only when the column above came back EMPTY, so nobody is left without a login. Name the record's own columns in braces — {firstName}.{sicilNo}@acme.com. Leave it blank to go on skipping those records.",
|
|
177
179
|
htmlFor: `${uid}-email-format`,
|
|
178
|
-
label:
|
|
180
|
+
label: t.identifierFallback,
|
|
179
181
|
children: /*#__PURE__*/ _jsx("input", {
|
|
180
182
|
className: theme.field.input,
|
|
181
183
|
disabled: disabled,
|
|
@@ -190,7 +192,7 @@ export function MappingAccountFields({ value, targetFields, targets, disabled, o
|
|
|
190
192
|
/*#__PURE__*/ _jsx(Field, {
|
|
191
193
|
hint: "Filled with the new account's id, so the record and its login know each other.",
|
|
192
194
|
htmlFor: `${uid}-id-column`,
|
|
193
|
-
label:
|
|
195
|
+
label: t.accountIdInto,
|
|
194
196
|
children: /*#__PURE__*/ _jsxs("select", {
|
|
195
197
|
className: theme.field.input,
|
|
196
198
|
disabled: disabled,
|
|
@@ -202,7 +204,7 @@ export function MappingAccountFields({ value, targetFields, targets, disabled, o
|
|
|
202
204
|
children: [
|
|
203
205
|
/*#__PURE__*/ _jsx("option", {
|
|
204
206
|
value: "",
|
|
205
|
-
children:
|
|
207
|
+
children: t.notSet
|
|
206
208
|
}),
|
|
207
209
|
targetFields.map((field)=>/*#__PURE__*/ _jsx("option", {
|
|
208
210
|
value: field,
|
|
@@ -221,7 +223,7 @@ export function MappingAccountFields({ value, targetFields, targets, disabled, o
|
|
|
221
223
|
children: [
|
|
222
224
|
/*#__PURE__*/ _jsx("span", {
|
|
223
225
|
className: theme.field.label,
|
|
224
|
-
children:
|
|
226
|
+
children: t.membership
|
|
225
227
|
}),
|
|
226
228
|
/*#__PURE__*/ _jsx("button", {
|
|
227
229
|
className: theme.button.ghost,
|
|
@@ -272,7 +274,7 @@ export function MappingAccountFields({ value, targetFields, targets, disabled, o
|
|
|
272
274
|
children: [
|
|
273
275
|
/*#__PURE__*/ _jsx("option", {
|
|
274
276
|
value: "",
|
|
275
|
-
children:
|
|
277
|
+
children: t.membershipTable
|
|
276
278
|
}),
|
|
277
279
|
targets.map((target)=>/*#__PURE__*/ _jsx("option", {
|
|
278
280
|
value: target.entity,
|
|
@@ -344,7 +346,7 @@ export function MappingAccountFields({ value, targetFields, targets, disabled, o
|
|
|
344
346
|
]
|
|
345
347
|
}),
|
|
346
348
|
/*#__PURE__*/ _jsx(Notice, {
|
|
347
|
-
title:
|
|
349
|
+
title: t.sharedPasswordTitle,
|
|
348
350
|
tone: "info",
|
|
349
351
|
children: "Every account this run creates is given the same opening password — asked for once, when the import is started, and stored nowhere. People change it themselves afterwards. A record whose value already has an account is linked to that one instead, so running this import again does not create a second."
|
|
350
352
|
})
|
|
@@ -77,8 +77,8 @@ export function MappingEditor({ mapping, targets, targetsLoading, endpoints, fre
|
|
|
77
77
|
className: theme.card.body,
|
|
78
78
|
children: [
|
|
79
79
|
/*#__PURE__*/ _jsxs(Section, {
|
|
80
|
-
purpose:
|
|
81
|
-
title:
|
|
80
|
+
purpose: labels.sections.whatThisIsPurpose,
|
|
81
|
+
title: labels.sections.whatThisIs,
|
|
82
82
|
children: [
|
|
83
83
|
/*#__PURE__*/ _jsx(Field, {
|
|
84
84
|
hint: endpoints.length === 0 ? labels.mappings.noEndpointsBody : readsFrom?.path ?? labels.mappings.readsFromHint,
|
|
@@ -173,8 +173,8 @@ export function MappingEditor({ mapping, targets, targetsLoading, endpoints, fre
|
|
|
173
173
|
]
|
|
174
174
|
}),
|
|
175
175
|
/*#__PURE__*/ _jsx(Section, {
|
|
176
|
-
purpose:
|
|
177
|
-
title:
|
|
176
|
+
purpose: labels.sections.matchingAndWritingPurpose,
|
|
177
|
+
title: labels.sections.matchingAndWriting,
|
|
178
178
|
children: /*#__PURE__*/ _jsx(MappingWriteModeFields, {
|
|
179
179
|
dedupConfigured: (draft.dedupTargetField ?? '').trim() !== '',
|
|
180
180
|
disabled: busy,
|
|
@@ -28,6 +28,7 @@ function describeLastRun(value) {
|
|
|
28
28
|
return Number.isNaN(when.getTime()) ? 'Never run' : `Last run ${when.toLocaleString()}`;
|
|
29
29
|
}
|
|
30
30
|
export function MappingList({ actions, sourceId, selectedId, reloadToken, onSelect, onRun }) {
|
|
31
|
+
const t = useLabels().errors;
|
|
31
32
|
const labels = useLabels();
|
|
32
33
|
const store = useIntegrationsStore();
|
|
33
34
|
const uid = useId();
|
|
@@ -146,7 +147,7 @@ export function MappingList({ actions, sourceId, selectedId, reloadToken, onSele
|
|
|
146
147
|
rows: 5
|
|
147
148
|
}) : list.items.length === 0 && !list.error ? /*#__PURE__*/ _jsx("p", {
|
|
148
149
|
className: theme.list.empty,
|
|
149
|
-
children: store.endpointsTotal === 0 ?
|
|
150
|
+
children: store.endpointsTotal === 0 ? t.noEndpointsForMapping : labels.mappings.empty
|
|
150
151
|
}) : /*#__PURE__*/ _jsxs(_Fragment, {
|
|
151
152
|
children: [
|
|
152
153
|
/*#__PURE__*/ _jsxs("p", {
|
|
@@ -180,7 +181,7 @@ export function MappingList({ actions, sourceId, selectedId, reloadToken, onSele
|
|
|
180
181
|
}),
|
|
181
182
|
/*#__PURE__*/ _jsx("span", {
|
|
182
183
|
className: theme.list.itemMeta,
|
|
183
|
-
children: mapping.targetEntity ||
|
|
184
|
+
children: mapping.targetEntity || t.noTargetEntity
|
|
184
185
|
}),
|
|
185
186
|
/*#__PURE__*/ _jsxs("span", {
|
|
186
187
|
className: "mt-1 flex flex-wrap items-center gap-1.5",
|