super 0.0.16 → 0.19.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/super/application.js +1401 -125
  3. data/app/assets/stylesheets/super/application.css +90702 -90026
  4. data/app/controllers/super/application_controller.rb +49 -6
  5. data/app/controllers/super/substructure_controller.rb +121 -37
  6. data/app/views/layouts/super/application.html.erb +1 -1
  7. data/app/views/super/application/_batch_button.html.erb +12 -0
  8. data/app/views/super/application/_batch_checkbox.csv.erb +1 -0
  9. data/app/views/super/application/_batch_checkbox.html.erb +5 -0
  10. data/app/views/super/application/_batch_form.html.erb +3 -0
  11. data/app/views/super/application/_collection_header.html.erb +7 -6
  12. data/app/views/super/application/_csv_button.html.erb +25 -0
  13. data/app/views/super/application/_display_actions.html.erb +2 -2
  14. data/app/views/super/application/_filter.html.erb +62 -2
  15. data/app/views/super/application/_layout.html.erb +13 -14
  16. data/app/views/super/application/_link.html.erb +8 -0
  17. data/app/views/super/application/_member_header.html.erb +7 -7
  18. data/app/views/super/application/_pagination.html.erb +1 -0
  19. data/app/views/super/application/_site_header.html.erb +4 -4
  20. data/app/views/super/application/_sort_expression.html.erb +2 -2
  21. data/app/views/super/application/_view_chain.html.erb +5 -0
  22. data/app/views/super/application/index.csv.erb +14 -0
  23. data/config/locales/en.yml +8 -0
  24. data/frontend/super-frontend/dist/application.css +90702 -90026
  25. data/frontend/super-frontend/dist/application.js +1401 -125
  26. data/frontend/super-frontend/dist/package.json +13 -0
  27. data/lib/generators/super/webpacker/USAGE +1 -7
  28. data/lib/generators/super/webpacker/templates/pack_super_application.js.tt +2 -0
  29. data/lib/generators/super/webpacker/webpacker_generator.rb +10 -6
  30. data/lib/super/cheat.rb +1 -0
  31. data/lib/super/display/guesser.rb +1 -1
  32. data/lib/super/display/schema_types.rb +6 -1
  33. data/lib/super/display.rb +2 -1
  34. data/lib/super/engine.rb +5 -0
  35. data/lib/super/error.rb +12 -0
  36. data/lib/super/filter/form_object.rb +74 -48
  37. data/lib/super/filter/guesser.rb +2 -0
  38. data/lib/super/filter/operator.rb +90 -64
  39. data/lib/super/filter/schema_types.rb +63 -80
  40. data/lib/super/filter.rb +1 -1
  41. data/lib/super/form/builder.rb +6 -3
  42. data/lib/super/form/field_transcript.rb +43 -0
  43. data/lib/super/form/guesser.rb +1 -1
  44. data/lib/super/form/schema_types.rb +11 -20
  45. data/lib/super/layout.rb +9 -33
  46. data/lib/super/link.rb +2 -7
  47. data/lib/super/link_builder.rb +0 -4
  48. data/lib/super/packaged_asset.rb +49 -0
  49. data/lib/super/pagination.rb +2 -1
  50. data/lib/super/reorderable_hash.rb +88 -0
  51. data/lib/super/reset.rb +20 -1
  52. data/lib/super/schema.rb +4 -0
  53. data/lib/super/version.rb +1 -1
  54. data/lib/super/view_chain.rb +25 -0
  55. data/lib/super.rb +4 -0
  56. metadata +46 -9
  57. data/app/views/super/application/_filter_type_select.html.erb +0 -21
  58. data/app/views/super/application/_filter_type_text.html.erb +0 -18
  59. data/app/views/super/application/_filter_type_timestamp.html.erb +0 -24
  60. data/app/views/super/application/_form_field_select.html.erb +0 -1
  61. data/lib/generators/super/webpacker/templates/pack_super_application.js.erb.tt +0 -2
@@ -5,12 +5,22 @@ module Super
5
5
  class ApplicationController < SubstructureController
6
6
  include ClientError::Handling
