super 0.0.0 → 0.0.5

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 (86) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +10 -0
  3. data/LICENSE +165 -0
  4. data/README.md +66 -18
  5. data/Rakefile +3 -1
  6. data/app/assets/config/super_manifest.js +2 -0
  7. data/app/assets/javascripts/super/application.js +3618 -0
  8. data/app/assets/stylesheets/super/application.css +98584 -0
  9. data/app/controllers/super/application_controller.rb +103 -0
  10. data/app/helpers/super/application_helper.rb +32 -0
  11. data/app/views/layouts/super/application.html.erb +39 -0
  12. data/app/views/super/application/_flash.html.erb +17 -0
  13. data/app/views/super/application/_form.html.erb +17 -0
  14. data/app/views/super/application/_form_field__destroy.html.erb +9 -0
  15. data/app/views/super/application/_form_field_select.html.erb +23 -0
  16. data/app/views/super/application/_form_field_text.html.erb +13 -0
  17. data/app/views/super/application/_form_fieldset.html.erb +8 -0
  18. data/app/views/super/application/_form_has_many.html.erb +21 -0
  19. data/app/views/super/application/_form_has_one.html.erb +11 -0
  20. data/app/views/super/application/_form_inline_errors.html.erb +10 -0
  21. data/app/views/super/application/_index.html.erb +45 -0
  22. data/app/views/super/application/_resource_header.html.erb +16 -0
  23. data/app/views/super/application/_resources_header.html.erb +16 -0
  24. data/app/views/super/application/_show.html.erb +10 -0
  25. data/app/views/super/application/_super_layout.html.erb +34 -0
  26. data/app/views/super/application/_super_panel.html.erb +11 -0
  27. data/app/views/super/application/edit.html.erb +6 -0
  28. data/app/views/super/application/index.html.erb +6 -0
  29. data/app/views/super/application/new.html.erb +6 -0
  30. data/app/views/super/application/nothing.html.erb +0 -0
  31. data/app/views/super/application/show.html.erb +6 -0
  32. data/app/views/super/feather/README.md +32 -0
  33. data/app/views/super/feather/_chevron_down.svg +1 -0
  34. data/docs/README.md +6 -0
  35. data/docs/controls.md +39 -0
  36. data/docs/faq.md +44 -0
  37. data/docs/quick_start.md +45 -0
  38. data/docs/webpacker.md +17 -0
  39. data/docs/yard_customizations.rb +41 -0
  40. data/frontend/super-frontend/build.js +36 -0
  41. data/frontend/super-frontend/dist/application.css +98584 -0
  42. data/frontend/super-frontend/dist/application.js +3618 -0
  43. data/frontend/super-frontend/package.json +21 -0
  44. data/frontend/super-frontend/postcss.config.js +6 -0
  45. data/frontend/super-frontend/src/javascripts/super/application.ts +18 -0
  46. data/frontend/super-frontend/src/javascripts/super/apply_template_controller.ts +21 -0
  47. data/frontend/super-frontend/src/javascripts/super/rails__ujs.d.ts +1 -0
  48. data/frontend/super-frontend/src/javascripts/super/toggle_pending_destruction_controller.ts +15 -0
  49. data/frontend/super-frontend/src/stylesheets/super/application.css +77 -0
  50. data/frontend/super-frontend/tailwind.config.js +9 -0
  51. data/frontend/super-frontend/tsconfig.json +13 -0
  52. data/frontend/super-frontend/yarn.lock +5540 -0
  53. data/lib/generators/super/install/USAGE +34 -0
  54. data/lib/generators/super/install/install_generator.rb +46 -0
  55. data/lib/generators/super/install/templates/base_controller.rb.tt +2 -0
  56. data/lib/generators/super/install/templates/initializer.rb.tt +5 -0
  57. data/lib/generators/super/resource/USAGE +8 -0
  58. data/lib/generators/super/resource/resource_generator.rb +52 -0
  59. data/lib/generators/super/resource/templates/resources_controller.rb.tt +45 -0
  60. data/lib/generators/super/webpacker/USAGE +14 -0
  61. data/lib/generators/super/webpacker/templates/pack_super_application.js.erb.tt +2 -0
  62. data/lib/generators/super/webpacker/webpacker_generator.rb +25 -0
  63. data/lib/super.rb +22 -4
  64. data/lib/super/action_inquirer.rb +101 -0
  65. data/lib/super/assets.rb +63 -0
  66. data/lib/super/compatibility.rb +13 -0
  67. data/lib/super/configuration.rb +103 -0
  68. data/lib/super/controls.rb +120 -0
  69. data/lib/super/display.rb +9 -0
  70. data/lib/super/display/schema_types.rb +40 -0
  71. data/lib/super/engine.rb +6 -0
  72. data/lib/super/error.rb +18 -0
  73. data/lib/super/form/schema_types.rb +115 -0
  74. data/lib/super/layout.rb +19 -0
  75. data/lib/super/link.rb +87 -0
  76. data/lib/super/navigation/automatic.rb +71 -0
  77. data/lib/super/pagination.rb +70 -0
  78. data/lib/super/panel.rb +17 -0
  79. data/lib/super/partial.rb +11 -0
  80. data/lib/super/plugin.rb +89 -0
  81. data/lib/super/schema.rb +73 -0
  82. data/lib/super/step.rb +36 -0
  83. data/lib/super/version.rb +1 -1
  84. data/lib/super/view_helper.rb +43 -0
  85. metadata +215 -14
  86. data/LICENSE.txt +0 -40
