Commit 98097869 authored by Stefano Alberto Russo's avatar Stefano Alberto Russo
Browse files

Improvements in the UI for handling tasks.

parent b2b1ab23
Loading
Loading
Loading
Loading
+0 −190
Original line number Diff line number Diff line

          {% if data.task %}
          <center>
          <div style="width:350px; display:block; border: #e0e0e0 solid 1px; margin:10px; background:#f8f8f8; margin-bottom:20px">
            <div style="margin-top:5px; padding:10px; text-align:center; border-bottom: #f8f8f8 solid 1px; ">
            <b>{{data.task.name}}</b>
            </div>
            <hr style="margin:0">

          {% else %}
          <div style="width:350px; float:left; border: #e0e0e0 solid 1px; margin:10px; background:#f8f8f8; margin-bottom:20px">

            <div style="margin-top:5px; padding:10px; text-align:center; border-bottom: #e0e0e0 solid 1px; ">
            <a href="?uuid={{ task.uuid }}"><b>{{ task.name }}</b></a>
            </div>


          {% endif %}



            <!-- <div style="background:{{task.color}}; height:24px;"></div> -->

            <!-- <div style="background:{{ task.container.color }}; height:14px;"></div> -->

            <!-- <div style="margin-bottom:15px; margin-top:0px">
              <div style="background:{{task.container.color}}; height:14px; width:149px; float:left"></div>
              <div style="background:{{task.computing.color}}; height:14px; width:149px; float:left"></div>
            </div> -->


            <div style="padding:10px; padding-left:15px; padding-right:15px; text-align:left;">
            <!-- <b>Container:</b> {{ task.container.name }} <span style="font-size:14px; background-color:{{task.container.color}}">&nbsp;&nbsp;&nbsp;&nbsp;</span> <br/>
            <b>Computing:</b> {{ task.computing.name }} <span style="font-size:14px; background-color:{{task.computing.color}}">&nbsp;&nbsp;&nbsp;&nbsp;</span><br/> -->

            <b>Software:</b>
            <a href="/software/?container_uuid={{ task.container.uuid }}" style="color:{{task.container.color}}">{{ task.container.name }}</a>
            {% if task.container.type == 'docker' %}<img src="/static/img/docker-logo.svg" style="height:18px; width:18px; margin-bottom:4px" />{% endif %}
            {% if task.container.type == 'singularity' %}<img src="/static/img/singularity-logo.svg" style="height:18px; width:18px; margin-bottom:4px" />{% endif %}

            <br/>

            <b>Computing:</b> <a href="/computing/?uuid={{ task.computing.uuid }}">{{ task.computing.name }}</a>
            <!-- <a href="/computing/?uuid={{ task.computing.uuid }}" no_style="color:{{task.computing.color}}"><i class="fa fa-external-link" ></i></a><br/> -->

            <div style="margin-top:2px">
            {% if task.status == "running" %}
             <b>Status:</b> <font color="green">running</font>
             {% if task.container.interface_protocol == 'http' or task.container.interface_protocol == 'https' %}
             {% else %}
             @ port {{ task.tcp_tunnel_port }}
             {% endif %}


            {% else %}
             <b>Status:</b> {{ task.status }}
            {% endif %}
            </div>
            </div>

            <div style="margin-bottom:10px; text-align:center; padding:5px">

            <!-- Stop / Delete / Cancel -->
            {% if task.status == "stopped" or task.status == "created" %}
            <a href="?uuid={{task.uuid}}&action=delete&fromlist=True" class="btn btn-action">Delete</a>
            {% else %}
            <a href="?uuid={{task.uuid}}&action=stop&fromlist=True" class="btn btn-action">Stop</a>
            {% endif %}

            <!-- Connect -->
            {% if task.interface_port %}
            {% if task.container.interface_protocol == 'http' or task.container.interface_protocol == 'https' %}
            {% if task.status == "running" %}
            <a href="/task_connect/?uuid={{task.uuid}}" class="btn btn-connect">Connect</a>
            {% else %}
            <a href="" class="btn btn-disabled">Connect</a>
            {% endif %}
            {% endif %}
            {% endif %}

            <!-- View log -->
            {% if task.status == "running" %}
            <a href="/task_log/?uuid={{task.uuid}}&action=viewlog" class="btn btn-action">Logs</a>
            {% else %}
            <a href="" class="btn btn-disabled">Logs</a>
            {% endif %}
            </div>



          </div>


          {% if data.task %}
          <br/>

           <a href="javascript:void(0);" id="show_button" onclick="toggle_visibility('details_div')">Details..</a>


           <div id="details_div" style="display:none; width:400px;">
           <b>Details <font size=-1>| <a href="javascript:void(0);" id="hide_button" onclick="toggle_visibility('details_div')" style="display:none">hide</a></font></b>


          <div style="display:block"; max-width:450px">
          <table class="dashboard" style="margin:10px">

            <!-- <tr>
             <td colspan="2">
              <div>
               <div style="background:{{task.container.color}}; height:24px; width:149px; float:left"></div>
               <div style="background:{{task.computing.color}}; height:24px; width:149px; float:left"></div>
              </div>
             </td>
            </tr>
             -->

           <!-- <tr>
            <td><b>Name</b></td>
            <td>{{ task.name }}</td>
           </tr> -->

           <!-- <tr>
            <td><b>UUID</b></td>
            <td>{{ task.uuid }}</td>
           </tr> -->

           <tr>
            <td><b>Short ID</b></td>
            <td>{{ task.short_uuid }}</td>
           </tr>

           <tr>
            <td><b>Status</b></td>
            <td>{{ task.status }}</td>
           </tr>

           <tr>
            <td><b>Created at</b></td>
            <td>{{ task.created }}</td>
           </tr>

           <tr>
            <td><b>Interface IP</b></td>
            <td>{{ task.interface_ip }}</td>
           </tr>

           <tr>
            <td><b>Interface port</b></td>
            <td>{{ task.interface_port }}</td>
           </tr>

           <tr>
            <td><b>Tunnel port</b></td>
            <td>{{ task.tcp_tunnel_port }}</td>
           </tr>

           {% if task.auth_token %}
           <tr>
            <td><b>Auth token</b></td>
            <td>{{ task.auth_token }}</td>
           </tr>
           {% endif %}

           {% if task.computing_options %}
           <tr>
            <td><b>Computing options</b></td>
            <td>{{ task.computing_options }}</td>
           </tr>
           {% endif %}


            <!-- <tr><td style="padding-right:0"><b>Direct link</b>
            <td>{% if task.status == "running" %}<a href="{{ task.sharable_link }}">{{ task.sharable_link }}</a>{% else %}N.A. (task not running) {% endif %}</td>
           </tr>-->




          </table>
          </div>

          <!-- <p style="margin-left:10px; font-size:0.9em; color:#484848">
          <i class="fa fa-info-circle" style="color:#337ab7"></i> You can share a direct link with other people, but remember that if you have no authentication in place anyone will be able to access.
          </p> -->
          </div>

          </center>


          {% endif  %}
