mirror of
https://github.com/jenkinsci/jenkins.git
synced 2026-10-26 19:15:09 +00:00
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:
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> start of main content ⇒ </x:comment>
|
||||
<d:invokeBody />
|
||||
<x:comment> ⇐ end of main content </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> start of main content ⇒ </x:comment>
|
||||
<d:invokeBody />
|
||||
<x:comment> ⇐ end of main content </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>
|
||||
@@ -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")
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
*,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
@use "../abstracts/mixins";
|
||||
|
||||
#side-panel {
|
||||
#buildHistoryPage {
|
||||
margin: 10px 0 10px 10px;
|
||||
}
|
||||
}
|
||||
|
||||
#buildHistoryPage {
|
||||
.jenkins-search {
|
||||
margin-inline: -0.25rem;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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,
|
||||
});
|
||||
|
||||
Reference in new issue
Block a user