From 6ad8d847d5e25072055ad5da197783a67327a20b Mon Sep 17 00:00:00 2001
From: Mathieu Massaviol <mathieu.massaviol@univ-amu.fr>
Date: Thu, 28 Nov 2024 11:52:39 +0100
Subject: [PATCH] Use community['@id'] as the tree root #73

---
 .../OcCatalogSelect/OcCatalogSelect.vue       |  3 +-
 .../OcLayoutCommunityWithTree.vue             |  6 +--
 src/pages/community/[community].vue           |  2 +-
 .../[community]/[resource]/[identifier].vue   |  2 +-
 .../catalog/[[identifier]].new.vue            |  2 +-
 src/sparql/tree.ts                            |  2 +
 src/stores/tree.ts                            | 41 ++++++++++++-------
 7 files changed, 36 insertions(+), 22 deletions(-)

diff --git a/src/components/FormInputs/OcCatalogSelect/OcCatalogSelect.vue b/src/components/FormInputs/OcCatalogSelect/OcCatalogSelect.vue
index fcb1829..2ff23a4 100644
--- a/src/components/FormInputs/OcCatalogSelect/OcCatalogSelect.vue
+++ b/src/components/FormInputs/OcCatalogSelect/OcCatalogSelect.vue
@@ -43,7 +43,6 @@ import TreeSelect from 'primevue/treeselect'
 import { getResourceVisibility } from '@/helpers/resourceVisibility'
 import { onMounted, ref, watch, type PropType } from 'vue'
 import { useI18n } from 'vue-i18n'
-import { homeNodeUri } from '@/stores/tree'
 
 const { t } = useI18n()
 const { translateValue } = useTranslateValue()
