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
|
if (useTypedConstant) {
|
||||||
? getTypedConstantOption(type, useTypedConstant)
|
return getTypedConstantOption(type, useTypedConstant);
|
||||||
: {
|
}
|
||||||
|
return {
|
||||||
value: '',
|
value: '',
|
||||||
label: '{{t("Null")}}',
|
label: '{{t("Null")}}',
|
||||||
component: ConstantTypes.null.component,
|
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 {
|
||||||
|
label: t('Date variables'),
|
||||||
value: '$date',
|
value: '$date',
|
||||||
key: '$date',
|
key: '$date',
|
||||||
disabled: dateOptions.every((option) => option.disabled),
|
disabled: dateOptions.every((option) => option.disabled),
|
||||||
children: dateOptions,
|
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