@flowgram.ai/form-materials 0.4.1 → 0.4.3
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/esm/index.js +198 -87
- package/dist/esm/index.js.map +1 -1
- package/dist/index.d.mts +29 -4
- package/dist/index.d.ts +29 -4
- package/dist/index.js +249 -139
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
- package/src/components/display-flow-value/index.tsx +2 -12
- package/src/components/display-inputs-values/index.tsx +44 -6
- package/src/components/dynamic-value-input/hooks.ts +23 -2
- package/src/components/dynamic-value-input/index.tsx +21 -12
- package/src/components/inputs-values/index.tsx +12 -1
- package/src/components/inputs-values-tree/hooks/use-child-list.tsx +8 -3
- package/src/components/inputs-values-tree/index.tsx +7 -1
- package/src/components/inputs-values-tree/row.tsx +23 -9
- package/src/components/json-editor-with-variables/extensions/variable-tag.tsx +1 -1
- package/src/components/prompt-editor-with-inputs/extensions/inputs-tree.tsx +11 -0
- package/src/components/prompt-editor-with-inputs/index.tsx +1 -2
- package/src/components/prompt-editor-with-inputs/inputs-picker.tsx +34 -17
- package/src/components/prompt-editor-with-variables/extensions/variable-tag.tsx +1 -1
- package/src/components/prompt-editor-with-variables/extensions/variable-tree.tsx +13 -1
- package/src/components/type-selector/index.tsx +12 -2
- package/src/index.ts +1 -0
- package/src/shared/flow-value/schema.ts +1 -1
- package/src/shared/flow-value/utils.ts +1 -1
- package/src/typings/flow-value/index.ts +1 -1
- package/src/validate/validate-flow-value/index.tsx +4 -16
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@flowgram.ai/form-materials",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.3",
|
|
4
4
|
"homepage": "https://flowgram.ai/",
|
|
5
5
|
"repository": "https://github.com/bytedance/flowgram.ai",
|
|
6
6
|
"license": "MIT",
|
|
@@ -35,8 +35,8 @@
|
|
|
35
35
|
"@codemirror/state": "~6.5.2",
|
|
36
36
|
"typescript": "^5.8.3",
|
|
37
37
|
"zod": "^3.24.4",
|
|
38
|
-
"@flowgram.ai/editor": "0.4.
|
|
39
|
-
"@flowgram.ai/json-schema": "0.4.
|
|
38
|
+
"@flowgram.ai/editor": "0.4.3",
|
|
39
|
+
"@flowgram.ai/json-schema": "0.4.3"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
42
|
"@types/lodash": "^4.14.137",
|
|
@@ -52,8 +52,8 @@
|
|
|
52
52
|
"tsup": "^8.0.1",
|
|
53
53
|
"typescript": "^5.8.3",
|
|
54
54
|
"vitest": "^0.34.6",
|
|
55
|
-
"@flowgram.ai/eslint-config": "0.4.
|
|
56
|
-
"@flowgram.ai/ts-config": "0.4.
|
|
55
|
+
"@flowgram.ai/eslint-config": "0.4.3",
|
|
56
|
+
"@flowgram.ai/ts-config": "0.4.3"
|
|
57
57
|
},
|
|
58
58
|
"peerDependencies": {
|
|
59
59
|
"react": ">=16.8",
|
|
@@ -9,6 +9,7 @@ import { JsonSchemaTypeManager, JsonSchemaUtils } from '@flowgram.ai/json-schema
|
|
|
9
9
|
import { useScopeAvailable } from '@flowgram.ai/editor';
|
|
10
10
|
|
|
11
11
|
import { IFlowValue } from '@/typings';
|
|
12
|
+
import { FlowValueUtils } from '@/shared';
|
|
12
13
|
import { DisplaySchemaTag } from '@/components/display-schema-tag';
|
|
13
14
|
|
|
14
15
|
interface PropsType {
|
|
@@ -31,18 +32,7 @@ export function DisplayFlowValue({ value, title, showIconInTree }: PropsType) {
|
|
|
31
32
|
return { type: 'string' };
|
|
32
33
|
}
|
|
33
34
|
if (value?.type === 'constant') {
|
|
34
|
-
|
|
35
|
-
return value?.schema;
|
|
36
|
-
}
|
|
37
|
-
if (typeof value?.content === 'string') {
|
|
38
|
-
return { type: 'string' };
|
|
39
|
-
}
|
|
40
|
-
if (typeof value?.content === 'number') {
|
|
41
|
-
return { type: 'number' };
|
|
42
|
-
}
|
|
43
|
-
if (typeof value?.content === 'boolean') {
|
|
44
|
-
return { type: 'boolean' };
|
|
45
|
-
}
|
|
35
|
+
return FlowValueUtils.inferConstantJsonSchema(value);
|
|
46
36
|
}
|
|
47
37
|
|
|
48
38
|
return { type: 'unknown' };
|
|
@@ -3,15 +3,19 @@
|
|
|
3
3
|
* SPDX-License-Identifier: MIT
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import React from 'react';
|
|
6
|
+
import React, { useMemo } from 'react';
|
|
7
7
|
|
|
8
|
-
import {
|
|
8
|
+
import { isPlainObject } from 'lodash';
|
|
9
|
+
import { useScopeAvailable } from '@flowgram.ai/editor';
|
|
10
|
+
|
|
11
|
+
import { FlowValueUtils } from '@/shared';
|
|
9
12
|
import { DisplayFlowValue } from '@/components/display-flow-value';
|
|
10
13
|
|
|
11
14
|
import { DisplayInputsWrapper } from './styles';
|
|
15
|
+
import { DisplaySchemaTag } from '../display-schema-tag';
|
|
12
16
|
|
|
13
17
|
interface PropsType {
|
|
14
|
-
value?:
|
|
18
|
+
value?: any;
|
|
15
19
|
showIconInTree?: boolean;
|
|
16
20
|
}
|
|
17
21
|
|
|
@@ -20,9 +24,43 @@ export function DisplayInputsValues({ value, showIconInTree }: PropsType) {
|
|
|
20
24
|
|
|
21
25
|
return (
|
|
22
26
|
<DisplayInputsWrapper>
|
|
23
|
-
{childEntries.map(([key, value]) =>
|
|
24
|
-
|
|
25
|
-
|
|
27
|
+
{childEntries.map(([key, value]) => {
|
|
28
|
+
if (FlowValueUtils.isFlowValue(value)) {
|
|
29
|
+
return (
|
|
30
|
+
<DisplayFlowValue key={key} title={key} value={value} showIconInTree={showIconInTree} />
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (isPlainObject(value)) {
|
|
35
|
+
return (
|
|
36
|
+
<DisplayInputsValueAllInTag
|
|
37
|
+
key={key}
|
|
38
|
+
title={key}
|
|
39
|
+
value={value}
|
|
40
|
+
showIconInTree={showIconInTree}
|
|
41
|
+
/>
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return null;
|
|
46
|
+
})}
|
|
26
47
|
</DisplayInputsWrapper>
|
|
27
48
|
);
|
|
28
49
|
}
|
|
50
|
+
|
|
51
|
+
export function DisplayInputsValueAllInTag({
|
|
52
|
+
value,
|
|
53
|
+
title,
|
|
54
|
+
showIconInTree,
|
|
55
|
+
}: PropsType & {
|
|
56
|
+
title: string;
|
|
57
|
+
}) {
|
|
58
|
+
const available = useScopeAvailable();
|
|
59
|
+
|
|
60
|
+
const schema = useMemo(
|
|
61
|
+
() => FlowValueUtils.inferJsonSchema(value, available.scope),
|
|
62
|
+
[available.version, value]
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
return <DisplaySchemaTag title={title} value={schema} showIconInTree={showIconInTree} />;
|
|
66
|
+
}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* SPDX-License-Identifier: MIT
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import { useMemo, useState } from 'react';
|
|
6
|
+
import { useEffect, useMemo, useRef, useState } from 'react';
|
|
7
7
|
|
|
8
8
|
import { IJsonSchema } from '@flowgram.ai/json-schema';
|
|
9
9
|
import { useScopeAvailable } from '@flowgram.ai/editor';
|
|
@@ -33,9 +33,30 @@ export function useSelectSchema(
|
|
|
33
33
|
defaultSelectSchema = value?.schema || defaultSelectSchema;
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
+
const changeVersion = useRef(0);
|
|
37
|
+
const effectVersion = useRef(0);
|
|
38
|
+
|
|
36
39
|
const [selectSchema, setSelectSchema] = useState(defaultSelectSchema);
|
|
37
40
|
|
|
38
|
-
|
|
41
|
+
useEffect(() => {
|
|
42
|
+
effectVersion.current += 1;
|
|
43
|
+
if (changeVersion.current === effectVersion.current) {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
effectVersion.current = changeVersion.current;
|
|
47
|
+
|
|
48
|
+
if (value?.type === 'constant' && value?.schema) {
|
|
49
|
+
setSelectSchema(value?.schema);
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
}, [value]);
|
|
53
|
+
|
|
54
|
+
const setSelectSchemaWithVersionUpdate = (schema: IJsonSchema) => {
|
|
55
|
+
setSelectSchema(schema);
|
|
56
|
+
changeVersion.current += 1;
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
return [selectSchema, setSelectSchemaWithVersionUpdate] as const;
|
|
39
60
|
}
|
|
40
61
|
|
|
41
62
|
export function useIncludeSchema(schemaFromProps?: IJsonSchema) {
|
|
@@ -5,11 +5,16 @@
|
|
|
5
5
|
|
|
6
6
|
import React from 'react';
|
|
7
7
|
|
|
8
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
JsonSchemaUtils,
|
|
10
|
+
IJsonSchema,
|
|
11
|
+
useTypeManager,
|
|
12
|
+
type JsonSchemaTypeManager,
|
|
13
|
+
} from '@flowgram.ai/json-schema';
|
|
9
14
|
import { IconButton } from '@douyinfe/semi-ui';
|
|
10
15
|
import { IconSetting } from '@douyinfe/semi-icons';
|
|
11
16
|
|
|
12
|
-
import { IFlowConstantRefValue } from '@/typings';
|
|
17
|
+
import { IFlowConstantRefValue, IFlowConstantValue } from '@/typings';
|
|
13
18
|
import { createInjectMaterial } from '@/shared';
|
|
14
19
|
import { InjectVariableSelector } from '@/components/variable-selector';
|
|
15
20
|
import { TypeSelector } from '@/components/type-selector';
|
|
@@ -32,6 +37,12 @@ interface PropsType {
|
|
|
32
37
|
};
|
|
33
38
|
}
|
|
34
39
|
|
|
40
|
+
const DEFAULT_VALUE: IFlowConstantValue = {
|
|
41
|
+
type: 'constant',
|
|
42
|
+
content: '',
|
|
43
|
+
schema: { type: 'string' },
|
|
44
|
+
};
|
|
45
|
+
|
|
35
46
|
export function DynamicValueInput({
|
|
36
47
|
value,
|
|
37
48
|
onChange,
|
|
@@ -44,6 +55,8 @@ export function DynamicValueInput({
|
|
|
44
55
|
const [selectSchema, setSelectSchema] = useSelectSchema(schemaFromProps, constantProps, value);
|
|
45
56
|
const includeSchema = useIncludeSchema(schemaFromProps);
|
|
46
57
|
|
|
58
|
+
const typeManager = useTypeManager() as JsonSchemaTypeManager;
|
|
59
|
+
|
|
47
60
|
const renderTypeSelector = () => {
|
|
48
61
|
if (schemaFromProps) {
|
|
49
62
|
return <TypeSelector value={schemaFromProps} readonly={true} />;
|
|
@@ -60,24 +73,20 @@ export function DynamicValueInput({
|
|
|
60
73
|
value={selectSchema}
|
|
61
74
|
onChange={(_v) => {
|
|
62
75
|
setSelectSchema(_v || { type: 'string' });
|
|
63
|
-
let content;
|
|
64
76
|
|
|
77
|
+
const schema = _v || { type: 'string' };
|
|
78
|
+
let content = typeManager.getDefaultValue(schema);
|
|
65
79
|
if (_v?.type === 'object') {
|
|
66
80
|
content = '{}';
|
|
67
81
|
}
|
|
68
|
-
|
|
69
82
|
if (_v?.type === 'array') {
|
|
70
83
|
content = '[]';
|
|
71
84
|
}
|
|
72
85
|
|
|
73
|
-
if (_v?.type === 'boolean') {
|
|
74
|
-
content = false;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
86
|
onChange({
|
|
78
87
|
type: 'constant',
|
|
79
88
|
content,
|
|
80
|
-
schema
|
|
89
|
+
schema,
|
|
81
90
|
});
|
|
82
91
|
}}
|
|
83
92
|
readonly={readonly}
|
|
@@ -92,7 +101,7 @@ export function DynamicValueInput({
|
|
|
92
101
|
<InjectVariableSelector
|
|
93
102
|
style={{ width: '100%' }}
|
|
94
103
|
value={value?.content}
|
|
95
|
-
onChange={(_v) => onChange(_v ? { type: 'ref', content: _v } :
|
|
104
|
+
onChange={(_v) => onChange(_v ? { type: 'ref', content: _v } : DEFAULT_VALUE)}
|
|
96
105
|
includeSchema={includeSchema}
|
|
97
106
|
readonly={readonly}
|
|
98
107
|
/>
|
|
@@ -107,16 +116,16 @@ export function DynamicValueInput({
|
|
|
107
116
|
onChange={(_v) => onChange({ type: 'constant', content: _v, schema: constantSchema })}
|
|
108
117
|
schema={constantSchema || { type: 'string' }}
|
|
109
118
|
readonly={readonly}
|
|
110
|
-
strategies={[...(constantProps?.strategies || [])]}
|
|
111
119
|
fallbackRenderer={() => (
|
|
112
120
|
<InjectVariableSelector
|
|
113
121
|
style={{ width: '100%' }}
|
|
114
|
-
onChange={(_v) => onChange(_v ? { type: 'ref', content: _v } :
|
|
122
|
+
onChange={(_v) => onChange(_v ? { type: 'ref', content: _v } : DEFAULT_VALUE)}
|
|
115
123
|
includeSchema={includeSchema}
|
|
116
124
|
readonly={readonly}
|
|
117
125
|
/>
|
|
118
126
|
)}
|
|
119
127
|
{...constantProps}
|
|
128
|
+
strategies={[...(constantProps?.strategies || [])]}
|
|
120
129
|
/>
|
|
121
130
|
);
|
|
122
131
|
};
|
|
@@ -67,7 +67,18 @@ export function InputsValues({
|
|
|
67
67
|
</UIRow>
|
|
68
68
|
))}
|
|
69
69
|
</UIRows>
|
|
70
|
-
<Button
|
|
70
|
+
<Button
|
|
71
|
+
disabled={readonly}
|
|
72
|
+
icon={<IconPlus />}
|
|
73
|
+
size="small"
|
|
74
|
+
onClick={() =>
|
|
75
|
+
add({
|
|
76
|
+
type: 'constant',
|
|
77
|
+
content: '',
|
|
78
|
+
schema: { type: 'string' },
|
|
79
|
+
})
|
|
80
|
+
}
|
|
81
|
+
>
|
|
71
82
|
{I18n.t('Add')}
|
|
72
83
|
</Button>
|
|
73
84
|
</div>
|
|
@@ -21,8 +21,9 @@ export function useChildList(
|
|
|
21
21
|
onChange?: (value: any) => void
|
|
22
22
|
): {
|
|
23
23
|
canAddField: boolean;
|
|
24
|
+
hasChildren: boolean;
|
|
24
25
|
list: ListItem[];
|
|
25
|
-
add: (
|
|
26
|
+
add: (defaultValue?: any) => void;
|
|
26
27
|
updateKey: (id: string, key: string) => void;
|
|
27
28
|
updateValue: (id: string, value: any) => void;
|
|
28
29
|
remove: (id: string) => void;
|
|
@@ -50,8 +51,6 @@ export function useChildList(
|
|
|
50
51
|
return undefined;
|
|
51
52
|
}, [value]);
|
|
52
53
|
|
|
53
|
-
console.log('debugger objectListValue', objectListValue);
|
|
54
|
-
|
|
55
54
|
const { list, add, updateKey, updateValue, remove } = useObjectList<any>({
|
|
56
55
|
value: objectListValue,
|
|
57
56
|
onChange: (value) => {
|
|
@@ -60,8 +59,14 @@ export function useChildList(
|
|
|
60
59
|
sortIndexKey: (value) => (FlowValueUtils.isFlowValue(value) ? 'extra.index' : ''),
|
|
61
60
|
});
|
|
62
61
|
|
|
62
|
+
const hasChildren = useMemo(
|
|
63
|
+
() => canAddField && (list.length > 0 || Object.keys(objectListValue || {}).length > 0),
|
|
64
|
+
[canAddField, list.length, Object.keys(objectListValue || {}).length]
|
|
65
|
+
);
|
|
66
|
+
|
|
63
67
|
return {
|
|
64
68
|
canAddField,
|
|
69
|
+
hasChildren,
|
|
65
70
|
list,
|
|
66
71
|
add,
|
|
67
72
|
updateKey,
|
|
@@ -47,7 +47,13 @@ export function InputsValuesTree(props: PropsType) {
|
|
|
47
47
|
disabled={readonly}
|
|
48
48
|
icon={<IconPlus />}
|
|
49
49
|
size="small"
|
|
50
|
-
onClick={
|
|
50
|
+
onClick={() => {
|
|
51
|
+
add({
|
|
52
|
+
type: 'constant',
|
|
53
|
+
content: '',
|
|
54
|
+
schema: { type: 'string' },
|
|
55
|
+
});
|
|
56
|
+
}}
|
|
51
57
|
>
|
|
52
58
|
{I18n.t('Add')}
|
|
53
59
|
</Button>
|
|
@@ -3,12 +3,13 @@
|
|
|
3
3
|
* SPDX-License-Identifier: MIT
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import React, { useState } from 'react';
|
|
6
|
+
import React, { useMemo, useState } from 'react';
|
|
7
7
|
|
|
8
8
|
import { I18n } from '@flowgram.ai/editor';
|
|
9
9
|
import { IconButton, Input } from '@douyinfe/semi-ui';
|
|
10
10
|
import { IconChevronDown, IconChevronRight, IconDelete } from '@douyinfe/semi-icons';
|
|
11
11
|
|
|
12
|
+
import { IFlowConstantValue } from '@/typings';
|
|
12
13
|
import { ConstantInputStrategy } from '@/components/constant-input';
|
|
13
14
|
|
|
14
15
|
import { PropsType } from './types';
|
|
@@ -64,14 +65,26 @@ export function InputValueRow(
|
|
|
64
65
|
} = props;
|
|
65
66
|
const [collapse, setCollapse] = useState(false);
|
|
66
67
|
|
|
67
|
-
const { canAddField, list, add, updateKey, updateValue, remove } = useChildList(
|
|
68
|
+
const { canAddField, hasChildren, list, add, updateKey, updateValue, remove } = useChildList(
|
|
68
69
|
value,
|
|
69
70
|
onUpdateValue
|
|
70
71
|
);
|
|
71
72
|
|
|
72
|
-
const
|
|
73
|
+
const strategies = useMemo(
|
|
74
|
+
() => [...(hasChildren ? [AddObjectChildStrategy] : []), ...(constantProps?.strategies || [])],
|
|
75
|
+
[hasChildren, constantProps?.strategies]
|
|
76
|
+
);
|
|
73
77
|
|
|
74
|
-
const flowDisplayValue =
|
|
78
|
+
const flowDisplayValue = useMemo(
|
|
79
|
+
() =>
|
|
80
|
+
hasChildren
|
|
81
|
+
? ({
|
|
82
|
+
type: 'constant',
|
|
83
|
+
schema: { type: 'object' },
|
|
84
|
+
} as IFlowConstantValue)
|
|
85
|
+
: value,
|
|
86
|
+
[hasChildren, value]
|
|
87
|
+
);
|
|
75
88
|
|
|
76
89
|
return (
|
|
77
90
|
<>
|
|
@@ -101,10 +114,7 @@ export function InputValueRow(
|
|
|
101
114
|
hasError={hasError}
|
|
102
115
|
constantProps={{
|
|
103
116
|
...constantProps,
|
|
104
|
-
strategies
|
|
105
|
-
...(hasChildren ? [AddObjectChildStrategy] : []),
|
|
106
|
-
...(constantProps?.strategies || []),
|
|
107
|
-
],
|
|
117
|
+
strategies,
|
|
108
118
|
}}
|
|
109
119
|
/>
|
|
110
120
|
<UIActions>
|
|
@@ -115,7 +125,11 @@ export function InputValueRow(
|
|
|
115
125
|
theme="borderless"
|
|
116
126
|
icon={<IconAddChildren />}
|
|
117
127
|
onClick={() => {
|
|
118
|
-
add(
|
|
128
|
+
add({
|
|
129
|
+
type: 'constant',
|
|
130
|
+
content: '',
|
|
131
|
+
schema: { type: 'string' },
|
|
132
|
+
});
|
|
119
133
|
setCollapse(true);
|
|
120
134
|
}}
|
|
121
135
|
/>
|
|
@@ -134,7 +134,7 @@ export function VariableTagInject() {
|
|
|
134
134
|
// 基于 {{var}} 的正则进行匹配,匹配后进行自定义渲染
|
|
135
135
|
useLayoutEffect(() => {
|
|
136
136
|
const atMatcher = new MatchDecorator({
|
|
137
|
-
regexp: /\{\{([^\}]+)\}\}/g,
|
|
137
|
+
regexp: /\{\{([^\}\{]+)\}\}/g,
|
|
138
138
|
decoration: (match) =>
|
|
139
139
|
Decoration.replace({
|
|
140
140
|
widget: new VariableTagWidget({
|
|
@@ -32,6 +32,17 @@ export function InputsTree({ inputsValues }: { inputsValues: Record<string, IFlo
|
|
|
32
32
|
return;
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
+
/**
|
|
36
|
+
* When user input {{xxxx}}, {{{xxx}}}(more brackets if possible), replace all brackets with {{xxxx}}
|
|
37
|
+
*/
|
|
38
|
+
let { from, to } = range;
|
|
39
|
+
while (editor.$view.state.doc.sliceString(from - 1, from) === '{') {
|
|
40
|
+
from--;
|
|
41
|
+
}
|
|
42
|
+
while (editor.$view.state.doc.sliceString(to, to + 1) === '}') {
|
|
43
|
+
to++;
|
|
44
|
+
}
|
|
45
|
+
|
|
35
46
|
editor.replaceText({
|
|
36
47
|
...range,
|
|
37
48
|
text: '{{' + variablePath + '}}',
|
|
@@ -5,13 +5,12 @@
|
|
|
5
5
|
|
|
6
6
|
import React from 'react';
|
|
7
7
|
|
|
8
|
-
import { IFlowValue } from '@/typings';
|
|
9
8
|
import { PromptEditor, PromptEditorPropsType } from '@/components/prompt-editor';
|
|
10
9
|
|
|
11
10
|
import { InputsTree } from './extensions/inputs-tree';
|
|
12
11
|
|
|
13
12
|
interface PropsType extends PromptEditorPropsType {
|
|
14
|
-
inputsValues:
|
|
13
|
+
inputsValues: any;
|
|
15
14
|
}
|
|
16
15
|
|
|
17
16
|
export function PromptEditorWithInputs({ inputsValues, ...restProps }: PropsType) {
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
import React, { useMemo } from 'react';
|
|
7
7
|
|
|
8
|
-
import { last } from 'lodash';
|
|
8
|
+
import { isPlainObject, last } from 'lodash';
|
|
9
9
|
import {
|
|
10
10
|
type ArrayType,
|
|
11
11
|
ASTMatch,
|
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
import { TreeNodeData } from '@douyinfe/semi-ui/lib/es/tree';
|
|
17
17
|
import { Tree } from '@douyinfe/semi-ui';
|
|
18
18
|
|
|
19
|
-
import {
|
|
19
|
+
import { FlowValueUtils } from '@/shared';
|
|
20
20
|
|
|
21
21
|
type VariableField = BaseVariableField<{ icon?: string | JSX.Element; title?: string }>;
|
|
22
22
|
|
|
@@ -24,7 +24,7 @@ export function InputsPicker({
|
|
|
24
24
|
inputsValues,
|
|
25
25
|
onSelect,
|
|
26
26
|
}: {
|
|
27
|
-
inputsValues:
|
|
27
|
+
inputsValues: any;
|
|
28
28
|
onSelect: (v: string) => void;
|
|
29
29
|
}) {
|
|
30
30
|
const available = useScopeAvailable();
|
|
@@ -76,23 +76,40 @@ export function InputsPicker({
|
|
|
76
76
|
};
|
|
77
77
|
};
|
|
78
78
|
|
|
79
|
-
const
|
|
80
|
-
()
|
|
81
|
-
Object.entries(inputsValues).map(([key, value]) => {
|
|
82
|
-
if (value?.type === 'ref') {
|
|
83
|
-
const variable = available.getByKeyPath(value.content || []);
|
|
79
|
+
const getTreeData = (value: any, keyPath: string[]): TreeNodeData | undefined => {
|
|
80
|
+
const currKey = keyPath.join('.');
|
|
84
81
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
82
|
+
if (FlowValueUtils.isFlowValue(value)) {
|
|
83
|
+
if (FlowValueUtils.isRef(value)) {
|
|
84
|
+
const variable = available.getByKeyPath(value.content || []);
|
|
85
|
+
if (variable) {
|
|
86
|
+
return renderVariable(variable, keyPath);
|
|
88
87
|
}
|
|
88
|
+
}
|
|
89
|
+
return {
|
|
90
|
+
key: currKey,
|
|
91
|
+
value: currKey,
|
|
92
|
+
label: last(keyPath),
|
|
93
|
+
};
|
|
94
|
+
}
|
|
89
95
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
+
if (isPlainObject(value)) {
|
|
97
|
+
return {
|
|
98
|
+
key: currKey,
|
|
99
|
+
value: currKey,
|
|
100
|
+
label: last(keyPath),
|
|
101
|
+
children: Object.entries(value)
|
|
102
|
+
.map(([key, value]) => getTreeData(value, [...keyPath, key])!)
|
|
103
|
+
.filter(Boolean),
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
const treeData: TreeNodeData[] = useMemo(
|
|
109
|
+
() =>
|
|
110
|
+
Object.entries(inputsValues)
|
|
111
|
+
.map(([key, value]) => getTreeData(value, [key])!)
|
|
112
|
+
.filter(Boolean),
|
|
96
113
|
[]
|
|
97
114
|
);
|
|
98
115
|
|
|
@@ -143,7 +143,7 @@ export function VariableTagInject() {
|
|
|
143
143
|
// 基于 {{var}} 的正则进行匹配,匹配后进行自定义渲染
|
|
144
144
|
useLayoutEffect(() => {
|
|
145
145
|
const atMatcher = new MatchDecorator({
|
|
146
|
-
regexp: /\{\{([^\}]+)\}\}/g,
|
|
146
|
+
regexp: /\{\{([^\}\{]+)\}\}/g,
|
|
147
147
|
decoration: (match) =>
|
|
148
148
|
Decoration.replace({
|
|
149
149
|
widget: new VariableTagWidget({
|
|
@@ -30,8 +30,20 @@ export function VariableTree() {
|
|
|
30
30
|
return;
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
+
/**
|
|
34
|
+
* When user input {{xxxx}}, {{{xxx}}}(more brackets if possible), replace all brackets with {{xxxx}}
|
|
35
|
+
*/
|
|
36
|
+
let { from, to } = range;
|
|
37
|
+
while (editor.$view.state.doc.sliceString(from - 1, from) === '{') {
|
|
38
|
+
from--;
|
|
39
|
+
}
|
|
40
|
+
while (editor.$view.state.doc.sliceString(to, to + 1) === '}') {
|
|
41
|
+
to++;
|
|
42
|
+
}
|
|
43
|
+
|
|
33
44
|
editor.replaceText({
|
|
34
|
-
|
|
45
|
+
from,
|
|
46
|
+
to,
|
|
35
47
|
text: '{{' + variablePath + '}}',
|
|
36
48
|
});
|
|
37
49
|
|
|
@@ -86,12 +86,22 @@ export function TypeSelector(props: TypeSelectorProps) {
|
|
|
86
86
|
[]
|
|
87
87
|
);
|
|
88
88
|
|
|
89
|
+
const isDisabled = readonly || disabled;
|
|
90
|
+
|
|
89
91
|
return (
|
|
90
92
|
<Cascader
|
|
91
|
-
disabled={
|
|
93
|
+
disabled={isDisabled}
|
|
92
94
|
size="small"
|
|
93
95
|
triggerRender={() => (
|
|
94
|
-
<IconButton
|
|
96
|
+
<IconButton
|
|
97
|
+
size="small"
|
|
98
|
+
style={{
|
|
99
|
+
...(isDisabled ? { pointerEvents: 'none' } : {}),
|
|
100
|
+
...(style || {}),
|
|
101
|
+
}}
|
|
102
|
+
disabled={isDisabled}
|
|
103
|
+
icon={icon}
|
|
104
|
+
/>
|
|
95
105
|
)}
|
|
96
106
|
treeData={options}
|
|
97
107
|
value={selectValue}
|
package/src/index.ts
CHANGED
|
@@ -14,7 +14,7 @@ export const extraSchema = z
|
|
|
14
14
|
|
|
15
15
|
export const constantSchema = z.object({
|
|
16
16
|
type: z.literal('constant'),
|
|
17
|
-
content: z.
|
|
17
|
+
content: z.any().optional(),
|
|
18
18
|
schema: z.any().optional(),
|
|
19
19
|
extra: extraSchema,
|
|
20
20
|
});
|
|
@@ -121,7 +121,7 @@ export namespace FlowValueUtils {
|
|
|
121
121
|
*/
|
|
122
122
|
export function getTemplateKeyPaths(value: IFlowTemplateValue) {
|
|
123
123
|
// find all keyPath wrapped in {{}}
|
|
124
|
-
const keyPathReg =
|
|
124
|
+
const keyPathReg = /\{\{([^\}\{]+)\}\}/g;
|
|
125
125
|
return uniq(value.content?.match(keyPathReg) || []).map((_keyPath) =>
|
|
126
126
|
_keyPath.slice(2, -2).split('.')
|
|
127
127
|
);
|
|
@@ -3,10 +3,11 @@
|
|
|
3
3
|
* SPDX-License-Identifier: MIT
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import { isNil
|
|
6
|
+
import { isNil } from 'lodash';
|
|
7
7
|
import { FeedbackLevel, FlowNodeEntity, getNodeScope } from '@flowgram.ai/editor';
|
|
8
8
|
|
|
9
|
-
import {
|
|
9
|
+
import { IFlowValue } from '@/typings';
|
|
10
|
+
import { FlowValueUtils } from '@/shared';
|
|
10
11
|
|
|
11
12
|
interface Context {
|
|
12
13
|
node: FlowNodeEntity;
|
|
@@ -43,7 +44,7 @@ export function validateFlowValue(value: IFlowValue | undefined, ctx: Context) {
|
|
|
43
44
|
}
|
|
44
45
|
|
|
45
46
|
if (value?.type === 'template') {
|
|
46
|
-
const allRefs = getTemplateKeyPaths(value);
|
|
47
|
+
const allRefs = FlowValueUtils.getTemplateKeyPaths(value);
|
|
47
48
|
|
|
48
49
|
for (const ref of allRefs) {
|
|
49
50
|
const variable = getNodeScope(node).available.getByKeyPath(ref);
|
|
@@ -58,16 +59,3 @@ export function validateFlowValue(value: IFlowValue | undefined, ctx: Context) {
|
|
|
58
59
|
|
|
59
60
|
return undefined;
|
|
60
61
|
}
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* get template key paths
|
|
64
|
-
* @param value
|
|
65
|
-
* @returns
|
|
66
|
-
*/
|
|
67
|
-
function getTemplateKeyPaths(value: IFlowTemplateValue) {
|
|
68
|
-
// find all keyPath wrapped in {{}}
|
|
69
|
-
const keyPathReg = /{{(.*?)}}/g;
|
|
70
|
-
return uniq(value.content?.match(keyPathReg) || []).map((_keyPath) =>
|
|
71
|
-
_keyPath.slice(2, -2).split('.')
|
|
72
|
-
);
|
|
73
|
-
}
|