@@ -124,7 +123,7 @@ onMounted(async () => {
     }
   } else {
     try {
-      for (const catalog of await getCatalogSummaryFromParentUri(homeNodeUri, props.auth)) {
+      for (const catalog of await getCatalogSummaryFromParentUri(props.community['@id'], props.auth)) {
         if (!Object.keys(catalogList.value).includes(catalog['@id'])) {
           const node = {
             key: catalog['@id'],
diff --git a/src/layout/OcLayoutCommunityWithTree/OcLayoutCommunityWithTree.vue b/src/layout/OcLayoutCommunityWithTree/OcLayoutCommunityWithTree.vue
index 69f42b8..5de24ba 100644
--- a/src/layout/OcLayoutCommunityWithTree/OcLayoutCommunityWithTree.vue
+++ b/src/layout/OcLayoutCommunityWithTree/OcLayoutCommunityWithTree.vue
@@ -58,7 +58,7 @@ import OcTopBar from '@/components/OcTopBar/OcTopBar.vue'
 import OcTreeCommunity from '@/components/OcTreeCommunity/OcTreeCommunity.vue'
 import type { OcBreadcrumbItem, OcCommunity } from '@/declarations'
 import { ref, type PropType, computed } from 'vue'
-import { useTreeStore, homeNodeUri } from '@/stores/tree'
+import { useTreeStore } from '@/stores/tree'
 import type { TreeNode } from 'primevue/treenode'
 import { useRouter, type RouteParamsRawGeneric } from 'vue-router'
 import { useI18n } from 'vue-i18n'
@@ -99,7 +99,7 @@ const currentNode = ref<TreeNode>()
 function onNodeSelect(node: TreeNode) {
   treeStore.state.selectedNodeKey = node.key
   currentNode.value = node
-  if (node.uri === homeNodeUri) {
+  if (node.uri === props.community['@id']) {
     router.push({
       name: 'community',
       params: { lang: locale.value, community: props.community?.name }
@@ -135,7 +135,7 @@ function onNodeSelect(node: TreeNode) {
 async function onNodeExpand(node: TreeNode) {
   if (!node.children || node.children.length == 0) {
     node.loading = true
-    await treeStore.fetchTreeNodesFromParentNodeURI(node.uri)
+    await treeStore.fetchTreeNodesFromParentNodeURI(node.uri, props.community)
     node.loading = false
   }
   treeStore.state.expandedNodesKeys.push(node.key)
diff --git a/src/pages/community/[community].vue b/src/pages/community/[community].vue
index 5f981de..1ccd39f 100644
--- a/src/pages/community/[community].vue
+++ b/src/pages/community/[community].vue
@@ -32,7 +32,7 @@ const { data: community } = useCommunityData()
 onBeforeMount(() => {
   if (!route.params.identifier){
     // Si pas d'identifiant dans la route on charge l'arbre de base s'il est vide
-    treeStore.fetchIfEmpty()
+    treeStore.fetchIfEmpty(community.value)
   }
 })
 
diff --git a/src/pages/community/[community]/[resource]/[identifier].vue b/src/pages/community/[community]/[resource]/[identifier].vue
index af914c3..dceb933 100644
--- a/src/pages/community/[community]/[resource]/[identifier].vue
+++ b/src/pages/community/[community]/[resource]/[identifier].vue
@@ -90,7 +90,7 @@ onMounted(() => {
   if (treeStore.state.selectedNodeKey === undefined) {
     // Si on arrive sur la page de ressource sans avoir selectionné un noeud
     // c'est qu'on arrive par l'URL et on doit charger et ouvrir l'arbre
-    treeStore.fetchTreeForResource(identifier.value, resourceType.value)
+    treeStore.fetchTreeForResource(identifier.value, resourceType.value, community.value)
   } else {
     treeStore.state.selectedNodeKey = identifier.value
   }
diff --git a/src/pages/community/[community]/catalog/[[identifier]].new.vue b/src/pages/community/[community]/catalog/[[identifier]].new.vue
index 35ef3a4..cf2f98b 100644
--- a/src/pages/community/[community]/catalog/[[identifier]].new.vue
+++ b/src/pages/community/[community]/catalog/[[identifier]].new.vue
@@ -129,7 +129,7 @@ const send = async () => {
     console.error(e)
     errorMessage.value = (e as Error).message ?? 'Error'
   }
-  treeStore.fetchTreeNodesFromParentNodeURI(catalog.value.parentCatalog['@id'])
+  treeStore.fetchTreeNodesFromParentNodeURI(catalog.value.parentCatalog['@id'], community.value)
   sending.value = false
 }
 </script>
diff --git a/src/sparql/tree.ts b/src/sparql/tree.ts
index 6800646..eed2d7d 100644
--- a/src/sparql/tree.ts
+++ b/src/sparql/tree.ts
@@ -65,6 +65,8 @@ export const getTreeNodesFromParentNodeURI = async (parentNodeUri: string, auth?
         ?node oct:graph ?g.
       }
       WHERE {
+        <${parentNodeUri}> rdf:type ?type.
+        FILTER (?type in (dcat:Catalog, dcat:Dataset, dcat:Distribution, dcat:DataService))
         {
           VALUES ?p { dcat:catalog dcat:dataset dcat:distribution dct:title dct:identifier rdf:type }
           <${parentNodeUri}> ?p ?o.
diff --git a/src/stores/tree.ts b/src/stores/tree.ts
index fd82c90..b58b28b 100644
--- a/src/stores/tree.ts
+++ b/src/stores/tree.ts
@@ -1,4 +1,4 @@
-import type { OcBreadcrumbItem, OcTreeNode } from '@/declarations'
+import type { OcBreadcrumbItem, OcCommunity, OcTreeNode } from '@/declarations'
 import { getTreeNodesFromParentNodeURI, getUrisBetweenHomeAndResource } from '@/sparql/tree'
 import { defineStore, storeToRefs } from 'pinia'
 import { computed, ref, watch } from 'vue'
@@ -14,8 +14,6 @@ interface TreeState {
   error: null | Error
 }
 
-export const homeNodeUri = 'https://www.irit.fr/opencommon/resourceTree/Home'
-
 export const useTreeStore = defineStore('tree', () => {
   const state = ref<TreeState>({
     nodes: [],
@@ -29,20 +27,24 @@ export const useTreeStore = defineStore('tree', () => {
 
   const account = storeToRefs(useAccountStore())
 
-  async function fetchIfEmpty() {
-    if (state.value.nodes.length == 0) {
+  async function fetchIfEmpty(community: OcCommunity) {
+    if (state.value.nodes.length == 0 || community['@id'] != state.value.nodes[0]['@id']) {
       state.value.loading = true
+      resetState()
 
-      const result = await getTreeNodesFromParentNodeURI(homeNodeUri, account.auth?.value)
-      state.value.nodes = result
+      const result = await getTreeNodesFromParentNodeURI(community['@id'], account.auth?.value)
+      
+      if (result.length && Object.keys(result[0]).length){
+        state.value.nodes = result
+      }
 
       state.value.loading = false
     }
   }
 
-  async function fetchTreeNodesFromParentNodeURI(parentNodeUri: string) {
+  async function fetchTreeNodesFromParentNodeURI(parentNodeUri: string, community: OcCommunity) {
     if (state.value.nodes.length == 0) {
-      await fetchIfEmpty()
+      await fetchIfEmpty(community)
     }
     let parentNode = findNode(parentNodeUri, state.value.nodes[0])
     if (parentNode) {
@@ -100,27 +102,27 @@ export const useTreeStore = defineStore('tree', () => {
     }
   }
 
-  async function fetchTreeForResource(resourceId: string, resourceType: string) {
+  async function fetchTreeForResource(resourceId: string, resourceType: string, community: OcCommunity) {
     state.value.loading = true
     const result = await getUrisBetweenHomeAndResource(
-      homeNodeUri,
+      community['@id'],
       resourceId,
       resourceType,
       account.auth?.value
     )
 
     if (result.length) {
-      const ordered = reorderNodesFromHomeToResource(result, homeNodeUri, resourceId)
+      const ordered = reorderNodesFromHomeToResource(result, community['@id'], resourceId)
 
       await ordered.reduce(async (promiseChain, item) => {
         await promiseChain
-        await fetchTreeNodesFromParentNodeURI(item['@id'])
+        await fetchTreeNodesFromParentNodeURI(item['@id'], community)
         state.value.expandedNodesKeys.push(item.identifier)
       }, Promise.resolve());
       state.value.selectedNodeKey = resourceId
     } else {
       console.warn('No path between home and resource of id "' + resourceId + '" found')
-      await fetchIfEmpty()
+      await fetchIfEmpty(community)
     }
 
     state.value.loading = false
@@ -214,11 +216,22 @@ export const useTreeStore = defineStore('tree', () => {
     }
   }
 
+  function resetState() {
+    state.value = {
+      nodes: [],
+      selectedNodeKey: undefined,
+      expandedNodesKeys: [],
+      loading: false,
+      error: null
+    }
+  }
+
   return {
     state,
     fetchIfEmpty,
     fetchTreeNodesFromParentNodeURI,
     fetchTreeForResource,
+    resetState,
     breadcrumb
   }
 })
-- 
GitLab