+96 −0
Original line number Diff line number Diff line
<div style="width:350px; display:block; border: #e0e0e0 solid 1px; margin:10px; background:#f8f8f8; margin-bottom:20px">
  {% if data.task %}
  <div style="margin-top:5px; padding:10px; text-align:center; border-bottom: #f8f8f8 solid 1px; ">
    <b>{{data.task.name}}</b>
  </div>
  <hr style="margin:0">
  {% else %}
  <div style="margin-top:5px; padding:10px; text-align:center; border-bottom: #e0e0e0 solid 1px; ">
    <a href="?uuid={{ task.uuid }}"><b>{{ task.name }}</b></a>
  </div>
  {% endif %}
  <div style="padding:10px; padding-left:15px; padding-right:15px; text-align:left;">
    <b>Software:</b>
    <a href="/software/?container_uuid={{ task.container.uuid }}" style="color:{{task.container.color}}">{{ task.container.name }}</a>
    {% if task.container.type == 'docker' %}<img src="/static/img/docker-logo.svg" style="height:18px; width:18px; margin-bottom:4px" />{% endif %}
    {% if task.container.type == 'singularity' %}<img src="/static/img/singularity-logo.svg" style="height:18px; width:18px; margin-bottom:4px" />{% endif %}
    <br/>
    <b>Computing:</b> <a href="/computing/?uuid={{ task.computing.uuid }}">{{ task.computing.name }}</a>
    <div style="margin-top:2px">
      {% if task.status == "running" %}
      <b>Status:</b> <font color="green">running</font>
      {% if task.container.interface_protocol == 'http' or task.container.interface_protocol == 'https' %}
      {% else %}
      @ port {{ task.tcp_tunnel_port }}
      {% endif %}
      {% else %}
      <b>Status:</b> {{ task.status }}
      {% endif %}
    </div>
  </div>
  <div style="margin-bottom:10px; text-align:center; padding:5px">
    <!-- Stop / Delete / Cancel -->
    {% if task.status == "stopped" or task.status == "created" %}
    <a href="?uuid={{task.uuid}}&action=delete" class="btn btn-action">Delete</a>
    {% else %}
    <a href="?uuid={{task.uuid}}&action=stop&fromlist={{fromlist}}" class="btn btn-action">Stop</a>
    {% endif %}
    <!-- Connect -->
    {% if task.interface_port %}
    {% if task.container.interface_protocol == 'http' or task.container.interface_protocol == 'https' %}
    {% if task.status == "running" %}
    <a href="/task_connect/?uuid={{task.uuid}}" class="btn btn-connect">Connect</a>
    {% else %}
    <a href="" class="btn btn-disabled">Connect</a>
    {% endif %}
    {% endif %}
    {% endif %}
    <!-- View log -->
    {% if task.status == "running" %}
    <a href="/task_log/?uuid={{task.uuid}}&action=viewlog" class="btn btn-action">Logs</a>
    {% else %}
    <a href="" class="btn btn-disabled">Logs</a>
    {% endif %}
  </div>
