Merge pull request #13308 from jakecrews74/github-pr-board-display-all

[Github Pull Requests Board] Show more than 10 PRs at one time
This commit is contained in:
Johan Haals
2022-08-30 11:15:46 +02:00
committed by GitHub
11 changed files with 136 additions and 36 deletions
+5
View File
@@ -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).
@@ -5,13 +5,27 @@
```ts
/// <reference types="react" />
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)
```
@@ -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"
},
@@ -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<GraphQlPullRequests<PullRequestsNumber[]>>();
const fn = React.useRef(
async (repo: string): Promise<PullRequestsNumber[]> => {
async (
repo: string,
pullRequestLimit?: number,
): Promise<PullRequestsNumber[]> => {
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<GraphQlPullRequests<PullRequestsNumber[]>>,
repositoryName: string,
organisation: string,
pullRequestLimit: number,
): Promise<PullRequestsNumber[]> {
const pullRequestEdges: PullRequestsNumber[] = [];
let result: GraphQlPullRequests<PullRequestsNumber[]> | 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;
}
@@ -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<PRCardFormating[]>([]);
const { repositories } = useUserRepositories();
const { loading, pullRequests, refreshPullRequests } =
usePullRequestsByTeam(repositories);
const { loading, pullRequests, refreshPullRequests } = usePullRequestsByTeam(
repositories,
pullRequestLimit,
);
const header = (
<InfoCardHeader onRefresh={refreshPullRequests}>
@@ -14,3 +14,4 @@
* limitations under the License.
*/
export { default as EntityTeamPullRequestsCard } from './EntityTeamPullRequestsCard';
export type { EntityTeamPullRequestsCardProps } from './EntityTeamPullRequestsCard';
@@ -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<PRCardFormating[]>([]);
const { repositories } = useUserRepositories();
const { loading, pullRequests, refreshPullRequests } =
usePullRequestsByTeam(repositories);
const { loading, pullRequests, refreshPullRequests } = usePullRequestsByTeam(
repositories,
pullRequestLimit,
);
const header = (
<InfoCardHeader onRefresh={refreshPullRequests}>
@@ -14,3 +14,4 @@
* limitations under the License.
*/
export { default as EntityTeamPullRequestsContent } from './EntityTeamPullRequestsContent';
export type { EntityTeamPullRequestsContentProps } from './EntityTeamPullRequestsContent';
@@ -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<PullRequestsColumn[]>([]);
const [loading, setLoading] = useState<boolean>(true);
const getPullRequests = useGetPullRequestsFromRepository();
@@ -27,7 +30,10 @@ export function usePullRequestsByTeam(repositories: string[]) {
const getPRsPerRepository = useCallback(
async (repository: string): Promise<PullRequests> => {
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(
@@ -17,3 +17,5 @@ export {
EntityTeamPullRequestsCard,
EntityTeamPullRequestsContent,
} from './plugin';
export type { EntityTeamPullRequestsCardProps } from './components/EntityTeamPullRequestsCard';
export type { EntityTeamPullRequestsContentProps } from './components/EntityTeamPullRequestsContent';
@@ -23,6 +23,10 @@ export type GraphQlPullRequests<T> = {
repository: {
pullRequests: {
edges: T;
pageInfo: {
hasNextPage: boolean;
endCursor?: string;
};
};
};
};