From ab7d755720166fb4ce7acaf629463dc7f0a00ffe Mon Sep 17 00:00:00 2001 From: Thierry Parmentelat Date: Sun, 15 Nov 2009 22:28:05 +0000 Subject: [PATCH] show extra tags in the nodes page as well feature extracted in includes/plc_visibletags.php fancier table headers with an optional title - could make footnotes less crucial going to the slice page from the slices page opens the node toggle and closes details --- planetlab/common/actions.php | 4 +- planetlab/includes/plc_functions.php | 5 +- planetlab/nodes/nodes.php | 45 ++++++++++------ planetlab/slices/slice.php | 79 +++++++++------------------- plekit/php/table.php | 23 ++++++-- plekit/tablesort/tablesort.js | 11 ++-- 6 files changed, 84 insertions(+), 83 deletions(-) diff --git a/planetlab/common/actions.php b/planetlab/common/actions.php index 2717d1e..ae98281 100644 --- a/planetlab/common/actions.php +++ b/planetlab/common/actions.php @@ -643,7 +643,7 @@ Our support team will be glad to answer any question that you might have. drupal_set_message ("Removed $count node(s)"); else drupal_set_error ("Could not remove selected nodes"); - plc_redirect(l_slice($slice_id) . " &show_nodes=true"); + plc_redirect(l_slice_nodes($slice_id)); break; } @@ -655,7 +655,7 @@ Our support team will be glad to answer any question that you might have. drupal_set_message ("Added $count node(s)"); else drupal_set_error ("Could not add all selected nodes"); - plc_redirect(l_slice($slice_id) . "&show_nodes=true" ); + plc_redirect(l_slice_nodes($slice_id)); break; } diff --git a/planetlab/includes/plc_functions.php b/planetlab/includes/plc_functions.php index 53600ae..3e69f23 100644 --- a/planetlab/includes/plc_functions.php +++ b/planetlab/includes/plc_functions.php @@ -2,9 +2,6 @@ // $Id$ -// will trash this eventually - //require_once 'plc_functions_trash.php'; - # note: this needs to be consistent with the value in Monitor/monitor/wrapper/plc.py global $PENDING_CONSORTIUM_ID; $PENDING_CONSORTIUM_ID = 0; @@ -215,7 +212,7 @@ function tab_nodegroups() { return array ('label'=>'Nodegroups', 'url'=>l_nodegr function tablook_event() { return array('image'=>'/planetlab/icons/event.png','height'=>18);} function tablook_comon() { return array('image'=>'/planetlab/icons/comon.png','height'=>18);} -//////////////////// + //////////////////////////////////////////////////////////// validation functions function topdomain ($hostname) { diff --git a/planetlab/nodes/nodes.php b/planetlab/nodes/nodes.php index ebe8079..951e985 100644 --- a/planetlab/nodes/nodes.php +++ b/planetlab/nodes/nodes.php @@ -16,6 +16,7 @@ include 'plc_header.php'; // Common functions require_once 'plc_functions.php'; require_once 'plc_peers.php'; +require_once 'plc_visibletags.php'; require_once 'linetabs.php'; require_once 'table.php'; require_once 'nifty.php'; @@ -61,7 +62,12 @@ function node_status ($node) { } // fetch nodes -$node_columns=array('hostname','node_type','site_id','node_id','boot_state','run_level','interface_ids','peer_id', 'arch','slice_ids'); +$node_fixed_columns=array('hostname','node_type','site_id','node_id','boot_state','run_level', + 'interface_ids','peer_id', 'slice_ids'); +$visibletags = new VisibleTags ($api, 'node'); +$visiblecolumns = $visibletags->column_names(); +$node_columns=array_merge($node_fixed_columns,$visiblecolumns); + // server-side filtering - set pattern in $_GET for filtering on hostname if ($pattern) { $node_filter['hostname']=$pattern; @@ -150,17 +156,31 @@ if ( ! $nodes ) { $nifty=new PlekitNifty ('','objects-list','big'); $nifty->start(); $headers = array (); $offset=0; -if (plc_is_admin()) { $headers["I"]="int"; $offset=1; } -$headers["P"]="string"; -$headers["R"]="string"; +$notes=array(); + +// fixed columns +if (plc_is_admin()) { + $short="I"; $long="node_id"; $type='int'; + $headers[$short]=array('type'=>$type,'title'=>$long); $notes []= "$short = $long"; + $offset=1; + } +$short="P"; $long="Peer"; $type='string'; + $headers[$short]=array('type'=>$type,'title'=>$long); $notes []= "$short = $long"; +$short="D"; $long="toplevel domain name"; $type='string'; + $headers[$short]=array('type'=>$type,'title'=>$long); $notes []= "$short = $long"; $headers["Site"]="string"; $headers["State"]="string"; + $notes []= "state* = node doesn't have an observed state, preferred state is displayed"; $headers["Hostname"]="string"; $headers["Type"]="string"; -$headers["IP"]="sortIPAddress"; -$headers["A"]="string"; -$headers["S"]='int'; -$headers["?"]="string"; +$short="IP"; $long="IP Address"; $type='sortIPAddress'; + $headers[$short]=array('type'=>$type,'title'=>$long); $notes []= "$short = $long"; +$short="SL"; $long="Number of slivers"; $type='int'; + $headers[$short]=array('type'=>$type,'title'=>$long); $notes []= "$short = $long"; + +$headers=array_merge($headers,$visibletags->headers()); +$notes=array_merge($notes,$visibletags->notes()); +$headers["?"]="string"; $notes []= "? = extra status info"; # initial sort on hostnames $table=new PlekitTable ("nodes",$headers,4+$offset); @@ -192,20 +212,13 @@ foreach ($nodes as $node) { $table->cell (l_node_t($node_id,$hostname)); $table->cell ($node_type); $table->cell (l_interface_t($interface_id,$ip),array('only-if'=> !$peer_id)); - $table->cell ($node['arch'],array('only-if'=> !$peer_id)); $table->cell (count($node['slice_ids'])); + foreach ($visiblecolumns as $tagname) $table->cell($node[$tagname]); $table->cell (node_status($node)); $table->row_end(); } -$notes=array(); -if (plc_is_admin()) $notes []= "I = node_id"; -$notes []= "R = region"; -$notes []= "A = arch"; -$notes []= "S = number of slivers"; -$notes []= "? = status"; -$notes []= "status* = node doesn't have an observed state, preferred state is displayed"; $table->end(array('notes'=>$notes)); $nifty->end(); diff --git a/planetlab/slices/slice.php b/planetlab/slices/slice.php index 9649136..91721ce 100644 --- a/planetlab/slices/slice.php +++ b/planetlab/slices/slice.php @@ -16,6 +16,7 @@ include 'plc_header.php'; // Common functions require_once 'plc_functions.php'; require_once 'plc_peers.php'; +require_once 'plc_visibletags.php'; require_once 'linetabs.php'; require_once 'table.php'; require_once 'details.php'; @@ -51,9 +52,7 @@ $name= $slice['name']; $expires = date( "d/m/Y", $slice['expires'] ); $site_id= $slice['site_id']; -//$node_ids=$slice['node_ids']; $person_ids=$slice['person_ids']; -//$slice_tag_ids= $slice['slice_tag_ids']; // get peers $peer_id= $slice['peer_id']; @@ -65,13 +64,6 @@ $sites= $api->GetSites( array( $site_id ) ); $site=$sites[0]; $site_name= $site['name']; $max_slices = $site['max_slices']; -// xxx PIs -//$pis=$api->GetPersons(...) - -// get all persons info -if (!empty($person_ids)) - $persons=$api->GetPersons($person_ids,array('email','enabled')); - //////////////////////////////////////// building blocks for the renew area // Constants @@ -268,11 +260,16 @@ $toggle->end(); //////////////////// persons $person_columns = array('email','person_id','first_name','last_name','roles'); -$persons=$api->GetPersons(array('person_id'=>$slice['person_ids'])); -// just propose to add everyone else, +// get persons in slice +if (!empty($person_ids)) + $persons=$api->GetPersons(array('person_id'=>$slice['person_ids']),$person_columns); +// just propose to add everyone else +// xxx this is maybe too much for admins as it slows stuff down // as regular persons can see only a fraction of the db anyway $potential_persons= - $api->GetPersons(array('~person_id'=>$slice['person_ids'],'peer_id'=>NULL,'enabled'=>true), + $api->GetPersons(array('~person_id'=>$slice['person_ids'], + 'peer_id'=>NULL, + 'enabled'=>true), $person_columns); $count=count($persons); @@ -388,35 +385,10 @@ $toggle->end(); // minimal list as a start $node_fixed_columns = array('hostname','node_id','peer_id','slice_ids_whitelist','run_level','boot_state'); -// scan tag types to find relevant additional columns -$nodeui_tag_types = $api->GetTagTypes(array('category'=>'node*/ui*')); -// extract tagname -$node_tag_columns = array_map(create_function('$tt','return $tt["tagname"];'),$nodeui_tag_types); -// build an ordered list of chunks {'tagname','header','rank','description'} -$more_tags = array(); -foreach ($nodeui_tag_types as $tag_type) { - $tagname=$tag_type['tagname']; - $chunk=array(); - $chunk['tagname']=$tagname; - $chunk['header']=$tagname; - $chunk['rank']=$tagname; - $chunk['type']='string'; - $chunk['description']=$tag_type['description']; - $category_tokens=split('/',$tag_type['category']); - foreach ($category_tokens as $token) { - $assign=split('=',$token); - if (count($assign)==2) - $chunk[$assign[0]]=$assign[1]; - } - $more_tags []= $chunk; -} - -function sort_chunks ($ch1, $ch2) { return strcmp($ch1['rank'],$ch2['rank']); } -usort ($more_tags, sort_chunks); - -//plc_debug('ordered additional tags',$more_tags); - -$node_columns=array_merge($node_fixed_columns,$node_tag_columns); +// create a VisibleTags object : basically the list of tag columns to show +$visibletags = new VisibleTags ($api, 'node'); +$visiblecolumns = $visibletags->column_names(); +$node_columns=array_merge($node_fixed_columns,$visiblecolumns); $nodes=$api->GetNodes(array('node_id'=>$slice['node_ids']),$node_columns); $potential_nodes=$api->GetNodes(array('~node_id'=>$slice['node_ids']),$node_columns); $count=count($nodes); @@ -438,13 +410,12 @@ $headers=array(); $notes=array(); $headers['peer']='string'; $headers['hostname']='string'; -$headers['S']='string'; -$notes[]='S = last known status'; -foreach ($more_tags as $chunk) { - $header=$chunk['header']; - $headers[$header]=$chunk['type']; - if ($header != $chunk['tagname']) $notes []= $header . ' = ' . $chunk['description']; -} +$short="ST"; $long="Last known status"; $type='string'; + $headers[$short]=array('type'=>$type,'title'=>$long); $notes []= "$short = $long"; +// the extra tags +$headers=array_merge($headers,$visibletags->headers()); +$notes=array_merge($notes,$visibletags->notes()); + if ($privileges) $headers[plc_delete_icon()]="none"; $table_options = array('notes'=>$notes, @@ -463,7 +434,7 @@ if ($nodes) foreach ($nodes as $node) { if ( empty($run_level)) $run_level=$node['boot_state']; $class=($run_level == 'boot') ? 'node-ok' : 'node-ko'; $table->cell($run_level,array('class'=>$class)); - foreach ($more_tags as $chunk) $table->cell($node[$chunk['tagname']]); + foreach ($visiblecolumns as $tagname) $table->cell($node[$tagname]); if ($privileges) $table->cell ($form->checkbox_html('node_ids[]',$node['node_id'])); $table->row_end(); @@ -509,11 +480,9 @@ if ($privileges) { $headers['hostname']='string'; $headers['S']='string'; $notes[]='S = last known status'; - foreach ($more_tags as $chunk) { - $header=$chunk['header']; - $headers[$header]=$chunk['type']; - if ($header != $chunk['tagname']) $notes []= $header . ' = ' . $chunk['description']; - } + // the extra tags + $headers=array_merge($headers,$visibletags->headers()); + $notes=array_merge($notes,$visibletags->notes()); $headers['+']="none"; $table=new PlekitTable('add_nodes',$headers,'1', $table_options); @@ -529,7 +498,7 @@ if ($privileges) { if ( empty($run_level)) $run_level=$node['boot_state']; $class=($run_level == 'boot') ? 'node-ok' : 'node-ko'; $table->cell($run_level,array('class'=>$class)); - foreach ($more_tags as $chunk) $table->cell($node[$chunk['tagname']]); + foreach ($visiblecolumns as $tagname) $table->cell($node[$tagname]); $table->cell ($form->checkbox_html('node_ids[]',$node['node_id'])); $table->row_end(); } diff --git a/plekit/php/table.php b/plekit/php/table.php index 480bd8b..dc5bd8e 100644 --- a/plekit/php/table.php +++ b/plekit/php/table.php @@ -15,7 +15,14 @@ drupal_set_html_head(' //////////////////////////////////////// // table_id: 's id tag - WARNING : do not use '-' in table ids as it's used for generating javascript code -// headers: an associative array "label"=>"type" +// headers: an associative array; the values can take several forms +// simple/legacy form is "label"=>"type" +// more advanced form is "label"=>options, it self a dict with the following known keys +// (*) 'type': the type for sorting; this is passed to the javascript layer for custom sorting +// default is to use 'text', custom sort functions can be specified with e.g. 'type'=>'sortAlphaNumericBottom' +// a special case is for type to be 'date-format' like e.g. 'type'=>'date-dmy' +// setting type to 'none' gives an non-sortable column +// (*) 'title': if set, this is used in the "Sort on ``''" bubble // sort_column: the column to sort on at load-time - set to negative number for no onload- sorting // options : an associative array to override options // - bullets1 : set to true if you want decorative bullets in column 1 (need white background) @@ -131,7 +138,16 @@ class PlekitTable { if ($this->caption) print "<caption> $this->caption </caption>"; print "<tr>"; - foreach ($this->headers as $label => $type) { + foreach ($this->headers as $label => $colspec) { + // which form is being used + if (is_array($colspec)) { + $type=$colspec['type']; + $title=ucfirst($colspec['title']); + } else { + // simple/legacy form + $type=$colspec; + $title=NULL; + } switch ($type) { case "none" : $class=""; break; @@ -142,7 +158,8 @@ class PlekitTable { default: $class="sortable-sort" . $type; break; } - printf ('<th class="%s plekit_table">%s</th>',$class,$label); + $title_part=$title ? "title=\"$title\"" : ""; + print ("<th class=\"$class plekit_table\" $title_part>$label</th>\n"); } print "</tr></thead><tbody>"; diff --git a/plekit/tablesort/tablesort.js b/plekit/tablesort/tablesort.js index c52382c..e9e8058 100644 --- a/plekit/tablesort/tablesort.js +++ b/plekit/tablesort/tablesort.js @@ -213,8 +213,8 @@ fdTableSort = { columnNumSortObj[i]["thNode"] = workArr[c][i]; columnNumSortObj["active"] = true; }; - - thtext = fdTableSort.getInnerText(workArr[c][i], true); + th_elt = workArr[c][i]; + thtext = fdTableSort.getInnerText(th_elt, true); for(var cn = workArr[c][i].childNodes.length; cn--;) { // Skip image nodes and links created by the filter script. @@ -230,7 +230,12 @@ fdTableSort = { aclone = a.cloneNode(true); //aclone.appendChild(document.createTextNode(thtext)); aclone.innerHTML = thtext; - aclone.title = "Sort on \u201c" + thtext.replace('<br />', '') + "\u201d"; + //if the <th> has title set, use this as an alternate text for the 'sort on ...' + if (th_elt.title) { + aclone.title = th_elt.title; + } else { + aclone.title = "Sort on \u201c" + (th_elt.title ? th_elt.title : thtext.replace('<br />', '')) + "\u201d"; + } aclone.onclick = aclone.onkeydown = workArr[c][i].onclick = fdTableSort.initWrapper; workArr[c][i].appendChild(aclone); if(showArrow) workArr[c][i].appendChild(span.cloneNode(false)); -- 2.43.0