diff --git a/.changeset/sweet-fishes-taste.md b/.changeset/sweet-fishes-taste.md
new file mode 100644
index 0000000000..8d1fcfc790
--- /dev/null
+++ b/.changeset/sweet-fishes-taste.md
@@ -0,0 +1,5 @@
+---
+'@backstage/plugin-github-pull-requests-board': patch
+---
+
+Add optional `pullRequestLimit` prop to `EntityTeamPullRequestsCard` and `EntityTeamPullRequestsContent` to limit the number of PRs shown per repository. Excluding this prop will default the number of pull requests shown to 10 per repository (the existing functionality).
diff --git a/plugins/github-pull-requests-board/api-report.md b/plugins/github-pull-requests-board/api-report.md
index 1657d455b5..81097118af 100644
--- a/plugins/github-pull-requests-board/api-report.md
+++ b/plugins/github-pull-requests-board/api-report.md
@@ -5,13 +5,27 @@
```ts
///
-import { FunctionComponent } from 'react';
+// @public (undocumented)
+export const EntityTeamPullRequestsCard: (
+ props: EntityTeamPullRequestsCardProps,
+) => JSX.Element;
// @public (undocumented)
-export const EntityTeamPullRequestsCard: FunctionComponent<{}>;
+export interface EntityTeamPullRequestsCardProps {
+ // (undocumented)
+ pullRequestLimit?: number;
+}
// @public (undocumented)
-export const EntityTeamPullRequestsContent: FunctionComponent<{}>;
+export const EntityTeamPullRequestsContent: (
+ props: EntityTeamPullRequestsContentProps,
+) => JSX.Element;
+
+// @public (undocumented)
+export interface EntityTeamPullRequestsContentProps {
+ // (undocumented)
+ pullRequestLimit?: number;
+}
// (No @packageDocumentation comment for this package)
```
diff --git a/plugins/github-pull-requests-board/package.json b/plugins/github-pull-requests-board/package.json
index 1b57aaddcf..b5bcc182cd 100644
--- a/plugins/github-pull-requests-board/package.json
+++ b/plugins/github-pull-requests-board/package.json
@@ -57,11 +57,11 @@
"@testing-library/user-event": "^14.0.0",
"@types/jest": "^26.0.7",
"@types/node": "^16.11.26",
+ "@types/react": "^16.13.1 || ^17.0.0",
"cross-fetch": "^3.1.5",
"msw": "^0.45.0"
},
"peerDependencies": {
- "@types/react": "^16.13.1 || ^17.0.0",
"react": "^16.13.1 || ^17.0.0",
"react-dom": "^16.13.1 || ^17.0.0"
},
diff --git a/plugins/github-pull-requests-board/src/api/useGetPullRequestsFromRepository.ts b/plugins/github-pull-requests-board/src/api/useGetPullRequestsFromRepository.ts
index bd5df89833..2295a01442 100644
--- a/plugins/github-pull-requests-board/src/api/useGetPullRequestsFromRepository.ts
+++ b/plugins/github-pull-requests-board/src/api/useGetPullRequestsFromRepository.ts
@@ -18,37 +18,86 @@ import React from 'react';
import { GraphQlPullRequests, PullRequestsNumber } from '../utils/types';
import { useOctokitGraphQl } from './useOctokitGraphQl';
+const PULL_REQUEST_LIMIT = 10;
+const GITHUB_GRAPHQL_MAX_ITEMS = 100;
+
export const useGetPullRequestsFromRepository = () => {
const graphql =
useOctokitGraphQl>();
const fn = React.useRef(
- async (repo: string): Promise => {
+ async (
+ repo: string,
+ pullRequestLimit?: number,
+ ): Promise => {
+ const limit = pullRequestLimit ?? PULL_REQUEST_LIMIT;
const [organisation, repositoryName] = repo.split('/');
- const { repository } = await graphql(
- `
- query ($name: String!, $owner: String!) {
- repository(name: $name, owner: $owner) {
- pullRequests(states: OPEN, first: 10) {
- edges {
- node {
- number
- }
- }
- }
- }
- }
- `,
- {
- name: repositoryName,
- owner: organisation,
- },
+ return await getPullRequestEdges(
+ graphql,
+ repositoryName,
+ organisation,
+ limit,
);
-
- return repository.pullRequests.edges;
},
);
return fn.current;
};
+
+async function getPullRequestEdges(
+ graphql: (
+ path: string,
+ options?: any,
+ ) => Promise>,
+ repositoryName: string,
+ organisation: string,
+ pullRequestLimit: number,
+): Promise {
+ const pullRequestEdges: PullRequestsNumber[] = [];
+ let result: GraphQlPullRequests | undefined = undefined;
+
+ do {
+ result = await graphql(
+ `
+ query (
+ $name: String!
+ $owner: String!
+ $first: Int
+ $endCursor: String
+ ) {
+ repository(name: $name, owner: $owner) {
+ pullRequests(states: OPEN, first: $first, after: $endCursor) {
+ edges {
+ node {
+ number
+ }
+ }
+ pageInfo {
+ hasNextPage
+ endCursor
+ }
+ }
+ }
+ }
+ `,
+ {
+ name: repositoryName,
+ owner: organisation,
+ first:
+ pullRequestLimit > GITHUB_GRAPHQL_MAX_ITEMS
+ ? GITHUB_GRAPHQL_MAX_ITEMS
+ : pullRequestLimit,
+ endCursor: result
+ ? result.repository.pullRequests.pageInfo.endCursor
+ : undefined,
+ },
+ );
+
+ pullRequestEdges.push(...result.repository.pullRequests.edges);
+
+ if (pullRequestEdges.length >= pullRequestLimit) return pullRequestEdges;
+ } while (result.repository.pullRequests.pageInfo.hasNextPage);
+
+ return pullRequestEdges;
+}
diff --git a/plugins/github-pull-requests-board/src/components/EntityTeamPullRequestsCard/EntityTeamPullRequestsCard.tsx b/plugins/github-pull-requests-board/src/components/EntityTeamPullRequestsCard/EntityTeamPullRequestsCard.tsx
index b19651536a..2ae33c6b07 100644
--- a/plugins/github-pull-requests-board/src/components/EntityTeamPullRequestsCard/EntityTeamPullRequestsCard.tsx
+++ b/plugins/github-pull-requests-board/src/components/EntityTeamPullRequestsCard/EntityTeamPullRequestsCard.tsx
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-import React, { FunctionComponent, useState } from 'react';
+import React, { useState } from 'react';
import { Grid, Typography } from '@material-ui/core';
import FullscreenIcon from '@material-ui/icons/Fullscreen';
@@ -28,11 +28,19 @@ import { PRCardFormating } from '../../utils/types';
import { DraftPrIcon } from '../icons/DraftPr';
import { useUserRepositories } from '../../hooks/useUserRepositories';
-const EntityTeamPullRequestsCard: FunctionComponent = () => {
+/** @public */
+export interface EntityTeamPullRequestsCardProps {
+ pullRequestLimit?: number;
+}
+
+const EntityTeamPullRequestsCard = (props: EntityTeamPullRequestsCardProps) => {
+ const { pullRequestLimit } = props;
const [infoCardFormat, setInfoCardFormat] = useState([]);
const { repositories } = useUserRepositories();
- const { loading, pullRequests, refreshPullRequests } =
- usePullRequestsByTeam(repositories);
+ const { loading, pullRequests, refreshPullRequests } = usePullRequestsByTeam(
+ repositories,
+ pullRequestLimit,
+ );
const header = (
diff --git a/plugins/github-pull-requests-board/src/components/EntityTeamPullRequestsCard/index.ts b/plugins/github-pull-requests-board/src/components/EntityTeamPullRequestsCard/index.ts
index bac16f1424..5c82402f7f 100644
--- a/plugins/github-pull-requests-board/src/components/EntityTeamPullRequestsCard/index.ts
+++ b/plugins/github-pull-requests-board/src/components/EntityTeamPullRequestsCard/index.ts
@@ -14,3 +14,4 @@
* limitations under the License.
*/
export { default as EntityTeamPullRequestsCard } from './EntityTeamPullRequestsCard';
+export type { EntityTeamPullRequestsCardProps } from './EntityTeamPullRequestsCard';
diff --git a/plugins/github-pull-requests-board/src/components/EntityTeamPullRequestsContent/EntityTeamPullRequestsContent.tsx b/plugins/github-pull-requests-board/src/components/EntityTeamPullRequestsContent/EntityTeamPullRequestsContent.tsx
index 33980e2364..de1dda2fb8 100644
--- a/plugins/github-pull-requests-board/src/components/EntityTeamPullRequestsContent/EntityTeamPullRequestsContent.tsx
+++ b/plugins/github-pull-requests-board/src/components/EntityTeamPullRequestsContent/EntityTeamPullRequestsContent.tsx
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-import React, { FunctionComponent, useState } from 'react';
+import React, { useState } from 'react';
import { Grid, Typography } from '@material-ui/core';
import { Progress, InfoCard } from '@backstage/core-components';
@@ -26,11 +26,21 @@ import { PRCardFormating } from '../../utils/types';
import { DraftPrIcon } from '../icons/DraftPr';
import { useUserRepositories } from '../../hooks/useUserRepositories';
-const EntityTeamPullRequestsContent: FunctionComponent = () => {
+/** @public */
+export interface EntityTeamPullRequestsContentProps {
+ pullRequestLimit?: number;
+}
+
+const EntityTeamPullRequestsContent = (
+ props: EntityTeamPullRequestsContentProps,
+) => {
+ const { pullRequestLimit } = props;
const [infoCardFormat, setInfoCardFormat] = useState([]);
const { repositories } = useUserRepositories();
- const { loading, pullRequests, refreshPullRequests } =
- usePullRequestsByTeam(repositories);
+ const { loading, pullRequests, refreshPullRequests } = usePullRequestsByTeam(
+ repositories,
+ pullRequestLimit,
+ );
const header = (
diff --git a/plugins/github-pull-requests-board/src/components/EntityTeamPullRequestsContent/index.ts b/plugins/github-pull-requests-board/src/components/EntityTeamPullRequestsContent/index.ts
index c2be57464c..032e698a21 100644
--- a/plugins/github-pull-requests-board/src/components/EntityTeamPullRequestsContent/index.ts
+++ b/plugins/github-pull-requests-board/src/components/EntityTeamPullRequestsContent/index.ts
@@ -14,3 +14,4 @@
* limitations under the License.
*/
export { default as EntityTeamPullRequestsContent } from './EntityTeamPullRequestsContent';
+export type { EntityTeamPullRequestsContentProps } from './EntityTeamPullRequestsContent';
diff --git a/plugins/github-pull-requests-board/src/hooks/usePullRequestsByTeam.tsx b/plugins/github-pull-requests-board/src/hooks/usePullRequestsByTeam.tsx
index 234a0baefd..2e6553f778 100644
--- a/plugins/github-pull-requests-board/src/hooks/usePullRequestsByTeam.tsx
+++ b/plugins/github-pull-requests-board/src/hooks/usePullRequestsByTeam.tsx
@@ -19,7 +19,10 @@ import { PullRequests, PullRequestsColumn } from '../utils/types';
import { useGetPullRequestsFromRepository } from '../api/useGetPullRequestsFromRepository';
import { useGetPullRequestDetails } from '../api/useGetPullRequestDetails';
-export function usePullRequestsByTeam(repositories: string[]) {
+export function usePullRequestsByTeam(
+ repositories: string[],
+ pullRequestLimit?: number,
+) {
const [pullRequests, setPullRequests] = useState([]);
const [loading, setLoading] = useState(true);
const getPullRequests = useGetPullRequestsFromRepository();
@@ -27,7 +30,10 @@ export function usePullRequestsByTeam(repositories: string[]) {
const getPRsPerRepository = useCallback(
async (repository: string): Promise => {
- const pullRequestsNumbers = await getPullRequests(repository);
+ const pullRequestsNumbers = await getPullRequests(
+ repository,
+ pullRequestLimit,
+ );
const pullRequestsWithDetails = await Promise.all(
pullRequestsNumbers.map(({ node }) =>
@@ -37,7 +43,7 @@ export function usePullRequestsByTeam(repositories: string[]) {
return pullRequestsWithDetails;
},
- [getPullRequests, getPullRequestDetails],
+ [getPullRequests, getPullRequestDetails, pullRequestLimit],
);
const getPRsFromTeam = useCallback(
diff --git a/plugins/github-pull-requests-board/src/index.ts b/plugins/github-pull-requests-board/src/index.ts
index d9cffaa468..c93c1732b8 100644
--- a/plugins/github-pull-requests-board/src/index.ts
+++ b/plugins/github-pull-requests-board/src/index.ts
@@ -17,3 +17,5 @@ export {
EntityTeamPullRequestsCard,
EntityTeamPullRequestsContent,
} from './plugin';
+export type { EntityTeamPullRequestsCardProps } from './components/EntityTeamPullRequestsCard';
+export type { EntityTeamPullRequestsContentProps } from './components/EntityTeamPullRequestsContent';
diff --git a/plugins/github-pull-requests-board/src/utils/types.tsx b/plugins/github-pull-requests-board/src/utils/types.tsx
index a2b121a1b8..a1e2dbfda3 100644
--- a/plugins/github-pull-requests-board/src/utils/types.tsx
+++ b/plugins/github-pull-requests-board/src/utils/types.tsx
@@ -23,6 +23,10 @@ export type GraphQlPullRequests = {
repository: {
pullRequests: {
edges: T;
+ pageInfo: {
+ hasNextPage: boolean;
+ endCursor?: string;
+ };
};
};
};