User Grid (basic) Time Sheets Grid (advanced)

Developer Project Report hours
Almeta Adams odio velit repudiandae 53.0
Alex Legros odio velit repudiandae 53.0
Cherly Kovacek suscipit consectetur beatae 53.0
Sixta Bashirian doloribus hic corporis 53.0
Maryanna Medhurst doloribus hic corporis 53.0
Desmond Murray doloribus hic corporis 53.0
Bong Witting doloribus hic corporis 53.0
Dania Crona vitae eum pariatur 53.0
Sylvester Hane saepe hic temporibus 53.0
Benita Thompson saepe hic temporibus 53.0
Juliana Hauck repudiandae officiis qui 53.0
Wiley Wuckert eum amet quia 53.0
Jamison Hagenes animi aperiam tenetur 53.0
Clifton Hintz odio velit repudiandae 53.0
Felisa Jaskolski eum amet quia 54.0
Crissy Brekke animi aperiam tenetur 54.0
Rossana Schneider eum amet quia 54.0
Royce Spencer animi aperiam tenetur 54.0
Jon Lindgren odio velit repudiandae 54.0
Dona Gutkowski saepe hic temporibus 54.0
Treena Wolf eum amet quia 54.0
Shannon Botsford eum amet quia 54.0
Myrtle O'Conner doloribus hic corporis 54.0
Marna Ritchie eum amet quia 54.0
Salley Kilback eum amet quia 54.0

Grid:

class TimeEntriesGrid < BaseGrid

  #
  # 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 => :project_id_select,
    :multiple => true,
    :include_blank => false
  ) do |value|
    self.where(:time_entries => {:project_id => value})
  end


  filter(
    :year, :enum,
    :select => :year_select,
    :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 => :month_select,
    :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)")

  protected

  def year_select
    TimeEntry.all.any? ? (TimeEntry.minimum(:date).year..TimeEntry.maximum(:date).year) : []
  end
  def month_select
    Date::MONTHNAMES[1..12].enum_for(:each_with_index).collect {|name, index| [name, index + 1]}
  end

  def project_id_select
    Project.all.map {|p| [p.name, p.id]}
  end
end

Controller:

class TimeEntriesController < ApplicationController

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

View:

.grid-index-grid
  %div{class: 'overflow-x-auto p-4'}
    = datagrid_form_for @time_entries_grid, url: time_entries_path
    %br/
    = datagrid_table(@time_entries_grid)
    = paginate @time_entries_grid.assets, window: 2
  %div
    = render :partial => "shared/source", :object => @time_entries_grid