tramway-admin 1.32.1.4 → 1.32.2.5

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
  SHA256:
3
- metadata.gz: 12f18ece55fa0e66275d0ace0972d67490dc5396d7003f0ea0f24ab89d3e1be8
4
- data.tar.gz: 4288cb1d7368b94747ddb238ece0024fca1e6f306a45aaf7c38a8e097b37ecf2
3
+ metadata.gz: 38545a69081961dbceae8db18e98f49405462bf332aeb852d001bf5332e0b127
4
+ data.tar.gz: 7f5e3942cba417767b231005efeddb6ea042ba8b91728946a286f4a97079d00e
5
5
  SHA512:
6
- metadata.gz: 65a7acba188612cc40301ff7949a4ecd5087154e7ecab8e4d8c9f366a56d2e9d043f3ad17d6e1cb9ac252e60615975a5c71b68f146bdf62edd9ef742d329baf1
7
- data.tar.gz: 4cd7656172be3b226933b5fc81bb995aef736ba49488398f9680723ebe905954b73bd185765b40b0151cfce42817faac6e8c81f7a03d878e27761fdf9f26ea2f
6
+ metadata.gz: d1e1eaf40a6b789dd0d9c368fa193152c484791397a259222d89a06f623332501e0b3af3d3d8a63d5785b6e8b9eed610bb091e632406b3a8b025cc2535878bfd
7
+ data.tar.gz: 14acb2b150a1dd2c5e0ecee95668c73ec93fab2805095d0918a95b36d21534e5afdd640a9f4afd3c02671231ebca72dc5d9e789e3fd534377eafe5d94e766cd8
data/README.md CHANGED
@@ -43,7 +43,7 @@ Rails.application.routes.draw do
43
43
  end
44
44
  ```
45
45
 
46
- #### 4. Then make `tramway-core` installation. [How-to](https://github.com/ulmic/tramway-dev/blob/develop/tramway-core/README.md#installation)
46
+ #### 4. Then make `tramway-core` installation. [How-to](https://github.com/Purple-Magic/tramway-core/blob/develop/README.md#installation)
47
47
 
48
48
 
49
49
  #### 5. And then execute:
@@ -88,31 +88,46 @@ Tramway::Admin.navbar_structure(
88
88
  project: :your_application_name
89
89
  )
90
90
  ```
91
+ #### 9. Create decorators and forms for all available_models.
92
+ You can run generator that will create all necessary files
93
+ ```bash
94
+ $ rails g tramway:admin:install
95
+ ```
96
+ Or generate decorator and form for only one model
97
+ ```bash
98
+ $ rails g tramway:admin:model Coworking
99
+ ```
100
+ If you're using several user roles in your admin dashboard, then you can specify scope for the form(default scope is `admin`)
101
+ ```bash
102
+ $ rails g tramway:admin:install --user-role=partner
103
+ ```
91
104
 
92
- #### 9. Create decorator for models
105
+ Or you can create forms and decorators manually as it written below:
106
+
107
+ #### 9a. Create decorator for models [manual option]
93
108
 
94
109
  *app/decorators/your_model_decorator.rb*
95
110
  ```ruby
96
111
  class YourModelDecorator < Tramway::Core::ApplicationDecorator
97
112
  decorate_associations :messages, :posts
98
-
113
+
99
114
  class << self
100
115
  def collections
101
116
  [ :all, :scope1, :scope2 ]
102
117
  end
103
-
118
+
104
119
  def list_attributes
105
120
  [ :begin_date, :end_date ]
106
121
  end
107
-
122
+
108
123
  def show_attributes
109
124
  [ :begin_date, :end_date ]
110
125
  end
111
-
126
+
112
127
  def show_associations
113
128
  [ :messages ]
114
129
  end
115
-
130
+
116
131
  def list_filters
117
132
  {
118
133
  filter_name: {
@@ -131,7 +146,7 @@ class YourModelDecorator < Tramway::Core::ApplicationDecorator
131
146
  }
132
147
  end
133
148
  end
134
-
149
+
135
150
  delegate_attributes :title
136
151
  end
137
152
  ```