7
7
 
8
- helper_method :current_action
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
9
13
 
10
14
  # Displays a list of records to the user
11
15
  def index
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
+
12
22
  @records = load_records
13
- @display = display_schema.apply(action: current_action)
23
+ @display = display_schema.apply(action: current_action, format: request.format)
14
24
  @view = index_view
15
25
  @query_form = initialize_query_form
16
26
  initialize_filter_form
@@ -21,7 +31,7 @@ module Super
21
31
  # Displays a specific record to the user
22
32
  def show
23
33
  @record = load_record
24
- @display = display_schema.apply(action: current_action)
34
+ @display = display_schema.apply(action: current_action, format: request.format)
25
35
  @view = show_view
26
36
  end
27
37
 
@@ -34,7 +44,8 @@ module Super
34
44
 
35
45
  # Creates a record, or shows the validation errors
36
46
  def create
37
- @record = build_record_with_params
47
+ @record = build_record
48
+ set_record_attributes
38
49
 
39
50
  if save_record
40
51
  redirect_to polymorphic_path(Super::Link.polymorphic_parts(@record))
@@ -56,8 +67,9 @@ module Super
56
67
  # Updates a record, or shows validation errors
57
68
  def update
58
69
  @record = load_record
70
+ set_record_attributes
59
71
 
60
- if update_record
72
+ if save_record
61
73
  redirect_to polymorphic_path(Super::Link.polymorphic_parts(@record))
62
74
  else
63
75
  @current_action = ActionInquirer.edit!
@@ -84,12 +96,43 @@ module Super
84
96
 
85
97
  private
86
98
 
87
- def current_action
99
+ helper_method def current_action
88
100
  @current_action ||=
89
101
  ActionInquirer.new(
90
102
  ActionInquirer.default_for_resources,
91
103
  params[:action]
92
104
  )
93
105
  end
106
+
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
136
+ end
94
137
  end
95
138
  end
@@ -4,10 +4,28 @@ module Super
4
4
  # Various methods that determine the behavior of your controllers. These
5
5
  # methods can and should be overridden.
6
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
+
7
25
  private
8
26
 
9
27
  helper_method def model
10
- raise NotImplementedError
28
+ raise Error::NotImplementedError
11
29
  end
12
30
 
13
31
  # This is an optional method
@@ -17,6 +35,16 @@ module Super
17
35
  model.name.pluralize
18
36
  end
19
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
+
20
48
  # Configures what database records are visible on load. This is an optional
21
49
  # method, it defaults to "`all`" methods
22
50
  #
@@ -50,7 +78,18 @@ module Super
50
78
  #
51
79
  # @return [ActionController::Parameters]
52
80
  helper_method def permitted_params
53
- strong_params = Super::Form::StrongParams.new(form_schema)
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
54
93
  params.require(strong_params.require(model)).permit(strong_params.permit)
55
94
  end
56
95
 
@@ -59,14 +98,26 @@ module Super
59
98
  #
60
99
  # @return [Array<Link>]
61
100
  helper_method def collection_actions
62
- Super::Link.find_all(:new)
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
63
110
  end
64
111
 
65
112
  # Configures the actions linked to on the show page as well as each row of
66
113
  # the table on the index page. This is an optional method
67
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
+ #
68
119
  # @return [Array<Link>]
69
- helper_method def member_actions
120
+ helper_method def member_actions(record)
70
121
  if current_action.show?
71
122
  Super::Link.find_all(:edit, :destroy)
72
123
  elsif current_action.edit?
@@ -115,6 +166,15 @@ module Super
115
166
  Super.configuration.index_records_per_page
116
167
  end
117
168
 
169
+ helper_method def batch_actions_enabled?
170
+ true
171
+ end
172
+
173
+ helper_method def batch_actions
174
+ [
175
+ ]
176
+ end
177
+
118
178
  def load_records
119
179
  base_scope
120
180
  end
@@ -127,18 +187,14 @@ module Super
127
187
  base_scope.build
128
188
  end
129
189
 
