import {
useEffect,
useRef,
useState,
useMemo,
useCallback,
lazy,
Suspense,
} from "react";
import { useSelector } from "react-redux";
import { Modal, Radio } from "antd";
import { jqx } from "jqwidgets-scripts/jqwidgets-react-tsx/jqxtreegrid";
import axios from "axios";
import loadingGif from "../../../assets/Loading.gif";
const JqxGrid = lazy(() =>
import("jqwidgets-scripts/jqwidgets-react-tsx/jqxgrid")
);
const JqxTreeGrid = lazy(() =>
import("jqwidgets-scripts/jqwidgets-react-tsx/jqxtreegrid")
);
const ListUI = ({
genoString,
setGenoString,
showGenoList,
setShowGenoList,
}) => {
const { serverDetails } = useSelector((state) => state.serverDetails);
const [dataAdapter, setDataAdapter] = useState(null);
const [dataAdapter2, setDataAdapter2] = useState(null);
const [showRecent, setShowRecent] = useState(false);
const [loading, setLoading] = useState(false);
const ref = useRef(null);
const ref2 = useRef(null);
const fetchData = useCallback(
async (url, method, headers = {}, data = null) => {
setLoading(true);
try {
const response = await axios({ url, method, headers, data });
return response.data;
} catch (error) {
console.error("Error fetching data: ", error);
if (typeof DisplayError !== "undefined") {
DisplayError({ message: error.message }, "#divError");
}
} finally {
setLoading(false);
}
},
[]
);
useEffect(() => {
if (showGenoList) {
const baseUrl =
window.location.protocol === "http:"
? serverDetails.internalServerUrl ?? ""
: serverDetails.ServerUrl ?? "";
if (showRecent) {
if (!dataAdapter2) {
fetchData(
`${baseUrl}/endpointForGRid`,
"POST",
{
"Content-Type": "application/json",
}
).then((data) => {
if (data) {
const source = {
datatype: "json",
type: "POST",
datafields: [
{ name: "objectid", map: "objectid", type: "int" },
{ name: "objectname", map: "objectname", type: "string" },
],
id: "objectid",
localdata: data.GetRecentlistDetails,
};
setDataAdapter2(new jqx.dataAdapter(source));
}
});
}
} else {
if (!dataAdapter) {
fetchData(
`${baseUrl}/endpointforTreegrid`,
"GET",
{
"Content-Type": "application/json",
}
).then((data) => {
if (data) {
const source = {
datatype: "json",
datafields: [
{ name: "GenoKey", type: "int" },
{ name: "ParentGenoKey", type: "int" },
{ name: "GenealogyCombination", type: "string" },
],
hierarchy: {
keyDataField: { name: "GenoKey" },
parentDataField: { name: "ParentGenoKey" },
},
id: "GenoKey",
localdata: data,
};
setDataAdapter(new jqx.dataAdapter(source));
}
});
}
}
}
}, [showGenoList, showRecent, serverDetails, fetchData, dataAdapter2, dataAdapter]);
const columns = useMemo(
() => [
{ text: "", dataField: "GenoKey", hidden: true },
{ text: "", dataField: "ParentGenoKey", hidden: true },
{ text: "Geno string", dataField: "GenealogyCombination" },
],
[]
);
const columns2 = useMemo(
() => [
{ text: "", dataField: "objectid", hidden: true },
{ text: "", dataField: "objectname", width: "100%" },
],
[]
);
const handleOk = () => {
const index = ref.current?.getselectedrowindex();
if (index !== undefined) {
setGenoString(ref.current?.getrowdata(index)?.GenealogyString);
setShowGenoList(false);
}
};
const handleCancel = () => setShowGenoList(false);
return (
<Modal
title="List UI"
open={showGenoList}
onOk={handleOk}
onCancel={handleCancel}
width={450}
centered
style={{ height: 400 }}
okButtonProps={{
style: {
backgroundColor: typeof c1 !== "undefined" ? c1 : "#184e54",
color: typeof p3 !== "undefined" ? p3 : "white",
},
}}
cancelButtonProps={{
style: {
backgroundColor: typeof c1 !== "undefined" ? c1 : "#184e54",
color: typeof p3 !== "undefined" ? p3 : "white",
},
}}
>
<div>
<Radio.Group
name="radiogroup"
defaultValue={1}
onChange={(e) => {
const value = e.target.value;
setShowRecent(value === 2);
setLoading(true);
}}
>
<Radio value={1}>TreeGrid</Radio>
<Radio value={2}>Grid</Radio>
</Radio.Group>
<div id="jqxtreeGridGenealogySel">
<div
style={{
justifyContent: "center",
alignItems: "center",
height: "100%",
zIndex: 999,
display: loading ? "flex" : "none",
}}
>
<img src={loadingGif} alt="Loading..." />
</div>
{dataAdapter2 && (
<Suspense
fallback={
<div
style={{
justifyContent: "center",
alignItems: "center",
height: "100%",
zIndex: 999,
display: "flex",
}}
>
<img src={loadingGif} alt="Loading..." />
</div>
}
>
<JqxGrid
ref={ref2}
width={"100%"}
showheader={false}
height={"350px"}
source={dataAdapter2}
columns={columns2}
enabletooltips={true}
editable={false}
style={{ display: showRecent ? "block" : "none" }}
selectionmode="singlerow"
theme="material"
onBindingcomplete={() => setLoading(false)}
ready={() => setLoading(false)}
/>
</Suspense>
)}
{dataAdapter && (
<Suspense
fallback={
<div
style={{
justifyContent: "center",
alignItems: "center",
height: "100%",
zIndex: 999,
display: "flex",
}}
>
<img src={loadingGif} alt="Loading..." />
</div>
}
>
<JqxTreeGrid
ref={ref}
width={"100%"}
showHeader={false}
height={"350px"}
source={dataAdapter}
style={{ display: !showRecent ? "block" : "none" }}
columns={columns}
enabletooltips={true}
editable={false}
selectionmode="singlerow"
theme="material"
onBindingcomplete={() => setLoading(false)}
ready={() => setLoading(false)}
/>
</Suspense>
)}
</div>
</div>
</Modal>
);
};
export default ListUI;
I’m experiencing an issue with rendering delays. When I click a radio button, the change event triggers and the JqxGrid updates, but there’s a noticeable delay in the radio button’s selection state updating— the clicked radio button shows as selected only after a delay.
Is there a way to address this delay? Additionally, any way to show a loading indicator while the JqxGrid or Tree Grid is rendering?