@zauru-sdk/components 1.0.54 → 1.0.60
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 +48 -0
- package/LICENCE.md +11 -11
- package/package.json +7 -7
- package/src/Alerts/ErrorBoundaryAlert/ErrorBoundaryAlert.tsx +66 -66
- package/src/Alerts/StaticAlert.tsx +121 -121
- package/src/Alerts/index.ts +2 -2
- package/src/BlockUI/BlockUI.tsx +50 -50
- package/src/BlockUI/index.tsx +1 -1
- package/src/Buttons/Button.tsx +90 -90
- package/src/Buttons/index.ts +1 -1
- package/src/Card/Card.tsx +24 -24
- package/src/Card/index.ts +1 -1
- package/src/Chat/ChatLayout.tsx +131 -131
- package/src/Chat/ChatMessageHistory.tsx +142 -142
- package/src/Chat/index.ts +2 -2
- package/src/ConnectionState/ConnectionState.tsx +27 -27
- package/src/ConnectionState/index.tsx +1 -1
- package/src/Containers/BodyContainer.tsx +14 -14
- package/src/Containers/ButtonSectionContainer.tsx +21 -21
- package/src/Containers/Container.tsx +39 -39
- package/src/Containers/DoubleContainer.tsx +48 -48
- package/src/Containers/MainContainer.tsx +17 -17
- package/src/Containers/OutletContainer.tsx +14 -14
- package/src/Containers/SubContainer.tsx +37 -37
- package/src/Containers/index.ts +7 -7
- package/src/DynamicTable/BasicPrintDynamicTable.tsx +73 -73
- package/src/DynamicTable/DynamicPrintTable.tsx +288 -288
- package/src/DynamicTable/DynamicTable.tsx +405 -405
- package/src/DynamicTable/GenericDynamicTable.tsx +456 -456
- package/src/DynamicTable/index.tsx +4 -4
- package/src/Footer/Footer.tsx +50 -50
- package/src/Footer/index.tsx +1 -1
- package/src/Form/Checkbox/index.tsx +96 -96
- package/src/Form/Checklist/index.tsx +35 -35
- package/src/Form/DatePicker/index.tsx +132 -132
- package/src/Form/DynamicBaculoForm/index.tsx +361 -361
- package/src/Form/FieldContainer/DoubleFieldContainer.tsx +35 -35
- package/src/Form/FieldContainer/QuadrupleFieldContainer.tsx +36 -36
- package/src/Form/FieldContainer/TripleFieldContainer.tsx +35 -35
- package/src/Form/FieldContainer/index.ts +3 -3
- package/src/Form/FileUpload/index.tsx +184 -184
- package/src/Form/FormButtons/index.tsx +78 -78
- package/src/Form/FormLayout/index.tsx +37 -37
- package/src/Form/SelectField/index.tsx +237 -237
- package/src/Form/TextArea/index.tsx +125 -125
- package/src/Form/TextField/index.tsx +194 -194
- package/src/Form/TimePicker/index.tsx +127 -127
- package/src/Form/YesNo/index.tsx +77 -77
- package/src/Form/index.ts +13 -13
- package/src/Labels/InfoLabel/index.tsx +21 -21
- package/src/Labels/index.tsx +1 -1
- package/src/Layouts/homeLayout/index.tsx +34 -34
- package/src/Layouts/index.ts +1 -1
- package/src/LineSeparator/LineSeparator.tsx +3 -3
- package/src/LineSeparator/index.tsx +1 -1
- package/src/Modal/Modal.tsx +104 -104
- package/src/Modal/index.tsx +1 -1
- package/src/NavBar/NavBar.tsx +223 -223
- package/src/NavBar/NavBar.types.ts +64 -64
- package/src/NavBar/NavBar.utils.ts +58 -58
- package/src/NavBar/index.tsx +5 -5
- package/src/ProgressBar/ProgressBar.tsx +25 -25
- package/src/ProgressBar/ProgressCircle.tsx +75 -75
- package/src/ProgressBar/index.tsx +2 -2
- package/src/Skeletons/LoadingInputSkeleton.tsx +12 -12
- package/src/Skeletons/index.ts +1 -1
- package/src/Tab/Tab.tsx +63 -63
- package/src/Tab/index.ts +1 -1
- package/src/Table/ZauruTable.tsx +265 -265
- package/src/Table/index.tsx +1 -1
- package/src/TaskList/TaskList.tsx +88 -88
- package/src/TaskList/index.ts +1 -1
- package/src/Titles/LabelArray.tsx +17 -17
- package/src/Titles/TableColumnTitle.tsx +9 -9
- package/src/Titles/TitleH1.tsx +10 -10
- package/src/Titles/TitleH2.tsx +10 -10
- package/src/Titles/TitleH3.tsx +10 -10
- package/src/Titles/index.ts +5 -5
- package/src/Tooltip/Tooltip.tsx +42 -42
- package/src/Tooltip/index.ts +1 -1
- package/src/WithTooltip/WithTooltip.tsx +21 -21
- package/src/WithTooltip/index.tsx +1 -1
- package/src/Wizards/StepWizard.tsx +88 -88
- package/src/Wizards/index.ts +1 -1
- package/src/Zendesk/Chat.tsx +83 -83
- package/src/Zendesk/index.ts +2 -2
- package/src/Zendesk/zendesk.config.ts +40 -40
- package/src/index.ts +24 -24
- package/src/postcss.config.mjs +5 -5
- package/src/tailwind.config.ts +10 -10
- package/src/tailwind.css +3 -3
- package/tsconfig.cjs.json +8 -8
- package/tsconfig.esm.json +11 -11
- package/tsconfig.json +17 -17
|
@@ -1,35 +1,35 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
|
|
3
|
-
type Props = {
|
|
4
|
-
children: React.ReactNode;
|
|
5
|
-
className?: string;
|
|
6
|
-
alignCenter?: boolean;
|
|
7
|
-
};
|
|
8
|
-
|
|
9
|
-
export const DoubleFieldContainer = (props: Props) => {
|
|
10
|
-
const { children, className, alignCenter = true } = props;
|
|
11
|
-
|
|
12
|
-
const getChildren = (index: number) => {
|
|
13
|
-
if (children && Array.isArray(children) && children[index]) {
|
|
14
|
-
return children[index];
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
if (children && index === 0) {
|
|
18
|
-
return children;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
return <></>;
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
return (
|
|
25
|
-
<>
|
|
26
|
-
<div
|
|
27
|
-
className={`grid md:grid-cols-2 sm:grid-cols-1 gap-4 ${className}`}
|
|
28
|
-
style={alignCenter ? { alignItems: "center" } : {}}
|
|
29
|
-
>
|
|
30
|
-
<div className="col-span-1">{getChildren(0)}</div>
|
|
31
|
-
<div className="col-span-1">{getChildren(1)}</div>
|
|
32
|
-
</div>
|
|
33
|
-
</>
|
|
34
|
-
);
|
|
35
|
-
};
|
|
1
|
+
import React from "react";
|
|
2
|
+
|
|
3
|
+
type Props = {
|
|
4
|
+
children: React.ReactNode;
|
|
5
|
+
className?: string;
|
|
6
|
+
alignCenter?: boolean;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export const DoubleFieldContainer = (props: Props) => {
|
|
10
|
+
const { children, className, alignCenter = true } = props;
|
|
11
|
+
|
|
12
|
+
const getChildren = (index: number) => {
|
|
13
|
+
if (children && Array.isArray(children) && children[index]) {
|
|
14
|
+
return children[index];
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
if (children && index === 0) {
|
|
18
|
+
return children;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return <></>;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
return (
|
|
25
|
+
<>
|
|
26
|
+
<div
|
|
27
|
+
className={`grid md:grid-cols-2 sm:grid-cols-1 gap-4 ${className}`}
|
|
28
|
+
style={alignCenter ? { alignItems: "center" } : {}}
|
|
29
|
+
>
|
|
30
|
+
<div className="col-span-1">{getChildren(0)}</div>
|
|
31
|
+
<div className="col-span-1">{getChildren(1)}</div>
|
|
32
|
+
</div>
|
|
33
|
+
</>
|
|
34
|
+
);
|
|
35
|
+
};
|
|
@@ -1,36 +1,36 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
|
|
3
|
-
type Props = {
|
|
4
|
-
children: React.ReactNode;
|
|
5
|
-
className?: string;
|
|
6
|
-
};
|
|
7
|
-
|
|
8
|
-
export const QuadrupleFieldContainer = (props: Props) => {
|
|
9
|
-
const { children, className } = props;
|
|
10
|
-
|
|
11
|
-
const getChildren = (index: number) => {
|
|
12
|
-
if (children && Array.isArray(children) && children[index]) {
|
|
13
|
-
return children[index];
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
if (children && index === 0) {
|
|
17
|
-
return children;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
return <></>;
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
return (
|
|
24
|
-
<>
|
|
25
|
-
<div
|
|
26
|
-
className={`grid lg:grid-cols-4 sm:grid-cols-2 xs:grid-cols-1 gap-4 ${className}`}
|
|
27
|
-
style={{ alignItems: "center" }}
|
|
28
|
-
>
|
|
29
|
-
<div className="col-span-1">{getChildren(0)}</div>
|
|
30
|
-
<div className="col-span-1">{getChildren(1)}</div>
|
|
31
|
-
<div className="col-span-1">{getChildren(2)}</div>
|
|
32
|
-
<div className="col-span-1">{getChildren(3)}</div>
|
|
33
|
-
</div>
|
|
34
|
-
</>
|
|
35
|
-
);
|
|
36
|
-
};
|
|
1
|
+
import React from "react";
|
|
2
|
+
|
|
3
|
+
type Props = {
|
|
4
|
+
children: React.ReactNode;
|
|
5
|
+
className?: string;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
export const QuadrupleFieldContainer = (props: Props) => {
|
|
9
|
+
const { children, className } = props;
|
|
10
|
+
|
|
11
|
+
const getChildren = (index: number) => {
|
|
12
|
+
if (children && Array.isArray(children) && children[index]) {
|
|
13
|
+
return children[index];
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
if (children && index === 0) {
|
|
17
|
+
return children;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
return <></>;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
return (
|
|
24
|
+
<>
|
|
25
|
+
<div
|
|
26
|
+
className={`grid lg:grid-cols-4 sm:grid-cols-2 xs:grid-cols-1 gap-4 ${className}`}
|
|
27
|
+
style={{ alignItems: "center" }}
|
|
28
|
+
>
|
|
29
|
+
<div className="col-span-1">{getChildren(0)}</div>
|
|
30
|
+
<div className="col-span-1">{getChildren(1)}</div>
|
|
31
|
+
<div className="col-span-1">{getChildren(2)}</div>
|
|
32
|
+
<div className="col-span-1">{getChildren(3)}</div>
|
|
33
|
+
</div>
|
|
34
|
+
</>
|
|
35
|
+
);
|
|
36
|
+
};
|
|
@@ -1,35 +1,35 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
|
|
3
|
-
type Props = {
|
|
4
|
-
children: React.ReactNode;
|
|
5
|
-
className?: string;
|
|
6
|
-
};
|
|
7
|
-
|
|
8
|
-
export const TripleFieldContainer = (props: Props) => {
|
|
9
|
-
const { children, className } = props;
|
|
10
|
-
|
|
11
|
-
const getChildren = (index: number) => {
|
|
12
|
-
if (children && Array.isArray(children) && children[index]) {
|
|
13
|
-
return children[index];
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
if (children && index === 0) {
|
|
17
|
-
return children;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
return <></>;
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
return (
|
|
24
|
-
<>
|
|
25
|
-
<div
|
|
26
|
-
className={`grid sm:grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4 ${className}`}
|
|
27
|
-
style={{ alignItems: "center" }}
|
|
28
|
-
>
|
|
29
|
-
<div className="col-span-1">{getChildren(0)}</div>
|
|
30
|
-
<div className="col-span-1">{getChildren(1)}</div>
|
|
31
|
-
<div className="col-span-1">{getChildren(2)}</div>
|
|
32
|
-
</div>
|
|
33
|
-
</>
|
|
34
|
-
);
|
|
35
|
-
};
|
|
1
|
+
import React from "react";
|
|
2
|
+
|
|
3
|
+
type Props = {
|
|
4
|
+
children: React.ReactNode;
|
|
5
|
+
className?: string;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
export const TripleFieldContainer = (props: Props) => {
|
|
9
|
+
const { children, className } = props;
|
|
10
|
+
|
|
11
|
+
const getChildren = (index: number) => {
|
|
12
|
+
if (children && Array.isArray(children) && children[index]) {
|
|
13
|
+
return children[index];
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
if (children && index === 0) {
|
|
17
|
+
return children;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
return <></>;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
return (
|
|
24
|
+
<>
|
|
25
|
+
<div
|
|
26
|
+
className={`grid sm:grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4 ${className}`}
|
|
27
|
+
style={{ alignItems: "center" }}
|
|
28
|
+
>
|
|
29
|
+
<div className="col-span-1">{getChildren(0)}</div>
|
|
30
|
+
<div className="col-span-1">{getChildren(1)}</div>
|
|
31
|
+
<div className="col-span-1">{getChildren(2)}</div>
|
|
32
|
+
</div>
|
|
33
|
+
</>
|
|
34
|
+
);
|
|
35
|
+
};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export * from "./DoubleFieldContainer.js";
|
|
2
|
-
export * from "./QuadrupleFieldContainer.js";
|
|
3
|
-
export * from "./TripleFieldContainer.js";
|
|
1
|
+
export * from "./DoubleFieldContainer.js";
|
|
2
|
+
export * from "./QuadrupleFieldContainer.js";
|
|
3
|
+
export * from "./TripleFieldContainer.js";
|
|
@@ -1,184 +1,184 @@
|
|
|
1
|
-
import { DownloadIconSVG, IdeaIconSVG } from "@zauru-sdk/icons";
|
|
2
|
-
import { useAppSelector } from "@zauru-sdk/redux";
|
|
3
|
-
import React, { useState } from "react";
|
|
4
|
-
|
|
5
|
-
type Props = {
|
|
6
|
-
id?: string;
|
|
7
|
-
name: string;
|
|
8
|
-
formName?: string;
|
|
9
|
-
title?: string;
|
|
10
|
-
helpText?: string;
|
|
11
|
-
hint?: string;
|
|
12
|
-
onChange?: (event: React.ChangeEvent<HTMLInputElement>) => void;
|
|
13
|
-
disabled?: boolean;
|
|
14
|
-
readOnly?: boolean;
|
|
15
|
-
error?: string | undefined;
|
|
16
|
-
fileTypes?: string[];
|
|
17
|
-
showAvailableTypes?: boolean;
|
|
18
|
-
className?: string;
|
|
19
|
-
defaultValue?: string | File;
|
|
20
|
-
download?: boolean;
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
export const FileUploadFieldWithoutValidation = (props: Props) => {
|
|
24
|
-
const {
|
|
25
|
-
id,
|
|
26
|
-
name,
|
|
27
|
-
title,
|
|
28
|
-
helpText,
|
|
29
|
-
hint,
|
|
30
|
-
onChange,
|
|
31
|
-
disabled = false,
|
|
32
|
-
readOnly = false,
|
|
33
|
-
error,
|
|
34
|
-
fileTypes = [],
|
|
35
|
-
showAvailableTypes = false,
|
|
36
|
-
className,
|
|
37
|
-
defaultValue = undefined,
|
|
38
|
-
download = false,
|
|
39
|
-
} = props;
|
|
40
|
-
|
|
41
|
-
const [showTooltip, setShowTooltip] = useState<boolean>(false);
|
|
42
|
-
|
|
43
|
-
if (typeof defaultValue == "string") {
|
|
44
|
-
if (download) {
|
|
45
|
-
return (
|
|
46
|
-
<div
|
|
47
|
-
role="button"
|
|
48
|
-
tabIndex={0}
|
|
49
|
-
onClick={() => {
|
|
50
|
-
window.open(defaultValue, "_blank");
|
|
51
|
-
}}
|
|
52
|
-
onKeyDown={(event) => {
|
|
53
|
-
// Permite que el evento se active con la tecla Enter
|
|
54
|
-
if (event.key === "Enter") {
|
|
55
|
-
window.open(defaultValue, "_blank");
|
|
56
|
-
}
|
|
57
|
-
}}
|
|
58
|
-
>
|
|
59
|
-
{title && (
|
|
60
|
-
<label
|
|
61
|
-
htmlFor={name}
|
|
62
|
-
className="block mb-1 text-sm font-medium text-gray-700"
|
|
63
|
-
>
|
|
64
|
-
{title}
|
|
65
|
-
</label>
|
|
66
|
-
)}{" "}
|
|
67
|
-
<DownloadIconSVG />
|
|
68
|
-
</div>
|
|
69
|
-
);
|
|
70
|
-
}
|
|
71
|
-
return (
|
|
72
|
-
<div className={`col-span-6 sm:col-span-3 ${className}`}>
|
|
73
|
-
{title && (
|
|
74
|
-
<label
|
|
75
|
-
htmlFor={name}
|
|
76
|
-
className={`block mb-1 text-sm font-medium text-gray-700`}
|
|
77
|
-
>
|
|
78
|
-
{title}
|
|
79
|
-
</label>
|
|
80
|
-
)}{" "}
|
|
81
|
-
<div
|
|
82
|
-
role="button"
|
|
83
|
-
tabIndex={0}
|
|
84
|
-
onClick={() => {
|
|
85
|
-
window.open(defaultValue, "_blank");
|
|
86
|
-
}}
|
|
87
|
-
onKeyDown={(event) => {
|
|
88
|
-
// Permite que el evento se active con la tecla Enter
|
|
89
|
-
if (event.key === "Enter") {
|
|
90
|
-
window.open(defaultValue, "_blank");
|
|
91
|
-
}
|
|
92
|
-
}}
|
|
93
|
-
>
|
|
94
|
-
<img
|
|
95
|
-
src={defaultValue}
|
|
96
|
-
alt={name}
|
|
97
|
-
className={`h-48 w-48 inline mr-1 pb-1`}
|
|
98
|
-
style={{
|
|
99
|
-
stroke: "currentColor",
|
|
100
|
-
strokeWidth: 2,
|
|
101
|
-
strokeLinecap: "round",
|
|
102
|
-
strokeLinejoin: "round",
|
|
103
|
-
fill: "none",
|
|
104
|
-
backgroundColor: "transparent",
|
|
105
|
-
}}
|
|
106
|
-
/>
|
|
107
|
-
</div>
|
|
108
|
-
</div>
|
|
109
|
-
);
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
const handleInputChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
|
113
|
-
onChange && onChange(event);
|
|
114
|
-
};
|
|
115
|
-
|
|
116
|
-
let hintMessage = hint;
|
|
117
|
-
if (showAvailableTypes && fileTypes.length > 0) {
|
|
118
|
-
hintMessage = `${hint} Archivos permitidos: ${fileTypes.join(", ")}`;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
const color = error ? "red" : "gray";
|
|
122
|
-
const isReadOnly = disabled || readOnly;
|
|
123
|
-
const bgColor = isReadOnly ? "bg-gray-200" : `bg-${color}-50`;
|
|
124
|
-
const textColor = isReadOnly ? "text-gray-500" : `text-${color}-900`;
|
|
125
|
-
const borderColor = isReadOnly ? "border-gray-300" : `border-${color}-500`;
|
|
126
|
-
|
|
127
|
-
return (
|
|
128
|
-
<div className={`col-span-6 sm:col-span-3 ${className}`}>
|
|
129
|
-
{title && (
|
|
130
|
-
<label
|
|
131
|
-
htmlFor={name}
|
|
132
|
-
className={`block mb-1 text-sm font-medium text-${color}-700`}
|
|
133
|
-
>
|
|
134
|
-
{title}
|
|
135
|
-
</label>
|
|
136
|
-
)}
|
|
137
|
-
<div className="flex relative items-center">
|
|
138
|
-
<input
|
|
139
|
-
type="file"
|
|
140
|
-
name={name}
|
|
141
|
-
id={id ?? name}
|
|
142
|
-
disabled={disabled}
|
|
143
|
-
readOnly={readOnly}
|
|
144
|
-
accept={fileTypes.map((ft) => `.${ft}`).join(", ")}
|
|
145
|
-
onChange={handleInputChange}
|
|
146
|
-
className={`block w-full rounded-md ${bgColor} ${borderColor} ${textColor} shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm`}
|
|
147
|
-
/>
|
|
148
|
-
{helpText && (
|
|
149
|
-
<div className="flex items-center relative ml-3">
|
|
150
|
-
<div
|
|
151
|
-
className="relative cursor-pointer"
|
|
152
|
-
onMouseEnter={() => setShowTooltip(true)}
|
|
153
|
-
onMouseLeave={() => setShowTooltip(false)}
|
|
154
|
-
>
|
|
155
|
-
<IdeaIconSVG />
|
|
156
|
-
{showTooltip && (
|
|
157
|
-
<div className="absolute -left-48 top-0 mt-8 p-2 bg-white border rounded shadow text-black z-50">
|
|
158
|
-
{helpText}
|
|
159
|
-
</div>
|
|
160
|
-
)}
|
|
161
|
-
</div>
|
|
162
|
-
</div>
|
|
163
|
-
)}
|
|
164
|
-
</div>
|
|
165
|
-
{error && (
|
|
166
|
-
<p className={`mt-2 text-sm text-${color}-600`}>
|
|
167
|
-
<span className="font-medium">Oops!</span> {error}
|
|
168
|
-
</p>
|
|
169
|
-
)}
|
|
170
|
-
{!error && hintMessage && (
|
|
171
|
-
<p className={`mt-2 italic text-sm text-${color}-500`}>{hintMessage}</p>
|
|
172
|
-
)}
|
|
173
|
-
</div>
|
|
174
|
-
);
|
|
175
|
-
};
|
|
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
|
-
};
|
|
1
|
+
import { DownloadIconSVG, IdeaIconSVG } from "@zauru-sdk/icons";
|
|
2
|
+
import { useAppSelector } from "@zauru-sdk/redux";
|
|
3
|
+
import React, { useState } from "react";
|
|
4
|
+
|
|
5
|
+
type Props = {
|
|
6
|
+
id?: string;
|
|
7
|
+
name: string;
|
|
8
|
+
formName?: string;
|
|
9
|
+
title?: string;
|
|
10
|
+
helpText?: string;
|
|
11
|
+
hint?: string;
|
|
12
|
+
onChange?: (event: React.ChangeEvent<HTMLInputElement>) => void;
|
|
13
|
+
disabled?: boolean;
|
|
14
|
+
readOnly?: boolean;
|
|
15
|
+
error?: string | undefined;
|
|
16
|
+
fileTypes?: string[];
|
|
17
|
+
showAvailableTypes?: boolean;
|
|
18
|
+
className?: string;
|
|
19
|
+
defaultValue?: string | File;
|
|
20
|
+
download?: boolean;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export const FileUploadFieldWithoutValidation = (props: Props) => {
|
|
24
|
+
const {
|
|
25
|
+
id,
|
|
26
|
+
name,
|
|
27
|
+
title,
|
|
28
|
+
helpText,
|
|
29
|
+
hint,
|
|
30
|
+
onChange,
|
|
31
|
+
disabled = false,
|
|
32
|
+
readOnly = false,
|
|
33
|
+
error,
|
|
34
|
+
fileTypes = [],
|
|
35
|
+
showAvailableTypes = false,
|
|
36
|
+
className,
|
|
37
|
+
defaultValue = undefined,
|
|
38
|
+
download = false,
|
|
39
|
+
} = props;
|
|
40
|
+
|
|
41
|
+
const [showTooltip, setShowTooltip] = useState<boolean>(false);
|
|
42
|
+
|
|
43
|
+
if (typeof defaultValue == "string") {
|
|
44
|
+
if (download) {
|
|
45
|
+
return (
|
|
46
|
+
<div
|
|
47
|
+
role="button"
|
|
48
|
+
tabIndex={0}
|
|
49
|
+
onClick={() => {
|
|
50
|
+
window.open(defaultValue, "_blank");
|
|
51
|
+
}}
|
|
52
|
+
onKeyDown={(event) => {
|
|
53
|
+
// Permite que el evento se active con la tecla Enter
|
|
54
|
+
if (event.key === "Enter") {
|
|
55
|
+
window.open(defaultValue, "_blank");
|
|
56
|
+
}
|
|
57
|
+
}}
|
|
58
|
+
>
|
|
59
|
+
{title && (
|
|
60
|
+
<label
|
|
61
|
+
htmlFor={name}
|
|
62
|
+
className="block mb-1 text-sm font-medium text-gray-700"
|
|
63
|
+
>
|
|
64
|
+
{title}
|
|
65
|
+
</label>
|
|
66
|
+
)}{" "}
|
|
67
|
+
<DownloadIconSVG />
|
|
68
|
+
</div>
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
return (
|
|
72
|
+
<div className={`col-span-6 sm:col-span-3 ${className}`}>
|
|
73
|
+
{title && (
|
|
74
|
+
<label
|
|
75
|
+
htmlFor={name}
|
|
76
|
+
className={`block mb-1 text-sm font-medium text-gray-700`}
|
|
77
|
+
>
|
|
78
|
+
{title}
|
|
79
|
+
</label>
|
|
80
|
+
)}{" "}
|
|
81
|
+
<div
|
|
82
|
+
role="button"
|
|
83
|
+
tabIndex={0}
|
|
84
|
+
onClick={() => {
|
|
85
|
+
window.open(defaultValue, "_blank");
|
|
86
|
+
}}
|
|
87
|
+
onKeyDown={(event) => {
|
|
88
|
+
// Permite que el evento se active con la tecla Enter
|
|
89
|
+
if (event.key === "Enter") {
|
|
90
|
+
window.open(defaultValue, "_blank");
|
|
91
|
+
}
|
|
92
|
+
}}
|
|
93
|
+
>
|
|
94
|
+
<img
|
|
95
|
+
src={defaultValue}
|
|
96
|
+
alt={name}
|
|
97
|
+
className={`h-48 w-48 inline mr-1 pb-1`}
|
|
98
|
+
style={{
|
|
99
|
+
stroke: "currentColor",
|
|
100
|
+
strokeWidth: 2,
|
|
101
|
+
strokeLinecap: "round",
|
|
102
|
+
strokeLinejoin: "round",
|
|
103
|
+
fill: "none",
|
|
104
|
+
backgroundColor: "transparent",
|
|
105
|
+
}}
|
|
106
|
+
/>
|
|
107
|
+
</div>
|
|
108
|
+
</div>
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const handleInputChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
|
113
|
+
onChange && onChange(event);
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
let hintMessage = hint;
|
|
117
|
+
if (showAvailableTypes && fileTypes.length > 0) {
|
|
118
|
+
hintMessage = `${hint} Archivos permitidos: ${fileTypes.join(", ")}`;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const color = error ? "red" : "gray";
|
|
122
|
+
const isReadOnly = disabled || readOnly;
|
|
123
|
+
const bgColor = isReadOnly ? "bg-gray-200" : `bg-${color}-50`;
|
|
124
|
+
const textColor = isReadOnly ? "text-gray-500" : `text-${color}-900`;
|
|
125
|
+
const borderColor = isReadOnly ? "border-gray-300" : `border-${color}-500`;
|
|
126
|
+
|
|
127
|
+
return (
|
|
128
|
+
<div className={`col-span-6 sm:col-span-3 ${className}`}>
|
|
129
|
+
{title && (
|
|
130
|
+
<label
|
|
131
|
+
htmlFor={name}
|
|
132
|
+
className={`block mb-1 text-sm font-medium text-${color}-700`}
|
|
133
|
+
>
|
|
134
|
+
{title}
|
|
135
|
+
</label>
|
|
136
|
+
)}
|
|
137
|
+
<div className="flex relative items-center">
|
|
138
|
+
<input
|
|
139
|
+
type="file"
|
|
140
|
+
name={name}
|
|
141
|
+
id={id ?? name}
|
|
142
|
+
disabled={disabled}
|
|
143
|
+
readOnly={readOnly}
|
|
144
|
+
accept={fileTypes.map((ft) => `.${ft}`).join(", ")}
|
|
145
|
+
onChange={handleInputChange}
|
|
146
|
+
className={`block w-full rounded-md ${bgColor} ${borderColor} ${textColor} shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm`}
|
|
147
|
+
/>
|
|
148
|
+
{helpText && (
|
|
149
|
+
<div className="flex items-center relative ml-3">
|
|
150
|
+
<div
|
|
151
|
+
className="relative cursor-pointer"
|
|
152
|
+
onMouseEnter={() => setShowTooltip(true)}
|
|
153
|
+
onMouseLeave={() => setShowTooltip(false)}
|
|
154
|
+
>
|
|
155
|
+
<IdeaIconSVG />
|
|
156
|
+
{showTooltip && (
|
|
157
|
+
<div className="absolute -left-48 top-0 mt-8 p-2 bg-white border rounded shadow text-black z-50">
|
|
158
|
+
{helpText}
|
|
159
|
+
</div>
|
|
160
|
+
)}
|
|
161
|
+
</div>
|
|
162
|
+
</div>
|
|
163
|
+
)}
|
|
164
|
+
</div>
|
|
165
|
+
{error && (
|
|
166
|
+
<p className={`mt-2 text-sm text-${color}-600`}>
|
|
167
|
+
<span className="font-medium">Oops!</span> {error}
|
|
168
|
+
</p>
|
|
169
|
+
)}
|
|
170
|
+
{!error && hintMessage && (
|
|
171
|
+
<p className={`mt-2 italic text-sm text-${color}-500`}>{hintMessage}</p>
|
|
172
|
+
)}
|
|
173
|
+
</div>
|
|
174
|
+
);
|
|
175
|
+
};
|
|
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
|
+
};
|