@flowgram.ai/form-materials 0.2.27 → 0.2.29
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/bin/materials.ts +1 -1
- package/dist/esm/index.js +466 -218
- package/dist/esm/index.js.map +1 -1
- package/dist/index.d.mts +53 -15
- package/dist/index.d.ts +53 -15
- package/dist/index.js +475 -225
- package/dist/index.js.map +1 -1
- package/package.json +6 -5
- package/src/components/batch-outputs/config.json +2 -1
- package/src/components/batch-outputs/index.tsx +4 -12
- package/src/components/code-editor/config.json +2 -1
- package/src/components/code-editor/language-features.ts +3 -4
- package/src/components/constant-input/index.tsx +19 -2
- package/src/components/constant-input/types.ts +1 -0
- package/src/components/dynamic-value-input/index.tsx +58 -9
- package/src/components/dynamic-value-input/styles.tsx +28 -2
- package/src/components/index.ts +1 -0
- package/src/components/inputs-values/config.json +12 -0
- package/src/components/inputs-values/index.tsx +60 -0
- package/src/components/inputs-values/styles.tsx +19 -0
- package/src/components/inputs-values/types.ts +19 -0
- package/src/components/json-schema-editor/index.tsx +14 -1
- package/src/components/prompt-editor-with-inputs/inputs-picker.tsx +1 -1
- package/src/components/type-selector/index.tsx +15 -8
- package/src/components/variable-selector/index.tsx +30 -11
- package/src/components/variable-selector/styles.tsx +18 -8
- package/src/effects/index.ts +0 -1
- package/src/form-plugins/index.ts +2 -1
- package/src/form-plugins/infer-inputs-plugin/config.json +7 -0
- package/src/form-plugins/infer-inputs-plugin/index.ts +108 -0
- package/src/hooks/index.tsx +6 -0
- package/src/hooks/use-object-list/config.json +8 -0
- package/src/{components/batch-outputs/use-list.ts → hooks/use-object-list/index.tsx} +49 -12
- package/src/typings/flow-value/config.json +3 -1
- package/src/typings/flow-value/index.ts +3 -0
- package/src/effects/provide-batch-outputs/config.json +0 -5
- package/src/effects/provide-batch-outputs/index.ts +0 -38
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@flowgram.ai/form-materials",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.29",
|
|
4
4
|
"homepage": "https://flowgram.ai/",
|
|
5
5
|
"repository": "https://github.com/bytedance/flowgram.ai",
|
|
6
6
|
"license": "MIT",
|
|
@@ -33,7 +33,8 @@
|
|
|
33
33
|
"@coze-editor/editor": "0.1.0-alpha.879fbb",
|
|
34
34
|
"@codemirror/view": "~6.38.0",
|
|
35
35
|
"@codemirror/state": "~6.5.2",
|
|
36
|
-
"
|
|
36
|
+
"typescript": "^5.8.3",
|
|
37
|
+
"@flowgram.ai/editor": "0.2.29"
|
|
37
38
|
},
|
|
38
39
|
"devDependencies": {
|
|
39
40
|
"@types/lodash": "^4.14.137",
|
|
@@ -47,10 +48,10 @@
|
|
|
47
48
|
"react-dom": "^18",
|
|
48
49
|
"styled-components": "^5",
|
|
49
50
|
"tsup": "^8.0.1",
|
|
50
|
-
"typescript": "^5.
|
|
51
|
+
"typescript": "^5.8.3",
|
|
51
52
|
"vitest": "^0.34.6",
|
|
52
|
-
"@flowgram.ai/eslint-config": "0.2.
|
|
53
|
-
"@flowgram.ai/ts-config": "0.2.
|
|
53
|
+
"@flowgram.ai/eslint-config": "0.2.29",
|
|
54
|
+
"@flowgram.ai/ts-config": "0.2.29"
|
|
54
55
|
},
|
|
55
56
|
"peerDependencies": {
|
|
56
57
|
"react": ">=16.8",
|
|
@@ -8,15 +8,15 @@ import React from 'react';
|
|
|
8
8
|
import { Button, Input } from '@douyinfe/semi-ui';
|
|
9
9
|
import { IconDelete, IconPlus } from '@douyinfe/semi-icons';
|
|
10
10
|
|
|
11
|
-
import { useList } from './use-list';
|
|
12
11
|
import { PropsType } from './types';
|
|
13
12
|
import { VariableSelector } from '../variable-selector';
|
|
13
|
+
import { useObjectList } from '../../hooks';
|
|
14
14
|
import { UIRow, UIRows } from './styles';
|
|
15
15
|
|
|
16
16
|
export function BatchOutputs(props: PropsType) {
|
|
17
17
|
const { readonly, style } = props;
|
|
18
18
|
|
|
19
|
-
const { list, add,
|
|
19
|
+
const { list, add, updateKey, updateValue, remove } = useObjectList(props);
|
|
20
20
|
|
|
21
21
|
return (
|
|
22
22
|
<div>
|
|
@@ -28,21 +28,13 @@ export function BatchOutputs(props: PropsType) {
|
|
|
28
28
|
disabled={readonly}
|
|
29
29
|
size="small"
|
|
30
30
|
value={item.key}
|
|
31
|
-
onChange={(v) =>
|
|
31
|
+
onChange={(v) => updateKey(item.id, v)}
|
|
32
32
|
/>
|
|
33
33
|
<VariableSelector
|
|
34
34
|
style={{ flexGrow: 1 }}
|
|
35
35
|
readonly={readonly}
|
|
36
36
|
value={item.value?.content}
|
|
37
|
-
onChange={(v) =>
|
|
38
|
-
update({
|
|
39
|
-
...item,
|
|
40
|
-
value: {
|
|
41
|
-
type: 'ref',
|
|
42
|
-
content: v,
|
|
43
|
-
},
|
|
44
|
-
})
|
|
45
|
-
}
|
|
37
|
+
onChange={(v) => updateValue(item.id, { type: 'ref', content: v })}
|
|
46
38
|
/>
|
|
47
39
|
<Button
|
|
48
40
|
disabled={readonly}
|
|
@@ -4,14 +4,15 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import { languages } from '@coze-editor/editor/preset-code';
|
|
7
|
-
|
|
7
|
+
import { typescript } from '@coze-editor/editor/language-typescript';
|
|
8
8
|
import { shell } from '@coze-editor/editor/language-shell';
|
|
9
9
|
import { python } from '@coze-editor/editor/language-python';
|
|
10
10
|
import { json } from '@coze-editor/editor/language-json';
|
|
11
11
|
import { mixLanguages } from '@coze-editor/editor';
|
|
12
12
|
|
|
13
13
|
languages.register('python', python);
|
|
14
|
-
|
|
14
|
+
languages.register('typescript', typescript);
|
|
15
|
+
languages.register('shell', shell);
|
|
15
16
|
|
|
16
17
|
languages.register('json', {
|
|
17
18
|
// mixLanguages is used to solve the problem that interpolation also uses parentheses, which causes incorrect highlighting
|
|
@@ -20,5 +21,3 @@ languages.register('json', {
|
|
|
20
21
|
}),
|
|
21
22
|
languageService: json.languageService,
|
|
22
23
|
});
|
|
23
|
-
|
|
24
|
-
languages.register('shell', shell);
|
|
@@ -65,10 +65,19 @@ const defaultStrategies: Strategy[] = [
|
|
|
65
65
|
];
|
|
66
66
|
|
|
67
67
|
export function ConstantInput(props: PropsType) {
|
|
68
|
-
const {
|
|
68
|
+
const {
|
|
69
|
+
value,
|
|
70
|
+
onChange,
|
|
71
|
+
schema,
|
|
72
|
+
strategies: extraStrategies,
|
|
73
|
+
fallbackRenderer,
|
|
74
|
+
readonly,
|
|
75
|
+
...rest
|
|
76
|
+
} = props;
|
|
69
77
|
|
|
70
78
|
const strategies = useMemo(
|
|
71
|
-
|
|
79
|
+
// user's extraStrategies first
|
|
80
|
+
() => [...(extraStrategies || []), ...defaultStrategies],
|
|
72
81
|
[extraStrategies]
|
|
73
82
|
);
|
|
74
83
|
|
|
@@ -79,6 +88,14 @@ export function ConstantInput(props: PropsType) {
|
|
|
79
88
|
}, [strategies, schema]);
|
|
80
89
|
|
|
81
90
|
if (!Renderer) {
|
|
91
|
+
if (fallbackRenderer) {
|
|
92
|
+
return React.createElement(fallbackRenderer, {
|
|
93
|
+
value,
|
|
94
|
+
onChange,
|
|
95
|
+
readonly,
|
|
96
|
+
...rest,
|
|
97
|
+
});
|
|
98
|
+
}
|
|
82
99
|
return <Input size="small" disabled placeholder="Unsupported type" />;
|
|
83
100
|
}
|
|
84
101
|
|
|
@@ -3,16 +3,19 @@
|
|
|
3
3
|
* SPDX-License-Identifier: MIT
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import React, { useMemo } from 'react';
|
|
6
|
+
import React, { useMemo, useState } from 'react';
|
|
7
7
|
|
|
8
|
+
import { useScopeAvailable } from '@flowgram.ai/editor';
|
|
8
9
|
import { IconButton } from '@douyinfe/semi-ui';
|
|
9
10
|
import { IconSetting } from '@douyinfe/semi-icons';
|
|
10
11
|
|
|
11
12
|
import { Strategy } from '../constant-input/types';
|
|
12
13
|
import { ConstantInput } from '../constant-input';
|
|
14
|
+
import { JsonSchemaUtils } from '../../utils';
|
|
13
15
|
import { IFlowConstantRefValue } from '../../typings/flow-value';
|
|
14
|
-
import { UIContainer, UIMain, UITrigger } from './styles';
|
|
16
|
+
import { UIContainer, UIMain, UITrigger, UIType } from './styles';
|
|
15
17
|
import { VariableSelector } from '../variable-selector';
|
|
18
|
+
import { TypeSelector } from '../type-selector';
|
|
16
19
|
import { IJsonSchema } from '../../typings';
|
|
17
20
|
|
|
18
21
|
interface PropsType {
|
|
@@ -34,16 +37,50 @@ export function DynamicValueInput({
|
|
|
34
37
|
onChange,
|
|
35
38
|
readonly,
|
|
36
39
|
style,
|
|
37
|
-
schema,
|
|
40
|
+
schema: schemaFromProps,
|
|
38
41
|
constantProps,
|
|
39
42
|
}: PropsType) {
|
|
43
|
+
const available = useScopeAvailable();
|
|
44
|
+
const refVariable = useMemo(() => {
|
|
45
|
+
if (value?.type === 'ref') {
|
|
46
|
+
return available.getByKeyPath(value.content);
|
|
47
|
+
}
|
|
48
|
+
}, [value, available]);
|
|
49
|
+
|
|
50
|
+
const [selectSchema, setSelectSchema] = useState(
|
|
51
|
+
schemaFromProps || constantProps?.schema || { type: 'string' }
|
|
52
|
+
);
|
|
53
|
+
|
|
54
|
+
const renderTypeSelector = () => {
|
|
55
|
+
if (schemaFromProps) {
|
|
56
|
+
return <TypeSelector value={schemaFromProps} readonly={true} />;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (value?.type === 'ref') {
|
|
60
|
+
const schema = refVariable?.type ? JsonSchemaUtils.astToSchema(refVariable?.type) : undefined;
|
|
61
|
+
|
|
62
|
+
return <TypeSelector value={schema} readonly={true} />;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return (
|
|
66
|
+
<TypeSelector
|
|
67
|
+
value={selectSchema}
|
|
68
|
+
onChange={(_v) => setSelectSchema(_v || { type: 'string' })}
|
|
69
|
+
readonly={readonly}
|
|
70
|
+
/>
|
|
71
|
+
);
|
|
72
|
+
};
|
|
73
|
+
|
|
40
74
|
// When is number type, include integer as well
|
|
41
75
|
const includeSchema = useMemo(() => {
|
|
42
|
-
if (
|
|
43
|
-
return
|
|
76
|
+
if (!schemaFromProps) {
|
|
77
|
+
return;
|
|
44
78
|
}
|
|
45
|
-
|
|
46
|
-
|
|
79
|
+
if (schemaFromProps?.type === 'number') {
|
|
80
|
+
return [schemaFromProps, { type: 'integer' }];
|
|
81
|
+
}
|
|
82
|
+
return { ...schemaFromProps, extra: { ...schemaFromProps?.extra, weak: true } };
|
|
83
|
+
}, [schemaFromProps]);
|
|
47
84
|
|
|
48
85
|
const renderMain = () => {
|
|
49
86
|
if (value?.type === 'ref') {
|
|
@@ -59,12 +96,23 @@ export function DynamicValueInput({
|
|
|
59
96
|
);
|
|
60
97
|
}
|
|
61
98
|
|
|
99
|
+
const constantSchema = schemaFromProps || selectSchema || { type: 'string' };
|
|
100
|
+
|
|
62
101
|
return (
|
|
63
102
|
<ConstantInput
|
|
64
103
|
value={value?.content}
|
|
65
|
-
onChange={(_v) => onChange({ type: 'constant', content: _v })}
|
|
66
|
-
schema={
|
|
104
|
+
onChange={(_v) => onChange({ type: 'constant', content: _v, schema: constantSchema })}
|
|
105
|
+
schema={constantSchema || { type: 'string' }}
|
|
67
106
|
readonly={readonly}
|
|
107
|
+
strategies={[...(constantProps?.strategies || [])]}
|
|
108
|
+
fallbackRenderer={() => (
|
|
109
|
+
<VariableSelector
|
|
110
|
+
style={{ width: '100%' }}
|
|
111
|
+
onChange={(_v) => onChange(_v ? { type: 'ref', content: _v } : undefined)}
|
|
112
|
+
includeSchema={includeSchema}
|
|
113
|
+
readonly={readonly}
|
|
114
|
+
/>
|
|
115
|
+
)}
|
|
68
116
|
{...constantProps}
|
|
69
117
|
/>
|
|
70
118
|
);
|
|
@@ -85,6 +133,7 @@ export function DynamicValueInput({
|
|
|
85
133
|
|
|
86
134
|
return (
|
|
87
135
|
<UIContainer style={style}>
|
|
136
|
+
<UIType>{renderTypeSelector()}</UIType>
|
|
88
137
|
<UIMain>{renderMain()}</UIMain>
|
|
89
138
|
<UITrigger>{renderTrigger()}</UITrigger>
|
|
90
139
|
</UIContainer>
|
|
@@ -8,7 +8,12 @@ import styled from 'styled-components';
|
|
|
8
8
|
export const UIContainer = styled.div`
|
|
9
9
|
display: flex;
|
|
10
10
|
align-items: center;
|
|
11
|
-
|
|
11
|
+
border-radius: 4px;
|
|
12
|
+
border: 1px solid var(--semi-color-border);
|
|
13
|
+
|
|
14
|
+
overflow: hidden;
|
|
15
|
+
|
|
16
|
+
background-color: var(--semi-color-fill-0);
|
|
12
17
|
`;
|
|
13
18
|
|
|
14
19
|
export const UIMain = styled.div`
|
|
@@ -20,7 +25,28 @@ export const UIMain = styled.div`
|
|
|
20
25
|
& .semi-input-number,
|
|
21
26
|
& .semi-select {
|
|
22
27
|
width: 100%;
|
|
28
|
+
border: none;
|
|
29
|
+
border-radius: 0;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
& .semi-input-wrapper {
|
|
33
|
+
border: none;
|
|
34
|
+
border-radius: 0;
|
|
35
|
+
}
|
|
36
|
+
`;
|
|
37
|
+
|
|
38
|
+
export const UIType = styled.div`
|
|
39
|
+
border-right: 1px solid #e5e5e5;
|
|
40
|
+
|
|
41
|
+
& .semi-button {
|
|
42
|
+
border-radius: 0;
|
|
23
43
|
}
|
|
24
44
|
`;
|
|
25
45
|
|
|
26
|
-
export const UITrigger = styled.div
|
|
46
|
+
export const UITrigger = styled.div`
|
|
47
|
+
border-left: 1px solid #e5e5e5;
|
|
48
|
+
|
|
49
|
+
& .semi-button {
|
|
50
|
+
border-radius: 0;
|
|
51
|
+
}
|
|
52
|
+
`;
|
package/src/components/index.ts
CHANGED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
|
|
3
|
+
* SPDX-License-Identifier: MIT
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import React from 'react';
|
|
7
|
+
|
|
8
|
+
import { Button, IconButton, Input } from '@douyinfe/semi-ui';
|
|
9
|
+
import { IconDelete, IconPlus } from '@douyinfe/semi-icons';
|
|
10
|
+
|
|
11
|
+
import { PropsType } from './types';
|
|
12
|
+
import { DynamicValueInput } from '../dynamic-value-input';
|
|
13
|
+
import { IFlowConstantRefValue, IFlowValue } from '../../typings';
|
|
14
|
+
import { useObjectList } from '../../hooks';
|
|
15
|
+
import { UIRow, UIRows } from './styles';
|
|
16
|
+
|
|
17
|
+
export function InputsValues({ value, onChange, style, readonly, constantProps }: PropsType) {
|
|
18
|
+
const { list, updateKey, updateValue, remove, add } = useObjectList<IFlowValue | undefined>({
|
|
19
|
+
value,
|
|
20
|
+
onChange,
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
return (
|
|
24
|
+
<div>
|
|
25
|
+
<UIRows style={style}>
|
|
26
|
+
{list.map((item) => (
|
|
27
|
+
<UIRow key={item.id}>
|
|
28
|
+
<Input
|
|
29
|
+
style={{ width: 100, minWidth: 100, maxWidth: 100 }}
|
|
30
|
+
disabled={readonly}
|
|
31
|
+
size="small"
|
|
32
|
+
value={item.key}
|
|
33
|
+
onChange={(v) => updateKey(item.id, v)}
|
|
34
|
+
/>
|
|
35
|
+
<DynamicValueInput
|
|
36
|
+
style={{ flexGrow: 1 }}
|
|
37
|
+
readonly={readonly}
|
|
38
|
+
value={item.value as IFlowConstantRefValue}
|
|
39
|
+
onChange={(v) => updateValue(item.id, v)}
|
|
40
|
+
constantProps={{
|
|
41
|
+
...constantProps,
|
|
42
|
+
strategies: [...(constantProps?.strategies || [])],
|
|
43
|
+
}}
|
|
44
|
+
/>
|
|
45
|
+
<IconButton
|
|
46
|
+
disabled={readonly}
|
|
47
|
+
theme="borderless"
|
|
48
|
+
icon={<IconDelete size="small" />}
|
|
49
|
+
size="small"
|
|
50
|
+
onClick={() => remove(item.id)}
|
|
51
|
+
/>
|
|
52
|
+
</UIRow>
|
|
53
|
+
))}
|
|
54
|
+
</UIRows>
|
|
55
|
+
<Button disabled={readonly} icon={<IconPlus />} size="small" onClick={add}>
|
|
56
|
+
Add
|
|
57
|
+
</Button>
|
|
58
|
+
</div>
|
|
59
|
+
);
|
|
60
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
|
|
3
|
+
* SPDX-License-Identifier: MIT
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import styled from 'styled-components';
|
|
7
|
+
|
|
8
|
+
export const UIRows = styled.div`
|
|
9
|
+
display: flex;
|
|
10
|
+
flex-direction: column;
|
|
11
|
+
gap: 10px;
|
|
12
|
+
margin-bottom: 10px;
|
|
13
|
+
`;
|
|
14
|
+
|
|
15
|
+
export const UIRow = styled.div`
|
|
16
|
+
display: flex;
|
|
17
|
+
align-items: center;
|
|
18
|
+
gap: 5px;
|
|
19
|
+
`;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
|
|
3
|
+
* SPDX-License-Identifier: MIT
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { Strategy } from '../constant-input/types';
|
|
7
|
+
import { IFlowValue } from '../../typings';
|
|
8
|
+
|
|
9
|
+
export interface PropsType {
|
|
10
|
+
value?: Record<string, IFlowValue | undefined>;
|
|
11
|
+
onChange: (value?: Record<string, IFlowValue | undefined>) => void;
|
|
12
|
+
readonly?: boolean;
|
|
13
|
+
hasError?: boolean;
|
|
14
|
+
style?: React.CSSProperties;
|
|
15
|
+
constantProps?: {
|
|
16
|
+
strategies?: Strategy[];
|
|
17
|
+
[key: string]: any;
|
|
18
|
+
};
|
|
19
|
+
}
|
|
@@ -44,8 +44,9 @@ export function JsonSchemaEditor(props: {
|
|
|
44
44
|
onChange?: (value: IJsonSchema) => void;
|
|
45
45
|
config?: ConfigType;
|
|
46
46
|
className?: string;
|
|
47
|
+
readonly?: boolean;
|
|
47
48
|
}) {
|
|
48
|
-
const { value = { type: 'object' }, config = {}, onChange: onChangeProps } = props;
|
|
49
|
+
const { value = { type: 'object' }, config = {}, onChange: onChangeProps, readonly } = props;
|
|
49
50
|
const { propertyList, onAddProperty, onRemoveProperty, onEditProperty } = usePropertiesEdit(
|
|
50
51
|
value,
|
|
51
52
|
onChangeProps
|
|
@@ -56,6 +57,7 @@ export function JsonSchemaEditor(props: {
|
|
|
56
57
|
<UIProperties>
|
|
57
58
|
{propertyList.map((_property, index) => (
|
|
58
59
|
<PropertyEdit
|
|
60
|
+
readonly={readonly}
|
|
59
61
|
key={_property.key}
|
|
60
62
|
value={_property}
|
|
61
63
|
config={config}
|
|
@@ -70,6 +72,7 @@ export function JsonSchemaEditor(props: {
|
|
|
70
72
|
))}
|
|
71
73
|
</UIProperties>
|
|
72
74
|
<Button
|
|
75
|
+
disabled={readonly}
|
|
73
76
|
size="small"
|
|
74
77
|
style={{ marginTop: 10, marginLeft: 16 }}
|
|
75
78
|
icon={<IconPlus />}
|
|
@@ -86,6 +89,7 @@ function PropertyEdit(props: {
|
|
|
86
89
|
config?: ConfigType;
|
|
87
90
|
onChange?: (value: PropertyValueType) => void;
|
|
88
91
|
onRemove?: () => void;
|
|
92
|
+
readonly?: boolean;
|
|
89
93
|
$isLast?: boolean;
|
|
90
94
|
$index?: number;
|
|
91
95
|
$isFirst?: boolean;
|
|
@@ -97,6 +101,7 @@ function PropertyEdit(props: {
|
|
|
97
101
|
const {
|
|
98
102
|
value,
|
|
99
103
|
config,
|
|
104
|
+
readonly,
|
|
100
105
|
$level = 0,
|
|
101
106
|
onChange: onChangeProps,
|
|
102
107
|
onRemove,
|
|
@@ -155,6 +160,7 @@ function PropertyEdit(props: {
|
|
|
155
160
|
<UIRow>
|
|
156
161
|
<UIName>
|
|
157
162
|
<BlurInput
|
|
163
|
+
disabled={readonly}
|
|
158
164
|
placeholder={config?.placeholder ?? 'Input Variable Name'}
|
|
159
165
|
size="small"
|
|
160
166
|
value={name}
|
|
@@ -164,6 +170,7 @@ function PropertyEdit(props: {
|
|
|
164
170
|
<UIType>
|
|
165
171
|
<TypeSelector
|
|
166
172
|
value={typeSelectorValue}
|
|
173
|
+
readonly={readonly}
|
|
167
174
|
onChange={(_value) => {
|
|
168
175
|
onChangeProps?.({
|
|
169
176
|
...(value || {}),
|
|
@@ -174,12 +181,14 @@ function PropertyEdit(props: {
|
|
|
174
181
|
</UIType>
|
|
175
182
|
<UIRequired>
|
|
176
183
|
<Checkbox
|
|
184
|
+
disabled={readonly}
|
|
177
185
|
checked={isPropertyRequired}
|
|
178
186
|
onChange={(e) => onChange('isPropertyRequired', e.target.checked)}
|
|
179
187
|
/>
|
|
180
188
|
</UIRequired>
|
|
181
189
|
<UIActions>
|
|
182
190
|
<IconButton
|
|
191
|
+
disabled={readonly}
|
|
183
192
|
size="small"
|
|
184
193
|
theme="borderless"
|
|
185
194
|
icon={expand ? <IconShrink size="small" /> : <IconExpand size="small" />}
|
|
@@ -189,6 +198,7 @@ function PropertyEdit(props: {
|
|
|
189
198
|
/>
|
|
190
199
|
{isDrilldownObject && (
|
|
191
200
|
<IconButton
|
|
201
|
+
disabled={readonly}
|
|
192
202
|
size="small"
|
|
193
203
|
theme="borderless"
|
|
194
204
|
icon={<IconAddChildren />}
|
|
@@ -199,6 +209,7 @@ function PropertyEdit(props: {
|
|
|
199
209
|
/>
|
|
200
210
|
)}
|
|
201
211
|
<IconButton
|
|
212
|
+
disabled={readonly}
|
|
202
213
|
size="small"
|
|
203
214
|
theme="borderless"
|
|
204
215
|
icon={<IconMinus size="small" />}
|
|
@@ -210,6 +221,7 @@ function PropertyEdit(props: {
|
|
|
210
221
|
<UIExpandDetail>
|
|
211
222
|
<UILabel>{config?.descTitle ?? 'Description'}</UILabel>
|
|
212
223
|
<BlurInput
|
|
224
|
+
disabled={readonly}
|
|
213
225
|
size="small"
|
|
214
226
|
value={description}
|
|
215
227
|
onChange={(value) => onChange('description', value)}
|
|
@@ -240,6 +252,7 @@ function PropertyEdit(props: {
|
|
|
240
252
|
<UIProperties $shrink={true}>
|
|
241
253
|
{propertyList.map((_property, index) => (
|
|
242
254
|
<PropertyEdit
|
|
255
|
+
readonly={readonly}
|
|
243
256
|
key={_property.key}
|
|
244
257
|
value={_property}
|
|
245
258
|
config={config}
|
|
@@ -79,7 +79,7 @@ export function InputsPicker({
|
|
|
79
79
|
const treeData: TreeNodeData[] = useMemo(
|
|
80
80
|
() =>
|
|
81
81
|
Object.entries(inputsValues).map(([key, value]) => {
|
|
82
|
-
if (value
|
|
82
|
+
if (value?.type === 'ref') {
|
|
83
83
|
const variable = available.getByKeyPath(value.content || []);
|
|
84
84
|
|
|
85
85
|
if (variable) {
|
|
@@ -5,14 +5,18 @@
|
|
|
5
5
|
|
|
6
6
|
import React, { useMemo } from 'react';
|
|
7
7
|
|
|
8
|
-
import {
|
|
8
|
+
import { Cascader, IconButton } from '@douyinfe/semi-ui';
|
|
9
9
|
|
|
10
10
|
import { IJsonSchema } from '../../typings';
|
|
11
11
|
import { ArrayIcons, VariableTypeIcons, getSchemaIcon, options } from './constants';
|
|
12
12
|
|
|
13
13
|
interface PropTypes {
|
|
14
14
|
value?: Partial<IJsonSchema>;
|
|
15
|
-
onChange
|
|
15
|
+
onChange?: (value?: Partial<IJsonSchema>) => void;
|
|
16
|
+
readonly?: boolean;
|
|
17
|
+
/**
|
|
18
|
+
* @deprecated use readonly instead
|
|
19
|
+
*/
|
|
16
20
|
disabled?: boolean;
|
|
17
21
|
style?: React.CSSProperties;
|
|
18
22
|
}
|
|
@@ -36,24 +40,27 @@ export const parseTypeSelectValue = (value?: string[]): Partial<IJsonSchema> | u
|
|
|
36
40
|
};
|
|
37
41
|
|
|
38
42
|
export function TypeSelector(props: PropTypes) {
|
|
39
|
-
const { value, onChange, disabled, style } = props;
|
|
43
|
+
const { value, onChange, readonly, disabled, style } = props;
|
|
40
44
|
|
|
41
45
|
const selectValue = useMemo(() => getTypeSelectValue(value), [value]);
|
|
42
46
|
|
|
43
47
|
return (
|
|
44
48
|
<Cascader
|
|
45
|
-
disabled={disabled}
|
|
49
|
+
disabled={readonly || disabled}
|
|
46
50
|
size="small"
|
|
47
51
|
triggerRender={() => (
|
|
48
|
-
<
|
|
49
|
-
|
|
50
|
-
|
|
52
|
+
<IconButton
|
|
53
|
+
size="small"
|
|
54
|
+
style={style}
|
|
55
|
+
disabled={readonly || disabled}
|
|
56
|
+
icon={getSchemaIcon(value)}
|
|
57
|
+
/>
|
|
51
58
|
)}
|
|
52
59
|
treeData={options}
|
|
53
60
|
value={selectValue}
|
|
54
61
|
leafOnly={true}
|
|
55
62
|
onChange={(value) => {
|
|
56
|
-
onChange(parseTypeSelectValue(value as string[]));
|
|
63
|
+
onChange?.(parseTypeSelectValue(value as string[]));
|
|
57
64
|
}}
|
|
58
65
|
/>
|
|
59
66
|
);
|
|
@@ -7,11 +7,12 @@ import React, { useMemo } from 'react';
|
|
|
7
7
|
|
|
8
8
|
import { TriggerRenderProps } from '@douyinfe/semi-ui/lib/es/treeSelect';
|
|
9
9
|
import { TreeNodeData } from '@douyinfe/semi-ui/lib/es/tree';
|
|
10
|
+
import { Popover } from '@douyinfe/semi-ui';
|
|
10
11
|
import { IconChevronDownStroked, IconIssueStroked } from '@douyinfe/semi-icons';
|
|
11
12
|
|
|
12
13
|
import { IJsonSchema } from '../../typings/json-schema';
|
|
13
14
|
import { useVariableTree } from './use-variable-tree';
|
|
14
|
-
import { UIRootTitle, UITag, UITreeSelect, UIVarName } from './styles';
|
|
15
|
+
import { UIPopoverContent, UIRootTitle, UITag, UITreeSelect, UIVarName } from './styles';
|
|
15
16
|
|
|
16
17
|
interface PropTypes {
|
|
17
18
|
value?: string[];
|
|
@@ -93,17 +94,35 @@ export const VariableSelector = ({
|
|
|
93
94
|
);
|
|
94
95
|
}
|
|
95
96
|
|
|
97
|
+
const rootIcon = renderIcon(_option.rootMeta?.icon || _option?.icon);
|
|
98
|
+
|
|
99
|
+
const rootTitle = (
|
|
100
|
+
<UIRootTitle>
|
|
101
|
+
{_option.rootMeta?.title ? `${_option.rootMeta?.title} -` : null}
|
|
102
|
+
</UIRootTitle>
|
|
103
|
+
);
|
|
104
|
+
|
|
96
105
|
return (
|
|
97
|
-
<
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
106
|
+
<div>
|
|
107
|
+
<Popover
|
|
108
|
+
content={
|
|
109
|
+
<UIPopoverContent>
|
|
110
|
+
{rootIcon}
|
|
111
|
+
{rootTitle}
|
|
112
|
+
<UIVarName>{_option.keyPath.slice(1).join('.')}</UIVarName>
|
|
113
|
+
</UIPopoverContent>
|
|
114
|
+
}
|
|
115
|
+
>
|
|
116
|
+
<UITag
|
|
117
|
+
prefixIcon={rootIcon}
|
|
118
|
+
closable={!readonly}
|
|
119
|
+
onClose={() => onChange(undefined)}
|
|
120
|
+
>
|
|
121
|
+
{rootTitle}
|
|
122
|
+
<UIVarName $inSelector>{_option.label}</UIVarName>
|
|
123
|
+
</UITag>
|
|
124
|
+
</Popover>
|
|
125
|
+
</div>
|
|
107
126
|
);
|
|
108
127
|
}}
|
|
109
128
|
showClear={false}
|