@@ -0,0 +1,103 @@
1
+ module Super
2
+ # Provides a default implementation for each of the resourceful actions
3
+ class ApplicationController < ActionController::Base
4
+ include Pluggable.new(:super_application_controller)
5
+
6
+ helper_method :action_inquirer
7
+ helper_method :controls
8
+
9
+ rescue_from Error::ClientError do |exception|
10
+ code, default_message =
11
+ case exception
12
+ when Error::UnprocessableEntity
13
+ [422, "Unprocessable entity"]
14
+ when Error::NotFound
15
+ [404, "Not found"]
16
+ when Error::Forbidden
17
+ [403, "Forbidden"]
18
+ when Error::Unauthorized
19
+ [401, "Unauthorized"]
20
+ when Error::BadRequest, Error::ClientError
21
+ [400, "Bad request"]
22
+ end
23
+
24
+ flash.now.alert =
25
+ if exception.message == exception.class.name.to_s
26
+ default_message
27
+ else
28
+ exception.message
29
+ end
30
+
31
+ render "nothing", status: code
32
+ end
33
+
34
+ def index
35
+ @resources = Step.load_resources(controls, params, action_inquirer)
36
+ @pagination = Step.initialize_pagination(@resources, request.GET)
37
+ @resources = Step.paginate_resources(@resources, @pagination)
38
+ end
39
+
40
+ def show
41
+ @resource = Step.load_resource(controls, params, action_inquirer)
42
+ end
43
+
44
+ def new
45
+ @resource = Step.build_resource(controls, action_inquirer)
46
+ end
47
+
48
+ def create
49
+ @resource = Step.build_resource_with_params(controls, action_inquirer, create_permitted_params)
50
+
51
+ if @resource.save
52
+ redirect_to polymorphic_path(Super.configuration.path_parts(@resource))
53
+ else
54
+ render :new, status: :bad_request
55
+ end
56
+ end
57
+
58
+ def edit
59
+ @resource = Step.load_resource(controls, params, action_inquirer)
60
+ end
61
+
62
+ def update
63
+ @resource = Step.load_resource(controls, params, action_inquirer)
64
+
65
+ if @resource.update(update_permitted_params)
66
+ redirect_to polymorphic_path(Super.configuration.path_parts(@resource))
67
+ else
68
+ render :edit, status: :bad_request
69
+ end
70
+ end
71
+
72
+ def destroy
73
+ @resource = Step.load_resource(controls, params, action_inquirer)
74
+
75
+ if @resource.destroy
76
+ redirect_to polymorphic_path(Super.configuration.path_parts(controls.model))
77
+ else
78
+ redirect_to polymorphic_path(Super.configuration.path_parts(@resource))
79
+ end
80
+ end
81
+
82
+ private
83
+
84
+ def controls
85
+ Super::Controls.new(new_controls)
86
+ end
87
+
88
+ def create_permitted_params
89
+ controls.permitted_params(params, action: action_inquirer)
90
+ end
91
+
92
+ def update_permitted_params
93
+ controls.permitted_params(params, action: action_inquirer)
94
+ end
95
+
96
+ def action_inquirer
97
+ @action_inquirer ||= ActionInquirer.new(
98
+ ActionInquirer.default_resources,
99
+ params[:action]
100
+ )
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,32 @@
1
+ module Super
2
+ module ApplicationHelper
3
+ def super_resolve_list_for_rendering(partials, block = -> {})
4
+ block_result = block.call
5
+ if block_result.present?
6
+ partials = [block_result, *partials]
7
+ end
8
+
9
+ partials = partials.map do |partial|
10
+ if partial.is_a?(Symbol)
11
+ instance_variable_get(partial)
12
+ else
13
+ partial
14
+ end
15
+ end
16
+
17
+ partials.compact
18
+ end
19
+
20
+ def super_render_partialish(partialish)
21
+ if partialish.respond_to?(:to_partial_path)
22
+ if partialish.is_a?(Super::Partial)
23
+ render(partialish, partialish.locals)
24
+ else
25
+ render(partialish)
26
+ end
27
+ else
28
+ partialish
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,39 @@
1
+ <!DOCTYPE html>
2
+ <html class="bg-gray-100">
3
+ <head>
4
+ <title><%= Super.configuration.title %></title>
5
+ <%= csrf_meta_tags %>
6
+ <% if respond_to?(:csp_meta_tag) -%>
7
+ <%= csp_meta_tag %>
8
+ <% end -%>
9
+
10
+ <meta name="viewport" content="width=device-width, initial-scale=1">
11
+
12
+ <% if Super.configuration.asset_handler.sprockets? %>
13
+ <%= stylesheet_link_tag "super/application", media: "all" %>
14
+ <%= javascript_include_tag "super/application" %>
15
+ <% elsif Super.configuration.asset_handler.webpacker? %>
16
+ <%= stylesheet_pack_tag "super/application", media: "all" %>
17
+ <%= javascript_pack_tag "super/application" %>
18
+ <% end %>
19
+ </head>
20
+
21
+ <body class="font-sans pb-4">
22
+ <div class="px-4">
23
+ <header class="pt-4">
24
+ <h1 class="text-lg font-bold mr-6 mb-1"><%= Super.configuration.title %></h1>
25
+ <%
26
+ route_namespace = Super.configuration.route_namespace.map(&:to_s).join("/")
27
+ Super::Navigation::Automatic.new(route_namespace: route_namespace).each do |text, href| %>
28
+ <%= link_to(text, href, class: "inline-block mr-6") %>
29
+ <% end %>
30
+ </header>
31
+
32
+ <%= render "flash" %>
33
+
34
+ <div class="pt-4"></div>
35
+
36
+ <%= yield %>
37
+ </div>
38
+ </body>
39
+ </html>
@@ -0,0 +1,17 @@
1
+ <%
2
+ colors = {
3
+ "notice" => { bg: "bg-blue-100", fg: "text-blue-400", border: "border-blue-600" },
4
+ "alert" => { bg: "bg-red-100", fg: "text-red-400", border: "border-red-600" },
5
+ }
6
+ %>
7
+
8
+ <div data-flash="anchor">
9
+ <% flash.each do |level, messages| %>
10
+ <% Array(messages).each do |message| %>
11
+ <% color = colors[level.to_s] || colors["notice"] %>
12
+ <div class="<%= "%<bg>s %<fg>s border-l-4 %<border>s p-4 mt-2" % color %>">
13
+ <%= message %>
14
+ </div>
15
+ <% end %>
16
+ <% end %>
17
+ </div>
@@ -0,0 +1,17 @@
1
+ <% schema = controls.form_schema(action: action_inquirer) %>
2
+
3
+ <%= form_for(Super.configuration.path_parts(@resource)) do |f| %>
4
+ <div class="max-w-3xl">
5
+ <% schema.fields.each do |field, type| %>
6
+ <%= render(
7
+ type,
8
+ form: f,
9
+ column: field
10
+ ) %>
11
+ <% end %>
12
+
13
+ <div>
14
+ <%= f.submit class: "super-button super-button--fill-blue mt-2" %>
15
+ </div>
16
+ </div>
17
+ <% end %>
@@ -0,0 +1,9 @@
1
+ <% if !local_assigns[:ungrouped] %>
2
+ <div class="super-field-group">
3
+ <% end %>
4
+ <%= form.check_box(column, data: { action: "toggle-pending-destruction#call" }) %>
5
+ <%= form.label(column) %>
6
+ <%= render "form_inline_errors", form: form, column: column %>
7
+ <% if !local_assigns[:ungrouped] %>
8
+ </div>
9
+ <% end %>
@@ -0,0 +1,23 @@
1
+ <% if !local_assigns[:ungrouped] %>
2
+ <div class="super-field-group">
3
+ <% end %>
4
+ <% if !local_assigns[:hide_label] %>
5
+ <%= form.label(column, class: "block") %>
6
+ <% end %>
7
+ <div class="<%= Super::ViewHelper.classes("super-input-select", ["mt-1", !local_assigns[:hide_label]]) %>">
8
+ <%= form.select(
9
+ column,
10
+ form_field_select[:collection],
11
+ { include_blank: true }.merge(form_field_select[:options] || {}),
12
+ { class: "super-input super-input-select-field" }
13
+ ) %>
14
+ <div class="super-input-select-icon text-gray-700">
15
+ <span class="h-4 w-4">
16
+ <%= render "super/feather/chevron_down.svg" %>
17
+ </span>
18
+ </div>
19
+ </div>
20
+ <%= render "form_inline_errors", form: form, column: column %>
21
+ <% if !local_assigns[:ungrouped] %>
22
+ </div>
23
+ <% end %>
@@ -0,0 +1,13 @@
1
+ <% if !local_assigns[:ungrouped] %>
2
+ <div class="super-field-group">
3
+ <% end %>
4
+ <% if !local_assigns[:hide_label] %>
5
+ <%= form.label(column, class: "block") %>
6
+ <% end %>
7
+ <div class="<%= Super::ViewHelper.classes(["mt-1", !local_assigns[:hide_label]]) %>">
8
+ <%= form.text_field(column, class: "super-input w-full") %>
9
+ <%= render "form_inline_errors", form: form, column: column %>
10
+ </div>
11
+ <% if !local_assigns[:ungrouped] %>
12
+ </div>
13
+ <% end %>
@@ -0,0 +1,8 @@
1
+ <fieldset class="border border-gray-300 rounded pb-4 px-4 mt-4 shadow" data-controller="toggle-pending-destruction">
2
+ <% if form_fieldset.label.present? %>
3
+ <legend class="bg-white p-1 -mx-1"><%= form_fieldset.label %></legend>
4
+ <% end %>
5
+ <% form_fieldset.nested_fields.each do |field, type| %>
6
+ <%= render(type, form: form, column: field) %>
7
+ <% end %>
8
+ </fieldset>
@@ -0,0 +1,21 @@
1
+ <div data-controller="apply-template">
2
+ <%= form.fields_for(form_has_many.reader) do |ff| %>
3
+ <%= render "form_fieldset", form_fieldset: form_has_many, form: ff %>
4
+ <% end %>
5
+
6
+ <%=
7
+ form.fields_for(
8
+ form_has_many.reader,
9
+ form.object.public_send(form_has_many.reader).build,
10
+ child_index: "TEMPLATEINDEX"
11
+ ) do |ff|
12
+ %>
13
+ <template data-target="apply-template.template">
14
+ <%= render "form_fieldset", form_fieldset: form_has_many, form: ff %>
15
+ </template>
16
+ <% end %>
17
+
18
+ <a href="#" data-action="apply-template#call" class="super-button super-button--fill-blue mt-2 inline-block">
19
+ Add <%= form_has_many.label %>
20
+ </a>
21
+ </div>
@@ -0,0 +1,11 @@
1
+ <div>
2
+ <%
3
+ if form.object.public_send(form_has_one.reader).nil?
4
+ form.object.public_send("build_" + form_has_one.reader.to_s)
5
+ end
6
+ %>
7
+
8
+ <%= form.fields_for(form_has_one.reader) do |ff| %>
9
+ <%= render "form_fieldset", form_fieldset: form_has_one, form: ff %>
10
+ <% end %>
11
+ </div>
@@ -0,0 +1,10 @@
1
+ <% if form.object %>
2
+ <% Super::ViewHelper.errors_accounting_for_reflections(form.object, column).each do |error_message| %>
3
+ <p class="text-red-400 text-xs italic pt-1"><%= error_message %></p>
4
+ <% end %>
5
+ <% else %>
6
+ <p class="text-red-400 text-xs italic pt-1">
7
+ This form doesn't have an object, so something is probably wrong.
8
+ Maybe <code>accepts_nested_attributes_for</code> isn't set up?
9
+ </p>
10
+ <% end %>
@@ -0,0 +1,45 @@
1
+ <% schema = controls.display_schema(action: action_inquirer) %>
2
+
3
+ <div class="mt-4 -mx-5 overflow-x-auto">
4
+ <table class="w-full">
5
+ <thead>
6
+ <tr class="text-left text-sm uppercase font-bold tracking-wide">
7
+ <% schema.field_keys.each do |column| %>
8
+ <th class="p-2 first:pl-5"><%= column.to_s.humanize %></th>
9
+ <% end %>
10
+ <th class="p-2 pr-5">Actions</th>
11
+ </tr>
12
+ </thead>
13
+ <tbody class="border-gray-400 border-solid border-t-2">
14
+ <% @resources.each do |resource| %>
15
+ <tr id="resource-pk-<%= resource.id %>" class="border-b border-gray-400">
16
+ <% schema.field_keys.each do |column| %>
17
+ <td class="p-2 first:pl-5"><%= Super::Display.format(schema, resource, column) %></td>
18
+ <% end %>
19
+ <td class="p-2 pr-5" style="word-spacing: 0.25rem">
20
+ <% controls.resource_actions(resource, params: params, action: action_inquirer).each do |link| %>
21
+ <%= link_to(link.text, link.href, link.options) %>
22
+ <% end %>
23
+ </td>
24
+ </tr>
25
+ <% end %>
26
+ </tbody>
27
+ </table>
28
+ </div>
29
+
30
+ <% if @pagination.necessary? %>
31
+ <div class="flex justify-end mr-2">
32
+ <div class="mt-4">
33
+ <% @pagination.each do |page_query_params, is_current_page, display| %>
34
+ <%= link_to(
35
+ display,
36
+ polymorphic_path(
37
+ Super.configuration.path_parts(controls.model),
38
+ page_query_params
39
+ ),
40
+ class: "inline-block ml-2 text-lg #{is_current_page ? " text-gray-900" : ""}"
41
+ ) %>
42
+ <% end %>
43
+ </div>
44
+ </div>
45
+ <% end %>
@@ -0,0 +1,16 @@
1
+ <header class="flex justify-between content-end">
2
+ <h1 class="text-xl">
3
+ <%= controls.title %>
4
+ </h1>
5
+ <div>
6
+ <% controls.resource_actions(@resource, params: params, action: action_inquirer).each do |link| %>
7
+ <%= link_to(
8
+ link.text,
9
+ link.href,
10
+ link.options.reverse_merge(
11
+ class: "super-button super-button--border-blue super-button-sm inline-block ml-2"
12
+ )
13
+ ) %>
14
+ <% end %>
15
+ </div>
16
+ </header>
@@ -0,0 +1,16 @@
1
+ <header class="flex justify-between content-end">
2
+ <h1 class="text-xl">
3
+ <%= controls.title %>
4
+ </h1>
5
+ <div>
6
+ <% controls.resources_actions(params: params, action: action_inquirer).each do |link| %>
7
+ <%= link_to(
8
+ link.text,
9
+ link.href,
10
+ link.options.reverse_merge(
11
+ class: "super-button super-button--border-blue super-button-sm inline-block ml-2"
12
+ )
13
+ ) %>
14
+ <% end %>
15
+ </div>
16
+ </header>
@@ -0,0 +1,10 @@
1
+ <% schema = controls.display_schema(action: action_inquirer) %>
2
+
3
+ <table class="max-w-full leading-loose mt-4">
4
+ <% schema.field_keys.each do |column| %>
5
+ <tr>
6
+ <th class="text-right px-4"><%= column.to_s.humanize %></th>
7
+ <td><%= Super::Display.format(schema, @resource, column) %></td>
8
+ </tr>
9
+ <% end %>
10
+ </table>
@@ -0,0 +1,34 @@
1
+ <%
2
+ super_layout_headers = super_resolve_list_for_rendering(super_layout.headers)
3
+ super_layout_asides = super_resolve_list_for_rendering(super_layout.asides)
4
+ super_layout_mains = super_resolve_list_for_rendering(super_layout.mains)
5
+ super_layout_footers = super_resolve_list_for_rendering(super_layout.footers)
6
+ %>
7
+
8
+ <% super_layout_headers.each do |partial| %>
9
+ <%= super_render_partialish(partial) %>
10
+ <% end %>
11
+
12
+ <% if super_layout_asides.empty? %>
13
+ <% super_layout_mains.each do |partial| %>
14
+ <%= super_render_partialish(partial) %>
15
+ <% end %>
16
+ <% else %>
17
+ <div class="clearfix -mx-2">
18
+ <div class="md:float-left md:w-9/12 px-2">
19
+ <% super_layout_mains.each do |partial| %>
20
+ <%= super_render_partialish(partial) %>
21
+ <% end %>
22
+ </div>
23
+
24
+ <div class="md:float-right md:w-3/12 px-2">
25
+ <% super_layout_asides.each do |partial| %>
26
+ <%= super_render_partialish(partial) %>
27
+ <% end %>
28
+ </div>
29
+ </div>
30
+ <% end %>
31
+
32
+ <% super_layout_footers.each do |partial| %>
33
+ <%= super_render_partialish(partial) %>
34
+ <% end %>