Skip to content

Commit

Permalink
offer theme (#1236)
Browse files Browse the repository at this point in the history
* move modules into assets

rm import
fix improper li nesting
break counts apparently

* create a reviews page

feel free to move around/rename

* Style tweaks

* Rename reviews to prs-needing-review

I can imagine wanting a "reviews" dashboard that displays broader
information in the future, e.g. things that have been reviewed.

* things we should really do

1. move selection to [data-attributes]
1. mark up with BEM

---------

Co-authored-by: Daniel Wagner-Hall <[email protected]>
  • Loading branch information
SallyMcGrath and illicitonion authored Dec 6, 2024
1 parent 307b094 commit af9f095
Show file tree
Hide file tree
Showing 9 changed files with 224 additions and 190 deletions.
5 changes: 5 additions & 0 deletions common-theme/assets/styles/states/bad.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
//use for failure/incorrect/negative

.is-bad {
background: var(--theme-color--bad);
}
5 changes: 5 additions & 0 deletions common-theme/assets/styles/states/problem.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
//use for warning alerts

.is-problem {
font-weight: bolder;
}
126 changes: 126 additions & 0 deletions org-cyf-itp/assets/custom-scripts/reviews/index.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
const awaitingReviewByAge = {};
const prsByModule = {};

// 400/700/900
function badness(name, count) {
if ((name === "old" || name == "this month") && count > 0) {
return 900;
}
if (name === "this week" && count > 20) {
return 900;
}
if (name === "this week" && count > 10) {
return 700;
}
return 400;
}

const ageToEmoji = {
"this week": "🟢",
"this month": "🟠",
old: "🔴",
};

function computeStatusClass(awaitingReview) {
const score = Math.max(
...Object.entries(awaitingReview).map(([name, count]) =>
badness(name, count)
)
);
if (score === 900) {
return "is-bad";
} else if (score === 700) {
return "is-medium";
} else {
return "is-good";
}
}

async function onLoad() {
for (const module of modules) {
awaitingReviewByAge[module] = {
"this week": 0,
"this month": 0,
old: 0,
};
prsByModule[module] = [];
}

for (const pr of (await fetchPrs()).filter(
(pr) => pr.status === "Needs Review"
)) {
awaitingReviewByAge[pr.module][pr.updatedAge]++;
prsByModule[pr.module].push(pr);
}
for (const module of modules) {
prsByModule[module].sort((l, r) => {
if (l.updatedAge > r.updatedAge) {
return 1;
} else if (l.updatedAge < r.updatedAge) {
return -1;
} else {
return l.number - r.number;
}
});
}

document.querySelector("#pr-list").innerText = "";

for (const module of modules) {
const awaitingReview = awaitingReviewByAge[module];
const totalPending = Object.values(awaitingReview).reduce(
(acc, cur) => acc + cur,
0
);

const overviewCard = document
.querySelector("template.overview-card")
.content.cloneNode(true);
overviewCard.querySelector(
".module"
).innerText = `${module} (${totalPending})`;
for (const [age, count] of Object.entries(awaitingReview)) {
const bucket = overviewCard.querySelector(
`.age-bucket.${age.replaceAll(" ", "-")} + .count`
);
if (bucket) bucket.innerText = count;
if (bucket && badness(age, count) === 900) {
bucket.classList.add("is-problem");
}
}
overviewCard
.querySelector(".overview-card")
.classList.add(computeStatusClass(awaitingReview));
document.querySelector("#overview").appendChild(overviewCard);

if (totalPending) {
const modulePrList = document
.querySelector("template.pr-list")
.content.cloneNode(true);
modulePrList.querySelector(
".module"
).innerText = `${module} (${totalPending})`;
for (const pr of prsByModule[module]) {
const prInList = document
.querySelector("template.pr-in-list")
.content.cloneNode(true);

prInList.querySelector(".emoji").innerText = ageToEmoji[pr.updatedAge];

const prLink = prInList.querySelector("a.pr-link");
prLink.href = pr.url;
prLink.innerText = `${pr.title}`;

const userLink = prInList.querySelector("a.user-link");
userLink.href = pr.userUrl;
userLink.innerText = `${pr.userName}`;

prInList.querySelector(".pr-number").innerText = pr.number;
modulePrList.querySelector("ul.pr-list").appendChild(prInList);
}
document.querySelector("#pr-list").appendChild(modulePrList);
}
}
}

onLoad();
26 changes: 26 additions & 0 deletions org-cyf-itp/assets/custom-theme/04-components/pr-overview.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
.c-pr-overview {
display: grid;
grid-template-columns: repeat(
auto-fit,
minmax(var(--theme-spacing--container-min), 1fr)
);
gap: var(--theme-spacing--2);
margin-bottom: var(--theme-spacing--4);

&__card {
box-shadow: var(--theme-box-shadow--slim);
padding: var(--theme-spacing--1);
display: grid;
gap: var(--theme-spacing--1);
}

&__age {
display: grid;
grid-template-columns: repeat(3, 1fr);
margin: auto 0 0;
}

&__bucket {
text-align: center;
}
}
8 changes: 8 additions & 0 deletions org-cyf-itp/content/prs-needing-review/_index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
+++
title="ITP PRs needing review"
layout="needs-review"
weight=2
emoji="🧑🏾‍🤝‍🧑🏾"
+++

### Modules in red have lots of PRs, or any old PRs needing review.
54 changes: 54 additions & 0 deletions org-cyf-itp/layouts/_default/needs-review.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
{{ define "main" }}
{{ partial "page-header.html" . }}
{{ with .Content }}
<section class="l-page__main c-copy">
{{ . }}
</section>
{{ end }}
<div id="overview" class="c-pr-overview"></div>

<div id="pr-list">Loading...</div>

<template class="overview-card">
<section class="c-pr-overview__card overview-card">
<h3 class="c-pr-overview__module e-heading__5 module"></h3>
<p class="c-pr-overview__description e-heading__6 ">
PRs waiting, time in <strong>days</strong>:
</p>

<dl class="c-pr-overview__age age-container">
<div>
<dt class="c-pr-overview__bucket age-bucket this-week">🟢 &lt;7</dt>
<dd class="c-pr-overview__count count"></dd>
</div>
<div>
<dt class="c-pr-overview__bucket age-bucket this-month">🟠 7-28</dt>
<dd class="c-pr-overview__count count"></dd>
</div>
<div>
<dt class="c-pr-overview__count age-bucket old">🔴 28+</dt>
<dd class="c-pr-overview__count count"></dd>
</div>
</dl>
<div class="c-pr-overview__values summary-values"></div>
</section>
</template>

<template class="pr-list">
<h2 class="e-heading__3 module"></h2>
<ul class="e-list pr-list"></ul>
</template>

<template class="pr-in-list">
<li>
<span class="c-emoji emoji"></span> <a class="e-link pr-link"></a> (<a
class="e-link user-link"></a>
- #<span class="pr-number"></span>)
</li>
</template>

{{ $common := resources.Get "custom-scripts/reviews/common.mjs" | resources.Minify }}
{{ $reviews := resources.Get "custom-scripts/reviews/index.mjs" | resources.Minify }}
{{ $js := slice $common $reviews | resources.Concat "js/reviews-bundle.js" | resources.Minify }}
<script type="module" src="{{ $js.RelPermalink }}"></script>
{{ end }}
85 changes: 0 additions & 85 deletions org-cyf-itp/static/prs/needs-review/index.html

This file was deleted.

Loading

0 comments on commit af9f095

Please sign in to comment.