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
Kayli Swaniawski voluptatem quaerat architecto 144.0
Monserrate Swaniawski dolor numquam cumque 119.0
Elaina Schiller quos aut impedit 118.0
Berniece Weimann non et est 117.0
Sheldon Harvey voluptatem quaerat architecto 117.0
Carmel Huel perferendis quaerat qui 117.0
Kamron Graham sint ut ea 116.0
Oleta Rau molestiae laudantium quo 112.0
Mathilde Huels quos aut impedit 111.0
Cristopher Considine voluptatem quaerat architecto 109.0
Elaina Schiller voluptatem quaerat architecto 109.0
Rosanna Schowalter molestiae laudantium quo 108.0
Keyon DuBuque perferendis quaerat qui 108.0
Monroe Rowe perferendis quaerat qui 108.0
Alycia Stracke molestiae laudantium quo 108.0
Moises Kuhlman molestiae laudantium quo 104.0
River Bergnaum molestiae laudantium quo 102.0
Pierre Abernathy et pariatur ut 102.0
Lora Kilback non et est 102.0
Domingo Franecki quos aut impedit 101.0
Jalyn Mante molestiae laudantium quo 101.0
Rosanna Schowalter perferendis quaerat qui 100.0
Jalyn Mante voluptatem quaerat architecto 100.0
Alycia Stracke voluptatem quaerat architecto 100.0
Davion Koepp sint ut ea 100.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>