</div>

{% if data.task %}
<div id="details_div" style="width:370px;">
  <div style="display:block"; max-width:450px">
    <table class="dashboard" style="margin:10px">
      <tr>
        <td><b>Created at</b></td>
        <td>{{ task.created }}</td>
      </tr>
      <tr>
        <td><b>Interface IP</b></td>
        <td>{{ task.interface_ip }}</td>
      </tr>
      <tr>
        <td><b>Interface port</b></td>
        <td>{{ task.interface_port }}</td>
      </tr>
      <tr>
        <td><b>Tunnel port</b></td>
        <td>{{ task.tcp_tunnel_port }}</td>
      </tr>
      {% if task.auth_token %}
      <tr>
        <td><b>Auth token</b></td>
        <td>{{ task.auth_token }}</td>
      </tr>
      {% endif %}
      {% if task.computing_options %}
      <tr>
        <td><b>Computing options</b></td>
        <td>{{ task.computing_options }}</td>
      </tr>
      {% endif %}
      <!-- <tr>
        <td style="padding-right:0"><b>Direct link</b></td>
        <td>{% if task.status == "running" %}<a href="{{ task.sharable_link }}">{{ task.sharable_link }}</a>{% else %}N.A. (task not running) {% endif %}</td>
      </tr> -->
    </table>
  </div>
</div>
{% endif  %}
+4 −4
Original line number Diff line number Diff line
@@ -6,7 +6,7 @@
<div class="container">
  <div class="dashboard">
    <div class="span8 offset2">
      <h1>New Task</h1>
      <h1><a href="/tasks">Tasks</a> <span style="font-size:18px"> / new</span></h1>
      <hr>


