effective_reports 0.1.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 +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +110 -0
- data/Rakefile +18 -0
- data/app/assets/config/effective_reports_manifest.js +3 -0
- data/app/assets/javascripts/effective_reports/base.js +15 -0
- data/app/assets/javascripts/effective_reports.js +1 -0
- data/app/assets/stylesheets/effective_reports/base.scss +0 -0
- data/app/assets/stylesheets/effective_reports.scss +1 -0
- data/app/controllers/admin/reports_controller.rb +16 -0
- data/app/datatables/admin/effective_reports_datatable.rb +31 -0
- data/app/datatables/effective_report_datatable.rb +21 -0
- data/app/helpers/effective_reports_helper.rb +60 -0
- data/app/mailers/effective/reports_mailer.rb +38 -0
- data/app/models/concerns/acts_as_reportable.rb +72 -0
- data/app/models/effective/report.rb +94 -0
- data/app/models/effective/report_column.rb +89 -0
- data/app/models/effective/report_scope.rb +48 -0
- data/app/views/admin/reports/_form.html.haml +8 -0
- data/app/views/admin/reports/_form_report.html.haml +194 -0
- data/app/views/admin/reports/_layout.html.haml +2 -0
- data/app/views/admin/reports/_report.html.haml +17 -0
- data/config/effective_reports.rb +37 -0
- data/config/routes.rb +16 -0
- data/db/migrate/01_create_effective_reports.rb.erb +54 -0
- data/db/seeds.rb +1 -0
- data/lib/effective_reports/engine.rb +18 -0
- data/lib/effective_reports/version.rb +3 -0
- data/lib/effective_reports.rb +27 -0
- data/lib/generators/effective_reports/install_generator.rb +32 -0
- data/lib/generators/templates/effective_reports_mailer_preview.rb +4 -0
- data/lib/tasks/effective_reports_tasks.rake +8 -0
- metadata +270 -0
@@ -0,0 +1,194 @@
|
|
1
|
+
= effective_form_with(model: [:admin, report], engine: true) do |f|
|
2
|
+
= f.text_field :title
|
3
|
+
= f.text_area :description
|
4
|
+
|
5
|
+
- if f.object.new_record?
|
6
|
+
= f.select :reportable_class_name, EffectiveReports.reportable_classes.map(&:name), label: 'Resource',
|
7
|
+
'data-load-ajax-url': effective_reports.new_admin_report_path,
|
8
|
+
'data-load-ajax-div': '#effective-reports-ajax'
|
9
|
+
- else
|
10
|
+
= f.static_field :reportable_class_name, label: 'Resource'
|
11
|
+
|
12
|
+
#effective-reports-ajax
|
13
|
+
-# Attributes
|
14
|
+
- attributes = f.object.reportable_attributes
|
15
|
+
- attributes_collection = reportable_attributes_collection(attributes)
|
16
|
+
|
17
|
+
- value_booleans = attributes.select { |_, type| type == :boolean }.keys
|
18
|
+
- value_dates = attributes.select { |_, type| type == :date }.keys
|
19
|
+
- value_decimals = attributes.select { |_, type| type == :decimal }.keys
|
20
|
+
- value_integers = attributes.select { |_, type| type == :integer }.keys
|
21
|
+
- value_prices = attributes.select { |_, type| type == :price }.keys
|
22
|
+
- value_strings = attributes.select { |_, type| type == :string }.keys
|
23
|
+
|
24
|
+
- value_belong_tos = attributes.select { |_, type| type == :belongs_to }.keys
|
25
|
+
- value_belong_to_polymorphics = attributes.select { |_, type| type == :belongs_to_polymorphic }.keys
|
26
|
+
- value_has_manys = attributes.select { |_, type| type == :has_many }.keys
|
27
|
+
- value_has_ones = attributes.select { |_, type| type == :has_one }.keys
|
28
|
+
|
29
|
+
-# Scopes
|
30
|
+
- scopes = f.object.reportable_scopes
|
31
|
+
- scopes_collection = reportable_scopes_collection(scopes)
|
32
|
+
|
33
|
+
- if attributes.present?
|
34
|
+
%h2 Report Columns
|
35
|
+
|
36
|
+
= f.has_many :report_columns do |frc|
|
37
|
+
.card.mb-2
|
38
|
+
.card-body.pb-2
|
39
|
+
.row
|
40
|
+
.col-md-4
|
41
|
+
= frc.select :name, attributes_collection, grouped: true, required: false, label: false
|
42
|
+
.col
|
43
|
+
= frc.show_if_any(:name, value_booleans) do
|
44
|
+
|
45
|
+
.row
|
46
|
+
.col.mt-2
|
47
|
+
= frc.check_box :filter, label: 'Filter by this column'
|
48
|
+
= frc.hidden_field :as, value: :boolean
|
49
|
+
|
50
|
+
.col.effective-report-filter{style: ('display: none;' unless frc.object.filter?)}
|
51
|
+
= frc.select :operation, reportable_operations_collection(:boolean), label: false
|
52
|
+
|
53
|
+
.col.effective-report-filter{style: ('display: none;' unless frc.object.filter?)}
|
54
|
+
= frc.radios :value_boolean, reportable_boolean_collection, label: false, buttons: true
|
55
|
+
|
56
|
+
= frc.show_if_any(:name, value_dates) do
|
57
|
+
.row
|
58
|
+
.col.mt-2
|
59
|
+
= frc.check_box :filter, label: 'Filter by this column'
|
60
|
+
= frc.hidden_field :as, value: :date
|
61
|
+
|
62
|
+
.col.effective-report-filter{style: ('display: none;' unless frc.object.filter?)}
|
63
|
+
= frc.select :operation, reportable_operations_collection(:date), label: false
|
64
|
+
|
65
|
+
.col.effective-report-filter{style: ('display: none;' unless frc.object.filter?)}
|
66
|
+
= frc.date_field :value_date, label: false
|
67
|
+
|
68
|
+
= frc.show_if_any(:name, value_decimals) do
|
69
|
+
.row
|
70
|
+
.col.mt-2
|
71
|
+
= frc.check_box :filter, label: 'Filter by this column'
|
72
|
+
= frc.hidden_field :as, value: :decimal
|
73
|
+
|
74
|
+
.col.effective-report-filter{style: ('display: none;' unless frc.object.filter?)}
|
75
|
+
= frc.select :operation, reportable_operations_collection(:decimal), label: false
|
76
|
+
|
77
|
+
.col.effective-report-filter{style: ('display: none;' unless frc.object.filter?)}
|
78
|
+
= frc.float_field :value_decimal, label: false
|
79
|
+
|
80
|
+
= frc.show_if_any(:name, value_integers) do
|
81
|
+
.row
|
82
|
+
.col.mt-2
|
83
|
+
= frc.check_box :filter, label: 'Filter by this column'
|
84
|
+
= frc.hidden_field :as, value: :integer
|
85
|
+
|
86
|
+
.col.effective-report-filter{style: ('display: none;' unless frc.object.filter?)}
|
87
|
+
= frc.select :operation, reportable_operations_collection(:integer), label: false
|
88
|
+
|
89
|
+
.col.effective-report-filter{style: ('display: none;' unless frc.object.filter?)}
|
90
|
+
= frc.integer_field :value_integer, label: false
|
91
|
+
|
92
|
+
= frc.show_if_any(:name, value_prices) do
|
93
|
+
.row
|
94
|
+
.col.mt-2
|
95
|
+
= frc.check_box :filter, label: 'Filter by this column'
|
96
|
+
= frc.hidden_field :as, value: :price
|
97
|
+
|
98
|
+
.col.effective-report-filter{style: ('display: none;' unless frc.object.filter?)}
|
99
|
+
= frc.select :operation, reportable_operations_collection(:price), label: false
|
100
|
+
|
101
|
+
.col.effective-report-filter{style: ('display: none;' unless frc.object.filter?)}
|
102
|
+
= frc.price_field :value_price, label: false
|
103
|
+
|
104
|
+
= frc.show_if_any(:name, value_strings) do
|
105
|
+
.row
|
106
|
+
.col.mt-2
|
107
|
+
= frc.check_box :filter, label: 'Filter by this column'
|
108
|
+
= frc.hidden_field :as, value: :string
|
109
|
+
|
110
|
+
.col.effective-report-filter{style: ('display: none;' unless frc.object.filter?)}
|
111
|
+
= frc.select :operation, reportable_operations_collection(:string), label: false
|
112
|
+
|
113
|
+
.col.effective-report-filter{style: ('display: none;' unless frc.object.filter?)}
|
114
|
+
= frc.text_field :value_string, label: false
|
115
|
+
|
116
|
+
= frc.show_if_any(:name, value_belong_tos) do
|
117
|
+
.row
|
118
|
+
.col.mt-2
|
119
|
+
= frc.check_box :filter, label: 'Filter by this column'
|
120
|
+
= frc.hidden_field :as, value: :belongs_to
|
121
|
+
|
122
|
+
.col.effective-report-filter{style: ('display: none;' unless frc.object.filter?)}
|
123
|
+
= frc.select :operation, reportable_operations_collection(:belongs_to), label: false
|
124
|
+
|
125
|
+
.col.effective-report-filter{style: ('display: none;' unless frc.object.filter?)}
|
126
|
+
= frc.text_field :value_associated, label: false
|
127
|
+
|
128
|
+
= frc.show_if_any(:name, value_belong_to_polymorphics) do
|
129
|
+
.row
|
130
|
+
.col.mt-2
|
131
|
+
= frc.check_box :filter, label: 'Filter by this column'
|
132
|
+
= frc.hidden_field :as, value: :belongs_to_polymorphic
|
133
|
+
|
134
|
+
.col.effective-report-filter{style: ('display: none;' unless frc.object.filter?)}
|
135
|
+
= frc.select :operation, reportable_operations_collection(:belongs_to_polymorphic), label: false
|
136
|
+
|
137
|
+
.col.effective-report-filter{style: ('display: none;' unless frc.object.filter?)}
|
138
|
+
= frc.text_field :value_associated, label: false
|
139
|
+
|
140
|
+
|
141
|
+
= frc.show_if_any(:name, value_has_manys) do
|
142
|
+
.row
|
143
|
+
.col.mt-2
|
144
|
+
= frc.check_box :filter, label: 'Filter by this column'
|
145
|
+
= frc.hidden_field :as, value: :has_many
|
146
|
+
|
147
|
+
.col.effective-report-filter{style: ('display: none;' unless frc.object.filter?)}
|
148
|
+
= frc.select :operation, reportable_operations_collection(:has_many), label: false
|
149
|
+
|
150
|
+
.col.effective-report-filter{style: ('display: none;' unless frc.object.filter?)}
|
151
|
+
= frc.text_field :value_associated, label: false
|
152
|
+
|
153
|
+
= frc.show_if_any(:name, value_has_ones) do
|
154
|
+
.row
|
155
|
+
.col.mt-2
|
156
|
+
= frc.check_box :filter, label: 'Filter by this column'
|
157
|
+
= frc.hidden_field :as, value: :has_one
|
158
|
+
|
159
|
+
.col.effective-report-filter{style: ('display: none;' unless frc.object.filter?)}
|
160
|
+
= frc.select :operation, reportable_operations_collection(:has_one), label: false
|
161
|
+
|
162
|
+
.col.effective-report-filter{style: ('display: none;' unless frc.object.filter?)}
|
163
|
+
= frc.text_field :value_associated, label: false
|
164
|
+
|
165
|
+
- if scopes.present?
|
166
|
+
%h2 Report Scopes
|
167
|
+
|
168
|
+
= f.has_many :report_scopes do |frs|
|
169
|
+
.card.mb-2
|
170
|
+
.card-body.pb-2
|
171
|
+
.row
|
172
|
+
.col
|
173
|
+
= frs.select :name, scopes_collection, grouped: true, required: false, label: false
|
174
|
+
.col
|
175
|
+
- scopes.select { |scope, type| type.present? }.each do |scope, type|
|
176
|
+
= frs.show_if(:name, scope) do
|
177
|
+
= frs.hidden_field :advanced, value: true
|
178
|
+
|
179
|
+
- if type == :boolean
|
180
|
+
= frs.radios :value_boolean, reportable_boolean_collection, label: 'Value', buttons: true, required: true, label: false
|
181
|
+
- elsif type == :date
|
182
|
+
= frs.date_field :value_date, label: 'Value', required: true, label: false
|
183
|
+
- elsif type == :decimal
|
184
|
+
= frs.date_field :value_decimal, label: 'Value', required: true, label: false
|
185
|
+
- elsif type == :integer
|
186
|
+
= frs.integer_field :value_integer, label: 'Value', required: true, label: false
|
187
|
+
- elsif type == :price
|
188
|
+
= frs.price_field :value_price, label: 'Value', required: true, label: false
|
189
|
+
- elsif type == :string
|
190
|
+
= frs.text_field :value_string, label: 'Value', required: true, label: false
|
191
|
+
- else
|
192
|
+
- raise("Unexpected scope datatype: #{type || 'nil'}")
|
193
|
+
|
194
|
+
= effective_submit(f)
|
@@ -0,0 +1,17 @@
|
|
1
|
+
- if report.description.present?
|
2
|
+
%p= report.description.to_s
|
3
|
+
|
4
|
+
- if report.filtered_report_columns.present? || report.report_scopes.present?
|
5
|
+
%p The results of this report have been filtered by the following:
|
6
|
+
|
7
|
+
- if report.filtered_report_columns.present?
|
8
|
+
%p= badges(report.filtered_report_columns.map(&:to_s))
|
9
|
+
|
10
|
+
- if report.report_scopes.present?
|
11
|
+
%p= badges(report.report_scopes.map(&:to_s))
|
12
|
+
|
13
|
+
= collapse('Show SQL') do
|
14
|
+
%p= report.collection.to_sql
|
15
|
+
|
16
|
+
- datatable = EffectiveReportDatatable.new(report: report)
|
17
|
+
= render_datatable(datatable)
|
@@ -0,0 +1,37 @@
|
|
1
|
+
EffectiveReports.setup do |config|
|
2
|
+
config.reports_table_name = :reports
|
3
|
+
config.report_columns_table_name = :report_columns
|
4
|
+
config.report_scopes_table_name = :report_scopes
|
5
|
+
|
6
|
+
# Layout Settings
|
7
|
+
# Configure the Layout per controller, or all at once
|
8
|
+
# config.layout = { application: 'application', admin: 'admin' }
|
9
|
+
|
10
|
+
# Reports Settings
|
11
|
+
# Configure the class responsible for the reports.
|
12
|
+
# This should extend from Effective::Reports
|
13
|
+
# config.reports_class_name = 'Effective::Reports'
|
14
|
+
|
15
|
+
# Reportable Class Names
|
16
|
+
# The following classes will be available to build reports from
|
17
|
+
# They must define acts_as_reportable to be included
|
18
|
+
config.reportable_class_names = ['User', 'Effective::Order']
|
19
|
+
|
20
|
+
# Mailer Settings
|
21
|
+
# Please see config/initializers/effective_reports.rb for default effective_* gem mailer settings
|
22
|
+
#
|
23
|
+
# Configure the class responsible to send e-mails.
|
24
|
+
# config.mailer = 'Effective::ReportsMailer'
|
25
|
+
#
|
26
|
+
# Override effective_resource mailer defaults
|
27
|
+
#
|
28
|
+
# config.parent_mailer = nil # The parent class responsible for sending emails
|
29
|
+
# config.deliver_method = nil # The deliver method, deliver_later or deliver_now
|
30
|
+
# config.mailer_layout = nil # Default mailer layout
|
31
|
+
# config.mailer_sender = nil # Default From value
|
32
|
+
# config.mailer_admin = nil # Default To value for Admin correspondence
|
33
|
+
# config.mailer_subject = nil # Proc.new method used to customize Subject
|
34
|
+
|
35
|
+
# Will work with effective_email_templates gem
|
36
|
+
config.use_effective_email_templates = true
|
37
|
+
end
|
data/config/routes.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
Rails.application.routes.draw do
|
4
|
+
mount EffectiveReports::Engine => '/', as: 'effective_reports'
|
5
|
+
end
|
6
|
+
|
7
|
+
EffectiveReports::Engine.routes.draw do
|
8
|
+
# Public routes
|
9
|
+
scope module: 'effective' do
|
10
|
+
end
|
11
|
+
|
12
|
+
namespace :admin do
|
13
|
+
resources :reports
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
class CreateEffectiveReports < ActiveRecord::Migration[6.0]
|
2
|
+
def change
|
3
|
+
create_table <%= @reports_table_name %> do |t|
|
4
|
+
t.integer :created_by_id
|
5
|
+
t.string :created_by_type
|
6
|
+
|
7
|
+
t.string :title
|
8
|
+
t.text :description
|
9
|
+
|
10
|
+
t.string :reportable_class_name
|
11
|
+
|
12
|
+
t.timestamps
|
13
|
+
end
|
14
|
+
|
15
|
+
create_table <%= @report_columns_table_name %> do |t|
|
16
|
+
t.integer :report_id
|
17
|
+
|
18
|
+
t.string :name
|
19
|
+
t.integer :position
|
20
|
+
|
21
|
+
t.string :as
|
22
|
+
|
23
|
+
t.boolean :filter
|
24
|
+
t.string :operation
|
25
|
+
|
26
|
+
t.text :value_associated
|
27
|
+
t.boolean :value_boolean
|
28
|
+
t.date :value_date
|
29
|
+
t.decimal :value_decimal
|
30
|
+
t.integer :value_integer
|
31
|
+
t.integer :value_price
|
32
|
+
t.string :value_string
|
33
|
+
|
34
|
+
t.timestamps
|
35
|
+
end
|
36
|
+
|
37
|
+
create_table <%= @report_scopes_table_name %> do |t|
|
38
|
+
t.integer :report_id
|
39
|
+
|
40
|
+
t.string :name
|
41
|
+
t.boolean :advanced
|
42
|
+
|
43
|
+
t.boolean :value_boolean
|
44
|
+
t.date :value_date
|
45
|
+
t.decimal :value_decimal
|
46
|
+
t.integer :value_integer
|
47
|
+
t.integer :value_price
|
48
|
+
t.string :value_string
|
49
|
+
|
50
|
+
t.timestamps
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
end
|
data/db/seeds.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
puts "Running effective_reports seeds"
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module EffectiveReports
|
2
|
+
class Engine < ::Rails::Engine
|
3
|
+
engine_name 'effective_reports'
|
4
|
+
|
5
|
+
# Set up our default configuration options.
|
6
|
+
initializer 'effective_reports.defaults', before: :load_config_initializers do |app|
|
7
|
+
eval File.read("#{config.root}/config/effective_reports.rb")
|
8
|
+
end
|
9
|
+
|
10
|
+
# Include acts_as_reportable concern and allow any ActiveRecord object to call it
|
11
|
+
initializer 'effective_reports.active_record' do |app|
|
12
|
+
app.config.to_prepare do
|
13
|
+
ActiveRecord::Base.extend(ActsAsReportable::Base)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'effective_resources'
|
2
|
+
require 'effective_datatables'
|
3
|
+
require 'effective_reports/engine'
|
4
|
+
require 'effective_reports/version'
|
5
|
+
|
6
|
+
module EffectiveReports
|
7
|
+
|
8
|
+
def self.config_keys
|
9
|
+
[
|
10
|
+
# Database Tables
|
11
|
+
:reports_table_name, :report_columns_table_name, :report_scopes_table_name,
|
12
|
+
|
13
|
+
:reportable_class_names,
|
14
|
+
|
15
|
+
# Effective Gem
|
16
|
+
:layout,
|
17
|
+
:mailer, :parent_mailer, :deliver_method, :mailer_layout, :mailer_sender, :mailer_admin, :mailer_subject, :use_effective_email_templates
|
18
|
+
]
|
19
|
+
end
|
20
|
+
|
21
|
+
include EffectiveGem
|
22
|
+
|
23
|
+
def self.reportable_classes
|
24
|
+
Array(reportable_class_names).map(&:safe_constantize).select { |klass| klass.try(:acts_as_reportable?) }
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module EffectiveReports
|
2
|
+
module Generators
|
3
|
+
class InstallGenerator < Rails::Generators::Base
|
4
|
+
include Rails::Generators::Migration
|
5
|
+
|
6
|
+
desc 'Creates an EffectiveReports initializer in your application.'
|
7
|
+
|
8
|
+
source_root File.expand_path('../../templates', __FILE__)
|
9
|
+
|
10
|
+
def self.next_migration_number(dirname)
|
11
|
+
if not ActiveRecord::Base.timestamped_migrations
|
12
|
+
Time.new.utc.strftime("%Y%m%d%H%M%S")
|
13
|
+
else
|
14
|
+
'%.3d' % (current_migration_number(dirname) + 1)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def copy_initializer
|
19
|
+
template ('../' * 3) + 'config/effective_reports.rb', 'config/initializers/effective_reports.rb'
|
20
|
+
end
|
21
|
+
|
22
|
+
def create_migration_file
|
23
|
+
@reports_table_name = ':' + EffectiveReports.reports_table_name.to_s
|
24
|
+
@report_columns_table_name = ':' + EffectiveReports.report_columns_table_name.to_s
|
25
|
+
@report_scopes_table_name = ':' + EffectiveReports.report_scopes_table_name.to_s
|
26
|
+
|
27
|
+
migration_template ('../' * 3) + 'db/migrate/01_create_effective_reports.rb.erb', 'db/migrate/create_effective_reports.rb'
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|