From 525833005648b95711395f2fc98755d19c0f747f Mon Sep 17 00:00:00 2001 From: Yuri Sizov Date: Fri, 3 Sep 2021 23:50:44 +0300 Subject: [PATCH] Add individual reviewer reports --- compose-db.js | 25 ++++ .../index/components/prs/PullRequestList.js | 12 +- src/paths/index/components/teams/TeamItem.js | 1 + src/paths/index/components/teams/TeamList.js | 125 +++++++++++++++--- src/paths/index/entry.js | 71 +++++++--- 5 files changed, 191 insertions(+), 43 deletions(-) diff --git a/compose-db.js b/compose-db.js index 84e3a68..87dfec0 100644 --- a/compose-db.js +++ b/compose-db.js @@ -3,6 +3,7 @@ const path = require('path'); const fetch = require('node-fetch'); const teams = {}; +const reviewers = {}; const authors = {}; const pulls = []; let page_count = 1; @@ -62,6 +63,7 @@ function processPulls(pullsRaw) { "milestone": null, "teams": [], + "reviewers": [], }; // Compose and link author information. @@ -152,6 +154,28 @@ function processPulls(pullsRaw) { pr.teams.push(team.id); } + // Add individual reviewers, if available + if (item.requested_reviewers.length > 0) { + item.requested_reviewers.forEach((reviewerItem) => { + const reviewer = { + "id": reviewerItem.id, + "name": reviewerItem.login, + "avatar": reviewerItem.avatar_url, + "slug": reviewerItem.login, + "pull_count": 0, + }; + + // Store the reviewer if it hasn't been stored before. + if (typeof reviewers[reviewer.id] == "undefined") { + reviewers[reviewer.id] = reviewer; + } + reviewers[reviewer.id].pull_count++; + + // Reference the reviewer. + pr.reviewers.push(reviewer.id); + }); + } + pulls.push(pr); }); } @@ -172,6 +196,7 @@ async function main() { const output = { "generated_at": Date.now(), "teams": teams, + "reviewers": reviewers, "authors": authors, "pulls": pulls, }; diff --git a/src/paths/index/components/prs/PullRequestList.js b/src/paths/index/components/prs/PullRequestList.js index 34d12dd..a19af6e 100644 --- a/src/paths/index/components/prs/PullRequestList.js +++ b/src/paths/index/components/prs/PullRequestList.js @@ -113,7 +113,8 @@ export default class PullRequestList extends LitElement { @property({ type: Array }) pulls = []; @property({ type: Object }) teams = {}; - @property( { type: Number }) selected_team = -1; + @property( { type: Number }) selected_group = -1; + @property({ type: Boolean }) selected_is_person = false; @property({ type: Object }) authors = {}; constructor() { @@ -270,7 +271,14 @@ export default class PullRequestList extends LitElement { ${pulls.map((item) => { const other_teams = []; item.teams.forEach((teamId) => { - if (teamId !== this.selected_team) { + if (teamId === -1) { + return; // continue + } + + if ( + this.selected_is_person + || (!this.selected_is_person && teamId !== this.selected_group) + ) { other_teams.push( this.teams[teamId].name ); diff --git a/src/paths/index/components/teams/TeamItem.js b/src/paths/index/components/teams/TeamItem.js index 06ffe0e..ee4fc2a 100644 --- a/src/paths/index/components/teams/TeamItem.js +++ b/src/paths/index/components/teams/TeamItem.js @@ -42,6 +42,7 @@ export default class TeamItem extends LitElement { :host .team-icon { background-size: cover; + border-radius: 2px; display: inline-block; width: 16px; height: 16px; diff --git a/src/paths/index/components/teams/TeamList.js b/src/paths/index/components/teams/TeamList.js index 0a18ca1..bd16fbb 100644 --- a/src/paths/index/components/teams/TeamList.js +++ b/src/paths/index/components/teams/TeamList.js @@ -10,11 +10,13 @@ export default class TeamList extends LitElement { :host { --teams-background-color: #fcfcfa; --teams-border-color: #515c6c; + --section-active-border-color: #397adf; } @media (prefers-color-scheme: dark) { :host { --teams-background-color: #0d1117; --teams-border-color: #515c6c; + --section-active-border-color: #397adf; } } @@ -29,44 +31,125 @@ export default class TeamList extends LitElement { min-height: 216px; } - :host .team-list h4 { - margin: 0 0 12px 0; + :host .team-list-switcher { + display: flex; + flex-direction: row; + justify-content: center; + } + :host .team-list-title { + cursor: pointer; + margin: 0 10px 12px 10px; + } + :host .team-list-title--active { + border-bottom: 3px solid var(--section-active-border-color); + } + + :host .team-list-section { + display: none; + } + :host .team-list-section--active { + display: block; } `; } @property({ type: Array }) teams = []; - @property({ type: Number }) selected_team = -1; + @property({ type: Array }) reviewers = []; + @property({ type: Number }) selected = -1; + @property({ type: Boolean }) selected_is_person = false; - onTabClicked(tabId, tabSlug, event) { + constructor() { + super(); + + this._currentSection = "teams"; + } + + onSwitcherClicked(switchTo, event) { + this._currentSection = switchTo; + this.requestUpdate(); + } + + onTabClicked(tabId, tabSlug, isPerson, event) { this.dispatchEvent(greports.util.createEvent("tabclick", { "tabId": tabId, + "isPerson": isPerson, })); greports.util.setHistoryHash(tabSlug); } + update(changedProperties) { + if (changedProperties.has("selected_is_person")) { + this._currentSection = (this.selected_is_person ? "reviewers" : "teams"); + } + + super.update(changedProperties); + } + render() { + const teamsClassList = [ "team-list-section", "team-list-section--teams" ]; + if (this._currentSection === "teams") { + teamsClassList.push("team-list-section--active"); + } + const reviewersClassList = [ "team-list-section", "team-list-section--reviewers" ]; + if (this._currentSection === "reviewers") { + reviewersClassList.push("team-list-section--active"); + } + return html`
-

