super 0.0.10 → 0.0.15

Sign up to get free protection for your applications and to get access to all the features.
Files changed (103) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +0 -9
  3. data/README.md +40 -52
  4. data/app/assets/javascripts/super/application.js +5672 -3671
  5. data/app/assets/stylesheets/super/application.css +114681 -71486
  6. data/app/controllers/super/application_controller.rb +31 -21
  7. data/app/helpers/super/form_builder_helper.rb +2 -0
  8. data/app/views/layouts/super/application.html.erb +15 -14
  9. data/app/views/super/application/{_super_schema_display_actions.html.erb → _display_actions.html.erb} +0 -0
  10. data/app/views/super/application/{_super_schema_display_index.html.erb → _display_index.html.erb} +4 -4
  11. data/app/views/super/application/_display_show.html.erb +8 -0
  12. data/app/views/super/application/_filter.html.erb +5 -13
  13. data/app/views/super/application/_filter_type_select.html.erb +5 -2
  14. data/app/views/super/application/_filter_type_text.html.erb +6 -4
  15. data/app/views/super/application/_filter_type_timestamp.html.erb +6 -5
  16. data/app/views/super/application/{_super_schema_form.html.erb → _form.html.erb} +2 -2
  17. data/app/views/super/application/_form_field.html.erb +5 -0
  18. data/app/views/super/application/{_super_layout.html.erb → _layout.html.erb} +8 -8
  19. data/app/views/super/application/{_super_pagination.html.erb → _pagination.html.erb} +1 -1
  20. data/app/views/super/application/{_super_panel.html.erb → _panel.html.erb} +2 -2
  21. data/app/views/super/application/_query.html.erb +18 -0
  22. data/app/views/super/application/_sort.html.erb +18 -0
  23. data/app/views/super/application/_sort_expression.html.erb +25 -0
  24. data/app/views/super/feather/README.md +1 -1
  25. data/app/views/super/feather/_x.html +15 -0
  26. data/config/routes.rb +2 -0
  27. data/frontend/super-frontend/dist/application.css +114681 -71486
  28. data/frontend/super-frontend/dist/application.js +5672 -3671
  29. data/lib/generators/super/action_text/action_text_generator.rb +2 -0
  30. data/lib/generators/super/install/install_generator.rb +18 -23
  31. data/lib/generators/super/install/templates/base_controller.rb.tt +9 -1
  32. data/lib/generators/super/install/templates/initializer.rb.tt +9 -2
  33. data/lib/generators/super/resource/resource_generator.rb +107 -30
  34. data/lib/generators/super/resource/templates/resources_controller.rb.tt +3 -9
  35. data/lib/generators/super/webpacker/webpacker_generator.rb +11 -5
  36. data/lib/super.rb +10 -2
  37. data/lib/super/action_inquirer.rb +13 -3
  38. data/lib/super/assets.rb +46 -23
  39. data/lib/super/badge.rb +61 -0
  40. data/lib/super/cheat.rb +17 -0
  41. data/lib/super/client_error.rb +2 -0
  42. data/lib/super/compatibility.rb +21 -0
  43. data/lib/super/configuration.rb +16 -24
  44. data/lib/super/controls.rb +11 -2
  45. data/lib/super/controls/optional.rb +44 -1
  46. data/lib/super/controls/steps.rb +53 -34
  47. data/lib/super/controls/view.rb +55 -0
  48. data/lib/super/display.rb +29 -13
  49. data/lib/super/display/guesser.rb +4 -0
  50. data/lib/super/display/schema_types.rb +118 -29
  51. data/lib/super/engine.rb +2 -0
  52. data/lib/super/error.rb +12 -0
  53. data/lib/super/filter.rb +2 -0
  54. data/lib/super/filter/form_object.rb +5 -8
  55. data/lib/super/filter/guesser.rb +2 -0
  56. data/lib/super/filter/operator.rb +2 -0
  57. data/lib/super/filter/schema_types.rb +2 -0
  58. data/lib/super/form.rb +3 -1
  59. data/lib/super/form/builder.rb +109 -27
  60. data/lib/super/form/guesser.rb +12 -1
  61. data/lib/super/form/inline_errors.rb +2 -0
  62. data/lib/super/form/schema_types.rb +75 -7
  63. data/lib/super/form/strong_params.rb +2 -0
  64. data/lib/super/layout.rb +3 -1
  65. data/lib/super/link.rb +44 -31
  66. data/lib/super/link_builder.rb +58 -0
  67. data/lib/super/navigation.rb +164 -0
  68. data/lib/super/pagination.rb +3 -43
  69. data/lib/super/panel.rb +3 -1
  70. data/lib/super/partial.rb +2 -0
  71. data/lib/super/partial/resolving.rb +2 -0
  72. data/lib/super/plugin.rb +2 -0
  73. data/lib/super/query/form_object.rb +48 -0
  74. data/lib/super/reset.rb +17 -0
  75. data/lib/super/schema.rb +2 -0
  76. data/lib/super/schema/common.rb +2 -0
  77. data/lib/super/schema/guesser.rb +2 -0
  78. data/lib/super/sort.rb +110 -0
  79. data/lib/super/useful/builder.rb +25 -0
  80. data/lib/super/useful/enum.rb +63 -0
  81. data/lib/super/version.rb +3 -1
  82. data/lib/super/view_helper.rb +2 -0
  83. data/lib/tasks/super/cheat.rake +9 -0
  84. metadata +45 -28
  85. data/CONTRIBUTING.md +0 -56
  86. data/Rakefile +0 -34
  87. data/STABILITY.md +0 -50
  88. data/app/views/super/application/_form_field_checkbox.html.erb +0 -1
  89. data/app/views/super/application/_form_field_rich_text_area.html.erb +0 -1
  90. data/app/views/super/application/_form_field_text.html.erb +0 -1
  91. data/app/views/super/application/_super_schema_display_show.html.erb +0 -8
  92. data/app/views/super/feather/_chevron_down.html +0 -1
  93. data/docs/README.md +0 -8
  94. data/docs/action_text.md +0 -48
  95. data/docs/cheat.md +0 -41
  96. data/docs/faq.md +0 -44
  97. data/docs/installation.md +0 -21
  98. data/docs/quick_start.md +0 -30
  99. data/docs/webpacker.md +0 -25
  100. data/docs/yard_customizations.rb +0 -41
  101. data/lib/super/controls/required.rb +0 -13
  102. data/lib/super/filter/plugin.rb +0 -47
  103. data/lib/super/navigation/automatic.rb +0 -71
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Super
4
+ class Badge
5
+ STYLES = {
6
+ light: "bg-gray-100 text-black",
7
+ dark: "bg-gray-900 text-white",
8
+ red: "bg-red-700 text-white",
9
+ orange: "bg-orange-400 text-black",
10
+ yellow: "bg-yellow-400 text-black",
11
+ green: "bg-green-700 text-white",
12
+ blue: "bg-blue-700 text-white",
13
+ purple: "bg-purple-800 text-white",
14
+ }
15
+
16
+ def initialize(text, styles: nil)
17
+ @text = text
18
+ @requested_styles = Array(styles.presence).flatten
19
+ end
20
+
21
+ def styles
22
+ return @styles if instance_variable_defined?(:@styles)
23
+ @styles =
24
+ if requested_styles.delete(:reset)
25
+ []
26
+ else
27
+ COMMON_STYLES
28
+ end
29
+
30
+ if requested_styles.empty?
31
+ @styles += [STYLES[:light]]
32
+ else
33
+ requested_styles.each do |style|
34
+ @styles +=
35
+ if STYLES.key?(style)
36
+ [STYLES[style]]
37
+ else
38
+ [style]
39
+ end
40
+ end
41
+ end
42
+
43
+ @styles
44
+ end
45
+
46
+ def to_s
47
+ ActionController::Base.helpers.content_tag(
48
+ :span,
49
+ @text,
50
+ class: styles.join(" ")
51
+ )
52
+ end
53
+
54
+ private
55
+
56
+ COMMON_STYLES = %w[rounded px-2 py-1 text-xs leading-none font-bold]
57
+ private_constant :COMMON_STYLES
58
+
59
+ attr_reader :requested_styles
60
+ end
61
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Super
4
+ class Cheat
5
+ def controls
6
+ paths = %w[controls.rb controls/optional.rb controls/steps.rb controls/view.rb]
7
+ methods =
8
+ paths
9
+ .map { |f| File.read(File.join(__dir__, f)) }
10
+ .flat_map { |content| content.scan(/^\s+def .*$/) }
11
+ .map { |method| method.strip.sub(/^def /, "#") }
12
+
13
+ puts "== Super::Controls"
14
+ puts methods.join("\n")
15
+ end
16
+ end
17
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Super
2
4
  # A container class for all user-facing (4xx) errors thrown by this library.
