super 0.0.0 → 0.0.5

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