super 0.0.5 → 0.0.10

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.
Files changed (113) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +4 -1
  3. data/CONTRIBUTING.md +56 -0
  4. data/README.md +68 -38
  5. data/STABILITY.md +50 -0
  6. data/app/assets/javascripts/super/application.js +1170 -359
  7. data/app/assets/stylesheets/super/application.css +78105 -50441
  8. data/app/controllers/super/application_controller.rb +44 -52
  9. data/app/helpers/super/form_builder_helper.rb +23 -0
  10. data/app/views/layouts/super/application.html.erb +26 -6
  11. data/app/views/super/application/{_resources_header.html.erb → _collection_header.html.erb} +5 -6
  12. data/app/views/super/application/_display_rich_text.html.erb +1 -0
  13. data/app/views/super/application/_filter.html.erb +14 -0
  14. data/app/views/super/application/_filter_type_select.html.erb +18 -0
  15. data/app/views/super/application/_filter_type_text.html.erb +16 -0
  16. data/app/views/super/application/_filter_type_timestamp.html.erb +23 -0
  17. data/app/views/super/application/_flash.html.erb +13 -13
  18. data/app/views/super/application/_form_field__destroy.html.erb +1 -9
  19. data/app/views/super/application/_form_field_checkbox.html.erb +1 -0
  20. data/app/views/super/application/_form_field_rich_text_area.html.erb +1 -0
  21. data/app/views/super/application/_form_field_select.html.erb +1 -23
  22. data/app/views/super/application/_form_field_text.html.erb +1 -13
  23. data/app/views/super/application/_form_has_many.html.erb +1 -1
  24. data/app/views/super/application/{_resource_header.html.erb → _member_header.html.erb} +6 -6
  25. data/app/views/super/application/_super_layout.html.erb +12 -17
  26. data/app/views/super/application/_super_pagination.html.erb +16 -0
  27. data/app/views/super/application/_super_panel.html.erb +3 -7
  28. data/app/views/super/application/_super_schema_display_actions.html.erb +5 -0
  29. data/app/views/super/application/_super_schema_display_index.html.erb +24 -0
  30. data/app/views/super/application/_super_schema_display_show.html.erb +8 -0
  31. data/app/views/super/application/_super_schema_form.html.erb +15 -0
  32. data/app/views/super/application/edit.html.erb +2 -6
  33. data/app/views/super/application/index.html.erb +2 -6
  34. data/app/views/super/application/new.html.erb +2 -6
  35. data/app/views/super/application/show.html.erb +2 -6
  36. data/app/views/super/feather/{_chevron_down.svg → _chevron_down.html} +0 -0
  37. data/config/locales/en.yml +5 -0
  38. data/docs/README.md +4 -2
  39. data/docs/action_text.md +48 -0
  40. data/docs/cheat.md +41 -0
  41. data/docs/faq.md +3 -3
  42. data/docs/installation.md +21 -0
  43. data/docs/quick_start.md +1 -16
  44. data/docs/webpacker.md +13 -5
  45. data/frontend/super-frontend/dist/application.css +78105 -50441
  46. data/frontend/super-frontend/dist/application.js +1170 -359
  47. data/lib/generators/super/action_text/USAGE +23 -0
  48. data/lib/generators/super/action_text/action_text_generator.rb +30 -0
  49. data/lib/generators/super/action_text/templates/pack_super_action_text.css +23 -0
  50. data/lib/generators/super/action_text/templates/pack_super_action_text.js +4 -0
  51. data/lib/generators/super/install/install_generator.rb +16 -0
  52. data/lib/generators/super/resource/templates/resources_controller.rb.tt +1 -31
  53. data/lib/generators/super/webpacker/USAGE +5 -4
  54. data/lib/generators/super/webpacker/webpacker_generator.rb +3 -2
  55. data/lib/super.rb +21 -3
  56. data/lib/super/action_inquirer.rb +2 -2
  57. data/lib/super/assets.rb +112 -38
  58. data/lib/super/client_error.rb +43 -0
  59. data/lib/super/compatibility.rb +13 -1
  60. data/lib/super/configuration.rb +21 -69
  61. data/lib/super/controls.rb +9 -116
  62. data/lib/super/controls/optional.rb +79 -0
  63. data/lib/super/controls/required.rb +13 -0
  64. data/lib/super/controls/steps.rb +114 -0
  65. data/lib/super/display.rb +66 -3
  66. data/lib/super/display/guesser.rb +34 -0
  67. data/lib/super/display/schema_types.rb +61 -25
  68. data/lib/super/engine.rb +9 -1
  69. data/lib/super/error.rb +17 -9
  70. data/lib/super/filter.rb +12 -0
  71. data/lib/super/filter/form_object.rb +97 -0
  72. data/lib/super/filter/guesser.rb +30 -0
  73. data/lib/super/filter/operator.rb +103 -0
  74. data/lib/super/filter/plugin.rb +47 -0
  75. data/lib/super/filter/schema_types.rb +112 -0
  76. data/lib/super/form.rb +35 -0
  77. data/lib/super/form/builder.rb +204 -0
  78. data/lib/super/form/guesser.rb +27 -0
  79. data/lib/super/form/inline_errors.rb +26 -0
  80. data/lib/super/form/schema_types.rb +29 -22
  81. data/lib/super/form/strong_params.rb +29 -0
  82. data/lib/super/layout.rb +28 -0
  83. data/lib/super/link.rb +55 -32
  84. data/lib/super/pagination.rb +55 -0
  85. data/lib/super/panel.rb +13 -0
  86. data/lib/super/partial.rb +12 -0
  87. data/lib/super/partial/resolving.rb +24 -0
  88. data/lib/super/plugin.rb +34 -63
  89. data/lib/super/schema.rb +12 -22
  90. data/lib/super/schema/common.rb +25 -0
  91. data/lib/super/schema/guesser.rb +77 -0
  92. data/lib/super/version.rb +1 -1
  93. data/lib/super/view_helper.rb +1 -20
  94. metadata +90 -33
  95. data/app/helpers/super/application_helper.rb +0 -32
  96. data/app/views/super/application/_form.html.erb +0 -17
  97. data/app/views/super/application/_form_inline_errors.html.erb +0 -10
  98. data/app/views/super/application/_index.html.erb +0 -45
  99. data/app/views/super/application/_show.html.erb +0 -10
  100. data/docs/controls.md +0 -39
  101. data/frontend/super-frontend/build.js +0 -36
  102. data/frontend/super-frontend/package.json +0 -21
  103. data/frontend/super-frontend/postcss.config.js +0 -6
  104. data/frontend/super-frontend/src/javascripts/super/application.ts +0 -18
  105. data/frontend/super-frontend/src/javascripts/super/apply_template_controller.ts +0 -21
  106. data/frontend/super-frontend/src/javascripts/super/rails__ujs.d.ts +0 -1
  107. data/frontend/super-frontend/src/javascripts/super/toggle_pending_destruction_controller.ts +0 -15
  108. data/frontend/super-frontend/src/stylesheets/super/application.css +0 -77
  109. data/frontend/super-frontend/tailwind.config.js +0 -9
  110. data/frontend/super-frontend/tsconfig.json +0 -13
  111. data/frontend/super-frontend/yarn.lock +0 -5540
  112. data/lib/super/step.rb +0 -36
  113. data/lib/tasks/super_tasks.rake +0 -4
