super 0.0.1 → 0.0.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.
Files changed (111) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +11 -0
  3. data/README.md +64 -78
  4. data/Rakefile +3 -1
  5. data/app/assets/config/super_manifest.js +2 -1
  6. data/app/assets/javascripts/super/application.js +1252 -316
  7. data/app/assets/stylesheets/super/application.css +102704 -17321
  8. data/app/controllers/super/application_controller.rb +50 -42
  9. data/app/helpers/super/application_helper.rb +39 -0
  10. data/app/views/layouts/super/application.html.erb +11 -7
  11. data/app/views/super/application/_collection_header.html.erb +15 -0
  12. data/app/views/super/application/_flash.html.erb +17 -0
  13. data/app/views/super/application/_form_field__destroy.html.erb +9 -0
  14. data/app/views/super/application/_form_field_select.html.erb +23 -0
  15. data/app/views/super/application/_form_field_text.html.erb +13 -0
  16. data/app/views/super/application/_form_fieldset.html.erb +8 -0
  17. data/app/views/super/application/_form_has_many.html.erb +21 -0
  18. data/app/views/super/application/_form_has_one.html.erb +11 -0
  19. data/app/views/super/application/_form_inline_errors.html.erb +10 -0
  20. data/app/views/super/application/_member_header.html.erb +16 -0
  21. data/app/views/super/application/_super_layout.html.erb +29 -0
  22. data/app/views/super/application/_super_panel.html.erb +7 -0
  23. data/app/views/super/application/_super_schema_display_actions.html.erb +5 -0
  24. data/app/views/super/application/_super_schema_display_index.html.erb +39 -0
  25. data/app/views/super/application/_super_schema_display_show.html.erb +8 -0
  26. data/app/views/super/application/_super_schema_form.html.erb +15 -0
  27. data/app/views/super/application/edit.html.erb +4 -5
  28. data/app/views/super/application/index.html.erb +6 -1
  29. data/app/views/super/application/new.html.erb +4 -5
  30. data/app/views/super/application/nothing.html.erb +0 -0
  31. data/app/views/super/application/show.html.erb +6 -10
  32. data/app/views/super/feather/{_chevron_down.svg → _chevron_down.html} +0 -0
  33. data/config/locales/en.yml +5 -0
  34. data/docs/README.md +6 -0
  35. data/docs/cheat.md +41 -0
  36. data/docs/faq.md +44 -0
  37. data/docs/quick_start.md +45 -0
  38. data/docs/webpacker.md +17 -0
  39. data/docs/yard_customizations.rb +41 -0
  40. data/frontend/super-frontend/build.js +14 -12
  41. data/frontend/super-frontend/dist/application.css +102704 -17321
  42. data/frontend/super-frontend/dist/application.js +1252 -316
  43. data/frontend/super-frontend/package.json +11 -4
  44. data/frontend/super-frontend/postcss.config.js +4 -4
  45. data/frontend/super-frontend/src/javascripts/super/application.ts +18 -0
  46. data/frontend/super-frontend/src/javascripts/super/apply_template_controller.ts +19 -0
  47. data/frontend/super-frontend/src/javascripts/super/rails__ujs.d.ts +1 -0
  48. data/frontend/super-frontend/src/javascripts/super/toggle_pending_destruction_controller.ts +15 -0
  49. data/frontend/super-frontend/src/stylesheets/super/application.css +63 -0
  50. data/frontend/super-frontend/tailwind.config.js +12 -4
  51. data/frontend/super-frontend/tsconfig.json +13 -0
  52. data/frontend/super-frontend/yarn.lock +1891 -1798
  53. data/lib/generators/super/install/USAGE +4 -2
  54. data/lib/generators/super/install/install_generator.rb +18 -3
  55. data/lib/generators/super/resource/USAGE +1 -2
  56. data/lib/generators/super/resource/resource_generator.rb +0 -2
  57. data/lib/generators/super/resource/templates/resources_controller.rb.tt +38 -2
  58. data/lib/generators/super/webpacker/webpacker_generator.rb +8 -0
  59. data/lib/super.rb +10 -5
  60. data/lib/super/action_inquirer.rb +101 -0
  61. data/lib/super/assets.rb +1 -0
  62. data/lib/super/client_error.rb +43 -0
  63. data/lib/super/compatibility.rb +13 -0
  64. data/lib/super/configuration.rb +60 -45
  65. data/lib/super/controls.rb +26 -15
  66. data/lib/super/controls/optional.rb +65 -0
  67. data/lib/super/controls/required.rb +41 -0
  68. data/lib/super/controls/steps.rb +115 -0
  69. data/lib/super/display/schema_types.rb +60 -18
  70. data/lib/super/engine.rb +1 -0
  71. data/lib/super/error.rb +10 -1
  72. data/lib/super/form.rb +48 -0
  73. data/lib/super/form/schema_types.rb +96 -21
  74. data/lib/super/layout.rb +47 -0
  75. data/lib/super/link.rb +110 -0
  76. data/lib/super/navigation/automatic.rb +2 -0
  77. data/lib/super/pagination.rb +19 -8
  78. data/lib/super/panel.rb +30 -0
  79. data/lib/super/partial.rb +11 -0
  80. data/lib/super/partial/resolving.rb +24 -0
  81. data/lib/super/schema.rb +64 -1
  82. data/lib/super/version.rb +1 -1
  83. data/lib/super/view_helper.rb +43 -0
  84. metadata +145 -38
  85. data/app/views/super/application/_form.html.erb +0 -13
  86. data/app/views/super/application/_form_field.html.erb +0 -7
  87. data/app/views/super/application/_form_generic_select.html.erb +0 -19
  88. data/app/views/super/application/_form_generic_text.html.erb +0 -7
  89. data/app/views/super/application/_index.html.erb +0 -58
  90. data/frontend/super-frontend/src/javascripts/super/application.js +0 -11
  91. data/lib/generators/super/resource/templates/resource_dashboard.rb.tt +0 -65
  92. data/lib/super/display.rb +0 -9
  93. data/lib/super/inline_callback.rb +0 -82
  94. data/lib/super/test_support/fixtures/members.yml +0 -336
  95. data/lib/super/test_support/fixtures/ships.yml +0 -10
  96. data/lib/super/test_support/setup.rb +0 -79
  97. data/lib/super/test_support/starfleet_seeder.rb +0 -49
  98. data/lib/super/test_support/templates/20190216224956_create_members.rb +0 -11
  99. data/lib/super/test_support/templates/20190803143320_create_ships.rb +0 -11
  100. data/lib/super/test_support/templates/20190806014121_add_ship_to_members.rb +0 -5
  101. data/lib/super/test_support/templates/admin/members_controller.rb +0 -9
  102. data/lib/super/test_support/templates/admin/ships_controller.rb +0 -9
  103. data/lib/super/test_support/templates/admin_controller.rb +0 -2
  104. data/lib/super/test_support/templates/member.rb +0 -16
  105. data/lib/super/test_support/templates/member_dashboard.rb +0 -90
  106. data/lib/super/test_support/templates/routes.rb +0 -10
  107. data/lib/super/test_support/templates/seeds.rb +0 -2
  108. data/lib/super/test_support/templates/ship.rb +0 -3
  109. data/lib/super/test_support/templates/ship_dashboard.rb +0 -79
  110. data/lib/super/view.rb +0 -25
  111. data/lib/tasks/super_tasks.rake +0 -4
