stash analysis logfile data for histogram construction
[sgn.git] / cgi-bin / maps / physical / clone_il_view.pl
blob9acf94b2268bed37ef8c8ed664a0f7664028cac4
1 use strict;
2 use warnings;
4 use CXGN::Page;
5 use CXGN::DB::Connection;
6 use CXGN::Page::FormattingHelpers qw( info_section_html
7 modesel
8 columnar_table_html
9 simple_selectbox_html
10 info_table_html
12 use CXGN::Tools::List qw/distinct str_in/;
14 my $page = CXGN::Page->new('Clone IL Mapping Assignments','Robert Buels');
15 $page->jsan_use(qw/MochiKit.Base MochiKit.Async MochiKit.Iter MochiKit.DOM MochiKit.Style/);
17 $page->header(('Clone IL Mapping Assignments') x 2);
19 my ($curr_proj) = $page->get_encoded_arguments('p');
20 $curr_proj ||= 1;
22 # map project IDs to country names
23 my @projmap = qw/dummy USA Korea China UK India Netherlands France Japan Spain USA USA Italy/;
25 # map project IDs to modesel button indexes
26 my @indexmap = ( 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 0, 0, 9);
28 print modesel([ map { [ "?p=$_" => $projmap[$_] ] } 1..9,12 ],
29 $indexmap[$curr_proj],
32 #look up all the il assignments for this project
33 my $dbh = CXGN::DB::Connection->new;
34 my $clone_name_sql = CXGN::Genomic::Clone->
35 clone_name_sql('l.shortname',
36 'c.platenum',
37 'c.wellrow',
38 'c.wellcol',
40 my $bacs = $dbh->selectall_arrayref(<<EOQ,undef,$curr_proj);
41 select cl.clone_id,
42 $clone_name_sql,
43 cl.sp_project_id,
44 ill.individual_id,
45 i.name
46 from sgn_people.sp_project_il_mapping_clone_log cl
47 join genomic.clone c using(clone_id)
48 join genomic.library l using(library_id)
49 left join sgn_people.sp_clone_il_mapping_segment_log ill on cl.clone_id=ill.clone_id and ill.is_current = true
50 left join phenome.individual i using(individual_id)
51 where cl.sp_project_id = ?
52 and cl.is_current = true
53 order by $clone_name_sql
54 EOQ
56 #if logged in, add edit controls
57 my $person = do {
58 if(my $person_id = CXGN::Login->new($dbh)->has_session) {
59 CXGN::People::Person->new($dbh, $person_id);
63 my $can_edit = $person #< person is logged in
64 && str_in($person->get_user_type,qw/sequencer curator/) #< and is the right user type
65 && str_in($curr_proj,$person->get_projects_associated_with_person); #< and has edit rights on this project
67 my @data = map {
68 my ($clone_id,$clone_name,$project_id,$il_id,$il_name) = @$_;
70 #link to clone info page
71 qq|<a href="/maps/physical/clone_info.pl?id=$clone_id">$clone_name</a>|,
73 #the project name
74 qq|<span id="proj_name_$clone_id">$projmap[$project_id]</span><span id="proj_id_$clone_id" style="display: none">$project_id</span>|,
76 #the IL line
77 qq|<span id="il_name_$clone_id">|.($il_name || '-').qq|</span><span style="display: none" id="il_id_$clone_id">|.($il_id||'').'</span>',
79 $can_edit ? edit_controls_html($clone_id,$il_id) : (),
81 } @$bacs;
83 my @headings = ('BAC', 'Project', 'IL Bin', $can_edit ? 'Edit' : ());
85 print columnar_table_html( headings => \@headings,
86 data => \@data,
87 __border => 1,
88 __align => 'lccr',
89 __tableattrs => 'align="center" width="60%" summary="" cellspacing="0"',
92 print editform_html($dbh,$person,$curr_proj);
94 #now here are the JS functions to do the updating
95 print <<EOJS;
96 <script language="JavaScript" type="text/javascript">
98 var TR = MochiKit.DOM.TR;
99 var TD = MochiKit.DOM.TD;
100 var A = MochiKit.DOM.A;
101 var map = MochiKit.Base.map;
102 var partial = MochiKit.Base.partial;
103 var TABLE = MochiKit.DOM.TABLE;
104 var THEAD = MochiKit.DOM.THEAD;
106 var set_row_content = function(row,req) {
107 var data = MochiKit.Async.evalJSONRequest(req);
109 row.proj_name.innerHTML = data.il_proj.disp;
110 row.proj_id.innerHTML = data.il_proj.val;
111 row.il_name.innerHTML = data.il_bin.disp;
112 row.il_id.innerHTML = data.il_bin.val;
114 check_editor_enable();
117 var set_row_error = function(row) {
118 row.proj_name.innerHTML = 'error';
119 row.il_name.innerHTML = 'error';
122 //get the three span elements in the relevant table row
123 var get_row_elements = function(clone_id) {
124 var row = { proj_name: document.getElementById('proj_name_'+clone_id),
125 proj_id: document.getElementById('proj_id_'+clone_id),
126 il_name: document.getElementById('il_name_'+clone_id),
127 il_id: document.getElementById('il_id_'+clone_id),
128 editbutton: document.getElementById('editbutton_'+clone_id),
129 posdiv: document.getElementById('posdiv_'+clone_id)
131 row.disabled = (row.proj_id.innerHTML == 'disabled') || (row.il_id.innerHTML == 'disabled');
132 return row;
135 var edform = document.clone_il_editor_form;
136 var edtable = document.getElementById('clone_il_editor_table');
138 //set the editor either enabled or disabled,
139 //depending on which clone it's currently
140 //editing
141 var check_editor_enable = function() {
143 var clone_id = edform.clone_id.value;
145 if(!clone_id) return;
147 var row = get_row_elements(clone_id);
149 if(row.disabled) {
150 edform.il.disabled = true;
151 edform.proj.disabled = true;
152 } else {
153 edform.il.disabled = false;
154 edform.proj.disabled = false;
158 //do a POST XHR to alter the clone in the database,
159 //also update its display fields
160 var alter_clone = function(clone_id,type,newvalue) {
161 var row = get_row_elements(clone_id);
163 var postcontent = type == 'proj' ? { clone_id: clone_id, action: 'set_il_proj', val: newvalue }
164 : { clone_id: clone_id, action: 'set_il_bin', val: newvalue };
166 var xhr_opt =
167 { headers: [["Content-type","application/x-www-form-urlencoded"]],
168 method: 'POST',
169 sendContent: MochiKit.Base.queryString(postcontent)
172 row.proj_name.innerHTML =
173 row.il_name.innerHTML =
174 '<div style="background: red; color: white; font-weight:bold; border: 2px outset gray;">wait</span>';
175 row.proj_id.innerHTML = row.il_id.innerHTML = 'disabled';
177 check_editor_enable();
179 var res = MochiKit.Async.doXHR('clone_async.pl',xhr_opt);
180 res.addCallbacks(partial(set_row_content,row),
181 partial(set_row_error,row)
185 var last_active_edit_button;
187 //pop up the edit form at the given button
188 var edit_row = function(clone_id) {
189 var row = get_row_elements(clone_id);
191 row.editbutton.blur();
192 edform.clone_id.value = clone_id;
194 edform.il.value = row.il_id.innerHTML || 'none';
195 edform.proj.value = row.proj_id.innerHTML;
197 edtable.style.display = 'block';
199 MochiKit.DOM.removeElement(edform);
200 MochiKit.DOM.appendChildNodes(row.posdiv,edform);
201 var divdims = MochiKit.Style.getElementDimensions(row.posdiv);
202 MochiKit.Style.setElementPosition(edtable,{x: divdims.w-4, y: 0});
204 check_editor_enable();
206 if(last_active_edit_button) {
207 MochiKit.Style.setStyle(last_active_edit_button,{background: 'none', fontWeight: 'normal', color: 'black'});
209 last_active_edit_button = row.editbutton;
210 MochiKit.Style.setStyle(row.editbutton,{background: '#666', fontWeight: 'bold', color: 'white' });
213 </script>
214 EOJS
216 $page->footer;
218 ############ SUBROUTINES ##############
220 sub il_bin_list {
221 return @{our $il_list ||= shift->selectall_arrayref(<<EOQ)}
222 select genotype_region_id, name
223 from phenome.genotype_region gr
224 join sgn.linkage_group lg using(lg_id)
225 join sgn.map_version mv using(map_version_id)
226 join sgn.map m using(map_id)
227 where type = 'bin' and m.short_name like '%1992%' and m.short_name like '%EXPEN%';
231 sub edit_controls_html {
232 my ($clone_id,$il_id) = @_;
233 $il_id ||= 'null';
234 return qq|<div style="position: relative; padding: 0" id="posdiv_$clone_id"><button id="editbutton_$clone_id" value="edit" style="background: none; border: 1px solid black;" onclick="edit_row($clone_id)">edit</button></div>|;
237 sub editform_html {
238 my ($dbh,$person,$curr_proj) = @_;
240 return '' unless $person;
242 my @person_projects = $person->get_projects_associated_with_person;
244 #@projmap is a array of [project_id,country name]
245 my $c;
246 my @projmap = map {
247 [++$c,$_]
248 } qw/USA Korea China UK India Netherlands France Japan Spain USA USA Italy/;
249 @projmap[9,10] = ($projmap[0]) x 2;
251 my @ils = il_bin_list($dbh);
253 #the values of all these form fields will be set by javascript each
254 #time this form is popped up at a given location
255 return join '',
257 '<form name="clone_il_editor_form">',
258 qq|<input name="clone_id" value="" type="hidden"/>|,
259 '<table id="clone_il_editor_table" style="display: none; position: absolute; background: #bbbbff; border: 1px solid black; z-index: 3"><tr><td><b>Project</b></td><td>',
260 simple_selectbox_html(name => "proj",
261 choices => [['','none'],
262 distinct map {$projmap[$_-1]} @person_projects
264 params => { onchange => "alter_clone(this.form.clone_id.value,'proj',this.value)" },
265 selected => $curr_proj,
267 '</td></tr><tr><td><b>IL</b></td><td>',
268 simple_selectbox_html(name => "il",
269 choices => [['','none'],
270 @ils,
272 params => { onchange => "alter_clone(this.form.clone_id.value,'il',this.value)" },
274 '</td></tr></table></form>',