super 0.18.0 → 0.19.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
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."