Gem source code Demo source code
Author: Bogdan Gusiev

User Grid (basic) Time Entry Grid (advanced) Document Grid (Mongoid)

Time Entries Grid


Developer Project Report hours
Austin Heathcote minus quaerat quo 54.0
Austin Heathcote dolor numquam cumque 97.0
Austin Heathcote non et est 80.0
Austin Heathcote sint ut ea 74.0
Austin Heathcote molestiae laudantium quo 37.0
Benedict Muller non et est 70.0
Benedict Muller minus quaerat quo 48.0
Benedict Muller et pariatur ut 39.0
Benedict Muller dolor numquam cumque 48.0
Benedict Muller voluptatem quaerat architecto 71.0
Benedict Muller quos aut impedit 55.0
Benedict Muller consequuntur nihil quo 102.0
Benedict Muller perferendis quaerat qui 49.0
Benedict Muller sint ut ea 53.0
Benedict Muller molestiae laudantium quo 58.0
Bernhard Buckridge sint ut ea 65.0
Bernhard Buckridge molestiae laudantium quo 45.0
Bernhard Buckridge non et est 66.0
Bernhard Buckridge consequuntur nihil quo 84.0
Bernhard Buckridge dolor numquam cumque 100.0
Bernhard Buckridge quos aut impedit 47.0
Bernhard Buckridge et pariatur ut 107.0
Bernhard Buckridge perferendis quaerat qui 73.0
Bernhard Buckridge voluptatem quaerat architecto 39.0
Bernhard Buckridge minus quaerat quo 67.0

Grid:

class TimeEntriesGrid

  include Datagrid

  #
  # Scope
  #

  scope do
    User.select(
      "users.name, projects.name as project_name, accounts.name as account_name, sum(time_entries.hours) as report_hours"
    ).joins(:time_entries => {:project => :account}).group("projects.name", "users.name", "accounts.name").order("users.name")

  end


  #
  # Filters
  #

  filter(:project_id, :enum,
    :select => lambda {Project.all.map {|p| [p.name, p.id]}},
    :multiple => true,
    :include_blank => false
  ) do |value|
    self.where(:time_entries => {:project_id => value})
  end


  filter(:year, :enum,
         :select => lambda { TimeEntry.all.any? ? (TimeEntry.minimum(:date).year..TimeEntry.maximum(:date).year) : []},
    :include_blank => false,
    :default => lambda {Date.today.year}
  ) do |value|
    self.where(["extract(year from time_entries.date) = ?", value.to_i])
  end

  filter(:month, :enum,
         :select => Date::MONTHNAMES[1..12].enum_for(:each_with_index).collect {|name, index| [name, index + 1]},
         :include_blank => false,
         :default => lambda {Date.today.month}
        ) do |value|

    self.where(["extract(month from time_entries.date) = ?", value.to_i])
  end


  #
  # Columns
  #

  column(:user_name, :header => "Developer", :order => "users.name") do
    self.name
  end
  column(:project_name, :header => "Project", :order => "projects.name")
  column(
    :account_name,
    :header => "Company",
    :order => "accounts.name",
  ) do |model|
    format(model.account_name) do
      render :partial => "time_entries/company", :locals => {:model => model}
    end
  end

  column(:report_hours, order: "sum(time_entries.hours)")

end

Controller:

class TimeEntriesController < ApplicationController

  def index
    @time_entries_grid = TimeEntriesGrid.new(params[:time_entries_grid]) do |scope|
      scope.page(params[:page])
    end
  end
end

View:


<h3>Time Entries Grid</h3>


<div class="left">
  <%= datagrid_form_for @time_entries_grid, url: time_entries_path %>
  <br/>

  <%= datagrid_table(@time_entries_grid) %>
  <%= paginate @time_entries_grid.assets %>

</div>

<div class="right">
  <%= render :partial => "shared/source", :object => @time_entries_grid %>
</div>