Closed Ellerden closed 4 years ago
Give me your current grid source code and I'll show how to add a "Total" row.
I already have a total row added it in the controller:
@stats_grid = StatsGrid.new(params[:stats_grid])
@total_by_day_row = ['Total', *([0] * 8)]
The thing is that I need to have all 'stage-filters' results as rows when 'totals' filter selected.
Here's the grid code:
class StatsGrid
include Datagrid
#
# Scope
#
scope do
Team.left_joins(recruiters: { user: :events })
.where('events.type': %w[placement_added placement_stage_changed])
.where.not('events.placement_id': nil)
.group('teams.id')
.order(:name)
end
#
# Filters
#
filter(
:status,
:enum,
select: Placement::STATS_STAGES.map { |v| [v.humanize, v] },
default: 'contacted',
include_blank: false
) do |stage|
query = if stage == 'sourced'
where("events.type = 'placement_added' OR events.properties->>'to' = 'sourced'")
else
where("events.properties->>'to' = ?", stage)
end
query
end
filter(
:performed_at,
:date,
default: Time.zone.now.beginning_of_week
) do |first_day_of_week, scope|
query = []
week = first_day_of_week.all_week
week.each do |day|
query.push(
"count(events.id) filter (where CAST(events.performed_at AS DATE) = ?) AS #{
day.strftime('%A')}"
)
end
scope.select(
"teams.*, count(events.id) AS total,
#{ActiveRecord::Base.sanitize_sql_array([query.join(', '), *week.to_a])}"
).where('events.performed_at': first_day_of_week..first_day_of_week + 1.week)
end
#
# Columns
#
column(:name) do |team, grid|
format(true) do
link_to team.name, display_team_path(
team.id,
:stats_by_recruiter,
team_stats_by_recruiter_grid: {
status: grid.status,
performed_at: grid.performed_at
}
)
end
end
dynamic do |grid|
performed_at.all_week.each do |day|
column(day.strftime('%A') + " #{day.day}", html: true) do |team|
team[day.strftime('%A').downcase]
end
end
end
column('total')
end
end
Placement::STATS_STAGES that are used as filters:
STATS_STAGES = %w[sourced contacted replied interviewed totals].freeze
Here is what you can do:
class StatsGrid
dynamic do |grid|
performed_at.all_week.each do |day|
column(grid.date_column_name(day), header: day.strftime('%A') + " #{day.day}") do |team|
format(team[day.strftime('%A').downcase) do |value|
value # I am not sure why the column is html only in your code - apply your formatting if any
end
end
end
def date_column_name(date)
:"day_#{date.strftime("%A").downcase}"
end
def total_row
['Total'] + performed_at.all_weeks.map do |day|
assets.sum {|row| data_value(row, date_column_name(day))}
end
end
View code (HAML for simplicity):
%table
= datagrid_header(@grid)
= datagrid_rows(@grid)
-# you can define a helper like datagrid_total_row if you want
%tr
- @grid.total_row.each do |value|
%td= value
Thanks, for the answer. Also, is it possible to show array of constants as a column?
I'd like to display each filter of STATS_STAGES as a row in column 'Name'.
STATS_STAGES = %w[sourced contacted replied interviewed totals].freeze
I am not sure why would you have problems with as you are already familiar with dynamic
. Please explain in more clearly.
Sorry, got it figured out) Thanks for your help
I use filters in grid (e.g. contacted/replied/canceled) and the last filter is 'Totals' - which basically should show all other filters at once as rows in one grid. Is it possible to do so? Or maybe there's a way to include a grid inside a grid when choosing a filter?
Here's what I mean — the usual, let's say 'contacted' filter is shown
So I should have smth like this in the end.