Skip to content

Commit

Permalink
Render react app
Browse files Browse the repository at this point in the history
  • Loading branch information
trungleduc committed Jan 8, 2024
1 parent 2461180 commit 582c41e
Show file tree
Hide file tree
Showing 10 changed files with 220 additions and 170 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,5 @@ config.yaml
.yarn
node_modules
frontend/dist
frontend/lib
frontend/lib
**/js/react/
2 changes: 1 addition & 1 deletion frontend/src/environments/App.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
export default function App() {
return (
<main>
<p>App</p>
<p>Foo bar</p>
</main>
);
}
2 changes: 1 addition & 1 deletion frontend/src/environments/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import App from './App';

const rootElement = document.getElementById('root');
const rootElement = document.getElementById('environments-root');
const root = createRoot(rootElement!);

root.render(
Expand Down
11 changes: 10 additions & 1 deletion frontend/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ const path = require('path');

const config = {
mode: process.env.NODE_ENV ?? "development",
watch: process.env.NODE_ENV === "production" ? false: true,
module: {
rules: [
{
Expand All @@ -20,11 +21,19 @@ const config = {
},
};

const distRoot = path.resolve(
__dirname,
'..',
'tljh_repo2docker',
'static',
'js'
);

const environmentsPageConfig = {
name: "environments",
entry: "./src/environments/main.tsx",
output: {
path: path.resolve(__dirname, "dist"),
path: path.resolve(distRoot, "react"),
filename: "environments.js",
},
...config,
Expand Down
2 changes: 2 additions & 0 deletions tljh_repo2docker/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

from .builder import BuildHandler
from .docker import list_images
from .imagesOld import ImagesHandlerOld
from .images import ImagesHandler
from .logs import LogsHandler

Expand Down Expand Up @@ -196,6 +197,7 @@ def tljh_custom_jupyterhub_config(c):
# register the handlers to manage the user images
c.JupyterHub.extra_handlers.extend(
[
(r"environments-old", ImagesHandlerOld),
(r"environments", ImagesHandler),
(r"api/environments", BuildHandler),
(r"api/environments/([^/]+)/logs", LogsHandler),
Expand Down
28 changes: 28 additions & 0 deletions tljh_repo2docker/imagesOld.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
from inspect import isawaitable
from jupyterhub.handlers.base import BaseHandler
from jupyterhub.utils import admin_only
from tornado import web

from .docker import list_containers, list_images


class ImagesHandlerOld(BaseHandler):
"""
Handler to show the list of environments as Docker images
"""

@web.authenticated
@admin_only
async def get(self):
images = await list_images()
containers = await list_containers()
result = self.render_template(
"images-old.html",
images=images + containers,
default_mem_limit=self.settings.get("default_mem_limit"),
default_cpu_limit=self.settings.get("default_cpu_limit"),
)
if isawaitable(result):
self.write(await result)
else:
self.write(result)
1 change: 0 additions & 1 deletion tljh_repo2docker/static/js/images.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ require([
var base_url = window.jhdata.base_url;
var api = new JHAPI(base_url);


function getRow(element) {
var original = element;
while (!element.hasClass("image-row")) {
Expand Down
170 changes: 170 additions & 0 deletions tljh_repo2docker/templates/images-old.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
{% extends "page.html" %}

{% block stylesheet %}
{{ super() }}
<link rel="stylesheet" href="{{ base_url }}environments-static/css/style.css" type="text/css"/>
<link rel="stylesheet" href="{{ base_url }}environments-static/vendor/xterm.css" type="text/css"/>
{% endblock %}

{% block main %}

<div class="container images-container">
<table class="table table-striped">
<thead>
<tr>
<th>Namess</th>
<th>Repository URL</th>
<th>Reference</th>
<th>Mem. Limit (GB)</th>
<th>CPU Limit</th>
<th>Status</th>
<th class="text-center"><a id="add-environment" role="button" class="btn btn-primary btn-xs">Add New</a></th>
</tr>
</thead>
<tbody>
{% for image in images %}
<tr class="image-row" data-image="{{ image.image_name }}" data-display-name="{{ image.display_name }}">
<td class="repo-col col-sm-3">
{{ image.display_name }}
</td>
<td class="repo-col col-sm-3">
<a href="{{ image.repo }}" target="_blank">{{ image.repo }}</a>
</td>
<td class="ref-col col-sm-1">
<a href="{{ image.repo }}/tree/{{ image.ref }}" target="_blank">{{ image.ref }}</a>
</td>
<td class="ref-col col-sm-1">
{% if image.mem_limit | length %}
{{ image.mem_limit | replace("G", "") }}
{% else %}
{{ default_mem_limit | replace("G", "") }}
{%- endif %}
</td>
<td class="ref-col col-sm-1">
{% if image.cpu_limit | length %}
{{ image.cpu_limit | replace("G", "") }}
{% else %}
{{ default_cpu_limit | replace("G", "") }}
{%- endif %}
</td>
<td class="status-col col-sm-1">
{% if image.status == 'building' %}
<i title="Building" class="fa fa-refresh fa-spin fa-lg fa-fw" style="color: orange;"></i>
<a role="button" class="logs btn btn-xs btn-info">Logs</a>
{%- elif image.status == 'built' %}
<i title="Built" class="fa fa-check-square fa-lg fa-fw" style="color: green;"></i>
{%- endif %}
</td>
<td class="build-col col-sm-2 text-center">
{% if image.status == 'built' %}
<a role="button" class="remove-environment btn btn-xs btn-danger">
Remove
</a>
{% else %}
<p class="bg-info">
The environment is under construction. This can take several minutes to complete.<br>
Click <a href="#" onClick="window.location.reload()">here</a> to refresh.
</p>
{%- endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>

{% call modal('Adding Environment', btn_label='OK', btn_class='btn-primary adding-button') %}
<div class="text-center">
<p><i class="fa fa-spinner fa-pulse fa-fw fa-3x"></i></p>
</div>
{% endcall %}

{% call modal('Removing Environment', btn_label='OK', btn_class='btn-primary removing-button') %}
<div class="text-center">
<p><i class="fa fa-spinner fa-pulse fa-fw fa-3x"></i></p>
</div>
{% endcall %}

{% call modal('Remove Environment', btn_label='Remove', btn_class='btn-danger remove-button') %}
Are you sure you want to remove the following environment?
<pre class="delete-environment">ENV</pre>
{% endcall %}

{% call modal('Show Logs', btn_label='Close', btn_class='btn-primary') %}
<div style="width: auto; height: 400px;" class="build-logs"></div>
{% endcall %}

{% macro environment_modal(name, multi=False) %}
{% call modal(name, btn_class='btn-primary save-button') %}
<div class="form-horizontal">
<div class="form-group">
<label for="repository-url" class="col-sm-4 control-label">Repository URL</label>
<div class="col-sm-8">
<input type="text" class="form-control repo-input" id="repository-url"/>
</div>
</div>
<div class="form-group">
<label for="reference" class="col-sm-4 control-label">Reference (git commit)</label>
<div class="col-sm-8">
<input type="text" class="form-control ref-input" id="reference" placeholder="HEAD"/>
</div>
</div>
<div class="form-group">
<label for="name" class="col-sm-4 control-label">Name of the environment</label>
<div class="col-sm-8">
<input data-toggle="tooltip" title="Allowed characters are a to z, A to Z, 0 to 9, - and _"
type="text" class="form-control name-input" id="name"/>
<p class="help-block">Example: course-python-101-B37</p>
<p class="help-block">If empty, a name will be generated from the repo URL</p>
</div>
</div>
<div class="form-group">
<label for="memory" class="col-sm-4 control-label">Memory Limit (GB)</label>
<div class="col-sm-8">
<input type="number" step="1" min="1" class="form-control memory-input" id="memory" placeholder="2"/>
</div>
</div>
<div class="form-group">
<label for="cpu" class="col-sm-4 control-label">CPU Limit</label>
<div class="col-sm-8">
<input type="number" step="1" min="1" class="form-control cpu-input" id="cpu" placeholder="2"/>
</div>
</div>
<details>
<summary>&gt; Advanced</summary>
<div class="form-group">
<label for="build-args" class="col-sm-4 control-label">Build Arguments</label>
<div class="col-sm-8">
<textarea class="form-control build-args-input" id="build-args" rows="4" placeholder="arg1=val1&#10;arg2=val2&#10;..."></textarea>
</div>
</div>
</details>
<details>
<summary>&gt; Credentials (optional)</summary>
<div class="form-group">
<label for="username" class="col-sm-4 control-label">Git Username</label>
<div class="col-sm-8">
<input type="text" class="form-control username-input" id="username"/>
</div>
</div>
<div class="form-group">
<label for="password" class="col-sm-4 control-label">Git Password</label>
<div class="col-sm-8">
<input type="password" class="form-control password-input" id="password"/>
</div>
</div>
</details>
</div>
{% endcall %}
{% endmacro %}

{{ environment_modal('Create Environment') }}

{% endblock %}

{% block script %}
{{ super() }}
<script type="text/javascript">
require(["{{ base_url }}environments-static/js/images.js"]);
</script>
{% endblock %}
Loading

0 comments on commit 582c41e

Please sign in to comment.