super 0.0.15 → 0.19.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (75) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -2
  3. data/app/assets/javascripts/super/application.js +1403 -127
  4. data/app/assets/stylesheets/super/application.css +90708 -90026
  5. data/app/controllers/super/application_controller.rb +73 -40
  6. data/app/controllers/super/substructure_controller.rb +349 -0
  7. data/app/helpers/super/form_builder_helper.rb +7 -0
  8. data/app/views/layouts/super/application.html.erb +3 -21
  9. data/app/views/super/application/_batch_button.html.erb +12 -0
  10. data/app/views/super/application/_batch_checkbox.csv.erb +1 -0
  11. data/app/views/super/application/_batch_checkbox.html.erb +5 -0
  12. data/app/views/super/application/_batch_form.html.erb +3 -0
  13. data/app/views/super/application/_collection_header.html.erb +8 -7
  14. data/app/views/super/application/_csv_button.html.erb +25 -0
  15. data/app/views/super/application/_display_actions.html.erb +2 -2
  16. data/app/views/super/application/_display_index.html.erb +1 -1
  17. data/app/views/super/application/_display_show.html.erb +1 -1
  18. data/app/views/super/application/_filter.html.erb +62 -2
  19. data/app/views/super/application/_layout.html.erb +13 -14
  20. data/app/views/super/application/_link.html.erb +8 -0
  21. data/app/views/super/application/_member_header.html.erb +8 -8
  22. data/app/views/super/application/_pagination.html.erb +2 -1
  23. data/app/views/super/application/_site_footer.html.erb +3 -0
  24. data/app/views/super/application/_site_header.html.erb +17 -0
  25. data/app/views/super/application/_sort_expression.html.erb +2 -2
  26. data/app/views/super/application/_view_chain.html.erb +5 -0
  27. data/app/views/super/application/index.csv.erb +14 -0
  28. data/config/locales/en.yml +8 -0
  29. data/frontend/super-frontend/dist/application.css +90708 -90026
  30. data/frontend/super-frontend/dist/application.js +1403 -127
  31. data/frontend/super-frontend/dist/package.json +13 -0
  32. data/lib/generators/super/install/templates/base_controller.rb.tt +0 -8
  33. data/lib/generators/super/resource/templates/resources_controller.rb.tt +4 -4
  34. data/lib/generators/super/webpacker/USAGE +1 -7
  35. data/lib/generators/super/webpacker/templates/pack_super_application.js.tt +2 -0
  36. data/lib/generators/super/webpacker/webpacker_generator.rb +10 -6
  37. data/lib/super/action_inquirer.rb +7 -0
  38. data/lib/super/badge.rb +0 -1
  39. data/lib/super/cheat.rb +7 -6
  40. data/lib/super/display/guesser.rb +1 -1
  41. data/lib/super/display/schema_types.rb +6 -1
  42. data/lib/super/display.rb +2 -1
  43. data/lib/super/engine.rb +5 -0
  44. data/lib/super/error.rb +12 -0
  45. data/lib/super/filter/form_object.rb +74 -48
  46. data/lib/super/filter/guesser.rb +2 -0
  47. data/lib/super/filter/operator.rb +90 -64
  48. data/lib/super/filter/schema_types.rb +63 -80
  49. data/lib/super/filter.rb +1 -1
  50. data/lib/super/form/builder.rb +6 -3
  51. data/lib/super/form/field_transcript.rb +43 -0
  52. data/lib/super/form/guesser.rb +1 -1
  53. data/lib/super/form/schema_types.rb +11 -20
  54. data/lib/super/layout.rb +9 -33
  55. data/lib/super/link.rb +3 -8
  56. data/lib/super/link_builder.rb +0 -4
  57. data/lib/super/packaged_asset.rb +49 -0
  58. data/lib/super/pagination.rb +4 -3
  59. data/lib/super/reorderable_hash.rb +88 -0
  60. data/lib/super/reset.rb +24 -0
  61. data/lib/super/schema.rb +4 -0
  62. data/lib/super/version.rb +1 -1
  63. data/lib/super/view_chain.rb +25 -0
  64. data/lib/super.rb +4 -1
  65. data/lib/tasks/super/cheat.rake +1 -1
  66. metadata +51 -15
  67. data/app/views/super/application/_filter_type_select.html.erb +0 -21
  68. data/app/views/super/application/_filter_type_text.html.erb +0 -18
  69. data/app/views/super/application/_filter_type_timestamp.html.erb +0 -24
  70. data/app/views/super/application/_form_field_select.html.erb +0 -1
  71. data/lib/generators/super/webpacker/templates/pack_super_application.js.erb.tt +0 -2
  72. data/lib/super/controls/optional.rb +0 -122
  73. data/lib/super/controls/steps.rb +0 -133
  74. data/lib/super/controls/view.rb +0 -55
  75. data/lib/super/controls.rb +0 -22
