From 8c8af78b9531e0e57f9986e6a474063fc6a47191 Mon Sep 17 00:00:00 2001
From: pkupczyk <piotr.kupczyk@id.ethz.ch>
Date: Thu, 16 Mar 2023 15:41:31 +0100
Subject: [PATCH] SSDM-13133 : Add info to Admin UI : registrator,
 registrationDate, modificationDate for users, groups, roles

---
 ui-admin/src/js/common/messages.js            |  2 +
 .../js/components/users/common/RolesGrid.jsx  | 17 ++++++
 .../users/common/UserGroupsGrid.jsx           | 20 +++++++
 .../js/components/users/common/UsersGrid.jsx  | 14 +++++
 .../users/form/common/RoleControllerAdd.js    |  6 +++
 .../users/form/common/RoleControllerLoad.js   |  6 +++
 .../form/user/UserFormControllerAddGroup.js   |  3 ++
 .../form/user/UserFormControllerChange.js     | 14 +++++
 .../users/form/user/UserFormControllerLoad.js |  9 ++++
 ...FormControllerRecalculateInheritedRoles.js |  8 +++
 .../users/form/user/UserFormFacade.js         |  5 ++
 .../UserGroupFormControllerAddUser.js         |  2 +
 .../UserGroupFormControllerChange.js          |  8 +++
 .../usergroup/UserGroupFormControllerLoad.js  |  6 +++
 .../form/usergroup/UserGroupFormFacade.js     |  3 ++
 .../js/components/users/search/UserSearch.jsx | 44 +++++++++++++++-
 .../form/user/UserFormComponentLoad.test.js   | 30 +++++++++++
 .../user/UserFormComponentSortRoles.test.js   | 40 ++++++++++++++
 .../UserGroupFormComponentLoad.test.js        | 24 +++++++++
 .../search/UserSearchComponentLoad.test.js    | 52 +++++++++++++++++++
 20 files changed, 311 insertions(+), 2 deletions(-)

diff --git a/ui-admin/src/js/common/messages.js b/ui-admin/src/js/common/messages.js
index a50f1b82546..ced30073849 100644
--- a/ui-admin/src/js/common/messages.js
+++ b/ui-admin/src/js/common/messages.js
@@ -141,6 +141,7 @@ const keys = {
   MATERIAL_TYPES: 'MATERIAL_TYPES',
   META_DATA: 'META_DATA',
   MINUTE_OR_MINUTES: 'MINUTE_OR_MINUTES',
+  MODIFICATION_DATE: 'MODIFICATION_DATE',
   MORE: 'MORE',
   NAME: 'NAME',
   NEW_COLLECTION_TYPE: 'NEW_COLLECTION_TYPE',
@@ -436,6 +437,7 @@ const messages_en = {
   [keys.MATERIAL_TYPE]: 'Material Type',
   [keys.META_DATA]: 'Meta Data',
   [keys.MORE]: 'More',
+  [keys.MODIFICATION_DATE]: 'Modification Date',
   [keys.MINUTE_OR_MINUTES]: '${0} minute(s)',
   [keys.NAME]: 'Name',
   [keys.NEW_COLLECTION_TYPE]: 'New Collection Type',
diff --git a/ui-admin/src/js/components/users/common/RolesGrid.jsx b/ui-admin/src/js/components/users/common/RolesGrid.jsx
index 9b5858e162f..2bd9398fb6a 100644
--- a/ui-admin/src/js/components/users/common/RolesGrid.jsx
+++ b/ui-admin/src/js/components/users/common/RolesGrid.jsx
@@ -8,6 +8,7 @@ import UserLink from '@src/js/components/common/link/UserLink.jsx'
 import UserGroupLink from '@src/js/components/common/link/UserGroupLink.jsx'
 import openbis from '@src/js/services/openbis.js'
 import ids from '@src/js/common/consts/ids.js'
+import date from '@src/js/common/date.js'
 import messages from '@src/js/common/messages.js'
 import logger from '@src/js/common/logger.js'
 
@@ -45,6 +46,8 @@ class RolesGrid extends React.PureComponent {
       throw 'Unsupported id: ' + id
     }
 
+    columnNames.push('registrator', 'registrationDate')
+
     const columns = this.getColumns().filter(
       column => columnNames.indexOf(column.name) !== -1
     )
@@ -236,6 +239,20 @@ class RolesGrid extends React.PureComponent {
                 this.compareProjectValue(params))
           )
         }