@@ -171,15 +186,7 @@ en:
171
186
  end_date Your end date filter
172
187
  ```
173
188
 
174
- #### 10. Add inheritance to YourModel
175
-
176
- *app/models/your_model.rb*
177
- ```ruby
178
- class YourModel < Tramway::Core::ApplicationRecord
179
- end
180
- ```
181
-
182
- #### 11. Create `Admin::YourModelForm`
189
+ #### 9b. Create `Admin::YourModelForm` [manual option]
183
190
 
184
191
  *app/forms/admin/your_model_form.rb
185
192
  ```ruby
@@ -192,13 +199,27 @@ class Admin::YourModelForm < Tramway::Core::ApplicationForm
192
199
  logo: :file,
193
200
  description: :ckeditor,
194
201
  date: :date_picker,
195
- text: :text
202
+ text: :text,
203
+ birth_date: {
204
+ type: :default,
205
+ input_options: {
206
+ hint: 'It should be more than 18'
207
+ }
208
+ }
196
209
  end
197
210
  end
198
211
  end
199
212
  ```
200
213
 
201
- ### 12. You can add search to your index page
214
+ #### 10. Add inheritance to YourModel
215
+
216
+ *app/models/your_model.rb*
217
+ ```ruby
218
+ class YourModel < Tramway::Core::ApplicationRecord
219
+ end
220
+ ```
221
+
222
+ ### 11. You can add search to your index page
202
223
 
203
224
  Tramway use gem [PgSearch](https://github.com/Casecommons/pg_search`) as search engine
204
225
 
@@ -446,8 +467,9 @@ en:
446
467
  my_dropdown: Very important dropdown
447
468
  ```
448
469
 
449
- ## Contributing
450
- Contribution directions go here.
470
+ ## Errors
471
+
472
+ * **Model or Form is not available** - `params[:model]` or `params[:form]` is empty **OR** current user does not have access to model or form in `params[:model]` or `params[:form]`
451
473
 
452
474
  ## License
453
475
  The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
@@ -21,7 +21,7 @@ module Tramway
21
21
  protected
22
22
 
23
23
  def check_available!
24
- raise 'Model or Form is not available' if !model_given? && !form_given?
24
+ raise 'Tramway::Admin - Model or Form is not available' if !model_given? && !form_given?
25
25
  end
26
26
 
27
27
  def check_available_scope!
@@ -92,7 +92,12 @@ module Tramway
92
92
  end
93
93
 
94
94
  def admin_form_class
95
- "::#{current_admin.role.camelize}::#{model_class}Form".constantize
95
+ class_name = "::#{current_admin.role.camelize}::#{model_class}Form"
96
+ if defined? class_name
97
+ class_name.constantize
98
+ else
99
+ raise "Tramway::Admin - you should create form for role `#{current_admin.role}` to edit #{model_class} model. It should be named #{class_name}"
100
+ end
96
101
  end
97
102
 
98
103
  def model_given?
@@ -0,0 +1,5 @@
1
+ class MultipleFileInput < SimpleForm::Inputs::FileInput
2
+ def input(wrapper_options)
3
+ super(wrapper_options.merge! multiple: true)
4
+ end
5
+ end
@@ -11,8 +11,8 @@
11
11
  %ul.navbar-nav
12
12
  - ::Tramway::Admin.navbar_items_for(@application_engine || @application.name, role: current_admin.role)&.each do |item|
13
13
  - case item.keys.first
14
- - when Class
15
- - model = item.keys.first
14
+ - when Class, String
15
+ - model = item.keys.first.is_a?(String) ? item.keys.first.constantize : item.keys.first
16
16
  - case item.values.first
17
17
  - when :singleton
18
18
  = model_menu_item model: model, route: ::Tramway::Admin::Engine.routes.url_helpers.singleton_path(model: model)
@@ -28,10 +28,13 @@
28
28
  - if sub_item.values.first == :singleton
29
29
  = dropdown_model_item model: model, route: ::Tramway::Admin::Engine.routes.url_helpers.singleton_path(model: model)
30
30
  - if sub_item.values.first == :record
