@flowgram.ai/form-materials 0.4.5 → 0.4.6
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/chunk-6OZSB6PD.js +10 -0
- package/dist/esm/chunk-6OZSB6PD.js.map +1 -0
- package/dist/esm/chunk-G4HQ7OSI.js +440 -0
- package/dist/esm/chunk-G4HQ7OSI.js.map +1 -0
- package/dist/esm/chunk-QIJ4QVB2.js +271 -0
- package/dist/esm/chunk-QIJ4QVB2.js.map +1 -0
- package/dist/esm/editor-6UMULJYB.js +180 -0
- package/dist/esm/editor-6UMULJYB.js.map +1 -0
- package/dist/esm/editor-E2BQTPCD.js +388 -0
- package/dist/esm/editor-E2BQTPCD.js.map +1 -0
- package/dist/esm/editor-H2R7JJLO.js +282 -0
- package/dist/esm/editor-H2R7JJLO.js.map +1 -0
- package/dist/esm/editor-JX42GFAZ.js +249 -0
- package/dist/esm/editor-JX42GFAZ.js.map +1 -0
- package/dist/esm/editor-YMNCDGUR.js +167 -0
- package/dist/esm/editor-YMNCDGUR.js.map +1 -0
- package/dist/esm/index.js +599 -2293
- package/dist/esm/index.js.map +1 -1
- package/dist/index.d.mts +133 -51
- package/dist/index.d.ts +133 -51
- package/dist/index.js +3499 -2802
- package/dist/index.js.map +1 -1
- package/package.json +6 -6
- package/src/components/code-editor/editor.tsx +96 -0
- package/src/components/code-editor/index.tsx +5 -89
- package/src/components/code-editor-mini/index.tsx +2 -2
- package/src/components/condition-row/index.tsx +4 -0
- package/src/components/db-condition-row/hooks/use-left.tsx +66 -0
- package/src/components/db-condition-row/hooks/use-op.tsx +59 -0
- package/src/components/db-condition-row/index.tsx +93 -0
- package/src/components/db-condition-row/styles.tsx +43 -0
- package/src/components/db-condition-row/types.ts +34 -0
- package/src/components/index.ts +1 -0
- package/src/components/json-editor-with-variables/editor.tsx +69 -0
- package/src/components/json-editor-with-variables/index.tsx +5 -60
- package/src/components/prompt-editor/editor.tsx +81 -0
- package/src/components/prompt-editor/index.tsx +5 -69
- package/src/components/prompt-editor-with-inputs/editor.tsx +25 -0
- package/src/components/prompt-editor-with-inputs/index.tsx +5 -15
- package/src/components/prompt-editor-with-variables/editor.tsx +22 -0
- package/src/components/prompt-editor-with-variables/index.tsx +5 -13
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.6",
|
|
4
4
|
"homepage": "https://flowgram.ai/",
|
|
5
5
|
"repository": "https://github.com/bytedance/flowgram.ai",
|
|
6
6
|
"license": "MIT",
|
|
@@ -30,13 +30,13 @@
|
|
|
30
30
|
"chalk": "^5.3.0",
|
|
31
31
|
"inquirer": "^9.2.7",
|
|
32
32
|
"immer": "~10.1.1",
|
|
33
|
-
"@coze-editor/editor": "0.1.0-alpha.
|
|
33
|
+
"@coze-editor/editor": "0.1.0-alpha.5a549c",
|
|
34
34
|
"@codemirror/view": "~6.38.0",
|
|
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.6",
|
|
39
|
+
"@flowgram.ai/json-schema": "0.4.6"
|
|
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/
|
|
56
|
-
"@flowgram.ai/
|
|
55
|
+
"@flowgram.ai/eslint-config": "0.4.6",
|
|
56
|
+
"@flowgram.ai/ts-config": "0.4.6"
|
|
57
57
|
},
|
|
58
58
|
"peerDependencies": {
|
|
59
59
|
"react": ">=16.8",
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
|
|
3
|
+
* SPDX-License-Identifier: MIT
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import React, { useEffect, useRef } from 'react';
|
|
7
|
+
|
|
8
|
+
import {
|
|
9
|
+
ActiveLinePlaceholder,
|
|
10
|
+
createRenderer,
|
|
11
|
+
EditorProvider,
|
|
12
|
+
InferValues,
|
|
13
|
+
} from '@coze-editor/editor/react';
|
|
14
|
+
import preset, { type EditorAPI } from '@coze-editor/editor/preset-code';
|
|
15
|
+
import { EditorView } from '@codemirror/view';
|
|
16
|
+
|
|
17
|
+
import { getSuffixByLanguageId } from './utils';
|
|
18
|
+
import { initTsWorker } from './language-features';
|
|
19
|
+
|
|
20
|
+
import './theme';
|
|
21
|
+
import './language-features';
|
|
22
|
+
|
|
23
|
+
const OriginCodeEditor = createRenderer(preset, [
|
|
24
|
+
EditorView.theme({
|
|
25
|
+
'&.cm-focused': {
|
|
26
|
+
outline: 'none',
|
|
27
|
+
},
|
|
28
|
+
}),
|
|
29
|
+
]);
|
|
30
|
+
|
|
31
|
+
type Preset = typeof preset;
|
|
32
|
+
type Options = Partial<InferValues<Preset[number]>>;
|
|
33
|
+
|
|
34
|
+
export interface CodeEditorPropsType extends React.PropsWithChildren<{}> {
|
|
35
|
+
value?: string;
|
|
36
|
+
onChange?: (value: string) => void;
|
|
37
|
+
languageId: 'python' | 'typescript' | 'shell' | 'json';
|
|
38
|
+
theme?: 'dark' | 'light';
|
|
39
|
+
placeholder?: string;
|
|
40
|
+
activeLinePlaceholder?: string;
|
|
41
|
+
readonly?: boolean;
|
|
42
|
+
options?: Options;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export function CodeEditor({
|
|
46
|
+
value,
|
|
47
|
+
onChange,
|
|
48
|
+
languageId = 'python',
|
|
49
|
+
theme = 'light',
|
|
50
|
+
children,
|
|
51
|
+
placeholder,
|
|
52
|
+
activeLinePlaceholder,
|
|
53
|
+
options,
|
|
54
|
+
readonly,
|
|
55
|
+
}: CodeEditorPropsType) {
|
|
56
|
+
const editorRef = useRef<EditorAPI | null>(null);
|
|
57
|
+
|
|
58
|
+
useEffect(() => {
|
|
59
|
+
if (languageId === 'typescript') {
|
|
60
|
+
initTsWorker();
|
|
61
|
+
}
|
|
62
|
+
}, [languageId]);
|
|
63
|
+
|
|
64
|
+
useEffect(() => {
|
|
65
|
+
// listen to value change
|
|
66
|
+
if (editorRef.current?.getValue() !== value) {
|
|
67
|
+
editorRef.current?.setValue(String(value || ''));
|
|
68
|
+
}
|
|
69
|
+
}, [value]);
|
|
70
|
+
|
|
71
|
+
return (
|
|
72
|
+
<EditorProvider>
|
|
73
|
+
<OriginCodeEditor
|
|
74
|
+
defaultValue={String(value || '')}
|
|
75
|
+
options={{
|
|
76
|
+
uri: `file:///untitled${getSuffixByLanguageId(languageId)}`,
|
|
77
|
+
languageId,
|
|
78
|
+
theme,
|
|
79
|
+
placeholder,
|
|
80
|
+
readOnly: readonly,
|
|
81
|
+
editable: !readonly,
|
|
82
|
+
...(options || {}),
|
|
83
|
+
}}
|
|
84
|
+
didMount={(editor: EditorAPI) => {
|
|
85
|
+
editorRef.current = editor;
|
|
86
|
+
}}
|
|
87
|
+
onChange={(e) => onChange?.(e.value)}
|
|
88
|
+
>
|
|
89
|
+
{activeLinePlaceholder && (
|
|
90
|
+
<ActiveLinePlaceholder>{activeLinePlaceholder}</ActiveLinePlaceholder>
|
|
91
|
+
)}
|
|
92
|
+
{children}
|
|
93
|
+
</OriginCodeEditor>
|
|
94
|
+
</EditorProvider>
|
|
95
|
+
);
|
|
96
|
+
}
|
|
@@ -3,94 +3,10 @@
|
|
|
3
3
|
* SPDX-License-Identifier: MIT
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import
|
|
6
|
+
import { lazy } from 'react';
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
EditorProvider,
|
|
12
|
-
InferValues,
|
|
13
|
-
} from '@coze-editor/editor/react';
|
|
14
|
-
import preset, { type EditorAPI } from '@coze-editor/editor/preset-code';
|
|
15
|
-
import { EditorView } from '@codemirror/view';
|
|
8
|
+
export const CodeEditor = lazy(() =>
|
|
9
|
+
import('./editor').then((module) => ({ default: module.CodeEditor }))
|
|
10
|
+
);
|
|
16
11
|
|
|
17
|
-
|
|
18
|
-
import { initTsWorker } from './language-features';
|
|
19
|
-
|
|
20
|
-
import './theme';
|
|
21
|
-
import './language-features';
|
|
22
|
-
|
|
23
|
-
const OriginCodeEditor = createRenderer(preset, [
|
|
24
|
-
EditorView.theme({
|
|
25
|
-
'&.cm-focused': {
|
|
26
|
-
outline: 'none',
|
|
27
|
-
},
|
|
28
|
-
}),
|
|
29
|
-
]);
|
|
30
|
-
|
|
31
|
-
type Preset = typeof preset;
|
|
32
|
-
type Options = Partial<InferValues<Preset[number]>>;
|
|
33
|
-
|
|
34
|
-
export interface CodeEditorPropsType extends React.PropsWithChildren<{}> {
|
|
35
|
-
value?: string;
|
|
36
|
-
onChange?: (value: string) => void;
|
|
37
|
-
languageId: 'python' | 'typescript' | 'shell' | 'json';
|
|
38
|
-
theme?: 'dark' | 'light';
|
|
39
|
-
placeholder?: string;
|
|
40
|
-
activeLinePlaceholder?: string;
|
|
41
|
-
readonly?: boolean;
|
|
42
|
-
options?: Options;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
export function CodeEditor({
|
|
46
|
-
value,
|
|
47
|
-
onChange,
|
|
48
|
-
languageId = 'python',
|
|
49
|
-
theme = 'light',
|
|
50
|
-
children,
|
|
51
|
-
placeholder,
|
|
52
|
-
activeLinePlaceholder,
|
|
53
|
-
options,
|
|
54
|
-
readonly,
|
|
55
|
-
}: CodeEditorPropsType) {
|
|
56
|
-
const editorRef = useRef<EditorAPI | null>(null);
|
|
57
|
-
|
|
58
|
-
useEffect(() => {
|
|
59
|
-
if (languageId === 'typescript') {
|
|
60
|
-
initTsWorker();
|
|
61
|
-
}
|
|
62
|
-
}, [languageId]);
|
|
63
|
-
|
|
64
|
-
useEffect(() => {
|
|
65
|
-
// listen to value change
|
|
66
|
-
if (editorRef.current?.getValue() !== value) {
|
|
67
|
-
editorRef.current?.setValue(String(value || ''));
|
|
68
|
-
}
|
|
69
|
-
}, [value]);
|
|
70
|
-
|
|
71
|
-
return (
|
|
72
|
-
<EditorProvider>
|
|
73
|
-
<OriginCodeEditor
|
|
74
|
-
defaultValue={value}
|
|
75
|
-
options={{
|
|
76
|
-
uri: `file:///untitled${getSuffixByLanguageId(languageId)}`,
|
|
77
|
-
languageId,
|
|
78
|
-
theme,
|
|
79
|
-
placeholder,
|
|
80
|
-
readOnly: readonly,
|
|
81
|
-
editable: !readonly,
|
|
82
|
-
...(options || {}),
|
|
83
|
-
}}
|
|
84
|
-
didMount={(editor: EditorAPI) => {
|
|
85
|
-
editorRef.current = editor;
|
|
86
|
-
}}
|
|
87
|
-
onChange={(e) => onChange?.(e.value)}
|
|
88
|
-
>
|
|
89
|
-
{activeLinePlaceholder && (
|
|
90
|
-
<ActiveLinePlaceholder>{activeLinePlaceholder}</ActiveLinePlaceholder>
|
|
91
|
-
)}
|
|
92
|
-
{children}
|
|
93
|
-
</OriginCodeEditor>
|
|
94
|
-
</EditorProvider>
|
|
95
|
-
);
|
|
96
|
-
}
|
|
12
|
+
export type { CodeEditorPropsType } from './editor';
|
|
@@ -7,11 +7,10 @@ import React from 'react';
|
|
|
7
7
|
|
|
8
8
|
import styled from 'styled-components';
|
|
9
9
|
|
|
10
|
-
import { CodeEditor, CodeEditorPropsType } from '@/components/code-editor';
|
|
10
|
+
import { CodeEditor, type CodeEditorPropsType } from '@/components/code-editor';
|
|
11
11
|
|
|
12
12
|
const UIMini = styled.div`
|
|
13
13
|
.ͼ1 .cm-content {
|
|
14
|
-
padding: 0;
|
|
15
14
|
}
|
|
16
15
|
`;
|
|
17
16
|
|
|
@@ -23,6 +22,7 @@ export function CodeEditorMini(props: CodeEditorPropsType) {
|
|
|
23
22
|
options={{
|
|
24
23
|
lineNumbersGutter: false,
|
|
25
24
|
foldGutter: false,
|
|
25
|
+
minHeight: 24,
|
|
26
26
|
...(props.options || {}),
|
|
27
27
|
}}
|
|
28
28
|
/>
|
|
@@ -15,6 +15,7 @@ import { ConditionRowValueType, IRules, OpConfigs } from './types';
|
|
|
15
15
|
import { UIContainer, UILeft, UIOperator, UIRight, UIValues } from './styles';
|
|
16
16
|
import { useRule } from './hooks/useRule';
|
|
17
17
|
import { useOp } from './hooks/useOp';
|
|
18
|
+
import { defaultOpConfigs, defaultRules } from './constants';
|
|
18
19
|
|
|
19
20
|
interface PropTypes {
|
|
20
21
|
value?: ConditionRowValueType;
|
|
@@ -96,4 +97,7 @@ export function ConditionRow({
|
|
|
96
97
|
);
|
|
97
98
|
}
|
|
98
99
|
|
|
100
|
+
ConditionRow.defaultRules = defaultRules;
|
|
101
|
+
ConditionRow.defaultOpConfigs = defaultOpConfigs;
|
|
102
|
+
|
|
99
103
|
export { type ConditionRowValueType };
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
|
|
3
|
+
* SPDX-License-Identifier: MIT
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { useMemo } from 'react';
|
|
7
|
+
import React from 'react';
|
|
8
|
+
|
|
9
|
+
import { JsonSchemaTypeManager, useTypeManager } from '@flowgram.ai/json-schema';
|
|
10
|
+
import { Icon } from '@douyinfe/semi-ui';
|
|
11
|
+
|
|
12
|
+
import { ConditionRow } from '@/components';
|
|
13
|
+
|
|
14
|
+
import { DBConditionOptionType, IRules } from '../types';
|
|
15
|
+
import { UIOptionLabel, UISelect } from '../styles';
|
|
16
|
+
|
|
17
|
+
const defaultRules = ConditionRow.defaultRules;
|
|
18
|
+
|
|
19
|
+
interface HookParams {
|
|
20
|
+
left?: string;
|
|
21
|
+
options?: DBConditionOptionType[];
|
|
22
|
+
userRules?: IRules;
|
|
23
|
+
readonly?: boolean;
|
|
24
|
+
onChange: (leftKey: string) => void;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function useLeft({ left, options, userRules, readonly, onChange }: HookParams) {
|
|
28
|
+
const rules = useMemo(() => ({ ...defaultRules, ...(userRules || {}) }), [userRules]);
|
|
29
|
+
|
|
30
|
+
const typeManager = useTypeManager() as JsonSchemaTypeManager;
|
|
31
|
+
|
|
32
|
+
const rule = useMemo(() => {
|
|
33
|
+
if (!left) return undefined;
|
|
34
|
+
|
|
35
|
+
const option = options?.find((item) => item.value === left);
|
|
36
|
+
|
|
37
|
+
if (!option?.schema?.type) {
|
|
38
|
+
return undefined;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return rules[option.schema.type];
|
|
42
|
+
}, [left, options, rules]);
|
|
43
|
+
|
|
44
|
+
const renderDBOptionSelect = () => (
|
|
45
|
+
<UISelect
|
|
46
|
+
disabled={readonly}
|
|
47
|
+
size="small"
|
|
48
|
+
style={{ width: '100%' }}
|
|
49
|
+
value={left}
|
|
50
|
+
onChange={(v) => onChange(v as string)}
|
|
51
|
+
optionList={
|
|
52
|
+
options?.map((item) => ({
|
|
53
|
+
label: (
|
|
54
|
+
<UIOptionLabel>
|
|
55
|
+
<Icon size="small" svg={typeManager.getDisplayIcon(item.schema)} />
|
|
56
|
+
{item.label}
|
|
57
|
+
</UIOptionLabel>
|
|
58
|
+
),
|
|
59
|
+
value: item.value,
|
|
60
|
+
})) || []
|
|
61
|
+
}
|
|
62
|
+
/>
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
return { rule, renderDBOptionSelect };
|
|
66
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
|
|
3
|
+
* SPDX-License-Identifier: MIT
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import React, { useMemo } from 'react';
|
|
7
|
+
|
|
8
|
+
import { I18n } from '@flowgram.ai/editor';
|
|
9
|
+
import { Button, Select } from '@douyinfe/semi-ui';
|
|
10
|
+
import { IconChevronDownStroked } from '@douyinfe/semi-icons';
|
|
11
|
+
|
|
12
|
+
import { ConditionRow } from '@/components';
|
|
13
|
+
|
|
14
|
+
import { IRule, OpConfigs } from '../types';
|
|
15
|
+
|
|
16
|
+
const defaultOpConfigs = ConditionRow.defaultOpConfigs;
|
|
17
|
+
|
|
18
|
+
interface HookParams {
|
|
19
|
+
rule?: IRule;
|
|
20
|
+
op?: string;
|
|
21
|
+
onChange: (op: string) => void;
|
|
22
|
+
readonly?: boolean;
|
|
23
|
+
userOps?: OpConfigs;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function useOp({ rule, op, onChange, readonly, userOps }: HookParams) {
|
|
27
|
+
const options = useMemo(
|
|
28
|
+
() =>
|
|
29
|
+
Object.keys(rule || {}).map((_op) => ({
|
|
30
|
+
...(defaultOpConfigs[_op] || {}),
|
|
31
|
+
...(userOps?.[_op] || {}),
|
|
32
|
+
value: _op,
|
|
33
|
+
label: I18n.t(userOps?.[_op]?.label || defaultOpConfigs[_op]?.label),
|
|
34
|
+
})),
|
|
35
|
+
[rule, userOps]
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
const opConfig = useMemo(() => defaultOpConfigs[op as string], [op]);
|
|
39
|
+
|
|
40
|
+
const renderOpSelect = () => (
|
|
41
|
+
<Select
|
|
42
|
+
style={{ height: 22 }}
|
|
43
|
+
disabled={readonly}
|
|
44
|
+
size="small"
|
|
45
|
+
value={op}
|
|
46
|
+
optionList={options}
|
|
47
|
+
onChange={(v) => {
|
|
48
|
+
onChange(v as string);
|
|
49
|
+
}}
|
|
50
|
+
triggerRender={({ value }) => (
|
|
51
|
+
<Button size="small" disabled={!rule}>
|
|
52
|
+
{opConfig?.abbreviation || <IconChevronDownStroked size="small" />}
|
|
53
|
+
</Button>
|
|
54
|
+
)}
|
|
55
|
+
/>
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
return { renderOpSelect, opConfig };
|
|
59
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
|
|
3
|
+
* SPDX-License-Identifier: MIT
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import React, { useMemo } from 'react';
|
|
7
|
+
|
|
8
|
+
import { I18n } from '@flowgram.ai/editor';
|
|
9
|
+
import { Input } from '@douyinfe/semi-ui';
|
|
10
|
+
|
|
11
|
+
import { InjectDynamicValueInput } from '@/components/dynamic-value-input';
|
|
12
|
+
|
|
13
|
+
import { DBConditionOptionType, DBConditionRowValueType, IRules, OpConfigs } from './types';
|
|
14
|
+
import { UIContainer, UILeft, UIOperator, UIRight, UIValues } from './styles';
|
|
15
|
+
import { useOp } from './hooks/use-op';
|
|
16
|
+
import { useLeft } from './hooks/use-left';
|
|
17
|
+
|
|
18
|
+
interface PropTypes {
|
|
19
|
+
value?: DBConditionRowValueType;
|
|
20
|
+
onChange: (value?: DBConditionRowValueType) => void;
|
|
21
|
+
style?: React.CSSProperties;
|
|
22
|
+
options?: DBConditionOptionType[];
|
|
23
|
+
readonly?: boolean;
|
|
24
|
+
ruleConfig?: {
|
|
25
|
+
ops?: OpConfigs;
|
|
26
|
+
rules?: IRules;
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const defaultRuleConfig = {
|
|
31
|
+
ops: {},
|
|
32
|
+
rules: {},
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export function DBConditionRow({
|
|
36
|
+
style,
|
|
37
|
+
value,
|
|
38
|
+
onChange,
|
|
39
|
+
readonly,
|
|
40
|
+
options,
|
|
41
|
+
ruleConfig = defaultRuleConfig,
|
|
42
|
+
}: PropTypes) {
|
|
43
|
+
const { left, operator, right } = value || {};
|
|
44
|
+
|
|
45
|
+
const { rule, renderDBOptionSelect } = useLeft({
|
|
46
|
+
left,
|
|
47
|
+
options,
|
|
48
|
+
onChange: (leftKey) => onChange({ ...value, left: leftKey }),
|
|
49
|
+
readonly,
|
|
50
|
+
userRules: ruleConfig.rules,
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
const { renderOpSelect, opConfig } = useOp({
|
|
54
|
+
rule,
|
|
55
|
+
op: operator,
|
|
56
|
+
onChange: (v) => onChange({ ...value, operator: v }),
|
|
57
|
+
readonly,
|
|
58
|
+
userOps: ruleConfig.ops,
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
const targetSchema = useMemo(() => {
|
|
62
|
+
const targetType: string | null = rule?.[operator || ''] || null;
|
|
63
|
+
return targetType ? { type: targetType, extra: { weak: true } } : null;
|
|
64
|
+
}, [rule, opConfig]);
|
|
65
|
+
|
|
66
|
+
return (
|
|
67
|
+
<UIContainer style={style}>
|
|
68
|
+
<UIOperator>{renderOpSelect()}</UIOperator>
|
|
69
|
+
<UIValues>
|
|
70
|
+
<UILeft>{renderDBOptionSelect()}</UILeft>
|
|
71
|
+
<UIRight>
|
|
72
|
+
{targetSchema ? (
|
|
73
|
+
<InjectDynamicValueInput
|
|
74
|
+
readonly={readonly || !rule}
|
|
75
|
+
value={right}
|
|
76
|
+
schema={targetSchema}
|
|
77
|
+
onChange={(v) => onChange({ ...value, right: v })}
|
|
78
|
+
/>
|
|
79
|
+
) : (
|
|
80
|
+
<Input
|
|
81
|
+
size="small"
|
|
82
|
+
disabled
|
|
83
|
+
style={{ pointerEvents: 'none' }}
|
|
84
|
+
value={opConfig?.rightDisplay || I18n.t('Empty')}
|
|
85
|
+
/>
|
|
86
|
+
)}
|
|
87
|
+
</UIRight>
|
|
88
|
+
</UIValues>
|
|
89
|
+
</UIContainer>
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export { type DBConditionRowValueType, type DBConditionOptionType };
|
|
@@ -0,0 +1,43 @@
|
|
|
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
|
+
import { Select } from '@douyinfe/semi-ui';
|
|
8
|
+
|
|
9
|
+
export const UIContainer = styled.div`
|
|
10
|
+
display: flex;
|
|
11
|
+
align-items: center;
|
|
12
|
+
gap: 4px;
|
|
13
|
+
`;
|
|
14
|
+
|
|
15
|
+
export const UIOperator = styled.div``;
|
|
16
|
+
|
|
17
|
+
export const UILeft = styled.div`
|
|
18
|
+
width: 100%;
|
|
19
|
+
`;
|
|
20
|
+
|
|
21
|
+
export const UIRight = styled.div`
|
|
22
|
+
width: 100%;
|
|
23
|
+
`;
|
|
24
|
+
|
|
25
|
+
export const UIValues = styled.div`
|
|
26
|
+
flex-grow: 1;
|
|
27
|
+
display: flex;
|
|
28
|
+
flex-direction: column;
|
|
29
|
+
align-items: center;
|
|
30
|
+
gap: 4px;
|
|
31
|
+
`;
|
|
32
|
+
|
|
33
|
+
export const UIOptionLabel = styled.div`
|
|
34
|
+
display: flex;
|
|
35
|
+
align-items: center;
|
|
36
|
+
gap: 10px;
|
|
37
|
+
`;
|
|
38
|
+
|
|
39
|
+
export const UISelect = styled(Select)`
|
|
40
|
+
& .semi-select-selection {
|
|
41
|
+
margin-left: 5px;
|
|
42
|
+
}
|
|
43
|
+
`;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
|
|
3
|
+
* SPDX-License-Identifier: MIT
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { IJsonSchema } from '@flowgram.ai/json-schema';
|
|
7
|
+
|
|
8
|
+
import { IFlowConstantRefValue } from '@/typings';
|
|
9
|
+
|
|
10
|
+
export interface OpConfig {
|
|
11
|
+
label: string;
|
|
12
|
+
abbreviation: string;
|
|
13
|
+
// When right is not a value, display this text
|
|
14
|
+
rightDisplay?: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export type OpConfigs = Record<string, OpConfig>;
|
|
18
|
+
|
|
19
|
+
export type IRule = Partial<Record<string, string | null>>;
|
|
20
|
+
|
|
21
|
+
export type IRules = Record<string, IRule>;
|
|
22
|
+
|
|
23
|
+
export interface DBConditionRowValueType {
|
|
24
|
+
left?: string;
|
|
25
|
+
schema?: IJsonSchema;
|
|
26
|
+
operator?: string;
|
|
27
|
+
right?: IFlowConstantRefValue;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface DBConditionOptionType {
|
|
31
|
+
label: string | JSX.Element;
|
|
32
|
+
value: string;
|
|
33
|
+
schema: IJsonSchema;
|
|
34
|
+
}
|
package/src/components/index.ts
CHANGED
|
@@ -10,6 +10,7 @@ export * from './batch-variable-selector';
|
|
|
10
10
|
export * from './constant-input';
|
|
11
11
|
export * from './dynamic-value-input';
|
|
12
12
|
export * from './condition-row';
|
|
13
|
+
export * from './db-condition-row';
|
|
13
14
|
export * from './batch-outputs';
|
|
14
15
|
export * from './prompt-editor';
|
|
15
16
|
export * from './prompt-editor-with-variables';
|
|
@@ -0,0 +1,69 @@
|
|
|
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 { I18n } from '@flowgram.ai/editor';
|
|
9
|
+
import { transformerCreator } from '@coze-editor/editor/preset-code';
|
|
10
|
+
import { Text } from '@coze-editor/editor/language-json';
|
|
11
|
+
|
|
12
|
+
import { CodeEditor, type CodeEditorPropsType } from '@/components/code-editor';
|
|
13
|
+
|
|
14
|
+
import { VariableTree } from './extensions/variable-tree';
|
|
15
|
+
import { VariableTagInject } from './extensions/variable-tag';
|
|
16
|
+
|
|
17
|
+
type Match = { match: string; range: [number, number] };
|
|
18
|
+
function findAllMatches(inputString: string, regex: RegExp): Match[] {
|
|
19
|
+
const globalRegex = new RegExp(
|
|
20
|
+
regex,
|
|
21
|
+
regex.flags.includes('g') ? regex.flags : regex.flags + 'g'
|
|
22
|
+
);
|
|
23
|
+
let match;
|
|
24
|
+
const matches: Match[] = [];
|
|
25
|
+
|
|
26
|
+
while ((match = globalRegex.exec(inputString)) !== null) {
|
|
27
|
+
if (match.index === globalRegex.lastIndex) {
|
|
28
|
+
globalRegex.lastIndex++;
|
|
29
|
+
}
|
|
30
|
+
matches.push({
|
|
31
|
+
match: match[0],
|
|
32
|
+
range: [match.index, match.index + match[0].length],
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return matches;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const transformer = transformerCreator((text: Text) => {
|
|
40
|
+
const originalSource = text.toString();
|
|
41
|
+
const matches = findAllMatches(originalSource, /\{\{([^\}]*)\}\}/g);
|
|
42
|
+
|
|
43
|
+
if (matches.length > 0) {
|
|
44
|
+
matches.forEach(({ range }) => {
|
|
45
|
+
text.replaceRange(range[0], range[1], 'null');
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return text;
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
export interface JsonEditorWithVariablesProps extends Omit<CodeEditorPropsType, 'languageId'> {}
|
|
53
|
+
|
|
54
|
+
export function JsonEditorWithVariables(props: JsonEditorWithVariablesProps) {
|
|
55
|
+
return (
|
|
56
|
+
<CodeEditor
|
|
57
|
+
languageId="json"
|
|
58
|
+
activeLinePlaceholder={I18n.t("Press '@' to Select variable")}
|
|
59
|
+
{...props}
|
|
60
|
+
options={{
|
|
61
|
+
transformer,
|
|
62
|
+
...(props.options || {}),
|
|
63
|
+
}}
|
|
64
|
+
>
|
|
65
|
+
<VariableTree />
|
|
66
|
+
<VariableTagInject />
|
|
67
|
+
</CodeEditor>
|
|
68
|
+
);
|
|
69
|
+
}
|