mirror of
https://gitee.com/nocobase/nocobase.git
synced 2025-05-05 13:39:24 +08:00
fix(kanban): fix incorrect appends parameter issue (#5592)
* refactor(kanban): optimize get appends function * fix(kanban): fix incorrect appends parameter issue * chore: remove useless code
This commit is contained in:
parent
ee1dd2375f
commit
a6f16acf1c
@ -0,0 +1,248 @@
|
||||
/**
|
||||
* This file is part of the NocoBase (R) project.
|
||||
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
||||
* Authors: NocoBase Team.
|
||||
*
|
||||
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
||||
* For more information, please refer to: https://www.nocobase.com/agreement.
|
||||
*/
|
||||
|
||||
import { Schema } from '@formily/json-schema';
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { getAppends } from '../../hooks/index';
|
||||
|
||||
describe('getAppends', () => {
|
||||
const mockGetCollectionJoinField = (name: string) => {
|
||||
const fields = {
|
||||
'users.profile': {
|
||||
type: 'hasOne',
|
||||
target: 'profiles',
|
||||
},
|
||||
'users.posts': {
|
||||
type: 'hasMany',
|
||||
target: 'posts',
|
||||
},
|
||||
'posts.author': {
|
||||
type: 'belongsTo',
|
||||
target: 'users',
|
||||
},
|
||||
'users.roles': {
|
||||
type: 'belongsToMany',
|
||||
target: 'roles',
|
||||
},
|
||||
'users.categories': {
|
||||
type: 'belongsToArray',
|
||||
target: 'categories',
|
||||
},
|
||||
};
|
||||
return fields[name];
|
||||
};
|
||||
|
||||
const mockGetCollection = (name: string) => {
|
||||
const collections = {
|
||||
categories: {
|
||||
template: 'tree',
|
||||
},
|
||||
users: {
|
||||
template: 'general',
|
||||
},
|
||||
};
|
||||
return collections[name];
|
||||
};
|
||||
|
||||
const createSchema = (properties) => {
|
||||
return new Schema({
|
||||
properties,
|
||||
});
|
||||
};
|
||||
|
||||
it('should handle basic association fields', () => {
|
||||
const schema = createSchema({
|
||||
profile: {
|
||||
'x-component': 'Input',
|
||||
'x-collection-field': 'users.profile',
|
||||
name: 'profile',
|
||||
},
|
||||
});
|
||||
|
||||
const updateAssociationValues = new Set<string>();
|
||||
const appends = new Set<string>();
|
||||
|
||||
getAppends({
|
||||
schema,
|
||||
prefix: '',
|
||||
updateAssociationValues,
|
||||
appends,
|
||||
getCollectionJoinField: mockGetCollectionJoinField,
|
||||
getCollection: mockGetCollection,
|
||||
dataSource: 'main',
|
||||
});
|
||||
|
||||
expect(Array.from(appends)).toEqual(['profile']);
|
||||
expect(Array.from(updateAssociationValues)).toEqual([]);
|
||||
});
|
||||
|
||||
it('should handle tree collection fields', () => {
|
||||
const schema = createSchema({
|
||||
categories: {
|
||||
'x-component': 'Input',
|
||||
'x-collection-field': 'users.categories',
|
||||
name: 'categories',
|
||||
},
|
||||
});
|
||||
|
||||
const updateAssociationValues = new Set<string>();
|
||||
const appends = new Set<string>();
|
||||
|
||||
getAppends({
|
||||
schema,
|
||||
prefix: '',
|
||||
updateAssociationValues,
|
||||
appends,
|
||||
getCollectionJoinField: mockGetCollectionJoinField,
|
||||
getCollection: mockGetCollection,
|
||||
dataSource: 'main',
|
||||
});
|
||||
|
||||
expect(Array.from(appends)).toEqual(['categories', 'categories.parent(recursively=true)']);
|
||||
});
|
||||
|
||||
it('should handle nested fields with sorting', () => {
|
||||
const schema = createSchema({
|
||||
posts: {
|
||||
'x-component': 'Input',
|
||||
'x-collection-field': 'users.posts',
|
||||
'x-component-props': {
|
||||
sortArr: 'createdAt',
|
||||
},
|
||||
name: 'posts',
|
||||
},
|
||||
});
|
||||
|
||||
const updateAssociationValues = new Set<string>();
|
||||
const appends = new Set<string>();
|
||||
|
||||
getAppends({
|
||||
schema,
|
||||
prefix: '',
|
||||
updateAssociationValues,
|
||||
appends,
|
||||
getCollectionJoinField: mockGetCollectionJoinField,
|
||||
getCollection: mockGetCollection,
|
||||
dataSource: 'main',
|
||||
});
|
||||
|
||||
expect(Array.from(appends)).toEqual(['posts(sort=createdAt)']);
|
||||
});
|
||||
|
||||
it('should handle nested SubTable mode', () => {
|
||||
const schema = createSchema({
|
||||
posts: {
|
||||
'x-component': 'Input',
|
||||
'x-collection-field': 'users.posts',
|
||||
'x-component-props': {
|
||||
mode: 'SubTable',
|
||||
},
|
||||
name: 'posts',
|
||||
properties: {
|
||||
author: {
|
||||
'x-component': 'Input',
|
||||
'x-collection-field': 'posts.author',
|
||||
name: 'author',
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const updateAssociationValues = new Set<string>();
|
||||
const appends = new Set<string>();
|
||||
|
||||
getAppends({
|
||||
schema,
|
||||
prefix: '',
|
||||
updateAssociationValues,
|
||||
appends,
|
||||
getCollectionJoinField: mockGetCollectionJoinField,
|
||||
getCollection: mockGetCollection,
|
||||
dataSource: 'main',
|
||||
});
|
||||
|
||||
expect(Array.from(appends)).toEqual(['posts', 'posts.author']);
|
||||
expect(Array.from(updateAssociationValues)).toEqual(['posts']);
|
||||
});
|
||||
|
||||
it('should ignore TableField components', () => {
|
||||
const schema = createSchema({
|
||||
posts: {
|
||||
'x-component': 'TableField',
|
||||
'x-collection-field': 'users.posts',
|
||||
name: 'posts',
|
||||
},
|
||||
});
|
||||
|
||||
const updateAssociationValues = new Set<string>();
|
||||
const appends = new Set<string>();
|
||||
|
||||
getAppends({
|
||||
schema,
|
||||
prefix: '',
|
||||
updateAssociationValues,
|
||||
appends,
|
||||
getCollectionJoinField: mockGetCollectionJoinField,
|
||||
getCollection: mockGetCollection,
|
||||
dataSource: 'main',
|
||||
});
|
||||
|
||||
expect(Array.from(appends)).toEqual([]);
|
||||
expect(Array.from(updateAssociationValues)).toEqual([]);
|
||||
});
|
||||
|
||||
it('should ignore Kanban.CardViewer components', () => {
|
||||
const schema = createSchema({
|
||||
cardViewer: {
|
||||
'x-component': 'Kanban.CardViewer',
|
||||
name: 'cardViewer',
|
||||
properties: {
|
||||
drawer: {
|
||||
name: 'drawer',
|
||||
type: 'void',
|
||||
properties: {
|
||||
grid: {
|
||||
name: 'grid',
|
||||
type: 'void',
|
||||
properties: {
|
||||
field1: {
|
||||
'x-component': 'Input',
|
||||
'x-collection-field': 'users.posts',
|
||||
name: 'field1',
|
||||
},
|
||||
field2: {
|
||||
'x-component': 'Input',
|
||||
'x-collection-field': 'posts.author',
|
||||
name: 'field2',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const updateAssociationValues = new Set<string>();
|
||||
const appends = new Set<string>();
|
||||
|
||||
getAppends({
|
||||
schema,
|
||||
prefix: '',
|
||||
updateAssociationValues,
|
||||
appends,
|
||||
getCollectionJoinField: mockGetCollectionJoinField,
|
||||
getCollection: mockGetCollection,
|
||||
dataSource: 'main',
|
||||
});
|
||||
|
||||
expect(Array.from(appends)).toEqual([]);
|
||||
expect(Array.from(updateAssociationValues)).toEqual([]);
|
||||
});
|
||||
});
|
@ -35,7 +35,7 @@ import {
|
||||
import { useAPIClient, useRequest } from '../../api-client';
|
||||
import { useNavigateNoUpdate } from '../../application/CustomRouterContextProvider';
|
||||
import { useFormBlockContext } from '../../block-provider/FormBlockProvider';
|
||||
import { useCollectionManager_deprecated, useCollection_deprecated } from '../../collection-manager';
|
||||
import { CollectionOptions, useCollectionManager_deprecated, useCollection_deprecated } from '../../collection-manager';
|
||||
import { DataBlock, useFilterBlock } from '../../filter-provider/FilterProvider';
|
||||
import { mergeFilter, transformToFilter } from '../../filter-provider/utils';
|
||||
import { useTreeParentRecord } from '../../modules/blocks/data-blocks/table/TreeRecordProvider';
|
||||
@ -1494,90 +1494,137 @@ export function getAssociationPath(str) {
|
||||
return str;
|
||||
}
|
||||
|
||||
export const useAssociationNames = (dataSource?: string) => {
|
||||
let updateAssociationValues = new Set([]);
|
||||
let appends = new Set([]);
|
||||
const { getCollectionJoinField, getCollection } = useCollectionManager_deprecated(dataSource);
|
||||
const fieldSchema = useFieldSchema();
|
||||
const _getAssociationAppends = (schema, str) => {
|
||||
schema.reduceProperties((pre, s) => {
|
||||
const prefix = pre || str;
|
||||
const collectionField = s['x-collection-field'] && getCollectionJoinField(s['x-collection-field'], dataSource);
|
||||
const isAssociationSubfield = s.name.includes('.');
|
||||
const isAssociationField =
|
||||
collectionField &&
|
||||
['hasOne', 'hasMany', 'belongsTo', 'belongsToMany', 'belongsToArray'].includes(collectionField.type);
|
||||
export const getAppends = ({
|
||||
schema,
|
||||
prefix: defaultPrefix,
|
||||
updateAssociationValues,
|
||||
appends,
|
||||
getCollectionJoinField,
|
||||
getCollection,
|
||||
dataSource,
|
||||
}: {
|
||||
schema: any;
|
||||
prefix: string;
|
||||
updateAssociationValues: Set<string>;
|
||||
appends: Set<string>;
|
||||
getCollectionJoinField: (name: string, dataSource: string) => any;
|
||||
getCollection: (name: any, customDataSource?: string) => CollectionOptions;
|
||||
dataSource: string;
|
||||
}) => {
|
||||
schema.reduceProperties((pre, s) => {
|
||||
const prefix = pre || defaultPrefix;
|
||||
const collectionField = s['x-collection-field'] && getCollectionJoinField(s['x-collection-field'], dataSource);
|
||||
const isAssociationSubfield = s.name.includes('.');
|
||||
const isAssociationField =
|
||||
collectionField &&
|
||||
['hasOne', 'hasMany', 'belongsTo', 'belongsToMany', 'belongsToArray'].includes(collectionField.type);
|
||||
|
||||
// 根据联动规则中条件的字段获取一些 appends
|
||||
// 需要排除掉子表格和子表单中的联动规则
|
||||
if (s['x-linkage-rules'] && !isSubMode(s)) {
|
||||
const collectAppends = (obj) => {
|
||||
const type = Object.keys(obj)[0] || '$and';
|
||||
const list = obj[type];
|
||||
// 根据联动规则中条件的字段获取一些 appends
|
||||
// 需要排除掉子表格和子表单中的联动规则
|
||||
if (s['x-linkage-rules'] && !isSubMode(s)) {
|
||||
const collectAppends = (obj) => {
|
||||
const type = Object.keys(obj)[0] || '$and';
|
||||
const list = obj[type];
|
||||
|
||||
list.forEach((item) => {
|
||||
if ('$and' in item || '$or' in item) {
|
||||
return collectAppends(item);
|
||||
}
|
||||
list.forEach((item) => {
|
||||
if ('$and' in item || '$or' in item) {
|
||||
return collectAppends(item);
|
||||
}
|
||||
|
||||
const fieldNames = getTargetField(item);
|
||||
const fieldNames = getTargetField(item);
|
||||
|
||||
// 只应该收集关系字段,只有大于 1 的时候才是关系字段
|
||||
if (fieldNames.length > 1) {
|
||||
appends.add(fieldNames.join('.'));
|
||||
}
|
||||
});
|
||||
};
|
||||
// 只应该收集关系字段,只有大于 1 的时候才是关系字段
|
||||
if (fieldNames.length > 1) {
|
||||
appends.add(fieldNames.join('.'));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const rules = s['x-linkage-rules'];
|
||||
rules.forEach(({ condition }) => {
|
||||
collectAppends(condition);
|
||||
const rules = s['x-linkage-rules'];
|
||||
rules.forEach(({ condition }) => {
|
||||
collectAppends(condition);
|
||||
});
|
||||
}
|
||||
|
||||
const isTreeCollection =
|
||||
isAssociationField && getCollection(collectionField.target, dataSource)?.template === 'tree';
|
||||
|
||||
if (collectionField && (isAssociationField || isAssociationSubfield) && s['x-component'] !== 'TableField') {
|
||||
const fieldPath = !isAssociationField && isAssociationSubfield ? getAssociationPath(s.name) : s.name;
|
||||
const path = prefix === '' || !prefix ? fieldPath : prefix + '.' + fieldPath;
|
||||
if (isTreeCollection) {
|
||||
appends.add(path);
|
||||
appends.add(`${path}.parent` + '(recursively=true)');
|
||||
} else {
|
||||
if (s['x-component-props']?.sortArr) {
|
||||
const sort = s['x-component-props']?.sortArr;
|
||||
appends.add(`${path}(sort=${sort})`);
|
||||
} else {
|
||||
appends.add(path);
|
||||
}
|
||||
}
|
||||
if (isSubMode(s)) {
|
||||
updateAssociationValues.add(path);
|
||||
const bufPrefix = prefix && prefix !== '' ? prefix + '.' + s.name : s.name;
|
||||
getAppends({
|
||||
schema: s,
|
||||
prefix: bufPrefix,
|
||||
updateAssociationValues,
|
||||
appends,
|
||||
getCollectionJoinField,
|
||||
getCollection,
|
||||
dataSource,
|
||||
});
|
||||
}
|
||||
const isTreeCollection =
|
||||
isAssociationField && getCollection(collectionField.target, dataSource)?.template === 'tree';
|
||||
if (collectionField && (isAssociationField || isAssociationSubfield) && s['x-component'] !== 'TableField') {
|
||||
const fieldPath = !isAssociationField && isAssociationSubfield ? getAssociationPath(s.name) : s.name;
|
||||
const path = prefix === '' || !prefix ? fieldPath : prefix + '.' + fieldPath;
|
||||
if (isTreeCollection) {
|
||||
appends.add(path);
|
||||
appends.add(`${path}.parent` + '(recursively=true)');
|
||||
} else {
|
||||
if (s['x-component-props']?.sortArr) {
|
||||
const sort = s['x-component-props']?.sortArr;
|
||||
appends.add(`${path}(sort=${sort})`);
|
||||
} else {
|
||||
appends.add(path);
|
||||
}
|
||||
}
|
||||
if (['Nester', 'SubTable', 'PopoverNester'].includes(s['x-component-props']?.mode)) {
|
||||
updateAssociationValues.add(path);
|
||||
const bufPrefix = prefix && prefix !== '' ? prefix + '.' + s.name : s.name;
|
||||
_getAssociationAppends(s, bufPrefix);
|
||||
}
|
||||
} else if (
|
||||
![
|
||||
'ActionBar',
|
||||
'Action',
|
||||
'Action.Link',
|
||||
'Action.Modal',
|
||||
'Selector',
|
||||
'Viewer',
|
||||
'AddNewer',
|
||||
'AssociationField.Selector',
|
||||
'AssociationField.AddNewer',
|
||||
'TableField',
|
||||
].includes(s['x-component'])
|
||||
) {
|
||||
_getAssociationAppends(s, str);
|
||||
}
|
||||
}, str);
|
||||
};
|
||||
} else if (
|
||||
![
|
||||
'ActionBar',
|
||||
'Action',
|
||||
'Action.Link',
|
||||
'Action.Modal',
|
||||
'Selector',
|
||||
'Viewer',
|
||||
'AddNewer',
|
||||
'AssociationField.Selector',
|
||||
'AssociationField.AddNewer',
|
||||
'TableField',
|
||||
'Kanban.CardViewer',
|
||||
].includes(s['x-component'])
|
||||
) {
|
||||
getAppends({
|
||||
schema: s,
|
||||
prefix: defaultPrefix,
|
||||
updateAssociationValues,
|
||||
appends,
|
||||
getCollectionJoinField,
|
||||
getCollection,
|
||||
dataSource,
|
||||
});
|
||||
}
|
||||
}, defaultPrefix);
|
||||
};
|
||||
|
||||
export const useAssociationNames = (dataSource?: string) => {
|
||||
const { getCollectionJoinField, getCollection } = useCollectionManager_deprecated(dataSource);
|
||||
const fieldSchema = useFieldSchema();
|
||||
|
||||
const getAssociationAppends = () => {
|
||||
updateAssociationValues = new Set([]);
|
||||
appends = new Set([]);
|
||||
_getAssociationAppends(fieldSchema, '');
|
||||
const updateAssociationValues = new Set([]);
|
||||
let appends = new Set([]);
|
||||
|
||||
getAppends({
|
||||
schema: fieldSchema,
|
||||
prefix: '',
|
||||
updateAssociationValues,
|
||||
appends,
|
||||
getCollectionJoinField,
|
||||
getCollection,
|
||||
dataSource,
|
||||
});
|
||||
appends = fillParentFields(appends);
|
||||
|
||||
console.log('appends', appends);
|
||||
|
||||
return { appends: [...appends], updateAssociationValues: [...updateAssociationValues] };
|
||||
};
|
||||
|
||||
|
@ -10,17 +10,17 @@
|
||||
import { css } from '@emotion/css';
|
||||
import { FormLayout } from '@formily/antd-v5';
|
||||
import { createForm } from '@formily/core';
|
||||
import { observer, RecursionField, useFieldSchema } from '@formily/react';
|
||||
import { RecursionField, useFieldSchema } from '@formily/react';
|
||||
import {
|
||||
DndContext,
|
||||
FormProvider,
|
||||
getCardItemSchema,
|
||||
PopupContextProvider,
|
||||
useCollection,
|
||||
useCollectionRecordData,
|
||||
usePopupSettings,
|
||||
usePopupUtils,
|
||||
VariablePopupRecordProvider,
|
||||
getCardItemSchema,
|
||||
} from '@nocobase/client';
|
||||
import { Schema } from '@nocobase/utils';
|
||||
import { Card } from 'antd';
|
||||
@ -68,98 +68,95 @@ const cardCss = css`
|
||||
const MemorizedRecursionField = React.memo(RecursionField);
|
||||
MemorizedRecursionField.displayName = 'MemorizedRecursionField';
|
||||
|
||||
export const KanbanCard: any = observer(
|
||||
() => {
|
||||
const collection = useCollection();
|
||||
const { setDisableCardDrag } = useContext(KanbanCardContext) || {};
|
||||
const fieldSchema = useFieldSchema();
|
||||
const { openPopup, getPopupSchemaFromSchema } = usePopupUtils();
|
||||
const recordData = useCollectionRecordData();
|
||||
const popupSchema = getPopupSchemaFromSchema(fieldSchema) || getPopupSchemaFromParent(fieldSchema);
|
||||
const [visible, setVisible] = useState(false);
|
||||
const { isPopupVisibleControlledByURL } = usePopupSettings();
|
||||
const handleCardClick = useCallback(
|
||||
(e: React.MouseEvent) => {
|
||||
const targetElement = e.target as Element; // 将事件目标转换为Element类型
|
||||
const currentTargetElement = e.currentTarget as Element;
|
||||
if (currentTargetElement.contains(targetElement)) {
|
||||
if (!isPopupVisibleControlledByURL()) {
|
||||
setVisible(true);
|
||||
} else {
|
||||
openPopup({
|
||||
popupUidUsedInURL: popupSchema?.['x-uid'],
|
||||
});
|
||||
}
|
||||
e.stopPropagation();
|
||||
export const KanbanCard: any = () => {
|
||||
const collection = useCollection();
|
||||
const { setDisableCardDrag } = useContext(KanbanCardContext) || {};
|
||||
const fieldSchema = useFieldSchema();
|
||||
const { openPopup, getPopupSchemaFromSchema } = usePopupUtils();
|
||||
const recordData = useCollectionRecordData();
|
||||
const popupSchema = getPopupSchemaFromSchema(fieldSchema) || getPopupSchemaFromParent(fieldSchema);
|
||||
const [visible, setVisible] = useState(false);
|
||||
const { isPopupVisibleControlledByURL } = usePopupSettings();
|
||||
const handleCardClick = useCallback(
|
||||
(e: React.MouseEvent) => {
|
||||
const targetElement = e.target as Element; // 将事件目标转换为Element类型
|
||||
const currentTargetElement = e.currentTarget as Element;
|
||||
if (currentTargetElement.contains(targetElement)) {
|
||||
if (!isPopupVisibleControlledByURL()) {
|
||||
setVisible(true);
|
||||
} else {
|
||||
e.stopPropagation();
|
||||
openPopup({
|
||||
popupUidUsedInURL: popupSchema?.['x-uid'],
|
||||
});
|
||||
}
|
||||
e.stopPropagation();
|
||||
} else {
|
||||
e.stopPropagation();
|
||||
}
|
||||
},
|
||||
[openPopup, popupSchema],
|
||||
);
|
||||
const cardStyle = useMemo(() => {
|
||||
return {
|
||||
cursor: 'pointer',
|
||||
overflow: 'hidden',
|
||||
};
|
||||
}, []);
|
||||
|
||||
const form = useMemo(() => {
|
||||
return createForm({
|
||||
values: recordData,
|
||||
});
|
||||
}, [recordData]);
|
||||
|
||||
const onDragStart = useCallback(() => {
|
||||
setDisableCardDrag?.(true);
|
||||
}, [setDisableCardDrag]);
|
||||
const onDragEnd = useCallback(() => {
|
||||
setDisableCardDrag?.(false);
|
||||
}, [setDisableCardDrag]);
|
||||
|
||||
// if not wrapped, only Tab component's content will be rendered, Drawer component's content will not be rendered
|
||||
const wrappedPopupSchema = useMemo(() => {
|
||||
return {
|
||||
type: 'void',
|
||||
properties: {
|
||||
drawer: popupSchema,
|
||||
},
|
||||
[openPopup, popupSchema],
|
||||
);
|
||||
const cardStyle = useMemo(() => {
|
||||
return {
|
||||
cursor: 'pointer',
|
||||
overflow: 'hidden',
|
||||
};
|
||||
}, []);
|
||||
};
|
||||
}, [popupSchema]);
|
||||
const cardItemSchema = getCardItemSchema?.(fieldSchema);
|
||||
const {
|
||||
layout = 'vertical',
|
||||
labelAlign = 'left',
|
||||
labelWidth = 120,
|
||||
labelWrap = true,
|
||||
} = cardItemSchema?.['x-component-props'] || {};
|
||||
|
||||
const form = useMemo(() => {
|
||||
return createForm({
|
||||
values: recordData,
|
||||
});
|
||||
}, [recordData]);
|
||||
|
||||
const onDragStart = useCallback(() => {
|
||||
setDisableCardDrag?.(true);
|
||||
}, [setDisableCardDrag]);
|
||||
const onDragEnd = useCallback(() => {
|
||||
setDisableCardDrag?.(false);
|
||||
}, [setDisableCardDrag]);
|
||||
|
||||
// if not wrapped, only Tab component's content will be rendered, Drawer component's content will not be rendered
|
||||
const wrappedPopupSchema = useMemo(() => {
|
||||
return {
|
||||
type: 'void',
|
||||
properties: {
|
||||
drawer: popupSchema,
|
||||
},
|
||||
};
|
||||
}, [popupSchema]);
|
||||
const cardItemSchema = getCardItemSchema?.(fieldSchema);
|
||||
const {
|
||||
layout = 'vertical',
|
||||
labelAlign = 'left',
|
||||
labelWidth = 120,
|
||||
labelWrap = true,
|
||||
} = cardItemSchema?.['x-component-props'] || {};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Card onClick={handleCardClick} bordered={false} hoverable style={cardStyle} className={cardCss}>
|
||||
<DndContext onDragStart={onDragStart} onDragEnd={onDragEnd}>
|
||||
<FormLayout
|
||||
layout={layout}
|
||||
labelAlign={labelAlign}
|
||||
labelWidth={layout === 'horizontal' ? labelWidth : null}
|
||||
labelWrap={labelWrap}
|
||||
>
|
||||
<FormProvider form={form}>
|
||||
<MemorizedRecursionField schema={fieldSchema} onlyRenderProperties />
|
||||
</FormProvider>
|
||||
</FormLayout>
|
||||
</DndContext>
|
||||
</Card>
|
||||
<PopupContextProvider visible={visible} setVisible={setVisible}>
|
||||
<VariablePopupRecordProvider recordData={recordData} collection={collection}>
|
||||
<MemorizedRecursionField schema={wrappedPopupSchema} />
|
||||
</VariablePopupRecordProvider>
|
||||
</PopupContextProvider>
|
||||
</>
|
||||
);
|
||||
},
|
||||
{ displayName: 'KanbanCard' },
|
||||
);
|
||||
return (
|
||||
<>
|
||||
<Card onClick={handleCardClick} bordered={false} hoverable style={cardStyle} className={cardCss}>
|
||||
<DndContext onDragStart={onDragStart} onDragEnd={onDragEnd}>
|
||||
<FormLayout
|
||||
layout={layout}
|
||||
labelAlign={labelAlign}
|
||||
labelWidth={layout === 'horizontal' ? labelWidth : null}
|
||||
labelWrap={labelWrap}
|
||||
>
|
||||
<FormProvider form={form}>
|
||||
<MemorizedRecursionField schema={fieldSchema} onlyRenderProperties />
|
||||
</FormProvider>
|
||||
</FormLayout>
|
||||
</DndContext>
|
||||
</Card>
|
||||
<PopupContextProvider visible={visible} setVisible={setVisible}>
|
||||
<VariablePopupRecordProvider recordData={recordData} collection={collection}>
|
||||
<MemorizedRecursionField schema={wrappedPopupSchema} />
|
||||
</VariablePopupRecordProvider>
|
||||
</PopupContextProvider>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
function getPopupSchemaFromParent(fieldSchema: Schema) {
|
||||
if (fieldSchema.parent?.properties?.cardViewer?.properties?.drawer) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user