31
- = dropdown_model_item model: model, route: ::Tramway::Admin::Engine.routes.url_helpers.records_path(model: model, scope: decorator_class(model).collections.first), pluralize: plural(model.model_name).capitalize
31
+ = dropdown_model_item model: model, route: ::Tramway::Admin::Engine.routes.url_helpers.records_path(model: model, scope: decorator_class(model).collections.first), pluralize: plural(model.constantize.model_name).capitalize
32
32
 
33
33
  %ul.nav.navbar-nav.ml-auto
34
34
  - if current_admin
35
+ %li.nav-item
36
+ %span.nav-link
37
+ = "#{current_admin.first_name} #{current_admin.last_name}"
35
38
  - if @notifications_count.present?
36
39
  - if @notifications_count > 0
37
40
  %li.nav-item.dropdown.notifications
@@ -10,6 +10,7 @@ require 'tramway/admin/notifications'
10
10
  require 'tramway/admin/welcome_page_actions'
11
11
  require 'tramway/admin/navbar'
12
12
  require 'tramway/error'
13
+ require 'tramway/admin/generators/install_generator'
13
14
 
14
15
  module Tramway
15
16
  Auth.layout_path = 'tramway/admin/application'
@@ -0,0 +1,20 @@
1
+ require 'rails/generators'
2
+ require 'tramway/admin/generators/model_generator'
3
+
4
+ module Tramway
5
+ module Admin
6
+ module Generators
7
+ class InstallGenerator < ::Rails::Generators::Base
8
+ source_root File.expand_path('templates', __dir__)
9
+ class_option :user_role, type: :string, default: 'admin'
10
+
11
+ def run_decorator_generators
12
+ project = Tramway::Core.application.name
13
+ ::Tramway::Admin.available_models_for(project).map do |model|
14
+ generate 'tramway:admin:model', model.to_s, "--user-role=#{options[:user_role]}"
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,109 @@
1
+ require 'rails/generators/named_base'
2
+
3
+ module Tramway
4
+ module Admin
5
+ module Generators
6
+ class ModelGenerator < ::Rails::Generators::NamedBase
7
+ source_root File.expand_path('templates', __dir__)
8
+ class_option :user_role, type: :string, default: 'admin'
9
+
10
+ COLLECTION_ATTRIBUTE_LIMIT = 4 # limiting columns in #index table
11
+ ATTRIBUTE_TYPE_MAPPING = {
12
+ date: :date_picker,
13
+ datetime: :date_picker,
14
+ time: :date_picker,
15
+ text: :text,
16
+ string: :string,
17
+ uuid: :string,
18
+ float: :float,
19
+ integer: :integer,
20
+ boolean: :boolean,
21
+ }
22
+ DEFAULT_FIELD_TYPE = :string
23
+ READ_ONLY_ATTRIBUTES = %w[id uuid created_at updated_at]
24
+
25
+ def run_decorator_generator
26
+ template(
27
+ 'decorator.rb.erb',
28
+ Rails.root.join("app/decorators/#{file_path}_decorator.rb"),
29
+ )
30
+ end
31
+
32
+ def run_forms_generator
33
+ template(
34
+ 'form.rb.erb',
35
+ Rails.root.join("app/forms/#{user_role}/#{file_path}_form.rb"),
36
+ )
37
+ end
38
+
39
+ private
40
+
41
+ def user_role
42
+ options[:user_role]
43
+ end
44
+
45
+ def attributes
46
+ # TODO: this for model associations, but they probably should be handled differently
47
+ # klass.reflections.keys +
48
+
49
+ klass.columns.map(&:name) -
50
+ redundant_attributes
51
+ end
52
+
53
+ def form_attributes
54
+ attributes - READ_ONLY_ATTRIBUTES
55
+ end
56
+
57
+ def form_type(attribute)
58
+ type = column_type_for_attribute(attribute.to_s)
59
+
60
+ if type
61
+ ATTRIBUTE_TYPE_MAPPING.fetch(type, DEFAULT_FIELD_TYPE)
62
+ # else
63
+ # association_type(attribute)
64
+ end
65
+ end
66
+
67
+ def redundant_attributes
68
+ klass.reflections.keys.flat_map do |relationship|
69
+ redundant_attributes_for(relationship)
70
+ end.compact
71
+ end
72
+
73
+ def redundant_attributes_for(relationship)
74
+ case association_type(relationship)
75
+ when :polymorphic
76
+ [relationship + '_id', relationship + '_type']
77
+ when :belongs_to
78
+ relationship + '_id'
79
+ end
80
+ end
81
+
82
+ def association_type(attribute)
83
+ relationship = klass.reflections[attribute.to_s]
84
+ if relationship.has_one?
85
+ :has_one
86
+ elsif relationship.collection?
87
+ :has_many
88
+ elsif relationship.polymorphic?
89
+ :polymorphic
90
+ else
91
+ :belongs_to
92
+ end
93
+ end
94
+
95
+ def column_type_for_attribute(attr)
96
+ column_types(attr)
97
+ end
98
+
99
+ def column_types(attr)
100
+ klass.columns.find { |column| column.name == attr }.try(:type)
101
+ end
102
+
103
+ def klass
104
+ @klass ||= Object.const_get(class_name)
105
+ end
106
+ end
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,52 @@
1
+ class <%= class_name %>Decorator < Tramway::Core::ApplicationDecorator
2
+ # Associations you want to show in admin dashboard
3
+ # decorate_associations :messages, :posts
4
+
5
+ class << self
6
+ def collections
7
+ # [ :all, :scope1, :scope2 ]
8
+ [ :all ]
9
+ end
10
+
11
+ def list_attributes
12
+ [
13
+ <% attributes.first(COLLECTION_ATTRIBUTE_LIMIT).each do |attr| -%>
14
+ :<%= attr %>,
15
+ <% end -%>
16
+ ]
17
+ end
18
+
19
+ def show_attributes
20
+ [
21
+ <% attributes.each do |attr| -%>
22
+ :<%= attr %>,
23
+ <% end -%>
24
+ ]
25
+ end
26
+
27
+ def show_associations
28
+ # Associations you want to show in admin dashboard
29
+ # [ :messages ]
30
+ end
31
+
32
+ def list_filters
33
+ # {
34
+ # filter_name: {
35
+ # type: :select,
36
+ # select_collection: filter_collection,
37
+ # query: lambda do |list, value|
38
+ # list.where some_attribute: value
39
+ # end
40
+ # },
41
+ # date_filter_name: {
42
+ # type: :dates,
43
+ # query: lambda do |list, begin_date, end_date|
44
+ # list.where 'created_at > ? AND created_at < ?', begin_date, end_date
45
+ # end
46
+ # }
47
+ # }
48
+ end
49
+ end
50
+
51
+ # delegate_attributes :title
52
+ end
@@ -0,0 +1,22 @@
1
+ class <%= user_role.capitalize %>::<%= class_name %>Form < Tramway::Core::ApplicationForm
2
+ properties <%= form_attributes.map{ |a| ":#{a}" }.join(', ') %>
3
+
4
+ def initialize(object)
5
+ super(object).tap do
6
+ # Here is the mapping from model attributes to simple_form inputs.
7
+ # form_properties title: :string,
8
+ # logo: :file,
9
+ # description: :ckeditor,
10
+ # games: :association,
11
+ # date: :date_picker,
12
+ # text: :text,
13
+ # birth_date: {
14
+ # type: :default,
15
+ # input_options: {
16
+ # hint: 'It should be more than 18'
17
+ # }
18
+ # }
19
+ form_properties <%= form_attributes.map{ |attr| "#{attr}: :#{form_type(attr)}"}.join(",\n ") %>
20
+ end
21
+ end
22
+ end
@@ -9,7 +9,7 @@ module Tramway::Admin::Navbar
9
9
  def navbar_items_for(project, role:)
