import React from 'dom-chef'; import cache from 'webext-storage-cache'; import select from 'select-dom'; 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 getDefaultBranch from '../github-helpers/get-default-branch'; import {getRepoURL, getRepoGQL} from '../github-helpers'; function getPRUrl(prNumber: number): string { return `/${getRepoURL()}/pull/${prNumber}/files`; } function getDropdown(prs: number[]): HTMLElement { // Markup copied from https://primer.style/css/components/dropdown return (
{prs.length}
); } function getSingleButton(prNumber: number, _?: number, prs?: number[]): HTMLElement { return ( #{prNumber} ); } /** @returns prsByFile {"filename1": [10, 3], "filename2": [2]} */ const getPrsByFile = cache.function(async (): Promise> => { const {repository} = await api.v4(` repository(${getRepoGQL()}) { pullRequests( first: 25, states: OPEN, baseRefName: "${await getDefaultBranch()}", orderBy: { field: UPDATED_AT, direction: DESC } ) { nodes { number files(first: 100) { nodes { path } } } } } `); const files: Record = {}; for (const pr of repository.pullRequests.nodes) { for (const {path} of pr.files.nodes) { files[path] = files[path] || []; if (files[path].length < 10) { files[path].push(pr.number); } } } return files; }, { maxAge: 1, staleWhileRevalidate: 9, cacheKey: () => __filebasename + ':' + getRepoURL() }); async function init(): Promise { // `clipboard-copy` on blob page, `#blob-edit-path` on edit page const path = select('clipboard-copy, #blob-edit-path')!.getAttribute('value')!; const {[path]: prs} = await getPrsByFile(); if (!prs) { return; } const [prNumber] = prs; // First one or only one if (pageDetect.isEditingFile()) { select('.file')!.after(
{ prs.length === 1 ? <>Careful, PR #{prNumber} is already touching this file : <> Careful, {prs.length} open PRs are already touching this file {prs.map(getSingleButton)} }
); return; } if (prs.length > 1) { select('.breadcrumb')!.before(getDropdown(prs)); return; } const link = getSingleButton(prNumber); link.classList.add('ml-2', 'tooltipped', 'tooltipped-ne'); link.setAttribute('aria-label', `This file is touched by PR #${prNumber}`); select('.breadcrumb')!.before(link); } void features.add({ id: __filebasename, description: 'Shows PRs that touch the current file.', screenshot: 'https://user-images.githubusercontent.com/55841/60622834-879e1f00-9de1-11e9-9a9e-bae5ec0b3728.png' }, { include: [ pageDetect.isEditingFile, pageDetect.isSingleFile ], init });