refactor: initialization when switching field components (#1915)
* fix: toManyNester only display one data * fix: sub-nester * fix: initialValue * fix: [null] * fix: record picker initValue * fix: initValue filter * fix: association select initialValue filter * fix: association select initialValue filter * fix: [null] --------- Co-authored-by: chenos <chenlinxh@gmail.com>
This commit is contained in:
parent
a0dd58e7e3
commit
e299f5452c
@ -1,7 +1,7 @@
|
|||||||
import { Schema, SchemaExpressionScopeContext, useField, useFieldSchema, useForm } from '@formily/react';
|
import { Schema, SchemaExpressionScopeContext, useField, useFieldSchema, useForm } from '@formily/react';
|
||||||
import { parse } from '@nocobase/utils/client';
|
import { parse } from '@nocobase/utils/client';
|
||||||
import { Modal, message } from 'antd';
|
import { Modal, message } from 'antd';
|
||||||
import { cloneDeep, isEqual, uniq, omitBy } from 'lodash';
|
import { cloneDeep, uniq } from 'lodash';
|
||||||
import get from 'lodash/get';
|
import get from 'lodash/get';
|
||||||
import omit from 'lodash/omit';
|
import omit from 'lodash/omit';
|
||||||
import { ChangeEvent, useContext, useEffect } from 'react';
|
import { ChangeEvent, useContext, useEffect } from 'react';
|
||||||
@ -16,12 +16,12 @@ import { transformToFilter } from '../../filter-provider/utils';
|
|||||||
import { useRecord } from '../../record-provider';
|
import { useRecord } from '../../record-provider';
|
||||||
import { removeNullCondition, useActionContext, useCompile } from '../../schema-component';
|
import { removeNullCondition, useActionContext, useCompile } from '../../schema-component';
|
||||||
import { BulkEditFormItemValueType } from '../../schema-initializer/components';
|
import { BulkEditFormItemValueType } from '../../schema-initializer/components';
|
||||||
|
import { useSchemaTemplateManager } from '../../schema-templates';
|
||||||
import { useCurrentUserContext } from '../../user';
|
import { useCurrentUserContext } from '../../user';
|
||||||
import { useBlockRequestContext, useFilterByTk } from '../BlockProvider';
|
import { useBlockRequestContext, useFilterByTk } from '../BlockProvider';
|
||||||
import { useDetailsBlockContext } from '../DetailsBlockProvider';
|
import { useDetailsBlockContext } from '../DetailsBlockProvider';
|
||||||
import { mergeFilter } from '../SharedFilterProvider';
|
import { mergeFilter } from '../SharedFilterProvider';
|
||||||
import { TableFieldResource } from '../TableFieldProvider';
|
import { TableFieldResource } from '../TableFieldProvider';
|
||||||
import { useSchemaTemplateManager } from '../../schema-templates';
|
|
||||||
|
|
||||||
export const usePickActionProps = () => {
|
export const usePickActionProps = () => {
|
||||||
const form = useForm();
|
const form = useForm();
|
||||||
@ -158,8 +158,8 @@ export const useCreateActionProps = () => {
|
|||||||
if (!skipValidator) {
|
if (!skipValidator) {
|
||||||
await form.submit();
|
await form.submit();
|
||||||
}
|
}
|
||||||
const formValues = getFormValues(filterByTk, field, form, fieldNames, getField, resource);
|
const values = getFormValues(filterByTk, field, form, fieldNames, getField, resource);
|
||||||
const values = omitBy(formValues, (value) => isEqual(JSON.stringify(value), '[{}]'));
|
// const values = omitBy(formValues, (value) => isEqual(JSON.stringify(value), '[{}]'));
|
||||||
if (addChild) {
|
if (addChild) {
|
||||||
const treeParentField = getTreeParentField();
|
const treeParentField = getTreeParentField();
|
||||||
values[treeParentField?.name ?? 'parent'] = currentRecord;
|
values[treeParentField?.name ?? 'parent'] = currentRecord;
|
||||||
|
@ -1,12 +1,9 @@
|
|||||||
import { ISchema } from '@formily/react';
|
import { ISchema } from '@formily/react';
|
||||||
import { uid } from '@formily/shared';
|
import { uid } from '@formily/shared';
|
||||||
import { cloneDeep } from 'lodash';
|
|
||||||
import {
|
import {
|
||||||
defaultProps,
|
defaultProps,
|
||||||
recordPickerSelector,
|
|
||||||
recordPickerViewer,
|
|
||||||
relationshipType,
|
relationshipType,
|
||||||
reverseFieldProperties,
|
reverseFieldProperties
|
||||||
} from './properties';
|
} from './properties';
|
||||||
import { IField } from './types';
|
import { IField } from './types';
|
||||||
|
|
||||||
@ -53,7 +50,7 @@ export const m2m: IField = {
|
|||||||
},
|
},
|
||||||
availableTypes: ['belongsToMany'],
|
availableTypes: ['belongsToMany'],
|
||||||
schemaInitialize(schema: ISchema, { readPretty, block, targetCollection }) {
|
schemaInitialize(schema: ISchema, { readPretty, block, targetCollection }) {
|
||||||
schema['type'] = 'array';
|
// schema['type'] = 'array';
|
||||||
if (targetCollection?.titleField && schema['x-component-props']) {
|
if (targetCollection?.titleField && schema['x-component-props']) {
|
||||||
schema['x-component-props'].fieldNames = schema['x-component-props'].fieldNames || { value: 'id' };
|
schema['x-component-props'].fieldNames = schema['x-component-props'].fieldNames || { value: 'id' };
|
||||||
schema['x-component-props'].fieldNames.label = targetCollection.titleField;
|
schema['x-component-props'].fieldNames.label = targetCollection.titleField;
|
||||||
|
@ -1,11 +1,8 @@
|
|||||||
import { ISchema } from '@formily/react';
|
import { ISchema } from '@formily/react';
|
||||||
import { cloneDeep } from 'lodash';
|
|
||||||
import {
|
import {
|
||||||
constraintsProps,
|
constraintsProps,
|
||||||
recordPickerSelector,
|
|
||||||
recordPickerViewer,
|
|
||||||
relationshipType,
|
relationshipType,
|
||||||
reverseFieldProperties,
|
reverseFieldProperties
|
||||||
} from './properties';
|
} from './properties';
|
||||||
import { IField } from './types';
|
import { IField } from './types';
|
||||||
|
|
||||||
@ -52,7 +49,7 @@ export const m2o: IField = {
|
|||||||
},
|
},
|
||||||
availableTypes: ['belongsTo'],
|
availableTypes: ['belongsTo'],
|
||||||
schemaInitialize(schema: ISchema, { block, readPretty, targetCollection }) {
|
schemaInitialize(schema: ISchema, { block, readPretty, targetCollection }) {
|
||||||
schema['type'] = 'object';
|
// schema['type'] = 'object';
|
||||||
if (targetCollection?.titleField && schema['x-component-props']) {
|
if (targetCollection?.titleField && schema['x-component-props']) {
|
||||||
schema['x-component-props'].fieldNames = schema['x-component-props'].fieldNames || { value: 'id' };
|
schema['x-component-props'].fieldNames = schema['x-component-props'].fieldNames || { value: 'id' };
|
||||||
schema['x-component-props'].fieldNames.label = targetCollection.titleField;
|
schema['x-component-props'].fieldNames.label = targetCollection.titleField;
|
||||||
|
@ -1,12 +1,5 @@
|
|||||||
import { ISchema } from '@formily/react';
|
import { ISchema } from '@formily/react';
|
||||||
import { cloneDeep } from 'lodash';
|
import { constraintsProps, relationshipType, reverseFieldProperties } from './properties';
|
||||||
import {
|
|
||||||
constraintsProps,
|
|
||||||
recordPickerSelector,
|
|
||||||
recordPickerViewer,
|
|
||||||
relationshipType,
|
|
||||||
reverseFieldProperties,
|
|
||||||
} from './properties';
|
|
||||||
import { IField } from './types';
|
import { IField } from './types';
|
||||||
|
|
||||||
export const o2m: IField = {
|
export const o2m: IField = {
|
||||||
@ -52,7 +45,7 @@ export const o2m: IField = {
|
|||||||
},
|
},
|
||||||
availableTypes: ['hasMany'],
|
availableTypes: ['hasMany'],
|
||||||
schemaInitialize(schema: ISchema, { field, block, readPretty, targetCollection }) {
|
schemaInitialize(schema: ISchema, { field, block, readPretty, targetCollection }) {
|
||||||
schema['type'] = 'array';
|
// schema['type'] = 'array';
|
||||||
if (targetCollection?.titleField && schema['x-component-props']) {
|
if (targetCollection?.titleField && schema['x-component-props']) {
|
||||||
schema['x-component-props'].fieldNames = schema['x-component-props'].fieldNames || { value: 'id' };
|
schema['x-component-props'].fieldNames = schema['x-component-props'].fieldNames || { value: 'id' };
|
||||||
schema['x-component-props'].fieldNames.label = targetCollection.titleField;
|
schema['x-component-props'].fieldNames.label = targetCollection.titleField;
|
||||||
|
@ -1,12 +1,5 @@
|
|||||||
import { ISchema } from '@formily/react';
|
import { ISchema } from '@formily/react';
|
||||||
import { cloneDeep } from 'lodash';
|
import { constraintsProps, relationshipType, reverseFieldProperties } from './properties';
|
||||||
import {
|
|
||||||
constraintsProps,
|
|
||||||
recordPickerSelector,
|
|
||||||
recordPickerViewer,
|
|
||||||
relationshipType,
|
|
||||||
reverseFieldProperties,
|
|
||||||
} from './properties';
|
|
||||||
import { IField } from './types';
|
import { IField } from './types';
|
||||||
|
|
||||||
export const o2o: IField = {
|
export const o2o: IField = {
|
||||||
@ -231,7 +224,7 @@ export const oho: IField = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
schemaInitialize(schema: ISchema, { field, block, readPretty, action }) {
|
schemaInitialize(schema: ISchema, { field, block, readPretty, action }) {
|
||||||
schema['type'] = 'object';
|
// schema['type'] = 'object';
|
||||||
if (['Table', 'Kanban'].includes(block)) {
|
if (['Table', 'Kanban'].includes(block)) {
|
||||||
schema['x-component-props'] = schema['x-component-props'] || {};
|
schema['x-component-props'] = schema['x-component-props'] || {};
|
||||||
schema['x-component-props']['ellipsis'] = true;
|
schema['x-component-props']['ellipsis'] = true;
|
||||||
@ -401,7 +394,7 @@ export const obo: IField = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
schemaInitialize(schema: ISchema, { field, block, readPretty, action, targetCollection }) {
|
schemaInitialize(schema: ISchema, { field, block, readPretty, action, targetCollection }) {
|
||||||
schema['type'] = 'object';
|
// schema['type'] = 'object';
|
||||||
if (['Table', 'Kanban'].includes(block)) {
|
if (['Table', 'Kanban'].includes(block)) {
|
||||||
schema['x-component-props'] = schema['x-component-props'] || {};
|
schema['x-component-props'] = schema['x-component-props'] || {};
|
||||||
schema['x-component-props']['ellipsis'] = true;
|
schema['x-component-props']['ellipsis'] = true;
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
|
import { Field } from '@formily/core';
|
||||||
import { observer, useField, useFieldSchema } from '@formily/react';
|
import { observer, useField, useFieldSchema } from '@formily/react';
|
||||||
import React, { useMemo } from 'react';
|
import React, { useMemo } from 'react';
|
||||||
import { useCollectionManager } from '../../../collection-manager';
|
import { useCollectionManager } from '../../../collection-manager';
|
||||||
import { AssociationFieldContext } from './context';
|
import { AssociationFieldContext } from './context';
|
||||||
|
|
||||||
export const AssociationFieldProvider = observer((props) => {
|
export const AssociationFieldProvider = observer((props) => {
|
||||||
const field = useField();
|
const field = useField<Field>();
|
||||||
const { getCollectionJoinField, getCollection } = useCollectionManager();
|
const { getCollectionJoinField, getCollection } = useCollectionManager();
|
||||||
const fieldSchema = useFieldSchema();
|
const fieldSchema = useFieldSchema();
|
||||||
|
|
||||||
@ -20,6 +21,7 @@ export const AssociationFieldProvider = observer((props) => {
|
|||||||
() => fieldSchema['x-component-props']?.mode || (isFileCollection ? 'FileManager' : 'Select'),
|
() => fieldSchema['x-component-props']?.mode || (isFileCollection ? 'FileManager' : 'Select'),
|
||||||
[fieldSchema['x-component-props']?.mode],
|
[fieldSchema['x-component-props']?.mode],
|
||||||
);
|
);
|
||||||
|
|
||||||
return collectionField ? (
|
return collectionField ? (
|
||||||
<AssociationFieldContext.Provider value={{ options: collectionField, field, currentMode }}>
|
<AssociationFieldContext.Provider value={{ options: collectionField, field, currentMode }}>
|
||||||
{props.children}
|
{props.children}
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
import { LoadingOutlined } from '@ant-design/icons';
|
import { LoadingOutlined } from '@ant-design/icons';
|
||||||
import { RecursionField, connect, mapProps, observer, useField, useFieldSchema } from '@formily/react';
|
import { RecursionField, connect, mapProps, observer, useField, useFieldSchema } from '@formily/react';
|
||||||
import { Input } from 'antd';
|
import { Input } from 'antd';
|
||||||
import React, { useCallback, useEffect, useMemo } from 'react';
|
import React from 'react';
|
||||||
import { useFieldTitle } from '../../hooks';
|
|
||||||
import { RemoteSelect, RemoteSelectProps } from '../remote-select';
|
import { RemoteSelect, RemoteSelectProps } from '../remote-select';
|
||||||
import useServiceOptions from './hooks';
|
import useServiceOptions from './hooks';
|
||||||
|
|
||||||
@ -17,28 +16,8 @@ const InternalAssociationSelect = observer((props: AssociationSelectProps) => {
|
|||||||
const fieldSchema = useFieldSchema();
|
const fieldSchema = useFieldSchema();
|
||||||
const service = useServiceOptions(props);
|
const service = useServiceOptions(props);
|
||||||
const isAllowAddNew = fieldSchema['x-add-new'];
|
const isAllowAddNew = fieldSchema['x-add-new'];
|
||||||
const normalizeValues = useCallback(
|
const value = Array.isArray(props.value) ? props.value.filter(Boolean) : props.value;
|
||||||
(obj) => {
|
|
||||||
if (!objectValue && typeof obj === 'object') {
|
|
||||||
return obj[fieldNames?.value];
|
|
||||||
}
|
|
||||||
return obj;
|
|
||||||
},
|
|
||||||
[objectValue, fieldNames?.value],
|
|
||||||
);
|
|
||||||
const value = useMemo(() => {
|
|
||||||
if (props.value === undefined || props.value === null || !Object.keys(props.value).length) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (Array.isArray(props.value)) {
|
|
||||||
return props.value;
|
|
||||||
} else {
|
|
||||||
return props.value;
|
|
||||||
}
|
|
||||||
}, [props.value, normalizeValues]);
|
|
||||||
useEffect(() => {
|
|
||||||
field.value = value;
|
|
||||||
}, []);
|
|
||||||
return (
|
return (
|
||||||
<div key={fieldSchema.name}>
|
<div key={fieldSchema.name}>
|
||||||
<Input.Group compact style={{ display: 'flex' }}>
|
<Input.Group compact style={{ display: 'flex' }}>
|
||||||
@ -75,9 +54,8 @@ export const AssociationSelect = InternalAssociationSelect as unknown as Associa
|
|||||||
|
|
||||||
export const AssociationSelectReadPretty = connect(
|
export const AssociationSelectReadPretty = connect(
|
||||||
(props: any) => {
|
(props: any) => {
|
||||||
if (props.fieldNames) {
|
|
||||||
const service = useServiceOptions(props);
|
const service = useServiceOptions(props);
|
||||||
useFieldTitle();
|
if (props.fieldNames) {
|
||||||
return <RemoteSelect.ReadPretty {...props} service={service}></RemoteSelect.ReadPretty>;
|
return <RemoteSelect.ReadPretty {...props} service={service}></RemoteSelect.ReadPretty>;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { observer, useField, useFieldSchema, useForm } from '@formily/react';
|
import { observer, useField, useFieldSchema, useForm } from '@formily/react';
|
||||||
import React from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import { SchemaComponentOptions } from '../../';
|
import { SchemaComponentOptions } from '../../';
|
||||||
import { useAssociationCreateActionProps as useCAP } from '../../../block-provider/hooks';
|
import { useAssociationCreateActionProps as useCAP } from '../../../block-provider/hooks';
|
||||||
import { AssociationFieldProvider } from './AssociationFieldProvider';
|
import { AssociationFieldProvider } from './AssociationFieldProvider';
|
||||||
@ -17,6 +17,31 @@ const EditableAssociationField = observer((props: any) => {
|
|||||||
const form = useForm();
|
const form = useForm();
|
||||||
const fieldSchema = useFieldSchema();
|
const fieldSchema = useFieldSchema();
|
||||||
const { options: collectionField, currentMode } = useAssociationFieldContext();
|
const { options: collectionField, currentMode } = useAssociationFieldContext();
|
||||||
|
const [loading, setLoading] = useState(true);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setLoading(true);
|
||||||
|
if (!collectionField) {
|
||||||
|
setLoading(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (field.value !== null && field.value !== undefined) {
|
||||||
|
setLoading(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (currentMode === 'Nester') {
|
||||||
|
if (['belongsTo', 'hasOne'].includes(collectionField.type)) {
|
||||||
|
field.value = {};
|
||||||
|
} else if (['belongsToMany', 'hasMany'].includes(collectionField.type)) {
|
||||||
|
field.value = [null];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setLoading(false);
|
||||||
|
}, [currentMode, collectionField, field.value]);
|
||||||
|
|
||||||
|
if (loading) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
const useCreateActionProps = () => {
|
const useCreateActionProps = () => {
|
||||||
const { onClick } = useCAP();
|
const { onClick } = useCAP();
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { RecursionField, observer, useField, useFieldSchema } from '@formily/react';
|
import { RecursionField, observer, useField, useFieldSchema } from '@formily/react';
|
||||||
import { Input, Select } from 'antd';
|
import { Input, Select } from 'antd';
|
||||||
import { differenceBy, unionBy } from 'lodash';
|
import { differenceBy, unionBy } from 'lodash';
|
||||||
import React, { useContext, useEffect, useState } from 'react';
|
import React, { useContext, useEffect, useMemo, useState } from 'react';
|
||||||
import {
|
import {
|
||||||
FormProvider,
|
FormProvider,
|
||||||
RecordPickerContext,
|
RecordPickerContext,
|
||||||
@ -71,7 +71,20 @@ export const InternalPicker = observer((props: any) => {
|
|||||||
const labelUiSchema = useLabelUiSchema(collectionField, fieldNames?.label || 'label');
|
const labelUiSchema = useLabelUiSchema(collectionField, fieldNames?.label || 'label');
|
||||||
const isAllowAddNew = fieldSchema['x-add-new'];
|
const isAllowAddNew = fieldSchema['x-add-new'];
|
||||||
const [selectedRows, setSelectedRows] = useState([]);
|
const [selectedRows, setSelectedRows] = useState([]);
|
||||||
const [options, setOptions] = useState([]);
|
const options = useMemo(() => {
|
||||||
|
if (value && Object.keys(value).length > 0) {
|
||||||
|
const opts = (Array.isArray(value) ? value : value ? [value] : []).filter(Boolean).map((option) => {
|
||||||
|
const label = option?.[fieldNames.label];
|
||||||
|
return {
|
||||||
|
...option,
|
||||||
|
[fieldNames.label]: getLabelFormatValue(compile(labelUiSchema), compile(label)),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
return opts;
|
||||||
|
}
|
||||||
|
return [];
|
||||||
|
}, [value, fieldNames?.label]);
|
||||||
|
|
||||||
const pickerProps = {
|
const pickerProps = {
|
||||||
size: 'small',
|
size: 'small',
|
||||||
fieldNames,
|
fieldNames,
|
||||||
@ -85,24 +98,11 @@ export const InternalPicker = observer((props: any) => {
|
|||||||
setSelectedRows,
|
setSelectedRows,
|
||||||
collectionField,
|
collectionField,
|
||||||
};
|
};
|
||||||
useEffect(() => {
|
|
||||||
if (value && Object.keys(value).length > 0) {
|
|
||||||
const opts = (Array.isArray(value) ? value : value ? [value] : []).map((option) => {
|
|
||||||
const label = option[fieldNames.label];
|
|
||||||
return {
|
|
||||||
...option,
|
|
||||||
[fieldNames.label]: getLabelFormatValue(compile(labelUiSchema), compile(label)),
|
|
||||||
};
|
|
||||||
});
|
|
||||||
setOptions(opts);
|
|
||||||
}
|
|
||||||
}, [value, fieldNames?.label]);
|
|
||||||
|
|
||||||
const getValue = () => {
|
const getValue = () => {
|
||||||
if (multiple == null) return null;
|
if (multiple == null) return null;
|
||||||
return Array.isArray(value) ? value?.map((v) => v[fieldNames.value]) : value?.[fieldNames.value];
|
return Array.isArray(value) ? value.filter(Boolean)?.map((v) => v?.[fieldNames.value]) : value?.[fieldNames.value];
|
||||||
};
|
};
|
||||||
|
|
||||||
const getFilter = () => {
|
const getFilter = () => {
|
||||||
const targetKey = collectionField?.targetKey || 'id';
|
const targetKey = collectionField?.targetKey || 'id';
|
||||||
const list = options.map((option) => option[targetKey]).filter(Boolean);
|
const list = options.map((option) => option[targetKey]).filter(Boolean);
|
||||||
|
@ -2,7 +2,7 @@ import { CloseCircleOutlined } from '@ant-design/icons';
|
|||||||
import { ArrayField } from '@formily/core';
|
import { ArrayField } from '@formily/core';
|
||||||
import { RecursionField, observer, useFieldSchema } from '@formily/react';
|
import { RecursionField, observer, useFieldSchema } from '@formily/react';
|
||||||
import { Button, Card, Divider } from 'antd';
|
import { Button, Card, Divider } from 'antd';
|
||||||
import React, { useContext, useEffect, useState } from 'react';
|
import React, { useContext } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { AssociationFieldContext } from './context';
|
import { AssociationFieldContext } from './context';
|
||||||
import { useAssociationFieldContext } from './hooks';
|
import { useAssociationFieldContext } from './hooks';
|
||||||
@ -22,28 +22,13 @@ const ToOneNester = (props) => {
|
|||||||
return <Card bordered={true}>{props.children}</Card>;
|
return <Card bordered={true}>{props.children}</Card>;
|
||||||
};
|
};
|
||||||
|
|
||||||
const toArr = (value, isReadpretty) => {
|
|
||||||
if (!value) {
|
|
||||||
return isReadpretty ? [] : [{}];
|
|
||||||
}
|
|
||||||
if (Array.isArray(value)) {
|
|
||||||
return value.length > 0 ? value : isReadpretty ? [] : [{}];
|
|
||||||
}
|
|
||||||
return [value];
|
|
||||||
};
|
|
||||||
|
|
||||||
const ToManyNester = observer((props) => {
|
const ToManyNester = observer((props) => {
|
||||||
const fieldSchema = useFieldSchema();
|
const fieldSchema = useFieldSchema();
|
||||||
const { field } = useAssociationFieldContext<ArrayField>();
|
const { field } = useAssociationFieldContext<ArrayField>();
|
||||||
const [values, setValues] = useState([]);
|
|
||||||
useEffect(() => {
|
|
||||||
const values = toArr(field.value, field.readPretty);
|
|
||||||
setValues(values);
|
|
||||||
}, []);
|
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
return (
|
return (
|
||||||
<Card bordered={true} style={{ position: 'relative' }}>
|
<Card bordered={true} style={{ position: 'relative' }}>
|
||||||
{values.map((value, index) => {
|
{(field.value || []).map((value, index) => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{!field.readPretty && (
|
{!field.readPretty && (
|
||||||
@ -51,9 +36,9 @@ const ToManyNester = observer((props) => {
|
|||||||
<CloseCircleOutlined
|
<CloseCircleOutlined
|
||||||
style={{ zIndex: 1000, position: 'absolute', color: '#a8a3a3' }}
|
style={{ zIndex: 1000, position: 'absolute', color: '#a8a3a3' }}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
const data = values.concat();
|
const result = field.value;
|
||||||
data.splice(index, 1);
|
result.splice(index, 1);
|
||||||
setValues(data);
|
field.value = result;
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@ -68,9 +53,9 @@ const ToManyNester = observer((props) => {
|
|||||||
type={'dashed'}
|
type={'dashed'}
|
||||||
block
|
block
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
const data = values.concat();
|
const result = field.value;
|
||||||
data.push({});
|
result.push({});
|
||||||
setValues(data);
|
field.value = result;
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{t('Add new')}
|
{t('Add new')}
|
||||||
|
@ -172,7 +172,7 @@ FormItem.Designer = function Designer() {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
const fieldSchemaWithoutRequired = _.omit(fieldSchema,'required')
|
const fieldSchemaWithoutRequired = _.omit(fieldSchema, 'required');
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<GeneralSchemaDesigner>
|
<GeneralSchemaDesigner>
|
||||||
@ -574,10 +574,10 @@ FormItem.Designer = function Designer() {
|
|||||||
schema['x-component-props'] = fieldSchema['x-component-props'];
|
schema['x-component-props'] = fieldSchema['x-component-props'];
|
||||||
field.componentProps = field.componentProps || {};
|
field.componentProps = field.componentProps || {};
|
||||||
field.componentProps.mode = mode;
|
field.componentProps.mode = mode;
|
||||||
if (mode === 'Nester') {
|
// if (mode === 'Nester') {
|
||||||
const initValue = ['hasMany', 'belongsToMany'].includes(collectionField?.type) ? [] : {};
|
// const initValue = ['hasMany', 'belongsToMany'].includes(collectionField?.type) ? [{}] : {};
|
||||||
field.value = field.value || initValue;
|
// field.value = field.value || initValue;
|
||||||
}
|
// }
|
||||||
dn.emit('patch', {
|
dn.emit('patch', {
|
||||||
schema,
|
schema,
|
||||||
});
|
});
|
||||||
|
@ -111,7 +111,7 @@ export class UpdateGuard {
|
|||||||
|
|
||||||
if (Array.isArray(associationValues)) {
|
if (Array.isArray(associationValues)) {
|
||||||
associationValues = associationValues.map((value) => {
|
associationValues = associationValues.map((value) => {
|
||||||
if (typeof value == 'string' || typeof value == 'number') {
|
if (value === undefined || value === null || typeof value == 'string' || typeof value == 'number') {
|
||||||
return value;
|
return value;
|
||||||
} else {
|
} else {
|
||||||
return sanitizeValue(value);
|
return sanitizeValue(value);
|
||||||
|
@ -0,0 +1,45 @@
|
|||||||
|
import { Migration } from '@nocobase/server';
|
||||||
|
import UiSchemaRepository from '../repository';
|
||||||
|
|
||||||
|
export default class extends Migration {
|
||||||
|
async up() {
|
||||||
|
const result = await this.app.version.satisfies('<0.9.3-alpha.2');
|
||||||
|
|
||||||
|
if (!result) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const r = this.db.getRepository<UiSchemaRepository>('uiSchemas');
|
||||||
|
const items = await r.find({
|
||||||
|
filter: {
|
||||||
|
'schema.x-component': 'CollectionField',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
console.log(items?.length);
|
||||||
|
await this.db.sequelize.transaction(async (transaction) => {
|
||||||
|
for (const item of items) {
|
||||||
|
const schema = item.schema;
|
||||||
|
if (!schema['x-collection-field']) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (schema['type'] === 'string') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const field = this.db.getFieldByPath(schema['x-collection-field']);
|
||||||
|
if (!field) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
console.log(schema['x-collection-field'], schema['type']);
|
||||||
|
if (['hasOne', 'belongsTo'].includes(field.type)) {
|
||||||
|
schema['type'] = 'string';
|
||||||
|
} else if (['hasMany', 'belongsToMany'].includes(field.type)) {
|
||||||
|
schema['type'] = 'string';
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
item.set('schema', schema);
|
||||||
|
await item.save({ transaction });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user