mirror of
https://github.com/godotengine/godot-interactive-changelog.git
synced 2026-01-04 02:10:03 +03:00
Start displaying the list of changes (PRs only so far)
This commit is contained in:
196
src/paths/index/components/changes/ChangesList.js
Normal file
196
src/paths/index/components/changes/ChangesList.js
Normal file
@@ -0,0 +1,196 @@
|
||||
import { LitElement, html, css, customElement, property } from 'lit-element';
|
||||
|
||||
import PullRequestItem from "./PullRequestItem";
|
||||
|
||||
@customElement('gr-changes-list')
|
||||
export default class ChangesList extends LitElement {
|
||||
static get styles() {
|
||||
return css`
|
||||
/** Colors and variables **/
|
||||
:host {
|
||||
--changes-background-color: #e5edf8;
|
||||
--changes-toolbar-color: #9bbaed;
|
||||
--changes-toolbar-accent-color: #5a6f90;
|
||||
}
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:host {
|
||||
--changes-background-color: #191d23;
|
||||
--changes-toolbar-color: #222c3d;
|
||||
--changes-toolbar-accent-color: #566783;
|
||||
}
|
||||
}
|
||||
|
||||
/** Component styling **/
|
||||
:host {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
:host .version-changes-empty {
|
||||
color: var(--g-font-color);
|
||||
display: inline-block;
|
||||
font-size: 20px;
|
||||
line-height: 24px;
|
||||
margin-top: 6px;
|
||||
margin-bottom: 12px;
|
||||
padding: 14px 12px;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
:host .version-changes {
|
||||
background-color: var(--changes-background-color);
|
||||
border-radius: 0 4px 4px 0;
|
||||
padding: 8px 12px;
|
||||
max-width: 760px;
|
||||
}
|
||||
|
||||
:host .version-changes-toolbar {
|
||||
background: var(--changes-toolbar-color);
|
||||
border-radius: 4px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 16px;
|
||||
padding: 10px 14px;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
:host .changes-count {
|
||||
font-size: 15px;
|
||||
}
|
||||
:host .changes-count strong {
|
||||
font-size: 18px;
|
||||
}
|
||||
:host .changes-count-label {
|
||||
color: var(--dimmed-font-color);
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 900px) {
|
||||
:host .version-changes {
|
||||
padding: 8px;
|
||||
max-width: 95%;
|
||||
margin: 0px auto;
|
||||
}
|
||||
|
||||
:host .changes-count {
|
||||
font-size: 17px;
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
}
|
||||
:host .changes-count strong {
|
||||
font-size: 20px;
|
||||
}
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
||||
@property({ type: Object }) version = {};
|
||||
@property({ type: Array }) log = [];
|
||||
@property({ type: Object }) authors = {};
|
||||
@property({ type: Object }) commits = {};
|
||||
@property({ type: Object }) pulls = {};
|
||||
|
||||
@property({ type: String }) selectedVersion = "";
|
||||
@property({ type: String }) selectedRelease = "";
|
||||
@property({ type: Boolean, reflect: true }) loading = false;
|
||||
|
||||
render(){
|
||||
if (this.selectedVersion === "") {
|
||||
return html``;
|
||||
}
|
||||
if (this.loading) {
|
||||
return html`
|
||||
<span class="version-changes-empty">Loading changes...</span>
|
||||
`
|
||||
}
|
||||
|
||||
let filtered_commits = [];
|
||||
let filtered_pulls = [];
|
||||
|
||||
let commit_log = this.version.commit_log;
|
||||
if (this.selectedRelease !== "") {
|
||||
for (let release of this.version.releases) {
|
||||
if (release.name === this.selectedRelease) {
|
||||
commit_log = release.commit_log;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
commit_log.forEach((commitHash) => {
|
||||
if (typeof this.commits[commitHash] === "undefined") {
|
||||
return; // This is not good.
|
||||
}
|
||||
|
||||
let commit = this.commits[commitHash];
|
||||
filtered_commits.push(commit);
|
||||
|
||||
if (commit.is_cherrypick && typeof this.commits[commit.cherrypick_hash] !== "undefined") {
|
||||
commit = this.commits[commit.cherrypick_hash];
|
||||
}
|
||||
|
||||
if (commit.pull !== "" && typeof this.pulls[commit.pull] !== "undefined") {
|
||||
const pull = this.pulls[commit.pull];
|
||||
|
||||
if (filtered_pulls.indexOf(pull) < 0) {
|
||||
filtered_pulls.push(this.pulls[commit.pull]);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return html`
|
||||
<div class="version-changes">
|
||||
<div class="version-changes-toolbar">
|
||||
<div class="changes-count">
|
||||
<strong>${filtered_commits.length}</strong>
|
||||
<span class="changes-count-label"> ${(filtered_commits.length === 1 ? "commit": "commits")}</span>
|
||||
</div>
|
||||
<div class="changes-count">
|
||||
<strong>${filtered_pulls.length}</strong>
|
||||
<span class="changes-count-label"> ${(filtered_pulls.length === 1 ? "PR": "PRs")}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
${(filtered_pulls.length === 0 ? html`
|
||||
<span class="version-changes-empty">This version contains no new changes.</span>
|
||||
` : null)}
|
||||
|
||||
${filtered_pulls.map((item) => {
|
||||
let authorIds = [];
|
||||
item.commits.forEach((commitHash) => {
|
||||
if (typeof this.commits[commitHash] === "undefined") {
|
||||
return;
|
||||
}
|
||||
const commit = this.commits[commitHash];
|
||||
commit.authored_by.forEach((authoredBy) => {
|
||||
if (authorIds.indexOf(authoredBy) < 0) {
|
||||
authorIds.push(authoredBy);
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
if (authorIds.indexOf(item.authored_by) < 0) {
|
||||
authorIds.push(item.authored_by);
|
||||
}
|
||||
|
||||
let authors = [];
|
||||
authorIds.forEach((authoredBy) => {
|
||||
if (typeof this.authors[authoredBy] !== "undefined") {
|
||||
authors.push(this.authors[authoredBy]);
|
||||
}
|
||||
});
|
||||
|
||||
return html`
|
||||
<gr-pull-request
|
||||
.id="${item.public_id}"
|
||||
.title="${item.title}"
|
||||
.authors="${authors}"
|
||||
.url="${item.url}"
|
||||
.created_at="${item.created_at}"
|
||||
.updated_at="${item.updated_at}"
|
||||
.labels="${item.labels}"
|
||||
/>
|
||||
`;
|
||||
})}
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
}
|
||||
226
src/paths/index/components/changes/PullRequestItem.js
Normal file
226
src/paths/index/components/changes/PullRequestItem.js
Normal file
@@ -0,0 +1,226 @@
|
||||
import { LitElement, html, css, customElement, property } from 'lit-element';
|
||||
|
||||
@customElement('gr-pull-request')
|
||||
export default class PullRequestItem extends LitElement {
|
||||
static get styles() {
|
||||
return css`
|
||||
/** Colors and variables **/
|
||||
:host {
|
||||
--pr-border-color: #fcfcfa;
|
||||
--star-font-color: #ffcc31;
|
||||
--ghost-font-color: #738b99;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:host {
|
||||
--pr-border-color: #0d1117;
|
||||
--star-font-color: #e0c537;
|
||||
--ghost-font-color: #495d68;
|
||||
}
|
||||
}
|
||||
|
||||
/** Component styling **/
|
||||
:host {
|
||||
border-bottom: 3px solid var(--pr-border-color);
|
||||
display: block;
|
||||
padding: 14px 12px 20px 12px;
|
||||
}
|
||||
|
||||
:host a {
|
||||
color: var(--link-font-color);
|
||||
text-decoration: none;
|
||||
}
|
||||
:host a:hover {
|
||||
color: var(--link-font-color-hover);
|
||||
}
|
||||
|
||||
:host .pr-title {
|
||||
display: inline-block;
|
||||
font-size: 20px;
|
||||
margin-top: 6px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
:host .pr-title-name {
|
||||
color: var(--g-font-color);
|
||||
line-height: 24px;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
:host .pr-container--draft .pr-title {
|
||||
filter: saturate(0.4);
|
||||
}
|
||||
:host .pr-container--draft .pr-title-name {
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
:host .pr-meta {
|
||||
color: var(--dimmed-font-color);
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
gap: 16px;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
:host .pr-labels {
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
padding: 4px 0;
|
||||
}
|
||||
|
||||
:host .pr-label {
|
||||
padding-right: 8px;
|
||||
}
|
||||
:host .pr-label-dot {
|
||||
border-radius: 4px;
|
||||
box-shadow: rgb(0 0 0 / 28%) 0 0 3px 0;
|
||||
display: inline-block;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
}
|
||||
:host .pr-label-name {
|
||||
padding-left: 3px;
|
||||
}
|
||||
|
||||
:host .pr-people {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 2px;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
:host .pr-author {
|
||||
|
||||
}
|
||||
:host .pr-author-value {
|
||||
display: inline-flex;
|
||||
flex-direction: row;
|
||||
gap: 6px;
|
||||
align-items: center;
|
||||
vertical-align: bottom;
|
||||
padding-left: 6px;
|
||||
}
|
||||
:host .pr-author-value--hot:before {
|
||||
content: "★";
|
||||
color: var(--star-font-color);
|
||||
}
|
||||
:host .pr-author-value--ghost {
|
||||
color: var(--ghost-font-color);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
:host .pr-author-avatar {
|
||||
background-size: cover;
|
||||
border-radius: 2px;
|
||||
display: inline-block;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 900px) {
|
||||
:host {
|
||||
padding: 14px 0 20px 0;
|
||||
}
|
||||
:host .pr-meta {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
:host .pr-labels {
|
||||
width: 100%;
|
||||
justify-content: space-between;
|
||||
}
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
||||
@property({ type: String }) id = '';
|
||||
@property({ type: String }) title = '';
|
||||
@property({ type: Array }) authors = [];
|
||||
@property({ type: String, reflect: true }) url = '';
|
||||
@property({ type: String }) created_at = '';
|
||||
@property({ type: String }) updated_at = '';
|
||||
@property({ type: Array }) labels = [];
|
||||
|
||||
render(){
|
||||
// Some labels aren't useful in this context; hide them.
|
||||
let filteredLabels = [];
|
||||
this.labels.forEach((item) => {
|
||||
if (item.name.startsWith("cherrypick:")) {
|
||||
return;
|
||||
}
|
||||
|
||||
filteredLabels.push(item);
|
||||
});
|
||||
|
||||
return html`
|
||||
<div class="pr-container ${(this.draft ? "pr-container--draft" : "")}">
|
||||
<div class="pr-title">
|
||||
<span class="pr-title-name">${this.title}</span>
|
||||
</div>
|
||||
|
||||
<div class="pr-meta">
|
||||
<div class="pr-labels">
|
||||
${filteredLabels.map((item) => {
|
||||
return html`
|
||||
<span
|
||||
class="pr-label"
|
||||
>
|
||||
<span
|
||||
class="pr-label-dot"
|
||||
style="background-color: ${item.color}"
|
||||
></span>
|
||||
<span
|
||||
class="pr-label-name"
|
||||
>
|
||||
${item.name}
|
||||
</span>
|
||||
</span>
|
||||
`;
|
||||
})}
|
||||
</div>
|
||||
|
||||
<div class="pr-people">
|
||||
<div>
|
||||
<span>submitted as </span>
|
||||
<a
|
||||
href="${this.url}"
|
||||
target="_blank"
|
||||
title="Open PR #${this.id} on GitHub"
|
||||
>
|
||||
GH-${this.id}
|
||||
</a>
|
||||
</div>
|
||||
<div class="pr-author">
|
||||
<span>by </span>
|
||||
${this.authors.map((author) => {
|
||||
const authorClassList = [ "pr-author-value" ];
|
||||
if (author.pull_count > 12) {
|
||||
authorClassList.push("pr-author-value--hot");
|
||||
}
|
||||
if (author.id === "") {
|
||||
authorClassList.push("pr-author-value--ghost");
|
||||
}
|
||||
|
||||
return html`
|
||||
<a
|
||||
class="${authorClassList.join(" ")}"
|
||||
href="https://github.com/godotengine/godot/pulls/${author.user}"
|
||||
target="_blank"
|
||||
title="Open all PRs by ${author.user}"
|
||||
>
|
||||
<span
|
||||
class="pr-author-avatar"
|
||||
style="background-image: url('${author.avatar}')"
|
||||
>
|
||||
|
||||
</span>
|
||||
${author.user}
|
||||
</a>
|
||||
`;
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
}
|
||||
@@ -174,7 +174,10 @@ export default class VersionItem extends LitElement {
|
||||
${this.name}
|
||||
</span>
|
||||
|
||||
<span class="${countClassList.join(" ")}">
|
||||
<span
|
||||
class="${countClassList.join(" ")}"
|
||||
title="${this.loading ? "" : `${this.pull_count} changes since last release.`}"
|
||||
>
|
||||
${this.loading ? "" : this.pull_count}
|
||||
</span>
|
||||
|
||||
|
||||
@@ -162,7 +162,7 @@ export default class VersionList extends LitElement {
|
||||
<gr-version-item
|
||||
.name="${item.name}"
|
||||
.type="${"main"}"
|
||||
.pull_count="${item.pull_count}"
|
||||
.pull_count="${item.commit_log.length}"
|
||||
?active="${this.selectedVersion === item.name}"
|
||||
?expanded="${this.toggledVersions.includes(item.name)}"
|
||||
?loading="${this.loadingVersions.includes(item.name)}"
|
||||
@@ -178,7 +178,7 @@ export default class VersionList extends LitElement {
|
||||
<gr-version-item
|
||||
.name="${release.name}"
|
||||
.type="${"sub"}"
|
||||
.pull_count="${release.pull_count}"
|
||||
.pull_count="${release.commit_log.length}"
|
||||
?active="${this.selectedVersion === item.name && this.selectedRelease === release.name}"
|
||||
@click="${this._onItemClicked.bind(this, "sub", item.name, release.name)}"
|
||||
@iconclick="${this._onItemIconClicked.bind(this, "sub", item.name, release.name)}"
|
||||
|
||||
@@ -6,6 +6,7 @@ import IndexHeader from "./components/IndexHeader";
|
||||
import IndexDescription from "./components/IndexDescription";
|
||||
|
||||
import VersionList from "./components/versions/VersionList";
|
||||
import ChangesList from "./components/changes/ChangesList";
|
||||
|
||||
@customElement('entry-component')
|
||||
export default class EntryComponent extends LitElement {
|
||||
@@ -86,9 +87,9 @@ export default class EntryComponent extends LitElement {
|
||||
this._versions = data;
|
||||
|
||||
this._versions.forEach((version) => {
|
||||
version.pull_count = 0;
|
||||
version.commit_log = [];
|
||||
version.releases.forEach((release) => {
|
||||
release.pull_count = 0;
|
||||
release.commit_log = [];
|
||||
});
|
||||
});
|
||||
} else {
|
||||
@@ -108,20 +109,21 @@ export default class EntryComponent extends LitElement {
|
||||
this._loadingVersions.push(version.name);
|
||||
|
||||
const versionData = await greports.api.getVersionData(this._selectedRepository, version.name);
|
||||
versionData.config = version;
|
||||
this._versionData[version.name] = versionData;
|
||||
|
||||
// Calculate number of changes for the version, and each if its releases.
|
||||
const commitLog = versionData.log;
|
||||
const [...commitLog] = versionData.log;
|
||||
commitLog.reverse();
|
||||
|
||||
version.pull_count = commitLog.length;
|
||||
version.commit_log = commitLog;
|
||||
version.releases.forEach((release) => {
|
||||
release.pull_count = 0;
|
||||
release.commit_log = [];
|
||||
|
||||
let counting = false;
|
||||
commitLog.forEach((commitHash, index) => {
|
||||
if (counting) {
|
||||
release.pull_count += 1;
|
||||
release.commit_log.push(commitHash);
|
||||
}
|
||||
|
||||
// We need to check indices for some refs, because they are not written
|
||||
@@ -131,7 +133,7 @@ export default class EntryComponent extends LitElement {
|
||||
if (release.from_ref === version.from_ref && index === 0) {
|
||||
counting = true;
|
||||
// HACK: Exclude the lower end by default, but include for the first range.
|
||||
release.pull_count += 1;
|
||||
release.commit_log.push(commitHash);
|
||||
}
|
||||
else if (commitHash === release.from_ref) {
|
||||
counting = true;
|
||||
@@ -166,6 +168,22 @@ export default class EntryComponent extends LitElement {
|
||||
const [...versions] = this._versions;
|
||||
const [...loadingVersions] = this._loadingVersions;
|
||||
|
||||
let version = {};
|
||||
let commitLog = [];
|
||||
let authors = {};
|
||||
let commits = {};
|
||||
let pulls = {};
|
||||
|
||||
if (this._selectedVersion !== "" && typeof this._versionData[this._selectedVersion] !== "undefined") {
|
||||
const versionData = this._versionData[this._selectedVersion];
|
||||
|
||||
version = versionData.config;
|
||||
commitLog = versionData.log;
|
||||
authors = versionData.authors;
|
||||
commits = versionData.commits;
|
||||
pulls = versionData.pulls;
|
||||
}
|
||||
|
||||
return html`
|
||||
<page-content>
|
||||
<shared-nav></shared-nav>
|
||||
@@ -183,6 +201,20 @@ export default class EntryComponent extends LitElement {
|
||||
.selectedRelease="${this._selectedRelease}"
|
||||
@versionclick="${this._onVersionClicked}"
|
||||
></gr-version-list>
|
||||
|
||||
${(this._selectedVersion !== "" ? html`
|
||||
<gr-changes-list
|
||||
.version=${version}
|
||||
.log="${commitLog}"
|
||||
.authors="${authors}"
|
||||
.commits="${commits}"
|
||||
.pulls="${pulls}"
|
||||
|
||||
.selectedVersion="${this._selectedVersion}"
|
||||
.selectedRelease="${this._selectedRelease}"
|
||||
?loading="${loadingVersions.indexOf(this._selectedVersion) >= 0}"
|
||||
></gr-changes-list>
|
||||
` : null)}
|
||||
</div>
|
||||
`)}
|
||||
</page-content>
|
||||
|
||||
Reference in New Issue
Block a user