From 1000400c68d964dac22b2e54351b6ecf147d0444 Mon Sep 17 00:00:00 2001
From: pkupczyk <piotr.kupczyk@id.ethz.ch>
Date: Tue, 12 Oct 2021 13:28:56 +0200
Subject: [PATCH] SSDM-11664 : NG UI & ELN : common table widget - make the
 Grid independent from openbis facade (provide hooks for loading and saving
 settings)

---
 .../components/common/grid/GridController.js  | 72 +++++-------------
 .../common/grid/GridWithSettings.jsx          | 62 +++++++++++++++
 .../src/js/components/common/grid/index.js    |  4 -
 .../components/tools/common/HistoryGrid.jsx   |  9 +--
 .../components/tools/common/PluginsGrid.jsx   | 10 +--
 .../components/tools/common/QueriesGrid.jsx   | 10 +--
 .../js/components/types/common/TypesGrid.jsx  | 10 +--
 .../types/common/VocabulariesGrid.jsx         | 10 +--
 .../components/types/form/VocabularyForm.jsx  |  9 +--
 .../js/components/users/common/RolesGrid.jsx  |  9 +--
 .../users/common/UserGroupsGrid.jsx           | 10 +--
 .../js/components/users/common/UsersGrid.jsx  | 10 +--
 .../js/views/DataGrid/DataGridController2.js  | 76 +++++++++++++------
 13 files changed, 157 insertions(+), 144 deletions(-)
 create mode 100644 openbis_ng_ui/src/js/components/common/grid/GridWithSettings.jsx

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 77df0ebb3d5..cab7d051f80 100644
--- a/openbis_ng_ui/src/js/components/common/grid/GridController.js
+++ b/openbis_ng_ui/src/js/components/common/grid/GridController.js
@@ -1,6 +1,5 @@
 import _ from 'lodash'
 import autoBind from 'auto-bind'
