Loading portal-gui/package-lock.json +2186 −281 File changed.Preview size limit exceeded, changes collapsed. Show changes portal-gui/package.json +3 −1 Original line number Diff line number Diff line Loading @@ -14,7 +14,9 @@ "react": "19.2.0", "react-dom": "19.2.0", "rsuite": "^6.0.0", "sass": "^1.94.2" "sass": "^1.94.2", "swagger-ui-dist": "^5.32.0", "swagger-ui-react": "^5.32.0" }, "devDependencies": { "@types/node": "^20", Loading portal-gui/src/app/(app)/apis/[id]/apiPage.module.scss +57 −1 Original line number Diff line number Diff line Loading @@ -101,3 +101,59 @@ max-width: 500px; } } /* Hide top description block from Swagger UI */ :global(.swagger-ui .information-container) { display: none; } /* Hide top header */ :global(.swagger-ui .topbar) { display: none; } /* Hide Schemas section */ :global(.swagger-ui .models) { display: none; } /* Hide server selection */ :global(.swagger-ui .scheme-container) { display: none; } /* Hide Filter Field */ :global(.swagger-ui .filter-container) { display: none; } /* JSON keys */ :global(.swagger-ui .hljs-attr) { color: #ffffff !important; } /* JSON punctuation like :, {}, [] */ :global(.swagger-ui .example) { color: #ffffff !important; } :global(.swagger-ui .example span) { color: #ffffff !important; } :global(.swagger-ui .highlight-code) { color: #ffffff !important; } :global(.swagger-ui .highlight-code span) { color: #ffffff !important; } /* Colons and brackets */ :global(.swagger-ui .language-json) { color: #ffffff !important; } /* Make sure responsesare also affected */ :global(.swagger-ui .headerline) { color: #ffffff !important; } :global(.swagger-ui pre code) { color: #ffffff !important; } portal-gui/src/app/(app)/apis/[id]/page.tsx +80 −32 Original line number Diff line number Diff line "use client"; import { IApi } from "@/app/utils/interfaces"; import Link from "next/link"; import "swagger-ui-react/swagger-ui.css"; import styles from "./apiPage.module.scss"; import { global } from "styled-jsx/css"; import { useEffect, useState } from "react"; import { useParams, useRouter } from "next/navigation"; import { IApi } from "@/app/utils/interfaces"; import { backArrowIcon } from "@/app/utils/icons"; import buttons from "@/app/styles/buttons.module.scss"; import { Button, Divider } from "rsuite"; import { useRouter } from "next/navigation"; import Error from "@/app/components/Error/Error"; import ErrorComponent from "@/app/components/Error/Error"; import Loader from "@/app/components/Loader/Loader"; import { useState } from "react"; import { format } from "date-fns"; import { StatusChip } from "@/app/components/Chip/StatusChip"; const api: IApi = { id: "a1f9c7e0-2a18-4ea1-9cd1-7c82f43a1e10", title: "Edge Cloud Zones Discovery", category: "Edge Compute Resources", provider: "Intracom Telecom", functionalities: ["Registration", "Retrieval"], size: 42, description: "Retrieve available edge cloud zones, including detailed metadata about geographical coverage, compute capacity, and supported service types.", protocol: "REST", version: "1.4.2", status: "Active", liveUrl: "https://api.example.com/edge-cloud-zones", published: "2023-11-12T10:32:00Z", instructions: "Use this API to dynamically discover edge zones before deploying compute workloads.", }; // const api: IApi | null = null; import SwaggerUI from "swagger-ui-react"; // import { oeg } from "@/app/utils/constants"; import { filterOpenApiByTag } from "@/app/utils/openapi-utils"; const ApiPage = () => { const {id} = useParams(); const router = useRouter(); const [isLoading, setIsLoading] = useState(false); const [api, setApi] = useState<IApi | null>(null); // const [swaggerSpec, setSwaggerSpec] = useState<any | null>(null); const [isLoading, setIsLoading] = useState(true); useEffect(() => { const fetchApi = async() => { try { // Fetch the hardcoded API details const res = await fetch(`/api/apis/${id}`); if (!res.ok) throw new Error("Not found"); const data = await res.json(); setApi(data); // Fetch the OpenAPI JSON // const specRes = await fetch("/api/swagger"); // const spec = await specRes.json(); // Filter spec by the API category (?) // const filteredSpec = filterOpenApiByTag(spec, data.category || data.title); // delete filteredSpec.info.description; // console.log("filteredSpec = " + filteredSpec); // setSwaggerSpec(filteredSpec); } catch (err) { setApi(null); // setSwaggerSpec(null); } finally { setIsLoading(false); } }; fetchApi(); }, [id]); if (isLoading) return <Loader />; if (!api) return ( <Error href="/" message="No selected Api found" linkText="Back to Home" /> <ErrorComponent href="/" message="No selected Api found" linkText="Back to Home" /> ); return ( Loading @@ -61,13 +85,7 @@ const ApiPage = () => { ))} </div> <p className={styles.meta}> <strong>Provider:</strong> {api.provider} </p> <p className={styles.meta}> <strong>Size:</strong> {api.size} <small>MB</small> </p> <Button className={buttons.primary}>Activate</Button> {/* <Button className={buttons.primary}>Activate</Button> */} <div className={styles.descriptionBox}> <h3>Description</h3> <p>{api.description}</p> Loading Loading @@ -96,7 +114,37 @@ const ApiPage = () => { <h3>How it works</h3> <p>{api.instructions}</p> </div> </div> <Divider size="sm" label="API Documentation" color="#004a8d" /> {/* Swagger UI */} {/* {swaggerSpec ? <SwaggerUI spec={swaggerSpec} docExpansion="none" // collapse endpoints defaultModelsExpandDepth={-1} // hides Schemas section defaultModelExpandDepth={-1} // hides model details displayRequestDuration={false} displayOperationId={false} tryItOutEnabled={true} filter={false} showExtensions={false} showCommonExtensions={false} /> : <p>Swagger spec not available</p> } */} <SwaggerUI url="/api/swagger" docExpansion="list" defaultModelsExpandDepth={-1} // hides Schemas section defaultModelExpandDepth={-1} // hides model details displayOperationId={false} displayRequestDuration={false} filter={api.tag} tryItOutEnabled={true} /> </div> ); }; Loading portal-gui/src/app/api/proxy/[...path]/route.ts 0 → 100644 +62 −0 Original line number Diff line number Diff line // import { error } from "console"; import { NextResponse, NextRequest } from "next/server"; import { oeg } from "@/app/utils/constants"; async function proxy( req: NextRequest) { try { // console.log("Request = " + req.nextUrl); const urlparts1 = req.nextUrl.toString().split('/'); const urlparts2 = urlparts1[urlparts1.length - 1].split('?'); const tag = urlparts2[0]; // console.log("Tag = " + tag); const search = req.nextUrl.search; // console.log("search = " + search); const targetUrl = `${oeg.baseUrl}${tag}${search}`; // console.log("Proxying to: " + targetUrl); const backendRes = await fetch( targetUrl, { method: req.method, headers: { "Content-Type": req.headers.get("content-type") || "application/json", Accept: req.headers.get("accept") || "application/json" }, body: req.method !== "GET" && req.method !== "HEAD" ? await req.text() : undefined } ); // Return raw response return new NextResponse(backendRes.body, { status: backendRes.status, headers: { "Content-Type": backendRes.headers.get("content-type") || "application/json" } }); } catch (err) { console.error("Proxy error:", err); return NextResponse.json( { error: "Proxy failed" }, { status: 500 } ); }; } export const GET = proxy; export const POST = proxy; export const PUT = proxy; export const DELETE = proxy; export const PATCH = proxy; Loading
portal-gui/package-lock.json +2186 −281 File changed.Preview size limit exceeded, changes collapsed. Show changes
portal-gui/package.json +3 −1 Original line number Diff line number Diff line Loading @@ -14,7 +14,9 @@ "react": "19.2.0", "react-dom": "19.2.0", "rsuite": "^6.0.0", "sass": "^1.94.2" "sass": "^1.94.2", "swagger-ui-dist": "^5.32.0", "swagger-ui-react": "^5.32.0" }, "devDependencies": { "@types/node": "^20", Loading
portal-gui/src/app/(app)/apis/[id]/apiPage.module.scss +57 −1 Original line number Diff line number Diff line Loading @@ -101,3 +101,59 @@ max-width: 500px; } } /* Hide top description block from Swagger UI */ :global(.swagger-ui .information-container) { display: none; } /* Hide top header */ :global(.swagger-ui .topbar) { display: none; } /* Hide Schemas section */ :global(.swagger-ui .models) { display: none; } /* Hide server selection */ :global(.swagger-ui .scheme-container) { display: none; } /* Hide Filter Field */ :global(.swagger-ui .filter-container) { display: none; } /* JSON keys */ :global(.swagger-ui .hljs-attr) { color: #ffffff !important; } /* JSON punctuation like :, {}, [] */ :global(.swagger-ui .example) { color: #ffffff !important; } :global(.swagger-ui .example span) { color: #ffffff !important; } :global(.swagger-ui .highlight-code) { color: #ffffff !important; } :global(.swagger-ui .highlight-code span) { color: #ffffff !important; } /* Colons and brackets */ :global(.swagger-ui .language-json) { color: #ffffff !important; } /* Make sure responsesare also affected */ :global(.swagger-ui .headerline) { color: #ffffff !important; } :global(.swagger-ui pre code) { color: #ffffff !important; }
portal-gui/src/app/(app)/apis/[id]/page.tsx +80 −32 Original line number Diff line number Diff line "use client"; import { IApi } from "@/app/utils/interfaces"; import Link from "next/link"; import "swagger-ui-react/swagger-ui.css"; import styles from "./apiPage.module.scss"; import { global } from "styled-jsx/css"; import { useEffect, useState } from "react"; import { useParams, useRouter } from "next/navigation"; import { IApi } from "@/app/utils/interfaces"; import { backArrowIcon } from "@/app/utils/icons"; import buttons from "@/app/styles/buttons.module.scss"; import { Button, Divider } from "rsuite"; import { useRouter } from "next/navigation"; import Error from "@/app/components/Error/Error"; import ErrorComponent from "@/app/components/Error/Error"; import Loader from "@/app/components/Loader/Loader"; import { useState } from "react"; import { format } from "date-fns"; import { StatusChip } from "@/app/components/Chip/StatusChip"; const api: IApi = { id: "a1f9c7e0-2a18-4ea1-9cd1-7c82f43a1e10", title: "Edge Cloud Zones Discovery", category: "Edge Compute Resources", provider: "Intracom Telecom", functionalities: ["Registration", "Retrieval"], size: 42, description: "Retrieve available edge cloud zones, including detailed metadata about geographical coverage, compute capacity, and supported service types.", protocol: "REST", version: "1.4.2", status: "Active", liveUrl: "https://api.example.com/edge-cloud-zones", published: "2023-11-12T10:32:00Z", instructions: "Use this API to dynamically discover edge zones before deploying compute workloads.", }; // const api: IApi | null = null; import SwaggerUI from "swagger-ui-react"; // import { oeg } from "@/app/utils/constants"; import { filterOpenApiByTag } from "@/app/utils/openapi-utils"; const ApiPage = () => { const {id} = useParams(); const router = useRouter(); const [isLoading, setIsLoading] = useState(false); const [api, setApi] = useState<IApi | null>(null); // const [swaggerSpec, setSwaggerSpec] = useState<any | null>(null); const [isLoading, setIsLoading] = useState(true); useEffect(() => { const fetchApi = async() => { try { // Fetch the hardcoded API details const res = await fetch(`/api/apis/${id}`); if (!res.ok) throw new Error("Not found"); const data = await res.json(); setApi(data); // Fetch the OpenAPI JSON // const specRes = await fetch("/api/swagger"); // const spec = await specRes.json(); // Filter spec by the API category (?) // const filteredSpec = filterOpenApiByTag(spec, data.category || data.title); // delete filteredSpec.info.description; // console.log("filteredSpec = " + filteredSpec); // setSwaggerSpec(filteredSpec); } catch (err) { setApi(null); // setSwaggerSpec(null); } finally { setIsLoading(false); } }; fetchApi(); }, [id]); if (isLoading) return <Loader />; if (!api) return ( <Error href="/" message="No selected Api found" linkText="Back to Home" /> <ErrorComponent href="/" message="No selected Api found" linkText="Back to Home" /> ); return ( Loading @@ -61,13 +85,7 @@ const ApiPage = () => { ))} </div> <p className={styles.meta}> <strong>Provider:</strong> {api.provider} </p> <p className={styles.meta}> <strong>Size:</strong> {api.size} <small>MB</small> </p> <Button className={buttons.primary}>Activate</Button> {/* <Button className={buttons.primary}>Activate</Button> */} <div className={styles.descriptionBox}> <h3>Description</h3> <p>{api.description}</p> Loading Loading @@ -96,7 +114,37 @@ const ApiPage = () => { <h3>How it works</h3> <p>{api.instructions}</p> </div> </div> <Divider size="sm" label="API Documentation" color="#004a8d" /> {/* Swagger UI */} {/* {swaggerSpec ? <SwaggerUI spec={swaggerSpec} docExpansion="none" // collapse endpoints defaultModelsExpandDepth={-1} // hides Schemas section defaultModelExpandDepth={-1} // hides model details displayRequestDuration={false} displayOperationId={false} tryItOutEnabled={true} filter={false} showExtensions={false} showCommonExtensions={false} /> : <p>Swagger spec not available</p> } */} <SwaggerUI url="/api/swagger" docExpansion="list" defaultModelsExpandDepth={-1} // hides Schemas section defaultModelExpandDepth={-1} // hides model details displayOperationId={false} displayRequestDuration={false} filter={api.tag} tryItOutEnabled={true} /> </div> ); }; Loading
portal-gui/src/app/api/proxy/[...path]/route.ts 0 → 100644 +62 −0 Original line number Diff line number Diff line // import { error } from "console"; import { NextResponse, NextRequest } from "next/server"; import { oeg } from "@/app/utils/constants"; async function proxy( req: NextRequest) { try { // console.log("Request = " + req.nextUrl); const urlparts1 = req.nextUrl.toString().split('/'); const urlparts2 = urlparts1[urlparts1.length - 1].split('?'); const tag = urlparts2[0]; // console.log("Tag = " + tag); const search = req.nextUrl.search; // console.log("search = " + search); const targetUrl = `${oeg.baseUrl}${tag}${search}`; // console.log("Proxying to: " + targetUrl); const backendRes = await fetch( targetUrl, { method: req.method, headers: { "Content-Type": req.headers.get("content-type") || "application/json", Accept: req.headers.get("accept") || "application/json" }, body: req.method !== "GET" && req.method !== "HEAD" ? await req.text() : undefined } ); // Return raw response return new NextResponse(backendRes.body, { status: backendRes.status, headers: { "Content-Type": backendRes.headers.get("content-type") || "application/json" } }); } catch (err) { console.error("Proxy error:", err); return NextResponse.json( { error: "Proxy failed" }, { status: 500 } ); }; } export const GET = proxy; export const POST = proxy; export const PUT = proxy; export const DELETE = proxy; export const PATCH = proxy;