lotus_admin 0.3.1 → 0.4.0

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: ad4c293efddd78c53545e0c36f058d03c259751e
4
- data.tar.gz: 9698ab1d3491b93ee79a66b6f07d5a163195d07f
3
+ metadata.gz: 4a9240be9d5d6c8e2984eae7a3fc3f059fd6b853
4
+ data.tar.gz: f728a8239f07eb2e08708903031b2fbb542dcc4b
5
5
  SHA512:
6
- metadata.gz: ab59485d6568188378061c231edc6ab033f7fcc15f98c43a41dcfaa7b4bc9980949017a93b720adc75928335191bea352f72fc069c02f3313fd92fe1e72cbca5
7
- data.tar.gz: 472832ebb676e795a81d68e896cacb052806f9636dddcd7f6dc6320badf7138c6aae05a19a447b5261a251404bcba838d81612bd252d7c2287d31c415fec9655
6
+ metadata.gz: b0393e4130d668a2e614404a5c95f46831a113649e5d3d5280e6ba73c6ef2cc1bbbc986f8ddff75457581bb43f723deae40ca546bca7637263dc38fbf2b33667
7
+ data.tar.gz: 3a7f73827b2a68988937535df3aeba48234f5e9efc68ee2ecf75344a2b1998b772202af5df257dbc4df8c6cd28c5c1b1f3160339f916e683a2d9efa1779a8cad
@@ -0,0 +1,74 @@
1
+ module LotusAdmin
2
+ module FileStreamer
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ include ActionController::Live
7
+
8
+ class_attribute :_exporter_class, instance_accessor: false
9
+ class_attribute :_exporter_filename, instance_accessor: false
10
+
11
+ let(:exporter) { self.class._exporter_class }
12
+ end
13
+
14
+ # Usage
15
+ #
16
+ # class LotusAdmin::OrganizationsController < LotusAdmin::AuthenticatedController
17
+ # exporter OrganizationExporter
18
+ #
19
+ # # optional filename customization in context of controller
20
+ # exports_filename { "organizations-#{ params[:parent_id] }" }
21
+ # end
22
+ class_methods do
23
+ def exporter(exporter_class)
24
+ self._exporter_class = exporter_class
25
+ end
26
+
27
+ def exports_filename(&block)
28
+ self._exporter_filename = block
29
+ end
30
+ end
31
+
32
+ # Usage
33
+ #
34
+ # def index
35
+ # super do |format|
36
+ # format.pdf { ... }
37
+ # end
38
+ # end
39
+ #
40
+ # Will automatically stream CSV from configured exporter
41
+ def index(&block)
42
+ super do |format|
43
+ if self.class._exporter_class.present?
44
+ format.csv do
45
+ if self.class._exporter_filename.present?
46
+ filename = instance_exec(&self.class._exporter_filename)
47
+ end
48
+
49
+ filename = "#{ resource_class.model_name.human(count: 2) }-exports-#{ SecureRandom.uuid }" if filename.blank?
50
+
51
+ stream_file filename.parameterize, 'csv' do |stream|
52
+ self.class._exporter_class.stream(ransack_object.result, stream) # full query, not just paginated
53
+ end
54
+ end
55
+ end
56
+
57
+ block.call(format) if block.present?
58
+ end
59
+ end
60
+
61
+ private
62
+
63
+ def stream_file(filename, extension, &block)
64
+ response.headers["Content-Type"] = "application/octet-stream"
65
+ response.headers["Content-Disposition"] = "attachment; filename=#{filename}.#{extension}"
66
+
67
+ begin
68
+ yield response.stream
69
+ ensure
70
+ response.stream.close
71
+ end
72
+ end
73
+ end
74
+ end
@@ -14,4 +14,12 @@ module LotusAdmin::ResourcefulController
14
14
  self._resource_class = model_class
15
15
  end
16
16
  end
17
+
18
+ def index(&block)
19
+ respond_to do |format|
20
+ format.html
21
+
22
+ block.call(format) if block.present?
23
+ end
24
+ end
17
25
  end
@@ -2,6 +2,7 @@ class LotusAdmin::AuthenticatedController < LotusAdmin::ApplicationController
2
2
  include LotusAdmin::PermittedParams
3
3
  include LotusAdmin::FilterableController
4
4
  include LotusAdmin::ResourcefulController
5
+ include LotusAdmin::FileStreamer
5
6
 
6
7
  before_action :authenticate_administrator!
7
8
  around_action :use_user_time_zone, if: :administrator_signed_in?
