Merge branch 'stable-3.15' * stable-3.15: Align the look&feel of the plugin manager with the intro page Fetch Gerrit version dynamically in intro.html Modernise Gerrit intro page Change-Id: Ia0cdef91bd887150fc66e39abd9225b046d9a357
diff --git a/src/main/resources/static/css/intro.css b/src/main/resources/static/css/intro.css new file mode 100644 index 0000000..90d0916 --- /dev/null +++ b/src/main/resources/static/css/intro.css
@@ -0,0 +1,241 @@ +:root { + --primary-blue: #2563eb; + --primary-hover: #1d4ed8; + --text-dark: #1f2937; + --text-body: #4b5563; + --text-light: #9ca3af; + --bg-light: #f9fafb; + --bg-card: #ffffff; + --border-light: #e5e7eb; + --btn-skip: #e5e7eb; + --btn-skip-hover: #d1d5db; +} + +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: 'Inter', system-ui, -apple-system, sans-serif; + background-color: var(--bg-light); + color: var(--text-body); + line-height: 1.6; + display: flex; + flex-direction: column; + min-height: 100vh; +} + +/* Header Styles */ +header { + background-color: var(--primary-blue); + color: white; + position: sticky; + top: 0; + z-index: 50; + box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1); +} + +.header-container { + max-width: 1200px; + margin: 0 auto; + padding: 1rem 1.5rem; + display: flex; + justify-content: space-between; + align-items: center; +} + +.header-title { + font-size: 1.25rem; + font-weight: 700; + letter-spacing: -0.025em; +} + +.skip-btn { + background-color: var(--btn-skip); + color: var(--text-dark); + text-decoration: none; + padding: 0.5rem 1.25rem; + border-radius: 0.5rem; + font-weight: 600; + font-size: 0.875rem; + transition: background-color 0.2s ease, transform 0.1s ease; +} + +.skip-btn:hover { + background-color: var(--btn-skip-hover); + transform: translateY(-1px); +} + +/* Main Layout */ +main { + flex: 1; + padding-bottom: 4rem; +} + +.hero-section { + max-width: 900px; + margin: 4rem auto 3rem; + padding: 0 1.5rem; + text-align: center; +} + +.hero-header { + display: flex; + align-items: center; + justify-content: center; + gap: 2rem; + margin-bottom: 2rem; +} + +.hero-image { + width: 160px; + height: auto; +} + +.hero-title { + font-size: 3.5rem; + font-weight: 800; + color: var(--text-dark); + line-height: 1.1; + text-align: left; + letter-spacing: -0.05em; +} + +.hero-intro-text { + font-size: 1.125rem; + color: var(--text-body); + max-width: 800px; + margin: 0 auto 2.5rem; + text-align: left; +} + +.hero-intro-text strong { + color: var(--text-dark); +} + +.install-btn { + display: inline-block; + background-color: var(--primary-blue); + color: white; + text-decoration: none; + padding: 0.875rem 2.5rem; + border-radius: 0.5rem; + font-weight: 600; + font-size: 1.125rem; + box-shadow: 0 4px 6px -1px rgba(37, 99, 235, 0.4); + transition: all 0.2s ease; +} + +.install-btn:hover { + background-color: var(--primary-hover); + box-shadow: 0 10px 15px -3px rgba(37, 99, 235, 0.4); + transform: translateY(-2px); +} + +.features-section { + max-width: 1200px; + margin: 0 auto; + padding: 0 1.5rem; + display: grid; + grid-template-columns: repeat(1, 1fr); + gap: 2rem; +} + +.feature-card { + background: var(--bg-card); + border: 1px solid var(--border-light); + border-radius: 1rem; + padding: 2rem; + display: flex; + flex-direction: column; + box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1); + transition: transform 0.2s ease, box-shadow 0.2s ease; +} + +.feature-card:hover { + transform: translateY(-4px); + box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1); +} + +.feature-title { + font-size: 1.25rem; + font-weight: 700; + color: var(--text-dark); + margin-bottom: 1rem; +} + +.feature-text { + flex: 1; + margin-bottom: 1.5rem; + font-size: 0.9375rem; +} + +.feature-actions { + display: flex; + gap: 0.75rem; + align-items: center; +} + +.icon-btn { + display: flex; + align-items: center; + justify-content: center; + width: 44px; + height: 44px; + border-radius: 50%; + background-color: #f3f4f6; + color: var(--text-body); + transition: all 0.2s ease; + text-decoration: none; +} + +.icon-btn svg { + width: 22px; + height: 22px; + fill: currentColor; +} + +/* Action Icon Hover Colors */ +.icon-btn.youtube:hover { background-color: #ff0000; color: white; } +.icon-btn.google:hover { background-color: #4285F4; color: white; } +.icon-btn.x-twitter:hover { background-color: #000000; color: white; } +.icon-btn.mastodon:hover { background-color: #6364FF; color: white; } +.icon-btn.bluesky:hover { background-color: #6364FF; color: white; } +.icon-btn.discord:hover { background-color: #5865F2; color: white; } + +@media (min-width: 768px) { + .features-section { + grid-template-columns: repeat(3, 1fr); + } +} + +@media (max-width: 640px) { + .hero-header { + flex-direction: column; + text-align: center; + gap: 1.5rem; + } + .hero-title { + text-align: center; + font-size: 2.5rem; + } + .hero-intro-text { + text-align: center; + } +} + +/* Footer Styles */ +footer { + background-color: var(--bg-card); + border-top: 1px solid var(--border-light); + padding: 2rem 1.5rem; + text-align: center; + margin-top: auto; +} + +.footer-text { + color: var(--text-light); + font-size: 0.875rem; +} \ No newline at end of file
diff --git a/src/main/resources/static/css/style.css b/src/main/resources/static/css/style.css index e187458..4692d86 100644 --- a/src/main/resources/static/css/style.css +++ b/src/main/resources/static/css/style.css
@@ -1,46 +1,79 @@ -.inprogress { - background-image: url("../images/spinner-24px.gif"); - background-repeat: no-repeat; - background-position-y: 7px; +.search-container { + max-width: 900px; + margin: 0 auto 2rem; + padding: 0 1.5rem; } - -.hidden { - display: none; -} - -h5 { - margin: 0px; -} - -td { - height: 40px; -} - -.main { - margin-top: 51px; -} - -button.btn-xs { - width: 65px; -} - -button.btn-sm { - width: 83px; -} - -button.btn-100 { +.search-input { width: 100%; + padding: 1rem 1.5rem; + border: 1px solid var(--border-light); + border-radius: 0.5rem; + font-size: 1rem; + font-family: inherit; + box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05); +} +.search-input:focus { + outline: none; + border-color: var(--primary-blue); +} +.status-label { + font-size: 0.75rem; + font-weight: 600; + padding: 0.375rem 0.75rem; + border-radius: 1rem; +} +.status-success { background: #dcfce7; color: #166534; } +.status-warning { background: #fee2e2; color: #991b1b; } +.status-default { background: #f3f4f6; color: #374151; } +.hidden { display: none !important; } +.version-info { + font-size: 0.875rem; + color: var(--text-light); + margin-bottom: 1rem; + display: flex; + flex-direction: column; + gap: 0.25rem; +} +.update-info { color: var(--primary-blue); font-weight: 600; } + +/* Adjusted install button for card context */ +.card-btn { + padding: 0.5rem 1.25rem; + font-size: 0.875rem; + border: none; + cursor: pointer; } -.label-success { - background-color: #888888; +/* Plugin Icon Header Styles */ +.plugin-header { + display: flex; + align-items: center; + gap: 0.75rem; + margin-bottom: 1rem; +} +.plugin-icon-wrapper { + display: flex; + align-items: center; + justify-content: center; + width: 36px; + height: 36px; + background-color: var(--bg-light); + color: var(--primary-blue); + border-radius: 0.5rem; + flex-shrink: 0; +} +.feature-title { + margin-bottom: 0; } -div.top-header { - padding-left: 35px; - padding-right: 35px; +/* Dynamic Card Style for Installable Plugins */ +.feature-card.card-installable { + border-color: var(--primary-blue); + box-shadow: 0 4px 12px -2px rgba(37, 99, 235, 0.25); } -.navbar-form input.searchbox { - width: 400px; +/* Dynamic Card Style for Upgradable Plugins */ +.feature-card.card-upgradable { + border-color: #f97316; /* Vibrant orange */ + box-shadow: 0 4px 12px -2px rgba(249, 115, 22, 0.25); } \ No newline at end of file
diff --git a/src/main/resources/static/index.html b/src/main/resources/static/index.html index 977ddac..cda1549 100644 --- a/src/main/resources/static/index.html +++ b/src/main/resources/static/index.html
@@ -1,83 +1,116 @@ <!DOCTYPE html> <html ng-app="PluginManager"> <head> -<meta charset="UTF-8"> -<title>Gerrit Plugin Manager</title> -<script src= "https://ajax.googleapis.com/ajax/libs/angularjs/1.4.7/angular.min.js"></script> -<script src="js/plugin-manager.js"></script> -<script src="https://code.jquery.com/jquery-2.1.4.min.js"></script> -<link - href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" - rel="stylesheet" - integrity="sha256-MfvZlkHCEqatNoGiOXveE8FIwMzZg4W85qfrfIFBfYc= sha512-dTfge/zgoMYpP7QbHy4gWMEGsbsdZeCXz7irItjcC3sPUFtf0kuFbDz/ixG7ArTxmDjLXDmezHubeNikyKGVyQ==" - crossorigin="anonymous"> -<link href="css/style.css" rel="stylesheet"> + <meta charset="UTF-8"> + <title>Gerrit Plugin Manager</title> + <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.7/angular.min.js"></script> + <script src="js/plugin-manager.js"></script> + <script src="https://code.jquery.com/jquery-2.1.4.min.js"></script> + + <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700;800&display=swap" rel="stylesheet"> + <link href="css/intro.css" rel="stylesheet"> + <link href="css/style.css" rel="stylesheet"> </head> -<body role="document" ng-controller="LoadInstalledPlugins as plugins"> - <nav class="navbar navbar-inverse navbar-fixed-top"> - <div class="container top-header"> - <div class="navbar-header"> - <a class="navbar-brand">Gerrit Plugins</a> +<body ng-controller="LoadInstalledPlugins as plugins"> + + <header> + <div class="header-container"> + <div class="header-title">Gerrit Code Review</div> + <button type="button" class="skip-btn" style="border: none; cursor: pointer;" ng-click="plugins.goToGerrit()"> + Done » Go To Gerrit + </button> </div> - <div class="navbar-collapse collapse"> - <form class="navbar-form navbar-left" role="search"> - <div class="form-group"> - <input type="text" class="form-control searchbox" placeholder="Search" ng-model="searchPlugin"> + </header> + + <main> + <div class="hero-section"> + <div class="hero-header"> + <img src="images/diffy-gerrit-code-review.png" alt="Gerrit Diffy" class="hero-image"> + <h2 class="hero-title">Plugin Manager</h2> </div> - </form> - <ul class="nav navbar-nav navbar-right"> - <li> - <div class="navbar-form navbar-right"> - <button type="button" - class="btn btn-sm btn-primary btn-100" - ng-click="plugins.goToGerrit()">Done » Go To Gerrit</button> - </div> - </li> - </ul> </div> - </div> - </nav> - <div class="container main" role="main"> - <div class="col-md-12"> - <table class="table table-striped"> - <thead> - <tr> - <th>Plugin Name</th> - <th>Version</th> - <th>Actions</th> - </tr> - </thead> - <tbody> - <tr ng-repeat="prop in plugins.list | filter:searchPlugin"> - <td><h4>{{prop.id}}<br/><small>{{prop.description.split('.')[0]}}</small></h4></td> - <td> - <p>{{prop.version}}</p> - <div ng-if="prop.update_version"> - <span class="glyphicon glyphicon-save"></span><b> {{prop.update_version}}</b> + + <div class="search-container"> + <p class="hero-intro-text"> + Browse, install, and keep your Gerrit Code Review environment up to date with the latest plugins built + on <a href="https://gerrit-ci.gerritforge.com/plugin-manager/">Gerrit-CI</a>. + </p> + <input type="text" class="search-input" placeholder="Search for plugins..." ng-model="searchPlugin"> + </div> + + <div class="features-section"> + <!-- Plugin Feature Cards with dynamic border/shading via ng-class --> + <div class="feature-card" + ng-repeat="prop in plugins.list | filter:searchPlugin" + ng-class="{ + 'card-installable': prop.version == '' && prop.update_version != undefined, + 'card-upgradable': prop.version != '' && prop.update_version != '' + }"> + + <!-- Icon and Title Wrapper --> + <div class="plugin-header"> + <div class="plugin-icon-wrapper"> + <!-- SVG Plug Icon --> + <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" + stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> + <path d="M12 22v-5"/> + <path d="M9 8V2"/> + <path d="M15 8V2"/> + <path d="M18 8v5a4 4 0 0 1-4 4h-4a4 4 0 0 1-4-4V8Z"/> + </svg> + </div> + <h3 class="feature-title">{{prop.id}}</h3> </div> - </td> - <td> - <h4> - <span id="installing-{{prop.id}}" - class="label label-default hidden">Installing</span> - <span - id="installed-{{prop.id}}" - class="label label-success {{ (prop.version != '' && prop.update_version == '') ? '':'hidden' }}">Up to date</span> - <span - id="failed-{{prop.id}}" class="label label-warning hidden">Failed</span> - <button id="{{prop.id}}" type="button" - class="btn btn-sm btn-primary {{ (prop.version == '' && prop.update_version != undefined) ? '':'hidden' }}" - ng-click="install(prop.id,prop.url)">Install</button> - <button id="{{prop.id}}" type="button" - class="btn btn-sm btn-primary {{ (prop.version != '' && prop.update_version != '') ? '':'hidden' }}" - ng-click="install(prop.id,prop.url)">Upgrade</button> - </h4> - </td> - </tr> - </tbody> - </table> - </div> - </div> + + <div class="version-info"> + <span>Version: {{prop.version || 'Not installed'}}</span> + <div ng-if="prop.update_version" class="update-info" + ng-style="prop.version != '' ? {'color': '#f97316'} : {}"> + <svg style="width: 14px; height: 14px; display: inline-block; vertical-align: middle; margin-right: 4px;" + fill="none" stroke="currentColor" viewBox="0 0 24 24"> + <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" + d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4"></path> + </svg> + Update available: {{prop.update_version}} + </div> + </div> + + <p class="feature-text">{{prop.description.split('.')[0]}}</p> + + <div class="feature-actions"> + <!-- Status Labels --> + <span id="installing-{{prop.id}}" class="status-label status-default hidden">Installing...</span> + <span id="installed-{{prop.id}}" + class="status-label status-success {{ (prop.version != '' && prop.update_version == '') ? '':'hidden' }}">Up to date</span> + <span id="failed-{{prop.id}}" class="status-label status-warning hidden">Failed</span> + + <!-- Action Buttons --> + <button id="install-{{prop.id}}" type="button" + class="install-btn card-btn {{ (prop.version == '' && prop.update_version != undefined) ? '':'hidden' }}" + ng-click="install(prop.id,prop.url)"> + Install + </button> + + <button id="upgrade-{{prop.id}}" type="button" + class="install-btn card-btn {{ (prop.version != '' && prop.update_version != '') ? '':'hidden' }}" + style="{{ (prop.version != '' && prop.update_version != '') ? 'background-color: #f97316; box-shadow: 0 4px 6px -1px rgba(249, 115, 22, 0.4);' : '' }}" + onmouseover="this.style.backgroundColor='#ea580c'" + onmouseout="this.style.backgroundColor='#f97316'" + ng-click="install(prop.id,prop.url)"> + Upgrade + </button> + </div> + </div> + </div> + </main> + + <footer> + <p class="footer-text"> + Gerrit Code Review - Copyright © 2026 The Android Open Source Project - Licensed under the Apache License, + Version 2.0. + </p> + </footer> + </body> </html>
diff --git a/src/main/resources/static/intro.html b/src/main/resources/static/intro.html index 39d97e9..7ce5686 100644 --- a/src/main/resources/static/intro.html +++ b/src/main/resources/static/intro.html
@@ -1,146 +1,136 @@ - <!DOCTYPE html> <html lang="en"> <head> -<meta charset="utf-8"> -<meta http-equiv="X-UA-Compatible" content="IE=edge"> -<meta name="viewport" content="width=device-width, initial-scale=1"> -<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags --> -<meta name="description" content="Gerrit Plugin Manager"> -<meta name="author" content="Gerrit Code Review"> -<link rel="icon" href="/favicon.ico"> - -<title>Gerrit Plugin Manager - Introduction</title> - -<!-- Bootstrap core CSS --> -<link - href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" - rel="stylesheet" - integrity="sha256-MfvZlkHCEqatNoGiOXveE8FIwMzZg4W85qfrfIFBfYc= sha512-dTfge/zgoMYpP7QbHy4gWMEGsbsdZeCXz7irItjcC3sPUFtf0kuFbDz/ixG7ArTxmDjLXDmezHubeNikyKGVyQ==" - crossorigin="anonymous"> -<link href="css/style.css" rel="stylesheet"> - -<!-- IE10 viewport hack for Surface/desktop Windows 8 bug --> -<link href="css/ie10-viewport-bug-workaround.css" rel="stylesheet"> - -<!-- Custom styles for this template --> -<link href="css/jumbotron.css" rel="stylesheet"> - -<!-- Just for debugging purposes. Don't actually copy these 2 lines! --> -<!--[if lt IE 9]><script src="../../assets/js/ie8-responsive-file-warning.js"></script><![endif]--> -<script src="js/ie-emulation-modes-warning.js"></script> - -<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries --> -<!--[if lt IE 9]> - <script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script> - <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script> - <![endif]--> + <meta charset="UTF-8"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <title>Gerrit Code Review - Welcome</title> + <link rel="preconnect" href="https://fonts.googleapis.com"> + <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> + <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet"> + <link href="css/intro.css" rel="stylesheet"> </head> - <body> - <nav class="navbar navbar-inverse navbar-fixed-top"> - <div class="container"> - <div class="navbar-header"> - <button type="button" class="navbar-toggle collapsed" - data-toggle="collapse" data-target="#navbar" - aria-expanded="false" aria-controls="navbar"> - <span class="sr-only">Toggle navigation</span> <span - class="icon-bar"></span> <span class="icon-bar"></span> <span - class="icon-bar"></span> - </button> - <a class="navbar-brand" href="../../../">» Skip intro</a> - </div> - </div> - </nav> + <header> + <div class="header-container"> + <div class="header-title">Gerrit Code Review</div> + <a href="/" class="skip-btn">> Skip Intro</a> + </div> + </header> - <!-- Main jumbotron for a primary marketing message or call to action --> - <div class="jumbotron"> - <div class="container gerritlogo"> - <h1>Welcome!</h1> - <p><b><a href="https://www.gerritcodereview.com" target="_blank">Gerrit Code Review</a></b> provides web-based code review and repository - management for the Git version control system.</p> - <p> - Before starting using it, you may want to consider <strong>installing - some extra plugins</strong> to extend its functionality, including <i>replication - to remote locations</i>, integration with <i>Atlassian Jira</i> - and other issue trackers workflow, <i>OAuth 2.0 - authentication</i> with external providers such as <i>Google - Account</i>, <i>GitHub</i> and <i>GitLab</i> and many others. - </p> - <p> - <p> - Once you're done with your plugins selection, click on the - top-right <strong>"> Go to Gerrit"</strong> link on the - top-right corner to access the Gerrit Code Review main screen. - </p> - <a class="btn btn-primary btn-lg" href="index.html" role="button">Install - plugins »</a> - </p> - </div> - </div> + <main> + <section class="hero-section"> + <div class="hero-header"> + <img src="images/diffy-gerrit-code-review.png" alt="Gerrit Diffy" class="hero-image"> + <h2 class="hero-title">Welcome to<br>Gerrit v<version id="gerrit-version">3.15</version></h2> + </div> - <div class="container"> - <!-- Example row of columns --> - <div class="row"> - <div class="col-md-4"> - <h2><span class="glyphicon glyphicon-film" aria-hidden="true"></span> Learn more</h2> - <p>Before starting using Gerrit Code Review, you may want to - spend a few minutes learning the basic concepts and how its - workflow works.</p> - <p>Get information from the source, with an introduction - video starring Shawn Pearce, the Gerrit Code Review project - founder, at the EclipseCon 2013.</p> - <p> - <a class="btn btn-default" - href="https://www.youtube.com/watch?v=Wxx8XndqZ7A&t=15s" - target="_blank" role="button">Watch Video »</a> - </p> - </div> - <div class="col-md-4"> - <h2><span class="glyphicon glyphicon-envelope" aria-hidden="true"></span> Get involved</h2> - <p>Gerrit Code Review is backed by a thriving Community of - users and contributors. The main channel to get in touch is - through the "repo-discuss" mailing list.</p> - <p>Join the discussions and feel free to ask questions. - Share your thoughts on how to improve Gerrit workflow and user - experience. - <p> - <a class="btn btn-default" - href="https://groups.google.com/forum/#!forum/repo-discuss" - target="_blank" role="button">Repo-discuss mailing list - »</a> - </p> - </div> - <div class="col-md-4"> - <h2><span class="glyphicon glyphicon-thumbs-up" aria-hidden="true"></span> Keep in touch</h2> - <p> - Get the latest news about Gerrit Code Review releases and - events by following the official social network channels of - the project, including <a - href="https://plus.google.com/communities/111271594706618791655" - target="_blank">Google+</a> and <a - href="https://twitter.com/gerritreview">Twitter</a>. - </p> - <p>Follow Gerrit and tweet about your experience to share - your thoughts and achievements with your daily code reviews. - <p> - <a href="https://twitter.com/gerritreview" - class="twitter-follow-button" data-show-count="false">Follow - @gerritreview</a> - <script async src="//platform.twitter.com/widgets.js" - charset="utf-8"></script> - </p> - </div> - </div> + <p class="hero-intro-text"> + Elevate your development workflow with Gerrit Code Review, the premier web-based code review and + repository management platform. Supercharge your team's productivity seamlessly by connecting with + your existing Git services, including <strong>GitHub</strong> and <strong>GitLab</strong>. + <br><br> + Unlock next-generation insights by extending Gerrit with cutting-edge plugins—integrate popular + AI review models like <strong>Google Gemini, OpenAI ChatGPT, and Anthropic Claude</strong> + to act as your automated co-reviewers! + <br><br> + Customize your environment below, or click the top-right <strong>'> Skip Intro'</strong> button + to access your main Gerrit dashboard. + </p> - <hr> + <a href="index.html" class="install-btn">Install Plugins</a> + </section> + + <section class="features-section"> + + <!-- Card 1 --> + <div class="feature-card"> + <h3 class="feature-title">Learn more</h3> + <p class="feature-text"> + Before starting using Gerrit Code Review, you may want to spend a few minutes learning the basic + concepts and how its workflow works. Get information from the source, with a collection of tutorials + and past Gerrit conferences videos and talks, organized in topic-focused playlists. + </p> + <div class="feature-actions"> + <a href="https://www.youtube.com/@GerritForgeTV/playlists" class="icon-btn youtube" title="Watch on YouTube" target="_blank"> + <svg viewBox="0 0 24 24"><path d="M23.498 6.186a3.016 3.016 0 0 0-2.122-2.136C19.505 3.545 12 3.545 12 3.545s-7.505 0-9.377.505A3.017 3.017 0 0 0 .502 6.186C0 8.07 0 12 0 12s0 3.93.502 5.814a3.016 3.016 0 0 0 2.122 2.136c1.871.505 9.376.505 9.376.505s7.505 0 9.377-.505a3.015 3.015 0 0 0 2.122-2.136C24 15.93 24 12 24 12s0-3.93-.502-5.814zM9.545 15.568V8.432L15.818 12l-6.273 3.568z"/></svg> + </a> + </div> + </div> + + <!-- Card 2 --> + <div class="feature-card"> + <h3 class="feature-title">Get involved</h3> + <p class="feature-text"> + Gerrit Code Review is backed by a thriving Community of users and contributors. + The main channel to get in touch is through the 'repo-discuss' mailing list. Join the discussions, + ask questions, and share your thoughts on how to improve the workflow and user experience. + </p> + <div class="feature-actions"> + <a href="https://groups.google.com/u/1/g/repo-discuss" class="icon-btn google" title="Join the Google Group" target="_blank"> + <svg viewBox="0 0 24 24"><path d="M12.48 10.92v3.28h7.84c-.24 1.84-.853 3.187-1.787 4.133-1.147 1.147-2.933 2.4-6.053 2.4-4.827 0-8.6-3.893-8.6-8.72s3.773-8.72 8.6-8.72c2.6 0 4.507 1.027 5.907 2.347l2.307-2.307C18.747 1.44 16.133 0 12.48 0 5.867 0 .307 5.387.307 12s5.56 12 12.173 12c3.573 0 6.267-1.173 8.373-3.36 2.16-2.16 2.84-5.213 2.84-7.667 0-.76-.053-1.467-.173-2.053H12.48z"/></svg> + </a> + </div> + </div> + + <!-- Card 3 --> + <div class="feature-card"> + <h3 class="feature-title">Keep in touch</h3> + <p class="feature-text"> + Get the latest news about Gerrit Code Review releases and events by following the official social + network channels of the project on X, Mastodon and BlueSky. Join our Discord server to interact live with + the Gerrit community and share your daily code review achievements. + </p> + <div class="feature-actions"> + <a href="https://x.com/GerritReview" class="icon-btn x-twitter" title="Follow us on X" target="_blank"> + <svg viewBox="0 0 24 24"><path d="M18.901 1.153h3.68l-8.04 9.19L24 22.846h-7.406l-5.8-7.584-6.638 7.584H.474l8.6-9.83L0 1.154h7.594l5.243 6.932ZM17.61 20.644h2.039L6.486 3.24H4.298Z"/></svg> + </a> + <a href="https://mastodon.social/@gerritreview" class="icon-btn mastodon" title="Follow us on Mastodon" target="_blank"> + <svg viewBox="0 0 24 24"><path d="M23.268 5.313c-.35-2.228-2.618-3.616-2.618-3.616C17.58.63 14.92 1.5 11.963 1.5h-.022c-2.957 0-5.617-.87-8.687.197 0 0-2.268 1.388-2.618 3.616-.364 2.336-.543 6.273-.131 9.774 1.11 9.42 12.012 8.435 12.012 8.435 4.544-.22 8.358-2.457 8.358-2.457l-.372-3.41c-2.316 1.387-5.596 1.706-8.384 1.353-2.946-.374-4.832-1.89-5.185-4.857-.023-.195-.037-.384-.047-.562 2.652 1.31 6.574 1.735 9.742 1.107 4.512-.89 6.077-4.145 6.077-4.145.45-3.376.516-7.79.54-10.239zM8.344 14.288v-4.996c0-1.282.463-2.383 1.389-2.383.997 0 1.496.862 1.496 2.584v3.083h2.646V9.493c0-1.722.499-2.584 1.496-2.584.926 0 1.389 1.101 1.389 2.383v4.996h2.518v-5.26c0-1.428-.352-2.529-1.055-3.302-.734-.805-1.7-1.208-2.898-1.208-1.472 0-2.57.65-3.284 1.95L12.013 8.3l-.025-1.844c-.714-1.3-1.812-1.95-3.284-1.95-1.198 0-2.164.403-2.898 1.208-.703.773-1.055 1.874-1.055 3.302v5.26h2.518z"/></svg> + </a> + <a href="https://bsky.app/profile/gerritreview.bsky.social" class="icon-btn bluesky" title="Follow us on Bluesky" target="_blank"> + <svg viewBox="0 0 600 530"><path d="m135.72 44.03c92.06 65.36 137.94 170.86 164.28 254.67 26.34-83.81 72.22-189.31 164.28-254.67 47.3-33.6 115.72-27.35 115.72 49.33 0 25.1-5.91 85.03-14.54 116.59-21.57 78.43-96.11 96.06-162.24 88.08 97.45 13.9 138.83 45.41 138.83 103.1 0 71.3-95.21 106.35-197.81 37.19-14.73-9.92-28.52-20.73-44.24-34.8-15.72 14.07-29.51 24.88-44.24 34.8-102.6 69.16-197.81 34.11-197.81-37.19 0-57.69 41.38-89.2 138.83-103.1-66.13 7.98-140.67-9.65-162.24-88.08-8.63-31.56-14.54-91.49-14.54-116.59 0-76.68 68.42-82.93 115.72-49.33z"/></svg> + </a> + <a href="https://discord.gg/eEZQrtzAwV" class="icon-btn discord" title="Join our Discord" target="_blank"> + <svg viewBox="0 0 24 24"><path d="M20.317 4.3698a19.7913 19.7913 0 00-4.8851-1.5152.0741.0741 0 00-.0785.0371c-.211.3753-.4447.8648-.6083 1.2495-1.8447-.2762-3.68-.2762-5.4868 0-.1636-.3933-.4058-.8742-.6177-1.2495a.077.077 0 00-.0785-.037 19.7363 19.7363 0 00-4.8852 1.515.0699.0699 0 00-.0321.0277C.5334 9.0458-.319 13.5799.0992 18.0578a.0824.0824 0 00.0312.0561c2.0528 1.5076 4.0413 2.4228 5.9929 3.0294a.0777.0777 0 00.0842-.0276c.4616-.6304.8731-1.2952 1.226-1.9942a.076.076 0 00-.0416-.1057c-.6528-.2476-1.2743-.5495-1.8722-.8923a.077.077 0 01-.0076-.1277c.1258-.0943.2517-.1923.3718-.2914a.0743.0743 0 01.0776-.0105c3.9278 1.7933 8.18 1.7933 12.0614 0a.0739.0739 0 01.0785.0095c.1202.099.246.1981.3728.2924a.077.077 0 01-.0066.1276 12.2986 12.2986 0 01-1.873.8914.0766.0766 0 00-.0407.1067c.3604.698.7719 1.3628 1.225 1.9932a.076.076 0 00.0842.0286c1.961-.6067 3.9495-1.5219 6.0023-3.0294a.077.077 0 00.0313-.0552c.5004-5.177-.8382-9.6739-3.5485-13.6604a.061.061 0 00-.0312-.0286zM8.02 15.3312c-1.1825 0-2.1569-1.0857-2.1569-2.419 0-1.3332.9555-2.4189 2.157-2.4189 1.2108 0 2.1757 1.0952 2.1568 2.419 0 1.3332-.9555 2.4189-2.1569 2.4189zm7.9748 0c-1.1825 0-2.1569-1.0857-2.1569-2.419 0-1.3332.9554-2.4189 2.1569-2.4189 1.2108 0 2.1757 1.0952 2.1568 2.419 0 1.3332-.946 2.4189-2.1568 2.4189Z"/></svg> + </a> + </div> + </div> + + </section> + </main> <footer> - <p><a href="https://www.gerritcodereview.com" href="_blank">Gerrit Code Review</a> - Copyright © 2018 The Android Open Source Project - - Licensed under the Apache License, Version 2.0.</p> + <p class="footer-text"> + Gerrit Code Review - Copyright © 2026 The Android Open Source Project - Licensed under the Apache License, Version 2.0. + </p> </footer> - </div> - <!-- /container --> + + <script> + document.addEventListener('DOMContentLoaded', () => { + fetch('/config/server/version') + .then(response => { + if (!response.ok) { + console.error('Error fetching Gerrit version: HTTP status ', response.status); + return ""; + } + return response.text(); + }) + .then(text => { + const lines = text.trim().split('\n').filter(line => line.length > 0); + if (lines.length > 1) { + const version = lines[lines.length - 1].replace(/"/g, ''); + const versionElement = document.getElementById('gerrit-version'); + if (versionElement) { + versionElement.textContent = version; + } + } + }) + .catch(error => { + console.error('Error fetching Gerrit version:', error); + }); + }); + </script> + </body> -</html> +</html> \ No newline at end of file
diff --git a/src/main/resources/static/js/plugin-manager.js b/src/main/resources/static/js/plugin-manager.js index 04a3cc3..3b1e5a4 100644 --- a/src/main/resources/static/js/plugin-manager.js +++ b/src/main/resources/static/js/plugin-manager.js
@@ -127,7 +127,8 @@ var pluginInstallData = { "url" : url }; - $("button#" + id).addClass("hidden"); + $("button#install-" + id).addClass("hidden"); + $("button#upgrade-" + id).addClass("hidden"); $("span#installing-" + id).removeClass("hidden"); var fileEnding = url.endsWith('.js') ? ".js" : ".jar"; $http.put($scope.getBaseUrl() + '/a/plugins/' + id + fileEnding, pluginInstallData).then(