mirror of
https://gitee.com/nocobase/nocobase.git
synced 2025-07-02 03:02:19 +08:00
fix: association block action permission verification failed (#3994)
* fix: association block action permission verification failed * test: association block action permission test * fix: useDataBlockProps * fix: useDataBlockProps * fix: useResourceName * fix: bug * fix: bug * fix: bug * fix: bug --------- Co-authored-by: chenos <chenlinxh@gmail.com>
This commit is contained in:
parent
e9f0e32a26
commit
ca49cc9dbd
@ -151,7 +151,12 @@ const useAllowedActions = () => {
|
||||
const useResourceName = () => {
|
||||
const service = useResourceActionContext();
|
||||
const result = useBlockRequestContext() || { service };
|
||||
return result?.props?.resource || result?.props?.collection || result?.service?.defaultRequest?.resource;
|
||||
return (
|
||||
result?.props?.resource ||
|
||||
result?.props?.association ||
|
||||
result?.props?.collection ||
|
||||
result?.service?.defaultRequest?.resource
|
||||
);
|
||||
};
|
||||
|
||||
export function useACLRoleContext() {
|
||||
@ -237,6 +242,9 @@ export const ACLActionProvider = (props) => {
|
||||
if (!actionPath) {
|
||||
return <>{props.children}</>;
|
||||
}
|
||||
if (!resource) {
|
||||
return <>{props.children}</>;
|
||||
}
|
||||
const params = parseAction(actionPath, { schema, recordPkValue });
|
||||
if (!params) {
|
||||
return <ACLActionParamsContext.Provider value={params}>{props.children}</ACLActionParamsContext.Provider>;
|
||||
|
@ -5,7 +5,7 @@ import { Button, Dropdown, MenuProps } from 'antd';
|
||||
import React, { useEffect, useMemo, useState, forwardRef, createRef } from 'react';
|
||||
import { composeRef } from 'rc-util/lib/ref';
|
||||
import { useDesignable } from '../../';
|
||||
import { useACLRolesCheck, useRecordPkValue } from '../../acl/ACLProvider';
|
||||
import { useACLRolesCheck, useRecordPkValue, useACLActionParamsContext } from '../../acl/ACLProvider';
|
||||
import {
|
||||
CollectionProvider_deprecated,
|
||||
useCollection_deprecated,
|
||||
@ -284,6 +284,12 @@ function FinallyButton({
|
||||
designable: boolean;
|
||||
}) {
|
||||
const { getCollection } = useCollectionManager_deprecated();
|
||||
const aclCtx = useACLActionParamsContext();
|
||||
const buttonStyle = useMemo(() => {
|
||||
return {
|
||||
opacity: designable && (field?.data?.hidden || !aclCtx) && 0.1,
|
||||
};
|
||||
}, [designable, field?.data?.hidden]);
|
||||
|
||||
if (inheritsCollections?.length > 0) {
|
||||
if (!linkageFromForm) {
|
||||
@ -293,6 +299,7 @@ function FinallyButton({
|
||||
danger={props.danger}
|
||||
type={componentType}
|
||||
icon={<DownOutlined />}
|
||||
style={{ ...props?.style, ...buttonStyle }}
|
||||
buttonsRender={([leftButton, rightButton]) => [
|
||||
React.cloneElement(leftButton as React.ReactElement<any, string>, {
|
||||
style: props?.style,
|
||||
@ -318,7 +325,7 @@ function FinallyButton({
|
||||
icon={icon}
|
||||
type={componentType}
|
||||
danger={props.danger}
|
||||
style={props?.style}
|
||||
style={{ ...props?.style, ...buttonStyle }}
|
||||
>
|
||||
{props.children} <DownOutlined />
|
||||
</Button>
|
||||
@ -344,6 +351,7 @@ function FinallyButton({
|
||||
style={{
|
||||
display: !designable && field?.data?.hidden && 'none',
|
||||
opacity: designable && field?.data?.hidden && 0.1,
|
||||
...buttonStyle,
|
||||
}}
|
||||
>
|
||||
{props.children}
|
||||
@ -365,6 +373,7 @@ function FinallyButton({
|
||||
...props?.style,
|
||||
display: !designable && field?.data?.hidden && 'none',
|
||||
opacity: designable && field?.data?.hidden && 0.1,
|
||||
...buttonStyle,
|
||||
}}
|
||||
>
|
||||
{props.children}
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { expect, test } from '@nocobase/test/e2e';
|
||||
import { oneTableBlock } from './utils';
|
||||
import { oneTableBlock, T3950 } from './utils';
|
||||
|
||||
test.describe('view', () => {
|
||||
//关系字段有权限,关系目标表无权限
|
||||
@ -232,3 +232,31 @@ test.describe('create', () => {
|
||||
await expect(page.getByLabel('block-item-CollectionField-users-form-users.username')).not.toBeVisible();
|
||||
});
|
||||
});
|
||||
|
||||
test('association block action permission', async ({ page, mockCollection, mockRecord, mockPage, mockRole }) => {
|
||||
await mockPage(T3950).goto();
|
||||
await mockRecord('general');
|
||||
await expect(await page.getByLabel('block-item-CardItem-general-')).toBeVisible();
|
||||
//新建角色并切换到新角色
|
||||
const roleData = await mockRole({
|
||||
default: true,
|
||||
allowNewMenu: true,
|
||||
strategy: {
|
||||
actions: ['view', 'update', 'destroy'],
|
||||
},
|
||||
});
|
||||
await mockPage(T3950).goto();
|
||||
await page.evaluate((roleData) => {
|
||||
window.localStorage.setItem('NOCOBASE_ROLE', roleData.name);
|
||||
}, roleData);
|
||||
await page.reload();
|
||||
await expect(await page.getByLabel('block-item-CardItem-general-')).toBeVisible();
|
||||
await page.getByLabel('action-Action.Link-View-view-').first().click();
|
||||
await expect(await page.getByLabel('block-item-CardItem-users-')).toBeVisible();
|
||||
await expect(await page.getByLabel('action-Action.Link-View-view-users-table-').first()).toBeVisible();
|
||||
await expect(await page.getByLabel('action-Action.Link-Edit-').first()).toBeVisible();
|
||||
await expect(await page.getByLabel('action-Action.Link-Delete-').first()).toBeVisible();
|
||||
await expect(
|
||||
await page.getByLabel('action-Action.Link-Disassociate-disassociate-users-table-').first(),
|
||||
).toBeVisible();
|
||||
});
|
||||
|
@ -3118,3 +3118,793 @@ export const newTableBlock: PageConfig = {
|
||||
'x-index': 1,
|
||||
},
|
||||
};
|
||||
|
||||
//T-3950
|
||||
export const T3950: PageConfig = {
|
||||
collections: [
|
||||
{
|
||||
name: 'general',
|
||||
fields: [
|
||||
{
|
||||
key: 'rednse3ig65',
|
||||
name: 'id',
|
||||
type: 'bigInt',
|
||||
interface: 'integer',
|
||||
description: null,
|
||||
collectionName: 'general',
|
||||
parentKey: null,
|
||||
reverseKey: null,
|
||||
autoIncrement: true,
|
||||
primaryKey: true,
|
||||
allowNull: false,
|
||||
uiSchema: {
|
||||
type: 'number',
|
||||
title: '{{t("ID")}}',
|
||||
'x-component': 'InputNumber',
|
||||
'x-read-pretty': true,
|
||||
},
|
||||
},
|
||||
{
|
||||
key: 'gav0bipnjfq',
|
||||
name: 'createdAt',
|
||||
type: 'date',
|
||||
interface: 'createdAt',
|
||||
description: null,
|
||||
collectionName: 'general',
|
||||
parentKey: null,
|
||||
reverseKey: null,
|
||||
field: 'createdAt',
|
||||
uiSchema: {
|
||||
type: 'datetime',
|
||||
title: '{{t("Created at")}}',
|
||||
'x-component': 'DatePicker',
|
||||
'x-component-props': {},
|
||||
'x-read-pretty': true,
|
||||
},
|
||||
},
|
||||
{
|
||||
key: '4z36i3tq78k',
|
||||
name: 'createdBy',
|
||||
type: 'belongsTo',
|
||||
interface: 'createdBy',
|
||||
description: null,
|
||||
collectionName: 'general',
|
||||
parentKey: null,
|
||||
reverseKey: null,
|
||||
target: 'users',
|
||||
foreignKey: 'createdById',
|
||||
uiSchema: {
|
||||
type: 'object',
|
||||
title: '{{t("Created by")}}',
|
||||
'x-component': 'AssociationField',
|
||||
'x-component-props': {
|
||||
fieldNames: {
|
||||
value: 'id',
|
||||
label: 'nickname',
|
||||
},
|
||||
},
|
||||
'x-read-pretty': true,
|
||||
},
|
||||
targetKey: 'id',
|
||||
},
|
||||
{
|
||||
key: 'vtrxdhfchau',
|
||||
name: 'updatedAt',
|
||||
type: 'date',
|
||||
interface: 'updatedAt',
|
||||
description: null,
|
||||
collectionName: 'general',
|
||||
parentKey: null,
|
||||
reverseKey: null,
|
||||
field: 'updatedAt',
|
||||
uiSchema: {
|
||||
type: 'string',
|
||||
title: '{{t("Last updated at")}}',
|
||||
'x-component': 'DatePicker',
|
||||
'x-component-props': {},
|
||||
'x-read-pretty': true,
|
||||
},
|
||||
},
|
||||
{
|
||||
key: 'mqk7xpljqze',
|
||||
name: 'updatedBy',
|
||||
type: 'belongsTo',
|
||||
interface: 'updatedBy',
|
||||
description: null,
|
||||
collectionName: 'general',
|
||||
parentKey: null,
|
||||
reverseKey: null,
|
||||
target: 'users',
|
||||
foreignKey: 'updatedById',
|
||||
uiSchema: {
|
||||
type: 'object',
|
||||
title: '{{t("Last updated by")}}',
|
||||
'x-component': 'AssociationField',
|
||||
'x-component-props': {
|
||||
fieldNames: {
|
||||
value: 'id',
|
||||
label: 'nickname',
|
||||
},
|
||||
},
|
||||
'x-read-pretty': true,
|
||||
},
|
||||
targetKey: 'id',
|
||||
},
|
||||
{
|
||||
key: 'eybc7t9ifwu',
|
||||
name: 'oneToMany',
|
||||
type: 'hasMany',
|
||||
interface: 'o2m',
|
||||
description: null,
|
||||
collectionName: 'general',
|
||||
parentKey: null,
|
||||
reverseKey: null,
|
||||
sourceKey: 'id',
|
||||
foreignKey: 'f_iw9gnd2ivcd',
|
||||
onDelete: 'SET NULL',
|
||||
uiSchema: {
|
||||
'x-component': 'AssociationField',
|
||||
'x-component-props': {
|
||||
multiple: true,
|
||||
},
|
||||
title: 'oneToMany',
|
||||
},
|
||||
target: 'users',
|
||||
targetKey: 'id',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
pageSchema: {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
'x-component': 'Page',
|
||||
'x-app-version': '0.21.0-alpha.6',
|
||||
properties: {
|
||||
qhfizzdk5jo: {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
'x-component': 'Grid',
|
||||
'x-initializer': 'page:addBlock',
|
||||
'x-app-version': '0.21.0-alpha.6',
|
||||
properties: {
|
||||
'7z14apvqexc': {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
'x-component': 'Grid.Row',
|
||||
'x-app-version': '0.21.0-alpha.6',
|
||||
properties: {
|
||||
wmnazvitfos: {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
'x-component': 'Grid.Col',
|
||||
'x-app-version': '0.21.0-alpha.6',
|
||||
properties: {
|
||||
x9oz9gu7q0z: {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
'x-decorator': 'TableBlockProvider',
|
||||
'x-acl-action': 'general:list',
|
||||
'x-use-decorator-props': 'useTableBlockDecoratorProps',
|
||||
'x-decorator-props': {
|
||||
collection: 'general',
|
||||
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': '0.21.0-alpha.6',
|
||||
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': '0.21.0-alpha.6',
|
||||
'x-uid': 'nn2njfaih86',
|
||||
'x-async': false,
|
||||
'x-index': 1,
|
||||
},
|
||||
'6a5603ynwr4': {
|
||||
_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': '0.21.0-alpha.6',
|
||||
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-designer': 'TableV2.ActionColumnDesigner',
|
||||
'x-initializer': 'table:configureItemActions',
|
||||
'x-app-version': '0.21.0-alpha.6',
|
||||
properties: {
|
||||
iy4tox4zcxc: {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
'x-decorator': 'DndContext',
|
||||
'x-component': 'Space',
|
||||
'x-component-props': {
|
||||
split: '|',
|
||||
},
|
||||
'x-app-version': '0.21.0-alpha.6',
|
||||
properties: {
|
||||
ikhm99e57nf: {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
title: '{{ t("View") }}',
|
||||
'x-action': 'view',
|
||||
'x-toolbar': 'ActionSchemaToolbar',
|
||||
'x-settings': 'actionSettings:view',
|
||||
'x-component': 'Action.Link',
|
||||
'x-component-props': {
|
||||
openMode: 'drawer',
|
||||
},
|
||||
'x-decorator': 'ACLActionProvider',
|
||||
'x-designer-props': {
|
||||
linkageAction: true,
|
||||
},
|
||||
properties: {
|
||||
drawer: {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
title: '{{ t("View record") }}',
|
||||
'x-component': 'Action.Container',
|
||||
'x-component-props': {
|
||||
className: 'nb-action-popup',
|
||||
},
|
||||
properties: {
|
||||
tabs: {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
'x-component': 'Tabs',
|
||||
'x-component-props': {},
|
||||
'x-initializer': 'popup:addTab',
|
||||
properties: {
|
||||
tab1: {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
title: '{{t("Details")}}',
|
||||
'x-component': 'Tabs.TabPane',
|
||||
'x-designer': 'Tabs.Designer',
|
||||
'x-component-props': {},
|
||||
properties: {
|
||||
grid: {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
'x-component': 'Grid',
|
||||
'x-initializer': 'popup:common:addBlock',
|
||||
properties: {
|
||||
hot6v7tha6h: {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
'x-component': 'Grid.Row',
|
||||
'x-app-version': '0.21.0-alpha.6',
|
||||
properties: {
|
||||
f87i04cltpt: {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
'x-component': 'Grid.Col',
|
||||
'x-app-version': '0.21.0-alpha.6',
|
||||
properties: {
|
||||
ojj1b5l9e8h: {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
'x-decorator': 'TableBlockProvider',
|
||||
'x-acl-action': 'undefined:list',
|
||||
'x-use-decorator-props': 'useTableBlockDecoratorProps',
|
||||
'x-decorator-props': {
|
||||
association: 'general.oneToMany',
|
||||
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': '0.21.0-alpha.6',
|
||||
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': '0.21.0-alpha.6',
|
||||
'x-uid': 'zgmpgolmvn2',
|
||||
'x-async': false,
|
||||
'x-index': 1,
|
||||
},
|
||||
'31phiwi82cg': {
|
||||
_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': '0.21.0-alpha.6',
|
||||
properties: {
|
||||
actions: {
|
||||
'x-uid': '0n4vabchec2',
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
title: '{{ t("Actions") }}',
|
||||
'x-action-column': 'actions',
|
||||
'x-decorator': 'TableV2.Column.ActionBar',
|
||||
'x-component': 'TableV2.Column',
|
||||
'x-designer': 'TableV2.ActionColumnDesigner',
|
||||
'x-initializer': 'table:configureItemActions',
|
||||
'x-app-version': '0.21.0-alpha.6',
|
||||
'x-component-props': {
|
||||
width: 400,
|
||||
},
|
||||
properties: {
|
||||
ddp51tpewsi: {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
'x-decorator': 'DndContext',
|
||||
'x-component': 'Space',
|
||||
'x-component-props': {
|
||||
split: '|',
|
||||
},
|
||||
'x-app-version': '0.21.0-alpha.6',
|
||||
properties: {
|
||||
woj7fep0hm4: {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
title: '{{ t("View") }}',
|
||||
'x-action': 'view',
|
||||
'x-toolbar': 'ActionSchemaToolbar',
|
||||
'x-settings': 'actionSettings:view',
|
||||
'x-component': 'Action.Link',
|
||||
'x-component-props': {
|
||||
openMode: 'drawer',
|
||||
},
|
||||
'x-decorator': 'ACLActionProvider',
|
||||
'x-designer-props': {
|
||||
linkageAction: true,
|
||||
},
|
||||
properties: {
|
||||
drawer: {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
title: '{{ t("View record") }}',
|
||||
'x-component': 'Action.Container',
|
||||
'x-component-props': {
|
||||
className: 'nb-action-popup',
|
||||
},
|
||||
properties: {
|
||||
tabs: {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
'x-component': 'Tabs',
|
||||
'x-component-props': {},
|
||||
'x-initializer': 'popup:addTab',
|
||||
properties: {
|
||||
tab1: {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
title: '{{t("Details")}}',
|
||||
'x-component':
|
||||
'Tabs.TabPane',
|
||||
'x-designer':
|
||||
'Tabs.Designer',
|
||||
'x-component-props': {},
|
||||
properties: {
|
||||
grid: {
|
||||
_isJSONSchemaObject:
|
||||
true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
'x-component': 'Grid',
|
||||
'x-initializer':
|
||||
'popup:common:addBlock',
|
||||
'x-uid': 'yo2uv487d2i',
|
||||
'x-async': false,
|
||||
'x-index': 1,
|
||||
},
|
||||
},
|
||||
'x-uid': 'lgdz91veg1u',
|
||||
'x-async': false,
|
||||
'x-index': 1,
|
||||
},
|
||||
},
|
||||
'x-uid': 'b2vze6fnrm9',
|
||||
'x-async': false,
|
||||
'x-index': 1,
|
||||
},
|
||||
},
|
||||
'x-uid': 'wga6ipim0zs',
|
||||
'x-async': false,
|
||||
'x-index': 1,
|
||||
},
|
||||
},
|
||||
'x-uid': 'fp0oo6x9tk3',
|
||||
'x-async': false,
|
||||
'x-index': 1,
|
||||
},
|
||||
pbbpkoavxwf: {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
title: '{{ t("Edit") }}',
|
||||
'x-action': 'update',
|
||||
'x-toolbar': 'ActionSchemaToolbar',
|
||||
'x-settings': 'actionSettings:edit',
|
||||
'x-component': 'Action.Link',
|
||||
'x-component-props': {
|
||||
openMode: 'drawer',
|
||||
icon: 'EditOutlined',
|
||||
},
|
||||
'x-decorator': 'ACLActionProvider',
|
||||
'x-designer-props': {
|
||||
linkageAction: true,
|
||||
},
|
||||
properties: {
|
||||
drawer: {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
title: '{{ t("Edit record") }}',
|
||||
'x-component': 'Action.Container',
|
||||
'x-component-props': {
|
||||
className: 'nb-action-popup',
|
||||
},
|
||||
properties: {
|
||||
tabs: {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
'x-component': 'Tabs',
|
||||
'x-component-props': {},
|
||||
'x-initializer': 'popup:addTab',
|
||||
properties: {
|
||||
tab1: {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
title: '{{t("Edit")}}',
|
||||
'x-component':
|
||||
'Tabs.TabPane',
|
||||
'x-designer':
|
||||
'Tabs.Designer',
|
||||
'x-component-props': {},
|
||||
properties: {
|
||||
grid: {
|
||||
_isJSONSchemaObject:
|
||||
true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
'x-component': 'Grid',
|
||||
'x-initializer':
|
||||
'popup:common:addBlock',
|
||||
'x-uid': 'o3xomb2tbiq',
|
||||
'x-async': false,
|
||||
'x-index': 1,
|
||||
},
|
||||
},
|
||||
'x-uid': 'lwulpt4io1w',
|
||||
'x-async': false,
|
||||
'x-index': 1,
|
||||
},
|
||||
},
|
||||
'x-uid': '8cx8aep0zld',
|
||||
'x-async': false,
|
||||
'x-index': 1,
|
||||
},
|
||||
},
|
||||
'x-uid': '7wh4slzk13s',
|
||||
'x-async': false,
|
||||
'x-index': 1,
|
||||
},
|
||||
},
|
||||
'x-uid': '332wvu9s2df',
|
||||
'x-async': false,
|
||||
'x-index': 2,
|
||||
},
|
||||
yrcve881mt3: {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
title: '{{ t("Delete") }}',
|
||||
'x-action': 'destroy',
|
||||
'x-component': 'Action.Link',
|
||||
'x-use-component-props':
|
||||
'useDestroyActionProps',
|
||||
'x-toolbar': 'ActionSchemaToolbar',
|
||||
'x-settings': 'actionSettings:delete',
|
||||
'x-component-props': {
|
||||
icon: 'DeleteOutlined',
|
||||
confirm: {
|
||||
title: "{{t('Delete record')}}",
|
||||
content:
|
||||
"{{t('Are you sure you want to delete it?')}}",
|
||||
},
|
||||
refreshDataBlockRequest: true,
|
||||
},
|
||||
'x-action-settings': {
|
||||
triggerWorkflows: [],
|
||||
},
|
||||
'x-decorator': 'ACLActionProvider',
|
||||
'x-designer-props': {
|
||||
linkageAction: true,
|
||||
},
|
||||
type: 'void',
|
||||
'x-uid': 'mtluxghu85k',
|
||||
'x-async': false,
|
||||
'x-index': 3,
|
||||
},
|
||||
kxt91wcprep: {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
title: '{{ t("Disassociate") }}',
|
||||
'x-action': 'disassociate',
|
||||
'x-component': 'Action.Link',
|
||||
'x-use-component-props':
|
||||
'useDisassociateActionProps',
|
||||
'x-toolbar': 'ActionSchemaToolbar',
|
||||
'x-settings':
|
||||
'actionSettings:disassociate',
|
||||
'x-component-props': {
|
||||
icon: 'DeleteOutlined',
|
||||
confirm: {
|
||||
title:
|
||||
"{{t('Disassociate record')}}",
|
||||
content:
|
||||
"{{t('Are you sure you want to disassociate it?')}}",
|
||||
},
|
||||
refreshDataBlockRequest: true,
|
||||
},
|
||||
'x-action-settings': {
|
||||
triggerWorkflows: [],
|
||||
},
|
||||
'x-acl-action': 'destroy',
|
||||
'x-decorator': 'ACLActionProvider',
|
||||
'x-designer-props': {
|
||||
linkageAction: true,
|
||||
},
|
||||
type: 'void',
|
||||
'x-uid': '5k40cx4ecp2',
|
||||
'x-async': false,
|
||||
'x-index': 4,
|
||||
},
|
||||
'48h9l3qoe5b': {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
'x-action': 'duplicate',
|
||||
'x-acl-action': 'create',
|
||||
title: '{{ t("Duplicate") }}',
|
||||
'x-component': 'Action.Link',
|
||||
'x-decorator': 'ACLActionProvider',
|
||||
'x-component-props': {
|
||||
openMode: 'drawer',
|
||||
component: 'DuplicateAction',
|
||||
type: 'primary',
|
||||
},
|
||||
'x-toolbar': 'ActionSchemaToolbar',
|
||||
'x-settings':
|
||||
'actionSettings:duplicate',
|
||||
'x-designer-props': {
|
||||
linkageAction: true,
|
||||
},
|
||||
properties: {
|
||||
drawer: {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
title: '{{ t("Duplicate") }}',
|
||||
'x-component': 'Action.Container',
|
||||
'x-component-props': {
|
||||
className: 'nb-action-popup',
|
||||
},
|
||||
properties: {
|
||||
tabs: {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
'x-component': 'Tabs',
|
||||
'x-component-props': {},
|
||||
'x-initializer': 'popup:addTab',
|
||||
properties: {
|
||||
tab1: {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
title: '{{t("Duplicate")}}',
|
||||
'x-component':
|
||||
'Tabs.TabPane',
|
||||
'x-designer':
|
||||
'Tabs.Designer',
|
||||
'x-component-props': {},
|
||||
properties: {
|
||||
grid: {
|
||||
_isJSONSchemaObject:
|
||||
true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
'x-component': 'Grid',
|
||||
'x-initializer':
|
||||
'popup:addNew:addBlock',
|
||||
'x-uid': '2t4rg7k178t',
|
||||
'x-async': false,
|
||||
'x-index': 1,
|
||||
},
|
||||
},
|
||||
'x-uid': 'ng2y7pqaveu',
|
||||
'x-async': false,
|
||||
'x-index': 1,
|
||||
},
|
||||
},
|
||||
'x-uid': 'x72op1sqzff',
|
||||
'x-async': false,
|
||||
'x-index': 1,
|
||||
},
|
||||
},
|
||||
'x-uid': 'mzj2aawxgxz',
|
||||
'x-async': false,
|
||||
'x-index': 1,
|
||||
},
|
||||
},
|
||||
'x-uid': '763g5tj8tpv',
|
||||
'x-async': false,
|
||||
'x-index': 5,
|
||||
},
|
||||
},
|
||||
'x-uid': 'lsdpfhk0yly',
|
||||
'x-async': false,
|
||||
'x-index': 1,
|
||||
},
|
||||
},
|
||||
'x-async': false,
|
||||
'x-index': 1,
|
||||
},
|
||||
},
|
||||
'x-uid': 'avs8m3jirw8',
|
||||
'x-async': false,
|
||||
'x-index': 2,
|
||||
},
|
||||
},
|
||||
'x-uid': 'somr5mwp4rz',
|
||||
'x-async': false,
|
||||
'x-index': 1,
|
||||
},
|
||||
},
|
||||
'x-uid': 'znf1jxx21qk',
|
||||
'x-async': false,
|
||||
'x-index': 1,
|
||||
},
|
||||
},
|
||||
'x-uid': 'lllxuunrv35',
|
||||
'x-async': false,
|
||||
'x-index': 1,
|
||||
},
|
||||
},
|
||||
'x-uid': '5eaxps0lomk',
|
||||
'x-async': false,
|
||||
'x-index': 1,
|
||||
},
|
||||
},
|
||||
'x-uid': 'y1hgiae4tyd',
|
||||
'x-async': false,
|
||||
'x-index': 1,
|
||||
},
|
||||
},
|
||||
'x-uid': '3hheczcpfvi',
|
||||
'x-async': false,
|
||||
'x-index': 1,
|
||||
},
|
||||
},
|
||||
'x-uid': 'z7x8atv4h5g',
|
||||
'x-async': false,
|
||||
'x-index': 1,
|
||||
},
|
||||
},
|
||||
'x-uid': 'iqn1ziznwgo',
|
||||
'x-async': false,
|
||||
'x-index': 1,
|
||||
},
|
||||
},
|
||||
'x-uid': '61os5ttg0l0',
|
||||
'x-async': false,
|
||||
'x-index': 1,
|
||||
},
|
||||
},
|
||||
'x-uid': 'f9u6co342wc',
|
||||
'x-async': false,
|
||||
'x-index': 1,
|
||||
},
|
||||
},
|
||||
'x-uid': '54oli77ezw1',
|
||||
'x-async': false,
|
||||
'x-index': 2,
|
||||
},
|
||||
},
|
||||
'x-uid': 'qqnn8vvrb67',
|
||||
'x-async': false,
|
||||
'x-index': 1,
|
||||
},
|
||||
},
|
||||
'x-uid': '438hxz838f0',
|
||||
'x-async': false,
|
||||
'x-index': 1,
|
||||
},
|
||||
},
|
||||
'x-uid': 'jzr9yjvjjx9',
|
||||
'x-async': false,
|
||||
'x-index': 1,
|
||||
},
|
||||
},
|
||||
'x-uid': 'l1ojfs69fw2',
|
||||
'x-async': false,
|
||||
'x-index': 1,
|
||||
},
|
||||
},
|
||||
'x-uid': 'ld5raudf49f',
|
||||
'x-async': true,
|
||||
'x-index': 1,
|
||||
},
|
||||
};
|
||||
|
@ -4,9 +4,7 @@ import {
|
||||
ActionContextProvider,
|
||||
CollectionProvider_deprecated,
|
||||
RecordProvider,
|
||||
CollectionProvider,
|
||||
FormBlockContext,
|
||||
CollectionRecordProvider,
|
||||
fetchTemplateData,
|
||||
useAPIClient,
|
||||
useActionContext,
|
||||
@ -17,10 +15,10 @@ import {
|
||||
useFormBlockContext,
|
||||
useCollectionParentRecordData,
|
||||
useRecord,
|
||||
useCollectionRecord,
|
||||
useACLActionParamsContext,
|
||||
} from '@nocobase/client';
|
||||
import { App, Button } from 'antd';
|
||||
import React, { useState } from 'react';
|
||||
import React, { useState, useMemo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
export const actionDesignerCss = css`
|
||||
@ -85,6 +83,12 @@ export const DuplicateAction = observer(
|
||||
const { t } = useTranslation();
|
||||
const collectionFields = getCollectionFields(__collection || name);
|
||||
const formctx = useFormBlockContext();
|
||||
const aclCtx = useACLActionParamsContext();
|
||||
const buttonStyle = useMemo(() => {
|
||||
return {
|
||||
opacity: designable && (field?.data?.hidden || !aclCtx) && 0.1,
|
||||
};
|
||||
}, [designable, field?.data?.hidden]);
|
||||
const template = {
|
||||
key: 'duplicate',
|
||||
dataId: id,
|
||||
@ -118,7 +122,7 @@ export const DuplicateAction = observer(
|
||||
}
|
||||
};
|
||||
const handelDuplicate = () => {
|
||||
if (!disabled && !loading) {
|
||||
if (!disabled && !loading && aclCtx) {
|
||||
if (duplicateFields?.length > 0) {
|
||||
if (duplicateMode === 'quickDulicate') {
|
||||
handelQuickDuplicate();
|
||||
@ -166,6 +170,7 @@ export const DuplicateAction = observer(
|
||||
opacity: designable && field?.data?.hidden && 0.1,
|
||||
cursor: loading ? 'not-allowed' : 'pointer',
|
||||
position: 'relative',
|
||||
...buttonStyle,
|
||||
}}
|
||||
onClick={handelDuplicate}
|
||||
>
|
||||
|
@ -64,7 +64,7 @@ export const RolesResourcesActions = connect((props) => {
|
||||
} else {
|
||||
actionMap[actionName] = {
|
||||
name: actionName,
|
||||
fields: collectionFields?.filter((field) => field.interface)?.map?.((item) => item.name),
|
||||
fields: collectionFields?.map?.((item) => item.name),
|
||||
};
|
||||
}
|
||||
onChange(Object.values(actionMap));
|
||||
|
Loading…
x
Reference in New Issue
Block a user