@@ -0,0 +1,113 @@
1
+ module LotusAdmin
2
+ class Exporter
3
+ class_attribute :_columns, instance_accessor: false
4
+ class_attribute :_decorates, instance_accessor: false
5
+ class_attribute :_resource_class, instance_accessor: false
6
+
7
+ self._columns = []
8
+ self._decorates = false
9
+
10
+ # reset so that each subclass has it's own collection
11
+ def self.inherited(other)
12
+ other._columns = []
13
+ end
14
+
15
+ class Column
16
+ attr_reader :attribute_name, :title, :block
17
+ def initialize(attribute_name, title, &block)
18
+ @attribute_name = attribute_name
19
+ @title = title
20
+ @block = block || ->(model){ model.public_send(attribute_name) }
21
+ end
22
+
23
+ def data(model)
24
+ block.call(model)
25
+ end
26
+ end
27
+
28
+ class << self
29
+ def stream(*args)
30
+ new.stream(*args)
31
+ end
32
+
33
+ def generate(*args)
34
+ new.generate(*args)
35
+ end
36
+
37
+ private
38
+
39
+ def column(attribute_name, title = nil, &block)
40
+ self._columns << Column.new(attribute_name, title, &block)
41
+ end
42
+
43
+ def decorates(boolean)
44
+ self._decorates = boolean
45
+ end
46
+
47
+ def model(resource_class)
48
+ self._resource_class = resource_class
49
+ end
50
+ end
51
+
52
+ def generate(collection)
53
+ @collection = collection
54
+
55
+ CSV.generate do |csv|
56
+ csv << headers
57
+
58
+ content.each do |row|
59
+ csv << row
60
+ end
61
+ end
62
+ end
63
+
64
+ def stream(collection, stream)
65
+ stream.write CSV.generate_line(headers)
66
+
67
+ @collection = collection
68
+
69
+ content.each do |row|
70
+ stream.write CSV.generate_line(row)
71
+ end
72
+ end
73
+
74
+ private
75
+
76
+ def view_context
77
+ @view_context ||= begin
78
+ ActionView::Base.new(ActionController::Base.view_paths).tap do |view|
79
+ view.class_eval do
80
+ include Rails.application.routes.url_helpers
81
+ include ::ApplicationHelper if defined?(::ApplicationHelper)
82
+ end
83
+ end
84
+ end
85
+ end
86
+
87
+ def headers
88
+ self.class._columns.map do |column|
89
+ column.title.presence || self.class._resource_class.human_attribute_name(column.attribute_name)
90
+ end
91
+ end
92
+
93
+ def content
94
+ each_item.map do |record|
95
+ record = record.decorate(view_context) if decorator?
96
+
97
+ self.class._columns.map do |column|
98
+ column.data(record)
99
+ end
100
+ end
101
+ end
102
+
103
+ def each_item(&block)
104
+ return @collection.each.lazy unless @collection.respond_to?(:find_each)
105
+
106
+ @collection.find_each(batch_size: 500).lazy
107
+ end
108
+
109
+ def decorator?
110
+ self.class._decorates == true
111
+ end
112
+ end
113
+ end
@@ -1,7 +1,11 @@
1
1
  .row
2
- .col-sm-6
2
+ .col-sm-5
3
3
  = paginate(collection, theme: 'lotus_admin')
4
4
 
5
- .col-sm-6
5
+ .col-sm-2.text-center
6
+ - if exporter.present?
7
+ = link_to 'CSV', url_for(params: { q: params[:q]&.to_unsafe_h }, format: :csv)
8
+
9
+ .col-sm-5
6
10
  .pagination-info
7
11
  %small= page_entries_info(collection)
@@ -1,3 +1,3 @@
1
1
  module LotusAdmin
2
- VERSION = '0.3.1'
2
+ VERSION = '0.4.0'
3
3
  end
data/lib/lotus_admin.rb CHANGED
@@ -1,5 +1,7 @@
1
1
  require "lotus_admin/engine"
2
2
 
3
+ require 'csv'
4
+
3
5
  require 'devise'
4
6
  require 'simple_form'
5
7
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lotus_admin
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matt Millsaps-Brewer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-03-05 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: rails
@@ -344,6 +344,7 @@ files:
344
344
  - app/assets/stylesheets/lotus_admin/components/_tables.scss
345
345
  - app/controllers/concerns/lotus_admin/devise_controllers.rb
346
346
  - app/controllers/concerns/lotus_admin/exposure.rb
347
+ - app/controllers/concerns/lotus_admin/file_streamer.rb
347
348
  - app/controllers/concerns/lotus_admin/filterable_controller.rb
348
349
  - app/controllers/concerns/lotus_admin/permitted_params.rb
349
350
  - app/controllers/concerns/lotus_admin/resourceful_controller.rb
@@ -370,6 +371,7 @@ files:
370
371
  - app/models/lotus_admin/application_record.rb
371
372
  - app/models/lotus_admin/filters/configuration.rb
372
373
  - app/models/lotus_admin/user.rb
374
+ - app/services/lotus_admin/exporter.rb
373
375
  - app/views/administrators/_links.html.haml
374
376
  - app/views/administrators/confirmations/new.html.haml
375
377
  - app/views/administrators/passwords/edit.html.haml