diff --git a/core/src/main/java/hudson/model/ManageJenkinsAction.java b/core/src/main/java/hudson/model/ManageJenkinsAction.java index b67dfd078716..c6c37a57662a 100644 --- a/core/src/main/java/hudson/model/ManageJenkinsAction.java +++ b/core/src/main/java/hudson/model/ManageJenkinsAction.java @@ -48,7 +48,10 @@ public class ManageJenkinsAction implements RootAction, StaplerFallback, ModelObjectWithContextMenu { @Override public String getIconFileName() { - return null; + if (Jenkins.get().hasAnyPermission(Jenkins.MANAGE, Jenkins.SYSTEM_READ)) + return "symbol-settings"; + else + return null; } @Override diff --git a/core/src/main/java/jenkins/model/Jenkins.java b/core/src/main/java/jenkins/model/Jenkins.java index afffe5122227..6e56858395b1 100644 --- a/core/src/main/java/jenkins/model/Jenkins.java +++ b/core/src/main/java/jenkins/model/Jenkins.java @@ -114,6 +114,7 @@ import hudson.model.ListView; import hudson.model.LoadBalancer; import hudson.model.LoadStatistics; +import hudson.model.ManageJenkinsAction; import hudson.model.ManagementLink; import hudson.model.Messages; import hudson.model.ModifiableViewGroup; @@ -4509,6 +4510,12 @@ public void doException() { @Override public ContextMenu doContextMenu(StaplerRequest request, StaplerResponse response) throws IOException, JellyException { ContextMenu menu = new ContextMenu().from(this, request, response); + for (MenuItem i : menu.items) { + if (i.url.equals(request.getContextPath() + "/manage")) { + // add "Manage Jenkins" subitems + i.subMenu = new ContextMenu().from(ExtensionList.lookupSingleton(ManageJenkinsAction.class), request, response, "index"); + } + } return menu; } diff --git a/core/src/main/resources/hudson/model/ManageJenkinsAction/index.jelly b/core/src/main/resources/hudson/model/ManageJenkinsAction/index.jelly index f01040649cc7..a345052bc588 100644 --- a/core/src/main/resources/hudson/model/ManageJenkinsAction/index.jelly +++ b/core/src/main/resources/hudson/model/ManageJenkinsAction/index.jelly @@ -27,7 +27,12 @@ THE SOFTWARE. --> - + + + + + + diff --git a/core/src/main/resources/hudson/model/View/AsynchPeople/index.jelly b/core/src/main/resources/hudson/model/View/AsynchPeople/index.jelly index 8d36211806d5..9775d4bba2f4 100644 --- a/core/src/main/resources/hudson/model/View/AsynchPeople/index.jelly +++ b/core/src/main/resources/hudson/model/View/AsynchPeople/index.jelly @@ -24,7 +24,8 @@ THE SOFTWARE. - + + diff --git a/core/src/main/resources/jenkins/management/AdministrativeMonitorsDecorator/footer.jelly b/core/src/main/resources/jenkins/management/AdministrativeMonitorsDecorator/footer.jelly new file mode 100644 index 000000000000..ff40bc54365c --- /dev/null +++ b/core/src/main/resources/jenkins/management/AdministrativeMonitorsDecorator/footer.jelly @@ -0,0 +1,71 @@ + + + + + + + + + + + + + +
+ + + + +
+ + + + + + diff --git a/core/src/main/resources/jenkins/management/AdministrativeMonitorsDecorator/footer.properties b/core/src/main/resources/jenkins/management/AdministrativeMonitorsDecorator/footer.properties new file mode 100644 index 000000000000..59c787763b8e --- /dev/null +++ b/core/src/main/resources/jenkins/management/AdministrativeMonitorsDecorator/footer.properties @@ -0,0 +1,2 @@ +tooltip=There are {0} active administrative monitors. +tooltipSec=There are {0} active security administrative monitors. diff --git a/core/src/main/resources/jenkins/management/AdministrativeMonitorsDecorator/footer_bg.properties b/core/src/main/resources/jenkins/management/AdministrativeMonitorsDecorator/footer_bg.properties new file mode 100644 index 000000000000..53275bc89bc7 --- /dev/null +++ b/core/src/main/resources/jenkins/management/AdministrativeMonitorsDecorator/footer_bg.properties @@ -0,0 +1,27 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2017, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +# There are {0} active administrative monitors. +tooltip=\ + В момента има {0} предупреждения. +Manage\ Jenkins=\ + Управление на Jenkins diff --git a/core/src/main/resources/jenkins/management/AdministrativeMonitorsDecorator/footer_de.properties b/core/src/main/resources/jenkins/management/AdministrativeMonitorsDecorator/footer_de.properties new file mode 100644 index 000000000000..df9d5a8ab8ff --- /dev/null +++ b/core/src/main/resources/jenkins/management/AdministrativeMonitorsDecorator/footer_de.properties @@ -0,0 +1,24 @@ +# The MIT License +# +# Copyright (c) 2017 Daniel Beck and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Manage\ Jenkins=Jenkins verwalten +tooltip={0,choice,0#Keine Administrator-Warnungen sind|1#{0} Administrator-Warnung ist|1<{0} Administrator-Warnungen sind} aktiv. diff --git a/core/src/main/resources/jenkins/management/AdministrativeMonitorsDecorator/footer_it.properties b/core/src/main/resources/jenkins/management/AdministrativeMonitorsDecorator/footer_it.properties new file mode 100644 index 000000000000..9967613a7191 --- /dev/null +++ b/core/src/main/resources/jenkins/management/AdministrativeMonitorsDecorator/footer_it.properties @@ -0,0 +1,25 @@ +# The MIT License +# +# Italian localization plugin for Jenkins +# Copyright © 2020 Alessandro Menti +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Manage\ Jenkins=Gestisci Jenkins +tooltip=Ci sono {0} monitor amministrativi attivi. diff --git a/core/src/main/resources/jenkins/management/AdministrativeMonitorsDecorator/footer_pl.properties b/core/src/main/resources/jenkins/management/AdministrativeMonitorsDecorator/footer_pl.properties new file mode 100644 index 000000000000..963548d361c7 --- /dev/null +++ b/core/src/main/resources/jenkins/management/AdministrativeMonitorsDecorator/footer_pl.properties @@ -0,0 +1,24 @@ +# The MIT License +# +# Copyright (c) 2016-2017, Damian Szczepanik +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. +# There are {0} active administrative monitors. +tooltip=Znaleziono {0} aktywnych powiadomień dla administratorów +Manage\ Jenkins=Zarządzaj Jenkinsem diff --git a/core/src/main/resources/jenkins/management/AdministrativeMonitorsDecorator/footer_pt_BR.properties b/core/src/main/resources/jenkins/management/AdministrativeMonitorsDecorator/footer_pt_BR.properties new file mode 100644 index 000000000000..103fb02ed797 --- /dev/null +++ b/core/src/main/resources/jenkins/management/AdministrativeMonitorsDecorator/footer_pt_BR.properties @@ -0,0 +1,24 @@ +# The MIT License +# +# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +tooltip=Existem {0} monitores administrativos ativos. +tooltipSec=Existem {0} monitores administrativos de segurança ativos. diff --git a/core/src/main/resources/jenkins/management/AdministrativeMonitorsDecorator/footer_tr.properties b/core/src/main/resources/jenkins/management/AdministrativeMonitorsDecorator/footer_tr.properties new file mode 100644 index 000000000000..8447c064c4aa --- /dev/null +++ b/core/src/main/resources/jenkins/management/AdministrativeMonitorsDecorator/footer_tr.properties @@ -0,0 +1,25 @@ +# The MIT License +# +# Copyright (c) 2021, Mustafa Ulu +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Manage\ Jenkins=Jenkins''i Yönet +tooltip={0} adet aktif yönetimsel gösterge var. +tooltipSec={0} adet aktif yönetimsel güvenlik göstergesi var. diff --git a/core/src/main/resources/jenkins/management/AdministrativeMonitorsDecorator/footer_zh_TW.properties b/core/src/main/resources/jenkins/management/AdministrativeMonitorsDecorator/footer_zh_TW.properties new file mode 100644 index 000000000000..8fb68379da9f --- /dev/null +++ b/core/src/main/resources/jenkins/management/AdministrativeMonitorsDecorator/footer_zh_TW.properties @@ -0,0 +1,2 @@ +tooltip=有 {0} 個啟用中的管理監視器。 +tooltipSec=有 {0} 個啟用中的安全性管理監視器。 diff --git a/core/src/main/resources/jenkins/management/AdministrativeMonitorsDecorator/resources.css b/core/src/main/resources/jenkins/management/AdministrativeMonitorsDecorator/resources.css new file mode 100644 index 000000000000..5960ecd93193 --- /dev/null +++ b/core/src/main/resources/jenkins/management/AdministrativeMonitorsDecorator/resources.css @@ -0,0 +1,182 @@ +.am-container { + height: 100%; +} + +.am-button { + position: relative; +} + +.am-button .am-monitor__indicator-mobile { + display: none; + position: absolute; + top: 0.25rem; + right: 0.25rem; + border-radius: 50%; + width: 0.65rem; + height: 0.65rem; + background-color: #ff9800; +} +.security-am .am-monitor__indicator-mobile { + background-color: #dc3545; +} + +.am-button .am-monitor__count { + display: inline-block; + display: inline-flex; + justify-content: center; + align-items: center; + height: 20px; + min-width: 20px; + + color: #fff; + background-color: #ff9800; + font-weight: bold; + + border-radius: 4px; +} +.am-button.security-am .am-monitor__count { + color: #fff; + background-color: #dc3545; +} +.am-container div.am-list { + position: absolute; + top: 48px; + right: 2%; + height: auto; + z-index: 0; + padding: 2em; + text-align: left; + display: block; + background-color: #fff; + background-color: var(--background); + border-radius: 5px; + + /* Darken the box shadow to make the popup visible over the search box */ + box-shadow: 0 1px 7px 0 rgba(0, 0, 0, 0.3); + + transition: all 0.15s cubic-bezier(0.84, 0.03, 0.21, 0.96); + opacity: 0; + transform: scale(0); +} +.am-container.visible div.am-list { + opacity: 1; + transform: scale(1); + z-index: 1000; +} +.am-container.visible .am-button { + background-color: #404040; + background-color: var(--header-link-bg-classic-active); + text-decoration: none; +} +.am-container .am-button:after { + content: ""; + display: inline-block; + position: absolute; + bottom: 0; + left: 32%; + width: 0; + height: 0; + border-left: 7px solid transparent; + border-right: 7px solid transparent; + border-bottom: 7px solid #fff; + opacity: 0; + transition-property: all; + transition-delay: 0s; + z-index: 1001; +} +.am-container.visible .am-button:after { + opacity: 1; + transition-property: all; + transition-delay: 0.15s; +} +.am-container .am-message { + display: block; + line-height: 1.4em; + margin-bottom: 1.4em; +} + +.am-message-list { + padding: 0; +} + +.am-container .am-message .alert form { + position: relative; + float: right; + margin: -6px 0 0 0 !important; + gap: 0.5rem; + display: flex; + padding-left: 0.5rem; +} + +.am-container .am-message .alert form span { + margin: 0 0 0 4px !important; +} + +.am-container .am-message .alert { + margin-bottom: 0 !important; +} + +.am-container .am-message dl dt::after { + content: ": "; +} + +/* Restore hyperlink style overriden by the page header */ +.am-container .am-list a:link { + display: inline-block; + color: #204a87; + color: var(--link-color); + text-decoration: underline; + margin-right: 0; + padding: 0; + font-weight: 600; + font-weight: var(--link-font-weight); +} +.am-container .am-list a:visited { + color: #5c3566; + color: var(--link-color); +} +.am-container .am-list a:hover, +.am-container .am-list a:focus, +.am-container .am-list a:active { + color: #5c3566; + color: var(--link-color); + background-color: transparent; + text-decoration: underline; + text-decoration: var(--link-text-decoration--hover); +} + +.am-container .am-list .alert-success a { + color: #155724; + color: var(--alert-success-text-color); +} + +.am-container .am-list .alert-info a { + color: #31708f; + color: var(--alert-info-text-color); +} + +.am-container .am-list .alert-warning a { + color: #8a6d3b; + color: var(--alert-warning-text-color); +} + +.am-container .am-list .alert-danger a { + color: #a94442; + color: var(--alert-danger-text-color); +} + +@media screen and (max-width: 576px) { + /* Hide non-security monitors on mobile view to avoid messing up the heading */ + #visible-am-container { + display: none; + } +} + +@media screen and (max-width: 768px) { + .am-button .am-monitor__indicator-mobile { + display: block; + } + .am-button .am-monitor__count { + display: none; + } +} diff --git a/core/src/main/resources/jenkins/management/AdministrativeMonitorsDecorator/resources.js b/core/src/main/resources/jenkins/management/AdministrativeMonitorsDecorator/resources.js new file mode 100644 index 000000000000..7278b6021ddf --- /dev/null +++ b/core/src/main/resources/jenkins/management/AdministrativeMonitorsDecorator/resources.js @@ -0,0 +1,124 @@ +(function () { + function initializeAmMonitor(amMonitorRoot, options) { + var button = amMonitorRoot.querySelector(".am-button"); + var amList = amMonitorRoot.querySelector(".am-list"); + if (button === null || amList === null) { + return null; + } + + var url = button.getAttribute("data-href"); + + function onClose(e) { + var list = amList; + var el = e.target; + while (el) { + if (el === list) { + return; // clicked in the list + } + el = el.parentElement; + } + close(); + } + + function onEscClose(e) { + var escapeKeyCode = 27; + if (e.keyCode === escapeKeyCode) { + close(); + } + } + + function show() { + if (options.closeAll) { + options.closeAll(); + } + + fetch(url).then((rsp) => { + if (rsp.ok) { + rsp.text().then((responseText) => { + var popupContent = responseText; + amList.innerHTML = popupContent; + amMonitorRoot.classList.add("visible"); + document.addEventListener("click", onClose); + document.addEventListener("keydown", onEscClose); + + // Applies all initialization code to the elements within the popup + // Among other things, this sets the CSRF crumb to the forms within + Behaviour.applySubtree(amList); + }); + } + }); + } + + function close() { + amMonitorRoot.classList.remove("visible"); + document.removeEventListener("click", onClose); + document.removeEventListener("keydown", onEscClose); + } + + function toggle(e) { + if (amMonitorRoot.classList.contains("visible")) { + close(); + } else { + show(); + } + e.preventDefault(); + } + + function startListeners() { + button.addEventListener("click", toggle); + } + + return { + close: close, + startListeners: startListeners, + }; + } + + document.addEventListener("DOMContentLoaded", function () { + var monitorWidgets; + + function closeAll() { + monitorWidgets.forEach(function (widget) { + widget.close(); + }); + } + + var normalMonitors = initializeAmMonitor( + document.getElementById("visible-am-container"), + { + closeAll: closeAll, + }, + ); + var securityMonitors = initializeAmMonitor( + document.getElementById("visible-sec-am-container"), + { + closeAll: closeAll, + }, + ); + monitorWidgets = [normalMonitors, securityMonitors].filter( + function (widget) { + return widget !== null; + }, + ); + + monitorWidgets.forEach(function (widget) { + widget.startListeners(); + }); + }); +})(); + +document.addEventListener("DOMContentLoaded", function () { + var amContainer = document.getElementById("visible-am-container"); + var amInsertion = document.getElementById("visible-am-insertion"); + + if (amInsertion) { + amInsertion.appendChild(amContainer); + } + + var secAmContainer = document.getElementById("visible-sec-am-container"); + var secAmInsertion = document.getElementById("visible-sec-am-insertion"); + + if (secAmInsertion) { + secAmInsertion.appendChild(secAmContainer); + } +});