Skip to content
Snippets Groups Projects
Commit cf79fabc authored by Tim Kreuzer's avatar Tim Kreuzer
Browse files

add first draft of images + templates

parent 5fbfdbaf
No related branches found
No related tags found
1 merge request!1Staging
static/images/base4NFDI_kurz_rgb.png

16.9 KiB

static/images/jupyter4nfdi_logo.png

353 KiB

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Generator: Adobe Illustrator 24.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg
version="1.1"
id="Ebene_1"
x="0px"
y="0px"
viewBox="0 0 283.47122 126.13"
xml:space="preserve"
sodipodi:docname="nfdi-logo-small.svg"
inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)"
width="283.47122"
height="126.13"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs
id="defs103" /><sodipodi:namedview
id="namedview101"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
showgrid="false"
inkscape:zoom="0.84333982"
inkscape:cx="390.11558"
inkscape:cy="-40.908776"
inkscape:window-width="1920"
inkscape:window-height="1200"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="Ebene_1"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0" />
<style
type="text/css"
id="style2">
.st0{fill:none;}
.st1{fill:#B3BCC2;}
.st2{fill:#FFFFFF;}
.st3{fill:#0BBBEF;}
.st4{fill:#A2C617;}
.st5{fill:#8A959C;}
.st6{fill:#45556A;}
</style>
<g
id="g98"
transform="translate(-70.86,-70.87)">
<path
class="st2"
d="m 220.66,70.87 c -22.97,0 -41.65,18.68 -41.65,41.65 v 76.35 c 0,4.49 3.64,8.13 8.13,8.13 4.49,0 8.13,-3.64 8.13,-8.13 v -50.61 h 12.86 c 4.18,0 7.57,-3.46 7.57,-7.73 0,-4.27 -3.39,-7.73 -7.57,-7.73 h -12.86 v -10.28 c 0,-14 11.39,-25.39 25.39,-25.39 4.49,0 8.13,-3.64 8.13,-8.13 0,-4.49 -3.64,-8.13 -8.13,-8.13"
id="path82" />
<g
id="g88">
<path
class="st2"
d="m 147.31,196.99 c -4.49,0 -8.13,-3.64 -8.13,-8.13 l 0.06,-33.76 c 0,-14 -11.39,-25.39 -25.39,-25.39 -14,0 -25.39,11.39 -25.39,25.39 0,4.49 -3.64,8.13 -8.13,8.13 -4.49,0 -8.13,-3.64 -8.13,-8.13 0,-22.96 18.68,-41.65 41.65,-41.65 22.97,0 41.65,18.68 41.65,41.65 v 33.76 c 0,4.49 -3.7,8.13 -8.19,8.13"
id="path84" />
<path
class="st3"
d="m 89.8,187.5 c 0,5.23 -4.24,9.47 -9.47,9.47 -5.23,0 -9.47,-4.24 -9.47,-9.47 0,-5.23 4.24,-9.47 9.47,-9.47 5.23,0 9.47,4.24 9.47,9.47"
id="path86" />
</g>
<g
id="g94">
<path
class="st4"
d="m 351.91,95.15 c 3.49,3.89 3.17,9.88 -0.72,13.37 -3.89,3.49 -9.88,3.16 -13.37,-0.73 -3.49,-3.89 -3.17,-9.88 0.72,-13.37 3.89,-3.49 9.88,-3.17 13.37,0.73"
id="path90" />
<path
class="st2"
d="m 352.99,133.86 v 55 c 0,4.49 -3.64,8.13 -8.13,8.13 v 0 c -4.49,0 -8.13,-3.64 -8.13,-8.13 v -55 c 0,-4.49 3.64,-8.13 8.13,-8.13 v 0 c 4.5,0 8.13,3.64 8.13,8.13 z"
id="path92" />
</g>
<path
class="st2"
d="m 304.88,70.87 c -4.49,0 -8.13,3.64 -8.13,8.13 v 43.2 c -7.06,-5.47 -15.91,-8.73 -25.51,-8.73 -23.03,0 -41.77,18.73 -41.77,41.76 0,23.03 18.73,41.76 41.77,41.76 23.03,0 41.76,-18.73 41.76,-41.76 V 79 c 0,-4.49 -3.63,-8.13 -8.12,-8.13 z m -33.64,109.87 c -14.07,0 -25.51,-11.44 -25.51,-25.51 0,-14.06 11.44,-25.51 25.51,-25.51 14.06,0 25.51,11.44 25.51,25.51 -0.01,14.07 -11.45,25.51 -25.51,25.51 z"
id="path96" />
</g>
</svg>
static/images/nfdi_rgb_Wortmarke_Zusatz_hoch.png

44.6 KiB

{%- import "macros/svgs.jinja" as svg -%}
{%- set jupyter_name = "Jupyter-JSC" -%}
{#- Get all systems configured for this hub,
sort them by weight and assign status ids -#}
{#- Jupyter should always be first -#}
{%- set incident_services = custom_config.get("incidentCheck", {}).get("services", {}) -%}
{%- set systems_default_order = [["JUPYTER", incident_services.get("JUPYTER", 40)]] -%}
{%- for system in custom_config.get("systems", {}) | sort(attribute='weight') -%}
{%- set system = system.upper().replace("-", '') -%}
{%- set status_id = incident_services.get(system, 0) -%}
{%- do systems_default_order.append([system, status_id]) -%}
{%- endfor -%}
{%- macro random_int(len) -%}
{%- for _ in range(len) -%}
{{ range(10) | random }}
{%- endfor -%}
{%- endmacro -%}
{%- macro number_of_users(system) -%}
{%- if system == "jupyter" -%}
{%- set system_svg = svg.users_svg -%}
{%- set url_suffix = "" -%}
{%- elif system == "jsccloud"%}
{%- set system_svg = svg.servers_svg -%}
{%- set url_suffix = "var-system=JSC-Cloud" -%}
{%- else -%}
{%- set system_svg = svg.servers_svg -%}
{%- set url_suffix = "var-system=" + system.upper() -%}
{%- endif -%}
<a class="system-users d-inline-block text-muted ms-1"
data-bs-toggle="tooltip" data-bs-placement="top" title="Number of active {%- if system == 'jupyter' %} users in the last 24 hours {%- else %} servers {%- endif -%}"
href="https://{{hostname}}/grafana/?{{url_suffix}}" target="_blank">
<span id="{{system}}-users">0</span>
<span> {{ system_svg | safe }} </span>
<div class="system-users-link-div d-inline-block">
<span class="system-users-link" id="{{system}}-users-link">
{{ svg.link_svg | safe }}
</span>
</div>
</a>
{%- endmacro -%}
{%- macro ampel(system, system_id) -%}
{%- set system_lower = system.lower() %}
<div id="ampel-{{system_lower}}" class="text-center">
<img class="ampel-img" src='{{static_url( "images/footer/systems/" + system_lower + ".svg?v=" + random_int(10) )}}' />
<a id="ampel-{{system_lower}}-tooltip" href="https://status.jsc.fz-juelich.de/services/{{system_id}}" target="_blank" class="align-middle" data-bs-toggle="tooltip" data-bs-placement="top">
{%- if system == "JUPYTER" -%}
{{ jupyter_name }}
{%- elif system == "JSCCLOUD" -%}
JSC-Cloud
{%- else -%}
{{ system }}
{%- endif -%}
</a>
{{ number_of_users(system_lower) }}
</div>
{%- endmacro -%}
{%- macro create_carousel_systems(start_index, length) -%}
{%- set end_index = start_index + length -%}
{%- for system_config in systems_default_order %}
{%- if loop.index0 >= start_index and loop.index0 < end_index %}
{{ ampel(system_config[0], system_config[1]) }}
{%- endif -%}
{%- endfor -%}
{%- endmacro -%}
{%- block footer -%}
<footer class="navbar mt-auto p-0">
<div id="footer-top" class="container-fluid justify-content-evenly p-4">
{%- if systems_default_order | length > 5 -%}
{#- We create a carousel to be able to show all systems in the footer #}
<div id="footerSystemsCarousel" class="carousel carousel-dark slide w-100" data-bs-ride="carousel" data-bs-interval="10000">
<div class="carousel-inner">
<div class="carousel-item active">
<div id="systems-page-1" class="d-flex justify-content-evenly">
{{ create_carousel_systems(0, 4) }}
</div>
</div>
<div class="carousel-item">
<div id="systems-page-2" class="d-flex justify-content-evenly">
{{ create_carousel_systems(4, 4) }}
</div>
</div>
</div>
<button class="carousel-control-prev" type="button" data-bs-target="#footerSystemsCarousel" data-bs-slide="prev" style="width: unset;">
<span class="carousel-control-prev-icon"></span>
<span class="visually-hidden">Previous</span>
</button>
<button class="carousel-control-next" type="button" data-bs-target="#footerSystemsCarousel" data-bs-slide="next" style="width: unset;">
<span class="carousel-control-next-icon"></span>
<span class="visually-hidden">Next</span>
</button>
</div>
{%- else -%}
{#- We only have a few systems and do not need a carousel to display them #}
<div id="systems-page-1" class="d-flex justify-content-evenly w-100">
{%- for system_config in systems_default_order %}
{{ ampel(system_config[0], system_config[1]) }}
{%- endfor %}
</div>
{%- endif %}
</div>
<div id="footer-bottom" class="container-fluid justify-content-center">
{%- set logo_width = "220px" -%}
{%- set div_classes = "px-2 text-center" %}
<a class="py-2 {{div_classes}}" target="_blank" href="https://www.fz-juelich.de">&copy; Forschungszentrum Jülich</a>
<div class="flex-grow-1 {{div_classes}}">
{%- set footer_margin = "m-1" %}
<a href="{{ base_url }}imprint">Legal Notice</a>
<span class="{{ footer_margin }}">|</span>
<a href="{{ base_url }}privacy">Privacy Policy</a>
<span class="{{ footer_margin }}">|</span>
<a href="{{ base_url }}terms">Terms of Service</a>
<span class="{{ footer_margin }}">|</span>
<a href="mailto:ds-support@fz-juelich.de?subject=Jupyter4NFDI Support&amp;body=Please describe your problem here. (english or german)">Support</a>
</div>
<div class="py-4 {{div_classes}}">
<a href="https://www.nfdi.de/" target="_blank">
<img id="helmholtz-logo" src='{{ static_url("images/nfdi-logo-small.svg", include_version=False) }}' height="60px">
</a>
</div>
</div>
</footer>
{%- endblock -%}
{%- block script -%}
<script type="text/javascript">
require(["jquery", "home/utils"], function (
$,
utils
) {
"use strict";
function reorderSystems(incidentsData) {
const systemsDefaultOrder = {{ systems_default_order | tojson}};
// Create copy of data and filter it
var systemsFiltered = { ...incidentsData };
for (let key in systemsFiltered) {
if (systemsFiltered[key].health < 30) delete systemsFiltered[key];
}
delete systemsFiltered["JUPYTER"]; // Jupyter should always be first
var systemsFilteredandSortedBySeverity = Object.keys(systemsFiltered).sort((a, b) => systemsFiltered[a]["health"] < systemsFiltered[b]["health"]);
// Finally, create sorted list with all systems
var systemsSorted = ["JUPYTER"];
systemsFilteredandSortedBySeverity.forEach((system) => {
systemsSorted.push(system);
});
systemsDefaultOrder.forEach(systemConfig => {
var system = systemConfig[0];
if (!systemsSorted.includes(system)) {
systemsSorted.push(system);
}
})
var carousel_exists = $("#footerSystemsCarousel").length;
// Recreate footer with systems in the sorted order
for (const [index, system] of systemsSorted.entries()) {
let ampel = $(`#ampel-${system.toLowerCase()}`);
ampel.remove();
if (!carousel_exists) {
$("#systems-page-1").append(ampel);
}
else {
if (index < 4) $("#systems-page-1").append(ampel);
else $("#systems-page-2").append(ampel);
}
}
}
function updateSystemHoverTooltips() {
const incidents = {{ incidents | tojson }};
for (const [system, systemInfo] of Object.entries(incidents)) {
if (systemInfo.incident) {
$(`#ampel-${system.toLowerCase()}-tooltip`)
.attr('data-bs-original-title', systemInfo.incident);
}
}
reorderSystems(incidents);
}
$(document).ready(function() {
updateSystemHoverTooltips();
utils.updateNumberOfUsers();
})
if (!(window.location.pathname.endsWith("home") || window.location.pathname.includes("spawn-pending"))) {
console.log("setup SSE")
let userSpawnerNotificationUrl = `${jhdata.base_url}api/users/${jhdata.user}/notifications/spawners?_xsrf=${window.jhdata.xsrf_token}`;
evtSourcesGlobal["footer"] = new EventSource(userSpawnerNotificationUrl);
evtSourcesGlobal["footer"].onmessage = (e) => {
utils.updateNumberOfUsers();
};
}
})
</script>
{%- endblock -%}
{%- macro create_user_widget() -%}
{%- if user %}
<div class="dropdown">
<button class="btn btn-outline-primary dropdown-toggle mb-2" type="button" data-bs-toggle="dropdown" data-bs-auto-close="outside">{{ user.name }}</button>
<ul class="dropdown-menu dropdown-menu-end w-100">
{%- if auth_state and auth_state.get("last_login", False) %}
<li><h6 class="dropdown-header">Last login</h6></li>
<li><a class="dropdown-item disabled text-black">{{ auth_state.get("last_login") }}</a></li>
<li><hr class="dropdown-divider"></li>
{%- endif -%}
<li><a class="dropdown-item text-decoration-none" href="{{ base_url }}2FA">2-Factor Authentication</a></li>
<li><hr class="dropdown-divider"></li>
<li>
<button id="logout" class="dropdown-item">
<svg class="align-middle" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-box-arrow-right" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M10 12.5a.5.5 0 0 1-.5.5h-8a.5.5 0 0 1-.5-.5v-9a.5.5 0 0 1 .5-.5h8a.5.5 0 0 1 .5.5v2a.5.5 0 0 0 1 0v-2A1.5 1.5 0 0 0 9.5 2h-8A1.5 1.5 0 0 0 0 3.5v9A1.5 1.5 0 0 0 1.5 14h8a1.5 1.5 0 0 0 1.5-1.5v-2a.5.5 0 0 0-1 0v2z"/>
<path fill-rule="evenodd" d="M15.854 8.354a.5.5 0 0 0 0-.708l-3-3a.5.5 0 0 0-.708.708L14.293 7.5H5.5a.5.5 0 0 0 0 1h8.793l-2.147 2.146a.5.5 0 0 0 .708.708l3-3z"/>
</svg>
<span class="align-middle">Logout</span>
</button>
</li>
</ul>
</div>
{%- else %}
<div class="empty mb-3"></div>
{%- endif -%}
{%- endmacro -%}
{%- macro create_navigation(prefix="") -%}
<ul class="nav">
{#- Show different headers depending on if a user is logged in or not -#}
{#- If not logged in, we cannot show these links in the user widget, so we put them in the nav bar instead -#}
<div class="d-flex">
{%- if user %}
<li class="nav-item"><a id="{{prefix}}start-nav-item" class="nav-link text-decoration-none" href="{{ base_url }}home">JupyterLab</a></li>
{%- if user.admin %}
<li class="nav-item"><a id="{{prefix}}admin-nav-item" class="nav-link text-decoration-none" href="{{ base_url }}admin">Admin</a></li>
{%- endif -%}
{%- else %}
<li class="nav-item"><a id="{{prefix}}start-nav-item" class="nav-link text-decoration-none" href="{{ base_url }}login">Login</a></li>
{%- endif %}
<li class="nav-item"><a id="{{prefix}}status-nav-item" class="nav-link text-decoration-none" target="_blank" href="https://status.jsc.fz-juelich.de/">JSC Status</a></li>
<li class="nav-item"><a id="{{prefix}}docs-nav-item" class="nav-link text-decoration-none" target="_blank" href="https://docs.{{hostname}}/github/FZJ-JSC/jupyter-jsc-notebooks/blob/documentation/index.ipynb">Documentation</a></li>
<li class="nav-item"><a id="{{prefix}}links-nav-item" class="nav-link text-decoration-none" href="{{ base_url }}links">More Links</a></li>
</div>
</ul>
{%- endmacro -%}
{%- block header %}
<nav class="navbar navbar-light navbar-expand-lg bg-white pb-0">
<div class="container-fluid">
<a class="navbar-brand" href="https://fz-juelich.de/jsc/en" target="_blank">
<img id="jsc-logo" class="p-3" title="https://base4nfdi.de/" alt="base4NFDIJSC" src='{{ static_url("images/base4NFDI_kurz_rgb.png", include_version=False) }}' height="100px">
</a>
{#- Button that toggles the navigation. Is visible on medium screens and smaller. #}
<button class="navbar-toggler mb-4" type="button" data-bs-toggle="collapse" data-bs-target="#navbarCollapsibleContent">
<span class="navbar-toggler-icon"></span>
</button>
{#- This div is hidden on medium screens and smaller. #}
<div class="collapse navbar-collapse align-self-end">
{{ create_navigation() }}
</div>
<div class="d-flex flex-column align-items-end ms-auto">
{{ create_user_widget() }}
</div>
</div>
{#- This div is toggled by the navbar toggle button above and appears below the logos. #}
<div class="collapse navbar-collapse d-lg-none" style="margin-left: 2rem;" id="navbarCollapsibleContent">
{{ create_navigation(prefix="collapse-") }}
</div>
</nav>
{%- endblock %}
{%- extends "page.html" -%}
{%- block stylesheet -%}
<link rel="stylesheet" href='{{static_url("css/login.css")}}' type="text/css" />
{%- endblock -%}
{%- macro carousel_item(title, href, title_text, text, active="") -%}
<div class="carousel-item {{active}}">
<a target="_blank" href="{{href}}" title="{{title}}">
<div class="text-small">
<ul type="square">
<li class="text-dark"><small>{{ title.upper() }}</small></li>
</ul>
</div>
<h3>{{ title_text }}</h3>
</a>
<p class="fs-5" style="color: #023d6b;">We are pleased to bring "Supercomputing in your browser".</p>
<p class="fs-5"> {{ text }} <a target="_blank" href="{{href}}">Read more.</a> </p>
</div>
{%- endmacro -%}
{%- block main -%}
<div class="row g-0 h-100 justify-content-center">
<div class="col-12 col-lg-4 order-lg-1">
<div id="login-div" class="d-flex flex-column bg-secondary h-100">
<div id="upper-login-div" class="d-flex flex-column justify-content-center mx-auto p-4">
<h3>Jupyter4NFDI</h3>
<p class="fs-5">
A central JupyterHub providing access to various software stacks
and computing resources across the NFDI consortia.
<br><br>
Log in is currently possible via Helmholtz AAI. Once <a href="https://nfdi-aai.de/" target="_blank">IAM4NFDI</a> is ready, we will use this AAI instead.
The resources you can use depend on the selected Identity Provider.
<br><br>
If you are an administrator and would like to add your resources to this central JupytreHub, feel free to <a href="mailto:ds-support@fz-juelich.de">contact</a> us.
</p>
</div>
<div id="lower-login-div" class="bg-info">
<div class="d-flex justify-content-center align-items-center mx-auto p-4">
<a id="btn-login" class="btn btn-primary" role="button">Login</a>
<div class="white-line"></div>
<img src='{{static_url("images/pages/login/User.svg", include_version=False) }}' />
<div class="white-line"></div>
<a id="btn-register" class="btn btn-primary" role="button"
href="https://judoor.fz-juelich.de">Register</a>
</div>
</div>
</div>
</div>
<div class="col-12 col-lg-8 order-lg-0">
<div id="carousel-background" class="d-flex align-items-center h-100">
<div id="login-carousel" class="carousel slide d-flex justify-content-center w-100" data-bs-ride="carousel">
<div class="carousel-indicators">
<button type="button" data-bs-target="#login-carousel" data-bs-slide-to="0" class="active" aria-current="true" aria-label="Slide 1"></button>
<button type="button" data-bs-target="#login-carousel" data-bs-slide-to="1" aria-label="Slide 2"></button>
<button type="button" data-bs-target="#login-carousel" data-bs-slide-to="2" aria-label="Slide 3"></button>
<button type="button" data-bs-target="#login-carousel" data-bs-slide-to="3" aria-label="Slide 4"></button>
</div>
<div class="carousel-inner">
{{ carousel_item("Jupyter", "https://jupyter.org", "Supercomputing in Your Browser",
"Jupyter-JSC is designed to provide the rich high performance computing (HPC) ecosystem
to the world's most popular software: web browsers. JupyterLab is a web-based interactive
development environment for Jupyter notebooks, code, and data. JupyterLab is flexible
to support a wide range of workflows in data science, scientific computing, and machine learning.",
"active") }}
{{ carousel_item("Jupyter Notebooks", "https://jupyter-notebook.readthedocs.io/en/stable/notebook.html",
"Share your Workflows", "Jupyter-JSC allows you to create and share documents that contain
live code, equations, visualizations and explanatory text. Uses include: data cleaning and transformation,
numerical simulation, statistical modeling, machine learning and much more.")
}}
{{ carousel_item("JupyterLab", "https://jupyterlab.readthedocs.io", "Next-Generation Notebook Interface",
"Jupyter-JSC gives access to JupyterLab, a web-based interactive development environment for Jupyter
notebooks, code, and data. JupyterLab is flexible: configure and arrange the user interface to support a
wide range of workflows in data science, scientific computing, and machine learning. JupyterLab is extensible
and modular: write plugins that add new components and integrate with existing ones.")
}}
{{ carousel_item("JupyterHub", "https://jupyterhub.readthedocs.io", "Serving Jupyter Notebooks for Multiple
Users", "Jupyter-JSC is a JupyterHub to serve Jupyter notebooks for multiple users. It can be used in
classes of students, a corporate data science group or scientific research group. It is a multi-user hub
that spawns, manages, and proxies multiple instances of the single-user Jupyter notebook server.") }}
</div>
<button class="carousel-control-prev" type="button" data-bs-target="#login-carousel" data-bs-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="visually-hidden">Previous</span>
</button>
<button class="carousel-control-next" type="button" data-bs-target="#login-carousel" data-bs-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="visually-hidden">Next</span>
</button>
</div>
</div>
</div>
</div>
{%- endblock -%}
{%- block script -%}
<script src='{{static_url("js/login.js", include_version=False) }}'></script>
<script>
$("nav [id$=nav-item]").removeClass("active");
$("#start-nav-item, #collapse-start-nav-item").addClass("active");
$("#btn-login").click(function () {
var url = window.location.search;
window.location.href = "{{ base_url }}oauth_login" + url;
});
</script>
{%- endblock -%}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment