mirror of
https://gitee.com/nocobase/nocobase.git
synced 2025-05-05 21:49:25 +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 { useAPIClient, useRequest } from '../../api-client';
|
||||||
import { useNavigateNoUpdate } from '../../application/CustomRouterContextProvider';
|
import { useNavigateNoUpdate } from '../../application/CustomRouterContextProvider';
|
||||||
import { useFormBlockContext } from '../../block-provider/FormBlockProvider';
|
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 { DataBlock, useFilterBlock } from '../../filter-provider/FilterProvider';
|
||||||
import { mergeFilter, transformToFilter } from '../../filter-provider/utils';
|
import { mergeFilter, transformToFilter } from '../../filter-provider/utils';
|
||||||
import { useTreeParentRecord } from '../../modules/blocks/data-blocks/table/TreeRecordProvider';
|
import { useTreeParentRecord } from '../../modules/blocks/data-blocks/table/TreeRecordProvider';
|
||||||
@ -1494,90 +1494,137 @@ export function getAssociationPath(str) {
|
|||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useAssociationNames = (dataSource?: string) => {
|
export const getAppends = ({
|
||||||
let updateAssociationValues = new Set([]);
|
schema,
|
||||||
let appends = new Set([]);
|
prefix: defaultPrefix,
|
||||||
const { getCollectionJoinField, getCollection } = useCollectionManager_deprecated(dataSource);
|
updateAssociationValues,
|
||||||
const fieldSchema = useFieldSchema();
|
appends,
|
||||||
const _getAssociationAppends = (schema, str) => {
|
getCollectionJoinField,
|
||||||
schema.reduceProperties((pre, s) => {
|
getCollection,
|
||||||
const prefix = pre || str;
|
dataSource,
|
||||||
const collectionField = s['x-collection-field'] && getCollectionJoinField(s['x-collection-field'], dataSource);
|
}: {
|
||||||
const isAssociationSubfield = s.name.includes('.');
|
schema: any;
|
||||||
const isAssociationField =
|
prefix: string;
|
||||||
collectionField &&
|
updateAssociationValues: Set<string>;
|
||||||
['hasOne', 'hasMany', 'belongsTo', 'belongsToMany', 'belongsToArray'].includes(collectionField.type);
|
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
|
// 根据联动规则中条件的字段获取一些 appends
|
||||||
// 需要排除掉子表格和子表单中的联动规则
|
// 需要排除掉子表格和子表单中的联动规则
|
||||||
if (s['x-linkage-rules'] && !isSubMode(s)) {
|
if (s['x-linkage-rules'] && !isSubMode(s)) {
|
||||||
const collectAppends = (obj) => {
|
const collectAppends = (obj) => {
|
||||||
const type = Object.keys(obj)[0] || '$and';
|
const type = Object.keys(obj)[0] || '$and';
|
||||||
const list = obj[type];
|
const list = obj[type];
|
||||||
|
|
||||||
list.forEach((item) => {
|
list.forEach((item) => {
|
||||||
if ('$and' in item || '$or' in item) {
|
if ('$and' in item || '$or' in item) {
|
||||||
return collectAppends(item);
|
return collectAppends(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
const fieldNames = getTargetField(item);
|
const fieldNames = getTargetField(item);
|
||||||
|
|
||||||
// 只应该收集关系字段,只有大于 1 的时候才是关系字段
|
// 只应该收集关系字段,只有大于 1 的时候才是关系字段
|
||||||
if (fieldNames.length > 1) {
|
if (fieldNames.length > 1) {
|
||||||
appends.add(fieldNames.join('.'));
|
appends.add(fieldNames.join('.'));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const rules = s['x-linkage-rules'];
|
const rules = s['x-linkage-rules'];
|
||||||
rules.forEach(({ condition }) => {
|
rules.forEach(({ condition }) => {
|
||||||
collectAppends(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 =
|
} else if (
|
||||||
isAssociationField && getCollection(collectionField.target, dataSource)?.template === 'tree';
|
![
|
||||||
if (collectionField && (isAssociationField || isAssociationSubfield) && s['x-component'] !== 'TableField') {
|
'ActionBar',
|
||||||
const fieldPath = !isAssociationField && isAssociationSubfield ? getAssociationPath(s.name) : s.name;
|
'Action',
|
||||||
const path = prefix === '' || !prefix ? fieldPath : prefix + '.' + fieldPath;
|
'Action.Link',
|
||||||
if (isTreeCollection) {
|
'Action.Modal',
|
||||||
appends.add(path);
|
'Selector',
|
||||||
appends.add(`${path}.parent` + '(recursively=true)');
|
'Viewer',
|
||||||
} else {
|
'AddNewer',
|
||||||
if (s['x-component-props']?.sortArr) {
|
'AssociationField.Selector',
|
||||||
const sort = s['x-component-props']?.sortArr;
|
'AssociationField.AddNewer',
|
||||||
appends.add(`${path}(sort=${sort})`);
|
'TableField',
|
||||||
} else {
|
'Kanban.CardViewer',
|
||||||
appends.add(path);
|
].includes(s['x-component'])
|
||||||
}
|
) {
|
||||||
}
|
getAppends({
|
||||||
if (['Nester', 'SubTable', 'PopoverNester'].includes(s['x-component-props']?.mode)) {
|
schema: s,
|
||||||
updateAssociationValues.add(path);
|
prefix: defaultPrefix,
|
||||||
const bufPrefix = prefix && prefix !== '' ? prefix + '.' + s.name : s.name;
|
updateAssociationValues,
|
||||||
_getAssociationAppends(s, bufPrefix);
|
appends,
|
||||||
}
|
getCollectionJoinField,
|
||||||
} else if (
|
getCollection,
|
||||||
![
|
dataSource,
|
||||||
'ActionBar',
|
});
|
||||||
'Action',
|
}
|
||||||
'Action.Link',
|
}, defaultPrefix);
|
||||||
'Action.Modal',
|
};
|
||||||
'Selector',
|
|
||||||
'Viewer',
|
export const useAssociationNames = (dataSource?: string) => {
|
||||||
'AddNewer',
|
const { getCollectionJoinField, getCollection } = useCollectionManager_deprecated(dataSource);
|
||||||
'AssociationField.Selector',
|
const fieldSchema = useFieldSchema();
|
||||||
'AssociationField.AddNewer',
|
|
||||||
'TableField',
|
|
||||||
].includes(s['x-component'])
|
|
||||||
) {
|
|
||||||
_getAssociationAppends(s, str);
|
|
||||||
}
|
|
||||||
}, str);
|
|
||||||
};
|
|
||||||
const getAssociationAppends = () => {
|
const getAssociationAppends = () => {
|
||||||
updateAssociationValues = new Set([]);
|
const updateAssociationValues = new Set([]);
|
||||||
appends = new Set([]);
|
let appends = new Set([]);
|
||||||
_getAssociationAppends(fieldSchema, '');
|
|
||||||
|
getAppends({
|
||||||
|
schema: fieldSchema,
|
||||||
|
prefix: '',
|
||||||
|
updateAssociationValues,
|
||||||
|
appends,
|
||||||
|
getCollectionJoinField,
|
||||||
|
getCollection,
|
||||||
|
dataSource,
|
||||||
|
});
|
||||||
appends = fillParentFields(appends);
|
appends = fillParentFields(appends);
|
||||||
|
|
||||||
|
console.log('appends', appends);
|
||||||
|
|
||||||
return { appends: [...appends], updateAssociationValues: [...updateAssociationValues] };
|
return { appends: [...appends], updateAssociationValues: [...updateAssociationValues] };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -10,17 +10,17 @@
|
|||||||
import { css } from '@emotion/css';
|
import { css } from '@emotion/css';
|
||||||
import { FormLayout } from '@formily/antd-v5';
|
import { FormLayout } from '@formily/antd-v5';
|
||||||
import { createForm } from '@formily/core';
|
import { createForm } from '@formily/core';
|
||||||
import { observer, RecursionField, useFieldSchema } from '@formily/react';
|
import { RecursionField, useFieldSchema } from '@formily/react';
|
||||||
import {
|
import {
|
||||||
DndContext,
|
DndContext,
|
||||||
FormProvider,
|
FormProvider,
|
||||||
|
getCardItemSchema,
|
||||||
PopupContextProvider,
|
PopupContextProvider,
|
||||||
useCollection,
|
useCollection,
|
||||||
useCollectionRecordData,
|
useCollectionRecordData,
|
||||||
usePopupSettings,
|
usePopupSettings,
|
||||||
usePopupUtils,
|
usePopupUtils,
|
||||||
VariablePopupRecordProvider,
|
VariablePopupRecordProvider,
|
||||||
getCardItemSchema,
|
|
||||||
} from '@nocobase/client';
|
} from '@nocobase/client';
|
||||||
import { Schema } from '@nocobase/utils';
|
import { Schema } from '@nocobase/utils';
|
||||||
import { Card } from 'antd';
|
import { Card } from 'antd';
|
||||||
@ -68,98 +68,95 @@ const cardCss = css`
|
|||||||
const MemorizedRecursionField = React.memo(RecursionField);
|
const MemorizedRecursionField = React.memo(RecursionField);
|
||||||
MemorizedRecursionField.displayName = 'MemorizedRecursionField';
|
MemorizedRecursionField.displayName = 'MemorizedRecursionField';
|
||||||
|
|
||||||
export const KanbanCard: any = observer(
|
export const KanbanCard: any = () => {
|
||||||
() => {
|
const collection = useCollection();
|
||||||
const collection = useCollection();
|
const { setDisableCardDrag } = useContext(KanbanCardContext) || {};
|
||||||
const { setDisableCardDrag } = useContext(KanbanCardContext) || {};
|
const fieldSchema = useFieldSchema();
|
||||||
const fieldSchema = useFieldSchema();
|
const { openPopup, getPopupSchemaFromSchema } = usePopupUtils();
|
||||||
const { openPopup, getPopupSchemaFromSchema } = usePopupUtils();
|
const recordData = useCollectionRecordData();
|
||||||
const recordData = useCollectionRecordData();
|
const popupSchema = getPopupSchemaFromSchema(fieldSchema) || getPopupSchemaFromParent(fieldSchema);
|
||||||
const popupSchema = getPopupSchemaFromSchema(fieldSchema) || getPopupSchemaFromParent(fieldSchema);
|
const [visible, setVisible] = useState(false);
|
||||||
const [visible, setVisible] = useState(false);
|
const { isPopupVisibleControlledByURL } = usePopupSettings();
|
||||||
const { isPopupVisibleControlledByURL } = usePopupSettings();
|
const handleCardClick = useCallback(
|
||||||
const handleCardClick = useCallback(
|
(e: React.MouseEvent) => {
|
||||||
(e: React.MouseEvent) => {
|
const targetElement = e.target as Element; // 将事件目标转换为Element类型
|
||||||
const targetElement = e.target as Element; // 将事件目标转换为Element类型
|
const currentTargetElement = e.currentTarget as Element;
|
||||||
const currentTargetElement = e.currentTarget as Element;
|
if (currentTargetElement.contains(targetElement)) {
|
||||||
if (currentTargetElement.contains(targetElement)) {
|
if (!isPopupVisibleControlledByURL()) {
|
||||||
if (!isPopupVisibleControlledByURL()) {
|
setVisible(true);
|
||||||
setVisible(true);
|
|
||||||
} else {
|
|
||||||
openPopup({
|
|
||||||
popupUidUsedInURL: popupSchema?.['x-uid'],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
e.stopPropagation();
|
|
||||||
} else {
|
} 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],
|
};
|
||||||
);
|
}, [popupSchema]);
|
||||||
const cardStyle = useMemo(() => {
|
const cardItemSchema = getCardItemSchema?.(fieldSchema);
|
||||||
return {
|
const {
|
||||||
cursor: 'pointer',
|
layout = 'vertical',
|
||||||
overflow: 'hidden',
|
labelAlign = 'left',
|
||||||
};
|
labelWidth = 120,
|
||||||
}, []);
|
labelWrap = true,
|
||||||
|
} = cardItemSchema?.['x-component-props'] || {};
|
||||||
|
|
||||||
const form = useMemo(() => {
|
return (
|
||||||
return createForm({
|
<>
|
||||||
values: recordData,
|
<Card onClick={handleCardClick} bordered={false} hoverable style={cardStyle} className={cardCss}>
|
||||||
});
|
<DndContext onDragStart={onDragStart} onDragEnd={onDragEnd}>
|
||||||
}, [recordData]);
|
<FormLayout
|
||||||
|
layout={layout}
|
||||||
const onDragStart = useCallback(() => {
|
labelAlign={labelAlign}
|
||||||
setDisableCardDrag?.(true);
|
labelWidth={layout === 'horizontal' ? labelWidth : null}
|
||||||
}, [setDisableCardDrag]);
|
labelWrap={labelWrap}
|
||||||
const onDragEnd = useCallback(() => {
|
>
|
||||||
setDisableCardDrag?.(false);
|
<FormProvider form={form}>
|
||||||
}, [setDisableCardDrag]);
|
<MemorizedRecursionField schema={fieldSchema} onlyRenderProperties />
|
||||||
|
</FormProvider>
|
||||||
// if not wrapped, only Tab component's content will be rendered, Drawer component's content will not be rendered
|
</FormLayout>
|
||||||
const wrappedPopupSchema = useMemo(() => {
|
</DndContext>
|
||||||
return {
|
</Card>
|
||||||
type: 'void',
|
<PopupContextProvider visible={visible} setVisible={setVisible}>
|
||||||
properties: {
|
<VariablePopupRecordProvider recordData={recordData} collection={collection}>
|
||||||
drawer: popupSchema,
|
<MemorizedRecursionField schema={wrappedPopupSchema} />
|
||||||
},
|
</VariablePopupRecordProvider>
|
||||||
};
|
</PopupContextProvider>
|
||||||
}, [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' },
|
|
||||||
);
|
|
||||||
|
|
||||||
function getPopupSchemaFromParent(fieldSchema: Schema) {
|
function getPopupSchemaFromParent(fieldSchema: Schema) {
|
||||||
if (fieldSchema.parent?.properties?.cardViewer?.properties?.drawer) {
|
if (fieldSchema.parent?.properties?.cardViewer?.properties?.drawer) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user