Commit 04129d565215a68f370e114fd2b5491455fccd46
Merge remote-tracking branch 'origin/feature/dataflow' into feature/dataflow
Showing
11 changed files
with
917 additions
and
180 deletions
... | ... | @@ -53,16 +53,10 @@ |
53 | 53 | color: @N7; |
54 | 54 | } |
55 | 55 | |
56 | - &-value-render { | |
57 | - position: absolute; | |
58 | - background-color: #fff; | |
59 | - width: calc(100% - 33px); | |
60 | - height: 30px; | |
61 | - display: flex; | |
62 | - align-items: center; | |
63 | - top: 1px; | |
64 | - left: 8px; | |
65 | - z-index: 1; | |
56 | + .qx-field-setter { | |
57 | + .ant-tag { | |
58 | + display: flex; | |
59 | + } | |
66 | 60 | } |
67 | 61 | } |
68 | 62 | ... | ... |
1 | 1 | import { ControlOutlined } from '@ant-design/icons'; |
2 | -import { Select, Tooltip, Input } from 'antd'; | |
2 | +import { Select, Tooltip } from 'antd'; | |
3 | 3 | import { size } from 'lodash-es'; |
4 | 4 | import React, { useState } from 'react'; |
5 | 5 | import type { QxBaseConditionField } from '../qx-base-condition'; |
6 | 6 | import { QxBaseIcon } from '../qx-base-icon'; |
7 | 7 | import { QxFieldSetter } from '../qx-field-setter'; |
8 | +import type { INode } from '../qx-flow-node-selector'; | |
9 | +import { | |
10 | + QxFlowNodeFieldSelector, | |
11 | + useNodeFieldDisplay, | |
12 | +} from '../qx-flow-node-selector'; | |
13 | +import { QxWidgetIcon } from '../qx-widget-icon'; | |
8 | 14 | |
9 | 15 | import './index.less'; |
10 | 16 | |
... | ... | @@ -666,147 +672,22 @@ const optValTypeCheck = { |
666 | 672 | }, |
667 | 673 | }; |
668 | 674 | |
669 | -export const WidgetsIcon = ({ widgetName }: { widgetName: string }) => { | |
670 | - let iconType: string = ''; | |
671 | - switch (widgetName) { | |
672 | - case 'qxInput': | |
673 | - iconType = 'icon-field-text'; | |
674 | - break; | |
675 | - case 'qxNumber': | |
676 | - iconType = 'icon-field-num'; | |
677 | - break; | |
678 | - case 'dateTime': | |
679 | - case 'qxDatetime': | |
680 | - iconType = 'icon-field-datetime'; | |
681 | - break; | |
682 | - case 'qxTime': | |
683 | - iconType = 'icon-field-time'; | |
684 | - break; | |
685 | - case 'qxSwitch': | |
686 | - iconType = 'icon-field-boolean'; | |
687 | - break; | |
688 | - case 'qxSelect': | |
689 | - iconType = 'icon-field-select'; | |
690 | - break; | |
691 | - case 'qxMultiSelect': | |
692 | - iconType = 'icon-field-multi-select'; | |
693 | - break; | |
694 | - case 'qxMobile': | |
695 | - iconType = 'icon-field-mobile'; | |
696 | - break; | |
697 | - case 'qxMoney': | |
698 | - iconType = 'icon-field-finance'; | |
699 | - break; | |
700 | - case 'qxEmail': | |
701 | - iconType = 'icon-field-email'; | |
702 | - break; | |
703 | - case 'qxPercent': | |
704 | - iconType = 'icon-field-percent'; | |
705 | - break; | |
706 | - case 'qxUpload': | |
707 | - iconType = 'icon-field-file'; | |
708 | - break; | |
709 | - case 'qxUploadImage': | |
710 | - iconType = 'icon-field-img'; | |
711 | - break; | |
712 | - case 'qxAddress': | |
713 | - iconType = 'icon-field-address'; | |
714 | - break; | |
715 | - case 'qxRichText': | |
716 | - iconType = 'icon-field-richtext'; | |
717 | - break; | |
718 | - case 'qxLocation': | |
719 | - iconType = 'icon-field-location'; | |
720 | - break; | |
721 | - case 'orgSelector': | |
722 | - iconType = 'icon-field-department'; | |
723 | - break; | |
724 | - case 'userSelector': | |
725 | - iconType = 'icon-field-user'; | |
726 | - break; | |
727 | - case 'createdBy': | |
728 | - case 'created_by': | |
729 | - iconType = 'icon-field-created-by'; | |
730 | - break; | |
731 | - case 'createdAt': | |
732 | - case 'created_at': | |
733 | - iconType = 'icon-field-created-at'; | |
734 | - break; | |
735 | - case 'updatedBy': | |
736 | - case 'updated_by': | |
737 | - iconType = 'icon-field-updated-by'; | |
738 | - break; | |
739 | - case 'updatedAt': | |
740 | - case 'updated_at': | |
741 | - iconType = 'icon-field-updated-at'; | |
742 | - break; | |
743 | - case 'qxBizNo': | |
744 | - iconType = 'icon-field-no'; | |
745 | - break; | |
746 | - case 'relSelector': | |
747 | - iconType = 'icon-field-rel'; | |
748 | - break; | |
749 | - case 'relField': | |
750 | - iconType = 'icon-field-ref'; | |
751 | - break; | |
752 | - case 'subform': | |
753 | - case 'table': | |
754 | - iconType = 'icon-field-subform'; | |
755 | - break; | |
756 | - case 'qxTree': | |
757 | - iconType = 'icon-field-tree'; | |
758 | - break; | |
759 | - case 'qxFormula': | |
760 | - iconType = 'icon-field-formula'; | |
761 | - break; | |
762 | - case 'qxDivider': | |
763 | - iconType = 'icon-field-divider'; | |
764 | - break; | |
765 | - case 'qxRemark': | |
766 | - iconType = 'icon-field-remark'; | |
767 | - break; | |
768 | - case 'qxEmbed': | |
769 | - iconType = 'icon-field-embed '; | |
770 | - break; | |
771 | - case 'qxTabs': | |
772 | - iconType = 'icon-editor_tab'; | |
773 | - break; | |
774 | - case 'qxLayout': | |
775 | - iconType = 'icon-editor_grid'; | |
776 | - break; | |
777 | - case 'simple': | |
778 | - iconType = 'icon-editor_layout'; | |
779 | - break; | |
780 | - case 'tabC': | |
781 | - iconType = 'icon-editor_tab'; | |
782 | - break; | |
783 | - case 'layout': | |
784 | - iconType = 'icon-editor_grid'; | |
785 | - break; | |
786 | - default: | |
787 | - iconType = 'icon-field-text'; | |
788 | - break; | |
789 | - } | |
790 | - return <QxBaseIcon type={iconType} />; | |
791 | -}; | |
792 | - | |
793 | 675 | export const QxBaseConditionItem: React.FC<QxBaseConditionItemProps> = ({ |
794 | 676 | value, |
795 | 677 | field, |
796 | 678 | remove, |
797 | 679 | onChange, |
798 | 680 | mode = 'condition', |
799 | - ValueAssignmentPopup, | |
681 | + node, | |
682 | + nodes, | |
800 | 683 | }) => { |
801 | - const [CustomValueRender, setCustomValueRender] = | |
802 | - useState<() => React.ReactNode>(); | |
803 | - | |
684 | + const valuesObj = value?.valuesObj?.[0] || {}; | |
804 | 685 | const [open, setOpen] = useState(false); |
805 | 686 | |
806 | - const handleChange = (val: any) => { | |
687 | + const handleChange = (val: any[]) => { | |
807 | 688 | onChange?.({ |
808 | 689 | ...(value || {}), |
809 | - mappingValues: val?.map((i: any) => i.value), | |
690 | + mappingValues: val?.length ? val?.map((i: any) => i.value) : [], | |
810 | 691 | valuesObj: val, |
811 | 692 | }); |
812 | 693 | }; |
... | ... | @@ -841,23 +722,23 @@ export const QxBaseConditionItem: React.FC<QxBaseConditionItemProps> = ({ |
841 | 722 | onChange?.(newValue); |
842 | 723 | }; |
843 | 724 | |
844 | - const handleDefaultValueSettingChange = ( | |
845 | - val: any, | |
846 | - valueRender: () => React.ReactNode, | |
847 | - ) => { | |
848 | - handleChange(val); | |
849 | - setCustomValueRender(() => valueRender); | |
725 | + const handleAssignment = (value: string) => { | |
726 | + handleChange([{ type: 'FIELD', value }]); | |
727 | + setOpen(false); | |
850 | 728 | }; |
851 | 729 | |
852 | - const handleOpenChange = setOpen; | |
730 | + const { genDisplayDom } = useNodeFieldDisplay({ | |
731 | + node: node, | |
732 | + nodes: nodes, | |
733 | + limitTypes: [field.fieldType], | |
734 | + }); | |
735 | + | |
736 | + const getName = (values: any[]) => { | |
737 | + return values.map((value) => genDisplayDom(value)) | |
738 | + } | |
853 | 739 | |
854 | 740 | const RenderContent = ( |
855 | 741 | <> |
856 | - {typeof CustomValueRender === 'function' && ( | |
857 | - <div className="qx-base-condition-item__content-value-render"> | |
858 | - {CustomValueRender()} | |
859 | - </div> | |
860 | - )} | |
861 | 742 | <QxFieldSetter |
862 | 743 | value={value?.valuesObj} |
863 | 744 | fieldGroupType={value?.fieldGroupType} |
... | ... | @@ -865,11 +746,12 @@ export const QxBaseConditionItem: React.FC<QxBaseConditionItemProps> = ({ |
865 | 746 | isMultiple={multipleType.includes(value?.fieldGroupType)} |
866 | 747 | isRange={optValTypeCheck.isRangeType(value?.opt)} |
867 | 748 | disabled={optValTypeCheck.isEmptyType(value?.opt)} |
749 | + getName={getName} | |
868 | 750 | /> |
869 | - {typeof ValueAssignmentPopup !== 'undefined' && ( | |
751 | + {mode === 'variable' && ( | |
870 | 752 | <ControlOutlined |
871 | 753 | onClick={() => { |
872 | - handleOpenChange(!open); | |
754 | + setOpen(!open); | |
873 | 755 | }} |
874 | 756 | className="qx-base-condition-item__content-suffix" |
875 | 757 | /> |
... | ... | @@ -900,7 +782,7 @@ export const QxBaseConditionItem: React.FC<QxBaseConditionItemProps> = ({ |
900 | 782 | <div className="qx-base-condition-item__header"> |
901 | 783 | <div className="qx-base-condition-item__header-left"> |
902 | 784 | <span className="qx-base-condition-item__header-icon"> |
903 | - <WidgetsIcon widgetName={field?.extract?.widget} /> | |
785 | + <QxWidgetIcon widgetName={field?.extract?.widget} /> | |
904 | 786 | </span> |
905 | 787 | <span className="qx-base-condition-item__header-text"> |
906 | 788 | {field.fieldName} |
... | ... | @@ -921,16 +803,18 @@ export const QxBaseConditionItem: React.FC<QxBaseConditionItemProps> = ({ |
921 | 803 | </div> |
922 | 804 | </div> |
923 | 805 | <div className="qx-base-condition-item__content"> |
924 | - {typeof ValueAssignmentPopup !== 'undefined' ? ( | |
925 | - <ValueAssignmentPopup | |
806 | + {mode === 'variable' ? ( | |
807 | + <QxFlowNodeFieldSelector | |
808 | + mode={mode} | |
809 | + node={node!} | |
810 | + nodes={nodes!} | |
926 | 811 | open={open} |
927 | - value={value} | |
928 | - field={field} | |
929 | - onChange={handleDefaultValueSettingChange} | |
930 | - onOpenChange={handleOpenChange} | |
812 | + value={valuesObj?.value} | |
813 | + onChange={handleAssignment} | |
814 | + limitTypes={[field.fieldType]} | |
931 | 815 | > |
932 | 816 | {RenderContent} |
933 | - </ValueAssignmentPopup> | |
817 | + </QxFlowNodeFieldSelector> | |
934 | 818 | ) : ( |
935 | 819 | RenderContent |
936 | 820 | )} |
... | ... | @@ -942,9 +826,10 @@ export const QxBaseConditionItem: React.FC<QxBaseConditionItemProps> = ({ |
942 | 826 | export interface ValueAssignmentPopupProps |
943 | 827 | extends Omit<QxBaseConditionItemProps, 'onChange'> { |
944 | 828 | children?: React.ReactNode; |
945 | - onChange?: (val: any, valueRender: () => React.ReactNode) => void; | |
829 | + onChange?: (val: any) => void; | |
946 | 830 | open?: boolean; |
947 | 831 | onOpenChange?: (open: boolean) => void; |
832 | + onClear?: () => void; | |
948 | 833 | } |
949 | 834 | |
950 | 835 | export interface QxBaseConditionItemProps { |
... | ... | @@ -952,6 +837,9 @@ export interface QxBaseConditionItemProps { |
952 | 837 | value?: any; |
953 | 838 | onChange?: (val: any) => void; |
954 | 839 | remove?: (field: QxBaseConditionField) => void; |
955 | - ValueAssignmentPopup?: React.FC<ValueAssignmentPopupProps>; | |
840 | + ValueAssignment?: React.FC<ValueAssignmentPopupProps>; | |
956 | 841 | mode?: string; |
842 | + node?: INode; | |
843 | + nodes?: INode[]; | |
844 | + // customDisplay?: (val: string) => React.ReactNode; | |
957 | 845 | } | ... | ... |
1 | 1 | import React, { useEffect, useState } from 'react'; |
2 | -import type { ValueAssignmentPopupProps } from '../qx-base-condition-item'; | |
3 | 2 | import { QxBaseConditionItem } from '../qx-base-condition-item'; |
4 | 3 | import './index.less'; |
4 | +import { INode } from '../qx-flow-node-selector'; | |
5 | 5 | |
6 | 6 | export enum FieldBaseType { |
7 | 7 | STRING = 'TEXT', |
... | ... | @@ -9,9 +9,8 @@ export enum FieldBaseType { |
9 | 9 | YEAR_SEC = 'DATE', |
10 | 10 | } |
11 | 11 | |
12 | - | |
13 | 12 | export const QxBaseCondition: React.FC<QxBaseConditionProps> = (props) => { |
14 | - const [localOptions, setLocalOptions] = useState(props.value || props.options || []); | |
13 | + const [localOptions, setLocalOptions] = useState(props.options || []); | |
15 | 14 | |
16 | 15 | const getDefaultConditionOptions = (item: QxBaseConditionField) => ({ |
17 | 16 | ...item, |
... | ... | @@ -36,7 +35,7 @@ export const QxBaseCondition: React.FC<QxBaseConditionProps> = (props) => { |
36 | 35 | const handleDelete = (key: number) => { |
37 | 36 | localOptions.splice(key, 1); |
38 | 37 | setLocalOptions([...localOptions]); |
39 | - props.onChange?.([...localOptions]) | |
38 | + props.onChange?.([...localOptions]); | |
40 | 39 | }; |
41 | 40 | |
42 | 41 | useEffect(() => { |
... | ... | @@ -52,13 +51,16 @@ export const QxBaseCondition: React.FC<QxBaseConditionProps> = (props) => { |
52 | 51 | key={item.code || key} |
53 | 52 | mode={props.mode} |
54 | 53 | {...item} |
55 | - value={props.value?.[key] || getDefaultConditionOptions(item)} | |
54 | + value={Object.assign( | |
55 | + {}, | |
56 | + getDefaultConditionOptions(item), | |
57 | + props.value?.[key] || {}, | |
58 | + )} | |
59 | + nodes={props.nodes} | |
60 | + node={props.node} | |
56 | 61 | field={item} |
57 | 62 | onChange={(val) => handleItemChange(val, key)} |
58 | 63 | remove={() => handleDelete(key)} |
59 | - ValueAssignmentPopup={ | |
60 | - (item.showValueAssignmentPopup ?? true) ? props.ValueAssignmentPopup : undefined | |
61 | - } | |
62 | 64 | /> |
63 | 65 | </div> |
64 | 66 | )); |
... | ... | @@ -80,13 +82,13 @@ export interface QxBaseConditionField { |
80 | 82 | } |
81 | 83 | |
82 | 84 | export interface QxBaseConditionOptionsProps extends QxBaseConditionField { |
83 | - showValueAssignmentPopup?: boolean; | |
85 | + showValueAssignment?: boolean; | |
84 | 86 | isMultiple?: boolean; |
85 | 87 | isRange?: boolean; |
86 | 88 | [key: string]: any; |
87 | 89 | } |
88 | 90 | |
89 | -export type QxBaseConditionMode = 'condition' | 'variable' | |
91 | +export type QxBaseConditionMode = 'condition' | 'variable'; | |
90 | 92 | |
91 | 93 | export interface QxBaseConditionProps { |
92 | 94 | showIdx?: boolean; |
... | ... | @@ -94,5 +96,6 @@ export interface QxBaseConditionProps { |
94 | 96 | options: QxBaseConditionOptionsProps[]; |
95 | 97 | value: any[]; |
96 | 98 | onChange?: (val: any[]) => void; |
97 | - ValueAssignmentPopup?: React.FC<ValueAssignmentPopupProps>; | |
99 | + nodes?: INode[] | |
100 | + node?: INode | |
98 | 101 | } | ... | ... |
... | ... | @@ -156,6 +156,7 @@ export interface paramColSelectProps extends ColSelectProps { |
156 | 156 | iconText?: string; // Popover-icon 自定义 后面跟随文本 |
157 | 157 | allowClear?: boolean; |
158 | 158 | popupOnBody?: boolean; // 下拉 跟随 body 还是自身 |
159 | + getName?: (val: any) => void | |
159 | 160 | } |
160 | 161 | |
161 | 162 | export const QxFieldSetter: React.FC<paramColSelectProps> = ({ |
... | ... | @@ -355,7 +356,7 @@ export const QxFieldSetter: React.FC<paramColSelectProps> = ({ |
355 | 356 | * @param str 字符串形式 |
356 | 357 | * @param joinParent 拼接父节点 |
357 | 358 | */ |
358 | - const getName = (val: string[], str?: boolean, joinParent?: boolean) => { | |
359 | + const getName = props?.getName || ((val: string[], str?: boolean, joinParent?: boolean) => { | |
359 | 360 | const name: any[] = []; |
360 | 361 | let flag: boolean = false; |
361 | 362 | (colsTree || []).map((tree) => { |
... | ... | @@ -440,7 +441,7 @@ export const QxFieldSetter: React.FC<paramColSelectProps> = ({ |
440 | 441 | } else { |
441 | 442 | return flag ? name : val; |
442 | 443 | } |
443 | - }; | |
444 | + }); | |
444 | 445 | |
445 | 446 | /** |
446 | 447 | * 名称转换 | ... | ... |
... | ... | @@ -41,7 +41,9 @@ export default () => { |
41 | 41 | hideCurrentOrg={true} |
42 | 42 | hideCurrentUser={true} |
43 | 43 | isMixValue={false} |
44 | - onChange={() => {}} | |
44 | + onChange={(val) => { | |
45 | + console.log(222222,val) | |
46 | + }} | |
45 | 47 | tableFields={optionsList} |
46 | 48 | params={{ funCoded: 'cjQhMZnwkO2QoVzxVPC', useId: true }} |
47 | 49 | value={{ | ... | ... |
src/qx-flow-node-selector/index.less
0 → 100644
1 | +@import '~@qx/ui/src/style/variable.less'; | |
2 | + | |
3 | +@ant-prefix-cls: ~'ant'; | |
4 | + | |
5 | +.qx-node-select { | |
6 | + &-dropdown { | |
7 | + max-height: calc(8 * 32px); | |
8 | + overflow: auto; | |
9 | + background-color: white; | |
10 | + box-shadow: 0 6px 16px 0 rgba(0, 0, 0, 0.08), | |
11 | + 0 3px 6px -4px rgba(0, 0, 0, 0.12), 0 9px 28px 8px rgba(0, 0, 0, 0.05); | |
12 | + border-radius: 8px; | |
13 | + | |
14 | + &-header { | |
15 | + display: flex; | |
16 | + align-items: center; | |
17 | + &__icon { | |
18 | + width: 14px; | |
19 | + height: 14px; | |
20 | + font-size: 14px; | |
21 | + line-height: 14px; | |
22 | + // color: @N7; | |
23 | + margin-right: 4px; | |
24 | + display: inline-block; | |
25 | + border-radius: 50%; | |
26 | + overflow: hidden; | |
27 | + // border: 1px solid @N6; | |
28 | + display: flex; | |
29 | + align-items: center; | |
30 | + justify-content: center; | |
31 | + | |
32 | + > img { | |
33 | + width: 14px; | |
34 | + height: 14px; | |
35 | + } | |
36 | + } | |
37 | + } | |
38 | + | |
39 | + .qx-node-select-item__icon { | |
40 | + margin-right: 4px; | |
41 | + } | |
42 | + | |
43 | + .@{ant-prefix-cls}-collapse-header, | |
44 | + .@{ant-prefix-cls}-collapse-content { | |
45 | + padding: 7px !important; | |
46 | + font-size: 14px; | |
47 | + } | |
48 | + | |
49 | + .@{ant-prefix-cls}-collapse-content { | |
50 | + background-color: @N3 !important; | |
51 | + padding: 0 !important; | |
52 | + | |
53 | + &-box { | |
54 | + padding: 0 !important; | |
55 | + } | |
56 | + } | |
57 | + } | |
58 | + | |
59 | + &-item { | |
60 | + width: 100%; | |
61 | + padding: 7px 16px 7px 32px !important; | |
62 | + &:hover { | |
63 | + background-color: @N4; | |
64 | + cursor: pointer; | |
65 | + } | |
66 | + | |
67 | + &__group { | |
68 | + padding: 0 0 0px 32px !important; | |
69 | + | |
70 | + &:hover { | |
71 | + background-color: transparent; | |
72 | + } | |
73 | + .@{ant-prefix-cls}-collapse-header { | |
74 | + padding: 7px 0 !important; | |
75 | + } | |
76 | + } | |
77 | + } | |
78 | + | |
79 | + &-input { | |
80 | + box-sizing: border-box; | |
81 | + margin: 0; | |
82 | + font-variant: tabular-nums; | |
83 | + list-style: none; | |
84 | + font-feature-settings: 'tnum', 'tnum'; | |
85 | + position: relative; | |
86 | + display: inline-block; | |
87 | + width: 100%; | |
88 | + height: 32px; | |
89 | + min-width: 0; | |
90 | + padding: 4px 32px 4px 4px; | |
91 | + color: rgba(0, 0, 0, 0.85); | |
92 | + font-size: 14px; | |
93 | + line-height: 1.5715; | |
94 | + background-color: #fff; | |
95 | + background-image: none; | |
96 | + border: 1px solid #d9d9d9; | |
97 | + border-radius: 4px; | |
98 | + transition: all 0.3s; | |
99 | + | |
100 | + &:hover { | |
101 | + border-color: @B8; | |
102 | + } | |
103 | + | |
104 | + &__content { | |
105 | + display: inline-flex; | |
106 | + color: @N9; | |
107 | + font-size: 14px; | |
108 | + | |
109 | + &-item { | |
110 | + margin-right: 4px; | |
111 | + display: flex; | |
112 | + align-items: center; | |
113 | + | |
114 | + &__icon { | |
115 | + width: 14px; | |
116 | + height: 14px; | |
117 | + font-size: 14px; | |
118 | + line-height: 14px; | |
119 | + // color: @N7; | |
120 | + margin-right: 4px; | |
121 | + display: inline-block; | |
122 | + border-radius: 50%; | |
123 | + // overflow: hidden; | |
124 | + // border: 1px solid @N6; | |
125 | + display: flex; | |
126 | + align-items: center; | |
127 | + justify-content: center; | |
128 | + | |
129 | + > img { | |
130 | + width: inherit; | |
131 | + height: inherit; | |
132 | + } | |
133 | + } | |
134 | + | |
135 | + &__arrow { | |
136 | + display: inline-flex; | |
137 | + align-items: center; | |
138 | + color: @N6; | |
139 | + } | |
140 | + } | |
141 | + } | |
142 | + | |
143 | + &__suffix { | |
144 | + position: absolute; | |
145 | + right: 10px; | |
146 | + top: 50%; | |
147 | + transform: translateY(-50%); | |
148 | + } | |
149 | + } | |
150 | +} | |
151 | + | |
152 | +.qx-node-select-dropdown { | |
153 | + > .@{ant-prefix-cls}-collapse { | |
154 | + > .@{ant-prefix-cls}-collapse-item { | |
155 | + > .@{ant-prefix-cls}-collapse-content { | |
156 | + padding-right: 7px !important; | |
157 | + } | |
158 | + } | |
159 | + } | |
160 | +} | ... | ... |
src/qx-flow-node-selector/index.tsx
0 → 100644
1 | +import { ControlOutlined } from '@ant-design/icons'; | |
2 | +import { QxWidgetIcon } from '@qx/common'; | |
3 | +import { Collapse, Dropdown, Empty, Tag } from 'antd'; | |
4 | +import cls from 'classnames'; | |
5 | +import { cloneDeep } from 'lodash-es'; | |
6 | +import React, { useEffect, useMemo, useState } from 'react'; | |
7 | +import { QxBaseIcon } from '../qx-base-icon'; | |
8 | +import { request } from '../utils'; | |
9 | +import './index.less'; | |
10 | +// import type { FiledType } from '@/interface'; | |
11 | +// import type { INode } from '@qx/flow'; | |
12 | + | |
13 | +const getAppsFields = (params: string[], appId = 'default') => { | |
14 | + return request.post(`/qx-apaas-lowcode/app/${appId}/fields`, { | |
15 | + data: params, | |
16 | + }); | |
17 | +}; | |
18 | + | |
19 | +export const getNodesMap = ( | |
20 | + nodes: INode[], | |
21 | + map: Record<string, INode> = {}, | |
22 | +) => { | |
23 | + if (!nodes) return {}; | |
24 | + for (let i = 0; i < nodes.length; i++) { | |
25 | + const node = nodes[i]; | |
26 | + if (!map[node.id]) { | |
27 | + map[node.id] = node; | |
28 | + } | |
29 | + | |
30 | + if (node.children && Array.isArray(node.children)) { | |
31 | + getNodesMap(node.children, map); | |
32 | + } | |
33 | + } | |
34 | + | |
35 | + return map; | |
36 | +}; | |
37 | + | |
38 | +export const getParentNodes = ( | |
39 | + node?: INode, | |
40 | + treeNodes?: INode[], | |
41 | + parentNode: INode[] = [], | |
42 | + allNodes = getNodesMap(treeNodes!), | |
43 | +) => { | |
44 | + if (!node || !treeNodes) return []; | |
45 | + if (node.previousId) { | |
46 | + parentNode.push(allNodes[node.previousId]); | |
47 | + getParentNodes(allNodes[node.previousId], treeNodes, parentNode, allNodes); | |
48 | + } | |
49 | + | |
50 | + return parentNode; | |
51 | +}; | |
52 | + | |
53 | +export enum FileTypeMap { | |
54 | + 'STRING' = '文本', | |
55 | + 'NUMBER' = '数字', | |
56 | + 'BOOL' = '布尔', | |
57 | + 'TIME' = '日期', | |
58 | + 'OBJECT' = '对象', | |
59 | + 'ARRAY' = '数组', | |
60 | + 'FORM' = '表单', | |
61 | + 'USER' = '人员', | |
62 | + 'ORG' = '部门', | |
63 | + 'FILE' = '文件', | |
64 | + 'PIC' = '图片', | |
65 | +} | |
66 | + | |
67 | +interface NodeFieldDisPlay { | |
68 | + node?: INode; | |
69 | + nodes?: INode[]; | |
70 | + limitTypes?: string[]; | |
71 | +} | |
72 | + | |
73 | +const icon = (icon: any) => { | |
74 | + if (icon?.$$typeof) { | |
75 | + return icon; | |
76 | + } | |
77 | + if (typeof icon !== 'string' && icon) { | |
78 | + return <QxBaseIcon type={icon.props.type} />; | |
79 | + } | |
80 | + | |
81 | + return <img src={icon} />; | |
82 | +}; | |
83 | + | |
84 | +export const useNodeFieldDisplay = ({ | |
85 | + node, | |
86 | + nodes, | |
87 | + limitTypes, | |
88 | +}: NodeFieldDisPlay) => { | |
89 | + const sourceParentNodes = | |
90 | + getParentNodes(node, nodes).filter( | |
91 | + (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 | + } | |
131 | + | |
132 | + return getEffectiveNodes(targetParentNodes); | |
133 | + }, [limitTypes, sourceParentNodes]); | |
134 | + | |
135 | + const getId = (val?: string) => { | |
136 | + if (!val) return; | |
137 | + const startIndex = val.indexOf('|') + 1; | |
138 | + const endIndex = val.indexOf('}'); | |
139 | + if (startIndex < endIndex) { | |
140 | + return val.substring(startIndex, endIndex); | |
141 | + } | |
142 | + return null; | |
143 | + }; | |
144 | + | |
145 | + const genDisplayDom = (value: string) => { | |
146 | + const itemId = getId(value); | |
147 | + if (!itemId) return; | |
148 | + let displayConfig: any[] = []; | |
149 | + let n = true; | |
150 | + let index = 0; | |
151 | + while (n && index <= 20) { | |
152 | + displayConfig = []; | |
153 | + const curNode = optionalNodes[index] || {}; | |
154 | + displayConfig.push({ | |
155 | + title: curNode.name, | |
156 | + icon: curNode.icon, | |
157 | + ...(optionalNodes[index] || {}), | |
158 | + }); | |
159 | + // eslint-disable-next-line @typescript-eslint/no-use-before-define | |
160 | + recursionNodeResult(curNode.data?.result); | |
161 | + index++; | |
162 | + } | |
163 | + | |
164 | + function recursionNodeResult(result: FiledType[], idx = 1) { | |
165 | + if (Array.isArray(result)) { | |
166 | + for (let i = 0; i < result.length; i++) { | |
167 | + const item = result[i]; | |
168 | + if (!n) return; | |
169 | + | |
170 | + displayConfig.splice(idx, 1, item); | |
171 | + displayConfig = displayConfig.slice(0, idx + 1); | |
172 | + | |
173 | + if (itemId === item.id) { | |
174 | + n = false; | |
175 | + return; | |
176 | + } | |
177 | + | |
178 | + if (Array.isArray(item.child)) { | |
179 | + recursionNodeResult(item.child, idx + 1); | |
180 | + } | |
181 | + } | |
182 | + } else { | |
183 | + n = false; | |
184 | + } | |
185 | + } | |
186 | + | |
187 | + return ( | |
188 | + <> | |
189 | + {displayConfig?.map((item, idx) => ( | |
190 | + <div | |
191 | + key={idx} | |
192 | + className='qx-node-select-input__content-item' | |
193 | + > | |
194 | + {item.icon && ( | |
195 | + <span | |
196 | + className='qx-node-select-input__content-item__icon' | |
197 | + > | |
198 | + {icon(item.icon)} | |
199 | + </span> | |
200 | + )} | |
201 | + <span | |
202 | + className='qx-node-select-input__content-item__text' | |
203 | + > | |
204 | + {item.type && | |
205 | + FileTypeMap[item.type] && | |
206 | + !item.icon && | |
207 | + `[${FileTypeMap[item.type]}]`} | |
208 | + {item.title} | |
209 | + </span> | |
210 | + {idx !== displayConfig.length - 1 && ( | |
211 | + <span | |
212 | + className='qx-node-select-input__content-item__arrow' | |
213 | + > | |
214 | + <svg | |
215 | + xmlns="http://www.w3.org/2000/svg" | |
216 | + width="1em" | |
217 | + height="1em" | |
218 | + fill="currentColor" | |
219 | + > | |
220 | + <path d="M5.80469 13.6423L4.86188 12.6995L9.57592 7.98548L4.86188 3.27143L5.80469 2.32863L10.9901 7.51403C10.9901 7.51406 10.9901 7.51407 10.5187 7.98548L10.9901 7.51403L11.4615 7.98548L5.80469 13.6423Z" /> | |
221 | + </svg> | |
222 | + </span> | |
223 | + )} | |
224 | + </div> | |
225 | + ))} | |
226 | + </> | |
227 | + ); | |
228 | + }; | |
229 | + | |
230 | + return { | |
231 | + genDisplayDom, | |
232 | + optionalNodes, | |
233 | + }; | |
234 | +}; | |
235 | + | |
236 | +const SelectItem = (props: any) => { | |
237 | + if (props.type === 'FORM') { | |
238 | + return ( | |
239 | + <div className={cls('qx-node-select-item', 'qx-node-select-item__group')}> | |
240 | + <Collapse | |
241 | + ghost | |
242 | + expandIconPosition="end" | |
243 | + items={[ | |
244 | + { | |
245 | + label: ( | |
246 | + <span> | |
247 | + {/* @ts-ignore */} | |
248 | + {`[${FileTypeMap[props.type]}]`} | |
249 | + {props.title} | |
250 | + </span> | |
251 | + ), | |
252 | + key: props.id, | |
253 | + children: props.child?.map((item: any, idx: number) => { | |
254 | + return ( | |
255 | + <SelectItem | |
256 | + key={item.code || idx} | |
257 | + {...item} | |
258 | + onClick={props.onClick} | |
259 | + /> | |
260 | + ); | |
261 | + }), | |
262 | + }, | |
263 | + ]} | |
264 | + /> | |
265 | + </div> | |
266 | + ); | |
267 | + } | |
268 | + | |
269 | + if (!props.child) { | |
270 | + return ( | |
271 | + <div | |
272 | + className={cls('qx-node-select-item')} | |
273 | + onClick={() => props.onClick(props)} | |
274 | + > | |
275 | + {/* @ts-ignore */} | |
276 | + {props.icon ? props.icon : `[${FileTypeMap[props.type]}]`} | |
277 | + {props.title} | |
278 | + </div> | |
279 | + ); | |
280 | + } | |
281 | + | |
282 | + return ( | |
283 | + <div className={cls('qx-node-select-item', 'qx-node-select-item__group')}> | |
284 | + <Collapse | |
285 | + ghost | |
286 | + expandIconPosition="end" | |
287 | + items={[ | |
288 | + { | |
289 | + label: ( | |
290 | + <span> | |
291 | + {/* @ts-ignore */} | |
292 | + {`[${FileTypeMap[props.type]}]`} | |
293 | + {props.title} | |
294 | + </span> | |
295 | + ), | |
296 | + key: props.id, | |
297 | + children: props.child?.map((item: any, idx: number) => { | |
298 | + return ( | |
299 | + <SelectItem | |
300 | + key={item.code || idx} | |
301 | + {...item} | |
302 | + onClick={props.onClick} | |
303 | + /> | |
304 | + ); | |
305 | + }), | |
306 | + }, | |
307 | + ]} | |
308 | + /> | |
309 | + </div> | |
310 | + ); | |
311 | +}; | |
312 | + | |
313 | +export const QxFlowNodeFieldSelector: React.FC<NodeFieldSelectProps> = ( | |
314 | + props, | |
315 | +) => { | |
316 | + const { mode = 'select' } = props; | |
317 | + | |
318 | + const [visible, setVisible] = useState(false); | |
319 | + | |
320 | + const [inputDisplay, setInputDisplay] = useState<React.ReactNode>(); | |
321 | + | |
322 | + const { optionalNodes, genDisplayDom } = useNodeFieldDisplay(props); | |
323 | + | |
324 | + const getOptions = () => { | |
325 | + if (!optionalNodes.length) { | |
326 | + return <Empty />; | |
327 | + } | |
328 | + return optionalNodes.map((node) => ({ | |
329 | + label: ( | |
330 | + <div className={cls('qx-node-select-dropdown-header')}> | |
331 | + <span className={cls('qx-node-select-dropdown-header__icon')}> | |
332 | + {icon(node.icon)} | |
333 | + </span> | |
334 | + {node.name} | |
335 | + </div> | |
336 | + ), | |
337 | + key: node.id, | |
338 | + children: Array.isArray(node.data?.result) | |
339 | + ? (node.data.result as FiledType[])?.map((item) => { | |
340 | + return ( | |
341 | + <SelectItem | |
342 | + key={item.id} | |
343 | + {...item} | |
344 | + onClick={(value: FiledType) => { | |
345 | + // eslint-disable-next-line @typescript-eslint/no-use-before-define | |
346 | + handleItemClick(node.id, value || item); | |
347 | + }} | |
348 | + /> | |
349 | + ); | |
350 | + }) | |
351 | + : [], | |
352 | + })); | |
353 | + }; | |
354 | + | |
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) => { | |
446 | + const newValue = '${' + `${nodeKey}|${item.id}` + '}'; | |
447 | + props.onChange?.(newValue, item); | |
448 | + if (!props.children) { | |
449 | + renderInputDisplay(newValue); | |
450 | + } | |
451 | + setVisible(false); | |
452 | + }; | |
453 | + | |
454 | + useEffect(() => { | |
455 | + handleGetAppsFields(); | |
456 | + }, []); | |
457 | + | |
458 | + useEffect(() => { | |
459 | + setVisible(props.open ?? false); | |
460 | + }, [props.open]); | |
461 | + | |
462 | + return ( | |
463 | + <div className={cls('qx-node-select')}> | |
464 | + <Dropdown | |
465 | + trigger={['click']} | |
466 | + overlayStyle={{ width: `${props?.width}px` }} | |
467 | + overlayClassName={cls('qx-node-select-dropdown')} | |
468 | + open={visible} | |
469 | + dropdownRender={() => ( | |
470 | + <Collapse ghost expandIconPosition="end" items={getOptions()} /> | |
471 | + )} | |
472 | + onOpenChange={(open) => { | |
473 | + if (mode === 'select') { | |
474 | + setVisible(open); | |
475 | + } | |
476 | + }} | |
477 | + > | |
478 | + {props.children ? ( | |
479 | + props.children | |
480 | + ) : ( | |
481 | + <div className={cls('qx-node-select-input')}> | |
482 | + {inputDisplay} | |
483 | + {mode === 'variable' && ( | |
484 | + <span | |
485 | + className="qx-node-select-input__suffix" | |
486 | + onClick={() => setVisible(!visible)} | |
487 | + > | |
488 | + <ControlOutlined /> | |
489 | + </span> | |
490 | + )} | |
491 | + </div> | |
492 | + )} | |
493 | + </Dropdown> | |
494 | + </div> | |
495 | + ); | |
496 | +}; | |
497 | + | |
498 | +export interface NodeFieldSelectProps { | |
499 | + node: INode; | |
500 | + nodes: INode[]; | |
501 | + onChange?: (val: any, opt?: FiledType) => void; | |
502 | + value?: string; | |
503 | + children?: React.ReactNode; | |
504 | + limitTypes?: string[]; | |
505 | + width?: number; | |
506 | + mode?: 'select' | 'variable'; | |
507 | + open?: boolean; | |
508 | +} | |
509 | + | |
510 | +export interface FiledType { | |
511 | + type: string; | |
512 | + id: string; | |
513 | + title: string; | |
514 | + code: string; | |
515 | + valueOpt?: string; | |
516 | + mappingValues?: any[]; | |
517 | + detailValues?: any; | |
518 | + condition?: any; | |
519 | + child?: FiledType[]; | |
520 | + qxProps?: { | |
521 | + formId?: string; | |
522 | + }; | |
523 | + [key: string]: any; | |
524 | +} | |
525 | + | |
526 | +export interface INode { | |
527 | + id: string; | |
528 | + type: string; | |
529 | + name: string; | |
530 | + data?: any; | |
531 | + children?: INode[]; | |
532 | + path?: string[]; | |
533 | + configuring?: boolean; | |
534 | + validateStatusError?: boolean; | |
535 | + next?: string[]; | |
536 | + tools?: string[] | React.FC<any>[]; | |
537 | + debuggerError?: boolean; | |
538 | + debuggerSuccess?: boolean; | |
539 | + [key: string]: any; | |
540 | +} | ... | ... |
src/qx-widget-icon/index.md
0 → 100644
1 | +--- | |
2 | +nav: | |
3 | + path: /component | |
4 | + title: 组件 | |
5 | + order: 1 | |
6 | +group: | |
7 | + path: /common | |
8 | + title: 表单字段图标 | |
9 | + order: 0 | |
10 | +--- | |
11 | + | |
12 | +## QxWidgetIcon 表单字段图标 | |
13 | + | |
14 | +### 表单字段图标 | |
15 | + | |
16 | +```tsx | |
17 | +import { QxWidgetIcon } from '@qx/common'; | |
18 | + | |
19 | +export default () => { | |
20 | + return <QxWidgetIcon widgetName="qxInput" />; | |
21 | +}; | |
22 | +``` | ... | ... |
src/qx-widget-icon/index.tsx
0 → 100644
1 | +import { QxBaseIcon } from '../qx-base-icon'; | |
2 | + | |
3 | +export const QxWidgetIcon = ({ widgetName }: { widgetName: string }) => { | |
4 | + let iconType: string = ''; | |
5 | + switch (widgetName) { | |
6 | + case 'qxInput': | |
7 | + iconType = 'icon-field-text'; | |
8 | + break; | |
9 | + case 'qxNumber': | |
10 | + iconType = 'icon-field-num'; | |
11 | + break; | |
12 | + case 'dateTime': | |
13 | + case 'qxDatetime': | |
14 | + iconType = 'icon-field-datetime'; | |
15 | + break; | |
16 | + case 'qxTime': | |
17 | + iconType = 'icon-field-time'; | |
18 | + break; | |
19 | + case 'qxSwitch': | |
20 | + iconType = 'icon-field-boolean'; | |
21 | + break; | |
22 | + case 'qxSelect': | |
23 | + iconType = 'icon-field-select'; | |
24 | + break; | |
25 | + case 'qxMultiSelect': | |
26 | + iconType = 'icon-field-multi-select'; | |
27 | + break; | |
28 | + case 'qxMobile': | |
29 | + iconType = 'icon-field-mobile'; | |
30 | + break; | |
31 | + case 'qxMoney': | |
32 | + iconType = 'icon-field-finance'; | |
33 | + break; | |
34 | + case 'qxEmail': | |
35 | + iconType = 'icon-field-email'; | |
36 | + break; | |
37 | + case 'qxPercent': | |
38 | + iconType = 'icon-field-percent'; | |
39 | + break; | |
40 | + case 'qxUpload': | |
41 | + iconType = 'icon-field-file'; | |
42 | + break; | |
43 | + case 'qxUploadImage': | |
44 | + iconType = 'icon-field-img'; | |
45 | + break; | |
46 | + case 'qxAddress': | |
47 | + iconType = 'icon-field-address'; | |
48 | + break; | |
49 | + case 'qxRichText': | |
50 | + iconType = 'icon-field-richtext'; | |
51 | + break; | |
52 | + case 'qxLocation': | |
53 | + iconType = 'icon-field-location'; | |
54 | + break; | |
55 | + case 'orgSelector': | |
56 | + iconType = 'icon-field-department'; | |
57 | + break; | |
58 | + case 'userSelector': | |
59 | + iconType = 'icon-field-user'; | |
60 | + break; | |
61 | + case 'createdBy': | |
62 | + case 'created_by': | |
63 | + iconType = 'icon-field-created-by'; | |
64 | + break; | |
65 | + case 'createdAt': | |
66 | + case 'created_at': | |
67 | + iconType = 'icon-field-created-at'; | |
68 | + break; | |
69 | + case 'updatedBy': | |
70 | + case 'updated_by': | |
71 | + iconType = 'icon-field-updated-by'; | |
72 | + break; | |
73 | + case 'updatedAt': | |
74 | + case 'updated_at': | |
75 | + iconType = 'icon-field-updated-at'; | |
76 | + break; | |
77 | + case 'qxBizNo': | |
78 | + iconType = 'icon-field-no'; | |
79 | + break; | |
80 | + case 'relSelector': | |
81 | + iconType = 'icon-field-rel'; | |
82 | + break; | |
83 | + case 'relField': | |
84 | + iconType = 'icon-field-ref'; | |
85 | + break; | |
86 | + case 'subform': | |
87 | + case 'table': | |
88 | + iconType = 'icon-field-subform'; | |
89 | + break; | |
90 | + case 'qxTree': | |
91 | + iconType = 'icon-field-tree'; | |
92 | + break; | |
93 | + case 'qxFormula': | |
94 | + iconType = 'icon-field-formula'; | |
95 | + break; | |
96 | + case 'qxDivider': | |
97 | + iconType = 'icon-field-divider'; | |
98 | + break; | |
99 | + case 'qxRemark': | |
100 | + iconType = 'icon-field-remark'; | |
101 | + break; | |
102 | + case 'qxEmbed': | |
103 | + iconType = 'icon-field-embed '; | |
104 | + break; | |
105 | + case 'qxTabs': | |
106 | + iconType = 'icon-editor_tab'; | |
107 | + break; | |
108 | + case 'qxLayout': | |
109 | + iconType = 'icon-editor_grid'; | |
110 | + break; | |
111 | + case 'simple': | |
112 | + iconType = 'icon-editor_layout'; | |
113 | + break; | |
114 | + case 'tabC': | |
115 | + iconType = 'icon-editor_tab'; | |
116 | + break; | |
117 | + case 'layout': | |
118 | + iconType = 'icon-editor_grid'; | |
119 | + break; | |
120 | + default: | |
121 | + iconType = 'icon-field-text'; | |
122 | + break; | |
123 | + } | |
124 | + return <QxBaseIcon type={iconType} />; | |
125 | +}; | ... | ... |