[Ovirt-devel] [PATCH] added smart pool UI bits to search results and other flexigrids
Scott Seago
sseago at redhat.com
Wed Oct 22 22:16:46 UTC 2008
Search results now show what smart pools the items belong to. There's also a pulldown selection to add selected results to a smart pool.
'Add to smart pool' pulldown is also available for the single-type tab pages for hosts, storage, vm pools, and vms.
Signed-off-by: Scott Seago <sseago at redhat.com>
---
src/app/controllers/pool_controller.rb | 4 ++-
src/app/controllers/search_controller.rb | 6 +++-
src/app/controllers/smart_pools_controller.rb | 24 ++++++++++++++-
src/app/models/host.rb | 3 +-
src/app/models/pool.rb | 3 +-
src/app/models/smart_pool.rb | 32 +++++++++++++++++++-
src/app/models/storage_pool.rb | 3 +-
src/app/models/vm.rb | 3 +-
src/app/views/hardware/show_hosts.rhtml | 29 +++++++++++++++++++
src/app/views/hardware/show_storage.rhtml | 29 +++++++++++++++++++
src/app/views/hardware/show_vms.rhtml | 29 +++++++++++++++++++
src/app/views/resources/show_vms.rhtml | 29 +++++++++++++++++++
src/app/views/search/_grid.rhtml | 3 +-
src/app/views/search/results.rhtml | 38 +++++++++++++++++++++++-
src/app/views/vm/_grid.rhtml | 2 +-
15 files changed, 223 insertions(+), 14 deletions(-)
diff --git a/src/app/controllers/pool_controller.rb b/src/app/controllers/pool_controller.rb
index 063cc43..03d1316 100644
--- a/src/app/controllers/pool_controller.rb
+++ b/src/app/controllers/pool_controller.rb
@@ -110,7 +110,9 @@ class PoolController < ApplicationController
attr_list = [:id, :description, :uuid,
:num_vcpus_allocated, :memory_allocated_in_mb,
:vnic_mac_addr, :state, :id]
- attr_list.insert(3, [:host, :hostname]) if @pool.get_hardware_pool.can_view(@user)
+ if (@pool.is_a? VmResourcePool) and @pool.get_hardware_pool.can_view(@user)
+ attr_list.insert(3, [:host, :hostname])
+ end
json_list(args[:full_items], attr_list, [:all], args[:find_opts])
end
diff --git a/src/app/controllers/search_controller.rb b/src/app/controllers/search_controller.rb
index cc7e527..3789309 100644
--- a/src/app/controllers/search_controller.rb
+++ b/src/app/controllers/search_controller.rb
@@ -96,7 +96,9 @@ class SearchController < ApplicationController
item_hash = {}
item = result[:model]
item_hash[:id] = item.class.name+"_"+item.id.to_s
- item_hash[:cell] = ["display_name", "display_class"].collect do |attr|
+ item_hash[:cell] = []
+ item_hash[:cell] << item_hash[:id] if params[:checkboxes]
+ item_hash[:cell] += ["display_name", "display_class"].collect do |attr|
if attr.is_a? Array
value = item
attr.each { |attr_item| value = value.send(attr_item)}
@@ -106,6 +108,8 @@ class SearchController < ApplicationController
end
end
item_hash[:cell] << result[:percent]
+ item_hash[:cell] << item.smart_pools.collect {|pool| pool.name}.join(', ')
+
item_hash
end
render :json => json_hash.to_json
diff --git a/src/app/controllers/smart_pools_controller.rb b/src/app/controllers/smart_pools_controller.rb
index 6bfe367..90b1419 100644
--- a/src/app/controllers/smart_pools_controller.rb
+++ b/src/app/controllers/smart_pools_controller.rb
@@ -23,7 +23,8 @@ class SmartPoolsController < PoolController
before_filter :pre_modify, :only => [:add_hosts, :remove_hosts,
:add_storage, :remove_storage,
:add_vms, :remove_vms,
- :add_pools, :remove_pools]
+ :add_pools, :remove_pools,
+ :add_items]
def show_vms
show
end
@@ -106,7 +107,7 @@ class SmartPoolsController < PoolController
end
find_opts = {:conditions => conditions}
end
- { :full_items => full_items, :find_opts => find_opts, :include_pool => :true}
+ { :full_items => full_items, :find_opts => find_opts, :include_pool => false}
end
def add_hosts
@@ -154,6 +155,25 @@ class SmartPoolsController < PoolController
end
end
+ def add_items
+ class_and_ids_str = params[:class_and_ids]
+ class_and_ids = class_and_ids_str.split(",").collect {|x| x.split("_")}
+
+ begin
+ @pool.transaction do
+ class_and_ids.each do |class_and_id|
+ @pool.add_item(class_and_id[0].constantize.find(class_and_id[1].to_i))
+ end
+ end
+ render :json => { :success => true,
+ :alert => "Add items to smart pool successful." }
+ rescue => ex
+ render :json => { :success => false,
+ :alert => "Add items to smart pool failed: " + ex.message }
+ end
+
+ end
+
def destroy
if @pool.destroy
alert="Smart Pool was successfully deleted."
diff --git a/src/app/models/host.rb b/src/app/models/host.rb
index 546da19..429f0c0 100644
--- a/src/app/models/host.rb
+++ b/src/app/models/host.rb
@@ -48,7 +48,8 @@ class Host < ActiveRecord::Base
:values => [ [ :created_at, 0, "created_at", :date ],
[ :updated_at, 1, "updated_at", :date ] ],
:terms => [ [ :hostname, 'H', "hostname" ],
- [ :search_users, 'U', "search_users" ] ]
+ [ :search_users, 'U', "search_users" ] ],
+ :eager_load => :smart_pools
KVM_HYPERVISOR_TYPE = "KVM"
diff --git a/src/app/models/pool.rb b/src/app/models/pool.rb
index d189649..b25fa55 100644
--- a/src/app/models/pool.rb
+++ b/src/app/models/pool.rb
@@ -89,7 +89,8 @@ class Pool < ActiveRecord::Base
end
acts_as_xapian :texts => [ :name ],
- :terms => [ [ :search_users, 'U', "search_users" ] ]
+ :terms => [ [ :search_users, 'U', "search_users" ] ],
+ :eager_load => :smart_pools
# this method lists pools with direct permission grants, but by default does
# not include implied permissions (i.e. subtrees)
diff --git a/src/app/models/smart_pool.rb b/src/app/models/smart_pool.rb
index 9104ee5..0ecbe05 100644
--- a/src/app/models/smart_pool.rb
+++ b/src/app/models/smart_pool.rb
@@ -39,8 +39,13 @@ class SmartPool < Pool
end
def add_item(item)
- tag = SmartPoolTag.new(:smart_pool => self, :tagged => item)
- tag.save!
+ begin
+ tag = SmartPoolTag.new(:smart_pool => self, :tagged => item)
+ tag.save!
+ rescue ActiveRecord::RecordInvalid
+ # this is thrown if the tagged item already belongs to the smart pool
+ # this operation should be a no-op rather than an error
+ end
end
def remove_item(item)
smart_pool_tags.find(:first, :conditions=> {
@@ -67,4 +72,27 @@ class SmartPool < Pool
end
end
+ def self.smart_pools_for_user(user)
+ nested_pools = DirectoryPool.get_smart_root.full_set_nested(
+ :privilege => Permission::PRIV_MODIFY, :user => user,
+ :smart_pool_set => true)
+ user_pools = []
+ other_pools = []
+ nested_pools.each do |pool_element|
+ pool = pool_element[:obj]
+ if pool.name == user
+ pool_element[:children].each do |child_element|
+ child_pool = child_element[:obj]
+ user_pools <<[child_pool.name, child_pool.id]
+ end
+ else
+ pool_element[:children].each do |child_element|
+ child_pool = child_element[:obj]
+ other_pools << [pool.name + " > " + child_pool.name, child_pool.id]
+ end
+ end
+ end
+ user_pools[-1] << "break"
+ user_pools + other_pools
+ end
end
diff --git a/src/app/models/storage_pool.rb b/src/app/models/storage_pool.rb
index aed2902..9c550b8 100644
--- a/src/app/models/storage_pool.rb
+++ b/src/app/models/storage_pool.rb
@@ -40,7 +40,8 @@ class StoragePool < ActiveRecord::Base
validates_presence_of :hardware_pool_id
acts_as_xapian :texts => [ :ip_addr, :target, :export_path, :type ],
- :terms => [ [ :search_users, 'U', "search_users" ] ]
+ :terms => [ [ :search_users, 'U', "search_users" ] ],
+ :eager_load => :smart_pools
ISCSI = "iSCSI"
NFS = "NFS"
LVM = "LVM"
diff --git a/src/app/models/vm.rb b/src/app/models/vm.rb
index 2eff87a..61c407c 100644
--- a/src/app/models/vm.rb
+++ b/src/app/models/vm.rb
@@ -37,7 +37,8 @@ class Vm < ActiveRecord::Base
:memory_allocated, :vnic_mac_addr
acts_as_xapian :texts => [ :uuid, :description, :vnic_mac_addr, :state ],
- :terms => [ [ :search_users, 'U', "search_users" ] ]
+ :terms => [ [ :search_users, 'U', "search_users" ] ],
+ :eager_load => :smart_pools
BOOT_DEV_HD = "hd"
BOOT_DEV_NETWORK = "network"
diff --git a/src/app/views/hardware/show_hosts.rhtml b/src/app/views/hardware/show_hosts.rhtml
index d33c920..2fd29bc 100644
--- a/src/app/views/hardware/show_hosts.rhtml
+++ b/src/app/views/hardware/show_hosts.rhtml
@@ -5,6 +5,21 @@
<a id="move_link" href="#" onClick="return validate_for_move();"><%= image_tag "icon_move.png", :style=>"vertical-align:middle;" %> Move</a>
<a id="move_link_hidden" href="<%= url_for :controller => 'hardware', :action => 'move', :id => @pool, :resource_type=>'hosts' %>" rel="facebox[.bolder]" style="display:none" ></a>
</li>
+ <li>
+ <%= image_tag "icon_smartpool.png", :style => "vertical-align:middle;" %> Add to Smart Pool <%= image_tag "icon_toolbar_arrow.gif", :style => "vertical-align:middle;" %>
+ <ul>
+ <% smart_pools = SmartPool.smart_pools_for_user(@user) %>
+ <% smart_pools.each_index { |index| %>
+ <li onClick="add_hosts_to_smart_pool(<%=smart_pools[index][1]%>)"
+ <% if (index == smart_pools.length - 1) or smart_pools[index].length == 3 %>
+ style="border-bottom: 1px solid #CCCCCC;"
+ <% end %>
+ >
+ <%=smart_pools[index][0]%>
+ </li>
+ <% } %>
+ </ul>
+ </li>
<% if @pool.id != HardwarePool.get_default_pool.id %>
<li><a href="#" onClick="remove_hosts()"><%= image_tag "icon_remove.png" %> Remove</a></li>
<% end %>
@@ -22,6 +37,20 @@
$('#move_link_hidden').click();
}
}
+ function add_hosts_to_smart_pool(smart_pool)
+ {
+ var hosts = get_selected_hosts();
+ if (validate_selected(hosts, "host")) {
+ $.post('<%= url_for :controller => "smart_pools", :action => "add_hosts" %>',
+ { resource_ids: hosts.toString(), id: smart_pool },
+ function(data,status){
+ $('#hosts_grid').flexReload();
+ if (data.alert) {
+ $.jGrowl(data.alert);
+ }
+ }, 'json');
+ }
+ }
function remove_hosts()
{
var hosts = get_selected_hosts();
diff --git a/src/app/views/hardware/show_storage.rhtml b/src/app/views/hardware/show_storage.rhtml
index 6466f9b..5ade456 100644
--- a/src/app/views/hardware/show_storage.rhtml
+++ b/src/app/views/hardware/show_storage.rhtml
@@ -6,6 +6,21 @@
<a id="move_link_hidden" href="<%= url_for :controller => 'hardware', :action => 'move', :id => @pool, :resource_type=>'storage' %>" rel="facebox[.bolder]" style="display:none" ></a>
</li>
<li>
+ <%= image_tag "icon_smartpool.png", :style => "vertical-align:middle;" %> Add to Smart Pool <%= image_tag "icon_toolbar_arrow.gif", :style => "vertical-align:middle;" %>
+ <ul>
+ <% smart_pools = SmartPool.smart_pools_for_user(@user) %>
+ <% smart_pools.each_index { |index| %>
+ <li onClick="add_storage_to_smart_pool(<%=smart_pools[index][1]%>)"
+ <% if (index == smart_pools.length - 1) or smart_pools[index].length == 3 %>
+ style="border-bottom: 1px solid #CCCCCC;"
+ <% end %>
+ >
+ <%=smart_pools[index][0]%>
+ </li>
+ <% } %>
+ </ul>
+ </li>
+ <li>
<a href="#" onClick="return validate_storage_for_remove();" ><%= image_tag "icon_remove.png", :style=>"vertical-align:middle;" %> Remove</a>
<a id="remove_link_hidden" href="<%= url_for :controller => 'hardware', :action => 'removestorage', :id => @pool %>" rel="facebox[.bolder]" style="display:none" ></a>
</li>
@@ -13,6 +28,20 @@
</div>
<script type="text/javascript">
+ function add_storage_to_smart_pool(smart_pool)
+ {
+ var storage = get_selected_storage();
+ if (validate_selected(storage, "storage pool")) {
+ $.post('<%= url_for :controller => "smart_pools", :action => "add_storage" %>',
+ { resource_ids: storage.toString(), id: smart_pool },
+ function(data,status){
+ $('#storage_grid').flexReload();
+ if (data.alert) {
+ $.jGrowl(data.alert);
+ }
+ }, 'json');
+ }
+ }
function remove_storage()
{
var storage = get_selected_storage();
diff --git a/src/app/views/hardware/show_vms.rhtml b/src/app/views/hardware/show_vms.rhtml
index ee14758..6a8ded5 100644
--- a/src/app/views/hardware/show_vms.rhtml
+++ b/src/app/views/hardware/show_vms.rhtml
@@ -1,6 +1,21 @@
<div id="toolbar_nav">
<ul>
<li><a href="<%= url_for :controller => 'resources', :action => 'new', :parent_id => @pool %>" rel="facebox[.bolder]"><%= image_tag "icon_add_vmpool.png", :style => "vertical-align:middle;" %> New Virtual Machine Pool</a></li>
+ <li>
+ <%= image_tag "icon_smartpool.png", :style => "vertical-align:middle;" %> Add to Smart Pool <%= image_tag "icon_toolbar_arrow.gif", :style => "vertical-align:middle;" %>
+ <ul>
+ <% smart_pools = SmartPool.smart_pools_for_user(@user) %>
+ <% smart_pools.each_index { |index| %>
+ <li onClick="add_vm_pools_to_smart_pool(<%=smart_pools[index][1]%>)"
+ <% if (index == smart_pools.length - 1) or smart_pools[index].length == 3 %>
+ style="border-bottom: 1px solid #CCCCCC;"
+ <% end %>
+ >
+ <%=smart_pools[index][0]%>
+ </li>
+ <% } %>
+ </ul>
+ </li>
<li><a href="#" onClick="delete_vm_pools()"><%= image_tag "icon_delete_white.png", :style => "vertical-align:middle;" %> Delete</a></li>
</ul>
</div>
@@ -9,6 +24,20 @@
{
return get_selected_checkboxes("vmpools_grid_form");
}
+ function add_vm_pools_to_smart_pool(smart_pool)
+ {
+ var vm_pools = get_selected_vm_pools();
+ if (validate_selected(vm_pools, "vm pool")) {
+ $.post('<%= url_for :controller => "smart_pools", :action => "add_pools" %>',
+ { resource_ids: vm_pools.toString(), id: smart_pool },
+ function(data,status){
+ $('#vmpools_grid').flexReload();
+ if (data.alert) {
+ $.jGrowl(data.alert);
+ }
+ }, 'json');
+ }
+ }
function delete_vm_pools()
{
var vm_pools = get_selected_vm_pools();
diff --git a/src/app/views/resources/show_vms.rhtml b/src/app/views/resources/show_vms.rhtml
index beca048..6f757f9 100644
--- a/src/app/views/resources/show_vms.rhtml
+++ b/src/app/views/resources/show_vms.rhtml
@@ -16,6 +16,21 @@
<% } %>
</ul>
</li>
+ <li>
+ <%= image_tag "icon_smartpool.png", :style => "vertical-align:middle;" %> Add to Smart Pool <%= image_tag "icon_toolbar_arrow.gif", :style => "vertical-align:middle;" %>
+ <ul>
+ <% smart_pools = SmartPool.smart_pools_for_user(@user) %>
+ <% smart_pools.each_index { |index| %>
+ <li onClick="add_vms_to_smart_pool(<%=smart_pools[index][1]%>)"
+ <% if (index == smart_pools.length - 1) or smart_pools[index].length == 3 %>
+ style="border-bottom: 1px solid #CCCCCC;"
+ <% end %>
+ >
+ <%=smart_pools[index][0]%>
+ </li>
+ <% } %>
+ </ul>
+ </li>
<li><a href="#" onClick="delete_vms()"><%= image_tag "icon_delete_white.png", :style => "vertical-align:middle;" %> Delete</a></li>
</ul>
</div>
@@ -24,6 +39,20 @@
{
return get_selected_checkboxes("vms_grid_form");
}
+ function add_vms_to_smart_pool(smart_pool)
+ {
+ var vms = get_selected_vms();
+ if (validate_selected(vms, "vm")) {
+ $.post('<%= url_for :controller => "smart_pools", :action => "add_vms" %>',
+ { resource_ids: vms.toString(), id: smart_pool },
+ function(data,status){
+ $('#vms_grid').flexReload();
+ if (data.alert) {
+ $.jGrowl(data.alert);
+ }
+ }, 'json');
+ }
+ }
function delete_vms()
{
var vms = get_selected_vms();
diff --git a/src/app/views/search/_grid.rhtml b/src/app/views/search/_grid.rhtml
index 2e60646..fca1ba0 100644
--- a/src/app/views/search/_grid.rhtml
+++ b/src/app/views/search/_grid.rhtml
@@ -18,7 +18,8 @@
<%= "{display: '', width : 20, align: 'left', process: #{table_id}checkbox}," if checkboxes %>
{display: 'Name', width : 200, align: 'left'},
{display: 'Type', width : 120, align: 'left'},
- {display: '% Match', width : 60, align: 'left'}
+ {display: '% Match', width : 60, align: 'left'},
+ {display: 'Smart Pools', width : 200, align: 'left'}
],
//sortname: "hostname",
//sortorder: "asc",
diff --git a/src/app/views/search/results.rhtml b/src/app/views/search/results.rhtml
index a7641b7..1989054 100644
--- a/src/app/views/search/results.rhtml
+++ b/src/app/views/search/results.rhtml
@@ -5,9 +5,25 @@
<input id="searchform-field" name="terms" value="<%=@terms%>" onkeypress="" type="text">
<input id="searchform-button" src="<%= image_path "icon_search.png"%>" title="Search" type="image">
<input id="searchform-model" type="hidden" name="model" value="<%=@model_param%>">
+ Search
</li>
<li>
- <%= image_tag "icon_move.png", :style => "vertical-align:middle;" %> Actions <%= image_tag "icon_toolbar_arrow.gif", :style => "vertical-align:middle;" %>
+ <%= image_tag "icon_smartpool.png", :style => "vertical-align:middle;" %> Add to Smart Pool <%= image_tag "icon_toolbar_arrow.gif", :style => "vertical-align:middle;" %>
+ <ul>
+ <% smart_pools = SmartPool.smart_pools_for_user(@user) %>
+ <% smart_pools.each_index { |index| %>
+ <li onClick="add_results_to_smart_pool(<%=smart_pools[index][1]%>)"
+ <% if (index == smart_pools.length - 1) or smart_pools[index].length == 3 %>
+ style="border-bottom: 1px solid #CCCCCC;"
+ <% end %>
+ >
+ <%=smart_pools[index][0]%>
+ </li>
+ <% } %>
+ </ul>
+ </li>
+ <li>
+ Show All <%= image_tag "icon_toolbar_arrow.gif", :style => "vertical-align:middle;" %>
<ul>
<% @types.each_index { |index| %>
<!-- for each button we need to submit current form with "model" set to @types[index][1] --!>
@@ -40,6 +56,24 @@
{ class_and_id: selected_ids[0].substring(3)})
}
}
+ function get_selected_results()
+ {
+ return get_selected_checkboxes("search_grid_form")
+ }
+ function add_results_to_smart_pool(smart_pool)
+ {
+ var results = get_selected_results();
+ if (validate_selected(results, "search result")) {
+ $.post('<%= url_for :controller => "smart_pools", :action => "add_items" %>',
+ { class_and_ids: results.toString(), id: smart_pool },
+ function(data,status){
+ $('#search_grid').flexReload();
+ if (data.alert) {
+ $.jGrowl(data.alert);
+ }
+ }, 'json');
+ }
+ }
</script>
<div class="panel_header"></div>
@@ -48,7 +82,7 @@
<%= render :partial => "/search/grid", :locals => { :table_id => "search_grid",
:terms => @terms,
:model => @model_param,
- :checkboxes => false,
+ :checkboxes => true,
:on_select => "results_select" } %>
</div>
<div class="selection_detail" id="results_selection">
diff --git a/src/app/views/vm/_grid.rhtml b/src/app/views/vm/_grid.rhtml
index 85bf094..b137de6 100644
--- a/src/app/views/vm/_grid.rhtml
+++ b/src/app/views/vm/_grid.rhtml
@@ -29,7 +29,7 @@
{display: '', name : 'id', width : 20, sortable : false, align: 'left', process: <%= table_id %>checkbox},
{display: 'Description', name : 'description', width : 180, sortable : true, align: 'left'},
{display: 'UUID', name : 'uuid', width : 180, sortable : true, align: 'left'},
- <% if @pool.get_hardware_pool.can_view(@user) %>
+ <% if (pool.is_a? VmResourcePool) and pool.get_hardware_pool.can_view(@user) %>
{display: 'Host', name : 'host', width: 180, sortable : true, align: 'left' },
<% end %>
{display: 'CPUs', name : 'num_vcpus_allocated', width : 40, sortable : true, align: 'left'},
--
1.5.5.1
More information about the ovirt-devel
mailing list