@@ -20,7 +20,8 @@ Example:
20
20
  config/initializers/super.rb
21
21
  app/controllers/admin_controller.rb
22
22
  app/controllers/admin/.keep
23
- app/super/.keep
23
+
24
+ This will also update your Sprockets manifest as necessary.
24
25
 
25
26
  Example:
26
27
  rails generate super:install --controller-namespace badminton
@@ -29,4 +30,5 @@ Example:
29
30
  config/initializers/super.rb
30
31
  app/controllers/badminton_controller.rb
31
32
  app/controllers/badminton/.keep
32
- app/super/.keep
33
+
34
+ This will also update your Sprockets manifest as necessary.
@@ -29,9 +29,24 @@ module Super
29
29
  create_file("app/controllers/#{controller_namespace}/.keep", "")
30
30
  end
31
31
 
32
- def create_directory_for_dashboards_slash_setup
33
- empty_directory("app/super")
34
- create_file("app/super/.keep", "")
32
+ def copy_cheatsheet
33
+ super_path = Pathname.new(Gem.loaded_specs["super"].full_gem_path).expand_path
34
+ super_cheat_path = super_path.join("docs", "cheat.md")
35
+
36
+ path =
37
+ if options["controller_namespace"].present?
38
+ "app/controllers/#{controller_namespace}/README.md"
39
+ else
40
+ "app/controllers/README.md"
41
+ end
42
+
43
+ create_file(path) do
44
+ super_cheat_path.read.sub(%r{<!--.*?-->}m, "").strip + "\n"
45
+ end
46
+ end
47
+
48
+ def setup_sprockets4_manifest
49
+ append_to_file "app/assets/config/manifest.js", "//= link super_manifest.js\n"
35
50
  end
