activeadmin-xls 1.0.5 → 2.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b3cefe4337bc929cc027541a8b378764fcee9c29
4
- data.tar.gz: 6ece12827ba7c2e0b85772b357c368a29d973c51
3
+ metadata.gz: '08d961ae05e4dca5b44e3e1615ce356fb8dd7e59'
4
+ data.tar.gz: 2c8f37c8e0c43cf10e91b9889576efeb3ff98297
5
5
  SHA512:
6
- metadata.gz: a505457094d423aad3857be11f8aaf26adafa48957678296019324c15736be6bc89c40be0b41e4e3ea79ed17d9abd205e4463937aca9f40618193bf7eb3e8de4
7
- data.tar.gz: 689a4ae242134e3cc0e7d7729b539eadca9349bbd141431422b7f0a83b10be7b3f72012ec60c92019b036973b9debe6f3e0b9ef947d35f815a51bb2dffb9c4a2
6
+ metadata.gz: c523bd762b313b3cb7002044462b80d5b300bb49c37606aa2b72da2da5e29702ba3c85c021fd886aad099fb606e6c5f2e0bff78118e872673311e66af7862bf5
7
+ data.tar.gz: fffc68d9617a1b2d61a7e639d4579379f4a4779eaa570d485c52dc86270649171fdf81b5583cf3d0f023ed66267e8011a5339c98fab73e63bddc148bf1ec9d41
data/.gitignore CHANGED
@@ -1,7 +1,7 @@
1
1
  spec/rails
2
2
  *.gem
3
3
  coverage
4
- *.xlsx
4
+ *.xls
5
5
  doc
6
6
  *.un~
7
7
  .yardoc
data/.travis.yml ADDED
@@ -0,0 +1,13 @@
1
+ language: ruby
2
+
3
+ rvm:
4
+ - 2.6.5
5
+
6
+ gemfile:
7
+ - gemfiles/rails_42.gemfile
8
+ - gemfiles/rails_52.gemfile
9
+ - gemfiles/rails_60.gemfile
10
+
11
+ script:
12
+ - bundle exec rake setup
13
+ - bundle exec rake
data/.yardopts ADDED
@@ -0,0 +1 @@
1
+ --no-private --protected lib/**/*.rb - README.md LICENSE
data/CHANGELOG.md CHANGED
@@ -1,33 +1,83 @@
1
1
  # Changelog
2
2
 
