super 0.0.1 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -1,25 +1,36 @@
1
+ require "super/controls/optional"
2
+ require "super/controls/required"
3
+ require "super/controls/steps"
4
+
1
5
  module Super
6
+ # A wrapper around the per-controller Controls classes. This class often
7
+ # directly delegates to the per-controller classes, but it can also provide
8
+ # some default implementation.
2
9
  class Controls
3
- def initialize(dashboard)
4
- @dashboard = dashboard
10
+ include Required
11
+ include Optional
12
+ include Steps
13
+
14
+ def initialize(actual)
15
+ @actual = actual
5
16
  end
6
17
 
7
- attr_reader :dashboard
18
+ attr_reader :actual
8
19
 
9
- def method_missing(method_name, *args)
10
- if @dashboard.respond_to?(method_name)
11
- @dashboard.public_send(method_name, *args)
12
- else
13
- super
14
- end
15
- end
20
+ private
16
21
 
17
- def respond_to_missing?(method_name, _ = false)
18
- if @dashboard.respond_to?(method_name)
19
- true
20
- else
21
- super
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
22
31
  end
32
+
33
+ yield
23
34
  end
24
35
  end
25
36
  end
@@ -0,0 +1,65 @@
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
+ default_for(:title) do
10
+ model.name.pluralize
11
+ end
12
+ end
13
+
14
+ # Configures what database records are visible on load. This is an optional
15
+ # method, it defaults to "`all`" methods
16
+ #
17
+ # @param action [ActionInquirer]
18
+ # @return [ActiveRecord::Relation]
19
+ def scope(action:)
20
+ default_for(:scope, action: action) do
21
+ model.all
22
+ end
23
+ end
24
+
25
+ # Configures the actions linked to on the index page. This is an optional
26
+ # method
27
+ #
28
+ # @param action [ActionInquirer]
29
+ # @return [Array<Link>]
30
+ def collection_actions(action:)
31
+ default_for(:collection_actions, action: action) do
32
+ Super::Link.find_all(:new)
33
+ end
34
+ end
35
+
36
+ # Configures the actions linked to on the show page as well as each row of
37
+ # the table on the index page. This is an optional method
38
+ #
39
+ # @param action [ActionInquirer]
40
+ # @return [Array<Link>]
41
+ def member_actions(action:)
42
+ default_for(:member_actions, action: action) do
43
+ if action.show?
44
+ Super::Link.find_all(:edit, :destroy)
45
+ elsif action.edit?
46
+ Super::Link.find_all(:show, :destroy)
47
+ else
48
+ Super::Link.find_all(:show, :edit, :destroy)
49
+ end
50
+ end
51
+ end
52
+
53
+ # Specifies how many records to show per page
54
+ #
55
+ # @param action [ActionInquirer]
56
+ # @param query_params [Hash]
57
+ # @return [ActiveRecord::Relation]
58
+ def records_per_page(action:, query_params:)
59
+ default_for(:records_per_page, action: action, query_params: query_params) do
60
+ Super.configuration.index_records_per_page
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,41 @@
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
+ @actual.model
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)
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,115 @@
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
+ default_for(:load_records, action: action, params: params) do
14
+ scope(action: action)
15
+ end
16
+ end
17
+
18
+ # Sets up pagination
19
+ #
20
+ # @param action [ActionInquirer]
21
+ # @param records [ActiveRecord::Relation]
22
+ # @param query_params [Hash]
23
+ # @return [Pagination]
24
+ def initialize_pagination(action:, records:, query_params:)
25
+ default_for(:initialize_pagination, action: action, records: records, query_params: query_params) do
26
+ Pagination.new(
27
+ total_count: records.size,
28
+ limit: records_per_page(action: action, query_params: query_params),
29
+ query_params: query_params,
30
+ page_query_param: :page
31
+ )
32
+ end
33
+ end
34
+
35
+ # Paginates
36
+ #
37
+ # @param action [ActionInquirer]
38
+ # @param records [ActiveRecord::Relation]
39
+ # @param pagination [Pagination]
40
+ # @return [ActiveRecord::Relation]
41
+ def paginate_records(action:, records:, pagination:)
42
+ default_for(:paginate_records, action: action, records: records, pagination: pagination) do
43
+ records
44
+ .limit(pagination.limit)
45
+ .offset(pagination.offset)
46
+ end
47
+ end
48
+
49
+ # Loads a record using `#scope`
50
+ #
51
+ # @param action [ActionInquirer]
52
+ # @param params [ActionController::Parameters]
53
+ # @return [ActiveRecord::Base]
54
+ def load_record(action:, params:)
55
+ default_for(:load_record, action: action, params: params) do
56
+ scope(action: action).find(params[:id])
57
+ end
58
+ end
59
+
60
+ # Builds a record using `#scope`
61
+ #
62
+ # @param action [ActionInquirer]
63
+ # @return [ActiveRecord::Base]
64
+ def build_record(action:)
65
+ default_for(:build_record) do
66
+ scope(action: action).build
67
+ end
68
+ end
69
+
70
+ # Builds and populates a record using `#scope`
71
+ #
72
+ # @param action [ActionInquirer]
73
+ # @param params [ActionController::Parameters]
74
+ # @return [ActiveRecord::Base]
75
+ def build_record_with_params(action:, params:)
76
+ default_for(:build_record_with_params, action: action, params: params) do
77
+ scope(action: action).build(permitted_params(params, action: action))
78
+ end
79
+ end
80
+
81
+ # Saves a record
82
+ #
83
+ # @param action [ActionInquirer]
84
+ # @param params [ActionController::Parameters]
85
+ # @return [ActiveRecord::Base]
86
+ def save_record(action:, record:, params:)
87
+ default_for(:save_record, action: action, record: record, params: params) do
88
+ record.save
89
+ end
90
+ end
91
+
92
+ # Saves a record
93
+ #
94
+ # @param action [ActionInquirer]
95
+ # @param params [ActionController::Parameters]
96
+ # @return [ActiveRecord::Base]
97
+ def update_record(action:, record:, params:)
98
+ default_for(:update_record, action: action, record: record, params: params) do
99
+ record.update(permitted_params(params, action: action))
100
+ end
101
+ end
102
+
103
+ # Destroys a record
104
+ #
105
+ # @param action [ActionInquirer]
106
+ # @param params [ActionController::Parameters]
107
+ # @return [ActiveRecord::Base, false]
108
+ def destroy_record(action:, record:, params:)
109
+ default_for(:update_record, action: action, record: record, params: params) do
110
+ record.destroy
111
+ end
112
+ end
113
+ end
114
+ end
115
+ end
@@ -3,39 +3,81 @@ module Super
3
3
  # This schema type is meant to be used for +#index+ or +#show+ actions to
