nodes can set tags, tags and nodegroups are mostly OK
authorThierry Parmentelat <thierry.parmentelat@sophia.inria.fr>
Tue, 3 Feb 2009 16:19:18 +0000 (16:19 +0000)
committerThierry Parmentelat <thierry.parmentelat@sophia.inria.fr>
Tue, 3 Feb 2009 16:19:18 +0000 (16:19 +0000)
14 files changed:
modules/planetlab.module
planetlab/actions.php
planetlab/events/index.php
planetlab/includes/plc_functions.php
planetlab/includes/plc_peers.php
planetlab/includes/plc_tables.php
planetlab/js/plc_tables.js
planetlab/nodes/node.php
planetlab/nodes/nodes.php
planetlab/persons/person.php
planetlab/sites/site.php
planetlab/sites/sites.php
planetlab/tags/nodegroup.php [new file with mode: 0644]
planetlab/tags/nodegroups.php

index be8293e..45e2db4 100644 (file)
@@ -105,7 +105,7 @@ function planetlab_block($op = 'list', $delta = 0, $edit = array()) {
       $block['content'] .= p( href(l_person_register(),"Create an account") );
       $block['content'] .= p( href(l_site_register(),"File a site registration") );
     } else {
-      $block['subject'] = $plc->person['email'];
+      $block['subject'] = truncate($plc->person['email'],30);
       $is_admin = in_array(10,$plc->person['role_ids']);
       $is_pi    = in_array(20,$plc->person['role_ids']);
       $is_user  = in_array(30,$plc->person['role_ids']);
@@ -140,7 +140,7 @@ function planetlab_block($op = 'list', $delta = 0, $edit = array()) {
       if (is_pi) 
        $user_item .= leaf( href( l_persons_site(plc_my_site_id()), "My users"));
       if ( $plc->alt_person && $plc->alt_auth) {
-       $email = $plc->person['email']
+       $email = truncate($plc->person['email'],20)
        $user_item .= leaf( href( l_sulogout(),"Log out of $email"));
       }        
       $user_item .= ul_end();
@@ -174,7 +174,7 @@ function planetlab_block($op = 'list', $delta = 0, $edit = array()) {
        $admin_item .= href(l_admin(),"Admin");
        $admin_item .= ul_start();
        $admin_item .= leaf( href( l_tags(),"Tags"));
-       $admin_item .= leaf( href( l_nodegroups(),"Node groups (xxx)"));
+       $admin_item .= leaf( href( l_nodegroups(),"Node groups"));
        $admin_item .= leaf (href(l_peers(),'Peers'));
        if ( $is_admin )
          $admin_item .= leaf (href(l_events(),'Events'));
index 564ada2..437541a 100644 (file)
@@ -46,6 +46,8 @@ $known_actions []= "delete-site";
 //     expects:        site_id
 $known_actions []= "expire-all-slices-in-site";
 //     expects:        slice_ids
+$known_actions []= "set-tag-on-node";
+//     expects:        node_id tagname value
 
 //////////////////////////////
 // sometimes we don't set 'action', but use the submit button name instead
@@ -242,6 +244,7 @@ switch ($action) {
  }
 
  case 'expire-all-slices-in-site': {
+   // xxx todo
    drupal_set_message("action $action not implemented in actions.php -- need tweaks and test");
    return;
 
@@ -260,6 +263,39 @@ switch ($action) {
    exit(0);
  }
 
+ case 'set-tag-on-node': {
+
+   $node_id = intval($_POST['node_id']);
+   $tag_type_id = intval($_POST['tag_type_id']);
+   $value = $_POST['value'];
+
+   $tag_types=$api->GetTagTypes(array($tag_type_id));
+   if (count ($tag_types) != 1) {
+     drupal_set_error ("Could not locate tag_type_id $tag_type_id </br> Tag not set.");
+   } else {
+     $tags = $api->GetNodeTags (array('node_id'=>$node_id, 'tag_type_id'=> $tag_type_id));
+     if ( count ($tags) == 1) {
+       $tag=$tags[0];
+       $tag_id=$tag['node_tag_id'];
+       $result=$api->UpdateNodeTag($tag_id,$value);
+       if ($result == 1) 
+        drupal_set_message ("Updated tag, new value = $value");
+       else
+        drupal_set_error ("Could not update tag");
+     } else {
+       $tag_id = $api->AddNodeTag($node_id,$tag_type_id,$value);
+       if ($tag_id) 
+        drupal_set_message ("Created tag, new value = $value");
+       else
+        drupal_set_error ("Could not create tag");
+     }
+   }
+   
+   header ("location: " . l_node($node_id));
+   exit();
+ }
+
+
  case 'debug': {
    plc_debug('GET',$_GET);
    plc_debug('POST',$_POST);
index 647b6b7..88a4046 100644 (file)
@@ -154,14 +154,6 @@ function parse_dates () {
 }
 
 //////////////////////////////////////////////////////////// layout
-function truncate ($text,$numb,$etc = "...") {
-  if (strlen($text) > $numb) {
-    $text = substr($text, 0, $numb);
-    $text = $text.$etc;
-  }
-  return $text;
-}
-
 // outline node ids and person ids with a link
 function e_node ($node_id) {
   if (! $node_id) return "";
index 03a8756..29136c7 100644 (file)
@@ -91,7 +91,7 @@ function l_tag_add()                  { return "/db/tags/tag_form.php"; }
 function l_tag_update($id)             { return "/db/tags/tag_form.php&action=update-tag-type&id=$id"; }
 
 function l_nodegroups ()               { return "/db/tags/nodegroups.php"; }
-function l_nodegroup ($nodegroup_id)   { return "/db/tags/nodegroups.php?id=$nodegroup_id"; }
+function l_nodegroup ($nodegroup_id)   { return "/db/tags/nodegroup.php?id=$nodegroup_id"; }
 function l_nodegroup_t ($nodegroup_id,$text) { 
                                          return href(l_nodegroup($nodegroup_id),$text); }
 
@@ -296,6 +296,14 @@ function plc_debug ($message,$object) {
   print "</pre>";
 }
 
+function truncate ($text,$numb,$etc = "...") {
+  if (strlen($text) > $numb) {
+    $text = substr($text, 0, $numb);
+    $text = $text.$etc;
+  }
+  return $text;
+}
+
 if (! function_exists ("drupal_set_error")) {
   function drupal_set_error ($text) {
     drupal_set_message ("<span class=error>$text</span>");
index e63552e..a464863 100644 (file)
@@ -81,12 +81,10 @@ class Peers {
     // return true if the peer is local 
     if ( ! $peer_id ) {
       print "<div>";
-      return true;
     } else {
       $classname=strtolower($this->classname($peer_id));
       // set two classes, one generic to all foreign, and one based on the peer's shortname for finer grain tuning
       printf ("<div class=\"plc-foreign %s\">",$classname);
-      return false;
     }
   }
 
@@ -95,6 +93,7 @@ class Peers {
   }
 }
 
+////////////////////////////////////////////////////////////
 class PeerScope {
   var $filter;
   var $label;
index 02b591b..5f9be14 100644 (file)
@@ -140,10 +140,10 @@ function plc_table_end ($table_id,$options_end=NULL) {
                    
 ////////////////////////////////////////
 function plc_table_foot ($options) {
-  print "</tbody><tfoot>";
+  print "</tbody><tfoot>\n";
   if ($options['footers']) 
     foreach ($options['footers'] as $footer) 
-      print "<tr> $footer </tr>";
+      print "<tr> $footer </tr>\n";
   print "</tfoot></table>\n";
 }
 
index 90edc81..afd4238 100644 (file)
@@ -14,15 +14,12 @@ function plc_table_paginator (opts,tablename) {
 
   /* get how many entries are matching:
      opts.visibleRows only holds the contents of the current page
-     so we store the number of matching entries in the tbody's classname
-     see plc_table_tbody_matching
+     so we store the number of matching entries in the tbody's 'matching' attribute
   */
   var totalMatches = opts.totalRows;
   var tbody=document.getElementById(tablename).getElementsByTagName("tbody")[0];
-  var cn=tbody.className;
-  if (cn.match (/matching-\d+/)) {
-    totalMatches=cn.match(/matching-\d+/)[0].replace("matching-","");
-  } 
+  var matching=tbody['matching'];
+  if (matching) totalMatches = matching;
 
   var label;
 
@@ -75,17 +72,16 @@ function plc_table_row_visible (row,visible) {
   row.className=cn;
 }
 
-/* maintain the number of matching entries in the <tbody> element's classname */
-function plc_table_tbody_matching (tbody, matching) {
-  var new_cn="matching-" + matching;
-  var cn=tbody.className;
-  if (cn.match("matching-")) {
-    cn=cn.replace(/matching-\d+/,new_cn);
-  } else {
-    cn=cn + " " + new_cn;
-  }
-  cn=cn.replace(/^ +/,"");
-  tbody.className=cn;
+// from a cell, extract visible text by removing <> and cache in 'plc_text' attribute
+var re_brackets = new RegExp ('<[^>]*>','g');
+
+function plc_table_cell_text (cell) {
+  if (cell['plc_text']) return cell['plc_text'];
+  var text = cell.innerHTML;
+  // remove what's between <>
+  text = text.replace(re_brackets,'');
+  cell['plc_text'] = text;
+  return text;
 }
 
 /* scan the table, and mark as visible 
@@ -96,7 +92,6 @@ function plc_table_filter (table_id,pattern_id,and_id) {
   var pattern_area = document.getElementById(pattern_id);
   var pattern_text = pattern_area.value;
   var row_index, row, cells, cell_index, cell, visible;
-  var pattern,i;
   var matching_entries=0;
   var and_button=document.getElementById(and_id);
   var and_if_true=and_button.checked;
@@ -104,8 +99,6 @@ function plc_table_filter (table_id,pattern_id,and_id) {
   // remove whitespaces at the beginning and end
   pattern_text = pattern_text.replace(/[ \t]+$/,"");
   pattern_text = pattern_text.replace(/^[ \t]+/,"");
-  // normnalize to lowercase
-  pattern_text = pattern_text.toLowerCase();
   
   if (pattern_text.indexOf ("&") != -1) {
     pattern_text = pattern_text.replace(/&/," ");
@@ -119,12 +112,17 @@ function plc_table_filter (table_id,pattern_id,and_id) {
     return;
   }
     
-  // var counter=0;
-  //  window.console.log ("entering plc_table_filter " + table_id);
+  var match_attempts=0;
+  var start=(new Date).getTime();
 
-  var re_brackets = new RegExp ('<[^>]*>','g');
-  var patterns = pattern_text.split(" ");
+  // re compile all patterns - ignore case
+  var pattern_texts = pattern_text.split(" ");
+  var patterns=new Array();
+  var i;
+  for (i in pattern_texts) 
+    patterns[i]=new RegExp(pattern_texts[i],"i");
 
+  // scan rows
   for (row_index = 0; row=rows[row_index]; row_index++) {
       cells=row.cells;
     
@@ -135,29 +133,27 @@ function plc_table_filter (table_id,pattern_id,and_id) {
       /* AND mode: all patterns must match */
       visible=true;
       for (i in patterns) {
-       var pattern_matched=false;
-       pattern=new RegExp(patterns[i],"i");
+       var matched=false;
+       var pattern=patterns[i];
        for (cell_index = 0; cell=cells[cell_index]; cell_index++) {
-         var against=cell.innerHTML;
-         against=against.replace(re_brackets,'');
-         //counter++;
-         //window.console.log ("plc_table_filter is matching " + against + " against " + pattern);
+         var against=plc_table_cell_text (cell);
+         match_attempts++;
          if ( against.match(pattern)) {
-           pattern_matched=true;
-           // alert ('AND matched! p='+pattern+' c='+cell.innerHTML);
+           matched=true;
            break;        
          }
        }
-       if ( ! pattern_matched ) visible=false;
+       if ( ! matched ) visible=false;
       }
     } else {
       /* OR mode: any match is good enough */
       visible=false;
       for (cell_index = 0; cell=cells[cell_index]; cell_index++) {
+       var against = cell.plc_table_cell_text(cell);
        for (i in patterns) {
          pattern=patterns[i];
-         //counter++;
-         if (cell.innerHTML.toLowerCase().match(pattern)) {
+         match_attempts++;
+         if (against.match(pattern)) {
            visible=true;
            // alert ('OR matched! p='+pattern+' c='+cell.innerHTML);
            break;
@@ -165,11 +161,16 @@ function plc_table_filter (table_id,pattern_id,and_id) {
        }
       }
     }
-    //window.console.log ("plc_table_filter has done " + counter + " matches");
     plc_table_row_visible(row,visible);
     if (visible) matching_entries +=1;
   }
-  plc_table_tbody_matching(tbody,matching_entries);
+  var end=(new Date).getTime();
+  var ms=end-start;
+  window.console.log ("plc_table_filter: " + 
+                     match_attempts + " matches - " +
+                     matching_entries + " lines - " + ms + " ms");
+  tbody['matching']=matching_entries;
+  tbody['match_attempts']=match_attempts;
   tablePaginater.init(table_id);
 }
 
index 8bb3bfb..a3cf5e8 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 
-  // $Id$
+// $Id$
 
 // Require login
 require_once 'plc_login.php';
@@ -98,6 +98,8 @@ if( !empty( $pcu_ids ) )
 //////////////////// display node info
 
 drupal_set_title("Details for node " . $hostname);
+$local_peer= ! $peer_id;
+
   
 // extra privileges to admins, and (pi||tech) on this site
 $privileges = plc_is_admin () || ( plc_in_site($site_id) && ( plc_is_pi() || plc_is_tech()));
@@ -131,7 +133,7 @@ $tabs["All nodes"]=l_nodes();
 plc_tabs($tabs);
 
 // show gray background on foreign objects : start a <div> with proper class
-$local_peer = $peers->block_start ($peer_id);
+$peers->block_start ($peer_id);
   
 plc_details_start ();
 if ( ! $local_peer) {
@@ -203,9 +205,12 @@ plc_details_line_list ("All site nodes",$nodes_area);
 
 plc_details_end ();
 
+plc_form_start(l_actions(), array('node_id'=>$node_id));
+
 //////////////////////////////////////////////////////////// Tags
 // get tags
 if ( $local_peer ) {
+  
   $tags=$api->GetNodeTags (array('node_id'=>$node_id));
   function get_tagname ($tag) { return $tag['tagname'];}
   $tagnames = array_map ("get_tagname",$tags);
@@ -230,7 +235,25 @@ if ( $local_peer ) {
       plc_table_cell($nodegroup_name);
       plc_table_row_end();
     }
-  plc_table_end("node_tags");
+  
+  $footers=array();
+  if ($privileges) {
+    // remove selected sites
+    // get list of tag names in the node/* category    
+    $all_tags= $api->GetTagTypes( array ("category"=>"node*"), array("tagname","tag_type_id"));
+
+    // xxx cannot use onchange=submit() - would need to somehow pass action name 
+    function tag_selector ($tag) { return array("display"=>$tag['tagname'],"value"=>$tag['tag_type_id']); }
+    $selector=array_map("tag_selector",$all_tags);
+    $add_tag_name=plc_form_select_text("tag_type_id",$selector,"Choose");
+    $add_tag_value=plc_form_text_text("value","",8);
+    $add_tag_submit=plc_form_submit_text("set-tag-on-node","Set Tag");
+
+    $add_tag_footer=plc_table_td_text($add_tag_name).plc_table_td_text($add_tag_value).plc_table_td_text($add_tag_submit);
+    $footers[]= $add_tag_footer;
+  }
+  
+  plc_table_end("node_tags",array('footers'=>$footers));
  }
 
 //////////////////////////////////////////////////////////// slices
@@ -265,9 +288,12 @@ if ( ! $slices  ) {
 //////////////////////////////////////////////////////////// interfaces
 if ( $local_peer ) {
 
+  plc_section ("Interfaces");
   // display interfaces
   if( ! $interfaces ) {
-    echo "<p><span class='plc-warning'>No interface</span>.  Please add an interface to make this a usable PLC node</p>.\n";
+    echo '<p>';
+    plc_warning_text("This node has no interface");
+    echo "Please add an interface to make this a usable PLC node.</p>\n";
   } else {
     $headers=array();
     if ( $privileges ) {
@@ -281,7 +307,6 @@ if ( $local_peer ) {
     $headers["MAC"]="string";
     $headers["bw limit"]="FileSize";
 
-    plc_section('Interfaces');
     $table_options=array('search_area'=>false,"pagesize_area"=>false,'notes_area'=>false);
     plc_table_start("node_interfaces",$headers,2,$table_options);
        
@@ -325,7 +350,9 @@ if ( $local_peer ) {
     plc_table_end("node_interfaces",array("footers"=>$footers));
   }
  }
-      
+
+plc_form_end();
+
 ////////////////////////////////////////////////////////////
 $peers->block_end($peer_id);
 
index 7916444..c60d16a 100644 (file)
@@ -33,6 +33,8 @@ $mysite_id=plc_my_site_id();
 $tabs['My nodes'] = array('url'=>l_nodes(),
                          'values'=>array('site_id'=>plc_my_site_id()),
                          'bubble'=>'Lists nodes on site ' . $mysite_id);
+$tabs['Local nodes'] = array ('url'=>l_nodes_peer('local'),
+                             'bubble' => 'Nodes local to this peer');
 // -------------------- 
 $node_filter=array();
 
index 11bcd15..832a540 100644 (file)
@@ -64,10 +64,10 @@ $slices= $api->GetSlices( $slice_ids, array( "slice_id", "name" ) );
 $keys= $api->GetKeys( $key_ids );
 
 drupal_set_title("Details for account " . $first_name . " " . $last_name);
+$local_peer = ! $peer_id;
 
 $peers = new Peers ($api);
 
-$local_peer = $peers->block_start ($peer_id);
 $is_my_account = plc_my_person_id() == $person_id;
 $privileges = plc_is_admin () || ( plc_in_site($site_id) && plc_is_pi());
 
@@ -126,6 +126,8 @@ $tabs['All Users'] = array ('url'=>l_persons(),
 
 plc_tabs($tabs);
     
+$peers->block_start ($peer_id);
+
 if ($local_peer && $privileges && ! $enabled ) 
   drupal_set_message ("$first_name $last_name is not enabled yet, you can enable her/him with the 'Enable' button below");
 
@@ -170,8 +172,7 @@ if( ! $slices) {
  }
 
 // we don't set 'action', but use the submit button name instead
-plc_form_start(l_actions(), 
-              array("person_id"=>$person_id,));
+plc_form_start(l_actions(), array("person_id"=>$person_id,));
 
 //////////////////// keys
 plc_section ("Keys");
@@ -261,9 +262,9 @@ if ($can_manage_sites) {
   $add_site_left_area=plc_form_select_text("site_id",$selector,"Choose a site to add");
   $add_site_area = $add_site_left_area . $add_site_right_area;
   if ($sites) 
-    $footers[]="<td colspan=3 style='text-align:right'> $remove_sites_area </td>";
+    $footers[]=plc_table_td_text ($remove_sites_area,3,"right");
   // add a new site
-  $footers []="<td colspan=3 style='text-align:right'> $add_site_area </td>";
+  $footers []= plc_table_td_text ($add_site_right_area,3,"right");
  }
 plc_table_end("person_sites",array("footers"=>$footers));
 
index 67a6783..117e29c 100644 (file)
@@ -92,15 +92,15 @@ foreach( $persons as $person ) {
   
 }
 
-// fetches peers and initialize hash peer_id->peer
 drupal_set_title("Details for site " . $sitename);
+$local_peer = ! $peer_id;
   
 // extra privileges to admins, and pi on this site
 $privileges = plc_is_admin () || ( plc_in_site($site_id) && plc_is_pi());
   
 $tabs=array();
 // available actions
-if ( ! $peer_id  && $privileges ) {
+if ( $local_peer  && $privileges ) {
   
   $tabs['Update']=array('url'=>l_site_update($site_id),
                        'bubble'=>"Update details of $sitename");
@@ -151,7 +151,7 @@ plc_details_line("Latitude",$site_lat);
 plc_details_line("Longitude",$site_long);
 plc_details_line("Peer",$peers->peer_link($peer_id));
 
-if ( ! $peer_id ) {
+if ( $local_peer ) {
 
   // Addresses
   if ($addresses) {
index 9a84876..c705c57 100644 (file)
@@ -124,9 +124,9 @@ if ($sites) foreach ($sites as $site) {
   $shortname = $peers->shortname($site['peer_id']);
   plc_table_row_start();
   plc_table_cell($shortname);
-  plc_table_cell (l_site_t($site['site_id'],$site['name']));
+  plc_table_cell (l_site_t($site['site_id'],htmlentities($site['name'])));
   plc_table_cell ($site['login_base']);
-  plc_table_cell ($site['abbreviated_name']);
+  plc_table_cell (htmlentities($site['abbreviated_name']));
   if (plc_is_admin()) {
     plc_table_cell(count($site['node_ids']));
     plc_table_cell(count($site['person_ids']));
diff --git a/planetlab/tags/nodegroup.php b/planetlab/tags/nodegroup.php
new file mode 100644 (file)
index 0000000..7cb1aab
--- /dev/null
@@ -0,0 +1,80 @@
+<?php
+
+// $Id$
+
+// Require login
+require_once 'plc_login.php';
+
+// Get session and API handles
+require_once 'plc_session.php';
+global $plc, $api;
+
+// Print header
+require_once 'plc_drupal.php';
+include 'plc_header.php';
+
+// Common functions
+require_once 'plc_functions.php';
+require_once 'plc_minitabs.php';
+require_once 'plc_tables.php';
+require_once 'plc_details.php';
+//require_once 'plc_forms.php';
+//require_once 'plc_peers.php';
+
+// -------------------- 
+// recognized URL arguments
+$nodegroup_id=intval($_GET['id']);
+if ( ! $nodegroup_id ) { plc_error('Malformed URL - id not set'); return; }
+
+////////////////////
+// Get all columns as we focus on only one entry
+$nodegroups= $api->GetNodeGroups( array($nodegroup_id));
+
+if (empty($nodegroups)) {
+  drupal_set_message ("NodeGroup " . $nodegroup_id . " not found");
+  return;
+ }
+
+$nodegroup=$nodegroups[0];
+$node_ids=$nodegroup['node_ids'];
+$tagname=$nodegroup['tagname'];
+
+# fetch corresponding nodes
+$node_columns = array("hostname","node_id");
+
+$nodes = $api->GetNodes( $node_ids, $node_columns);
+
+$tabs ["All nodegroups"] = array ('url'=>l_nodegroups(),
+                                 'bubble'=>'All nodegroups');
+$tabs ["All tags"] = array ('url'=>l_tags(),
+                           'bubble'=>'All tags');
+$tabs ["Local nodes"] = array ('url'=>l_nodes_peer('local'),
+                            'bubble'=>'All local nodes');
+
+drupal_set_title("Details for node group " . $nodegroup['groupname']);
+plc_tabs($tabs);
+
+plc_details_start();
+plc_details_line ("Node group name",$nodegroup['groupname']);
+plc_details_line ("Based on tag",href(l_tag($nodegroup['tag_type_id']),$tagname));
+plc_details_line("Matching value",$nodegroup['value']);
+plc_details_line("# nodes",count($nodegroup['node_ids']));
+plc_details_end();
+
+// xxx : add & delete buttons would make sense here too
+plc_section("Nodes");
+
+$headers["Hostname"]="string";
+
+plc_table_start("nodegroup_nodes",$headers,0,array('search_width'=>15));
+if ($nodes) foreach ($nodes as $node) {
+  plc_table_row_start ();
+  plc_table_cell ( href (l_node ($node['node_id']),$node['hostname']));
+  plc_table_row_end ();
+}
+
+plc_table_end ("nodegroup_nodes");
+// Print footer
+include 'plc_footer.php';
+
+?>
index e82b2b6..17778b1 100644 (file)
@@ -1,5 +1,7 @@
 <?php
 
+// $Id$
+
 // Require login
 require_once 'plc_login.php';
 
@@ -7,297 +9,71 @@ require_once 'plc_login.php';
 require_once 'plc_session.php';
 global $plc, $api;
 
-
-// Common functions
-require_once 'plc_functions.php';
-require_once 'plc_sorts.php';
-
-// find person roles
-$_person= $plc->person;
-$_roles= $_person['role_ids'];
-
-
-// if sent here from another page remove then redirect
-if( $_GET['remove'] && $_GET['nodegroup_id'] ) {
-  $ng_id= $_GET['nodegroup_id'];
-  $node_id= $_GET['remove'];
-
-  $api->DeleteNodeFromNodeGroup( intval( $node_id ), intval( $ng_id ) );
-
-  header( "location: index.php?id=$node_id" );
-  exit();
-  
-}
-
-
 // Print header
-require_once 'plc_drupal.php'; 
-drupal_set_title('Node Groups');
+require_once 'plc_drupal.php';
 include 'plc_header.php';
 
+// Common functions
+require_once 'plc_functions.php';
+require_once 'plc_minitabs.php';
+require_once 'plc_tables.php';
 
-// if no id display list of nodegroups
-if( !$_GET['id'] && !$_GET['nodegroup_id'] ) {
-  $nodegroup_info= $api->GetNodeGroups( NULL, array( "nodegroup_id", "name", "description" ) );
-
-  echo "<h2>Node Groups</h2>\n
-       <table cellpadding=2><thead><tr><th>Name</th><th>Description</th>";
-
-   // if admin we need to more cells
-   if(  in_array( "10", $_person['role_ids'] ) )
-     echo "<th></th><th></th>";
-   echo "</thead><tbody>";
-
-  foreach( $nodegroup_info as $type ) {
-    echo "<tr><td><a href='/db/nodes/node_groups.php?nodegroup_id=". $type['nodegroup_id'] ."'>". $type['name'] ."</a></td><td>". $type['description'] ."</td>";
-    // if admin display edit/delet links
-    if(  in_array( "10", $_person['role_ids'] ) ) {
-      echo "<td><a href='/db/nodes/node_groups.php?nodegroup_id=". $type['nodegroup_id'] ."'>Edit</a></td>";
-      echo plc_delete_link_button('node_groups.php?del_type=' . $type['nodegroup_id'],
-                                 $type['name']);
-      echo "</td>";
-    }
-    echo "</tr>\n";
-
-  }
-
-  echo "</tbody></table>\n";
-
-}
-// if id is set then show nodegroup info
-elseif( $_GET['id'] ) {
-  $nodegroup_id= $_GET['id'];
-
-  $nodegroup_info= $api->GetNodeGroups( array( intval( $nodegroup_id ) ), 
-                                       array( "name", "nodegroup_id", "node_ids" ) );
-  $node_info= $api->GetNodes( $nodegroup_info[0]['node_ids'], array( "node_id", "hostname" ) );
-
-  //display info 
-  echo "<h2>Node Group ". $nodegroup_info[0]['name'] ."</h2>\n";
-
-  if( empty( $nodegroup_info[0]['node_ids'] ) )
-    echo "<p>No nodes in node group.";
-  else {
-    echo "<table cellpadding=2><thead><tr><th>Hostname</th>";
-
-    // if admin need more cells
-    if( in_array( 10, $_roles ) ) 
-      echo "<th>Remove</th>";
-
-    echo "</tr>\n";
-
-    foreach( $node_info as $node ) {
-      echo "<tr><td><a href='/db/nodes/index.php?id=". $node['node_id'] ."'>". $node['hostname'] ."</a></td>";
-
-      if( in_array( 10, $_roles ) )
-        echo "<td><a href='/db/nodes/node_groups.php?remove=". $node['node_id'] ."&nodegroup_id=". $nodegroup_id ."'>remove</a></td>";
-
-      echo "</tr>";
+// -------------------- 
+// recognized URL arguments
+$pattern=$_GET['pattern'];
 
-    }
+// --- decoration
+$title="Nodegroups";
+$tabs=array();
+$tabs['Tags'] = array('url'=>l_tags(),
+                     'bubble'=>'Lists all known tag types');
+// -------------------- 
+$node_filter=array();
 
-    echo "</tbody></table>\n";
 
-  }
+// fetch objs
+$nodegroup_columns=array("nodegroup_id","groupname","tagname","value","node_ids");
 
-}
-// if no id add else update
-elseif( $_GET['add'] ) {
-  // add node group and redirect to update nodes for it
 if( $_POST['add_sub'] ) {
-    $name= $_POST['name'];
-    $description= $_POST['description'];
+// server-side filtering - set pattern in $_GET for filtering on hostname
+if ($pattern) {
+  $nodegroup_filter['groupname']=$pattern;
+  $title .= " matching " . $pattern;
} else {
+  $nodegroup_filter['groupname']="*";
+ }
 
-    $fields= array( 'name'=>$name, 'description'=>$description );
+// go
+$nodegroups=$api->GetNodeGroups($nodegroup_filter,$nodegroup_columns);
 
-    // add it
-    $api->AddNodeGroup( $fields );
+// --------------------
+drupal_set_title($title);
 
-    // get nodegroup_id
-    $group_info= $api->GetNodeGroups( array( $name ), array( "nodegroup_id" ) );
+plc_tabs($tabs);
 
-    // redirect
-    header( "location: node_groups.php?id=". $group_info[0]['nodegroup_id'] );
-    exit();
-
-  }
-  
-  // add form
-  echo "<form method=post action='node_groups.php?add=1'>";
-  echo "<h2>Create Node Group</h2>\n";
-  echo "<table><tbody>\n";
-  echo "<tr><th>Name: </th><td><input type=text name='name' value=''></td></tr>\n<tr><th>Description: </th><td><input type=text name='description' size=50></td></tr>\n";
-  echo "</tbody></table>\n";
-
-  echo "<br /><input type=submit value='Add Node Group' name='add_sub'>\n</form\n";
-
-  echo "<p><a href='index.php'>Back to Node Index</a>\n";
-  
-}
-elseif( $_GET['nodegroup_id'] )
-{
-  // get node group id
-  $node_group_id= $_GET['nodegroup_id'];
+if ( ! $nodegroups ) {
+  drupal_set_message ('No node group found');
+  return;
+ }
   
-  // if add node submitted, add
-  if( $_POST['add'] )
-  {
-    $add_nodes= $_POST['add_nodes'];
-
-    // add nodes to node group
-    foreach( $add_nodes as $add_node )
-    {
-      $api->AddNodeToNodeGroup( intval( $add_node ), intval( $node_group_id ) );
-
-    }
-    
-  }
-
-  // if remove node submitted, remove
-  if( $_POST['remove'] )
-  {
-    $rem_nodes= $_POST['rem_nodes'];
-
-    // remove nodes from node group
-    foreach( $rem_nodes as $rem_node )
-    {
-      $api->DeleteNodeFromNodeGroup( intval( $rem_node ), intval( $node_group_id ) );
-
-    }
-    
-  }
-
-  // update name and description
-  $name= $_POST['name'];
-  $description= $_POST['description'];
-
-  $fields= array();
-
-  if( $name )
-    $fields['name']= $name;
-
-  if( $description )
-    $fields['description']= $description;
-
-  // api call
-  if( !empty( $fields ) )
-    $api->UpdateNodeGroup( intval( $node_group_id ), $fields );
-
-  // get node_group info
-  $group_info= $api->GetNodeGroups( array( intval( $node_group_id ) ),
-                                   array( "node_ids", "name", "conf_file_ids", "description" ) );
-
-  $node_ids = $group_info[0]['node_ids'];
-  $name = $group_info[0]['name'];
-  $conf_file_ids = $group_info[0]['conf_file_ids'];
-  $description = $group_info[0]['description'];
-
-  // get node info
-  if( !empty( $node_ids ) )
-    $node_info= $api->GetNodes( $node_ids, 
-                               array( "hostname", "node_id" ) );
-
-  // get site names and ids
-  $site_info= $api->GetSites( NULL, array( "site_id", "name" ) );
-  sort_sites( $site_info );
-
-  // if site_id is in post use it, if not use the user's primary
-  if( $_POST['site_id'] )
-    $site_id= $_POST['site_id'];
-  else
-    $site_id= $_person['site_ids'][0];
-
-  // get site nodes for $site_id
-  $sid= intval( $site_id );
-  $site_node_info= $api->GetSites( array( $sid ), array( "node_ids" ) );
-  $site_nodes= $site_node_info[0]['node_ids'];
-
-
-  // gets all node_ids from site that arent already associated with the node group
-  foreach( $site_nodes as $snode) {
-    if( !in_array( $snode, $node_ids ) )
-      $snodes[]= $snode;
-
-  }
-
-  // Get node info from new list
-  if( !empty( $snodes ) )
-    $snode_info= $api->GetNodes( $snodes, array( "hostname", "node_id" ) );
-
-
-  // start form
-  echo "<form action='node_groups.php?nodegroup_id=$node_group_id' method=post name='fm'>\n";
-  echo "<h2>Update Node Group id $name</h2>\n";
-
-  echo "Select a site to add nodes from.<br />\n";
-  echo "<select name='site_id' onChange='submit()'>\n";
-
-  foreach( $site_info as $site ) {
-    echo "<option value=". $site['site_id'];
-    if( $site['site_id'] == $site_id )
-      echo " selected";
-    echo ">". $site['name'] ."</option>\n";
-    
-  }
-
-  echo "</select>\n";
-
-  echo "<hr />\n";
-
-  // show all availible nodes at $site_id
-  if( $snode_info ) {
-    echo $added;
-    echo "<table><tbody>\n";
-    
-    foreach( $snode_info as $snodes ) {
-      echo "<tr><td><input type=checkbox name='add_nodes[]' value=". $snodes['node_id'] ."> </td><td> ". $snodes['hostname'] ." </td></tr>\n";
-    
-    }
-    
-    echo "</tbody></table>\n";
-    echo "<p><input type=submit value='Add Nodes' name='add'>\n";
-
-  }
-  else
-    echo "<p>All nodes on site already added.\n";
-
-  echo "<hr />\n";
-
-  // show all nodes currently associated
-  echo $removed;
-  echo "<h5>Nodes already associated with node group</h5>\n";
-  if( $node_info ) {
-    echo "<u>Check boxes of nodes to remove:</u>\n";
-    echo "<table><tbody>\n";
-
-    foreach( $node_info as $node ) {
-      echo "<tr><td><input type=checkbox name='rem_nodes[]' value=". $node['node_id'] ."> </td><td> ". $node['hostname'] ." </td></tr>\n";
-    
-    }
-    
-    echo "</tbody></table>\n";
-    echo "<p><input type=submit value='Remove Nodes' name='remove'>\n";
-    
-  }
-  else
-    echo "<p>No nodes associated with node group.\n";
-
-  echo "<hr />\n";
-
-  echo "<table><tbody>\n";
-  echo "<tr><th>Name: </th><td><input type=text name='name' value='$name'></td></tr>\n";
-  echo "<tr><th>Description: </th><td><input type=text name='description' value='$description' size=50></td></tr>\n";
-
-  echo "</tbody></table>\n";
-  echo "<br /><input type=submit value='Update Node Group' name='update'>\n";
-
-  echo "</form>\n";
-
-  echo "<br /><a href='/db/nodes/node_groups.php'>Back to Node Group Index</a>\n";
-
 
+$headers = array ( "Name"=>"string",
+                  "Tag"=>"string",
+                  "Value"=>"string",
+                  "Nodes"=>"int");
+
+# initial sort on groupname
+plc_table_start("nodegroups",$headers,0);
+
+foreach ($nodegroups as $nodegroup) {
+  plc_table_row_start();
+  plc_table_cell (href(l_nodegroup($nodegroup['nodegroup_id']),$nodegroup['groupname']));
+  plc_table_cell ($nodegroup['tagname']);
+  plc_table_cell ($nodegroup['value']);
+  plc_table_cell (count($nodegroup['node_ids']));
+  plc_table_row_end();
 }
 
+plc_table_end("nodegroups");
 
 // Print footer
 include 'plc_footer.php';