generated from Luis/nextjs-python-web-template
Compare commits
39 Commits
09f80b1f42
...
dev
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
102e38988c | ||
|
|
4e7c44eeb5 | ||
|
|
3238cdf36d | ||
|
|
1abbc383ec | ||
| 5a09cc8e31 | |||
|
|
c6e1b8a21d | ||
|
|
afe291c54c | ||
| 6024090f69 | |||
|
|
596e87c31b | ||
|
|
06c55f151b | ||
|
|
04675f5e9e | ||
|
|
b5008306cb | ||
|
|
1b549549c0 | ||
|
|
29aa17ca7c | ||
|
|
e06afab048 | ||
|
|
697d2685f3 | ||
|
|
2f6ad476b3 | ||
|
|
dc04001dca | ||
|
|
3828402865 | ||
|
|
5b64eb4c3f | ||
|
|
eebc7eee20 | ||
|
|
2e787aa386 | ||
|
|
90c6df93f4 | ||
| 374fdfdaea | |||
|
|
a240cfd340 | ||
|
|
eaec0feb96 | ||
|
|
f3ab6e1b45 | ||
|
|
2c79dabce0 | ||
|
|
fd09d73edd | ||
|
|
2000c1444a | ||
|
|
b98c6090af | ||
| 42a25a2eda | |||
| b6b2bfbee5 | |||
|
|
ea0148fdaf | ||
|
|
7ae1d5f768 | ||
|
|
ec67dd1bac | ||
|
|
522d7eb69a | ||
|
|
07a5a2fc24 | ||
|
|
59e33f3ead |
12
.gitlab-ci.yml
Normal file
12
.gitlab-ci.yml
Normal file
@@ -0,0 +1,12 @@
|
||||
stages:
|
||||
- release
|
||||
|
||||
release:
|
||||
stage: release
|
||||
script:
|
||||
- set -x
|
||||
- ./service-aware-network-front-end/pkgs/clan-cli/push_docker.sh
|
||||
only:
|
||||
- dev
|
||||
tags:
|
||||
- ea
|
||||
@@ -5,7 +5,11 @@ cors_url = [
|
||||
"http://0.0.0.0",
|
||||
"http://[::]",
|
||||
]
|
||||
cors_ports = ["*", 3000, 2979]
|
||||
cors_ports = ["*", 3000, 2979, 8001, 8002]
|
||||
cors_whitelist = []
|
||||
for u in cors_url:
|
||||
for p in cors_ports:
|
||||
cors_whitelist.append(f"{u}:{p}")
|
||||
|
||||
# host for the server, frontend, backend and emulators
|
||||
host = "127.0.0.1"
|
||||
|
||||
@@ -6,6 +6,7 @@ from datetime import datetime
|
||||
|
||||
# Importing FastAPI and related components
|
||||
from fastapi import FastAPI
|
||||
from fastapi.middleware.cors import CORSMiddleware
|
||||
from fastapi.responses import HTMLResponse, JSONResponse
|
||||
|
||||
# Importing configuration and schemas from the clan_cli package
|
||||
@@ -25,6 +26,14 @@ apps = [
|
||||
(app_c1, config.c1_port),
|
||||
(app_c2, config.c2_port),
|
||||
]
|
||||
for app, port in apps:
|
||||
app.add_middleware(
|
||||
CORSMiddleware,
|
||||
allow_origins=config.cors_whitelist,
|
||||
allow_credentials=True,
|
||||
allow_methods=["*"],
|
||||
allow_headers=["*"],
|
||||
)
|
||||
|
||||
|
||||
# Healthcheck endpoints for different applications
|
||||
@@ -97,11 +106,13 @@ async def consume_service_from_other_entity_c1() -> HTMLResponse:
|
||||
|
||||
@app_c1.get("/v1/print_daemon1/register", response_class=JSONResponse)
|
||||
async def register_c1() -> JSONResponse:
|
||||
time.sleep(2)
|
||||
return JSONResponse(content={"status": "registered"}, status_code=200)
|
||||
|
||||
|
||||
@app_c1.get("/v1/print_daemon1/deregister", response_class=JSONResponse)
|
||||
async def deregister_c1() -> JSONResponse:
|
||||
time.sleep(2)
|
||||
return JSONResponse(content={"status": "deregistered"}, status_code=200)
|
||||
|
||||
|
||||
@@ -119,13 +130,15 @@ async def consume_service_from_other_entity_c2() -> HTMLResponse:
|
||||
return HTMLResponse(content=html_content, status_code=200)
|
||||
|
||||
|
||||
@app_c2.get("/v1/print_daemon1/register", response_class=JSONResponse)
|
||||
@app_c2.get("/v1/print_daemon2/register", response_class=JSONResponse)
|
||||
async def register_c2() -> JSONResponse:
|
||||
time.sleep(2)
|
||||
return JSONResponse(content={"status": "registered"}, status_code=200)
|
||||
|
||||
|
||||
@app_c2.get("/v1/print_daemon1/deregister", response_class=JSONResponse)
|
||||
@app_c2.get("/v1/print_daemon2/deregister", response_class=JSONResponse)
|
||||
async def deregister_c2() -> JSONResponse:
|
||||
time.sleep(2)
|
||||
return JSONResponse(content={"status": "deregistered"}, status_code=200)
|
||||
|
||||
|
||||
@@ -138,32 +151,9 @@ async def ap_list_of_services() -> JSONResponse:
|
||||
"uuid": "bdd640fb-0667-1ad1-1c80-317fa3b1799d",
|
||||
"service_name": "Carlos Printing0",
|
||||
"service_type": "3D Printing",
|
||||
"endpoint_url": "http://127.0.0.1:8000/v1/print_daemon0",
|
||||
"other": {},
|
||||
"entity_did": "did:sov:test:120",
|
||||
"status": {"data": ["draft", "registered"]},
|
||||
"action": {
|
||||
"data": [
|
||||
{
|
||||
"name": "register",
|
||||
"endpoint": "http://127.0.0.1:8000/v1/print_daemon0/register",
|
||||
},
|
||||
{
|
||||
"name": "deregister",
|
||||
"endpoint": "http://127.0.0.1:8000/v1/print_daemon0/deregister",
|
||||
},
|
||||
]
|
||||
},
|
||||
"usage": [{"times_consumed": 2, "consumer_entity_did": "did:sov:test:120"}],
|
||||
},
|
||||
# Service 2 (similar structure)
|
||||
{
|
||||
"uuid": "23b8c1e9-3924-56de-3eb1-3b9046685257",
|
||||
"service_name": "Carlos Printing1",
|
||||
"service_type": "3D Printing",
|
||||
"endpoint_url": "http://127.0.0.1:8001/v1/print_daemon1",
|
||||
"other": {},
|
||||
"entity_did": "did:sov:test:121",
|
||||
"entity_did": "did:sov:test:120",
|
||||
"status": {"data": ["draft", "registered"]},
|
||||
"action": {
|
||||
"data": [
|
||||
@@ -179,13 +169,14 @@ async def ap_list_of_services() -> JSONResponse:
|
||||
},
|
||||
"usage": [{"times_consumed": 2, "consumer_entity_did": "did:sov:test:120"}],
|
||||
},
|
||||
# Service 2 (similar structure)
|
||||
{
|
||||
"uuid": "bd9c66b3-ad3c-2d6d-1a3d-1fa7bc8960a9",
|
||||
"service_name": "Carlos Printing2",
|
||||
"uuid": "23b8c1e9-3924-56de-3eb1-3b9046685257",
|
||||
"service_name": "Carlos Printing1",
|
||||
"service_type": "3D Printing",
|
||||
"endpoint_url": "http://127.0.0.1:8002/v1/print_daemon2",
|
||||
"other": {},
|
||||
"entity_did": "did:sov:test:122",
|
||||
"entity_did": "did:sov:test:121",
|
||||
"status": {"data": ["draft", "registered"]},
|
||||
"action": {
|
||||
"data": [
|
||||
@@ -202,12 +193,12 @@ async def ap_list_of_services() -> JSONResponse:
|
||||
"usage": [{"times_consumed": 2, "consumer_entity_did": "did:sov:test:120"}],
|
||||
},
|
||||
{
|
||||
"uuid": "972a8469-1641-9f82-8b9d-2434e465e150",
|
||||
"service_name": "Carlos Printing3",
|
||||
"uuid": "bd9c66b3-ad3c-2d6d-1a3d-1fa7bc8960a9",
|
||||
"service_name": "Carlos Printing2",
|
||||
"service_type": "3D Printing",
|
||||
"endpoint_url": "http://127.0.0.1:8003/v1/print_daemon3",
|
||||
"other": {},
|
||||
"entity_did": "did:sov:test:123",
|
||||
"entity_did": "did:sov:test:122",
|
||||
"status": {"data": ["draft", "registered"]},
|
||||
"action": {
|
||||
"data": [
|
||||
@@ -223,6 +214,28 @@ async def ap_list_of_services() -> JSONResponse:
|
||||
},
|
||||
"usage": [{"times_consumed": 2, "consumer_entity_did": "did:sov:test:120"}],
|
||||
},
|
||||
{
|
||||
"uuid": "972a8469-1641-9f82-8b9d-2434e465e150",
|
||||
"service_name": "Carlos Printing3",
|
||||
"service_type": "3D Printing",
|
||||
"endpoint_url": "http://127.0.0.1:8004/v1/print_daemon4",
|
||||
"other": {},
|
||||
"entity_did": "did:sov:test:123",
|
||||
"status": {"data": ["draft", "registered"]},
|
||||
"action": {
|
||||
"data": [
|
||||
{
|
||||
"name": "register",
|
||||
"endpoint": "http://127.0.0.1:8004/v1/print_daemon4/register",
|
||||
},
|
||||
{
|
||||
"name": "deregister",
|
||||
"endpoint": "http://127.0.0.1:8004/v1/print_daemon4/deregister",
|
||||
},
|
||||
]
|
||||
},
|
||||
"usage": [{"times_consumed": 2, "consumer_entity_did": "did:sov:test:120"}],
|
||||
},
|
||||
]
|
||||
return JSONResponse(content=res, status_code=200)
|
||||
|
||||
|
||||
@@ -75,6 +75,7 @@ def create_entities(num: int = 5, role: str = "entity") -> list[EntityCreate]:
|
||||
|
||||
|
||||
def create_service(idx: int, entity: Entity) -> ServiceCreate:
|
||||
idx += 1
|
||||
se = ServiceCreate(
|
||||
uuid=uuids[idx],
|
||||
service_name=f"Carlos Printing{idx}",
|
||||
@@ -113,7 +114,7 @@ def test_create_entities(api_client: ApiClient) -> None:
|
||||
def test_create_services(api_client: ApiClient) -> None:
|
||||
sapi = ServicesApi(api_client=api_client)
|
||||
eapi = EntitiesApi(api_client=api_client)
|
||||
for midx, entity in enumerate(eapi.get_all_entities()):
|
||||
for midx, entity in enumerate(eapi.get_entity_by_roles([Role("service_prosumer")])):
|
||||
service_obj = create_service(midx, entity)
|
||||
service = sapi.create_service(service_obj)
|
||||
assert service.uuid == service_obj.uuid
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{ fetchzip }:
|
||||
fetchzip {
|
||||
url = "https://gitea.gchq.icu/api/packages/IoSL/generic/IoSL-service-aware-frontend/0w66bp3ncw1sbp91jl3ihv7n3z67ja1b9dg5rkxblqkmnsag3if5/assets.tar.gz";
|
||||
sha256 = "0w66bp3ncw1sbp91jl3ihv7n3z67ja1b9dg5rkxblqkmnsag3if5";
|
||||
url = "https://gitea.gchq.icu/api/packages/IoSL/generic/IoSL-service-aware-frontend/15svaig548jz1l8qsiqcycmw3hkb4805rb08mwlv2isxxshrj9ij/assets.tar.gz";
|
||||
sha256 = "15svaig548jz1l8qsiqcycmw3hkb4805rb08mwlv2isxxshrj9ij";
|
||||
}
|
||||
|
||||
@@ -6,13 +6,15 @@ import { useGetAllRepositories } from "@/api/repositories/repositories";
|
||||
import SummaryDetails from "@/components/summary_card";
|
||||
import CustomTable from "@/components/table";
|
||||
import {
|
||||
APSummaryDetails,
|
||||
APAttachmentsTableConfig,
|
||||
APServiceRepositoryTableConfig,
|
||||
} from "@/config/access_point";
|
||||
import { useEffect } from "react";
|
||||
import useGetEntityByNameOrDid from "@/components/hooks/useGetEntityByNameOrDid";
|
||||
import { projectConfig } from "@/config/config";
|
||||
|
||||
export default function AccessPoint() {
|
||||
const { entity } = useGetEntityByNameOrDid("AP");
|
||||
const {
|
||||
data: APAttachementData,
|
||||
isLoading: loadingAttachements,
|
||||
@@ -45,7 +47,7 @@ export default function AccessPoint() {
|
||||
useEffect(() => {
|
||||
const interval = setInterval(() => {
|
||||
onRefresh();
|
||||
}, 5000);
|
||||
}, projectConfig.REFRESH_FREQUENCY);
|
||||
|
||||
return () => clearInterval(interval);
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
@@ -54,10 +56,25 @@ export default function AccessPoint() {
|
||||
return (
|
||||
<div className="m-10">
|
||||
<SummaryDetails
|
||||
fake
|
||||
hasRefreshButton
|
||||
onRefresh={onRefresh}
|
||||
entity={{ name: "Access Point", details: APSummaryDetails }}
|
||||
entity={{
|
||||
name: "Access Point",
|
||||
details: [
|
||||
{
|
||||
label: "DID",
|
||||
value: entity?.did,
|
||||
},
|
||||
{
|
||||
label: "IP",
|
||||
value: entity?.ip,
|
||||
},
|
||||
{
|
||||
label: "Network",
|
||||
value: entity?.network,
|
||||
},
|
||||
],
|
||||
}}
|
||||
/>
|
||||
<div>
|
||||
<h4>Attachment View</h4>
|
||||
|
||||
@@ -1,19 +1,14 @@
|
||||
"use client";
|
||||
import { useEffect, useMemo, useRef, useState } from "react";
|
||||
import { useEffect, useMemo, useState } from "react";
|
||||
import { ClientTableConfig, ServiceTableConfig } from "@/config/client_1";
|
||||
import CustomTable from "@/components/table";
|
||||
import {
|
||||
Alert,
|
||||
Button,
|
||||
Card,
|
||||
CardContent,
|
||||
CardHeader,
|
||||
Snackbar,
|
||||
Typography,
|
||||
CircularProgress,
|
||||
IconButton,
|
||||
} from "@mui/material";
|
||||
import CopyToClipboard from "@/components/copy_to_clipboard";
|
||||
import {
|
||||
attachEntity,
|
||||
detachEntity,
|
||||
@@ -27,6 +22,9 @@ import { useGetAllServices } from "@/api/services/services";
|
||||
import axios from "axios";
|
||||
import CloseIcon from "@mui/icons-material/Close";
|
||||
import { useSearchParams } from "next/navigation";
|
||||
import SummaryDetails from "@/components/summary_card";
|
||||
import { projectConfig } from "@/config/config";
|
||||
import ConsumeDisplayComponent from "@/components/consume_content";
|
||||
|
||||
interface SnackMessage {
|
||||
message: string;
|
||||
@@ -108,8 +106,12 @@ const AttachButton = ({
|
||||
|
||||
export default function Client() {
|
||||
const searchParams = useSearchParams();
|
||||
console.log("params: ", searchParams);
|
||||
const name = searchParams.get("name") ?? "";
|
||||
const [consumeContent, setConsumeContent] = useState(null);
|
||||
const [snackbarOpen, setSnackbarOpen] = useState(false);
|
||||
const [snackbarMessage, setSnackbarMessage] = useState<
|
||||
SnackMessage | undefined
|
||||
>(undefined);
|
||||
|
||||
const { entity: entity } = useGetEntityByNameOrDid(name);
|
||||
const {
|
||||
@@ -136,24 +138,21 @@ export default function Client() {
|
||||
useEffect(() => {
|
||||
const interval = setInterval(() => {
|
||||
onRefresh();
|
||||
}, 5000);
|
||||
}, projectConfig.REFRESH_FREQUENCY);
|
||||
|
||||
return () => clearInterval(interval);
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
|
||||
const cardContentRef = useRef<HTMLDivElement>(null);
|
||||
const [snackbarOpen, setSnackbarOpen] = useState(false);
|
||||
const [snackbarMessage, setSnackbarMessage] = useState<
|
||||
SnackMessage | undefined
|
||||
>(undefined);
|
||||
|
||||
const closeSnackBar = () => {
|
||||
setSnackbarMessage(undefined);
|
||||
setSnackbarOpen(false);
|
||||
};
|
||||
|
||||
console.log("entity", entity);
|
||||
// Consume
|
||||
const handleConsumeContent = (content: any) => {
|
||||
setConsumeContent(content);
|
||||
};
|
||||
|
||||
if (services_loading) return <Skeleton height={500} />;
|
||||
if (!services) return <Alert severity="error">Client not found</Alert>;
|
||||
@@ -181,34 +180,43 @@ export default function Client() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Card variant="outlined">
|
||||
<CardHeader
|
||||
subheader="Summary"
|
||||
action={<CopyToClipboard contentRef={cardContentRef} />}
|
||||
/>
|
||||
<CardContent ref={cardContentRef}>
|
||||
<Typography color="text.primary" gutterBottom>
|
||||
DID: <code>{entity?.did}</code>
|
||||
</Typography>
|
||||
<Typography color="text.primary" gutterBottom>
|
||||
IP: <code>{entity?.ip}</code>
|
||||
</Typography>
|
||||
<Typography color="text.primary" gutterBottom>
|
||||
Network: <code>{entity?.network}</code>
|
||||
</Typography>
|
||||
</CardContent>
|
||||
</Card>
|
||||
<div>
|
||||
<h4>Client View</h4>
|
||||
<CustomTable
|
||||
loading={services_loading}
|
||||
data={clients}
|
||||
configuration={ClientTableConfig}
|
||||
tkey="client-table"
|
||||
/>
|
||||
<SummaryDetails
|
||||
entity={{
|
||||
name: "",
|
||||
details: [
|
||||
{ label: "DID", value: entity?.did },
|
||||
{ label: "IP", value: entity?.ip },
|
||||
{ label: "Network", value: entity?.network },
|
||||
],
|
||||
}}
|
||||
/>
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
flexWrap: "nowrap",
|
||||
alignItems: "center",
|
||||
}}
|
||||
>
|
||||
<div style={{ width: consumeContent ? "55%" : "100%" }}>
|
||||
<h4>Service Consumer View</h4>
|
||||
<CustomTable
|
||||
loading={services_loading}
|
||||
data={clients}
|
||||
onConsumeAction={handleConsumeContent}
|
||||
configuration={ClientTableConfig}
|
||||
tkey="client-table"
|
||||
/>
|
||||
</div>
|
||||
{consumeContent && (
|
||||
<div style={{ width: "40%" }}>
|
||||
<h4>Service Output</h4>
|
||||
<ConsumeDisplayComponent htmlContent={consumeContent} />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div>
|
||||
<h4>Service View</h4>
|
||||
<h4>Service Producer View</h4>
|
||||
<CustomTable
|
||||
loading={services_loading}
|
||||
data={services?.data}
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
"use client";
|
||||
|
||||
import { DLGResolutionTableConfig, DLGSummaryDetails } from "@/config/dlg";
|
||||
import { DLGResolutionTableConfig } from "@/config/dlg";
|
||||
import CustomTable from "@/components/table";
|
||||
import SummaryDetails from "@/components/summary_card";
|
||||
import { useEffect } from "react";
|
||||
import { useGetAllResolutions } from "@/api/resolution/resolution";
|
||||
import { mutate } from "swr";
|
||||
import useGetEntityByNameOrDid from "@/components/hooks/useGetEntityByNameOrDid";
|
||||
import { projectConfig } from "@/config/config";
|
||||
|
||||
export default function DLG() {
|
||||
const { entity } = useGetEntityByNameOrDid("DLG");
|
||||
const {
|
||||
data: resolutionData,
|
||||
isLoading: loadingResolutions,
|
||||
@@ -28,7 +31,7 @@ export default function DLG() {
|
||||
useEffect(() => {
|
||||
const interval = setInterval(() => {
|
||||
onRefresh();
|
||||
}, 5000);
|
||||
}, projectConfig.REFRESH_FREQUENCY);
|
||||
|
||||
return () => clearInterval(interval);
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
@@ -37,12 +40,24 @@ export default function DLG() {
|
||||
return (
|
||||
<div className="m-10">
|
||||
<SummaryDetails
|
||||
fake
|
||||
hasRefreshButton
|
||||
onRefresh={onRefresh}
|
||||
entity={{
|
||||
name: "Distributed Ledger Gateway",
|
||||
details: DLGSummaryDetails,
|
||||
details: [
|
||||
{
|
||||
label: "DID",
|
||||
value: entity?.did,
|
||||
},
|
||||
{
|
||||
label: "IP",
|
||||
value: entity?.ip,
|
||||
},
|
||||
{
|
||||
label: "Network",
|
||||
value: entity?.network,
|
||||
},
|
||||
],
|
||||
}}
|
||||
/>
|
||||
<div>
|
||||
|
||||
@@ -8,6 +8,7 @@ import dynamic from "next/dynamic";
|
||||
import { useEffect } from "react";
|
||||
import { mutate } from "swr";
|
||||
import ErrorBoundary from "@/components/error_boundary";
|
||||
import { projectConfig } from "@/config/config";
|
||||
|
||||
const NoSSRSequenceDiagram = dynamic(
|
||||
() => import("../../components/sequence_diagram"),
|
||||
@@ -30,7 +31,7 @@ export default function Home() {
|
||||
useEffect(() => {
|
||||
const interval = setInterval(() => {
|
||||
onRefresh();
|
||||
}, 5000);
|
||||
}, projectConfig.REFRESH_FREQUENCY);
|
||||
|
||||
return () => clearInterval(interval);
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
|
||||
73
pkgs/ui/src/components/consume_action/index.tsx
Normal file
73
pkgs/ui/src/components/consume_action/index.tsx
Normal file
@@ -0,0 +1,73 @@
|
||||
import { Button, CircularProgress, Snackbar } from "@mui/material";
|
||||
import { useState } from "react";
|
||||
import axios from "axios";
|
||||
|
||||
const ConsumeAction = ({
|
||||
endpoint,
|
||||
onConsume,
|
||||
}: {
|
||||
endpoint: string;
|
||||
rowData?: any;
|
||||
onConsume?: any;
|
||||
}) => {
|
||||
const [error, setError] = useState(null);
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
if (error) console.error("Error in state", error);
|
||||
|
||||
const handleConsume = () => {
|
||||
if (loading) return;
|
||||
|
||||
setLoading(true);
|
||||
|
||||
const axiosConfig = {
|
||||
url: endpoint,
|
||||
method: "GET",
|
||||
data: null,
|
||||
withCredentials: true,
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
Accept: "application/json",
|
||||
},
|
||||
};
|
||||
|
||||
axios(axiosConfig)
|
||||
.then((response) => {
|
||||
if (onConsume) {
|
||||
onConsume(response.data);
|
||||
console.log("I got the data from consume: ", response.data);
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
if (onConsume) onConsume(null);
|
||||
console.error("Error happened during consume: ", error);
|
||||
setError(error);
|
||||
})
|
||||
.finally(() => {
|
||||
setLoading(false);
|
||||
});
|
||||
};
|
||||
|
||||
const handleCloseSnackbar = () => {
|
||||
setError(null);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Button disabled={loading} onClick={handleConsume} variant="contained">
|
||||
{loading ? <CircularProgress size={24} /> : `Consume`}
|
||||
</Button>
|
||||
{error && (
|
||||
<Snackbar
|
||||
anchorOrigin={{ vertical: "top", horizontal: "center" }}
|
||||
open={error}
|
||||
autoHideDuration={2000}
|
||||
message={`Something happened during consume: ${error}`}
|
||||
onClose={handleCloseSnackbar}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default ConsumeAction;
|
||||
9
pkgs/ui/src/components/consume_content/index.tsx
Normal file
9
pkgs/ui/src/components/consume_content/index.tsx
Normal file
@@ -0,0 +1,9 @@
|
||||
const ConsumeDisplayComponent = ({ htmlContent }: { htmlContent: any }) => {
|
||||
return (
|
||||
<div>
|
||||
<div dangerouslySetInnerHTML={{ __html: htmlContent }} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ConsumeDisplayComponent;
|
||||
231
pkgs/ui/src/components/entity_actions/index.tsx
Normal file
231
pkgs/ui/src/components/entity_actions/index.tsx
Normal file
@@ -0,0 +1,231 @@
|
||||
import { IEntityActions } from "@/types";
|
||||
import {
|
||||
Button,
|
||||
Snackbar,
|
||||
Alert,
|
||||
AlertColor,
|
||||
CircularProgress,
|
||||
Dialog,
|
||||
DialogTitle,
|
||||
DialogContent,
|
||||
DialogContentText,
|
||||
DialogActions,
|
||||
} from "@mui/material";
|
||||
import { useState } from "react";
|
||||
import { deleteEntity } from "@/api/entities/entities";
|
||||
import axios from "axios";
|
||||
|
||||
interface Props {
|
||||
endpointData: IEntityActions[];
|
||||
rowData?: any;
|
||||
}
|
||||
|
||||
const SNACKBAR_DEFAULT = {
|
||||
open: false,
|
||||
message: "",
|
||||
severity: "info" as AlertColor,
|
||||
};
|
||||
|
||||
const EntityActions = ({ endpointData, rowData }: Props) => {
|
||||
const [snackbar, setSnackbar] = useState<{
|
||||
open: boolean;
|
||||
message: string;
|
||||
severity: AlertColor;
|
||||
}>(SNACKBAR_DEFAULT);
|
||||
|
||||
const [registerData, setRegisterData] = useState(null);
|
||||
const [registerError, setRegisterError] = useState(null);
|
||||
const [loadingRegister, setLoadingRegister] = useState(false);
|
||||
|
||||
const [DeregisterData, setDeRegisterData] = useState(null);
|
||||
const [DeregisterError, setDeRegisterError] = useState(null);
|
||||
const [loadingDeRegister, setLoadingDeRegister] = useState(false);
|
||||
|
||||
const [loadingDelete, setLoadingDelete] = useState(false);
|
||||
const [confirmDelete, setConfirmDelete] = useState(false);
|
||||
|
||||
if (registerData) console.log("Register Data in state", registerData);
|
||||
if (registerError) console.error("Register Error in state", registerError);
|
||||
|
||||
if (DeregisterData) console.log("Register Data in state", DeregisterData);
|
||||
if (DeregisterError)
|
||||
console.error("Register Error in state", DeregisterError);
|
||||
|
||||
const onDeleteEntity = async () => {
|
||||
setLoadingDelete(true);
|
||||
if (rowData)
|
||||
try {
|
||||
const response = await deleteEntity({
|
||||
entity_did: rowData?.entity_did,
|
||||
});
|
||||
setSnackbar({
|
||||
open: true,
|
||||
message: response.data.message,
|
||||
severity: "success",
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("Error deleting entity: ", error);
|
||||
setSnackbar({
|
||||
open: true,
|
||||
message: "Failed to delete entity.",
|
||||
severity: "error",
|
||||
});
|
||||
} finally {
|
||||
setLoadingDelete(false);
|
||||
closeDeleteConfirmation();
|
||||
}
|
||||
};
|
||||
|
||||
const onRegisterEntity = (endpoint: string) => {
|
||||
if (loadingRegister) return;
|
||||
|
||||
setLoadingRegister(true);
|
||||
|
||||
const axiosConfig = {
|
||||
url: endpoint,
|
||||
method: "GET",
|
||||
data: null,
|
||||
withCredentials: true,
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
Accept: "application/json",
|
||||
},
|
||||
};
|
||||
|
||||
axios(axiosConfig)
|
||||
.then((response) => {
|
||||
setRegisterData(response.data);
|
||||
console.log("I got the data from register: ", response.data);
|
||||
setSnackbar({
|
||||
open: true,
|
||||
message: "Registered successfully!",
|
||||
severity: "success",
|
||||
});
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Error happened during register: ", error);
|
||||
setRegisterError(error);
|
||||
setSnackbar({
|
||||
open: true,
|
||||
message: error,
|
||||
severity: "error",
|
||||
});
|
||||
})
|
||||
.finally(() => {
|
||||
setLoadingRegister(false);
|
||||
});
|
||||
};
|
||||
|
||||
const onDeregisterEntity = (endpoint: string) => {
|
||||
if (loadingDeRegister) return;
|
||||
|
||||
setLoadingDeRegister(true);
|
||||
|
||||
const axiosConfig = {
|
||||
url: endpoint,
|
||||
method: "GET",
|
||||
data: null,
|
||||
};
|
||||
|
||||
axios(axiosConfig)
|
||||
.then((response) => {
|
||||
setDeRegisterData(response.data);
|
||||
console.log("I got the data from deregister: ", response.data);
|
||||
setSnackbar({
|
||||
open: true,
|
||||
message: "De-Registered successfully!",
|
||||
severity: "success",
|
||||
});
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Error happened during deregister: ", error);
|
||||
setDeRegisterError(error);
|
||||
setSnackbar({
|
||||
open: true,
|
||||
message: error,
|
||||
severity: "error",
|
||||
});
|
||||
})
|
||||
.finally(() => {
|
||||
setLoadingDeRegister(false);
|
||||
});
|
||||
};
|
||||
|
||||
const handleCloseSnackbar = () => {
|
||||
setSnackbar(SNACKBAR_DEFAULT);
|
||||
};
|
||||
|
||||
const openDeleteConfirmation = () => {
|
||||
setConfirmDelete(true);
|
||||
};
|
||||
|
||||
const closeDeleteConfirmation = () => {
|
||||
setConfirmDelete(false);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="flex justify-between">
|
||||
{endpointData.map(
|
||||
({ name, endpoint }: IEntityActions, index: number) => {
|
||||
const isRegister = name && name.toLocaleLowerCase() === "register";
|
||||
// const isDeRegister = name && name.toLocaleLowerCase() === "deregister";
|
||||
return (
|
||||
<Button
|
||||
disabled={loadingRegister || loadingDeRegister}
|
||||
key={index}
|
||||
onClick={() =>
|
||||
isRegister
|
||||
? onRegisterEntity(endpoint)
|
||||
: onDeregisterEntity(endpoint)
|
||||
}
|
||||
variant="contained"
|
||||
size="small"
|
||||
>
|
||||
{name}
|
||||
</Button>
|
||||
);
|
||||
},
|
||||
)}
|
||||
<Button
|
||||
disabled={loadingDelete}
|
||||
onClick={openDeleteConfirmation}
|
||||
size="small"
|
||||
variant="contained"
|
||||
>
|
||||
Delete
|
||||
</Button>
|
||||
</div>
|
||||
<Dialog open={confirmDelete} onClose={closeDeleteConfirmation}>
|
||||
<DialogTitle>Delete Entity Confirmation</DialogTitle>
|
||||
<DialogContent>
|
||||
<DialogContentText>
|
||||
Are you sure you want to delete this entity?
|
||||
</DialogContentText>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button onClick={closeDeleteConfirmation}>Cancel</Button>
|
||||
<Button variant="contained" onClick={onDeleteEntity}>
|
||||
{loadingDelete ? <CircularProgress size={24} /> : `Confirm`}
|
||||
</Button>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
<Snackbar
|
||||
anchorOrigin={{ vertical: "top", horizontal: "center" }}
|
||||
open={snackbar.open}
|
||||
autoHideDuration={5000}
|
||||
onClose={handleCloseSnackbar}
|
||||
>
|
||||
<Alert
|
||||
onClose={handleCloseSnackbar}
|
||||
severity={snackbar?.severity}
|
||||
sx={{ width: "100%" }}
|
||||
>
|
||||
{snackbar.message}
|
||||
</Alert>
|
||||
</Snackbar>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default EntityActions;
|
||||
49
pkgs/ui/src/components/hooks/useAxios.tsx
Normal file
49
pkgs/ui/src/components/hooks/useAxios.tsx
Normal file
@@ -0,0 +1,49 @@
|
||||
import { useState, useEffect } from "react";
|
||||
import axios from "axios";
|
||||
import { projectConfig } from "@/config/config";
|
||||
|
||||
const useAxios = (
|
||||
url: string,
|
||||
method = "GET",
|
||||
payload = null,
|
||||
isFullUrl = false,
|
||||
shouldFetch = false,
|
||||
) => {
|
||||
const [data, setData] = useState(null);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [error, setError] = useState(null);
|
||||
|
||||
const fetch = () => {
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
const finalUrl = isFullUrl ? url : projectConfig.BASE_URL + url;
|
||||
|
||||
const axiosConfig = {
|
||||
url: finalUrl,
|
||||
method,
|
||||
data: payload,
|
||||
};
|
||||
|
||||
axios(axiosConfig)
|
||||
.then((response) => {
|
||||
setData(response.data);
|
||||
})
|
||||
.catch((error) => {
|
||||
setError(error);
|
||||
})
|
||||
.finally(() => {
|
||||
setLoading(false);
|
||||
});
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (shouldFetch) {
|
||||
fetch();
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [url, method, JSON.stringify(payload), shouldFetch]);
|
||||
|
||||
return { data, loading, error, refetch: fetch };
|
||||
};
|
||||
|
||||
export default useAxios;
|
||||
@@ -1,33 +0,0 @@
|
||||
import { useState, useEffect } from "react";
|
||||
import axios from "axios";
|
||||
import { projectConfig } from "@/config/config";
|
||||
|
||||
const useFetch = (url: string) => {
|
||||
const [data, setData] = useState([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [error, setError] = useState(null);
|
||||
|
||||
const fetch = () => {
|
||||
setLoading(true);
|
||||
axios
|
||||
.get(projectConfig.BASE_URL + url)
|
||||
.then((response) => {
|
||||
setData(response.data);
|
||||
})
|
||||
.catch((error) => {
|
||||
setError(error);
|
||||
})
|
||||
.finally(() => {
|
||||
setLoading(false);
|
||||
});
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
fetch();
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [url]);
|
||||
|
||||
return { data, loading, error, fetch };
|
||||
};
|
||||
|
||||
export default useFetch;
|
||||
@@ -1,7 +1,7 @@
|
||||
import { getGroupColor, sanitizeDID } from "@/utils/helpers";
|
||||
|
||||
export const generateMermaidString = (data: any) => {
|
||||
if (!data) return "";
|
||||
if (!data || !data.length) return "";
|
||||
|
||||
let mermaidString = "sequenceDiagram\n";
|
||||
const participantDetails = new Map();
|
||||
|
||||
@@ -15,6 +15,7 @@ import {
|
||||
IconButton,
|
||||
List,
|
||||
TextField,
|
||||
useMediaQuery,
|
||||
} from "@mui/material";
|
||||
//Icons
|
||||
import RefreshIcon from "@mui/icons-material/Refresh";
|
||||
@@ -43,32 +44,52 @@ const SequenceDiagram = () => {
|
||||
swrKey: eventMessagesKeyFunc,
|
||||
} = useGetAllEventmessages();
|
||||
|
||||
const mermaidRef: any = useRef(null);
|
||||
const [scale, setScale] = useState(1);
|
||||
const [openFilters, setOpenFilters] = useState(false);
|
||||
|
||||
const [sequenceNr, setSequenceNr] = useState("");
|
||||
const hasData = eventMessagesData?.data;
|
||||
|
||||
const mermaidRef: any = useRef(null);
|
||||
|
||||
const hasData = eventMessagesData?.data && eventMessagesData?.data.length > 0;
|
||||
const mermaidString = generateMermaidString(eventMessagesData?.data);
|
||||
const allEventMessages = extractAllEventMessages(eventMessagesData?.data);
|
||||
const dataDependency = JSON.stringify(hasData ? eventMessagesData?.data : "");
|
||||
|
||||
const userPrefersDarkmode = useMediaQuery("(prefers-color-scheme: dark)");
|
||||
|
||||
const iconButtonColor = userPrefersDarkmode ? "default" : "primary";
|
||||
|
||||
useEffect(() => {
|
||||
if (!loadingEventMessages && hasData)
|
||||
mermaid.initialize({
|
||||
startOnLoad: false,
|
||||
securityLevel: "loose",
|
||||
sequence: {
|
||||
mirrorActors: true,
|
||||
showSequenceNumbers: true,
|
||||
},
|
||||
});
|
||||
const currentMermaidRef = mermaidRef?.current;
|
||||
|
||||
if (mermaidRef.current) {
|
||||
mermaidRef.current.innerHTML = mermaidString;
|
||||
mermaid.init(undefined, mermaidRef.current);
|
||||
if (!loadingEventMessages && hasData) {
|
||||
if (
|
||||
currentMermaidRef &&
|
||||
!currentMermaidRef.getAttribute("data-processed")
|
||||
) {
|
||||
mermaid.initialize({
|
||||
startOnLoad: false,
|
||||
securityLevel: "loose",
|
||||
sequence: {
|
||||
mirrorActors: true,
|
||||
showSequenceNumbers: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
if (currentMermaidRef) {
|
||||
currentMermaidRef.innerHTML = mermaidString;
|
||||
mermaid.init(undefined, currentMermaidRef);
|
||||
}
|
||||
}
|
||||
}, [loadingEventMessages, hasData, mermaidString]);
|
||||
return () => {
|
||||
if (currentMermaidRef) {
|
||||
currentMermaidRef.removeAttribute("data-processed");
|
||||
currentMermaidRef.innerHTML = "";
|
||||
}
|
||||
};
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [dataDependency]);
|
||||
|
||||
useEffect(() => {
|
||||
if (mermaidRef.current) {
|
||||
@@ -176,37 +197,37 @@ const SequenceDiagram = () => {
|
||||
<>
|
||||
<div className="flex justify-end">
|
||||
<Tooltip placement="top" title="Filter Messages">
|
||||
<IconButton color="primary" onClick={toggleFilters}>
|
||||
<IconButton color={iconButtonColor} onClick={toggleFilters}>
|
||||
<FilterAltIcon />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
<Tooltip placement="top" title="Refresh Diagram">
|
||||
<IconButton color="primary" onClick={onRefresh}>
|
||||
<IconButton color={iconButtonColor} onClick={onRefresh}>
|
||||
<RefreshIcon />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
<Tooltip title="Zoom In" placement="top">
|
||||
<IconButton color="primary" onClick={zoomIn}>
|
||||
<IconButton color={iconButtonColor} onClick={zoomIn}>
|
||||
<ZoomInIcon />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
<Tooltip title="Zoom Out" placement="top">
|
||||
<IconButton color="primary" onClick={zoomOut}>
|
||||
<IconButton color={iconButtonColor} onClick={zoomOut}>
|
||||
<ZoomOutIcon />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
<Tooltip title="Reset" placement="top">
|
||||
<IconButton color="primary" onClick={resetZoom}>
|
||||
<IconButton color={iconButtonColor} onClick={resetZoom}>
|
||||
<ResetIcon />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
<Tooltip title="View in Fullscreen" placement="top">
|
||||
<IconButton color="primary" onClick={viewInFullScreen}>
|
||||
<IconButton color={iconButtonColor} onClick={viewInFullScreen}>
|
||||
<FullscreenIcon />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
<Tooltip title="Download as PNG" placement="top">
|
||||
<IconButton color="primary" onClick={downloadAsPng}>
|
||||
<IconButton color={iconButtonColor} onClick={downloadAsPng}>
|
||||
<DownloadIcon />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
|
||||
@@ -93,7 +93,7 @@ export function Sidebar(props: SidebarProps) {
|
||||
const menuEntityEntries: MenuEntry[] = React.useMemo(() => {
|
||||
if (entityData) {
|
||||
return Array.isArray(entityData.data)
|
||||
? entityData.data.map((entity) => ({
|
||||
? entityData.data.map((entity: any) => ({
|
||||
icon: <PersonIcon />,
|
||||
label: entity.name,
|
||||
to: entity.name,
|
||||
|
||||
@@ -12,7 +12,13 @@ import { ICustomTable, CustomTableConfiguration } from "@/types";
|
||||
import { Checkbox, Skeleton } from "@mui/material";
|
||||
import ErrorBoundary from "@/components/error_boundary";
|
||||
|
||||
const CustomTable = ({ configuration, data, loading, tkey }: ICustomTable) => {
|
||||
const CustomTable = ({
|
||||
configuration,
|
||||
data,
|
||||
loading,
|
||||
tkey,
|
||||
onConsumeAction,
|
||||
}: ICustomTable) => {
|
||||
if (loading)
|
||||
return <Skeleton variant="rectangular" animation="wave" height={200} />;
|
||||
|
||||
@@ -23,7 +29,12 @@ const CustomTable = ({ configuration, data, loading, tkey }: ICustomTable) => {
|
||||
const renderTableCell = (
|
||||
value: any,
|
||||
cellKey: string,
|
||||
render?: (param: any) => void | undefined,
|
||||
render?: (
|
||||
param: any,
|
||||
data?: any,
|
||||
onFunc?: (param: any) => void,
|
||||
) => void | undefined,
|
||||
rowData?: any,
|
||||
) => {
|
||||
let renderedValue = value;
|
||||
|
||||
@@ -35,7 +46,7 @@ const CustomTable = ({ configuration, data, loading, tkey }: ICustomTable) => {
|
||||
renderedValue = <Checkbox disabled checked={value} />;
|
||||
|
||||
// cover use case if we want to render a component
|
||||
if (render) renderedValue = render(value);
|
||||
if (render) renderedValue = render(value, rowData, onConsumeAction);
|
||||
|
||||
// catch use case where the value is an object but the render function is not provided in the table config
|
||||
if (
|
||||
@@ -66,17 +77,18 @@ const CustomTable = ({ configuration, data, loading, tkey }: ICustomTable) => {
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
{data.map((data: any, rowIndex: number) => (
|
||||
{data.map((rowData: any, rowIndex: number) => (
|
||||
<StyledTableRow key={rowIndex}>
|
||||
{configuration.map(
|
||||
(column: CustomTableConfiguration, columnIndex: number) => {
|
||||
const cellValue: any = data[column.key];
|
||||
const cellValue: any = rowData[column.key];
|
||||
const cellKey = tkey + ":" + column.key + ":" + rowIndex;
|
||||
const renderComponent = column?.render;
|
||||
return renderTableCell(
|
||||
cellValue,
|
||||
cellKey + ":" + columnIndex,
|
||||
renderComponent,
|
||||
rowData,
|
||||
);
|
||||
},
|
||||
)}
|
||||
|
||||
@@ -1,20 +1,3 @@
|
||||
// AP - Summary
|
||||
|
||||
export const APSummaryDetails = [
|
||||
{
|
||||
label: "DID",
|
||||
value: "did:sov:test:1274",
|
||||
},
|
||||
{
|
||||
label: "IP",
|
||||
value: "127.0.0.2",
|
||||
},
|
||||
{
|
||||
label: "Network",
|
||||
value: "Carlo's Home Network",
|
||||
},
|
||||
];
|
||||
|
||||
// AP - 2 Tables Configurations to display labels
|
||||
|
||||
export const APAttachmentsTableConfig = [
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import { Button, IconButton, Tooltip } from "@mui/material";
|
||||
import AddCircleIcon from "@mui/icons-material/AddCircle";
|
||||
import RemoveCircleIcon from "@mui/icons-material/RemoveCircle";
|
||||
import DeleteIcon from "@mui/icons-material/Delete";
|
||||
import EntityActions from "@/components/entity_actions";
|
||||
import ConsumeAction from "@/components/consume_action";
|
||||
|
||||
export const ClientTableConfig = [
|
||||
{
|
||||
@@ -15,11 +13,13 @@ export const ClientTableConfig = [
|
||||
{
|
||||
key: "endpoint_url",
|
||||
label: "End Point",
|
||||
render: () => {
|
||||
render: (value: any, rowData: any, onConsume: any) => {
|
||||
return (
|
||||
<Button disabled variant="outlined">
|
||||
Consume
|
||||
</Button>
|
||||
<ConsumeAction
|
||||
rowData={rowData}
|
||||
onConsume={onConsume}
|
||||
endpoint={value}
|
||||
/>
|
||||
);
|
||||
},
|
||||
},
|
||||
@@ -88,39 +88,10 @@ export const ServiceTableConfig = [
|
||||
{
|
||||
key: "action",
|
||||
label: "Actions",
|
||||
render: () => {
|
||||
return (
|
||||
<>
|
||||
<Tooltip title="Register" placement="top">
|
||||
<IconButton disabled size="small">
|
||||
<AddCircleIcon />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
|
||||
<Tooltip title="De-register" placement="top">
|
||||
<IconButton disabled size="small">
|
||||
<RemoveCircleIcon />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
<Tooltip title="Delete" placement="top">
|
||||
<IconButton disabled size="small" color="secondary">
|
||||
<DeleteIcon />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
</>
|
||||
);
|
||||
// let renderedValue: any = "";
|
||||
// if (typeof value === "object")
|
||||
// renderedValue = (
|
||||
// <>
|
||||
// {[...value.data, { name: 'Delete', endpoint: '' }].map((actionType: any) => (
|
||||
// <>
|
||||
// <Button disabled style={{ marginRight: 8 }} variant="outlined" size="small">{actionType.name}</Button>
|
||||
// </>
|
||||
// ))}
|
||||
// </>
|
||||
// );
|
||||
// return renderedValue;
|
||||
render: (value: any, rowData?: any) => {
|
||||
if (value && value?.data.length > 0)
|
||||
return <EntityActions rowData={rowData} endpointData={value.data} />;
|
||||
else return "N/A";
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
@@ -9,6 +9,7 @@ import BuildIcon from "@mui/icons-material/Build";
|
||||
|
||||
export const projectConfig: any = {
|
||||
BASE_URL: "http://localhost:2979/api/v1",
|
||||
REFRESH_FREQUENCY: 5000,
|
||||
GROUPS: [
|
||||
{
|
||||
groupName: "Attachement",
|
||||
|
||||
@@ -1,18 +1,5 @@
|
||||
// DLG Summary Details
|
||||
|
||||
import { formatDateTime } from "@/utils/helpers";
|
||||
|
||||
export const DLGSummaryDetails = [
|
||||
{
|
||||
label: "DID",
|
||||
value: "did:sov:test:1274",
|
||||
},
|
||||
{
|
||||
label: "URL",
|
||||
value: "dlg.tu-berlin.de",
|
||||
},
|
||||
];
|
||||
|
||||
// DLG - 2 Tables Configurations to display labels
|
||||
|
||||
export const DLGResolutionDummyData = [
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
export interface CustomTableConfiguration {
|
||||
key: string;
|
||||
label: string;
|
||||
render?: (param: any) => void;
|
||||
render?: (param: any, rowData?: any, onConsume?: any) => void;
|
||||
}
|
||||
|
||||
export interface ICustomTable {
|
||||
@@ -9,21 +9,27 @@ export interface ICustomTable {
|
||||
data: any;
|
||||
loading?: boolean;
|
||||
tkey: string;
|
||||
onConsumeAction?: (param: any) => void;
|
||||
}
|
||||
|
||||
export interface EntityDetails {
|
||||
label: string;
|
||||
value: string;
|
||||
value: string | undefined;
|
||||
}
|
||||
|
||||
export interface Entity {
|
||||
name: string;
|
||||
name?: string;
|
||||
details: EntityDetails[];
|
||||
}
|
||||
|
||||
export interface ISummaryDetails {
|
||||
entity: any;
|
||||
entity: Entity;
|
||||
fake?: boolean;
|
||||
hasRefreshButton?: boolean;
|
||||
onRefresh?: () => void;
|
||||
}
|
||||
|
||||
export interface IEntityActions {
|
||||
name: string;
|
||||
endpoint: string;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user