From cd1e3a494f97941e174508f9f1a19ecbbdec79b0 Mon Sep 17 00:00:00 2001
From: pkupczyk <piotr.kupczyk@id.ethz.ch>
Date: Tue, 15 Feb 2022 11:53:58 +0100
Subject: [PATCH] SSDM-11169 : Properties overview in the new admin UI - the
 grid

---
 openbis_ng_ui/src/js/common/consts/ids.js     |  2 +
 openbis_ng_ui/src/js/common/messages.js       |  2 +
 .../common/link/PropertyTypeLink.jsx          | 31 ++++++
 .../types/common/PropertyTypesGrid.jsx        | 94 +++++++++++++++++++
 .../js/components/types/search/TypeSearch.jsx | 72 +++++++++++++-
 5 files changed, 198 insertions(+), 3 deletions(-)
 create mode 100644 openbis_ng_ui/src/js/components/common/link/PropertyTypeLink.jsx
 create mode 100644 openbis_ng_ui/src/js/components/types/common/PropertyTypesGrid.jsx

diff --git a/openbis_ng_ui/src/js/common/consts/ids.js b/openbis_ng_ui/src/js/common/consts/ids.js
index 9256e4b3e18..8bbfa70cf03 100644
--- a/openbis_ng_ui/src/js/common/consts/ids.js
+++ b/openbis_ng_ui/src/js/common/consts/ids.js
@@ -4,6 +4,7 @@ const COLLECTION_TYPES_GRID_ID = 'collection_types_grid'
 const DATA_SET_TYPES_GRID_ID = 'data_set_types_grid'
 const MATERIAL_TYPES_GRID_ID = 'material_types_grid'
 const VOCABULARY_TYPES_GRID_ID = 'vocabulary_types_grid'
+const PROPERTY_TYPES_GRID_ID = 'property_types_grid'
 const USERS_GRID_ID = 'users_grid'
 const USERS_OF_GROUP_GRID_ID = 'users_of_group_grid'
 const GROUPS_GRID_ID = 'groups_grid'
