super 0.0.7 → 0.0.8
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/CONTRIBUTING.md +56 -0
- data/README.md +6 -0
- data/STABILITY.md +50 -0
- data/app/assets/javascripts/super/application.js +12 -7
- data/app/controllers/super/application_controller.rb +1 -1
- data/app/views/layouts/super/application.html.erb +14 -6
- data/app/views/super/application/_super_panel.html.erb +1 -1
- data/app/views/super/application/_super_schema_display_index.html.erb +4 -4
- data/app/views/super/application/_super_schema_display_show.html.erb +3 -3
- data/app/views/super/application/_super_schema_form.html.erb +1 -1
- data/frontend/super-frontend/dist/application.js +12 -7
- data/frontend/super-frontend/src/javascripts/super/application.ts +5 -8
- data/lib/generators/super/resource/templates/resources_controller.rb.tt +1 -31
- data/lib/generators/super/webpacker/webpacker_generator.rb +3 -2
- data/lib/super.rb +11 -0
- data/lib/super/assets.rb +108 -38
- data/lib/super/configuration.rb +18 -73
- data/lib/super/controls.rb +2 -25
- data/lib/super/controls/optional.rb +41 -16
- data/lib/super/controls/required.rb +1 -29
- data/lib/super/controls/steps.rb +9 -23
- data/lib/super/display.rb +72 -0
- data/lib/super/display/guesser.rb +34 -0
- data/lib/super/display/schema_types.rb +19 -62
- data/lib/super/engine.rb +1 -1
- data/lib/super/filter.rb +5 -130
- data/lib/super/filter/form_object.rb +97 -0
- data/lib/super/filter/guesser.rb +30 -0
- data/lib/super/filter/plugin.rb +47 -0
- data/lib/super/filter/schema_types.rb +1 -7
- data/lib/super/form.rb +27 -40
- data/lib/super/form/builder.rb +48 -0
- data/lib/super/form/guesser.rb +27 -0
- data/lib/super/form/schema_types.rb +19 -29
- data/lib/super/form/strong_params.rb +29 -0
- data/lib/super/pagination.rb +10 -16
- data/lib/super/schema.rb +0 -25
- data/lib/super/schema/common.rb +25 -0
- data/lib/super/schema/guesser.rb +77 -0
- data/lib/super/version.rb +1 -1
- metadata +14 -2
data/lib/super/configuration.rb
CHANGED
@@ -19,84 +19,29 @@ module Super
|
|
19
19
|
# end
|
20
20
|
# ```
|
21
21
|
class Configuration
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
22
|
+
def initialize
|
23
|
+
self.title = "Super Admin"
|
24
|
+
self.index_records_per_page = 20
|
25
|
+
self.controller_namespace = "admin"
|
26
|
+
self.route_namespace = :admin
|
26
27
|
|
27
|
-
|
28
|
-
|
29
|
-
if value.respond_to?(:call)
|
30
|
-
value = value.call
|
31
|
-
end
|
28
|
+
controller_plugins.use(prepend: Super::Filter::ControllerMethods)
|
29
|
+
controller_plugins.use(prepend: Super::Pagination::ControllerMethods)
|
32
30
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
Plugin::Registry.controller.use(prepend: Super::Filter::ControllerMethods)
|
37
|
-
Plugin::Registry.controller.use(prepend: Super::Pagination::ControllerMethods)
|
38
|
-
end
|
39
|
-
|
40
|
-
def configured?(attr)
|
41
|
-
instance_variable_defined?("@#{attr}")
|
42
|
-
end
|
43
|
-
|
44
|
-
module ClassMethods
|
45
|
-
def defaults
|
46
|
-
@defaults ||= {}
|
47
|
-
end
|
48
|
-
|
49
|
-
def wraps
|
50
|
-
@wraps ||= {}
|
51
|
-
end
|
52
|
-
|
53
|
-
def configure(attr, wrap: nil, enum: nil, **kwargs)
|
54
|
-
if kwargs.key?(:default)
|
55
|
-
defaults[attr] = kwargs[:default]
|
56
|
-
end
|
57
|
-
|
58
|
-
define_method(attr) do
|
59
|
-
if !configured?(attr)
|
60
|
-
raise Error::UnconfiguredConfiguration, "unconfigured: #{attr}"
|
61
|
-
end
|
62
|
-
|
63
|
-
result = instance_variable_get("@#{attr}")
|
64
|
-
|
65
|
-
if wrap.nil?
|
66
|
-
result
|
67
|
-
else
|
68
|
-
wrap.call(result)
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
define_method("#{attr}=") do |value|
|
73
|
-
if enum.is_a?(Array)
|
74
|
-
if !enum.include?(value)
|
75
|
-
raise Error::InvalidConfiguration,
|
76
|
-
"tried to set `#{attr}` to `#{value.inspect}`, " \
|
77
|
-
"expected: #{enum.join(", ")}"
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
instance_variable_set("@#{attr}", value)
|
82
|
-
value
|
83
|
-
end
|
84
|
-
end
|
85
|
-
end
|
31
|
+
self.javascripts = [Super::Assets.auto("super/application")]
|
32
|
+
self.stylesheets = [Super::Assets.auto("super/application")]
|
86
33
|
end
|
87
34
|
|
88
|
-
|
35
|
+
attr_accessor :title
|
36
|
+
attr_accessor :index_records_per_page
|
37
|
+
attr_accessor :controller_namespace
|
38
|
+
attr_writer :route_namespace
|
39
|
+
def route_namespace
|
40
|
+
[@route_namespace].flatten
|
41
|
+
end
|
89
42
|
|
90
|
-
|
91
|
-
|
92
|
-
# @!attribute [rw]
|
93
|
-
configure :index_records_per_page, default: 20
|
94
|
-
# @!attribute [rw]
|
95
|
-
configure :controller_namespace, default: "admin"
|
96
|
-
# @!attribute [rw]
|
97
|
-
configure :route_namespace, default: :admin, wrap: -> (val) { [val].flatten }
|
98
|
-
# @!attribute [rw]
|
99
|
-
configure :asset_handler, default: -> { Super::Assets.auto }
|
43
|
+
attr_accessor :javascripts
|
44
|
+
attr_accessor :stylesheets
|
100
45
|
|
101
46
|
def controller_plugins
|
102
47
|
Plugin::Registry.controller
|
data/lib/super/controls.rb
CHANGED
@@ -3,34 +3,11 @@ require "super/controls/required"
|
|
3
3
|
require "super/controls/steps"
|
4
4
|
|
5
5
|
module Super
|
6
|
-
#
|
7
|
-
#
|
8
|
-
# some default implementation.
|
6
|
+
# The base Controls class. Most parts of Super can be configured by
|
7
|
+
# customizing its methods.
|
9
8
|
class Controls
|
10
9
|
include Required
|
11
10
|
include Optional
|
12
11
|
include Steps
|
13
|
-
|
14
|
-
def initialize(actual)
|
15
|
-
@actual = actual
|
16
|
-
end
|
17
|
-
|
18
|
-
attr_reader :actual
|
19
|
-
|
20
|
-
private
|
21
|
-
|
22
|
-
def default_for(method_name, *args, **kwargs)
|
23
|
-
if @actual.respond_to?(method_name)
|
24
|
-
if args.empty? && kwargs.empty?
|
25
|
-
return @actual.public_send(method_name)
|
26
|
-
elsif args.empty?
|
27
|
-
return @actual.public_send(method_name, **kwargs)
|
28
|
-
else
|
29
|
-
return @actual.public_send(method_name, *args)
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
yield
|
34
|
-
end
|
35
12
|
end
|
36
13
|
end
|
@@ -6,9 +6,7 @@ module Super
|
|
6
6
|
#
|
7
7
|
# @return [String]
|
8
8
|
def title
|
9
|
-
|
10
|
-
model.name.pluralize
|
11
|
-
end
|
9
|
+
model.name.pluralize
|
12
10
|
end
|
13
11
|
|
14
12
|
# Configures what database records are visible on load. This is an optional
|
@@ -17,20 +15,49 @@ module Super
|
|
17
15
|
# @param action [ActionInquirer]
|
18
16
|
# @return [ActiveRecord::Relation]
|
19
17
|
def scope(action:)
|
20
|
-
|
21
|
-
|
18
|
+
model.all
|
19
|
+
end
|
20
|
+
|
21
|
+
# Configures the fields that are displayed on the index and show actions.
|
22
|
+
# This is a required method
|
23
|
+
#
|
24
|
+
# @param action [ActionInquirer]
|
25
|
+
# @return [Display]
|
26
|
+
def display_schema(action:)
|
27
|
+
Display.new(action: action) do |fields, type|
|
28
|
+
Display::Guesser.new(model: model, action: action, fields: fields, type: type).call
|
22
29
|
end
|
23
30
|
end
|
24
31
|
|
32
|
+
# Configures the editable fields on the new and edit actions. This is a
|
33
|
+
# required method
|
34
|
+
#
|
35
|
+
# @param action [ActionInquirer]
|
36
|
+
# @return [Form]
|
37
|
+
def form_schema(action:)
|
38
|
+
Form.new do |fields, type|
|
39
|
+
Form::Guesser.new(model: model, fields: fields, type: type).call
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# Configures which parameters could be written to the database. This is a
|
44
|
+
# required method
|
45
|
+
#
|
46
|
+
# @param params [ActionController::Parameters]
|
47
|
+
# @param action [ActionInquirer]
|
48
|
+
# @return [ActionController::Parameters]
|
49
|
+
def permitted_params(params, action:)
|
50
|
+
strong_params = Super::Form::StrongParams.new(form_schema(action: action))
|
51
|
+
params.require(strong_params.require(model)).permit(strong_params.permit)
|
52
|
+
end
|
53
|
+
|
25
54
|
# Configures the actions linked to on the index page. This is an optional
|
26
55
|
# method
|
27
56
|
#
|
28
57
|
# @param action [ActionInquirer]
|
29
58
|
# @return [Array<Link>]
|
30
59
|
def collection_actions(action:)
|
31
|
-
|
32
|
-
Super::Link.find_all(:new)
|
33
|
-
end
|
60
|
+
Super::Link.find_all(:new)
|
34
61
|
end
|
35
62
|
|
36
63
|
# Configures the actions linked to on the show page as well as each row of
|
@@ -39,14 +66,12 @@ module Super
|
|
39
66
|
# @param action [ActionInquirer]
|
40
67
|
# @return [Array<Link>]
|
41
68
|
def member_actions(action:)
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
Super::Link.find_all(:show, :edit, :destroy)
|
49
|
-
end
|
69
|
+
if action.show?
|
70
|
+
Super::Link.find_all(:edit, :destroy)
|
71
|
+
elsif action.edit?
|
72
|
+
Super::Link.find_all(:show, :destroy)
|
73
|
+
else
|
74
|
+
Super::Link.find_all(:show, :edit, :destroy)
|
50
75
|
end
|
51
76
|
end
|
52
77
|
end
|
@@ -6,35 +6,7 @@ module Super
|
|
6
6
|
#
|
7
7
|
# @return [ActiveRecord::Base]
|
8
8
|
def model
|
9
|
-
|
10
|
-
end
|
11
|
-
|
12
|
-
# Configures which parameters could be written to the database. This is a
|
13
|
-
# required method
|
14
|
-
#
|
15
|
-
# @param params [ActionController::Parameters]
|
16
|
-
# @param action [ActionInquirer]
|
17
|
-
# @return [ActionController::Parameters]
|
18
|
-
def permitted_params(params, action:)
|
19
|
-
@actual.permitted_params(params, action: action)
|
20
|
-
end
|
21
|
-
|
22
|
-
# Configures the fields that are displayed on the index and show actions.
|
23
|
-
# This is a required method
|
24
|
-
#
|
25
|
-
# @param action [ActionInquirer]
|
26
|
-
# @return [Schema]
|
27
|
-
def display_schema(action:)
|
28
|
-
@actual.display_schema(action: action)
|
29
|
-
end
|
30
|
-
|
31
|
-
# Configures the editable fields on the new and edit actions. This is a
|
32
|
-
# required method
|
33
|
-
#
|
34
|
-
# @param action [ActionInquirer]
|
35
|
-
# @return [Schema]
|
36
|
-
def form_schema(action:)
|
37
|
-
@actual.form_schema(action: action)
|
9
|
+
raise NotImplementedError
|
38
10
|
end
|
39
11
|
end
|
40
12
|
end
|
data/lib/super/controls/steps.rb
CHANGED
@@ -10,9 +10,7 @@ module Super
|
|
10
10
|
# @param params [ActionController::Parameters]
|
11
11
|
# @return [ActiveRecord::Relation]
|
12
12
|
def load_records(action:, params:)
|
13
|
-
|
14
|
-
scope(action: action)
|
15
|
-
end
|
13
|
+
scope(action: action)
|
16
14
|
end
|
17
15
|
|
18
16
|
# Loads a record using `#scope`
|
@@ -21,9 +19,7 @@ module Super
|
|
21
19
|
# @param params [ActionController::Parameters]
|
22
20
|
# @return [ActiveRecord::Base]
|
23
21
|
def load_record(action:, params:)
|
24
|
-
|
25
|
-
scope(action: action).find(params[:id])
|
26
|
-
end
|
22
|
+
scope(action: action).find(params[:id])
|
27
23
|
end
|
28
24
|
|
29
25
|
# Builds a record using `#scope`
|
@@ -31,9 +27,7 @@ module Super
|
|
31
27
|
# @param action [ActionInquirer]
|
32
28
|
# @return [ActiveRecord::Base]
|
33
29
|
def build_record(action:)
|
34
|
-
|
35
|
-
scope(action: action).build
|
36
|
-
end
|
30
|
+
scope(action: action).build
|
37
31
|
end
|
38
32
|
|
39
33
|
# Builds and populates a record using `#scope`
|
@@ -42,31 +36,25 @@ module Super
|
|
42
36
|
# @param params [ActionController::Parameters]
|
43
37
|
# @return [ActiveRecord::Base]
|
44
38
|
def build_record_with_params(action:, params:)
|
45
|
-
|
46
|
-
scope(action: action).build(permitted_params(params, action: action))
|
47
|
-
end
|
39
|
+
scope(action: action).build(permitted_params(params, action: action))
|
48
40
|
end
|
49
41
|
|
50
42
|
# Saves a record
|
51
43
|
#
|
52
44
|
# @param action [ActionInquirer]
|
53
45
|
# @param params [ActionController::Parameters]
|
54
|
-
# @return [
|
46
|
+
# @return [true, false]
|
55
47
|
def save_record(action:, record:, params:)
|
56
|
-
|
57
|
-
record.save
|
58
|
-
end
|
48
|
+
record.save
|
59
49
|
end
|
60
50
|
|
61
51
|
# Saves a record
|
62
52
|
#
|
63
53
|
# @param action [ActionInquirer]
|
64
54
|
# @param params [ActionController::Parameters]
|
65
|
-
# @return [
|
55
|
+
# @return [true, false]
|
66
56
|
def update_record(action:, record:, params:)
|
67
|
-
|
68
|
-
record.update(permitted_params(params, action: action))
|
69
|
-
end
|
57
|
+
record.update(permitted_params(params, action: action))
|
70
58
|
end
|
71
59
|
|
72
60
|
# Destroys a record
|
@@ -75,9 +63,7 @@ module Super
|
|
75
63
|
# @param params [ActionController::Parameters]
|
76
64
|
# @return [ActiveRecord::Base, false]
|
77
65
|
def destroy_record(action:, record:, params:)
|
78
|
-
|
79
|
-
record.destroy
|
80
|
-
end
|
66
|
+
record.destroy
|
81
67
|
end
|
82
68
|
|
83
69
|
def build_index_view
|
@@ -0,0 +1,72 @@
|
|
1
|
+
module Super
|
2
|
+
# This schema type is meant to be used for +#index+ or +#show+ actions to
|
3
|
+
# transform database fields into something that is human friendly.
|
4
|
+
#
|
5
|
+
# ```
|
6
|
+
# class MembersController::Controls
|
7
|
+
# # ...
|
8
|
+
#
|
9
|
+
# def show_schema
|
10
|
+
# Super::Display.new do |fields, type|
|
11
|
+
# fields[:name] = type.manual { |name| name }
|
12
|
+
# fields[:rank] = type.manual { |rank| rank }
|
13
|
+
# fields[:position] = type.manual { |position| position }
|
14
|
+
# fields[:ship] = type.manual { |ship| "#{ship.name} (Ship ##{ship.id})" }
|
15
|
+
# fields[:created_at] = type.manual { |created_at| created_at.iso8601 }
|
16
|
+
# fields[:updated_at] = type.manual { |updated_at| updated_at.iso8601 }
|
17
|
+
# end
|
18
|
+
# end
|
19
|
+
#
|
20
|
+
# # ...
|
21
|
+
# end
|
22
|
+
# ```
|
23
|
+
class Display
|
24
|
+
include Schema::Common
|
25
|
+
|
26
|
+
def initialize(action:)
|
27
|
+
@action_inquirer = action
|
28
|
+
@fields = Super::Schema::Fields.new
|
29
|
+
@schema_types = SchemaTypes.new(fields: @fields)
|
30
|
+
|
31
|
+
yield(@fields, @schema_types)
|
32
|
+
|
33
|
+
return if !@action_inquirer.index?
|
34
|
+
return if @schema_types.actions_called?
|
35
|
+
@fields[:actions] = @schema_types.actions
|
36
|
+
end
|
37
|
+
|
38
|
+
def to_partial_path
|
39
|
+
if @action_inquirer.index?
|
40
|
+
"super_schema_display_index"
|
41
|
+
elsif @action_inquirer.show?
|
42
|
+
"super_schema_display_show"
|
43
|
+
else
|
44
|
+
"super_schema_display_#{@action_inquirer.action}"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# @private
|
49
|
+
def render_field(template:, record:, column:)
|
50
|
+
formatter = @fields[column]
|
51
|
+
|
52
|
+
formatted =
|
53
|
+
if formatter.real?
|
54
|
+
value = record.public_send(column)
|
55
|
+
formatter.present(value)
|
56
|
+
else
|
57
|
+
formatter.present
|
58
|
+
end
|
59
|
+
|
60
|
+
if formatted.respond_to?(:to_partial_path)
|
61
|
+
if formatted.respond_to?(:locals)
|
62
|
+
formatted.locals[:record] ||= record
|
63
|
+
template.render(formatted, formatted.locals)
|
64
|
+
else
|
65
|
+
template.render(formatted)
|
66
|
+
end
|
67
|
+
else
|
68
|
+
formatted
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Super
|
2
|
+
class Display
|
3
|
+
class Guesser
|
4
|
+
def initialize(model:, action:, fields:, type:)
|
5
|
+
@model = model
|
6
|
+
@action_inquirer = action
|
7
|
+
@fields = fields
|
8
|
+
@type = type
|
9
|
+
end
|
10
|
+
|
11
|
+
def call
|
12
|
+
Schema::Guesser
|
13
|
+
.new(model: @model, fields: @fields, type: @type)
|
14
|
+
.ignore_foreign_keys
|
15
|
+
.limit { 5 if @action_inquirer.index? }
|
16
|
+
.assign_type { |attribute_name| attribute_type_for(attribute_name) }
|
17
|
+
.call
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def attribute_type_for(attribute_name)
|
23
|
+
type = @model.type_for_attribute(attribute_name).type
|
24
|
+
|
25
|
+
case type
|
26
|
+
when :datetime
|
27
|
+
@type.timestamp
|
28
|
+
else
|
29
|
+
@type.text
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|