@@ -2,78 +2,88 @@
2
2
 
3
3
  module Super
4
4
  # Provides a default implementation for each of the resourceful actions
5
- class ApplicationController < ActionController::Base
5
+ class ApplicationController < SubstructureController
6
6
  include ClientError::Handling
7
7
 
8
- helper_method :action_inquirer
9
- helper_method :controls
10
- helper_method :navigation
8
+ before_action do
9
+ if Super::PackagedAsset.warning_message
10
+ flash.now[:mismatching_package_json_gemfile_versions] = Super::PackagedAsset.warning_message
11
+ end
12
+ end
11
13
 
12
14
  # Displays a list of records to the user
13
15
  def index
14
- @records = controls.load_records(action: action_inquirer, params: params)
15
- @display = controls.display_schema(action: action_inquirer).apply(action: action_inquirer)
16
- @view = controls.index_view
17
- @query_form = controls.initialize_query_form(params: params, current_path: request.path)
18
- controls.initialize_filter_form(query_form: @query_form)
19
- controls.initialize_sort_form(query_form: @query_form)
20
- @records = controls.apply_queries(query_form: @query_form, records: @records)
16
+ if request.format.ref == :csv && !csv_enabled?
17
+ params_for_rebuilding_url = params.to_unsafe_hash
18
+ params_for_rebuilding_url.delete("format")
19
+ return redirect_to params_for_rebuilding_url
20
+ end
21
+
22
+ @records = load_records
23
+ @display = display_schema.apply(action: current_action, format: request.format)
24
+ @view = index_view
25
+ @query_form = initialize_query_form
26
+ initialize_filter_form
27
+ initialize_sort_form
28
+ @records = apply_queries
21
29
  end
22
30
 
23
31
  # Displays a specific record to the user
24
32
  def show
25
- @record = controls.load_record(action: action_inquirer, params: params)
26
- @display = controls.display_schema(action: action_inquirer).apply(action: action_inquirer)
27
- @view = controls.show_view
33
+ @record = load_record
34
+ @display = display_schema.apply(action: current_action, format: request.format)
35
+ @view = show_view
28
36
  end
29
37
 
30
38
  # Displays a form to allow the user to create a new record
31
39
  def new
32
- @record = controls.build_record(action: action_inquirer)
33
- @form = controls.form_schema(action: action_inquirer)
34
- @view = controls.new_view
40
+ @record = build_record
41
+ @form = form_schema
42
+ @view = new_view
35
43
  end
36
44
 
37
45
  # Creates a record, or shows the validation errors
38
46
  def create
39
- @record = controls.build_record_with_params(action: action_inquirer, params: params)
47
+ @record = build_record
48
+ set_record_attributes
40
49
 
41
- if controls.save_record(action: action_inquirer, record: @record, params: params)
50
+ if save_record
42
51
  redirect_to polymorphic_path(Super::Link.polymorphic_parts(@record))
43
52
  else
