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;
}
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;
}
// $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;
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) {
// 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';
}
// 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;
$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);
$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();
// 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';
$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'];
$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
//////////////////// 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);
// 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);
$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,
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();
$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);
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();
}
////////////////////////////////////////
// table_id: <table>'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 ``<title>''" 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)
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;
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>";
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.
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));