Skip to content

Commit

Permalink
Merge pull request #64 from joshtyf/feature/service-catalog-pagination
Browse files Browse the repository at this point in the history
Implement pagination for Service Catalog
  • Loading branch information
Ziyang-98 authored Feb 17, 2024
2 parents 16cf368 + 5c3f92c commit eb32c5c
Show file tree
Hide file tree
Showing 2 changed files with 162 additions and 12 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import { Pipeline } from "@/types/pipeline"
import { useCallback, useEffect, useState } from "react"

interface UsePaginationOptions {
itemsPerPage?: number
services?: Pipeline[] | void
}

type ItemsPerRowType = "5" | "10" | "15" | "20" | "25"

const ITEMS_PER_PAGE = {
"5": 5,
"10": 10,
"15": 15,
"20": 20,
"25": 25,
}

const usePagination = ({ services }: UsePaginationOptions) => {
const [page, setPage] = useState<number>(1)
const [itemsPerPage, setItemsPerPage] = useState<number>(ITEMS_PER_PAGE["10"])
const [servicesAtPage, setServicesAtPage] = useState<Pipeline[]>(
services ? services.slice(0, itemsPerPage) : []
)
const noOfPages = services ? Math.ceil(services.length / itemsPerPage) : 0

const handleSetServicesAtPage = useCallback(
(pageNo: number, items: number = itemsPerPage) => {
const startIndex = (pageNo - 1) * items
const endIndex = pageNo * items
setServicesAtPage(services ? services.slice(startIndex, endIndex) : [])
},
[services, itemsPerPage]
)

useEffect(() => {
if (page > noOfPages) {
// Set page to last page
const newPageNo = noOfPages
setPage(newPageNo)
handleSetServicesAtPage(newPageNo)
} else {
handleSetServicesAtPage(page)
}
}, [itemsPerPage, page, services, handleSetServicesAtPage, noOfPages])

const handleClickNextPage = () => {
if (page < noOfPages) {
handleSetServicesAtPage(page + 1)
setPage(page + 1)
}
}

const handleClickPrevPage = () => {
if (page > 1) {
handleSetServicesAtPage(page - 1)
setPage(page - 1)
}
}

const handleClickPageNo = (pageNo: number) => {
handleSetServicesAtPage(pageNo)
setPage(pageNo)
}

const handleSetItemsPerPage = (itemsPerPageValue: ItemsPerRowType) => {
const itemsPerPage = ITEMS_PER_PAGE[itemsPerPageValue]
setItemsPerPage(itemsPerPage)
}
return {
page,
noOfPages,
handleClickNextPage,
isNextDisabled: page === noOfPages,
handleClickPrevPage,
isPrevDisabled: page === 1,
handleClickPageNo,
handleSetItemsPerPage,
servicesAtPage,
}
}

export default usePagination
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,66 @@ import {
PaginationPrevious,
} from "@/components/ui/pagination"
import { AppRouterInstance } from "next/dist/shared/lib/app-router-context.shared-runtime"
import usePagination from "../_hooks/use-pagination"
import {
Select,
SelectContent,
SelectGroup,
SelectItem,
SelectLabel,
SelectTrigger,
SelectValue,
} from "@/components/ui/select"
interface ServicesViewProps {
services: Pipeline[] | void
router: AppRouterInstance
}

const createPaginationItems = (
currentPage: number,
noOfPages: number,
handleClickPageNo: (pageNo: number) => void
) => {
const paginationItems = []
for (let i = 1; i <= noOfPages; i++) {
paginationItems.push(
<PaginationItem key={i}>
<Button
variant="ghost"
className="p-0"
onClick={() => {
handleClickPageNo(i)
}}
>
<PaginationLink isActive={i === currentPage}>{i}</PaginationLink>
</Button>
</PaginationItem>
)
}
return paginationItems
}

export default function ServicesView({ services, router }: ServicesViewProps) {
const {
page,
noOfPages,
handleClickNextPage,
isNextDisabled,
handleClickPrevPage,
isPrevDisabled,
handleClickPageNo,
handleSetItemsPerPage,
servicesAtPage,
} = usePagination({ itemsPerPage: 4, services })

return services && services.length === 0 ? (
<div className="flex justify-center items-center w-full h-3/5">
<h1 className="font-bold text-3xl">No services available</h1>
</div>
) : (
<>
<div className=" grid grid-cols-auto-fill-min-20 gap-y-10 max-h-[75%] overflow-y-auto">
{services?.map((service) => (
{servicesAtPage?.map((service) => (
<div key={service.id} className="flex items-center justify-center">
<Card className="w-[250px] shadow">
<CardHeader>
Expand All @@ -48,20 +94,41 @@ export default function ServicesView({ services, router }: ServicesViewProps) {
<Pagination>
<PaginationContent>
<PaginationItem>
<PaginationPrevious />
</PaginationItem>
<PaginationItem>
<PaginationLink isActive>1</PaginationLink>
</PaginationItem>
<PaginationItem>
<PaginationLink>2</PaginationLink>
</PaginationItem>
<PaginationItem>
<PaginationLink>3</PaginationLink>
<Button
variant="ghost"
className="p-0"
disabled={isPrevDisabled}
onClick={handleClickPrevPage}
>
<PaginationPrevious />
</Button>
</PaginationItem>
{createPaginationItems(page, noOfPages, handleClickPageNo)}
<PaginationItem>
<PaginationNext />
<Button
variant="ghost"
className="p-0"
disabled={isNextDisabled}
onClick={handleClickNextPage}
>
<PaginationNext />
</Button>
</PaginationItem>
<Select defaultValue="10" onValueChange={handleSetItemsPerPage}>
<SelectTrigger className="w-[100px]">
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectGroup>
<SelectLabel>Items per page</SelectLabel>
<SelectItem value={"5"}>5</SelectItem>
<SelectItem value={"10"}>10</SelectItem>
<SelectItem value={"15"}>15</SelectItem>
<SelectItem value={"20"}>20</SelectItem>
<SelectItem value={"25"}>25</SelectItem>
</SelectGroup>
</SelectContent>
</Select>
</PaginationContent>
</Pagination>
</div>
Expand Down

0 comments on commit eb32c5c

Please sign in to comment.