import React from 'dom-chef'; import select from 'select-dom'; import onetime from 'onetime'; import elementReady from 'element-ready'; import * as pageDetect from 'github-url-detection'; import features from '.'; import {observeOneMutation} from '../helpers/simplified-element-observer'; async function getProjectsTab(): Promise { return elementReady([ '[data-hotkey="g b"]', // In organizations and repos '[aria-label="User profile"] [href$="?tab=projects"]' // In user profiles ].join()); } // We can't detect whether the user can create projects on a repo, so this link is potentially a 404 async function addNewProjectLink(): Promise { if (!await getProjectsTab()) { return false; } // URLs patterns: // https://github.com/orgs/USER/projects/new // https://github.com/USER/REPO/projects/new const path = location.pathname.split('/', 3); const base = path.length > 2 ? path.join('/') : '/orgs' + path.join('/'); select('.Header [href="/new"]')!.parentElement!.append( New project ); } export default async function getTabCount(tab: Element): Promise { const counter = select('.Counter, .num', tab); if (!counter) { // GitHub might have already dropped the counter, which means it's 0 return 0; } if (!counter.firstChild) { // It's still loading await observeOneMutation(tab); } return Number(counter.textContent); } async function removeProjectsTab(): Promise { const projectsTab = await getProjectsTab(); if ( !projectsTab || // Projects disabled 🎉 projectsTab.matches('.selected') || // User is on Projects tab 👀 await getTabCount(projectsTab) > 0 // There are open projects ) { return false; } projectsTab.remove(); } void features.add(__filebasename, { include: [ pageDetect.isRepo, pageDetect.isUserProfile, pageDetect.isOrganizationProfile ], exclude: [ // Repo/Organization owners should see the tab. If they don't need it, they should disable Projects altogether pageDetect.canUserEditRepo, pageDetect.canUserEditOrganization ], awaitDomReady: false, init: removeProjectsTab }, { include: [ pageDetect.isRepo, pageDetect.isOrganizationProfile ], awaitDomReady: false, init: onetime(addNewProjectLink) });