44
- @action_inquirer = ActionInquirer.new!
45
- @form = controls.form_schema(action: action_inquirer)
46
- @view = controls.new_view
53
+ @current_action = ActionInquirer.new!
54
+ @form = form_schema
55
+ @view = new_view
47
56
  render :new, status: :bad_request
48
57
  end
49
58
  end
50
59
 
51
60
  # Displays a form to allow the user to update an existing record
52
61
  def edit
53
- @record = controls.load_record(action: action_inquirer, params: params)
54
- @form = controls.form_schema(action: action_inquirer)
55
- @view = controls.edit_view
62
+ @record = load_record
63
+ @form = form_schema
64
+ @view = edit_view
56
65
  end
57
66
 
58
67
  # Updates a record, or shows validation errors
59
68
  def update
60
- @record = controls.load_record(action: action_inquirer, params: params)
69
+ @record = load_record
70
+ set_record_attributes
61
71
 
62
- if controls.update_record(action: action_inquirer, record: @record, params: params)
72
+ if save_record
63
73
  redirect_to polymorphic_path(Super::Link.polymorphic_parts(@record))
64
74
  else
65
- @action_inquirer = ActionInquirer.edit!
66
- @form = controls.form_schema(action: action_inquirer)
67
- @view = controls.edit_view
75
+ @current_action = ActionInquirer.edit!
76
+ @form = form_schema
77
+ @view = edit_view
68
78
  render :edit, status: :bad_request
69
79
  end
70
80
  end
71
81
 
72
82
  # Deletes a record, or shows validation errors
73
83
  def destroy
74
- @record = controls.load_record(action: action_inquirer, params: params)
84
+ @record = load_record
75
85
 
76
- if controls.destroy_record(action: action_inquirer, record: @record, params: params)
86
+ if destroy_record
77
87
  redirect_to polymorphic_path(Super::Link.polymorphic_parts(@record))
78
88
  else
79
89
  flash.alert = "Couldn't delete record"
@@ -86,20 +96,43 @@ module Super
86
96
 
87
97
  private
88
98
 
89
- def controls
90
- @controls ||= new_controls
91
- end
92
-
93
- def action_inquirer
94
- @action_inquirer ||=
99
+ helper_method def current_action
100
+ @current_action ||=
95
101
  ActionInquirer.new(
96
102
  ActionInquirer.default_for_resources,
97
103
  params[:action]
98
104
  )
99
105
  end
100
106
 
101
- def navigation
102
- Navigation.new(&:all)
107
+ def with_current_action(action)
108
+ original = @current_action
109
+ @current_action = ActionInquirer.new(
110
+ ActionInquirer.default_for_resources,
111
+ action
112
+ )
113
+ yield
114
+ ensure
115
+ @current_action = original
116
+ end
117
+
118
+ helper_method def resolved_member_actions(record)
119
+ member_actions(record).map do |action|
120
+ if action.respond_to?(:resolve)
121
+ action.resolve(record: record, params: params)
122
+ else
123
+ action
124
+ end
125
+ end
126
+ end
127
+
128
+ helper_method def resolved_collection_actions
129
+ collection_actions.map do |action|
130
+ if action.respond_to?(:resolve)
131
+ action.resolve(params: params)
132
+ else
133
+ action
134
+ end
135
+ end
103
136
  end
104
137
  end
105
138
  end