-import openbis from '@src/js/services/openbis.js'
 import compare from '@src/js/common/compare.js'
 
 export default class GridController {
@@ -313,68 +312,31 @@ export default class GridController {
   }
 
   async _loadSettings() {
-    const props = this.context.getProps()
+    const { loadSettings } = this.context.getProps()
 
-    if (
-      !props.settingsId ||
-      !props.settingsId.webAppId ||
-      !props.settingsId.gridId
-    ) {
-      return Promise.resolve()
+    if (loadSettings) {
+      return await loadSettings()
+    } else {
+      return null
     }
-
-    let id = new openbis.Me()
-    let fo = new openbis.PersonFetchOptions()
-    fo.withWebAppSettings(props.settingsId.webAppId).withAllSettings()
-
-    return openbis.getPersons([id], fo).then(map => {
-      let person = map[id]
-      let webAppSettings = person.webAppSettings[props.settingsId.webAppId]
-      if (webAppSettings && webAppSettings.settings) {
-        let gridSettings = webAppSettings.settings[props.settingsId.gridId]
-        if (gridSettings) {
-          let settings = JSON.parse(gridSettings.value)
-          if (settings) {
-            return settings
-          } else {
-            return {}
-          }
-        }
-      }
-    })
   }
 
   async _saveSettings() {
-    const props = this.context.getProps()
-    const state = this.context.getState()
+    const { onSettingsChange } = this.context.getProps()
 
-    if (
-      !props.settingsId ||
-      !props.settingsId.webAppId ||
-      !props.settingsId.gridId
-    ) {
-      throw new Error(
-        'Incorrect grid component usage. Settings id is missing. Please contact a developer.'
-      )
-    }
+    if (onSettingsChange) {
+      const state = this.context.getState()
 
-    let settings = {
-      pageSize: state.pageSize,
-      sort: state.sort,
-      sortDirection: state.sortDirection,
-      columnsVisibility: state.columnsVisibility,
-      columnsSorting: state.columnsSorting
-    }
-
-    let gridSettings = new openbis.WebAppSettingCreation()
-    gridSettings.setName(props.settingsId.gridId)
-    gridSettings.setValue(JSON.stringify(settings))
-
-    let update = new openbis.PersonUpdate()
-    update.setUserId(new openbis.Me())
-    update.getWebAppSettings(props.settingsId.webAppId).add(gridSettings)
+      let settings = {
+        pageSize: state.pageSize,
+        sort: state.sort,
+        sortDirection: state.sortDirection,
+        columnsVisibility: state.columnsVisibility,
+        columnsSorting: state.columnsSorting
+      }
 
-    await openbis.updatePersons([update])
+      onSettingsChange(settings)
+    }
   }
 
   _filterRows(rows, columns, filters) {
diff --git a/openbis_ng_ui/src/js/components/common/grid/GridWithSettings.jsx b/openbis_ng_ui/src/js/components/common/grid/GridWithSettings.jsx
new file mode 100644
index 00000000000..5e1ef524efb
--- /dev/null
+++ b/openbis_ng_ui/src/js/components/common/grid/GridWithSettings.jsx
@@ -0,0 +1,62 @@
+import React from 'react'
+import autoBind from 'auto-bind'
+import Grid from '@src/js/components/common/grid/Grid.jsx'
+import openbis from '@src/js/services/openbis.js'
+import ids from '@src/js/common/consts/ids.js'
+import logger from '@src/js/common/logger.js'
+
+export default class GridWithSettings extends React.PureComponent {
+  constructor(props) {
+    super(props)
+    autoBind(this)
+
+    if (!props.id) {
+      throw new Error('Grid id cannot be empty!')
+    }
+  }
+
+  render() {
+    logger.log(logger.DEBUG, 'GridWithSettings.render')
+    return (
+      <Grid
+        {...this.props}
+        loadSettings={this.loadSettings}
+        onSettingsChange={this.onSettingsChange}
+      />
+    )
+  }
+
+  async loadSettings() {
+    const id = new openbis.Me()
+    const fo = new openbis.PersonFetchOptions()
+    fo.withWebAppSettings(ids.WEB_APP_ID).withAllSettings()
+
+    return openbis.getPersons([id], fo).then(map => {
+      const person = map[id]
+      const webAppSettings = person.webAppSettings[ids.WEB_APP_ID]
+      if (webAppSettings && webAppSettings.settings) {
+        let gridSettings = webAppSettings.settings[this.props.id]
+        if (gridSettings) {
+          let settings = JSON.parse(gridSettings.value)
+          if (settings) {
+            return settings
+          } else {
+            return null
+          }
+        }
+      }
+    })
+  }
+
+  async onSettingsChange(settings) {
+    const gridSettings = new openbis.WebAppSettingCreation()
+    gridSettings.setName(this.props.id)
+    gridSettings.setValue(JSON.stringify(settings))
+
+    const update = new openbis.PersonUpdate()
+    update.setUserId(new openbis.Me())
+    update.getWebAppSettings(ids.WEB_APP_ID).add(gridSettings)
+
+    await openbis.updatePersons([update])
+  }
+}
diff --git a/openbis_ng_ui/src/js/components/common/grid/index.js b/openbis_ng_ui/src/js/components/common/grid/index.js
index 11d76905ec9..994f8f6c65a 100644
--- a/openbis_ng_ui/src/js/components/common/grid/index.js
+++ b/openbis_ng_ui/src/js/components/common/grid/index.js
@@ -1,13 +1,9 @@
-import openbis from '@src/js/services/openbis.js'
 import ThemeProvider from '@src/js/components/common/theme/ThemeProvider.jsx'
 import Grid from '@src/js/components/common/grid/Grid.jsx'
-import SelectField from '@src/js/components/common/form/SelectField.jsx'
 import Loading from '@src/js/components/common/loading/Loading.jsx'
 
 export default {
-  openbis,
   ThemeProvider,
   Grid,
-  SelectField,
   Loading
 }
diff --git a/openbis_ng_ui/src/js/components/tools/common/HistoryGrid.jsx b/openbis_ng_ui/src/js/components/tools/common/HistoryGrid.jsx
index 10b38cd68d5..f07e560b8b8 100644
--- a/openbis_ng_ui/src/js/components/tools/common/HistoryGrid.jsx
+++ b/openbis_ng_ui/src/js/components/tools/common/HistoryGrid.jsx
@@ -1,7 +1,7 @@
 import _ from 'lodash'
 import React from 'react'
 import autoBind from 'auto-bind'
-import Grid from '@src/js/components/common/grid/Grid.jsx'
+import GridWithSettings from '@src/js/components/common/grid/GridWithSettings.jsx'
 import UserLink from '@src/js/components/common/link/UserLink.jsx'
 import SelectField from '@src/js/components/common/form/SelectField.jsx'
 import DateRangeField from '@src/js/components/common/form/DateRangeField.jsx'
@@ -121,11 +121,8 @@ class HistoryGrid extends React.PureComponent {
     logger.log(logger.DEBUG, 'HistoryGrid.render')
 
     return (
-      <Grid
-        settingsId={{
-          webAppId: ids.WEB_APP_ID,
-          gridId: this.getId()
-        }}
+      <GridWithSettings
+        id={this.getId()}
         header={this.getHeader()}
         columns={[
           {
diff --git a/openbis_ng_ui/src/js/components/tools/common/PluginsGrid.jsx b/openbis_ng_ui/src/js/components/tools/common/PluginsGrid.jsx
index 97cdee1ac48..c9e527c5c6f 100644
--- a/openbis_ng_ui/src/js/components/tools/common/PluginsGrid.jsx
+++ b/openbis_ng_ui/src/js/components/tools/common/PluginsGrid.jsx
@@ -1,10 +1,9 @@
 import React from 'react'
-import Grid from '@src/js/components/common/grid/Grid.jsx'
+import GridWithSettings from '@src/js/components/common/grid/GridWithSettings.jsx'
 import PluginLink from '@src/js/components/common/link/PluginLink.jsx'
 import UserLink from '@src/js/components/common/link/UserLink.jsx'
 import EntityKind from '@src/js/components/common/dto/EntityKind.js'
 import openbis from '@src/js/services/openbis.js'
-import ids from '@src/js/common/consts/ids.js'
 import messages from '@src/js/common/messages.js'
 import logger from '@src/js/common/logger.js'
 
@@ -22,11 +21,8 @@ class PluginsGrid extends React.PureComponent {
     } = this.props
 
     return (
-      <Grid
-        settingsId={{
-          webAppId: ids.WEB_APP_ID,
-          gridId: id
-        }}
+      <GridWithSettings
+        id={id}
         controllerRef={controllerRef}
         header={this.getHeader()}
         columns={[
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 4a085d75248..66857129693 100644
--- a/openbis_ng_ui/src/js/components/tools/common/QueriesGrid.jsx
+++ b/openbis_ng_ui/src/js/components/tools/common/QueriesGrid.jsx
@@ -1,9 +1,8 @@
 import React from 'react'
-import Grid from '@src/js/components/common/grid/Grid.jsx'
+import GridWithSettings from '@src/js/components/common/grid/GridWithSettings.jsx'
 import QueryLink from '@src/js/components/common/link/QueryLink.jsx'
 import UserLink from '@src/js/components/common/link/UserLink.jsx'
 import QueryType from '@src/js/components/common/dto/QueryType.js'
-import ids from '@src/js/common/consts/ids.js'
 import messages from '@src/js/common/messages.js'
 import logger from '@src/js/common/logger.js'
 
@@ -15,11 +14,8 @@ class QueriesGrid extends React.PureComponent {
       this.props
 
     return (
-      <Grid
-        settingsId={{
-          webAppId: ids.WEB_APP_ID,
-          gridId: id
-        }}
+      <GridWithSettings
+        id={id}
         controllerRef={controllerRef}
         header={messages.get(messages.QUERIES)}
         columns={[
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 d3e00a83524..edc7dcceff8 100644
--- a/openbis_ng_ui/src/js/components/types/common/TypesGrid.jsx
+++ b/openbis_ng_ui/src/js/components/types/common/TypesGrid.jsx
@@ -1,9 +1,8 @@
 import React from 'react'
-import Grid from '@src/js/components/common/grid/Grid.jsx'
+import GridWithSettings from '@src/js/components/common/grid/GridWithSettings.jsx'
 import TypeLink from '@src/js/components/common/link/TypeLink.jsx'
 import PluginLink from '@src/js/components/common/link/PluginLink.jsx'
 import openbis from '@src/js/services/openbis.js'
-import ids from '@src/js/common/consts/ids.js'
 import messages from '@src/js/common/messages.js'
 import logger from '@src/js/common/logger.js'
 
@@ -15,11 +14,8 @@ class TypesGrid extends React.PureComponent {
       this.props
 
     return (
-      <Grid
-        settingsId={{
-          webAppId: ids.WEB_APP_ID,
-          gridId: id
-        }}
+      <GridWithSettings
+        id={id}
         controllerRef={controllerRef}
         header={this.getHeader()}
         columns={this.getColumns()}
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 a3134d96bf8..ec05b05efb7 100644
--- a/openbis_ng_ui/src/js/components/types/common/VocabulariesGrid.jsx
+++ b/openbis_ng_ui/src/js/components/types/common/VocabulariesGrid.jsx
@@ -1,7 +1,6 @@
 import React from 'react'
-import Grid from '@src/js/components/common/grid/Grid.jsx'
+import GridWithSettings from '@src/js/components/common/grid/GridWithSettings.jsx'
 import VocabularyLink from '@src/js/components/common/link/VocabularyLink.jsx'
-import ids from '@src/js/common/consts/ids.js'
 import messages from '@src/js/common/messages.js'
 import logger from '@src/js/common/logger.js'
 
@@ -13,11 +12,8 @@ class VocabulariesGrid extends React.PureComponent {
       this.props
 
     return (
-      <Grid
-        settingsId={{
-          webAppId: ids.WEB_APP_ID,
-          gridId: id
-        }}
+      <GridWithSettings
+        id={id}
         controllerRef={controllerRef}
         header={messages.get(messages.VOCABULARY_TYPES)}
         columns={[
diff --git a/openbis_ng_ui/src/js/components/types/form/VocabularyForm.jsx b/openbis_ng_ui/src/js/components/types/form/VocabularyForm.jsx
index 1f41d359060..a4e4009da27 100644
--- a/openbis_ng_ui/src/js/components/types/form/VocabularyForm.jsx
+++ b/openbis_ng_ui/src/js/components/types/form/VocabularyForm.jsx
@@ -5,7 +5,7 @@ import { connect } from 'react-redux'
 import { withStyles } from '@material-ui/core/styles'
 import ComponentContext from '@src/js/components/common/ComponentContext.js'
 import PageWithTwoPanels from '@src/js/components/common/page/PageWithTwoPanels.jsx'
-import Grid from '@src/js/components/common/grid/Grid.jsx'
+import GridWithSettings from '@src/js/components/common/grid/GridWithSettings.jsx'
 import GridContainer from '@src/js/components/common/grid/GridContainer.jsx'
 import VocabularyFormSelectionType from '@src/js/components/types/form/VocabularyFormSelectionType.js'
 import VocabularyFormController from '@src/js/components/types/form/VocabularyFormController.js'
@@ -111,11 +111,8 @@ class VocabularyForm extends React.PureComponent {
 
     return (
       <GridContainer onClick={this.handleClickContainer}>
-        <Grid
-          settingsId={{
-            webAppId: ids.WEB_APP_ID,
-            gridId: ids.VOCABULARY_TERMS_GRID_ID
-          }}
+        <GridWithSettings
+          id={ids.VOCABULARY_TERMS_GRID_ID}
           controllerRef={this.handleGridControllerRef}
           header={messages.get(messages.TERMS)}
           columns={columns}
diff --git a/openbis_ng_ui/src/js/components/users/common/RolesGrid.jsx b/openbis_ng_ui/src/js/components/users/common/RolesGrid.jsx
index f39ba9591f6..5f4e6c87600 100644
--- a/openbis_ng_ui/src/js/components/users/common/RolesGrid.jsx
+++ b/openbis_ng_ui/src/js/components/users/common/RolesGrid.jsx
@@ -2,7 +2,7 @@ import _ from 'lodash'
 import React from 'react'
 import autoBind from 'auto-bind'
 import { withStyles } from '@material-ui/core/styles'
-import Grid from '@src/js/components/common/grid/Grid.jsx'
+import GridWithSettings from '@src/js/components/common/grid/GridWithSettings.jsx'
 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'
@@ -49,11 +49,8 @@ class RolesGrid extends React.PureComponent {
     )
 
     return (
-      <Grid
-        settingsId={{
-          webAppId: ids.WEB_APP_ID,
-          gridId: id
-        }}
+      <GridWithSettings
+        id={id}
         controllerRef={controllerRef}
         header={this.getHeader()}
         columns={columns}
diff --git a/openbis_ng_ui/src/js/components/users/common/UserGroupsGrid.jsx b/openbis_ng_ui/src/js/components/users/common/UserGroupsGrid.jsx
index fd8cbc8f233..f1cd0e895d0 100644
--- a/openbis_ng_ui/src/js/components/users/common/UserGroupsGrid.jsx
+++ b/openbis_ng_ui/src/js/components/users/common/UserGroupsGrid.jsx
@@ -1,7 +1,6 @@
 import React from 'react'
-import Grid from '@src/js/components/common/grid/Grid.jsx'
+import GridWithSettings from '@src/js/components/common/grid/GridWithSettings.jsx'
 import UserGroupLink from '@src/js/components/common/link/UserGroupLink.jsx'
-import ids from '@src/js/common/consts/ids.js'
 import messages from '@src/js/common/messages.js'
 import logger from '@src/js/common/logger.js'
 
@@ -13,11 +12,8 @@ export default class GroupsGrid extends React.PureComponent {
       this.props
 
     return (
-      <Grid
-        settingsId={{
-          webAppId: ids.WEB_APP_ID,
-          gridId: id
-        }}
+      <GridWithSettings
+        id={id}
         controllerRef={controllerRef}
         header={messages.get(messages.GROUPS)}
         columns={[
diff --git a/openbis_ng_ui/src/js/components/users/common/UsersGrid.jsx b/openbis_ng_ui/src/js/components/users/common/UsersGrid.jsx
index 049f9eaed5b..cba69b3b869 100644
--- a/openbis_ng_ui/src/js/components/users/common/UsersGrid.jsx
+++ b/openbis_ng_ui/src/js/components/users/common/UsersGrid.jsx
@@ -2,9 +2,8 @@ import _ from 'lodash'
 import React from 'react'
 import autoBind from 'auto-bind'
 import { withStyles } from '@material-ui/core/styles'
-import Grid from '@src/js/components/common/grid/Grid.jsx'
+import GridWithSettings from '@src/js/components/common/grid/GridWithSettings.jsx'
 import UserLink from '@src/js/components/common/link/UserLink.jsx'
-import ids from '@src/js/common/consts/ids.js'
 import messages from '@src/js/common/messages.js'
 import logger from '@src/js/common/logger.js'
 
@@ -23,11 +22,8 @@ class UsersGrid extends React.PureComponent {
       this.props
 
     return (
-      <Grid
-        settingsId={{
-          webAppId: ids.WEB_APP_ID,
-          gridId: id
-        }}
+      <GridWithSettings
+        id={id}
         controllerRef={controllerRef}
         header={messages.get(messages.USERS)}
         columns={[
diff --git a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/DataGrid/DataGridController2.js b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/DataGrid/DataGridController2.js
index a91bdc72511..8e4f3eff271 100644
--- a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/DataGrid/DataGridController2.js
+++ b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/DataGrid/DataGridController2.js
@@ -50,32 +50,47 @@ function DataGridController2(
   };
 
   this._init = function (session, $container, extraOptions) {
-    var openbis = window.NgUiGrid.default.openbis;
-    openbis.init().then(function () {
-      openbis.useSession(session);
-      var GridElement = React.createElement(
-        window.NgUiGrid.default.ThemeProvider,
-        {},
-        React.createElement(window.NgUiGrid.default.Grid, {
-          settingsId: {
-            webAppId: "ELN-LIMS",
-            gridId: _this.gridId,
-          },
-          controllerRef: function (controller) {
-            _this.controller = controller;
-          },
-          header: _this.header,
-          loadColumns: _this._loadColumns,
-          loadRows: _this._loadRows,
-          onSelectedRowChange: function (selectedRow) {
-            if (rowClickEventHandler) {
-              rowClickEventHandler(selectedRow);
-            }
-          },
-        })
-      );
+    var GridElement = React.createElement(
+      window.NgUiGrid.default.ThemeProvider,
+      {},
+      React.createElement(window.NgUiGrid.default.Grid, {
+        settingsId: {
+          webAppId: "ELN-LIMS",
+          gridId: _this.gridId,
+        },
+        controllerRef: function (controller) {
+          _this.controller = controller;
+        },
+        header: _this.header,
+        loadSettings: _this._loadSettings,
+        loadColumns: _this._loadColumns,
+        loadRows: _this._loadRows,
+        onSettingsChange: _this._onSettingsChange,
+        onSelectedRowChange: _this._onSelectedRowChange,
+      })
+    );
+
+    ReactDOM.render(GridElement, $container.get(0));
+  };
 
-      ReactDOM.render(GridElement, $container.get(0));
+  this._loadSettings = function () {
+    return new Promise(function (resolve) {
+      mainController.serverFacade.getSetting(configKey, function (settingsStr) {
+        var settingsObj = null;
+        if (settingsStr) {
+          try {
+            settingsObj = JSON.parse(settingsStr);
+          } catch (e) {
+            console.log(
+              "[WARNING] Could not parse grid settings",
+              configKey,
+              settingsStr,
+              e
+            );
+          }
+        }
+        resolve(settingsObj);
+      });
     });
   };
 
@@ -216,6 +231,17 @@ function DataGridController2(
     });
   };
 
+  this._onSettingsChange = function (settingsObj) {
+    let settingsStr = JSON.stringify(settingsObj);
+    mainController.serverFacade.setSetting(configKey, settingsStr);
+  };
+
+  this._onSelectedRowChange = function (selectedRow) {
+    if (rowClickEventHandler) {
+      rowClickEventHandler(selectedRow);
+    }
+  };
+
   this.refreshHeight = function () {};
 
   this.refresh = function () {};
-- 
GitLab