4
4
  # transform database fields into something that is human friendly.
5
5
  #
6
- # Note: The constants under "Defined Under Namespace" are considered
7
- # private.
6
+ # ```
7
+ # class MembersController::Controls
8
+ # # ...
8
9
  #
9
- # class MemberDashboard
10
- # # ...
11
- #
12
- # def show_schema
13
- # Super::Schema.new(Super::Display::SchemaTypes.new) do |fields, type|
14
- # fields[:name] = type.dynamic { |name| name }
15
- # fields[:rank] = type.dynamic { |rank| rank }
16
- # fields[:position] = type.dynamic { |position| position }
17
- # fields[:ship] = type.dynamic { |ship| "#{ship.name} (Ship ##{ship.id})" }
18
- # fields[:created_at] = type.dynamic { |created_at| created_at.iso8601 }
19
- # fields[:updated_at] = type.dynamic { |updated_at| updated_at.iso8601 }
20
- # end
10
+ # def show_schema
11
+ # Super::Schema.new(Super::Display::SchemaTypes.new) do |fields, type|
12
+ # fields[:name] = type.dynamic { |name| name }
13
+ # fields[:rank] = type.dynamic { |rank| rank }
14
+ # fields[:position] = type.dynamic { |position| position }
15
+ # fields[:ship] = type.dynamic { |ship| "#{ship.name} (Ship ##{ship.id})" }
16
+ # fields[:created_at] = type.dynamic { |created_at| created_at.iso8601 }
17
+ # fields[:updated_at] = type.dynamic { |updated_at| updated_at.iso8601 }
21
18
  # end
22
- #
23
- # # ...
24
19
  # end
20
+ #
21
+ # # ...
22
+ # end
23
+ # ```
25
24
  class SchemaTypes
26
25
  class Dynamic
27
26
  def initialize(transform_block)
28
27
  @transform_block = transform_block
29
28
  end
30
29
 
31
- def present(field)
32
- @transform_block.call(field)
30
+ def present(value)
31
+ @transform_block.call(value)
32
+ end
33
+
34
+ def real?
35
+ true
36
+ end
37
+ end
38
+
39
+ class Bypass
40
+ def initialize(partial:, real:)
41
+ @partial = partial
42
+ @real = real
43
+ end
44
+
45
+ def present
46
+ Partial.new(@partial)
47
+ end
48
+
49
+ def real?
50
+ @real
33
51
  end
34
52
  end
35
53
 
54
+ def initialize(action_inquirer)
55
+ @action_inquirer = action_inquirer
56
+ @actions_called = false
57
+ end
58
+
59
+ def before_yield(fields:)
60
+ @fields = fields
61
+ end
62
+
63
+ def after_yield
64
+ return if !@action_inquirer.index?
65
+ return if @actions_called
66
+ @fields[:actions] = actions
67
+ end
68
+
36
69
  def dynamic(&transform_block)
37
70
  Dynamic.new(transform_block)
38
71
  end
72
+
73
+ def actions
74
+ @actions_called = true
75
+ Bypass.new(partial: "super_schema_display_actions", real: false)
76
+ end
77
+
78
+ def to_partial_path
79
+ "super_schema_display_#{@action_inquirer.action}"
80
+ end
39
81
  end
40
82
  end
41
83
  end
@@ -1,4 +1,5 @@
1
1
  module Super
2
+ # Configures the host Rails app to work with Super
2
3
  class Engine < ::Rails::Engine
3
4
  initializer "super.assets.precompile" do |app|
4
5
  if Super::Assets.sprockets_available?
@@ -1,8 +1,17 @@
1
1
  module Super
2
+ # A container class for all internal errors thrown by this library
3
+ #
4
+ # See also `Super::ClientError`
2
5
  class Error < StandardError
6
+ # Error raised when some configuration is not set
3
7
  class UnconfiguredConfiguration < Error; end
8
+ # Error raised when a configuration is set to a invalid value
4
9
  class InvalidConfiguration < Error; end
5
- class InvalidStyle < Error; end
10
+ # Error raised on problematic plugins, see `Super::Plugin`
6
11
  class InvalidPluginArgument < Error; end
12
+ # Error raised on problematic ActionInquirer settings, see `Super::ActionInquirer`
13
+ class ActionInquirerError < Error; end
14
+ # Error raised when a `Super::Link` couldn't be found
15
+ class LinkNotRegistered < Error; end
7
16
  end
8
17
  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