super 0.18.0 → 0.19.0.rc1

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 (41) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/super/application.js +1260 -117
  3. data/app/assets/stylesheets/super/application.css +90711 -90034
  4. data/app/controllers/super/application_controller.rb +32 -2
  5. data/app/controllers/super/substructure_controller.rb +65 -29
  6. data/app/views/super/application/_batch_button.html.erb +12 -0
  7. data/app/views/super/application/_batch_checkbox.csv.erb +1 -0
  8. data/app/views/super/application/_batch_checkbox.html.erb +5 -0
  9. data/app/views/super/application/_batch_form.html.erb +3 -0
  10. data/app/views/super/application/_collection_header.html.erb +7 -6
  11. data/app/views/super/application/_csv_button.html.erb +25 -0
  12. data/app/views/super/application/_display_actions.html.erb +2 -2
  13. data/app/views/super/application/_layout.html.erb +13 -14
  14. data/app/views/super/application/_link.html.erb +8 -0
  15. data/app/views/super/application/_member_header.html.erb +7 -7
  16. data/app/views/super/application/_pagination.html.erb +1 -0
  17. data/app/views/super/application/_site_header.html.erb +4 -4
  18. data/app/views/super/application/_view_chain.html.erb +5 -0
  19. data/config/locales/en.yml +8 -0
  20. data/frontend/super-frontend/dist/application.css +90711 -90034
  21. data/frontend/super-frontend/dist/application.js +1260 -117
  22. data/frontend/super-frontend/dist/package.json +13 -0
  23. data/lib/generators/super/webpacker/USAGE +1 -7
  24. data/lib/generators/super/webpacker/templates/pack_super_application.js.tt +2 -0
  25. data/lib/generators/super/webpacker/webpacker_generator.rb +10 -6
  26. data/lib/super/cheat.rb +1 -0
  27. data/lib/super/display/schema_types.rb +6 -0
  28. data/lib/super/engine.rb +5 -0
  29. data/lib/super/error.rb +9 -0
  30. data/lib/super/layout.rb +9 -33
  31. data/lib/super/link.rb +2 -7
  32. data/lib/super/link_builder.rb +0 -4
  33. data/lib/super/packaged_asset.rb +49 -0
  34. data/lib/super/pagination.rb +2 -1
  35. data/lib/super/reorderable_hash.rb +88 -0
  36. data/lib/super/reset.rb +20 -4
  37. data/lib/super/version.rb +1 -1
  38. data/lib/super/view_chain.rb +25 -0
  39. data/lib/super.rb +3 -0
  40. metadata +31 -6
  41. data/lib/generators/super/webpacker/templates/pack_super_application.js.erb.tt +0 -2
@@ -5,10 +5,20 @@ 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
23
  @display = display_schema.apply(action: current_action, format: request.format)
14
24
  @view = index_view
@@ -86,7 +96,7 @@ module Super
86
96
 
87
97
  private
88
98
 
89
- def current_action
99
+ helper_method def current_action
90
100
  @current_action ||=
91
101
  ActionInquirer.new(
92
102
  ActionInquirer.default_for_resources,
@@ -104,5 +114,25 @@ module Super
104
114
  ensure
105
115
  @current_action = original
106
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
107
137
  end
108
138
  end
@@ -4,6 +4,24 @@ 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
@@ -80,7 +98,15 @@ module Super
80
98
  #
81
99
  # @return [Array<Link>]
82
100
  helper_method def collection_actions
83
- 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
84
110
  end
85
111
 
86
112
  # Configures the actions linked to on the show page as well as each row of
@@ -140,6 +166,15 @@ module Super
140
166
  Super.configuration.index_records_per_page
141
167
  end
142
168
 
169
+ helper_method def batch_actions_enabled?
170
+ true
171
+ end
172
+
173
+ helper_method def batch_actions
174
+ [
175
+ ]
176
+ end
177
+
143
178
  def load_records
144
179
  base_scope
145
180
  end
@@ -198,7 +233,7 @@ module Super
198
233
  end
199
234
  end
200
235
 
201
- def pagination_disabled_param
236
+ helper_method def pagination_disabled_param
202
237
  :_all_pages
203
238
  end
204
239
 
@@ -229,50 +264,51 @@ module Super
229
264
  .offset(@pagination.offset)
230
265
  end
231
266
 
267
+ helper_method def csv_enabled?
268
+ true
269
+ end
270
+
232
271
  def index_view
233
272
  Super::Layout.new(
234
- mains: [
235
- Super::Panel.new(
236
- Super::Partial.new("collection_header"),
237
- :@display
238
- ),
239
- ],
240
- asides: [
241
- :@query_form,
242
- ]
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
+ )
243
282
  )
244
283
  end
245
284
 
246
285
  def show_view
247
286
  Super::Layout.new(
248
- mains: [
249
- Super::Panel.new(
250
- Super::Partial.new("member_header"),
251
- :@display
252
- ),
253
- ]
287
+ main: Super::ViewChain.new(
288
+ main_panel: Super::Panel.new,
289
+ main_header: Super::Partial.new("collection_header"),
290
+ main: :@display
291
+ )
254
292
  )
255
293
  end
256
294
 
257
295
  def new_view
258
296
  Super::Layout.new(
259
- mains: [
260
- Super::Panel.new(
261
- Super::Partial.new("collection_header"),
262
- :@form
263
- ),
264
- ]
297
+ main: Super::ViewChain.new(
298
+ main_panel: Super::Panel.new,
299
+ main_header: Super::Partial.new("collection_header"),
300
+ main: :@form
301
+ )
265
302
  )
266
303
  end
267
304
 
268
305
  def edit_view
269
306
  Super::Layout.new(
270
- mains: [
271
- Super::Panel.new(
272
- Super::Partial.new("member_header"),
273
- :@form
274
- ),
275
- ]
307
+ main: Super::ViewChain.new(
308
+ main_panel: Super::Panel.new,
309
+ main_header: Super::Partial.new("member_header"),
310
+ main: :@form
311
+ )
276
312
  )
277
313
  end
278
314
 
@@ -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(record).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,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(@record).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>
@@ -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 %>
@@ -1,5 +1,13 @@
1
1
  ---
2
2
  en:
3
3
  super:
4
+ batch:
5
+ none_error: This batch action received no items to act upon
6
+ csv:
7
+ initial_cta: Export CSV
8
+ modal_header: Export CSV
9
+ download_current_cta: Download current view
10
+ download_all_cta: Download all matching query
4
11
  layout:
5
12
  powered_by: "%{env} environment. Powered by Super %{version}."
13
+ mismatching_package_json_gemfile_versions: "The version of Super specified in your package.json file does not match the version specified in your Gemfile.lock."