next_on_rails 0.1.1
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.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +591 -0
- data/Rakefile +32 -0
- data/app/controllers/next_on_rails/application_controller.rb +21 -0
- data/app/controllers/next_on_rails/devise_token_auth_override/concerns/current_resource_serializer.rb +15 -0
- data/app/controllers/next_on_rails/devise_token_auth_override/confirmations_controller.rb +4 -0
- data/app/controllers/next_on_rails/devise_token_auth_override/omniauth_callbacks_controller.rb +7 -0
- data/app/controllers/next_on_rails/devise_token_auth_override/passwords_controller.rb +23 -0
- data/app/controllers/next_on_rails/devise_token_auth_override/registrations_controller.rb +33 -0
- data/app/controllers/next_on_rails/devise_token_auth_override/sessions_controller.rb +27 -0
- data/app/controllers/next_on_rails/devise_token_auth_override/token_validations_controller.rb +13 -0
- data/app/controllers/next_on_rails/devise_token_auth_override/unlocks_controller.rb +23 -0
- data/app/controllers/next_on_rails/merger_controller.rb +36 -0
- data/app/serializers/next_on_rails/active_model_errors_serializer.rb +45 -0
- data/app/serializers/next_on_rails/errors_serializer.rb +16 -0
- data/config/routes.rb +12 -0
- data/lib/generators/nor/backend/backend_generator.rb +129 -0
- data/lib/generators/nor/backend/templates/Procfile +2 -0
- data/lib/generators/nor/backend/templates/application_controller.rb +2 -0
- data/lib/generators/nor/backend/templates/cors.rb +23 -0
- data/lib/generators/nor/backend/templates/current_user_serializer.rb.tt +8 -0
- data/lib/generators/nor/backend/templates/user.rb.tt +8 -0
- data/lib/generators/nor/backend/templates/user_migration.rb.tt +53 -0
- data/lib/generators/nor/backend/templates/user_serializer.rb.tt +11 -0
- data/lib/generators/nor/frontend/frontend_generator.rb +60 -0
- data/lib/generators/nor/frontend/templates/frontend/components/flash.js +29 -0
- data/lib/generators/nor/frontend/templates/frontend/components/inputs.js +69 -0
- data/lib/generators/nor/frontend/templates/frontend/components/login-form.js +23 -0
- data/lib/generators/nor/frontend/templates/frontend/components/registration-form.js +49 -0
- data/lib/generators/nor/frontend/templates/frontend/next-on-rails.config.js +3 -0
- data/lib/generators/nor/frontend/templates/frontend/next.config.js +20 -0
- data/lib/generators/nor/frontend/templates/frontend/pages/_app.js +3 -0
- data/lib/generators/nor/frontend/templates/frontend/pages/index.js +57 -0
- data/lib/generators/nor/frontend/templates/frontend/server.js +31 -0
- data/lib/generators/nor/frontend/templates/frontend/stylesheets/application.scss +2 -0
- data/lib/generators/nor/install/USAGE +30 -0
- data/lib/generators/nor/install/install_generator.rb +8 -0
- data/lib/generators/nor/scaffold/USAGE +10 -0
- data/lib/generators/nor/scaffold/scaffold_generator.rb +53 -0
- data/lib/generators/nor/scaffold/templates/controller.rb.tt +40 -0
- data/lib/generators/nor/scaffold/templates/frontend/components/details.js.tt +20 -0
- data/lib/generators/nor/scaffold/templates/frontend/components/form.js.tt +17 -0
- data/lib/generators/nor/scaffold/templates/frontend/pages/crud.js.tt +123 -0
- data/lib/generators/nor/scaffold/templates/frontend/pages/edit.js.tt +55 -0
- data/lib/generators/nor/scaffold/templates/frontend/pages/index.js.tt +88 -0
- data/lib/generators/nor/scaffold/templates/frontend/pages/new.js.tt +51 -0
- data/lib/generators/nor/scaffold/templates/frontend/pages/show.js.tt +43 -0
- data/lib/next_on_rails.rb +12 -0
- data/lib/next_on_rails/engine.rb +5 -0
- data/lib/next_on_rails/version.rb +3 -0
- data/lib/tasks/next_on_rails_tasks.rake +4 -0
- metadata +235 -0
@@ -0,0 +1,30 @@
|
|
1
|
+
Description:
|
2
|
+
This generator will install all the necessary configuration and migration
|
3
|
+
files for the Next On Rails gem. See
|
4
|
+
https://github.com/Uqido/next-on-rails for more information.
|
5
|
+
|
6
|
+
Arguments:
|
7
|
+
USER_CLASS # The name of the class to use for user authentication. Default is
|
8
|
+
# 'User'
|
9
|
+
MOUNT_PATH # The path at which to mount the authentication routes. Default is
|
10
|
+
# 'auth'.
|
11
|
+
|
12
|
+
Example:
|
13
|
+
rails generate nor:install User auth
|
14
|
+
|
15
|
+
This will create:
|
16
|
+
config/initializers/devise_token_auth.rb
|
17
|
+
db/migrate/<%= Time.zone.now.utc.strftime("%Y%m%d%H%M%S") %>_create_devise_token_auth_create_users.rb
|
18
|
+
app/models/user.rb
|
19
|
+
|
20
|
+
If 'app/models/user.rb' already exists, the following line will be inserted
|
21
|
+
after the class definition:
|
22
|
+
include DeviseTokenAuth::Concerns::User
|
23
|
+
|
24
|
+
The following line will be inserted into your application controller at
|
25
|
+
app/controllers/application_controller.rb:
|
26
|
+
include DeviseTokenAuth::Concerns::SetUserByToken
|
27
|
+
|
28
|
+
The following line will be inserted at the top of 'config/routes.rb' if it
|
29
|
+
does not already exist:
|
30
|
+
mount_devise_token_auth_for 'User', at: 'auth'
|
@@ -0,0 +1,10 @@
|
|
1
|
+
Description:
|
2
|
+
This generator create a scaffold for a resource. It will setup a model, a
|
3
|
+
controller and a React page component for the Next.js frontend. See
|
4
|
+
https://github.com/Uqido/next-on-rails for more information.
|
5
|
+
|
6
|
+
Arguments:
|
7
|
+
RESOURCE_CLASS # The name of the resource class
|
8
|
+
|
9
|
+
Example:
|
10
|
+
rails generate nor:scaffold Post
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module Nor
|
2
|
+
class ScaffoldGenerator < Rails::Generators::NamedBase
|
3
|
+
include Rails::Generators::ResourceHelpers
|
4
|
+
|
5
|
+
source_root File.expand_path('templates', __dir__)
|
6
|
+
|
7
|
+
argument :attributes, type: :array, default: [], banner: 'field:type field:type'
|
8
|
+
|
9
|
+
def rails_scaffold
|
10
|
+
generate 'model', class_name, *attributes.map { |attribute| "#{attribute.name}:#{attribute.type}" }
|
11
|
+
template 'controller.rb', File.join('app', 'controllers', "#{plural_table_name}_controller.rb")
|
12
|
+
generate 'serializer', class_name
|
13
|
+
gsub_file File.join('app', 'serializers', "#{singular_table_name}_serializer.rb"), 'attributes ', "attributes #{attributes_list_string}"
|
14
|
+
route "resources :#{plural_name}"
|
15
|
+
end
|
16
|
+
|
17
|
+
def react_page_component
|
18
|
+
directory 'frontend/pages', File.join('frontend', 'pages', plural_table_name)
|
19
|
+
directory 'frontend/components', File.join('frontend', 'components', plural_table_name)
|
20
|
+
end
|
21
|
+
|
22
|
+
def add_server_js_get
|
23
|
+
code = <<~CODE
|
24
|
+
\s\s\s\sserver.get('/#{plural_table_name}/:id(\\\\\\\\d+)', (req, res) => {
|
25
|
+
\s\s\s\s app.render(req, res, '/#{plural_table_name}/show', { id: req.params.id })
|
26
|
+
\s\s\s\s})
|
27
|
+
|
28
|
+
\s\s\s\sserver.get('/#{plural_table_name}/:id(\\\\\\\\d+)/edit', (req, res) => {
|
29
|
+
\s\s\s\s app.render(req, res, '/#{plural_table_name}/edit', { id: req.params.id })
|
30
|
+
\s\s\s\s})
|
31
|
+
|
32
|
+
CODE
|
33
|
+
insert_into_file File.join('frontend', 'server.js'), code, before: " server.get('*'"
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def input_type(attribute)
|
39
|
+
case attribute.type
|
40
|
+
when :boolean
|
41
|
+
return 'CheckBox'
|
42
|
+
when :text
|
43
|
+
return 'TextArea'
|
44
|
+
else
|
45
|
+
return 'Input'
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def attributes_list_string
|
50
|
+
(['id'] + attributes_names).map { |attribute_name| ":#{attribute_name}" }.join(', ')
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
class <%= controller_class_name %>Controller < ApplicationController
|
2
|
+
before_action :set_<%= singular_table_name %>, only: [:show, :update, :destroy]
|
3
|
+
|
4
|
+
def index
|
5
|
+
@<%= plural_table_name %> = <%= class_name %>.all
|
6
|
+
render json: <%= class_name %>Serializer.new(@<%= plural_table_name %>)
|
7
|
+
end
|
8
|
+
|
9
|
+
def show
|
10
|
+
render_resource @<%= singular_table_name %>
|
11
|
+
end
|
12
|
+
|
13
|
+
def create
|
14
|
+
@<%= singular_table_name %> = <%= class_name %>.new(<%= singular_table_name %>_params)
|
15
|
+
@<%= singular_table_name %>.save
|
16
|
+
render_resource @<%= singular_table_name %>, status: :created, location: @<%= singular_table_name %>
|
17
|
+
end
|
18
|
+
|
19
|
+
def update
|
20
|
+
@<%= singular_table_name %>.update(<%= singular_table_name %>_params)
|
21
|
+
render_resource @<%= singular_table_name %>
|
22
|
+
end
|
23
|
+
|
24
|
+
def destroy
|
25
|
+
@<%= singular_table_name %>.destroy
|
26
|
+
render head: :ok
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
# Use callbacks to share common setup or constraints between actions.
|
32
|
+
def set_<%= singular_table_name %>
|
33
|
+
@<%= singular_table_name %> = <%= class_name %>.find(params[:id])
|
34
|
+
end
|
35
|
+
|
36
|
+
# Only allow a trusted parameter "white list" through.
|
37
|
+
def <%= singular_table_name %>_params
|
38
|
+
params.permit(<%= attributes_list_string %>)
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
const <%= controller_class_name %>Details = ({ <%= singular_table_name.camelize(:lower) %> }) => (
|
2
|
+
<dl>
|
3
|
+
<% attributes_names.each do |attribute_name| -%>
|
4
|
+
<dt>
|
5
|
+
<b><%= attribute_name.titleize %></b>
|
6
|
+
</dt>
|
7
|
+
<dd>{<%= singular_table_name.camelize(:lower) %>.<%= attribute_name.camelize(:lower) %>}</dd>
|
8
|
+
<% end -%>
|
9
|
+
<dt>
|
10
|
+
<b>Created At</b>
|
11
|
+
</dt>
|
12
|
+
<dd>{<%= singular_table_name.camelize(:lower) %>.createdAt}</dd>
|
13
|
+
<dt>
|
14
|
+
<b>Updated At</b>
|
15
|
+
</dt>
|
16
|
+
<dd>{<%= singular_table_name.camelize(:lower) %>.updatedAt}</dd>
|
17
|
+
</dl>
|
18
|
+
)
|
19
|
+
|
20
|
+
export default <%= controller_class_name %>Details
|
@@ -0,0 +1,17 @@
|
|
1
|
+
import { Input, TextArea, CheckBox, Select, HiddenIdField } from '../inputs'
|
2
|
+
|
3
|
+
const <%= controller_class_name %>Form = ({ <%= singular_table_name.camelize(:lower) %> = {}, submit, getError }) => {
|
4
|
+
return (
|
5
|
+
<form onSubmit={submit}>
|
6
|
+
<HiddenIdField id={<%= singular_table_name.camelize(:lower) %>.id} />
|
7
|
+
<% attributes.each do |attribute| -%>
|
8
|
+
<<%= input_type(attribute) %> name="<%= attribute.name %>" value={<%= singular_table_name.camelize(:lower) %>.<%= attribute.name.camelize(:lower) %>} error={getError('<%= attribute.name %>')} />
|
9
|
+
<% end -%>
|
10
|
+
<button type="submit" className="btn btn-primary">
|
11
|
+
Save
|
12
|
+
</button>
|
13
|
+
</form>
|
14
|
+
)
|
15
|
+
}
|
16
|
+
|
17
|
+
export default <%= controller_class_name %>Form
|
@@ -0,0 +1,123 @@
|
|
1
|
+
import Link from 'next/link'
|
2
|
+
import { useState } from 'react'
|
3
|
+
import { useLoading } from 'next-on-rails/utils'
|
4
|
+
import { getInitialResources, useResources, useResourceForm } from 'next-on-rails/resources'
|
5
|
+
|
6
|
+
import <%= controller_class_name %>Details from '../../components/<%= plural_table_name %>/details'
|
7
|
+
import <%= controller_class_name %>Form from '../../components/<%= plural_table_name %>/form'
|
8
|
+
|
9
|
+
const <%= controller_class_name %>Crud = props => {
|
10
|
+
const [editMode, setEditMode] = useState(false)
|
11
|
+
const loading = useLoading()
|
12
|
+
const [<%= plural_table_name.camelize(:lower) %>, <%= singular_table_name.camelize(:lower) %>, { show, create, update, destroy }, dispatch] = useResources(
|
13
|
+
'<%= plural_table_name.camelize(:lower) %>',
|
14
|
+
props.<%= plural_table_name.camelize(:lower) %>,
|
15
|
+
props.<%= plural_table_name.camelize(:lower) %>[0]
|
16
|
+
)
|
17
|
+
const clickShow = id => event => {
|
18
|
+
show(id)
|
19
|
+
setEditMode(false)
|
20
|
+
}
|
21
|
+
const clickEdit = id => event => {
|
22
|
+
show(id)
|
23
|
+
setEditMode(true)
|
24
|
+
}
|
25
|
+
const [submitForCreateAction, getCreateActionError] = useResourceForm(create)
|
26
|
+
const [submitForUpdateAction, getUpdateActionError] = useResourceForm(update)
|
27
|
+
const clickDestroy = id => event => destroy(id)
|
28
|
+
const rowBg = id => (<%= singular_table_name.camelize(:lower) %> && <%= singular_table_name.camelize(:lower) %>.id === id ? 'bg-light' : '')
|
29
|
+
|
30
|
+
return (
|
31
|
+
<div>
|
32
|
+
<div className="position-absolute">{loading ? 'Loading...' : null}</div>
|
33
|
+
<div className="container pt-4">
|
34
|
+
<h1 className="mb-5"><%= controller_class_name.titleize %></h1>
|
35
|
+
|
36
|
+
<div className="row">
|
37
|
+
<div className="col">
|
38
|
+
<h3>List <%= controller_class_name.titleize %></h3>
|
39
|
+
{<%= plural_table_name.camelize(:lower) %>.length > 0 ? (
|
40
|
+
<table className="table">
|
41
|
+
<thead>
|
42
|
+
<tr>
|
43
|
+
<th>ID</th>
|
44
|
+
<% attributes_names.each do |attribute_name| -%>
|
45
|
+
<th><%= attribute_name.titleize %></th>
|
46
|
+
<% end -%>
|
47
|
+
<th></th>
|
48
|
+
</tr>
|
49
|
+
</thead>
|
50
|
+
<tbody>
|
51
|
+
{<%= plural_table_name.camelize(:lower) %>.map(<%= singular_table_name.camelize(:lower) %> => (
|
52
|
+
<tr key={<%= singular_table_name.camelize(:lower) %>.id} className={rowBg(<%= singular_table_name.camelize(:lower) %>.id)}>
|
53
|
+
<td>{<%= singular_table_name.camelize(:lower) %>.id}</td>
|
54
|
+
<% attributes_names.each do |attribute_name| -%>
|
55
|
+
<td>{<%= singular_table_name.camelize(:lower) %>.<%= attribute_name.camelize(:lower) %>}</td>
|
56
|
+
<% end -%>
|
57
|
+
<td className="text-right">
|
58
|
+
<div className="btn-group">
|
59
|
+
<button onClick={clickShow(<%= singular_table_name.camelize(:lower) %>.id)} className="btn btn-sm btn-info">
|
60
|
+
Show
|
61
|
+
</button>
|
62
|
+
<button onClick={clickEdit(<%= singular_table_name.camelize(:lower) %>.id)} className="btn btn-sm btn-info">
|
63
|
+
Edit
|
64
|
+
</button>
|
65
|
+
<button className="btn btn-sm btn-danger" onClick={clickDestroy(<%= singular_table_name.camelize(:lower) %>.id)}>
|
66
|
+
Delete
|
67
|
+
</button>
|
68
|
+
</div>
|
69
|
+
</td>
|
70
|
+
</tr>
|
71
|
+
))}
|
72
|
+
</tbody>
|
73
|
+
</table>
|
74
|
+
) : (
|
75
|
+
<p>No <%= controller_class_name.titleize %> Found</p>
|
76
|
+
)}
|
77
|
+
</div>
|
78
|
+
|
79
|
+
<div className="col">
|
80
|
+
{<%= singular_table_name.camelize(:lower) %> ? (
|
81
|
+
<React.Fragment>
|
82
|
+
<h3>{`<%= class_name %> #${<%= singular_table_name.camelize(:lower) %>.id}`}</h3>
|
83
|
+
{editMode ? (
|
84
|
+
<<%= controller_class_name %>Form key={<%= singular_table_name.camelize(:lower) %>.id} <%= singular_table_name.camelize(:lower) %>={<%= singular_table_name.camelize(:lower) %>} submit={submitForUpdateAction} getError={getUpdateActionError} />
|
85
|
+
) : (
|
86
|
+
<<%= controller_class_name %>Details <%= singular_table_name.camelize(:lower) %>={<%= singular_table_name.camelize(:lower) %>} />
|
87
|
+
)}
|
88
|
+
</React.Fragment>
|
89
|
+
) : (
|
90
|
+
<p>No <%= class_name.titleize %> Selected</p>
|
91
|
+
)}
|
92
|
+
</div>
|
93
|
+
</div>
|
94
|
+
|
95
|
+
<hr />
|
96
|
+
|
97
|
+
<div>
|
98
|
+
<h3>Create New <%= class_name.titleize %></h3>
|
99
|
+
<<%= controller_class_name %>Form submit={submitForCreateAction} getError={getCreateActionError} />
|
100
|
+
</div>
|
101
|
+
|
102
|
+
<hr />
|
103
|
+
|
104
|
+
<ul className="nav">
|
105
|
+
<li className="nav-item">
|
106
|
+
<Link href="/<%= plural_table_name %>">
|
107
|
+
<a className="nav-link">List <%= controller_class_name.titleize %></a>
|
108
|
+
</Link>
|
109
|
+
</li>
|
110
|
+
<li className="nav-item">
|
111
|
+
<Link href="/">
|
112
|
+
<a className="nav-link">Go to Home</a>
|
113
|
+
</Link>
|
114
|
+
</li>
|
115
|
+
</ul>
|
116
|
+
</div>
|
117
|
+
</div>
|
118
|
+
)
|
119
|
+
}
|
120
|
+
|
121
|
+
<%= controller_class_name %>Crud.getInitialProps = getInitialResources('<%= plural_table_name.camelize(:lower) %>')
|
122
|
+
|
123
|
+
export default <%= controller_class_name %>Crud
|
@@ -0,0 +1,55 @@
|
|
1
|
+
import { useState } from 'react'
|
2
|
+
import Link from 'next/link'
|
3
|
+
import Router from 'next/router'
|
4
|
+
import { useLoading, useFlash, getDetailFromResponseError } from 'next-on-rails/utils'
|
5
|
+
import { getInitialResource, useResources, useResourceForm } from 'next-on-rails/resources'
|
6
|
+
|
7
|
+
import <%= controller_class_name %>Form from '../../components/<%= plural_table_name %>/form'
|
8
|
+
|
9
|
+
const <%= controller_class_name %>Edit = props => {
|
10
|
+
const loading = useLoading()
|
11
|
+
const { setFlash } = useFlash()
|
12
|
+
const [, <%= singular_table_name.camelize(:lower) %>, { update }] = useResources('<%= plural_table_name.camelize(:lower) %>', props.<%= plural_table_name.camelize(:lower) %>, props.<%= singular_table_name.camelize(:lower) %>)
|
13
|
+
|
14
|
+
const [submit, getError] = useResourceForm(
|
15
|
+
update,
|
16
|
+
<%= singular_table_name %> => {
|
17
|
+
Router.push(`/<%= plural_table_name %>/show?id=${<%= singular_table_name.camelize(:lower) %>.id}`, `/<%= plural_table_name %>/${<%= singular_table_name.camelize(:lower) %>.id}`).then(() =>
|
18
|
+
setFlash({ notice: '<%= class_name.titleize %> updated successfully' })
|
19
|
+
)
|
20
|
+
},
|
21
|
+
error => {
|
22
|
+
setFlash({ alert: getDetailFromResponseError(error) })
|
23
|
+
}
|
24
|
+
)
|
25
|
+
|
26
|
+
return (
|
27
|
+
<div>
|
28
|
+
<div className="position-absolute">{loading ? 'Loading...' : null}</div>
|
29
|
+
<div className="container pt-4">
|
30
|
+
<h1 className="mb-5">Update <%= class_name.titleize %> #{<%= singular_table_name.camelize(:lower) %>.id}</h1>
|
31
|
+
|
32
|
+
<<%= controller_class_name %>Form <%= singular_table_name.camelize(:lower) %>={<%= singular_table_name.camelize(:lower) %>} submit={submit} getError={getError} />
|
33
|
+
|
34
|
+
<hr />
|
35
|
+
|
36
|
+
<ul className="nav">
|
37
|
+
<li className="nav-item">
|
38
|
+
<Link href="/<%= plural_table_name %>">
|
39
|
+
<a className="nav-link">List <%= controller_class_name.titleize %></a>
|
40
|
+
</Link>
|
41
|
+
</li>
|
42
|
+
<li className="nav-item">
|
43
|
+
<Link href={`/<%= plural_table_name %>/show?id=${<%= singular_table_name.camelize(:lower) %>.id}`} as={`/<%= plural_table_name %>/${<%= singular_table_name.camelize(:lower) %>.id}`}>
|
44
|
+
<a className="nav-link">Show <%= class_name.titleize %></a>
|
45
|
+
</Link>
|
46
|
+
</li>
|
47
|
+
</ul>
|
48
|
+
</div>
|
49
|
+
</div>
|
50
|
+
)
|
51
|
+
}
|
52
|
+
|
53
|
+
<%= controller_class_name %>Edit.getInitialProps = getInitialResource('<%= singular_table_name.camelize(:lower) %>')
|
54
|
+
|
55
|
+
export default <%= controller_class_name %>Edit
|
@@ -0,0 +1,88 @@
|
|
1
|
+
import { useState } from 'react'
|
2
|
+
import Link from 'next/link'
|
3
|
+
import { useLoading, useFlash } from 'next-on-rails/utils'
|
4
|
+
import { getInitialResources, useResources } from 'next-on-rails/resources'
|
5
|
+
|
6
|
+
import Flash from '../../components/flash'
|
7
|
+
|
8
|
+
const <%= controller_class_name %>Index = props => {
|
9
|
+
const loading = useLoading()
|
10
|
+
const { setFlash } = useFlash()
|
11
|
+
|
12
|
+
const [<%= plural_table_name.camelize(:lower) %>, _, { destroy }] = useResources('<%= plural_table_name.camelize(:lower) %>', props.<%= plural_table_name.camelize(:lower) %>, props.<%= singular_table_name.camelize(:lower) %>)
|
13
|
+
|
14
|
+
const clickDestroy = id => event => destroy(id).then(() => setFlash({ notice: '<%= class_name.titleize %> deleted successfully' }))
|
15
|
+
|
16
|
+
return (
|
17
|
+
<div>
|
18
|
+
<div className="position-absolute">{loading ? 'Loading...' : null}</div>
|
19
|
+
<div className="container pt-4">
|
20
|
+
<Flash />
|
21
|
+
<h1 className="mb-5"><%= controller_class_name.titleize %></h1>
|
22
|
+
|
23
|
+
{<%= plural_table_name.camelize(:lower) %>.length > 0 ? (
|
24
|
+
<table className="table">
|
25
|
+
<thead>
|
26
|
+
<tr>
|
27
|
+
<th>ID</th>
|
28
|
+
<% attributes_names.each do |attribute_name| -%>
|
29
|
+
<th><%= attribute_name.titleize %></th>
|
30
|
+
<% end -%>
|
31
|
+
<th></th>
|
32
|
+
</tr>
|
33
|
+
</thead>
|
34
|
+
<tbody>
|
35
|
+
{<%= plural_table_name.camelize(:lower) %>.map(<%= singular_table_name.camelize(:lower) %> => (
|
36
|
+
<tr key={<%= singular_table_name.camelize(:lower) %>.id}>
|
37
|
+
<td>{<%= singular_table_name.camelize(:lower) %>.id}</td>
|
38
|
+
<% attributes_names.each do |attribute_name| -%>
|
39
|
+
<td>{<%= singular_table_name.camelize(:lower) %>.<%= attribute_name.camelize(:lower) %>}</td>
|
40
|
+
<% end -%>
|
41
|
+
<td className="text-right">
|
42
|
+
<div className="btn-group">
|
43
|
+
<Link href={`/<%= plural_table_name %>/show?id=${<%= singular_table_name.camelize(:lower) %>.id}`} as={`/<%= plural_table_name %>/${<%= singular_table_name.camelize(:lower) %>.id}`}>
|
44
|
+
<a className="btn btn-sm btn-info">Show</a>
|
45
|
+
</Link>
|
46
|
+
<Link href={`/<%= plural_table_name %>/edit?id=${<%= singular_table_name.camelize(:lower) %>.id}`} as={`/<%= plural_table_name %>/${<%= singular_table_name.camelize(:lower) %>.id}/edit`}>
|
47
|
+
<a className="btn btn-sm btn-info">Edit</a>
|
48
|
+
</Link>
|
49
|
+
<button className="btn btn-sm btn-danger" onClick={clickDestroy(<%= singular_table_name.camelize(:lower) %>.id)}>
|
50
|
+
Delete
|
51
|
+
</button>
|
52
|
+
</div>
|
53
|
+
</td>
|
54
|
+
</tr>
|
55
|
+
))}
|
56
|
+
</tbody>
|
57
|
+
</table>
|
58
|
+
) : (
|
59
|
+
<p>No <%= controller_class_name.titleize %> Found</p>
|
60
|
+
)}
|
61
|
+
|
62
|
+
<hr />
|
63
|
+
|
64
|
+
<ul className="nav">
|
65
|
+
<li className="nav-item">
|
66
|
+
<Link href="/<%= plural_table_name %>/new">
|
67
|
+
<a className="nav-link">New <%= class_name.titleize %></a>
|
68
|
+
</Link>
|
69
|
+
</li>
|
70
|
+
<li className="nav-item">
|
71
|
+
<Link href="/<%= plural_table_name %>/crud">
|
72
|
+
<a className="nav-link">One Page CRUD</a>
|
73
|
+
</Link>
|
74
|
+
</li>
|
75
|
+
<li className="nav-item">
|
76
|
+
<Link href="/">
|
77
|
+
<a className="nav-link">Go to Home</a>
|
78
|
+
</Link>
|
79
|
+
</li>
|
80
|
+
</ul>
|
81
|
+
</div>
|
82
|
+
</div>
|
83
|
+
)
|
84
|
+
}
|
85
|
+
|
86
|
+
<%= controller_class_name %>Index.getInitialProps = getInitialResources('<%= plural_table_name.camelize(:lower) %>')
|
87
|
+
|
88
|
+
export default <%= controller_class_name %>Index
|