@@ -2,12 +2,24 @@ module Super
2
2
  module Compatability
3
3
  module_function
4
4
 
5
- def rails_50_errable_fields(field)
5
+ # Rails 5.1 and after lets you find field errors using either a string or a
6
+ # symbol.
7
+ def errable_fields(field)
6
8
  if Rails::VERSION::MAJOR == 5 && Rails::VERSION::MINOR == 0
7
9
  [field.to_s, field.to_sym]
8
10
  else
9
11
  field
10
12
  end
11
13
  end
14
+
15
+ def sanitize_sql_like(query)
16
+ if ActiveRecord::VERSION::MAJOR == 4
17
+ ActiveRecord::Base.send(:sanitize_sql_like, query)
18
+ elsif ActiveRecord::VERSION::MAJOR == 5 && ActiveRecord::VERSION::MINOR <= 1
19
+ ActiveRecord::Base.send(:sanitize_sql_like, query)
20
+ else
21
+ ActiveRecord::Base.sanitize_sql_like(query)
22
+ end
23
+ end
12
24
  end
13
25
  end
@@ -19,81 +19,33 @@ module Super
19
19
  # end
20
20
  # ```
21
21
  class Configuration
22
- module ConfigurationLogic # @api private
23
- def self.included(base)
24
- base.extend(ClassMethods)
25
- end
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
- def initialize
28
- self.class.defaults.each do |key, value|
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
- public_send("#{key}=", value)
34
- end
35
- end
36
-
37
- def configured?(attr)
38
- instance_variable_defined?("@#{attr}")
39
- end
40
-
41
- module ClassMethods
42
- def defaults
43
- @defaults ||= {}
44
- end
45
-
46
- def wraps
47
- @wraps ||= {}
48
- end
49
-
50
- def configure(attr, wrap: nil, enum: nil, **kwargs)
51
- if kwargs.key?(:default)
52
- defaults[attr] = kwargs[:default]
53
- end
54
-
55
- define_method(attr) do
56
- if !configured?(attr)
57
- raise Error::UnconfiguredConfiguration, "unconfigured: #{attr}"
58
- end
59
-
60
- result = instance_variable_get("@#{attr}")
61
-
62
- if wrap.nil?
63
- result
64
- else
65
- wrap.call(result)
66
- end
67
- end
68
-
69
- define_method("#{attr}=") do |value|
70
- if enum.is_a?(Array)
71
- if !enum.include?(value)
72
- raise Error::InvalidConfiguration,
73
- "tried to set `#{attr}` to `#{value.inspect}`, " \
74
- "expected: #{enum.join(", ")}"
75
- end
76
- end
31
+ self.javascripts = [Super::Assets.auto("super/application")]
32
+ self.stylesheets = [Super::Assets.auto("super/application")]
33
+ end
77
34
 