@@ -20,7 +20,7 @@

      {% if data.step != 'created' %}
      <div style="float:left; background:#ffffff; margin-left:10px; margin-right:10px; margin-top:0px; margin-bottom:20px">
          <h4>Software container</h4>
          <h4>Software <i class="fa fa-check-square" style="color:#23BE23"></i></h4>
          <div class="row" style="padding:5px">
          {% include "components/container_card.html" with container=data.task_container container_arch=data.task_container_arch disable_play_button=True  %}
          </div>
@@ -31,7 +31,7 @@
      {% if data.step == 'two' %}

      <div style="width:300px; float:left; background:#ffffff; margin-left:10px; margin-right:10px; margin-top:0px; margin-bottom:0px">
          <h4>Computing resource</h4>
          <h4>Choose Computing</h4>
          <div class="row" style="padding:5px">
          {% for computing in data.computings %}
          {% include "components/computing_card.html" with container=data.task_container container_arch=data.task_container_arch %}
@@ -44,7 +44,7 @@


      <div style="width:300px; float:left; background:#ffffff; margin-left:10px; margin-right:10px; margin-top:0px; margin-bottom:0px">
          <h4>Computing resource</h4>
          <h4>Computing <i class="fa fa-check-square" style="color:#23BE23"></i></h4>
          <div class="row" style="padding:5px">
          {% include "components/computing_card.html" with computing=data.task_computing %}
          </div>
+21 −23
Original line number Diff line number Diff line
@@ -6,44 +6,45 @@
<div class="container">
  <div class="dashboard">
    <div class="span8 offset2">

      {% if data.task %}
      <h1><a href="/tasks">Tasks</a> <span style="font-size:18px"> / {{ data.task.name }}</span></h1>
      {% else %}
      <h1>Tasks</h1>
      {% endif %}

      <hr>
      <div class="row" style="padding:5px">
      {% if data.task %}
      {% include "components/task.html" with task=data.task details=True %}
      {% include "components/task_card.html" with task=data.task details=True%}
      {% else %}
      {% for task in data.tasks %}
      {% include "components/task.html" with task=task %}
      <div class="form-filter" style="margin-bottom:20px">
        <form action="" method="POST">
          <input type="text" class="form-control" id="filter_text" name="filter_text" placeholder="Search..." style="width:200px; margin:0; display:inline" value="{{data.filter_text}}" autofocus>
          <select class="form-control" id="filter_status" name="filter_status" style="width:120px; margin:0; display:inline">
            <option value="all" {% if data.filter_status == 'all' %}selected{% endif %}>All</option>
            {% for status in data.task_statuses %}
            <option value="{{status}}" {% if data.filter_status == status %}selected{% endif %}>{{ status | title }}</option>
            {% endfor %}
      {% endif %}
          </select>
          {% csrf_token %}
          <button type="submit" class="btn btn-secondary">Go</button>
          &nbsp; &nbsp; <font size=4.0em>|</font> &nbsp; <a href="/new_task">Run new...</a>
        </form>
      </div>

      {% if not data.task %}
      <div class="row" style="padding:10px; padding-left:15px">
      <a href="/new_task">New task...</a>
      <div class="row" style="padding:5px">
        {% for task in data.tasks %}
        {% include "components/task_card.html" with task=task fromlist=True %}
        {% empty %}
        <p>No tasks found.</p>
        {% endfor %}
      </div>
      {% endif %}

      <br/>
      <br/>
      <br/>
      <br/>
      <br/>
      <br/>

      </div>
    </div>
  </div>
</div>

{% include "footer.html" %}


<script>
function toggle_visibility(id) {
      var x = document.getElementById(id);
@@ -61,6 +62,3 @@ function toggle_visibility(id) {
      }
    }
</script>