130
- def build_record_with_params
131
- base_scope.build(permitted_params)
190
+ def set_record_attributes
191
+ @record.attributes = permitted_params
132
192
  end
133
193
 
134
194
  def save_record
135
195
  @record.save
136
196
  end
137
197
 
138
- def update_record
139
- @record.update(permitted_params)
140
- end
141
-
142
198
  def destroy_record
143
199
  @record.destroy
144
200
  end
@@ -177,6 +233,14 @@ module Super
177
233
  end
178
234
  end
179
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
+
180
244
  # Sets up pagination
181
245
  #
182
246
  # @return [Pagination]
@@ -193,55 +257,58 @@ module Super
193
257
  #
194
258
  # @return [ActiveRecord::Relation]
195
259
  def paginate_records
260
+ return @records if !pagination_enabled?
261
+
196
262
  @records
197
263
  .limit(@pagination.limit)
198
264
  .offset(@pagination.offset)
199
265
  end
200
266
 
267
+ helper_method def csv_enabled?
268
+ true
269
+ end
270
+
201
271
  def index_view
202
272
  Super::Layout.new(
203
- mains: [
204
- Super::Panel.new(
205
- Super::Partial.new("collection_header"),
206
- :@display
207
- ),
208
- ],
209
- asides: [
210
- :@query_form,
211
- ]
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
+ )
212
282
  )
213
283
  end
214
284
 
215
285
  def show_view
216
286
  Super::Layout.new(
217
- mains: [
218
- Super::Panel.new(
219
- Super::Partial.new("member_header"),
220
- :@display
221
- ),
222
- ]
287
+ main: Super::ViewChain.new(
288
+ main_panel: Super::Panel.new,
289
+ main_header: Super::Partial.new("collection_header"),
290
+ main: :@display
291
+ )
223
292
  )
224
293
  end
225
294
 
226
295
  def new_view
227
296
  Super::Layout.new(
228
- mains: [
229
- Super::Panel.new(
230
- Super::Partial.new("collection_header"),
231
- :@form
232
- ),
233
- ]
297
+ main: Super::ViewChain.new(
298
+ main_panel: Super::Panel.new,
299
+ main_header: Super::Partial.new("collection_header"),
300
+ main: :@form
301
+ )
234
302
  )
235
303
  end
236
304
 
237
305
  def edit_view
238
306
  Super::Layout.new(
239
- mains: [
240
- Super::Panel.new(
241
- Super::Partial.new("member_header"),
242
- :@form
243
- ),
244
- ]
307
+ main: Super::ViewChain.new(
308
+ main_panel: Super::Panel.new,
309
+ main_header: Super::Partial.new("member_header"),
310
+ main: :@form
311
+ )
245
312
  )
246
313
  end
247
314
 
@@ -249,6 +316,7 @@ module Super
249
316
  included do
250
317
  helper_method :site_title
251
318
  helper_method :site_navigation
319
+ helper_method :document_title
252
320
  end
253
321
 
254
322
  private
@@ -260,6 +328,22 @@ module Super
260
328
  def site_navigation
261
329
  Super::Navigation.new(&:all)
262
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
263
347
  end
264
348
  end
265
349
  end
@@ -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 %>
@@ -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>
@@ -2,14 +2,15 @@
2
2
  <h1 class="text-xl">
3
3
  <%= title %>
4
4
  </h1>
5
- <div>
6
- <% collection_actions.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
- <% member_actions.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>
@@ -1,6 +1,66 @@
1
1
  <h1 class="text-lg">Filter</h1>
2
- <% filter.each_field do |filter_field| %>
2
+ <% filter.each_attribute do |attribute_form_object| %>
3
3
  <div class="mt-4">
