binda 0.1.5 → 0.1.6
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 +42 -26
- data/Rakefile +4 -0
- data/app/assets/javascripts/binda/application.js +3 -0
- data/app/assets/javascripts/binda/components/field_setting_choices.js +5 -5
- data/app/assets/javascripts/binda/components/fileupload.js +1 -1
- data/app/assets/javascripts/binda/components/form_item_collapsable.js +245 -0
- data/app/assets/javascripts/binda/components/form_item_image.js +1 -1
- data/app/assets/javascripts/binda/components/login-shader.js +1 -1
- data/app/assets/javascripts/binda/components/login_form.js +1 -1
- data/app/assets/javascripts/binda/components/sortable.js +21 -30
- data/app/assets/javascripts/binda/dist/binda.bundle.js +299 -377
- data/app/assets/javascripts/binda/index.js +9 -17
- data/app/assets/stylesheets/binda/components/field_setting_choices.scss +5 -3
- data/app/assets/stylesheets/binda/components/form_item.scss +23 -70
- data/app/assets/stylesheets/binda/components/standard-form.scss +56 -1
- data/app/assets/stylesheets/binda/settings/tiny_mce_overrides.scss +8 -0
- data/app/controllers/binda/application_controller.rb +6 -0
- data/app/controllers/binda/boards_controller.rb +18 -12
- data/app/controllers/binda/components_controller.rb +21 -16
- data/app/controllers/binda/field_groups_controller.rb +57 -16
- data/app/controllers/binda/field_settings_controller.rb +14 -2
- data/app/controllers/binda/repeaters_controller.rb +2 -2
- data/app/controllers/binda/structures_controller.rb +32 -16
- data/app/controllers/concerns/binda/fieldable_helpers.rb +2 -2
- data/app/helpers/binda/components_helper.rb +16 -4
- data/app/helpers/binda/field_groups_helper.rb +4 -1
- data/app/models/binda/asset.rb +1 -3
- data/app/models/binda/component.rb +17 -10
- data/app/models/binda/date.rb +2 -6
- data/app/models/binda/field_group.rb +7 -5
- data/app/models/binda/field_setting.rb +69 -8
- data/app/models/binda/gallery.rb +2 -3
- data/app/models/binda/image.rb +7 -1
- data/app/models/binda/relation.rb +2 -5
- data/app/models/binda/repeater.rb +10 -14
- data/app/models/binda/selection.rb +3 -3
- data/app/models/binda/structure.rb +9 -5
- data/app/models/binda/text.rb +2 -6
- data/app/models/binda/user.rb +10 -0
- data/app/models/concerns/binda/field_uniqueness.rb +31 -0
- data/app/models/concerns/binda/fieldable_association_helpers.rb +31 -11
- data/app/models/concerns/binda/fieldable_associations.rb +2 -3
- data/app/models/concerns/binda/fields.rb +21 -0
- data/app/views/binda/boards/edit.html.erb +2 -1
- data/app/views/binda/components/edit.html.erb +2 -1
- data/app/views/binda/field_groups/_form_body.html.erb +4 -42
- data/app/views/binda/field_groups/_form_header.html.erb +11 -0
- data/app/views/binda/field_groups/_form_item.html.erb +4 -6
- data/app/views/binda/field_groups/_form_new_item.html.erb +8 -0
- data/app/views/binda/field_groups/_form_section.html.erb +17 -27
- data/app/views/binda/field_groups/_form_section_repeater.html.erb +17 -18
- data/app/views/binda/field_groups/_form_sidebar.html.erb +13 -0
- data/app/views/binda/field_groups/form_item/_form_item_editor.html.erb +9 -5
- data/app/views/binda/field_groups/form_item/{_form_item_persisted_editor.html.erb → _form_item_editor_existing_item.html.erb} +1 -4
- data/app/views/binda/field_groups/form_item/_form_item_editor_new_item.html.erb +3 -0
- data/app/views/binda/field_groups/form_item/_form_item_header.html.erb +23 -24
- data/app/views/binda/field_groups/form_section/_form_section_header.html.erb +45 -0
- data/app/views/binda/field_groups/form_section/_form_section_list.html.erb +9 -0
- data/app/views/binda/fieldable/_form_body.html.erb +6 -1
- data/app/views/binda/fieldable/_form_item_date.html.erb +1 -1
- data/app/views/binda/fieldable/_form_item_image.html.erb +1 -1
- data/app/views/binda/fieldable/_form_item_new_repeater.html.erb +7 -21
- data/app/views/binda/fieldable/_form_item_relation.html.erb +7 -7
- data/app/views/binda/fieldable/_form_item_repeater.html.erb +9 -99
- data/app/views/binda/fieldable/_form_item_selections.html.erb +1 -1
- data/app/views/binda/fieldable/_form_item_string.html.erb +5 -12
- data/app/views/binda/fieldable/_form_item_text.html.erb +5 -13
- data/app/views/binda/fieldable/_form_item_video.html.erb +1 -1
- data/app/views/binda/fieldable/_form_section.html.erb +11 -10
- data/app/views/binda/fieldable/_form_section_repeater.html.erb +2 -3
- data/app/views/binda/fieldable/form_item_repeater/_form_item_repeater_header.html.erb +32 -0
- data/app/views/binda/fieldable/form_item_repeater/_form_item_repeater_list.html.erb +19 -0
- data/app/views/binda/fieldable/form_item_repeater/_form_item_repeater_list_item.html.erb +42 -0
- data/app/views/binda/structures/_form_field_group_item.html.erb +5 -0
- data/app/views/binda/structures/_form_new_field_group_item.html.erb +8 -0
- data/app/views/binda/structures/_form_section.html.erb +16 -78
- data/app/views/binda/structures/_form_sidebar.html.erb +9 -8
- data/app/views/binda/structures/form_field_group_item/_form_field_group_item_editor.html.erb +18 -0
- data/app/views/binda/structures/form_field_group_item/_form_field_group_item_field_setting_form.html.erb +12 -0
- data/app/views/binda/structures/form_field_group_item/_form_field_group_item_field_settings.html.erb +18 -0
- data/app/views/binda/structures/form_field_group_item/_form_field_group_item_header.html.erb +29 -0
- data/app/views/binda/structures/form_section/_form_section_header.html.erb +26 -0
- data/app/views/binda/structures/form_section/_form_section_list.html.erb +8 -0
- data/config/initializers/simple_form__fileupload.rb +3 -4
- data/config/locales/en.yml +9 -4
- data/config/routes.rb +4 -0
- data/lib/binda/version.rb +1 -1
- data/lib/generators/binda/install/install_generator.rb +17 -6
- data/lib/generators/binda/maintenance/maintenance_generator.rb +12 -8
- data/lib/generators/binda/setup/setup_generator.rb +23 -27
- data/lib/tasks/create_missing_field_instances_task.rake +10 -0
- data/lib/tasks/remove_orphan_fields_task.rake +1 -7
- data/lib/tasks/user_tasks.rake +1 -7
- data/vendor/assets/javascripts/lodash.js +17097 -0
- metadata +39 -7
- data/app/assets/javascripts/binda/components/form_item.js +0 -113
- data/app/assets/javascripts/binda/components/form_item_editor.js +0 -39
- data/app/assets/javascripts/binda/components/form_item_repeater.js +0 -127
- data/app/views/binda/field_groups/form_item/_form_item_new_editor.html.erb +0 -8
data/app/models/binda/gallery.rb
CHANGED
data/app/models/binda/image.rb
CHANGED
|
@@ -4,9 +4,12 @@ module Binda
|
|
|
4
4
|
|
|
5
5
|
mount_uploader :image, ImageUploader
|
|
6
6
|
|
|
7
|
+
# Register image details
|
|
8
|
+
#
|
|
9
|
+
# Do not delete. This method is used by a rake task
|
|
7
10
|
def register_deatils
|
|
8
11
|
if !self.image.present?
|
|
9
|
-
|
|
12
|
+
warn "Ops, there is no image for Binda::Image id=#{self.id}"
|
|
10
13
|
elsif CarrierWave::Uploader::Base.storage == CarrierWave::Storage::File
|
|
11
14
|
file = MiniMagick::Image.open(::Rails.root.join(self.image.path))
|
|
12
15
|
register_details_of(file)
|
|
@@ -16,6 +19,9 @@ module Binda
|
|
|
16
19
|
end
|
|
17
20
|
end
|
|
18
21
|
|
|
22
|
+
# Register image details
|
|
23
|
+
#
|
|
24
|
+
# This method is used by register_deatils in a rake task
|
|
19
25
|
def register_details_of(file)
|
|
20
26
|
self.file_width = file.width
|
|
21
27
|
self.file_height = file.height
|
|
@@ -18,11 +18,8 @@ module Binda
|
|
|
18
18
|
# relation.dependent_components << dependent
|
|
19
19
|
class Relation < ApplicationRecord
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
validates :fieldable_id, presence: true
|
|
25
|
-
validates :fieldable_type, presence: true
|
|
21
|
+
include Fields
|
|
22
|
+
include FieldUniqueness
|
|
26
23
|
|
|
27
24
|
# Relations are the connection between a Owner to its Dependents
|
|
28
25
|
# The Active Relation connects a Relation to a Dependent (which is can be a Component or a Board)
|
|
@@ -2,13 +2,7 @@ module Binda
|
|
|
2
2
|
class Repeater < ApplicationRecord
|
|
3
3
|
|
|
4
4
|
include FieldableAssociations
|
|
5
|
-
|
|
6
|
-
# Associations
|
|
7
|
-
belongs_to :fieldable, polymorphic: true
|
|
8
|
-
belongs_to :field_setting
|
|
9
|
-
|
|
10
|
-
validates :fieldable_id, presence: true
|
|
11
|
-
validates :fieldable_type, presence: true
|
|
5
|
+
include Fields
|
|
12
6
|
|
|
13
7
|
# The following direct association is used to securely delete associated fields
|
|
14
8
|
# Infact via `fieldable` the associated fields might not be deleted
|
|
@@ -20,17 +14,19 @@ module Binda
|
|
|
20
14
|
#
|
|
21
15
|
# This methods ensure that every repeater instance has an explicit position.
|
|
22
16
|
# The latest repeater created gets the highest position number.
|
|
23
|
-
# The first position is 1 (not 0).
|
|
24
17
|
#
|
|
25
18
|
# @return [object] Repeater instance
|
|
26
19
|
def set_default_position
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
20
|
+
Repeater
|
|
21
|
+
.where(
|
|
22
|
+
field_setting_id: self.field_setting_id,
|
|
23
|
+
fieldable_id: self.fieldable_id,
|
|
24
|
+
fieldable_type: self.fieldable_type
|
|
25
|
+
)
|
|
26
|
+
.each{|repeater| repeater.increment(:position).save!}
|
|
33
27
|
end
|
|
34
28
|
|
|
29
|
+
|
|
30
|
+
|
|
35
31
|
end
|
|
36
32
|
end
|
|
@@ -132,11 +132,11 @@ module Binda
|
|
|
132
132
|
#
|
|
133
133
|
class Selection < ApplicationRecord
|
|
134
134
|
|
|
135
|
-
|
|
136
|
-
|
|
135
|
+
include Fields
|
|
136
|
+
include FieldUniqueness
|
|
137
137
|
|
|
138
|
+
has_and_belongs_to_many :choices
|
|
138
139
|
validate :has_choices
|
|
139
|
-
validates :fieldable_id, presence: true
|
|
140
140
|
|
|
141
141
|
after_save do
|
|
142
142
|
if !self.field_setting.allow_null &&
|
|
@@ -23,6 +23,7 @@ module Binda
|
|
|
23
23
|
extend FriendlyId
|
|
24
24
|
friendly_id :default_slug, use: [:slugged, :finders]
|
|
25
25
|
|
|
26
|
+
before_save :board_contraints
|
|
26
27
|
after_create :add_default_field_group
|
|
27
28
|
after_save :add_instance_details
|
|
28
29
|
after_create :set_default_position
|
|
@@ -72,17 +73,21 @@ module Binda
|
|
|
72
73
|
# It also disable categories (this could be a different method, or method could be more explicit)
|
|
73
74
|
def add_instance_details
|
|
74
75
|
if self.instance_type == 'board'
|
|
75
|
-
|
|
76
|
-
add_default_board
|
|
76
|
+
add_default_board
|
|
77
77
|
end
|
|
78
78
|
end
|
|
79
79
|
|
|
80
|
+
def board_contraints
|
|
81
|
+
self.has_categories = false if self.instance_type == 'board'
|
|
82
|
+
end
|
|
83
|
+
|
|
80
84
|
# Add default board to a structure if needed
|
|
81
85
|
def add_default_board
|
|
82
86
|
if Board.where(structure_id: self.id).empty?
|
|
83
87
|
board = self.build_board( name: self.name )
|
|
84
88
|
unless board.save
|
|
85
|
-
|
|
89
|
+
errors.add(:base, I18n.t('binda.default_field_group.error_on_create'))
|
|
90
|
+
# return redirect_to structure_path(self.slug), flash: { error: I18n.t('binda.default_field_group.error_on_create') }
|
|
86
91
|
end
|
|
87
92
|
end
|
|
88
93
|
end
|
|
@@ -94,8 +99,7 @@ module Binda
|
|
|
94
99
|
#
|
|
95
100
|
# @return [object] Repeater instance
|
|
96
101
|
def set_default_position
|
|
97
|
-
|
|
98
|
-
self.update_attribute('position', position)
|
|
102
|
+
Structure.all.each{|structure| structure.increment(:position).save!}
|
|
99
103
|
end
|
|
100
104
|
|
|
101
105
|
end
|
data/app/models/binda/text.rb
CHANGED
|
@@ -7,12 +7,8 @@ module Binda
|
|
|
7
7
|
# a simple string of text as well.
|
|
8
8
|
class Text < ApplicationRecord
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
belongs_to :field_setting
|
|
13
|
-
|
|
14
|
-
validates :fieldable_id, presence: true
|
|
15
|
-
validates :fieldable_type, presence: true
|
|
10
|
+
include Fields
|
|
11
|
+
include FieldUniqueness
|
|
16
12
|
|
|
17
13
|
end
|
|
18
14
|
end
|
data/app/models/binda/user.rb
CHANGED
|
@@ -4,5 +4,15 @@ module Binda
|
|
|
4
4
|
# :confirmable, :lockable, :timeoutable and :omniauthable
|
|
5
5
|
devise :database_authenticatable, :registerable,
|
|
6
6
|
:recoverable, :rememberable, :trackable, :validatable
|
|
7
|
+
|
|
8
|
+
def self.create_super_admin_user
|
|
9
|
+
STDOUT.puts "What is your email? [mail@domain.com]"
|
|
10
|
+
username = STDIN.gets.strip
|
|
11
|
+
username = 'mail@domain.com' if username.blank?
|
|
12
|
+
STDOUT.puts "What is your password? [password]"
|
|
13
|
+
password = STDIN.gets.strip
|
|
14
|
+
password = 'password' if password.blank?
|
|
15
|
+
User.create!( email: username, password: password, password_confirmation: password, is_superadmin: true )
|
|
16
|
+
end
|
|
7
17
|
end
|
|
8
18
|
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
module Binda
|
|
2
|
+
# Some fields are meant to be unique, meaning there must be only one instance
|
|
3
|
+
# associated with a specific component and field setting
|
|
4
|
+
module FieldUniqueness
|
|
5
|
+
|
|
6
|
+
extend ActiveSupport::Concern
|
|
7
|
+
|
|
8
|
+
included do
|
|
9
|
+
validate :field_uniqueness
|
|
10
|
+
end
|
|
11
|
+
# Make sure there is only one instance associated simultaneously with a specific component and field setting
|
|
12
|
+
# @return [boolean]
|
|
13
|
+
def field_uniqueness
|
|
14
|
+
instances = Text.where(
|
|
15
|
+
field_setting_id: self.field_setting.id,
|
|
16
|
+
fieldable_id: self.fieldable_id,
|
|
17
|
+
fieldable_type: self.fieldable_type
|
|
18
|
+
)
|
|
19
|
+
if instances.any? && instances.first.id != self.id
|
|
20
|
+
errors.add(:base, I18n.t("binda.duplicate_validation", {
|
|
21
|
+
arg1: self.field_setting.field_type,
|
|
22
|
+
arg2: self.fieldable_id,
|
|
23
|
+
arg3: self.field_setting.slug
|
|
24
|
+
}))
|
|
25
|
+
return false
|
|
26
|
+
else
|
|
27
|
+
return true
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -10,9 +10,15 @@ module Binda
|
|
|
10
10
|
# @return [string] Returns the content of the text
|
|
11
11
|
# @return [error] Raise an error if no record is found
|
|
12
12
|
def get_text(field_slug)
|
|
13
|
-
obj =
|
|
13
|
+
obj = Text
|
|
14
|
+
.includes(:field_setting)
|
|
15
|
+
.where(fieldable_id: self.id, fieldable_type: self.class.name)
|
|
16
|
+
.where(binda_field_settings: { slug: field_slug })
|
|
17
|
+
.where.not(binda_field_settings: { field_type: "string" })
|
|
18
|
+
.first
|
|
14
19
|
unless obj.nil?
|
|
15
|
-
|
|
20
|
+
# to_s ensures the returned object is class String
|
|
21
|
+
obj.content.to_s
|
|
16
22
|
else
|
|
17
23
|
check_text_error field_slug
|
|
18
24
|
end
|
|
@@ -21,7 +27,7 @@ module Binda
|
|
|
21
27
|
# Check why get_text doesn't return a value
|
|
22
28
|
# This method isn't supposed to be used by anything other than get_text method
|
|
23
29
|
def check_text_error(field_slug)
|
|
24
|
-
you_mean_string = !self.strings.find{ |t| t.field_setting_id == FieldSetting.get_id( field_slug ) && t.type
|
|
30
|
+
you_mean_string = !self.strings.find{ |t| t.field_setting_id == FieldSetting.get_id( field_slug ) && t.type == 'Binda::String' }.nil?
|
|
25
31
|
if you_mean_string
|
|
26
32
|
raise ArgumentError, "This slug (#{field_slug}) is associated to a string not a text. Use get_string() instead on instance (#{self.class.name} ##{self.id}).", caller
|
|
27
33
|
else
|
|
@@ -34,7 +40,12 @@ module Binda
|
|
|
34
40
|
# @param field_slug [string] The slug of the field setting
|
|
35
41
|
# @return [boolean]
|
|
36
42
|
def has_text(field_slug)
|
|
37
|
-
obj =
|
|
43
|
+
obj = Text
|
|
44
|
+
.includes(:field_setting)
|
|
45
|
+
.where(fieldable_id: self.id, fieldable_type: self.class.name)
|
|
46
|
+
.where(binda_field_settings: { slug: field_slug })
|
|
47
|
+
.where.not(binda_field_settings: { field_type: "string" })
|
|
48
|
+
.first
|
|
38
49
|
raise ArgumentError, "There isn't any text associated to the current slug (#{field_slug}) on instance (#{self.class.name} ##{self.id}).", caller if obj.nil?
|
|
39
50
|
if obj.present?
|
|
40
51
|
return !obj.content.nil?
|
|
@@ -50,9 +61,14 @@ module Binda
|
|
|
50
61
|
# @return [string] Returns the content of the string
|
|
51
62
|
# @return [error] Raise an error if no record is found
|
|
52
63
|
def get_string(field_slug)
|
|
53
|
-
obj =
|
|
64
|
+
obj = Text
|
|
65
|
+
.includes(:field_setting)
|
|
66
|
+
.where(fieldable_id: self.id, fieldable_type: self.class.name)
|
|
67
|
+
.where(binda_field_settings: { slug: field_slug, field_type: "string" })
|
|
68
|
+
.first
|
|
54
69
|
unless obj.nil?
|
|
55
|
-
|
|
70
|
+
# to_s ensures the returned object is class String
|
|
71
|
+
obj.content.to_s
|
|
56
72
|
else
|
|
57
73
|
check_string_error field_slug
|
|
58
74
|
end
|
|
@@ -61,7 +77,7 @@ module Binda
|
|
|
61
77
|
# Check why get_string doesn't return a value
|
|
62
78
|
# This method isn't supposed to be used by anything other than get_string method
|
|
63
79
|
def check_string_error(field_slug)
|
|
64
|
-
you_mean_text = !self.strings.find{ |t| t.field_setting_id == FieldSetting.get_id( field_slug ) && t.type
|
|
80
|
+
you_mean_text = !self.strings.find{ |t| t.field_setting_id == FieldSetting.get_id( field_slug ) && t.type == 'Binda::Text' }.nil?
|
|
65
81
|
if you_mean_text
|
|
66
82
|
raise ArgumentError, "This slug (#{field_slug}) is associated to a text not a string. Use get_text() instead on instance (#{self.class.name} ##{self.id}).", caller
|
|
67
83
|
else
|
|
@@ -74,7 +90,11 @@ module Binda
|
|
|
74
90
|
# @param field_slug [string] The slug of the field setting
|
|
75
91
|
# @return [boolean]
|
|
76
92
|
def has_string(field_slug)
|
|
77
|
-
obj =
|
|
93
|
+
obj = Text
|
|
94
|
+
.includes(:field_setting)
|
|
95
|
+
.where(fieldable_id: self.id, fieldable_type: self.class.name)
|
|
96
|
+
.where(binda_field_settings: { slug: field_slug, field_type: "string" })
|
|
97
|
+
.first
|
|
78
98
|
raise ArgumentError, "There isn't any string associated to the current slug (#{field_slug}) on instance (#{self.class.name} ##{self.id}).", caller if obj.nil?
|
|
79
99
|
if obj.present?
|
|
80
100
|
return !obj.content.nil?
|
|
@@ -130,7 +150,7 @@ module Binda
|
|
|
130
150
|
# Alternative query
|
|
131
151
|
# obj = Image.where(field_setting_id: FieldSetting.get_id( field_slug ), fieldable_id: self.id, fieldable_type: self.class.to_s ).first
|
|
132
152
|
raise ArgumentError, "There isn't any image associated to the current slug (#{field_slug}) on instance (#{self.class.name} ##{self.id}).", caller if obj.nil?
|
|
133
|
-
if obj.image.present? && obj.image.respond_to?(size) && %w[thumb
|
|
153
|
+
if obj.image.present? && obj.image.respond_to?(size) && %w[thumb].include?(size)
|
|
134
154
|
obj.image.send(size).send(info)
|
|
135
155
|
elsif obj.image.present?
|
|
136
156
|
obj.image.send(info)
|
|
@@ -142,7 +162,7 @@ module Binda
|
|
|
142
162
|
# Get image size
|
|
143
163
|
#
|
|
144
164
|
# @param field_slug [string] The slug of the field setting
|
|
145
|
-
# @return [
|
|
165
|
+
# @return [float] with image type
|
|
146
166
|
def get_image_size(field_slug)
|
|
147
167
|
obj = self.images.find{ |t| t.field_setting_id == FieldSetting.get_id( field_slug ) }
|
|
148
168
|
return bytes_to_megabytes(obj.file_size)
|
|
@@ -165,7 +185,7 @@ module Binda
|
|
|
165
185
|
# Get image dimension
|
|
166
186
|
#
|
|
167
187
|
# @param field_slug [string] The slug of the field setting
|
|
168
|
-
# @return [hash] with width and height
|
|
188
|
+
# @return [hash] with width and height as floats
|
|
169
189
|
def get_image_dimension(field_slug)
|
|
170
190
|
obj = self.images.find{ |t| t.field_setting_id == FieldSetting.get_id( field_slug ) }
|
|
171
191
|
return { width: obj.file_width, height: obj.file_height }
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
module Binda
|
|
2
2
|
# Fieldable associations are Binda's core feature.
|
|
3
3
|
#
|
|
4
|
-
# They provide
|
|
5
|
-
# (texts, assets, dates and so on) to store data in a simple yet powerful way.
|
|
6
|
-
# make use of a set of helpers to retrieve fields data belonging to each model instance.
|
|
4
|
+
# They provide classes like `Binda::Component` and `Binda::Board` with a collection of fields
|
|
5
|
+
# (texts, assets, dates and so on) to store data in a simple yet powerful way.
|
|
7
6
|
module FieldableAssociations
|
|
8
7
|
|
|
9
8
|
extend ActiveSupport::Concern
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
module Binda
|
|
2
|
+
# Fieldable associated are Binda's core fields.
|
|
3
|
+
#
|
|
4
|
+
# They are associated to classes like `Binda::Component` and `Binda::Board` and store data
|
|
5
|
+
# in a simple yet powerful way.
|
|
6
|
+
module Fields
|
|
7
|
+
|
|
8
|
+
extend ActiveSupport::Concern
|
|
9
|
+
|
|
10
|
+
included do
|
|
11
|
+
# Associations
|
|
12
|
+
belongs_to :fieldable, polymorphic: true
|
|
13
|
+
belongs_to :field_setting
|
|
14
|
+
|
|
15
|
+
validates :field_setting, presence: true
|
|
16
|
+
validates :fieldable_id, presence: true
|
|
17
|
+
validates :fieldable_type, presence: true
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -7,7 +7,8 @@
|
|
|
7
7
|
<div class="main-header--buttons">
|
|
8
8
|
<% if @structure.has_preview %>
|
|
9
9
|
<a href="<%= "#{binda.root_path}#{@structure.slug}/#{@instance.slug}" %>"
|
|
10
|
-
class="main-header--link b-btn b-btn-primary"
|
|
10
|
+
class="main-header--link b-btn b-btn-primary"
|
|
11
|
+
target="_blank">
|
|
11
12
|
<i class="fas fa-link"></i>
|
|
12
13
|
<%= t 'binda.preview' %>
|
|
13
14
|
<%= @structure.name.humanize.split.map(&:capitalize).join(' ') %>
|
|
@@ -8,7 +8,8 @@
|
|
|
8
8
|
<div class="main-header--buttons">
|
|
9
9
|
<% if @structure.has_preview %>
|
|
10
10
|
<a href="<%= "#{binda.root_path}#{@structure.slug}/#{@instance.slug}" %>"
|
|
11
|
-
class="main-header--link b-btn b-btn-primary"
|
|
11
|
+
class="main-header--link b-btn b-btn-primary"
|
|
12
|
+
target="_blank">
|
|
12
13
|
<i class="fas fa-link"></i>
|
|
13
14
|
<%= t 'binda.preview' %>
|
|
14
15
|
<%= @structure.name.humanize.split.map(&:capitalize).join(' ') %>
|
|
@@ -4,52 +4,14 @@
|
|
|
4
4
|
<%= f.error_notification %>
|
|
5
5
|
<%= render 'layouts/binda/form_errors', f: f %>
|
|
6
6
|
<div class="standard-form--body">
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
<small><%= "#{ t :details }" %></small>
|
|
10
|
-
</div>
|
|
11
|
-
<%= f.input :name %>
|
|
12
|
-
<% if @field_group.slug.nil? %>
|
|
13
|
-
<%= f.input :slug, as: :hidden %>
|
|
14
|
-
<% else %>
|
|
15
|
-
<%= f.input :slug %>
|
|
16
|
-
<% end %>
|
|
17
|
-
</div>
|
|
18
|
-
<div class="standard-form--container">
|
|
19
|
-
<div id="form-section--field-group-<%= @field_group.id %>" class="form-section--wide-container">
|
|
20
|
-
<div class="standard-form--header">
|
|
21
|
-
<small><%= "#{ t 'binda.field_setting.plural' }" %></small>
|
|
22
|
-
</div>
|
|
23
|
-
<%= render "form_section", f: f %>
|
|
24
|
-
</div>
|
|
25
|
-
</div>
|
|
7
|
+
<%= render "form_header", f: f %>
|
|
8
|
+
<%= render "form_section", f: f %>
|
|
26
9
|
<% @field_group.field_settings.where( field_type: 'repeater' ).order( :position, :id ).each do |repeater| %>
|
|
27
|
-
|
|
28
|
-
<div id="form-section--repeater-<%= repeater.id %>" class="form-section--wide-container">
|
|
29
|
-
<div class="form-section">
|
|
30
|
-
<div class="standard-form--header field-settings-header">
|
|
31
|
-
<small><%= "#{ t('binda.repeater_field_settings', arg1: repeater.name ) }" %></small>
|
|
32
|
-
</div>
|
|
33
|
-
<%= render "form_section_repeater", f: f, repeater: repeater %>
|
|
34
|
-
</div>
|
|
35
|
-
</div>
|
|
36
|
-
</div>
|
|
10
|
+
<%= render "form_section_repeater", f: f, repeater: repeater %>
|
|
37
11
|
<% end %>
|
|
38
12
|
</div>
|
|
39
13
|
<div class="standard-form--sidebar">
|
|
40
|
-
|
|
41
|
-
<div class="standard-form--header">
|
|
42
|
-
<small><%= "#{ t :setting }".pluralize %></small>
|
|
43
|
-
</div>
|
|
44
|
-
<div class="standard-form--main-actions">
|
|
45
|
-
<%= button_tag '<i class="fas fa-check"></i>Save changes'.html_safe, {
|
|
46
|
-
class: 'b-btn b-btn-primary b-btn-settings',
|
|
47
|
-
id: 'save',
|
|
48
|
-
'data-entries-number': get_entries_number,
|
|
49
|
-
'data-instance-type': @structure.instance_type.pluralize
|
|
50
|
-
} %>
|
|
51
|
-
</div>
|
|
52
|
-
</div>
|
|
14
|
+
<%= render "form_sidebar" %>
|
|
53
15
|
</div>
|
|
54
16
|
<% end %>
|
|
55
17
|
</div>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
<div class="standard-form--container">
|
|
2
|
+
<div class="standard-form--header">
|
|
3
|
+
<small><%= "#{ t :details }" %></small>
|
|
4
|
+
</div>
|
|
5
|
+
<%= f.input :name %>
|
|
6
|
+
<% if @field_group.slug.nil? %>
|
|
7
|
+
<%= f.input :slug, as: :hidden %>
|
|
8
|
+
<% else %>
|
|
9
|
+
<%= f.input :slug %>
|
|
10
|
+
<% end %>
|
|
11
|
+
</div>
|