Add board directory view (#1132)

* feat(directory): add board directory view

* fix(directory): populate board status

* style(directory): tighten board table

* docs(board manager): point board owners to manager

* fix(directory): show loading status

* style(directory): center board column in directory table

* perf(directory): cap board status checks

* style(directory): simplify board row links

* test(ci): stabilize coverage run

* test(ci): stabilize coverage harness

* test(ci): avoid async app flush act

* test(app): narrow layout harness coverage

* test(ci): stabilize app update distribution mock

* test(ci): preload app harness before route tests

* fix(directory): address final review findings
This commit is contained in:
Tommaso Casaburi
2026-05-19 23:34:33 +07:00
committed by GitHub
parent 4370e89174
commit cda1f7519f
62 changed files with 1572 additions and 171 deletions
+306
View File
@@ -0,0 +1,306 @@
.page {
max-width: none;
margin: 0;
padding: 0 0 24px;
color: var(--body-font-color);
font-family: var(--body-font-family);
font-size: var(--body-font-size);
}
.desktopDivider {
display: block;
}
.divider {
display: block;
}
.desktopNavLinks {
display: flex;
align-items: center;
gap: 4px;
text-align: left;
font-size: 13px;
text-transform: capitalize;
}
.desktopNavLinks a:not([class~='button']),
.desktopFooterButtons a:not([class~='button']) {
all: unset;
}
.mobileNavLinks {
display: none;
text-align: center;
text-transform: capitalize;
margin-top: 5px;
}
.mobileNavLinks button {
text-transform: capitalize;
margin: 5px 2px;
}
.mobileNavLinks a:not([class~='button']),
.mobileFooterButtons a:not([class~='button']) {
all: unset;
}
.desktopFooterButtons {
display: flex;
align-items: center;
gap: 4px;
width: 100%;
text-transform: capitalize;
}
.mobileFooterButtons {
text-align: center;
text-transform: capitalize;
}
.mobileFooterButtons button {
text-transform: capitalize;
margin: 5px 2px;
}
.directorySummary {
margin: 0 0 12px;
text-align: center;
font-size: 10pt;
font-weight: 700;
}
.directoryIntro {
width: 80%;
max-width: 810px;
margin: 0 auto 8px;
text-align: center;
font-size: 12px;
line-height: 1.4;
}
.directoryIntro a {
color: var(--post-link-text-color);
text-decoration: var(--post-link-text-decoration);
}
.directoryIntro a:hover {
color: var(--post-link-text-color-hover);
}
.error {
margin-bottom: 8px;
}
.flashListing {
width: 80%;
max-width: 810px;
margin: 10px auto 0;
border-collapse: separate;
border-spacing: 1px;
table-layout: auto;
}
.flashListing td {
padding: 2px;
font-size: 12px;
text-align: center;
}
.flashListing thead td {
background: #98e;
border: 1px solid #000;
font-weight: 700;
}
.dirRow {
background: transparent;
}
.numberCell,
.scoreCell,
.ownerCell,
.statusCell,
.actionsCell {
white-space: nowrap;
}
.numberCell,
.scoreCell,
.actionsCell {
width: 1%;
}
.postblock {
padding: 5px !important;
text-align: center;
}
.boardCol {
text-align: center;
vertical-align: middle;
word-break: break-all;
}
.ownerCell {
text-align: center;
}
.ownerName {
font-weight: var(--post-name-font-weight, 700);
}
.viewLink {
color: var(--post-link-text-color);
text-decoration: var(--post-link-text-decoration);
}
.viewLink:hover {
color: var(--post-link-text-color-hover);
}
.actionButton {
all: unset;
cursor: pointer;
color: var(--post-link-text-color);
text-decoration: var(--post-link-text-decoration);
}
.actionButton:hover,
.actionButton:focus-visible {
color: var(--post-link-text-color-hover);
}
.actionButton:focus-visible {
outline: 1px dotted currentcolor;
outline-offset: 1px;
}
.scoreValue {
font-weight: 700;
}
.statusOnline {
color: green;
}
.statusOffline {
color: red;
}
.statusUnavailable {
color: var(--body-font-color);
}
.statusUnavailableHelp {
margin-left: 2px;
font-weight: 700;
cursor: help;
}
.directoryFootnote {
width: 80%;
max-width: 810px;
margin: 14px auto 0;
text-align: center;
font-size: 11px;
line-height: 1.4;
opacity: 0.85;
}
.directoryFootnote a {
color: var(--post-link-text-color);
text-decoration: var(--post-link-text-decoration);
}
.directoryFootnote a:hover {
color: var(--post-link-text-color-hover);
}
.footerState {
margin: 8px 0;
text-align: center;
}
.garland {
border-image-slice: 50 0 50 0;
border-image-width: 40px 0px 0px 0px;
border-image-outset: 0px 0px 0px 0px;
border-image-repeat: repeat repeat;
border-image-source: url('/assets/garland.png');
border-style: solid;
padding-top: 50px;
}
@media (max-width: 640px) {
.desktopDivider,
.desktopNavLinks {
display: none;
}
.mobileNavLinks {
display: block;
}
.flashListing,
.directoryIntro,
.directoryFootnote {
width: calc(100% - 10px);
max-width: calc(100% - 10px);
margin-left: auto;
margin-right: auto;
}
.flashListing {
margin-top: 10px;
}
.actionsCell {
white-space: nowrap;
}
}
:global(body.yotsuba) .rowOdd td {
background: #ede2d4;
}
:global(body.yotsuba) .flashListing thead td {
background: #ea8;
}
:global(body.yotsuba-b) .rowOdd td {
background: #e0e5f6;
}
:global(body.futaba) .rowOdd td {
background: #ede2d4;
}
:global(body.futaba) .flashListing thead td {
background: #f0e0d6;
}
:global(body.burichan) .rowOdd td {
background: #e0e5f6;
}
:global(body.burichan) .flashListing thead td {
background: #c3c9e9;
}
:global(body.tomorrow) .rowOdd td {
background: rgba(255, 255, 255, 0.1);
}
:global(body.tomorrow) .flashListing thead td {
background: #b294bb;
}
:global(body.photon) .rowOdd td {
background: #888;
}
:global(body.photon) .flashListing thead td {
background: #ddd;
}