10
10
  project = project.underscore.to_sym unless project.is_a? Symbol
11
11
  @navbar_structure[project]&.map do |item|
12
- if item.is_a? Class
12
+ if item.is_a?(Class) || item.is_a?(String)
13
13
  should_be_in_navbar_as item, project, role
14
14
  elsif item.is_a? Hash
15
15
  sub_items = item.values.first.map do |sub_item|
@@ -23,10 +23,10 @@ module Tramway::Admin::Navbar
23
23
  private
24
24
 
25
25
  def should_be_in_navbar_as(item, project, role)
26
- if singleton_models_for(project, role: role).include?(item)
27
- { item => :singleton }
28
- elsif available_models_for(project, role: role).include?(item)
29
- { item => :record }
26
+ if singleton_models_for(project, role: role).map(&:to_s).include?(item.to_s)
27
+ { item.to_s => :singleton }
28
+ elsif available_models_for(project, role: role).map(&:to_s).include?(item.to_s)
29
+ { item.to_s => :record }
30
30
  elsif item.is_a? Symbol
31
31
  :divider
32
32
  end
@@ -6,10 +6,10 @@ module Tramway::Admin::RecordsModels
6
6
  @available_models[project] ||= {}
7
7
  @available_models[project][role] ||= {}
8
8
  models.each do |model|
