Commit c4e52be16cbc189e678a5acb125f62a215e2790f

Authored by qiang.tian
1 parent bcaa9a07

refactor: qx-base-condition & qx-flow-node-selector

@@ -7,6 +7,7 @@ import { QxBaseIcon } from '../qx-base-icon'; @@ -7,6 +7,7 @@ import { QxBaseIcon } from '../qx-base-icon';
7 import { QxFieldSetter } from '../qx-field-setter'; 7 import { QxFieldSetter } from '../qx-field-setter';
8 import type { INode } from '../qx-flow-node-selector'; 8 import type { INode } from '../qx-flow-node-selector';
9 import { 9 import {
  10 + FieldMapType,
10 QxFlowNodeFieldSelector, 11 QxFlowNodeFieldSelector,
11 useNodeFieldDisplay, 12 useNodeFieldDisplay,
12 } from '../qx-flow-node-selector'; 13 } from '../qx-flow-node-selector';
@@ -681,7 +682,9 @@ export const QxBaseConditionItem: React.FC<QxBaseConditionItemProps> = ({ @@ -681,7 +682,9 @@ export const QxBaseConditionItem: React.FC<QxBaseConditionItemProps> = ({
681 node, 682 node,
682 nodes, 683 nodes,
683 subset, 684 subset,
684 - params 685 + params,
  686 + fieldGroupType,
  687 + isMixValue,
685 }) => { 688 }) => {
686 const valuesObj = value?.valuesObj?.[0] || {}; 689 const valuesObj = value?.valuesObj?.[0] || {};
687 const [open, setOpen] = useState(false); 690 const [open, setOpen] = useState(false);
@@ -732,36 +735,37 @@ export const QxBaseConditionItem: React.FC<QxBaseConditionItemProps> = ({ @@ -732,36 +735,37 @@ export const QxBaseConditionItem: React.FC<QxBaseConditionItemProps> = ({
732 const { genDisplayDom } = useNodeFieldDisplay({ 735 const { genDisplayDom } = useNodeFieldDisplay({
733 node: node, 736 node: node,
734 nodes: nodes, 737 nodes: nodes,
735 - limitTypes: [field.fieldType], 738 + limitTypes: [field.extract?.fieldType],
736 value: valuesObj?.value, 739 value: valuesObj?.value,
737 - subset 740 + subset,
738 }); 741 });
739 742
740 const getName = (values: any[]) => { 743 const getName = (values: any[]) => {
741 - return values.map((value) => genDisplayDom(value))  
742 - } 744 + return Array.isArray(values)
  745 + ? values.map((value) => genDisplayDom(value))
  746 + : [];
  747 + };
743 748
744 const RenderContent = ( 749 const RenderContent = (
745 <> 750 <>
746 <QxFieldSetter 751 <QxFieldSetter
747 params={params || field?.params} 752 params={params || field?.params}
748 value={value?.valuesObj} 753 value={value?.valuesObj}
749 - fieldGroupType={value?.fieldGroupType} 754 + fieldGroupType={fieldGroupType}
750 onChange={handleChange} 755 onChange={handleChange}
751 - isMultiple={multipleType.includes(value?.fieldGroupType)} 756 + isMultiple={multipleType.includes(fieldGroupType)}
752 isRange={optValTypeCheck.isRangeType(value?.opt)} 757 isRange={optValTypeCheck.isRangeType(value?.opt)}
753 disabled={optValTypeCheck.isEmptyType(value?.opt)} 758 disabled={optValTypeCheck.isEmptyType(value?.opt)}
754 getName={getName} 759 getName={getName}
755 widget={field.extract?.widget} 760 widget={field.extract?.widget}
  761 + isMixValue={isMixValue}
  762 + />
  763 + <ControlOutlined
  764 + onClick={() => {
  765 + setOpen(!open);
  766 + }}
  767 + className="qx-base-condition-item__content-suffix"
756 /> 768 />
757 - {mode === 'variable' && (  
758 - <ControlOutlined  
759 - onClick={() => {  
760 - setOpen(!open);  
761 - }}  
762 - className="qx-base-condition-item__content-suffix"  
763 - />  
764 - )}  
765 </> 769 </>
766 ); 770 );
767 771
@@ -774,7 +778,7 @@ export const QxBaseConditionItem: React.FC<QxBaseConditionItemProps> = ({ @@ -774,7 +778,7 @@ export const QxBaseConditionItem: React.FC<QxBaseConditionItemProps> = ({
774 className="qx-base-condition-item__header-filter__select" 778 className="qx-base-condition-item__header-filter__select"
775 bordered={false} 779 bordered={false}
776 fieldNames={{ label: 'text', value: 'key' }} 780 fieldNames={{ label: 'text', value: 'key' }}
777 - options={ConditionCol[value.fieldGroupType]?.operations || []} 781 + options={ConditionCol[fieldGroupType]?.operations || []}
778 onChange={handleFilerChange} 782 onChange={handleFilerChange}
779 /> 783 />
780 ); 784 );
@@ -788,10 +792,14 @@ export const QxBaseConditionItem: React.FC<QxBaseConditionItemProps> = ({ @@ -788,10 +792,14 @@ export const QxBaseConditionItem: React.FC<QxBaseConditionItemProps> = ({
788 <div className="qx-base-condition-item__header"> 792 <div className="qx-base-condition-item__header">
789 <div className="qx-base-condition-item__header-left"> 793 <div className="qx-base-condition-item__header-left">
790 <span className="qx-base-condition-item__header-icon"> 794 <span className="qx-base-condition-item__header-icon">
791 - <QxWidgetIcon widgetName={field?.extract?.widget} /> 795 + {field.extract?.widget ? (
  796 + <QxWidgetIcon widgetName={field.extract.widget} />
  797 + ) : (
  798 + `[${FieldMapType[field.extract.fieldType]}]`
  799 + )}
792 </span> 800 </span>
793 <span className="qx-base-condition-item__header-text"> 801 <span className="qx-base-condition-item__header-text">
794 - {field.fieldName} 802 + {field.name}
795 </span> 803 </span>
796 </div> 804 </div>
797 <div className="qx-base-condition-item__header-right"> 805 <div className="qx-base-condition-item__header-right">
@@ -809,22 +817,18 @@ export const QxBaseConditionItem: React.FC<QxBaseConditionItemProps> = ({ @@ -809,22 +817,18 @@ export const QxBaseConditionItem: React.FC<QxBaseConditionItemProps> = ({
809 </div> 817 </div>
810 </div> 818 </div>
811 <div className="qx-base-condition-item__content"> 819 <div className="qx-base-condition-item__content">
812 - {mode === 'variable' ? (  
813 - <QxFlowNodeFieldSelector  
814 - mode={mode}  
815 - node={node!}  
816 - nodes={nodes!}  
817 - open={open}  
818 - value={valuesObj?.value}  
819 - onChange={handleAssignment}  
820 - limitTypes={[field.fieldType]}  
821 - subset={subset}  
822 - >  
823 - {RenderContent}  
824 - </QxFlowNodeFieldSelector>  
825 - ) : (  
826 - RenderContent  
827 - )} 820 + <QxFlowNodeFieldSelector
  821 + mode="variable"
  822 + node={node!}
  823 + nodes={nodes!}
  824 + open={open}
  825 + value={valuesObj?.value}
  826 + onChange={handleAssignment}
  827 + limitTypes={[field.extract?.fieldType]}
  828 + subset={subset}
  829 + >
  830 + {RenderContent}
  831 + </QxFlowNodeFieldSelector>
828 </div> 832 </div>
829 </div> 833 </div>
830 ); 834 );
@@ -848,6 +852,6 @@ export interface QxBaseConditionItemProps { @@ -848,6 +852,6 @@ export interface QxBaseConditionItemProps {
848 mode?: string; 852 mode?: string;
849 node?: INode; 853 node?: INode;
850 nodes?: INode[]; 854 nodes?: INode[];
851 - [key: string]: any 855 + [key: string]: any;
852 // customDisplay?: (val: string) => React.ReactNode; 856 // customDisplay?: (val: string) => React.ReactNode;
853 } 857 }
1 -import React, { useEffect, useState } from 'react'; 1 +import React from 'react';
2 import { QxBaseConditionItem } from '../qx-base-condition-item'; 2 import { QxBaseConditionItem } from '../qx-base-condition-item';
3 import { INode } from '../qx-flow-node-selector'; 3 import { INode } from '../qx-flow-node-selector';
4 import './index.less'; 4 import './index.less';
@@ -11,42 +11,46 @@ const FieldBaseType = { @@ -11,42 +11,46 @@ const FieldBaseType = {
11 }; 11 };
12 12
13 export const QxBaseCondition: React.FC<QxBaseConditionProps> = (props) => { 13 export const QxBaseCondition: React.FC<QxBaseConditionProps> = (props) => {
14 - const [localOptions, setLocalOptions] = useState(props.options || []); 14 + // const [localOptions, setLocalOptions] = useState(props.value || props.options || []);
15 15
16 - const getDefaultConditionOptions = (item: QxBaseConditionField) => ({  
17 - ...item,  
18 - fieldGroupType:  
19 - FieldBaseType[item.fieldType] ||  
20 - item.fieldGroupType ||  
21 - item.fieldType ||  
22 - 'TEXT',  
23 - mappingValues: [],  
24 - opt: 'IS',  
25 - valuesObj: [],  
26 - }); 16 + const getDefaultCondition = (item: QxBaseConditionField) => {
  17 + return {
  18 + type: item.extract?.fieldType,
  19 + code: item.code,
  20 + title: item.name,
  21 + opt: 'IS',
  22 + };
  23 + };
27 24
28 const handleItemChange = (val: any, key: number) => { 25 const handleItemChange = (val: any, key: number) => {
29 props.onChange?.( 26 props.onChange?.(
30 - localOptions?.map((item, idx) => { 27 + props.value?.map((item, idx) => {
31 if (idx === key) return val; 28 if (idx === key) return val;
32 return props.value?.[idx] 29 return props.value?.[idx]
33 ? props.value?.[idx] 30 ? props.value?.[idx]
34 - : getDefaultConditionOptions(item); 31 + : getDefaultCondition(item);
35 }), 32 }),
36 ); 33 );
37 }; 34 };
38 35
39 const handleDelete = (key: number) => { 36 const handleDelete = (key: number) => {
40 - localOptions.splice(key, 1);  
41 - setLocalOptions([...localOptions]);  
42 - props.onChange?.([...localOptions]); 37 + if (props.value && Array.isArray(props.value)) {
  38 + props.value.splice(key, 1);
  39 + props.onChange?.([...props.value]);
  40 + }
43 }; 41 };
44 42
45 - useEffect(() => {  
46 - setLocalOptions(props.options);  
47 - }, [props.options]); 43 + const getFieldGroupType = (fieldExtract: QxBaseConditionField['extract']) => {
  44 + return (
  45 + fieldExtract?.fieldGroupType ||
  46 + FieldBaseType[fieldExtract.fieldType] ||
  47 + fieldExtract?.fieldType ||
  48 + 'TEXT'
  49 + );
  50 + };
48 51
49 - const RenderCondition = localOptions?.map((item, key) => ( 52 +
  53 + const RenderCondition = props.value?.map((item, key) => (
50 <div className="qx-base-condition-list-item" key={item.code || key}> 54 <div className="qx-base-condition-list-item" key={item.code || key}>
51 {(props?.showIdx ?? true) && ( 55 {(props?.showIdx ?? true) && (
52 <span className="qx-base-condition-list-item__idx">{key + 1}.</span> 56 <span className="qx-base-condition-list-item__idx">{key + 1}.</span>
@@ -55,14 +59,14 @@ export const QxBaseCondition: React.FC<QxBaseConditionProps> = (props) => { @@ -55,14 +59,14 @@ export const QxBaseCondition: React.FC<QxBaseConditionProps> = (props) => {
55 key={item.code || key} 59 key={item.code || key}
56 mode={props.mode || 'condition'} 60 mode={props.mode || 'condition'}
57 {...item} 61 {...item}
  62 + fieldGroupType={getFieldGroupType(item.field.extract)}
58 value={Object.assign( 63 value={Object.assign(
59 {}, 64 {},
60 - getDefaultConditionOptions(item), 65 + getDefaultCondition(item.field),
61 props.value?.[key] || {}, 66 props.value?.[key] || {},
62 )} 67 )}
63 nodes={props.nodes} 68 nodes={props.nodes}
64 node={props.node} 69 node={props.node}
65 - field={item}  
66 subset={props.subset} 70 subset={props.subset}
67 onChange={(val) => handleItemChange(val, key)} 71 onChange={(val) => handleItemChange(val, key)}
68 remove={() => handleDelete(key)} 72 remove={() => handleDelete(key)}
@@ -77,14 +81,21 @@ export const QxBaseCondition: React.FC<QxBaseConditionProps> = (props) => { @@ -77,14 +81,21 @@ export const QxBaseCondition: React.FC<QxBaseConditionProps> = (props) => {
77 ); 81 );
78 }; 82 };
79 83
80 -export interface QxBaseConditionField {  
81 - field: string; 84 +export interface QxBaseConditionFieldExtract {
  85 + widget: string;
  86 + $base?: boolean;
  87 + allowSelect?: boolean;
  88 + fieldKey: string;
82 fieldType: keyof typeof FieldBaseType; 89 fieldType: keyof typeof FieldBaseType;
83 - fieldName: string;  
84 - fieldGroupType: string;  
85 - qxProps?: string;  
86 - extract: any;  
87 - params?: any 90 + fieldGroupType?: string;
  91 + relId?: string;
  92 + [key: string]: any;
  93 +}
  94 +
  95 +export interface QxBaseConditionField {
  96 + name?: string;
  97 + code: string;
  98 + extract: QxBaseConditionFieldExtract;
88 } 99 }
89 100
90 export interface QxBaseConditionOptionsProps extends QxBaseConditionField { 101 export interface QxBaseConditionOptionsProps extends QxBaseConditionField {
1 -import { ControlOutlined } from '@ant-design/icons';  
2 import { QxWidgetIcon } from '@qx/common'; 1 import { QxWidgetIcon } from '@qx/common';
3 import { Collapse, Dropdown, Empty, Tag } from 'antd'; 2 import { Collapse, Dropdown, Empty, Tag } from 'antd';
4 import cls from 'classnames'; 3 import cls from 'classnames';
@@ -50,7 +49,7 @@ export const getParentNodes = ( @@ -50,7 +49,7 @@ export const getParentNodes = (
50 return parentNode; 49 return parentNode;
51 }; 50 };
52 51
53 -export enum FileTypeMap { 52 +export enum FieldMapType {
54 'STRING' = '文本', 53 'STRING' = '文本',
55 'NUMBER' = '数字', 54 'NUMBER' = '数字',
56 'BOOL' = '布尔', 55 'BOOL' = '布尔',
@@ -164,9 +163,9 @@ export const useNodeFieldDisplay = ({ @@ -164,9 +163,9 @@ export const useNodeFieldDisplay = ({
164 )} 163 )}
165 <span className="qx-node-select-input__content-item__text"> 164 <span className="qx-node-select-input__content-item__text">
166 {item.type && 165 {item.type &&
167 - FileTypeMap[item.type] && 166 + FieldMapType[item.type] &&
168 !item.icon && 167 !item.icon &&
169 - `[${FileTypeMap[item.type]}]`} 168 + `[${FieldMapType[item.type]}]`}
170 {item.title} 169 {item.title}
171 </span> 170 </span>
172 {idx !== displayConfig.length - 1 && ( 171 {idx !== displayConfig.length - 1 && (
@@ -268,14 +267,42 @@ export const useNodeFieldDisplay = ({ @@ -268,14 +267,42 @@ export const useNodeFieldDisplay = ({
268 return sourceParentNodes; 267 return sourceParentNodes;
269 }; 268 };
270 269
  270 + const correctionNodeField = (fields: FiledType[] | FiledType) => {
  271 + if (Array.isArray(fields)) {
  272 + for (let i = 0; i <= fields.length; i++) {
  273 + correctionNodeField(fields[i]);
  274 + }
  275 + } else if (fields) {
  276 + Object.assign(fields, {
  277 + ...fields,
  278 + name: fields.title,
  279 + extract: {
  280 + ...(fields.extract || {}),
  281 + fieldType: fields.type,
  282 + fieldKey: fields.code,
  283 + },
  284 + child: correctionNodeField(fields.child!),
  285 + });
  286 + }
  287 +
  288 + return fields;
  289 + };
  290 +
271 const getOptionalNodes = async () => { 291 const getOptionalNodes = async () => {
272 const targetParentNodes = await handleGetAppsFields(); 292 const targetParentNodes = await handleGetAppsFields();
  293 +
  294 + for (let i = 0; i< targetParentNodes.length;i++) {
  295 + correctionNodeField(targetParentNodes[i].data?.result || [])
  296 + }
  297 +
273 if (!limitTypes) return setOptionalNodes(targetParentNodes); 298 if (!limitTypes) return setOptionalNodes(targetParentNodes);
274 299
275 function getEffectiveResult(result: FiledType[]) { 300 function getEffectiveResult(result: FiledType[]) {
276 const newResult = []; 301 const newResult = [];
277 for (let i = 0; i < result.length; i++) { 302 for (let i = 0; i < result.length; i++) {
278 - const resultItem = result[i] || {}; 303 + const resultItem = result[i] || {};
  304 + correctionNodeField(resultItem)
  305 +
279 if (resultItem.child) { 306 if (resultItem.child) {
280 resultItem.child = getEffectiveResult(resultItem.child); 307 resultItem.child = getEffectiveResult(resultItem.child);
281 if ( 308 if (
@@ -333,8 +360,8 @@ const SelectItem = (props: any) => { @@ -333,8 +360,8 @@ const SelectItem = (props: any) => {
333 label: ( 360 label: (
334 <span> 361 <span>
335 {/* @ts-ignore */} 362 {/* @ts-ignore */}
336 - {`[${FileTypeMap[props.type]}]`}  
337 - {props.title} 363 + {`[${FieldMapType[props.extract?.fieldType]}]`}
  364 + {props.name}
338 </span> 365 </span>
339 ), 366 ),
340 key: props.id, 367 key: props.id,
@@ -361,8 +388,8 @@ const SelectItem = (props: any) => { @@ -361,8 +388,8 @@ const SelectItem = (props: any) => {
361 onClick={() => props.onClick(props)} 388 onClick={() => props.onClick(props)}
362 > 389 >
363 {/* @ts-ignore */} 390 {/* @ts-ignore */}
364 - {props.icon ? props.icon : `[${FileTypeMap[props.type]}]`}  
365 - {props.title} 391 + {props.icon ? props.icon : `[${FieldMapType[props.extract?.fieldType]}]`}
  392 + {props.name}
366 </div> 393 </div>
367 ); 394 );
368 } 395 }
@@ -377,8 +404,8 @@ const SelectItem = (props: any) => { @@ -377,8 +404,8 @@ const SelectItem = (props: any) => {
377 label: ( 404 label: (
378 <span> 405 <span>
379 {/* @ts-ignore */} 406 {/* @ts-ignore */}
380 - {`[${FileTypeMap[props.type]}]`}  
381 - {props.title} 407 + {`[${FieldMapType[props.extract?.fieldType]}]`}
  408 + {props.name}
382 </span> 409 </span>
383 ), 410 ),
384 key: props.id, 411 key: props.id,
@@ -401,14 +428,13 @@ const SelectItem = (props: any) => { @@ -401,14 +428,13 @@ const SelectItem = (props: any) => {
401 export const QxFlowNodeFieldSelector: React.FC<NodeFieldSelectProps> = ( 428 export const QxFlowNodeFieldSelector: React.FC<NodeFieldSelectProps> = (
402 props, 429 props,
403 ) => { 430 ) => {
404 - const { mode = 'select' } = props;  
405 -  
406 const [visible, setVisible] = useState(false); 431 const [visible, setVisible] = useState(false);
407 432
408 const { optionalNodes, renderInputDisplay, inputDisplay } = 433 const { optionalNodes, renderInputDisplay, inputDisplay } =
409 useNodeFieldDisplay(props); 434 useNodeFieldDisplay(props);
410 435
411 const getOptions = () => { 436 const getOptions = () => {
  437 + console.log('optionalNodes', optionalNodes);
412 return optionalNodes.map((node) => ({ 438 return optionalNodes.map((node) => ({
413 label: ( 439 label: (
414 <div className={cls('qx-node-select-dropdown-header')}> 440 <div className={cls('qx-node-select-dropdown-header')}>
@@ -468,7 +494,7 @@ export const QxFlowNodeFieldSelector: React.FC<NodeFieldSelectProps> = ( @@ -468,7 +494,7 @@ export const QxFlowNodeFieldSelector: React.FC<NodeFieldSelectProps> = (
468 open={visible} 494 open={visible}
469 dropdownRender={dropdownRender} 495 dropdownRender={dropdownRender}
470 onOpenChange={(open) => { 496 onOpenChange={(open) => {
471 - if (mode === 'select') { 497 + if (props.children) {
472 setVisible(open); 498 setVisible(open);
473 } 499 }
474 }} 500 }}
@@ -476,16 +502,11 @@ export const QxFlowNodeFieldSelector: React.FC<NodeFieldSelectProps> = ( @@ -476,16 +502,11 @@ export const QxFlowNodeFieldSelector: React.FC<NodeFieldSelectProps> = (
476 {props.children ? ( 502 {props.children ? (
477 props.children 503 props.children
478 ) : ( 504 ) : (
479 - <div className={cls('qx-node-select-input')}> 505 + <div
  506 + className={cls('qx-node-select-input')}
  507 + onClick={() => setVisible(!visible)}
  508 + >
480 {inputDisplay} 509 {inputDisplay}
481 - {mode === 'variable' && (  
482 - <span  
483 - className="qx-node-select-input__suffix"  
484 - onClick={() => setVisible(!visible)}  
485 - >  
486 - <ControlOutlined />  
487 - </span>  
488 - )}  
489 </div> 510 </div>
490 )} 511 )}
491 </Dropdown> 512 </Dropdown>