Commit 0a35b13e28d41974d089b34b1693ab2c7dec4f01

Authored by 陈洋
2 parents fd918200 bbc9ad99

Merge remote-tracking branch 'origin/feature/dataflow' into feature/dataflow

1 { 1 {
2 "name": "@qx/common", 2 "name": "@qx/common",
3 - "version": "3.0.0-alpha.22", 3 + "version": "3.0.0-alpha.23",
4 "description": "A react library developed with dumi", 4 "description": "A react library developed with dumi",
5 "license": "MIT", 5 "license": "MIT",
6 "module": "dist/index.js", 6 "module": "dist/index.js",
@@ -680,6 +680,8 @@ export const QxBaseConditionItem: React.FC<QxBaseConditionItemProps> = ({ @@ -680,6 +680,8 @@ export const QxBaseConditionItem: React.FC<QxBaseConditionItemProps> = ({
680 mode = 'condition', 680 mode = 'condition',
681 node, 681 node,
682 nodes, 682 nodes,
  683 + subset,
  684 + params
683 }) => { 685 }) => {
684 const valuesObj = value?.valuesObj?.[0] || {}; 686 const valuesObj = value?.valuesObj?.[0] || {};
685 const [open, setOpen] = useState(false); 687 const [open, setOpen] = useState(false);
@@ -731,6 +733,8 @@ export const QxBaseConditionItem: React.FC<QxBaseConditionItemProps> = ({ @@ -731,6 +733,8 @@ export const QxBaseConditionItem: React.FC<QxBaseConditionItemProps> = ({
731 node: node, 733 node: node,
732 nodes: nodes, 734 nodes: nodes,
733 limitTypes: [field.fieldType], 735 limitTypes: [field.fieldType],
  736 + value: valuesObj?.value,
  737 + subset
734 }); 738 });
735 739
736 const getName = (values: any[]) => { 740 const getName = (values: any[]) => {
@@ -740,6 +744,7 @@ export const QxBaseConditionItem: React.FC<QxBaseConditionItemProps> = ({ @@ -740,6 +744,7 @@ export const QxBaseConditionItem: React.FC<QxBaseConditionItemProps> = ({
740 const RenderContent = ( 744 const RenderContent = (
741 <> 745 <>
742 <QxFieldSetter 746 <QxFieldSetter
  747 + params={params || field?.params}
743 value={value?.valuesObj} 748 value={value?.valuesObj}
744 fieldGroupType={value?.fieldGroupType} 749 fieldGroupType={value?.fieldGroupType}
745 onChange={handleChange} 750 onChange={handleChange}
@@ -747,6 +752,7 @@ export const QxBaseConditionItem: React.FC<QxBaseConditionItemProps> = ({ @@ -747,6 +752,7 @@ export const QxBaseConditionItem: React.FC<QxBaseConditionItemProps> = ({
747 isRange={optValTypeCheck.isRangeType(value?.opt)} 752 isRange={optValTypeCheck.isRangeType(value?.opt)}
748 disabled={optValTypeCheck.isEmptyType(value?.opt)} 753 disabled={optValTypeCheck.isEmptyType(value?.opt)}
749 getName={getName} 754 getName={getName}
  755 + widget={field.extract?.widget}
750 /> 756 />
751 {mode === 'variable' && ( 757 {mode === 'variable' && (
752 <ControlOutlined 758 <ControlOutlined
@@ -812,6 +818,7 @@ export const QxBaseConditionItem: React.FC<QxBaseConditionItemProps> = ({ @@ -812,6 +818,7 @@ export const QxBaseConditionItem: React.FC<QxBaseConditionItemProps> = ({
812 value={valuesObj?.value} 818 value={valuesObj?.value}
813 onChange={handleAssignment} 819 onChange={handleAssignment}
814 limitTypes={[field.fieldType]} 820 limitTypes={[field.fieldType]}
  821 + subset={subset}
815 > 822 >
816 {RenderContent} 823 {RenderContent}
817 </QxFlowNodeFieldSelector> 824 </QxFlowNodeFieldSelector>
@@ -841,5 +848,6 @@ export interface QxBaseConditionItemProps { @@ -841,5 +848,6 @@ export interface QxBaseConditionItemProps {
841 mode?: string; 848 mode?: string;
842 node?: INode; 849 node?: INode;
843 nodes?: INode[]; 850 nodes?: INode[];
  851 + [key: string]: any
844 // customDisplay?: (val: string) => React.ReactNode; 852 // customDisplay?: (val: string) => React.ReactNode;
845 } 853 }
1 import React, { useEffect, useState } from 'react'; 1 import React, { useEffect, useState } from 'react';
2 import { QxBaseConditionItem } from '../qx-base-condition-item'; 2 import { QxBaseConditionItem } from '../qx-base-condition-item';
3 -import './index.less';  
4 import { INode } from '../qx-flow-node-selector'; 3 import { INode } from '../qx-flow-node-selector';
  4 +import './index.less';
5 5
6 -export enum FieldBaseType {  
7 - STRING = 'TEXT',  
8 - DOUBLE = 'NUM',  
9 - YEAR_SEC = 'DATE',  
10 -} 6 +const FieldBaseType = {
  7 + STRING: 'TEXT',
  8 + DOUBLE: 'NUM',
  9 + NUMBER: 'NUM',
  10 + YEAR_SEC: 'DATE',
  11 +};
11 12
12 export const QxBaseCondition: React.FC<QxBaseConditionProps> = (props) => { 13 export const QxBaseCondition: React.FC<QxBaseConditionProps> = (props) => {
13 const [localOptions, setLocalOptions] = useState(props.options || []); 14 const [localOptions, setLocalOptions] = useState(props.options || []);
14 15
15 const getDefaultConditionOptions = (item: QxBaseConditionField) => ({ 16 const getDefaultConditionOptions = (item: QxBaseConditionField) => ({
16 ...item, 17 ...item,
17 - // @ts-ignore  
18 - fieldGroupType: FieldBaseType[item.fieldType] || 'TEXT', 18 + fieldGroupType:
  19 + FieldBaseType[item.fieldType] ||
  20 + item.fieldGroupType ||
  21 + item.fieldType ||
  22 + 'TEXT',
19 mappingValues: [], 23 mappingValues: [],
20 opt: 'IS', 24 opt: 'IS',
21 valuesObj: [], 25 valuesObj: [],
@@ -49,7 +53,7 @@ export const QxBaseCondition: React.FC<QxBaseConditionProps> = (props) => { @@ -49,7 +53,7 @@ export const QxBaseCondition: React.FC<QxBaseConditionProps> = (props) => {
49 )} 53 )}
50 <QxBaseConditionItem 54 <QxBaseConditionItem
51 key={item.code || key} 55 key={item.code || key}
52 - mode={props.mode} 56 + mode={props.mode || 'condition'}
53 {...item} 57 {...item}
54 value={Object.assign( 58 value={Object.assign(
55 {}, 59 {},
@@ -59,6 +63,7 @@ export const QxBaseCondition: React.FC<QxBaseConditionProps> = (props) => { @@ -59,6 +63,7 @@ export const QxBaseCondition: React.FC<QxBaseConditionProps> = (props) => {
59 nodes={props.nodes} 63 nodes={props.nodes}
60 node={props.node} 64 node={props.node}
61 field={item} 65 field={item}
  66 + subset={props.subset}
62 onChange={(val) => handleItemChange(val, key)} 67 onChange={(val) => handleItemChange(val, key)}
63 remove={() => handleDelete(key)} 68 remove={() => handleDelete(key)}
64 /> 69 />
@@ -74,11 +79,12 @@ export const QxBaseCondition: React.FC<QxBaseConditionProps> = (props) => { @@ -74,11 +79,12 @@ export const QxBaseCondition: React.FC<QxBaseConditionProps> = (props) => {
74 79
75 export interface QxBaseConditionField { 80 export interface QxBaseConditionField {
76 field: string; 81 field: string;
77 - fieldType: string; 82 + fieldType: keyof typeof FieldBaseType;
78 fieldName: string; 83 fieldName: string;
79 fieldGroupType: string; 84 fieldGroupType: string;
80 qxProps?: string; 85 qxProps?: string;
81 - extract?: any; 86 + extract: any;
  87 + params?: any
82 } 88 }
83 89
84 export interface QxBaseConditionOptionsProps extends QxBaseConditionField { 90 export interface QxBaseConditionOptionsProps extends QxBaseConditionField {
@@ -96,6 +102,7 @@ export interface QxBaseConditionProps { @@ -96,6 +102,7 @@ export interface QxBaseConditionProps {
96 options: QxBaseConditionOptionsProps[]; 102 options: QxBaseConditionOptionsProps[];
97 value: any[]; 103 value: any[];
98 onChange?: (val: any[]) => void; 104 onChange?: (val: any[]) => void;
99 - nodes?: INode[]  
100 - node?: INode 105 + nodes?: INode[];
  106 + node?: INode;
  107 + subset?: boolean;
101 } 108 }
@@ -80,6 +80,7 @@ export const AddressSetter: React.FC<InputSetterProps> = ({ value, onChange, ... @@ -80,6 +80,7 @@ export const AddressSetter: React.FC<InputSetterProps> = ({ value, onChange, ...
80 closable 80 closable
81 onClose={(e) => removeItem(e, item)} 81 onClose={(e) => removeItem(e, item)}
82 onClick={(e) => e.stopPropagation()} 82 onClick={(e) => e.stopPropagation()}
  83 + bordered={false}
83 > 84 >
84 {/*// @ts-ignore*/} 85 {/*// @ts-ignore*/}
85 {props.getName && props.getName([item])} 86 {props.getName && props.getName([item])}
@@ -95,6 +96,7 @@ export const AddressSetter: React.FC<InputSetterProps> = ({ value, onChange, ... @@ -95,6 +96,7 @@ export const AddressSetter: React.FC<InputSetterProps> = ({ value, onChange, ...
95 placeholder="请选择" 96 placeholder="请选择"
96 disabled={props.disabled} 97 disabled={props.disabled}
97 onChange={handleManualChange} 98 onChange={handleManualChange}
  99 + schema={{}}
98 /> 100 />
99 )} 101 )}
100 </> 102 </>
@@ -76,6 +76,7 @@ export const InputSetter: React.FC<InputSetterProps> = ({ value, onChange, ...pr @@ -76,6 +76,7 @@ export const InputSetter: React.FC<InputSetterProps> = ({ value, onChange, ...pr
76 title={props.getCompleteName && props.getCompleteName([item])} 76 title={props.getCompleteName && props.getCompleteName([item])}
77 onClose={(e) => removeItem(e, item)} 77 onClose={(e) => removeItem(e, item)}
78 onClick={(e) => e.stopPropagation()} 78 onClick={(e) => e.stopPropagation()}
  79 + bordered={false}
79 > 80 >
80 {props.getName && props.getName([item])} 81 {props.getName && props.getName([item])}
81 </Tag> 82 </Tag>
@@ -217,6 +217,7 @@ export const OrgSetter: React.FC<OrgSetterProps> = ({ @@ -217,6 +217,7 @@ export const OrgSetter: React.FC<OrgSetterProps> = ({
217 closable 217 closable
218 onClose={(e) => removeItem(e, id)} 218 onClose={(e) => removeItem(e, id)}
219 onClick={(e) => e.stopPropagation()} 219 onClick={(e) => e.stopPropagation()}
  220 + bordered={false}
220 > 221 >
221 {valueMap[id]} 222 {valueMap[id]}
222 </Tag> 223 </Tag>
@@ -265,6 +265,7 @@ export const RelSetter: React.FC<UserSelectProps> = ({ @@ -265,6 +265,7 @@ export const RelSetter: React.FC<UserSelectProps> = ({
265 closable 265 closable
266 onClose={(e) => removeItem(e, item.value)} 266 onClose={(e) => removeItem(e, item.value)}
267 onClick={(e) => e.stopPropagation()} 267 onClick={(e) => e.stopPropagation()}
  268 + bordered={false}
268 > 269 >
269 {valueMap[item.value]} 270 {valueMap[item.value]}
270 </Tag> 271 </Tag>
@@ -287,6 +287,7 @@ export const RelTreeSetter: React.FC<UserSelectProps> = ({ @@ -287,6 +287,7 @@ export const RelTreeSetter: React.FC<UserSelectProps> = ({
287 closable 287 closable
288 onClose={(e) => removeItem(e, item.value)} 288 onClose={(e) => removeItem(e, item.value)}
289 onClick={(e) => e.stopPropagation()} 289 onClick={(e) => e.stopPropagation()}
  290 + bordered={false}
290 > 291 >
291 {valueMap[item.value]} 292 {valueMap[item.value]}
292 </Tag> 293 </Tag>
@@ -219,6 +219,7 @@ export const UserSetter: React.FC<UserSelectProps> = ({ @@ -219,6 +219,7 @@ export const UserSetter: React.FC<UserSelectProps> = ({
219 closable 219 closable
220 onClose={(e) => removeItem(e, id)} 220 onClose={(e) => removeItem(e, id)}
221 onClick={(e) => e.stopPropagation()} 221 onClick={(e) => e.stopPropagation()}
  222 + bordered={false}
222 > 223 >
223 {valueMap[id]} 224 {valueMap[id]}
224 </Tag> 225 </Tag>
@@ -3,7 +3,7 @@ import { QxWidgetIcon } from '@qx/common'; @@ -3,7 +3,7 @@ import { QxWidgetIcon } from '@qx/common';
3 import { Collapse, Dropdown, Empty, Tag } from 'antd'; 3 import { Collapse, Dropdown, Empty, Tag } from 'antd';
4 import cls from 'classnames'; 4 import cls from 'classnames';
5 import { cloneDeep } from 'lodash-es'; 5 import { cloneDeep } from 'lodash-es';
6 -import React, { useEffect, useMemo, useState } from 'react'; 6 +import React, { useEffect, useState } from 'react';
7 import { QxBaseIcon } from '../qx-base-icon'; 7 import { QxBaseIcon } from '../qx-base-icon';
8 import { request } from '../utils'; 8 import { request } from '../utils';
9 import './index.less'; 9 import './index.less';
@@ -68,6 +68,8 @@ interface NodeFieldDisPlay { @@ -68,6 +68,8 @@ interface NodeFieldDisPlay {
68 node?: INode; 68 node?: INode;
69 nodes?: INode[]; 69 nodes?: INode[];
70 limitTypes?: string[]; 70 limitTypes?: string[];
  71 + value?: string;
  72 + subset?: boolean;
71 } 73 }
72 74
73 const icon = (icon: any) => { 75 const icon = (icon: any) => {
@@ -85,52 +87,18 @@ export const useNodeFieldDisplay = ({ @@ -85,52 +87,18 @@ export const useNodeFieldDisplay = ({
85 node, 87 node,
86 nodes, 88 nodes,
87 limitTypes, 89 limitTypes,
  90 + value,
  91 + subset = true,
88 }: NodeFieldDisPlay) => { 92 }: NodeFieldDisPlay) => {
89 - const sourceParentNodes = 93 + const sourceParentNodes = cloneDeep(
90 getParentNodes(node, nodes).filter( 94 getParentNodes(node, nodes).filter(
91 (node) => !['default_DF_BRANCH'].includes(node.type), 95 (node) => !['default_DF_BRANCH'].includes(node.type),
92 - ) || [];  
93 -  
94 - const optionalNodes = useMemo(() => {  
95 - const targetParentNodes = cloneDeep(sourceParentNodes);  
96 - if (!limitTypes) return targetParentNodes;  
97 -  
98 - function getEffectiveNodes(nodes: INode[]) {  
99 - return nodes.reduce<INode[]>((pre, cur) => {  
100 - const curNode = cur;  
101 -  
102 - if (Array.isArray(curNode.data?.result)) {  
103 - const resultNodes = (curNode.data.result as FiledType[]).filter(  
104 - (i) => {  
105 - if (i.child && Array.isArray(i.child)) {  
106 - // eslint-disable-next-line @typescript-eslint/no-use-before-define  
107 - i.child = getEffectiveResult(i.child);  
108 - }  
109 - return limitTypes!.includes(i.type);  
110 - },  
111 - );  
112 -  
113 - if (resultNodes?.length) {  
114 - curNode.data.result = resultNodes;  
115 - pre.push(curNode);  
116 - }  
117 - }  
118 -  
119 - return pre;  
120 - }, []);  
121 - }  
122 -  
123 - function getEffectiveResult(result: FiledType[]) {  
124 - return result.filter((item) => {  
125 - if (item.child && Array.isArray(item.child)) {  
126 - item.child = getEffectiveResult(item.child);  
127 - }  
128 - return limitTypes?.includes(item.fieldType);  
129 - });  
130 - } 96 + ) || [],
  97 + );
131 98
132 - return getEffectiveNodes(targetParentNodes);  
133 - }, [limitTypes, sourceParentNodes]); 99 + // const [targetParentNodes, setTargetParentNodes] = useState(sourceParentNodes)
  100 + const [inputDisplay, setInputDisplay] = useState<React.ReactNode>();
  101 + const [optionalNodes, setOptionalNodes] = useState<INode[]>([]); // 根据 fieldType 过滤后的 nodes
134 102
135 const getId = (val?: string) => { 103 const getId = (val?: string) => {
136 if (!val) return; 104 if (!val) return;
@@ -150,11 +118,12 @@ export const useNodeFieldDisplay = ({ @@ -150,11 +118,12 @@ export const useNodeFieldDisplay = ({
150 let index = 0; 118 let index = 0;
151 while (n && index <= 20) { 119 while (n && index <= 20) {
152 displayConfig = []; 120 displayConfig = [];
153 - const curNode = optionalNodes[index] || {}; 121 + // eslint-disable-next-line @typescript-eslint/no-use-before-define
  122 + const curNode = cloneDeep(optionalNodes[index]) || {};
154 displayConfig.push({ 123 displayConfig.push({
155 title: curNode.name, 124 title: curNode.name,
156 icon: curNode.icon, 125 icon: curNode.icon,
157 - ...(optionalNodes[index] || {}), 126 + ...curNode,
158 }); 127 });
159 // eslint-disable-next-line @typescript-eslint/no-use-before-define 128 // eslint-disable-next-line @typescript-eslint/no-use-before-define
160 recursionNodeResult(curNode.data?.result); 129 recursionNodeResult(curNode.data?.result);
@@ -187,20 +156,13 @@ export const useNodeFieldDisplay = ({ @@ -187,20 +156,13 @@ export const useNodeFieldDisplay = ({
187 return ( 156 return (
188 <> 157 <>
189 {displayConfig?.map((item, idx) => ( 158 {displayConfig?.map((item, idx) => (
190 - <div  
191 - key={idx}  
192 - className='qx-node-select-input__content-item'  
193 - > 159 + <div key={idx} className="qx-node-select-input__content-item">
194 {item.icon && ( 160 {item.icon && (
195 - <span  
196 - className='qx-node-select-input__content-item__icon'  
197 - > 161 + <span className="qx-node-select-input__content-item__icon">
198 {icon(item.icon)} 162 {icon(item.icon)}
199 </span> 163 </span>
200 )} 164 )}
201 - <span  
202 - className='qx-node-select-input__content-item__text'  
203 - > 165 + <span className="qx-node-select-input__content-item__text">
204 {item.type && 166 {item.type &&
205 FileTypeMap[item.type] && 167 FileTypeMap[item.type] &&
206 !item.icon && 168 !item.icon &&
@@ -208,9 +170,7 @@ export const useNodeFieldDisplay = ({ @@ -208,9 +170,7 @@ export const useNodeFieldDisplay = ({
208 {item.title} 170 {item.title}
209 </span> 171 </span>
210 {idx !== displayConfig.length - 1 && ( 172 {idx !== displayConfig.length - 1 && (
211 - <span  
212 - className='qx-node-select-input__content-item__arrow'  
213 - > 173 + <span className="qx-node-select-input__content-item__arrow">
214 <svg 174 <svg
215 xmlns="http://www.w3.org/2000/svg" 175 xmlns="http://www.w3.org/2000/svg"
216 width="1em" 176 width="1em"
@@ -227,9 +187,137 @@ export const useNodeFieldDisplay = ({ @@ -227,9 +187,137 @@ export const useNodeFieldDisplay = ({
227 ); 187 );
228 }; 188 };
229 189
  190 + const renderInputDisplay = (val: string = value || '') => {
  191 + setInputDisplay(
  192 + <Tag bordered={false} className="qx-node-select-input__content">
  193 + {genDisplayDom(val)}
  194 + </Tag>,
  195 + );
  196 + };
  197 +
  198 + /***
  199 + * 查找有 formId 的 result
  200 + */
  201 + const findResultByFormId = () => {
  202 + const forms: FiledType[] = [];
  203 + sourceParentNodes.forEach((node) => {
  204 + if (Array.isArray(node.data?.result)) {
  205 + // eslint-disable-next-line @typescript-eslint/no-use-before-define
  206 + recursionNodeResult(node.data?.result);
  207 + }
  208 + });
  209 +
  210 + function recursionNodeResult(result: FiledType[] | FiledType) {
  211 + if (!Array.isArray(result) && result) {
  212 + if (result.qxProps && result.qxProps?.formId) {
  213 + forms.push(result);
  214 + }
  215 + }
  216 + if (Array.isArray(result)) {
  217 + result.forEach((i) => {
  218 + if (i.qxProps && i.qxProps?.formId) {
  219 + forms.push(i);
  220 + } else if (i.child) {
  221 + recursionNodeResult(i.child);
  222 + }
  223 + });
  224 + }
  225 + }
  226 +
  227 + return forms;
  228 + };
  229 +
  230 + /**
  231 + * 查询所有 formId 的字段,并给 result 添加 child
  232 + */
  233 + const handleGetAppsFields = async () => {
  234 + const forms = findResultByFormId();
  235 + const ids = forms.map((item) => item.qxProps?.formId);
  236 + if (Array.isArray(ids) && ids.length && subset) {
  237 + try {
  238 + const data = await getAppsFields(ids as any[]);
  239 + Object.keys(data).forEach((id) => {
  240 + const form = forms.find((item) => item.qxProps?.formId === id);
  241 + if (!form) return;
  242 +
  243 + const childItem = data[id].map((item: FiledType) => ({
  244 + ...item,
  245 + icon: (
  246 + <span className="qx-node-select-item__icon">
  247 + <QxWidgetIcon widgetName={item.extract?.widget || 'qxInput'} />
  248 + </span>
  249 + ),
  250 + title: item.name,
  251 + id: item.code,
  252 + type: item.extract?.fieldType,
  253 + }));
  254 +
  255 + if (Array.isArray(form.child)) {
  256 + form.child.push(childItem);
  257 + } else {
  258 + form.child = childItem;
  259 + }
  260 + });
  261 + // console.log(2222222, targetParentNodes, forms);
  262 + } catch (error) {
  263 + // appsFields = {};
  264 + } finally {
  265 + renderInputDisplay();
  266 + }
  267 + }
  268 + return sourceParentNodes;
  269 + };
  270 +
  271 + const getOptionalNodes = async () => {
  272 + const targetParentNodes = await handleGetAppsFields();
  273 + if (!limitTypes) return setOptionalNodes(targetParentNodes);
  274 +
  275 + function getEffectiveResult(result: FiledType[]) {
  276 + const newResult = [];
  277 + for (let i = 0; i < result.length; i++) {
  278 + const resultItem = result[i] || {};
  279 + if (resultItem.child) {
  280 + resultItem.child = getEffectiveResult(resultItem.child);
  281 + if (
  282 + (Array.isArray(resultItem.child) && resultItem.child.length) ||
  283 + limitTypes?.includes(resultItem.type)
  284 + ) {
  285 + newResult.push(resultItem);
  286 + }
  287 + } else if (limitTypes?.includes(resultItem.type)) {
  288 + newResult.push(resultItem);
  289 + }
  290 + }
  291 +
  292 + return newResult;
  293 + }
  294 +
  295 + function getEffectiveNodes(nodes: INode[]) {
  296 + for (let i = 0; i <= nodes.length; i++) {
  297 + const node = nodes[i] || {};
  298 + const nodeResult = node.data?.result;
  299 + if (Array.isArray(nodeResult) && nodeResult.length) {
  300 + node.data.result = getEffectiveResult(nodeResult);
  301 + }
  302 + }
  303 +
  304 + return nodes;
  305 + }
  306 +
  307 + const newNodes = getEffectiveNodes(targetParentNodes);
  308 + setOptionalNodes([...newNodes]);
  309 + };
  310 +
  311 + useEffect(() => {
  312 + getOptionalNodes();
  313 + }, []);
  314 +
230 return { 315 return {
231 genDisplayDom, 316 genDisplayDom,
232 optionalNodes, 317 optionalNodes,
  318 + // targetParentNodes,
  319 + renderInputDisplay,
  320 + inputDisplay,
233 }; 321 };
234 }; 322 };
235 323
@@ -266,7 +354,7 @@ const SelectItem = (props: any) => { @@ -266,7 +354,7 @@ const SelectItem = (props: any) => {
266 ); 354 );
267 } 355 }
268 356
269 - if (!props.child) { 357 + if (!props.child || !props.child.length) {
270 return ( 358 return (
271 <div 359 <div
272 className={cls('qx-node-select-item')} 360 className={cls('qx-node-select-item')}
@@ -317,14 +405,10 @@ export const QxFlowNodeFieldSelector: React.FC<NodeFieldSelectProps> = ( @@ -317,14 +405,10 @@ export const QxFlowNodeFieldSelector: React.FC<NodeFieldSelectProps> = (
317 405
318 const [visible, setVisible] = useState(false); 406 const [visible, setVisible] = useState(false);
319 407
320 - const [inputDisplay, setInputDisplay] = useState<React.ReactNode>();  
321 -  
322 - const { optionalNodes, genDisplayDom } = useNodeFieldDisplay(props); 408 + const { optionalNodes, renderInputDisplay, inputDisplay } =
  409 + useNodeFieldDisplay(props);
323 410
324 const getOptions = () => { 411 const getOptions = () => {
325 - if (!optionalNodes.length) {  
326 - return <Empty />;  
327 - }  
328 return optionalNodes.map((node) => ({ 412 return optionalNodes.map((node) => ({
329 label: ( 413 label: (
330 <div className={cls('qx-node-select-dropdown-header')}> 414 <div className={cls('qx-node-select-dropdown-header')}>
@@ -352,96 +436,6 @@ export const QxFlowNodeFieldSelector: React.FC<NodeFieldSelectProps> = ( @@ -352,96 +436,6 @@ export const QxFlowNodeFieldSelector: React.FC<NodeFieldSelectProps> = (
352 })); 436 }));
353 }; 437 };
354 438
355 - const getForms = () => {  
356 - const forms: FiledType[] = [];  
357 - optionalNodes.forEach((node) => {  
358 - if (Array.isArray(node.data?.result)) {  
359 - // eslint-disable-next-line @typescript-eslint/no-use-before-define  
360 - recursionNodeResult(node.data?.result);  
361 - }  
362 - });  
363 -  
364 - function recursionNodeResult(result: FiledType[] | FiledType) {  
365 - if (!Array.isArray(result) && result) {  
366 - if (result.qxProps && result.qxProps?.formId) {  
367 - forms.push(result);  
368 - }  
369 - }  
370 - if (Array.isArray(result)) {  
371 - result.forEach((i) => {  
372 - if (i.qxProps && i.qxProps?.formId) {  
373 - forms.push(i);  
374 - } else if (i.child) {  
375 - recursionNodeResult(i.child);  
376 - }  
377 - });  
378 - }  
379 - }  
380 -  
381 - return forms;  
382 - };  
383 -  
384 - const renderInputDisplay = (val: string = props.value || '') => {  
385 - setInputDisplay(  
386 - <Tag bordered={false} className="qx-node-select-input__content">  
387 - {genDisplayDom(val)}  
388 - </Tag>,  
389 - );  
390 - };  
391 -  
392 - const handleGetAppsFields = async () => {  
393 - const forms = getForms();  
394 - const ids = forms.map(  
395 - (item) => item.qxProps?.formId && !props.limitTypes?.includes(item.type),  
396 - );  
397 - console.log(ids, 'ids')  
398 - if (Array.isArray(ids) && ids.length) {  
399 - try {  
400 - const data = await getAppsFields(ids as any[]);  
401 - Object.keys(data).forEach((id) => {  
402 - forms.forEach((i) => {  
403 - if (i.qxProps?.formId === id) {  
404 - if (Array.isArray(i.child)) {  
405 - i.child.push(  
406 - data[id].map((item: FiledType) => ({  
407 - icon: (  
408 - <span className="qx-node-select-item__icon">  
409 - <QxWidgetIcon  
410 - widgetName={item.extract?.widget || 'qxInput'}  
411 - />  
412 - </span>  
413 - ),  
414 - title: item.name,  
415 - code: item.code,  
416 - id: item.code,  
417 - type: item.extract?.fieldType,  
418 - })),  
419 - );  
420 - } else {  
421 - i.child = data[id].map((item: FiledType) => ({  
422 - icon: (  
423 - <span className="qx-node-select-item__icon">  
424 - <QxWidgetIcon  
425 - widgetName={item.extract?.widget || 'qxInput'}  
426 - />  
427 - </span>  
428 - ),  
429 - title: item.name,  
430 - code: item.code,  
431 - id: item.code,  
432 - type: item.extract?.fieldType,  
433 - }));  
434 - }  
435 - }  
436 - });  
437 - });  
438 - renderInputDisplay();  
439 - } catch (error) {  
440 - // appsFields = {};  
441 - }  
442 - }  
443 - };  
444 -  
445 const handleItemClick = (nodeKey: string, item: any) => { 439 const handleItemClick = (nodeKey: string, item: any) => {
446 const newValue = '${' + `${nodeKey}|${item.id}` + '}'; 440 const newValue = '${' + `${nodeKey}|${item.id}` + '}';
447 props.onChange?.(newValue, item); 441 props.onChange?.(newValue, item);
@@ -452,23 +446,27 @@ export const QxFlowNodeFieldSelector: React.FC<NodeFieldSelectProps> = ( @@ -452,23 +446,27 @@ export const QxFlowNodeFieldSelector: React.FC<NodeFieldSelectProps> = (
452 }; 446 };
453 447
454 useEffect(() => { 448 useEffect(() => {
455 - handleGetAppsFields();  
456 - }, []);  
457 -  
458 - useEffect(() => {  
459 setVisible(props.open ?? false); 449 setVisible(props.open ?? false);
460 }, [props.open]); 450 }, [props.open]);
461 451
  452 + const dropdownRender = () => {
  453 + const items = getOptions();
  454 + if (Array.isArray(items) && items.length) {
  455 + return <Collapse ghost expandIconPosition="end" items={items} />;
  456 + } else {
  457 + return <Empty />;
  458 + }
  459 + };
  460 +
462 return ( 461 return (
463 <div className={cls('qx-node-select')}> 462 <div className={cls('qx-node-select')}>
464 <Dropdown 463 <Dropdown
  464 + destroyPopupOnHide
465 trigger={['click']} 465 trigger={['click']}
466 overlayStyle={{ width: `${props?.width}px` }} 466 overlayStyle={{ width: `${props?.width}px` }}
467 overlayClassName={cls('qx-node-select-dropdown')} 467 overlayClassName={cls('qx-node-select-dropdown')}
468 open={visible} 468 open={visible}
469 - dropdownRender={() => (  
470 - <Collapse ghost expandIconPosition="end" items={getOptions()} />  
471 - )} 469 + dropdownRender={dropdownRender}
472 onOpenChange={(open) => { 470 onOpenChange={(open) => {
473 if (mode === 'select') { 471 if (mode === 'select') {
474 setVisible(open); 472 setVisible(open);
@@ -505,6 +503,7 @@ export interface NodeFieldSelectProps { @@ -505,6 +503,7 @@ export interface NodeFieldSelectProps {
505 width?: number; 503 width?: number;
506 mode?: 'select' | 'variable'; 504 mode?: 'select' | 'variable';
507 open?: boolean; 505 open?: boolean;
  506 + subset?: boolean;
508 } 507 }
509 508
510 export interface FiledType { 509 export interface FiledType {