super 0.0.12 → 0.17.0
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/.yardopts +0 -1
- data/README.md +38 -46
- data/app/assets/javascripts/super/application.js +5747 -3803
- data/app/assets/stylesheets/super/application.css +114686 -71486
- data/app/controllers/super/application_controller.rb +44 -37
- data/app/controllers/super/substructure_controller.rb +276 -0
- data/app/helpers/super/form_builder_helper.rb +7 -0
- data/app/views/layouts/super/application.html.erb +4 -19
- data/app/views/super/application/_collection_header.html.erb +2 -2
- data/app/views/super/application/_display_actions.html.erb +1 -1
- data/app/views/super/application/_display_index.html.erb +2 -2
- data/app/views/super/application/_display_show.html.erb +1 -1
- data/app/views/super/application/_filter.html.erb +62 -2
- data/app/views/super/application/_form_field.html.erb +5 -0
- data/app/views/super/application/_layout.html.erb +1 -1
- data/app/views/super/application/_member_header.html.erb +2 -2
- data/app/views/super/application/_pagination.html.erb +1 -1
- data/app/views/super/application/_site_footer.html.erb +3 -0
- data/app/views/super/application/_site_header.html.erb +17 -0
- data/app/views/super/application/_sort_expression.html.erb +2 -2
- data/app/views/super/feather/README.md +0 -1
- data/frontend/super-frontend/dist/application.css +114686 -71486
- data/frontend/super-frontend/dist/application.js +5747 -3803
- data/lib/generators/super/install/install_generator.rb +0 -16
- data/lib/generators/super/install/templates/base_controller.rb.tt +0 -8
- data/lib/generators/super/resource/templates/resources_controller.rb.tt +4 -4
- data/lib/generators/super/webpacker/webpacker_generator.rb +9 -5
- data/lib/super.rb +5 -2
- data/lib/super/action_inquirer.rb +18 -3
- data/lib/super/assets.rb +44 -23
- data/lib/super/badge.rb +60 -0
- data/lib/super/cheat.rb +17 -0
- data/lib/super/compatibility.rb +19 -0
- data/lib/super/display/guesser.rb +3 -1
- data/lib/super/display/schema_types.rb +51 -2
- data/lib/super/error.rb +2 -0
- data/lib/super/filter.rb +1 -1
- data/lib/super/filter/form_object.rb +74 -48
- data/lib/super/filter/guesser.rb +2 -0
- data/lib/super/filter/operator.rb +90 -64
- data/lib/super/filter/schema_types.rb +63 -80
- data/lib/super/form/builder.rb +110 -27
- data/lib/super/form/field_transcript.rb +43 -0
- data/lib/super/form/guesser.rb +10 -1
- data/lib/super/form/schema_types.rb +73 -16
- data/lib/super/link.rb +38 -32
- data/lib/super/link_builder.rb +58 -0
- data/lib/super/navigation.rb +164 -0
- data/lib/super/pagination.rb +2 -44
- data/lib/super/reset.rb +22 -0
- data/lib/super/schema.rb +4 -0
- data/lib/super/useful/builder.rb +4 -4
- data/lib/super/version.rb +1 -1
- data/lib/tasks/super/cheat.rake +9 -0
- metadata +14 -19
- data/CONTRIBUTING.md +0 -56
- data/Rakefile +0 -36
- data/app/views/super/application/_filter_type_select.html.erb +0 -21
- data/app/views/super/application/_filter_type_text.html.erb +0 -18
- data/app/views/super/application/_filter_type_timestamp.html.erb +0 -24
- data/app/views/super/application/_form_field_checkbox.html.erb +0 -1
- data/app/views/super/application/_form_field_rich_text_area.html.erb +0 -1
- data/app/views/super/application/_form_field_select.html.erb +0 -1
- data/app/views/super/application/_form_field_text.html.erb +0 -1
- data/app/views/super/feather/_chevron_down.html +0 -1
- data/docs/cheat.md +0 -41
- data/lib/super/controls.rb +0 -22
- data/lib/super/controls/optional.rb +0 -113
- data/lib/super/controls/steps.rb +0 -106
- data/lib/super/controls/view.rb +0 -55
- data/lib/super/navigation/automatic.rb +0 -73
@@ -2,75 +2,78 @@
|
|
2
2
|
|
3
3
|
module Super
|
4
4
|
# Provides a default implementation for each of the resourceful actions
|
5
|
-
class ApplicationController <
|
5
|
+
class ApplicationController < SubstructureController
|
6
6
|
include ClientError::Handling
|
7
7
|
|
8
|
-
helper_method :
|
9
|
-
helper_method :controls
|
8
|
+
helper_method :current_action
|
10
9
|
|
11
10
|
# Displays a list of records to the user
|
12
11
|
def index
|
13
|
-
@records =
|
14
|
-
@display =
|
15
|
-
@view =
|
16
|
-
@query_form =
|
17
|
-
|
18
|
-
|
19
|
-
@records =
|
12
|
+
@records = load_records
|
13
|
+
@display = display_schema.apply(action: current_action)
|
14
|
+
@view = index_view
|
15
|
+
@query_form = initialize_query_form
|
16
|
+
initialize_filter_form
|
17
|
+
initialize_sort_form
|
18
|
+
@records = apply_queries
|
20
19
|
end
|
21
20
|
|
22
21
|
# Displays a specific record to the user
|
23
22
|
def show
|
24
|
-
@record =
|
25
|
-
@display =
|
26
|
-
@view =
|
23
|
+
@record = load_record
|
24
|
+
@display = display_schema.apply(action: current_action)
|
25
|
+
@view = show_view
|
27
26
|
end
|
28
27
|
|
29
28
|
# Displays a form to allow the user to create a new record
|
30
29
|
def new
|
31
|
-
@record =
|
32
|
-
@form =
|
33
|
-
@view =
|
30
|
+
@record = build_record
|
31
|
+
@form = form_schema
|
32
|
+
@view = new_view
|
34
33
|
end
|
35
34
|
|
36
35
|
# Creates a record, or shows the validation errors
|
37
36
|
def create
|
38
|
-
@record =
|
37
|
+
@record = build_record
|
38
|
+
set_record_attributes
|
39
39
|
|
40
|
-
if
|
40
|
+
if save_record
|
41
41
|
redirect_to polymorphic_path(Super::Link.polymorphic_parts(@record))
|
42
42
|
else
|
43
|
-
@
|
44
|
-
@
|
43
|
+
@current_action = ActionInquirer.new!
|
44
|
+
@form = form_schema
|
45
|
+
@view = new_view
|
45
46
|
render :new, status: :bad_request
|
46
47
|
end
|
47
48
|
end
|
48
49
|
|
49
50
|
# Displays a form to allow the user to update an existing record
|
50
51
|
def edit
|
51
|
-
@record =
|
52
|
-
@form =
|
53
|
-
@view =
|
52
|
+
@record = load_record
|
53
|
+
@form = form_schema
|
54
|
+
@view = edit_view
|
54
55
|
end
|
55
56
|
|
56
57
|
# Updates a record, or shows validation errors
|
57
58
|
def update
|
58
|
-
@record =
|
59
|
+
@record = load_record
|
60
|
+
set_record_attributes
|
59
61
|
|
60
|
-
if
|
62
|
+
if save_record
|
61
63
|
redirect_to polymorphic_path(Super::Link.polymorphic_parts(@record))
|
62
64
|
else
|
63
|
-
@
|
64
|
-
@
|
65
|
+
@current_action = ActionInquirer.edit!
|
66
|
+
@form = form_schema
|
67
|
+
@view = edit_view
|
65
68
|
render :edit, status: :bad_request
|
66
69
|
end
|
67
70
|
end
|
68
71
|
|
69
72
|
# Deletes a record, or shows validation errors
|
70
73
|
def destroy
|
71
|
-
@record =
|
74
|
+
@record = load_record
|
72
75
|
|
73
|
-
if
|
76
|
+
if destroy_record
|
74
77
|
redirect_to polymorphic_path(Super::Link.polymorphic_parts(@record))
|
75
78
|
else
|
76
79
|
flash.alert = "Couldn't delete record"
|
@@ -83,19 +86,23 @@ module Super
|
|
83
86
|
|
84
87
|
private
|
85
88
|
|
86
|
-
def
|
87
|
-
@
|
89
|
+
def current_action
|
90
|
+
@current_action ||=
|
91
|
+
ActionInquirer.new(
|
92
|
+
ActionInquirer.default_for_resources,
|
93
|
+
params[:action]
|
94
|
+
)
|
88
95
|
end
|
89
96
|
|
90
|
-
def
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
def action_inquirer_for(action)
|
95
|
-
ActionInquirer.new(
|
97
|
+
def with_current_action(action)
|
98
|
+
original = @current_action
|
99
|
+
@current_action = ActionInquirer.new(
|
96
100
|
ActionInquirer.default_for_resources,
|
97
101
|
action
|
98
102
|
)
|
103
|
+
yield
|
104
|
+
ensure
|
105
|
+
@current_action = original
|
99
106
|
end
|
100
107
|
end
|
101
108
|
end
|
@@ -0,0 +1,276 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Super
|
4
|
+
# Various methods that determine the behavior of your controllers. These
|
5
|
+
# methods can and should be overridden.
|
6
|
+
class SubstructureController < ActionController::Base
|
7
|
+
private
|
8
|
+
|
9
|
+
helper_method def model
|
10
|
+
raise NotImplementedError
|
11
|
+
end
|
12
|
+
|
13
|
+
# This is an optional method
|
14
|
+
#
|
15
|
+
# @return [String]
|
16
|
+
helper_method def title
|
17
|
+
model.name.pluralize
|
18
|
+
end
|
19
|
+
|
20
|
+
# Configures what database records are visible on load. This is an optional
|
21
|
+
# method, it defaults to "`all`" methods
|
22
|
+
#
|
23
|
+
# @return [ActiveRecord::Relation]
|
24
|
+
helper_method def base_scope
|
25
|
+
model.all
|
26
|
+
end
|
27
|
+
|
28
|
+
# Configures the fields that are displayed on the index and show actions.
|
29
|
+
# This is a required method
|
30
|
+
#
|
31
|
+
# @return [Display]
|
32
|
+
helper_method def display_schema
|
33
|
+
Display.new do |fields, type|
|
34
|
+
Display::Guesser.new(model: model, action: current_action, fields: fields, type: type).call
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# Configures the editable fields on the new and edit actions. This is a
|
39
|
+
# required method
|
40
|
+
#
|
41
|
+
# @return [Form]
|
42
|
+
helper_method def form_schema
|
43
|
+
Form.new do |fields, type|
|
44
|
+
Form::Guesser.new(model: model, fields: fields, type: type).call
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# Configures which parameters could be written to the database. This is a
|
49
|
+
# required method
|
50
|
+
#
|
51
|
+
# @return [ActionController::Parameters]
|
52
|
+
helper_method def permitted_params
|
53
|
+
strong_params =
|
54
|
+
if current_action.create?
|
55
|
+
with_current_action("new") do
|
56
|
+
Super::Form::StrongParams.new(form_schema)
|
57
|
+
end
|
58
|
+
elsif current_action.update?
|
59
|
+
with_current_action("edit") do
|
60
|
+
Super::Form::StrongParams.new(form_schema)
|
61
|
+
end
|
62
|
+
else
|
63
|
+
Super::Form::StrongParams.new(form_schema)
|
64
|
+
end
|
65
|
+
params.require(strong_params.require(model)).permit(strong_params.permit)
|
66
|
+
end
|
67
|
+
|
68
|
+
# Configures the actions linked to on the index page. This is an optional
|
69
|
+
# method
|
70
|
+
#
|
71
|
+
# @return [Array<Link>]
|
72
|
+
helper_method def collection_actions
|
73
|
+
Super::Link.find_all(:new)
|
74
|
+
end
|
75
|
+
|
76
|
+
# Configures the actions linked to on the show page as well as each row of
|
77
|
+
# the table on the index page. This is an optional method
|
78
|
+
#
|
79
|
+
# Favor the `record` argument over the `@record` instance variable;
|
80
|
+
# `@record` won't always be set, notably on the index page where it's
|
81
|
+
# called on every row
|
82
|
+
#
|
83
|
+
# @return [Array<Link>]
|
84
|
+
helper_method def member_actions(record)
|
85
|
+
if current_action.show?
|
86
|
+
Super::Link.find_all(:edit, :destroy)
|
87
|
+
elsif current_action.edit?
|
88
|
+
Super::Link.find_all(:show, :destroy)
|
89
|
+
else
|
90
|
+
Super::Link.find_all(:show, :edit, :destroy)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
helper_method def filters_enabled?
|
95
|
+
true
|
96
|
+
end
|
97
|
+
|
98
|
+
helper_method def filter_schema
|
99
|
+
Super::Filter.new do |fields, type|
|
100
|
+
Super::Filter::Guesser.new(model: model, fields: fields, type: type).call
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
helper_method def sort_enabled?
|
105
|
+
true
|
106
|
+
end
|
107
|
+
|
108
|
+
helper_method def sortable_columns
|
109
|
+
action = ActionInquirer.new(
|
110
|
+
ActionInquirer.default_for_resources,
|
111
|
+
"index"
|
112
|
+
)
|
113
|
+
attribute_names =
|
114
|
+
display_schema.each_attribute.map do |key, val|
|
115
|
+
val = val.build if val.respond_to?(:build)
|
116
|
+
key if val.real?
|
117
|
+
end
|
118
|
+
|
119
|
+
attribute_names.compact
|
120
|
+
end
|
121
|
+
|
122
|
+
helper_method def default_sort
|
123
|
+
{ id: :desc }
|
124
|
+
end
|
125
|
+
|
126
|
+
# Specifies how many records to show per page
|
127
|
+
#
|
128
|
+
# @return [ActiveRecord::Relation]
|
129
|
+
helper_method def records_per_page
|
130
|
+
Super.configuration.index_records_per_page
|
131
|
+
end
|
132
|
+
|
133
|
+
def load_records
|
134
|
+
base_scope
|
135
|
+
end
|
136
|
+
|
137
|
+
def load_record
|
138
|
+
base_scope.find(params[:id])
|
139
|
+
end
|
140
|
+
|
141
|
+
def build_record
|
142
|
+
base_scope.build
|
143
|
+
end
|
144
|
+
|
145
|
+
def set_record_attributes
|
146
|
+
@record.attributes = permitted_params
|
147
|
+
end
|
148
|
+
|
149
|
+
def save_record
|
150
|
+
@record.save
|
151
|
+
end
|
152
|
+
|
153
|
+
def destroy_record
|
154
|
+
@record.destroy
|
155
|
+
end
|
156
|
+
|
157
|
+
def initialize_query_form
|
158
|
+
Super::Query::FormObject.new(
|
159
|
+
model: model,
|
160
|
+
params: params,
|
161
|
+
namespace: :q,
|
162
|
+
current_path: request.path,
|
163
|
+
)
|
164
|
+
end
|
165
|
+
|
166
|
+
def apply_queries
|
167
|
+
@query_form.apply_changes(@records)
|
168
|
+
end
|
169
|
+
|
170
|
+
def initialize_filter_form
|
171
|
+
if filters_enabled?
|
172
|
+
@query_form.add(
|
173
|
+
Super::Filter::FormObject,
|
174
|
+
namespace: :f,
|
175
|
+
schema: filter_schema
|
176
|
+
)
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
def initialize_sort_form
|
181
|
+
if sort_enabled?
|
182
|
+
@query_form.add(
|
183
|
+
Super::Sort::FormObject,
|
184
|
+
namespace: :s,
|
185
|
+
default: default_sort,
|
186
|
+
sortable_columns: sortable_columns
|
187
|
+
)
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
# Sets up pagination
|
192
|
+
#
|
193
|
+
# @return [Pagination]
|
194
|
+
def initialize_pagination
|
195
|
+
Pagination.new(
|
196
|
+
total_count: @records.size,
|
197
|
+
limit: records_per_page,
|
198
|
+
query_params: request.GET,
|
199
|
+
page_query_param: :page
|
200
|
+
)
|
201
|
+
end
|
202
|
+
|
203
|
+
# Paginates
|
204
|
+
#
|
205
|
+
# @return [ActiveRecord::Relation]
|
206
|
+
def paginate_records
|
207
|
+
@records
|
208
|
+
.limit(@pagination.limit)
|
209
|
+
.offset(@pagination.offset)
|
210
|
+
end
|
211
|
+
|
212
|
+
def index_view
|
213
|
+
Super::Layout.new(
|
214
|
+
mains: [
|
215
|
+
Super::Panel.new(
|
216
|
+
Super::Partial.new("collection_header"),
|
217
|
+
:@display
|
218
|
+
),
|
219
|
+
],
|
220
|
+
asides: [
|
221
|
+
:@query_form,
|
222
|
+
]
|
223
|
+
)
|
224
|
+
end
|
225
|
+
|
226
|
+
def show_view
|
227
|
+
Super::Layout.new(
|
228
|
+
mains: [
|
229
|
+
Super::Panel.new(
|
230
|
+
Super::Partial.new("member_header"),
|
231
|
+
:@display
|
232
|
+
),
|
233
|
+
]
|
234
|
+
)
|
235
|
+
end
|
236
|
+
|
237
|
+
def new_view
|
238
|
+
Super::Layout.new(
|
239
|
+
mains: [
|
240
|
+
Super::Panel.new(
|
241
|
+
Super::Partial.new("collection_header"),
|
242
|
+
:@form
|
243
|
+
),
|
244
|
+
]
|
245
|
+
)
|
246
|
+
end
|
247
|
+
|
248
|
+
def edit_view
|
249
|
+
Super::Layout.new(
|
250
|
+
mains: [
|
251
|
+
Super::Panel.new(
|
252
|
+
Super::Partial.new("member_header"),
|
253
|
+
:@form
|
254
|
+
),
|
255
|
+
]
|
256
|
+
)
|
257
|
+
end
|
258
|
+
|
259
|
+
concerning :Sitewide do
|
260
|
+
included do
|
261
|
+
helper_method :site_title
|
262
|
+
helper_method :site_navigation
|
263
|
+
end
|
264
|
+
|
265
|
+
private
|
266
|
+
|
267
|
+
def site_title
|
268
|
+
Super.configuration.title
|
269
|
+
end
|
270
|
+
|
271
|
+
def site_navigation
|
272
|
+
Super::Navigation.new(&:all)
|
273
|
+
end
|
274
|
+
end
|
275
|
+
end
|
276
|
+
end
|
@@ -1,7 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Super
|
4
|
+
# These are form builder view helpers. They are similar to what Rails ships
|
5
|
+
# out of the box but adds some styling and functionality.
|
6
|
+
#
|
7
|
+
# These helpers are available both in Super views and in your application's
|
8
|
+
# views.
|
4
9
|
module FormBuilderHelper
|
10
|
+
# Super's version of `#form_for`
|
5
11
|
def super_form_for(record, options = {}, &block)
|
6
12
|
original = ActionView::Base.field_error_proc
|
7
13
|
ActionView::Base.field_error_proc = Form::Builder::FIELD_ERROR_PROC
|
@@ -12,6 +18,7 @@ module Super
|
|
12
18
|
ActionView::Base.field_error_proc = original
|
13
19
|
end
|
14
20
|
|
21
|
+
# Super's version of `#form_with`
|
15
22
|
def super_form_with(**options, &block)
|
16
23
|
original = ActionView::Base.field_error_proc
|
17
24
|
ActionView::Base.field_error_proc = Form::Builder::FIELD_ERROR_PROC
|
@@ -13,11 +13,7 @@
|
|
13
13
|
<% if stylesheet.handler.sprockets? %>
|
14
14
|
<%= stylesheet_link_tag(stylesheet.path, **stylesheet.arguments) %>
|
15
15
|
<% elsif stylesheet.handler.webpacker? %>
|
16
|
-
|
17
|
-
<%= stylesheet_packs_with_chunks_tag(stylesheet.path) %>
|
18
|
-
<% else %>
|
19
|
-
<%= stylesheet_pack_tag(stylesheet.path, **stylesheet.arguments) %>
|
20
|
-
<% end %>
|
16
|
+
<%= stylesheet_pack_tag(stylesheet.path, **stylesheet.arguments) %>
|
21
17
|
<% end %>
|
22
18
|
<% end %>
|
23
19
|
|
@@ -25,23 +21,14 @@
|
|
25
21
|
<% if javascript.handler.sprockets? %>
|
26
22
|
<%= javascript_include_tag(javascript.path) %>
|
27
23
|
<% elsif javascript.handler.webpacker? %>
|
28
|
-
|
29
|
-
<%= javascript_packs_with_chunks_tag(javascript.path) %>
|
30
|
-
<% else %>
|
31
|
-
<%= javascript_pack_tag(javascript.path) %>
|
32
|
-
<% end %>
|
24
|
+
<%= javascript_pack_tag(javascript.path) %>
|
33
25
|
<% end %>
|
34
26
|
<% end %>
|
35
27
|
</head>
|
36
28
|
|
37
29
|
<body class="font-sans pb-4">
|
38
30
|
<div class="px-4">
|
39
|
-
|
40
|
-
<h1 class="text-lg font-bold mr-6 mb-1"><%= Super.configuration.title %></h1>
|
41
|
-
<% Super::Navigation::Automatic.new.each do |text, href| %>
|
42
|
-
<%= link_to(text, href, class: "inline-block mr-6") %>
|
43
|
-
<% end %>
|
44
|
-
</header>
|
31
|
+
<%= render "site_header" %>
|
45
32
|
|
46
33
|
<%= render "flash" %>
|
47
34
|
|
@@ -49,9 +36,7 @@
|
|
49
36
|
|
50
37
|
<%= yield %>
|
51
38
|
|
52
|
-
|
53
|
-
<%= t("super.layout.powered_by", env: Rails.env.capitalize, version: Super::VERSION) %>
|
54
|
-
</div>
|
39
|
+
<%= render "site_footer" %>
|
55
40
|
</div>
|
56
41
|
</body>
|
57
42
|
</html>
|