@pautena/react-design-system 0.1.4 → 0.3.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 (61) hide show
  1. package/dist/cjs/index.js +13 -4
  2. package/dist/cjs/index.js.map +1 -1
  3. package/dist/cjs/types/components/value-displays/index.d.ts +1 -0
  4. package/dist/cjs/types/components/value-displays/value-datetime/index.d.ts +1 -0
  5. package/dist/cjs/types/components/value-displays/value-datetime/value-datetime.d.ts +18 -0
  6. package/dist/cjs/types/generators/generators.mock.d.ts +9 -5
  7. package/dist/cjs/types/generators/generators.model.d.ts +25 -1
  8. package/dist/cjs/types/generators/model-router/index.d.ts +1 -0
  9. package/dist/cjs/types/generators/model-router/screens/add-screen.d.ts +1 -1
  10. package/dist/cjs/types/generators/model-router/screens/list-screen.d.ts +1 -1
  11. package/dist/cjs/types/generators/model-router/screens/screens.types.d.ts +20 -0
  12. package/dist/cjs/types/generators/model-router/screens/update-screen.d.ts +1 -1
  13. package/dist/cjs/types/index.d.ts +1 -0
  14. package/dist/esm/index.js +13 -4
  15. package/dist/esm/index.js.map +1 -1
  16. package/dist/esm/types/components/value-displays/index.d.ts +1 -0
  17. package/dist/esm/types/components/value-displays/value-datetime/index.d.ts +1 -0
  18. package/dist/esm/types/components/value-displays/value-datetime/value-datetime.d.ts +18 -0
  19. package/dist/esm/types/generators/generators.mock.d.ts +9 -5
  20. package/dist/esm/types/generators/generators.model.d.ts +25 -1
  21. package/dist/esm/types/generators/model-router/index.d.ts +1 -0
  22. package/dist/esm/types/generators/model-router/screens/add-screen.d.ts +1 -1
  23. package/dist/esm/types/generators/model-router/screens/list-screen.d.ts +1 -1
  24. package/dist/esm/types/generators/model-router/screens/screens.types.d.ts +20 -0
  25. package/dist/esm/types/generators/model-router/screens/update-screen.d.ts +1 -1
  26. package/dist/esm/types/index.d.ts +1 -0
  27. package/dist/index.d.ts +98 -4
  28. package/package.json +6 -2
  29. package/src/components/header/header.test.tsx +2 -12
  30. package/src/components/tab/tab-card/tab-card.tsx +2 -2
  31. package/src/components/table-list/table-list.test.tsx +8 -1
  32. package/src/components/table-list/table-list.tsx +3 -3
  33. package/src/components/value-displays/index.ts +1 -0
  34. package/src/components/value-displays/value-datetime/index.ts +1 -0
  35. package/src/components/value-displays/value-datetime/value-datetime.stories.tsx +21 -0
  36. package/src/components/value-displays/value-datetime/value-datetime.test.tsx +23 -0
  37. package/src/components/value-displays/value-datetime/value-datetime.tsx +40 -0
  38. package/src/components/value-displays/value-text/{value-test.test.tsx → value-text.test.tsx} +0 -0
  39. package/src/generators/generators.mock.ts +56 -17
  40. package/src/generators/generators.model.ts +39 -1
  41. package/src/generators/model-form/model-form.stories.tsx +2 -2
  42. package/src/generators/model-form/model-form.test.tsx +39 -22
  43. package/src/generators/model-form/model-form.tsx +220 -33
  44. package/src/generators/model-router/index.ts +1 -0
  45. package/src/generators/model-router/model-router.test.tsx +264 -57
  46. package/src/generators/model-router/model-router.tsx +4 -3
  47. package/src/generators/model-router/screens/add-screen.tsx +2 -1
  48. package/src/generators/model-router/screens/list-screen.tsx +41 -26
  49. package/src/generators/model-router/screens/screens.types.ts +25 -0
  50. package/src/generators/model-router/screens/update-screen.tsx +2 -1
  51. package/src/generators/model-router/stories/list-screen.stories.tsx +51 -0
  52. package/src/generators/model-router/stories/model-router.stories.tsx +66 -3
  53. package/src/generators/object-details/object-details.tsx +5 -4
  54. package/src/index.ts +1 -0
  55. package/src/layouts/app-bar-with-drawer-layout/app-bar-with-drawer-layout.stories.tsx +1 -1
  56. package/src/layouts/app-bar-with-drawer-layout/app-bar-with-drawer-layout.tsx +1 -1
  57. package/src/storybook.tsx +10 -0
  58. package/src/tests/actions.ts +43 -0
  59. package/src/tests/assertions.ts +70 -1
  60. package/src/tests/index.ts +1 -0
  61. package/src/tests/testing-library.tsx +5 -1
