feat: 搜索框
parent
d443f21805
commit
887b47a55a
@ -0,0 +1,225 @@
|
||||
import { createContext, useContext, useEffect, useState } from 'react';
|
||||
import { Form, Input, Row, Col, Select, DatePicker, Space, Button } from 'antd';
|
||||
import { objectMapper, at, isEmpty } from '@/utils/commons';
|
||||
import { DATE_FORMAT } from '@/config';
|
||||
import useFormStore from '@/stores/Form';
|
||||
import usePresets from '@/hooks/usePresets';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
const { RangePicker } = DatePicker;
|
||||
|
||||
const SearchForm = ({ initialValue, onSubmit, onReset, ...props }) => {
|
||||
const { t } = useTranslation();
|
||||
const presets = usePresets();
|
||||
const [formValues, setFormValues] = useFormStore((state) => [state.formValues, state.setFormValues]);
|
||||
const [formValuesToSub, setFormValuesToSub] = useFormStore((state) => [state.formValuesToSub, state.setFormValuesToSub]);
|
||||
const [form] = Form.useForm();
|
||||
const { sort, hides, shows, fieldProps } = {
|
||||
sort: '',
|
||||
// initialValue: '',
|
||||
fieldProps: '',
|
||||
hides: [],
|
||||
shows: [],
|
||||
...props.defaultValue,
|
||||
};
|
||||
const { confirmText } = props;
|
||||
const readValues = { ...initialValue, ...formValues };
|
||||
|
||||
const formValuesMapper = (values) => {
|
||||
const destinationObject = {
|
||||
'referenceNo': { key: 'referenceNo' },
|
||||
'dates': [
|
||||
{ key: 'startdate', transform: (arrVal) => (arrVal ? arrVal[0].format(DATE_FORMAT) : '') },
|
||||
{ key: 'enddate', transform: (arrVal) => (arrVal ? arrVal[1].format(DATE_FORMAT) : '') },
|
||||
],
|
||||
'invoiceStatus': { key: 'invoiceStatus', transform: (value) => value?.value || value?.key || '', default: '' },
|
||||
};
|
||||
let dest = {};
|
||||
const { dates, ...omittedValue } = values;
|
||||
dest = { ...omittedValue, ...objectMapper(values, destinationObject) };
|
||||
for (const key in dest) {
|
||||
if (Object.prototype.hasOwnProperty.call(dest, key)) {
|
||||
dest[key] = typeof dest[key] === 'string' ? (dest[key] || '').trim() : dest[key];
|
||||
}
|
||||
}
|
||||
// omit empty
|
||||
Object.keys(dest).forEach((key) => (dest[key] == null || dest[key] === '' || dest[key].length === 0) && delete dest[key]);
|
||||
return dest;
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const dest = formValuesMapper(formValues);
|
||||
setFormValuesToSub(dest);
|
||||
return () => {};
|
||||
}, []);
|
||||
|
||||
const onFinish = (values) => {
|
||||
console.log('Received values of form, origin form value: ', values);
|
||||
const dest = formValuesMapper(values);
|
||||
console.log('form value send to onSubmit:', dest);
|
||||
const str = new URLSearchParams(dest).toString();
|
||||
setFormValues(values);
|
||||
setFormValuesToSub(dest);
|
||||
if (typeof onSubmit === 'function') {
|
||||
onSubmit(null, dest, values, str);
|
||||
}
|
||||
};
|
||||
|
||||
const handleReset = () => {
|
||||
form.setFieldsValue({
|
||||
// 'DateType': undefined,
|
||||
});
|
||||
if (typeof onReset === 'function') {
|
||||
onReset();
|
||||
}
|
||||
};
|
||||
const onValuesChange = (changedValues, allValues) => {
|
||||
|
||||
const dest = formValuesMapper(allValues);
|
||||
setFormValues(allValues);
|
||||
setFormValuesToSub(dest);
|
||||
// console.log('form onValuesChange', Object.keys(changedValues), args);
|
||||
};
|
||||
return (
|
||||
<>
|
||||
<Form form={form} name='advanced_search' className='orders-search-form' onFinish={onFinish} onValuesChange={onValuesChange}>
|
||||
{/* <EditableContext.Provider value={form}> */}
|
||||
<Row gutter={16}>
|
||||
{getFields({ sort, initialValue: readValues, hides, shows, fieldProps, form, presets, t })}
|
||||
{/* 'textAlign': 'right' */}
|
||||
<Col flex='1 0 90px' className='flex justify-normal items-start' >
|
||||
<Space align='center'>
|
||||
<Button size={'middle'} type='primary' htmlType='submit'>
|
||||
{confirmText || t('Search')}
|
||||
</Button>
|
||||
{/* <Button size="small" onClick={onReset}>
|
||||
重置
|
||||
</Button> */}
|
||||
</Space>
|
||||
</Col>
|
||||
</Row>
|
||||
{/* </EditableContext.Provider> */}
|
||||
</Form>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
function getFields(props) {
|
||||
const { fieldProps, form, presets, t } = props;
|
||||
const bigCol = 4 * 2;
|
||||
const midCol = 6;
|
||||
const layoutProps = {
|
||||
// gutter: { xs: 8, sm: 8, lg: 16 },
|
||||
lg: { span: 4 },
|
||||
md: { span: 8 },
|
||||
sm: { span: 12 },
|
||||
xs: { span: 24 },
|
||||
};
|
||||
const item = (name, sort = 0, render, col) => {
|
||||
const customCol = col || 4;
|
||||
const mdCol = customCol * 2;
|
||||
return {
|
||||
'key': '',
|
||||
sort,
|
||||
name,
|
||||
render,
|
||||
'hide': false,
|
||||
'col': { lg: { span: customCol }, md: { span: mdCol < 8 ? 10 : mdCol }, flex: mdCol < 8 ? '1 0' : '' },
|
||||
};
|
||||
};
|
||||
let baseChildren = [];
|
||||
baseChildren = [
|
||||
item(
|
||||
'referenceNo',
|
||||
99,
|
||||
<Form.Item name='referenceNo'>
|
||||
<Input placeholder={t('group:RefNo')} allowClear />
|
||||
</Form.Item>,4
|
||||
),
|
||||
item(
|
||||
'invoiceStatus',
|
||||
99,
|
||||
<Form.Item name={`invoiceStatus`} initialValue={at(props, 'initialValue.invoiceStatus')[0] || (fieldProps?.invoiceStatus?.show_all ? { key: '-1', label: '所有' } : undefined)}>
|
||||
<Select style={{ width: '100%' }} placeholder='所有状态' labelInValue>
|
||||
{fieldProps?.invoiceStatus?.show_all && (
|
||||
<Select.Option key='所有' value='-1'>
|
||||
所有
|
||||
</Select.Option>
|
||||
)}
|
||||
<Select.Option key='已成行' value='1'>
|
||||
已成行
|
||||
</Select.Option>
|
||||
<Select.Option key='未成行' value='0'>
|
||||
未成行
|
||||
</Select.Option>
|
||||
</Select>
|
||||
</Form.Item>,
|
||||
3
|
||||
),
|
||||
item(
|
||||
'dates',
|
||||
99,
|
||||
<Form.Item name={'dates'} {...fieldProps.dates} initialValue={at(props, 'initialValue.dates')[0]}>
|
||||
{/* <DatePickerCharts isform={true} {...fieldProps.dates} form={form} /> */}
|
||||
<RangePicker
|
||||
allowClear={true}
|
||||
inputReadOnly={true}
|
||||
presets={presets}
|
||||
// defaultValue={toJS(arrivalDateRange)}
|
||||
placeholder={['From', 'Thru']}
|
||||
// onChange={(dateRange) => {
|
||||
// reservationStore.updatePropertyValue('arrivalDateRange', dateRange == null ? [] : dateRange)
|
||||
// }}
|
||||
/>
|
||||
</Form.Item>,
|
||||
fieldProps?.dates?.col || midCol
|
||||
),
|
||||
];
|
||||
baseChildren = baseChildren
|
||||
.map((x) => {
|
||||
x.hide = false;
|
||||
if (props.sort === undefined) {
|
||||
return x;
|
||||
}
|
||||
const tmpSort = props.sort;
|
||||
for (const key in tmpSort) {
|
||||
if (Object.prototype.hasOwnProperty.call(tmpSort, key)) {
|
||||
if (x.name === key) {
|
||||
x.sort = tmpSort[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
return x;
|
||||
})
|
||||
.map((x) => {
|
||||
if (props.hides.length === 0 && props.shows.length === 0) {
|
||||
return x;
|
||||
}
|
||||
if (props.hides.length === 0) {
|
||||
x.hide = !props.shows.includes(x.name);
|
||||
} else if (props.shows.length === 0) {
|
||||
x.hide = props.hides.includes(x.name);
|
||||
}
|
||||
return x;
|
||||
})
|
||||
.filter((x) => !x.hide)
|
||||
.sort((a, b) => {
|
||||
return a.sort < b.sort ? -1 : 1;
|
||||
});
|
||||
const children = [];
|
||||
const leftStyle = {}; // { borderRight: '1px solid #dedede' };
|
||||
for (let i = 0; i < baseChildren.length; i++) {
|
||||
let style = {}; // { padding: '0px 2px' };
|
||||
style = i % 2 === 0 && baseChildren[i].col === 12 ? { ...style, ...leftStyle } : style;
|
||||
style = !baseChildren[i].hide ? { ...style, display: 'block' } : { ...style, display: 'none' };
|
||||
const Item = (
|
||||
<Col key={String(i)} style={style} {...layoutProps} {...baseChildren[i].col}>
|
||||
{baseChildren[i].render}
|
||||
</Col>
|
||||
);
|
||||
children.push(Item);
|
||||
}
|
||||
return children;
|
||||
}
|
||||
|
||||
export default SearchForm;
|
@ -0,0 +1,12 @@
|
||||
import { create } from 'zustand';
|
||||
import { devtools } from 'zustand/middleware';
|
||||
|
||||
export const useFormStore = create(
|
||||
devtools((set, get) => ({
|
||||
formValues: {},
|
||||
setFormValues: (values) => set((state) => ({ formValues: { ...state.formValues, ...values } })),
|
||||
formValuesToSub: {},
|
||||
setFormValuesToSub: (values) => set((state) => ({ formValuesToSub: { ...state.formValuesToSub, ...values } })),
|
||||
}))
|
||||
);
|
||||
export default useFormStore;
|
Loading…
Reference in New Issue