@@ -0,0 +1,349 @@
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
+ def self.batch(action_name)
8
+ mod = Module.new do
9
+ define_method(action_name) do
10
+ if !params[:batch]
11
+ flash.alert = I18n.t("super.batch.none_error")
12
+ return render :nothing, status: :bad_request
13
+ end
14
+
15
+ super()
16
+ end
17
+ end
18
+
19
+ const_set("Batch__#{action_name}__#{SecureRandom.hex(4)}", mod)
20
+ prepend(mod)
21
+
22
+ action_name
23
+ end
24
+
25
+ private
26
+
27
+ helper_method def model
28
+ raise Error::NotImplementedError
29
+ end
30
+
31
+ # This is an optional method
32
+ #
33
+ # @return [String]
34
+ helper_method def title
35
+ model.name.pluralize
36
+ end
37
+
38
+ # This defines what to set in the <title> tag. It works in conjunction with
39
+ # the `#site_title` method
40
+ #
41
+ # @return [String, void]
42
+ helper_method def page_title
43
+ model.name.pluralize
44
+ rescue Error::NotImplementedError, NameError
45
+ return nil
46
+ end
47
+
48
+ # Configures what database records are visible on load. This is an optional
49
+ # method, it defaults to "`all`" methods
50
+ #
51
+ # @return [ActiveRecord::Relation]
52
+ helper_method def base_scope
53
+ model.all
54
+ end
55
+
56
+ # Configures the fields that are displayed on the index and show actions.
57
+ # This is a required method
58
+ #
59
+ # @return [Display]
60
+ helper_method def display_schema
61
+ Display.new do |fields, type|
62
+ Display::Guesser.new(model: model, action: current_action, fields: fields, type: type).call
63
+ end
64
+ end
65
+
66
+ # Configures the editable fields on the new and edit actions. This is a
67
+ # required method
68
+ #
69
+ # @return [Form]
70
+ helper_method def form_schema
71
+ Form.new do |fields, type|
72
+ Form::Guesser.new(model: model, fields: fields, type: type).call
73
+ end
74
+ end
75
+
76
+ # Configures which parameters could be written to the database. This is a
77
+ # required method
78
+ #
79
+ # @return [ActionController::Parameters]
80
+ helper_method def permitted_params
81
+ strong_params =
82
+ if current_action.create?
83
+ with_current_action("new") do
84
+ Super::Form::StrongParams.new(form_schema)
85
+ end
86
+ elsif current_action.update?
87
+ with_current_action("edit") do
88
+ Super::Form::StrongParams.new(form_schema)
89
+ end
90
+ else
91
+ Super::Form::StrongParams.new(form_schema)
92
+ end
93
+ params.require(strong_params.require(model)).permit(strong_params.permit)
94
+ end
95
+
96
+ # Configures the actions linked to on the index page. This is an optional
97
+ # method
98
+ #
99
+ # @return [Array<Link>]
100
+ helper_method def collection_actions
101
+ if current_action.index?
102
+ [
103
+ Super::Partial.new("csv_button"),
104
+ Super::Partial.new("batch_button"),
105
+ Super::Link.find(:new)
106
+ ]
107
+ else
108
+ Super::Link.find_all(:new)
109
+ end
110
+ end
111
+
112
+ # Configures the actions linked to on the show page as well as each row of
113
+ # the table on the index page. This is an optional method
114
+ #
115
+ # Favor the `record` argument over the `@record` instance variable;
116
+ # `@record` won't always be set, notably on the index page where it's
117
+ # called on every row
118
+ #
119
+ # @return [Array<Link>]
120
+ helper_method def member_actions(record)
121
+ if current_action.show?
122
+ Super::Link.find_all(:edit, :destroy)
123
+ elsif current_action.edit?
124
+ Super::Link.find_all(:show, :destroy)
125
+ else
126
+ Super::Link.find_all(:show, :edit, :destroy)
127
+ end
128
+ end
129
+
130
+ helper_method def filters_enabled?
131
+ true
132
+ end
133
+
134
+ helper_method def filter_schema
135
+ Super::Filter.new do |fields, type|
136
+ Super::Filter::Guesser.new(model: model, fields: fields, type: type).call
137
+ end
138
+ end
139
+
140
+ helper_method def sort_enabled?
141
+ true
142
+ end
143
+
144
+ helper_method def sortable_columns
145
+ action = ActionInquirer.new(
146
+ ActionInquirer.default_for_resources,
147
+ "index"
148
+ )
149
+ attribute_names =
150
+ display_schema.each_attribute.map do |key, val|
151
+ val = val.build if val.respond_to?(:build)
152
+ key if val.real?
153
+ end
154
+
155
+ attribute_names.compact
156
+ end
157
+
158
+ helper_method def default_sort
159
+ { id: :desc }
160
+ end
161
+
162
+ # Specifies how many records to show per page
163
+ #
164
+ # @return [ActiveRecord::Relation]
165
+ helper_method def records_per_page
166
+ Super.configuration.index_records_per_page
167
+ end
168
+
169
+ helper_method def batch_actions_enabled?
170
+ true
171
+ end
172
+
173
+ helper_method def batch_actions
174
+ [
175
+ ]
176
+ end
177
+
178
+ def load_records
179
+ base_scope
180
+ end
181
+
182
+ def load_record
183
+ base_scope.find(params[:id])
184
+ end
185
+
186
+ def build_record
187
+ base_scope.build
188
+ end
189
+
190
+ def set_record_attributes
191
+ @record.attributes = permitted_params
192
+ end
193
+
194
+ def save_record
195
+ @record.save
196
+ end
197
+
198
+ def destroy_record
199
+ @record.destroy
200
+ end
201
+
202
+ def initialize_query_form
203
+ Super::Query::FormObject.new(
204
+ model: model,
205
+ params: params,
206
+ namespace: :q,
207
+ current_path: request.path,
208
+ )
209
+ end
210
+
211
+ def apply_queries
212
+ @query_form.apply_changes(@records)
213
+ end
214
+
215
+ def initialize_filter_form
216
+ if filters_enabled?
217
+ @query_form.add(
218
+ Super::Filter::FormObject,
219
+ namespace: :f,
220
+ schema: filter_schema
221
+ )
222
+ end
223
+ end
224
+
225
+ def initialize_sort_form
226
+ if sort_enabled?
227
+ @query_form.add(
228
+ Super::Sort::FormObject,
229
+ namespace: :s,
230
+ default: default_sort,
231
+ sortable_columns: sortable_columns
232
+ )
233
+ end
234
+ end
235
+
236
+ helper_method def pagination_disabled_param
237
+ :_all_pages
238
+ end
239
+
240
+ def pagination_enabled?
241
+ !params.key?(pagination_disabled_param)
242
+ end
243
+
244
+ # Sets up pagination
245
+ #
246
+ # @return [Pagination]
247
+ def initialize_pagination
248
+ Pagination.new(
249
+ total_count: @records.size,
250
+ limit: records_per_page,
251
+ query_params: request.GET,
252
+ page_query_param: :page
253
+ )
254
+ end
255
+
256
+ # Paginates
257
+ #
258
+ # @return [ActiveRecord::Relation]
259
+ def paginate_records
260
+ return @records if !pagination_enabled?
261
+
262
+ @records
263
+ .limit(@pagination.limit)
264
+ .offset(@pagination.offset)
265
+ end
266
+
267
+ helper_method def csv_enabled?
268
+ true
269
+ end
270
+
271
+ def index_view
272
+ Super::Layout.new(
273
+ main: Super::ViewChain.new(
274
+ main_panel: Super::Panel.new,
275
+ batch_form: Super::Partial.new("batch_form"),
276
+ main_header: Super::Partial.new("collection_header"),
277
+ main: :@display
278
+ ),
279
+ aside: Super::ViewChain.new(
280
+ main: :@query_form
281
+ )
282
+ )
283
+ end
284
+
285
+ def show_view
286
+ Super::Layout.new(
287
+ main: Super::ViewChain.new(
288
+ main_panel: Super::Panel.new,
289
+ main_header: Super::Partial.new("collection_header"),
290
+ main: :@display
291
+ )
292
+ )
293
+ end
294
+
295
+ def new_view
296
+ Super::Layout.new(
297
+ main: Super::ViewChain.new(
298
+ main_panel: Super::Panel.new,
299
+ main_header: Super::Partial.new("collection_header"),
300
+ main: :@form
301
+ )
302
+ )
303
+ end
304
+
305
+ def edit_view
306
+ Super::Layout.new(
307
+ main: Super::ViewChain.new(
308
+ main_panel: Super::Panel.new,
309
+ main_header: Super::Partial.new("member_header"),
310
+ main: :@form
311
+ )
312
+ )
313
+ end
314
+
315
+ concerning :Sitewide do
316
+ included do
317
+ helper_method :site_title
318
+ helper_method :site_navigation
319
+ helper_method :document_title
320
+ end
321
+
322
+ private
323
+
324
+ def site_title
325
+ Super.configuration.title
326
+ end
327
+
328
+ def site_navigation
329
+ Super::Navigation.new(&:all)
330
+ end
331
+
332
+ def document_title
333
+ if instance_variable_defined?(:@document_title)
334
+ return @document_title
335
+ end
336
+
337
+ document_title_segments.map(&:presence).compact.join(document_title_separator)
338
+ end
339
+
340
+ def document_title_segments
341
+ @document_title_segments ||= [page_title, site_title]
342
+ end
343
+
344
+ def document_title_separator
345
+ @document_title_separator ||= " - "
346
+ end
347
+ end
348
+ end
349
+ 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
@@ -1,7 +1,7 @@
1
1
  <!DOCTYPE html>
