activeadmin-xls 1.1.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a30a7f1fc93455cecb1aac5d28026454061ebdcd
4
- data.tar.gz: a1342476206f3a3b7ba04c15df545d620af315eb
3
+ metadata.gz: 0061e54090d183ee6259739d20d7db62eb890790
4
+ data.tar.gz: 7691fe01a10bcdd3aac3239f690ae98f95258460
5
5
  SHA512:
6
- metadata.gz: acd27c54cbf49c5148d94625f4872b89291513fbea277ff8fb0e96231a40ce8172fb9cae4d91ad4e1adeda135ce45feb704a5396a2c66252a49f97abf3ab9de8
7
- data.tar.gz: 9baa56bf539d13050c67b6a9e911323a0d5bd04bd43b6182eb32f0de4e6c125aaca61b32adafa86addd387072d751db5497f1b3273320abbd2aa044912b19f0e
6
+ metadata.gz: 522ac0e6309ad124d216acdd64228efec606836dd75369f90b9f8e2e806e017c658190a841c56bf54b3e77fe72bd3b5cac00be571db3602745a22f432855f33d
7
+ data.tar.gz: ffab449bd41cfb19b97d5b879d656f531a2cde929e98a5188b90765a5bce506200fd328f3f49a1ce4819d8837c8d5e994839abf4a36bd3c8e2dc1cbff97d1990
@@ -0,0 +1,12 @@
1
+ language: ruby
2
+
3
+ rvm:
4
+ - 2.2
5
+
6
+ gemfile:
7
+ - gemfiles/rails_42.gemfile
8
+ - gemfiles/rails_51.gemfile
9
+
10
+ script:
11
+ - bundle exec rake setup
12
+ - bundle exec rake
@@ -0,0 +1 @@
1
+ --no-private --protected lib/**/*.rb - README.md LICENSE
data/Gemfile CHANGED
@@ -14,4 +14,5 @@ group :test do
14
14
  gem 'rspec-mocks', '~> 3.7'
15
15
  gem 'rspec-rails', '~> 3.7'
16
16
  gem 'simplecov', require: false
17
+ gem 'codecov', require: false
17
18
  end
data/README.md CHANGED
@@ -1,23 +1,25 @@
1
1
  # Active Admin Xls
2
2
 
