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
Pierre Abernathy consequuntur nihil quo 82.0
Berniece Weimann minus quaerat quo 75.0
Ambrose Marvin molestiae laudantium quo 57.0
Isabel Okuneva molestiae laudantium quo 125.0
Constance Ward consequuntur nihil quo 77.0
Pierre Abernathy minus quaerat quo 49.0
River Bergnaum consequuntur nihil quo 60.0
Rylee Fadel voluptatem quaerat architecto 80.0
Carmel Huel molestiae laudantium quo 76.0
Mikayla Goldner minus quaerat quo 44.0
Kolby Murazik consequuntur nihil quo 59.0
Triston Lynch consequuntur nihil quo 48.0
Louisa Franecki minus quaerat quo 67.0
Domingo Franecki molestiae laudantium quo 32.0
Leonardo Smith voluptatem quaerat architecto 60.0
Berniece Weimann consequuntur nihil quo 39.0
Mikayla Goldner consequuntur nihil quo 75.0
River Bergnaum minus quaerat quo 70.0
Cathryn Boehm voluptatem quaerat architecto 40.0
Kolby Murazik minus quaerat quo 73.0
Triston Lynch minus quaerat quo 65.0
Louisa Franecki consequuntur nihil quo 89.0
Constance Ward minus quaerat quo 100.0
Colin Harber minus quaerat quo 94.0
Jacky Kreiger molestiae laudantium quo 105.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>