+      },
+      {
+        name: 'registrator',
+        label: messages.get(messages.REGISTRATOR),
+        getValue: ({ row }) => row.registrator.value,
+        renderValue: ({ value }) => {
+          return <UserLink userId={value} />
+        }
+      },
+      {
+        name: 'registrationDate',
+        label: messages.get(messages.REGISTRATION_DATE),
+        getValue: ({ row }) => date.format(row.registrationDate.value),
+        renderValue: this.renderDefault
       }
     ]
   }
diff --git a/ui-admin/src/js/components/users/common/UserGroupsGrid.jsx b/ui-admin/src/js/components/users/common/UserGroupsGrid.jsx
index 3420e7b6d6f..623b4ed57ec 100644
--- a/ui-admin/src/js/components/users/common/UserGroupsGrid.jsx
+++ b/ui-admin/src/js/components/users/common/UserGroupsGrid.jsx
@@ -2,6 +2,8 @@ import React from 'react'
 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 UserLink from '@src/js/components/common/link/UserLink.jsx'
+import date from '@src/js/common/date.js'
 import messages from '@src/js/common/messages.js'
 import logger from '@src/js/common/logger.js'
 
@@ -36,6 +38,24 @@ export default class GroupsGrid extends React.PureComponent {
             name: 'description',
             label: messages.get(messages.DESCRIPTION),
             getValue: ({ row }) => row.description.value
+          },
+          {
+            name: 'registrator',
+            label: messages.get(messages.REGISTRATOR),
+            getValue: ({ row }) => row.registrator.value,
+            renderValue: ({ value }) => {
+              return <UserLink userId={value} />
+            }
+          },
+          {
+            name: 'registrationDate',
+            label: messages.get(messages.REGISTRATION_DATE),
+            getValue: ({ row }) => date.format(row.registrationDate.value)
+          },
+          {
+            name: 'modificationDate',
+            label: messages.get(messages.MODIFICATION_DATE),
+            getValue: ({ row }) => date.format(row.modificationDate.value)
           }
         ]}
         rows={rows}
diff --git a/ui-admin/src/js/components/users/common/UsersGrid.jsx b/ui-admin/src/js/components/users/common/UsersGrid.jsx
index fc400039c7f..458a0a920c4 100644
--- a/ui-admin/src/js/components/users/common/UsersGrid.jsx
+++ b/ui-admin/src/js/components/users/common/UsersGrid.jsx
@@ -5,6 +5,7 @@ import { withStyles } from '@material-ui/core/styles'
 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 date from '@src/js/common/date.js'
 import messages from '@src/js/common/messages.js'
 import logger from '@src/js/common/logger.js'
 
@@ -63,6 +64,19 @@ class UsersGrid extends React.PureComponent {
             name: 'active',
             label: messages.get(messages.ACTIVE),
             getValue: ({ row }) => row.active.value
+          },
+          {
+            name: 'registrator',
+            label: messages.get(messages.REGISTRATOR),
+            getValue: ({ row }) => row.registrator.value,
+            renderValue: ({ value }) => {
+              return <UserLink userId={value} />
+            }
+          },
+          {
+            name: 'registrationDate',
+            label: messages.get(messages.REGISTRATION_DATE),
+            getValue: ({ row }) => date.format(row.registrationDate.value)
           }
         ]}
         rows={rows}
