From 7cfdbdd7c05e79990ddda6acc8991e5be24760a0 Mon Sep 17 00:00:00 2001
From: Remi  PLANEL <rplanel@pasteur.fr>
Date: Wed, 20 Sep 2023 16:46:26 +0200
Subject: [PATCH] Automatic systems list

---
 components/content/ListSystems.vue     | 39 +++++++++++--------
 content/2.defense-systems/abi2.md      |  2 +
 content/2.defense-systems/abia.md      |  2 +
 content/2.defense-systems/abib.md      |  2 +
 content/2.defense-systems/abic.md      |  2 +
 content/2.defense-systems/abid.md      |  2 +
 content/2.defense-systems/abie.md      |  2 +
 content/2.defense-systems/abig.md      |  2 +
 content/2.defense-systems/abih.md      |  2 +
 content/2.defense-systems/abiv.md      |  2 +
 content/2.defense-systems/rst_paris.md |  2 +
 nuxt.config.ts                         |  6 +--
 pages/defense-systems.vue              | 53 ++++++++++++++++++++++++++
 13 files changed, 100 insertions(+), 18 deletions(-)
 create mode 100644 pages/defense-systems.vue

diff --git a/components/content/ListSystems.vue b/components/content/ListSystems.vue
index 6c5efb7a..beb7ef11 100644
--- a/components/content/ListSystems.vue
+++ b/components/content/ListSystems.vue
@@ -1,34 +1,43 @@
 <script setup lang="ts">
-
 const props = defineProps<{
-    systems: any;
+    headers: Array<Object>
+    systems: Array<Object>
+
 }>();
 const itemsPerParge = ref(25)
 const search = ref('')
 const sortBy = ref([{ key: 'system', order: 'asc' }])
-const headers = ref([{
-    title: "Systems",
-    key: "system"
-}, { title: "Articles", key: "dois" }
-])
 
+function filterOnlyCapsText(value, query, item) {
+    if (value != null && query != null) {
+        if (typeof value === 'string') {
+            return value.toString().toLowerCase().indexOf(query.toLowerCase()) !== -1
+        }
+        if (typeof value == 'object') {
+            if (value?.name) {
+                return value.name.toString().toLowerCase().indexOf(query.toLowerCase()) !== -1
+            }
+        }
+    }
+    return false
+}
 </script>
 <template>
     <v-card flat color="transparent" class="my-5">
         <v-toolbar>
             <v-toolbar-title>Defense Systems</v-toolbar-title>
 
-            <v-text-field v-model="search" density="compact" variant="underlined" append-inner-icon="mdi-magnify"
-                label="Search" single-line hide-details class="mx-2"></v-text-field>
+            <v-text-field v-model="search" density="compact" variant="underlined" prepend-inner-icon="mdi-magnify"
+                label="Search for defense systems" single-line hide-details class="mx-2" clearable></v-text-field>
         </v-toolbar>
-        <v-data-table :items-per-page="itemsPerParge" v-model:sort-by="sortBy" :headers="headers" :items="props.systems"
-            :search="search">
+        <v-data-table :items-per-page="itemsPerParge" v-model:sort-by="sortBy" :headers="props.headers"
+            :custom-filter="filterOnlyCapsText" :items="props.systems" :search="search">
             <template #[`item.system`]="{ item }">
-                <v-chip variant="text" link :to="`/defense-systems/${item.columns.system.toLowerCase()}`">{{
-                    item.columns.system }}</v-chip>
+                <v-chip variant="text" link :to="`${item.columns.system.path}`">{{
+                    item.columns.system.name }}</v-chip>
             </template>
-            <template #[`item.dois`]="{ item }">
-                <ArticleDoiList :items="item.columns.dois" :divider="false" />
+            <template #[`item.doi`]="{ item }">
+                <ArticleDoiList v-if="item.columns?.doi" :items="[item.columns.doi]" :divider="false" />
             </template>
         </v-data-table>
     </v-card>
diff --git a/content/2.defense-systems/abi2.md b/content/2.defense-systems/abi2.md
index ca92286d..b7f40795 100644
--- a/content/2.defense-systems/abi2.md
+++ b/content/2.defense-systems/abi2.md
@@ -1,5 +1,7 @@
 ---
 title: Abi2
+tableColumns:
+    doi: 10.1016/j.mib.2005.06.006
 ---
 
 The Abi2 system is composed of one protein: Abi_2.
diff --git a/content/2.defense-systems/abia.md b/content/2.defense-systems/abia.md
index 1c086536..bb5ea851 100644
--- a/content/2.defense-systems/abia.md
+++ b/content/2.defense-systems/abia.md
@@ -1,5 +1,7 @@
 ---
 title: AbiA
+tableColumns:
+    doi: 10.1016/j.mib.2005.06.006
 ---
 
 The AbiA system have been describe in a total of 2 subsystems.
diff --git a/content/2.defense-systems/abib.md b/content/2.defense-systems/abib.md
index e3bfe669..0428f535 100644
--- a/content/2.defense-systems/abib.md
+++ b/content/2.defense-systems/abib.md
@@ -1,5 +1,7 @@
 ---
 title: AbiB
+tableColumns:
+    doi: 10.1016/j.mib.2005.06.006
 ---
 
 The AbiB system is composed of one protein: AbiB.
