From 2ac06c850ac3b3c2e5d8f6579a0831e43ca62a5a Mon Sep 17 00:00:00 2001 From: Ayushi Sharma Date: Sun, 21 Apr 2024 21:33:21 +0530 Subject: [PATCH] feat: fixed filter functionality --- .../apsara-ui/src/Listing/InfiniteScroll.tsx | 48 +++++++------------ .../apsara-ui/src/Listing/Listing.stories.tsx | 36 ++++++++++++-- 2 files changed, 51 insertions(+), 33 deletions(-) diff --git a/packages/apsara-ui/src/Listing/InfiniteScroll.tsx b/packages/apsara-ui/src/Listing/InfiniteScroll.tsx index 528a8deb..65899160 100644 --- a/packages/apsara-ui/src/Listing/InfiniteScroll.tsx +++ b/packages/apsara-ui/src/Listing/InfiniteScroll.tsx @@ -4,8 +4,10 @@ import React, { useState, useEffect } from "react"; interface InfiniteScrollProps { fetchMoreData: (page: number, pageSize: number, filters: any) => Promise; contentRef: React.RefObject; + page: number; pageSize?: number; filters?: any; + threshold?: number; renderItem: (item: T) => React.ReactNode; loadingComponent?: React.ReactNode; noMoreDataComponent?: React.ReactNode; @@ -14,26 +16,30 @@ interface InfiniteScrollProps { const InfiniteScroll: React.FC> = ({ fetchMoreData, contentRef, + page, pageSize = 10, + threshold = 0, filters, renderItem, loadingComponent, noMoreDataComponent, }) => { const [data, setData] = useState([]); - const [page, setPage] = useState(1); const [isLoading, setIsLoading] = useState(false); const [hasMoreData, setHasMoreData] = useState(true); - const [isFirstFetch, setIsFirstFetch] = useState(true); - const onBottomHit = debounce(async () => { + useEffect(() => { + setData([]); + setHasMoreData(true); + }, [filters]); + + const fetchMore = debounce(async () => { if (!isLoading && hasMoreData && isBottom(contentRef)) { setIsLoading(true); try { const newData = await fetchMoreData(page, pageSize, filters); setData((prevData) => prevData.concat(newData)); - setPage((prevPage) => prevPage + 1); - setHasMoreData(newData.length > 0); + setHasMoreData(newData.length < pageSize ? false : true); } finally { setIsLoading(false); } @@ -41,23 +47,17 @@ const InfiniteScroll: React.FC> = ({ }, 200); useEffect(() => { - setPage(1); - setHasMoreData(true); - setData([]); - }, [filters]); - - useEffect(() => { - if (isFirstFetch) { - onBottomHit(); + if (page == 1 && !data.length) { + fetchMore(); } - setIsFirstFetch(false); const onScroll = () => { - onBottomHit(); + if (page != 1) { + fetchMore(); + } }; const currentContentRef = contentRef.current; - if (currentContentRef) { currentContentRef.addEventListener("scroll", onScroll); } @@ -67,19 +67,7 @@ const InfiniteScroll: React.FC> = ({ currentContentRef.removeEventListener("scroll", onScroll); } }; - }, [ - contentRef, - isLoading, - hasMoreData, - page, - filters, - fetchMoreData, - setData, - setPage, - setHasMoreData, - isFirstFetch, - onBottomHit, - ]); + }, [contentRef, fetchMore, page, filters]); const isBottom = (ref: React.RefObject) => { if (!ref.current) { @@ -88,7 +76,7 @@ const InfiniteScroll: React.FC> = ({ const { scrollTop, scrollHeight, clientHeight } = ref.current; - return scrollTop + clientHeight >= scrollHeight; + return scrollTop + clientHeight >= scrollHeight - threshold; }; return ( diff --git a/packages/apsara-ui/src/Listing/Listing.stories.tsx b/packages/apsara-ui/src/Listing/Listing.stories.tsx index 1d4a3d68..cc2b6398 100644 --- a/packages/apsara-ui/src/Listing/Listing.stories.tsx +++ b/packages/apsara-ui/src/Listing/Listing.stories.tsx @@ -1,8 +1,9 @@ -import React, { useRef, useState } from "react"; +import React, { FormEvent, useRef, useState } from "react"; import Listing from "./Listing"; import InfiniteListing from "./InfiniteListing"; import { ScrollableList, UserCard } from "./Listing.styles"; import InfiniteScroll from "./InfiniteScroll"; +import Search from "../Search"; export default { title: "Data Display/Listing", @@ -194,6 +195,10 @@ export const infiniteListingWithApply = () => { export const infiniteListWithCustomComponent = () => { const pageSize = 10; const contentRef = useRef(null); + const [searchTerm, setSearchTerm] = useState(""); + const [filter, setFilter] = useState(); + const [page, setPage] = useState(1); + const fetchRecords = (page: number, pageSize: number) => { return Array.from({ length: pageSize }, (_, i) => ({ name: `user ${page * pageSize + i}`, @@ -203,9 +208,14 @@ export const infiniteListWithCustomComponent = () => { }; const fetchMore = async (page: number, pageSize: number, filter: string) => { - console.log(filter); - const records = fetchRecords(page, pageSize); + if (page === 4) return []; + + let records = fetchRecords(page, pageSize); + if (filter) { + records = records.filter((record) => record.name.toLowerCase().includes(filter.toLowerCase())); + } + setPage((prevPage) => prevPage + 1); return records; }; @@ -224,11 +234,31 @@ export const infiniteListWithCustomComponent = () => { ); }; + const onSubmit = (e: FormEvent) => { + e.preventDefault(); + setPage(1); + setFilter(searchTerm); + }; + return (
+
+ { + return setSearchTerm(e.target.value); + }} + placeholder="Type your search query here.." + // @ts-ignore + secondary={true} + /> + }