9
- if model.class == Class
10
- @available_models[project][role].merge! model => %i[index show update create destroy]
9
+ if model.class == Class || model.class == String
10
+ @available_models[project][role].merge! model.to_s => %i[index show update create destroy]
11
11
  elsif model.class == Hash
12
- @available_models[project][role].merge! model
12
+ @available_models[project][role].merge! model.to_s
13
13
  end
14
14
  end
15
15
  @available_models = @available_models.with_indifferent_access
@@ -32,7 +32,10 @@ module Tramway::Admin::RecordsModels
32
32
  end
33
33
  end.flatten.compact
34
34
  end
35
- models
35
+ # TODO: somehow cache results?
36
+ models.map do |model|
37
+ model.class == String ? model.constantize : model
38
+ end
36
39
  end
37
40
 
38
41
  def available_models(role:)
@@ -7,9 +7,9 @@ module Tramway::Admin::SingletonModels
7
7
  @singleton_models[project][role] ||= {}
8
8
  models.each do |model|
9
9
  if model.class == Class
10
- @singleton_models[project][role].merge! model => %i[index show update create destroy]
10
+ @singleton_models[project][role].merge! model.to_s => %i[index show update create destroy]
11
11
  elsif model.class == Hash
12
- @singleton_models[project][role].merge! model
12
+ @singleton_models[project][role].merge! model.to_s
13
13
  end
14
14
  end
15
15
  @singleton_models = @singleton_models.with_indifferent_access
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Tramway
4
4
  module Admin
5
- VERSION = '1.32.1.4'
5
+ VERSION = '1.32.2.5'
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tramway-admin
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.32.1.4
4
+ version: 1.32.2.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Pavel Kalashnikov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-12-01 00:00:00.000000000 Z
11
+ date: 2020-12-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: tramway-core
@@ -252,6 +252,7 @@ files:
252
252
  - app/helpers/tramway/admin/records_helper.rb
253
253
  - app/helpers/tramway/admin/russian_cases_helper.rb
254
254
  - app/helpers/tramway/admin/singleton_helper.rb
255
+ - app/inputs/multiple_file_input.rb
255
256
  - app/jobs/tramway/admin/application_job.rb
256
257
  - app/mailers/tramway/admin/application_mailer.rb
257
258
  - app/models/tramway/user/user.rb
@@ -290,6 +291,10 @@ files:
290
291
  - lib/tramway/admin/additional_buttons.rb
291
292
  - lib/tramway/admin/engine.rb
292
293
  - lib/tramway/admin/forms.rb
294
+ - lib/tramway/admin/generators/install_generator.rb
295
+ - lib/tramway/admin/generators/model_generator.rb
296
+ - lib/tramway/admin/generators/templates/decorator.rb.erb
297
+ - lib/tramway/admin/generators/templates/form.rb.erb
293
298
  - lib/tramway/admin/navbar.rb
294
299
  - lib/tramway/admin/notifications.rb
295
300
  - lib/tramway/admin/record_routes_helper.rb