Merge remote-tracking branch 'origin/master' into add-user-agreement-to-login-screen

This commit is contained in:
Long Vu
2020-11-17 17:27:30 -05:00
158 changed files with 5417 additions and 1979 deletions

View File

@@ -1,9 +1,8 @@
// Copyright (c) Jupyter Development Team.
// Distributed under the terms of the Modified BSD License.
require(["jquery", "bootstrap", "moment", "jhapi", "utils"], function(
require(["jquery", "moment", "jhapi", "utils"], function(
$,
bs,
moment,
JHAPI,
utils

View File

@@ -1,16 +1,14 @@
// Copyright (c) Jupyter Development Team.
// Distributed under the terms of the Modified BSD License.
require(["jquery", "moment", "jhapi", "utils"], function(
require(["jquery", "moment", "jhapi"], function(
$,
moment,
JHAPI,
utils
JHAPI
) {
"use strict";
var base_url = window.jhdata.base_url;
var prefix = window.jhdata.prefix;
var user = window.jhdata.user;
var api = new JHAPI(base_url);
@@ -50,6 +48,17 @@ require(["jquery", "moment", "jhapi", "utils"], function(
}
}
function startServer() {
var row = getRow($(this));
var serverName = row.find(".new-server-name").val();
if (serverName === "") {
// ../spawn/user/ causes a 404, ../spawn/user redirects correctly to the default server
window.location.href = "./spawn/" + user;
} else {
window.location.href = "./spawn/" + user + "/" + serverName;
}
}
function stopServer() {
var row = getRow($(this));
var serverName = row.data("server-name");
@@ -90,19 +99,22 @@ require(["jquery", "moment", "jhapi", "utils"], function(
});
api.stop_server(user, {
success: function() {
$("#stop").hide();
$("#start")
.text("Start My Server")
.attr("title", "Start your default server")
.attr("disabled", false)
.attr("href", base_url + "spawn/" + user)
.off("click");
},
});
});
$(".new-server-btn").click(function() {
var row = getRow($(this));
var serverName = row.find(".new-server-name").val();
window.location.href = "../spawn/" + user + "/" + serverName;
$(".new-server-btn").click(startServer);
$(".new-server-name").on('keypress', function(e) {
if (e.which === 13) {
startServer.call(this);
}
});
$(".stop-server").click(stopServer);

View File

@@ -0,0 +1,13 @@
// Copyright (c) Jupyter Development Team.
// Distributed under the terms of the Modified BSD License.
require(["jquery", "utils"], function($, utils) {
"use strict";
var hash = utils.parse_url(window.location.href).hash;
if (hash !== undefined && hash !== '') {
var el = $("#start");
var current_spawn_url = el.attr("href");
el.attr("href", current_spawn_url + hash);
}
});

View File

@@ -2,7 +2,7 @@
// Original Copyright (c) IPython Development Team.
// Distributed under the terms of the Modified BSD License.
// Modifications Copyright (c) Juptyer Development Team.
// Modifications Copyright (c) Jupyter Development Team.
// Distributed under the terms of the Modified BSD License.
define(["jquery"], function($) {

View File

@@ -1,3 +1,12 @@
i.sort-icon {
margin-left: 4px;
}
tr.pagination-row > td.pagination-page-info {
vertical-align: middle;
}
.version_footer {
bottom: 0;
width: 100%;
}

View File

@@ -6,7 +6,7 @@
.bg-warning();
padding:10px;
}
.service-login {
text-align: center;
display: table-cell;
@@ -27,9 +27,9 @@
}
input[type=submit] {
margin-top: 16px;
margin-top: 0px;
}
.form-control:focus, input[type=submit]:focus {
box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px @jupyter-orange;
border-color: @jupyter-orange;

View File

@@ -1,8 +1,30 @@
@import "../components/bootstrap/less/variables.less";
@logo-height: 28px;
.jpy-logo {
height: @logo-height;
margin-top: (@navbar-height - @logo-height) / 2;
#jupyterhub-logo {
@media (max-width: @grid-float-breakpoint) {
// same length as the navbar-toggle element, displayed on responsive mode
margin-left: 15px;
}
.jpy-logo {
height: @logo-height;
margin-top: (@navbar-height - @logo-height) / 2;
}
}
.navbar-right {
li {
span {
// same as .nav > li > a from bootstrap, but applied to the span[id="login_widget"]
// or any other span that matches .nav > li > span, but only in responsive mode
@media (max-width: @grid-float-breakpoint) {
position: relative;
display: block;
padding: 10px 15px;
}
}
}
}
#header {
@@ -26,3 +48,19 @@
// .progress-log-event:hover {
// background: rgba(66, 165, 245, 0.2);
// }
.feedback {
&-container {
margin-top: 16px;
}
&-widget {
padding: 5px 0px 0px 6px;
i {
font-size: 2em;
color: lightgrey;
}
}
}

View File

@@ -22,7 +22,7 @@
<thead>
<tr>
{% block thead %}
{{ th("User (%i)" % users|length, 'name') }}
{{ th("User", 'name') }}
{{ th("Admin", 'admin') }}
{{ th("Last Activity", 'last_activity') }}
{{ th("Running (%i)" % running|length, 'running', colspan=2) }}
@@ -96,11 +96,23 @@
<a role="button" class="delete-server btn btn-xs btn-warning">delete server</a>
{%- endif -%}
</td>
</tr>
{% endblock user_row %}
</tr>
{% endfor %}
{% endfor %}
</tbody>
<tfoot>
<tr class="pagination-row">
<td colspan="3">
{% if pagination.links %}
<div class="pagination menu">{{ pagination.links|safe }}</div>
{% endif %}
</td>
<td colspan="2" class="pagination-page-info">
Displaying users {{ pagination.info.start|safe }} - {{ pagination.info.end|safe }} of {{ pagination.info.total|safe }}
</td>
</tr>
</tfoot>
</table>
</div>
@@ -158,6 +170,14 @@
{% endblock %}
{% block footer %}
<div class="container-fluid navbar-default small version_footer">
<div class="navbar-text">
JupyterHub {{ server_version }}
</div>
</div>
{% endblock %}
{% block script %}
{{ super() }}
<script type="text/javascript">

View File

@@ -4,7 +4,6 @@
{% endif %}
{% block main %}
<div class="container">
<div class="row">
<div class="text-center">
@@ -83,7 +82,8 @@
</tbody>
</table>
{% endif %}
{% endblock %}
</div>
{% endblock main %}
{% block script %}
{{ super() }}

View File

@@ -56,13 +56,18 @@
tabindex="2"
/>
<input
type="submit"
id="login_submit"
class='btn btn-jupyter'
value='Sign In'
tabindex="3"
/>
<div class="feedback-container">
<input
id="login_submit"
type="submit"
class='btn btn-jupyter'
value='Sign in'
tabindex="3"
/>
<div class="feedback-widget hidden">
<i class="fa fa-spinner"></i>
</div>
</div>
{% block login_terms %}
{% if login_term_url %}
@@ -91,6 +96,13 @@ if (window.location.protocol === "http:") {
var warning = document.getElementById('insecure-login-warning');
warning.className = warning.className.replace(/\bhidden\b/, '');
}
// setup onSubmit feedback
$('form').submit((e) => {
var form = $(e.target);
form.find('.feedback-container>input').attr('disabled', true);
form.find('.feedback-container>*').toggleClass('hidden');
form.find('.feedback-widget>*').toggleClass('fa-pulse');
});
</script>
{% if login_term_url %}

View File

@@ -23,7 +23,14 @@
{% endif %}
Would you like to retry starting it?
{% else %}
Your server {{ server_name }} is not running. Would you like to start it?
Your server {{ server_name }} is not running.
{% if implicit_spawn_seconds %}
It will be restarted automatically.
If you are not redirected in a few seconds,
click below to launch your server.
{% else %}
Would you like to start it?
{% endif %}
{% endif %}
</p>
{% endblock %}
@@ -42,3 +49,21 @@
</div>
{% endblock %}
{% block script %}
{{ super () }}
{% if implicit_spawn_seconds %}
<script type="text/javascript">
var spawn_url = "{{ spawn_url }}";
var implicit_spawn_seconds = {{ implicit_spawn_seconds }};
setTimeout(function () {
console.log("redirecting to spawn at", spawn_url);
window.location = spawn_url;
},
1000 * implicit_spawn_seconds
);
</script>
{% endif %}
<script type="text/javascript">
require(["not_running"]);
</script>
{% endblock script %}

View File

@@ -34,9 +34,14 @@
{% block stylesheet %}
<link rel="stylesheet" href="{{ static_url("css/style.min.css") }}" type="text/css"/>
{% endblock %}
{% block favicon %}
<link rel="icon" href="{{ static_url("favicon.ico") }}" type="image/x-icon">
{% endblock %}
{% block scripts %}
<script src="{{static_url("components/requirejs/require.js") }}" type="text/javascript" charset="utf-8"></script>
<script src="{{static_url("components/jquery/dist/jquery.min.js") }}" type="text/javascript" charset="utf-8"></script>
<script src="{{static_url("components/bootstrap/dist/js/bootstrap.min.js") }}" type="text/javascript" charset="utf-8"></script>
{% endblock %}
<script>
require.config({
{% if version_hash %}
@@ -63,7 +68,7 @@
base_url: "{{base_url}}",
prefix: "{{prefix}}",
{% if user %}
user: "{{user.name}}",
user: "{{user.json_escaped_name}}",
{% endif %}
{% if admin_access %}
admin_access: true,
@@ -101,12 +106,14 @@
<a href="{{logo_url or base_url}}"><img src='{{base_url}}logo' alt='JupyterHub' class='jpy-logo' title='Home'/></a>
</span>
{% endblock %}
{% if user %}
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#thenavbar" aria-expanded="false">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
{% endif %}
</div>
<div class="collapse navbar-collapse" id="thenavbar">
@@ -118,6 +125,16 @@
{% if user.admin %}
<li><a href="{{base_url}}admin">Admin</a></li>
{% endif %}
{% if services %}
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Services<span class="caret"></span></a>
<ul class="dropdown-menu">
{% for service in services %}
<li><a class="dropdown-item" href="{{service.prefix}}">{{service.name}}</a></li>
{% endfor %}
</ul>
</li>
{% endif %}
{% endblock %}
</ul>
{% endif %}
@@ -127,7 +144,7 @@
{% block login_widget %}
<span id="login_widget">
{% if user %}
<p class="navbar-text">{{user.name}}</p>
<p class="navbar-text">{{user.name}}</p>
<a id="logout" role="button" class="navbar-btn btn-sm btn btn-default" href="{{logout_url}}"> <i aria-hidden="true" class="fa fa-sign-out"></i> Logout</a>
{% else %}
<a id="login" role="button" class="btn-sm btn navbar-btn btn-default" href="{{login_url}}">Login</a>
@@ -148,7 +165,7 @@
{% block announcement %}
{% if announcement %}
<div class="container text-center announcement">
<div class="container text-center announcement alert alert-warning">
{{ announcement | safe }}
</div>
{% endif %}
@@ -158,6 +175,9 @@
{% block main %}
{% endblock %}
{% block footer %}
{% endblock %}
{% call modal('Error', btn_label='OK') %}
<div class="ajax-error">
The error

View File

@@ -8,7 +8,7 @@
<div class="container">
{% block heading %}
<div class="row text-center">
<h1>Spawner Options</h1>
<h1>Server Options</h1>
</div>
{% endblock %}
<div class="row col-sm-offset-2 col-sm-8">
@@ -23,9 +23,27 @@
<form enctype="multipart/form-data" id="spawn_form" action="{{url}}" method="post" role="form">
{{spawner_options_form | safe}}
<br>
<input type="submit" value="Spawn" class="btn btn-jupyter form-control">
<div class="feedback-container">
<input type="submit" value="Start" class="btn btn-jupyter form-control">
<div class="feedback-widget hidden">
<i class="fa fa-spinner"></i>
</div>
</div>
</form>
</div>
</div>
{% endblock %}
{% block script %}
{{ super() }}
<script>
// setup onSubmit feedback
$('form').submit((e) => {
var form = $(e.target);
form.find('.feedback-container>input').attr('disabled', true);
form.find('.feedback-container>*').toggleClass('hidden');
form.find('.feedback-widget>*').toggleClass('fa-pulse');
});
</script>
{% endblock %}