Revert "Standardise experimental Jenkins pages, make the side panel independently scrollable + make the build bar sticky (#26863)" (#27265)

This reverts commit e8809b04ee.
This commit is contained in:
Guruprasad Bhat authored and GitHub committed 2026-08-20 15:15:00 -06:00
1 parent 20471bcb33
commit a5e091590f
23 files changed
+402 -289

No files matched your search

@@ -27,7 +27,7 @@ THE SOFTWARE.
-->
<?jelly escape-by-default='true'?>
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:f="/lib/form" xmlns:i="jelly:fmt">
<l:side-panel>
<l:side-panel sticky="true">
<l:app-bar title="${%Plugins}" />
<l:tasks>
<l:task href="${rootURL}/manage/pluginManager/" icon="symbol-download" title="${%Updates}" badge="${app.updateCenter.badge}"/>
@@ -36,7 +36,7 @@ THE SOFTWARE.
<l:breadcrumb title="${readOnlyMode ? '%Configuration' : '%Configure'}" />
<l:side-panel>
<l:side-panel sticky="true">
<l:app-bar title="${readOnlyMode ? '%Configuration' : '%Configure'}" />
<div id="tasks">
<l:skeleton type="side-panel" />
@@ -1,6 +1,6 @@
<?jelly escape-by-default='true'?>
<j:jelly xmlns:j="jelly:core">
<a href="${rootURL}/" class="app-jenkins-logo" tooltip="Jenkins ${app.VERSION}" data-tooltip-delay="1000">
<a href="${rootURL}/" class="app-jenkins-logo">
<img id="jenkins-head-icon" src="${imagesURL}/svgs/logo.svg" aria-hidden="true" />
<span class="jenkins-mobile-hide">Jenkins</span>
</a>
@@ -11,9 +11,7 @@ Behaviour.specify(
let errorMessage = holder.getAttribute("data-error-message");
var scroller = new AutoScroller(
holder.closest(".progressive-text-container, #main-panel, #page-body") ||
document.scrollingElement ||
document.documentElement,
holder.closest(".progressive-text-container") || document.body,
);
/*
fetches the latest update from the server
@@ -169,12 +169,12 @@ THE SOFTWARE.
logout="${%logout}"/>
</j:if>
<div id="page-body" class="${layoutType eq 'full-screen' ? 'app-full-screen-page-body' : 'app-page-body'} clear">
<div id="page-body" class="app-page-body app-page-body--${layoutType} clear">
<j:if test="${layoutType=='two-column'}">
<j:set var="mode" value="side-panel" />
<d:invokeBody />
</j:if>
<div class="app-page-body__contents">
<div id="main-panel">
<j:set var="mode" value="main-panel" />
<d:invokeBody/>
</div>
@@ -26,47 +26,40 @@ THE SOFTWARE.
<j:jelly xmlns:j="jelly:core" xmlns:x="jelly:xml" xmlns:st="jelly:stapler" xmlns:d="jelly:define">
<st:documentation>
Generates the body as the main content part of a Jenkins page.
<st:attribute name="width">
Optional, sets the width of the page. Available options are 'default', 'narrow', or 'wide'.
</st:attribute>
</st:documentation>
<j:if test="${mode=='main-panel'}">
<div id="main-panel" class="app-main-panel
${attrs.width eq 'wide' ? 'app-main-panel--wide' : ''}
${attrs.width eq 'narrow' ? 'app-main-panel--narrow' : ''}">
<j:if test="${app.isQuietingDown()}">
<j:choose>
<j:when test="${app.isPreparingSafeRestart()}">
<div id='safe-restart-msg'>
<j:choose>
<j:when test="${!app.getQuietDownReason().trim().isEmpty()}">
${app.getQuietDownReason()}
</j:when>
<j:otherwise>
${%saferestart}
</j:otherwise>
</j:choose>
</div>
</j:when>
<j:otherwise>
<div id='shutdown-msg'>
<j:choose>
<j:when test="${app.getQuietDownReason() != null}">
${app.getQuietDownReason()}
</j:when>
<j:otherwise>
${%shutdown}
</j:otherwise>
</j:choose>
</div>
</j:otherwise>
</j:choose>
</j:if>
<a id="skip2content" />
<x:comment>&#10;start of main content ⇒&#10;</x:comment>
<d:invokeBody />
<x:comment>&#10;⇐ end of main content&#10;</x:comment>
</div>
<j:if test="${app.isQuietingDown()}">
<j:choose>
<j:when test="${app.isPreparingSafeRestart()}">
<div id='safe-restart-msg'>
<j:choose>
<j:when test="${!app.getQuietDownReason().trim().isEmpty()}">
${app.getQuietDownReason()}
</j:when>
<j:otherwise>
${%saferestart}
</j:otherwise>
</j:choose>
</div>
</j:when>
<j:otherwise>
<div id='shutdown-msg'>
<j:choose>
<j:when test="${app.getQuietDownReason() != null}">
${app.getQuietDownReason()}
</j:when>
<j:otherwise>
${%shutdown}
</j:otherwise>
</j:choose>
</div>
</j:otherwise>
</j:choose>
</j:if>
<a id="skip2content" />
<x:comment>&#10;start of main content ⇒&#10;</x:comment>
<d:invokeBody />
<x:comment>&#10;⇐ end of main content&#10;</x:comment>
</j:if>
</j:jelly>
@@ -70,7 +70,7 @@ THE SOFTWARE.
Defaults to false if not set.
</st:attribute>
<st:attribute name="width">
Optional, sets the width of the page. Available options are 'narrow' or 'wide'.
Optional, sets the width of the page. Available options are 'default' or 'wide'.
</st:attribute>
</st:documentation>
@@ -83,7 +83,8 @@ THE SOFTWARE.
<l:layout title="${pageTitle} - ${manageJenkinsAction.displayName}"
permission="${attrs.permission}"
permissions="${attrs.permissions}">
permissions="${attrs.permissions}"
type="${(newManageJenkins or attrs.includeSidepanel) ? 'two-column' : 'one-column'}">
<j:if test="${attrs.includeBreadcrumb}">
<!-- Hacky - this will be improved in subsequent PRs -->
@@ -124,40 +125,44 @@ THE SOFTWARE.
</j:forEach>
</l:tasks>
</l:side-panel>
<l:main-panel width="${attrs.width ?: 'narrow'}">
<j:if test="${!attrs.containsKey('header')}">
<l:app-bar title="${pageTitle}" />
<j:if test="${!empty(description)}">
<div class="jenkins-page-description">
${description}
</div>
</j:if>
</j:if>
<l:main-panel>
<div class="app-settings-container">
<div class="app-settings-container__inner ${attrs.width eq 'wide' ? 'app-settings-container__inner--wide' : ''}">
<j:if test="${!attrs.containsKey('header')}">
<l:app-bar title="${pageTitle}" />
<j:if test="${!empty(description)}">
<div class="jenkins-page-description">
${description}
</div>
</j:if>
</j:if>
<j:out value="${attrs.header}" />
<j:out value="${attrs.header}" />
<j:choose>
<j:when test="${!attrs.noDefer}">
<l:defer>
<l:defer.placeholder>
<j:choose>
<j:when test="${attrs.containsKey('placeholder')}">
<j:out value="${attrs.placeholder}" />
</j:when>
<j:otherwise>
<l:skeleton type="form" />
</j:otherwise>
</j:choose>
</l:defer.placeholder>
<l:defer.children>
<j:choose>
<j:when test="${!attrs.noDefer}">
<l:defer>
<l:defer.placeholder>
<j:choose>
<j:when test="${attrs.containsKey('placeholder')}">
<j:out value="${attrs.placeholder}" />
</j:when>
<j:otherwise>
<l:skeleton type="form" />
</j:otherwise>
</j:choose>
</l:defer.placeholder>
<l:defer.children>
<d:invokeBody />
</l:defer.children>
</l:defer>
</j:when>
<j:otherwise>
<d:invokeBody />
</l:defer.children>
</l:defer>
</j:when>
<j:otherwise>
<d:invokeBody />
</j:otherwise>
</j:choose>
</j:otherwise>
</j:choose>
</div>
</div>
</l:main-panel>
</j:when>
<j:otherwise>
@@ -165,7 +170,7 @@ THE SOFTWARE.
<st:include page="sidepanel" />
</j:if>
<l:main-panel width="${attrs.width ?: 'narrow'}">
<l:main-panel>
<j:if test="${!attrs.containsKey('header')}">
<l:app-bar title="${pageTitle}" />
<j:if test="${!empty(description)}">
@@ -26,11 +26,17 @@ THE SOFTWARE.
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define">
<st:documentation>
Generates a left side content as part of a Jenkins page. Typically known as two-column or left-side + main-content layouts
<st:attribute name="sticky">
Make the side panel sticky. Should not be used on pages that include widgets in the sidepanel and when plugins can
add their own tasks, so the number of tasks is not fixed.
</st:attribute>
</st:documentation>
<j:if test="${mode=='side-panel'}">
<div id="side-panel" class="app-page-body__sidebar">
<div id="side-panel" class="app-page-body__sidebar ${attrs.sticky == 'true' ? 'app-page-body__sidebar--sticky' : ''}">
<d:invokeBody />
</div>
</j:if>
</j:jelly>
+35
View File
@@ -17,9 +17,44 @@ function init() {
computeOverflow();
});
// Fade in the page header on scroll, increasing opacity and intensity of the backdrop blur
window.addEventListener("scroll", () => {
const navigation = document.querySelector("#page-header");
const scrollY = Math.max(0, window.scrollY);
navigation.style.setProperty(
"--background-opacity",
Math.min(70, scrollY) + "%",
);
navigation.style.setProperty(
"--background-blur",
Math.min(40, scrollY) + "px",
);
if (
!document.querySelector("#main-panel > .jenkins-search--app-bar") &&
!document.querySelector(".app-page-body__sidebar--sticky")
) {
const prefersContrast = window.matchMedia(
"(prefers-contrast: more)",
).matches;
navigation.style.setProperty(
"--border-opacity",
Math.min(
prefersContrast ? 100 : 15,
prefersContrast ? scrollY * 3 : scrollY,
) + "%",
);
}
});
window.addEventListener("load", () => {
// We can't use :has due to HtmlUnit CSS Parser not supporting it, so
// these are workarounds for that same behaviour
if (document.querySelector("#main-panel > .jenkins-app-bar--sticky")) {
document
.querySelector(".jenkins-header")
.classList.add("jenkins-header--has-sticky-app-bar");
}
if (!document.querySelector(".jenkins-breadcrumbs__list-item")) {
document
.querySelector(".jenkins-header")
+5 -9
View File
@@ -79,14 +79,10 @@ $semantics: (
--background: rgb(254 254 254);
// Header
--header-background: color-mix(
in sRGB,
var(--background),
var(--text-color-secondary) 2.5%
);
--header-background: var(--background);
--header-border: var(--text-color-secondary);
--header-color: var(--text-color);
--header-height: 3.5rem;
--header-height: 4.125rem;
// App bar
--bottom-app-bar-padding: 0.875rem;
@@ -272,7 +268,7 @@ $semantics: (
--panel-border-color: var(--light-grey);
// Form
--section-padding: 1.25rem;
--section-padding: 1.625rem;
--input-color: var(--white);
--input-border: color-mix(
in sRGB,
@@ -289,7 +285,7 @@ $semantics: (
--form-item-max-width--small: min(35vw, 1200px);
@media screen and (max-width: breakpoints.$tablet-breakpoint) {
--section-padding: 1rem;
--section-padding: 1.25rem;
--form-item-max-width: 100%;
--form-item-max-width--medium: 100%;
--form-item-max-width--small: 100%;
@@ -297,7 +293,7 @@ $semantics: (
--form-label-font-weight: var(--font-bold-weight);
--form-input-padding: 0.5rem 0.625rem;
--form-input-border-radius: 0.6875rem;
--form-input-border-radius: 0.625rem;
--form-input-glow: 0 0 0 0.5rem transparent;
--form-input-glow--focus: 0 0 0 0.25rem var(--focus-input-glow);
--pre-background: var(--button-background);
+3 -2
View File
@@ -1,8 +1,9 @@
html {
height: 100%;
box-sizing: border-box;
-webkit-tap-highlight-color: transparent;
color: var(--text-color);
overscroll-behavior: none;
scroll-padding-top: calc(var(--header-height) + var(--section-padding));
scrollbar-color: oklch(from var(--text-color-secondary) l c h / 0.35)
oklch(from var(--text-color-secondary) l c h / 0.05);
}
@@ -12,7 +13,7 @@ body {
min-height: 100vh;
display: flex;
flex-direction: column;
background-color: var(--header-background);
background-color: var(--background);
}
*,
+95 -95
View File
@@ -1,103 +1,21 @@
@use "../base/breakpoints";
/* -------------------------------------- */
.app-page-body {
position: relative;
display: grid;
border: var(--jenkins-border);
margin-inline: var(--page-inset);
height: calc(100vh - var(--header-height) - var(--page-inset));
border-radius: var(--form-input-border-radius);
overflow: hidden;
--top: color-mix(in oklch, white 1.5%, var(--card-background));
--background: var(--card-background);
background-color: var(--card-background);
background-image: linear-gradient(in oklch, var(--top), var(--background));
background-size: 100% 90vh;
background-repeat: no-repeat;
isolation: isolate;
&:has(> .app-page-body__sidebar) {
grid-template-columns: auto 1fr;
}
@media (width < 740px) {
display: flex;
flex-direction: column;
overflow-y: auto;
}
& > .app-page-body__sidebar {
padding: var(--section-padding);
@media (width >= 740px) {
width: 280px;
min-height: calc(100vh - var(--header-height) - var(--page-inset));
}
@media (width > breakpoints.$tablet-breakpoint) {
width: 320px;
}
}
& > .app-page-body__contents {
padding: var(--section-padding);
padding-bottom: 0;
}
@media (width >= 740px) {
&:not(:has(#side-panel .pane, #side-panel .jenkins-card)) {
& > .app-page-body__sidebar {
overflow-y: auto;
border-right: var(--jenkins-border);
}
& > .app-page-body__contents {
overflow-y: auto;
}
}
}
// Remove this when sidepanels no longer contain widgets
&:has(#side-panel .pane, #side-panel .jenkins-card) {
overflow-y: auto;
& > .app-page-body__sidebar {
padding-right: 0;
#tasks {
margin-bottom: 1rem;
}
.jenkins-card,
.pane-frame {
margin-inline: -0.5rem;
}
}
}
display: flex;
justify-content: flex-start;
align-items: stretch;
flex: 1 0 auto;
}
.app-main-panel {
margin-bottom: var(--section-padding);
&--narrow {
max-width: 900px;
margin-inline: auto;
}
&--wide {
width: 70vw;
max-width: 1700px;
margin-inline: auto;
}
}
.app-full-screen-page-body {
.app-main-panel {
display: flex;
flex-direction: column;
min-height: 100vh;
.app-page-body__sidebar {
@media (min-width: breakpoints.$tablet-breakpoint) {
&--sticky {
position: sticky;
top: var(--header-height);
align-self: flex-start;
}
}
}
@@ -107,6 +25,88 @@
display: table;
}
#side-panel {
flex-shrink: 0;
}
#main-panel {
padding: 0 var(--section-padding) var(--section-padding)
var(--section-padding);
display: inline-block;
width: 100%;
}
.app-page-body--one-column {
--form-item-max-width: calc(85vw - 4rem);
@media screen and (width <= 1200px) {
--form-item-max-width: 100%;
}
max-width: 85vw;
#main-panel {
width: 100vw;
}
.jenkins-section {
max-width: unset;
}
@media (width <= 1200px) {
max-width: unset;
}
margin: auto;
}
body.two-column #main-panel {
width: calc(100% - var(--side-panel-width));
flex: 1;
display: block;
}
body.full-screen {
padding: 0;
}
body.full-screen #main-panel {
padding: 0;
}
body.two-column #side-panel {
width: var(--side-panel-width);
}
@media (max-width: breakpoints.$tablet-breakpoint) {
body.two-column #page-body {
flex-wrap: wrap;
}
body.two-column #side-panel {
width: 100%;
border-right: none;
}
body.two-column #main-panel {
margin-left: 0;
width: 100%;
}
}
.app-project-status-table {
width: 100%;
overflow-x: auto;
}
@media (width >= 1170px) {
body.two-column #main-panel {
width: calc(
100% - calc(var(--side-panel-width) + calc(var(--section-padding) * 2))
);
}
}
// Clearfixes extracted from responsive-grid.css as they essential
.clearfix::before,
.clearfix::after,
+4 -12
View File
@@ -3,21 +3,13 @@
// clicks.
// Keep this list in sync with the `position: sticky` rules across the SCSS sources.
:root[data-disable-sticky="true"] {
.app-page-body {
height: auto !important;
overflow: visible !important;
}
.app-page-body > .app-page-body__sidebar,
.app-page-body > .app-page-body__contents {
overflow-y: visible !important;
}
.jenkins-header,
.jenkins-app-bar--sticky,
.jenkins-bottom-app-bar__shadow,
.app-build-bar,
.bottom-sticker,
#bottom-sticker {
#bottom-sticker,
.app-page-body__sidebar--sticky,
.app-plugin-manager__sidebar {
position: relative !important;
// Reset the sticky offsets too — with relative positioning these would otherwise
+6 -7
View File
@@ -3,7 +3,7 @@
align-items: center;
justify-content: space-between;
margin-bottom: 0.875rem;
min-height: 2.5rem;
min-height: 2.875rem;
gap: var(--section-padding);
flex-wrap: wrap;
@@ -68,23 +68,23 @@
&--sticky {
position: sticky;
top: 0;
top: var(--header-height);
z-index: 2;
&::before,
&::after {
content: "";
position: absolute;
inset: calc(var(--section-padding) * -1)
inset: calc(var(--header-height) * -1)
calc(var(--section-padding) * -1) -0.875rem;
z-index: -1;
pointer-events: none;
}
&::before {
background: var(--top);
background: var(--background);
mask-image: linear-gradient(black 70%, transparent);
opacity: 0.6;
opacity: 0.55;
}
&::after {
@@ -106,8 +106,7 @@
h1,
h2 {
margin: 0;
font-size: 1.1875rem;
font-weight: 550;
font-size: 1.3125rem;
}
&__subtitle {
@@ -9,7 +9,6 @@
&__list {
display: flex;
margin: 0;
& > * {
z-index: 1;
@@ -4,7 +4,6 @@
width: 100%;
clear: both;
font-size: var(--font-size-sm);
display: none;
}
.page-footer .container-fluid {
+42 -4
View File
@@ -1,6 +1,13 @@
@use "../abstracts/mixins";
.jenkins-header {
--background-opacity: 0%;
--background-blur: 0;
--border-opacity: 0%;
position: sticky;
top: 0;
z-index: 999;
display: flex;
align-items: center;
gap: var(--section-padding);
@@ -9,6 +16,26 @@
min-height: var(--header-height);
color: var(--header-color);
&::before {
content: "";
position: absolute;
inset: 0;
backdrop-filter: blur(var(--background-blur));
background: color-mix(
in sRGB,
var(--header-background) var(--background-opacity),
transparent
);
border-bottom: var(--jenkins-border-width) solid
color-mix(
in sRGB,
var(--header-border) var(--border-opacity),
transparent
);
background-clip: padding-box;
z-index: -1;
}
.app-jenkins-logo {
@include mixins.item($border: false);
@@ -52,7 +79,7 @@
}
#jenkins-head-icon {
width: 1.5rem;
width: 1.625rem;
}
}
@@ -64,6 +91,11 @@
// For customizable-header-plugin
color: inherit !important;
svg {
width: 1.25rem;
height: 1.25rem;
}
img {
width: 1.625rem;
height: 1.625rem;
@@ -89,7 +121,7 @@
&__main {
display: grid;
grid-template-columns: 1fr auto;
padding-left: calc(var(--section-padding) + var(--page-inset));
padding-left: var(--section-padding);
width: 100%;
}
@@ -103,8 +135,14 @@
display: flex;
align-items: center;
justify-content: center;
gap: 0.25rem;
padding-right: calc(var(--section-padding) + var(--page-inset));
gap: 0.5rem;
padding-right: var(--section-padding);
}
&--has-sticky-app-bar {
&::before {
mask-image: linear-gradient(black 50%, transparent);
}
}
&--no-breadcrumbs {
@@ -1,14 +1,19 @@
@use "../abstracts/mixins";
@use "../base/breakpoints";
$inset: 0.6875rem;
$background-outset: 0.5rem;
#tasks,
.tasks,
.subtasks {
display: flex;
flex-direction: column;
margin: 0 var(--section-padding) var(--section-padding) var(--section-padding);
gap: 0.125rem;
@media (min-width: breakpoints.$tablet-breakpoint) {
margin-right: calc($background-outset);
}
}
.subtasks {
@@ -22,11 +27,12 @@ $inset: 0.6875rem;
#side-panel {
.jenkins-app-bar {
margin-inline: $inset;
margin-left: var(--section-padding);
margin-right: var(--section-padding);
}
& > #tasks > .jenkins-search-container {
margin: 0 0 1rem;
margin: 0 0 1rem #{-$background-outset};
.jenkins-search__icon {
width: 2.625rem;
@@ -39,6 +45,10 @@ $inset: 0.6875rem;
}
}
#tasks .task {
margin: 0 0 0 calc($background-outset * -1);
}
#tasks,
.tasks {
.task .task-link {
@@ -47,7 +57,7 @@ $inset: 0.6875rem;
display: flex;
align-items: center;
justify-content: flex-start;
padding: 0.5rem $inset;
padding: 0.5rem 0.6875rem;
gap: 0.625rem;
width: 100%;
font-size: var(--font-size-sm);
@@ -105,7 +115,7 @@ $inset: 0.6875rem;
font-size: var(--font-size-sm);
color: var(--text-color-secondary);
font-weight: var(--font-bold-weight);
margin: 1rem 0 0.375rem $inset;
margin: 1rem 0 0.375rem;
&:first-of-type {
margin-top: 0.375rem;
@@ -8,6 +8,10 @@
overflow: hidden;
}
#side-panel .pane-frame {
margin-left: 10px;
}
#side-panel .pane-header,
.app-build-content .pane-header {
font-size: var(--font-size-sm);
+84 -55
View File
@@ -12,6 +12,7 @@
.app-build__grid {
gap: calc(var(--section-padding) / 2);
margin-bottom: calc(var(--section-padding) * -0.5);
& > * {
height: 350px;
@@ -138,66 +139,101 @@
}
}
@keyframes app-build-bar-border-on-scroll {
from {
border-bottom-color: color-mix(
in sRGB,
var(--jenkins-border-color),
transparent
);
}
body:has(.app-build-bar),
body:has(.app-settings-container) {
--top: color-mix(in sRGB, var(--text-color-secondary) 4%, var(--background));
--bottom: color-mix(
in sRGB,
var(--text-color-secondary) 2%,
var(--background)
);
to {
border-bottom-color: var(--jenkins-border-color);
background: linear-gradient(var(--top), var(--bottom));
background-attachment: fixed;
}
.app-settings-container {
--background: var(--card-background);
--top: color-mix(
in sRGB,
var(--text-color-secondary) 2%,
var(--card-background)
);
position: relative;
background-color: var(--card-background);
background-image: linear-gradient(var(--top), var(--card-background));
background-size: 100% 90vh;
background-repeat: no-repeat;
border: var(--jenkins-border);
border-radius: var(--form-input-border-radius);
z-index: 0;
min-height: calc(100vh - var(--header-height) - var(--section-padding));
&__inner {
max-width: 900px;
margin: auto;
padding: var(--section-padding);
display: flex;
flex-direction: column;
&--wide {
width: 70vw;
max-width: 1700px;
}
// TODO - this can be moved to app-bar.scss when Manage Jenkins flag is removed
.jenkins-app-bar--sticky {
padding: var(--section-padding) 0 !important;
margin: -1rem 0 0.5rem !important;
&::before,
&::after {
inset: 0 !important;
}
&::before {
background: color-mix(
in sRGB,
var(--text-color-secondary) 2%,
var(--card-background)
) !important;
mask-image: linear-gradient(black 60%, transparent) !important;
opacity: 0.75 !important;
}
&::after {
left: calc(var(--section-padding) * -1) !important;
right: calc(var(--section-padding) * -1) !important;
mask-image: linear-gradient(black 65%, transparent) !important;
}
}
}
}
.app-build-bar {
--app-build-bar-border-color: color-mix(
in sRGB,
var(--jenkins-border-color),
transparent
);
position: sticky;
top: 0;
position: relative;
display: grid;
grid-template-columns: 1fr auto 1fr;
align-items: center;
align-items: start;
gap: 0.5rem 1.5rem;
min-height: var(--header-height);
background-color: color-mix(in oklch, transparent 25%, var(--top));
padding-inline: var(--section-padding);
min-height: 2.875rem;
margin-top: -5px;
padding-bottom: 0.75rem;
z-index: 102;
border-bottom: var(--jenkins-border-width) solid
var(--app-build-bar-border-color);
margin-left: calc(var(--section-padding) * -1);
margin-right: calc(var(--section-padding) * -1);
@media (width <= 1200px) {
display: flex;
flex-direction: column;
}
&::before {
content: "";
position: absolute;
inset: 0;
inset: -1000px calc(var(--section-padding) * -1) 0;
background-color: var(--background);
border-bottom: var(--jenkins-border-width) solid var(--card-border-color);
z-index: -1;
pointer-events: none;
backdrop-filter: blur(15px);
}
@supports (animation-timeline: scroll()) {
animation-name: app-build-bar-border-on-scroll;
animation-duration: 1s;
animation-fill-mode: both;
animation-timing-function: linear;
animation-timeline: scroll(nearest block);
animation-range: 0 var(--header-height);
}
@media (width < 740px) {
position: relative;
display: flex;
flex-direction: column;
align-items: start;
padding-block: var(--section-padding);
}
.app-build-bar__content {
@@ -211,7 +247,6 @@
display: inline-flex;
align-items: center;
justify-content: center;
margin-block: 0.5rem;
}
.app-build-bar__controls {
@@ -219,7 +254,7 @@
align-items: center;
justify-content: end;
flex: 1;
gap: 0.5rem;
gap: 0.75rem;
@media (width <= 600px) {
justify-content: stretch;
@@ -243,14 +278,12 @@
svg {
width: 2rem;
height: 2rem;
flex-shrink: 0;
}
}
h1 {
margin-bottom: 0;
font-size: 1.1875rem;
font-weight: 550;
font-size: 1.25rem;
}
.jenkins-button {
@@ -292,10 +325,6 @@
}
}
.app-page-body__contents:has(.app-build-bar) {
padding-top: 0;
}
.app-build-content {
display: flex;
flex-direction: column;
+6
View File
@@ -1,5 +1,11 @@
@use "../abstracts/mixins";
#side-panel {
#buildHistoryPage {
margin: 10px 0 10px 10px;
}
}
#buildHistoryPage {
.jenkins-search {
margin-inline: -0.25rem;
+10
View File
@@ -104,3 +104,13 @@
border-radius: 0.25em;
}
}
.app-plugin-manager__sidebar {
position: sticky;
top: calc(40px + 1.6rem);
h1 {
margin-top: 1rem !important;
margin-bottom: 0.1rem !important;
}
}
+9 -16
View File
@@ -2088,14 +2088,6 @@ function AutoScroller(scrollContainer) {
return null;
}
function isViewportScroller(scrollDiv) {
return (
scrollDiv === document.body ||
scrollDiv === document.documentElement ||
scrollDiv === document.scrollingElement
);
}
return {
bottomThreshold: 25,
scrollContainer: scrollContainer,
@@ -2119,13 +2111,14 @@ function AutoScroller(scrollContainer) {
// when used with the BODY tag, the height needs to be the viewport height, instead of
// the element height.
const height = isViewportScroller(scrollDiv)
? getViewportHeight()
: scrollDiv.clientHeight;
const scrollPos = isViewportScroller(scrollDiv)
? Math.max(scrollDiv.scrollTop, document.documentElement.scrollTop)
: scrollDiv.scrollTop;
const diff = currentHeight - scrollPos - height;
//var height = ((scrollDiv.style.pixelHeight) ? scrollDiv.style.pixelHeight : scrollDiv.offsetHeight);
var height = getViewportHeight();
var scrollPos = Math.max(
scrollDiv.scrollTop,
document.documentElement.scrollTop,
);
var diff = currentHeight - scrollPos - height;
// window.alert("currentHeight=" + currentHeight + ",scrollTop=" + scrollDiv.scrollTop + ",height=" + height);
return diff < this.bottomThreshold;
},
@@ -2134,7 +2127,7 @@ function AutoScroller(scrollContainer) {
var scrollDiv = this.scrollContainer;
var currentHeight = this.getCurrentHeight();
if (isViewportScroller(scrollDiv)) {
if (scrollDiv === document.body) {
window.scrollTo({
top: currentHeight,
});