action_blocks 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/LICENSE +21 -0
- data/README.md +121 -0
- data/Rakefile +33 -0
- data/app/assets/config/action_blocks.js +2 -0
- data/app/assets/javascripts/action_blocks/application.js +15 -0
- data/app/assets/stylesheets/action_blocks/application.css +15 -0
- data/app/controllers/action_blocks/attachments_controller.rb +22 -0
- data/app/controllers/action_blocks/barchart_blocks_controller.rb +14 -0
- data/app/controllers/action_blocks/base_controller.rb +22 -0
- data/app/controllers/action_blocks/blocks_controller.rb +16 -0
- data/app/controllers/action_blocks/command_blocks_controller.rb +6 -0
- data/app/controllers/action_blocks/form_blocks_controller.rb +13 -0
- data/app/controllers/action_blocks/model_blocks_controller.rb +13 -0
- data/app/controllers/action_blocks/table_blocks_controller.rb +13 -0
- data/app/controllers/action_blocks/workspace_blocks_controller.rb +6 -0
- data/app/helpers/action_blocks/application_helper.rb +4 -0
- data/app/jobs/action_blocks/application_job.rb +4 -0
- data/app/mailers/action_blocks/application_mailer.rb +6 -0
- data/app/models/action_blocks/application_record.rb +5 -0
- data/app/views/layouts/action_blocks/application.html.erb +16 -0
- data/config/initializers/action_blocks.rb +9 -0
- data/config/routes.rb +10 -0
- data/lib/action_block_loader.rb +120 -0
- data/lib/action_blocks.rb +76 -0
- data/lib/action_blocks/builders/authorization_builder.rb +21 -0
- data/lib/action_blocks/builders/barchart_builder.rb +48 -0
- data/lib/action_blocks/builders/base_builder.rb +221 -0
- data/lib/action_blocks/builders/block_type.rb +11 -0
- data/lib/action_blocks/builders/command_builder.rb +6 -0
- data/lib/action_blocks/builders/form_builder.rb +117 -0
- data/lib/action_blocks/builders/layout_builder.rb +15 -0
- data/lib/action_blocks/builders/model_builder.rb +566 -0
- data/lib/action_blocks/builders/summary_field_aggregation_functions.rb +41 -0
- data/lib/action_blocks/builders/table_builder.rb +259 -0
- data/lib/action_blocks/builders/workspace_builder.rb +282 -0
- data/lib/action_blocks/data_engine/authorization_adapter.rb +127 -0
- data/lib/action_blocks/data_engine/data_engine.rb +116 -0
- data/lib/action_blocks/data_engine/database_functions.rb +39 -0
- data/lib/action_blocks/data_engine/fields_engine.rb +103 -0
- data/lib/action_blocks/data_engine/filter_adapter.rb +105 -0
- data/lib/action_blocks/data_engine/filter_engine.rb +88 -0
- data/lib/action_blocks/data_engine/selections_via_where_engine.rb +134 -0
- data/lib/action_blocks/data_engine/summary_engine.rb +72 -0
- data/lib/action_blocks/engine.rb +5 -0
- data/lib/action_blocks/error.rb +62 -0
- data/lib/action_blocks/generator_helper.rb +134 -0
- data/lib/action_blocks/generators/action_blocks/model_block/USAGE +8 -0
- data/lib/action_blocks/generators/action_blocks/model_block/model_block_generator.rb +17 -0
- data/lib/action_blocks/generators/action_blocks/model_block/templates/model_block.rb +13 -0
- data/lib/action_blocks/generators/action_blocks/type/USAGE +8 -0
- data/lib/action_blocks/generators/action_blocks/type/templates/controller.rb +3 -0
- data/lib/action_blocks/generators/action_blocks/type/templates/dsl.rb +38 -0
- data/lib/action_blocks/generators/action_blocks/type/templates/type.css +3 -0
- data/lib/action_blocks/generators/action_blocks/type/templates/type.js +22 -0
- data/lib/action_blocks/generators/action_blocks/type/type_generator.rb +33 -0
- data/lib/action_blocks/store.rb +151 -0
- data/lib/action_blocks/version.rb +3 -0
- data/lib/generators/active_blocks/model_block/USAGE +8 -0
- data/lib/generators/active_blocks/model_block/model_block_generator.rb +17 -0
- data/lib/generators/active_blocks/model_block/templates/model_block.rb +13 -0
- data/lib/generators/active_blocks/type/USAGE +8 -0
- data/lib/generators/active_blocks/type/templates/controller.rb +3 -0
- data/lib/generators/active_blocks/type/templates/dsl.rb +38 -0
- data/lib/generators/active_blocks/type/templates/type.css +3 -0
- data/lib/generators/active_blocks/type/templates/type.js +22 -0
- data/lib/generators/active_blocks/type/type_generator.rb +33 -0
- data/lib/tasks/active_blocks_tasks.rake +4 -0
- metadata +128 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: a75a9346f84e224424ecd5353246ad7add3cf51236db4582edad2195e1e5ee5e
|
|
4
|
+
data.tar.gz: a63d8109813b23def1edbae53957734b135a835b8670ea2cf7698f7cf889e5c1
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: dec0b245ea8c07e74fcc1bad08152b02b581cb84a5fa19b222041a5fb7a75f55da43c11d49a9bd66d9eec80f604929468cd4a99afbeab7050e5020db388d3dc8
|
|
7
|
+
data.tar.gz: 38360d45575e3c1672668301867391dcfd80674b37c61395e49abc12789c01ca63596c08313e9fff3044c4ebbc5fc6bc16aefb04f74075da78828308fa951df7
|
data/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2018 CTEH LLC
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# ActionBlocks
|
|
2
|
+
[](https://travis-ci.org/CTEH/action_blocks)
|
|
3
|
+
|
|
4
|
+
ActionBlocks is a Ruby On Rails engine for building administrative database-driven applications.
|
|
5
|
+
|
|
6
|
+
* Automates Backend and Frontend Development
|
|
7
|
+
|
|
8
|
+
* Supports Granular Authorization
|
|
9
|
+
|
|
10
|
+
* Leverages PostgreSQL for Performance
|
|
11
|
+
|
|
12
|
+
* Encourages Task Oriented UI
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
Automates Backend and Frontend Development
|
|
16
|
+
-------------------
|
|
17
|
+
|
|
18
|
+
A single low-code DSL is used to define both the backend and frontend.
|
|
19
|
+
|
|
20
|
+

|
|
21
|
+
|
|
22
|
+
```ruby
|
|
23
|
+
ActionBlocks.app do
|
|
24
|
+
title "My App"
|
|
25
|
+
workspace :main do
|
|
26
|
+
subspace :orders do
|
|
27
|
+
dashboard :all_orders do
|
|
28
|
+
table :list_all do
|
|
29
|
+
model :order
|
|
30
|
+
columns [:number, :employee, :customer, :status]
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
...
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Supports Granular Authorization
|
|
38
|
+
----------
|
|
39
|
+
|
|
40
|
+
Row Level Security (RLS) is defined for each role.
|
|
41
|
+
|
|
42
|
+
```ruby
|
|
43
|
+
ActionBlock.authorize Post do
|
|
44
|
+
grant :reviewer do
|
|
45
|
+
_or(
|
|
46
|
+
_eq(:author_id, _user(:id)),
|
|
47
|
+
_eq(:status, 'Published')
|
|
48
|
+
),
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Field Level Security (FLS) is defined for each role.
|
|
54
|
+
|
|
55
|
+
```ruby
|
|
56
|
+
read do
|
|
57
|
+
read :employee, [:admin ]
|
|
58
|
+
read :customer, [:admin, :customer]
|
|
59
|
+
read :social_security [:admin, :customer]
|
|
60
|
+
read :order_date, [:admin, :customer]
|
|
61
|
+
read :shipped_date, [:admin, :customer]
|
|
62
|
+
read :ship_name, [:admin, :customer]
|
|
63
|
+
read :ship_address1, [:admin, :customer]
|
|
64
|
+
read :ship_address2, [:admin, :customer]
|
|
65
|
+
read :ship_city, [:admin, :customer]
|
|
66
|
+
read :ship_state, [:admin, :customer]
|
|
67
|
+
read :ship_postal_code, [:admin, :customer]
|
|
68
|
+
read :ship_country, [:admin, :customer]
|
|
69
|
+
read :shipping_fee, [:admin, :customer]
|
|
70
|
+
read :payment_type, [:admin, :customer]
|
|
71
|
+
read :paid_date, [:admin, :customer]
|
|
72
|
+
read :created_at, [:admin, :customer]
|
|
73
|
+
read :updated_at, [:admin, :customer]
|
|
74
|
+
read :region, [:admin, :customer]
|
|
75
|
+
read :referred_by, [:admin, :customer]
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
Leverages PostgreSQL for Performance
|
|
83
|
+
------------
|
|
84
|
+
|
|
85
|
+
ActionBlocks is similar to [Hasura](https://blog.hasura.io/architecture-of-a-high-performance-graphql-to-sql-server-58d9944b8a87) since it avoids N+1 queries and pushes JSON generation into PostgreSQL
|
|
86
|
+
|
|
87
|
+
* Uses an intelligent DSL managed data engine that avoids the N+1 problem associated with retrieving data in related tables and running authorization checks.
|
|
88
|
+
|
|
89
|
+
* Bypasses the performance tax of marshalling results to Objects and ultimately to JSON by pushing the transformation into PostgreSQL.
|
|
90
|
+
|
|
91
|
+
Encourages Task Oriented UI
|
|
92
|
+
------------
|
|
93
|
+
|
|
94
|
+
Following the pholisophy of make the right thing the easy thing, ActionBlocks doesn't support CRUD. Instead it provides a rich DSL for Task Oriented UIs as explained https://cqrs.wordpress.com/documents/task-based-ui/
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
## License
|
|
99
|
+
MIT License
|
|
100
|
+
|
|
101
|
+
Copyright (c) 2018 CTEH LLC
|
|
102
|
+
|
|
103
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
104
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
105
|
+
in the Software without restriction, including without limitation the rights
|
|
106
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
107
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
108
|
+
furnished to do so, subject to the following conditions:
|
|
109
|
+
|
|
110
|
+
The above copyright notice and this permission notice shall be included in all
|
|
111
|
+
copies or substantial portions of the Software.
|
|
112
|
+
|
|
113
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
114
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
115
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
116
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
117
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
118
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
119
|
+
SOFTWARE.
|
|
120
|
+
|
|
121
|
+
|
data/Rakefile
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
begin
|
|
2
|
+
require 'bundler/setup'
|
|
3
|
+
rescue LoadError
|
|
4
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
require 'rdoc/task'
|
|
8
|
+
|
|
9
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
|
10
|
+
rdoc.rdoc_dir = 'rdoc'
|
|
11
|
+
rdoc.title = 'ActionBlocks'
|
|
12
|
+
rdoc.options << '--line-numbers'
|
|
13
|
+
rdoc.rdoc_files.include('README.md')
|
|
14
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
APP_RAKEFILE = File.expand_path("test/north_winds/Rakefile", __dir__)
|
|
18
|
+
load 'rails/tasks/engine.rake'
|
|
19
|
+
|
|
20
|
+
load 'rails/tasks/statistics.rake'
|
|
21
|
+
|
|
22
|
+
require 'bundler/gem_tasks'
|
|
23
|
+
|
|
24
|
+
require 'rake/testtask'
|
|
25
|
+
|
|
26
|
+
Rake::TestTask.new(:test) do |t|
|
|
27
|
+
t.libs << 'test'
|
|
28
|
+
t.pattern = 'test/**/*_test.rb'
|
|
29
|
+
t.verbose = false
|
|
30
|
+
t.warning = false
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
task default: :test
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// This is a manifest file that'll be compiled into application.js, which will include all the files
|
|
2
|
+
// listed below.
|
|
3
|
+
//
|
|
4
|
+
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
|
|
5
|
+
// or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
|
|
6
|
+
//
|
|
7
|
+
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
|
|
8
|
+
// compiled file. JavaScript code in this file should be added after the last require_* statement.
|
|
9
|
+
//
|
|
10
|
+
// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
|
|
11
|
+
// about supported directives.
|
|
12
|
+
//
|
|
13
|
+
//= require rails-ujs
|
|
14
|
+
//= require activestorage
|
|
15
|
+
//= require_tree .
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* This is a manifest file that'll be compiled into application.css, which will include all the files
|
|
3
|
+
* listed below.
|
|
4
|
+
*
|
|
5
|
+
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
|
|
6
|
+
* or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
|
|
7
|
+
*
|
|
8
|
+
* You're free to add application-wide styles to this file and they'll appear at the bottom of the
|
|
9
|
+
* compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
|
|
10
|
+
* files in this directory. Styles in this file should be added after the last require_* statement.
|
|
11
|
+
* It is generally better to create a new file per style scope.
|
|
12
|
+
*
|
|
13
|
+
*= require_tree .
|
|
14
|
+
*= require_self
|
|
15
|
+
*/
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
module ActionBlocks
|
|
2
|
+
class AttachmentsController < ActionController::Base
|
|
3
|
+
before_action :authenticate_user!
|
|
4
|
+
|
|
5
|
+
def download
|
|
6
|
+
model = ActionBlocks.find(params[:model_key])
|
|
7
|
+
if model == nil
|
|
8
|
+
raise RecordNotFound
|
|
9
|
+
end
|
|
10
|
+
id = params[:id]
|
|
11
|
+
field = params[:field]
|
|
12
|
+
record = model.active_model.find(id)
|
|
13
|
+
attachment = record.send(field)
|
|
14
|
+
begin
|
|
15
|
+
send_data attachment.download
|
|
16
|
+
rescue Module::DelegationError
|
|
17
|
+
raise ActiveRecord::RecordNotFound
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
module ActionBlocks
|
|
2
|
+
class BarchartBlocksController < ActionBlocks::BaseController
|
|
3
|
+
before_action :authenticate_user!
|
|
4
|
+
|
|
5
|
+
def analytics
|
|
6
|
+
block = ActionBlocks.find(params[:block_key])
|
|
7
|
+
user = nil
|
|
8
|
+
if block.calculate == :count
|
|
9
|
+
render plain: block.scope.call().group(block.group.column).count.to_json
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
module ActionBlocks
|
|
2
|
+
|
|
3
|
+
class BaseController < ApplicationController
|
|
4
|
+
# Disable need for authenticity token as we
|
|
5
|
+
# we are integrating with clients not rendered by rails
|
|
6
|
+
|
|
7
|
+
# JRH - https://labs.chiedo.com/blog/authenticating-your-reactjs-app-with-devise-no-extra-gems-needed/
|
|
8
|
+
|
|
9
|
+
before_action :validate_action_block
|
|
10
|
+
def validate_action_block
|
|
11
|
+
if Rails.env.development? || Rails.env.test?
|
|
12
|
+
if ActionBlocks.invalid?
|
|
13
|
+
Rails.logger.error "ActionBlock application invalid"
|
|
14
|
+
Rails.logger.error ActionBlocks.errors
|
|
15
|
+
raise "ActionBlock application invalid #{ActionBlocks.errors}"
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
module ActionBlocks
|
|
2
|
+
class BlocksController < BaseController
|
|
3
|
+
before_action :authenticate_user!
|
|
4
|
+
skip_before_action :validate_action_block
|
|
5
|
+
|
|
6
|
+
def index
|
|
7
|
+
user = nil
|
|
8
|
+
if ActionBlocks.invalid?
|
|
9
|
+
render json: {errors: ActionBlocks.errors}.to_json, content_type: 'application/json'
|
|
10
|
+
else
|
|
11
|
+
render json: ActionBlocks.hashify(user).to_json, content_type: 'application/json'
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
module ActionBlocks
|
|
2
|
+
|
|
3
|
+
class FormBlocksController < ActionBlocks::BaseController
|
|
4
|
+
before_action :authenticate_user!
|
|
5
|
+
|
|
6
|
+
def record
|
|
7
|
+
form = ActionBlocks.find(params[:block_key])
|
|
8
|
+
record_id = Integer(params[:record_id])
|
|
9
|
+
render json: form.record_to_json(user: current_user, record_id: record_id)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
module ActionBlocks
|
|
2
|
+
|
|
3
|
+
class ModelBlocksController < ActionBlocks::BaseController
|
|
4
|
+
before_action :authenticate_user!
|
|
5
|
+
|
|
6
|
+
def name
|
|
7
|
+
model_block = ActionBlocks.find(params[:block_key])
|
|
8
|
+
record_id = Integer(params[:record_id])
|
|
9
|
+
render json: model_block.name_to_json(record_id: record_id, user: current_user)
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
module ActionBlocks
|
|
2
|
+
class TableBlocksController < ActionBlocks::BaseController
|
|
3
|
+
before_action :authenticate_user!
|
|
4
|
+
|
|
5
|
+
def records
|
|
6
|
+
params.permit([:block_key, :subspace_model_id, :dashboard_model_id])
|
|
7
|
+
user = current_user
|
|
8
|
+
table = ActionBlocks.find(params[:block_key])
|
|
9
|
+
render json: table.to_json(user: current_user, params: params)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<title>Active blocks</title>
|
|
5
|
+
<%= csrf_meta_tags %>
|
|
6
|
+
<%= csp_meta_tag %>
|
|
7
|
+
|
|
8
|
+
<%= stylesheet_link_tag "action_blocks/application", media: "all" %>
|
|
9
|
+
<%= javascript_include_tag "action_blocks/application" %>
|
|
10
|
+
</head>
|
|
11
|
+
<body>
|
|
12
|
+
|
|
13
|
+
<%= yield %>
|
|
14
|
+
|
|
15
|
+
</body>
|
|
16
|
+
</html>
|
data/config/routes.rb
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
ActionBlocks::Engine.routes.draw do
|
|
2
|
+
get "action_blocks/blocks", to: "blocks#blocks"
|
|
3
|
+
get "table_blocks/:block_key(/:subspace_model_id)(/:dashboard_model_id)/records", to: "table_blocks#records"
|
|
4
|
+
get "form_blocks/:block_key/:record_id/record", to: "form_blocks#record"
|
|
5
|
+
get "blocks", to: "blocks#index"
|
|
6
|
+
get "barchart_blocks/:block_key/analytics", to: "barchart_blocks#analytics"
|
|
7
|
+
get "model_blocks/:block_key/:record_id/name", to: "model_blocks#name"
|
|
8
|
+
get 'attachments/:model_key/:id/:field' => "attachments#download"
|
|
9
|
+
|
|
10
|
+
end
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
# require 'active_admin/reloader'
|
|
2
|
+
|
|
3
|
+
module ActionBlocks
|
|
4
|
+
class Loader
|
|
5
|
+
|
|
6
|
+
attr_reader :application, :load_paths
|
|
7
|
+
def initialize(path)
|
|
8
|
+
@load_paths = [File.expand_path(path, Rails.root)]
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
# Whether all configuration files have been loaded
|
|
12
|
+
def loaded?
|
|
13
|
+
@@loaded ||= false
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# Removes all defined controllers from memory. Useful in
|
|
17
|
+
# development, where they are reloaded on each request.
|
|
18
|
+
def unload!
|
|
19
|
+
ActionBlocks.unload!
|
|
20
|
+
@@loaded = false
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Loads all ruby files that are within the load_paths setting.
|
|
24
|
+
# To reload everything simply call `ActionBlocks.unload!`
|
|
25
|
+
def load!
|
|
26
|
+
Rails.logger.debug "ActionBlocks::Loader load!()"
|
|
27
|
+
Rails.logger.debug " loaded?:#{loaded?().inspect}"
|
|
28
|
+
unless loaded?
|
|
29
|
+
# ActiveSupport::Notifications.publish BeforeLoadEvent, self # before_load hook
|
|
30
|
+
files.each{ |file| load file } # load files
|
|
31
|
+
# ActiveSupport::Notifications.publish AfterLoadEvent, self # after_load hook
|
|
32
|
+
@@loaded = true
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def load(file)
|
|
37
|
+
Rails.logger.debug "ActionBlocks::Loader load(#{file})"
|
|
38
|
+
DatabaseHitDuringLoad.capture{ super }
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Returns ALL the files to be loaded
|
|
42
|
+
def files
|
|
43
|
+
load_paths.flatten.compact.uniq.flat_map{ |path| Dir["#{path}/**/*.rb"] }
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Since app/blocks is alphabetically before app/models, we have to remove it
|
|
47
|
+
# from the host app's +autoload_paths+ to prevent missing constant errors.
|
|
48
|
+
#
|
|
49
|
+
# As well, we have to remove it from +eager_load_paths+ to prevent the
|
|
50
|
+
# files from being loaded twice in production.
|
|
51
|
+
def remove_active_admin_load_paths_from_rails_autoload_and_eager_load
|
|
52
|
+
ActiveSupport::Dependencies.autoload_paths -= load_paths
|
|
53
|
+
Rails.application.config.eager_load_paths -= load_paths
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Hook into the Rails code reloading mechanism so that things are reloaded
|
|
57
|
+
# properly in development mode.
|
|
58
|
+
#
|
|
59
|
+
# If any of the app files (e.g. models) has changed, we need to reload all
|
|
60
|
+
# the admin files. If the admin files themselves has changed, we need to
|
|
61
|
+
# regenerate the routes as well.
|
|
62
|
+
def attach_reloader
|
|
63
|
+
# ActiveSupport::Reloader.to_prepare(*args, &block)
|
|
64
|
+
Rails.application.config.after_initialize do |app|
|
|
65
|
+
if app.config.reload_classes_only_on_change
|
|
66
|
+
# Rails is about to unload all the app files (e.g. models), so we
|
|
67
|
+
# should first unload the classes generated by Active Admin, otherwise
|
|
68
|
+
# they will contain references to the stale (unloaded) classes.
|
|
69
|
+
ActiveSupport::Reloader.to_prepare(prepend: true) do
|
|
70
|
+
ActionBlocks.unload!
|
|
71
|
+
end
|
|
72
|
+
else
|
|
73
|
+
# If the user has configured the app to always reload app files after
|
|
74
|
+
# each request, so we should unload the generated classes too.
|
|
75
|
+
ActiveSupport::Reloader.to_complete() do
|
|
76
|
+
puts "ActiveSupport::Reloader.to_complete()\n"
|
|
77
|
+
# ActionBlocks.application.unload!
|
|
78
|
+
# @@loaded = false
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# block_drs = {}
|
|
83
|
+
#
|
|
84
|
+
# load_paths.each do |path|
|
|
85
|
+
# block_drs[path] = [:rb]
|
|
86
|
+
# end
|
|
87
|
+
|
|
88
|
+
# routes_reloader = app.config.file_watcher.new([], block_drs) do
|
|
89
|
+
# app.reload_routes!
|
|
90
|
+
# end
|
|
91
|
+
#
|
|
92
|
+
# app.reloaders << routes_reloader
|
|
93
|
+
|
|
94
|
+
ActiveSupport::Reloader.to_prepare do
|
|
95
|
+
# Rails.logger.debug("--> 1. ActionBlocks::Loader.new('app/blocks')")
|
|
96
|
+
loader = ActionBlocks::Loader.new('app/blocks')
|
|
97
|
+
loader.unload!
|
|
98
|
+
loader.load!
|
|
99
|
+
ActionBlocks.after_load
|
|
100
|
+
|
|
101
|
+
# loader.attach_reloader
|
|
102
|
+
# Rails might have reloaded the routes for other reasons (e.g.
|
|
103
|
+
# routes.rb has changed), in which case Active Admin would have been
|
|
104
|
+
# loaded via the `ActiveAdmin.routes` call in `routes.rb`.
|
|
105
|
+
#
|
|
106
|
+
# Otherwise, we should check if any of the admin files are changed
|
|
107
|
+
# and force the routes to reload if necessary. This would again causes
|
|
108
|
+
# Active Admin to load via `ActiveAdmin.routes`.
|
|
109
|
+
#
|
|
110
|
+
# Finally, if Active Admin is still not loaded at this point, then we
|
|
111
|
+
# would need to load it manually.
|
|
112
|
+
# unless ActionBlocks.application.loaded?
|
|
113
|
+
# routes_reloader.execute_if_updated
|
|
114
|
+
# self.load!
|
|
115
|
+
# end
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
end #attach_reloader
|
|
119
|
+
end
|
|
120
|
+
end
|