motor-admin 0.1.33 → 0.1.39
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 +4 -4
- data/app/controllers/concerns/motor/load_and_authorize_dynamic_resource.rb +70 -0
- data/app/controllers/motor/alerts_controller.rb +12 -6
- data/app/controllers/motor/audits_controller.rb +16 -0
- data/app/controllers/motor/configs_controller.rb +1 -0
- data/app/controllers/motor/dashboards_controller.rb +4 -0
- data/app/controllers/motor/data_controller.rb +2 -57
- data/app/controllers/motor/forms_controller.rb +4 -0
- data/app/controllers/motor/queries_controller.rb +4 -0
- data/app/controllers/motor/resources_controller.rb +1 -0
- data/app/controllers/motor/ui_controller.rb +4 -0
- data/app/models/motor/alert.rb +2 -0
- data/app/models/motor/application_record.rb +10 -0
- data/app/models/motor/audit.rb +9 -0
- data/app/models/motor/config.rb +2 -0
- data/app/models/motor/dashboard.rb +2 -0
- data/app/models/motor/form.rb +2 -0
- data/app/models/motor/query.rb +2 -0
- data/app/models/motor/resource.rb +2 -0
- data/app/views/motor/ui/show.html.erb +1 -1
- data/config/routes.rb +1 -0
- data/lib/generators/motor/templates/install.rb +40 -16
- data/lib/motor.rb +11 -2
- data/lib/motor/admin.rb +8 -0
- data/lib/motor/alerts/persistance.rb +4 -1
- data/lib/motor/alerts/scheduler.rb +1 -1
- data/lib/motor/api_query/sort.rb +1 -1
- data/lib/motor/build_schema.rb +3 -3
- data/lib/motor/build_schema/load_from_rails.rb +2 -1
- data/lib/motor/build_schema/merge_schema_configs.rb +8 -4
- data/lib/motor/build_schema/reorder_schema.rb +10 -4
- data/lib/motor/configs.rb +16 -0
- data/lib/motor/configs/build_configs_hash.rb +83 -0
- data/lib/motor/configs/build_ui_app_tag.rb +71 -0
- data/lib/motor/configs/load_from_cache.rb +81 -0
- data/lib/motor/configs/sync_from_file.rb +34 -0
- data/lib/motor/configs/sync_from_hash.rb +124 -0
- data/lib/motor/configs/sync_middleware.rb +72 -0
- data/lib/motor/configs/sync_with_remote.rb +39 -0
- data/lib/motor/configs/write_to_file.rb +36 -0
- data/lib/motor/dashboards/persistance.rb +4 -1
- data/lib/motor/forms/persistance.rb +4 -1
- data/lib/motor/net_http_utils.rb +37 -0
- data/lib/motor/queries/persistance.rb +4 -1
- data/lib/motor/railtie.rb +11 -0
- data/lib/motor/tags.rb +2 -1
- data/lib/motor/tasks/motor.rake +29 -0
- data/lib/motor/version.rb +1 -1
- data/ui/dist/{main-b3096c53c77bd4641e52.css.gz → main-e443f49b386b119ff25a.css.gz} +0 -0
- data/ui/dist/main-e443f49b386b119ff25a.js.gz +0 -0
- data/ui/dist/manifest.json +5 -5
- metadata +33 -5
- data/lib/motor/ui_configs.rb +0 -82
- data/ui/dist/main-b3096c53c77bd4641e52.js.gz +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2e0ab742c32ae1b59bfa12c6eb1f838e5d379cb5a964521fe7f345de5fabf953
|
4
|
+
data.tar.gz: 9f018c3475ae06b4104e35f30774c80b2098a8a23b7fa3a8e4ac35df089ee98e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '0651978240824b17dc1f379047faf9f5c5a393b9bebe6e37ae692a606630a300454a2c56c88173383defef451787555006d355fe26c2dd38173f0ece03e116a0'
|
7
|
+
data.tar.gz: b15c006847a5c9dcea315741ccc3a46e3a2bba49ab05d2aceab44c75a530ba0f5fad79067aae0b8e31abad9cda105a827cbdb892d93fd1c2c1fe72a2f62a8637
|
@@ -0,0 +1,70 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Motor
|
4
|
+
module LoadAndAuthorizeDynamicResource
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
INSTANCE_VARIABLE_NAME = 'resource'
|
8
|
+
|
9
|
+
included do
|
10
|
+
before_action :load_and_authorize_resource
|
11
|
+
before_action :load_and_authorize_association
|
12
|
+
end
|
13
|
+
|
14
|
+
def resource_class
|
15
|
+
@resource_class ||=
|
16
|
+
Motor::BuildSchema::Utils.classify_slug(resource_name_prefix + params[:resource])
|
17
|
+
end
|
18
|
+
|
19
|
+
def resource_name_prefix
|
20
|
+
''
|
21
|
+
end
|
22
|
+
|
23
|
+
def load_and_authorize_resource
|
24
|
+
options = {
|
25
|
+
class: resource_class,
|
26
|
+
parent: false,
|
27
|
+
instance_name: INSTANCE_VARIABLE_NAME
|
28
|
+
}
|
29
|
+
|
30
|
+
if params[:resource_id].present?
|
31
|
+
options = options.merge(
|
32
|
+
parent: true,
|
33
|
+
id_param: :resource_id
|
34
|
+
)
|
35
|
+
end
|
36
|
+
|
37
|
+
CanCan::ControllerResource.new(
|
38
|
+
self,
|
39
|
+
options
|
40
|
+
).load_and_authorize_resource
|
41
|
+
rescue ActiveRecord::RecordNotFound
|
42
|
+
head :not_found
|
43
|
+
rescue StandardError => e
|
44
|
+
render json: { errors: [e.message] }, status: :unprocessable_entity
|
45
|
+
end
|
46
|
+
|
47
|
+
def load_and_authorize_association
|
48
|
+
return if params[:association].blank?
|
49
|
+
|
50
|
+
association = resource_class.reflections[params[:association]]
|
51
|
+
|
52
|
+
if association
|
53
|
+
CanCan::ControllerResource.new(
|
54
|
+
self,
|
55
|
+
class: association.klass,
|
56
|
+
parent: false,
|
57
|
+
through: :resource,
|
58
|
+
through_association: params[:association].to_sym,
|
59
|
+
instance_name: INSTANCE_VARIABLE_NAME
|
60
|
+
).load_and_authorize_resource
|
61
|
+
else
|
62
|
+
render json: { message: 'Unknown association' }, status: :not_found
|
63
|
+
end
|
64
|
+
rescue ActiveRecord::RecordNotFound
|
65
|
+
head :not_found
|
66
|
+
rescue StandardError => e
|
67
|
+
render json: { errors: [e.message] }, status: :unprocessable_entity
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -18,12 +18,15 @@ module Motor
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def create
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
21
|
+
if Motor::Alerts::Persistance.name_already_exists?(@alert)
|
22
|
+
name_already_exists_response
|
23
|
+
else
|
24
|
+
ApplicationRecord.transaction { @alert.save! }
|
25
|
+
Motor::Alerts::ScheduledAlertsCache.clear
|
26
|
+
Motor::Configs::WriteToFile.call
|
27
|
+
|
28
|
+
render json: { data: Motor::ApiQuery::BuildJson.call(@alert, params) }
|
29
|
+
end
|
27
30
|
rescue Motor::Alerts::Persistance::InvalidInterval
|
28
31
|
invalid_interval_response
|
29
32
|
end
|
@@ -31,6 +34,7 @@ module Motor
|
|
31
34
|
def update
|
32
35
|
Motor::Alerts::Persistance.update_from_params!(@alert, alert_params)
|
33
36
|
Motor::Alerts::ScheduledAlertsCache.clear
|
37
|
+
Motor::Configs::WriteToFile.call
|
34
38
|
|
35
39
|
render json: { data: Motor::ApiQuery::BuildJson.call(@alert, params) }
|
36
40
|
rescue Motor::Alerts::Persistance::NameAlreadyExists
|
@@ -42,6 +46,8 @@ module Motor
|
|
42
46
|
def destroy
|
43
47
|
@alert.update!(deleted_at: Time.current)
|
44
48
|
|
49
|
+
Motor::Configs::WriteToFile.call
|
50
|
+
|
45
51
|
head :ok
|
46
52
|
end
|
47
53
|
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Motor
|
4
|
+
class AuditsController < ApiBaseController
|
5
|
+
load_and_authorize_resource :audit
|
6
|
+
|
7
|
+
def index
|
8
|
+
audits = Motor::ApiQuery.call(@audits, params)
|
9
|
+
|
10
|
+
render json: {
|
11
|
+
data: Motor::ApiQuery::BuildJson.call(audits, params),
|
12
|
+
meta: Motor::ApiQuery::BuildMeta.call(audits, params)
|
13
|
+
}
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -22,6 +22,7 @@ module Motor
|
|
22
22
|
render json: { errors: [{ source: 'title', detail: 'Title already exists' }] }, status: :unprocessable_entity
|
23
23
|
else
|
24
24
|
ApplicationRecord.transaction { @dashboard.save! }
|
25
|
+
Motor::Configs::WriteToFile.call
|
25
26
|
|
26
27
|
render json: { data: Motor::ApiQuery::BuildJson.call(@dashboard, params) }
|
27
28
|
end
|
@@ -31,6 +32,7 @@ module Motor
|
|
31
32
|
|
32
33
|
def update
|
33
34
|
Motor::Dashboards::Persistance.update_from_params!(@dashboard, dashboard_params)
|
35
|
+
Motor::Configs::WriteToFile.call
|
34
36
|
|
35
37
|
render json: { data: Motor::ApiQuery::BuildJson.call(@dashboard, params) }
|
36
38
|
rescue Motor::Dashboards::Persistance::TitleAlreadyExists
|
@@ -40,6 +42,8 @@ module Motor
|
|
40
42
|
def destroy
|
41
43
|
@dashboard.update!(deleted_at: Time.current)
|
42
44
|
|
45
|
+
Motor::Configs::WriteToFile.call
|
46
|
+
|
43
47
|
head :ok
|
44
48
|
end
|
45
49
|
|
@@ -2,14 +2,10 @@
|
|
2
2
|
|
3
3
|
module Motor
|
4
4
|
class DataController < ApiBaseController
|
5
|
-
include Motor::WrapIoParams
|
6
|
-
|
7
|
-
INSTANCE_VARIABLE_NAME = 'resource'
|
8
|
-
|
9
5
|
wrap_parameters :data, except: %i[include fields]
|
10
6
|
|
11
|
-
|
12
|
-
|
7
|
+
include Motor::WrapIoParams
|
8
|
+
include Motor::LoadAndAuthorizeDynamicResource
|
13
9
|
|
14
10
|
def index
|
15
11
|
@resources = Motor::ApiQuery.call(@resources, params)
|
@@ -64,57 +60,6 @@ module Motor
|
|
64
60
|
|
65
61
|
private
|
66
62
|
|
67
|
-
def resource_class
|
68
|
-
@resource_class ||= Motor::BuildSchema::Utils.classify_slug(params[:resource])
|
69
|
-
end
|
70
|
-
|
71
|
-
def load_and_authorize_resource
|
72
|
-
options = {
|
73
|
-
class: resource_class,
|
74
|
-
parent: false,
|
75
|
-
instance_name: INSTANCE_VARIABLE_NAME
|
76
|
-
}
|
77
|
-
|
78
|
-
if params[:resource_id].present?
|
79
|
-
options = options.merge(
|
80
|
-
parent: true,
|
81
|
-
id_param: :resource_id
|
82
|
-
)
|
83
|
-
end
|
84
|
-
|
85
|
-
CanCan::ControllerResource.new(
|
86
|
-
self,
|
87
|
-
options
|
88
|
-
).load_and_authorize_resource
|
89
|
-
rescue ActiveRecord::RecordNotFound
|
90
|
-
head :not_found
|
91
|
-
rescue StandardError => e
|
92
|
-
render json: { errors: [e.message] }, status: :unprocessable_entity
|
93
|
-
end
|
94
|
-
|
95
|
-
def load_and_authorize_association
|
96
|
-
return if params[:association].blank?
|
97
|
-
|
98
|
-
association = resource_class.reflections[params[:association]]
|
99
|
-
|
100
|
-
if association
|
101
|
-
CanCan::ControllerResource.new(
|
102
|
-
self,
|
103
|
-
class: association.klass,
|
104
|
-
parent: false,
|
105
|
-
through: :resource,
|
106
|
-
through_association: params[:association].to_sym,
|
107
|
-
instance_name: INSTANCE_VARIABLE_NAME
|
108
|
-
).load_and_authorize_resource
|
109
|
-
else
|
110
|
-
render json: { message: 'Unknown association' }, status: :not_found
|
111
|
-
end
|
112
|
-
rescue ActiveRecord::RecordNotFound
|
113
|
-
head :not_found
|
114
|
-
rescue StandardError => e
|
115
|
-
render json: { errors: [e.message] }, status: :unprocessable_entity
|
116
|
-
end
|
117
|
-
|
118
63
|
def resource_params
|
119
64
|
if params[:data].present?
|
120
65
|
params.require(:data).except(resource_class.primary_key).permit!
|
@@ -22,6 +22,7 @@ module Motor
|
|
22
22
|
render json: { errors: [{ source: 'name', detail: 'Name already exists' }] }, status: :unprocessable_entity
|
23
23
|
else
|
24
24
|
ApplicationRecord.transaction { @form.save! }
|
25
|
+
Motor::Configs::WriteToFile.call
|
25
26
|
|
26
27
|
render json: { data: Motor::ApiQuery::BuildJson.call(@form, params) }
|
27
28
|
end
|
@@ -31,6 +32,7 @@ module Motor
|
|
31
32
|
|
32
33
|
def update
|
33
34
|
Motor::Forms::Persistance.update_from_params!(@form, form_params)
|
35
|
+
Motor::Configs::WriteToFile.call
|
34
36
|
|
35
37
|
render json: { data: Motor::ApiQuery::BuildJson.call(@form, params) }
|
36
38
|
rescue Motor::Forms::Persistance::NameAlreadyExists
|
@@ -40,6 +42,8 @@ module Motor
|
|
40
42
|
def destroy
|
41
43
|
@form.update!(deleted_at: Time.current)
|
42
44
|
|
45
|
+
Motor::Configs::WriteToFile.call
|
46
|
+
|
43
47
|
head :ok
|
44
48
|
end
|
45
49
|
|
@@ -22,6 +22,7 @@ module Motor
|
|
22
22
|
render json: { errors: [{ source: 'name', detail: 'Name already exists' }] }, status: :unprocessable_entity
|
23
23
|
else
|
24
24
|
ApplicationRecord.transaction { @query.save! }
|
25
|
+
Motor::Configs::WriteToFile.call
|
25
26
|
|
26
27
|
render json: { data: Motor::ApiQuery::BuildJson.call(@query, params) }
|
27
28
|
end
|
@@ -31,6 +32,7 @@ module Motor
|
|
31
32
|
|
32
33
|
def update
|
33
34
|
Motor::Queries::Persistance.update_from_params!(@query, query_params)
|
35
|
+
Motor::Configs::WriteToFile.call
|
34
36
|
|
35
37
|
render json: { data: Motor::ApiQuery::BuildJson.call(@query, params) }
|
36
38
|
rescue Motor::Queries::Persistance::NameAlreadyExists
|
@@ -40,6 +42,8 @@ module Motor
|
|
40
42
|
def destroy
|
41
43
|
@query.update!(deleted_at: Time.current)
|
42
44
|
|
45
|
+
Motor::Configs::WriteToFile.call
|
46
|
+
|
43
47
|
head :ok
|
44
48
|
end
|
45
49
|
|
@@ -7,12 +7,16 @@ module Motor
|
|
7
7
|
def index
|
8
8
|
Motor.reload! if Motor.development?
|
9
9
|
|
10
|
+
Motor::Configs::SyncFromFile.call
|
11
|
+
|
10
12
|
render :show
|
11
13
|
end
|
12
14
|
|
13
15
|
def show
|
14
16
|
Motor.reload! if Motor.development?
|
15
17
|
|
18
|
+
Motor::Configs::SyncFromFile.call
|
19
|
+
|
16
20
|
render :show
|
17
21
|
end
|
18
22
|
end
|
data/app/models/motor/alert.rb
CHANGED
@@ -4,5 +4,15 @@ module Motor
|
|
4
4
|
class ApplicationRecord < ActiveRecord::Base
|
5
5
|
self.abstract_class = true
|
6
6
|
self.table_name_prefix = 'motor_'
|
7
|
+
|
8
|
+
def self.audited(*args)
|
9
|
+
default_class = Audited.audit_class
|
10
|
+
|
11
|
+
Audited.audit_class = Motor::Audit
|
12
|
+
|
13
|
+
super
|
14
|
+
ensure
|
15
|
+
Audited.audit_class = default_class
|
16
|
+
end
|
7
17
|
end
|
8
18
|
end
|
data/app/models/motor/config.rb
CHANGED
data/app/models/motor/form.rb
CHANGED
data/app/models/motor/query.rb
CHANGED
@@ -1 +1 @@
|
|
1
|
-
<%= raw(Motor::
|
1
|
+
<%= raw(Motor::Configs::BuildUiAppTag.call) %>
|
data/config/routes.rb
CHANGED
@@ -15,6 +15,7 @@ Motor::Admin.routes.draw do
|
|
15
15
|
resources :alerts, only: %i[index show create update destroy]
|
16
16
|
resources :active_storage_attachments, only: %i[create], path: 'data/active_storage__attachments'
|
17
17
|
resource :schema, only: %i[show update]
|
18
|
+
resources :audits, only: %i[index]
|
18
19
|
resources :resources, path: '/data/:resource',
|
19
20
|
only: %i[index show update create destroy],
|
20
21
|
controller: 'data' do
|
@@ -13,9 +13,9 @@ class <%= migration_class_name %> < ActiveRecord::Migration[<%= ActiveRecord::Mi
|
|
13
13
|
|
14
14
|
t.index :updated_at
|
15
15
|
t.index 'lower(name)',
|
16
|
-
|
17
|
-
|
18
|
-
|
16
|
+
name: 'motor_queries_lower_name_unique_index',
|
17
|
+
unique: true,
|
18
|
+
where: 'deleted_at IS NULL'
|
19
19
|
end
|
20
20
|
|
21
21
|
create_table :motor_dashboards, force: true do |t|
|
@@ -30,9 +30,9 @@ class <%= migration_class_name %> < ActiveRecord::Migration[<%= ActiveRecord::Mi
|
|
30
30
|
|
31
31
|
t.index :updated_at
|
32
32
|
t.index 'lower(title)',
|
33
|
-
|
34
|
-
|
35
|
-
|
33
|
+
name: 'motor_dashboards_lower_title_unique_index',
|
34
|
+
unique: true,
|
35
|
+
where: 'deleted_at IS NULL'
|
36
36
|
end
|
37
37
|
|
38
38
|
create_table :motor_forms, force: true do |t|
|
@@ -49,9 +49,9 @@ class <%= migration_class_name %> < ActiveRecord::Migration[<%= ActiveRecord::Mi
|
|
49
49
|
|
50
50
|
t.index :updated_at
|
51
51
|
t.index 'lower(name)',
|
52
|
-
|
53
|
-
|
54
|
-
|
52
|
+
name: 'motor_forms_lower_name_unique_index',
|
53
|
+
unique: true,
|
54
|
+
where: 'deleted_at IS NULL'
|
55
55
|
end
|
56
56
|
|
57
57
|
create_table :motor_resources, force: true do |t|
|
@@ -87,9 +87,9 @@ class <%= migration_class_name %> < ActiveRecord::Migration[<%= ActiveRecord::Mi
|
|
87
87
|
|
88
88
|
t.index :updated_at
|
89
89
|
t.index 'lower(name)',
|
90
|
-
|
91
|
-
|
92
|
-
|
90
|
+
name: 'motor_alerts_lower_name_unique_index',
|
91
|
+
unique: true,
|
92
|
+
where: 'deleted_at IS NULL'
|
93
93
|
end
|
94
94
|
|
95
95
|
create_table :motor_alert_locks, force: true do |t|
|
@@ -107,8 +107,8 @@ class <%= migration_class_name %> < ActiveRecord::Migration[<%= ActiveRecord::Mi
|
|
107
107
|
t.timestamps
|
108
108
|
|
109
109
|
t.index 'lower(name)',
|
110
|
-
|
111
|
-
|
110
|
+
name: 'motor_tags_lower_name_unique_index',
|
111
|
+
unique: true
|
112
112
|
end
|
113
113
|
|
114
114
|
create_table :motor_taggable_tags, force: true do |t|
|
@@ -117,12 +117,36 @@ class <%= migration_class_name %> < ActiveRecord::Migration[<%= ActiveRecord::Mi
|
|
117
117
|
t.column :taggable_type, :string, null: false
|
118
118
|
|
119
119
|
t.index %i[taggable_id taggable_type tag_id],
|
120
|
-
|
121
|
-
|
120
|
+
name: 'motor_polymorphic_association_tag_index',
|
121
|
+
unique: true
|
122
122
|
end
|
123
|
+
|
124
|
+
create_table :motor_audits, force: true do |t|
|
125
|
+
t.column :auditable_id, :integer
|
126
|
+
t.column :auditable_type, :string
|
127
|
+
t.column :associated_id, :integer
|
128
|
+
t.column :associated_type, :string
|
129
|
+
t.column :user_id, :integer
|
130
|
+
t.column :user_type, :string
|
131
|
+
t.column :username, :string
|
132
|
+
t.column :action, :string
|
133
|
+
t.column :audited_changes, :text
|
134
|
+
t.column :version, :integer, default: 0
|
135
|
+
t.column :comment, :string
|
136
|
+
t.column :remote_address, :string
|
137
|
+
t.column :request_uuid, :string
|
138
|
+
t.column :created_at, :datetime
|
139
|
+
end
|
140
|
+
|
141
|
+
add_index :motor_audits, %i[auditable_type auditable_id version], name: 'motor_auditable_index'
|
142
|
+
add_index :motor_audits, %i[associated_type associated_id], name: 'motor_auditable_associated_index'
|
143
|
+
add_index :motor_audits, %i[user_id user_type], name: 'motor_auditable_user_index'
|
144
|
+
add_index :motor_audits, :request_uuid
|
145
|
+
add_index :motor_audits, :created_at
|
123
146
|
end
|
124
147
|
|
125
148
|
def self.down
|
149
|
+
drop_table :motor_audits
|
126
150
|
drop_table :motor_alert_locks
|
127
151
|
drop_table :motor_alerts
|
128
152
|
drop_table :motor_taggable_tags
|