superglue 0.53.2 → 1.0.0

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 (64) hide show
  1. checksums.yaml +4 -4
  2. data/lib/generators/superglue/install/install_generator.rb +119 -0
  3. data/lib/{install/templates/web → generators/superglue/install/templates}/application.json.props +2 -2
  4. data/lib/generators/superglue/install/templates/js/application.jsx +35 -0
  5. data/lib/generators/superglue/install/templates/js/application_visit.js +113 -0
  6. data/lib/generators/superglue/install/templates/js/components.js +2 -0
  7. data/lib/generators/superglue/install/templates/js/flash.js +44 -0
  8. data/lib/generators/superglue/install/templates/js/inputs.jsx +302 -0
  9. data/lib/generators/superglue/install/templates/js/jsconfig.json +9 -0
  10. data/lib/generators/superglue/install/templates/js/layout.jsx +16 -0
  11. data/lib/generators/superglue/install/templates/js/page_to_page_mapping.js +35 -0
  12. data/lib/generators/superglue/install/templates/js/store.js +30 -0
  13. data/lib/{install/templates/web/application.js → generators/superglue/install/templates/ts/application.tsx} +10 -16
  14. data/lib/generators/superglue/install/templates/ts/application_visit.ts +122 -0
  15. data/lib/generators/superglue/install/templates/ts/components.ts +2 -0
  16. data/lib/generators/superglue/install/templates/ts/flash.ts +46 -0
  17. data/lib/generators/superglue/install/templates/ts/inputs.tsx +547 -0
  18. data/lib/generators/superglue/install/templates/ts/layout.tsx +16 -0
  19. data/lib/generators/superglue/install/templates/ts/page_to_page_mapping.ts +34 -0
  20. data/lib/generators/superglue/install/templates/ts/store.ts +34 -0
  21. data/lib/generators/superglue/install/templates/ts/tsconfig.json +27 -0
  22. data/lib/generators/superglue/scaffold/scaffold_generator.rb +16 -0
  23. data/lib/generators/superglue/scaffold_controller/scaffold_controller_generator.rb +61 -0
  24. data/lib/generators/{rails/templates/web → superglue/view_collection/templates/erb}/edit.html.erb +1 -1
  25. data/lib/generators/{rails/templates/web → superglue/view_collection/templates/erb}/index.html.erb +1 -1
  26. data/lib/generators/{rails/templates/web → superglue/view_collection/templates/erb}/new.html.erb +1 -1
  27. data/lib/generators/{rails/templates/web → superglue/view_collection/templates/erb}/show.html.erb +1 -1
  28. data/lib/generators/superglue/view_collection/templates/js/edit.jsx +40 -0
  29. data/lib/generators/superglue/view_collection/templates/js/index.jsx +62 -0
  30. data/lib/generators/superglue/view_collection/templates/js/new.jsx +38 -0
  31. data/lib/generators/superglue/view_collection/templates/js/show.jsx +26 -0
  32. data/lib/generators/superglue/view_collection/templates/props/edit.json.props +9 -0
  33. data/lib/generators/superglue/view_collection/templates/props/index.json.props +14 -0
  34. data/lib/generators/superglue/view_collection/templates/props/new.json.props +10 -0
  35. data/lib/generators/superglue/view_collection/templates/props/show.json.props +6 -0
  36. data/lib/generators/superglue/view_collection/templates/ts/edit.tsx +54 -0
  37. data/lib/generators/superglue/view_collection/templates/ts/index.tsx +77 -0
  38. data/lib/generators/superglue/view_collection/templates/ts/new.tsx +50 -0
  39. data/lib/generators/superglue/view_collection/templates/ts/show.tsx +37 -0
  40. data/lib/generators/superglue/view_collection/view_collection_generator.rb +180 -0
  41. data/lib/superglue/helpers.rb +1 -1
  42. data/lib/superglue.rb +2 -1
  43. metadata +60 -43
  44. data/lib/generators/rails/scaffold_controller_generator.rb +0 -12
  45. data/lib/generators/rails/superglue_generator.rb +0 -98
  46. data/lib/generators/rails/templates/controller.rb.tt +0 -82
  47. data/lib/generators/rails/templates/edit.json.props +0 -12
  48. data/lib/generators/rails/templates/index.json.props +0 -14
  49. data/lib/generators/rails/templates/new.json.props +0 -13
  50. data/lib/generators/rails/templates/show.json.props +0 -6
  51. data/lib/generators/rails/templates/web/edit.js +0 -35
  52. data/lib/generators/rails/templates/web/index.js +0 -56
  53. data/lib/generators/rails/templates/web/new.js +0 -33
  54. data/lib/generators/rails/templates/web/show.js +0 -28
  55. data/lib/install/templates/web/actions.js +0 -6
  56. data/lib/install/templates/web/application_visit.js +0 -65
  57. data/lib/install/templates/web/flash.js +0 -19
  58. data/lib/install/templates/web/page_to_page_mapping.js +0 -12
  59. data/lib/install/templates/web/pages.js +0 -15
  60. data/lib/install/templates/web/store.js +0 -32
  61. data/lib/install/web.rb +0 -55
  62. data/lib/tasks/install.rake +0 -9
  63. /data/lib/{install/templates/web → generators/superglue/install/templates}/initializer.rb +0 -0
  64. /data/lib/generators/{rails/templates → superglue/view_collection/templates/props}/_form.json.props +0 -0
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This file was copied over from Rails land and slightly modified to account
4
+ # for Superglue templates
5
+
6
+ require "rails/generators/resource_helpers"
7
+ require "rails/generators/rails/scaffold_controller/scaffold_controller_generator"
8
+
9
+ module Superglue
10
+ module Generators
11
+ class ScaffoldControllerGenerator < Rails::Generators::NamedBase # :nodoc:
12
+ include Rails::Generators::ResourceHelpers
13
+
14
+ # Superglue uses the out-of-the-box controller generated by Rails.
15
+ source_root Rails::Generators::ScaffoldControllerGenerator.source_root
16
+
17
+ check_class_collision suffix: "Controller"
18
+
19
+ class_option :helper, type: :boolean
20
+ class_option :orm, banner: "NAME", type: :string, required: true,
21
+ desc: "ORM to generate the controller for"
22
+
23
+ class_option :skip_routes, type: :boolean, desc: "Don't add routes to config/routes.rb."
24
+
25
+ argument :attributes, type: :array, default: [], banner: "field:type field:type"
26
+
27
+ def create_controller_files
28
+ template "controller.rb", File.join("app/controllers", controller_class_path, "#{controller_file_name}_controller.rb")
29
+ end
30
+
31
+ # Replaces template_engine (and its default erb), with view_collection
32
+ # defaulting to superglue:view_collection
33
+ hook_for :view_collection, required: true, default: "view_collection"
34
+
35
+ hook_for :resource_route, in: :rails, required: true do |route|
36
+ invoke route unless options.skip_routes?
37
+ end
38
+
39
+ hook_for :test_framework, in: :rails, as: :scaffold
40
+
41
+ # Invoke the helper using the controller name (pluralized)
42
+ hook_for :helper, in: :rails, as: :scaffold do |invoked|
43
+ invoke invoked, [controller_name]
44
+ end
45
+
46
+ private
47
+
48
+ def permitted_params
49
+ attachments, others = attributes_names.partition { |name| attachments?(name) }
50
+ params = others.map { |name| ":#{name}" }
51
+ params += attachments.map { |name| "#{name}: []" }
52
+ params.join(", ")
53
+ end
54
+
55
+ def attachments?(name)
56
+ attribute = attributes.find { |attr| attr.name == name }
57
+ attribute&.attachments?
58
+ end
59
+ end
60
+ end
61
+ end
@@ -1,7 +1,7 @@
1
1
  <%% initial_state = controller.render_to_string(active_template_virtual_path, formats: [:json], locals: local_assigns, layout: true) %>