@@ -1,7 +1,10 @@
1
- import { Model, ModelField } from "./generators.model";
1
+ import { BasicModelInstance, Model, ModelField } from "./generators.model";
2
2
  import { faker } from "@faker-js/faker";
3
- import { BasicData } from "../components";
3
+ import { newArrayWithSize } from "../utils";
4
4
 
5
+ export const BirthDateFormat = "dd/MM/yyyy";
6
+ export const ReturnTimeFormat = "HH:mm";
7
+ export const TradeDateFormat = "dd/MM/yyyy HH:mm";
5
8
  export const mockModel: Model = {
6
9
  fields: [
7
10
  {
@@ -46,7 +49,8 @@ export const mockModel: Model = {
46
49
  },
47
50
  {
48
51
  id: "gender",
49
- type: "string",
52
+ type: "enum",
53
+ value: faker.definitions.name?.gender || [],
50
54
  description: "User gender",
51
55
  name: "Gender",
52
56
  xs: 12,
@@ -65,23 +69,27 @@ export const mockModel: Model = {
65
69
  },
66
70
  {
67
71
  id: "birthDate",
68
- type: "string",
72
+ type: "date",
73
+ format: BirthDateFormat,
74
+ default: new Date(2014, 8, 18),
69
75
  description: "When he was born",
70
76
  name: "Birth Date",
71
77
  xs: 12,
72
78
  sm: 6,
73
79
  md: 6,
74
- listable: true,
80
+ listable: false,
75
81
  },
76
82
  {
77
83
  id: "car",
78
84
  type: "group",
79
85
  description: "Information about the user car",
80
86
  name: "User car",
87
+ xs: 12,
81
88
  value: [
82
89
  {
83
90
  id: "model",
84
- type: "string",
91
+ type: "enum",
92
+ value: faker.definitions.vehicle?.model || [],
85
93
  description: "Lorem ipsum",
86
94
  name: "Model",
87
95
  xs: 12,
@@ -89,7 +97,8 @@ export const mockModel: Model = {
89
97
  },
90
98
  {
91
99
  id: "manufacturer",
92
- type: "string",
100
+ type: "enum",
101
+ value: faker.definitions.vehicle?.manufacturer || [],
93
102
  description: "Lorem ipsum",
94
103
  name: "Manufacturer",
95
104
  xs: 12,
@@ -105,7 +114,8 @@ export const mockModel: Model = {
105
114
  },
106
115
  {
107
116
  id: "type",
108
- type: "string",
117
+ type: "multienum",
118
+ value: faker.definitions.vehicle?.type || [],
109
119
  description: "Lorem ipsum",
110
120
  name: "Type",
111
121
  xs: 12,
@@ -127,6 +137,16 @@ export const mockModel: Model = {
127
137
  xs: 12,
128
138
  sm: 4,
129
139
  },
140
+ {
141
+ id: "returnTime",
142
+ type: "time",
143
+ format: ReturnTimeFormat,
144
+ default: new Date(1970, 0, 1, 9, 0),
145
+ description: "Lorem ipsum",
146
+ name: "Return time",
147
+ xs: 12,
148
+ sm: 4,
149
+ },
130
150
  ],
131
151
  },
132
152
  {
@@ -156,11 +176,13 @@ export const mockModel: Model = {
156
176
  },
157
177
  {
158
178
  id: "tradeDate",
159
- type: "string",
179
+ type: "datetime",
180
+ format: TradeDateFormat,
181
+ default: new Date(2022, 8, 12, 9, 0),
160
182
  description: "Lorem ipsum",
161
183
  name: "Trade date",
162
184
  xs: 12,
163
- sm: 3,
185
+ sm: 5,
164
186
  },
165
187
  ],
166
188
  };
@@ -172,19 +194,20 @@ export interface MockInstance {
172
194
  lastName: string;
173
195
  gender: string;
174
196
  age: number;
175
- birthDate: string;
197
+ birthDate: Date;
176
198
  car: {
177
199
  model: string;
178
200
  manufacturer: string;
179
201
  color: string;
180
- type: string;
202
+ type: string[];
181
203
  vin: string;
182
204
  vrm: string;
205
+ returnTime: Date;
183
206
  };
184
207
  quantity: number;
185
208
  available: boolean;
186
209
  currency: string;
187
- tradeDate: string;
210
+ tradeDate: Date;
188
211
  }
189
212
 
190
213
  const mockFieldValue = {
@@ -194,20 +217,36 @@ const mockFieldValue = {
194
217
  lastName: faker.name.lastName,
195
218
  gender: faker.name.gender,
196
219
  age: () => faker.datatype.number({ min: 20, max: 60 }),
197
- birthDate: () => faker.datatype.datetime().toString(),
220
+ birthDate: () => {
221
+ const date = faker.date.recent();
222
+ return new Date(date.getFullYear(), date.getMonth(), date.getDate());
223
+ },
224
+ returnTime: () => {
225
+ const date = faker.date.recent();
226
+ const time = new Date();
227
+ time.setHours(date.getHours());
228
+ time.setMinutes(date.getMinutes());
229
+ time.setSeconds(0);
230
+ time.setMilliseconds(0);
231
+ return time;
232
+ },
198
233
  model: faker.vehicle.model,
199
234
  manufacturer: faker.vehicle.manufacturer,
200
235
  color: faker.vehicle.color,
201
- type: faker.vehicle.type,
236
+ type: () => {
237
+ const array = newArrayWithSize(faker.datatype.number({ min: 2, max: 5 }), 0);
238
+ const result = array.map(() => faker.vehicle.type());
239
+ return [...new Set(result)];
240
+ },
202
241
  vin: faker.vehicle.vin,
203
242
  vrm: faker.vehicle.vrm,
204
243
  quantity: () => faker.datatype.number({ min: 1, max: 9 }),
205
244
  available: faker.datatype.boolean,
206
245
  currency: () => "MXN",
207
- tradeDate: () => "Thu Jul 21 2022 22:44:10 GMT+0200 (Central European Summer Time)",
246
+ tradeDate: faker.date.recent,
208
247
  };
209
248
 
210
- export const createModelInstance = <T extends BasicData>(model: Model, seed = 100): T => {
249
+ export const createModelInstance = <T extends BasicModelInstance>(model: Model, seed = 100): T => {
211
250
  faker.seed(seed);
212
251
  const obj = {};
213
252
 
@@ -25,7 +25,43 @@ type BooleanField = {
25
25
  type: "boolean";
26
26
  };
27
27
 
28
- type SingleFields = StringField | NumberField | BooleanField;
28
+ type EnumField = {
29
+ type: "enum";
30
+ value: string[];
31
+ };
32
+
33
+ type MultiEnumField = {
34
+ type: "multienum";
35
+ value: string[];
36
+ };
37
+
38
+ type DateField = {
39
+ type: "date";
40
+ format: string;
41
+ default: any;
42
+ };
43
+
44
+ type TimeField = {
45
+ type: "time";
46
+ format: string;
47
+ default: any;
48
+ };
49
+
50
+ type DatetimeField = {
51
+ type: "datetime";
52
+ format: string;
53
+ default: any;
54
+ };
55
+
56
+ type SingleFields =
57
+ | StringField
58
+ | NumberField
59
+ | BooleanField
60
+ | EnumField
61
+ | MultiEnumField
62
+ | DateField
63
+ | TimeField
64
+ | DatetimeField;
29
65
 
30
66
  export type GroupField = {
31
67
  type: "group";
@@ -44,3 +80,5 @@ export interface BasicModelInstance {
44
80
  id: string;
45
81
  [key: string]: any;
46
82
  }
83
+
84
+ export type ModelFieldTypes = "string" | "number" | "boolean" | "enum" | "multienum";
@@ -1,6 +1,6 @@
1
1
  import { ComponentMeta } from "@storybook/react";
2
2
  import { ModelForm } from "./model-form";
3
- import { createTemplate, withPadding } from "../../storybook";
3
+ import { createTemplate, withPadding, withLocalizationProvider } from "../../storybook";
4
4
  import { createModelInstance, mockModel } from "../generators.mock";
5
5
 
6
6
  const initialValues = createModelInstance(mockModel);
@@ -8,7 +8,7 @@ const initialValues = createModelInstance(mockModel);
8
8
  export default {
9
9
  title: "Generators/ModelForm",
10
10
  component: ModelForm,
11
- decorators: [withPadding(2)],
11
+ decorators: [withPadding(2), withLocalizationProvider],
12
12
  parameters: {
13
13
  layout: "fullscreen",
14
14
  },
@@ -5,8 +5,19 @@ import {
5
5
  expectModelFieldInputValue,
6
6
  render,
7
7
  screen,
8
+ selectOption,
9
+ selectOptions,
10
+ pickDatetime,
11
+ expectToHaveBeenCalledOnceWithMockInstance,
8
12
  } from "../../tests";
9
- import { createModelInstance, MockInstance, mockModel } from "../generators.mock";
13
+ import {
14
+ BirthDateFormat,
15
+ createModelInstance,
16
+ MockInstance,
17
+ mockModel,
18
+ ReturnTimeFormat,
19
+ TradeDateFormat,
20
+ } from "../generators.mock";
10
21
  import userEvent from "@testing-library/user-event";
11
22
 
12
23
  describe("ModelForm", () => {
@@ -47,54 +58,60 @@ describe("ModelForm", () => {
47
58
 
48
59
  it("would call onSubmit if I fullfill all inputs and press the submit button", async () => {
49
60
  const { onSubmit } = renderComponent();
61
+ const birthDate = new Date(2047, 11, 26);
62
+ const returnTime = new Date(1970, 0, 1, 10, 12);
63
+ const tradeDate = new Date(2047, 11, 26, 12, 50);
50
64
 
51
65
  await userEvent.type(screen.getByRole("textbox", { name: "Id" }), "Id-1");
52
66
  await userEvent.type(screen.getByRole("textbox", { name: /first name/i }), "Karianne");
53
67
  await userEvent.type(screen.getByRole("textbox", { name: /middle name/i }), "Noah");
54
68
  await userEvent.type(screen.getByRole("textbox", { name: /last name/i }), "Gorczany");
55
- await userEvent.type(screen.getByRole("textbox", { name: /gender/i }), "Cis Man");
69
+ await selectOption(screen.getByRole("button", { name: /gender/i }), "Cis Man");
56
70
  await userEvent.type(screen.getByRole("spinbutton", { name: /age/i }), "37");
57
- await userEvent.type(
58
- screen.getByRole("textbox", { name: /birth date/i }),
59
- "Tue Nov 26 2047 12:14:19",
60
- );
61
- await userEvent.type(screen.getByRole("textbox", { name: /model/i }), "Spyder");
62
- await userEvent.type(screen.getByRole("textbox", { name: /manufacturer/i }), "Bugatti");
71
+ pickDatetime(screen.getByRole("textbox", { name: /birth date/i }), birthDate, BirthDateFormat);
72
+ await selectOption(screen.getByRole("button", { name: /model/i }), "Spyder");
73
+ await selectOption(screen.getByRole("button", { name: /manufacturer/i }), "Bugatti");
63
74
  await userEvent.type(screen.getByRole("textbox", { name: /color/i }), "red");
64
- await userEvent.type(screen.getByRole("textbox", { name: /type/i }), "Convertible");
75
+ await selectOptions(screen.getByRole("button", { name: /type/i }), [
76
+ "Coupe",
77
+ "Hatchback",
78
+ "Minivan",
79
+ ]);
65
80
  await userEvent.type(screen.getByRole("textbox", { name: /vin/i }), "46N6UE4VJ2XL28828");
66
81
  await userEvent.type(screen.getByRole("textbox", { name: /vrm/i }), "NE51AFH");
82
+ pickDatetime(
83
+ screen.getByRole("textbox", { name: /return time/i }),
84
+ returnTime,
85
+ ReturnTimeFormat,
86
+ );
67
87
  await userEvent.type(screen.getByRole("spinbutton", { name: /q/i }), "9");
68
- await userEvent.type(screen.getByRole("textbox", { name: /available/i }), "true");
88
+ await userEvent.click(screen.getByRole("checkbox", { name: /available/i }));
69
89
  await userEvent.type(screen.getByRole("textbox", { name: /currency/i }), "mxn");
70
- await userEvent.type(
71
- screen.getByRole("textbox", { name: /trade date/i }),
72
- "Thu Jul 21 2022 22:44:10",
73
- );
90
+ pickDatetime(screen.getByRole("textbox", { name: /trade date/i }), tradeDate, TradeDateFormat);
74
91
 
75
92
  await userEvent.click(screen.getByRole("button", { name: /save/i }));
76
93
 
77
- expect(onSubmit).toHaveBeenCalledTimes(1);
78
- expect(onSubmit).toHaveBeenCalledWith({
94
+ expectToHaveBeenCalledOnceWithMockInstance(onSubmit, {
79
95
  id: "Id-1",
80
96
  firstName: "Karianne",
81
97
  middleName: "Noah",
82
98
  lastName: "Gorczany",
83
99
  gender: "Cis Man",
84
- age: "37",
85
- birthDate: "Tue Nov 26 2047 12:14:19",
100
+ age: 37,
101
+ birthDate,
86
102
  car: {
87
103
  model: "Spyder",
88
104
  manufacturer: "Bugatti",
89
105
  color: "red",
90
- type: "Convertible",
106
+ type: ["Coupe", "Hatchback", "Minivan"],
91
107
  vin: "46N6UE4VJ2XL28828",
92
108
  vrm: "NE51AFH",
109
+ returnTime,
93
110
  },
94
- quantity: "9",
95
- available: "true",
111
+ quantity: 9,
112
+ available: true,
96
113
  currency: "mxn",
97
- tradeDate: "Thu Jul 21 2022 22:44:10",
114
+ tradeDate,
98
115
  });
99
116
  });
100
117
  });
@@ -1,8 +1,69 @@
1
- import { Box, Button, Grid, Paper, TextField, Typography } from "@mui/material";
2
- import React, { ChangeEvent, FormEvent } from "react";
1
+ import {
2
+ Box,
3
+ Button,
4
+ Checkbox,
5
+ FormControl,
6
+ FormControlLabel,
7
+ Grid,
8
+ InputLabel,
9
+ ListItemText,
10
+ MenuItem,
11
+ Paper,
12
+ Select,
13
+ SelectChangeEvent,
14
+ TextField,
15
+ Typography,
16
+ } from "@mui/material";
17
+ import { DesktopDatePicker, TimePicker, DateTimePicker } from "@mui/x-date-pickers";
18
+ import React, { ChangeEvent, FormEvent, ReactElement, useMemo } from "react";
3
19
  import { useState } from "react";
4
20
  import { useGetDefaultThemeColor } from "../../utils/theme";
5
- import { Model, ModelField, BasicModelInstance } from "../generators.model";
21
+ import { Model, ModelField, BasicModelInstance, ModelFieldTypes } from "../generators.model";
22
+
23
+ const InitialStateZeroValue: Record<string, any> = {
24
+ string: undefined,
25
+ number: undefined,
26
+ boolean: false,
27
+ enum: "",
28
+ multienum: [],
29
+ date: "01/01/1970",
30
+ group: {},
31
+ };
32
+
33
+ const getFieldInitialState = <T extends BasicModelInstance>(
34
+ field: ModelField,
35
+ initialValues: T | undefined,
36
+ ) => {
37
+ return initialValues ? initialValues[field.id] : InitialStateZeroValue[field.type];
38
+ };
39
+
40
+ const getValuesInitialState = <T extends BasicModelInstance>(
41
+ model: Model,
42
+ initialValues: T | undefined,
43
+ ): T => {
44
+ const obj = {} as any;
45
+
46
+ model.fields.forEach((field) => {
47
+ let value: any;
48
+ if (field.type === "group") {
49
+ value = {};
50
+ field.value.forEach((groupField) => {
51
+ value[groupField.id] = getFieldInitialState(
52
+ groupField,
53
+ initialValues && initialValues[field.id],
54
+ );
55
+ });
56
+ } else if (field.type === "date" || field.type === "time") {
57
+ value = (initialValues && initialValues[field.id]) || field.default;
58
+ } else {
59
+ value = getFieldInitialState(field, initialValues);
60
+ }
61
+
62
+ obj[field.id] = value;
63
+ });
64
+
65
+ return obj;
66
+ };
6
67
 
7
68
  export interface ModelFormProps<T extends BasicModelInstance> {
8
69
  model: Model;
@@ -17,28 +78,63 @@ export const ModelForm = <T extends BasicModelInstance>({
17
78
  onSubmit,
18
79
  initialValues,
19
80
  }: ModelFormProps<T>) => {
20
- const [values, setValues] = useState<T>(initialValues || ({} as T));
21
-
22
- const handleInputChange = (e: ChangeEvent<any>, key: string | undefined) => {
23
- e.preventDefault();
24
-
25
- e.target;
81
+ const valuesInitialState = useMemo(
82
+ () => getValuesInitialState<T>(model, initialValues),
83
+ [model, initialValues],
84
+ );
85
+ const [values, setValues] = useState<T>(valuesInitialState);
26
86
 
87
+ const setKeyValue = (name: string, key: string | undefined, value: any) => {
27
88
  setValues((v) => {
28
89
  const n: Record<string, object> = {};
29
90
  if (key) {
30
91
  n[key] = {
31
92
  ...v[key],
32
- [e.target.name]: e.target.value,
93
+ [name]: value,
33
94
  };
34
95
  } else {
35
- n[e.target.name] = e.target.value;
96
+ n[name] = value;
36
97
  }
37
98
 
38
99
  return { ...v, ...n };
39
100
  });
40
101
  };
41
102
 
103
+ const handleCheckboxChange = (e: ChangeEvent<any>, key: string | undefined) => {
104
+ e.preventDefault();
105
+ setKeyValue(e.target.name, key, e.target.checked);
106
+ };
107
+
108
+ const handleSelectChange = (e: SelectChangeEvent<any>, key: string | undefined) => {
109
+ e.preventDefault();
110
+ setKeyValue(e.target.name, key, e.target.value);
111
+ };
112
+
113
+ const handleMultiSelectChange = (e: SelectChangeEvent<any>, key: string | undefined) => {
114
+ e.preventDefault();
115
+ const { value } = e.target;
116
+ const newValue = typeof value === "string" ? value.split(",") : value;
117
+ setKeyValue(e.target.name, key, newValue);
118
+ };
119
+
120
+ const handleInputChange = (
121
+ e: ChangeEvent<any>,
122
+ key: string | undefined,
123
+ type: ModelFieldTypes,
124
+ ) => {
125
+ e.preventDefault();
126
+
127
+ let value = e.target.value;
128
+ if (type === "number") {
129
+ value = parseInt(e.target.value);
130
+ }
131
+ setKeyValue(e.target.name, key, value);
132
+ };
133
+
134
+ const handleDateChange = (value: any, key: string | undefined, id: string) => {
135
+ setKeyValue(id, key, value);
136
+ };
137
+
42
138
  const handleSubmit = (e: FormEvent<HTMLFormElement>) => {
43
139
  e.preventDefault();
44
140
  onSubmit(values);
@@ -48,28 +144,113 @@ export const ModelForm = <T extends BasicModelInstance>({
48
144
  const defaultColor = useGetDefaultThemeColor({ lightWeight: 200, darkWeight: 800 });
49
145
 
50
146
  const { id, type, name, description, xs, sm, md, lg, xl } = field;
147
+
148
+ let fieldInput: ReactElement;
149
+ const value = key ? values[key][id] : values[id];
51
150
  if (type === "group") {
52
- return (
53
- <Grid item key={id} xs={xs} sm={sm} md={md} lg={lg} xl={xl}>
54
- <Paper>
55
- <Box bgcolor={defaultColor} px={2} py={1} mb={2}>
56
- <Typography variant="h6" role="heading" aria-level={1}>
57
- {name}
58
- </Typography>
59
- <Typography variant="body2" role="heading" aria-level={2}>
60
- {description}
61
- </Typography>
62
- </Box>
63
- <Grid container spacing={2} sx={{ p: 2 }}>
64
- {field.value.map((f) => renderField(f, id))}
65
- </Grid>
66
- </Paper>
67
- </Grid>
151
+ fieldInput = (
152
+ <Paper>
153
+ <Box bgcolor={defaultColor} px={2} py={1} mb={2}>
154
+ <Typography variant="h6" role="heading" aria-level={1}>
155
+ {name}
156
+ </Typography>
157
+ <Typography variant="body2" role="heading" aria-level={2}>
158
+ {description}
159
+ </Typography>
160
+ </Box>
161
+ <Grid container spacing={2} sx={{ p: 2 }}>
162
+ {field.value.map((f) => renderField(f, id))}
163
+ </Grid>
164
+ </Paper>
68
165
  );
69
- }
70
-
71
- return (
72
- <Grid item key={id} xs={xs} sm={sm} md={md} lg={lg} xl={xl}>
166
+ } else if (type === "boolean") {
167
+ fieldInput = (
168
+ <Box sx={{ height: 1, display: "flex", alignItems: "center" }}>
169
+ <FormControlLabel
170
+ control={
171
+ <Checkbox name={id} onChange={(e) => handleCheckboxChange(e, key)} checked={value} />
172
+ }
173
+ label={name}
174
+ />
175
+ </Box>
176
+ );
177
+ } else if (type === "enum") {
178
+ fieldInput = (
179
+ <FormControl fullWidth>
180
+ <InputLabel id={`${id}-select-label`}>{name}</InputLabel>
181
+ <Select
182
+ labelId={`${id}-select-label`}
183
+ id={`${id}-select`}
184
+ value={value}
185
+ label={name}
186
+ name={id}
187
+ onChange={(e) => handleSelectChange(e, key)}
188
+ required
189
+ >
190
+ {field.value.map((fieldValue) => (
191
+ <MenuItem key={fieldValue} value={fieldValue}>
192
+ {fieldValue}
193
+ </MenuItem>
194
+ ))}
195
+ </Select>
196
+ </FormControl>
197
+ );
198
+ } else if (type === "multienum") {
199
+ fieldInput = (
200
+ <FormControl fullWidth>
201
+ <InputLabel id={`${id}-select-label`}>{name}</InputLabel>
202
+ <Select
203
+ labelId={`${id}-select-label`}
204
+ id={`${id}-select`}
205
+ value={value || []}
206
+ renderValue={(selected) => selected.join(", ")}
207
+ label={name}
208
+ name={id}
209
+ onChange={(e) => handleMultiSelectChange(e, key)}
210
+ required
211
+ multiple
212
+ >
213
+ {field.value.map((fieldValue) => (
214
+ <MenuItem key={fieldValue} value={fieldValue}>
215
+ <Checkbox checked={(value || []).includes(fieldValue)} />
216
+ <ListItemText primary={fieldValue} />
217
+ </MenuItem>
218
+ ))}
219
+ </Select>
220
+ </FormControl>
221
+ );
222
+ } else if (type === "date") {
223
+ fieldInput = (
224
+ <DesktopDatePicker
225
+ label={name}
226
+ inputFormat={field.format}
227
+ value={value}
228
+ onChange={(value) => handleDateChange(value, key, id)}
229
+ renderInput={(params: any) => <TextField {...params} />}
230
+ />
231
+ );
232
+ } else if (type === "time") {
233
+ fieldInput = (
234
+ <TimePicker
235
+ label={name}
236
+ inputFormat={field.format}
237
+ value={value}
238
+ onChange={(value) => handleDateChange(value, key, id)}
239
+ renderInput={(params: any) => <TextField {...params} />}
240
+ />
241
+ );
242
+ } else if (type === "datetime") {
243
+ fieldInput = (
244
+ <DateTimePicker
245
+ label={name}
246
+ inputFormat={field.format}
247
+ value={value}
248
+ onChange={(value) => handleDateChange(value, key, id)}
249
+ renderInput={(params: any) => <TextField {...params} />}
250
+ />
251
+ );
252
+ } else {
253
+ fieldInput = (
73
254
  <TextField
74
255
  required
75
256
  type={type}
@@ -77,9 +258,15 @@ export const ModelForm = <T extends BasicModelInstance>({
77
258
  name={id}
78
259
  variant="outlined"
79
260
  fullWidth
80
- value={key && key in values ? values[key][id] : values[id]}
81
- onChange={(e) => handleInputChange(e, key)}
261
+ value={value}
262
+ onChange={(e) => handleInputChange(e, key, type)}
82
263
  />
264
+ );
265
+ }
266
+
267
+ return (
268
+ <Grid item key={id} xs={xs} sm={sm} md={md} lg={lg} xl={xl}>
269
+ {fieldInput}
83
270
  </Grid>
84
271
  );
85
272
  };
@@ -1 +1,2 @@
1
1
  export * from "./model-router";
2
+ export * from "./model-router.types";