Add plugins search box on the top navigation bar
Introduce a top search box to be able to filter the list of plugins.
Specifying a search keyword helps a lot on focusing on what the
administrator is looking for, without having to go through an
alphabetical long list.
Change-Id: I5af06c87c7d1232368bd52ff7ecc000924835824
diff --git a/src/main/resources/static/css/style.css b/src/main/resources/static/css/style.css
index e1d4044..ddcd2b2 100644
--- a/src/main/resources/static/css/style.css
+++ b/src/main/resources/static/css/style.css
@@ -31,4 +31,8 @@
div.top-header {
padding-left: 35px;
padding-right: 35px;
+}
+
+.navbar-form input.searchbox {
+ width: 400px;
}
\ No newline at end of file
diff --git a/src/main/resources/static/index.html b/src/main/resources/static/index.html
index be86bd7..9ca7d04 100644
--- a/src/main/resources/static/index.html
+++ b/src/main/resources/static/index.html
@@ -14,21 +14,25 @@
<link href="css/style.css" rel="stylesheet">
</head>
-<body role="document">
+<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>
</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">
+ </div>
+ </form>
<ul class="nav navbar-nav navbar-right">
<li><a href="/">> Go to Gerrit</a></li>
</ul>
</div>
</div>
</nav>
- <div class="container main" role="main"
- ng-controller="LoadInstalledPlugins as plugins">
+ <div class="container main" role="main">
<div class="col-md-12">
<table class="table table-striped">
<thead>
@@ -41,24 +45,24 @@
</tr>
</thead>
<tbody>
- <tr ng-repeat="(key, prop) in plugins.list">
- <td>{{key}}</td>
+ <tr ng-repeat="prop in plugins.list | filter:searchPlugin">
+ <td>{{prop.id}}</td>
<td>{{prop.version}}</td>
<td>{{prop.update_version}}</td>
<td>{{prop.sha1}}</td>
<td>
<h5>
- <span id="installing-{{key}}"
+ <span id="installing-{{prop.id}}"
class="label label-default hidden">Installing</span>
<span
- id="installed-{{key}}"
+ id="installed-{{prop.id}}"
class="label label-success {{ (prop.version != '' && prop.update_version == '') ? '':'hidden' }}">Up to date</span>
<span
- id="failed-{{key}}" class="label label-warning hidden">Failed</span>
- <button id="{{key}}" type="button"
+ id="failed-{{prop.id}}" class="label label-warning hidden">Failed</span>
+ <button id="{{prop.id}}" type="button"
class="btn btn-xs btn-primary {{ (prop.version == '' && prop.update_version != undefined) ? '':'hidden' }}"
ng-click="install(prop.id,prop.url)">Install</button>
- <button id="{{key}}" type="button"
+ <button id="{{prop.id}}" type="button"
class="btn btn-xs btn-primary {{ (prop.version != '' && prop.update_version != '') ? '':'hidden' }}"
ng-click="install(prop.id,prop.url)">Upgrade</button>
</h5>
diff --git a/src/main/resources/static/js/plugin-manager.js b/src/main/resources/static/js/plugin-manager.js
index f721d42..b458bc2 100644
--- a/src/main/resources/static/js/plugin-manager.js
+++ b/src/main/resources/static/js/plugin-manager.js
@@ -17,22 +17,49 @@
function($scope, $http) {
var plugins = this;
- plugins.list = {};
+ plugins.list = [];
plugins.available = {};
+ $scope.searchPlugin = '';
+
+ $scope.pluginIndexOf = function(pluginId) {
+ var pluginIndex = -1
+
+ angular.forEach(plugins.list, function(row, rowIndex) {
+ if (row.id == pluginId) {
+ pluginIndex = rowIndex
+ }
+ });
+
+ return pluginIndex;
+ }
+
$scope.refreshInstalled = function() {
$http.get('/plugins/?all', plugins.httpConfig).then(
function successCallback(response) {
angular.forEach(response.data, function(plugin) {
- plugins.list[plugin.id] = {
- id: plugin.id,
- index_url: plugin.index_url,
- version: plugin.version,
- sha1: '',
- url: plugin.url,
- update_version: ''
+ var currPluginIdx = $scope.pluginIndexOf(plugin.id);
+
+ if (currPluginIdx < 0) {
+ plugins.list.push({
+ id : plugin.id,
+ index_url : plugin.index_url,
+ version : plugin.version,
+ sha1 : '',
+ url : plugin.url,
+ update_version : ''
+ });
+ } else {
+ plugins.list[currPluginIdx] = {
+ id : plugin.id,
+ index_url : plugin.index_url,
+ version : plugin.version,
+ sha1 : '',
+ url : plugin.url,
+ update_version : ''
+ }
}
});
@@ -43,34 +70,43 @@
$scope.refreshAvailable = function() {
$http.get('/plugins/plugin-manager/available', plugins.httpConfig)
- .then(function successCallback(response) {
+ .then(
+ function successCallback(response) {
- angular.forEach(response.data, function(plugin) {
- var currPlugin = plugins.list[plugin.id];
+ angular.forEach(response.data, function(plugin) {
+ var currRow = $scope.pluginIndexOf(plugin.id);
+ var currPlugin = currRow < 0 ? undefined
+ : plugins.list[currRow];
- if(currPlugin === undefined) {
- currPlugin = {
- id: plugin.id,
- index_url: '',
- version: ''
- }
- }
+ if (currPlugin === undefined) {
+ currPlugin = {
+ id : plugin.id,
+ index_url : '',
+ version : ''
+ }
+ }
- if(plugin.version != currPlugin.version) {
- currPlugin.update_version = plugin.version;
- }
- currPlugin.sha1 = plugin.sha1;
- currPlugin.url = plugin.url;
+ if (plugin.version != currPlugin.version) {
+ currPlugin.update_version = plugin.version;
+ }
+ currPlugin.sha1 = plugin.sha1;
+ currPlugin.url = plugin.url;
- plugins.list[plugin.id] = currPlugin;
- });
- plugins.available = response.data;
- }, function errorCallback(response) {
- });
+ if (currRow < 0) {
+ plugins.list.push(currPlugin);
+ } else {
+ plugins.list[currRow] = currPlugin;
+ }
+ });
+ plugins.available = response.data;
+ }, function errorCallback(response) {
+ });
}
$scope.install = function(id, url) {
- var pluginInstallData = { "url" : url };
+ var pluginInstallData = {
+ "url" : url
+ };
$("button#" + id).addClass("hidden");
$("span#installing-" + id).removeClass("hidden");
$http.put('/a/plugins/' + id + ".jar", pluginInstallData).then(