From a2efd0961c7b623347e0750acb9218eb43c561f5 Mon Sep 17 00:00:00 2001
From: TCHERNIATINSKY <philippe.tcherniatinsky@inrae.fr>
Date: Mon, 11 Apr 2022 16:38:32 +0200
Subject: [PATCH 1/2] Ajout de dynamicColumn dans referenceReturn

---
 .../inra/oresing/rest/ApplicationResult.java  | 11 +++++++++
 .../fr/inra/oresing/rest/OreSiResources.java  | 10 +++++++-
 .../inra/oresing/rest/OreSiResourcesTest.java | 23 ++++++++++---------
 3 files changed, 32 insertions(+), 12 deletions(-)

diff --git a/src/main/java/fr/inra/oresing/rest/ApplicationResult.java b/src/main/java/fr/inra/oresing/rest/ApplicationResult.java
index e63a155bc..cfad3644b 100644
--- a/src/main/java/fr/inra/oresing/rest/ApplicationResult.java
+++ b/src/main/java/fr/inra/oresing/rest/ApplicationResult.java
@@ -28,6 +28,7 @@ public class ApplicationResult {
         String label;
         Set<String> children;
         Map<String, Column> columns;
+        Map<String, DynamicColumn> dynamicColumns;
 
         @Value
         public static class Column {
@@ -37,6 +38,16 @@ public class ApplicationResult {
             String linkedTo;
         }
 
+        @Value
+        public static class DynamicColumn {
+            String id;
+            String title;
+            String headerPrefix;
+            String reference;
+            String referenceColumnToLookForHeader;
+            boolean presenceConstraint;
+        }
+
         @Value
         public static class ReferenceUUIDAndDisplay {
             String display;
diff --git a/src/main/java/fr/inra/oresing/rest/OreSiResources.java b/src/main/java/fr/inra/oresing/rest/OreSiResources.java
index e7a8c814c..d35b56a50 100644
--- a/src/main/java/fr/inra/oresing/rest/OreSiResources.java
+++ b/src/main/java/fr/inra/oresing/rest/OreSiResources.java
@@ -123,8 +123,16 @@ public class OreSiResources {
         });
         Map<String, ApplicationResult.Reference> references = Maps.transformEntries(application.getConfiguration().getReferences(), (reference, referenceDescription) -> {
             Map<String, ApplicationResult.Reference.Column> columns = Maps.transformEntries(referenceDescription.doGetStaticColumnDescriptions(), (column, columnDescription) -> new ApplicationResult.Reference.Column(column, column, referenceDescription.getKeyColumns().contains(column), null));
+            Map<String, ApplicationResult.Reference.DynamicColumn> dynamicColumns = Maps.transformEntries(referenceDescription.getDynamicColumns(), (dynamicColumnName, dynamicColumnDescription) ->
+                    new ApplicationResult.Reference.DynamicColumn(
+                            dynamicColumnName,
+                            dynamicColumnName,
+                            dynamicColumnDescription.getHeaderPrefix(),
+                            dynamicColumnDescription.getReference(),
+                            dynamicColumnDescription.getReferenceColumnToLookForHeader(),
+                            dynamicColumnDescription.getPresenceConstraint().isMandatory()));
             Set<String> children = childrenPerReferences.get(reference);
-            return new ApplicationResult.Reference(reference, reference, children, columns);
+            return new ApplicationResult.Reference(reference, reference, children, columns, dynamicColumns);
         });
         Map<String, ApplicationResult.DataType> dataTypes = Maps.transformEntries(application.getConfiguration().getDataTypes(), (dataType, dataTypeDescription) -> {
             Map<String, ApplicationResult.DataType.Variable> variables = Maps.transformEntries(dataTypeDescription.getData(), (variable, variableDescription) -> {
diff --git a/src/test/java/fr/inra/oresing/rest/OreSiResourcesTest.java b/src/test/java/fr/inra/oresing/rest/OreSiResourcesTest.java
index 304026d5a..f0b4039a7 100644
--- a/src/test/java/fr/inra/oresing/rest/OreSiResourcesTest.java
+++ b/src/test/java/fr/inra/oresing/rest/OreSiResourcesTest.java
@@ -49,21 +49,13 @@ import java.io.InputStream;
 import java.net.URL;
 import java.nio.charset.StandardCharsets;
 import java.nio.file.Path;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Set;
-import java.util.UUID;
+import java.util.*;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
 import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
 import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
-import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
-import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
-import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
 
 @RunWith(SpringRunner.class)
 @SpringBootTest(classes = OreSiNg.class)
@@ -597,7 +589,7 @@ public class OreSiResourcesTest {
 
         URL resource = getClass().getResource(fixtures.getRecursivityApplicationConfigurationResourceName());
         try (InputStream in = Objects.requireNonNull(resource).openStream()) {
-            MockMultipartFile configuration = new MockMultipartFile("file", "monsore.yaml", "text/plain", in);
+            MockMultipartFile configuration = new MockMultipartFile("file", "recursivity.yaml", "text/plain", in);
             //définition de l'application
             authenticationService.addUserRightCreateApplication(userId);
 
@@ -609,6 +601,15 @@ public class OreSiResourcesTest {
                     .andReturn().getResponse().getContentAsString();
 
             JsonPath.parse(response).read("$.id");
+
+
+            response = mockMvc.perform(MockMvcRequestBuilders.get("/api/v1/applications/recursivite")
+                            .cookie(authCookie))
+                    .andExpect(status().is2xxSuccessful())
+                    .andExpect(jsonPath("$.references.taxon.dynamicColumns['propriétés de taxons'].reference", IsEqual.equalTo("proprietes_taxon")))
+                   .andExpect(jsonPath("$.references.taxon.dynamicColumns['propriétés de taxons'].headerPrefix", IsEqual.equalTo("pt_")))
+                     .andReturn().getResponse().getContentAsString();
+            log.debug(response);
         }
 
         String response;
-- 
GitLab


From 1f46b63d3bfc4c818f22b79857f2cf7cbc0814b9 Mon Sep 17 00:00:00 2001
From: lucile varloteaux <lucile.varloteaux@inrae.fr>
Date: Thu, 14 Apr 2022 16:48:36 +0200
Subject: [PATCH 2/2] =?UTF-8?q?reste=20=C3=A0=20faire=20la=20modal?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 ui/src/main.js                                |   4 +-
 ui/src/style/_common.scss                     |   4 +
 .../views/references/ReferenceTableView.vue   | 101 ++++++++++--------
 .../references/ReferencesManagementView.vue   |  27 ++---
 4 files changed, 79 insertions(+), 57 deletions(-)

diff --git a/ui/src/main.js b/ui/src/main.js
index 5dd6832d4..7bf9d25f8 100644
--- a/ui/src/main.js
+++ b/ui/src/main.js
@@ -54,6 +54,7 @@ import {
   faArchive,
   faTimesCircle,
   faEdit,
+  faInfo,
 } from "@fortawesome/free-solid-svg-icons";
 import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
 library.add(
@@ -106,7 +107,8 @@ library.add(
   faSortUp,
   faArchive,
   faTimesCircle,
-  faEdit
+  faEdit,
+  faInfo
 );
 Vue.component("vue-fontawesome", FontAwesomeIcon);
 
diff --git a/ui/src/style/_common.scss b/ui/src/style/_common.scss
index 292b182b2..28ab9bbcd 100644
--- a/ui/src/style/_common.scss
+++ b/ui/src/style/_common.scss
@@ -210,3 +210,7 @@ a.dropdown-item.is-active, .dropdown .dropdown-menu .has-link a.is-active, butto
   position: initial;
   z-index: 0;
 }
+
+.svg-inline--fa.fa-info{
+  height: 24px;
+}
diff --git a/ui/src/views/references/ReferenceTableView.vue b/ui/src/views/references/ReferenceTableView.vue
index b52c47dcd..6e9cbb4d0 100644
--- a/ui/src/views/references/ReferenceTableView.vue
+++ b/ui/src/views/references/ReferenceTableView.vue
@@ -12,44 +12,42 @@
 
     <div v-if="reference && columns">
       <b-table
-          :data="tableValues"
-          :striped="true"
-          :isFocusable="true"
-          :isHoverable="true"
-          :sticky-header="true"
-          height="100%"
-          style="padding-bottom: 20px; position: relative;z-index: 1;"
+        :data="tableValues"
+        :striped="true"
+        :isFocusable="true"
+        :isHoverable="true"
+        :sticky-header="true"
+        height="100%"
+        style="padding-bottom: 20px; position: relative; z-index: 1"
       >
         <b-table-column
-            v-for="column in columns"
-            :key="column.id"
-            :field="column.id"
-            :label="column.title"
-            sortable
-            :sticky="column.key"
-            v-slot="props"
+          v-for="column in columns"
+          :key="column.id"
+          :field="column.id"
+          :label="column.title"
+          sortable
+          :sticky="column.key"
+          v-slot="props"
         >
-          <span v-if="column.id === 'nom du taxon déterminé'">
-            <a @click="showModal(props.row[column.id])">
-              {{ props.row[column.id] }}</a
-            >
+          <span v-if="info(column.id)">
+            <b-button
+                size="is-small"
+                type="is-dark"
+                v-if="showBtnTablDynamicColumn(props.row[column.id])"
+                @click="showModal(props.row[column.id])"
+                icon-left="info"
+                rounded
+                style="height: inherit"
+            ></b-button>
+            <p v-else></p>
             <b-modal
-                v-show="isSelectedName === props.row[column.id]"
-                v-model="isCardModalActive"
-                width = 70%
-                data-backdrop="static"
+              v-model="isCardModalActive"
+              width="70%"
             >
               <div class="card">
-                <div class="card-header">
-                  <div class="title card-header-title">
-                    <p field="name">Propriétés de {{ props.row[column.id] }}</p>
-                  </div>
-                </div>
                 <div class="card-content">
                   <ul>
-                    <li v-for="item in taxonTbl.proprietes_taxon" :key="item.code_sandre">
-                      {{ item }}
-                    </li>
+                    <li v-for="modalObj in modalArrayObj" :key="modalObj.id">{{ modalObj }}</li>
                   </ul>
                 </div>
               </div>
@@ -61,9 +59,9 @@
           <b-collapse v-else :open="false">
             <template #trigger>
               <b-button
-                  :label="'' + (tableValues.indexOf(props.row) + 1)"
-                  type="is-small"
-                  aria-controls="contentIdForA11y1"
+                :label="'' + (tableValues.indexOf(props.row) + 1)"
+                type="is-small"
+                aria-controls="contentIdForA11y1"
               />
             </template>
             {{ referenceValues[tableValues.indexOf(props.row)].naturalKey }}
@@ -122,19 +120,27 @@ export default class ReferenceTableView extends Vue {
   perPage = 15;
 
   // show modal and cards
-  isSelectedName = "";
   isCardModalActive = false;
-  nameColumn = 'nom du taxon déterminé';
-  taxonTbl = [];
+  modalArrayObj = [];
 
-  showModal(name) {
-    this.isSelectedName = name;
+  showModal(tablDynamicColumn) {
     this.isCardModalActive = true;
-    for(let i =0; i<this.tableValues.length; i++) {
-      if (this.tableValues[i][this.nameColumn] === name) {
-        this.taxonTbl = this.tableValues[i];
-      }
+    this.modalArrayObj = Object.entries(tablDynamicColumn).filter(a=>a[1]).map(function(a){let obj = {}; obj[a[0]]=a[1]; return obj});
+    console.log(this.modalArrayObj);
+    return this.modalArrayObj;
+  }
+  info(column) {
+    let dynamicColumn = Object.entries(this.reference.dynamicColumns).filter(a=>a[1]);
+    for (let i = 0; i< dynamicColumn.length; i++) {
+      if(dynamicColumn[i][0] === column)
+        return true;
     }
+    return false;
+  }
+
+  showBtnTablDynamicColumn(tablDynamicColumn) {
+    let showModal = Object.entries(tablDynamicColumn).filter(a=>a[1]).map(function(a){let obj = {}; obj[a[0]]=a[1]; return obj});
+    return showModal.length !== 0;
   }
 
   async created() {
@@ -195,7 +201,15 @@ export default class ReferenceTableView extends Vue {
           if (c1.title < c2.title) {
             return -1;
           }
-
+          if (c1.title > c2.title) {
+            return 1;
+          }
+          return 0;
+        }),
+        ...Object.values(this.reference.dynamicColumns).sort((c1, c2) => {
+          if (c1.title < c2.title) {
+            return -1;
+          }
           if (c1.title > c2.title) {
             return 1;
           }
@@ -203,7 +217,6 @@ export default class ReferenceTableView extends Vue {
         }),
       ];
     }
-
     if (this.referenceValues) {
       this.tableValues = Object.values(this.referenceValues).map((refValue) => refValue.values);
     }
diff --git a/ui/src/views/references/ReferencesManagementView.vue b/ui/src/views/references/ReferencesManagementView.vue
index 97882f58b..433a81b6c 100644
--- a/ui/src/views/references/ReferencesManagementView.vue
+++ b/ui/src/views/references/ReferencesManagementView.vue
@@ -16,7 +16,7 @@
         :key="ref.id"
         :option="ref"
         :level="0"
-        :id="i+1"
+        :id="i + 1"
         :onClickLabelCb="(event, label) => openRefDetails(event, label)"
         :onUploadCb="(label, refFile) => uploadReferenceCsv(label, refFile)"
         :buttons="buttons"
@@ -125,18 +125,21 @@ export default class ReferencesManagementView extends Vue {
       if (this.application.referenceSynthesis[i].referenceType === ref.label) {
         return this.application.referenceSynthesis[i].lineCount;
       } else {
-        for (let n=0; n<ref.children.length; n++) {
-          if( this.application.referenceSynthesis[i].referenceType === ref.children[n].label) {
+        for (let n = 0; n < ref.children.length; n++) {
+          if (this.application.referenceSynthesis[i].referenceType === ref.children[n].label) {
             ref.children[n] = {
               ...ref.children[n],
-              lineCountChild : this.application.referenceSynthesis[i].lineCount,
+              lineCountChild: this.application.referenceSynthesis[i].lineCount,
             };
           } else {
-            for (let j=0; j<ref.children[n].children.length; j++) {
-              if( this.application.referenceSynthesis[i].referenceType === ref.children[n].children[j].label) {
+            for (let j = 0; j < ref.children[n].children.length; j++) {
+              if (
+                this.application.referenceSynthesis[i].referenceType ===
+                ref.children[n].children[j].label
+              ) {
                 ref.children[n].children[j] = {
                   ...ref.children[n].children[j],
-                  lineCountChild : this.application.referenceSynthesis[i].lineCount,
+                  lineCountChild: this.application.referenceSynthesis[i].lineCount,
                 };
               }
             }
@@ -150,12 +153,12 @@ export default class ReferencesManagementView extends Vue {
     const reference = this.findReferenceByLabel(label);
     if (reference) {
       let csv = await this.referenceService.getReferenceCsv(this.applicationName, reference.id);
-      console.log(csv)
-      var hiddenElement = document.createElement('a');
-      hiddenElement.href = 'data:text/csv;charset=utf-8,' + encodeURI(csv);
+      console.log(csv);
+      var hiddenElement = document.createElement("a");
+      hiddenElement.href = "data:text/csv;charset=utf-8," + encodeURI(csv);
 
       //provide the name for the CSV file to be downloaded
-      hiddenElement.download = 'export.csv';
+      hiddenElement.download = "export.csv";
       hiddenElement.click();
       return false;
     }
@@ -182,4 +185,4 @@ export default class ReferencesManagementView extends Vue {
   margin-bottom: 10px;
   border: 1px solid white;
 }
-</style>
\ No newline at end of file
+</style>
-- 
GitLab