tramway-core 1.17.1 → 1.17.2.3
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/README.md +83 -2
- data/app/assets/javascripts/tramway/core/application.js +1 -1
- data/app/controllers/tramway/core/application_controller.rb +8 -12
- data/app/decorators/tramway/core/application_decorator.rb +16 -28
- data/app/decorators/tramway/core/associations/class_helper.rb +13 -13
- data/app/decorators/tramway/core/associations/object_helper.rb +31 -3
- data/app/decorators/tramway/core/attributes/view_helper.rb +26 -0
- data/app/decorators/tramway/core/concerns/attributes_decorator_helper.rb +47 -26
- data/app/decorators/tramway/core/delegating/class_helper.rb +9 -0
- data/app/forms/tramway/core/application_form.rb +83 -171
- data/app/forms/tramway/core/application_forms/association_object_helpers.rb +31 -0
- data/app/forms/tramway/core/application_forms/constant_class_actions.rb +7 -0
- data/app/forms/tramway/core/application_forms/constant_object_actions.rb +13 -0
- data/app/forms/tramway/core/application_forms/properties_object_helper.rb +23 -0
- data/app/forms/tramway/core/extendable_form.rb +3 -70
- data/app/forms/tramway/core/extendable_forms_helpers/class_builder.rb +34 -0
- data/app/forms/tramway/core/extendable_forms_helpers/ignored_properties_helper.rb +11 -0
- data/app/forms/tramway/core/extendable_forms_helpers/more_properties_helper.rb +27 -0
- data/app/forms/tramway/core/extendable_forms_helpers/properties_helper.rb +16 -0
- data/app/forms/tramway/core/extendable_forms_helpers/submit/class_helpers.rb +18 -0
- data/app/forms/tramway/core/extendable_forms_helpers/submit/object_helpers.rb +7 -0
- data/app/forms/tramway/core/extendable_forms_helpers/validators.rb +40 -0
- data/app/helpers/tramway/core/copy_to_clipboard_helper.rb +6 -10
- data/app/helpers/tramway/core/title_helper.rb +17 -22
- data/app/models/tramway/core/application_record.rb +38 -40
- data/app/uploaders/image_defaults.rb +2 -1
- data/app/uploaders/photo_uploader.rb +8 -8
- data/config/initializers/plurals.rb +2 -2
- data/lib/tramway/collection.rb +4 -6
- data/lib/tramway/collections.rb +4 -0
- data/lib/tramway/collections/helper.rb +15 -14
- data/lib/tramway/core.rb +22 -22
- data/lib/tramway/core/engine.rb +4 -8
- data/lib/tramway/core/generators.rb +4 -0
- data/lib/tramway/core/generators/install_generator.rb +17 -17
- data/lib/tramway/core/version.rb +1 -1
- data/lib/tramway/error.rb +12 -1
- data/lib/yaml/errors.yml +35 -0
- metadata +20 -3
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Tramway::Core::ExtendableFormsHelpers::ClassBuilder
|
4
|
+
def build_form_class(name, simple_properties, more_properties)
|
5
|
+
Object.const_set(name, Class.new(::Tramway::Core::ApplicationForm) do
|
6
|
+
properties(*simple_properties.keys) if simple_properties.keys.any?
|
7
|
+
|
8
|
+
include Tramway::Core::ExtendableFormsHelpers::Submit::ObjectHelpers
|
9
|
+
include Tramway::Core::ExtendableFormsHelpers::Validators
|
10
|
+
extend Tramway::Core::ExtendableFormsHelpers::Submit::ClassHelpers
|
11
|
+
extend Tramway::Core::ExtendableFormsHelpers::PropertiesHelper
|
12
|
+
extend Tramway::Core::ExtendableFormsHelpers::MorePropertiesHelper
|
13
|
+
extend Tramway::Core::ExtendableFormsHelpers::IgnoredPropertiesHelper
|
14
|
+
|
15
|
+
define_submit_method simple_properties, more_properties
|
16
|
+
define_properties_method simple_properties, more_properties
|
17
|
+
define_ignored_properties_method
|
18
|
+
|
19
|
+
more_properties.each do |property|
|
20
|
+
define_property_method property[0]
|
21
|
+
|
22
|
+
case property[1][:object].field_type
|
23
|
+
when 'file'
|
24
|
+
field = property[1][:object]
|
25
|
+
define_file_property_assignment_method property field
|
26
|
+
else
|
27
|
+
next unless property[1][:validates].present?
|
28
|
+
|
29
|
+
define_assignment_method property
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end)
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Tramway::Core::ExtendableFormsHelpers::IgnoredPropertiesHelper
|
4
|
+
def define_ignored_properties_method
|
5
|
+
define_method :jsonb_ignored_properties do |properties|
|
6
|
+
properties.map do |property|
|
7
|
+
property[0].to_s if property[1][:object].field_type == 'file'
|
8
|
+
end.compact
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Tramway::Core::ExtendableFormsHelpers::MorePropertiesHelper
|
4
|
+
def define_property_method(property_name)
|
5
|
+
define_method property_name do
|
6
|
+
model.values[property_name] if model.values
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def define_assignment_method(property)
|
11
|
+
define_method "#{property[0]}=" do |value|
|
12
|
+
property[1][:validates].each do |pair|
|
13
|
+
make_validates property[0], pair, value
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def define_file_property_assignment_method(property, field)
|
19
|
+
define_method "#{property[0]}=" do |value|
|
20
|
+
file_instance = property[1][:association_model].find_or_create_by(
|
21
|
+
"#{model.class.name.underscore}_id" => model.id, "#{field.class.name.underscore}_id" => field.id
|
22
|
+
)
|
23
|
+
file_instance.file = value
|
24
|
+
file_instance.save!
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Tramway::Core::ExtendableFormsHelpers::PropertiesHelper
|
4
|
+
def define_properties_method(simple_properties, more_properties)
|
5
|
+
define_method 'properties' do
|
6
|
+
hash = simple_properties.each_with_object({}) do |property, h|
|
7
|
+
h.merge! property[0] => property[1] unless model.class.state_machines.keys.include?(property[0])
|
8
|
+
end
|
9
|
+
more_properties.reduce(hash) do |h, property|
|
10
|
+
h.merge! property[0] => {
|
11
|
+
extended_form_property: property[1][:object]
|
12
|
+
}
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Tramway::Core::ExtendableFormsHelpers::Submit::ClassHelpers
|
4
|
+
def define_submit_method(simple_properties, more_properties)
|
5
|
+
define_method 'submit' do |params|
|
6
|
+
model.values ||= {}
|
7
|
+
extended_params = extended(simple_properties, more_properties, params)
|
8
|
+
params.each do |key, value|
|
9
|
+
method_name = "#{key}="
|
10
|
+
send method_name, value if respond_to?(method_name)
|
11
|
+
end
|
12
|
+
model.values = extended_params.reduce(model.values) do |hash, pair|
|
13
|
+
hash.merge! pair[0] => pair[1]
|
14
|
+
end
|
15
|
+
super(params) && model.errors.empty?
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,7 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Tramway::Core::ExtendableFormsHelpers::Submit::ObjectHelpers
|
4
|
+
def extended(simple_properties, more_properties, params)
|
5
|
+
params.except(*simple_properties.keys).except(*jsonb_ignored_properties(more_properties)).permit!.to_h
|
6
|
+
end
|
7
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Tramway::Core::ExtendableFormsHelpers::Validators
|
4
|
+
def make_validates(property_name, validation, value)
|
5
|
+
case validation[0].to_s
|
6
|
+
when 'presence'
|
7
|
+
presence_validator property_name, validation, value
|
8
|
+
when 'inclusion'
|
9
|
+
inclusion_validator property_name, validation, value
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def presence_validator(property_name, validation, value)
|
14
|
+
validator_object = PresenceValidator.new(attributes: :not_blank)
|
15
|
+
return if validation[1] == 'false'
|
16
|
+
return if validation[1] == 'true' && validator_object.send(:valid?, value)
|
17
|
+
|
18
|
+
model.errors.add(
|
19
|
+
property_name,
|
20
|
+
I18n.t(
|
21
|
+
"activerecord.errors.models.#{model.class.name.underscore}.attributes.default.#{validation[0]}",
|
22
|
+
value: value
|
23
|
+
)
|
24
|
+
)
|
25
|
+
end
|
26
|
+
|
27
|
+
def inclusion_validator(property_name, validation, value)
|
28
|
+
in_array = validation[1][:in]
|
29
|
+
|
30
|
+
return if value.in? in_array
|
31
|
+
|
32
|
+
model.errors.add(
|
33
|
+
property_name,
|
34
|
+
I18n.t(
|
35
|
+
"activerecord.errors.models.#{model.class.name.underscore}.attributes.default.#{validation[0]}",
|
36
|
+
value: value
|
37
|
+
)
|
38
|
+
)
|
39
|
+
end
|
40
|
+
end
|
@@ -1,15 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
module Tramway
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
style: 'margin-left: 15px' do
|
10
|
-
fa_icon 'copy'
|
11
|
-
end
|
12
|
-
end
|
3
|
+
module Tramway::Core::CopyToClipboardHelper
|
4
|
+
def copy_to_clipboard(id)
|
5
|
+
button_tag class: 'btn btn-info clipboard-btn',
|
6
|
+
data: { clipboard_action: 'copy', clipboard_target: "##{id}" },
|
7
|
+
style: 'margin-left: 15px' do
|
8
|
+
fa_icon 'copy'
|
13
9
|
end
|
14
10
|
end
|
15
11
|
end
|
@@ -1,29 +1,24 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
module Tramway
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
raise error.message
|
13
|
-
end
|
14
|
-
end
|
3
|
+
module Tramway::Core::TitleHelper
|
4
|
+
def title(page_title = default_title)
|
5
|
+
if @application.present?
|
6
|
+
title_text = "#{page_title} | #{@application.try(:title) || @application.public_name}"
|
7
|
+
content_for(:title) { title_text }
|
8
|
+
else
|
9
|
+
Tramway::Error.raise_error(:tramway, :core, :title_helper, :title, :you_should_set_tramway_core_application)
|
10
|
+
end
|
11
|
+
end
|
15
12
|
|
16
|
-
|
17
|
-
|
18
|
-
|
13
|
+
def default_title
|
14
|
+
t('.title')
|
15
|
+
end
|
19
16
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
end
|
26
|
-
end
|
17
|
+
def page_title(action, model_name)
|
18
|
+
if I18n.locale == :ru
|
19
|
+
t("helpers.actions.#{action}") + ' ' + genitive(model_name)
|
20
|
+
else
|
21
|
+
t("helpers.actions.#{action}") + ' ' + model_name.model_name.human.downcase
|
27
22
|
end
|
28
23
|
end
|
29
24
|
end
|
@@ -2,52 +2,50 @@
|
|
2
2
|
|
3
3
|
require 'carrierwave/orm/activerecord' if defined?(CarrierWave::Mount)
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
audited
|
10
|
-
extend ::Enumerize
|
11
|
-
|
12
|
-
state_machine :state, initial: :active do
|
13
|
-
state :active
|
14
|
-
state :removed
|
15
|
-
|
16
|
-
event :remove do
|
17
|
-
transition active: :remove
|
18
|
-
end
|
19
|
-
end
|
5
|
+
class Tramway::Core::ApplicationRecord < ActiveRecord::Base
|
6
|
+
self.abstract_class = true
|
7
|
+
audited
|
8
|
+
extend ::Enumerize
|
20
9
|
|
21
|
-
|
22
|
-
|
23
|
-
|
10
|
+
state_machine :state, initial: :active do
|
11
|
+
state :active
|
12
|
+
state :removed
|
24
13
|
|
25
|
-
|
14
|
+
event :remove do
|
15
|
+
transition active: :remove
|
16
|
+
end
|
17
|
+
end
|
26
18
|
|
27
|
-
|
28
|
-
|
29
|
-
|
19
|
+
scope :active, -> { where state: :active }
|
20
|
+
scope :created_by_user, lambda { |user_id|
|
21
|
+
joins(:audits).where('audits.action = \'create\' AND audits.user_id = ?', user_id)
|
22
|
+
}
|
23
|
+
scope :admin_scope, ->(_arg) { all }
|
30
24
|
|
31
|
-
|
32
|
-
class << self
|
33
|
-
def human_attribute_name(attribute_name, *_args)
|
34
|
-
excepted_attributes = %w[created_at updated_at state]
|
35
|
-
if attribute_name.to_s.in? excepted_attributes
|
36
|
-
I18n.t "activerecord.attributes.tramway/core/application_record.#{attribute_name}"
|
37
|
-
else
|
38
|
-
super attribute_name
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
def search_by(*attributes, **associations)
|
43
|
-
pg_search_scope :full_text_search, against: attributes, associated_against: associations
|
44
|
-
end
|
45
|
-
end
|
25
|
+
include ::PgSearch::Model
|
46
26
|
|
47
|
-
|
48
|
-
|
49
|
-
|
27
|
+
def creator
|
28
|
+
audits.where(action: :create).first.user
|
29
|
+
end
|
30
|
+
|
31
|
+
# FIXME: detect inhertited locales
|
32
|
+
class << self
|
33
|
+
def human_attribute_name(attribute_name, *_args)
|
34
|
+
excepted_attributes = %w[created_at updated_at state]
|
35
|
+
if attribute_name.to_s.in? excepted_attributes
|
36
|
+
I18n.t "activerecord.attributes.tramway/core/application_record.#{attribute_name}"
|
37
|
+
else
|
38
|
+
super attribute_name
|
50
39
|
end
|
51
40
|
end
|
41
|
+
|
42
|
+
def search_by(*attributes, **associations)
|
43
|
+
pg_search_scope :full_text_search, against: attributes, associated_against: associations
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# FIXME: detect inhertited locales
|
48
|
+
def human_state_name
|
49
|
+
I18n.t "activerecord.state_machines.tramway/core/application_record.state.states.#{state}"
|
52
50
|
end
|
53
51
|
end
|
@@ -4,7 +4,8 @@ module ImageDefaults
|
|
4
4
|
include CarrierWave::MiniMagick
|
5
5
|
|
6
6
|
def default_url
|
7
|
-
"/images/fallback/#{model.class.model_name.to_s.underscore}/" <<
|
7
|
+
"/images/fallback/#{model.class.model_name.to_s.underscore}/" <<
|
8
|
+
[mounted_as, version_name].compact.join('_') << '.gif'
|
8
9
|
end
|
9
10
|
|
10
11
|
def extension_white_list
|
@@ -44,14 +44,14 @@ class PhotoUploader < ApplicationUploader
|
|
44
44
|
before :cache, :capture_size
|
45
45
|
|
46
46
|
def capture_size(file)
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
47
|
+
return unless version_name.blank?
|
48
|
+
|
49
|
+
if file.path.nil?
|
50
|
+
img = ::MiniMagick::Image.read(file.file)
|
51
|
+
@width = img[:width]
|
52
|
+
@height = img[:height]
|
53
|
+
else
|
54
|
+
@width, @height = `identify -format "%wx %h" #{file.path}`.split(/x/).map(&:to_i)
|
55
55
|
end
|
56
56
|
end
|
57
57
|
end
|
@@ -6,7 +6,7 @@
|
|
6
6
|
plural: {
|
7
7
|
keys: %i[zero one few many],
|
8
8
|
rule: lambda do |n|
|
9
|
-
if n
|
9
|
+
if n.zero?
|
10
10
|
:zero
|
11
11
|
elsif n % 10 == 1 && n % 100 != 11
|
12
12
|
# 1, 21, 31, 41, 51, 61...
|
@@ -14,7 +14,7 @@
|
|
14
14
|
elsif [2, 3, 4].include?(n % 10) && ![12, 13, 14].include?(n % 100)
|
15
15
|
# 2-4, 22-24, 32-34...
|
16
16
|
:few
|
17
|
-
elsif n % 10
|
17
|
+
elsif n % 10.zero? || ![5, 6, 7, 8, 9].include?(n % 10) || ![11, 12, 13, 14].include?(n % 100)
|
18
18
|
# 0, 5-20, 25-30, 35-40...
|
19
19
|
:many
|
20
20
|
end
|
data/lib/tramway/collection.rb
CHANGED
@@ -1,11 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
class
|
5
|
-
|
6
|
-
|
7
|
-
raise 'Please add collection to list method'
|
8
|
-
end
|
3
|
+
class Tramway::Collection
|
4
|
+
class << self
|
5
|
+
def list
|
6
|
+
raise 'Please add collection to list method'
|
9
7
|
end
|
10
8
|
end
|
11
9
|
end
|
@@ -1,20 +1,21 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
module Collections
|
5
|
-
module Helper
|
6
|
-
def collection_list_by(name:)
|
7
|
-
begin
|
8
|
-
require name # needed to load class name with collection
|
9
|
-
rescue LoadError
|
10
|
-
raise "No such file #{name}. You should create file in the `lib/#{name}.rb` or elsewhere you want"
|
11
|
-
end
|
12
|
-
unless ::Tramway::Collection.descendants.map(&:to_s).include?(name.camelize)
|
13
|
-
raise "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."
|
14
|
-
end
|
3
|
+
require 'tramway/collections'
|
15
4
|
|
16
|
-
|
17
|
-
|
5
|
+
module Tramway::Collections::Helper
|
6
|
+
def collection_list_by(name:)
|
7
|
+
begin
|
8
|
+
require name # needed to load class name with collection
|
9
|
+
rescue LoadError
|
10
|
+
raise "No such file #{name}. You should create file in the `lib/#{name}.rb` or elsewhere you want"
|
18
11
|
end
|
12
|
+
unless ::Tramway::Collection.descendants.map(&:to_s).include?(name.camelize)
|
13
|
+
::Tramway::Error.raise_error(
|
14
|
+
:tramway, :collections, :helper, :collection_list_by, :there_no_such_collection,
|
15
|
+
name_camelize: name.camelize
|
16
|
+
)
|
17
|
+
end
|
18
|
+
|
19
|
+
name.camelize.constantize.list
|
19
20
|
end
|
20
21
|
end
|
data/lib/tramway/core.rb
CHANGED
@@ -9,37 +9,37 @@ require 'reform'
|
|
9
9
|
require 'pg_search'
|
10
10
|
require 'validators/presence_validator'
|
11
11
|
|
12
|
-
module Tramway
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
@application.send "#{attr}=", value
|
19
|
-
end
|
12
|
+
module Tramway::Core
|
13
|
+
class << self
|
14
|
+
def initialize_application(**options)
|
15
|
+
@application ||= Tramway::Core::Application.new
|
16
|
+
options.each do |attr, value|
|
17
|
+
@application.send "#{attr}=", value
|
20
18
|
end
|
19
|
+
end
|
21
20
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
end
|
29
|
-
else
|
30
|
-
@application
|
21
|
+
def application_object
|
22
|
+
if @application&.model_class.present?
|
23
|
+
begin
|
24
|
+
@application.model_class.first
|
25
|
+
rescue StandardError
|
26
|
+
nil
|
31
27
|
end
|
28
|
+
else
|
29
|
+
@application
|
32
30
|
end
|
31
|
+
end
|
33
32
|
|
34
|
-
|
33
|
+
def root
|
34
|
+
File.dirname __dir__
|
35
35
|
end
|
36
|
+
|
37
|
+
attr_reader :application
|
36
38
|
end
|
37
39
|
end
|
38
40
|
|
39
41
|
# HACK: FIXME
|
40
42
|
|
41
|
-
|
42
|
-
|
43
|
-
def merge!(*args); end
|
44
|
-
end
|
43
|
+
class ActiveModel::Errors
|
44
|
+
def merge!(*args); end
|
45
45
|
end
|