diff --git a/openbis_ng_ui/src/js/common/messages.js b/openbis_ng_ui/src/js/common/messages.js
index de419a8b908e56121f447d543511a6bf92acd910..d0e5f764b2d83b44c6ab4dd0a70a407319693cce 100644
--- a/openbis_ng_ui/src/js/common/messages.js
+++ b/openbis_ng_ui/src/js/common/messages.js
@@ -89,6 +89,7 @@ const keys = {
   EVALUATE: 'EVALUATE',
   EVENT_TYPE: 'EVENT_TYPE',
   EXECUTE: 'EXECUTE',
+  EXPAND_ALL: 'EXPAND_ALL',
   EXPORT: 'EXPORT',
   EXPORT_PLAIN_TEXT_WARNING: 'EXPORT_PLAIN_TEXT_WARNING',
   EXPORTS: 'EXPORTS',
@@ -382,6 +383,7 @@ const messages_en = {
   [keys.EVALUATE]: 'Evaluate',
   [keys.EVENT_TYPE]: 'Event Type',
   [keys.EXECUTE]: 'Execute',
+  [keys.EXPAND_ALL]: 'Expand all',
   [keys.EXPORT]: 'Export',
   [keys.EXPORT_PLAIN_TEXT_WARNING]: 'Do not use this file for Batch Update! This file does not contain rich text formatting. If used for Batch Update, all rich text formatting in the updated entries will be lost!',
   [keys.EXPORTS]: 'Exports',
diff --git a/openbis_ng_ui/src/js/components/common/browser/Browser.jsx b/openbis_ng_ui/src/js/components/common/browser/Browser.jsx
index a99b01023fbeb0b890e417313b4868ee925ecaa6..a25d370950693163cb4e247a3ebe9940632a893f 100644
--- a/openbis_ng_ui/src/js/components/common/browser/Browser.jsx
+++ b/openbis_ng_ui/src/js/components/common/browser/Browser.jsx
@@ -7,7 +7,7 @@ import FilterField from '@src/js/components/common/form/FilterField.jsx'
 import BrowserRoot from '@src/js/components/common/browser/BrowserRoot.jsx'
 import BrowserNode from '@src/js/components/common/browser/BrowserNode.jsx'
 import BrowserNodeAutoShowSelected from '@src/js/components/common/browser/BrowserNodeAutoShowSelected.jsx'
-import BrowserNodeCollapseAll from '@src/js/components/common/browser/BrowserNodeCollapseAll.jsx'
+import BrowserNodeCollapseExpandAll from '@src/js/components/common/browser/BrowserNodeCollapseExpandAll.jsx'
 import logger from '@src/js/common/logger.js'
 
 const styles = theme => ({
@@ -136,6 +136,9 @@ class Browser extends React.PureComponent {
     const { controller } = this
     const { classes } = this.props
 
+    const node = controller.getNodeSetAsRoot() ||
+      controller.getRoot() || { canHaveChildren: true }
+
     return (
       <FilterField
         filter={controller.getFilter() || ''}
@@ -148,12 +151,11 @@ class Browser extends React.PureComponent {
               value={controller.isAutoShowSelectedObject()}
               onClick={controller.changeAutoShowSelectedObject}
             />
-            <BrowserNodeCollapseAll
-              node={
-                controller.getNodeSetAsRoot() ||
-                controller.getRoot() || { canHaveChildren: true }
-              }
-              onClick={controller.collapseAllNodes}
+            <BrowserNodeCollapseExpandAll
+              node={node}
+              expand={controller.isExpandAllNodesAvailable(node.id)}
+              onCollapseAll={controller.collapseAllNodes}
+              onExpandAll={controller.expandAllNodes}
             />
           </div>
         }
diff --git a/openbis_ng_ui/src/js/components/common/browser/BrowserController.js b/openbis_ng_ui/src/js/components/common/browser/BrowserController.js
index 6ded0747e1ab10f58b89c21073d9ff1c29954866..dd7e2699c53231168c881ffeb8169c3f9cea56d7 100644
--- a/openbis_ng_ui/src/js/components/common/browser/BrowserController.js
+++ b/openbis_ng_ui/src/js/components/common/browser/BrowserController.js
@@ -231,6 +231,14 @@ export default class BrowserController {
     await this._getTreeController().collapseAllNodes(nodeId)
   }
 
+  async expandAllNodes(nodeId) {
+    await this._getTreeController().expandAllNodes(nodeId)
+  }
+
+  isExpandAllNodesAvailable(nodeId) {
+    return this._getTreeController().isExpandAllNodesAvailable(nodeId)
+  }
+
   async setNodeAsRoot(node) {
     let nodeSetAsRoot = null
 
diff --git a/openbis_ng_ui/src/js/components/common/browser/BrowserNode.jsx b/openbis_ng_ui/src/js/components/common/browser/BrowserNode.jsx
index a505c24fdcf656af21a5b2346ff073061a0c2a87..d3c149e17e2480f27d758fbed0231bdaa84b3b22 100644
--- a/openbis_ng_ui/src/js/components/common/browser/BrowserNode.jsx
+++ b/openbis_ng_ui/src/js/components/common/browser/BrowserNode.jsx
@@ -14,7 +14,7 @@ import ExpandMoreIcon from '@material-ui/icons/ExpandMore'
 import BrowserNode from '@src/js/components/common/browser/BrowserNode.jsx'
 import BrowserNodeSetAsRoot from '@src/js/components/common/browser/BrowserNodeSetAsRoot.jsx'
 import BrowserNodeSortings from '@src/js/components/common/browser/BrowserNodeSortings.jsx'
-import BrowserNodeCollapseAll from '@src/js/components/common/browser/BrowserNodeCollapseAll.jsx'
+import BrowserNodeCollapseExpandAll from '@src/js/components/common/browser/BrowserNodeCollapseExpandAll.jsx'
 import Message from '@src/js/components/common/form/Message.jsx'
 import messages from '@src/js/common/messages.js'
 import util from '@src/js/common/util.js'
@@ -105,6 +105,11 @@ class BrowserNodeClass extends React.PureComponent {
     controller.collapseAllNodes(nodeId)
   }
 
+  handleExpandAll(nodeId) {
+    const { controller } = this.props
+    controller.expandAllNodes(nodeId)
+  }
+
   handleSetAsRoot(nodeId) {
     const { controller } = this.props
     controller.setNodeAsRoot(nodeId)
@@ -239,7 +244,7 @@ class BrowserNodeClass extends React.PureComponent {
   }
 
   renderOptions(node) {
-    const { classes } = this.props
+    const { controller, classes } = this.props
 
     return (
       <div className={classes.options}>
@@ -249,7 +254,12 @@ class BrowserNodeClass extends React.PureComponent {
           onChange={this.handleSortingChange}
           onClearCustom={this.handleCustomSortingClear}
         />
-        <BrowserNodeCollapseAll node={node} onClick={this.handleCollapseAll} />
+        <BrowserNodeCollapseExpandAll
+          node={node}
+          expand={controller.isExpandAllNodesAvailable(node.id)}
+          onCollapseAll={this.handleCollapseAll}
+          onExpandAll={this.handleExpandAll}
+        />
       </div>
     )
   }
diff --git a/openbis_ng_ui/src/js/components/common/browser/BrowserNodeCollapseAll.jsx b/openbis_ng_ui/src/js/components/common/browser/BrowserNodeCollapseExpandAll.jsx
similarity index 61%
rename from openbis_ng_ui/src/js/components/common/browser/BrowserNodeCollapseAll.jsx
rename to openbis_ng_ui/src/js/components/common/browser/BrowserNodeCollapseExpandAll.jsx
index cd97d36e80b4e9ba8b037196018dc8d84c24294c..def224e7e859fc4b2139f3dbebb0d62cdf0840ff 100644
--- a/openbis_ng_ui/src/js/components/common/browser/BrowserNodeCollapseAll.jsx
+++ b/openbis_ng_ui/src/js/components/common/browser/BrowserNodeCollapseExpandAll.jsx
@@ -4,9 +4,9 @@ import { withStyles } from '@material-ui/core/styles'
 import Tooltip from '@src/js/components/common/form/Tooltip.jsx'
 import IconButton from '@material-ui/core/IconButton'
 import UnfoldLessIcon from '@material-ui/icons/UnfoldLess'
+import UnfoldMoreIcon from '@material-ui/icons/UnfoldMore'
 import messages from '@src/js/common/messages.js'
 import logger from '@src/js/common/logger.js'
-import id from 'date-fns/esm/locale/id/index.js'
 
 const styles = theme => ({
   container: {
@@ -18,7 +18,7 @@ const styles = theme => ({
   }
 })
 
-class BrowserNodeCollapseAll extends React.PureComponent {
+class BrowserNodeCollapseExpandAll extends React.PureComponent {
   constructor(props) {
     super(props)
     autoBind(this)
@@ -27,16 +27,20 @@ class BrowserNodeCollapseAll extends React.PureComponent {
   handleClick(event) {
     event.preventDefault()
     event.stopPropagation()
-    const { node } = this.props
+    const { node, expand } = this.props
     if (node.id) {
-      this.props.onClick(node.id)
+      if (expand) {
+        this.props.onExpandAll(node.id)
+      } else {
+        this.props.onCollapseAll(node.id)
+      }
     }
   }
 
   render() {
     logger.log(logger.DEBUG, 'BrowserNodeCollapseAll.render')
 
-    const { node, classes } = this.props
+    const { node, expand, classes } = this.props
 
     if (!node || !node.canHaveChildren) {
       return null
@@ -44,13 +48,21 @@ class BrowserNodeCollapseAll extends React.PureComponent {
 
     return (
       <div className={classes.container}>
-        <Tooltip title={messages.get(messages.COLLAPSE_ALL)}>
+        <Tooltip
+          title={messages.get(
+            expand ? messages.EXPAND_ALL : messages.COLLAPSE_ALL
+          )}
+        >
           <IconButton
             size='small'
             onClick={this.handleClick}
             classes={{ root: classes.button }}
           >
-            <UnfoldLessIcon fontSize='small' />
+            {expand ? (
+              <UnfoldMoreIcon fontSize='small' />
+            ) : (
+              <UnfoldLessIcon fontSize='small' />
+            )}
           </IconButton>
         </Tooltip>
       </div>
@@ -58,4 +70,4 @@ class BrowserNodeCollapseAll extends React.PureComponent {
   }
 }
 
-export default withStyles(styles)(BrowserNodeCollapseAll)
+export default withStyles(styles)(BrowserNodeCollapseExpandAll)
diff --git a/openbis_ng_ui/src/js/components/common/browser/BrowserTreeController.js b/openbis_ng_ui/src/js/components/common/browser/BrowserTreeController.js
index dd3cc51ac30f718918229af3268c25e7f670239e..f967ef519071c68c205fb23b687a9dfccde46489 100644
--- a/openbis_ng_ui/src/js/components/common/browser/BrowserTreeController.js
+++ b/openbis_ng_ui/src/js/components/common/browser/BrowserTreeController.js
@@ -26,6 +26,7 @@ export default class BrowserTreeController {
       nodes: {},
       selectedObject: null,
       expandedIds: {},
+      expandAllIds: {},
       sortingIds: {}
     })
     this.context = context
@@ -48,6 +49,7 @@ export default class BrowserTreeController {
       nodes: {},
       selectedObject: state.selectedObject,
       expandedIds: {},
+      expandAllIds: {},
       sortingIds: {},
       customSortings: {}
     }
@@ -588,6 +590,19 @@ export default class BrowserTreeController {
         this._doCollapseNode(newState, node.id, false)
       }
 
+      const idsToExpandAll = _.difference(
+        Object.keys(state.expandedIds),
+        Object.keys(newState.expandedIds)
+      )
+
+      if (!_.isEmpty(idsToExpandAll)) {
+        const newExpandAllIds = {
+          ...newState.expandAllIds,
+          [nodeId]: idsToExpandAll
+        }
+        newState.expandAllIds = newExpandAllIds
+      }
+
       await this.context.setState(newState)
       this._saveSettings()
     }
@@ -625,6 +640,29 @@ export default class BrowserTreeController {
     }
   }
 
+  async expandAllNodes(nodeId) {
+    const state = this.context.getState()
+    const idsToExpand = state.expandAllIds[nodeId]
+
+    if (!_.isEmpty(idsToExpand)) {
+      const newState = { ...state }
+      newState.expandAllIds = { ...state.expandAllIds }
+
+      idsToExpand.forEach(idToExpand => {
+        this._doExpandNode(newState, idToExpand)
+      })
+      delete newState.expandAllIds[nodeId]
+
+      this.context.setState(newState)
+    }
+  }
+
+  isExpandAllNodesAvailable(nodeId) {
+    const state = this.context.getState()
+    const idsToExpand = state.expandAllIds[nodeId]
+    return !_.isEmpty(idsToExpand)
+  }
+
   async selectObject(nodeObject) {
     const state = this.context.getState()