36
51
 
37
52
  private
@@ -1,9 +1,8 @@
1
1
  Description:
2
- Creates a controller and its respective "control".
2
+ Creates a controller
3
3
 
4
4
  Example:
5
5
  rails generate super:resource Thing
6
6
 
7
7
  This will create:
8
8
  app/controllers/admin/things_controller.rb
9
- app/controls/thing_controls.rb
@@ -14,8 +14,6 @@ module Super
14
14
  "resources_controller.rb",
15
15
  "app/controllers/#{controller_subdir}#{file_path.pluralize}_controller.rb"
16
16
  )
17
-
18
- template("resource_dashboard.rb", "app/super/#{file_path}_dashboard.rb")
19
17
  end
20
18
 
21
19
  private
@@ -2,8 +2,44 @@
2
2
  class <%= class_name.pluralize %>Controller < <%= parent_controller_name %>
3
3
  private
4
4
 
5
- def dashboard
6
- <%= class_name %>Dashboard.new
5
+ def new_controls
6
+ Controls.new
7
+ end
8
+
9
+ class Controls
10
+ def title
11
+ <%= class_name %>.name.pluralize
12
+ end
13
+
14
+ def model
15
+ <%= class_name %>
16
+ end
17
+
18
+ def scope(action:)
19
+ if action.read?
20
+ <%= class_name %>.all
21
+ else
22
+ <%= class_name %>.all
23
+ end
24
+ end
25
+
26
+ def permitted_params(params, action:)
27
+ if action.create?
28
+ params.require(:<%= file_name %>).permit()
29
+ else
30
+ params.require(:<%= file_name %>).permit()
31
+ end
32
+ end
33
+
34
+ def display_schema(action:)
35
+ Super::Schema.new(Super::Display::SchemaTypes.new) do |fields, type|
36
+ end
37
+ end
38
+
39
+ def form_schema(action:)
40
+ Super::Schema.new(Super::Form::SchemaTypes.new) do |fields, type|
41
+ end
42
+ end
7
43
  end
8
44
  end
9
45
  <% end -%>
@@ -9,6 +9,14 @@ module Super
9
9
  )
10
10
  end
11
11
 
12
+ def set_asset_handler_to_webpacker
13
+ insert_into_file(
14
+ "config/initializers/super.rb",
15
+ " c.asset_handler = Super::Assets.webpacker\n",
16
+ before: /\bend\b/
17
+ )
18
+ end
19
+
12
20
  def remind_about_erb
13
21
  say "Make sure ERB is set up for Webpacker!", :bold
14
22
  say "Run if needed: rails webpacker:install:erb", :bold
@@ -1,18 +1,23 @@
1
- require "tsort"
2
1
  require "active_support/concern"
3
2
 
3
+ require "super/action_inquirer"
4
4
  require "super/assets"
5
+ require "super/client_error"
6
+ require "super/compatibility"
5
7
  require "super/configuration"
6
8
  require "super/controls"
9
+ require "super/display/schema_types"
7
10
  require "super/engine"
8
11
  require "super/error"
9
- require "super/display"
10
- require "super/display/schema_types"
12
+ require "super/form"
11
13
  require "super/form/schema_types"
12
- require "super/inline_callback"
14
+ require "super/layout"
15
+ require "super/link"
13
16
  require "super/navigation/automatic"
14
17
  require "super/pagination"
18
+ require "super/panel"
19
+ require "super/partial"
15
20
  require "super/plugin"
16
21
  require "super/schema"
17
22
  require "super/version"
