fix: 处理同名组件选择异常情况,文本切换组件阈值,时间选择具体范围 (#712)

Co-authored-by: wjh <wwwjh0710@163.com>
Co-committed-by: wjh <wwwjh0710@163.com>
This commit is contained in:
wjh 2024-04-15 17:40:22 +08:00 committed by baijingfeng
parent a87d95210c
commit 2020643371
8 changed files with 56 additions and 22 deletions

View File

@ -0,0 +1,5 @@
---
"@hera/plugin-mobile": patch
---
修改mobile组件同名切换问题文本切换阈值时间范围

View File

@ -1,7 +1,13 @@
import { useMemo, useState } from 'react'; import { useMemo, useState } from 'react';
import { useFieldSchema } from '@nocobase/schema'; import { useFieldSchema } from '@nocobase/schema';
import { useCollection, useCollectionManager, useDesignable, useDesigner } from '@nocobase/client'; import { useCollection, useCollectionManager, useDesignable, useDesigner } from '@nocobase/client';
import { canBeDataField, canBeRelatedField, convertFormat, isTabSearchCollapsibleInputItem } from '../../utils'; import {
canBeDataField,
canBeRelatedField,
changFormat,
convertFormat,
isTabSearchCollapsibleInputItem,
} from '../../utils';
import { useTabSearchCollapsibleInputItem } from './hooks'; import { useTabSearchCollapsibleInputItem } from './hooks';
import { dayjs } from '@nocobase/utils/client'; import { dayjs } from '@nocobase/utils/client';
@ -11,13 +17,16 @@ export const useTabSearchCollapsibleInputItemAction = (props) => {
const collection = useCollection(); const collection = useCollection();
const cm = useCollectionManager(); const cm = useCollectionManager();
const { dn } = useDesignable(); const { dn } = useDesignable();
const collectionField = useMemo(() => collection?.getField(fieldSchema.name as any), [collection, fieldSchema.name]); const collectionField = useMemo(
() => collection?.getField(fieldSchema['fieldName'] as any),
[collection, fieldSchema['fieldName']],
);
const properties = fieldSchema.parent.properties; const properties = fieldSchema.parent.properties;
const Designer = useDesigner(); const Designer = useDesigner();
const [customLabelKey, setCustomLabelKey] = useState(fieldSchema['name'] as string); const [customLabelKey, setCustomLabelKey] = useState(fieldSchema['fieldName'] as string);
const [fieldInterface, setFieldInterface] = useState(fieldSchema['x-component-props'].interface); const [fieldInterface, setFieldInterface] = useState(fieldSchema['x-component-props'].interface);
const defaultValue = canBeDataField(fieldInterface) const defaultValue = canBeDataField(fieldInterface)
? convertFormat(new Date()) + '&' + convertFormat(new Date()) ? changFormat(dayjs(new Date()).startOf('date')) + '&' + changFormat(dayjs(new Date()).endOf('date'))
: ''; : '';
const [value, setValue] = useState(defaultValue); const [value, setValue] = useState(defaultValue);
const options = Object.values(properties) const options = Object.values(properties)
@ -25,7 +34,7 @@ export const useTabSearchCollapsibleInputItemAction = (props) => {
if (isTabSearchCollapsibleInputItem(option['x-component'])) { if (isTabSearchCollapsibleInputItem(option['x-component'])) {
return { return {
label: option['title'], label: option['title'],
value: option['name'], value: option['fieldName'],
interface: option['x-component-props'].interface, interface: option['x-component-props'].interface,
}; };
} }
@ -36,7 +45,7 @@ export const useTabSearchCollapsibleInputItemAction = (props) => {
let time; let time;
let filterKey = `${customLabelKey}.$includes`; let filterKey = `${customLabelKey}.$includes`;
if (canBeDataField(fieldInterface)) { if (canBeDataField(fieldInterface)) {
time = value.split('&'); time = value.split('&').map((value) => JSON.parse(value));
filterKey = `${customLabelKey}.$dateBetween`; filterKey = `${customLabelKey}.$dateBetween`;
} }
if (canBeRelatedField(fieldInterface)) { if (canBeRelatedField(fieldInterface)) {
@ -48,7 +57,7 @@ export const useTabSearchCollapsibleInputItemAction = (props) => {
}; };
const onSelectChange = (label) => { const onSelectChange = (label) => {
const type = Object.values(properties).find((value) => value.name === label)['x-component-props'].interface; const type = Object.values(properties).find((value) => value['fieldName'] === label)['x-component-props'].interface;
if (canBeRelatedField(type)) { if (canBeRelatedField(type)) {
const titleField = cm.getCollection(collection.name + '.' + label).titleField; const titleField = cm.getCollection(collection.name + '.' + label).titleField;
fieldSchema['x-component-props']['correlation'] = label; fieldSchema['x-component-props']['correlation'] = label;
@ -63,7 +72,7 @@ export const useTabSearchCollapsibleInputItemAction = (props) => {
} }
setFieldInterface(type); setFieldInterface(type);
if (canBeDataField(type)) { if (canBeDataField(type)) {
setValue(convertFormat(new Date()) + '&' + convertFormat(new Date())); setValue(changFormat(new Date()) + '&' + changFormat(new Date()));
} else { } else {
setValue(''); setValue('');
} }

View File

@ -3,7 +3,8 @@ import { useTranslation } from '../../../../locale';
import { Grid, Divider, Picker, Input, Space, ActionSheet, DatePicker, CalendarPicker } from 'antd-mobile'; import { Grid, Divider, Picker, Input, Space, ActionSheet, DatePicker, CalendarPicker } from 'antd-mobile';
import { DownOutline } from 'antd-mobile-icons'; import { DownOutline } from 'antd-mobile-icons';
import type { Action } from 'antd-mobile/es/components/action-sheet'; import type { Action } from 'antd-mobile/es/components/action-sheet';
import { convertFormat } from '../../utils'; import { changFormat, convertFormat } from '../../utils';
import { dayjs } from '@nocobase/utils/client';
export const ISelect = (props) => { export const ISelect = (props) => {
const { options, onChange, customLabelKey } = props; const { options, onChange, customLabelKey } = props;
@ -25,7 +26,7 @@ export const ISelect = (props) => {
{options.find((option) => option.value === customLabelKey).label} {options.find((option) => option.value === customLabelKey).label}
</span> </span>
<DownOutline /> <DownOutline />
{options.length <= 3 ? ( {options.length <= 5 ? (
<ActionSheet <ActionSheet
visible={visible} visible={visible}
actions={actions} actions={actions}
@ -67,13 +68,13 @@ export const IDatePicker = (props) => {
> >
<Grid columns={5}> <Grid columns={5}>
<Grid.Item span={2} style={{ textAlign: 'end' }}> <Grid.Item span={2} style={{ textAlign: 'end' }}>
{time[0]} {convertFormat(JSON.parse(time[0]))}
</Grid.Item> </Grid.Item>
<Grid.Item span={1} style={{ textAlign: 'center' }}> <Grid.Item span={1} style={{ textAlign: 'center' }}>
- -
</Grid.Item> </Grid.Item>
<Grid.Item span={2} style={{ textAlign: 'start' }}> <Grid.Item span={2} style={{ textAlign: 'start' }}>
{time[1]} {convertFormat(JSON.parse(time[1]))}
</Grid.Item> </Grid.Item>
</Grid> </Grid>
</div> </div>
@ -82,9 +83,15 @@ export const IDatePicker = (props) => {
selectionMode="range" selectionMode="range"
onMaskClick={() => setVisible(false)} onMaskClick={() => setVisible(false)}
onClose={() => setVisible(false)} onClose={() => setVisible(false)}
onConfirm={(v) => { onConfirm={([start, end]) => {
onInputChange(convertFormat(v[0]) + '&' + convertFormat(v[1])); const startTime = dayjs(start).startOf('date').toISOString();
onChange(convertFormat(v[0]) + '&' + convertFormat(v[1])); const endTime = dayjs(end).endOf('date').toISOString();
// TODO: 此处受上游影响,格式必须确定为这样, 时间有限,不再往上追查
const timeString = `"${startTime}"&"${endTime}"`;
onInputChange(timeString);
onChange(timeString);
}} }}
/> />
</Grid.Item> </Grid.Item>

View File

@ -9,7 +9,10 @@ export const useTabSearchFieldItemAction = (props) => {
const { t } = useTranslation(); const { t } = useTranslation();
const fieldSchema = useFieldSchema(); const fieldSchema = useFieldSchema();
const c = useCollection(); const c = useCollection();
const collectionField = React.useMemo(() => c?.getField(fieldSchema.name as any), [c, fieldSchema.name]); const collectionField = React.useMemo(
() => c?.getField(fieldSchema['fieldName'] as any),
[c, fieldSchema['fieldName']],
);
const Designer = useDesigner(); const Designer = useDesigner();
const valueKey = _valueKey || collectionField?.targetKey || 'id'; const valueKey = _valueKey || collectionField?.targetKey || 'id';
const labelKey = _labelKey || fieldSchema['x-component-props']?.fieldNames?.label || valueKey; const labelKey = _labelKey || fieldSchema['x-component-props']?.fieldNames?.label || valueKey;

View File

@ -10,7 +10,10 @@ export const useTabSearchFieldItemProps = () => {
const collection = useCollection(); const collection = useCollection();
const optionalFieldList = useOptionalFieldList(); const optionalFieldList = useOptionalFieldList();
const cm = useCollectionManager(); const cm = useCollectionManager();
const collectionField = useMemo(() => collection?.getField(fieldSchema.name as any), [collection, fieldSchema.name]); const collectionField = useMemo(
() => collection?.getField(fieldSchema['fieldName'] as any),
[collection, fieldSchema['fieldName']],
);
const { onSelected } = useTabSearchCollapsibleInputItem(); const { onSelected } = useTabSearchCollapsibleInputItem();
const result = { list: null, valueKey: '', labelKey: '', filterKey: '' }; const result = { list: null, valueKey: '', labelKey: '', filterKey: '' };
if (!collection) return; if (!collection) return;
@ -18,7 +21,7 @@ export const useTabSearchFieldItemProps = () => {
result.labelKey = fieldSchema['x-component-props']?.fieldNames?.label || result.valueKey; result.labelKey = fieldSchema['x-component-props']?.fieldNames?.label || result.valueKey;
const fieldInterface = fieldSchema['x-component-props'].interface; const fieldInterface = fieldSchema['x-component-props'].interface;
if (canBeOptionalField(fieldInterface)) { if (canBeOptionalField(fieldInterface)) {
const field = optionalFieldList.find((field) => field.name === fieldSchema.name); const field = optionalFieldList.find((field) => field.fieldName === fieldSchema['fieldName']);
const operatorMap = { const operatorMap = {
select: '$in', select: '$in',
multipleSelect: '$anyOf', multipleSelect: '$anyOf',
@ -30,7 +33,7 @@ export const useTabSearchFieldItemProps = () => {
result.valueKey = 'value'; result.valueKey = 'value';
result.labelKey = 'label'; result.labelKey = 'label';
result.list = _list; result.list = _list;
result.filterKey = `${field.name}.${operatorMap[field.interface]}`; result.filterKey = `${field.fieldName}.${operatorMap[field.interface]}`;
} }
return { return {

View File

@ -1,11 +1,12 @@
export const createTabSearchItemSchema = (options) => { export const createTabSearchItemSchema = (options) => {
const { field, itemComponent, label, itemUseProps, collection } = options; const { field, itemComponent, label, itemUseProps, collection, type } = options;
return { return {
name: field.key, name: field.key,
title: field.uiSchema?.title, title: field.uiSchema?.title,
Component: 'TabSearchFieldSchemaInitializerGadget', Component: 'TabSearchFieldSchemaInitializerGadget',
schema: { schema: {
name: field.name, name: field.name + type,
fieldName: field.name,
title: field.uiSchema?.title, title: field.uiSchema?.title,
type: 'void', type: 'void',
'x-toolbar': 'CollapseItemSchemaToolbar', 'x-toolbar': 'CollapseItemSchemaToolbar',

View File

@ -24,7 +24,7 @@ const textFieldsItem: SchemaInitializerItemType<any> = {
const label = canBeRelatedField(field.interface) const label = canBeRelatedField(field.interface)
? cm.getCollection(`${collection.name}.${field.name}`).titleField ? cm.getCollection(`${collection.name}.${field.name}`).titleField
: field.name; : field.name;
return createTabSearchItemSchema({ field, itemComponent, label, collection }); return createTabSearchItemSchema({ field, itemComponent, label, collection, type: 'text' });
} }
}) })
.filter(Boolean); .filter(Boolean);
@ -51,6 +51,7 @@ const choicesFieldsItem: SchemaInitializerItemType<any> = {
itemComponent, itemComponent,
label, label,
itemUseProps: 'useTabSearchFieldItemProps', itemUseProps: 'useTabSearchFieldItemProps',
type: 'choices',
}); });
} else if (canBeRelatedField(field.interface)) { } else if (canBeRelatedField(field.interface)) {
return createTabSearchItemSchema({ return createTabSearchItemSchema({
@ -58,6 +59,7 @@ const choicesFieldsItem: SchemaInitializerItemType<any> = {
itemComponent, itemComponent,
label, label,
itemUseProps: 'useTabSearchFieldItemRelatedProps', itemUseProps: 'useTabSearchFieldItemRelatedProps',
type: 'choices',
}); });
} }
}) })

View File

@ -31,3 +31,7 @@ export const canBeSearchField = (_interface: string) => canBeSearchFields.includ
export const convertFormat = (currentDate) => { export const convertFormat = (currentDate) => {
return dayjs(currentDate).format('YYYY-MM-DD'); return dayjs(currentDate).format('YYYY-MM-DD');
}; };
export const changFormat = (currentDate) => {
return JSON.stringify(dayjs(currentDate));
};