78
- instance_variable_set("@#{attr}", value)
79
- value
80
- end
81
- end
82
- end
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
83
41
  end
84
42
 
85
- include ConfigurationLogic
43
+ attr_accessor :javascripts
44
+ attr_accessor :stylesheets
86
45
 
87
- # @!attribute [rw]
88
- configure :title
89
- # @!attribute [rw]
90
- configure :index_resources_per_page, default: 20
91
- # @!attribute [rw]
92
- configure :controller_namespace, default: "admin"
93
- # @!attribute [rw]
94
- configure :route_namespace, default: :admin, wrap: -> (val) { [val].flatten }
95
- # @!attribute [rw]
96
- configure :asset_handler, default: -> { Super::Assets.auto }
46
+ def controller_plugins
47
+ Plugin::Registry.controller
48
+ end
97
49
 
98
50
  # @api private
99
51
  def path_parts(*parts)
@@ -1,120 +1,13 @@
1
+ require "super/controls/optional"
2
+ require "super/controls/required"
3
+ require "super/controls/steps"
4
+
1
5
  module Super
2
- # A wrapper around the per-controller Controls classes. This class often
3
- # directly delegates to the per-controller classes, but it can also provide
4
- # some default implementation.
6
+ # The base Controls class. Most parts of Super can be configured by
7
+ # customizing its methods.
5
8
  class Controls