18
- require "super/view"
23
+ require "super/view_helper"
@@ -0,0 +1,101 @@
1
+ module Super
2
+ # ```ruby
3
+ # action = Super::ActionInquirer.new(
4
+ # Super::ActionInquirer.default_for_resources,
5
+ # :index
6
+ # )
7
+ #
8
+ # action.read? # => true
9
+ # action.index? # => true
10
+ # action.show? # => false
11
+ # action.write? # => false
12
+ # ```
13
+ class ActionInquirer
14
+ attr_reader :action
15
+
16
+ # @return [Hash<Symbol, Array<Symbol>>] default settings for initialization
17
+ #
18
+ def self.default_for_resources
19
+ {
20
+ read: %i[index show new edit],
21
+ write: %i[create update destroy],
22
+ delete: %i[destroy]
23
+ }
24
+ end
25
+
26
+ def initialize(categories_and_their_actions, action)
27
+ @categories = categories_and_their_actions.keys.map(&:to_s)
28
+ @actions = categories_and_their_actions.values.flatten.uniq.map(&:to_s)
29
+ @actions_categories = {}
30
+
31
+ categories_and_their_actions.each do |c, actions|
32
+ c = c.to_s
33
+
34
+ actions.each do |a|
35
+ a = a.to_s
36
+ @actions_categories[a] ||= []
37
+ @actions_categories[a].push(c)
38
+ end
39
+ end
40
+
41
+ intersection = @categories & @actions
42
+ if intersection.any?
43
+ raise Error::ActionInquirerError,
44
+ "Found shared elements between categories and actions: #{intersection.join(", ")}"
45
+ end
46
+
47
+ self.action = action
48
+ end
49
+
50
+ def action=(new_action)
51
+ new_action = new_action.to_s
52
+ if !@actions.include?(new_action)
53
+ raise Error::ActionInquirerError, "Unknown action: #{new_action}"
54
+ end
55
+
56
+ @action = new_action
57
+ end
58
+
59
+ def respond_to_missing?(method_name, *)
60
+ inquiry = parse_inquiry(method_name)
61
+
62
+ return super if !inquiry
63
+
64
+ @actions.include?(inquiry) || @categories.include?(inquiry) || super
65
+ end
66
+
67
+ def method_missing(method_name, *)
68
+ inquiry = parse_inquiry(method_name)
69
+
70
+ return super if !inquiry
71
+
72
+ if @actions.include?(inquiry)
73
+ matches_action?(inquiry)
74
+ elsif @categories.include?(inquiry)
75
+ matches_category?(inquiry)
76
+ else
77
+ super
78
+ end
79
+ end
80
+
81
+ private
82
+
83
+ def parse_inquiry(method_name)
84
+ inquiry = method_name.to_s
85
+
86
+ if inquiry[-1] != "?"
87
+ return nil
88
+ end
89
+
90
+ inquiry.chomp("?")
91
+ end
92
+
93
+ def matches_action?(inquiry)
94
+ @action == inquiry
95
+ end
96
+
97
+ def matches_category?(inquiry)
98
+ @actions_categories[@action].include?(inquiry)
99
+ end
100
+ end
101
+ end
@@ -1,4 +1,5 @@
1
1
  module Super
2
+ # Utilities for determining whether to use Sprockets or Webpacker
2
3
  class Assets
3
4
  def self.sprockets_available?
4
5
  Gem::Dependency.new("sprockets").matching_specs.any?
@@ -0,0 +1,43 @@
1
+ module Super
2
+ # A container class for all user-facing (4xx) errors thrown by this library.
3
+ #
4
+ # See also `Super::Error`
5
+ class ClientError < StandardError
6
+ class BadRequest < ClientError; end
7
+ class Unauthorized < ClientError; end
8
+ class Forbidden < ClientError; end
9
+ class NotFound < ClientError; end
10
+ class UnprocessableEntity < ClientError; end
11
+
12
+ module Handling
13
+ extend ActiveSupport::Concern
14
+
15
+ included do
16
+ rescue_from ::Super::ClientError do |exception|
17
+ code, default_message =
18
+ case exception
19
+ when ClientError::UnprocessableEntity
20
+ [422, "Unprocessable entity"]
21
+ when ClientError::NotFound
22
+ [404, "Not found"]
23
+ when ClientError::Forbidden
24
+ [403, "Forbidden"]
25
+ when ClientError::Unauthorized
26
+ [401, "Unauthorized"]
27
+ when ClientError::BadRequest, ClientError
28
+ [400, "Bad request"]
29
+ end
30
+
31
+ flash.now.alert =
32
+ if exception.message == exception.class.name.to_s
33
+ default_message
34
+ else
35
+ exception.message
36
+ end
37
+
38
+ render "nothing", status: code
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,13 @@
1
+ module Super
2
+ module Compatability
3
+ module_function
4
+
5
+ def rails_50_errable_fields(field)
6
+ if Rails::VERSION::MAJOR == 5 && Rails::VERSION::MINOR == 0
7
+ [field.to_s, field.to_sym]
8
+ else
9
+ field
10
+ end
11
+ end
12
+ end
13
+ end
@@ -1,4 +1,6 @@
1
1
  module Super