3
5
  #
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Super
2
4
  module Compatability
3
5
  module_function
@@ -21,5 +23,24 @@ module Super
21
23
  ActiveRecord::Base.sanitize_sql_like(query)
22
24
  end
23
25
  end
26
+
27
+ def polymorphic_path_container
28
+ if Rails::VERSION::MAJOR == 5 && Rails::VERSION::MINOR == 0
29
+ @polymorphic_path_container ||=
30
+ begin
31
+ klass = Class.new do
32
+ include ActionDispatch::Routing::PolymorphicRoutes
33
+
34
+ def method_missing(method_name)
35
+ Rails.application.routes.url_helpers.public_send(method_name)
36
+ end
37
+ end
38
+
39
+ klass.new
40
+ end
41
+ else
42
+ Rails.application.routes.url_helpers
43
+ end
44
+ end
24
45
  end
25
46
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Super
2
4
  # @yield [Configuration]
3
5
  # @return [Configuration]
@@ -19,37 +21,27 @@ module Super
19
21
  # end
20
22
  # ```
21
23
  class Configuration
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
27
-
28
- controller_plugins.use(prepend: Super::Filter::ControllerMethods)
29
- controller_plugins.use(prepend: Super::Pagination::ControllerMethods)
24
+ include ActiveSupport::Configurable
30
25
 