diff --git a/ui-admin/src/js/components/users/form/common/RoleControllerAdd.js b/ui-admin/src/js/components/users/form/common/RoleControllerAdd.js
index 0dbd7eff971..fcfc754f845 100644
--- a/ui-admin/src/js/components/users/form/common/RoleControllerAdd.js
+++ b/ui-admin/src/js/components/users/form/common/RoleControllerAdd.js
@@ -27,6 +27,12 @@ export default class RoleControllerAdd {
       role: FormUtil.createField({
         visible: false
       }),
+      registrator: FormUtil.createField({
+        visible: false
+      }),
+      registrationDate: FormUtil.createField({
+        visible: false
+      }),
       original: null
     }
 
diff --git a/ui-admin/src/js/components/users/form/common/RoleControllerLoad.js b/ui-admin/src/js/components/users/form/common/RoleControllerLoad.js
index 13b5ec3729f..f85051d21ff 100644
--- a/ui-admin/src/js/components/users/form/common/RoleControllerLoad.js
+++ b/ui-admin/src/js/components/users/form/common/RoleControllerLoad.js
@@ -52,6 +52,12 @@ export default class RoleControllerLoad {
       role: FormUtil.createField({
         value: _.get(loadedRole, 'role', null),
         enabled: inheritedFrom === null
+      }),
+      registrator: FormUtil.createField({
+        value: _.get(loadedRole, 'registrator.userId', null)
+      }),
+      registrationDate: FormUtil.createField({
+        value: _.get(loadedRole, 'registrationDate', null)
       })
     }
     role.original = _.cloneDeep(role)
diff --git a/ui-admin/src/js/components/users/form/user/UserFormControllerAddGroup.js b/ui-admin/src/js/components/users/form/user/UserFormControllerAddGroup.js
index b6faae8702d..077602a9d35 100644
--- a/ui-admin/src/js/components/users/form/user/UserFormControllerAddGroup.js
+++ b/ui-admin/src/js/components/users/form/user/UserFormControllerAddGroup.js
@@ -16,6 +16,9 @@ export default class UserFormControllerAddGroup {
       id: _.uniqueId('group-'),
       code: FormUtil.createField({}),
       description: FormUtil.createField({}),
+      registrator: FormUtil.createField({}),
+      registrationDate: FormUtil.createField({}),
+      modificationDate: FormUtil.createField({}),
       original: null
     }
 
diff --git a/ui-admin/src/js/components/users/form/user/UserFormControllerChange.js b/ui-admin/src/js/components/users/form/user/UserFormControllerChange.js
index ff24b471607..78ade47d241 100644
--- a/ui-admin/src/js/components/users/form/user/UserFormControllerChange.js
+++ b/ui-admin/src/js/components/users/form/user/UserFormControllerChange.js
@@ -75,6 +75,20 @@ export default class UserFormControllerChange extends PageControllerChange {
         description: {
           ...newGroup.description,
           value: groupDefinition.description
+        },
+        registrator: {
+          ...newGroup.registrator,
+          value: groupDefinition.registrator
+            ? groupDefinition.registrator.userId
+            : null
+        },
+        registrationDate: {
+          ...newGroup.registrationDate,
+          value: groupDefinition.registrationDate
+        },
+        modificationDate: {
+          ...newGroup.modificationDate,
+          value: groupDefinition.modificationDate
         }
       })
 
diff --git a/ui-admin/src/js/components/users/form/user/UserFormControllerLoad.js b/ui-admin/src/js/components/users/form/user/UserFormControllerLoad.js
index c03014d728c..93ef5843c16 100644
--- a/ui-admin/src/js/components/users/form/user/UserFormControllerLoad.js
+++ b/ui-admin/src/js/components/users/form/user/UserFormControllerLoad.js
@@ -127,6 +127,15 @@ export default class UserFormControllerLoad extends PageControllerLoad {
       }),
       description: FormUtil.createField({
         value: _.get(loadedGroup, 'description', null)
+      }),
+      registrator: FormUtil.createField({
+        value: _.get(loadedGroup, 'registrator.userId', null)
+      }),
+      registrationDate: FormUtil.createField({
+        value: _.get(loadedGroup, 'registrationDate', null)
+      }),
+      modificationDate: FormUtil.createField({
+        value: _.get(loadedGroup, 'modificationDate', null)
       })
     }
     group.original = _.cloneDeep(group)
