mirror of https://github.com/jenkinsci/jenkins.git
Merge branch 'master' into new-buttons-1-dashboard
This commit is contained in:
commit
1fa24ea550
|
@ -25,8 +25,18 @@
|
|||
package hudson.model;
|
||||
|
||||
import hudson.Extension;
|
||||
import hudson.Util;
|
||||
import java.io.IOException;
|
||||
import jenkins.model.Jenkins;
|
||||
import jenkins.model.ModelObjectWithContextMenu;
|
||||
import org.apache.commons.jelly.JellyException;
|
||||
import org.jenkinsci.Symbol;
|
||||
import org.kohsuke.accmod.Restricted;
|
||||
import org.kohsuke.accmod.restrictions.NoExternalUse;
|
||||
import org.kohsuke.stapler.Stapler;
|
||||
import org.kohsuke.stapler.StaplerFallback;
|
||||
import org.kohsuke.stapler.StaplerRequest;
|
||||
import org.kohsuke.stapler.StaplerResponse;
|
||||
|
||||
/**
|
||||
* Adds the "Manage Jenkins" link to the top page.
|
||||
|
@ -34,7 +44,7 @@ import org.jenkinsci.Symbol;
|
|||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
@Extension(ordinal = 100) @Symbol("manageJenkins")
|
||||
public class ManageJenkinsAction implements RootAction {
|
||||
public class ManageJenkinsAction implements RootAction, StaplerFallback, ModelObjectWithContextMenu {
|
||||
@Override
|
||||
public String getIconFileName() {
|
||||
if (Jenkins.get().hasAnyPermission(Jenkins.MANAGE, Jenkins.SYSTEM_READ))
|
||||
|
@ -52,4 +62,29 @@ public class ManageJenkinsAction implements RootAction {
|
|||
public String getUrlName() {
|
||||
return "/manage";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getStaplerFallback() {
|
||||
return Jenkins.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ContextMenu doContextMenu(StaplerRequest request, StaplerResponse response) throws JellyException, IOException {
|
||||
return new ContextMenu().from(this, request, response, "index");
|
||||
}
|
||||
|
||||
/**
|
||||
* Workaround to ensuring that links in context menus resolve correctly in the submenu of the top-level 'Dashboard'
|
||||
* menu.
|
||||
*/
|
||||
@Restricted(NoExternalUse.class)
|
||||
public void addContextMenuItem(ContextMenu menu, String url, String icon, String iconXml, String text, boolean post, boolean requiresConfirmation) {
|
||||
if (Stapler.getCurrentRequest().findAncestorObject(this.getClass()) != null || !Util.isSafeToRedirectTo(url)) {
|
||||
// Default behavior if the URL is absolute or scheme-relative, or the current object is an ancestor (i.e. would resolve correctly)
|
||||
menu.add(url, icon, iconXml, text, post, requiresConfirmation);
|
||||
return;
|
||||
}
|
||||
// If neither is the case, rewrite the relative URL to point to inside the /manage/ URL space
|
||||
menu.add("manage/" + url, icon, iconXml, text, post, requiresConfirmation);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -115,6 +115,7 @@ import hudson.model.Label;
|
|||
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;
|
||||
|
@ -4415,7 +4416,7 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve
|
|||
for (MenuItem i : menu.items) {
|
||||
if (i.url.equals(request.getContextPath() + "/manage")) {
|
||||
// add "Manage Jenkins" subitems
|
||||
i.subMenu = new ContextMenu().from(this, request, response, "manage");
|
||||
i.subMenu = new ContextMenu().from(ExtensionList.lookupSingleton(ManageJenkinsAction.class), request, response, "index");
|
||||
}
|
||||
}
|
||||
return menu;
|
||||
|
|
|
@ -595,6 +595,8 @@ public class IconSet {
|
|||
translations.put("icon-text", "symbol-details");
|
||||
translations.put("icon-up", "symbol-arrow-up");
|
||||
translations.put("icon-user", "symbol-people");
|
||||
translations.put("icon-undo", "symbol-undo");
|
||||
translations.put("icon-redo", "symbol-redo");
|
||||
ICON_TO_SYMBOL_TRANSLATIONS = translations;
|
||||
}
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ l.side_panel {
|
|||
l.task(icon:"icon-up icon-md", href:rootURL+'/', title:_("Back to Dashboard"))
|
||||
l.task(icon:"symbol-settings", href:"${rootURL}/manage", title:_("Manage Jenkins"))
|
||||
if (!app.updateCenter.jobs.isEmpty()) {
|
||||
l.task(icon: "symbol-download", href:"${rootURL}/updateCenter/", title:_("Update Center"))
|
||||
l.task(icon: "symbol-download", href:"../updateCenter/", title:_("Update Center"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,5 +31,12 @@ THE SOFTWARE.
|
|||
<l:task contextMenu="false" href="${buildUrl.baseUrl}/" icon="symbol-details" title="${%Status}"/>
|
||||
<l:task href="${buildUrl.baseUrl}/changes" icon="symbol-changes" title="${%Changes}"/>
|
||||
<p:console-link/>
|
||||
<l:task href="${buildUrl.baseUrl}/configure" icon="symbol-settings" title="${h.hasPermission(it,it.UPDATE)?'%Edit Build Information':'%View Build Information'}"/>
|
||||
<j:choose>
|
||||
<j:when test="${h.hasPermission(it,it.UPDATE)}">
|
||||
<l:task icon="symbol-edit-note" href="${buildUrl.baseUrl}/configure" title="${%Edit Build Information}"/>
|
||||
</j:when>
|
||||
<j:otherwise>
|
||||
<l:task icon="symbol-view" href="${buildUrl.baseUrl}/configure" title="${%View Build Information}"/>
|
||||
</j:otherwise>
|
||||
</j:choose>
|
||||
</j:jelly>
|
||||
|
|
|
@ -34,7 +34,7 @@ THE SOFTWARE.
|
|||
<l:task href="${rootURL}/" icon="icon-up icon-md" title="${%Back to Dashboard}"/>
|
||||
<l:task href="${rootURL}/manage" icon="symbol-settings" permissions="${app.MANAGE_AND_SYSTEM_READ}" title="${%Manage Jenkins}"/>
|
||||
<l:task href="new" icon="symbol-add" permission="${createPermission}" title="${%New Node}"/>
|
||||
<l:task href="${rootURL}/configureClouds" icon="symbol-cloud" permission="${app.SYSTEM_READ}"
|
||||
<l:task href="../configureClouds" icon="symbol-cloud" permission="${app.SYSTEM_READ}"
|
||||
title="${app.hasPermission(app.ADMINISTER) ? '%Configure Clouds' : '%View Clouds'}"/>
|
||||
<l:task href="configure" icon="symbol-settings" permissions="${app.MANAGE_AND_SYSTEM_READ}" title="${%Node Monitoring}"/>
|
||||
</l:tasks>
|
||||
|
|
|
@ -31,7 +31,7 @@ THE SOFTWARE.
|
|||
<l:app-bar title="${%Manage Jenkins}" />
|
||||
|
||||
<j:if test="${taskTags==null}">
|
||||
<st:include page="sidepanel.jelly" />
|
||||
<st:include page="sidepanel.jelly" it="${app}" />
|
||||
</j:if>
|
||||
|
||||
<l:main-panel>
|
||||
|
@ -39,10 +39,10 @@ THE SOFTWARE.
|
|||
<j:forEach var="am" items="${app.activeAdministrativeMonitors}">
|
||||
<st:include page="message.jelly" it="${am}" />
|
||||
</j:forEach>
|
||||
<st:include page="downgrade.jelly" />
|
||||
<st:include page="downgrade.jelly" it="${app}" />
|
||||
</section>
|
||||
|
||||
<j:forEach var="category" items="${it.categorizedManagementLinks.entrySet()}">
|
||||
<j:forEach var="category" items="${app.categorizedManagementLinks.entrySet()}">
|
||||
<section class="jenkins-section jenkins-section--bottom-padding">
|
||||
<h2 class="jenkins-section__title">${category.key.label}</h2>
|
||||
${taskTags!=null and attrs.contextMenu!='false' ? taskTags.addHeader(category.key.label) : null}
|
||||
|
@ -55,7 +55,7 @@ THE SOFTWARE.
|
|||
<j:set var="iconXml">
|
||||
<l:icon src="${m.iconFileName}" />
|
||||
</j:set>
|
||||
${taskTags!=null and attrs.contextMenu!='false' ? taskTags.add(m.urlName, iconSrc, iconXml, m.displayName, m.requiresPOST, m.requiresConfirmation) : null}
|
||||
${taskTags!=null and attrs.contextMenu!='false' ? it.addContextMenuItem(taskTags, m.urlName, iconSrc, iconXml, m.displayName, m.requiresPOST, m.requiresConfirmation) : null}
|
||||
<j:choose>
|
||||
<j:when test="${m.requiresConfirmation}">
|
||||
<l:confirmationLink href="${m.urlName}" post="${m.requiresPOST}" message="${%are.you.sure(m.displayName)}">
|
|
@ -32,7 +32,7 @@ THE SOFTWARE.
|
|||
<l:tasks>
|
||||
<l:task href="${rootURL}/" icon="icon-up icon-md" title="${%Back to Dashboard}"/>
|
||||
<l:task href="${rootURL}/manage" icon="symbol-settings" title="${%Manage Jenkins}"/>
|
||||
<l:task href="${rootURL}/pluginManager/" icon="icon-plugin icon-lg" title="${%Manage Plugins}"/>
|
||||
<l:task href="../pluginManager/" icon="icon-plugin icon-lg" title="${%Manage Plugins}"/>
|
||||
</l:tasks>
|
||||
</l:side-panel>
|
||||
</j:jelly>
|
||||
|
|
|
@ -13,7 +13,7 @@ l.layout(norefresh:true, permission:app.SYSTEM_READ, title:my.displayName) {
|
|||
l.side_panel {
|
||||
l.tasks {
|
||||
l.task(icon:"icon-up icon-md", href:rootURL+'/', title:_("Back to Dashboard"))
|
||||
l.task(icon:"symbol-settings", href:"${rootURL}/computer/", title:_("Manage Nodes"))
|
||||
l.task(icon:"symbol-settings", href: "../computer/", title:_("Manage Nodes"))
|
||||
}
|
||||
}
|
||||
l.app_bar(title: my.displayName)
|
||||
|
|
|
@ -26,9 +26,10 @@ THE SOFTWARE.
|
|||
<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:layout title="${it.displayName} ${%Load Statistics}">
|
||||
<st:include page="sidepanel.jelly" />
|
||||
<l:breadcrumb title="${%Load Statistics}"/>
|
||||
<l:main-panel>
|
||||
<j:set var="prefix" value="overallLoad" />
|
||||
<st:include page="main.jelly" from="${it.overallLoad}" />
|
||||
</l:main-panel>
|
||||
</l:layout>
|
||||
</j:jelly>
|
||||
</j:jelly>
|
||||
|
|
|
@ -29,6 +29,7 @@ THE SOFTWARE.
|
|||
<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">
|
||||
<l:layout permissions="${app.MANAGE_AND_SYSTEM_READ}" title="${%System Information}">
|
||||
<st:include page="sidepanel.jelly" />
|
||||
<l:breadcrumb title="${%System Information}"/>
|
||||
<l:main-panel>
|
||||
<l:hasPermission permission="${app.SYSTEM_READ}">
|
||||
<div class="jenkins-app-bar">
|
||||
|
|
|
@ -30,6 +30,7 @@ THE SOFTWARE.
|
|||
<l:layout permission="${h.ADMINISTER}" title="${%Script Console}">
|
||||
<st:include page="sidepanel.jelly" />
|
||||
|
||||
<l:breadcrumb title="${%Script Console}"/>
|
||||
<l:main-panel>
|
||||
<h1>${%Script Console}</h1>
|
||||
|
||||
|
|
2
pom.xml
2
pom.xml
|
@ -73,7 +73,7 @@ THE SOFTWARE.
|
|||
</issueManagement>
|
||||
|
||||
<properties>
|
||||
<revision>2.359</revision>
|
||||
<revision>2.360</revision>
|
||||
<changelist>-SNAPSHOT</changelist>
|
||||
|
||||
<!-- *.html files are in UTF-8, and *.properties are in iso-8859-1, so this configuration is actually incorrect,
|
||||
|
|
|
@ -90,7 +90,7 @@ THE SOFTWARE.
|
|||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>jenkins-test-harness</artifactId>
|
||||
<version>1797.v711534844e8a_</version>
|
||||
<version>1802.v9de0d87365d2</version>
|
||||
<scope>test</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
|
|
|
@ -86,7 +86,7 @@ public class Jenkins64991Test {
|
|||
|
||||
final Page redirectedPage = HtmlFormUtil.submit(loginPage.getFormByName("login"));
|
||||
assertTrue(redirectedPage.isHtmlPage());
|
||||
assertEquals(j.getURL() + "manage", redirectedPage.getUrl().toExternalForm());
|
||||
assertEquals(j.getURL() + "manage/", redirectedPage.getUrl().toExternalForm());
|
||||
assertThat(redirectedPage.getWebResponse().getContentAsString(), containsStringIgnoringCase(Messages.GlobalSecurityConfiguration_DisplayName()));
|
||||
}
|
||||
|
||||
|
|
|
@ -11,9 +11,7 @@ import com.gargoylesoftware.htmlunit.WebRequest;
|
|||
import com.gargoylesoftware.htmlunit.util.NameValuePair;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import javax.servlet.ServletException;
|
||||
|
@ -498,8 +496,6 @@ public class DoActionFilterTest extends StaplerAbstractTest {
|
|||
|
||||
public void doWithResponseImpl(ResponseImpl response) { replyOk(); }
|
||||
|
||||
public void doWithRequestAndResponse(RequestAndResponse requestAndResponse) { replyOk(); }
|
||||
|
||||
// special case to keep Groovy parameter name, but does not seem to indicate it's automatically a web method
|
||||
@CapturedParameterNames("req")
|
||||
public void doAnnotatedResponseSuccess(Object req) { replyOk(); }
|
||||
|
@ -509,21 +505,6 @@ public class DoActionFilterTest extends StaplerAbstractTest {
|
|||
// public void doAnnotatedJsonOutputFilter() { replyOk(); }
|
||||
}
|
||||
|
||||
public abstract static class RequestAndResponse implements StaplerRequest, StaplerResponse {
|
||||
@Override
|
||||
public CollectionAndEnumeration getHeaderNames() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CollectionAndEnumeration getHeaders(String name) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public abstract static class CollectionAndEnumeration implements Collection, Enumeration {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNotOkSpecialCases_withServletRequest() throws Exception {
|
||||
assertNotReachable("testNewRulesNotOkSpecialCases/withServletRequest/");
|
||||
|
@ -548,12 +529,6 @@ public class DoActionFilterTest extends StaplerAbstractTest {
|
|||
assertDoActionRequestWasBlockedAndResetFlag();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNotOkSpecialCases_withRequestAndResponse() throws Exception {
|
||||
assertNotReachable("testNewRulesNotOkSpecialCases/withRequestAndResponse/");
|
||||
assertDoActionRequestWasBlockedAndResetFlag();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNotOkSpecialCases_annotatedResponseSuccess() throws Exception {
|
||||
assertNotReachable("testNewRulesNotOkSpecialCases/annotatedResponseSuccess/");
|
||||
|
|
|
@ -26,12 +26,10 @@
|
|||
"@jenkins-cd/js-test": "^1.2.3",
|
||||
"autoprefixer": "^10.4.7",
|
||||
"clean-webpack-plugin": "^4.0.0",
|
||||
"copy-webpack-plugin": "^6.4.1",
|
||||
"css-loader": "^5.2.7",
|
||||
"css-minimizer-webpack-plugin": "^1.0.0",
|
||||
"copy-webpack-plugin": "^11.0.0",
|
||||
"css-loader": "^6.7.1",
|
||||
"css-minimizer-webpack-plugin": "^4.0.0",
|
||||
"eslint": "^8.19.0",
|
||||
"eslint-plugin-only-warn": "^1.0.3",
|
||||
"file-loader": "^6.2.0",
|
||||
"handlebars": "^3.0.8",
|
||||
"handlebars-loader": "^1.7.2",
|
||||
"jest": "^26.0.1",
|
||||
|
@ -39,16 +37,16 @@
|
|||
"jest-junit": "^14.0.0",
|
||||
"jest-standard-reporter": "^2.0.0",
|
||||
"less": "^4.1.3",
|
||||
"less-loader": "^7.3.0",
|
||||
"mini-css-extract-plugin": "^1.6.2",
|
||||
"less-loader": "^11.0.0",
|
||||
"mini-css-extract-plugin": "^2.6.1",
|
||||
"postcss": "^8.4.14",
|
||||
"postcss-loader": "^4.3.0",
|
||||
"style-loader": "^2.0.0",
|
||||
"postcss-loader": "^7.0.1",
|
||||
"style-loader": "^3.3.1",
|
||||
"stylelint": "^14.9.1",
|
||||
"stylelint-config-standard": "^26.0.0",
|
||||
"webpack": "^4.46.0",
|
||||
"webpack": "^5.73.0",
|
||||
"webpack-cli": "^4.10.0",
|
||||
"webpack-fix-style-only-entries": "^0.5.0"
|
||||
"webpack-remove-empty-scripts": "^0.8.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/preset-env": "^7.18.6",
|
||||
|
@ -56,7 +54,7 @@
|
|||
"bootstrap": "3.4.1",
|
||||
"jenkins-js-modules": "^1.5.0",
|
||||
"jquery": "3.6.0",
|
||||
"lodash": "^4.17.20",
|
||||
"lodash": "^4.17.21",
|
||||
"postcss-less": "^6.0.0",
|
||||
"sortablejs": "^1.15.0",
|
||||
"window-handle": "^1.0.0"
|
||||
|
|
|
@ -1131,7 +1131,7 @@ td.progress-bar-done {
|
|||
}
|
||||
|
||||
td.progress-bar-left {
|
||||
background-color: #ebecf0;
|
||||
background-color: #bababa;
|
||||
}
|
||||
|
||||
table.progress-bar.red {
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" class="ionicon" viewBox="0 0 512 512">
|
||||
<title>edit-note</title>
|
||||
<path d="M384 224v184a40 40 0 01-40 40H104a40 40 0 01-40-40V168a40 40 0 0140-40h167.48" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32"/>
|
||||
<path d="M459.94 53.25a16.06 16.06 0 00-23.22-.56L424.35 65a8 8 0 000 11.31l11.34 11.32a8 8 0 0011.34 0l12.06-12c6.1-6.09 6.67-16.01.85-22.38zM399.34 90L218.82 270.2a9 9 0 00-2.31 3.93L208.16 299a3.91 3.91 0 004.86 4.86l24.85-8.35a9 9 0 003.93-2.31L422 112.66a9 9 0 000-12.66l-9.95-10a9 9 0 00-12.71 0z" fill="currentColor"/>
|
||||
</svg>
|
After Width: | Height: | Size: 632 B |
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" class="ionicon" viewBox="0 0 512 512"><title>Arrow Redo</title><path d="M448 256L272 88v96C103.57 184 64 304.77 64 424c48.61-62.24 91.6-96 208-96v96z" fill="none" stroke="currentColor" stroke-linejoin="round" stroke-width="32"/></svg>
|
After Width: | Height: | Size: 274 B |
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" class="ionicon" viewBox="0 0 512 512"><title>Arrow Undo</title><path d="M240 424v-96c116.4 0 159.39 33.76 208 96 0-119.23-39.57-240-208-240V88L64 256z" fill="none" stroke="currentColor" stroke-linejoin="round" stroke-width="32"/></svg>
|
After Width: | Height: | Size: 275 B |
|
@ -2,8 +2,8 @@
|
|||
|
||||
const path = require('path');
|
||||
const MiniCSSExtractPlugin = require('mini-css-extract-plugin');
|
||||
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
|
||||
const FixStyleOnlyEntriesPlugin = require('webpack-fix-style-only-entries');
|
||||
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
|
||||
const RemoveEmptyScriptsPlugin = require('webpack-remove-empty-scripts');
|
||||
const CopyPlugin = require('copy-webpack-plugin');
|
||||
const { CleanWebpackPlugin: CleanPlugin } = require('clean-webpack-plugin');
|
||||
|
||||
|
@ -42,7 +42,7 @@ module.exports = (env, argv) => ({
|
|||
},
|
||||
devtool: argv.mode === 'production' ? 'source-map' : 'inline-cheap-module-source-map',
|
||||
plugins: [
|
||||
new FixStyleOnlyEntriesPlugin(),
|
||||
new RemoveEmptyScriptsPlugin({}),
|
||||
new MiniCSSExtractPlugin({
|
||||
filename: "[name].css",
|
||||
}),
|
||||
|
@ -77,14 +77,12 @@ module.exports = (env, argv) => ({
|
|||
loader: 'css-loader',
|
||||
options: {
|
||||
sourceMap: true,
|
||||
url: (url, resourcePath) => {
|
||||
// ignore the URLS on the base styles as they are picked
|
||||
// from the src/main/webapp/images dir
|
||||
if (resourcePath.includes('styles.less')) {
|
||||
return false;
|
||||
// ignore the URLS on the base styles as they are picked
|
||||
// from the src/main/webapp/images dir
|
||||
url: {
|
||||
filter: (url, resourcePath) => {
|
||||
return !resourcePath.includes('styles.less');
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -104,15 +102,10 @@ module.exports = (env, argv) => ({
|
|||
},
|
||||
{
|
||||
test: /\.(woff(2)?|ttf|eot|svg)(\?v=\d+\.\d+\.\d+)?$/,
|
||||
use: [
|
||||
{
|
||||
loader: 'file-loader',
|
||||
options: {
|
||||
name: '[name].[ext]',
|
||||
outputPath: 'fonts/'
|
||||
}
|
||||
}
|
||||
]
|
||||
type: "asset/resource",
|
||||
generator: {
|
||||
filename: 'fonts/[name].[ext]',
|
||||
},
|
||||
},
|
||||
{
|
||||
test: /\.hbs$/,
|
||||
|
|
3036
war/yarn.lock
3036
war/yarn.lock
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue