| <!-- |
| 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: "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> |