fix(client/record-picker): support record-picker show format DataPicker (#888)

* fix(client/record-picker): support record-picker show format DataPicker

* fix(client/record-picker): undefined judgment and when change field's label refresh format in time

(cherry picked from commit 381e71b1f72a8dd092c9e6ad0c36926102b8a7e2)
This commit is contained in:
lyf-coder 2022-10-11 22:43:27 +08:00 committed by chenos
parent d6d2e639ce
commit 47c1764ac3
3 changed files with 47 additions and 13 deletions

View File

@ -9,6 +9,7 @@ import { FormProvider, SchemaComponentOptions } from '../../core';
import { useCompile } from '../../hooks'; import { useCompile } from '../../hooks';
import { ActionContext, useActionContext } from '../action'; import { ActionContext, useActionContext } from '../action';
import { useFieldNames } from './useFieldNames'; import { useFieldNames } from './useFieldNames';
import { getLabelFormatValue, useLabelUiSchema } from './util';
const RecordPickerContext = createContext(null); const RecordPickerContext = createContext(null);
@ -23,15 +24,15 @@ const useTableSelectorProps = () => {
rowSelection: { rowSelection: {
type: multiple ? 'checkbox' : 'radio', type: multiple ? 'checkbox' : 'radio',
// defaultSelectedRowKeys: rcSelectRows?.map((item) => item[rowKey||'id']), // defaultSelectedRowKeys: rcSelectRows?.map((item) => item[rowKey||'id']),
selectedRowKeys: rcSelectRows?.map((item) => item[rowKey||'id']), selectedRowKeys: rcSelectRows?.map((item) => item[rowKey || 'id']),
}, },
onRowSelectionChange(selectedRowKeys, selectedRows) { onRowSelectionChange(selectedRowKeys, selectedRows) {
if (multiple) { if (multiple) {
const scopeRows = field.value || []; const scopeRows = field.value || [];
const allSelectedRows = rcSelectRows || []; const allSelectedRows = rcSelectRows || [];
const otherRows = differenceBy(allSelectedRows, scopeRows, rowKey||'id'); const otherRows = differenceBy(allSelectedRows, scopeRows, rowKey || 'id');
const unionSelectedRows = unionBy(otherRows, selectedRows, rowKey||'id'); const unionSelectedRows = unionBy(otherRows, selectedRows, rowKey || 'id');
const unionSelectedRowKeys = unionSelectedRows.map((item) => item[rowKey||'id']) const unionSelectedRowKeys = unionSelectedRows.map((item) => item[rowKey || 'id']);
setSelectedRows?.(unionSelectedRows); setSelectedRows?.(unionSelectedRows);
onRowSelectionChange?.(unionSelectedRowKeys, unionSelectedRows); onRowSelectionChange?.(unionSelectedRowKeys, unionSelectedRows);
} else { } else {
@ -74,30 +75,31 @@ export const InputRecordPicker: React.FC<any> = (props) => {
const fieldSchema = useFieldSchema(); const fieldSchema = useFieldSchema();
const collectionField = useAssociation(props); const collectionField = useAssociation(props);
const compile = useCompile(); const compile = useCompile();
const labelUiSchema = useLabelUiSchema(collectionField, fieldNames?.label || 'label');
const [selectedRows, setSelectedRows] = useState([]); const [selectedRows, setSelectedRows] = useState([]);
const [options, setOptions] = useState([]); const [options, setOptions] = useState([]);
useEffect(() => { useEffect(() => {
if (value) { if (value) {
const opts = (Array.isArray(value) ? value : value ? [value] : []).map(option => { const opts = (Array.isArray(value) ? value : value ? [value] : []).map((option) => {
const label = option[fieldNames.label]; const label = option[fieldNames.label];
return { return {
...option, ...option,
[fieldNames.label]: compile(label), [fieldNames.label]: getLabelFormatValue(labelUiSchema, compile(label)),
}; };
}); });
setOptions(opts); setOptions(opts);
setSelectedRows(opts); setSelectedRows(opts);
} }
}, [value]) }, [value,fieldNames?.label]);
const getValue = () => { const getValue = () => {
if (multiple == null) return null; if (multiple == null) return null;
// console.log('getValue', multiple, value, Array.isArray(value)); // console.log('getValue', multiple, value, Array.isArray(value));
return Array.isArray(value) ? value?.map(v => v[fieldNames.value]) : value?.[fieldNames.value]; return Array.isArray(value) ? value?.map((v) => v[fieldNames.value]) : value?.[fieldNames.value];
} };
return ( return (
<div> <div>
<Select <Select

View File

@ -10,10 +10,12 @@ import { useCompile } from '../../hooks';
import { ActionContext } from '../action'; import { ActionContext } from '../action';
import { EllipsisWithTooltip } from '../input/EllipsisWithTooltip'; import { EllipsisWithTooltip } from '../input/EllipsisWithTooltip';
import { useFieldNames } from './useFieldNames'; import { useFieldNames } from './useFieldNames';
import { getLabelFormatValue, useLabelUiSchema } from './util';
interface IEllipsisWithTooltipRef { interface IEllipsisWithTooltipRef {
setPopoverVisible: (boolean) => void; setPopoverVisible: (boolean) => void;
} }
export const ReadPrettyRecordPicker: React.FC = observer((props: any) => { export const ReadPrettyRecordPicker: React.FC = observer((props: any) => {
const { ellipsis } = props; const { ellipsis } = props;
const fieldSchema = useFieldSchema(); const fieldSchema = useFieldSchema();
@ -27,10 +29,13 @@ export const ReadPrettyRecordPicker: React.FC = observer((props: any) => {
const collectionField = getField(fieldSchema.name) || getCollectionJoinField(fieldSchema?.['x-collection-field']); const collectionField = getField(fieldSchema.name) || getCollectionJoinField(fieldSchema?.['x-collection-field']);
const [record, setRecord] = useState({}); const [record, setRecord] = useState({});
const compile = useCompile(); const compile = useCompile();
const labelUiSchema = useLabelUiSchema(collectionField, fieldNames?.label || 'label');
const ellipsisWithTooltipRef = useRef<IEllipsisWithTooltipRef>(); const ellipsisWithTooltipRef = useRef<IEllipsisWithTooltipRef>();
const renderRecords = () => const renderRecords = () =>
toArr(field.value).map((record, index, arr) => { toArr(field.value).map((record, index, arr) => {
const val =
compile(record?.[fieldNames?.label || 'label']) || record?.[fieldNames?.value || 'value'] || record?.id;
return ( return (
<Fragment key={`${record.id}_${index}`}> <Fragment key={`${record.id}_${index}`}>
<span> <span>
@ -43,10 +48,10 @@ export const ReadPrettyRecordPicker: React.FC = observer((props: any) => {
ellipsisWithTooltipRef?.current?.setPopoverVisible(false); ellipsisWithTooltipRef?.current?.setPopoverVisible(false);
}} }}
> >
{compile(record?.[fieldNames?.label || 'label']) || record?.[fieldNames?.value || 'value'] || record?.id} {getLabelFormatValue(labelUiSchema, val)}
</a> </a>
</span> </span>
{index < arr.length - 1 ? <span style={{ marginRight: 4, color: '#aaa' }}>, </span> : null} {index < arr.length - 1 ? <span style={{ marginRight: 4, color: '#aaa' }}>,</span> : null}
</Fragment> </Fragment>
); );
}); });

View File

@ -0,0 +1,27 @@
import { getDefaultFormat, str2moment } from '@nocobase/utils/client';
import moment from 'moment';
import { isArr } from '@formily/shared';
import { CollectionFieldOptions, useCollectionManager } from '../../../collection-manager';
import { ISchema } from '@formily/react';
export const useLabelUiSchema = (collectionField: CollectionFieldOptions, label: string): ISchema => {
const { getCollectionJoinField } = useCollectionManager();
const labelField = getCollectionJoinField(`${collectionField.target}.${label}`) as CollectionFieldOptions;
return labelField?.uiSchema;
};
export const getDatePickerLabels = (props): string => {
const format = getDefaultFormat(props) as string;
const m = str2moment(props.value, props) as moment.Moment;
const labels = m && m.isValid() ? m.format(format) : props.value;
return isArr(labels) ? labels.join('~') : labels;
};
export const getLabelFormatValue = (labelUiSchema: ISchema, value: any): string => {
switch (labelUiSchema?.['x-component']) {
case 'DatePicker':
return getDatePickerLabels({ ...labelUiSchema?.['x-component-props'], value });
default:
return value;
}
};