@@ -26,6 +27,7 @@ export default {
   DATA_SET_TYPES_GRID_ID,
   MATERIAL_TYPES_GRID_ID,
   VOCABULARY_TYPES_GRID_ID,
+  PROPERTY_TYPES_GRID_ID,
   USERS_GRID_ID,
   USERS_OF_GROUP_GRID_ID,
   GROUPS_GRID_ID,
diff --git a/openbis_ng_ui/src/js/common/messages.js b/openbis_ng_ui/src/js/common/messages.js
index d7fb8ad393f..87eb04627a2 100644
--- a/openbis_ng_ui/src/js/common/messages.js
+++ b/openbis_ng_ui/src/js/common/messages.js
@@ -107,6 +107,7 @@ const keys = {
   MANDATORY: 'MANDATORY',
   MATERIAL_TYPE: 'MATERIAL_TYPE',
   MATERIAL_TYPES: 'MATERIAL_TYPES',
+  META_DATA: 'META_DATA',
   NAME: 'NAME',
   NEW_COLLECTION_TYPE: 'NEW_COLLECTION_TYPE',
   NEW_DATA_SET_TYPE: 'NEW_DATA_SET_TYPE',
@@ -338,6 +339,7 @@ const messages_en = {
   [keys.MANDATORY]: 'Mandatory',
   [keys.MATERIAL_TYPES]: 'Material Types',
   [keys.MATERIAL_TYPE]: 'Material Type',
+  [keys.META_DATA]: 'Meta Data',
   [keys.NAME]: 'Name',
   [keys.NEW_COLLECTION_TYPE]: 'New Collection Type',
   [keys.NEW_DATA_SET_TYPE]: 'New Data Set Type',
diff --git a/openbis_ng_ui/src/js/components/common/link/PropertyTypeLink.jsx b/openbis_ng_ui/src/js/components/common/link/PropertyTypeLink.jsx
new file mode 100644
index 00000000000..db9f2b5868c
--- /dev/null
+++ b/openbis_ng_ui/src/js/components/common/link/PropertyTypeLink.jsx
@@ -0,0 +1,31 @@
+import React from 'react'
+import LinkToObject from '@src/js/components/common/form/LinkToObject.jsx'
+import pages from '@src/js/common/consts/pages.js'
+import objectTypes from '@src/js/common/consts/objectType.js'
+import logger from '@src/js/common/logger.js'
+
+class PropertyTypeLink extends React.PureComponent {
+  render() {
+    logger.log(logger.DEBUG, 'PropertyTypeLink.render')
+
+    const { propertyTypeCode } = this.props
+
+    if (propertyTypeCode) {
+      return (
+        <LinkToObject
+          page={pages.TYPES}
+          object={{
+            type: objectTypes.PROPERTY_TYPE,
+            id: propertyTypeCode
+          }}
+        >
+          {propertyTypeCode}
+        </LinkToObject>
+      )
+    } else {
+      return null
+    }
+  }
+}
+
+export default PropertyTypeLink
diff --git a/openbis_ng_ui/src/js/components/types/common/PropertyTypesGrid.jsx b/openbis_ng_ui/src/js/components/types/common/PropertyTypesGrid.jsx
new file mode 100644
index 00000000000..55044791ab7
--- /dev/null
+++ b/openbis_ng_ui/src/js/components/types/common/PropertyTypesGrid.jsx
@@ -0,0 +1,94 @@
+import _ from 'lodash'
+import React from 'react'
+import GridWithSettings from '@src/js/components/common/grid/GridWithSettings.jsx'
+import PropertyTypeLink from '@src/js/components/common/link/PropertyTypeLink.jsx'
+import messages from '@src/js/common/messages.js'
+import logger from '@src/js/common/logger.js'
+
+class PropertyTypesGrid extends React.PureComponent {
+  render() {
+    logger.log(logger.DEBUG, 'PropertyTypesGrid.render')
+
+    const { id, rows, selectedRowId, onSelectedRowChange, controllerRef } =
+      this.props
+
+    return (
+      <GridWithSettings
+        id={id}
+        controllerRef={controllerRef}
+        header={messages.get(messages.PROPERTY_TYPES)}
+        columns={[
+          {
+            name: 'code',
+            label: messages.get(messages.CODE),
+            getValue: ({ row }) => row.code,
+            renderValue: ({ row }) => {
+              return <PropertyTypeLink propertyTypeCode={row.code} />
+            }
+          },
+          {
+            name: 'label',
+            label: messages.get(messages.LABEL),
+            getValue: ({ row }) => row.label
+          },
+          {
+            name: 'description',
+            label: messages.get(messages.DESCRIPTION),
+            getValue: ({ row }) => row.description
+          },
+          {
+            name: 'dataType',
+            label: messages.get(messages.DATA_TYPE),
+            getValue: ({ row }) => row.dataType
+          },
+          {
+            name: 'vocabulary',
+            label: messages.get(messages.VOCABULARY_TYPE),
+            getValue: ({ row }) => row.vocabulary
+          },
+          {
+            name: 'materialType',
+            label: messages.get(messages.MATERIAL_TYPE),
+            getValue: ({ row }) => row.materialType
+          },
+          {
+            name: 'sampleType',
+            label: messages.get(messages.OBJECT_TYPE),
+            getValue: ({ row }) => row.sampleType
+          },
+          {
+            name: 'schema',
+            label: messages.get(messages.XML_SCHEMA),
+            getValue: ({ row }) => row.schema
+          },
+          {
+            name: 'transformation',
+            label: messages.get(messages.XSLT_SCRIPT),
+            getValue: ({ row }) => row.schema
+          },
+          {
+            name: 'metaData',
+            label: messages.get(messages.META_DATA),
+            getValue: ({ row }) =>
+              _.isEmpty(row.metaData) ? null : JSON.stringify(row.metaData),
+            renderValue: ({ value }) => {
+              return <pre>{value}</pre>
+            }
+          },
+          {
+            name: 'internal',
+            label: messages.get(messages.INTERNAL),
+            getValue: ({ row }) => row.internal
+          }
+        ]}
+        rows={rows}
+        sort='code'
+        selectable={true}
+        selectedRowId={selectedRowId}
+        onSelectedRowChange={onSelectedRowChange}
+      />
+    )
+  }
+}
+
+export default PropertyTypesGrid
diff --git a/openbis_ng_ui/src/js/components/types/search/TypeSearch.jsx b/openbis_ng_ui/src/js/components/types/search/TypeSearch.jsx
index e5b73b77ee6..2e33fca2fa4 100644
--- a/openbis_ng_ui/src/js/components/types/search/TypeSearch.jsx
+++ b/openbis_ng_ui/src/js/components/types/search/TypeSearch.jsx
@@ -6,6 +6,7 @@ import Container from '@src/js/components/common/form/Container.jsx'
 import GridContainer from '@src/js/components/common/grid/GridContainer.jsx'
 import TypesGrid from '@src/js/components/types/common/TypesGrid.jsx'
 import VocabulariesGrid from '@src/js/components/types/common/VocabulariesGrid.jsx'
+import PropertyTypesGrid from '@src/js/components/types/common/PropertyTypesGrid.jsx'
 import Message from '@src/js/components/common/form/Message.jsx'
 import ids from '@src/js/common/consts/ids.js'
 import objectTypes from '@src/js/common/consts/objectType.js'
@@ -45,7 +46,8 @@ class TypeSearch extends React.Component {
         this.loadCollectionTypes(),
         this.loadDataSetTypes(),
         this.loadMaterialTypes(),
-        this.loadVocabularyTypes()
+        this.loadVocabularyTypes(),
+        this.loadPropertyTypes()
       ])
       this.setState(() => ({
         loaded: true
@@ -193,6 +195,43 @@ class TypeSearch extends React.Component {
     })
   }
 
+  async loadPropertyTypes() {
+    if (!this.shouldLoad(objectTypes.PROPERTY_TYPE)) {
+      return
+    }
+
+    const fo = new openbis.PropertyTypeFetchOptions()
+    fo.withVocabulary()
+    fo.withMaterialType()
+    fo.withSampleType()
+
+    const result = await openbis.searchPropertyTypes(
+      new openbis.PropertyTypeSearchCriteria(),
+      fo
+    )
+
+    const types = util
+      .filter(result.objects, this.props.searchText, ['code', 'description'])
+      .map(object => ({
+        id: _.get(object, 'code'),
+        code: _.get(object, 'code'),
+        label: _.get(object, 'label'),
+        description: _.get(object, 'description'),
+        internal: _.get(object, 'managedInternally'),
+        dataType: _.get(object, 'dataType'),
+        vocabulary: _.get(object, 'vocabulary.code'),
+        materialType: _.get(object, 'materialType.code'),
+        sampleType: _.get(object, 'sampleType.code'),
+        schema: _.get(object, 'schema'),
+        transformation: _.get(object, 'transformation'),
+        metaData: _.get(object, 'metaData')
+      }))
+
+    this.setState({
+      propertyTypes: types
+    })
+  }
+
   shouldLoad(objectType) {
     return this.props.objectType === objectType || !this.props.objectType
   }
@@ -231,6 +270,7 @@ class TypeSearch extends React.Component {
         {this.renderDataSetTypes()}
         {this.renderMaterialTypes()}
         {this.renderVocabularyTypes()}
+        {this.renderPropertyTypes()}
       </GridContainer>
     )
   }
@@ -242,7 +282,8 @@ class TypeSearch extends React.Component {
       collectionTypes = [],
       dataSetTypes = [],
       materialTypes = [],
-      vocabularyTypes = []
+      vocabularyTypes = [],
+      propertyTypes = []
     } = this.state
 
     if (
@@ -251,7 +292,8 @@ class TypeSearch extends React.Component {
       collectionTypes.length === 0 &&
       dataSetTypes.length === 0 &&
       materialTypes.length === 0 &&
-      vocabularyTypes.length === 0
+      vocabularyTypes.length === 0 &&
+      propertyTypes.length === 0
     ) {
       return (
         <Container>
@@ -385,6 +427,30 @@ class TypeSearch extends React.Component {
     }
   }
 
+  renderPropertyTypes() {
+    if (
+      this.shouldRender(objectTypes.PROPERTY_TYPE, this.state.propertyTypes)
+    ) {
+      const { classes } = this.props
+      return (
+        <div className={classes.grid}>
+          <PropertyTypesGrid
+            id={ids.PROPERTY_TYPES_GRID_ID}
+            controllerRef={controller =>
+              (this.gridControllers[objectTypes.PROPERTY_TYPE] = controller)
+            }
+            rows={this.state.propertyTypes}
+            onSelectedRowChange={this.handleSelectedRowChange(
+              objectTypes.PROPERTY_TYPE
+            )}
+          />
+        </div>
+      )
+    } else {
+      return null
+    }
+  }
+
   shouldRender(objectType, types) {
     return this.props.objectType === objectType || (types && types.length > 0)
   }
-- 
GitLab