All,
I'm attaching a patch that partially implements the Pools page in the new UI. While it's not done yet, you can look at the code to see how to code other other pages for the new UI.
Here are some pointers:
1. We're using namespaced routes for the controllers/views.
The controllers are located in:
aeolus/src/app/controllers/$NAMESPACE/
The same thing for views.
The URLs look like this: http://example.com/image_factory/assemblies
The layout for the new UI is at: aeolus/src/views/layouts/newui.haml
2. Most of the time you will be using the "list" and the "details" panes. You set their content using `content_for :list` and `content_for :details` in the views.
When you don't specify the "details" content, the list will take up all the vertical space.
3. The controllers use your typical restful/crud actions: index, show, new, create, destroy, update. And they use the proper HTTP methods (PUT for `update`, DELETE for destroy, etc.) -- you can run `rake routes` to see the URLs, HTTP methods and the path helpers.
For nonstandard stuff feel free to add new actions of course.
4. Form submit:
When you have a form with GET or POST method, a single submit button and a static form action URL, it's all good.
It gets trickier when you have a form full of checkboxes (e.g. the list pane) and you want to do batch actions on them. Especially since it must work without JavaScript and with non-GET or POST methods.
For that you can use the new `restful_submit_tag` helper that Ladislav cooked up. You use it like this:
= restful_submit_tag "Delete", "delete", resources_pool(@pool.id), 'DELETE'
(button text, button name, form action URL, HTTP method)
It will create some hidden fields that our app will translate to proper HTTP methods.
Note that you can use multiple submit buttons with different form URLs. This allows you to put "New Pool" and "Delete Selected Pools" along with "Edit Selected Pool" buttons all into the same form and it'll all work.
If you're confused, I recomend that you look at the the attached patch. It shows the stuff described here in action.
Feel free to ask me questions on IRC or this list.
Thomas
From: Tomas Sedovic tsedovic@redhat.com
This is the first step towards implementing the Pools page in the new UI.
Actions `index` and `show` are in place and display the proper pages (though the content is pretty much still missing).
The "New Pool" button is working; the "Edit" one is hooked up to the Controller and has some basic code but the functionality is not there yet.
When you click on the pool name, you will see the "Details" pane with the appropriate tabs. The contents of the tabs are missing as well. --- src/app/controllers/resources/pools_controller.rb | 59 +++++++++++++++++++++ src/app/models/pool.rb | 1 + src/app/stylesheets/newui.scss | 21 +++++-- src/app/views/layouts/newui.haml | 10 ++-- src/app/views/resources/pools/_list.haml | 23 ++++++++ src/app/views/resources/pools/index.haml | 3 +- src/app/views/resources/pools/new.haml | 11 ++++ src/app/views/resources/pools/show.haml | 24 ++++++++ 8 files changed, 141 insertions(+), 11 deletions(-) create mode 100644 src/app/views/resources/pools/_list.haml create mode 100644 src/app/views/resources/pools/new.haml create mode 100644 src/app/views/resources/pools/show.haml
diff --git a/src/app/controllers/resources/pools_controller.rb b/src/app/controllers/resources/pools_controller.rb index 39d3b7c..426e016 100644 --- a/src/app/controllers/resources/pools_controller.rb +++ b/src/app/controllers/resources/pools_controller.rb @@ -1,6 +1,65 @@ class Resources::PoolsController < ApplicationController before_filter :require_user + before_filter :load_pools, :only => [:index, :show]
def index end + + def show + @pool = Pool.find(params[:id]) + end + + def edit + render :text => "Edit Pool #{params[:id]}" + end + + def new + require_privilege(Privilege::POOL_MODIFY) + @pool = Pool.new + end + + def create + require_privilege(Privilege::POOL_MODIFY) + + @pool = Pool.new(params[:pool]) + quota = Quota.new + quota.save! + + @pool.quota_id = quota.id + @pool.zone = Zone.default + if @pool.save + flash[:notice] = "Pool added." + redirect_to :action => 'show', :id => @pool.id + else + render :action => :new + end + end + + def edit + selected_pools = params[:pool][:selected].reject {|id, checked| checked == '0'} + if selected_pools.size != 1 + flash[:notice] = "Select a single pool." + redirect_to :action => 'index' + else + pool_id = selected_pools.first[0] + @pool = Pool.find(pool_id) + render :text => "Editing pool '#{@pool.name}'" + end + end + + protected + + def load_pools + @header = [ + { :name => "Pool name", :sort_attr => :name }, + { :name => "% Quota used", :sortable => false }, + { :name => "Quota (Instances)", :sort_attr => "quotas.total_instances"}, + { :name => "Zone", :sort_attr => "zones.name" } + ] + @pools = Pool.paginate(:all, :include => [ :quota, :zone ], + :page => params[:page] || 1, + :order => (params[:order_field] || 'name') +' '+ (params[:order_dir] || 'asc') + ) + @url_params = params.clone + end end diff --git a/src/app/models/pool.rb b/src/app/models/pool.rb index 597128b..32783d8 100644 --- a/src/app/models/pool.rb +++ b/src/app/models/pool.rb @@ -32,6 +32,7 @@ class Pool < ActiveRecord::Base
validates_presence_of :name validates_presence_of :zone + validates_uniqueness_of :name validates_uniqueness_of :exported_as, :if => :exported_as
validates_format_of :name, :with => /^[\w -]*$/n, :message => "must only contain: numbers, letters, spaces, '_' and '-'" diff --git a/src/app/stylesheets/newui.scss b/src/app/stylesheets/newui.scss index 5b341bd..933165d 100644 --- a/src/app/stylesheets/newui.scss +++ b/src/app/stylesheets/newui.scss @@ -1329,25 +1329,34 @@ a.iconbutton {
}
+ +$details-height: 190px; +$content-left: 180px; + #list-view { border: 1px solid; padding: 1em; position: absolute; top: 1em; - left: 15em; + left: $content-left; right: 0; - bottom: 320px; overflow: auto; + &.part { + bottom: $details-height + 30px; + } + &.full { + bottom: 1em; + } }
#details-view { border: 1px solid; position: absolute; - left: 15em; + left: $content-left; right: 0; - height: 270px; - bottom: 1em; - padding: 1em; + height: $details-height; + bottom: 0; + padding: 0; }
/* DEBUG GRID */ diff --git a/src/app/views/layouts/newui.haml b/src/app/views/layouts/newui.haml index 664cf1f..26a0a48 100644 --- a/src/app/views/layouts/newui.haml +++ b/src/app/views/layouts/newui.haml @@ -38,13 +38,15 @@ = render_navigation({:context => 'new', :expand_all => true, :level => 1}) = render_navigation({:context => 'new', :expand_all => true, :level => 2}) #content - = render :partial => '/layouts/notification' #saved-searches Saved searches - #list-view + - details = !(yield :details).blank? + #list-view{ :class => details ? 'part' : 'full'} + = render :partial => '/layouts/notification' = (yield :list or yield) - #details-view - = yield :details + - if details + #details-view + = yield :details %footer = render :partial => "layouts/footer" #grid diff --git a/src/app/views/resources/pools/_list.haml b/src/app/views/resources/pools/_list.haml new file mode 100644 index 0000000..6d1e4db --- /dev/null +++ b/src/app/views/resources/pools/_list.haml @@ -0,0 +1,23 @@ +- form_tag do |f| + = restful_submit_tag "New Pool", "new", new_resources_pool_path, 'GET' + = restful_submit_tag "Edit", "edit", edit_resources_pool_path(@pools.first), 'GET' + %p + Select: + = link_to "All", @url_params.merge(:select => 'all') + %span> , + = link_to "None", @url_params.merge(:select => 'none') + %table + = sortable_table_header @header + - @pools.each do |pool| + %tr + %td + - selected = @url_params[:select] == 'all' + = check_box(:pool, "selected[#{pool.id}]", :checked => selected) + = link_to pool.name, resources_pool_path(pool) + %td + =((pool.quota.maximum_running_instances || 0)/100)*pool.quota.total_instances + ='%' + %td + =pool.quota.total_instances + %td + =pool.zone.name diff --git a/src/app/views/resources/pools/index.haml b/src/app/views/resources/pools/index.haml index 5716106..62ccbc6 100644 --- a/src/app/views/resources/pools/index.haml +++ b/src/app/views/resources/pools/index.haml @@ -1 +1,2 @@ -resources/pools/index.haml +- content_for :list do + = render :partial => 'list' diff --git a/src/app/views/resources/pools/new.haml b/src/app/views/resources/pools/new.haml new file mode 100644 index 0000000..032f0ac --- /dev/null +++ b/src/app/views/resources/pools/new.haml @@ -0,0 +1,11 @@ += error_messages_for 'account' +%h1 Create a new Pool +- form_for @pool, :url => resources_pools_path do |form| + %h2 Pool + %fieldset + %label.grid_2.alpha Name: + = form.text_field :name, :class => "grid_5" + = form.error_message_on :name, 'Name ' + .clear.grid_14.prefix_2.alpha Provide a descriptive name for this pool. + + = submit_tag "Save", :class => "submit formbutton" diff --git a/src/app/views/resources/pools/show.haml b/src/app/views/resources/pools/show.haml new file mode 100644 index 0000000..b28cc48 --- /dev/null +++ b/src/app/views/resources/pools/show.haml @@ -0,0 +1,24 @@ +- content_for :list do + = render :partial => 'list' + +- content_for :details do + %ul + %li + = link_to 'Properties', '#properties' + %li + = link_to 'Deployments', '#deployments' + %li + = link_to 'Instances', '#instances' + %li + = link_to 'History', '#history' + %li + = link_to 'Permissions', '#permissions' + %h3 + Details for + = @pool.name + +- content_for :scripts do + :javascript + $(document).ready(function() { + $('#details-view').tabs(); + });
deltacloud-devel@lists.fedorahosted.org