Teams:

+
+

+ Teams +

+

+ Reviewers +

+
- ${(this.teams.length > 0) ? - this.teams.map((item) => { - return html` - - `; - }) : html` - Loading... - ` - } +
+ ${(this.teams.length > 0) ? + this.teams.map((item) => { + return html` + + `; + }) : html` + There are no teams + ` + } +
+ +
+ ${(this.reviewers.length > 0) ? + this.reviewers.map((item) => { + return html` + + `; + }) : html` + There are no reviewers + ` + } +
`; } diff --git a/src/paths/index/entry.js b/src/paths/index/entry.js index d7abb1c..60f7712 100644 --- a/src/paths/index/entry.js +++ b/src/paths/index/entry.js @@ -38,7 +38,10 @@ export default class EntryComponent extends LitElement { this._teams = {}; this._orderedTeams = []; - this._selectedTeam = -1; + this._reviewers = {}; + this._orderedReviewers = []; + this._selectedGroup = -1; + this._selectedIsPerson = false; this._authors = {}; this._pulls = []; @@ -61,6 +64,7 @@ export default class EntryComponent extends LitElement { if (data) { this._generatedAt = data.generated_at; this._teams = data.teams; + this._reviewers = data.reviewers; this._authors = data.authors; this._pulls = data.pulls; @@ -74,27 +78,47 @@ export default class EntryComponent extends LitElement { return 0; }); - // Try to select the team that was passed in the URL. - let hasPresetTeam = false; + this._orderedReviewers = Object.values(this._reviewers); + this._orderedReviewers.sort((a, b) => { + if (a.name > b.name) return 1; + if (a.name < b.name) return -1; + return 0; + }); + + // Try to select the team or the reviewer that was passed in the URL. + let hasPresetGroup = false; const requested_slug = greports.util.getHistoryHash(); if (requested_slug !== "") { for (let i = 0; i < this._orderedTeams.length; i++) { const team = this._orderedTeams[i]; if (team.slug === requested_slug) { - this._selectedTeam = team.id; - hasPresetTeam = true; + this._selectedGroup = team.id; + this._selectedIsPerson = false; + hasPresetGroup = true; break; } } + + if (!hasPresetGroup) { + for (let i = 0; i < this._orderedReviewers.length; i++) { + const reviewer = this._orderedReviewers[i]; + if (reviewer.slug === requested_slug) { + this._selectedGroup = reviewer.id; + this._selectedIsPerson = true; + hasPresetGroup = true; + break; + } + } + } } - // If no team was passed in the URL, or that team is not available, use the first one. - if (!hasPresetTeam) { + // If no team/reviewer was passed in the URL, or that team/reviewer is not available, use the first team. + if (!hasPresetGroup) { if (this._orderedTeams.length) { - this._selectedTeam = this._orderedTeams[0].id; + this._selectedGroup = this._orderedTeams[0].id; greports.util.setHistoryHash(this._orderedTeams[0].slug); } else { - this._selectedTeam = -1; + this._selectedGroup = -1; greports.util.setHistoryHash(""); } } @@ -102,7 +126,10 @@ export default class EntryComponent extends LitElement { this._generatedAt = null; this._teams = {}; this._orderedTeams = []; - this._selectedTeam = -1; + this._reviewers = {}; + this._orderedReviewers = []; + this._selectedGroup = -1; + this._selectedIsPerson = false; this._authors = {}; this._pulls = []; } @@ -111,21 +138,22 @@ export default class EntryComponent extends LitElement { } onTabClicked(event) { - this._selectedTeam = event.detail.tabId; + this._selectedGroup = event.detail.tabId; + this._selectedIsPerson = event.detail.isPerson; this.requestUpdate(); - } - onSortClicked(sortOrder, event) { - this._sortBy = sortOrder; - this.requestUpdate(); + window.scrollTo(0, 0); } render(){ let pulls = []; this._pulls.forEach((pull) => { - if (pull.teams.includes(this._selectedTeam)) { - pulls.push(pull); - } + if (!this._selectedIsPerson && pull.teams.includes(this._selectedGroup)) { + pulls.push(pull); + } + if (this._selectedIsPerson && pull.reviewers.includes(this._selectedGroup)) { + pulls.push(pull); + } }); return html` @@ -136,14 +164,17 @@ export default class EntryComponent extends LitElement {