fix(Varaible): fix option is disabled (#2043)
* perf: use useMemo * refactor: extract className * refactor: fix lint warning * fix: fix can not be selected * refactor: reduces count of compile runs * fix: fix T-494 * fix: should disable options that no children * fix: fix T-496
This commit is contained in:
		
							parent
							
								
									50865d76bc
								
							
						
					
					
						commit
						e506c1781e
					
				| @ -14,6 +14,23 @@ import { Option } from '../../../schema-settings/VariableInput/type'; | |||||||
| import { XButton } from './XButton'; | import { XButton } from './XButton'; | ||||||
| 
 | 
 | ||||||
| const JT_VALUE_RE = /^\s*{{\s*([^{}]+)\s*}}\s*$/; | const JT_VALUE_RE = /^\s*{{\s*([^{}]+)\s*}}\s*$/; | ||||||
|  | const groupClass = css` | ||||||
|  |   width: auto; | ||||||
|  |   display: flex !important; | ||||||
|  |   .ant-input-disabled { | ||||||
|  |     .ant-tag { | ||||||
|  |       color: #bfbfbf; | ||||||
|  |       border-color: #d9d9d9; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   .ant-input.null-value { | ||||||
|  |     width: 4em; | ||||||
|  |     min-width: 4em; | ||||||
|  |   } | ||||||
|  | `;
 | ||||||
|  | const userSelectNone = css` | ||||||
|  |   user-select: 'none'; | ||||||
|  | `;
 | ||||||
| 
 | 
 | ||||||
| function parseValue(value: any): string | string[] { | function parseValue(value: any): string | string[] { | ||||||
|   if (value == null) { |   if (value == null) { | ||||||
| @ -133,34 +150,40 @@ export function Input(props) { | |||||||
| 
 | 
 | ||||||
|   const [variableText, setVariableText] = React.useState(''); |   const [variableText, setVariableText] = React.useState(''); | ||||||
| 
 | 
 | ||||||
|   const loadData = (selectedOptions: Option[]) => { |  | ||||||
|     const option = selectedOptions[selectedOptions.length - 1]; |  | ||||||
|     if (option.loadChildren) { |  | ||||||
|       // 需要保证 selectedOptions 是一个响应式对象,这样才能触发重新渲染
 |  | ||||||
|       option.loadChildren(option); |  | ||||||
|     } |  | ||||||
|   }; |  | ||||||
| 
 |  | ||||||
|   const { component: ConstantComponent, ...constantOption }: VariableOptions & { component?: React.FC<any> } = |   const { component: ConstantComponent, ...constantOption }: VariableOptions & { component?: React.FC<any> } = | ||||||
|     useMemo(() => { |     useMemo(() => { | ||||||
|       return children |       if (children) { | ||||||
|         ? { |         return { | ||||||
|             value: '', |           value: '', | ||||||
|             label: '{{t("Constant")}}', |           label: '{{t("Constant")}}', | ||||||
|           } |         }; | ||||||
|         : useTypedConstant |       } | ||||||
|         ? getTypedConstantOption(type, useTypedConstant) |       if (useTypedConstant) { | ||||||
|         : { |         return getTypedConstantOption(type, useTypedConstant); | ||||||
|             value: '', |       } | ||||||
|             label: '{{t("Null")}}', |       return { | ||||||
|             component: ConstantTypes.null.component, |         value: '', | ||||||
|           }; |         label: '{{t("Null")}}', | ||||||
|  |         component: ConstantTypes.null.component, | ||||||
|  |       }; | ||||||
|     }, [type, useTypedConstant]); |     }, [type, useTypedConstant]); | ||||||
| 
 | 
 | ||||||
|   const options: VariableOptions[] = useMemo( |   const [options, setOptions] = React.useState<Option[]>(() => { | ||||||
|     () => compile([constantOption, ...variableOptions]), |     return compile([constantOption, ...variableOptions]); | ||||||
|     [constantOption, variableOptions], |   }); | ||||||
|   ); | 
 | ||||||
|  |   useEffect(() => { | ||||||
|  |     const newOptions: Option[] = [constantOption, ...variableOptions]; | ||||||
|  |     setOptions(deepCompileLabel(newOptions, compile)); | ||||||
|  |   }, [variableOptions]); | ||||||
|  | 
 | ||||||
|  |   const loadData = async (selectedOptions: Option[]) => { | ||||||
|  |     const option = selectedOptions[selectedOptions.length - 1]; | ||||||
|  |     if (option.loadChildren) { | ||||||
|  |       await option.loadChildren(option); | ||||||
|  |       setOptions((prev) => [...prev]); | ||||||
|  |     } | ||||||
|  |   }; | ||||||
| 
 | 
 | ||||||
|   const onSwitch = useCallback( |   const onSwitch = useCallback( | ||||||
|     (next) => { |     (next) => { | ||||||
| @ -183,7 +206,7 @@ export function Input(props) { | |||||||
| 
 | 
 | ||||||
|   useEffect(() => { |   useEffect(() => { | ||||||
|     const run = async () => { |     const run = async () => { | ||||||
|       if (!variable) { |       if (!variable || options.length <= 1) { | ||||||
|         return; |         return; | ||||||
|       } |       } | ||||||
|       let prevOption: Option = null; |       let prevOption: Option = null; | ||||||
| @ -195,47 +218,28 @@ export function Input(props) { | |||||||
|           if (i === 0) { |           if (i === 0) { | ||||||
|             prevOption = options.find((item) => item.value === key); |             prevOption = options.find((item) => item.value === key); | ||||||
|           } else { |           } else { | ||||||
|             if (prevOption.children?.length === 0 && prevOption.loadChildren) { |             if (prevOption.loadChildren && !prevOption.children?.length) { | ||||||
|               await prevOption.loadChildren(prevOption); |               await prevOption.loadChildren(prevOption); | ||||||
|             } |             } | ||||||
|             prevOption = prevOption.children.find((item) => item.value === key); |             prevOption = prevOption.children.find((item) => item.value === key); | ||||||
|           } |           } | ||||||
|           labels.push(prevOption.label); |           labels.push(prevOption.label); | ||||||
|           setVariableText(labels.join(' / ')); |  | ||||||
|         } catch (err) { |         } catch (err) { | ||||||
|           error(err); |           error(err); | ||||||
|         } |         } | ||||||
|       } |       } | ||||||
|  |       setOptions([...options]); | ||||||
|  |       setVariableText(labels.join(' / ')); | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     // 如果没有这个延迟,会导致选择父节点时不展开子节点
 |     // 如果没有这个延迟,会导致选择父节点时不展开子节点
 | ||||||
|     setTimeout(run); |     setTimeout(run); | ||||||
|   }, [variable]); |   }, [variable, options.length]); | ||||||
| 
 | 
 | ||||||
|   const disabled = props.disabled || form.disabled; |   const disabled = props.disabled || form.disabled; | ||||||
| 
 | 
 | ||||||
|   return ( |   return ( | ||||||
|     <AntInput.Group |     <AntInput.Group compact style={style} className={classNames(className, groupClass)}> | ||||||
|       compact |  | ||||||
|       style={style} |  | ||||||
|       className={classNames( |  | ||||||
|         className, |  | ||||||
|         css` |  | ||||||
|           width: auto; |  | ||||||
|           display: flex !important; |  | ||||||
|           .ant-input-disabled { |  | ||||||
|             .ant-tag { |  | ||||||
|               color: #bfbfbf; |  | ||||||
|               border-color: #d9d9d9; |  | ||||||
|             } |  | ||||||
|           } |  | ||||||
|           .ant-input.null-value { |  | ||||||
|             width: 4em; |  | ||||||
|             min-width: 4em; |  | ||||||
|           } |  | ||||||
|         `,
 |  | ||||||
|       )} |  | ||||||
|     > |  | ||||||
|       {variable ? ( |       {variable ? ( | ||||||
|         <div |         <div | ||||||
|           className={css` |           className={css` | ||||||
| @ -282,12 +286,7 @@ export function Input(props) { | |||||||
|           </div> |           </div> | ||||||
|           {!disabled ? ( |           {!disabled ? ( | ||||||
|             <span |             <span | ||||||
|               className={cx( |               className={cx('ant-select-clear', userSelectNone)} | ||||||
|                 'ant-select-clear', |  | ||||||
|                 css` |  | ||||||
|                   user-select: 'none'; |  | ||||||
|                 `,
 |  | ||||||
|               )} |  | ||||||
|               // eslint-disable-next-line react/no-unknown-property
 |               // eslint-disable-next-line react/no-unknown-property
 | ||||||
|               unselectable="on" |               unselectable="on" | ||||||
|               aria-hidden |               aria-hidden | ||||||
| @ -314,3 +313,14 @@ export function Input(props) { | |||||||
|     </AntInput.Group> |     </AntInput.Group> | ||||||
|   ); |   ); | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | function deepCompileLabel(list: Option[], compile) { | ||||||
|  |   return list.map((item) => { | ||||||
|  |     const children = item.children ? deepCompileLabel(item.children, compile) : null; | ||||||
|  |     return { | ||||||
|  |       ...item, | ||||||
|  |       label: compile(item.label), | ||||||
|  |       children, | ||||||
|  |     }; | ||||||
|  |   }); | ||||||
|  | } | ||||||
|  | |||||||
| @ -1,152 +1,156 @@ | |||||||
| import { useCompile } from '../../../schema-component'; | import { useMemo } from 'react'; | ||||||
|  | import { useTranslation } from 'react-i18next'; | ||||||
| 
 | 
 | ||||||
| export const useDateVariable = ({ operator, schema }) => { | export const useDateVariable = ({ operator, schema }) => { | ||||||
|   const compile = useCompile(); |   const { t } = useTranslation(); | ||||||
|   const operatorValue = operator?.value || ''; |   const operatorValue = operator?.value || ''; | ||||||
| 
 |   const disabled = !['DatePicker', 'DatePicker.RangePicker'].includes(schema?.['x-component']); | ||||||
|   if (!operator || !schema) return null; |  | ||||||
| 
 |  | ||||||
|   const disabled = !['DatePicker', 'DatePicker.RangePicker'].includes(schema['x-component']); |  | ||||||
|   const dateOptions = [ |   const dateOptions = [ | ||||||
|     { |     { | ||||||
|       key: 'now', |       key: 'now', | ||||||
|       value: 'now', |       value: 'now', | ||||||
|       label: `{{t("Now")}}`, |       label: t('Now'), | ||||||
|       disabled: schema['x-component'] !== 'DatePicker' || operatorValue === '$dateBetween', |       disabled: schema?.['x-component'] !== 'DatePicker' || operatorValue === '$dateBetween', | ||||||
|     }, |     }, | ||||||
|     { |     { | ||||||
|       key: 'yesterday', |       key: 'yesterday', | ||||||
|       value: 'yesterday', |       value: 'yesterday', | ||||||
|       label: `{{t("Yesterday")}}`, |       label: t('Yesterday'), | ||||||
|       disabled, |       disabled, | ||||||
|     }, |     }, | ||||||
|     { |     { | ||||||
|       key: 'today', |       key: 'today', | ||||||
|       value: 'today', |       value: 'today', | ||||||
|       label: `{{t("Today")}}`, |       label: t('Today'), | ||||||
|       disabled, |       disabled, | ||||||
|     }, |     }, | ||||||
|     { |     { | ||||||
|       key: 'tomorrow', |       key: 'tomorrow', | ||||||
|       value: 'tomorrow', |       value: 'tomorrow', | ||||||
|       label: `{{t("Tomorrow")}}`, |       label: t('Tomorrow'), | ||||||
|       disabled, |       disabled, | ||||||
|     }, |     }, | ||||||
|     { |     { | ||||||
|       key: 'lastIsoWeek', |       key: 'lastIsoWeek', | ||||||
|       value: 'lastIsoWeek', |       value: 'lastIsoWeek', | ||||||
|       label: `{{t("Last week")}}`, |       label: t('Last week'), | ||||||
|       disabled, |       disabled, | ||||||
|     }, |     }, | ||||||
|     { |     { | ||||||
|       key: 'thisIsoWeek', |       key: 'thisIsoWeek', | ||||||
|       value: 'thisIsoWeek', |       value: 'thisIsoWeek', | ||||||
|       label: `{{t("This week")}}`, |       label: t('This week'), | ||||||
|       disabled, |       disabled, | ||||||
|     }, |     }, | ||||||
|     { |     { | ||||||
|       key: 'nextIsoWeek', |       key: 'nextIsoWeek', | ||||||
|       value: 'nextIsoWeek', |       value: 'nextIsoWeek', | ||||||
|       label: `{{t("Next week")}}`, |       label: t('Next week'), | ||||||
|       disabled, |       disabled, | ||||||
|     }, |     }, | ||||||
|     { |     { | ||||||
|       key: 'lastMonth', |       key: 'lastMonth', | ||||||
|       value: 'lastMonth', |       value: 'lastMonth', | ||||||
|       label: `{{t("Last month")}}`, |       label: t('Last month'), | ||||||
|       disabled, |       disabled, | ||||||
|     }, |     }, | ||||||
|     { |     { | ||||||
|       key: 'thisMonth', |       key: 'thisMonth', | ||||||
|       value: 'thisMonth', |       value: 'thisMonth', | ||||||
|       label: `{{t("This month")}}`, |       label: t('This month'), | ||||||
|       disabled, |       disabled, | ||||||
|     }, |     }, | ||||||
|     { |     { | ||||||
|       key: 'nextMonth', |       key: 'nextMonth', | ||||||
|       value: 'nextMonth', |       value: 'nextMonth', | ||||||
|       label: `{{t("Next month")}}`, |       label: t('Next month'), | ||||||
|       disabled, |       disabled, | ||||||
|     }, |     }, | ||||||
|     { |     { | ||||||
|       key: 'lastQuarter', |       key: 'lastQuarter', | ||||||
|       value: 'lastQuarter', |       value: 'lastQuarter', | ||||||
|       label: `{{t("Last quarter")}}`, |       label: t('Last quarter'), | ||||||
|       disabled, |       disabled, | ||||||
|     }, |     }, | ||||||
|     { |     { | ||||||
|       key: 'thisQuarter', |       key: 'thisQuarter', | ||||||
|       value: 'thisQuarter', |       value: 'thisQuarter', | ||||||
|       label: `{{t("This quarter")}}`, |       label: t('This quarter'), | ||||||
|       disabled, |       disabled, | ||||||
|     }, |     }, | ||||||
|     { |     { | ||||||
|       key: 'nextQuarter', |       key: 'nextQuarter', | ||||||
|       value: 'nextQuarter', |       value: 'nextQuarter', | ||||||
|       label: `{{t("Next quarter")}}`, |       label: t('Next quarter'), | ||||||
|       disabled, |       disabled, | ||||||
|     }, |     }, | ||||||
|     { |     { | ||||||
|       key: 'lastYear', |       key: 'lastYear', | ||||||
|       value: 'lastYear', |       value: 'lastYear', | ||||||
|       label: `{{t("Last year")}}`, |       label: t('Last year'), | ||||||
|       disabled, |       disabled, | ||||||
|     }, |     }, | ||||||
|     { |     { | ||||||
|       key: 'thisYear', |       key: 'thisYear', | ||||||
|       value: 'thisYear', |       value: 'thisYear', | ||||||
|       label: `{{t("This year")}}`, |       label: t('This year'), | ||||||
|       disabled, |       disabled, | ||||||
|     }, |     }, | ||||||
|     { |     { | ||||||
|       key: 'nextYear', |       key: 'nextYear', | ||||||
|       value: 'nextYear', |       value: 'nextYear', | ||||||
|       label: `{{t("Next year")}}`, |       label: t('Next year'), | ||||||
|       disabled, |       disabled, | ||||||
|     }, |     }, | ||||||
|     { |     { | ||||||
|       key: 'last7Days', |       key: 'last7Days', | ||||||
|       value: 'last7Days', |       value: 'last7Days', | ||||||
|       label: `{{t("Last 7 days")}}`, |       label: t('Last 7 days'), | ||||||
|       disabled, |       disabled, | ||||||
|     }, |     }, | ||||||
|     { |     { | ||||||
|       key: 'next7Days', |       key: 'next7Days', | ||||||
|       value: 'next7Days', |       value: 'next7Days', | ||||||
|       label: `{{t("Next 7 days")}}`, |       label: t('Next 7 days'), | ||||||
|       disabled, |       disabled, | ||||||
|     }, |     }, | ||||||
|     { |     { | ||||||
|       key: 'last30Days', |       key: 'last30Days', | ||||||
|       value: 'last30Days', |       value: 'last30Days', | ||||||
|       label: `{{t("Last 30 days")}}`, |       label: t('Last 30 days'), | ||||||
|       disabled, |       disabled, | ||||||
|     }, |     }, | ||||||
|     { |     { | ||||||
|       key: 'next30Days', |       key: 'next30Days', | ||||||
|       value: 'next30Days', |       value: 'next30Days', | ||||||
|       label: `{{t("Next 30 days")}}`, |       label: t('Next 30 days'), | ||||||
|       disabled, |       disabled, | ||||||
|     }, |     }, | ||||||
|     { |     { | ||||||
|       key: 'last90Days', |       key: 'last90Days', | ||||||
|       value: 'last90Days', |       value: 'last90Days', | ||||||
|       label: `{{t("Last 90 days")}}`, |       label: t('Last 90 days'), | ||||||
|       disabled, |       disabled, | ||||||
|     }, |     }, | ||||||
|     { |     { | ||||||
|       key: 'next90Days', |       key: 'next90Days', | ||||||
|       value: 'next90Days', |       value: 'next90Days', | ||||||
|       label: `{{t("Next 90 days")}}`, |       label: t('Next 90 days'), | ||||||
|       disabled, |       disabled, | ||||||
|     }, |     }, | ||||||
|   ]; |   ]; | ||||||
| 
 | 
 | ||||||
|   return compile({ |   const result = useMemo(() => { | ||||||
|     label: `{{t("Date variables")}}`, |     return { | ||||||
|     value: '$date', |       label: t('Date variables'), | ||||||
|     key: '$date', |       value: '$date', | ||||||
|     disabled: dateOptions.every((option) => option.disabled), |       key: '$date', | ||||||
|     children: dateOptions, |       disabled: dateOptions.every((option) => option.disabled), | ||||||
|   }); |       children: dateOptions, | ||||||
|  |     }; | ||||||
|  |   }, [schema?.['x-component']]); | ||||||
|  | 
 | ||||||
|  |   if (!operator || !schema) return null; | ||||||
|  | 
 | ||||||
|  |   return result; | ||||||
| }; | }; | ||||||
|  | |||||||
| @ -1,6 +1,6 @@ | |||||||
| import { observable } from '@formily/reactive'; |  | ||||||
| import { error } from '@nocobase/utils/client'; | import { error } from '@nocobase/utils/client'; | ||||||
| import { useMemo, useRef } from 'react'; | import { useMemo } from 'react'; | ||||||
|  | import { useTranslation } from 'react-i18next'; | ||||||
| import { useCompile, useGetFilterOptions } from '../../../schema-component'; | import { useCompile, useGetFilterOptions } from '../../../schema-component'; | ||||||
| import { FieldOption, Option } from '../type'; | import { FieldOption, Option } from '../type'; | ||||||
| 
 | 
 | ||||||
| @ -9,16 +9,20 @@ interface GetOptionsParams { | |||||||
|   depth: number; |   depth: number; | ||||||
|   maxDepth?: number; |   maxDepth?: number; | ||||||
|   loadChildren?: (option: Option) => Promise<void>; |   loadChildren?: (option: Option) => Promise<void>; | ||||||
|  |   compile: (value: string) => any; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| const getChildren = (options: FieldOption[], { schema, depth, maxDepth, loadChildren }: GetOptionsParams): Option[] => { | const getChildren = ( | ||||||
|  |   options: FieldOption[], | ||||||
|  |   { schema, depth, maxDepth, loadChildren, compile }: GetOptionsParams, | ||||||
|  | ): Option[] => { | ||||||
|   const result = options |   const result = options | ||||||
|     .map((option): Option => { |     .map((option): Option => { | ||||||
|       if (!option.target) { |       if (!option.target) { | ||||||
|         return { |         return { | ||||||
|           key: option.name, |           key: option.name, | ||||||
|           value: option.name, |           value: option.name, | ||||||
|           label: option.title, |           label: compile(option.title), | ||||||
|           // TODO: 现在是通过组件的名称来过滤能够被选择的选项,这样的坏处是不够精确,后续可以优化
 |           // TODO: 现在是通过组件的名称来过滤能够被选择的选项,这样的坏处是不够精确,后续可以优化
 | ||||||
|           disabled: schema?.['x-component'] !== option.schema?.['x-component'], |           disabled: schema?.['x-component'] !== option.schema?.['x-component'], | ||||||
|           isLeaf: true, |           isLeaf: true, | ||||||
| @ -33,7 +37,7 @@ const getChildren = (options: FieldOption[], { schema, depth, maxDepth, loadChil | |||||||
|       return { |       return { | ||||||
|         key: option.name, |         key: option.name, | ||||||
|         value: option.name, |         value: option.name, | ||||||
|         label: option.title, |         label: compile(option.title), | ||||||
|         children: [], |         children: [], | ||||||
|         isLeaf: false, |         isLeaf: false, | ||||||
|         field: option, |         field: option, | ||||||
| @ -47,10 +51,9 @@ const getChildren = (options: FieldOption[], { schema, depth, maxDepth, loadChil | |||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| export const useUserVariable = ({ schema, maxDepth = 3 }: { schema: any; maxDepth?: number }) => { | export const useUserVariable = ({ schema, maxDepth = 3 }: { schema: any; maxDepth?: number }) => { | ||||||
|  |   const { t } = useTranslation(); | ||||||
|   const compile = useCompile(); |   const compile = useCompile(); | ||||||
|   const getFilterOptions = useGetFilterOptions(); |   const getFilterOptions = useGetFilterOptions(); | ||||||
|   const schemaRef = useRef(schema); |  | ||||||
|   schemaRef.current = schema; |  | ||||||
| 
 | 
 | ||||||
|   const loadChildren = (option: Option): Promise<void> => { |   const loadChildren = (option: Option): Promise<void> => { | ||||||
|     if (!option.field?.target) { |     if (!option.field?.target) { | ||||||
| @ -65,14 +68,20 @@ export const useUserVariable = ({ schema, maxDepth = 3 }: { schema: any; maxDept | |||||||
|       setTimeout(() => { |       setTimeout(() => { | ||||||
|         const children = |         const children = | ||||||
|           getChildren(getFilterOptions(collectionName), { |           getChildren(getFilterOptions(collectionName), { | ||||||
|             schema: schemaRef.current, |             schema, | ||||||
|             depth: option.depth + 1, |             depth: option.depth + 1, | ||||||
|             maxDepth, |             maxDepth, | ||||||
|             loadChildren, |             loadChildren, | ||||||
|  |             compile, | ||||||
|           }) || []; |           }) || []; | ||||||
| 
 | 
 | ||||||
|         option.children = compile(children); |         if (children.length === 0) { | ||||||
|         resolve(void 0); |           option.disabled = true; | ||||||
|  |           resolve(); | ||||||
|  |           return; | ||||||
|  |         } | ||||||
|  |         option.children = children; | ||||||
|  |         resolve(); | ||||||
| 
 | 
 | ||||||
|         // 延迟 5 毫秒,防止阻塞主线程,导致 UI 卡顿
 |         // 延迟 5 毫秒,防止阻塞主线程,导致 UI 卡顿
 | ||||||
|       }, 5); |       }, 5); | ||||||
| @ -80,8 +89,8 @@ export const useUserVariable = ({ schema, maxDepth = 3 }: { schema: any; maxDept | |||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|   const result = useMemo(() => { |   const result = useMemo(() => { | ||||||
|     return compile({ |     return { | ||||||
|       label: `{{t("Current user")}}`, |       label: t('Current user'), | ||||||
|       value: '$user', |       value: '$user', | ||||||
|       key: '$user', |       key: '$user', | ||||||
|       children: [], |       children: [], | ||||||
| @ -91,9 +100,8 @@ export const useUserVariable = ({ schema, maxDepth = 3 }: { schema: any; maxDept | |||||||
|       }, |       }, | ||||||
|       depth: 0, |       depth: 0, | ||||||
|       loadChildren, |       loadChildren, | ||||||
|     } as Option); |     } as Option; | ||||||
|   }, []); |   }, [schema?.['x-component']]); | ||||||
| 
 | 
 | ||||||
|   // 必须使用 observable 包一下,使其变成响应式对象,不然 children 加载后不会更新 UI
 |   return result; | ||||||
|   return observable(result); |  | ||||||
| }; | }; | ||||||
|  | |||||||
| @ -1,3 +1,4 @@ | |||||||
|  | import { useMemo } from 'react'; | ||||||
| import { useValues } from '../../../schema-component/antd/filter/useValues'; | import { useValues } from '../../../schema-component/antd/filter/useValues'; | ||||||
| import { useDateVariable } from './useDateVariable'; | import { useDateVariable } from './useDateVariable'; | ||||||
| import { useUserVariable } from './useUserVariable'; | import { useUserVariable } from './useUserVariable'; | ||||||
| @ -7,7 +8,9 @@ export const useVariableOptions = () => { | |||||||
|   const userVariable = useUserVariable({ maxDepth: 3, schema }); |   const userVariable = useUserVariable({ maxDepth: 3, schema }); | ||||||
|   const dateVariable = useDateVariable({ operator, schema }); |   const dateVariable = useDateVariable({ operator, schema }); | ||||||
| 
 | 
 | ||||||
|  |   const result = useMemo(() => [userVariable, dateVariable], [dateVariable, userVariable]); | ||||||
|  | 
 | ||||||
|   if (!operator || !schema) return []; |   if (!operator || !schema) return []; | ||||||
| 
 | 
 | ||||||
|   return [userVariable, dateVariable]; |   return result; | ||||||
| }; | }; | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user