/admin/plugins: Add progress indicators and report errors

This commit is contained in:
Marcel Klehr 2013-03-26 11:19:36 +01:00
parent b35d9c14fd
commit e8bae61cf5
4 changed files with 101 additions and 53 deletions

View File

@ -81,13 +81,15 @@ exports.socketio = function (hook_name, args, cb) {
socket.on("install", function (plugin_name) { socket.on("install", function (plugin_name) {
installer.install(plugin_name, function (er) { installer.install(plugin_name, function (er) {
socket.emit("finished:install", {error: er}); if(er) console.warn(er)
socket.emit("finished:install", {error: er? er.message : null});
}); });
}); });
socket.on("uninstall", function (plugin_name) { socket.on("uninstall", function (plugin_name) {
installer.uninstall(plugin_name, function (er) { installer.uninstall(plugin_name, function (er) {
socket.emit("finished:uninstall", {error: er}); if(er) console.warn(er)
socket.emit("finished:uninstall", {error: er? er.message : null});
}); });
}); });
}); });

View File

@ -35,7 +35,8 @@ div.menu li:last-child {
div.innerwrapper { div.innerwrapper {
padding: 15px; padding: 15px;
padding-left: 265px; margin-left: 265px;
position:relative; /* Allows us to position the loading indicator relative to this div */
} }
#wrapper { #wrapper {
@ -121,6 +122,7 @@ table {
border-spacing: 0; border-spacing: 0;
width: 100%; width: 100%;
margin: 20px 0; margin: 20px 0;
position:relative; /* Allows us to position the loading indicator relative to the table */
} }
table thead tr { table thead tr {
@ -135,13 +137,23 @@ td, th {
display: none; display: none;
} }
#progress { .progress {
position: absolute; position: absolute;
bottom: 50px; top: 0; left: 0; bottom:0; right:0;
padding: auto;
padding-top: 20%;
background: rgba(255,255,255,0.85);
display: none;
/*border-radius: 7px;
border: 1px solid #ddd;*/
} }
#progress img { .progress * {
vertical-align: top; display: block;
margin: 0 auto;
text-align: center;
color: #999;
} }
.settings { .settings {

View File

@ -22,6 +22,7 @@ $(document).ready(function () {
search.searchTerm = searchTerm; search.searchTerm = searchTerm;
socket.emit("search", {searchTerm: searchTerm, offset:search.offset, limit: limit, sortBy: search.sortBy, sortDir: search.sortDir}); socket.emit("search", {searchTerm: searchTerm, offset:search.offset, limit: limit, sortBy: search.sortBy, sortDir: search.sortDir});
search.offset += limit; search.offset += limit;
$('#search-progress').show()
} }
search.offset = 0; search.offset = 0;
search.limit = 12; search.limit = 12;
@ -59,6 +60,18 @@ $(document).ready(function () {
}) })
} }
var progress = {
show: function(msg) {
$('#progress').show()
$('#progress .message').text(msg)
$(window).scrollTop(0)
},
hide: function() {
$('#progress').hide()
$('#progress .message').text('')
}
}
function updateHandlers() { function updateHandlers() {
// Search // Search
$("#search-query").unbind('keyup').keyup(function () { $("#search-query").unbind('keyup').keyup(function () {
@ -67,14 +80,18 @@ $(document).ready(function () {
// update & install // update & install
$(".do-install, .do-update").unbind('click').click(function (e) { $(".do-install, .do-update").unbind('click').click(function (e) {
var row = $(e.target).closest("tr"); var row = $(e.target).closest("tr")
socket.emit("install", row.find(".name").text()); , plugin = row.find(".name").text();
socket.emit("install", plugin);
progress.show('Installing plugin '+plugin+'...')
}); });
// uninstall // uninstall
$(".do-uninstall").unbind('click').click(function (e) { $(".do-uninstall").unbind('click').click(function (e) {
var row = $(e.target).closest("tr"); var row = $(e.target).closest("tr")
socket.emit("uninstall", row.find(".name").text()); , plugin = row.find(".name").text();
socket.emit("uninstall", plugin);
progress.show('Uninstalling plugin '+plugin+'...')
}); });
// Infinite scroll // Infinite scroll
@ -121,16 +138,18 @@ $(document).ready(function () {
var searchWidget = $(".search-results"); var searchWidget = $(".search-results");
searchWidget.find(".results *").remove(); searchWidget.find(".results *").remove();
displayPluginList(search.results, searchWidget.find(".results"), searchWidget.find(".template tr")) displayPluginList(search.results, searchWidget.find(".results"), searchWidget.find(".template tr"))
$('#search-progress').hide()
}); });
socket.on('results:installed', function (data) { socket.on('results:installed', function (data) {
sortPluginList(data.installed, 'name', /*ASC?*/true); sortPluginList(data.installed, 'name', /*ASC?*/true);
$("#installed-plugins *").remove();
data.installed = data.installed.filter(function(plugin) { data.installed = data.installed.filter(function(plugin) {
return plugin.name != 'ep_etherpad-lite' return plugin.name != 'ep_etherpad-lite'
}) })
$("#installed-plugins *").remove();
displayPluginList(data.installed, $("#installed-plugins"), $("#installed-plugin-template")); displayPluginList(data.installed, $("#installed-plugins"), $("#installed-plugin-template"));
progress.hide()
setTimeout(function() { setTimeout(function() {
socket.emit('checkUpdates'); socket.emit('checkUpdates');
@ -150,6 +169,16 @@ $(document).ready(function () {
updateHandlers(); updateHandlers();
}) })
socket.on('finished:install', function(data) {
if(data.error) alert('An error occured while installing the plugin. \n'+data.error)
socket.emit("getInstalled");
})
socket.on('finished:uninstall', function(data) {
if(data.error) alert('An error occured while uninstalling the plugin. \n'+data.error)
socket.emit("getInstalled");
})
// init // init
updateHandlers(); updateHandlers();
socket.emit("getInstalled"); socket.emit("getInstalled");

View File

@ -28,65 +28,70 @@
<li><a href="plugins/info">Troubleshooting information</a> </li> <li><a href="plugins/info">Troubleshooting information</a> </li>
<% e.end_block(); %> <% e.end_block(); %>
</ul> </ul>
<div id="progress"><img src="../static/img/loading.gif">&nbsp;&nbsp;<span class="message"></span></div>
</div> </div>
<div class="innerwrapper"> <div class="innerwrapper">
<h2>Installed plugins</h2> <h2>Installed plugins</h2>
<table>
<thead>
<tr>
<th>Name</th>
<th>Description</th>
<th>Version</th>
<td></td>
</tr>
</thead>
<tbody class="template">
<tr id="installed-plugin-template">
<td class="name" data-label="Name"></td>
<td class="description" data-label="Description"></td>
<td class="version" data-label="Version"></td>
<td class="actions">
<input type="button" value="Uninstall" class="do-uninstall">
</td>
</tr>
</tbody>
<tbody id="installed-plugins">
</tbody>
</table>
<div class="paged listing search-results">
<div class="separator"></div>
<h2>Available plugins</h2>
<form>
<input type="text" name="search" placeholder="Search for plugins to install" id="search-query">
</form>
<table> <table>
<thead> <thead>
<tr> <tr>
<th class="sort up" data-label="name">Name</th> <th>Name</th>
<th class="sort none" data-label="description">Description</th> <th>Description</th>
<th class="sort none" data-label="Version">Version</th> <th>Version</th>
<td></td> <td></td>
</tr> </tr>
</thead> </thead>
<tbody class="template"> <tbody class="template">
<tr> <tr id="installed-plugin-template">
<td class="name" data-label="Name"></td> <td class="name" data-label="Name"></td>
<td class="description" data-label="Description"></td> <td class="description" data-label="Description"></td>
<td class="version" data-label="Version"></td> <td class="version" data-label="Version"></td>
<td class="actions"> <td class="actions">
<input type="button" value="Install" class="do-install"> <input type="button" value="Uninstall" class="do-uninstall">
</td> </td>
</tr> </tr>
</tbody> </tbody>
<tbody class="results"> <tbody id="installed-plugins">
</tbody> </tbody>
</table> </table>
</div>
<div class="paged listing search-results">
<div class="separator"></div>
<h2>Available plugins</h2>
<form>
<input type="text" name="search" placeholder="Search for plugins to install" id="search-query">
</form>
<table>
<thead>
<tr>
<th class="sort up" data-label="name">Name</th>
<th class="sort none" data-label="description">Description</th>
<th class="sort none" data-label="Version">Version</th>
<td></td>
</tr>
</thead>
<tbody class="template">
<tr>
<td class="name" data-label="Name"></td>
<td class="description" data-label="Description"></td>
<td class="version" data-label="Version"></td>
<td class="actions">
<input type="button" value="Install" class="do-install">
</td>
</tr>
</tbody>
<tbody class="results">
</tbody>
<tbody>
<tr><td>
<div id="search-progress" class="progress"><img src="../static/img/loading.gif"/></div>
</td></tr>
</tbody>
</table>
</div>
<div id="progress" class="progress"><p><img src="../static/img/loading.gif"/></p><p><span class="message"></span></p></div>
</div> </div>
</div> </div>