tramway 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/MIT-LICENSE +20 -0
- data/README.md +889 -15
- data/Rakefile +8 -8
- data/app/assets/config/tramway_core_manifest.js +2 -0
- data/app/assets/images/tramway/mona_lisa_from_prado.jpg +0 -0
- data/app/assets/images/tramway/mona_lisa_from_prado_square.jpg +0 -0
- data/app/assets/javascripts/bootstrap-datepicker-1.8.0.js +2035 -0
- data/app/assets/javascripts/bootstrap-datepicker-1.8.0.ru.min.js +64 -0
- data/app/assets/javascripts/ckeditor/config.js +30 -0
- data/app/assets/javascripts/ckeditor/plugins/image/dialogs/image.js +1259 -0
- data/app/assets/javascripts/ckeditor/plugins/image/icons/hidpi/image.png +0 -0
- data/app/assets/javascripts/ckeditor/plugins/image/icons/image.png +0 -0
- data/app/assets/javascripts/ckeditor/plugins/image/images/noimage.png +0 -0
- data/app/assets/javascripts/ckeditor/plugins/image/lang/en.js +25 -0
- data/app/assets/javascripts/ckeditor/plugins/image/lang/ru.js +25 -0
- data/app/assets/javascripts/ckeditor/plugins/image/plugin.js +184 -0
- data/app/assets/javascripts/ckeditor/plugins/youtube/images/icon-hdpi.png +0 -0
- data/app/assets/javascripts/ckeditor/plugins/youtube/images/icon.png +0 -0
- data/app/assets/javascripts/ckeditor/plugins/youtube/lang/en.js +25 -0
- data/app/assets/javascripts/ckeditor/plugins/youtube/lang/ru.js +25 -0
- data/app/assets/javascripts/ckeditor/plugins/youtube/plugin.js +449 -0
- data/app/assets/javascripts/tramway/application.js +60 -0
- data/app/assets/stylesheets/tramway/application.sass +60 -0
- data/app/assets/stylesheets/tramway/bootstrap-datepicker-1.8.0.css +477 -0
- data/app/controllers/concerns/auth_management.rb +26 -0
- data/app/controllers/concerns/filtering.rb +43 -0
- data/app/controllers/tramway/application_controller.rb +142 -0
- data/app/controllers/tramway/export/application_controller.rb +5 -0
- data/app/controllers/tramway/has_and_belongs_to_many_records_controller.rb +26 -0
- data/app/controllers/tramway/records_controller.rb +86 -0
- data/app/controllers/tramway/sessions_controller.rb +49 -0
- data/app/controllers/tramway/singletons_controller.rb +48 -0
- data/app/controllers/tramway/welcome_controller.rb +17 -0
- data/app/decorators/tramway/application_decorated_collection.rb +15 -0
- data/app/decorators/tramway/application_decorator.rb +124 -0
- data/app/decorators/tramway/associations/class_helper.rb +45 -0
- data/app/decorators/tramway/associations/object_helper.rb +58 -0
- data/app/decorators/tramway/attributes/view_helper.rb +30 -0
- data/app/decorators/tramway/concerns/attributes_decorator_helper.rb +97 -0
- data/app/decorators/tramway/concerns/table_builder.rb +33 -0
- data/app/decorators/tramway/default/values_helper.rb +23 -0
- data/app/decorators/tramway/delegating/class_helper.rb +9 -0
- data/app/decorators/tramway/user_decorator.rb +49 -0
- data/app/forms/admin/tramway/user_form.rb +24 -0
- data/app/forms/tramway/application_form.rb +124 -0
- data/app/forms/tramway/application_forms/association_class_helpers.rb +7 -0
- data/app/forms/tramway/application_forms/association_object_helpers.rb +36 -0
- data/app/forms/tramway/application_forms/constant_class_actions.rb +7 -0
- data/app/forms/tramway/application_forms/constant_object_actions.rb +20 -0
- data/app/forms/tramway/application_forms/frontend.rb +12 -0
- data/app/forms/tramway/application_forms/object_helpers.rb +15 -0
- data/app/forms/tramway/application_forms/properties_object_helper.rb +16 -0
- data/app/forms/tramway/application_forms/submit_helper.rb +26 -0
- data/app/forms/tramway/extendable_form.rb +15 -0
- data/app/forms/tramway/extendable_forms_helpers/class_builder.rb +34 -0
- data/app/forms/tramway/extendable_forms_helpers/ignored_properties_helper.rb +11 -0
- data/app/forms/tramway/extendable_forms_helpers/more_properties_helper.rb +31 -0
- data/app/forms/tramway/extendable_forms_helpers/properties_helper.rb +16 -0
- data/app/forms/tramway/extendable_forms_helpers/submit/class_helpers.rb +18 -0
- data/app/forms/tramway/extendable_forms_helpers/submit/object_helpers.rb +21 -0
- data/app/forms/tramway/extendable_forms_helpers/validators.rb +40 -0
- data/app/forms/tramway/extended_application_form.rb +23 -0
- data/app/forms/tramway/form_creator.rb +7 -0
- data/app/forms/tramway/session_form.rb +26 -0
- data/app/helpers/tramway/actions_helper.rb +45 -0
- data/app/helpers/tramway/additional_buttons_builder.rb +12 -0
- data/app/helpers/tramway/application_helper.rb +27 -0
- data/app/helpers/tramway/cases_helper.rb +13 -0
- data/app/helpers/tramway/copy_to_clipboard_helper.rb +11 -0
- data/app/helpers/tramway/focus_generator_helper.rb +10 -0
- data/app/helpers/tramway/frontend_helper.rb +26 -0
- data/app/helpers/tramway/inputs/associations_helper.rb +30 -0
- data/app/helpers/tramway/inputs/polymorphic_associations_helper.rb +24 -0
- data/app/helpers/tramway/inputs_helper.rb +96 -0
- data/app/helpers/tramway/model_helper.rb +7 -0
- data/app/helpers/tramway/navbar_helper.rb +11 -0
- data/app/helpers/tramway/records_helper.rb +120 -0
- data/app/helpers/tramway/russian_cases_helper.rb +26 -0
- data/app/helpers/tramway/singleton_helper.rb +12 -0
- data/app/helpers/tramway/state_machine_buttons_helper.rb +61 -0
- data/app/helpers/tramway/title_helper.rb +25 -0
- data/app/inputs/date_picker_input.rb +4 -0
- data/app/inputs/multiple_file_input.rb +7 -0
- data/app/models/tramway/application_record.rb +60 -0
- data/app/models/tramway/user.rb +23 -0
- data/app/uploaders/application_uploader.rb +22 -0
- data/app/uploaders/file_uploader.rb +4 -0
- data/app/uploaders/ico_uploader.rb +7 -0
- data/app/uploaders/image_defaults.rb +14 -0
- data/app/uploaders/photo_uploader.rb +54 -0
- data/app/views/layouts/tramway/application.html.haml +32 -0
- data/app/views/layouts/tramway/shared/_navbar.html.haml +46 -0
- data/app/views/tramway/404.haml +1 -0
- data/app/views/tramway/records/_form.html.haml +22 -0
- data/app/views/tramway/records/_list.html.haml +38 -0
- data/app/views/tramway/records/_search.html.haml +34 -0
- data/app/views/tramway/records/edit.html.haml +1 -0
- data/app/views/tramway/records/index.html.haml +31 -0
- data/app/views/tramway/records/new.html.haml +1 -0
- data/app/views/tramway/records/show.html.haml +1 -0
- data/app/views/tramway/sessions/new.html.haml +9 -0
- data/app/views/tramway/shared/_input.html.haml +34 -0
- data/app/views/tramway/shared/_input_extended.html.haml +14 -0
- data/app/views/tramway/shared/_messages.html.haml +10 -0
- data/app/views/tramway/shared/_show.html.haml +35 -0
- data/app/views/tramway/shared/errors/server_error.html.haml +12 -0
- data/app/views/tramway/shared/input_extended_types/_checkbox.html.haml +1 -0
- data/app/views/tramway/shared/input_extended_types/_select.html.haml +16 -0
- data/app/views/tramway/shared/input_extended_types/_simple.html.haml +4 -0
- data/app/views/tramway/shared/input_extended_types/_yes_no.html.haml +4 -0
- data/app/views/tramway/shared/show/_attribute_tr.html.haml +9 -0
- data/app/views/tramway/shared/show/associations/_habtm_row.html.haml +14 -0
- data/app/views/tramway/shared/show/associations/_list.html.haml +21 -0
- data/app/views/tramway/shared/show/associations/_row.html.haml +19 -0
- data/app/views/tramway/shared/show/associations/_table_row.html.haml +21 -0
- data/app/views/tramway/singletons/_form.html.haml +15 -0
- data/app/views/tramway/singletons/edit.html.haml +1 -0
- data/app/views/tramway/singletons/new.html.haml +1 -0
- data/app/views/tramway/singletons/show.html.haml +1 -0
- data/app/views/tramway/welcome/index.html.haml +4 -0
- data/config/initializers/assets.rb +7 -0
- data/config/initializers/carrierwave.rb +5 -0
- data/config/initializers/ckeditor.rb +9 -0
- data/config/initializers/plurals.rb +25 -0
- data/config/locales/en/collections.yml +4 -0
- data/config/locales/en/date.yml +16 -0
- data/config/locales/en/dates.yml +10 -0
- data/config/locales/en/helpers.yml +26 -0
- data/config/locales/en/locale.yml +11 -0
- data/config/locales/en/messages.yml +7 -0
- data/config/locales/en/models.yml +9 -0
- data/config/locales/en/simple_form_extension.yml +8 -0
- data/config/locales/en/state_machines.yml +8 -0
- data/config/locales/ru/collections.yml +4 -0
- data/config/locales/ru/date.yml +16 -0
- data/config/locales/ru/dates.yml +10 -0
- data/config/locales/ru/helpers.yml +30 -0
- data/config/locales/ru/locale.yml +6 -0
- data/config/locales/ru/messages.yml +7 -0
- data/config/locales/ru/models.yml +21 -0
- data/config/locales/ru/simple_form_extension.yml +8 -0
- data/config/locales/ru/state_machines.yml +8 -0
- data/config/routes.rb +13 -0
- data/lib/string.rb +18 -0
- data/lib/tramway/application.rb +10 -0
- data/lib/tramway/class_name_helpers.rb +15 -0
- data/lib/tramway/collection.rb +9 -0
- data/lib/tramway/collections/helper.rb +21 -0
- data/lib/tramway/collections.rb +4 -0
- data/lib/tramway/engine.rb +14 -0
- data/lib/tramway/error.rb +32 -0
- data/lib/tramway/forms.rb +5 -0
- data/lib/tramway/generators/install_generator.rb +49 -0
- data/lib/tramway/generators/model_generator.rb +105 -0
- data/lib/tramway/generators/templates/create_tramway_users.rb +18 -0
- data/lib/tramway/generators/templates/decorator.rb.erb +56 -0
- data/lib/tramway/generators/templates/form.rb.erb +22 -0
- data/lib/tramway/generators/templates/initializers/simple_form.rb +23 -0
- data/lib/tramway/generators/templates/initializers/simple_form_bootstrap.rb +133 -0
- data/lib/tramway/generators.rb +4 -0
- data/lib/tramway/navbar.rb +44 -0
- data/lib/tramway/notifications.rb +12 -0
- data/lib/tramway/record_routes_helper.rb +23 -0
- data/lib/tramway/records_models.rb +52 -0
- data/lib/tramway/singleton_models.rb +32 -0
- data/lib/tramway/spec/helpers/navbar_helper.rb +7 -0
- data/lib/tramway/spec/helpers/tramway_helpers.rb +47 -0
- data/lib/tramway/version.rb +3 -1
- data/lib/tramway/welcome_page_actions.rb +5 -0
- data/lib/tramway/yaml/errors.yml +49 -0
- data/lib/tramway.rb +143 -2
- data/lib/validators/presence_validator.rb +9 -0
- metadata +582 -25
- data/.gitignore +0 -9
- data/.travis.yml +0 -5
- data/Gemfile +0 -6
- data/bin/console +0 -14
- data/bin/setup +0 -8
- data/tramway.gemspec +0 -26
@@ -0,0 +1,133 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
SimpleForm.setup do |config|
|
4
|
+
config.error_notification_class = 'alert alert-danger'
|
5
|
+
config.button_class = 'btn btn-default'
|
6
|
+
config.boolean_label_class = nil
|
7
|
+
|
8
|
+
config.wrappers :vertical_form, tag: 'div', class: 'form-group', error_class: 'has-error' do |b|
|
9
|
+
b.use :html5
|
10
|
+
b.use :placeholder
|
11
|
+
b.optional :maxlength
|
12
|
+
b.optional :pattern
|
13
|
+
b.optional :min_max
|
14
|
+
b.optional :readonly
|
15
|
+
b.use :label, class: 'control-label'
|
16
|
+
|
17
|
+
b.use :input, class: 'form-control'
|
18
|
+
b.use :error, wrap_with: { tag: 'span', class: 'help-block' }
|
19
|
+
b.use :hint, wrap_with: { tag: 'p', class: 'help-block' }
|
20
|
+
end
|
21
|
+
|
22
|
+
config.wrappers :vertical_file_input, tag: 'div', class: 'form-group', error_class: 'has-error' do |b|
|
23
|
+
b.use :html5
|
24
|
+
b.use :placeholder
|
25
|
+
b.optional :maxlength
|
26
|
+
b.optional :readonly
|
27
|
+
b.use :label, class: 'control-label'
|
28
|
+
|
29
|
+
b.use :input
|
30
|
+
b.use :error, wrap_with: { tag: 'span', class: 'help-block' }
|
31
|
+
b.use :hint, wrap_with: { tag: 'p', class: 'help-block' }
|
32
|
+
end
|
33
|
+
|
34
|
+
config.wrappers :vertical_boolean, tag: 'div', class: 'form-group', error_class: 'has-error' do |b|
|
35
|
+
b.use :html5
|
36
|
+
b.optional :readonly
|
37
|
+
|
38
|
+
b.wrapper tag: 'div', class: 'checkbox' do |ba|
|
39
|
+
ba.use :label_input
|
40
|
+
end
|
41
|
+
|
42
|
+
b.use :error, wrap_with: { tag: 'span', class: 'help-block' }
|
43
|
+
b.use :hint, wrap_with: { tag: 'p', class: 'help-block' }
|
44
|
+
end
|
45
|
+
|
46
|
+
config.wrappers :vertical_radio_and_checkboxes, tag: 'div', class: 'form-group', error_class: 'has-error' do |b|
|
47
|
+
b.use :html5
|
48
|
+
b.optional :readonly
|
49
|
+
b.use :label, class: 'control-label'
|
50
|
+
b.use :input
|
51
|
+
b.use :error, wrap_with: { tag: 'span', class: 'help-block' }
|
52
|
+
b.use :hint, wrap_with: { tag: 'p', class: 'help-block' }
|
53
|
+
end
|
54
|
+
|
55
|
+
config.wrappers :horizontal_form, tag: 'div', class: 'form-group', error_class: 'has-error' do |b|
|
56
|
+
b.use :html5
|
57
|
+
b.use :placeholder
|
58
|
+
b.optional :maxlength
|
59
|
+
b.optional :pattern
|
60
|
+
b.optional :min_max
|
61
|
+
b.optional :readonly
|
62
|
+
b.use :label, class: 'col-sm-3 control-label'
|
63
|
+
|
64
|
+
b.wrapper tag: 'div', class: 'col-sm-9' do |ba|
|
65
|
+
ba.use :input, class: 'form-control'
|
66
|
+
ba.use :error, wrap_with: { tag: 'span', class: 'help-block' }
|
67
|
+
ba.use :hint, wrap_with: { tag: 'p', class: 'help-block' }
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
config.wrappers :horizontal_file_input, tag: 'div', class: 'form-group', error_class: 'has-error' do |b|
|
72
|
+
b.use :html5
|
73
|
+
b.use :placeholder
|
74
|
+
b.optional :maxlength
|
75
|
+
b.optional :readonly
|
76
|
+
b.use :label, class: 'col-sm-3 control-label'
|
77
|
+
|
78
|
+
b.wrapper tag: 'div', class: 'col-sm-9' do |ba|
|
79
|
+
ba.use :input
|
80
|
+
ba.use :error, wrap_with: { tag: 'span', class: 'help-block' }
|
81
|
+
ba.use :hint, wrap_with: { tag: 'p', class: 'help-block' }
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
config.wrappers :horizontal_boolean, tag: 'div', class: 'form-group', error_class: 'has-error' do |b|
|
86
|
+
b.use :html5
|
87
|
+
b.optional :readonly
|
88
|
+
|
89
|
+
b.wrapper tag: 'div', class: 'col-sm-offset-3 col-sm-9' do |wr|
|
90
|
+
wr.wrapper tag: 'div', class: 'checkbox' do |ba|
|
91
|
+
ba.use :label_input, class: 'col-sm-9'
|
92
|
+
end
|
93
|
+
|
94
|
+
wr.use :error, wrap_with: { tag: 'span', class: 'help-block' }
|
95
|
+
wr.use :hint, wrap_with: { tag: 'p', class: 'help-block' }
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
config.wrappers :horizontal_radio_and_checkboxes, tag: 'div', class: 'form-group', error_class: 'has-error' do |b|
|
100
|
+
b.use :html5
|
101
|
+
b.optional :readonly
|
102
|
+
|
103
|
+
b.use :label, class: 'col-sm-3 control-label'
|
104
|
+
|
105
|
+
b.wrapper tag: 'div', class: 'col-sm-9' do |ba|
|
106
|
+
ba.use :input
|
107
|
+
ba.use :error, wrap_with: { tag: 'span', class: 'help-block' }
|
108
|
+
ba.use :hint, wrap_with: { tag: 'p', class: 'help-block' }
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
config.wrappers :inline_form, tag: 'div', class: 'form-group', error_class: 'has-error' do |b|
|
113
|
+
b.use :html5
|
114
|
+
b.use :placeholder
|
115
|
+
b.optional :maxlength
|
116
|
+
b.optional :pattern
|
117
|
+
b.optional :min_max
|
118
|
+
b.optional :readonly
|
119
|
+
b.use :label, class: 'sr-only'
|
120
|
+
|
121
|
+
b.use :input, class: 'form-control'
|
122
|
+
b.use :error, wrap_with: { tag: 'span', class: 'help-block' }
|
123
|
+
b.use :hint, wrap_with: { tag: 'p', class: 'help-block' }
|
124
|
+
end
|
125
|
+
|
126
|
+
config.default_wrapper = :vertical_form
|
127
|
+
config.wrapper_mappings = {
|
128
|
+
check_boxes: :vertical_radio_and_checkboxes,
|
129
|
+
radio_buttons: :vertical_radio_and_checkboxes,
|
130
|
+
file: :vertical_file_input,
|
131
|
+
boolean: :vertical_boolean
|
132
|
+
}
|
133
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Tramway::Navbar
|
4
|
+
def navbar_structure(*links, project:)
|
5
|
+
@navbar_structure ||= {}
|
6
|
+
@navbar_structure.merge! project => links
|
7
|
+
end
|
8
|
+
|
9
|
+
def navbar_items_for(project, role:)
|
10
|
+
project = project.underscore.to_sym unless project.is_a? Symbol
|
11
|
+
|
12
|
+
return [] unless @navbar_structure&.dig(project).present?
|
13
|
+
|
14
|
+
@navbar_structure[project].map { |item| add_to_navbar item, project, role }.compact || []
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def should_be_in_navbar_as(item, project, role)
|
20
|
+
if singleton_models_for(project, role: role).map(&:to_s).include?(item.to_s)
|
21
|
+
{ item.to_s => :singleton }
|
22
|
+
elsif available_models_for(project, role: role).map(&:to_s).include?(item.to_s)
|
23
|
+
{ item.to_s => :record }
|
24
|
+
elsif item.is_a? Symbol
|
25
|
+
:divider
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def parse_hash_options_to_navbar(item, project, role)
|
30
|
+
sub_items = item.values.first.map do |sub_item|
|
31
|
+
should_be_in_navbar_as sub_item, project, role
|
32
|
+
end.compact
|
33
|
+
{ item.keys.first => sub_items } if sub_items.any?
|
34
|
+
end
|
35
|
+
|
36
|
+
def add_to_navbar(item, project, role)
|
37
|
+
case item
|
38
|
+
when Class, String
|
39
|
+
should_be_in_navbar_as item, project, role
|
40
|
+
when Hash
|
41
|
+
parse_hash_options_to_navbar item, project, role
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Tramway::RecordRoutesHelper
|
4
|
+
def record_path(*args, **options)
|
5
|
+
options[:model] ||= params[:model]
|
6
|
+
super args, options
|
7
|
+
end
|
8
|
+
|
9
|
+
def edit_record_path(*args, **options)
|
10
|
+
options[:model] ||= params[:model]
|
11
|
+
super args, options
|
12
|
+
end
|
13
|
+
|
14
|
+
def new_record_path(*args, **options)
|
15
|
+
options[:model] ||= params[:model]
|
16
|
+
super args, options
|
17
|
+
end
|
18
|
+
|
19
|
+
def records_path(*args, **options)
|
20
|
+
options[:model] ||= params[:model]
|
21
|
+
super args, options
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Tramway::RecordsModels
|
4
|
+
def set_available_models(*models, project:, role: :admin)
|
5
|
+
initialize_available_models_for project, role
|
6
|
+
|
7
|
+
models.each do |model|
|
8
|
+
if model.instance_of?(Class) || model.instance_of?(String)
|
9
|
+
@available_models[project][role].merge! model.to_s => %i[index show update create destroy]
|
10
|
+
elsif model.instance_of?(Hash)
|
11
|
+
@available_models[project][role].merge! model
|
12
|
+
end
|
13
|
+
end
|
14
|
+
@available_models = @available_models.with_indifferent_access
|
15
|
+
end
|
16
|
+
|
17
|
+
def available_models_for(project, role: :admin)
|
18
|
+
project = project.underscore.to_sym unless project.is_a? Symbol
|
19
|
+
models = get_models_by_key(@available_models, project, role)
|
20
|
+
models = available_models_for_engine(project, role, models) if project_is_engine?(project)
|
21
|
+
|
22
|
+
models.map do |model|
|
23
|
+
model.instance_of?(String) ? model.constantize : model
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def available_models(role:)
|
28
|
+
models_array models_type: :available, role: role
|
29
|
+
end
|
30
|
+
|
31
|
+
def clear_available_models!
|
32
|
+
@available_models = {}
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def initialize_available_models_for(project, role)
|
38
|
+
@available_models ||= {}
|
39
|
+
@available_models[project] ||= {}
|
40
|
+
@available_models[project][role] ||= {}
|
41
|
+
end
|
42
|
+
|
43
|
+
def available_models_for_engine(project, role, models)
|
44
|
+
models + engine_class(project).dependencies.map do |dependency|
|
45
|
+
if @available_models&.dig(dependency, role).present?
|
46
|
+
@available_models&.dig(dependency, role)&.keys
|
47
|
+
else
|
48
|
+
Tramway::Error.raise_error :records, :there_is_no_dependency, dependency: dependency, project: project
|
49
|
+
end
|
50
|
+
end.flatten.compact
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Tramway::SingletonModels
|
4
|
+
def set_singleton_models(*models, project:, role: :admin)
|
5
|
+
@singleton_models ||= {}
|
6
|
+
@singleton_models[project] ||= {}
|
7
|
+
@singleton_models[project][role] ||= {}
|
8
|
+
models.each do |model|
|
9
|
+
if model.instance_of?(Class)
|
10
|
+
@singleton_models[project][role].merge! model.to_s => %i[index show update create destroy]
|
11
|
+
elsif model.instance_of?(Hash)
|
12
|
+
@singleton_models[project][role].merge! model.to_s
|
13
|
+
end
|
14
|
+
end
|
15
|
+
@singleton_models = @singleton_models.with_indifferent_access
|
16
|
+
end
|
17
|
+
|
18
|
+
def singleton_models_for(project, role: :admin)
|
19
|
+
project = project.underscore.to_sym unless project.is_a? Symbol
|
20
|
+
models = get_models_by_key(@singleton_models, project, role)
|
21
|
+
if project_is_engine?(project)
|
22
|
+
models += engine_class(project).dependencies.map do |dependency|
|
23
|
+
@singleton_models&.dig(dependency, role)&.keys
|
24
|
+
end.flatten.compact
|
25
|
+
end
|
26
|
+
models
|
27
|
+
end
|
28
|
+
|
29
|
+
def singleton_models(role:)
|
30
|
+
models_array models_type: :singleton, role: role
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module TramwayHelpers
|
4
|
+
def click_on_association_delete_button(object)
|
5
|
+
delete_path = ::Tramway::Engine.routes.url_helpers.record_path(
|
6
|
+
object.id,
|
7
|
+
model: object.class
|
8
|
+
)
|
9
|
+
row = find("td[colspan='2'] td a[href='#{delete_path}']").parent_node(level: 2)
|
10
|
+
row.find('td button.delete[type="submit"]').click
|
11
|
+
end
|
12
|
+
|
13
|
+
def click_on_tab(text)
|
14
|
+
find('li.nav-item a.nav-link', text: text).click
|
15
|
+
end
|
16
|
+
|
17
|
+
def click_on_table_item(text)
|
18
|
+
find('table td a', text: text).click
|
19
|
+
end
|
20
|
+
|
21
|
+
def click_on_delete_button(object)
|
22
|
+
delete_path = ::Tramway::Engine.routes.url_helpers.record_path(
|
23
|
+
object.id,
|
24
|
+
model: object.class
|
25
|
+
)
|
26
|
+
form = find("form[action='#{delete_path}']")
|
27
|
+
form.find('button[type="submit"]').click
|
28
|
+
end
|
29
|
+
|
30
|
+
def fill_in_ckeditor(name, with:)
|
31
|
+
id = name.gsub(']', '').split('[').join('_')
|
32
|
+
content = with.to_json # convert to a safe javascript string
|
33
|
+
page.execute_script <<-SCRIPT
|
34
|
+
CKEDITOR.instances['#{id}'].setData(#{content});
|
35
|
+
$('textarea##{id}').text(#{content});
|
36
|
+
SCRIPT
|
37
|
+
end
|
38
|
+
|
39
|
+
def fill_in_datepicker(name, with:)
|
40
|
+
return unless with.present?
|
41
|
+
|
42
|
+
input = find("input[name=#{name.gsub('[', '\[').gsub(']', '\]')}]")
|
43
|
+
input.click
|
44
|
+
|
45
|
+
find('td.day', text: /^#{with.day}$/, match: :first).click
|
46
|
+
end
|
47
|
+
end
|
data/lib/tramway/version.rb
CHANGED
@@ -0,0 +1,49 @@
|
|
1
|
+
tramway:
|
2
|
+
project:
|
3
|
+
no_instance_of_application_class: "Looks like you have not create at least one instance of %{application_class} model OR Tramway Application Model is nil"
|
4
|
+
collections:
|
5
|
+
helper:
|
6
|
+
collection_list_by:
|
7
|
+
there_no_such_collection: "There no such collection named %{name_camelize}. Please create class with self method `list` and extended of `Tramway::Collection`. You should reload your server after creating this collection."
|
8
|
+
input_helper:
|
9
|
+
association_params:
|
10
|
+
defined_with_property_method: "It seems you've defined association attributes with `property` method. Please, use `association` method. `association :%{property}`"
|
11
|
+
use_polymorphic_association: "It seems you've used `association` input type in the Form. Please, use `polymorphic_association` type. `%{property}: :polymorphic_association`"
|
12
|
+
title_helper:
|
13
|
+
title:
|
14
|
+
you_should_set_tramway_application: "You should set Tramway::Core::Application class using `::Tramway::Core.initialize_application model_class: #{model_class_name}` in config/initializers/tramway.rb OR maybe you don't have any records of application model"
|
15
|
+
application_form:
|
16
|
+
initialize:
|
17
|
+
polymorphic_class_is_nil: "Polymorphic association class is nil. Maybe, you should write `assocation #{association_name}` after `properties #{association_name}_id, #{association_name}_type`"
|
18
|
+
validates:
|
19
|
+
you_need_to_set_model_class: 'You need to set `model_class` name while using validations. Just write `self.model_class = YOUR_MODEL_NAME` in the class area.'
|
20
|
+
submit:
|
21
|
+
params_should_not_be_nil: "ApplicationForm::Params should not be nil"
|
22
|
+
save:
|
23
|
+
looks_like_you_have_method: "Looks like you have method `%{method_name}` in %{model_class}. You should rename it or rename property in %{class_name}"
|
24
|
+
argument_error: "We have ArgumentError with message: %{message}"
|
25
|
+
model_class:
|
26
|
+
there_is_not_model_class: "There is not model class name for %{name}. Should be %{model_class_name} or you can use another class to initialize form object or just initialize form with object."
|
27
|
+
concerns:
|
28
|
+
attribute_decorator_helper:
|
29
|
+
you_should_mount_photo_uploader: "You should mount PhotoUploader to your model. Just add `mount_uploader %{attribute_name}, PhotoUploader` to your model. %{message}"
|
30
|
+
associations:
|
31
|
+
object_helper:
|
32
|
+
please_specify_association_name: "Please, specify `%{association_name}` association class_name in %{object_class} model. For example: `has_many :%{association_name}, class_name: '%{association_class_name}'`"
|
33
|
+
habtm_add_class_not_defined: "You should define class `%{class}` to be able add and remove `%{association_name}`"
|
34
|
+
class_helper:
|
35
|
+
model_does_not_have_association: "Model %{object_class} does not have association named `%{association_name}`"
|
36
|
+
application_decorator:
|
37
|
+
attributes:
|
38
|
+
method_is_reserved_word: "Method `%{attribute_name}` is reserved word. Please, create or delegate method in %{class_name} with another name."
|
39
|
+
title:
|
40
|
+
please_implement_title: "Please, implement `title` method in a %{class_name} or delegate it to %{object_class}"
|
41
|
+
link:
|
42
|
+
method_link_uses_file_attribute: "Method `link` uses `file` attribute of the decorated object. If decorated object doesn't contain `file`, you shouldn't use `link` method."
|
43
|
+
generators:
|
44
|
+
install: 'Initialize Tramway application before running generators. Add `Tramway.initialize_application name: :your_application_name` to `config/initializers/tramway.rb`'
|
45
|
+
records:
|
46
|
+
there_is_no_dependency: "There is no dependency `%{dependency}` for plugin: %{project}. Please, check file `tramway-%{project}/lib/tramway/%{project}/%{project}.rb`"
|
47
|
+
application_controller:
|
48
|
+
create_form_for_role: "Tramway - you should create form for role `%{role}` to edit %{model_class} model. It should be named %{class_name}"
|
49
|
+
model_or_form_not_available: 'Tramway - Model or Form is not available. Looks like current user does not have access to change this model. Update your tramway initializer file'
|
data/lib/tramway.rb
CHANGED
@@ -1,5 +1,146 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'tramway/engine'
|
4
|
+
require 'tramway/collection'
|
5
|
+
require 'tramway/collections/helper'
|
6
|
+
require 'font_awesome5_rails'
|
7
|
+
require 'pg_search'
|
8
|
+
require 'validators/presence_validator'
|
9
|
+
require 'tramway/singleton_models'
|
10
|
+
require 'tramway/records_models'
|
11
|
+
require 'tramway/forms'
|
12
|
+
require 'tramway/notifications'
|
13
|
+
require 'tramway/welcome_page_actions'
|
14
|
+
require 'tramway/navbar'
|
15
|
+
require 'tramway/error'
|
16
|
+
require 'tramway/generators/install_generator'
|
17
|
+
require 'tramway/class_name_helpers'
|
2
18
|
|
3
19
|
module Tramway
|
4
|
-
|
20
|
+
class << self
|
21
|
+
def initialize_application(**options)
|
22
|
+
@application ||= Tramway::Application.new
|
23
|
+
|
24
|
+
options.each { |attr, value| @application.send "#{attr}=", value }
|
25
|
+
end
|
26
|
+
|
27
|
+
def application_object
|
28
|
+
@application&.model_class.present? ? @application.model_class.first : @application
|
29
|
+
end
|
30
|
+
|
31
|
+
def root
|
32
|
+
File.dirname __dir__
|
33
|
+
end
|
34
|
+
|
35
|
+
attr_reader :application, :customized_admin_navbar
|
36
|
+
|
37
|
+
include Tramway::RecordsModels
|
38
|
+
include Tramway::SingletonModels
|
39
|
+
include Tramway::Forms
|
40
|
+
include Tramway::Notifications
|
41
|
+
include Tramway::WelcomePageActions
|
42
|
+
include Tramway::Navbar
|
43
|
+
|
44
|
+
def engine_class(project)
|
45
|
+
class_name = "Tramway::#{project.to_s.camelize}"
|
46
|
+
class_name.classify.safe_constantize
|
47
|
+
end
|
48
|
+
|
49
|
+
def project_is_engine?(project)
|
50
|
+
engine_class(project)
|
51
|
+
end
|
52
|
+
|
53
|
+
def get_models_by_key(checked_models, project, role)
|
54
|
+
unless project.present?
|
55
|
+
Tramway::Error.raise_error(
|
56
|
+
:tramway,
|
57
|
+
:project,
|
58
|
+
:no_instance_of_application_class,
|
59
|
+
application_class: Tramway.application.model_class
|
60
|
+
)
|
61
|
+
end
|
62
|
+
|
63
|
+
checked_models && checked_models[project]&.dig(role)&.keys || []
|
64
|
+
end
|
65
|
+
|
66
|
+
def models_array(models_type:, role:)
|
67
|
+
instance_variable_get("@#{models_type}_models")&.map { |projects| projects.last[role]&.keys }&.flatten || []
|
68
|
+
end
|
69
|
+
|
70
|
+
def action_is_available?(record, project:, role:, model_name:, action:)
|
71
|
+
project = project.underscore.to_sym unless project.is_a? Symbol
|
72
|
+
actions = select_actions(project: project, role: role.to_sym, model_name: model_name)
|
73
|
+
availability = compute_availability actions, action
|
74
|
+
|
75
|
+
return false unless availability.present?
|
76
|
+
return true if availability.is_a? Symbol
|
77
|
+
|
78
|
+
availability.call record
|
79
|
+
end
|
80
|
+
|
81
|
+
def compute_availability(actions, action)
|
82
|
+
case actions
|
83
|
+
when Array
|
84
|
+
actions.select { |a| a.to_sym == action.to_sym }.first
|
85
|
+
when Hash
|
86
|
+
actions[action.to_sym]
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def select_actions(project:, role:, model_name:)
|
91
|
+
stringify = ->(models) { stringify_keys(models&.dig(project, role))&.dig(model_name) }
|
92
|
+
stringify.call(@singleton_models) || stringify.call(@available_models)
|
93
|
+
end
|
94
|
+
|
95
|
+
def stringify_keys(hash)
|
96
|
+
hash&.reduce({}) { |new_hash, pair| new_hash.merge! pair[0].to_s => pair[1] }
|
97
|
+
end
|
98
|
+
|
99
|
+
def admin_model
|
100
|
+
auth_config.first[:user_model]
|
101
|
+
end
|
102
|
+
|
103
|
+
def auth_config
|
104
|
+
@@auth_config ||= [{ user_model: Tramway::User, auth_attributes: :email }]
|
105
|
+
@@auth_config
|
106
|
+
end
|
107
|
+
|
108
|
+
def auth_config=(params)
|
109
|
+
case params
|
110
|
+
when Hash
|
111
|
+
@@auth_config = [params]
|
112
|
+
when Array
|
113
|
+
@@auth_config = params
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
def user_based_models
|
118
|
+
@@auth_config ||= []
|
119
|
+
@@auth_config.map do |conf|
|
120
|
+
conf[:user_model]
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
def auth_attributes
|
125
|
+
@@auth_config ||= []
|
126
|
+
@@auth_config.reduce({}) do |hash, conf|
|
127
|
+
hash.merge! conf[:user_model] => conf[:auth_attributes]
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
def root_path_for=(**options)
|
132
|
+
@root_path ||= {}
|
133
|
+
@root_path.merge! options
|
134
|
+
end
|
135
|
+
|
136
|
+
def root_path_for(user_class)
|
137
|
+
@root_path&.dig(user_class) || '/'
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
# HACK: FIXME
|
143
|
+
|
144
|
+
class ActiveModel::Errors
|
145
|
+
def merge!(*args); end
|
5
146
|
end
|