diff --git a/openbis_ng_ui/src/js/common/consts/ids.js b/openbis_ng_ui/src/js/common/consts/ids.js
index e67fb80b8c1f3e46cc19e623854aa50f873294bb..5a7846afc1fcc11bccce0fb49bf44223e9d3349b 100644
--- a/openbis_ng_ui/src/js/common/consts/ids.js
+++ b/openbis_ng_ui/src/js/common/consts/ids.js
@@ -11,7 +11,8 @@ const USER_ROLES_GRID_ID = 'user_roles_grid'
 const USER_GROUP_USERS_GRID_ID = 'user_group_users_grid'
 const USER_GROUP_ROLES_GRID_ID = 'user_group_roles_grid'
 const VOCABULARY_TERMS_GRID_ID = 'vocabulary_terms_grid'
-const PLUGINS_GRID_ID = 'plugins_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'
 
 export default {
@@ -28,6 +29,7 @@ export default {
   USER_GROUP_USERS_GRID_ID,
   USER_GROUP_ROLES_GRID_ID,
   VOCABULARY_TERMS_GRID_ID,
-  PLUGINS_GRID_ID,
+  DYNAMIC_PROPERTY_PLUGINS_GRID_ID,
+  ENTITY_VALIDATION_PLUGINS_GRID_ID,
   QUERIES_GRID_ID
 }
diff --git a/openbis_ng_ui/src/js/common/consts/routes.js b/openbis_ng_ui/src/js/common/consts/routes.js
index fa46b47981a6c321b9bb83472ba1ea910798c2cc..cefa0431ff2fc7cd2be25e8c4692ae6363286ba5 100644
--- a/openbis_ng_ui/src/js/common/consts/routes.js
+++ b/openbis_ng_ui/src/js/common/consts/routes.js
@@ -172,6 +172,14 @@ const routes = {
     page: pages.TOOLS,
     type: objectTypes.DYNAMIC_PROPERTY_PLUGIN
   }),
+  DYNAMIC_PROPERTY_PLUGIN_OVERVIEW: new Route(
+    '/dynamic-property-plugin-overview',
+    {
+      page: pages.TOOLS,
+      type: objectTypes.OVERVIEW,
+      id: objectTypes.DYNAMIC_PROPERTY_PLUGIN
+    }
+  ),
   NEW_ENTITY_VALIDATION_PLUGIN: new Route('/new-entity-validation-plugin/:id', {
     page: pages.TOOLS,
     type: objectTypes.NEW_ENTITY_VALIDATION_PLUGIN
@@ -180,6 +188,14 @@ const routes = {
     page: pages.TOOLS,
     type: objectTypes.ENTITY_VALIDATION_PLUGIN
   }),
+  ENTITY_VALIDATION_PLUGIN_OVERVIEW: new Route(
+    '/entity-validation-plugin-overview',
+    {
+      page: pages.TOOLS,
+      type: objectTypes.OVERVIEW,
+      id: objectTypes.ENTITY_VALIDATION_PLUGIN
+    }
+  ),
   NEW_QUERY: new Route('/new-query/:id', {
     page: pages.TOOLS,
     type: objectTypes.NEW_QUERY
@@ -188,6 +204,11 @@ const routes = {
     page: pages.TOOLS,
     type: objectTypes.QUERY
   }),
+  QUERY_OVERVIEW: new Route('/query-overview', {
+    page: pages.TOOLS,
+    type: objectTypes.OVERVIEW,
+    id: objectTypes.QUERY
+  }),
   DEFAULT: new DefaultRoute()
 }
 
diff --git a/openbis_ng_ui/src/js/components/tools/Tools.jsx b/openbis_ng_ui/src/js/components/tools/Tools.jsx
index a94357004519db31f62b803c638bb6c3244411a3..39bf19687a88565dde375c98dc158f72772d49f0 100644
--- a/openbis_ng_ui/src/js/components/tools/Tools.jsx
+++ b/openbis_ng_ui/src/js/components/tools/Tools.jsx
@@ -50,27 +50,40 @@ class Tools extends React.Component {
     ) {
       return <QueryForm object={object} />
     } else if (object.type === objectType.SEARCH) {
-      return <ToolSearch objectId={object.id} />
+      return <ToolSearch searchText={object.id} />
+    } else if (object.type === objectType.OVERVIEW) {
+      return <ToolSearch objectType={object.id} />
     }
   }
 
   renderTab(tab) {
     const { object, changed } = tab
 
-    const prefixes = {
-      [objectType.DYNAMIC_PROPERTY_PLUGIN]: 'Dynamic Property Plugin: ',
-      [objectType.NEW_DYNAMIC_PROPERTY_PLUGIN]: 'New Dynamic Property Plugin ',
-      [objectType.ENTITY_VALIDATION_PLUGIN]: 'Entity Validation Plugin: ',
-      [objectType.NEW_ENTITY_VALIDATION_PLUGIN]:
-        'New Entity Validation Plugin ',
-      [objectType.QUERY]: 'Query: ',
-      [objectType.NEW_QUERY]: 'New Query ',
-      [objectType.SEARCH]: 'Search: '
+    let label = null
+
+    if (object.type === objectType.OVERVIEW) {
+      const labels = {
+        [objectType.DYNAMIC_PROPERTY_PLUGIN]: 'Dynamic Property Plugins',
+        [objectType.ENTITY_VALIDATION_PLUGIN]: 'Entity Validation Plugins',
+        [objectType.QUERY]: 'Queries'
+      }
+      label = labels[object.id]
+    } else {
+      const prefixes = {
+        [objectType.DYNAMIC_PROPERTY_PLUGIN]: 'Dynamic Property Plugin: ',
+        [objectType.NEW_DYNAMIC_PROPERTY_PLUGIN]:
+          'New Dynamic Property Plugin ',
+        [objectType.ENTITY_VALIDATION_PLUGIN]: 'Entity Validation Plugin: ',
+        [objectType.NEW_ENTITY_VALIDATION_PLUGIN]:
+          'New Entity Validation Plugin ',
+        [objectType.QUERY]: 'Query: ',
+        [objectType.NEW_QUERY]: 'New Query ',
+        [objectType.SEARCH]: 'Search: '
+      }
+      label = prefixes[object.type] + object.id
     }
 
-    return (
-      <ContentTab label={prefixes[object.type] + object.id} changed={changed} />
-    )
+    return <ContentTab label={label} changed={changed} />
   }
 }
 
