diff --git a/src/components/pages/AppOverview/AppOverview.scss b/src/components/pages/AppOverview/AppOverview.scss index 8c0bb6f36..2ca099973 100644 --- a/src/components/pages/AppOverview/AppOverview.scss +++ b/src/components/pages/AppOverview/AppOverview.scss @@ -180,3 +180,7 @@ margin-top: 3px !important; font-size: 0.75rem !important; } + +.load-more-btn { + text-align: center; +} diff --git a/src/components/pages/AppOverview/index.tsx b/src/components/pages/AppOverview/index.tsx index 3d7c7f1ac..20441c8c8 100644 --- a/src/components/pages/AppOverview/index.tsx +++ b/src/components/pages/AppOverview/index.tsx @@ -30,6 +30,7 @@ import { PageSnackbar, ErrorBar, CircleProgress, + LoadMoreButton, } from '@catena-x/portal-shared-components' import { useTheme, Box } from '@mui/material' import { @@ -38,7 +39,11 @@ import { appToCard, } from 'features/apps/mapper' import { useFetchProvidedAppsQuery } from 'features/apps/apiSlice' -import { type AppInfo, type AppMarketplaceApp } from 'features/apps/types' +import { + type ProvidedApps, + type AppInfo, + type AppMarketplaceApp, +} from 'features/apps/types' import { useDispatch } from 'react-redux' import debounce from 'lodash.debounce' import { OVERLAYS } from 'types/Constants' @@ -58,7 +63,6 @@ export default function AppOverview() { const theme = useTheme() const dispatch = useDispatch() - const { data, refetch, isSuccess, isFetching } = useFetchProvidedAppsQuery() // Add an ESLint exception until there is a solution // eslint-disable-next-line const [itemCards, setItemCards] = useState([]) @@ -73,6 +77,17 @@ export default function AppOverview() { const [filterItem, setFilterItem] = useState() const [searchExpr, setSearchExpr] = useState('') + const [page, setPage] = useState(0) + const [argsData, setArgsData] = useState({ + page, + args: { + expr: '', + statusFilter: '', + }, + }) + + const { data, isFetching, isSuccess, refetch } = + useFetchProvidedAppsQuery(argsData) // Add an ESLint exception until there is a solution // eslint-disable-next-line const valueMap: any = { @@ -107,13 +122,17 @@ export default function AppOverview() { }, [itemCards]) useEffect(() => { - if (data) { - const filterItems = data.content?.map((item: AppMarketplaceApp) => - appToCard(item) + dispatch(setCurrentActiveStep()) + if (data?.content) + setCards( + data?.meta.page === 0 + ? setDataInfo(data) + : (i: CardItems[]) => i.concat(setDataInfo(data)) ) - setCards(filterItems) - } - }, [data]) + }, [data, dispatch]) + + const setDataInfo = (data: ProvidedApps) => + data.content.map((item: AppMarketplaceApp) => appToCard(item)) const debouncedSearch = useMemo( () => @@ -157,7 +176,25 @@ export default function AppOverview() { const setView = (e: React.MouseEvent) => { const viewValue = e.currentTarget.value setGroup(viewValue) - debouncedSearch(searchExpr, itemCards, viewValue) + setArgsData({ + page: 0, + args: { + expr: '', + statusFilter: viewValue, + }, + }) + setPage(0) + } + + const nextPage = () => { + setArgsData({ + page: page + 1, + args: { + expr: '', + statusFilter: group, + }, + }) + setPage(page + 1) } const categoryViews = [ @@ -297,6 +334,11 @@ export default function AppOverview() { ))} )} +
+ {data?.meta && data?.meta?.totalPages > page + 1 && ( + + )} +
{state && ( diff --git a/src/components/pages/AppOverviewNew/index.tsx b/src/components/pages/AppOverviewNew/index.tsx index 26dcfae79..86fe0bf07 100644 --- a/src/components/pages/AppOverviewNew/index.tsx +++ b/src/components/pages/AppOverviewNew/index.tsx @@ -28,7 +28,15 @@ import { appToCard } from 'features/apps/mapper' export default function AppOverviewNew() { const { t } = useTranslation() - const { data, refetch, isSuccess } = useFetchProvidedAppsQuery() + const { data, refetch, isSuccess } = useFetchProvidedAppsQuery({ + page: 0, + args: { + expr: '', + statusFilter: 'All', + }, + }) + // apiSlice has since been updated to accept params for pagination. + // Temporary solution until this page is completed. return (
diff --git a/src/features/apps/apiSlice.ts b/src/features/apps/apiSlice.ts index 61265b962..6a686c987 100644 --- a/src/features/apps/apiSlice.ts +++ b/src/features/apps/apiSlice.ts @@ -27,20 +27,21 @@ import i18next from 'i18next' import { getApiBase } from 'services/EnvironmentService' import { apiBaseQuery } from 'utils/rtkUtil' import { PAGE_SIZE } from 'types/Constants' -import type { - AppDetails, - AppMarketplaceApp, - SubscriptionStatusItem, - SubscriptionStatusDuplicateItem, - ActiveSubscriptionItem, - ProvidedApps, - DocumentRequestData, - SubscriptionAppRequest, - AgreementRequest, - ActiveSubscription, - ActiveSubscriptionDetails, - FetchSubscriptionAppQueryType, - SubscribedActiveApps, +import { + type AppDetails, + type AppMarketplaceApp, + type SubscriptionStatusItem, + type SubscriptionStatusDuplicateItem, + type ActiveSubscriptionItem, + type ProvidedApps, + type DocumentRequestData, + type SubscriptionAppRequest, + type AgreementRequest, + type ActiveSubscription, + type ActiveSubscriptionDetails, + type FetchSubscriptionAppQueryType, + type SubscribedActiveApps, + StatusIdEnum, } from './types' export const apiSlice = createApi({ @@ -104,8 +105,16 @@ export const apiSlice = createApi({ return { data: subscriptionData } }, }), - fetchProvidedApps: builder.query({ - query: () => '/api/apps/provided', + fetchProvidedApps: builder.query({ + query: (fetchArgs) => { + const { page, args } = fetchArgs + const baseUrl = `/api/apps/provided?page=${page}&size=15` + const statusId = args?.statusFilter + ? args.statusFilter + : StatusIdEnum.All + const offerName = args?.expr ? `&offerName=${args.expr}` : '' + return `${baseUrl}&statusId=${statusId}${offerName}` + }, }), fetchBusinessApps: builder.query({ query: () => '/api/apps/business', diff --git a/src/features/apps/types.ts b/src/features/apps/types.ts index b68a26c1e..057de1a74 100644 --- a/src/features/apps/types.ts +++ b/src/features/apps/types.ts @@ -264,3 +264,11 @@ export interface SubscribedActiveApps { subscriptionId: string image: string } + +export enum StatusIdEnum { + Active = 'Active', + Inactive = 'Inactive', + InReview = 'InReview', + WIP = 'WIP', + All = 'All', +}