4
- <%= render(filter_field, form: form) %>
4
+ <%= form.fields_for(attribute_form_object.field_name, attribute_form_object) do |attribute_form| %>
5
+ <% selected_index = 0 %>
6
+ <div data-controller="tab-container" data-tab-container-tab-identifier-getter-value="tabIdentifierValue" data-tab-container-tab-controller-name-value="tab">
7
+ <div>
8
+ <span class="inline-block"><%= attribute_form_object.humanized_attribute_name %></span>
9
+ <select data-tab-container-target="control" data-action="tab-container#change" class="super-input super-input-select inline-block">
10
+ <% selected = false %>
11
+ <% attribute_form_object.each_operator.with_index do |operator_form_object, index| %>
12
+ <%
13
+ selected_attribute =
14
+ if !selected && operator_form_object.specified?
15
+ selected = true
16
+ selected_index = index
17
+ %(selected=selected)
18
+ else
19
+ ""
20
+ end
21
+ %>
22
+ <option value="<%= operator_form_object.identifier %>" <%= selected_attribute %>><%= operator_form_object.operator.humanized_operator_name %></option>
23
+ <% end %>
24
+ </select>
25
+ </div>
26
+ <div>
27
+ <% attribute_form_object.each_operator.with_index do |operator_form_object, index| %>
28
+ <div data-controller="tab" data-tab-tab-container-getter-value="tabContainer" data-tab-container-target="tab" data-tab-identifier-value="<%= operator_form_object.identifier %>">
29
+ <% form_html = capture do %>
30
+ <div data-tab-target="content">
31
+ <%= attribute_form.fields_for(operator_form_object.identifier, operator_form_object) do |operator_form| %>
32
+ <div class="flex gap-x-2 mt-2">
33
+ <% operator_form_object.each_field.with_index do |operator_field_name, index| %>
34
+ <div class="flex-1">
35
+ <% if operator_field_name == Super::Filter::FormObject::OperatorForm::NULLARY %>
36
+ <%= operator_form.super.check_box(operator_field_name, {}, "1", "") %>
37
+ <%= operator_form.super.label(operator_field_name, nil, super: { class: "select-none ml-1" }) %>
38
+ <% elsif operator_form_object.operator.respond_to?(:field_transcript) && operator_form_object.operator.field_transcript %>
39
+ <% field_transcript = operator_form_object.operator.field_transcript %>
40
+ <% if field_transcript.super? %>
41
+ <%= operator_form.super.public_send(field_transcript.method_name, operator_field_name, *field_transcript.args, **field_transcript.kwargs) %>
42
+ <% else %>
43
+ <%= operator_form.public_send(field_transcript.method_name, operator_field_name, *field_transcript.args, **field_transcript.kwargs) %>
44
+ <% end %>
45
+ <% else %>
46
+ <%= operator_form.super.text_field(operator_field_name) %>
47
+ <% end %>
48
+ </div>
49
+ <% end %>
50
+ </div>
51
+ <% end %>
52
+ </div>
53
+ <% end %>
54
+
55
+ <%= form_html if index == selected_index %>
56
+
57
+ <template data-tab-target="pocket">
58
+ <%= form_html %>
59
+ </template>
60
+ </div>
61
+ <% end %>
62
+ </div>
63
+ </div>
64
+ <% end %>
5
65
  </div>
6
66
  <% end %>
@@ -1,29 +1,28 @@
1
- <% layout.resolve(self) %>
1
+ <%# <% layout.resolve(self) %1> %>
2
2
 
3
- <% layout.resolved_headers.each do |partial| %>
4
- <%= Super::Partial.render(partial, template: self) %>
3
+ <% if layout.header %>
4
+ <%= render layout.header %>
5
5
  <% end %>
6
6
 
7
- <% if layout.resolved_asides.empty? %>
8
- <% layout.resolved_mains.each do |partial| %>
9
- <%= Super::Partial.render(partial, template: self) %>
10
- <% end %>
11
- <% else %>
7
+ <% if layout.aside %>
12
8
  <div class="flow-root -mx-2">
13
9
  <div class="md:float-left md:w-9/12 px-2">
14
- <% layout.resolved_mains.each do |partial| %>
15
- <%= Super::Partial.render(partial, template: self) %>
10
+ <% if layout.main %>
11
+ <%= render layout.main %>
16
12
  <% end %>
17
13
  </div>
18
14
 
19
15
  <div class="md:float-right md:w-3/12 px-2">
