Refactor pull request items for reusability

This commit is contained in:
Yuri Sizov
2023-03-23 16:08:25 +01:00
parent 8cf623ad29
commit 00dd47a740
5 changed files with 204 additions and 110 deletions

View File

@@ -55,6 +55,7 @@ export default class ChangesList extends LitElement {
@property({ type: Object }) commits = {};
@property({ type: Object }) pulls = {};
@property({ type: String }) selectedRepository = "";
@property({ type: String }) selectedVersion = "";
@property({ type: String }) selectedRelease = "";
@property({ type: Boolean, reflect: true }) loading = false;
@@ -239,7 +240,7 @@ export default class ChangesList extends LitElement {
const pull = item.pull;
return html`
<gr-pull-request
<gr-pull-item
.id="${pull.public_id}"
.title="${pull.title}"
.authors="${item.authors}"
@@ -247,6 +248,7 @@ export default class ChangesList extends LitElement {
.created_at="${pull.created_at}"
.updated_at="${pull.updated_at}"
.labels="${pull.labels}"
.repository="${this.selectedRepository}"
/>
`;
})}

View File

@@ -1,19 +1,22 @@
import { LitElement, html, css, customElement, property } from 'lit-element';
@customElement('gr-pull-request')
import ChangeItemAuthor from './base/ChangeItemAuthor';
import ChangeItemLabel from './base/ChangeItemLabel';
@customElement('gr-pull-item')
export default class PullRequestItem extends LitElement {
static get styles() {
return css`
/** Colors and variables **/
:host {
--pr-border-color: #fcfcfa;
--item-border-color: #fcfcfa;
--star-font-color: #ffcc31;
--ghost-font-color: #738b99;
}
@media (prefers-color-scheme: dark) {
:host {
--pr-border-color: #0d1117;
--item-border-color: #0d1117;
--star-font-color: #e0c537;
--ghost-font-color: #495d68;
}
@@ -21,7 +24,7 @@ export default class PullRequestItem extends LitElement {
/** Component styling **/
:host {
border-bottom: 3px solid var(--pr-border-color);
border-bottom: 3px solid var(--item-border-color);
display: block;
padding: 14px 12px 20px 12px;
}
@@ -34,26 +37,19 @@ export default class PullRequestItem extends LitElement {
color: var(--link-font-color-hover);
}
:host .pr-title {
:host .item-title {
display: inline-block;
font-size: 20px;
margin-top: 6px;
margin-bottom: 12px;
}
:host .pr-title-name {
:host .item-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 {
:host .item-meta {
color: var(--dimmed-font-color);
display: flex;
flex-direction: row;
@@ -62,84 +58,37 @@ export default class PullRequestItem extends LitElement {
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 {
:host .item-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;
:host .item-authors {
}
@media only screen and (max-width: 900px) {
:host {
padding: 14px 0 20px 0;
}
:host .pr-meta {
:host .item-meta {
flex-wrap: wrap;
}
:host .pr-labels {
width: 100%;
justify-content: space-between;
}
}
`;
}
@property({ type: String }) id = '';
@property({ type: String, reflect: true }) id = '';
@property({ type: String }) title = '';
@property({ type: Array }) authors = [];
@property({ type: String, reflect: true }) url = '';
@property({ type: String }) url = '';
@property({ type: String }) created_at = '';
@property({ type: String }) updated_at = '';
@property({ type: Array }) labels = [];
@property({ type: String }) repository = '';
render(){
// Some labels aren't useful in this context; hide them.
let filteredLabels = [];
@@ -152,33 +101,24 @@ export default class PullRequestItem extends LitElement {
});
return html`
<div class="pr-container ${(this.draft ? "pr-container--draft" : "")}">
<div class="pr-title">
<span class="pr-title-name">${this.title}</span>
<div class="item-container">
<div class="item-title">
<span class="item-title-name">${this.title}</span>
</div>
<div class="pr-meta">
<div class="pr-labels">
<div class="item-meta">
<div class="item-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>
<gr-change-label
.name="${item.name}"
.color="${item.color}"
></gr-change-label>
`;
})}
</div>
<div class="pr-people">
<div class="item-people">
<div>
<span>submitted as </span>
<a
@@ -189,32 +129,19 @@ export default class PullRequestItem extends LitElement {
GH-${this.id}
</a>
</div>
<div class="pr-author">
<div class="item-authors">
<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}')"
>
<gr-change-author
.id="${author.id}"
.user="${author.user}"
.avatar="${author.avatar}"
.is_hot="${author.pull_count > 12}"
</span>
${author.user}
</a>
.url="${`https://github.com/${this.repository}/pulls/${author.user}`}"
.url_title="${`Open all PRs by ${author.user}`}"
></gr-change-author>
`;
})}
</div>

View File

@@ -0,0 +1,96 @@
import { LitElement, html, css, customElement, property } from 'lit-element';
@customElement('gr-change-author')
export default class ChangeItemAuthor extends LitElement {
static get styles() {
return css`
/** Colors and variables **/
:host {
--star-font-color: #ffcc31;
--ghost-font-color: #738b99;
}
@media (prefers-color-scheme: dark) {
:host {
--star-font-color: #e0c537;
--ghost-font-color: #495d68;
}
}
/** Component styling **/
:host {
}
:host a {
color: var(--link-font-color);
text-decoration: none;
}
:host a:hover {
color: var(--link-font-color-hover);
}
:host .item-author {
display: inline-flex;
flex-direction: row;
gap: 6px;
align-items: center;
vertical-align: bottom;
padding-left: 6px;
}
:host .item-author--hot:before {
content: "★";
color: var(--star-font-color);
}
:host .item-author--ghost {
color: var(--ghost-font-color);
font-weight: 600;
}
:host .item-author-avatar {
background-size: cover;
border-radius: 2px;
display: inline-block;
width: 16px;
height: 16px;
}
@media only screen and (max-width: 900px) {
:host {
}
}
`;
}
@property({ type: String }) id = '';
@property({ type: String, reflect: true }) user = '';
@property({ type: String }) avatar = '';
@property({ type: Boolean }) is_hot = false;
@property({ type: String }) url = '';
@property({ type: String }) url_title = '';
render(){
const authorClassList = [ "item-author" ];
if (this.is_hot) {
authorClassList.push("item-author--hot");
}
if (this.id === "") {
authorClassList.push("item-author--ghost");
}
return html`
<a
class="${authorClassList.join(" ")}"
href="${this.url}"
target="_blank"
title="${this.url_title}"
>
<span
class="item-author-avatar"
style="background-image: url('${this.avatar}')"
></span>
${this.user}
</a>
`;
}
}

View File

@@ -0,0 +1,68 @@
import { LitElement, html, css, customElement, property } from 'lit-element';
@customElement('gr-change-label')
export default class ChangeItemLabel extends LitElement {
static get styles() {
return css`
/** Colors and variables **/
:host {
}
@media (prefers-color-scheme: dark) {
:host {
}
}
/** Component styling **/
:host {
}
:host .item-labels {
display: flex;
flex-flow: row wrap;
padding: 4px 0;
}
:host .item-label {
padding-right: 8px;
}
:host .item-label-dot {
border-radius: 4px;
box-shadow: rgb(0 0 0 / 28%) 0 0 3px 0;
display: inline-block;
width: 8px;
height: 8px;
}
:host .item-label-name {
padding-left: 3px;
}
@media only screen and (max-width: 900px) {
:host .item-labels {
width: 100%;
justify-content: space-between;
}
}
`;
}
@property({ type: String, reflect: true }) name = '';
@property({ type: String }) color = '';
render(){
return html`
<span class="item-label">
<span
class="item-label-dot"
style="background-color: ${this.color}"
></span>
<span class="item-label-name">
${this.name}
</span>
</span>
`;
}
}

View File

@@ -226,6 +226,7 @@ export default class EntryComponent extends LitElement {
.commits="${commits}"
.pulls="${pulls}"
.selectedRepository="${this._selectedRepository}"
.selectedVersion="${this._selectedVersion}"
.selectedRelease="${this._selectedRelease}"
?loading="${loadingVersions.indexOf(this._selectedVersion) >= 0}"