From 0fc89454925818f6874c621d9522d16869033ce4 Mon Sep 17 00:00:00 2001 From: Naumov Alexey Date: Thu, 18 Nov 2021 01:31:50 +0300 Subject: [PATCH] feat(core-app): CB-1435 option to disable operations with metadata --- .../core-app/src/CoreSettingsService.ts | 2 ++ .../NodesManager/NavNodeContextMenuService.ts | 20 ++++++++++++++++--- .../ObjectPropertyTableFooter.tsx | 9 ++++++++- .../ObjectPropertyTableFooterService.ts | 4 +++- .../packages/product-default/src/config.json5 | 4 ++++ 5 files changed, 34 insertions(+), 5 deletions(-) diff --git a/webapp/packages/core-app/src/CoreSettingsService.ts b/webapp/packages/core-app/src/CoreSettingsService.ts index 4d5917a883..b0103fcd55 100644 --- a/webapp/packages/core-app/src/CoreSettingsService.ts +++ b/webapp/packages/core-app/src/CoreSettingsService.ts @@ -16,6 +16,8 @@ const defaultSettings = { 'app.logViewer.maxFailedRequests': 3, // temporary limit for all nodes children in app 'app.navigationTree.childrenLimit': 500, + 'app.metadata.editing': false, + 'app.metadata.deleting': false, }; export type CoreSettings = typeof defaultSettings; diff --git a/webapp/packages/core-app/src/shared/NodesManager/NavNodeContextMenuService.ts b/webapp/packages/core-app/src/shared/NodesManager/NavNodeContextMenuService.ts index fc448c60bc..6283e7963a 100644 --- a/webapp/packages/core-app/src/shared/NodesManager/NavNodeContextMenuService.ts +++ b/webapp/packages/core-app/src/shared/NodesManager/NavNodeContextMenuService.ts @@ -11,6 +11,7 @@ import { CommonDialogService, ConfirmationDialogDelete, DialogueStateResult, Ren import { NotificationService } from '@cloudbeaver/core-events'; import { ActionService, ACTION_DELETE, ACTION_OPEN, ACTION_REFRESH, ACTION_RENAME, DATA_CONTEXT_MENU_NESTED, MenuSeparatorItem, MenuService } from '@cloudbeaver/core-view'; +import { CoreSettingsService } from '../../../src/CoreSettingsService'; import { DATA_CONTEXT_NAV_NODE_ACTIONS } from '../../NavigationTree/NavigationTreeNode/TreeNodeMenu/DATA_CONTEXT_NAV_NODE_ACTIONS'; import { DATA_CONTEXT_NAV_NODE } from './DATA_CONTEXT_NAV_NODE'; import { ENodeFeature } from './ENodeFeature'; @@ -34,6 +35,7 @@ export class NavNodeContextMenuService extends Bootstrap { private readonly navTreeResource: NavTreeResource, private readonly actionService: ActionService, private readonly menuService: MenuService, + private readonly coreSettingsService: CoreSettingsService ) { super(); } @@ -41,7 +43,7 @@ export class NavNodeContextMenuService extends Bootstrap { register(): void { this.actionService.addHandler({ id: 'nav-node-base-handler', - isActionApplicable(context, action) { + isActionApplicable: (context, action) => { const node = context.tryGet(DATA_CONTEXT_NAV_NODE); if (!node) { @@ -49,11 +51,23 @@ export class NavNodeContextMenuService extends Bootstrap { } if (action === ACTION_RENAME) { - return node.features?.includes(ENodeFeature.canRename) || false; + const globalPermission = this.coreSettingsService.settings.getValue('app.metadata.editing'); + + if (!globalPermission) { + return false; + } + + return !!node.features?.includes(ENodeFeature.canRename); } if (action === ACTION_DELETE) { - return node.features?.includes(ENodeFeature.canDelete) || false; + const globalPermission = this.coreSettingsService.settings.getValue('app.metadata.deleting'); + + if (!globalPermission) { + return false; + } + + return !!node.features?.includes(ENodeFeature.canDelete); } return [ diff --git a/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectPropertyTable/ObjectPropertyTableFooter.tsx b/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectPropertyTable/ObjectPropertyTableFooter.tsx index 3f8f0231e7..007bc8d999 100644 --- a/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectPropertyTable/ObjectPropertyTableFooter.tsx +++ b/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectPropertyTable/ObjectPropertyTableFooter.tsx @@ -23,9 +23,16 @@ interface Props { export const ObjectPropertyTableFooter = observer(function ObjectPropertyTableFooter({ nodeIds, tableState, className }) { const service = useService(ObjectPropertyTableFooterService); + const items = service.constructMenuWithContext(nodeIds, tableState); + const hidden = items.every(item => item.isHidden); + + if (hidden) { + return null; + } + return ( - {service.constructMenuWithContext(nodeIds, tableState).map((topItem, i) => ( + {items.map((topItem, i) => ( ))} diff --git a/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectPropertyTable/ObjectPropertyTableFooterService.ts b/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectPropertyTable/ObjectPropertyTableFooterService.ts index c7bb75bdea..3b7395182d 100644 --- a/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectPropertyTable/ObjectPropertyTableFooterService.ts +++ b/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectPropertyTable/ObjectPropertyTableFooterService.ts @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. */ -import { ENodeFeature, getNodeName, NavNode, NavNodeInfoResource, NavTreeResource } from '@cloudbeaver/core-app'; +import { CoreSettingsService, ENodeFeature, getNodeName, NavNode, NavNodeInfoResource, NavTreeResource } from '@cloudbeaver/core-app'; import type { TableState } from '@cloudbeaver/core-blocks'; import { injectable } from '@cloudbeaver/core-di'; import { @@ -32,6 +32,7 @@ export class ObjectPropertyTableFooterService { private readonly navNodeInfoResource: NavNodeInfoResource, private readonly notificationService: NotificationService, private readonly commonDialogService: CommonDialogService, + private readonly coreSettingsService: CoreSettingsService ) { this.contextMenuService.addPanel(this.objectPropertyTableFooterToken); @@ -44,6 +45,7 @@ export class ObjectPropertyTableFooterService { isPresent(context) { return context.contextType === ObjectPropertyTableFooterService.objectPropertyContextType; }, + isHidden: () => !this.coreSettingsService.settings.getValue('app.metadata.deleting'), isDisabled: context => { if (context.data.tableState.selectedList.length === 0) { return true; diff --git a/webapp/packages/product-default/src/config.json5 b/webapp/packages/product-default/src/config.json5 index 3ea2f1689e..b1144012d0 100644 --- a/webapp/packages/product-default/src/config.json5 +++ b/webapp/packages/product-default/src/config.json5 @@ -9,6 +9,10 @@ defaultLanguage: "en" }, app: { + metadata: { + editing: false, + deleting: false, + }, // Log viewer config logViewer: { refreshTimeout: 3000,