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

Feature: Add frontend demo website #37

Open
wants to merge 32 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
4ef44cf
add frontend
syphax-bouazzouni Aug 1, 2024
e0d85ba
clean next default global css
syphax-bouazzouni Nov 11, 2024
ea1bf58
tmp commit
syphax-bouazzouni Nov 11, 2024
a90f02f
Merge remote-tracking branch 'origin/main' into gh-page
syphax-bouazzouni Nov 11, 2024
db22b71
tmp
syphax-bouazzouni Nov 11, 2024
47d8d86
update deploy CI to use gradle
syphax-bouazzouni Dec 19, 2024
4e58d1c
add PostgreSQL database and H2 for test
syphax-bouazzouni Dec 20, 2024
d55e991
add user model and repository layers
syphax-bouazzouni Dec 20, 2024
0fe3b3f
add jwt token generator and filter validator
syphax-bouazzouni Dec 20, 2024
43e5d66
add spring security using the jwtAuthenticationFilter and users
syphax-bouazzouni Dec 20, 2024
042472f
add AuthController to register, login and logout users
syphax-bouazzouni Dec 20, 2024
1ff5994
add a global exception handler
syphax-bouazzouni Dec 20, 2024
a3d7ee3
add properties tests for jwt
syphax-bouazzouni Dec 20, 2024
0079676
add collections crud
syphax-bouazzouni Dec 23, 2024
af3bba4
add better swagger documentation for the authentication features
syphax-bouazzouni Dec 23, 2024
2c04796
add better swagger documentation for the authentication features
syphax-bouazzouni Dec 23, 2024
6845564
Merge branch 'feature/add-user-auth' into feature/collections-feature
syphax-bouazzouni Dec 23, 2024
3ca71b3
Merge branch 'feature/collections-feature' into feature/add-frontend
syphax-bouazzouni Dec 23, 2024
f62bbcf
fix removed main page
syphax-bouazzouni Dec 23, 2024
844c285
create modal utils to handle opening and closing modal
syphax-bouazzouni Dec 23, 2024
ca9f8f3
clean auth and collections controllers and catch better exception
syphax-bouazzouni Dec 27, 2024
2754e33
clean auth and collection controllers
syphax-bouazzouni Dec 27, 2024
7d7411d
catch better bad credentials exception
syphax-bouazzouni Dec 27, 2024
bd3ff9e
add users controlller
syphax-bouazzouni Dec 27, 2024
ed604af
Merge branch 'feature/collections-feature' into feature/add-frontend
syphax-bouazzouni Dec 27, 2024
40cdb73
add tailwind and shadcn
syphax-bouazzouni Dec 27, 2024
891fa6a
add new header design
syphax-bouazzouni Jan 6, 2025
e21ffdb
add .env.sample
syphax-bouazzouni Jan 6, 2025
6031159
add shadcn UI components
syphax-bouazzouni Jan 6, 2025
47fa5a9
updating the homepage design migrating to shadcn ui
syphax-bouazzouni Jan 6, 2025
3c5bfdb
add a placeholder for the login page
syphax-bouazzouni Jan 6, 2025
8f818f1
add key for selector component
syphax-bouazzouni Jan 6, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file added .attach_pid1264587
Empty file.
8 changes: 4 additions & 4 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,13 @@ jobs:
uses: actions/setup-java@v2
with:
distribution: 'temurin'
java-version: '11'
java-version: '17'

- name: Run tests
run: mvn test
run: ./gradlew test

- name: Build with Maven
run: mvn clean package
- name: Build with Gradle
run: ./gradlew clean build

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
Expand Down
57 changes: 18 additions & 39 deletions .github/workflows/deploy-frontend.yml
Original file line number Diff line number Diff line change
@@ -1,60 +1,39 @@
# Sample workflow for building and deploying a Next.js site to GitHub Pages
#
# To get started with Next.js see: https://nextjs.org/docs/getting-started
#
name: Deploy Next.js site to Pages

on:
# Runs on pushes targeting the default branch
push:
branches: ["gh-page"]

# Allows you to run this workflow manually from the Actions tab
branches: [ "gh-page" ]
workflow_dispatch:

# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
permissions:
contents: read
pages: write
id-token: write

# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
concurrency:
group: "pages"
cancel-in-progress: false

jobs:
# Build job
build:
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./src/frontend

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Detect package manager
id: detect-package-manager
run: |
if [ -f "${{ github.workspace }}/yarn.lock" ]; then
echo "manager=yarn" >> $GITHUB_OUTPUT
echo "command=install" >> $GITHUB_OUTPUT
echo "runner=yarn" >> $GITHUB_OUTPUT
exit 0
elif [ -f "${{ github.workspace }}/package.json" ]; then
echo "manager=npm" >> $GITHUB_OUTPUT
echo "command=ci" >> $GITHUB_OUTPUT
echo "runner=npx --no-install" >> $GITHUB_OUTPUT
exit 0
else
echo "Unable to determine package manager"
exit 1
fi

- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: "lts/*"
cache: ${{ steps.detect-package-manager.outputs.manager }}

- name: Create .npmrc for authentication
run: |
echo "//npm.pkg.github.com/:_authToken=${{ secrets.NPM_TOKEN }}" >> ~/.npmrc
echo "@ts4nfdi:registry=https://npm.pkg.github.com" >> ~/.npmrc

- name: Setup Pages
uses: actions/configure-pages@v4
Expand All @@ -64,24 +43,24 @@ jobs:
with:
path: |
.next/cache
# Generate a new cache whenever packages or source files change.
key: ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json', '**/yarn.lock') }}-${{ hashFiles('**.[jt]s', '**.[jt]sx') }}
# If source files changed but packages didn't, rebuild from a prior cache.
key: ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json') }}-${{ hashFiles('**.[jt]s', '**.[jt]sx') }}
restore-keys: |
${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json', '**/yarn.lock') }}-
${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json') }}-

- name: Install dependencies
run: ${{ steps.detect-package-manager.outputs.manager }} ${{ steps.detect-package-manager.outputs.command }}
run: npm install --legacy-peer-deps

- name: Build with Next.js
run: ${{ steps.detect-package-manager.outputs.runner }} next build
run: npm run build

- name: ls
run: ls -l

- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: ./out
path: /home/runner/work/api-gateway/api-gateway/src/frontend/out

# Deployment job
deploy:
environment:
name: github-pages
Expand Down
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,9 @@ bin/
src/frontend/node_modules/

src/frontend/.next/

_next/

src/frontend/.env

node_modules/
4 changes: 1 addition & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
FROM openjdk:11-jre
RUN rm -rf /usr/local/tomcat/webapps/*
RUN mkdir -p /logs
COPY ./target/API-Gateway-0.0.1-SNAPSHOT.jar /usr/local/tomcat/webapps/API-Gateway-0.0.1-SNAPSHOT.jar
COPY ./build/libs/api-gateway-1.0-SNAPSHOT.jar /usr/local/tomcat/webapps/API-Gateway-0.0.1-SNAPSHOT.jar
EXPOSE 8080
CMD ["sh","-c", "java -jar /usr/local/tomcat/webapps/API-Gateway-0.0.1-SNAPSHOT.jar"]


5 changes: 5 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,11 @@ dependencies {
// Swagger UI
implementation group: 'org.springdoc', name: 'springdoc-openapi-starter-webmvc-ui', version: '2.6.0'

// Jwt authentification
implementation 'io.jsonwebtoken:jjwt-api:0.11.5'
runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.11.5'
runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.11.5'

// Tests
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testRuntimeOnly 'com.h2database:h2'
Expand Down
33 changes: 29 additions & 4 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
version: '3.8'

version: '3.9'
services:
api-gateway-backend:
build:
Expand All @@ -8,11 +7,37 @@ services:
container_name: api-gateway
ports:
- "8080:8080"
restart: always
profiles:
- all
depends_on:
- postgres
environment:
ONTOPORTAL_APIKEY: "put here APIKEY"
SPRING_DATASOURCE_URL: jdbc:postgresql://0.0.0.0:5432/db
POSTGRES_PASSWORD: password
POSTGRES_USER: backend
SPRING_JPA_HIBERNATE_DDL_AUTO: update

postgres:
image: postgres
restart: always
environment:
- POSTGRES_DB=db
- POSTGRES_PASSWORD=password
- POSTGRES_USER=developer
ports:
- "5432:5432"
networks:
- api-gateway
- network

adminer:
image: adminer
restart: always
ports:
- "8081:8080"
networks:
- network
networks:
api-gateway:
network:
driver: bridge
1 change: 1 addition & 0 deletions src/frontend/.env.sample
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
API_GATEWAY_URL=https://ts4nfdi-api-gateway.prod.km.k8s.zbmed.de/api-gateway
6 changes: 6 additions & 0 deletions src/frontend/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"extends": "next/core-web-vitals",
"rules": {
"@typescript-eslint/no-explicit-any": "off"
}
}
36 changes: 36 additions & 0 deletions src/frontend/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js
.yarn/install-state.gz

# testing
/coverage

# next.js
/.next/
/out/

# production
/build

# misc
.DS_Store
*.pem

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# local env files
.env*.local

# vercel
.vercel

# typescript
*.tsbuildinfo
next-env.d.ts
24 changes: 24 additions & 0 deletions src/frontend/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Terminology Service Widgets Demonstration
A simple Next.js project to demonstrate the integration of the Terminology Service Suite widgets.

For this demo, a Next.js app was set up in Pycharm with `Node.js v18.17.0`.

## Install and run the demo application

1) Install

```bash
npm install --legacy-peer-deps
```

2) Run
```bash
npm run dev
```

## Implementation

Click [here](https://ts4nfdi.github.io/terminology-service-suite/comp/latest/) for detailed instructions on how to implement the
package.

A sample integration is shown in `MainPage.tsx`.
66 changes: 66 additions & 0 deletions src/frontend/app/Header.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import React from 'react';
import {Button} from '@/components/ui/button';
import {Card, CardContent, CardDescription, CardHeader, CardTitle} from '@/components/ui/card';
import {ExternalLinkIcon} from "lucide-react";
import Link from "next/link";

const PageHeader = () => {
const isLoggedIn = false; //TODO Replace with your auth logic

return (
<div>
<header className="border-b">
<div className="flex h-16 items-center px-4 max-w-7xl mx-auto">
<div className="flex-1 flex items-center gap-2">
<img src={'/api-gateway/logo.png'} alt="Icon" className="w-6 h-6"/>
<h1 className="text-xl font-bold">TSNFDI API Gateway</h1>
</div>

{isLoggedIn ? (
<a href="/profile" className="text-blue-600 hover:underline">
My Profile
</a>
) : (
<Button className="bg-blue-600"><Link href={'/auth/login'}>Login</Link></Button>
)}
</div>
</header>

<div className="bg-gradient-to-r from-blue-600 to-indigo-600">
<Card className="max-w-7xl mx-auto bg-transparent border-0 shadow-none text-white">
<CardHeader className="py-16 w-3/4">
<CardTitle className="text-4xl font-bold">Welcome to TSNFDI API Gateway</CardTitle>
<CardDescription className="text-xl text-white/80 mt-5">
The TS4NFDI Federated Service is an advanced, dynamic solution designed to perform federated
calls across multiple Terminology Services (TS) within NFDI. It is particularly tailored for
environments where integration and aggregation of diverse data sources are essential. The
service offers search capabilities, enabling users to refine search results based on
specific criteria, and supports responses in both JSON and JSON-LD formats.
</CardDescription>
</CardHeader>
<CardContent className="w-2/4">
<a
href={process.env.API_GATEWAY_URL}
target="_blank"
rel="noopener noreferrer"
className="block"
>
<Card className="transition-colors hover:bg-muted/90">
<CardContent className="flex items-center justify-between p-6">
<div className="space-y-1">
<p className="text-sm text-muted-foreground">
Access the API endpoint for documentation and usage
</p>
</div>
<ExternalLinkIcon className="h-5 w-5"/>
</CardContent>
</Card>
</a>
</CardContent>
</Card>
</div>
</div>
);
};

export default PageHeader;
35 changes: 35 additions & 0 deletions src/frontend/app/MainPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import React from 'react';
import {CardContent, CardHeader} from "@/components/ui/card";
import PageHeader from './Header';
import {Separator} from "@/components/ui/separator";
import ArtefactsTable from "@/app/home/browse/BrowseResources";
import Autocomplete from "@/app/home/search/AutoComplete";


export function MainPage({apiUrl}: { apiUrl: string }) {
return (<>
<PageHeader/>
<div className="bg-white w-full">
<div className='container mx-auto space-y-2'>
<CardHeader>
<h2 className='text-2xl font-semibold text-gray-900'>Find a concept</h2>
</CardHeader>
<CardContent>
<Autocomplete apiUrl={`${apiUrl}/search?query=`}/>
</CardContent>
</div>
<Separator/>
<div className='bg-white w-full'>
<div className='container mx-auto my-5 space-y-2'>
<CardHeader>
<h2 className='text-2xl font-semibold text-gray-900'>Browse resources</h2>
</CardHeader>
<CardContent>
<ArtefactsTable apiUrl={`${apiUrl}/artefacts?showResponseConfiguration=true`}/>
</CardContent>
</div>
</div>
</div>
</>
)
}
14 changes: 14 additions & 0 deletions src/frontend/app/auth/login/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import {Card, CardHeader} from "@/components/ui/card";

export default function login() {
return (
<div className='flex justify-center h-screen bg-gray-50'>
<Card className={'mt-12 h-1/4 align-middle flex items-center'}>
<CardHeader>
Not yet enabled, come back soon to use authentification
</CardHeader>
</Card>
</div>
)

}
Binary file added src/frontend/app/favicon.ico
Binary file not shown.
Loading
Loading