[PATCH] BZ810919 mustach-ify pretty-view pool header so that instance/deployment counts are automatically updated
Imre Farkas
ifarkas at redhat.com
Tue May 22 10:12:40 UTC 2012
On 05/22/2012 08:44 AM, Tzu-Mainn Chen wrote:
> ---
> src/app/controllers/pools_controller.rb | 7 ++-
> src/app/helpers/mustache_helper.rb | 22 ++++++++++-
> src/app/views/pools/_header_index.html.haml | 5 ++-
> src/app/views/pools/_pretty_list.html.haml | 24 ++---------
> .../views/pools/_pretty_list_header.html.mustache | 24 +++++++++++
> src/app/views/pools/_scoreboard_index.html.haml | 29 --------------
> .../views/pools/_scoreboard_index.html.mustache | 41 ++++++++++++++++++++
> src/public/javascripts/backbone/models.js | 5 ++
> src/public/javascripts/backbone/routers.js | 8 +---
> src/public/javascripts/backbone/views.js | 36 ++++++++---------
> 10 files changed, 122 insertions(+), 79 deletions(-)
> create mode 100644 src/app/views/pools/_pretty_list_header.html.mustache
> delete mode 100644 src/app/views/pools/_scoreboard_index.html.haml
> create mode 100644 src/app/views/pools/_scoreboard_index.html.mustache
>
> diff --git a/src/app/controllers/pools_controller.rb b/src/app/controllers/pools_controller.rb
> index 6eaa6f1..d53fd3f 100644
> --- a/src/app/controllers/pools_controller.rb
> +++ b/src/app/controllers/pools_controller.rb
> @@ -83,12 +83,13 @@ class PoolsController< ApplicationController
> format.json do
> case @details_tab[:id]
> when 'pools'
> - render :json => @pools.map{ |pool| view_context.pool_for_mustache(pool) }
> + json = @pools.map{ |pool| view_context.pool_for_mustache(pool) }
> when 'instances'
> - render :json => @instances.map{ |instance| view_context.instance_for_mustache(instance) }
> + json = @instances.map{ |instance| view_context.instance_for_mustache(instance) }
> when 'deployments'
> - render :json => @deployments.map{ |deployment| view_context.deployment_for_mustache(deployment) }
> + json = @deployments.map{ |deployment| view_context.deployment_for_mustache(deployment) }
> end
> + render :json => { :collection => json, :user_info => view_context.user_info_for_mustache() }
You don't need the parentheses here...
> end
> end
> end
> diff --git a/src/app/helpers/mustache_helper.rb b/src/app/helpers/mustache_helper.rb
> index cc3670a..1c10d10 100644
> --- a/src/app/helpers/mustache_helper.rb
> +++ b/src/app/helpers/mustache_helper.rb
> @@ -19,6 +19,23 @@
>
> module MustacheHelper
>
> + def user_info_for_mustache()
...and neither here
> + user_pools = Pool.list_for_user(current_user, Privilege::CREATE, Deployment);
> + user_instances = current_user.owned_instances
> + user_available_quota = current_user.quota.maximum_running_instances
> + {
> + :user_pools_count => user_pools.count,
> + :pools_in_use => user_pools.select { |pool| pool.instances.pending_or_deployed.count> 0 }.count,
> + :deployments_count => current_user.deployments.count,
> + :instances_count => user_instances.count,
> + :instances_pending_count => user_instances.select {|instance| instance.state == Instance::STATE_NEW || instance.state == Instance::STATE_PENDING}.count,
You can also use the scopes defined on instance like:
:instances_pending_count => user_instances.pending.count
> + :instances_failed_count => user_instances.failed.count,
> + :percentage_quota => number_to_percentage(current_user.quota.percentage_used, :precision => 0),
> + :user_running_instances => current_user.quota.running_instances,
> + :user_available_quota => user_available_quota.nil? ? raw('∞') : user_available_quota
> + }
> + end
> +
> def instance_for_mustache(instance)
> available_actions = instance.get_action_list
>
> @@ -76,6 +93,7 @@ module MustacheHelper
> {
> :id => pool.id,
> :name => pool.name,
> + :view_path => pool_path(pool),
> :filter_view_path => pool_path(pool, :view => :filter),
> :failed_instances_present => pool_statistics[:instances_failed_count]> 0,
> :deployments_count => pool.deployments.count,
> @@ -91,7 +109,9 @@ module MustacheHelper
> :pool_family => {
> :name => pool.pool_family.name,
> :path => user_can_access_pool_family ? pool_family_path(pool.pool_family) : nil
> - }
> + },
> +
> + :user_deployments => paginate_collection(pool.deployments.list_for_user(current_user, Privilege::VIEW).ascending_by_name, params[:page], PER_PAGE)
> }
> end
>
> diff --git a/src/app/views/pools/_header_index.html.haml b/src/app/views/pools/_header_index.html.haml
> index 5735208..aab67c3 100644
> --- a/src/app/views/pools/_header_index.html.haml
> +++ b/src/app/views/pools/_header_index.html.haml
> @@ -7,4 +7,7 @@
> = link_to t('pools.new_pool'), new_pool_path, { :class => 'button primary', :id => 'new_pool_button' }
> %h1.section-index= t 'pools.index.overview'
>
> -= render :partial => 'scoreboard_index'
> \ No newline at end of file
> += render :partial => 'scoreboard_index', :mustache => user_info_for_mustache()
You don't need the parentheses here too
> +
> +%script#poolScoreboardIndexTemplate{ :type => 'text/html' }
> + = render :partial => 'scoreboard_index'
> diff --git a/src/app/views/pools/_pretty_list.html.haml b/src/app/views/pools/_pretty_list.html.haml
> index 041d092..7061af6 100644
> --- a/src/app/views/pools/_pretty_list.html.haml
> +++ b/src/app/views/pools/_pretty_list.html.haml
> @@ -4,25 +4,8 @@
> .content#pools-list
> - @pools.each do |pool|
> %div.pool.overview{:id => ['pool', pool.id], :class => ('collapsed' unless pool.deployments.size> 0)}
> - %header
> - %h3.name
> - = link_to pool.name, pool
> - %dl.statistics
> - %ul.groups
> - %li
> - %dt=t 'deployments.deployments'
> - %dd.count.deployment= pool.deployments.size
> - %li
> - %dt=t 'instances.instances.other'
> - %dd.count.instance= pool.instances.size
> - %dd.count.instance.pending= pool.instances.select {|i| i.state == Instance::STATE_PENDING }.length
> - %dd.count.instance.failure= pool.instances.select {|i| i.state == Instance::STATE_ERROR || i.state == Instance::STATE_CREATE_FAILED }.length
> - %li
> - %dt=t'quota_used'
> - %dd.percentage.quota
> - = number_to_percentage(pool.quota.percentage_used, :precision => 0)
> - %a.control{:href => '#'}
> - %span Expand/Collapse
> + %header{:class => "pool-header-#{pool.id}"}
> + = render :partial => 'pretty_list_header', :mustache => pool_for_mustache(pool)
> %div.content
> - deployments = paginate_collection(pool.deployments.includes(:owner, :pool, :instances, :events).list_for_user(current_user, Privilege::VIEW).ascending_by_name, params[:page], PER_PAGE)
> = render :partial => 'deployments', :locals => {:pool => pool, :deployments => deployments}
> @@ -48,3 +31,6 @@
> });
> })
> });
> +
> +%script#poolPrettyListHeaderTemplate{ :type => 'text/html' }
> + = render :partial => 'pretty_list_header'
> diff --git a/src/app/views/pools/_pretty_list_header.html.mustache b/src/app/views/pools/_pretty_list_header.html.mustache
> new file mode 100644
> index 0000000..140cd67
> --- /dev/null
> +++ b/src/app/views/pools/_pretty_list_header.html.mustache
> @@ -0,0 +1,24 @@
> +<h3 class="name">
> +<%= link_to('{{name}}', '{{view_path}}') %>
> +</h3>
> +<dl class="statistics">
> +<ul class="groups">
> +<li>
> +<dt><%= t('deployments.deployments')%></dt>
> +<dd class="count deployment">{{deployments_count}}</dd>
> +</li>
> +<li>
> +<dt><%= t('instances.instances.other')%></dt>
> +<dd class="count instance">{{statistics.total_instances}}</dd>
> +<dd class="count instance pending">{{statistics.instances_pending}}</dd>
> +<dd class="count instance failure">{{statistics.instances_failed_count}}</dd>
> +</li>
> +<li>
> +<dt><%= t('quota_used')%></dt>
> +<dd class="percentage_quota">{{statistics.quota_percent}}</dd>
> +</li>
> +</ul>
> +</dl>
> +<a class="control" href="#">
> +<span>Expand/Collapse</span>
> +</a>
> diff --git a/src/app/views/pools/_scoreboard_index.html.haml b/src/app/views/pools/_scoreboard_index.html.haml
> deleted file mode 100644
> index 24a6689..0000000
> --- a/src/app/views/pools/_scoreboard_index.html.haml
> +++ /dev/null
> @@ -1,29 +0,0 @@
> -#scoreboard
> - %dl.statistics
> - %ul.groups
> - %li
> - %dt= t("pools.pools")
> - %dd.count.pool= @user_pools.count
> - %dd.count.pool.partial= @statistics[:pools_in_use]
> - %li
> - %dt= t("deployments.deployments")
> - %dd.count.deployment= @statistics[:deployments]
> - %li
> - %dt= t("instances.instances.other")
> - %dd.count.instance= @statistics[:instances]
> - %dd.count.instance.pending= @statistics[:instances_pending]
> - %dd.count.instance.failure= @statistics[:instances_failed_count]
> - %li
> - %ul.subgroup
> - %li
> - %dt= t("alerts_label")
> - %dd.count.alert= @statistics[:instances_failed_count]
> - %li
> - %dt
> - = t("user")
> - = t("quota_used")
> - %dd.percentage.quota= number_to_percentage(@statistics[:user_used_percentage], :precision => 0)
> - %dd.fraction.instance
> - %span.part= @statistics[:user_running_instances]
> - %span.divider.label.small.caps of
> - %span.total= @statistics[:user_available_quota].nil? ? raw('∞') : @statistics[:user_available_quota]
> diff --git a/src/app/views/pools/_scoreboard_index.html.mustache b/src/app/views/pools/_scoreboard_index.html.mustache
> new file mode 100644
> index 0000000..c45f265
> --- /dev/null
> +++ b/src/app/views/pools/_scoreboard_index.html.mustache
> @@ -0,0 +1,41 @@
> +<div id="scoreboard" class="scoreboard">
> +<dl class="statistics">
> +<ul class="groups">
> +<li>
> +<dt><%= t('pools.pools')%></dt>
> +<dd class="count pool">{{user_pools_count}}</dd>
> +<dd class="count pool partial">{{pools_in_use}}</dd>
> +</li>
> +<li>
> +<dt><%= t('deployments.deployments')%></dt>
> +<dd class="count deployment">{{deployments_count}}</dd>
> +</li>
> +<li>
> +<dt><%= t('instances.instances.other')%></dt>
> +<dd class="count instance">{{instances_count}}</dd>
> +<dd class="count instance pending">{{instances_pending_count}}</dd>
> +<dd class="count instance failure">{{instances_failed_count}}</dd>
> +</li>
> +<li>
> +<ul class="subgroup">
> +<li>
> +<dt><%= t('alerts_label')%></dt>
> +<dd class="count alert">{{instances_failed_count}}</dd>
> +</li>
> +</ul>
> +</li>
> +<li>
> +<dt>
> +<%= t('user')%>
> +<%= t('quota_used')%>
> +</dt>
> +<dd class="percentage quota">{{percentage_quota}}</dd>
> +<dd class="fraction instance">
> +<span class="part">{{user_running_instances}}</span>
> +<span class="divider label small caps">of</span>
> +<span class="total"><%= @statistics[:user_available_quota].nil? ? raw('∞') : @statistics[:user_available_quota] %></span>
> +</dd>
> +</li>
> +</ul>
> +</dl>
> +</div>
> diff --git a/src/public/javascripts/backbone/models.js b/src/public/javascripts/backbone/models.js
> index 8c40572..4c3084d 100644
> --- a/src/public/javascripts/backbone/models.js
> +++ b/src/public/javascripts/backbone/models.js
> @@ -1,5 +1,6 @@
> Conductor.Models = Conductor.Models || {}
>
> +Conductor.Models.UserInfo = Backbone.Model.extend({});
>
> Conductor.Models.Pool = Backbone.Model.extend({
> initialize: function() {
> @@ -17,6 +18,10 @@ Conductor.Models.Pool = Backbone.Model.extend({
> Conductor.Models.Pools = Backbone.Collection.extend({
> model: Backbone.Model.Pool,
> queryParams: {},
> + parse: function(response) {
> + this.userInfo = new Conductor.Models.UserInfo(response.user_info);
> + return response.collection;
> + },
> url: function() {
> var path = Conductor.prefixedPath('/pools');
> return Conductor.parameterizedPath(path, this.queryParams);
> diff --git a/src/public/javascripts/backbone/routers.js b/src/public/javascripts/backbone/routers.js
> index 8d99ac5..b9a712a 100644
> --- a/src/public/javascripts/backbone/routers.js
> +++ b/src/public/javascripts/backbone/routers.js
> @@ -12,13 +12,7 @@ Conductor.Routers.Pools = Backbone.Router.extend({
> setInterval(function() {
> var view = new Conductor.Views.PoolsIndex();
>
> - if (view.currentView() == 'table') {
> - view.collection = new Conductor.Models.Pools();
> - }
> - else if (view.currentView() == 'pretty') {
> - view.collection = new Conductor.Models.Deployments();
> - }
> -
> + view.collection = new Conductor.Models.Pools();
> view.collection.queryParams = view.queryParams();
> view.collection.bind('change', function() { view.render() });
>
> diff --git a/src/public/javascripts/backbone/views.js b/src/public/javascripts/backbone/views.js
> index 55e2c35..e3cf278 100644
> --- a/src/public/javascripts/backbone/views.js
> +++ b/src/public/javascripts/backbone/views.js
> @@ -79,38 +79,36 @@ Conductor.Views.PoolsIndex = Backbone.View.extend({
> }
> else if (this.currentView() == 'pretty') {
> var cardsPerRow = 5;
> - var poolIds = this.collection.models.map(function(model) {
> - return model.attributes.pool.id;
> - });
> - $.unique(poolIds);
> - var deployments = this.collection.models.map(function(model) {
> - return model.attributes;
> - });
>
> - for(var j = 0; j< poolIds.length; j++) {
> - var poolId = poolIds[j];
> - var $rows = this.$('#deployment-arrays-' + poolId).empty();
> - var poolDeployments = deployments.filter(function(attributes) {
> - return attributes.pool.id == poolId;
> - });
> + var self = this;
> + var headerTemplate = $('#poolPrettyListHeaderTemplate');
> + $.each(this.collection.models, function(index, value) {
> + var poolId = value.attributes.id;
> + var $rows = self.$('#deployment-arrays-' + poolId).empty();
> + var poolDeployments = value.attributes.user_deployments;
> for(var i = 0; i< poolDeployments.length; i += cardsPerRow) {
> -
> - var deplyomentCarsHtml = '';
> + var deploymentCardsHtml = '';
> $.each(poolDeployments.slice(i, i + cardsPerRow), function(deploymentIndex, deployment) {
> - deplyomentCarsHtml += Mustache.to_html($template.html(), deployment);
> + deploymentCardsHtml += Mustache.to_html($template.html(), deployment);
> });
>
> - var $row = this.make('ul', {'class': 'deployment-array small'}, deplyomentCarsHtml);
> + var $row = self.make('ul', {'class': 'deployment-array small'}, deploymentCardsHtml);
> $rows.append($row);
> }
> - }
> +
> + var $header = $('header.pool-header-' + poolId);
> + $header.html(Mustache.to_html(headerTemplate.html(), value.toJSON()));
> + });
> }
> +
> + var scoreboardTemplate = $('#poolScoreboardIndexTemplate');
> + var $scoreboard = $('div.scoreboard');
> + $scoreboard.html(Mustache.to_html(scoreboardTemplate.html(), this.collection.userInfo.toJSON()));
> }
> });
>
> Conductor.Views.PoolsShow = Backbone.View.extend({
> el: '#content',
> -
> currentView: function() {
> if ($('form.filterable-data').length> 0) {
> return 'table'
Conditional ACK: I've only encountered one little issue with updating
the 'scoreboard' div. It places another div with the same 'scoreboard'
id inside of it. Please fix that.
There are 4 inline notes and you can find a few places where the lines
are over the 80 chars limit.
More information about the aeolus-devel
mailing list