diff --git a/pkgs/ui/src/app/home/page.tsx b/pkgs/ui/src/app/home/page.tsx
index 7b31e65..bd22485 100644
--- a/pkgs/ui/src/app/home/page.tsx
+++ b/pkgs/ui/src/app/home/page.tsx
@@ -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
diff --git a/pkgs/ui/src/components/entity_actions/index.tsx b/pkgs/ui/src/components/entity_actions/index.tsx
new file mode 100644
index 0000000..7a3ba8d
--- /dev/null
+++ b/pkgs/ui/src/components/entity_actions/index.tsx
@@ -0,0 +1,111 @@
+import { IEntityActions } from "@/types";
+import { Button, Snackbar, Alert, AlertColor } from "@mui/material";
+import { useState } from "react";
+import useAxios from "../hooks/useAxios";
+import { deleteEntity } from "@/api/entities/entities";
+
+interface Props {
+ endpointData: IEntityActions[];
+ rowData?: any;
+}
+
+const SNACKBAR_DEFAULT = {
+ open: false,
+ message: "",
+ severity: "info" as AlertColor,
+};
+
+const EntityActions = ({ endpointData, rowData }: Props) => {
+ const [currentEndpoint, setCurrentEndpoint] = useState("");
+ const [shouldFetch, setShouldFetch] = useState(false);
+ const { error } = useAxios(currentEndpoint, "GET", null, true, shouldFetch);
+
+ const [snackbar, setSnackbar] = useState<{
+ open: boolean;
+ message: string;
+ severity: AlertColor;
+ }>(SNACKBAR_DEFAULT);
+
+ console.error("Error registering/deregistering:", error);
+
+ const onDeleteEntity = async () => {
+ if (rowData)
+ try {
+ const response = await deleteEntity({
+ entity_did: rowData?.entity_did,
+ });
+ console.log("On Delete:", response.data.message);
+ 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",
+ });
+ }
+ };
+
+ const onRegisterEntity = (endpoint: string) => {
+ setCurrentEndpoint(endpoint);
+ setShouldFetch(true);
+ };
+
+ const onDeregisterEntity = (endpoint: string) => {
+ setCurrentEndpoint(endpoint);
+ setShouldFetch(true);
+ };
+
+ const handleCloseSnackbar = () => {
+ setSnackbar(SNACKBAR_DEFAULT);
+ };
+
+ return (
+ <>
+
+ {endpointData.map(
+ ({ name, endpoint }: IEntityActions, index: number) => {
+ const isRegister = name && name.toLocaleLowerCase() === "register";
+ return (
+
+ );
+ },
+ )}
+
+
+
+
+ {snackbar.message}
+
+
+ >
+ );
+};
+
+export default EntityActions;
diff --git a/pkgs/ui/src/components/hooks/useAxios.tsx b/pkgs/ui/src/components/hooks/useAxios.tsx
new file mode 100644
index 0000000..48a0493
--- /dev/null
+++ b/pkgs/ui/src/components/hooks/useAxios.tsx
@@ -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;
diff --git a/pkgs/ui/src/components/hooks/useFetch.tsx b/pkgs/ui/src/components/hooks/useFetch.tsx
deleted file mode 100644
index 8eae13c..0000000
--- a/pkgs/ui/src/components/hooks/useFetch.tsx
+++ /dev/null
@@ -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;
diff --git a/pkgs/ui/src/components/sequence_diagram/helpers.ts b/pkgs/ui/src/components/sequence_diagram/helpers.ts
index 8e1b4a3..2c83cce 100644
--- a/pkgs/ui/src/components/sequence_diagram/helpers.ts
+++ b/pkgs/ui/src/components/sequence_diagram/helpers.ts
@@ -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();
diff --git a/pkgs/ui/src/components/sequence_diagram/index.tsx b/pkgs/ui/src/components/sequence_diagram/index.tsx
index 6d9e7b8..4c5754b 100644
--- a/pkgs/ui/src/components/sequence_diagram/index.tsx
+++ b/pkgs/ui/src/components/sequence_diagram/index.tsx
@@ -43,32 +43,48 @@ 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 : "");
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) {
diff --git a/pkgs/ui/src/components/sidebar/index.tsx b/pkgs/ui/src/components/sidebar/index.tsx
index 69ac216..79de3da 100644
--- a/pkgs/ui/src/components/sidebar/index.tsx
+++ b/pkgs/ui/src/components/sidebar/index.tsx
@@ -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:
,
label: entity.name,
to: entity.name,
diff --git a/pkgs/ui/src/components/table/index.tsx b/pkgs/ui/src/components/table/index.tsx
index 635fbe4..d4d35bf 100644
--- a/pkgs/ui/src/components/table/index.tsx
+++ b/pkgs/ui/src/components/table/index.tsx
@@ -23,7 +23,8 @@ const CustomTable = ({ configuration, data, loading, tkey }: ICustomTable) => {
const renderTableCell = (
value: any,
cellKey: string,
- render?: (param: any) => void | undefined,
+ render?: (param: any, data?: any) => void | undefined,
+ rowData?: any,
) => {
let renderedValue = value;
@@ -35,7 +36,7 @@ const CustomTable = ({ configuration, data, loading, tkey }: ICustomTable) => {
renderedValue =
;
// cover use case if we want to render a component
- if (render) renderedValue = render(value);
+ if (render) renderedValue = render(value, rowData);
// catch use case where the value is an object but the render function is not provided in the table config
if (
@@ -66,17 +67,18 @@ const CustomTable = ({ configuration, data, loading, tkey }: ICustomTable) => {
- {data.map((data: any, rowIndex: number) => (
+ {data.map((rowData: any, rowIndex: number) => (
{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,
);
},
)}
diff --git a/pkgs/ui/src/config/access_point/index.tsx b/pkgs/ui/src/config/access_point/index.tsx
index 8fae746..7b3d58b 100644
--- a/pkgs/ui/src/config/access_point/index.tsx
+++ b/pkgs/ui/src/config/access_point/index.tsx
@@ -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 = [
diff --git a/pkgs/ui/src/config/client_1/index.tsx b/pkgs/ui/src/config/client_1/index.tsx
index e1ad33e..d8190f2 100644
--- a/pkgs/ui/src/config/client_1/index.tsx
+++ b/pkgs/ui/src/config/client_1/index.tsx
@@ -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 { Button } from "@mui/material";
+import EntityActions from "@/components/entity_actions";
export const ClientTableConfig = [
{
@@ -88,39 +86,10 @@ export const ServiceTableConfig = [
{
key: "action",
label: "Actions",
- render: () => {
- return (
- <>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- >
- );
- // let renderedValue: any = "";
- // if (typeof value === "object")
- // renderedValue = (
- // <>
- // {[...value.data, { name: 'Delete', endpoint: '' }].map((actionType: any) => (
- // <>
- //
- // >
- // ))}
- // >
- // );
- // return renderedValue;
+ render: (value: any, rowData?: any) => {
+ if (value && value?.data.length > 0)
+ return ;
+ else return "N/A";
},
},
];
diff --git a/pkgs/ui/src/config/config.tsx b/pkgs/ui/src/config/config.tsx
index a42175e..7f4a73a 100644
--- a/pkgs/ui/src/config/config.tsx
+++ b/pkgs/ui/src/config/config.tsx
@@ -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",
diff --git a/pkgs/ui/src/config/dlg/index.ts b/pkgs/ui/src/config/dlg/index.ts
index 1fdafde..6afdd7c 100644
--- a/pkgs/ui/src/config/dlg/index.ts
+++ b/pkgs/ui/src/config/dlg/index.ts
@@ -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 = [
diff --git a/pkgs/ui/src/types/index.ts b/pkgs/ui/src/types/index.ts
index d1be251..28fe7f0 100644
--- a/pkgs/ui/src/types/index.ts
+++ b/pkgs/ui/src/types/index.ts
@@ -13,17 +13,22 @@ export interface ICustomTable {
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;
+}