2
2
  <html class="bg-gray-100">
3
3
  <head>
4
- <title><%= Super.configuration.title %></title>
4
+ <title><%= document_title %></title>
5
5
  <%= csrf_meta_tags %>
6
6
  <% if respond_to?(:csp_meta_tag) -%>
7
7
  <%= csp_meta_tag %>
@@ -28,23 +28,7 @@
28
28
 
29
29
  <body class="font-sans pb-4">
30
30
  <div class="px-4">
31
- <header class="pt-4">
32
- <h1 class="text-lg font-bold mr-6 mb-1"><%= Super.configuration.title %></h1>
33
- <% navigation.definition.each do |link_or_menu| %>
34
- <% if link_or_menu.is_a?(Super::Link) %>
35
- <%= link_or_menu.to_s(default_options: { class: "inline-block mr-6" }) %>
36
- <% else %>
37
- <details class="details-reset select-none inline-block mr-6" data-controller="click-outside-to-close" data-action="click@window->click-outside-to-close#close">
38
- <summary class="text-blue-700"><%= link_or_menu.title %></summary>
39
- <ul class="absolute bg-white shadow-md px-4 py-3">
40
- <% link_or_menu.links.each do |link| %>
41
- <li><%= link.to_s(default_options: { class: "" }) %></li>
42
- <% end %>
43
- </ul>
44
- </details>
45
- <% end %>
46
- <% end %>
47
- </header>
31
+ <%= render "site_header" %>
48
32
 