31
- self.javascripts = [Super::Assets.auto("super/application")]
32
- self.stylesheets = [Super::Assets.auto("super/application")]
26
+ config_accessor(:title) { "Super Admin" }
27
+ config_accessor(:index_records_per_page) { 100 }
28
+ config_accessor(:javascripts) do
29
+ [Super::Assets.auto("super/application")]
33
30
  end
34
-
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
31
+ config_accessor(:stylesheets) do
32
+ [Super::Assets.auto("super/application")]
41
33
  end
42
34
 
43
- attr_accessor :javascripts
44
- attr_accessor :stylesheets
35
+ config_accessor(:path) { "/admin" }
36
+ config_accessor(:generator_module) { "admin" }
37
+ config_accessor(:generator_as) { "admin" }
45
38
 
46
- def controller_plugins
47
- Plugin::Registry.controller
39
+ def initialize
40
+ controller_plugins.use(prepend: Super::Pagination::ControllerMethods)
48
41
  end
49
42
 
50
- # @api private
51
- def path_parts(*parts)
52
- route_namespace + parts
43
+ def controller_plugins
44
+ Plugin::Registry.controller
53
45
  end
54
46
  end
55
47
  end
@@ -1,13 +1,22 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "super/controls/optional"
2
- require "super/controls/required"
3
4
  require "super/controls/steps"
5
+ require "super/controls/view"
4
6
 
5
7
  module Super
6
8
  # The base Controls class. Most parts of Super can be configured by
7
9
  # customizing its methods.
8
10
  class Controls
9
- include Required
10
11
  include Optional
11
12
  include Steps
