@workbench-kit/shell-react 0.0.2-prototype.0.2.43 → 0.0.2-prototype.0.2.44
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +39 -0
- package/package.json +10 -9
- package/src/editor/workspace-reconcile.tsx +12 -7
- package/src/field-remap/chrome-labels.ts +99 -0
- package/src/field-remap/convert-note-editor.tsx +115 -106
- package/src/field-remap/detail-panel.tsx +524 -456
- package/src/field-remap/document-io.tsx +299 -0
- package/src/field-remap/flow.tsx +188 -126
- package/src/field-remap/panel.tsx +60 -0
- package/src/field-remap/transform-options-editor.tsx +64 -48
- package/src/field-remap/view.css +46 -147
- package/src/keybinding-management-settings.ts +4 -0
- package/src/management/keybinding-settings-view.tsx +31 -0
- package/src/management/keybinding-settings.tsx +4 -21
- package/src/management/use-keybinding-management.ts +3 -3
- package/src/shell/provider.tsx +10 -1
package/README.md
CHANGED
|
@@ -120,6 +120,7 @@ import {
|
|
|
120
120
|
FieldRemapFlowMapper,
|
|
121
121
|
createJsonataValueTransform,
|
|
122
122
|
} from '@workbench-kit/shell-react/field-remap';
|
|
123
|
+
import type { FieldRemapDocument } from '@workbench-kit/field-remap';
|
|
123
124
|
import '@workbench-kit/shell-react/field-remap/view.css';
|
|
124
125
|
|
|
125
126
|
// Uncontrolled demo:
|
|
@@ -133,6 +134,44 @@ import '@workbench-kit/shell-react/field-remap/view.css';
|
|
|
133
134
|
for Flow-only embeds and custom bundler setups. The full barrel
|
|
134
135
|
`import { FieldRemapPanel } from '@workbench-kit/shell-react'` stays supported.
|
|
135
136
|
|
|
137
|
+
### n→m operators in direct Flow embeds
|
|
138
|
+
|
|
139
|
+
`FieldRemapFlowMapper` keeps durable edges and document-v2 combine/split operators
|
|
140
|
+
controlled. A host that enables operator authoring owns both arrays and commits each
|
|
141
|
+
complete next operator array through the same persistence/history boundary:
|
|
142
|
+
|
|
143
|
+
```tsx
|
|
144
|
+
const [document, setDocument] = useState(initialDocument);
|
|
145
|
+
const commitDocumentChange = (next: FieldRemapDocument) => {
|
|
146
|
+
setDocument(next);
|
|
147
|
+
hostHistory.record(next);
|
|
148
|
+
persist(next);
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
<FieldRemapFlowMapper
|
|
152
|
+
sources={sources}
|
|
153
|
+
targets={targets}
|
|
154
|
+
transforms={registry}
|
|
155
|
+
edges={document.edges}
|
|
156
|
+
onEdgesChange={(next) => commitDocumentChange({ ...document, edges: next })}
|
|
157
|
+
operators={document.operators ?? []}
|
|
158
|
+
onOperatorsChange={(next) => commitDocumentChange({ ...document, operators: next })}
|
|
159
|
+
/>;
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
The presence of `onOperatorsChange` is the operator-authoring capability signal: it
|
|
163
|
+
enables the existing Add combine / Add split actions and routes operator wiring, detail,
|
|
164
|
+
and deletion mutations through that callback. Omitting the callback is intentional
|
|
165
|
+
inspect-only projection; supplied operators can still render and be selected, but operator
|
|
166
|
+
mutation chrome is absent. Do not infer writability from operator count, sample, chrome, or
|
|
167
|
+
labels. `readOnly` suppresses Flow authoring even when mutation callbacks are present.
|
|
168
|
+
|
|
169
|
+
`FieldRemapPanel` already supplies this wiring for its fully uncontrolled composite
|
|
170
|
+
`{ edges, operators }` state. If either durable channel is controlled, its existing
|
|
171
|
+
composite `historyOwner` contract applies as described below; consumers do not add a second
|
|
172
|
+
operator state layer merely to enable Panel authoring. Direct operator inventory drag/drop
|
|
173
|
+
and double-click placement are deferred to [#219](https://github.com/NewChoBo/workbench-kit/issues/219).
|
|
174
|
+
|
|
136
175
|
### Semantic history ownership
|
|
137
176
|
|
|
138
177
|
`FieldRemapPanel` keeps a private composite `{ edges, operators }` undo/redo stack only
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@workbench-kit/shell-react",
|
|
3
|
-
"version": "0.0.2-prototype.0.2.
|
|
3
|
+
"version": "0.0.2-prototype.0.2.44",
|
|
4
4
|
"private": false,
|
|
5
5
|
"sideEffects": [
|
|
6
6
|
"**/*.css"
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
"./field-remap": "./src/field-remap/index.ts",
|
|
17
17
|
"./field-remap/view.css": "./src/field-remap/view.css",
|
|
18
18
|
"./host-shell": "./src/shell/host-shell.tsx",
|
|
19
|
+
"./keybinding-management-settings": "./src/keybinding-management-settings.ts",
|
|
19
20
|
"./layout-storage": "./src/workbench/layout-storage.ts",
|
|
20
21
|
"./provider": "./src/shell/provider.tsx",
|
|
21
22
|
"./shell": "./src/shell/shell.tsx"
|
|
@@ -32,14 +33,14 @@
|
|
|
32
33
|
"@radix-ui/react-slot": "^1.3.0",
|
|
33
34
|
"@xyflow/react": "^12.11.2",
|
|
34
35
|
"jsonata": "^2.2.0",
|
|
35
|
-
"@workbench-kit/platform": "0.0.2-prototype.0.2.
|
|
36
|
-
"@workbench-kit/field-remap": "0.0.2-prototype.0.2.
|
|
37
|
-
"@workbench-kit/tokens": "0.0.2-prototype.0.2.
|
|
38
|
-
"@workbench-kit/react": "0.0.2-prototype.0.2.
|
|
39
|
-
"@workbench-kit/workbench-
|
|
40
|
-
"@workbench-kit/workbench-
|
|
41
|
-
"@workbench-kit/workspace": "0.0.2-prototype.0.2.
|
|
42
|
-
"@workbench-kit/workbench-
|
|
36
|
+
"@workbench-kit/platform": "0.0.2-prototype.0.2.44",
|
|
37
|
+
"@workbench-kit/field-remap": "0.0.2-prototype.0.2.44",
|
|
38
|
+
"@workbench-kit/tokens": "0.0.2-prototype.0.2.44",
|
|
39
|
+
"@workbench-kit/react": "0.0.2-prototype.0.2.44",
|
|
40
|
+
"@workbench-kit/workbench-config": "0.0.2-prototype.0.2.44",
|
|
41
|
+
"@workbench-kit/workbench-core": "0.0.2-prototype.0.2.44",
|
|
42
|
+
"@workbench-kit/workspace": "0.0.2-prototype.0.2.44",
|
|
43
|
+
"@workbench-kit/workbench-extension-sdk": "0.0.2-prototype.0.2.44"
|
|
43
44
|
},
|
|
44
45
|
"peerDependencies": {
|
|
45
46
|
"react": "^19.0.0",
|
|
@@ -1,19 +1,24 @@
|
|
|
1
1
|
import { useEffect } from 'react';
|
|
2
|
+
import type { EditorService } from '@workbench-kit/workbench-core';
|
|
2
3
|
|
|
3
4
|
import { createWorkspaceFileAvailabilityChecker } from './workspace-file-availability.js';
|
|
4
|
-
import { useEditorService } from './use-editor.js';
|
|
5
|
-
import { useWorkbench } from '../shell/provider.js';
|
|
6
5
|
import {
|
|
7
6
|
isWorkspaceResourceService,
|
|
8
7
|
useWorkspaceResourceState,
|
|
9
8
|
} from '../workbench/workspace-view-state.js';
|
|
10
9
|
|
|
10
|
+
interface EditorWorkspaceReconcilerProps {
|
|
11
|
+
readonly editorService: EditorService;
|
|
12
|
+
readonly workspaceHostService?: unknown;
|
|
13
|
+
}
|
|
14
|
+
|
|
11
15
|
/** Component-only module so Vite Fast Refresh can accept this boundary. */
|
|
12
|
-
export function EditorWorkspaceReconciler(
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
16
|
+
export function EditorWorkspaceReconciler({
|
|
17
|
+
editorService,
|
|
18
|
+
workspaceHostService,
|
|
19
|
+
}: EditorWorkspaceReconcilerProps): null {
|
|
20
|
+
const workspaceService = isWorkspaceResourceService(workspaceHostService)
|
|
21
|
+
? workspaceHostService
|
|
17
22
|
: undefined;
|
|
18
23
|
const workspaceState = useWorkspaceResourceState(workspaceService);
|
|
19
24
|
|
|
@@ -43,6 +43,31 @@ export interface FieldRemapChromeLabels {
|
|
|
43
43
|
/** Additive selection-detail Modal copy. Omitted legacy label objects use English defaults. */
|
|
44
44
|
readonly detailModalTitle?: string;
|
|
45
45
|
readonly closeDetailModal?: string;
|
|
46
|
+
/** Additive current-v2 document import/export chrome copy. */
|
|
47
|
+
readonly exportDocumentJson?: string;
|
|
48
|
+
readonly copyDocumentJson?: string;
|
|
49
|
+
readonly exportDocumentTitle?: string;
|
|
50
|
+
readonly closeDocumentExport?: string;
|
|
51
|
+
readonly exportDocumentDescription?: string;
|
|
52
|
+
readonly exportDocumentLabel?: string;
|
|
53
|
+
readonly importDocumentJson?: string;
|
|
54
|
+
readonly importDocumentTitle?: string;
|
|
55
|
+
readonly closeDocumentImport?: string;
|
|
56
|
+
readonly importDocumentDescription?: string;
|
|
57
|
+
readonly importDocumentLabel?: string;
|
|
58
|
+
readonly importDocumentPlaceholder?: string;
|
|
59
|
+
readonly applyDocumentImport?: string;
|
|
60
|
+
readonly cancelDocumentImport?: string;
|
|
61
|
+
readonly documentCopied?: string;
|
|
62
|
+
readonly documentCopyFailed?: string;
|
|
63
|
+
readonly documentImportUnavailable?: string;
|
|
64
|
+
readonly documentImportInvalidJson?: string;
|
|
65
|
+
readonly documentImportUnsupportedVersion?: string;
|
|
66
|
+
readonly documentImportInvalidDocument?: string;
|
|
67
|
+
readonly documentImportDuplicateId?: string;
|
|
68
|
+
readonly documentImportIncompatibleSource?: string;
|
|
69
|
+
readonly documentImportIncompatibleTarget?: string;
|
|
70
|
+
readonly documentImportUnavailableTransform?: string;
|
|
46
71
|
/** Additive Flow preview copy. Omitted legacy label objects use English defaults. */
|
|
47
72
|
readonly previewTitle?: string;
|
|
48
73
|
readonly previewLoading?: string;
|
|
@@ -86,6 +111,32 @@ export const defaultFieldRemapChromeLabels = {
|
|
|
86
111
|
readOnlyEmptyDetailDescription: 'Select a mapping to inspect its details.',
|
|
87
112
|
detailModalTitle: 'Mapping details',
|
|
88
113
|
closeDetailModal: 'Close details',
|
|
114
|
+
exportDocumentJson: 'Export JSON',
|
|
115
|
+
copyDocumentJson: 'Copy JSON',
|
|
116
|
+
exportDocumentTitle: 'Export mapping document',
|
|
117
|
+
closeDocumentExport: 'Close export',
|
|
118
|
+
exportDocumentDescription:
|
|
119
|
+
'Copy the current version 2 mapping document or select the JSON manually.',
|
|
120
|
+
exportDocumentLabel: 'Current mapping document JSON',
|
|
121
|
+
importDocumentJson: 'Import JSON',
|
|
122
|
+
importDocumentTitle: 'Import mapping document',
|
|
123
|
+
closeDocumentImport: 'Close import',
|
|
124
|
+
importDocumentDescription:
|
|
125
|
+
'Paste a current version 2 mapping document. A valid import replaces the complete mapping in one step.',
|
|
126
|
+
importDocumentLabel: 'Mapping document JSON',
|
|
127
|
+
importDocumentPlaceholder: 'Paste mapping document JSON',
|
|
128
|
+
applyDocumentImport: 'Validate and import',
|
|
129
|
+
cancelDocumentImport: 'Cancel',
|
|
130
|
+
documentCopied: 'Mapping document copied.',
|
|
131
|
+
documentCopyFailed: 'The mapping document could not be copied.',
|
|
132
|
+
documentImportUnavailable: 'Import is unavailable for this mapping.',
|
|
133
|
+
documentImportInvalidJson: 'Enter valid mapping document JSON.',
|
|
134
|
+
documentImportUnsupportedVersion: 'This mapping document version is not supported.',
|
|
135
|
+
documentImportInvalidDocument: 'This mapping document is invalid.',
|
|
136
|
+
documentImportDuplicateId: 'This mapping document contains duplicate identities.',
|
|
137
|
+
documentImportIncompatibleSource: 'This mapping document uses an unavailable source field.',
|
|
138
|
+
documentImportIncompatibleTarget: 'This mapping document uses an unavailable target field.',
|
|
139
|
+
documentImportUnavailableTransform: 'This mapping document uses an unavailable convert.',
|
|
89
140
|
previewTitle: 'Sample preview',
|
|
90
141
|
previewLoading: 'Updating preview…',
|
|
91
142
|
previewError: 'Preview failed',
|
|
@@ -128,6 +179,30 @@ export const fieldRemapChromeLabelKeys = {
|
|
|
128
179
|
readOnlyEmptyDetailDescription: 'fieldRemap.readOnlyEmptyDetailDescription',
|
|
129
180
|
detailModalTitle: 'fieldRemap.detailModalTitle',
|
|
130
181
|
closeDetailModal: 'fieldRemap.closeDetailModal',
|
|
182
|
+
exportDocumentJson: 'fieldRemap.exportDocumentJson',
|
|
183
|
+
copyDocumentJson: 'fieldRemap.copyDocumentJson',
|
|
184
|
+
exportDocumentTitle: 'fieldRemap.exportDocumentTitle',
|
|
185
|
+
closeDocumentExport: 'fieldRemap.closeDocumentExport',
|
|
186
|
+
exportDocumentDescription: 'fieldRemap.exportDocumentDescription',
|
|
187
|
+
exportDocumentLabel: 'fieldRemap.exportDocumentLabel',
|
|
188
|
+
importDocumentJson: 'fieldRemap.importDocumentJson',
|
|
189
|
+
importDocumentTitle: 'fieldRemap.importDocumentTitle',
|
|
190
|
+
closeDocumentImport: 'fieldRemap.closeDocumentImport',
|
|
191
|
+
importDocumentDescription: 'fieldRemap.importDocumentDescription',
|
|
192
|
+
importDocumentLabel: 'fieldRemap.importDocumentLabel',
|
|
193
|
+
importDocumentPlaceholder: 'fieldRemap.importDocumentPlaceholder',
|
|
194
|
+
applyDocumentImport: 'fieldRemap.applyDocumentImport',
|
|
195
|
+
cancelDocumentImport: 'fieldRemap.cancelDocumentImport',
|
|
196
|
+
documentCopied: 'fieldRemap.documentCopied',
|
|
197
|
+
documentCopyFailed: 'fieldRemap.documentCopyFailed',
|
|
198
|
+
documentImportUnavailable: 'fieldRemap.documentImportUnavailable',
|
|
199
|
+
documentImportInvalidJson: 'fieldRemap.documentImportInvalidJson',
|
|
200
|
+
documentImportUnsupportedVersion: 'fieldRemap.documentImportUnsupportedVersion',
|
|
201
|
+
documentImportInvalidDocument: 'fieldRemap.documentImportInvalidDocument',
|
|
202
|
+
documentImportDuplicateId: 'fieldRemap.documentImportDuplicateId',
|
|
203
|
+
documentImportIncompatibleSource: 'fieldRemap.documentImportIncompatibleSource',
|
|
204
|
+
documentImportIncompatibleTarget: 'fieldRemap.documentImportIncompatibleTarget',
|
|
205
|
+
documentImportUnavailableTransform: 'fieldRemap.documentImportUnavailableTransform',
|
|
131
206
|
previewTitle: 'fieldRemap.previewTitle',
|
|
132
207
|
previewLoading: 'fieldRemap.previewLoading',
|
|
133
208
|
previewError: 'fieldRemap.previewError',
|
|
@@ -180,6 +255,30 @@ export function resolveFieldRemapChromeLabels(
|
|
|
180
255
|
readOnlyEmptyDetailDescription: resolve('readOnlyEmptyDetailDescription'),
|
|
181
256
|
detailModalTitle: resolve('detailModalTitle'),
|
|
182
257
|
closeDetailModal: resolve('closeDetailModal'),
|
|
258
|
+
exportDocumentJson: resolve('exportDocumentJson'),
|
|
259
|
+
copyDocumentJson: resolve('copyDocumentJson'),
|
|
260
|
+
exportDocumentTitle: resolve('exportDocumentTitle'),
|
|
261
|
+
closeDocumentExport: resolve('closeDocumentExport'),
|
|
262
|
+
exportDocumentDescription: resolve('exportDocumentDescription'),
|
|
263
|
+
exportDocumentLabel: resolve('exportDocumentLabel'),
|
|
264
|
+
importDocumentJson: resolve('importDocumentJson'),
|
|
265
|
+
importDocumentTitle: resolve('importDocumentTitle'),
|
|
266
|
+
closeDocumentImport: resolve('closeDocumentImport'),
|
|
267
|
+
importDocumentDescription: resolve('importDocumentDescription'),
|
|
268
|
+
importDocumentLabel: resolve('importDocumentLabel'),
|
|
269
|
+
importDocumentPlaceholder: resolve('importDocumentPlaceholder'),
|
|
270
|
+
applyDocumentImport: resolve('applyDocumentImport'),
|
|
271
|
+
cancelDocumentImport: resolve('cancelDocumentImport'),
|
|
272
|
+
documentCopied: resolve('documentCopied'),
|
|
273
|
+
documentCopyFailed: resolve('documentCopyFailed'),
|
|
274
|
+
documentImportUnavailable: resolve('documentImportUnavailable'),
|
|
275
|
+
documentImportInvalidJson: resolve('documentImportInvalidJson'),
|
|
276
|
+
documentImportUnsupportedVersion: resolve('documentImportUnsupportedVersion'),
|
|
277
|
+
documentImportInvalidDocument: resolve('documentImportInvalidDocument'),
|
|
278
|
+
documentImportDuplicateId: resolve('documentImportDuplicateId'),
|
|
279
|
+
documentImportIncompatibleSource: resolve('documentImportIncompatibleSource'),
|
|
280
|
+
documentImportIncompatibleTarget: resolve('documentImportIncompatibleTarget'),
|
|
281
|
+
documentImportUnavailableTransform: resolve('documentImportUnavailableTransform'),
|
|
183
282
|
previewTitle: resolve('previewTitle'),
|
|
184
283
|
previewLoading: resolve('previewLoading'),
|
|
185
284
|
previewError: resolve('previewError'),
|
|
@@ -1,5 +1,12 @@
|
|
|
1
|
-
import { useMemo, type JSX } from 'react';
|
|
2
|
-
import {
|
|
1
|
+
import { useId, useMemo, type JSX } from 'react';
|
|
2
|
+
import {
|
|
3
|
+
Button,
|
|
4
|
+
Select,
|
|
5
|
+
WorkbenchPropertyHint,
|
|
6
|
+
WorkbenchPropertyRow,
|
|
7
|
+
WorkbenchPropertySection,
|
|
8
|
+
WorkbenchPropertyStack,
|
|
9
|
+
} from '@workbench-kit/react/primitives';
|
|
3
10
|
import {
|
|
4
11
|
optionFieldsForStep,
|
|
5
12
|
resolveOptionSteps,
|
|
@@ -46,6 +53,7 @@ export function ConvertNoteEditor({
|
|
|
46
53
|
onSelectionChange,
|
|
47
54
|
readOnly = false,
|
|
48
55
|
}: ConvertNoteEditorProps): JSX.Element | null {
|
|
56
|
+
const transformSelectId = useId();
|
|
49
57
|
const chain = edge.transformIds ?? [];
|
|
50
58
|
const transformId = chain[stepIndex];
|
|
51
59
|
|
|
@@ -91,115 +99,116 @@ export function ConvertNoteEditor({
|
|
|
91
99
|
data-testid="field-remap-convert-note"
|
|
92
100
|
aria-label="Convert note editor"
|
|
93
101
|
>
|
|
94
|
-
<
|
|
95
|
-
<
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
102
|
+
<WorkbenchPropertyStack gap="sm">
|
|
103
|
+
<WorkbenchPropertySection
|
|
104
|
+
title="Convert"
|
|
105
|
+
actions={
|
|
106
|
+
<div className="workbench-field-remap-convert-note__actions">
|
|
107
|
+
<Button
|
|
108
|
+
compact
|
|
109
|
+
type="button"
|
|
110
|
+
data-testid="field-remap-convert-note-back"
|
|
111
|
+
onClick={() => onSelectionChange({ kind: 'edge', edgeId: edge.id })}
|
|
112
|
+
>
|
|
113
|
+
Binding
|
|
114
|
+
</Button>
|
|
115
|
+
<Button
|
|
116
|
+
compact
|
|
117
|
+
type="button"
|
|
118
|
+
data-testid="field-remap-convert-note-clear"
|
|
119
|
+
onClick={() => onSelectionChange(null)}
|
|
120
|
+
>
|
|
121
|
+
Close
|
|
122
|
+
</Button>
|
|
123
|
+
</div>
|
|
124
|
+
}
|
|
125
|
+
>
|
|
126
|
+
<WorkbenchPropertyRow label="Transform">
|
|
127
|
+
<strong data-testid="field-remap-convert-note-title">{stepLabel}</strong>
|
|
128
|
+
</WorkbenchPropertyRow>
|
|
129
|
+
<WorkbenchPropertyRow label="Binding">
|
|
130
|
+
<code
|
|
131
|
+
className="workbench-field-remap-convert-note__binding"
|
|
132
|
+
data-testid="field-remap-convert-note-binding"
|
|
133
|
+
>
|
|
134
|
+
{edge.sourceFieldId} → {edge.targetSlotId}
|
|
135
|
+
</code>
|
|
136
|
+
</WorkbenchPropertyRow>
|
|
137
|
+
<WorkbenchPropertyHint className="workbench-field-remap-convert-note__muted">
|
|
105
138
|
Step {stepIndex + 1} of {chain.length} on this binding
|
|
106
|
-
</
|
|
107
|
-
</
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
139
|
+
</WorkbenchPropertyHint>
|
|
140
|
+
</WorkbenchPropertySection>
|
|
141
|
+
|
|
142
|
+
<WorkbenchPropertySection title="Transform" data-testid="field-remap-step-settings">
|
|
143
|
+
<WorkbenchPropertyRow htmlFor={transformSelectId} label="Registry id">
|
|
144
|
+
<Select
|
|
145
|
+
id={transformSelectId}
|
|
146
|
+
aria-label="Convert transform id"
|
|
147
|
+
controlWidth="full"
|
|
148
|
+
data-testid="field-remap-step-id"
|
|
149
|
+
value={transformId}
|
|
150
|
+
disabled={readOnly}
|
|
151
|
+
onValueChange={(nextTransformId) => {
|
|
152
|
+
applyEdge(
|
|
153
|
+
setTransformStepIdOnEdge(edge, stepIndex, nextTransformId, {
|
|
154
|
+
registry: transforms,
|
|
155
|
+
sourceType: portTypes.sourceType,
|
|
156
|
+
targetType: portTypes.targetType,
|
|
157
|
+
}),
|
|
158
|
+
);
|
|
159
|
+
}}
|
|
160
|
+
>
|
|
161
|
+
{!replaceCatalog.some((item) => item.id === transformId) ? (
|
|
162
|
+
<option value={transformId}>{transformId}</option>
|
|
163
|
+
) : null}
|
|
164
|
+
{replaceCatalog.map((item) => (
|
|
165
|
+
<option key={item.id} value={item.id}>
|
|
166
|
+
{item.label}
|
|
167
|
+
</option>
|
|
168
|
+
))}
|
|
169
|
+
</Select>
|
|
170
|
+
</WorkbenchPropertyRow>
|
|
171
|
+
</WorkbenchPropertySection>
|
|
127
172
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
>
|
|
133
|
-
<h5 id="field-remap-convert-note-registry">Transform</h5>
|
|
134
|
-
<label className="workbench-field-remap-convert-note__field">
|
|
135
|
-
<span>Registry id</span>
|
|
136
|
-
<select
|
|
137
|
-
aria-label="Convert transform id"
|
|
138
|
-
data-testid="field-remap-step-id"
|
|
139
|
-
value={transformId}
|
|
173
|
+
<WorkbenchPropertySection title="Options">
|
|
174
|
+
<TransformOptionsEditor
|
|
175
|
+
fields={optionFields}
|
|
176
|
+
value={optionValue}
|
|
140
177
|
disabled={readOnly}
|
|
141
|
-
onChange={(
|
|
142
|
-
applyEdge(
|
|
143
|
-
setTransformStepIdOnEdge(edge, stepIndex, event.target.value, {
|
|
144
|
-
registry: transforms,
|
|
145
|
-
sourceType: portTypes.sourceType,
|
|
146
|
-
targetType: portTypes.targetType,
|
|
147
|
-
}),
|
|
148
|
-
);
|
|
178
|
+
onChange={(nextOptions) => {
|
|
179
|
+
applyEdge(replaceTransformStepOptionsOnEdge(edge, stepIndex, nextOptions));
|
|
149
180
|
}}
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
<option value={transformId}>{transformId}</option>
|
|
153
|
-
) : null}
|
|
154
|
-
{replaceCatalog.map((item) => (
|
|
155
|
-
<option key={item.id} value={item.id}>
|
|
156
|
-
{item.label}
|
|
157
|
-
</option>
|
|
158
|
-
))}
|
|
159
|
-
</select>
|
|
160
|
-
</label>
|
|
161
|
-
</section>
|
|
181
|
+
/>
|
|
182
|
+
</WorkbenchPropertySection>
|
|
162
183
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
onSelectionChange({
|
|
192
|
-
kind: 'transformStep',
|
|
193
|
-
edgeId: edge.id,
|
|
194
|
-
stepIndex: Math.min(stepIndex, nextLen - 1),
|
|
195
|
-
});
|
|
196
|
-
}
|
|
197
|
-
}}
|
|
198
|
-
>
|
|
199
|
-
Remove convert
|
|
200
|
-
</Button>
|
|
201
|
-
</div>
|
|
202
|
-
) : null}
|
|
184
|
+
{!readOnly ? (
|
|
185
|
+
<WorkbenchPropertySection title="Actions">
|
|
186
|
+
<WorkbenchPropertyRow label="Convert step">
|
|
187
|
+
<Button
|
|
188
|
+
compact
|
|
189
|
+
type="button"
|
|
190
|
+
data-testid="field-remap-convert-note-remove"
|
|
191
|
+
onClick={() => {
|
|
192
|
+
const next = removeTransformStepFromEdge(edge, stepIndex);
|
|
193
|
+
applyEdge(next);
|
|
194
|
+
const nextLen = next.transformIds?.length ?? 0;
|
|
195
|
+
if (nextLen === 0) {
|
|
196
|
+
onSelectionChange({ kind: 'edge', edgeId: edge.id });
|
|
197
|
+
} else {
|
|
198
|
+
onSelectionChange({
|
|
199
|
+
kind: 'transformStep',
|
|
200
|
+
edgeId: edge.id,
|
|
201
|
+
stepIndex: Math.min(stepIndex, nextLen - 1),
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
}}
|
|
205
|
+
>
|
|
206
|
+
Remove convert
|
|
207
|
+
</Button>
|
|
208
|
+
</WorkbenchPropertyRow>
|
|
209
|
+
</WorkbenchPropertySection>
|
|
210
|
+
) : null}
|
|
211
|
+
</WorkbenchPropertyStack>
|
|
203
212
|
</aside>
|
|
204
213
|
);
|
|
205
214
|
}
|