diff --git a/ui-admin/src/js/components/users/form/user/UserFormControllerRecalculateInheritedRoles.js b/ui-admin/src/js/components/users/form/user/UserFormControllerRecalculateInheritedRoles.js
index 15f3642045b..dfbc544ea89 100644
--- a/ui-admin/src/js/components/users/form/user/UserFormControllerRecalculateInheritedRoles.js
+++ b/ui-admin/src/js/components/users/form/user/UserFormControllerRecalculateInheritedRoles.js
@@ -60,6 +60,14 @@ export default class UserFormControllerRecalculateInheritedRoles {
           role: FormUtil.createField({
             value: _.get(roleDefinition, 'role'),
             enabled: false
+          }),
+          registrator: FormUtil.createField({
+            value: _.get(roleDefinition, 'registrator.userId'),
+            enabled: false
+          }),
+          registrationDate: FormUtil.createField({
+            value: _.get(roleDefinition, 'registrationDate'),
+            enabled: false
           })
         }
 
diff --git a/ui-admin/src/js/components/users/form/user/UserFormFacade.js b/ui-admin/src/js/components/users/form/user/UserFormFacade.js
index 6a069b96ffb..a89e689bd5d 100644
--- a/ui-admin/src/js/components/users/form/user/UserFormFacade.js
+++ b/ui-admin/src/js/components/users/form/user/UserFormFacade.js
@@ -8,6 +8,7 @@ export default class UserFormFacade {
     fo.withRoleAssignments().withAuthorizationGroup()
     fo.withRoleAssignments().withSpace()
     fo.withRoleAssignments().withProject().withSpace()
+    fo.withRoleAssignments().withRegistrator()
     return openbis.getPersons([id], fo).then(map => {
       return map[userId]
     })
@@ -17,9 +18,11 @@ export default class UserFormFacade {
     const criteria = new openbis.AuthorizationGroupSearchCriteria()
     const fo = new openbis.AuthorizationGroupFetchOptions()
     fo.withUsers()
+    fo.withRegistrator()
     fo.withRoleAssignments().withAuthorizationGroup()
     fo.withRoleAssignments().withSpace()
     fo.withRoleAssignments().withProject().withSpace()
+    fo.withRoleAssignments().withRegistrator()
     return openbis.searchAuthorizationGroups(criteria, fo).then(result => {
       return result.getObjects().filter(group => {
         return group.getUsers().some(user => {
@@ -32,9 +35,11 @@ export default class UserFormFacade {
   async loadGroups() {
     const criteria = new openbis.AuthorizationGroupSearchCriteria()
     const fo = new openbis.AuthorizationGroupFetchOptions()
+    fo.withRegistrator()
     fo.withRoleAssignments().withAuthorizationGroup()
     fo.withRoleAssignments().withSpace()
     fo.withRoleAssignments().withProject().withSpace()
+    fo.withRoleAssignments().withRegistrator()
     return openbis.searchAuthorizationGroups(criteria, fo).then(result => {
       return result.getObjects()
     })
diff --git a/ui-admin/src/js/components/users/form/usergroup/UserGroupFormControllerAddUser.js b/ui-admin/src/js/components/users/form/usergroup/UserGroupFormControllerAddUser.js
index 4459acf6fc5..9e232700dee 100644
--- a/ui-admin/src/js/components/users/form/usergroup/UserGroupFormControllerAddUser.js
+++ b/ui-admin/src/js/components/users/form/usergroup/UserGroupFormControllerAddUser.js
@@ -20,6 +20,8 @@ export default class UserGroupFormControllerAddUser {
       email: FormUtil.createField({}),
       space: FormUtil.createField({}),
       active: FormUtil.createField({}),
+      registrator: FormUtil.createField({}),
+      registrationDate: FormUtil.createField({}),
       original: null
     }
 
diff --git a/ui-admin/src/js/components/users/form/usergroup/UserGroupFormControllerChange.js b/ui-admin/src/js/components/users/form/usergroup/UserGroupFormControllerChange.js
index ff765ec4901..ae38b774234 100644
--- a/ui-admin/src/js/components/users/form/usergroup/UserGroupFormControllerChange.js
+++ b/ui-admin/src/js/components/users/form/usergroup/UserGroupFormControllerChange.js
@@ -84,6 +84,14 @@ export default class UserGroupFormControllerChange extends PageControllerChange
         active: {
           ...newUser.active,
           value: user.active
+        },
+        registrator: {
+          ...newUser.registrator,
+          value: user.registrator ? user.registrator.userId : null
+        },
+        registrationDate: {
+          ...newUser.registrationDate,
+          value: user.registrationDate
         }
       })
     }
diff --git a/ui-admin/src/js/components/users/form/usergroup/UserGroupFormControllerLoad.js b/ui-admin/src/js/components/users/form/usergroup/UserGroupFormControllerLoad.js
index 6445e6935d8..2882cacc7d6 100644
--- a/ui-admin/src/js/components/users/form/usergroup/UserGroupFormControllerLoad.js
+++ b/ui-admin/src/js/components/users/form/usergroup/UserGroupFormControllerLoad.js
@@ -109,6 +109,12 @@ export default class UserGroupFormControllerLoad extends PageControllerLoad {
       }),
       active: FormUtil.createField({
         value: _.get(loadedUser, 'active', null)
+      }),
+      registrator: FormUtil.createField({
+        value: _.get(loadedUser, 'registrator.userId', null)
+      }),
+      registrationDate: FormUtil.createField({
+        value: _.get(loadedUser, 'registrationDate', null)
       })
     }
     user.original = _.cloneDeep(user)
diff --git a/ui-admin/src/js/components/users/form/usergroup/UserGroupFormFacade.js b/ui-admin/src/js/components/users/form/usergroup/UserGroupFormFacade.js
index f4b6db3a95d..7dc9c20b9ec 100644
--- a/ui-admin/src/js/components/users/form/usergroup/UserGroupFormFacade.js
+++ b/ui-admin/src/js/components/users/form/usergroup/UserGroupFormFacade.js
@@ -5,8 +5,10 @@ export default class UserGroupFormFacade {
     const id = new openbis.AuthorizationGroupPermId(groupCode)
     const fo = new openbis.AuthorizationGroupFetchOptions()
     fo.withUsers().withSpace()
+    fo.withUsers().withRegistrator()
     fo.withRoleAssignments().withSpace()
     fo.withRoleAssignments().withProject().withSpace()
+    fo.withRoleAssignments().withRegistrator()
     return openbis.getAuthorizationGroups([id], fo).then(map => {
       return map[groupCode]
     })
@@ -16,6 +18,7 @@ export default class UserGroupFormFacade {
     const criteria = new openbis.PersonSearchCriteria()
     const fo = new openbis.PersonFetchOptions()
     fo.withSpace()
+    fo.withRegistrator()
     return openbis.searchPersons(criteria, fo).then(result => {
       return result.getObjects()
     })
diff --git a/ui-admin/src/js/components/users/search/UserSearch.jsx b/ui-admin/src/js/components/users/search/UserSearch.jsx
index a362a8f616b..5e7e41315f2 100644
--- a/ui-admin/src/js/components/users/search/UserSearch.jsx
+++ b/ui-admin/src/js/components/users/search/UserSearch.jsx
@@ -65,6 +65,7 @@ class UserSearch extends React.Component {
 
     const fo = new openbis.PersonFetchOptions()
     fo.withSpace()
+    fo.withRegistrator()
 
     const result = await openbis.searchPersons(
       new openbis.PersonSearchCriteria(),
@@ -80,7 +81,13 @@ class UserSearch extends React.Component {
         lastName: FormUtil.createField({ value: _.get(object, 'lastName') }),
         email: FormUtil.createField({ value: _.get(object, 'email') }),
         space: FormUtil.createField({ value: _.get(object, 'space.code') }),
-        active: FormUtil.createField({ value: _.get(object, 'active') })
+        active: FormUtil.createField({ value: _.get(object, 'active') }),
+        registrator: FormUtil.createField({
+          value: _.get(object, 'registrator.userId')
+        }),
+        registrationDate: FormUtil.createField({
+          value: _.get(object, 'registrationDate')
+        })
       }))
 
     this.setState({
@@ -96,11 +103,13 @@ class UserSearch extends React.Component {
     const userFo = new openbis.PersonFetchOptions()
     userFo.withRoleAssignments().withSpace()
     userFo.withRoleAssignments().withProject().withSpace()
+    userFo.withRoleAssignments().withRegistrator()
 
     const groupFo = new openbis.AuthorizationGroupFetchOptions()
     groupFo.withUsers()
     groupFo.withRoleAssignments().withSpace()
     groupFo.withRoleAssignments().withProject().withSpace()
+    groupFo.withRoleAssignments().withRegistrator()
 
     const [userResult, groupResult] = await Promise.all([
       openbis.searchPersons(new openbis.PersonSearchCriteria(), userFo),
@@ -143,6 +152,12 @@ class UserSearch extends React.Component {
             project: FormUtil.createField({ value: project }),
             role: FormUtil.createField({
               value: _.get(userAssignment, 'role', null)
+            }),
+            registrator: FormUtil.createField({
+              value: _.get(userAssignment, 'registrator.userId')
+            }),
+            registrationDate: FormUtil.createField({
+              value: _.get(userAssignment, 'registrationDate')
             })
           })
         })
@@ -184,6 +199,12 @@ class UserSearch extends React.Component {
             project: FormUtil.createField({ value: project }),
             role: FormUtil.createField({
               value: _.get(groupAssignment, 'role', null)
+            }),
+            registrator: FormUtil.createField({
+              value: _.get(groupAssignment, 'registrator.userId')
+            }),
+            registrationDate: FormUtil.createField({
+              value: _.get(groupAssignment, 'registrationDate')
             })
           })
         })
@@ -200,9 +221,12 @@ class UserSearch extends React.Component {
       return
     }
 
+    const fo = new openbis.AuthorizationGroupFetchOptions()
+    fo.withRegistrator()
+
     const result = await openbis.searchAuthorizationGroups(
       new openbis.AuthorizationGroupSearchCriteria(),
-      new openbis.AuthorizationGroupFetchOptions()
+      fo
     )
 
     const userGroups = util
@@ -212,6 +236,15 @@ class UserSearch extends React.Component {
         code: FormUtil.createField({ value: _.get(object, 'code') }),
         description: FormUtil.createField({
           value: _.get(object, 'description')
+        }),
+        registrator: FormUtil.createField({
+          value: _.get(object, 'registrator.userId')
+        }),
+        registrationDate: FormUtil.createField({
+          value: _.get(object, 'registrationDate')
+        }),
+        modificationDate: FormUtil.createField({
+          value: _.get(object, 'modificationDate')
         })
       }))
 
@@ -228,6 +261,7 @@ class UserSearch extends React.Component {
     const fo = new openbis.AuthorizationGroupFetchOptions()
     fo.withRoleAssignments().withSpace()
     fo.withRoleAssignments().withProject().withSpace()
+    fo.withRoleAssignments().withRegistrator()
 
     const result = await openbis.searchAuthorizationGroups(
       new openbis.AuthorizationGroupSearchCriteria(),
@@ -266,6 +300,12 @@ class UserSearch extends React.Component {
           project: FormUtil.createField({ value: project }),
           role: FormUtil.createField({
             value: _.get(roleAssignment, 'role', null)
+          }),
+          registrator: FormUtil.createField({
+            value: _.get(roleAssignment, 'registrator.userId')
+          }),
+          registrationDate: FormUtil.createField({
+            value: _.get(roleAssignment, 'registrationDate')
           })
         })
       })
diff --git a/ui-admin/srcTest/js/components/users/form/user/UserFormComponentLoad.test.js b/ui-admin/srcTest/js/components/users/form/user/UserFormComponentLoad.test.js
index f158187895f..cc9d1d98ade 100644
--- a/ui-admin/srcTest/js/components/users/form/user/UserFormComponentLoad.test.js
+++ b/ui-admin/srcTest/js/components/users/form/user/UserFormComponentLoad.test.js
@@ -109,6 +109,24 @@ async function testLoadExisting() {
         label: 'Description',
         filter: null,
         sort: null
+      },
+      {
+        name: 'registrator',
+        label: 'Registrator',
+        filter: null,
+        sort: null
+      },
+      {
+        name: 'registrationDate',
+        label: 'Registration Date',
+        filter: null,
+        sort: null
+      },
+      {
+        name: 'modificationDate',
+        label: 'Modification Date',
+        filter: null,
+        sort: null
       }
     ],
     rows: [
@@ -155,6 +173,18 @@ async function testLoadExisting() {
         label: 'Role',
         filter: null,
         sort: null
+      },
+      {
+        name: 'registrator',
+        label: 'Registrator',
+        filter: null,
+        sort: null
+      },
+      {
+        name: 'registrationDate',
+        label: 'Registration Date',
+        filter: null,
+        sort: null
       }
     ],
     rows: [
diff --git a/ui-admin/srcTest/js/components/users/form/user/UserFormComponentSortRoles.test.js b/ui-admin/srcTest/js/components/users/form/user/UserFormComponentSortRoles.test.js
index 596fd36c5e4..2828a4d4436 100644
--- a/ui-admin/srcTest/js/components/users/form/user/UserFormComponentSortRoles.test.js
+++ b/ui-admin/srcTest/js/components/users/form/user/UserFormComponentSortRoles.test.js
@@ -126,6 +126,14 @@ async function testSortRoles() {
         {
           name: 'role',
           sort: null
+        },
+        {
+          name: 'registrator',
+          sort: null
+        },
+        {
+          name: 'registrationDate',
+          sort: null
         }
       ],
       rows: [
@@ -164,6 +172,14 @@ async function testSortRoles() {
         {
           name: 'role',
           sort: null
+        },
+        {
+          name: 'registrator',
+          sort: null
+        },
+        {
+          name: 'registrationDate',
+          sort: null
         }
       ],
       rows: [
@@ -202,6 +218,14 @@ async function testSortRoles() {
         {
           name: 'role',
           sort: null
+        },
+        {
+          name: 'registrator',
+          sort: null
+        },
+        {
+          name: 'registrationDate',
+          sort: null
         }
       ],
       rows: [
@@ -240,6 +264,14 @@ async function testSortRoles() {
         {
           name: 'role',
           sort: null
+        },
+        {
+          name: 'registrator',
+          sort: null
+        },
+        {
+          name: 'registrationDate',
+          sort: null
         }
       ],
       rows: [
@@ -278,6 +310,14 @@ async function testSortRoles() {
         {
           name: 'role',
           sort: 'asc'
+        },
+        {
+          name: 'registrator',
+          sort: null
+        },
+        {
+          name: 'registrationDate',
+          sort: null
         }
       ],
       rows: [
diff --git a/ui-admin/srcTest/js/components/users/form/usergroup/UserGroupFormComponentLoad.test.js b/ui-admin/srcTest/js/components/users/form/usergroup/UserGroupFormComponentLoad.test.js
index f2895757f2e..cceb40940ed 100644
--- a/ui-admin/srcTest/js/components/users/form/usergroup/UserGroupFormComponentLoad.test.js
+++ b/ui-admin/srcTest/js/components/users/form/usergroup/UserGroupFormComponentLoad.test.js
@@ -120,6 +120,18 @@ async function testLoadExisting() {
         label: 'Active',
         filter: null,
         sort: null
+      },
+      {
+        name: 'registrator',
+        label: 'Registrator',
+        filter: null,
+        sort: null
+      },
+      {
+        name: 'registrationDate',
+        label: 'Registration Date',
+        filter: null,
+        sort: null
       }
     ],
     rows: [inactiveUser, mySpaceUser, testSpaceUser].map(user => ({
@@ -160,6 +172,18 @@ async function testLoadExisting() {
         label: 'Role',
         filter: null,
         sort: null
+      },
+      {
+        name: 'registrator',
+        label: 'Registrator',
+        filter: null,
+        sort: null
+      },
+      {
+        name: 'registrationDate',
+        label: 'Registration Date',
+        filter: null,
+        sort: null
       }
     ],
     rows: [
diff --git a/ui-admin/srcTest/js/components/users/search/UserSearchComponentLoad.test.js b/ui-admin/srcTest/js/components/users/search/UserSearchComponentLoad.test.js
index 9b30b114408..b481693130d 100644
--- a/ui-admin/srcTest/js/components/users/search/UserSearchComponentLoad.test.js
+++ b/ui-admin/srcTest/js/components/users/search/UserSearchComponentLoad.test.js
@@ -70,6 +70,14 @@ async function testLoadWithSearchText(resultsFound) {
           {
             name: 'active',
             label: 'Active'
+          },
+          {
+            name: 'registrator',
+            label: 'Registrator'
+          },
+          {
+            name: 'registrationDate',
+            label: 'Registration Date'
           }
         ],
         rows: [
@@ -120,6 +128,14 @@ async function testLoadWithSearchText(resultsFound) {
           {
             label: 'Role',
             name: 'role'
+          },
+          {
+            name: 'registrator',
+            label: 'Registrator'
+          },
+          {
+            name: 'registrationDate',
+            label: 'Registration Date'
           }
         ],
         rows: [
@@ -184,6 +200,18 @@ async function testLoadWithSearchText(resultsFound) {
           {
             name: 'description',
             label: 'Description'
+          },
+          {
+            name: 'registrator',
+            label: 'Registrator'
+          },
+          {
+            name: 'registrationDate',
+            label: 'Registration Date'
+          },
+          {
+            name: 'modificationDate',
+            label: 'Modification Date'
           }
         ],
         rows: [
@@ -216,6 +244,14 @@ async function testLoadWithSearchText(resultsFound) {
           {
             label: 'Role',
             name: 'role'
+          },
+          {
+            name: 'registrator',
+            label: 'Registrator'
+          },
+          {
+            name: 'registrationDate',
+            label: 'Registration Date'
           }
         ],
         rows: [
@@ -298,6 +334,14 @@ async function testLoadWithObjectType(resultsFound) {
         {
           name: 'active',
           label: 'Active'
+        },
+        {
+          name: 'registrator',
+          label: 'Registrator'
+        },
+        {
+          name: 'registrationDate',
+          label: 'Registration Date'
         }
       ],
       rows: resultsFound
@@ -360,6 +404,14 @@ async function testLoadWithObjectType(resultsFound) {
         {
           label: 'Role',
           name: 'role'
+        },
+        {
+          name: 'registrator',
+          label: 'Registrator'
+        },
+        {
+          name: 'registrationDate',
+          label: 'Registration Date'
         }
       ],
       rows: resultsFound
-- 
GitLab