From 0aa44919e098ccf40ba5ecf7e0156f86f94ffb46 Mon Sep 17 00:00:00 2001
From: pkupczyk <piotr.kupczyk@id.ethz.ch>
Date: Thu, 13 Jul 2023 14:09:57 +0200
Subject: [PATCH] SSDM-13817 : Add information help for Vocabulary Term
 Template

---
 ui-admin/src/js/common/messages.js            |  4 ++
 .../components/common/form/FormFieldView.jsx  | 42 +++++++++++++++----
 .../js/components/common/form/TextField.jsx   |  4 +-
 .../VocabularyTypeFormControllerValidate.js   |  4 ++
 ...VocabularyTypeFormParametersVocabulary.jsx |  1 +
 ui-admin/srcTest/js/common/fixture.js         |  2 +-
 6 files changed, 46 insertions(+), 11 deletions(-)

diff --git a/ui-admin/src/js/common/messages.js b/ui-admin/src/js/common/messages.js
index 87b66643b99..6d12c7370c8 100644
--- a/ui-admin/src/js/common/messages.js
+++ b/ui-admin/src/js/common/messages.js
@@ -265,6 +265,8 @@ const keys = {
   UPDATE_IF_EXISTS: 'UPDATE_IF_EXISTS',
   UPDATE_MODE: "UPDATE_MODE",
   URL_TEMPLATE: 'URL_TEMPLATE',
+  URL_TEMPLATE_HINT: 'URL_TEMPLATE_HINT',
+  URL_TEMPLATE_PATTERN: 'URL_TEMPLATE_PATTERN',
   USAGES: 'USAGES',
   USER: 'USER',
   USERS: 'USERS',
@@ -564,6 +566,8 @@ const messages_en = {
   [keys.UPDATE_IF_EXISTS]: 'Update if exists',
   [keys.UPDATE_MODE]: 'Update Mode',
   [keys.URL_TEMPLATE]: 'URL Template',
+  [keys.URL_TEMPLATE_HINT]: 'For example:\nhttp://www.ebi.ac.uk/QuickGO/GTerm?id=${term}',
+  [keys.URL_TEMPLATE_PATTERN]: "URL template must contain '${term}', which will be substituted with appropriate term automatically.",
   [keys.USAGES]: 'Usages',
   [keys.USERS]: 'Users',
   [keys.USERS_WHO_REGISTERED_SOME_DATA_CANNOT_BE_REMOVED]: 'Users who have already registered some data cannot be removed.',
diff --git a/ui-admin/src/js/components/common/form/FormFieldView.jsx b/ui-admin/src/js/components/common/form/FormFieldView.jsx
index 18d067315e1..678968a61e6 100644
--- a/ui-admin/src/js/components/common/form/FormFieldView.jsx
+++ b/ui-admin/src/js/components/common/form/FormFieldView.jsx
@@ -1,8 +1,19 @@
+import _ from 'lodash'
 import React from 'react'
 import { withStyles } from '@material-ui/core/styles'
 import Typography from '@material-ui/core/Typography'
+import InfoIcon from '@material-ui/icons/Info'
+import Tooltip from '@src/js/components/common/form/Tooltip.jsx'
 
 const styles = theme => ({
+  container: {
+    display: 'flex',
+    flexDirection: 'row',
+    alignItems: 'center'
+  },
+  control: {
+    flex: '1 1 auto'
+  },
   label: {
     fontSize: theme.typography.label.fontSize,
     color: theme.typography.label.color
@@ -13,20 +24,35 @@ const styles = theme => ({
     borderBottomStyle: 'solid',
     borderBottomColor: theme.palette.border.secondary
   },
-  container: {}
+  description: {
+    flex: '0 0 auto',
+    '& svg': {
+      color: theme.palette.hint.main
+    },
+    cursor: 'pointer'
+  }
 })
 
 class FormFieldView extends React.PureComponent {
   render() {
-    const { label, value, classes } = this.props
+    const { label, value, description, classes } = this.props
     return (
       <div className={classes.container}>
-        <Typography variant='body2' component='div' className={classes.label}>
-          {label}
-        </Typography>
-        <Typography variant='body2' component='div' className={classes.value}>
-          {value ? value : <span>&nbsp;</span>}
-        </Typography>
+        <div className={classes.control}>
+          <Typography variant='body2' component='div' className={classes.label}>
+            {label}
+          </Typography>
+          <Typography variant='body2' component='div' className={classes.value}>
+            {value ? value : <span>&nbsp;</span>}
+          </Typography>
+        </div>
+        {!_.isNil(description) && (
+          <div className={classes.description}>
+            <Tooltip title={description}>
+              <InfoIcon fontSize='small' />
+            </Tooltip>
+          </div>
+        )}
       </div>
     )
   }
diff --git a/ui-admin/src/js/components/common/form/TextField.jsx b/ui-admin/src/js/components/common/form/TextField.jsx
index 33bceabf18f..68c4dfb9482 100644
--- a/ui-admin/src/js/components/common/form/TextField.jsx
+++ b/ui-admin/src/js/components/common/form/TextField.jsx
@@ -50,8 +50,8 @@ class TextFormField extends React.PureComponent {
   }
 
   renderView() {
-    const { label, value } = this.props
-    return <FormFieldView label={label} value={value} />
+    const { label, value, description } = this.props
+    return <FormFieldView label={label} value={value} description={description} />
   }
 
   renderEdit() {
diff --git a/ui-admin/src/js/components/types/form/vocabularytype/VocabularyTypeFormControllerValidate.js b/ui-admin/src/js/components/types/form/vocabularytype/VocabularyTypeFormControllerValidate.js
index d21b7c1da49..2052499d395 100644
--- a/ui-admin/src/js/components/types/form/vocabularytype/VocabularyTypeFormControllerValidate.js
+++ b/ui-admin/src/js/components/types/form/vocabularytype/VocabularyTypeFormControllerValidate.js
@@ -2,6 +2,8 @@ import PageControllerValidate from '@src/js/components/common/page/PageConroller
 import VocabularyTypeFormSelectionType from '@src/js/components/types/form/vocabularytype/VocabularyTypeFormSelectionType.js'
 import messages from '@src/js/common/messages.js'
 
+const URL_TEMPLATE_PATTERN = /^.*\$\{term\}.*$/
+
 export default class VocabularyTypeFormControllerValidate extends PageControllerValidate {
   validate(validator) {
     const { vocabulary, terms } = this.context.getState()
@@ -53,6 +55,8 @@ export default class VocabularyTypeFormControllerValidate extends PageController
       validator.validateCode(vocabulary, 'code', messages.get(messages.CODE))
     }
 
+    validator.validatePattern(vocabulary, 'urlTemplate', messages.get(messages.URL_TEMPLATE_PATTERN), URL_TEMPLATE_PATTERN)
+
     return validator.withErrors(vocabulary)
   }
 
diff --git a/ui-admin/src/js/components/types/form/vocabularytype/VocabularyTypeFormParametersVocabulary.jsx b/ui-admin/src/js/components/types/form/vocabularytype/VocabularyTypeFormParametersVocabulary.jsx
index d189ab492fc..86ffd487ad2 100644
--- a/ui-admin/src/js/components/types/form/vocabularytype/VocabularyTypeFormParametersVocabulary.jsx
+++ b/ui-admin/src/js/components/types/form/vocabularytype/VocabularyTypeFormParametersVocabulary.jsx
@@ -222,6 +222,7 @@ class VocabularyTypeFormParametersVocabulary extends React.PureComponent {
         <TextField
           reference={this.references.urlTemplate}
           label={messages.get(messages.URL_TEMPLATE)}
+          description={messages.get(messages.URL_TEMPLATE_HINT)}
           name='urlTemplate'
           error={error}
           disabled={!enabled}
diff --git a/ui-admin/srcTest/js/common/fixture.js b/ui-admin/srcTest/js/common/fixture.js
index 795d9341de0..272ea021073 100644
--- a/ui-admin/srcTest/js/common/fixture.js
+++ b/ui-admin/srcTest/js/common/fixture.js
@@ -165,7 +165,7 @@ TEST_TERM_6_DTO.setOfficial(false)
 const TEST_VOCABULARY_DTO = new openbis.Vocabulary()
 TEST_VOCABULARY_DTO.setCode('TEST_VOCABULARY')
 TEST_VOCABULARY_DTO.setDescription('TEST_DESCRIPTION')
-TEST_VOCABULARY_DTO.setUrlTemplate('TEST_URL_TEMPLATE')
+TEST_VOCABULARY_DTO.setUrlTemplate('http://test-url-template/${term}')
 TEST_VOCABULARY_DTO.setTerms([
   TEST_TERM_1_DTO,
   TEST_TERM_2_DTO,
-- 
GitLab