49
33
  <%= render "flash" %>
50
34
 
@@ -52,9 +36,7 @@
52
36
 
53
37
  <%= yield %>
54
38
 
55
- <div class="pt-8 text-sm text-gray-800">
56
- <%= t("super.layout.powered_by", env: Rails.env.capitalize, version: Super::VERSION) %>
57
- </div>
39
+ <%= render "site_footer" %>
58
40
  </div>
59
41
  </body>
60
42
  </html>
@@ -0,0 +1,12 @@
1
+ <% default_options = {} unless defined?(default_options) %>
2
+ <% if batch_actions_enabled? && batch_actions.any? %>
3
+ <details class="details-reset details-backdrop-transparent inline-block">
4
+ <summary class="cursor-pointer <%= default_options[:class] %>" id="batch-actions">Batch actions</summary>
5
+
6
+ <ul class="absolute bg-white shadow-md px-4 py-3 z-20">
7
+ <% batch_actions.each do |batch_action| %>
8
+ <li><button data-controller="batch" data-batch-method-value="<%= batch_action.options&.dig(:method) || "get" %>" data-batch-action-value="<%= batch_action.href %>" data-action="batch#submit" class="<%= default_options[:class] %>"><%= batch_action.text %></button></li>
9
+ <% end %>
10
+ </ul>
11
+ </details>
12
+ <% end %>
@@ -0,0 +1 @@
1
+ <%= value -%>
@@ -0,0 +1,5 @@
1
+ <div class="whitespace-nowrap gap-1">
2
+ <% html_id = "batch-checkbox-#{value.to_s.gsub(/[^a-z0-9]+/, "-")}" %>
3
+ <input type="checkbox" name="batch[]" value="<%= value %>" id="<%= html_id %>">
4
+ <label for="<%= html_id %>"><%= value %></label>
5
+ </div>
@@ -0,0 +1,3 @@
1
+ <form>
2
+ <%= yield %>
3
+ </form>
@@ -1,15 +1,16 @@
1
1
  <header class="flex justify-between content-end">
