From e4b781c41fc63b9b399293dd644d5fce1acbffc0 Mon Sep 17 00:00:00 2001 From: PhilReact Date: Wed, 12 Mar 2025 08:47:50 +0200 Subject: [PATCH] added custom styles for list --- src/common/ListLoader.tsx | 81 ++++++++++++------- src/common/Spacer.tsx | 15 ++++ .../ResourceList/ResourceListDisplay.tsx | 58 ++++++++++--- 3 files changed, 114 insertions(+), 40 deletions(-) create mode 100644 src/common/Spacer.tsx diff --git a/src/common/ListLoader.tsx b/src/common/ListLoader.tsx index a677e07..581bf8c 100644 --- a/src/common/ListLoader.tsx +++ b/src/common/ListLoader.tsx @@ -1,5 +1,6 @@ -import { Box, Typography } from "@mui/material" -import { BarSpinner } from "./Spinners/BarSpinner/BarSpinner" +import { Box, Typography } from "@mui/material"; +import { BarSpinner } from "./Spinners/BarSpinner/BarSpinner"; +import { CSSProperties } from "react"; interface ListLoaderProps { isLoading: boolean; @@ -7,37 +8,55 @@ interface ListLoaderProps { resultsLength: number; noResultsMessage?: string; // Optional message when no results children: React.ReactNode; // Required, to render the list content + loaderList?: (status: "LOADING" | "NO_RESULTS") => React.ReactNode; // Function type + loaderHeight?: CSSProperties } - -export const ListLoader = ({ isLoading, loadingMessage, resultsLength, children, noResultsMessage }: ListLoaderProps) => { +export const ListLoader = ({ + isLoading, + loadingMessage, + resultsLength, + children, + noResultsMessage, + loaderList, + loaderHeight +}: ListLoaderProps) => { return ( <> - {isLoading && ( - - - {loadingMessage || `Fetching list`} - - )} - {!isLoading && resultsLength === 0 && ( - - {noResultsMessage} - - )} - {!isLoading && resultsLength > 0 && ( - <> - {children} - - )} + {loaderList && isLoading && ( + <> + {loaderList("LOADING")} + + )} + {loaderList && !isLoading && resultsLength === 0 && ( + <> + {loaderList("NO_RESULTS")} + + )} + {!loaderList && isLoading && ( + + + {loadingMessage || `Fetching list`} + + )} + {!loaderList && !isLoading && resultsLength === 0 && ( + + {noResultsMessage} + + )} + {!isLoading && resultsLength > 0 && <>{children}} - ) -} + ); +}; diff --git a/src/common/Spacer.tsx b/src/common/Spacer.tsx new file mode 100644 index 0000000..b1a2743 --- /dev/null +++ b/src/common/Spacer.tsx @@ -0,0 +1,15 @@ +import { Box } from "@mui/material"; + +export const Spacer = ({ height, width, ...props }: any) => { + return ( + + ); + }; \ No newline at end of file diff --git a/src/components/ResourceList/ResourceListDisplay.tsx b/src/components/ResourceList/ResourceListDisplay.tsx index a2c709b..16efad9 100644 --- a/src/components/ResourceList/ResourceListDisplay.tsx +++ b/src/components/ResourceList/ResourceListDisplay.tsx @@ -15,16 +15,43 @@ import { ListLoader } from "../../common/ListLoader"; import { ListItem, useCacheStore } from "../../state/cache"; import { ResourceLoader } from "./ResourceLoader"; import { ItemCardWrapper } from "./ItemCardWrapper"; +import { Spacer } from "../../common/Spacer"; + +interface ResourceListStyles { + gap?: number + listLoadingHeight?: CSSProperties +} + +interface DefaultLoaderParams { + listLoadingText?: string + listNoResultsText?: string + listItemLoadingText?: string + listItemErrorText?: string +} + interface PropsResourceListDisplay { params: QortalSearchParams; listItem: (item: ListItem, index: number) => React.ReactNode; // Function type + styles?: ResourceListStyles + loaderItem?: (status: "LOADING" | "ERROR") => React.ReactNode; // Function type + defaultLoaderParams?: DefaultLoaderParams + loaderList?: (status: "LOADING" | "NO_RESULTS") => React.ReactNode; // Function type } + + + export const ResourceListDisplay = ({ params, listItem, + styles = { + gap: 1 + }, + defaultLoaderParams, + loaderItem, + loaderList }: PropsResourceListDisplay) => { const [list, setList] = useState([]); const { fetchResources } = useResources(); @@ -50,10 +77,12 @@ export const ResourceListDisplay = ({ return (
-
+
{(item: QortalMetadata, index: number) => ( - + <> + {styles?.gap && } + + + {styles?.gap && } + )}
@@ -78,38 +112,44 @@ interface ListItemWrapperProps { item: QortalMetadata; index: number; render: (item: ListItem, index: number) => React.ReactNode; + defaultLoaderParams?: DefaultLoaderParams; + renderListItemLoader?:(status: "LOADING" | "ERROR")=> React.ReactNode; } const ListItemWrapper: React.FC = ({ item, index, render, + defaultLoaderParams, + renderListItemLoader }) => { - console.log("Rendering wrapped item:", item, index); const getResourceCache = useCacheStore().getResourceCache; const findCachedResource = getResourceCache( `${item.service}-${item.name}-${item.identifier}`, true ); - if (findCachedResource === null) + if (findCachedResource === null && !renderListItemLoader) return ( ); - if (findCachedResource === false) + if (findCachedResource === false && !renderListItemLoader) return ( ); + if(renderListItemLoader && (findCachedResource === false || findCachedResource === null)){ + return renderListItemLoader(findCachedResource === null ? "LOADING" : "ERROR") + } // Example transformation (Modify item if needed) const transformedItem = findCachedResource