| Index: appengine/swarming/templates/user_tasks.html
|
| diff --git a/appengine/swarming/templates/user_tasks.html b/appengine/swarming/templates/user_tasks.html
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..249e29eca2713b51e6031ab93bb499b7f0ebf4bc
|
| --- /dev/null
|
| +++ b/appengine/swarming/templates/user_tasks.html
|
| @@ -0,0 +1,375 @@
|
| +{% extends "swarming/base.html" %}
|
| +
|
| +
|
| +{% block headers %}
|
| +<style>
|
| + h1 {
|
| + margin-top: 10px;
|
| + margin-bottom: 10px;
|
| + }
|
| +
|
| + table.layout_table {
|
| + border-spacing: 0;
|
| + font-family: monospace;
|
| + }
|
| +
|
| + table.layout_table thead {
|
| + background-color: #C0C0C0;
|
| + font-weight:bold;
|
| + }
|
| +
|
| + table.layout_table tbody tr:nth-child(even) {
|
| + background-color: #eeeeee;
|
| + }
|
| +
|
| + table.layout_table td:first-child {
|
| + border-color: black;
|
| + border-right: thin solid;
|
| + padding-right: 1em;
|
| + }
|
| +
|
| + table.layout_table td:nth-child(2) {
|
| + padding-left: 1em;
|
| + }
|
| +
|
| + table.layout_table td:nth-child(4) {
|
| + border-color: black;
|
| + border-right: thin solid;
|
| + padding-right: 1em;
|
| + }
|
| +
|
| + table.layout_table td:nth-child(5) {
|
| + border-color: black;
|
| + border-right: thin solid;
|
| + padding-left: 1em;
|
| + padding-right: 1em;
|
| + }
|
| +
|
| + table.layout_table td:nth-child(6) {
|
| + padding-left: 1em;
|
| + padding-right: 0.5em;
|
| + }
|
| +
|
| + table.alterning_background td:nth-child(3) {
|
| + text-align: center;
|
| + white-space: nowrap;
|
| + }
|
| +
|
| + table.alterning_background td:nth-child(4) {
|
| + text-align: right;
|
| + white-space: nowrap;
|
| + }
|
| +
|
| + table.alterning_background td:nth-child(5) {
|
| + text-align: right;
|
| + white-space: nowrap;
|
| + }
|
| +
|
| + table.alterning_background td:nth-child(6) {
|
| + white-space: nowrap;
|
| + }
|
| +
|
| + table.alterning_background td:nth-child(7) {
|
| + text-align: right;
|
| + white-space: nowrap;
|
| + }
|
| +
|
| + #limitRange {
|
| + width: inherit;
|
| + }
|
| +</style>
|
| +<script>
|
| + function radio_value(field) {
|
| + var radios = document.getElementsByName(field);
|
| + for (var i = 0, length = radios.length; i < length; i++) {
|
| + if (radios[i].checked) {
|
| + return radios[i].value;
|
| + }
|
| + }
|
| + }
|
| +
|
| + function get_limit() {
|
| + return document.getElementById('limitText').value;
|
| + }
|
| +
|
| + function update_limit_text(val) {
|
| + document.getElementById('limitText').value = val;
|
| + }
|
| +
|
| + function update_limit_range(val) {
|
| + document.getElementById('limitRange').value = val;
|
| + }
|
| +
|
| + function update_sort() {
|
| + // This resets the cursor and filters.
|
| + var sort = radio_value("sort");
|
| + var url = '/user/tasks?sort=' + sort + '&limit=' + get_limit();
|
| + document.location.href = url;
|
| + }
|
| +
|
| + function update_filter() {
|
| + // This resets the cursor, sort and task name.
|
| + var task_tag = document.getElementById("task_tag").value;
|
| + var url = '/user/tasks?state=' + encodeURIComponent(radio_value("state")) +
|
| + '&limit=' + encodeURIComponent(get_limit()) +
|
| + '&task_tag=' + encodeURIComponent(task_tag);
|
| + document.location.href = url;
|
| + }
|
| +</script>
|
| +{% endblock %}
|
| +
|
| +
|
| +{% block body %}
|
| +{% import 'swarming/bot_view.html' as bot_view %}
|
| +
|
| +<h1>Tasks</h1>
|
| +<a href="/">Back to root</a>
|
| +<br/>
|
| +<h1>THIS UI WILL GO AWAY ON JAN 1, 2017. If it has something you need and the new UI doesn't have it, file a bug ASAP. </h1>
|
| +<a href="{{try_link}}">Try out the new task list UI</a>
|
| +<p>
|
| +<form id="filter" name="filter" method="GET">
|
| +<input type="range" id="limitRange" name="limit" value="{{limit}}" min=10
|
| + max=500 step=5 onchange="update_limit_text(this.value);"
|
| + onmousemove="update_limit_text(this.value);" >
|
| +<input type="text" id="limitText" value="{{limit}}" maxlength="3"
|
| + onchange="update_limit_range(this.value);">
|
| +<input type="submit" value="Set limit">
|
| +<p>
|
| +<table class=layout_table title="Select order and filter">
|
| + <thead>
|
| + <tr>
|
| + <td align=center>Sort</td>
|
| + <td></td>
|
| + <td>State (total last 24h)</td>
|
| + <td></td>
|
| + <td>Search by tag</td>
|
| + </tr>
|
| + </thead>
|
| + <tbody>
|
| + <tr>
|
| + <td>
|
| + {% for key, name, item_title in sort_choices %}
|
| + <label title="{{item_title}}">
|
| + <input type="radio" name="sort" value="{{key}}"
|
| + onchange="update_sort()"
|
| + {% if sort == key %}checked{%endif%}>
|
| + {{name}}
|
| + </input>
|
| + </label>
|
| + <br>
|
| + {% endfor %}
|
| + </td>
|
| + {% for state_column in state_choices %}
|
| + <td>
|
| + {% for key, name, item_title in state_column %}
|
| + <label title="{{item_title}}">
|
| + <input type="radio" name="state" value="{{key}}"
|
| + onchange="update_filter()"
|
| + {% if state == key %}checked{%endif%}>
|
| + {{name}}
|
| + </input>
|
| + </label>
|
| + <br>
|
| + {% endfor %}
|
| + </td>
|
| + {% endfor %}
|
| + <td>
|
| + <div title="Task tags uses whole tag search ONLY. Using it resets sort to 'Created' and the task state filter to 'All'.">
|
| + Task tags<br>
|
| + (whole tag only, 1 per line)
|
| + <br>
|
| + <textarea id="task_tag" name="task_tag" rows="3" cols="30">{{task_tag}}</textarea>
|
| + <br>
|
| + <input type="submit" value="Search">
|
| + </div>
|
| + </td>
|
| + </tr>
|
| + <tbody>
|
| +</table>
|
| +</form>
|
| +<br>
|
| +
|
| +
|
| +{% macro total_pending_star() %}
|
| + {% if has_pending %}*{% endif %}
|
| +{% endmacro %}
|
| +
|
| +
|
| +{% macro total_running_star() %}
|
| + {% if has_running %}*{% endif %}
|
| +{% endmacro %}
|
| +
|
| +
|
| +{% macro next_page_link() %}
|
| +{% if cursor %}
|
| +<p>
|
| +{% if task_tag %}
|
| + <a href="/oldui/user/tasks?limit={{limit}}&state={{state}}&task_tag={{task_tag|urlencode}}&cursor={{cursor|urlencode}}">Next page</a>
|
| +{% else %}
|
| + <a href="/oldui/user/tasks?limit={{limit}}&state={{state}}&sort={{sort}}&cursor={{cursor|urlencode}}">Next page</a>
|
| +{% endif %}
|
| +{% endif %}
|
| +{% endmacro %}
|
| +
|
| +
|
| +{% if tasks %}
|
| + <table id="request-table" class="alterning_background"
|
| + summary="This table lists all test requests">
|
| + <thead>
|
| + <th>Name</th>
|
| + <th>Status</th>
|
| + <th>Requested</th>
|
| + <th>Pending</th>
|
| + <th>Duration</th>
|
| + <th>$USD</th>
|
| + <th>User</th>
|
| + <th>Bot</th>
|
| + <th>Priority</th>
|
| + </thead>
|
| + <tbody>
|
| + {% for task in tasks %}
|
| + <tr class="request {% if task.failure or task.internal_failure or task.is_exceptional %}failed_test{% endif%}">
|
| + <td>
|
| + <a href="/oldui/user/task/{{task.task_id}}">{{task.name}}</a>
|
| + </td>
|
| + <td>
|
| + {{task.to_string()|safe}}
|
| + {% if task.request.has_access and task.can_be_canceled %}
|
| + <form id="cancel_{{task.task_id}}" method="POST"
|
| + action="/oldui/user/task/{{task.task_id}}/cancel"
|
| + style="display:inline">
|
| + <input type="hidden" name="redirect_to" value="listing" />
|
| + <input type="hidden" name="xsrf_token" value="{{xsrf_token}}" />
|
| + <input type="submit" value="Cancel" style="display:inline"></input>
|
| + </form>
|
| + {% endif %}
|
| + </td>
|
| + <td>{{task.created_ts|succinctdatetimeformat}}</td>
|
| + <td>
|
| + {{bot_view.pending_star(task)}}{{task.pending_now(now)|timedeltaformat}}
|
| + </td>
|
| + <td>
|
| + {{bot_view.running_star(task)}}
|
| + {% if task.deduped_from %}
|
| + <span title="Duration of the original task. This task wasn't actually run as it was deduped."
|
| + style="color:green">
|
| + {{task.duration_now(now)|timedeltaformat}}
|
| + </span>
|
| + {% else %}
|
| + {{task.duration_now(now)|timedeltaformat}}
|
| + {% endif %}
|
| + </td>
|
| + <td>
|
| + {% if task.cost_usd %}
|
| + {{task.cost_usd|round(4) }} $
|
| + {% elif task.cost_saved_usd %}
|
| + <span style="color:green">-{{task.cost_saved_usd|round(4) }} $</span>
|
| + {% else %}
|
| + ‑‑
|
| + {% endif %}
|
| + </td>
|
| + <td>
|
| + {% if task.user %}
|
| + <a href="/oldui/user/tasks?task_tag=user:{{task.user}}&limit={{limit}}">{{task.user}}</a>
|
| + {% else %}
|
| + ‑‑
|
| + {% endif %}
|
| + </td>
|
| + <td>{{bot_view.bot_link(task.bot_id, is_privileged_user)}}</td>
|
| + <td>{{task.request.priority}}</td>
|
| + </tr>
|
| + {% endfor %}
|
| + {% if show_footer %}
|
| + <tr>
|
| + <td> </td>
|
| + <td></td>
|
| + <td></td>
|
| + <td></td>
|
| + <td></td>
|
| + <td></td>
|
| + <td></td>
|
| + <td></td>
|
| + </tr>
|
| + {% endif %}
|
| + </tbody>
|
| + {% if show_footer %}
|
| + <tfoot>
|
| + <tr>
|
| + <td>{{ next_page_link() }}</td>
|
| + <td></td>
|
| + <td><strong>Median</strong></td>
|
| + <td>
|
| + {{total_pending_star()}}{{pending_median|timedeltaformat}}
|
| + </td>
|
| + <td>
|
| + {{total_running_star()}}{{duration_median|timedeltaformat}}
|
| + </td>
|
| + <td></td>
|
| + <td></td>
|
| + </tr>
|
| + <tr>
|
| + <td></td>
|
| + <td><strong>Total: </strong>{{tasks|length}}</td>
|
| + <td><strong>Average</strong></td>
|
| + <td>
|
| + {{total_pending_star()}}{{pending_average|timedeltaformat}}
|
| + </td>
|
| + <td>
|
| + {{total_running_star()}}{{duration_average|timedeltaformat}}
|
| + </td>
|
| + <td></td>
|
| + <td></td>
|
| + <td></td>
|
| + </tr>
|
| + <tr>
|
| + <td></td>
|
| + <td></td>
|
| + <td><strong>Sum</strong></td>
|
| + <td>
|
| + {{total_pending_star()}}{{pending_sum|timedeltaformat}}
|
| + </td>
|
| + <td>
|
| + {{total_running_star()}}{{duration_sum|timedeltaformat}}
|
| + </td>
|
| + <td>
|
| + {% if total_cost_usd %}
|
| + {{total_cost_usd|round(4) }} $
|
| + {% else %}
|
| + ‑‑
|
| + {% endif %}
|
| + </td>
|
| + <td></td>
|
| + <td></td>
|
| + </tr>
|
| + <tr>
|
| + <td></td>
|
| + <td></td>
|
| + <td><strong>Saved by deduping</strong></td>
|
| + <td></td>
|
| + <td>
|
| + {{total_saved|timedeltaformat}}
|
| + </td>
|
| + <td>
|
| + {% if total_cost_saved_usd %}
|
| + <span style="color:green">{{total_cost_saved_usd|round(4) }} $</span>
|
| + {% else %}
|
| + ‑‑
|
| + {% endif %}
|
| + </td>
|
| + <td>
|
| + ({{'%1.1f' % total_saved_percent}}%)
|
| + </td>
|
| + <td></td>
|
| + <td></td>
|
| + </tr>
|
| + </tfoot>
|
| + {% else %}
|
| + {{ next_page_link() }}
|
| + {% endif %}
|
| + </table>
|
| +{% else %}
|
| + No data to show for this selection.
|
| +{% endif %}
|
| +
|
| +{% endblock %}
|
|
|