diff --git a/openbis_ng_ui/src/js/common/consts/ids.js b/openbis_ng_ui/src/js/common/consts/ids.js
index 7b561933fb27356e12f9dd64f2dd8a7cf693078f..9256e4b3e18d0efd3de1f934b19dad9736dabb3d 100644
--- a/openbis_ng_ui/src/js/common/consts/ids.js
+++ b/openbis_ng_ui/src/js/common/consts/ids.js
@@ -16,6 +16,8 @@ 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 HISTORY_OF_DELETION_GRID_ID = 'history_of_deletion_grid'
+const HISTORY_OF_FREEZING_GRID_ID = 'history_of_freezing_grid'
 
 export default {
   WEB_APP_ID,
@@ -35,5 +37,7 @@ export default {
   VOCABULARY_TERMS_GRID_ID,
   DYNAMIC_PROPERTY_PLUGINS_GRID_ID,
   ENTITY_VALIDATION_PLUGINS_GRID_ID,
-  QUERIES_GRID_ID
+  QUERIES_GRID_ID,
+  HISTORY_OF_DELETION_GRID_ID,
+  HISTORY_OF_FREEZING_GRID_ID
 }
diff --git a/openbis_ng_ui/src/js/common/consts/objectType.js b/openbis_ng_ui/src/js/common/consts/objectType.js
index 3cf4daf47be73ff89d8c54f41f48862eac629aca..75c3c93e8af6cff21637ebf3bdecbf1cd22e06be 100644
--- a/openbis_ng_ui/src/js/common/consts/objectType.js
+++ b/openbis_ng_ui/src/js/common/consts/objectType.js
@@ -19,6 +19,7 @@ const USER_GROUP = 'userGroup'
 const DYNAMIC_PROPERTY_PLUGIN = 'dynamicPropertyPlugin'
 const ENTITY_VALIDATION_PLUGIN = 'entityValidationPlugin'
 const QUERY = 'query'
+const HISTORY = 'history'
 
 const SEARCH = 'search'
 const OVERVIEW = 'overview'
@@ -44,6 +45,7 @@ export default {
   DYNAMIC_PROPERTY_PLUGIN,
   ENTITY_VALIDATION_PLUGIN,
   QUERY,
+  HISTORY,
   SEARCH,
   OVERVIEW
 }
diff --git a/openbis_ng_ui/src/js/common/consts/routes.js b/openbis_ng_ui/src/js/common/consts/routes.js
index cefa0431ff2fc7cd2be25e8c4692ae6363286ba5..d09d850b0bae92dc0515c2ad052abe9c7aac96d7 100644
--- a/openbis_ng_ui/src/js/common/consts/routes.js
+++ b/openbis_ng_ui/src/js/common/consts/routes.js
@@ -209,6 +209,15 @@ const routes = {
     type: objectTypes.OVERVIEW,
     id: objectTypes.QUERY
   }),
+  HISTORY: new Route('/history/:id', {
+    page: pages.TOOLS,
+    type: objectTypes.HISTORY
+  }),
+  HISTORY_OVERVIEW: new Route('/history-overview', {
+    page: pages.TOOLS,
+    type: objectTypes.OVERVIEW,
+    id: objectTypes.HISTORY
+  }),
   DEFAULT: new DefaultRoute()
 }
 
