Skip to content
Snippets Groups Projects
Commit 9f4e6679 authored by Stefano Alberto Russo's avatar Stefano Alberto Russo
Browse files

UI/UX improvements for new tasks and navigation. Fixes.

parent 90cee362
Branches
Tags
No related merge requests found
......@@ -48,9 +48,9 @@ class Command(BaseCommand):
To change it, head to the <a href="/admin">admin</a> page and edit the <code>Text</code> model.
<br/><br/>
The default installation provides a test user register with email <code>testuser@rosetta.platform</code>
and password <code>testpass</code>, which you can use to login on the menu on the right or using the link
below and give Rosetta a try immediately. If you run with the default docker-compose file (i.e. you just
run <code>rosetta/setup</code>), then you will also have a few demo computing resources you can play with
and password <code>testpass</code>, which you can use to login on the menu on the rightand give Rosetta
a try immediately. If you run with the default docker-compose file (i.e. you just run
<code>rosetta/setup</code>), then you will also have a few demo computing resources you can play with
out-of-the-box, including a small Slurm cluster. Otherwise, you will need to setup your own computing
resources either platform-wide or as user.
</div>
......
......@@ -112,7 +112,7 @@
</div>
<div style="margin-bottom:13px; margin-top: 3px; text-align:center">
<a href="/create_task?task_container_uuid={{ container.uuid }}" class="btn btn-light" style="border: #c0c0c0 1px solid">&nbsp;<i class="fa fa-play" style="color:green"></i></a>
<a href="/create_task?task_container_uuid={{ container.uuid }}&step=two" class="btn btn-light" style="border: #c0c0c0 1px solid">&nbsp;<i class="fa fa-play" style="color:green"></i></a>
</div>
......
......@@ -12,15 +12,24 @@
{% if data.container %}
<h1><a href="/containers">Containers</a> <span style="font-size:18px"> / {{ data.container.name }}</span></h1>
{% else %}
{% if data.mode == 'new_task' %}
<h1>New task</h1>
<hr/>
<h3>Step 1: choose software container.</h3>
<br/>
{% else %}
<h1>Containers</h1>
<hr/>
{% endif %}
<div class="form-filter" style="margin-bottom:20px">
<form action="" method="POST">
<input type="hidden" name="mode" value="{{data.mode}}">
<input type="text" class="form-control" id="search_text" name="search_text" placeholder="Search..." style="width:200px; margin:0; display:inline" value="{{data.search_text}}" autofocus>
<select class="form-control" id="search_type" name="search_type" style="width:120px; margin:0; display:inline">
......
......@@ -11,45 +11,49 @@
<h1>New Task</h1>
<hr>
{% if data.step == 'one' %}
<h3>Step 1: name, container and computing.</h3>
{% if data.step == 'two' %}
<h3>Step 2: set task name and computing.</h3>
{% elif data.step == 'three' %}
<h3>Step 3: add authentication and computing details.</h3>
{% endif %}
<br/>
<div style="width:300px; float:left; border: #e0e0e0 solid 1px; margin:10px; background:#f8f8f8; margin-bottom:15px">
<div style="padding:10px; margin-top:5px; text-align:center; border-bottom: {{data.task_container.color}} solid 10px; ">
<a href="?uuid={{ container.uuid }}">{{ data.task_container.name }}</a>&nbsp;
{% if data.task_container.type == 'docker' %}<img src="/static/img/docker-logo.svg" style="height:18px; width:18px; margin-bottom:4px" />{% endif %}
{% if data.task_container.type == 'singularity' %}<img src="/static/img/singularity-logo.svg" style="height:18px; width:18px; margin-bottom:4px" />{% endif %}
</div>
<div style="padding:10px; height: 64px; vertical-align: middle;">
<b>Image:</b> {{ data.task_container.image_name }}<br/>
<b>Version:</b> {{ data.task_container.image_tag }}
</div>
</div>
{% if data.step == 'two' %}
<form action="/create_task/" method="POST">
{% csrf_token %}
<input type="hidden" name="step" value="one" />
<input type="hidden" name="step" value="{{ data.next_step }}" />
<input type="hidden" name="task_container_uuid" value="{{data.task_container.uuid}}">
<div style="width:300px; float:left; border: #e0e0e0 solid 0px; margin:10px; background:#f8f8f8; margin-bottom:15px">
<table class="dashboard" style="max-width:700px">
<table style="max-width:100%; border: #e0e0e0 solid 1px; margin:0">
<tr><td colspan="2"></td></tr>
<tr>
<td><b>Task name </b></td>
<td>
<input type="text" name="task_name" value="" placeholder="" size="23" required />
<input type="text" name="task_name" value="" placeholder="" size="" required />
</td>
</tr>
<tr>
<td><b>Task container</b></td><td>
{% if data.task_container %}
<select name="task_container_uuid">
<option value="{{data.task_container.uuid}}" selected>{{data.task_container.name}} ({{data.task_container.type.title}})</option>
</select>
{% else %}
<select name="task_container_uuid" >
{% for container in data.containers %}
<option value="{{container.uuid}}">{{container.name}} ({{container.type.title}})</option>
{% endfor %}
</select>
{% endif %}
</td>
</tr>
<tr>
<td><b>Computing resource</b></td><td>
<td><b>Computing</b></td><td>
<select name="task_computing_uuid" >
{% for computing in data.computings %}}
<option value="{{ computing.uuid }}">{{ computing.name}}</option>
......@@ -59,38 +63,30 @@
</tr>
<tr>
<td colspan=2 align=center style="padding:20px">
<td colspan=2 align=center style="padding:9px">
<input type="submit" value="Next">
</td>
</tr>
</table>
</div>
</form>
{% elif data.step == 'two' %}
{% elif data.step == 'three' %}
<h3>Step 2: add authentication and computing details</h3>
<br/>
<table class="dashboard" style="max-width:700px">
<tr><td colspan="2"></td></tr>
<div style="width:300px; float:left; border: #e0e0e0 solid 0px; margin:10px; background:#f8f8f8; margin-bottom:15px">
<table style="width:100%; height:126px; border: #e0e0e0 solid 1px; margin:0">
<tr>
<tr valign="bottom">
<td><b>Task name </b></td>
<td>
<input type="text" name="task_name_RECAP" value="{{ data.task_name }}" placeholder="" size="23" disabled />
<input type="text" name="task_name_RECAP" value="{{ data.task_name }}" placeholder="" size="" disabled />
</td>
</tr>
<tr>
<td><b>Task container</b></td><td>
<select name="task_container_uuid_RECAP">
<option value="" selected>{{data.task_container.name}} ({{data.task_container.type.title}})</option>
</select>
</td>
</tr>
<tr>
<td><b>Computing resource</b></td><td>
<tr valign="top">
<td><b>Computing</b></td><td>
<select name="task_computing_uuid_RECAP" >
<option value="">{{ data.task_computing.name}}</option>
</select>
......@@ -98,8 +94,10 @@
</tr>
</table>
</div>
<div style="width:640px; float:left; border: #e0e0e0 solid 0px; margin:10px; background:#f8f8f8; margin-bottom:15px">
<br>
{% if data.task_container.type == 'singularity' and not data.task_container.supports_dynamic_ports %}
<div> <p style="font-size:15px; max-width:700px; margin-bottom:20px; margin-left:5px">
<i class="fa fa-exclamation-triangle" style="color:orange"></i> This container does not support dynamic ports and you are running it with Singularity, without network insulation. This means that if the container port is already occupied, it will not be able to start.
......@@ -114,7 +112,8 @@
<form action="/create_task/" method="POST">
{% csrf_token %}
<input type="hidden" name="step" value="two" />
<input type="hidden" name="task_container_uuid" value="{{data.task_container.uuid}}">
<input type="hidden" name="step" value="{{ data.next_step }}" />
<input type="hidden" name="task_name" value="{{ data.task_name }}" />
<input type="hidden" name="task_container_uuid" value="{{ data.task_container.uuid }}" />
<input type="hidden" name="task_computing_uuid" value="{{ data.task_computing.uuid }}" />
......@@ -180,7 +179,7 @@
</td>
</tr> -->
{% if data.task_computing.type == 'slurm' %}
{% if data.task_computing.access_method == 'slurm+ssh' %}
<tr>
<td><b>Computing options</b></td>
<td>
......@@ -207,6 +206,7 @@
</tr>
</table>
</form>
</div>
{% else %}
......
......@@ -25,17 +25,6 @@
{% endif %}
</div>
</div>
<div style="display:table-row">
<div class="text-vertical-bottom">
{% if user.is_authenticated %}
<a href="/tasks" class="btn btn-dark btn-lg">Tasks</a>
<a href="/containers" class="btn btn-dark btn-lg">Containers</a>
{% else %}
<a href="/login" class="btn btn-dark btn-lg">Log In</a>
{% endif %}
</div>
</div>
</header>
{% include "footer.html" %}
......
......@@ -28,7 +28,7 @@
{% if not data.task and not data.tasks %}
<div class="row" style="padding:10px; padding-left:15px">
<i>Nothing here. To create a new task, choose a container from the "containers" menu entry and run it by hitting the play button.</i>
<a href="/create_task">New task...</a>
</div>
{% endif %}
......
......@@ -402,35 +402,12 @@ def create_task(request):
data['profile'] = Profile.objects.get(user=request.user)
data['title'] = 'New Task'
# Step if any
step = request.POST.get('step', None)
# Container uuid if any
container_uuid = request.GET.get('task_container_uuid', None)
if container_uuid:
try:
data['task_container'] = Container.objects.get(uuid=container_uuid, user=request.user)
except Container.DoesNotExist:
data['task_container'] = Container.objects.get(uuid=container_uuid, user=None)
else:
# Get containers
data['containers'] = list(Container.objects.filter(user=None)) + list(Container.objects.filter(user=request.user))
# Get computings
data['computings'] = list(Computing.objects.filter(user=None)) + list(Computing.objects.filter(user=request.user))
# Handle step
if step:
# Task name
task_name = request.POST.get('task_name', None)
if not task_name:
raise ErrorMessage('Missing task name')
data['task_name'] = task_name
# Task container
# Get task container helper function
def get_task_container(request):
task_container_uuid = request.POST.get('task_container_uuid', None)
if not task_container_uuid:
# At the second step the task uuid is set via a GET request
task_container_uuid = request.GET.get('task_container_uuid', None)
try:
task_container = Container.objects.get(uuid=task_container_uuid, user=None)
except Container.DoesNotExist:
......@@ -438,9 +415,10 @@ def create_task(request):
task_container = Container.objects.get(uuid=task_container_uuid, user=request.user)
except Container.DoesNotExist:
raise Exception('Consistency error, container with uuid "{}" does not exists or user "{}" does not have access rights'.format(task_container_uuid, request.user.email))
data['task_container'] = task_container
return task_container
# Task computing
# Get task computing helper function
def get_task_computing(request):
task_computing_uuid = request.POST.get('task_computing_uuid', None)
try:
task_computing = Computing.objects.get(uuid=task_computing_uuid, user=None)
......@@ -450,26 +428,75 @@ def create_task(request):
except Computing.DoesNotExist:
raise Exception('Consistency error, computing with uuid "{}" does not exists or user "{}" does not have access rights'.format(task_computing_uuid, request.user.email))
task_computing.attach_user_conf(request.user)
data['task_computing'] = task_computing
return task_computing
# Get task name helper function
def get_task_name(request):
task_name = request.POST.get('task_name', None)
if not task_name:
raise ErrorMessage('Missing task name')
return task_name
# Handle step one/two
if step == 'one':
# Get step if any, check both POST and GET
step = request.POST.get('step', None)
if not step:
step = request.GET.get('step', None)
# Set step and task uuid
data['step'] = 'two'
# Handle the various steps
if not step:
# Step one is assumed: chose software container
return HttpResponseRedirect('/containers/?mode=new_task')
elif step == 'two':
# Get software container
data['task_container'] = get_task_container(request)
# List all computing resources
data['computings'] = list(Computing.objects.filter(user=None)) + list(Computing.objects.filter(user=request.user))
data['step'] = 'two'
data['next_step'] = 'three'
elif step == 'three':
# Get software container
data['task_container'] = get_task_container(request)
# Get computing resource
data['task_computing'] = get_task_computing(request)
# Get task name
data['task_name'] = get_task_name(request)
# Set current and next step
data['step'] = 'three'
data['next_step'] = 'last'
elif step == 'last':
# Get software container
data['task_container'] = get_task_container(request)
# Get computing resource
data['task_computing'] = get_task_computing(request)
# Get task name
data['task_name'] = get_task_name(request)
# Generate the task uuid
task_uuid = str(uuid.uuid4())
# Create the task object
task = Task(uuid = task_uuid,
user = request.user,
name = task_name,
name = data['task_name'],
status = TaskStatuses.created,
container = task_container,
computing = task_computing)
container = data['task_container'],
computing = data['task_computing'])
# Add auth
task.auth_user = request.POST.get('auth_user', None)
......@@ -534,10 +561,6 @@ def create_task(request):
# Set step
data['step'] = 'created'
else:
# Set step
data['step'] = 'one'
return render(request, 'create_task.html', {'data': data})
......@@ -608,10 +631,15 @@ def containers(request):
search_text = request.POST.get('search_text', '')
search_type = request.POST.get('search_type', 'All')
# Set bak to page data
# Set back to page data
data['search_type'] = search_type
data['search_text'] = search_text
# Are we using this page as first step of a new task?
data['mode'] = request.GET.get('mode', None)
if not data['mode']:
data['mode'] = request.POST.get('mode', None)
# Do we have to operate on a specific container?
if uuid:
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment