Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add config.horizontal_scroll_list to enable horizontal scrolling colu… #3017

Merged
merged 3 commits into from
May 2, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
(->
$ = jQuery

setFrozenColPositions = ->
$listForm = $('#bulk_form')
return unless $listForm.is('.ra-horizontal-scroll-list')
$listForm.find('table tr').each (index, tr) ->
firstPosition = 0
$(tr).find('.ra-horizontal-scroll-frozen').each (idx, td) ->
tdLeft = $(td).position().left
firstPosition = tdLeft if idx == 0
td.style.left = "#{tdLeft - firstPosition}px"

$(window).on('load', setFrozenColPositions) # Update after link icons load.
$(document).on('rails_admin.dom_ready', setFrozenColPositions)
)()
1 change: 1 addition & 0 deletions app/assets/javascripts/rails_admin/rails_admin.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,6 @@
//= require 'rails_admin/ra.i18n'
//= require 'rails_admin/bootstrap/bootstrap'
//= require 'rails_admin/ra.widgets'
//= require 'rails_admin/ra.horizontal-scroll-list'
//= require 'rails_admin/ui'
//= require 'rails_admin/custom/ui'
29 changes: 29 additions & 0 deletions app/assets/stylesheets/rails_admin/ra.horizontal-scroll-table.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
.ra-horizontal-scroll-table {
margin-bottom: 20px;
overflow-x: auto;
.table {
margin-bottom: 0;
}

.ra-horizontal-scroll-frozen {
position: sticky;
}

// Remove transparency on frozen cells.
$table-bg-default: if($table-bg == transparent, if($body-bg == transparent, #fff, $body-bg), $table-bg) !default;
.table-striped > tbody > tr:nth-child(even) > td, .table-striped > thead > tr > th {
background-color: $table-bg-default;
}
$table-bg-header-sort: #e2eff6 !default;
.table .ra-horizontal-scroll-frozen {
&.headerSortUp, &.headerSortDown {
background-color: $table-bg-header-sort;
}
}

// border-right isn't sticky
.ra-horizontal-scroll-frozen-last {
box-shadow: -1px 0 0 0 $table-border-color inset;
padding-right: $table-condensed-cell-padding + 1px;
}
}
1 change: 1 addition & 0 deletions app/assets/stylesheets/rails_admin/rails_admin.scss.erb
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
@import "rails_admin/bootstrap-datetimepicker-build";
@import "rails_admin/ra.filtering-multiselect";
@import "rails_admin/ra.widgets";
@import "rails_admin/ra.horizontal-scroll-table";
@import "rails_admin/jquery.colorpicker";


Expand Down
84 changes: 49 additions & 35 deletions app/views/rails_admin/main/index.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,13 @@
properties = @model_config.list.with(controller: self.controller, view: self, object: @abstract_model.model.new).visible_fields
checkboxes = @model_config.list.checkboxes?
# columns paginate
sets = get_column_sets(properties)
properties = sets[params[:set].to_i] || []
other_left = ((params[:set].to_i - 1) >= 0) && sets[params[:set].to_i - 1].present?
other_right = sets[params[:set].to_i + 1].present?
horiz_scroll = @model_config.list.horizontal_scroll_list_calc
unless horiz_scroll[:enabled]
sets = get_column_sets(properties)
properties = sets[params[:set].to_i] || []
other_left = ((params[:set].to_i - 1) >= 0) && sets[params[:set].to_i - 1].present?
other_right = sets[params[:set].to_i + 1].present?
end
sbull marked this conversation as resolved.
Show resolved Hide resolved

- content_for :contextual_tabs do
- if checkboxes
Expand Down Expand Up @@ -68,43 +71,54 @@
%li{class: "#{'active' if scope.to_s == params[:scope] || (params[:scope].blank? && index == 0)}"}
%a{href: index_path(params.merge(scope: scope, page: nil)), class: 'pjax'}= I18n.t("admin.scopes.#{@abstract_model.to_param}.#{scope}", default: I18n.t("admin.scopes.#{scope}", default: scope.to_s.titleize))

= form_tag bulk_action_path(model_name: @abstract_model.to_param), method: :post, id: "bulk_form", class: "form" do
= form_tag bulk_action_path(model_name: @abstract_model.to_param), method: :post, id: "bulk_form", class: ["form", horiz_scroll[:num_frozen_columns] > 0 ? "ra-horizontal-scroll-list" : nil].compact.join(' ') do
= hidden_field_tag :bulk_action
- if description.present?
%p
%strong= description

%table.table.table-condensed.table-striped
%thead
%tr
- if checkboxes
%th.shrink
%input.toggle{type: "checkbox"}
- if other_left
%th.other.left.shrink= "..."
- properties.each do |property|
- selected = (sort == property.name.to_s)
- if property.sortable
- sort_location = index_path params.except('sort_reverse').except('page').merge(sort: property.name).merge(selected && sort_reverse != "true" ? {sort_reverse: "true"} : {})
- sort_direction = (sort_reverse == 'true' ? "headerSortUp" : "headerSortDown" if selected)
%th{class: "#{property.sortable && "header pjax" || nil} #{sort_direction if property.sortable && sort_direction} #{property.css_class} #{property.type_css_class}", :'data-href' => (property.sortable && sort_location), rel: "tooltip", title: "#{property.hint}"}= capitalize_first_letter(property.label)
- if other_right
%th.other.right.shrink= "..."
%th.last.shrink
%tbody
- @objects.each do |object|
%tr{class: "#{@abstract_model.param_key}_row #{@model_config.list.with(object: object).row_css_class}"}
.table-wrapper{class: horiz_scroll[:enabled] && 'ra-horizontal-scroll-table'}
%table.table.table-condensed.table-striped
%thead
%tr
- horiz_scroll_i = horiz_scroll[:num_frozen_columns]
- if checkboxes
%td= check_box_tag "bulk_ids[]", object.id, false
- if @other_left_link ||= other_left && index_path(params.except('set').merge(params[:set].to_i != 1 ? {set: (params[:set].to_i - 1)} : {}))
%td.other.left= link_to "...", @other_left_link, class: 'pjax'
- properties.map{ |property| property.bind(:object, object) }.each do |property|
- value = property.pretty_value
%td{class: "#{property.css_class} #{property.type_css_class}", title: strip_tags(value.to_s)}= value
- if @other_right_link ||= other_right && index_path(params.merge(set: (params[:set].to_i + 1)))
%td.other.right= link_to "...", @other_right_link, class: 'pjax'
%td.last.links
%ul.inline.list-inline= menu_for :member, @abstract_model, object, true
%th.shrink{class: [(horiz_scroll_i -= 1) > -1 && 'ra-horizontal-scroll-frozen', horiz_scroll_i == 0 && 'ra-horizontal-scroll-frozen-last']}
%input.toggle{type: "checkbox"}
- if horiz_scroll[:enabled]
%th.last.shrink{class: [(horiz_scroll_i -= 1) > -1 && 'ra-horizontal-scroll-frozen', horiz_scroll_i == 0 && 'ra-horizontal-scroll-frozen-last']}
- elsif other_left
%th.other.left.shrink= "..."
- properties.each do |property|
- selected = (sort == property.name.to_s)
- if property.sortable
- sort_location = index_path params.except('sort_reverse').except('page').merge(sort: property.name).merge(selected && sort_reverse != "true" ? {sort_reverse: "true"} : {})
- sort_direction = (sort_reverse == 'true' ? "headerSortUp" : "headerSortDown" if selected)
%th{class: [property.sortable && "header pjax", property.sortable && sort_direction, property.css_class, property.type_css_class, (horiz_scroll_i -= 1) > -1 && 'ra-horizontal-scroll-frozen', horiz_scroll_i == 0 && 'ra-horizontal-scroll-frozen-last'], :'data-href' => (property.sortable && sort_location), rel: "tooltip", title: "#{property.hint}"}= capitalize_first_letter(property.label)
- unless horiz_scroll[:enabled]
- if other_right
%th.other.right.shrink= "..."
%th.last.shrink
%tbody
- @objects.each do |object|
- horiz_scroll_i = horiz_scroll[:num_frozen_columns]
%tr{class: "#{@abstract_model.param_key}_row #{@model_config.list.with(object: object).row_css_class}"}
- if checkboxes
%td{class: [(horiz_scroll_i -= 1) > -1 && 'ra-horizontal-scroll-frozen', horiz_scroll_i == 0 && 'ra-horizontal-scroll-frozen-last']}= check_box_tag "bulk_ids[]", object.id, false
- td_links = capture do
%td.last.links{class: [(horiz_scroll_i -= 1) > -1 && 'ra-horizontal-scroll-frozen', horiz_scroll_i == 0 && 'ra-horizontal-scroll-frozen-last']}
%ul.inline.list-inline= menu_for :member, @abstract_model, object, true
- if horiz_scroll[:enabled]
= td_links
- elsif @other_left_link ||= other_left && index_path(params.except('set').merge(params[:set].to_i != 1 ? {set: (params[:set].to_i - 1)} : {}))
%td.other.left= link_to "...", @other_left_link, class: 'pjax'
- properties.map{ |property| property.bind(:object, object) }.each do |property|
- value = property.pretty_value
%td{class: [property.css_class, property.type_css_class, (horiz_scroll_i -= 1) > -1 && 'ra-horizontal-scroll-frozen', horiz_scroll_i == 0 && 'ra-horizontal-scroll-frozen-last' ], title: strip_tags(value.to_s)}= value
- unless horiz_scroll[:enabled]
- if @other_right_link ||= other_right && index_path(params.merge(set: (params[:set].to_i + 1)))
%td.other.right= link_to "...", @other_right_link, class: 'pjax'
= td_links

- if @model_config.list.limited_pagination
.row
Expand Down
4 changes: 4 additions & 0 deletions lib/rails_admin/config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ class << self
# Set the max width of columns in list view before a new set is created
attr_accessor :total_columns_width

# Enable horizontal-scroll table in list view, ignore total_columns_width
attr_accessor :horizontal_scroll_list
sbull marked this conversation as resolved.
Show resolved Hide resolved

# set parent controller
attr_accessor :parent_controller

Expand Down Expand Up @@ -285,6 +288,7 @@ def reset
@excluded_models = []
@included_models = []
@total_columns_width = 697
@horizontal_scroll_list = nil
@label_methods = [:name, :title]
@main_app_name = proc { [Rails.application.engine_name.titleize.chomp(' Application'), 'Admin'] }
@registry = {}
Expand Down
24 changes: 24 additions & 0 deletions lib/rails_admin/config/sections/list.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,30 @@ class List < RailsAdmin::Config::Sections::Base
register_instance_option :row_css_class do
''
end

register_instance_option :horizontal_scroll_list do
nil
end

def horizontal_scroll_list_calc
global_config = RailsAdmin::Config.horizontal_scroll_list
model_config = horizontal_scroll_list
enabled = model_config == false ? false : (!!model_config || !!global_config)
if enabled
num_frozen = model_config[:num_frozen_columns] if model_config.is_a?(Hash)
unless num_frozen
num_frozen = global_config[:num_frozen_columns] if global_config.is_a?(Hash)
num_frozen ||= 3 # by default, freeze checkboxes, links & first property (usually primary key / id?)
num_frozen -= 1 unless checkboxes? # model config should be explicit about this, only adjust if using global config
end
else
num_frozen = 0
end
{
enabled: enabled,
num_frozen_columns: num_frozen,
}
end
end
end
end
Expand Down
173 changes: 173 additions & 0 deletions spec/integration/config/list/rails_admin_config_list_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -474,4 +474,177 @@
end
end
end

describe 'horizontal-scroll list option' do
all_team_columns = ['', '', 'Id', 'Created at', 'Updated at', 'Division', 'Name', 'Logo url', 'Team Manager', 'Ballpark', 'Mascot', 'Founded', 'Wins', 'Losses', 'Win percentage', 'Revenue', 'Color', 'Custom field', 'Main Sponsor', 'Players', 'Some Fans', 'Comments']

it "displays all fields on one page when true" do
RailsAdmin.config do |config|
config.horizontal_scroll_list = true
end
FactoryGirl.create_list :team, 3
visit index_path(model_name: 'team')
cols = all('th').collect(&:text)
expect(cols[0..4]).to eq(all_team_columns[0..4])
expect(cols).to contain_exactly(*all_team_columns)
expect(page).to have_selector('.table-wrapper.ra-horizontal-scroll-table')
expect(page).to have_selector('.ra-horizontal-scroll-list')
expect(all('.ra-horizontal-scroll-frozen').count).to eq(12)
expect(all('th.ra-horizontal-scroll-frozen').count).to eq(3)
expect(all('td.ra-horizontal-scroll-frozen').count).to eq(9)
expect(all('.ra-horizontal-scroll-frozen-last').count).to eq(4)
end

it "displays all fields with custom frozen columns" do
RailsAdmin.config do |config|
config.horizontal_scroll_list = {num_frozen_columns: 2}
end
FactoryGirl.create_list :team, 3
visit index_path(model_name: 'team')
cols = all('th').collect(&:text)
expect(cols[0..4]).to eq(all_team_columns[0..4])
expect(cols).to contain_exactly(*all_team_columns)
expect(page).to have_selector('.table-wrapper.ra-horizontal-scroll-table')
expect(page).to have_selector('.ra-horizontal-scroll-list')
expect(all('.ra-horizontal-scroll-frozen').count).to eq(8)
expect(all('th.ra-horizontal-scroll-frozen').count).to eq(2)
expect(all('td.ra-horizontal-scroll-frozen').count).to eq(6)
expect(all('.ra-horizontal-scroll-frozen-last').count).to eq(4)
end

it "displays all fields with no checkboxes" do
RailsAdmin.config do |config|
config.horizontal_scroll_list = true
end
RailsAdmin.config Team do
list do
checkboxes false
end
end
FactoryGirl.create_list :team, 3
visit index_path(model_name: 'team')
cols = all('th').collect(&:text)
expect(cols[0..3]).to eq(all_team_columns[1..4])
expect(cols).to contain_exactly(*all_team_columns[1..-1])
expect(all('.ra-horizontal-scroll-frozen').count).to eq(8)
expect(all('th.ra-horizontal-scroll-frozen').count).to eq(2)
expect(all('td.ra-horizontal-scroll-frozen').count).to eq(6)
expect(all('.ra-horizontal-scroll-frozen-last').count).to eq(4)
end

it "displays all fields with no frozen columns" do
RailsAdmin.config do |config|
config.horizontal_scroll_list = {num_frozen_columns: 0}
end
FactoryGirl.create_list :team, 3
visit index_path(model_name: 'team')
cols = all('th').collect(&:text)
expect(cols[0..4]).to eq(all_team_columns[0..4])
expect(cols).to contain_exactly(*all_team_columns)
expect(page).to have_selector('.table-wrapper.ra-horizontal-scroll-table')
expect(page).not_to have_selector('.ra-horizontal-scroll-list')
expect(all('.ra-horizontal-scroll-frozen').count).to eq(0)
expect(all('.ra-horizontal-scroll-frozen-last').count).to eq(0)
end

it "displays sets when not set" do
visit index_path(model_name: 'team')
expect(all('th').collect(&:text)).to eq ['', 'Id', 'Created at', 'Updated at', 'Division', 'Name', 'Logo url', '...', '']
expect(page).to have_selector('.table-wrapper')
expect(page).not_to have_selector('.table-wrapper.ra-horizontal-scroll-table')
expect(page).not_to have_selector('.ra-horizontal-scroll-list')
expect(all('.ra-horizontal-scroll-frozen').count).to eq(0)
expect(all('.ra-horizontal-scroll-frozen-last').count).to eq(0)
end

it "displays sets when global config is on but model config is off" do
RailsAdmin.config do |config|
config.horizontal_scroll_list = true
end
RailsAdmin.config Team do
list do
horizontal_scroll_list false
end
end
visit index_path(model_name: 'team')
expect(all('th').collect(&:text)).to eq ['', 'Id', 'Created at', 'Updated at', 'Division', 'Name', 'Logo url', '...', '']
expect(page).to have_selector('.table-wrapper')
expect(page).not_to have_selector('.table-wrapper.ra-horizontal-scroll-table')
expect(page).not_to have_selector('.ra-horizontal-scroll-list')
expect(all('.ra-horizontal-scroll-frozen').count).to eq(0)
expect(all('.ra-horizontal-scroll-frozen-last').count).to eq(0)
end

it "displays all fields when global config is off but model config is on" do
RailsAdmin.config Team do
list do
horizontal_scroll_list true
end
end
FactoryGirl.create_list :team, 3
visit index_path(model_name: 'team')
cols = all('th').collect(&:text)
expect(cols[0..4]).to eq(all_team_columns[0..4])
expect(cols).to contain_exactly(*all_team_columns)
expect(page).to have_selector('.table-wrapper.ra-horizontal-scroll-table')
expect(page).to have_selector('.ra-horizontal-scroll-list')
expect(all('.ra-horizontal-scroll-frozen').count).to eq(12)
expect(all('th.ra-horizontal-scroll-frozen').count).to eq(3)
expect(all('td.ra-horizontal-scroll-frozen').count).to eq(9)
expect(all('.ra-horizontal-scroll-frozen-last').count).to eq(4)
end

it "displays all fields with custom model config settings" do
RailsAdmin.config do |config|
config.horizontal_scroll_list = true
end
RailsAdmin.config Team do
list do
horizontal_scroll_list(num_frozen_columns: 2)
end
end
FactoryGirl.create_list :team, 3
FactoryGirl.create_list :player, 3
visit index_path(model_name: 'team')
cols = all('th').collect(&:text)
expect(cols[0..4]).to eq(all_team_columns[0..4])
expect(cols).to contain_exactly(*all_team_columns)
expect(page).to have_selector('.table-wrapper.ra-horizontal-scroll-table')
expect(page).to have_selector('.ra-horizontal-scroll-list')
expect(all('.ra-horizontal-scroll-frozen').count).to eq(8)
expect(all('th.ra-horizontal-scroll-frozen').count).to eq(2)
expect(all('td.ra-horizontal-scroll-frozen').count).to eq(6)
expect(all('.ra-horizontal-scroll-frozen-last').count).to eq(4)
visit index_path(model_name: 'player')
expect(page).to have_selector('.table-wrapper.ra-horizontal-scroll-table')
expect(page).to have_selector('.ra-horizontal-scroll-list')
expect(all('.ra-horizontal-scroll-frozen').count).to eq(12)
expect(all('th.ra-horizontal-scroll-frozen').count).to eq(3)
expect(all('td.ra-horizontal-scroll-frozen').count).to eq(9)
expect(all('.ra-horizontal-scroll-frozen-last').count).to eq(4)
end

it "displays all fields with model config checkbox settings" do
RailsAdmin.config do |config|
config.horizontal_scroll_list = true
end
RailsAdmin.config Team do
list do
horizontal_scroll_list(num_frozen_columns: 3)
checkboxes false
end
end
FactoryGirl.create_list :team, 3
visit index_path(model_name: 'team')
cols = all('th').collect(&:text)
expect(cols[0..3]).to eq(all_team_columns[1..4])
expect(cols).to contain_exactly(*all_team_columns[1..-1])
expect(page).to have_selector('.table-wrapper.ra-horizontal-scroll-table')
expect(page).to have_selector('.ra-horizontal-scroll-list')
expect(all('.ra-horizontal-scroll-frozen').count).to eq(12)
expect(all('th.ra-horizontal-scroll-frozen').count).to eq(3)
expect(all('td.ra-horizontal-scroll-frozen').count).to eq(9)
expect(all('.ra-horizontal-scroll-frozen-last').count).to eq(4)
end
end
end