Skip to content

Commit c286411

Browse files
committed
Add TypeScript support for Vue scaffolds
1 parent f370f23 commit c286411

File tree

17 files changed

+658
-6
lines changed

17 files changed

+658
-6
lines changed

lib/generators/inertia_templates/scaffold/templates/react/Index.tsx.tt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import <%= inertia_component_name %>, { <%= inertia_model_type %> } from './<%=
33

44
interface IndexProps {
55
<%= plural_table_name %>: <%= inertia_model_type %>[]
6-
flash: { notice: string }
6+
flash: { notice?: string }
77
}
88

99
export default function Index({ <%= plural_table_name %>, flash }: IndexProps) {

lib/generators/inertia_templates/scaffold/templates/react/Show.tsx.tt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import <%= inertia_component_name %>, { <%= inertia_model_type %> } from './<%=
44

55
interface ShowProps {
66
<%= singular_table_name %>: <%= inertia_model_type %>
7-
flash: { notice: string }
7+
flash: { notice?: string }
88
}
99

1010
export default function Show({ <%= singular_table_name %>, flash }: ShowProps) {
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<template>
2+
<Head title="Editing <%= human_name.downcase %>" />
3+
4+
<h1>Editing <%= human_name.downcase %></h1>
5+
6+
<Form
7+
:<%= singular_table_name %>="<%= singular_table_name %>"
8+
submitText="Update <%= human_name.downcase %>"
9+
@onSubmit="handleSubmit"
10+
/>
11+
12+
<br />
13+
14+
<div>
15+
<Link :href="`<%= js_resource_path %>`">Show this <%= human_name.downcase %></Link> |
16+
<Link href="<%= js_resources_path %>">Back to <%= human_name.pluralize.downcase %></Link>
17+
</div>
18+
</template>
19+
20+
<script setup lang="ts">
21+
import { Link, Head, InertiaForm } from '@inertiajs/vue3'
22+
import Form, { <%= inertia_component_name %>FormType } from './Form.vue'
23+
import { <%= inertia_model_type %> } from './<%= inertia_component_name %>.vue'
24+
25+
const { <%= singular_table_name %> } = defineProps<{ <%= singular_table_name %>: <%= inertia_model_type %> }>()
26+
27+
const handleSubmit = (form: InertiaForm<<%= inertia_component_name %>FormType>) => {
28+
form.transform((data) => ({ <%= singular_table_name %>: data }))
29+
<% if attributes.any?(&:attachments?) -%>
30+
form.post(`<%= js_resource_path %>`, {
31+
headers: { 'X-HTTP-METHOD-OVERRIDE': 'put' },
32+
})
33+
<% else -%>
34+
form.patch(`<%= js_resource_path %>`)
35+
<% end -%>
36+
}
37+
</script>
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
<template>
2+
<form @submit.prevent="emit('onSubmit', form)">
3+
<% attributes.each do |attribute| -%>
4+
<% if attribute.password_digest? -%>
5+
<div>
6+
<label class="label" for="password">Password</label>
7+
<input
8+
type="password"
9+
name="password"
10+
id="password"
11+
v-model="form.password"
12+
/>
13+
<div v-if="form.errors.password" class="error">
14+
{{ form.errors.password }}
15+
</div>
16+
</div>
17+
18+
<div>
19+
<label class="label" for="password_confirmation">
20+
Password Confirmation
21+
</label>
22+
<input
23+
type="password"
24+
name="password_confirmation"
25+
id="password_confirmation"
26+
v-model="form.password_confirmation"
27+
/>
28+
<div v-if="form.errors.password_confirmation" class="error">
29+
{{ form.errors.password_confirmation }}
30+
</div>
31+
</div>
32+
<% else -%>
33+
<div>
34+
<label class="label" for="<%= attribute.singular_name %>"><%= attribute.human_name %></label>
35+
<% if input_type(attribute) == "text_area" -%>
36+
<textarea name="<%= attribute.singular_name %>" id="<%= attribute.singular_name %>" v-model="form.<%= attribute.column_name %>" />
37+
<% elsif attribute.attachment? -%>
38+
<input
39+
type="file"
40+
name="<%= attribute.singular_name %>"
41+
id="<%= attribute.singular_name %>"
42+
@input="form.<%= attribute.column_name %> = (($event.target as HTMLInputElement).files || [])[0]"
43+
/>
44+
<% elsif attribute.attachments? -%>
45+
<input
46+
type="file"
47+
multiple
48+
name="<%= attribute.singular_name %>[]"
49+
id="<%= attribute.singular_name %>"
50+
@input="form.<%= attribute.column_name %> = Array.from(($event.target as HTMLInputElement).files || [])"
51+
/>
52+
<% else -%>
53+
<input type="<%= input_type(attribute) %>" name="<%= attribute.singular_name %>" id="<%= attribute.singular_name %>" v-model="form.<%= attribute.column_name %>" />
54+
<% end -%>
55+
<div v-if="form.errors.<%= attribute.column_name %>" class="error">
56+
{{ form.errors.<%= attribute.column_name %> }}
57+
</div>
58+
</div>
59+
<% end -%>
60+
<% end -%>
61+
<div>
62+
<button type="submit" :disabled="form.processing">
63+
{{ submitText }}
64+
</button>
65+
</div>
66+
</form>
67+
</template>
68+
69+
<script setup lang="ts">
70+
import { useForm, InertiaForm } from '@inertiajs/vue3'
71+
import { <%= inertia_model_type %> } from './<%= inertia_component_name %>.vue'
72+
73+
export type <%= inertia_component_name %>FormType = Omit<<%= inertia_model_type %>, <%= omit_input_attributes.map { |a| "'#{a}'" }.join(' | ') %>><% if custom_form_attributes.any? -%> & {
74+
<% custom_form_attributes.map do |attribute| -%>
75+
<% if attribute.password_digest? -%>
76+
password: string
77+
password_confirmation: string
78+
<% elsif attribute.attachment? -%>
79+
<%= attribute.column_name %>?: File
80+
<% elsif attribute.attachments? -%>
81+
<%= attribute.column_name %>?: File[]
82+
<% end -%>
83+
<% end -%>
84+
}<% end -%>
85+
86+
const { <%= singular_table_name %>, submitText } = defineProps<{
87+
<%= singular_table_name %>: <%= inertia_model_type %>
88+
submitText: string
89+
}>()
90+
91+
const emit = defineEmits<{
92+
onSubmit: [form: InertiaForm<<%= inertia_component_name %>FormType>]
93+
}>()
94+
95+
const form = useForm<<%= inertia_component_name %>FormType>({
96+
<% attributes.reject { |a| a.attachment? || a.attachments? }.each do |attribute| -%>
97+
<% if attribute.password_digest? -%>
98+
password: '',
99+
password_confirmation: '',
100+
<% else -%>
101+
<%= attribute.column_name %>: <%= singular_table_name %>.<%= attribute.column_name %>,
102+
<% end -%>
103+
<% end -%>
104+
})
105+
</script>
106+
107+
<style scoped>
108+
.label {
109+
display: block;
110+
}
111+
.error {
112+
color: red;
113+
}
114+
</style>
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<template>
2+
<Head title="<%= human_name.pluralize %>" />
3+
4+
<p v-if="flash.notice" class="notice">{{ flash.notice }}</p>
5+
6+
<h1><%= human_name.pluralize %></h1>
7+
8+
<div>
9+
<div v-for="<%= singular_table_name %> in <%= plural_table_name %>" :key="<%= singular_table_name %>.id">
10+
<<%= inertia_component_name %> :<%= singular_table_name %>="<%= singular_table_name %>" />
11+
<p>
12+
<Link :href="`<%= js_resource_path %>`">Show this <%= human_name.downcase %></Link>
13+
</p>
14+
</div>
15+
</div>
16+
17+
<Link href="<%= js_new_resource_path %>">New <%= human_name.downcase %></Link>
18+
</template>
19+
20+
<script setup lang="ts">
21+
import { Link, Head } from '@inertiajs/vue3'
22+
import <%= inertia_component_name %> from './<%= inertia_component_name %>.vue'
23+
24+
const { <%= plural_table_name %>, flash } = defineProps(['<%= plural_table_name %>', 'flash'])
25+
</script>
26+
27+
<style scoped>
28+
.notice {
29+
color: green;
30+
}
31+
</style>
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<template>
2+
<Head title="New <%= human_name.downcase %>" />
3+
4+
<h1>New <%= human_name.downcase %></h1>
5+
6+
<Form
7+
:<%= singular_table_name %>="<%= singular_table_name %>"
8+
submitText="Create <%= human_name.downcase %>"
9+
@onSubmit="handleSubmit"
10+
/>
11+
12+
<br />
13+
14+
<div>
15+
<Link href="<%= js_resources_path %>">Back to <%= human_name.pluralize.downcase %></Link>
16+
</div>
17+
</template>
18+
19+
<script setup lang="ts">
20+
import { Link, Head, InertiaForm } from '@inertiajs/vue3'
21+
import Form, { <%= inertia_component_name %>FormType } from './Form.vue'
22+
import { <%= inertia_model_type %> } from './<%= inertia_component_name %>.vue'
23+
24+
const { <%= singular_table_name %> } = defineProps<{ <%= singular_table_name %>: <%= inertia_model_type %> }>()
25+
26+
const handleSubmit = (form: InertiaForm<<%= inertia_component_name %>FormType>) => {
27+
form.transform((data) => ({ <%= singular_table_name %>: data }))
28+
form.post('<%= js_resources_path %>')
29+
}
30+
</script>
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<template>
2+
<div>
3+
<% attributes.reject(&:password_digest?).each do |attribute| -%>
4+
<p>
5+
<strong><%= attribute.human_name %>:</strong>
6+
<% if attribute.attachment? -%>
7+
<a v-if="<%= singular_table_name %>.<%= attribute.column_name %>" :href="<%= singular_table_name %>.<%= attribute.column_name %>.url">
8+
{{ <%= singular_table_name %>.<%= attribute.column_name %>.filename }}
9+
</a>
10+
</p>
11+
<% elsif attribute.attachments? -%>
12+
</p>
13+
<div v-for="file in <%= singular_table_name %>.<%= attribute.column_name %>">
14+
<a :href="file.url">{{ file.filename }}</a>
15+
</div>
16+
<% else -%>
17+
{{ <%= singular_table_name %>.<%= attribute.column_name %> }}
18+
</p>
19+
<% end -%>
20+
<% end -%>
21+
</div>
22+
</template>
23+
24+
<script setup lang="ts">
25+
export interface <%= inertia_model_type %> {
26+
id: number
27+
<% attributes.reject(&:password_digest?).each do |attribute| -%>
28+
<%= attribute.column_name %>: <%= ts_type(attribute) %>
29+
<% end -%>
30+
}
31+
32+
const { <%= singular_table_name %> } = defineProps<{ <%= singular_table_name %>: <%= inertia_model_type %> }>()
33+
</script>
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<template>
2+
<Head :title="`<%= human_name %> #${<%= singular_table_name %>.id}`" />
3+
4+
<p v-if="flash.notice" class="notice">{{ flash.notice }}</p>
5+
6+
<h1><%= human_name %> #{{ <%= singular_table_name %>.id }}</h1>
7+
8+
<<%= inertia_component_name %> :<%= singular_table_name %>="<%= singular_table_name %>" />
9+
10+
<div>
11+
<Link :href="`<%= js_edit_resource_path %>`">Edit this <%= human_name.downcase %></Link> |
12+
<Link href="<%= js_resources_path %>">Back to <%= human_name.pluralize.downcase %></Link>
13+
14+
<br />
15+
16+
<Link
17+
:href="`<%= js_resource_path %>`"
18+
@click="onDestroy"
19+
as="button"
20+
method="delete"
21+
>
22+
Destroy this <%= human_name.downcase %>
23+
</Link>
24+
</div>
25+
</template>
26+
27+
<script setup lang="ts">
28+
import { Link, Head } from '@inertiajs/vue3'
29+
import <%= inertia_component_name %>, { <%= inertia_model_type %> } from './<%= inertia_component_name %>.vue'
30+
31+
const { <%= singular_table_name %>, flash } = defineProps<{
32+
<%= singular_table_name %>: <%= inertia_model_type %>
33+
flash: { notice?: string }
34+
}>()
35+
36+
const onDestroy = (e: Event) => {
37+
if (!confirm('Are you sure you want to delete this <%= human_name.downcase %>?')) {
38+
e.preventDefault()
39+
}
40+
}
41+
</script>
42+
43+
<style scoped>
44+
.notice {
45+
color: green;
46+
}
47+
</style>

lib/generators/inertia_tw_templates/scaffold/templates/react/Index.tsx.tt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import <%= inertia_component_name %>, { <%= inertia_model_type %> } from './<%=
44

55
interface IndexProps {
66
<%= plural_table_name %>: <%= inertia_model_type %>[]
7-
flash: { notice: string }
7+
flash: { notice?: string }
88
}
99

1010
export default function Index({ <%= plural_table_name %>, flash }: IndexProps) {

lib/generators/inertia_tw_templates/scaffold/templates/react/Show.tsx.tt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import <%= inertia_component_name %>, { <%= inertia_model_type %> } from './<%=
44

55
interface ShowProps {
66
<%= singular_table_name %>: <%= inertia_model_type %>
7-
flash: { notice: string }
7+
flash: { notice?: string }
88
}
99

1010
export default function Show({ <%= singular_table_name %>, flash }: ShowProps) {

0 commit comments

Comments
 (0)