2
2
 
3
3
  <script type="text/javascript">
4
- window.SUPERGLUE_INITIAL_PAGE_STATE=<%%= initial_state.html_safe %>;
4
+ window.SUPERGLUE_INITIAL_PAGE_STATE=<%%= initial_state.html_safe %>;<%%# erblint:disable ErbSafety %>
5
5
  </script>
6
6
 
7
7
  <%%# If you need SSR follow instructions at %>
@@ -1,7 +1,7 @@
1
1
  <%% initial_state = controller.render_to_string(active_template_virtual_path, formats: [:json], locals: local_assigns, layout: true) %>
2
2
 
3
3
  <script type="text/javascript">
4
- window.SUPERGLUE_INITIAL_PAGE_STATE=<%%= initial_state.html_safe %>;
4
+ window.SUPERGLUE_INITIAL_PAGE_STATE=<%%= initial_state.html_safe %>;<%%# erblint:disable ErbSafety %>
5
5
  </script>
6
6
 
7
7
  <%%# If you need SSR follow instructions at %>
@@ -1,7 +1,7 @@
1
1
  <%% initial_state = controller.render_to_string(active_template_virtual_path, formats: [:json], locals: local_assigns, layout: true) %>
2
2
 
3
3
  <script type="text/javascript">
4
- window.SUPERGLUE_INITIAL_PAGE_STATE=<%%= initial_state.html_safe %>;
4
+ window.SUPERGLUE_INITIAL_PAGE_STATE=<%%= initial_state.html_safe %>;<%%# erblint:disable ErbSafety %>
5
5
  </script>
