Merge pull request #6828 from takluyver/terminal-list

Add terminals tab to the dashboard
pull/37/head
Min RK 11 years ago
commit 196b91e73b

@ -173,6 +173,7 @@ class NotebookWebApplication(web.Application):
mathjax_url=ipython_app.mathjax_url,
config=ipython_app.config,
jinja2_env=env,
terminals_available=False, # Set later if terminals are available
)
# allow custom overrides for the tornado web app.
@ -765,10 +766,9 @@ class NotebookApp(BaseIPythonApplication):
try:
from .terminal import initialize
initialize(self.web_app)
self.web_app.terminals_available = True
self.web_app.settings['terminals_available'] = True
except ImportError as e:
self.log.info("Terminals not available (error was %s)", e)
self.web_app.terminals_available = False
def init_signal(self):
if not sys.platform.startswith('win'):

@ -11,6 +11,7 @@ require([
'tree/js/clusterlist',
'tree/js/sessionlist',
'tree/js/kernellist',
'tree/js/terminallist',
'auth/js/loginwidget',
// only loaded, not used:
'jqueryui',
@ -25,7 +26,8 @@ require([
notebooklist,
clusterlist,
sesssionlist,
kernellist,
kernellist,
terminallist,
loginwidget){
page = new page.Page();
@ -44,6 +46,11 @@ require([
kernel_list = new kernellist.KernelList('#running_list', $.extend({
session_list: session_list},
common_options));
if (utils.get_body_data("terminalsAvailable") === "True") {
terminal_list = new terminallist.TerminalList('#terminal_list', common_options);
}
login_widget = new loginwidget.LoginWidget('#login_widget', common_options);
$('#new_notebook').click(function (e) {

@ -0,0 +1,103 @@
// Copyright (c) IPython Development Team.
// Distributed under the terms of the Modified BSD License.
define([
'base/js/namespace',
'base/js/utils',
'jquery',
'tree/js/notebooklist',
], function(IPython, utils, $, notebooklist) {
"use strict";
var TerminalList = function (selector, options) {
// Constructor
//
// Parameters:
// selector: string
// options: dictionary
// Dictionary of keyword arguments.
// base_url: string
this.base_url = options.base_url || utils.get_body_data("baseUrl");
this.element_name = options.element_name || 'terminal';
this.selector = selector;
this.terminals = [];
if (this.selector !== undefined) {
this.element = $(selector);
this.style();
this.bind_events();
this.load_terminals();
}
};
TerminalList.prototype = Object.create(notebooklist.NotebookList.prototype);
TerminalList.prototype.bind_events = function () {
var that = this;
$('#refresh_' + this.element_name + '_list').click(function () {
that.load_terminals();
});
$('#new_terminal').click($.proxy(this.new_terminal, this));
};
TerminalList.prototype.new_terminal = function() {
var url = utils.url_join_encode(this.base_url, 'terminals/new');
window.open(url, '_blank');
};
TerminalList.prototype.load_terminals = function() {
var that = this;
var url = utils.url_join_encode(this.base_url, 'api/terminals');
$.ajax(url, {
type: "GET",
cache: false,
dataType: "json",
success: $.proxy(this.terminals_loaded, this),
error : utils.log_ajax_error
});
};
TerminalList.prototype.terminals_loaded = function (data) {
this.terminals = data;
this.clear_list();
var item, path_name, term;
for (var i=0; i < this.terminals.length; i++) {
term = this.terminals[i];
item = this.new_item(-1);
this.add_link(term.name, item);
this.add_shutdown_button(term.name, item);
}
$('#terminal_list_header').toggle(data.length === 0);
};
TerminalList.prototype.add_link = function(name, item) {
item.data('term-name', name);
item.find(".item_name").text("terminals/" + name);
item.find(".item_icon").addClass("fa fa-terminal");
var link = item.find("a.item_link")
.attr('href', utils.url_join_encode(this.base_url, "terminals", name));
link.attr('target', '_blank');
this.add_shutdown_button(name, item);
};
TerminalList.prototype.add_shutdown_button = function(name, item) {
var that = this;
var shutdown_button = $("<button/>").text("Shutdown").addClass("btn btn-xs btn-danger").
click(function (e) {
var settings = {
processData : false,
type : "DELETE",
dataType : "json",
success : function () {
that.load_terminals();
},
error : utils.log_ajax_error,
};
var url = utils.url_join_encode(that.base_url, 'api/terminals', name);
$.ajax(url, settings);
return false;
});
item.find(".item_buttons").text("").append(shutdown_button);
};
return {TerminalList: TerminalList};
});

@ -12,6 +12,7 @@
data-base-url="{{base_url}}"
data-notebook-path="{{notebook_path}}"
data-terminals-available="{{terminals_available}}"
{% endblock %}
@ -24,6 +25,9 @@ data-notebook-path="{{notebook_path}}"
<ul id="tabs" class="nav nav-tabs">
<li class="active"><a href="#notebooks" data-toggle="tab">Notebooks</a></li>
<li><a href="#running" data-toggle="tab">Running</a></li>
{% if terminals_available %}
<li><a href="#terminals" data-toggle="tab">Terminals</a></li>
{% endif %}
<li><a href="#clusters" data-toggle="tab">Clusters</a></li>
</ul>
@ -79,6 +83,29 @@ data-notebook-path="{{notebook_path}}"
</div>
</div>
</div>
{% if terminals_available %}
<div id="terminals" class="tab-pane">
<div id="terminal_toolbar" class="row">
<div class="col-xs-8 no-padding">
<span id="terminal_list_info">Currently running terminals</span>
</div>
<div class="col-xs-4 no-padding tree-buttons">
<span id="terminal_buttons" class="pull-right">
<button id="new_terminal" title="New terminal" class="btn btn-default btn-xs">New Terminal</button>
<button id="refresh_terminal_list" title="Refresh terminal list" class="btn btn-default btn-xs"><i class="fa fa-refresh"></i></button>
</span>
</div>
</div>
<div id="terminal_list">
<div id="terminal_list_header" class="row list_header">
<div> There are no terminals running. </div>
</div>
</div>
</div>
{% endif %}
<div id="clusters" class="tab-pane">

@ -55,7 +55,8 @@ class TreeHandler(IPythonHandler):
self.write(self.render_template('tree.html',
page_title=page_title,
notebook_path=path,
breadcrumbs=breadcrumbs
breadcrumbs=breadcrumbs,
terminals_available=self.settings['terminals_available'],
))

Loading…
Cancel
Save