---
 src/app/controllers/image_controller.rb      |   85 +++++++++++++++++++++++
 src/app/controllers/instance_controller.rb   |    6 +-
 src/app/controllers/pool_controller.rb       |   51 +++++++++++++-
 src/app/helpers/image_helper.rb              |    2 +
 src/app/models/image.rb                      |   37 ++++++++++
 src/app/models/instance.rb                   |   32 +++++++++
 src/app/views/image/show.html.erb            |   85 +++++++++++++++++++++++
 src/app/views/instance/new.html.erb          |   96 +++++++++++++++++++++++---
 src/app/views/layouts/_main_nav.html.erb     |    1 +
 src/app/views/pool/images.html.erb           |   20 ------
 src/app/views/pool/show.html.erb             |   89 +++++++++++++-----------
 src/test/functional/image_controller_test.rb |    8 ++
 src/test/unit/helpers/image_helper_test.rb   |    4 +
 13 files changed, 442 insertions(+), 74 deletions(-)
 create mode 100644 src/app/controllers/image_controller.rb
 create mode 100644 src/app/helpers/image_helper.rb
 create mode 100644 src/app/views/image/show.html.erb
 delete mode 100644 src/app/views/pool/images.html.erb
 create mode 100644 src/test/functional/image_controller_test.rb
 create mode 100644 src/test/unit/helpers/image_helper_test.rb

diff --git a/src/app/controllers/image_controller.rb 
b/src/app/controllers/image_controller.rb
new file mode 100644
index 0000000..0c15eb5
--- /dev/null
+++ b/src/app/controllers/image_controller.rb
@@ -0,0 +1,85 @@
+#
+# Copyright (C) 2009 Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA  02110-1301, USA.  A copy of the GNU General Public License is
+# also available at http://www.gnu.org/copyleft/gpl.html.
+
+# Filters added to this controller apply to all controllers in the application.
+# Likewise, all the methods added will be available for all controllers.
+
+require 'util/taskomatic'
+
+class ImageController < ApplicationController
+  before_filter :require_user
+
+  def index
+  end
+
+  def show
+    # FIXME: check on privilege IMAGE_VIEW which currently doesn't exist
+    #require_privilege(Privilege::POOL_VIEW, @pool)
+    # only displays empty table
+  end
+
+  def images_paginate
+    # FIXME: check on privilege IMAGE_VIEW which currently doesn't exist
+    #require_privilege(Privilege::POOL_VIEW, @pool)
+
+    # datatables sends pagination in format:
+    #   iDisplayStart - start index
+    #   iDisplayLength - num of recs
+    # => we need to count page num
+    page = params[:iDisplayStart].to_i / Image::RECS_PER_PAGE
+
+    if params[:mode].to_s == 'simple'
+      simple_mode = true
+      cols = Image::COLUMNS_SIMPLE
+      default_order_col = 1
+    else
+      cols = Image::COLUMNS
+      simple_mode = false
+      default_order_col = 2
+    end
+
+    # FIXME: check sortable on selected column
+    order_col_rec = cols[params[:iSortCol_0].to_i]
+    order_col = cols[default_order_col] unless order_col_rec && 
order_col_rec[:opts][:searchable]
+    order = order_col[:id] + " " + (params[:sSortDir_0] == 'desc' ? 'desc' : 
'asc')
+
+    @images = Image.search_filter(params[:sSearch]).paginate(
+      :page => page + 1, 
+      :include => :instances,
+      :order => order
+    )
+
+    expand_button_html = "<img src='/images/dir_closed.png'>"
+
+    data = @images.map do |i|
+      if simple_mode
+        [i.id, i.name, i.architecture, i.instances.size]
+      else
+        [i.id, expand_button_html, i.name, i.architecture, i.instances.size, 
"TODO: some description here?"]
+      end
+    end
+
+    render :json => {
+      :sEcho => params[:sEcho],
+      :iTotalRecords => @images.total_entries,
+      :iTotalDisplayRecords => @images.total_entries,
+      :aaData => data
+    }
+  end
+
+end
diff --git a/src/app/controllers/instance_controller.rb 
b/src/app/controllers/instance_controller.rb
index 0008c06..e73d7cd 100644
--- a/src/app/controllers/instance_controller.rb
+++ b/src/app/controllers/instance_controller.rb
@@ -38,9 +38,9 @@ class InstanceController < ApplicationController
   end
 
   def new