3
- Excel Spreadsheet Export for [Active Admin](https://www.activeadmin.info/)
3
+ Excel Spreadsheet Export for [Active Admin]
4
4
 
5
- [![Gem Version](https://badge.fury.io/rb/activeadmin-xls.svg)](https://badge.fury.io/rb/activeadmin-xls)
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]
6
10
 
7
11
  ## Synopsis
8
12
 
9
13
  This gem provides xls downloads for Active Admin resources.
10
14
 
11
- 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].
12
16
 
13
- Usage example:
17
+ ## Usage
14
18
 
15
- Add the following to your Gemfile and you are good to go.
16
- All resource index views will now include a link for download directly
17
- to xls.
19
+ Add the following to your Gemfile. All resource index views will now include a link for download directly to xls.
18
20
 
19
21
  ```ruby
20
- gem 'activeadmin-xls', '~>1.1.0'
22
+ gem 'activeadmin-xls', '~>2.0.0'
21
23
  ```
22
24
 
23
25
  For Active Admin 1.0, you will also have to update config/initializers/active_admin.rb. Update the download\_links setting to include xls:
@@ -26,6 +28,10 @@ For Active Admin 1.0, you will also have to update config/initializers/active_ad
26
28
  config.download_links = %i[csv xml json xls]
27
29
  ```
28
30
 
31
+ ## Dependencies
32
+
33
+ This gem depends on [spreadsheet] to generate xls files.
34
+
29
35
  ## Examples
30
36
 
31
37
  Here are a few quick examples of things you can easily tweak.
@@ -126,30 +132,46 @@ Running specs for this gem requires that you construct a rails application.
126
132
 
127
133
  To execute the specs, navigate to the gem directory, run bundle install and run these to rake tasks:
128
134
 
129
- ### Rails 3.2
135
+ ### Rails 4.2
130
136
 
131
137
  ```text
132
- bundle install --gemfile=gemfiles/rails_32.gemfile
138
+ bundle install --gemfile=gemfiles/rails_42.gemfile
133
139
  ```
134
140
 
135
141
  ```text
136
- BUNDLE_GEMFILE=gemfiles/rails_32.gemfile bundle exec rake setup
142
+ BUNDLE_GEMFILE=gemfiles/rails_42.gemfile bundle exec rake setup
137
143
  ```
138
144
 
139
145
  ```text
140
- BUNDLE_GEMFILE=gemfiles/rails_32.gemfile bundle exec rake
146
+ BUNDLE_GEMFILE=gemfiles/rails_42.gemfile bundle exec rake
141
147
  ```
142
148
 
143
- ### Rails 4.2
149
+ ### Rails 5.1
144
150
 
145
151
  ```text
146
- bundle install --gemfile=gemfiles/rails_42.gemfile
152
+ bundle install --gemfile=gemfiles/rails_51.gemfile
147
153
  ```
148
154
 
149
155
  ```text
150
- BUNDLE_GEMFILE=gemfiles/rails_42.gemfile bundle exec rake setup
156
+ BUNDLE_GEMFILE=gemfiles/rails_51.gemfile bundle exec rake setup
151
157
  ```
152
158
 
153
159
  ```text
154
- BUNDLE_GEMFILE=gemfiles/rails_42.gemfile bundle exec rake
160
+ BUNDLE_GEMFILE=gemfiles/rails_51.gemfile bundle exec rake
155
161
  ```
162
+
163
+ [Active Admin]:https://www.activeadmin.info/
164
+ [activeadmin-axlsx]:https://github.com/randym/activeadmin-axlsx
165
+ [to_xls]:https://github.com/splendeo/to_xls
166
+ [spreadsheet]:https://github.com/zdavatz/spreadsheet
167
+
168
+ [rubygems_badge]: https://img.shields.io/gem/v/activeadmin-xls.svg
169
+ [rubygems]: https://rubygems.org/gems/activeadmin-xls
170
+ [travis_badge]: https://img.shields.io/travis/thambley/activeadmin-xls/master.svg
171
+ [travis]: https://travis-ci.org/thambley/activeadmin-xls
172
+ [codeclimate_badge]: https://api.codeclimate.com/v1/badges/e294712bac54d4520182/maintainability
173
+ [codeclimate]: https://codeclimate.com/github/thambley/activeadmin-xls/maintainability
174
+ [codecov_badge]: https://codecov.io/gh/thambley/activeadmin-xls/branch/master/graph/badge.svg
175
+ [codecov]: https://codecov.io/gh/thambley/activeadmin-xls
176
+ [inch_badge]: http://inch-ci.org/github/thambley/activeadmin-xls.svg?branch=master
177
+ [inch]: http://inch-ci.org/github/thambley/activeadmin-xls
data/Rakefile CHANGED
@@ -5,8 +5,27 @@ require 'rspec/core/rake_task'
5
5
  desc 'Creates a test rails app for the specs to run against'
6
6
  task :setup do
7
7
  require 'rails/version'
8
- system('mkdir spec/rails') unless File.exist?('spec/rails')
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
@@ -21,9 +21,9 @@ Gem::Specification.new do |s|
21
21
 
22
22
  s.files = git_tracked_files - gem_ignored_files
23
23
 
24
- s.add_runtime_dependency 'activeadmin', '>= 0.6.6', '< 2'
24
+ s.add_runtime_dependency 'activeadmin', '>= 1.0.0', '< 2'
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
@@ -0,0 +1,22 @@
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', '1.2.1'
10
+ gem 'devise', '~> 4.2'
11
+ gem 'rails', '5.1.5'
12
+ gem 'turbolinks', '~> 5.0.0'
13
+ gem 'tzinfo-data'
14
+
15
+ group :test do
16
+ gem 'shoulda-matchers', '~> 3.1'
17
+ if ruby_major_version > 2 || (ruby_major_version == 2 && ruby_minor_version > 1)
18
+ gem 'test-unit', '~> 3.0'
19
+ end
20
+ end
21
+
22
+ 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::xls::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,8 +244,11 @@ module ActiveAdmin
138
244
  end
139
245
  end
140
246
 
141
- # remove all columns, and add columns by name
142
- # each column_name should be a symbol
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
143
252
  def only_columns(*column_names)
144
253
  clear_columns
145
254
  column_names.each do |column_name|
@@ -148,6 +257,9 @@ module ActiveAdmin
148
257
  end
149
258
 
150
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
151
263
  # @return [Spreadsheet::Workbook]
152
264
  def serialize(collection, view_context = nil)
153
265
  @collection = collection
@@ -159,15 +271,32 @@ module ActiveAdmin
159
271
  to_stream
160
272
  end
161
273
 
162
- # Xls column
274
+ # Xls column information
163
275
  class Column
276
+ # @param name [String, Symbol] Name of the column. If the name of the
277
+ # column is an existing attribute of the resource class, the value
278
+ # can be retreived automatically if no block is specified
279
+ # @param block [Proc] A procedure to generate data for the column
280
+ # instead of retreiving the value from the resource directly
164
281
  def initialize(name, block = nil)
165
282
  @name = name
166
283
  @data = block || @name
167
284
  end
168
285
 
169
- attr_reader :name, :data
286
+ # @return [String, Symbol] Column name
287
+ attr_reader :name
288
+
289
+ # @return [String, Symbol, Proc] The column name used to look up the
290
+ # value, or a block used to generate the value to display.
291
+ attr_reader :data
170
292
 
293
+ # Returns a localized version of the column name if a scope is given.
294
+ # Otherwise, it returns the titleized column name without translation.
295
+ #
296
+ # @param i18n_scope [String, Symbol, Array<String>, Array<Symbol>]
297
+ # Translation scope. If not provided, the column name will be used.
298
+ #
299
+ # @see I18n
171
300
  def localized_name(i18n_scope = nil)
172
301
  return name.to_s.titleize unless i18n_scope
173
302
  I18n.t name, scope: i18n_scope
@@ -1,6 +1,6 @@
1
1
  module ActiveAdmin
2
2
  module Xls
3
- # extends activeadmin dsl to include xls
3
+ # Extends activeadmin dsl to include xls
4
4
  module DSL
5
5
  delegate(:after_filter,
6
6
  :before_filter,
@@ -15,6 +15,53 @@ module ActiveAdmin
15
15
  to: :xls_builder,
16
16
  prefix: :config)
17
17
 
18
+ # Creates a default XLS Builder to respond to xls requests for this
19
+ # resource. Options are passed to the Builder initialize method.
20
+ #
21
+ # @param [Hash] options the options for the builder
22
+ # @option options [Hash] :header_format a hash of format properties to
23
+ # apply to the header row. Any properties specified will be merged with
24
+ # the default header styles.
25
+ # @option options [Array] :i18n_scope the I18n scope to use when looking
26
+ # up localized column headers.
27
+ # @param [Block] block block given will evaluated against the instance of
28
+ # Builder. That means you can call any method on the builder from within
29
+ # that block.
30
+ # @return A new instance of Builder
31
+ #
32
+ # @example Using the DSL
33
+ # xls(i18n_scope: [:active_admin, :xls, :post],
34
+ # header_format: { weight: :bold, color: :blue }) do
35
+ # # Specify that you want to white list column output.
36
+ # # whitelist
37
+ #
38
+ # # Do not serialize the header, only output data.
39
+ # # skip_header
40
+ #
41
+ # # restrict columns to a list without customization
42
+ # # only_columns :title, :author
43
+ #
44
+ # # deleting columns from the report
45
+ # delete_columns :id, :created_at, :updated_at
46
+ #
47
+ # # adding a column to the report with customization
48
+ # column(:author) do |post|
49
+ # "#{post.author.first_name} #{post.author.last_name}"
50
+ # end
51
+ #
52
+ # # inserting additional data with after_filter
53
+ # after_filter do |sheet|
54
+ # # todo
55
+ # end
56
+ #
57
+ # # inserting data with before_filter
58
+ # before_filter do |sheet|
59
+ # # todo
60
+ # end
61
+ # end
62
+ #
63
+ # @see Builder
64
+ # @see https://github.com/zdavatz/spreadsheet/blob/master/lib/spreadsheet/format.rb
18
65
  def xls(options = {}, &block)
19
66
  config.xls_builder = ActiveAdmin::Xls::Builder.new(
20
67
  config.resource_class,
@@ -1,6 +1,6 @@
1
1
  module ActiveAdmin
2
2
  module Xls
3
- # extends activeadmin with xls downloads
3
+ # Extends ActiveAdmin with xls downloads
4
4
  class Engine < ::Rails::Engine
5
5
  engine_name 'active_admin_xls'
6
6
 
@@ -14,7 +14,7 @@ module ActiveAdmin
14
14
  ActiveAdmin::ResourceDSL.send :include, ActiveAdmin::Xls::DSL
15
15
  ActiveAdmin::Resource.send :include, ActiveAdmin::Xls::ResourceExtension
16
16
  ActiveAdmin::ResourceController.send(
17
- :include,
17
+ :prepend,
18
18
  ActiveAdmin::Xls::ResourceControllerExtension
19
19
  )
20
20
  end
@@ -1,25 +1,19 @@
1
1
  module ActiveAdmin
2
2
  module Xls
3
+ # Extends the resource controller to respond to xls requests
3
4
  module ResourceControllerExtension
4
- def self.included(base)
5
- base.send :alias_method_chain, :per_page, :xls
6
- base.send :alias_method_chain, :index, :xls
7
- base.send :alias_method_chain, :rescue_active_admin_access_denied, :xls
8
- base.send :respond_to, :xls
5
+ def self.prepended(base)
6
+ base.send :respond_to, :xls, only: :index
9
7
  end
10
8
 
11
- def index_with_xls
12
- index_without_xls do |format|
9
+ # Patches index to respond to requests with xls mime type by
10
+ # sending a generated xls document serializing the current
11
+ # collection
12
+ def index
13
+ super do |format|
13
14
  format.xls do
14
- xls_collection = if method(:find_collection).arity.zero?
15
- collection
16
- else
17
- find_collection except: :pagination
18
- end
19
- xls = active_admin_config.xls_builder.serialize(
20
- xls_collection,
21
- view_context
22
- )
15
+ xls = active_admin_config.xls_builder.serialize(xls_collection,
16
+ view_context)
23
17
  send_data(xls,
24
18
  filename: xls_filename,
25
19
  type: Mime::Type.lookup_by_extension(:xls))
@@ -29,7 +23,12 @@ module ActiveAdmin
29
23
  end
30
24
  end
31
25
 
32
- def rescue_active_admin_access_denied_with_xls(exception)
26
+ # Patches rescue_active_admin_access_denied to respond to xls
27
+ # mime type. Provides administrators information on how to
28
+ # configure activeadmin to respond propertly to xls requests
29
+ #
30
+ # param exception [Exception] unauthorized access error
31
+ def rescue_active_admin_access_denied(exception)
33
32
  if request.format == Mime::Type.lookup_by_extension(:xls)
34
33
  respond_to do |format|
35
34
  format.xls do
@@ -38,27 +37,25 @@ module ActiveAdmin
38
37
  end
39
38
  end
40
39
  else
41
- rescue_active_admin_access_denied_without_xls(exception)
40
+ super(exception)
42
41
  end
43
42
  end
44
43
 
45
- # patch per_page to use the CSV record max for pagination
46
- # when the format is xls
47
- def per_page_with_xls
48
- if request.format == Mime::Type.lookup_by_extension(:xls)
49
- return max_per_page if respond_to?(:max_per_page, true)
50
- active_admin_config.max_per_page
51
- end
52
-
53
- per_page_without_xls
54
- end
55
-
56
44
  # Returns a filename for the xls file using the collection_name
57
45
  # and current date such as 'my-articles-2011-06-24.xls'.
46
+ #
47
+ # @return [String] with default filename
58
48
  def xls_filename
59
49
  timestamp = Time.now.strftime('%Y-%m-%d')
60
50
  "#{resource_collection_name.to_s.tr('_', '-')}-#{timestamp}.xls"
61
51
  end
52
+
53
+ # Returns the collection to use when generating an xls file.
54
+ # It uses the find_collection function if it is available, and uses
55
+ # collection if find_collection isn't available.
56
+ def xls_collection
57
+ find_collection except: :pagination
58
+ end
62
59
  end
63
60
  end
64
61
  end
@@ -1,10 +1,25 @@
1
1
  module ActiveAdmin
2
+ # Provides xls functionality to ActiveAdmin resources
2
3
  module Xls
4
+ # Extends ActiveAdmin Resource
3
5
  module ResourceExtension
6
+ # Sets the XLS Builder
7
+ #
8
+ # @param builder [Builder] the new builder object
9
+ # @return [Builder] the builder for this resource
4
10
  def xls_builder=(builder)
5
11
  @xls_builder = builder
6
12
  end
7
13
 
14
+ # Returns the XLS Builder. Creates a new Builder if none exists.
15
+ #
16
+ # @return [Builder] the builder for this resource
17
+ #
18
+ # @example Localize column headers
19
+ # # app/admin/posts.rb
20
+ # ActiveAdmin.register Post do
21
+ # config.xls_builder.i18n_scope = [:active_record, :models, :posts]
22
+ # end
8
23
  def xls_builder
9
24
  @xls_builder ||= ActiveAdmin::Xls::Builder.new(resource_class)
10
25
  end
@@ -1,5 +1,6 @@
1
1
  module ActiveAdmin
2
2
  module Xls
3
- VERSION = '1.1.0'.freeze
3
+ # ActiveAdmin XLS gem version
4
+ VERSION = '2.0.0'.freeze
4
5
  end
5
6
  end
File without changes
@@ -4,6 +4,14 @@ SimpleCov.start do
4
4
  add_filter '/spec/'
5
5
  end
6
6
 
7
+ if ENV['CI'] == 'true'
8
+ require 'codecov'
9
+ SimpleCov.formatters = [
10
+ SimpleCov::Formatter::HTMLFormatter,
11
+ SimpleCov::Formatter::Codecov
12
+ ]
13
+ end
14
+
7
15
  ENV['RAILS_ENV'] = 'test'
8
16
 
9
17
  # prepare ENV for rails
@@ -16,24 +16,51 @@ gsub_file(
16
16
  "\ncucumber_with_reloading:\n <<: *test\n database: db/cucumber.sqlite3"
17
17
  )
18
18
 
19
+ if File.exist?('config/secrets.yml')
20
+ require 'securerandom'
21
+ cucumber_secret = SecureRandom.hex(64)
22
+ gsub_file 'config/secrets.yml',
23
+ /\z/,
24
+ "\ncucumber:\n secret_key_base: #{cucumber_secret}"
25
+ end
26
+
27
+ base_record = if Rails::VERSION::MAJOR >= 5
28
+ 'ApplicationRecord'
29
+ else
30
+ 'ActiveRecord::Base'
31
+ end
32
+
19
33
  # Generate some test models
20
34
  generate :model, 'post title:string body:text published_at:datetime author_id:integer category_id:integer'
21
- inject_into_file 'app/models/post.rb', " belongs_to :author, class_name: 'User'\n belongs_to :category\n accepts_nested_attributes_for :author\n", after: "class Post < ActiveRecord::Base\n"
22
- # Rails 3.2.3 model generator declare attr_accessible
23
- if Rails::VERSION::MAJOR == 3
24
- inject_into_file 'app/models/post.rb',
25
- " attr_accessible :author\n",
26
- before: 'end'
27
- end
35
+ post_model_setup = if Rails::VERSION::MAJOR >= 5
36
+ <<-MODEL
37
+ belongs_to :author, class_name: 'User'
38
+ belongs_to :category, optional: true
39
+ accepts_nested_attributes_for :author
40
+ MODEL
41
+ else
42
+ <<-MODEL
43
+ belongs_to :author, class_name: 'User'
44
+ belongs_to :category
45
+ accepts_nested_attributes_for :author
46
+ MODEL
47
+ end
48
+ inject_into_file 'app/models/post.rb',
49
+ post_model_setup,
50
+ after: "class Post < #{base_record}\n"
51
+
28
52
  generate :model, 'user type:string first_name:string last_name:string username:string age:integer'
29
53
  inject_into_file 'app/models/user.rb',
30
54
  " has_many :posts, foreign_key: 'author_id'\n",
31
- after: "class User < ActiveRecord::Base\n"
55
+ after: "class User < #{base_record}\n"
56
+
32
57
  generate :model, 'publisher --migration=false --parent=User'
58
+
33
59
  generate :model, 'category name:string description:text'
34
60
  inject_into_file 'app/models/category.rb',
35
61
  " has_many :posts\n accepts_nested_attributes_for :posts\n",
36
- after: "class Category < ActiveRecord::Base\n"
62
+ after: "class Category < #{base_record}\n"
63
+
37
64
  generate :model, 'store name:string'
38
65
 
39
66
  # Generate a model with string ids
@@ -57,13 +84,7 @@ MODEL
57
84
 
58
85
  inject_into_file 'app/models/tag.rb',
59
86
  id_model_setup,
60
- after: "class Tag < ActiveRecord::Base\n"
61
-
62
- if Rails::VERSION::MAJOR == 3 && Rails::VERSION::MINOR == 1 # Rails 3.1 Gotcha
63
- gsub_file 'app/models/tag.rb',
64
- /self\.primary_key.*$/,
65
- 'define_attr_method :primary_key, :id'
66
- end
87
+ after: "class Tag < #{base_record}\n"
67
88
 
68
89
  # Configure default_url_options in test environment
69
90
  inject_into_file(
@@ -86,27 +107,17 @@ append_file 'config/locales/en.yml',
86
107
  directory File.expand_path('../templates/admin', __FILE__), 'app/admin'
87
108
 
88
109
  run 'rm Gemfile'
89
- run 'rm -r test'
90
- run 'rm -r spec'
91
110
 
92
111
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
93
112
 
94
- if Rails::VERSION::MAJOR == 3
95
- # we need this routing path, named "logout_path", for testing
96
- route <<-ROUTE
97
- devise_scope :user do
98
- match '/admin/logout' => 'active_admin/devise/sessions#destroy', as: :logout
99
- end
100
- ROUTE
101
- end
102
-
103
113
  generate :'active_admin:install'
104
114
 
105
- if Rails::VERSION::MAJOR > 3
106
- inject_into_file 'config/initializers/active_admin.rb',
107
- " config.download_links = %i[csv xml json xls]\n",
108
- after: " # == Download Links\n"
109
- end
115
+ run 'rm -r test'
116
+ run 'rm -r spec'
117
+
118
+ inject_into_file 'config/initializers/active_admin.rb',
119
+ " config.download_links = %i[csv xml json xls]\n",
120
+ after: " # == Download Links\n"
110
121
 
111
122
  # Setup a root path for devise
112
123
  route "root to: 'admin/dashboard#index'"
@@ -1,22 +1,7 @@
1
1
  require 'spec_helper'
2
- describe ActiveAdmin::ResourceController do
2
+ describe Admin::CategoriesController, type: :controller do
3
3
  let(:mime) { Mime::Type.lookup_by_extension(:xls) }
4
4
 
5
- let(:request) do
6
- ActionController::TestRequest.new.tap do |test_request|
7
- test_request.accept = mime
8
- end
9
- end
10
-
11
- let(:response) { ActionController::TestResponse.new }
12
-
13
- let(:controller) do
14
- Admin::CategoriesController.new.tap do |controller|
15
- controller.request = request
16
- controller.response = response
17
- end
18
- end
19
-
20
5
  let(:filename) do
21
6
  "#{controller.resource_class.to_s.downcase.pluralize}-#{Time.now.strftime('%Y-%m-%d')}.xls"
22
7
  end
@@ -27,26 +12,11 @@ describe ActiveAdmin::ResourceController do
27
12
 
28
13
  context 'when making requests with the xls mime type' do
29
14
  it 'returns xls attachment when requested' do
30
- controller.send :index
15
+ request.accept = mime
16
+ get :index
31
17
  disposition = "attachment; filename=\"#{filename}\""
32
18
  expect(response.headers['Content-Disposition']).to eq(disposition)
33
19
  expect(response.headers['Content-Transfer-Encoding']).to eq('binary')
34
20
  end
35
-
36
- it 'returns max_csv_records for per_page' do
37
- # this might need to go away!
38
- max_csv_records = if controller.respond_to?(:max_csv_records, true)
39
- controller.send(:max_csv_records)
40
- else
41
- controller.send(:per_page)
42
- end
43
- expect(controller.send(:per_page)).to eq(max_csv_records)
44
- end
45
-
46
- it 'uses the default per_page when we do not specify xls mime type' do
47
- controller.request.accept = 'text/html'
48
- aa_default_per_page = ActiveAdmin.application.default_per_page
49
- expect(controller.send(:per_page)).to eq(aa_default_per_page)
50
- end
51
21
  end
52
22
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activeadmin-xls
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Todd Hambley
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-02-27 00:00:00.000000000 Z
11
+ date: 2018-03-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activeadmin
@@ -16,7 +16,7 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 0.6.6
19
+ version: 1.0.0
20
20
  - - "<"
21
21
  - !ruby/object:Gem::Version
22
22
  version: '2'
@@ -26,7 +26,7 @@ dependencies:
26
26
  requirements:
27
27
  - - ">="
28
28
  - !ruby/object:Gem::Version
29
- version: 0.6.6
29
+ version: 1.0.0
30
30
  - - "<"
31
31
  - !ruby/object:Gem::Version
32
32
  version: '2'
@@ -55,15 +55,16 @@ files:
55
55
  - ".gemignore"
56
56
  - ".gitignore"
57
57
  - ".rspec"
58
- - ".yardops"
58
+ - ".travis.yml"
59
+ - ".yardopts"
59
60
  - CHANGELOG.md
60
61
  - Gemfile
61
62
  - LICENSE
62
63
  - README.md
63
64
  - Rakefile
64
65
  - activeadmin-xls.gemspec
65
- - gemfiles/rails_32.gemfile
66
66
  - gemfiles/rails_42.gemfile
67
+ - gemfiles/rails_51.gemfile
67
68
  - lib/active_admin/xls/builder.rb
68
69
  - lib/active_admin/xls/dsl.rb
69
70
  - lib/active_admin/xls/engine.rb
@@ -71,6 +72,7 @@ files:
71
72
  - lib/active_admin/xls/resource_extension.rb
72
73
  - lib/active_admin/xls/version.rb
73
74
  - lib/activeadmin-xls.rb
75
+ - spec/rails_helper.rb
74
76
  - spec/spec_helper.rb
75
77
  - spec/support/rails_template.rb
76
78
  - spec/support/rails_template_with_data.rb
@@ -95,7 +97,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
95
97
  requirements:
96
98
  - - ">="
97
99
  - !ruby/object:Gem::Version
98
- version: 1.9.2
100
+ version: 2.0.0
99
101
  required_rubygems_version: !ruby/object:Gem::Requirement
100
102
  requirements:
101
103
  - - ">="
data/.yardops DELETED
@@ -1 +0,0 @@
1
- --no-private --protected app/**/*.rb - README.md LEGAL
@@ -1,30 +0,0 @@
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 'rails', '3.2.22.5'
10
-
11
- gem 'activeadmin', '0.6.6'
12
-
13
- group :assets do
14
- gem 'coffee-rails', '~> 3.2.1'
15
- gem 'sass-rails', '~> 3.2.3'
16
-
17
- # See https://github.com/sstephenson/execjs#readme for more supported runtimes
18
- # gem 'therubyracer', :platforms => :ruby
19
-
20
- gem 'uglifier', '>= 1.0.3'
21
- end
22
-
23
- group :test do
24
- gem 'shoulda-matchers', '~> 2.8.0'
25
- if ruby_major_version > 2 || (ruby_major_version == 2 && ruby_minor_version > 1)
26
- gem 'test-unit', '~> 3.0'
27
- end
28
- end
29
-
30
- gemspec path: "../"