generated from Luis/nextjs-python-web-template
added consume view and loaders on the buttons when clicked
This commit is contained in:
committed by
Sara Pervana
parent
1b549549c0
commit
b5008306cb
@@ -24,6 +24,7 @@ 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;
|
||||
@@ -105,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 {
|
||||
@@ -139,16 +144,16 @@ export default function Client() {
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
|
||||
const [snackbarOpen, setSnackbarOpen] = useState(false);
|
||||
const [snackbarMessage, setSnackbarMessage] = useState<
|
||||
SnackMessage | undefined
|
||||
>(undefined);
|
||||
|
||||
const closeSnackBar = () => {
|
||||
setSnackbarMessage(undefined);
|
||||
setSnackbarOpen(false);
|
||||
};
|
||||
|
||||
// Consume
|
||||
const handleConsumeContent = (content: any) => {
|
||||
setConsumeContent(content);
|
||||
};
|
||||
|
||||
if (services_loading) return <Skeleton height={500} />;
|
||||
if (!services) return <Alert severity="error">Client not found</Alert>;
|
||||
|
||||
@@ -185,17 +190,26 @@ export default function Client() {
|
||||
],
|
||||
}}
|
||||
/>
|
||||
<div>
|
||||
<h4>Client View</h4>
|
||||
<CustomTable
|
||||
loading={services_loading}
|
||||
data={clients}
|
||||
configuration={ClientTableConfig}
|
||||
tkey="client-table"
|
||||
/>
|
||||
<div className="flex items-center flex-nowrap justify-between w-full">
|
||||
<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}
|
||||
@@ -231,3 +245,18 @@ export default function Client() {
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const ClientTable = () => {
|
||||
return (
|
||||
<div>
|
||||
{/* <h4>Client View</h4>
|
||||
<CustomTable
|
||||
loading={services_loading}
|
||||
data={clients}
|
||||
onConsumeAction={handleConsumeContent}
|
||||
configuration={ClientTableConfig}
|
||||
tkey="client-table"
|
||||
/> */}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,15 +1,25 @@
|
||||
import { Button } from "@mui/material";
|
||||
import { Button, CircularProgress, Snackbar } from "@mui/material";
|
||||
import { useState } from "react";
|
||||
import axios from "axios";
|
||||
|
||||
const ConsumeAction = ({ endpoint }: { endpoint: string }) => {
|
||||
const [data, setData] = useState(null);
|
||||
const ConsumeAction = ({
|
||||
endpoint,
|
||||
onConsume,
|
||||
}: {
|
||||
endpoint: string;
|
||||
rowData?: any;
|
||||
onConsume?: any;
|
||||
}) => {
|
||||
const [error, setError] = useState(null);
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
if (data) console.log("Data in state", data);
|
||||
if (error) console.log("Error in state", error);
|
||||
if (error) console.error("Error in state", error);
|
||||
|
||||
const handleConsume = () => {
|
||||
if (loading) return;
|
||||
|
||||
setLoading(true);
|
||||
|
||||
const onConsume = () => {
|
||||
const axiosConfig = {
|
||||
url: endpoint,
|
||||
method: "GET",
|
||||
@@ -23,20 +33,40 @@ const ConsumeAction = ({ endpoint }: { endpoint: string }) => {
|
||||
|
||||
axios(axiosConfig)
|
||||
.then((response) => {
|
||||
setData(response.data);
|
||||
console.log("I got the data from consume: ", response.data);
|
||||
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(() => {});
|
||||
.finally(() => {
|
||||
setLoading(false);
|
||||
});
|
||||
};
|
||||
|
||||
const handleCloseSnackbar = () => {
|
||||
setError(null);
|
||||
};
|
||||
|
||||
return (
|
||||
<Button onClick={onConsume} variant="outlined">
|
||||
Consume
|
||||
</Button>
|
||||
<>
|
||||
<Button disabled={loading} onClick={handleConsume} variant="outlined">
|
||||
{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}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
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;
|
||||
@@ -1,5 +1,11 @@
|
||||
import { IEntityActions } from "@/types";
|
||||
import { Button, Snackbar, Alert, AlertColor } from "@mui/material";
|
||||
import {
|
||||
Button,
|
||||
Snackbar,
|
||||
Alert,
|
||||
AlertColor,
|
||||
CircularProgress,
|
||||
} from "@mui/material";
|
||||
import { useState } from "react";
|
||||
import { deleteEntity } from "@/api/entities/entities";
|
||||
import axios from "axios";
|
||||
@@ -24,17 +30,23 @@ const EntityActions = ({ endpointData, rowData }: Props) => {
|
||||
|
||||
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);
|
||||
|
||||
if (registerData) console.log("Register Data in state", registerData);
|
||||
if (registerError) console.log("Register Error in state", registerError);
|
||||
if (registerError) console.error("Register Error in state", registerError);
|
||||
|
||||
if (DeregisterData) console.log("Register Data in state", DeregisterData);
|
||||
if (DeregisterError) console.log("Register Error in state", DeregisterError);
|
||||
if (DeregisterError)
|
||||
console.error("Register Error in state", DeregisterError);
|
||||
|
||||
const onDeleteEntity = async () => {
|
||||
setLoadingDelete(true);
|
||||
if (rowData)
|
||||
try {
|
||||
const response = await deleteEntity({
|
||||
@@ -52,10 +64,16 @@ const EntityActions = ({ endpointData, rowData }: Props) => {
|
||||
message: "Failed to delete entity.",
|
||||
severity: "error",
|
||||
});
|
||||
} finally {
|
||||
setLoadingDelete(false);
|
||||
}
|
||||
};
|
||||
|
||||
const onRegisterEntity = (endpoint: string) => {
|
||||
if (loadingRegister) return;
|
||||
|
||||
setLoadingRegister(true);
|
||||
|
||||
const axiosConfig = {
|
||||
url: endpoint,
|
||||
method: "GET",
|
||||
@@ -76,10 +94,16 @@ const EntityActions = ({ endpointData, rowData }: Props) => {
|
||||
console.error("Error happened during register: ", error);
|
||||
setRegisterError(error);
|
||||
})
|
||||
.finally(() => {});
|
||||
.finally(() => {
|
||||
setLoadingRegister(false);
|
||||
});
|
||||
};
|
||||
|
||||
const onDeregisterEntity = (endpoint: string) => {
|
||||
if (loadingDeRegister) return;
|
||||
|
||||
setLoadingDeRegister(true);
|
||||
|
||||
const axiosConfig = {
|
||||
url: endpoint,
|
||||
method: "GET",
|
||||
@@ -95,7 +119,9 @@ const EntityActions = ({ endpointData, rowData }: Props) => {
|
||||
console.error("Error happened during deregister: ", error);
|
||||
setDeRegisterError(error);
|
||||
})
|
||||
.finally(() => {});
|
||||
.finally(() => {
|
||||
setLoadingDeRegister(false);
|
||||
});
|
||||
};
|
||||
|
||||
const handleCloseSnackbar = () => {
|
||||
@@ -108,8 +134,10 @@ const EntityActions = ({ endpointData, rowData }: Props) => {
|
||||
{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
|
||||
@@ -124,8 +152,13 @@ const EntityActions = ({ endpointData, rowData }: Props) => {
|
||||
);
|
||||
},
|
||||
)}
|
||||
<Button onClick={onDeleteEntity} size="small" variant="contained">
|
||||
Delete
|
||||
<Button
|
||||
disabled={loadingDelete}
|
||||
onClick={onDeleteEntity}
|
||||
size="small"
|
||||
variant="contained"
|
||||
>
|
||||
{loadingDelete ? <CircularProgress size={24} /> : `Delete`}
|
||||
</Button>
|
||||
</div>
|
||||
<Snackbar
|
||||
|
||||
@@ -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,11 @@ const CustomTable = ({ configuration, data, loading, tkey }: ICustomTable) => {
|
||||
const renderTableCell = (
|
||||
value: any,
|
||||
cellKey: string,
|
||||
render?: (param: any, data?: any) => void | undefined,
|
||||
render?: (
|
||||
param: any,
|
||||
data?: any,
|
||||
onFunc?: (param: any) => void,
|
||||
) => void | undefined,
|
||||
rowData?: any,
|
||||
) => {
|
||||
let renderedValue = value;
|
||||
@@ -36,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, rowData);
|
||||
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 (
|
||||
|
||||
@@ -13,8 +13,14 @@ export const ClientTableConfig = [
|
||||
{
|
||||
key: "endpoint_url",
|
||||
label: "End Point",
|
||||
render: (value: any) => {
|
||||
return <ConsumeAction endpoint={value} />;
|
||||
render: (value: any, rowData: any, onConsume: any) => {
|
||||
return (
|
||||
<ConsumeAction
|
||||
rowData={rowData}
|
||||
onConsume={onConsume}
|
||||
endpoint={value}
|
||||
/>
|
||||
);
|
||||
},
|
||||
},
|
||||
// {
|
||||
|
||||
@@ -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,6 +9,7 @@ export interface ICustomTable {
|
||||
data: any;
|
||||
loading?: boolean;
|
||||
tkey: string;
|
||||
onConsumeAction?: (param: any) => void;
|
||||
}
|
||||
|
||||
export interface EntityDetails {
|
||||
|
||||
Reference in New Issue
Block a user