Merge branch 'master' into add-groups-to-command-palette

This commit is contained in:
Jan Faracik 2025-02-16 17:10:25 +00:00
commit cc3779171a
21 changed files with 259 additions and 197 deletions

View File

@ -42,6 +42,35 @@ You may add multiple changelog entries if applicable by adding a new entry to th
- Second changelog entry
-->
### Proposed changelog category
/label <update-this-with-category>
<!--
The changelog entry needs to have a category which is selected based on the label.
If there's no changelog then the label should be `skip-changelog`.
The available categories are:
* bug - Minor bug. Will be listed after features
* developer - Changes which impact plugin developers
* dependencies - Pull requests that update a dependency
* internal - Internal only change, not user facing
* into-lts - Changes that are backported to the LTS baseline
* localization - Updates localization files
* major-bug - Major bug. Will be highlighted on the top of the changelog
* major-rfe - Major enhancement. Will be highlighted on the top
* rfe - Minor enhancement
* regression-fix - Fixes a regression in one of the previous Jenkins releases
* removed - Removes a feature or a public API
* skip-changelog - Should not be shown in the changelog
Non-changelog categories:
* web-ui - Changes in the web UI
Non-changelog categories require a changelog category but should be used if applicable,
comma separate to provide multiple categories in the label command.
-->
### Proposed upgrade guidelines
N/A

View File

@ -0,0 +1,31 @@
name: Require Changelog Label
on:
pull_request_target:
types: [opened, labeled, unlabeled, synchronize]
branches:
- 'master'
jobs:
label:
runs-on: ubuntu-latest
permissions:
issues: write
pull-requests: write
steps:
- uses: mheap/github-action-required-labels@388fd6af37b34cdfe5a23b37060e763217e58b03 # v5
with:
mode: minimum
count: 1
add_comment: true
message: "Missing required label for changelog. Requires {{errorString}} {{count}} of: {{ provided }}. Found: {{ applied }}.\n\nYou can add the required label by adding a comment with the following text: `/label <category>`"
labels: |
bug
developer
dependencies
internal
localization
major-bug
major-rfe
rfe
regression-fix
removed
skip-changelog

View File

@ -63,7 +63,7 @@ THE SOFTWARE.
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-framework-bom</artifactId>
<version>6.2.2</version>
<version>6.2.3</version>
<type>pom</type>
<scope>import</scope>
</dependency>

View File

