@workbench-kit/shell-react 0.0.2-prototype.0.2.26 → 0.0.2-prototype.0.2.28
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 +18 -2
- package/package.json +10 -10
- package/src/chat/command-policy.ts +3 -17
- package/src/commands/use-command-descriptors.ts +2 -30
- package/src/commands/use-context-key-revision.ts +12 -12
- package/src/commands/use-extension-registry-command-descriptors.ts +46 -0
- package/src/devtools/use-workbench-devtools-snapshot.ts +1 -1
- package/src/editor/pane-visibility.ts +0 -23
- package/src/editor/view-providers.tsx +0 -7
- package/src/explorer/reveal.ts +1 -12
- package/src/extensions/builtin/commands/src/command-inspector-editor-host.ts +1 -19
- package/src/extensions/builtin/commands/src/index.ts +2 -2
- package/src/field-remap/convert-note-editor.tsx +2 -4
- package/src/field-remap/convert-palette.tsx +17 -20
- package/src/field-remap/flow-adapter.ts +21 -57
- package/src/field-remap/flow-ops.ts +0 -24
- package/src/field-remap/index.ts +0 -1
- package/src/field-remap/io-class-browse.tsx +29 -6
- package/src/field-remap/jsonata-transform.ts +9 -39
- package/src/field-remap/shape-io-editor.tsx +1 -1
- package/src/field-remap/transform-options-editor.tsx +1 -2
- package/src/field-remap/view.css +4 -29
- package/src/index.ts +1 -10
- package/src/jdw/widget-form-view.tsx +3 -20
- package/src/jdw/widget-preview-view.tsx +2 -20
- package/src/management/use-command-management.ts +22 -7
- package/src/management/use-keybinding-management.ts +1 -10
- package/src/shell/provider.tsx +19 -9
- package/src/shell/shell.tsx +11 -4
- package/src/workbench/command-host.tsx +46 -7
- package/src/workbench/command-palette.ts +12 -45
- package/src/workbench/workspace-view-state.ts +18 -1
- package/src/field-remap/graph.tsx +0 -559
- package/src/field-remap/table-mapping-adapter.ts +0 -59
- package/src/field-remap/tree.tsx +0 -404
package/README.md
CHANGED
|
@@ -17,6 +17,7 @@ Peer: React 19.
|
|
|
17
17
|
## Quick start
|
|
18
18
|
|
|
19
19
|
```tsx
|
|
20
|
+
import { AppIcon } from '@workbench-kit/react/primitives';
|
|
20
21
|
import { BUILTIN_WORKBENCH_EXTENSIONS } from '@workbench-kit/shell-react';
|
|
21
22
|
import { EditorArea } from '@workbench-kit/shell-react';
|
|
22
23
|
import { WorkbenchProvider } from '@workbench-kit/shell-react/provider';
|
|
@@ -25,7 +26,12 @@ import { WorkbenchShell } from '@workbench-kit/shell-react/shell';
|
|
|
25
26
|
export function App() {
|
|
26
27
|
return (
|
|
27
28
|
<WorkbenchProvider availableExtensions={BUILTIN_WORKBENCH_EXTENSIONS}>
|
|
28
|
-
<WorkbenchShell
|
|
29
|
+
<WorkbenchShell
|
|
30
|
+
appIcon={<AppIcon alt="" src="/app-icon.svg" />}
|
|
31
|
+
title="Workbench"
|
|
32
|
+
primarySidebar={<aside />}
|
|
33
|
+
editorArea={<EditorArea />}
|
|
34
|
+
/>
|
|
29
35
|
</WorkbenchProvider>
|
|
30
36
|
);
|
|
31
37
|
}
|
|
@@ -40,7 +46,9 @@ host wants the Kit editor, or omit it for a product-owned editor region.
|
|
|
40
46
|
|
|
41
47
|
Performance-sensitive hosts should import orchestration from the focused
|
|
42
48
|
`provider`, `host-shell`, `shell`, `command-host`, `command-palette`, and
|
|
43
|
-
`command-descriptors` subpaths.
|
|
49
|
+
`command-descriptors` subpaths. Hosts that already own the canonical extension
|
|
50
|
+
registry can use `registry-command-descriptors` without importing Provider
|
|
51
|
+
context into that leaf bundle. The root barrel remains the discovery surface,
|
|
44
52
|
not the default runtime import graph.
|
|
45
53
|
|
|
46
54
|
Use `host-shell` when the product owns sidebar, editor, panel, and overlay content.
|
|
@@ -53,6 +61,14 @@ layout-only chrome without host services, start from
|
|
|
53
61
|
`@workbench-kit/react/workbench/shell` — see
|
|
54
62
|
[Getting Started](../../docs/guides/getting-started.md).
|
|
55
63
|
|
|
64
|
+
## Host-owned branding
|
|
65
|
+
|
|
66
|
+
The default title bar does not embed a product mark. Pass the host-owned mark through
|
|
67
|
+
`appIcon`, omit it for a text-only identity, or replace the complete `titleBar` surface.
|
|
68
|
+
The shell wraps `appIcon` as decorative content, so interactive controls do not belong
|
|
69
|
+
in this slot. `AppIcon` from `@workbench-kit/react/primitives` is the optional sizing
|
|
70
|
+
and image-fit helper; it does not include fallback artwork.
|
|
71
|
+
|
|
56
72
|
## Field Remap embed (slim subpath)
|
|
57
73
|
|
|
58
74
|
Hosts that only need the Field Remap mapper UI can import the slim subpath instead
|
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.28",
|
|
4
4
|
"private": false,
|
|
5
5
|
"sideEffects": [
|
|
6
6
|
"**/*.css"
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
"exports": {
|
|
10
10
|
".": "./src/index.ts",
|
|
11
11
|
"./command-descriptors": "./src/commands/use-command-descriptors.ts",
|
|
12
|
+
"./registry-command-descriptors": "./src/commands/use-extension-registry-command-descriptors.ts",
|
|
12
13
|
"./command-host": "./src/workbench/command-host.tsx",
|
|
13
14
|
"./command-palette": "./src/workbench/command-palette.ts",
|
|
14
15
|
"./field-remap": "./src/field-remap/index.ts",
|
|
@@ -30,15 +31,14 @@
|
|
|
30
31
|
"@radix-ui/react-slot": "^1.3.0",
|
|
31
32
|
"@xyflow/react": "^12.11.2",
|
|
32
33
|
"jsonata": "^2.2.0",
|
|
33
|
-
"react
|
|
34
|
-
"@workbench-kit/
|
|
35
|
-
"@workbench-kit/
|
|
36
|
-
"@workbench-kit/workbench-config": "0.0.2-prototype.0.2.
|
|
37
|
-
"@workbench-kit/workbench-extension-sdk": "0.0.2-prototype.0.2.
|
|
38
|
-
"@workbench-kit/
|
|
39
|
-
"@workbench-kit/workspace": "0.0.2-prototype.0.2.
|
|
40
|
-
"@workbench-kit/
|
|
41
|
-
"@workbench-kit/react": "0.0.2-prototype.0.2.26"
|
|
34
|
+
"@workbench-kit/react": "0.0.2-prototype.0.2.28",
|
|
35
|
+
"@workbench-kit/tokens": "0.0.2-prototype.0.2.28",
|
|
36
|
+
"@workbench-kit/field-remap": "0.0.2-prototype.0.2.28",
|
|
37
|
+
"@workbench-kit/workbench-config": "0.0.2-prototype.0.2.28",
|
|
38
|
+
"@workbench-kit/workbench-extension-sdk": "0.0.2-prototype.0.2.28",
|
|
39
|
+
"@workbench-kit/platform": "0.0.2-prototype.0.2.28",
|
|
40
|
+
"@workbench-kit/workspace": "0.0.2-prototype.0.2.28",
|
|
41
|
+
"@workbench-kit/workbench-core": "0.0.2-prototype.0.2.28"
|
|
42
42
|
},
|
|
43
43
|
"peerDependencies": {
|
|
44
44
|
"react": "^19.0.0",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import {
|
|
2
|
+
isWorkbenchCommandExecutionPolicy,
|
|
3
|
+
type ResolveWorkbenchCommandExecutionPolicyInput,
|
|
4
4
|
} from '@workbench-kit/react/workbench';
|
|
5
5
|
import type { WorkbenchStorageReader } from '@workbench-kit/workbench-core';
|
|
6
6
|
|
|
@@ -8,12 +8,6 @@ import { readPersistedLocalPreferences } from '../management/preference-settings
|
|
|
8
8
|
|
|
9
9
|
export const WORKBENCH_AI_CHAT_COMMAND_DEFAULT_POLICY_KEY = 'workbench.chat.aiCommandDefaultPolicy';
|
|
10
10
|
|
|
11
|
-
function isWorkbenchCommandExecutionPolicy(
|
|
12
|
-
value: unknown,
|
|
13
|
-
): value is WorkbenchCommandExecutionPolicy {
|
|
14
|
-
return value === 'auto-allow' || value === 'approval-required' || value === 'auto-deny';
|
|
15
|
-
}
|
|
16
|
-
|
|
17
11
|
export function readWorkbenchAiChatCommandPolicyInput(
|
|
18
12
|
storageKey?: string,
|
|
19
13
|
storage?: WorkbenchStorageReader,
|
|
@@ -29,14 +23,6 @@ export function readWorkbenchAiChatCommandPolicyInput(
|
|
|
29
23
|
};
|
|
30
24
|
}
|
|
31
25
|
|
|
32
|
-
export function createWorkbenchAiChatCommandPolicyById(
|
|
33
|
-
entries: Readonly<Record<string, WorkbenchCommandExecutionPolicy>>,
|
|
34
|
-
): ResolveWorkbenchCommandExecutionPolicyInput {
|
|
35
|
-
return {
|
|
36
|
-
policyByCommandId: entries,
|
|
37
|
-
};
|
|
38
|
-
}
|
|
39
|
-
|
|
40
26
|
export function mergeWorkbenchAiChatCommandPolicyInput(
|
|
41
27
|
...inputs: readonly ResolveWorkbenchCommandExecutionPolicyInput[]
|
|
42
28
|
): ResolveWorkbenchCommandExecutionPolicyInput {
|
|
@@ -1,12 +1,7 @@
|
|
|
1
|
-
import { useEffect, useMemo, useReducer } from 'react';
|
|
2
1
|
import type { WorkbenchCommandDescriptor } from '@workbench-kit/react/workbench';
|
|
3
2
|
|
|
4
3
|
import { useWorkbench } from '../shell/provider.js';
|
|
5
|
-
import {
|
|
6
|
-
collectExtensionCommandFeaturesById,
|
|
7
|
-
extensionCommandToDescriptor,
|
|
8
|
-
mergeWorkbenchCommandDescriptors,
|
|
9
|
-
} from '../workbench/command-palette.js';
|
|
4
|
+
import { useExtensionRegistryCommandDescriptors } from './use-extension-registry-command-descriptors.js';
|
|
10
5
|
|
|
11
6
|
const EMPTY_COMMAND_DESCRIPTORS: readonly WorkbenchCommandDescriptor[] = [];
|
|
12
7
|
|
|
@@ -14,28 +9,5 @@ export function useWorkbenchCommandDescriptors(
|
|
|
14
9
|
additionalCommands: readonly WorkbenchCommandDescriptor[] = EMPTY_COMMAND_DESCRIPTORS,
|
|
15
10
|
) {
|
|
16
11
|
const { extensionRegistry } = useWorkbench();
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
useEffect(() => {
|
|
20
|
-
const disposable = extensionRegistry.commands.onDidRegisterCommand(() => {
|
|
21
|
-
refreshCommands();
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
return () => {
|
|
25
|
-
disposable.dispose();
|
|
26
|
-
};
|
|
27
|
-
}, [extensionRegistry.commands]);
|
|
28
|
-
|
|
29
|
-
return useMemo(() => {
|
|
30
|
-
const commandFeaturesById = collectExtensionCommandFeaturesById(extensionRegistry);
|
|
31
|
-
|
|
32
|
-
return mergeWorkbenchCommandDescriptors(
|
|
33
|
-
extensionRegistry.commands
|
|
34
|
-
.getCommands()
|
|
35
|
-
.map((command) =>
|
|
36
|
-
extensionCommandToDescriptor(command, commandFeaturesById.get(command.id)),
|
|
37
|
-
),
|
|
38
|
-
[...additionalCommands],
|
|
39
|
-
);
|
|
40
|
-
}, [additionalCommands, extensionRegistry, refreshToken]);
|
|
12
|
+
return useExtensionRegistryCommandDescriptors(extensionRegistry, additionalCommands);
|
|
41
13
|
}
|
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useCallback, useSyncExternalStore } from 'react';
|
|
2
2
|
import type { ContextKeyService } from '@workbench-kit/platform';
|
|
3
3
|
|
|
4
4
|
export function useContextKeyRevision(contextKeyService: ContextKeyService): number {
|
|
5
|
-
const
|
|
5
|
+
const subscribe = useCallback(
|
|
6
|
+
(onStoreChange: () => void) => {
|
|
7
|
+
const disposable = contextKeyService.onDidChangeContext(onStoreChange);
|
|
6
8
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
}
|
|
9
|
+
return () => {
|
|
10
|
+
disposable.dispose();
|
|
11
|
+
};
|
|
12
|
+
},
|
|
13
|
+
[contextKeyService],
|
|
14
|
+
);
|
|
15
|
+
const getSnapshot = useCallback(() => contextKeyService.getRevision(), [contextKeyService]);
|
|
11
16
|
|
|
12
|
-
|
|
13
|
-
disposable.dispose();
|
|
14
|
-
};
|
|
15
|
-
}, [contextKeyService]);
|
|
16
|
-
|
|
17
|
-
return revision;
|
|
17
|
+
return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
|
|
18
18
|
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { WorkbenchCommandDescriptor } from '@workbench-kit/react/workbench';
|
|
2
|
+
import type { ExtensionRegistry } from '@workbench-kit/workbench-core';
|
|
3
|
+
import { useEffect, useMemo, useReducer } from 'react';
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
collectExtensionCommandFeaturesById,
|
|
7
|
+
extensionCommandToDescriptor,
|
|
8
|
+
mergeWorkbenchCommandDescriptors,
|
|
9
|
+
} from '../workbench/command-palette.js';
|
|
10
|
+
|
|
11
|
+
const EMPTY_COMMAND_DESCRIPTORS: readonly WorkbenchCommandDescriptor[] = [];
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Resolves command descriptors from a host-owned registry without importing
|
|
15
|
+
* WorkbenchProvider. Use this leaf hook when the host already owns the
|
|
16
|
+
* canonical registry instance or when bundler context isolation matters.
|
|
17
|
+
*/
|
|
18
|
+
export function useExtensionRegistryCommandDescriptors(
|
|
19
|
+
extensionRegistry: ExtensionRegistry,
|
|
20
|
+
additionalCommands: readonly WorkbenchCommandDescriptor[] = EMPTY_COMMAND_DESCRIPTORS,
|
|
21
|
+
): readonly WorkbenchCommandDescriptor[] {
|
|
22
|
+
const [refreshToken, refreshCommands] = useReducer((count: number) => count + 1, 0);
|
|
23
|
+
|
|
24
|
+
useEffect(() => {
|
|
25
|
+
const disposable = extensionRegistry.commands.onDidChangeCommands(() => {
|
|
26
|
+
refreshCommands();
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
return () => {
|
|
30
|
+
disposable.dispose();
|
|
31
|
+
};
|
|
32
|
+
}, [extensionRegistry.commands]);
|
|
33
|
+
|
|
34
|
+
return useMemo(() => {
|
|
35
|
+
const commandFeaturesById = collectExtensionCommandFeaturesById(extensionRegistry);
|
|
36
|
+
|
|
37
|
+
return mergeWorkbenchCommandDescriptors(
|
|
38
|
+
extensionRegistry.commands
|
|
39
|
+
.getCommands()
|
|
40
|
+
.map((command) =>
|
|
41
|
+
extensionCommandToDescriptor(command, commandFeaturesById.get(command.id)),
|
|
42
|
+
),
|
|
43
|
+
[...additionalCommands],
|
|
44
|
+
);
|
|
45
|
+
}, [additionalCommands, extensionRegistry, refreshToken]);
|
|
46
|
+
}
|
|
@@ -35,7 +35,7 @@ export function useWorkbenchDevtoolsSnapshot(): WorkbenchDevtoolsSnapshot {
|
|
|
35
35
|
editorService.onDidChangeEditors(() => {
|
|
36
36
|
notifyChange(onStoreChange);
|
|
37
37
|
}),
|
|
38
|
-
extensionRegistry.commands.
|
|
38
|
+
extensionRegistry.commands.onDidChangeCommands(() => {
|
|
39
39
|
notifyChange(onStoreChange);
|
|
40
40
|
}),
|
|
41
41
|
extensionRegistry.menus.onDidRegisterMenuItem(() => {
|
|
@@ -71,29 +71,6 @@ export function countVisibleEditorPanes(visibility: EditorPaneVisibility): numbe
|
|
|
71
71
|
return Number(visibility.code) + Number(visibility.form) + Number(visibility.preview);
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
-
export function toggleEditorPaneVisibility(
|
|
75
|
-
visibility: EditorPaneVisibility,
|
|
76
|
-
pane: EditorPaneKind,
|
|
77
|
-
): EditorPaneVisibility {
|
|
78
|
-
const nextValue = !visibility[pane];
|
|
79
|
-
|
|
80
|
-
if (!nextValue && countVisibleEditorPanes(visibility) <= 1) {
|
|
81
|
-
return visibility;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
return {
|
|
85
|
-
...visibility,
|
|
86
|
-
[pane]: nextValue,
|
|
87
|
-
};
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
export function sanitizeEditorPaneVisibility(
|
|
91
|
-
visibility: EditorPaneVisibility,
|
|
92
|
-
options: { formEligible: boolean; previewEligible: boolean },
|
|
93
|
-
): EditorPaneVisibility {
|
|
94
|
-
return resolveEffectiveEditorPaneVisibility(visibility, options);
|
|
95
|
-
}
|
|
96
|
-
|
|
97
74
|
export function resolveEffectiveEditorPaneVisibility(
|
|
98
75
|
preference: EditorPaneVisibility,
|
|
99
76
|
options: { formEligible: boolean; previewEligible: boolean },
|
|
@@ -38,13 +38,6 @@ export interface ResolvedEditorDocumentViews {
|
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
export const JSON_FORM_PROVIDER_ID = 'workbench-kit.editor.form.json' as const;
|
|
41
|
-
/** @deprecated Prefer `workbench-kit.samples.jdw.widget-form` from samples.jdw. */
|
|
42
|
-
export const JDW_WIDGET_FORM_PROVIDER_ID = 'workbench-kit.samples.jdw.widget-form' as const;
|
|
43
|
-
/** @deprecated Prefer `workbench-kit.samples.jdw.widget-preview` from samples.jdw. */
|
|
44
|
-
export const JDW_PREVIEW_PROVIDER_ID = 'workbench-kit.samples.jdw.widget-preview' as const;
|
|
45
|
-
/** @deprecated Prefer `workbench-kit.builtin.editor.markdown-preview` from builtin.editor. */
|
|
46
|
-
export const MARKDOWN_PREVIEW_PROVIDER_ID =
|
|
47
|
-
'workbench-kit.builtin.editor.markdown-preview' as const;
|
|
48
41
|
|
|
49
42
|
/**
|
|
50
43
|
* Opt-in shallow top-level JSON object form.
|
package/src/explorer/reveal.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { workspaceExplorerParentPaths } from '@workbench-kit/react/workbench/workspace';
|
|
1
2
|
import type { WorkspaceSelectionState } from '@workbench-kit/workspace';
|
|
2
3
|
|
|
3
4
|
import {
|
|
@@ -69,18 +70,6 @@ export function applyExplorerPathReveal(
|
|
|
69
70
|
});
|
|
70
71
|
}
|
|
71
72
|
|
|
72
|
-
function workspaceExplorerParentPaths(path: string): string[] {
|
|
73
|
-
const segments = path.split('/').filter(Boolean);
|
|
74
|
-
return segments.slice(0, -1).map((_, index) => segments.slice(0, index + 1).join('/'));
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
export function isExplorerHostCommand(commandId: string): boolean {
|
|
78
|
-
return (
|
|
79
|
-
commandId === BUILTIN_EXPLORER_REVEAL_COMMAND_ID ||
|
|
80
|
-
commandId === BUILTIN_EXPLORER_FOCUS_COMMAND_ID
|
|
81
|
-
);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
73
|
export async function runExplorerHostCommandSideEffects(
|
|
85
74
|
commandId: string,
|
|
86
75
|
args: readonly unknown[],
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
+
import { parseCommandInspectorUri } from '@workbench-kit/react/workbench/management';
|
|
1
2
|
import type { EditorHost } from '@workbench-kit/workbench-extension-sdk';
|
|
2
3
|
|
|
3
|
-
const COMMAND_INSPECTOR_URI_PREFIX = 'workbench://command/inspect/' as const;
|
|
4
|
-
|
|
5
4
|
export const COMMAND_INSPECTOR_EDITOR_ID = 'workbench-kit.builtin.commands.inspector' as const;
|
|
6
5
|
export const COMMAND_INSPECTOR_EDITOR_HOST_RENDER_KIND =
|
|
7
6
|
'workbench-kit.builtin.commands/inspector' as const;
|
|
@@ -46,23 +45,6 @@ export class CommandInspectorEditorHost implements EditorHost {
|
|
|
46
45
|
}
|
|
47
46
|
}
|
|
48
47
|
|
|
49
|
-
export function parseCommandInspectorUri(resourceUri: string): string | undefined {
|
|
50
|
-
if (!resourceUri.startsWith(COMMAND_INSPECTOR_URI_PREFIX)) {
|
|
51
|
-
return undefined;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
const encodedId = resourceUri.slice(COMMAND_INSPECTOR_URI_PREFIX.length);
|
|
55
|
-
if (!encodedId) {
|
|
56
|
-
return undefined;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
try {
|
|
60
|
-
return decodeURIComponent(encodedId);
|
|
61
|
-
} catch {
|
|
62
|
-
return undefined;
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
|
|
66
48
|
export function isCommandInspectorEditorHostRenderData(
|
|
67
49
|
value: unknown,
|
|
68
50
|
): value is CommandInspectorEditorHostRenderData {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
+
import { parseCommandInspectorUri } from '@workbench-kit/react/workbench/management';
|
|
1
2
|
import type { ExtensionContext } from '@workbench-kit/workbench-extension-sdk';
|
|
2
3
|
|
|
3
4
|
import {
|
|
4
5
|
COMMAND_INSPECTOR_EDITOR_ID,
|
|
5
6
|
CommandInspectorEditorHost,
|
|
6
|
-
parseCommandInspectorUri,
|
|
7
7
|
} from './command-inspector-editor-host.js';
|
|
8
8
|
|
|
9
9
|
export const EXTENSION_ID = 'workbench-kit.builtin.commands' as const;
|
|
@@ -21,9 +21,9 @@ export {
|
|
|
21
21
|
COMMAND_INSPECTOR_EDITOR_ID,
|
|
22
22
|
CommandInspectorEditorHost,
|
|
23
23
|
isCommandInspectorEditorHostRenderData,
|
|
24
|
-
parseCommandInspectorUri,
|
|
25
24
|
type CommandInspectorEditorHostRenderData,
|
|
26
25
|
} from './command-inspector-editor-host.js';
|
|
26
|
+
export { parseCommandInspectorUri };
|
|
27
27
|
|
|
28
28
|
export function activate(context: ExtensionContext): void {
|
|
29
29
|
context.editorResolvers.registerResolver({
|
|
@@ -57,10 +57,8 @@ export function ConvertNoteEditor({
|
|
|
57
57
|
if (!transformId) {
|
|
58
58
|
return {};
|
|
59
59
|
}
|
|
60
|
-
return (
|
|
61
|
-
|
|
62
|
-
);
|
|
63
|
-
}, [chain, edge.transformOptionSteps, edge.transformOptions, stepIndex, transformId]);
|
|
60
|
+
return resolveOptionSteps(chain, edge.transformOptionSteps)[stepIndex] ?? {};
|
|
61
|
+
}, [chain, edge.transformOptionSteps, stepIndex, transformId]);
|
|
64
62
|
|
|
65
63
|
const replaceCatalog = listCompatibleTransforms({
|
|
66
64
|
registry: transforms,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { JSX } from 'react';
|
|
2
|
+
import { SideBarList, SideBarListItem } from '@workbench-kit/react/layout';
|
|
2
3
|
import { Button } from '@workbench-kit/react/primitives';
|
|
3
4
|
import type { ValueTransformRegistry } from '@workbench-kit/field-remap';
|
|
4
5
|
|
|
@@ -59,7 +60,7 @@ export function FieldRemapConvertPalette({
|
|
|
59
60
|
</Button>
|
|
60
61
|
</div>
|
|
61
62
|
|
|
62
|
-
<
|
|
63
|
+
<SideBarList
|
|
63
64
|
className="workbench-field-remap-convert-palette__list"
|
|
64
65
|
role="listbox"
|
|
65
66
|
aria-label={chromeLabels.convertsListAriaLabel}
|
|
@@ -67,27 +68,23 @@ export function FieldRemapConvertPalette({
|
|
|
67
68
|
{catalog.map((definition) => {
|
|
68
69
|
const selected = definition.id === selectedTransformId;
|
|
69
70
|
return (
|
|
70
|
-
<
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
<strong>{definition.label}</strong>
|
|
85
|
-
<code>{definition.id}</code>
|
|
86
|
-
</button>
|
|
87
|
-
</li>
|
|
71
|
+
<SideBarListItem
|
|
72
|
+
key={definition.id}
|
|
73
|
+
aria-selected={selected}
|
|
74
|
+
data-testid={`field-remap-palette-item-${definition.id}`}
|
|
75
|
+
role="option"
|
|
76
|
+
selected={selected}
|
|
77
|
+
variant="stacked"
|
|
78
|
+
wrapperProps={{ role: 'presentation' }}
|
|
79
|
+
onClick={() => onSelectedTransformIdChange(definition.id)}
|
|
80
|
+
onDoubleClick={() => onPlaceDraft(definition.id)}
|
|
81
|
+
>
|
|
82
|
+
<strong>{definition.label}</strong>
|
|
83
|
+
<code title={definition.id}>{definition.id}</code>
|
|
84
|
+
</SideBarListItem>
|
|
88
85
|
);
|
|
89
86
|
})}
|
|
90
|
-
</
|
|
87
|
+
</SideBarList>
|
|
91
88
|
|
|
92
89
|
{onAddCombine || onAddSplit ? (
|
|
93
90
|
<div
|
|
@@ -14,14 +14,6 @@ import {
|
|
|
14
14
|
type ValueTransformRegistry,
|
|
15
15
|
} from '@workbench-kit/field-remap';
|
|
16
16
|
|
|
17
|
-
export type FieldRemapFlowNodeKind =
|
|
18
|
-
| 'source-object'
|
|
19
|
-
| 'target-object'
|
|
20
|
-
| 'transform'
|
|
21
|
-
| 'draft-transform'
|
|
22
|
-
| 'combine-operator'
|
|
23
|
-
| 'split-operator';
|
|
24
|
-
|
|
25
17
|
export type FieldRemapPort = {
|
|
26
18
|
fieldId: string;
|
|
27
19
|
label: string;
|
|
@@ -106,14 +98,6 @@ const TRANSFORM_X = 320;
|
|
|
106
98
|
const TARGET_X = 620;
|
|
107
99
|
const TRANSFORM_ROW_GAP = 72;
|
|
108
100
|
|
|
109
|
-
export function sourceObjectNodeId(): string {
|
|
110
|
-
return SOURCE_OBJECT_NODE_ID;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
export function targetObjectNodeId(): string {
|
|
114
|
-
return TARGET_OBJECT_NODE_ID;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
101
|
/** Handle id for a field/slot port on an object node. */
|
|
118
102
|
export function portHandleId(fieldOrSlotId: string): string {
|
|
119
103
|
return fieldOrSlotId;
|
|
@@ -478,28 +462,21 @@ function resolveConnectionPortIds(connection: {
|
|
|
478
462
|
return {};
|
|
479
463
|
}
|
|
480
464
|
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
targetSlotId = connection.targetHandle;
|
|
492
|
-
} else if (target.startsWith('tgt:')) {
|
|
493
|
-
targetSlotId = target.slice('tgt:'.length);
|
|
494
|
-
}
|
|
495
|
-
|
|
496
|
-
return { sourceFieldId, targetSlotId };
|
|
465
|
+
return {
|
|
466
|
+
sourceFieldId:
|
|
467
|
+
source === SOURCE_OBJECT_NODE_ID && connection.sourceHandle
|
|
468
|
+
? connection.sourceHandle
|
|
469
|
+
: undefined,
|
|
470
|
+
targetSlotId:
|
|
471
|
+
target === TARGET_OBJECT_NODE_ID && connection.targetHandle
|
|
472
|
+
? connection.targetHandle
|
|
473
|
+
: undefined,
|
|
474
|
+
};
|
|
497
475
|
}
|
|
498
476
|
|
|
499
477
|
/**
|
|
500
478
|
* Supported connect matrix for state-changing canvas drags:
|
|
501
479
|
* - source-object port → target-object port (creates / replaces a `MappingEdge`)
|
|
502
|
-
* - legacy `src:*` → `tgt:*` single-field node ids (tests / older graphs)
|
|
503
480
|
* - source-object port → `draft:*` (bind draft input)
|
|
504
481
|
* - `draft:*` → target-object port (bind draft output; finalize when both ends set)
|
|
505
482
|
* - source-object port → `xf:*` `in` (rebind source; splice off earlier steps)
|
|
@@ -656,13 +633,10 @@ export function isValidFieldRemapFlowConnection(
|
|
|
656
633
|
});
|
|
657
634
|
}
|
|
658
635
|
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
// Legacy single-field node ids (older graphs / tests).
|
|
664
|
-
topologyOk = true;
|
|
665
|
-
}
|
|
636
|
+
const topologyOk =
|
|
637
|
+
source === SOURCE_OBJECT_NODE_ID &&
|
|
638
|
+
target === TARGET_OBJECT_NODE_ID &&
|
|
639
|
+
Boolean(connection.sourceHandle && connection.targetHandle);
|
|
666
640
|
|
|
667
641
|
if (!topologyOk) {
|
|
668
642
|
return false;
|
|
@@ -696,7 +670,7 @@ export type FieldRemapFlowConnectResult = {
|
|
|
696
670
|
readonly removeEdgeIds?: readonly string[];
|
|
697
671
|
};
|
|
698
672
|
|
|
699
|
-
/** Parse React Flow
|
|
673
|
+
/** Parse a React Flow object-port connection into a kit MappingEdge. */
|
|
700
674
|
export function connectionToMappingEdge(input: {
|
|
701
675
|
readonly sourceNodeId: string;
|
|
702
676
|
readonly targetNodeId: string;
|
|
@@ -704,21 +678,12 @@ export function connectionToMappingEdge(input: {
|
|
|
704
678
|
readonly targetHandle?: string | null;
|
|
705
679
|
readonly existing: readonly MappingEdge[];
|
|
706
680
|
}): MappingEdge | null {
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
}
|
|
713
|
-
// Legacy single-field node ids (older graphs / tests).
|
|
714
|
-
sourceFieldId = input.sourceNodeId.slice('src:'.length);
|
|
715
|
-
}
|
|
716
|
-
|
|
717
|
-
if (input.targetNodeId === TARGET_OBJECT_NODE_ID && input.targetHandle) {
|
|
718
|
-
targetSlotId = input.targetHandle;
|
|
719
|
-
} else if (input.targetNodeId.startsWith('tgt:')) {
|
|
720
|
-
targetSlotId = input.targetNodeId.slice('tgt:'.length);
|
|
721
|
-
}
|
|
681
|
+
const { sourceFieldId, targetSlotId } = resolveConnectionPortIds({
|
|
682
|
+
source: input.sourceNodeId,
|
|
683
|
+
target: input.targetNodeId,
|
|
684
|
+
sourceHandle: input.sourceHandle,
|
|
685
|
+
targetHandle: input.targetHandle,
|
|
686
|
+
});
|
|
722
687
|
|
|
723
688
|
if (!sourceFieldId || !targetSlotId) {
|
|
724
689
|
return null;
|
|
@@ -827,7 +792,6 @@ export function applyFieldRemapFlowConnection(input: {
|
|
|
827
792
|
itemEdges: undefined,
|
|
828
793
|
itemTransformIds: undefined,
|
|
829
794
|
itemTransformOptionSteps: undefined,
|
|
830
|
-
itemTransformOptions: undefined,
|
|
831
795
|
},
|
|
832
796
|
removeEdgeIds: [edgeA.id],
|
|
833
797
|
};
|
|
@@ -7,7 +7,6 @@ import {
|
|
|
7
7
|
findTargetSlot,
|
|
8
8
|
isTransformChainCompatible,
|
|
9
9
|
optionFieldsForStep,
|
|
10
|
-
patchOptionStep,
|
|
11
10
|
resizeOptionSteps,
|
|
12
11
|
sanitizeOptionRecord,
|
|
13
12
|
type CombineMappingOperator,
|
|
@@ -214,29 +213,6 @@ export function removeTransformStepFromEdge(edge: MappingEdge, stepIndex: number
|
|
|
214
213
|
};
|
|
215
214
|
}
|
|
216
215
|
|
|
217
|
-
export function patchTransformStepOptionOnEdge(
|
|
218
|
-
edge: MappingEdge,
|
|
219
|
-
stepIndex: number,
|
|
220
|
-
key: string,
|
|
221
|
-
value: unknown,
|
|
222
|
-
): MappingEdge {
|
|
223
|
-
const length = edge.transformIds?.length ?? 0;
|
|
224
|
-
if (stepIndex < 0 || stepIndex >= length) {
|
|
225
|
-
return edge;
|
|
226
|
-
}
|
|
227
|
-
return {
|
|
228
|
-
...edge,
|
|
229
|
-
transformOptionSteps: patchOptionStep(
|
|
230
|
-
edge.transformOptionSteps,
|
|
231
|
-
length,
|
|
232
|
-
stepIndex,
|
|
233
|
-
key,
|
|
234
|
-
value,
|
|
235
|
-
edge.transformOptions,
|
|
236
|
-
),
|
|
237
|
-
};
|
|
238
|
-
}
|
|
239
|
-
|
|
240
216
|
export function replaceTransformStepOptionsOnEdge(
|
|
241
217
|
edge: MappingEdge,
|
|
242
218
|
stepIndex: number,
|
package/src/field-remap/index.ts
CHANGED