blob: 5eac79051ab4d3a538c89be3558006e9756d1bd7 [file] [log] [blame]
<!--
The <pending-tasks-sk> custom element declaration. Displays a table of tasks that are not yet
completed, including popups with detailed information.
Attributes:
None.
Events:
None.
Methods:
None.
-->
<dom-module id="pending-tasks-sk">
<style>
paper-dialog {
min-width: 200px;
max-width: calc(100% - 10px);
}
table.queue {
border-spacing: 0px;
padding-top: 2em;
}
tr.headers {
background-color: #CCCCFF;
text-align: center;
}
td.nowrap {
white-space: nowrap;
}
th,
td {
padding: 15px;
border: solid black 1px;
}
.delete-button {
--paper-icon-button-disabled: {
display: none;
}
}
</style>
<template>
<confirm-dialog-sk id="confirm_dialog"></confirm-dialog-sk>
<h2>Tasks in the Queue</h2>
<!-- Section for popups. -->
<template is="dom-repeat" items="{{pendingTasks}}" as="pendingTask" index-as="index">
<paper-dialog heading="Task Details" id="{{ getTaskDetailsId(index) }}">
<paper-dialog-scrollable>
<pre>{{ formatTask(pendingTask) }}</pre>
</paper-dialog-scrollable>
</paper-dialog>
</template>
<table class="queue" id="queue">
<tr class="headers">
<td>Queue Position</td>
<td>Added</td>
<td>Task Type</td>
<td>User</td>
<td>Swarming Logs</td>
<td>Request</td>
</tr>
<template is="dom-repeat" items="{{pendingTasks}}" as="pendingTask" index-as="index">
<tr>
<!-- Queue Position col -->
<td class="nowrap">
<span>{{ incrementOne(index) }}</span>
<paper-icon-button icon="delete" mini
class="delete-button"
disabled="{{!pendingTask.canDelete}}"
alt="Delete"
data-index$="{{index}}"
data-type="delete">
</paper-icon-button>
</td>
<!-- Added col -->
<td>{{ formatTimestamp(pendingTask.TsAdded) }}
<template is="dom-if" if="{{ pendingTask.FutureDate }}">
<br/>
<div style="color:red;">(scheduled in the future)</div>
</template>
</td>
<!-- Task Type col -->
<td>{{pendingTask.TaskType}}</td>
<!-- User col -->
<td>{{pendingTask.Username}}</td>
<!-- Swarming logs col -->
<td class="nowrap">
<template is="dom-if" if="{{ pendingTask.FutureDate }}">
N/A
</template>
<template is="dom-if" if="{{ !pendingTask.FutureDate }}">
<template is="dom-if" if="{{ pendingTask.SwarmingLogs }}">
<a href="{{ pendingTask.SwarmingLogs }}" target="_blank">Swarming Logs</a>
</template>
</template>
</td>
<!-- Request col -->
<td class="nowrap">
<a href="javascript:void(0);" data-id$="{{index}}">Task Details</a>
</td>
</tr>
</template>
</table>
</template>
</dom-module>
<script>
Polymer({
is: "pending-tasks-sk",
properties: {
pendingTasks: {
type: Array,
value: [],
},
taskDescriptors: {
type: Array,
value: function() {
return [{type: "ChromiumPerf",
get_url: "/_/get_chromium_perf_tasks",
delete_url: "/_/delete_chromium_perf_task"},
{type: "ChromiumAnalysis",
get_url: "/_/get_chromium_analysis_tasks",
delete_url: "/_/delete_chromium_analysis_task"},
{type: "MetricsAnalysis",
get_url: "/_/get_metrics_analysis_tasks",
delete_url: "/_/delete_metrics_analysis_task"},
{type: "CaptureSkps",
get_url: "/_/get_capture_skp_tasks",
delete_url: "/_/delete_capture_skps_task"},
{type: "LuaScript",
get_url: "/_/get_lua_script_tasks",
delete_url: "/_/delete_lua_script_task"},
{type: "ChromiumBuild",
get_url: "/_/get_chromium_build_tasks",
delete_url: "/_/delete_chromium_build_task"},
{type: "RecreatePageSets",
get_url: "/_/get_recreate_page_sets_tasks",
delete_url: "/_/delete_recreate_page_sets_task"},
{type: "RecreateWebpageArchives",
get_url: "/_/get_recreate_webpage_archives_tasks",
delete_url: "/_/delete_recreate_webpage_archives_task"},
];
}
},
},
ready: function() {
this.reload();
this.$.queue.addEventListener('click', function(e) {
var anchor = sk.findParent(e.target, "A");
if (anchor != null) {
var index = anchor.dataset.id;
this.toggleDialog(this.getTaskDetailsId(index));
}
}.bind(this));
this.$.queue.addEventListener('click', function(e) {
var button = sk.findParent(e.target, "PAPER-ICON-BUTTON");
if (button != null && button.dataset.type == "delete") {
var index = button.dataset.index;
this.$.confirm_dialog.open("Proceed with deleting task?")
.then(this.deleteTask.bind(this, index));
}
}.bind(this));
},
reload: function() {
this.pendingTasks = []
var queryParams = {
"size": 100,
"not_completed": true,
}
var queryStr = "?" + sk.query.fromObject(queryParams);
this.taskDescriptors.forEach(function(obj) {
sk.post(obj.get_url + queryStr).then(JSON.parse).then(function(json) {
this.updatePendingTasks(json, obj);
}.bind(this)).catch(sk.errorMessage);
}.bind(this));
// Find all tasks scheduled in the future.
var queryParams = {"include_future_runs": true,}
var queryStr = "?" + sk.query.fromObject(queryParams);
this.taskDescriptors.forEach(function(obj) {
sk.post(obj.get_url + queryStr).then(JSON.parse).then(function(json) {
this.updatePendingTasks(json, obj);
}.bind(this)).catch(sk.errorMessage);
}.bind(this));
},
incrementOne: function(index) {
return index + 1;
},
getTaskDetailsId: function(index) {
return "task_details" + index;
},
formatTask: function(task) {
return JSON.stringify(task, null, 4);
},
updatePendingTasks: function(json, taskDescriptor) {
var tasks = json.data
for (index in tasks) {
var task = tasks[index];
task["canDelete"] = json.permissions[index].DeleteAllowed;
task["Id"] = json.ids[index];
task["TaskType"] = taskDescriptor.type;
task["GetURL"] = taskDescriptor.get_url;
task["DeleteURL"] = taskDescriptor.delete_url;
// Check if this is a completed task set to repeat.
if (task["RepeatAfterDays"] != 0 && task["TaskDone"]) {
// Calculate the future date.
var timestamp = ctfe.getTimestamp(task["TsAdded"]);
timestamp.setDate(timestamp.getDate() + task["RepeatAfterDays"]);
task["FutureDate"] = true;
task["TsAdded"] = ctfe.getCtDbTimestamp(new Date(timestamp));
}
}
this.pendingTasks = this.pendingTasks.concat(tasks)
// Sort pending tasks according to TsAdded.
this.pendingTasks.sort(function(a, b){return a["TsAdded"] - b["TsAdded"]});
},
deleteTask: function(deleteIndex) {
var pendingTask = this.pendingTasks[deleteIndex];
var params = {};
params["id"] = pendingTask.Id;
sk.post(pendingTask.DeleteURL, JSON.stringify(params)).then(function() {
$$$("#confirm_toast").text = "Deleted " + pendingTask.TaskType + " task " + pendingTask.Id;
$$$("#confirm_toast").show();
}.bind(this)).catch(sk.errorMessage).then(function() {
this.reload();
}.bind(this));
},
toggleDialog: function(id) {
Polymer.dom(this.root).querySelector('#' + id).toggle();
},
formatTimestamp: ctfe.getFormattedTimestamp,
});
</script>