super 0.17.0 → 0.20.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +4 -4
  3. data/app/assets/javascripts/super/application.js +1260 -117
  4. data/app/assets/stylesheets/super/application.css +90711 -90034
  5. data/app/controllers/super/application_controller.rb +34 -4
  6. data/app/controllers/super/substructure_controller.rb +125 -29
  7. data/app/helpers/super/form_builder_helper.rb +4 -4
  8. data/app/views/layouts/super/application.html.erb +1 -1
  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 +9 -0
  12. data/app/views/super/application/_batch_form.html.erb +3 -0
  13. data/app/views/super/application/_collection_header.html.erb +7 -6
  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/_form.html.erb +1 -1
  17. data/app/views/super/application/_layout.html.erb +13 -14
  18. data/app/views/super/application/_link.html.erb +8 -0
  19. data/app/views/super/application/_member_header.html.erb +7 -7
  20. data/app/views/super/application/_pagination.html.erb +2 -4
  21. data/app/views/super/application/_site_footer.html.erb +1 -1
  22. data/app/views/super/application/_site_header.html.erb +4 -4
  23. data/app/views/super/application/_view_chain.html.erb +5 -0
  24. data/app/views/super/application/index.csv.erb +14 -0
  25. data/config/locales/en.yml +15 -1
  26. data/frontend/super-frontend/dist/application.css +90711 -90034
  27. data/frontend/super-frontend/dist/application.js +6512 -5379
  28. data/frontend/super-frontend/dist/package.json +13 -0
  29. data/lib/generators/super/webpacker/USAGE +1 -7
  30. data/lib/generators/super/webpacker/templates/pack_super_application.js.tt +2 -0
  31. data/lib/generators/super/webpacker/webpacker_generator.rb +10 -6
  32. data/lib/super/action_inquirer.rb +3 -0
  33. data/lib/super/cheat.rb +1 -0
  34. data/lib/super/display/schema_types.rb +6 -0
  35. data/lib/super/display.rb +2 -1
  36. data/lib/super/engine.rb +5 -0
  37. data/lib/super/error.rb +11 -0
  38. data/lib/super/form/schema_types.rb +8 -36
  39. data/lib/super/form_builder/action_text_methods.rb +16 -0
  40. data/lib/super/form_builder/base_methods.rb +73 -0
  41. data/lib/super/form_builder/flatpickr_methods.rb +75 -0
  42. data/lib/super/form_builder/option_methods.rb +73 -0
  43. data/lib/super/form_builder.rb +143 -0
  44. data/lib/super/layout.rb +9 -33
  45. data/lib/super/link.rb +49 -70
  46. data/lib/super/link_builder.rb +24 -47
  47. data/lib/super/packaged_asset.rb +49 -0
  48. data/lib/super/pagination.rb +2 -1
  49. data/lib/super/reorderable_hash.rb +88 -0
  50. data/lib/super/reset.rb +20 -1
  51. data/lib/super/useful/i19.rb +35 -0
  52. data/lib/super/version.rb +1 -1
  53. data/lib/super/view_chain.rb +25 -0
  54. data/lib/super.rb +9 -1
  55. metadata +55 -10
  56. data/lib/generators/super/webpacker/templates/pack_super_application.js.erb.tt +0 -2
  57. data/lib/super/form/builder.rb +0 -289
@@ -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
 
@@ -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
+ resolve_member_action(action, record)
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
+ resolve_collection_action(action)
132
+ else
133
+ action
134
+ end
135
+ end
136
+ end
107
137
  end
108
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
  #
@@ -65,12 +93,28 @@ module Super
65
93
  params.require(strong_params.require(model)).permit(strong_params.permit)
66
94
  end
67
95
 
96
+ helper_method def form_record(record)
97
+ record
98
+ end
99
+
100
+ helper_method def form_action(record)
101
+ Super::Link.polymorphic_parts(record)
102
+ end
103
+
68
104
  # Configures the actions linked to on the index page. This is an optional
69
105
  # method
70
106
  #
71
107
  # @return [Array<Link>]
72
108
  helper_method def collection_actions
73
- Super::Link.find_all(:new)
109
+ if current_action.index?
110
+ [
111
+ Super::Partial.new("csv_button"),
112
+ Super::Partial.new("batch_button"),
113
+ Super::Link.find(:new)
114
+ ]
115
+ else
116
+ Super::Link.find_all(:new)
117
+ end
74
118
  end
75
119
 