2
+ # @yield [Configuration]
3
+ # @return [Configuration]
2
4
  def self.configuration
3
5
  @configuration ||= Configuration.new
4
6
 
@@ -9,78 +11,91 @@ module Super
9
11
  @configuration
10
12
  end
11
13
 
12
- module ConfigurationLogic
13
- def self.included(base)
14
- base.extend(ClassMethods)
15
- end
16
-
17
- def initialize
18
- self.class.defaults.each do |key, value|
19
- if value.respond_to?(:call)
20
- value = value.call
21
- end
22
-
23
- public_send("#{key}=", value)
14
+ # Allows setting global configuration
15
+ #
16
+ # ```ruby
17
+ # Super.configuration do |c|
18
+ # c.title = "My Admin Site"
19
+ # end
20
+ # ```
21
+ class Configuration
22
+ module ConfigurationLogic # @api private
23
+ def self.included(base)
24
+ base.extend(ClassMethods)
24
25
  end
25
- end
26
26
 
27
- def configured?(attr)
28
- instance_variable_defined?("@#{attr}")
29
- end
27
+ def initialize
28
+ self.class.defaults.each do |key, value|
29
+ if value.respond_to?(:call)
30
+ value = value.call
31
+ end
30
32
 
31
- module ClassMethods
32
- def defaults
33
- @defaults ||= {}
33
+ public_send("#{key}=", value)
34
+ end
34
35
  end
35
36
 
36
- def wraps
37
- @wraps ||= {}
37
+ def configured?(attr)
38
+ instance_variable_defined?("@#{attr}")
38
39
  end
39
40
 
40
- def configure(attr, wrap: nil, enum: nil, **kwargs)
41
- if kwargs.key?(:default)
42
- defaults[attr] = kwargs[:default]
41
+ module ClassMethods
42
+ def defaults
43
+ @defaults ||= {}
43
44
  end
44
45
 
45
- define_method(attr) do
46
- if !configured?(attr)
47
- raise Error::UnconfiguredConfiguration, "unconfigured: #{attr}"
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]
48
53
  end
49
54
 
50
- result = instance_variable_get("@#{attr}")
55
+ define_method(attr) do
56
+ if !configured?(attr)
57
+ raise Error::UnconfiguredConfiguration, "unconfigured: #{attr}"
58
+ end
51
59
 
52
- if wrap.nil?
53
- result
54
- else
55
- wrap.call(result)
56
- end
57
- end
60
+ result = instance_variable_get("@#{attr}")
58
61
 
59
- define_method("#{attr}=") do |value|
60
- if enum.is_a?(Array)
61
- if !enum.include?(value)
62
- raise Error::InvalidConfiguration,
63
- "tried to set `#{attr}` to `#{value.inspect}`, " \
64
- "expected: #{enum.join(", ")}"
62
+ if wrap.nil?
63
+ result
64
+ else
65
+ wrap.call(result)
65
66
  end
66
67
  end
67
68
 
68
- instance_variable_set("@#{attr}", value)
69
- value
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
77
+
78
+ instance_variable_set("@#{attr}", value)
79
+ value
80
+ end
70
81
  end
71
82
  end
72
83
  end
73
- end
74
84
 
75
- class Configuration
76
85
  include ConfigurationLogic
77
86
 
87
+ # @!attribute [rw]
78
88
  configure :title
79
- configure :index_resources_per_page, default: 20
89
+ # @!attribute [rw]
90
+ configure :index_records_per_page, default: 20
91
+ # @!attribute [rw]
80
92
  configure :controller_namespace, default: "admin"
93
+ # @!attribute [rw]
81
94
  configure :route_namespace, default: :admin, wrap: -> (val) { [val].flatten }
95
+ # @!attribute [rw]
82
96
  configure :asset_handler, default: -> { Super::Assets.auto }
83
97
 
98
+ # @api private
84
99
  def path_parts(*parts)
85
100
  route_namespace + parts
86
101
  end