13
+ include View
14
+
15
+ # Specifies the model. This is a required method
16
+ #
17
+ # @return [ActiveRecord::Base]
18
+ def model
19
+ raise NotImplementedError
20
+ end
12
21
  end
13
22
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Super
2
4
  class Controls
3
5
  # Methods for `Controls` that have a sane default implementation
@@ -24,7 +26,7 @@ module Super
24
26
  # @param action [ActionInquirer]
25
27
  # @return [Display]
26
28
  def display_schema(action:)
27
- Display.new(action: action) do |fields, type|
29
+ Display.new do |fields, type|
28
30
  Display::Guesser.new(model: model, action: action, fields: fields, type: type).call
29
31
  end
30
32
  end
@@ -74,6 +76,47 @@ module Super
74
76
  Super::Link.find_all(:show, :edit, :destroy)
75
77
  end
76
78
  end
79
+
80
+ def filters_enabled?
81
+ true
82
+ end
83
+
84
+ def filter_schema
85
+ Super::Filter.new do |fields, type|
86
+ Super::Filter::Guesser.new(model: model, fields: fields, type: type).call
87
+ end
88
+ end
89
+
90
+ def sort_enabled?
91
+ true
92
+ end
93
+
94
+ def sortable_columns
95
+ action = ActionInquirer.new(
96
+ ActionInquirer.default_for_resources,
97
+ "index"
98
+ )
99
+ attribute_names =
100
+ display_schema(action: action).each_attribute.map do |key, val|
101
+ val = val.build if val.respond_to?(:build)
102
+ key if val.real?
103
+ end
104
+
105
+ attribute_names.compact
106
+ end
107
+
108
+ def default_sort
109
+ { id: :desc }
110
+ end
111
+
112
+ # Specifies how many records to show per page
113
+ #
114
+ # @param action [ActionInquirer]
115
+ # @param query_params [Hash]
116
+ # @return [ActiveRecord::Relation]
117
+ def records_per_page(action:, query_params:)
118
+ Super.configuration.index_records_per_page
119
+ end
77
120
  end
78
121
  end
79
122
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Super
2
4
  class Controls
3
5
  # Methods that are called by controller actions. All of these methods have
@@ -66,49 +68,66 @@ module Super
66
68
  record.destroy
67
69
  end
68
70
 
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
- ]
71
+ def initialize_query_form(params:, current_path:)
72
+ Super::Query::FormObject.new(
73
+ model: model,
74
+ params: params,
75
+ namespace: :q,
76
+ current_path: current_path,
77
77
  )
78
78
  end
79
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
- )
80
+ def apply_queries(query_form:, records:)
81
+ query_form.apply_changes(records)
89
82
  end
90
83
 
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
- )
84
+ def initialize_filter_form(query_form:)
85
+ if filters_enabled?
86
+ query_form.add(
87
+ Super::Filter::FormObject,
88
+ namespace: :f,
89
+ schema: filter_schema
90
+ )
91
+ end
100
92
  end
101
93
 
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
- ]
94
+ def initialize_sort_form(query_form:)
95
+ if sort_enabled?
96
+ query_form.add(
97
+ Super::Sort::FormObject,
98
+ namespace: :s,
99
+ default: default_sort,
100
+ sortable_columns: sortable_columns
101
+ )
102
+ end
103
+ end
104
+
105
+ # Sets up pagination
106
+ #
107
+ # @param action [ActionInquirer]
108
+ # @param records [ActiveRecord::Relation]
109
+ # @param query_params [Hash]
110
+ # @return [Pagination]
111
+ def initialize_pagination(action:, records:, query_params:)
112
+ Pagination.new(
113
+ total_count: records.size,
114
+ limit: records_per_page(action: action, query_params: query_params),
115
+ query_params: query_params,
116
+ page_query_param: :page
110
117
  )
111
118
  end