3
+ ## [Unreleased]
4
+
5
+ ## 2.0.3
6
+
7
+ ### Changed
8
+
9
+ * ignore test/ folder for gem building [#21][] by [@cprodhomme][]
10
+
11
+ ## 2.0.2
12
+
13
+ ### Changed
14
+
15
+ * Remove ActiveAdmin runtime dependency version limit '<2' [#16][] by [@reaper][]
16
+
17
+ ## 2.0.1
18
+
19
+ ### Fixed
20
+
21
+ * fix issue with xls_builder retaining data between requests when there is an exception on a computed field [#13][]
22
+
23
+ ## 2.0.0
24
+
25
+ ### Changed
26
+
27
+ * Drop support for ruby 1.9, rails 3.2, and ActiveAdmin 0.6.6.
28
+ * Add support for rails 5.1 [#8][]
29
+
30
+ ## 1.1.0
31
+
32
+ ### Added
33
+
34
+ * Add only_columns [#7][]
35
+
36
+ ### Fixed
37
+
38
+ * Fix typo in README.md [#11][] by [@cpunion][]
39
+
40
+ ### Changed
41
+
42
+ * Update tests for ActiveAdmin 1.2
43
+
3
44
  ## 1.0.5
4
45
 
5
- ### Updates
46
+ ### Fixed
6
47
 
7
48
  * Fix #1 - Unnecessary database access
8
49
  * Fix broken tests
9
50
 
10
51
  ## 1.0.4
11
52
 
12
- ### Updates
53
+ ### Fixed
13
54
 
14
55
  * Minor bug fixes / typo corrections
15
56
 
16
57
  ## 1.0.3
17
58
 
18
- ### Updates
59
+ ### Fixed
19
60
 
20
61
  * Move require rake from gemspec to lib/activeadmin-xls.rb [#4][] by [@ejaypcanaria][]
21
62
 
22
63
  ## 1.0.2
23
64
 
24
- ### Bug Fixes
65
+ ### Fixed
25
66
 
26
67
  * Fixes undefined local variable or `method max_per_page` [#3][] by [@rewritten][]
27
68
 
28
69
  <!--- Link List --->
29
70
  [#3]: https://github.com/thambley/activeadmin-xls/issues/3
30
71
  [#4]: https://github.com/thambley/activeadmin-xls/pull/4
72
+ [#7]: https://github.com/thambley/activeadmin-xls/issues/7
73
+ [#8]: https://github.com/thambley/activeadmin-xls/issues/8
74
+ [#11]: https://github.com/thambley/activeadmin-xls/pull/11
75
+ [#13]: https://github.com/thambley/activeadmin-xls/issues/13
76
+ [#16]: https://github.com/thambley/activeadmin-xls/pull/16
77
+ [#21]: https://github.com/thambley/activeadmin-xls/pull/21
31
78
 
32
79
  [@rewritten]: https://github.com/rewritten
33
80
  [@ejaypcanaria]: https://github.com/ejaypcanaria
81
+ [@cpunion]: https://github.com/cpunion
82
+ [@reaper]: https://github.com/reaper
83
+ [@cprodhomme]: https://github.com/cprodhomme
data/Gemfile CHANGED
@@ -4,11 +4,11 @@ gem 'spreadsheet', '~> 1.1', '>= 1.1.4'
4
4
 
5
5
  group :development, :test do
6
6
  gem 'rails-i18n' # Gives us default i18n for many languages
7
- gem 'sqlite3'
8
7
  gem 'yard'
9
8
  end
10
9
 
11
10
  group :test do
11
+ gem 'codecov', require: false
12
12
  gem 'cucumber-rails', require: false
13
13
  gem 'database_cleaner'
14
14
  gem 'rspec-mocks', '~> 3.7'
data/README.md CHANGED
@@ -1,34 +1,38 @@
1
- # Active Admin Xls: Excel Spreadsheet Export for Active Admin
1
+ # Active Admin Xls
2
2
 
3
- **Git**: [http://github.com/thambley/activeadmin-xls](http://github.com/thambley/activeadmin-xls)
3
+ Excel Spreadsheet Export for [Active Admin]
4
4
 
5
- **Author**: Todd Hambley
6
-
7
- **Copyright**: 2014 ~ 2017
8
-
9
- **License**: MIT License
10
-
11
- **Latest Version**: 1.0.4
12
-
13
- **Release Date**: 2017.11.22
5
+ [![Version][rubygems_badge]][rubygems]
6
+ [![Travis CI][travis_badge]][travis]
7
+ [![Quality][codeclimate_badge]][codeclimate]
8
+ [![Coverage][codecov_badge]][codecov]
9
+ [![Inch CI][inch_badge]][inch]
14
10
 
15
11
  ## Synopsis
16
12
 
17
13
  This gem provides xls downloads for Active Admin resources.
18
14
 
19
- This gem borrows heavily from [https://github.com/randym/activeadmin-axlsx](https://github.com/randym/activeadmin-axlsx) and [https://github.com/splendeo/to_xls](https://github.com/splendeo/to_xls).
15
+ This gem borrows heavily from [activeadmin-axlsx] and [to_xls].
20
16
 
21
- Usage example:
17
+ ## Usage
22
18
 
23
- Add the following to your Gemfile and you are good to go.
24
- All resource index views will now include a link for download directly
25
- to xls.
19
+ Add the following to your Gemfile. All resource index views will now include a link for download directly to xls.
26
20
 
27
21
  ```ruby
28
- gem 'activeadmin-xls'
22
+ gem 'activeadmin-xls', '~>2.0.0'
29
23
  ```
30
24
 
31
- ## Cool Toys
25
+ For Active Admin 1.0 and above, you will also have to update config/initializers/active_admin.rb. Update the download\_links setting to include xls:
26
+
27
+ ```ruby
28
+ config.download_links = %i[csv xml json xls]
29
+ ```
30
+
31
+ ## Dependencies
32
+
33
+ This gem depends on [spreadsheet] to generate xls files.
34
+
35
+ ## Examples
32
36
 
33
37
  Here are a few quick examples of things you can easily tweak.
34
38
 
@@ -71,6 +75,15 @@ ActiveAdmin.register Post do
71
75
  end
72
76
  ```
73
77
 
78
+ ### Restrict columns to a list
79
+
80
+ ```ruby
81
+ # app/admin/posts.rb
82
+ ActiveAdmin.register Post do
83
+ config.xls_builder.only_columns :title, :author
84
+ end
85
+ ```
86
+
74
87
  ## Using the DSL
75
88
 
76
89
  Everything that you do with the config's default builder can be done via
@@ -91,10 +104,13 @@ ActiveAdmin.register Post do
91
104
  # Do not serialize the header, only output data.
92
105
  # skip_header
93
106
 
107
+ # restrict columns to a list without customization
108
+ # only_columns :title, :author
109
+
94
110
  # deleting columns from the report
95
111
  delete_columns :id, :created_at, :updated_at
96
112
 
97
- # adding a column to the report
113
+ # adding a column to the report with customization
98
114
  column(:author) { |post| "#{post.author.first_name} #{post.author.last_name}" }
99
115
 
100
116
  # inserting additional data with after_filter
@@ -110,42 +126,66 @@ ActiveAdmin.register Post do
110
126
  end
111
127
  ```
112
128
 
113
- ## Specs
129
+ ## Testing
114
130
 
115
131
  Running specs for this gem requires that you construct a rails application.
116
132
 
117
133
  To execute the specs, navigate to the gem directory, run bundle install and run these to rake tasks:
118
134
 
119
- ### Rails 3.2
135
+ ### Rails 4.2
120
136
 
121
137
  ```text
122
- bundle install --gemfile=gemfiles/rails_32.gemfile
138
+ bundle install --gemfile=gemfiles/rails_42.gemfile
123
139
  ```
124
140
 
125
141
  ```text
126
- BUNDLE_GEMFILE=gemfiles/rails_32.gemfile bundle exec rake setup
142
+ BUNDLE_GEMFILE=gemfiles/rails_42.gemfile bundle exec rake setup
127
143
  ```
128
144
 
129
145
  ```text
130
- BUNDLE_GEMFILE=gemfiles/rails_32.gemfile bundle exec rake
146
+ BUNDLE_GEMFILE=gemfiles/rails_42.gemfile bundle exec rake
131
147
  ```
132
148
 
133
- ### Rails 4.2
149
+ ### Rails 5.2
134
150
 
135
151
  ```text
136
- bundle install --gemfile=gemfiles/rails_42.gemfile
152
+ bundle install --gemfile=gemfiles/rails_52.gemfile
137
153
  ```
138
154
 
139
155
  ```text
140
- BUNDLE_GEMFILE=gemfiles/rails_42.gemfile bundle exec rake setup
156
+ BUNDLE_GEMFILE=gemfiles/rails_52.gemfile bundle exec rake setup
141
157
  ```
142
158
 
143
159
  ```text
144
- BUNDLE_GEMFILE=gemfiles/rails_42.gemfile bundle exec rake
160
+ BUNDLE_GEMFILE=gemfiles/rails_52.gemfile bundle exec rake
145
161
  ```
146
162
 
147
- ## Copyright and License
163
+ ### Rails 6.0
148
164
 
149
- activeadmin-xls &copy; 2014 by [Todd Hambley](mailto:thambley@travelleaders.com).
165
+ ```text
166
+ bundle install --gemfile=gemfiles/rails_60.gemfile
167
+ ```
168
+
169
+ ```text
170
+ BUNDLE_GEMFILE=gemfiles/rails_60.gemfile bundle exec rake setup
171
+ ```
172
+
173
+ ```text
174
+ BUNDLE_GEMFILE=gemfiles/rails_60.gemfile bundle exec rake
175
+ ```
150
176
 
151
- activeadmin-xls is licensed under the MIT license. Please see the LICENSE document for more information.
177
+ [Active Admin]:https://www.activeadmin.info/
178
+ [activeadmin-axlsx]:https://github.com/randym/activeadmin-axlsx
179
+ [to_xls]:https://github.com/splendeo/to_xls
180
+ [spreadsheet]:https://github.com/zdavatz/spreadsheet
181
+
182
+ [rubygems_badge]: https://img.shields.io/gem/v/activeadmin-xls.svg
183
+ [rubygems]: https://rubygems.org/gems/activeadmin-xls
184
+ [travis_badge]: https://img.shields.io/travis/thambley/activeadmin-xls/master.svg
185
+ [travis]: https://travis-ci.org/thambley/activeadmin-xls
186
+ [codeclimate_badge]: https://api.codeclimate.com/v1/badges/e294712bac54d4520182/maintainability
187
+ [codeclimate]: https://codeclimate.com/github/thambley/activeadmin-xls/maintainability
188
+ [codecov_badge]: https://codecov.io/gh/thambley/activeadmin-xls/branch/master/graph/badge.svg
189
+ [codecov]: https://codecov.io/gh/thambley/activeadmin-xls
190
+ [inch_badge]: http://inch-ci.org/github/thambley/activeadmin-xls.svg?branch=master
191
+ [inch]: http://inch-ci.org/github/thambley/activeadmin-xls
data/Rakefile CHANGED
@@ -1,12 +1,31 @@
1
1
  #!/usr/bin/env rake
2
+ require File.expand_path('../lib/active_admin/xls/version', __FILE__)
2
3
  require 'rspec/core/rake_task'
3
4
 
4
5
  desc 'Creates a test rails app for the specs to run against'
5
6
  task :setup do
6
7
  require 'rails/version'
7
- system('mkdir spec/rails') unless File.exist?('spec/rails')
8
- puts "system \"bundle exec rails new spec/rails/rails-#{Rails::VERSION::STRING} -m spec/support/rails_template_with_data.rb\""
9
- system "bundle exec rails new spec/rails/rails-#{Rails::VERSION::STRING} -m spec/support/rails_template_with_data.rb"
8
+ base_dir = 'spec/rails'
9
+ app_dir = "#{base_dir}/rails-#{Rails::VERSION::STRING}"
10
+ template = 'rails_template_with_data'
11
+
12
+ if File.exist? app_dir
13
+ puts "test app #{app_dir} already exists; skipping"
14
+ else
15
+ system "mkdir -p #{base_dir}"
16
+ args = %W[
17
+ -m spec/support/#{template}.rb
18
+ --skip-bundle
19
+ --skip-listen
20
+ --skip-turbolinks
21
+ --skip-test-unit
22
+ --skip-coffee
23
+ ]
24
+
25
+ command = ['bundle', 'exec', 'rails', 'new', app_dir, *args].join(' ')
26
+ env = { 'BUNDLE_GEMFILE' => ENV['BUNDLE_GEMFILE'] }
27
+ Bundler.with_clean_env { Kernel.exec(env, command) }
28
+ end
10
29
  end
11
30
 
12
31
  RSpec::Core::RakeTask.new
@@ -17,6 +36,7 @@ desc 'build the gem'
17
36
  task :build do
18
37
  system 'gem build activeadmin-xls.gemspec'
19
38
  end
39
+
20
40
  desc 'build and release the gem'
21
41
  task release: :build do
22
42
  system "gem push activeadmin-xls-#{ActiveAdmin::Xls::VERSION}.gem"
@@ -19,11 +19,11 @@ Gem::Specification.new do |s|
19
19
  git_tracked_files = `git ls-files`.split("\n").sort
20
20
  gem_ignored_files = `git ls-files -i -X .gemignore`.split("\n")
21
21
 
22
- s.files = git_tracked_files - gem_ignored_files
22
+ s.files = (git_tracked_files - gem_ignored_files).reject { |f| f.match(%r{^(test|spec|features)/}) }
23
23
 
24
- s.add_runtime_dependency 'activeadmin', '>= 0.6.6', '< 2'
24
+ s.add_runtime_dependency 'activeadmin', '>= 1.0.0'
25
25
  s.add_runtime_dependency 'spreadsheet', '~> 1.0'
26
26
 
27
- s.required_ruby_version = '>= 1.9.2'
27
+ s.required_ruby_version = '>= 2.0.0'
28
28
  s.require_path = 'lib'
29
29
  end
@@ -6,9 +6,11 @@ ruby_minor_version = RUBY_VERSION.split('.')[1].to_i
6
6
 
7
7
  eval_gemfile(File.expand_path(File.join('..', 'Gemfile'), __dir__))
8
8
 
9
- gem 'activeadmin', '1.0.0'
9
+ gem 'activeadmin', '1.4.3'
10
10
  gem 'devise', '~> 4.2'
11
- gem 'rails', '4.2.10'
11
+ gem 'rails', '4.2.11'
12
+ gem 'sprockets', '< 4.0'
13
+ gem 'sqlite3', '~> 1.3.0'
12
14
  gem 'turbolinks', '~> 5.0.0'
13
15
  gem 'tzinfo-data'
14
16
 
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env ruby
2
+ source 'https://rubygems.org'
3
+
4
+ ruby_major_version = RUBY_VERSION.split('.')[0].to_i
5
+ ruby_minor_version = RUBY_VERSION.split('.')[1].to_i
6
+
7
+ eval_gemfile(File.expand_path(File.join('..', 'Gemfile'), __dir__))
8
+
9
+ gem 'activeadmin', '2.4.0'
10
+ gem 'bootsnap', require: false
11
+ gem 'devise', '~> 4.7'
12
+ gem 'rails', ' ~> 5.2'
13
+ gem 'sqlite3', '~> 1.4.0'
14
+ gem 'turbolinks', '~> 5.2.0'
15
+ gem 'tzinfo-data'
16
+
17
+ group :test do
18
+ gem 'shoulda-matchers', '~> 3.1'
19
+ if ruby_major_version > 2 || (ruby_major_version == 2 && ruby_minor_version > 1)
20
+ gem 'test-unit', '~> 3.0'
21
+ end
22
+ end
23
+
24
+ gemspec path: "../"
@@ -0,0 +1,25 @@
1
+ #!/usr/bin/env ruby
2
+ source 'https://rubygems.org'
3
+
4
+ ruby_major_version = RUBY_VERSION.split('.')[0].to_i
5
+ ruby_minor_version = RUBY_VERSION.split('.')[1].to_i
6
+
7
+ eval_gemfile(File.expand_path(File.join('..', 'Gemfile'), __dir__))
8
+
9
+ gem 'activeadmin', '2.4.0'
10
+ gem 'bootsnap', require: false
11
+ gem 'devise', '~> 4.7'
12
+ gem 'rails', '~> 6'
13
+ gem 'sqlite3', '~> 1.4.0'
14
+ gem 'turbolinks', '~> 5.2.0'
15
+ gem 'tzinfo-data'
16
+ gem 'webpacker', '~> 4.x'
17
+
18
+ group :test do
19
+ gem 'shoulda-matchers', '~> 3.1'
20
+ if ruby_major_version > 2 || (ruby_major_version == 2 && ruby_minor_version > 1)
21
+ gem 'test-unit', '~> 3.0'
22
+ end
23
+ end
24
+
25
+ gemspec path: "../"
@@ -7,26 +7,28 @@ module ActiveAdmin
7
7
  class Builder
8
8
  include MethodOrProcHelper
9
9
 
10
- # @param resource_class The resource this builder generate column
10
+ # @param [Class] resource_class The resource this builder generate column
11
11
  # information for.
12
- # @param [Hash] options the options for this builder
13
- # @option [Hash] :header_format - a hash of format properties to apply
14
- # to the header row. Any properties specified will be merged with the
15
- # default header styles. @see https://github.com/zdavatz/spreadsheet/blob/master/lib/spreadsheet/format.rb
16
- # @option [Array] :i18n_scope - the I18n scope to use when looking
12
+ # @param [Hash] options the options for the builder
13
+ # @option options [Hash] :header_format A hash of format properties to
14
+ # apply to the header row. Any properties specified will be merged with
15
+ # the default header styles.
16
+ # @option options [Array] :i18n_scope the I18n scope to use when looking
17
17
  # up localized column headers.
18
- # @param [Block] Any block given will evaluated against this instance of
18
+ # @param [Block] block Block given will evaluated against this instance of
19
19
  # Builder. That means you can call any method on the builder from within
20
20
  # that block.
21
21
  # @example
22
- # ActiveAdmin::Xls:Builder.new(Post, i18n: [:xls]) do
22
+ # ActiveAdmin::Xls::Builder.new(Post, i18n: [:xls]) do
23
23
  # delete_columns :id, :created_at, :updated_at
24
24
  # column(:author_name) { |post| post.author.name }
25
- # after_filter { |sheet|
26
- #
27
- # }
25
+ # after_filter do |sheet|
26
+ # # todo
27
+ # end
28
28
  # end
29
- # @see ActiveAdmin::Axlsx::DSL
29
+ #
30
+ # @see DSL
31
+ # @see https://github.com/zdavatz/spreadsheet/blob/master/lib/spreadsheet/format.rb
30
32
  def initialize(resource_class, options = {}, &block)
31
33
  @skip_header = false
32
34
  @resource_class = resource_class
@@ -39,6 +41,8 @@ module ActiveAdmin
39
41
 
40
42
  # The default header style
41
43
  # @return [Hash]
44
+ #
45
+ # @see https://github.com/zdavatz/spreadsheet/blob/master/lib/spreadsheet/format.rb
42
46
  def header_format
43
47
  @header_format ||= {}
44
48
  end
@@ -47,9 +51,28 @@ module ActiveAdmin
47
51
 
48
52
  # This has can be used to override the default header style for your
49
53
  # sheet. Any values you provide will be merged with the default styles.
50
- # Precidence is given to your hash
54
+ # Precedence is given to your hash
55
+ #
56
+ # @example In Builder.new
57
+ # options = {
58
+ # header_format: { weight: :bold },
59
+ # i18n_scope: %i[xls post]
60
+ # }
61
+ # Builder.new(Post, options) do
62
+ # skip_header
63
+ # end
64
+ #
65
+ # @example With DSL
66
+ # ActiveAdmin.register Post do
67
+ # xls(header_format: { weight: :bold }, i18n_scope: %i[xls post]) do
68
+ # skip_header
69
+ # end
70
+ # end
71
+ #
72
+ # @example Simple DSL without block
73
+ # xls header_format: { weight: :bold }
74
+ #
51
75
  # @see https://github.com/zdavatz/spreadsheet/blob/master/lib/spreadsheet/format.rb
52
- # for more details on how to create and apply style.
53
76
  def header_format=(format_hash)
54
77
  @header_format = header_format.merge(format_hash)
55
78
  end
@@ -57,33 +80,85 @@ module ActiveAdmin
57
80
  alias header_style= header_format=
58
81
 
59
82
  # Indicates that we do not want to serialize the column headers
83
+ #
84
+ # @example In Builder.new
85
+ # options = {
86
+ # header_format: { weight: :bold },
87
+ # i18n_scope: %i[xls post]
88
+ # }
89
+ # Builder.new(Post, options) do
90
+ # skip_header
91
+ # end
92
+ #
93
+ # @example With DSL
94
+ # ActiveAdmin.register Post do
95
+ # xls(header_format: { weight: :bold }, i18n_scope: %i[xls post]) do
96
+ # skip_header
97
+ # end
98
+ # end
60
99
  def skip_header
61
100
  @skip_header = true
62
101
  end
63
102
 
64
- # The scope to use when looking up column names to generate the
65
- # report header
66
- attr_reader :i18n_scope
67
-
68
- # This is the I18n scope that will be used when looking up your
69
- # colum names in the current I18n locale.
103
+ # The I18n scope that will be used when looking up your
104
+ # column names in the current I18n locale.
70
105
  # If you set it to [:active_admin, :resources, :posts] the
71
106
  # serializer will render the value at active_admin.resources.posts.title
72
107
  # in the current translations
108
+ #
73
109
  # @note If you do not set this, the column name will be titleized.
74
- attr_writer :i18n_scope
110
+ attr_accessor :i18n_scope
75
111
 
76
112
  # The stored block that will be executed after your report is generated.
113
+ #
114
+ # @yieldparam sheet [Spreadsheet::Worksheet] the worksheet where the
115
+ # collection has been serialized
116
+ #
117
+ # @example With DSL
118
+ # xls do
119
+ # after_filter do |sheet|
120
+ # row_number = sheet.dimensions[1]
121
+ # sheet.update_row(row_number)
122
+ # row_number += 1
123
+ # sheet.update_row(row_number, 'Author Name', 'Number of Posts')
124
+ # users = collection.map(&:author).uniq(&:id)
125
+ # users.each do |user|
126
+ # row_number += 1
127
+ # sheet.update_row(row_number,
128
+ # "#{user.first_name} #{user.last_name}",
129
+ # user.posts.size)
130
+ # end
131
+ # end
132
+ # end
77
133
  def after_filter(&block)
78
134
  @after_filter = block
79
135
  end
80
136
 
81
137
  # the stored block that will be executed before your report is generated.
138
+ #
139
+ # @yieldparam sheet [Spreadsheet::Worksheet] the worksheet where the
140
+ # collection has been serialized
141
+ #
142
+ # @example with DSL
143
+ # xls do
144
+ # before_filter do |sheet|
145
+ # users = collection.map(&:author)
146
+ # users.each do |user|
147
+ # user.first_name = 'Set In Proc' if user.first_name == 'bob'
148
+ # end
149
+ # row_number = sheet.dimensions[1]
150
+ # sheet.update_row(row_number, 'Created', Time.zone.now)
151
+ # row_number += 1
152
+ # sheet.update_row(row_number, '')
153
+ # end
154
+ # end
82
155
  def before_filter(&block)
83
156
  @before_filter = block
84
157
  end
85
158
 
86
- # The columns this builder will be serializing
159
+ # Returns the columns the builder will serialize.
160
+ #
161
+ # @return [Array<Column>] columns configued on the builder.
87
162
  def columns
88
163
  # execute each update from @column_updates
89
164
  # set @columns_loaded = true
@@ -92,13 +167,20 @@ module ActiveAdmin
92
167
  end
93
168
 
94
169
  # The collection we are serializing.
170
+ #
95
171
  # @note This is only available after serialize has been called,
96
172
  # and is reset on each subsequent call.
97
173
  attr_reader :collection
98
174
 
99
- # removes all columns from the builder. This is useful when you want to
175
+ # Removes all columns from the builder. This is useful when you want to
100
176
  # only render specific columns. To remove specific columns use
101
177
  # ignore_column.
178
+ #
179
+ # @example Using alias whitelist
180
+ # Builder.new(Post, header_style: {}, i18n_scope: %i[xls post]) do
181
+ # whitelist
182
+ # column :title
183
+ # end
102
184
  def clear_columns
103
185
  @columns_loaded = true
104
186
  @column_updates = []
@@ -114,6 +196,18 @@ module ActiveAdmin
114
196
  # @param [Symbol] name The name of the column.
115
197
  # @param [Proc] block A block of code that is executed on the resource
116
198
  # when generating row data for this column.
199
+ #
200
+ # @example With block
201
+ # xls(i18n_scope: [:rspec], header_style: { size: 20 }) do
202
+ # delete_columns :id, :created_at
203
+ # column(:author) { |post| post.author.first_name }
204
+ # end
205
+ #
206
+ # @example With default value
207
+ # Builder.new(Post, header_style: {}, i18n_scope: %i[xls post]) do
208
+ # whitelist
209
+ # column :title
210
+ # end
117
211
  def column(name, &block)
118
212
  if @columns_loaded
119
213
  columns << Column.new(name, block)
@@ -125,8 +219,20 @@ module ActiveAdmin
125
219
  end
126
220
  end
127
221
 
128
- # removes columns by name
129
- # each column_name should be a symbol
222
+ # Removes columns by name.
223
+ # Each column_name should be a symbol.
224
+ #
225
+ # @example In Builder.new
226
+ # options = {
227
+ # header_style: { size: 10, color: 'red' },
228
+ # i18n_scope: %i[xls post]
229
+ # }
230
+ # Builder.new(Post, options) do
231
+ # delete_columns :id, :created_at, :updated_at
232
+ # column(:author) do |resource|
233
+ # "#{resource.author.first_name} #{resource.author.last_name}"
234
+ # end
235
+ # end
130
236
  def delete_columns(*column_names)
131
237
  if @columns_loaded
132
238
  columns.delete_if { |column| column_names.include?(column.name) }
@@ -138,27 +244,61 @@ module ActiveAdmin
138
244
  end
139
245
  end
140
246
 
247
+ # Removes all columns, and add columns by name.
248
+ # Each column_name should be a symbol
249
+ #
250
+ # @example
251
+ # config.xls_builder.only_columns :title, :author
252
+ def only_columns(*column_names)
253
+ clear_columns
254
+ column_names.each do |column_name|
255
+ column column_name
256
+ end
257
+ end
258
+
141
259
  # Serializes the collection provided
260
+ #
261
+ # @param collection [Enumerable] list of resources to serialize
262
+ # @param view_context object on which unknown methods may be executed
142
263
  # @return [Spreadsheet::Workbook]
143
264
  def serialize(collection, view_context = nil)
144
265
  @collection = collection
145
266
  @view_context = view_context
267
+ book = Spreadsheet::Workbook.new
268
+ sheet = book.create_worksheet
146
269
  load_columns unless @columns_loaded
147
- apply_filter @before_filter
148
- export_collection(collection)
149
- apply_filter @after_filter
150
- to_stream
270
+ apply_filter @before_filter, sheet
271
+ export_collection collection, sheet
272
+ apply_filter @after_filter, sheet
273
+ to_stream book
151
274
  end
152
275
 
153
- # Xls column
276
+ # Xls column information
154
277
  class Column
278
+ # @param name [String, Symbol] Name of the column. If the name of the
279
+ # column is an existing attribute of the resource class, the value
280
+ # can be retreived automatically if no block is specified
281
+ # @param block [Proc] A procedure to generate data for the column
282
+ # instead of retreiving the value from the resource directly
155
283
  def initialize(name, block = nil)
156
284
  @name = name
157
285
  @data = block || @name
158
286
  end
159
287
 
160
- attr_reader :name, :data
288
+ # @return [String, Symbol] Column name
289
+ attr_reader :name
290
+
291
+ # @return [String, Symbol, Proc] The column name used to look up the
292
+ # value, or a block used to generate the value to display.
293
+ attr_reader :data
161
294
 
295
+ # Returns a localized version of the column name if a scope is given.
296
+ # Otherwise, it returns the titleized column name without translation.
297
+ #
298
+ # @param i18n_scope [String, Symbol, Array<String>, Array<Symbol>]
299
+ # Translation scope. If not provided, the column name will be used.
300
+ #
301
+ # @see I18n
162
302
  def localized_name(i18n_scope = nil)
163
303
  return name.to_s.titleize unless i18n_scope
164
304
  I18n.t name, scope: i18n_scope
@@ -176,18 +316,13 @@ module ActiveAdmin
176
316
  columns
177
317
  end
178
318
 
179
- def to_stream
319
+ def to_stream(book)
180
320
  stream = StringIO.new('')
181
321
  book.write stream
182
- clean_up
183
322
  stream.string
184
323
  end
185
324
 
186
- def clean_up
187
- @book = @sheet = nil
188
- end
189
-
190
- def export_collection(collection)
325
+ def export_collection(collection, sheet)
191
326
  return if columns.none?
192
327
  row_index = sheet.dimensions[1]
193
328
 
@@ -216,7 +351,7 @@ module ActiveAdmin
216
351
  end.compact
217
352
  end
218
353
 
219
- def apply_filter(filter)
354
+ def apply_filter(filter, sheet)
220
355
  filter.call(sheet) if filter
221
356
  end
222
357
 
@@ -238,14 +373,6 @@ module ActiveAdmin
238
373
  resource.respond_to?(column.name)
239
374
  end
240
375
 
241
- def sheet
242
- @sheet ||= book.create_worksheet
243
- end
244
-
245
- def book
246
- @book ||= ::Spreadsheet::Workbook.new
247
- end
248
-
249
376
  def resource_columns(resource)
250
377
  [Column.new(:id)] + resource.content_columns.map do |column|
251
378
  Column.new(column.name.to_sym)