diff --git a/packages/datalib/src/CollectionGridDisplay.ts b/packages/datalib/src/CollectionGridDisplay.ts index 74dfe747d..a70c20968 100644 --- a/packages/datalib/src/CollectionGridDisplay.ts +++ b/packages/datalib/src/CollectionGridDisplay.ts @@ -95,7 +95,8 @@ export class CollectionGridDisplay extends GridDisplay { cache: GridCache, setCache: ChangeCacheFunc, loadedRows, - changeSet + changeSet, + readOnly = false ) { super(config, setConfig, cache, setCache, driver); const changedDocs = _.compact(changeSet.updates.map(chs => chs.document)); @@ -103,7 +104,7 @@ export class CollectionGridDisplay extends GridDisplay { this.columns = analyseCollectionDisplayColumns([...(loadedRows || []), ...changedDocs, ...insertedDocs], this); this.filterable = true; this.sortable = true; - this.editable = true; + this.editable = !readOnly; this.supportsReload = true; this.isDynamicStructure = true; this.changeSetKeyFields = ['_id']; diff --git a/packages/datalib/src/TableFormViewDisplay.ts b/packages/datalib/src/TableFormViewDisplay.ts index 3698357b4..ca1cfd3b7 100644 --- a/packages/datalib/src/TableFormViewDisplay.ts +++ b/packages/datalib/src/TableFormViewDisplay.ts @@ -23,7 +23,8 @@ export class TableFormViewDisplay extends FormViewDisplay { dbinfo: DatabaseInfo, displayOptions, serverVersion, - getDictionaryDescription: DictionaryDescriptionFunc = null + getDictionaryDescription: DictionaryDescriptionFunc = null, + isReadOnly = false ) { super(config, setConfig, cache, setCache, driver, dbinfo, serverVersion); this.gridDisplay = new TableGridDisplay( @@ -36,7 +37,8 @@ export class TableFormViewDisplay extends FormViewDisplay { dbinfo, displayOptions, serverVersion, - getDictionaryDescription + getDictionaryDescription, + isReadOnly ); this.gridDisplay.addAllExpandedColumnsToSelected = true; @@ -263,4 +265,8 @@ export class TableFormViewDisplay extends FormViewDisplay { isExpandedColumn(uniqueName: string) { return this.gridDisplay.isExpandedColumn(uniqueName); } + + get editable() { + return this.gridDisplay.editable; + } } diff --git a/packages/datalib/src/TableGridDisplay.ts b/packages/datalib/src/TableGridDisplay.ts index e9480835d..fc0472071 100644 --- a/packages/datalib/src/TableGridDisplay.ts +++ b/packages/datalib/src/TableGridDisplay.ts @@ -36,7 +36,8 @@ export class TableGridDisplay extends GridDisplay { dbinfo: DatabaseInfo, public displayOptions: any, serverVersion, - public getDictionaryDescription: DictionaryDescriptionFunc = null + public getDictionaryDescription: DictionaryDescriptionFunc = null, + isReadOnly = false ) { super(config, setConfig, cache, setCache, driver, dbinfo, serverVersion); @@ -53,7 +54,7 @@ export class TableGridDisplay extends GridDisplay { this.filterable = true; this.sortable = true; this.groupable = true; - this.editable = true; + this.editable = !isReadOnly; this.supportsReload = true; this.baseTable = this.table; if (this.table && this.table.columns) { diff --git a/packages/web/src/appobj/AppObjectCore.svelte b/packages/web/src/appobj/AppObjectCore.svelte index ed0e33bd8..b17909fd7 100644 --- a/packages/web/src/appobj/AppObjectCore.svelte +++ b/packages/web/src/appobj/AppObjectCore.svelte @@ -14,6 +14,7 @@ export let isBold = false; export let isBusy = false; export let statusIcon = undefined; + export let statusIconBefore = undefined; export let statusTitle = undefined; export let extInfo = undefined; export let menu = undefined; @@ -101,6 +102,11 @@ {/if} {title} + {#if statusIconBefore} + + + + {/if} {#if statusIcon} diff --git a/packages/web/src/appobj/ConnectionAppObject.svelte b/packages/web/src/appobj/ConnectionAppObject.svelte index d75772209..7a2a70b32 100644 --- a/packages/web/src/appobj/ConnectionAppObject.svelte +++ b/packages/web/src/appobj/ConnectionAppObject.svelte @@ -200,6 +200,7 @@ : _.get($currentDatabase, 'connection._id') == data._id} statusIcon={statusIcon || engineStatusIcon} statusTitle={statusTitle || engineStatusTitle} + statusIconBefore={data.isReadOnly ? 'icon lock' : null} {extInfo} colorMark={passProps?.connectionColorFactory && passProps?.connectionColorFactory({ conid: data._id })} menu={getContextMenu} diff --git a/packages/web/src/appobj/DatabaseAppObject.svelte b/packages/web/src/appobj/DatabaseAppObject.svelte index 78e86a980..cba517142 100644 --- a/packages/web/src/appobj/DatabaseAppObject.svelte +++ b/packages/web/src/appobj/DatabaseAppObject.svelte @@ -177,7 +177,7 @@ driver?.databaseEngineTypes?.includes('sql') && { onClick: handleNewTable, text: 'New table' }, driver?.databaseEngineTypes?.includes('document') && { onClick: handleNewCollection, text: 'New collection' }, { divider: true }, - { onClick: handleImport, text: 'Import' }, + !connection.isReadOnly && { onClick: handleImport, text: 'Import' }, { onClick: handleExport, text: 'Export' }, { onClick: handleShowDiagram, text: 'Show diagram' }, { onClick: handleSqlGenerator, text: 'SQL Generator' }, diff --git a/packages/web/src/datagrid/DataGrid.svelte b/packages/web/src/datagrid/DataGrid.svelte index 52bfdad87..02db99cc9 100644 --- a/packages/web/src/datagrid/DataGrid.svelte +++ b/packages/web/src/datagrid/DataGrid.svelte @@ -69,8 +69,7 @@ import _ from 'lodash'; import registerCommand from '../commands/registerCommand'; import { registerMenu } from '../utility/contextMenu'; - import { getBoolSettingsValue } from '../settings/settingsTools'; - import { getLocalStorage, getLocalStorage, getLocalStorage, setLocalStorage } from '../utility/storageCache'; + import { getLocalStorage, setLocalStorage } from '../utility/storageCache'; export let config; export let setConfig; diff --git a/packages/web/src/datagrid/TableDataGrid.svelte b/packages/web/src/datagrid/TableDataGrid.svelte index b38120bbc..7db002ff7 100644 --- a/packages/web/src/datagrid/TableDataGrid.svelte +++ b/packages/web/src/datagrid/TableDataGrid.svelte @@ -70,7 +70,8 @@ extendedDbInfo, { showHintColumns: getBoolSettingsValue('dataGrid.showHintColumns', true) }, $serverVersion, - table => getDictionaryDescription(table, conid, database, $apps, $connections) + table => getDictionaryDescription(table, conid, database, $apps, $connections), + $connection?.isReadOnly ) : null; @@ -86,7 +87,8 @@ extendedDbInfo, { showHintColumns: getBoolSettingsValue('dataGrid.showHintColumns', true) }, $serverVersion, - table => getDictionaryDescription(table, conid, database, $apps, $connections) + table => getDictionaryDescription(table, conid, database, $apps, $connections), + $connection?.isReadOnly ) : null; diff --git a/packages/web/src/formview/ChangeSetFormer.ts b/packages/web/src/formview/ChangeSetFormer.ts index e9f645d13..7b640e8d7 100644 --- a/packages/web/src/formview/ChangeSetFormer.ts +++ b/packages/web/src/formview/ChangeSetFormer.ts @@ -82,6 +82,9 @@ export default class ChangeSetFormer extends Former { redo() { this.dispatchChangeSet({ type: 'redo' }); } + get editable() { + return this.display.editable; + } get canUndo() { return this.changeSetState.canUndo; } diff --git a/packages/web/src/formview/FormView.svelte b/packages/web/src/formview/FormView.svelte index 548998d66..bca7f5d0a 100644 --- a/packages/web/src/formview/FormView.svelte +++ b/packages/web/src/formview/FormView.svelte @@ -327,6 +327,7 @@ const [inplaceEditorState, dispatchInsplaceEditor] = createReducer((state, action) => { switch (action.type) { case 'show': { + if (!former.editable) return {}; const column = getCellColumn(action.cell); if (!column) return state; if (column.uniquePath.length > 1) return state; diff --git a/packages/web/src/icons/FontIcon.svelte b/packages/web/src/icons/FontIcon.svelte index 1ff16ff98..93a7283ae 100644 --- a/packages/web/src/icons/FontIcon.svelte +++ b/packages/web/src/icons/FontIcon.svelte @@ -93,6 +93,7 @@ 'icon dots-vertical': 'mdi mdi-dots-vertical', 'icon add': 'mdi mdi-plus-circle', 'icon json': 'mdi mdi-code-json', + 'icon lock': 'mdi mdi-lock', 'icon run': 'mdi mdi-play', 'icon chevron-down': 'mdi mdi-chevron-down', diff --git a/packages/web/src/impexp/FormConnectionSelect.svelte b/packages/web/src/impexp/FormConnectionSelect.svelte index 4f7911f32..c87d144c4 100644 --- a/packages/web/src/impexp/FormConnectionSelect.svelte +++ b/packages/web/src/impexp/FormConnectionSelect.svelte @@ -3,16 +3,20 @@ import FormSelectField from '../forms/FormSelectField.svelte'; import getConnectionLabel from '../utility/getConnectionLabel'; import { useConnectionList } from '../utility/metadataLoaders'; + export let allowChooseModel = false; + export let direction; $: connections = useConnectionList(); $: connectionOptions = [ ...(allowChooseModel ? [{ label: '(DB Model)', value: '__model' }] : []), ..._.sortBy( - ($connections || []).map(conn => ({ - value: conn._id, - label: getConnectionLabel(conn), - })), + ($connections || []) + .filter(conn => (direction == 'target' ? !conn.isReadOnly : true)) + .map(conn => ({ + value: conn._id, + label: getConnectionLabel(conn), + })), 'label' ), ]; diff --git a/packages/web/src/impexp/SourceTargetConfig.svelte b/packages/web/src/impexp/SourceTargetConfig.svelte index 1574668ab..43755fe2e 100644 --- a/packages/web/src/impexp/SourceTargetConfig.svelte +++ b/packages/web/src/impexp/SourceTargetConfig.svelte @@ -114,7 +114,7 @@ /> {#if storageType == 'database' || storageType == 'query'} - + {/if} {#if storageType == 'database'} diff --git a/packages/web/src/tabs/CollectionDataTab.svelte b/packages/web/src/tabs/CollectionDataTab.svelte index 067873c3a..db7ab7728 100644 --- a/packages/web/src/tabs/CollectionDataTab.svelte +++ b/packages/web/src/tabs/CollectionDataTab.svelte @@ -89,7 +89,8 @@ $cache, cache.update, loadedRows, - $changeSetStore?.value + $changeSetStore?.value, + $connection?.isReadOnly ) : null; // $: console.log('LOADED ROWS MONGO', loadedRows); diff --git a/packages/web/src/widgets/StatusBar.svelte b/packages/web/src/widgets/StatusBar.svelte index 5e640d7ca..b448245d4 100644 --- a/packages/web/src/widgets/StatusBar.svelte +++ b/packages/web/src/widgets/StatusBar.svelte @@ -12,7 +12,7 @@ import { findCommand } from '../commands/runCommand'; import { useConnectionColor } from '../utility/useConnectionColor'; import { apiCall } from '../utility/api'; -import { statusBarTabInfo } from '../utility/statusBarStore'; + import { statusBarTabInfo } from '../utility/statusBarStore'; $: databaseName = $currentDatabase && $currentDatabase.name; $: connection = $currentDatabase && $currentDatabase.connection; @@ -44,7 +44,11 @@ import { statusBarTabInfo } from '../utility/statusBarStore';
{#if databaseName}
- + {#if connection?.isReadOnly} + + {:else} + + {/if} {databaseName}
{#if dbid} diff --git a/packages/web/src/widgets/TabsPanel.svelte b/packages/web/src/widgets/TabsPanel.svelte index bf3345e15..0e6538b9d 100644 --- a/packages/web/src/widgets/TabsPanel.svelte +++ b/packages/web/src/widgets/TabsPanel.svelte @@ -390,6 +390,9 @@
{tabGroup.tabDbName} + {#if $connectionList?.find(x => x._id == tabGroup.tabs[0]?.props?.conid)?.isReadOnly} + + {/if}