@flowgram.ai/form-materials 0.1.0-alpha.10 → 0.1.0-alpha.11
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 +104 -15
- package/dist/esm/index.js.map +1 -1
- package/dist/index.d.mts +8 -1
- package/dist/index.d.ts +8 -1
- package/dist/index.js +116 -31
- package/dist/index.js.map +1 -1
- package/package.json +6 -5
- package/src/components/code-editor/config.json +2 -1
- package/src/components/code-editor/index.tsx +16 -1
- package/src/components/code-editor/language-features.ts +3 -4
- package/src/components/code-editor/theme/light.ts +1 -1
- package/src/components/json-editor-with-variables/index.tsx +47 -1
- package/src/components/json-schema-editor/hooks.tsx +3 -1
- package/src/components/prompt-editor/index.tsx +2 -1
- package/src/components/prompt-editor/types.tsx +1 -0
- package/src/effects/auto-rename-ref/index.ts +59 -8
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@flowgram.ai/form-materials",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.11",
|
|
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.1.0-alpha.11"
|
|
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/
|
|
53
|
-
"@flowgram.ai/
|
|
53
|
+
"@flowgram.ai/ts-config": "0.1.0-alpha.11",
|
|
54
|
+
"@flowgram.ai/eslint-config": "0.1.0-alpha.11"
|
|
54
55
|
},
|
|
55
56
|
"peerDependencies": {
|
|
56
57
|
"react": ">=16.8",
|
|
@@ -5,7 +5,12 @@
|
|
|
5
5
|
|
|
6
6
|
import React, { useEffect, useRef } from 'react';
|
|
7
7
|
|
|
8
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
ActiveLinePlaceholder,
|
|
10
|
+
createRenderer,
|
|
11
|
+
EditorProvider,
|
|
12
|
+
InferValues,
|
|
13
|
+
} from '@coze-editor/editor/react';
|
|
9
14
|
import preset, { type EditorAPI } from '@coze-editor/editor/preset-code';
|
|
10
15
|
import { EditorView } from '@codemirror/view';
|
|
11
16
|
|
|
@@ -22,6 +27,9 @@ const OriginCodeEditor = createRenderer(preset, [
|
|
|
22
27
|
}),
|
|
23
28
|
]);
|
|
24
29
|
|
|
30
|
+
type Preset = typeof preset;
|
|
31
|
+
type Options = Partial<InferValues<Preset[number]>>;
|
|
32
|
+
|
|
25
33
|
export interface CodeEditorPropsType extends React.PropsWithChildren<{}> {
|
|
26
34
|
value?: string;
|
|
27
35
|
onChange?: (value: string) => void;
|
|
@@ -29,6 +37,8 @@ export interface CodeEditorPropsType extends React.PropsWithChildren<{}> {
|
|
|
29
37
|
theme?: 'dark' | 'light';
|
|
30
38
|
placeholder?: string;
|
|
31
39
|
activeLinePlaceholder?: string;
|
|
40
|
+
readonly?: boolean;
|
|
41
|
+
options?: Options;
|
|
32
42
|
}
|
|
33
43
|
|
|
34
44
|
export function CodeEditor({
|
|
@@ -39,6 +49,8 @@ export function CodeEditor({
|
|
|
39
49
|
children,
|
|
40
50
|
placeholder,
|
|
41
51
|
activeLinePlaceholder,
|
|
52
|
+
options,
|
|
53
|
+
readonly,
|
|
42
54
|
}: CodeEditorPropsType) {
|
|
43
55
|
const editorRef = useRef<EditorAPI | null>(null);
|
|
44
56
|
|
|
@@ -58,6 +70,9 @@ export function CodeEditor({
|
|
|
58
70
|
languageId,
|
|
59
71
|
theme,
|
|
60
72
|
placeholder,
|
|
73
|
+
readOnly: readonly,
|
|
74
|
+
editable: !readonly,
|
|
75
|
+
...(options || {}),
|
|
61
76
|
}}
|
|
62
77
|
didMount={(editor: EditorAPI) => {
|
|
63
78
|
editorRef.current = editor;
|
|
@@ -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);
|
|
@@ -30,7 +30,7 @@ export const lightTheme: Extension = createTheme({
|
|
|
30
30
|
gutterBorderColor: 'transparent',
|
|
31
31
|
gutterBorderWidth: 0,
|
|
32
32
|
lineHighlight: '#f0f0f0',
|
|
33
|
-
bracketColors: ['#
|
|
33
|
+
bracketColors: ['#FFD700', '#DD99FF', '#78B0FF'],
|
|
34
34
|
tooltip: {
|
|
35
35
|
backgroundColor: '#f0f0f0',
|
|
36
36
|
color: '#000',
|
|
@@ -5,13 +5,59 @@
|
|
|
5
5
|
|
|
6
6
|
import React from 'react';
|
|
7
7
|
|
|
8
|
+
import { transformerCreator } from '@coze-editor/editor/preset-code';
|
|
9
|
+
import { Text } from '@coze-editor/editor/language-json';
|
|
10
|
+
|
|
8
11
|
import { VariableTree } from './extensions/variable-tree';
|
|
9
12
|
import { VariableTagInject } from './extensions/variable-tag';
|
|
10
13
|
import { CodeEditor, type CodeEditorPropsType } from '../code-editor';
|
|
11
14
|
|
|
15
|
+
type Match = { match: string; range: [number, number] };
|
|
16
|
+
function findAllMatches(inputString: string, regex: RegExp): Match[] {
|
|
17
|
+
const globalRegex = new RegExp(
|
|
18
|
+
regex,
|
|
19
|
+
regex.flags.includes('g') ? regex.flags : regex.flags + 'g'
|
|
20
|
+
);
|
|
21
|
+
let match;
|
|
22
|
+
const matches: Match[] = [];
|
|
23
|
+
|
|
24
|
+
while ((match = globalRegex.exec(inputString)) !== null) {
|
|
25
|
+
if (match.index === globalRegex.lastIndex) {
|
|
26
|
+
globalRegex.lastIndex++;
|
|
27
|
+
}
|
|
28
|
+
matches.push({
|
|
29
|
+
match: match[0],
|
|
30
|
+
range: [match.index, match.index + match[0].length],
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return matches;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const transformer = transformerCreator((text: Text) => {
|
|
38
|
+
const originalSource = text.toString();
|
|
39
|
+
const matches = findAllMatches(originalSource, /\{\{([^\}]*)\}\}/g);
|
|
40
|
+
|
|
41
|
+
if (matches.length > 0) {
|
|
42
|
+
matches.forEach(({ range }) => {
|
|
43
|
+
text.replaceRange(range[0], range[1], 'null');
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return text;
|
|
48
|
+
});
|
|
49
|
+
|
|
12
50
|
export function JsonEditorWithVariables(props: Omit<CodeEditorPropsType, 'languageId'>) {
|
|
13
51
|
return (
|
|
14
|
-
<CodeEditor
|
|
52
|
+
<CodeEditor
|
|
53
|
+
languageId="json"
|
|
54
|
+
activeLinePlaceholder="Press '@' to Select variable"
|
|
55
|
+
{...props}
|
|
56
|
+
options={{
|
|
57
|
+
transformer,
|
|
58
|
+
...(props.options || {}),
|
|
59
|
+
}}
|
|
60
|
+
>
|
|
15
61
|
<VariableTree />
|
|
16
62
|
<VariableTagInject />
|
|
17
63
|
</CodeEditor>
|
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
|
|
6
6
|
import { useEffect, useMemo, useRef, useState } from 'react';
|
|
7
7
|
|
|
8
|
+
import { omit } from 'lodash';
|
|
9
|
+
|
|
8
10
|
import { IJsonSchema } from '../../typings';
|
|
9
11
|
import { PropertyValueType } from './types';
|
|
10
12
|
|
|
@@ -113,7 +115,7 @@ export function usePropertiesEdit(
|
|
|
113
115
|
continue;
|
|
114
116
|
}
|
|
115
117
|
|
|
116
|
-
nextProperties[_property.name] = _property;
|
|
118
|
+
nextProperties[_property.name] = omit(_property, ['key', 'name', 'isPropertyRequired']);
|
|
117
119
|
|
|
118
120
|
if (_property.isPropertyRequired) {
|
|
119
121
|
nextRequired.push(_property.name);
|
|
@@ -26,6 +26,7 @@ export function PromptEditor(props: PropsType) {
|
|
|
26
26
|
style,
|
|
27
27
|
hasError,
|
|
28
28
|
children,
|
|
29
|
+
disableMarkdownHighlight,
|
|
29
30
|
} = props || {};
|
|
30
31
|
|
|
31
32
|
const editorRef = useRef<EditorAPI | null>(null);
|
|
@@ -58,7 +59,7 @@ export function PromptEditor(props: PropsType) {
|
|
|
58
59
|
{activeLinePlaceholder && (
|
|
59
60
|
<ActiveLinePlaceholder>{activeLinePlaceholder}</ActiveLinePlaceholder>
|
|
60
61
|
)}
|
|
61
|
-
<MarkdownHighlight />
|
|
62
|
+
{!disableMarkdownHighlight && <MarkdownHighlight />}
|
|
62
63
|
<LanguageSupport />
|
|
63
64
|
<JinjaHighlight />
|
|
64
65
|
{children}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* SPDX-License-Identifier: MIT
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import { isArray, isObject } from 'lodash';
|
|
6
|
+
import { isArray, isObject, uniq } from 'lodash';
|
|
7
7
|
import {
|
|
8
8
|
DataEvent,
|
|
9
9
|
Effect,
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
VariableFieldKeyRenameService,
|
|
12
12
|
} from '@flowgram.ai/editor';
|
|
13
13
|
|
|
14
|
-
import { IFlowRefValue } from '../../typings';
|
|
14
|
+
import { IFlowRefValue, IFlowTemplateValue } from '../../typings';
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
17
|
* Auto rename ref when form item's key is renamed
|
|
@@ -44,9 +44,34 @@ export const autoRenameRefEffect: EffectOptions[] = [
|
|
|
44
44
|
|
|
45
45
|
// traverse rename refs inside form item 'name'
|
|
46
46
|
traverseRef(name, form.getValueIn(name), (_drilldownName, _v) => {
|
|
47
|
-
if (
|
|
48
|
-
|
|
49
|
-
|
|
47
|
+
if (_v.type === 'ref') {
|
|
48
|
+
// ref auto rename
|
|
49
|
+
if (isKeyPathMatch(_v.content, beforeKeyPath)) {
|
|
50
|
+
_v.content = [...afterKeyPath, ...(_v.content || [])?.slice(beforeKeyPath.length)];
|
|
51
|
+
form.setValueIn(_drilldownName, _v);
|
|
52
|
+
}
|
|
53
|
+
} else if (_v.type === 'template') {
|
|
54
|
+
// template auto rename
|
|
55
|
+
const templateKeyPaths = getTemplateKeyPaths(_v);
|
|
56
|
+
let hasMatch = false;
|
|
57
|
+
|
|
58
|
+
templateKeyPaths.forEach((_keyPath) => {
|
|
59
|
+
if (isKeyPathMatch(_keyPath, beforeKeyPath)) {
|
|
60
|
+
hasMatch = true;
|
|
61
|
+
const nextKeyPath = [
|
|
62
|
+
...afterKeyPath,
|
|
63
|
+
...(_keyPath || [])?.slice(beforeKeyPath.length),
|
|
64
|
+
];
|
|
65
|
+
_v.content = _v.content?.replace(
|
|
66
|
+
`{{${_keyPath.join('.')}}`,
|
|
67
|
+
`{{${nextKeyPath.join('.')}}`
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
if (hasMatch) {
|
|
73
|
+
form.setValueIn(_drilldownName, { ..._v });
|
|
74
|
+
}
|
|
50
75
|
}
|
|
51
76
|
});
|
|
52
77
|
});
|
|
@@ -64,8 +89,21 @@ export const autoRenameRefEffect: EffectOptions[] = [
|
|
|
64
89
|
* @param targetKeyPath
|
|
65
90
|
* @returns
|
|
66
91
|
*/
|
|
67
|
-
function
|
|
68
|
-
return targetKeyPath.every((_key, index) => _key ===
|
|
92
|
+
function isKeyPathMatch(keyPath: string[] = [], targetKeyPath: string[]) {
|
|
93
|
+
return targetKeyPath.every((_key, index) => _key === keyPath[index]);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* get template key paths
|
|
98
|
+
* @param value
|
|
99
|
+
* @returns
|
|
100
|
+
*/
|
|
101
|
+
function getTemplateKeyPaths(value: IFlowTemplateValue) {
|
|
102
|
+
// find all keyPath wrapped in {{}}
|
|
103
|
+
const keyPathReg = /{{(.*?)}}/g;
|
|
104
|
+
return uniq(value.content?.match(keyPathReg) || []).map((_keyPath) =>
|
|
105
|
+
_keyPath.slice(2, -2).split('.')
|
|
106
|
+
);
|
|
69
107
|
}
|
|
70
108
|
|
|
71
109
|
/**
|
|
@@ -79,19 +117,32 @@ function isRef(value: any): value is IFlowRefValue {
|
|
|
79
117
|
);
|
|
80
118
|
}
|
|
81
119
|
|
|
120
|
+
function isTemplate(value: any): value is IFlowTemplateValue {
|
|
121
|
+
return value?.type === 'template' && typeof value?.content === 'string';
|
|
122
|
+
}
|
|
123
|
+
|
|
82
124
|
/**
|
|
83
125
|
* Traverse value to find ref
|
|
84
126
|
* @param value
|
|
85
127
|
* @param options
|
|
86
128
|
* @returns
|
|
87
129
|
*/
|
|
88
|
-
function traverseRef(
|
|
130
|
+
function traverseRef(
|
|
131
|
+
name: string,
|
|
132
|
+
value: any,
|
|
133
|
+
cb: (name: string, _v: IFlowRefValue | IFlowTemplateValue) => void
|
|
134
|
+
) {
|
|
89
135
|
if (isObject(value)) {
|
|
90
136
|
if (isRef(value)) {
|
|
91
137
|
cb(name, value);
|
|
92
138
|
return;
|
|
93
139
|
}
|
|
94
140
|
|
|
141
|
+
if (isTemplate(value)) {
|
|
142
|
+
cb(name, value);
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
|
|
95
146
|
Object.entries(value).forEach(([_key, _value]) => {
|
|
96
147
|
traverseRef(`${name}.${_key}`, _value, cb);
|
|
97
148
|
});
|