ts: Convert portico/team.js to TypeScript.

This commit converts "portico/team.js" to TypeScript as well
as adds the required type definitions.

Some values were extracted into variables for type-checking.
This commit is contained in:
sbansal1999 2023-03-21 13:29:04 +05:30 committed by Tim Abbott
parent cc6661f777
commit a8b5167f89
1 changed files with 52 additions and 20 deletions

View File

@ -1,7 +1,26 @@
import $ from "jquery";
import _ from "lodash";
const repo_name_to_tab_name = {
// The list of repository names is duplicated here in order to provide
// a clear type for Contributor objects.
//
// TODO: We can avoid this if we introduce a `contributions` object
// referenced from Contributor, rather than having repository names be
// direct keys in the namespace that also has `email`.
const all_repository_names = [
"zulip",
"zulip-desktop",
"zulip-mobile",
"python-zulip-api",
"zulip-js",
"zulipbot",
"zulip-terminal",
"zulip-ios-legacy",
"zulip-android",
] as const;
type RepositoryName = (typeof all_repository_names)[number];
const repo_name_to_tab_name: Record<RepositoryName, string> = {
zulip: "server",
"zulip-desktop": "desktop",
"zulip-mobile": "mobile",
@ -13,26 +32,36 @@ const repo_name_to_tab_name = {
"zulip-android": "",
};
export type Contributor = {
avatar: string;
email?: string;
github_username?: string;
name: string;
} & {
[K in RepositoryName]?: number;
};
// Remember the loaded repositories so that HTML is not redundantly edited
// if a user leaves and then revisits the same tab.
const loaded_repos = [];
const loaded_repos: string[] = [];
function calculate_total_commits(contributor) {
function calculate_total_commits(contributor: Contributor): number {
let commits = 0;
for (const repo_name of Object.keys(repo_name_to_tab_name)) {
for (const repo_name of all_repository_names) {
commits += contributor[repo_name] || 0;
}
return commits;
}
function get_profile_url(contributor, tab_name) {
const commit_email_linked_to_github = "github_username" in contributor;
if (commit_email_linked_to_github) {
return "https://github.com/" + contributor.github_username;
function get_profile_url(contributor: Contributor, tab_name?: string): string | undefined {
if (contributor.github_username) {
return `https://github.com/${contributor.github_username}`;
}
const email = contributor.email;
if (!email) {
return undefined;
}
if (tab_name) {
return `https://github.com/zulip/${tab_name}/commits?author=${email}`;
@ -47,21 +76,21 @@ function get_profile_url(contributor, tab_name) {
return undefined;
}
function get_display_name(contributor) {
function get_display_name(contributor: Contributor): string {
if (contributor.github_username) {
return "@" + contributor.github_username;
}
return contributor.name;
}
function exclude_bot_contributors(contributor) {
function exclude_bot_contributors(contributor: Contributor): boolean {
return contributor.github_username !== "dependabot[bot]";
}
// TODO (for v2 of /team/ contributors):
// - Make tab header responsive.
// - Display full name instead of GitHub username.
export default function render_tabs(contributors) {
export default function render_tabs(contributors: Contributor[]): void {
const template = _.template($("#contributors-template").html());
const count_template = _.template($("#count-template").html());
const total_count_template = _.template($("#total-count-template").html());
@ -93,7 +122,7 @@ export default function render_tabs(contributors) {
}),
);
for (const repo_name of Object.keys(repo_name_to_tab_name)) {
for (const repo_name of all_repository_names) {
const tab_name = repo_name_to_tab_name[repo_name];
if (!tab_name) {
continue;
@ -103,11 +132,13 @@ export default function render_tabs(contributors) {
$(`#${CSS.escape(tab_name)}`).on("click", () => {
if (!loaded_repos.includes(repo_name)) {
const filtered_by_repo = contributors_list.filter((c) => c[repo_name]);
const filtered_by_repo = contributors_list.filter((c) => c[repo_name] || 0);
const html = filtered_by_repo
.sort((a, b) =>
a[repo_name] < b[repo_name] ? 1 : a[repo_name] > b[repo_name] ? -1 : 0,
)
.sort((a, b) => {
const a_commits = a[repo_name] || 0;
const b_commits = b[repo_name] || 0;
return a_commits < b_commits ? 1 : a_commits > b_commits ? -1 : 0;
})
.map((c) =>
template({
name: get_display_name(c),
@ -121,9 +152,10 @@ export default function render_tabs(contributors) {
$(`#tab-${CSS.escape(tab_name)} .contributors-grid`).html(html);
const contributor_count = filtered_by_repo.length;
const hundred_plus_contributor_count = filtered_by_repo.filter(
(c) => c[repo_name] >= 100,
).length;
const hundred_plus_contributor_count = filtered_by_repo.filter((c) => {
const commits = c[repo_name] || 0;
return commits >= 100;
}).length;
const repo_url = `https://github.com/zulip/${repo_name}`;
$(`#tab-${CSS.escape(tab_name)}`).prepend(
count_template({