6
- def initialize(actual)
7
- @actual = actual
8
- end
9
-
10
- attr_reader :actual
11
-
12
- # This is an optional method
13
- #
14
- # @return [String]
15
- def title
16
- if @actual.respond_to?(:title)
17
- return @actual.title
18
- end
19
-
20
- model.name.pluralize
21
- end
22
-
23
- # Specifies the model. This is a required method
24
- #
25
- # @return [ActiveRecord::Base]
26
- def model
27
- @actual.model
28
- end
29
-
30
- # Configures the actions linked to on the index page. This is an optional
31
- # method
32
- #
33
- # @param params [ActionController::Parameters]
34
- # @param action [ActionInquirer]
35
- # @return [Array<Link>]
36
- def resources_actions(params:, action:)
37
- actions =
38
- if @actual.respond_to?(:resources_actions)
39
- @actual.resources_actions(params: params, action: action)
40
- else
41
- [:new]
42
- end
43
-
44
- actions.map do |link|
45
- link = Link.resolve(link)
46
-
47
- link.call(params: params)
48
- end
49
- end
50
-
51
- # Configures the actions linked to on the show page as well as each row of
52
- # the table on the index page. This is an optional method
53
- #
54
- # @param resource [ActiveRecord::Base]
55
- # @param params [ActionController::Parameters]
56
- # @param action [ActionInquirer]
57
- # @return [Array<Link>]
58
- def resource_actions(resource, params:, action:)
59
- actions =
60
- if @actual.respond_to?(:resource_actions)
61
- @actual.resource_actions(resource, params: params, action: action)
62
- else
63
- if action.show?
64
- [:edit, :destroy]
65
- elsif action.edit?
66
- [:show, :destroy]
67
- else
68
- [:show, :edit, :destroy]
69
- end
70
- end
71
-
72
- actions.map do |link|
73
- link = Link.resolve(link)
74
-
75
- link.call(resource, params: params)
76
- end
77
- end
78
-
79
- # Configures what database records are visible on load. This is an optional
80
- # method, it defaults to "`all`" methods
81
- #
82
- # @param action [ActionInquirer]
83
- # @return [ActiveRecord::Relation]
84
- def scope(action:)
85
- if @actual.respond_to?(:scope)
86
- return @actual.scope(action: action)
87
- end
88
-
89
- model.all
90
- end
91
-
92
- # Configures which parameters could be written to the database. This is a
93
- # required method
94
- #
95
- # @param params [ActionController::Parameters]
96
- # @param action [ActionInquirer]
97
- # @return [ActionController::Parameters]
98
- def permitted_params(params, action:)
99
- @actual.permitted_params(params, action: action)
100
- end
101
-
102
- # Configures the fields that are displayed on the index and show actions.
103
- # This is a required method
104
- #
105
- # @param action [ActionInquirer]
106
- # @return [Schema]
107
- def display_schema(action:)
108
- @actual.display_schema(action: action)
109
- end
110
-
111
- # Configures the editable fields on the new and edit actions. This is a
112
- # required method
113
- #
114
- # @param action [ActionInquirer]
115
- # @return [Schema]
116
- def form_schema(action:)
117
- @actual.form_schema(action: action)
118
- end
9
+ include Required
10
+ include Optional
11
+ include Steps
119
12
  end
120
13
  end
