@@ -8,11 +8,17 @@ import {
8
8
import { setToastMessage } from '@app-builder/components/MarbleToaster' ;
9
9
import { isStatusConflictHttpError } from '@app-builder/models' ;
10
10
import { serverServices } from '@app-builder/services/init.server' ;
11
- import { parseFormSafe } from '@app-builder/utils/input-validation' ;
12
11
import { zodResolver } from '@hookform/resolvers/zod' ;
13
12
import { type ActionArgs , json } from '@remix-run/node' ;
14
13
import { useFetcher } from '@remix-run/react' ;
15
- import { Button , HiddenInputs , Input , Modal , Select } from '@ui-design-system' ;
14
+ import {
15
+ Button ,
16
+ Checkbox ,
17
+ HiddenInputs ,
18
+ Input ,
19
+ Modal ,
20
+ Select ,
21
+ } from '@ui-design-system' ;
16
22
import { Plus } from '@ui-icons' ;
17
23
import { type Namespace } from 'i18next' ;
18
24
import { useEffect , useState } from 'react' ;
@@ -27,12 +33,13 @@ export const handle = {
27
33
const createFieldFormSchema = z . object ( {
28
34
name : z
29
35
. string ( )
30
- . nonempty ( )
36
+ . min ( 1 )
31
37
. regex ( / ^ [ a - z A - Z 0 - 9 _ ] + $ / , { message : 'Only alphanumeric and _' } ) ,
32
38
description : z . string ( ) ,
33
39
required : z . string ( ) ,
34
40
type : z . enum ( [ 'String' , 'Bool' , 'Timestamp' , 'Float' , 'Int' ] ) ,
35
41
tableId : z . string ( ) ,
42
+ isEnum : z . boolean ( ) ,
36
43
} ) ;
37
44
38
45
const VALUE_TYPES = [
@@ -52,24 +59,27 @@ export async function action({ request }: ActionArgs) {
52
59
failureRedirect : '/login' ,
53
60
} ) ;
54
61
55
- const parsedForm = await parseFormSafe ( request , createFieldFormSchema ) ;
56
- if ( ! parsedForm . success ) {
57
- parsedForm . error . flatten ( ( issue ) => issue ) ;
62
+ const parsedData = createFieldFormSchema . safeParse ( await request . json ( ) ) ;
63
+
64
+ if ( ! parsedData . success ) {
65
+ parsedData . error . flatten ( ( issue ) => issue ) ;
58
66
59
67
return json ( {
60
68
success : false as const ,
61
- values : parsedForm . formData ,
62
- error : parsedForm . error . format ( ) ,
69
+ values : null ,
70
+ error : parsedData . error . format ( ) ,
63
71
} ) ;
64
72
}
65
- const { name, description, type, required, tableId } = parsedForm . data ;
73
+ const { name, description, type, required, tableId, isEnum } =
74
+ parsedData . data ;
66
75
67
76
try {
68
77
await apiClient . postDataModelTableField ( tableId , {
69
78
name : name ,
70
79
description : description ,
71
80
type,
72
81
nullable : required === 'optional' ,
82
+ is_enum : isEnum ,
73
83
} ) ;
74
84
return json ( {
75
85
success : true as const ,
@@ -87,15 +97,15 @@ export async function action({ request }: ActionArgs) {
87
97
return json (
88
98
{
89
99
success : false as const ,
90
- values : parsedForm . data ,
100
+ values : parsedData . data ,
91
101
error : error ,
92
102
} ,
93
103
{ headers : { 'Set-Cookie' : await commitSession ( session ) } }
94
104
) ;
95
105
} else {
96
106
return json ( {
97
107
success : false as const ,
98
- values : parsedForm . data ,
108
+ values : parsedData . data ,
99
109
error : error ,
100
110
} ) ;
101
111
}
@@ -115,6 +125,7 @@ export function CreateField({ tableId }: { tableId: string }) {
115
125
description : '' ,
116
126
type : VALUE_TYPES [ 0 ] . value ,
117
127
tableId : tableId ,
128
+ isEnum : false ,
118
129
} ,
119
130
} ) ;
120
131
const { control, register, reset } = formMethods ;
@@ -137,10 +148,11 @@ export function CreateField({ tableId }: { tableId: string }) {
137
148
< Modal . Content >
138
149
< Form
139
150
control = { control }
140
- onSubmit = { ( { formData } ) => {
141
- fetcher . submit ( formData , {
151
+ onSubmit = { ( { formDataJson } ) => {
152
+ fetcher . submit ( formDataJson , {
142
153
method : 'POST' ,
143
154
action : '/ressources/data/createField' ,
155
+ encType : 'application/json' ,
144
156
} ) ;
145
157
} }
146
158
>
@@ -242,6 +254,28 @@ export function CreateField({ tableId }: { tableId: string }) {
242
254
) }
243
255
/>
244
256
</ div >
257
+ < FormField
258
+ name = "isEnum"
259
+ control = { control }
260
+ render = { ( { field } ) => (
261
+ < FormItem className = "flex flex-row items-center gap-4" >
262
+ < FormControl >
263
+ < Checkbox
264
+ onCheckedChange = { ( checked ) => {
265
+ field . onChange ( checked ) ;
266
+ } }
267
+ />
268
+ </ FormControl >
269
+ < FormLabel >
270
+ < p > { t ( 'data:create_field.is_enum.title' ) } </ p >
271
+ < p className = "text-xs" >
272
+ { t ( 'data:create_field.is_enum.subtitle' ) }
273
+ </ p >
274
+ </ FormLabel >
275
+ < FormError />
276
+ </ FormItem >
277
+ ) }
278
+ />
245
279
</ div >
246
280
< div className = "flex flex-1 flex-row gap-2" >
247
281
< Modal . Close asChild >
0 commit comments