diff --git a/packages/web/src/appobj/ArchiveFolderAppObject.svelte b/packages/web/src/appobj/ArchiveFolderAppObject.svelte
index 8ffa9bec2..ca463e54e 100644
--- a/packages/web/src/appobj/ArchiveFolderAppObject.svelte
+++ b/packages/web/src/appobj/ArchiveFolderAppObject.svelte
@@ -17,6 +17,7 @@
import InputTextModal from '../modals/InputTextModal.svelte';
import ErrorMessageModal from '../modals/ErrorMessageModal.svelte';
import { apiCall } from '../utility/api';
+ import hasPermission from '../utility/hasPermission';
export let data;
@@ -140,6 +141,7 @@ await dbgateApi.deployDb(${JSON.stringify(
],
data.name != 'default' &&
+ hasPermission('dbops/model/compare') &&
_.get($currentDatabase, 'connection._id') && {
onClick: handleCompareWithCurrentDb,
text: `Compare with ${_.get($currentDatabase, 'name')}`,
diff --git a/packages/web/src/appobj/ConnectionAppObject.svelte b/packages/web/src/appobj/ConnectionAppObject.svelte
index 76521f594..8c3020e5b 100644
--- a/packages/web/src/appobj/ConnectionAppObject.svelte
+++ b/packages/web/src/appobj/ConnectionAppObject.svelte
@@ -106,6 +106,7 @@
import AboutModal from '../modals/AboutModal.svelte';
import { tick } from 'svelte';
import { getConnectionLabel } from 'dbgate-tools';
+ import hasPermission from '../utility/hasPermission';
export let data;
export let passProps;
@@ -220,26 +221,27 @@
};
return [
- config.runAsPortal == false && [
- {
- text: $openedConnections.includes(data._id) ? 'View details' : 'Edit',
- onClick: handleOpenConnectionTab,
- },
- !$openedConnections.includes(data._id) && {
- text: 'Delete',
- onClick: handleDelete,
- },
- {
- text: 'Duplicate',
- onClick: handleDuplicate,
- },
- ],
+ config.runAsPortal == false &&
+ !config.storageDatabase && [
+ {
+ text: $openedConnections.includes(data._id) ? 'View details' : 'Edit',
+ onClick: handleOpenConnectionTab,
+ },
+ !$openedConnections.includes(data._id) && {
+ text: 'Delete',
+ onClick: handleDelete,
+ },
+ {
+ text: 'Duplicate',
+ onClick: handleDuplicate,
+ },
+ ],
!data.singleDatabase && [
!$openedConnections.includes(data._id) && {
text: 'Connect',
onClick: handleConnect,
},
- { onClick: handleNewQuery, text: 'New query', isNewQuery: true },
+ hasPermission(`dbops/query`) && { onClick: handleNewQuery, text: 'New query', isNewQuery: true },
$openedConnections.includes(data._id) &&
data.status && {
text: 'Refresh',
@@ -249,7 +251,8 @@
text: 'Disconnect',
onClick: handleDisconnect,
},
- $openedConnections.includes(data._id) &&
+ hasPermission(`dbops/createdb`) &&
+ $openedConnections.includes(data._id) &&
driver?.supportedCreateDatabase &&
!data.isReadOnly && {
text: 'Create database',
diff --git a/packages/web/src/appobj/DatabaseAppObject.svelte b/packages/web/src/appobj/DatabaseAppObject.svelte
index ddf2c66d5..4673664f9 100644
--- a/packages/web/src/appobj/DatabaseAppObject.svelte
+++ b/packages/web/src/appobj/DatabaseAppObject.svelte
@@ -280,20 +280,27 @@
driver?.databaseEngineTypes?.includes('sql') || driver?.databaseEngineTypes?.includes('document');
return [
- { onClick: handleNewQuery, text: 'New query', isNewQuery: true },
- driver?.databaseEngineTypes?.includes('sql') && { onClick: handleNewTable, text: 'New table' },
- driver?.databaseEngineTypes?.includes('document') && {
- onClick: handleNewCollection,
- text: `New ${driver?.collectionSingularLabel ?? 'collection/container'}`,
- },
- driver?.databaseEngineTypes?.includes('sql') && { onClick: handleQueryDesigner, text: 'Design query' },
+ hasPermission(`dbops/query`) && { onClick: handleNewQuery, text: 'New query', isNewQuery: true },
+ hasPermission(`dbops/model/edit`) &&
+ !connection.isReadOnly &&
+ driver?.databaseEngineTypes?.includes('sql') && { onClick: handleNewTable, text: 'New table' },
+ !connection.isReadOnly &&
+ hasPermission(`dbops/model/edit`) &&
+ driver?.databaseEngineTypes?.includes('document') && {
+ onClick: handleNewCollection,
+ text: `New ${driver?.collectionSingularLabel ?? 'collection/container'}`,
+ },
+ hasPermission(`dbops/query`) &&
+ driver?.databaseEngineTypes?.includes('sql') && { onClick: handleQueryDesigner, text: 'Design query' },
driver?.databaseEngineTypes?.includes('sql') && {
onClick: handleNewPerspective,
text: 'Design perspective query',
},
{ divider: true },
- isSqlOrDoc && !connection.isReadOnly && { onClick: handleImport, text: 'Import wizard' },
- isSqlOrDoc && { onClick: handleExport, text: 'Export wizard' },
+ isSqlOrDoc &&
+ !connection.isReadOnly &&
+ hasPermission(`dbops/import`) && { onClick: handleImport, text: 'Import wizard' },
+ isSqlOrDoc && hasPermission(`dbops/export`) && { onClick: handleExport, text: 'Export wizard' },
driver?.databaseEngineTypes?.includes('sql') &&
hasPermission(`dbops/sql-dump/import`) &&
!connection.isReadOnly && { onClick: handleSqlRestore, text: 'Restore/import SQL dump' },
@@ -301,7 +308,9 @@
hasPermission(`dbops/sql-dump/export`) && { onClick: handleSqlDump, text: 'Backup/export SQL dump' },
isSqlOrDoc &&
!connection.isReadOnly &&
- !connection.singleDatabase && { onClick: handleDropDatabase, text: 'Drop database' },
+ !connection.singleDatabase &&
+ isSqlOrDoc &&
+ hasPermission(`dbops/dropdb`) && { onClick: handleDropDatabase, text: 'Drop database' },
{ divider: true },
driver?.databaseEngineTypes?.includes('sql') && { onClick: handleCopyName, text: 'Copy database name' },
driver?.databaseEngineTypes?.includes('sql') && { onClick: handleShowDiagram, text: 'Show diagram' },
@@ -309,10 +318,14 @@
hasPermission(`dbops/sql-generator`) && { onClick: handleSqlGenerator, text: 'SQL Generator' },
driver?.supportsDatabaseProfiler &&
hasPermission(`dbops/profiler`) && { onClick: handleDatabaseProfiler, text: 'Database profiler' },
- isSqlOrDoc && { onClick: handleOpenJsonModel, text: 'Open model as JSON' },
- isSqlOrDoc && { onClick: handleExportModel, text: 'Export DB model - experimental' },
+ isSqlOrDoc &&
+ isSqlOrDoc &&
+ hasPermission(`dbops/model/view`) && { onClick: handleOpenJsonModel, text: 'Open model as JSON' },
+ isSqlOrDoc &&
+ hasPermission(`dbops/model/view`) && { onClick: handleExportModel, text: 'Export DB model - experimental' },
isSqlOrDoc &&
_.get($currentDatabase, 'connection._id') &&
+ hasPermission('dbops/model/compare') &&
(_.get($currentDatabase, 'connection._id') != _.get(connection, '_id') ||
(_.get($currentDatabase, 'connection._id') == _.get(connection, '_id') &&
_.get($currentDatabase, 'name') != _.get(connection, 'name'))) && {
diff --git a/packages/web/src/appobj/DatabaseObjectAppObject.svelte b/packages/web/src/appobj/DatabaseObjectAppObject.svelte
index f228acaf3..92529e8fd 100644
--- a/packages/web/src/appobj/DatabaseObjectAppObject.svelte
+++ b/packages/web/src/appobj/DatabaseObjectAppObject.svelte
@@ -98,12 +98,12 @@
isDrop: true,
requiresWriteAccess: true,
},
- {
+ hasPermission('dbops/table/rename') && {
label: 'Rename table',
isRename: true,
requiresWriteAccess: true,
},
- {
+ hasPermission('dbops/table/truncate') && {
label: 'Truncate table',
isTruncate: true,
requiresWriteAccess: true,
@@ -113,29 +113,29 @@
isCopyTableName: true,
requiresWriteAccess: false,
},
- {
+ hasPermission('dbops/table/backup') && {
label: 'Create table backup',
isDuplicateTable: true,
requiresWriteAccess: true,
},
- {
+ hasPermission('dbops/model/view') && {
label: 'Show diagram',
isDiagram: true,
},
{
divider: true,
},
- {
+ hasPermission('dbops/export') && {
label: 'Export',
functionName: 'tableReader',
isExport: true,
},
- {
+ hasPermission('dbops/import') && {
label: 'Import',
isImport: true,
requiresWriteAccess: true,
},
- {
+ hasPermission('dbops/charts') && {
label: 'Open active chart',
isActiveChart: true,
},
diff --git a/packages/web/src/buttons/ToolStripExportButton.svelte b/packages/web/src/buttons/ToolStripExportButton.svelte
index 4e6311e52..6d800f757 100644
--- a/packages/web/src/buttons/ToolStripExportButton.svelte
+++ b/packages/web/src/buttons/ToolStripExportButton.svelte
@@ -20,6 +20,7 @@
-{#if quickExportHandlerRef}
-
-{:else}
-
+{#if hasPermission('dbops/export')}
+ {#if quickExportHandlerRef}
+
+ {:else}
+
+ {/if}
{/if}
diff --git a/packages/web/src/datagrid/CollectionDataGridCore.svelte b/packages/web/src/datagrid/CollectionDataGridCore.svelte
index a7b256fcb..b8fbf7e75 100644
--- a/packages/web/src/datagrid/CollectionDataGridCore.svelte
+++ b/packages/web/src/datagrid/CollectionDataGridCore.svelte
@@ -246,10 +246,15 @@
registerQuickExportHandler(quickExportHandler);
- registerMenu({ command: 'collectionDataGrid.openQuery', tag: 'export' }, () => ({
- ...createQuickExportMenu(quickExportHandler, { command: 'collectionDataGrid.export' }),
- tag: 'export',
- }));
+ registerMenu({ command: 'collectionDataGrid.openQuery', tag: 'export' }, () =>
+ createQuickExportMenu(
+ quickExportHandler,
+ {
+ command: 'collectionDataGrid.export',
+ },
+ { tag: 'export' }
+ )
+ );
function handleSetLoadedRows(rows) {
loadedRows = rows;
diff --git a/packages/web/src/datagrid/DataGridCore.svelte b/packages/web/src/datagrid/DataGridCore.svelte
index eeb0f8e5c..c4330a497 100644
--- a/packages/web/src/datagrid/DataGridCore.svelte
+++ b/packages/web/src/datagrid/DataGridCore.svelte
@@ -430,6 +430,7 @@
import { openJsonLinesData } from '../utility/openJsonLinesData';
import contextMenuActivator from '../utility/contextMenuActivator';
import InputTextModal from '../modals/InputTextModal.svelte';
+ import hasPermission from '../utility/hasPermission';
export let onLoadNextData = undefined;
export let grider = undefined;
diff --git a/packages/web/src/datagrid/JslDataGridCore.svelte b/packages/web/src/datagrid/JslDataGridCore.svelte
index c25164e6b..18d0cfb33 100644
--- a/packages/web/src/datagrid/JslDataGridCore.svelte
+++ b/packages/web/src/datagrid/JslDataGridCore.svelte
@@ -186,10 +186,15 @@
};
registerQuickExportHandler(quickExportHandler);
- registerMenu(() => ({
- ...createQuickExportMenu(quickExportHandler, { command: 'jslTableGrid.export' }),
- tag: 'export',
- }));
+ registerMenu(() =>
+ createQuickExportMenu(
+ quickExportHandler,
+ {
+ command: 'jslTableGrid.export',
+ },
+ { tag: 'export' }
+ )
+ );
function handleSetLoadedRows(rows) {
loadedRows = rows;
diff --git a/packages/web/src/datagrid/SqlDataGridCore.svelte b/packages/web/src/datagrid/SqlDataGridCore.svelte
index 7b8357e3c..df8157d86 100644
--- a/packages/web/src/datagrid/SqlDataGridCore.svelte
+++ b/packages/web/src/datagrid/SqlDataGridCore.svelte
@@ -5,7 +5,7 @@
id: 'sqlDataGrid.openActiveChart',
category: 'Data grid',
name: 'Open active chart',
- testEnabled: () => getCurrentEditor() != null,
+ testEnabled: () => getCurrentEditor() != null && hasPermission('dbops/charts'),
onClick: () => getCurrentEditor().openActiveChart(),
});
@@ -13,7 +13,7 @@
id: 'sqlDataGrid.openQuery',
category: 'Data grid',
name: 'Open query',
- testEnabled: () => getCurrentEditor() != null,
+ testEnabled: () => getCurrentEditor() != null && hasPermission('dbops/query'),
onClick: () => getCurrentEditor().openQuery(),
});
@@ -23,7 +23,7 @@
name: 'Export',
icon: 'icon export',
keyText: 'CtrlOrCommand+E',
- testEnabled: () => getCurrentEditor() != null,
+ testEnabled: () => getCurrentEditor() != null && hasPermission('dbops/export'),
onClick: () => getCurrentEditor().exportGrid(),
});
@@ -83,6 +83,7 @@
import ChangeSetGrider from './ChangeSetGrider';
import LoadingDataGridCore from './LoadingDataGridCore.svelte';
+ import hasPermission from '../utility/hasPermission';
export let conid;
export let display;
@@ -209,10 +210,14 @@
registerMenu(
{ command: 'sqlDataGrid.openActiveChart', tag: 'chart' },
{ command: 'sqlDataGrid.openQuery', tag: 'export' },
- () => ({
- ...createQuickExportMenu(quickExportHandler, { command: 'sqlDataGrid.export' }),
- tag: 'export',
- })
+ () =>
+ createQuickExportMenu(
+ quickExportHandler,
+ {
+ command: 'sqlDataGrid.export',
+ },
+ { tag: 'export' }
+ )
);
function handleSetLoadedRows(rows) {
diff --git a/packages/web/src/tabs/TableStructureTab.svelte b/packages/web/src/tabs/TableStructureTab.svelte
index 8f77b7fc8..6c39a3b2f 100644
--- a/packages/web/src/tabs/TableStructureTab.svelte
+++ b/packages/web/src/tabs/TableStructureTab.svelte
@@ -61,6 +61,7 @@
import ToolStripContainer from '../buttons/ToolStripContainer.svelte';
import ToolStripCommandButton from '../buttons/ToolStripCommandButton.svelte';
import ToolStripButton from '../buttons/ToolStripButton.svelte';
+ import hasPermission from '../utility/hasPermission';
export let tabid;
export let conid;
@@ -171,7 +172,7 @@
tableInfo={showTable}
dbInfo={$dbInfo}
{driver}
- setTableInfo={objectTypeField == 'tables' && !$connection?.isReadOnly
+ setTableInfo={objectTypeField == 'tables' && !$connection?.isReadOnly && hasPermission(`dbops/model/edit`)
? tableInfoUpdater =>
setEditorData(tbl =>
tbl
diff --git a/packages/web/src/utility/createQuickExportMenu.ts b/packages/web/src/utility/createQuickExportMenu.ts
index 69fa70788..10c575257 100644
--- a/packages/web/src/utility/createQuickExportMenu.ts
+++ b/packages/web/src/utility/createQuickExportMenu.ts
@@ -1,5 +1,6 @@
import type { QuickExportDefinition } from 'dbgate-types';
import { currentArchive, getCurrentArchive, getExtensions } from '../stores';
+import hasPermission from './hasPermission';
export function createQuickExportMenuItems(handler: (fmt: QuickExportDefinition) => Function, advancedExportMenuItem) {
const extensions = getExtensions();
@@ -34,10 +35,16 @@ export function createQuickExportMenuItems(handler: (fmt: QuickExportDefinition)
export default function createQuickExportMenu(
handler: (fmt: QuickExportDefinition) => Function,
- advancedExportMenuItem
+ advancedExportMenuItem,
+ additionalFields = {}
) {
+ if (!hasPermission('dbops/export')) {
+ return null;
+ }
+
return {
text: 'Export',
submenu: createQuickExportMenuItems(handler, advancedExportMenuItem),
+ ...advancedExportMenuItem,
};
}