super 0.0.16 → 0.19.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.
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
+ -%>