kanbanworkflowstimelinescrumrubyroadmapproject-planningproject-managementopenprojectangularissue-trackerifcgantt-chartganttbug-trackerboardsbcf
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
188 lines
4.0 KiB
188 lines
4.0 KiB
##
|
|
# Abstract cell. Subclass this for a concrete table.
|
|
class TableCell < RailsCell
|
|
include UsersHelper
|
|
include SortHelper
|
|
include PaginationHelper
|
|
include WillPaginate::ActionView
|
|
|
|
options :groups, :roles, :status, :project
|
|
options show_inline_create: true
|
|
options table_id: nil
|
|
|
|
class << self
|
|
##
|
|
# Names used by sort logic meaning these names
|
|
# will be used directly in the generated SQL queries.
|
|
#
|
|
# This will also generate getters for these columns
|
|
# on the RowCell class for this TableCell. The getters
|
|
# are calling the same methods on the model for the Row.
|
|
# E.g.:
|
|
#
|
|
# Users::TableCell.columns :weight
|
|
# model = Struct.new(:weight).new 42
|
|
# row_cell = Users::Table::RowCell.new model
|
|
# row_cell.weight == model.weight
|
|
def columns(*names)
|
|
return Array(@columns) if names.empty?
|
|
|
|
@columns = names.map(&:to_sym)
|
|
rc = row_class
|
|
|
|
names.each do |name|
|
|
rc.property name
|
|
end
|
|
end
|
|
|
|
##
|
|
# Define which of the registered columns are sortable
|
|
# Applies only if +sortable?+ is true
|
|
def sortable_columns(*names)
|
|
if names.present?
|
|
@sortable_columns = names.map(&:to_sym)
|
|
# set available criteria
|
|
return
|
|
end
|
|
|
|
# return all columns unless defined otherwise
|
|
if @sortable_columns.nil?
|
|
columns
|
|
else
|
|
Array(@sortable_columns)
|
|
end
|
|
end
|
|
|
|
def add_column(name)
|
|
@columns = Array(@columns) + [name]
|
|
row_class.property name
|
|
end
|
|
|
|
def row_class
|
|
mod = namespace || "Table"
|
|
class_name = "RowCell"
|
|
|
|
"#{mod}::#{class_name}".constantize
|
|
rescue NameError
|
|
raise(
|
|
NameError,
|
|
"#{mod}::#{class_name} required by #{mod}::TableCell not defined. " +
|
|
"Expected to be defined in `app/cells/#{mod.underscore}/#{class_name.underscore}.rb`."
|
|
)
|
|
end
|
|
|
|
def namespace
|
|
name.split("::")[0..-2].join("::").presence
|
|
end
|
|
end
|
|
|
|
def prepare
|
|
initialize_sorted_model if sortable?
|
|
end
|
|
|
|
def initialize_sorted_model
|
|
sort_init *initial_sort.map(&:to_s)
|
|
sort_update sortable_columns.map(&:to_s)
|
|
@model = paginate_collection apply_sort(model)
|
|
end
|
|
|
|
def apply_sort(model)
|
|
case model
|
|
when ActiveRecord::QueryMethods
|
|
sort_collection(model, sort_clause)
|
|
when Queries::BaseQuery
|
|
model
|
|
.order(@sort_criteria.to_query_hash)
|
|
.results
|
|
else
|
|
raise ArgumentError, "Cannot sort the given model class #{model.class}"
|
|
end
|
|
end
|
|
|
|
##
|
|
# Sorts the data to be displayed.
|
|
#
|
|
# @param query [ActiveRecord::QueryMethods] An active record collection.
|
|
# @param sort_clause [String] The SQL used as the sort clause.
|
|
def sort_collection(query, sort_clause)
|
|
query
|
|
.reorder(sort_clause)
|
|
.order(Arel.sql(initial_order))
|
|
end
|
|
|
|
def paginate_collection(query)
|
|
query
|
|
.page(page_param(controller.params))
|
|
.per_page(per_page_param)
|
|
end
|
|
|
|
def rows
|
|
model
|
|
end
|
|
|
|
def columns
|
|
self.class.columns
|
|
end
|
|
|
|
def sortable_columns
|
|
self.class.sortable_columns
|
|
end
|
|
|
|
def render_row(row)
|
|
cell(self.class.row_class, row, table: self).call
|
|
end
|
|
|
|
def initial_sort
|
|
[columns.first, :asc]
|
|
end
|
|
|
|
def initial_order
|
|
initial_sort.join(' ')
|
|
end
|
|
|
|
def paginated?
|
|
rows.respond_to? :total_entries
|
|
end
|
|
|
|
def build_sort_header(column, options)
|
|
sort_header_tag(column, options)
|
|
end
|
|
|
|
def button_header
|
|
content_tag :div, '', class: 'generic-table--empty-header'
|
|
end
|
|
|
|
def inline_create_link
|
|
nil
|
|
end
|
|
|
|
def sortable?
|
|
true
|
|
end
|
|
|
|
def sortable_column?(column)
|
|
sortable? && sortable_columns.include?(column.to_sym)
|
|
end
|
|
|
|
##
|
|
# An array listing each column and its respective options.
|
|
#
|
|
# @return Array<Array>
|
|
def headers
|
|
columns.map { |name| [name.to_s, {}] }
|
|
end
|
|
|
|
def empty_row_message
|
|
I18n.t :no_results_title_text
|
|
end
|
|
|
|
# required by the sort helper
|
|
|
|
delegate :controller_name, to: :controller
|
|
|
|
delegate :action_name, to: :controller
|
|
|
|
def options
|
|
super
|
|
end
|
|
end
|
|
|