This is an automated email from the ASF dual-hosted git repository.

lahirujayathilake pushed a commit to branch cybershuttle-staging
in repository https://gitbox.apache.org/repos/asf/airavata.git


The following commit(s) were added to refs/heads/cybershuttle-staging by this 
push:
     new adee56c567 File tree added to ProjectDetails.tsx
adee56c567 is described below

commit adee56c567facefd6bee4a0b600ce907f1c3e097
Author: javad-aslanov <[email protected]>
AuthorDate: Mon Mar 31 18:45:12 2025 -0400

    File tree added to ProjectDetails.tsx
---
 .../src/components/notebooks/ProjectDetails.tsx    | 163 ++++++++++++++-------
 1 file changed, 114 insertions(+), 49 deletions(-)

diff --git 
a/modules/research-framework/portal/src/components/notebooks/ProjectDetails.tsx 
b/modules/research-framework/portal/src/components/notebooks/ProjectDetails.tsx
index 2cf9590076..9b9141d712 100644
--- 
a/modules/research-framework/portal/src/components/notebooks/ProjectDetails.tsx
+++ 
b/modules/research-framework/portal/src/components/notebooks/ProjectDetails.tsx
@@ -8,7 +8,7 @@ import {
   Separator,
   Button,
   Icon,
-  Link as ChakraLink,
+  Link as ChakraLink, Heading, ListItem, Center, ListRoot,
 } from "@chakra-ui/react";
 // @ts-expect-error This is fine
 import { MOCK_PROJECTS } from "../../data/MOCK_DATA";
@@ -16,16 +16,25 @@ import { useEffect, useState } from "react";
 import { BiArrowBack } from "react-icons/bi";
 import { ProjectType } from "@/interfaces/ProjectType";
 import { Metadata } from "../Metadata";
+import {FiFile, FiFolder} from "react-icons/fi";
+
+interface FileTreeItem {
+  name: string;
+  type: string;
+  sha: string;
+}
 
 async function getProject(slug: string | undefined) {
   return MOCK_PROJECTS.find(
-    (project: ProjectType) => project.metadata.slug === slug
+      (project: ProjectType) => project.metadata.slug === slug
   );
 }
 
 const ProjectDetails = () => {
   const { slug } = useParams();
   const [project, setProject] = useState<ProjectType | null>(null);
+  const [fileTree, setFileTree] = useState<FileTreeItem[]>([]);
+  const [fileTreeLoading, setFileTreeLoading] = useState(false);
 
   useEffect(() => {
     if (!slug) return;
@@ -37,61 +46,117 @@ const ProjectDetails = () => {
     getData();
   }, [slug]);
 
-  if (!project) return <Spinner />;
-
   const isNotebook = project?.notebookViewer !== undefined;
 
-  return (
-    <>
-      <NavBar />
+  useEffect(() => {
+    if (project && !isNotebook) {
+      const repoUrl = project.repositoryUrl;
+      // @ts-expect-error This is fine
+      const match = repoUrl.match(/github\.com\/([^/]+)\/([^/]+)/);
+      if (match) {
+        const owner = match[1];
+        const repo = match[2].replace(/\.git$/, "");
+        setFileTreeLoading(true);
+        fetch(`https://api.github.com/repos/${owner}/${repo}/contents`)
+            .then((res) => res.json())
+            .then((data) => {
+              setFileTree(data);
+              setFileTreeLoading(false);
+            })
+            .catch((error) => {
+              console.error("Error fetching file tree:", error);
+              setFileTreeLoading(false);
+            });
+      }
+    }
+  }, [project, isNotebook]);
 
-      <Container maxW="breakpoint-lg" mx="auto" p={4} mt={16}>
-        <Box>
-          <HStack alignItems="center" mb={4}>
-            <Icon>
-              <BiArrowBack />
-            </Icon>
-            <Link to="/">Back to Projects</Link>
-          </HStack>
-        </Box>
-        <Metadata metadata={project.metadata} />
+  if (!project) return <Spinner />;
 
-        <Separator my={8} />
+  return (
+      <>
+        <NavBar />
 
-        <Button colorPalette="teal" mb={4} w="full">
-          <ChakraLink
-            target="_blank"
-            href={project?.notebookViewer || project?.repositoryUrl}
-            color="white"
-            fontWeight="bold"
-            display="block"
-            width="100%"
-            textAlign="center"
-          >
-            Open
-          </ChakraLink>
-        </Button>
+        <Container maxW="breakpoint-lg" mx="auto" p={4} mt={16}>
+          <Box>
+            <HStack alignItems="center" mb={4}>
+              <Icon>
+                <BiArrowBack />
+              </Icon>
+              <Link to="/">Back to Projects</Link>
+            </HStack>
+          </Box>
+          <Metadata metadata={project.metadata} />
 
-        <Box border="2px solid black">
-          <Box height="600px" borderRadius="md" overflow="hidden">
-            {isNotebook ? (
-              <iframe
-                title="notebook"
-                src={project?.notebookViewer}
-                width="100%"
-                height="100%"
-              />
-            ) : (
-              <iframe
+          <Separator my={8} />
+
+          <Button colorPalette="teal" mb={4} w="full">
+            <ChakraLink
+                target="_blank"
+                href={project?.notebookViewer || project?.repositoryUrl}
+                color="white"
+                fontWeight="bold"
+                display="block"
                 width="100%"
-                height="100%"
-                
src={`https://emgithub.com/iframe.html?target=${project.repositoryUrl}%2Fblob%2Fmaster%2FREADME.md&style=default&type=markdown&showBorder=on&showLineNumbers=on&showFileMeta=on&showFullPath=on&showCopy=on`}
-              ></iframe>
-            )}
+                textAlign="center"
+            >
+              Open
+            </ChakraLink>
+          </Button>
+
+          <Box border="1px" borderColor="gray.200" borderRadius="md" 
overflow="hidden">
+            <Box height="600px" bg="gray.50" p={4} overflow="auto">
+              {isNotebook ? (
+                  <iframe
+                      title="notebook"
+                      src={project?.notebookViewer}
+                      width="100%"
+                      height="100%"
+                      style={{ border: "none" }}
+                  />
+              ) : fileTreeLoading ? (
+                  <Center height="100%">
+                    <Spinner size="xl" />
+                  </Center>
+              ) : (
+                  <Box
+                      bg="white"
+                      p={4}
+                      borderRadius="md"
+                      shadow="md"
+                      overflow="auto"
+                      height="full"
+                  >
+                    <Heading as="h2" size="lg" mb={4}>
+                      {project.metadata.title}
+                    </Heading>
+                    <ListRoot>
+                      {fileTree &&
+                          fileTree.map((file) => (
+                              <ListItem
+                                  key={file.sha}
+                                  display="flex"
+                                  alignItems="center"
+                                  p={2}
+                                  borderRadius="md"
+                                  _hover={{ bg: "gray.100" }}
+                              >
+                                <Icon
+                                    as={file.type === "dir" ? FiFolder : 
FiFile}
+                                    color={file.type === "dir" ? "blue.500" : 
"gray.500"}
+                                    mr={2}
+                                />
+
+                                <p>{file.name}</p>
+                              </ListItem>
+                          ))}
+                    </ListRoot>
+                  </Box>
+              )}
+            </Box>
           </Box>
-        </Box>
-      </Container>
-    </>
+        </Container>
+      </>
   );
 };
 

Reply via email to