@ -56,7 +56,7 @@ public class ModelHyperlinkNote extends HyperlinkNote {
return encodeTo("/" + c.getUrl(), node.getDisplayName());
}
String nodePath = node == Jenkins.get() ? "(built-in)" : node.getNodeName();
return encodeTo("/computer/" + nodePath, node.getDisplayName());
return encodeTo("/computer/" + nodePath + "/", node.getDisplayName());
}
/**

View File

@ -488,7 +488,7 @@ public abstract class AbstractBuild<P extends AbstractProject<P, R>, R extends A
if (node instanceof Jenkins) {
listener.getLogger().print(Messages.AbstractBuild_BuildingOnMaster());
} else {
listener.getLogger().print(Messages.AbstractBuild_BuildingRemotely(ModelHyperlinkNote.encodeTo("/computer/" + builtOn, node.getDisplayName())));
listener.getLogger().print(Messages.AbstractBuild_BuildingRemotely(ModelHyperlinkNote.encodeTo("/computer/" + builtOn + "/", node.getDisplayName())));
Set<LabelAtom> assignedLabels = new HashSet<>(node.getAssignedLabels());
assignedLabels.remove(node.getSelfLabel());
if (!assignedLabels.isEmpty()) {

View File

@ -59,7 +59,7 @@ import org.kohsuke.stapler.StaplerRequest2;
* {@link NodeProperty}s show up in the configuration screen of a node, and they are persisted with the {@link Node} object.
*
* <p>
* To add UI action to {@link Node}s, i.e. a new link shown in the left side menu on a node page ({@code ./computer/<a node>}), see instead {@link hudson.model.TransientComputerActionFactory}.
* To add UI action to {@link Node}s, i.e. a new link shown in the left side menu on a node page ({@code ./computer/<a node>/}), see instead {@link hudson.model.TransientComputerActionFactory}.
*
*
* <h2>Views</h2>

View File

@ -35,6 +35,7 @@ import java.lang.ref.Cleaner;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.AccessDeniedException;
import java.nio.file.AtomicMoveNotSupportedException;
import java.nio.file.Files;
import java.nio.file.InvalidPathException;
@ -246,11 +247,11 @@ public class AtomicFileWriter extends Writer {
// Both files are on the same filesystem, so this should not happen.
LOGGER.log(Level.WARNING, e, () -> "Atomic move " + source + "" + destination + " not supported. Falling back to non-atomic move.");
atomicMoveSupported = false;
} catch (AccessDeniedException e) {
LOGGER.log(Level.INFO, e, () -> "Move " + source + "" + destination + " failed, perhaps due to a temporary file lock. Falling back to non-atomic move.");
}
}
if (!atomicMoveSupported) {
Files.move(source, destination, StandardCopyOption.REPLACE_EXISTING);
}
Files.move(source, destination, StandardCopyOption.REPLACE_EXISTING);
}
private static final class CleanupChecker implements Runnable {

View File

@ -5479,7 +5479,7 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve
@Override
public boolean hasPermission(Permission permission) {
// no one should be allowed to delete the master.
// this hides the "delete" link from the /computer/(master) page.
// this hides the "delete" link from the /computer/(built-in)/ page.
if (permission == Computer.DELETE)
return false;
// Configuration of master node requires ADMINISTER permission

View File

@ -50,7 +50,7 @@ window.buildTimeTrend_displayBuilds = function (data) {
let buildInfoStr = escapeHTML(e.builtOnStr || "");
if (e.builtOn) {
buildInfo = document.createElement("a");
buildInfo.href = rootURL + "/computer/" + e.builtOn;
buildInfo.href = rootURL + "/computer/" + e.builtOn + "/";
buildInfo.classList.add("model-link", "inside");
buildInfo.innerText = buildInfoStr;
} else {

View File

@ -47,7 +47,7 @@ THE SOFTWARE.
</j:if>
<j:if test="${e.key != null and e.key.length() > 0}">
<h1 id="id${e.key.hashCode()}">
<l:icon class="symbol-computer icon-lg"/> <a class="model-link inside" href="${rootURL}/computer/${e.key}">${e.key}</a>
<l:icon class="symbol-computer icon-lg"/> <a class="model-link inside" href="${rootURL}/computer/${e.key}/">${e.key}</a>
</h1>
</j:if>
<j:forEach var="t" items="${e.value.entrySet()}">

View File

@ -81,7 +81,7 @@ THE SOFTWARE.
<td class="pane">
<div style="white-space: normal">
<j:choose>
<j:when test="${exeparent != null}">
<j:when test="${exe == null and exeparent != null }">
<j:choose>
<j:when test="${exeparentcanread}">
<a href="${rootURL}/${exeparent.url}"><l:breakable value="${exeparent.fullDisplayName}"/></a>

View File

@ -31,7 +31,7 @@ THE SOFTWARE.
</st:documentation>
<j:choose>
<j:when test="${value!=null and value!=app}">
<a href="${rootURL}/computer/${value.nodeName}" class="model-link inside">${value.nodeName}</a>
<a href="${rootURL}/computer/${value.nodeName}/" class="model-link inside">${value.nodeName}</a>
</j:when>
<j:when test="${valueStr != null and valueStr != ''}">
${valueStr}
@ -40,4 +40,4 @@ THE SOFTWARE.
${%built-in}
</j:otherwise>
</j:choose>
</j:jelly>
</j:jelly>

View File

@ -23,9 +23,9 @@ Behaviour.specify("a.task-link-no-confirm", "task-link", 0, function (el) {
headers: crumb.wrap({}),
}).then((rsp) => {
if (rsp.ok) {
notificationBar(success, notificationBar.SUCCESS);
notificationBar.show(success, notificationBar.SUCCESS);
} else {
notificationBar(failure, notificationBar.ERROR);
notificationBar.show(failure, notificationBar.ERROR);
}
});
ev.preventDefault();

View File

@ -31,17 +31,17 @@
"clean-webpack-plugin": "4.0.0",
"css-loader": "7.1.2",
"css-minimizer-webpack-plugin": "7.0.0",
"eslint": "9.20.0",
"eslint": "9.20.1",
"eslint-config-prettier": "10.0.1",
"eslint-formatter-checkstyle": "8.40.0",
"globals": "15.14.0",
"globals": "15.15.0",
"handlebars-loader": "1.7.3",
"mini-css-extract-plugin": "2.9.2",
"postcss": "8.5.1",
"postcss": "8.5.2",
"postcss-loader": "8.1.1",
"postcss-preset-env": "10.1.3",
"postcss-scss": "4.0.9",
"prettier": "3.4.2",
"prettier": "3.5.0",
"sass": "1.84.0",
"sass-loader": "16.0.4",
"style-loader": "4.0.0",

View File

@ -98,7 +98,7 @@ THE SOFTWARE.
<spotless.check.skip>false</spotless.check.skip>
<!-- Make sure to keep the jetty-ee9-maven-plugin version in war/pom.xml in sync with the Jetty release in Winstone: -->
<winstone.version>8.4</winstone.version>
<node.version>20.18.2</node.version>
<node.version>20.18.3</node.version>
</properties>
<!--

View File

@ -1,25 +1,28 @@
import $ from "jquery";
import { createElementFromHtml } from "@/util/dom";
var getItems = function () {
var d = $.Deferred();
$.get("itemCategories?depth=3&iconStyle=icon-xlg").done(function (data) {
d.resolve(data);
});
return d.promise();
const nameInput = document.querySelector(`#createItem input[name="name"]`);
const copyFromInput = document.querySelector(`#createItem input[name="from"]`);
const copyRadio = document.querySelector(`#createItem input[value="copy"]`);
const getItems = function () {
return fetch("itemCategories?depth=3&iconStyle=icon-xlg").then((response) =>
response.json(),
);
};
var jRoot = $("head").attr("data-rooturl");
const jRoot = document.querySelector("head").getAttribute("data-rooturl");
$.when(getItems()).done(function (data) {
$(function () {
document.addEventListener("DOMContentLoaded", () => {
getItems().then((data) => {
//////////////////////////
// helper functions...
function parseResponseFromCheckJobName(data) {
var html = $.parseHTML(data);
var element = html[0];
if (element !== undefined) {
return $(element).text();
var parser = new DOMParser();
var html = parser.parseFromString(data, "text/html");
var element = html.body.firstChild;
if (element) {
return element.textContent;
}
return undefined;
}
@ -38,50 +41,48 @@ $.when(getItems()).done(function (data) {
}
function getCopyFromValue() {
return $('input[type="text"][name="from"]', "#createItem").val();
return copyFromInput.value;
}
function isItemNameEmpty() {
var itemName = $('input[name="name"]', "#createItem").val();
return itemName === "" ? true : false;
var itemName = nameInput.value;
return itemName.trim() === "";
}
function getFieldValidationStatus(fieldId) {
return $("#" + fieldId).data("valid");
return document.querySelector("#" + fieldId)?.dataset.valid === "true";
}
function setFieldValidationStatus(fieldId, status) {
$("#" + fieldId).data("valid", status);
const element = document.querySelector("#" + fieldId);
if (element) {
element.dataset.valid = status;
}
}
function activateValidationMessage(messageId, context, message) {
if (message !== undefined && message !== "") {
$(messageId, context).text("» " + message);
document.querySelector(context + " " + messageId).textContent =
"» " + message;
}
cleanValidationMessages(context);
$(messageId).removeClass("input-message-disabled");
enableSubmit(false);
document
.querySelector(messageId)
.classList.remove("input-message-disabled");
refreshSubmitButtonState();
}
function cleanValidationMessages(context) {
$(context)
.find(".input-validation-message")
.addClass("input-message-disabled");
document
.querySelectorAll(context + " .input-validation-message")
.forEach((element) => element.classList.add("input-message-disabled"));
}
function enableSubmit(status) {
var btn = $(".bottom-sticker-inner button[type=submit]");
if (status === true) {
if (btn.hasClass("disabled")) {
btn.removeClass("disabled");
btn.prop("disabled", false);
}
} else {
if (!btn.hasClass("disabled")) {
btn.addClass("disabled");
btn.prop("disabled", true);
}
}
function refreshSubmitButtonState() {
const submitButton = document.querySelector(
".bottom-sticker-inner button[type=submit]",
);
submitButton.disabled = !getFormValidationStatus();
}
function getFormValidationStatus() {
@ -95,19 +96,23 @@ $.when(getItems()).done(function (data) {
}
function cleanItemSelection() {
$(".categories").find('li[role="radio"]').attr("aria-checked", "false");
$("#createItem")
.find('input[type="radio"][name="mode"]')
.removeAttr("checked");
$(".categories").find(".active").removeClass("active");
document
.querySelector('.categories li[role="radio"]')
.setAttribute("aria-checked", "false");
document
.querySelector('#createItem input[type="radio"][name="mode"]')
.removeAttribute("checked");
document.querySelectorAll(".categories .active").forEach((item) => {
item.classList.remove("active");
});
setFieldValidationStatus("items", false);
}
function cleanCopyFromOption() {
$("#createItem")
.find('input[type="radio"][value="copy"]')
.removeAttr("checked");
$('input[type="text"][name="from"]', "#createItem").val("");
copyRadio?.removeAttribute("checked");
if (copyFromInput) {
copyFromInput.value = "";
}
setFieldValidationStatus("from", false);
}
@ -115,16 +120,18 @@ $.when(getItems()).done(function (data) {
// Draw functions
function drawCategory(category) {
var $category = $("<div/>")
.addClass("category")
.attr("id", "j-add-item-type-" + cleanClassName(category.id));
var $items = $("<ul/>").addClass("j-item-options");
var $catHeader = $('<div class="header" />');
var $category = createElementFromHtml("<div class='category' />");
$category.setAttribute(
"id",
"j-add-item-type-" + cleanClassName(category.id),
);
var $items = createElementFromHtml(`<ul class="j-item-options" />`);
var $catHeader = createElementFromHtml(`<div class="header" />`);
var title = "<h2>" + category.name + "</h2>";
var description = "<p>" + category.description + "</p>";
// Add items
$.each(category.items, function (i, elem) {
category.items.forEach((elem) => {
$items.append(drawItem(elem));
});
@ -169,17 +176,13 @@ $.when(getItems()).done(function (data) {
cleanCopyFromOption();
cleanItemSelection();
$(this).attr("aria-checked", "true");
$(this).find('input[type="radio"][name="mode"]').prop("checked", true);
$(this).addClass("active");
item.setAttribute("aria-checked", "true");
radio.checked = true;
item.classList.add("active");
setFieldValidationStatus("items", true);
if (!getFieldValidationStatus("name")) {
$('input[name="name"][type="text"]', "#createItem").focus();
} else {
if (getFormValidationStatus()) {
enableSubmit(true);
}
if (getFieldValidationStatus("name")) {
refreshSubmitButtonState();
}
}
@ -253,98 +256,106 @@ $.when(getItems()).done(function (data) {
}
// The main panel content is hidden by default via an inline style. We're ready to remove that now.
$("#add-item-panel").removeAttr("style");
document.querySelector("#add-item-panel").removeAttribute("style");
// Render all categories
var $categories = $("div.categories");
$.each(data.categories, function (i, elem) {
drawCategory(elem).appendTo($categories);
var $categories = document.querySelector("div.categories");
data.categories.forEach((elem) => {
$categories.append(drawCategory(elem));
});
// Focus
$("#add-item-panel").find("#name").focus();
document.querySelector("#add-item-panel #name").focus();
// Init NameField
$('input[name="name"]', "#createItem").on("blur input", function () {
function nameFieldEvent() {
if (!isItemNameEmpty()) {
var itemName = $('input[name="name"]', "#createItem").val();
$.get("checkJobName", { value: itemName }).done(function (data) {
var message = parseResponseFromCheckJobName(data);
if (message !== "") {
activateValidationMessage(
"#itemname-invalid",
".add-item-name",
message,
);
} else {
cleanValidationMessages(".add-item-name");
setFieldValidationStatus("name", true);
if (getFormValidationStatus()) {
enableSubmit(true);
}
}
});
var itemName = nameInput.value;
fetch(`checkJobName?value=${encodeURIComponent(itemName)}`).then(
(response) => {
response.text().then((data) => {
var message = parseResponseFromCheckJobName(data);
if (message !== "") {
activateValidationMessage(
"#itemname-invalid",
".add-item-name",
message,
);
} else {
cleanValidationMessages(".add-item-name");
setFieldValidationStatus("name", true);
refreshSubmitButtonState();
}
});
},
);
} else {
enableSubmit(false);
setFieldValidationStatus("name", false);
cleanValidationMessages(".add-item-name");
activateValidationMessage("#itemname-required", ".add-item-name");
refreshSubmitButtonState();
}
});
}
nameInput.addEventListener("blur", nameFieldEvent);
nameInput.addEventListener("input", nameFieldEvent);
// Init CopyFromField
$('input[name="from"]', "#createItem").on("blur input", function () {
function copyFromFieldEvent() {
if (getCopyFromValue() === "") {
$("#createItem")
.find('input[type="radio"][value="copy"]')
.removeAttr("checked");
copyRadio.removeAttribute("checked");
} else {
cleanItemSelection();
$("#createItem")
.find('input[type="radio"][value="copy"]')
.prop("checked", true);
copyRadio.setAttribute("checked", true);
setFieldValidationStatus("from", true);
if (!getFieldValidationStatus("name")) {
activateValidationMessage("#itemname-required", ".add-item-name");
setTimeout(function () {
var parentName = $('input[name="from"]', "#createItem").val();
$.get("job/" + parentName + "/api/json?tree=name").done(
function (data) {
if (data.name === parentName) {
//if "name" is invalid, but "from" is a valid job, then switch focus to "name"
$('input[name="name"][type="text"]', "#createItem").focus();
}
var parentName = copyFromInput.value;
fetch("job/" + parentName + "/api/json?tree=name").then(
(response) => {
response.json().then((data) => {
if (data.name === parentName) {
//if "name" is invalid, but "from" is a valid job, then switch focus to "name"
nameInput.focus();
}
});
},
);
}, 400);
} else {
if (getFormValidationStatus()) {
enableSubmit(true);
}
refreshSubmitButtonState();
}
}
});
}
copyFromInput?.addEventListener("blur", copyFromFieldEvent);
copyFromInput?.addEventListener("input", copyFromFieldEvent);
// Client-side validation
$("#createItem").submit(function (event) {
if (!getFormValidationStatus()) {
event.preventDefault();
if (!getFieldValidationStatus("name")) {
activateValidationMessage("#itemname-required", ".add-item-name");
$('input[name="name"][type="text"]', "#createItem").focus();
} else {
if (
!getFieldValidationStatus("items") &&
!getFieldValidationStatus("from")
) {
activateValidationMessage("#itemtype-required", ".add-item-name");
$('input[name="name"][type="text"]', "#createItem").focus();
document
.querySelector("#createItem")
.addEventListener("submit", function (event) {
if (!getFormValidationStatus()) {
event.preventDefault();
if (!getFieldValidationStatus("name")) {
activateValidationMessage("#itemname-required", ".add-item-name");
nameInput.focus();
} else {
if (
!getFieldValidationStatus("items") &&
!getFieldValidationStatus("from")
) {
activateValidationMessage("#itemtype-required", ".add-item-name");
nameInput.focus();
}
}
}
}
});
});
// Disable the submit button
enableSubmit(false);
refreshSubmitButtonState();
});
});

View File

@ -31,11 +31,12 @@ $semantics: (
:root,
.app-theme-picker__picker[data-theme="none"] {
// Font related properties
--font-family-sans: system-ui, "Segoe UI", roboto, "Noto Sans", oxygen,
ubuntu, cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", arial,
sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
--font-family-mono: ui-monospace, sfmono-regular, sf mono, jetbrainsmono,
consolas, monospace;
--font-family-sans:
system-ui, "Segoe UI", roboto, "Noto Sans", oxygen, ubuntu, cantarell,
"Fira Sans", "Droid Sans", "Helvetica Neue", arial, sans-serif,
"Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
--font-family-mono:
ui-monospace, sfmono-regular, sf mono, jetbrainsmono, consolas, monospace;
--font-size-base: 1rem; // 16px
--font-size-sm: 0.875rem; // 14px
--font-size-xs: 0.75rem; // 12px
@ -212,23 +213,24 @@ $semantics: (
// Tooltips
--tooltip-backdrop-filter: saturate(2) blur(20px);
--tooltip-color: var(--text-color);
--tooltip-box-shadow: 0 0 8px 2px rgb(0 0 50 / 0.05),
var(--jenkins-border--subtle-shadow), 0 10px 50px rgb(0 0 20 / 0.1);
--tooltip-box-shadow:
0 0 8px 2px rgb(0 0 50 / 0.05), var(--jenkins-border--subtle-shadow),
0 10px 50px rgb(0 0 20 / 0.1);
// Dropdowns
--dropdown-backdrop-filter: saturate(1.5) blur(20px);
--dropdown-box-shadow: var(--jenkins-border--subtle-shadow),
0 10px 30px rgb(0 0 20 / 0.1), 0 2px 10px rgb(0 0 20 / 0.05),
inset 0 -1px 2px rgb(255 255 255 / 0.025);
--dropdown-box-shadow:
var(--jenkins-border--subtle-shadow), 0 10px 30px rgb(0 0 20 / 0.1),
0 2px 10px rgb(0 0 20 / 0.05), inset 0 -1px 2px rgb(255 255 255 / 0.025);
// Dialogs
::backdrop {
--dialog-backdrop-background: hsl(240 10% 20% / 0.8);
}
--dialog-box-shadow: var(--jenkins-border--subtle-shadow),
0 10px 40px rgb(0 0 20 / 0.15), 0 2px 15px rgb(0 0 20 / 0.05),
inset 0 0 2px 2px rgb(255 255 255 / 0.025);
--dialog-box-shadow:
var(--jenkins-border--subtle-shadow), 0 10px 40px rgb(0 0 20 / 0.15),
0 2px 15px rgb(0 0 20 / 0.05), inset 0 0 2px 2px rgb(255 255 255 / 0.025);
// Dark link
--link-dark-color: var(--text-color);

View File

@ -55,11 +55,8 @@
&::before {
background-color: var(--color);
background-image: radial-gradient(
at 40% 20%,
hsl(28 100% 74% / 1) 0,
transparent 50%
),
background-image:
radial-gradient(at 40% 20%, hsl(28 100% 74% / 1) 0, transparent 50%),
radial-gradient(at 80% 0%, hsl(189 100% 56% / 1) 0, transparent 50%),
radial-gradient(at 0% 50%, hsl(355 85% 93% / 1) 0, transparent 50%),
radial-gradient(at 80% 50%, hsl(359 70% 46%) 0, transparent 50%),
@ -71,11 +68,8 @@
}
&::after {
background-image: radial-gradient(
at 40% 20%,
hsl(212 100% 74% / 1) 0,
transparent 50%
),
background-image:
radial-gradient(at 40% 20%, hsl(212 100% 74% / 1) 0, transparent 50%),
radial-gradient(at 80% 0%, hsl(13 100% 56% / 1) 0, transparent 50%),
radial-gradient(at 0% 50%, hsl(179 85% 93% / 1) 0, transparent 50%),
radial-gradient(at 80% 50%, hsl(164 100% 76% / 1) 0, transparent 50%),

View File

@ -45,11 +45,8 @@
}
&::before {
background-image: radial-gradient(
at 40% 20%,
var(--orange) 0,
transparent 50%
),
background-image:
radial-gradient(at 40% 20%, var(--orange) 0, transparent 50%),
radial-gradient(at 80% 0%, var(--cyan) 0, transparent 50%),
radial-gradient(at 0% 50%, var(--light-pink) 0, transparent 50%),
radial-gradient(at 80% 50%, var(--light-red) 0, transparent 50%),
@ -59,11 +56,8 @@
}
&::after {
background-image: radial-gradient(
at 40% 20%,
var(--light-cyan) 0,
transparent 50%
),
background-image:
radial-gradient(at 40% 20%, var(--light-cyan) 0, transparent 50%),
radial-gradient(at 80% 0%, var(--dark-orange) 0, transparent 50%),
radial-gradient(at 0% 50%, var(--light-blue) 0, transparent 50%),
radial-gradient(at 80% 50%, var(--light-green) 0, transparent 50%),

View File

@ -360,7 +360,7 @@ THE SOFTWARE.
<!-- dependency of junit and echarts-api -->
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>jackson2-api</artifactId>
<version>2.17.0-379.v02de8ec9f64c</version>
<version>2.17.0-386.vcb_b_037da_0d62</version>
<type>hpi</type>
</artifactItem>
<artifactItem>
@ -691,8 +691,8 @@ THE SOFTWARE.
<javax.xml.transform.TransformerFactory>com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl</javax.xml.transform.TransformerFactory>
</systemProperties>
<webApp>
<!-- Enable nicer console logging. -->
<extraClasspath>${project.build.directory}/support-log-formatter.jar</extraClasspath>
<!-- Allow resources to be reloaded and enable nicer console logging. -->
<extraClasspath>${project.basedir}/../core/src/main/resources,${project.build.directory}/support-log-formatter.jar</extraClasspath>
<contextPath>${contextPath}</contextPath>
<webInfIncludeJarPattern>.*(jenkins-core|target/classes).*</webInfIncludeJarPattern>
</webApp>

View File

@ -3541,9 +3541,9 @@ __metadata:
languageName: node
linkType: hard
"eslint@npm:9.20.0":
version: 9.20.0
resolution: "eslint@npm:9.20.0"
"eslint@npm:9.20.1":
version: 9.20.1
resolution: "eslint@npm:9.20.1"
dependencies:
"@eslint-community/eslint-utils": "npm:^4.2.0"
"@eslint-community/regexpp": "npm:^4.12.1"
@ -3586,7 +3586,7 @@ __metadata:
optional: true
bin:
eslint: bin/eslint.js
checksum: 10c0/5eb2d9b5ed85a0b022871d19719417d110afb07a4abfedd856ad03d9a821def5f6bc31d7c407ca27f56e5e66e39375300fd2b877017245eb99c44060d6c983bd
checksum: 10c0/056789dd5a00897730376f8c0a191e22840e97b7276916068ec096341cb2ec3a918c8bd474bf94ccd7b457ad9fbc16e5c521a993c7cc6ebcf241933e2fd378b0
languageName: node
linkType: hard
@ -3987,10 +3987,10 @@ __metadata:
languageName: node
linkType: hard
"globals@npm:15.14.0":
version: 15.14.0
resolution: "globals@npm:15.14.0"
checksum: 10c0/039deb8648bd373b7940c15df9f96ab7508fe92b31bbd39cbd1c1a740bd26db12457aa3e5d211553b234f30e9b1db2fee3683012f543a01a6942c9062857facb
"globals@npm:15.15.0":
version: 15.15.0
resolution: "globals@npm:15.15.0"
checksum: 10c0/f9ae80996392ca71316495a39bec88ac43ae3525a438b5626cd9d5ce9d5500d0a98a266409605f8cd7241c7acf57c354a48111ea02a767ba4f374b806d6861fe
languageName: node
linkType: hard
@ -4403,21 +4403,21 @@ __metadata:
clean-webpack-plugin: "npm:4.0.0"
css-loader: "npm:7.1.2"
css-minimizer-webpack-plugin: "npm:7.0.0"
eslint: "npm:9.20.0"
eslint: "npm:9.20.1"
eslint-config-prettier: "npm:10.0.1"
eslint-formatter-checkstyle: "npm:8.40.0"
globals: "npm:15.14.0"
globals: "npm:15.15.0"
handlebars: "npm:4.7.8"
handlebars-loader: "npm:1.7.3"
hotkeys-js: "npm:3.12.2"
jquery: "npm:3.7.1"
lodash: "npm:4.17.21"
mini-css-extract-plugin: "npm:2.9.2"
postcss: "npm:8.5.1"
postcss: "npm:8.5.2"
postcss-loader: "npm:8.1.1"
postcss-preset-env: "npm:10.1.3"
postcss-scss: "npm:4.0.9"
prettier: "npm:3.4.2"
prettier: "npm:3.5.0"
sass: "npm:1.84.0"
sass-loader: "npm:16.0.4"
sortablejs: "npm:1.15.6"
@ -6143,14 +6143,14 @@ __metadata:
languageName: node
linkType: hard
"postcss@npm:8.5.1, postcss@npm:^8.4.33, postcss@npm:^8.4.38, postcss@npm:^8.5.1":
version: 8.5.1
resolution: "postcss@npm:8.5.1"
"postcss@npm:8.5.2, postcss@npm:^8.4.33, postcss@npm:^8.4.38, postcss@npm:^8.5.1":
version: 8.5.2
resolution: "postcss@npm:8.5.2"
dependencies:
nanoid: "npm:^3.3.8"
picocolors: "npm:^1.1.1"
source-map-js: "npm:^1.2.1"
checksum: 10c0/c4d90c59c98e8a0c102b77d3f4cac190f883b42d63dc60e2f3ed840f16197c0c8e25a4327d2e9a847b45a985612317dc0534178feeebd0a1cf3eb0eecf75cae4
checksum: 10c0/3044d49bc725029ab62292e8bf9849741251b95f3b754e191bf8b4025414d40ec3b4ac05c5a563d4b50060b5c8e96683eb4d783d8d8fa3867eb7b763cbe66127
languageName: node
linkType: hard
@ -6161,12 +6161,12 @@ __metadata:
languageName: node
linkType: hard
"prettier@npm:3.4.2":
version: 3.4.2
resolution: "prettier@npm:3.4.2"
"prettier@npm:3.5.0":
version: 3.5.0
resolution: "prettier@npm:3.5.0"
bin:
prettier: bin/prettier.cjs
checksum: 10c0/99e076a26ed0aba4ebc043880d0f08bbb8c59a4c6641cdee6cdadf2205bdd87aa1d7823f50c3aea41e015e99878d37c58d7b5f0e663bba0ef047f94e36b96446
checksum: 10c0/6c355d74c377f5622953229d92477e8b9779162e848db90fd7e06c431deb73585d31fafc4516cf5868917825b97b9ec7c87c8d8b8e03ccd9fc9c0b7699d1a650
languageName: node
linkType: hard