mirror of
https://github.com/Qortal/qapp-core.git
synced 2025-06-14 17:41:20 +00:00
added custom styles for list
This commit is contained in:
parent
d5f796281b
commit
e4b781c41f
@ -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 && (
|
||||
<Box sx={{
|
||||
display: 'flex',
|
||||
gap: '20px',
|
||||
alignItems: 'center',
|
||||
overflow: "auto",
|
||||
}}>
|
||||
<BarSpinner width="22px" color="green" />
|
||||
<Typography>{loadingMessage || `Fetching list`}</Typography>
|
||||
</Box>
|
||||
)}
|
||||
{!isLoading && resultsLength === 0 && (
|
||||
<Typography
|
||||
style={{
|
||||
display: "block",
|
||||
}}
|
||||
>
|
||||
{noResultsMessage}
|
||||
</Typography>
|
||||
)}
|
||||
{!isLoading && resultsLength > 0 && (
|
||||
<>
|
||||
{children}
|
||||
</>
|
||||
)}
|
||||
{loaderList && isLoading && (
|
||||
<>
|
||||
{loaderList("LOADING")}
|
||||
</>
|
||||
)}
|
||||
{loaderList && !isLoading && resultsLength === 0 && (
|
||||
<>
|
||||
{loaderList("NO_RESULTS")}
|
||||
</>
|
||||
)}
|
||||
{!loaderList && isLoading && (
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
gap: "20px",
|
||||
alignItems: "center",
|
||||
overflow: "auto",
|
||||
height: loaderHeight || "auto"
|
||||
}}
|
||||
>
|
||||
<BarSpinner width="22px" color="green" />
|
||||
<Typography>{loadingMessage || `Fetching list`}</Typography>
|
||||
</Box>
|
||||
)}
|
||||
{!loaderList && !isLoading && resultsLength === 0 && (
|
||||
<Typography
|
||||
style={{
|
||||
display: "block",
|
||||
}}
|
||||
>
|
||||
{noResultsMessage}
|
||||
</Typography>
|
||||
)}
|
||||
{!isLoading && resultsLength > 0 && <>{children}</>}
|
||||
</>
|
||||
)
|
||||
}
|
||||
);
|
||||
};
|
||||
|
15
src/common/Spacer.tsx
Normal file
15
src/common/Spacer.tsx
Normal file
@ -0,0 +1,15 @@
|
||||
import { Box } from "@mui/material";
|
||||
|
||||
export const Spacer = ({ height, width, ...props }: any) => {
|
||||
return (
|
||||
<Box
|
||||
sx={{
|
||||
height: height ? height : '0px',
|
||||
display: 'flex',
|
||||
flexShrink: 0,
|
||||
width: width ? width : '0px',
|
||||
...(props || {})
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
@ -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<QortalMetadata[]>([]);
|
||||
const { fetchResources } = useResources();
|
||||
@ -50,10 +77,12 @@ export const ResourceListDisplay = ({
|
||||
|
||||
return (
|
||||
<ListLoader
|
||||
noResultsMessage="No results available"
|
||||
noResultsMessage={defaultLoaderParams?.listNoResultsText || "No results available"}
|
||||
resultsLength={list?.length}
|
||||
isLoading={isLoading}
|
||||
loadingMessage="Retrieving list. Please wait."
|
||||
loadingMessage={defaultLoaderParams?.listLoadingText || "Retrieving list. Please wait."}
|
||||
loaderList={loaderList}
|
||||
loaderHeight={styles?.listLoadingHeight}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
@ -62,10 +91,15 @@ export const ResourceListDisplay = ({
|
||||
width: "100%",
|
||||
}}
|
||||
>
|
||||
<div style={{ display: "flex", flexGrow: isLoading ? 0 : 1 }}>
|
||||
<div style={{ display: "flex", flexGrow: 1 }}>
|
||||
<VirtualizedList list={list}>
|
||||
{(item: QortalMetadata, index: number) => (
|
||||
<ListItemWrapper item={item} index={index} render={listItem} />
|
||||
<>
|
||||
{styles?.gap && <Spacer height={`${styles.gap / 2}rem`} /> }
|
||||
<Spacer/>
|
||||
<ListItemWrapper defaultLoaderParams={defaultLoaderParams} item={item} index={index} render={listItem} renderListItemLoader={loaderItem} />
|
||||
{styles?.gap && <Spacer height={`${styles.gap / 2}rem`} /> }
|
||||
</>
|
||||
)}
|
||||
</VirtualizedList>
|
||||
</div>
|
||||
@ -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<ListItemWrapperProps> = ({
|
||||
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 (
|
||||
<ItemCardWrapper height={60} isInCart={false}>
|
||||
<ResourceLoader
|
||||
message="Fetching Data..."
|
||||
message={defaultLoaderParams?.listItemLoadingText || "Fetching Data..."}
|
||||
status="loading"
|
||||
/>
|
||||
</ItemCardWrapper>
|
||||
);
|
||||
if (findCachedResource === false)
|
||||
if (findCachedResource === false && !renderListItemLoader)
|
||||
return (
|
||||
<ItemCardWrapper height={60} isInCart={false}>
|
||||
<ResourceLoader
|
||||
message="Product is unavailble at this moment... Try again later."
|
||||
message={defaultLoaderParams?.listItemErrorText ||"Resource is unavailble at this moment... Try again later."}
|
||||
status="error"
|
||||
/>
|
||||
</ItemCardWrapper>
|
||||
);
|
||||
if(renderListItemLoader && (findCachedResource === false || findCachedResource === null)){
|
||||
return renderListItemLoader(findCachedResource === null ? "LOADING" : "ERROR")
|
||||
}
|
||||
|
||||
// Example transformation (Modify item if needed)
|
||||
const transformedItem = findCachedResource
|
||||
|
Loading…
x
Reference in New Issue
Block a user