6
6
 
7
7
  <%%# If you need SSR follow instructions at %>
@@ -1,7 +1,7 @@
1
1
  <%% initial_state = controller.render_to_string(active_template_virtual_path, formats: [:json], locals: local_assigns, layout: true) %>
2
2
 
3
3
  <script type="text/javascript">
4
- window.SUPERGLUE_INITIAL_PAGE_STATE=<%%= initial_state.html_safe %>;
4
+ window.SUPERGLUE_INITIAL_PAGE_STATE=<%%= initial_state.html_safe %>;<%%# erblint:disable ErbSafety %>
5
5
  </script>
6
6
 
7
7
  <%%# If you need SSR follow instructions at %>
@@ -0,0 +1,40 @@
1
+ import React from 'react'
2
+ import {
3
+ Form,
4
+ Layout,
5
+ <%- attributes.each do |attr| -%>
6
+ <%= js_component(attr)%>,
7
+ <%- end -%>
8
+ SubmitButton
9
+ } from '@javascript/components'
10
+ import { useContent } from '@thoughtbot/superglue'
11
+ import { useAppSelector } from '@javascript/store'
12
+
13
+ export default function <%= js_plural_table_name(:upper) %>Edit() {
14
+ const {
15
+ <%= js_singular_table_name %>Form,
16
+ <%= js_singular_table_name %>Path,
17
+ <%= js_plural_table_name %>Path,
18
+ } = useContent()
19
+
20
+ const {
21
+ inputs,
22
+ form,
23
+ extras
24
+ } = <%= js_singular_table_name %>Form
25
+ const validationErrors = useAppSelector((state) => state.flash["<%= js_singular_table_name%>FormErrors"])
26
+
27
+ return (
28
+ <Layout>
29
+ <Form {...form} extras={extras} validationErrors={validationErrors} data-sg-visit>
30
+ <%- attributes.each do |attr| -%>
31
+ <<%= js_component(attr)%> {...inputs.<%= attr.column_name.camelize(:lower)%>} label="<%= attr.column_name.humanize %>" errorKey="<%= attr.column_name %>" />
32
+ <%- end -%>
33
+ <SubmitButton {...inputs.submit} type="submit"> {inputs.submit.text} </SubmitButton>
34
+ </Form>
35
+
36
+ <a href={<%= js_singular_table_name %>Path} data-sg-visit>Show</a>
37
+ <a href={<%= js_plural_table_name %>Path} data-sg-visit>Back</a>
38
+ </Layout>
39
+ )
40
+ }
@@ -0,0 +1,62 @@
1
+ import React from 'react'
2
+ import { Form, Layout } from '@javascript/components'
3
+ import { useContent } from '@thoughtbot/superglue'
4
+
5
+ export default function <%= js_plural_table_name(:upper) %>Index() {
6
+ const {
7
+ new<%= js_singular_table_name(:upper) %>Path,
8
+ <%= js_plural_table_name %> = [],
9
+ } = useContent()
10
+
11
+ const <%= js_singular_table_name %>Items = <%= js_plural_table_name %>.map((<%= js_singular_table_name %>) => {
12
+ const {
13
+ id,
14
+ <%- showable_attributes.each do |attr| -%>
15
+ <%= attr.column_name.camelize(:lower)%>,
16
+ <%- end -%>
17
+ edit<%= js_singular_table_name(:upper) %>Path,
18
+ <%= js_singular_table_name %>Path,
19
+ deleteForm
20
+ } = <%= js_singular_table_name %>
21
+
22
+ const { form, extras } = deleteForm;
23
+
24
+ return (
25
+ <tr key={id}>
26
+ <%- showable_attributes.each do |attr| -%>
27
+ <td>{<%=attr.column_name.camelize(:lower)%>}</td>
28
+ <%- end -%>
29
+ <td><a href={ <%= js_singular_table_name %>Path } data-sg-visit>Show</a></td>
30
+ <td><a href={ edit<%= js_singular_table_name(:upper) %>Path } data-sg-visit>Edit</a></td>
31
+ <td>
32
+ <Form {...form} extras={extras} data-sg-visit>
33
+ <button type="submit">Delete</button>
34
+ </Form>
35
+ </td>
36
+ </tr>
37
+ )
38
+ })
39
+
40
+ return (
41
+ <Layout>
42
+ <h1><%= js_plural_table_name(:upper) %></h1>
43
+
44
+ <table>
45
+ <thead>
46
+ <%- showable_attributes.each do |attr| -%>
47
+ <tr><th><%=attr.column_name.humanize%></th></tr>
48
+ <%- end -%>
49
+ <tr>
50
+ <th colSpan={3}></th>
51
+ </tr>
52
+ </thead>
53
+
54
+ <tbody>
55
+ {<%= js_singular_table_name %>Items}
56
+ </tbody>
57
+ </table>
58
+ <br />
59
+ <a href={new<%= js_singular_table_name(:upper) %>Path} data-sg-visit>New <%= singular_table_name.humanize %></a>
60
+ </Layout>
61
+ )
62
+ }
@@ -0,0 +1,38 @@
1
+ import React from 'react'
2
+ import {
3
+ Form,
4
+ Layout,
5
+ <%- attributes.each do |attr| -%>
6
+ <%= js_component(attr)%>,
7
+ <%- end -%>
8
+ SubmitButton
9
+ } from '@javascript/components'
10
+ import { useContent } from '@thoughtbot/superglue'
11
+ import { useAppSelector } from '@javascript/store'
12
+
13
+ export default function <%= js_plural_table_name(:upper) %>New() {
14
+ const {
15
+ <%= js_singular_table_name %>Form,
16
+ <%= js_plural_table_name %>Path
17
+ } = useContent()
18
+
19
+ const {
20
+ inputs,
21
+ form,
22
+ extras
23
+ } = <%= js_singular_table_name %>Form
24
+ const validationErrors = useAppSelector((state) => state.flash["<%= js_singular_table_name%>FormErrors"])
25
+
26
+ return (
27
+ <Layout>
28
+ <Form {...form} extras={extras} validationErrors={validationErrors} data-sg-visit>
29
+ <%- attributes.each do |attr| -%>
30
+ <<%= js_component(attr)%> {...inputs.<%= attr.column_name.camelize(:lower)%>} label="<%= attr.column_name.humanize %>" errorKey="<%= attr.column_name %>" />
31
+ <%- end -%>
32
+ <SubmitButton {...inputs.submit} type="submit"> {inputs.submit.text} </SubmitButton>
33
+ </Form>
34
+
35
+ <a href={<%= js_plural_table_name %>Path} data-sg-visit>Back</a>
36
+ </Layout>
37
+ )
38
+ }
@@ -0,0 +1,26 @@
1
+ import React from 'react'
2
+ import { Layout } from '@javascript/components'
3
+ import { useContent } from '@thoughtbot/superglue'
4
+
5
+ export default function <%= js_plural_table_name(:upper) %>Show() {
6
+ const {
7
+ <%- showable_attributes.each do |attr| -%>
8
+ <%= attr.column_name.camelize(:lower) %>,
9
+ <%- end -%>
10
+ edit<%= js_singular_table_name(:upper) %>Path,
11
+ <%= js_plural_table_name %>Path
12
+ } = useContent()
13
+
14
+ return (
15
+ <Layout>
16
+ <%- showable_attributes.each do |attr| -%>
17
+ <p>
18
+ <strong><%= attr.column_name.humanize %>:</strong>
19
+ {<%=attr.column_name.camelize(:lower)%>}
20
+ </p>
21
+ <%- end -%>
22
+ <a href={ edit<%= js_singular_table_name(:upper) %>Path } data-sg-visit>Edit</a>
23
+ <a href={ <%= js_plural_table_name %>Path } data-sg-visit>Back</a>
24
+ </Layout>
25
+ )
26
+ }
@@ -0,0 +1,9 @@
1
+ if @<%= singular_table_name %>.errors.any?
2
+ flash.now["<%= js_singular_table_name%>FormErrors"] = @<%= singular_table_name %>.errors.as_json
3
+ end
4
+
5
+ json.<%= js_singular_table_name %>Form(partial: 'form') do
6
+ end
7
+
8
+ json.<%= js_singular_table_name%>Path <%= singular_table_name%>_path(@<%=singular_table_name%>)
9
+ json.<%= js_plural_table_name %>Path <%= plural_table_name %>_path
@@ -0,0 +1,14 @@
1
+ json.<%= js_plural_table_name %> do
2
+ json.array! @<%= plural_table_name %> do |<%= singular_table_name %>|
3
+ <%- attributes_list_with_timestamps.each do |attr| -%>
4
+ json.<%=attr.to_s.camelize(:lower)%> <%= singular_table_name %>.<%=attr%>
5
+ <%- end -%>
6
+ json.edit<%=js_singular_table_name(:upper)%>Path edit_<%=singular_table_name%>_path(<%=singular_table_name%>)
7
+ json.<%=js_singular_table_name%>Path <%=singular_table_name%>_path(<%=singular_table_name%>)
8
+ json.deleteForm do
9
+ form_props(model: <%=singular_table_name%>, method: :delete)
10
+ end
11
+ end
12
+ end
13
+
14
+ json.new<%= js_singular_table_name(:upper) %>Path new_<%= singular_table_name %>_path
@@ -0,0 +1,10 @@
1
+ if @<%= singular_table_name %>.errors.any?
2
+ flash.now["<%= js_singular_table_name%>FormErrors"] = @<%= singular_table_name %>.errors.as_json
3
+ end
4
+
5
+ json.<%= js_singular_table_name %>Form(partial: 'form') do
6
+ end
7
+
8
+ json.<%= js_plural_table_name %>Path <%= plural_table_name %>_path
9
+
10
+
@@ -0,0 +1,6 @@
1
+ <%- attributes_list_with_timestamps.each do |attr|-%>
2
+ json.<%=attr.to_s.camelize(:lower)%> @<%= singular_table_name %>.<%=attr%>
3
+ <%- end -%>
4
+
5
+ json.<%= js_plural_table_name %>Path <%= plural_table_name %>_path
6
+ json.edit<%= js_singular_table_name(:upper) %>Path edit_<%= singular_table_name %>_path(@<%= singular_table_name %>)
@@ -0,0 +1,54 @@
1
+ import React from 'react'
2
+ import {
3
+ Form,
4
+ FormProps,
5
+ Layout,
6
+ <%- attributes.each do |attr| -%>
7
+ <%= js_component(attr)%>,
8
+ <%= js_component(attr)%>Props,
9
+ <%- end -%>
10
+ SubmitButton,
11
+ SubmitButtonProps
12
+ } from '@javascript/components'
13
+ import { useContent } from '@thoughtbot/superglue'
14
+ import { useAppSelector } from '@javascript/store'
15
+
16
+ type ContentProps = {
17
+ <%= js_singular_table_name %>Path: string
18
+ <%= js_plural_table_name %>Path: string,
19
+ <%= js_singular_table_name %>Form: FormProps<{
20
+ <%- attributes.each do |attr| -%>
21
+ <%= attr.column_name.camelize(:lower)%>: <%= js_component(attr)%>Props
22
+ <%- end -%>
23
+ submit: SubmitButtonProps
24
+ }>
25
+ }
26
+
27
+ export default function <%= js_plural_table_name(:upper) %>Edit() {
28
+ const {
29
+ <%= js_singular_table_name %>Form,
30
+ <%= js_singular_table_name %>Path,
31
+ <%= js_plural_table_name %>Path,
32
+ } = useContent<ContentProps>()
33
+
34
+ const {
35
+ inputs,
36
+ form,
37
+ extras
38
+ } = <%= js_singular_table_name %>Form
39
+ const validationErrors = useAppSelector((state) => state.flash["<%= js_singular_table_name%>FormErrors"])
40
+
41
+ return (
42
+ <Layout>
43
+ <Form {...form} extras={extras} validationErrors={validationErrors} data-sg-visit>
44
+ <%- attributes.each do |attr| -%>
45
+ <<%= js_component(attr)%> {...inputs.<%= attr.column_name.camelize(:lower)%>} label="<%= attr.column_name.humanize %>" errorKey="<%= attr.column_name %>" />
46
+ <%- end -%>
47
+ <SubmitButton {...inputs.submit} type="submit"> {inputs.submit.text} </SubmitButton>
48
+ </Form>
49
+
50
+ <a href={<%= js_singular_table_name %>Path} data-sg-visit>Show</a>
51
+ <a href={<%= js_plural_table_name %>Path} data-sg-visit>Back</a>
52
+ </Layout>
53
+ )
54
+ }
@@ -0,0 +1,77 @@
1
+ import React from 'react'
2
+ import { Form, FormProps, Layout } from '@javascript/components'
3
+ import { useContent } from '@thoughtbot/superglue'
4
+
5
+ type ContentProps = {
6
+ new<%= js_singular_table_name(:upper) %>Path: string
7
+ <%= js_plural_table_name %>: {
8
+ id: number,
9
+ <%- showable_attributes.each do |attr| -%>
10
+ <%= attr.column_name.camelize(:lower)%>: <%= json_mappable_type(attr)%>
11
+ <%- end -%>
12
+ createdAt: string,
13
+ updatedAt: string,
14
+ edit<%= js_singular_table_name(:upper) %>Path: string,
15
+ <%= js_singular_table_name %>Path: string,
16
+ deleteForm: FormProps
17
+ }[]
18
+ }
19
+
20
+ export default function <%= js_plural_table_name(:upper) %>Index() {
21
+ const {
22
+ new<%= js_singular_table_name(:upper) %>Path,
23
+ <%= js_plural_table_name %> = [],
24
+ } = useContent<ContentProps>()
25
+
26
+ const <%= js_singular_table_name %>Items = <%= js_plural_table_name %>.map((<%= js_singular_table_name %>) => {
27
+ const {
28
+ id,
29
+ <%- showable_attributes.each do |attr| -%>
30
+ <%= attr.column_name.camelize(:lower)%>,
31
+ <%- end -%>
32
+ edit<%= js_singular_table_name(:upper) %>Path,
33
+ <%= js_singular_table_name %>Path,
34
+ deleteForm
35
+ } = <%= js_singular_table_name %>
36
+
37
+ const { form, extras } = deleteForm;
38
+
39
+ return (
40
+ <tr key={id}>
41
+ <%- showable_attributes.each do |attr| -%>
42
+ <td>{<%=attr.column_name.camelize(:lower)%>}</td>
43
+ <%- end -%>
44
+ <td><a href={ <%= js_singular_table_name %>Path } data-sg-visit>Show</a></td>
45
+ <td><a href={ edit<%= js_singular_table_name(:upper) %>Path } data-sg-visit>Edit</a></td>
46
+ <td>
47
+ <Form {...form} extras={extras} data-sg-visit>
48
+ <button type="submit">Delete</button>
49
+ </Form>
50
+ </td>
51
+ </tr>
52
+ )
53
+ })
54
+
55
+ return (
56
+ <Layout>
57
+ <h1><%= js_plural_table_name(:upper) %></h1>
58
+
59
+ <table>
60
+ <thead>
61
+ <%- showable_attributes.each do |attr| -%>
62
+ <tr><th><%=attr.column_name.humanize%></th></tr>
63
+ <%- end -%>
64
+ <tr>
65
+ <th colSpan={3}></th>
66
+ </tr>
67
+ </thead>
68
+
69
+ <tbody>
70
+ {<%= js_singular_table_name %>Items}
71
+ </tbody>
72
+ </table>
73
+ <br />
74
+ <a href={new<%= js_singular_table_name(:upper) %>Path} data-sg-visit>New <%= singular_table_name.humanize %></a>
75
+ </Layout>
76
+ )
77
+ }
@@ -0,0 +1,50 @@
1
+ import React from 'react'
2
+ import {
3
+ Form,
4
+ FormProps,
5
+ Layout,
6
+ <%- attributes.each do |attr| -%>
7
+ <%= js_component(attr)%>,
8
+ <%= js_component(attr)%>Props,
9
+ <%- end -%>
10
+ SubmitButton,
11
+ SubmitButtonProps
12
+ } from '@javascript/components'
13
+ import { useContent } from '@thoughtbot/superglue'
14
+ import { useAppSelector } from '@javascript/store'
15
+
16
+ type ContentProps = {
17
+ <%= js_plural_table_name %>Path: string
18
+ <%= js_singular_table_name %>Form: FormProps<{
19
+ <%- attributes.each do |attr| -%>
20
+ <%= attr.column_name.camelize(:lower)%>: <%= js_component(attr)%>Props
21
+ <%- end -%>
22
+ submit: SubmitButtonProps
23
+ }>
24
+ }
25
+
26
+ export default function <%= js_plural_table_name(:upper) %>New() {
27
+ const {
28
+ <%= js_singular_table_name %>Form,
29
+ <%= js_plural_table_name %>Path,
30
+ } = useContent<ContentProps>()
31
+ const {
32
+ inputs,
33
+ form,
34
+ extras
35
+ } = <%= js_singular_table_name %>Form
36
+ const validationErrors = useAppSelector((state) => state.flash["<%= js_singular_table_name%>FormErrors"])
37
+
38
+ return (
39
+ <Layout>
40
+ <Form {...form} extras={extras} validationErrors={validationErrors} data-sg-visit>
41
+ <%- attributes.each do |attr| -%>
42
+ <<%= js_component(attr)%> {...inputs.<%= attr.column_name.camelize(:lower)%>} label="<%= attr.column_name.humanize %>" errorKey="<%= attr.column_name %>" />
43
+ <%- end -%>
44
+ <SubmitButton {...inputs.submit} type="submit"> {inputs.submit.text} </SubmitButton>
45
+ </Form>
46
+
47
+ <a href={<%= js_plural_table_name %>Path} data-sg-visit>Back</a>
48
+ </Layout>
49
+ )
50
+ }
@@ -0,0 +1,37 @@
1
+ import React from 'react'
2
+ import { Layout } from '@javascript/components'
3
+ import { useContent } from '@thoughtbot/superglue'
4
+
5
+ type ContentProps = {
6
+ id: string
7
+ <%- attributes.each do |attr| -%>
8
+ <%= attr.column_name.camelize(:lower)%>: <%= json_mappable_type(attr)%>
9
+ <%- end -%>
10
+ createdAt: string
11
+ updatedAt: string
12
+ <%= js_plural_table_name %>Path: string
13
+ edit<%= js_singular_table_name(:upper) %>Path: string
14
+ }
15
+
16
+ export default function <%= js_plural_table_name(:upper) %>Show() {
17
+ const {
18
+ <%- showable_attributes.each do |attr| -%>
19
+ <%= attr.column_name.camelize(:lower) %>,
20
+ <%- end -%>
21
+ edit<%= js_singular_table_name(:upper) %>Path,
22
+ <%= js_plural_table_name %>Path,
23
+ } = useContent<ContentProps>()
24
+
25
+ return (
26
+ <Layout>
27
+ <%- showable_attributes.each do |attr| -%>
28
+ <p>
29
+ <strong><%= attr.column_name.humanize %>:</strong>
30
+ {<%=attr.column_name.camelize(:lower)%>}
31
+ </p>
32
+ <%- end -%>
33
+ <a href={ edit<%= js_singular_table_name(:upper) %>Path } data-sg-visit>Edit</a>
34
+ <a href={ <%= js_plural_table_name %>Path } data-sg-visit>Back</a>
35
+ </Layout>
36
+ )
37
+ }