diff --git a/openbis_ng_ui/src/js/common/date.js b/openbis_ng_ui/src/js/common/date.js
new file mode 100644
index 0000000000000000000000000000000000000000..afda66e7e7cb32b8e96aa0e0cfc69cd139e26c00
--- /dev/null
+++ b/openbis_ng_ui/src/js/common/date.js
@@ -0,0 +1,22 @@
+function format(millis) {
+  if (millis === null) {
+    return ''
+  }
+
+  var date = new Date(millis)
+
+  const year = String(date.getFullYear()).padStart(4, '0')
+  const month = String(date.getMonth() + 1).padStart(2, '0')
+  const day = String(date.getDate()).padStart(2, '0')
+  const hours = String(date.getHours()).padStart(2, '0')
+  const minutes = String(date.getMinutes()).padStart(2, '0')
+  const seconds = String(date.getSeconds()).padStart(2, '0')
+
+  return (
+    year + '-' + month + '-' + day + ' ' + hours + ':' + minutes + ':' + seconds
+  )
+}
+
+export default {
+  format
+}
diff --git a/openbis_ng_ui/src/js/common/messages.js b/openbis_ng_ui/src/js/common/messages.js
index 945a0d822344dc195ec76cc678ef59233243a34a..3e137f09068006ce7661646b813031b6d2a2b231 100644
--- a/openbis_ng_ui/src/js/common/messages.js
+++ b/openbis_ng_ui/src/js/common/messages.js
@@ -23,6 +23,7 @@ const keys = {
   CONFIRMATION_REMOVE_IT: 'CONFIRMATION_REMOVE_IT',
   CONFIRMATION_UNSAVED_CHANGES: 'CONFIRMATION_UNSAVED_CHANGES',
   CONTAINER: 'CONTAINER',
+  CONTENT: 'CONTENT',
   CONVERTED: 'CONVERTED',
   CRASH: 'CRASH',
   DATABASE: 'DATABASE',
@@ -31,7 +32,9 @@ const keys = {
   DATA_TYPE: 'DATA_TYPE',
   DATA_TYPE_NOT_SELECTED_FOR_PREVIEW: 'DATA_TYPE_NOT_SELECTED_FOR_PREVIEW',
   DATA_TYPE_NOT_SUPPORTED: 'DATA_TYPE_NOT_SUPPORTED',
+  DATE: 'DATE',
   DEACTIVATE_USER: 'DEACTIVATE_USER',
+  DELETIONS: 'DELETIONS',
   DESCRIPTION: 'DESCRIPTION',
   DISALLOW_DELETION: 'DISALLOW_DELETION',
   DYNAMIC_PROPERTY_PLUGIN: 'DYNAMIC_PROPERTY_PLUGIN',
@@ -39,22 +42,31 @@ const keys = {
   EDIT: 'EDIT',
   EMAIL: 'EMAIL',
   ENTITY: 'ENTITY',
+  ENTITY_IDENTIFIER: 'ENTITY_IDENTIFIER',
   ENTITY_KIND: 'ENTITY_KIND',
+  ENTITY_PROJECT: 'ENTITY_PROJECT',
+  ENTITY_REGISTRATION_DATE: 'ENTITY_REGISTRATION_DATE',
+  ENTITY_REGISTRATOR: 'ENTITY_REGISTRATOR',
+  ENTITY_SPACE: 'ENTITY_SPACE',
+  ENTITY_TYPE: 'ENTITY_TYPE',
   ENTITY_TYPE_PATTERN: 'ENTITY_TYPE_PATTERN',
   ENTITY_VALIDATION_PLUGIN: 'ENTITY_VALIDATION_PLUGIN',
   ENTITY_VALIDATION_PLUGINS: 'ENTITY_VALIDATION_PLUGINS',
   ERROR: 'ERROR',
   EVALUATE: 'EVALUATE',
+  EVENT_TYPE: 'EVENT_TYPE',
   EXECUTE: 'EXECUTE',
   FILTER: 'FILTER',
   FIRST_NAME: 'FIRST_NAME',
   FIRST_PAGE: 'FIRST_PAGE',
   FORM_PREVIEW: 'FORM_PREVIEW',
+  FREEZES: 'FREEZES',
   GENERATED_CODE_PREFIX: 'GENERATED_CODE_PREFIX',
   GENERATE_CODES: 'GENERATE_CODES',
   GLOBAL: 'GLOBAL',
   GROUP: 'GROUP',
   GROUPS: 'GROUPS',
+  HISTORY: 'HISTORY',
   HOME_SPACE: 'HOME_SPACE',
   INHERITED_FROM: 'INHERITED_FROM',
   INITIAL_VALUE: 'INITIAL_VALUE',
@@ -118,6 +130,7 @@ const keys = {
   QUERY_HINT: 'QUERY_HINT',
   QUERY_PUBLIC_WARNING: 'QUERY_PUBLIC_WARNING',
   QUERY_TYPE: 'QUERY_TYPE',
+  REASON: 'REASON',
   REGISTRATOR: 'REGISTRATOR',
   REMOVE: 'REMOVE',
   REMOVE_TERM: 'REMOVE_TERM',
@@ -183,49 +196,63 @@ const messages_en = {
   [keys.CANCEL]: 'Cancel',
   [keys.CLOSE]: 'Close',
   [keys.CODE]: 'Code',
-  [keys.COLLECTION_TYPE]: 'Collection Type',
   [keys.COLLECTION_TYPES]: 'Collection Types',
-  [keys.CONFIRM]: 'Confirm',
+  [keys.COLLECTION_TYPE]: 'Collection Type',
   [keys.CONFIRMATION]: 'Confirmation',
   [keys.CONFIRMATION_ACTIVATE_USER]: 'Are you sure you want to activate the user?',
   [keys.CONFIRMATION_DEACTIVATE_USER]: 'Are you sure you want to deactivate the user?',
   [keys.CONFIRMATION_REMOVE]: 'Are you sure you want to remove "${0}"?',
   [keys.CONFIRMATION_REMOVE_IT]: 'Are you sure you want to remove it?',
   [keys.CONFIRMATION_UNSAVED_CHANGES]: 'Are you sure you want to lose the unsaved changes?',
+  [keys.CONFIRM]: 'Confirm',
   [keys.CONTAINER]: 'Container',
+  [keys.CONTENT]: 'Content',
   [keys.CONVERTED]: 'Converted',
   [keys.CRASH]: 'Something went wrong :(',
   [keys.DATABASE]: 'Database',
-  [keys.DATA_SET_TYPE]: 'Data Set Type',
   [keys.DATA_SET_TYPES]: 'Data Set Types',
+  [keys.DATA_SET_TYPE]: 'Data Set Type',
   [keys.DATA_TYPE]: 'Data Type',
   [keys.DATA_TYPE_NOT_SELECTED_FOR_PREVIEW]: 'Please select a data type to display the field preview.',
   [keys.DATA_TYPE_NOT_SUPPORTED]: 'The selected data type is not supported yet.',
+  [keys.DATE]: 'Date',
   [keys.DEACTIVATE_USER]: 'Deactivate user',
+  [keys.DELETIONS]: 'Deletions',
   [keys.DESCRIPTION]: 'Description',
   [keys.DISALLOW_DELETION]: 'Disallow Deletion',
-  [keys.DYNAMIC_PROPERTY_PLUGIN]: 'Dynamic Property Plugin',
   [keys.DYNAMIC_PROPERTY_PLUGINS]: 'Dynamic Property Plugins',
+  [keys.DYNAMIC_PROPERTY_PLUGIN]: 'Dynamic Property Plugin',
   [keys.EDIT]: 'Edit',
   [keys.EMAIL]: 'Email',
   [keys.ENTITY]: 'Entity',
+  [keys.ENTITY_IDENTIFIER]: 'Entity Identifier',
   [keys.ENTITY_KIND]: 'Entity Kind',
+  [keys.ENTITY_PROJECT]: 'Entity Project',
+  [keys.ENTITY_REGISTRATION_DATE]: 'Entity Registration Date',
+  [keys.ENTITY_REGISTRATOR]: 'Entity Registrator',
+  [keys.ENTITY_SPACE]: 'Entity Space',
+  [keys.ENTITY_TYPE]: 'Entity Type',
   [keys.ENTITY_TYPE_PATTERN]: 'Entity Type Pattern',
-  [keys.ENTITY_VALIDATION_PLUGIN]: 'Entity Validation Plugin',
   [keys.ENTITY_VALIDATION_PLUGINS]: 'Entity Validation Plugins',
+  [keys.ENTITY_VALIDATION_PLUGIN]: 'Entity Validation Plugin',
   [keys.ERROR]: 'Error',
   [keys.EVALUATE]: 'Evaluate',
+  [keys.EVENT_TYPE]: 'Event Type',
   [keys.EXECUTE]: 'Execute',
   [keys.FILTER]: 'Filter',
   [keys.FIRST_NAME]: 'First Name',
   [keys.FIRST_PAGE]: 'First Page',
   [keys.FORM_PREVIEW]: 'Form Preview',
+  [keys.FREEZES]: 'Freezes',
   [keys.GENERATED_CODE_PREFIX]: 'Generated code prefix',
   [keys.GENERATE_CODES]: 'Generate Codes',
   [keys.GLOBAL]: 'Global',
-  [keys.GROUP]: 'Group',
   [keys.GROUPS]: 'Groups',
+  [keys.GROUP]: 'Group',
+  [keys.HISTORY]: 'History',
+  [keys.HISTORY]: 'History',
   [keys.HOME_SPACE]: 'Home Space',
+  [keys.IDENTIFIER]: 'Identifier',
   [keys.INHERITED_FROM]: 'Inherited From',
   [keys.INITIAL_VALUE]: 'Initial Value',
   [keys.IS_NEW_ENTITY]: 'Is New Entity',
@@ -239,8 +266,8 @@ const messages_en = {
   [keys.MAIN_DATA_SET_PATH]: 'Main Data Set Path',
   [keys.MAIN_DATA_SET_PATTERN]: 'Main Data Set Pattern',
   [keys.MANDATORY]: 'Mandatory',
-  [keys.MATERIAL_TYPE]: 'Material Type',
   [keys.MATERIAL_TYPES]: 'Material Types',
+  [keys.MATERIAL_TYPE]: 'Material Type',
   [keys.NAME]: 'Name',
   [keys.NEW_COLLECTION_TYPE]: 'New Collection Type',
   [keys.NEW_DATA_SET_TYPE]: 'New Data Set Type',
@@ -256,8 +283,8 @@ const messages_en = {
   [keys.NO_RESULTS_FOUND]: 'No results found',
   [keys.OBJECT_DOES_NOT_EXIST]: 'Object does not exist',
   [keys.OBJECT_NOT_VISIBLE_DUE_TO_FILTERING_AND_PAGING]: 'The selected object is currently not visible in the list due to the chosen filtering and paging.',
-  [keys.OBJECT_TYPE]: 'Object Type',
   [keys.OBJECT_TYPES]: 'Object Types',
+  [keys.OBJECT_TYPE]: 'Object Type',
   [keys.OFFICIAL]: 'Official',
   [keys.OFFICIAL_TERM_HINT]: 'Unofficial (aka ad-hoc) terms can be created by regular users from the non-admin UI. Once verified a term can be made official by an admin. WARNING: Official terms cannot be made unofficial again.',
   [keys.ONLY_FIRST_RESULTS_SHOWN]: 'Showing only the first ${0} results (${1} results found)',
@@ -288,15 +315,16 @@ const messages_en = {
   [keys.QUERY_HINT]: 'A query can contain parameters in the following format: ${parameterName}.',
   [keys.QUERY_PUBLIC_WARNING]: 'Security warning: this query is public (i.e. visible to other users) and is defined for a database that is not assigned to any space. Please make sure the query returns only data that can be seen by every user or the results contain one of the special columns (i.e. experiment_key/sample_key/data_set_key) that will be used for an automatic query results filtering.',
   [keys.QUERY_TYPE]: 'Query Type',
+  [keys.REASON]: 'Reason',
   [keys.REGISTRATOR]: 'Registrator',
   [keys.REMOVE]: 'Remove',
   [keys.REMOVE_TERM]: 'Remove Term',
-  [keys.RESULT]: 'Result',
   [keys.RESULTS]: 'Results',
-  [keys.ROLE]: 'Role',
+  [keys.RESULT]: 'Result',
   [keys.ROLES]: 'Roles',
   [keys.ROLES_OF_GROUPS]: 'Groups\' Roles',
   [keys.ROLES_OF_USERS]: 'Users\' Roles',
+  [keys.ROLE]: 'Role',
   [keys.ROLE_IS_INHERITED]: 'This role is inherited from ${0} group.',
   [keys.ROLE_IS_INSTANCE_ADMIN]: 'This is an instance admin role. It gives an access to the user and master data management functionality.',
   [keys.ROWS_PER_PAGE]: 'Rows per page: ',
@@ -313,16 +341,16 @@ const messages_en = {
   [keys.SPACE]: 'Space',
   [keys.SQL]: 'SQL',
   [keys.SUBCODES_UNIQUE]: 'Unique Subcodes',
-  [keys.TERM]: 'Term',
   [keys.TERMS]: 'Terms',
+  [keys.TERM]: 'Term',
   [keys.TERM_IS_INTERNAL]: 'This is a system internal term. The term parameters cannot be changed. The term cannot be removed.',
   [keys.TESTER]: 'Tester',
   [keys.TOOLS]: 'Tools',
   [keys.TYPES]: 'Types',
   [keys.UNSAVED_CHANGES]: 'You have unsaved changes',
   [keys.URL_TEMPLATE]: 'URL Template',
-  [keys.USER]: 'User',
   [keys.USERS]: 'Users',
+  [keys.USER]: 'User',
   [keys.USER_ID]: 'User Id',
   [keys.VALIDATION_CANNOT_BE_EMPTY]: '${0} cannot be empty',
   [keys.VALIDATION_CODE_PATTERN]: '${0} can only contain A-Z, a-z, 0-9 and _, -, .',
@@ -331,8 +359,8 @@ const messages_en = {
   [keys.VALIDATION_TERM_CODE_PATTERN]: '${0} can only contain A-Z, a-z, 0-9 and _, -, ., :',
   [keys.VALIDATION_USER_CODE_PATTERN]: '${0} can only contain A-Z, a-z, 0-9 and _, -, ., @',
   [keys.VISIBLE]: 'Visible',
-  [keys.VOCABULARY_TYPE]: 'Vocabulary Type',
   [keys.VOCABULARY_TYPES]: 'Vocabulary Types',
+  [keys.VOCABULARY_TYPE]: 'Vocabulary Type',
   [keys.VOCABULARY_TYPE_IS_INTERNAL]: 'This is a system internal vocabulary. The vocabulary parameters cannot be changed.',
   [keys.XML_SCHEMA]: 'XML Schema',
   [keys.XSLT_SCRIPT]: 'XSLT Script',
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 1f4f7e685c36cfe4bc6c9e1d141a470ab8998567..20208cc6ac34a9f8c05454dd8083d452cd914535 100644
--- a/openbis_ng_ui/src/js/components/common/grid/GridController.js
+++ b/openbis_ng_ui/src/js/components/common/grid/GridController.js
@@ -33,24 +33,24 @@ export default class GridController {
       }
 
       columns.push(this.initColumn(column))
+    })
 
-      context.initState({
-        loaded: false,
-        filters: {},
-        page: 0,
-        pageSize: 10,
-        columns,
-        allRows: [],
-        filteredRows: [],
-        sortedRows: [],
-        currentRows: [],
-        selectedRow: null,
-        sort: initialSort,
-        sortDirection: initialSortDirection
-      })
-
-      this.context = context
+    context.initState({
+      loaded: false,
+      filters: {},
+      page: 0,
+      pageSize: 10,
+      columns,
+      allRows: [],
+      filteredRows: [],
+      sortedRows: [],
+      currentRows: [],
+      selectedRow: null,
+      sort: initialSort,
+      sortDirection: initialSortDirection
     })
+
+    this.context = context
   }
 
   initColumn(config) {
@@ -61,14 +61,15 @@ export default class GridController {
       name: config.name,
       label: config.label,
       getValue: config.getValue,
-      render: row => {
+      render: (row, classes) => {
         const value = config.getValue({ row, column })
 
         const renderedValue = config.renderValue
           ? config.renderValue({
               value,
               row,
-              column
+              column,
+              classes
             })
           : value
 
diff --git a/openbis_ng_ui/src/js/components/common/grid/GridRow.jsx b/openbis_ng_ui/src/js/components/common/grid/GridRow.jsx
index dfc6d0f39ff292cd5ed2ce69366aae5070a9d446..9f0763380b83e38cca3f97d88587babb4b796439 100644
--- a/openbis_ng_ui/src/js/components/common/grid/GridRow.jsx
+++ b/openbis_ng_ui/src/js/components/common/grid/GridRow.jsx
@@ -3,6 +3,7 @@ import { withStyles } from '@material-ui/core/styles'
 import TableRow from '@material-ui/core/TableRow'
 import TableCell from '@material-ui/core/TableCell'
 import logger from '@src/js/common/logger.js'
+import util from '@src/js/common/util.js'
 
 const styles = theme => ({
   row: {
@@ -11,6 +12,12 @@ const styles = theme => ({
   cell: {
     padding: `${theme.spacing(1)}px ${theme.spacing(2)}px`,
     borderColor: theme.palette.border.secondary
+  },
+  wrap: {
+    whiteSpace: 'normal'
+  },
+  nowrap: {
+    whiteSpace: 'nowrap'
   }
 })
 
@@ -51,9 +58,15 @@ class GridRow extends React.PureComponent {
     const { classes } = this.props
 
     if (column.visible) {
-      let rendered = column.render(row)
+      let rendered = column.render(row, {
+        wrap: classes.wrap,
+        nowrap: classes.nowrap
+      })
       return (
-        <TableCell key={column.name} classes={{ root: classes.cell }}>
+        <TableCell
+          key={column.name}
+          classes={{ root: util.classNames(classes.cell, classes.nowrap) }}
+        >
           {rendered ? rendered : <span>&nbsp;</span>}
         </TableCell>
       )
diff --git a/openbis_ng_ui/src/js/components/tools/Tools.jsx b/openbis_ng_ui/src/js/components/tools/Tools.jsx
index 67401b47355b904998a9919a562f1b724edb3718..88b84215d7b0129955981157e4e8f139a2b7d6e3 100644
--- a/openbis_ng_ui/src/js/components/tools/Tools.jsx
+++ b/openbis_ng_ui/src/js/components/tools/Tools.jsx
@@ -9,6 +9,7 @@ import ToolBrowser from '@src/js/components/tools/browser/ToolBrowser.jsx'
 import ToolSearch from '@src/js/components/tools/search/ToolSearch.jsx'
 import PluginForm from '@src/js/components/tools/form/plugin/PluginForm.jsx'
 import QueryForm from '@src/js/components/tools/form/query/QueryForm.jsx'
+import HistoryForm from '@src/js/components/tools/form/history/HistoryForm.jsx'
 import messages from '@src/js/common/messages.js'
 
 const styles = () => ({
@@ -50,6 +51,8 @@ class Tools extends React.Component {
       object.type === objectType.QUERY
     ) {
       return <QueryForm object={object} />
+    } else if (object.type === objectType.HISTORY) {
+      return <HistoryForm object={object} />
     } else if (object.type === objectType.SEARCH) {
       return <ToolSearch searchText={object.id} />
     } else if (object.type === objectType.OVERVIEW) {
@@ -70,7 +73,8 @@ class Tools extends React.Component {
         [objectType.ENTITY_VALIDATION_PLUGIN]: messages.get(
           messages.ENTITY_VALIDATION_PLUGINS
         ),
-        [objectType.QUERY]: messages.get(messages.QUERIES)
+        [objectType.QUERY]: messages.get(messages.QUERIES),
+        [objectType.HISTORY]: messages.get(messages.HISTORY)
       }
       label = labels[object.id]
     } else {
@@ -85,6 +89,7 @@ class Tools extends React.Component {
         [objectType.ENTITY_VALIDATION_PLUGIN]:
           messages.get(messages.ENTITY_VALIDATION_PLUGIN) + ': ',
         [objectType.QUERY]: messages.get(messages.QUERY) + ': ',
+        [objectType.HISTORY]: messages.get(messages.HISTORY) + ': ',
         [objectType.SEARCH]: messages.get(messages.SEARCH) + ': '
       }
       label = prefixes[object.type] + object.id
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 89088077066cd3f40d6eb00f53ba4abfb93cef9c..a765aafc2dab7788767a9c1979da2b7aa6a9386c 100644
--- a/openbis_ng_ui/src/js/components/tools/browser/ToolBrowserController.js
+++ b/openbis_ng_ui/src/js/components/tools/browser/ToolBrowserController.js
@@ -71,6 +71,29 @@ export default class ToolBrowserController extends BrowserController {
         }
       })
 
+      const historyNodes = [
+        {
+          id: `history/deletion`,
+          text: openbis.EventType.DELETION,
+          object: {
+            type: objectType.HISTORY,
+            id: openbis.EventType.DELETION
+          },
+          canMatchFilter: true,
+          canRemove: false
+        },
+        {
+          id: `history/freeze`,
+          text: openbis.EventType.FREEZING,
+          object: {
+            type: objectType.HISTORY,
+            id: openbis.EventType.FREEZING
+          },
+          canMatchFilter: true,
+          canRemove: false
+        }
+      ]
+
       let nodes = [
         {
           id: 'dynamicPropertyPlugins',
@@ -104,6 +127,12 @@ export default class ToolBrowserController extends BrowserController {
           children: queryNodes,
           childrenType: objectType.NEW_QUERY,
           canAdd: true
+        },
+        {
+          id: 'history',
+          text: messages.get(messages.HISTORY),
+          children: historyNodes,
+          canAdd: 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
new file mode 100644
index 0000000000000000000000000000000000000000..139d2db68b22867276ab21137516bc318d6c383e
--- /dev/null
+++ b/openbis_ng_ui/src/js/components/tools/common/HistoryGrid.jsx
@@ -0,0 +1,166 @@
+import React from 'react'
+import Grid from '@src/js/components/common/grid/Grid.jsx'
+import UserLink from '@src/js/components/common/link/UserLink.jsx'
+import Collapse from '@material-ui/core/Collapse'
+import Link from '@material-ui/core/Link'
+import openbis from '@src/js/services/openbis.js'
+import messages from '@src/js/common/messages.js'
+import date from '@src/js/common/date.js'
+import ids from '@src/js/common/consts/ids.js'
+import logger from '@src/js/common/logger.js'
+
+class HistoryGrid extends React.PureComponent {
+  constructor(props) {
+    super(props)
+
+    this.state = {
+      shown: {}
+    }
+  }
+
+  handleVisibilityChange(row, fieldName) {
+    const { onRowChange } = this.props
+    if (onRowChange) {
+      onRowChange(row.id, {
+        [fieldName]: {
+          ...row[fieldName],
+          visible: !row[fieldName].visible
+        }
+      })
+    }
+  }
+
+  render() {
+    logger.log(logger.DEBUG, 'HistoryGrid.render')
+
+    const {
+      rows,
+      selectedRowId,
+      onSelectedRowChange,
+      controllerRef
+    } = this.props
+
+    return (
+      <Grid
+        id={this.getId()}
+        header={this.getHeader()}
+        controllerRef={controllerRef}
+        columns={[
+          {
+            name: 'eventType',
+            label: messages.get(messages.EVENT_TYPE),
+            getValue: ({ row }) => row.eventType.value
+          },
+          {
+            name: 'entityType',
+            label: messages.get(messages.ENTITY_TYPE),
+            getValue: ({ row }) => row.entityType.value
+          },
+          {
+            name: 'entityIdentifier',
+            label: messages.get(messages.ENTITY_IDENTIFIER),
+            getValue: ({ row }) => row.identifier.value
+          },
+          {
+            name: 'entitySpace',
+            label: messages.get(messages.ENTITY_SPACE),
+            getValue: ({ row }) => row.entitySpace.value
+          },
+          {
+            name: 'entityProject',
+            label: messages.get(messages.ENTITY_PROJECT),
+            getValue: ({ row }) => row.entityProject.value
+          },
+          {
+            name: 'entityRegistrator',
+            label: messages.get(messages.ENTITY_REGISTRATOR),
+            getValue: ({ row }) => row.entityRegistrator.value
+          },
+          {
+            name: 'entityRegistrationDate',
+            label: messages.get(messages.ENTITY_REGISTRATION_DATE),
+            getValue: ({ row }) => date.format(row.entityRegistrationDate.value)
+          },
+          {
+            name: 'description',
+            label: messages.get(messages.DESCRIPTION),
+            getValue: ({ row }) => row.description.value
+          },
+          {
+            name: 'reason',
+            label: messages.get(messages.REASON),
+            getValue: ({ row }) => row.reason.value
+          },
+          {
+            name: 'content',
+            label: messages.get(messages.CONTENT),
+            getValue: ({ row }) => row.content.value,
+            renderValue: ({ row }) => {
+              const { value, visible } = row.content
+              if (value) {
+                return (
+                  <div>
+                    <Link
+                      onClick={() => {
+                        this.handleVisibilityChange(row, 'content')
+                      }}
+                    >
+                      {visible ? 'hide' : 'show'}
+                    </Link>
+                    <Collapse
+                      in={visible}
+                      mountOnEnter={true}
+                      unmountOnExit={true}
+                    >
+                      <pre>{value}</pre>
+                    </Collapse>
+                  </div>
+                )
+              } else {
+                return null
+              }
+            }
+          },
+          {
+            name: 'registrator',
+            label: messages.get(messages.USER),
+            getValue: ({ row }) => row.registrator.value,
+            renderValue: ({ value }) => {
+              return <UserLink userId={value} />
+            }
+          },
+          {
+            name: 'registrationDate',
+            label: messages.get(messages.DATE),
+            getValue: ({ row }) => date.format(row.registrationDate.value)
+          }
+        ]}
+        rows={rows}
+        selectedRowId={selectedRowId}
+        onSelectedRowChange={onSelectedRowChange}
+      />
+    )
+  }
+
+  getId() {
+    const { eventType } = this.props
+
+    if (eventType === openbis.EventType.DELETION) {
+      return ids.HISTORY_OF_DELETION_GRID_ID
+    } else if (eventType === openbis.EventType.FREEZING) {
+      return ids.HISTORY_OF_FREEZING_GRID_ID
+    }
+  }
+
+  getHeader() {
+    const { eventType } = this.props
+
+    if (eventType === openbis.EventType.DELETION) {
+      return messages.get(messages.DELETIONS)
+    } else if (eventType === openbis.EventType.FREEZING) {
+      return messages.get(messages.FREEZES)
+    }
+  }
+}
+
+export default HistoryGrid
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 1f96f375ab1cc964db12f8c9a4481b7f753c0a01..f833b6d2ade3437cc6c40642d6e032827b5ec1f5 100644
--- a/openbis_ng_ui/src/js/components/tools/common/PluginsGrid.jsx
+++ b/openbis_ng_ui/src/js/components/tools/common/PluginsGrid.jsx
@@ -43,7 +43,10 @@ class PluginsGrid extends React.PureComponent {
           {
             name: 'description',
             label: messages.get(messages.DESCRIPTION),
-            getValue: ({ row }) => row.description.value
+            getValue: ({ row }) => row.description.value,
+            renderValue: ({ value, classes }) => (
+              <span className={classes.wrap}>{value}</span>
+            )
           },
           {
             name: 'pluginKind',
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 20320dfa19aa868c2092beffd2363a8f80bcce6f..10b8c71918e78bfab0bbdb7405c68195cca962f1 100644
--- a/openbis_ng_ui/src/js/components/tools/common/QueriesGrid.jsx
+++ b/openbis_ng_ui/src/js/components/tools/common/QueriesGrid.jsx
@@ -36,7 +36,10 @@ class QueriesGrid extends React.PureComponent {
           {
             name: 'description',
             label: messages.get(messages.DESCRIPTION),
-            getValue: ({ row }) => row.description.value
+            getValue: ({ row }) => row.description.value,
+            renderValue: ({ value, classes }) => (
+              <span className={classes.wrap}>{value}</span>
+            )
           },
           {
             name: 'database',
diff --git a/openbis_ng_ui/src/js/components/tools/form/history/HistoryForm.jsx b/openbis_ng_ui/src/js/components/tools/form/history/HistoryForm.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..94461d1c751f92b378466fc780cdd2d77f315206
--- /dev/null
+++ b/openbis_ng_ui/src/js/components/tools/form/history/HistoryForm.jsx
@@ -0,0 +1,127 @@
+import _ from 'lodash'
+import React from 'react'
+import autoBind from 'auto-bind'
+import { connect } from 'react-redux'
+import { withStyles } from '@material-ui/core/styles'
+import GridContainer from '@src/js/components/common/grid/GridContainer.jsx'
+import HistoryGrid from '@src/js/components/tools/common/HistoryGrid.jsx'
+import FormUtil from '@src/js/components/common/form/FormUtil.js'
+import openbis from '@src/js/services/openbis.js'
+import store from '@src/js/store/store.js'
+import actions from '@src/js/store/actions/actions.js'
+import logger from '@src/js/common/logger.js'
+
+const styles = () => ({})
+
+class HistoryForm extends React.PureComponent {
+  constructor(props) {
+    super(props)
+    autoBind(this)
+
+    this.state = {
+      loaded: false,
+      selection: null
+    }
+  }
+
+  componentDidMount() {
+    this.load()
+  }
+
+  async load() {
+    try {
+      const rows = await this.loadEvents(this.props.object.id)
+      this.setState(() => ({
+        rows,
+        loaded: true
+      }))
+    } catch (error) {
+      store.dispatch(actions.errorChange(error))
+    }
+  }
+
+  async loadEvents(eventType) {
+    const criteria = new openbis.EventSearchCriteria()
+    criteria.withEventType().thatEquals(eventType)
+
+    const fo = new openbis.EventFetchOptions()
+    fo.withRegistrator()
+
+    const result = await openbis.searchEvents(criteria, fo)
+
+    return result.objects.map(event => ({
+      id: _.get(event, 'id'),
+      eventType: FormUtil.createField({ value: _.get(event, 'eventType') }),
+      entityType: FormUtil.createField({ value: _.get(event, 'entityType') }),
+      entitySpace: FormUtil.createField({
+        value: _.get(event, 'entitySpace')
+      }),
+      entityProject: FormUtil.createField({
+        value: _.get(event, 'entityProject')
+      }),
+      entityRegistrator: FormUtil.createField({
+        value: _.get(event, 'entityRegistrator')
+      }),
+      entityRegistrationDate: FormUtil.createField({
+        value: _.get(event, 'entityRegistrationDate')
+      }),
+      identifier: FormUtil.createField({
+        value: _.get(event, 'identifier')
+      }),
+      description: FormUtil.createField({
+        value: _.get(event, 'description')
+      }),
+      reason: FormUtil.createField({
+        value: _.get(event, 'reason')
+      }),
+      content: FormUtil.createField({
+        value: _.get(event, 'content'),
+        visible: false
+      }),
+      registrator: FormUtil.createField({
+        value: _.get(event, 'registrator.userId')
+      }),
+      registrationDate: FormUtil.createField({
+        value: _.get(event, 'registrationDate')
+      })
+    }))
+  }
+
+  handleRowChange(rowId, change) {
+    const rows = this.state.rows
+    this.setState(state => {
+      const index = rows.findIndex(row => row.id === rowId)
+      if (index !== -1) {
+        const row = rows[index]
+        const newRows = Array.from(rows)
+        newRows[index] = {
+          ...row,
+          ...change
+        }
+        return {
+          ...state,
+          rows: newRows
+        }
+      }
+    })
+  }
+
+  render() {
+    logger.log(logger.DEBUG, 'HistoryForm.render')
+
+    const { id } = this.props.object
+    const { rows } = this.state
+
+    return (
+      <GridContainer>
+        <HistoryGrid
+          eventType={id}
+          rows={rows}
+          onRowChange={this.handleRowChange}
+        />
+      </GridContainer>
+    )
+  }
+}
+
+export default _.flow(connect(), withStyles(styles))(HistoryForm)
diff --git a/openbis_ng_ui/src/js/components/types/common/TypesGrid.jsx b/openbis_ng_ui/src/js/components/types/common/TypesGrid.jsx
index 554b96c41f1d98a5fd4408217482ed01a57eef5a..15dc0e50eae0cf3542edcde402a75657f528633c 100644
--- a/openbis_ng_ui/src/js/components/types/common/TypesGrid.jsx
+++ b/openbis_ng_ui/src/js/components/types/common/TypesGrid.jsx
@@ -62,7 +62,10 @@ class TypesGrid extends React.PureComponent {
     columns.push({
       name: 'description',
       label: messages.get(messages.DESCRIPTION),
-      getValue: ({ row }) => row.description
+      getValue: ({ row }) => row.description,
+      renderValue: ({ value, classes }) => (
+        <span className={classes.wrap}>{value}</span>
+      )
     })
 
     columns.push({
diff --git a/openbis_ng_ui/src/js/components/types/common/VocabulariesGrid.jsx b/openbis_ng_ui/src/js/components/types/common/VocabulariesGrid.jsx
index 962b146b6c8eef9ee22a5769b83aa5931376ca23..6d2144e97c7943e9e6259b93d64ab54b9ebd1579 100644
--- a/openbis_ng_ui/src/js/components/types/common/VocabulariesGrid.jsx
+++ b/openbis_ng_ui/src/js/components/types/common/VocabulariesGrid.jsx
@@ -34,7 +34,10 @@ class VocabulariesGrid extends React.PureComponent {
           {
             name: 'description',
             label: messages.get(messages.DESCRIPTION),
-            getValue: ({ row }) => row.description
+            getValue: ({ row }) => row.description,
+            renderValue: ({ value, classes }) => (
+              <span className={classes.wrap}>{value}</span>
+            )
           },
           {
             name: 'urlTemplate',
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 16055aec359b671fcf158d6e63ae0788c6fffc52..820ccb7e0656393254df88e910b07b2968ccb7d2 100644
--- a/openbis_ng_ui/src/js/components/users/common/UserGroupsGrid.jsx
+++ b/openbis_ng_ui/src/js/components/users/common/UserGroupsGrid.jsx
@@ -34,7 +34,10 @@ export default class GroupsGrid extends React.PureComponent {
           {
             name: 'description',
             label: messages.get(messages.DESCRIPTION),
-            getValue: ({ row }) => row.description.value
+            getValue: ({ row }) => row.description.value,
+            renderValue: ({ value, classes }) => (
+              <span className={classes.wrap}>{value}</span>
+            )
           }
         ]}
         rows={rows}
diff --git a/openbis_ng_ui/src/js/services/openbis/api.js b/openbis_ng_ui/src/js/services/openbis/api.js
index 6342a38da5b52c4178b56d5f9bb5b096ff4962f7..e503d363b846d639fca4e92733cd79283a1e1136 100644
--- a/openbis_ng_ui/src/js/services/openbis/api.js
+++ b/openbis_ng_ui/src/js/services/openbis/api.js
@@ -115,6 +115,10 @@ class Facade {
     return this.promise(this.v3.searchPropertyAssignments(criteria, fo))
   }
 
+  searchEvents(criteria, fo) {
+    return this.promise(this.v3.searchEvents(criteria, fo))
+  }
+
   getSampleTypes(ids, fo) {
     return this.promise(this.v3.getSampleTypes(ids, fo))
   }
diff --git a/openbis_ng_ui/src/js/services/openbis/dto.js b/openbis_ng_ui/src/js/services/openbis/dto.js
index ea7cb50f111e5f1a6a27c1adbb658bbe5476c3a6..e219445ce2f5993227a19714ea6c6e6acbb1694a 100644
--- a/openbis_ng_ui/src/js/services/openbis/dto.js
+++ b/openbis_ng_ui/src/js/services/openbis/dto.js
@@ -23,6 +23,11 @@ const CLASS_FULL_NAMES = [
   'as/dto/dataset/update/UpdateDataSetTypesOperation',
   'as/dto/entitytype/EntityKind',
   'as/dto/entitytype/id/EntityTypePermId',
+  'as/dto/event/fetchoptions/EventFetchOptions',
+  'as/dto/event/search/EventSearchCriteria',
+  'as/dto/event/EntityType',
+  'as/dto/event/Event',
+  'as/dto/event/EventType',
   'as/dto/experiment/create/CreateExperimentTypesOperation',
   'as/dto/experiment/create/ExperimentTypeCreation',
   'as/dto/experiment/delete/DeleteExperimentTypesOperation',