diff --git a/content/2.defense-systems/abic.md b/content/2.defense-systems/abic.md
index 1a332dd7..26d4e748 100644
--- a/content/2.defense-systems/abic.md
+++ b/content/2.defense-systems/abic.md
@@ -1,5 +1,7 @@
 ---
 title: AbiC
+tableColumns:
+    doi: 10.1016/j.mib.2005.06.006
 ---
 
 The AbiC system is composed of one protein: AbiC.
diff --git a/content/2.defense-systems/abid.md b/content/2.defense-systems/abid.md
index d4280862..6b1230e0 100644
--- a/content/2.defense-systems/abid.md
+++ b/content/2.defense-systems/abid.md
@@ -1,5 +1,7 @@
 ---
 title: AbiD
+tableColumns:
+    doi: 10.1016/j.mib.2005.06.006
 ---
 
 The AbiD system is composed of one protein: AbiD.
diff --git a/content/2.defense-systems/abie.md b/content/2.defense-systems/abie.md
index d24eab50..b83cbadb 100644
--- a/content/2.defense-systems/abie.md
+++ b/content/2.defense-systems/abie.md
@@ -1,5 +1,7 @@
 ---
 title: AbiE
+tableColumns:
+    doi: 10.1016/j.mib.2005.06.006
 ---
 
 AbiE is a family of an anti-phage defense systems. They act through a Toxin-Antitoxin mechanism, and are comprised of a pair of genes, with one gene being toxic while the other confers immunity to this toxicity. 
diff --git a/content/2.defense-systems/abig.md b/content/2.defense-systems/abig.md
index 1f46ad07..b21a9877 100644
--- a/content/2.defense-systems/abig.md
+++ b/content/2.defense-systems/abig.md
@@ -1,5 +1,7 @@
 ---
 title: AbiG
+tableColumns:
+    doi: 10.1016/j.mib.2005.06.006
 ---
 
 The AbiG system is composed of 2 proteins: AbiGi and, AbiGii.
diff --git a/content/2.defense-systems/abih.md b/content/2.defense-systems/abih.md
index d3040552..32d4ddc2 100644
--- a/content/2.defense-systems/abih.md
+++ b/content/2.defense-systems/abih.md
@@ -1,5 +1,7 @@
 ---
 title: AbiH
+tableColumns:
+    doi: 10.1111/j.1574-6968.1996.tb08446.x
 ---
 
 ## Example of genomic structure
diff --git a/content/2.defense-systems/abiv.md b/content/2.defense-systems/abiv.md
index a8f2a985..162b5edd 100644
--- a/content/2.defense-systems/abiv.md
+++ b/content/2.defense-systems/abiv.md
@@ -1,5 +1,7 @@
 ---
 title: AbiV
+tableColumns:
+    doi: 10.1128/AEM.00780-08
 ---
 
 ## Example of genomic structure
diff --git a/content/2.defense-systems/rst_paris.md b/content/2.defense-systems/rst_paris.md
index 52e9a898..98e839fd 100644
--- a/content/2.defense-systems/rst_paris.md
+++ b/content/2.defense-systems/rst_paris.md
@@ -1,5 +1,7 @@
 ---
 title: Rst_PARIS
+tableColumns:
+    doi: https://doi.org/10.1101/2021.01.21.427644
 ---
 
 ## Description
diff --git a/nuxt.config.ts b/nuxt.config.ts
index 6a2750ee..60c5287a 100644
--- a/nuxt.config.ts
+++ b/nuxt.config.ts
@@ -14,8 +14,8 @@ export default defineNuxtConfig({
   devtools: {
     enabled: false
   },
-  app: {
-    baseURL: '/wiki',
-  }
+  // app: {
+  //   baseURL: '/wiki',
+  // }
 
 })
diff --git a/pages/defense-systems.vue b/pages/defense-systems.vue
new file mode 100644
index 00000000..a417b5f1
--- /dev/null
+++ b/pages/defense-systems.vue
@@ -0,0 +1,53 @@
+<script setup lang="ts">
+const { data, error, pending } = await useAsyncData(
+    'list-defense-systems',
+    () => queryContent('/defense-systems').find()
+)
+const defaultHeaders = ref([{ title: 'System', key: "system" }])
+const tableKey = "tableColumns"
+
+const sanitizedData = computed(() => {
+    if (data?.value && data.value?.length > 0) {
+        return data.value?.filter(entry => {
+            if (entry._dir === "old" || entry._dir === "") {
+                return false
+            }
+            return true
+        })
+    } else {
+        return []
+    }
+})
+
+const headers = computed(() => {
+
+    const uniqHeaders = Array.from(sanitizedData.value.reduce((headerSet, df) => {
+        if (df?.[tableKey]) {
+            return new Set([...headerSet, ...Object.keys(df[tableKey])])
+        }
+        else { return headerSet }
+    }, new Set()))
+    return [...defaultHeaders.value, ...uniqHeaders.map(value => { return { title: value, key: value } })]
+
+})
+const systems = computed(() => {
+    return sanitizedData.value.map((content) => {
+        return {
+            system: { name: content.title, path: content._path },
+            ...content[tableKey]
+        }
+    })
+
+
+})
+
+
+</script>
+<template>
+    <v-card>
+        <v-card-title>List systems</v-card-title>
+        <v-card-text>
+            <ListSystems :headers=headers :systems="systems"></ListSystems>
+        </v-card-text>
+    </v-card>
+</template>
\ No newline at end of file
-- 
GitLab