119
+
120
+ # Paginates
121
+ #
122
+ # @param action [ActionInquirer]
123
+ # @param records [ActiveRecord::Relation]
124
+ # @param pagination [Pagination]
125
+ # @return [ActiveRecord::Relation]
126
+ def paginate_records(action:, records:, pagination:)
127
+ records
128
+ .limit(pagination.limit)
129
+ .offset(pagination.offset)
130
+ end
112
131
  end
113
132
  end
114
133
  end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Super
4
+ class Controls
5
+ # Methods for `Controls` that have a sane default implementation
6
+ module View
7
+ def index_view
8
+ Super::Layout.new(
9
+ mains: [
10
+ Super::Panel.new(
11
+ Super::Partial.new("collection_header"),
12
+ :@display
13
+ ),
14
+ ],
15
+ asides: [
16
+ :@query_form,
17
+ ]
18
+ )
19
+ end
20
+
21
+ def show_view
22
+ Super::Layout.new(
23
+ mains: [
24
+ Super::Panel.new(
25
+ Super::Partial.new("member_header"),
26
+ :@display
27
+ ),
28
+ ]
29
+ )
30
+ end
31
+
32
+ def new_view
33
+ Super::Layout.new(
34
+ mains: [
35
+ Super::Panel.new(
36
+ Super::Partial.new("collection_header"),
37
+ :@form
38
+ ),
39
+ ]
40
+ )
41
+ end
42
+
43
+ def edit_view
44
+ Super::Layout.new(
45
+ mains: [
46
+ Super::Panel.new(
47
+ Super::Partial.new("member_header"),
48
+ :@form
49
+ ),
50
+ ]
51
+ )
52
+ end
53
+ end
54
+ end
55
+ end
data/lib/super/display.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Super
2
4
  # This schema type is meant to be used for +#index+ or +#show+ actions to
3
5
  # transform database fields into something that is human friendly.
@@ -23,39 +25,53 @@ module Super
23
25
  class Display
24
26
  include Schema::Common
25
27
 
26
- def initialize(action:)
27
- @action_inquirer = action
28
+ def initialize
28
29
  @fields = Super::Schema::Fields.new
29
30
  @schema_types = SchemaTypes.new(fields: @fields)
30
31
 
31
32
  yield(@fields, @schema_types)
33
+ end
32
34
 
33
- return if !@action_inquirer.index?
34
- return if @schema_types.actions_called?
35
+ def apply(action:)
36
+ @action_inquirer = action
37
+ return self if !@action_inquirer.index?
38
+ return self if @schema_types.actions_called?
35
39
  @fields[:actions] = @schema_types.actions
40
+ self
36
41
  end
37
42
 
38
43
  def to_partial_path
39
- if @action_inquirer.index?
40
- "super_schema_display_index"
44
+ if @action_inquirer.nil?
45
+ raise Super::Error::Initalization,
46
+ "You must call the `#apply` method after instantiating Super::Display"
47
+ elsif @action_inquirer.index?
48
+ "display_index"
41
49
  elsif @action_inquirer.show?
42
- "super_schema_display_show"
50
+ "display_show"
43
51
  else
44
- "super_schema_display_#{@action_inquirer.action}"
52
+ "display_#{@action_inquirer.action}"
45
53
  end
46
54
  end
47
55
 
48
56
  # @private
49
- def render_field(template:, record:, column:)
57
+ def render_attribute(template:, record:, column:)
50
58
  formatter = @fields[column]
59
+ formatter = formatter.build if formatter.respond_to?(:build)
51
60
 
52
61
  formatted =
53
- if formatter.real?
62
+ SchemaTypes::TYPES
63
+ .case(formatter.type)
64
+ .when(:record) do
65
+ formatter.present(column, record)
66
+ end
67
+ .when(:column) do
54
68
  value = record.public_send(column)
55
- formatter.present(value)
56
- else
57
- formatter.present
69
+ formatter.present(column, value)
70
+ end
71
+ .when(:none) do
72
+ formatter.present(column)
58
73
  end
74
+ .result
59
75
 
60
76
  if formatted.respond_to?(:to_partial_path)
61
77
  if formatted.respond_to?(:locals)