diff --git a/openbis_ng_ui/src/js/components/tools/browser/ToolBrowserController.js b/openbis_ng_ui/src/js/components/tools/browser/ToolBrowserController.js
index 439e88f4adef2545b711a318860e060fc531ee1a..0da5138e3814a8164d4ba1ca2b2ba88aab49c1fe 100644
--- a/openbis_ng_ui/src/js/components/tools/browser/ToolBrowserController.js
+++ b/openbis_ng_ui/src/js/components/tools/browser/ToolBrowserController.js
@@ -74,6 +74,10 @@ export default class ToolBrowserController extends BrowserController {
         {
           id: 'dynamicPropertyPlugins',
           text: 'Dynamic Property Plugins',
+          object: {
+            type: objectType.OVERVIEW,
+            id: objectType.DYNAMIC_PROPERTY_PLUGIN
+          },
           children: dynamicPropertyPluginNodes,
           childrenType: objectType.NEW_DYNAMIC_PROPERTY_PLUGIN,
           canAdd: true
@@ -81,6 +85,10 @@ export default class ToolBrowserController extends BrowserController {
         {
           id: 'entityValidationPlugins',
           text: 'Entity Validation Plugins',
+          object: {
+            type: objectType.OVERVIEW,
+            id: objectType.ENTITY_VALIDATION_PLUGIN
+          },
           children: entityValidationPluginNodes,
           childrenType: objectType.NEW_ENTITY_VALIDATION_PLUGIN,
           canAdd: true
@@ -88,6 +96,10 @@ export default class ToolBrowserController extends BrowserController {
         {
           id: 'queries',
           text: 'Queries',
+          object: {
+            type: objectType.OVERVIEW,
+            id: objectType.QUERY
+          },
           children: queryNodes,
           childrenType: objectType.NEW_QUERY,
           canAdd: true
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 ffbc4ea51a290f999ced3dc2cd3563476005110b..1b5c8acbcd7f0d144992c22d46e5d1343760e007 100644
--- a/openbis_ng_ui/src/js/components/tools/common/PluginsGrid.jsx
+++ b/openbis_ng_ui/src/js/components/tools/common/PluginsGrid.jsx
@@ -2,6 +2,7 @@ import React from 'react'
 import Grid from '@src/js/components/common/grid/Grid.jsx'
 import PluginLink from '@src/js/components/common/link/PluginLink.jsx'
 import UserLink from '@src/js/components/common/link/UserLink.jsx'
+import openbis from '@src/js/services/openbis.js'
 import logger from '@src/js/common/logger.js'
 
 class PluginsGrid extends React.PureComponent {
@@ -10,6 +11,7 @@ class PluginsGrid extends React.PureComponent {
 
     const {
       id,
+      pluginType,
       rows,
       selectedRowId,
       onSelectedRowChange,
@@ -20,7 +22,7 @@ class PluginsGrid extends React.PureComponent {
       <Grid
         id={id}
         controllerRef={controllerRef}
-        header='Plugins'
+        header={this.getHeader()}
         columns={[
           {
             name: 'name',
@@ -31,7 +33,7 @@ class PluginsGrid extends React.PureComponent {
               return (
                 <PluginLink
                   pluginName={row.name.value}
-                  pluginType={row.pluginType.value}
+                  pluginType={pluginType}
                 />
               )
             }
@@ -41,11 +43,6 @@ class PluginsGrid extends React.PureComponent {
             label: 'Description',
             getValue: ({ row }) => row.description.value
           },
-          {
-            name: 'pluginType',
-            label: 'Plugin Type',
-            getValue: ({ row }) => row.pluginType.value
-          },
           {
             name: 'pluginKind',
             label: 'Plugin Kind',
@@ -71,6 +68,16 @@ class PluginsGrid extends React.PureComponent {
       />
     )
   }
+
+  getHeader() {
+    const { pluginType } = this.props
+
+    if (pluginType === openbis.PluginType.DYNAMIC_PROPERTY) {
+      return 'Dynamic Property Plugins'
+    } else if (pluginType === openbis.PluginType.ENTITY_VALIDATION) {
+      return 'Entity Validation Plugins'
+    }
+  }
 }
 
 export default PluginsGrid
diff --git a/openbis_ng_ui/src/js/components/tools/search/ToolSearch.jsx b/openbis_ng_ui/src/js/components/tools/search/ToolSearch.jsx
index e70696207d96f4417fe1ea6ea6c5b5a1d01756df..ff65e67efce71774b19e3b6a1d5e63ce4bc06798 100644
--- a/openbis_ng_ui/src/js/components/tools/search/ToolSearch.jsx
+++ b/openbis_ng_ui/src/js/components/tools/search/ToolSearch.jsx
@@ -4,11 +4,14 @@ import React from 'react'
 import GridContainer from '@src/js/components/common/grid/GridContainer.jsx'
 import PluginsGrid from '@src/js/components/tools/common/PluginsGrid.jsx'
 import QueriesGrid from '@src/js/components/tools/common/QueriesGrid.jsx'
+import Message from '@src/js/components/common/form/Message.jsx'
 import FormUtil from '@src/js/components/common/form/FormUtil.js'
 import ids from '@src/js/common/consts/ids.js'
+import objectTypes from '@src/js/common/consts/objectType.js'
 import store from '@src/js/store/store.js'
 import actions from '@src/js/store/actions/actions.js'
 import openbis from '@src/js/services/openbis.js'
+import util from '@src/js/common/util.js'
 import logger from '@src/js/common/logger.js'
 
 class ToolSearch extends React.Component {
@@ -23,75 +26,103 @@ class ToolSearch extends React.Component {
   }
 
   componentDidMount() {
-    Promise.all([this.loadPlugins(), this.loadQueries()])
-      .then(([plugins, queries]) => {
-        this.setState(() => ({
-          loaded: true,
-          plugins,
-          queries
-        }))
-      })
-      .catch(error => {
-        store.dispatch(actions.errorChange(error))
-      })
+    this.load()
   }
 
-  loadPlugins() {
-    let query = this.props.objectId
+  async load() {
+    try {
+      await Promise.all([
+        this.loadDynamicPropertyPlugins(),
+        this.loadEntityValidationPlugins(),
+        this.loadQueries()
+      ])
+      this.setState(() => ({
+        loaded: true
+      }))
+    } catch (error) {
+      store.dispatch(actions.errorChange(error))
+    }
+  }
 
-    let criteria = new openbis.PluginSearchCriteria()
-    criteria.withName().thatContains(query)
+  async loadDynamicPropertyPlugins() {
+    if (!this.shouldLoad(objectTypes.DYNAMIC_PROPERTY_PLUGIN)) {
+      return
+    }
 
-    let fo = new openbis.PluginFetchOptions()
-    fo.withScript()
-    fo.withRegistrator()
+    const dynamicPropertyPlugins = await this.loadPlugins(
+      openbis.PluginType.DYNAMIC_PROPERTY
+    )
 
-    return openbis.searchPlugins(criteria, fo).then(result => {
-      return result.objects
-        .filter(plugin => {
-          return (
-            plugin.pluginType === openbis.PluginType.DYNAMIC_PROPERTY ||
-            plugin.pluginType === openbis.PluginType.ENTITY_VALIDATION
-          )
-        })
-        .map(plugin => {
-          const entityKinds = _.get(plugin, 'entityKinds', [])
-
-          return {
-            id: _.get(plugin, 'name'),
-            name: FormUtil.createField({ value: _.get(plugin, 'name') }),
-            description: FormUtil.createField({
-              value: _.get(plugin, 'description')
-            }),
-            pluginType: FormUtil.createField({
-              value: _.get(plugin, 'pluginType')
-            }),
-            pluginKind: FormUtil.createField({
-              value: _.get(plugin, 'pluginKind')
-            }),
-            entityKind: FormUtil.createField({
-              value: entityKinds.length === 1 ? entityKinds[0] : null
-            }),
-            script: FormUtil.createField({ value: _.get(plugin, 'script') }),
-            registrator: FormUtil.createField({
-              value: _.get(plugin, 'registrator.userId')
-            })
-          }
-        })
+    this.setState({
+      dynamicPropertyPlugins
     })
   }
 
-  loadQueries() {
-    let query = this.props.objectId
+  async loadEntityValidationPlugins() {
+    if (!this.shouldLoad(objectTypes.ENTITY_VALIDATION_PLUGIN)) {
+      return
+    }
 
-    let criteria = new openbis.QuerySearchCriteria()
-    criteria.withName().thatContains(query)
+    const entityValidationPlugins = await this.loadPlugins(
+      openbis.PluginType.ENTITY_VALIDATION
+    )
+
+    this.setState({
+      entityValidationPlugins
+    })
+  }
 
-    let fo = new openbis.QueryFetchOptions()
+  async loadPlugins(pluginType) {
+    const criteria = new openbis.PluginSearchCriteria()
+    criteria.withPluginType().thatEquals(pluginType)
+
+    const fo = new openbis.PluginFetchOptions()
+    fo.withScript()
+    fo.withRegistrator()
+
+    const result = await openbis.searchPlugins(criteria, fo)
+
+    return util
+      .filter(result.objects, this.props.searchText, ['name', 'description'])
+      .map(plugin => {
+        const entityKinds = _.get(plugin, 'entityKinds', [])
+
+        return {
+          id: _.get(plugin, 'name'),
+          name: FormUtil.createField({ value: _.get(plugin, 'name') }),
+          description: FormUtil.createField({
+            value: _.get(plugin, 'description')
+          }),
+          pluginKind: FormUtil.createField({
+            value: _.get(plugin, 'pluginKind')
+          }),
+          entityKind: FormUtil.createField({
+            value: entityKinds.length === 1 ? entityKinds[0] : null
+          }),
+          script: FormUtil.createField({ value: _.get(plugin, 'script') }),
+          registrator: FormUtil.createField({
+            value: _.get(plugin, 'registrator.userId')
+          })
+        }
+      })
+  }
+
+  async loadQueries() {
+    if (!this.shouldLoad(objectTypes.QUERY)) {
+      return
+    }
+
+    const fo = new openbis.QueryFetchOptions()
     fo.withRegistrator()
 
-    return openbis.searchQueries(criteria, fo).then(result => {
-      return result.objects.map(query => ({
+    const result = await openbis.searchQueries(
+      new openbis.QuerySearchCriteria(),
+      fo
+    )
+
+    const queries = util
+      .filter(result.objects, this.props.searchText, ['name', 'description'])
+      .map(query => ({
         id: _.get(query, 'name'),
         name: FormUtil.createField({ value: _.get(query, 'name') }),
         description: FormUtil.createField({
@@ -116,35 +147,38 @@ class ToolSearch extends React.Component {
           value: _.get(query, 'registrator.userId')
         })
       }))
+
+    this.setState({
+      queries
     })
   }
 
+  shouldLoad(objectType) {
+    return this.props.objectType === objectType || !this.props.objectType
+  }
+
   handleClickContainer() {
     this.setState({
       selection: null
     })
   }
 
-  handleSelectedPluginRowChange(row) {
-    if (row) {
-      this.setState({
-        selection: {
-          type: 'plugin',
-          id: row.id
-        }
-      })
+  handleSelectedRowChange(objectType) {
+    return row => {
+      if (row) {
+        this.setState({
+          selection: {
+            type: objectType,
+            id: row.id
+          }
+        })
+      }
     }
   }
 
-  handleSelectedQueryRowChange(row) {
-    if (row) {
-      this.setState({
-        selection: {
-          type: 'query',
-          id: row.id
-        }
-      })
-    }
+  getSelectedRowId(objectType) {
+    const { selection } = this.state
+    return selection && selection.type === objectType ? selection.id : null
   }
 
   render() {
@@ -154,28 +188,103 @@ class ToolSearch extends React.Component {
       return null
     }
 
-    const { selection } = this.state
-
     return (
       <GridContainer onClick={this.handleClickContainer}>
+        {this.renderNoResultsFoundMessage()}
+        {this.renderDynamicPropertyPlugins()}
+        {this.renderEntityValidationPlugins()}
+        {this.renderQueries()}
+      </GridContainer>
+    )
+  }
+
+  renderNoResultsFoundMessage() {
+    const { objectType } = this.props
+    const {
+      dynamicPropertyPlugins = [],
+      entityValidationPlugins = [],
+      queries = []
+    } = this.state
+
+    if (
+      !objectType &&
+      dynamicPropertyPlugins.length === 0 &&
+      entityValidationPlugins.length === 0 &&
+      queries.length === 0
+    ) {
+      return <Message type='info'>No results found.</Message>
+    } else {
+      return null
+    }
+  }
+
+  renderDynamicPropertyPlugins() {
+    if (
+      this.shouldRender(
+        objectTypes.DYNAMIC_PROPERTY_PLUGIN,
+        this.state.dynamicPropertyPlugins
+      )
+    ) {
+      return (
         <PluginsGrid
-          id={ids.PLUGINS_GRID_ID}
-          rows={this.state.plugins}
-          onSelectedRowChange={this.handleSelectedPluginRowChange}
-          selectedRowId={
-            selection && selection.type === 'plugin' ? selection.id : null
-          }
+          id={ids.DYNAMIC_PROPERTY_PLUGINS_GRID_ID}
+          pluginType={openbis.PluginType.DYNAMIC_PROPERTY}
+          rows={this.state.dynamicPropertyPlugins}
+          onSelectedRowChange={this.handleSelectedRowChange(
+            objectTypes.DYNAMIC_PROPERTY_PLUGIN
+          )}
+          selectedRowId={this.getSelectedRowId(
+            objectTypes.DYNAMIC_PROPERTY_PLUGIN
+          )}
         />
+      )
+    } else {
+      return null
+    }
+  }
+
+  renderEntityValidationPlugins() {
+    if (
+      this.shouldRender(
+        objectTypes.ENTITY_VALIDATION_PLUGIN,
+        this.state.entityValidationPlugins
+      )
+    ) {
+      return (
+        <PluginsGrid
+          id={ids.ENTITY_VALIDATION_PLUGINS_GRID_ID}
+          pluginType={openbis.PluginType.ENTITY_VALIDATION}
+          rows={this.state.entityValidationPlugins}
+          onSelectedRowChange={this.handleSelectedRowChange(
+            objectTypes.ENTITY_VALIDATION_PLUGIN
+          )}
+          selectedRowId={this.getSelectedRowId(
+            objectTypes.ENTITY_VALIDATION_PLUGIN
+          )}
+        />
+      )
+    } else {
+      return null
+    }
+  }
+
+  renderQueries() {
+    if (this.shouldRender(objectTypes.QUERY, this.state.queries)) {
+      return (
         <QueriesGrid
           id={ids.QUERIES_GRID_ID}
           rows={this.state.queries}
-          onSelectedRowChange={this.handleSelectedQueryRowChange}
-          selectedRowId={
-            selection && selection.type === 'query' ? selection.id : null
-          }
+          onSelectedRowChange={this.handleSelectedRowChange(objectTypes.QUERY)}
+          selectedRowId={this.getSelectedRowId(objectTypes.QUERY)}
         />
-      </GridContainer>
-    )
+      )
+    } else {
+      return null
+    }
+  }
+
+  shouldRender(objectType, types) {
+    return this.props.objectType === objectType || (types && types.length > 0)
   }
 }