-    @instance = Instance.new({:pool_id => params[:id]})
-    @pool = Pool.find(params[:id])
-    require_privilege(Privilege::INSTANCE_MODIFY,@pool)
+    @instance = Instance.new(params[:instance])
+    require_privilege(Privilege::POOL_VIEW, @instance.pool) if @instance.pool
+    @pools = Pool.list_for_user(@current_user, Privilege::POOL_VIEW)
   end
 
   def create
diff --git a/src/app/controllers/pool_controller.rb 
b/src/app/controllers/pool_controller.rb
index 2ae0988..5613ddd 100644
--- a/src/app/controllers/pool_controller.rb
+++ b/src/app/controllers/pool_controller.rb
@@ -78,9 +78,58 @@ class PoolController < ApplicationController
   def delete
   end
 
-  def images
+  def instances_paginate
     @pool = Pool.find(params[:id])
     require_privilege(Privilege::POOL_VIEW, @pool)
+
+    # datatables sends pagination in format:
+    #   iDisplayStart - start index
+    #   iDisplayLength - num of recs
+    # => we need to count page num
+    page = params[:iDisplayStart].to_i / Instance::RECS_PER_PAGE
+
+    order_col_rec = Instance::COLUMNS[params[:iSortCol_0].to_i]
+    order_col = Instance::COLUMNS[2] unless order_col_rec && 
order_col_rec[:opts][:searchable]
+    order = order_col[:id] + " " + (params[:sSortDir_0] == 'desc' ? 'desc' : 
'asc')
+
+    @instances = Instance.search_filter(params[:sSearch]).paginate(
+      :page => page + 1, 
+      :order => order,
+      :conditions => {:pool_id => @pool.id}
+    )
+
+    # FIXME: default stylesheet redefines link color
+    details_html = "<a href='#' class='details_link'>Details</a>"
+
+    render :json => {
+      :sEcho => params[:sEcho],
+      :iTotalRecords => @instances.total_entries,
+      :iTotalDisplayRecords => @instances.total_entries,
+      :aaData => @instances.map {|i| [i.id, "", i.name, details_html, i.state, 
i.hardware_profile.name, i.image.name]}
+    }
   end
 
+
+  def accounts_for_pool
+    @pool =  Pool.find(params[:pool_id])
+    require_privilege(Privilege::ACCOUNT_VIEW,@pool)
+    @cloud_accounts = []
+    all_accounts = CloudAccount.list_for_user(@current_user, 
Privilege::ACCOUNT_ADD)
+    all_accounts.each {|account|
+      @cloud_accounts << account unless @pool.cloud_accounts.map{|x| 
x.id}.include?(account.id)
+    }
+  end
+
+  def add_account
+    @pool = Pool.find(params[:pool])
+    @cloud_account = CloudAccount.find(params[:cloud_account])
+    require_privilege(Privilege::ACCOUNT_ADD,@pool)
+    require_privilege(Privilege::ACCOUNT_ADD,@cloud_account)
+    Pool.transaction do
+      @pool.cloud_accounts << @cloud_account unless 
@pool.cloud_accounts.map{|x| x.id}.include?(@cloud_account.id)
+      @pool.save!
+      @pool.populate_realms_and_images([...@cloud_account])
+    end
+    redirect_to :action => 'show', :id => @pool.id
+  end
 end
diff --git a/src/app/helpers/image_helper.rb b/src/app/helpers/image_helper.rb
new file mode 100644
index 0000000..b1092d1
--- /dev/null
+++ b/src/app/helpers/image_helper.rb
@@ -0,0 +1,2 @@
+module ImageHelper
+end
diff --git a/src/app/models/image.rb b/src/app/models/image.rb
index 86806a4..6591823 100644
--- a/src/app/models/image.rb
+++ b/src/app/models/image.rb
@@ -20,6 +20,11 @@
 # Likewise, all the methods added will be available for all controllers.
 
 class Image < ActiveRecord::Base
+  RECS_PER_PAGE = 15
+
+  cattr_reader :per_page
+  @@per_page = RECS_PER_PAGE
+
   has_many :instances
   belongs_to :provider
 
@@ -43,6 +48,38 @@ class Image < ActiveRecord::Base
 
   validates_presence_of :architecture, :if => :provider
 
+  # used to get sorting column in controller and in view to generate datatable 
definition and
+  # html table structure
+  COLUMNS = [
+    {:id => 'id', :header => '<input type="checkbox" id="image_id_all" 
onclick="checkAll(event)">', :opts => {:checkbox_id => 'image_id', :searchable 
=> false, :sortable => false, :width => '1px', :class => 'center'}},
+    {:id => 'expand_button', :header => '', :header => '', :opts => 
{:searchable => false, :sortable => false, :width => '1px'}},
+    {:id => 'name', :header => 'Name', :opts => {:width => "30%"}},
+    {:id => 'architecture', :header => 'Architecture', :opts => {:width => 
"10%"}},
+    {:id => 'instances', :header => 'Instances', :opts => {:sortable => false, 
:width => "10%"}},
+    {:id => 'details', :header => '', :opts => {:sortable => false, :visible 
=> false, :searchable => false}},
+  ]
+
+  COLUMNS_SIMPLE = [
+    {:id => 'id', :header => '', :opts => {:visible => false, :searchable => 
false, :sortable => false, :width => '1px', :class => 'center'}},
+    {:id => 'name', :header => 'Name', :opts => {:width => "50%"}},
+    {:id => 'architecture', :header => 'Architecture', :opts => {:width => 
"30%"}},
+    {:id => 'instances', :header => 'Instances', :opts => {:sortable => false, 
:width => "20%"}},
+  ]
+
+  SEARCHABLE_COLUMNS = %w(name architecture)
+
+  # FIXME: duplicit code with definition in app/models/image.rb
+  # what's the best strategy? inherit from same class, include module,...?
+  named_scope :search_filter, lambda {|str|
+    if str.to_s.empty?
+      {:conditions => {}}
+    else
+      $stderr.puts SEARCHABLE_COLUMNS.map {|c| "#{c} like ?"}.join(" OR ")
+      $stderr.puts Array.new(SEARCHABLE_COLUMNS.size, "%#{str}%").inspect
+      {:conditions => [SEARCHABLE_COLUMNS.map {|c| "#{c} like ?"}.join(" OR 
")] + Array.new(SEARCHABLE_COLUMNS.size, "%#{str}%")}
+    end
+  }
+
 
   def provider_image?
     !provider.nil?
diff --git a/src/app/models/instance.rb b/src/app/models/instance.rb
index fa89844..9cb6c62 100644
--- a/src/app/models/instance.rb
+++ b/src/app/models/instance.rb
@@ -20,6 +20,11 @@
 # Likewise, all the methods added will be available for all controllers.
 
 class Instance < ActiveRecord::Base
+  RECS_PER_PAGE = 15
+
+  cattr_reader :per_page
+  @@per_page = RECS_PER_PAGE
+
   belongs_to :pool
   belongs_to :cloud_account
 
@@ -56,6 +61,33 @@ class Instance < ActiveRecord::Base
      :in => [STATE_NEW, STATE_PENDING, STATE_RUNNING,
              STATE_SHUTTING_DOWN, STATE_STOPPED, STATE_CREATE_FAILED]
 
+  # used to get sorting column in controller and in view to generate datatable 
definition and
+  # html table structure
+  COLUMNS = [
+    {:id => 'id', :header => '<input type="checkbox" id="image_id_all" 
onclick="checkAll(event)">', :opts => {:checkbox_id => 'image_id', :searchable 
=> false, :sortable => false, :width => '1px', :class => 'center'}},
+    {:id => 'actions', :header => 'Actions', :opts => {:width => "15%", 
:sortable => false}},
+    {:id => 'name', :header => 'Name', :opts => {:width => "25%"}},
+    {:id => 'details', :header => '', :opts => {:width => "10%", :sortable => 
false, :searchable => false}},
+    {:id => 'state', :header => 'State', :opts => {:width => "15%"}},
+    {:id => 'hwprofile', :header => 'HW profile', :opts => {:width => "15%"}},
+    {:id => 'image', :header => 'Image', :opts => {:sortable => false}},
+  ]
+
+  SEARCHABLE_COLUMNS = %w(name state)
+
+  # FIXME: duplicit code with definition in app/models/image.rb
+  # what's the best strategy? inherit from same class, include module,...?
+  named_scope :search_filter, lambda {|str|
+    if str.to_s.empty?
+      {:conditions => {}}
+    else
+      $stderr.puts SEARCHABLE_COLUMNS.map {|c| "#{c} like ?"}.join(" OR ")
+      $stderr.puts Array.new(SEARCHABLE_COLUMNS.size, "%#{str}%").inspect
+      {:conditions => [SEARCHABLE_COLUMNS.map {|c| "#{c} like ?"}.join(" OR 
")] + Array.new(SEARCHABLE_COLUMNS.size, "%#{str}%")}
+    end
+  }
+
+
   def get_action_list(user=nil)
     # return empty list rather than nil
     # FIXME: not handling pending state now -- only current state
diff --git a/src/app/views/image/show.html.erb 
b/src/app/views/image/show.html.erb
new file mode 100644
index 0000000..e25bd86
--- /dev/null
+++ b/src/app/views/image/show.html.erb
@@ -0,0 +1,85 @@
+<script type="text/javascript">
+
+  function fnOpenClose() {
+    $('td img', dataTable_images_table.fnGetNodes() ).each( function () {
+      $(this).click( function () {
+        var nTr = this.parentNode.parentNode;
+        if ( this.src.match('dir_open') )
+        {
+          /* This row is already open - close it */
+          this.src = "/images/dir_closed.png";
+          /* fnClose doesn't do anything for server-side processing - do it 
ourselves :-) */
+          var nRemove = $(nTr).next()[0];
+          nRemove.parentNode.removeChild( nRemove );
+        }
+        else
+        {
+          /* Open this row */
+          this.src = "/images/dir_open.png";
+          dataTable_images_table.fnOpen( nTr, 
dataTable_images_table.fnGetData(nTr)[5], 'details' );
+        }
+      });
+    });
+  }
+ 
+  function getCheckedRows() {
+    return $('input[name="image_id[]"]:checked', 
dataTable_images_table).length;
+  }
+  
+  function showButtons() {
+    getCheckedRows();
+    $('input[name="create_image"]').attr('disabled', getCheckedRows() != 1);
+  }
+  
+  function checkRow(ev) {
+    var box = $('input[name="image_id[]"]', ev.target.parentNode);
+    if ($(ev.target).attr('name') != "image_id[]")
+      box.attr('checked', !box.attr('checked'));
+    showButtons();
+  }
+
+  function checkAll(ev) {
+    $('input[name="image_id[]"]', dataTable_images_table).attr('checked', 
$(ev.target).attr('checked'))
+  }
+
+  function drawCallback() {
+    $('#image_id_all').attr('checked', false);
+    fnOpenClose();
+  }
+
+  function createInstance() {
+    var selected_row = $('input[name="image_id[]"]:checked', 
dataTable_images_table);
+    location.href = '<%= url_for(:controller => "instance", :action => "new") 
%>?instance[image_id]=' + selected_row.attr('value');
+  }
+</script>
+
+<%= datatable(
+  Image::COLUMNS.map {|c| c[:opts]}, 
+  {
+    :table_dom_id => 'images_table',
+    :per_page => Image::RECS_PER_PAGE, 
+    :sort_by => "[2, 'asc']", 
+    :serverside => true,
+    :ajax_source => url_for(:controller => 'image', :action => 
'images_paginate'),
+    :append => ".fnSetFilteringDelay()",
+    :persist_state => false,
+    :click_callback => "function(ev) {checkRow(ev);}",
+    :draw_callback => "drawCallback",
+  }
+) %>
+  <div style="padding:20px">
+    <input type="button" value="Create instance" name="create_image" 
disabled=true onclick="createInstance()">
+  </div>
+  <table class="datatable display" id="images_table">
+    <thead>
+      <tr>
+        <% Image::COLUMNS.each do |c| %>
+          <%= "<th>#{c[:header]}</th>" %>
+        <% end %>
+      </tr>
+    </thead>
+    <tbody>
+  </tbody>
+</table>
+
+
diff --git a/src/app/views/instance/new.html.erb 
b/src/app/views/instance/new.html.erb
index 986959a..13077be 100644
--- a/src/app/views/instance/new.html.erb
+++ b/src/app/views/instance/new.html.erb
@@ -2,28 +2,102 @@
   <%= error_messages_for 'instance' %>
 
   <h2>Add a New Instance</h2><br />
-  <% form_tag :action => 'create' do-%>
+  <% form_tag({:action => 'create'}, 
+              :id => "instance_form") do-%>
   <ul>
     <li><label>Name<span>Name for this new Instance</span></label><%= 
text_field :instance, :name, :class => "txtfield" %></li>
-    <% if @pool.hardware_profiles.size > 0 %>
+
+    <li><label>Image<span>Choose a bundled image to use</span></label>
+    <input type="button" style="cursor:pointer" onclick="showImages(event)" 
name="image_selector" value="<%= @instance.image ? @instance.image.name : 
"click to select image"%>"/>
+    </li>
+    <input type=hidden name="instance[image_id]" value="<%= @instance.image ? 
@instance.image.id : '' %>">
+
+    <li><label>Pool<span>Pick your pool</span></label>
+      <%= select("instance", "pool_id",
+                 @pools.collect {|p| [ p.name, p.id ] },
+                 { :include_blank => true },
+                 {:onchange => "poolSelected(this)"}) %>
+    </li>
+
+    <% if @instance.pool and @instance.pool.hardware_profiles.size > 0 %>
       <li><label>Hardware Profile<span>Pick your hardware 
profile</span></label>
         <%= select("instance", "hardware_profile_id",
-                   @pool.hardware_profiles.collect {|p| [ p.name, p.id ] },
+                   @instance.pool.hardware_profiles.collect {|p| [ p.name, 
p.id ] },
                    { :include_blank => true }) %>
       </li>
     <% end %>
-    <% if @pool.images.size > 0 %>
-      <li><label>Image<span>Choose a bundled image to use</span></label>
-        <%= select("instance", "image_id", @pool.images.collect {|i| [ 
truncate(i.name, 29, '...'), i.id ] }, { :include_blank => true }) %>
-      </li>
-    <% end %>
-    <% if @pool.realms.size > 0 %>
+    <% if @instance.pool and @instance.pool.realms.size > 0 %>
       <li><label>Realm<span>Choose a realm</span></label>
-        <%= select("instance", "front_end_realm", @pool.realms, { 
:include_blank => false }) %>
+        <%= select("instance", "front_end_realm", @instance.pool.realms, { 
:include_blank => false }) %>
       </li>
     <% end %>
   </ul>
-    <%= hidden_field :instance,  :pool_id %>
     <%= submit_tag "Save", :class => "submit" %>
     <% end %>
+  </div>
+
+
+
+<script type="text/javascript">
+  function showImages(ev) {
+    $("#images_table_wrapper").css('display', 'block');
+    images_dialog = $("#images_table_wrapper").dialog({
+      title: "Select image for new instance",
+      dialogClass: 'flora', 
+      width: 600, 
+      height: 500, 
+      modal: true, 
+      overlay: {opacity: 0.2, background: "black"}
+    });
+  }
+
+  function selectImage(ev) {
+    var image_id = dataTable_images_table.fnGetData(ev.target.parentNode)[0];
+    var image_name = dataTable_images_table.fnGetData(ev.target.parentNode)[1];
+    $("#images_table_wrapper").css('display', 'none');
+    $("#images_table_wrapper").dialog('close');
+    $('input[name="image_selector"]').attr('value', image_name);
+    $('input[name="instance[image_id]"]').attr('value', image_id);
+  }
+
+  function poolSelected(field) {
+    // TODO: ajax load would be nicer, but complete page reload is easy to 
implement
+    location.href = '<%= url_for(:action => "new") %>?' + 
$("#instance_form").serialize();
+    //var url = '<%= url_for(:controller => 'pool', :action => 
:profiles_and_realms) %>/' + field.value;
+    //$.getJSON(url, function(data) {
+    //  $("#instance_hardware_profile_id").find('option').remove().end();
+    //  $(data.hardware_profiles).each(function(rec) { 
+    //    $("#instance_hardware_profile_id").append('<select 
value="'+rec.id+'">'+rec.name+'</select>');
+    //  });
+    //  $(data.front_end_realm).each(function(rec) { 
+    //    $("#instance_front_end_realm").append('<select 
value="'+rec+'">'+rec+'</select>');
+    //  });
+    //});
+  }
+</script>
+
+<%= datatable(
+  Image::COLUMNS_SIMPLE.map {|c| c[:opts]}, 
+  {
+    :table_dom_id => 'images_table',
+    :per_page => Image::RECS_PER_PAGE, 
+    :sort_by => "[2, 'asc']", 
+    :serverside => true,
+    :ajax_source => url_for(:controller => 'image', :action => 
'images_paginate') + "?mode=simple",
+    :append => ".fnSetFilteringDelay()",
+    :click_callback => "function(event) {selectImage(event)}",
+  }
+) %>
+<div style="display:none" id="images_table_wrapper">
+  <table class="datatable display" id="images_table">
+    <thead>
+      <tr>
+        <% Image::COLUMNS_SIMPLE.each do |c| %>
+          <%= "<th>#{c[:header]}</th>" %>
+        <% end %>
+      </tr>
+    </thead>
+    <tbody>
+  </tbody>
+</table>
 </div>
diff --git a/src/app/views/layouts/_main_nav.html.erb 
b/src/app/views/layouts/_main_nav.html.erb
index 0155bd6..d18ac48 100644
--- a/src/app/views/layouts/_main_nav.html.erb
+++ b/src/app/views/layouts/_main_nav.html.erb
@@ -1,3 +1,4 @@
+<%=link_to "View images", {:controller => "image", :action => "show"}, :class 
=> "actionlink" %>
 <%=link_to "Add a provider", {:controller => "provider", :action => "new"}, 
:class => "actionlink" %>
 
 <%=link_to "Add a pool",     {:controller => "pool", :action => "new"}, :class 
=> "actionlink" %>
diff --git a/src/app/views/pool/images.html.erb 
b/src/app/views/pool/images.html.erb
deleted file mode 100644
index e0187a8..0000000
--- a/src/app/views/pool/images.html.erb
+++ /dev/null
@@ -1,20 +0,0 @@
-<% if @pool.images.size == 0 %>
-<h1>There are no images to display</h1>
-<% else %>
-    <table>
-      <thead>
-        <tr>
-        <th scope="col">Name</th>
-          <th scope="col">Arch</th>
-        </tr>
-      </thead>
-      <tbody>
-  <%[email protected] {|image| %>
-        <tr>
-          <td><%= image.name %></td>
-          <td><%= image.architecture %></td>
-        </tr>
-      <% } %>
-    </tbody>
-  </table>
-<% end %>
\ No newline at end of file
diff --git a/src/app/views/pool/show.html.erb b/src/app/views/pool/show.html.erb
index ef637f1..7a4ce39 100644
--- a/src/app/views/pool/show.html.erb
+++ b/src/app/views/pool/show.html.erb
@@ -1,42 +1,53 @@
-<% if @instances.size == 0 %>
-<h1>There are no instances to display</h1>
-<% else %>
-  <table>
-    <thead>
-      <tr>
-      <th scope="col">Actions</th>
-      <th scope="col">Name</th>
-      <th scope="col">State</th>
-      <th scope="col">Hardware Profile</th>
-      <th scope="col">Image</th>
-      </tr>
-    </thead>
-    <tbody>
-      <%[email protected] {|instance| %>
-        <tr>
-          <td>
-            <ul class="instance_action_list">
-            <%instance.get_action_list.each {|action|%>
-              <li>
-              <%= link_to action, :controller => "instance",
-                                  :action => "instance_action",
-                                  :id => instance,
-                                 :instance_action => action %>
-              </li>
-           <% } %>
-            </ul>
-          </td>
-          <td><%= instance.name %></td>
-          <td><%= instance.state %></td>
-          <td><%= instance.hardware_profile.name %></td>
-          <td><%= instance.image.name %></td>
-        </tr>
-      <% } %>
-    </tbody>
-  </table>
-<% end %>
-<%= link_to "Add a new instance", {:controller => "instance", :action => 
"new", :id => @pool}, :class=>"actionlink"%>
+<%= datatable(
+  Instance::COLUMNS.map {|c| c[:opts]}, 
+  {
+    :table_dom_id => 'instances_table',
+    :per_page => Instance::RECS_PER_PAGE, 
+    :sort_by => "[3, 'asc']", 
+    :serverside => true,
+    :ajax_source => url_for(:controller => 'pool', :action => 
'instances_paginate') + "/#[email protected]}",
+    :append => ".fnSetFilteringDelay()",
+    :persist_state => false,
+    :click_callback => "function(ev) {clickRow(ev);}",
+  }
+) %>
+<table class="datatable display" id="instances_table">
+  <thead>
+    <tr>
+        <% Instance::COLUMNS.each do |c| %>
+          <%= "<th>#{c[:header]}</th>" %>
+        <% end %>
+    </tr>
+  </thead>
+  <tbody>
+  </tbody>
+</table>
+<script type="text/javascript">
+  function showInstanceDetailsDialog() {
+    images_dialog = $("<div>TODO: show dialog</div>").dialog({
+      title: "Instance details",
+      dialogClass: 'flora', 
+      width: 600, 
+      height: 300, 
+      modal: true, 
+      overlay: {opacity: 0.2, background: "black"}
+    });
+  }
+
+  function clickRow(ev) {
+    var box = $('input[name="image_id[]"]', ev.target.parentNode);
+    if ($(ev.target).hasClass('details_link')) showInstanceDetailsDialog();
+    if ($(ev.target).attr('name') != "image_id[]")
+      box.attr('checked', !box.attr('checked'));
+  }
+
+  function checkAll(ev) {
+    $('input[name="image_id[]"]', dataTable_instances_table).attr('checked', 
$(ev.target).attr('checked'))
+  }
+
+</script>
+
+<%= link_to "Add a new instance", {:controller => "instance", :action => 
"new", "instance[pool_id]" => @pool}, :class=>"actionlink"%>
 <%= link_to "User access",  {:controller => "permissions", :action => "list", 
:pool_id => @pool.id}, :class=>"actionlink" if has_view_perms? %>
 <%= link_to "Hardware Profiles",  {:action => "hardware_profiles", :id => 
@pool.id}, :class=>"actionlink"%>
-<%=link_to "View Images", {:controller => "pool", :action => "images", :id => 
@pool}, :class => "actionlink" %>
 <%= link_to "Realms",  {:action => "realms", :id => @pool.id}, 
:class=>"actionlink"%>
diff --git a/src/test/functional/image_controller_test.rb 
b/src/test/functional/image_controller_test.rb
new file mode 100644
index 0000000..73b754b
--- /dev/null
+++ b/src/test/functional/image_controller_test.rb
@@ -0,0 +1,8 @@
+require 'test_helper'
+
+class ImageControllerTest < ActionController::TestCase
+  # Replace this with your real tests.
+  test "the truth" do
+    assert true
+  end
+end
diff --git a/src/test/unit/helpers/image_helper_test.rb 
b/src/test/unit/helpers/image_helper_test.rb
new file mode 100644
index 0000000..7c407bc
--- /dev/null
+++ b/src/test/unit/helpers/image_helper_test.rb
@@ -0,0 +1,4 @@
+require 'test_helper'
+
+class ImageHelperTest < ActionView::TestCase
+end
-- 
1.6.2.5

_______________________________________________
deltacloud-devel mailing list
[email protected]
https://fedorahosted.org/mailman/listinfo/deltacloud-devel

Reply via email to