+78 −85
Original line number Diff line number Diff line
@@ -485,33 +485,48 @@ def account(request):
@private_view
def tasks(request):

    # Init data
    # Get data
    action  = request.GET.get('action', None)
    uuid    = request.GET.get('uuid', None)
    filter_text = request.POST.get('filter_text', '')
    filter_status = request.POST.get('filter_status', 'all')
    fromlist = booleanize(request.GET.get('fromlist', False))

    # Set data
    data={}
    data['user']  = request.user
    data['profile'] = Profile.objects.get(user=request.user)
    data['title'] = 'Tasks'

    # Get action if any
    action  = request.GET.get('action', None)
    uuid    = request.GET.get('uuid', None)
    fromlist = request.GET.get('fromlist', False)
    details = booleanize(request.GET.get('details', None))
    data['filter_text'] = filter_text
    data['filter_status'] = filter_status
    task_statuses = []
    for var in vars(TaskStatuses):
        if var.startswith('_'):
            continue
        task_statuses.append(var)
    data['task_statuses'] = sorted(task_statuses)

    # Get the task if a specific uuid is given, or get them all, possibly filtering
    if uuid:
        task = Task.objects.get(user=request.user, uuid=uuid)
        data['task'] = task

    else:
        tasks = Task.objects.filter(user=request.user).order_by('created')

    # Do we have to operate on a specific task?
    if uuid:
        if filter_status and filter_status != 'all':
            tasks = tasks.filter(status=filter_status)

        try:
        if filter_text:
            tasks = tasks.filter(name__icontains=filter_text)

            # Get the task (raises if none available including no permission)
            try:
                task = Task.objects.get(user=request.user, uuid=uuid)
            except Task.DoesNotExist:
                raise ErrorMessage('Task does not exists or no access rights')
        # Update task statuses
        for task in tasks:
            task.update_status()

            data['task'] = task
        # Set task and tasks variables
        data['tasks'] = tasks

            #  Task actions
    # Handle delete action
    if action=='delete':
        if task.status not in [TaskStatuses.stopped, TaskStatuses.exited]:
            try:
@@ -542,10 +557,12 @@ def tasks(request):
            data['error'] = 'Error in deleting the task'
            logger.error('Error in deleting task with uuid="{}": "{}"'.format(uuid, e))
            return render(request, 'error.html', {'data': data})
        return redirect('/tasks/')



            elif action=='stop': # or delete,a and if delete also remove object
    # Handle stop action
    elif action=='stop':
        try:
            # Remove proxy files. Do it here or will cause issues when reloading the conf re-using ports of stopped tasks.
            try:
                os.remove('/shared/etc_apache2_sites_enabled/{}.conf'.format(task.uuid))
@@ -562,38 +579,14 @@ def tasks(request):
            data['error'] = 'Error in getting the task or performing the required action'
            logger.error('Error in getting the task with uuid="{}" or performing the required action: "{}"'.format(uuid, e))
            return render(request, 'error.html', {'data': data})
        return redirect('/tasks/?uuid={}'.format(task.uuid))

        # Ok, redirect if there was an action
        if action:
        # Redirect
        if fromlist:
            return redirect('/tasks')
            else:
                if not task.uuid:
                    # it has just been deleted
                    return redirect('/tasks')
        else:
            return redirect('/tasks/?uuid={}'.format(task.uuid))


    # Do we have to list all the tasks?
    if not uuid or (uuid and not details):

        # Get all tasks for list
        try:
            tasks = Task.objects.filter(user=request.user).order_by('created')
        except Exception as e:
            data['error'] = 'Error in getting Tasks info'
            logger.error('Error in getting Virtual Devices: "{}"'.format(e))
            return render(request, 'error.html', {'data': data})

        # Update task statuses
        for task in tasks:
            task.update_status()

        # Set task and tasks variables
        data['task']  = None
        data['tasks'] = tasks

    return render(request, 'tasks.html', {'data': data})