diff --git a/openbis_ng_ui/src/js/common/consts/ids.js b/openbis_ng_ui/src/js/common/consts/ids.js
index 0861f9e06075a0fc0f3d0fbb4a3fabf009ee182b..b0dd040ce0238465e3705fb44ecc5a1054233c48 100644
--- a/openbis_ng_ui/src/js/common/consts/ids.js
+++ b/openbis_ng_ui/src/js/common/consts/ids.js
@@ -22,6 +22,7 @@ const VOCABULARY_TERMS_GRID_ID = 'vocabulary_terms_grid'
 const DYNAMIC_PROPERTY_PLUGINS_GRID_ID = 'dynamic_property_plugins_grid'
 const ENTITY_VALIDATION_PLUGINS_GRID_ID = 'entity_validation_plugins_grid'
 const QUERIES_GRID_ID = 'queries_grid'
+const QUERY_RESULTS_GRID_ID = 'query_results_grid'
 const HISTORY_OF_DELETION_GRID_ID = 'history_of_deletion_grid'
 const HISTORY_OF_FREEZING_GRID_ID = 'history_of_freezing_grid'
 const PERSONAL_ACCESS_TOKEN_GRID_ID = 'personal_access_token_grid'
@@ -56,6 +57,7 @@ export default {
   DYNAMIC_PROPERTY_PLUGINS_GRID_ID,
   ENTITY_VALIDATION_PLUGINS_GRID_ID,
   QUERIES_GRID_ID,
+  QUERY_RESULTS_GRID_ID,
   HISTORY_OF_DELETION_GRID_ID,
   HISTORY_OF_FREEZING_GRID_ID,
   PERSONAL_ACCESS_TOKEN_GRID_ID,
diff --git a/openbis_ng_ui/src/js/components/common/grid/GridController.js b/openbis_ng_ui/src/js/components/common/grid/GridController.js
index 6148ee82bcfce5239ed14e3a22d6bd40704c54f9..84ab5683d93bf122ea2af4941d9b36f573a58b49 100644
--- a/openbis_ng_ui/src/js/components/common/grid/GridController.js
+++ b/openbis_ng_ui/src/js/components/common/grid/GridController.js
@@ -1034,7 +1034,19 @@ export default class GridController {
   }
 
   async handleExportTSV(exportable) {
-    const { exportOptions } = this.context.getState()
+    const _this = this
+    const state = this.context.getState()
+    const props = this.context.getProps()
+
+    const { onExportTSV } = props
+    const { exportOptions } = state
+
+    if (!onExportTSV) {
+      console.error(
+        'Missing onExportTSV callback function for grid with id: ' + props.id
+      )
+      return
+    }
 
     function _stringToUtf16ByteArray(str) {
       var bytes = []
@@ -1132,54 +1144,63 @@ export default class GridController {
       )
     }
 
-    const state = this.context.getState()
-    const props = this.context.getProps()
-
-    var data = []
-    var columns = []
+    async function _exportedFileDownload() {
+      var data = []
+      var columns = []
 
-    if (exportOptions.columns === GridExportOptions.ALL_COLUMNS) {
-      columns = this.getAllColumns()
-    } else if (exportOptions.columns === GridExportOptions.VISIBLE_COLUMNS) {
-      columns = this.getVisibleColumns()
-    } else {
-      throw Error('Unsupported columns option: ' + exportOptions.columns)
-    }
-
-    columns = columns.filter(column => column.exportable)
-
-    if (exportOptions.rows === GridExportOptions.ALL_PAGES) {
-      if (state.local) {
-        data = state.sortedRows
-      } else if (props.loadRows) {
-        const loadedResult = await props.loadRows({
-          filters: state.filters,
-          globalFilter: state.globalFilter,
-          page: 0,
-          pageSize: 1000000,
-          sortings: state.sortings
-        })
-        data = loadedResult.rows
+      if (exportOptions.columns === GridExportOptions.ALL_COLUMNS) {
+        columns = _this.getAllColumns()
+      } else if (exportOptions.columns === GridExportOptions.VISIBLE_COLUMNS) {
+        columns = _this.getVisibleColumns()
+      } else {
+        throw Error('Unsupported columns option: ' + exportOptions.columns)
       }
 
-      _exportColumnsFromData(data, columns)
-    } else if (exportOptions.rows === GridExportOptions.CURRENT_PAGE) {
-      data = state.rows
-      _exportColumnsFromData(data, columns)
-    } else if (exportOptions.rows === GridExportOptions.SELECTED_ROWS) {
-      data = Object.values(state.multiselectedRows).map(
-        selectedRow => selectedRow.data
-      )
-      _exportColumnsFromData(data, columns)
-    } else {
-      throw Error('Unsupported rows option: ' + exportOptions.columns)
+      columns = columns.filter(column => column.exportable)
+
+      if (exportOptions.rows === GridExportOptions.ALL_PAGES) {
+        if (state.local) {
+          data = state.sortedRows
+        } else if (props.loadRows) {
+          const loadedResult = await props.loadRows({
+            filters: state.filters,
+            globalFilter: state.globalFilter,
+            page: 0,
+            pageSize: 1000000,
+            sortings: state.sortings
+          })
+          data = loadedResult.rows
+        }
+        _exportColumnsFromData(data, columns)
+      } else if (exportOptions.rows === GridExportOptions.CURRENT_PAGE) {
+        data = state.rows
+        _exportColumnsFromData(data, columns)
+      } else if (exportOptions.rows === GridExportOptions.SELECTED_ROWS) {
+        data = Object.values(state.multiselectedRows).map(
+          selectedRow => selectedRow.data
+        )
+        _exportColumnsFromData(data, columns)
+      } else {
+        throw Error('Unsupported rows option: ' + exportOptions.columns)
+      }
     }
+
+    onExportTSV({
+      exportedFileDownload: _exportedFileDownload
+    })
   }
 
   async handleExportXLS(exportable) {
     const state = this.context.getState()
     const props = this.context.getProps()
 
+    if (!props.onExportXLS) {
+      console.error(
+        'Missing onExportXLS callback function for grid with id: ' + props.id
+      )
+      return
+    }
+
     let exportedRows = []
 
     if (state.exportOptions.rows === GridExportOptions.ALL_PAGES) {
diff --git a/openbis_ng_ui/src/js/components/common/grid/GridWithSettings.jsx b/openbis_ng_ui/src/js/components/common/grid/GridWithOpenbis.jsx
similarity index 68%
rename from openbis_ng_ui/src/js/components/common/grid/GridWithSettings.jsx
rename to openbis_ng_ui/src/js/components/common/grid/GridWithOpenbis.jsx
index f3c14b34dc6fd840df0930c19bfca2cf97f85662..ad7be2a10ed0c85daec149d17daa87cff039294f 100644
--- a/openbis_ng_ui/src/js/components/common/grid/GridWithSettings.jsx
+++ b/openbis_ng_ui/src/js/components/common/grid/GridWithOpenbis.jsx
@@ -6,29 +6,44 @@ import openbis from '@src/js/services/openbis.js'
 import ids from '@src/js/common/consts/ids.js'
 import logger from '@src/js/common/logger.js'
 
-export default class GridWithSettings extends React.PureComponent {
+export default class GridWithOpenbis extends React.PureComponent {
   constructor(props) {
     super(props)
     autoBind(this)
 
-    if (!props.id) {
-      throw new Error('Grid id cannot be empty!')
+    if (props.id === undefined || props.id === null) {
+      throw new Error('Grid id cannot be null or undefined!')
+    }
+
+    if (props.settingsId === undefined) {
+      throw new Error('Grid settingsId cannot be undefined!')
     }
   }
 
   render() {
-    logger.log(logger.DEBUG, 'GridWithSettings.render')
+    logger.log(logger.DEBUG, 'GridWithOpenbis.render')
     return (
       <Grid
         {...this.props}
         loadSettings={this.loadSettings}
         onSettingsChange={this.onSettingsChange}
         onExportXLS={this.onExportXLS}
+        onExportTSV={this.onExportTSV}
       />
     )
   }
 
+  getSettingsId() {
+    return this.props.settingsId
+  }
+
   async loadSettings() {
+    const settingsId = this.getSettingsId()
+
+    if (!settingsId) {
+      return null
+    }
+
     const id = new openbis.Me()
     const fo = new openbis.PersonFetchOptions()
     fo.withWebAppSettings(ids.WEB_APP_ID).withAllSettings()
@@ -37,7 +52,7 @@ export default class GridWithSettings extends React.PureComponent {
       const person = map[id]
       const webAppSettings = person.webAppSettings[ids.WEB_APP_ID]
       if (webAppSettings && webAppSettings.settings) {
-        let gridSettings = webAppSettings.settings[this.props.id]
+        let gridSettings = webAppSettings.settings[settingsId]
         if (gridSettings) {
           let settings = JSON.parse(gridSettings.value)
           if (settings) {
@@ -51,8 +66,14 @@ export default class GridWithSettings extends React.PureComponent {
   }
 
   async onSettingsChange(settings) {
+    const settingsId = this.getSettingsId()
+
+    if (!settingsId) {
+      return
+    }
+
     const gridSettings = new openbis.WebAppSettingCreation()
-    gridSettings.setName(this.props.id)
+    gridSettings.setName(settingsId)
     gridSettings.setValue(JSON.stringify(settings))
 
     const update = new openbis.PersonUpdate()
@@ -84,12 +105,18 @@ export default class GridWithSettings extends React.PureComponent {
       const result = await openbis.executeService(serviceId, serviceOptions)
 
       if (result.status === 'OK') {
-        let downloadUrl =
+        const filePath = result.result
+        const fileName = filePath.substring(filePath.lastIndexOf('/') + 1)
+        const fileUrl =
           '/openbis/download/?sessionID=' +
           encodeURIComponent(AppController.getInstance().getSessionToken()) +
           '&filePath=' +
-          encodeURIComponent(result.result)
-        window.open(downloadUrl, '_blank').focus()
+          encodeURIComponent(filePath)
+
+        const link = document.createElement('a')
+        link.href = fileUrl
+        link.download = fileName
+        link.click()
       } else if (result.status === 'error') {
         AppController.getInstance().errorChange(result.message)
       } else {
@@ -101,4 +128,15 @@ export default class GridWithSettings extends React.PureComponent {
       AppController.getInstance().loadingChange(false)
     }
   }
+
+  async onExportTSV({ exportedFileDownload }) {
+    try {
+      AppController.getInstance().loadingChange(true)
+      await exportedFileDownload()
+    } catch (e) {
+      AppController.getInstance().errorChange(JSON.stringify(e.message))
+    } finally {
+      AppController.getInstance().loadingChange(false)
+    }
+  }
 }
diff --git a/openbis_ng_ui/src/js/components/tools/common/HistoryGrid.jsx b/openbis_ng_ui/src/js/components/tools/common/HistoryGrid.jsx
index 93a7ed950855f540f01081ee62efb4a4bc4970ea..938bf7d31c9433d6c6b313688908ec8eba6341aa 100644
--- a/openbis_ng_ui/src/js/components/tools/common/HistoryGrid.jsx
+++ b/openbis_ng_ui/src/js/components/tools/common/HistoryGrid.jsx
@@ -1,7 +1,7 @@
 import _ from 'lodash'
 import React from 'react'
 import autoBind from 'auto-bind'
-import GridWithSettings from '@src/js/components/common/grid/GridWithSettings.jsx'
+import GridWithOpenbis from '@src/js/components/common/grid/GridWithOpenbis.jsx'
 import GridExportOptions from '@src/js/components/common/grid/GridExportOptions.js'
 import GridFilterOptions from '@src/js/components/common/grid/GridFilterOptions.js'
 import UserLink from '@src/js/components/common/link/UserLink.jsx'
@@ -118,9 +118,12 @@ class HistoryGrid extends React.PureComponent {
   render() {
     logger.log(logger.DEBUG, 'HistoryGrid.render')
 
+    const id = this.getId()
+
     return (
-      <GridWithSettings
-        id={this.getId()}
+      <GridWithOpenbis
+        id={id}
+        settingsId={id}
         filterModes={[GridFilterOptions.COLUMN_FILTERS]}
         header={this.getHeader()}
         columns={[
diff --git a/openbis_ng_ui/src/js/components/tools/common/PersonalAccessTokensGrid.jsx b/openbis_ng_ui/src/js/components/tools/common/PersonalAccessTokensGrid.jsx
index 1ff579e985b4d5492e048a852a38f2eae7a05257..6591ac446bf8d1414388d7ad04cd439854168eed 100644
--- a/openbis_ng_ui/src/js/components/tools/common/PersonalAccessTokensGrid.jsx
+++ b/openbis_ng_ui/src/js/components/tools/common/PersonalAccessTokensGrid.jsx
@@ -1,6 +1,6 @@
 import _ from 'lodash'
 import React from 'react'
-import GridWithSettings from '@src/js/components/common/grid/GridWithSettings.jsx'
+import GridWithOpenbis from '@src/js/components/common/grid/GridWithOpenbis.jsx'
 import GridExportOptions from '@src/js/components/common/grid/GridExportOptions.js'
 import DateRangeField from '@src/js/components/common/form/DateRangeField.jsx'
 import SelectField from '@src/js/components/common/form/SelectField.jsx'
@@ -26,9 +26,12 @@ class PersonalAccessTokensGrid extends React.PureComponent {
     const { rows, selectedRowId, onSelectedRowChange, controllerRef } =
       this.props
 
+    const id = ids.PERSONAL_ACCESS_TOKEN_GRID_ID
+
     return (
-      <GridWithSettings
-        id={ids.PERSONAL_ACCESS_TOKEN_GRID_ID}
+      <GridWithOpenbis
+        id={id}
+        settingsId={id}
         controllerRef={controllerRef}
         header={messages.get(messages.PERSONAL_ACCESS_TOKENS)}
         columns={[
diff --git a/openbis_ng_ui/src/js/components/tools/common/PluginsGrid.jsx b/openbis_ng_ui/src/js/components/tools/common/PluginsGrid.jsx
index 8c4f4f1a826ffd5c2715aa14e1c2352333ef3b8c..823b9a90eb018778a1fd1b356b0ef95267423fb3 100644
--- a/openbis_ng_ui/src/js/components/tools/common/PluginsGrid.jsx
+++ b/openbis_ng_ui/src/js/components/tools/common/PluginsGrid.jsx
@@ -1,5 +1,5 @@
 import React from 'react'
-import GridWithSettings from '@src/js/components/common/grid/GridWithSettings.jsx'
+import GridWithOpenbis from '@src/js/components/common/grid/GridWithOpenbis.jsx'
 import GridExportOptions from '@src/js/components/common/grid/GridExportOptions.js'
 import PluginLink from '@src/js/components/common/link/PluginLink.jsx'
 import UserLink from '@src/js/components/common/link/UserLink.jsx'
@@ -22,8 +22,9 @@ class PluginsGrid extends React.PureComponent {
     } = this.props
 
     return (
-      <GridWithSettings
+      <GridWithOpenbis
         id={id}
+        settingsId={id}
         controllerRef={controllerRef}
         header={this.getHeader()}
         sort='name'
diff --git a/openbis_ng_ui/src/js/components/tools/common/QueriesGrid.jsx b/openbis_ng_ui/src/js/components/tools/common/QueriesGrid.jsx
index 7537f53b408d36808c0af1cbe5d7bcbe05e996fe..c280fea6ebb05f56ed65d51b6a7d70e88b9a5d02 100644
--- a/openbis_ng_ui/src/js/components/tools/common/QueriesGrid.jsx
+++ b/openbis_ng_ui/src/js/components/tools/common/QueriesGrid.jsx
@@ -1,5 +1,5 @@
 import React from 'react'
-import GridWithSettings from '@src/js/components/common/grid/GridWithSettings.jsx'
+import GridWithOpenbis from '@src/js/components/common/grid/GridWithOpenbis.jsx'
 import GridExportOptions from '@src/js/components/common/grid/GridExportOptions.js'
 import QueryLink from '@src/js/components/common/link/QueryLink.jsx'
 import UserLink from '@src/js/components/common/link/UserLink.jsx'
@@ -15,8 +15,9 @@ class QueriesGrid extends React.PureComponent {
       this.props
 
     return (
-      <GridWithSettings
+      <GridWithOpenbis
         id={id}
+        settingsId={id}
         controllerRef={controllerRef}
         header={messages.get(messages.QUERIES)}
         sort='name'
diff --git a/openbis_ng_ui/src/js/components/tools/form/query/QueryFormExecuteResultsGrid.jsx b/openbis_ng_ui/src/js/components/tools/form/query/QueryFormExecuteResultsGrid.jsx
index f2b4911da665acbbe7c5a48f136817f27dd7b96d..a594b3ea8b4e4205a6ec096329d1336448970b0e 100644
--- a/openbis_ng_ui/src/js/components/tools/form/query/QueryFormExecuteResultsGrid.jsx
+++ b/openbis_ng_ui/src/js/components/tools/form/query/QueryFormExecuteResultsGrid.jsx
@@ -1,7 +1,8 @@
 import React from 'react'
 import { withStyles } from '@material-ui/core/styles'
-import Grid from '@src/js/components/common/grid/Grid.jsx'
+import GridWithOpenbis from '@src/js/components/common/grid/GridWithOpenbis.jsx'
 import GridExportOptions from '@src/js/components/common/grid/GridExportOptions.js'
+import ids from '@src/js/common/consts/ids.js'
 import logger from '@src/js/common/logger.js'
 
 const styles = () => ({})
@@ -13,7 +14,9 @@ class QueryFormExecuteResultsGrid extends React.PureComponent {
     const { tableModel } = this.props
 
     return (
-      <Grid
+      <GridWithOpenbis
+        id={ids.QUERY_RESULTS_GRID_ID}
+        settingsId={null}
         columns={this.getColumns(tableModel)}
         rows={this.getRows(tableModel)}
         exportable={{
diff --git a/openbis_ng_ui/src/js/components/types/common/EntityTypesGrid.jsx b/openbis_ng_ui/src/js/components/types/common/EntityTypesGrid.jsx
index 1a0003e327cd103bc0da3adbf86db99281779ea4..0e4e388db2c307ed4f58912d6af2687f7c77f969 100644
--- a/openbis_ng_ui/src/js/components/types/common/EntityTypesGrid.jsx
+++ b/openbis_ng_ui/src/js/components/types/common/EntityTypesGrid.jsx
@@ -1,5 +1,5 @@
 import React from 'react'
-import GridWithSettings from '@src/js/components/common/grid/GridWithSettings.jsx'
+import GridWithOpenbis from '@src/js/components/common/grid/GridWithOpenbis.jsx'
 import EntityTypeLink from '@src/js/components/common/link/EntityTypeLink.jsx'
 import PluginLink from '@src/js/components/common/link/PluginLink.jsx'
 import openbis from '@src/js/services/openbis.js'
@@ -20,8 +20,9 @@ class EntityTypesGrid extends React.PureComponent {
     } = this.props
 
     return (
-      <GridWithSettings
+      <GridWithOpenbis
         id={id}
+        settingsId={id}
         controllerRef={controllerRef}
         header={this.getHeader()}
         columns={this.getColumns()}
diff --git a/openbis_ng_ui/src/js/components/types/common/PropertyTypesGrid.jsx b/openbis_ng_ui/src/js/components/types/common/PropertyTypesGrid.jsx
index decee67ed9cfacfa8c0e3903921ee2db232e0cb7..9275a57b15e7a5cd3f6c97415553fee255b19db9 100644
--- a/openbis_ng_ui/src/js/components/types/common/PropertyTypesGrid.jsx
+++ b/openbis_ng_ui/src/js/components/types/common/PropertyTypesGrid.jsx
@@ -1,5 +1,5 @@
 import React from 'react'
-import GridWithSettings from '@src/js/components/common/grid/GridWithSettings.jsx'
+import GridWithOpenbis from '@src/js/components/common/grid/GridWithOpenbis.jsx'
 import GridExportOptions from '@src/js/components/common/grid/GridExportOptions.js'
 import EntityTypeLink from '@src/js/components/common/link/EntityTypeLink.jsx'
 import VocabularyTypeLink from '@src/js/components/common/link/VocabularyTypeLink.jsx'
@@ -17,8 +17,9 @@ class PropertyTypesGrid extends React.PureComponent {
       this.props
 
     return (
-      <GridWithSettings
+      <GridWithOpenbis
         id={id}
+        settingsId={id}
         controllerRef={controllerRef}
         header={messages.get(messages.PROPERTY_TYPES)}
         columns={[
diff --git a/openbis_ng_ui/src/js/components/types/common/VocabularyTypesGrid.jsx b/openbis_ng_ui/src/js/components/types/common/VocabularyTypesGrid.jsx
index 7e73c4502bea1caedbe5a19ce529d781fb82477b..aee8093b071c9ec19b67074f9c6a9d7667fd988c 100644
--- a/openbis_ng_ui/src/js/components/types/common/VocabularyTypesGrid.jsx
+++ b/openbis_ng_ui/src/js/components/types/common/VocabularyTypesGrid.jsx
@@ -1,5 +1,5 @@
 import React from 'react'
-import GridWithSettings from '@src/js/components/common/grid/GridWithSettings.jsx'
+import GridWithOpenbis from '@src/js/components/common/grid/GridWithOpenbis.jsx'
 import GridExportOptions from '@src/js/components/common/grid/GridExportOptions.js'
 import VocabularyTypeLink from '@src/js/components/common/link/VocabularyTypeLink.jsx'
 import messages from '@src/js/common/messages.js'
@@ -13,8 +13,9 @@ class VocabularyTypesGrid extends React.PureComponent {
       this.props
 
     return (
-      <GridWithSettings
+      <GridWithOpenbis
         id={id}
+        settingsId={id}
         controllerRef={controllerRef}
         header={messages.get(messages.VOCABULARY_TYPES)}
         columns={[
diff --git a/openbis_ng_ui/src/js/components/types/form/vocabularytype/VocabularyTypeForm.jsx b/openbis_ng_ui/src/js/components/types/form/vocabularytype/VocabularyTypeForm.jsx
index 64b0c83ad50adf6b936cf39a1e62bfb6d20e0cd8..cf03f4c502109ce053efad2c36042bb0ae31762d 100644
--- a/openbis_ng_ui/src/js/components/types/form/vocabularytype/VocabularyTypeForm.jsx
+++ b/openbis_ng_ui/src/js/components/types/form/vocabularytype/VocabularyTypeForm.jsx
@@ -2,7 +2,7 @@ import React from 'react'
 import autoBind from 'auto-bind'
 import ComponentContext from '@src/js/components/common/ComponentContext.js'
 import PageWithTwoPanels from '@src/js/components/common/page/PageWithTwoPanels.jsx'
-import GridWithSettings from '@src/js/components/common/grid/GridWithSettings.jsx'
+import GridWithOpenbis from '@src/js/components/common/grid/GridWithOpenbis.jsx'
 import GridExportOptions from '@src/js/components/common/grid/GridExportOptions.js'
 import GridContainer from '@src/js/components/common/grid/GridContainer.jsx'
 import VocabularyTypeFormSelectionType from '@src/js/components/types/form/vocabularytype/VocabularyTypeFormSelectionType.js'
@@ -99,10 +99,13 @@ class VocabularyTypeForm extends React.PureComponent {
   renderMainPanel() {
     const { terms, selection } = this.state
 
+    const id = ids.VOCABULARY_TERMS_GRID_ID
+
     return (
       <GridContainer onClick={this.handleClickContainer}>
-        <GridWithSettings
-          id={ids.VOCABULARY_TERMS_GRID_ID}
+        <GridWithOpenbis
+          id={id}
+          settingsId={id}
           controllerRef={this.handleGridControllerRef}
           header={messages.get(messages.TERMS)}
           columns={columns}
diff --git a/openbis_ng_ui/src/js/components/users/common/RolesGrid.jsx b/openbis_ng_ui/src/js/components/users/common/RolesGrid.jsx
index 74b613ad15964dde88b334710cac94dd0d49ff0a..9b5858e162f72b8a8ac347b820ea1ba01f335199 100644
--- a/openbis_ng_ui/src/js/components/users/common/RolesGrid.jsx
+++ b/openbis_ng_ui/src/js/components/users/common/RolesGrid.jsx
@@ -2,7 +2,7 @@ import _ from 'lodash'
 import React from 'react'
 import autoBind from 'auto-bind'
 import { withStyles } from '@material-ui/core/styles'
-import GridWithSettings from '@src/js/components/common/grid/GridWithSettings.jsx'
+import GridWithOpenbis from '@src/js/components/common/grid/GridWithOpenbis.jsx'
 import GridExportOptions from '@src/js/components/common/grid/GridExportOptions.js'
 import UserLink from '@src/js/components/common/link/UserLink.jsx'
 import UserGroupLink from '@src/js/components/common/link/UserGroupLink.jsx'
@@ -50,8 +50,9 @@ class RolesGrid extends React.PureComponent {
     )
 
     return (
-      <GridWithSettings
+      <GridWithOpenbis
         id={id}
+        settingsId={id}
         controllerRef={controllerRef}
         header={this.getHeader()}
         columns={columns}
diff --git a/openbis_ng_ui/src/js/components/users/common/UserGroupsGrid.jsx b/openbis_ng_ui/src/js/components/users/common/UserGroupsGrid.jsx
index dae251ed2fc38829f144b3ccffafc0b3a392365f..3420e7b6d6f44023d6c76032f4665e1be212fc72 100644
--- a/openbis_ng_ui/src/js/components/users/common/UserGroupsGrid.jsx
+++ b/openbis_ng_ui/src/js/components/users/common/UserGroupsGrid.jsx
@@ -1,5 +1,5 @@
 import React from 'react'
-import GridWithSettings from '@src/js/components/common/grid/GridWithSettings.jsx'
+import GridWithOpenbis from '@src/js/components/common/grid/GridWithOpenbis.jsx'
 import GridExportOptions from '@src/js/components/common/grid/GridExportOptions.js'
 import UserGroupLink from '@src/js/components/common/link/UserGroupLink.jsx'
 import messages from '@src/js/common/messages.js'
@@ -13,8 +13,9 @@ export default class GroupsGrid extends React.PureComponent {
       this.props
 
     return (
-      <GridWithSettings
+      <GridWithOpenbis
         id={id}
+        settingsId={id}
         controllerRef={controllerRef}
         header={messages.get(messages.GROUPS)}
         sort='code'
diff --git a/openbis_ng_ui/src/js/components/users/common/UsersGrid.jsx b/openbis_ng_ui/src/js/components/users/common/UsersGrid.jsx
index bc4fa36816b48d777b6d72ea82bd660905c753df..fc400039c7f571a613f81fa0dc252812aa3b36c7 100644
--- a/openbis_ng_ui/src/js/components/users/common/UsersGrid.jsx
+++ b/openbis_ng_ui/src/js/components/users/common/UsersGrid.jsx
@@ -2,7 +2,7 @@ import _ from 'lodash'
 import React from 'react'
 import autoBind from 'auto-bind'
 import { withStyles } from '@material-ui/core/styles'
-import GridWithSettings from '@src/js/components/common/grid/GridWithSettings.jsx'
+import GridWithOpenbis from '@src/js/components/common/grid/GridWithOpenbis.jsx'
 import GridExportOptions from '@src/js/components/common/grid/GridExportOptions.js'
 import UserLink from '@src/js/components/common/link/UserLink.jsx'
 import messages from '@src/js/common/messages.js'
@@ -23,8 +23,9 @@ class UsersGrid extends React.PureComponent {
       this.props
 
     return (
-      <GridWithSettings
+      <GridWithOpenbis
         id={id}
+        settingsId={id}
         controllerRef={controllerRef}
         header={messages.get(messages.USERS)}
         sort='userId'
diff --git a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/DataGrid/DataGridController.js b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/DataGrid/DataGridController.js
index 76204d03172cff1e2c48ac76b2a79c5bcaf488ae..a2a5719556de884856f836796359bde24fdffd50 100644
--- a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/DataGrid/DataGridController.js
+++ b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/DataGrid/DataGridController.js
@@ -76,6 +76,7 @@ function DataGridController(
                     onRowClick: rowClickEventHandler,
                     exportable: exportable,
                     onExportXLS: _this._onExportXLS,
+                    onExportTSV: _this._onExportTSV,
                     selectable: false,
                     multiselectable: multiselectable,
                     actions: _this._actions(extraOptions),
@@ -294,19 +295,39 @@ function DataGridController(
 			Util.unblockUI()
 
 			if(result.result.status === "OK"){
-				let downloadUrl = "/openbis/download/?sessionID=" + encodeURIComponent(mainController.serverFacade.getSession()) + "&filePath=" + encodeURIComponent(result.result.result)
-				window.open(downloadUrl, '_blank').focus();
+				const filePath = result.result.result
+				const fileName = filePath.substring(filePath.lastIndexOf('/') + 1)
+				const fileUrl =
+				  '/openbis/download/?sessionID=' +
+				  encodeURIComponent(mainController.serverFacade.getSession()) +
+				  '&filePath=' +
+				  encodeURIComponent(filePath)
+
+				const link = document.createElement('a')
+				link.href = fileUrl
+				link.download = fileName
+				link.click()
 			}else if(result.result.status === "error"){
 				Util.showError(result.result.message)
 			}else{
-				Util.showError("Export failed: " + JSON.stringify(result))
+				Util.showError(JSON.stringify(result))
 			}
 		}, "xls-export", function(error) {
 			Util.unblockUI()
-			Util.showError("Export failed: " + JSON.stringify(error));
+			Util.showError(JSON.stringify(error));
 		}, true);
 	}
 
+	this._onExportTSV = function (parameters) {
+		Util.blockUI()
+		parameters.exportedFileDownload().then(function(){
+			Util.unblockUI()
+		}, function(error){
+			Util.unblockUI()
+			Util.showError(JSON.stringify(error))
+		})
+	}
+
     this.refresh = function () {
         if (_this.controller) {
             _this.controller.load()