Skip to content

Commit

Permalink
PLU-164: Migrate all pagination to chakra/ogp ds (#341)
Browse files Browse the repository at this point in the history
  • Loading branch information
m0nggh authored Jan 8, 2024
1 parent df41a62 commit ccf840c
Show file tree
Hide file tree
Showing 13 changed files with 84 additions and 78 deletions.
24 changes: 3 additions & 21 deletions packages/backend/src/graphql/queries/get-executions.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import paginate from '@/helpers/pagination'
import Execution from '@/models/execution'
import ExtendedQueryBuilder from '@/models/query-builder'
import Context from '@/types/express/context'
Expand Down Expand Up @@ -27,35 +28,16 @@ const getExecutions = async (
}
}

const results = context.currentUser
const executionsQuery = context.currentUser
.$relatedQuery('executions')
.withGraphFetched({
flow: {
steps: true,
},
})
.where(filterBuilder)
.limit(params.limit)
.offset(params.offset)
.orderBy('created_at', 'desc')

const resultSize = context.currentUser
.$relatedQuery('executions')
.where(filterBuilder)
.resultSize()

const [records, count] = await Promise.all([results, resultSize])

return {
pageInfo: {
currentPage: Math.ceil(params.offset / params.limit + 1),
totalPages: Math.ceil(count / params.limit),
},
edges: records.map((record: Execution) => {
return {
node: record,
}
}),
}
return paginate(executionsQuery, params.limit, params.offset)
}
export default getExecutions
2 changes: 1 addition & 1 deletion packages/backend/src/graphql/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -482,7 +482,7 @@ type User {

type PageInfo {
currentPage: Int!
totalPages: Int!
totalCount: Int!
}

type ExecutionEdge {
Expand Down
2 changes: 1 addition & 1 deletion packages/backend/src/helpers/pagination.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const paginate = async (
return {
pageInfo: {
currentPage: Math.ceil(offset / limit + 1),
totalPages: Math.ceil(count / limit),
totalCount: count,
},
edges: records.map((record: Model) => {
return {
Expand Down
4 changes: 2 additions & 2 deletions packages/frontend/src/components/AppBar/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import * as URLS from 'config/urls'
export default function AppBar(): React.ReactElement {
return (
<Box maxW="full">
<Flex alignItems="center" pl={6} pr={3} py={4} gap={6}>
<Box flexGrow="1">
<Flex alignItems="center" pl={6} pr={3} py={4} gap={{ base: 3, sm: 6 }}>
<Box flexGrow="1" flexShrink="0">
<Image src={mainLogo} h={8} w={8} />
</Box>

Expand Down
31 changes: 14 additions & 17 deletions packages/frontend/src/components/AppFlows/index.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import type { IFlow } from '@plumber/types'

import { Link, useSearchParams } from 'react-router-dom'
import { useSearchParams } from 'react-router-dom'
import { useQuery } from '@apollo/client'
import Pagination from '@mui/material/Pagination'
import PaginationItem from '@mui/material/PaginationItem'
import { Flex } from '@chakra-ui/react'
import { Pagination } from '@opengovsg/design-system-react'
import AppFlowRow from 'components/FlowRow'
import NoResultFound from 'components/NoResultFound'
import * as URLS from 'config/urls'
Expand Down Expand Up @@ -55,20 +55,17 @@ export default function AppFlows(props: AppFlowsProps): React.ReactElement {
<AppFlowRow key={appFlow.id} flow={appFlow} />
))}

{pageInfo && pageInfo.totalPages > 1 && (
<Pagination
sx={{ display: 'flex', justifyContent: 'center', mt: 3 }}
page={pageInfo?.currentPage}
count={pageInfo?.totalPages}
onChange={(event, page) => setSearchParams({ page: page.toString() })}
renderItem={(item) => (
<PaginationItem
component={Link}
to={`${item.page === 1 ? '' : `?page=${item.page}`}`}
{...item}
/>
)}
/>
{pageInfo && pageInfo.totalCount > FLOW_PER_PAGE && (
<Flex justifyContent="center" mt={6}>
<Pagination
currentPage={pageInfo?.currentPage}
onPageChange={(page) =>
setSearchParams(page === 1 ? {} : { page: page.toString() })
}
pageSize={FLOW_PER_PAGE}
totalCount={pageInfo?.totalCount}
></Pagination>
</Flex>
)}
</>
)
Expand Down
10 changes: 8 additions & 2 deletions packages/frontend/src/components/ExecutionStep/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,13 @@ import AppIcon from 'components/AppIcon'
import ErrorResult from 'components/ErrorResult'
import JSONViewer from 'components/JSONViewer'
import { GET_APP } from 'graphql/queries/get-app'
import { EXECUTION_STEP_PER_PAGE } from 'pages/Execution'

import RetryButton from './RetryButton'

type ExecutionStepProps = {
index: number
page: number
executionStep: IExecutionStep
}

Expand All @@ -41,9 +43,13 @@ const errorIcon = (
color="interaction.critical.default"
/>
)
const getStepPosition = (page: number, index: number) => {
return (page - 1) * EXECUTION_STEP_PER_PAGE + index + 1
}

export default function ExecutionStep({
index,
page,
executionStep,
}: ExecutionStepProps): React.ReactElement | null {
const { data } = useQuery(GET_APP, {
Expand Down Expand Up @@ -91,11 +97,11 @@ export default function ExecutionStep({

<Box>
<Text textStyle="body-2">
{index === 0 ? 'Trigger' : 'Action'}
{index === 0 && page === 1 ? 'Trigger' : 'Action'}
</Text>

<Text textStyle="h5">
{index + 1}. {app?.name}
{getStepPosition(page, index)}. {app?.name}
</Text>
</Box>
</HStack>
Expand Down
4 changes: 2 additions & 2 deletions packages/frontend/src/graphql/pagination.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export type TEdge<TNode> =

export type TPageInfo = {
currentPage: number
totalPages: number
totalCount: number
}

export type TExisting<TNode> = Readonly<{
Expand All @@ -34,7 +34,7 @@ const makeEmptyData = <TNode>(): TExisting<TNode> => {
edges: [],
pageInfo: {
currentPage: 1,
totalPages: 1,
totalCount: 0,
},
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export const GET_EXECUTION_STEPS = gql`
) {
pageInfo {
currentPage
totalPages
totalCount
}
edges {
node {
Expand Down
2 changes: 1 addition & 1 deletion packages/frontend/src/graphql/queries/get-executions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export const GET_EXECUTIONS = gql`
) {
pageInfo {
currentPage
totalPages
totalCount
}
edges {
node {
Expand Down
2 changes: 1 addition & 1 deletion packages/frontend/src/graphql/queries/get-flows.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export const GET_FLOWS = gql`
) {
pageInfo {
currentPage
totalPages
totalCount
}
edges {
node {
Expand Down
34 changes: 26 additions & 8 deletions packages/frontend/src/pages/Execution/index.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import type { IExecutionStep } from '@plumber/types'

import * as React from 'react'
import { useParams } from 'react-router-dom'
import { useParams, useSearchParams } from 'react-router-dom'
import { useQuery } from '@apollo/client'
import { Box, Grid, Text } from '@chakra-ui/react'
import { Infobox } from '@opengovsg/design-system-react'
import { Box, Flex, Grid, Text } from '@chakra-ui/react'
import { Infobox, Pagination } from '@opengovsg/design-system-react'
import Container from 'components/Container'
import ExecutionHeader from 'components/ExecutionHeader'
import ExecutionStep from 'components/ExecutionStep'
Expand All @@ -15,23 +15,25 @@ type ExecutionParams = {
executionId: string
}

const EXECUTION_PER_PAGE = 100
export const EXECUTION_STEP_PER_PAGE = 100

const getLimitAndOffset = (page: number) => ({
limit: EXECUTION_PER_PAGE,
offset: (page - 1) * EXECUTION_PER_PAGE,
limit: EXECUTION_STEP_PER_PAGE,
offset: (page - 1) * EXECUTION_STEP_PER_PAGE,
})

export default function Execution(): React.ReactElement {
const { executionId } = useParams() as ExecutionParams
const [searchParams, setSearchParams] = useSearchParams()
const page = parseInt(searchParams.get('page') || '', 10) || 1
const { data: execution } = useQuery(GET_EXECUTION, {
variables: { executionId },
})
const { data, loading } = useQuery(GET_EXECUTION_STEPS, {
variables: { executionId, ...getLimitAndOffset(1) },
variables: { executionId, ...getLimitAndOffset(page) },
})

const { edges } = data?.getExecutionSteps || {}
const { pageInfo, edges } = data?.getExecutionSteps || {}
const executionSteps: IExecutionStep[] = edges?.map(
(edge: { node: IExecutionStep }) => edge.node,
)
Expand Down Expand Up @@ -62,9 +64,25 @@ export default function Execution(): React.ReactElement {
key={executionStep.id}
executionStep={executionStep}
index={i}
page={page}
/>
))}
</Grid>

{!loading &&
pageInfo &&
pageInfo.totalCount > EXECUTION_STEP_PER_PAGE && (
<Flex justifyContent="center" mt={6}>
<Pagination
currentPage={pageInfo?.currentPage}
onPageChange={(page) =>
setSearchParams(page === 1 ? {} : { page: page.toString() })
}
pageSize={EXECUTION_STEP_PER_PAGE}
totalCount={pageInfo?.totalCount}
></Pagination>
</Flex>
)}
</Container>
)
}
22 changes: 12 additions & 10 deletions packages/frontend/src/pages/Executions/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import {
InputLeftElement,
InputRightElement,
} from '@chakra-ui/react'
import Pagination from '@mui/material/Pagination'
import { Pagination } from '@opengovsg/design-system-react'
import Container from 'components/Container'
import ExecutionRow from 'components/ExecutionRow'
import ExecutionStatusMenu, { StatusType } from 'components/ExecutionStatusMenu'
Expand Down Expand Up @@ -77,7 +77,7 @@ export default function Executions(): ReactElement {

// page handling
const handlePageChange = useCallback(
(event: ChangeEvent<unknown>, page: number) =>
(page: number) =>
formatSearchParams({
page,
status: filterStatus,
Expand Down Expand Up @@ -157,7 +157,7 @@ export default function Executions(): ReactElement {
</Hide>
<PageTitle title={EXECUTIONS_TITLE} />
</Flex>
<InputGroup w="25rem">
<InputGroup maxW="25rem">
<InputLeftElement>
<Icon as={BiSearch} boxSize={5} />
</InputLeftElement>
Expand Down Expand Up @@ -204,13 +204,15 @@ export default function Executions(): ReactElement {
<ExecutionRow key={execution.id} execution={execution} />
))}

{!loading && pageInfo && pageInfo.totalPages > 1 && (
<Pagination
sx={{ display: 'flex', justifyContent: 'center', mt: 3 }}
page={pageInfo?.currentPage}
count={pageInfo?.totalPages}
onChange={handlePageChange}
/>
{!loading && pageInfo && pageInfo.totalCount > EXECUTION_PER_PAGE && (
<Flex justifyContent="center" mt={6}>
<Pagination
currentPage={pageInfo?.currentPage}
onPageChange={handlePageChange}
pageSize={EXECUTION_PER_PAGE}
totalCount={pageInfo?.totalCount}
></Pagination>
</Flex>
)}
</Container>
</Box>
Expand Down
23 changes: 12 additions & 11 deletions packages/frontend/src/pages/Flows/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ import { forwardRef, useCallback, useMemo } from 'react'
import type { LinkProps } from 'react-router-dom'
import { Link, useSearchParams } from 'react-router-dom'
import { useQuery } from '@apollo/client'
import { Hide } from '@chakra-ui/react'
import { Flex, Hide } from '@chakra-ui/react'
import AddIcon from '@mui/icons-material/Add'
import Box from '@mui/material/Box'
import CircularProgress from '@mui/material/CircularProgress'
import Divider from '@mui/material/Divider'
import Grid from '@mui/material/Grid'
import Pagination from '@mui/material/Pagination'
import { Pagination } from '@opengovsg/design-system-react'
import ConditionalIconButton from 'components/ConditionalIconButton'
import Container from 'components/Container'
import EmptyFlowsTemplate from 'components/EmptyFlows'
Expand Down Expand Up @@ -54,7 +54,7 @@ export default function Flows(): React.ReactElement {
)

const handlePageChange = useCallback(
(_event: React.ChangeEvent<unknown>, page: number) => {
(page: number) => {
formatSearchParams({
page,
input: flowName,
Expand Down Expand Up @@ -91,7 +91,6 @@ export default function Flows(): React.ReactElement {
})

const { pageInfo, edges } = data?.getFlows || {}

const flows: IFlow[] = edges?.map(({ node }: { node: IFlow }) => node)
const hasFlows = flows?.length

Expand Down Expand Up @@ -170,13 +169,15 @@ export default function Flows(): React.ReactElement {
/>
)}

{!loading && pageInfo && pageInfo.totalPages > 1 && (
<Pagination
sx={{ display: 'flex', justifyContent: 'center', mt: 3 }}
page={pageInfo?.currentPage}
count={pageInfo?.totalPages}
onChange={handlePageChange}
/>
{!loading && pageInfo && pageInfo.totalCount > FLOW_PER_PAGE && (
<Flex justifyContent="center" mt={6}>
<Pagination
currentPage={pageInfo?.currentPage}
onPageChange={handlePageChange}
pageSize={FLOW_PER_PAGE}
totalCount={pageInfo?.totalCount}
></Pagination>
</Flex>
)}
</Container>
</Box>
Expand Down

0 comments on commit ccf840c

Please sign in to comment.