76
120
  # Configures the actions linked to on the show page as well as each row of
@@ -91,6 +135,14 @@ module Super
91
135
  end
92
136
  end
93
137
 
138
+ helper_method def resolve_collection_action(action)
139
+ action.resolve(params: params)
140
+ end
141
+
142
+ helper_method def resolve_member_action(action, record)
143
+ action.resolve(params: params, record: record)
144
+ end
145
+
94
146
  helper_method def filters_enabled?
95
147
  true
96
148
  end
@@ -130,6 +182,15 @@ module Super
130
182
  Super.configuration.index_records_per_page
131
183
  end
132
184
 
185
+ helper_method def batch_actions_enabled?
186
+ true
187
+ end
188
+
189
+ helper_method def batch_actions
190
+ [
191
+ ]
192
+ end
193
+
133
194
  def load_records
134
195
  base_scope
135
196
  end
@@ -188,6 +249,14 @@ module Super
188
249
  end
189
250
  end
190
251
 
252
+ helper_method def pagination_disabled_param
253
+ :_all_pages
254
+ end
255
+
256
+ def pagination_enabled?
257
+ !params.key?(pagination_disabled_param)
258
+ end
259
+
191
260
  # Sets up pagination
192
261
  #
193
262
  # @return [Pagination]
@@ -204,55 +273,65 @@ module Super
204
273
  #
205
274
  # @return [ActiveRecord::Relation]
206
275
  def paginate_records
276
+ return @records if !pagination_enabled?
277
+
207
278
  @records
208
279
  .limit(@pagination.limit)
209
280
  .offset(@pagination.offset)
210
281
  end
211
282
 
283
+ helper_method def paginated_link(page_query_params)
284
+ polymorphic_path(
285
+ Super::Link.polymorphic_parts(model),
286
+ page_query_params
287
+ )
288
+ end
289
+
290
+ helper_method def csv_enabled?
291
+ true
292
+ end
293
+
212
294
  def index_view
213
295
  Super::Layout.new(
214
- mains: [
215
- Super::Panel.new(
216
- Super::Partial.new("collection_header"),
217
- :@display
218
- ),
219
- ],
220
- asides: [
221
- :@query_form,
222
- ]
296
+ main: Super::ViewChain.new(
297
+ main_panel: Super::Panel.new,
298
+ batch_form: Super::Partial.new("batch_form"),
299
+ main_header: Super::Partial.new("collection_header"),
300
+ main: :@display
301
+ ),
302
+ aside: Super::ViewChain.new(
303
+ main: :@query_form
304
+ )
223
305
  )
224
306
  end
225
307
 
226
308
  def show_view
227
309
  Super::Layout.new(
228
- mains: [
229
- Super::Panel.new(
230
- Super::Partial.new("member_header"),
231
- :@display
232
- ),
233
- ]
310
+ main: Super::ViewChain.new(
311
+ main_panel: Super::Panel.new,
312
+ main_header: Super::Partial.new("member_header"),
313
+ main: :@display
314
+ )
234
315
  )
235
316
  end
236
317
 
237
318
  def new_view
238
319
  Super::Layout.new(
239
- mains: [
240
- Super::Panel.new(
241
- Super::Partial.new("collection_header"),
242
- :@form
243
- ),
244
- ]
320
+ main: Super::ViewChain.new(
321
+ main_panel: Super::Panel.new,
322
+ main_header: Super::Partial.new("collection_header"),
323
+ main: :@form
324
+ )
245
325
  )
246
326
  end
247
327
 
248
328
  def edit_view
249
329
  Super::Layout.new(
250
- mains: [
251
- Super::Panel.new(
252
- Super::Partial.new("member_header"),
253
- :@form
254
- ),
255
- ]
330
+ main: Super::ViewChain.new(
331
+ main_panel: Super::Panel.new,
332
+ main_header: Super::Partial.new("member_header"),
333
+ main: :@form
334
+ )
256
335
  )
257
336
  end
258
337
 
@@ -260,6 +339,7 @@ module Super
260
339
  included do
261
340
  helper_method :site_title
262
341
  helper_method :site_navigation
342
+ helper_method :document_title
263
343
  end
264
344
 
265
345
  private
@@ -271,6 +351,22 @@ module Super
271
351
  def site_navigation
272
352
  Super::Navigation.new(&:all)
273
353
  end
