blob: 83a8ad6dc98ec0348f77e72f35eb3389379635fc [file] [log] [blame]
<!--
This in an HTML Import-able file that contains the definition
of the following elements:
<task-scheduler-blacklist-sk>
Status information about the task scheduler.
To use this file import it:
<link href="/res/imp/task-scheduler-blacklist-sk.html" rel="import" />
Usage:
<task-scheduler-blacklist-sk></task-scheduler-blacklist-sk>
Properties:
// input
rules: Array of Objects indicating the current set of blacklist rules:
added_by: String, Who added the rule.
task_spec_patterns: Array, regular expressions which match task_spec names.
commits: Array, commit hashes
description: String, detailed information about the rule.
name: String, name of the rule.
Methods:
None.
Events:
None.
-->
<link rel="import" href="/res/imp/bower_components/iron-flex-layout/iron-flex-layout-classes.html">
<link rel="import" href="/res/imp/bower_components/iron-icons/iron-icons.html">
<link rel="import" href="/res/imp/bower_components/paper-button/paper-button.html">
<link rel="import" href="/res/imp/bower_components/paper-checkbox/paper-checkbox.html">
<link rel="import" href="/res/imp/bower_components/paper-dialog/paper-dialog.html">
<link rel="import" href="/res/imp/bower_components/paper-fab/paper-fab.html">
<link rel="import" href="/res/imp/bower_components/paper-icon-button/paper-icon-button.html">
<link rel="import" href="/res/imp/bower_components/paper-input/paper-input.html">
<link rel="import" href="/res/imp/bower_components/paper-input/paper-textarea.html">
<link rel="import" href="/res/imp/bower_components/paper-spinner/paper-spinner.html">
<link rel="import" href="/res/common/imp/autocomplete-input-sk.html">
<link rel="import" href="/res/common/imp/human-date-sk.html">
<link rel="import" href="/res/common/imp/input-list-sk.html">
<dom-module id="task-scheduler-blacklist-sk">
<template>
<style include="iron-flex iron-flex-alignment">
:host {
font-family: sans-serif;
}
.task_spec_pattern, .commit {
font-family: "Lucida Console", Monaco, monospace;
}
.container {
margin: 5px;
padding: 10px;
border: 1px solid #eeeeee;
font-size: 12px;
}
.container h2 {
font-size: 16px;
}
#add_button {
padding: 0.7em 0.57em;
margin-top: 10px;
}
#input_pane {
width: 400px;
}
#range_checkbox {
margin-top: 18px;
}
paper-fab {
background-color: #d23f31;
margin: 25px;
position: fixed;
bottom: 20px;
right: 20px;
}
.table {
border-collapse: collapse;
display: table;
}
.tr {
border-bottom: 1px solid #EEEEEE;
display: table-row;
}
.tr:hover {
background-color: #F5F5F5;
}
.tr:hover .tr:hover {
background-color: #FFFFFF;
}
.td,.th {
display: table-cell;
padding: 10px;
}
.td {
color: #212121;
font-size: 0.813em;
vertical-align: middle;
}
.th {
color: #767676;
font-size: 0.75em;
}
</style>
<div class="table" hidden$="{{_loading}}">
<div class="tr">
<div class="th"><!-- delete button--></div>
<div class="th">Name</div>
<div class="th">Added by</div>
<div class="th">TaskSpec Patterns</div>
<div class="th">Commits</div>
<div class="th">Description</div>
</div>
<template is="dom-repeat" items="{{rules}}">
<div class="tr">
<div class="td">
<paper-icon-button icon="delete" on-click="_remove_rule" value="{{item.name}}"></paper-icon-button>
</div>
<div class="td">{{item.name}}</div>
<div class="td">{{item.added_by}}</div>
<div class="td">
<template is="dom-repeat" items="{{item.task_spec_patterns}}">
<div class="task_spec_pattern">{{item}}</div>
</template>
</div>
<div class="td">
<template is="dom-repeat" items="{{item.commits}}">
<div class="commit">{{item}}</div>
</template>
</div>
<div class="td">{{item.description}}</div>
</div>
</template>
</div>
<paper-spinner active$="{{_loading}}"></paper-spinner>
<paper-fab icon="add" on-click="_add_rule_popup"></paper-fab>
<paper-dialog id="add_dialog">
<h2>Add a blacklist rule</h2>
<div class="layout horizontal">
<div id="input_pane">
<paper-input label="name" value="{{_input_name}}"></paper-input>
<input-list-sk
heading="task_spec patterns"
values="{{_input_task_spec_patterns}}"
on-keyup="_task_specs_keyup"
></input-list-sk>
<div class="container">
<h2>commit(s)</h2>
<autocomplete-input-sk
autocomplete="[[commits]]"
label="single commit or range start (oldest; inclusive)"
value="{{_input_commit}}"
accept-custom-value="true"
></autocomplete-input-sk>
<paper-checkbox checked="{{_input_commit_is_range}}" id="range_checkbox">
commit range?
</paper-checkbox>
<autocomplete-input-sk
autocomplete="[[commits]]"
hidden$="{{!_input_commit_is_range}}"
label="commit range end (newest; non-inclusive)"
value="{{_input_commit_range_end}}"
accept-custom-value="true"
></autocomplete-input-sk>
</div>
<paper-textarea label="description" value="{{_input_description}}" rows="5"></paper-textarea>
<paper-button on-click="_add_rule" id="add_button" raised>Add Rule</paper-button>
</div>
<div class="container">
<h2>Current pattern matches these specs:</h2>
<template is="dom-repeat" items="{{_matched_task_specs}}">
<div>{{item}}</div>
</template>
</div>
</div>
</paper-dialog>
</template>
<script>
(function(){
Polymer({
is: "task-scheduler-blacklist-sk",
properties: {
task_specs: {
type: Array,
value: function() {
return [];
},
},
commits: {
type: Array,
value: function() {
return [];
},
},
rules: {
type: Array,
},
_input_task_spec_patterns: {
type: Array,
value: function() {
return [];
},
},
_input_commit: {
type: String,
value: "",
},
_input_commit_is_range: {
type: Boolean,
value: false,
},
_input_commit_range_end: {
type: String,
value: "",
},
_input_description: {
type: String,
value: "",
},
_input_name: {
type: String,
value: "",
},
_loading: {
type: Boolean,
value: false,
},
_matched_task_specs: {
type: Array,
value: function() {
return [];
},
},
},
_add_rule() {
// Validate the form inputs.
if (this._input_name == "") {
sk.errorMessage("Rules must have a name.");
return;
} else if (this._input_name.length > 50) {
sk.errorMessage("Rule names are 50 characters maximum. Use the 'description' field for detailed information.")
return;
}
// Submit the new rule to the server.
var data = {
"task_spec_patterns": this._input_task_spec_patterns,
"commits": [],
"description": this._input_description,
"name": this._input_name,
};
if (this._input_commit) {
data["commits"].push(this._input_commit.trim());
}
if (this._input_commit_is_range) {
data["commits"].push(this._input_commit_range_end.trim());
}
if (this._input_task_spec_patterns.length == 0 && data["commits"].length == 0) {
sk.errorMessage("Rules must have at least one task_spec pattern and/or commit.")
return;
}
var str = JSON.stringify(data);
this._loading = true;
this.$.add_dialog.close();
sk.post("/json/blacklist", str).then(function(resp) {
this._loading = false;
var rules;
try {
rules = JSON.parse(resp).rules;
} catch(e) {
sk.errorMessage("Got invalid response from the server: " + e);
return;
}
this.rules = [];
for (var key in rules) {
this.push("rules", rules[key]);
}
this._input_task_spec_patterns = [];
this._input_commit = "";
this._input_commit_is_range = false;
this._input_commit_range_end = "";
this._input_description = "";
this._input_name = "";
}.bind(this), function(err) {
this._loading = false;
this.$.add_dialog.open();
sk.errorMessage(err);
}.bind(this));
},
_add_rule_popup() {
this.$.add_dialog.open();
},
_task_specs_keyup(e) {
var pattern = e.target.value;
this._matched_task_specs = [];
if (!pattern || pattern == "") {
return;
}
for (var i = 0; i < this.task_specs.length; ++i) {
if (this.task_specs[i].match(pattern)) {
this.push("_matched_task_specs", this.task_specs[i]);
}
}
},
_remove_rule(e) {
var data = {
"id": e.model.item.id,
};
var str = JSON.stringify(data);
this._loading = true;
sk.delete("/json/blacklist", str).then(function(resp) {
this._loading = false;
var rules;
try {
rules = JSON.parse(resp).rules;
} catch(e) {
sk.errorMessage("Got invalid response from the server: " + e);
return;
}
this.rules = [];
for (var key in rules) {
this.push("rules", rules[key]);
}
}.bind(this), function(err) {
this._loading = false;
sk.errorMessage(err);
}.bind(this));
},
});
})();
</script>
</dom-module>