2
2
  <h1 class="text-xl">
3
- <%= controls.title %>
3
+ <%= title %>
4
4
  </h1>
5
- <div>
6
- <% controls.collection_actions(action: action_inquirer).each do |link| %>
7
- <%= link.to_s(
5
+ <div class="flex gap-2">
6
+ <% resolved_collection_actions.each do |link| %>
7
+ <%= render(
8
+ link,
8
9
  default_options: {
9
- class: "super-button super-button--border-blue super-button-sm inline-block ml-2"
10
- },
11
- params: params
10
+ class: "super-button super-button--border-blue super-button-sm inline-block"
11
+ }
12
12
  ) %>
13
13
  <% end %>
14
14
  </div>
15
15
  </header>
16
+ <%= yield if block_given? %>
@@ -0,0 +1,25 @@
1
+ <% default_options = {} unless defined?(default_options) %>
2
+ <% if csv_enabled? %>
3
+ <details class="details-reset details-backdrop-dark inline-block">
4
+ <summary class="cursor-pointer <%= default_options[:class] %>"><%= t("super.csv.initial_cta") %></summary>
5
+ <details-dialog class="bg-white shadow-md px-4 py-4 rounded-lg">
6
+ <header class="flex items-center">
7
+ <h1 class="font-semibold border-b-1 flex-1"><%= t("super.csv.modal_header") %></h1>
8
+ <button type="button" data-close-dialog class="flex-initial h-4 w-4"><%= render("super/feather/x") %></button>
9
+ </header>
10
+ <div class="mt-3">
11
+ <% linkable_params = params.to_unsafe_hash %>
12
+ <%= link_to(
13
+ t("super.csv.download_current_cta"),
14
+ linkable_params.merge(format: :csv),
15
+ class: "super-button"
16
+ ) %>
17
+ <%= link_to(
18
+ t("super.csv.download_all_cta"),
19
+ linkable_params.merge(format: :csv, pagination_disabled_param => 1),
20
+ class: "super-button"
21
+ ) %>
22
+ </div>
23
+ </details-dialog>
24
+ </details>
25
+ <% end %>
@@ -1,5 +1,5 @@
1
1
  <div>
2
- <% controls.member_actions(action: action_inquirer).each do |link| %>
3
- <span class="pr-2 last:pr-0"><%= link.to_s(record: record, params: params) %></span>
2
+ <% resolved_member_actions(record).each do |link| %>
3
+ <span class="pr-2 last:pr-0"><%= render link %></span>
4
4
  <% end %>
5
5
  </div>
@@ -4,7 +4,7 @@
4
4
  <tr class="">
5
5
  <% display_index.each_attribute_name do |attribute_name| %>
6
6
  <th class="p-2 first:pl-6 border-b border-b-2 border-gray-400 text-gray-600 text-left text-sm font-normal bg-white top-0 z-10">
7
- <%= controls.model.human_attribute_name(attribute_name) %>
7
+ <%= model.human_attribute_name(attribute_name) %>
8
8
  </th>
9
9
  <% end %>
10
10
  </tr>