354
+
355
+ def document_title
356
+ if instance_variable_defined?(:@document_title)
357
+ return @document_title
358
+ end
359
+
360
+ document_title_segments.map(&:presence).compact.join(document_title_separator)
361
+ end
362
+
363
+ def document_title_segments
364
+ @document_title_segments ||= [page_title, site_title]
365
+ end
366
+
367
+ def document_title_separator
368
+ @document_title_separator ||= " - "
369
+ end
274
370
  end
275
371
  end
276
372
  end
@@ -10,9 +10,9 @@ module Super
10
10
  # Super's version of `#form_for`
11
11
  def super_form_for(record, options = {}, &block)
12
12
  original = ActionView::Base.field_error_proc
13
- ActionView::Base.field_error_proc = Form::Builder::FIELD_ERROR_PROC
13
+ ActionView::Base.field_error_proc = FormBuilder::FIELD_ERROR_PROC
14
14
 
15
- options[:builder] ||= Form::Builder
15
+ options[:builder] ||= FormBuilder
16
16
  return form_for(record, options, &block)
17
17
  ensure
18
18
  ActionView::Base.field_error_proc = original
@@ -21,9 +21,9 @@ module Super
21
21
  # Super's version of `#form_with`
22
22
  def super_form_with(**options, &block)
23
23
  original = ActionView::Base.field_error_proc
24
- ActionView::Base.field_error_proc = Form::Builder::FIELD_ERROR_PROC
24
+ ActionView::Base.field_error_proc = FormBuilder::FIELD_ERROR_PROC
25
25
 
26
- options[:builder] ||= Form::Builder
26
+ options[:builder] ||= FormBuilder
27
27
  return form_with(**options, &block)
28
28
  ensure
29
29
  ActionView::Base.field_error_proc = original
@@ -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,9 @@
1
+ <% if current_action.collection? %>
2
+ <div class="whitespace-nowrap gap-1">
3
+ <% html_id = "batch-checkbox-#{value.to_s.gsub(/[^a-z0-9]+/, "-")}" %>
4
+ <input type="checkbox" name="batch[]" value="<%= value %>" id="<%= html_id %>">
5
+ <label for="<%= html_id %>"><%= value %></label>
6
+ </div>
7
+ <% else %>
8
+ <%= value %>
9
+ <% end %>
@@ -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,4 +1,4 @@
1
- <%= super_form_for(Super::Link.polymorphic_parts(@record), builder: Super::Form::Builder) do |f| %>
1
+ <%= super_form_for(form_record(@record), url: form_action(@record)) do |f| %>
2
2
  <div class="max-w-3xl">
3
3
  <% form.each_attribute do |field, type| %>
4
4
  <%= render(
@@ -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,13 +1,11 @@
1
+ <%= yield %>
1
2
  <% if @pagination.necessary? %>
2
3
  <div class="flex justify-end mr-2">
3
4
  <div class="mt-4">
4
5
  <% @pagination.each do |page_query_params, is_current_page, display| %>
5
6
  <%= link_to(
6
7
  display,
7
- polymorphic_path(
8
- Super::Link.polymorphic_parts(model),
9
- page_query_params
10
- ),
8
+ paginated_link(page_query_params),
11
9
  class: "inline-block ml-2 text-lg #{is_current_page ? " text-gray-900" : ""}"
12
10
  ) %>
13
11
  <% end %>
@@ -1,3 +1,3 @@
1
1
  <div class="pt-8 text-sm text-gray-800">
2
- <%= t("super.layout.powered_by", env: Rails.env.capitalize, version: Super::VERSION) %>
2
+ <%= t("super.layout.powered_by_html", env: Rails.env.capitalize, version: Super::VERSION) %>
3
3
  </div>
@@ -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 %>
@@ -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
+ -%>
@@ -1,5 +1,19 @@
1
1
  ---
2
2
  en:
3
3
  super:
4
+ actions:
5
+ new: New
6
+ index: Index
7
+ show: View
8
+ edit: Edit
9
+ destroy: Delete
10
+ batch:
11
+ none_error: This batch action received no items to act upon
12
+ csv:
13
+ initial_cta: Export CSV
14
+ modal_header: Export CSV
15
+ download_current_cta: Download current view
16
+ download_all_cta: Download all matching query
4
17
  layout:
5
- powered_by: "%{env} environment. Powered by Super %{version}."
18
+ powered_by_html: "%{env} environment. Powered by Super %{version}. <a href='https://superadministration.github.io/v%{version}/'>Developer docs.</a>"
19
+ 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."