Commit a40c9e8a authored by Leo Iannacone's avatar Leo Iannacone

Merge remote-tracking branch 'github/master' into portable

parents 2029a426 894dea43
# 0.5.0 (2014-06-16)
* [new] add packages search bar
* [new] get buildlog preview by default instead of datestamp when click on a package
* [new] always show datestamp information below the title
* [new] add page Commands which documents out the tasks interface of Deb-o-Matic
* [new] better tooltip over the action buttons (such as Download, View al file, Get all)
* [new] show the debomatic architecture in the header description
* [new] show architecture and version in footer if header is hidden in preferences
* [fix] when watching a file which gets deletion tail lib crashes
# 0.4.2 (2014-06-15) # 0.4.2 (2014-06-15)
* [fix] calculate pidfile for debomatic status check after merging configurations * [fix] calculate pidfile for debomatic status check after merging configurations
...@@ -20,7 +30,7 @@ ...@@ -20,7 +30,7 @@
# 0.2.3 (2014-06-06) # 0.2.3 (2014-06-06)
* [new] get all sources in one click * [new] get all sources in one click
* [fix] code valdiatation via jshint * [fix] code validatation via jshint
# 0.2.2 (2014-06-04) # 0.2.2 (2014-06-04)
* [fix] upgrade to express 4.x * [fix] upgrade to express 4.x
......
...@@ -5,6 +5,13 @@ debomatic-webui ...@@ -5,6 +5,13 @@ debomatic-webui
This interface is built up on [node](http://nodejs.org/) platform and uses intensely [socket.io](http://socket.io/) and [jquery](http://jquery.com/) technologies. This interface is built up on [node](http://nodejs.org/) platform and uses intensely [socket.io](http://socket.io/) and [jquery](http://jquery.com/) technologies.
Whenever you want to leave a suggestion or file a bug report, please open a [new issue](https://github.com/LeoIannacone/debomatic-webui/issues). Whenever you want to leave a suggestion or file a bug report, please open a [new issue](https://github.com/LeoIannacone/debomatic-webui/issues).
Some **debomatic-webui** instances are already running over:
* http://debomatic-amd64.debian.net
* http://debomatic-i386.debian.net
* http://debomatic-armel.debian.net
* http://debomatic-armhf.debian.net
* http://debomatic-powerpc.debian.net
## Requirements ## Requirements
You need **JSONLogger** debomatic module (provided along with this interface) to get installed in debomatic. You need **JSONLogger** debomatic module (provided along with this interface) to get installed in debomatic.
......
...@@ -45,6 +45,8 @@ app.get('/', routes.index); ...@@ -45,6 +45,8 @@ app.get('/', routes.index);
app.get(config.routes.distribution, routes.distribution); app.get(config.routes.distribution, routes.distribution);
if (config.routes.preferences) if (config.routes.preferences)
app.get(config.routes.preferences, routes.preferences); app.get(config.routes.preferences, routes.preferences);
if (config.routes.commands)
app.get(config.routes.commands, routes.commands);
var server = http.createServer(app), var server = http.createServer(app),
io = require('socket.io').listen(server, config.socket); io = require('socket.io').listen(server, config.socket);
......
...@@ -28,10 +28,10 @@ config.routes = {}; ...@@ -28,10 +28,10 @@ config.routes = {};
config.routes.debomatic = '/debomatic'; config.routes.debomatic = '/debomatic';
config.routes.distribution = '/distribution'; config.routes.distribution = '/distribution';
config.routes.preferences = '/preferences'; config.routes.preferences = '/preferences';
config.routes.commands = '/commands';
// web configuration
config.web = {}; config.web = {};
config.web.title = 'Deb-o-Matic web.ui';
config.web.description = 'This is a web interface for debomatic';
// debomatic configuration exportable for web // debomatic configuration exportable for web
config.web.debomatic = {}; config.web.debomatic = {};
...@@ -47,6 +47,10 @@ config.web.debomatic.dput.login = 'debomatic'; ...@@ -47,6 +47,10 @@ config.web.debomatic.dput.login = 'debomatic';
config.web.debomatic.dput.method = 'scp'; config.web.debomatic.dput.method = 'scp';
config.web.debomatic.dput.unsigned_uploads = false; config.web.debomatic.dput.unsigned_uploads = false;
// header title and description
config.web.title = 'Deb-o-Matic web.ui';
config.web.description = 'This is a web interface for debomatic over ' + config.web.debomatic.architecture;
// list of files get preview // list of files get preview
config.web.file = {}; config.web.file = {};
config.web.file.preview = ['buildlog']; config.web.file.preview = ['buildlog'];
...@@ -67,7 +71,7 @@ config.web.preferences.debug = 0; // debug level - 0 means disabled ...@@ -67,7 +71,7 @@ config.web.preferences.debug = 0; // debug level - 0 means disabled
// DO NOT TOUCH these ones // DO NOT TOUCH these ones
config.version = '0.4.2'; config.version = '0.5.0';
config.events = {}; config.events = {};
config.events.error = 'error'; config.events.error = 'error';
......
...@@ -10,6 +10,7 @@ Tail.prototype.watchEvent = function (e) { ...@@ -10,6 +10,7 @@ Tail.prototype.watchEvent = function (e) {
return fs.stat(this.filename, function (err, stats) { return fs.stat(this.filename, function (err, stats) {
if (err) { if (err) {
_this.emit('error', err); _this.emit('error', err);
return;
} }
if (stats.size < _this.pos) { if (stats.size < _this.pos) {
_this.pos = stats.size; _this.pos = stats.size;
......
...@@ -101,10 +101,10 @@ function Page_Distrubion(socket) { ...@@ -101,10 +101,10 @@ function Page_Distrubion(socket) {
label = complete_name; label = complete_name;
if (!view.file.path) if (!view.file.path)
view.file.path = config.paths.debomatic + '/' + view.distribution.name + '/pool/' + view.package.orig_name + '/' + complete_name; view.file.path = config.paths.debomatic + '/' + view.distribution.name + '/pool/' + view.package.orig_name + '/' + complete_name;
label += ' <a class="btn btn-link btn-lg" title="Download" href="' + view.file.path + '"> ' + label += ' <a class="btn btn-link btn-lg" data-toggle="tooltip" title="Download" href="' + view.file.path + '"> ' +
'<span class="glyphicon glyphicon-download-alt"></span></a>'; '<span class="glyphicon glyphicon-download-alt"></span></a>';
if (current_file_in_preview) { if (current_file_in_preview) {
var view_all = $('<a id="get-whole-file" class="btn btn-link btn-lg" title="View the whole file"></a>'); var view_all = $('<a id="get-whole-file" data-toggle="tooltip" class="btn btn-link btn-lg" title="View the whole file"></a>');
view_all.html('<span class="glyphicon glyphicon-eye-open"></span>'); view_all.html('<span class="glyphicon glyphicon-eye-open"></span>');
label += view_all.get(0).outerHTML; label += view_all.get(0).outerHTML;
} }
...@@ -122,7 +122,7 @@ function Page_Distrubion(socket) { ...@@ -122,7 +122,7 @@ function Page_Distrubion(socket) {
$("#get-whole-file").on('click', function () { $("#get-whole-file").on('click', function () {
debug(1, "get the whole file"); debug(1, "get the whole file");
file.get(true); file.get(true);
$(this).remove(); $(this).fadeOut('fast');
}); });
}, },
clean: function () { clean: function () {
...@@ -140,9 +140,10 @@ function Page_Distrubion(socket) { ...@@ -140,9 +140,10 @@ function Page_Distrubion(socket) {
if (socket_data.distribution.packages && socket_data.distribution.packages.length > 0) { if (socket_data.distribution.packages && socket_data.distribution.packages.length > 0) {
socket_data.distribution.packages.forEach(function (p) { socket_data.distribution.packages.forEach(function (p) {
tmp.package = p; tmp.package = p;
// get datestamp if package is clicked // get buildlog if package is clicked
$('#packages ul').append('<li id="package-' + p.orig_name + '"><a href="' + $('#packages ul').append('<li id="package-' + p.orig_name + '"><a href="' +
Utils.from_view_to_hash(tmp) + '/datestamp">' + p.name + ' <span>' + p.version + '</span></a></li>'); Utils.from_view_to_hash(tmp) + '/buildlog"><span class="name">' + p.name + '</span> ' +
'<span class="version">' + p.version + '</span></a></li>');
view.packages[p.orig_name] = Utils.clone(p); view.packages[p.orig_name] = Utils.clone(p);
}); });
packages.select(); packages.select();
...@@ -154,6 +155,7 @@ function Page_Distrubion(socket) { ...@@ -154,6 +155,7 @@ function Page_Distrubion(socket) {
}, },
clean: function () { clean: function () {
$('#packages ul').html(''); $('#packages ul').html('');
$('#packages .search').val('');
}, },
get: function () { get: function () {
if (Utils.check_view_distribution(view)) { if (Utils.check_view_distribution(view)) {
...@@ -168,6 +170,7 @@ function Page_Distrubion(socket) { ...@@ -168,6 +170,7 @@ function Page_Distrubion(socket) {
if (Utils.check_view_package(view)) { if (Utils.check_view_package(view)) {
$('#packages li[id="package-' + view.package.orig_name + '"]').addClass('active'); $('#packages li[id="package-' + view.package.orig_name + '"]').addClass('active');
} }
packages.search();
}, },
unselect: function () { unselect: function () {
$('#packages li').removeClass('active'); $('#packages li').removeClass('active');
...@@ -195,6 +198,26 @@ function Page_Distrubion(socket) { ...@@ -195,6 +198,26 @@ function Page_Distrubion(socket) {
}, },
hide: function () { hide: function () {
$('#packages').hide(); $('#packages').hide();
},
search: function (token) {
if (!token)
token = $("#packages .search").val();
if (!token) {
debug(2, "packages search token empty - showing all");
$("#packages li").show();
} else {
$("#packages li").not('.active').each(function (index) {
var p_name = $(this).find('a span.name').text();
if (p_name.indexOf(token) < 0) {
debug(2, "packages search token:", token, "hiding:", this);
$(this).hide();
} else {
debug(2, "packages search token:", token, "showing:", this);
$(this).show();
}
});
}
sticky.updateOffset();
} }
}; };
...@@ -258,6 +281,26 @@ function Page_Distrubion(socket) { ...@@ -258,6 +281,26 @@ function Page_Distrubion(socket) {
query_data.package = view.package; query_data.package = view.package;
debug_socket('emit', _e.package_files_list, query_data); debug_socket('emit', _e.package_files_list, query_data);
socket.emit(_e.package_files_list, query_data); socket.emit(_e.package_files_list, query_data);
files.get_datestamp();
}
},
get_datestamp: function (socket_data) {
if (Utils.check_view_package(view)) {
if (socket_data && socket_data.package != view.package.orig_name)
return;
var url = config.paths.debomatic + '/' +
view.distribution.name + '/pool/' +
view.package.orig_name + '/' +
view.package.orig_name + '.datestamp';
debug(2, 'getting datestamp');
$.get(url, function (data) {
data = data.replace('Build finished', 'finished');
data = data.replace('Elapsed', 'elapsed');
data = data.replace(/\n$/g, '');
data = data.replace(/\n/g, ' - ');
data = data.replace(/at /g, '');
$("#file .datestamp").html(data);
});
} }
}, },
select: function () { select: function () {
...@@ -280,27 +323,28 @@ function Page_Distrubion(socket) { ...@@ -280,27 +323,28 @@ function Page_Distrubion(socket) {
var file = { var file = {
set: function (socket_data) { set: function (socket_data) {
var file_content = $('#file pre');
view.file = Utils.clone(socket_data.file); view.file = Utils.clone(socket_data.file);
$('#file pre').html(socket_data.file.content); file_content.text(socket_data.file.content);
$('#file').show(); file_content.show();
if (current_file_in_preview) if (current_file_in_preview)
$('#file pre').scrollTop($('#file pre')[0].scrollHeight); file_content.scrollTop(file_content[0].scrollHeight);
}, },
clean: function () { clean: function () {
$('#file pre').html(''); $('#file pre').html('');
$('#file').hide(); $('#file').hide();
}, },
append: function (new_content) { append: function (new_content) {
var content = $('#file pre'); var file_content = $('#file pre');
if (!current_file_in_preview) { if (!current_file_in_preview) {
content.append(new_content); file.append(new_content);
} else { } else {
// always show only config.file.num_lines lines in preview // always show only config.file.num_lines lines in preview
content = content.html().replace(/\n$/, '').split('\n'); var content = file_content.html().replace(/\n$/, '').split('\n');
content = content.concat(new_content.replace(/\n$/, '').split('\n')); content = content.concat(new_content.replace(/\n$/, '').split('\n'));
content = content.slice(-config.file.num_lines).join('\n'); content = content.slice(-config.file.num_lines).join('\n');
$('#file pre').html(content); file_content.html(content);
$('#file pre').scrollTop($('#file pre')[0].scrollHeight); file_content.scrollTop(file_content[0].scrollHeight);
} }
if (config.preferences.autoscroll) { if (config.preferences.autoscroll) {
...@@ -341,16 +385,17 @@ function Page_Distrubion(socket) { ...@@ -341,16 +385,17 @@ function Page_Distrubion(socket) {
} }
debug(2, "file set preview", preview); debug(2, "file set preview", preview);
current_file_in_preview = preview; current_file_in_preview = preview;
var file = $('#file pre');
if (preview) { if (preview) {
$('#file pre').addClass('preview'); $('#file pre').addClass('preview');
var height = (config.file.num_lines) * var height = (config.file.num_lines) *
parseInt($('#file pre').css('line-height').replace(/[^-\d\.]/g, '')) + parseInt(file.css('line-height').replace(/[^-\d\.]/g, '')) +
parseInt($('#file pre').css('padding-top').replace(/[^-\d\.]/g, '')) + parseInt(file.css('padding-top').replace(/[^-\d\.]/g, '')) +
parseInt($('#file pre').css('padding-bottom').replace(/[^-\d\.]/g, '')); parseInt(file.css('padding-bottom').replace(/[^-\d\.]/g, ''));
$('#file pre').css('max-height', height); file.css('max-height', height);
} else { } else {
$('#file pre').removeClass('preview'); file.removeClass('preview');
$('#file pre').css('max-height', 'auto'); file.css('max-height', 'auto');
} }
} }
...@@ -451,6 +496,8 @@ function Page_Distrubion(socket) { ...@@ -451,6 +496,8 @@ function Page_Distrubion(socket) {
var error = { var error = {
set: function (socket_error) { set: function (socket_error) {
if ($('#error').is(':visible'))
return;
$('#error span').html(socket_error); $('#error span').html(socket_error);
error.view(); error.view();
}, },
...@@ -561,6 +608,8 @@ function Page_Distrubion(socket) { ...@@ -561,6 +608,8 @@ function Page_Distrubion(socket) {
breadcrumb.update(); breadcrumb.update();
select(); select();
sticky.reset(); sticky.reset();
// active tooltip
$("[data-toggle='tooltip']").tooltip();
} }
}; };
...@@ -598,6 +647,7 @@ function Page_Distrubion(socket) { ...@@ -598,6 +647,7 @@ function Page_Distrubion(socket) {
socket.on(config.events.broadcast.status_update, function (socket_data) { socket.on(config.events.broadcast.status_update, function (socket_data) {
packages.set_status(socket_data); packages.set_status(socket_data);
sticky.set_status(socket_data); sticky.set_status(socket_data);
files.get_datestamp(socket_data);
}); });
socket.on(_e.package_files_list, function (socket_data) { socket.on(_e.package_files_list, function (socket_data) {
...@@ -662,6 +712,11 @@ function Page_Distrubion(socket) { ...@@ -662,6 +712,11 @@ function Page_Distrubion(socket) {
} }
watch_for_new_lines(); watch_for_new_lines();
// Handle search packages
$('#packages .search').on('keyup', function (event) {
packages.search($(event.target).val());
});
// Update html according with preferences // Update html according with preferences
preferences(); preferences();
......
...@@ -134,9 +134,11 @@ function Page_Generic() { ...@@ -134,9 +134,11 @@ function Page_Generic() {
this.preferences = function () { this.preferences = function () {
if (config.preferences.header) { if (config.preferences.header) {
$('#pageheader').show(); $('#pageheader').show();
$('footer .info').hide();
$('.navbar .home-link').hide(); $('.navbar .home-link').hide();
} else { } else {
$('#pageheader').hide(); $('#pageheader').hide();
$('footer .info').show();
$('.navbar .home-link').show(); $('.navbar .home-link').show();
} }
......
...@@ -102,6 +102,14 @@ footer { ...@@ -102,6 +102,14 @@ footer {
border-top: 1px solid #f0f0f0; border-top: 1px solid #f0f0f0;
} }
footer .info {
margin-right: 5px;
}
#packages .search {
margin-bottom: 5px;
}
#packages li .icon { #packages li .icon {
float: right; float: right;
margin-top: -3px; margin-top: -3px;
...@@ -156,11 +164,17 @@ footer { ...@@ -156,11 +164,17 @@ footer {
color: #101010; color: #101010;
} }
#file .datestamp {
padding-top: 3px;
margin-top: 2px;
display: inline-block;
}
#file pre.preview { #file pre.preview {
overflow:hidden; overflow:hidden;
} }
#title a.btn { #title a.btn {
padding-right: 0; padding: 10px 12px;
float: right; float: right;
} }
'use strict';
/* var config = require('../lib/config.js');
* GET home page.
*/
var config = require('../lib/config.js') exports.index = function (req, res) {
res.render('index', config);
};
exports.index = function(req, res){ exports.distribution = function (req, res) {
res.render('index', config) res.render('distribution', config);
}; };
exports.distribution = function(req, res) { exports.preferences = function (req, res) {
res.render('distribution', config) res.render('preferences', config);
}; };
exports.preferences = function(req, res) { exports.commands = function (req, res) {
res.render('preferences', config) res.render('commands', config);
} };
<% include header.ejs %>
<article class="page">
<!-- <header><h2>Commands</h2></header>
<p class="lead text-muted">
Simple maker for .commands file
</p> -->
<section>
<ul class="nav nav-tabs">
<li class="active"><a href="#introduction" data-toggle="tab">Introduction</a></li>
<li><a href="#remove-packages" data-toggle="tab">Remove</a></li>
<li><a href="#rebuild-packages" data-toggle="tab">Rebuild</a></li>
<li><a href="#porter-uploads" data-toggle="tab">Porter</a></li>
<li><a href="#rebuild-packages-with-extra-build-dependencies" data-toggle="tab">Rebuild with extra</a></li>
</ul>
<!-- Tab panes -->
<div class="tab-content">
<div class="tab-pane active" id="introduction">
<h3>Commands</h3>
<p><b>Deb-o-Matic</b> provides an interface to perform specific tasks into the
Deb-o-Matic <code>packagedir</code> directory such as removing uploaded files or
rebuilding packages. These operations are handled by commands stored in
<code>.commands</code> files, and uploaded into Deb-o-Matic <code>packagedir</code> by using
<code>dcut</code> utility, or by hand.</p>
<p>Using dcut is usually simpler, just launch the following command:</p>
<pre>dcut -U mydebomatic commandfile.commands</pre>
<p>where <code>mydebomatic</code> is a dput host as described in dput.cf (5) man page, and
<code>commandfile.commands</code> is the file containing the commands to be executed by
Deb-o-Matic.</p>
<p>Multiple commands can be stored in a single <code>.commands</code> file, but it is
usually safer to issue a single command per file.</p>
<div class="alert alert-warning">
<b>Caution:</b> If signature checking support is enabled, .commands files must be signed otherwise they will be deleted and no action will be taken.
</div>
</div>
<div class="tab-pane" id="remove-packages">
<h3>Remove packages</h3>
<p>It could happen some files are kept into Deb-o-Matic <code>packagedir</code> and you
need to remove them. In order to do so, you must use the <code>rm</code> command:</p>
<pre>echo "rm foo*" &gt; foo.commands</pre>
<p>where <code>foo*</code> is a regular expression matching the files you want to remove.</p>
</div>
<div class="tab-pane" id="rebuild-packages">
<h3>Rebuild packages</h3>
<p>You could want to rebuild a package already in the mirrors to see whether it
compiles with newer packages, to analyze its content, and so on. In order to do
so, you must use the <code>rebuild</code> command:</p>
<pre>echo "rebuild foo_version dist" &gt; foo.commands</pre>
<p>where <code>foo</code> is the name of the source package you want to rebuild,
<code>version</code> is the version of the package you want to rebuild, and <code>dist</code> is
the distribution which rebuild the package for.</p>
<p>Deb-o-Matic can also rebuild packages available in other distributions. The
syntax is similar, you just have to indicate which distribution to pick
packages from:</p>
<pre>echo "rebuild foo_version dist origin" &gt; foo.commands</pre>
<p>where <code>origin</code> is the distribution to pick packages from.</p>
<div class="alert alert-warning">
<b>Caution:</b> Make sure packages are available in the distribution mirrors, otherwise they
cannot be downloaded and processed by Deb-o-Matic.
</div>
</div>
<div class="tab-pane" id="porter-uploads">
<h3>Porter uploads</h3>
<p>You could want to prepare a porter upload, a binary-only upload which generates
architecture dependent binaries only. Additional information can be found in
<a class="reference external" href="http://www.debian.org/doc/manuals/developers-reference/pkgs.html#porter-guidelines">Debian Developer’s Reference</a>.</p>
<p>In order to do so, you must use the <code>rebuild</code> command:</p>
<pre>echo "porter foo_version dist Joe Doe &lt;j.doe@acme.com&gt;" &gt; foo.commands</pre>
<p>where foo is the name of the source package you want to rebuild, version is
the version of the package you want to rebuild, dist is the distribution which
rebuild package for, and the element between quotes is the address to be used
as maintainer field, which is usually the developer who is preparing the
upload.</p>
<div class="alert alert-warning">
<b>Caution:</b> Make sure packages are available in the distribution mirrors, otherwise they
cannot be downloaded and processed by Deb-o-Matic.
</div>
</div>
<div class="tab-pane" id="rebuild-packages-with-extra-build-dependencies">
<h3>Rebuild packages with extra build-dependencies</h3>
<p>You could want to rebuild a package already in the mirrors also adding a
specific build-dependency to see whether it compiles with a newer library
version. In order to do so, you must use the <code>builddep</code> command:</p>
<pre>echo "builddep foo_version dist extrapackage=packageversion" &gt; foo.commands</pre>
<p>where <code>extrapackage</code> is the name of the package you want to install before
the compilation takes place, and <code>packageversion</code> is the optional version of
the package you want to install.</p>
<div class="alert alert-warning">
<b>Caution:</b> Make sure packages are available in the distribution mirrors, otherwise they
cannot be downloaded and processed by Deb-o-Matic.
</div>
</div>
</div>
</section>
</article>
<% include footer.ejs %>
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
<aside id="sidebar" class="col-md-3"> <aside id="sidebar" class="col-md-3">
<nav id="packages"> <nav id="packages">
<h2>Packages</h2> <h2>Packages</h2>
<input type="text" class="form-control search" placeholder="Search">
<ul class="nav nav-pills nav-stacked"></ul> <ul class="nav nav-pills nav-stacked"></ul>
</nav> </nav>
...@@ -25,7 +26,7 @@ ...@@ -25,7 +26,7 @@
<div class="others"> <div class="others">
<nav id="sources"> <nav id="sources">
<h4>Sources <h4>Sources
<a class="btn btn-link" title="Get all sources in one click" onclick="download_all('#sources')"> <a class="btn btn-link" data-toggle="tooltip" data-placement="right" title="Get all sources in one click" onclick="download_all('#sources')">
<span class="glyphicon glyphicon-download-alt"></span> <span class="glyphicon glyphicon-download-alt"></span>
</a> </a>
</h4> </h4>
...@@ -33,7 +34,7 @@ ...@@ -33,7 +34,7 @@
</nav> </nav>
<nav id="debs"> <nav id="debs">
<h4>Debs <h4>Debs
<a class="btn btn-link" title="Get all debs in one click" onclick="download_all('#debs')"> <a class="btn btn-link" data-toggle="tooltip" data-placement="right" title="Get all debs in one click" onclick="download_all('#debs')">
<span class="glyphicon glyphicon-download-alt"></span> <span class="glyphicon glyphicon-download-alt"></span>
</a> </a>
</h4> </h4>
...@@ -41,7 +42,7 @@ ...@@ -41,7 +42,7 @@
</nav> </nav>
</div> </div>
</section> </section>
<section title="Back on Top" id="sticky-package"> <section data-toggle="tooltip" title="Back on Top" id="sticky-package">
<div id="sticky-package-content"> <div id="sticky-package-content">
<div class="panel-heading"> <div class="panel-heading">
<h3 class="panel-title"> <h3 class="panel-title">
...@@ -64,6 +65,7 @@ ...@@ -64,6 +65,7 @@
</header> </header>
<div id="welcome"></div> <div id="welcome"></div>
<div id="file"> <div id="file">
<h5><span class="label label-default datestamp"></span></h5>
<pre></pre> <pre></pre>
<div id="fileOffset"></div> <div id="fileOffset"></div>
</div> </div>
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
<small class="copyright pull-right text-muted"> <small class="copyright pull-right text-muted">
Fork me on <a href="https://github.com/LeoIannacone/debomatic-webui">github</a> Fork me on <a href="https://github.com/LeoIannacone/debomatic-webui">github</a>
</small> </small>
<small class="info pull-right text-muted"><%= web.debomatic.architecture %> (<%= version %>)</small>
<div id="status" class="clearfix"> <div id="status" class="clearfix">
<span class="label label-default">status:</span> <span class="label label-default">status:</span>
<span class="debomatic idle text-muted">Idle</span> <span class="debomatic idle text-muted">Idle</span>
......
...@@ -27,6 +27,9 @@ ...@@ -27,6 +27,9 @@
</div> </div>
<div id="pages"> <div id="pages">
<ul class="nav navbar-nav pull-right"> <ul class="nav navbar-nav pull-right">
<% if (web.paths.commands) { %>
<li><a href="<%= web.paths.commands %>">Commands</a></li>
<% } %>
<% if (web.paths.preferences) { %> <% if (web.paths.preferences) { %>
<li><a href="<%= web.paths.preferences %>">Preferences</a></li> <li><a href="<%= web.paths.preferences %>">Preferences</a></li>
<% } %> <% } %>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment