@zauru-sdk/components 1.0.98 → 1.0.100
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.
- package/CHANGELOG.md +16 -0
- package/dist/Form/Checkbox/index.d.ts +1 -3
- package/dist/Form/DatePicker/index.d.ts +1 -3
- package/dist/Form/FileUpload/index.d.ts +1 -2
- package/dist/Form/ReactZodForm/index.d.ts +12 -0
- package/dist/Form/SelectField/index.d.ts +6 -9
- package/dist/Form/TextArea/index.d.ts +1 -3
- package/dist/Form/TextField/index.d.ts +1 -3
- package/dist/Form/TimePicker/index.d.ts +1 -2
- package/dist/Form/YesNo/index.d.ts +1 -0
- package/dist/Form/index.d.ts +1 -2
- package/dist/Layouts/homeLayout/index.d.ts +3 -1
- package/dist/Modal/Modal.d.ts +1 -1
- package/dist/Zendesk/zendesk.config.d.ts +1 -1
- package/dist/cjs/Alerts/StaticAlert.js +0 -6
- package/dist/cjs/Buttons/Button.js +13 -2
- package/dist/cjs/DynamicTable/DynamicPrintTable.js +2 -2
- package/dist/cjs/DynamicTable/DynamicTable.js +3 -3
- package/dist/cjs/DynamicTable/GenericDynamicTable.js +4 -5
- package/dist/cjs/Footer/Footer.js +1 -1
- package/dist/cjs/Form/Checkbox/index.js +14 -14
- package/dist/cjs/Form/Checklist/index.js +1 -1
- package/dist/cjs/Form/DatePicker/index.js +14 -13
- package/dist/cjs/Form/DynamicBaculoForm/index.js +1 -1
- package/dist/cjs/Form/FileUpload/index.js +25 -13
- package/dist/cjs/Form/ReactZodForm/index.js +31 -0
- package/dist/cjs/Form/SelectField/index.js +118 -73
- package/dist/cjs/Form/TextArea/index.js +15 -15
- package/dist/cjs/Form/TextField/index.js +20 -16
- package/dist/cjs/Form/TimePicker/index.js +17 -15
- package/dist/cjs/Form/YesNo/index.js +12 -6
- package/dist/cjs/Form/index.js +1 -2
- package/dist/cjs/Layouts/homeLayout/index.js +45 -8
- package/dist/cjs/Modal/Modal.js +1 -2
- package/dist/cjs/NavBar/NavBar.js +12 -17
- package/dist/cjs/Table/ZauruTable.js +11 -4
- package/dist/cjs/WithTooltip/WithTooltip.js +1 -1
- package/dist/cjs/Zendesk/zendesk.config.js +7 -9
- package/dist/esm/Alerts/StaticAlert.js +0 -6
- package/dist/esm/Buttons/Button.js +13 -2
- package/dist/esm/DynamicTable/DynamicPrintTable.js +4 -4
- package/dist/esm/DynamicTable/DynamicTable.js +6 -6
- package/dist/esm/DynamicTable/GenericDynamicTable.js +7 -8
- package/dist/esm/Footer/Footer.js +1 -1
- package/dist/esm/Form/Checkbox/index.js +13 -12
- package/dist/esm/Form/Checklist/index.js +2 -2
- package/dist/esm/Form/DatePicker/index.js +13 -11
- package/dist/esm/Form/DynamicBaculoForm/index.js +2 -2
- package/dist/esm/Form/FileUpload/index.js +24 -11
- package/dist/esm/Form/ReactZodForm/index.js +27 -0
- package/dist/esm/Form/SelectField/index.js +118 -49
- package/dist/esm/Form/TextArea/index.js +14 -13
- package/dist/esm/Form/TextField/index.js +19 -14
- package/dist/esm/Form/TimePicker/index.js +16 -13
- package/dist/esm/Form/YesNo/index.js +12 -6
- package/dist/esm/Form/index.js +1 -2
- package/dist/esm/Layouts/homeLayout/index.js +46 -9
- package/dist/esm/Modal/Modal.js +1 -2
- package/dist/esm/NavBar/NavBar.js +12 -17
- package/dist/esm/Table/ZauruTable.js +11 -4
- package/dist/esm/WithTooltip/WithTooltip.js +2 -2
- package/dist/esm/Zendesk/zendesk.config.js +7 -6
- package/package.json +9 -6
- package/src/Alerts/StaticAlert.tsx +0 -10
- package/src/Buttons/Button.tsx +24 -4
- package/src/DynamicTable/DynamicPrintTable.tsx +5 -6
- package/src/DynamicTable/DynamicTable.tsx +7 -7
- package/src/DynamicTable/GenericDynamicTable.tsx +7 -8
- package/src/Footer/Footer.tsx +1 -1
- package/src/Form/Checkbox/index.tsx +21 -18
- package/src/Form/Checklist/index.tsx +2 -2
- package/src/Form/DatePicker/index.tsx +22 -19
- package/src/Form/DynamicBaculoForm/index.tsx +2 -2
- package/src/Form/FileUpload/index.tsx +29 -14
- package/src/Form/ReactZodForm/index.tsx +60 -0
- package/src/Form/SelectField/index.tsx +246 -130
- package/src/Form/TextArea/index.tsx +22 -19
- package/src/Form/TextField/index.tsx +25 -18
- package/src/Form/TimePicker/index.tsx +25 -18
- package/src/Form/YesNo/index.tsx +20 -7
- package/src/Form/index.ts +1 -2
- package/src/Layouts/homeLayout/index.tsx +114 -21
- package/src/Modal/Modal.tsx +2 -5
- package/src/NavBar/NavBar.tsx +35 -46
- package/src/Table/ZauruTable.tsx +11 -4
- package/src/WithTooltip/WithTooltip.tsx +8 -7
- package/src/Zendesk/zendesk.config.ts +8 -6
- package/dist/Form/FormLayout/index.d.ts +0 -11
- package/dist/Form/RadioButtonGroup/index.d.ts +0 -20
- package/dist/cjs/Form/FormLayout/index.js +0 -11
- package/dist/cjs/Form/RadioButtonGroup/index.js +0 -26
- package/dist/esm/Form/FormLayout/index.js +0 -7
- package/dist/esm/Form/RadioButtonGroup/index.js +0 -21
- package/src/Form/FormLayout/index.tsx +0 -37
- package/src/Form/RadioButtonGroup/index.tsx +0 -108
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import jwt from "jsonwebtoken";
|
|
1
|
+
//import jwt from "jsonwebtoken";
|
|
2
2
|
export function zendeskJwt(current_user, configuration) {
|
|
3
3
|
// get the INFO
|
|
4
4
|
const jwtSecret = configuration.zendeskJWTSecret;
|
|
@@ -16,9 +16,10 @@ export function zendeskJwt(current_user, configuration) {
|
|
|
16
16
|
scope: "user",
|
|
17
17
|
exp: expiresIn,
|
|
18
18
|
};
|
|
19
|
-
const jwtHeader = { kid: jwtKey, typ: "JWT", alg: "HS256" };
|
|
20
|
-
return jwt.sign(payload, jwtSecret, {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
});
|
|
19
|
+
// const jwtHeader: jwt.JwtHeader = { kid: jwtKey, typ: "JWT", alg: "HS256" };
|
|
20
|
+
// return jwt.sign(payload, jwtSecret, {
|
|
21
|
+
// algorithm: "HS256",
|
|
22
|
+
// header: jwtHeader,
|
|
23
|
+
// });
|
|
24
|
+
return {};
|
|
24
25
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zauru-sdk/components",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.100",
|
|
4
4
|
"description": "Componentes reutilizables en las WebApps de Zauru.",
|
|
5
5
|
"main": "./dist/cjs/index.js",
|
|
6
6
|
"module": "./dist/esm/index.js",
|
|
@@ -31,21 +31,24 @@
|
|
|
31
31
|
"typescript": "^5.1.6"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
+
"@hookform/resolvers": "^3.9.0",
|
|
34
35
|
"@reduxjs/toolkit": "^2.2.1",
|
|
35
36
|
"@remix-run/react": "^2.8.1",
|
|
36
|
-
"@zauru-sdk/common": "^1.0.
|
|
37
|
-
"@zauru-sdk/hooks": "^1.0.
|
|
37
|
+
"@zauru-sdk/common": "^1.0.99",
|
|
38
|
+
"@zauru-sdk/hooks": "^1.0.99",
|
|
38
39
|
"@zauru-sdk/icons": "^1.0.60",
|
|
39
40
|
"@zauru-sdk/types": "^1.0.98",
|
|
40
|
-
"@zauru-sdk/utils": "^1.0.
|
|
41
|
+
"@zauru-sdk/utils": "^1.0.99",
|
|
41
42
|
"framer-motion": "^11.0.8",
|
|
42
43
|
"jsonwebtoken": "^9.0.2",
|
|
43
44
|
"react": "^18.2.0",
|
|
44
45
|
"react-data-table-component": "^7.6.2",
|
|
45
46
|
"react-dom": "^18.2.0",
|
|
47
|
+
"react-hook-form": "^7.53.0",
|
|
46
48
|
"react-is": "^18.2.0",
|
|
47
49
|
"react-select": "^5.8.0",
|
|
48
|
-
"styled-components": "^5.3.5"
|
|
50
|
+
"styled-components": "^5.3.5",
|
|
51
|
+
"zod": "^3.23.8"
|
|
49
52
|
},
|
|
50
|
-
"gitHead": "
|
|
53
|
+
"gitHead": "c1abff96d35de414e81db8d1cff843e430d06ff7"
|
|
51
54
|
}
|
|
@@ -33,16 +33,6 @@ const getConfig = (type: string) => {
|
|
|
33
33
|
<path d="M8.445 12.6675A.9.9 0 0 0 7.1424 13.91l2.5726 2.7448c.3679.3856.9884.3689 1.335-.036l5.591-7.0366a.9.9 0 0 0-1.3674-1.1705l-4.6548 5.9132a.4.4 0 0 1-.607.0252l-1.567-1.6826zM1.9995 12c0-5.5 4.5-10 10-10s10 4.5 10 10-4.5 10-10 10-10-4.5-10-10z"></path>
|
|
34
34
|
),
|
|
35
35
|
};
|
|
36
|
-
case "warning":
|
|
37
|
-
return {
|
|
38
|
-
containerClassName:
|
|
39
|
-
"text-yellow-900 bg-yellow-100 border border-yellow-200 rounded-md",
|
|
40
|
-
buttonClassName:
|
|
41
|
-
"rounded-md focus:outline-none focus:ring-2 focus:ring-yellow-500",
|
|
42
|
-
path: (
|
|
43
|
-
<path d="M12 2C6.5 2 2 6.5 2 12s4.5 10 10 10 10-4.5 10-10S17.5 2 12 2M12 18a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3zm0-9a1 1 0 0 1 1 1v4a1 1 0 0 1-2 0v-4a1 1 0 0 1 1-1z" />
|
|
44
|
-
),
|
|
45
|
-
};
|
|
46
36
|
default:
|
|
47
37
|
return {
|
|
48
38
|
containerClassName:
|
package/src/Buttons/Button.tsx
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import type { ColorInterface } from "../NavBar/NavBar.types.js";
|
|
2
|
+
import { useFormContext } from "react-hook-form";
|
|
3
|
+
import { WithTooltip } from "../index.js";
|
|
2
4
|
|
|
3
5
|
type Props = {
|
|
4
6
|
type?: "reset" | "button" | "submit" | undefined;
|
|
@@ -28,6 +30,10 @@ export const Button = (props: Props) => {
|
|
|
28
30
|
disabled = false,
|
|
29
31
|
} = props;
|
|
30
32
|
|
|
33
|
+
const formContext = useFormContext();
|
|
34
|
+
const formHasErrors = formContext ? !formContext.formState.isValid : false;
|
|
35
|
+
const formErrors = formContext ? formContext.formState.errors : {};
|
|
36
|
+
|
|
31
37
|
const COLORS = {
|
|
32
38
|
green: {
|
|
33
39
|
bg900: "bg-green-900",
|
|
@@ -67,17 +73,25 @@ export const Button = (props: Props) => {
|
|
|
67
73
|
|
|
68
74
|
const inside = children ?? title;
|
|
69
75
|
|
|
70
|
-
|
|
76
|
+
const errorMessage = formHasErrors
|
|
77
|
+
? Object.values(formErrors)
|
|
78
|
+
.map((error) => error?.message?.toString())
|
|
79
|
+
.join(", ")
|
|
80
|
+
: "";
|
|
81
|
+
|
|
82
|
+
const buttonContent = (
|
|
71
83
|
<button
|
|
72
84
|
type={type}
|
|
73
85
|
name="action"
|
|
74
|
-
disabled={loading || disabled}
|
|
86
|
+
disabled={loading || disabled || formHasErrors}
|
|
75
87
|
value={name}
|
|
76
88
|
onClick={onClickSave}
|
|
77
|
-
className={`ml-2 ${
|
|
89
|
+
className={`ml-2 ${
|
|
90
|
+
loading || disabled || formHasErrors ? " bg-opacity-25 " : ""
|
|
91
|
+
} ${
|
|
78
92
|
loading
|
|
79
93
|
? " cursor-progress"
|
|
80
|
-
: `${disabled ? "" : `hover:${color.bg700}`}`
|
|
94
|
+
: `${disabled || formHasErrors ? "" : `hover:${color.bg700}`}`
|
|
81
95
|
} inline-flex justify-center rounded-md border border-transparent ${
|
|
82
96
|
color.bg600
|
|
83
97
|
} py-2 px-4 text-sm font-medium text-white shadow-sm focus:outline-none focus:ring-2 focus:${
|
|
@@ -87,4 +101,10 @@ export const Button = (props: Props) => {
|
|
|
87
101
|
{loading ? loadingText : inside}
|
|
88
102
|
</button>
|
|
89
103
|
);
|
|
104
|
+
|
|
105
|
+
return formHasErrors ? (
|
|
106
|
+
<WithTooltip text={errorMessage}>{buttonContent}</WithTooltip>
|
|
107
|
+
) : (
|
|
108
|
+
buttonContent
|
|
109
|
+
);
|
|
90
110
|
};
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import React, { useEffect, useCallback, useState, type ReactNode } from "react";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import type { SingleValue } from "react-select";
|
|
2
|
+
import { TextField } from "../Form/TextField/index.js";
|
|
3
|
+
import { SelectField } from "../Form/SelectField/index.js";
|
|
5
4
|
import { useAppSelector } from "@zauru-sdk/redux";
|
|
6
5
|
import { SelectFieldOption } from "@zauru-sdk/types";
|
|
7
6
|
|
|
@@ -43,11 +42,11 @@ export const DynamicPrintTable = ({ forwardedRef, ...props }: Props) => {
|
|
|
43
42
|
rowIndex: number,
|
|
44
43
|
defaultValue?: SelectFieldOption
|
|
45
44
|
) => (
|
|
46
|
-
<
|
|
45
|
+
<SelectField
|
|
47
46
|
key={rowIndex}
|
|
48
47
|
name="item_select"
|
|
49
48
|
isClearable
|
|
50
|
-
onChange={(value:
|
|
49
|
+
onChange={(value: SelectFieldOption | null) => {
|
|
51
50
|
const selectedItem = items?.find((x) => x.value === value?.value);
|
|
52
51
|
updateRow(rowIndex, selectedItem);
|
|
53
52
|
}}
|
|
@@ -57,7 +56,7 @@ export const DynamicPrintTable = ({ forwardedRef, ...props }: Props) => {
|
|
|
57
56
|
);
|
|
58
57
|
|
|
59
58
|
const createItemQuantity = (rowIndex: number, defaultValue?: number) => (
|
|
60
|
-
<
|
|
59
|
+
<TextField
|
|
61
60
|
key={rowIndex}
|
|
62
61
|
name="item_quantity"
|
|
63
62
|
type="number"
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React, { useEffect, useState } from "react";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
2
|
+
import { TextArea } from "../Form/TextArea/index.js";
|
|
3
|
+
import { TextField } from "../Form/TextField/index.js";
|
|
4
|
+
import { CheckBox } from "../Form/Checkbox/index.js";
|
|
5
5
|
|
|
6
6
|
type Props = {
|
|
7
7
|
cellInputs?: boolean;
|
|
@@ -251,7 +251,7 @@ export const DynamicTable = (
|
|
|
251
251
|
style={{ ...cellBordered, ...pastelGrayBackground }}
|
|
252
252
|
>
|
|
253
253
|
<div className="inline-flex">
|
|
254
|
-
<
|
|
254
|
+
<TextField
|
|
255
255
|
style={{ maxWidth: "45%", minWidth: "45%" }}
|
|
256
256
|
name={`column${col.id}`}
|
|
257
257
|
defaultValue={tableData[`column${col.id}`] || 1}
|
|
@@ -298,7 +298,7 @@ export const DynamicTable = (
|
|
|
298
298
|
}}
|
|
299
299
|
>
|
|
300
300
|
<div className="inline-flex">
|
|
301
|
-
<
|
|
301
|
+
<TextField
|
|
302
302
|
style={{ maxWidth: "45%", minWidth: "45%" }}
|
|
303
303
|
name={`row${rowId}`}
|
|
304
304
|
defaultValue={tableData[`row${rowId}`] || 1}
|
|
@@ -329,13 +329,13 @@ export const DynamicTable = (
|
|
|
329
329
|
style={{ ...cellBordered, ...cellCenteredContent }}
|
|
330
330
|
>
|
|
331
331
|
{cellInputs ? (
|
|
332
|
-
<
|
|
332
|
+
<TextArea
|
|
333
333
|
name={cellId}
|
|
334
334
|
defaultValue={tableData[cellId] || ""}
|
|
335
335
|
onChange={(value) => handleInputChange(cellId, value)}
|
|
336
336
|
/>
|
|
337
337
|
) : (
|
|
338
|
-
<
|
|
338
|
+
<CheckBox
|
|
339
339
|
name={cellId}
|
|
340
340
|
defaultValue={cellValidation}
|
|
341
341
|
onChange={(value) => {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React, { useEffect, useState } from "react";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
2
|
+
import { SelectField } from "../Form/SelectField/index.js";
|
|
3
|
+
import { TextField } from "../Form/TextField/index.js";
|
|
4
|
+
import { CheckBox } from "../Form/Checkbox/index.js";
|
|
5
5
|
import { createModal } from "../Modal/index.js";
|
|
6
6
|
import { Button } from "../Buttons/index.js";
|
|
7
7
|
import {
|
|
@@ -122,7 +122,6 @@ export const GenericDynamicTable = (props: Props) => {
|
|
|
122
122
|
newDeletedData.push(deletedItem);
|
|
123
123
|
}
|
|
124
124
|
setDeletedData(newDeletedData);
|
|
125
|
-
onChange && onChange(tableData?.filter((x) => x.id !== rowId));
|
|
126
125
|
setTableData((prevData) => prevData?.filter((x) => x.id !== rowId));
|
|
127
126
|
};
|
|
128
127
|
|
|
@@ -200,10 +199,10 @@ export const GenericDynamicTable = (props: Props) => {
|
|
|
200
199
|
|
|
201
200
|
const FieldComponent =
|
|
202
201
|
column.type === "textField"
|
|
203
|
-
?
|
|
202
|
+
? TextField
|
|
204
203
|
: column.type === "checkbox"
|
|
205
|
-
?
|
|
206
|
-
:
|
|
204
|
+
? CheckBox
|
|
205
|
+
: SelectField;
|
|
207
206
|
|
|
208
207
|
const setTableValue = (columnName: string, newValue: any) => {
|
|
209
208
|
setTableData((prevState) => {
|
|
@@ -361,7 +360,7 @@ export const GenericDynamicTable = (props: Props) => {
|
|
|
361
360
|
<div className={`${className}`}>
|
|
362
361
|
{searcheables.length > 0 && (
|
|
363
362
|
<div>
|
|
364
|
-
<
|
|
363
|
+
<TextField
|
|
365
364
|
className="mb-2"
|
|
366
365
|
name="search"
|
|
367
366
|
title={`Buscar por: ${searcheables
|
package/src/Footer/Footer.tsx
CHANGED
|
@@ -37,7 +37,7 @@ export const Footer = ({
|
|
|
37
37
|
<div className="px-4 mx-auto flex flex-wrap items-center justify-center">
|
|
38
38
|
<p className="text-white text-[1.2rem]">
|
|
39
39
|
{`Creado en `} <a href={href}>Zauru</a>{" "}
|
|
40
|
-
{`con ❤️ ${new Date().getFullYear()} v.
|
|
40
|
+
{`con ❤️ ${new Date().getFullYear()} v.2.0.0`}
|
|
41
41
|
</p>
|
|
42
42
|
{showConnection && (
|
|
43
43
|
<div className="ml-5">
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
import { useAppSelector } from "@zauru-sdk/redux";
|
|
2
1
|
import React, { useEffect, useState } from "react";
|
|
2
|
+
import { useFormContext } from "react-hook-form";
|
|
3
3
|
|
|
4
4
|
type Props = {
|
|
5
5
|
id?: string;
|
|
6
6
|
name?: string;
|
|
7
|
-
formName?: string;
|
|
8
7
|
label?: string;
|
|
9
8
|
defaultValue?: boolean;
|
|
10
9
|
onChange?: (
|
|
@@ -12,19 +11,19 @@ type Props = {
|
|
|
12
11
|
event: React.ChangeEvent<HTMLInputElement>
|
|
13
12
|
) => { stopUIChange: boolean } | void;
|
|
14
13
|
disabled?: boolean;
|
|
15
|
-
error?: string | undefined;
|
|
16
14
|
borderColor?: string;
|
|
15
|
+
required?: boolean;
|
|
17
16
|
};
|
|
18
17
|
|
|
19
|
-
export const
|
|
18
|
+
export const CheckBox = (props: Props) => {
|
|
20
19
|
const {
|
|
21
20
|
id,
|
|
22
21
|
name,
|
|
23
22
|
defaultValue = false,
|
|
24
23
|
onChange,
|
|
25
24
|
disabled = false,
|
|
26
|
-
error,
|
|
27
25
|
label,
|
|
26
|
+
required = false,
|
|
28
27
|
} = props;
|
|
29
28
|
|
|
30
29
|
const [checked, setChecked] = useState(defaultValue);
|
|
@@ -35,6 +34,9 @@ export const CheckboxWithoutValidation = (props: Props) => {
|
|
|
35
34
|
|
|
36
35
|
const handleInputChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
|
37
36
|
const isChecked = event.target.checked;
|
|
37
|
+
if (register) {
|
|
38
|
+
register.onChange(event);
|
|
39
|
+
}
|
|
38
40
|
if (onChange) {
|
|
39
41
|
const result = onChange(isChecked, event);
|
|
40
42
|
if (result?.stopUIChange) {
|
|
@@ -44,6 +46,15 @@ export const CheckboxWithoutValidation = (props: Props) => {
|
|
|
44
46
|
setChecked(isChecked);
|
|
45
47
|
};
|
|
46
48
|
|
|
49
|
+
const {
|
|
50
|
+
register: tempRegister,
|
|
51
|
+
formState: { errors },
|
|
52
|
+
} = useFormContext() || { formState: {} }; // Obtener el contexto solo si existe
|
|
53
|
+
const error = errors ? errors[props.name ?? "-1"] : undefined;
|
|
54
|
+
const register = tempRegister
|
|
55
|
+
? tempRegister(props.name ?? "-1", { required })
|
|
56
|
+
: undefined; // Solo usar register si está disponible
|
|
57
|
+
|
|
47
58
|
const color = error ? "red" : "gray";
|
|
48
59
|
const borderColor = disabled ? "border-gray-300" : `border-${color}-500`;
|
|
49
60
|
|
|
@@ -51,11 +62,12 @@ export const CheckboxWithoutValidation = (props: Props) => {
|
|
|
51
62
|
<input
|
|
52
63
|
type="checkbox"
|
|
53
64
|
id={id ?? name}
|
|
54
|
-
name={name}
|
|
55
65
|
checked={checked}
|
|
56
|
-
onChange={handleInputChange}
|
|
57
66
|
className={`form-checkbox h-4 w-4 text-indigo-600 ${borderColor} focus:border-indigo-500 focus:ring-indigo-500`}
|
|
58
67
|
disabled={disabled}
|
|
68
|
+
{...(register ?? {})}
|
|
69
|
+
name={name}
|
|
70
|
+
onChange={handleInputChange}
|
|
59
71
|
/>
|
|
60
72
|
);
|
|
61
73
|
|
|
@@ -73,24 +85,15 @@ export const CheckboxWithoutValidation = (props: Props) => {
|
|
|
73
85
|
className={`ml-2 block text-sm font-medium text-${color}-700 dark:text-${color}-500`}
|
|
74
86
|
>
|
|
75
87
|
{label}
|
|
88
|
+
{required && <span className="text-red-500">*</span>}
|
|
76
89
|
</label>
|
|
77
90
|
)}
|
|
78
91
|
</div>
|
|
79
92
|
{error && (
|
|
80
93
|
<p className={`mt-2 text-sm text-${color}-600 dark:text-${color}-500`}>
|
|
81
|
-
<span className="font-medium">Oops!</span> {error}
|
|
94
|
+
<span className="font-medium">Oops!</span> {error.message?.toString()}
|
|
82
95
|
</p>
|
|
83
96
|
)}
|
|
84
97
|
</div>
|
|
85
98
|
);
|
|
86
99
|
};
|
|
87
|
-
|
|
88
|
-
//<reference> https://tailwindui.com/components/application-ui/forms/form-layouts
|
|
89
|
-
export const CheckBox = (props: Props) => {
|
|
90
|
-
const { formValidations } = useAppSelector((state) => state.formValidation);
|
|
91
|
-
const error = formValidations[props.formName ?? "-1"]?.[props.name ?? "-1"];
|
|
92
|
-
|
|
93
|
-
props = { ...props, error };
|
|
94
|
-
|
|
95
|
-
return <CheckboxWithoutValidation {...props} />;
|
|
96
|
-
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import {
|
|
2
|
+
import { CheckBox } from "../Checkbox/index.js";
|
|
3
3
|
|
|
4
4
|
export type ChecklistItem = {
|
|
5
5
|
id: string;
|
|
@@ -24,7 +24,7 @@ export const Checklist: React.FC<ChecklistProps> = ({ items, onChange }) => {
|
|
|
24
24
|
return (
|
|
25
25
|
<div>
|
|
26
26
|
{items.map((item) => (
|
|
27
|
-
<
|
|
27
|
+
<CheckBox
|
|
28
28
|
key={item.id}
|
|
29
29
|
{...item}
|
|
30
30
|
onChange={(value) => handleCheckboxChange(item.name, value)}
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import React, { useEffect, useState } from "react";
|
|
2
2
|
import { CalendarIconSVG, CloseSvgIcon, IdeaIconSVG } from "@zauru-sdk/icons";
|
|
3
|
-
import {
|
|
3
|
+
import { useFormContext } from "react-hook-form";
|
|
4
4
|
|
|
5
5
|
type Props = {
|
|
6
6
|
id?: string;
|
|
7
7
|
name: string;
|
|
8
|
-
formName?: string;
|
|
9
8
|
title?: string;
|
|
10
9
|
hint?: string;
|
|
11
10
|
helpText?: string;
|
|
@@ -13,12 +12,12 @@ type Props = {
|
|
|
13
12
|
onChange?: (value: string) => void;
|
|
14
13
|
isClearable?: boolean;
|
|
15
14
|
tabIndex?: number;
|
|
16
|
-
error?: string;
|
|
17
15
|
disabled?: boolean;
|
|
18
16
|
className?: string;
|
|
17
|
+
required?: boolean;
|
|
19
18
|
};
|
|
20
19
|
|
|
21
|
-
export const
|
|
20
|
+
export const FormDatePicker = (props: Props) => {
|
|
22
21
|
const {
|
|
23
22
|
id,
|
|
24
23
|
name,
|
|
@@ -28,14 +27,22 @@ export const FormDatePickerWithoutValidation = (props: Props) => {
|
|
|
28
27
|
helpText,
|
|
29
28
|
onChange,
|
|
30
29
|
tabIndex,
|
|
31
|
-
error,
|
|
32
30
|
disabled = false,
|
|
33
31
|
className = "",
|
|
34
32
|
isClearable = false,
|
|
33
|
+
required = false,
|
|
35
34
|
} = props;
|
|
36
35
|
|
|
37
36
|
const [value, setValue] = useState<string | null>(defaultValue);
|
|
38
37
|
const [showTooltip, setShowTooltip] = useState<boolean>(false);
|
|
38
|
+
const {
|
|
39
|
+
register: tempRegister,
|
|
40
|
+
formState: { errors },
|
|
41
|
+
} = useFormContext() || { formState: {} }; // Obtener el contexto solo si existe
|
|
42
|
+
const error = errors ? errors[props.name ?? "-1"] : undefined;
|
|
43
|
+
const register = tempRegister
|
|
44
|
+
? tempRegister(props.name ?? "-1", { required })
|
|
45
|
+
: undefined; // Solo usar register si está disponible
|
|
39
46
|
|
|
40
47
|
const color = error ? "red" : "gray";
|
|
41
48
|
|
|
@@ -61,6 +68,7 @@ export const FormDatePickerWithoutValidation = (props: Props) => {
|
|
|
61
68
|
className={`block text-sm font-medium ${textColor} ${className}`}
|
|
62
69
|
>
|
|
63
70
|
{title}
|
|
71
|
+
{required && <span className="text-red-500">*</span>}
|
|
64
72
|
</label>
|
|
65
73
|
)}
|
|
66
74
|
<div className="flex relative items-center">
|
|
@@ -69,16 +77,20 @@ export const FormDatePickerWithoutValidation = (props: Props) => {
|
|
|
69
77
|
</div>
|
|
70
78
|
<input
|
|
71
79
|
id={id}
|
|
72
|
-
name={name}
|
|
73
80
|
tabIndex={tabIndex}
|
|
74
81
|
type="date"
|
|
82
|
+
value={value ?? ""}
|
|
83
|
+
pattern="\d{4}-\d{2}-\d{2}"
|
|
84
|
+
className={`${bgColor} ${borderColor} ${textColor} text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full pl-10 p-2.5`}
|
|
85
|
+
{...(register ?? {})}
|
|
86
|
+
name={name}
|
|
75
87
|
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
|
76
88
|
setValue(e.target.value);
|
|
77
89
|
onChange && onChange(e.target.value);
|
|
90
|
+
if (register) {
|
|
91
|
+
register.onChange(e);
|
|
92
|
+
}
|
|
78
93
|
}}
|
|
79
|
-
value={value ?? ""}
|
|
80
|
-
pattern="\d{4}-\d{2}-\d{2}"
|
|
81
|
-
className={`${bgColor} ${borderColor} ${textColor} text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full pl-10 p-2.5`}
|
|
82
94
|
></input>
|
|
83
95
|
{value && isClearable && (
|
|
84
96
|
<button
|
|
@@ -108,7 +120,7 @@ export const FormDatePickerWithoutValidation = (props: Props) => {
|
|
|
108
120
|
</div>
|
|
109
121
|
{error && (
|
|
110
122
|
<p className={`mt-2 text-sm text-${color}-600 dark:text-${color}-500`}>
|
|
111
|
-
<span className="font-medium">Oops!</span> {error}
|
|
123
|
+
<span className="font-medium">Oops!</span> {error.message?.toString()}
|
|
112
124
|
</p>
|
|
113
125
|
)}
|
|
114
126
|
{!error && hint && (
|
|
@@ -121,12 +133,3 @@ export const FormDatePickerWithoutValidation = (props: Props) => {
|
|
|
121
133
|
</>
|
|
122
134
|
);
|
|
123
135
|
};
|
|
124
|
-
|
|
125
|
-
export const FormDatePicker = (props: Props) => {
|
|
126
|
-
const { formValidations } = useAppSelector((state) => state.formValidation);
|
|
127
|
-
const error = formValidations[props.formName ?? "-1"]?.[props.name ?? "-1"];
|
|
128
|
-
|
|
129
|
-
props = { ...props, error };
|
|
130
|
-
|
|
131
|
-
return <FormDatePickerWithoutValidation {...props} />;
|
|
132
|
-
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { TextField
|
|
1
|
+
import { TextField } from "../TextField/index.js";
|
|
2
2
|
import { TripleFieldContainer } from "../FieldContainer/index.js";
|
|
3
3
|
import { DoubleFieldContainer } from "../FieldContainer/index.js";
|
|
4
4
|
import { YesNo } from "../YesNo/index.js";
|
|
@@ -74,7 +74,7 @@ export function DynamicBaculoForm(props: Props) {
|
|
|
74
74
|
}
|
|
75
75
|
case "zauru_data":
|
|
76
76
|
return (
|
|
77
|
-
<
|
|
77
|
+
<TextField
|
|
78
78
|
key={field.id}
|
|
79
79
|
title={`${field.required ? "*" : ""}${field.name}`}
|
|
80
80
|
hint={field.hint}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { DownloadIconSVG, IdeaIconSVG } from "@zauru-sdk/icons";
|
|
2
|
-
import { useAppSelector } from "@zauru-sdk/redux";
|
|
3
2
|
import React, { useState } from "react";
|
|
3
|
+
import { useFormContext } from "react-hook-form";
|
|
4
4
|
|
|
5
5
|
type Props = {
|
|
6
6
|
id?: string;
|
|
@@ -12,15 +12,15 @@ type Props = {
|
|
|
12
12
|
onChange?: (event: React.ChangeEvent<HTMLInputElement>) => void;
|
|
13
13
|
disabled?: boolean;
|
|
14
14
|
readOnly?: boolean;
|
|
15
|
-
error?: string | undefined;
|
|
16
15
|
fileTypes?: string[];
|
|
17
16
|
showAvailableTypes?: boolean;
|
|
18
17
|
className?: string;
|
|
19
18
|
defaultValue?: string | File;
|
|
20
19
|
download?: boolean;
|
|
20
|
+
required?: boolean;
|
|
21
21
|
};
|
|
22
22
|
|
|
23
|
-
export const
|
|
23
|
+
export const FileUploadField = (props: Props) => {
|
|
24
24
|
const {
|
|
25
25
|
id,
|
|
26
26
|
name,
|
|
@@ -30,14 +30,23 @@ export const FileUploadFieldWithoutValidation = (props: Props) => {
|
|
|
30
30
|
onChange,
|
|
31
31
|
disabled = false,
|
|
32
32
|
readOnly = false,
|
|
33
|
-
error,
|
|
34
33
|
fileTypes = [],
|
|
35
34
|
showAvailableTypes = false,
|
|
36
35
|
className,
|
|
37
36
|
defaultValue = undefined,
|
|
38
37
|
download = false,
|
|
38
|
+
required = false,
|
|
39
39
|
} = props;
|
|
40
40
|
|
|
41
|
+
const {
|
|
42
|
+
register: tempRegister,
|
|
43
|
+
formState: { errors },
|
|
44
|
+
} = useFormContext() || { formState: {} }; // Obtener el contexto solo si existe
|
|
45
|
+
const error = errors ? errors[props.name ?? "-1"] : undefined;
|
|
46
|
+
const register = tempRegister
|
|
47
|
+
? tempRegister(props.name ?? "-1", { required })
|
|
48
|
+
: undefined; // Solo usar register si está disponible
|
|
49
|
+
|
|
41
50
|
const [showTooltip, setShowTooltip] = useState<boolean>(false);
|
|
42
51
|
|
|
43
52
|
if (typeof defaultValue == "string") {
|
|
@@ -76,17 +85,32 @@ export const FileUploadFieldWithoutValidation = (props: Props) => {
|
|
|
76
85
|
className={`block mb-1 text-sm font-medium text-gray-700`}
|
|
77
86
|
>
|
|
78
87
|
{title}
|
|
88
|
+
{required && <span className="text-red-500">*</span>}
|
|
79
89
|
</label>
|
|
80
90
|
)}{" "}
|
|
81
91
|
<div
|
|
82
92
|
role="button"
|
|
83
93
|
tabIndex={0}
|
|
84
94
|
onClick={() => {
|
|
95
|
+
if (register) {
|
|
96
|
+
register.onChange({
|
|
97
|
+
target: {
|
|
98
|
+
value: defaultValue,
|
|
99
|
+
},
|
|
100
|
+
});
|
|
101
|
+
}
|
|
85
102
|
window.open(defaultValue, "_blank");
|
|
86
103
|
}}
|
|
87
104
|
onKeyDown={(event) => {
|
|
88
105
|
// Permite que el evento se active con la tecla Enter
|
|
89
106
|
if (event.key === "Enter") {
|
|
107
|
+
if (register) {
|
|
108
|
+
register.onChange({
|
|
109
|
+
target: {
|
|
110
|
+
value: defaultValue,
|
|
111
|
+
},
|
|
112
|
+
});
|
|
113
|
+
}
|
|
90
114
|
window.open(defaultValue, "_blank");
|
|
91
115
|
}
|
|
92
116
|
}}
|
|
@@ -164,7 +188,7 @@ export const FileUploadFieldWithoutValidation = (props: Props) => {
|
|
|
164
188
|
</div>
|
|
165
189
|
{error && (
|
|
166
190
|
<p className={`mt-2 text-sm text-${color}-600`}>
|
|
167
|
-
<span className="font-medium">Oops!</span> {error}
|
|
191
|
+
<span className="font-medium">Oops!</span> {error.message?.toString()}
|
|
168
192
|
</p>
|
|
169
193
|
)}
|
|
170
194
|
{!error && hintMessage && (
|
|
@@ -173,12 +197,3 @@ export const FileUploadFieldWithoutValidation = (props: Props) => {
|
|
|
173
197
|
</div>
|
|
174
198
|
);
|
|
175
199
|
};
|
|
176
|
-
|
|
177
|
-
export const FileUploadField = (props: Props) => {
|
|
178
|
-
const { formValidations } = useAppSelector((state) => state.formValidation);
|
|
179
|
-
const error = formValidations[props.formName ?? "-1"]?.[props.name ?? "-1"];
|
|
180
|
-
|
|
181
|
-
props = { ...props, error };
|
|
182
|
-
|
|
183
|
-
return <FileUploadFieldWithoutValidation {...props} />;
|
|
184
|
-
};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { zodResolver } from "@hookform/resolvers/zod";
|
|
2
|
+
import { Form, useSubmit } from "@remix-run/react";
|
|
3
|
+
import {
|
|
4
|
+
FieldValues,
|
|
5
|
+
FormProvider,
|
|
6
|
+
SubmitHandler,
|
|
7
|
+
useForm,
|
|
8
|
+
} from "react-hook-form";
|
|
9
|
+
import { z, ZodSchema } from "zod";
|
|
10
|
+
import React from "react";
|
|
11
|
+
|
|
12
|
+
type Props = {
|
|
13
|
+
children: React.ReactNode;
|
|
14
|
+
schema?: ZodSchema;
|
|
15
|
+
onSubmit?: SubmitHandler<FieldValues>;
|
|
16
|
+
id?: string;
|
|
17
|
+
method?: "post" | "put" | "delete" | "patch";
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
const emptySchema = z.any();
|
|
21
|
+
|
|
22
|
+
export const ReactZodForm = (props: Props) => {
|
|
23
|
+
const {
|
|
24
|
+
children,
|
|
25
|
+
method = "post",
|
|
26
|
+
schema = emptySchema,
|
|
27
|
+
onSubmit,
|
|
28
|
+
id,
|
|
29
|
+
} = props;
|
|
30
|
+
|
|
31
|
+
const submit = useSubmit();
|
|
32
|
+
const methods = useForm({
|
|
33
|
+
resolver: zodResolver(schema),
|
|
34
|
+
mode: "onSubmit",
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
const handleSubmit: SubmitHandler<FieldValues> = (data, event) => {
|
|
38
|
+
if (onSubmit) {
|
|
39
|
+
onSubmit(data, event);
|
|
40
|
+
} else {
|
|
41
|
+
// If no onSubmit is provided, use Remix's submit function
|
|
42
|
+
submit(event?.target as HTMLFormElement, { method });
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
return (
|
|
47
|
+
<FormProvider {...methods}>
|
|
48
|
+
<Form
|
|
49
|
+
onSubmit={onSubmit ? methods.handleSubmit(onSubmit) : undefined}
|
|
50
|
+
//onSubmit={methods.handleSubmit(handleSubmit)}
|
|
51
|
+
method={method}
|
|
52
|
+
id={id}
|
|
53
|
+
>
|
|
54
|
+
{children}
|
|
55
|
+
</Form>
|
|
56
|
+
</FormProvider>
|
|
57
|
+
);
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
export default ReactZodForm;
|