User Grid (basic) Time Sheets Grid (advanced)

Developer Project Report hours
Shane Glover eum amet quia 55.0
Myriam Von doloribus hic corporis 55.0
Felisa Jaskolski saepe hic temporibus 55.0
Clifton Hintz animi aperiam tenetur 55.0
Treena Wolf vitae eum pariatur 56.0
Desmond Murray suscipit consectetur beatae 56.0
Isidro McCullough odio velit repudiandae 56.0
Milagros Lemke animi aperiam tenetur 56.0
Lillie Hamill suscipit consectetur beatae 56.0
Joelle Hodkiewicz odio velit repudiandae 56.0
Ophelia Hermiston quibusdam sed sit 56.0
Wen Daniel perspiciatis totam perferendis 56.0
Shane Glover repudiandae officiis qui 56.0
Cristopher Dooley saepe hic temporibus 56.0
Royce Spencer suscipit consectetur beatae 56.0
Joelle Hodkiewicz eum amet quia 56.0
Deja Corkery perspiciatis totam perferendis 56.0
Royce Spencer perspiciatis totam perferendis 56.0
Cathey Prohaska eum amet quia 56.0
Li Considine quibusdam sed sit 56.0
Lesia Hyatt perspiciatis totam perferendis 56.0
Treena Wolf suscipit consectetur beatae 56.0
Almeta Adams suscipit consectetur beatae 56.0
Terisa Ruecker vitae eum pariatur 56.0
Maryanna Medhurst odio velit repudiandae 57.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