Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Task/86 markdown description #104

Merged
merged 11 commits into from
Oct 8, 2024
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"js-file-download": "^0.4.12",
"jwt-decode": "^3.1.2",
"keycloak-js": "^22.0.5",
"markdown-to-jsx": "^7.5.0",
"mem": "^9.0.2",
"moment": "^2.29.3",
"n3": "^1.17.3",
Expand Down
63 changes: 63 additions & 0 deletions src/common/markdown/Markdown.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
.markdown {
font-size: large;
font-weight: lighter;
text-align: justify;
}

.markdown table {
width: 100%;
border: 1px solid black;
border-collapse: collapse;
margin: 20px 0;
}

.markdown th,
.markdown td {
border: 1px solid black;
padding: 8px;
text-align: left;
}

.markdown th {
background-color: #f2f2f2;
font-weight: bold;
}

.markdown tr:nth-child(even) {
background-color: #f9f9f9;
}

.markdown tr:hover {
background-color: #e0e0e0;
}

.markdown pre {
background-color: #f5f5f5;
border: 1px solid #ccc;
border-radius: 4px;
padding: 10px;
overflow-x: auto;
font-family: 'Courier New', Courier, monospace;
white-space: pre-wrap;
}

.markdown code {
background-color: #e8e8e8;
border-radius: 4px;
padding: 2px 4px;
font-family: 'Courier New', Courier, monospace;
}

.markdown pre code {
background: none;
color: inherit;
}

.item-card .markdown {
max-height: 200px;
overflow: hidden;
}

.ellipsis {
margin: auto;
}
34 changes: 34 additions & 0 deletions src/common/markdown/Markdown.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import MarkdownToJSX from 'markdown-to-jsx';
import React, { useEffect, useRef, useState } from 'react';
import './Markdown.css'

type MarkdownProps = {
children: React.ReactNode;
};

const Markdown: React.FC<MarkdownProps> = ({ children }) => {
const [isTruncated, setIsTruncated] = useState(false);
const contentRef = useRef<HTMLDivElement | null>(null);

useEffect(() => {
const checkTruncation = () => {
if (contentRef.current) {
setIsTruncated(contentRef.current.scrollHeight > contentRef.current.clientHeight + 1);
}
}

checkTruncation();

}, [children]);

return (
<>
<div ref={contentRef} className='markdown'>
<MarkdownToJSX>{children}</MarkdownToJSX>
</div>
{isTruncated && <div className='ellipsis'>...</div>}
</>
);
};

export default Markdown;
3 changes: 2 additions & 1 deletion src/components/ItemCard/ItemCard.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import classNames from 'classnames';
import { FC } from 'react';
import { useTranslation } from 'react-i18next';

