super 0.0.4 → 0.0.9
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/.yardopts +13 -0
- data/CONTRIBUTING.md +56 -0
- data/README.md +60 -85
- data/STABILITY.md +50 -0
- data/app/assets/javascripts/super/application.js +1169 -359
- data/app/assets/stylesheets/super/application.css +86648 -30707
- data/app/controllers/super/application_controller.rb +44 -71
- data/app/views/layouts/super/application.html.erb +26 -6
- data/app/views/super/application/{_resources_header.html.erb → _collection_header.html.erb} +5 -6
- data/app/views/super/application/_display_rich_text.html.erb +1 -0
- data/app/views/super/application/_filter.html.erb +14 -0
- data/app/views/super/application/_filter_type_select.html.erb +31 -0
- data/app/views/super/application/_filter_type_text.html.erb +22 -0
- data/app/views/super/application/_filter_type_timestamp.html.erb +35 -0
- data/app/views/super/application/_flash.html.erb +13 -13
- data/app/views/super/application/_form_field__destroy.html.erb +6 -2
- data/app/views/super/application/_form_field_checkbox.html.erb +15 -0
- data/app/views/super/application/_form_field_generic.html.erb +19 -0
- data/app/views/super/application/_form_field_rich_text_area.html.erb +13 -0
- data/app/views/super/application/_form_field_select.html.erb +11 -5
- data/app/views/super/application/_form_field_text.html.erb +13 -5
- data/app/views/super/application/_form_has_many.html.erb +3 -3
- data/app/views/super/application/_form_inline_errors.html.erb +1 -1
- data/app/views/super/application/{_resource_header.html.erb → _member_header.html.erb} +6 -6
- data/app/views/super/application/_super_layout.html.erb +12 -17
- data/app/views/super/application/_super_pagination.html.erb +16 -0
- data/app/views/super/application/_super_panel.html.erb +3 -7
- data/app/views/super/application/_super_schema_display_actions.html.erb +5 -0
- data/app/views/super/application/_super_schema_display_index.html.erb +24 -0
- data/app/views/super/application/_super_schema_display_show.html.erb +8 -0
- data/app/views/super/application/{_form.html.erb → _super_schema_form.html.erb} +2 -4
- data/app/views/super/application/edit.html.erb +1 -1
- data/app/views/super/application/index.html.erb +1 -1
- data/app/views/super/application/new.html.erb +1 -1
- data/app/views/super/application/show.html.erb +1 -1
- data/app/views/super/feather/{_chevron_down.svg → _chevron_down.html} +0 -0
- data/config/locales/en.yml +5 -0
- data/docs/README.md +8 -0
- data/docs/action_text.md +48 -0
- data/docs/cheat.md +41 -0
- data/docs/faq.md +44 -0
- data/docs/installation.md +21 -0
- data/docs/quick_start.md +30 -0
- data/docs/webpacker.md +25 -0
- data/docs/yard_customizations.rb +41 -0
- data/frontend/super-frontend/build.js +1 -1
- data/frontend/super-frontend/dist/application.css +86648 -30707
- data/frontend/super-frontend/dist/application.js +1169 -359
- data/frontend/super-frontend/package.json +2 -3
- data/frontend/super-frontend/src/javascripts/super/{application.ts → application.js} +5 -8
- data/frontend/super-frontend/src/javascripts/super/apply_template_controller.js +17 -0
- data/frontend/super-frontend/src/javascripts/super/{toggle_pending_destruction_controller.ts → toggle_pending_destruction_controller.js} +2 -2
- data/frontend/super-frontend/tailwind.config.js +7 -1
- data/frontend/super-frontend/yarn.lock +1368 -1391
- data/lib/generators/super/action_text/USAGE +23 -0
- data/lib/generators/super/action_text/action_text_generator.rb +30 -0
- data/lib/generators/super/action_text/templates/pack_super_action_text.css +23 -0
- data/lib/generators/super/action_text/templates/pack_super_action_text.js +4 -0
- data/lib/generators/super/install/install_generator.rb +16 -0
- data/lib/generators/super/resource/templates/resources_controller.rb.tt +1 -31
- data/lib/generators/super/webpacker/USAGE +5 -4
- data/lib/generators/super/webpacker/webpacker_generator.rb +10 -1
- data/lib/super.rb +22 -5
- data/lib/super/action_inquirer.rb +2 -2
- data/lib/super/assets.rb +112 -38
- data/lib/super/client_error.rb +43 -0
- data/lib/super/compatibility.rb +25 -0
- data/lib/super/configuration.rb +21 -69
- data/lib/super/controls.rb +9 -257
- data/lib/super/controls/optional.rb +79 -0
- data/lib/super/controls/required.rb +13 -0
- data/lib/super/controls/steps.rb +114 -0
- data/lib/super/display.rb +66 -3
- data/lib/super/display/guesser.rb +34 -0
- data/lib/super/display/schema_types.rb +61 -25
- data/lib/super/engine.rb +7 -1
- data/lib/super/error.rb +8 -9
- data/lib/super/filter.rb +12 -0
- data/lib/super/filter/form_object.rb +97 -0
- data/lib/super/filter/guesser.rb +30 -0
- data/lib/super/filter/operator.rb +103 -0
- data/lib/super/filter/plugin.rb +47 -0
- data/lib/super/filter/schema_types.rb +112 -0
- data/lib/super/form.rb +35 -0
- data/lib/super/form/builder.rb +48 -0
- data/lib/super/form/guesser.rb +27 -0
- data/lib/super/form/schema_types.rb +29 -22
- data/lib/super/form/strong_params.rb +29 -0
- data/lib/super/layout.rb +28 -0
- data/lib/super/link.rb +55 -32
- data/lib/super/pagination.rb +55 -0
- data/lib/super/panel.rb +13 -0
- data/lib/super/partial.rb +12 -0
- data/lib/super/partial/resolving.rb +24 -0
- data/lib/super/plugin.rb +34 -63
- data/lib/super/schema.rb +12 -22
- data/lib/super/schema/common.rb +25 -0
- data/lib/super/schema/guesser.rb +77 -0
- data/lib/super/version.rb +1 -1
- data/lib/super/view_helper.rb +43 -0
- metadata +138 -41
- data/app/helpers/super/application_helper.rb +0 -32
- data/app/views/super/application/_index.html.erb +0 -45
- data/app/views/super/application/_show.html.erb +0 -10
- data/frontend/super-frontend/src/javascripts/super/apply_template_controller.ts +0 -21
- data/frontend/super-frontend/src/javascripts/super/rails__ujs.d.ts +0 -1
- data/frontend/super-frontend/tsconfig.json +0 -13
- data/lib/super/action.rb +0 -22
- data/lib/super/action/step.rb +0 -36
- data/lib/super/test_support/copy_app_templates/controllers/favorite_things_controller.rb +0 -50
- data/lib/super/test_support/copy_app_templates/controllers/members_controller.rb +0 -74
- data/lib/super/test_support/copy_app_templates/controllers/ships_controller.rb +0 -47
- data/lib/super/test_support/copy_app_templates/migrations/20190216224956_create_members.rb +0 -11
- data/lib/super/test_support/copy_app_templates/migrations/20190803143320_create_ships.rb +0 -11
- data/lib/super/test_support/copy_app_templates/migrations/20190806014121_add_ship_to_members.rb +0 -5
- data/lib/super/test_support/copy_app_templates/migrations/20191126050453_create_favorite_things.rb +0 -10
- data/lib/super/test_support/copy_app_templates/models/favorite_thing.rb +0 -7
- data/lib/super/test_support/copy_app_templates/models/member.rb +0 -23
- data/lib/super/test_support/copy_app_templates/models/ship.rb +0 -3
- data/lib/super/test_support/copy_app_templates/routes.rb +0 -11
- data/lib/super/test_support/copy_app_templates/seeds.rb +0 -2
- data/lib/super/test_support/copy_app_templates/views/members/_favorite_things.html.erb +0 -11
- data/lib/super/test_support/fixtures/favorite_things.yml +0 -9
- data/lib/super/test_support/fixtures/members.yml +0 -336
- data/lib/super/test_support/fixtures/ships.yml +0 -10
- data/lib/super/test_support/generate_copy_app.rb +0 -42
- data/lib/super/test_support/generate_dummy.rb +0 -93
- data/lib/super/test_support/starfleet_seeder.rb +0 -50
- data/lib/tasks/super_tasks.rake +0 -4
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
module Super
|
|
2
|
+
class Filter
|
|
3
|
+
class Guesser
|
|
4
|
+
def initialize(model:, fields:, type:)
|
|
5
|
+
@model = model
|
|
6
|
+
@fields = fields
|
|
7
|
+
@type = type
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def call
|
|
11
|
+
Schema::Guesser
|
|
12
|
+
.new(model: @model, fields: @fields, type: @type)
|
|
13
|
+
.assign_type { |attribute_name| attribute_type_for(attribute_name) }
|
|
14
|
+
.call
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
private
|
|
18
|
+
|
|
19
|
+
def attribute_type_for(attribute_name)
|
|
20
|
+
type = @model.type_for_attribute(attribute_name).type
|
|
21
|
+
case type
|
|
22
|
+
when :datetime
|
|
23
|
+
@type.timestamp
|
|
24
|
+
else
|
|
25
|
+
@type.text
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
module Super
|
|
2
|
+
class Filter
|
|
3
|
+
module Operator
|
|
4
|
+
class Definition
|
|
5
|
+
def initialize(identifier, name, filter)
|
|
6
|
+
@identifier = identifier
|
|
7
|
+
@name = name
|
|
8
|
+
@filter = filter
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
attr_reader :identifier
|
|
12
|
+
attr_reader :name
|
|
13
|
+
|
|
14
|
+
def filter(*args)
|
|
15
|
+
@filter.call(args)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
class << self
|
|
20
|
+
def registry
|
|
21
|
+
@registry ||= {}
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def range_defaults
|
|
25
|
+
[
|
|
26
|
+
registry["between"],
|
|
27
|
+
]
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def select_defaults
|
|
31
|
+
[
|
|
32
|
+
registry["eq"],
|
|
33
|
+
registry["neq"],
|
|
34
|
+
]
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def text_defaults
|
|
38
|
+
[
|
|
39
|
+
registry["eq"],
|
|
40
|
+
registry["neq"],
|
|
41
|
+
registry["contain"],
|
|
42
|
+
registry["ncontain"],
|
|
43
|
+
registry["start"],
|
|
44
|
+
registry["end"],
|
|
45
|
+
]
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def define(identifier, name, &filter)
|
|
49
|
+
identifier = identifier.to_s
|
|
50
|
+
name = name.to_s
|
|
51
|
+
|
|
52
|
+
definition = Definition.new(identifier, name, filter)
|
|
53
|
+
|
|
54
|
+
registry[identifier] = definition
|
|
55
|
+
|
|
56
|
+
define_singleton_method(identifier) do
|
|
57
|
+
registry[identifier]
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
define("eq", "equals") do |relation, field, query|
|
|
63
|
+
relation.where(field => query)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
define("neq", "doesn't equal") do |relation, field, query|
|
|
67
|
+
relation.where.not(field => query)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
define("contain", "contains") do |relation, field, query|
|
|
71
|
+
query = "%#{Compatability.sanitize_sql_like(query)}%"
|
|
72
|
+
relation.where("#{field} LIKE ?", "%#{query}%")
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
define("ncontain", "doesn't contain") do |relation, field, query|
|
|
76
|
+
query = "%#{Compatability.sanitize_sql_like(query)}%"
|
|
77
|
+
relation.where("#{field} NOT LIKE ?", query)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
define("start", "starts with") do |relation, field, query|
|
|
81
|
+
query = "#{Compatability.sanitize_sql_like(query)}%"
|
|
82
|
+
relation.where("#{field} LIKE ?", query)
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
define("end", "ends with") do |relation, field, query|
|
|
86
|
+
query = "%#{Compatability.sanitize_sql_like(query)}"
|
|
87
|
+
relation.where("#{field} LIKE ?", query)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
define("between", "between") do |relation, field, query0, query1|
|
|
91
|
+
if query0.present?
|
|
92
|
+
relation = relation.where("#{field} >= ?", query0)
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
if query1.present?
|
|
96
|
+
relation = relation.where("#{field} <= ?", query1)
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
relation
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
module Super
|
|
2
|
+
class Filter
|
|
3
|
+
module ControllerMethods
|
|
4
|
+
def index
|
|
5
|
+
super
|
|
6
|
+
@filter_form = controls.initialize_filtering(params: params, query_params: request.GET)
|
|
7
|
+
@records = controls.filter_records(filter_form: @filter_form, records: @records)
|
|
8
|
+
@view.asides.push(:@filter_form)
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
class Controls
|
|
14
|
+
module Optional
|
|
15
|
+
def filters_enabled?
|
|
16
|
+
true
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def filter_schema
|
|
20
|
+
Filter.new do |fields, type|
|
|
21
|
+
Filter::Guesser.new(model: model, fields: fields, type: type).call
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
module Steps
|
|
27
|
+
def initialize_filtering(params:, query_params:)
|
|
28
|
+
if filters_enabled?
|
|
29
|
+
Super::Filter::FormObject.new(
|
|
30
|
+
model: model,
|
|
31
|
+
schema: filter_schema,
|
|
32
|
+
params: params[:q],
|
|
33
|
+
url: query_params
|
|
34
|
+
)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def filter_records(filter_form:, records:)
|
|
39
|
+
if filters_enabled? && records
|
|
40
|
+
filter_form.to_search_query(records)
|
|
41
|
+
else
|
|
42
|
+
records
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
module Super
|
|
2
|
+
class Filter
|
|
3
|
+
# This schema type is used to configure the filtering form on your +#index+
|
|
4
|
+
# action.
|
|
5
|
+
#
|
|
6
|
+
# The +operators:+ keyword argument can be left out in each case. There is
|
|
7
|
+
# a default set of operators that are provided.
|
|
8
|
+
#
|
|
9
|
+
# Note: The constants under "Defined Under Namespace" are considered
|
|
10
|
+
# private.
|
|
11
|
+
#
|
|
12
|
+
# class MemberDashboard
|
|
13
|
+
# # ...
|
|
14
|
+
#
|
|
15
|
+
# def filter_schema
|
|
16
|
+
# Super::Filter.new do |fields, type|
|
|
17
|
+
# fields[:name] = type.text(operators: [
|
|
18
|
+
# Super::Filter::Operator.eq,
|
|
19
|
+
# Super::Filter::Operator.contain,
|
|
20
|
+
# Super::Filter::Operator.ncontain,
|
|
21
|
+
# Super::Filter::Operator.start,
|
|
22
|
+
# Super::Filter::Operator.end,
|
|
23
|
+
# ])
|
|
24
|
+
# fields[:rank] = type.select(collection: Member.ranks.values)
|
|
25
|
+
# fields[:position] = type.text(operators: [
|
|
26
|
+
# Super::Filter::Operator.eq,
|
|
27
|
+
# Super::Filter::Operator.neq,
|
|
28
|
+
# Super::Filter::Operator.contain,
|
|
29
|
+
# Super::Filter::Operator.ncontain,
|
|
30
|
+
# ])
|
|
31
|
+
# fields[:ship_id] = type.select(
|
|
32
|
+
# collection: Ship.all.map { |s| ["#{s.name} (Ship ##{s.id})", s.id] },
|
|
33
|
+
# )
|
|
34
|
+
# fields[:created_at] = type.timestamp
|
|
35
|
+
# fields[:updated_at] = type.timestamp
|
|
36
|
+
# end
|
|
37
|
+
# end
|
|
38
|
+
#
|
|
39
|
+
# # ...
|
|
40
|
+
# end
|
|
41
|
+
class SchemaTypes
|
|
42
|
+
class Text
|
|
43
|
+
def initialize(partial_path:, operators:)
|
|
44
|
+
@partial_path = partial_path
|
|
45
|
+
@operators = operators
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
attr_reader :operators
|
|
49
|
+
|
|
50
|
+
def to_partial_path
|
|
51
|
+
@partial_path
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def q
|
|
55
|
+
[:q]
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
class Select
|
|
60
|
+
def initialize(collection:, operators:)
|
|
61
|
+
@collection = collection
|
|
62
|
+
@operators = operators
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
attr_reader :collection
|
|
66
|
+
attr_reader :operators
|
|
67
|
+
|
|
68
|
+
def to_partial_path
|
|
69
|
+
"filter_type_select"
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def q
|
|
73
|
+
[:q]
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
class Timestamp
|
|
78
|
+
def initialize(operators:)
|
|
79
|
+
@operators = operators
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
attr_reader :operators
|
|
83
|
+
|
|
84
|
+
def to_partial_path
|
|
85
|
+
"filter_type_timestamp"
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def q
|
|
89
|
+
[:q0, :q1]
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def select(collection:, operators: Filter::Operator.select_defaults)
|
|
94
|
+
Select.new(
|
|
95
|
+
collection: collection,
|
|
96
|
+
operators: operators
|
|
97
|
+
)
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def text(operators: Filter::Operator.text_defaults)
|
|
101
|
+
Text.new(
|
|
102
|
+
partial_path: "filter_type_text",
|
|
103
|
+
operators: operators
|
|
104
|
+
)
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def timestamp(operators: Filter::Operator.range_defaults)
|
|
108
|
+
Timestamp.new(operators: operators)
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
end
|
data/lib/super/form.rb
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
module Super
|
|
2
|
+
# This schema type is used on your +#edit+ and +#new+ forms
|
|
3
|
+
#
|
|
4
|
+
# ```ruby
|
|
5
|
+
# class MembersController::Controls
|
|
6
|
+
# # ...
|
|
7
|
+
#
|
|
8
|
+
# def new_schema
|
|
9
|
+
# Super::Form.new do |fields, type|
|
|
10
|
+
# fields[:name] = type.string
|
|
11
|
+
# fields[:rank] = type.select
|
|
12
|
+
# fields[:position] = type.string
|
|
13
|
+
# fields[:ship_id] = type.select(
|
|
14
|
+
# collection: Ship.all.map { |s| ["#{s.name} (Ship ##{s.id})", s.id] },
|
|
15
|
+
# )
|
|
16
|
+
# end
|
|
17
|
+
# end
|
|
18
|
+
#
|
|
19
|
+
# # ...
|
|
20
|
+
# end
|
|
21
|
+
# ```
|
|
22
|
+
class Form
|
|
23
|
+
include Schema::Common
|
|
24
|
+
|
|
25
|
+
def initialize
|
|
26
|
+
@fields = Schema::Fields.new
|
|
27
|
+
@schema_types = SchemaTypes.new(fields: @fields)
|
|
28
|
+
yield(@fields, @schema_types)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def to_partial_path
|
|
32
|
+
"super_schema_form"
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
module Super
|
|
2
|
+
class Form
|
|
3
|
+
module FieldErrorProc
|
|
4
|
+
def error_wrapping(html_tag)
|
|
5
|
+
if Thread.current[:super_form_builder]
|
|
6
|
+
return html_tag
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
super
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
class Builder < ActionView::Helpers::FormBuilder
|
|
14
|
+
# These methods were originally defined in the following files
|
|
15
|
+
#
|
|
16
|
+
# * actionview/lib/action_view/helpers/form_helper.rb
|
|
17
|
+
# * actionview/lib/action_view/helpers/form_options_helper.rb
|
|
18
|
+
# * actionview/lib/action_view/helpers/date_helper.rb
|
|
19
|
+
%w[
|
|
20
|
+
label text_field password_field hidden_field file_field text_area
|
|
21
|
+
check_box radio_button color_field search_field telephone_field
|
|
22
|
+
date_field time_field datetime_field month_field week_field url_field
|
|
23
|
+
email_field number_field range_field
|
|
24
|
+
|
|
25
|
+
select collection_select grouped_collection_select time_zone_select
|
|
26
|
+
collection_radio_buttons collection_check_boxes
|
|
27
|
+
|
|
28
|
+
time_select datetime_select date_select
|
|
29
|
+
].each do |field_type_method|
|
|
30
|
+
class_eval(<<~RUBY, __FILE__, __LINE__ + 1)
|
|
31
|
+
def #{field_type_method}(*)
|
|
32
|
+
Thread.current[:super_form_builder] = true
|
|
33
|
+
super
|
|
34
|
+
ensure
|
|
35
|
+
Thread.current[:super_form_builder] = nil
|
|
36
|
+
end
|
|
37
|
+
RUBY
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
alias datetime_local_field datetime_field
|
|
41
|
+
alias phone_field telephone_field
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
ActionView::Helpers::Tags::Base.class_eval do
|
|
47
|
+
prepend Super::Form::FieldErrorProc
|
|
48
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
module Super
|
|
2
|
+
class Form
|
|
3
|
+
class Guesser
|
|
4
|
+
def initialize(model:, fields:, type:)
|
|
5
|
+
@model = model
|
|
6
|
+
@fields = fields
|
|
7
|
+
@type = type
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def call
|
|
11
|
+
Schema::Guesser
|
|
12
|
+
.new(model: @model, fields: @fields, type: @type)
|
|
13
|
+
.assign_type { |attribute_name| attribute_type_for(attribute_name) }
|
|
14
|
+
.reject { |attribute_name| attribute_name == "id" }
|
|
15
|
+
.reject { |attribute_name| attribute_name == "created_at" }
|
|
16
|
+
.reject { |attribute_name| attribute_name == "updated_at" }
|
|
17
|
+
.call
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
private
|
|
21
|
+
|
|
22
|
+
def attribute_type_for(attribute_name)
|
|
23
|
+
@type.string
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -1,26 +1,5 @@
|
|
|
1
1
|
module Super
|
|
2
2
|
class Form
|
|
3
|
-
# This schema type is used on your +#edit+ and +#new+ forms
|
|
4
|
-
#
|
|
5
|
-
# ```ruby
|
|
6
|
-
# class MembersController::Controls
|
|
7
|
-
# # ...
|
|
8
|
-
#
|
|
9
|
-
# def new_schema
|
|
10
|
-
# Super::Schema.new(Super::Form::SchemaTypes.new) do |fields, type|
|
|
11
|
-
# fields[:name] = type.generic("form_field_text")
|
|
12
|
-
# fields[:rank] = type.generic("form_field_select", collection: Member.ranks.keys)
|
|
13
|
-
# fields[:position] = type.generic("form_field_text")
|
|
14
|
-
# fields[:ship_id] = type.generic(
|
|
15
|
-
# "form_field_select",
|
|
16
|
-
# collection: Ship.all.map { |s| ["#{s.name} (Ship ##{s.id})", s.id] },
|
|
17
|
-
# )
|
|
18
|
-
# end
|
|
19
|
-
# end
|
|
20
|
-
#
|
|
21
|
-
# # ...
|
|
22
|
-
# end
|
|
23
|
-
# ```
|
|
24
3
|
class SchemaTypes
|
|
25
4
|
class Generic
|
|
26
5
|
def initialize(partial_path:, extras:, nested:)
|
|
@@ -31,6 +10,16 @@ module Super
|
|
|
31
10
|
|
|
32
11
|
attr_reader :nested_fields
|
|
33
12
|
|
|
13
|
+
def each_attribute
|
|
14
|
+
if block_given?
|
|
15
|
+
@nested_fields.each do |key, value|
|
|
16
|
+
yield(key, value)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
enum_for(:each_attribute)
|
|
21
|
+
end
|
|
22
|
+
|
|
34
23
|
# This takes advantage of a feature of Rails. If the value of
|
|
35
24
|
# `#to_partial_path` is `my_form_field`, Rails renders
|
|
36
25
|
# `app/views/super/application/_my_form_field.html.erb`, and this
|
|
@@ -69,7 +58,7 @@ module Super
|
|
|
69
58
|
end
|
|
70
59
|
end
|
|
71
60
|
|
|
72
|
-
def
|
|
61
|
+
def initialize(fields:)
|
|
73
62
|
@fields = fields
|
|
74
63
|
end
|
|
75
64
|
|
|
@@ -77,6 +66,24 @@ module Super
|
|
|
77
66
|
Generic.new(partial_path: partial_path, extras: extras, nested: {})
|
|
78
67
|
end
|
|
79
68
|
|
|
69
|
+
def select(**extras)
|
|
70
|
+
Generic.new(partial_path: "form_field_select", extras: extras, nested: {})
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def string(**extras)
|
|
74
|
+
Generic.new(partial_path: "form_field_text", extras: extras, nested: {})
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
alias text string
|
|
78
|
+
|
|
79
|
+
def rich_text_area(**extras)
|
|
80
|
+
Generic.new(partial_path: "form_field_rich_text_area", extras: extras, nested: {})
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def checkbox(**extras)
|
|
84
|
+
Generic.new(partial_path: "form_field_checkbox", extras: extras, nested: {})
|
|
85
|
+
end
|
|
86
|
+
|
|
80
87
|
def has_many(reader, **extras)
|
|
81
88
|
nested = @fields.nested do
|
|
82
89
|
yield
|