20
- <% layout.resolved_asides.each do |partial| %>
21
- <%= Super::Partial.render(partial, template: self) %>
22
- <% end %>
16
+ <%= render layout.aside %>
23
17
  </div>
24
18
  </div>
19
+ <% else %>
20
+ <% if layout.main %>
21
+ <%= render layout.main %>
22
+ <% end %>
25
23
  <% end %>
26
24
 
27
- <% layout.resolved_footers.each do |partial| %>
25
+ <% if layout.footer %>
26
+ <%= render layout.footer %>
28
27
  <%= Super::Partial.render(partial, template: self) %>
29
28
  <% end %>
@@ -0,0 +1,8 @@
1
+ <%=
2
+ default_options ||= {}
3
+ link_to(
4
+ link.text,
5
+ link.href,
6
+ default_options.deep_merge(link.options)
7
+ )
8
+ %>
@@ -2,15 +2,15 @@
2
2
  <h1 class="text-xl">
3
3
  <%= title %>
4
4
  </h1>
5
- <div>
6
- <% member_actions.each do |link| %>
7
- <%= link.to_s(
5
+ <div class="flex gap-2">
6
+ <% resolved_member_actions(@record).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
- record: @record,
12
- params: params
10
+ class: "super-button super-button--border-blue super-button-sm inline-block"
11
+ }
13
12
  ) %>
14
13
  <% end %>
15
14
  </div>
16
15
  </header>
16
+ <%= yield if block_given? %>
@@ -1,3 +1,4 @@
1
+ <%= yield %>
1
2
  <% if @pagination.necessary? %>
2
3
  <div class="flex justify-end mr-2">
3
4
  <div class="mt-4">
@@ -2,13 +2,13 @@
2
2
  <h1 class="text-lg font-bold mr-6 mb-1"><%= site_title %></h1>
3
3
  <% site_navigation.definition.each do |link_or_menu| %>
4
4
  <% if link_or_menu.is_a?(Super::Link) %>
5
- <%= link_or_menu.to_s(default_options: { class: "inline-block mr-6" }) %>
5
+ <%= render(link_or_menu, default_options: { class: "inline-block mr-6" }) %>
6
6
  <% else %>
7
- <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">
7
+ <details class="details-reset details-backdrop-transparent select-none inline-block mr-6">
8
8
  <summary class="text-blue-700"><%= link_or_menu.title %></summary>
9
- <ul class="absolute bg-white shadow-md px-4 py-3">
9
+ <ul class="absolute bg-white shadow-md px-4 py-3 z-20">
10
10
  <% link_or_menu.links.each do |link| %>
11
- <li><%= link.to_s(default_options: { class: "" }) %></li>
11
+ <li><%= render(link, default_options: { class: "" }) %></li>
12
12
  <% end %>
13
13
  </ul>
14
14
  </details>
@@ -5,7 +5,7 @@
5
5
  :a,
6
6
  sort.sortable_columns,
7
7
  {},
8
- {}
8
+ { class: "w-full" }
9
9
  ) %>
10
10
  </div>
11
11
  <div class="flex-none w-2">
@@ -15,7 +15,7 @@
15
15
  :d,
16
16
  sort.class::DIRECTIONS,
17
17
  { include_blank: false },
18
- {}
18
+ { class: "w-full" }
19
19
  ) %>
20
20
  </div>
21
21
  <div class="flex-none pl-2">
@@ -0,0 +1,5 @@
1
+ <% current = view_chain.chain.shift %>
2
+ <% current = instance_variable_get(current) if current.kind_of?(Symbol) %>
3
+ <%= render(current) do %>
4
+ <%= render(view_chain) %>
5
+ <% end %>
@@ -0,0 +1,14 @@
1
+ <%=
2
+ attribute_names = @display.each_attribute_name.to_a
3
+
4
+ CSV
5
+ .generate(write_headers: true, headers: attribute_names) do |csv|
6
+ @records.each do |record|
7
+ row = attribute_names.map do |attribute_name|
8
+ @display.render_attribute(template: self, record: record, column: attribute_name)
9
+ end
10
+ csv << row
11
+ end
12
+ end
13
+ .html_safe
14
+ -%>