@@ -0,0 +1,79 @@
1
+ module Super
2
+ class Controls
3
+ # Methods for `Controls` that have a sane default implementation
4
+ module Optional
5
+ # This is an optional method
6
+ #
7
+ # @return [String]
8
+ def title
9
+ model.name.pluralize
10
+ end
11
+
12
+ # Configures what database records are visible on load. This is an optional
13
+ # method, it defaults to "`all`" methods
14
+ #
15
+ # @param action [ActionInquirer]
16
+ # @return [ActiveRecord::Relation]
17
+ def scope(action:)
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
29
+ end
30
+ end
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
+
54
+ # Configures the actions linked to on the index page. This is an optional
55
+ # method
56
+ #
57
+ # @param action [ActionInquirer]
58
+ # @return [Array<Link>]
59
+ def collection_actions(action:)
60
+ Super::Link.find_all(:new)
61
+ end
62
+
63
+ # Configures the actions linked to on the show page as well as each row of
64
+ # the table on the index page. This is an optional method
65
+ #
66
+ # @param action [ActionInquirer]
67
+ # @return [Array<Link>]
68
+ def member_actions(action:)
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)
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,13 @@
1
+ module Super
2
+ class Controls
3
+ # Methods for `Controls` that must be defined for Super to work properly
4
+ module Required
5
+ # Specifies the model. This is a required method
6
+ #
7
+ # @return [ActiveRecord::Base]
8
+ def model
9
+ raise NotImplementedError
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,114 @@
1
+ module Super
2
+ class Controls
3
+ # Methods that are called by controller actions. All of these methods have
4
+ # a default implementation, but feel free to override as needed.
5
+ module Steps
6
+ # Tells the controller how to load records in the index action using
7
+ # `#scope`
8
+ #
9
+ # @param action [ActionInquirer]
10
+ # @param params [ActionController::Parameters]
11
+ # @return [ActiveRecord::Relation]
12
+ def load_records(action:, params:)
13
+ scope(action: action)
14
+ end
15
+
16
+ # Loads a record using `#scope`
17
+ #
18
+ # @param action [ActionInquirer]
19
+ # @param params [ActionController::Parameters]
20
+ # @return [ActiveRecord::Base]
21
+ def load_record(action:, params:)
22
+ scope(action: action).find(params[:id])
23
+ end
24
+
25
+ # Builds a record using `#scope`
26
+ #
27
+ # @param action [ActionInquirer]
28
+ # @return [ActiveRecord::Base]
29
+ def build_record(action:)
30
+ scope(action: action).build
31
+ end
32
+
33
+ # Builds and populates a record using `#scope`
34
+ #
35
+ # @param action [ActionInquirer]
36
+ # @param params [ActionController::Parameters]
37
+ # @return [ActiveRecord::Base]
38
+ def build_record_with_params(action:, params:)
39
+ scope(action: action).build(permitted_params(params, action: action))
40
+ end
41
+
42
+ # Saves a record
43
+ #
44
+ # @param action [ActionInquirer]
45
+ # @param params [ActionController::Parameters]
46
+ # @return [true, false]
47
+ def save_record(action:, record:, params:)
48
+ record.save
49
+ end
50
+
51
+ # Saves a record
52
+ #
53
+ # @param action [ActionInquirer]
54
+ # @param params [ActionController::Parameters]
55
+ # @return [true, false]
56
+ def update_record(action:, record:, params:)
57
+ record.update(permitted_params(params, action: action))
58
+ end
59
+
60
+ # Destroys a record
61
+ #
62
+ # @param action [ActionInquirer]
63
+ # @param params [ActionController::Parameters]
64
+ # @return [ActiveRecord::Base, false]
65
+ def destroy_record(action:, record:, params:)
66
+ record.destroy
67
+ end
68
+
69
+ def build_index_view
70
+ Super::Layout.new(
71
+ mains: [
72
+ Super::Panel.new(
73
+ Super::Partial.new("collection_header"),
74
+ :@display
75
+ ),
76
+ ]
77
+ )
78
+ end
79
+
80
+ def build_show_view
81
+ Super::Layout.new(
82
+ mains: [
83
+ Super::Panel.new(
84
+ Super::Partial.new("member_header"),
85
+ :@display
86
+ ),
87
+ ]
88
+ )
89
+ end
90
+
91
+ def build_new_view
92
+ Super::Layout.new(
93
+ mains: [
94
+ Super::Panel.new(
95
+ Super::Partial.new("collection_header"),
96
+ :@form
97
+ ),
98
+ ]
99
+ )
100
+ end
101
+
102
+ def build_edit_view
103
+ Super::Layout.new(
104
+ mains: [
105
+ Super::Panel.new(
106
+ Super::Partial.new("member_header"),
107
+ :@form
108
+ ),
109
+ ]
110
+ )
111
+ end
112
+ end
113
+ end
114
+ end