generated from Luis/nextjs-python-web-template
Merge pull request 'UI: Fixed exception in service view rendering' (#56) from Qubasa-main into main
This commit was merged in pull request #56.
This commit is contained in:
@@ -79,17 +79,23 @@ def create_service(idx: int, entity: Entity) -> ServiceCreate:
|
|||||||
uuid=uuids[idx],
|
uuid=uuids[idx],
|
||||||
service_name=f"Carlos Printing{idx}",
|
service_name=f"Carlos Printing{idx}",
|
||||||
service_type="3D Printing",
|
service_type="3D Printing",
|
||||||
endpoint_url=f"{entity.ip}/v1/print_daemon{idx}",
|
endpoint_url=f"http://{entity.ip}/v1/print_daemon{idx}",
|
||||||
status={"data": ["draft", "registered"]},
|
status={"data": ["draft", "registered"]},
|
||||||
other={},
|
other={},
|
||||||
action={
|
action={
|
||||||
"data": [
|
"data": [
|
||||||
{"name": "register", "path": "/register"},
|
{
|
||||||
{"name": "deregister", "path": "/deregister"},
|
"name": "register",
|
||||||
|
"endpoint": f"http://{entity.ip}/v1/print_daemon{idx}/register",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "deregister",
|
||||||
|
"endpoint": f"http://{entity.ip}/v1/print_daemon{idx}/deregister",
|
||||||
|
},
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
entity_did=entity.did,
|
entity_did=entity.did,
|
||||||
usage=[],
|
usage=[{"times_consumed": 2, "consumer_entity_did": "did:sov:test:120"}],
|
||||||
)
|
)
|
||||||
|
|
||||||
return se
|
return se
|
||||||
|
|||||||
49
pkgs/ui/src/components/error_boundary.tsx
Normal file
49
pkgs/ui/src/components/error_boundary.tsx
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
import React from "react";
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
children: React.ReactNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface State {
|
||||||
|
hasError: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
class ErrorBoundary extends React.Component<Props, State> {
|
||||||
|
constructor(props: Props) {
|
||||||
|
super(props);
|
||||||
|
|
||||||
|
// Define a state variable to track whether is an error or not
|
||||||
|
this.state = { hasError: false };
|
||||||
|
}
|
||||||
|
static getDerivedStateFromError(error: Error): State {
|
||||||
|
console.error(error);
|
||||||
|
// Update state so the next render will show the fallback UI
|
||||||
|
return { hasError: true };
|
||||||
|
}
|
||||||
|
componentDidCatch(error: Error, errorInfo: React.ErrorInfo): void {
|
||||||
|
// You can use your own error logging service here
|
||||||
|
console.log({ error, errorInfo });
|
||||||
|
}
|
||||||
|
render(): React.ReactNode {
|
||||||
|
// Check if the error is thrown
|
||||||
|
if (this.state.hasError) {
|
||||||
|
// You can render any custom fallback UI
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<h2>Oops, there is an error!</h2>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={() => this.setState({ hasError: false })}
|
||||||
|
>
|
||||||
|
Try again?
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return children components in case of no error
|
||||||
|
return this.props.children;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ErrorBoundary;
|
||||||
@@ -10,6 +10,7 @@ import { NoDataOverlay } from "@/components/noDataOverlay";
|
|||||||
import { StyledTableCell, StyledTableRow } from "./style";
|
import { StyledTableCell, StyledTableRow } from "./style";
|
||||||
import { ICustomTable, CustomTableConfiguration } from "@/types";
|
import { ICustomTable, CustomTableConfiguration } from "@/types";
|
||||||
import { Checkbox, Skeleton } from "@mui/material";
|
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 }: ICustomTable) => {
|
||||||
if (loading)
|
if (loading)
|
||||||
@@ -35,11 +36,15 @@ const CustomTable = ({ configuration, data, loading, tkey }: ICustomTable) => {
|
|||||||
|
|
||||||
// cover use case if we want to render a component
|
// cover use case if we want to render a component
|
||||||
if (render) renderedValue = render(value);
|
if (render) renderedValue = render(value);
|
||||||
|
if (typeof renderedValue === "object" && render === undefined) {
|
||||||
|
console.warn("Missing render function for column " + cellKey);
|
||||||
|
}
|
||||||
return (
|
return (
|
||||||
|
<ErrorBoundary>
|
||||||
<StyledTableCell key={cellKey} align="left">
|
<StyledTableCell key={cellKey} align="left">
|
||||||
{renderedValue}
|
{renderedValue}
|
||||||
</StyledTableCell>
|
</StyledTableCell>
|
||||||
|
</ErrorBoundary>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -54,19 +54,28 @@ export const ServiceTableConfig = [
|
|||||||
{
|
{
|
||||||
key: "status",
|
key: "status",
|
||||||
label: "Status",
|
label: "Status",
|
||||||
|
render: (value: any) => {
|
||||||
|
let renderedValue: any = "";
|
||||||
|
if (Array.isArray(value.data)) {
|
||||||
|
renderedValue = value.data.join(", ");
|
||||||
|
} else {
|
||||||
|
console.error("Status is not an array", value);
|
||||||
|
}
|
||||||
|
return renderedValue;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "other",
|
key: "action",
|
||||||
label: "Action",
|
label: "Action",
|
||||||
render: (value: any) => {
|
render: (value: any) => {
|
||||||
let renderedValue: any = "";
|
let renderedValue: any = "";
|
||||||
|
console.log("value", value.data);
|
||||||
if (typeof value === "object")
|
if (typeof value === "object")
|
||||||
renderedValue = (
|
renderedValue = (
|
||||||
<>
|
<>
|
||||||
{value.action.map((actionType: string) => (
|
{value.data.map((actionType: any) => (
|
||||||
<>
|
<>
|
||||||
<code>{actionType}</code>
|
<Button>{actionType.name}</Button>
|
||||||
<br />
|
|
||||||
</>
|
</>
|
||||||
))}
|
))}
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -1,77 +0,0 @@
|
|||||||
import { Button } from "@mui/material";
|
|
||||||
|
|
||||||
export const Client2ConsumerTableConfig = [
|
|
||||||
{
|
|
||||||
key: "service_name",
|
|
||||||
label: "Service name",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: "service_type",
|
|
||||||
label: "Service Type",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: "endpoint_url",
|
|
||||||
label: "End Point",
|
|
||||||
render: () => {
|
|
||||||
return (
|
|
||||||
<Button disabled variant="outlined">
|
|
||||||
Consume
|
|
||||||
</Button>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
// {
|
|
||||||
// key: "entity",
|
|
||||||
// label: "Entity",
|
|
||||||
// },
|
|
||||||
{
|
|
||||||
key: "entity_did",
|
|
||||||
label: "Entity DID",
|
|
||||||
},
|
|
||||||
// {
|
|
||||||
// key: "network",
|
|
||||||
// label: "Network",
|
|
||||||
// },
|
|
||||||
];
|
|
||||||
|
|
||||||
export const Client2ProducerTableConfig = [
|
|
||||||
{
|
|
||||||
key: "service_name",
|
|
||||||
label: "Service name",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: "service_type",
|
|
||||||
label: "Service Type",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: "endpoint_url",
|
|
||||||
label: "End Point",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: "entity_did",
|
|
||||||
label: "Entity DID",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: "status",
|
|
||||||
label: "Status",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: "other",
|
|
||||||
label: "Action",
|
|
||||||
render: (value: any) => {
|
|
||||||
let renderedValue: any = "";
|
|
||||||
if (typeof value === "object")
|
|
||||||
renderedValue = (
|
|
||||||
<>
|
|
||||||
{value.action.map((actionType: string) => (
|
|
||||||
<>
|
|
||||||
<code>{actionType}</code>
|
|
||||||
<br />
|
|
||||||
</>
|
|
||||||
))}
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
return renderedValue;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
];
|
|
||||||
Reference in New Issue
Block a user