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:
katherinehhh 2024-04-10 16:38:37 +08:00 committed by GitHub
parent e9f0e32a26
commit ca49cc9dbd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 850 additions and 10 deletions

View File

@ -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>;

View File

@ -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}

View File

@ -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();
});

View File

@ -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,
},
};

View File

@ -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}
>

View File

@ -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));