Commit 946cc626 authored by Matthieu Muffato's avatar Matthieu Muffato
Browse files

Many updates to the pipeline-parameters tab

* Full refresh only for deletion / addition
* Each edition input-field can be restored and validated independently
* Using more of bootstrap
parent 7c508636
......@@ -333,7 +333,7 @@ function onSuccess_dbConnect(res) {
fetch_resources();
// And the pipeline-wide parameters
fetch_and_setup_change_listener( "scripts/db_fetch_pipeline_params.pl", "scripts/db_update_nonobject.pl", "#pipeline_wide_parameters" );
fetch_and_setup_change_listener( "scripts/db_fetch_pipeline_params.pl", "scripts/db_update_nonobject.pl", "#pipeline_wide_parameters" );
// We load the jobs form
$.get('./scripts/db_jobs_form.pl', {url : guiHive.pipeline_url, version : guiHive.version} ,function(data) {
......@@ -413,37 +413,132 @@ function fetch_and_setup_change_listener(fetch_url, write_url, target_div) {
});
}
function get_url_data(ref_object) {
console.log(ref_object);
var url_data = "url="+ guiHive.pipeline_url +
"&method="+$(ref_object).attr("data-method") +
"&version="+guiHive.version;
function add_links(name, f) {
if ($(ref_object).attr(name)) {
var blocks = $(ref_object).attr(name).split(",");
var vals = jQuery.map(blocks, function(e,i) {
var parts = e.split("=");
console.log(parts);
console.log($('#'+parts[1]));
return parts[0] + "=" + f($('#'+parts[1])[0]);
});
return "&" + vals.join("&");
} else {
return "";
}
};
url_data = url_data + add_links('data-linkTo', function(o) {return o.value});
url_data = url_data + add_links('data-linkToDef', function(o) {return o.defaultValue});
return url_data
};
function onFetchSuccess_handler(resp) {
if (resp.status != "ok") {
log(resp);
} else {
var d = $(target_div);
d.html(resp.out_msg);
d.find(".ajaxable_btn").click( onClick_handler );
d.find(".monitored_input").keyup( onChange_handler );
d.find(".input_restorer").click( onRestoreRequest_handler );
return;
}
};
function onChange_handler(evt) {
var curr_val = this.value;
var ref_val = this.dataset.value;
var target_container = $('#' + this.id + "_monitor");
var targets = target_container.find(".btn");
if (curr_val === ref_val) {
targets.addClass("disabled");
} else {
targets.removeClass("disabled");
}
};
var d = $(target_div);
d.html(resp.out_msg);
d.find(".monitored_input").map( function(i, obj) {
var target_container = $(obj);
target_container.addClass("control-group");
target_container.addClass("input-append");
var monitored_input = target_container.find("input")[0];
var input_sender = $('<a class="btn btn-mini add-on"><i class="icon-ok-sign"></i></a>');
target_container.append(input_sender);
var input_restorer = $('<a class="btn btn-mini add-on"><i class="icon-remove-sign"></i></a>');
target_container.append(input_restorer);
var targets = target_container.find(".btn");
targets.hide();
$(monitored_input).keyup( function(evt) {
var is_change = (monitored_input.value !== monitored_input.defaultValue);
var is_valid_input = !target_container.hasClass("onlyalpha") || (monitored_input.value.match(/^[0-9a-zA-Z\_]*$/) !== null);
input_restorer.toggle(is_change);
input_sender.toggle(is_change && is_valid_input);
target_container.toggleClass("info", is_change && is_valid_input);
target_container.toggleClass("error", is_change && !is_valid_input);
});
input_restorer.click( function(evt) {
monitored_input.value = monitored_input.defaultValue;
targets.hide();
target_container.removeClass("success");
target_container.removeClass("info");
target_container.removeClass("error");
});
input_sender.click( function(evt) {
var url_data = get_url_data(monitored_input);
target_container.removeClass("info");
console.log(url_data);
$.ajax({
url : write_url,
type : "post",
data : url_data,
dataType : "json",
async : false,
cache : false,
success : function(updateRes) {
console.log(updateRes);
if (updateRes.status === "ok") {
monitored_input.defaultValue = monitored_input.value;
targets.hide();
target_container.addClass("success");
} else {
target_container.addClass("error");
log(updateRes);
};
},
});
});
});
d.find(".ajaxable_btn").click( function(evt) {
var url_data = get_url_data(this);
//console.log("evt", evt);
//console.log("this", this);
console.log(url_data);
$.ajax({
url : write_url,
type : "post",
data : url_data,
dataType : "json",
async : false,
cache : false,
success : function(updateRes) {
if (updateRes.status !== "ok") {
log(updateRes);
};
},
complete : doFetch
});
});
function onRestoreRequest_handler(evt) {
var target_name = $(this).attr("data-linkTo");
var elem = $('#'+target_name);
elem.val(elem.data("value"));
$('#' + target_name + "_monitor").find(".btn").addClass("disabled");
}
d.find("#p_new_key").keyup( function(evt) {
var is_error = false;
jQuery.map(d.find(".control-group"), function(obj, i) {
if ($(obj).children("input[value='"+evt.target.value+"']").length) {
$(obj).addClass("warning");
is_error = true;
} else {
$(obj).removeClass("warning");
}
});
is_error = is_error || !(evt.target.value.match(/^[0-9a-zA-Z\_]*$/));
d.find(".btn[data-method^='store']").toggleClass("disabled", is_error);
d.find("#row_new_pw_param").find('td.control-group').toggleClass("error", is_error);
});
};
function onClick_handler(evt) {
$.ajax({
......
......@@ -46,12 +46,12 @@ sub main {
my $dbConn = check_db_versions_match($decoded_json);
my $response = msg->new();
my $all_params_hash;
eval {
$all_params_hash = $dbConn->get_PipelineWideParametersAdaptor()->fetch_param_hash();
$response->out_msg(formPipelineWideParameters($all_params_hash)) if $all_params_hash;
my $all_params_hash = $dbConn->get_PipelineWideParametersAdaptor()->fetch_param_hash();
die "all_params_hash is undefined\n" unless $all_params_hash;
$response->out_msg(formPipelineWideParameters($all_params_hash));
};
if ($@ or (not $all_params_hash)) {
if ($@) {
$response->err_msg("I can't retrieve the pipeline-wide parameters: $@");
$response->status("FAILED");
}
......@@ -72,27 +72,18 @@ sub formPipelineWideParameters {
sub template_mappings_PARAMS {
my ($all_params_hash) = @_;
my $vals;
my @existing_parameters;
my $i = 0;
for my $param (sort keys %$all_params_hash) {
my $this_param_data = {
"key" => $param,
"value" => stringify_if_needed($all_params_hash->{$param}),
"parameterKeyID" => "p_$param",
"parameterValueID" => "v_$param",
"adaptor" => "PipelineWideParameters",
"key_field" => "param_name",
"key_value" => "param_value",
"update_method" => "update",
"delete_method" => "remove",
"param_index" => $i,
};
push @{$vals->{existing_parameters}}, $this_param_data;
push @existing_parameters, $this_param_data;
$i++;
}
$vals->{new_parameter} = [{
"adaptor" => "PipelineWideParameters",
"method" => "store",
"fields" => "param_name,param_value",
}],
return $vals;
return { 'existing_parameters' => \@existing_parameters };
}
sub stringify_if_needed {
......
......@@ -37,41 +37,29 @@ use version_check;
my $json_data = shift @ARGV || '{"adaptor":["PipelineWideParameters"],"method":["store"],"url":["mysql://ensro@127.0.0.1:4306/mm14_protein_trees_78"],"fields":["param_name,param_value"],"args":["a,2"],"version":["62"]}';
my $var = decode_json($json_data);
my $url = $var->{url}->[0];
my $args = uri_unescape($var->{args}->[0]);
my $adaptor_name = $var->{adaptor}->[0];
my $method = $var->{method}->[0];
my $version = $var->{version}->[0];
my $fields = $var->{fields}->[0];
my @fields = split(/,/,$fields);
my @args = split(/,/,$args,scalar(@fields));
##### This if is copied over from a script, but I don't know if it's really needed
# If we pass the 'NULL' string, then we undef the value to update a NULL mysql value:
if ((scalar @args == 1) && ($args[0] eq "NULL")) {
@args = undef;
}
my $dbConn = check_db_versions_match($var);
my $response = msg->new();
$adaptor_name = "get_".$adaptor_name."Adaptor";
my $adaptor = $dbConn->$adaptor_name;
warn Dumper(\@fields, \@args);
warn Dumper $var;
my %obj = ();
@obj{@fields} = @args;
warn Dumper(\%obj);
eval {
$adaptor->$method(\%obj);
my $method = $var->{method}->[0];
my $adaptor = $dbConn->get_PipelineWideParametersAdaptor();
if ($method eq 'update_key') {
my $objs = $adaptor->fetch_all(sprintf('param_name = "%s"', $var->{inikey}->[0]));
die "I was expecting to find a single object for $var->{inikey}->[0]\n" if not $objs or (scalar(@$objs) != 1);
$adaptor->remove($objs->[0]);
my $new_obj = bless { 'param_name' => $var->{key}->[0], 'param_value' => $objs->[0]->{param_value} }, 'Bio::EnsEMBL::Hive::PipelineWideParameters';
$adaptor->store($new_obj);
} else {
my $obj = bless { 'param_name' => $var->{key}->[0], 'param_value' => $var->{value}->[0] }, 'Bio::EnsEMBL::Hive::PipelineWideParameters';
$adaptor->$method($obj);
}
};
$response->err_msg($@);
$response->status($response->err_msg) if ($@);
print $response->toJSON();
......@@ -13,57 +13,54 @@
limitations under the License.
-->
<table id="pw_param_table">
<table id="pw_param_table" class="table table-striped">
<tr>
<th>Name</th>
<th>Value</th>
<th></th>
<th class="input-large">Name</th>
<th class="input-mini"></th>
<th class="input-xxlarge">Value</th>
<th class="input-mini"></th>
<th></th>
</tr>
<TMPL_LOOP NAME=existing_parameters>
<tr>
<td><span id="<TMPL_VAR NAME=parameterKeyID>" data-value="<TMPL_VAR NAME=key>">
<TMPL_VAR NAME=key>
</span></td>
<td><input
id="<TMPL_VAR NAME=parameterValueID>"
class="monitored_input"
<td class="monitored_input onlyalpha" colspan="2">
<input
id="pw_key_<TMPL_VAR NAME=param_index>"
class="input-large"
type="text"
data-value="<TMPL_VAR NAME=value ESCAPE=HTML>"
value="<TMPL_VAR NAME=value ESCAPE=HTML>">
value="<TMPL_VAR NAME=key>"
data-method="update_key"
data-linkTo="key=pw_key_<TMPL_VAR NAME=param_index>"
data-linkToDef="inikey=pw_key_<TMPL_VAR NAME=param_index>"
>
</td>
<td id="<TMPL_VAR NAME=parameterValueID>_monitor">
<a class="ajaxable_btn btn btn-mini disabled"
data-adaptor="<TMPL_VAR NAME=adaptor>"
data-method="<TMPL_VAR NAME=update_method>"
data-fields="<TMPL_VAR NAME=key_field>,<TMPL_VAR NAME=key_value>"
data-linkTo="<TMPL_VAR NAME=parameterKeyID>,<TMPL_VAR NAME=parameterValueID>"><i class="icon-ok-sign"></i></a>
<a class="input_restorer btn btn-mini disabled"
data-linkTo="<TMPL_VAR NAME=parameterValueID>"><i class="icon-remove-sign"></i></a>
<td class="monitored_input" colspan="2">
<input
id="pw_value_<TMPL_VAR NAME=param_index>"
type="text"
class="input-xxlarge"
value="<TMPL_VAR NAME=value ESCAPE=HTML>"
data-method="update"
data-linkTo="value=pw_value_<TMPL_VAR NAME=param_index>"
data-linkToDef="key=pw_key_<TMPL_VAR NAME=param_index>"
>
</td>
<td><a class="ajaxable_btn btn btn-mini"
data-adaptor="<TMPL_VAR NAME=adaptor>"
data-method="<TMPL_VAR NAME=delete_method>"
data-fields="<TMPL_VAR NAME=key_field>"
data-linkTo="<TMPL_VAR NAME=parameterKeyID>"><i class="icon-minus-sign"></i></a>
data-method="remove"
data-linkToDef="key=pw_key_<TMPL_VAR NAME=param_index>"><i class="icon-minus-sign"></i></a>
</td>
</tr>
</TMPL_LOOP> <!-- existing_parameters -->
<TMPL_LOOP NAME=new_parameter>
<tr>
<td><input type="text" id="p_new_key" placeholder="new parameter's name"></td>
<td><input type="text" id="p_new_value" placeholder="new parameter's value"></td>
<tr id="row_new_pw_param">
<td class="control-group onlyalpha" colspan="2"><input class="input-large" type="text" id="p_new_key" placeholder="new parameter's name"></td>
<td colspan="2"><input class="input-xxlarge" type="text" id="p_new_value" placeholder="new parameter's value"></td>
<td><a class="ajaxable_btn btn btn-mini"
data-adaptor="<TMPL_VAR NAME=adaptor>"
data-method="<TMPL_VAR NAME=method>"
data-fields="<TMPL_VAR NAME=fields>"
data-linkTo="p_new_key,p_new_value"><i class="icon-plus-sign"></i></a>
data-method="store"
data-linkTo="key=p_new_key,value=p_new_value"><i class="icon-plus-sign"></i></a>
</td>
<td></td>
</tr>
</TMPL_LOOP> <!-- new parameter -->
</table>
......
......@@ -235,17 +235,8 @@ html, body {
#pw_param_table {
font-size : 12px;
background-color : #E6EBF0;
margin-left : 10px;
}
#pw_param_table th {
padding: 5px;
}
#pw_param_table tr td:first-child {
padding-left : 10px;
padding-right: 10px;
width : 1000px;
}
#pw_param_table tr td {
......@@ -257,10 +248,6 @@ html, body {
padding-top: 6px;
}
#pw_param_table tr td:nth-child(2) input {
width: 500px;
}
.footer_spacer {
height: 40px;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment