mirror of
https://gitee.com/nocobase/nocobase.git
synced 2025-07-02 03:02:19 +08:00
Merge branch 'next' into develop
This commit is contained in:
commit
3c82ca5bf4
2
.github/dependabot.yml
vendored
2
.github/dependabot.yml
vendored
@ -4,7 +4,7 @@ updates:
|
|||||||
directory: "/" # 包管理器文件在仓库的位置,"/"代表仓库的根目录
|
directory: "/" # 包管理器文件在仓库的位置,"/"代表仓库的根目录
|
||||||
schedule:
|
schedule:
|
||||||
interval: "weekly" # Dependabot检查更新的频率,可以是"daily", "weekly", 或者 "monthly"
|
interval: "weekly" # Dependabot检查更新的频率,可以是"daily", "weekly", 或者 "monthly"
|
||||||
open-pull-requests-limit: 1 # Dependabot同时打开的pull request的最大数量
|
open-pull-requests-limit: 3 # Dependabot同时打开的pull request的最大数量
|
||||||
ignore:
|
ignore:
|
||||||
- dependency-name: "axios"
|
- dependency-name: "axios"
|
||||||
- dependency-name: "dotenv"
|
- dependency-name: "dotenv"
|
||||||
|
8
packages/core/build/package.json
Executable file → Normal file
8
packages/core/build/package.json
Executable file → Normal file
@ -9,9 +9,9 @@
|
|||||||
},
|
},
|
||||||
"typings": "./index.d.ts",
|
"typings": "./index.d.ts",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/core": "7.22.10",
|
"@babel/core": "7.25.2",
|
||||||
"@babel/plugin-transform-modules-amd": "7.22.5",
|
"@babel/plugin-transform-modules-amd": "7.24.7",
|
||||||
"@babel/preset-env": "7.22.10",
|
"@babel/preset-env": "7.25.3",
|
||||||
"@hapi/topo": "^6.0.0",
|
"@hapi/topo": "^6.0.0",
|
||||||
"@lerna/project": "4.0.0",
|
"@lerna/project": "4.0.0",
|
||||||
"@types/gulp": "^4.0.13",
|
"@types/gulp": "^4.0.13",
|
||||||
@ -25,7 +25,7 @@
|
|||||||
"gulp": "4.0.2",
|
"gulp": "4.0.2",
|
||||||
"gulp-typescript": "6.0.0-alpha.1",
|
"gulp-typescript": "6.0.0-alpha.1",
|
||||||
"tar": "^6.2.0",
|
"tar": "^6.2.0",
|
||||||
"tsup": "7.2.0",
|
"tsup": "8.2.4",
|
||||||
"typescript": "5.1.3",
|
"typescript": "5.1.3",
|
||||||
"update-notifier": "3.0.0",
|
"update-notifier": "3.0.0",
|
||||||
"vite-plugin-css-injected-by-js": "^3.2.1",
|
"vite-plugin-css-injected-by-js": "^3.2.1",
|
||||||
|
@ -297,4 +297,12 @@ export class Collection {
|
|||||||
isTitleField(field: CollectionFieldOptions) {
|
isTitleField(field: CollectionFieldOptions) {
|
||||||
return this.app.dataSourceManager.collectionFieldInterfaceManager.getFieldInterface(field.interface)?.titleUsable;
|
return this.app.dataSourceManager.collectionFieldInterfaceManager.getFieldInterface(field.interface)?.titleUsable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* is inherited from other collections
|
||||||
|
* @returns boolean
|
||||||
|
*/
|
||||||
|
isInherited() {
|
||||||
|
return this.inherits.length > 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,47 @@
|
|||||||
|
/**
|
||||||
|
* 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 { expect, test } from '@nocobase/test/e2e';
|
||||||
|
import { T5084 } from './templates';
|
||||||
|
|
||||||
|
test.describe('Add new: inherit', () => {
|
||||||
|
test('creating block by child collection should work correctly', async ({ page, mockPage }) => {
|
||||||
|
await mockPage(T5084).goto();
|
||||||
|
|
||||||
|
// 1. click the "Add new" button, and then create a block, the block's collection should be "parent"
|
||||||
|
await page.getByRole('button', { name: 'plus Add new' }).click();
|
||||||
|
await page.getByLabel('schema-initializer-Grid-popup').hover();
|
||||||
|
await page.getByRole('menuitem', { name: 'form Form right' }).hover();
|
||||||
|
await page.getByRole('menuitem', { name: 'Current collection' }).click();
|
||||||
|
await page.getByLabel('block-item-CardItem-parent-form').hover();
|
||||||
|
await expect(page.getByLabel('block-item-CardItem-parent-form').getByText('parent')).toBeVisible();
|
||||||
|
// close popup
|
||||||
|
await page.getByLabel('drawer-Action.Container-parent-Add record-mask').click();
|
||||||
|
|
||||||
|
// 2. click the "child1" option, and then create a block, the block's collection should be "child1"
|
||||||
|
await page.getByRole('button', { name: 'down' }).hover();
|
||||||
|
await page.getByRole('menuitem', { name: 'child1' }).click();
|
||||||
|
await page.getByLabel('schema-initializer-Grid-popup').hover();
|
||||||
|
await page.getByRole('menuitem', { name: 'form Form right' }).hover();
|
||||||
|
await page.getByRole('menuitem', { name: 'Current collection' }).click();
|
||||||
|
await page.getByLabel('block-item-CardItem-child1-').hover();
|
||||||
|
await expect(page.getByLabel('block-item-CardItem-child1-').getByText('child1')).toBeVisible();
|
||||||
|
// close popup
|
||||||
|
await page.getByLabel('drawer-Action.Container-child1-Add record-mask').click();
|
||||||
|
|
||||||
|
// 3. click the "child2" option, and then create a block, the block's collection should be "child2"
|
||||||
|
await page.getByRole('button', { name: 'down' }).hover();
|
||||||
|
await page.getByRole('menuitem', { name: 'child2' }).click();
|
||||||
|
await page.getByLabel('schema-initializer-Grid-popup').hover();
|
||||||
|
await page.getByRole('menuitem', { name: 'form Form right' }).hover();
|
||||||
|
await page.getByRole('menuitem', { name: 'Current collection' }).click();
|
||||||
|
await page.getByLabel('block-item-CardItem-child2-').hover();
|
||||||
|
await expect(page.getByLabel('block-item-CardItem-child2-').getByText('child2')).toBeVisible();
|
||||||
|
});
|
||||||
|
});
|
@ -0,0 +1,273 @@
|
|||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
export const T5084 = {
|
||||||
|
collections: [
|
||||||
|
{
|
||||||
|
name: 'parent',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'child1',
|
||||||
|
inherits: ['parent'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'child2',
|
||||||
|
inherits: ['parent'],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
pageSchema: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'Page',
|
||||||
|
properties: {
|
||||||
|
'9z728grhuw5': {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'Grid',
|
||||||
|
'x-initializer': 'page:addBlock',
|
||||||
|
properties: {
|
||||||
|
qunhcwzgdrq: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'Grid.Row',
|
||||||
|
'x-app-version': '1.3.0-alpha',
|
||||||
|
properties: {
|
||||||
|
'232zkncxw1p': {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'Grid.Col',
|
||||||
|
'x-app-version': '1.3.0-alpha',
|
||||||
|
properties: {
|
||||||
|
hj5wtj01v9m: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-decorator': 'TableBlockProvider',
|
||||||
|
'x-acl-action': 'parent:list',
|
||||||
|
'x-use-decorator-props': 'useTableBlockDecoratorProps',
|
||||||
|
'x-decorator-props': {
|
||||||
|
collection: 'parent',
|
||||||
|
dataSource: 'main',
|
||||||
|
action: 'list',
|
||||||
|
params: {
|
||||||
|
pageSize: 20,
|
||||||
|
},
|
||||||
|
rowKey: 'id',
|
||||||
|
showIndex: true,
|
||||||
|
dragSort: false,
|
||||||
|
},
|
||||||
|
'x-toolbar': 'BlockSchemaToolbar',
|
||||||
|
'x-settings': 'blockSettings:table',
|
||||||
|
'x-component': 'CardItem',
|
||||||
|
'x-filter-targets': [],
|
||||||
|
'x-app-version': '1.3.0-alpha',
|
||||||
|
properties: {
|
||||||
|
actions: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-initializer': 'table:configureActions',
|
||||||
|
'x-component': 'ActionBar',
|
||||||
|
'x-component-props': {
|
||||||
|
style: {
|
||||||
|
marginBottom: 'var(--nb-spacing)',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-app-version': '1.3.0-alpha',
|
||||||
|
properties: {
|
||||||
|
uqw9g1a6bx2: {
|
||||||
|
'x-uid': 'atwcb9plntt',
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-action': 'create',
|
||||||
|
'x-acl-action': 'create',
|
||||||
|
title: "{{t('Add new')}}",
|
||||||
|
'x-toolbar': 'ActionSchemaToolbar',
|
||||||
|
'x-settings': 'actionSettings:addNew',
|
||||||
|
'x-component': 'Action',
|
||||||
|
'x-decorator': 'ACLActionProvider',
|
||||||
|
'x-component-props': {
|
||||||
|
openMode: 'drawer',
|
||||||
|
type: 'primary',
|
||||||
|
component: 'CreateRecordAction',
|
||||||
|
icon: 'PlusOutlined',
|
||||||
|
},
|
||||||
|
'x-action-context': {
|
||||||
|
dataSource: 'main',
|
||||||
|
collection: 'parent',
|
||||||
|
},
|
||||||
|
'x-align': 'right',
|
||||||
|
'x-acl-action-props': {
|
||||||
|
skipScopeCheck: true,
|
||||||
|
},
|
||||||
|
'x-app-version': '1.3.0-alpha',
|
||||||
|
'x-enable-children': [
|
||||||
|
{
|
||||||
|
collection: 'child1',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
collection: 'child2',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'x-allow-add-to-current': true,
|
||||||
|
properties: {
|
||||||
|
drawer: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
title: '{{ t("Add record") }}',
|
||||||
|
'x-component': 'Action.Container',
|
||||||
|
'x-component-props': {
|
||||||
|
className: 'nb-action-popup',
|
||||||
|
},
|
||||||
|
'x-app-version': '1.3.0-alpha',
|
||||||
|
properties: {
|
||||||
|
tabs: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'Tabs',
|
||||||
|
'x-component-props': {},
|
||||||
|
'x-initializer': 'popup:addTab',
|
||||||
|
'x-initializer-props': {
|
||||||
|
gridInitializer: 'popup:addNew:addBlock',
|
||||||
|
},
|
||||||
|
'x-app-version': '1.3.0-alpha',
|
||||||
|
properties: {
|
||||||
|
tab1: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
title: '{{t("Add new")}}',
|
||||||
|
'x-component': 'Tabs.TabPane',
|
||||||
|
'x-designer': 'Tabs.Designer',
|
||||||
|
'x-component-props': {},
|
||||||
|
'x-app-version': '1.3.0-alpha',
|
||||||
|
properties: {
|
||||||
|
grid: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'Grid',
|
||||||
|
'x-initializer': 'popup:addNew:addBlock',
|
||||||
|
'x-app-version': '1.3.0-alpha',
|
||||||
|
'x-uid': '9b9jmnkn2f5',
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': 'flmsg97ib9h',
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': 'xd5niej584x',
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': 'nlmwpvv9vd3',
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': 'v0oc2ik3mqw',
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 1,
|
||||||
|
},
|
||||||
|
jecm8jee085: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'array',
|
||||||
|
'x-initializer': 'table:configureColumns',
|
||||||
|
'x-component': 'TableV2',
|
||||||
|
'x-use-component-props': 'useTableBlockProps',
|
||||||
|
'x-component-props': {
|
||||||
|
rowKey: 'id',
|
||||||
|
rowSelection: {
|
||||||
|
type: 'checkbox',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-app-version': '1.3.0-alpha',
|
||||||
|
properties: {
|
||||||
|
actions: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
title: '{{ t("Actions") }}',
|
||||||
|
'x-action-column': 'actions',
|
||||||
|
'x-decorator': 'TableV2.Column.ActionBar',
|
||||||
|
'x-component': 'TableV2.Column',
|
||||||
|
'x-toolbar': 'TableColumnSchemaToolbar',
|
||||||
|
'x-initializer': 'table:configureItemActions',
|
||||||
|
'x-settings': 'fieldSettings:TableColumn',
|
||||||
|
'x-toolbar-props': {
|
||||||
|
initializer: 'table:configureItemActions',
|
||||||
|
},
|
||||||
|
'x-app-version': '1.3.0-alpha',
|
||||||
|
properties: {
|
||||||
|
'4f5sce3w9fx': {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-decorator': 'DndContext',
|
||||||
|
'x-component': 'Space',
|
||||||
|
'x-component-props': {
|
||||||
|
split: '|',
|
||||||
|
},
|
||||||
|
'x-app-version': '1.3.0-alpha',
|
||||||
|
'x-uid': 'qtr5an6qbu6',
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': 'r8msyk257y9',
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': 'm2m7kgypy5z',
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 2,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': 'g0mdajxejhl',
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': 'r7uvf8c2gdq',
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': 'fr8e99uwlgl',
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': 'awqpmazhs8a',
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': 'st43un0l7kl',
|
||||||
|
'x-async': true,
|
||||||
|
'x-index': 1,
|
||||||
|
},
|
||||||
|
};
|
@ -20,7 +20,7 @@ export const BlockSchemaToolbar = (props) => {
|
|||||||
const cm = useCollectionManager();
|
const cm = useCollectionManager();
|
||||||
let { name: currentCollectionName, title: currentCollectionTitle } = useCollection() || {};
|
let { name: currentCollectionName, title: currentCollectionTitle } = useCollection() || {};
|
||||||
const template = useSchemaTemplate();
|
const template = useSchemaTemplate();
|
||||||
const { association } = useDataBlockProps() || {};
|
const { association, collection } = useDataBlockProps() || {};
|
||||||
const compile = useCompile();
|
const compile = useCompile();
|
||||||
|
|
||||||
if (association) {
|
if (association) {
|
||||||
@ -31,7 +31,10 @@ export const BlockSchemaToolbar = (props) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const associationField = cm.getCollectionField(association);
|
const associationField = cm.getCollectionField(association);
|
||||||
const associationCollection = cm.getCollection(associationField?.target);
|
// If both the collection and association parameters exist at the same time,
|
||||||
|
// it means that the collection of the current block is a child collection of inheritance,
|
||||||
|
// and the title of the child collection needs to be displayed at this time
|
||||||
|
const associationCollection = cm.getCollection(collection || associationField?.target);
|
||||||
const templateName = ['FormItem', 'ReadPrettyFormItem'].includes(template?.componentName)
|
const templateName = ['FormItem', 'ReadPrettyFormItem'].includes(template?.componentName)
|
||||||
? `${template?.name} ${t('(Fields only)')}`
|
? `${template?.name} ${t('(Fields only)')}`
|
||||||
: template?.name;
|
: template?.name;
|
||||||
|
@ -11,10 +11,10 @@ import { FormOutlined } from '@ant-design/icons';
|
|||||||
import React, { useCallback } from 'react';
|
import React, { useCallback } from 'react';
|
||||||
import { SchemaInitializerItem, useSchemaInitializer, useSchemaInitializerItem } from '../../../../application';
|
import { SchemaInitializerItem, useSchemaInitializer, useSchemaInitializerItem } from '../../../../application';
|
||||||
import { useCollection_deprecated } from '../../../../collection-manager';
|
import { useCollection_deprecated } from '../../../../collection-manager';
|
||||||
|
import { useAssociationName, useCollectionManager } from '../../../../data-source';
|
||||||
import { useRecordCollectionDataSourceItems } from '../../../../schema-initializer/utils';
|
import { useRecordCollectionDataSourceItems } from '../../../../schema-initializer/utils';
|
||||||
import { useSchemaTemplateManager } from '../../../../schema-templates';
|
import { useSchemaTemplateManager } from '../../../../schema-templates';
|
||||||
import { createDetailsUISchema } from './createDetailsUISchema';
|
import { createDetailsUISchema } from './createDetailsUISchema';
|
||||||
import { useAssociationName } from '../../../../data-source';
|
|
||||||
|
|
||||||
export const RecordReadPrettyFormBlockInitializer = () => {
|
export const RecordReadPrettyFormBlockInitializer = () => {
|
||||||
const itemConfig = useSchemaInitializerItem();
|
const itemConfig = useSchemaInitializerItem();
|
||||||
@ -37,21 +37,26 @@ export function useCreateSingleDetailsSchema() {
|
|||||||
const { insert } = useSchemaInitializer();
|
const { insert } = useSchemaInitializer();
|
||||||
const { getTemplateSchemaByMode } = useSchemaTemplateManager();
|
const { getTemplateSchemaByMode } = useSchemaTemplateManager();
|
||||||
const association = useAssociationName();
|
const association = useAssociationName();
|
||||||
|
const cm = useCollectionManager();
|
||||||
|
|
||||||
const templateWrap = useCallback(
|
const templateWrap = useCallback(
|
||||||
(templateSchema, options) => {
|
(templateSchema, options) => {
|
||||||
const { item } = options;
|
const { item } = options;
|
||||||
if (item.template.componentName === 'ReadPrettyFormItem') {
|
if (item.template.componentName === 'ReadPrettyFormItem') {
|
||||||
|
const collectionName = item.collectionName || item.name;
|
||||||
|
const collection = cm.getCollection(collectionName);
|
||||||
const blockSchema = createDetailsUISchema(
|
const blockSchema = createDetailsUISchema(
|
||||||
association
|
association
|
||||||
? {
|
? {
|
||||||
association,
|
association,
|
||||||
|
// see: https://applink.feishu.cn/client/message/link/open?token=AmP9n9dkwcABZrr3nBdAwAI%3D
|
||||||
|
collectionName: collection.isInherited() ? collectionName : undefined,
|
||||||
dataSource: item.dataSource,
|
dataSource: item.dataSource,
|
||||||
templateSchema: templateSchema,
|
templateSchema: templateSchema,
|
||||||
isCurrent: true,
|
isCurrent: true,
|
||||||
}
|
}
|
||||||
: {
|
: {
|
||||||
collectionName: item.collectionName || item.name,
|
collectionName,
|
||||||
dataSource: item.dataSource,
|
dataSource: item.dataSource,
|
||||||
templateSchema: templateSchema,
|
templateSchema: templateSchema,
|
||||||
},
|
},
|
||||||
@ -64,7 +69,7 @@ export function useCreateSingleDetailsSchema() {
|
|||||||
return templateSchema;
|
return templateSchema;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[association],
|
[association, cm],
|
||||||
);
|
);
|
||||||
|
|
||||||
const createSingleDetailsSchema = useCallback(
|
const createSingleDetailsSchema = useCallback(
|
||||||
@ -73,23 +78,27 @@ export function useCreateSingleDetailsSchema() {
|
|||||||
const template = await getTemplateSchemaByMode(item);
|
const template = await getTemplateSchemaByMode(item);
|
||||||
insert(templateWrap(template, { item }));
|
insert(templateWrap(template, { item }));
|
||||||
} else {
|
} else {
|
||||||
|
const collectionName = item.collectionName || item.name;
|
||||||
|
const collection = cm.getCollection(collectionName);
|
||||||
insert(
|
insert(
|
||||||
createDetailsUISchema(
|
createDetailsUISchema(
|
||||||
association
|
association
|
||||||
? {
|
? {
|
||||||
association,
|
association,
|
||||||
|
// see: https://applink.feishu.cn/client/message/link/open?token=AmP9n9dkwcABZrr3nBdAwAI%3D
|
||||||
|
collectionName: collection.isInherited() ? collectionName : undefined,
|
||||||
dataSource: item.dataSource,
|
dataSource: item.dataSource,
|
||||||
isCurrent: true,
|
isCurrent: true,
|
||||||
}
|
}
|
||||||
: {
|
: {
|
||||||
collectionName: item.collectionName || item.name,
|
collectionName,
|
||||||
dataSource: item.dataSource,
|
dataSource: item.dataSource,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[association, getTemplateSchemaByMode, insert, templateWrap],
|
[association, cm, getTemplateSchemaByMode, insert, templateWrap],
|
||||||
);
|
);
|
||||||
|
|
||||||
return { createSingleDetailsSchema, templateWrap };
|
return { createSingleDetailsSchema, templateWrap };
|
||||||
|
@ -10,8 +10,8 @@
|
|||||||
import { FormOutlined } from '@ant-design/icons';
|
import { FormOutlined } from '@ant-design/icons';
|
||||||
import React, { useCallback } from 'react';
|
import React, { useCallback } from 'react';
|
||||||
import { SchemaInitializerItem, useSchemaInitializer, useSchemaInitializerItem } from '../../../../application';
|
import { SchemaInitializerItem, useSchemaInitializer, useSchemaInitializerItem } from '../../../../application';
|
||||||
import { useAssociationName } from '../../../../data-source';
|
|
||||||
import { useCollection_deprecated } from '../../../../collection-manager';
|
import { useCollection_deprecated } from '../../../../collection-manager';
|
||||||
|
import { useAssociationName, useCollectionManager } from '../../../../data-source';
|
||||||
import { useRecordCollectionDataSourceItems } from '../../../../schema-initializer/utils';
|
import { useRecordCollectionDataSourceItems } from '../../../../schema-initializer/utils';
|
||||||
import { useSchemaTemplateManager } from '../../../../schema-templates';
|
import { useSchemaTemplateManager } from '../../../../schema-templates';
|
||||||
import { createEditFormBlockUISchema } from './createEditFormBlockUISchema';
|
import { createEditFormBlockUISchema } from './createEditFormBlockUISchema';
|
||||||
@ -49,40 +49,47 @@ export const RecordFormBlockInitializer = () => {
|
|||||||
export function useCreateEditFormBlock() {
|
export function useCreateEditFormBlock() {
|
||||||
const { insert } = useSchemaInitializer();
|
const { insert } = useSchemaInitializer();
|
||||||
const association = useAssociationName();
|
const association = useAssociationName();
|
||||||
|
const cm = useCollectionManager();
|
||||||
|
|
||||||
const createEditFormBlock = useCallback(
|
const createEditFormBlock = useCallback(
|
||||||
({ item }) => {
|
({ item }) => {
|
||||||
|
const collectionName = item.collectionName || item.name;
|
||||||
|
const collection = cm.getCollection(collectionName);
|
||||||
insert(
|
insert(
|
||||||
createEditFormBlockUISchema(
|
createEditFormBlockUISchema(
|
||||||
association
|
association
|
||||||
? {
|
? {
|
||||||
association,
|
association,
|
||||||
|
collectionName: collection.isInherited() ? collectionName : undefined,
|
||||||
dataSource: item.dataSource,
|
dataSource: item.dataSource,
|
||||||
isCurrent: true,
|
isCurrent: true,
|
||||||
}
|
}
|
||||||
: {
|
: {
|
||||||
collectionName: item.collectionName || item.name,
|
collectionName,
|
||||||
dataSource: item.dataSource,
|
dataSource: item.dataSource,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
[association, insert],
|
[association, cm, insert],
|
||||||
);
|
);
|
||||||
|
|
||||||
const templateWrap = useCallback(
|
const templateWrap = useCallback(
|
||||||
(templateSchema, { item }) => {
|
(templateSchema, { item }) => {
|
||||||
if (item.template.componentName === 'FormItem') {
|
if (item.template.componentName === 'FormItem') {
|
||||||
|
const collectionName = item.collectionName || item.name;
|
||||||
|
const collection = cm.getCollection(collectionName);
|
||||||
const blockSchema = createEditFormBlockUISchema(
|
const blockSchema = createEditFormBlockUISchema(
|
||||||
association
|
association
|
||||||
? {
|
? {
|
||||||
association,
|
association,
|
||||||
|
collectionName: collection.isInherited() ? collectionName : undefined,
|
||||||
dataSource: item.dataSource,
|
dataSource: item.dataSource,
|
||||||
templateSchema: templateSchema,
|
templateSchema: templateSchema,
|
||||||
isCurrent: true,
|
isCurrent: true,
|
||||||
}
|
}
|
||||||
: {
|
: {
|
||||||
collectionName: item.collectionName || item.name,
|
collectionName,
|
||||||
dataSource: item.dataSource,
|
dataSource: item.dataSource,
|
||||||
templateSchema: templateSchema,
|
templateSchema: templateSchema,
|
||||||
},
|
},
|
||||||
@ -95,7 +102,7 @@ export function useCreateEditFormBlock() {
|
|||||||
return templateSchema;
|
return templateSchema;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[association],
|
[association, cm],
|
||||||
);
|
);
|
||||||
|
|
||||||
return { createEditFormBlock, templateWrap };
|
return { createEditFormBlock, templateWrap };
|
||||||
|
@ -155,7 +155,7 @@ const PagePopupsItemProvider: FC<{
|
|||||||
<PopupVisibleProvider visible={visible} setVisible={setVisible}>
|
<PopupVisibleProvider visible={visible} setVisible={setVisible}>
|
||||||
<DataBlockProvider
|
<DataBlockProvider
|
||||||
dataSource={context.dataSource}
|
dataSource={context.dataSource}
|
||||||
collection={context.collection}
|
collection={params.collection || context.collection}
|
||||||
association={context.association}
|
association={context.association}
|
||||||
sourceId={params.sourceid}
|
sourceId={params.sourceid}
|
||||||
filterByTk={params.filterbytk}
|
filterByTk={params.filterbytk}
|
||||||
|
@ -35,6 +35,8 @@ export interface PopupParams {
|
|||||||
sourceid?: string;
|
sourceid?: string;
|
||||||
/** tab uid */
|
/** tab uid */
|
||||||
tab?: string;
|
tab?: string;
|
||||||
|
/** collection name */
|
||||||
|
collection?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PopupContextStorage extends PopupContext {
|
export interface PopupContextStorage extends PopupContext {
|
||||||
@ -101,9 +103,11 @@ export const getPopupParamsFromPath = _.memoize((path: string) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
export const getPopupPathFromParams = (params: PopupParams) => {
|
export const getPopupPathFromParams = (params: PopupParams) => {
|
||||||
const { popupuid: popupUid, tab, filterbytk, sourceid } = params;
|
const { popupuid: popupUid, tab, filterbytk, sourceid, collection } = params;
|
||||||
const popupPath = [
|
const popupPath = [
|
||||||
popupUid,
|
popupUid,
|
||||||
|
collection && 'collection',
|
||||||
|
collection,
|
||||||
filterbytk && 'filterbytk',
|
filterbytk && 'filterbytk',
|
||||||
filterbytk,
|
filterbytk,
|
||||||
sourceid && 'sourceid',
|
sourceid && 'sourceid',
|
||||||
@ -148,15 +152,18 @@ export const usePagePopup = () => {
|
|||||||
popupUid,
|
popupUid,
|
||||||
recordData,
|
recordData,
|
||||||
sourceId,
|
sourceId,
|
||||||
|
collection: _collection,
|
||||||
}: {
|
}: {
|
||||||
popupUid: string;
|
popupUid: string;
|
||||||
recordData: Record<string, any>;
|
recordData: Record<string, any>;
|
||||||
sourceId: string;
|
sourceId: string;
|
||||||
tabKey?: string;
|
tabKey?: string;
|
||||||
|
collection?: string;
|
||||||
}) => {
|
}) => {
|
||||||
const filterByTK = cm.getFilterByTK(association || collection, recordData);
|
const filterByTK = cm.getFilterByTK(association || collection, recordData);
|
||||||
return getPopupPathFromParams({
|
return getPopupPathFromParams({
|
||||||
popupuid: popupUid,
|
popupuid: popupUid,
|
||||||
|
collection: _collection,
|
||||||
filterbytk: filterByTK,
|
filterbytk: filterByTK,
|
||||||
sourceid: sourceId,
|
sourceid: sourceId,
|
||||||
tab: tabKey,
|
tab: tabKey,
|
||||||
@ -179,9 +186,12 @@ export const usePagePopup = () => {
|
|||||||
({
|
({
|
||||||
recordData,
|
recordData,
|
||||||
parentRecordData,
|
parentRecordData,
|
||||||
|
collectionNameUsedInURL,
|
||||||
}: {
|
}: {
|
||||||
recordData?: Record<string, any>;
|
recordData?: Record<string, any>;
|
||||||
parentRecordData?: Record<string, any>;
|
parentRecordData?: Record<string, any>;
|
||||||
|
/** if this value exists, it will be saved in the URL */
|
||||||
|
collectionNameUsedInURL?: string;
|
||||||
} = {}) => {
|
} = {}) => {
|
||||||
if (!isPopupVisibleControlledByURL()) {
|
if (!isPopupVisibleControlledByURL()) {
|
||||||
return setVisibleFromAction?.(true);
|
return setVisibleFromAction?.(true);
|
||||||
@ -190,7 +200,12 @@ export const usePagePopup = () => {
|
|||||||
const sourceId = getSourceId(parentRecordData);
|
const sourceId = getSourceId(parentRecordData);
|
||||||
|
|
||||||
recordData = recordData || record?.data;
|
recordData = recordData || record?.data;
|
||||||
const pathname = getNewPathname({ popupUid: currentPopupUidWithoutOpened, recordData, sourceId });
|
const pathname = getNewPathname({
|
||||||
|
popupUid: currentPopupUidWithoutOpened,
|
||||||
|
recordData,
|
||||||
|
sourceId,
|
||||||
|
collection: collectionNameUsedInURL,
|
||||||
|
});
|
||||||
let url = location.pathname;
|
let url = location.pathname;
|
||||||
if (_.last(url) === '/') {
|
if (_.last(url) === '/') {
|
||||||
url = url.slice(0, -1);
|
url = url.slice(0, -1);
|
||||||
|
@ -166,7 +166,9 @@ const useTableColumns = (props: { showDel?: boolean; isSubTable?: boolean }) =>
|
|||||||
title: render(),
|
title: render(),
|
||||||
dataIndex: 'TABLE_COLUMN_INITIALIZER',
|
dataIndex: 'TABLE_COLUMN_INITIALIZER',
|
||||||
key: 'TABLE_COLUMN_INITIALIZER',
|
key: 'TABLE_COLUMN_INITIALIZER',
|
||||||
render: designable ? () => <div style={{ width: '100%' }} /> : null,
|
render: designable
|
||||||
|
? () => <div style={{ width: '100%', minWidth: '180px' }} className="nb-column-initializer" />
|
||||||
|
: null,
|
||||||
fixed: designable ? 'right' : 'none',
|
fixed: designable ? 'right' : 'none',
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
@ -13,7 +13,6 @@ import {
|
|||||||
useActionAvailable,
|
useActionAvailable,
|
||||||
useCollection,
|
useCollection,
|
||||||
useCollectionManager_deprecated,
|
useCollectionManager_deprecated,
|
||||||
useCollection_deprecated,
|
|
||||||
useCreateAssociationDetailsBlock,
|
useCreateAssociationDetailsBlock,
|
||||||
useCreateAssociationDetailsWithoutPagination,
|
useCreateAssociationDetailsWithoutPagination,
|
||||||
useCreateAssociationFormBlock,
|
useCreateAssociationFormBlock,
|
||||||
@ -46,7 +45,7 @@ export const canMakeAssociationBlock = (field) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
function useRecordBlocks() {
|
function useRecordBlocks() {
|
||||||
const collection = useCollection_deprecated();
|
const collection = useCollection();
|
||||||
const { getChildrenCollections } = useCollectionManager_deprecated();
|
const { getChildrenCollections } = useCollectionManager_deprecated();
|
||||||
const collectionsWithView = getChildrenCollections(collection.name, true, collection.dataSource).filter(
|
const collectionsWithView = getChildrenCollections(collection.name, true, collection.dataSource).filter(
|
||||||
(v) => v?.filterTargetKey,
|
(v) => v?.filterTargetKey,
|
||||||
@ -60,7 +59,7 @@ function useRecordBlocks() {
|
|||||||
collectionName: collection.name,
|
collectionName: collection.name,
|
||||||
dataSource: collection.dataSource,
|
dataSource: collection.dataSource,
|
||||||
useComponentProps() {
|
useComponentProps() {
|
||||||
const currentCollection = useCollection_deprecated();
|
const currentCollection = useCollection();
|
||||||
const { createSingleDetailsSchema, templateWrap } = useCreateSingleDetailsSchema();
|
const { createSingleDetailsSchema, templateWrap } = useCreateSingleDetailsSchema();
|
||||||
const { createAssociationDetailsBlock } = useCreateAssociationDetailsBlock();
|
const { createAssociationDetailsBlock } = useCreateAssociationDetailsBlock();
|
||||||
const {
|
const {
|
||||||
@ -126,7 +125,7 @@ function useRecordBlocks() {
|
|||||||
collectionName: collection.name,
|
collectionName: collection.name,
|
||||||
dataSource: collection.dataSource,
|
dataSource: collection.dataSource,
|
||||||
useComponentProps() {
|
useComponentProps() {
|
||||||
const currentCollection = useCollection_deprecated();
|
const currentCollection = useCollection();
|
||||||
const { createEditFormBlock, templateWrap: templateWrapEdit } = useCreateEditFormBlock();
|
const { createEditFormBlock, templateWrap: templateWrapEdit } = useCreateEditFormBlock();
|
||||||
const collectionsNeedToDisplay = [currentCollection, ...collectionsWithView];
|
const collectionsNeedToDisplay = [currentCollection, ...collectionsWithView];
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ import { observer, useField, useFieldSchema, useForm } from '@formily/react';
|
|||||||
import { Button, Dropdown, MenuProps } from 'antd';
|
import { Button, Dropdown, MenuProps } from 'antd';
|
||||||
import { composeRef } from 'rc-util/lib/ref';
|
import { composeRef } from 'rc-util/lib/ref';
|
||||||
import React, { createRef, forwardRef, useEffect, useMemo } from 'react';
|
import React, { createRef, forwardRef, useEffect, useMemo } from 'react';
|
||||||
import { Collection, useDesignable } from '../../';
|
import { Collection, useCollectionManager, useDesignable } from '../../';
|
||||||
import { useACLActionParamsContext, useACLRolesCheck, useRecordPkValue } from '../../acl/ACLProvider';
|
import { useACLActionParamsContext, useACLRolesCheck, useRecordPkValue } from '../../acl/ACLProvider';
|
||||||
import { useCollectionManager_deprecated, useCollection_deprecated } from '../../collection-manager';
|
import { useCollectionManager_deprecated, useCollection_deprecated } from '../../collection-manager';
|
||||||
import { useTreeParentRecord } from '../../modules/blocks/data-blocks/table/TreeRecordProvider';
|
import { useTreeParentRecord } from '../../modules/blocks/data-blocks/table/TreeRecordProvider';
|
||||||
@ -65,7 +65,6 @@ function useAclCheckFn() {
|
|||||||
|
|
||||||
const InternalCreateRecordAction = (props: any, ref) => {
|
const InternalCreateRecordAction = (props: any, ref) => {
|
||||||
const fieldSchema = useFieldSchema();
|
const fieldSchema = useFieldSchema();
|
||||||
const openMode = fieldSchema?.['x-component-props']?.['openMode'];
|
|
||||||
const field: any = useField();
|
const field: any = useField();
|
||||||
const linkageRules: any[] = fieldSchema?.['x-linkage-rules'] || [];
|
const linkageRules: any[] = fieldSchema?.['x-linkage-rules'] || [];
|
||||||
const values = useRecord();
|
const values = useRecord();
|
||||||
@ -73,6 +72,7 @@ const InternalCreateRecordAction = (props: any, ref) => {
|
|||||||
const localVariables = useLocalVariables({ currentForm: { values } as any });
|
const localVariables = useLocalVariables({ currentForm: { values } as any });
|
||||||
const { openPopup } = usePagePopup();
|
const { openPopup } = usePagePopup();
|
||||||
const treeRecordData = useTreeParentRecord();
|
const treeRecordData = useTreeParentRecord();
|
||||||
|
const cm = useCollectionManager();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
field.stateOfLinkageRules = {};
|
field.stateOfLinkageRules = {};
|
||||||
@ -98,13 +98,22 @@ const InternalCreateRecordAction = (props: any, ref) => {
|
|||||||
<div ref={buttonRef as React.Ref<HTMLButtonElement>}>
|
<div ref={buttonRef as React.Ref<HTMLButtonElement>}>
|
||||||
<CreateAction
|
<CreateAction
|
||||||
{...props}
|
{...props}
|
||||||
onClick={(collection: Collection) => {
|
onClick={(collection: Partial<Collection>) => {
|
||||||
|
collection = cm.getCollection(collection.name) || collection;
|
||||||
|
|
||||||
if (treeRecordData) {
|
if (treeRecordData) {
|
||||||
openPopup({
|
openPopup({
|
||||||
recordData: treeRecordData,
|
recordData: treeRecordData,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
openPopup();
|
// fix https://nocobase.height.app/T-5084/description
|
||||||
|
if (collection.isInherited?.()) {
|
||||||
|
openPopup({
|
||||||
|
collectionNameUsedInURL: collection.name,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
openPopup();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
@ -12,9 +12,9 @@ import React, { useCallback } from 'react';
|
|||||||
|
|
||||||
import { SchemaInitializerItem, useSchemaInitializer, useSchemaInitializerItem } from '../../application';
|
import { SchemaInitializerItem, useSchemaInitializer, useSchemaInitializerItem } from '../../application';
|
||||||
import { useCollectionManager_deprecated } from '../../collection-manager';
|
import { useCollectionManager_deprecated } from '../../collection-manager';
|
||||||
|
import { createDetailsWithPaginationUISchema } from '../../modules/blocks/data-blocks/details-multi/createDetailsWithPaginationUISchema';
|
||||||
import { useSchemaTemplateManager } from '../../schema-templates';
|
import { useSchemaTemplateManager } from '../../schema-templates';
|
||||||
import { useRecordCollectionDataSourceItems } from '../utils';
|
import { useRecordCollectionDataSourceItems } from '../utils';
|
||||||
import { createDetailsWithPaginationUISchema } from '../../modules/blocks/data-blocks/details-multi/createDetailsWithPaginationUISchema';
|
|
||||||
|
|
||||||
export const RecordAssociationDetailsBlockInitializer = () => {
|
export const RecordAssociationDetailsBlockInitializer = () => {
|
||||||
const itemConfig = useSchemaInitializerItem();
|
const itemConfig = useSchemaInitializerItem();
|
||||||
|
@ -19,7 +19,9 @@ export const useStyles = createStyles(({ token, css }) => {
|
|||||||
.ant-table-thead button[aria-label*='schema-initializer-TableV2-table:configureColumns'] > .ant-btn-icon {
|
.ant-table-thead button[aria-label*='schema-initializer-TableV2-table:configureColumns'] > .ant-btn-icon {
|
||||||
margin: 0px;
|
margin: 0px;
|
||||||
}
|
}
|
||||||
|
.ant-table-tbody .nb-column-initializer {
|
||||||
|
min-width: 40px !important;
|
||||||
|
}
|
||||||
// reset Select record popup
|
// reset Select record popup
|
||||||
.ant-table-thead
|
.ant-table-thead
|
||||||
button[aria-label*='schema-initializer-TableV2.Selector-table:configureColumns']
|
button[aria-label*='schema-initializer-TableV2.Selector-table:configureColumns']
|
||||||
@ -54,10 +56,6 @@ export const useStyles = createStyles(({ token, css }) => {
|
|||||||
.ant-card-body .nb-action-bar .ant-btn-icon {
|
.ant-card-body .nb-action-bar .ant-btn-icon {
|
||||||
margin-inline-end: 0px !important;
|
margin-inline-end: 0px !important;
|
||||||
}
|
}
|
||||||
.ant-card-body .ant-table-cell-fix-right:last-child {
|
|
||||||
// display: table-cell;
|
|
||||||
// width: auto;
|
|
||||||
}
|
|
||||||
.ant-card-body .nb-table-container {
|
.ant-card-body .nb-table-container {
|
||||||
margin-right: -20px;
|
margin-right: -20px;
|
||||||
margin-left: -10px;
|
margin-left: -10px;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user