mirror of
https://github.com/jupyterhub/jupyterhub.git
synced 2025-10-07 10:04:07 +00:00
add and run djlint formatter
This commit is contained in:
@@ -33,6 +33,15 @@ repos:
|
|||||||
rev: v4.0.0-alpha.8
|
rev: v4.0.0-alpha.8
|
||||||
hooks:
|
hooks:
|
||||||
- id: prettier
|
- id: prettier
|
||||||
|
exclude: .*/templates/.*
|
||||||
|
|
||||||
|
# autoformat HTML templates
|
||||||
|
- repo: https://github.com/djlint/djLint
|
||||||
|
rev: v1.34.1
|
||||||
|
hooks:
|
||||||
|
- id: djlint-reformat-jinja
|
||||||
|
files: ".*templates/.*.html"
|
||||||
|
types_or: ["html"]
|
||||||
|
|
||||||
# Autoformat and linting, misc. details
|
# Autoformat and linting, misc. details
|
||||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||||
|
@@ -1,26 +1,24 @@
|
|||||||
{%- extends "!layout.html" %}
|
{%- extends "!layout.html" %}
|
||||||
|
|
||||||
{# not sure why, but theme CSS prevents scrolling within redoc content
|
{# not sure why, but theme CSS prevents scrolling within redoc content
|
||||||
# If this were fixed, we could keep the navbar and footer
|
# If this were fixed, we could keep the navbar and footer
|
||||||
#}
|
#}
|
||||||
{%- block css %}{%- endblock %}
|
{% block css %}
|
||||||
{%- block docs_navbar %}{%- endblock %}
|
{% endblock css %}
|
||||||
{%- block footer %}{% endblock %}
|
{% block docs_navbar %}
|
||||||
{%- block body_tag %}
|
{% endblock docs_navbar %}
|
||||||
<body>
|
{% block footer %}
|
||||||
{%- endblock %}
|
{% endblock footer %}
|
||||||
|
{# djlint: off #}
|
||||||
|
{%- block body_tag -%}<body>{%- endblock body_tag %}
|
||||||
|
{# djlint: on #}
|
||||||
{%- block extrahead %}
|
{%- block extrahead %}
|
||||||
{{ super() }}
|
{{ super() }}
|
||||||
<link href="{{ pathto('_static/redoc-fonts.css', 1) }}"
|
<link href="{{ pathto('_static/redoc-fonts.css', 1) }}" rel="stylesheet" />
|
||||||
rel="stylesheet"
|
<script src="{{ pathto('_static/redoc.js', 1) }}"></script>
|
||||||
/>
|
{%- endblock extrahead %}
|
||||||
<script src="{{ pathto('_static/redoc.js', 1) }}"></script>
|
|
||||||
{%- endblock %}
|
|
||||||
|
|
||||||
{%- block content %}
|
{%- block content %}
|
||||||
<redoc id="redoc-spec"></redoc>
|
<redoc id="redoc-spec"></redoc>
|
||||||
<script>
|
<script>
|
||||||
if (location.protocol === "file:") {
|
if (location.protocol === "file:") {
|
||||||
document.body.innerText = "Rendered API specification doesn't work with file: protocol. Use sphinx-autobuild to do local builds of the docs, served over HTTP."
|
document.body.innerText = "Rendered API specification doesn't work with file: protocol. Use sphinx-autobuild to do local builds of the docs, served over HTTP."
|
||||||
} else {
|
} else {
|
||||||
@@ -30,5 +28,5 @@
|
|||||||
document.getElementById("redoc-spec"),
|
document.getElementById("redoc-spec"),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
{%- endblock %}
|
{%- endblock content %}
|
||||||
|
@@ -1,9 +1,10 @@
|
|||||||
{% extends "templates/page.html" %} {% block announcement %}
|
{% extends "templates/page.html" %}
|
||||||
<div class="container text-center announcement"></div>
|
{% block announcement %}<div class="container text-center announcement"></div>{% endblock %}
|
||||||
{% endblock %} {% block script %} {{ super() }}
|
{% block script %}
|
||||||
<script>
|
{{ super() }}
|
||||||
|
<script>
|
||||||
$.get("/services/announcement/", function (data) {
|
$.get("/services/announcement/", function (data) {
|
||||||
$(".announcement").html(data["announcement"]);
|
$(".announcement").html(data["announcement"]);
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@@ -2,11 +2,9 @@
|
|||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
|
|
||||||
<title>JupyterHub</title>
|
<title>JupyterHub</title>
|
||||||
<meta http-equiv="X-UA-Compatible" content="chrome=1" />
|
<meta http-equiv="X-UA-Compatible" content="chrome=1" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
|
||||||
<link rel="stylesheet" href="/static/css/style.min.css" type="text/css" />
|
<link rel="stylesheet" href="/static/css/style.min.css" type="text/css" />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
@@ -7,30 +7,23 @@ It makes the following modifications:
|
|||||||
- update logo url to jupyterhub
|
- update logo url to jupyterhub
|
||||||
- remove `?redirects` url param that may be added by jupyterhub
|
- remove `?redirects` url param that may be added by jupyterhub
|
||||||
#}
|
#}
|
||||||
|
|
||||||
{% extends "templates/page.html" %}
|
{% extends "templates/page.html" %}
|
||||||
|
|
||||||
{% block header_buttons %}
|
{% block header_buttons %}
|
||||||
{{ super() }}
|
{{ super() }}
|
||||||
<span>
|
<span>
|
||||||
<a
|
<a href="{{ hub_control_panel_url }}"
|
||||||
href="{{hub_control_panel_url}}"
|
id="jupyterhub-control-panel-link"
|
||||||
id="jupyterhub-control-panel-link"
|
class="btn btn-default btn-sm navbar-btn pull-right"
|
||||||
class="btn btn-default btn-sm navbar-btn pull-right"
|
style="margin-right: 4px;
|
||||||
style="margin-right: 4px; margin-left: 2px"
|
margin-left: 2px">Control Panel</a>
|
||||||
>
|
</span>
|
||||||
Control Panel
|
|
||||||
</a>
|
|
||||||
</span>
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block logo %}
|
{% block logo %}
|
||||||
<img src="{{logo_url}}" alt="Jupyter Notebook" />
|
<img src="{{ logo_url }}" alt="Jupyter Notebook" />
|
||||||
{% endblock logo %}
|
{% endblock logo %}
|
||||||
|
|
||||||
{% block script %}
|
{% block script %}
|
||||||
{{ super() }}
|
{{ super() }}
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
function _remove_redirects_param() {
|
function _remove_redirects_param() {
|
||||||
// remove ?redirects= param from URL so that
|
// remove ?redirects= param from URL so that
|
||||||
// successful page loads don't increment the redirect loop counter
|
// successful page loads don't increment the redirect loop counter
|
||||||
@@ -57,5 +50,5 @@ It makes the following modifications:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
_remove_redirects_param();
|
_remove_redirects_param();
|
||||||
</script>
|
</script>
|
||||||
{% endblock script %}
|
{% endblock script %}
|
||||||
|
@@ -120,6 +120,11 @@ select = [
|
|||||||
"F", # flake8
|
"F", # flake8
|
||||||
]
|
]
|
||||||
|
|
||||||
|
# djlint lints/formats our jinja templates
|
||||||
|
# https://djlint.com/docs/configuration/
|
||||||
|
[tool.djlint]
|
||||||
|
indent = 2
|
||||||
|
|
||||||
# tbump is used to simplify and standardize the release process when updating
|
# tbump is used to simplify and standardize the release process when updating
|
||||||
# the version, making a git commit and tag, and pushing changes.
|
# the version, making a git commit and tag, and pushing changes.
|
||||||
#
|
#
|
||||||
|
@@ -1,5 +1,2 @@
|
|||||||
{% extends "error.html" %}
|
{% extends "error.html" %}
|
||||||
|
{% block error_detail %}<p>Jupyter has lots of moons, but this is not one...</p>{% endblock %}
|
||||||
{% block error_detail %}
|
|
||||||
<p>Jupyter has lots of moons, but this is not one...</p>
|
|
||||||
{% endblock %}
|
|
||||||
|
@@ -1,55 +1,51 @@
|
|||||||
{% extends "page.html" %}
|
{% extends "page.html" %}
|
||||||
{% block login_widget %}
|
{% block login_widget %}{% endblock %}
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block main %}
|
{% block main %}
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row justify-content-center">
|
<div class="row justify-content-center">
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<h1 class="text-center">Accept sharing invitation</h1>
|
<h1 class="text-center">Accept sharing invitation</h1>
|
||||||
<p class="lead">
|
<p class="lead">
|
||||||
You ({{ user.name }}) have been invited to access {{ owner.name }}'s server
|
You ({{ user.name }}) have been invited to access {{ owner.name }}'s server
|
||||||
{%- if spawner.name %} ({{ spawner.name }}){%- endif %} at <a href="{{ spawner_url | safe }}">{{ spawner_url }}</a>
|
{%- if spawner.name %}({{ spawner.name }}){%- endif %} at <a href="{{ spawner_url | safe }}">{{ spawner_url }}</a>
|
||||||
</p>
|
</p>
|
||||||
|
{% if not spawner_ready %}
|
||||||
{% if not spawner_ready %}
|
<p class="alert alert-danger">
|
||||||
<p class="alert alert-danger">
|
The server at {{ spawner_url }} is not currently running.
|
||||||
The server at {{ spawner_url }} is not currently running.
|
After accepting permission, you may need to ask {{ owner.name }}
|
||||||
After accepting permission, you may need to ask {{ owner.name }}
|
to start the server before you can access it.
|
||||||
to start the server before you can access it.
|
</p>
|
||||||
</p>
|
{% endif %}
|
||||||
{% endif %}
|
<form method="POST" action="">
|
||||||
|
<div class="card">
|
||||||
<form method="POST" action="">
|
<div class="card-header">
|
||||||
<div class="card">
|
By accepting the invitation, you will be granted the following permissions,
|
||||||
<div class="card-header">
|
restricted to this particular server:
|
||||||
By accepting the invitation, you will be granted the following permissions,
|
</div>
|
||||||
restricted to this particular server:
|
<div class="card-body">
|
||||||
</div>
|
{# these are the 'real' inputs to the form -#}
|
||||||
<div class="card-body">
|
<input type="hidden" name="_xsrf" value="{{ xsrf }}" />
|
||||||
{# these are the 'real' inputs to the form -#}
|
<input type="hidden" name="code" value="{{ code }}" />
|
||||||
<input type="hidden" name="_xsrf" value="{{ xsrf }}" />
|
{% for scope_info in scope_descriptions -%}
|
||||||
<input type="hidden" name="code" value="{{ code }}" />
|
<div class="form-check input-group">
|
||||||
{% for scope_info in scope_descriptions -%}
|
<label>
|
||||||
<div class="form-check input-group">
|
<span>
|
||||||
<label>
|
{{ scope_info['description'] }}
|
||||||
<span>
|
{% if scope_info['filter'] %}Applies to {{ scope_info['filter'] }}.{% endif %}
|
||||||
{{ scope_info['description'] }}
|
</span>
|
||||||
{% if scope_info['filter'] %}
|
</label>
|
||||||
Applies to {{ scope_info['filter'] }}. {% endif %}
|
</div>
|
||||||
</span>
|
{% endfor -%}
|
||||||
</label>
|
</div>
|
||||||
|
<div class="card-footer">
|
||||||
|
<button type="submit" class="form-control btn btn-jupyter">Accept invitation</button>
|
||||||
|
<p class="small">
|
||||||
|
After accepting the invitation, you will be redirected to <a href="{{ next_url | safe }}">{{ next_url }}</a>.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
</div>
|
</div>
|
||||||
{% endfor -%}
|
|
||||||
</div>
|
|
||||||
<div class="card-footer">
|
|
||||||
<button type="submit" class="form-control btn btn-jupyter" >Accept invitation</button>
|
|
||||||
<p class="small">
|
|
||||||
After accepting the invitation, you will be redirected to <a href="{{ next_url | safe }}">{{ next_url }}</a>.
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
|
||||||
</div></div></div>
|
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@@ -1,17 +1,13 @@
|
|||||||
{% extends "page.html" %}
|
{% extends "page.html" %}
|
||||||
|
|
||||||
{% block main %}
|
{% block main %}
|
||||||
<div id="react-admin-hook">
|
<div id="react-admin-hook">
|
||||||
<script id="jupyterhub-admin-config">
|
<script id="jupyterhub-admin-config">
|
||||||
window.api_page_limit = parseInt("{{ api_page_limit|safe }}")
|
window.api_page_limit = parseInt("{{ api_page_limit|safe }}")
|
||||||
window.base_url = "{{ base_url|safe }}"
|
window.base_url = "{{ base_url|safe }}"
|
||||||
</script>
|
</script>
|
||||||
<script src={{ static_url("js/admin-react.js") }}></script>
|
<script src={{ static_url("js/admin-react.js") }}></script>
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block footer %}
|
{% block footer %}
|
||||||
<div class="py-2 px-4 bg-body-tertiary small version_footer">
|
<div class="py-2 px-4 bg-body-tertiary small version_footer">JupyterHub {{ server_version }}</div>
|
||||||
JupyterHub {{ server_version }}
|
|
||||||
</div>
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@@ -1,40 +1,19 @@
|
|||||||
{% extends "page.html" %}
|
{% extends "page.html" %}
|
||||||
|
{% block login_widget %}{% endblock %}
|
||||||
{% block login_widget %}
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block main %}
|
{% block main %}
|
||||||
|
<div class="error">
|
||||||
<div class="error">
|
{% block h1_error %}
|
||||||
{% block h1_error %}
|
<h1>{{ status_code }} : {{ status_message }}</h1>
|
||||||
<h1>
|
{% endblock h1_error %}
|
||||||
{{status_code}} : {{status_message}}
|
{% block error_detail %}
|
||||||
</h1>
|
{% if message %}<p>{{ message }}</p>{% endif %}
|
||||||
{% endblock h1_error %}
|
{% if message_html %}<p>{{ message_html | safe }}</p>{% endif %}
|
||||||
{% block error_detail %}
|
{% if extra_error_html %}<p>{{ extra_error_html | safe }}</p>{% endif %}
|
||||||
{% if message %}
|
{% endblock error_detail %}
|
||||||
<p>
|
</div>
|
||||||
{{message}}
|
|
||||||
</p>
|
|
||||||
{% endif %}
|
|
||||||
{% if message_html %}
|
|
||||||
<p>
|
|
||||||
{{message_html | safe}}
|
|
||||||
</p>
|
|
||||||
{% endif %}
|
|
||||||
{% if extra_error_html %}
|
|
||||||
<p>
|
|
||||||
{{extra_error_html | safe}}
|
|
||||||
</p>
|
|
||||||
{% endif %}
|
|
||||||
{% endblock error_detail %}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block script %}
|
{% block script %}
|
||||||
{{super()}}
|
{{ super() }}
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
function _remove_redirects_from_url() {
|
function _remove_redirects_from_url() {
|
||||||
if (window.location.search.length <= 1) {
|
if (window.location.search.length <= 1) {
|
||||||
|
@@ -2,93 +2,89 @@
|
|||||||
{% if announcement_home is string %}
|
{% if announcement_home is string %}
|
||||||
{% set announcement = announcement_home %}
|
{% set announcement = announcement_home %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% block main %}
|
{% block main %}
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<h1 class="sr-only">JupyterHub home page</h1>
|
<h1 class="sr-only">JupyterHub home page</h1>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="text-center">
|
<div class="text-center">
|
||||||
{% if default_server.active %}
|
{% if default_server.active %}<a id="stop" role="button" class="btn btn-lg btn-danger">Stop My Server</a>{% endif %}
|
||||||
<a id="stop" role="button" class="btn btn-lg btn-danger">
|
<a id="start"
|
||||||
Stop My Server
|
role="button"
|
||||||
|
class="btn btn-lg btn-primary"
|
||||||
|
href="{{ url }}">
|
||||||
|
{% if not default_server.active %}Start{% endif %}
|
||||||
|
My Server
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
</div>
|
||||||
<a id="start" role="button" class="btn btn-lg btn-primary" href="{{ url }}">
|
|
||||||
{% if not default_server.active %}Start{% endif %}
|
|
||||||
My Server
|
|
||||||
</a>
|
|
||||||
</div>
|
</div>
|
||||||
|
{% if allow_named_servers %}
|
||||||
|
<h2>Named Servers</h2>
|
||||||
|
<p>
|
||||||
|
In addition to your default server,
|
||||||
|
you may have additional
|
||||||
|
{% if named_server_limit_per_user > 0 %}{{ named_server_limit_per_user }}{% endif %}
|
||||||
|
server(s) with names.
|
||||||
|
This allows you to have more than one server running at the same time.
|
||||||
|
</p>
|
||||||
|
{% set named_spawners = user.all_spawners(include_default=False)|list %}
|
||||||
|
<table class="server-table table table-striped">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Server name</th>
|
||||||
|
<th>URL</th>
|
||||||
|
<th>Last activity</th>
|
||||||
|
<th>Actions</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr class="home-server-row add-server-row">
|
||||||
|
<td colspan="4">
|
||||||
|
<input class="new-server-name"
|
||||||
|
aria-label="server name"
|
||||||
|
placeholder="name-your-server">
|
||||||
|
<button role="button"
|
||||||
|
type="button"
|
||||||
|
class="new-server-btn btn btn-xs btn-primary">Add New Server</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% for spawner in named_spawners %}
|
||||||
|
<tr class="home-server-row" data-server-name="{{ spawner.name }}">
|
||||||
|
{# name #}
|
||||||
|
<td>{{ spawner.name }}</td>
|
||||||
|
{# url #}
|
||||||
|
<td>
|
||||||
|
<a class="server-link {% if not spawner.ready %}hidden{% endif %}"
|
||||||
|
href="{{ user.server_url(spawner.name) }}">{{ user.server_url(spawner.name) }}</a>
|
||||||
|
</td>
|
||||||
|
{# activity #}
|
||||||
|
<td class='time-col'>
|
||||||
|
{% if spawner.last_activity %}
|
||||||
|
{{ spawner.last_activity.isoformat() + 'Z' }}
|
||||||
|
{% else %}
|
||||||
|
Never
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
{# actions #}
|
||||||
|
<td>
|
||||||
|
<a role="button"
|
||||||
|
class="stop-server btn btn-xs btn-danger{% if not spawner.active %} hidden{% endif %}"
|
||||||
|
id="stop-{{ spawner.name }}">stop</a>
|
||||||
|
<a role="button"
|
||||||
|
class="start-server btn btn-xs btn-primary {% if spawner.active %}hidden{% endif %}"
|
||||||
|
id="start-{{ spawner.name }}"
|
||||||
|
href="{{ base_url }}spawn/{{ user.name }}/{{ spawner.name }}">start</a>
|
||||||
|
<button role="button"
|
||||||
|
class="delete-server btn btn-xs btn-danger{% if spawner.active %} hidden{% endif %}"
|
||||||
|
id="delete-{{ spawner.name }}">delete</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
{% if allow_named_servers %}
|
|
||||||
<h2>
|
|
||||||
Named Servers
|
|
||||||
</h2>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
In addition to your default server,
|
|
||||||
you may have additional {% if named_server_limit_per_user > 0 %}{{ named_server_limit_per_user }} {% endif %}server(s) with names.
|
|
||||||
This allows you to have more than one server running at the same time.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
{% set named_spawners = user.all_spawners(include_default=False)|list %}
|
|
||||||
|
|
||||||
<table class="server-table table table-striped">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>Server name</th>
|
|
||||||
<th>URL</th>
|
|
||||||
<th>Last activity</th>
|
|
||||||
<th>Actions</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<tr class="home-server-row add-server-row">
|
|
||||||
<td colspan="4">
|
|
||||||
<input class="new-server-name" aria-label="server name" placeholder="name-your-server">
|
|
||||||
<button role="button" type="button" class="new-server-btn btn btn-xs btn-primary">
|
|
||||||
Add New Server
|
|
||||||
</button>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{% for spawner in named_spawners %}
|
|
||||||
<tr class="home-server-row" data-server-name="{{ spawner.name }}">
|
|
||||||
{# name #}
|
|
||||||
<td>{{ spawner.name }}</td>
|
|
||||||
{# url #}
|
|
||||||
<td>
|
|
||||||
<a class="server-link {% if not spawner.ready %}hidden{% endif %}" href="{{ user.server_url(spawner.name) }}">
|
|
||||||
{{ user.server_url(spawner.name) }}
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
{# activity #}
|
|
||||||
<td class='time-col'>
|
|
||||||
{% if spawner.last_activity %}
|
|
||||||
{{ spawner.last_activity.isoformat() + 'Z' }}
|
|
||||||
{% else %}
|
|
||||||
Never
|
|
||||||
{% endif %}
|
|
||||||
</td>
|
|
||||||
{# actions #}
|
|
||||||
<td>
|
|
||||||
<a role="button" class="stop-server btn btn-xs btn-danger{% if not spawner.active %} hidden{% endif %}" id="stop-{{ spawner.name }}">stop</a>
|
|
||||||
<a role="button" class="start-server btn btn-xs btn-primary {% if spawner.active %} hidden{% endif %}" id="start-{{ spawner.name }}"
|
|
||||||
href="{{ base_url }}spawn/{{ user.name }}/{{ spawner.name }}"
|
|
||||||
>
|
|
||||||
start
|
|
||||||
</a>
|
|
||||||
<button role="button" class="delete-server btn btn-xs btn-danger{% if spawner.active %} hidden{% endif %}" id="delete-{{ spawner.name }}">delete</button>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{% endfor %}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
{% endblock main %}
|
{% endblock main %}
|
||||||
|
|
||||||
{% block script %}
|
{% block script %}
|
||||||
{{ super() }}
|
{{ super() }}
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">require(["home"]);</script>
|
||||||
require(["home"]);
|
|
||||||
</script>
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@@ -2,112 +2,94 @@
|
|||||||
{% if announcement_login is string %}
|
{% if announcement_login is string %}
|
||||||
{% set announcement = announcement_login %}
|
{% set announcement = announcement_login %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% block login_widget %}{% endblock %}
|
||||||
{% block login_widget %}
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block main %}
|
{% block main %}
|
||||||
|
{% block login %}
|
||||||
{% block login %}
|
<div id="login-main" class="container">
|
||||||
<div id="login-main" class="container">
|
{% block login_container %}
|
||||||
{% block login_container %}
|
{% if custom_html %}
|
||||||
{% if custom_html %}
|
{{ custom_html | safe }}
|
||||||
{{ custom_html | safe }}
|
{% elif login_service %}
|
||||||
{% elif login_service %}
|
<div class="service-login">
|
||||||
<div class="service-login">
|
<p id='insecure-login-warning' class='hidden'>
|
||||||
<p id='insecure-login-warning' class='hidden'>
|
Warning: JupyterHub seems to be served over an unsecured HTTP connection.
|
||||||
Warning: JupyterHub seems to be served over an unsecured HTTP connection.
|
We strongly recommend enabling HTTPS for JupyterHub.
|
||||||
We strongly recommend enabling HTTPS for JupyterHub.
|
</p>
|
||||||
</p>
|
<a role="button"
|
||||||
|
class='btn btn-jupyter btn-lg'
|
||||||
<a role="button" class='btn btn-jupyter btn-lg' href='{{ authenticator_login_url | safe }}'>
|
href='{{ authenticator_login_url | safe }}'>Sign in with {{ login_service }}</a>
|
||||||
Sign in with {{login_service}}
|
</div>
|
||||||
</a>
|
{% else %}
|
||||||
</div>
|
<form action="{{ authenticator_login_url | safe }}"
|
||||||
{% else %}
|
method="post"
|
||||||
<form action="{{ authenticator_login_url | safe }}" method="post" role="form">
|
role="form">
|
||||||
<div class="auth-form-header">
|
<div class="auth-form-header">
|
||||||
<h1>Sign in</h1>
|
<h1>Sign in</h1>
|
||||||
</div>
|
</div>
|
||||||
<div class='auth-form-body m-auto'>
|
<div class='auth-form-body m-auto'>
|
||||||
|
<p id='insecure-login-warning' class='hidden'>
|
||||||
<p id='insecure-login-warning' class='hidden'>
|
Warning: JupyterHub seems to be served over an unsecured HTTP connection.
|
||||||
Warning: JupyterHub seems to be served over an unsecured HTTP connection.
|
We strongly recommend enabling HTTPS for JupyterHub.
|
||||||
We strongly recommend enabling HTTPS for JupyterHub.
|
</p>
|
||||||
</p>
|
{% if login_error %}<p class="login_error">{{ login_error }}</p>{% endif %}
|
||||||
|
<input type="hidden" name="_xsrf" value="{{ xsrf }}" />
|
||||||
{% if login_error %}
|
<label for="username_input">Username:</label>
|
||||||
<p class="login_error">
|
<input id="username_input"
|
||||||
{{login_error}}
|
type="text"
|
||||||
</p>
|
autocapitalize="off"
|
||||||
{% endif %}
|
autocorrect="off"
|
||||||
<input type="hidden" name="_xsrf" value="{{ xsrf }}"/>
|
autocomplete="username"
|
||||||
<label for="username_input">Username:</label>
|
class="form-control"
|
||||||
<input
|
name="username"
|
||||||
id="username_input"
|
val="{{ username }}"
|
||||||
type="text"
|
autofocus="autofocus" />
|
||||||
autocapitalize="off"
|
<label for='password_input'>Password:</label>
|
||||||
autocorrect="off"
|
<input type="password"
|
||||||
autocomplete="username"
|
class="form-control"
|
||||||
class="form-control"
|
autocomplete="current-password"
|
||||||
name="username"
|
name="password"
|
||||||
val="{{username}}"
|
id="password_input" />
|
||||||
autofocus="autofocus"
|
{% if authenticator.request_otp %}
|
||||||
/>
|
<label for='otp_input'>{{ authenticator.otp_prompt }}</label>
|
||||||
<label for='password_input'>Password:</label>
|
<input class="form-control"
|
||||||
<input
|
autocomplete="one-time-password"
|
||||||
type="password"
|
name="otp"
|
||||||
class="form-control"
|
id="otp_input" />
|
||||||
autocomplete="current-password"
|
{% endif %}
|
||||||
name="password"
|
<div class="feedback-container">
|
||||||
id="password_input"
|
<input id="login_submit"
|
||||||
/>
|
type="submit"
|
||||||
{% if authenticator.request_otp %}
|
class='btn btn-jupyter form-control'
|
||||||
<label for='otp_input'>{{ authenticator.otp_prompt }}</label>
|
value='Sign in'
|
||||||
<input
|
tabindex="3" />
|
||||||
class="form-control"
|
<div class="feedback-widget hidden">
|
||||||
autocomplete="one-time-password"
|
<i class="fa fa-spinner"></i>
|
||||||
name="otp"
|
</div>
|
||||||
id="otp_input"
|
</div>
|
||||||
/>
|
{% block login_terms %}
|
||||||
{% endif %}
|
{% if login_term_url %}
|
||||||
|
<div id="login_terms" class="login_terms">
|
||||||
<div class="feedback-container">
|
<input type="checkbox"
|
||||||
<input
|
id="login_terms_checkbox"
|
||||||
id="login_submit"
|
name="login_terms_checkbox"
|
||||||
type="submit"
|
required />
|
||||||
class='btn btn-jupyter form-control'
|
{% block login_terms_text %}
|
||||||
value='Sign in'
|
{# allow overriding the text #}
|
||||||
tabindex="3"
|
By logging into the platform you accept the <a href="{{ login_term_url }}">terms and conditions</a>.
|
||||||
/>
|
{% endblock login_terms_text %}
|
||||||
<div class="feedback-widget hidden">
|
</div>
|
||||||
<i class="fa fa-spinner"></i>
|
{% endif %}
|
||||||
</div>
|
{% endblock login_terms %}
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
{% endif %}
|
||||||
|
{% endblock login_container %}
|
||||||
</div>
|
</div>
|
||||||
|
{% endblock login %}
|
||||||
{% block login_terms %}
|
|
||||||
{% if login_term_url %}
|
|
||||||
<div id="login_terms" class="login_terms">
|
|
||||||
<input type="checkbox" id="login_terms_checkbox" name="login_terms_checkbox" required />
|
|
||||||
{% block login_terms_text %} {# allow overriding the text #}
|
|
||||||
By logging into the platform you accept the <a href="{{ login_term_url }}">terms and conditions</a>.
|
|
||||||
{% endblock login_terms_text %}
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
{% endblock login_terms %}
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
{% endif %}
|
|
||||||
{% endblock login_container %}
|
|
||||||
</div>
|
|
||||||
{% endblock login %}
|
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block script %}
|
{% block script %}
|
||||||
{{ super() }}
|
{{ super() }}
|
||||||
<script>
|
<script>
|
||||||
if (window.location.protocol === "http:") {
|
if (window.location.protocol === "http:") {
|
||||||
// unhide http warning
|
// unhide http warning
|
||||||
var warning = document.getElementById('insecure-login-warning');
|
var warning = document.getElementById('insecure-login-warning');
|
||||||
@@ -120,5 +102,5 @@ $('form').submit((e) => {
|
|||||||
form.find('.feedback-container>*').toggleClass('hidden');
|
form.find('.feedback-container>*').toggleClass('hidden');
|
||||||
form.find('.feedback-widget>*').toggleClass('fa-pulse');
|
form.find('.feedback-widget>*').toggleClass('fa-pulse');
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@@ -2,13 +2,8 @@
|
|||||||
{% if announcement_logout is string %}
|
{% if announcement_logout is string %}
|
||||||
{% set announcement = announcement_logout %}
|
{% set announcement = announcement_logout %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% block main %}
|
{% block main %}
|
||||||
|
<div id="logout-main" class="container">
|
||||||
<div id="logout-main" class="container">
|
<p>Successfully logged out.</p>
|
||||||
<p>
|
</div>
|
||||||
Successfully logged out.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@@ -1,60 +1,62 @@
|
|||||||
{% extends "page.html" %}
|
{% extends "page.html" %}
|
||||||
|
|
||||||
{% block main %}
|
{% block main %}
|
||||||
|
<div class="container">
|
||||||
<div class="container">
|
<div class="row">
|
||||||
<div class="row">
|
<div class="text-center">
|
||||||
<div class="text-center">
|
{% block heading %}
|
||||||
{% block heading %}
|
<h1>
|
||||||
<h1>
|
{% if failed %}
|
||||||
{% if failed %}
|
Spawn failed
|
||||||
Spawn failed
|
{% else %}
|
||||||
{% else %}
|
Server not running
|
||||||
Server not running
|
{% endif %}
|
||||||
{% endif %}
|
</h1>
|
||||||
</h1>
|
{% endblock %}
|
||||||
{% endblock %}
|
{% block message %}
|
||||||
{% block message %}
|
<p>
|
||||||
<p>
|
{% if failed %}
|
||||||
{% if failed %}
|
The latest attempt to start your server {{ server_name }} has failed.
|
||||||
The latest attempt to start your server {{ server_name }} has failed.
|
{% if failed_html_message %}
|
||||||
{% if failed_html_message %}
|
</p>
|
||||||
</p><p>{{ failed_html_message | safe }}</p><p>
|
<p>{{ failed_html_message | safe }}</p>
|
||||||
{% elif failed_message %}
|
<p>{% elif failed_message %}</p>
|
||||||
</p><p>{{ failed_message }}</p><p>
|
<p>{{ failed_message }}</p>
|
||||||
{% endif %}
|
<p>
|
||||||
Would you like to retry starting it?
|
{% endif %}
|
||||||
{% else %}
|
Would you like to retry starting it?
|
||||||
Your server {{ server_name }} is not running.
|
{% else %}
|
||||||
{% if implicit_spawn_seconds %}
|
Your server {{ server_name }} is not running.
|
||||||
It will be restarted automatically.
|
{% if implicit_spawn_seconds %}
|
||||||
If you are not redirected in a few seconds,
|
It will be restarted automatically.
|
||||||
click below to launch your server.
|
If you are not redirected in a few seconds,
|
||||||
{% else %}
|
click below to launch your server.
|
||||||
Would you like to start it?
|
{% else %}
|
||||||
{% endif %}
|
Would you like to start it?
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</p>
|
{% endif %}
|
||||||
{% endblock %}
|
</p>
|
||||||
{% block start_button %}
|
{% endblock %}
|
||||||
<a id="start" role="button" class="btn btn-lg btn-primary" href="{{ spawn_url }}">
|
{% block start_button %}
|
||||||
{% if failed %}
|
<a id="start"
|
||||||
Relaunch
|
role="button"
|
||||||
{% else %}
|
class="btn btn-lg btn-primary"
|
||||||
Launch
|
href="{{ spawn_url }}">
|
||||||
{% endif %}
|
{% if failed %}
|
||||||
Server {{ server_name }}
|
Relaunch
|
||||||
</a>
|
{% else %}
|
||||||
{% endblock %}
|
Launch
|
||||||
|
{% endif %}
|
||||||
|
Server {{ server_name }}
|
||||||
|
</a>
|
||||||
|
{% endblock %}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% block script %}
|
{% block script %}
|
||||||
{{ super () }}
|
{{ super () }}
|
||||||
{% if implicit_spawn_seconds %}
|
{% if implicit_spawn_seconds %}
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
var spawn_url = "{{ spawn_url }}";
|
var spawn_url = "{{ spawn_url }}";
|
||||||
var implicit_spawn_seconds = {{ implicit_spawn_seconds }};
|
var implicit_spawn_seconds = {{ implicit_spawn_seconds }};
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
@@ -63,9 +65,7 @@
|
|||||||
},
|
},
|
||||||
1000 * implicit_spawn_seconds
|
1000 * implicit_spawn_seconds
|
||||||
);
|
);
|
||||||
</script>
|
</script>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">require(["not_running"]);</script>
|
||||||
require(["not_running"]);
|
|
||||||
</script>
|
|
||||||
{% endblock script %}
|
{% endblock script %}
|
||||||
|
@@ -1,60 +1,47 @@
|
|||||||
{% extends "page.html" %}
|
{% extends "page.html" %}
|
||||||
|
{% block login_widget %}{% endblock %}
|
||||||
{% block login_widget %}
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block main %}
|
{% block main %}
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row justify-content-center">
|
<div class="row justify-content-center">
|
||||||
<div class="col-md-8">
|
<div class="col-md-8">
|
||||||
<h1 class="text-center">Authorize access</h1>
|
<h1 class="text-center">Authorize access</h1>
|
||||||
<p class="lead">
|
<p class="lead">An application is requesting authorization to access data associated with your JupyterHub account</p>
|
||||||
An application is requesting authorization to access data associated with your JupyterHub account
|
<p>
|
||||||
</p>
|
{{ oauth_client.description }} (oauth URL: {{ oauth_client.redirect_uri }})
|
||||||
<p>
|
would like permission to identify you.
|
||||||
{{ oauth_client.description }} (oauth URL: {{ oauth_client.redirect_uri }})
|
{% if scope_descriptions | length == 1 and not scope_descriptions[0].scope %}
|
||||||
would like permission to identify you.
|
It will not be able to take actions on
|
||||||
{% if scope_descriptions | length == 1 and not scope_descriptions[0].scope %}
|
your behalf.
|
||||||
It will not be able to take actions on
|
{% endif %}
|
||||||
your behalf.
|
</p>
|
||||||
{% endif %}
|
<form method="POST" action="">
|
||||||
</p>
|
<div class="card">
|
||||||
|
<div class="card-header">
|
||||||
<form method="POST" action="">
|
<p class="h5">This will grant the application permission to:</p>
|
||||||
<div class="card">
|
|
||||||
<div class="card-header">
|
|
||||||
<p class="h5">This will grant the application permission to:
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div class="card-body">
|
|
||||||
<input type="hidden" name="_xsrf" value="{{ xsrf }}"/>
|
|
||||||
{# these are the 'real' inputs to the form -#}
|
|
||||||
{% for scope in allowed_scopes %}
|
|
||||||
<input type="hidden" name="scopes" value="{{ scope }}"/>
|
|
||||||
{% endfor %}
|
|
||||||
|
|
||||||
{% for scope_info in scope_descriptions %}
|
|
||||||
<div class="checkbox input-group">
|
|
||||||
<label>
|
|
||||||
<input type="checkbox" name="raw-scopes" checked="true" title="This authorization is required"
|
|
||||||
disabled="disabled"
|
|
||||||
{# disabled because it's required #} />
|
|
||||||
<span>
|
|
||||||
{{ scope_info['description'] }}
|
|
||||||
{% if scope_info['filter'] %}
|
|
||||||
Applies to {{ scope_info['filter'] }}.
|
|
||||||
{% endif %}
|
|
||||||
</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
<div class="card-body">
|
||||||
</div>
|
<input type="hidden" name="_xsrf" value="{{ xsrf }}" />
|
||||||
<div class="card-footer">
|
{# these are the 'real' inputs to the form -#}
|
||||||
<button type="submit" class="form-control btn btn-jupyter mt-2">Authorize</button>
|
{% for scope in allowed_scopes %}<input type="hidden" name="scopes" value="{{ scope }}" />{% endfor %}
|
||||||
|
{% for scope_info in scope_descriptions %}
|
||||||
|
<div class="checkbox input-group">
|
||||||
|
<label>
|
||||||
|
<input type="checkbox" name="raw-scopes" checked="true" title="This authorization is required"
|
||||||
|
disabled="disabled"
|
||||||
|
{# disabled because it's required #} />
|
||||||
|
<span>
|
||||||
|
{{ scope_info['description'] }}
|
||||||
|
{% if scope_info['filter'] %}Applies to {{ scope_info['filter'] }}.{% endif %}
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
<div class="card-footer">
|
||||||
|
<button type="submit" class="form-control btn btn-jupyter mt-2">Authorize</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
{% endblock %}
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{% endblock %}
|
|
||||||
|
@@ -1,51 +1,55 @@
|
|||||||
{% macro modal(title, btn_label=None, btn_class="btn-primary") %}
|
{% macro modal(title, btn_label=None, btn_class="btn-primary") %}
|
||||||
{% set key = title.replace(' ', '-').lower() %}
|
{% set key = title.replace(' ', '-').lower() %}
|
||||||
{% set btn_label = btn_label or title %}
|
{% set btn_label = btn_label or title %}
|
||||||
<div class="modal fade" id="{{key}}-dialog" tabindex="-1" role="dialog" aria-labelledby="{{key}}-label" aria-hidden="true">
|
<div class="modal fade"
|
||||||
<div class="modal-dialog">
|
id="{{ key }}-dialog"
|
||||||
<div class="modal-content">
|
tabindex="-1"
|
||||||
<div class="modal-header">
|
role="dialog"
|
||||||
<h2 class="modal-title" id="{{key}}-label">{{title}}</h1>
|
aria-labelledby="{{ key }}-label"
|
||||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
aria-hidden="true">
|
||||||
</div>
|
<div class="modal-dialog">
|
||||||
<div class="modal-body">
|
<div class="modal-content">
|
||||||
{{ caller() }}
|
<div class="modal-header">
|
||||||
</div>
|
<h2 class="modal-title" id="{{ key }}-label">
|
||||||
<div class="modal-footer">
|
{{ title }}
|
||||||
<button type="button" class="btn {{btn_class}}" data-bs-dismiss="modal" data-dismiss="modal">{{btn_label}}</button>
|
</h1>
|
||||||
|
<button type="button"
|
||||||
|
class="btn-close"
|
||||||
|
data-bs-dismiss="modal"
|
||||||
|
aria-label="Close"></button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">{{ caller() }}</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button"
|
||||||
|
class="btn {{ btn_class }}"
|
||||||
|
data-bs-dismiss="modal"
|
||||||
|
data-dismiss="modal">{{ btn_label }}</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
{% endmacro %}
|
{% endmacro %}
|
||||||
|
|
||||||
|
|
||||||
<!DOCTYPE HTML>
|
<!DOCTYPE HTML>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
|
<head>
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
|
<title>
|
||||||
<title>{% block title %}JupyterHub{% endblock %}</title>
|
{% block title %}JupyterHub{% endblock %}
|
||||||
|
</title>
|
||||||
<meta http-equiv="X-UA-Compatible" content="chrome=1">
|
<meta http-equiv="X-UA-Compatible" content="chrome=1">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
|
||||||
{% block stylesheet %}
|
{% block stylesheet %}
|
||||||
<link rel="stylesheet" href="{{ static_url("css/style.min.css") }}" type="text/css"/>
|
<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 %}
|
{% endblock %}
|
||||||
|
{% block favicon %}<link rel="icon" href="{{ static_url("favicon.ico") }}" type="image/x-icon">{% endblock %}
|
||||||
{% block scripts %}
|
{% block scripts %}
|
||||||
<script src="{{static_url("components/bootstrap/dist/js/bootstrap.bundle.min.js") }}" type="text/javascript" charset="utf-8"></script>
|
<script src="{{static_url("components/bootstrap/dist/js/bootstrap.bundle.min.js") }}" type="text/javascript" charset="utf-8"></script>
|
||||||
<script src="{{static_url("components/requirejs/require.js") }}" type="text/javascript" charset="utf-8"></script>
|
<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/jquery/dist/jquery.min.js") }}" type="text/javascript" charset="utf-8"></script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
<script>
|
<script>
|
||||||
require.config({
|
require.config({
|
||||||
{% if version_hash %}
|
{% if version_hash %}urlArgs: "v={{version_hash}}",{% endif %}
|
||||||
urlArgs: "v={{version_hash}}",
|
|
||||||
{% endif %}
|
|
||||||
baseUrl: '{{static_url("js", include_version=False)}}',
|
baseUrl: '{{static_url("js", include_version=False)}}',
|
||||||
paths: {
|
paths: {
|
||||||
components: '../components',
|
components: '../components',
|
||||||
@@ -54,7 +58,6 @@
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
window.jhdata = {
|
window.jhdata = {
|
||||||
base_url: "{{base_url}}",
|
base_url: "{{base_url}}",
|
||||||
@@ -79,109 +82,96 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
xsrf_token: "{{ xsrf_token }}",
|
xsrf_token: "{{ xsrf_token }}",
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
{% block meta %}
|
||||||
{% block meta %}
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
|
|
||||||
<noscript>
|
|
||||||
<div id='noscript'>
|
|
||||||
JupyterHub requires JavaScript.<br>
|
|
||||||
Please enable it to proceed.
|
|
||||||
</div>
|
|
||||||
</noscript>
|
|
||||||
|
|
||||||
{% block nav_bar %}
|
|
||||||
<nav class="navbar navbar-expand-sm bg-body-tertiary mb-4">
|
|
||||||
<div class="container-fluid">
|
|
||||||
{% block logo %}
|
|
||||||
<span id="jupyterhub-logo" class="navbar-brand">
|
|
||||||
<a href="{{logo_url or base_url}}"><img src='{{base_url}}logo' alt='JupyterHub logo' class='jpy-logo' title='Home'/></a>
|
|
||||||
</span>
|
|
||||||
{% endblock %}
|
|
||||||
{% if user %}
|
|
||||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#thenavbar" aria-controls="thenavbar" aria-expanded="false" aria-label="Toggle navigation">
|
|
||||||
<span class="navbar-toggler-icon"></span>
|
|
||||||
</button>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<div class="collapse navbar-collapse" id="thenavbar">
|
|
||||||
{% if user %}
|
|
||||||
<ul class="navbar-nav me-auto mb-0">
|
|
||||||
{% block nav_bar_left_items %}
|
|
||||||
<li class="nav-item"><a class="nav-link" href="{{base_url}}home">Home</a></li>
|
|
||||||
<li class="nav-item"><a class="nav-link" href="{{base_url}}token">Token</a></li>
|
|
||||||
{% if 'admin-ui' in parsed_scopes %}
|
|
||||||
<li class="nav-item"><a class="nav-link" href="{{base_url}}admin">Admin</a></li>
|
|
||||||
{% endif %}
|
|
||||||
{% if services %}
|
|
||||||
<li class="nav-item dropdown">
|
|
||||||
<a href="#" class="nav-link dropdown-toggle" data-bs-toggle="dropdown" role="button" aria-expanded="false">Services</a>
|
|
||||||
<ul class="dropdown-menu">
|
|
||||||
{% for service in services %}
|
|
||||||
{% block service scoped %}
|
|
||||||
<li><a class="dropdown-item" href="{{service.href}}">{{service.name}}</a></li>
|
|
||||||
{% endblock %}
|
|
||||||
{% endfor %}
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
{% endif %}
|
|
||||||
{% endblock %}
|
|
||||||
</ul>
|
|
||||||
{% endif %}
|
|
||||||
<ul class="nav navbar-nav me-2">
|
|
||||||
{% block nav_bar_right_items %}
|
|
||||||
<li class="nav-item">
|
|
||||||
{% block login_widget %}
|
|
||||||
<span id="login_widget">
|
|
||||||
{% if user %}
|
|
||||||
<span class="navbar-text">{{user.name}}</span>
|
|
||||||
<a id="logout" role="button" class="btn btn-sm btn-outline-dark" href="{{logout_url}}"> <i aria-hidden="true" class="fa fa-sign-out"></i> Logout</a>
|
|
||||||
{% else %}
|
|
||||||
<a id="login" role="button" class="btn btn-sm btn-outline-dark" href="{{login_url}}">Login</a>
|
|
||||||
{% endif %}
|
|
||||||
</span>
|
|
||||||
{% endblock %}
|
|
||||||
</li>
|
|
||||||
{% endblock %}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{% block header %}
|
|
||||||
{% endblock %}
|
|
||||||
</div>
|
|
||||||
</nav>
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
{% block announcement %}
|
<noscript>
|
||||||
{% if announcement %}
|
<div id='noscript'>
|
||||||
<div class="container text-center announcement alert alert-warning">
|
JupyterHub requires JavaScript.
|
||||||
{{ announcement | safe }}
|
<br>
|
||||||
|
Please enable it to proceed.
|
||||||
</div>
|
</div>
|
||||||
|
</noscript>
|
||||||
|
{% block nav_bar %}
|
||||||
|
<nav class="navbar navbar-expand-sm bg-body-tertiary mb-4">
|
||||||
|
<div class="container-fluid">
|
||||||
|
{% block logo %}
|
||||||
|
<span id="jupyterhub-logo" class="navbar-brand">
|
||||||
|
<a href="{{ logo_url or base_url }}">
|
||||||
|
<img src='{{ base_url }}logo' alt='JupyterHub logo' class='jpy-logo' title='Home' />
|
||||||
|
</a>
|
||||||
|
</span>
|
||||||
|
{% endblock %}
|
||||||
|
{% if user %}
|
||||||
|
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#thenavbar" aria-controls="thenavbar" aria-expanded="false" aria-label="Toggle navigation">
|
||||||
|
<span class="navbar-toggler-icon"></span>
|
||||||
|
</button>
|
||||||
|
{% endif %}
|
||||||
|
<div class="collapse navbar-collapse" id="thenavbar">
|
||||||
|
{% if user %}
|
||||||
|
<ul class="navbar-nav me-auto mb-0">
|
||||||
|
{% block nav_bar_left_items %}
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="{{ base_url }}home">Home</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="{{ base_url }}token">Token</a>
|
||||||
|
</li>
|
||||||
|
{% if 'admin-ui' in parsed_scopes %}
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="{{ base_url }}admin">Admin</a>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
{% if services %}
|
||||||
|
<li class="nav-item dropdown">
|
||||||
|
<a href="#" class="nav-link dropdown-toggle" data-bs-toggle="dropdown" role="button" aria-expanded="false">Services</a>
|
||||||
|
<ul class="dropdown-menu">
|
||||||
|
{% for service in services %}
|
||||||
|
{% block service scoped %}
|
||||||
|
<li>
|
||||||
|
<a class="dropdown-item" href="{{ service.href }}">{{ service.name }}</a>
|
||||||
|
</li>
|
||||||
|
{% endblock %}
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
</ul>
|
||||||
|
{% endif %}
|
||||||
{% block main %}
|
<ul class="nav navbar-nav me-2">
|
||||||
|
{% block nav_bar_right_items %}
|
||||||
|
<li class="nav-item">
|
||||||
|
{% block login_widget %}
|
||||||
|
<span id="login_widget">
|
||||||
|
{% if user %}
|
||||||
|
<span class="navbar-text">{{ user.name }}</span>
|
||||||
|
<a id="logout" role="button" class="btn btn-sm btn-outline-dark" href="{{ logout_url }}"> <i aria-hidden="true" class="fa fa-sign-out"></i> Logout</a>
|
||||||
|
{% else %}
|
||||||
|
<a id="login" role="button" class="btn btn-sm btn-outline-dark" href="{{ login_url }}">Login</a>
|
||||||
|
{% endif %}
|
||||||
|
</span>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
</li>
|
||||||
{% block footer %}
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
{% block header %}{% endblock %}
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
{% endblock %}
|
||||||
|
{% block announcement %}
|
||||||
|
{% if announcement %}
|
||||||
|
<div class="container text-center announcement alert alert-warning">{{ announcement | safe }}</div>
|
||||||
|
{% endif %}
|
||||||
|
{% endblock %}
|
||||||
|
{% block main %}{% endblock %}
|
||||||
|
{% block footer %}{% endblock %}
|
||||||
{% call modal('Error', btn_label='OK') %}
|
{% call modal('Error', btn_label='OK') %}
|
||||||
<div class="ajax-error alert-danger">
|
<div class="ajax-error alert-danger">The error</div>
|
||||||
The error
|
|
||||||
</div>
|
|
||||||
{% endcall %}
|
{% endcall %}
|
||||||
|
{% block script %}{% endblock %}
|
||||||
{% block script %}
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
@@ -2,43 +2,39 @@
|
|||||||
{% if announcement_spawn is string %}
|
{% if announcement_spawn is string %}
|
||||||
{% set announcement = announcement_spawn %}
|
{% set announcement = announcement_spawn %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% block main %}
|
{% block main %}
|
||||||
|
<div class="container">
|
||||||
<div class="container">
|
{% block heading %}
|
||||||
{% block heading %}
|
<div class="row text-center">
|
||||||
<div class="row text-center">
|
<h1>Server Options</h1>
|
||||||
<h1>Server Options</h1>
|
|
||||||
</div>
|
|
||||||
{% endblock %}
|
|
||||||
<div class="row justify-content-center">
|
|
||||||
<div class="col-md-8">
|
|
||||||
{% if for_user and user.name != for_user.name -%}
|
|
||||||
<p>Spawning server for {{ for_user.name }}</p>
|
|
||||||
{% endif -%}
|
|
||||||
{% if error_message -%}
|
|
||||||
<p class="spawn-error-msg alert alert-danger">
|
|
||||||
Error: {{error_message}}
|
|
||||||
</p>
|
|
||||||
{% endif %}
|
|
||||||
<form enctype="multipart/form-data" id="spawn_form" action="{{ url | safe }}" method="post" role="form">
|
|
||||||
{{spawner_options_form | safe}}
|
|
||||||
<br>
|
|
||||||
<div class="feedback-container">
|
|
||||||
<button type="submit" class="btn btn-jupyter form-control">Start</button>
|
|
||||||
<div class="feedback-widget hidden">
|
|
||||||
<i class="fa fa-spinner"></i>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</form>
|
{% endblock %}
|
||||||
</div>
|
<div class="row justify-content-center">
|
||||||
</div>
|
<div class="col-md-8">
|
||||||
|
{% if for_user and user.name != for_user.name -%}
|
||||||
{% endblock %}
|
<p>Spawning server for {{ for_user.name }}</p>
|
||||||
|
{% endif -%}
|
||||||
{% block script %}
|
{% if error_message -%}<p class="spawn-error-msg alert alert-danger">Error: {{ error_message }}</p>{% endif %}
|
||||||
{{ super() }}
|
<form enctype="multipart/form-data"
|
||||||
<script>
|
id="spawn_form"
|
||||||
|
action="{{ url | safe }}"
|
||||||
|
method="post"
|
||||||
|
role="form">
|
||||||
|
{{ spawner_options_form | safe }}
|
||||||
|
<br>
|
||||||
|
<div class="feedback-container">
|
||||||
|
<button type="submit" class="btn btn-jupyter form-control">Start</button>
|
||||||
|
<div class="feedback-widget hidden">
|
||||||
|
<i class="fa fa-spinner"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
|
{% block script %}
|
||||||
|
{{ super() }}
|
||||||
|
<script>
|
||||||
// setup onSubmit feedback
|
// setup onSubmit feedback
|
||||||
$('form').submit((e) => {
|
$('form').submit((e) => {
|
||||||
var form = $(e.target);
|
var form = $(e.target);
|
||||||
@@ -46,5 +42,5 @@ $('form').submit((e) => {
|
|||||||
form.find('.feedback-container>*').toggleClass('hidden');
|
form.find('.feedback-container>*').toggleClass('hidden');
|
||||||
form.find('.feedback-widget>*').toggleClass('fa-pulse');
|
form.find('.feedback-widget>*').toggleClass('fa-pulse');
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@@ -1,37 +1,39 @@
|
|||||||
{% extends "page.html" %}
|
{% extends "page.html" %}
|
||||||
|
|
||||||
{% block main %}
|
{% block main %}
|
||||||
|
<div class="container">
|
||||||
<div class="container">
|
<div class="row">
|
||||||
<div class="row">
|
<div class="text-center">
|
||||||
<div class="text-center">
|
{% block message %}
|
||||||
{% block message %}
|
<p>Your server is starting up.</p>
|
||||||
<p>Your server is starting up.</p>
|
<p>You will be redirected automatically when it's ready for you.</p>
|
||||||
<p>You will be redirected automatically when it's ready for you.</p>
|
{% endblock %}
|
||||||
{% endblock %}
|
<div class="progress">
|
||||||
<div class="progress">
|
<div id="progress-bar"
|
||||||
<div id="progress-bar" class="progress-bar" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 0%;">
|
class="progress-bar"
|
||||||
<span class="sr-only"><span id="sr-progress">0%</span> Complete</span>
|
role="progressbar"
|
||||||
|
aria-valuenow="0"
|
||||||
|
aria-valuemin="0"
|
||||||
|
aria-valuemax="100"
|
||||||
|
style="width: 0%">
|
||||||
|
<span class="sr-only"><span id="sr-progress">0%</span> Complete</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<p id="progress-message"></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row justify-content-center">
|
||||||
|
<div class="col-md-8">
|
||||||
|
<details id="progress-details">
|
||||||
|
<summary>Event log</summary>
|
||||||
|
<div id="progress-log"></div>
|
||||||
|
</details>
|
||||||
</div>
|
</div>
|
||||||
<p id="progress-message"></p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row justify-content-center">
|
|
||||||
<div class="col-md-8">
|
|
||||||
<details id="progress-details">
|
|
||||||
<summary>Event log</summary>
|
|
||||||
<div id="progress-log"></div>
|
|
||||||
</details>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block script %}
|
{% block script %}
|
||||||
{{ super() }}
|
{{ super() }}
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
require(["jquery"], function ($) {
|
require(["jquery"], function ($) {
|
||||||
$("#refresh").click(function () {
|
$("#refresh").click(function () {
|
||||||
window.location.reload();
|
window.location.reload();
|
||||||
@@ -90,5 +92,5 @@ require(["jquery"], function ($) {
|
|||||||
// signal that page has finished loading (mostly for tests)
|
// signal that page has finished loading (mostly for tests)
|
||||||
window._jupyterhub_page_loaded = true;
|
window._jupyterhub_page_loaded = true;
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@@ -1,25 +1,23 @@
|
|||||||
{% extends "page.html" %}
|
{% extends "page.html" %}
|
||||||
|
|
||||||
{% block main %}
|
{% block main %}
|
||||||
|
<div class="container">
|
||||||
<div class="container">
|
<div class="row">
|
||||||
<div class="row">
|
<div class="text-center">
|
||||||
<div class="text-center">
|
{% block message %}
|
||||||
{% block message %}
|
<p>Your server is stopping.</p>
|
||||||
<p>Your server is stopping.</p>
|
<p>You will be able to start it again once it has finished stopping.</p>
|
||||||
<p>You will be able to start it again once it has finished stopping.</p>
|
{% endblock message %}
|
||||||
{% endblock message %}
|
<p>
|
||||||
<p><i class="fa fa-spinner fa-pulse fa-fw fa-3x" aria-hidden="true"></i></p>
|
<i class="fa fa-spinner fa-pulse fa-fw fa-3x" aria-hidden="true"></i>
|
||||||
<a role="button" id="refresh" class="btn btn-lg btn-primary" href="#">refresh</a>
|
</p>
|
||||||
|
<a role="button" id="refresh" class="btn btn-lg btn-primary" href="#">refresh</a>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block script %}
|
{% block script %}
|
||||||
{{ super() }}
|
{{ super() }}
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
require(["jquery"], function ($) {
|
require(["jquery"], function ($) {
|
||||||
$("#refresh").click(function () {
|
$("#refresh").click(function () {
|
||||||
window.location.reload();
|
window.location.reload();
|
||||||
@@ -28,5 +26,5 @@ require(["jquery"], function ($) {
|
|||||||
window.location.reload();
|
window.location.reload();
|
||||||
}, 5000);
|
}, 5000);
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@@ -1,58 +1,47 @@
|
|||||||
{% extends "page.html" %}
|
{% extends "page.html" %}
|
||||||
|
|
||||||
{% block main %}
|
{% block main %}
|
||||||
|
<div class="container">
|
||||||
<div class="container">
|
<h1 class="sr-only">Manage JupyterHub Tokens</h1>
|
||||||
<h1 class="sr-only">Manage JupyterHub Tokens</h1>
|
<div class="row justify-content-center">
|
||||||
<div class="row justify-content-center">
|
<form id="request-token-form" class="col-lg-6">
|
||||||
<form id="request-token-form" class="col-lg-6">
|
<div class="form-group">
|
||||||
<div class="form-group">
|
<label for="token-note" class="form-label">Note</label>
|
||||||
<label for="token-note" class="form-label">Note</label>
|
<input id="token-note"
|
||||||
<input
|
class="form-control"
|
||||||
id="token-note"
|
placeholder="note to identify your new token">
|
||||||
class="form-control"
|
<small id="note-note" class="form-text">This note will help you keep track of what your tokens are for.</small>
|
||||||
placeholder="note to identify your new token">
|
<br />
|
||||||
<small id="note-note" class="form-text">
|
<label for="token-expiration-seconds" class="form-label">Token expires in</label>
|
||||||
This note will help you keep track of what your tokens are for.
|
{% block expiration_options %}
|
||||||
</small>
|
<select id="token-expiration-seconds" class="form-select">
|
||||||
<br/>
|
<!-- unit used for each value is `seconds` -->
|
||||||
<label for="token-expiration-seconds" class="form-label">Token expires in</label>
|
<option value="3600">1 Hour</option>
|
||||||
{% block expiration_options %}
|
<option value="86400">1 Day</option>
|
||||||
<select id="token-expiration-seconds"
|
<option value="604800">1 Week</option>
|
||||||
class="form-select">
|
<option value="" selected="selected">Never</option>
|
||||||
<!-- unit used for each value is `seconds` -->
|
</select>
|
||||||
<option value="3600">1 Hour</option>
|
{% endblock expiration_options %}
|
||||||
<option value="86400">1 Day</option>
|
<small id="note-expires-at" class="form-text">You can configure when your token will expire.</small>
|
||||||
<option value="604800">1 Week</option>
|
<br />
|
||||||
<option value="" selected="selected">Never</option>
|
<label for="token-scopes" class="form-label">Permissions</label>
|
||||||
</select>
|
<input id="token-scopes"
|
||||||
{% endblock expiration_options %}
|
class="form-control"
|
||||||
<small id="note-expires-at" class="form-text">
|
placeholder="list of scopes for the token to have, separated by space">
|
||||||
You can configure when your token will expire.
|
<small id="note-token-scopes" class="form-text">
|
||||||
</small>
|
You can limit the permissions of the token so it can only do what you want it to.
|
||||||
<br/>
|
If none are specified, the token will have permission to do everything you can do.
|
||||||
<label for="token-scopes" class="form-label">Permissions</label>
|
See the <a href="https://jupyterhub.readthedocs.io/en/stable/rbac/scopes.html#available-scopes">JupyterHub documentation for a list of available scopes</a>.
|
||||||
<input id="token-scopes" class="form-control" placeholder="list of scopes for the token to have, separated by space">
|
</small>
|
||||||
<small id="note-token-scopes" class="form-text">
|
</div>
|
||||||
You can limit the permissions of the token so it can only do what you want it to.
|
<div class="text-center m-4">
|
||||||
If none are specified, the token will have permission to do everything you can do.
|
<button type="submit" class="btn btn-lg btn-jupyter">Request new API token</button>
|
||||||
See the <a href="https://jupyterhub.readthedocs.io/en/stable/rbac/scopes.html#available-scopes">JupyterHub documentation for a list of available scopes</a>.
|
</div>
|
||||||
</small>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<div class="text-center m-4">
|
<div class="row justify-content-center">
|
||||||
<button type="submit" class="btn btn-lg btn-jupyter">
|
|
||||||
Request new API token
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row justify-content-center">
|
|
||||||
<div id="token-area" class="col-lg-6" style="display: none;">
|
<div id="token-area" class="col-lg-6" style="display: none;">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-header">
|
<div class="card-header">Your new API Token</div>
|
||||||
Your new API Token
|
|
||||||
</div>
|
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<p class="card-title text-center">
|
<p class="card-title text-center">
|
||||||
<span id="token-result"></span>
|
<span id="token-result"></span>
|
||||||
@@ -64,138 +53,129 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{% if api_tokens %}
|
||||||
{% if api_tokens %}
|
<div class="row" id="api-tokens-section">
|
||||||
<div class="row" id="api-tokens-section">
|
<div class="col">
|
||||||
<div class="col">
|
<h2>API Tokens</h2>
|
||||||
<h2>API Tokens</h2>
|
<p>
|
||||||
<p>
|
These are tokens with access to the JupyterHub API.
|
||||||
These are tokens with access to the JupyterHub API.
|
Permissions for each token may be viewed via the JupyterHub tokens API.
|
||||||
Permissions for each token may be viewed via the JupyterHub tokens API.
|
Revoking the API token for a running server will require restarting that server.
|
||||||
Revoking the API token for a running server will require restarting that server.
|
</p>
|
||||||
</p>
|
<table class="table table-striped" id="api-tokens-table">
|
||||||
<table class="table table-striped" id="api-tokens-table">
|
<thead>
|
||||||
<thead>
|
<tr>
|
||||||
<tr>
|
<th>Note</th>
|
||||||
<th>Note</th>
|
<th>Permissions</th>
|
||||||
<th>Permissions</th>
|
<th>Last used</th>
|
||||||
<th>Last used</th>
|
<th>Created</th>
|
||||||
<th>Created</th>
|
<th>Expires</th>
|
||||||
<th>Expires</th>
|
</tr>
|
||||||
</tr>
|
</thead>
|
||||||
</thead>
|
<tbody>
|
||||||
<tbody>
|
{% for token in api_tokens %}
|
||||||
{% for token in api_tokens %}
|
<tr class="token-row container" data-token-id="{{ token.api_id }}">
|
||||||
<tr class="token-row container" data-token-id="{{token.api_id}}">
|
{% block token_row scoped %}
|
||||||
{% block token_row scoped %}
|
<td class="note-col col">{{ token.note }}</td>
|
||||||
<td class="note-col col">{{token.note}}</td>
|
<td class="scope-col col">
|
||||||
<td class="scope-col col">
|
<details>
|
||||||
<details>
|
<summary>scopes</summary>
|
||||||
<summary>scopes</summary>
|
{% for scope in token.scopes %}<pre class="token-scope">{{ scope }}</pre>{% endfor %}
|
||||||
{% for scope in token.scopes %}
|
</details>
|
||||||
<pre class="token-scope">{{ scope }}</pre>
|
</td>
|
||||||
{% endfor %}
|
<td class="time-col col">
|
||||||
</details>
|
{%- if token.last_activity -%}
|
||||||
</td>
|
{{ token.last_activity.isoformat() + 'Z' }}
|
||||||
<td class="time-col col">
|
{%- else -%}
|
||||||
{%- if token.last_activity -%}
|
Never
|
||||||
{{ token.last_activity.isoformat() + 'Z' }}
|
{%- endif -%}
|
||||||
{%- else -%}
|
</td>
|
||||||
Never
|
<td class="time-col col">
|
||||||
{%- endif -%}
|
{%- if token.created -%}
|
||||||
</td>
|
{{ token.created.isoformat() + 'Z' }}
|
||||||
<td class="time-col col">
|
{%- else -%}
|
||||||
{%- if token.created -%}
|
N/A
|
||||||
{{ token.created.isoformat() + 'Z' }}
|
{%- endif -%}
|
||||||
{%- else -%}
|
</td>
|
||||||
N/A
|
<td class="time-col col">
|
||||||
{%- endif -%}
|
{%- if token.expires_at -%}
|
||||||
</td>
|
{{ token.expires_at.isoformat() + 'Z' }}
|
||||||
<td class="time-col col">
|
{%- else -%}
|
||||||
{%- if token.expires_at -%}
|
Never
|
||||||
{{ token.expires_at.isoformat() + 'Z' }}
|
{%- endif -%}
|
||||||
{%- else -%}
|
</td>
|
||||||
Never
|
<td class="col text-center">
|
||||||
{%- endif -%}
|
<button class="revoke-token-btn btn btn-xs btn-danger">revoke</button>
|
||||||
</td>
|
</td>
|
||||||
<td class="col text-center">
|
{% endblock token_row %}
|
||||||
<button class="revoke-token-btn btn btn-xs btn-danger">revoke</button>
|
</tr>
|
||||||
</td>
|
{% endfor %}
|
||||||
{% endblock token_row %}
|
</tbody>
|
||||||
</tr>
|
</table>
|
||||||
{% endfor %}
|
</div>
|
||||||
</tbody>
|
</div>
|
||||||
</table>
|
{% endif %}
|
||||||
</div>
|
{% if oauth_clients %}
|
||||||
</div>
|
<div class="row" id="oauth-clients-section">
|
||||||
{% endif %}
|
<h2>Authorized Applications</h2>
|
||||||
|
<p>
|
||||||
{% if oauth_clients %}
|
These are applications that use OAuth with JupyterHub
|
||||||
<div class="row" id="oauth-clients-section">
|
to identify users (mostly notebook servers).
|
||||||
<h2>Authorized Applications</h2>
|
OAuth tokens can generally only be used to identify you,
|
||||||
<p>
|
not take actions on your behalf.
|
||||||
These are applications that use OAuth with JupyterHub
|
</p>
|
||||||
to identify users (mostly notebook servers).
|
<table class="table table-striped" id="oauth-tokens-table">
|
||||||
|
<thead>
|
||||||
OAuth tokens can generally only be used to identify you,
|
<tr>
|
||||||
not take actions on your behalf.
|
<th>Application</th>
|
||||||
</p>
|
<th>Permissions</th>
|
||||||
<table class="table table-striped" id="oauth-tokens-table">
|
<th>Last used</th>
|
||||||
<thead>
|
<th>First authorized</th>
|
||||||
<tr>
|
</tr>
|
||||||
<th>Application</th>
|
</thead>
|
||||||
<th>Permissions</th>
|
<tbody>
|
||||||
<th>Last used</th>
|
{% for client in oauth_clients %}
|
||||||
<th>First authorized</th>
|
<tr class="token-row" data-token-id="{{ client['token_id'] }}">
|
||||||
</tr>
|
{% block client_row scoped %}
|
||||||
</thead>
|
<td class="note-col col-sm-4">{{ client['description'] }}</td>
|
||||||
<tbody>
|
<td class="scope-col col-sm-1">
|
||||||
{% for client in oauth_clients %}
|
<details>
|
||||||
<tr class="token-row"
|
<summary>scopes</summary>
|
||||||
data-token-id="{{ client['token_id'] }}">
|
{# create set of scopes on all tokens -#}
|
||||||
{% block client_row scoped %}
|
{# sum concatenates all token.scopes into a single list -#}
|
||||||
<td class="note-col col-sm-4">{{ client['description'] }}</td>
|
{# then filter to unique set and sort -#}
|
||||||
<td class="scope-col col-sm-1">
|
{% for scope in client.tokens | sum(attribute="scopes", start=[]) | unique | sort %}
|
||||||
<details>
|
<pre class="token-scope">{{ scope }}</pre>
|
||||||
<summary>scopes</summary>
|
{% endfor %}
|
||||||
{# create set of scopes on all tokens -#}
|
</details>
|
||||||
{# sum concatenates all token.scopes into a single list -#}
|
</td>
|
||||||
{# then filter to unique set and sort -#}
|
<td class="time-col col-sm-3">
|
||||||
{% for scope in client.tokens | sum(attribute="scopes", start=[]) | unique | sort %}
|
{%- if client['last_activity'] -%}
|
||||||
<pre class="token-scope">{{ scope }}</pre>
|
{{ client['last_activity'].isoformat() + 'Z' }}
|
||||||
{% endfor %}
|
{%- else -%}
|
||||||
</details>
|
Never
|
||||||
</td>
|
{%- endif -%}
|
||||||
<td class="time-col col-sm-3">
|
</td>
|
||||||
{%- if client['last_activity'] -%}
|
<td class="time-col col-sm-3">
|
||||||
{{ client['last_activity'].isoformat() + 'Z' }}
|
{%- if client['created'] -%}
|
||||||
{%- else -%}
|
{{ client['created'].isoformat() + 'Z' }}
|
||||||
Never
|
{%- else -%}
|
||||||
{%- endif -%}
|
N/A
|
||||||
</td>
|
{%- endif -%}
|
||||||
<td class="time-col col-sm-3">
|
</td>
|
||||||
{%- if client['created'] -%}
|
<td class="col-sm-1 text-center">
|
||||||
{{ client['created'].isoformat() + 'Z' }}
|
<button class="revoke-token-btn btn btn-xs btn-danger">revoke</button>
|
||||||
{%- else -%}
|
{% endblock client_row %}
|
||||||
N/A
|
</tr>
|
||||||
{%- endif -%}
|
{% endfor %}
|
||||||
</td>
|
</tbody>
|
||||||
<td class="col-sm-1 text-center">
|
</table>
|
||||||
<button class="revoke-token-btn btn btn-xs btn-danger">revoke</button>
|
</div>
|
||||||
{% endblock client_row %}
|
{% endif %}
|
||||||
</tr>
|
</div>
|
||||||
{% endfor %}
|
{% endblock main %}
|
||||||
</tbody>
|
{% block script %}
|
||||||
</table>
|
{{ super() }}
|
||||||
</div>
|
<script type="text/javascript">require(["token"]);</script>
|
||||||
{% endif %}
|
{% endblock script %}
|
||||||
</div>
|
|
||||||
{% endblock main %}
|
|
||||||
|
|
||||||
{% block script %}
|
|
||||||
{{ super() }}
|
|
||||||
<script type="text/javascript">
|
|
||||||
require(["token"]);
|
|
||||||
</script>
|
|
||||||
{% endblock script %}
|
|
||||||
|
Reference in New Issue
Block a user