Expand Down Expand Up @@ -33,7 +34,7 @@ const ItemCard: FC<IItemCard> = ({
const { t } = useTranslation();

return (
<div className={styles.card}>
<div className={classNames(styles.card, 'item-card')}>
<div className={styles.label}>
<Title>{label}</Title>
{isGaiaXCompliant === undefined ? null : (
Expand Down
5 changes: 3 additions & 2 deletions src/components/ItemCard/OntologyCardContent.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { FC } from 'react';
import React, { FC } from 'react';
import { useTranslation } from 'react-i18next';
import { useNavigate } from 'react-router-dom';

import Markdown from '../../common/markdown/Markdown';
import { Ontology } from '../../types/ontologies.model';
import Title from '../Title/Title';
import GaiaXButton from '../buttons/GaiaXButton';
Expand All @@ -26,7 +27,7 @@ const OntologyCardContent: FC<IOntologyCardContent> = ({ ontology } ) => {
<div style={{ textAlign: 'left' }}>
<Title>{ontology.subject}</Title>
</div>
<p>{ontology.description}</p>
<Markdown>{ontology.description}</Markdown>
<div className={styles.button}>
<GaiaXButton
label={t('details.more-details')}
Expand Down
7 changes: 4 additions & 3 deletions src/components/ItemCard/ResourceCardContent.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { FC } from 'react';
import React, { FC } from 'react';
import { useTranslation } from 'react-i18next';
import { useNavigate } from 'react-router-dom';

import Markdown from '../../common/markdown/Markdown';
import { Resource } from '../../types/resources.model';
import Title from '../Title/Title';
import GaiaXButton from '../buttons/GaiaXButton';
Expand All @@ -18,7 +19,7 @@ const ResourceCardContent: FC<IResourceCardContent> = ({ resource }) => {

const handleNavigationToDetailsPage = () => {
const encodedUri = encodeURIComponent(JSON.stringify(resource.claimsGraphUri));
navigate(`/details/${encodedUri}`);
navigate(`/resources/${encodedUri}`);
};

return (
Expand All @@ -29,7 +30,7 @@ const ResourceCardContent: FC<IResourceCardContent> = ({ resource }) => {
))
}
</Title>
<p>{resource.description}</p>
<Markdown>{resource.description}</Markdown>
<div className={styles.button}>
<GaiaXButton
label={t('details.more-details')}
Expand Down
5 changes: 3 additions & 2 deletions src/components/Routes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { Route, Routes as ReactRoutes } from 'react-router-dom';

import WorkInProgress from '../WorkInProgress';
import { Column } from '../common/styles';
import DetailsPage from '../pages/details/DetailsPage';
import Home from '../pages/home/Home';

import AccountHome from './account/AccountHome';
Expand All @@ -12,6 +11,7 @@ import DashboardPage from './dashboard/dashboard_page';
import LcmFinal from './dashboard/lcm/LcmFinal';
import LcmServices from './dashboard/lcm/LcmServices';
import OntologiesDetailsPage from './detailsPage/pages/ontologies/OntologiesDetailsPage';
import ResourceDetailsPage from './detailsPage/pages/resources/ResourceDetailsPage';
import ShapesDetailsPage from './detailsPage/pages/shapes/ShapesDetailsPage';
import DiscoveryItem from './discovery/DiscoveryItem';
import SearchView from './discovery/search/SearchView';
Expand Down Expand Up @@ -43,7 +43,8 @@ const Routes: FC = () => (
<Route path="/service-offerings" element={ViewContainer(<ProtectedRoute><ServiceOfferings/></ProtectedRoute>)}/>
<Route path="/participants" element={ViewContainer(<Participants />)} />
<Route path="/resources" element={ViewContainer(<ProtectedRoute><Resources /></ProtectedRoute>)} />
<Route path="/details/:resourceId" element={ViewContainer(<ProtectedRoute><DetailsPage/></ProtectedRoute>)}/>
<Route path="/resources/:resourceId"
element={ViewContainer(<ProtectedRoute><ResourceDetailsPage/></ProtectedRoute>)}/>
<Route path="/services" element={ViewContainer(<SearchView type="services" />)} />
<Route path="/help" element={ViewContainer(<WorkInProgress component="Help" />)} />
<Route path="/loginfail" element={ViewContainer(<LoginFail />)} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { FC, useContext } from 'react';
import { useTranslation } from 'react-i18next';
import { useNavigate } from 'react-router-dom';

import Markdown from '../../../../common/markdown/Markdown';
import { OntologyContext } from '../../../../context/OntologyContext';
import { Shape } from '../../../../types/shapes.model';
import Text from '../../../Text/Text';
Expand All @@ -25,7 +26,9 @@ const OntologyMainContent: FC = () => {
return (
<div className={styles['container']}>
<Title>{t('ontologies.title')}</Title>
<Text>{ontology.description}</Text>
<Markdown>
{ontology.description}
</Markdown>
{ontology.relatedShapes.length > 0 && (
<div style={{ textAlign: 'left' }}>
<Text>{t('ontologies.classes')}</Text>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
.details-page-container {
display: flex;
flex-direction: row;
justify-content: space-between;
width: auto;
}

.new-car-loader {
display: flex;
justify-content: center;
}
62 changes: 62 additions & 0 deletions src/components/detailsPage/pages/resources/ResourceDetailsPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import MapCard from 'components/cards/MapCard';
import SidebarCard from 'components/cards/SidebarCard';
import { AuthContext } from 'context/AuthContextProvider';
import { useContext, useEffect, useState } from 'react';
import { useParams } from 'react-router-dom';
import { CypherQueryApiService as cypherQuery } from 'services/cypherQueryApiService';

import LoadingIndicator from '../../../loading_view/LoadingIndicator';
import NoContent from '../../../nocontent/NoContent';

import styles from './ResourceDatails.module.css';
import ResourceMainContent from './ResourceMainContent';

export default function ResourceDetailsPage() {
const authContext = useContext(AuthContext);
const [selfDescriptionData, setSelfDescriptionData] = useState(null);
const { resourceId } = useParams();
const [isLoading, setIsLoading] = useState(true);

useEffect(() => {
const fetchAndSetSelfDescriptions = async () => {
try {
const response = await cypherQuery.getOneSelfDescriptions(resourceId);
console.log('Fetched data: ', response);
if (response) {
setSelfDescriptionData(response);
}
} finally {
setIsLoading(false);
}
};

if (resourceId && authContext.isAuthenticated) {
fetchAndSetSelfDescriptions();
}
}, [resourceId, authContext.isAuthenticated]);

return (
<div className={styles['details-page-container']}>
<LoadingIndicator visible={isLoading}/>
{!isLoading && (
<>
<NoContent message={'No data available.'} visible={!selfDescriptionData}/>
{selfDescriptionData && (
<>
<div>
<ResourceMainContent cardData={selfDescriptionData}/>
</div>
<div>
<MapCard/>
<SidebarCard
title="Offered by"
subtitle="3D Mapping Solutions GmbH"
text="We offer high-precision 3D map data of roads and urban environments for applications in autonomous driving, robotics, urban planning and navigation systems."
/>
</div>
</>)}
</>
)}
</div>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
.details-card-container {
box-shadow: 10px 15px 20px rgba(0, 0, 0, 0.25);
display: flex;
flex-direction: column;
flex: 1;
align-items: flex-start;
padding: 30px;
width: 90%;
background-color: white;
margin-top: 20px;
margin-bottom: 20px;
border-radius: 10px;
}

.details-grid-container {
display: grid;
grid-template-columns: repeat(2, 1fr); /* Creates two columns of equal width */
margin-top: 20px; /* Optional: Adds some space above the grid */
justify-items: stretch;
align-items: start;
}
Loading