import React from 'dom-chef'; import cache from 'webext-storage-cache'; import onetime from 'onetime'; import {observe} from 'selector-observer'; import MergeIcon from 'octicon/git-merge.svg'; import * as pageDetect from 'github-url-detection'; import PullRequestIcon from 'octicon/git-pull-request.svg'; import features from '.'; import * as api from '../github-helpers/api'; import {getRepo, upperCaseFirst} from '../github-helpers'; interface PullRequest { number: number; state: string; isDraft: boolean; url: string; } const getPullRequestsAssociatedWithBranch = cache.function(async (): Promise> => { const {repository} = await api.v4(` repository() { refs(refPrefix: "refs/heads/", last: 100) { nodes { name associatedPullRequests(last: 1, orderBy: {field: CREATED_AT, direction: DESC}) { nodes { number state isDraft url timelineItems(last: 1, itemTypes: [HEAD_REF_DELETED_EVENT, HEAD_REF_RESTORED_EVENT]) { nodes { __typename } } } } } } } `); const pullRequests: Record = {}; for (const {name, associatedPullRequests} of repository.refs.nodes) { const [prInfo] = associatedPullRequests.nodes; // Check if the ref was deleted, since the result includes pr's that are not in fact related to this branch but rather to the branch name. const headRefWasDeleted = prInfo?.timelineItems.nodes[0]?.__typename === 'HeadRefDeletedEvent'; if (prInfo && !headRefWasDeleted) { prInfo.state = prInfo.isDraft && prInfo.state === 'OPEN' ? 'Draft' : upperCaseFirst(prInfo.state); pullRequests[name] = prInfo; } } return pullRequests; }, { maxAge: {hours: 1}, staleWhileRevalidate: {days: 4}, cacheKey: () => 'associatedBranchPullRequests:' + getRepo()!.nameWithOwner }); const stateClass: Record = { Open: '--green', Closed: '--red', Merged: '--purple', Draft: '' }; async function init(): Promise { const associatedPullRequests = await getPullRequestsAssociatedWithBranch(); observe('.test-compare-link', { add(branchCompareLink) { const branchName = branchCompareLink.closest('[branch]')!.getAttribute('branch')!; const prInfo = associatedPullRequests[branchName]; if (prInfo) { const StateIcon = prInfo.state === 'Merged' ? MergeIcon : PullRequestIcon; branchCompareLink.replaceWith(
#{prInfo.number}{' '} {prInfo.state}
); } } }); } void features.add(__filebasename, { include: [ pageDetect.isBranches ], exclude: [ () => !pageDetect.isForkedRepo() ], awaitDomReady: false, init: onetime(init) });